Forráskód Böngészése

added search implementation to transport layer

stefan 9 hónapja
szülő
commit
39ee823520

+ 5 - 0
api/shellmatta.h

@@ -209,6 +209,9 @@ typedef enum
 /** @brief max length of a plain data payload */
 #define SHELLMATTA_TRANPORT_PAYLOAD_MAXLENGTH           ((uint8_t)(255))
 
+/** @brief size of the shellmatta transport uuid */
+#define SHELLMATTA_TRANPORT_UUID_LENGTH                 ((uint8_t)(16))
+
 /**
  * @brief shellmatta transport crc function definition for custom crcs
  * @param[in]   data        data to calculate the crc of
@@ -256,6 +259,7 @@ typedef struct
     uint32_t                        payloadIndex;       /**< read index of the payload                      */
     uint32_t                        crcIndex;           /**< read index of the checksum                     */
     uint8_t                         hostBufferSize;     /**< buffersize of the host                         */
+    uint8_t                         uuid[SHELLMATTA_TRANPORT_UUID_LENGTH]; /**< uuid if the shellmatta      */
     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                      */
@@ -388,6 +392,7 @@ shellmatta_retCode_t shellmatta_opt_long(   shellmatta_handle_t         handle,
 shellmatta_retCode_t shellmatta_transport_configure(shellmatta_handle_t         handle,
                                                     bool                        mandatory,
                                                     bool                        disableAutoFlush,
+                                                    uint8_t                     uuid[SHELLMATTA_TRANPORT_UUID_LENGTH],
                                                     shellmatta_transport_crc_t  customCrcFct);
 
 shellmatta_retCode_t shellmatta_transport_reset(shellmatta_handle_t handle);

+ 26 - 1
doc/shellmatta_transport_layer.dox

@@ -98,7 +98,32 @@
 
     @section shellmatta_transport_layer_addressing Addressing and Search
 
-    @todo Not implemented yet
+    The shellmatta comes with a primitive multidrop implementation to address
+    and find multiple shellmatta transport layer enabled devices on a bus.
+
+    Every command comes with a source and destination address.
+    0 is the broadcast address an received everytime.
+
+    The packet response is sent to the source from the request packet.
+
+    To assign a new address to a shellmatta transport layer enabled device
+    there is a possibility to search for devices on the bus.
+
+    Every shellmatta which enables this feature requires a 16 byte UUID to be
+    specified which is unique on the bus.
+    The Host can then search for shellmatta nodes using a range of UUIDs
+    using command 0x03.
+
+    Every shellmatta instance within this range will respond.
+    If more than one shellmatta is in the specified range this will lead to
+    collisions on the bus. When the host detects collisions it shall repeat
+    the search requests with different ranges until only one shellmatta
+    responds.
+
+    Once the host has found a single shellmatta in one range it can assign a
+    unique address using command 0x04.
+
+    The shellmatta can now be accessed using this address.
 
 
     @section shellmatta_transport_layer_crc CRC calculation

+ 56 - 2
src/shellmatta_transport.c

@@ -25,7 +25,6 @@
  * @note    The packetType, payloadLength and payload have to be preset!
  *
  * @param[in, out]  transportLayer  transport layer instance to work on
- * @param[in]       packetType      type of packet to send
  * @param[in]       packet          packet to send
  * @return          errorcode
  */
@@ -58,6 +57,47 @@ static shellmatta_retCode_t shellmatta_transport_send(shellmatta_transport_layer
                                     header->payloadLength);
 }
 
+/**
+ * @brief   check a search packet and return if our UUID is in the search range
+ * @param[in, out]  transportLayer  transport layer instance to work on
+ * @param[in]       packet          search packet
+ * @return          true - UUID in passed range
+ */
+static bool shellmatta_transport_search(shellmatta_transport_layer_t *transportLayer,
+                                                        shellmatta_transport_packet_t *packet)
+{
+    bool match = true;
+    uint32_t i;
+    uint8_t *uuid1;
+    uint8_t *uuid2;
+
+    /** -# check packet length */
+    if(SHELLMATTA_TRANPORT_UUID_LENGTH != packet->header.payloadLength)
+    {
+        return false;
+    }
+
+    uuid1 = (uint8_t *)&packet->payload[0u];
+    uuid2 = (uint8_t *)&packet->payload[SHELLMATTA_TRANPORT_UUID_LENGTH];
+
+    /** -# compare UUID with range */
+    for(i = 0u; i < (SHELLMATTA_TRANPORT_UUID_LENGTH - 1u); i ++)
+    {
+        if((transportLayer->uuid[i] < uuid1[i]) || (transportLayer->uuid[i] > uuid2[i]))
+        {
+            match = false;
+        }
+    }
+
+    /** -# explicitly check lowest digit - this is not inclusive to the lower limit */
+    if((transportLayer->uuid[i] <= uuid1[i]) || (transportLayer->uuid[i] > uuid2[i]))
+    {
+        match = false;
+    }
+
+    return match;
+}
+
 /**
  * @brief           Initializes the transportLayerInst
  * @param[in, out]  transportLayer  transport layer instance to work on
@@ -80,12 +120,14 @@ shellmatta_retCode_t shellmatta_transport_init( shellmatta_transport_layer_t
  * @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]       uuid                UUID for multidrop search (default NULL)
  * @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,
+                                                    uint8_t                     uuid[SHELLMATTA_TRANPORT_UUID_LENGTH],
                                                     shellmatta_transport_crc_t  customCrcFct)
 {
     shellmatta_retCode_t    ret     = SHELLMATTA_OK;
@@ -106,6 +148,11 @@ shellmatta_retCode_t shellmatta_transport_configure(shellmatta_handle_t
         {
             transportLayer->active = true;
         }
+
+        if(NULL != uuid)
+        {
+            (void)memcpy(transportLayer->uuid, uuid, SHELLMATTA_TRANPORT_UUID_LENGTH);
+        }
     }
     else
     {
@@ -290,7 +337,14 @@ shellmatta_retCode_t shellmatta_transport_process(shellmatta_transport_layer_t
                     break;
 
                 case SHELLMATTA_TRANSPORT_PACKET_SEARCH_DEVICE_REQUEST:
-                    /** @todo implement */
+                    /** -# check if our own uuid is inside the passed range */
+                    if(true == shellmatta_transport_search(transportLayer, &transportLayer->inPacket))
+                    {
+                        intPacket.header.packetType = SHELLMATTA_TRANSPORT_PACKET_SEARCH_DEVICE_RESPOND;
+                        intPacket.header.payloadLength = SHELLMATTA_TRANPORT_UUID_LENGTH;
+                        (void)memcpy(intPacket.payload, transportLayer->uuid, SHELLMATTA_TRANPORT_UUID_LENGTH);
+                        (void)shellmatta_transport_send(transportLayer, (shellmatta_transport_packet_t *)&intPacket);
+                    }
                     break;
 
                 case SHELLMATTA_TRANSPORT_PACKET_SEARCH_DEVICE_RESPOND:

+ 3 - 3
test/integrationtest_transport/test_integration_transport.cpp

@@ -265,7 +265,7 @@ SCENARIO("Integration test of Transport layer", "[integration, transport]")
         {
             /* 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_transport_configure(handle, false, true, NULL, NULL);
             shellmatta_processData(handle, (char*)"\x01\x01\x00\x16\x00\x00\x00\x00"
                                                 "doSomething argument\r\n"
                                                 "\x7b\x49\xfa\x72", 34u);
@@ -353,7 +353,7 @@ SCENARIO("Integration test of Transport layer with mandatory transport layer", "
         write_length = 0u;
 
         WHEN("The tansport layer is set to mandatory") {
-            ret = shellmatta_transport_configure(handle, true, false, NULL);
+            ret = shellmatta_transport_configure(handle, true, false, NULL, NULL);
             CHECK(ret == SHELLMATTA_OK);
 
             AND_WHEN("manual mode is used after transport layer mode")
@@ -407,7 +407,7 @@ SCENARIO("Integration test of Transport layer - reset transport layer", "[integr
         write_length = 0u;
 
         WHEN("The tansport layer is set to mandatory") {
-            ret = shellmatta_transport_configure(handle, true, false, NULL);
+            ret = shellmatta_transport_configure(handle, true, false, NULL, NULL);
             CHECK(ret == SHELLMATTA_OK);
 
             AND_WHEN("A partial telegram is passed")