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

Committer:
WilliamAF
Date:
Tue Apr 02 05:55:13 2019 +0000
Revision:
0:fa546fb96b80
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WilliamAF 0:fa546fb96b80 1 #include "LoraComms.h"
WilliamAF 0:fa546fb96b80 2 #include "MTSLog.h"
WilliamAF 0:fa546fb96b80 3 #include "MTSText.h"
WilliamAF 0:fa546fb96b80 4
WilliamAF 0:fa546fb96b80 5 #define CHANNEL_PLAN lora::ChannelPlan_AU915()
WilliamAF 0:fa546fb96b80 6 #define REQUEST_ACK_AFTER 1 // Only request ACK from gateway every x packets
WilliamAF 0:fa546fb96b80 7 #define DISCONNECT_AFTER_LOST 5 // Disconnect from network after x failed acks
WilliamAF 0:fa546fb96b80 8 #define JOIN_RETRIES 5
WilliamAF 0:fa546fb96b80 9 #define JOIN_DELAY 1 // Seconds to wait for ack when joining network
WilliamAF 0:fa546fb96b80 10
WilliamAF 0:fa546fb96b80 11 static std::string network_name = "UQ_St_Lucia";
WilliamAF 0:fa546fb96b80 12 static std::string network_passphrase = "xxxxx";
WilliamAF 0:fa546fb96b80 13 static uint8_t frequency_sub_band = 7;
WilliamAF 0:fa546fb96b80 14 static lora::NetworkType network_type = lora::PRIVATE_MTS;
WilliamAF 0:fa546fb96b80 15 static bool adr = false;
WilliamAF 0:fa546fb96b80 16
WilliamAF 0:fa546fb96b80 17 mDot* initializeLora() {
WilliamAF 0:fa546fb96b80 18
WilliamAF 0:fa546fb96b80 19 mDot* dot = mDot::getInstance(new CHANNEL_PLAN);
WilliamAF 0:fa546fb96b80 20
WilliamAF 0:fa546fb96b80 21 if (!dot->getStandbyFlag()) {
WilliamAF 0:fa546fb96b80 22 // start from a well-known state
WilliamAF 0:fa546fb96b80 23 logInfo("defaulting Dot configuration");
WilliamAF 0:fa546fb96b80 24 dot->resetConfig();
WilliamAF 0:fa546fb96b80 25 dot->resetNetworkSession();
WilliamAF 0:fa546fb96b80 26
WilliamAF 0:fa546fb96b80 27 // make sure library logging is turned on
WilliamAF 0:fa546fb96b80 28 dot->setLogLevel(mts::MTSLog::INFO_LEVEL);
WilliamAF 0:fa546fb96b80 29
WilliamAF 0:fa546fb96b80 30 // update configuration if necessary
WilliamAF 0:fa546fb96b80 31 if (dot->getJoinMode() != mDot::OTA) {
WilliamAF 0:fa546fb96b80 32 logInfo("changing network join mode to OTA");
WilliamAF 0:fa546fb96b80 33 if (dot->setJoinMode(mDot::OTA) != mDot::MDOT_OK) {
WilliamAF 0:fa546fb96b80 34 logError("failed to set network join mode to OTA");
WilliamAF 0:fa546fb96b80 35 }
WilliamAF 0:fa546fb96b80 36 }
WilliamAF 0:fa546fb96b80 37
WilliamAF 0:fa546fb96b80 38 update_ota_config_name_phrase(dot, network_name, network_passphrase,
WilliamAF 0:fa546fb96b80 39 frequency_sub_band, network_type, JOIN_RETRIES);
WilliamAF 0:fa546fb96b80 40
WilliamAF 0:fa546fb96b80 41 // configure network link checks
WilliamAF 0:fa546fb96b80 42 // network link checks are a good alternative to requiring the gateway
WilliamAF 0:fa546fb96b80 43 // to ACK every packet and should allow a single gateway to handle more
WilliamAF 0:fa546fb96b80 44 // Dots.
WilliamAF 0:fa546fb96b80 45 update_network_link_check_config(dot, DISCONNECT_AFTER_LOST,
WilliamAF 0:fa546fb96b80 46 REQUEST_ACK_AFTER);
WilliamAF 0:fa546fb96b80 47
WilliamAF 0:fa546fb96b80 48 // enable or disable Adaptive Data Rate
WilliamAF 0:fa546fb96b80 49 dot->setAdr(adr);
WilliamAF 0:fa546fb96b80 50
WilliamAF 0:fa546fb96b80 51 // Configure the join delay
WilliamAF 0:fa546fb96b80 52 dot->setJoinDelay(JOIN_DELAY);
WilliamAF 0:fa546fb96b80 53
WilliamAF 0:fa546fb96b80 54 // save changes to configuration
WilliamAF 0:fa546fb96b80 55 logInfo("saving configuration");
WilliamAF 0:fa546fb96b80 56 if (!dot->saveConfig()) {
WilliamAF 0:fa546fb96b80 57 logError("failed to save configuration");
WilliamAF 0:fa546fb96b80 58 }
WilliamAF 0:fa546fb96b80 59
WilliamAF 0:fa546fb96b80 60 // display configuration
WilliamAF 0:fa546fb96b80 61 display_config(dot);
WilliamAF 0:fa546fb96b80 62 } else {
WilliamAF 0:fa546fb96b80 63 // restore the saved session if the dot woke from deepsleep mode
WilliamAF 0:fa546fb96b80 64 // useful to use with deepsleep because session info is otherwise lost
WilliamAF 0:fa546fb96b80 65 // when the dot enters deepsleep
WilliamAF 0:fa546fb96b80 66 logInfo("restoring network session from NVM");
WilliamAF 0:fa546fb96b80 67 dot->restoreNetworkSession();
WilliamAF 0:fa546fb96b80 68 }
WilliamAF 0:fa546fb96b80 69
WilliamAF 0:fa546fb96b80 70 return dot;
WilliamAF 0:fa546fb96b80 71 }
WilliamAF 0:fa546fb96b80 72
WilliamAF 0:fa546fb96b80 73 // Copyright multitech
WilliamAF 0:fa546fb96b80 74 void display_config(mDot* dot) {
WilliamAF 0:fa546fb96b80 75 // display configuration and library version information
WilliamAF 0:fa546fb96b80 76 logInfo("=====================");
WilliamAF 0:fa546fb96b80 77 logInfo("general configuration");
WilliamAF 0:fa546fb96b80 78 logInfo("=====================");
WilliamAF 0:fa546fb96b80 79 logInfo("version ------------------ %s", dot->getId().c_str());
WilliamAF 0:fa546fb96b80 80 logInfo("device ID/EUI ------------ %s", mts::Text::bin2hexString(dot->getDeviceId()).c_str());
WilliamAF 0:fa546fb96b80 81 logInfo("default channel plan ----- %s", mDot::FrequencyBandStr(dot->getDefaultFrequencyBand()).c_str());
WilliamAF 0:fa546fb96b80 82 logInfo("current channel plan ----- %s", mDot::FrequencyBandStr(dot->getFrequencyBand()).c_str());
WilliamAF 0:fa546fb96b80 83 if (lora::ChannelPlan::IsPlanFixed(dot->getFrequencyBand())) {
WilliamAF 0:fa546fb96b80 84 logInfo("frequency sub band ------- %u", dot->getFrequencySubBand());
WilliamAF 0:fa546fb96b80 85 }
WilliamAF 0:fa546fb96b80 86
WilliamAF 0:fa546fb96b80 87 std::string network_mode_str("Undefined");
WilliamAF 0:fa546fb96b80 88 uint8_t network_mode = dot->getPublicNetwork();
WilliamAF 0:fa546fb96b80 89 if (network_mode == lora::PRIVATE_MTS)
WilliamAF 0:fa546fb96b80 90 network_mode_str = "Private MTS";
WilliamAF 0:fa546fb96b80 91 else if (network_mode == lora::PUBLIC_LORAWAN)
WilliamAF 0:fa546fb96b80 92 network_mode_str = "Public LoRaWAN";
WilliamAF 0:fa546fb96b80 93 else if (network_mode == lora::PRIVATE_LORAWAN)
WilliamAF 0:fa546fb96b80 94 network_mode_str = "Private LoRaWAN";
WilliamAF 0:fa546fb96b80 95 logInfo("public network ----------- %s", network_mode_str.c_str());
WilliamAF 0:fa546fb96b80 96
WilliamAF 0:fa546fb96b80 97 logInfo("=========================");
WilliamAF 0:fa546fb96b80 98 logInfo("credentials configuration");
WilliamAF 0:fa546fb96b80 99 logInfo("=========================");
WilliamAF 0:fa546fb96b80 100 logInfo("device class ------------- %s", dot->getClass().c_str());
WilliamAF 0:fa546fb96b80 101 logInfo("network join mode -------- %s", mDot::JoinModeStr(dot->getJoinMode()).c_str());
WilliamAF 0:fa546fb96b80 102 if (dot->getJoinMode() == mDot::MANUAL || dot->getJoinMode() == mDot::PEER_TO_PEER) {
WilliamAF 0:fa546fb96b80 103 logInfo("network address ---------- %s", mts::Text::bin2hexString(dot->getNetworkAddress()).c_str());
WilliamAF 0:fa546fb96b80 104 logInfo("network session key------- %s", mts::Text::bin2hexString(dot->getNetworkSessionKey()).c_str());
WilliamAF 0:fa546fb96b80 105 logInfo("data session key---------- %s", mts::Text::bin2hexString(dot->getDataSessionKey()).c_str());
WilliamAF 0:fa546fb96b80 106 } else {
WilliamAF 0:fa546fb96b80 107 logInfo("network name ------------- %s", dot->getNetworkName().c_str());
WilliamAF 0:fa546fb96b80 108 logInfo("network phrase ----------- %s", dot->getNetworkPassphrase().c_str());
WilliamAF 0:fa546fb96b80 109 logInfo("network EUI -------------- %s", mts::Text::bin2hexString(dot->getNetworkId()).c_str());
WilliamAF 0:fa546fb96b80 110 logInfo("network KEY -------------- %s", mts::Text::bin2hexString(dot->getNetworkKey()).c_str());
WilliamAF 0:fa546fb96b80 111 }
WilliamAF 0:fa546fb96b80 112 logInfo("========================");
WilliamAF 0:fa546fb96b80 113 logInfo("communication parameters");
WilliamAF 0:fa546fb96b80 114 logInfo("========================");
WilliamAF 0:fa546fb96b80 115 if (dot->getJoinMode() == mDot::PEER_TO_PEER) {
WilliamAF 0:fa546fb96b80 116 logInfo("TX frequency ------------- %lu", dot->getTxFrequency());
WilliamAF 0:fa546fb96b80 117 } else {
WilliamAF 0:fa546fb96b80 118 logInfo("acks --------------------- %s, %u attempts", dot->getAck() > 0 ? "on" : "off", dot->getAck());
WilliamAF 0:fa546fb96b80 119 }
WilliamAF 0:fa546fb96b80 120 logInfo("TX datarate -------------- %s", mDot::DataRateStr(dot->getTxDataRate()).c_str());
WilliamAF 0:fa546fb96b80 121 logInfo("TX power ----------------- %lu dBm", dot->getTxPower());
WilliamAF 0:fa546fb96b80 122 logInfo("antenna gain ------------- %u dBm", dot->getAntennaGain());
WilliamAF 0:fa546fb96b80 123 logInfo("LBT ---------------------- %s", dot->getLbtTimeUs() ? "on" : "off");
WilliamAF 0:fa546fb96b80 124 if (dot->getLbtTimeUs()) {
WilliamAF 0:fa546fb96b80 125 logInfo("LBT time ----------------- %lu us", dot->getLbtTimeUs());
WilliamAF 0:fa546fb96b80 126 logInfo("LBT threshold ------------ %d dBm", dot->getLbtThreshold());
WilliamAF 0:fa546fb96b80 127 }
WilliamAF 0:fa546fb96b80 128 }
WilliamAF 0:fa546fb96b80 129
WilliamAF 0:fa546fb96b80 130 // Copyright multitech
WilliamAF 0:fa546fb96b80 131 void update_ota_config_name_phrase(mDot* dot,
WilliamAF 0:fa546fb96b80 132 std::string network_name,
WilliamAF 0:fa546fb96b80 133 std::string network_passphrase,
WilliamAF 0:fa546fb96b80 134 uint8_t frequency_sub_band,
WilliamAF 0:fa546fb96b80 135 lora::NetworkType network_type,
WilliamAF 0:fa546fb96b80 136 uint8_t ack) {
WilliamAF 0:fa546fb96b80 137 std::string current_network_name = dot->getNetworkName();
WilliamAF 0:fa546fb96b80 138 std::string current_network_passphrase = dot->getNetworkPassphrase();
WilliamAF 0:fa546fb96b80 139 uint8_t current_frequency_sub_band = dot->getFrequencySubBand();
WilliamAF 0:fa546fb96b80 140 uint8_t current_network_type = dot->getPublicNetwork();
WilliamAF 0:fa546fb96b80 141 uint8_t current_ack = dot->getAck();
WilliamAF 0:fa546fb96b80 142
WilliamAF 0:fa546fb96b80 143 if (current_network_name != network_name) {
WilliamAF 0:fa546fb96b80 144 logInfo("changing network name from \"%s\" to \"%s\"",
WilliamAF 0:fa546fb96b80 145 current_network_name.c_str(), network_name.c_str());
WilliamAF 0:fa546fb96b80 146 if (dot->setNetworkName(network_name) != mDot::MDOT_OK) {
WilliamAF 0:fa546fb96b80 147 logError("failed to set network name to \"%s\"",
WilliamAF 0:fa546fb96b80 148 network_name.c_str());
WilliamAF 0:fa546fb96b80 149 }
WilliamAF 0:fa546fb96b80 150 }
WilliamAF 0:fa546fb96b80 151
WilliamAF 0:fa546fb96b80 152 if (current_network_passphrase != network_passphrase) {
WilliamAF 0:fa546fb96b80 153 logInfo("changing network passphrase from \"%s\" to \"%s\"", current_network_passphrase.c_str(), network_passphrase.c_str());
WilliamAF 0:fa546fb96b80 154 if (dot->setNetworkPassphrase(network_passphrase) != mDot::MDOT_OK) {
WilliamAF 0:fa546fb96b80 155 logError("failed to set network passphrase to \"%s\"", network_passphrase.c_str());
WilliamAF 0:fa546fb96b80 156 }
WilliamAF 0:fa546fb96b80 157 }
WilliamAF 0:fa546fb96b80 158
WilliamAF 0:fa546fb96b80 159 if (lora::ChannelPlan::IsPlanFixed(dot->getFrequencyBand())) {
WilliamAF 0:fa546fb96b80 160 if (current_frequency_sub_band != frequency_sub_band) {
WilliamAF 0:fa546fb96b80 161 logInfo("changing frequency sub band from %u to %u",
WilliamAF 0:fa546fb96b80 162 current_frequency_sub_band, frequency_sub_band);
WilliamAF 0:fa546fb96b80 163 if (dot->setFrequencySubBand(frequency_sub_band) != mDot::MDOT_OK) {
WilliamAF 0:fa546fb96b80 164 logError("failed to set frequency sub band to %u",
WilliamAF 0:fa546fb96b80 165 frequency_sub_band);
WilliamAF 0:fa546fb96b80 166 }
WilliamAF 0:fa546fb96b80 167 }
WilliamAF 0:fa546fb96b80 168 }
WilliamAF 0:fa546fb96b80 169
WilliamAF 0:fa546fb96b80 170 if (current_network_type != network_type) {
WilliamAF 0:fa546fb96b80 171 if (dot->setPublicNetwork(network_type) != mDot::MDOT_OK) {
WilliamAF 0:fa546fb96b80 172 logError("failed to set network type");
WilliamAF 0:fa546fb96b80 173 }
WilliamAF 0:fa546fb96b80 174 }
WilliamAF 0:fa546fb96b80 175
WilliamAF 0:fa546fb96b80 176 if (current_ack != ack) {
WilliamAF 0:fa546fb96b80 177 logInfo("changing acks from %u to %u", current_ack, ack);
WilliamAF 0:fa546fb96b80 178 if (dot->setAck(ack) != mDot::MDOT_OK) {
WilliamAF 0:fa546fb96b80 179 logError("failed to set acks to %u", ack);
WilliamAF 0:fa546fb96b80 180 }
WilliamAF 0:fa546fb96b80 181 }
WilliamAF 0:fa546fb96b80 182 }
WilliamAF 0:fa546fb96b80 183
WilliamAF 0:fa546fb96b80 184 // Copyright multitech
WilliamAF 0:fa546fb96b80 185 void update_network_link_check_config(mDot* dot, uint8_t link_check_count,
WilliamAF 0:fa546fb96b80 186 uint8_t link_check_threshold) {
WilliamAF 0:fa546fb96b80 187 uint8_t current_link_check_count = dot->getLinkCheckCount();
WilliamAF 0:fa546fb96b80 188 uint8_t current_link_check_threshold = dot->getLinkCheckThreshold();
WilliamAF 0:fa546fb96b80 189
WilliamAF 0:fa546fb96b80 190 if (current_link_check_count != link_check_count) {
WilliamAF 0:fa546fb96b80 191 logInfo("changing link check count from %u to %u", current_link_check_count,
WilliamAF 0:fa546fb96b80 192 link_check_count);
WilliamAF 0:fa546fb96b80 193 if (dot->setLinkCheckCount(link_check_count) != mDot::MDOT_OK) {
WilliamAF 0:fa546fb96b80 194 logError("failed to set link check count to %u", link_check_count);
WilliamAF 0:fa546fb96b80 195 }
WilliamAF 0:fa546fb96b80 196 }
WilliamAF 0:fa546fb96b80 197
WilliamAF 0:fa546fb96b80 198 if (current_link_check_threshold != link_check_threshold) {
WilliamAF 0:fa546fb96b80 199 logInfo("changing link check threshold from %u to %u",
WilliamAF 0:fa546fb96b80 200 current_link_check_threshold, link_check_threshold);
WilliamAF 0:fa546fb96b80 201 if (dot->setLinkCheckThreshold(link_check_threshold) != mDot::MDOT_OK) {
WilliamAF 0:fa546fb96b80 202 logError("failed to set link check threshold to %u",
WilliamAF 0:fa546fb96b80 203 link_check_threshold);
WilliamAF 0:fa546fb96b80 204 }
WilliamAF 0:fa546fb96b80 205 }
WilliamAF 0:fa546fb96b80 206 }
WilliamAF 0:fa546fb96b80 207
WilliamAF 0:fa546fb96b80 208 // Copyright multitech
WilliamAF 0:fa546fb96b80 209 void join_network(mDot* dot) {
WilliamAF 0:fa546fb96b80 210 int32_t j_attempts = 0;
WilliamAF 0:fa546fb96b80 211 int32_t ret = mDot::MDOT_ERROR;
WilliamAF 0:fa546fb96b80 212
WilliamAF 0:fa546fb96b80 213 // attempt to join the network
WilliamAF 0:fa546fb96b80 214 while (ret != mDot::MDOT_OK) {
WilliamAF 0:fa546fb96b80 215 logInfo("attempt %d to join network", ++j_attempts);
WilliamAF 0:fa546fb96b80 216 ret = dot->joinNetwork();
WilliamAF 0:fa546fb96b80 217 if (ret != mDot::MDOT_OK) {
WilliamAF 0:fa546fb96b80 218 logError("failed to join network %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
WilliamAF 0:fa546fb96b80 219 // in some frequency bands we need to wait until another channel is available before transmitting again
WilliamAF 0:fa546fb96b80 220 uint32_t delay_s = (dot->getNextTxMs() / 1000) + 1;
WilliamAF 0:fa546fb96b80 221 if (delay_s < 5) {
WilliamAF 0:fa546fb96b80 222 logInfo("waiting %lu s until next free channel", delay_s);
WilliamAF 0:fa546fb96b80 223 wait(delay_s);
WilliamAF 0:fa546fb96b80 224 } else {
WilliamAF 0:fa546fb96b80 225 logInfo("sleeping %lu s until next free channel", delay_s);
WilliamAF 0:fa546fb96b80 226 dot->sleep(delay_s, mDot::RTC_ALARM, false);
WilliamAF 0:fa546fb96b80 227 }
WilliamAF 0:fa546fb96b80 228 }
WilliamAF 0:fa546fb96b80 229 }
WilliamAF 0:fa546fb96b80 230 }