Преглед изворни кода

currently at least mostly stable working

Fischer, Simon пре 3 година
родитељ
комит
1449371f88
4 измењених фајлова са 90 додато и 54 уклоњено
  1. 10 7
      src/shellmatta.c
  2. 5 5
      src/shellmatta_crc.c
  3. 68 37
      src/shellmatta_transport.c
  4. 7 5
      src/shellmatta_transport.h

+ 10 - 7
src/shellmatta.c

@@ -121,6 +121,7 @@ shellmatta_retCode_t shellmatta_doInit(
 
         /* init transport layer */
         shellmatta_init_transport_inst();
+        transportLayerInst.originalWrite = inst->write;
     }
 
     return SHELLMATTA_OK;
@@ -395,7 +396,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
             while ( (size > headerCounter) 
                 ||  (   (true == transportLayerInst.mandatory)
                     &&  (size > headerCounter))
-                ||  (   (true == transportLayerInst.continueStep)))
+                ||  (true == transportLayerInst.continueStep))
             {
                 switch (transportLayerInst.state)
                 {
@@ -424,11 +425,11 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                     break;
                 
                 case STATE_GET_H2S_SEQUENCE_CNT:
-                    transportLayerInst.h2s_sequenceCnt = data[headerCounter];
+                    packetSequenceCounter_h2s = data[headerCounter];
                     break;
                 
                 case STATE_GET_S2H_SEQUENCE_CNT:
-                    transportLayerInst.s2h_sequenceCnt = data[headerCounter];
+                    packetSequenceCounter_s2h = data[headerCounter];
                     break;
 
                 case STATE_GET_PAYLOAD:
@@ -454,7 +455,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                 if (SHELLMATTA_ERROR == ret)
                 {
                     shellmatta_reset_transport();
-                    shellmatta_printf(handle, "crc error");
+                    utils_writeEcho(handle, "crc error\r\n", 11);
                     utils_terminateInput(inst);
                     return SHELLMATTA_OK;
                 }
@@ -463,12 +464,14 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
 
                 if (transportLayerInst.state == STATE_PROCESS_PAYLOAD)
                 {
-                    /* recursive call with complete payload */
-                    // TODO: replace inst->write function pointer with transport layer write function
+                    /* replace inst->write function pointer with transport layer write function */
                     transportLayerInst.originalWrite = inst->write;
                     inst->write = shellmatta_write_transport;
+                    
+                    /* recursive call with complete payload */
                     shellmatta_processData(handle, payloadBuffer, payloadLength);
-                    // TODO: set back inst->write function pointer to original
+                    
+                    /* set back inst->write function pointer to original */
                     inst->write = transportLayerInst.originalWrite;
                     shellmatta_handle_transport_fsm(data);
                     return SHELLMATTA_OK;

+ 5 - 5
src/shellmatta_crc.c

@@ -51,11 +51,11 @@ uint32_t crc32Table[] = {
  */
 uint32_t reverse(uint32_t x, int bits)
 {
-    x = ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1); // Swap _<>_
-    x = ((x & 0x33333333) << 2) | ((x & 0xCCCCCCCC) >> 2); // Swap __<>__
-    x = ((x & 0x0F0F0F0F) << 4) | ((x & 0xF0F0F0F0) >> 4); // Swap ____<>____
-    x = ((x & 0x00FF00FF) << 8) | ((x & 0xFF00FF00) >> 8); // Swap ...
-    x = ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16); // Swap ...
+    x = ((x & 0x55555555) << 1)  | ((x & 0xAAAAAAAA) >> 1);
+    x = ((x & 0x33333333) << 2)  | ((x & 0xCCCCCCCC) >> 2);
+    x = ((x & 0x0F0F0F0F) << 4)  | ((x & 0xF0F0F0F0) >> 4);
+    x = ((x & 0x00FF00FF) << 8)  | ((x & 0xFF00FF00) >> 8);
+    x = ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16);
     return x >> (32 - bits);
 }
 

+ 68 - 37
src/shellmatta_transport.c

@@ -7,8 +7,11 @@
 #include "shellmatta_transport.h"
 #include "shellmatta_crc.h"
 #include <string.h>
+#include <stdio.h>
 
 /* init global variables */
+uint32_t sentPayloadBytes = 0;
+
 uint8_t protocolVersion                     = 0u;
 shellmatta_transport_packet_t packetType    = 0u;
 uint8_t payloadLength                       = 0u;
@@ -17,8 +20,8 @@ uint8_t destination                         = 0u;
 uint32_t crc32                              = 0u;
 uint8_t payloadCounter                      = 0u;
 uint8_t crcCounter                          = 0u;
-uint32_t packetSequenceCounter_h2s          = 0u;
-uint32_t packetSequenceCounter_s2h          = 0u;
+uint8_t packetSequenceCounter_h2s           = 0u;
+uint8_t packetSequenceCounter_s2h           = 0u;
 shellmatta_transport_layer_t transportLayerInst = {
     0,
     0,
@@ -105,7 +108,14 @@ shellmatta_retCode_t shellmatta_handle_transport_fsm(char *data)
         break;
 
     case STATE_GET_S2H_SEQUENCE_CNT:
-        transportLayerInst.state = STATE_GET_PAYLOAD;
+        if (packetType == PACKET_SEQ_CNT_REQUEST)
+        {
+            transportLayerInst.state = STATE_GET_CRC;
+        }
+        else
+        {
+            transportLayerInst.state = STATE_GET_PAYLOAD;
+        }
         break;
 
     case STATE_GET_PAYLOAD:
@@ -119,73 +129,85 @@ shellmatta_retCode_t shellmatta_handle_transport_fsm(char *data)
     case STATE_GET_CRC:
         if (SHELLMATTA_LENGTH_CRC <= crcCounter)
         {
-            char data[SHELLMATTA_PAYLOAD_MAXLENGTH + 1 + SHELLMATTA_HEADER_LENGTH];
-            memset(data, 0, SHELLMATTA_PAYLOAD_MAXLENGTH + 1 + SHELLMATTA_HEADER_LENGTH);
-            data[0] = SHELLMATTA_START_OF_HEADER;
-            data[1] = protocolVersion;
-            data[2] = packetType;
-            data[3] = payloadLength;
-            data[4] = source;
-            data[5] = destination;
-            data[6] = transportLayerInst.h2s_sequenceCnt;
-            data[7] = transportLayerInst.s2h_sequenceCnt;
-            strncat(&data[8], payloadBuffer, payloadLength);
+            
+            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);
 
             uint32_t refCrc;
 
-            refCrc = crc32Calc(data, SHELLMATTA_HEADER_LENGTH + payloadLength);
+            refCrc = crc32Calc(crcdata, SHELLMATTA_HEADER_LENGTH + payloadLength);
 
             if (crc32 == refCrc)
             {
+                crcCounter = 0;
+                crc32 = 0;
+                transportLayerInst.state = STATE_GET_SOH;
+
                 /* crc is correct */
+                transportLayerInst.h2s_sequenceCnt++;
 
                 switch (packetType)
                 {
                 case PACKET_DATA:
                     transportLayerInst.state = STATE_PROCESS_PAYLOAD;
-                    transportLayerInst.h2s_sequenceCnt++;
                     break;
                 
                 case PACKET_SEQ_CNT_REQUEST:
-                    transportLayerInst.h2s_sequenceCnt++;
+                    /* change packet type to response */
+                    packetType = PACKET_SEQ_CNT_RESPOND;
+                    /* send out packet with no payload */
+                    shellmatta_write_transport("", 0);
+                    if (transportLayerInst.h2s_sequenceCnt != packetSequenceCounter_h2s)
+                    {
+                        crc32 = 0;
+                    }
                     break;
 
                 case PACKET_SEQ_CNT_RESPOND:
-                    transportLayerInst.h2s_sequenceCnt++;
                     break;
                 
                 case PACKET_MAX_BUFFERSIZE_REQUEST:
-                    transportLayerInst.h2s_sequenceCnt++;
                     break;
 
                 case PACKET_MAX_BUFFERSIZE_RESPOND:
-                    transportLayerInst.h2s_sequenceCnt++;
                     break;
                 
                 case PACKET_SEARCH_DEVICE_REQUEST:
-                    transportLayerInst.h2s_sequenceCnt++;
                     break;
                 
                 case PACKET_SEARCH_DEVICE_RESPOND:
-                    transportLayerInst.h2s_sequenceCnt++;
                     break;
 
                 case PACKET_SET_ADDRESS_REQUEST:
-                    transportLayerInst.h2s_sequenceCnt++;
                     break;
 
                 case PACKET_SET_ADDRESS_RESPOND:
-                    transportLayerInst.h2s_sequenceCnt++;
                     break;
 
-                /* should not happen */
+                /* wrong packet type */
                 default:
+                    /* undo sequence counter increment */
+                    transportLayerInst.h2s_sequenceCnt--;
                     break;
                 }
                 break;
             }
             else
             {
+                // TODO: improve this
+                crcCounter = 0;
+                crc32 = 0;
+                transportLayerInst.state = STATE_GET_SOH;
+
                 /* crc is incorrect */
                 return SHELLMATTA_ERROR;
             }
@@ -215,29 +237,38 @@ shellmatta_retCode_t shellmatta_handle_transport_fsm(char *data)
 
 shellmatta_retCode_t shellmatta_write_transport(const char* data, uint32_t length)
 {
+    /* 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 outPayloadLength = length + SHELLMATTA_HEADER_LENGTH + SHELLMATTA_LENGTH_CRC;
-
-    outputBuffer[0] = SHELLMATTA_START_OF_HEADER;
-    outputBuffer[1] = 0x01u;
-    outputBuffer[2] = 0x00u;
-    outputBuffer[3] = length;
-    outputBuffer[4] = 0x01u;
-    outputBuffer[5] = 0x00u;
-    outputBuffer[6] = transportLayerInst.h2s_sequenceCnt;
-    outputBuffer[7] = ++transportLayerInst.s2h_sequenceCnt;
-
-    memcpy(&outputBuffer[8], data, length);
+    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 */
+
+    /* response of sequence counters is only packet type without payload */
+    if (packetType != PACKET_SEQ_CNT_RESPOND)
+    {
+        memcpy(&outputBuffer[8], data, length);
+    }
+
     uint32_t outCrc = crc32Calc((char*) outputBuffer, SHELLMATTA_HEADER_LENGTH + length);
 
+    /* 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);
 
+    /* use original write function to send full buffer */
     shellmatta_retCode_t ret = transportLayerInst.originalWrite((char*) outputBuffer, outPayloadLength);
     return ret;
 }

+ 7 - 5
src/shellmatta_transport.h

@@ -9,6 +9,8 @@
 
 #include "shellmatta.h"
 
+#define PROTOCOL_VERSION                    0x01u
+
 /** @brief value of start-of-header character */
 #define SHELLMATTA_START_OF_HEADER          0x01u
 
@@ -83,13 +85,13 @@ typedef enum
 
 typedef struct
 {
-    uint32_t h2s_sequenceCnt;               /**<  */
-    uint32_t s2h_sequenceCnt;               /**<  */
+    uint8_t h2s_sequenceCnt;                /**<  */
+    uint8_t s2h_sequenceCnt;                /**<  */
     shellmatta_transport_state_t state;     /**<  */
     bool mandatory;                         /**<  */
     bool active;                            /**<  */
     bool continueStep;                      /**<  */
-    shellmatta_write_t originalWrite;        /**<  */
+    shellmatta_write_t originalWrite;       /**<  */
 } shellmatta_transport_layer_t;
 
 extern uint8_t protocolVersion;
@@ -100,8 +102,8 @@ extern uint8_t destination;
 extern uint32_t crc32;
 extern uint8_t payloadCounter;
 extern uint8_t crcCounter;
-extern uint32_t packetSequenceCounter_h2s;
-extern uint32_t packetSequenceCounter_s2h;
+extern uint8_t packetSequenceCounter_h2s;
+extern uint8_t packetSequenceCounter_s2h;
 extern char payloadBuffer[SHELLMATTA_PAYLOAD_MAXLENGTH + 1];
 
 extern shellmatta_transport_layer_t transportLayerInst;