A simple program that connects to University of Queensland's Lora network and requests a joke, then prints the joke to usb serial.
Dependencies: fota-mdot libmDot MTS-Serial
src/LoraComms.cpp
- Committer:
- WilliamAF
- Date:
- 2019-09-28
- Revision:
- 1:ca2d24ec97ba
- Parent:
- 0:fa546fb96b80
File content as of revision 1:ca2d24ec97ba:
#include "LoraComms.h" #include "MTSLog.h" #include "MTSText.h" #define CHANNEL_PLAN lora::ChannelPlan_AU915() #define REQUEST_ACK_AFTER 1 // Only request ACK from gateway every x packets #define DISCONNECT_AFTER_LOST 5 // Disconnect from network after x failed acks #define JOIN_RETRIES 5 #define JOIN_DELAY 1 // Seconds to wait for ack when joining network static std::string network_name = "UQ_St_Lucia"; static std::string network_passphrase = "xxxxx"; static uint8_t frequency_sub_band = 7; static lora::NetworkType network_type = lora::PRIVATE_MTS; static bool adr = false; mDot* initializeLora() { mDot* dot = mDot::getInstance(new CHANNEL_PLAN); if (!dot->getStandbyFlag()) { // start from a well-known state logInfo("defaulting Dot configuration"); dot->resetConfig(); dot->resetNetworkSession(); // make sure library logging is turned on dot->setLogLevel(mts::MTSLog::INFO_LEVEL); // update configuration if necessary if (dot->getJoinMode() != mDot::OTA) { logInfo("changing network join mode to OTA"); if (dot->setJoinMode(mDot::OTA) != mDot::MDOT_OK) { logError("failed to set network join mode to OTA"); } } update_ota_config_name_phrase(dot, network_name, network_passphrase, frequency_sub_band, network_type, JOIN_RETRIES); // configure network link checks // network link checks are a good alternative to requiring the gateway // to ACK every packet and should allow a single gateway to handle more // Dots. update_network_link_check_config(dot, DISCONNECT_AFTER_LOST, REQUEST_ACK_AFTER); // enable or disable Adaptive Data Rate dot->setAdr(adr); // Configure the join delay dot->setJoinDelay(JOIN_DELAY); // save changes to configuration logInfo("saving configuration"); if (!dot->saveConfig()) { logError("failed to save configuration"); } // display configuration display_config(dot); } else { // restore the saved session if the dot woke from deepsleep mode // useful to use with deepsleep because session info is otherwise lost // when the dot enters deepsleep logInfo("restoring network session from NVM"); dot->restoreNetworkSession(); } return dot; } // Copyright multitech void display_config(mDot* dot) { // display configuration and library version information logInfo("====================="); logInfo("general configuration"); logInfo("====================="); logInfo("version ------------------ %s", dot->getId().c_str()); logInfo("device ID/EUI ------------ %s", mts::Text::bin2hexString(dot->getDeviceId()).c_str()); logInfo("default channel plan ----- %s", mDot::FrequencyBandStr(dot->getDefaultFrequencyBand()).c_str()); logInfo("current channel plan ----- %s", mDot::FrequencyBandStr(dot->getFrequencyBand()).c_str()); if (lora::ChannelPlan::IsPlanFixed(dot->getFrequencyBand())) { logInfo("frequency sub band ------- %u", dot->getFrequencySubBand()); } std::string network_mode_str("Undefined"); uint8_t network_mode = dot->getPublicNetwork(); if (network_mode == lora::PRIVATE_MTS) network_mode_str = "Private MTS"; else if (network_mode == lora::PUBLIC_LORAWAN) network_mode_str = "Public LoRaWAN"; else if (network_mode == lora::PRIVATE_LORAWAN) network_mode_str = "Private LoRaWAN"; logInfo("public network ----------- %s", network_mode_str.c_str()); logInfo("========================="); logInfo("credentials configuration"); logInfo("========================="); logInfo("device class ------------- %s", dot->getClass().c_str()); logInfo("network join mode -------- %s", mDot::JoinModeStr(dot->getJoinMode()).c_str()); if (dot->getJoinMode() == mDot::MANUAL || dot->getJoinMode() == mDot::PEER_TO_PEER) { logInfo("network address ---------- %s", mts::Text::bin2hexString(dot->getNetworkAddress()).c_str()); logInfo("network session key------- %s", mts::Text::bin2hexString(dot->getNetworkSessionKey()).c_str()); logInfo("data session key---------- %s", mts::Text::bin2hexString(dot->getDataSessionKey()).c_str()); } else { logInfo("network name ------------- %s", dot->getNetworkName().c_str()); logInfo("network phrase ----------- %s", dot->getNetworkPassphrase().c_str()); logInfo("network EUI -------------- %s", mts::Text::bin2hexString(dot->getNetworkId()).c_str()); logInfo("network KEY -------------- %s", mts::Text::bin2hexString(dot->getNetworkKey()).c_str()); } logInfo("========================"); logInfo("communication parameters"); logInfo("========================"); if (dot->getJoinMode() == mDot::PEER_TO_PEER) { logInfo("TX frequency ------------- %lu", dot->getTxFrequency()); } else { logInfo("acks --------------------- %s, %u attempts", dot->getAck() > 0 ? "on" : "off", dot->getAck()); } logInfo("TX datarate -------------- %s", mDot::DataRateStr(dot->getTxDataRate()).c_str()); logInfo("TX power ----------------- %lu dBm", dot->getTxPower()); logInfo("antenna gain ------------- %u dBm", dot->getAntennaGain()); logInfo("LBT ---------------------- %s", dot->getLbtTimeUs() ? "on" : "off"); if (dot->getLbtTimeUs()) { logInfo("LBT time ----------------- %lu us", dot->getLbtTimeUs()); logInfo("LBT threshold ------------ %d dBm", dot->getLbtThreshold()); } } // Copyright multitech void update_ota_config_name_phrase(mDot* dot, std::string network_name, std::string network_passphrase, uint8_t frequency_sub_band, lora::NetworkType network_type, uint8_t ack) { std::string current_network_name = dot->getNetworkName(); std::string current_network_passphrase = dot->getNetworkPassphrase(); uint8_t current_frequency_sub_band = dot->getFrequencySubBand(); uint8_t current_network_type = dot->getPublicNetwork(); uint8_t current_ack = dot->getAck(); if (current_network_name != network_name) { logInfo("changing network name from \"%s\" to \"%s\"", current_network_name.c_str(), network_name.c_str()); if (dot->setNetworkName(network_name) != mDot::MDOT_OK) { logError("failed to set network name to \"%s\"", network_name.c_str()); } } if (current_network_passphrase != network_passphrase) { logInfo("changing network passphrase from \"%s\" to \"%s\"", current_network_passphrase.c_str(), network_passphrase.c_str()); if (dot->setNetworkPassphrase(network_passphrase) != mDot::MDOT_OK) { logError("failed to set network passphrase to \"%s\"", network_passphrase.c_str()); } } if (lora::ChannelPlan::IsPlanFixed(dot->getFrequencyBand())) { if (current_frequency_sub_band != frequency_sub_band) { logInfo("changing frequency sub band from %u to %u", current_frequency_sub_band, frequency_sub_band); if (dot->setFrequencySubBand(frequency_sub_band) != mDot::MDOT_OK) { logError("failed to set frequency sub band to %u", frequency_sub_band); } } } if (current_network_type != network_type) { if (dot->setPublicNetwork(network_type) != mDot::MDOT_OK) { logError("failed to set network type"); } } if (current_ack != ack) { logInfo("changing acks from %u to %u", current_ack, ack); if (dot->setAck(ack) != mDot::MDOT_OK) { logError("failed to set acks to %u", ack); } } } // Copyright multitech void update_network_link_check_config(mDot* dot, uint8_t link_check_count, uint8_t link_check_threshold) { uint8_t current_link_check_count = dot->getLinkCheckCount(); uint8_t current_link_check_threshold = dot->getLinkCheckThreshold(); if (current_link_check_count != link_check_count) { logInfo("changing link check count from %u to %u", current_link_check_count, link_check_count); if (dot->setLinkCheckCount(link_check_count) != mDot::MDOT_OK) { logError("failed to set link check count to %u", link_check_count); } } if (current_link_check_threshold != link_check_threshold) { logInfo("changing link check threshold from %u to %u", current_link_check_threshold, link_check_threshold); if (dot->setLinkCheckThreshold(link_check_threshold) != mDot::MDOT_OK) { logError("failed to set link check threshold to %u", link_check_threshold); } } } // Copyright multitech void join_network(mDot* dot) { int32_t j_attempts = 0; int32_t ret = mDot::MDOT_ERROR; // attempt to join the network while (ret != mDot::MDOT_OK) { logInfo("attempt %d to join network", ++j_attempts); ret = dot->joinNetwork(); if (ret != mDot::MDOT_OK) { logError("failed to join network %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); // in some frequency bands we need to wait until another channel is available before transmitting again uint32_t delay_s = (dot->getNextTxMs() / 1000) + 1; if (delay_s < 5) { logInfo("waiting %lu s until next free channel", delay_s); wait(delay_s); } else { logInfo("sleeping %lu s until next free channel", delay_s); dot->sleep(delay_s, mDot::RTC_ALARM, false); } } } }