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.

111 lines
2.3 KiB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <termios.h>
  6. #include "context.h"
  7. #include "linebuffer.h"
  8. #include "logging.h"
  9. #include "xmodem.h"
  10. /* states */
  11. enum {
  12. STATE_NONE = 0,
  13. STATE_DEBUG_ASK, /* waiting for "Press any key.." */
  14. STATE_DEBUG, /* debug mode entered */
  15. STATE_SWITCH_BAUDRATE, /* switching baudrate */
  16. STATE_XMODEM, /* xmodem active */
  17. STATE_XMODEM_COMPLETE, /* xmodem complete */
  18. STATE_BOOT, /* booting firmware */
  19. };
  20. /* messages */
  21. char *rx_msg[] = {
  22. "Press any key to enter debug mode within 3 seconds.",
  23. "Enter Debug Mode",
  24. "Now, console speed will be changed to 115200 bps",
  25. "OK",
  26. "Console speed will be changed to 9600 bps",
  27. NULL
  28. };
  29. /* message IDs */
  30. enum {
  31. MSG_DEBUG_ASK = 0,
  32. MSG_DEBUG,
  33. MSG_BAUD_HIGH,
  34. MSG_XMODEM_OK,
  35. MSG_BAUD_LOW,
  36. };
  37. int statemachine_read(int fd, void *privdata)
  38. {
  39. struct context *ctx = (struct context *)privdata;
  40. if (ctx->state == STATE_XMODEM) {
  41. if (xmodem_read(fd, privdata) < 0)
  42. ctx->state = STATE_XMODEM_COMPLETE;
  43. return 0;
  44. }
  45. if (linebuffer_read(ctx->lbuf, fd) < 0)
  46. return -1;
  47. char *line;
  48. while ((line = linebuffer_get(ctx->lbuf)) != NULL) {
  49. log_print(LOG_DEBUG, "%s: '%s'", ctx->devname, line);
  50. int msg = 0;
  51. while (rx_msg[msg] != NULL) {
  52. if (strcmp(line, rx_msg[msg]) == 0)
  53. break;
  54. msg++;
  55. }
  56. /* wait for "Press any key" */
  57. if (msg == MSG_DEBUG_ASK) {
  58. ctx->state = STATE_DEBUG_ASK;
  59. write(fd, "\r\n", 2);
  60. /* debug mode entered */
  61. } else if (msg == MSG_DEBUG) {
  62. /* if device supports it, switch to high baudrate */
  63. if (ctx->dev_setbaudrate != NULL) {
  64. ctx->state = STATE_SWITCH_BAUDRATE;
  65. write(fd, "ATBA5\r\n", 7);
  66. } else {
  67. ctx->state = STATE_XMODEM;
  68. write(fd, "ATLC\r\n", 6);
  69. }
  70. /* follow device to high baudrate */
  71. } else if (msg == MSG_BAUD_HIGH) {
  72. ctx->dev_setbaudrate(ctx, B115200);
  73. linebuffer_clear(ctx->lbuf);
  74. ctx->state = STATE_XMODEM;
  75. write(fd, "ATLC\r\n", 6);
  76. /* transfer was success */
  77. } else if (msg == MSG_XMODEM_OK && ctx->state == STATE_XMODEM_COMPLETE) {
  78. ctx->state = STATE_BOOT;
  79. write(fd, "ATGR\r\n", 6);
  80. /* follow device to low baudrate */
  81. } else if (msg == MSG_BAUD_LOW) {
  82. ctx->dev_setbaudrate(ctx, B9600);
  83. linebuffer_clear(ctx->lbuf);
  84. }
  85. free(line);
  86. };
  87. return 0;
  88. }