fota lib for mdot

Dependents:   UQ_LoraWAN

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Lora.h Source File

Lora.h

00001 /**   __  ___     ____  _    ______        __     ____         __                  ____
00002  *   /  |/  /_ __/ / /_(_)__/_  __/__ ____/ /    / __/_ _____ / /____ __ _  ___   /  _/__  ____
00003  *  / /|_/ / // / / __/ /___// / / -_) __/ _ \  _\ \/ // (_-</ __/ -_)  ' \(_-<  _/ // _ \/ __/  __
00004  * /_/  /_/\_,_/_/\__/_/    /_/  \__/\__/_//_/ /___/\_, /___/\__/\__/_/_/_/___/ /___/_//_/\__/  /_/
00005  * Copyright (C) 2015 by Multi-Tech Systems        /___/
00006  *
00007  *
00008  * @author Jason Reiss
00009  * @date   10-31-2015
00010  * @brief  lora namespace defines global settings, structures and enums for the lora library
00011  *
00012  * @details
00013  *
00014  *
00015  *
00016  */
00017 
00018 #ifndef __LORA_H__
00019 #define __LORA_H__
00020 
00021 #include "mbed.h"
00022 #include <assert.h>
00023 #include "MTSLog.h"
00024 //#include <cstring>
00025 #include <inttypes.h>
00026 
00027 namespace lora {
00028 
00029     /**
00030      * Frequency bandwidth of a Datarate, higher bandwidth gives higher datarate
00031      */
00032     enum Bandwidth {
00033         BW_125,
00034         BW_250,
00035         BW_500,
00036         BW_FSK = 50
00037     };
00038 
00039     /**
00040      * Spreading factor of a Datarate, lower spreading factor gives higher datarate
00041      */
00042     enum SpreadingFactors {
00043         SF_6 = 6,
00044         SF_7,
00045         SF_8,
00046         SF_9,
00047         SF_10,
00048         SF_11,
00049         SF_12,
00050         SF_FSK,
00051         SF_INVALID
00052     };
00053 
00054     /**
00055      * Datarates for use with ChannelPlan
00056      */
00057     enum Datarates {
00058         DR_0 = 0,
00059         DR_1,
00060         DR_2,
00061         DR_3,
00062         DR_4,
00063         DR_5,
00064         DR_6,
00065         DR_7,
00066         DR_8,
00067         DR_9,
00068         DR_10,
00069         DR_11,
00070         DR_12,
00071         DR_13,
00072         DR_14,
00073         DR_15
00074     };
00075 
00076     const uint8_t MIN_DATARATE = (uint8_t) DR_0;             //!< Minimum datarate
00077 
00078 
00079     const uint8_t MAX_PHY_PACKET_SIZE = 255;                    //!< Maximum size for a packet
00080     const uint8_t MAX_APPS = 8;                                 //!< Maximum number of apps sessions to save
00081     const uint8_t MAX_MULTICAST_SESSIONS = 8;                   //!< Maximum number of multicast sessions to save
00082     const uint8_t EUI_SIZE = 8;                                 //!< Number of bytes in an EUI
00083     const uint8_t KEY_SIZE = 16;                                //!< Number of bytes in an AES key
00084 
00085     const uint8_t DEFAULT_NUM_CHANNELS = 16;                    //!< Default number of channels in a plan
00086     const uint8_t DEFAULT_RX1_DR_OFFSET = 0;                    //!< Default datarate offset for first rx window
00087     const uint8_t DEFAULT_RX2_DATARATE = 0;                     //!< Default datarate for second rx window
00088     const uint8_t DEFAULT_TX_POWER = 14;                        //!< Default transmit power
00089     const uint8_t DEFAULT_CODE_RATE = 1;                        //!< Default coding rate 1:4/5, 2:4/6, 3:4/7, 4:4/8
00090     const uint8_t DEFAULT_PREAMBLE_LEN = 8;                     //!< Default preamble length
00091 
00092     const int32_t MAX_FCNT_GAP = 16384;                         //!< Maximum allowed gap in sequence numbers before roll-over
00093 
00094     const uint16_t PRIVATE_JOIN_DELAY = 1000;                   //!< Default join delay used for private network
00095     const uint16_t PUBLIC_JOIN_DELAY = 5000;                    //!< Default join delay used for public network
00096     const uint16_t DEFAULT_JOIN_DELAY = PRIVATE_JOIN_DELAY;     //!< Default join delay1
00097     const uint16_t DEFAULT_RX_DELAY = 1000;                     //!< Default delay for first receive window
00098     const uint16_t DEFAULT_RX_TIMEOUT = 3000;                   //!< Default timeout for receive windows
00099 
00100     const uint8_t HI_DR_SYMBOL_TIMEOUT = 12;                    //!< Symbol timeout for receive at datarate with SF < 11
00101     const uint8_t LO_DR_SYMBOL_TIMEOUT = 8;                     //!< Symbol timeout for receive at datarate with SF > 10
00102 
00103     const uint16_t RX2_DELAY_OFFSET = 1000;                     //!< Delay between first and second window
00104     const uint16_t RXC_OFFSET = 50;                             //!< Time between end of RXC after TX and RX1
00105 
00106     const uint8_t US915_125K_NUM_CHANS = 64;                    //!< Number of 125k channels in US915 channel plan
00107     const uint8_t US915_500K_NUM_CHANS = 8;                     //!< Number of 500k channels in US915 channel plan
00108 
00109     const uint32_t US915_125K_FREQ_BASE = 902300000;            //!< Frequency base for 125k US915 uplink channels
00110     const uint32_t US915_125K_FREQ_STEP = 200000;               //!< Frequency step for 125k US915 uplink channels
00111 
00112     const uint32_t US915_500K_FREQ_BASE = 903000000;            //!< Frequency base for 500k US915 uplink channels
00113     const uint32_t US915_500K_FREQ_STEP = 1600000;              //!< Frequency step for 500k US915 uplink channels
00114 
00115     const uint32_t US915_500K_DBASE = 923300000;                //!< Frequency base for 500k US915 downlink channels
00116     const uint32_t US915_500K_DSTEP = 600000;                   //!< Frequency step for 500k US915 downlink channels
00117 
00118     const uint32_t US915_FREQ_MIN = 902000000;
00119     const uint32_t US915_FREQ_MAX = 928000000;
00120 
00121     const uint8_t US915_MIN_DATARATE = (uint8_t) DR_0;       //!< Minimum transmit datarate for US915
00122     const uint8_t US915_MAX_DATARATE = (uint8_t) DR_4;       //!< Maximum transmit datarate for US915
00123 
00124     const uint8_t US915_MIN_DATARATE_OFFSET = (uint8_t) 0;       //!< Minimum transmit datarate for US915
00125     const uint8_t US915_MAX_DATARATE_OFFSET = (uint8_t) 3;       //!< Maximum transmit datarate for US915
00126 
00127     const uint8_t AU915_125K_NUM_CHANS = 64;                    //!< Number of 125k channels in AU915 channel plan
00128     const uint8_t AU915_500K_NUM_CHANS = 8;                     //!< Number of 500k channels in AU915 channel plan
00129 
00130     const uint32_t AU915_125K_FREQ_BASE = 915200000;            //!< Frequency base for 125k AU915 uplink channels
00131     const uint32_t AU915_125K_FREQ_STEP = 200000;               //!< Frequency step for 125k AU915 uplink channels
00132 
00133     const uint32_t AU915_500K_FREQ_BASE = 915900000;            //!< Frequency base for 500k AU915 uplink channels
00134     const uint32_t AU915_500K_FREQ_STEP = 1600000;              //!< Frequency step for 500k AU915 uplink channels
00135 
00136     const uint32_t AU915_500K_DBASE = 923300000;                //!< Frequency base for 500k AU915 downlink channels
00137     const uint32_t AU915_500K_DSTEP = 600000;                   //!< Frequency step for 500k AU915 downlink channels
00138 
00139     const uint32_t AU915_FREQ_MIN = 915000000;
00140     const uint32_t AU915_FREQ_MAX = 928000000;
00141 
00142     const uint8_t AU915_MIN_DATARATE = (uint8_t) DR_0;       //!< Minimum transmit datarate for AU915
00143     const uint8_t AU915_MAX_DATARATE = (uint8_t) DR_6;       //!< Maximum transmit datarate for AU915
00144 
00145     const uint8_t AU915_MIN_DATARATE_OFFSET = (uint8_t) 0;       //!< Minimum transmit datarate for AU915
00146     const uint8_t AU915_MAX_DATARATE_OFFSET = (uint8_t) 5;       //!< Maximum transmit datarate for AU915
00147 
00148     const uint8_t EU868_125K_NUM_CHANS = 16;                    //!< Number of 125k channels in EU868 channel plan
00149     const uint8_t EU868_DEFAULT_NUM_CHANS = 3;                  //!< Number of default channels in EU868 channel plan
00150     const uint32_t EU868_125K_FREQ_BASE = 868100000;            //!< Frequency base for 125k EU868 uplink channels
00151     const uint32_t EU868_125K_FREQ_STEP = 200000;               //!< Frequency step for 125k EU868 uplink channels
00152     const uint32_t EU868_RX2_FREQ = 869525000;                  //!< Frequency default for second rx window in EU868
00153 
00154     const uint8_t EU868_TX_POWER_MAX = 14;                      //!< Max power for EU868 channel plan
00155 
00156     const uint8_t KR920_125K_NUM_CHANS = 16;                    //!< Number of 125k channels in KR920 channel plan
00157     const uint8_t KR920_DEFAULT_NUM_CHANS = 3;                  //!< Number of default channels in KR920 channel plan
00158     const uint32_t KR920_125K_FREQ_BASE = 868100000;            //!< Frequency base for 125k KR920 uplink channels
00159     const uint32_t KR920_125K_FREQ_STEP = 200000;               //!< Frequency step for 125k KR920 uplink channels
00160     const uint32_t KR920_RX2_FREQ = 869525000;                  //!< Frequency default for second rx window in KR920
00161 
00162     const uint8_t KR920_TX_POWER_MAX = 14;                      //!< Max power for KR920 channel plan
00163 
00164     const uint8_t AS923_125K_NUM_CHANS = 16;                    //!< Number of 125k channels in AS923 channel plan
00165     const uint8_t AS923_DEFAULT_NUM_CHANS = 2;                  //!< Number of default channels in AS923 channel plan
00166     const uint32_t AS923_125K_FREQ_BASE = 868100000;            //!< Frequency base for 125k AS923 uplink channels
00167     const uint32_t AS923_125K_FREQ_STEP = 200000;               //!< Frequency step for 125k AS923 uplink channels
00168     const uint32_t AS923_RX2_FREQ = 869525000;                  //!< Frequency default for second rx window in AS923
00169 
00170     const uint8_t AS923_TX_POWER_MAX = 14;                      //!< Max power for AS923 channel plan
00171 
00172     const uint8_t IN865_125K_NUM_CHANS = 16;                    //!< Number of 125k channels in IN865 channel plan
00173     const uint8_t IN865_DEFAULT_NUM_CHANS = 3;                  //!< Number of default channels in IN865 channel plan
00174     const uint32_t IN865_125K_DEF_FREQ_1 = 865062500;
00175     const uint32_t IN865_125K_DEF_FREQ_2 = 865402500;
00176     const uint32_t IN865_125K_DEF_FREQ_3 = 865985000;
00177     const uint32_t IN865_RX2_FREQ = 866550000;                  //!< Frequency default for second rx window in IN865
00178 
00179     const uint8_t IN865_TX_POWER_MAX = 30;                      //!< Max power for IN865 channel plan
00180 
00181     // 0.1% duty cycle 863-868
00182     // Limiting to 865-868 allows for 1% duty cycle
00183     const uint32_t EU868_MILLI_FREQ_MIN = 865000000;
00184     const uint32_t EU868_MILLI_FREQ_MAX = 868000000;
00185 
00186     const uint32_t EU868_MILLI_1_FREQ_MIN = 868700000;
00187     const uint32_t EU868_MILLI_1_FREQ_MAX = 869200000;
00188 
00189     // 1% duty cycle
00190     const uint32_t EU868_CENTI_FREQ_MIN = 868000000;
00191     const uint32_t EU868_CENTI_FREQ_MAX = 868600000;
00192 
00193     // 10% duty cycle
00194     const uint32_t EU868_DECI_FREQ_MIN = 869400000;
00195     const uint32_t EU868_DECI_FREQ_MAX = 869650000;
00196 
00197     // Below 7dBm there is no duty cycle for these frequencies
00198     // Up to 14dBm there is 1% duty cycle
00199     const uint32_t EU868_VAR_FREQ_MIN = 869700000;
00200     const uint32_t EU868_VAR_FREQ_MAX = 870000000;
00201 
00202     const uint32_t EU868_FREQ_MIN = 863000000;
00203     const uint32_t EU868_FREQ_MAX = 870000000;
00204 
00205     const uint8_t EU868_MIN_DATARATE = (uint8_t) DR_0;       //!< Minimum transmit datarate for EU868
00206     const uint8_t EU868_MAX_DATARATE = (uint8_t) DR_7;       //!< Maximum transmit datarate for EU868
00207 
00208     const uint8_t EU868_MIN_DATARATE_OFFSET = (uint8_t) 0;       //!< Minimum transmit datarate for US915
00209     const uint8_t EU868_MAX_DATARATE_OFFSET = (uint8_t) 5;       //!< Maximum transmit datarate for US915
00210 
00211     const int16_t DEFAULT_FREE_CHAN_RSSI_THRESHOLD = -90;       //!< Threshold for channel activity detection (CAD) dBm
00212 
00213     const uint8_t CHAN_MASK_SIZE = 16;                          //!< Number of bits in a channel mask
00214     const uint8_t COMMANDS_BUFFER_SIZE = 15;                    //!< Size of Mac Command buffer
00215 
00216     const uint8_t PKT_HEADER = 0;                               //!< Index to packet mHdr field
00217     const uint8_t PKT_ADDRESS = 1;                              //!< Index to first byte of packet address field
00218     const uint8_t PKT_FRAME_CONTROL = PKT_ADDRESS + 4;          //!< Index to packet fCtrl field @see UplinkControl
00219     const uint8_t PKT_FRAME_COUNTER = PKT_FRAME_CONTROL + 1;    //!< Index to packet frame counter field
00220     const uint8_t PKT_OPTIONS_START = PKT_FRAME_COUNTER + 2;    //!< Index to start of optional mac commands
00221 
00222     const uint8_t PKT_JOIN_APP_NONCE = 1;                       //!< Index to application nonce in Join Accept message
00223     const uint8_t PKT_JOIN_NETWORK_ID = 4;                      //!< Index to network id in Join Accept message
00224     const uint8_t PKT_JOIN_NETWORK_ADDRESS = 7;                 //!< Index to network address in Join Accept message
00225     const uint8_t PKT_JOIN_DL_SETTINGS = 11;                    //!< Index to downlink settings in Join Accept message
00226     const uint8_t PKT_JOIN_RX_DELAY = 12;                       //!< Index to rx delay in Join Accept message
00227 
00228     const uint8_t ADR_ACK_LIMIT = 64;                           //!< Number of packets without ADR ACK Request
00229     const uint8_t ADR_ACK_DELAY = 32;                           //!< Number of packets to expect ADR ACK Response within
00230 
00231     const uint16_t ACK_TIMEOUT = 2000;                          //!< Base millisecond timeout to resend after missed ACK
00232     const uint16_t ACK_TIMEOUT_RND = 1000;                      //!< Random millisecond adjustment to resend after missed ACK
00233 
00234     const uint8_t FRAME_OVERHEAD = 13;                          //!< Bytes of network info overhead in a frame
00235 
00236     const uint16_t MAX_OFF_AIR_WAIT = 5000U;                    //!< Max time in ms to block for a duty cycle restriction to expire before erroring out
00237     /**
00238      * Settings for type of network
00239      *
00240      * PRIVATE_MTS - Sync Word 0x12, US/AU Downlink frequencies per Frequency Sub Band
00241      * PUBLIC_LORAWAN - Sync Word 0x34
00242      * PRIVATE_LORAWAN - Sync Word 0x12
00243      * PEER_TO_PEER - Sync Word 0x56 used for Dot to Dot communication
00244      *
00245      * Join Delay window settings are independent of Network Type setting
00246      */
00247     enum NetworkType {
00248         PRIVATE_MTS = 0,
00249         PUBLIC_LORAWAN = 1,
00250         PRIVATE_LORAWAN = 2,
00251         PEER_TO_PEER = 4
00252     };
00253 
00254     /**
00255      * Enum for on/off settings
00256      */
00257     enum Enabled {
00258         OFF = 0,
00259         ON = 1
00260     };
00261 
00262     /**
00263      * Return status of mac functions
00264      */
00265     enum MacStatus {
00266         LORA_OK = 0,
00267         LORA_ERROR = 1,
00268         LORA_JOIN_ERROR = 2,
00269         LORA_SEND_ERROR = 3,
00270         LORA_MIC_ERROR = 4,
00271         LORA_ADDRESS_ERROR = 5,
00272         LORA_NO_CHANS_ENABLED = 6,
00273         LORA_COMMAND_BUFFER_FULL = 7,
00274         LORA_UNKNOWN_MAC_COMMAND = 8,
00275         LORA_ADR_OFF = 9,
00276         LORA_BUSY = 10,
00277         LORA_LINK_BUSY = 11,
00278         LORA_RADIO_BUSY = 12,
00279         LORA_BUFFER_FULL = 13,
00280         LORA_JOIN_BACKOFF = 14,
00281         LORA_NO_FREE_CHAN = 15,
00282         LORA_AGGREGATED_DUTY_CYCLE = 16,
00283         LORA_MAC_COMMAND_ERROR = 17,
00284         LORA_MAX_PAYLOAD_EXCEEDED = 18,
00285         LORA_LBT_CHANNEL_BUSY = 19
00286     };
00287 
00288     /**
00289      * State for Link
00290      */
00291     enum LinkState {
00292         LINK_IDLE = 0,  //!< Link ready to send or receive
00293         LINK_TX,        //!< Link is busy sending
00294         LINK_ACK_TX,    //!< Link is busy resending after missed ACK
00295         LINK_REP_TX,    //!< Link is busy repeating
00296         LINK_RX,        //!< Link has receive window open
00297         LINK_RX1,       //!< Link has first received window open
00298         LINK_RX2,       //!< Link has second received window open
00299         LINK_RXC,       //!< Link has class C received window open
00300         LINK_P2P,       //!< Link is busy sending
00301     };
00302 
00303     /**
00304      * State for MAC
00305      */
00306     enum MacState {
00307         MAC_IDLE,
00308         MAC_RX1,
00309         MAC_RX2,
00310         MAC_RXC,
00311         MAC_TX,
00312         MAC_JOIN
00313     };
00314 
00315     /**
00316      * Operation class for device
00317      */
00318     enum MoteClass {
00319         CLASS_A = 0x00, //!< Device can only receive in windows opened after a transmit
00320         CLASS_B = 0x01, //!< Device can receive in windows sychronized with gateway beacon
00321         CLASS_C = 0x02  //!< Device can receive any time when not transmitting
00322     };
00323 
00324     /**
00325      * Direction of a packet
00326      */
00327     enum Direction {
00328         DIR_UP = 0,     //!< Packet is sent from mote to gateway
00329         DIR_DOWN = 1,   //!< Packet was received from gateway
00330         DIR_PEER = 2    //!< Packet was received from peer
00331     };
00332 
00333 
00334     /**
00335      * Received window used by Link
00336      */
00337     enum ReceiveWindows {
00338         RX_1 = 1,           //!< First receive window
00339         RX_2,               //!< Second receive window
00340         RX_BEACON,          //!< Beacon receive window
00341         RX_SLOT,            //!< Ping Slot receive window
00342         RXC,                //!< Class C continuous window
00343         RX_TEST
00344     };
00345 
00346     /**
00347      * Datarate range for a Channel
00348      */
00349     typedef union {
00350             int8_t Value;
00351             struct {
00352                     int8_t Min :4;
00353                     int8_t Max :4;
00354             } Fields;
00355     } DatarateRange;
00356 
00357     /**
00358      * Datarate used for transmitting and receiving
00359      */
00360     typedef struct Datarate {
00361             uint8_t Index;
00362             uint8_t Bandwidth;
00363             uint8_t Coderate;
00364             uint8_t PreambleLength;
00365             uint8_t SpreadingFactor;
00366             uint8_t Crc;
00367             uint8_t TxIQ;
00368             uint8_t RxIQ;
00369             uint8_t SymbolTimeout();
00370             Datarate();
00371     } Datarate;
00372 
00373     /**
00374      * Channel used for transmitting
00375      */
00376     typedef struct {
00377             uint8_t Index;
00378             uint32_t Frequency;
00379             DatarateRange DrRange;
00380     } Channel;
00381 
00382     /**
00383      * Receive window
00384      */
00385     typedef struct {
00386             uint8_t Index;
00387             uint32_t Frequency;
00388             uint8_t DatarateIndex;
00389     } RxWindow;
00390 
00391     /**
00392      * Duty band for limiting time-on-air for regional regulations
00393      */
00394     typedef struct {
00395             uint8_t Index;
00396             uint32_t FrequencyMin;
00397             uint32_t FrequencyMax;
00398             uint8_t PowerMax;
00399             uint16_t DutyCycle;          //!< Multiplier of time on air, 0:100%, 1:50%, 2:33%, 10:10%, 100:1%, 1000,0.1%
00400             uint32_t TimeOffEnd;         //!< Timestamp when this band will be available
00401     } DutyBand;
00402 
00403     /**
00404      * Device configuration
00405      */
00406     typedef struct {
00407             uint8_t FrequencyBand;      //!< Used to choose ChannelPlan
00408             uint8_t EUI[8];             //!< Unique identifier assigned to device
00409     } DeviceConfig;
00410 
00411     /**
00412      * Network configuration
00413      */
00414     typedef struct {
00415             uint8_t Mode;               //!< PUBLIC, PRIVATE or PEER_TO_PEER network mode
00416             uint8_t Class;              //!< Operating class of device
00417             uint8_t EUI[8];             //!< Network ID or AppEUI
00418             uint8_t Key[16];            //!< Network Key or AppKey
00419             uint8_t JoinDelay;          //!< Number of seconds to wait before 1st RX Window
00420             uint8_t RxDelay;            //!< Number of seconds to wait before 1st RX Window
00421             uint8_t FrequencySubBand;   //!< FrequencySubBand used for US915 hybrid operation 0:72 channels, 1:1-8 channels ...
00422             uint8_t AckAttempts;        //!< Number of attempts to send packet and receive an ACK from server
00423             uint8_t Retries;            //!< Number of times to resend a packet without receiving an ACK, redundancy
00424             uint8_t ADREnabled;         //!< Enable adaptive datarate
00425             uint8_t CADEnabled;         //!< Enable listen before talk/channel activity detection
00426             uint8_t RepeaterMode;       //!< Limit payloads to repeater compatible sizes
00427             uint8_t TxPower;            //!< Default radio output power in dBm
00428             uint8_t TxPowerMax;         //!< Max transmit power
00429             uint8_t TxDatarate;         //!< Datarate for P2P transmit
00430             uint32_t TxFrequency;       //!< Frequency for P2P transmit
00431             int8_t AntennaGain;         //!< Antenna Gain
00432             uint8_t DisableEncryption;  //!< Disable Encryption
00433             uint8_t DisableCRC;        //!< Disable CRC on uplink packets
00434             uint16_t P2PACKTimeout;
00435             uint16_t P2PACKBackoff;
00436             uint8_t JoinRx1DatarateOffset;  //!< Offset for datarate for first window
00437             uint32_t JoinRx2Frequency;      //!< Frequency used in second window
00438             uint8_t JoinRx2DatarateIndex;   //!< Datarate for second window
00439     } NetworkConfig;
00440 
00441     /**
00442      * Network session info
00443      * Some settings are acquired in join message and others may be changed through Mac Commands from server
00444      */
00445     typedef struct {
00446             uint8_t Joined;                     //!< State of session
00447             uint8_t Rx1DatarateOffset;          //!< Offset for datarate for first window
00448             uint32_t Rx2Frequency;              //!< Frequency used in second window
00449             uint8_t Rx2DatarateIndex;           //!< Datarate for second window
00450             uint8_t TxPower;                    //!< Current total radiated output power in dBm
00451             uint8_t TxDatarate;                 //!< Current datarate can be changed when ADR is enabled
00452             uint32_t Address;                   //!< Network address
00453             uint32_t NetworkID;                 //!< Network ID 24-bits
00454             uint8_t NetworkSessionKey[16];      //!< Network session key
00455             uint8_t ApplicationSessionKey[16];  //!< Data session key
00456             uint16_t ChannelMask[4];            //!< Current channel mask
00457             uint16_t ChannelMask500k;           //!< Current channel mask for 500k channels
00458             uint32_t DownlinkCounter;           //!< Downlink counter of last packet received from server
00459             uint32_t UplinkCounter;             //!< Uplink counter of last packet received from server
00460             uint8_t Redundancy;                 //!< Number of time to repeat an uplink
00461             uint8_t MaxDutyCycle;               //!< Current Max Duty Cycle value
00462             uint32_t JoinTimeOnAir;              //!< Balance of time on air used during join attempts
00463             uint32_t JoinTimeOffEnd;            //!< RTC time of next join attempt
00464             uint32_t JoinFirstAttempt;          //!< RTC time of first failed join attempt
00465             uint32_t AggregatedTimeOffEnd;      //!< Time off air expiration for aggregate duty cycle
00466             uint16_t AggregateDutyCycle;        //!< Used for enforcing time-on-air
00467             uint8_t AckCounter;                 //!< Current number of packets sent without ACK from server
00468             uint8_t AdrCounter;                 //!< Current number of packets received without downlink from server
00469             uint8_t RxDelay;                    //!< Number of seconds to wait before 1st RX Window
00470             uint8_t CommandBuffer[COMMANDS_BUFFER_SIZE]; //!< Buffer to hold Mac Commands and parameters to be sent in next packet
00471             uint8_t CommandBufferIndex;         //!< Index to place next Mac Command, also current size of Command Buffer
00472             bool SrvRequestedAck;               //!< Indicator of ACK requested by server in last packet received
00473             bool DataPending;                   //!< Indicator of data pending at server
00474             uint8_t RxTimingSetupReqReceived;   //!< Indicator that RxTimingSetupAns should be included in uplink
00475             uint8_t RxParamSetupReqAnswer;      //!< Indicator that RxParamSetupAns should be included in uplink
00476             uint8_t DlChannelReqAnswer;         //!< Indicator that DlChannelAns should be included in uplink
00477             uint8_t DownlinkDwelltime;          //!< On air dwell time for downlink packets 0:NONE,1:400ms
00478             uint8_t UplinkDwelltime;            //!< On air dwell time for uplink packets 0:NONE,1:400ms
00479             uint8_t Max_EIRP;                   //!< Maximum allowed EIRP for uplink
00480     } NetworkSession;
00481 
00482     /**
00483      * Multicast session info
00484      */
00485     typedef struct {
00486             uint32_t Address;               //!< Network address
00487             uint8_t NetworkSessionKey[16];  //!< Network session key
00488             uint8_t DataSessionKey[16];     //!< Data session key
00489             uint32_t DownlinkCounter;       //!< Downlink counter of last packet received from server
00490     } MulticastSession;
00491 
00492     /**
00493      * Application configuration
00494      */
00495     typedef struct {
00496             uint8_t Port;                   //!< Port used by application
00497             uint8_t AppEUI;                 //!< Application ID
00498             uint8_t AppKey[16];             //!< Application Key
00499     } ApplicationConfig;
00500 
00501     /**
00502      * Statistics of current network session
00503      */
00504     typedef struct Statistics {
00505             uint32_t Up;                    //!< Number of uplink packets sent
00506             uint32_t Down;                  //!< Number of downlink packets received
00507             uint32_t Joins;                 //!< Number of join requests sent
00508             uint32_t JoinFails;             //!< Number of join requests without response or invalid response
00509             uint32_t MissedAcks;            //!< Number of missed acknowledgement attempts of confirmed packets
00510             uint32_t CRCErrors;             //!< Number of CRC errors in received packets
00511             int32_t AvgCount;              //!< Number of packets used to compute rolling average of RSSI and SNR
00512             int16_t Rssi;                   //!< RSSI of last packet received
00513             int16_t RssiMin;                //!< Minimum RSSI of last AvgCount packets
00514             int16_t RssiMax;                //!< Maximum RSSI of last AvgCount packets
00515             int16_t RssiAvg;                //!< Rolling average RSSI of last AvgCount packets
00516             int16_t Snr;                     //!< SNR of last packet received
00517             int16_t SnrMin;                  //!< Minimum SNR of last AvgCount packets
00518             int16_t SnrMax;                  //!< Maximum SNR of last AvgCount packets
00519             int16_t SnrAvg;                  //!< Rolling average SNR of last AvgCount packets
00520     } Statistics;
00521 
00522     /**
00523      *  Testing settings
00524      */
00525     typedef struct {
00526             uint8_t TestMode;
00527             uint8_t SkipMICCheck;
00528             uint8_t DisableDutyCycle;
00529             uint8_t DisableRx1;
00530             uint8_t DisableRx2;
00531             uint8_t FixedUplinkCounter;
00532             uint8_t DisableRandomJoinDatarate;
00533     } Testing;
00534 
00535     /**
00536      * Combination of device, network, testing settings and statistics
00537      */
00538     typedef struct {
00539             DeviceConfig Device;
00540             NetworkConfig Network;
00541             NetworkSession Session;
00542             ApplicationConfig Applications[MAX_APPS];
00543             MulticastSession Multicast[MAX_MULTICAST_SESSIONS];
00544             Statistics Stats;
00545             Testing Test;
00546     } Settings;
00547 
00548     /**
00549      * Downlink settings sent in Join Accept message
00550      */
00551     typedef union {
00552             uint8_t Value;
00553             struct {
00554                     uint8_t Rx2Datarate :4;
00555                     uint8_t Rx1Offset :3;
00556                     uint8_t RFU :1;
00557             };
00558     } DownlinkSettings;
00559 
00560     /**
00561      * Frame structure for Join Request
00562      */
00563     typedef struct {
00564             uint8_t Type;
00565             uint8_t AppEUI[8];
00566             uint8_t DevEUI[8];
00567             uint8_t Nonce[2];
00568             uint8_t MIC[4];
00569     } JoinRequestFrame;
00570 
00571     /**
00572      * Mac header of uplink and downlink packets
00573      */
00574     typedef union {
00575             uint8_t Value;
00576             struct {
00577                     uint8_t Major :2;
00578                     uint8_t RFU :3;
00579                     uint8_t MType :3;
00580             } Bits;
00581     } MacHeader;
00582 
00583     /**
00584      * Frame control field of uplink packets
00585      */
00586     typedef union {
00587             uint8_t Value;
00588             struct {
00589                     uint8_t OptionsLength :4;
00590                     uint8_t ClassB :1;
00591                     uint8_t Ack :1;
00592                     uint8_t AdrAckReq :1;
00593                     uint8_t Adr :1;
00594             } Bits;
00595     } UplinkControl;
00596 
00597     /**
00598      * Frame control field of downlink packets
00599      */
00600     typedef union {
00601             uint8_t Value;
00602             struct {
00603                     uint8_t OptionsLength :4;
00604                     uint8_t FPending :1;
00605                     uint8_t Ack :1;
00606                     uint8_t RFU :1;
00607                     uint8_t Adr :1;
00608             } Bits;
00609     } DownlinkControl;
00610 
00611     /**
00612      * Frame type of packet
00613      */
00614     typedef enum {
00615         FRAME_TYPE_JOIN_REQ = 0x00,
00616         FRAME_TYPE_JOIN_ACCEPT = 0x01,
00617         FRAME_TYPE_DATA_UNCONFIRMED_UP = 0x02,
00618         FRAME_TYPE_DATA_UNCONFIRMED_DOWN = 0x03,
00619         FRAME_TYPE_DATA_CONFIRMED_UP = 0x04,
00620         FRAME_TYPE_DATA_CONFIRMED_DOWN = 0x05,
00621         FRAME_TYPE_RFU = 0x06,
00622         FRAME_TYPE_PROPRIETARY = 0x07,
00623     } FrameType;
00624 
00625     /**
00626      * LoRaWAN mote MAC commands
00627      */
00628     typedef enum {
00629         /* Class A */
00630         MOTE_MAC_LINK_CHECK_REQ = 0x02,
00631         MOTE_MAC_LINK_ADR_ANS = 0x03,
00632         MOTE_MAC_DUTY_CYCLE_ANS = 0x04,
00633         MOTE_MAC_RX_PARAM_SETUP_ANS = 0x05,
00634         MOTE_MAC_DEV_STATUS_ANS = 0x06,
00635         MOTE_MAC_NEW_CHANNEL_ANS = 0x07,
00636         MOTE_MAC_RX_TIMING_SETUP_ANS = 0x08,
00637         MOTE_MAC_TX_PARAM_SETUP_ANS = 0x09,
00638         MOTE_MAC_DL_CHANNEL_ANS = 0x0A,
00639 
00640         /* Class B */
00641         MOTE_MAC_PING_SLOT_INFO_REQ = 0x0B,
00642         MOTE_MAC_PING_SLOT_FREQ_ANS = 0x0C,
00643         MOTE_MAC_PING_SLOT_CHANNEL_ANS = 0x0D,
00644         MOTE_MAC_BEACON_TIMING_REQ = 0x0E,
00645         MOTE_MAC_BEACON_FREQ_ANS = 0x0F,
00646 
00647         /* Multitech */
00648         MOTE_MAC_PING_REQ = 0x80,
00649         MOTE_MAC_CHANGE_CLASS = 0x81,
00650         MOTE_MAC_MULTIPART_START_REQ = 0x82,
00651         MOTE_MAC_MULTIPART_START_ANS = 0x83,
00652         MOTE_MAC_MULTIPART_CHUNK = 0x84,
00653         MOTE_MAC_MULTIPART_END_REQ = 0x85,
00654         MOTE_MAC_MULTIPART_END_ANS = 0x86
00655     } MoteCommand;
00656 
00657     /*!
00658      * LoRaWAN server MAC commands
00659      */
00660     typedef enum {
00661         /* Class A */
00662         SRV_MAC_LINK_CHECK_ANS = 0x02,
00663         SRV_MAC_LINK_ADR_REQ = 0x03,
00664         SRV_MAC_DUTY_CYCLE_REQ = 0x04,
00665         SRV_MAC_RX_PARAM_SETUP_REQ = 0x05,
00666         SRV_MAC_DEV_STATUS_REQ = 0x06,
00667         SRV_MAC_NEW_CHANNEL_REQ = 0x07,
00668         SRV_MAC_RX_TIMING_SETUP_REQ = 0x08,
00669         SRV_MAC_TX_PARAM_SETUP_REQ = 0x09,
00670         SRV_MAC_DL_CHANNEL_REQ = 0x0A,
00671 
00672         /* Class B */
00673         SRV_MAC_PING_SLOT_INFO_ANS = 0x0B,
00674         SRV_MAC_PING_SLOT_FREQ_REQ = 0x0C,
00675         SRV_MAC_PING_SLOT_CHANNEL_REQ = 0x0D,
00676         SRV_MAC_BEACON_TIMING_ANS = 0x0E,
00677         SRV_MAC_BEACON_FREQ_REQ = 0x0F,
00678 
00679         /* Multitech */
00680         SRV_MAC_PING_ANS = 0x80,
00681         SRV_MAC_CHANGE_CLASS = 0x81,
00682         SRV_MAC_MULTIPART_START_REQ = 0x82,
00683         SRV_MAC_MULTIPART_START_ANS = 0x83,
00684         SRV_MAC_MULTIPART_CHUNK = 0x84,
00685         SRV_MAC_MULTIPART_END_REQ = 0x85,
00686         SRV_MAC_MULTIPART_END_ANS = 0x86
00687     } ServerCommand;
00688 
00689     /**
00690      * Random seed for software RNG
00691      */
00692     void srand(uint32_t seed);
00693 
00694     /**
00695      * Software RNG for consistent results across differing hardware
00696      */
00697     int rand(void);
00698 
00699     /**
00700      * Generate random number bounded by min and max
00701      */
00702     int32_t rand_r(int32_t min, int32_t max);
00703 
00704     uint8_t CountBits(uint16_t mask);
00705 
00706     /**
00707      * Copy 3-bytes network order from array into LSB of integer value
00708      */
00709     void CopyNetIDtoInt(const uint8_t* arr, uint32_t& val);
00710 
00711     /**
00712      * Copy LSB 3-bytes from integer value into array network order
00713      */
00714     void CopyNetIDtoArray(uint32_t val, uint8_t* arr);
00715 
00716     /**
00717      * Copy 4-bytes network order from array in to integer value
00718      */
00719     void CopyAddrtoInt(const uint8_t* arr, uint32_t& val);
00720 
00721     /**
00722      * Copy 4-bytes from integer in to array network order
00723      */
00724     void CopyAddrtoArray(uint32_t val, uint8_t* arr);
00725 
00726     /**
00727      * Copy 3-bytes network order from array into integer value and multiply by 100
00728      */
00729     void CopyFreqtoInt(const uint8_t* arr, uint32_t& freq);
00730 
00731     /**
00732      * Reverse memory copy
00733      */
00734     void memcpy_r(uint8_t *dst, const uint8_t *src, size_t n);
00735 
00736 }
00737 
00738 #endif
00739