libmDot0mbed5
Fork of libmDot-mbed5 by
Diff: Lora.h
- Revision:
- 16:b630e18103e5
- Child:
- 17:306ffaa5d79b
diff -r ea598f178cce -r b630e18103e5 Lora.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lora.h Thu Aug 04 15:11:24 2016 -0500 @@ -0,0 +1,707 @@ +/** __ ___ ____ _ ______ __ ____ __ ____ + * / |/ /_ __/ / /_(_)__/_ __/__ ____/ / / __/_ _____ / /____ __ _ ___ / _/__ ____ + * / /|_/ / // / / __/ /___// / / -_) __/ _ \ _\ \/ // (_-</ __/ -_) ' \(_-< _/ // _ \/ __/ __ + * /_/ /_/\_,_/_/\__/_/ /_/ \__/\__/_//_/ /___/\_, /___/\__/\__/_/_/_/___/ /___/_//_/\__/ /_/ + * Copyright (C) 2015 by Multi-Tech Systems /___/ + * + * + * @author Jason Reiss + * @date 10-31-2015 + * @brief lora namespace defines global settings, structures and enums for the lora library + * + * @details + * + * + * + */ + +#ifndef __LORA_H__ +#define __LORA_H__ + +#include "mbed.h" +#include <assert.h> +#include "MTSLog.h" +//#include <cstring> +#include <inttypes.h> + +namespace lora { + + /** + * Frequency bandwidth of a Datarate, higher bandwidth gives higher datarate + */ + enum Bandwidth { + BW_125, + BW_250, + BW_500, + BW_FSK = 50 + }; + + /** + * Spreading factor of a Datarate, lower spreading factor gives higher datarate + */ + enum SpreadingFactors { + SF_6 = 6, + SF_7, + SF_8, + SF_9, + SF_10, + SF_11, + SF_12, + SF_FSK, + SF_INVALID + }; + + /** + * Datarates for use with ChannelPlan + */ + enum Datarates { + DR_0 = 0, + DR_1, + DR_2, + DR_3, + DR_4, + DR_5, + DR_6, + DR_7, + DR_8, + DR_9, + DR_10, + DR_11, + DR_12, + DR_13, + DR_14, + DR_15 + }; + + const uint8_t MIN_DATARATE = (uint8_t) DR_0; //!< Minimum datarate + + + const uint8_t MAX_PHY_PACKET_SIZE = 255; //!< Maximum size for a packet + const uint8_t MAX_APPS = 8; //!< Maximum number of apps sessions to save + const uint8_t MAX_MULTICAST_SESSIONS = 8; //!< Maximum number of multicast sessions to save + const uint8_t EUI_SIZE = 8; //!< Number of bytes in an EUI + const uint8_t KEY_SIZE = 16; //!< Number of bytes in an AES key + + const uint8_t DEFAULT_NUM_CHANNELS = 16; //!< Default number of channels in a plan + const uint8_t DEFAULT_RX1_DR_OFFSET = 0; //!< Default datarate offset for first rx window + const uint8_t DEFAULT_RX2_DATARATE = 0; //!< Default datarate for second rx window + const uint8_t DEFAULT_TX_POWER = 14; //!< Default transmit power + const uint8_t DEFAULT_CODE_RATE = 1; //!< Default coding rate 1:4/5, 2:4/6, 3:4/7, 4:4/8 + const uint8_t DEFAULT_PREAMBLE_LEN = 8; //!< Default preamble length + + const int32_t MAX_FCNT_GAP = 16384; //!< Maximum allowed gap in sequence numbers before roll-over + + const uint16_t PRIVATE_JOIN_DELAY = 1000; //!< Default join delay used for private network + const uint16_t PUBLIC_JOIN_DELAY = 5000; //!< Default join delay used for public network + const uint16_t DEFAULT_JOIN_DELAY = PRIVATE_JOIN_DELAY; //!< Default join delay1 + const uint16_t DEFAULT_RX_DELAY = 1000; //!< Default delay for first receive window + const uint16_t DEFAULT_RX_TIMEOUT = 3000; //!< Default timeout for receive windows + + const uint8_t HI_DR_SYMBOL_TIMEOUT = 12; //!< Symbol timeout for receive at datarate with SF < 11 + const uint8_t LO_DR_SYMBOL_TIMEOUT = 8; //!< Symbol timeout for receive at datarate with SF > 10 + + const uint16_t RX2_DELAY_OFFSET = 1000; //!< Delay between first and second window + const uint16_t RXC_OFFSET = 50; //!< Time between end of RXC after TX and RX1 + + const uint8_t US915_125K_NUM_CHANS = 64; //!< Number of 125k channels in US915 channel plan + const uint8_t US915_500K_NUM_CHANS = 8; //!< Number of 500k channels in US915 channel plan + + const uint32_t US915_125K_FREQ_BASE = 902300000; //!< Frequency base for 125k US915 uplink channels + const uint32_t US915_125K_FREQ_STEP = 200000; //!< Frequency step for 125k US915 uplink channels + + const uint32_t US915_500K_FREQ_BASE = 903000000; //!< Frequency base for 500k US915 uplink channels + const uint32_t US915_500K_FREQ_STEP = 1600000; //!< Frequency step for 500k US915 uplink channels + + const uint32_t US915_500K_DBASE = 923300000; //!< Frequency base for 500k US915 downlink channels + const uint32_t US915_500K_DSTEP = 600000; //!< Frequency step for 500k US915 downlink channels + + const uint32_t US915_FREQ_MIN = 902000000; + const uint32_t US915_FREQ_MAX = 928000000; + + const uint8_t US915_MIN_DATARATE = (uint8_t) DR_0; //!< Minimum transmit datarate for US915 + const uint8_t US915_MAX_DATARATE = (uint8_t) DR_4; //!< Maximum transmit datarate for US915 + + const uint8_t US915_MIN_DATARATE_OFFSET = (uint8_t) 0; //!< Minimum transmit datarate for US915 + const uint8_t US915_MAX_DATARATE_OFFSET = (uint8_t) 3; //!< Maximum transmit datarate for US915 + + const uint8_t AU915_125K_NUM_CHANS = 64; //!< Number of 125k channels in AU915 channel plan + const uint8_t AU915_500K_NUM_CHANS = 8; //!< Number of 500k channels in AU915 channel plan + + const uint32_t AU915_125K_FREQ_BASE = 915200000; //!< Frequency base for 125k AU915 uplink channels + const uint32_t AU915_125K_FREQ_STEP = 200000; //!< Frequency step for 125k AU915 uplink channels + + const uint32_t AU915_500K_FREQ_BASE = 915900000; //!< Frequency base for 500k AU915 uplink channels + const uint32_t AU915_500K_FREQ_STEP = 1600000; //!< Frequency step for 500k AU915 uplink channels + + const uint32_t AU915_500K_DBASE = 923300000; //!< Frequency base for 500k AU915 downlink channels + const uint32_t AU915_500K_DSTEP = 600000; //!< Frequency step for 500k AU915 downlink channels + + const uint32_t AU915_FREQ_MIN = 915000000; + const uint32_t AU915_FREQ_MAX = 928000000; + + const uint8_t AU915_MIN_DATARATE = (uint8_t) DR_0; //!< Minimum transmit datarate for AU915 + const uint8_t AU915_MAX_DATARATE = (uint8_t) DR_4; //!< Maximum transmit datarate for AU915 + + const uint8_t AU915_MIN_DATARATE_OFFSET = (uint8_t) 0; //!< Minimum transmit datarate for AU915 + const uint8_t AU915_MAX_DATARATE_OFFSET = (uint8_t) 3; //!< Maximum transmit datarate for AU915 + + const uint8_t EU868_125K_NUM_CHANS = 16; //!< Number of 125k channels in EU868 channel plan + const uint8_t EU868_DEFAULT_NUM_CHANS = 3; //!< Number of defualt channels in EU868 channel plan + const uint32_t EU868_125K_FREQ_BASE = 868100000; //!< Frequency base for 125k EU868 uplink channels + const uint32_t EU868_125K_FREQ_STEP = 200000; //!< Frequency step for 125k EU868 uplink channels + const uint32_t EU868_RX2_FREQ = 869525000; //!< Frequency default for second rx window in EU868 + + const uint8_t EU868_TX_POWER_MAX = 14; //!< Max power for EU868 channel plan + + // 0.1% duty cycle 863-868 + // Limiting to 865-868 allows for 1% duty cycle + const uint32_t EU868_MILLI_FREQ_MIN = 865000000; + const uint32_t EU868_MILLI_FREQ_MAX = 868000000; + + const uint32_t EU868_MILLI_1_FREQ_MIN = 868700000; + const uint32_t EU868_MILLI_1_FREQ_MAX = 869200000; + + // 1% duty cycle + const uint32_t EU868_CENTI_FREQ_MIN = 868000000; + const uint32_t EU868_CENTI_FREQ_MAX = 868600000; + + // 10% duty cycle + const uint32_t EU868_DECI_FREQ_MIN = 869400000; + const uint32_t EU868_DECI_FREQ_MAX = 869650000; + + // Below 7dBm there is no duty cycle for these frequencies + // Up to 14dBm there is 1% duty cycle + const uint32_t EU868_VAR_FREQ_MIN = 869700000; + const uint32_t EU868_VAR_FREQ_MAX = 870000000; + + const uint32_t EU868_FREQ_MIN = 863000000; + const uint32_t EU868_FREQ_MAX = 870000000; + + const uint8_t EU868_MIN_DATARATE = (uint8_t) DR_0; //!< Minimum transmit datarate for EU868 + const uint8_t EU868_MAX_DATARATE = (uint8_t) DR_7; //!< Maximum transmit datarate for EU868 + + const uint8_t EU868_MIN_DATARATE_OFFSET = (uint8_t) 0; //!< Minimum transmit datarate for US915 + const uint8_t EU868_MAX_DATARATE_OFFSET = (uint8_t) 5; //!< Maximum transmit datarate for US915 + + const int16_t DEFAULT_FREE_CHAN_RSSI_THRESHOLD = -90; //!< Threshold for channel activity detection (CAD) dBm + + const uint8_t CHAN_MASK_SIZE = 16; //!< Number of bits in a channel mask + const uint8_t COMMANDS_BUFFER_SIZE = 15; //!< Size of Mac Command buffer + + const uint8_t PKT_HEADER = 0; //!< Index to packet mHdr field + const uint8_t PKT_ADDRESS = 1; //!< Index to first byte of packet address field + const uint8_t PKT_FRAME_CONTROL = PKT_ADDRESS + 4; //!< Index to packet fCtrl field @see UplinkControl + const uint8_t PKT_FRAME_COUNTER = PKT_FRAME_CONTROL + 1; //!< Index to packet frame counter field + const uint8_t PKT_OPTIONS_START = PKT_FRAME_COUNTER + 2; //!< Index to start of optional mac commands + + const uint8_t PKT_JOIN_APP_NONCE = 1; //!< Index to application nonce in Join Accept message + const uint8_t PKT_JOIN_NETWORK_ID = 4; //!< Index to network id in Join Accept message + const uint8_t PKT_JOIN_NETWORK_ADDRESS = 7; //!< Index to network address in Join Accept message + const uint8_t PKT_JOIN_DL_SETTINGS = 11; //!< Index to downlink settings in Join Accept message + const uint8_t PKT_JOIN_RX_DELAY = 12; //!< Index to rx delay in Join Accept message + + const uint8_t ADR_ACK_LIMIT = 64; //!< Number of packets without ADR ACK Request + const uint8_t ADR_ACK_DELAY = 32; //!< Number of packets to expect ADR ACK Response within + + const uint16_t ACK_TIMEOUT = 2000; //!< Base millisecond timeout to resend after missed ACK + const uint16_t ACK_TIMEOUT_RND = 1000; //!< Random millisecond adjustment to resend after missed ACK + + const uint8_t FRAME_OVERHEAD = 13; //!< Bytes of network info overhead in a frame + + /** + * Settings to choose ChannelPlan + */ + enum FrequencyBand { + EU868, //!< EU 863-870 16 channel uplink + US915, //!< US 902-928 64-125k/8-500k uplink and 8-500k downlink channels + AU915, //!< US 915-928 64-125k/8-500k uplink and 8-500k downlink channels + CN779, //!< + CN470, //!< + EU433, //!< + }; + + /** + * Settings for type of network + * PUBLIC - defaults to 5/6 second join windows and 0x34 sync word + * PRIVATE - defaults to 1/2 second join windows and 0x12 sync word + */ + enum NetworkType { + PRIVATE = 0, + PUBLIC = 1, + PEER_TO_PEER = 4 + }; + + /** + * Enum for on/off settings + */ + enum Enabled { + OFF = 0, + ON = 1 + }; + + /** + * Return status of mac functions + */ + enum MacStatus { + LORA_OK = 0, + LORA_ERROR = 1, + LORA_JOIN_ERROR = 2, + LORA_SEND_ERROR = 3, + LORA_MIC_ERROR = 4, + LORA_ADDRESS_ERROR = 5, + LORA_NO_CHANS_ENABLED = 6, + LORA_COMMAND_BUFFER_FULL = 7, + LORA_UNKNOWN_MAC_COMMAND = 8, + LORA_ADR_OFF = 9, + LORA_BUSY = 10, + LORA_LINK_BUSY = 11, + LORA_RADIO_BUSY = 12, + LORA_BUFFER_FULL = 13, + LORA_JOIN_BACKOFF = 14, + LORA_NO_FREE_CHAN = 15, + LORA_AGGREGATED_DUTY_CYCLE = 16, + LORA_MAX_PAYLOAD_EXCEEDED + }; + + /** + * State for Link + */ + enum LinkState { + LINK_IDLE = 0, //!< Link ready to send or receive + LINK_TX, //!< Link is busy sending + LINK_ACK_TX, //!< Link is busy resending after missed ACK + LINK_REP_TX, //!< Link is busy repeating + LINK_RX, //!< Link has receive window open + LINK_RX1, //!< Link has first received window open + LINK_RX2, //!< Link has second received window open + LINK_RXC, //!< Link has class C received window open + LINK_P2P, //!< Link is busy sending + }; + + /** + * State for MAC + */ + enum MacState { + MAC_IDLE, + MAC_RX1, + MAC_RX2, + MAC_RXC, + MAC_TX + }; + + /** + * Operation class for device + */ + enum MoteClass { + CLASS_A = 0x00, //!< Device can only receive in windows opened after a transmit + CLASS_B = 0x01, //!< Device can receive in windows sychronized with gateway beacon + CLASS_C = 0x02 //!< Device can receive any time when not transmitting + }; + + /** + * Direction of a packet + */ + enum Direction { + DIR_UP = 0, //!< Packet is sent from mote to gateway + DIR_DOWN = 1, //!< Packet was received from gateway + DIR_PEER = 2 //!< Packet was received from peer + }; + + + /** + * Received window used by Link + */ + enum ReceiveWindows { + RX_1 = 1, //!< First receive window + RX_2, //!< Second receive window + RX_BEACON, //!< Beacon receive window + RX_SLOT, //!< Beacon Slot receive window + RX_TEST + }; + + /** + * Datarate range for a Channel + */ + typedef union { + int8_t Value; + struct { + int8_t Min :4; + int8_t Max :4; + } Fields; + } DatarateRange; + + /** + * Datarate used for transmitting and receiving + */ + typedef struct Datarate { + uint8_t Index; + uint8_t Bandwidth; + uint8_t Coderate; + uint8_t PreambleLength; + uint8_t SpreadingFactor; + uint8_t Crc; + uint8_t TxIQ; + uint8_t RxIQ; + uint8_t SymbolTimeout(); + Datarate(); + } Datarate; + + /** + * Channel used for transmitting + */ + typedef struct { + uint8_t Index; + uint32_t Frequency; + DatarateRange DrRange; + } Channel; + + /** + * Receive window + */ + typedef struct { + uint8_t Index; + uint32_t Frequency; + uint8_t DatarateIndex; + } RxWindow; + + /** + * Duty band for limiting time-on-air for regional regulations + */ + typedef struct { + uint8_t Index; + uint32_t FrequencyMin; + uint32_t FrequencyMax; + uint8_t PowerMax; + uint16_t DutyCycle; //!< Multiplier of time on air, 0:100%, 1:50%, 2:33%, 10:10%, 100:1%, 1000,0.1% + uint32_t TimeOffEnd; //!< Timestamp when this band will be available + } DutyBand; + + /** + * Device configuration + */ + typedef struct { + uint8_t FrequencyBand; //!< Used to choose ChannelPlan + uint8_t EUI[8]; //!< Unique identifier assigned to device + } DeviceConfig; + + /** + * Network configuration + */ + typedef struct { + uint8_t Mode; //!< PUBLIC, PRIVATE or PEER_TO_PEER network mode + uint8_t Class; //!< Operating class of device + uint8_t EUI[8]; //!< Network ID or AppEUI + uint8_t Key[16]; //!< Network Key or AppKey + uint8_t JoinDelay; //!< Number of seconds to wait before 1st RX Window + uint8_t RxDelay; //!< Number of seconds to wait before 1st RX Window + uint8_t ChannelGroup; //!< ChannelGroup used for US915 hybrid operation 0:72 channels, 1:1-8 channels ... + uint8_t AckAttempts; //!< Number of attempts to send packet and receive an ACK from server + uint8_t Retries; //!< Number of times to resend a packet without receiving an ACK, redundancy + uint8_t ADREnabled; //!< Enable adaptive datarate + uint8_t CADEnabled; //!< Enable listen before talk/channel activity detection + uint8_t RepeaterMode; //!< Limit payloads to repeater compatible sizes + uint8_t TxPower; //!< Default radio output power in dBm + uint8_t TxPowerMax; //!< Max transmit power + uint8_t TxDatarate; //!< Datarate for P2P transmit + uint32_t TxFrequency; //!< Frequency for P2P transmit + int8_t AntennaGain; //!< Antenna Gain + uint8_t DisableEncryption; //!< Disable Encryption + uint8_t DisableCRC; //!< Disable CRC on uplink packets + uint16_t P2PACKTimeout; + uint16_t P2PACKBackoff; + uint8_t JoinRx1DatarateOffset; //!< Offset for datarate for first window + uint32_t JoinRx2Frequency; //!< Frequency used in second window + uint8_t JoinRx2DatarateIndex; //!< Datarate for second window + } NetworkConfig; + + /** + * Network session info + * Some settings are acquired in join message and others may be changed through Mac Commands from server + */ + typedef struct { + uint8_t Joined; //!< State of session + uint8_t Rx1DatarateOffset; //!< Offset for datarate for first window + uint32_t Rx2Frequency; //!< Frequency used in second window + uint8_t Rx2DatarateIndex; //!< Datarate for second window + uint8_t TxPower; //!< Current total radiated output power in dBm + uint8_t TxDatarate; //!< Current datarate can be changed when ADR is enabled + uint32_t Address; //!< Network address + uint32_t NetworkID; //!< Network ID 24-bits + uint8_t NetworkSessionKey[16]; //!< Network session key + uint8_t ApplicationSessionKey[16]; //!< Data session key + uint16_t ChannelMask[4]; //!< Current channel mask + uint16_t ChannelMask500k; //!< Current channel mask for 500k channels + uint32_t DownlinkCounter; //!< Downlink counter of last packet received from server + uint32_t UplinkCounter; //!< Uplink counter of last packet received from server + uint8_t Redundancy; //!< Number of time to repeat an uplink + uint8_t MaxDutyCycle; //!< Current Max Duty Cycle value + uint32_t JoinTimeOnAir; //!< Balance of time on air used during join attempts + uint32_t JoinTimeOffEnd; //!< RTC time of next join attempt + uint32_t JoinFirstAttempt; //!< RTC time of first failed join attempt + uint32_t AggregatedTimeOffEnd; //!< Time off air expiration for aggregate duty cycle + uint16_t AggregateDutyCycle; //!< Used for enforcing time-on-air + uint8_t AckCounter; //!< Current number of packets sent without ACK from server + uint8_t AdrCounter; //!< Current number of packets received without downlink from server + uint8_t RxDelay; //!< Number of seconds to wait before 1st RX Window + uint8_t CommandBuffer[COMMANDS_BUFFER_SIZE]; //!< Buffer to hold Mac Commands and parameters to be sent in next packet + uint8_t CommandBufferIndex; //!< Index to place next Mac Command, also current size of Command Buffer + bool SrvRequestedAck; //!< Indicator of ACK requested by server in last packet received + bool DataPending; //!< Indicator of data pending at server + uint8_t RxTimingSetupReqReceived; //!< Indicator that RxTimingSetupAns should be included in uplink + uint8_t RxParamSetupReqAnswer; //!< Indicator that RxParamSetupAns should be included in uplink + } NetworkSession; + + /** + * Multicast session info + */ + typedef struct { + uint32_t Address; //!< Network address + uint8_t NetworkSessionKey[16]; //!< Network session key + uint8_t DataSessionKey[16]; //!< Data session key + uint32_t DownlinkCounter; //!< Downlink counter of last packet received from server + } MulticastSession; + + /** + * Application configuration + */ + typedef struct { + uint8_t Port; //!< Port used by application + uint8_t AppEUI; //!< Application ID + uint8_t AppKey[16]; //!< Application Key + } ApplicationConfig; + + /** + * Statistics of current network session + */ + typedef struct Statistics { + uint32_t Up; //!< Number of uplink packets sent + uint32_t Down; //!< Number of downlink packets received + uint32_t Joins; //!< Number of join requests sent + uint32_t JoinFails; //!< Number of join requests without response or invalid response + uint32_t MissedAcks; //!< Number of missed acknowledgement attempts of confirmed packets + uint32_t CRCErrors; //!< Number of CRC errors in received packets + int32_t AvgCount; //!< Number of packets used to compute rolling average of RSSI and SNR + int16_t Rssi; //!< RSSI of last packet received + int16_t RssiMin; //!< Minimum RSSI of last AvgCount packets + int16_t RssiMax; //!< Maximum RSSI of last AvgCount packets + int16_t RssiAvg; //!< Rolling average RSSI of last AvgCount packets + int16_t Snr; //!< SNR of last packet received + int16_t SnrMin; //!< Minimum SNR of last AvgCount packets + int16_t SnrMax; //!< Maximum SNR of last AvgCount packets + int16_t SnrAvg; //!< Rolling average SNR of last AvgCount packets + } Statistics; + + /** + * Testing settings + */ + typedef struct { + uint8_t TestMode; + uint8_t SkipMICCheck; + uint8_t DisableDutyCycle; + uint8_t DisableRx1; + uint8_t DisableRx2; + uint8_t FixedUplinkCounter; + uint8_t DisableRandomJoinDatarate; + } Testing; + + /** + * Combination of device, network, testing settings and statistics + */ + typedef struct { + DeviceConfig Device; + NetworkConfig Network; + NetworkSession Session; + ApplicationConfig Applications[MAX_APPS]; + MulticastSession Multicast[MAX_MULTICAST_SESSIONS]; + Statistics Stats; + Testing Test; + } Settings; + + /** + * Downlink settings sent in Join Accept message + */ + typedef union { + uint8_t Value; + struct { + uint8_t Rx2Datarate :4; + uint8_t Rx1Offset :3; + uint8_t RFU :1; + }; + } DownlinkSettings; + + /** + * Frame structure for Join Request + */ + typedef struct { + uint8_t Type; + uint8_t AppEUI[8]; + uint8_t DevEUI[8]; + uint8_t Nonce[2]; + uint8_t MIC[4]; + } JoinRequestFrame; + + /** + * Mac header of uplink and downlink packets + */ + typedef union { + uint8_t Value; + struct { + uint8_t Major :2; + uint8_t RFU :3; + uint8_t MType :3; + } Bits; + } MacHeader; + + /** + * Frame control field of uplink packets + */ + typedef union { + uint8_t Value; + struct { + uint8_t OptionsLength :4; + uint8_t ClassB :1; + uint8_t Ack :1; + uint8_t AdrAckReq :1; + uint8_t Adr :1; + } Bits; + } UplinkControl; + + /** + * Frame control field of downlink packets + */ + typedef union { + uint8_t Value; + struct { + uint8_t OptionsLength :4; + uint8_t FPending :1; + uint8_t Ack :1; + uint8_t RFU :1; + uint8_t Adr :1; + } Bits; + } DownlinkControl; + + /** + * Frame type of packet + */ + typedef enum { + FRAME_TYPE_JOIN_REQ = 0x00, + FRAME_TYPE_JOIN_ACCEPT = 0x01, + FRAME_TYPE_DATA_UNCONFIRMED_UP = 0x02, + FRAME_TYPE_DATA_UNCONFIRMED_DOWN = 0x03, + FRAME_TYPE_DATA_CONFIRMED_UP = 0x04, + FRAME_TYPE_DATA_CONFIRMED_DOWN = 0x05, + FRAME_TYPE_RFU = 0x06, + FRAME_TYPE_PROPRIETARY = 0x07, + } FrameType; + + /** + * LoRaWAN mote MAC commands + */ + typedef enum { + /* Class A */ + MOTE_MAC_LINK_CHECK_REQ = 0x02, + MOTE_MAC_LINK_ADR_ANS = 0x03, + MOTE_MAC_DUTY_CYCLE_ANS = 0x04, + MOTE_MAC_RX_PARAM_SETUP_ANS = 0x05, + MOTE_MAC_DEV_STATUS_ANS = 0x06, + MOTE_MAC_NEW_CHANNEL_ANS = 0x07, + MOTE_MAC_RX_TIMING_SETUP_ANS = 0x08, + + /* Class B */ + MOTE_MAC_PING_SLOT_INFO_REQ = 0x09, + MOTE_MAC_PING_SLOT_FREQ_ANS = 0x0a, + MOTE_MAC_PING_SLOT_CHANNEL_ANS = 0x0a, + MOTE_MAC_BEACON_TIMING_REQ = 0x0b, + MOTE_MAC_BEACON_FREQ_ANS = 0x0c, + + /* Multitech */ + MOTE_MAC_PING_REQ = 0x80, + MOTE_MAC_CHANGE_CLASS = 0x81, + MOTE_MAC_MULTIPART_START_REQ = 0x82, + MOTE_MAC_MULTIPART_START_ANS = 0x83, + MOTE_MAC_MULTIPART_CHUNK = 0x84, + MOTE_MAC_MULTIPART_END_REQ = 0x85, + MOTE_MAC_MULTIPART_END_ANS = 0x86 + } MoteCommand; + + /*! + * LoRaWAN server MAC commands + */ + typedef enum { + /* Class A */ + SRV_MAC_LINK_CHECK_ANS = 0x02, + SRV_MAC_LINK_ADR_REQ = 0x03, + SRV_MAC_DUTY_CYCLE_REQ = 0x04, + SRV_MAC_RX_PARAM_SETUP_REQ = 0x05, + SRV_MAC_DEV_STATUS_REQ = 0x06, + SRV_MAC_NEW_CHANNEL_REQ = 0x07, + SRV_MAC_RX_TIMING_SETUP_REQ = 0x08, + + /* Class B */ + SRV_MAC_PING_SLOT_INFO_ANS = 0x09, + SRV_MAC_PING_SLOT_FREQ_REQ = 0x0a, + SRV_MAC_PING_SLOT_CHANNEL_REQ = 0x0a, + SRV_MAC_BEACON_TIMING_ANS = 0x0b, + SRV_MAC_BEACON_FREQ_REQ = 0x0c, + + /* Multitech */ + SRV_MAC_PING_ANS = 0x80, + SRV_MAC_CHANGE_CLASS = 0x81, + SRV_MAC_MULTIPART_START_REQ = 0x82, + SRV_MAC_MULTIPART_START_ANS = 0x83, + SRV_MAC_MULTIPART_CHUNK = 0x84, + SRV_MAC_MULTIPART_END_REQ = 0x85, + SRV_MAC_MULTIPART_END_ANS = 0x86 + } ServerCommand; + + /** + * Random seed for software RNG + */ + void srand(uint32_t seed); + + /** + * Software RNG for consistent results across differing hardware + */ + int rand(void); + + /** + * Generate random number bounded by min and max + */ + int32_t rand_r(int32_t min, int32_t max); + + uint8_t CountBits(uint16_t mask); + + /** + * Copy 3-bytes network order from array into LSB of integer value + */ + void CopyNetIDtoInt(const uint8_t* arr, uint32_t& val); + + /** + * Copy LSB 3-bytes from integer value into array network order + */ + void CopyNetIDtoArray(uint32_t val, uint8_t* arr); + + /** + * Copy 4-bytes network order from array in to integer value + */ + void CopyAddrtoInt(const uint8_t* arr, uint32_t& val); + + /** + * Copy 4-bytes from integer in to array network order + */ + void CopyAddrtoArray(uint32_t val, uint8_t* arr); + + /** + * Copy 3-bytes network order from array into integer value and multiply by 100 + */ + void CopyFreqtoInt(const uint8_t* arr, uint32_t& freq); + + /** + * Reverse memory copy + */ + void memcpy_r(uint8_t *dst, const uint8_t *src, size_t n); + +} + +#endif +