GCC Code Coverage Report


Directory: src/gate/
File: src/gate/io/serialports.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 0 117 0.0%
Functions: 0 16 0.0%
Branches: 0 42 0.0%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/io/serialports.h"
30 #include "gate/threading.h"
31 #include "gate/results.h"
32 #include "gate/debugging.h"
33
34 #if defined(GATE_SYS_WIN16)
35 # define GATE_IO_SERIALPORTS_WIN16_IMPL 1
36 #elif defined(GATE_SYS_WIN)
37 # define GATE_IO_SERIALPORTS_WINAPI_IMPL 1
38 #elif defined(GATE_SYS_POSIX)
39 # define GATE_IO_SERIALPORTS_POSIX_IMPL 1
40 #elif defined(GATE_SYS_EFI)
41 # define GATE_IO_SERIALPORTS_EFI_IMPL 1
42 #elif defined(GATE_SYS_DOS)
43 # define GATE_IO_SERIALPORTS_DOS_IMPL 1
44 #else
45 # define GATE_IO_SERIALPORTS_NO_IMPL 1
46 #endif
47
48
49 typedef struct gate_serialport_stream
50 {
51 GATE_INTERFACE_VTBL(gate_resourcestream) const* vtbl;
52
53 gate_atomic_int_t ref_counter;
54 gate_serialport_t port_handle;
55 char buffer[4096];
56 gate_size_t buffer_used;
57
58 } gate_serialport_stream_t;
59
60 static void gate_serialport_stream_release(void* self)
61 {
62 gate_serialport_stream_t* stream = (gate_serialport_stream_t*)self;
63 if (0 == gate_atomic_int_dec(&stream->ref_counter))
64 {
65 gate_serialport_close(stream->port_handle);
66 gate_mem_dealloc(stream);
67 }
68 }
69 static int gate_serialport_stream_retain(void* self)
70 {
71 gate_serialport_stream_t* stream = (gate_serialport_stream_t*)self;
72 return gate_atomic_int_inc(&stream->ref_counter);
73 }
74 static char const* gate_serialport_stream_get_interface_name(void* self)
75 {
76 (void)self;
77 return GATE_INTERFACE_NAME_RESOURCESTREAM;
78 }
79 static gate_result_t gate_serialport_stream_peek(void* self, char* buffer, gate_size_t bufferlength, gate_size_t* returned)
80 {
81 gate_serialport_stream_t* stream = (gate_serialport_stream_t*)self;
82 gate_result_t ret;
83
84 do
85 {
86 if (stream->buffer_used == 0)
87 {
88 ret = gate_serialport_read(stream->port_handle, &stream->buffer[0], sizeof(stream->buffer), &stream->buffer_used);
89 if (GATE_FAILED(ret))
90 {
91 stream->buffer_used = 0;
92 if (ret != GATE_RESULT_NODATA)
93 {
94 break;
95 }
96 }
97 }
98
99 ret = GATE_RESULT_OK;
100
101 if (stream->buffer_used != 0)
102 {
103 if (bufferlength > stream->buffer_used)
104 {
105 bufferlength = stream->buffer_used;
106 }
107 gate_mem_copy(buffer, &stream->buffer[0], bufferlength);
108 }
109 else
110 {
111 bufferlength = 0;
112 }
113
114 if (returned != NULL)
115 {
116 *returned = bufferlength;
117 }
118 } while (0);
119
120 return ret;
121 }
122 static gate_result_t gate_serialport_stream_read(void* self, char* buffer, gate_size_t bufferlength, gate_size_t* returned)
123 {
124 gate_serialport_stream_t* stream = (gate_serialport_stream_t*)self;
125 gate_result_t ret;
126 gate_size_t bytesreceived = 0;
127 gate_uint32_t delay = 0;
128 static gate_uint32_t const max_delay = 50;
129 while (bytesreceived == 0)
130 {
131 ret = gate_serialport_stream_peek(self, buffer, bufferlength, &bytesreceived);
132 if (GATE_FAILED(ret))
133 {
134 break;
135 }
136 else
137 {
138 if (bytesreceived == 0)
139 {
140 gate_thread_sleep(delay);
141 if (delay < max_delay)
142 {
143 ++delay;
144 }
145 }
146 else
147 {
148 if (bytesreceived < stream->buffer_used)
149 {
150 gate_mem_move(&stream->buffer[0], &stream->buffer[bytesreceived], stream->buffer_used - bytesreceived);
151 stream->buffer_used -= bytesreceived;
152 }
153 else
154 {
155 stream->buffer_used = 0;
156 }
157 }
158 }
159 }
160 if (returned != NULL)
161 {
162 *returned = bytesreceived;
163 }
164 return ret;
165 }
166
167 static gate_result_t gate_serialport_stream_write(void* self, char const* buffer, gate_size_t bufferlength, gate_size_t* written)
168 {
169 gate_serialport_stream_t* stream = (gate_serialport_stream_t*)self;
170 return gate_serialport_write(stream->port_handle, buffer, bufferlength, written);
171 }
172 static gate_result_t gate_serialport_stream_flush(void* self)
173 {
174 (void)self;
175 return GATE_RESULT_OK;
176 }
177
178 static gate_result_t gate_serialport_stream_get_resource(void* self, gate_enumint_t resource_type, gate_uintptr_t* resource)
179 {
180 gate_result_t ret = GATE_RESULT_OK;
181 gate_serialport_stream_t* stream = (gate_serialport_stream_t*)self;
182
183 switch (resource_type)
184 {
185 case GATE_STREAM_RESOURCE_DEFAULT:
186 case GATE_STREAM_RESOURCE_INPUT:
187 case GATE_STREAM_RESOURCE_OUTPUT: *resource = (gate_uintptr_t)stream->port_handle;
188 default:
189 ret = GATE_RESULT_NOTSUPPORTED;
190 }
191 return ret;
192 }
193
194 static GATE_INTERFACE_VTBL(gate_resourcestream) gate_serialport_stream_vtbl;
195 static void gate_init_serialport_stream_vtbl()
196 {
197 if (!gate_serialport_stream_vtbl.get_interface_name)
198 {
199 GATE_INTERFACE_VTBL(gate_resourcestream) const local_vtbl =
200 {
201 &gate_serialport_stream_get_interface_name,
202 &gate_serialport_stream_release,
203 &gate_serialport_stream_retain,
204
205 &gate_serialport_stream_read,
206 &gate_serialport_stream_peek,
207 &gate_serialport_stream_write,
208 &gate_serialport_stream_flush,
209
210 &gate_serialport_stream_get_resource
211 };
212 gate_serialport_stream_vtbl = local_vtbl;
213 }
214 }
215
216 gate_result_t gate_serialport_openstream(
217 gate_string_t const* port_id, gate_uint32_t baudrate,
218 gate_enumint_t bits, gate_enumint_t parity, gate_enumint_t stopbits, gate_enumint_t flowcontrol,
219 gate_stream_t** stream)
220 {
221 gate_result_t ret;
222 gate_serialport_stream_t* ptr;
223
224 ptr = (gate_serialport_stream_t*)gate_mem_alloc(sizeof(gate_serialport_stream_t));
225 if (ptr == NULL)
226 {
227 ret = GATE_RESULT_OUTOFMEMORY;
228 }
229 else
230 {
231 gate_mem_clear(ptr, sizeof(gate_serialport_stream_t));
232 gate_init_serialport_stream_vtbl();
233 ptr->vtbl = &gate_serialport_stream_vtbl;
234 gate_atomic_int_init(&ptr->ref_counter, 1);
235 ptr->buffer_used = 0;
236 ret = gate_serialport_open(port_id, baudrate, bits, parity, stopbits, flowcontrol, 0, false, &ptr->port_handle);
237 if (GATE_FAILED(ret))
238 {
239 gate_mem_dealloc(ptr);
240 }
241 else
242 {
243 *stream = (gate_stream_t*)ptr;
244 }
245 }
246 return ret;
247 }
248
249
250 #if defined(GATE_SYS_WIN)
251
252 #include "gate/platforms.h"
253
254 static gate_result_t winapi_setup_comm(HANDLE hfile, DCB* dcb,
255 gate_uint32_t baudrate, unsigned bits, unsigned parity, unsigned stopbits,
256 unsigned flowcontrol, gate_uint32_t timeout, gate_bool_t asynchronous)
257 {
258 gate_result_t ret = GATE_RESULT_FAILED;
259
260 do
261 {
262 #if !defined(GATE_SYS_WIN16)
263 dcb->DCBlength = sizeof(dcb);
264 #endif
265 if (FALSE == GetCommState(hfile, dcb))
266 {
267 gate_win32_print_lasterror(&ret, NULL, 0);
268 break;
269 }
270 if (baudrate != 0)
271 {
272 dcb->BaudRate = baudrate;
273 }
274 dcb->ByteSize = (BYTE)bits;
275 dcb->fParity = TRUE;
276 dcb->fNull = FALSE;
277 dcb->fBinary = TRUE;
278 #if !defined(GATE_SYS_WIN16)
279 dcb->fAbortOnError = FALSE;
280 #endif
281
282 switch (parity)
283 {
284 case GATE_SERIALPORT_PARITY_ODD: { dcb->Parity = ODDPARITY; break; }
285 case GATE_SERIALPORT_PARITY_EVEN: { dcb->Parity = EVENPARITY; break; }
286 case GATE_SERIALPORT_PARITY_MARK: { dcb->Parity = MARKPARITY; break; }
287 case GATE_SERIALPORT_PARITY_SPACE: { dcb->Parity = SPACEPARITY; break; }
288 case GATE_SERIALPORT_PARITY_NONE:
289 default: { dcb->Parity = NOPARITY; break; }
290 }
291
292 switch (stopbits)
293 {
294 case GATE_SERIALPORT_STOPBITS_1_5: { dcb->StopBits = ONE5STOPBITS; break; }
295 case GATE_SERIALPORT_STOPBITS_2_0: { dcb->StopBits = TWOSTOPBITS; break; }
296 case GATE_SERIALPORT_STOPBITS_1_0:
297 default: { dcb->StopBits = ONESTOPBIT; break; }
298 }
299
300 switch (flowcontrol)
301 {
302 case GATE_SERIALPORT_FLOWCTRL_HARDWARE:
303 {
304 dcb->fInX = FALSE;
305 dcb->fOutX = FALSE;
306 dcb->fOutxDsrFlow = FALSE;
307 dcb->fOutxCtsFlow = FALSE;
308 #if defined(GATE_SYS_WIN16)
309 dcb->fDtrDisable = 0;
310 dcb->fRtsDisable = 0;
311 #else
312 dcb->fDtrControl = DTR_CONTROL_ENABLE;
313 dcb->fRtsControl = RTS_CONTROL_ENABLE;
314 #endif
315 break;
316 }
317 case GATE_SERIALPORT_FLOWCTRL_HANDSHAKE:
318 {
319 dcb->fInX = FALSE;
320 dcb->fOutX = FALSE;
321 dcb->fOutxDsrFlow = FALSE;
322 dcb->fOutxCtsFlow = FALSE;
323 #if defined(GATE_SYS_WIN16)
324 dcb->fDtrDisable = 0;
325 dcb->fRtsDisable = 0;
326 #else
327 dcb->fDtrControl = DTR_CONTROL_HANDSHAKE;
328 dcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
329 #endif
330 break;
331 }
332 case GATE_SERIALPORT_FLOWCTRL_XON:
333 {
334 dcb->fInX = TRUE;
335 dcb->fOutX = TRUE;
336 dcb->fOutxDsrFlow = FALSE;
337 dcb->fOutxCtsFlow = FALSE;
338 #if defined(GATE_SYS_WIN16)
339 dcb->fDtrDisable = 1;
340 dcb->fRtsDisable = 1;
341 #else
342 dcb->fDtrControl = DTR_CONTROL_DISABLE;
343 dcb->fRtsControl = RTS_CONTROL_DISABLE;
344 #endif
345 break;
346 }
347 case GATE_SERIALPORT_FLOWCTRL_NONE:
348 default:
349 {
350 dcb->fInX = FALSE;
351 dcb->fOutX = FALSE;
352 dcb->fOutxDsrFlow = FALSE;
353 dcb->fOutxCtsFlow = FALSE;
354 #if defined(GATE_SYS_WIN16)
355 dcb->fDtrDisable = 1;
356 dcb->fRtsDisable = 1;
357 #else
358 dcb->fDtrControl = DTR_CONTROL_DISABLE;
359 dcb->fRtsControl = RTS_CONTROL_DISABLE;
360 #endif
361 break;
362 }
363 }
364
365 #if defined(GATE_SYS_WIN16)
366 if (0 != SetCommState(dcb))
367 #else
368 if (FALSE == SetCommState(hfile, dcb))
369 #endif
370 {
371 gate_win32_print_lasterror(&ret, NULL, 0);
372 break;
373 }
374 ret = GATE_RESULT_OK;
375 } while (0);
376
377 return ret;
378 }
379
380 #endif
381
382
383 #if defined(GATE_IO_SERIALPORTS_WIN16_IMPL)
384
385 #define GATE_IO_SERIALPORTS_DEFAULT_READ_BUFFER 1024
386 #define GATE_IO_SERIALPORTS_DEFAULT_WRITE_BUFFER 128
387
388 #include "tchar.h"
389
390 gate_result_t gate_serialport_enum(gate_serialport_enum_callback_t callback, void* userparam)
391 {
392 return GATE_RESULT_NOTSUPPORTED;
393 }
394
395 gate_result_t gate_serialport_open(
396 gate_string_t const* port_id, gate_uint32_t baudrate,
397 gate_enumint_t bits, gate_enumint_t parity, gate_enumint_t stopbits, gate_enumint_t flowcontrol,
398 gate_uint32_t timeout, gate_bool_t asynchronous, gate_serialport_t* port_handle)
399 {
400 gate_result_t ret = GATE_RESULT_FAILED;
401 char port_name[256];
402 int handle = -1;
403 DCB dcb;
404 do
405 {
406 handle = OpenComm(port_name, GATE_IO_SERIALPORTS_DEFAULT_READ_BUFFER, GATE_IO_SERIALPORTS_DEFAULT_WRITE_BUFFER);
407 if (handle < 0)
408 {
409 ret = GATE_RESULT_FAILED;
410 break;
411 }
412
413 ret = winapi_setup_comm(handle, &dcb, baudrate, bits, parity, stopbits, flowcontrol, timeout, asynchronous);
414 GATE_BREAK_IF_FAILED(ret);
415
416 if (port_handle)
417 {
418 *port_handle = (gate_serialport_t)handle;
419 handle = -1;
420 }
421 ret = GATE_RESULT_OK;
422 } while (0);
423
424 if (handle >= 0)
425 {
426 CloseComm(handle);
427 }
428
429 return ret;
430 }
431
432 gate_result_t gate_serialport_close(gate_serialport_t port_handle)
433 {
434 int handle = (int)port_handle;
435 if (handle < 0)
436 {
437 return GATE_RESULT_INVALIDARG;
438 }
439 else
440 {
441 CloseComm(handle);
442 return GATE_RESULT_OK;
443 }
444
445 }
446 gate_result_t gate_serialport_read(gate_serialport_t port_handle, char* buffer, gate_size_t bufferlen, gate_size_t* bytesreceived)
447 {
448 int handle = (int)port_handle;
449 int result;
450
451 if (bufferlen > GATE_IO_SERIALPORTS_DEFAULT_READ_BUFFER)
452 {
453 bufferlen = GATE_IO_SERIALPORTS_DEFAULT_READ_BUFFER;
454 }
455 result = ReadComm(handle, &buffer[0], (int)bufferlen);
456 if (result < 0)
457 {
458 if (bytesreceived)
459 {
460 *bytesreceived = (gate_size_t)(-result);
461 }
462 return GATE_RESULT_FAILED;
463 }
464 else
465 {
466 if (bytesreceived)
467 {
468 *bytesreceived = (gate_size_t)result;
469
470 }
471 return GATE_RESULT_OK;
472 }
473 }
474 gate_result_t gate_serialport_write(gate_serialport_t port_handle, char const* buffer, gate_size_t bufferlen, gate_size_t* byteswritten)
475 {
476 int handle = (int)port_handle;
477 int result;
478
479 if (bufferlen > GATE_IO_SERIALPORTS_DEFAULT_WRITE_BUFFER)
480 {
481 bufferlen = GATE_IO_SERIALPORTS_DEFAULT_WRITE_BUFFER;
482 }
483 result = WriteComm(handle, &buffer[0], (int)bufferlen);
484 if (result < 0)
485 {
486 if (byteswritten)
487 {
488 *byteswritten = (gate_size_t)(-result);
489 }
490 return GATE_RESULT_FAILED;
491 }
492 else
493 {
494 if (byteswritten)
495 {
496 *byteswritten = (gate_size_t)result;
497 }
498 return GATE_RESULT_OK;
499 }
500 }
501
502
503 #endif /* GATE_IO_SERIALPORTS_WIN16_IMPL */
504
505
506
507 #if defined(GATE_IO_SERIALPORTS_WINAPI_IMPL)
508
509 # include "gate/platforms.h"
510 # include "gate/platform/windows/win32registry.h"
511
512
513 #if defined(GATE_SYS_WINCE)
514
515 typedef struct
516 {
517 gate_serialport_enum_callback_t callback;
518 void* userparam;
519 //gate_win32_registry_enum_keys
520
521 } gate_serialport_enum_registry_param_t;
522
523 static gate_bool_t gate_serialport_enum_registry_callback(LPCTSTR base_path, LPCTSTR sub_path, void* userparam)
524 {
525 gate_bool_t ret = true;
526 gate_serialport_enum_registry_param_t* param = (gate_serialport_enum_registry_param_t*)userparam;
527 gate_result_t result;
528 char com_name[GATE_MAX_FILENAME_LENGTH];
529 gate_size_t com_name_used;
530 TCHAR com_key[GATE_MAX_FILEPATH_LENGTH];
531 gate_size_t com_key_used;
532 char com_descr[GATE_MAX_FILENAME_LENGTH];
533 gate_size_t com_descr_used = sizeof(com_descr);
534
535 do
536 {
537 result = gate_win32_registry_read_str(GATE_WIN32_REGISTRY_LOCALMACHINE, sub_path, _T("Name"),
538 com_name, sizeof(com_name), &com_name_used);
539 if (GATE_FAILED(result))
540 {
541 break;
542 }
543
544 if (0 != gate_str_pos(com_name, com_name_used, "COM", 3, 0))
545 {
546 break;
547 }
548
549 com_key[0] = 0;
550 com_descr[0] = 0;
551
552 result = gate_win32_registry_read_winstr(GATE_WIN32_REGISTRY_LOCALMACHINE, sub_path, _T("Key"),
553 com_key, sizeof(com_key) / sizeof(com_key[0]), &com_key_used);
554 if (GATE_SUCCEEDED(result))
555 {
556 gate_win32_registry_read_str(GATE_WIN32_REGISTRY_LOCALMACHINE, com_key, _T("FriendlyName"),
557 com_descr, sizeof(com_descr), &com_descr_used);
558 }
559
560 if (param->callback)
561 {
562 ret = param->callback(com_name, com_descr, param->userparam);
563 }
564 } while (0);
565 return ret;
566 }
567
568
569 gate_result_t gate_serialport_enum(gate_serialport_enum_callback_t callback, void* userparam)
570 {
571 gate_result_t ret = GATE_RESULT_OK;
572 gate_serialport_enum_registry_param_t param;
573
574 param.callback = callback;
575 param.userparam = userparam;
576
577 ret = gate_win32_registry_enum_keys(GATE_WIN32_REGISTRY_LOCALMACHINE, _T("Drivers\\Active\\"),
578 &gate_serialport_enum_registry_callback, &param);
579
580 return ret;
581 }
582
583 #elif defined(GATE_SYS_WINSTORE) /* defined(GATE_SYS_WINCE) */
584
585 gate_result_t gate_serialport_enum(gate_serialport_enum_callback_t callback, void* userparam)
586 {
587 return GATE_RESULT_NOTSUPPORTED;
588 }
589
590 #else /* defined(GATE_SYS_WINSTORE) */
591
592 # include <setupapi.h>
593
594 gate_result_t gate_serialport_enum(gate_serialport_enum_callback_t callback, void* userparam)
595 {
596 gate_result_t ret = GATE_RESULT_FAILED;
597 DWORD dwClassCount = 0;
598 DWORD ndxClass;
599 DWORD ndxInfo;
600 GUID classGuids[256];
601 HDEVINFO hdevinfo;
602 SP_DEVINFO_DATA devinfo_data;
603 HKEY hKey;
604 DWORD dwType;
605 TCHAR buffer[GATE_MAX_FILENAME_LENGTH * 2];
606 DWORD bufferlen;
607 char portid[GATE_MAX_FILENAME_LENGTH * 2];
608 char descr[GATE_MAX_FILENAME_LENGTH * 2];
609 gate_bool_t continueEnum = true;
610 gate_win32_setupapi_t const* const setupapi = gate_win32_setupapi();
611
612 do
613 {
614 if ((setupapi->SetupApiDiDestroyDeviceInfoList == NULL)
615 || (setupapi->SetupApiDiGetClassDevs == NULL)
616 || (setupapi->SetupApiDiEnumDeviceInfo == NULL)
617 || (setupapi->SetupApiDiGetDeviceRegistryProperty == NULL)
618 || (setupapi->SetupApiDiClassGuidsFromName == NULL)
619 || (setupapi->SetupApiDiOpenDevRegKey == NULL)
620 || (gate_platform.AdvRegQueryValueEx == NULL)
621 || (gate_platform.AdvRegCloseKey == NULL)
622 )
623 {
624 ret = GATE_RESULT_NOTSUPPORTED;
625 break;
626 }
627
628 if (!setupapi->SetupApiDiClassGuidsFromName(_T("Ports"), classGuids, sizeof(classGuids) / sizeof(classGuids[0]), &dwClassCount))
629 {
630 ret = GATE_RESULT_FAILED;
631 break;
632 }
633
634 devinfo_data.cbSize = sizeof(devinfo_data);
635
636 for (ndxClass = 0; continueEnum && (ndxClass != dwClassCount); ++ndxClass)
637 {
638 hdevinfo = (HDEVINFO)setupapi->SetupApiDiGetClassDevs(&classGuids[ndxClass], NULL, NULL, DIGCF_PRESENT);
639 if (INVALID_HANDLE_VALUE == hdevinfo)
640 {
641 continue;
642 }
643
644 for (ndxInfo = 0; continueEnum && setupapi->SetupApiDiEnumDeviceInfo(hdevinfo, ndxInfo, &devinfo_data); ++ndxInfo)
645 {
646 hKey = setupapi->SetupApiDiOpenDevRegKey(hdevinfo, &devinfo_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
647 if (hKey == INVALID_HANDLE_VALUE)
648 {
649 continue;
650 }
651
652 dwType = 0;
653 bufferlen = sizeof(buffer) - sizeof(buffer[0]);
654
655 if (ERROR_SUCCESS == gate_platform.AdvRegQueryValueEx(hKey, _T("PortName"), NULL, &dwType, (LPBYTE)buffer, &bufferlen))
656 {
657 if (REG_SZ == dwType)
658 {
659 buffer[bufferlen / sizeof(TCHAR)] = 0;
660 }
661 if (0 != gate_win32_winstr_2_utf8(buffer, bufferlen / sizeof(TCHAR), portid, sizeof(portid)))
662 {
663 if (setupapi->SetupApiDiGetDeviceRegistryProperty(hdevinfo, &devinfo_data, SPDRP_FRIENDLYNAME, NULL, (PBYTE)&buffer[0], sizeof(buffer), &bufferlen))
664 {
665 gate_win32_winstr_2_utf8(buffer, bufferlen / sizeof(TCHAR), descr, sizeof(descr));
666 }
667 else
668 {
669 descr[0] = 0;
670 }
671 continueEnum &= callback(portid, descr, userparam);
672 }
673 }
674 gate_platform.AdvRegCloseKey(hKey);
675 }
676 setupapi->SetupApiDiDestroyDeviceInfoList(hdevinfo);
677 ret = GATE_RESULT_OK;
678 }
679 } while (0);
680 return ret;
681 }
682 #endif
683
684
685 gate_result_t gate_serialport_open(
686 gate_string_t const* port_id, gate_uint32_t baudrate,
687 gate_enumint_t bits, gate_enumint_t parity, gate_enumint_t stopbits, gate_enumint_t flowcontrol,
688 gate_uint32_t timeout, gate_bool_t asynchronous, gate_serialport_t* port_handle)
689 {
690 gate_result_t ret;
691 TCHAR path[GATE_MAX_FILENAME_LENGTH * 2] = _T("\\\\.\\");
692 HANDLE hfile = INVALID_HANDLE_VALUE;
693 DCB dcb;
694 #if !defined(GATE_SYS_WIN16)
695 COMMTIMEOUTS cto;
696 #endif
697
698 do
699 {
700 gate_win32_utf8_2_winstr(port_id->str, port_id->length, &path[4], sizeof(path) / sizeof(path[0]) - 5);
701 hfile = gate_win32_createfile(path, GENERIC_READ | GENERIC_WRITE, 0, OPEN_EXISTING, 0,
702 (asynchronous ? FILE_FLAG_OVERLAPPED : 0), NULL);
703 if (hfile == INVALID_HANDLE_VALUE)
704 {
705 gate_win32_print_lasterror(&ret, NULL, 0);
706 break;
707 }
708
709 ret = winapi_setup_comm(hfile, &dcb, baudrate, bits, parity, stopbits, flowcontrol, timeout, asynchronous);
710 GATE_BREAK_IF_FAILED(ret);
711
712 if (timeout != 0)
713 {
714 #if !defined(GATE_SYS_WIN16)
715 if (GetCommTimeouts(hfile, &cto))
716 {
717 cto.ReadIntervalTimeout = 0;
718 cto.ReadTotalTimeoutMultiplier = 0;
719 cto.ReadTotalTimeoutConstant = 10;
720
721 /*
722 cto.ReadIntervalTimeout = MAXDWORD;
723 cto.ReadTotalTimeoutConstant = timeout;
724 cto.ReadIntervalTimeout = 0;
725 cto.ReadTotalTimeoutMultiplier = 0;
726 cto.ReadTotalTimeoutConstant = 0;
727 */
728
729 cto.WriteTotalTimeoutMultiplier = 1;
730 cto.WriteTotalTimeoutConstant = 1;
731 /*
732 cto.WriteTotalTimeoutConstant = readTimeout ? *readTimeout : 100;
733 */
734
735 SetCommTimeouts(hfile, &cto);
736 }
737 #endif
738 }
739 /*
740 SetCommMask(hfile, EV_RXCHAR | EV_TXEMPTY);
741 */
742
743 *port_handle = (gate_serialport_t)hfile;
744 hfile = INVALID_HANDLE_VALUE;
745 ret = GATE_RESULT_OK;
746 } while (0);
747
748 if ((hfile != INVALID_HANDLE_VALUE) && (hfile != (HANDLE)NULL))
749 {
750 CloseHandle(hfile);
751 }
752
753 return ret;
754 }
755 gate_result_t gate_serialport_close(gate_serialport_t port_handle)
756 {
757 HANDLE hfile = (HANDLE)port_handle;
758 /*
759 SetCommMask(hfile, 0);
760 */
761 CloseHandle(hfile);
762 return GATE_RESULT_OK;
763 }
764 gate_result_t gate_serialport_read(gate_serialport_t port_handle, char* buffer, gate_size_t bufferlen, gate_size_t* bytesreceived)
765 {
766 gate_result_t ret;
767 HANDLE hfile = (HANDLE)port_handle;
768 DWORD bytesread;
769 DWORD dwError = 0;
770 COMSTAT status = GATE_INIT_EMPTY;
771
772 do
773 {
774 if (ClearCommError(hfile, &dwError, &status))
775 {
776 if (status.cbInQue == 0)
777 {
778 ret = GATE_RESULT_NODATA;
779 break;
780 }
781 if (status.cbInQue < bufferlen)
782 {
783 bufferlen = (gate_size_t)status.cbInQue;
784 }
785 }
786 if (FALSE == gate_win32_readfile(hfile, buffer, (DWORD)bufferlen, &bytesread, NULL))
787 {
788 gate_win32_print_lasterror(&ret, NULL, 0);
789 break;
790 }
791 if (bytesreceived != NULL)
792 {
793 *bytesreceived = (gate_size_t)bytesread;
794 }
795 ret = GATE_RESULT_OK;
796
797 } while (0);
798
799 return ret;
800 }
801
802 gate_result_t gate_serialport_write(gate_serialport_t port_handle, char const* buffer, gate_size_t bufferlen, gate_size_t* byteswritten)
803 {
804 gate_result_t ret;
805 HANDLE hfile = (HANDLE)port_handle;
806 DWORD written;
807
808 do
809 {
810 if (FALSE == gate_win32_writefile(hfile, buffer, (DWORD)bufferlen, &written, NULL))
811 {
812 gate_win32_print_lasterror(&ret, NULL, 0);
813 break;
814 }
815 if (byteswritten != NULL)
816 {
817 *byteswritten = (gate_size_t)written;
818 }
819 ret = GATE_RESULT_OK;
820 } while (0);
821
822 return ret;
823 }
824
825 #endif /* GATE_IO_SERIALPORTS_WINAPI_IMPL */
826
827
828
829
830 #if defined(GATE_IO_SERIALPORTS_POSIX_IMPL)
831
832 #include "gate/platforms.h"
833 #include "gate/files.h"
834
835 #include <termios.h>
836
837 struct gate_serialport_enum_dir_param
838 {
839 gate_serialport_enum_callback_t callback;
840 void* callback_param;
841 };
842
843 static gate_bool_t gate_serialport_enum_dir_cb(gate_file_entry_t const* entry, void* userparam)
844 {
845 struct gate_serialport_enum_dir_param* param = (struct gate_serialport_enum_dir_param*)userparam;
846 char path[4096];
847 gate_result_t result;
848 gate_string_t sub_dir_path;
849 gate_string_create_static(&sub_dir_path, entry->path);
850
851 result = gate_file_exists(&sub_dir_path);
852 if (GATE_SUCCEEDED(result))
853 {
854 gate_file_build_path(path, sizeof(path), sub_dir_path.str, sub_dir_path.length, "device", 6);
855 //TODO: implementation
856 }
857 return true;
858 }
859
860 gate_result_t gate_serialport_enum(gate_serialport_enum_callback_t callback, void* userparam)
861 {
862 gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED;
863 static gate_string_t const sys_dir = { "/sys/class/tty", 14, NULL };
864 struct gate_serialport_enum_dir_param param;
865
866 param.callback = callback;
867 param.callback_param = userparam;
868
869 ret = gate_file_list(&sys_dir, &gate_serialport_enum_dir_cb, &param);
870 return ret;
871 }
872
873 gate_result_t gate_serialport_open(
874 gate_string_t const* port_id, gate_uint32_t baudrate,
875 gate_enumint_t bits, gate_enumint_t parity, gate_enumint_t stopbits, gate_enumint_t flowcontrol,
876 gate_uint32_t timeout, gate_bool_t asynchronous, gate_serialport_t* port_handle)
877 {
878 gate_result_t ret = GATE_RESULT_FAILED;
879 char path[GATE_MAX_FILEPATH_LENGTH] = GATE_INIT_EMPTY;
880 gate_platform_stream_t stream;
881 int fd;
882 struct termios term_info;
883
884 do
885 {
886 gate_platform_stream_set_invalid(&stream);
887 gate_string_to_buffer(port_id, path, sizeof(path));
888 ret = gate_platform_stream_open(path, GATE_PLATFORM_STREAM_OPEN_READWRITE, 0, &stream);
889 GATE_BREAK_IF_FAILED(ret);
890
891 fd = (int)(gate_intptr_t)stream;
892
893 if (0 != tcgetattr(fd, &term_info))
894 {
895
896 }
897
898 if (port_handle)
899 {
900 *port_handle = stream;
901 gate_platform_stream_set_invalid(&stream);
902 }
903 ret = GATE_RESULT_OK;
904 } while (0);
905
906 if (gate_platform_stream_valid(stream))
907 {
908 gate_platform_stream_close(stream);
909 }
910
911 return ret;
912 }
913 gate_result_t gate_serialport_close(gate_serialport_t port_handle)
914 {
915 gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED;
916
917 return ret;
918 }
919 gate_result_t gate_serialport_read(gate_serialport_t port_handle, char* buffer, gate_size_t bufferlen, gate_size_t* bytesreceived)
920 {
921 gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED;
922
923 return ret;
924 }
925 gate_result_t gate_serialport_write(gate_serialport_t port_handle, char const* buffer, gate_size_t bufferlen, gate_size_t* byteswritten)
926 {
927 gate_result_t ret = GATE_RESULT_NOTIMPLEMENTED;
928
929 return ret;
930 }
931
932
933 #endif /* GATE_IO_SERIALPORTS_POSIX_IMPL */
934
935
936
937
938 #if defined(GATE_IO_SERIALPORTS_EFI_IMPL)
939
940 #include "gate/platform/efi/efi_gate.h"
941
942 static char const* const gate_serial_port_efi_id = "COM";
943
944 gate_result_t gate_serialport_enum(gate_serialport_enum_callback_t callback, void* userparam)
945 {
946 gate_result_t result;
947 void* ser_port = NULL;
948
949 result = gate_platform_efi_serport_get(&ser_port);
950 if (GATE_SUCCEEDED(result))
951 {
952 if (callback)
953 {
954 callback(gate_serial_port_efi_id, "EFI Serial Port", userparam);
955 }
956 }
957 return result;
958 }
959
960 #define GATE_SERIALPORT_PARITY_NONE 0
961 #define GATE_SERIALPORT_PARITY_ODD 1
962 #define GATE_SERIALPORT_PARITY_EVEN 2
963 #define GATE_SERIALPORT_PARITY_MARK 3
964 #define GATE_SERIALPORT_PARITY_SPACE 4
965
966 #define GATE_SERIALPORT_STOPBITS_1_0 10
967 #define GATE_SERIALPORT_STOPBITS_1_5 15
968 #define GATE_SERIALPORT_STOPBITS_2_0 20
969
970 gate_result_t gate_serialport_open(
971 gate_string_t const* port_id, gate_uint32_t baudrate,
972 gate_enumint_t bits, gate_enumint_t parity, gate_enumint_t stopbits, gate_enumint_t flowcontrol,
973 gate_uint32_t timeout_ms, gate_bool_t asynchronous, gate_serialport_t* port_handle)
974 {
975 gate_result_t ret = GATE_RESULT_FAILED;
976 void* efi_ser_port = NULL;
977 gate_uint8_t efi_parity = GATE_PLATFORM_EFI_SERIAL_PARITY_DEFAULT;
978 gate_uint8_t efi_stopbits = GATE_PLATFORM_EFI_SERIAL_STOPBITS_DEFAULT;
979
980 do
981 {
982 if (!gate_string_equals_str(port_id, gate_serial_port_efi_id))
983 {
984 ret = GATE_RESULT_NOMATCH;
985 break;
986 }
987
988 ret = gate_platform_efi_serport_get(&efi_ser_port);
989 GATE_BREAK_IF_FAILED(ret);
990
991 switch (parity)
992 {
993 case GATE_SERIALPORT_PARITY_NONE: efi_parity = GATE_PLATFORM_EFI_SERIAL_PARITY_NO; break;
994 case GATE_SERIALPORT_PARITY_ODD: efi_parity = GATE_PLATFORM_EFI_SERIAL_PARITY_ODD; break;
995 case GATE_SERIALPORT_PARITY_EVEN: efi_parity = GATE_PLATFORM_EFI_SERIAL_PARITY_EVEN; break;
996 case GATE_SERIALPORT_PARITY_MARK: efi_parity = GATE_PLATFORM_EFI_SERIAL_PARITY_MARK; break;
997 case GATE_SERIALPORT_PARITY_SPACE: efi_parity = GATE_PLATFORM_EFI_SERIAL_PARITY_SPACE; break;
998 }
999
1000 switch (stopbits)
1001 {
1002 case GATE_SERIALPORT_STOPBITS_1_0: efi_stopbits = GATE_PLATFORM_EFI_SERIAL_STOPBITS_1; break;
1003 case GATE_SERIALPORT_STOPBITS_1_5: efi_stopbits = GATE_PLATFORM_EFI_SERIAL_STOPBITS_15; break;
1004 case GATE_SERIALPORT_STOPBITS_2_0: efi_stopbits = GATE_PLATFORM_EFI_SERIAL_STOPBITS_2; break;
1005 }
1006
1007 ret = gate_platform_efi_serport_setup(efi_ser_port, baudrate, timeout_ms * 1000, efi_parity, bits, efi_stopbits);
1008 GATE_BREAK_IF_FAILED(ret);
1009
1010 if (port_handle)
1011 {
1012 *port_handle = efi_ser_port;
1013 }
1014 ret = GATE_RESULT_OK;
1015
1016 } while (0);
1017
1018 return ret;
1019 }
1020
1021 gate_result_t gate_serialport_close(gate_serialport_t port_handle)
1022 {
1023 (void)port_handle;
1024 return GATE_RESULT_OK;
1025 }
1026
1027 gate_result_t gate_serialport_read(gate_serialport_t port_handle, char* buffer, gate_size_t bufferlen, gate_size_t* bytesreceived)
1028 {
1029 gate_size_t received = 0;
1030 gate_result_t result = gate_platform_efi_serport_read(port_handle, (void*)buffer, bufferlen, &received);
1031 if (GATE_SUCCEEDED(result))
1032 {
1033 if (bytesreceived)
1034 {
1035 *bytesreceived = received;
1036 }
1037 if (received == 0)
1038 {
1039 result = GATE_RESULT_NODATA;
1040 }
1041 }
1042 else if (result == GATE_RESULT_TIMEOUT)
1043 {
1044 if (bytesreceived)
1045 {
1046 *bytesreceived = 0;
1047 }
1048 result = GATE_RESULT_NODATA;
1049 }
1050 return result;
1051 }
1052
1053 gate_result_t gate_serialport_write(gate_serialport_t port_handle, char const* buffer, gate_size_t bufferlen, gate_size_t* byteswritten)
1054 {
1055 return gate_platform_efi_serport_write(port_handle, (void const*)buffer, bufferlen, byteswritten);
1056 }
1057
1058 #endif /* GATE_IO_SERIALPORTS_EFI_IMPL */
1059
1060
1061 #if defined(GATE_IO_SERIALPORTS_DOS_IMPL)
1062
1063 #include <bios.h>
1064 #include "gate/times.h"
1065
1066 static gate_string_t const port_id_com1 = GATE_STRING_INIT_STATIC("COM1");
1067 static gate_string_t const port_id_com2 = GATE_STRING_INIT_STATIC("COM2");
1068 static gate_string_t const port_id_com3 = GATE_STRING_INIT_STATIC("COM3");
1069 static gate_string_t const port_id_com4 = GATE_STRING_INIT_STATIC("COM4");
1070 static gate_uint32_t port_timeout[4] = { 0 };
1071
1072 gate_result_t gate_serialport_enum(gate_serialport_enum_callback_t callback, void* userparam)
1073 {
1074 if (callback)
1075 {
1076 callback(port_id_com1.str, port_id_com1.str, userparam);
1077 callback(port_id_com2.str, port_id_com2.str, userparam);
1078 callback(port_id_com3.str, port_id_com3.str, userparam);
1079 callback(port_id_com4.str, port_id_com4.str, userparam);
1080 }
1081 return GATE_RESULT_OK;
1082 }
1083
1084 gate_result_t gate_serialport_open(
1085 gate_string_t const* port_id, gate_uint32_t baudrate,
1086 gate_enumint_t bits, gate_enumint_t parity, gate_enumint_t stopbits, gate_enumint_t flowcontrol,
1087 gate_uint32_t timeout_ms, gate_bool_t asynchronous, gate_serialport_t* port_handle)
1088 {
1089 unsigned config = 0;
1090 unsigned port = 0;
1091
1092 if (gate_string_equals(port_id, &port_id_com1))
1093 {
1094 port = 0;
1095 }
1096 else if (gate_string_equals(port_id, &port_id_com2))
1097 {
1098 port = 1;
1099 }
1100 else if (gate_string_equals(port_id, &port_id_com3))
1101 {
1102 port = 2;
1103 }
1104 else if (gate_string_equals(port_id, &port_id_com4))
1105 {
1106 port = 3;
1107 }
1108 else
1109 {
1110 return GATE_RESULT_INVALIDARG;
1111 }
1112
1113 if (asynchronous)
1114 {
1115 return GATE_RESULT_INVALIDARG;
1116 }
1117
1118 switch (flowcontrol)
1119 {
1120 case GATE_SERIALPORT_FLOWCTRL_NONE:
1121 break;
1122 default:
1123 return GATE_RESULT_INVALIDARG;
1124 }
1125
1126 switch (bits)
1127 {
1128 case 7:
1129 config |= _COM_CHR7;
1130 break;
1131 case 8:
1132 config |= _COM_CHR8;
1133 break;
1134 default:
1135 return GATE_RESULT_INVALIDARG;
1136 }
1137
1138 switch (parity)
1139 {
1140 case GATE_SERIALPORT_PARITY_NONE:
1141 config |= _COM_NOPARITY;
1142 break;
1143 case GATE_SERIALPORT_PARITY_ODD:
1144 config |= _COM_ODDPARITY;
1145 break;
1146 case GATE_SERIALPORT_PARITY_EVEN:
1147 config |= _COM_EVENPARITY;
1148 break;
1149 case GATE_SERIALPORT_PARITY_SPACE:
1150 config |= _COM_SPACEPARITY;
1151 break;
1152 default:
1153 return GATE_RESULT_INVALIDARG;
1154 }
1155
1156 switch (stopbits)
1157 {
1158 case GATE_SERIALPORT_STOPBITS_1_0:
1159 config |= _COM_STOP1;
1160 break;
1161 case GATE_SERIALPORT_STOPBITS_2_0:
1162 config |= _COM_STOP2;
1163 break;
1164 default:
1165 return GATE_RESULT_INVALIDARG;
1166 }
1167
1168 switch (baudrate)
1169 {
1170 case GATE_SERIALPORT_BAUDRATE_110:
1171 config |= _COM_110;
1172 break;
1173 case GATE_SERIALPORT_BAUDRATE_300:
1174 config |= _COM_300;
1175 break;
1176 case GATE_SERIALPORT_BAUDRATE_600:
1177 config |= _COM_600;
1178 break;
1179 case GATE_SERIALPORT_BAUDRATE_1200:
1180 config |= _COM_1200;
1181 break;
1182 case GATE_SERIALPORT_BAUDRATE_2400:
1183 config |= _COM_2400;
1184 break;
1185 case GATE_SERIALPORT_BAUDRATE_4800:
1186 config |= _COM_4800;
1187 break;
1188 case GATE_SERIALPORT_BAUDRATE_9600:
1189 config |= _COM_9600;
1190 break;
1191 default:
1192 return GATE_RESULT_INVALIDARG;
1193 }
1194
1195 _bios_serialcom(_COM_INIT, port, config);
1196 port_timeout[port] = timeout_ms;
1197 if (port_handle)
1198 {
1199 *port_handle = (gate_serialport_t)port;
1200 }
1201 return GATE_RESULT_OK;
1202 }
1203
1204 #define GATE_SERIALPORT_BIOS_STATUS_DATA_RECEIVED 0x0100
1205 #define GATE_SERIALPORT_BIOS_STATUS_OVERFLOW 0x0200
1206 #define GATE_SERIALPORT_BIOS_STATUS_PARITY_ERROR 0x0400
1207 #define GATE_SERIALPORT_BIOS_STATUS_PROTOCOL_ERROR 0x0800
1208 #define GATE_SERIALPORT_BIOS_STATUS_INTERRUPTION 0x1000
1209 #define GATE_SERIALPORT_BIOS_STATUS_HOLDREG 0x2000
1210 #define GATE_SERIALPORT_BIOS_STATUS_SHIFTREG 0x4000
1211 #define GATE_SERIALPORT_BIOS_STATUS_TIMEOUT 0x8000
1212
1213
1214 gate_result_t gate_serialport_close(gate_serialport_t port_handle)
1215 {
1216 (void)port_handle;
1217 return GATE_RESULT_OK;
1218 }
1219 gate_result_t gate_serialport_read(gate_serialport_t port_handle, char* buffer, gate_size_t bufferlen, gate_size_t* bytesreceived)
1220 {
1221 static unsigned const avail_mask = GATE_SERIALPORT_BIOS_STATUS_HOLDREG | GATE_SERIALPORT_BIOS_STATUS_SHIFTREG | GATE_SERIALPORT_BIOS_STATUS_DATA_RECEIVED;
1222 static unsigned const error_mask = GATE_SERIALPORT_BIOS_STATUS_TIMEOUT | GATE_SERIALPORT_BIOS_STATUS_OVERFLOW | GATE_SERIALPORT_BIOS_STATUS_PARITY_ERROR | GATE_SERIALPORT_BIOS_STATUS_PROTOCOL_ERROR;
1223 //static unsigned avail_mask = GATE_SERIALPORT_BIOS_STATUS_DATA_RECEIVED;
1224 unsigned port = (unsigned)port_handle;
1225 unsigned status;
1226 unsigned old_status = 0;
1227 unsigned data;
1228 unsigned timeout_ms = port_timeout[port];
1229 gate_timecounter_t now;
1230 gate_timecounter_t timeout_point;
1231
1232 gate_size_t received = 0;
1233 gate_timecounter_now(&now);
1234 timeout_point = gate_timecounter_add(now, (gate_int64_t)timeout_ms * 1000);
1235
1236 while ((received < bufferlen) && (now <= timeout_point))
1237 {
1238 status = _bios_serialcom(_COM_STATUS, port, 0);
1239 if (status != old_status)
1240 {
1241 old_status = status;
1242 }
1243 if ((status & avail_mask) == 0)
1244 {
1245 /* nothing to read */
1246 if (received > 0)
1247 {
1248 break;
1249 }
1250 }
1251 else
1252 {
1253 /* there is data to read */
1254 data = _bios_serialcom(_COM_RECEIVE, port, 0);
1255 if ((data & error_mask) == 0)
1256 {
1257 buffer[received] = (char)(data & 0xff);
1258 ++received;
1259 }
1260 break;
1261 }
1262 gate_timecounter_now(&now);
1263 }
1264
1265 if (received > 0)
1266 {
1267 if (bytesreceived)
1268 {
1269 *bytesreceived = received;
1270 }
1271 return GATE_RESULT_OK;
1272 }
1273 else
1274 {
1275 return GATE_RESULT_NODATA;
1276 }
1277 }
1278 gate_result_t gate_serialport_write(gate_serialport_t port_handle, char const* buffer, gate_size_t bufferlen, gate_size_t* byteswritten)
1279 {
1280 unsigned port = (unsigned)port_handle;
1281 unsigned written = 0;
1282 unsigned status;
1283 unsigned chr;
1284
1285 while (bufferlen > 0)
1286 {
1287 chr = (unsigned char)*buffer;
1288 status = _bios_serialcom(_COM_SEND, port, chr);
1289 --bufferlen;
1290 ++buffer;
1291 ++written;
1292 }
1293 if (byteswritten)
1294 {
1295 *byteswritten = written;
1296 }
1297 return GATE_RESULT_OK;
1298 }
1299
1300 #endif /* GATE_IO_SERIALPORTS_DOS_IMPL */
1301
1302
1303
1304
1305 #if defined(GATE_IO_SERIALPORTS_NO_IMPL)
1306
1307 gate_result_t gate_serialport_enum(gate_serialport_enum_callback_t callback, void* userparam)
1308 {
1309 GATE_UNUSED_ARG(callback);
1310 GATE_UNUSED_ARG(userparam);
1311 return GATE_RESULT_NOTIMPLEMENTED;
1312 }
1313
1314 gate_result_t gate_serialport_open(
1315 gate_string_t const* port_id, gate_uint32_t baudrate,
1316 gate_enumint_t bits, gate_enumint_t parity, gate_enumint_t stopbits, gate_enumint_t flowcontrol,
1317 gate_uint32_t timeout, gate_bool_t asynchronous, gate_serialport_t* port_handle)
1318 {
1319 GATE_UNUSED_ARG(port_id);
1320 GATE_UNUSED_ARG(baudrate);
1321 GATE_UNUSED_ARG(bits);
1322 GATE_UNUSED_ARG(parity);
1323 GATE_UNUSED_ARG(stopbits);
1324 GATE_UNUSED_ARG(flowcontrol);
1325 GATE_UNUSED_ARG(timeout);
1326 GATE_UNUSED_ARG(asynchronous);
1327 GATE_UNUSED_ARG(port_handle);
1328 return GATE_RESULT_NOTIMPLEMENTED;
1329 }
1330
1331 gate_result_t gate_serialport_close(gate_serialport_t port_handle)
1332 {
1333 GATE_UNUSED_ARG(port_handle);
1334 return GATE_RESULT_NOTIMPLEMENTED;
1335 }
1336 gate_result_t gate_serialport_read(gate_serialport_t port_handle, char* buffer, gate_size_t bufferlen, gate_size_t* bytesreceived)
1337 {
1338 GATE_UNUSED_ARG(port_handle);
1339 GATE_UNUSED_ARG(buffer);
1340 GATE_UNUSED_ARG(bufferlen);
1341 GATE_UNUSED_ARG(bytesreceived);
1342 return GATE_RESULT_NOTIMPLEMENTED;
1343 }
1344 gate_result_t gate_serialport_write(gate_serialport_t port_handle, char const* buffer, gate_size_t bufferlen, gate_size_t* byteswritten)
1345 {
1346 GATE_UNUSED_ARG(port_handle);
1347 GATE_UNUSED_ARG(buffer);
1348 GATE_UNUSED_ARG(bufferlen);
1349 GATE_UNUSED_ARG(byteswritten);
1350 return GATE_RESULT_NOTIMPLEMENTED;
1351 }
1352
1353 #endif /* GATE_IO_SERIALPORTS_NO_IMPL */
1354