|
@@ -0,0 +1,228 @@
|
|
|
+/*
|
|
|
+ * Copyright (c) 2021 - 2024 Stefan Strobel <stefan.strobel@shimatta.net>
|
|
|
+ *
|
|
|
+ * This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
|
+ */
|
|
|
+
|
|
|
+/**
|
|
|
+ * @file test_integration_ymodem.cpp
|
|
|
+ * @brief integration test implementation for the ymodem module of the shellmatta
|
|
|
+ * @author Stefan Strobel <stefan.strobel@shimatta.net>
|
|
|
+ */
|
|
|
+
|
|
|
+#include "test/framework/catch.hpp"
|
|
|
+extern "C" {
|
|
|
+ #include "shellmatta.h"
|
|
|
+}
|
|
|
+#include <string.h>
|
|
|
+
|
|
|
+static uint32_t write_callCnt = 0u;
|
|
|
+static char write_data[1024];
|
|
|
+static uint32_t write_length;
|
|
|
+static bool cancelled;
|
|
|
+static uint32_t receivedFileSize;
|
|
|
+static char *receivedFileName;
|
|
|
+static uint8_t *receivedPacketData;
|
|
|
+static uint32_t receivedPacketSize;
|
|
|
+static uint32_t receivedPacketNum;
|
|
|
+static bool transmissionCompleted;
|
|
|
+static shellmatta_retCode_t transmissionCompletedResult;
|
|
|
+
|
|
|
+static shellmatta_retCode_t writeFct(const char* data, uint32_t length)
|
|
|
+{
|
|
|
+ write_callCnt ++;
|
|
|
+ while((length > 0) && (write_length < sizeof(write_data)))
|
|
|
+ {
|
|
|
+ write_data[write_length] = *data;
|
|
|
+ data ++;
|
|
|
+ length --;
|
|
|
+ write_length ++;
|
|
|
+ }
|
|
|
+
|
|
|
+ return SHELLMATTA_OK;
|
|
|
+}
|
|
|
+
|
|
|
+static void ymodemCallbackCancel(shellmatta_handle_t handle)
|
|
|
+{
|
|
|
+ (void)handle;
|
|
|
+ cancelled = true;
|
|
|
+}
|
|
|
+
|
|
|
+static void ymodemCallbackReceiveHeader(shellmatta_handle_t handle,
|
|
|
+ uint32_t fileSize,
|
|
|
+ char* fileName) {
|
|
|
+
|
|
|
+ shellmatta_ymodem_pause(handle);
|
|
|
+
|
|
|
+ receivedFileSize = fileSize;
|
|
|
+ receivedFileName = fileName;
|
|
|
+}
|
|
|
+
|
|
|
+static void ymodemCallbackReceivePacket(shellmatta_handle_t handle,
|
|
|
+ uint8_t *data,
|
|
|
+ uint32_t packetSize,
|
|
|
+ uint32_t packetNum)
|
|
|
+{
|
|
|
+ (void)handle;
|
|
|
+ receivedPacketData = data;
|
|
|
+ receivedPacketSize = packetSize;
|
|
|
+ receivedPacketNum = packetNum;
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+static void ymodemCallbackTransmissionComplete(shellmatta_handle_t handle,
|
|
|
+ shellmatta_retCode_t result)
|
|
|
+{
|
|
|
+ (void)handle;
|
|
|
+ transmissionCompleted = true;
|
|
|
+ transmissionCompletedResult = result;
|
|
|
+}
|
|
|
+
|
|
|
+SCENARIO("Test successful transmissions in ymodem")
|
|
|
+{
|
|
|
+ GIVEN("An initialized and empty Shellmatta instance")
|
|
|
+ {
|
|
|
+ shellmatta_retCode_t ret;
|
|
|
+ shellmatta_instance_t inst;
|
|
|
+ shellmatta_handle_t handle;
|
|
|
+ char buffer[1024u];
|
|
|
+ char historyBuffer[1024u];
|
|
|
+ uint8_t ymodemBuffer[1024u];
|
|
|
+
|
|
|
+ cancelled = false;
|
|
|
+ receivedFileSize = 0u;
|
|
|
+ receivedFileName = NULL;
|
|
|
+ receivedPacketData = NULL;
|
|
|
+ receivedPacketSize = 0u;
|
|
|
+ receivedPacketNum = 0u;
|
|
|
+ transmissionCompleted = false;
|
|
|
+ transmissionCompletedResult = SHELLMATTA_USE_FAULT;
|
|
|
+
|
|
|
+ CHECK(SHELLMATTA_OK == shellmatta_doInit( &inst,
|
|
|
+ &handle,
|
|
|
+ buffer,
|
|
|
+ sizeof(buffer),
|
|
|
+ historyBuffer,
|
|
|
+ sizeof(historyBuffer),
|
|
|
+ "shellmatta->",
|
|
|
+ NULL,
|
|
|
+ writeFct));
|
|
|
+
|
|
|
+ WHEN("Starting a ymodem session and passing data.")
|
|
|
+ {
|
|
|
+ ret = shellmatta_ymodem_init(handle,
|
|
|
+ ymodemBuffer,
|
|
|
+ ymodemCallbackCancel,
|
|
|
+ ymodemCallbackReceiveHeader,
|
|
|
+ ymodemCallbackReceivePacket,
|
|
|
+ ymodemCallbackTransmissionComplete);
|
|
|
+
|
|
|
+ AND_WHEN("ymodem is polled")
|
|
|
+ {
|
|
|
+ write_length = 0u;
|
|
|
+ ret = shellmatta_processData(handle, (char *)"", 0);
|
|
|
+ CHECK(ret == SHELLMATTA_OK);
|
|
|
+
|
|
|
+ THEN("ymodem sends C starting character")
|
|
|
+ {
|
|
|
+ CHECK(write_length == 1u);
|
|
|
+ REQUIRE(write_data[0] == 'C');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ AND_WHEN("Packet 0 is sent")
|
|
|
+ {
|
|
|
+ char packet0[1029u] = "\x02\x00\xFF" "Filename\0" "1044 \0";
|
|
|
+ packet0[1027u] = '\x55';
|
|
|
+ packet0[1028u] = '\x2E';
|
|
|
+ char packet1[133u] = "\x01\x01\xFE" "Some data...\0";
|
|
|
+ packet1[131u] = '\x09';
|
|
|
+ packet1[132u] = '\x75';
|
|
|
+ char packet2[1029u] = "\x02\x02\xFD" "Some additional data\0";
|
|
|
+ packet2[1027u] = '\xCD';
|
|
|
+ packet2[1028u] = '\xD4';
|
|
|
+
|
|
|
+ write_length = 0u;
|
|
|
+ ret = shellmatta_processData(handle, packet0, sizeof(packet0));
|
|
|
+ CHECK(ret == SHELLMATTA_OK);
|
|
|
+
|
|
|
+ CHECK(write_length == 0u);
|
|
|
+
|
|
|
+ ret = shellmatta_ymodem_resume(handle);
|
|
|
+ CHECK(ret == SHELLMATTA_OK);
|
|
|
+
|
|
|
+ THEN("ymodem calls the received header callback and sends an ACK")
|
|
|
+ {
|
|
|
+ CHECK_THAT(receivedFileName, Catch::Matchers::Equals("Filename"));
|
|
|
+ CHECK(receivedFileSize == 1044);
|
|
|
+
|
|
|
+ CHECK(write_length == 2u);
|
|
|
+ CHECK(write_data[0] == '\x06');
|
|
|
+ REQUIRE(write_data[1] == 'C');
|
|
|
+
|
|
|
+ AND_WHEN("The rest of the packets is sent")
|
|
|
+ {
|
|
|
+ write_length = 0u;
|
|
|
+ ret = shellmatta_processData(handle, packet1, sizeof(packet1));
|
|
|
+ CHECK(ret == SHELLMATTA_OK);
|
|
|
+
|
|
|
+ CHECK_THAT((char *)receivedPacketData, Catch::Matchers::Equals("Some data..."));
|
|
|
+ CHECK(receivedPacketSize == 128);
|
|
|
+ CHECK(receivedPacketNum == 1);
|
|
|
+
|
|
|
+ receivedPacketData = NULL;
|
|
|
+ receivedPacketSize = 0u;
|
|
|
+ receivedPacketNum = 0u;
|
|
|
+
|
|
|
+ ret = shellmatta_processData(handle, packet2, sizeof(packet2));
|
|
|
+ CHECK(ret == SHELLMATTA_OK);
|
|
|
+
|
|
|
+ CHECK_THAT((char *)receivedPacketData, Catch::Matchers::Equals("Some additional data"));
|
|
|
+ CHECK(receivedPacketSize == 20);
|
|
|
+ CHECK(receivedPacketNum == 2);
|
|
|
+
|
|
|
+ ret = shellmatta_processData(handle, (char*)"\x04", 1);
|
|
|
+ CHECK(ret == SHELLMATTA_OK);
|
|
|
+
|
|
|
+ ret = shellmatta_processData(handle, (char*)"\x04", 1);
|
|
|
+ CHECK(ret == SHELLMATTA_OK);
|
|
|
+
|
|
|
+ ret = shellmatta_processData(handle, (char*)"\x04", 1);
|
|
|
+ CHECK(ret == SHELLMATTA_OK);
|
|
|
+
|
|
|
+ CHECK(write_length == 8u);
|
|
|
+ CHECK(write_data[0] == '\x06');
|
|
|
+ CHECK(write_data[1] == '\x06');
|
|
|
+ CHECK(write_data[2] == '\x06');
|
|
|
+ CHECK(write_data[3] == 'C');
|
|
|
+ CHECK(write_data[4] == '\x06');
|
|
|
+ CHECK(write_data[5] == 'C');
|
|
|
+ CHECK(write_data[6] == '\x06');
|
|
|
+ CHECK(write_data[7] == 'C');
|
|
|
+
|
|
|
+ write_length = 0u;
|
|
|
+ memset(write_data, 0, sizeof(write_data));
|
|
|
+
|
|
|
+ ret = shellmatta_processData(handle, (char*)"", 0);
|
|
|
+ CHECK(ret == SHELLMATTA_OK);
|
|
|
+ ret = shellmatta_processData(handle, (char*)"", 0);
|
|
|
+ CHECK(ret == SHELLMATTA_OK);
|
|
|
+ ret = shellmatta_processData(handle, (char*)"", 0);
|
|
|
+ CHECK(ret == SHELLMATTA_OK);
|
|
|
+
|
|
|
+ THEN("The transmission finishes successfully")
|
|
|
+ {
|
|
|
+ CHECK(write_length == 14);
|
|
|
+ CHECK_THAT(write_data, Catch::Matchers::Equals("\r\nshellmatta->"));
|
|
|
+
|
|
|
+ CHECK(transmissionCompleted == true);
|
|
|
+ REQUIRE(transmissionCompletedResult == SHELLMATTA_OK);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|