|
@@ -34,6 +34,7 @@ typedef enum {
|
|
#define YMODEM_PACKET_SIZE 128u /**< default packet size of ymodem transmission */
|
|
#define YMODEM_PACKET_SIZE 128u /**< default packet size of ymodem transmission */
|
|
#define YMODEM_PACKET_SIZE_1K 1024u /**< extended packet size of ymodem transmission */
|
|
#define YMODEM_PACKET_SIZE_1K 1024u /**< extended packet size of ymodem transmission */
|
|
#define YMODEM_CRC_SIZE 2u /**< CRC size of the ymodem packet */
|
|
#define YMODEM_CRC_SIZE 2u /**< CRC size of the ymodem packet */
|
|
|
|
+#define YMODEM_EOT_NUMBER 2u /**< Number of EOTs or polls to be received */
|
|
|
|
|
|
/**
|
|
/**
|
|
* @brief forwards the given character to write-function without formatting
|
|
* @brief forwards the given character to write-function without formatting
|
|
@@ -72,6 +73,7 @@ static void shellmatta_ymodem_reset(shellmatta_handle_t handle, bool doCancel)
|
|
inst->ymodem.totalBytesReceived = 0u;
|
|
inst->ymodem.totalBytesReceived = 0u;
|
|
inst->ymodem.fileSize = 0u;
|
|
inst->ymodem.fileSize = 0u;
|
|
inst->ymodem.pauseRequested = false;
|
|
inst->ymodem.pauseRequested = false;
|
|
|
|
+ inst->ymodem.pollCyclesLeft = 0u;
|
|
|
|
|
|
#ifdef SHELLMATTA_TRANSPORT
|
|
#ifdef SHELLMATTA_TRANSPORT
|
|
/** .-# reenable transport layer optional mode */
|
|
/** .-# reenable transport layer optional mode */
|
|
@@ -145,28 +147,13 @@ static shellmatta_retCode_t ymodem_stateMachine(shellmatta_handle_t handle, uint
|
|
break;
|
|
break;
|
|
|
|
|
|
case YMODEM_EOT:
|
|
case YMODEM_EOT:
|
|
- /** -# check if the received data matches the file size */
|
|
|
|
- if((inst->ymodem.totalBytesReceived < inst->ymodem.fileSize) ||
|
|
|
|
- ((inst->ymodem.totalBytesReceived - inst->ymodem.fileSize) >= YMODEM_PACKET_SIZE_1K))
|
|
|
|
- {
|
|
|
|
- ret = SHELLMATTA_ERROR;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- inst->ymodem.transmissionCompleteCallback(ret);
|
|
|
|
-
|
|
|
|
- // todo add a wait state to answer some more EOTs after time
|
|
|
|
-
|
|
|
|
/** -# ACK the successful file reception */
|
|
/** -# ACK the successful file reception */
|
|
shellmatta_ymodem_control(handle, YMODEM_ACK);
|
|
shellmatta_ymodem_control(handle, YMODEM_ACK);
|
|
shellmatta_ymodem_control(handle, YMODEM_CRC);
|
|
shellmatta_ymodem_control(handle, YMODEM_CRC);
|
|
|
|
|
|
-#ifdef SHELLMATTA_TRANSPORT
|
|
|
|
- /** .-# reenable transport layer optional mode */
|
|
|
|
- inst->transportLayer.suspendOptional = false;
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
- inst->ymodem.state = SHELLMATTA_YMODEM_INACTIVE;
|
|
|
|
- (void)utils_terminateInput(inst);
|
|
|
|
|
|
+ /** -# handle additional EOTs in WAIT FOR END state */
|
|
|
|
+ inst->ymodem.state = SHELLMATTA_YMODEM_WAIT_FOR_END;
|
|
|
|
+ inst->ymodem.pollCyclesLeft = YMODEM_EOT_NUMBER;
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
/** -# ignore unexpected characters on start */
|
|
/** -# ignore unexpected characters on start */
|
|
@@ -251,6 +238,16 @@ static shellmatta_retCode_t ymodem_stateMachine(shellmatta_handle_t handle, uint
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
|
|
+ case SHELLMATTA_YMODEM_WAIT_FOR_END:
|
|
|
|
+
|
|
|
|
+ inst->ymodem.pollCyclesLeft = YMODEM_EOT_NUMBER;
|
|
|
|
+ if(YMODEM_EOT == byte)
|
|
|
|
+ {
|
|
|
|
+ /** -# ACK the successful file reception */
|
|
|
|
+ shellmatta_ymodem_control(handle, YMODEM_ACK);
|
|
|
|
+ shellmatta_ymodem_control(handle, YMODEM_CRC);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
/** -# unexpected state - should never happen */
|
|
/** -# unexpected state - should never happen */
|
|
break;
|
|
break;
|
|
@@ -287,11 +284,41 @@ shellmatta_retCode_t shellmatta_ymodem_poll(shellmatta_handle_t handle)
|
|
shellmatta_retCode_t ret = SHELLMATTA_ERROR;
|
|
shellmatta_retCode_t ret = SHELLMATTA_ERROR;
|
|
shellmatta_instance_t *inst = (shellmatta_instance_t*)handle;
|
|
shellmatta_instance_t *inst = (shellmatta_instance_t*)handle;
|
|
|
|
|
|
- if (inst->ymodem.state == SHELLMATTA_YMODEM_WAIT_FOR_START)
|
|
|
|
|
|
+ switch (inst->ymodem.state)
|
|
{
|
|
{
|
|
|
|
+ case SHELLMATTA_YMODEM_WAIT_FOR_START:
|
|
/** -# send ymodem symbol to start transmission */
|
|
/** -# send ymodem symbol to start transmission */
|
|
shellmatta_ymodem_control(handle, YMODEM_CRC);
|
|
shellmatta_ymodem_control(handle, YMODEM_CRC);
|
|
ret = SHELLMATTA_OK;
|
|
ret = SHELLMATTA_OK;
|
|
|
|
+ break;
|
|
|
|
+ case SHELLMATTA_YMODEM_WAIT_FOR_END:
|
|
|
|
+ if(0u != inst->ymodem.pollCyclesLeft)
|
|
|
|
+ {
|
|
|
|
+ inst->ymodem.pollCyclesLeft --;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ ret = SHELLMATTA_OK;
|
|
|
|
+ /** -# check if the received data matches the file size */
|
|
|
|
+ if((inst->ymodem.totalBytesReceived < inst->ymodem.fileSize) ||
|
|
|
|
+ ((inst->ymodem.totalBytesReceived - inst->ymodem.fileSize) >= YMODEM_PACKET_SIZE_1K))
|
|
|
|
+ {
|
|
|
|
+ ret = SHELLMATTA_ERROR;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+#ifdef SHELLMATTA_TRANSPORT
|
|
|
|
+ /** .-# reenable transport layer optional mode */
|
|
|
|
+ inst->transportLayer.suspendOptional = false;
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ shellmatta_ymodem_reset(handle, false);
|
|
|
|
+ inst->ymodem.transmissionCompleteCallback(ret);
|
|
|
|
+ (void)utils_terminateInput(inst);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ /* nothing to do */
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
|
|
return ret;
|
|
return ret;
|