1
0
Эх сурвалжийг харах

ymodem support multiple files transmission

Lyn 6 жил өмнө
parent
commit
626d0e9e06

+ 30 - 8
components/utilities/ymodem/ymodem.c

@@ -266,6 +266,7 @@ static rt_err_t _rym_do_fin(struct rym_ctx *ctx)
     enum rym_code code;
     rt_uint16_t recv_crc;
     rt_size_t i;
+    rt_size_t data_sz;
 
     ctx->stage = RYM_STAGE_FINISHING;
     /* we already got one EOT in the caller. invoke the callback if there is
@@ -282,7 +283,15 @@ static rt_err_t _rym_do_fin(struct rym_ctx *ctx)
     _rym_putchar(ctx, RYM_CODE_C);
 
     code = _rym_read_code(ctx, RYM_WAIT_PKG_TICK);
-    if (code != RYM_CODE_SOH)
+    if (code == RYM_CODE_SOH)
+    {
+        data_sz = _RYM_SOH_PKG_SZ;
+    }
+    else if(code == RYM_CODE_STX)
+    {
+        data_sz = _RYM_STX_PKG_SZ;
+    }
+    else
         return -RYM_ERR_CODE;
 
     i = _rym_read_data(ctx, _RYM_SOH_PKG_SZ-1);
@@ -290,8 +299,6 @@ static rt_err_t _rym_do_fin(struct rym_ctx *ctx)
         return -RYM_ERR_DSZ;
 
     /* sanity check
-     *
-     * TODO: multiple files transmission
      */
     if (ctx->buf[1] != 0 || ctx->buf[2] != 0xFF)
         return -RYM_ERR_SEQ;
@@ -300,6 +307,14 @@ static rt_err_t _rym_do_fin(struct rym_ctx *ctx)
     if (recv_crc != CRC16(ctx->buf+3, _RYM_SOH_PKG_SZ-5))
         return -RYM_ERR_CRC;
 
+    /*next file transmission*/
+    if (ctx->buf[3] != 0)
+    {
+        if (ctx->on_begin && ctx->on_begin(ctx, ctx->buf+3, data_sz-5) != RYM_CODE_ACK)
+            return -RYM_ERR_CAN;
+        return RT_EOK;
+    }
+
     /* congratulations, check passed. */
     ctx->stage = RYM_STAGE_FINISHED;
 
@@ -324,12 +339,19 @@ static rt_err_t _rym_do_recv(
     err = _rym_do_handshake(ctx, handshake_timeout);
     if (err != RT_EOK)
         return err;
+    while (1)
+    {
+        err = _rym_do_trans(ctx);
+        if (err != RT_EOK)
+            return err;
 
-    err = _rym_do_trans(ctx);
-    if (err != RT_EOK)
-        return err;
-
-    return _rym_do_fin(ctx);
+        err = _rym_do_fin(ctx);
+        if (err != RT_EOK)
+            return err;
+        if (ctx->stage == RYM_STAGE_FINISHED)
+            break;
+    }
+    return err;
 }
 
 rt_err_t rym_recv_on_device(