Library for LoRa communication using MultiTech MDOT.
Dependents: mDot_test_rx adc_sensor_lora mDotEVBM2X mDot_AT_firmware ... more
Function documentation is in mDot.h
Warning
Using libmDot 2.0.3 and above with an existing application may require a change in the MacEvent handler!
Compile applications with mbed v121 and mbed-rtos v116 libraries.
In AT Command Firmware remove line 803.
CommandTerminal/CommandTerminal.cpp
delete[] info->RxBuffer;
Likewise, if your application is handling events from the library asynchronously.
Revision 15:b50f92f1c6ff, committed 2016-08-18
- Comitter:
- jreiss
- Date:
- Thu Aug 18 16:07:10 2016 +0000
- Parent:
- 14:121e4c454964
- Child:
- 16:e4f80db195b6
- Commit message:
- update libmDot to 2.0.3
Changed in this revision
--- a/LoRaMac/LoRaMacEvent.h Mon Apr 04 09:58:34 2016 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- / _____) _ | |
- ( (____ _____ ____ _| |_ _____ ____| |__
- \____ \| ___ | (_ _) ___ |/ ___) _ \
- _____) ) ____| | | || |_| ____( (___| | | |
- (______/|_____)_|_|_| \__)_____)\____)_| |_|
- (C)2013 Semtech
-
- Description: Generic radio driver definition
-
- License: Revised BSD License, see LICENSE.TXT file include in the project
-
- Maintainer: Miguel Luis and Gregory Cristian
- */
-#ifndef __LORAMACEVENT_H__
-#define __LORAMACEVENT_H__
-
-/*!
- * LoRaMAC event flags
- */
-typedef union {
- uint8_t Value;
- struct {
- uint8_t :1;
- uint8_t Tx :1;
- uint8_t Rx :1;
- uint8_t RxData :1;
- uint8_t RxSlot :2;
- uint8_t LinkCheck :1;
- uint8_t JoinAccept :1;
- } Bits;
-} LoRaMacEventFlags;
-
-typedef enum {
- LORAMAC_EVENT_INFO_STATUS_OK = 0,
- LORAMAC_EVENT_INFO_STATUS_ERROR,
- LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT,
- LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT,
- LORAMAC_EVENT_INFO_STATUS_RX_ERROR,
- LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL,
- LORAMAC_EVENT_INFO_STATUS_DOWNLINK_FAIL,
- LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL,
- LORAMAC_EVENT_INFO_STATUS_MIC_FAIL,
-} LoRaMacEventInfoStatus;
-
-/*!
- * LoRaMAC event information
- */
-typedef struct {
- LoRaMacEventInfoStatus Status;
- bool TxAckReceived;
- uint8_t TxNbRetries;
- uint8_t TxDatarate;
- uint8_t RxPort;
- uint8_t *RxBuffer;
- uint8_t RxBufferSize;
- int16_t RxRssi;
- uint8_t RxSnr;
- uint16_t Energy;
- uint8_t DemodMargin;
- uint8_t NbGateways;
-} LoRaMacEventInfo;
-
-/*!
- * LoRaMAC events structure
- * Used to notify upper layers of MAC events
- */
-class LoRaMacEvent {
- public:
-
- virtual ~LoRaMacEvent() {}
-
- /*!
- * MAC layer event callback prototype.
- *
- * \param [IN] flags Bit field indicating the MAC events occurred
- * \param [IN] info Details about MAC events occurred
- */
- virtual void MacEvent(LoRaMacEventFlags *flags, LoRaMacEventInfo *info) {
-
- if (flags->Bits.Rx) {
- delete[] info->RxBuffer;
- }
- }
-
- virtual uint8_t MeasureBattery(void) {
- return 255;
- }
-};
-
-#endif // __LORAMACEVENT_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Lora.h Thu Aug 18 16:07:10 2016 +0000
@@ -0,0 +1,709 @@
+/** __ ___ ____ _ ______ __ ____ __ ____
+ * / |/ /_ __/ / /_(_)__/_ __/__ ____/ / / __/_ _____ / /____ __ _ ___ / _/__ ____
+ * / /|_/ / // / / __/ /___// / / -_) __/ _ \ _\ \/ // (_-</ __/ -_) ' \(_-< _/ // _ \/ __/ __
+ * /_/ /_/\_,_/_/\__/_/ /_/ \__/\__/_//_/ /___/\_, /___/\__/\__/_/_/_/___/ /___/_//_/\__/ /_/
+ * 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,
+ MAC_JOIN
+ };
+
+ /**
+ * 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
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MacEvents.h Thu Aug 18 16:07:10 2016 +0000
@@ -0,0 +1,52 @@
+/** __ ___ ____ _ ______ __ ____ __ ____
+ * / |/ /_ __/ / /_(_)__/_ __/__ ____/ / / __/_ _____ / /____ __ _ ___ / _/__ ____
+ * / /|_/ / // / / __/ /___// / / -_) __/ _ \ _\ \/ // (_-</ __/ -_) ' \(_-< _/ // _ \/ __/ __
+ * /_/ /_/\_,_/_/\__/_/ /_/ \__/\__/_//_/ /___/\_, /___/\__/\__/_/_/_/___/ /___/_//_/\__/ /_/
+ * Copyright (C) 2015 by Multi-Tech Systems /___/
+ *
+ *
+ * @author Jason Reiss
+ * @date 10-31-2015
+ * @brief lora::MacEvents provides an interface for events from the Mac layer
+ *
+ * @details
+ *
+ */
+
+#ifndef __LORA_MAC_EVENTS_H__
+#define __LORA_MAC_EVENTS_H__
+
+#include "Lora.h"
+
+namespace lora {
+
+ class MacEvents {
+
+ public:
+ virtual ~MacEvents() {};
+
+ virtual void TxDone(uint8_t dr) = 0;
+ virtual void TxTimeout(void) = 0;
+
+ virtual void JoinAccept(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) = 0;
+ virtual void JoinFailed(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) = 0;
+ 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=0) = 0;
+ virtual void RxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr, lora::DownlinkControl ctrl, uint8_t slot) = 0;
+
+ virtual void Pong(int16_t m_rssi, int8_t m_snr, int16_t s_rssi, int8_t s_snr) = 0;
+ virtual void NetworkLinkCheck(int16_t m_rssi, int8_t m_snr, int8_t s_snr, uint8_t s_gateways) = 0;
+
+ virtual void RxTimeout(uint8_t slot) = 0;
+ virtual void RxError(uint8_t slot) = 0;
+
+ virtual uint8_t MeasureBattery() = 0;
+
+ private:
+
+
+ };
+
+}
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Mote.h Thu Aug 18 16:07:10 2016 +0000
@@ -0,0 +1,257 @@
+/** __ ___ ____ _ ______ __ ____ __ ____
+ * / |/ /_ __/ / /_(_)__/_ __/__ ____/ / / __/_ _____ / /____ __ _ ___ / _/__ ____
+ * / /|_/ / // / / __/ /___// / / -_) __/ _ \ _\ \/ // (_-</ __/ -_) ' \(_-< _/ // _ \/ __/ __
+ * /_/ /_/\_,_/_/\__/_/ /_/ \__/\__/_//_/ /___/\_, /___/\__/\__/_/_/_/___/ /___/_//_/\__/ /_/
+ * Copyright (C) 2015 by Multi-Tech Systems /___/
+ *
+ *
+ * @author Jason Reiss
+ * @date 10-31-2015
+ * @brief lora::Mote provides a user level class that abstracts the complexity of the Mac layer
+ *
+ * @details
+ *
+ */
+
+#ifndef __LORA_MOTE_H__
+#define __LORA_MOTE_H__
+
+#include "rtos.h"
+#include "MacEvents.h"
+#include <vector>
+
+class SxRadio;
+class SxRadio1272;
+
+namespace lora {
+
+ class Mac;
+ class ChannelPlan;
+
+ class MoteEvents: public MacEvents {
+
+ /**
+ * Fired at end of TX
+ * @param dr datarate used for TX
+ */
+ virtual void TxDone(uint8_t dr);
+
+ /**
+ * Fired if TX timed out
+ */
+ virtual void TxTimeout(void);
+
+ /**
+ * Fired when JoinAccept message is received and MIC is validated
+ * @param payload received bytes
+ * @param size number of received bytes
+ * @param rssi of received packet
+ * @param snr of received packet
+ */
+ virtual void JoinAccept(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr);
+
+ /**
+ * Fired when JoinAccept message is received and MIC is not valid
+ * @param payload received bytes
+ * @param size number of received bytes
+ * @param rssi of received packet
+ * @param snr of received packet
+ */
+ virtual void JoinFailed(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr);
+
+ /**
+ * Fired when non duplicate packet is received and MIC is valid
+ * @param port of packet
+ * @param payload received bytes
+ * @param size number of received bytes
+ * @param rssi of received packet
+ * @param snr of received packet
+ * @param ctrl Downlink control field of packet
+ * @param slot rx window packet was received
+ * @param retries number of attempts before ack was received
+ */
+ 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 = 0);
+
+ /**
+ * Fired when radio has received a packet, packet is not validated
+ * @param payload received bytes
+ * @param size number of received bytes
+ * @param rssi of received packet
+ * @param snr of received packet
+ * @param ctrl Downlink control field of packet
+ * @param slot rx window packet was received
+ */
+ virtual void RxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr, lora::DownlinkControl ctrl, uint8_t slot);
+
+ /**
+ * Fired if rx window times out
+ * @param slot rx window that timed out
+ */
+ virtual void RxTimeout(uint8_t slot);
+
+ /**
+ * Fired if rx CRC error
+ * @param slot rx window that errored
+ */
+ virtual void RxError(uint8_t slot);
+
+ /**
+ * Fired if pong packet is received
+ * @param m_rssi of received packet at mote
+ * @param m_snr of received packet at mote
+ * @param s_rssi of received packet at server
+ * @param s_snr of received packet at server
+ */
+ virtual void Pong(int16_t m_rssi, int8_t m_snr, int16_t s_rssi, int8_t s_snr);
+
+ /**
+ * Fired if network link check answer is received
+ * @param m_rssi of received packet at mote
+ * @param m_snr of received packet at mote
+ * @param s_snr margin of received packet at server
+ * @param s_gateways number of gateways reporting the packet
+ */
+ virtual void NetworkLinkCheck(int16_t m_rssi, int8_t m_snr, int8_t s_snr, uint8_t s_gateways);
+
+ /**
+ * Callback to for device to measure the battery level and report to server
+ * @return battery level 0-255, 0 - external power, 1-254 level min-max, 255 device unable to measure battery
+ */
+ virtual uint8_t MeasureBattery();
+ };
+
+ class Mote {
+ public:
+ Mote(Settings* settings);
+ virtual ~Mote();
+
+ /**
+ * Indicator for network session join status
+ * @return true if joined to network
+ */
+ bool Joined();
+
+ /**
+ * Send join request
+ * @return LORA_OK if request was sent
+ */
+ uint8_t Join();
+
+ /**
+ * Send a packet
+ * @param port to send packet
+ * @param payload of packet
+ * @param size in bytes
+ * @return LORA_OK if successful
+ * @return LORA_MAX_PAYLOAD_EXCEEDED if payload size exceeds datarate maximum
+ * @return LORA_NO_CHANS_ENABLED if there is not an available channel that supports the current datarate
+ * @return LORA_LINK_BUSY if link was busy
+ * @return LORA_RADIO_BUSY if radio was busy
+ * @return LORA_BUFFER_FULL if mac commands filled the packet, client should resend the packet
+ */
+ uint8_t Send(uint8_t port, const uint8_t* payload, uint8_t size);
+
+ /**
+ * Configure the channel plan
+ * @param freqBand EU868, US915, AU915
+ * @return LORA_OK
+ */
+ uint8_t SetChannelPlan(uint8_t freqBand);
+
+ /**
+ * Get the channel mask of currently enabled channels
+ * @return vector containing channel bit masks
+ */
+ std::vector<uint16_t> GetChannelMask();
+
+ /**
+ * Set a 16 bit channel mask with index
+ * @param index of mask to set 0:0-15, 1:16-31 ...
+ * @param mask 16 bit mask of enabled channels
+ * @return true
+ */
+ virtual uint8_t SetChannelMask(uint8_t index, uint16_t mask);
+
+ /**
+ * Set the current channel group for hybrid operation 1-8 else 0 for 64 channel operation
+ * @param group 0-8
+ */
+ uint8_t SetChannelGroup(uint8_t group);
+
+ /**
+ * Get the current channel group
+ * @return group 0-8
+ */
+ uint8_t GetChannelGroup();
+
+ /**
+ * Add a channel to the channel plan
+ * EU868 allows additional channels to be added
+ * Channels 0-2 are fixed default channels
+ *
+ * @param index of the channel
+ * @param frequency of the channel or 0 to remove channel
+ * @param range of datarates allowed by the channel
+ * @return LORA_OK if channel was added
+ */
+ uint8_t AddChannel(uint8_t index, uint32_t frequency, lora::DatarateRange range);
+
+ /**
+ * Set network mode
+ * Choose Public LoRaWAN mode or Private Multitech mode
+ *
+ * Public mode uses 0x34 sync word with 5/6 second join windows
+ * Private mode uses 0x12 sync word with 1/2 second join windows
+ * US915/AU915 Rx1 and Rx2 are fixed per Channel Group setting
+ *
+ * @param mode public or private
+ * @return LORA_OK
+ */
+ uint8_t SetNetworkMode(uint8_t mode);
+
+ /**
+ * Get a pointer to the mac layer
+ * @return Mac mac
+ */
+ Mac* GetMac();
+
+ /**
+ * Get a pointer to the radio
+ * Can be used to read radio registers or get a random value based on RSSI
+ *
+ * @return SxRadio pointer
+ */
+ SxRadio* GetRadio();
+
+ /**
+ * Get the current statistics for the device
+ * @return Statistics
+ */
+ Statistics& GetStats();
+
+ /**
+ * Get time on air with current settings for provided payload bytes
+ * 13 overhead bytes will be added to payload
+ * @param bytes of payload data
+ * @return time-on-air in ms
+ */
+ uint32_t GetTimeOnAir(uint8_t bytes);
+
+ /**
+ * Call before setting device in sleep mode to place radio in sleep
+ */
+ void Sleep();
+
+ protected:
+ SxRadio1272* _radio;
+ Settings* _settings;
+ Mac* _mac;
+
+ private:
+ ChannelPlan* _plan;
+ MoteEvents _events;
+ };
+
+}
+#endif
+
Binary file libmDot.ar has changed
--- a/mDot.h Mon Apr 04 09:58:34 2016 -0500
+++ b/mDot.h Thu Aug 18 16:07:10 2016 +0000
@@ -5,17 +5,16 @@
#include "mbed.h"
#include "rtos.h"
+#include "Mote.h"
#include <vector>
#include <map>
#include <string>
class mDotEvent;
-class LoRaMacEvent;
class LoRaConfig;
-class LoRaMac;
-class MdotRadio;
class mDot {
+ friend class mDotEvent;
private:
@@ -27,6 +26,8 @@
__WFI();
}
+ void initLora();
+
void setLastError(const std::string& str);
static bool validateBaudRate(const uint32_t& baud);
@@ -61,10 +62,11 @@
static mDot* _instance;
- LoRaMac* _mac;
- MdotRadio* _radio;
- LoRaMacEvent* _events;
+ lora::Mote _mote;
LoRaConfig* _config;
+ lora::Settings _settings;
+ mDotEvent* _events;
+
Thread _idle_thread;
std::string _last_error;
static const uint32_t _baud_rates[];
@@ -114,7 +116,7 @@
} mdot_ret_code;
enum JoinMode {
- MANUAL,
+ MANUAL = 0,
OTA,
AUTO_OTA,
PEER_TO_PEER
@@ -158,8 +160,11 @@
};
enum FrequencyBands {
- FB_868, // EU868
- FB_915 // US915
+ FB_868 = 0,
+ FB_915 = 1,
+ FB_EU868 = 0, // EU868
+ FB_US915 = 1, // US915
+ FB_AU915 = 2
};
enum FrequencySubBands {
@@ -200,7 +205,7 @@
typedef struct {
int16_t fd;
- char name[30];
+ char name[33];
uint32_t size;
} mdot_file;
@@ -210,6 +215,7 @@
uint32_t Joins;
uint32_t JoinFails;
uint32_t MissedAcks;
+ uint32_t CRCErrors;
} mdot_stats;
typedef struct {
@@ -332,6 +338,10 @@
*/
bool getStandbyFlag();
+ std::vector<uint16_t> getChannelMask();
+
+ int32_t setChannelMask(uint8_t offset, uint16_t mask);
+
/** Add a channel frequencies currently in use
* @returns MDOT_OK
*/
@@ -551,13 +561,14 @@
*/
void saveNetworkSession();
- /** Set number of times joining will retry before giving up
+ /** Set number of times joining will retry each sub-band before changing
+ * to the next subband in US915 and AU915
* @param retries must be between 0 - 255
* @returns MDOT_OK if success
*/
int32_t setJoinRetries(const uint8_t& retries);
- /** Set number of times joining will retry before giving up
+ /** Get number of times joining will retry each sub-band
* @returns join retries (0 - 255)
*/
uint8_t getJoinRetries();
@@ -680,6 +691,42 @@
*/
uint32_t setJoinDelay(uint8_t delay);
+ /** Get join Rx1 datarate offset
+ * defaults to 0
+ * @returns offset
+ */
+ uint8_t getJoinRx1DataRateOffset();
+
+ /** Set join Rx1 datarate offset
+ * @param offset for datarate
+ * @return MDOT_OK if success
+ */
+ uint32_t setJoinRx1DataRateOffset(uint8_t offset);
+
+ /** Get join Rx2 datarate
+ * defaults to US:DR8, AU:DR8, EU:DR0
+ * @returns datarate
+ */
+ uint8_t getJoinRx2DataRate();
+
+ /** Set join Rx2 datarate
+ * @param datarate
+ * @return MDOT_OK if success
+ */
+ uint32_t setJoinRx2DataRate(uint8_t datarate);
+
+ /** Get join Rx2 frequency
+ * defaults US:923.3, AU:923.3, EU:869.525
+ * @returns frequency
+ */
+ uint32_t getJoinRx2Frequency();
+
+ /** Set join Rx2 frequency
+ * @param frequency
+ * @return MDOT_OK if success
+ */
+ uint32_t setJoinRx2Frequency(uint32_t frequency);
+
/** Get rx delay in seconds
* Defaults to 1 second
* @returns number of seconds before response message is expected
@@ -712,11 +759,22 @@
*/
bool getDataPending();
- /** Get transmitting
+ /** Get ack requested
+ * only valid after sending data to the gateway
+ * @returns true if server has requested ack
+ */
+ bool getAckRequested();
+
+ /** Get is transmitting indicator
* @returns true if currently transmitting
*/
bool getIsTransmitting();
+ /** Get is idle indicator
+ * @returns true if not currently transmitting, waiting or receiving
+ */
+ bool getIsIdle();
+
/** Set TX data rate
* data rates affect maximum payload size
* @param dr SF_7 - SF_12|DR0-DR7 for Europe, SF_7 - SF_10 | DR0-DR4 for United States
@@ -734,7 +792,6 @@
*/
uint32_t getRadioRandom();
-
/** Get data rate spreading factor and bandwidth
* EU868 Datarates
* ---------------
@@ -755,6 +812,14 @@
* DR3 - SF7BW125
* DR4 - SF8BW500
*
+ * AU915 Datarates
+ * ---------------
+ * DR0 - SF10BW125
+ * DR1 - SF9BW125
+ * DR2 - SF8BW125
+ * DR3 - SF7BW125
+ * DR4 - SF8BW500
+ *
* @returns spreading factor and bandwidth
*/
std::string getDateRateDetails(uint8_t rate);
@@ -795,6 +860,10 @@
*/
bool getTxWait();
+ /** Cancel pending rx windows
+ */
+ void cancelRxWindow();
+
/** Get time on air
* @returns the amount of time (in ms) it would take to send bytes bytes based on current configuration
*/
@@ -869,6 +938,24 @@
*/
int32_t send(const std::vector<uint8_t>& data, const bool& blocking = true, const bool& highBw = false);
+ /** Inject mac command
+ * @param data a vector containing mac commands
+ * @returns MDOT_OK
+ */
+ int32_t injectMacCommand(const std::vector<uint8_t>& data);
+
+ /**
+ * Clear MAC command buffer to be sent in next uplink
+ * @returns MDOT_OK
+ */
+ int32_t clearMacCommands();
+
+ /**
+ * Get MAC command buffer to be sent in next uplink
+ * @returns command bytes
+ */
+ std::vector<uint8_t> getMacCommands();
+
/** Fetch data received from the gateway
* this function only checks to see if a packet has been received - it does not open a receive window
* send() must be called before recv()
@@ -1104,7 +1191,6 @@
int32_t setFlowControl(const bool& on);
bool getFlowControl();
-
// get/set serial clear on error
// if enabled the data read from the serial port will be discarded if it cannot be sent or if the send fails
// set function returns MDOT_OK if success
@@ -1113,8 +1199,26 @@
// MTS_RADIO_DEBUG_COMMANDS
+ /** Disable Duty cycle
+ * enables or disables the duty cycle limitations
+ * **** ONLY TO BE USED FOR TESTINGS PURPOSES ****
+ * **** ALL DEPLOYABLE CODE MUST ADHERE TO LOCAL REGULATIONS ****
+ * **** THIS SETTING WILL NOT BE SAVED TO CONFIGURATION *****
+ * @param val true to disable duty-cycle (default:false)
+ */
+ int32_t setDisableDutyCycle(bool val);
+
+ /** Disable Duty cycle
+ * **** ONLY TO BE USED FOR TESTINGS PURPOSES ****
+ * **** ALL DEPLOYABLE CODE MUST ADHERE TO LOCAL REGULATIONS ****
+ * **** THIS SETTING WILL NOT BE SAVED TO CONFIGURATION *****
+ * @return true if duty-cycle is disabled (default:false)
+ */
+ uint8_t getDisableDutyCycle();
+
void openRxWindow(uint32_t timeout, uint8_t bandwidth = 0);
- void sendContinuous();
+ void closeRxWindow();
+ void sendContinuous(bool enable=true);
int32_t setDeviceId(const std::vector<uint8_t>& id);
int32_t setFrequencyBand(const uint8_t& band);
bool saveProtectedConfig();
@@ -1158,3 +1262,4 @@
};
#endif
+
--- a/mDotEvent.h Mon Apr 04 09:58:34 2016 -0500
+++ b/mDotEvent.h Thu Aug 18 16:07:10 2016 +0000
@@ -1,29 +1,298 @@
-#include "LoRaMacEvent.h"
+#ifndef MDOT_EVENT_H
+#define MDOT_EVENT_H
+
+#include "mDot.h"
+#include "MacEvents.h"
#include "MTSLog.h"
+#include "MTSText.h"
-class mDotEvent : public LoRaMacEvent {
+typedef union {
+ uint8_t Value;
+ struct {
+ uint8_t :1;
+ uint8_t Tx :1;
+ uint8_t Rx :1;
+ uint8_t RxData :1;
+ uint8_t RxSlot :2;
+ uint8_t LinkCheck :1;
+ uint8_t JoinAccept :1;
+ } Bits;
+} LoRaMacEventFlags;
+
+typedef enum {
+ LORAMAC_EVENT_INFO_STATUS_OK = 0,
+ LORAMAC_EVENT_INFO_STATUS_ERROR,
+ LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT,
+ LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT,
+ LORAMAC_EVENT_INFO_STATUS_RX_ERROR,
+ LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL,
+ LORAMAC_EVENT_INFO_STATUS_DOWNLINK_FAIL,
+ LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL,
+ LORAMAC_EVENT_INFO_STATUS_MIC_FAIL,
+} LoRaMacEventInfoStatus;
+
+/*!
+ * LoRaMAC event information
+ */
+typedef struct {
+ LoRaMacEventInfoStatus Status;
+ lora::DownlinkControl Ctrl;
+ bool TxAckReceived;
+ uint8_t TxNbRetries;
+ uint8_t TxDatarate;
+ uint8_t RxPort;
+ uint8_t *RxBuffer;
+ uint8_t RxBufferSize;
+ int16_t RxRssi;
+ uint8_t RxSnr;
+ uint16_t Energy;
+ uint8_t DemodMargin;
+ uint8_t NbGateways;
+} LoRaMacEventInfo;
+
+class mDotEvent: public lora::MacEvents {
public:
- virtual ~mDotEvent() {}
+ mDotEvent()
+ :
+ LinkCheckAnsReceived(false),
+ DemodMargin(0),
+ NbGateways(0),
+ PacketReceived(false),
+ RxPort(0),
+ RxPayloadSize(0),
+ PongReceived(false),
+ PongRssi(0),
+ PongSnr(0),
+ AckReceived(false),
+ TxNbRetries(0)
+ {
+ memset(&_flags, 0, sizeof(LoRaMacEventFlags));
+ memset(&_info, 0, sizeof(LoRaMacEventInfo));
+ }
- /*!
- * MAC layer event callback prototype.
- *
- * \param [IN] flags Bit field indicating the MAC events occurred
- * \param [IN] info Details about MAC events occurred
- */
+ virtual ~mDotEvent() {
+ }
+
virtual void MacEvent(LoRaMacEventFlags *flags, LoRaMacEventInfo *info) {
- logDebug("mDotEvent");
+ if (mts::MTSLog::getLogLevel() == mts::MTSLog::TRACE_LEVEL) {
+ std::string msg = "OK";
+ switch (info->Status) {
+ case LORAMAC_EVENT_INFO_STATUS_ERROR:
+ msg = "ERROR";
+ break;
+ case LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT:
+ msg = "TX_TIMEOUT";
+ break;
+ case LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT:
+ msg = "RX_TIMEOUT";
+ break;
+ case LORAMAC_EVENT_INFO_STATUS_RX_ERROR:
+ msg = "RX_ERROR";
+ break;
+ case LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL:
+ msg = "JOIN_FAIL";
+ break;
+ case LORAMAC_EVENT_INFO_STATUS_DOWNLINK_FAIL:
+ msg = "DOWNLINK_FAIL";
+ break;
+ case LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL:
+ msg = "ADDRESS_FAIL";
+ break;
+ case LORAMAC_EVENT_INFO_STATUS_MIC_FAIL:
+ msg = "MIC_FAIL";
+ break;
+ default:
+ break;
+ }
+ logTrace("Event: %s", msg.c_str());
+
+ logTrace("Flags Tx: %d Rx: %d RxData: %d RxSlot: %d LinkCheck: %d JoinAccept: %d",
+ flags->Bits.Tx, flags->Bits.Rx, flags->Bits.RxData, flags->Bits.RxSlot, flags->Bits.LinkCheck, flags->Bits.JoinAccept);
+ logTrace("Info: Status: %d ACK: %d Retries: %d TxDR: %d RxPort: %d RxSize: %d RSSI: %d SNR: %d Energy: %d Margin: %d Gateways: %d",
+ info->Status, info->TxAckReceived, info->TxNbRetries, info->TxDatarate, info->RxPort, info->RxBufferSize,
+ info->RxRssi, info->RxSnr, info->Energy, info->DemodMargin, info->NbGateways);
+ }
+ }
+
+ virtual void TxDone(uint8_t dr) {
+ RxPayloadSize = 0;
+ LinkCheckAnsReceived = false;
+ PacketReceived = false;
+ AckReceived = false;
+ PongReceived = false;
+
+ logDebug("mDotEvent - TxDone");
+ memset(&_flags, 0, sizeof(LoRaMacEventFlags));
+ memset(&_info, 0, sizeof(LoRaMacEventInfo));
+
+ _flags.Bits.Tx = 1;
+ _info.TxDatarate = dr;
+ _info.Status = LORAMAC_EVENT_INFO_STATUS_OK;
+ Notify();
+ }
+
+ void Notify() {
+ MacEvent(&_flags, &_info);
+ }
+
+ virtual void TxTimeout(void) {
+ logDebug("mDotEvent - TxTimeout");
+
+ _flags.Bits.Tx = 1;
+ _info.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT;
+ Notify();
+ }
+
+ virtual void JoinAccept(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) {
+ logDebug("mDotEvent - JoinAccept");
+
+ _flags.Bits.Tx = 0;
+ _flags.Bits.JoinAccept = 1;
+ _info.Status = LORAMAC_EVENT_INFO_STATUS_OK;
+ Notify();
+ }
+
+ virtual void JoinFailed(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) {
+ logDebug("mDotEvent - JoinFailed");
- if (flags->Bits.Rx) {
- logDebug("Rx");
+ _flags.Bits.Tx = 0;
+ _flags.Bits.JoinAccept = 1;
+ _info.Status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL;
+ Notify();
+ }
+
+ 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 = 0) {
+ logDebug("mDotEvent - PacketRx");
+ RxPort = port;
+ PacketReceived = true;
+
+ memcpy(RxPayload, payload, size);
+ RxPayloadSize = size;
+
+ if (ctrl.Bits.Ack) {
+ AckReceived = true;
+ }
+
+ if (mts::MTSLog::getLogLevel() == mts::MTSLog::TRACE_LEVEL) {
+ std::string packet = mts::Text::bin2hexString(RxPayload, size);
+ logTrace("Payload: %s", packet.c_str());
+ }
+
+ _flags.Bits.Tx = 0;
+ _flags.Bits.Rx = 1;
+ _flags.Bits.RxData = size > 0;
+ _flags.Bits.RxSlot = slot;
+ _info.RxBuffer = payload;
+ _info.RxBufferSize = size;
+ _info.RxPort = port;
+ _info.RxRssi = rssi;
+ _info.RxSnr = snr;
+ _info.TxAckReceived = AckReceived;
+ _info.TxAckReceived = retries;
+ _info.Status = LORAMAC_EVENT_INFO_STATUS_OK;
+ Notify();
+ }
+
+ virtual void RxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr, lora::DownlinkControl ctrl, uint8_t slot) {
+ logDebug("mDotEvent - RxDone");
+ }
- // Event Object must delete RxBuffer
- delete[] info->RxBuffer;
- }
+ virtual void Pong(int16_t m_rssi, int8_t m_snr, int16_t s_rssi, int8_t s_snr) {
+ logDebug("mDotEvent - Pong");
+ PongReceived = true;
+ PongRssi = s_rssi;
+ PongSnr = s_snr;
+ }
+
+ virtual void NetworkLinkCheck(int16_t m_rssi, int8_t m_snr, int8_t s_snr, uint8_t s_gateways) {
+ logDebug("mDotEvent - NetworkLinkCheck");
+ LinkCheckAnsReceived = true;
+ DemodMargin = s_snr;
+ NbGateways = s_gateways;
+
+ _flags.Bits.Tx = 0;
+ _flags.Bits.LinkCheck = 1;
+ _info.RxRssi = m_rssi;
+ _info.RxSnr = m_snr;
+ _info.DemodMargin = s_snr;
+ _info.NbGateways = s_gateways;
+ _info.Status = LORAMAC_EVENT_INFO_STATUS_OK;
+ Notify();
+ }
+
+ virtual void RxTimeout(uint8_t slot) {
+ // logDebug("mDotEvent - RxTimeout");
+
+ _flags.Bits.Tx = 0;
+ _flags.Bits.RxSlot = slot;
+ _info.Status = LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT;
+ Notify();
+ }
+
+ virtual void RxError(uint8_t slot) {
+ logDebug("mDotEvent - RxError");
+
+ memset(&_flags, 0, sizeof(LoRaMacEventFlags));
+ memset(&_info, 0, sizeof(LoRaMacEventInfo));
+
+ _flags.Bits.RxSlot = slot;
+ _info.Status = LORAMAC_EVENT_INFO_STATUS_RX_ERROR;
+ Notify();
}
virtual uint8_t MeasureBattery(void) {
return 255;
}
+
+ bool LinkCheckAnsReceived;
+ uint8_t DemodMargin;
+ uint8_t NbGateways;
+
+ bool PacketReceived;
+ uint8_t RxPort;
+ uint8_t RxPayload[255];
+ uint8_t RxPayloadSize;
+
+ bool PongReceived;
+ int16_t PongRssi;
+ int16_t PongSnr;
+
+ bool AckReceived;
+ uint8_t TxNbRetries;
+
+ LoRaMacEventFlags& Flags() {
+ return _flags;
+ }
+ LoRaMacEventInfo& Info() {
+ return _info;
+ }
+
+ private:
+
+ LoRaMacEventFlags _flags;
+ LoRaMacEventInfo _info;
+
+//
+// /*!
+// * MAC layer event callback prototype.
+// *
+// * \param [IN] flags Bit field indicating the MAC events occurred
+// * \param [IN] info Details about MAC events occurred
+// */
+// virtual void MacEvent(LoRaMacEventFlags *flags, LoRaMacEventInfo *info) {
+// logDebug("mDotEvent");
+//
+// if (flags->Bits.Rx) {
+// logDebug("Rx");
+//
+// // Event Object must delete RxBuffer
+// delete[] info->RxBuffer;
+// }
+// }
+//
+
};
+
+#endif // __MDOT_EVENT_H__
+