Przeglądaj źródła

fix sending large amounts of data via transport layer

stefan 3 lat temu
rodzic
commit
d5b2e3a422

+ 6 - 8
src/shellmatta_transport.c

@@ -274,7 +274,6 @@ shellmatta_retCode_t shellmatta_transport_write(shellmatta_transport_layer_t *tr
     uint32_t processedLength    = 0u;
     uint32_t piledUpPayload;
     uint32_t splitLength;
-    uint32_t splitPayloadLength;
     uint32_t restOfPayload;
 
     /* foot-controlled loop to send packets without payload length */
@@ -284,19 +283,18 @@ shellmatta_retCode_t shellmatta_transport_write(shellmatta_transport_layer_t *tr
 
         /* compute length of next payload split */
         restOfPayload = (outPayloadLength - processedLength);
-        if (restOfPayload > SHELLMATTA_TRANPORT_PAYLOAD_MAXLENGTH)
+        if (restOfPayload > (SHELLMATTA_TRANPORT_PAYLOAD_MAXLENGTH - piledUpPayload))
         {
-            splitLength = SHELLMATTA_TRANPORT_PAYLOAD_MAXLENGTH;
+            splitLength = SHELLMATTA_TRANPORT_PAYLOAD_MAXLENGTH - piledUpPayload;
         }
         else
         {
-            splitLength = (restOfPayload + SHELLMATTA_TRANSPORT_LENGTH_STATIC) % SHELLMATTA_TRANPORT_PAYLOAD_MAXLENGTH;
+            splitLength = restOfPayload;
         }
-        splitPayloadLength = splitLength - SHELLMATTA_TRANSPORT_LENGTH_STATIC;
 
-        (void)memcpy(&packet->payload[piledUpPayload], &data[processedLength], splitPayloadLength);
-        header->payloadLength += splitPayloadLength;
-        processedLength += splitPayloadLength;
+        (void)memcpy(&packet->payload[piledUpPayload], &data[processedLength], splitLength);
+        header->payloadLength += splitLength;
+        processedLength += splitLength;
 
         if(header->payloadLength >= SHELLMATTA_TRANPORT_PAYLOAD_MAXLENGTH)
         {

+ 119 - 1
test/integrationtest/test_integration_transport.cpp

@@ -60,6 +60,58 @@ shellmatta_cmd_t doSomethingCmd =
     NULL
 };
 
+static shellmatta_retCode_t largePayload(shellmatta_handle_t handle, const char *arguments, uint32_t length)
+{
+    uint32_t i;
+
+    for (i = 0u; i < 8; i ++)
+    {
+        shellmatta_printf(handle, "This is my very very very very large payload\r\n");
+    }
+
+    (void)arguments;
+    (void)length;
+
+    return SHELLMATTA_OK;
+}
+shellmatta_cmd_t largePayloadCmd =
+{
+    (char*)"largePayload",
+    (char*)"lp",
+    (char*)"Function returns large payload",
+    (char*)"i have much to say",
+    largePayload,
+    NULL
+};
+
+static shellmatta_retCode_t largePayloadAtOnce(shellmatta_handle_t handle, const char *arguments, uint32_t length)
+{
+    shellmatta_write(handle,
+                    (char*)"This is my very very very very large payload\r\n"
+                    "This is my very very very very large payload\r\n"
+                    "This is my very very very very large payload\r\n"
+                    "This is my very very very very large payload\r\n"
+                    "This is my very very very very large payload\r\n"
+                    "This is my very very very very large payload\r\n"
+                    "This is my very very very very large payload\r\n"
+                    "This is my very very very very large payload\r\n",
+                    46u*8u);
+
+    (void)arguments;
+    (void)length;
+
+    return SHELLMATTA_OK;
+}
+shellmatta_cmd_t largePayloadAtOnceCmd =
+{
+    (char*)"largePayload",
+    (char*)"lp",
+    (char*)"Function returns large payload",
+    (char*)"i have much to say",
+    largePayloadAtOnce,
+    NULL
+};
+
 SCENARIO("Integration test of Transport layer", "[integration, transport]")
 {
     GIVEN("Shellmatta up and running with one command")
@@ -115,11 +167,77 @@ SCENARIO("Integration test of Transport layer", "[integration, transport]")
                                            "shellmatta->"
                                            "\xc8\xae\xc0\x56";
 
-                CHECK( write_length == 59);
+                CHECK( write_length == 59u);
                 REQUIRE( memcmp(write_data, dummyData, 59) == 0);
             }
         }
 
+        WHEN("Large payload is written by shellmatta in steps")
+        {
+            /* add large payload command */
+            shellmatta_addCmd(handle, &largePayloadCmd);
+
+            /* check with valid payload - disable echo to reduce cluttering */
+            shellmatta_configure(handle, SHELLMATTA_MODE_INSERT, false, '\r');
+            shellmatta_processData(handle, (char*)"\x01\x01\x00\x0e\x00\x00\x00\x00"
+                                                "largePayload\r\n"
+                                                "\xad\x33\x31\xcc", 26u);
+            THEN("The shellmatta responds multiple telegrams")
+            {
+                char *dummyData =   (char*)"\x01\x01\x00\xff\x00\x00\x01\x01"
+                                           "This is my very very very very large payload\r\n"
+                                           "This is my very very very very large payload\r\n"
+                                           "This is my very very very very large payload\r\n"
+                                           "This is my very very very very large payload\r\n"
+                                           "This is my very very very very large payload\r\n"
+                                           "This is my very very very"
+                                           "\x0f\x90\xc0\xfd"
+                                           "\x01\x01\x00\x7f\x00\x00\x01\x02"
+                                           " very large payload\r\n"
+                                           "This is my very very very very large payload\r\n"
+                                           "This is my very very very very large payload\r\n"
+                                           "\r\n"
+                                           "shellmatta->"
+                                           "\x00\xc9\x5d\x37";
+
+                CHECK( write_length == 406u);
+                REQUIRE( memcmp(write_data, dummyData, 406u) == 0);
+            }
+        }
+
+        WHEN("Large payload is written by shellmatta at once")
+        {
+            /* add large payload command */
+            shellmatta_addCmd(handle, &largePayloadAtOnceCmd);
+
+            /* check with valid payload - disable echo to reduce cluttering */
+            shellmatta_configure(handle, SHELLMATTA_MODE_INSERT, false, '\r');
+            shellmatta_processData(handle, (char*)"\x01\x01\x00\x0e\x00\x00\x00\x00"
+                                                "largePayload\r\n"
+                                                "\xad\x33\x31\xcc", 26u);
+            THEN("The shellmatta responds multiple telegrams")
+            {
+                char *dummyData =   (char*)"\x01\x01\x00\xff\x00\x00\x01\x01"
+                                           "This is my very very very very large payload\r\n"
+                                           "This is my very very very very large payload\r\n"
+                                           "This is my very very very very large payload\r\n"
+                                           "This is my very very very very large payload\r\n"
+                                           "This is my very very very very large payload\r\n"
+                                           "This is my very very very"
+                                           "\x0f\x90\xc0\xfd"
+                                           "\x01\x01\x00\x7f\x00\x00\x01\x02"
+                                           " very large payload\r\n"
+                                           "This is my very very very very large payload\r\n"
+                                           "This is my very very very very large payload\r\n"
+                                           "\r\n"
+                                           "shellmatta->"
+                                           "\x00\xc9\x5d\x37";
+
+                CHECK( write_length == 406u);
+                REQUIRE( memcmp(write_data, dummyData, 406u) == 0);
+            }
+        }
+
         WHEN("manual mode is used after transport layer mode")
         {
             /* check with valid payload - disable echo to reduce cluttering */