Prechádzať zdrojové kódy

possibly stable version

Fischer, Simon | Friedrich Lütze GmbH 3 rokov pred
rodič
commit
e148b51adc
1 zmenil súbory, kde vykonal 84 pridanie a 55 odobranie
  1. 84 55
      src/shellmatta_transport.c

+ 84 - 55
src/shellmatta_transport.c

@@ -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;
 }