Nathanaël Semhoun / Mbed OS mdot_commonsense

Dependencies:   libmDot-mbed5

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRa.cpp Source File

LoRa.cpp

00001 #include "LoRa.h"
00002 #include "Logging.h"
00003 
00004 #define MAX_SEND_LIST_SIZE 10
00005 #define KEEPALIVE_MESSAGE "0K\n"
00006 
00007 RtosTimer* LoRaReadTimer;
00008 
00009 LoRa::LoRa()
00010     : m_nextSend(0),
00011     m_nextKeepalive(0)
00012 {
00013     m_dot = mDot::getInstance();
00014 }
00015 
00016 LoRa::~LoRa()
00017 {
00018 }
00019 
00020 void LoRa::PeriodicTimer()
00021 {
00022     // On commence par gérer les cas ou on a un vrai message à envoyer
00023     if (m_toSend.size() > 0) {
00024         if (_send(m_toSend.front()) == LoRa::e_srWaitMore) {
00025             return; // <==
00026         }
00027         m_toSend.pop_front();
00028     }
00029     else if (m_currentMessage.length() > 0) {
00030         if (_send(m_currentMessage) == LoRa::e_srWaitMore) {
00031             return; // <==
00032         }
00033         m_currentMessage.clear();
00034     }
00035     else if (m_nextKeepalive > time(NULL)) {
00036         if (_send(KEEPALIVE_MESSAGE) == LoRa::e_srWaitMore) {
00037             return; // <==
00038         }
00039     }
00040     else {
00041         return; // <==
00042     }
00043     
00044     std::string data = _receive();
00045     if (data.size() > 0) {
00046         m_readed.push_back(data);
00047     }
00048 }
00049 
00050 bool LoRa::init(LoRaConfig_t p_loraConfig)
00051 {
00052     m_delayForKeepAlive = (uint32_t)p_loraConfig.loraDelayForKeepAlive;
00053     m_minDelayBetweenMessage = (uint32_t)p_loraConfig.loraMinDelayBetweenMessage;
00054     
00055     m_dot->resetConfig();
00056     m_dot->resetNetworkSession();
00057        
00058     m_errorCode = mDot::MDOT_OK;
00059     std::vector<uint8_t> temp;
00060     
00061     LOG_DEBUG("Setting frequency sub band to '%d'...", p_loraConfig.subBand);
00062     if ((m_errorCode = m_dot->setFrequencySubBand(p_loraConfig.subBand)) != mDot::MDOT_OK) {
00063         LOG_ERROR("(%d): %s", m_errorCode, getError().c_str());
00064         return false;
00065     }
00066     
00067     LOG_DEBUG("Setting network name to '%s'", p_loraConfig.networkName.c_str());
00068     if ((m_errorCode = m_dot->setNetworkName(p_loraConfig.networkName)) != mDot::MDOT_OK) {
00069         LOG_ERROR("(%d): %s", m_errorCode, getError().c_str());
00070         return false;
00071     }
00072     
00073     LOG_DEBUG("Setting network passphrase to '%s'", p_loraConfig.networkPassphrase.c_str());
00074     if ((m_errorCode = m_dot->setNetworkPassphrase(p_loraConfig.networkPassphrase)) != mDot::MDOT_OK) {
00075         LOG_ERROR("(%d): %s", m_errorCode, getError().c_str());
00076         return false;
00077     }
00078     
00079     LOG_DEBUG("Setting TX spreading factor");
00080     if ((m_errorCode = m_dot->setTxDataRate(p_loraConfig.spreadingFactor)) != mDot::MDOT_OK) {
00081          LOG_ERROR("(%d): %s", m_errorCode, getError().c_str());
00082          return false;
00083     }
00084     
00085     // request receive confirmation of packets from the gateway
00086     LOG_DEBUG("Disabling ACKs");
00087     if ((m_errorCode = m_dot->setAck(0)) != mDot::MDOT_OK) {
00088          LOG_ERROR("(%d): %s", m_errorCode, getError().c_str());
00089          return false;
00090     }
00091     
00092     LOG_DEBUG("Saving config");
00093     if (!m_dot->saveConfig()) {
00094         LOG_ERROR("Failed to save configuration");
00095     }
00096 
00097     LOG_DEBUG("LoRa initialized");
00098     return true;
00099 }
00100 
00101 bool LoRa::connect()
00102 {
00103     m_dot->resetNetworkSession();
00104     LOG_DEBUG("Joining network");
00105     while ((m_errorCode = m_dot->joinNetwork()) != mDot::MDOT_OK) {
00106         m_dot->resetNetworkSession();
00107         LOG_ERROR("(%d): %s", m_errorCode, getError().c_str());
00108         osDelay(m_dot->getNextTxMs());
00109     }
00110     LOG_DEBUG("Network Joined!\r\n");
00111     return true;
00112 }
00113 
00114 std::string LoRa::getVersion()
00115 {
00116     return m_dot->getId();
00117 }
00118 
00119 LoRa::SendResult LoRa::_send(const std::string text)
00120 {
00121     time_t now = time(NULL);
00122     
00123     if (m_nextSend > now) {
00124         return e_srWaitMore; // <==
00125     }
00126     
00127     uint32_t timeTillSend = m_dot->getNextTxMs();
00128     if (timeTillSend != 0) {
00129         LOG_DEBUG("waiting %lu ms to send\r\n", timeTillSend);
00130         m_nextSend = time(NULL) + (uint16_t)(timeTillSend / 1000);
00131         return e_srWaitMore;
00132     }
00133 
00134     m_errorCode = mDot::MDOT_OK;
00135      
00136     std::string data_str = text;
00137     LOG_DEBUG("Sending data...  %s", data_str.c_str());
00138     std::vector<uint8_t> data;
00139     for (std::string::iterator it = data_str.begin(); it != data_str.end(); it++)
00140         data.push_back((uint8_t) *it);
00141 
00142     if ((m_errorCode = m_dot->send(data)) != mDot::MDOT_OK)
00143     {
00144         LOG_ERROR("(%d): %s", m_errorCode, getError().c_str());
00145         return e_srError;
00146     }
00147     LOG_DEBUG("Sended data...");
00148     
00149     uint16_t secTillSend =  (uint16_t)(m_dot->getNextTxMs() / 1000);
00150     m_nextSend = time(NULL) + std::max(m_minDelayBetweenMessage, secTillSend);
00151     m_nextKeepalive = time(NULL) + std::max(m_delayForKeepAlive, secTillSend);
00152     
00153     return e_srOK;
00154 }
00155 
00156 void LoRa::send(const std::string text)
00157 {
00158     if (text.length() > LORA_PACKET_MAX_SIZE) {
00159         return; // Message trop gros on ne fait rien
00160     }
00161     
00162     if ((text.length() + m_currentMessage.length()) <= LORA_PACKET_MAX_SIZE) {
00163         m_currentMessage = m_currentMessage + text;
00164         return;
00165     }
00166     
00167     if (m_toSend.size() >= MAX_SEND_LIST_SIZE) {
00168         return;
00169     }
00170     m_toSend.push_back(m_currentMessage);
00171     m_currentMessage = text;
00172 }
00173 
00174 std::string LoRa::_receive()
00175 {
00176     LOG_DEBUG("Receiving packet...  ");
00177     std::vector<uint8_t> data;
00178  
00179     if (m_dot->recv(data) == mDot::MDOT_OK) {
00180         if (data.size() > 0) {
00181             std::string res = std::string((const char*) &data[0], data.size());
00182             LOG_DEBUG("Received data...  %s", res.c_str());
00183             return res;
00184         }
00185     }
00186     return "";
00187 }
00188  
00189 std::string LoRa::receive()
00190 {
00191     if (m_readed.size() > 0) {
00192         std::string res = m_readed.front();
00193         m_readed.pop_front();
00194         return res;
00195     }
00196     return "";
00197 }
00198  
00199 std::string LoRa::getError()
00200 {   
00201     return mDot::getReturnCodeString(m_errorCode) + " - " + m_dot->getLastError();
00202 }