ES-2024 reverter
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.

102 lines
2.2 KiB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <fcntl.h>
  6. #include <termios.h>
  7. #include "context.h"
  8. #include "event.h"
  9. #include "logging.h"
  10. #include "statemachine.h"
  11. struct serial_device {
  12. struct termios oldtio;
  13. struct termios newtio;
  14. };
  15. static int open_serial(struct context *ctx, const char *devname)
  16. {
  17. struct serial_device *sdev = (struct serial_device *)ctx->dev_privdata;
  18. ctx->fd = open(devname, O_RDWR);
  19. if (ctx->fd < 0) {
  20. log_print(LOG_ERROR, "open_serial(): open(%s)", devname);
  21. return -1;
  22. }
  23. ctx->devname = strdup(devname);
  24. if (tcgetattr(ctx->fd, &sdev->oldtio) != 0) {
  25. log_print(LOG_WARN, "open_serial(): tcgetattr()");
  26. close(ctx->fd);
  27. return -1;
  28. }
  29. bzero(&sdev->newtio, sizeof(struct termios));
  30. sdev->newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
  31. tcflush(ctx->fd, TCIOFLUSH);
  32. if (tcsetattr(ctx->fd, TCSANOW, &sdev->newtio) != 0) {
  33. log_print(LOG_WARN, "open_serial(): tcsetattr()");
  34. close(ctx->fd);
  35. return -1;
  36. }
  37. return 0;
  38. }
  39. static int setbaudrate(struct context *ctx, int baudrate)
  40. {
  41. struct serial_device *sdev = (struct serial_device *)ctx->dev_privdata;
  42. cfsetispeed(&sdev->newtio, baudrate);
  43. cfsetospeed(&sdev->newtio, baudrate);
  44. if (tcsetattr(ctx->fd, TCSANOW, &sdev->newtio) != 0) {
  45. log_print(LOG_WARN, "open_serial(): tcsetattr()");
  46. close(ctx->fd);
  47. return -1;
  48. }
  49. return 0;
  50. }
  51. static int close_serial(struct context *ctx)
  52. {
  53. struct serial_device *sdev = (struct serial_device *)ctx->dev_privdata;
  54. event_remove_fd(ctx->event);
  55. tcsetattr(ctx->fd, TCSANOW, &sdev->oldtio);
  56. free(ctx->devname);
  57. close(ctx->fd);
  58. return 0;
  59. }
  60. int serial_init(struct context *ctx, const char *device)
  61. {
  62. ctx->dev_privdata = malloc(sizeof(struct serial_device));
  63. if (ctx->dev_privdata == NULL) {
  64. log_print(LOG_WARN, "serial_init_cb(): out of memory");
  65. destroy_context(ctx);
  66. return -1;
  67. }
  68. if (open_serial(ctx, device) < 0) {
  69. free(ctx->dev_privdata);
  70. destroy_context(ctx);
  71. return -1;
  72. }
  73. log_print(LOG_EVERYTIME, "listen on %s", ctx->devname);
  74. ctx->dev_close = close_serial;
  75. ctx->dev_setbaudrate = setbaudrate;
  76. ctx->event = event_add_readfd(NULL, ctx->fd, statemachine_read, ctx);
  77. return 0;
  78. }