FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
TestSetCommState.c
1
20#include <stdio.h>
21#include <sys/stat.h>
22
23#include <winpr/comm.h>
24#include <winpr/crt.h>
25
26#include "../comm.h"
27
28static void init_empty_dcb(DCB* pDcb)
29{
30 WINPR_ASSERT(pDcb);
31
32 ZeroMemory(pDcb, sizeof(DCB));
33 pDcb->DCBlength = sizeof(DCB);
34 pDcb->XonChar = 1;
35 pDcb->XoffChar = 2;
36}
37
38static BOOL test_fParity(HANDLE hComm)
39{
40 DCB dcb = { 0 };
41 BOOL result = 0;
42
43 init_empty_dcb(&dcb);
44 result = GetCommState(hComm, &dcb);
45 if (!result)
46 {
47 (void)fprintf(stderr, "GetCommState failure: 0x%08" PRIx32 "\n", GetLastError());
48 return FALSE;
49 }
50
51 /* test 1 */
52 dcb.fParity = TRUE;
53 result = SetCommState(hComm, &dcb);
54 if (!result)
55 {
56 (void)fprintf(stderr, "SetCommState failure: 0x%08" PRIx32 "\n", GetLastError());
57 return FALSE;
58 }
59
60 init_empty_dcb(&dcb);
61 result = GetCommState(hComm, &dcb);
62 if (!result)
63 {
64 (void)fprintf(stderr, "GetCommState failure: 0x%08" PRIx32 "\n", GetLastError());
65 return FALSE;
66 }
67
68 if (!dcb.fParity)
69 {
70 (void)fprintf(stderr, "unexpected fParity: %" PRIu32 " instead of TRUE\n", dcb.fParity);
71 return FALSE;
72 }
73
74 /* test 2 */
75 dcb.fParity = FALSE;
76 result = SetCommState(hComm, &dcb);
77 if (!result)
78 {
79 (void)fprintf(stderr, "SetCommState failure: 0x%08" PRIx32 "\n", GetLastError());
80 return FALSE;
81 }
82
83 init_empty_dcb(&dcb);
84 result = GetCommState(hComm, &dcb);
85 if (!result)
86 {
87 (void)fprintf(stderr, "GetCommState failure: 0x%08" PRIx32 "\n", GetLastError());
88 return FALSE;
89 }
90
91 if (dcb.fParity)
92 {
93 (void)fprintf(stderr, "unexpected fParity: %" PRIu32 " instead of FALSE\n", dcb.fParity);
94 return FALSE;
95 }
96
97 /* test 3 (redo test 1) */
98 dcb.fParity = TRUE;
99 result = SetCommState(hComm, &dcb);
100 if (!result)
101 {
102 (void)fprintf(stderr, "SetCommState failure: 0x%08" PRIx32 "\n", GetLastError());
103 return FALSE;
104 }
105
106 init_empty_dcb(&dcb);
107 result = GetCommState(hComm, &dcb);
108 if (!result)
109 {
110 (void)fprintf(stderr, "GetCommState failure: 0x%08" PRIx32 "\n", GetLastError());
111 return FALSE;
112 }
113
114 if (!dcb.fParity)
115 {
116 (void)fprintf(stderr, "unexpected fParity: %" PRIu32 " instead of TRUE\n", dcb.fParity);
117 return FALSE;
118 }
119
120 return TRUE;
121}
122
123static BOOL test_SerialSys(HANDLE hComm)
124{
125 DCB dcb = { 0 };
126 BOOL result = 0;
127
128 init_empty_dcb(&dcb);
129 result = GetCommState(hComm, &dcb);
130 if (!result)
131 {
132 (void)fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError());
133 return FALSE;
134 }
135
136 /* Test 1 */
137 dcb.BaudRate = CBR_115200;
138 result = SetCommState(hComm, &dcb);
139 if (!result)
140 {
141 (void)fprintf(stderr, "SetCommState failure: 0x%08x\n", GetLastError());
142 return FALSE;
143 }
144
145 init_empty_dcb(&dcb);
146 result = GetCommState(hComm, &dcb);
147 if (!result)
148 {
149 (void)fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError());
150 return FALSE;
151 }
152 if (dcb.BaudRate != CBR_115200)
153 {
154 (void)fprintf(stderr, "SetCommState failure: could not set BaudRate=%d (CBR_115200)\n",
155 CBR_115200);
156 return FALSE;
157 }
158
159 /* Test 2 using a different baud rate */
160
161 dcb.BaudRate = CBR_57600;
162 result = SetCommState(hComm, &dcb);
163 if (!result)
164 {
165 (void)fprintf(stderr, "SetCommState failure: 0x%x\n", GetLastError());
166 return FALSE;
167 }
168
169 init_empty_dcb(&dcb);
170 result = GetCommState(hComm, &dcb);
171 if (!result)
172 {
173 (void)fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError());
174 return FALSE;
175 }
176 if (dcb.BaudRate != CBR_57600)
177 {
178 (void)fprintf(stderr, "SetCommState failure: could not set BaudRate=%d (CBR_57600)\n",
179 CBR_57600);
180 return FALSE;
181 }
182
183 /* Test 3 using an unsupported baud rate on Linux */
184 dcb.BaudRate = CBR_128000;
185 result = SetCommState(hComm, &dcb);
186 if (result)
187 {
188 (void)fprintf(stderr,
189 "SetCommState failure: unexpected support of BaudRate=%d (CBR_128000)\n",
190 CBR_128000);
191 return FALSE;
192 }
193
194 return TRUE;
195}
196
197static BOOL test_SerCxSys(HANDLE hComm)
198{
199 /* as of today there is no difference */
200 return test_SerialSys(hComm);
201}
202
203static BOOL test_SerCx2Sys(HANDLE hComm)
204{
205 /* as of today there is no difference */
206 return test_SerialSys(hComm);
207}
208
209static BOOL test_generic(HANDLE hComm)
210{
211 DCB dcb = { 0 };
212 DCB dcb2 = { 0 };
213 BOOL result = 0;
214
215 init_empty_dcb(&dcb);
216 result = GetCommState(hComm, &dcb);
217 if (!result)
218 {
219 (void)fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError());
220 return FALSE;
221 }
222
223 /* Checks whether we get the same information before and after SetCommState */
224 memcpy(&dcb2, &dcb, sizeof(DCB));
225 result = SetCommState(hComm, &dcb);
226 if (!result)
227 {
228 (void)fprintf(stderr, "SetCommState failure: 0x%08x\n", GetLastError());
229 return FALSE;
230 }
231
232 result = GetCommState(hComm, &dcb);
233 if (!result)
234 {
235 (void)fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError());
236 return FALSE;
237 }
238
239 if (memcmp(&dcb, &dcb2, sizeof(DCB)) != 0)
240 {
241 (void)fprintf(stderr,
242 "DCB is different after SetCommState() whereas it should have not changed\n");
243 return FALSE;
244 }
245
246 // TODO: a more complete and generic test using GetCommProperties()
247
248 /* TMP: TODO: fBinary tests */
249
250 /* fParity tests */
251 if (!test_fParity(hComm))
252 {
253 (void)fprintf(stderr, "test_fParity failure\n");
254 return FALSE;
255 }
256
257 return TRUE;
258}
259
260int TestSetCommState(int argc, char* argv[])
261{
262 struct stat statbuf = { 0 };
263 BOOL result = 0;
264 HANDLE hComm = NULL;
265
266 if (stat("/dev/ttyS0", &statbuf) < 0)
267 {
268 (void)fprintf(stderr, "/dev/ttyS0 not available, making the test to succeed though\n");
269 return EXIT_SUCCESS;
270 }
271
272 result = DefineCommDevice("COM1", "/dev/ttyS0");
273 if (!result)
274 {
275 (void)fprintf(stderr, "DefineCommDevice failure: 0x%x\n", GetLastError());
276 return EXIT_FAILURE;
277 }
278
279 hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
280 if (hComm == INVALID_HANDLE_VALUE)
281 {
282 (void)fprintf(stderr, "CreateFileA failure: 0x%x\n", GetLastError());
283 return EXIT_FAILURE;
284 }
285
286 if (!test_generic(hComm))
287 {
288 (void)fprintf(stderr, "test_generic failure (SerialDriverUnknown)\n");
289 return EXIT_FAILURE;
290 }
291
292 _comm_setServerSerialDriver(hComm, SerialDriverSerialSys);
293 if (!test_generic(hComm))
294 {
295 (void)fprintf(stderr, "test_generic failure (SerialDriverSerialSys)\n");
296 return EXIT_FAILURE;
297 }
298 if (!test_SerialSys(hComm))
299 {
300 (void)fprintf(stderr, "test_SerialSys failure\n");
301 return EXIT_FAILURE;
302 }
303
304 _comm_setServerSerialDriver(hComm, SerialDriverSerCxSys);
305 if (!test_generic(hComm))
306 {
307 (void)fprintf(stderr, "test_generic failure (SerialDriverSerCxSys)\n");
308 return EXIT_FAILURE;
309 }
310 if (!test_SerCxSys(hComm))
311 {
312 (void)fprintf(stderr, "test_SerCxSys failure\n");
313 return EXIT_FAILURE;
314 }
315
316 _comm_setServerSerialDriver(hComm, SerialDriverSerCx2Sys);
317 if (!test_generic(hComm))
318 {
319 (void)fprintf(stderr, "test_generic failure (SerialDriverSerCx2Sys)\n");
320 return EXIT_FAILURE;
321 }
322 if (!test_SerCx2Sys(hComm))
323 {
324 (void)fprintf(stderr, "test_SerCx2Sys failure\n");
325 return EXIT_FAILURE;
326 }
327
328 if (!CloseHandle(hComm))
329 {
330 (void)fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError());
331 return EXIT_FAILURE;
332 }
333
334 return EXIT_SUCCESS;
335}