serial.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. * (C) Copyright 2000
  3. * Murray Jensen <Murray.Jensen@csiro.au>
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <unistd.h>
  8. #include <string.h>
  9. #include <fcntl.h>
  10. #include <sys/time.h>
  11. #include "serial.h"
  12. #if defined(__sun__) || \
  13. defined(__OpenBSD__) || \
  14. defined(__FreeBSD__) || \
  15. defined(__NetBSD__) || \
  16. defined(__APPLE__)
  17. static struct termios tios = { BRKINT, 0, B115200|CS8|CREAD, 0, { 0 } };
  18. #else
  19. static struct termios tios = { BRKINT, 0, B115200|CS8|CREAD, 0, 0 };
  20. #endif
  21. static struct speedmap {
  22. char *str;
  23. speed_t val;
  24. } speedmap[] = {
  25. { "50", B50 }, { "75", B75 }, { "110", B110 },
  26. { "134", B134 }, { "150", B150 }, { "200", B200 },
  27. { "300", B300 }, { "600", B600 }, { "1200", B1200 },
  28. { "1800", B1800 }, { "2400", B2400 }, { "4800", B4800 },
  29. { "9600", B9600 }, { "19200", B19200 }, { "38400", B38400 },
  30. { "57600", B57600 },
  31. #ifdef B76800
  32. { "76800", B76800 },
  33. #endif
  34. { "115200", B115200 },
  35. #ifdef B153600
  36. { "153600", B153600 },
  37. #endif
  38. { "230400", B230400 },
  39. #ifdef B307200
  40. { "307200", B307200 },
  41. #endif
  42. #ifdef B460800
  43. { "460800", B460800 }
  44. #endif
  45. };
  46. static int nspeeds = sizeof speedmap / sizeof speedmap[0];
  47. speed_t
  48. cvtspeed(char *str)
  49. {
  50. struct speedmap *smp = speedmap, *esmp = &speedmap[nspeeds];
  51. while (smp < esmp) {
  52. if (strcmp(str, smp->str) == 0)
  53. return (smp->val);
  54. smp++;
  55. }
  56. return B0;
  57. }
  58. int
  59. serialopen(char *device, speed_t speed)
  60. {
  61. int fd;
  62. if (cfsetospeed(&tios, speed) < 0)
  63. return -1;
  64. if ((fd = open(device, O_RDWR)) < 0)
  65. return -1;
  66. if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
  67. (void)close(fd);
  68. return -1;
  69. }
  70. return fd;
  71. }
  72. int
  73. serialreadchar(int fd, int timeout)
  74. {
  75. fd_set fds;
  76. struct timeval tv;
  77. int n;
  78. char ch;
  79. tv.tv_sec = timeout;
  80. tv.tv_usec = 0;
  81. FD_ZERO(&fds);
  82. FD_SET(fd, &fds);
  83. /* this is a fucking horrible quick hack - fix this */
  84. if ((n = select(fd + 1, &fds, 0, 0, &tv)) < 0)
  85. return SERIAL_ERROR;
  86. if (n == 0)
  87. return SERIAL_TIMEOUT;
  88. if ((n = read(fd, &ch, 1)) < 0)
  89. return SERIAL_ERROR;
  90. if (n == 0)
  91. return SERIAL_EOF;
  92. return ch;
  93. }
  94. int
  95. serialwrite(int fd, char *buf, int len)
  96. {
  97. int n;
  98. do {
  99. n = write(fd, buf, len);
  100. if (n < 0)
  101. return 1;
  102. len -= n;
  103. buf += n;
  104. } while (len > 0);
  105. return 0;
  106. }
  107. int
  108. serialclose(int fd)
  109. {
  110. return close(fd);
  111. }