Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 83 additions & 8 deletions lib/application/maincontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,11 @@ void mainController::handleEventsStateNetworking(applicationEvent theEvent) {
LoRaWAN::handleEvents(theEvent);
break;

case applicationEvent::downlinkApplicationPayloadReceived:
handleDownLink(LoRaWAN::getPort(), LoRaWAN::getPayloadPtr(), LoRaWAN::getPayloadLength());
LoRaWAN::getReceivedDownlinkMessage();
break;

default:
break;
}
Expand Down Expand Up @@ -389,7 +394,7 @@ void mainController::showLoRaWanStatus() {
snprintf(tmpString, screen::maxConsoleTextLength, "Gateways : %u", static_cast<uint8_t>(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);
Expand Down Expand Up @@ -590,7 +595,7 @@ void mainController::showPrompt() {
}

void mainController::showHelp() {
cli::sendResponse("<enter> :show build info and license\n");
cli::sendResponse("<enter> : 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");
Expand All @@ -613,12 +618,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<uint8_t>(battery::getType()));
cli::sendResponse("radioType: %s (%d)\n", toString(sx126x::getType()), static_cast<uint8_t>(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<uint8_t>(battery::getType()));
cli::sendResponse("radio : %s (%d)\n", toString(sx126x::getType()), static_cast<uint8_t>(sx126x::getType()));
time_t rtcTime = realTimeClock::get();
cli::sendResponse("RTC : %s", ctime(&rtcTime));

for (uint32_t sensorDeviceIndex = 0; sensorDeviceIndex < static_cast<uint32_t>(sensorDeviceType::nmbrOfKnownDevices); sensorDeviceIndex++) {
if (sensorDeviceCollection::isPresent(sensorDeviceIndex)) {
Expand Down Expand Up @@ -780,6 +787,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) {
Expand Down Expand Up @@ -938,4 +946,71 @@ void mainController::showMeasurementsCsv() {
nmbrOfGroups++;
offset += measurementGroup::lengthInBytes(tmpGroup.getNumberOfMeasurements());
}
}

void mainController::setDisplay(const uint8_t* payload, const uint32_t payloadLength) {
if (payload == nullptr) {
return;
}
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<uint8_t>(tmpDeviceIndex), static_cast<uint8_t>(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 (payload == nullptr) {
return;
}
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<uint8_t>(tmpDeviceIndex), static_cast<uint8_t>(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;
}
}
14 changes: 9 additions & 5 deletions lib/application/maincontroller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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);
};
3 changes: 3 additions & 0 deletions lib/logging/logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
6 changes: 6 additions & 0 deletions lib/lorawan/deviceaddress.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down
5 changes: 5 additions & 0 deletions lib/lorawan/framecount.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
43 changes: 35 additions & 8 deletions lib/lorawan/lorawan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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() {
Expand All @@ -1113,7 +1116,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());

Expand Down Expand Up @@ -1141,13 +1144,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
Expand Down Expand Up @@ -1195,11 +1198,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());
}
}

Expand Down Expand Up @@ -1341,3 +1344,27 @@ void LoRaWAN::resetMacLayer() {
resetChannels();
saveChannels();
}

uint8_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);
}

const uint8_t* LoRaWAN::getPayloadPtr() {
if (framePayloadLength > 0) {
return rawMessage + framePayloadOffset;
} else {
return nullptr;
}
}
11 changes: 10 additions & 1 deletion lib/lorawan/lorawan.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,16 @@ 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 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);
static void getReceivedDownlinkMessage();
static txRxCycleState getState();
Expand Down Expand Up @@ -186,9 +193,11 @@ 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();



// #############################################################
// ### Other Helper functions ###
// #############################################################
Expand Down
6 changes: 3 additions & 3 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
22 changes: 1 addition & 21 deletions test/generic/test_framecount/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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);
Expand Down
Loading
Loading