19 #include <ucommon/ucommon.h>
20 #include <ucommon/export.h>
23 #if !defined(_MSWINDOWS_) && defined(HAVE_TERMIOS_H)
25 #include <sys/select.h>
30 #ifdef HAVE_SYS_IOCTL_H
31 #include <sys/ioctl.h>
37 using namespace UCOMMON_NAMESPACE;
39 class __LOCAL serial :
public Serial
43 struct termios original, current;
46 bool set(
const char *format);
47 void dtr(timeout_t timeout);
48 size_t get(
void *data,
size_t len);
49 size_t put(
void *data,
size_t len);
50 void bin(
size_t size, timeout_t timeout);
51 void text(
char nl1,
char nl2);
53 bool flush(timeout_t timeout);
54 bool wait(timeout_t timeout);
61 serial(
const char *name);
65 serial::serial(
const char *name) : Serial()
67 fd = ::open(name, O_RDWR | O_NDELAY);
73 long ioflags = fcntl(fd, F_GETFL);
74 tcgetattr(fd, ¤t);
75 tcgetattr(fd, &original);
77 current.c_oflag = current.c_lflag = 0;
78 current.c_cflag = CLOCAL | CREAD | HUPCL;
79 current.c_iflag = IGNBRK;
81 memset(¤t.c_cc, 0,
sizeof(current.c_cc));
82 current.c_cc[VMIN] = 1;
84 cfsetispeed(¤t, cfgetispeed(&original));
85 cfsetospeed(¤t, cfgetospeed(&original));
87 current.c_cflag |= original.c_cflag & (CRTSCTS | CSIZE | PARENB | PARODD | CSTOPB);
88 current.c_iflag |= original.c_iflag & (IXON | IXANY | IXOFF);
90 tcsetattr(fd, TCSANOW, ¤t);
91 fcntl(fd, F_SETFL, ioflags & ~O_NDELAY);
93 #if defined(TIOCM_RTS) && defined(TIOCMODG)
95 ioctl(fd, TIOCMODG, &mcs);
97 ioctl(fd, TIOCMODS, &mcs);
111 serial::operator bool()
119 bool serial::operator!()
127 void serial::restore(
void)
132 memcpy(¤t, &original,
sizeof(current));
133 tcsetattr(fd, TCSANOW, ¤t);
136 bool serial::set(
const char *format)
138 assert(format != NULL);
145 String::set(buf,
sizeof(buf), format);
147 char *cp = strtok(buf,
",");
152 current.c_cflag &= ~(PARENB | PARODD);
156 current.c_cflag = (current.c_cflag & ~PARODD) | PARENB;
160 current.c_cflag |= (PARODD | PARENB);
164 current.c_cflag &= ~CRTSCTS;
165 current.c_cflag |= (IXON | IXANY | IXOFF);
169 current.c_cflag |= CRTSCTS;
170 current.c_cflag &= ~(IXON | IXANY | IXOFF);
174 current.c_cflag |= CRTSCTS;
175 current.c_cflag |= (IXON | IXANY | IXOFF);
190 current.c_cflag &= ~CSTOPB;
193 current.c_cflag |= CSTOPB;
196 current.c_cflag = (current.c_cflag & ~CSIZE) | CS5;
199 current.c_cflag = (current.c_cflag & ~CSIZE) | CS6;
202 current.c_cflag = (current.c_cflag & ~CSIZE) | CS7;
205 current.c_cflag = (current.c_cflag & ~CSIZE) | CS8;
209 cfsetispeed(¤t, B921600);
210 cfsetospeed(¤t, B921600);
215 cfsetispeed(¤t, B576000);
216 cfsetospeed(¤t, B576000);
221 cfsetispeed(¤t, B500000);
222 cfsetospeed(¤t, B500000);
227 cfsetispeed(¤t, B460800);
228 cfsetospeed(¤t, B460800);
233 cfsetispeed(¤t, B230400);
234 cfsetospeed(¤t, B230400);
239 cfsetispeed(¤t, B115200);
240 cfsetospeed(¤t, B115200);
245 cfsetispeed(¤t, B57600);
246 cfsetospeed(¤t, B57600);
251 cfsetispeed(¤t, B38400);
252 cfsetospeed(¤t, B38400);
256 cfsetispeed(¤t, B19200);
257 cfsetospeed(¤t, B19200);
260 cfsetispeed(¤t, B9600);
261 cfsetospeed(¤t, B9600);
264 cfsetispeed(¤t, B4800);
265 cfsetospeed(¤t, B4800);
268 cfsetispeed(¤t, B2400);
269 cfsetospeed(¤t, B2400);
272 cfsetispeed(¤t, B1200);
273 cfsetospeed(¤t, B1200);
276 cfsetispeed(¤t, B600);
277 cfsetospeed(¤t, B600);
280 cfsetispeed(¤t, B300);
281 cfsetospeed(¤t, B300);
284 cfsetispeed(¤t, B110);
285 cfsetospeed(¤t, B110);
289 cfsetispeed(¤t, B200);
290 cfsetospeed(¤t, B200);
295 cfsetispeed(¤t, B150);
296 cfsetospeed(¤t, B150);
301 cfsetispeed(¤t, B134);
302 cfsetospeed(¤t, B134);
307 cfsetispeed(¤t, B0);
308 cfsetospeed(¤t, B0);
320 cp = strtok(NULL,
",");
322 tcsetattr(fd, TCSANOW, ¤t);
326 void serial::dtr(timeout_t timeout)
331 struct termios tty, old;
334 cfsetospeed(&tty, B0);
335 cfsetispeed(&tty, B0);
336 tcsetattr(fd, TCSANOW, &tty);
339 Thread::sleep(timeout);
340 tcsetattr(fd, TCSANOW, &old);
344 size_t serial::get(
void *data,
size_t len)
349 ssize_t rts = ::read(fd, data, len);
357 size_t serial::put(
void *data,
size_t len)
362 ssize_t rts = ::write(fd, data, len);
370 void serial::bin(
size_t size, timeout_t timeout)
376 int max = fpathconf(fd, _PC_MAX_INPUT);
380 if(size > (
size_t)max)
383 current.c_cc[VEOL] = current.c_cc[VEOL2] = 0;
384 current.c_cc[VMIN] = (
unsigned char)size;
385 current.c_cc[VTIME] = (
unsigned char)( (timeout + 99l) / 100l);
386 current.c_lflag &= ~ICANON;
387 tcsetattr(fd, TCSANOW, ¤t);
390 void serial::text(
char nl1,
char nl2)
392 current.c_cc[VMIN] = current.c_cc[VTIME] = 0;
393 current.c_cc[VEOL] = nl1;
394 current.c_cc[VEOL2] = nl2;
395 current.c_lflag |= ICANON;
396 tcsetattr(fd, TCSANOW, ¤t);
399 void serial::clear(
void)
401 tcflush(fd, TCIFLUSH);
404 void serial::sync(
void)
409 bool serial::wait(timeout_t timeout)
413 struct timeval *tvp = &tv;
419 if(timeout == Timer::inf)
422 tv.tv_usec = (timeout % 1000) * 1000;
423 tv.tv_sec = timeout / 1000;
428 status = select(fd + 1, &grp, NULL, NULL, tvp);
435 if(FD_ISSET(fd, &grp))
441 bool serial::flush(timeout_t timeout)
445 struct timeval *tvp = &tv;
452 if(timeout == Timer::inf)
455 tv.tv_usec = (timeout % 1000) * 1000;
456 tv.tv_sec = timeout / 1000;
461 status = select(fd + 1, NULL, &grp, NULL, tvp);
467 if(status > 0 && FD_ISSET(fd, &grp))
471 tcflush(fd, TCOFLUSH);
476 Serial *Serial::create(
const char *name)
478 assert(name != NULL);
481 fsys::fileinfo_t ino;
484 String::set(buf,
sizeof(buf), name);
488 if(eq(name,
"tty", 3))
489 snprintf(buf,
sizeof(buf),
"/dev/%s", name);
491 snprintf(buf,
sizeof(buf),
"/dev/tty%s", name);
494 char *cp = strchr(buf,
':');
497 fsys::fileinfo(buf, &ino);
498 if(!fsys::ischar(&ino))
500 serial_t dev =
new serial(buf);
501 name = strchr(name,
':');
507 stringpager *Serial::list(
void)
509 stringpager *list =
new stringpager;
513 fsys::open(dir,
"/dev", fsys::ACCESS_DIRECTORY);
514 while(is(dir) && fsys::read(dir, filename,
sizeof(filename)) > 0) {
515 if(eq(filename,
"tty", 3))
516 list->add(filename + 3);
#define BAYONNE_NAMESPACE
GNU Bayonne library namespace.