classC example

Dependencies:   lorawan1v1

Committer:
Wayne Roberts
Date:
Tue May 29 14:21:35 2018 -0700
Revision:
1:708d73c0e43c
Parent:
0:4b6e76c6608f
update to latest library version

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 1:708d73c0e43c 468 #ifdef TARGET_DISCO_L072CZ_LRWAN1
Wayne Roberts 0:4b6e76c6608f 469 if (mcpsIndication->Buffer[0])
Wayne Roberts 0:4b6e76c6608f 470 blue = LED_ON;
Wayne Roberts 0:4b6e76c6608f 471 else
Wayne Roberts 0:4b6e76c6608f 472 blue = LED_OFF;
Wayne Roberts 1:708d73c0e43c 473 #else
Wayne Roberts 1:708d73c0e43c 474 /* your target LED */
Wayne Roberts 1:708d73c0e43c 475 #endif /* ..TARGET_DISCO_L072CZ_LRWAN1 */
Wayne Roberts 0:4b6e76c6608f 476
Wayne Roberts 0:4b6e76c6608f 477 switch( mcpsIndication->Port )
Wayne Roberts 0:4b6e76c6608f 478 {
Wayne Roberts 0:4b6e76c6608f 479 case 1: // The application LED can be controlled on port 1 or 2
Wayne Roberts 0:4b6e76c6608f 480 case 2:
Wayne Roberts 0:4b6e76c6608f 481 break;
Wayne Roberts 0:4b6e76c6608f 482 case 224:
Wayne Roberts 0:4b6e76c6608f 483 if( ComplianceTest.Running == false )
Wayne Roberts 0:4b6e76c6608f 484 {
Wayne Roberts 0:4b6e76c6608f 485 // Check compliance test enable command (i)
Wayne Roberts 0:4b6e76c6608f 486 if( ( mcpsIndication->BufferSize == 4 ) &&
Wayne Roberts 0:4b6e76c6608f 487 ( mcpsIndication->Buffer[0] == 0x01 ) &&
Wayne Roberts 0:4b6e76c6608f 488 ( mcpsIndication->Buffer[1] == 0x01 ) &&
Wayne Roberts 0:4b6e76c6608f 489 ( mcpsIndication->Buffer[2] == 0x01 ) &&
Wayne Roberts 0:4b6e76c6608f 490 ( mcpsIndication->Buffer[3] == 0x01 ) )
Wayne Roberts 0:4b6e76c6608f 491 {
Wayne Roberts 0:4b6e76c6608f 492 gIsTxConfirmed = false;
Wayne Roberts 0:4b6e76c6608f 493 AppPort = 224;
Wayne Roberts 0:4b6e76c6608f 494 gAppDataSize = 2;
Wayne Roberts 0:4b6e76c6608f 495 ComplianceTest.DownLinkCounter = 0;
Wayne Roberts 0:4b6e76c6608f 496 ComplianceTest.LinkCheck = false;
Wayne Roberts 0:4b6e76c6608f 497 ComplianceTest.DemodMargin = 0;
Wayne Roberts 0:4b6e76c6608f 498 ComplianceTest.NbGateways = 0;
Wayne Roberts 0:4b6e76c6608f 499 ComplianceTest.Running = true;
Wayne Roberts 0:4b6e76c6608f 500 ComplianceTest.State = 1;
Wayne Roberts 0:4b6e76c6608f 501
Wayne Roberts 0:4b6e76c6608f 502 MibRequestConfirm_t mibReq;
Wayne Roberts 0:4b6e76c6608f 503 mibReq.Type = MIB_ADR;
Wayne Roberts 0:4b6e76c6608f 504 mibReq.Param.AdrEnable = true;
Wayne Roberts 0:4b6e76c6608f 505 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 506
Wayne Roberts 0:4b6e76c6608f 507 #if defined( USE_BAND_868 )
Wayne Roberts 0:4b6e76c6608f 508 DutyCycleOn = false;
Wayne Roberts 0:4b6e76c6608f 509 #endif
Wayne Roberts 0:4b6e76c6608f 510 }
Wayne Roberts 0:4b6e76c6608f 511 }
Wayne Roberts 0:4b6e76c6608f 512 else
Wayne Roberts 0:4b6e76c6608f 513 {
Wayne Roberts 0:4b6e76c6608f 514 ComplianceTest.State = mcpsIndication->Buffer[0];
Wayne Roberts 0:4b6e76c6608f 515 switch( ComplianceTest.State )
Wayne Roberts 0:4b6e76c6608f 516 {
Wayne Roberts 0:4b6e76c6608f 517 case 0: // Check compliance test disable command (ii)
Wayne Roberts 0:4b6e76c6608f 518 gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
Wayne Roberts 0:4b6e76c6608f 519 AppPort = LORAWAN_APP_PORT;
Wayne Roberts 0:4b6e76c6608f 520 gAppDataSize = LORAWAN_APP_DATA_SIZE;
Wayne Roberts 0:4b6e76c6608f 521 ComplianceTest.DownLinkCounter = 0;
Wayne Roberts 0:4b6e76c6608f 522 ComplianceTest.Running = false;
Wayne Roberts 0:4b6e76c6608f 523
Wayne Roberts 0:4b6e76c6608f 524 MibRequestConfirm_t mibReq;
Wayne Roberts 0:4b6e76c6608f 525 mibReq.Type = MIB_ADR;
Wayne Roberts 0:4b6e76c6608f 526 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
Wayne Roberts 0:4b6e76c6608f 527 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 528 #if defined( USE_BAND_868 )
Wayne Roberts 0:4b6e76c6608f 529 DutyCycleOn = LORAWAN_DUTYCYCLE_ON;
Wayne Roberts 0:4b6e76c6608f 530 #endif
Wayne Roberts 0:4b6e76c6608f 531 break;
Wayne Roberts 0:4b6e76c6608f 532 case 1: // (iii, iv)
Wayne Roberts 0:4b6e76c6608f 533 gAppDataSize = 2;
Wayne Roberts 0:4b6e76c6608f 534 break;
Wayne Roberts 0:4b6e76c6608f 535 case 2: // Enable confirmed messages (v)
Wayne Roberts 0:4b6e76c6608f 536 gIsTxConfirmed = true;
Wayne Roberts 0:4b6e76c6608f 537 ComplianceTest.State = 1;
Wayne Roberts 0:4b6e76c6608f 538 break;
Wayne Roberts 0:4b6e76c6608f 539 case 3: // Disable confirmed messages (vi)
Wayne Roberts 0:4b6e76c6608f 540 gIsTxConfirmed = false;
Wayne Roberts 0:4b6e76c6608f 541 ComplianceTest.State = 1;
Wayne Roberts 0:4b6e76c6608f 542 break;
Wayne Roberts 0:4b6e76c6608f 543 case 4: // (vii)
Wayne Roberts 0:4b6e76c6608f 544 gAppDataSize = mcpsIndication->BufferSize;
Wayne Roberts 0:4b6e76c6608f 545
Wayne Roberts 0:4b6e76c6608f 546 AppData[0] = 4;
Wayne Roberts 0:4b6e76c6608f 547 for( uint8_t i = 1; i < gAppDataSize; i++ )
Wayne Roberts 0:4b6e76c6608f 548 {
Wayne Roberts 0:4b6e76c6608f 549 AppData[i] = mcpsIndication->Buffer[i] + 1;
Wayne Roberts 0:4b6e76c6608f 550 }
Wayne Roberts 0:4b6e76c6608f 551 break;
Wayne Roberts 0:4b6e76c6608f 552 case 5: // (viii)
Wayne Roberts 0:4b6e76c6608f 553 {
Wayne Roberts 0:4b6e76c6608f 554 MlmeReq_t mlmeReq;
Wayne Roberts 0:4b6e76c6608f 555 mlmeReq.Type = MLME_LINK_CHECK;
Wayne Roberts 0:4b6e76c6608f 556 LoRaMacMlmeRequest( &mlmeReq );
Wayne Roberts 0:4b6e76c6608f 557 }
Wayne Roberts 0:4b6e76c6608f 558 break;
Wayne Roberts 0:4b6e76c6608f 559 case 6: // (ix)
Wayne Roberts 0:4b6e76c6608f 560 {
Wayne Roberts 0:4b6e76c6608f 561 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:4b6e76c6608f 562 MlmeReq_t mlmeReq = {};
Wayne Roberts 0:4b6e76c6608f 563
Wayne Roberts 0:4b6e76c6608f 564 // Disable TestMode and revert back to normal operation
Wayne Roberts 0:4b6e76c6608f 565 gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
Wayne Roberts 0:4b6e76c6608f 566 AppPort = LORAWAN_APP_PORT;
Wayne Roberts 0:4b6e76c6608f 567 gAppDataSize = LORAWAN_APP_DATA_SIZE;
Wayne Roberts 0:4b6e76c6608f 568 ComplianceTest.DownLinkCounter = 0;
Wayne Roberts 0:4b6e76c6608f 569 ComplianceTest.Running = false;
Wayne Roberts 0:4b6e76c6608f 570
Wayne Roberts 0:4b6e76c6608f 571 MibRequestConfirm_t mibReq;
Wayne Roberts 0:4b6e76c6608f 572 mibReq.Type = MIB_ADR;
Wayne Roberts 0:4b6e76c6608f 573 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
Wayne Roberts 0:4b6e76c6608f 574 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 575 #if defined( USE_BAND_868 )
Wayne Roberts 0:4b6e76c6608f 576 DutyCycleOn = LORAWAN_DUTYCYCLE_ON;
Wayne Roberts 0:4b6e76c6608f 577 #endif
Wayne Roberts 0:4b6e76c6608f 578
Wayne Roberts 0:4b6e76c6608f 579 mlmeReq.Type = MLME_JOIN;
Wayne Roberts 0:4b6e76c6608f 580
Wayne Roberts 0:4b6e76c6608f 581 mlmeReq.Req.Join.DevEui = DevEui;
Wayne Roberts 0:4b6e76c6608f 582 mlmeReq.Req.Join.JoinEui = JoinEui;
Wayne Roberts 0:4b6e76c6608f 583 mlmeReq.Req.Join.NwkKey = NwkKey;
Wayne Roberts 0:4b6e76c6608f 584 #ifdef LORAWAN_ROOT_APPKEY
Wayne Roberts 0:4b6e76c6608f 585 mlmeReq.Req.Join.AppKey = AppKey;
Wayne Roberts 0:4b6e76c6608f 586 #endif /* LORAWAN_ROOT_APPKEY */
Wayne Roberts 0:4b6e76c6608f 587
Wayne Roberts 0:4b6e76c6608f 588 LoRaMacMlmeRequest( &mlmeReq );
Wayne Roberts 0:4b6e76c6608f 589 #endif /* LORAWAN_JOIN_EUI */
Wayne Roberts 0:4b6e76c6608f 590 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:4b6e76c6608f 591 }
Wayne Roberts 0:4b6e76c6608f 592 break;
Wayne Roberts 0:4b6e76c6608f 593 case 7: // Switch end device Class
Wayne Roberts 0:4b6e76c6608f 594 {
Wayne Roberts 0:4b6e76c6608f 595 MlmeReq_t mlmeReq;
Wayne Roberts 0:4b6e76c6608f 596
Wayne Roberts 0:4b6e76c6608f 597 mlmeReq.Type = MLME_SWITCH_CLASS;
Wayne Roberts 0:4b6e76c6608f 598
Wayne Roberts 0:4b6e76c6608f 599 // CLASS_A = 0, CLASS_B = 1, CLASS_C = 2
Wayne Roberts 0:4b6e76c6608f 600 mlmeReq.Req.SwitchClass.Class = ( DeviceClass_t )mcpsIndication->Buffer[1];
Wayne Roberts 0:4b6e76c6608f 601
Wayne Roberts 0:4b6e76c6608f 602 LoRaMacMlmeRequest( &mlmeReq );
Wayne Roberts 0:4b6e76c6608f 603
Wayne Roberts 0:4b6e76c6608f 604 PrepareTxFrame( AppPort );
Wayne Roberts 0:4b6e76c6608f 605 /*status =*/ SendFrame(gIsTxConfirmed, gAppDataSize);
Wayne Roberts 0:4b6e76c6608f 606 }
Wayne Roberts 0:4b6e76c6608f 607 break;
Wayne Roberts 0:4b6e76c6608f 608 case 8: // Send PingSlotInfoReq
Wayne Roberts 0:4b6e76c6608f 609 {
Wayne Roberts 0:4b6e76c6608f 610 MlmeReq_t mlmeReq;
Wayne Roberts 0:4b6e76c6608f 611
Wayne Roberts 0:4b6e76c6608f 612 mlmeReq.Type = MLME_PING_SLOT_INFO;
Wayne Roberts 0:4b6e76c6608f 613
Wayne Roberts 0:4b6e76c6608f 614 mlmeReq.Req.PingSlotInfo.Value = mcpsIndication->Buffer[1];
Wayne Roberts 0:4b6e76c6608f 615
Wayne Roberts 0:4b6e76c6608f 616 LoRaMacMlmeRequest( &mlmeReq );
Wayne Roberts 0:4b6e76c6608f 617 PrepareTxFrame( AppPort );
Wayne Roberts 0:4b6e76c6608f 618 /*status =*/ SendFrame(gIsTxConfirmed, gAppDataSize);
Wayne Roberts 0:4b6e76c6608f 619 }
Wayne Roberts 0:4b6e76c6608f 620 break;
Wayne Roberts 0:4b6e76c6608f 621 case 9: // Send BeaconTimingReq
Wayne Roberts 0:4b6e76c6608f 622 {
Wayne Roberts 0:4b6e76c6608f 623 MlmeReq_t mlmeReq;
Wayne Roberts 0:4b6e76c6608f 624
Wayne Roberts 0:4b6e76c6608f 625 mlmeReq.Type = MLME_BEACON_TIMING;
Wayne Roberts 0:4b6e76c6608f 626
Wayne Roberts 0:4b6e76c6608f 627 LoRaMacMlmeRequest( &mlmeReq );
Wayne Roberts 0:4b6e76c6608f 628 PrepareTxFrame( AppPort );
Wayne Roberts 0:4b6e76c6608f 629 /*status =*/ SendFrame(gIsTxConfirmed, gAppDataSize);
Wayne Roberts 0:4b6e76c6608f 630 }
Wayne Roberts 0:4b6e76c6608f 631 break;
Wayne Roberts 0:4b6e76c6608f 632 default:
Wayne Roberts 0:4b6e76c6608f 633 break;
Wayne Roberts 0:4b6e76c6608f 634 }
Wayne Roberts 0:4b6e76c6608f 635 }
Wayne Roberts 0:4b6e76c6608f 636 break;
Wayne Roberts 0:4b6e76c6608f 637 default:
Wayne Roberts 0:4b6e76c6608f 638 break;
Wayne Roberts 0:4b6e76c6608f 639 }
Wayne Roberts 0:4b6e76c6608f 640
Wayne Roberts 0:4b6e76c6608f 641 }
Wayne Roberts 0:4b6e76c6608f 642
Wayne Roberts 0:4b6e76c6608f 643 } // ..McpsIndication()
Wayne Roberts 0:4b6e76c6608f 644
Wayne Roberts 0:4b6e76c6608f 645 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:4b6e76c6608f 646 void
Wayne Roberts 0:4b6e76c6608f 647 join(uint8_t tries)
Wayne Roberts 0:4b6e76c6608f 648 {
Wayne Roberts 0:4b6e76c6608f 649 char str[64];
Wayne Roberts 0:4b6e76c6608f 650 LoRaMacStatus_t status;
Wayne Roberts 0:4b6e76c6608f 651 MlmeReq_t mlmeReq = { };
Wayne Roberts 0:4b6e76c6608f 652
Wayne Roberts 0:4b6e76c6608f 653 mlmeReq.Type = MLME_JOIN;
Wayne Roberts 0:4b6e76c6608f 654
Wayne Roberts 0:4b6e76c6608f 655 #ifdef LORAWAN_ROOT_APPKEY
Wayne Roberts 0:4b6e76c6608f 656 mlmeReq.Req.Join.AppKey = AppKey;
Wayne Roberts 0:4b6e76c6608f 657 #endif
Wayne Roberts 0:4b6e76c6608f 658 mlmeReq.Req.Join.DevEui = DevEui;
Wayne Roberts 0:4b6e76c6608f 659 mlmeReq.Req.Join.JoinEui = JoinEui;
Wayne Roberts 0:4b6e76c6608f 660 mlmeReq.Req.Join.NwkKey = NwkKey;
Wayne Roberts 0:4b6e76c6608f 661 mlmeReq.Req.Join.NbTrials = tries;
Wayne Roberts 0:4b6e76c6608f 662 status = LoRaMacMlmeRequest( &mlmeReq );
Wayne Roberts 0:4b6e76c6608f 663 if (status != LORAMAC_STATUS_OK) {
Wayne Roberts 0:4b6e76c6608f 664 LoRaMacStatus_to_string(status, str);
Wayne Roberts 0:4b6e76c6608f 665 } else {
Wayne Roberts 0:4b6e76c6608f 666 extLed = 1;
Wayne Roberts 0:4b6e76c6608f 667 flags.startup = 1;
Wayne Roberts 0:4b6e76c6608f 668 }
Wayne Roberts 0:4b6e76c6608f 669 }
Wayne Roberts 0:4b6e76c6608f 670 #endif /* LORAWAN_JOIN_EUI */
Wayne Roberts 0:4b6e76c6608f 671
Wayne Roberts 0:4b6e76c6608f 672 /*!
Wayne Roberts 0:4b6e76c6608f 673 * \brief MLME-Confirm event function
Wayne Roberts 0:4b6e76c6608f 674 *
Wayne Roberts 0:4b6e76c6608f 675 * \param [IN] mlmeConfirm - Pointer to the confirm structure,
Wayne Roberts 0:4b6e76c6608f 676 * containing confirm attributes.
Wayne Roberts 0:4b6e76c6608f 677 */
Wayne Roberts 0:4b6e76c6608f 678 static void MlmeConfirm( const MlmeConfirm_t *mlmeConfirm )
Wayne Roberts 0:4b6e76c6608f 679 {
Wayne Roberts 0:4b6e76c6608f 680 char str[64];
Wayne Roberts 0:4b6e76c6608f 681 static uint8_t failCnt = 0;
Wayne Roberts 0:4b6e76c6608f 682
Wayne Roberts 0:4b6e76c6608f 683 Mlme_to_string(mlmeConfirm->MlmeRequest, str);
Wayne Roberts 0:4b6e76c6608f 684 APP_PRINTF("MlmeConfirm %s ", str);
Wayne Roberts 0:4b6e76c6608f 685 LoRaMacEventInfoStatus_to_string(mlmeConfirm->Status, str);
Wayne Roberts 0:4b6e76c6608f 686 if (mlmeConfirm->Status != LORAMAC_EVENT_INFO_STATUS_OK) {
Wayne Roberts 0:4b6e76c6608f 687 APP_PRINTF("\e[31m%s \e[0m\r\n", str);
Wayne Roberts 0:4b6e76c6608f 688 } else {
Wayne Roberts 0:4b6e76c6608f 689 APP_PRINTF("%s\r\n", str);
Wayne Roberts 0:4b6e76c6608f 690 }
Wayne Roberts 0:4b6e76c6608f 691
Wayne Roberts 0:4b6e76c6608f 692 #if defined(LORAWAN_ROOT_APPKEY) && defined(LORAWAN_JOIN_EUI)
Wayne Roberts 0:4b6e76c6608f 693 /* 1v1 joinNonce is incrementing non-volatile value */
Wayne Roberts 0:4b6e76c6608f 694 if (mlmeConfirm->MlmeRequest == MLME_JOIN) {
Wayne Roberts 0:4b6e76c6608f 695 vt.APP_PRINTF(" rxJoinNonce:%u vs %u",
Wayne Roberts 0:4b6e76c6608f 696 mlmeConfirm->fields.join.rxJoinNonce,
Wayne Roberts 0:4b6e76c6608f 697 mlmeConfirm->fields.join.myJoinNonce
Wayne Roberts 0:4b6e76c6608f 698 );
Wayne Roberts 0:4b6e76c6608f 699 }
Wayne Roberts 0:4b6e76c6608f 700 #endif /* LORAWAN_ROOT_APPKEY */
Wayne Roberts 0:4b6e76c6608f 701
Wayne Roberts 0:4b6e76c6608f 702 if (mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK)
Wayne Roberts 0:4b6e76c6608f 703 {
Wayne Roberts 0:4b6e76c6608f 704 failCnt = 0;
Wayne Roberts 0:4b6e76c6608f 705 switch (mlmeConfirm->MlmeRequest)
Wayne Roberts 0:4b6e76c6608f 706 {
Wayne Roberts 0:4b6e76c6608f 707 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:4b6e76c6608f 708 case MLME_JOIN:
Wayne Roberts 0:4b6e76c6608f 709 {
Wayne Roberts 0:4b6e76c6608f 710 // Status is OK, node has joined the network
Wayne Roberts 0:4b6e76c6608f 711 /* collect any mac cmds from server until expected channel mask */
Wayne Roberts 0:4b6e76c6608f 712 extLed = 0;
Wayne Roberts 0:4b6e76c6608f 713 DeviceState = DEVICE_STATE_JOIN_OK;
Wayne Roberts 0:4b6e76c6608f 714 break;
Wayne Roberts 0:4b6e76c6608f 715 }
Wayne Roberts 0:4b6e76c6608f 716 #endif /* LORAWAN_JOIN_EUI*/
Wayne Roberts 0:4b6e76c6608f 717 case MLME_LINK_CHECK:
Wayne Roberts 0:4b6e76c6608f 718 {
Wayne Roberts 0:4b6e76c6608f 719 // Check DemodMargin
Wayne Roberts 0:4b6e76c6608f 720 // Check NbGateways
Wayne Roberts 0:4b6e76c6608f 721 if( ComplianceTest.Running == true )
Wayne Roberts 0:4b6e76c6608f 722 {
Wayne Roberts 0:4b6e76c6608f 723 ComplianceTest.LinkCheck = true;
Wayne Roberts 0:4b6e76c6608f 724 ComplianceTest.DemodMargin = mlmeConfirm->fields.link.DemodMargin;
Wayne Roberts 0:4b6e76c6608f 725 ComplianceTest.NbGateways = mlmeConfirm->fields.link.NbGateways;
Wayne Roberts 0:4b6e76c6608f 726 }
Wayne Roberts 0:4b6e76c6608f 727 break;
Wayne Roberts 0:4b6e76c6608f 728 }
Wayne Roberts 0:4b6e76c6608f 729 case MLME_TIME_REQ:
Wayne Roberts 0:4b6e76c6608f 730 break;
Wayne Roberts 0:4b6e76c6608f 731 default:
Wayne Roberts 0:4b6e76c6608f 732 /* TODO: handle unknown MLME request */
Wayne Roberts 0:4b6e76c6608f 733 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:4b6e76c6608f 734 break;
Wayne Roberts 0:4b6e76c6608f 735 }
Wayne Roberts 0:4b6e76c6608f 736 }
Wayne Roberts 0:4b6e76c6608f 737 else // not ok...
Wayne Roberts 0:4b6e76c6608f 738 {
Wayne Roberts 0:4b6e76c6608f 739 failCnt++;
Wayne Roberts 0:4b6e76c6608f 740
Wayne Roberts 0:4b6e76c6608f 741 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:4b6e76c6608f 742 if (failCnt > 5) {
Wayne Roberts 0:4b6e76c6608f 743 join(1);
Wayne Roberts 0:4b6e76c6608f 744 return;
Wayne Roberts 0:4b6e76c6608f 745 }
Wayne Roberts 0:4b6e76c6608f 746 #endif
Wayne Roberts 0:4b6e76c6608f 747
Wayne Roberts 0:4b6e76c6608f 748 switch( mlmeConfirm->MlmeRequest )
Wayne Roberts 0:4b6e76c6608f 749 {
Wayne Roberts 0:4b6e76c6608f 750 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:4b6e76c6608f 751 case MLME_JOIN:
Wayne Roberts 0:4b6e76c6608f 752 {
Wayne Roberts 0:4b6e76c6608f 753 // Join failed, restart join procedure
Wayne Roberts 0:4b6e76c6608f 754 break;
Wayne Roberts 0:4b6e76c6608f 755 }
Wayne Roberts 0:4b6e76c6608f 756 #endif /* LORAWAN_JOIN_EUI */
Wayne Roberts 0:4b6e76c6608f 757 case MLME_LINK_CHECK:
Wayne Roberts 0:4b6e76c6608f 758 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:4b6e76c6608f 759 break;
Wayne Roberts 0:4b6e76c6608f 760 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:4b6e76c6608f 761 case MLME_REJOIN_0:
Wayne Roberts 0:4b6e76c6608f 762 break;
Wayne Roberts 0:4b6e76c6608f 763 case MLME_REJOIN_2:
Wayne Roberts 0:4b6e76c6608f 764 break;
Wayne Roberts 0:4b6e76c6608f 765 case MLME_TIME_REQ:
Wayne Roberts 0:4b6e76c6608f 766 break;
Wayne Roberts 0:4b6e76c6608f 767 #endif /* LORAWAN_JOIN_EUI */
Wayne Roberts 0:4b6e76c6608f 768 default:
Wayne Roberts 0:4b6e76c6608f 769 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:4b6e76c6608f 770 break;
Wayne Roberts 0:4b6e76c6608f 771 }
Wayne Roberts 0:4b6e76c6608f 772 }
Wayne Roberts 0:4b6e76c6608f 773 } // ..MlmeConfirm
Wayne Roberts 0:4b6e76c6608f 774
Wayne Roberts 0:4b6e76c6608f 775 static void MlmeIndication( const MlmeIndication_t *MlmeIndication )
Wayne Roberts 0:4b6e76c6608f 776 {
Wayne Roberts 0:4b6e76c6608f 777 char str[48];
Wayne Roberts 0:4b6e76c6608f 778 MibRequestConfirm_t mibReq;
Wayne Roberts 0:4b6e76c6608f 779
Wayne Roberts 0:4b6e76c6608f 780 Mlme_to_string(MlmeIndication->MlmeIndication, str);
Wayne Roberts 0:4b6e76c6608f 781 APP_PRINTF("MlmeIndication %s ", str);
Wayne Roberts 0:4b6e76c6608f 782 LoRaMacEventInfoStatus_to_string(MlmeIndication->Status, str);
Wayne Roberts 0:4b6e76c6608f 783 if (MlmeIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK) {
Wayne Roberts 0:4b6e76c6608f 784 APP_PRINTF("\e[31m%s \e[0m\r\n", str);
Wayne Roberts 0:4b6e76c6608f 785 } else {
Wayne Roberts 0:4b6e76c6608f 786 APP_PRINTF("%s\r\n", str);
Wayne Roberts 0:4b6e76c6608f 787 }
Wayne Roberts 0:4b6e76c6608f 788
Wayne Roberts 0:4b6e76c6608f 789 switch( MlmeIndication->MlmeIndication )
Wayne Roberts 0:4b6e76c6608f 790 {
Wayne Roberts 0:4b6e76c6608f 791 case MLME_SWITCH_CLASS:
Wayne Roberts 0:4b6e76c6608f 792 {
Wayne Roberts 0:4b6e76c6608f 793 /* mac gave up on beacon */
Wayne Roberts 0:4b6e76c6608f 794 mibReq.Type = MIB_DEVICE_CLASS;
Wayne Roberts 0:4b6e76c6608f 795 mibReq.Param.Class = CLASS_A;
Wayne Roberts 0:4b6e76c6608f 796 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 797
Wayne Roberts 0:4b6e76c6608f 798 // Switch to class A again
Wayne Roberts 0:4b6e76c6608f 799 DeviceState = DEVICE_STATE_SLEEP; // class-B manual switch
Wayne Roberts 0:4b6e76c6608f 800 break;
Wayne Roberts 0:4b6e76c6608f 801 }
Wayne Roberts 0:4b6e76c6608f 802 case MLME_BEACON:
Wayne Roberts 0:4b6e76c6608f 803 {
Wayne Roberts 0:4b6e76c6608f 804 LoRaMacEventInfoStatus_to_string(MlmeIndication->Status, str);
Wayne Roberts 0:4b6e76c6608f 805 break;
Wayne Roberts 0:4b6e76c6608f 806
Wayne Roberts 0:4b6e76c6608f 807 }
Wayne Roberts 0:4b6e76c6608f 808 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:4b6e76c6608f 809 case MLME_JOIN:
Wayne Roberts 0:4b6e76c6608f 810 APP_PRINTF("%" PRIu32 "hz try%u ", MlmeIndication->freqHz, MlmeIndication->JoinRequestTrials);
Wayne Roberts 0:4b6e76c6608f 811 break;
Wayne Roberts 0:4b6e76c6608f 812 #endif /* !LORAWAN_JOIN_EUI */
Wayne Roberts 0:4b6e76c6608f 813 default:
Wayne Roberts 0:4b6e76c6608f 814 break;
Wayne Roberts 0:4b6e76c6608f 815 }
Wayne Roberts 0:4b6e76c6608f 816
Wayne Roberts 0:4b6e76c6608f 817 } // ..MlmeIndication()
Wayne Roberts 0:4b6e76c6608f 818
Wayne Roberts 0:4b6e76c6608f 819 uint8_t periodicity;
Wayne Roberts 0:4b6e76c6608f 820
Wayne Roberts 0:4b6e76c6608f 821
Wayne Roberts 0:4b6e76c6608f 822 void SerialRxProcess( void )
Wayne Roberts 0:4b6e76c6608f 823 {
Wayne Roberts 0:4b6e76c6608f 824 char str[48];
Wayne Roberts 0:4b6e76c6608f 825 MibRequestConfirm_t mibReq;
Wayne Roberts 0:4b6e76c6608f 826 LoRaMacStatus_t status;
Wayne Roberts 0:4b6e76c6608f 827 MlmeReq_t mlmeReq;
Wayne Roberts 0:4b6e76c6608f 828 #ifndef LORAWAN_JOIN_EUI
Wayne Roberts 0:4b6e76c6608f 829 static uint8_t icnt = 0;
Wayne Roberts 0:4b6e76c6608f 830 #endif
Wayne Roberts 0:4b6e76c6608f 831
Wayne Roberts 0:4b6e76c6608f 832 if( pc.readable( ) == true ) {
Wayne Roberts 0:4b6e76c6608f 833 char ch = pc.getc();
Wayne Roberts 0:4b6e76c6608f 834 #ifndef LORAWAN_JOIN_EUI
Wayne Roberts 0:4b6e76c6608f 835 if (ch == 'I') {
Wayne Roberts 0:4b6e76c6608f 836 if (++icnt == 3) {
Wayne Roberts 0:4b6e76c6608f 837 APP_PRINTF("reset-fcnts\r\n");
Wayne Roberts 0:4b6e76c6608f 838 eeprom_clear(EEPROM_AFCNTDWN);
Wayne Roberts 0:4b6e76c6608f 839 eeprom_clear(EEPROM_NFCNTDWN);
Wayne Roberts 0:4b6e76c6608f 840 eeprom_clear(EEPROM_FCNTUP);
Wayne Roberts 0:4b6e76c6608f 841 }
Wayne Roberts 0:4b6e76c6608f 842 } else
Wayne Roberts 0:4b6e76c6608f 843 icnt = 0;
Wayne Roberts 0:4b6e76c6608f 844 #endif /* !LORAWAN_JOIN_EUI */
Wayne Roberts 0:4b6e76c6608f 845
Wayne Roberts 0:4b6e76c6608f 846 if ( ch >= '0' && ch <= '9') {
Wayne Roberts 0:4b6e76c6608f 847 c_ch = ch - '0';
Wayne Roberts 0:4b6e76c6608f 848 DeviceState = DEVICE_STATE_SEND;
Wayne Roberts 0:4b6e76c6608f 849 return;
Wayne Roberts 0:4b6e76c6608f 850 }
Wayne Roberts 0:4b6e76c6608f 851 switch( ch ) {
Wayne Roberts 0:4b6e76c6608f 852 case 'C':
Wayne Roberts 0:4b6e76c6608f 853 mibReq.Type = MIB_DEVICE_CLASS;
Wayne Roberts 0:4b6e76c6608f 854 mibReq.Param.Class = CLASS_C;
Wayne Roberts 0:4b6e76c6608f 855 status = LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 856 LoRaMacStatus_to_string(status, str);
Wayne Roberts 0:4b6e76c6608f 857 APP_PRINTF("to classC:%s\r\n", str);
Wayne Roberts 0:4b6e76c6608f 858 break;
Wayne Roberts 0:4b6e76c6608f 859 case 'L':
Wayne Roberts 0:4b6e76c6608f 860 mlmeReq.Type = MLME_LINK_CHECK;
Wayne Roberts 0:4b6e76c6608f 861 status = LoRaMacMlmeRequest( &mlmeReq );
Wayne Roberts 0:4b6e76c6608f 862 if (status == LORAMAC_STATUS_OK)
Wayne Roberts 0:4b6e76c6608f 863 SendFrame(false, 0);
Wayne Roberts 0:4b6e76c6608f 864 else {
Wayne Roberts 0:4b6e76c6608f 865 LoRaMacStatus_to_string(status, str);
Wayne Roberts 0:4b6e76c6608f 866 APP_PRINTF("%s\r\n", str);
Wayne Roberts 0:4b6e76c6608f 867 }
Wayne Roberts 0:4b6e76c6608f 868 break;
Wayne Roberts 0:4b6e76c6608f 869 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:4b6e76c6608f 870 case 'j':
Wayne Roberts 0:4b6e76c6608f 871 DeviceState = DEVICE_STATE_JOIN;
Wayne Roberts 0:4b6e76c6608f 872 break;
Wayne Roberts 0:4b6e76c6608f 873 #endif
Wayne Roberts 0:4b6e76c6608f 874 case 'a':
Wayne Roberts 0:4b6e76c6608f 875 flags.ackDownlink ^= 1;
Wayne Roberts 0:4b6e76c6608f 876 APP_PRINTF("ackDownlink:%u\r\n", flags.ackDownlink);
Wayne Roberts 0:4b6e76c6608f 877 break;
Wayne Roberts 0:4b6e76c6608f 878 case '.':
Wayne Roberts 0:4b6e76c6608f 879 print_buf(DevEui, 8, "DevEui");
Wayne Roberts 0:4b6e76c6608f 880 mibReq.Type = MIB_DEVICE_CLASS;
Wayne Roberts 0:4b6e76c6608f 881 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 882 APP_PRINTF("class-");
Wayne Roberts 0:4b6e76c6608f 883 switch (mibReq.Param.Class) {
Wayne Roberts 0:4b6e76c6608f 884 case CLASS_A: APP_PRINTF("A "); break;
Wayne Roberts 0:4b6e76c6608f 885 case CLASS_B: APP_PRINTF("B "); break;
Wayne Roberts 0:4b6e76c6608f 886 case CLASS_C: APP_PRINTF("C "); break;
Wayne Roberts 0:4b6e76c6608f 887 }
Wayne Roberts 0:4b6e76c6608f 888 mibReq.Type = MIB_RX2_CHANNEL;
Wayne Roberts 0:4b6e76c6608f 889 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 890 APP_PRINTF(" rx2 %uhz dr%u, ackDownlink:%u\r\n", mibReq.Param.Rx2Channel.FrequencyHz, mibReq.Param.Rx2Channel.Datarate, flags.ackDownlink);
Wayne Roberts 0:4b6e76c6608f 891 LoRaMacPrintStatus();
Wayne Roberts 0:4b6e76c6608f 892 break;
Wayne Roberts 0:4b6e76c6608f 893 case '?':
Wayne Roberts 0:4b6e76c6608f 894 APP_PRINTF("C start classC\r\n");
Wayne Roberts 0:4b6e76c6608f 895 APP_PRINTF("L send link check\r\n");
Wayne Roberts 0:4b6e76c6608f 896 APP_PRINTF("j send joinReq\r\n");
Wayne Roberts 0:4b6e76c6608f 897 APP_PRINTF("a toggle ackDownlink\r\n");
Wayne Roberts 0:4b6e76c6608f 898 APP_PRINTF(". print status\r\n");
Wayne Roberts 0:4b6e76c6608f 899 break;
Wayne Roberts 0:4b6e76c6608f 900 default:
Wayne Roberts 0:4b6e76c6608f 901 break;
Wayne Roberts 0:4b6e76c6608f 902 }
Wayne Roberts 0:4b6e76c6608f 903 }
Wayne Roberts 0:4b6e76c6608f 904 }
Wayne Roberts 0:4b6e76c6608f 905
Wayne Roberts 0:4b6e76c6608f 906 static void button_isr()
Wayne Roberts 0:4b6e76c6608f 907 {
Wayne Roberts 0:4b6e76c6608f 908 c_ch = 0xff;
Wayne Roberts 0:4b6e76c6608f 909 DeviceState = DEVICE_STATE_SEND;
Wayne Roberts 0:4b6e76c6608f 910 buttonStartAt = LoRaMacReadTimer();
Wayne Roberts 0:4b6e76c6608f 911 }
Wayne Roberts 0:4b6e76c6608f 912
Wayne Roberts 0:4b6e76c6608f 913 static const LoRaMacPrimitives_t LoRaMacPrimitives = {
Wayne Roberts 0:4b6e76c6608f 914 McpsConfirm,
Wayne Roberts 0:4b6e76c6608f 915 McpsIndication,
Wayne Roberts 0:4b6e76c6608f 916 MlmeConfirm,
Wayne Roberts 0:4b6e76c6608f 917 MlmeIndication
Wayne Roberts 0:4b6e76c6608f 918 };
Wayne Roberts 0:4b6e76c6608f 919
Wayne Roberts 0:4b6e76c6608f 920 static const LoRaMacCallback_t LoRaMacCallbacks = {
Wayne Roberts 0:4b6e76c6608f 921 BoardGetBatteryLevel,
Wayne Roberts 0:4b6e76c6608f 922 NULL
Wayne Roberts 0:4b6e76c6608f 923 };
Wayne Roberts 0:4b6e76c6608f 924
Wayne Roberts 0:4b6e76c6608f 925 /**
Wayne Roberts 0:4b6e76c6608f 926 * Main application entry point.
Wayne Roberts 0:4b6e76c6608f 927 */
Wayne Roberts 0:4b6e76c6608f 928 int main()
Wayne Roberts 0:4b6e76c6608f 929 {
Wayne Roberts 0:4b6e76c6608f 930 LoRaMacStatus_t status;
Wayne Roberts 0:4b6e76c6608f 931 MibRequestConfirm_t mibReq;
Wayne Roberts 0:4b6e76c6608f 932
Wayne Roberts 0:4b6e76c6608f 933 DeviceState = DEVICE_STATE_INIT;
Wayne Roberts 0:4b6e76c6608f 934
Wayne Roberts 0:4b6e76c6608f 935 if (sleep_manager_can_deep_sleep())
Wayne Roberts 0:4b6e76c6608f 936 sleep_manager_lock_deep_sleep(); // prevent deep sleep
Wayne Roberts 0:4b6e76c6608f 937
Wayne Roberts 0:4b6e76c6608f 938 #ifdef JUMPER_ENABLE
Wayne Roberts 0:4b6e76c6608f 939 jumper_out = 1;
Wayne Roberts 0:4b6e76c6608f 940 jumper_in.mode(PullDown);
Wayne Roberts 0:4b6e76c6608f 941 jumper_in.rise(jumper_callback);
Wayne Roberts 0:4b6e76c6608f 942 // Q: does InterruptIn.rise() call immediately if already high?
Wayne Roberts 0:4b6e76c6608f 943 if (jumper_in.read())
Wayne Roberts 0:4b6e76c6608f 944 jumper_callback(); // A: probably not
Wayne Roberts 0:4b6e76c6608f 945 #endif /* JUMPER_ENABLE */
Wayne Roberts 0:4b6e76c6608f 946
Wayne Roberts 0:4b6e76c6608f 947 while( 1 )
Wayne Roberts 0:4b6e76c6608f 948 {
Wayne Roberts 0:4b6e76c6608f 949 SerialRxProcess( );
Wayne Roberts 0:4b6e76c6608f 950
Wayne Roberts 0:4b6e76c6608f 951 switch( DeviceState )
Wayne Roberts 0:4b6e76c6608f 952 {
Wayne Roberts 0:4b6e76c6608f 953 case DEVICE_STATE_INIT:
Wayne Roberts 0:4b6e76c6608f 954 {
Wayne Roberts 0:4b6e76c6608f 955 status = LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks );
Wayne Roberts 0:4b6e76c6608f 956 if (LORAMAC_STATUS_OK != status) {
Wayne Roberts 0:4b6e76c6608f 957 char str[48];
Wayne Roberts 0:4b6e76c6608f 958 LoRaMacStatus_to_string(status, str);
Wayne Roberts 0:4b6e76c6608f 959 APP_PRINTF("MacInit: %s\r\n", str);
Wayne Roberts 0:4b6e76c6608f 960 for (;;) asm("nop");
Wayne Roberts 0:4b6e76c6608f 961 }
Wayne Roberts 0:4b6e76c6608f 962
Wayne Roberts 0:4b6e76c6608f 963 pwm.period(1.0 / 60);
Wayne Roberts 0:4b6e76c6608f 964 c_ch = 0xff;
Wayne Roberts 0:4b6e76c6608f 965 button_pin.mode(PullDown);
Wayne Roberts 0:4b6e76c6608f 966 #ifdef TARGET_DISCO_L072CZ_LRWAN1
Wayne Roberts 0:4b6e76c6608f 967 button_pin.fall(button_isr);
Wayne Roberts 0:4b6e76c6608f 968 #else
Wayne Roberts 0:4b6e76c6608f 969 button_pin.rise(button_isr);
Wayne Roberts 0:4b6e76c6608f 970 #endif
Wayne Roberts 0:4b6e76c6608f 971
Wayne Roberts 0:4b6e76c6608f 972 mibReq.Type = MIB_ADR;
Wayne Roberts 0:4b6e76c6608f 973 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
Wayne Roberts 0:4b6e76c6608f 974 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 975
Wayne Roberts 0:4b6e76c6608f 976 mibReq.Type = MIB_PUBLIC_NETWORK;
Wayne Roberts 0:4b6e76c6608f 977 mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK;
Wayne Roberts 0:4b6e76c6608f 978 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 979
Wayne Roberts 0:4b6e76c6608f 980 #if defined( USE_BAND_868 )
Wayne Roberts 0:4b6e76c6608f 981 DutyCycleOn = LORAWAN_DUTYCYCLE_ON ;
Wayne Roberts 0:4b6e76c6608f 982 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
Wayne Roberts 0:4b6e76c6608f 983 LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 );
Wayne Roberts 0:4b6e76c6608f 984 LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 );
Wayne Roberts 0:4b6e76c6608f 985 LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 );
Wayne Roberts 0:4b6e76c6608f 986 LoRaMacChannelAdd( 6, ( ChannelParams_t )LC7 );
Wayne Roberts 0:4b6e76c6608f 987 LoRaMacChannelAdd( 7, ( ChannelParams_t )LC8 );
Wayne Roberts 0:4b6e76c6608f 988 LoRaMacChannelAdd( 8, ( ChannelParams_t )LC9 );
Wayne Roberts 0:4b6e76c6608f 989 LoRaMacChannelAdd( 9, ( ChannelParams_t )LC10 );
Wayne Roberts 0:4b6e76c6608f 990
Wayne Roberts 0:4b6e76c6608f 991 mibReq.Type = MIB_RX2_CHANNEL;
Wayne Roberts 0:4b6e76c6608f 992 mibReq.Param.Rx2Channel = ( Rx2ChannelParams_t ){ 869525000, DR_3 };
Wayne Roberts 0:4b6e76c6608f 993 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 994 #endif
Wayne Roberts 0:4b6e76c6608f 995
Wayne Roberts 0:4b6e76c6608f 996 #endif
Wayne Roberts 0:4b6e76c6608f 997
Wayne Roberts 0:4b6e76c6608f 998 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:4b6e76c6608f 999
Wayne Roberts 0:4b6e76c6608f 1000 #ifndef SENETCO /* for senet, use network provided DevEUI */
Wayne Roberts 0:4b6e76c6608f 1001 // Initialize LoRaMac device unique ID
Wayne Roberts 0:4b6e76c6608f 1002 HardwareIDtoDevEUI(DevEui);
Wayne Roberts 0:4b6e76c6608f 1003 #ifdef LORAWAN_ROOT_APPKEY
Wayne Roberts 0:4b6e76c6608f 1004 // inverted DevEui provisioned as v1.1 on server (non-inv = lorawan1v0)
Wayne Roberts 0:4b6e76c6608f 1005 for (int i = 0; i < 8; i++)
Wayne Roberts 0:4b6e76c6608f 1006 DevEui[i] ^= 0xff;
Wayne Roberts 0:4b6e76c6608f 1007 #endif /* LORAWAN_ROOT_APPKEY */
Wayne Roberts 0:4b6e76c6608f 1008 #endif /* !SENETCO */
Wayne Roberts 0:4b6e76c6608f 1009 print_buf(DevEui, 8, "DevEui");
Wayne Roberts 0:4b6e76c6608f 1010 DeviceState = DEVICE_STATE_JOIN;
Wayne Roberts 0:4b6e76c6608f 1011 #else /* ABP... */
Wayne Roberts 0:4b6e76c6608f 1012
Wayne Roberts 0:4b6e76c6608f 1013 mibReq.Type = MIB_DEV_ADDR;
Wayne Roberts 0:4b6e76c6608f 1014 mibReq.Param.DevAddr = DevAddr;
Wayne Roberts 0:4b6e76c6608f 1015 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 1016 SerialDisplayUpdateDevAddr(DevAddr);
Wayne Roberts 0:4b6e76c6608f 1017
Wayne Roberts 0:4b6e76c6608f 1018 mibReq.Type = MIB_APP_SKEY;
Wayne Roberts 0:4b6e76c6608f 1019 mibReq.Param.key = AppSKey;
Wayne Roberts 0:4b6e76c6608f 1020 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 1021 SerialDisplayUpdateKey(ROW_AppSKey, AppSKey);
Wayne Roberts 0:4b6e76c6608f 1022
Wayne Roberts 0:4b6e76c6608f 1023 #if defined(LORAWAN_SNwkSIntKey) && defined(LORAWAN_NwkSEncKey)
Wayne Roberts 0:4b6e76c6608f 1024 /* lorawan 1v1 ABP */
Wayne Roberts 0:4b6e76c6608f 1025 mibReq.Type = MIB_NwkSEncKey;
Wayne Roberts 0:4b6e76c6608f 1026 mibReq.Param.key = NwkSEncKey;
Wayne Roberts 0:4b6e76c6608f 1027 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 1028 SerialDisplayUpdateKey(ROW_NwkSEncKey, NwkSEncKey);
Wayne Roberts 0:4b6e76c6608f 1029
Wayne Roberts 0:4b6e76c6608f 1030 mibReq.Type = MIB_SNwkSIntKey;
Wayne Roberts 0:4b6e76c6608f 1031 mibReq.Param.key = SNwkSIntKey;
Wayne Roberts 0:4b6e76c6608f 1032 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 1033 SerialDisplayUpdateKey(ROW_SNwkSIntKey, SNwkSIntKey);
Wayne Roberts 0:4b6e76c6608f 1034
Wayne Roberts 0:4b6e76c6608f 1035 mibReq.Type = MIB_FNwkSIntKey;
Wayne Roberts 0:4b6e76c6608f 1036 mibReq.Param.key = FNwkSIntKey;
Wayne Roberts 0:4b6e76c6608f 1037 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 1038 SerialDisplayUpdateKey(ROW_FNwkSIntKey, mibReq.Param.key);
Wayne Roberts 0:4b6e76c6608f 1039 #else
Wayne Roberts 0:4b6e76c6608f 1040 /* lorawan 1v0 ABP */
Wayne Roberts 0:4b6e76c6608f 1041 mibReq.Type = MIB_NwkSKey;
Wayne Roberts 0:4b6e76c6608f 1042 mibReq.Param.key = FNwkSIntKey;
Wayne Roberts 0:4b6e76c6608f 1043 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 1044 SerialDisplayUpdateKey(ROW_FNwkSIntKey, mibReq.Param.key);
Wayne Roberts 0:4b6e76c6608f 1045 #endif
Wayne Roberts 0:4b6e76c6608f 1046
Wayne Roberts 0:4b6e76c6608f 1047 DeviceState = DEVICE_STATE_TRIGGER;
Wayne Roberts 0:4b6e76c6608f 1048 #endif /* !LORAWAN_JOIN_EUI */
Wayne Roberts 0:4b6e76c6608f 1049
Wayne Roberts 0:4b6e76c6608f 1050 #if defined( USE_BAND_ARIB_8CH )
Wayne Roberts 0:4b6e76c6608f 1051 mibReq.Type = MIB_MAX_LISTEN_TIME;
Wayne Roberts 0:4b6e76c6608f 1052 mibReq.Param.MaxListenTime = 7000000;
Wayne Roberts 0:4b6e76c6608f 1053 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 1054 #endif /* USE_BAND_ARIB_8CH */
Wayne Roberts 0:4b6e76c6608f 1055
Wayne Roberts 0:4b6e76c6608f 1056
Wayne Roberts 0:4b6e76c6608f 1057 flags.ackDownlink = 1;
Wayne Roberts 0:4b6e76c6608f 1058 flags.startup = 1;
Wayne Roberts 0:4b6e76c6608f 1059 break;
Wayne Roberts 0:4b6e76c6608f 1060 }
Wayne Roberts 0:4b6e76c6608f 1061 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:4b6e76c6608f 1062 case DEVICE_STATE_JOIN:
Wayne Roberts 0:4b6e76c6608f 1063 {
Wayne Roberts 0:4b6e76c6608f 1064 join(8);
Wayne Roberts 0:4b6e76c6608f 1065 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:4b6e76c6608f 1066 break;
Wayne Roberts 0:4b6e76c6608f 1067 }
Wayne Roberts 0:4b6e76c6608f 1068 case DEVICE_STATE_JOIN_OK:
Wayne Roberts 0:4b6e76c6608f 1069 MibRequestConfirm_t mibReq;
Wayne Roberts 0:4b6e76c6608f 1070 mibReq.Type = MIB_NETWORK_JOINED;
Wayne Roberts 0:4b6e76c6608f 1071 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 1072 if (mibReq.Param.IsNetworkJoined)
Wayne Roberts 0:4b6e76c6608f 1073 APP_PRINTF("joined ");
Wayne Roberts 0:4b6e76c6608f 1074 mibReq.Type = MIB_DEV_ADDR;
Wayne Roberts 0:4b6e76c6608f 1075 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 1076 APP_PRINTF("DevAddr:%08" PRIx32 " ", mibReq.Param.DevAddr);
Wayne Roberts 0:4b6e76c6608f 1077 mibReq.Type = MIB_FNwkSIntKey;
Wayne Roberts 0:4b6e76c6608f 1078 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 1079 print_buf(mibReq.Param.key, 16, "FNwkSIntKey");
Wayne Roberts 0:4b6e76c6608f 1080 mibReq.Type = MIB_APP_SKEY;
Wayne Roberts 0:4b6e76c6608f 1081 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 1082 print_buf(mibReq.Param.key, 16, "AppSKey");
Wayne Roberts 0:4b6e76c6608f 1083
Wayne Roberts 0:4b6e76c6608f 1084 #ifdef LORAWAN_ROOT_APPKEY
Wayne Roberts 0:4b6e76c6608f 1085 mibReq.Type = MIB_SNwkSIntKey;
Wayne Roberts 0:4b6e76c6608f 1086 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 1087 SerialDisplayUpdateKey(ROW_SNwkSIntKey, mibReq.Param.key);
Wayne Roberts 0:4b6e76c6608f 1088 mibReq.Type = MIB_NwkSEncKey;
Wayne Roberts 0:4b6e76c6608f 1089 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 1090 SerialDisplayUpdateKey(ROW_NwkSEncKey, mibReq.Param.key);
Wayne Roberts 0:4b6e76c6608f 1091 #endif /* LORAWAN_ROOT_APPKEY */
Wayne Roberts 0:4b6e76c6608f 1092 DeviceState = DEVICE_STATE_TRIGGER;
Wayne Roberts 0:4b6e76c6608f 1093 break;
Wayne Roberts 0:4b6e76c6608f 1094 #endif /* LORAWAN_JOIN_EUI */
Wayne Roberts 0:4b6e76c6608f 1095 case DEVICE_STATE_SWITCH_CLASS_C:
Wayne Roberts 0:4b6e76c6608f 1096 APP_PRINTF("toclassC ");
Wayne Roberts 0:4b6e76c6608f 1097 mibReq.Type = MIB_DEVICE_CLASS;
Wayne Roberts 0:4b6e76c6608f 1098 mibReq.Param.Class = CLASS_C;
Wayne Roberts 0:4b6e76c6608f 1099 status = LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:4b6e76c6608f 1100 if (status != LORAMAC_STATUS_OK) {
Wayne Roberts 0:4b6e76c6608f 1101 char str[48];
Wayne Roberts 0:4b6e76c6608f 1102 LoRaMacStatus_to_string(status, str);
Wayne Roberts 0:4b6e76c6608f 1103 APP_PRINTF("%s\r\n", str);
Wayne Roberts 0:4b6e76c6608f 1104 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:4b6e76c6608f 1105 } else {
Wayne Roberts 0:4b6e76c6608f 1106 /* send uplink with payload, so app server gets new session */
Wayne Roberts 0:4b6e76c6608f 1107 APP_PRINTF("OK\r\n");
Wayne Roberts 0:4b6e76c6608f 1108 DeviceState = DEVICE_STATE_SEND;
Wayne Roberts 0:4b6e76c6608f 1109 }
Wayne Roberts 0:4b6e76c6608f 1110 break;
Wayne Roberts 0:4b6e76c6608f 1111 case DEVICE_STATE_SEND:
Wayne Roberts 0:4b6e76c6608f 1112 PrepareTxFrame( AppPort );
Wayne Roberts 0:4b6e76c6608f 1113 status = SendFrame(gIsTxConfirmed, gAppDataSize);
Wayne Roberts 0:4b6e76c6608f 1114 if (status == LORAMAC_STATUS_OK) {
Wayne Roberts 0:4b6e76c6608f 1115 /* McpsConfirm or McpsIndication callback will continue */
Wayne Roberts 0:4b6e76c6608f 1116 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:4b6e76c6608f 1117 } else
Wayne Roberts 0:4b6e76c6608f 1118 DeviceState = DEVICE_STATE_TRIGGER;
Wayne Roberts 0:4b6e76c6608f 1119 break;
Wayne Roberts 0:4b6e76c6608f 1120 case DEVICE_STATE_SLEEP:
Wayne Roberts 0:4b6e76c6608f 1121 {
Wayne Roberts 0:4b6e76c6608f 1122 // Wake up through events
Wayne Roberts 0:4b6e76c6608f 1123 sleep_manager_sleep_auto();
Wayne Roberts 0:4b6e76c6608f 1124 break;
Wayne Roberts 0:4b6e76c6608f 1125 }
Wayne Roberts 0:4b6e76c6608f 1126 case DEVICE_STATE_TRIGGER:
Wayne Roberts 0:4b6e76c6608f 1127 /* wait button ISR */
Wayne Roberts 0:4b6e76c6608f 1128 sleep_manager_sleep_auto();
Wayne Roberts 0:4b6e76c6608f 1129 break;
Wayne Roberts 0:4b6e76c6608f 1130 default:
Wayne Roberts 0:4b6e76c6608f 1131 DeviceState = DEVICE_STATE_INIT;
Wayne Roberts 0:4b6e76c6608f 1132 break;
Wayne Roberts 0:4b6e76c6608f 1133 } // ..switch( DeviceState )
Wayne Roberts 0:4b6e76c6608f 1134
Wayne Roberts 0:4b6e76c6608f 1135 LoRaMacUserContext();
Wayne Roberts 0:4b6e76c6608f 1136 } // ..while( 1 )
Wayne Roberts 0:4b6e76c6608f 1137 }