Factory firmware for the MultiTech Dotbox (MTDOT-BOX) and EVB (MTDOT-EVB) products.

Dependencies:   NCP5623B GpsParser ISL29011 libmDot-mbed5 MTS-Serial MMA845x DOGS102 MPL3115A2

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaHandler.cpp Source File

LoRaHandler.cpp

00001 /* Copyright (c) <2016> <MultiTech Systems>, MIT License
00002  *
00003  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
00004  * and associated documentation files (the "Software"), to deal in the Software without restriction, 
00005  * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
00006  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
00007  * furnished to do so, subject to the following conditions:
00008  *
00009  * The above copyright notice and this permission notice shall be included in all copies or 
00010  * substantial portions of the Software.
00011  *
00012  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
00013  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
00014  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
00015  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
00016  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017  */
00018 
00019 #include "LoRaHandler.h"
00020 
00021 #define signal (int32_t)0xA0
00022 
00023 typedef enum {
00024     l_none = 0,
00025     l_link_check,
00026     l_send,
00027     l_join
00028 } InternalLoRa;
00029 
00030 uint8_t cmd = l_none;
00031 std::vector<uint8_t> send_data;
00032 
00033 void l_worker(void const* argument) {
00034     LoRaHandler* l = (LoRaHandler*)argument;
00035     osEvent e;
00036 
00037     int32_t ret;
00038     mDot::link_check lc;
00039     mDot::rssi_stats rs;
00040     mDot::snr_stats ss;
00041 
00042     while (true) {
00043         e = Thread::signal_wait(signal);
00044         if (e.status == osEventSignal) {
00045             l->_status = LoRaHandler::busy;
00046             l->_tick.attach(l, &LoRaHandler::blinker, 0.05);
00047             switch (cmd) {
00048                 case l_link_check:
00049                     l->_mutex.lock();
00050                     lc = l->_dot->networkLinkCheck();
00051                     l->_mutex.unlock();
00052                     if (lc.status) {
00053                         l->_link.up = lc;
00054                         l->_mutex.lock();
00055                         rs = l->_dot->getRssiStats();
00056                         ss = l->_dot->getSnrStats();
00057                         l->_mutex.unlock();
00058                         l->_link.down.rssi = rs.last;
00059                         l->_link.down.snr = ss.last;
00060                         l->_status = LoRaHandler::link_check_success;
00061                     } else {
00062                         l->_status = LoRaHandler::link_check_failure;
00063                     }
00064                     osSignalSet(l->_main, loraSignal);
00065                     l->_tick.detach();
00066                     l->_activity_led = LoRaHandler::green;
00067                     break;
00068 
00069                 case l_send:
00070                     l->_mutex.lock();
00071                     ret = l->_dot->send(send_data);
00072                     l->_mutex.unlock();
00073                     if (ret == mDot::MDOT_OK)
00074                         l->_status = LoRaHandler::send_success;
00075                     else if(ret == mDot::MDOT_MAX_PAYLOAD_EXCEEDED)
00076                         l->_status = LoRaHandler::send_failure_payload;
00077                     else
00078                         l->_status = LoRaHandler::send_failure;
00079                     osSignalSet(l->_main, loraSignal);
00080                     l->_tick.detach();
00081                     l->_activity_led = LoRaHandler::green;
00082                     break;
00083 
00084                 case l_join:
00085                     l->_mutex.lock();
00086                     ret = l->_dot->joinNetworkOnce();
00087                     l->_join_attempts++;
00088                     l->_mutex.unlock();
00089                     if (ret == mDot::MDOT_OK) {
00090                         send_data.clear();
00091                         l->_mutex.lock();
00092                         l->_dot->send(send_data);
00093                         l->_dot->send(send_data);
00094                         while(l->_dot->getDataPending()) {
00095                             l->_dot->send(send_data);
00096                         }
00097                         l->_dot->send(send_data);
00098                         l->_mutex.unlock();
00099                         l->_status = LoRaHandler::join_success;
00100                         osSignalSet(l->_main, loraSignal);
00101                         l->_tick.detach();
00102                         l->_activity_led = LoRaHandler::green;
00103                     } else {
00104                         l->_status = LoRaHandler::join_failure;
00105                         osSignalSet(l->_main, loraSignal);
00106                         l->_tick.detach();
00107                         l->_activity_led = LoRaHandler::red;
00108                     }
00109 
00110                     break;
00111 
00112                 default:
00113                     l->_status = LoRaHandler::none;
00114                     break;
00115             }
00116         }
00117     }
00118 }
00119 
00120 LoRaHandler::LoRaHandler(osThreadId main, mDot* dot)
00121     : _main(main),
00122     _thread(l_worker, (void*)this),
00123     _status(none),
00124     _join_attempts(1),
00125     _activity_led(XBEE_DIO1, PIN_OUTPUT, PullNone, red),
00126     _dot(dot)
00127 {
00128     _link.status = false;
00129     _activity_led = red;
00130 }
00131 
00132 bool LoRaHandler::linkCheck() {
00133     return action(l_link_check);
00134 }
00135 
00136 bool LoRaHandler::send(std::vector<uint8_t> data) {
00137     send_data = data;
00138     return action(l_send);
00139 }
00140 
00141 bool LoRaHandler::join() {
00142     return action(l_join);
00143 }
00144 
00145 bool LoRaHandler::action(uint8_t c) {
00146     if (_status != busy) {
00147         cmd = c;
00148         _thread.signal_set(signal);
00149         _thread.signal_clr(signal);
00150         return true;
00151     }
00152 
00153     return false;
00154 }
00155 
00156 LoRaHandler::LoRaStatus LoRaHandler::getStatus() {
00157     LoRaStatus status;
00158     _mutex.lock();
00159     status = _status;
00160     _mutex.unlock();
00161 
00162     return status;
00163 }
00164 
00165 LoRaHandler::LoRaLink LoRaHandler::getLinkCheckResults() {
00166     LoRaLink link;
00167     _mutex.lock();
00168     link = _link;
00169     _mutex.unlock();
00170 
00171     return link;
00172 }
00173 
00174 uint32_t LoRaHandler::getJoinAttempts() {
00175     uint32_t val;
00176 
00177     _mutex.lock();
00178     val = _join_attempts;
00179     _mutex.unlock();
00180 
00181     return val;
00182 }
00183 
00184 void LoRaHandler::resetJoinAttempts() {
00185     _mutex.lock();
00186     _join_attempts = 1;
00187     _mutex.unlock();
00188 }
00189 
00190 void LoRaHandler::blinker() {
00191     _activity_led = !_activity_led;
00192 }
00193 
00194 void LoRaHandler::resetActivityLed() {
00195     _activity_led = red;
00196 }
00197 
00198