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