Wenkai Gong / libmDot-mbed5-UNSWDot
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mDotEvent.h Source File

mDotEvent.h

00001 /**********************************************************************
00002 * COPYRIGHT 2015 MULTI-TECH SYSTEMS, INC.
00003 *
00004 * Redistribution and use in source and binary forms, with or without modification,
00005 * are permitted provided that the following conditions are met:
00006 *   1. Redistributions of source code must retain the above copyright notice,
00007 *      this list of conditions and the following disclaimer.
00008 *   2. Redistributions in binary form must reproduce the above copyright notice,
00009 *      this list of conditions and the following disclaimer in the documentation
00010 *      and/or other materials provided with the distribution.
00011 *   3. Neither the name of MULTI-TECH SYSTEMS, INC. nor the names of its contributors
00012 *      may be used to endorse or promote products derived from this software
00013 *      without specific prior written permission.
00014 *
00015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00016 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00017 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00018 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00019 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00020 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00021 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00022 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00023 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00024 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 *
00026 ******************************************************************************
00027 */
00028 
00029 #ifndef MDOT_EVENT_H
00030 #define MDOT_EVENT_H
00031 
00032 #include "mbed.h"
00033 #include "mDot.h"
00034 #include "MacEvents.h"
00035 #include "MTSLog.h"
00036 #include "MTSText.h"
00037 
00038 typedef union {
00039         uint8_t Value;
00040         struct {
00041                 uint8_t :1;
00042                 uint8_t Tx :1;
00043                 uint8_t Rx :1;
00044                 uint8_t RxData :1;
00045                 uint8_t RxSlot :2;
00046                 uint8_t LinkCheck :1;
00047                 uint8_t JoinAccept :1;
00048         } Bits;
00049 } LoRaMacEventFlags;
00050 
00051 typedef enum {
00052     LORAMAC_EVENT_INFO_STATUS_OK = 0,
00053     LORAMAC_EVENT_INFO_STATUS_ERROR,
00054     LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT,
00055     LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT,
00056     LORAMAC_EVENT_INFO_STATUS_RX_ERROR,
00057     LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL,
00058     LORAMAC_EVENT_INFO_STATUS_DOWNLINK_FAIL,
00059     LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL,
00060     LORAMAC_EVENT_INFO_STATUS_MIC_FAIL,
00061 } LoRaMacEventInfoStatus;
00062 
00063 /*!
00064  * LoRaMAC event information
00065  */
00066 typedef struct {
00067         LoRaMacEventInfoStatus Status;
00068         lora::DownlinkControl Ctrl;
00069         bool TxAckReceived;
00070         bool DuplicateRx;
00071         uint8_t TxNbRetries;
00072         uint8_t TxDatarate;
00073         uint8_t RxPort;
00074         uint8_t *RxBuffer;
00075         uint8_t RxBufferSize;
00076         int16_t RxRssi;
00077         uint8_t RxSnr;
00078         uint16_t Energy;
00079         uint8_t DemodMargin;
00080         uint8_t NbGateways;
00081 } LoRaMacEventInfo ;
00082 
00083 class mDotEvent: public lora::MacEvents {
00084     public:
00085 
00086         mDotEvent()
00087         :
00088           LinkCheckAnsReceived(false),
00089           DemodMargin(0),
00090           NbGateways(0),
00091           PacketReceived(false),
00092           RxPort(0),
00093           RxPayloadSize(0),
00094           BeaconLocked(false),
00095           PongReceived(false),
00096           PongRssi(0),
00097           PongSnr(0),
00098           ServerTimeReceived(false),
00099           ServerTimeSeconds(0U),
00100           AckReceived(false),
00101           DuplicateRx(false),
00102           TxNbRetries(0)
00103         {
00104             memset(&_flags, 0, sizeof(LoRaMacEventFlags));
00105             memset(&_info, 0, sizeof(LoRaMacEventInfo ));
00106         }
00107 
00108         virtual ~mDotEvent() {
00109         }
00110 
00111         virtual void MacEvent(LoRaMacEventFlags *flags, LoRaMacEventInfo  *info) {
00112             if (mts::MTSLog::getLogLevel() == mts::MTSLog::TRACE_LEVEL) {
00113                 std::string msg = "OK";
00114                 switch (info->Status) {
00115                     case LORAMAC_EVENT_INFO_STATUS_ERROR:
00116                         msg = "ERROR";
00117                         break;
00118                     case LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT:
00119                         msg = "TX_TIMEOUT";
00120                         break;
00121                     case LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT:
00122                         msg = "RX_TIMEOUT";
00123                         break;
00124                     case LORAMAC_EVENT_INFO_STATUS_RX_ERROR:
00125                         msg = "RX_ERROR";
00126                         break;
00127                     case LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL:
00128                         msg = "JOIN_FAIL";
00129                         break;
00130                     case LORAMAC_EVENT_INFO_STATUS_DOWNLINK_FAIL:
00131                         msg = "DOWNLINK_FAIL";
00132                         break;
00133                     case LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL:
00134                         msg = "ADDRESS_FAIL";
00135                         break;
00136                     case LORAMAC_EVENT_INFO_STATUS_MIC_FAIL:
00137                         msg = "MIC_FAIL";
00138                         break;
00139                     default:
00140                         break;
00141                 }
00142                 logTrace("Event: %s", msg.c_str());
00143 
00144                 logTrace("Flags Tx: %d Rx: %d RxData: %d RxSlot: %d LinkCheck: %d JoinAccept: %d",
00145                          flags->Bits.Tx, flags->Bits.Rx, flags->Bits.RxData, flags->Bits.RxSlot, flags->Bits.LinkCheck, flags->Bits.JoinAccept);
00146                 logTrace("Info: Status: %d ACK: %d Retries: %d TxDR: %d RxPort: %d RxSize: %d RSSI: %d SNR: %d Energy: %d Margin: %d Gateways: %d",
00147                          info->Status, info->TxAckReceived, info->TxNbRetries, info->TxDatarate, info->RxPort, info->RxBufferSize,
00148                          info->RxRssi, info->RxSnr, info->Energy, info->DemodMargin, info->NbGateways);
00149             }
00150         }
00151 
00152         virtual void TxStart() {
00153             logDebug("mDotEvent - TxStart");
00154 
00155         }
00156 
00157         virtual void TxDone(uint8_t dr) {
00158             _timeSinceTx.reset();
00159             _timeSinceTx.start();
00160 
00161             RxPayloadSize = 0;
00162             LinkCheckAnsReceived = false;
00163             PacketReceived = false;
00164             AckReceived = false;
00165             DuplicateRx = false;
00166             PongReceived = false;
00167             TxNbRetries = 0;
00168 
00169             logDebug("mDotEvent - TxDone");
00170             memset(&_flags, 0, sizeof(LoRaMacEventFlags));
00171             memset(&_info, 0, sizeof(LoRaMacEventInfo ));
00172 
00173             _flags.Bits.Tx = 1;
00174             _info.TxDatarate = dr;
00175             _info.Status = LORAMAC_EVENT_INFO_STATUS_OK;
00176             Notify();
00177 
00178         }
00179 
00180         void Notify() {
00181             MacEvent(&_flags, &_info);
00182         }
00183 
00184         virtual void TxTimeout(void) {
00185             logDebug("mDotEvent - TxTimeout");
00186 
00187             _flags.Bits.Tx = 1;
00188             _info.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT;
00189             Notify();
00190         }
00191 
00192         virtual void JoinAccept(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) {
00193             logDebug("mDotEvent - JoinAccept");
00194 
00195             _flags.Bits.Tx = 0;
00196             _flags.Bits.JoinAccept = 1;
00197             _info.Status = LORAMAC_EVENT_INFO_STATUS_OK;
00198             Notify();
00199 
00200         }
00201 
00202         virtual void JoinFailed(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) {
00203             logDebug("mDotEvent - JoinFailed");
00204 
00205             _flags.Bits.Tx = 0;
00206             _flags.Bits.JoinAccept = 1;
00207             _info.Status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL;
00208             Notify();
00209 
00210         }
00211 
00212         virtual void MissedAck(uint8_t retries) {
00213             logDebug("mDotEvent - MissedAck : retries %u", retries);
00214             TxNbRetries = retries;
00215             _info.TxNbRetries = retries;
00216         }
00217 
00218         virtual void PacketRx(uint8_t port, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr, lora::DownlinkControl ctrl, uint8_t slot, uint8_t retries, uint32_t address, bool dupRx) {
00219             logDebug("mDotEvent - PacketRx ADDR: %08x", address);
00220             RxPort = port;
00221             PacketReceived = true;
00222 
00223             memcpy(RxPayload, payload, size);
00224             RxPayloadSize = size;
00225 
00226             if (ctrl.Bits.Ack) {
00227                 AckReceived = true;
00228             }
00229 
00230             DuplicateRx = dupRx;
00231 
00232             if (mts::MTSLog::getLogLevel() == mts::MTSLog::TRACE_LEVEL) {
00233                 std::string packet = mts::Text::bin2hexString(RxPayload, size);
00234                 logTrace("Payload: %s", packet.c_str());
00235             }
00236 
00237             _flags.Bits.Tx = 0;
00238             _flags.Bits.Rx = 1;
00239             _flags.Bits.RxData = size > 0;
00240             _flags.Bits.RxSlot = slot;
00241             _info.RxBuffer = payload;
00242             _info.RxBufferSize = size;
00243             _info.RxPort = port;
00244             _info.RxRssi = rssi;
00245             _info.RxSnr = snr;
00246             _info.TxAckReceived = AckReceived;
00247             _info.DuplicateRx = DuplicateRx;
00248             _info.TxNbRetries = retries;
00249             _info.Status = LORAMAC_EVENT_INFO_STATUS_OK;
00250             Notify();
00251         }
00252         
00253         virtual void PacketRx2(uint8_t port, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr, lora::DownlinkControl ctrl, uint8_t slot, uint8_t retries, uint32_t address, bool dupRx) {
00254             logDebug("mDotEvent - PacketRx ADDR: %08x", address);
00255             RxPort = port;
00256             PacketReceived = true;
00257 
00258             memcpy(RxPayload, payload, size);
00259             RxPayloadSize = size;
00260 
00261             if (ctrl.Bits.Ack) {
00262                 AckReceived = true;
00263             }
00264 
00265             DuplicateRx = dupRx;
00266 
00267             if (mts::MTSLog::getLogLevel() == mts::MTSLog::TRACE_LEVEL) {
00268                 std::string packet = mts::Text::bin2hexString(RxPayload, size);
00269                 int number = (int)strtol(packet.c_str(), NULL, 16);
00270                 logTrace("Payload: %d", number);
00271             }
00272 
00273             _flags.Bits.Tx = 0;
00274             _flags.Bits.Rx = 1;
00275             _flags.Bits.RxData = size > 0;
00276             _flags.Bits.RxSlot = slot;
00277             _info.RxBuffer = payload;
00278             _info.RxBufferSize = size;
00279             _info.RxPort = port;
00280             _info.RxRssi = rssi;
00281             _info.RxSnr = snr;
00282             _info.TxAckReceived = AckReceived;
00283             _info.DuplicateRx = DuplicateRx;
00284             _info.TxNbRetries = retries;
00285             _info.Status = LORAMAC_EVENT_INFO_STATUS_OK;
00286             Notify();
00287         }
00288 
00289         virtual void RxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr, lora::DownlinkControl ctrl, uint8_t slot) {
00290             logDebug("mDotEvent - RxDone");
00291 
00292         }
00293 
00294         virtual void BeaconRx(const lora::BeaconData_t& beacon_data, int16_t rssi, int8_t snr) {
00295             logDebug("mDotEvent - BeaconRx");
00296             BeaconLocked = true;
00297             BeaconData = beacon_data;
00298         }
00299 
00300         virtual void BeaconLost() {
00301             logDebug("mDotEvent - BeaconLost");
00302             BeaconLocked = false;
00303         }
00304 
00305         virtual void Pong(int16_t m_rssi, int8_t m_snr, int16_t s_rssi, int8_t s_snr) {
00306             logDebug("mDotEvent - Pong");
00307             PongReceived = true;
00308             PongRssi = s_rssi;
00309             PongSnr = s_snr;
00310         }
00311 
00312         virtual void ServerTime(uint32_t seconds, uint8_t sub_seconds) {
00313             logDebug("mDotEvent - ServerTime");
00314             ServerTimeReceived = true;
00315 
00316             uint64_t current_server_time_ms = static_cast<uint64_t>(seconds) * 1000 +
00317                 static_cast<uint16_t>(sub_seconds) * 4 + _timeSinceTx.read_ms();
00318 
00319             ServerTimeSeconds = static_cast<uint32_t>(current_server_time_ms / 1000);
00320             ServerTimeMillis = static_cast<uint16_t>(current_server_time_ms % 1000);
00321         }
00322 
00323         virtual void NetworkLinkCheck(int16_t m_rssi, int8_t m_snr, int8_t s_snr, uint8_t s_gateways) {
00324             logDebug("mDotEvent - NetworkLinkCheck");
00325             LinkCheckAnsReceived = true;
00326             DemodMargin = s_snr;
00327             NbGateways = s_gateways;
00328 
00329             _flags.Bits.Tx = 0;
00330             _flags.Bits.LinkCheck = 1;
00331             _info.RxRssi = m_rssi;
00332             _info.RxSnr = m_snr;
00333             _info.DemodMargin = s_snr;
00334             _info.NbGateways = s_gateways;
00335             _info.Status = LORAMAC_EVENT_INFO_STATUS_OK;
00336             Notify();
00337         }
00338 
00339         virtual void RxTimeout(uint8_t slot) {
00340             logDebug("mDotEvent - RxTimeout on Slot %d", slot);
00341 
00342             _flags.Bits.Tx = 0;
00343             _flags.Bits.RxSlot = slot;
00344             _info.Status = LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT;
00345             Notify();
00346 
00347         }
00348 
00349         virtual void RxError(uint8_t slot) {
00350             logDebug("mDotEvent - RxError");
00351 
00352             memset(&_flags, 0, sizeof(LoRaMacEventFlags));
00353             memset(&_info, 0, sizeof(LoRaMacEventInfo ));
00354 
00355             _flags.Bits.RxSlot = slot;
00356             _info.Status = LORAMAC_EVENT_INFO_STATUS_RX_ERROR;
00357             Notify();
00358 
00359         }
00360 
00361         virtual uint8_t MeasureBattery(void) {
00362             return 255;
00363         }
00364 
00365         bool LinkCheckAnsReceived;
00366         uint8_t DemodMargin;
00367         uint8_t NbGateways;
00368 
00369         bool PacketReceived;
00370         uint8_t RxPort;
00371         uint8_t RxPayload[255];
00372         uint8_t RxPayloadSize;
00373 
00374         bool BeaconLocked;
00375         lora::BeaconData_t BeaconData;
00376 
00377         bool PongReceived;
00378         int16_t PongRssi;
00379         int16_t PongSnr;
00380 
00381         bool ServerTimeReceived;
00382         uint32_t ServerTimeSeconds;
00383         uint16_t ServerTimeMillis;
00384 
00385         bool AckReceived;
00386         bool DuplicateRx;
00387         uint8_t TxNbRetries;
00388 
00389         LoRaMacEventFlags& Flags() {
00390             return _flags;
00391         }
00392         LoRaMacEventInfo & Info() {
00393             return _info;
00394         }
00395 
00396     private:
00397 
00398         LoRaMacEventFlags _flags;
00399         LoRaMacEventInfo  _info;
00400 
00401         Timer _timeSinceTx;
00402 
00403 //
00404 //        /*!
00405 //         * MAC layer event callback prototype.
00406 //         *
00407 //         * \param [IN] flags Bit field indicating the MAC events occurred
00408 //         * \param [IN] info  Details about MAC events occurred
00409 //         */
00410 //        virtual void MacEvent(LoRaMacEventFlags *flags, LoRaMacEventInfo *info) {
00411 //            logDebug("mDotEvent");
00412 //
00413 //            if (flags->Bits.Rx) {
00414 //                logDebug("Rx");
00415 //
00416 //                // Event Object must delete RxBuffer
00417 //                delete[] info->RxBuffer;
00418 //            }
00419 //        }
00420 //
00421 
00422 };
00423 
00424 #endif // __MDOT_EVENT_H__