Mirror of CollapseOS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
3.0KB

  1. #include <stdlib.h>
  2. #include <unistd.h>
  3. #include <termios.h>
  4. #include <errno.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. void mread(int fd, char *s, int count)
  8. {
  9. while (count) {
  10. while (read(fd, s, 1) == 0) {
  11. usleep(1000);
  12. }
  13. s++;
  14. count--;
  15. }
  16. }
  17. static void mexpect(int fd, char ec)
  18. {
  19. char c;
  20. mread(fd, &c, 1);
  21. if (c != ec) {
  22. fprintf(stderr, "Expected %d but got %d\n", ec, c);
  23. }
  24. }
  25. void readprompt(int fd)
  26. {
  27. mexpect(fd, ' ');
  28. mexpect(fd, 'o');
  29. mexpect(fd, 'k');
  30. mexpect(fd, '\r');
  31. mexpect(fd, '\n');
  32. }
  33. void sendcmd(int fd, char *cmd)
  34. {
  35. char junk[2];
  36. while (*cmd) {
  37. write(fd, cmd, 1);
  38. read(fd, &junk, 1);
  39. cmd++;
  40. // The other side is sometimes much slower than us and if we don't let
  41. // it breathe, it can choke.
  42. usleep(1000);
  43. }
  44. write(fd, "\r", 1);
  45. mexpect(fd, '\r');
  46. mexpect(fd, '\n');
  47. usleep(1000);
  48. }
  49. // Send a cmd and also read the " ok" prompt
  50. void sendcmdp(int fd, char *cmd)
  51. {
  52. sendcmd(fd, cmd);
  53. readprompt(fd);
  54. }
  55. // from https://stackoverflow.com/a/6947758
  56. // discussion from https://stackoverflow.com/a/26006680 is interesting,
  57. // but we don't want POSIX compliance.
  58. int set_interface_attribs(int fd, int speed, int parity)
  59. {
  60. struct termios tty;
  61. if (tcgetattr (fd, &tty) != 0) {
  62. fprintf(stderr, "error %d from tcgetattr", errno);
  63. return -1;
  64. }
  65. if (speed) {
  66. cfsetospeed (&tty, speed);
  67. cfsetispeed (&tty, speed);
  68. }
  69. tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
  70. // disable IGNBRK for mismatched speed tests; otherwise receive break
  71. // as \000 chars
  72. tty.c_iflag &= ~IGNBRK; // disable break processing
  73. tty.c_lflag = 0; // no signaling chars, no echo,
  74. // no canonical processing
  75. tty.c_oflag = 0; // no remapping, no delays
  76. tty.c_cc[VMIN] = 0; // read doesn't block
  77. tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
  78. tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
  79. tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
  80. // enable reading
  81. tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
  82. tty.c_cflag |= parity;
  83. tty.c_cflag &= ~CSTOPB;
  84. tty.c_cflag &= ~CRTSCTS;
  85. if (tcsetattr (fd, TCSANOW, &tty) != 0) {
  86. fprintf(stderr, "error %d from tcsetattr", errno);
  87. return -1;
  88. }
  89. return 0;
  90. }
  91. void set_blocking(int fd, int should_block)
  92. {
  93. struct termios tty;
  94. memset(&tty, 0, sizeof tty);
  95. if (tcgetattr (fd, &tty) != 0) {
  96. fprintf(stderr, "error %d from tggetattr", errno);
  97. return;
  98. }
  99. tty.c_cc[VMIN] = should_block ? 1 : 0;
  100. tty.c_cc[VTIME] = 1; // 0.1 seconds read timeout
  101. if (tcsetattr (fd, TCSANOW, &tty) != 0) {
  102. fprintf(stderr, "error %d setting term attributes", errno);
  103. }
  104. }