ymodem.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #ifndef __YMODEM_H__
  2. #define __YMODEM_H__
  3. /*
  4. * File : ymodem.h
  5. * COPYRIGHT (C) 2012, Shanghai Real-Thread Technology Co., Ltd
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2013-04-14 Grissiom initial implementation
  10. */
  11. #include "rtthread.h"
  12. /* The word "RYM" is stand for "Real-YModem". */
  13. enum rym_code {
  14. RYM_CODE_NONE = 0x00,
  15. RYM_CODE_SOH = 0x01,
  16. RYM_CODE_STX = 0x02,
  17. RYM_CODE_EOT = 0x04,
  18. RYM_CODE_ACK = 0x06,
  19. RYM_CODE_NAK = 0x15,
  20. RYM_CODE_CAN = 0x18,
  21. RYM_CODE_C = 0x43,
  22. };
  23. /* RYM error code
  24. *
  25. * We use the rt_err_t to return error values. We take use of current error
  26. * codes available in RTT and append ourselves.
  27. */
  28. /* timeout on handshake */
  29. #define RYM_ERR_TMO 0x70
  30. /* wrong code, wrong SOH, STX etc. */
  31. #define RYM_ERR_CODE 0x71
  32. /* wrong sequence number */
  33. #define RYM_ERR_SEQ 0x72
  34. /* wrong CRC checksum */
  35. #define RYM_ERR_CRC 0x73
  36. /* not enough data received */
  37. #define RYM_ERR_DSZ 0x74
  38. /* the transmission is aborted by user */
  39. #define RYM_ERR_CAN 0x75
  40. /* how many ticks wait for chars between packet. */
  41. #ifndef RYM_WAIT_CHR_TICK
  42. #define RYM_WAIT_CHR_TICK (RT_TICK_PER_SECOND * 3)
  43. #endif
  44. /* how many ticks wait for between packet. */
  45. #ifndef RYM_WAIT_PKG_TICK
  46. #define RYM_WAIT_PKG_TICK (RT_TICK_PER_SECOND * 3)
  47. #endif
  48. /* how many ticks between two handshake code. */
  49. #ifndef RYM_CHD_INTV_TICK
  50. #define RYM_CHD_INTV_TICK (RT_TICK_PER_SECOND * 3)
  51. #endif
  52. /* how many CAN be sent when user active end the session. */
  53. #ifndef RYM_END_SESSION_SEND_CAN_NUM
  54. #define RYM_END_SESSION_SEND_CAN_NUM 0x07
  55. #endif
  56. enum rym_stage {
  57. RYM_STAGE_NONE,
  58. /* set when C is send */
  59. RYM_STAGE_ESTABLISHING,
  60. /* set when we've got the packet 0 and sent ACK and second C */
  61. RYM_STAGE_ESTABLISHED,
  62. /* set when the sender respond to our second C and recviever got a real
  63. * data packet. */
  64. RYM_STAGE_TRANSMITTING,
  65. /* set when the sender send a EOT */
  66. RYM_STAGE_FINISHING,
  67. /* set when transmission is really finished, i.e., after the NAK, C, final
  68. * NULL packet stuff. */
  69. RYM_STAGE_FINISHED,
  70. };
  71. struct rym_ctx;
  72. /* when receiving files, the buf will be the data received from ymodem protocol
  73. * and the len is the data size.
  74. *
  75. * TODO:
  76. * When sending files, the len is the buf size in RYM. The callback need to
  77. * fill the buf with data to send. Returning RYM_CODE_EOT will terminate the
  78. * transfer and the buf will be discarded. Any other return values will cause
  79. * the transfer continue.
  80. */
  81. typedef enum rym_code (*rym_callback)(struct rym_ctx *ctx, rt_uint8_t *buf, rt_size_t len);
  82. /* Currently RYM only support one transfer session(ctx) for simplicity.
  83. *
  84. * In case we could support multiple sessions in The future, the first argument
  85. * of APIs are (struct rym_ctx*).
  86. */
  87. struct rym_ctx
  88. {
  89. rym_callback on_data;
  90. rym_callback on_begin;
  91. rym_callback on_end;
  92. /* When error happened, user need to check this to get when the error has
  93. * happened. */
  94. enum rym_stage stage;
  95. /* user could get the error content through this */
  96. rt_uint8_t *buf;
  97. struct rt_semaphore sem;
  98. rt_device_t dev;
  99. };
  100. /** recv a file on device dev with ymodem session ctx.
  101. *
  102. * If an error happens, you can get where it is failed from ctx->stage.
  103. *
  104. * @param on_begin The callback will be invoked when the first packet arrived.
  105. * This packet often contain file names and the size of the file, if the sender
  106. * support it. So if you want to save the data to a file, you may need to
  107. * create the file on need. It is the on_begin's responsibility to parse the
  108. * data content. The on_begin can be NULL, in which case the transmission will
  109. * continue without any side-effects.
  110. *
  111. * @param on_data The callback will be invoked on the packets received. The
  112. * callback should save the data to the destination. The return value will be
  113. * sent to the sender and in turn, only RYM_{ACK,CAN} is valid. When on_data is
  114. * NULL, RYM will barely send ACK on every packet and have no side-effects.
  115. *
  116. * @param on_end The callback will be invoked when one transmission is
  117. * finished. The data should be 128 bytes of NULL. You can do some cleaning job
  118. * in this callback such as closing the file. The return value of this callback
  119. * is ignored. As above, this parameter can be NULL if you don't need such
  120. * function.
  121. *
  122. * @param handshake_timeout the timeout when hand shaking. The unit is in
  123. * second.
  124. */
  125. rt_err_t rym_recv_on_device(struct rym_ctx *ctx, rt_device_t dev, rt_uint16_t oflag,
  126. rym_callback on_begin, rym_callback on_data, rym_callback on_end,
  127. int handshake_timeout);
  128. #endif