rs232_posix.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. /*
  2. * Copyright (c) 2011 Petr Stetiar <[email protected]>, Gaben Ltd.
  3. *
  4. * Permission is hereby granted, free of charge, to any person
  5. * obtaining a copy of this software and associated documentation
  6. * files (the "Software"), to deal in the Software without
  7. * restriction, including without limitation the rights to use,
  8. * copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the
  10. * Software is furnished to do so, subject to the following
  11. * conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. * OTHER DEALINGS IN THE SOFTWARE.
  24. *
  25. */
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <errno.h>
  30. #include <termios.h>
  31. #include <sys/types.h>
  32. #include <sys/stat.h>
  33. #include <sys/time.h>
  34. #include <sys/timeb.h>
  35. #include <sys/ioctl.h>
  36. #include <fcntl.h>
  37. #include <unistd.h>
  38. #include "librs232/rs232.h"
  39. struct rs232_port_t *
  40. rs232_init(void)
  41. {
  42. struct rs232_port_t *p = NULL;
  43. p = (struct rs232_port_t *) malloc(sizeof(struct rs232_port_t));
  44. if (p == NULL)
  45. return NULL;
  46. p->pt = (struct rs232_posix_t *) malloc(sizeof(struct rs232_posix_t));
  47. if (p->pt == NULL)
  48. return NULL;
  49. DBG("p=%p p->pt=%p\n", (void *)p, p->pt);
  50. memset(p->pt, 0, sizeof(struct rs232_posix_t));
  51. memset(p->dev, 0, RS232_STRLEN_DEVICE+1);
  52. strncpyz(p->dev, RS232_PORT_POSIX, RS232_STRLEN_DEVICE);
  53. p->baud = RS232_BAUD_115200;
  54. p->data = RS232_DATA_8;
  55. p->parity = RS232_PARITY_NONE;
  56. p->stop = RS232_STOP_1;
  57. p->flow = RS232_FLOW_OFF;
  58. p->status = RS232_PORT_CLOSED;
  59. p->dtr = RS232_DTR_OFF;
  60. p->rts = RS232_RTS_OFF;
  61. return p;
  62. }
  63. void
  64. rs232_end(struct rs232_port_t *p)
  65. {
  66. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  67. DBG("p=%p p->pt=%p\n", (void *)p, p->pt);
  68. if (!rs232_port_open(p)) {
  69. free(p->pt);
  70. free(p);
  71. return;
  72. }
  73. rs232_flush(p);
  74. if (tcsetattr(ux->fd, TCSANOW, &ux->oldterm) < 0) {
  75. DBG("tcsetattr() %d %s\n", errno, strerror(errno))
  76. return;
  77. }
  78. rs232_close(p);
  79. free(p->pt);
  80. free(p);
  81. }
  82. unsigned int
  83. rs232_in_queue(struct rs232_port_t *p, unsigned int *in_bytes)
  84. {
  85. fd_set set;
  86. int ret;
  87. int b;
  88. struct timeval tv;
  89. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  90. DBG("p=%p p->pt=%p\n", (void *)p, p->pt);
  91. if (!rs232_port_open(p))
  92. return RS232_ERR_PORT_CLOSED;
  93. FD_ZERO(&set);
  94. FD_SET(ux->fd, &set);
  95. /* don't work reliable with 0 */
  96. tv.tv_usec = 1;
  97. tv.tv_sec = 0;
  98. select(ux->fd+1, &set, NULL, NULL, &tv);
  99. ret = ioctl(ux->fd, FIONREAD, &b);
  100. if (ret == -1) {
  101. *in_bytes = 0;
  102. DBG("%s\n", "RS232_ERR_IOCTL");
  103. return RS232_ERR_IOCTL;
  104. }
  105. *in_bytes = b;
  106. DBG("in_bytes=%d\n", b);
  107. return RS232_ERR_NOERROR;
  108. }
  109. /* some USB<->RS232 converters buffer a lot, so this function tries to discard
  110. this buffer - useful mainly after rs232_open() */
  111. void
  112. rs232_in_queue_clear(struct rs232_port_t *p)
  113. {
  114. fd_set set;
  115. unsigned int ret;
  116. unsigned int blen;
  117. unsigned char *buf = NULL;
  118. struct timeval tv;
  119. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  120. DBG("p=%p p->pt=%p\n", (void *)p, p->pt);
  121. if (!rs232_port_open(p))
  122. return;
  123. rs232_in_queue(p, &blen);
  124. if (blen > 0) {
  125. buf = (unsigned char*) malloc(blen * sizeof(unsigned char*)+1);
  126. if (buf == NULL)
  127. return;
  128. FD_ZERO(&set);
  129. FD_SET(ux->fd, &set);
  130. tv.tv_usec = 1;
  131. tv.tv_sec = 0;
  132. ret = select(ux->fd+1, &set, NULL, NULL, &tv);
  133. DBG("select=%d\n", ret);
  134. if (ret <= 0) {
  135. free(buf);
  136. return;
  137. }
  138. ret = read(ux->fd, buf, blen);
  139. DBG("read=%d\n", ret);
  140. free(buf);
  141. }
  142. }
  143. unsigned int
  144. rs232_read(struct rs232_port_t *p, unsigned char *buf, unsigned int buf_len,
  145. unsigned int *read_len)
  146. {
  147. int r;
  148. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  149. DBG("p=%p p->pt=%p buf_len=%d\n", (void *)p, p->pt, buf_len);
  150. if (!rs232_port_open(p))
  151. return RS232_ERR_PORT_CLOSED;
  152. r = read(ux->fd, buf, buf_len);
  153. if (r == -1) {
  154. *read_len = 0;
  155. DBG("errno: %d strerror: %s %s\n",
  156. errno, strerror(errno), "RS232_ERR_READ");
  157. return RS232_ERR_READ;
  158. }
  159. *read_len = r;
  160. DBG("read_len=%d hex='%s' ascii='%s'\n", r, rs232_hex_dump(buf, r),
  161. rs232_ascii_dump(buf, r));
  162. return RS232_ERR_NOERROR;
  163. }
  164. static int
  165. duration(struct timeval *t1, struct timeval *t2)
  166. {
  167. return (t2->tv_sec-t1->tv_sec)*1000 + (t2->tv_usec - t1->tv_usec)/1000;
  168. }
  169. /* this function waits either for timeout or buf_len bytes,
  170. whatever happens first and doesn't return earlier */
  171. unsigned int
  172. rs232_read_timeout_forced(struct rs232_port_t *p, unsigned char *buf,
  173. unsigned int buf_len, unsigned int *read_len,
  174. unsigned int timeout)
  175. {
  176. int b;
  177. int ret;
  178. int reti;
  179. fd_set set;
  180. int r;
  181. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  182. struct timeval tv;
  183. struct timeval t1;
  184. struct timeval t2;
  185. DBG("p=%p p->pt=%p buf_len=%d timeout=%d\n", (void *)p, p->pt, buf_len,
  186. timeout);
  187. if (!rs232_port_open(p))
  188. return RS232_ERR_PORT_CLOSED;
  189. FD_ZERO(&set);
  190. FD_SET(ux->fd, &set);
  191. tv.tv_sec = (timeout * 1000) / 1000000;
  192. tv.tv_usec = (timeout * 1000) % 1000000;
  193. *read_len = 0;
  194. gettimeofday(&t1, NULL);
  195. while (1) {
  196. ret = select(ux->fd+1, &set, NULL, NULL, &tv);
  197. gettimeofday(&t2, NULL);
  198. if (ret == 0) {
  199. DBG("%s\n", "select timeout");
  200. break;
  201. }
  202. if (ret == -1) {
  203. DBG("%s\n", "select error");
  204. break;
  205. }
  206. if (duration(&t1, &t2) >= (int) timeout) {
  207. DBG("%s\n", "timeout");
  208. break;
  209. }
  210. reti = ioctl(ux->fd, FIONREAD, &b);
  211. if (reti == -1) {
  212. DBG("%s\n", "ioctl error");
  213. break;
  214. }
  215. if ((unsigned int) b >= buf_len) {
  216. DBG("fionread=%d\n", b);
  217. break;
  218. }
  219. }
  220. switch (ret) {
  221. case 0:
  222. DBG("%s\n", "RS232_ERR_TIMEOUT");
  223. return RS232_ERR_TIMEOUT;
  224. case 1:
  225. r = read(ux->fd, buf, buf_len);
  226. if (r == -1) {
  227. DBG("errno: %d strerror: %s %s\n",
  228. errno, strerror(errno), "RS232_ERR_READ");
  229. return RS232_ERR_READ;
  230. }
  231. DBG("read_len=%d hex='%s' ascii='%s'\n", r,
  232. rs232_hex_dump(buf, r),
  233. rs232_ascii_dump(buf, r));
  234. *read_len = r;
  235. break;
  236. default:
  237. DBG("%s\n", "RS232_ERR_SELECT");
  238. return RS232_ERR_SELECT;
  239. }
  240. return RS232_ERR_NOERROR;
  241. }
  242. unsigned int
  243. rs232_read_timeout(struct rs232_port_t *p, unsigned char *buf,
  244. unsigned int buf_len, unsigned int *read_len,
  245. unsigned int timeout)
  246. {
  247. int ret;
  248. fd_set set;
  249. int r;
  250. struct timeval tv;
  251. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  252. DBG("p=%p p->pt=%p buf_len=%d timeout=%d\n", (void *)p, p->pt,
  253. buf_len, timeout);
  254. if (!rs232_port_open(p))
  255. return RS232_ERR_PORT_CLOSED;
  256. FD_ZERO(&set);
  257. FD_SET(ux->fd, &set);
  258. tv.tv_sec = (timeout * 1000) / 1000000;
  259. tv.tv_usec = (timeout * 1000) % 1000000;
  260. *read_len = 0;
  261. ret = select(ux->fd+1, &set, NULL, NULL, &tv);
  262. switch (ret) {
  263. case 0:
  264. DBG("%s\n", "RS232_ERR_TIMEOUT");
  265. return RS232_ERR_TIMEOUT;
  266. case 1:
  267. r = read(ux->fd, buf, buf_len);
  268. if (r == -1) {
  269. DBG("errno: %d strerror: %s %s\n",
  270. errno, strerror(errno), "RS232_ERR_READ");
  271. return RS232_ERR_READ;
  272. }
  273. DBG("read_len=%d hex='%s' ascii='%s'\n", r,
  274. rs232_hex_dump(buf, r),
  275. rs232_ascii_dump(buf, r));
  276. *read_len = r;
  277. break;
  278. default:
  279. DBG("%s\n", "RS232_ERR_SELECT");
  280. return RS232_ERR_SELECT;
  281. }
  282. return RS232_ERR_NOERROR;
  283. }
  284. unsigned int
  285. rs232_write(struct rs232_port_t *p, const unsigned char *buf, unsigned int buf_len,
  286. unsigned int *write_len)
  287. {
  288. int w;
  289. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  290. DBG("p=%p p->pt=%p hex='%s' ascii='%s' buf_len=%d\n",
  291. (void *)p, p->pt, rs232_hex_dump(buf, buf_len),
  292. rs232_ascii_dump(buf, buf_len), buf_len);
  293. if (!rs232_port_open(p))
  294. return RS232_ERR_PORT_CLOSED;
  295. w = write(ux->fd, buf, buf_len);
  296. if (w == -1) {
  297. DBG("errno: %d strerror: %s %s\n",
  298. errno, strerror(errno), "RS232_ERR_WRITE");
  299. *write_len = 0;
  300. return RS232_ERR_WRITE;
  301. }
  302. *write_len = w;
  303. DBG("write_len=%d hex='%s' ascii='%s'\n", w, rs232_hex_dump(buf, w),
  304. rs232_ascii_dump(buf, w));
  305. return RS232_ERR_NOERROR;
  306. }
  307. unsigned int
  308. rs232_write_timeout(struct rs232_port_t *p, const unsigned char *buf,
  309. unsigned int buf_len, unsigned int *write_len,
  310. unsigned int timeout)
  311. {
  312. int ret;
  313. fd_set set;
  314. int w;
  315. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  316. struct timeval tv;
  317. DBG("p=%p p->pt=%p timeout=%d\n", (void *)p, p->pt, timeout);
  318. if (!rs232_port_open(p))
  319. return RS232_ERR_PORT_CLOSED;
  320. FD_ZERO(&set);
  321. FD_SET(ux->fd, &set);
  322. tv.tv_sec = (timeout * 1000) / 1000000;
  323. tv.tv_usec = (timeout * 1000) % 1000000;
  324. *write_len = 0;
  325. ret = select(ux->fd+1, NULL, &set, NULL, &tv);
  326. switch (ret) {
  327. case 0:
  328. DBG("%s\n", "RS232_ERR_TIMEOUT");
  329. return RS232_ERR_TIMEOUT;
  330. case 1:
  331. w = write(ux->fd, buf, buf_len);
  332. if (w == -1) {
  333. DBG("errno: %d strerror: %s %s\n",
  334. errno, strerror(errno), "RS232_ERR_WRITE");
  335. return RS232_ERR_WRITE;
  336. }
  337. *write_len = w;
  338. DBG("write_len=%d hex='%s' ascii='%s'\n", w,
  339. rs232_hex_dump(buf, w),
  340. rs232_ascii_dump(buf, w));
  341. break;
  342. default:
  343. DBG("%s\n", "RS232_ERR_SELECT");
  344. return RS232_ERR_SELECT;
  345. }
  346. return RS232_ERR_NOERROR;
  347. }
  348. unsigned int
  349. rs232_open(struct rs232_port_t *p)
  350. {
  351. int flags;
  352. struct termios term;
  353. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  354. DBG("p=%p p->pt=%p\n", (void *)p, p->pt);
  355. ux->fd = open(p->dev, O_RDWR | O_NOCTTY | O_NDELAY);
  356. if (ux->fd < 0) {
  357. DBG("open() %d %s\n", errno, strerror(errno))
  358. return RS232_ERR_OPEN;
  359. }
  360. /*
  361. * On OSX (and maybe on more systems), we need to open() the port with
  362. * O_NDELAY, because otherwise it would block forever waiting for DCD
  363. * signal, so here we restore back to blocking operations.
  364. */
  365. flags = fcntl(ux->fd, F_GETFL);
  366. flags &= ~O_NDELAY;
  367. fcntl(ux->fd, F_SETFL, flags);
  368. if (tcflush(ux->fd, TCIOFLUSH) < 0) {
  369. DBG("tcflush() %d %s\n", errno, strerror(errno))
  370. return RS232_ERR_CONFIG;
  371. }
  372. GET_PORT_STATE(ux->fd, &term)
  373. GET_PORT_STATE(ux->fd, &ux->oldterm)
  374. term.c_cflag |= (CREAD | CLOCAL);
  375. term.c_iflag = IGNPAR;
  376. term.c_oflag = 0;
  377. term.c_lflag = 0;
  378. term.c_cc[VINTR] = _POSIX_VDISABLE;
  379. term.c_cc[VQUIT] = _POSIX_VDISABLE;
  380. term.c_cc[VSTART] = _POSIX_VDISABLE;
  381. term.c_cc[VSTOP] = _POSIX_VDISABLE;
  382. term.c_cc[VSUSP] = _POSIX_VDISABLE;
  383. term.c_cc[VEOF] = _POSIX_VDISABLE;
  384. term.c_cc[VEOL] = _POSIX_VDISABLE;
  385. term.c_cc[VERASE] = _POSIX_VDISABLE;
  386. term.c_cc[VKILL] = _POSIX_VDISABLE;
  387. SET_PORT_STATE(ux->fd, &term)
  388. rs232_set_baud(p, p->baud);
  389. rs232_set_data(p, p->data);
  390. rs232_set_parity(p, p->parity);
  391. rs232_set_stop(p, p->stop);
  392. rs232_set_flow(p, p->flow);
  393. p->status = RS232_PORT_OPEN;
  394. return RS232_ERR_NOERROR;
  395. }
  396. void
  397. rs232_set_device(struct rs232_port_t *p, const char *device)
  398. {
  399. DBG("p=%p old=%s new=%s\n", (void *)p, p->dev, device);
  400. strncpyz(p->dev, device, RS232_STRLEN_DEVICE);
  401. return;
  402. }
  403. unsigned int
  404. rs232_set_baud(struct rs232_port_t *p, enum rs232_baud_e baud)
  405. {
  406. struct termios term;
  407. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  408. DBG("p=%p p->pt=%p baud=%d (%s bauds)\n",
  409. (void *)p, p->pt, baud, rs232_strbaud(baud));
  410. if (!rs232_port_open(p))
  411. return RS232_ERR_PORT_CLOSED;
  412. GET_PORT_STATE(ux->fd, &term)
  413. switch (baud) {
  414. case RS232_BAUD_300:
  415. cfsetispeed(&term, B300);
  416. cfsetospeed(&term, B300);
  417. break;
  418. case RS232_BAUD_2400:
  419. cfsetispeed(&term, B2400);
  420. cfsetospeed(&term, B2400);
  421. break;
  422. case RS232_BAUD_4800:
  423. cfsetispeed(&term, B4800);
  424. cfsetospeed(&term, B4800);
  425. break;
  426. case RS232_BAUD_9600:
  427. cfsetispeed(&term, B9600);
  428. cfsetospeed(&term, B9600);
  429. break;
  430. case RS232_BAUD_19200:
  431. cfsetispeed(&term, B19200);
  432. cfsetospeed(&term, B19200);
  433. break;
  434. case RS232_BAUD_38400:
  435. cfsetispeed(&term, B38400);
  436. cfsetospeed(&term, B38400);
  437. break;
  438. case RS232_BAUD_57600:
  439. cfsetispeed(&term, B57600);
  440. cfsetospeed(&term, B57600);
  441. break;
  442. case RS232_BAUD_115200:
  443. cfsetispeed(&term, B115200);
  444. cfsetospeed(&term, B115200);
  445. break;
  446. case RS232_BAUD_460800:
  447. cfsetispeed(&term, B460800);
  448. cfsetospeed(&term, B460800);
  449. break;
  450. default:
  451. return RS232_ERR_UNKNOWN;
  452. }
  453. SET_PORT_STATE(ux->fd, &term)
  454. p->baud = baud;
  455. return RS232_ERR_NOERROR;
  456. }
  457. unsigned int
  458. rs232_set_dtr(struct rs232_port_t *p, enum rs232_dtr_e state)
  459. {
  460. int ret;
  461. int set;
  462. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  463. DBG("p=%p p->pt=%p dtr=%d (dtr control %s)\n",
  464. (void *)p, p->pt, state, rs232_strdtr(state));
  465. if (!rs232_port_open(p))
  466. return RS232_ERR_PORT_CLOSED;
  467. ret = ioctl(ux->fd, TIOCMGET, &set);
  468. if (ret == -1) {
  469. DBG("%s\n", "TIOCMGET RS232_ERR_IOCTL");
  470. return RS232_ERR_IOCTL;
  471. }
  472. switch (state) {
  473. case RS232_DTR_OFF:
  474. set &= ~TIOCM_DTR;
  475. break;
  476. case RS232_DTR_ON:
  477. set |= TIOCM_DTR;
  478. break;
  479. default:
  480. return RS232_ERR_UNKNOWN;
  481. }
  482. ret = ioctl(ux->fd, TIOCMSET, &set);
  483. if (ret == -1) {
  484. DBG("%s\n", "TIOCMSET RS232_ERR_IOCTL");
  485. return RS232_ERR_IOCTL;
  486. }
  487. p->dtr = state;
  488. return RS232_ERR_NOERROR;
  489. }
  490. unsigned int
  491. rs232_set_rts(struct rs232_port_t *p, enum rs232_rts_e state)
  492. {
  493. int ret;
  494. int set;
  495. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  496. DBG("p=%p p->pt=%p rts=%d (rts control %s)\n",
  497. (void *)p, p->pt, state, rs232_strrts(state));
  498. if (!rs232_port_open(p))
  499. return RS232_ERR_PORT_CLOSED;
  500. ret = ioctl(ux->fd, TIOCMGET, &set);
  501. if (ret == -1) {
  502. DBG("%s\n", "TIOCMGET RS232_ERR_IOCTL");
  503. return RS232_ERR_IOCTL;
  504. }
  505. switch (state) {
  506. case RS232_RTS_OFF:
  507. set &= ~TIOCM_RTS;
  508. break;
  509. case RS232_RTS_ON:
  510. set |= TIOCM_RTS;
  511. break;
  512. default:
  513. return RS232_ERR_UNKNOWN;
  514. }
  515. ret = ioctl(ux->fd, TIOCMSET, &set);
  516. if (ret == -1) {
  517. DBG("%s\n", "TIOCMSET RS232_ERR_IOCTL");
  518. return RS232_ERR_IOCTL;
  519. }
  520. p->rts = state;
  521. return RS232_ERR_NOERROR;
  522. }
  523. unsigned int
  524. rs232_set_parity(struct rs232_port_t *p, enum rs232_parity_e parity)
  525. {
  526. struct termios term;
  527. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  528. DBG("p=%p p->pt=%p parity=%d (parity %s)\n",
  529. (void *)p, p->pt, parity, rs232_strparity(parity));
  530. if (!rs232_port_open(p))
  531. return RS232_ERR_PORT_CLOSED;
  532. GET_PORT_STATE(ux->fd, &term)
  533. switch (parity) {
  534. case RS232_PARITY_NONE:
  535. term.c_cflag &= ~PARENB;
  536. break;
  537. case RS232_PARITY_ODD:
  538. term.c_cflag |= (PARENB | PARODD);
  539. break;
  540. case RS232_PARITY_EVEN:
  541. term.c_cflag &= ~PARODD;
  542. term.c_cflag |= PARENB;
  543. break;
  544. default:
  545. return RS232_ERR_UNKNOWN;
  546. }
  547. SET_PORT_STATE(ux->fd, &term)
  548. p->parity = parity;
  549. return RS232_ERR_NOERROR;
  550. }
  551. unsigned int
  552. rs232_set_stop(struct rs232_port_t *p, enum rs232_stop_e stop)
  553. {
  554. struct termios term;
  555. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  556. DBG("p=%p p->pt=%p stop=%d (%s stop bits)\n",
  557. (void *)p, p->pt, stop, rs232_strstop(stop));
  558. if (!rs232_port_open(p))
  559. return RS232_ERR_PORT_CLOSED;
  560. GET_PORT_STATE(ux->fd, &term)
  561. term.c_cflag &= ~CSTOPB;
  562. switch (stop) {
  563. case RS232_STOP_1:
  564. break;
  565. case RS232_STOP_2:
  566. term.c_cflag |= CSTOPB;
  567. break;
  568. default:
  569. return RS232_ERR_UNKNOWN;
  570. }
  571. SET_PORT_STATE(ux->fd, &term)
  572. p->stop = stop;
  573. return RS232_ERR_NOERROR;
  574. }
  575. unsigned int
  576. rs232_set_data(struct rs232_port_t *p, enum rs232_data_e data)
  577. {
  578. struct termios term;
  579. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  580. DBG("p=%p p->pt=%p data=%d (%s data bits)\n",
  581. (void *)p, p->pt, data, rs232_strdata(data));
  582. if (!rs232_port_open(p))
  583. return RS232_ERR_PORT_CLOSED;
  584. GET_PORT_STATE(ux->fd, &term)
  585. term.c_cflag &= ~CSIZE;
  586. switch (data) {
  587. case RS232_DATA_5:
  588. term.c_cflag |= CS5;
  589. break;
  590. case RS232_DATA_6:
  591. term.c_cflag |= CS6;
  592. break;
  593. case RS232_DATA_7:
  594. term.c_cflag |= CS7;
  595. break;
  596. case RS232_DATA_8:
  597. term.c_cflag |= CS8;
  598. break;
  599. default:
  600. return RS232_ERR_UNKNOWN;
  601. }
  602. SET_PORT_STATE(ux->fd, &term)
  603. p->data = data;
  604. return RS232_ERR_NOERROR;
  605. }
  606. unsigned int
  607. rs232_set_flow(struct rs232_port_t *p, enum rs232_flow_e flow)
  608. {
  609. struct termios term;
  610. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  611. DBG("p=%p p->pt=%p flow=%d (flow control %s)\n",
  612. (void *)p, p->pt, flow, rs232_strflow(flow));
  613. if (!rs232_port_open(p))
  614. return RS232_ERR_PORT_CLOSED;
  615. GET_PORT_STATE(ux->fd, &term)
  616. switch (flow) {
  617. case RS232_FLOW_OFF:
  618. term.c_cflag &= ~CRTSCTS;
  619. term.c_iflag &= ~(IXON | IXOFF | IXANY);
  620. break;
  621. case RS232_FLOW_HW:
  622. term.c_cflag |= CRTSCTS;
  623. term.c_iflag &= ~(IXON | IXOFF | IXANY);
  624. break;
  625. case RS232_FLOW_XON_XOFF:
  626. term.c_cflag &= ~CRTSCTS;
  627. term.c_iflag |= (IXON | IXOFF | IXANY);
  628. break;
  629. default:
  630. return RS232_ERR_UNKNOWN;
  631. }
  632. SET_PORT_STATE(ux->fd, &term)
  633. p->flow = flow;
  634. return RS232_ERR_NOERROR;
  635. }
  636. unsigned int
  637. rs232_flush(struct rs232_port_t *p)
  638. {
  639. int ret;
  640. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  641. DBG("p=%p p->pt=%p\n", (void *)p, p->pt);
  642. if (!rs232_port_open(p))
  643. return RS232_ERR_PORT_CLOSED;
  644. ret = tcflush(ux->fd, TCIOFLUSH);
  645. if (ret == -1)
  646. return RS232_ERR_FLUSH;
  647. return RS232_ERR_NOERROR;
  648. }
  649. unsigned int
  650. rs232_close(struct rs232_port_t *p)
  651. {
  652. int ret;
  653. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  654. DBG("p=%p p->pt=%p\n", (void *)p, p->pt);
  655. if (!rs232_port_open(p))
  656. return RS232_ERR_PORT_CLOSED;
  657. ret = close(ux->fd);
  658. if (ret == -1)
  659. return RS232_ERR_CLOSE;
  660. p->status = RS232_PORT_CLOSED;
  661. return RS232_ERR_NOERROR;
  662. }
  663. unsigned int
  664. rs232_fd(struct rs232_port_t *p)
  665. {
  666. struct rs232_posix_t *ux = (struct rs232_posix_t *)p->pt;
  667. DBG("p=%p p->pt=%p ux->fd=%d\n", (void *)p, p->pt, ux->fd);
  668. return (unsigned int) ux->fd;
  669. }