
send GPS uplinks in Cayenne LPP format
Dependencies: lib_gps lorawan1v1
radio chip selection
Radio chip driver is not included, because two options are available.
If you're using SX1272 or SX1276, then import sx127x driver into your program.
if you're using SX1261 or SX1262, then import sx126x driver into your program.
If you're using NAmote72 or Murata discovery, then you must import only sx127x driver.
See LoRaWAN library page for provisioning onto network: Commissioning.h
Connection To GPS Receiver
This demonstration depends on GPS receiver sending NMEA into one of the UART on your target CPU.
Such as GP-20U7.
Sends uplink in cayenne LPP format.
Connection to NUCLEO form factor
Jumper for auto-uplink: PC6->PC8 = CN10-2->CN10-4
name | connector pin | CPU pin |
Vdd | CN7-5 | |
Gnd | CN7-8 | |
UART | CN7-2 | PC11 |
Connection to DISCO_L072CZ_LRWAN1
Jumper for auto-uplink: PA11->PA12 = CN3-14->CN3-15
name | connector pin | CPU pin |
Vdd | CN3-5 | |
Gnd | CN3-6 | |
UART | CN3-21 | PA10 |
main.cpp@2:fdd36ff9b181, 2018-05-24 (annotated)
- Committer:
- Wayne Roberts
- Date:
- Thu May 24 18:03:26 2018 -0700
- Revision:
- 2:fdd36ff9b181
- Parent:
- 0:d467d869e49c
add gps time to status display
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Wayne Roberts |
0:d467d869e49c | 1 | /* |
Wayne Roberts |
0:d467d869e49c | 2 | / _____) _ | | |
Wayne Roberts |
0:d467d869e49c | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ |
Wayne Roberts |
0:d467d869e49c | 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ |
Wayne Roberts |
0:d467d869e49c | 5 | _____) ) ____| | | || |_| ____( (___| | | | |
Wayne Roberts |
0:d467d869e49c | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| |
Wayne Roberts |
0:d467d869e49c | 7 | (C)2018 Semtech |
Wayne Roberts |
0:d467d869e49c | 8 | |
Wayne Roberts |
0:d467d869e49c | 9 | Description: LoRaMac classB device implementation |
Wayne Roberts |
0:d467d869e49c | 10 | |
Wayne Roberts |
0:d467d869e49c | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project |
Wayne Roberts |
0:d467d869e49c | 12 | |
Wayne Roberts |
0:d467d869e49c | 13 | */ |
Wayne Roberts |
0:d467d869e49c | 14 | |
Wayne Roberts |
0:d467d869e49c | 15 | #include "LoRaMac1v1.h" |
Wayne Roberts |
0:d467d869e49c | 16 | #include "LoRaMacString.h" |
Wayne Roberts |
0:d467d869e49c | 17 | #include "gps.h" |
Wayne Roberts |
0:d467d869e49c | 18 | |
Wayne Roberts |
0:d467d869e49c | 19 | /*! |
Wayne Roberts |
0:d467d869e49c | 20 | * Defines the application data transmission duty cycle. 5s, value in [ms]. |
Wayne Roberts |
0:d467d869e49c | 21 | */ |
Wayne Roberts |
0:d467d869e49c | 22 | #define APP_TX_DUTYCYCLE_us 8000000 |
Wayne Roberts |
0:d467d869e49c | 23 | |
Wayne Roberts |
0:d467d869e49c | 24 | /*! |
Wayne Roberts |
0:d467d869e49c | 25 | * Defines a random delay for application data transmission duty cycle. 1s, |
Wayne Roberts |
0:d467d869e49c | 26 | * value in [ms]. |
Wayne Roberts |
0:d467d869e49c | 27 | */ |
Wayne Roberts |
0:d467d869e49c | 28 | #define APP_TX_DUTYCYCLE_RND_us 2000000 |
Wayne Roberts |
0:d467d869e49c | 29 | |
Wayne Roberts |
0:d467d869e49c | 30 | /*! |
Wayne Roberts |
0:d467d869e49c | 31 | * Default datarate |
Wayne Roberts |
0:d467d869e49c | 32 | */ |
Wayne Roberts |
0:d467d869e49c | 33 | |
Wayne Roberts |
0:d467d869e49c | 34 | #if defined( USE_BAND_ARIB_8CH ) |
Wayne Roberts |
0:d467d869e49c | 35 | #define LORAWAN_DEFAULT_DATARATE DR_3 |
Wayne Roberts |
0:d467d869e49c | 36 | #else |
Wayne Roberts |
0:d467d869e49c | 37 | #define LORAWAN_DEFAULT_DATARATE DR_0 |
Wayne Roberts |
0:d467d869e49c | 38 | #endif |
Wayne Roberts |
0:d467d869e49c | 39 | |
Wayne Roberts |
0:d467d869e49c | 40 | /*! |
Wayne Roberts |
0:d467d869e49c | 41 | * LoRaWAN confirmed messages |
Wayne Roberts |
0:d467d869e49c | 42 | */ |
Wayne Roberts |
0:d467d869e49c | 43 | #define LORAWAN_CONFIRMED_MSG_ON false |
Wayne Roberts |
0:d467d869e49c | 44 | |
Wayne Roberts |
0:d467d869e49c | 45 | /*! |
Wayne Roberts |
0:d467d869e49c | 46 | * LoRaWAN Adaptive Data Rate |
Wayne Roberts |
0:d467d869e49c | 47 | * |
Wayne Roberts |
0:d467d869e49c | 48 | * \remark Please note that when ADR is enabled the end-device should be static |
Wayne Roberts |
0:d467d869e49c | 49 | */ |
Wayne Roberts |
0:d467d869e49c | 50 | #define LORAWAN_ADR_ON 1 |
Wayne Roberts |
0:d467d869e49c | 51 | |
Wayne Roberts |
0:d467d869e49c | 52 | #if defined( USE_BAND_868 ) |
Wayne Roberts |
0:d467d869e49c | 53 | |
Wayne Roberts |
0:d467d869e49c | 54 | /*! |
Wayne Roberts |
0:d467d869e49c | 55 | * LoRaWAN ETSI duty cycle control enable/disable |
Wayne Roberts |
0:d467d869e49c | 56 | * |
Wayne Roberts |
0:d467d869e49c | 57 | * \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes |
Wayne Roberts |
0:d467d869e49c | 58 | */ |
Wayne Roberts |
0:d467d869e49c | 59 | #define LORAWAN_DUTYCYCLE_ON false |
Wayne Roberts |
0:d467d869e49c | 60 | |
Wayne Roberts |
0:d467d869e49c | 61 | #define USE_SEMTECH_DEFAULT_CHANNEL_LINEUP 1 |
Wayne Roberts |
0:d467d869e49c | 62 | |
Wayne Roberts |
0:d467d869e49c | 63 | #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 ) |
Wayne Roberts |
0:d467d869e49c | 64 | |
Wayne Roberts |
0:d467d869e49c | 65 | #define LC4 { 867100000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
Wayne Roberts |
0:d467d869e49c | 66 | #define LC5 { 867300000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
Wayne Roberts |
0:d467d869e49c | 67 | #define LC6 { 867500000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
Wayne Roberts |
0:d467d869e49c | 68 | #define LC7 { 867700000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
Wayne Roberts |
0:d467d869e49c | 69 | #define LC8 { 867900000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
Wayne Roberts |
0:d467d869e49c | 70 | #define LC9 { 868800000, { ( ( DR_7 << 4 ) | DR_7 ) }, 2 } |
Wayne Roberts |
0:d467d869e49c | 71 | #define LC10 { 868300000, { ( ( DR_6 << 4 ) | DR_6 ) }, 1 } |
Wayne Roberts |
0:d467d869e49c | 72 | |
Wayne Roberts |
0:d467d869e49c | 73 | #endif |
Wayne Roberts |
0:d467d869e49c | 74 | |
Wayne Roberts |
0:d467d869e49c | 75 | #endif |
Wayne Roberts |
0:d467d869e49c | 76 | |
Wayne Roberts |
0:d467d869e49c | 77 | /*! |
Wayne Roberts |
0:d467d869e49c | 78 | * LoRaWAN application port |
Wayne Roberts |
0:d467d869e49c | 79 | */ |
Wayne Roberts |
0:d467d869e49c | 80 | #define LORAWAN_APP_PORT 2 |
Wayne Roberts |
0:d467d869e49c | 81 | |
Wayne Roberts |
0:d467d869e49c | 82 | /*! |
Wayne Roberts |
0:d467d869e49c | 83 | * User application data buffer size |
Wayne Roberts |
0:d467d869e49c | 84 | */ |
Wayne Roberts |
0:d467d869e49c | 85 | #define LORAWAN_APP_DATA_SIZE 3 |
Wayne Roberts |
0:d467d869e49c | 86 | |
Wayne Roberts |
0:d467d869e49c | 87 | |
Wayne Roberts |
0:d467d869e49c | 88 | #ifdef LORAWAN_JOIN_EUI |
Wayne Roberts |
0:d467d869e49c | 89 | static uint8_t DevEui[] = LORAWAN_DEVICE_EUI; |
Wayne Roberts |
0:d467d869e49c | 90 | static const uint8_t JoinEui[] = LORAWAN_JOIN_EUI; |
Wayne Roberts |
0:d467d869e49c | 91 | static const uint8_t NwkKey[] = LORAWAN_ROOT_NWKKEY; |
Wayne Roberts |
0:d467d869e49c | 92 | #ifdef LORAWAN_ROOT_APPKEY |
Wayne Roberts |
0:d467d869e49c | 93 | static const uint8_t AppKey[] = LORAWAN_ROOT_APPKEY; |
Wayne Roberts |
0:d467d869e49c | 94 | #endif |
Wayne Roberts |
0:d467d869e49c | 95 | #else |
Wayne Roberts |
0:d467d869e49c | 96 | static const uint8_t FNwkSIntKey[] = LORAWAN_FNwkSIntKey; |
Wayne Roberts |
0:d467d869e49c | 97 | static const uint8_t AppSKey[] = LORAWAN_APPSKEY; |
Wayne Roberts |
0:d467d869e49c | 98 | static const uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS; |
Wayne Roberts |
0:d467d869e49c | 99 | #if defined(LORAWAN_SNwkSIntKey) && defined(LORAWAN_NwkSEncKey) |
Wayne Roberts |
0:d467d869e49c | 100 | static const uint8_t SNwkSIntKey[] = LORAWAN_SNwkSIntKey; |
Wayne Roberts |
0:d467d869e49c | 101 | static const uint8_t NwkSEncKey[] = LORAWAN_NwkSEncKey; |
Wayne Roberts |
0:d467d869e49c | 102 | #endif |
Wayne Roberts |
0:d467d869e49c | 103 | #endif |
Wayne Roberts |
0:d467d869e49c | 104 | |
Wayne Roberts |
0:d467d869e49c | 105 | |
Wayne Roberts |
0:d467d869e49c | 106 | #ifdef TARGET_DISCO_L072CZ_LRWAN1 |
Wayne Roberts |
0:d467d869e49c | 107 | #define GREEN LED1 |
Wayne Roberts |
0:d467d869e49c | 108 | #define RED2 LED2 |
Wayne Roberts |
0:d467d869e49c | 109 | #define BLUE LED3 |
Wayne Roberts |
0:d467d869e49c | 110 | #define RED4 LED4 |
Wayne Roberts |
0:d467d869e49c | 111 | DigitalOut blue(BLUE); |
Wayne Roberts |
0:d467d869e49c | 112 | #define LED_ON 1 |
Wayne Roberts |
0:d467d869e49c | 113 | #define LED_OFF 0 |
Wayne Roberts |
0:d467d869e49c | 114 | #endif /* TARGET_DISCO_L072CZ_LRWAN1 */ |
Wayne Roberts |
0:d467d869e49c | 115 | /*! |
Wayne Roberts |
0:d467d869e49c | 116 | * Application port |
Wayne Roberts |
0:d467d869e49c | 117 | */ |
Wayne Roberts |
0:d467d869e49c | 118 | static uint8_t AppPort = LORAWAN_APP_PORT; |
Wayne Roberts |
0:d467d869e49c | 119 | |
Wayne Roberts |
0:d467d869e49c | 120 | /*! |
Wayne Roberts |
0:d467d869e49c | 121 | * User application data size |
Wayne Roberts |
0:d467d869e49c | 122 | */ |
Wayne Roberts |
0:d467d869e49c | 123 | static uint8_t gAppDataSize = LORAWAN_APP_DATA_SIZE; |
Wayne Roberts |
0:d467d869e49c | 124 | |
Wayne Roberts |
0:d467d869e49c | 125 | /*! |
Wayne Roberts |
0:d467d869e49c | 126 | * User application data buffer size |
Wayne Roberts |
0:d467d869e49c | 127 | */ |
Wayne Roberts |
0:d467d869e49c | 128 | #define LORAWAN_APP_DATA_MAX_SIZE 64 |
Wayne Roberts |
0:d467d869e49c | 129 | |
Wayne Roberts |
0:d467d869e49c | 130 | /*! |
Wayne Roberts |
0:d467d869e49c | 131 | * User application data |
Wayne Roberts |
0:d467d869e49c | 132 | */ |
Wayne Roberts |
0:d467d869e49c | 133 | static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE]; |
Wayne Roberts |
0:d467d869e49c | 134 | |
Wayne Roberts |
0:d467d869e49c | 135 | /*! |
Wayne Roberts |
0:d467d869e49c | 136 | * Indicates if the node is sending confirmed or unconfirmed messages |
Wayne Roberts |
0:d467d869e49c | 137 | */ |
Wayne Roberts |
0:d467d869e49c | 138 | static uint8_t gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON; |
Wayne Roberts |
0:d467d869e49c | 139 | |
Wayne Roberts |
0:d467d869e49c | 140 | /*! |
Wayne Roberts |
0:d467d869e49c | 141 | * Timer to handle the application data transmission duty cycle |
Wayne Roberts |
0:d467d869e49c | 142 | * |
Wayne Roberts |
0:d467d869e49c | 143 | */ |
Wayne Roberts |
0:d467d869e49c | 144 | LowPowerTimeout tx_timeout; |
Wayne Roberts |
0:d467d869e49c | 145 | |
Wayne Roberts |
0:d467d869e49c | 146 | /*! |
Wayne Roberts |
0:d467d869e49c | 147 | * Indicates if a new packet can be sent |
Wayne Roberts |
0:d467d869e49c | 148 | */ |
Wayne Roberts |
0:d467d869e49c | 149 | static volatile struct { |
Wayne Roberts |
0:d467d869e49c | 150 | uint8_t startup : 1; |
Wayne Roberts |
0:d467d869e49c | 151 | uint8_t ackDownlink : 1; |
Wayne Roberts |
0:d467d869e49c | 152 | } flags; |
Wayne Roberts |
0:d467d869e49c | 153 | |
Wayne Roberts |
0:d467d869e49c | 154 | /*! |
Wayne Roberts |
0:d467d869e49c | 155 | * Device states |
Wayne Roberts |
0:d467d869e49c | 156 | */ |
Wayne Roberts |
0:d467d869e49c | 157 | volatile enum eDevicState |
Wayne Roberts |
0:d467d869e49c | 158 | { |
Wayne Roberts |
0:d467d869e49c | 159 | /* 0 */ DEVICE_STATE_INIT = 0, |
Wayne Roberts |
0:d467d869e49c | 160 | /* 1 */ DEVICE_STATE_SEND, |
Wayne Roberts |
0:d467d869e49c | 161 | /* 2 */ DEVICE_STATE_SLEEP, |
Wayne Roberts |
0:d467d869e49c | 162 | #ifdef LORAWAN_JOIN_EUI |
Wayne Roberts |
0:d467d869e49c | 163 | /* 3 */ DEVICE_STATE_JOIN, |
Wayne Roberts |
0:d467d869e49c | 164 | /* 4 */ DEVICE_STATE_JOIN_OK |
Wayne Roberts |
0:d467d869e49c | 165 | #endif /* LORAWAN_JOIN_EUI */ |
Wayne Roberts |
0:d467d869e49c | 166 | } DeviceState, WakeUpState; |
Wayne Roberts |
0:d467d869e49c | 167 | |
Wayne Roberts |
0:d467d869e49c | 168 | #if defined(TARGET_MOTE_L152RC) && !defined(TARGET_FF_ARDUINO) |
Wayne Roberts |
0:d467d869e49c | 169 | #define TARGET_FF_ARDUINO |
Wayne Roberts |
0:d467d869e49c | 170 | #endif |
Wayne Roberts |
0:d467d869e49c | 171 | |
Wayne Roberts |
0:d467d869e49c | 172 | #if defined(TARGET_FF_ARDUINO) |
Wayne Roberts |
0:d467d869e49c | 173 | #ifdef TARGET_DISCO_L072CZ_LRWAN1 |
Wayne Roberts |
0:d467d869e49c | 174 | #define LED_GREEN LED1 |
Wayne Roberts |
0:d467d869e49c | 175 | #define LED_RED2 LED2 // next to LD7 |
Wayne Roberts |
0:d467d869e49c | 176 | #define LED_BLUE LED3 |
Wayne Roberts |
0:d467d869e49c | 177 | #define LED_RED4 LED4 |
Wayne Roberts |
0:d467d869e49c | 178 | InterruptIn button_pin(USER_BUTTON); |
Wayne Roberts |
0:d467d869e49c | 179 | #define BUTTON_PRESSED 0 |
Wayne Roberts |
0:d467d869e49c | 180 | DigitalOut extLed(LED_RED4); |
Wayne Roberts |
0:d467d869e49c | 181 | #else |
Wayne Roberts |
0:d467d869e49c | 182 | InterruptIn button_pin(D8); |
Wayne Roberts |
0:d467d869e49c | 183 | #define BUTTON_PRESSED 1 |
Wayne Roberts |
0:d467d869e49c | 184 | DigitalOut extLed(D15); |
Wayne Roberts |
0:d467d869e49c | 185 | #endif |
Wayne Roberts |
0:d467d869e49c | 186 | #endif /* TARGET_FF_ARDUINO */ |
Wayne Roberts |
0:d467d869e49c | 187 | |
Wayne Roberts |
0:d467d869e49c | 188 | #define JUMPER_ENABLE |
Wayne Roberts |
0:d467d869e49c | 189 | |
Wayne Roberts |
0:d467d869e49c | 190 | #if defined(JUMPER_ENABLE) |
Wayne Roberts |
0:d467d869e49c | 191 | #define TX_INTERVAL_US 15000000 |
Wayne Roberts |
0:d467d869e49c | 192 | #if defined(TARGET_FF_MORPHO) |
Wayne Roberts |
0:d467d869e49c | 193 | #ifdef TARGET_DISCO_L072CZ_LRWAN1 |
Wayne Roberts |
0:d467d869e49c | 194 | DigitalOut jumper_out(PA_11); |
Wayne Roberts |
0:d467d869e49c | 195 | InterruptIn jumper_in(PA_12); |
Wayne Roberts |
0:d467d869e49c | 196 | #else |
Wayne Roberts |
0:d467d869e49c | 197 | DigitalOut jumper_out(PC_8); |
Wayne Roberts |
0:d467d869e49c | 198 | InterruptIn jumper_in(PC_6); |
Wayne Roberts |
0:d467d869e49c | 199 | #endif |
Wayne Roberts |
0:d467d869e49c | 200 | #endif /* TARGET_FF_MORPHO */ |
Wayne Roberts |
0:d467d869e49c | 201 | #endif /* JUMPER_ENABLE */ |
Wayne Roberts |
0:d467d869e49c | 202 | |
Wayne Roberts |
0:d467d869e49c | 203 | uint8_t c_ch; |
Wayne Roberts |
0:d467d869e49c | 204 | us_timestamp_t buttonStartAt; |
Wayne Roberts |
0:d467d869e49c | 205 | |
Wayne Roberts |
0:d467d869e49c | 206 | #ifdef TARGET_FF_MORPHO |
Wayne Roberts |
0:d467d869e49c | 207 | /* https://www.sparkfun.com/products/13740 */ |
Wayne Roberts |
0:d467d869e49c | 208 | #ifdef TARGET_DISCO_L072CZ_LRWAN1 |
Wayne Roberts |
0:d467d869e49c | 209 | GPS gps(PA_9, PA_10, NC); |
Wayne Roberts |
0:d467d869e49c | 210 | #else |
Wayne Roberts |
0:d467d869e49c | 211 | GPS gps(PC_10, PC_11, NC); |
Wayne Roberts |
0:d467d869e49c | 212 | #endif |
Wayne Roberts |
0:d467d869e49c | 213 | #endif /* TARGET_FF_MORPHO */ |
Wayne Roberts |
0:d467d869e49c | 214 | |
Wayne Roberts |
0:d467d869e49c | 215 | /*! |
Wayne Roberts |
0:d467d869e49c | 216 | * LoRaWAN compliance tests support data |
Wayne Roberts |
0:d467d869e49c | 217 | */ |
Wayne Roberts |
0:d467d869e49c | 218 | struct ComplianceTest_s |
Wayne Roberts |
0:d467d869e49c | 219 | { |
Wayne Roberts |
0:d467d869e49c | 220 | bool Running; |
Wayne Roberts |
0:d467d869e49c | 221 | uint8_t State; |
Wayne Roberts |
0:d467d869e49c | 222 | bool IsTxConfirmed; |
Wayne Roberts |
0:d467d869e49c | 223 | uint8_t AppPort; |
Wayne Roberts |
0:d467d869e49c | 224 | uint8_t AppDataSize; |
Wayne Roberts |
0:d467d869e49c | 225 | uint8_t *AppDataBuffer; |
Wayne Roberts |
0:d467d869e49c | 226 | uint16_t DownLinkCounter; |
Wayne Roberts |
0:d467d869e49c | 227 | bool LinkCheck; |
Wayne Roberts |
0:d467d869e49c | 228 | uint8_t DemodMargin; |
Wayne Roberts |
0:d467d869e49c | 229 | uint8_t NbGateways; |
Wayne Roberts |
0:d467d869e49c | 230 | }ComplianceTest; |
Wayne Roberts |
0:d467d869e49c | 231 | |
Wayne Roberts |
0:d467d869e49c | 232 | #ifdef JUMPER_ENABLE |
Wayne Roberts |
0:d467d869e49c | 233 | void autoUplink() |
Wayne Roberts |
0:d467d869e49c | 234 | { |
Wayne Roberts |
0:d467d869e49c | 235 | if (jumper_in.read() == 1) { |
Wayne Roberts |
0:d467d869e49c | 236 | tx_timeout.attach_us(autoUplink, TX_INTERVAL_US); |
Wayne Roberts |
0:d467d869e49c | 237 | } |
Wayne Roberts |
0:d467d869e49c | 238 | |
Wayne Roberts |
0:d467d869e49c | 239 | c_ch = 0xff; |
Wayne Roberts |
0:d467d869e49c | 240 | DeviceState = DEVICE_STATE_SEND; |
Wayne Roberts |
0:d467d869e49c | 241 | } |
Wayne Roberts |
0:d467d869e49c | 242 | |
Wayne Roberts |
0:d467d869e49c | 243 | void jumper_callback() |
Wayne Roberts |
0:d467d869e49c | 244 | { |
Wayne Roberts |
0:d467d869e49c | 245 | tx_timeout.attach_us(autoUplink, TX_INTERVAL_US); |
Wayne Roberts |
0:d467d869e49c | 246 | } |
Wayne Roberts |
0:d467d869e49c | 247 | #endif /* JUMPER_ENABLE */ |
Wayne Roberts |
0:d467d869e49c | 248 | |
Wayne Roberts |
0:d467d869e49c | 249 | |
Wayne Roberts |
0:d467d869e49c | 250 | #define LPP_DIGITAL_INPUT 0 // 1 byte |
Wayne Roberts |
0:d467d869e49c | 251 | #define LPP_DIGITAL_OUTPUT 1 // 1 byte |
Wayne Roberts |
0:d467d869e49c | 252 | #define LPP_ANALOG_INPUT 2 // 2 bytes, 0.01 signed |
Wayne Roberts |
0:d467d869e49c | 253 | #define LPP_ANALOG_OUTPUT 3 // 2 bytes, 0.01 signed |
Wayne Roberts |
0:d467d869e49c | 254 | #define LPP_LUMINOSITY 101 // 2 bytes, 1 lux unsigned |
Wayne Roberts |
0:d467d869e49c | 255 | #define LPP_PRESENCE 102 // 1 byte, 1 |
Wayne Roberts |
0:d467d869e49c | 256 | #define LPP_TEMPERATURE 103 // 2 bytes, 0.1°C signed |
Wayne Roberts |
0:d467d869e49c | 257 | #define LPP_RELATIVE_HUMIDITY 104 // 1 byte, 0.5% unsigned |
Wayne Roberts |
0:d467d869e49c | 258 | #define LPP_ACCELEROMETER 113 // 2 bytes per axis, 0.001G |
Wayne Roberts |
0:d467d869e49c | 259 | #define LPP_BAROMETRIC_PRESSURE 115 // 2 bytes 0.1 hPa Unsigned |
Wayne Roberts |
0:d467d869e49c | 260 | #define LPP_GYROMETER 134 // 2 bytes per axis, 0.01 °/s |
Wayne Roberts |
0:d467d869e49c | 261 | #define LPP_GPS 136 // 3 byte lon/lat 0.0001 °, 3 bytes alt 0.01m |
Wayne Roberts |
0:d467d869e49c | 262 | |
Wayne Roberts |
0:d467d869e49c | 263 | |
Wayne Roberts |
0:d467d869e49c | 264 | // Data ID + Data Type + Data Size |
Wayne Roberts |
0:d467d869e49c | 265 | #define LPP_DIGITAL_INPUT_SIZE 3 |
Wayne Roberts |
0:d467d869e49c | 266 | #define LPP_DIGITAL_OUTPUT_SIZE 3 |
Wayne Roberts |
0:d467d869e49c | 267 | #define LPP_ANALOG_INPUT_SIZE 4 |
Wayne Roberts |
0:d467d869e49c | 268 | #define LPP_ANALOG_OUTPUT_SIZE 4 |
Wayne Roberts |
0:d467d869e49c | 269 | #define LPP_LUMINOSITY_SIZE 4 |
Wayne Roberts |
0:d467d869e49c | 270 | #define LPP_PRESENCE_SIZE 3 |
Wayne Roberts |
0:d467d869e49c | 271 | #define LPP_TEMPERATURE_SIZE 4 |
Wayne Roberts |
0:d467d869e49c | 272 | #define LPP_RELATIVE_HUMIDITY_SIZE 3 |
Wayne Roberts |
0:d467d869e49c | 273 | #define LPP_ACCELEROMETER_SIZE 8 |
Wayne Roberts |
0:d467d869e49c | 274 | #define LPP_BAROMETRIC_PRESSURE_SIZE 4 |
Wayne Roberts |
0:d467d869e49c | 275 | #define LPP_GYROMETER_SIZE 8 |
Wayne Roberts |
0:d467d869e49c | 276 | #define LPP_GPS_SIZE 11 |
Wayne Roberts |
0:d467d869e49c | 277 | |
Wayne Roberts |
0:d467d869e49c | 278 | #define CAYENNE_CH_GPS 5 |
Wayne Roberts |
0:d467d869e49c | 279 | |
Wayne Roberts |
0:d467d869e49c | 280 | /*! |
Wayne Roberts |
0:d467d869e49c | 281 | * \brief Prepares the payload of the frame |
Wayne Roberts |
0:d467d869e49c | 282 | */ |
Wayne Roberts |
0:d467d869e49c | 283 | static void PrepareTxFrame( uint8_t port ) |
Wayne Roberts |
0:d467d869e49c | 284 | { |
Wayne Roberts |
0:d467d869e49c | 285 | int32_t lat, lon, alt; |
Wayne Roberts |
0:d467d869e49c | 286 | |
Wayne Roberts |
0:d467d869e49c | 287 | while (button_pin.read() == BUTTON_PRESSED) { |
Wayne Roberts |
0:d467d869e49c | 288 | us_timestamp_t duration = LoRaMacReadTimer() - buttonStartAt; |
Wayne Roberts |
0:d467d869e49c | 289 | if (duration > 1000000) { |
Wayne Roberts |
0:d467d869e49c | 290 | gAppDataSize = 0; |
Wayne Roberts |
0:d467d869e49c | 291 | AppData[gAppDataSize++] = 0; |
Wayne Roberts |
0:d467d869e49c | 292 | return; |
Wayne Roberts |
0:d467d869e49c | 293 | } |
Wayne Roberts |
0:d467d869e49c | 294 | } |
Wayne Roberts |
0:d467d869e49c | 295 | |
Wayne Roberts |
0:d467d869e49c | 296 | gps.service(); |
Wayne Roberts |
0:d467d869e49c | 297 | |
Wayne Roberts |
0:d467d869e49c | 298 | lat = gps.Latitude * 10000; |
Wayne Roberts |
0:d467d869e49c | 299 | lon = gps.Longitude * 10000; |
Wayne Roberts |
0:d467d869e49c | 300 | alt = atoi(gps.NmeaGpsData.NmeaAltitude) * 100; |
Wayne Roberts |
0:d467d869e49c | 301 | |
Wayne Roberts |
0:d467d869e49c | 302 | gAppDataSize = 0; |
Wayne Roberts |
0:d467d869e49c | 303 | AppData[gAppDataSize++] = CAYENNE_CH_GPS; |
Wayne Roberts |
0:d467d869e49c | 304 | AppData[gAppDataSize++] = LPP_GPS; |
Wayne Roberts |
0:d467d869e49c | 305 | AppData[gAppDataSize++] = lat >> 16; |
Wayne Roberts |
0:d467d869e49c | 306 | AppData[gAppDataSize++] = lat >> 8; |
Wayne Roberts |
0:d467d869e49c | 307 | AppData[gAppDataSize++] = lat; |
Wayne Roberts |
0:d467d869e49c | 308 | AppData[gAppDataSize++] = lon >> 16; |
Wayne Roberts |
0:d467d869e49c | 309 | AppData[gAppDataSize++] = lon >> 8; |
Wayne Roberts |
0:d467d869e49c | 310 | AppData[gAppDataSize++] = lon; |
Wayne Roberts |
0:d467d869e49c | 311 | AppData[gAppDataSize++] = alt >> 16; |
Wayne Roberts |
0:d467d869e49c | 312 | AppData[gAppDataSize++] = alt >> 8; |
Wayne Roberts |
0:d467d869e49c | 313 | AppData[gAppDataSize++] = alt; |
Wayne Roberts |
0:d467d869e49c | 314 | } |
Wayne Roberts |
0:d467d869e49c | 315 | |
Wayne Roberts |
0:d467d869e49c | 316 | |
Wayne Roberts |
0:d467d869e49c | 317 | /*! |
Wayne Roberts |
0:d467d869e49c | 318 | * \brief Prepares the payload of the frame |
Wayne Roberts |
0:d467d869e49c | 319 | * |
Wayne Roberts |
0:d467d869e49c | 320 | * \retval [0: frame could be send, 1: error] |
Wayne Roberts |
0:d467d869e49c | 321 | */ |
Wayne Roberts |
0:d467d869e49c | 322 | static LoRaMacStatus_t SendFrame(bool IsTxConfirmed, uint8_t AppDataSize) |
Wayne Roberts |
0:d467d869e49c | 323 | { |
Wayne Roberts |
0:d467d869e49c | 324 | LoRaMacStatus_t status; |
Wayne Roberts |
0:d467d869e49c | 325 | char str[64]; |
Wayne Roberts |
0:d467d869e49c | 326 | McpsReq_t mcpsReq; |
Wayne Roberts |
0:d467d869e49c | 327 | LoRaMacTxInfo_t txInfo; |
Wayne Roberts |
0:d467d869e49c | 328 | |
Wayne Roberts |
0:d467d869e49c | 329 | if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK ) |
Wayne Roberts |
0:d467d869e49c | 330 | { |
Wayne Roberts |
0:d467d869e49c | 331 | // Send empty frame in order to flush MAC commands |
Wayne Roberts |
0:d467d869e49c | 332 | mcpsReq.Type = MCPS_UNCONFIRMED; |
Wayne Roberts |
0:d467d869e49c | 333 | mcpsReq.Req.fBuffer = NULL; |
Wayne Roberts |
0:d467d869e49c | 334 | mcpsReq.Req.fBufferSize = 0; |
Wayne Roberts |
0:d467d869e49c | 335 | mcpsReq.Req.Datarate = LORAWAN_DEFAULT_DATARATE; |
Wayne Roberts |
0:d467d869e49c | 336 | } |
Wayne Roberts |
0:d467d869e49c | 337 | else |
Wayne Roberts |
0:d467d869e49c | 338 | { |
Wayne Roberts |
0:d467d869e49c | 339 | if( IsTxConfirmed == false ) |
Wayne Roberts |
0:d467d869e49c | 340 | { |
Wayne Roberts |
0:d467d869e49c | 341 | mcpsReq.Type = MCPS_UNCONFIRMED; |
Wayne Roberts |
0:d467d869e49c | 342 | mcpsReq.Req.fPort = AppPort; |
Wayne Roberts |
0:d467d869e49c | 343 | mcpsReq.Req.fBuffer = AppData; |
Wayne Roberts |
0:d467d869e49c | 344 | mcpsReq.Req.fBufferSize = AppDataSize; |
Wayne Roberts |
0:d467d869e49c | 345 | mcpsReq.Req.Datarate = LORAWAN_DEFAULT_DATARATE; |
Wayne Roberts |
0:d467d869e49c | 346 | } |
Wayne Roberts |
0:d467d869e49c | 347 | else |
Wayne Roberts |
0:d467d869e49c | 348 | { |
Wayne Roberts |
0:d467d869e49c | 349 | mcpsReq.Type = MCPS_CONFIRMED; |
Wayne Roberts |
0:d467d869e49c | 350 | mcpsReq.Req.fPort = AppPort; |
Wayne Roberts |
0:d467d869e49c | 351 | mcpsReq.Req.fBuffer = AppData; |
Wayne Roberts |
0:d467d869e49c | 352 | mcpsReq.Req.fBufferSize = AppDataSize; |
Wayne Roberts |
0:d467d869e49c | 353 | mcpsReq.Req.Datarate = LORAWAN_DEFAULT_DATARATE; |
Wayne Roberts |
0:d467d869e49c | 354 | } |
Wayne Roberts |
0:d467d869e49c | 355 | } |
Wayne Roberts |
0:d467d869e49c | 356 | |
Wayne Roberts |
0:d467d869e49c | 357 | status = LoRaMacMcpsRequest( &mcpsReq ); |
Wayne Roberts |
0:d467d869e49c | 358 | if (status == LORAMAC_STATUS_OK) { |
Wayne Roberts |
0:d467d869e49c | 359 | APP_PRINTF("sendFrame() OK "); |
Wayne Roberts |
0:d467d869e49c | 360 | if (mcpsReq.Req.fBufferSize > 0) { |
Wayne Roberts |
0:d467d869e49c | 361 | APP_PRINTF("FPort%u ", mcpsReq.Req.fPort); |
Wayne Roberts |
0:d467d869e49c | 362 | print_buf(AppData, mcpsReq.Req.fBufferSize, "uplink"); |
Wayne Roberts |
0:d467d869e49c | 363 | } |
Wayne Roberts |
0:d467d869e49c | 364 | } else { |
Wayne Roberts |
0:d467d869e49c | 365 | LoRaMacStatus_to_string(status, str); |
Wayne Roberts |
0:d467d869e49c | 366 | APP_PRINTF("sendFrame() \e[31m%s rx%d\r\n", str, LoRaMacGetRxSlot()); |
Wayne Roberts |
0:d467d869e49c | 367 | } |
Wayne Roberts |
0:d467d869e49c | 368 | |
Wayne Roberts |
0:d467d869e49c | 369 | return status; |
Wayne Roberts |
0:d467d869e49c | 370 | } // ..SendFrame() |
Wayne Roberts |
0:d467d869e49c | 371 | |
Wayne Roberts |
0:d467d869e49c | 372 | #define ACK_DEFER_US 800000 |
Wayne Roberts |
0:d467d869e49c | 373 | void ack_isr() |
Wayne Roberts |
0:d467d869e49c | 374 | { |
Wayne Roberts |
0:d467d869e49c | 375 | SendFrame(false, 0); |
Wayne Roberts |
0:d467d869e49c | 376 | } |
Wayne Roberts |
0:d467d869e49c | 377 | |
Wayne Roberts |
0:d467d869e49c | 378 | /*! |
Wayne Roberts |
0:d467d869e49c | 379 | * \brief MCPS-Confirm event function |
Wayne Roberts |
0:d467d869e49c | 380 | * |
Wayne Roberts |
0:d467d869e49c | 381 | * \param [IN] mcpsConfirm - Pointer to the confirm structure, |
Wayne Roberts |
0:d467d869e49c | 382 | * containing confirm attributes. |
Wayne Roberts |
0:d467d869e49c | 383 | */ |
Wayne Roberts |
0:d467d869e49c | 384 | static void McpsConfirm( const McpsConfirm_t *mcpsConfirm ) |
Wayne Roberts |
0:d467d869e49c | 385 | { |
Wayne Roberts |
0:d467d869e49c | 386 | char str[64]; |
Wayne Roberts |
0:d467d869e49c | 387 | |
Wayne Roberts |
0:d467d869e49c | 388 | APP_PRINTF("McpsConfirm up:%" PRIu32 "hz ", mcpsConfirm->UpLinkFreqHz); |
Wayne Roberts |
0:d467d869e49c | 389 | LoRaMacEventInfoStatus_to_string(mcpsConfirm->Status, str); |
Wayne Roberts |
0:d467d869e49c | 390 | if (mcpsConfirm->AckReceived) |
Wayne Roberts |
0:d467d869e49c | 391 | APP_PRINTF("Ack "); |
Wayne Roberts |
0:d467d869e49c | 392 | APP_PRINTF("dr%u FCntUp:%" PRIu32 " ", mcpsConfirm->Datarate, mcpsConfirm->UpLinkCounter); |
Wayne Roberts |
0:d467d869e49c | 393 | if (mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) { |
Wayne Roberts |
0:d467d869e49c | 394 | APP_PRINTF("%s\r\n", str); |
Wayne Roberts |
0:d467d869e49c | 395 | } else { |
Wayne Roberts |
0:d467d869e49c | 396 | APP_PRINTF("\e[31m%s\e[0m\r\n", str); |
Wayne Roberts |
0:d467d869e49c | 397 | } |
Wayne Roberts |
0:d467d869e49c | 398 | |
Wayne Roberts |
0:d467d869e49c | 399 | if (mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) |
Wayne Roberts |
0:d467d869e49c | 400 | { |
Wayne Roberts |
0:d467d869e49c | 401 | switch( mcpsConfirm->McpsRequest ) |
Wayne Roberts |
0:d467d869e49c | 402 | { |
Wayne Roberts |
0:d467d869e49c | 403 | case MCPS_UNCONFIRMED: |
Wayne Roberts |
0:d467d869e49c | 404 | { |
Wayne Roberts |
0:d467d869e49c | 405 | // Check Datarate |
Wayne Roberts |
0:d467d869e49c | 406 | // Check TxPower |
Wayne Roberts |
0:d467d869e49c | 407 | break; |
Wayne Roberts |
0:d467d869e49c | 408 | } |
Wayne Roberts |
0:d467d869e49c | 409 | case MCPS_CONFIRMED: |
Wayne Roberts |
0:d467d869e49c | 410 | { |
Wayne Roberts |
0:d467d869e49c | 411 | // Check Datarate |
Wayne Roberts |
0:d467d869e49c | 412 | // Check TxPower |
Wayne Roberts |
0:d467d869e49c | 413 | // Check AckReceived |
Wayne Roberts |
0:d467d869e49c | 414 | // Check NbTrials |
Wayne Roberts |
0:d467d869e49c | 415 | //LoRaMacUplinkStatus.Acked = mcpsConfirm->AckReceived; |
Wayne Roberts |
0:d467d869e49c | 416 | break; |
Wayne Roberts |
0:d467d869e49c | 417 | } |
Wayne Roberts |
0:d467d869e49c | 418 | case MCPS_PROPRIETARY: |
Wayne Roberts |
0:d467d869e49c | 419 | { |
Wayne Roberts |
0:d467d869e49c | 420 | break; |
Wayne Roberts |
0:d467d869e49c | 421 | } |
Wayne Roberts |
0:d467d869e49c | 422 | default: |
Wayne Roberts |
0:d467d869e49c | 423 | break; |
Wayne Roberts |
0:d467d869e49c | 424 | } |
Wayne Roberts |
0:d467d869e49c | 425 | DeviceState = DEVICE_STATE_SLEEP; |
Wayne Roberts |
0:d467d869e49c | 426 | } else { |
Wayne Roberts |
0:d467d869e49c | 427 | /* fail */ |
Wayne Roberts |
0:d467d869e49c | 428 | DeviceState = DEVICE_STATE_SLEEP; |
Wayne Roberts |
0:d467d869e49c | 429 | |
Wayne Roberts |
0:d467d869e49c | 430 | #if 0 |
Wayne Roberts |
0:d467d869e49c | 431 | if (flags.startup && mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT) { |
Wayne Roberts |
0:d467d869e49c | 432 | } |
Wayne Roberts |
0:d467d869e49c | 433 | #endif /* if 0 */ |
Wayne Roberts |
0:d467d869e49c | 434 | } |
Wayne Roberts |
0:d467d869e49c | 435 | |
Wayne Roberts |
0:d467d869e49c | 436 | } // ..McpsConfirm() |
Wayne Roberts |
0:d467d869e49c | 437 | |
Wayne Roberts |
0:d467d869e49c | 438 | |
Wayne Roberts |
0:d467d869e49c | 439 | /*! |
Wayne Roberts |
0:d467d869e49c | 440 | * \brief MCPS-Indication event function |
Wayne Roberts |
0:d467d869e49c | 441 | * |
Wayne Roberts |
0:d467d869e49c | 442 | * \param [IN] mcpsIndication - Pointer to the indication structure, |
Wayne Roberts |
0:d467d869e49c | 443 | * containing indication attributes. |
Wayne Roberts |
0:d467d869e49c | 444 | */ |
Wayne Roberts |
0:d467d869e49c | 445 | static void McpsIndication( const McpsIndication_t *mcpsIndication ) |
Wayne Roberts |
0:d467d869e49c | 446 | { |
Wayne Roberts |
0:d467d869e49c | 447 | char str[64]; |
Wayne Roberts |
0:d467d869e49c | 448 | int8_t Snr; |
Wayne Roberts |
0:d467d869e49c | 449 | |
Wayne Roberts |
0:d467d869e49c | 450 | APP_PRINTF("McpsIndication rx%d ADR_ACK_CNT:%u ", mcpsIndication->RxSlot, mcpsIndication->ADR_ACK_CNT); |
Wayne Roberts |
0:d467d869e49c | 451 | |
Wayne Roberts |
0:d467d869e49c | 452 | if (mcpsIndication->Snr & 0x80) { // The SNR sign bit is 1 |
Wayne Roberts |
0:d467d869e49c | 453 | // Invert and divide by 4 |
Wayne Roberts |
0:d467d869e49c | 454 | Snr = ( ( ~mcpsIndication->Snr + 1 ) & 0xFF ) >> 2; |
Wayne Roberts |
0:d467d869e49c | 455 | Snr = -Snr; |
Wayne Roberts |
0:d467d869e49c | 456 | } else { |
Wayne Roberts |
0:d467d869e49c | 457 | // Divide by 4 |
Wayne Roberts |
0:d467d869e49c | 458 | Snr = ( mcpsIndication->Snr & 0xFF ) >> 2; |
Wayne Roberts |
0:d467d869e49c | 459 | } |
Wayne Roberts |
0:d467d869e49c | 460 | |
Wayne Roberts |
0:d467d869e49c | 461 | if (mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK) |
Wayne Roberts |
0:d467d869e49c | 462 | { |
Wayne Roberts |
0:d467d869e49c | 463 | LoRaMacEventInfoStatus_to_string(mcpsIndication->Status, str); |
Wayne Roberts |
0:d467d869e49c | 464 | APP_PRINTF("\e[31m%s\e[0m\r\n", str); |
Wayne Roberts |
0:d467d869e49c | 465 | return; |
Wayne Roberts |
0:d467d869e49c | 466 | } |
Wayne Roberts |
0:d467d869e49c | 467 | APP_PRINTF("OK Snr:%d FCntDown:%u\r\n", Snr, mcpsIndication->receivedFCntDown); |
Wayne Roberts |
0:d467d869e49c | 468 | |
Wayne Roberts |
0:d467d869e49c | 469 | switch( mcpsIndication->McpsIndication ) |
Wayne Roberts |
0:d467d869e49c | 470 | { |
Wayne Roberts |
0:d467d869e49c | 471 | case MCPS_UNCONFIRMED: |
Wayne Roberts |
0:d467d869e49c | 472 | { |
Wayne Roberts |
0:d467d869e49c | 473 | break; |
Wayne Roberts |
0:d467d869e49c | 474 | } |
Wayne Roberts |
0:d467d869e49c | 475 | case MCPS_CONFIRMED: |
Wayne Roberts |
0:d467d869e49c | 476 | { |
Wayne Roberts |
0:d467d869e49c | 477 | if (flags.ackDownlink) { |
Wayne Roberts |
0:d467d869e49c | 478 | tx_timeout.attach_us(ack_isr, ACK_DEFER_US); |
Wayne Roberts |
0:d467d869e49c | 479 | APP_PRINTF("confAck "); |
Wayne Roberts |
0:d467d869e49c | 480 | } |
Wayne Roberts |
0:d467d869e49c | 481 | break; |
Wayne Roberts |
0:d467d869e49c | 482 | } |
Wayne Roberts |
0:d467d869e49c | 483 | case MCPS_PROPRIETARY: |
Wayne Roberts |
0:d467d869e49c | 484 | { |
Wayne Roberts |
0:d467d869e49c | 485 | break; |
Wayne Roberts |
0:d467d869e49c | 486 | } |
Wayne Roberts |
0:d467d869e49c | 487 | case MCPS_MULTICAST: |
Wayne Roberts |
0:d467d869e49c | 488 | { |
Wayne Roberts |
0:d467d869e49c | 489 | break; |
Wayne Roberts |
0:d467d869e49c | 490 | } |
Wayne Roberts |
0:d467d869e49c | 491 | default: |
Wayne Roberts |
0:d467d869e49c | 492 | break; |
Wayne Roberts |
0:d467d869e49c | 493 | } |
Wayne Roberts |
0:d467d869e49c | 494 | |
Wayne Roberts |
0:d467d869e49c | 495 | // Check Multicast |
Wayne Roberts |
0:d467d869e49c | 496 | // Check Port |
Wayne Roberts |
0:d467d869e49c | 497 | // Check Datarate |
Wayne Roberts |
0:d467d869e49c | 498 | // Check FramePending |
Wayne Roberts |
0:d467d869e49c | 499 | // Check Buffer |
Wayne Roberts |
0:d467d869e49c | 500 | // Check BufferSize |
Wayne Roberts |
0:d467d869e49c | 501 | // Check Rssi |
Wayne Roberts |
0:d467d869e49c | 502 | // Check Snr |
Wayne Roberts |
0:d467d869e49c | 503 | // Check RxSlot |
Wayne Roberts |
0:d467d869e49c | 504 | |
Wayne Roberts |
0:d467d869e49c | 505 | |
Wayne Roberts |
0:d467d869e49c | 506 | if( ComplianceTest.Running == true ) |
Wayne Roberts |
0:d467d869e49c | 507 | { |
Wayne Roberts |
0:d467d869e49c | 508 | ComplianceTest.DownLinkCounter++; |
Wayne Roberts |
0:d467d869e49c | 509 | } |
Wayne Roberts |
0:d467d869e49c | 510 | |
Wayne Roberts |
0:d467d869e49c | 511 | if (mcpsIndication->RxData) |
Wayne Roberts |
0:d467d869e49c | 512 | { |
Wayne Roberts |
0:d467d869e49c | 513 | APP_PRINTF("FPort%u ", mcpsIndication->Port); |
Wayne Roberts |
0:d467d869e49c | 514 | print_buf(mcpsIndication->Buffer, mcpsIndication->BufferSize, ""); |
Wayne Roberts |
0:d467d869e49c | 515 | #ifdef TARGET_DISCO_L072CZ_LRWAN1 |
Wayne Roberts |
0:d467d869e49c | 516 | if (mcpsIndication->Buffer[0]) |
Wayne Roberts |
0:d467d869e49c | 517 | blue = LED_ON; |
Wayne Roberts |
0:d467d869e49c | 518 | else |
Wayne Roberts |
0:d467d869e49c | 519 | blue = LED_OFF; |
Wayne Roberts |
0:d467d869e49c | 520 | #endif /* TARGET_DISCO_L072CZ_LRWAN1 */ |
Wayne Roberts |
0:d467d869e49c | 521 | |
Wayne Roberts |
0:d467d869e49c | 522 | switch( mcpsIndication->Port ) |
Wayne Roberts |
0:d467d869e49c | 523 | { |
Wayne Roberts |
0:d467d869e49c | 524 | case 1: // The application LED can be controlled on port 1 or 2 |
Wayne Roberts |
0:d467d869e49c | 525 | case 2: |
Wayne Roberts |
0:d467d869e49c | 526 | break; |
Wayne Roberts |
0:d467d869e49c | 527 | case 224: |
Wayne Roberts |
0:d467d869e49c | 528 | if( ComplianceTest.Running == false ) |
Wayne Roberts |
0:d467d869e49c | 529 | { |
Wayne Roberts |
0:d467d869e49c | 530 | // Check compliance test enable command (i) |
Wayne Roberts |
0:d467d869e49c | 531 | if( ( mcpsIndication->BufferSize == 4 ) && |
Wayne Roberts |
0:d467d869e49c | 532 | ( mcpsIndication->Buffer[0] == 0x01 ) && |
Wayne Roberts |
0:d467d869e49c | 533 | ( mcpsIndication->Buffer[1] == 0x01 ) && |
Wayne Roberts |
0:d467d869e49c | 534 | ( mcpsIndication->Buffer[2] == 0x01 ) && |
Wayne Roberts |
0:d467d869e49c | 535 | ( mcpsIndication->Buffer[3] == 0x01 ) ) |
Wayne Roberts |
0:d467d869e49c | 536 | { |
Wayne Roberts |
0:d467d869e49c | 537 | gIsTxConfirmed = false; |
Wayne Roberts |
0:d467d869e49c | 538 | AppPort = 224; |
Wayne Roberts |
0:d467d869e49c | 539 | gAppDataSize = 2; |
Wayne Roberts |
0:d467d869e49c | 540 | ComplianceTest.DownLinkCounter = 0; |
Wayne Roberts |
0:d467d869e49c | 541 | ComplianceTest.LinkCheck = false; |
Wayne Roberts |
0:d467d869e49c | 542 | ComplianceTest.DemodMargin = 0; |
Wayne Roberts |
0:d467d869e49c | 543 | ComplianceTest.NbGateways = 0; |
Wayne Roberts |
0:d467d869e49c | 544 | ComplianceTest.Running = true; |
Wayne Roberts |
0:d467d869e49c | 545 | ComplianceTest.State = 1; |
Wayne Roberts |
0:d467d869e49c | 546 | |
Wayne Roberts |
0:d467d869e49c | 547 | MibRequestConfirm_t mibReq; |
Wayne Roberts |
0:d467d869e49c | 548 | mibReq.Type = MIB_ADR; |
Wayne Roberts |
0:d467d869e49c | 549 | mibReq.Param.AdrEnable = true; |
Wayne Roberts |
0:d467d869e49c | 550 | LoRaMacMibSetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 551 | |
Wayne Roberts |
0:d467d869e49c | 552 | #if defined( USE_BAND_868 ) |
Wayne Roberts |
0:d467d869e49c | 553 | DutyCycleOn = false; |
Wayne Roberts |
0:d467d869e49c | 554 | #endif |
Wayne Roberts |
0:d467d869e49c | 555 | } |
Wayne Roberts |
0:d467d869e49c | 556 | } |
Wayne Roberts |
0:d467d869e49c | 557 | else |
Wayne Roberts |
0:d467d869e49c | 558 | { |
Wayne Roberts |
0:d467d869e49c | 559 | ComplianceTest.State = mcpsIndication->Buffer[0]; |
Wayne Roberts |
0:d467d869e49c | 560 | switch( ComplianceTest.State ) |
Wayne Roberts |
0:d467d869e49c | 561 | { |
Wayne Roberts |
0:d467d869e49c | 562 | case 0: // Check compliance test disable command (ii) |
Wayne Roberts |
0:d467d869e49c | 563 | gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON; |
Wayne Roberts |
0:d467d869e49c | 564 | AppPort = LORAWAN_APP_PORT; |
Wayne Roberts |
0:d467d869e49c | 565 | gAppDataSize = LORAWAN_APP_DATA_SIZE; |
Wayne Roberts |
0:d467d869e49c | 566 | ComplianceTest.DownLinkCounter = 0; |
Wayne Roberts |
0:d467d869e49c | 567 | ComplianceTest.Running = false; |
Wayne Roberts |
0:d467d869e49c | 568 | |
Wayne Roberts |
0:d467d869e49c | 569 | MibRequestConfirm_t mibReq; |
Wayne Roberts |
0:d467d869e49c | 570 | mibReq.Type = MIB_ADR; |
Wayne Roberts |
0:d467d869e49c | 571 | mibReq.Param.AdrEnable = LORAWAN_ADR_ON; |
Wayne Roberts |
0:d467d869e49c | 572 | LoRaMacMibSetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 573 | #if defined( USE_BAND_868 ) |
Wayne Roberts |
0:d467d869e49c | 574 | DutyCycleOn = LORAWAN_DUTYCYCLE_ON; |
Wayne Roberts |
0:d467d869e49c | 575 | #endif |
Wayne Roberts |
0:d467d869e49c | 576 | break; |
Wayne Roberts |
0:d467d869e49c | 577 | case 1: // (iii, iv) |
Wayne Roberts |
0:d467d869e49c | 578 | gAppDataSize = 2; |
Wayne Roberts |
0:d467d869e49c | 579 | break; |
Wayne Roberts |
0:d467d869e49c | 580 | case 2: // Enable confirmed messages (v) |
Wayne Roberts |
0:d467d869e49c | 581 | gIsTxConfirmed = true; |
Wayne Roberts |
0:d467d869e49c | 582 | ComplianceTest.State = 1; |
Wayne Roberts |
0:d467d869e49c | 583 | break; |
Wayne Roberts |
0:d467d869e49c | 584 | case 3: // Disable confirmed messages (vi) |
Wayne Roberts |
0:d467d869e49c | 585 | gIsTxConfirmed = false; |
Wayne Roberts |
0:d467d869e49c | 586 | ComplianceTest.State = 1; |
Wayne Roberts |
0:d467d869e49c | 587 | break; |
Wayne Roberts |
0:d467d869e49c | 588 | case 4: // (vii) |
Wayne Roberts |
0:d467d869e49c | 589 | gAppDataSize = mcpsIndication->BufferSize; |
Wayne Roberts |
0:d467d869e49c | 590 | |
Wayne Roberts |
0:d467d869e49c | 591 | AppData[0] = 4; |
Wayne Roberts |
0:d467d869e49c | 592 | for( uint8_t i = 1; i < gAppDataSize; i++ ) |
Wayne Roberts |
0:d467d869e49c | 593 | { |
Wayne Roberts |
0:d467d869e49c | 594 | AppData[i] = mcpsIndication->Buffer[i] + 1; |
Wayne Roberts |
0:d467d869e49c | 595 | } |
Wayne Roberts |
0:d467d869e49c | 596 | break; |
Wayne Roberts |
0:d467d869e49c | 597 | case 5: // (viii) |
Wayne Roberts |
0:d467d869e49c | 598 | { |
Wayne Roberts |
0:d467d869e49c | 599 | MlmeReq_t mlmeReq; |
Wayne Roberts |
0:d467d869e49c | 600 | mlmeReq.Type = MLME_LINK_CHECK; |
Wayne Roberts |
0:d467d869e49c | 601 | LoRaMacMlmeRequest( &mlmeReq ); |
Wayne Roberts |
0:d467d869e49c | 602 | } |
Wayne Roberts |
0:d467d869e49c | 603 | break; |
Wayne Roberts |
0:d467d869e49c | 604 | case 6: // (ix) |
Wayne Roberts |
0:d467d869e49c | 605 | { |
Wayne Roberts |
0:d467d869e49c | 606 | #ifdef LORAWAN_JOIN_EUI |
Wayne Roberts |
0:d467d869e49c | 607 | MlmeReq_t mlmeReq = {}; |
Wayne Roberts |
0:d467d869e49c | 608 | |
Wayne Roberts |
0:d467d869e49c | 609 | // Disable TestMode and revert back to normal operation |
Wayne Roberts |
0:d467d869e49c | 610 | gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON; |
Wayne Roberts |
0:d467d869e49c | 611 | AppPort = LORAWAN_APP_PORT; |
Wayne Roberts |
0:d467d869e49c | 612 | gAppDataSize = LORAWAN_APP_DATA_SIZE; |
Wayne Roberts |
0:d467d869e49c | 613 | ComplianceTest.DownLinkCounter = 0; |
Wayne Roberts |
0:d467d869e49c | 614 | ComplianceTest.Running = false; |
Wayne Roberts |
0:d467d869e49c | 615 | |
Wayne Roberts |
0:d467d869e49c | 616 | MibRequestConfirm_t mibReq; |
Wayne Roberts |
0:d467d869e49c | 617 | mibReq.Type = MIB_ADR; |
Wayne Roberts |
0:d467d869e49c | 618 | mibReq.Param.AdrEnable = LORAWAN_ADR_ON; |
Wayne Roberts |
0:d467d869e49c | 619 | LoRaMacMibSetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 620 | #if defined( USE_BAND_868 ) |
Wayne Roberts |
0:d467d869e49c | 621 | DutyCycleOn = LORAWAN_DUTYCYCLE_ON; |
Wayne Roberts |
0:d467d869e49c | 622 | #endif |
Wayne Roberts |
0:d467d869e49c | 623 | |
Wayne Roberts |
0:d467d869e49c | 624 | mlmeReq.Type = MLME_JOIN; |
Wayne Roberts |
0:d467d869e49c | 625 | |
Wayne Roberts |
0:d467d869e49c | 626 | mlmeReq.Req.Join.DevEui = DevEui; |
Wayne Roberts |
0:d467d869e49c | 627 | mlmeReq.Req.Join.JoinEui = JoinEui; |
Wayne Roberts |
0:d467d869e49c | 628 | mlmeReq.Req.Join.NwkKey = NwkKey; |
Wayne Roberts |
0:d467d869e49c | 629 | #ifdef LORAWAN_ROOT_APPKEY |
Wayne Roberts |
0:d467d869e49c | 630 | mlmeReq.Req.Join.AppKey = AppKey; |
Wayne Roberts |
0:d467d869e49c | 631 | #endif /* LORAWAN_ROOT_APPKEY */ |
Wayne Roberts |
0:d467d869e49c | 632 | |
Wayne Roberts |
0:d467d869e49c | 633 | LoRaMacMlmeRequest( &mlmeReq ); |
Wayne Roberts |
0:d467d869e49c | 634 | #endif /* LORAWAN_JOIN_EUI */ |
Wayne Roberts |
0:d467d869e49c | 635 | DeviceState = DEVICE_STATE_SLEEP; |
Wayne Roberts |
0:d467d869e49c | 636 | } |
Wayne Roberts |
0:d467d869e49c | 637 | break; |
Wayne Roberts |
0:d467d869e49c | 638 | case 7: // Switch end device Class |
Wayne Roberts |
0:d467d869e49c | 639 | { |
Wayne Roberts |
0:d467d869e49c | 640 | MlmeReq_t mlmeReq; |
Wayne Roberts |
0:d467d869e49c | 641 | |
Wayne Roberts |
0:d467d869e49c | 642 | mlmeReq.Type = MLME_SWITCH_CLASS; |
Wayne Roberts |
0:d467d869e49c | 643 | |
Wayne Roberts |
0:d467d869e49c | 644 | // CLASS_A = 0, CLASS_B = 1, CLASS_C = 2 |
Wayne Roberts |
0:d467d869e49c | 645 | mlmeReq.Req.SwitchClass.Class = ( DeviceClass_t )mcpsIndication->Buffer[1]; |
Wayne Roberts |
0:d467d869e49c | 646 | |
Wayne Roberts |
0:d467d869e49c | 647 | LoRaMacMlmeRequest( &mlmeReq ); |
Wayne Roberts |
0:d467d869e49c | 648 | |
Wayne Roberts |
0:d467d869e49c | 649 | PrepareTxFrame( AppPort ); |
Wayne Roberts |
0:d467d869e49c | 650 | /*status =*/ SendFrame(gIsTxConfirmed, gAppDataSize); |
Wayne Roberts |
0:d467d869e49c | 651 | } |
Wayne Roberts |
0:d467d869e49c | 652 | break; |
Wayne Roberts |
0:d467d869e49c | 653 | case 8: // Send PingSlotInfoReq |
Wayne Roberts |
0:d467d869e49c | 654 | { |
Wayne Roberts |
0:d467d869e49c | 655 | MlmeReq_t mlmeReq; |
Wayne Roberts |
0:d467d869e49c | 656 | |
Wayne Roberts |
0:d467d869e49c | 657 | mlmeReq.Type = MLME_PING_SLOT_INFO; |
Wayne Roberts |
0:d467d869e49c | 658 | |
Wayne Roberts |
0:d467d869e49c | 659 | mlmeReq.Req.PingSlotInfo.Value = mcpsIndication->Buffer[1]; |
Wayne Roberts |
0:d467d869e49c | 660 | |
Wayne Roberts |
0:d467d869e49c | 661 | LoRaMacMlmeRequest( &mlmeReq ); |
Wayne Roberts |
0:d467d869e49c | 662 | PrepareTxFrame( AppPort ); |
Wayne Roberts |
0:d467d869e49c | 663 | /*status =*/ SendFrame(gIsTxConfirmed, gAppDataSize); |
Wayne Roberts |
0:d467d869e49c | 664 | } |
Wayne Roberts |
0:d467d869e49c | 665 | break; |
Wayne Roberts |
0:d467d869e49c | 666 | case 9: // Send BeaconTimingReq |
Wayne Roberts |
0:d467d869e49c | 667 | { |
Wayne Roberts |
0:d467d869e49c | 668 | MlmeReq_t mlmeReq; |
Wayne Roberts |
0:d467d869e49c | 669 | |
Wayne Roberts |
0:d467d869e49c | 670 | mlmeReq.Type = MLME_BEACON_TIMING; |
Wayne Roberts |
0:d467d869e49c | 671 | |
Wayne Roberts |
0:d467d869e49c | 672 | LoRaMacMlmeRequest( &mlmeReq ); |
Wayne Roberts |
0:d467d869e49c | 673 | PrepareTxFrame( AppPort ); |
Wayne Roberts |
0:d467d869e49c | 674 | /*status =*/ SendFrame(gIsTxConfirmed, gAppDataSize); |
Wayne Roberts |
0:d467d869e49c | 675 | } |
Wayne Roberts |
0:d467d869e49c | 676 | break; |
Wayne Roberts |
0:d467d869e49c | 677 | default: |
Wayne Roberts |
0:d467d869e49c | 678 | break; |
Wayne Roberts |
0:d467d869e49c | 679 | } |
Wayne Roberts |
0:d467d869e49c | 680 | } |
Wayne Roberts |
0:d467d869e49c | 681 | break; |
Wayne Roberts |
0:d467d869e49c | 682 | default: |
Wayne Roberts |
0:d467d869e49c | 683 | break; |
Wayne Roberts |
0:d467d869e49c | 684 | } |
Wayne Roberts |
0:d467d869e49c | 685 | |
Wayne Roberts |
0:d467d869e49c | 686 | } |
Wayne Roberts |
0:d467d869e49c | 687 | |
Wayne Roberts |
0:d467d869e49c | 688 | } // ..McpsIndication() |
Wayne Roberts |
0:d467d869e49c | 689 | |
Wayne Roberts |
0:d467d869e49c | 690 | #ifdef LORAWAN_JOIN_EUI |
Wayne Roberts |
0:d467d869e49c | 691 | void |
Wayne Roberts |
0:d467d869e49c | 692 | join(uint8_t tries) |
Wayne Roberts |
0:d467d869e49c | 693 | { |
Wayne Roberts |
0:d467d869e49c | 694 | char str[64]; |
Wayne Roberts |
0:d467d869e49c | 695 | LoRaMacStatus_t status; |
Wayne Roberts |
0:d467d869e49c | 696 | MlmeReq_t mlmeReq = { }; |
Wayne Roberts |
0:d467d869e49c | 697 | |
Wayne Roberts |
0:d467d869e49c | 698 | mlmeReq.Type = MLME_JOIN; |
Wayne Roberts |
0:d467d869e49c | 699 | |
Wayne Roberts |
0:d467d869e49c | 700 | #ifdef LORAWAN_ROOT_APPKEY |
Wayne Roberts |
0:d467d869e49c | 701 | mlmeReq.Req.Join.AppKey = AppKey; |
Wayne Roberts |
0:d467d869e49c | 702 | #endif |
Wayne Roberts |
0:d467d869e49c | 703 | mlmeReq.Req.Join.DevEui = DevEui; |
Wayne Roberts |
0:d467d869e49c | 704 | mlmeReq.Req.Join.JoinEui = JoinEui; |
Wayne Roberts |
0:d467d869e49c | 705 | mlmeReq.Req.Join.NwkKey = NwkKey; |
Wayne Roberts |
0:d467d869e49c | 706 | mlmeReq.Req.Join.NbTrials = tries; |
Wayne Roberts |
0:d467d869e49c | 707 | status = LoRaMacMlmeRequest( &mlmeReq ); |
Wayne Roberts |
0:d467d869e49c | 708 | if (status != LORAMAC_STATUS_OK) { |
Wayne Roberts |
0:d467d869e49c | 709 | LoRaMacStatus_to_string(status, str); |
Wayne Roberts |
0:d467d869e49c | 710 | } else { |
Wayne Roberts |
0:d467d869e49c | 711 | extLed = 1; |
Wayne Roberts |
0:d467d869e49c | 712 | flags.startup = 1; |
Wayne Roberts |
0:d467d869e49c | 713 | } |
Wayne Roberts |
0:d467d869e49c | 714 | } |
Wayne Roberts |
0:d467d869e49c | 715 | #endif /* LORAWAN_JOIN_EUI */ |
Wayne Roberts |
0:d467d869e49c | 716 | |
Wayne Roberts |
0:d467d869e49c | 717 | /*! |
Wayne Roberts |
0:d467d869e49c | 718 | * \brief MLME-Confirm event function |
Wayne Roberts |
0:d467d869e49c | 719 | * |
Wayne Roberts |
0:d467d869e49c | 720 | * \param [IN] mlmeConfirm - Pointer to the confirm structure, |
Wayne Roberts |
0:d467d869e49c | 721 | * containing confirm attributes. |
Wayne Roberts |
0:d467d869e49c | 722 | */ |
Wayne Roberts |
0:d467d869e49c | 723 | static void MlmeConfirm( const MlmeConfirm_t *mlmeConfirm ) |
Wayne Roberts |
0:d467d869e49c | 724 | { |
Wayne Roberts |
0:d467d869e49c | 725 | char str[64]; |
Wayne Roberts |
0:d467d869e49c | 726 | static uint8_t failCnt = 0; |
Wayne Roberts |
0:d467d869e49c | 727 | |
Wayne Roberts |
0:d467d869e49c | 728 | Mlme_to_string(mlmeConfirm->MlmeRequest, str); |
Wayne Roberts |
0:d467d869e49c | 729 | APP_PRINTF("MlmeConfirm %s ", str); |
Wayne Roberts |
0:d467d869e49c | 730 | LoRaMacEventInfoStatus_to_string(mlmeConfirm->Status, str); |
Wayne Roberts |
0:d467d869e49c | 731 | if (mlmeConfirm->Status != LORAMAC_EVENT_INFO_STATUS_OK) { |
Wayne Roberts |
0:d467d869e49c | 732 | APP_PRINTF("\e[31m%s \e[0m\r\n", str); |
Wayne Roberts |
0:d467d869e49c | 733 | } else { |
Wayne Roberts |
0:d467d869e49c | 734 | APP_PRINTF("%s\r\n", str); |
Wayne Roberts |
0:d467d869e49c | 735 | } |
Wayne Roberts |
0:d467d869e49c | 736 | |
Wayne Roberts |
0:d467d869e49c | 737 | #if defined(LORAWAN_ROOT_APPKEY) && defined(LORAWAN_JOIN_EUI) |
Wayne Roberts |
0:d467d869e49c | 738 | /* 1v1 joinNonce is incrementing non-volatile value */ |
Wayne Roberts |
0:d467d869e49c | 739 | if (mlmeConfirm->MlmeRequest == MLME_JOIN) { |
Wayne Roberts |
0:d467d869e49c | 740 | vt.APP_PRINTF(" rxJoinNonce:%u vs %u", |
Wayne Roberts |
0:d467d869e49c | 741 | mlmeConfirm->fields.join.rxJoinNonce, |
Wayne Roberts |
0:d467d869e49c | 742 | mlmeConfirm->fields.join.myJoinNonce |
Wayne Roberts |
0:d467d869e49c | 743 | ); |
Wayne Roberts |
0:d467d869e49c | 744 | } |
Wayne Roberts |
0:d467d869e49c | 745 | #endif /* LORAWAN_ROOT_APPKEY */ |
Wayne Roberts |
0:d467d869e49c | 746 | |
Wayne Roberts |
0:d467d869e49c | 747 | if (mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) |
Wayne Roberts |
0:d467d869e49c | 748 | { |
Wayne Roberts |
0:d467d869e49c | 749 | failCnt = 0; |
Wayne Roberts |
0:d467d869e49c | 750 | switch (mlmeConfirm->MlmeRequest) |
Wayne Roberts |
0:d467d869e49c | 751 | { |
Wayne Roberts |
0:d467d869e49c | 752 | #ifdef LORAWAN_JOIN_EUI |
Wayne Roberts |
0:d467d869e49c | 753 | case MLME_JOIN: |
Wayne Roberts |
0:d467d869e49c | 754 | { |
Wayne Roberts |
0:d467d869e49c | 755 | // Status is OK, node has joined the network |
Wayne Roberts |
0:d467d869e49c | 756 | /* collect any mac cmds from server until expected channel mask */ |
Wayne Roberts |
0:d467d869e49c | 757 | extLed = 0; |
Wayne Roberts |
0:d467d869e49c | 758 | DeviceState = DEVICE_STATE_JOIN_OK; |
Wayne Roberts |
0:d467d869e49c | 759 | break; |
Wayne Roberts |
0:d467d869e49c | 760 | } |
Wayne Roberts |
0:d467d869e49c | 761 | #endif /* LORAWAN_JOIN_EUI*/ |
Wayne Roberts |
0:d467d869e49c | 762 | case MLME_LINK_CHECK: |
Wayne Roberts |
0:d467d869e49c | 763 | { |
Wayne Roberts |
0:d467d869e49c | 764 | // Check DemodMargin |
Wayne Roberts |
0:d467d869e49c | 765 | // Check NbGateways |
Wayne Roberts |
0:d467d869e49c | 766 | if( ComplianceTest.Running == true ) |
Wayne Roberts |
0:d467d869e49c | 767 | { |
Wayne Roberts |
0:d467d869e49c | 768 | ComplianceTest.LinkCheck = true; |
Wayne Roberts |
0:d467d869e49c | 769 | ComplianceTest.DemodMargin = mlmeConfirm->fields.link.DemodMargin; |
Wayne Roberts |
0:d467d869e49c | 770 | ComplianceTest.NbGateways = mlmeConfirm->fields.link.NbGateways; |
Wayne Roberts |
0:d467d869e49c | 771 | } |
Wayne Roberts |
0:d467d869e49c | 772 | break; |
Wayne Roberts |
0:d467d869e49c | 773 | } |
Wayne Roberts |
0:d467d869e49c | 774 | case MLME_TIME_REQ: |
Wayne Roberts |
0:d467d869e49c | 775 | break; |
Wayne Roberts |
0:d467d869e49c | 776 | default: |
Wayne Roberts |
0:d467d869e49c | 777 | /* TODO: handle unknown MLME request */ |
Wayne Roberts |
0:d467d869e49c | 778 | DeviceState = DEVICE_STATE_SLEEP; |
Wayne Roberts |
0:d467d869e49c | 779 | break; |
Wayne Roberts |
0:d467d869e49c | 780 | } |
Wayne Roberts |
0:d467d869e49c | 781 | } |
Wayne Roberts |
0:d467d869e49c | 782 | else // not ok... |
Wayne Roberts |
0:d467d869e49c | 783 | { |
Wayne Roberts |
0:d467d869e49c | 784 | failCnt++; |
Wayne Roberts |
0:d467d869e49c | 785 | |
Wayne Roberts |
0:d467d869e49c | 786 | #ifdef LORAWAN_JOIN_EUI |
Wayne Roberts |
0:d467d869e49c | 787 | if (failCnt > 5) { |
Wayne Roberts |
0:d467d869e49c | 788 | join(1); |
Wayne Roberts |
0:d467d869e49c | 789 | return; |
Wayne Roberts |
0:d467d869e49c | 790 | } |
Wayne Roberts |
0:d467d869e49c | 791 | #endif |
Wayne Roberts |
0:d467d869e49c | 792 | |
Wayne Roberts |
0:d467d869e49c | 793 | switch( mlmeConfirm->MlmeRequest ) |
Wayne Roberts |
0:d467d869e49c | 794 | { |
Wayne Roberts |
0:d467d869e49c | 795 | #ifdef LORAWAN_JOIN_EUI |
Wayne Roberts |
0:d467d869e49c | 796 | case MLME_JOIN: |
Wayne Roberts |
0:d467d869e49c | 797 | { |
Wayne Roberts |
0:d467d869e49c | 798 | // Join failed, restart join procedure |
Wayne Roberts |
0:d467d869e49c | 799 | break; |
Wayne Roberts |
0:d467d869e49c | 800 | } |
Wayne Roberts |
0:d467d869e49c | 801 | #endif /* LORAWAN_JOIN_EUI */ |
Wayne Roberts |
0:d467d869e49c | 802 | case MLME_LINK_CHECK: |
Wayne Roberts |
0:d467d869e49c | 803 | DeviceState = DEVICE_STATE_SLEEP; |
Wayne Roberts |
0:d467d869e49c | 804 | break; |
Wayne Roberts |
0:d467d869e49c | 805 | #ifdef LORAWAN_JOIN_EUI |
Wayne Roberts |
0:d467d869e49c | 806 | case MLME_REJOIN_0: |
Wayne Roberts |
0:d467d869e49c | 807 | break; |
Wayne Roberts |
0:d467d869e49c | 808 | case MLME_REJOIN_2: |
Wayne Roberts |
0:d467d869e49c | 809 | break; |
Wayne Roberts |
0:d467d869e49c | 810 | case MLME_TIME_REQ: |
Wayne Roberts |
0:d467d869e49c | 811 | break; |
Wayne Roberts |
0:d467d869e49c | 812 | #endif /* LORAWAN_JOIN_EUI */ |
Wayne Roberts |
0:d467d869e49c | 813 | default: |
Wayne Roberts |
0:d467d869e49c | 814 | DeviceState = DEVICE_STATE_SLEEP; |
Wayne Roberts |
0:d467d869e49c | 815 | break; |
Wayne Roberts |
0:d467d869e49c | 816 | } |
Wayne Roberts |
0:d467d869e49c | 817 | } |
Wayne Roberts |
0:d467d869e49c | 818 | } // ..MlmeConfirm |
Wayne Roberts |
0:d467d869e49c | 819 | |
Wayne Roberts |
0:d467d869e49c | 820 | static void MlmeIndication( const MlmeIndication_t *MlmeIndication ) |
Wayne Roberts |
0:d467d869e49c | 821 | { |
Wayne Roberts |
0:d467d869e49c | 822 | char str[48]; |
Wayne Roberts |
0:d467d869e49c | 823 | MibRequestConfirm_t mibReq; |
Wayne Roberts |
0:d467d869e49c | 824 | |
Wayne Roberts |
0:d467d869e49c | 825 | Mlme_to_string(MlmeIndication->MlmeIndication, str); |
Wayne Roberts |
0:d467d869e49c | 826 | APP_PRINTF("MlmeIndication %s ", str); |
Wayne Roberts |
0:d467d869e49c | 827 | LoRaMacEventInfoStatus_to_string(MlmeIndication->Status, str); |
Wayne Roberts |
0:d467d869e49c | 828 | if (MlmeIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK) { |
Wayne Roberts |
0:d467d869e49c | 829 | APP_PRINTF("\e[31m%s \e[0m\r\n", str); |
Wayne Roberts |
0:d467d869e49c | 830 | } else { |
Wayne Roberts |
0:d467d869e49c | 831 | APP_PRINTF("%s\r\n", str); |
Wayne Roberts |
0:d467d869e49c | 832 | } |
Wayne Roberts |
0:d467d869e49c | 833 | |
Wayne Roberts |
0:d467d869e49c | 834 | switch( MlmeIndication->MlmeIndication ) |
Wayne Roberts |
0:d467d869e49c | 835 | { |
Wayne Roberts |
0:d467d869e49c | 836 | case MLME_SWITCH_CLASS: |
Wayne Roberts |
0:d467d869e49c | 837 | { |
Wayne Roberts |
0:d467d869e49c | 838 | /* mac gave up on beacon */ |
Wayne Roberts |
0:d467d869e49c | 839 | mibReq.Type = MIB_DEVICE_CLASS; |
Wayne Roberts |
0:d467d869e49c | 840 | mibReq.Param.Class = CLASS_A; |
Wayne Roberts |
0:d467d869e49c | 841 | LoRaMacMibSetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 842 | |
Wayne Roberts |
0:d467d869e49c | 843 | // Switch to class A again |
Wayne Roberts |
0:d467d869e49c | 844 | DeviceState = DEVICE_STATE_SLEEP; // class-B manual switch |
Wayne Roberts |
0:d467d869e49c | 845 | break; |
Wayne Roberts |
0:d467d869e49c | 846 | } |
Wayne Roberts |
0:d467d869e49c | 847 | case MLME_BEACON: |
Wayne Roberts |
0:d467d869e49c | 848 | { |
Wayne Roberts |
0:d467d869e49c | 849 | LoRaMacEventInfoStatus_to_string(MlmeIndication->Status, str); |
Wayne Roberts |
0:d467d869e49c | 850 | break; |
Wayne Roberts |
0:d467d869e49c | 851 | |
Wayne Roberts |
0:d467d869e49c | 852 | } |
Wayne Roberts |
0:d467d869e49c | 853 | #ifdef LORAWAN_JOIN_EUI |
Wayne Roberts |
0:d467d869e49c | 854 | case MLME_JOIN: |
Wayne Roberts |
0:d467d869e49c | 855 | APP_PRINTF("%" PRIu32 "hz try%u ", MlmeIndication->freqHz, MlmeIndication->JoinRequestTrials); |
Wayne Roberts |
0:d467d869e49c | 856 | break; |
Wayne Roberts |
0:d467d869e49c | 857 | #endif /* !LORAWAN_JOIN_EUI */ |
Wayne Roberts |
0:d467d869e49c | 858 | default: |
Wayne Roberts |
0:d467d869e49c | 859 | break; |
Wayne Roberts |
0:d467d869e49c | 860 | } |
Wayne Roberts |
0:d467d869e49c | 861 | |
Wayne Roberts |
0:d467d869e49c | 862 | } // ..MlmeIndication() |
Wayne Roberts |
0:d467d869e49c | 863 | |
Wayne Roberts |
0:d467d869e49c | 864 | uint8_t periodicity; |
Wayne Roberts |
0:d467d869e49c | 865 | |
Wayne Roberts |
0:d467d869e49c | 866 | |
Wayne Roberts |
0:d467d869e49c | 867 | void SerialRxProcess( void ) |
Wayne Roberts |
0:d467d869e49c | 868 | { |
Wayne Roberts |
0:d467d869e49c | 869 | char str[48]; |
Wayne Roberts |
0:d467d869e49c | 870 | MibRequestConfirm_t mibReq; |
Wayne Roberts |
0:d467d869e49c | 871 | LoRaMacStatus_t status; |
Wayne Roberts |
0:d467d869e49c | 872 | MlmeReq_t mlmeReq; |
Wayne Roberts |
0:d467d869e49c | 873 | #ifndef LORAWAN_JOIN_EUI |
Wayne Roberts |
0:d467d869e49c | 874 | static uint8_t icnt = 0; |
Wayne Roberts |
0:d467d869e49c | 875 | #endif |
Wayne Roberts |
0:d467d869e49c | 876 | |
Wayne Roberts |
0:d467d869e49c | 877 | if( pc.readable( ) == true ) { |
Wayne Roberts |
0:d467d869e49c | 878 | char ch = pc.getc(); |
Wayne Roberts |
0:d467d869e49c | 879 | #ifndef LORAWAN_JOIN_EUI |
Wayne Roberts |
0:d467d869e49c | 880 | if (ch == 'I') { |
Wayne Roberts |
0:d467d869e49c | 881 | if (++icnt == 3) { |
Wayne Roberts |
0:d467d869e49c | 882 | APP_PRINTF("reset-fcnts\r\n"); |
Wayne Roberts |
0:d467d869e49c | 883 | eeprom_clear(EEPROM_AFCNTDWN); |
Wayne Roberts |
0:d467d869e49c | 884 | eeprom_clear(EEPROM_NFCNTDWN); |
Wayne Roberts |
0:d467d869e49c | 885 | eeprom_clear(EEPROM_FCNTUP); |
Wayne Roberts |
0:d467d869e49c | 886 | } |
Wayne Roberts |
0:d467d869e49c | 887 | } else |
Wayne Roberts |
0:d467d869e49c | 888 | icnt = 0; |
Wayne Roberts |
0:d467d869e49c | 889 | #endif /* !LORAWAN_JOIN_EUI */ |
Wayne Roberts |
0:d467d869e49c | 890 | |
Wayne Roberts |
0:d467d869e49c | 891 | if ( ch >= '0' && ch <= '9') { |
Wayne Roberts |
0:d467d869e49c | 892 | c_ch = ch - '0'; |
Wayne Roberts |
0:d467d869e49c | 893 | DeviceState = DEVICE_STATE_SEND; |
Wayne Roberts |
0:d467d869e49c | 894 | return; |
Wayne Roberts |
0:d467d869e49c | 895 | } |
Wayne Roberts |
0:d467d869e49c | 896 | switch( ch ) { |
Wayne Roberts |
0:d467d869e49c | 897 | case 'L': |
Wayne Roberts |
0:d467d869e49c | 898 | mlmeReq.Type = MLME_LINK_CHECK; |
Wayne Roberts |
0:d467d869e49c | 899 | status = LoRaMacMlmeRequest( &mlmeReq ); |
Wayne Roberts |
0:d467d869e49c | 900 | if (status == LORAMAC_STATUS_OK) |
Wayne Roberts |
0:d467d869e49c | 901 | SendFrame(false, 0); |
Wayne Roberts |
0:d467d869e49c | 902 | else { |
Wayne Roberts |
0:d467d869e49c | 903 | LoRaMacStatus_to_string(status, str); |
Wayne Roberts |
0:d467d869e49c | 904 | APP_PRINTF("%s\r\n", str); |
Wayne Roberts |
0:d467d869e49c | 905 | } |
Wayne Roberts |
0:d467d869e49c | 906 | break; |
Wayne Roberts |
0:d467d869e49c | 907 | #ifdef LORAWAN_JOIN_EUI |
Wayne Roberts |
0:d467d869e49c | 908 | case 'j': |
Wayne Roberts |
0:d467d869e49c | 909 | DeviceState = DEVICE_STATE_JOIN; |
Wayne Roberts |
0:d467d869e49c | 910 | break; |
Wayne Roberts |
0:d467d869e49c | 911 | #endif |
Wayne Roberts |
0:d467d869e49c | 912 | case 'a': |
Wayne Roberts |
0:d467d869e49c | 913 | flags.ackDownlink ^= 1; |
Wayne Roberts |
0:d467d869e49c | 914 | APP_PRINTF("ackDownlink:%u\r\n", flags.ackDownlink); |
Wayne Roberts |
0:d467d869e49c | 915 | break; |
Wayne Roberts |
0:d467d869e49c | 916 | case '.': |
Wayne Roberts |
0:d467d869e49c | 917 | uint16_t altitudeGps; |
Wayne Roberts |
0:d467d869e49c | 918 | print_buf(DevEui, 8, "DevEui"); |
Wayne Roberts |
0:d467d869e49c | 919 | mibReq.Type = MIB_DEV_ADDR; |
Wayne Roberts |
0:d467d869e49c | 920 | LoRaMacMibGetRequestConfirm( &mibReq ); |
Wayne Roberts |
2:fdd36ff9b181 | 921 | APP_PRINTF("DevAddr:%08lx ", mibReq.Param.DevAddr); |
Wayne Roberts |
0:d467d869e49c | 922 | mibReq.Type = MIB_RX2_CHANNEL; |
Wayne Roberts |
0:d467d869e49c | 923 | LoRaMacMibGetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 924 | APP_PRINTF(" rx2 %uhz dr%u, ackDownlink:%u\r\n", mibReq.Param.Rx2Channel.FrequencyHz, mibReq.Param.Rx2Channel.Datarate, flags.ackDownlink); |
Wayne Roberts |
0:d467d869e49c | 925 | LoRaMacPrintStatus(); |
Wayne Roberts |
0:d467d869e49c | 926 | gps.service(); |
Wayne Roberts |
2:fdd36ff9b181 | 927 | str[0] = gps.NmeaGpsData.NmeaUtcTime[0]; // hour |
Wayne Roberts |
2:fdd36ff9b181 | 928 | str[1] = gps.NmeaGpsData.NmeaUtcTime[1]; |
Wayne Roberts |
2:fdd36ff9b181 | 929 | str[2] = ':'; |
Wayne Roberts |
2:fdd36ff9b181 | 930 | str[3] = gps.NmeaGpsData.NmeaUtcTime[2]; // minute |
Wayne Roberts |
2:fdd36ff9b181 | 931 | str[4] = gps.NmeaGpsData.NmeaUtcTime[3]; |
Wayne Roberts |
2:fdd36ff9b181 | 932 | str[5] = ':'; |
Wayne Roberts |
2:fdd36ff9b181 | 933 | str[6] = gps.NmeaGpsData.NmeaUtcTime[4]; // second |
Wayne Roberts |
2:fdd36ff9b181 | 934 | str[7] = gps.NmeaGpsData.NmeaUtcTime[5]; |
Wayne Roberts |
2:fdd36ff9b181 | 935 | str[8] = 'Z'; |
Wayne Roberts |
2:fdd36ff9b181 | 936 | str[9] = 0; |
Wayne Roberts |
2:fdd36ff9b181 | 937 | APP_PRINTF("%s ", str); |
Wayne Roberts |
0:d467d869e49c | 938 | altitudeGps = atoi( gps.NmeaGpsData.NmeaAltitude ); |
Wayne Roberts |
0:d467d869e49c | 939 | APP_PRINTF("gps %f, %f, %d\r\n", gps.Latitude, gps.Longitude, altitudeGps); |
Wayne Roberts |
0:d467d869e49c | 940 | break; |
Wayne Roberts |
0:d467d869e49c | 941 | case '?': |
Wayne Roberts |
0:d467d869e49c | 942 | APP_PRINTF("C start classC\r\n"); |
Wayne Roberts |
0:d467d869e49c | 943 | APP_PRINTF("L send link check\r\n"); |
Wayne Roberts |
0:d467d869e49c | 944 | APP_PRINTF("j send joinReq\r\n"); |
Wayne Roberts |
0:d467d869e49c | 945 | APP_PRINTF("a toggle ackDownlink\r\n"); |
Wayne Roberts |
0:d467d869e49c | 946 | APP_PRINTF(". print status\r\n"); |
Wayne Roberts |
0:d467d869e49c | 947 | break; |
Wayne Roberts |
0:d467d869e49c | 948 | default: |
Wayne Roberts |
0:d467d869e49c | 949 | break; |
Wayne Roberts |
0:d467d869e49c | 950 | } |
Wayne Roberts |
0:d467d869e49c | 951 | } |
Wayne Roberts |
0:d467d869e49c | 952 | } |
Wayne Roberts |
0:d467d869e49c | 953 | |
Wayne Roberts |
0:d467d869e49c | 954 | static void button_isr() |
Wayne Roberts |
0:d467d869e49c | 955 | { |
Wayne Roberts |
0:d467d869e49c | 956 | c_ch = 0xff; |
Wayne Roberts |
0:d467d869e49c | 957 | DeviceState = DEVICE_STATE_SEND; |
Wayne Roberts |
0:d467d869e49c | 958 | buttonStartAt = LoRaMacReadTimer(); |
Wayne Roberts |
0:d467d869e49c | 959 | } |
Wayne Roberts |
0:d467d869e49c | 960 | |
Wayne Roberts |
0:d467d869e49c | 961 | static const LoRaMacPrimitives_t LoRaMacPrimitives = { |
Wayne Roberts |
0:d467d869e49c | 962 | McpsConfirm, |
Wayne Roberts |
0:d467d869e49c | 963 | McpsIndication, |
Wayne Roberts |
0:d467d869e49c | 964 | MlmeConfirm, |
Wayne Roberts |
0:d467d869e49c | 965 | MlmeIndication |
Wayne Roberts |
0:d467d869e49c | 966 | }; |
Wayne Roberts |
0:d467d869e49c | 967 | |
Wayne Roberts |
0:d467d869e49c | 968 | static const LoRaMacCallback_t LoRaMacCallbacks = { |
Wayne Roberts |
0:d467d869e49c | 969 | BoardGetBatteryLevel, |
Wayne Roberts |
0:d467d869e49c | 970 | NULL |
Wayne Roberts |
0:d467d869e49c | 971 | }; |
Wayne Roberts |
0:d467d869e49c | 972 | |
Wayne Roberts |
0:d467d869e49c | 973 | /** |
Wayne Roberts |
0:d467d869e49c | 974 | * Main application entry point. |
Wayne Roberts |
0:d467d869e49c | 975 | */ |
Wayne Roberts |
0:d467d869e49c | 976 | int main() |
Wayne Roberts |
0:d467d869e49c | 977 | { |
Wayne Roberts |
0:d467d869e49c | 978 | LoRaMacStatus_t status; |
Wayne Roberts |
0:d467d869e49c | 979 | MibRequestConfirm_t mibReq; |
Wayne Roberts |
0:d467d869e49c | 980 | |
Wayne Roberts |
0:d467d869e49c | 981 | DeviceState = DEVICE_STATE_INIT; |
Wayne Roberts |
0:d467d869e49c | 982 | |
Wayne Roberts |
0:d467d869e49c | 983 | if (sleep_manager_can_deep_sleep()) |
Wayne Roberts |
0:d467d869e49c | 984 | sleep_manager_lock_deep_sleep(); // prevent deep sleep |
Wayne Roberts |
0:d467d869e49c | 985 | |
Wayne Roberts |
0:d467d869e49c | 986 | #ifdef JUMPER_ENABLE |
Wayne Roberts |
0:d467d869e49c | 987 | jumper_out = 1; |
Wayne Roberts |
0:d467d869e49c | 988 | jumper_in.mode(PullDown); |
Wayne Roberts |
0:d467d869e49c | 989 | jumper_in.rise(jumper_callback); |
Wayne Roberts |
0:d467d869e49c | 990 | // Q: does InterruptIn.rise() call immediately if already high? |
Wayne Roberts |
0:d467d869e49c | 991 | if (jumper_in.read()) |
Wayne Roberts |
0:d467d869e49c | 992 | jumper_callback(); // A: probably not |
Wayne Roberts |
0:d467d869e49c | 993 | #endif /* JUMPER_ENABLE */ |
Wayne Roberts |
0:d467d869e49c | 994 | |
Wayne Roberts |
0:d467d869e49c | 995 | gps.init(); |
Wayne Roberts |
0:d467d869e49c | 996 | |
Wayne Roberts |
0:d467d869e49c | 997 | while( 1 ) |
Wayne Roberts |
0:d467d869e49c | 998 | { |
Wayne Roberts |
0:d467d869e49c | 999 | SerialRxProcess( ); |
Wayne Roberts |
0:d467d869e49c | 1000 | |
Wayne Roberts |
0:d467d869e49c | 1001 | switch( DeviceState ) |
Wayne Roberts |
0:d467d869e49c | 1002 | { |
Wayne Roberts |
0:d467d869e49c | 1003 | case DEVICE_STATE_INIT: |
Wayne Roberts |
0:d467d869e49c | 1004 | { |
Wayne Roberts |
0:d467d869e49c | 1005 | status = LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks ); |
Wayne Roberts |
0:d467d869e49c | 1006 | if (LORAMAC_STATUS_OK != status) { |
Wayne Roberts |
0:d467d869e49c | 1007 | char str[48]; |
Wayne Roberts |
0:d467d869e49c | 1008 | LoRaMacStatus_to_string(status, str); |
Wayne Roberts |
0:d467d869e49c | 1009 | APP_PRINTF("MacInit: %s\r\n", str); |
Wayne Roberts |
0:d467d869e49c | 1010 | for (;;) asm("nop"); |
Wayne Roberts |
0:d467d869e49c | 1011 | } |
Wayne Roberts |
0:d467d869e49c | 1012 | |
Wayne Roberts |
0:d467d869e49c | 1013 | c_ch = 0xff; |
Wayne Roberts |
0:d467d869e49c | 1014 | button_pin.mode(PullDown); |
Wayne Roberts |
0:d467d869e49c | 1015 | #ifdef TARGET_DISCO_L072CZ_LRWAN1 |
Wayne Roberts |
0:d467d869e49c | 1016 | button_pin.fall(button_isr); |
Wayne Roberts |
0:d467d869e49c | 1017 | #else |
Wayne Roberts |
0:d467d869e49c | 1018 | button_pin.rise(button_isr); |
Wayne Roberts |
0:d467d869e49c | 1019 | #endif |
Wayne Roberts |
0:d467d869e49c | 1020 | |
Wayne Roberts |
0:d467d869e49c | 1021 | mibReq.Type = MIB_ADR; |
Wayne Roberts |
0:d467d869e49c | 1022 | mibReq.Param.AdrEnable = LORAWAN_ADR_ON; |
Wayne Roberts |
0:d467d869e49c | 1023 | LoRaMacMibSetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1024 | |
Wayne Roberts |
0:d467d869e49c | 1025 | mibReq.Type = MIB_PUBLIC_NETWORK; |
Wayne Roberts |
0:d467d869e49c | 1026 | mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK; |
Wayne Roberts |
0:d467d869e49c | 1027 | LoRaMacMibSetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1028 | |
Wayne Roberts |
0:d467d869e49c | 1029 | #if defined( USE_BAND_868 ) |
Wayne Roberts |
0:d467d869e49c | 1030 | DutyCycleOn = LORAWAN_DUTYCYCLE_ON ; |
Wayne Roberts |
0:d467d869e49c | 1031 | #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 ) |
Wayne Roberts |
0:d467d869e49c | 1032 | LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 ); |
Wayne Roberts |
0:d467d869e49c | 1033 | LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 ); |
Wayne Roberts |
0:d467d869e49c | 1034 | LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 ); |
Wayne Roberts |
0:d467d869e49c | 1035 | LoRaMacChannelAdd( 6, ( ChannelParams_t )LC7 ); |
Wayne Roberts |
0:d467d869e49c | 1036 | LoRaMacChannelAdd( 7, ( ChannelParams_t )LC8 ); |
Wayne Roberts |
0:d467d869e49c | 1037 | LoRaMacChannelAdd( 8, ( ChannelParams_t )LC9 ); |
Wayne Roberts |
0:d467d869e49c | 1038 | LoRaMacChannelAdd( 9, ( ChannelParams_t )LC10 ); |
Wayne Roberts |
0:d467d869e49c | 1039 | |
Wayne Roberts |
0:d467d869e49c | 1040 | mibReq.Type = MIB_RX2_CHANNEL; |
Wayne Roberts |
0:d467d869e49c | 1041 | mibReq.Param.Rx2Channel = ( Rx2ChannelParams_t ){ 869525000, DR_3 }; |
Wayne Roberts |
0:d467d869e49c | 1042 | LoRaMacMibSetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1043 | #endif |
Wayne Roberts |
0:d467d869e49c | 1044 | |
Wayne Roberts |
0:d467d869e49c | 1045 | #endif |
Wayne Roberts |
0:d467d869e49c | 1046 | |
Wayne Roberts |
0:d467d869e49c | 1047 | #ifdef LORAWAN_JOIN_EUI |
Wayne Roberts |
0:d467d869e49c | 1048 | |
Wayne Roberts |
0:d467d869e49c | 1049 | #ifndef SENETCO /* for senet, use network provided DevEUI */ |
Wayne Roberts |
0:d467d869e49c | 1050 | // Initialize LoRaMac device unique ID |
Wayne Roberts |
0:d467d869e49c | 1051 | HardwareIDtoDevEUI(DevEui); |
Wayne Roberts |
0:d467d869e49c | 1052 | #ifdef LORAWAN_ROOT_APPKEY |
Wayne Roberts |
0:d467d869e49c | 1053 | // inverted DevEui provisioned as v1.1 on server (non-inv = lorawan1v0) |
Wayne Roberts |
0:d467d869e49c | 1054 | for (int i = 0; i < 8; i++) |
Wayne Roberts |
0:d467d869e49c | 1055 | DevEui[i] ^= 0xff; |
Wayne Roberts |
0:d467d869e49c | 1056 | #endif /* LORAWAN_ROOT_APPKEY */ |
Wayne Roberts |
0:d467d869e49c | 1057 | #endif /* !SENETCO */ |
Wayne Roberts |
0:d467d869e49c | 1058 | print_buf(DevEui, 8, "DevEui"); |
Wayne Roberts |
0:d467d869e49c | 1059 | DeviceState = DEVICE_STATE_JOIN; |
Wayne Roberts |
0:d467d869e49c | 1060 | #else /* ABP... */ |
Wayne Roberts |
0:d467d869e49c | 1061 | |
Wayne Roberts |
0:d467d869e49c | 1062 | mibReq.Type = MIB_DEV_ADDR; |
Wayne Roberts |
0:d467d869e49c | 1063 | mibReq.Param.DevAddr = DevAddr; |
Wayne Roberts |
0:d467d869e49c | 1064 | LoRaMacMibSetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1065 | SerialDisplayUpdateDevAddr(DevAddr); |
Wayne Roberts |
0:d467d869e49c | 1066 | |
Wayne Roberts |
0:d467d869e49c | 1067 | mibReq.Type = MIB_APP_SKEY; |
Wayne Roberts |
0:d467d869e49c | 1068 | mibReq.Param.key = AppSKey; |
Wayne Roberts |
0:d467d869e49c | 1069 | LoRaMacMibSetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1070 | SerialDisplayUpdateKey(ROW_AppSKey, AppSKey); |
Wayne Roberts |
0:d467d869e49c | 1071 | |
Wayne Roberts |
0:d467d869e49c | 1072 | #if defined(LORAWAN_SNwkSIntKey) && defined(LORAWAN_NwkSEncKey) |
Wayne Roberts |
0:d467d869e49c | 1073 | /* lorawan 1v1 ABP */ |
Wayne Roberts |
0:d467d869e49c | 1074 | mibReq.Type = MIB_NwkSEncKey; |
Wayne Roberts |
0:d467d869e49c | 1075 | mibReq.Param.key = NwkSEncKey; |
Wayne Roberts |
0:d467d869e49c | 1076 | LoRaMacMibSetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1077 | SerialDisplayUpdateKey(ROW_NwkSEncKey, NwkSEncKey); |
Wayne Roberts |
0:d467d869e49c | 1078 | |
Wayne Roberts |
0:d467d869e49c | 1079 | mibReq.Type = MIB_SNwkSIntKey; |
Wayne Roberts |
0:d467d869e49c | 1080 | mibReq.Param.key = SNwkSIntKey; |
Wayne Roberts |
0:d467d869e49c | 1081 | LoRaMacMibSetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1082 | SerialDisplayUpdateKey(ROW_SNwkSIntKey, SNwkSIntKey); |
Wayne Roberts |
0:d467d869e49c | 1083 | |
Wayne Roberts |
0:d467d869e49c | 1084 | mibReq.Type = MIB_FNwkSIntKey; |
Wayne Roberts |
0:d467d869e49c | 1085 | mibReq.Param.key = FNwkSIntKey; |
Wayne Roberts |
0:d467d869e49c | 1086 | LoRaMacMibSetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1087 | SerialDisplayUpdateKey(ROW_FNwkSIntKey, mibReq.Param.key); |
Wayne Roberts |
0:d467d869e49c | 1088 | #else |
Wayne Roberts |
0:d467d869e49c | 1089 | /* lorawan 1v0 ABP */ |
Wayne Roberts |
0:d467d869e49c | 1090 | mibReq.Type = MIB_NwkSKey; |
Wayne Roberts |
0:d467d869e49c | 1091 | mibReq.Param.key = FNwkSIntKey; |
Wayne Roberts |
0:d467d869e49c | 1092 | LoRaMacMibSetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1093 | SerialDisplayUpdateKey(ROW_FNwkSIntKey, mibReq.Param.key); |
Wayne Roberts |
0:d467d869e49c | 1094 | #endif |
Wayne Roberts |
0:d467d869e49c | 1095 | |
Wayne Roberts |
0:d467d869e49c | 1096 | DeviceState = DEVICE_STATE_SLEEP; |
Wayne Roberts |
0:d467d869e49c | 1097 | #endif /* !LORAWAN_JOIN_EUI */ |
Wayne Roberts |
0:d467d869e49c | 1098 | |
Wayne Roberts |
0:d467d869e49c | 1099 | #if defined( USE_BAND_ARIB_8CH ) |
Wayne Roberts |
0:d467d869e49c | 1100 | mibReq.Type = MIB_MAX_LISTEN_TIME; |
Wayne Roberts |
0:d467d869e49c | 1101 | mibReq.Param.MaxListenTime = 7000000; |
Wayne Roberts |
0:d467d869e49c | 1102 | LoRaMacMibSetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1103 | #endif /* USE_BAND_ARIB_8CH */ |
Wayne Roberts |
0:d467d869e49c | 1104 | |
Wayne Roberts |
0:d467d869e49c | 1105 | flags.ackDownlink = 1; |
Wayne Roberts |
0:d467d869e49c | 1106 | flags.startup = 1; |
Wayne Roberts |
0:d467d869e49c | 1107 | break; |
Wayne Roberts |
0:d467d869e49c | 1108 | } |
Wayne Roberts |
0:d467d869e49c | 1109 | #ifdef LORAWAN_JOIN_EUI |
Wayne Roberts |
0:d467d869e49c | 1110 | case DEVICE_STATE_JOIN: |
Wayne Roberts |
0:d467d869e49c | 1111 | { |
Wayne Roberts |
0:d467d869e49c | 1112 | join(8); |
Wayne Roberts |
0:d467d869e49c | 1113 | DeviceState = DEVICE_STATE_SLEEP; |
Wayne Roberts |
0:d467d869e49c | 1114 | break; |
Wayne Roberts |
0:d467d869e49c | 1115 | } |
Wayne Roberts |
0:d467d869e49c | 1116 | case DEVICE_STATE_JOIN_OK: |
Wayne Roberts |
0:d467d869e49c | 1117 | MibRequestConfirm_t mibReq; |
Wayne Roberts |
0:d467d869e49c | 1118 | mibReq.Type = MIB_NETWORK_JOINED; |
Wayne Roberts |
0:d467d869e49c | 1119 | LoRaMacMibGetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1120 | if (mibReq.Param.IsNetworkJoined) |
Wayne Roberts |
0:d467d869e49c | 1121 | APP_PRINTF("joined "); |
Wayne Roberts |
0:d467d869e49c | 1122 | mibReq.Type = MIB_DEV_ADDR; |
Wayne Roberts |
0:d467d869e49c | 1123 | LoRaMacMibGetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1124 | APP_PRINTF("DevAddr:%08" PRIx32 "\r\n", mibReq.Param.DevAddr); |
Wayne Roberts |
0:d467d869e49c | 1125 | mibReq.Type = MIB_FNwkSIntKey; |
Wayne Roberts |
0:d467d869e49c | 1126 | LoRaMacMibGetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1127 | print_buf(mibReq.Param.key, 16, "FNwkSIntKey"); |
Wayne Roberts |
0:d467d869e49c | 1128 | mibReq.Type = MIB_APP_SKEY; |
Wayne Roberts |
0:d467d869e49c | 1129 | LoRaMacMibGetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1130 | print_buf(mibReq.Param.key, 16, "AppSKey"); |
Wayne Roberts |
0:d467d869e49c | 1131 | |
Wayne Roberts |
0:d467d869e49c | 1132 | #ifdef LORAWAN_ROOT_APPKEY |
Wayne Roberts |
0:d467d869e49c | 1133 | mibReq.Type = MIB_SNwkSIntKey; |
Wayne Roberts |
0:d467d869e49c | 1134 | LoRaMacMibGetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1135 | SerialDisplayUpdateKey(ROW_SNwkSIntKey, mibReq.Param.key); |
Wayne Roberts |
0:d467d869e49c | 1136 | mibReq.Type = MIB_NwkSEncKey; |
Wayne Roberts |
0:d467d869e49c | 1137 | LoRaMacMibGetRequestConfirm( &mibReq ); |
Wayne Roberts |
0:d467d869e49c | 1138 | SerialDisplayUpdateKey(ROW_NwkSEncKey, mibReq.Param.key); |
Wayne Roberts |
0:d467d869e49c | 1139 | #endif /* LORAWAN_ROOT_APPKEY */ |
Wayne Roberts |
0:d467d869e49c | 1140 | DeviceState = DEVICE_STATE_SLEEP; |
Wayne Roberts |
0:d467d869e49c | 1141 | break; |
Wayne Roberts |
0:d467d869e49c | 1142 | #endif /* LORAWAN_JOIN_EUI */ |
Wayne Roberts |
0:d467d869e49c | 1143 | case DEVICE_STATE_SEND: |
Wayne Roberts |
0:d467d869e49c | 1144 | PrepareTxFrame( AppPort ); |
Wayne Roberts |
0:d467d869e49c | 1145 | status = SendFrame(gIsTxConfirmed, gAppDataSize); |
Wayne Roberts |
0:d467d869e49c | 1146 | if (status == LORAMAC_STATUS_OK) { |
Wayne Roberts |
0:d467d869e49c | 1147 | /* McpsConfirm or McpsIndication callback will continue */ |
Wayne Roberts |
0:d467d869e49c | 1148 | } |
Wayne Roberts |
0:d467d869e49c | 1149 | DeviceState = DEVICE_STATE_SLEEP; |
Wayne Roberts |
0:d467d869e49c | 1150 | break; |
Wayne Roberts |
0:d467d869e49c | 1151 | case DEVICE_STATE_SLEEP: |
Wayne Roberts |
0:d467d869e49c | 1152 | { |
Wayne Roberts |
0:d467d869e49c | 1153 | // Wake up through events |
Wayne Roberts |
0:d467d869e49c | 1154 | sleep_manager_sleep_auto(); |
Wayne Roberts |
0:d467d869e49c | 1155 | break; |
Wayne Roberts |
0:d467d869e49c | 1156 | } |
Wayne Roberts |
0:d467d869e49c | 1157 | default: |
Wayne Roberts |
0:d467d869e49c | 1158 | DeviceState = DEVICE_STATE_INIT; |
Wayne Roberts |
0:d467d869e49c | 1159 | break; |
Wayne Roberts |
0:d467d869e49c | 1160 | } // ..switch( DeviceState ) |
Wayne Roberts |
0:d467d869e49c | 1161 | |
Wayne Roberts |
0:d467d869e49c | 1162 | gps.service(); |
Wayne Roberts |
0:d467d869e49c | 1163 | |
Wayne Roberts |
0:d467d869e49c | 1164 | LoRaMacUserContext(); |
Wayne Roberts |
0:d467d869e49c | 1165 | } // ..while( 1 ) |
Wayne Roberts |
0:d467d869e49c | 1166 | } |