|
@@ -10,7 +10,7 @@
|
|
|
|
|
|
/* init global variables */
|
|
|
uint8_t protocolVersion = 0u;
|
|
|
-shellmatta_transport_packet_t packetType = 0u;
|
|
|
+shellmatta_transport_packet_t packetType = PACKET_DATA;
|
|
|
uint32_t payloadLength = 0u;
|
|
|
uint8_t source = 0u;
|
|
|
uint8_t destination = 0u;
|
|
@@ -20,29 +20,29 @@ uint8_t crcCounter = 0u;
|
|
|
uint8_t packetSequenceCounter_h2s = 0u;
|
|
|
uint8_t packetSequenceCounter_s2h = 0u;
|
|
|
shellmatta_transport_layer_t transportLayerInst = {
|
|
|
- 0,
|
|
|
- 0,
|
|
|
+ 0u,
|
|
|
+ 0u,
|
|
|
STATE_GET_SOH,
|
|
|
false,
|
|
|
false,
|
|
|
false,
|
|
|
NULL
|
|
|
};
|
|
|
-char payloadBuffer[SHELLMATTA_PAYLOAD_MAXLENGTH + 1];
|
|
|
+char payloadBuffer[SHELLMATTA_PAYLOAD_MAXLENGTH];
|
|
|
|
|
|
/**
|
|
|
* @brief Initializes the transportLayerInst
|
|
|
* @return errorcode #SHELLMATTA_OK
|
|
|
*/
|
|
|
-shellmatta_retCode_t shellmatta_init_transport_inst()
|
|
|
+shellmatta_retCode_t shellmatta_init_transport_inst(void)
|
|
|
{
|
|
|
- transportLayerInst.h2s_sequenceCnt = 0;
|
|
|
- transportLayerInst.s2h_sequenceCnt = 0;
|
|
|
+ transportLayerInst.h2s_sequenceCnt = 0u;
|
|
|
+ transportLayerInst.s2h_sequenceCnt = 0u;
|
|
|
transportLayerInst.state = STATE_GET_SOH;
|
|
|
transportLayerInst.mandatory = false;
|
|
|
transportLayerInst.active = false;
|
|
|
transportLayerInst.continueStep = false;
|
|
|
- memset(payloadBuffer, 0, SHELLMATTA_PAYLOAD_MAXLENGTH + 1);
|
|
|
+ memset(payloadBuffer, 0u, SHELLMATTA_PAYLOAD_MAXLENGTH);
|
|
|
|
|
|
return SHELLMATTA_OK;
|
|
|
}
|
|
@@ -51,11 +51,11 @@ shellmatta_retCode_t shellmatta_init_transport_inst()
|
|
|
* @brief Resets all values of tranportLayerInst except for sequence counters
|
|
|
* @return errorcode #SHELLMATTA_OK
|
|
|
*/
|
|
|
-shellmatta_retCode_t shellmatta_reset_transport()
|
|
|
+shellmatta_retCode_t shellmatta_reset_transport(void)
|
|
|
{
|
|
|
transportLayerInst.state = STATE_GET_SOH;
|
|
|
protocolVersion = 0u;
|
|
|
- packetType = 0u;
|
|
|
+ packetType = PACKET_DATA;
|
|
|
payloadLength = 0u;
|
|
|
source = 0u;
|
|
|
destination = 0u;
|
|
@@ -63,7 +63,7 @@ shellmatta_retCode_t shellmatta_reset_transport()
|
|
|
payloadCounter = 0u;
|
|
|
crcCounter = 0u;
|
|
|
transportLayerInst.active = false;
|
|
|
- memset(payloadBuffer, 0, SHELLMATTA_PAYLOAD_MAXLENGTH + 1);
|
|
|
+ memset(payloadBuffer, 0u, SHELLMATTA_PAYLOAD_MAXLENGTH);
|
|
|
|
|
|
return SHELLMATTA_OK;
|
|
|
}
|
|
@@ -88,7 +88,7 @@ shellmatta_retCode_t shellmatta_handle_transport_fsm(char *data)
|
|
|
transportLayerInst.state = STATE_GET_PROTOCOL_VERSION;
|
|
|
transportLayerInst.active = true;
|
|
|
}
|
|
|
- else
|
|
|
+ else if (0x00 != *data)
|
|
|
{
|
|
|
/* if SOH is not found, handle data as manual input */
|
|
|
transportLayerInst.state = STATE_MANUAL_INPUT;
|
|
@@ -166,17 +166,17 @@ shellmatta_retCode_t shellmatta_handle_transport_fsm(char *data)
|
|
|
if (SHELLMATTA_LENGTH_CRC <= crcCounter)
|
|
|
{
|
|
|
/* for crc computation only */
|
|
|
- char crcdata[SHELLMATTA_PAYLOAD_MAXLENGTH + 1 + SHELLMATTA_HEADER_LENGTH];
|
|
|
- memset(crcdata, 0, SHELLMATTA_PAYLOAD_MAXLENGTH + 1 + SHELLMATTA_HEADER_LENGTH);
|
|
|
- crcdata[0] = SHELLMATTA_START_OF_HEADER;
|
|
|
- crcdata[1] = protocolVersion;
|
|
|
- crcdata[2] = packetType;
|
|
|
- crcdata[3] = payloadLength;
|
|
|
- crcdata[4] = source;
|
|
|
- crcdata[5] = destination;
|
|
|
- crcdata[6] = packetSequenceCounter_h2s;
|
|
|
- crcdata[7] = packetSequenceCounter_s2h;
|
|
|
- strncat(&crcdata[8], payloadBuffer, payloadLength);
|
|
|
+ char crcdata[SHELLMATTA_PAYLOAD_MAXLENGTH + SHELLMATTA_HEADER_LENGTH];
|
|
|
+ memset(crcdata, 0u, SHELLMATTA_PAYLOAD_MAXLENGTH + SHELLMATTA_HEADER_LENGTH);
|
|
|
+ crcdata[SHELLMATTA_POS_SOH] = SHELLMATTA_START_OF_HEADER;
|
|
|
+ crcdata[SHELLMATTA_POS_PROT_VER] = protocolVersion;
|
|
|
+ crcdata[SHELLMATTA_POS_PACKET_TYPE] = packetType;
|
|
|
+ crcdata[SHELLMATTA_POS_PAYLOAD_LEN] = payloadLength;
|
|
|
+ crcdata[SHELLMATTA_POS_SRC] = source;
|
|
|
+ crcdata[SHELLMATTA_POS_DST] = destination;
|
|
|
+ crcdata[SHELLMATTA_POS_CNT_H2S] = packetSequenceCounter_h2s;
|
|
|
+ crcdata[SHELLMATTA_POS_CNT_S2H] = packetSequenceCounter_s2h;
|
|
|
+ strncat(&crcdata[SHELLMATTA_POS_PAYLOAD], payloadBuffer, payloadLength);
|
|
|
|
|
|
uint32_t refCrc;
|
|
|
|
|
@@ -201,7 +201,7 @@ shellmatta_retCode_t shellmatta_handle_transport_fsm(char *data)
|
|
|
/* change packet type to response */
|
|
|
packetType = PACKET_SEQ_CNT_RESPOND;
|
|
|
/* send out packet with no payload */
|
|
|
- shellmatta_write_transport("", 0);
|
|
|
+ shellmatta_write_transport("", 0u);
|
|
|
break;
|
|
|
|
|
|
case PACKET_SEQ_CNT_RESPOND:
|
|
@@ -240,8 +240,8 @@ shellmatta_retCode_t shellmatta_handle_transport_fsm(char *data)
|
|
|
}
|
|
|
|
|
|
/* reset crc variables */
|
|
|
- crcCounter = 0;
|
|
|
- crc32 = 0;
|
|
|
+ crcCounter = 0u;
|
|
|
+ crc32 = 0u;
|
|
|
}
|
|
|
break;
|
|
|
|
|
@@ -249,7 +249,7 @@ shellmatta_retCode_t shellmatta_handle_transport_fsm(char *data)
|
|
|
case STATE_PROCESS_PAYLOAD:
|
|
|
transportLayerInst.state = STATE_GET_SOH;
|
|
|
protocolVersion = 0u;
|
|
|
- packetType = 0u;
|
|
|
+ packetType = PACKET_DATA;
|
|
|
payloadLength = 0u;
|
|
|
source = 0u;
|
|
|
destination = 0u;
|
|
@@ -257,7 +257,7 @@ shellmatta_retCode_t shellmatta_handle_transport_fsm(char *data)
|
|
|
payloadCounter = 0u;
|
|
|
crcCounter = 0u;
|
|
|
transportLayerInst.active = false;
|
|
|
- memset(payloadBuffer, 0, SHELLMATTA_PAYLOAD_MAXLENGTH + 1);
|
|
|
+ memset(payloadBuffer, 0u, SHELLMATTA_PAYLOAD_MAXLENGTH);
|
|
|
break;
|
|
|
|
|
|
default:
|
|
@@ -274,43 +274,72 @@ shellmatta_retCode_t shellmatta_handle_transport_fsm(char *data)
|
|
|
* The input data is copied into a new array along with the header and crc32.\n
|
|
|
* The resulting buffer is the forwarded to the original write function.\n
|
|
|
*
|
|
|
+ * @note If length of data exceeds #UINT8_MAX, data is sent in multiple packets.\n
|
|
|
+ *
|
|
|
* @param[in] data pointer to input data to process
|
|
|
* @return errorcode #SHELLMATTA_OK
|
|
|
*/
|
|
|
shellmatta_retCode_t shellmatta_write_transport(const char* data, uint32_t length)
|
|
|
{
|
|
|
+ shellmatta_retCode_t ret = SHELLMATTA_OK;
|
|
|
+
|
|
|
/* create buffer for data + header + crc with maximum size */
|
|
|
- uint8_t outputBuffer[ SHELLMATTA_HEADER_LENGTH + /* length of header */
|
|
|
- SHELLMATTA_PAYLOAD_MAXLENGTH + 1 + /* max length of payload */
|
|
|
- SHELLMATTA_LENGTH_CRC]; /* length of crc */
|
|
|
+ uint8_t outputBuffer[ SHELLMATTA_HEADER_LENGTH + /* length of header */
|
|
|
+ SHELLMATTA_PAYLOAD_MAXLENGTH + /* max length of payload */
|
|
|
+ SHELLMATTA_LENGTH_CRC]; /* length of crc */
|
|
|
|
|
|
- uint32_t outPayloadLength = length + SHELLMATTA_HEADER_LENGTH + SHELLMATTA_LENGTH_CRC;
|
|
|
-
|
|
|
- /* fill buffer with header data */
|
|
|
- outputBuffer[0] = SHELLMATTA_START_OF_HEADER; /* start of header */
|
|
|
- outputBuffer[1] = PROTOCOL_VERSION; /* protocol version */
|
|
|
- outputBuffer[2] = packetType; /* packet type */
|
|
|
- outputBuffer[3] = length; /* payload length */
|
|
|
- outputBuffer[4] = 0x00u; /* source */
|
|
|
- outputBuffer[5] = 0x00u; /* destination */
|
|
|
- outputBuffer[6] = transportLayerInst.h2s_sequenceCnt; /* sequence counter host to shellmatta */
|
|
|
- outputBuffer[7] = ++transportLayerInst.s2h_sequenceCnt; /* sequence counter shellmatta to host */
|
|
|
-
|
|
|
- /* skip copying of payload in case of sequence counter response */
|
|
|
- if (packetType != PACKET_SEQ_CNT_RESPOND)
|
|
|
+ uint16_t outputBufferSize = sizeof(outputBuffer);
|
|
|
+ uint32_t outPayloadLength = length;
|
|
|
+
|
|
|
+ /* handle data with length bigger than max length */
|
|
|
+ uint16_t processedLength = 0u;
|
|
|
+ uint16_t splitLength = 0u;
|
|
|
+ uint16_t splitPayloadLength = 0u;
|
|
|
+ uint16_t restOfPayload = 0u;
|
|
|
+
|
|
|
+ /* foot-controlled loop to send packets without payload length */
|
|
|
+ do
|
|
|
{
|
|
|
- memcpy(&outputBuffer[8], data, length);
|
|
|
- }
|
|
|
+ /* compute length of next payload split */
|
|
|
+ restOfPayload = (outPayloadLength - processedLength);
|
|
|
+ if (restOfPayload > SHELLMATTA_PAYLOAD_MAXLENGTH)
|
|
|
+ {
|
|
|
+ splitLength = outputBufferSize;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ splitLength = (restOfPayload + SHELLMATTA_HEADER_LENGTH + SHELLMATTA_LENGTH_CRC) % outputBufferSize;
|
|
|
+ }
|
|
|
+ splitPayloadLength = splitLength - SHELLMATTA_HEADER_LENGTH - SHELLMATTA_LENGTH_CRC;
|
|
|
+
|
|
|
+ /* fill buffer with header data */
|
|
|
+ outputBuffer[SHELLMATTA_POS_SOH] = SHELLMATTA_START_OF_HEADER; /* start of header */
|
|
|
+ outputBuffer[SHELLMATTA_POS_PROT_VER] = PROTOCOL_VERSION; /* protocol version */
|
|
|
+ outputBuffer[SHELLMATTA_POS_PACKET_TYPE] = packetType; /* packet type */
|
|
|
+ outputBuffer[SHELLMATTA_POS_PAYLOAD_LEN] = splitPayloadLength; /* payload length */
|
|
|
+ outputBuffer[SHELLMATTA_POS_SRC] = 0x00u; /* source */
|
|
|
+ outputBuffer[SHELLMATTA_POS_DST] = 0x00u; /* destination */
|
|
|
+ outputBuffer[SHELLMATTA_POS_CNT_H2S] = transportLayerInst.h2s_sequenceCnt; /* sequence counter host to shellmatta */
|
|
|
+ outputBuffer[SHELLMATTA_POS_CNT_S2H] = ++transportLayerInst.s2h_sequenceCnt; /* sequence counter shellmatta to host */
|
|
|
+
|
|
|
+ /* skip copying of payload in case of sequence counter response */
|
|
|
+ if (packetType != PACKET_SEQ_CNT_RESPOND)
|
|
|
+ {
|
|
|
+ memcpy(&outputBuffer[SHELLMATTA_POS_PAYLOAD], data + processedLength, splitPayloadLength);
|
|
|
+ }
|
|
|
|
|
|
- uint32_t outCrc = crc32Calc((char*) outputBuffer, SHELLMATTA_HEADER_LENGTH + length);
|
|
|
+ uint32_t outCrc = crc32Calc((char*) outputBuffer, SHELLMATTA_HEADER_LENGTH + splitPayloadLength);
|
|
|
|
|
|
- /* append crc to end of payload */
|
|
|
- outputBuffer[length + SHELLMATTA_HEADER_LENGTH + 0] = (uint8_t)(outCrc >> 0);
|
|
|
- outputBuffer[length + SHELLMATTA_HEADER_LENGTH + 1] = (uint8_t)(outCrc >> 8);
|
|
|
- outputBuffer[length + SHELLMATTA_HEADER_LENGTH + 2] = (uint8_t)(outCrc >> 16);
|
|
|
- outputBuffer[length + SHELLMATTA_HEADER_LENGTH + 3] = (uint8_t)(outCrc >> 24);
|
|
|
+ /* append crc to end of payload */
|
|
|
+ outputBuffer[splitPayloadLength + SHELLMATTA_HEADER_LENGTH] = (uint8_t)(outCrc);
|
|
|
+ outputBuffer[splitPayloadLength + SHELLMATTA_HEADER_LENGTH + SHELLMATTA_SHIFT_BY_1] = (uint8_t)(outCrc >> SHELLMATTA_SHIFT_BY_8);
|
|
|
+ outputBuffer[splitPayloadLength + SHELLMATTA_HEADER_LENGTH + SHELLMATTA_SHIFT_BY_2] = (uint8_t)(outCrc >> SHELLMATTA_SHIFT_BY_16);
|
|
|
+ outputBuffer[splitPayloadLength + SHELLMATTA_HEADER_LENGTH + SHELLMATTA_SHIFT_BY_3] = (uint8_t)(outCrc >> SHELLMATTA_SHIFT_BY_24);
|
|
|
|
|
|
- /* use original write function to send full buffer */
|
|
|
- shellmatta_retCode_t ret = transportLayerInst.originalWrite((char*) outputBuffer, outPayloadLength);
|
|
|
+ /* use original write function to send full buffer */
|
|
|
+ ret = transportLayerInst.originalWrite((char*) outputBuffer, splitLength);
|
|
|
+ processedLength += splitPayloadLength;
|
|
|
+ }
|
|
|
+ while (processedLength < outPayloadLength);
|
|
|
return ret;
|
|
|
}
|