diff options
Diffstat (limited to 'winpr/libwinpr/comm/test')
-rw-r--r-- | winpr/libwinpr/comm/test/CMakeLists.txt | 35 | ||||
-rw-r--r-- | winpr/libwinpr/comm/test/TestCommConfig.c | 148 | ||||
-rw-r--r-- | winpr/libwinpr/comm/test/TestCommDevice.c | 115 | ||||
-rw-r--r-- | winpr/libwinpr/comm/test/TestCommMonitor.c | 70 | ||||
-rw-r--r-- | winpr/libwinpr/comm/test/TestControlSettings.c | 123 | ||||
-rw-r--r-- | winpr/libwinpr/comm/test/TestGetCommState.c | 138 | ||||
-rw-r--r-- | winpr/libwinpr/comm/test/TestHandflow.c | 92 | ||||
-rw-r--r-- | winpr/libwinpr/comm/test/TestSerialChars.c | 178 | ||||
-rw-r--r-- | winpr/libwinpr/comm/test/TestSetCommState.c | 332 | ||||
-rw-r--r-- | winpr/libwinpr/comm/test/TestTimeouts.c | 138 |
10 files changed, 1369 insertions, 0 deletions
diff --git a/winpr/libwinpr/comm/test/CMakeLists.txt b/winpr/libwinpr/comm/test/CMakeLists.txt new file mode 100644 index 0000000..f5ae406 --- /dev/null +++ b/winpr/libwinpr/comm/test/CMakeLists.txt @@ -0,0 +1,35 @@ + +set(MODULE_NAME "TestComm") +set(MODULE_PREFIX "TEST_COMM") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestCommDevice.c + TestCommConfig.c + TestGetCommState.c + TestSetCommState.c + TestSerialChars.c + TestControlSettings.c + TestHandflow.c + TestTimeouts.c + TestCommMonitor.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +target_link_libraries(${MODULE_NAME} winpr) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) + set_tests_properties(${TestName} PROPERTIES LABELS "comm" ) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") + diff --git a/winpr/libwinpr/comm/test/TestCommConfig.c b/winpr/libwinpr/comm/test/TestCommConfig.c new file mode 100644 index 0000000..c405f14 --- /dev/null +++ b/winpr/libwinpr/comm/test/TestCommConfig.c @@ -0,0 +1,148 @@ +/** + * WinPR: Windows Portable Runtime + * Serial Communication API + * + * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * Copyright 2014 Hewlett-Packard Development Company, L.P. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <sys/stat.h> + +#include <winpr/crt.h> +#include <winpr/comm.h> +#include <winpr/file.h> +#include <winpr/synch.h> +#include <winpr/handle.h> + +int TestCommConfig(int argc, char* argv[]) +{ + DCB dcb = { 0 }; + HANDLE hComm; + BOOL success; + LPCSTR lpFileName = "\\\\.\\COM1"; + COMMPROP commProp = { 0 }; + struct stat statbuf = { 0 }; + + hComm = CreateFileA(lpFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + + if (hComm && (hComm != INVALID_HANDLE_VALUE)) + { + fprintf(stderr, + "CreateFileA failure: could create a handle on a not yet defined device: %s\n", + lpFileName); + return EXIT_FAILURE; + } + + if (stat("/dev/ttyS0", &statbuf) < 0) + { + fprintf(stderr, "/dev/ttyS0 not available, making the test to succeed though\n"); + return EXIT_SUCCESS; + } + + success = DefineCommDevice(lpFileName, "/dev/ttyS0"); + if (!success) + { + fprintf(stderr, "DefineCommDevice failure: %s\n", lpFileName); + return EXIT_FAILURE; + } + + hComm = CreateFileA(lpFileName, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_WRITE, /* invalid parmaeter */ + NULL, CREATE_NEW, /* invalid parameter */ + 0, (HANDLE)1234); /* invalid parmaeter */ + if (hComm != INVALID_HANDLE_VALUE) + { + fprintf(stderr, + "CreateFileA failure: could create a handle with some invalid parameters %s\n", + lpFileName); + return EXIT_FAILURE; + } + + hComm = CreateFileA(lpFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + + if (!hComm || (hComm == INVALID_HANDLE_VALUE)) + { + fprintf(stderr, "CreateFileA failure: %s GetLastError() = 0x%08x\n", lpFileName, + GetLastError()); + return EXIT_FAILURE; + } + + /* TODO: a second call to CreateFileA should failed and + * GetLastError should return ERROR_SHARING_VIOLATION */ + + dcb.DCBlength = sizeof(DCB); + success = GetCommState(hComm, &dcb); + if (!success) + { + fprintf(stderr, "GetCommState failure: GetLastError() = Ox%x\n", GetLastError()); + return EXIT_FAILURE; + } + + fprintf(stderr, + "BaudRate: %" PRIu32 " ByteSize: %" PRIu8 " Parity: %" PRIu8 " StopBits: %" PRIu8 "\n", + dcb.BaudRate, dcb.ByteSize, dcb.Parity, dcb.StopBits); + + if (!GetCommProperties(hComm, &commProp)) + { + fprintf(stderr, "GetCommProperties failure: GetLastError(): 0x%08x\n", GetLastError()); + return EXIT_FAILURE; + } + + if ((commProp.dwSettableBaud & BAUD_57600) <= 0) + { + fprintf(stderr, "BAUD_57600 unsupported!\n"); + return EXIT_FAILURE; + } + + if ((commProp.dwSettableBaud & BAUD_14400) > 0) + { + fprintf(stderr, "BAUD_14400 supported!\n"); + return EXIT_FAILURE; + } + + dcb.BaudRate = CBR_57600; + dcb.ByteSize = 8; + dcb.Parity = NOPARITY; + dcb.StopBits = ONESTOPBIT; + + success = SetCommState(hComm, &dcb); + + if (!success) + { + fprintf(stderr, "SetCommState failure: GetLastError() = 0x%x\n", GetLastError()); + return EXIT_FAILURE; + } + + success = GetCommState(hComm, &dcb); + + if (!success) + { + fprintf(stderr, "GetCommState failure: GetLastError() = 0x%x\n", GetLastError()); + return 0; + } + + if ((dcb.BaudRate != CBR_57600) || (dcb.ByteSize != 8) || (dcb.Parity != NOPARITY) || + (dcb.StopBits != ONESTOPBIT)) + { + fprintf(stderr, + "Got an unexpeted value among: BaudRate: %" PRIu32 " ByteSize: %" PRIu8 + " Parity: %" PRIu8 " StopBits: %" PRIu8 "\n", + dcb.BaudRate, dcb.ByteSize, dcb.Parity, dcb.StopBits); + } + + CloseHandle(hComm); + + return 0; +} diff --git a/winpr/libwinpr/comm/test/TestCommDevice.c b/winpr/libwinpr/comm/test/TestCommDevice.c new file mode 100644 index 0000000..09eb1c2 --- /dev/null +++ b/winpr/libwinpr/comm/test/TestCommDevice.c @@ -0,0 +1,115 @@ +/** + * WinPR: Windows Portable Runtime + * Serial Communication API + * + * Copyright 2014 Hewlett-Packard Development Company, L.P. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> + +#include <winpr/comm.h> +#include <winpr/tchar.h> + +static int test_CommDevice(LPCTSTR lpDeviceName, BOOL expectedResult) +{ + BOOL result; + TCHAR lpTargetPath[MAX_PATH]; + size_t tcslen; + + result = DefineCommDevice(lpDeviceName, _T("/dev/test")); + if ((!expectedResult && result) || (expectedResult && !result)) /* logical XOR */ + { + _tprintf(_T("DefineCommDevice failure: device name: %s, expected result: %s, result: %s\n"), + lpDeviceName, (expectedResult ? "TRUE" : "FALSE"), (result ? "TRUE" : "FALSE")); + + return FALSE; + } + + result = IsCommDevice(lpDeviceName); + if ((!expectedResult && result) || (expectedResult && !result)) /* logical XOR */ + { + _tprintf(_T("IsCommDevice failure: device name: %s, expected result: %s, result: %s\n"), + lpDeviceName, (expectedResult ? "TRUE" : "FALSE"), (result ? "TRUE" : "FALSE")); + + return FALSE; + } + + tcslen = (size_t)QueryCommDevice(lpDeviceName, lpTargetPath, MAX_PATH); + if (expectedResult) + { + if (tcslen <= _tcslen(lpTargetPath)) /* at least 2 more TCHAR are expected */ + { + _tprintf(_T("QueryCommDevice failure: didn't find the device name: %s\n"), + lpDeviceName); + return FALSE; + } + + if (_tcscmp(_T("/dev/test"), lpTargetPath) != 0) + { + _tprintf( + _T("QueryCommDevice failure: device name: %s, expected result: %s, result: %s\n"), + lpDeviceName, _T("/dev/test"), lpTargetPath); + + return FALSE; + } + + if (lpTargetPath[_tcslen(lpTargetPath) + 1] != 0) + { + _tprintf(_T("QueryCommDevice failure: device name: %s, the second NULL character is ") + _T("missing at the end of the buffer\n"), + lpDeviceName); + return FALSE; + } + } + else + { + if (tcslen > 0) + { + _tprintf(_T("QueryCommDevice failure: device name: %s, expected result: <none>, ") + _T("result: %") _T(PRIuz) _T(" %s\n"), + lpDeviceName, tcslen, lpTargetPath); + + return FALSE; + } + } + + return TRUE; +} + +int TestCommDevice(int argc, char* argv[]) +{ + if (!test_CommDevice(_T("COM0"), FALSE)) + return EXIT_FAILURE; + + if (!test_CommDevice(_T("COM1"), TRUE)) + return EXIT_FAILURE; + + if (!test_CommDevice(_T("COM1"), TRUE)) + return EXIT_FAILURE; + + if (!test_CommDevice(_T("COM10"), FALSE)) + return EXIT_FAILURE; + + if (!test_CommDevice(_T("\\\\.\\COM5"), TRUE)) + return EXIT_FAILURE; + + if (!test_CommDevice(_T("\\\\.\\COM10"), TRUE)) + return EXIT_FAILURE; + + if (!test_CommDevice(_T("\\\\.COM10"), FALSE)) + return EXIT_FAILURE; + + return 0; +} diff --git a/winpr/libwinpr/comm/test/TestCommMonitor.c b/winpr/libwinpr/comm/test/TestCommMonitor.c new file mode 100644 index 0000000..fe28a86 --- /dev/null +++ b/winpr/libwinpr/comm/test/TestCommMonitor.c @@ -0,0 +1,70 @@ + +#include <winpr/crt.h> +#include <winpr/comm.h> +#include <winpr/file.h> +#include <winpr/synch.h> +#include <winpr/handle.h> + +int TestCommMonitor(int argc, char* argv[]) +{ + HANDLE hComm; + DWORD dwError; + BOOL fSuccess; + DWORD dwEvtMask; + OVERLAPPED overlapped = { 0 }; + LPCSTR lpFileName = "\\\\.\\COM1"; + + hComm = CreateFileA(lpFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, NULL); + + if (!hComm || (hComm == INVALID_HANDLE_VALUE)) + { + printf("CreateFileA failure: %s\n", lpFileName); + return -1; + } + + fSuccess = SetCommMask(hComm, EV_CTS | EV_DSR); + + if (!fSuccess) + { + printf("SetCommMask failure: GetLastError() = %" PRIu32 "\n", GetLastError()); + return -1; + } + + if (!(overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + { + printf("CreateEvent failed: GetLastError() = %" PRIu32 "\n", GetLastError()); + return -1; + } + + if (WaitCommEvent(hComm, &dwEvtMask, &overlapped)) + { + if (dwEvtMask & EV_DSR) + { + printf("EV_DSR\n"); + } + + if (dwEvtMask & EV_CTS) + { + printf("EV_CTS\n"); + } + } + else + { + dwError = GetLastError(); + + if (dwError == ERROR_IO_PENDING) + { + printf("ERROR_IO_PENDING\n"); + } + else + { + printf("WaitCommEvent failure: GetLastError() = %" PRIu32 "\n", dwError); + return -1; + } + } + + CloseHandle(hComm); + + return 0; +} diff --git a/winpr/libwinpr/comm/test/TestControlSettings.c b/winpr/libwinpr/comm/test/TestControlSettings.c new file mode 100644 index 0000000..7611dbb --- /dev/null +++ b/winpr/libwinpr/comm/test/TestControlSettings.c @@ -0,0 +1,123 @@ +/** + * WinPR: Windows Portable Runtime + * Serial Communication API + * + * Copyright 2014 Hewlett-Packard Development Company, L.P. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> + +#include <sys/stat.h> + +#include <winpr/comm.h> +#include <winpr/crt.h> + +#include "../comm.h" + +int TestControlSettings(int argc, char* argv[]) +{ + struct stat statbuf; + BOOL result; + HANDLE hComm; + DCB dcb; + + if (stat("/dev/ttyS0", &statbuf) < 0) + { + fprintf(stderr, "/dev/ttyS0 not available, making the test to succeed though\n"); + return EXIT_SUCCESS; + } + + result = DefineCommDevice("COM1", "/dev/ttyS0"); + if (!result) + { + fprintf(stderr, "DefineCommDevice failure: 0x%x\n", GetLastError()); + return EXIT_FAILURE; + } + + hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + if (hComm == INVALID_HANDLE_VALUE) + { + fprintf(stderr, "CreateFileA failure: 0x%x\n", GetLastError()); + return EXIT_FAILURE; + } + + ZeroMemory(&dcb, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + if (!GetCommState(hComm, &dcb)) + { + fprintf(stderr, "GetCommState failure; GetLastError(): %08x\n", GetLastError()); + return FALSE; + } + + /* Test 1 */ + + dcb.ByteSize = 5; + dcb.StopBits = ONESTOPBIT; + dcb.Parity = MARKPARITY; + + if (!SetCommState(hComm, &dcb)) + { + fprintf(stderr, "SetCommState failure; GetLastError(): %08x\n", GetLastError()); + return FALSE; + } + + ZeroMemory(&dcb, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + if (!GetCommState(hComm, &dcb)) + { + fprintf(stderr, "GetCommState failure; GetLastError(): %08x\n", GetLastError()); + return FALSE; + } + + if ((dcb.ByteSize != 5) || (dcb.StopBits != ONESTOPBIT) || (dcb.Parity != MARKPARITY)) + { + fprintf(stderr, "test1 failed.\n"); + return FALSE; + } + + /* Test 2 */ + + dcb.ByteSize = 8; + dcb.StopBits = ONESTOPBIT; + dcb.Parity = NOPARITY; + + if (!SetCommState(hComm, &dcb)) + { + fprintf(stderr, "SetCommState failure; GetLastError(): %08x\n", GetLastError()); + return FALSE; + } + + ZeroMemory(&dcb, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + if (!GetCommState(hComm, &dcb)) + { + fprintf(stderr, "GetCommState failure; GetLastError(): %08x\n", GetLastError()); + return FALSE; + } + + if ((dcb.ByteSize != 8) || (dcb.StopBits != ONESTOPBIT) || (dcb.Parity != NOPARITY)) + { + fprintf(stderr, "test2 failed.\n"); + return FALSE; + } + + if (!CloseHandle(hComm)) + { + fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError()); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/winpr/libwinpr/comm/test/TestGetCommState.c b/winpr/libwinpr/comm/test/TestGetCommState.c new file mode 100644 index 0000000..909e61a --- /dev/null +++ b/winpr/libwinpr/comm/test/TestGetCommState.c @@ -0,0 +1,138 @@ +/** + * WinPR: Windows Portable Runtime + * Serial Communication API + * + * Copyright 2014 Hewlett-Packard Development Company, L.P. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <sys/stat.h> + +#include <winpr/comm.h> +#include <winpr/crt.h> + +#include "../comm.h" + +static BOOL test_generic(HANDLE hComm) +{ + DCB dcb, *pDcb; + BOOL result; + + ZeroMemory(&dcb, sizeof(DCB)); + result = GetCommState(hComm, &dcb); + if (result) + { + printf("GetCommState failure, should have returned false because dcb.DCBlength has been " + "let uninitialized\n"); + return FALSE; + } + + ZeroMemory(&dcb, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB) / 2; /* improper value */ + result = GetCommState(hComm, &dcb); + if (result) + { + printf("GetCommState failure, should have return false because dcb.DCBlength was not " + "correctly initialized\n"); + return FALSE; + } + + ZeroMemory(&dcb, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + result = GetCommState(hComm, &dcb); + if (!result) + { + printf("GetCommState failure: Ox%x, with adjusted DCBlength\n", GetLastError()); + return FALSE; + } + + pDcb = (DCB*)calloc(2, sizeof(DCB)); + if (!pDcb) + return FALSE; + pDcb->DCBlength = sizeof(DCB) * 2; + result = GetCommState(hComm, pDcb); + result = result && (pDcb->DCBlength == sizeof(DCB) * 2); + free(pDcb); + if (!result) + { + printf("GetCommState failure: 0x%x, with bigger DCBlength\n", GetLastError()); + return FALSE; + } + + return TRUE; +} + +int TestGetCommState(int argc, char* argv[]) +{ + struct stat statbuf; + BOOL result; + HANDLE hComm; + + if (stat("/dev/ttyS0", &statbuf) < 0) + { + fprintf(stderr, "/dev/ttyS0 not available, making the test to succeed though\n"); + return EXIT_SUCCESS; + } + + result = DefineCommDevice("COM1", "/dev/ttyS0"); + if (!result) + { + printf("DefineCommDevice failure: 0x%x\n", GetLastError()); + return EXIT_FAILURE; + } + + hComm = CreateFileA("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + + if (hComm == INVALID_HANDLE_VALUE) + { + printf("CreateFileA failure: 0x%x\n", GetLastError()); + return EXIT_FAILURE; + } + + if (!test_generic(hComm)) + { + printf("test_generic failure (SerialDriverUnknown)\n"); + return EXIT_FAILURE; + } + + _comm_setServerSerialDriver(hComm, SerialDriverSerialSys); + if (!test_generic(hComm)) + { + printf("test_generic failure (SerialDriverSerialSys)\n"); + return EXIT_FAILURE; + } + + _comm_setServerSerialDriver(hComm, SerialDriverSerCxSys); + if (!test_generic(hComm)) + { + printf("test_generic failure (SerialDriverSerCxSys)\n"); + return EXIT_FAILURE; + } + + _comm_setServerSerialDriver(hComm, SerialDriverSerCx2Sys); + if (!test_generic(hComm)) + { + printf("test_generic failure (SerialDriverSerCx2Sys)\n"); + return EXIT_FAILURE; + } + + if (!CloseHandle(hComm)) + { + fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError()); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/winpr/libwinpr/comm/test/TestHandflow.c b/winpr/libwinpr/comm/test/TestHandflow.c new file mode 100644 index 0000000..ad7fe3c --- /dev/null +++ b/winpr/libwinpr/comm/test/TestHandflow.c @@ -0,0 +1,92 @@ +/** + * WinPR: Windows Portable Runtime + * Serial Communication API + * + * Copyright 2014 Hewlett-Packard Development Company, L.P. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <sys/stat.h> + +#ifndef _WIN32 +#include <termios.h> +#endif + +#include <winpr/comm.h> +#include <winpr/crt.h> + +#include "../comm.h" + +static BOOL test_SerialSys(HANDLE hComm) +{ + // TMP: TODO: + return TRUE; +} + +int TestHandflow(int argc, char* argv[]) +{ + struct stat statbuf; + BOOL result; + HANDLE hComm; + + if (stat("/dev/ttyS0", &statbuf) < 0) + { + fprintf(stderr, "/dev/ttyS0 not available, making the test to succeed though\n"); + return EXIT_SUCCESS; + } + + result = DefineCommDevice("COM1", "/dev/ttyS0"); + if (!result) + { + fprintf(stderr, "DefineCommDevice failure: 0x%x\n", GetLastError()); + return EXIT_FAILURE; + } + + hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + if (hComm == INVALID_HANDLE_VALUE) + { + fprintf(stderr, "CreateFileA failure: 0x%x\n", GetLastError()); + return EXIT_FAILURE; + } + + _comm_setServerSerialDriver(hComm, SerialDriverSerialSys); + if (!test_SerialSys(hComm)) + { + fprintf(stderr, "test_SerCxSys failure\n"); + return EXIT_FAILURE; + } + + /* _comm_setServerSerialDriver(hComm, SerialDriverSerCxSys); */ + /* if (!test_SerCxSys(hComm)) */ + /* { */ + /* fprintf(stderr, "test_SerCxSys failure\n"); */ + /* return EXIT_FAILURE; */ + /* } */ + + /* _comm_setServerSerialDriver(hComm, SerialDriverSerCx2Sys); */ + /* if (!test_SerCx2Sys(hComm)) */ + /* { */ + /* fprintf(stderr, "test_SerCxSys failure\n"); */ + /* return EXIT_FAILURE; */ + /* } */ + + if (!CloseHandle(hComm)) + { + fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError()); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/winpr/libwinpr/comm/test/TestSerialChars.c b/winpr/libwinpr/comm/test/TestSerialChars.c new file mode 100644 index 0000000..b235321 --- /dev/null +++ b/winpr/libwinpr/comm/test/TestSerialChars.c @@ -0,0 +1,178 @@ +/** + * WinPR: Windows Portable Runtime + * Serial Communication API + * + * Copyright 2014 Hewlett-Packard Development Company, L.P. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <sys/stat.h> + +#ifndef _WIN32 +#include <termios.h> +#endif + +#include <winpr/comm.h> +#include <winpr/crt.h> + +#include "../comm.h" + +static BOOL test_SerCxSys(HANDLE hComm) +{ + DCB dcb = { 0 }; + UCHAR XonChar, XoffChar; + + struct termios currentTermios = { 0 }; + + if (tcgetattr(((WINPR_COMM*)hComm)->fd, ¤tTermios) < 0) + { + fprintf(stderr, "tcgetattr failure.\n"); + return FALSE; + } + + dcb.DCBlength = sizeof(DCB); + if (!GetCommState(hComm, &dcb)) + { + fprintf(stderr, "GetCommState failure, GetLastError(): 0x%08x\n", GetLastError()); + return FALSE; + } + + if ((dcb.XonChar == '\0') || (dcb.XoffChar == '\0')) + { + fprintf(stderr, "test_SerCxSys failure, expected XonChar and XoffChar to be set\n"); + return FALSE; + } + + /* retrieve Xon/Xoff chars */ + if ((dcb.XonChar != currentTermios.c_cc[VSTART]) || + (dcb.XoffChar != currentTermios.c_cc[VSTOP])) + { + fprintf(stderr, "test_SerCxSys failure, could not retrieve XonChar and XoffChar\n"); + return FALSE; + } + + /* swap XonChar/XoffChar */ + + XonChar = dcb.XonChar; + XoffChar = dcb.XoffChar; + dcb.XonChar = XoffChar; + dcb.XoffChar = XonChar; + if (!SetCommState(hComm, &dcb)) + { + fprintf(stderr, "SetCommState failure, GetLastError(): 0x%08x\n", GetLastError()); + return FALSE; + } + + ZeroMemory(&dcb, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + if (!GetCommState(hComm, &dcb)) + { + fprintf(stderr, "GetCommState failure, GetLastError(): 0x%08x\n", GetLastError()); + return FALSE; + } + + if ((dcb.XonChar != XoffChar) || (dcb.XoffChar != XonChar)) + { + fprintf(stderr, "test_SerCxSys, expected XonChar and XoffChar to be swapped\n"); + return FALSE; + } + + /* same XonChar / XoffChar */ + dcb.XonChar = dcb.XoffChar; + if (SetCommState(hComm, &dcb)) + { + fprintf(stderr, "test_SerCxSys failure, SetCommState() was supposed to failed because " + "XonChar and XoffChar are the same\n"); + return FALSE; + } + if (GetLastError() != ERROR_INVALID_PARAMETER) + { + fprintf(stderr, "test_SerCxSys failure, SetCommState() was supposed to failed with " + "GetLastError()=ERROR_INVALID_PARAMETER\n"); + return FALSE; + } + + return TRUE; +} + +static BOOL test_SerCx2Sys(HANDLE hComm) +{ + DCB dcb = { 0 }; + + dcb.DCBlength = sizeof(DCB); + if (!GetCommState(hComm, &dcb)) + { + fprintf(stderr, "GetCommState failure; GetLastError(): %08x\n", GetLastError()); + return FALSE; + } + + if ((dcb.ErrorChar != '\0') || (dcb.EofChar != '\0') || (dcb.EvtChar != '\0') || + (dcb.XonChar != '\0') || (dcb.XoffChar != '\0')) + { + fprintf(stderr, "test_SerCx2Sys failure, expected all characters to be: '\\0'\n"); + return FALSE; + } + + return TRUE; +} + +int TestSerialChars(int argc, char* argv[]) +{ + struct stat statbuf; + BOOL result; + HANDLE hComm; + + if (stat("/dev/ttyS0", &statbuf) < 0) + { + fprintf(stderr, "/dev/ttyS0 not available, making the test to succeed though\n"); + return EXIT_SUCCESS; + } + + result = DefineCommDevice("COM1", "/dev/ttyS0"); + if (!result) + { + fprintf(stderr, "DefineCommDevice failure: 0x%x\n", GetLastError()); + return EXIT_FAILURE; + } + + hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + if (hComm == INVALID_HANDLE_VALUE) + { + fprintf(stderr, "CreateFileA failure: 0x%x\n", GetLastError()); + return EXIT_FAILURE; + } + + _comm_setServerSerialDriver(hComm, SerialDriverSerCxSys); + if (!test_SerCxSys(hComm)) + { + fprintf(stderr, "test_SerCxSys failure\n"); + return EXIT_FAILURE; + } + + _comm_setServerSerialDriver(hComm, SerialDriverSerCx2Sys); + if (!test_SerCx2Sys(hComm)) + { + fprintf(stderr, "test_SerCxSys failure\n"); + return EXIT_FAILURE; + } + + if (!CloseHandle(hComm)) + { + fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError()); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/winpr/libwinpr/comm/test/TestSetCommState.c b/winpr/libwinpr/comm/test/TestSetCommState.c new file mode 100644 index 0000000..0204058 --- /dev/null +++ b/winpr/libwinpr/comm/test/TestSetCommState.c @@ -0,0 +1,332 @@ +/** + * WinPR: Windows Portable Runtime + * Serial Communication API + * + * Copyright 2014 Hewlett-Packard Development Company, L.P. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <sys/stat.h> + +#include <winpr/comm.h> +#include <winpr/crt.h> + +#include "../comm.h" + +static void init_empty_dcb(DCB* pDcb) +{ + WINPR_ASSERT(pDcb); + + ZeroMemory(pDcb, sizeof(DCB)); + pDcb->DCBlength = sizeof(DCB); + pDcb->XonChar = 1; + pDcb->XoffChar = 2; +} + +static BOOL test_fParity(HANDLE hComm) +{ + DCB dcb; + BOOL result; + + init_empty_dcb(&dcb); + result = GetCommState(hComm, &dcb); + if (!result) + { + fprintf(stderr, "GetCommState failure: 0x%08" PRIx32 "\n", GetLastError()); + return FALSE; + } + + /* test 1 */ + dcb.fParity = TRUE; + result = SetCommState(hComm, &dcb); + if (!result) + { + fprintf(stderr, "SetCommState failure: 0x%08" PRIx32 "\n", GetLastError()); + return FALSE; + } + + init_empty_dcb(&dcb); + result = GetCommState(hComm, &dcb); + if (!result) + { + fprintf(stderr, "GetCommState failure: 0x%08" PRIx32 "\n", GetLastError()); + return FALSE; + } + + if (!dcb.fParity) + { + fprintf(stderr, "unexpected fParity: %" PRIu32 " instead of TRUE\n", dcb.fParity); + return FALSE; + } + + /* test 2 */ + dcb.fParity = FALSE; + result = SetCommState(hComm, &dcb); + if (!result) + { + fprintf(stderr, "SetCommState failure: 0x%08" PRIx32 "\n", GetLastError()); + return FALSE; + } + + init_empty_dcb(&dcb); + result = GetCommState(hComm, &dcb); + if (!result) + { + fprintf(stderr, "GetCommState failure: 0x%08" PRIx32 "\n", GetLastError()); + return FALSE; + } + + if (dcb.fParity) + { + fprintf(stderr, "unexpected fParity: %" PRIu32 " instead of FALSE\n", dcb.fParity); + return FALSE; + } + + /* test 3 (redo test 1) */ + dcb.fParity = TRUE; + result = SetCommState(hComm, &dcb); + if (!result) + { + fprintf(stderr, "SetCommState failure: 0x%08" PRIx32 "\n", GetLastError()); + return FALSE; + } + + init_empty_dcb(&dcb); + result = GetCommState(hComm, &dcb); + if (!result) + { + fprintf(stderr, "GetCommState failure: 0x%08" PRIx32 "\n", GetLastError()); + return FALSE; + } + + if (!dcb.fParity) + { + fprintf(stderr, "unexpected fParity: %" PRIu32 " instead of TRUE\n", dcb.fParity); + return FALSE; + } + + return TRUE; +} + +static BOOL test_SerialSys(HANDLE hComm) +{ + DCB dcb; + BOOL result; + + init_empty_dcb(&dcb); + result = GetCommState(hComm, &dcb); + if (!result) + { + fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError()); + return FALSE; + } + + /* Test 1 */ + dcb.BaudRate = CBR_115200; + result = SetCommState(hComm, &dcb); + if (!result) + { + fprintf(stderr, "SetCommState failure: 0x%08x\n", GetLastError()); + return FALSE; + } + + init_empty_dcb(&dcb); + result = GetCommState(hComm, &dcb); + if (!result) + { + fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError()); + return FALSE; + } + if (dcb.BaudRate != CBR_115200) + { + fprintf(stderr, "SetCommState failure: could not set BaudRate=%d (CBR_115200)\n", + CBR_115200); + return FALSE; + } + + /* Test 2 using a defferent baud rate */ + + dcb.BaudRate = CBR_57600; + result = SetCommState(hComm, &dcb); + if (!result) + { + fprintf(stderr, "SetCommState failure: 0x%x\n", GetLastError()); + return FALSE; + } + + init_empty_dcb(&dcb); + result = GetCommState(hComm, &dcb); + if (!result) + { + fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError()); + return FALSE; + } + if (dcb.BaudRate != CBR_57600) + { + fprintf(stderr, "SetCommState failure: could not set BaudRate=%d (CBR_57600)\n", CBR_57600); + return FALSE; + } + + /* Test 3 using an unsupported baud rate on Linux */ + dcb.BaudRate = CBR_128000; + result = SetCommState(hComm, &dcb); + if (result) + { + fprintf(stderr, "SetCommState failure: unexpected support of BaudRate=%d (CBR_128000)\n", + CBR_128000); + return FALSE; + } + + return TRUE; +} + +static BOOL test_SerCxSys(HANDLE hComm) +{ + /* as of today there is no difference */ + return test_SerialSys(hComm); +} + +static BOOL test_SerCx2Sys(HANDLE hComm) +{ + /* as of today there is no difference */ + return test_SerialSys(hComm); +} + +static BOOL test_generic(HANDLE hComm) +{ + DCB dcb, dcb2; + BOOL result; + + init_empty_dcb(&dcb); + result = GetCommState(hComm, &dcb); + if (!result) + { + fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError()); + return FALSE; + } + + /* Checks whether we get the same information before and after SetCommState */ + memcpy(&dcb2, &dcb, sizeof(DCB)); + result = SetCommState(hComm, &dcb); + if (!result) + { + fprintf(stderr, "SetCommState failure: 0x%08x\n", GetLastError()); + return FALSE; + } + + result = GetCommState(hComm, &dcb); + if (!result) + { + fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError()); + return FALSE; + } + + if (memcmp(&dcb, &dcb2, sizeof(DCB)) != 0) + { + fprintf(stderr, + "DCB is different after SetCommState() whereas it should have not changed\n"); + return FALSE; + } + + // TODO: a more complete and generic test using GetCommProperties() + + /* TMP: TODO: fBinary tests */ + + /* fParity tests */ + if (!test_fParity(hComm)) + { + fprintf(stderr, "test_fParity failure\n"); + return FALSE; + } + + return TRUE; +} + +int TestSetCommState(int argc, char* argv[]) +{ + struct stat statbuf; + BOOL result; + HANDLE hComm; + + if (stat("/dev/ttyS0", &statbuf) < 0) + { + fprintf(stderr, "/dev/ttyS0 not available, making the test to succeed though\n"); + return EXIT_SUCCESS; + } + + result = DefineCommDevice("COM1", "/dev/ttyS0"); + if (!result) + { + fprintf(stderr, "DefineCommDevice failure: 0x%x\n", GetLastError()); + return EXIT_FAILURE; + } + + hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + if (hComm == INVALID_HANDLE_VALUE) + { + fprintf(stderr, "CreateFileA failure: 0x%x\n", GetLastError()); + return EXIT_FAILURE; + } + + if (!test_generic(hComm)) + { + fprintf(stderr, "test_generic failure (SerialDriverUnknown)\n"); + return EXIT_FAILURE; + } + + _comm_setServerSerialDriver(hComm, SerialDriverSerialSys); + if (!test_generic(hComm)) + { + fprintf(stderr, "test_generic failure (SerialDriverSerialSys)\n"); + return EXIT_FAILURE; + } + if (!test_SerialSys(hComm)) + { + fprintf(stderr, "test_SerialSys failure\n"); + return EXIT_FAILURE; + } + + _comm_setServerSerialDriver(hComm, SerialDriverSerCxSys); + if (!test_generic(hComm)) + { + fprintf(stderr, "test_generic failure (SerialDriverSerCxSys)\n"); + return EXIT_FAILURE; + } + if (!test_SerCxSys(hComm)) + { + fprintf(stderr, "test_SerCxSys failure\n"); + return EXIT_FAILURE; + } + + _comm_setServerSerialDriver(hComm, SerialDriverSerCx2Sys); + if (!test_generic(hComm)) + { + fprintf(stderr, "test_generic failure (SerialDriverSerCx2Sys)\n"); + return EXIT_FAILURE; + } + if (!test_SerCx2Sys(hComm)) + { + fprintf(stderr, "test_SerCx2Sys failure\n"); + return EXIT_FAILURE; + } + + if (!CloseHandle(hComm)) + { + fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError()); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/winpr/libwinpr/comm/test/TestTimeouts.c b/winpr/libwinpr/comm/test/TestTimeouts.c new file mode 100644 index 0000000..c2d3be8 --- /dev/null +++ b/winpr/libwinpr/comm/test/TestTimeouts.c @@ -0,0 +1,138 @@ +/** + * WinPR: Windows Portable Runtime + * Serial Communication API + * + * Copyright 2014 Hewlett-Packard Development Company, L.P. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <sys/stat.h> + +#ifndef _WIN32 +#include <termios.h> +#endif + +#include <winpr/comm.h> +#include <winpr/crt.h> + +#include "../comm.h" + +static BOOL test_generic(HANDLE hComm) +{ + COMMTIMEOUTS timeouts = { 0 }, timeouts2 = { 0 }; + + timeouts.ReadIntervalTimeout = 1; + timeouts.ReadTotalTimeoutMultiplier = 2; + timeouts.ReadTotalTimeoutConstant = 3; + timeouts.WriteTotalTimeoutMultiplier = 4; + timeouts.WriteTotalTimeoutConstant = 5; + + if (!SetCommTimeouts(hComm, &timeouts)) + { + fprintf(stderr, "SetCommTimeouts failure, GetLastError: 0x%08x\n", GetLastError()); + return FALSE; + } + + if (!GetCommTimeouts(hComm, &timeouts2)) + { + fprintf(stderr, "GetCommTimeouts failure, GetLastError: 0x%08x\n", GetLastError()); + return FALSE; + } + + if (memcmp(&timeouts, &timeouts2, sizeof(COMMTIMEOUTS)) != 0) + { + fprintf(stderr, "TestTimeouts failure, didn't get back the same timeouts.\n"); + return FALSE; + } + + /* not supported combination */ + timeouts.ReadIntervalTimeout = MAXULONG; + timeouts.ReadTotalTimeoutConstant = MAXULONG; + if (SetCommTimeouts(hComm, &timeouts)) + { + fprintf(stderr, + "SetCommTimeouts succeeded with ReadIntervalTimeout and ReadTotalTimeoutConstant " + "set to MAXULONG. GetLastError: 0x%08x\n", + GetLastError()); + return FALSE; + } + + if (GetLastError() != ERROR_INVALID_PARAMETER) + { + fprintf(stderr, + "SetCommTimeouts failure, expected GetLastError to return ERROR_INVALID_PARAMETER " + "and got: 0x%08x\n", + GetLastError()); + return FALSE; + } + + return TRUE; +} + +int TestTimeouts(int argc, char* argv[]) +{ + struct stat statbuf; + BOOL result; + HANDLE hComm; + + if (stat("/dev/ttyS0", &statbuf) < 0) + { + fprintf(stderr, "/dev/ttyS0 not available, making the test to succeed though\n"); + return EXIT_SUCCESS; + } + + result = DefineCommDevice("COM1", "/dev/ttyS0"); + if (!result) + { + fprintf(stderr, "DefineCommDevice failure: 0x%x\n", GetLastError()); + return EXIT_FAILURE; + } + + hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + if (hComm == INVALID_HANDLE_VALUE) + { + fprintf(stderr, "CreateFileA failure: 0x%x\n", GetLastError()); + return EXIT_FAILURE; + } + + _comm_setServerSerialDriver(hComm, SerialDriverSerialSys); + if (!test_generic(hComm)) + { + fprintf(stderr, "test_SerialSys failure\n"); + return EXIT_FAILURE; + } + + _comm_setServerSerialDriver(hComm, SerialDriverSerCxSys); + if (!test_generic(hComm)) + { + fprintf(stderr, "test_SerCxSys failure\n"); + return EXIT_FAILURE; + } + + _comm_setServerSerialDriver(hComm, SerialDriverSerCx2Sys); + if (!test_generic(hComm)) + { + fprintf(stderr, "test_SerCx2Sys failure\n"); + return EXIT_FAILURE; + } + + if (!CloseHandle(hComm)) + { + fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError()); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} |