Ver Fonte

basic transport layer working

Fischer, Simon há 3 anos atrás
pai
commit
714785561b
3 ficheiros alterados com 155 adições e 74 exclusões
  1. 81 52
      src/shellmatta.c
  2. 61 13
      src/shellmatta_transport.c
  3. 13 9
      src/shellmatta_transport.h

+ 81 - 52
src/shellmatta.c

@@ -386,73 +386,95 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
     if(     (NULL               != inst)
         &&  (SHELLMATTA_MAGIC   == inst->magic))
     {
-
-        uint8_t headerCounter = 0;
-        while ( (size >= headerCounter) 
-            ||  (   (true == transportLayerInst.mandatory)
-                &&  (size >= headerCounter)))
+        if (    (transportLayerInst.state != STATE_PROCESS_PAYLOAD)
+            &&  (transportLayerInst.state != STATE_MANUAL_INPUT))
         {
-            /* if payload is reached, continue with usual behaviour */
-            if (STATE_GET_PAYLOAD == transportLayerInst.state)
+            // TODO: Move this into shellmatta_transport.c
+            /* use headerCounter to watch how many header fields have been worked on */
+            uint8_t headerCounter = 0;
+            while ( (size > headerCounter) 
+                ||  (   (true == transportLayerInst.mandatory)
+                    &&  (size > headerCounter))
+                ||  (   (true == transportLayerInst.continueStep)))
             {
-                break;
-            }
+                switch (transportLayerInst.state)
+                {
+                case STATE_GET_SOH:
+                    /* wait for SOH or go to payload */
+                    break;
 
-            switch (transportLayerInst.state)
-            {
-            case STATE_GET_SOH:
-                /* wait for SOH or go to payload */
-                break;
+                case STATE_GET_PROTOCOL_VERSION:
+                    protocolVersion = data[headerCounter];
+                    break;
 
-            case STATE_GET_PROTOCOL_VERSION:
-                protocolVersion = data[headerCounter];
-                break;
+                case STATE_GET_PACKET_TYPE:
+                    packetType = data[headerCounter];
+                    break;
 
-            case STATE_GET_PACKET_TYPE:
-                packetType = data[headerCounter];
-                break;
+                case STATE_GET_PAYLOAD_LENGTH:
+                    payloadLength = data[headerCounter];
+                    break;
 
-            case STATE_GET_PAYLOAD_LENGTH:
-                payloadLength = data[headerCounter];
-                break;
+                case STATE_GET_SOURCE:
+                    source = data[headerCounter];
+                    break;
 
-            case STATE_GET_SOURCE:
-                source = data[headerCounter];
-                break;
+                case STATE_GET_DESTINATION:
+                    destination = data[headerCounter];
+                    break;
+                
+                case STATE_GET_H2S_SEQUENCE_CNT:
+                    transportLayerInst.h2s_sequenceCnt = data[headerCounter];
+                    break;
+                
+                case STATE_GET_S2H_SEQUENCE_CNT:
+                    transportLayerInst.s2h_sequenceCnt = data[headerCounter];
+                    break;
 
-            case STATE_GET_DESTINATION:
-                destination = data[headerCounter];
-                break;
-            
-            case STATE_GET_H2S_SEQUENCE_CNT:
-                transportLayerInst.h2s_sequenceCnt = data[headerCounter];
-                break;
-            
-            case STATE_GET_S2H_SEQUENCE_CNT:
-                transportLayerInst.s2h_sequenceCnt = data[headerCounter];
-                break;
+                case STATE_GET_PAYLOAD:
+                    if (0u == payloadLength)
+                    {
+                        transportLayerInst.continueStep = true;
+                    }
+                    payloadBuffer[payloadCounter++] = data[headerCounter];
+                    break;
 
-            case STATE_GET_CRC:
-                crc32 |= data[headerCounter] << (SHELLMATTA_LENGTH_CRC - crcCounter++);
-                break;
-            
-            default:
-                break;
+                case STATE_GET_CRC:
+                    transportLayerInst.continueStep = false;
+                    crc32 |= data[headerCounter] << (SHELLMATTA_LENGTH_CRC - crcCounter++) * 8u;
+                    break;
+                
+                default:
+                    break;
+                }
+                /* handling of transport layer fsm */
+                ret = shellmatta_handle_transport_fsm(&transportLayerInst, data);
+                
+                if (SHELLMATTA_ERROR == ret)
+                {
+                    // TODO: Better error handling
+                    /* error in this case means crc error */
+                    shellmatta_printf(handle, "crc error\r\n");
+                    transportLayerInst.state = STATE_GET_SOH;
+                }
+
+                headerCounter++;
+
+                if (transportLayerInst.state == STATE_PROCESS_PAYLOAD)
+                {
+                    shellmatta_processData(handle, payloadBuffer, payloadLength);
+                    shellmatta_handle_transport_fsm(&transportLayerInst, data);
+                    return SHELLMATTA_OK;
+                }
             }
-            /* handling of transport layer fsm */
-            shellmatta_handle_transport_fsm(&transportLayerInst, data);
-            headerCounter++;
         }
 
-        /* if all data is processed but transport layer fsm is still not in payload, return */
-        if (transportLayerInst.state != STATE_GET_PAYLOAD)
+        if (    (transportLayerInst.active)
+            &&  (transportLayerInst.state != STATE_PROCESS_PAYLOAD)
+            &&  (transportLayerInst.state != STATE_MANUAL_INPUT))
         {
             return SHELLMATTA_OK;
         }
-        else
-        {
-            payloadCounter += size;
-        }
 
         /** -# in busy mode - keep calling this command */
         if(NULL != inst->busyCmd)
@@ -780,6 +802,13 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
     {
         ret = SHELLMATTA_USE_FAULT;
     }
+
+    /* if manual input happened, reset transport layer fsm back to initial state */
+    if (transportLayerInst.state == STATE_MANUAL_INPUT)
+    {
+        transportLayerInst.state = STATE_GET_SOH;
+    }
+
     return ret;
 }
 

+ 61 - 13
src/shellmatta_transport.c

@@ -5,6 +5,26 @@
  */
 
 #include "shellmatta_transport.h"
+#include <string.h>
+
+/* init global variables */
+uint8_t protocolVersion                  = 0u;
+shellmatta_transport_packet_t packetType = 0u;
+uint8_t payloadLength                    = 0u;
+uint8_t source                           = 0u;
+uint8_t destination                      = 0u;
+uint32_t crc32                           = 0u;
+uint8_t payloadCounter                   = 0u;
+uint8_t crcCounter                       = 0u;
+shellmatta_transport_layer_t transportLayerInst = {
+    0,
+    0,
+    STATE_GET_SOH,
+    false,
+    false,
+    false
+};
+char payloadBuffer[SHELLMATTA_PAYLOAD_MAXLENGTH + 1];
 
 shellmatta_retCode_t shellmatta_init_transport_inst()
 {
@@ -13,6 +33,8 @@ shellmatta_retCode_t shellmatta_init_transport_inst()
     transportLayerInst.state = STATE_GET_SOH;
     transportLayerInst.mandatory = false;
     transportLayerInst.active = false;
+    transportLayerInst.continueStep = false;
+    memset(payloadBuffer, 0, SHELLMATTA_PAYLOAD_MAXLENGTH + 1);
 
     return SHELLMATTA_OK;
 }
@@ -29,53 +51,79 @@ shellmatta_retCode_t shellmatta_handle_transport_fsm(shellmatta_transport_layer_
         }
         else
         {
+            transportLayer->state = STATE_MANUAL_INPUT;
             transportLayer->active = false;
-            transportLayer->state = STATE_GET_PAYLOAD;
         }
         break;
+
+    case STATE_MANUAL_INPUT:
+        break;
+
     case STATE_GET_PROTOCOL_VERSION:
         transportLayer->state = STATE_GET_PACKET_TYPE;
         break;
+
     case STATE_GET_PACKET_TYPE:
         transportLayer->state = STATE_GET_PAYLOAD_LENGTH;
         break;
+
     case STATE_GET_PAYLOAD_LENGTH:
         transportLayer->state = STATE_GET_SOURCE;
         break;
+
     case STATE_GET_SOURCE:
         transportLayer->state = STATE_GET_DESTINATION;
         break;
+
     case STATE_GET_DESTINATION:
         transportLayer->state = STATE_GET_H2S_SEQUENCE_CNT;
         break;
+
     case STATE_GET_H2S_SEQUENCE_CNT:
         transportLayer->state = STATE_GET_S2H_SEQUENCE_CNT;
         break;
+
     case STATE_GET_S2H_SEQUENCE_CNT:
         transportLayer->state = STATE_GET_PAYLOAD;
         break;
+
     case STATE_GET_PAYLOAD:
-        if (    (payloadLength == payloadCounter)
+        if (    (payloadLength <= payloadCounter)
             &&  (true == transportLayer->active))
         {
             transportLayer->state = STATE_GET_CRC;
         }
         break;
+
     case STATE_GET_CRC:
-        if (SHELLMATTA_LENGTH_CRC == crcCounter)
+        if (SHELLMATTA_LENGTH_CRC <= crcCounter)
         {
-            transportLayer->state = STATE_GET_SOH;
-            protocolVersion = 0u;
-            packetType      = 0u;
-            payloadLength   = 0u;
-            source          = 0u;
-            destination     = 0u;
-            crc32           = 0u;
-            payloadCounter  = 0u;
-            crcCounter      = 0u;
-            transportLayer->active = false;
+            /* debug check for crc 0x01 0x01 0x01 0x01 */
+            if (crc32 == 16843009u)
+            {
+                transportLayer->state = STATE_PROCESS_PAYLOAD;
+                break;
+            }
+            else
+            {
+                return SHELLMATTA_ERROR;
+            }
         }
         break;
+
+    case STATE_PROCESS_PAYLOAD:
+        transportLayer->state = STATE_GET_SOH;
+        protocolVersion = 0u;
+        packetType      = 0u;
+        payloadLength   = 0u;
+        source          = 0u;
+        destination     = 0u;
+        crc32           = 0u;
+        payloadCounter  = 0u;
+        crcCounter      = 0u;
+        transportLayer->active = false;
+        memset(payloadBuffer, 0, SHELLMATTA_PAYLOAD_MAXLENGTH + 1);
+        break;
     
     default:
         break;

+ 13 - 9
src/shellmatta_transport.h

@@ -51,6 +51,7 @@
 typedef enum
 {
     STATE_GET_SOH                =0u,   /**< start of header state of transport layer */
+    STATE_MANUAL_INPUT              ,
     STATE_GET_PROTOCOL_VERSION      ,   /**< protocol version state of transport layer */
     STATE_GET_PACKET_TYPE           ,   /**< packet type state of transport layer */
     STATE_GET_PAYLOAD_LENGTH        ,   /**< payload length state of transport layer */
@@ -60,6 +61,7 @@ typedef enum
     STATE_GET_S2H_SEQUENCE_CNT      ,   /**< shellmatta to host sequence counter state of transport layer */
     STATE_GET_PAYLOAD               ,   /**< payload state of transport layer */
     STATE_GET_CRC                   ,   /**< crc state of transport layer */
+    STATE_PROCESS_PAYLOAD
 } shellmatta_transport_state_t;
 
 /**
@@ -85,18 +87,20 @@ typedef struct
     shellmatta_transport_state_t state;     /**<  */
     bool mandatory;                         /**<  */
     bool active;                            /**<  */
+    bool continueStep;                      /**<  */
 } shellmatta_transport_layer_t;
 
-static uint8_t protocolVersion                  = 0u;
-static shellmatta_transport_packet_t packetType = 0u;
-static uint8_t payloadLength                    = 0u;
-static uint8_t source                           = 0u;
-static uint8_t destination                      = 0u;
-static uint32_t crc32                           = 0u;
-static uint8_t payloadCounter                   = 0u;
-static uint8_t crcCounter                       = 0u;
+extern uint8_t protocolVersion;
+extern shellmatta_transport_packet_t packetType;
+extern uint8_t payloadLength;
+extern uint8_t source;
+extern uint8_t destination;
+extern uint32_t crc32;
+extern uint8_t payloadCounter;
+extern uint8_t crcCounter;
+extern char payloadBuffer[SHELLMATTA_PAYLOAD_MAXLENGTH + 1];
 
-shellmatta_transport_layer_t transportLayerInst;
+extern shellmatta_transport_layer_t transportLayerInst;
 
 shellmatta_retCode_t shellmatta_init_transport_inst();