MultiTech / libmDot-Custom

Fork of libmDot-custom by Jason Reiss

Information

Library has been updated to mbed 5.x

The LoRaWAN Certification test mode implementation is built-in to libmDot code. When a start test mode packet is received the library will not return until test mode has ended.

Warning

This library is currently in BETA release. Unresolved issues may be experienced. Software is provided as is with no expectation of support of bug fixes in the future. Please report issues found through the mbed website or directly to support.multitech.com.

Changing of channel plan parameters may cause the device to no longer respect local RF regulations. Please use caution and respect your local regulations.

In AT Command Firmware remove line 803.

CommandTerminal/CommandTerminal.cpp

        delete[] info->RxBuffer;

Likewise, if your application is handling events from the library asynchronously.

Creating new channel plans

Copy EU868 or US915 custom channel plan as a starting point

Import programmDot_AT_firmware_CUSTOM

AT Firmware with custom channel plan support

EU868 provides a framework for a DYNAMIC channel plan with duty-cycle limitations

US915 provides a framework for a FIXED channel plan

RADIO_POWERS are measured output in dBm for each radio tx power setting.

Additional MAC Commands can be implemented by overriding the HandleMacCommand function.

Steps

  1. Setup datarates, duty-cycle bands and channels in ChannelPlan_* constructor
  2. Modify GetJoinDatarate and CalculateJoinBackoff to change join datarates and backoff
  3. Customize HandleJoinAccept datarates
  4. Use GetRxWindow(int) to define how the device open Rx window 1 and 2
  5. GetNextChannel will pick a channel from the enabled channel at the current datarate before each TX
Committer:
jreiss
Date:
Sat Sep 17 18:00:18 2016 +0000
Revision:
18:aa39c917aa3f
Parent:
17:dd0f69240713
Child:
23:3830a5f61f09
update library archive; change license notice in EU868.cpp and US915.cpp

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jreiss 18:aa39c917aa3f 1 /** __ ___ ____ _ ______ __ ____ __ ____
jreiss 18:aa39c917aa3f 2 * / |/ /_ __/ / /_(_)__/_ __/__ ____/ / / __/_ _____ / /____ __ _ ___ / _/__ ____
jreiss 18:aa39c917aa3f 3 * / /|_/ / // / / __/ /___// / / -_) __/ _ \ _\ \/ // (_-</ __/ -_) ' \(_-< _/ // _ \/ __/ __
jreiss 18:aa39c917aa3f 4 * /_/ /_/\_,_/_/\__/_/ /_/ \__/\__/_//_/ /___/\_, /___/\__/\__/_/_/_/___/ /___/_//_/\__/ /_/
jreiss 18:aa39c917aa3f 5 * Copyright (C) 2015 by Multi-Tech Systems /___/
jreiss 18:aa39c917aa3f 6 *
jreiss 18:aa39c917aa3f 7 *
jreiss 18:aa39c917aa3f 8 * @author Jason Reiss
jreiss 18:aa39c917aa3f 9 * @date 10-31-2015
jreiss 18:aa39c917aa3f 10 * @brief lora namespace defines global settings, structures and enums for the lora library
jreiss 18:aa39c917aa3f 11 *
jreiss 18:aa39c917aa3f 12 * @details
jreiss 18:aa39c917aa3f 13 *
jreiss 18:aa39c917aa3f 14 *
jreiss 18:aa39c917aa3f 15 *
jreiss 18:aa39c917aa3f 16 */
jreiss 18:aa39c917aa3f 17
jreiss 18:aa39c917aa3f 18 #ifndef __LORA_H__
jreiss 18:aa39c917aa3f 19 #define __LORA_H__
jreiss 18:aa39c917aa3f 20
jreiss 18:aa39c917aa3f 21 #include "mbed.h"
jreiss 18:aa39c917aa3f 22 #include <assert.h>
jreiss 18:aa39c917aa3f 23 #include "MTSLog.h"
jreiss 18:aa39c917aa3f 24 //#include <cstring>
jreiss 18:aa39c917aa3f 25 #include <inttypes.h>
jreiss 18:aa39c917aa3f 26
jreiss 18:aa39c917aa3f 27 namespace lora {
jreiss 18:aa39c917aa3f 28
jreiss 18:aa39c917aa3f 29 /**
jreiss 18:aa39c917aa3f 30 * Frequency bandwidth of a Datarate, higher bandwidth gives higher datarate
jreiss 18:aa39c917aa3f 31 */
jreiss 18:aa39c917aa3f 32 enum Bandwidth {
jreiss 18:aa39c917aa3f 33 BW_125,
jreiss 18:aa39c917aa3f 34 BW_250,
jreiss 18:aa39c917aa3f 35 BW_500,
jreiss 18:aa39c917aa3f 36 BW_FSK = 50
jreiss 18:aa39c917aa3f 37 };
jreiss 18:aa39c917aa3f 38
jreiss 18:aa39c917aa3f 39 /**
jreiss 18:aa39c917aa3f 40 * Spreading factor of a Datarate, lower spreading factor gives higher datarate
jreiss 18:aa39c917aa3f 41 */
jreiss 18:aa39c917aa3f 42 enum SpreadingFactors {
jreiss 18:aa39c917aa3f 43 SF_6 = 6,
jreiss 18:aa39c917aa3f 44 SF_7,
jreiss 18:aa39c917aa3f 45 SF_8,
jreiss 18:aa39c917aa3f 46 SF_9,
jreiss 18:aa39c917aa3f 47 SF_10,
jreiss 18:aa39c917aa3f 48 SF_11,
jreiss 18:aa39c917aa3f 49 SF_12,
jreiss 18:aa39c917aa3f 50 SF_FSK,
jreiss 18:aa39c917aa3f 51 SF_INVALID
jreiss 18:aa39c917aa3f 52 };
jreiss 18:aa39c917aa3f 53
jreiss 18:aa39c917aa3f 54 /**
jreiss 18:aa39c917aa3f 55 * Datarates for use with ChannelPlan
jreiss 18:aa39c917aa3f 56 */
jreiss 18:aa39c917aa3f 57 enum Datarates {
jreiss 18:aa39c917aa3f 58 DR_0 = 0,
jreiss 18:aa39c917aa3f 59 DR_1,
jreiss 18:aa39c917aa3f 60 DR_2,
jreiss 18:aa39c917aa3f 61 DR_3,
jreiss 18:aa39c917aa3f 62 DR_4,
jreiss 18:aa39c917aa3f 63 DR_5,
jreiss 18:aa39c917aa3f 64 DR_6,
jreiss 18:aa39c917aa3f 65 DR_7,
jreiss 18:aa39c917aa3f 66 DR_8,
jreiss 18:aa39c917aa3f 67 DR_9,
jreiss 18:aa39c917aa3f 68 DR_10,
jreiss 18:aa39c917aa3f 69 DR_11,
jreiss 18:aa39c917aa3f 70 DR_12,
jreiss 18:aa39c917aa3f 71 DR_13,
jreiss 18:aa39c917aa3f 72 DR_14,
jreiss 18:aa39c917aa3f 73 DR_15
jreiss 18:aa39c917aa3f 74 };
jreiss 18:aa39c917aa3f 75
jreiss 18:aa39c917aa3f 76 const uint8_t MIN_DATARATE = (uint8_t) DR_0; //!< Minimum datarate
jreiss 18:aa39c917aa3f 77
jreiss 18:aa39c917aa3f 78
jreiss 18:aa39c917aa3f 79 const uint8_t MAX_PHY_PACKET_SIZE = 255; //!< Maximum size for a packet
jreiss 18:aa39c917aa3f 80 const uint8_t MAX_APPS = 8; //!< Maximum number of apps sessions to save
jreiss 18:aa39c917aa3f 81 const uint8_t MAX_MULTICAST_SESSIONS = 8; //!< Maximum number of multicast sessions to save
jreiss 18:aa39c917aa3f 82 const uint8_t EUI_SIZE = 8; //!< Number of bytes in an EUI
jreiss 18:aa39c917aa3f 83 const uint8_t KEY_SIZE = 16; //!< Number of bytes in an AES key
jreiss 18:aa39c917aa3f 84
jreiss 18:aa39c917aa3f 85 const uint8_t DEFAULT_NUM_CHANNELS = 16; //!< Default number of channels in a plan
jreiss 18:aa39c917aa3f 86 const uint8_t DEFAULT_RX1_DR_OFFSET = 0; //!< Default datarate offset for first rx window
jreiss 18:aa39c917aa3f 87 const uint8_t DEFAULT_RX2_DATARATE = 0; //!< Default datarate for second rx window
jreiss 18:aa39c917aa3f 88 const uint8_t DEFAULT_TX_POWER = 14; //!< Default transmit power
jreiss 18:aa39c917aa3f 89 const uint8_t DEFAULT_CODE_RATE = 1; //!< Default coding rate 1:4/5, 2:4/6, 3:4/7, 4:4/8
jreiss 18:aa39c917aa3f 90 const uint8_t DEFAULT_PREAMBLE_LEN = 8; //!< Default preamble length
jreiss 18:aa39c917aa3f 91
jreiss 18:aa39c917aa3f 92 const int32_t MAX_FCNT_GAP = 16384; //!< Maximum allowed gap in sequence numbers before roll-over
jreiss 18:aa39c917aa3f 93
jreiss 18:aa39c917aa3f 94 const uint16_t PRIVATE_JOIN_DELAY = 1000; //!< Default join delay used for private network
jreiss 18:aa39c917aa3f 95 const uint16_t PUBLIC_JOIN_DELAY = 5000; //!< Default join delay used for public network
jreiss 18:aa39c917aa3f 96 const uint16_t DEFAULT_JOIN_DELAY = PRIVATE_JOIN_DELAY; //!< Default join delay1
jreiss 18:aa39c917aa3f 97 const uint16_t DEFAULT_RX_DELAY = 1000; //!< Default delay for first receive window
jreiss 18:aa39c917aa3f 98 const uint16_t DEFAULT_RX_TIMEOUT = 3000; //!< Default timeout for receive windows
jreiss 18:aa39c917aa3f 99
jreiss 18:aa39c917aa3f 100 const uint8_t HI_DR_SYMBOL_TIMEOUT = 12; //!< Symbol timeout for receive at datarate with SF < 11
jreiss 18:aa39c917aa3f 101 const uint8_t LO_DR_SYMBOL_TIMEOUT = 8; //!< Symbol timeout for receive at datarate with SF > 10
jreiss 18:aa39c917aa3f 102
jreiss 18:aa39c917aa3f 103 const uint16_t RX2_DELAY_OFFSET = 1000; //!< Delay between first and second window
jreiss 18:aa39c917aa3f 104 const uint16_t RXC_OFFSET = 50; //!< Time between end of RXC after TX and RX1
jreiss 18:aa39c917aa3f 105
jreiss 18:aa39c917aa3f 106 const uint8_t US915_125K_NUM_CHANS = 64; //!< Number of 125k channels in US915 channel plan
jreiss 18:aa39c917aa3f 107 const uint8_t US915_500K_NUM_CHANS = 8; //!< Number of 500k channels in US915 channel plan
jreiss 18:aa39c917aa3f 108
jreiss 18:aa39c917aa3f 109 const uint32_t US915_125K_FREQ_BASE = 902300000; //!< Frequency base for 125k US915 uplink channels
jreiss 18:aa39c917aa3f 110 const uint32_t US915_125K_FREQ_STEP = 200000; //!< Frequency step for 125k US915 uplink channels
jreiss 18:aa39c917aa3f 111
jreiss 18:aa39c917aa3f 112 const uint32_t US915_500K_FREQ_BASE = 903000000; //!< Frequency base for 500k US915 uplink channels
jreiss 18:aa39c917aa3f 113 const uint32_t US915_500K_FREQ_STEP = 1600000; //!< Frequency step for 500k US915 uplink channels
jreiss 18:aa39c917aa3f 114
jreiss 18:aa39c917aa3f 115 const uint32_t US915_500K_DBASE = 923300000; //!< Frequency base for 500k US915 downlink channels
jreiss 18:aa39c917aa3f 116 const uint32_t US915_500K_DSTEP = 600000; //!< Frequency step for 500k US915 downlink channels
jreiss 18:aa39c917aa3f 117
jreiss 18:aa39c917aa3f 118 const uint32_t US915_FREQ_MIN = 902000000;
jreiss 18:aa39c917aa3f 119 const uint32_t US915_FREQ_MAX = 928000000;
jreiss 18:aa39c917aa3f 120
jreiss 18:aa39c917aa3f 121 const uint8_t US915_MIN_DATARATE = (uint8_t) DR_0; //!< Minimum transmit datarate for US915
jreiss 18:aa39c917aa3f 122 const uint8_t US915_MAX_DATARATE = (uint8_t) DR_4; //!< Maximum transmit datarate for US915
jreiss 18:aa39c917aa3f 123
jreiss 18:aa39c917aa3f 124 const uint8_t US915_MIN_DATARATE_OFFSET = (uint8_t) 0; //!< Minimum transmit datarate for US915
jreiss 18:aa39c917aa3f 125 const uint8_t US915_MAX_DATARATE_OFFSET = (uint8_t) 3; //!< Maximum transmit datarate for US915
jreiss 18:aa39c917aa3f 126
jreiss 18:aa39c917aa3f 127 const uint8_t AU915_125K_NUM_CHANS = 64; //!< Number of 125k channels in AU915 channel plan
jreiss 18:aa39c917aa3f 128 const uint8_t AU915_500K_NUM_CHANS = 8; //!< Number of 500k channels in AU915 channel plan
jreiss 18:aa39c917aa3f 129
jreiss 18:aa39c917aa3f 130 const uint32_t AU915_125K_FREQ_BASE = 915200000; //!< Frequency base for 125k AU915 uplink channels
jreiss 18:aa39c917aa3f 131 const uint32_t AU915_125K_FREQ_STEP = 200000; //!< Frequency step for 125k AU915 uplink channels
jreiss 18:aa39c917aa3f 132
jreiss 18:aa39c917aa3f 133 const uint32_t AU915_500K_FREQ_BASE = 915900000; //!< Frequency base for 500k AU915 uplink channels
jreiss 18:aa39c917aa3f 134 const uint32_t AU915_500K_FREQ_STEP = 1600000; //!< Frequency step for 500k AU915 uplink channels
jreiss 18:aa39c917aa3f 135
jreiss 18:aa39c917aa3f 136 const uint32_t AU915_500K_DBASE = 923300000; //!< Frequency base for 500k AU915 downlink channels
jreiss 18:aa39c917aa3f 137 const uint32_t AU915_500K_DSTEP = 600000; //!< Frequency step for 500k AU915 downlink channels
jreiss 18:aa39c917aa3f 138
jreiss 18:aa39c917aa3f 139 const uint32_t AU915_FREQ_MIN = 915000000;
jreiss 18:aa39c917aa3f 140 const uint32_t AU915_FREQ_MAX = 928000000;
jreiss 18:aa39c917aa3f 141
jreiss 18:aa39c917aa3f 142 const uint8_t AU915_MIN_DATARATE = (uint8_t) DR_0; //!< Minimum transmit datarate for AU915
jreiss 18:aa39c917aa3f 143 const uint8_t AU915_MAX_DATARATE = (uint8_t) DR_4; //!< Maximum transmit datarate for AU915
jreiss 18:aa39c917aa3f 144
jreiss 18:aa39c917aa3f 145 const uint8_t AU915_MIN_DATARATE_OFFSET = (uint8_t) 0; //!< Minimum transmit datarate for AU915
jreiss 18:aa39c917aa3f 146 const uint8_t AU915_MAX_DATARATE_OFFSET = (uint8_t) 3; //!< Maximum transmit datarate for AU915
jreiss 18:aa39c917aa3f 147
jreiss 18:aa39c917aa3f 148 const uint8_t EU868_125K_NUM_CHANS = 16; //!< Number of 125k channels in EU868 channel plan
jreiss 18:aa39c917aa3f 149 const uint8_t EU868_DEFAULT_NUM_CHANS = 3; //!< Number of defualt channels in EU868 channel plan
jreiss 18:aa39c917aa3f 150 const uint32_t EU868_125K_FREQ_BASE = 868100000; //!< Frequency base for 125k EU868 uplink channels
jreiss 18:aa39c917aa3f 151 const uint32_t EU868_125K_FREQ_STEP = 200000; //!< Frequency step for 125k EU868 uplink channels
jreiss 18:aa39c917aa3f 152 const uint32_t EU868_RX2_FREQ = 869525000; //!< Frequency default for second rx window in EU868
jreiss 18:aa39c917aa3f 153
jreiss 18:aa39c917aa3f 154 const uint8_t EU868_TX_POWER_MAX = 14; //!< Max power for EU868 channel plan
jreiss 18:aa39c917aa3f 155
jreiss 18:aa39c917aa3f 156 // 0.1% duty cycle 863-868
jreiss 18:aa39c917aa3f 157 // Limiting to 865-868 allows for 1% duty cycle
jreiss 18:aa39c917aa3f 158 const uint32_t EU868_MILLI_FREQ_MIN = 865000000;
jreiss 18:aa39c917aa3f 159 const uint32_t EU868_MILLI_FREQ_MAX = 868000000;
jreiss 18:aa39c917aa3f 160
jreiss 18:aa39c917aa3f 161 const uint32_t EU868_MILLI_1_FREQ_MIN = 868700000;
jreiss 18:aa39c917aa3f 162 const uint32_t EU868_MILLI_1_FREQ_MAX = 869200000;
jreiss 18:aa39c917aa3f 163
jreiss 18:aa39c917aa3f 164 // 1% duty cycle
jreiss 18:aa39c917aa3f 165 const uint32_t EU868_CENTI_FREQ_MIN = 868000000;
jreiss 18:aa39c917aa3f 166 const uint32_t EU868_CENTI_FREQ_MAX = 868600000;
jreiss 18:aa39c917aa3f 167
jreiss 18:aa39c917aa3f 168 // 10% duty cycle
jreiss 18:aa39c917aa3f 169 const uint32_t EU868_DECI_FREQ_MIN = 869400000;
jreiss 18:aa39c917aa3f 170 const uint32_t EU868_DECI_FREQ_MAX = 869650000;
jreiss 18:aa39c917aa3f 171
jreiss 18:aa39c917aa3f 172 // Below 7dBm there is no duty cycle for these frequencies
jreiss 18:aa39c917aa3f 173 // Up to 14dBm there is 1% duty cycle
jreiss 18:aa39c917aa3f 174 const uint32_t EU868_VAR_FREQ_MIN = 869700000;
jreiss 18:aa39c917aa3f 175 const uint32_t EU868_VAR_FREQ_MAX = 870000000;
jreiss 18:aa39c917aa3f 176
jreiss 18:aa39c917aa3f 177 const uint32_t EU868_FREQ_MIN = 863000000;
jreiss 18:aa39c917aa3f 178 const uint32_t EU868_FREQ_MAX = 870000000;
jreiss 18:aa39c917aa3f 179
jreiss 18:aa39c917aa3f 180 const uint8_t EU868_MIN_DATARATE = (uint8_t) DR_0; //!< Minimum transmit datarate for EU868
jreiss 18:aa39c917aa3f 181 const uint8_t EU868_MAX_DATARATE = (uint8_t) DR_7; //!< Maximum transmit datarate for EU868
jreiss 18:aa39c917aa3f 182
jreiss 18:aa39c917aa3f 183 const uint8_t EU868_MIN_DATARATE_OFFSET = (uint8_t) 0; //!< Minimum transmit datarate for US915
jreiss 18:aa39c917aa3f 184 const uint8_t EU868_MAX_DATARATE_OFFSET = (uint8_t) 5; //!< Maximum transmit datarate for US915
jreiss 18:aa39c917aa3f 185
jreiss 18:aa39c917aa3f 186 const int16_t DEFAULT_FREE_CHAN_RSSI_THRESHOLD = -90; //!< Threshold for channel activity detection (CAD) dBm
jreiss 18:aa39c917aa3f 187
jreiss 18:aa39c917aa3f 188 const uint8_t CHAN_MASK_SIZE = 16; //!< Number of bits in a channel mask
jreiss 18:aa39c917aa3f 189 const uint8_t COMMANDS_BUFFER_SIZE = 15; //!< Size of Mac Command buffer
jreiss 18:aa39c917aa3f 190
jreiss 18:aa39c917aa3f 191 const uint8_t PKT_HEADER = 0; //!< Index to packet mHdr field
jreiss 18:aa39c917aa3f 192 const uint8_t PKT_ADDRESS = 1; //!< Index to first byte of packet address field
jreiss 18:aa39c917aa3f 193 const uint8_t PKT_FRAME_CONTROL = PKT_ADDRESS + 4; //!< Index to packet fCtrl field @see UplinkControl
jreiss 18:aa39c917aa3f 194 const uint8_t PKT_FRAME_COUNTER = PKT_FRAME_CONTROL + 1; //!< Index to packet frame counter field
jreiss 18:aa39c917aa3f 195 const uint8_t PKT_OPTIONS_START = PKT_FRAME_COUNTER + 2; //!< Index to start of optional mac commands
jreiss 18:aa39c917aa3f 196
jreiss 18:aa39c917aa3f 197 const uint8_t PKT_JOIN_APP_NONCE = 1; //!< Index to application nonce in Join Accept message
jreiss 18:aa39c917aa3f 198 const uint8_t PKT_JOIN_NETWORK_ID = 4; //!< Index to network id in Join Accept message
jreiss 18:aa39c917aa3f 199 const uint8_t PKT_JOIN_NETWORK_ADDRESS = 7; //!< Index to network address in Join Accept message
jreiss 18:aa39c917aa3f 200 const uint8_t PKT_JOIN_DL_SETTINGS = 11; //!< Index to downlink settings in Join Accept message
jreiss 18:aa39c917aa3f 201 const uint8_t PKT_JOIN_RX_DELAY = 12; //!< Index to rx delay in Join Accept message
jreiss 18:aa39c917aa3f 202
jreiss 18:aa39c917aa3f 203 const uint8_t ADR_ACK_LIMIT = 64; //!< Number of packets without ADR ACK Request
jreiss 18:aa39c917aa3f 204 const uint8_t ADR_ACK_DELAY = 32; //!< Number of packets to expect ADR ACK Response within
jreiss 18:aa39c917aa3f 205
jreiss 18:aa39c917aa3f 206 const uint16_t ACK_TIMEOUT = 2000; //!< Base millisecond timeout to resend after missed ACK
jreiss 18:aa39c917aa3f 207 const uint16_t ACK_TIMEOUT_RND = 1000; //!< Random millisecond adjustment to resend after missed ACK
jreiss 18:aa39c917aa3f 208
jreiss 18:aa39c917aa3f 209 const uint8_t FRAME_OVERHEAD = 13; //!< Bytes of network info overhead in a frame
jreiss 18:aa39c917aa3f 210
jreiss 18:aa39c917aa3f 211 /**
jreiss 18:aa39c917aa3f 212 * Settings to choose ChannelPlan
jreiss 18:aa39c917aa3f 213 */
jreiss 18:aa39c917aa3f 214 enum FrequencyBand {
jreiss 18:aa39c917aa3f 215 EU868, //!< EU 863-870 16 channel uplink
jreiss 18:aa39c917aa3f 216 US915, //!< US 902-928 64-125k/8-500k uplink and 8-500k downlink channels
jreiss 18:aa39c917aa3f 217 AU915, //!< US 915-928 64-125k/8-500k uplink and 8-500k downlink channels
jreiss 18:aa39c917aa3f 218 CN779, //!<
jreiss 18:aa39c917aa3f 219 CN470, //!<
jreiss 18:aa39c917aa3f 220 EU433, //!<
jreiss 18:aa39c917aa3f 221 };
jreiss 18:aa39c917aa3f 222
jreiss 18:aa39c917aa3f 223 /**
jreiss 18:aa39c917aa3f 224 * Settings for type of network
jreiss 18:aa39c917aa3f 225 * PUBLIC - defaults to 5/6 second join windows and 0x34 sync word
jreiss 18:aa39c917aa3f 226 * PRIVATE - defaults to 1/2 second join windows and 0x12 sync word
jreiss 18:aa39c917aa3f 227 */
jreiss 18:aa39c917aa3f 228 enum NetworkType {
jreiss 18:aa39c917aa3f 229 PRIVATE = 0,
jreiss 18:aa39c917aa3f 230 PUBLIC = 1,
jreiss 18:aa39c917aa3f 231 PEER_TO_PEER = 4
jreiss 18:aa39c917aa3f 232 };
jreiss 18:aa39c917aa3f 233
jreiss 18:aa39c917aa3f 234 /**
jreiss 18:aa39c917aa3f 235 * Enum for on/off settings
jreiss 18:aa39c917aa3f 236 */
jreiss 18:aa39c917aa3f 237 enum Enabled {
jreiss 18:aa39c917aa3f 238 OFF = 0,
jreiss 18:aa39c917aa3f 239 ON = 1
jreiss 18:aa39c917aa3f 240 };
jreiss 18:aa39c917aa3f 241
jreiss 18:aa39c917aa3f 242 /**
jreiss 18:aa39c917aa3f 243 * Return status of mac functions
jreiss 18:aa39c917aa3f 244 */
jreiss 18:aa39c917aa3f 245 enum MacStatus {
jreiss 18:aa39c917aa3f 246 LORA_OK = 0,
jreiss 18:aa39c917aa3f 247 LORA_ERROR = 1,
jreiss 18:aa39c917aa3f 248 LORA_JOIN_ERROR = 2,
jreiss 18:aa39c917aa3f 249 LORA_SEND_ERROR = 3,
jreiss 18:aa39c917aa3f 250 LORA_MIC_ERROR = 4,
jreiss 18:aa39c917aa3f 251 LORA_ADDRESS_ERROR = 5,
jreiss 18:aa39c917aa3f 252 LORA_NO_CHANS_ENABLED = 6,
jreiss 18:aa39c917aa3f 253 LORA_COMMAND_BUFFER_FULL = 7,
jreiss 18:aa39c917aa3f 254 LORA_UNKNOWN_MAC_COMMAND = 8,
jreiss 18:aa39c917aa3f 255 LORA_ADR_OFF = 9,
jreiss 18:aa39c917aa3f 256 LORA_BUSY = 10,
jreiss 18:aa39c917aa3f 257 LORA_LINK_BUSY = 11,
jreiss 18:aa39c917aa3f 258 LORA_RADIO_BUSY = 12,
jreiss 18:aa39c917aa3f 259 LORA_BUFFER_FULL = 13,
jreiss 18:aa39c917aa3f 260 LORA_JOIN_BACKOFF = 14,
jreiss 18:aa39c917aa3f 261 LORA_NO_FREE_CHAN = 15,
jreiss 18:aa39c917aa3f 262 LORA_AGGREGATED_DUTY_CYCLE = 16,
jreiss 18:aa39c917aa3f 263 LORA_MAC_COMMAND_ERROR = 17,
jreiss 18:aa39c917aa3f 264 LORA_MAX_PAYLOAD_EXCEEDED = 18
jreiss 18:aa39c917aa3f 265 };
jreiss 18:aa39c917aa3f 266
jreiss 18:aa39c917aa3f 267 /**
jreiss 18:aa39c917aa3f 268 * State for Link
jreiss 18:aa39c917aa3f 269 */
jreiss 18:aa39c917aa3f 270 enum LinkState {
jreiss 18:aa39c917aa3f 271 LINK_IDLE = 0, //!< Link ready to send or receive
jreiss 18:aa39c917aa3f 272 LINK_TX, //!< Link is busy sending
jreiss 18:aa39c917aa3f 273 LINK_ACK_TX, //!< Link is busy resending after missed ACK
jreiss 18:aa39c917aa3f 274 LINK_REP_TX, //!< Link is busy repeating
jreiss 18:aa39c917aa3f 275 LINK_RX, //!< Link has receive window open
jreiss 18:aa39c917aa3f 276 LINK_RX1, //!< Link has first received window open
jreiss 18:aa39c917aa3f 277 LINK_RX2, //!< Link has second received window open
jreiss 18:aa39c917aa3f 278 LINK_RXC, //!< Link has class C received window open
jreiss 18:aa39c917aa3f 279 LINK_P2P, //!< Link is busy sending
jreiss 18:aa39c917aa3f 280 };
jreiss 18:aa39c917aa3f 281
jreiss 18:aa39c917aa3f 282 /**
jreiss 18:aa39c917aa3f 283 * State for MAC
jreiss 18:aa39c917aa3f 284 */
jreiss 18:aa39c917aa3f 285 enum MacState {
jreiss 18:aa39c917aa3f 286 MAC_IDLE,
jreiss 18:aa39c917aa3f 287 MAC_RX1,
jreiss 18:aa39c917aa3f 288 MAC_RX2,
jreiss 18:aa39c917aa3f 289 MAC_RXC,
jreiss 18:aa39c917aa3f 290 MAC_TX,
jreiss 18:aa39c917aa3f 291 MAC_JOIN
jreiss 18:aa39c917aa3f 292 };
jreiss 18:aa39c917aa3f 293
jreiss 18:aa39c917aa3f 294 /**
jreiss 18:aa39c917aa3f 295 * Operation class for device
jreiss 18:aa39c917aa3f 296 */
jreiss 18:aa39c917aa3f 297 enum MoteClass {
jreiss 18:aa39c917aa3f 298 CLASS_A = 0x00, //!< Device can only receive in windows opened after a transmit
jreiss 18:aa39c917aa3f 299 CLASS_B = 0x01, //!< Device can receive in windows sychronized with gateway beacon
jreiss 18:aa39c917aa3f 300 CLASS_C = 0x02 //!< Device can receive any time when not transmitting
jreiss 18:aa39c917aa3f 301 };
jreiss 18:aa39c917aa3f 302
jreiss 18:aa39c917aa3f 303 /**
jreiss 18:aa39c917aa3f 304 * Direction of a packet
jreiss 18:aa39c917aa3f 305 */
jreiss 18:aa39c917aa3f 306 enum Direction {
jreiss 18:aa39c917aa3f 307 DIR_UP = 0, //!< Packet is sent from mote to gateway
jreiss 18:aa39c917aa3f 308 DIR_DOWN = 1, //!< Packet was received from gateway
jreiss 18:aa39c917aa3f 309 DIR_PEER = 2 //!< Packet was received from peer
jreiss 18:aa39c917aa3f 310 };
jreiss 18:aa39c917aa3f 311
jreiss 18:aa39c917aa3f 312
jreiss 18:aa39c917aa3f 313 /**
jreiss 18:aa39c917aa3f 314 * Received window used by Link
jreiss 18:aa39c917aa3f 315 */
jreiss 18:aa39c917aa3f 316 enum ReceiveWindows {
jreiss 18:aa39c917aa3f 317 RX_1 = 1, //!< First receive window
jreiss 18:aa39c917aa3f 318 RX_2, //!< Second receive window
jreiss 18:aa39c917aa3f 319 RX_BEACON, //!< Beacon receive window
jreiss 18:aa39c917aa3f 320 RX_SLOT, //!< Beacon Slot receive window
jreiss 18:aa39c917aa3f 321 RX_TEST
jreiss 18:aa39c917aa3f 322 };
jreiss 18:aa39c917aa3f 323
jreiss 18:aa39c917aa3f 324 /**
jreiss 18:aa39c917aa3f 325 * Datarate range for a Channel
jreiss 18:aa39c917aa3f 326 */
jreiss 18:aa39c917aa3f 327 typedef union {
jreiss 18:aa39c917aa3f 328 int8_t Value;
jreiss 18:aa39c917aa3f 329 struct {
jreiss 18:aa39c917aa3f 330 int8_t Min :4;
jreiss 18:aa39c917aa3f 331 int8_t Max :4;
jreiss 18:aa39c917aa3f 332 } Fields;
jreiss 18:aa39c917aa3f 333 } DatarateRange;
jreiss 18:aa39c917aa3f 334
jreiss 18:aa39c917aa3f 335 /**
jreiss 18:aa39c917aa3f 336 * Datarate used for transmitting and receiving
jreiss 18:aa39c917aa3f 337 */
jreiss 18:aa39c917aa3f 338 typedef struct Datarate {
jreiss 18:aa39c917aa3f 339 uint8_t Index;
jreiss 18:aa39c917aa3f 340 uint8_t Bandwidth;
jreiss 18:aa39c917aa3f 341 uint8_t Coderate;
jreiss 18:aa39c917aa3f 342 uint8_t PreambleLength;
jreiss 18:aa39c917aa3f 343 uint8_t SpreadingFactor;
jreiss 18:aa39c917aa3f 344 uint8_t Crc;
jreiss 18:aa39c917aa3f 345 uint8_t TxIQ;
jreiss 18:aa39c917aa3f 346 uint8_t RxIQ;
jreiss 18:aa39c917aa3f 347 uint8_t SymbolTimeout();
jreiss 18:aa39c917aa3f 348 Datarate();
jreiss 18:aa39c917aa3f 349 } Datarate;
jreiss 18:aa39c917aa3f 350
jreiss 18:aa39c917aa3f 351 /**
jreiss 18:aa39c917aa3f 352 * Channel used for transmitting
jreiss 18:aa39c917aa3f 353 */
jreiss 18:aa39c917aa3f 354 typedef struct {
jreiss 18:aa39c917aa3f 355 uint8_t Index;
jreiss 18:aa39c917aa3f 356 uint32_t Frequency;
jreiss 18:aa39c917aa3f 357 DatarateRange DrRange;
jreiss 18:aa39c917aa3f 358 } Channel;
jreiss 18:aa39c917aa3f 359
jreiss 18:aa39c917aa3f 360 /**
jreiss 18:aa39c917aa3f 361 * Receive window
jreiss 18:aa39c917aa3f 362 */
jreiss 18:aa39c917aa3f 363 typedef struct {
jreiss 18:aa39c917aa3f 364 uint8_t Index;
jreiss 18:aa39c917aa3f 365 uint32_t Frequency;
jreiss 18:aa39c917aa3f 366 uint8_t DatarateIndex;
jreiss 18:aa39c917aa3f 367 } RxWindow;
jreiss 18:aa39c917aa3f 368
jreiss 18:aa39c917aa3f 369 /**
jreiss 18:aa39c917aa3f 370 * Duty band for limiting time-on-air for regional regulations
jreiss 18:aa39c917aa3f 371 */
jreiss 18:aa39c917aa3f 372 typedef struct {
jreiss 18:aa39c917aa3f 373 uint8_t Index;
jreiss 18:aa39c917aa3f 374 uint32_t FrequencyMin;
jreiss 18:aa39c917aa3f 375 uint32_t FrequencyMax;
jreiss 18:aa39c917aa3f 376 uint8_t PowerMax;
jreiss 18:aa39c917aa3f 377 uint16_t DutyCycle; //!< Multiplier of time on air, 0:100%, 1:50%, 2:33%, 10:10%, 100:1%, 1000,0.1%
jreiss 18:aa39c917aa3f 378 uint32_t TimeOffEnd; //!< Timestamp when this band will be available
jreiss 18:aa39c917aa3f 379 } DutyBand;
jreiss 18:aa39c917aa3f 380
jreiss 18:aa39c917aa3f 381 /**
jreiss 18:aa39c917aa3f 382 * Device configuration
jreiss 18:aa39c917aa3f 383 */
jreiss 18:aa39c917aa3f 384 typedef struct {
jreiss 18:aa39c917aa3f 385 uint8_t FrequencyBand; //!< Used to choose ChannelPlan
jreiss 18:aa39c917aa3f 386 uint8_t EUI[8]; //!< Unique identifier assigned to device
jreiss 18:aa39c917aa3f 387 } DeviceConfig;
jreiss 18:aa39c917aa3f 388
jreiss 18:aa39c917aa3f 389 /**
jreiss 18:aa39c917aa3f 390 * Network configuration
jreiss 18:aa39c917aa3f 391 */
jreiss 18:aa39c917aa3f 392 typedef struct {
jreiss 18:aa39c917aa3f 393 uint8_t Mode; //!< PUBLIC, PRIVATE or PEER_TO_PEER network mode
jreiss 18:aa39c917aa3f 394 uint8_t Class; //!< Operating class of device
jreiss 18:aa39c917aa3f 395 uint8_t EUI[8]; //!< Network ID or AppEUI
jreiss 18:aa39c917aa3f 396 uint8_t Key[16]; //!< Network Key or AppKey
jreiss 18:aa39c917aa3f 397 uint8_t JoinDelay; //!< Number of seconds to wait before 1st RX Window
jreiss 18:aa39c917aa3f 398 uint8_t RxDelay; //!< Number of seconds to wait before 1st RX Window
jreiss 18:aa39c917aa3f 399 uint8_t ChannelGroup; //!< ChannelGroup used for US915 hybrid operation 0:72 channels, 1:1-8 channels ...
jreiss 18:aa39c917aa3f 400 uint8_t AckAttempts; //!< Number of attempts to send packet and receive an ACK from server
jreiss 18:aa39c917aa3f 401 uint8_t Retries; //!< Number of times to resend a packet without receiving an ACK, redundancy
jreiss 18:aa39c917aa3f 402 uint8_t ADREnabled; //!< Enable adaptive datarate
jreiss 18:aa39c917aa3f 403 uint8_t CADEnabled; //!< Enable listen before talk/channel activity detection
jreiss 18:aa39c917aa3f 404 uint8_t RepeaterMode; //!< Limit payloads to repeater compatible sizes
jreiss 18:aa39c917aa3f 405 uint8_t TxPower; //!< Default radio output power in dBm
jreiss 18:aa39c917aa3f 406 uint8_t TxPowerMax; //!< Max transmit power
jreiss 18:aa39c917aa3f 407 uint8_t TxDatarate; //!< Datarate for P2P transmit
jreiss 18:aa39c917aa3f 408 uint32_t TxFrequency; //!< Frequency for P2P transmit
jreiss 18:aa39c917aa3f 409 int8_t AntennaGain; //!< Antenna Gain
jreiss 18:aa39c917aa3f 410 uint8_t DisableEncryption; //!< Disable Encryption
jreiss 18:aa39c917aa3f 411 uint8_t DisableCRC; //!< Disable CRC on uplink packets
jreiss 18:aa39c917aa3f 412 uint16_t P2PACKTimeout;
jreiss 18:aa39c917aa3f 413 uint16_t P2PACKBackoff;
jreiss 18:aa39c917aa3f 414 uint8_t JoinRx1DatarateOffset; //!< Offset for datarate for first window
jreiss 18:aa39c917aa3f 415 uint32_t JoinRx2Frequency; //!< Frequency used in second window
jreiss 18:aa39c917aa3f 416 uint8_t JoinRx2DatarateIndex; //!< Datarate for second window
jreiss 18:aa39c917aa3f 417 } NetworkConfig;
jreiss 18:aa39c917aa3f 418
jreiss 18:aa39c917aa3f 419 /**
jreiss 18:aa39c917aa3f 420 * Network session info
jreiss 18:aa39c917aa3f 421 * Some settings are acquired in join message and others may be changed through Mac Commands from server
jreiss 18:aa39c917aa3f 422 */
jreiss 18:aa39c917aa3f 423 typedef struct {
jreiss 18:aa39c917aa3f 424 uint8_t Joined; //!< State of session
jreiss 18:aa39c917aa3f 425 uint8_t Rx1DatarateOffset; //!< Offset for datarate for first window
jreiss 18:aa39c917aa3f 426 uint32_t Rx2Frequency; //!< Frequency used in second window
jreiss 18:aa39c917aa3f 427 uint8_t Rx2DatarateIndex; //!< Datarate for second window
jreiss 18:aa39c917aa3f 428 uint8_t TxPower; //!< Current total radiated output power in dBm
jreiss 18:aa39c917aa3f 429 uint8_t TxDatarate; //!< Current datarate can be changed when ADR is enabled
jreiss 18:aa39c917aa3f 430 uint32_t Address; //!< Network address
jreiss 18:aa39c917aa3f 431 uint32_t NetworkID; //!< Network ID 24-bits
jreiss 18:aa39c917aa3f 432 uint8_t NetworkSessionKey[16]; //!< Network session key
jreiss 18:aa39c917aa3f 433 uint8_t ApplicationSessionKey[16]; //!< Data session key
jreiss 18:aa39c917aa3f 434 uint16_t ChannelMask[4]; //!< Current channel mask
jreiss 18:aa39c917aa3f 435 uint16_t ChannelMask500k; //!< Current channel mask for 500k channels
jreiss 18:aa39c917aa3f 436 uint32_t DownlinkCounter; //!< Downlink counter of last packet received from server
jreiss 18:aa39c917aa3f 437 uint32_t UplinkCounter; //!< Uplink counter of last packet received from server
jreiss 18:aa39c917aa3f 438 uint8_t Redundancy; //!< Number of time to repeat an uplink
jreiss 18:aa39c917aa3f 439 uint8_t MaxDutyCycle; //!< Current Max Duty Cycle value
jreiss 18:aa39c917aa3f 440 uint32_t JoinTimeOnAir; //!< Balance of time on air used during join attempts
jreiss 18:aa39c917aa3f 441 uint32_t JoinTimeOffEnd; //!< RTC time of next join attempt
jreiss 18:aa39c917aa3f 442 uint32_t JoinFirstAttempt; //!< RTC time of first failed join attempt
jreiss 18:aa39c917aa3f 443 uint32_t AggregatedTimeOffEnd; //!< Time off air expiration for aggregate duty cycle
jreiss 18:aa39c917aa3f 444 uint16_t AggregateDutyCycle; //!< Used for enforcing time-on-air
jreiss 18:aa39c917aa3f 445 uint8_t AckCounter; //!< Current number of packets sent without ACK from server
jreiss 18:aa39c917aa3f 446 uint8_t AdrCounter; //!< Current number of packets received without downlink from server
jreiss 18:aa39c917aa3f 447 uint8_t RxDelay; //!< Number of seconds to wait before 1st RX Window
jreiss 18:aa39c917aa3f 448 uint8_t CommandBuffer[COMMANDS_BUFFER_SIZE]; //!< Buffer to hold Mac Commands and parameters to be sent in next packet
jreiss 18:aa39c917aa3f 449 uint8_t CommandBufferIndex; //!< Index to place next Mac Command, also current size of Command Buffer
jreiss 18:aa39c917aa3f 450 bool SrvRequestedAck; //!< Indicator of ACK requested by server in last packet received
jreiss 18:aa39c917aa3f 451 bool DataPending; //!< Indicator of data pending at server
jreiss 18:aa39c917aa3f 452 uint8_t RxTimingSetupReqReceived; //!< Indicator that RxTimingSetupAns should be included in uplink
jreiss 18:aa39c917aa3f 453 uint8_t RxParamSetupReqAnswer; //!< Indicator that RxParamSetupAns should be included in uplink
jreiss 18:aa39c917aa3f 454 } NetworkSession;
jreiss 18:aa39c917aa3f 455
jreiss 18:aa39c917aa3f 456 /**
jreiss 18:aa39c917aa3f 457 * Multicast session info
jreiss 18:aa39c917aa3f 458 */
jreiss 18:aa39c917aa3f 459 typedef struct {
jreiss 18:aa39c917aa3f 460 uint32_t Address; //!< Network address
jreiss 18:aa39c917aa3f 461 uint8_t NetworkSessionKey[16]; //!< Network session key
jreiss 18:aa39c917aa3f 462 uint8_t DataSessionKey[16]; //!< Data session key
jreiss 18:aa39c917aa3f 463 uint32_t DownlinkCounter; //!< Downlink counter of last packet received from server
jreiss 18:aa39c917aa3f 464 } MulticastSession;
jreiss 18:aa39c917aa3f 465
jreiss 18:aa39c917aa3f 466 /**
jreiss 18:aa39c917aa3f 467 * Application configuration
jreiss 18:aa39c917aa3f 468 */
jreiss 18:aa39c917aa3f 469 typedef struct {
jreiss 18:aa39c917aa3f 470 uint8_t Port; //!< Port used by application
jreiss 18:aa39c917aa3f 471 uint8_t AppEUI; //!< Application ID
jreiss 18:aa39c917aa3f 472 uint8_t AppKey[16]; //!< Application Key
jreiss 18:aa39c917aa3f 473 } ApplicationConfig;
jreiss 18:aa39c917aa3f 474
jreiss 18:aa39c917aa3f 475 /**
jreiss 18:aa39c917aa3f 476 * Statistics of current network session
jreiss 18:aa39c917aa3f 477 */
jreiss 18:aa39c917aa3f 478 typedef struct Statistics {
jreiss 18:aa39c917aa3f 479 uint32_t Up; //!< Number of uplink packets sent
jreiss 18:aa39c917aa3f 480 uint32_t Down; //!< Number of downlink packets received
jreiss 18:aa39c917aa3f 481 uint32_t Joins; //!< Number of join requests sent
jreiss 18:aa39c917aa3f 482 uint32_t JoinFails; //!< Number of join requests without response or invalid response
jreiss 18:aa39c917aa3f 483 uint32_t MissedAcks; //!< Number of missed acknowledgement attempts of confirmed packets
jreiss 18:aa39c917aa3f 484 uint32_t CRCErrors; //!< Number of CRC errors in received packets
jreiss 18:aa39c917aa3f 485 int32_t AvgCount; //!< Number of packets used to compute rolling average of RSSI and SNR
jreiss 18:aa39c917aa3f 486 int16_t Rssi; //!< RSSI of last packet received
jreiss 18:aa39c917aa3f 487 int16_t RssiMin; //!< Minimum RSSI of last AvgCount packets
jreiss 18:aa39c917aa3f 488 int16_t RssiMax; //!< Maximum RSSI of last AvgCount packets
jreiss 18:aa39c917aa3f 489 int16_t RssiAvg; //!< Rolling average RSSI of last AvgCount packets
jreiss 18:aa39c917aa3f 490 int16_t Snr; //!< SNR of last packet received
jreiss 18:aa39c917aa3f 491 int16_t SnrMin; //!< Minimum SNR of last AvgCount packets
jreiss 18:aa39c917aa3f 492 int16_t SnrMax; //!< Maximum SNR of last AvgCount packets
jreiss 18:aa39c917aa3f 493 int16_t SnrAvg; //!< Rolling average SNR of last AvgCount packets
jreiss 18:aa39c917aa3f 494 } Statistics;
jreiss 18:aa39c917aa3f 495
jreiss 18:aa39c917aa3f 496 /**
jreiss 18:aa39c917aa3f 497 * Testing settings
jreiss 18:aa39c917aa3f 498 */
jreiss 18:aa39c917aa3f 499 typedef struct {
jreiss 18:aa39c917aa3f 500 uint8_t TestMode;
jreiss 18:aa39c917aa3f 501 uint8_t SkipMICCheck;
jreiss 18:aa39c917aa3f 502 uint8_t DisableDutyCycle;
jreiss 18:aa39c917aa3f 503 uint8_t DisableRx1;
jreiss 18:aa39c917aa3f 504 uint8_t DisableRx2;
jreiss 18:aa39c917aa3f 505 uint8_t FixedUplinkCounter;
jreiss 18:aa39c917aa3f 506 uint8_t DisableRandomJoinDatarate;
jreiss 18:aa39c917aa3f 507 } Testing;
jreiss 18:aa39c917aa3f 508
jreiss 18:aa39c917aa3f 509 /**
jreiss 18:aa39c917aa3f 510 * Combination of device, network, testing settings and statistics
jreiss 18:aa39c917aa3f 511 */
jreiss 18:aa39c917aa3f 512 typedef struct {
jreiss 18:aa39c917aa3f 513 DeviceConfig Device;
jreiss 18:aa39c917aa3f 514 NetworkConfig Network;
jreiss 18:aa39c917aa3f 515 NetworkSession Session;
jreiss 18:aa39c917aa3f 516 ApplicationConfig Applications[MAX_APPS];
jreiss 18:aa39c917aa3f 517 MulticastSession Multicast[MAX_MULTICAST_SESSIONS];
jreiss 18:aa39c917aa3f 518 Statistics Stats;
jreiss 18:aa39c917aa3f 519 Testing Test;
jreiss 18:aa39c917aa3f 520 } Settings;
jreiss 18:aa39c917aa3f 521
jreiss 18:aa39c917aa3f 522 /**
jreiss 18:aa39c917aa3f 523 * Downlink settings sent in Join Accept message
jreiss 18:aa39c917aa3f 524 */
jreiss 18:aa39c917aa3f 525 typedef union {
jreiss 18:aa39c917aa3f 526 uint8_t Value;
jreiss 18:aa39c917aa3f 527 struct {
jreiss 18:aa39c917aa3f 528 uint8_t Rx2Datarate :4;
jreiss 18:aa39c917aa3f 529 uint8_t Rx1Offset :3;
jreiss 18:aa39c917aa3f 530 uint8_t RFU :1;
jreiss 18:aa39c917aa3f 531 };
jreiss 18:aa39c917aa3f 532 } DownlinkSettings;
jreiss 18:aa39c917aa3f 533
jreiss 18:aa39c917aa3f 534 /**
jreiss 18:aa39c917aa3f 535 * Frame structure for Join Request
jreiss 18:aa39c917aa3f 536 */
jreiss 18:aa39c917aa3f 537 typedef struct {
jreiss 18:aa39c917aa3f 538 uint8_t Type;
jreiss 18:aa39c917aa3f 539 uint8_t AppEUI[8];
jreiss 18:aa39c917aa3f 540 uint8_t DevEUI[8];
jreiss 18:aa39c917aa3f 541 uint8_t Nonce[2];
jreiss 18:aa39c917aa3f 542 uint8_t MIC[4];
jreiss 18:aa39c917aa3f 543 } JoinRequestFrame;
jreiss 18:aa39c917aa3f 544
jreiss 18:aa39c917aa3f 545 /**
jreiss 18:aa39c917aa3f 546 * Mac header of uplink and downlink packets
jreiss 18:aa39c917aa3f 547 */
jreiss 18:aa39c917aa3f 548 typedef union {
jreiss 18:aa39c917aa3f 549 uint8_t Value;
jreiss 18:aa39c917aa3f 550 struct {
jreiss 18:aa39c917aa3f 551 uint8_t Major :2;
jreiss 18:aa39c917aa3f 552 uint8_t RFU :3;
jreiss 18:aa39c917aa3f 553 uint8_t MType :3;
jreiss 18:aa39c917aa3f 554 } Bits;
jreiss 18:aa39c917aa3f 555 } MacHeader;
jreiss 18:aa39c917aa3f 556
jreiss 18:aa39c917aa3f 557 /**
jreiss 18:aa39c917aa3f 558 * Frame control field of uplink packets
jreiss 18:aa39c917aa3f 559 */
jreiss 18:aa39c917aa3f 560 typedef union {
jreiss 18:aa39c917aa3f 561 uint8_t Value;
jreiss 18:aa39c917aa3f 562 struct {
jreiss 18:aa39c917aa3f 563 uint8_t OptionsLength :4;
jreiss 18:aa39c917aa3f 564 uint8_t ClassB :1;
jreiss 18:aa39c917aa3f 565 uint8_t Ack :1;
jreiss 18:aa39c917aa3f 566 uint8_t AdrAckReq :1;
jreiss 18:aa39c917aa3f 567 uint8_t Adr :1;
jreiss 18:aa39c917aa3f 568 } Bits;
jreiss 18:aa39c917aa3f 569 } UplinkControl;
jreiss 18:aa39c917aa3f 570
jreiss 18:aa39c917aa3f 571 /**
jreiss 18:aa39c917aa3f 572 * Frame control field of downlink packets
jreiss 18:aa39c917aa3f 573 */
jreiss 18:aa39c917aa3f 574 typedef union {
jreiss 18:aa39c917aa3f 575 uint8_t Value;
jreiss 18:aa39c917aa3f 576 struct {
jreiss 18:aa39c917aa3f 577 uint8_t OptionsLength :4;
jreiss 18:aa39c917aa3f 578 uint8_t FPending :1;
jreiss 18:aa39c917aa3f 579 uint8_t Ack :1;
jreiss 18:aa39c917aa3f 580 uint8_t RFU :1;
jreiss 18:aa39c917aa3f 581 uint8_t Adr :1;
jreiss 18:aa39c917aa3f 582 } Bits;
jreiss 18:aa39c917aa3f 583 } DownlinkControl;
jreiss 18:aa39c917aa3f 584
jreiss 18:aa39c917aa3f 585 /**
jreiss 18:aa39c917aa3f 586 * Frame type of packet
jreiss 18:aa39c917aa3f 587 */
jreiss 18:aa39c917aa3f 588 typedef enum {
jreiss 18:aa39c917aa3f 589 FRAME_TYPE_JOIN_REQ = 0x00,
jreiss 18:aa39c917aa3f 590 FRAME_TYPE_JOIN_ACCEPT = 0x01,
jreiss 18:aa39c917aa3f 591 FRAME_TYPE_DATA_UNCONFIRMED_UP = 0x02,
jreiss 18:aa39c917aa3f 592 FRAME_TYPE_DATA_UNCONFIRMED_DOWN = 0x03,
jreiss 18:aa39c917aa3f 593 FRAME_TYPE_DATA_CONFIRMED_UP = 0x04,
jreiss 18:aa39c917aa3f 594 FRAME_TYPE_DATA_CONFIRMED_DOWN = 0x05,
jreiss 18:aa39c917aa3f 595 FRAME_TYPE_RFU = 0x06,
jreiss 18:aa39c917aa3f 596 FRAME_TYPE_PROPRIETARY = 0x07,
jreiss 18:aa39c917aa3f 597 } FrameType;
jreiss 18:aa39c917aa3f 598
jreiss 18:aa39c917aa3f 599 /**
jreiss 18:aa39c917aa3f 600 * LoRaWAN mote MAC commands
jreiss 18:aa39c917aa3f 601 */
jreiss 18:aa39c917aa3f 602 typedef enum {
jreiss 18:aa39c917aa3f 603 /* Class A */
jreiss 18:aa39c917aa3f 604 MOTE_MAC_LINK_CHECK_REQ = 0x02,
jreiss 18:aa39c917aa3f 605 MOTE_MAC_LINK_ADR_ANS = 0x03,
jreiss 18:aa39c917aa3f 606 MOTE_MAC_DUTY_CYCLE_ANS = 0x04,
jreiss 18:aa39c917aa3f 607 MOTE_MAC_RX_PARAM_SETUP_ANS = 0x05,
jreiss 18:aa39c917aa3f 608 MOTE_MAC_DEV_STATUS_ANS = 0x06,
jreiss 18:aa39c917aa3f 609 MOTE_MAC_NEW_CHANNEL_ANS = 0x07,
jreiss 18:aa39c917aa3f 610 MOTE_MAC_RX_TIMING_SETUP_ANS = 0x08,
jreiss 18:aa39c917aa3f 611
jreiss 18:aa39c917aa3f 612 /* Class B */
jreiss 18:aa39c917aa3f 613 MOTE_MAC_PING_SLOT_INFO_REQ = 0x09,
jreiss 18:aa39c917aa3f 614 MOTE_MAC_PING_SLOT_FREQ_ANS = 0x0a,
jreiss 18:aa39c917aa3f 615 MOTE_MAC_PING_SLOT_CHANNEL_ANS = 0x0a,
jreiss 18:aa39c917aa3f 616 MOTE_MAC_BEACON_TIMING_REQ = 0x0b,
jreiss 18:aa39c917aa3f 617 MOTE_MAC_BEACON_FREQ_ANS = 0x0c,
jreiss 18:aa39c917aa3f 618
jreiss 18:aa39c917aa3f 619 /* Multitech */
jreiss 18:aa39c917aa3f 620 MOTE_MAC_PING_REQ = 0x80,
jreiss 18:aa39c917aa3f 621 MOTE_MAC_CHANGE_CLASS = 0x81,
jreiss 18:aa39c917aa3f 622 MOTE_MAC_MULTIPART_START_REQ = 0x82,
jreiss 18:aa39c917aa3f 623 MOTE_MAC_MULTIPART_START_ANS = 0x83,
jreiss 18:aa39c917aa3f 624 MOTE_MAC_MULTIPART_CHUNK = 0x84,
jreiss 18:aa39c917aa3f 625 MOTE_MAC_MULTIPART_END_REQ = 0x85,
jreiss 18:aa39c917aa3f 626 MOTE_MAC_MULTIPART_END_ANS = 0x86
jreiss 18:aa39c917aa3f 627 } MoteCommand;
jreiss 18:aa39c917aa3f 628
jreiss 18:aa39c917aa3f 629 /*!
jreiss 18:aa39c917aa3f 630 * LoRaWAN server MAC commands
jreiss 18:aa39c917aa3f 631 */
jreiss 18:aa39c917aa3f 632 typedef enum {
jreiss 18:aa39c917aa3f 633 /* Class A */
jreiss 18:aa39c917aa3f 634 SRV_MAC_LINK_CHECK_ANS = 0x02,
jreiss 18:aa39c917aa3f 635 SRV_MAC_LINK_ADR_REQ = 0x03,
jreiss 18:aa39c917aa3f 636 SRV_MAC_DUTY_CYCLE_REQ = 0x04,
jreiss 18:aa39c917aa3f 637 SRV_MAC_RX_PARAM_SETUP_REQ = 0x05,
jreiss 18:aa39c917aa3f 638 SRV_MAC_DEV_STATUS_REQ = 0x06,
jreiss 18:aa39c917aa3f 639 SRV_MAC_NEW_CHANNEL_REQ = 0x07,
jreiss 18:aa39c917aa3f 640 SRV_MAC_RX_TIMING_SETUP_REQ = 0x08,
jreiss 18:aa39c917aa3f 641
jreiss 18:aa39c917aa3f 642 /* Class B */
jreiss 18:aa39c917aa3f 643 SRV_MAC_PING_SLOT_INFO_ANS = 0x09,
jreiss 18:aa39c917aa3f 644 SRV_MAC_PING_SLOT_FREQ_REQ = 0x0a,
jreiss 18:aa39c917aa3f 645 SRV_MAC_PING_SLOT_CHANNEL_REQ = 0x0a,
jreiss 18:aa39c917aa3f 646 SRV_MAC_BEACON_TIMING_ANS = 0x0b,
jreiss 18:aa39c917aa3f 647 SRV_MAC_BEACON_FREQ_REQ = 0x0c,
jreiss 18:aa39c917aa3f 648
jreiss 18:aa39c917aa3f 649 /* Multitech */
jreiss 18:aa39c917aa3f 650 SRV_MAC_PING_ANS = 0x80,
jreiss 18:aa39c917aa3f 651 SRV_MAC_CHANGE_CLASS = 0x81,
jreiss 18:aa39c917aa3f 652 SRV_MAC_MULTIPART_START_REQ = 0x82,
jreiss 18:aa39c917aa3f 653 SRV_MAC_MULTIPART_START_ANS = 0x83,
jreiss 18:aa39c917aa3f 654 SRV_MAC_MULTIPART_CHUNK = 0x84,
jreiss 18:aa39c917aa3f 655 SRV_MAC_MULTIPART_END_REQ = 0x85,
jreiss 18:aa39c917aa3f 656 SRV_MAC_MULTIPART_END_ANS = 0x86
jreiss 18:aa39c917aa3f 657 } ServerCommand;
jreiss 18:aa39c917aa3f 658
jreiss 18:aa39c917aa3f 659 /**
jreiss 18:aa39c917aa3f 660 * Random seed for software RNG
jreiss 18:aa39c917aa3f 661 */
jreiss 18:aa39c917aa3f 662 void srand(uint32_t seed);
jreiss 18:aa39c917aa3f 663
jreiss 18:aa39c917aa3f 664 /**
jreiss 18:aa39c917aa3f 665 * Software RNG for consistent results across differing hardware
jreiss 18:aa39c917aa3f 666 */
jreiss 18:aa39c917aa3f 667 int rand(void);
jreiss 18:aa39c917aa3f 668
jreiss 18:aa39c917aa3f 669 /**
jreiss 18:aa39c917aa3f 670 * Generate random number bounded by min and max
jreiss 18:aa39c917aa3f 671 */
jreiss 18:aa39c917aa3f 672 int32_t rand_r(int32_t min, int32_t max);
jreiss 18:aa39c917aa3f 673
jreiss 18:aa39c917aa3f 674 uint8_t CountBits(uint16_t mask);
jreiss 18:aa39c917aa3f 675
jreiss 18:aa39c917aa3f 676 /**
jreiss 18:aa39c917aa3f 677 * Copy 3-bytes network order from array into LSB of integer value
jreiss 18:aa39c917aa3f 678 */
jreiss 18:aa39c917aa3f 679 void CopyNetIDtoInt(const uint8_t* arr, uint32_t& val);
jreiss 18:aa39c917aa3f 680
jreiss 18:aa39c917aa3f 681 /**
jreiss 18:aa39c917aa3f 682 * Copy LSB 3-bytes from integer value into array network order
jreiss 18:aa39c917aa3f 683 */
jreiss 18:aa39c917aa3f 684 void CopyNetIDtoArray(uint32_t val, uint8_t* arr);
jreiss 18:aa39c917aa3f 685
jreiss 18:aa39c917aa3f 686 /**
jreiss 18:aa39c917aa3f 687 * Copy 4-bytes network order from array in to integer value
jreiss 18:aa39c917aa3f 688 */
jreiss 18:aa39c917aa3f 689 void CopyAddrtoInt(const uint8_t* arr, uint32_t& val);
jreiss 18:aa39c917aa3f 690
jreiss 18:aa39c917aa3f 691 /**
jreiss 18:aa39c917aa3f 692 * Copy 4-bytes from integer in to array network order
jreiss 18:aa39c917aa3f 693 */
jreiss 18:aa39c917aa3f 694 void CopyAddrtoArray(uint32_t val, uint8_t* arr);
jreiss 18:aa39c917aa3f 695
jreiss 18:aa39c917aa3f 696 /**
jreiss 18:aa39c917aa3f 697 * Copy 3-bytes network order from array into integer value and multiply by 100
jreiss 18:aa39c917aa3f 698 */
jreiss 18:aa39c917aa3f 699 void CopyFreqtoInt(const uint8_t* arr, uint32_t& freq);
jreiss 18:aa39c917aa3f 700
jreiss 18:aa39c917aa3f 701 /**
jreiss 18:aa39c917aa3f 702 * Reverse memory copy
jreiss 18:aa39c917aa3f 703 */
jreiss 18:aa39c917aa3f 704 void memcpy_r(uint8_t *dst, const uint8_t *src, size_t n);
jreiss 18:aa39c917aa3f 705
jreiss 18:aa39c917aa3f 706 }
jreiss 18:aa39c917aa3f 707
jreiss 18:aa39c917aa3f 708 #endif
jreiss 18:aa39c917aa3f 709
jreiss 15:b50f92f1c6ff 710