Prechádzať zdrojové kódy

added shellmatta transport configure interface

stefan 3 rokov pred
rodič
commit
59d7eeb689

+ 27 - 13
api/shellmatta.h

@@ -129,6 +129,13 @@ typedef enum
 /** @brief max length of a plain data payload */
 #define SHELLMATTA_TRANPORT_PAYLOAD_MAXLENGTH           ((uint8_t)(255))
 
+/**
+ * @brief shellmatta transport crc function definition for custom crcs
+ * @param[in]   data        data to calculate the crc of
+ * @param[in]   size        size of the data in bytes
+ */
+typedef uint32_t (*shellmatta_transport_crc_t)(const char* data, const uint32_t size);
+
 /**
  * @brief structure of one shellmatta transport header
  */
@@ -159,17 +166,19 @@ typedef struct __attribute__((__packed__))
  */
 typedef struct
 {
-    shellmatta_transport_state_t    state;          /**< current state of the transport layer reception */
-    bool                            active;         /**< is transport layer communication active        */
-    bool                            mandatory;      /**< is the transport layer enforced                */
-    uint8_t                         sequenceH2S;    /**< sequence counter host to shellmatta            */
-    uint8_t                         sequenceS2H;    /**< sequenc counter shellmatta to host             */
-    uint32_t                        headerIndex;    /**< read indey of the header                       */
-    uint32_t                        payloadIndex;   /**< read index of the payload                      */
-    uint32_t                        crcIndex;       /**< read index of the checmsum                     */
-    shellmatta_transport_packet_t   inPacket;       /**< buffer for the received packets                */
-    shellmatta_transport_packet_t   outPacket;      /**< buffer for the sent packets                    */
-    shellmatta_write_t              writeFct;       /**< shellmatta write function                      */
+    shellmatta_transport_state_t    state;              /**< current state of the transport layer reception */
+    bool                            active;             /**< is transport layer communication active        */
+    bool                            disableAutoFlush;   /**< enforce manual flushing                        */
+    bool                            mandatory;          /**< is the transport layer enforced                */
+    uint8_t                         sequenceH2S;        /**< sequence counter host to shellmatta            */
+    uint8_t                         sequenceS2H;        /**< sequenc counter shellmatta to host             */
+    uint32_t                        headerIndex;        /**< read indey of the header                       */
+    uint32_t                        payloadIndex;       /**< read index of the payload                      */
+    uint32_t                        crcIndex;           /**< read index of the checmsum                     */
+    shellmatta_transport_packet_t   inPacket;           /**< buffer for the received packets                */
+    shellmatta_transport_packet_t   outPacket;          /**< buffer for the sent packets                    */
+    shellmatta_write_t              writeFct;           /**< shellmatta write function                      */
+    shellmatta_transport_crc_t      customCrcFct;       /**< use this function to calculate crcs            */
 } shellmatta_transport_layer_t;
 
 /**
@@ -271,9 +280,14 @@ shellmatta_retCode_t shellmatta_opt_long(   shellmatta_handle_t         handle,
                                             char                        **argument,
                                             uint32_t                    *argLen);
 
-shellmatta_retCode_t shellmatta_transport_reset(shellmatta_transport_layer_t *transportLayer);
+shellmatta_retCode_t shellmatta_transport_configure(shellmatta_handle_t         handle,
+                                                    bool                        mandatory,
+                                                    bool                        disableAutoFlush,
+                                                    shellmatta_transport_crc_t  customCrcFct);
+
+shellmatta_retCode_t shellmatta_transport_reset(shellmatta_handle_t     handle);
 
-shellmatta_retCode_t shellmatta_transport_flush(shellmatta_transport_layer_t *transportLayer);
+shellmatta_retCode_t shellmatta_transport_flush(shellmatta_handle_t     handle);
 
 #ifndef SHELLMATTA_STRIP_PRINTF
 shellmatta_retCode_t shellmatta_printf(     shellmatta_handle_t handle,

+ 4 - 1
src/shellmatta.c

@@ -767,7 +767,10 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
             ret = shellmatta_processDataInt(handle, tmpData, 0);
         }
 
-        (void)shellmatta_transport_flush(&inst->transportLayer);
+        if (false == inst->transportLayer.disableAutoFlush)
+        {
+            (void)shellmatta_transport_flush(handle);
+        }
     }
     else
     {

+ 5 - 5
src/shellmatta_crc.c

@@ -76,9 +76,9 @@ static uint32_t reverse(uint32_t x, uint32_t bits)
  * @param[in]   size            amount of bytes to be processed
  * @return      crc             calculated crc32 value
  */
-static uint32_t crc32Slow(const char* data, uint16_t size)
+static uint32_t crc32Slow(const char* data, uint32_t size)
 {
-    uint16_t i;
+    uint32_t i;
     uint8_t j;
     uint32_t polynom = reverse(CRC32_POLYNOM, 32u);
     uint8_t pivotByte;
@@ -117,9 +117,9 @@ static uint32_t crc32Slow(const char* data, uint16_t size)
  * @param[in]   lookupTable     pointer to uint32_t lookup table for crc computation
  * @return      crc             calculated crc32 value
  */
-static uint32_t crc32Fast(const char* data, uint16_t size, const uint32_t* lookupTable)
+static uint32_t crc32Fast(const char* data, uint32_t size, const uint32_t* lookupTable)
 {
-    uint16_t i;
+    uint32_t i;
     uint32_t crcTemp = 0xffffffffu;
 
     for (i = 0u; i < size; i++)
@@ -139,7 +139,7 @@ static uint32_t crc32Fast(const char* data, uint16_t size, const uint32_t* looku
  * @param[in]   size            amount of bytes to be processed
  * @return      crc             calculated crc32 value
  */
-uint32_t crc32Calc(const char* data, uint16_t size)
+uint32_t crc32Calc(const char* data, uint32_t size)
 {
     #ifdef  SHELLMATTA_TRANSPORT_CRC_NO_LOOKUP
         return crc32Slow(data, size);

+ 1 - 1
src/shellmatta_crc.h

@@ -20,6 +20,6 @@
 #define CRC32_POLYNOM   0x04c11db7u     /**< crc-32 ethernet 802.3                          */
 #define BITS_PER_BYTE   ((uint8_t)8)    /**< amount of bits per byte; to avoid magic number */
 
-uint32_t crc32Calc(const char* data, uint16_t size);
+uint32_t crc32Calc(const char* data, uint32_t size);
 
 #endif /* _SHELLMATTA_CRC_H_ */

+ 87 - 19
src/shellmatta_transport.c

@@ -7,6 +7,7 @@
 #include "shellmatta_transport.h"
 #include "shellmatta.h"
 #include "shellmatta_crc.h"
+#include "shellmatta_utils.h"
 #include <string.h>
 
 
@@ -64,21 +65,74 @@ shellmatta_retCode_t shellmatta_transport_init( shellmatta_transport_layer_t
     return SHELLMATTA_OK;
 }
 
+/**
+ * @brief           Configures the transport layer
+ * @param[in, out]  handle              shellmatta handle of the instance
+ * @param[in]       mandatory           enforce using the transport layer
+ * @param[in]       disableAutoFlush    enforce manual flushing of the output packet
+ * @param[in]       customCrcFct        use a custom crc generation (default NULL)
+ * @return          errorcode
+ */
+shellmatta_retCode_t shellmatta_transport_configure(shellmatta_handle_t         handle,
+                                                    bool                        mandatory,
+                                                    bool                        disableAutoFlush,
+                                                    shellmatta_transport_crc_t  customCrcFct)
+{
+    shellmatta_retCode_t    ret     = SHELLMATTA_OK;
+    shellmatta_instance_t   *inst   = (shellmatta_instance_t*)handle;
+
+    /** -# check parameters for plausibility  */
+    if(     (NULL               != inst)
+        &&  (SHELLMATTA_MAGIC   == inst->magic))
+    {
+        shellmatta_transport_layer_t *transportLayer = &inst->transportLayer;
+
+        transportLayer->mandatory           = mandatory;
+        transportLayer->disableAutoFlush    = disableAutoFlush;
+        transportLayer->customCrcFct        = customCrcFct;
+
+        /** -# set the transport layer active when configured as mandatory */
+        if(true == mandatory)
+        {
+            transportLayer->active = true;
+        }
+    }
+    else
+    {
+        ret = SHELLMATTA_USE_FAULT;
+    }
+
+    return ret;
+}
+
 /**
  * @brief           Resets all values of tranportLayerInst except for sequence counters
- * @param[in, out]  transportLayer  transport layer instance to work on
- * @return          errorcode       #SHELLMATTA_OK
+ * @param[in, out]  handle      shellmatta handle of the instance
+ * @return          errorcode
  */
-shellmatta_retCode_t shellmatta_transport_reset(shellmatta_transport_layer_t *transportLayer)
+shellmatta_retCode_t shellmatta_transport_reset(shellmatta_handle_t handle)
 {
-    uint8_t sequenceH2S = transportLayer->sequenceH2S;
-    uint8_t sequenceS2H = transportLayer->sequenceS2H;
-    memset(transportLayer, 0u, sizeof(shellmatta_transport_layer_t));
+    shellmatta_retCode_t    ret     = SHELLMATTA_OK;
+    shellmatta_instance_t   *inst   = (shellmatta_instance_t*)handle;
 
-    transportLayer->sequenceH2S = sequenceH2S;
-    transportLayer->sequenceS2H = sequenceS2H;
+    /** -# check parameters for plausibility  */
+    if(     (NULL               != inst)
+        &&  (SHELLMATTA_MAGIC   == inst->magic))
+    {
+        shellmatta_transport_layer_t *transportLayer = &inst->transportLayer;
+        uint8_t sequenceH2S = transportLayer->sequenceH2S;
+        uint8_t sequenceS2H = transportLayer->sequenceS2H;
+        memset(transportLayer, 0u, sizeof(shellmatta_transport_layer_t));
 
-    return SHELLMATTA_OK;
+        transportLayer->sequenceH2S = sequenceH2S;
+        transportLayer->sequenceS2H = sequenceS2H;
+    }
+    else
+    {
+        ret = SHELLMATTA_USE_FAULT;
+    }
+
+    return ret;
 }
 
 /**
@@ -175,7 +229,9 @@ shellmatta_retCode_t shellmatta_transport_process(shellmatta_transport_layer_t
 
         if (transportLayer->crcIndex >= SHELLMATTA_TRANSPORT_LENGTH_CRC)
         {
-            refCrc = crc32Calc(rawPacket, SHELLMATTA_TRANSPORT_LENGTH_HEADER + header->payloadLength);
+            refCrc = SHELLMATTA_TRANSPORT_CALC_CRC(transportLayer,
+                                                   rawPacket,
+                                                   SHELLMATTA_TRANSPORT_LENGTH_HEADER + header->payloadLength);
 
             /* if crc is correct, further handling of data depends on type of packet */
             if (transportLayer->inPacket.crc == refCrc)
@@ -311,19 +367,31 @@ shellmatta_retCode_t shellmatta_transport_write(shellmatta_transport_layer_t *tr
 /**
  * @brief           Send out piled up payload
  * 
- * @param[in, out]  transportLayer  transport layer instance to work on
- * @return          errorcode       #SHELLMATTA_OK
+ * @param[in, out]  handle      shellmatta handle of the instance
+ * @return          errorcode
  */
-shellmatta_retCode_t shellmatta_transport_flush(shellmatta_transport_layer_t *transportLayer)
+shellmatta_retCode_t shellmatta_transport_flush(shellmatta_handle_t handle)
 {
-    shellmatta_retCode_t ret = SHELLMATTA_OK;
-    shellmatta_transport_packet_t *packet = &transportLayer->outPacket;
+    shellmatta_retCode_t    ret = SHELLMATTA_OK;
+    shellmatta_instance_t   *inst = (shellmatta_instance_t*)handle;
+
+    /** -# check parameters for plausibility  */
+    if(     (NULL               != inst)
+        &&  (SHELLMATTA_MAGIC   == inst->magic))
+    {
+
+        shellmatta_transport_packet_t *packet = &inst->transportLayer.outPacket;
 
-    if(0 != packet->header.payloadLength)
+        if(0 != packet->header.payloadLength)
+        {
+            packet->header.packetType = SHELLMATTA_TRANSPORT_PACKET_DATA;
+            ret = shellmatta_transport_send(&inst->transportLayer, packet);
+            packet->header.payloadLength = 0u;
+        }
+    }
+    else
     {
-        packet->header.packetType = SHELLMATTA_TRANSPORT_PACKET_DATA;
-        ret = shellmatta_transport_send(transportLayer, &transportLayer->outPacket);
-        packet->header.payloadLength = 0u;
+        ret = SHELLMATTA_USE_FAULT;
     }
 
     return ret;

+ 5 - 0
src/shellmatta_transport.h

@@ -30,6 +30,11 @@ typedef struct __attribute__((__packed__))
 /** @brief length of crc32 */
 #define SHELLMATTA_TRANSPORT_LENGTH_STATIC  (SHELLMATTA_TRANSPORT_LENGTH_HEADER + SHELLMATTA_TRANSPORT_LENGTH_CRC)
 
+/** @brief helper macro for CRC calculation */
+#define SHELLMATTA_TRANSPORT_CALC_CRC(transporLayer, data, size)    NULL != (transportLayer)->customCrcFct ?         \
+                                                                    (transportLayer)->customCrcFct((data), (size)) : \
+                                                                    crc32Calc((data), (size));
+
 /**
  * @brief definitions of shellmatta transport layer packet types
  */

+ 32 - 0
test/integrationtest/test_integration_transport.cpp

@@ -262,6 +262,38 @@ SCENARIO("Integration test of Transport layer", "[integration, transport]")
             }
         }
 
+        WHEN("disabling auto flush")
+        {
+            /* check with valid payload - disable echo to reduce cluttering */
+            shellmatta_configure(handle, SHELLMATTA_MODE_INSERT, false, '\r');
+            shellmatta_transport_configure(handle, false, true, NULL);
+            shellmatta_processData(handle, (char*)"\x01\x01\x00\x16\x00\x00\x00\x00"
+                                                "doSomething argument\r\n"
+                                                "\x7b\x49\xfa\x72", 34u);
+
+            THEN("The Shellmatta does not respond")
+            {
+                CHECK( write_length == 0u);
+
+                AND_WHEN("The flush method is called")
+                {
+                    shellmatta_transport_flush(handle);
+                    THEN("The shellmatta returns the data")
+                    {
+
+                        char *dummyData =   (char*)"\x01\x01\x00\x2f\x00\x00\x01\x01"
+                                                "doSomething argument - length: 20"
+                                                "\r\n"
+                                                "shellmatta->"
+                                                "\xc8\xae\xc0\x56";
+
+                        CHECK( write_length == 59u);
+                        REQUIRE( memcmp(write_data, dummyData, 59) == 0);
+                    }
+                }
+            }
+        }
+
         WHEN("Sequence counter is requested")
         {
             /* request sequence counter */