Skip to content

Commit 1710cae

Browse files
authored
minor : use downlinks to configure sensors or display
Merge Develop into Main
2 parents d88d395 + 84dbf0b commit 1710cae

File tree

10 files changed

+159
-89
lines changed

10 files changed

+159
-89
lines changed

lib/application/maincontroller.cpp

Lines changed: 83 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,11 @@ void mainController::handleEventsStateNetworking(applicationEvent theEvent) {
260260
LoRaWAN::handleEvents(theEvent);
261261
break;
262262

263+
case applicationEvent::downlinkApplicationPayloadReceived:
264+
handleDownLink(LoRaWAN::getPort(), LoRaWAN::getPayloadPtr(), LoRaWAN::getPayloadLength());
265+
LoRaWAN::getReceivedDownlinkMessage();
266+
break;
267+
263268
default:
264269
break;
265270
}
@@ -389,7 +394,7 @@ void mainController::showLoRaWanStatus() {
389394
snprintf(tmpString, screen::maxConsoleTextLength, "Gateways : %u", static_cast<uint8_t>(LoRaWAN::gatewayCount));
390395
screen::setText(5, tmpString);
391396
time_t rtcTime = realTimeClock::get();
392-
const struct tm* rtcTime2 = localtime(&rtcTime);
397+
const struct tm* rtcTime2 = gmtime(&rtcTime);
393398
strftime(tmpString, screen::maxConsoleTextLength, "Date : %Y-%b-%d", rtcTime2);
394399
screen::setText(6, tmpString);
395400
strftime(tmpString, screen::maxConsoleTextLength, "Time : %H:%M:%S", rtcTime2);
@@ -590,7 +595,7 @@ void mainController::showPrompt() {
590595
}
591596

592597
void mainController::showHelp() {
593-
cli::sendResponse("<enter> :show build info and license\n");
598+
cli::sendResponse("<enter> : show build info and license\n");
594599
cli::sendResponse("? : show help\n");
595600
cli::sendResponse("gds : show device status\n");
596601
cli::sendResponse("gms : show recorded measurements status\n");
@@ -613,12 +618,14 @@ void mainController::showHelp() {
613618
}
614619

615620
void mainController::showDeviceStatus() {
616-
cli::sendResponse("UID : %s\n", uniqueId::asHexString());
617-
cli::sendResponse("name : %s\n", name);
618-
cli::sendResponse("display : %s\n", display::isPresent() ? "present" : "not present");
619-
cli::sendResponse("EEPROM : %d * 64K present\n", nonVolatileStorage::getNmbr64KBanks());
620-
cli::sendResponse("battery : %s (%d)\n", toString(battery::getType()), static_cast<uint8_t>(battery::getType()));
621-
cli::sendResponse("radioType: %s (%d)\n", toString(sx126x::getType()), static_cast<uint8_t>(sx126x::getType()));
621+
cli::sendResponse("UID : %s\n", uniqueId::asHexString());
622+
cli::sendResponse("name : %s\n", name);
623+
cli::sendResponse("display : %s\n", display::isPresent() ? "present" : "not present");
624+
cli::sendResponse("EEPROM : %d * 64K present\n", nonVolatileStorage::getNmbr64KBanks());
625+
cli::sendResponse("battery : %s (%d)\n", toString(battery::getType()), static_cast<uint8_t>(battery::getType()));
626+
cli::sendResponse("radio : %s (%d)\n", toString(sx126x::getType()), static_cast<uint8_t>(sx126x::getType()));
627+
time_t rtcTime = realTimeClock::get();
628+
cli::sendResponse("RTC : %s", ctime(&rtcTime));
622629

623630
for (uint32_t sensorDeviceIndex = 0; sensorDeviceIndex < static_cast<uint32_t>(sensorDeviceType::nmbrOfKnownDevices); sensorDeviceIndex++) {
624631
if (sensorDeviceCollection::isPresent(sensorDeviceIndex)) {
@@ -780,6 +787,7 @@ void mainController::setDisplay(const cliCommand& theCommand) {
780787
displayChannelIndex[tmpLineIndex] = tmpChannelIndex;
781788

782789
cli::sendResponse("display line %u set to %s - %s\n", tmpLineIndex, sensorDeviceCollection::name(tmpDeviceIndex), sensorDeviceCollection::name(tmpDeviceIndex, tmpChannelIndex));
790+
showMain();
783791
}
784792

785793
void mainController::setSensor(const cliCommand& theCommand) {
@@ -938,4 +946,71 @@ void mainController::showMeasurementsCsv() {
938946
nmbrOfGroups++;
939947
offset += measurementGroup::lengthInBytes(tmpGroup.getNumberOfMeasurements());
940948
}
949+
}
950+
951+
void mainController::setDisplay(const uint8_t* payload, const uint32_t payloadLength) {
952+
if (payload == nullptr) {
953+
return;
954+
}
955+
if (payloadLength != 3) {
956+
return;
957+
}
958+
uint32_t tmpLineIndex = payload[0];
959+
if (tmpLineIndex >= screen::nmbrOfMeasurementTextLines) {
960+
return;
961+
}
962+
uint32_t tmpDeviceIndex = payload[1];
963+
uint32_t tmpChannelIndex = payload[2];
964+
if (!sensorDeviceCollection::isValid(tmpDeviceIndex, tmpChannelIndex)) {
965+
return;
966+
}
967+
uint8_t tmpDeviceAndChannel = sensorChannel::compressDeviceAndChannelIndex(static_cast<uint8_t>(tmpDeviceIndex), static_cast<uint8_t>(tmpChannelIndex));
968+
settingsCollection::save(tmpDeviceAndChannel, settingsCollection::settingIndex::displaySettings, tmpLineIndex);
969+
displayDeviceIndex[tmpLineIndex] = tmpDeviceIndex;
970+
displayChannelIndex[tmpLineIndex] = tmpChannelIndex;
971+
showMain();
972+
}
973+
974+
void mainController::setSensor(const uint8_t* payload, const uint32_t payloadLength) {
975+
if (payload == nullptr) {
976+
return;
977+
}
978+
if (payloadLength != 4) {
979+
return;
980+
}
981+
uint32_t tmpDeviceIndex = payload[0];
982+
uint32_t tmpChannelIndex = payload[1];
983+
if (!sensorDeviceCollection::isValid(tmpDeviceIndex, tmpChannelIndex)) {
984+
return;
985+
}
986+
uint32_t tmpOversamplingIndex = payload[2];
987+
;
988+
uint32_t tmpPrescalerIndex = payload[3];
989+
;
990+
if (tmpPrescalerIndex > sensorChannel::maxPrescalerIndex) {
991+
tmpPrescalerIndex = sensorChannel::maxPrescalerIndex;
992+
}
993+
if (tmpOversamplingIndex > sensorChannel::maxOversamplingIndex) {
994+
tmpOversamplingIndex = sensorChannel::maxOversamplingIndex;
995+
}
996+
if (tmpOversamplingIndex > tmpPrescalerIndex) {
997+
tmpOversamplingIndex = tmpPrescalerIndex;
998+
}
999+
uint8_t tmpCombined = sensorChannel::compressOversamplingAndPrescalerIndex(tmpOversamplingIndex, tmpPrescalerIndex);
1000+
uint8_t tmpDeviceAndChannel = sensorChannel::compressDeviceAndChannelIndex(static_cast<uint8_t>(tmpDeviceIndex), static_cast<uint8_t>(tmpChannelIndex));
1001+
settingsCollection::save(tmpCombined, settingsCollection::settingIndex::sensorSettings, tmpDeviceAndChannel);
1002+
sensorDeviceCollection::channel(tmpDeviceIndex, tmpChannelIndex).setIndex(tmpOversamplingIndex, tmpPrescalerIndex);
1003+
}
1004+
1005+
void mainController::handleDownLink(const uint8_t port, const uint8_t* payload, const uint32_t payloadLength) {
1006+
switch (port) {
1007+
case 1:
1008+
setDisplay(payload, payloadLength);
1009+
break;
1010+
case 2:
1011+
setSensor(payload, payloadLength);
1012+
break;
1013+
default:
1014+
break;
1015+
}
9411016
}

lib/application/maincontroller.hpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ class mainController {
3737

3838
static constexpr uint32_t minNmbrAnswers{2};
3939
static constexpr uint32_t maxNmbrRequests{12};
40-
41-
#ifndef unitTesting
42-
43-
// private:
44-
#endif
40+
41+
#ifndef unitTesting
42+
43+
// private:
44+
#endif
4545
static char name[maxNameLength + 1];
4646
static uint32_t displayDeviceIndex[screen::nmbrOfMeasurementTextLines];
4747
static uint32_t displayChannelIndex[screen::nmbrOfMeasurementTextLines];
@@ -80,4 +80,8 @@ class mainController {
8080
static void setRadioType(const cliCommand& aCommand);
8181
static void setDisplay(const cliCommand& aCommand);
8282
static void setSensor(const cliCommand& aCommand);
83+
84+
static void setSensor(const uint8_t* payload, const uint32_t payloadLength);
85+
static void setDisplay(const uint8_t* payload, const uint32_t payloadLength);
86+
static void handleDownLink(const uint8_t port, const uint8_t* payload, const uint32_t payloadLength);
8387
};

lib/logging/logging.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ char logging::buffer[bufferLength]{};
2727

2828
void logging::initialize() {
2929
enable(logging::destination::uart1);
30+
31+
enable(logging::source::lorawanData);
32+
3033
enable(logging::source::error);
3134
enable(logging::source::criticalError);
3235
}

lib/lorawan/deviceaddress.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010

1111
class deviceAddress {
1212
public:
13+
deviceAddress() = default;
14+
deviceAddress(const deviceAddress&) = delete;
15+
deviceAddress& operator=(const deviceAddress&) = delete;
16+
deviceAddress(deviceAddress&&) = delete;
17+
deviceAddress& operator=(deviceAddress&&) = delete;
18+
1319
static constexpr uint32_t lengthInBytes{4};
1420
static constexpr uint32_t lengthAsHexAscii{8};
1521

lib/lorawan/framecount.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99

1010
class frameCount {
1111
public:
12+
frameCount() = default;
13+
frameCount(const frameCount&) = delete;
14+
frameCount& operator=(const frameCount&) = delete;
15+
frameCount& operator=(frameCount&&) = delete;
16+
1217
static constexpr uint32_t lengthInBytes{4};
1318
static constexpr uint32_t lengthInWords{1};
1419
void guessFromUint16(uint16_t frameCount16Lsb);

lib/lorawan/lorawan.cpp

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ void LoRaWAN::encryptDecryptPayload(const aesKey& theKey, linkDirection theLinkD
386386
}
387387

388388
void LoRaWAN::generateKeysK1K2() {
389-
for (uint32_t byteIndex=0; byteIndex < aesKey::lengthInBytes; byteIndex++) {
389+
for (uint32_t byteIndex = 0; byteIndex < aesKey::lengthInBytes; byteIndex++) {
390390
K1.setByte(byteIndex, 0);
391391
K2.setByte(byteIndex, 0);
392392
}
@@ -627,15 +627,15 @@ void LoRaWAN::handleEvents(applicationEvent theEvent) {
627627
case messageType::application:
628628
lptim::stop();
629629
processMacContents();
630-
applicationEventBuffer.push(applicationEvent::downlinkApplicationPayloadReceived);
631630
goTo(txRxCycleState::waitForRxMessageReadout);
631+
applicationEventBuffer.push(applicationEvent::downlinkApplicationPayloadReceived);
632632
return;
633633
break;
634634
case messageType::lorawanMac:
635635
lptim::stop();
636636
processMacContents();
637-
applicationEventBuffer.push(applicationEvent::downlinkMacCommandReceived);
638637
goTo(txRxCycleState::idle);
638+
applicationEventBuffer.push(applicationEvent::downlinkMacCommandReceived);
639639
return;
640640
break;
641641
case messageType::invalid: // intentional fallthrough
@@ -676,12 +676,14 @@ void LoRaWAN::handleEvents(applicationEvent theEvent) {
676676
messageType receivedMessageType = decodeMessage();
677677
switch (receivedMessageType) {
678678
case messageType::application:
679+
lptim::stop();
679680
processMacContents();
680681
applicationEventBuffer.push(applicationEvent::downlinkApplicationPayloadReceived);
681682
goTo(txRxCycleState::waitForRxMessageReadout);
682683
return;
683684
break;
684685
case messageType::lorawanMac:
686+
lptim::stop();
685687
processMacContents();
686688
applicationEventBuffer.push(applicationEvent::downlinkMacCommandReceived);
687689
goTo(txRxCycleState::idle);
@@ -1099,6 +1101,7 @@ void LoRaWAN::sendUplink(uint8_t theFramePort, const uint8_t applicationData[],
10991101
void LoRaWAN::getReceivedDownlinkMessage() {
11001102
// sx126x::getReceivedMessage();
11011103
// downlinkMessage.processDownlinkMessage(applicationPayloadReceived);
1104+
goTo(txRxCycleState::idle);
11021105
}
11031106

11041107
messageType LoRaWAN::decodeMessage() {
@@ -1113,7 +1116,7 @@ messageType LoRaWAN::decodeMessage() {
11131116
// 2. Extract & guess the downLinkFrameCount, as we need this to check the MIC
11141117
uint16_t receivedDownlinkFramecount = receivedFramecount();
11151118
frameCount guessedDownlinkFramecount;
1116-
guessedDownlinkFramecount = downlinkFrameCount;
1119+
guessedDownlinkFramecount.setFromWord(downlinkFrameCount.getAsWord());
11171120
guessedDownlinkFramecount.guessFromUint16(receivedDownlinkFramecount);
11181121
logging::snprintf(logging::source::lorawanMac, "receivedFramecount = %u, lastFramecount = %u, guessedFramecount = %u\n", receivedDownlinkFramecount, downlinkFrameCount.getAsWord(), guessedDownlinkFramecount.getAsWord());
11191122

@@ -1141,13 +1144,13 @@ messageType LoRaWAN::decodeMessage() {
11411144
}
11421145

11431146
// 5. check if the frameCount is valid
1144-
if (!isValidDownlinkFrameCount(guessedDownlinkFramecount)) {
1147+
if (!isValidDownlinkFrameCount(guessedDownlinkFramecount.getAsWord())) {
11451148
logging::snprintf(logging::source::error, "Error : invalid downlinkFrameCount : received %u, current %u\n", guessedDownlinkFramecount.getAsWord(), downlinkFrameCount.getAsWord());
11461149
return messageType::invalid;
11471150
}
11481151

11491152
// 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)
1150-
downlinkFrameCount = guessedDownlinkFramecount;
1153+
downlinkFrameCount.setFromWord(guessedDownlinkFramecount.getAsWord());
11511154
settingsCollection::save(downlinkFrameCount.getAsWord(), settingsCollection::settingIndex::downlinkFrameCounter);
11521155

11531156
// 6.5 If we had sticky macOut stuff, we can clear that now, as we did receive a valid downlink
@@ -1195,11 +1198,11 @@ uint32_t LoRaWAN::getReceiveTimeout(spreadingFactor aSpreadingFactor) {
11951198
}
11961199
}
11971200

1198-
bool LoRaWAN::isValidDownlinkFrameCount(frameCount testFrameCount) {
1201+
bool LoRaWAN::isValidDownlinkFrameCount(uint32_t testValue) {
11991202
if (downlinkFrameCount.getAsWord() == 0) {
12001203
return true; // no downlink received yet, so any frameCount is valid
12011204
} else {
1202-
return (testFrameCount.getAsWord() > downlinkFrameCount.getAsWord());
1205+
return (testValue > downlinkFrameCount.getAsWord());
12031206
}
12041207
}
12051208

@@ -1341,3 +1344,27 @@ void LoRaWAN::resetMacLayer() {
13411344
resetChannels();
13421345
saveChannels();
13431346
}
1347+
1348+
uint8_t LoRaWAN::getPort() {
1349+
if (framePortLength > 0) {
1350+
return rawMessage[framePortOffset];
1351+
} else {
1352+
return 0;
1353+
}
1354+
}
1355+
1356+
uint32_t LoRaWAN::getPayloadLength() {
1357+
return framePayloadLength;
1358+
}
1359+
1360+
void LoRaWAN::getPayload(uint8_t* destination, uint32_t length) {
1361+
memcpy(destination, rawMessage + framePayloadOffset, length);
1362+
}
1363+
1364+
const uint8_t* LoRaWAN::getPayloadPtr() {
1365+
if (framePayloadLength > 0) {
1366+
return rawMessage + framePayloadOffset;
1367+
} else {
1368+
return nullptr;
1369+
}
1370+
}

lib/lorawan/lorawan.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,16 @@ class LoRaWAN {
5858

5959
static void handleEvents(applicationEvent theEvent);
6060
static uint32_t getMaxApplicationPayloadLength();
61+
6162
static void sendUplink(uint8_t framePort, const uint8_t payload[], uint32_t payloadLength);
6263
static void sendUplink(const measurementGroup &aMeasurementGroup);
6364

65+
static uint8_t getPort();
66+
static uint32_t getPayloadLength();
67+
static void getPayload(uint8_t* destination, uint32_t length);
68+
static const uint8_t * getPayloadPtr();
69+
70+
6471
static void appendMacCommand(macCommand theMacCommand);
6572
static void getReceivedDownlinkMessage();
6673
static txRxCycleState getState();
@@ -186,9 +193,11 @@ class LoRaWAN {
186193
static uint16_t receivedFramecount();
187194
static uint32_t receivedDeviceAddress();
188195
static uint32_t receivedMic();
189-
static bool isValidDownlinkFrameCount(frameCount testFrameCount);
196+
static bool isValidDownlinkFrameCount(uint32_t testFrameCount);
190197
static messageType decodeMessage();
191198

199+
200+
192201
// #############################################################
193202
// ### Other Helper functions ###
194203
// #############################################################

platformio.ini

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ test_filter =
120120
;generic/test_logging
121121
;generic/test_gpio
122122
;generic/test_power
123-
generic/test_display
123+
;generic/test_display
124124
;generic/test_battery
125125
;generic/test_bme68x
126126
;generic/test_tsl2591
@@ -131,8 +131,8 @@ test_filter =
131131
;generic/test_applicationevent
132132
;generic/test_graphics
133133
;generic/test_lorawan_deviceaddress
134-
;generic/test_framecount
135-
;generic/test_lorawan_0_general
134+
generic/test_framecount
135+
generic/test_lorawan_0_general
136136
;generic/test_lorawan_1_rawmessage
137137
;generic/test_lorawan_2_crypto
138138
;generic/test_lorawan_3_txrxcycle

test/generic/test_framecount/test.cpp

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,25 +21,6 @@ void test_initialize() {
2121
}
2222
}
2323

24-
void test_operatorAssign() {
25-
frameCount testFrameCount1;
26-
frameCount testFrameCount2;
27-
TEST_ASSERT_EQUAL(0, testFrameCount1.getAsWord());
28-
TEST_ASSERT_EQUAL(0, testFrameCount2.getAsWord());
29-
testFrameCount1.setFromWord(0x12345678);
30-
TEST_ASSERT_EQUAL(0x12345678, testFrameCount1.getAsWord());
31-
uint8_t expectedBytes1[frameCount::lengthInBytes]{0x78, 0x56, 0x34, 0x12};
32-
for (uint32_t index = 0; index < frameCount::lengthInBytes; index++) {
33-
TEST_ASSERT_EQUAL(expectedBytes1[index], testFrameCount1.getAsByte(index));
34-
}
35-
testFrameCount2 = testFrameCount1;
36-
TEST_ASSERT_EQUAL(0x12345678, testFrameCount2.getAsWord());
37-
uint8_t expectedBytes2[frameCount::lengthInBytes]{0x78, 0x56, 0x34, 0x12};
38-
for (uint32_t index = 0; index < frameCount::lengthInBytes; index++) {
39-
TEST_ASSERT_EQUAL(expectedBytes2[index], testFrameCount2.getAsByte(index));
40-
}
41-
}
42-
4324
void test_setFromByteArray() {
4425
frameCount testFrameCount;
4526
uint8_t testBytes[frameCount::lengthInBytes]{0x78, 0x56, 0x34, 0x12};
@@ -106,8 +87,7 @@ int main(int argc, char **argv) {
10687
#endif
10788
UNITY_BEGIN();
10889
RUN_TEST(test_initialize);
109-
RUN_TEST(test_operatorAssign);
110-
RUN_TEST(test_setFromByteArray);
90+
RUN_TEST(test_setFromByteArray);
11191
RUN_TEST(test_SetFromWord);
11292
RUN_TEST(test_operatorIncrement);
11393
RUN_TEST(test_guessFromUint16);

0 commit comments

Comments
 (0)