19 #include <ucommon/ucommon.h>
20 #include <ucommon/export.h>
26 #define ASCII_XON 0x11
27 #define ASCII_XOFF 0x13
30 using namespace UCOMMON_NAMESPACE;
32 class __LOCAL serial :
public Serial
36 DCB original, current;
39 bool set(
const char *format);
40 size_t get(
void *addr,
size_t len);
41 size_t put(
void *addr,
size_t len);
42 void dtr(timeout_t toggle_time);
43 void bin(
size_t size, timeout_t timeout);
44 void text(
char nl1,
char nl2);
46 bool flush(timeout_t timeout);
47 bool wait(timeout_t timeout);
54 serial(
const char *name);
58 serial::serial(
const char *name) : Serial()
61 GENERIC_READ | GENERIC_WRITE,
65 FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING,
68 if(fd == INVALID_HANDLE_VALUE) {
72 current.DCBlength =
sizeof(DCB);
73 original.DCBlength =
sizeof(DCB);
75 GetCommState(fd, &original);
76 GetCommState(fd, ¤t);
78 current.DCBlength =
sizeof(DCB);
79 current.BaudRate = 1200;
80 current.Parity = NOPARITY;
83 current.XonChar = ASCII_XON;
84 current.XoffChar = ASCII_XOFF;
86 current.XoffLim = 100;
87 current.fOutxDsrFlow = 0;
88 current.fDtrControl = DTR_CONTROL_ENABLE;
89 current.fOutxCtsFlow = 1;
90 current.fRtsControl = RTS_CONTROL_ENABLE;
91 current.fInX = current.fOutX = 0;
93 current.fBinary =
true;
94 current.fParity =
true;
96 SetCommState(fd, ¤t);
101 if(fd == INVALID_HANDLE_VALUE)
106 fd = INVALID_HANDLE_VALUE;
109 serial::operator bool()
111 if(fd == INVALID_HANDLE_VALUE)
117 bool serial::operator!()
119 if(fd == INVALID_HANDLE_VALUE)
125 void serial::restore(
void)
127 if(fd == INVALID_HANDLE_VALUE)
130 memcpy(¤t, &original,
sizeof(current));
131 SetCommState(fd, ¤t);
134 bool serial::set(
const char *format)
136 assert(format != NULL);
138 if(fd == INVALID_HANDLE_VALUE)
143 String::set(buf,
sizeof(buf), format);
145 char *cp = strtok(buf,
",");
150 current.Parity = NOPARITY;
154 current.Parity = EVENPARITY;
158 current.Parity = ODDPARITY;
162 current.fInX = current.fOutX = TRUE;
163 current.fOutxCtsFlow = FALSE;
164 current.fRtsControl = FALSE;
168 current.fInX = current.fOutX = FALSE;
169 current.fOutxCtsFlow = TRUE;
170 current.fRtsControl = RTS_CONTROL_HANDSHAKE;
174 current.fInX = current.fOutX = TRUE;
175 current.fOutxCtsFlow = TRUE;
176 current.fRtsControl = RTS_CONTROL_HANDSHAKE;
191 current.StopBits = ONESTOPBIT;
194 current.StopBits = TWOSTOPBITS;
200 current.ByteSize = (
unsigned char)opt;
203 current.BaudRate = opt;
211 cp = strtok(NULL,
",");
213 current.DCBlength =
sizeof(DCB);
214 SetCommState(fd, ¤t);
218 size_t serial::get(
void *data,
size_t len)
220 DWORD dwLength = 0, dwError, dwReadLength;
225 if(fd == INVALID_HANDLE_VALUE)
229 ClearCommError(fd, &dwError, &cs);
232 if(len > (
size_t)cs.cbInQue)
233 dwReadLength = cs.cbInQue;
237 memset(&ol, 0,
sizeof(OVERLAPPED));
238 ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
240 if(dwReadLength > 0) {
241 if(ReadFile(fd, data, dwReadLength, &dwLength, &ol) == FALSE) {
242 if(GetLastError() == ERROR_IO_PENDING) {
243 WaitForSingleObject(ol.hEvent, INFINITE);
244 GetOverlappedResult(fd, &ol, &dwLength, TRUE);
247 ClearCommError(fd, &dwError, &cs);
251 if(ol.hEvent != INVALID_HANDLE_VALUE)
252 CloseHandle(ol.hEvent);
257 size_t serial::put(
void *data,
size_t len)
260 unsigned long dwError = 0;
264 ClearCommError(fd, &dwError, &cs);
266 unsigned long retSize = 0;
268 memset(&ol, 0,
sizeof(OVERLAPPED));
269 ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
271 if(WriteFile(fd, data, len, &retSize, &ol) == FALSE) {
272 if(GetLastError() == ERROR_IO_PENDING) {
273 WaitForSingleObject(ol.hEvent, INFINITE);
274 GetOverlappedResult(fd, &ol, &retSize, TRUE);
277 ClearCommError(fd, &dwError, &cs);
280 if(ol.hEvent != INVALID_HANDLE_VALUE)
281 CloseHandle(ol.hEvent);
286 bool serial::wait(timeout_t timeout)
288 unsigned long dwError;
291 if(fd == INVALID_HANDLE_VALUE)
294 ClearCommError(fd, &dwError, &cs);
297 return (0 != cs.cbInQue);
304 memset(&ol, 0,
sizeof(OVERLAPPED));
305 ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
307 SetCommMask(fd, dwMask);
309 if((suc = WaitCommEvent(fd, &dwEvents, &ol)) == FALSE) {
310 if(GetLastError() == ERROR_IO_PENDING) {
313 dwError = WaitForSingleObject(ol.hEvent, timeout);
314 if (dwError != WAIT_OBJECT_0)
317 suc = GetOverlappedResult(fd, &ol, &transferred, TRUE);
319 suc = (dwEvents & dwMask) ? TRUE : FALSE;
322 ClearCommError(fd, &dwError, &cs);
325 if(ol.hEvent != INVALID_HANDLE_VALUE)
326 CloseHandle(ol.hEvent);
333 bool serial::flush(timeout_t timeout)
335 unsigned long dwError;
338 if(fd == INVALID_HANDLE_VALUE)
341 ClearCommError(fd, &dwError, &cs);
343 if(timeout == 0 && cs.cbOutQue > 0) {
344 PurgeComm(fd, PURGE_TXABORT | PURGE_TXCLEAR);
356 memset(&ol, 0,
sizeof(OVERLAPPED));
357 ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
359 SetCommMask(fd, dwMask);
361 if((suc = WaitCommEvent(fd, &dwEvents, &ol)) == FALSE) {
362 if(GetLastError() == ERROR_IO_PENDING) {
365 dwError = WaitForSingleObject(ol.hEvent, timeout);
366 if (dwError != WAIT_OBJECT_0)
369 suc = GetOverlappedResult(fd, &ol, &transferred, TRUE);
371 suc = (dwEvents & dwMask) ? TRUE : FALSE;
374 ClearCommError(fd, &dwError, &cs);
377 if(ol.hEvent != INVALID_HANDLE_VALUE)
378 CloseHandle(ol.hEvent);
383 PurgeComm(fd, PURGE_TXABORT | PURGE_TXCLEAR);
387 void serial::clear(
void)
389 PurgeComm(fd, PURGE_RXABORT | PURGE_RXCLEAR);
392 void serial::sync(
void)
396 void serial::bin(
size_t size, timeout_t timeout)
400 void serial::text(
char nl1,
char nl2)
404 void serial::dtr(timeout_t timeout)
406 EscapeCommFunction(fd, CLRDTR);
408 Thread::sleep(timeout);
409 EscapeCommFunction(fd, SETDTR);
413 Serial *Serial::create(
const char *name)
417 String::set(buf,
sizeof(buf), name);
419 char *cp = strchr(buf,
':');
423 serial_t dev =
new serial(buf);
424 name = strchr(name,
':');
431 stringpager *Serial::list(
void)
435 DWORD size =
sizeof(keyname);
436 stringpager *list =
new stringpager;
440 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_READ, ®) == ERROR_SUCCESS) {
441 while(RegEnumKeyEx(reg, index++, keyname, &size, NULL, NULL, NULL, &fTime) == ERROR_SUCCESS) {
#define BAYONNE_NAMESPACE
GNU Bayonne library namespace.