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
LoraComms.cpp
00001 #include "LoraComms.h" 00002 #include "MTSLog.h" 00003 #include "MTSText.h" 00004 00005 #define CHANNEL_PLAN lora::ChannelPlan_AU915() 00006 #define REQUEST_ACK_AFTER 1 // Only request ACK from gateway every x packets 00007 #define DISCONNECT_AFTER_LOST 5 // Disconnect from network after x failed acks 00008 #define JOIN_RETRIES 5 00009 #define JOIN_DELAY 1 // Seconds to wait for ack when joining network 00010 00011 static std::string network_name = "UQ_St_Lucia"; 00012 static std::string network_passphrase = "xxxxx"; 00013 static uint8_t frequency_sub_band = 7; 00014 static lora::NetworkType network_type = lora::PRIVATE_MTS; 00015 static bool adr = false; 00016 00017 mDot* initializeLora() { 00018 00019 mDot* dot = mDot::getInstance(new CHANNEL_PLAN); 00020 00021 if (!dot->getStandbyFlag()) { 00022 // start from a well-known state 00023 logInfo("defaulting Dot configuration"); 00024 dot->resetConfig(); 00025 dot->resetNetworkSession(); 00026 00027 // make sure library logging is turned on 00028 dot->setLogLevel(mts::MTSLog::INFO_LEVEL); 00029 00030 // update configuration if necessary 00031 if (dot->getJoinMode() != mDot::OTA) { 00032 logInfo("changing network join mode to OTA"); 00033 if (dot->setJoinMode(mDot::OTA) != mDot::MDOT_OK) { 00034 logError("failed to set network join mode to OTA"); 00035 } 00036 } 00037 00038 update_ota_config_name_phrase(dot, network_name, network_passphrase, 00039 frequency_sub_band, network_type, JOIN_RETRIES); 00040 00041 // configure network link checks 00042 // network link checks are a good alternative to requiring the gateway 00043 // to ACK every packet and should allow a single gateway to handle more 00044 // Dots. 00045 update_network_link_check_config(dot, DISCONNECT_AFTER_LOST, 00046 REQUEST_ACK_AFTER); 00047 00048 // enable or disable Adaptive Data Rate 00049 dot->setAdr(adr); 00050 00051 // Configure the join delay 00052 dot->setJoinDelay(JOIN_DELAY); 00053 00054 // save changes to configuration 00055 logInfo("saving configuration"); 00056 if (!dot->saveConfig()) { 00057 logError("failed to save configuration"); 00058 } 00059 00060 // display configuration 00061 display_config(dot); 00062 } else { 00063 // restore the saved session if the dot woke from deepsleep mode 00064 // useful to use with deepsleep because session info is otherwise lost 00065 // when the dot enters deepsleep 00066 logInfo("restoring network session from NVM"); 00067 dot->restoreNetworkSession(); 00068 } 00069 00070 return dot; 00071 } 00072 00073 // Copyright multitech 00074 void display_config(mDot* dot) { 00075 // display configuration and library version information 00076 logInfo("====================="); 00077 logInfo("general configuration"); 00078 logInfo("====================="); 00079 logInfo("version ------------------ %s", dot->getId().c_str()); 00080 logInfo("device ID/EUI ------------ %s", mts::Text::bin2hexString(dot->getDeviceId()).c_str()); 00081 logInfo("default channel plan ----- %s", mDot::FrequencyBandStr(dot->getDefaultFrequencyBand()).c_str()); 00082 logInfo("current channel plan ----- %s", mDot::FrequencyBandStr(dot->getFrequencyBand()).c_str()); 00083 if (lora::ChannelPlan::IsPlanFixed(dot->getFrequencyBand())) { 00084 logInfo("frequency sub band ------- %u", dot->getFrequencySubBand()); 00085 } 00086 00087 std::string network_mode_str("Undefined"); 00088 uint8_t network_mode = dot->getPublicNetwork(); 00089 if (network_mode == lora::PRIVATE_MTS) 00090 network_mode_str = "Private MTS"; 00091 else if (network_mode == lora::PUBLIC_LORAWAN) 00092 network_mode_str = "Public LoRaWAN"; 00093 else if (network_mode == lora::PRIVATE_LORAWAN) 00094 network_mode_str = "Private LoRaWAN"; 00095 logInfo("public network ----------- %s", network_mode_str.c_str()); 00096 00097 logInfo("========================="); 00098 logInfo("credentials configuration"); 00099 logInfo("========================="); 00100 logInfo("device class ------------- %s", dot->getClass().c_str()); 00101 logInfo("network join mode -------- %s", mDot::JoinModeStr(dot->getJoinMode()).c_str()); 00102 if (dot->getJoinMode() == mDot::MANUAL || dot->getJoinMode() == mDot::PEER_TO_PEER) { 00103 logInfo("network address ---------- %s", mts::Text::bin2hexString(dot->getNetworkAddress()).c_str()); 00104 logInfo("network session key------- %s", mts::Text::bin2hexString(dot->getNetworkSessionKey()).c_str()); 00105 logInfo("data session key---------- %s", mts::Text::bin2hexString(dot->getDataSessionKey()).c_str()); 00106 } else { 00107 logInfo("network name ------------- %s", dot->getNetworkName().c_str()); 00108 logInfo("network phrase ----------- %s", dot->getNetworkPassphrase().c_str()); 00109 logInfo("network EUI -------------- %s", mts::Text::bin2hexString(dot->getNetworkId()).c_str()); 00110 logInfo("network KEY -------------- %s", mts::Text::bin2hexString(dot->getNetworkKey()).c_str()); 00111 } 00112 logInfo("========================"); 00113 logInfo("communication parameters"); 00114 logInfo("========================"); 00115 if (dot->getJoinMode() == mDot::PEER_TO_PEER) { 00116 logInfo("TX frequency ------------- %lu", dot->getTxFrequency()); 00117 } else { 00118 logInfo("acks --------------------- %s, %u attempts", dot->getAck() > 0 ? "on" : "off", dot->getAck()); 00119 } 00120 logInfo("TX datarate -------------- %s", mDot::DataRateStr(dot->getTxDataRate()).c_str()); 00121 logInfo("TX power ----------------- %lu dBm", dot->getTxPower()); 00122 logInfo("antenna gain ------------- %u dBm", dot->getAntennaGain()); 00123 logInfo("LBT ---------------------- %s", dot->getLbtTimeUs() ? "on" : "off"); 00124 if (dot->getLbtTimeUs()) { 00125 logInfo("LBT time ----------------- %lu us", dot->getLbtTimeUs()); 00126 logInfo("LBT threshold ------------ %d dBm", dot->getLbtThreshold()); 00127 } 00128 } 00129 00130 // Copyright multitech 00131 void update_ota_config_name_phrase(mDot* dot, 00132 std::string network_name, 00133 std::string network_passphrase, 00134 uint8_t frequency_sub_band, 00135 lora::NetworkType network_type, 00136 uint8_t ack) { 00137 std::string current_network_name = dot->getNetworkName(); 00138 std::string current_network_passphrase = dot->getNetworkPassphrase(); 00139 uint8_t current_frequency_sub_band = dot->getFrequencySubBand(); 00140 uint8_t current_network_type = dot->getPublicNetwork(); 00141 uint8_t current_ack = dot->getAck(); 00142 00143 if (current_network_name != network_name) { 00144 logInfo("changing network name from \"%s\" to \"%s\"", 00145 current_network_name.c_str(), network_name.c_str()); 00146 if (dot->setNetworkName(network_name) != mDot::MDOT_OK) { 00147 logError("failed to set network name to \"%s\"", 00148 network_name.c_str()); 00149 } 00150 } 00151 00152 if (current_network_passphrase != network_passphrase) { 00153 logInfo("changing network passphrase from \"%s\" to \"%s\"", current_network_passphrase.c_str(), network_passphrase.c_str()); 00154 if (dot->setNetworkPassphrase(network_passphrase) != mDot::MDOT_OK) { 00155 logError("failed to set network passphrase to \"%s\"", network_passphrase.c_str()); 00156 } 00157 } 00158 00159 if (lora::ChannelPlan::IsPlanFixed(dot->getFrequencyBand())) { 00160 if (current_frequency_sub_band != frequency_sub_band) { 00161 logInfo("changing frequency sub band from %u to %u", 00162 current_frequency_sub_band, frequency_sub_band); 00163 if (dot->setFrequencySubBand(frequency_sub_band) != mDot::MDOT_OK) { 00164 logError("failed to set frequency sub band to %u", 00165 frequency_sub_band); 00166 } 00167 } 00168 } 00169 00170 if (current_network_type != network_type) { 00171 if (dot->setPublicNetwork(network_type) != mDot::MDOT_OK) { 00172 logError("failed to set network type"); 00173 } 00174 } 00175 00176 if (current_ack != ack) { 00177 logInfo("changing acks from %u to %u", current_ack, ack); 00178 if (dot->setAck(ack) != mDot::MDOT_OK) { 00179 logError("failed to set acks to %u", ack); 00180 } 00181 } 00182 } 00183 00184 // Copyright multitech 00185 void update_network_link_check_config(mDot* dot, uint8_t link_check_count, 00186 uint8_t link_check_threshold) { 00187 uint8_t current_link_check_count = dot->getLinkCheckCount(); 00188 uint8_t current_link_check_threshold = dot->getLinkCheckThreshold(); 00189 00190 if (current_link_check_count != link_check_count) { 00191 logInfo("changing link check count from %u to %u", current_link_check_count, 00192 link_check_count); 00193 if (dot->setLinkCheckCount(link_check_count) != mDot::MDOT_OK) { 00194 logError("failed to set link check count to %u", link_check_count); 00195 } 00196 } 00197 00198 if (current_link_check_threshold != link_check_threshold) { 00199 logInfo("changing link check threshold from %u to %u", 00200 current_link_check_threshold, link_check_threshold); 00201 if (dot->setLinkCheckThreshold(link_check_threshold) != mDot::MDOT_OK) { 00202 logError("failed to set link check threshold to %u", 00203 link_check_threshold); 00204 } 00205 } 00206 } 00207 00208 // Copyright multitech 00209 void join_network(mDot* dot) { 00210 int32_t j_attempts = 0; 00211 int32_t ret = mDot::MDOT_ERROR; 00212 00213 // attempt to join the network 00214 while (ret != mDot::MDOT_OK) { 00215 logInfo("attempt %d to join network", ++j_attempts); 00216 ret = dot->joinNetwork(); 00217 if (ret != mDot::MDOT_OK) { 00218 logError("failed to join network %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); 00219 // in some frequency bands we need to wait until another channel is available before transmitting again 00220 uint32_t delay_s = (dot->getNextTxMs() / 1000) + 1; 00221 if (delay_s < 5) { 00222 logInfo("waiting %lu s until next free channel", delay_s); 00223 wait(delay_s); 00224 } else { 00225 logInfo("sleeping %lu s until next free channel", delay_s); 00226 dot->sleep(delay_s, mDot::RTC_ALARM, false); 00227 } 00228 } 00229 } 00230 }
Generated on Sun Jul 17 2022 22:41:36 by 1.7.2