classC example

Dependencies:   lorawan1v1

Committer:
Wayne Roberts
Date:
Fri May 04 18:18:03 2018 -0700
Revision:
0:4b6e76c6608f
Child:
1:708d73c0e43c
initial commit

Who changed what in which revision?

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