From c1ee107812e04ed5dbf1ed752d2b5bb4c5ca56ad Mon Sep 17 00:00:00 2001 From: Pascal Roobrouck Date: Mon, 14 Jul 2025 09:45:22 +0200 Subject: [PATCH 1/5] cosmetic improvements * refresh display immediately after changing contents via CLI * add RTC value in showDeviceStatus --- lib/application/maincontroller.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/application/maincontroller.cpp b/lib/application/maincontroller.cpp index 8f82718..29ebe76 100644 --- a/lib/application/maincontroller.cpp +++ b/lib/application/maincontroller.cpp @@ -389,7 +389,7 @@ void mainController::showLoRaWanStatus() { snprintf(tmpString, screen::maxConsoleTextLength, "Gateways : %u", static_cast(LoRaWAN::gatewayCount)); screen::setText(5, tmpString); time_t rtcTime = realTimeClock::get(); - const struct tm* rtcTime2 = localtime(&rtcTime); + const struct tm* rtcTime2 = gmtime(&rtcTime); strftime(tmpString, screen::maxConsoleTextLength, "Date : %Y-%b-%d", rtcTime2); screen::setText(6, tmpString); strftime(tmpString, screen::maxConsoleTextLength, "Time : %H:%M:%S", rtcTime2); @@ -613,12 +613,14 @@ void mainController::showHelp() { } void mainController::showDeviceStatus() { - cli::sendResponse("UID : %s\n", uniqueId::asHexString()); - cli::sendResponse("name : %s\n", name); - cli::sendResponse("display : %s\n", display::isPresent() ? "present" : "not present"); - cli::sendResponse("EEPROM : %d * 64K present\n", nonVolatileStorage::getNmbr64KBanks()); - cli::sendResponse("battery : %s (%d)\n", toString(battery::getType()), static_cast(battery::getType())); - cli::sendResponse("radioType: %s (%d)\n", toString(sx126x::getType()), static_cast(sx126x::getType())); + cli::sendResponse("UID : %s\n", uniqueId::asHexString()); + cli::sendResponse("name : %s\n", name); + cli::sendResponse("display : %s\n", display::isPresent() ? "present" : "not present"); + cli::sendResponse("EEPROM : %d * 64K present\n", nonVolatileStorage::getNmbr64KBanks()); + cli::sendResponse("battery : %s (%d)\n", toString(battery::getType()), static_cast(battery::getType())); + cli::sendResponse("radio : %s (%d)\n", toString(sx126x::getType()), static_cast(sx126x::getType())); + time_t rtcTime = realTimeClock::get(); + cli::sendResponse("RTC : %s", ctime(&rtcTime)); for (uint32_t sensorDeviceIndex = 0; sensorDeviceIndex < static_cast(sensorDeviceType::nmbrOfKnownDevices); sensorDeviceIndex++) { if (sensorDeviceCollection::isPresent(sensorDeviceIndex)) { @@ -780,6 +782,7 @@ void mainController::setDisplay(const cliCommand& theCommand) { displayChannelIndex[tmpLineIndex] = tmpChannelIndex; cli::sendResponse("display line %u set to %s - %s\n", tmpLineIndex, sensorDeviceCollection::name(tmpDeviceIndex), sensorDeviceCollection::name(tmpDeviceIndex, tmpChannelIndex)); + showMain(); } void mainController::setSensor(const cliCommand& theCommand) { From 4d9126136a9ddc9bc957baecb4bc750eb36c0266 Mon Sep 17 00:00:00 2001 From: Pascal Roobrouck Date: Wed, 16 Jul 2025 11:16:28 +0200 Subject: [PATCH 2/5] refactoring getting rid of a few default methods to avoid confusion --- lib/application/maincontroller.cpp | 63 +++++++++++++++++++- lib/application/maincontroller.hpp | 14 +++-- lib/lorawan/deviceaddress.hpp | 6 ++ lib/lorawan/framecount.hpp | 5 ++ lib/lorawan/lorawan.cpp | 10 ++-- lib/lorawan/lorawan.hpp | 2 +- platformio.ini | 6 +- test/generic/test_framecount/test.cpp | 22 +------ test/generic/test_lorawan_0_general/test.cpp | 47 ++------------- 9 files changed, 96 insertions(+), 79 deletions(-) diff --git a/lib/application/maincontroller.cpp b/lib/application/maincontroller.cpp index 29ebe76..29b574e 100644 --- a/lib/application/maincontroller.cpp +++ b/lib/application/maincontroller.cpp @@ -590,7 +590,7 @@ void mainController::showPrompt() { } void mainController::showHelp() { - cli::sendResponse(" :show build info and license\n"); + cli::sendResponse(" : show build info and license\n"); cli::sendResponse("? : show help\n"); cli::sendResponse("gds : show device status\n"); cli::sendResponse("gms : show recorded measurements status\n"); @@ -941,4 +941,65 @@ void mainController::showMeasurementsCsv() { nmbrOfGroups++; offset += measurementGroup::lengthInBytes(tmpGroup.getNumberOfMeasurements()); } +} + +void mainController::setDisplay(const uint8_t* payload, const uint32_t payloadLength) { + if (payloadLength != 3) { + return; + } + uint32_t tmpLineIndex = payload[0]; + if (tmpLineIndex >= screen::nmbrOfMeasurementTextLines) { + return; + } + uint32_t tmpDeviceIndex = payload[1]; + uint32_t tmpChannelIndex = payload[2]; + if (!sensorDeviceCollection::isValid(tmpDeviceIndex, tmpChannelIndex)) { + return; + } + uint8_t tmpDeviceAndChannel = sensorChannel::compressDeviceAndChannelIndex(static_cast(tmpDeviceIndex), static_cast(tmpChannelIndex)); + settingsCollection::save(tmpDeviceAndChannel, settingsCollection::settingIndex::displaySettings, tmpLineIndex); + displayDeviceIndex[tmpLineIndex] = tmpDeviceIndex; + displayChannelIndex[tmpLineIndex] = tmpChannelIndex; + // showMain(); +} + +void mainController::setSensor(const uint8_t* payload, const uint32_t payloadLength) { + if (payloadLength != 4) { + return; + } + uint32_t tmpDeviceIndex = payload[0]; + uint32_t tmpChannelIndex = payload[1]; + if (!sensorDeviceCollection::isValid(tmpDeviceIndex, tmpChannelIndex)) { + return; + } + uint32_t tmpOversamplingIndex = payload[2]; + ; + uint32_t tmpPrescalerIndex = payload[3]; + ; + if (tmpPrescalerIndex > sensorChannel::maxPrescalerIndex) { + tmpPrescalerIndex = sensorChannel::maxPrescalerIndex; + } + if (tmpOversamplingIndex > sensorChannel::maxOversamplingIndex) { + tmpOversamplingIndex = sensorChannel::maxOversamplingIndex; + } + if (tmpOversamplingIndex > tmpPrescalerIndex) { + tmpOversamplingIndex = tmpPrescalerIndex; + } + uint8_t tmpCombined = sensorChannel::compressOversamplingAndPrescalerIndex(tmpOversamplingIndex, tmpPrescalerIndex); + uint8_t tmpDeviceAndChannel = sensorChannel::compressDeviceAndChannelIndex(static_cast(tmpDeviceIndex), static_cast(tmpChannelIndex)); + settingsCollection::save(tmpCombined, settingsCollection::settingIndex::sensorSettings, tmpDeviceAndChannel); + sensorDeviceCollection::channel(tmpDeviceIndex, tmpChannelIndex).setIndex(tmpOversamplingIndex, tmpPrescalerIndex); +} + +void mainController::handleDownLink(const uint8_t port, const uint8_t* payload, const uint32_t payloadLength) { + switch (port) { + case 1: + setDisplay(payload, payloadLength); + break; + case 2: + setSensor(payload, payloadLength); + break; + default: + break; + } } \ No newline at end of file diff --git a/lib/application/maincontroller.hpp b/lib/application/maincontroller.hpp index c4468a1..97660ca 100644 --- a/lib/application/maincontroller.hpp +++ b/lib/application/maincontroller.hpp @@ -37,11 +37,11 @@ class mainController { static constexpr uint32_t minNmbrAnswers{2}; static constexpr uint32_t maxNmbrRequests{12}; - - #ifndef unitTesting - - // private: - #endif + +#ifndef unitTesting + +// private: +#endif static char name[maxNameLength + 1]; static uint32_t displayDeviceIndex[screen::nmbrOfMeasurementTextLines]; static uint32_t displayChannelIndex[screen::nmbrOfMeasurementTextLines]; @@ -80,4 +80,8 @@ class mainController { static void setRadioType(const cliCommand& aCommand); static void setDisplay(const cliCommand& aCommand); static void setSensor(const cliCommand& aCommand); + + static void setSensor(const uint8_t* payload, const uint32_t payloadLength); + static void setDisplay(const uint8_t* payload, const uint32_t payloadLength); + static void handleDownLink(const uint8_t port, const uint8_t* payload, const uint32_t payloadLength); }; diff --git a/lib/lorawan/deviceaddress.hpp b/lib/lorawan/deviceaddress.hpp index 9ba71c7..4179690 100644 --- a/lib/lorawan/deviceaddress.hpp +++ b/lib/lorawan/deviceaddress.hpp @@ -10,6 +10,12 @@ class deviceAddress { public: + deviceAddress() = default; + deviceAddress(const deviceAddress&) = delete; + deviceAddress& operator=(const deviceAddress&) = delete; + deviceAddress(deviceAddress&&) = delete; + deviceAddress& operator=(deviceAddress&&) = delete; + static constexpr uint32_t lengthInBytes{4}; static constexpr uint32_t lengthAsHexAscii{8}; diff --git a/lib/lorawan/framecount.hpp b/lib/lorawan/framecount.hpp index 4da798b..fcdc560 100644 --- a/lib/lorawan/framecount.hpp +++ b/lib/lorawan/framecount.hpp @@ -9,6 +9,11 @@ class frameCount { public: + frameCount() = default; + frameCount(const frameCount&) = delete; + frameCount& operator=(const frameCount&) = delete; + frameCount& operator=(frameCount&&) = delete; + static constexpr uint32_t lengthInBytes{4}; static constexpr uint32_t lengthInWords{1}; void guessFromUint16(uint16_t frameCount16Lsb); diff --git a/lib/lorawan/lorawan.cpp b/lib/lorawan/lorawan.cpp index d3beabf..4d999cb 100644 --- a/lib/lorawan/lorawan.cpp +++ b/lib/lorawan/lorawan.cpp @@ -1113,7 +1113,7 @@ messageType LoRaWAN::decodeMessage() { // 2. Extract & guess the downLinkFrameCount, as we need this to check the MIC uint16_t receivedDownlinkFramecount = receivedFramecount(); frameCount guessedDownlinkFramecount; - guessedDownlinkFramecount = downlinkFrameCount; + guessedDownlinkFramecount.setFromWord(downlinkFrameCount.getAsWord()); guessedDownlinkFramecount.guessFromUint16(receivedDownlinkFramecount); logging::snprintf(logging::source::lorawanMac, "receivedFramecount = %u, lastFramecount = %u, guessedFramecount = %u\n", receivedDownlinkFramecount, downlinkFrameCount.getAsWord(), guessedDownlinkFramecount.getAsWord()); @@ -1141,13 +1141,13 @@ messageType LoRaWAN::decodeMessage() { } // 5. check if the frameCount is valid - if (!isValidDownlinkFrameCount(guessedDownlinkFramecount)) { + if (!isValidDownlinkFrameCount(guessedDownlinkFramecount.getAsWord())) { logging::snprintf(logging::source::error, "Error : invalid downlinkFrameCount : received %u, current %u\n", guessedDownlinkFramecount.getAsWord(), downlinkFrameCount.getAsWord()); return messageType::invalid; } // 6. Seems a valid message, so update the downlinkFrameCount to what we've received (not just incrementing it, as there could be gaps in the sequence due to lost packets) - downlinkFrameCount = guessedDownlinkFramecount; + downlinkFrameCount.setFromWord(guessedDownlinkFramecount.getAsWord()); settingsCollection::save(downlinkFrameCount.getAsWord(), settingsCollection::settingIndex::downlinkFrameCounter); // 6.5 If we had sticky macOut stuff, we can clear that now, as we did receive a valid downlink @@ -1195,11 +1195,11 @@ uint32_t LoRaWAN::getReceiveTimeout(spreadingFactor aSpreadingFactor) { } } -bool LoRaWAN::isValidDownlinkFrameCount(frameCount testFrameCount) { +bool LoRaWAN::isValidDownlinkFrameCount(uint32_t testValue) { if (downlinkFrameCount.getAsWord() == 0) { return true; // no downlink received yet, so any frameCount is valid } else { - return (testFrameCount.getAsWord() > downlinkFrameCount.getAsWord()); + return (testValue > downlinkFrameCount.getAsWord()); } } diff --git a/lib/lorawan/lorawan.hpp b/lib/lorawan/lorawan.hpp index 64940ef..1f2c0cf 100644 --- a/lib/lorawan/lorawan.hpp +++ b/lib/lorawan/lorawan.hpp @@ -186,7 +186,7 @@ class LoRaWAN { static uint16_t receivedFramecount(); static uint32_t receivedDeviceAddress(); static uint32_t receivedMic(); - static bool isValidDownlinkFrameCount(frameCount testFrameCount); + static bool isValidDownlinkFrameCount(uint32_t testFrameCount); static messageType decodeMessage(); // ############################################################# diff --git a/platformio.ini b/platformio.ini index 73f8546..a3fe8bc 100644 --- a/platformio.ini +++ b/platformio.ini @@ -120,7 +120,7 @@ test_filter = ;generic/test_logging ;generic/test_gpio ;generic/test_power - generic/test_display + ;generic/test_display ;generic/test_battery ;generic/test_bme68x ;generic/test_tsl2591 @@ -131,8 +131,8 @@ test_filter = ;generic/test_applicationevent ;generic/test_graphics ;generic/test_lorawan_deviceaddress - ;generic/test_framecount - ;generic/test_lorawan_0_general + generic/test_framecount + generic/test_lorawan_0_general ;generic/test_lorawan_1_rawmessage ;generic/test_lorawan_2_crypto ;generic/test_lorawan_3_txrxcycle diff --git a/test/generic/test_framecount/test.cpp b/test/generic/test_framecount/test.cpp index bd6ec61..74e1373 100644 --- a/test/generic/test_framecount/test.cpp +++ b/test/generic/test_framecount/test.cpp @@ -21,25 +21,6 @@ void test_initialize() { } } -void test_operatorAssign() { - frameCount testFrameCount1; - frameCount testFrameCount2; - TEST_ASSERT_EQUAL(0, testFrameCount1.getAsWord()); - TEST_ASSERT_EQUAL(0, testFrameCount2.getAsWord()); - testFrameCount1.setFromWord(0x12345678); - TEST_ASSERT_EQUAL(0x12345678, testFrameCount1.getAsWord()); - uint8_t expectedBytes1[frameCount::lengthInBytes]{0x78, 0x56, 0x34, 0x12}; - for (uint32_t index = 0; index < frameCount::lengthInBytes; index++) { - TEST_ASSERT_EQUAL(expectedBytes1[index], testFrameCount1.getAsByte(index)); - } - testFrameCount2 = testFrameCount1; - TEST_ASSERT_EQUAL(0x12345678, testFrameCount2.getAsWord()); - uint8_t expectedBytes2[frameCount::lengthInBytes]{0x78, 0x56, 0x34, 0x12}; - for (uint32_t index = 0; index < frameCount::lengthInBytes; index++) { - TEST_ASSERT_EQUAL(expectedBytes2[index], testFrameCount2.getAsByte(index)); - } -} - void test_setFromByteArray() { frameCount testFrameCount; uint8_t testBytes[frameCount::lengthInBytes]{0x78, 0x56, 0x34, 0x12}; @@ -106,8 +87,7 @@ int main(int argc, char **argv) { #endif UNITY_BEGIN(); RUN_TEST(test_initialize); - RUN_TEST(test_operatorAssign); - RUN_TEST(test_setFromByteArray); + RUN_TEST(test_setFromByteArray); RUN_TEST(test_SetFromWord); RUN_TEST(test_operatorIncrement); RUN_TEST(test_guessFromUint16); diff --git a/test/generic/test_lorawan_0_general/test.cpp b/test/generic/test_lorawan_0_general/test.cpp index 22deac4..639016b 100644 --- a/test/generic/test_lorawan_0_general/test.cpp +++ b/test/generic/test_lorawan_0_general/test.cpp @@ -112,13 +112,13 @@ void test_isValidDownlinkFrameCount() { LoRaWAN::downlinkFrameCount.setFromWord(0); frameCount testFrameCount; testFrameCount.setFromWord(10); - TEST_ASSERT_TRUE(LoRaWAN::isValidDownlinkFrameCount(testFrameCount)); + TEST_ASSERT_TRUE(LoRaWAN::isValidDownlinkFrameCount(testFrameCount.getAsWord())); LoRaWAN::downlinkFrameCount.setFromWord(9); - TEST_ASSERT_TRUE(LoRaWAN::isValidDownlinkFrameCount(testFrameCount)); + TEST_ASSERT_TRUE(LoRaWAN::isValidDownlinkFrameCount(testFrameCount.getAsWord())); LoRaWAN::downlinkFrameCount.setFromWord(10); - TEST_ASSERT_FALSE(LoRaWAN::isValidDownlinkFrameCount(testFrameCount)); + TEST_ASSERT_FALSE(LoRaWAN::isValidDownlinkFrameCount(testFrameCount.getAsWord())); LoRaWAN::downlinkFrameCount.setFromWord(11); - TEST_ASSERT_FALSE(LoRaWAN::isValidDownlinkFrameCount(testFrameCount)); + TEST_ASSERT_FALSE(LoRaWAN::isValidDownlinkFrameCount(testFrameCount.getAsWord())); } void test_dump() { @@ -136,44 +136,6 @@ void test_dump() { TEST_MESSAGE("For Coverage only"); } -// void test_saveContext() { -// memset(mockEepromMemory, 0x00, 512); - -// LoRaWAN::DevAddr = 0x44657641; // reads as DevA in memory -// LoRaWAN::uplinkFrameCount = 0x554C4643; // reads as ULFC in memory -// LoRaWAN::downlinkFrameCount = 0x444C4643; // reads as DLFC in memory -// LoRaWAN::rx1DelayInSeconds = 7; -// LoRaWAN::currentDataRateIndex = 3; -// LoRaWAN::applicationKey.setFromHexString("000102030405060708090A0B0C0D0E0F"); -// LoRaWAN::networkKey.setFromHexString("101112131415161718191A1B1C1D1E1F"); - -// LoRaWAN::saveConfig(); -// LoRaWAN::saveState(); -// LoRaWAN::saveChannels(); - -// LoRaWAN::DevAddr = 0; -// LoRaWAN::uplinkFrameCount = 0; -// LoRaWAN::downlinkFrameCount = 0; -// LoRaWAN::rx1DelayInSeconds = 0; -// LoRaWAN::currentDataRateIndex = 0; -// LoRaWAN::applicationKey.setFromHexString("00000000000000000000000000000000"); -// LoRaWAN::networkKey.setFromHexString("00000000000000000000000000000000"); - -// LoRaWAN::restoreConfig(); -// LoRaWAN::restoreState(); -// LoRaWAN::restoreChannels(); - -// TEST_ASSERT_EQUAL_UINT32(0x44657641, LoRaWAN::DevAddr.asUint32); -// TEST_ASSERT_EQUAL_UINT32(0x554C4643, LoRaWAN::uplinkFrameCount.toUint32()); -// TEST_ASSERT_EQUAL_UINT32(0x444C4643, LoRaWAN::downlinkFrameCount.toUint32()); -// TEST_ASSERT_EQUAL_UINT32(7, LoRaWAN::rx1DelayInSeconds); -// TEST_ASSERT_EQUAL_UINT32(3, LoRaWAN::currentDataRateIndex); -// char tmpKeyAsHexString[33]; -// hexAscii::byteArrayToHexString(tmpKeyAsHexString, LoRaWAN::applicationKey.asBytes(), 16); -// TEST_ASSERT_EQUAL_STRING("000102030405060708090A0B0C0D0E0F", tmpKeyAsHexString); -// hexAscii::byteArrayToHexString(tmpKeyAsHexString, LoRaWAN::networkKey.asBytes(), 16); -// TEST_ASSERT_EQUAL_STRING("101112131415161718191A1B1C1D1E1F", tmpKeyAsHexString); -// } int main(int argc, char **argv) { UNITY_BEGIN(); @@ -187,7 +149,6 @@ int main(int argc, char **argv) { RUN_TEST(test_save_restore_channels); RUN_TEST(test_isValidDownlinkFrameCount); RUN_TEST(test_dump); - // RUN_TEST(test_saveContext); UNITY_END(); } \ No newline at end of file From da705fb687738bf7f3bf3922268fe1807a3d36dd Mon Sep 17 00:00:00 2001 From: Pascal Roobrouck Date: Wed, 16 Jul 2025 13:18:26 +0200 Subject: [PATCH 3/5] step 1 receiving downlink payload next step is retrieve it and decode it --- lib/application/maincontroller.cpp | 4 ++++ lib/logging/logging.cpp | 3 +++ lib/lorawan/lorawan.cpp | 9 ++++++--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/application/maincontroller.cpp b/lib/application/maincontroller.cpp index 29ebe76..4e0b43a 100644 --- a/lib/application/maincontroller.cpp +++ b/lib/application/maincontroller.cpp @@ -260,6 +260,10 @@ void mainController::handleEventsStateNetworking(applicationEvent theEvent) { LoRaWAN::handleEvents(theEvent); break; + case applicationEvent::downlinkApplicationPayloadReceived: + logging::snprintf("## --> Received application payload ##\n"); + LoRaWAN::getReceivedDownlinkMessage(); + break; default: break; } diff --git a/lib/logging/logging.cpp b/lib/logging/logging.cpp index 0f3c129..683fa14 100644 --- a/lib/logging/logging.cpp +++ b/lib/logging/logging.cpp @@ -27,6 +27,9 @@ char logging::buffer[bufferLength]{}; void logging::initialize() { enable(logging::destination::uart1); + + enable(logging::source::lorawanData); + enable(logging::source::error); enable(logging::source::criticalError); } diff --git a/lib/lorawan/lorawan.cpp b/lib/lorawan/lorawan.cpp index d3beabf..d35d309 100644 --- a/lib/lorawan/lorawan.cpp +++ b/lib/lorawan/lorawan.cpp @@ -386,7 +386,7 @@ void LoRaWAN::encryptDecryptPayload(const aesKey& theKey, linkDirection theLinkD } void LoRaWAN::generateKeysK1K2() { - for (uint32_t byteIndex=0; byteIndex < aesKey::lengthInBytes; byteIndex++) { + for (uint32_t byteIndex = 0; byteIndex < aesKey::lengthInBytes; byteIndex++) { K1.setByte(byteIndex, 0); K2.setByte(byteIndex, 0); } @@ -627,15 +627,15 @@ void LoRaWAN::handleEvents(applicationEvent theEvent) { case messageType::application: lptim::stop(); processMacContents(); - applicationEventBuffer.push(applicationEvent::downlinkApplicationPayloadReceived); goTo(txRxCycleState::waitForRxMessageReadout); + applicationEventBuffer.push(applicationEvent::downlinkApplicationPayloadReceived); return; break; case messageType::lorawanMac: lptim::stop(); processMacContents(); - applicationEventBuffer.push(applicationEvent::downlinkMacCommandReceived); goTo(txRxCycleState::idle); + applicationEventBuffer.push(applicationEvent::downlinkMacCommandReceived); return; break; case messageType::invalid: // intentional fallthrough @@ -676,12 +676,14 @@ void LoRaWAN::handleEvents(applicationEvent theEvent) { messageType receivedMessageType = decodeMessage(); switch (receivedMessageType) { case messageType::application: + lptim::stop(); processMacContents(); applicationEventBuffer.push(applicationEvent::downlinkApplicationPayloadReceived); goTo(txRxCycleState::waitForRxMessageReadout); return; break; case messageType::lorawanMac: + lptim::stop(); processMacContents(); applicationEventBuffer.push(applicationEvent::downlinkMacCommandReceived); goTo(txRxCycleState::idle); @@ -1099,6 +1101,7 @@ void LoRaWAN::sendUplink(uint8_t theFramePort, const uint8_t applicationData[], void LoRaWAN::getReceivedDownlinkMessage() { // sx126x::getReceivedMessage(); // downlinkMessage.processDownlinkMessage(applicationPayloadReceived); + goTo(txRxCycleState::idle); } messageType LoRaWAN::decodeMessage() { From b510854cae682d525d749cae4a1c3d044a7af632 Mon Sep 17 00:00:00 2001 From: Pascal Roobrouck Date: Wed, 16 Jul 2025 14:27:39 +0200 Subject: [PATCH 4/5] receiving downlink data in mainController port payloadLength payload next step is calling a handler --- lib/application/maincontroller.cpp | 15 +++++++++++++-- lib/lorawan/lorawan.cpp | 16 ++++++++++++++++ lib/lorawan/lorawan.hpp | 8 ++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/application/maincontroller.cpp b/lib/application/maincontroller.cpp index 4e0b43a..e8f5d35 100644 --- a/lib/application/maincontroller.cpp +++ b/lib/application/maincontroller.cpp @@ -260,10 +260,21 @@ void mainController::handleEventsStateNetworking(applicationEvent theEvent) { LoRaWAN::handleEvents(theEvent); break; - case applicationEvent::downlinkApplicationPayloadReceived: + case applicationEvent::downlinkApplicationPayloadReceived: { logging::snprintf("## --> Received application payload ##\n"); + logging::snprintf("port : %u\n", LoRaWAN::getPort()); + uint32_t payloadLength = LoRaWAN::getPayloadLength(); + logging::snprintf("payload length : %u\n", payloadLength); + uint8_t payload[payloadLength]; + LoRaWAN::getPayload(payload, payloadLength); + logging::snprintf("payload : "); + for (uint8_t i = 0; i < payloadLength; i++) { + logging::snprintf("%02X ", payload[i]); + } + logging::snprintf("\n"); LoRaWAN::getReceivedDownlinkMessage(); - break; + } break; + default: break; } diff --git a/lib/lorawan/lorawan.cpp b/lib/lorawan/lorawan.cpp index d35d309..d44e39d 100644 --- a/lib/lorawan/lorawan.cpp +++ b/lib/lorawan/lorawan.cpp @@ -1344,3 +1344,19 @@ void LoRaWAN::resetMacLayer() { resetChannels(); saveChannels(); } + +uint32_t LoRaWAN::getPort() { + if (framePortLength > 0) { + return rawMessage[framePortOffset]; + } else { + return 0; + } +} + +uint32_t LoRaWAN::getPayloadLength() { + return framePayloadLength; +} + +void LoRaWAN::getPayload(uint8_t* destination, uint32_t length) { + memcpy(destination, rawMessage + framePayloadOffset, length); +} diff --git a/lib/lorawan/lorawan.hpp b/lib/lorawan/lorawan.hpp index 64940ef..286f5d2 100644 --- a/lib/lorawan/lorawan.hpp +++ b/lib/lorawan/lorawan.hpp @@ -58,9 +58,15 @@ class LoRaWAN { static void handleEvents(applicationEvent theEvent); static uint32_t getMaxApplicationPayloadLength(); + static void sendUplink(uint8_t framePort, const uint8_t payload[], uint32_t payloadLength); static void sendUplink(const measurementGroup &aMeasurementGroup); + static uint32_t getPort(); + static uint32_t getPayloadLength(); + static void getPayload(uint8_t* destination, uint32_t length); + + static void appendMacCommand(macCommand theMacCommand); static void getReceivedDownlinkMessage(); static txRxCycleState getState(); @@ -189,6 +195,8 @@ class LoRaWAN { static bool isValidDownlinkFrameCount(frameCount testFrameCount); static messageType decodeMessage(); + + // ############################################################# // ### Other Helper functions ### // ############################################################# From 84dbf0bb4096866aec2cba468fcddc1be844fcb6 Mon Sep 17 00:00:00 2001 From: Pascal Roobrouck Date: Wed, 16 Jul 2025 14:54:09 +0200 Subject: [PATCH 5/5] handle downlink requests in mainController --- lib/application/maincontroller.cpp | 24 ++++++++++-------------- lib/lorawan/lorawan.cpp | 10 +++++++++- lib/lorawan/lorawan.hpp | 3 ++- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/lib/application/maincontroller.cpp b/lib/application/maincontroller.cpp index 6fd382d..ab4025e 100644 --- a/lib/application/maincontroller.cpp +++ b/lib/application/maincontroller.cpp @@ -260,20 +260,10 @@ void mainController::handleEventsStateNetworking(applicationEvent theEvent) { LoRaWAN::handleEvents(theEvent); break; - case applicationEvent::downlinkApplicationPayloadReceived: { - logging::snprintf("## --> Received application payload ##\n"); - logging::snprintf("port : %u\n", LoRaWAN::getPort()); - uint32_t payloadLength = LoRaWAN::getPayloadLength(); - logging::snprintf("payload length : %u\n", payloadLength); - uint8_t payload[payloadLength]; - LoRaWAN::getPayload(payload, payloadLength); - logging::snprintf("payload : "); - for (uint8_t i = 0; i < payloadLength; i++) { - logging::snprintf("%02X ", payload[i]); - } - logging::snprintf("\n"); + case applicationEvent::downlinkApplicationPayloadReceived: + handleDownLink(LoRaWAN::getPort(), LoRaWAN::getPayloadPtr(), LoRaWAN::getPayloadLength()); LoRaWAN::getReceivedDownlinkMessage(); - } break; + break; default: break; @@ -959,6 +949,9 @@ void mainController::showMeasurementsCsv() { } void mainController::setDisplay(const uint8_t* payload, const uint32_t payloadLength) { + if (payload == nullptr) { + return; + } if (payloadLength != 3) { return; } @@ -975,10 +968,13 @@ void mainController::setDisplay(const uint8_t* payload, const uint32_t payloadLe settingsCollection::save(tmpDeviceAndChannel, settingsCollection::settingIndex::displaySettings, tmpLineIndex); displayDeviceIndex[tmpLineIndex] = tmpDeviceIndex; displayChannelIndex[tmpLineIndex] = tmpChannelIndex; - // showMain(); + showMain(); } void mainController::setSensor(const uint8_t* payload, const uint32_t payloadLength) { + if (payload == nullptr) { + return; + } if (payloadLength != 4) { return; } diff --git a/lib/lorawan/lorawan.cpp b/lib/lorawan/lorawan.cpp index 413b224..35df600 100644 --- a/lib/lorawan/lorawan.cpp +++ b/lib/lorawan/lorawan.cpp @@ -1345,7 +1345,7 @@ void LoRaWAN::resetMacLayer() { saveChannels(); } -uint32_t LoRaWAN::getPort() { +uint8_t LoRaWAN::getPort() { if (framePortLength > 0) { return rawMessage[framePortOffset]; } else { @@ -1360,3 +1360,11 @@ uint32_t LoRaWAN::getPayloadLength() { void LoRaWAN::getPayload(uint8_t* destination, uint32_t length) { memcpy(destination, rawMessage + framePayloadOffset, length); } + +const uint8_t* LoRaWAN::getPayloadPtr() { + if (framePayloadLength > 0) { + return rawMessage + framePayloadOffset; + } else { + return nullptr; + } +} \ No newline at end of file diff --git a/lib/lorawan/lorawan.hpp b/lib/lorawan/lorawan.hpp index ee6e45f..6719886 100644 --- a/lib/lorawan/lorawan.hpp +++ b/lib/lorawan/lorawan.hpp @@ -62,9 +62,10 @@ class LoRaWAN { static void sendUplink(uint8_t framePort, const uint8_t payload[], uint32_t payloadLength); static void sendUplink(const measurementGroup &aMeasurementGroup); - static uint32_t getPort(); + static uint8_t getPort(); static uint32_t getPayloadLength(); static void getPayload(uint8_t* destination, uint32_t length); + static const uint8_t * getPayloadPtr(); static void appendMacCommand(macCommand theMacCommand);