lora experiments
Dependencies: BLE_API LoRaWAN-lib SX1276Lib mbed nRF51822 HCSR04Lib
Fork of LoRa by
main.cpp@2:ce7cea075e95, 2016-06-01 (annotated)
- Committer:
- haaspors
- Date:
- Wed Jun 01 14:07:25 2016 +0000
- Revision:
- 2:ce7cea075e95
- Parent:
- 0:4c1fcbfcc7bf
- Child:
- 3:70d40f678f37
BLE custom GATT and DFU service.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
olav | 0:4c1fcbfcc7bf | 1 | #include "mbed.h" |
olav | 0:4c1fcbfcc7bf | 2 | #include "board.h" |
olav | 0:4c1fcbfcc7bf | 3 | #include "radio.h" |
olav | 0:4c1fcbfcc7bf | 4 | |
olav | 0:4c1fcbfcc7bf | 5 | #include "LoRaMac.h" |
olav | 0:4c1fcbfcc7bf | 6 | #include "Comissioning.h" |
olav | 0:4c1fcbfcc7bf | 7 | |
haaspors | 2:ce7cea075e95 | 8 | #include "ble/BLE.h" |
haaspors | 2:ce7cea075e95 | 9 | #include "ble/services/DFUService.h" |
haaspors | 2:ce7cea075e95 | 10 | |
olav | 0:4c1fcbfcc7bf | 11 | /*! |
olav | 0:4c1fcbfcc7bf | 12 | * Join requests trials duty cycle. |
olav | 0:4c1fcbfcc7bf | 13 | */ |
olav | 0:4c1fcbfcc7bf | 14 | #define OVER_THE_AIR_ACTIVATION_DUTYCYCLE 10000000 // 10 [s] value in us |
olav | 0:4c1fcbfcc7bf | 15 | |
olav | 0:4c1fcbfcc7bf | 16 | /*! |
olav | 0:4c1fcbfcc7bf | 17 | * Defines the application data transmission duty cycle. 5s, value in [us]. |
olav | 0:4c1fcbfcc7bf | 18 | */ |
olav | 0:4c1fcbfcc7bf | 19 | #define APP_TX_DUTYCYCLE 5000000 |
olav | 0:4c1fcbfcc7bf | 20 | |
olav | 0:4c1fcbfcc7bf | 21 | /*! |
olav | 0:4c1fcbfcc7bf | 22 | * Defines a random delay for application data transmission duty cycle. 1s, |
olav | 0:4c1fcbfcc7bf | 23 | * value in [us]. |
olav | 0:4c1fcbfcc7bf | 24 | */ |
olav | 0:4c1fcbfcc7bf | 25 | #define APP_TX_DUTYCYCLE_RND 1000000 |
olav | 0:4c1fcbfcc7bf | 26 | |
olav | 0:4c1fcbfcc7bf | 27 | /*! |
olav | 0:4c1fcbfcc7bf | 28 | * Default mote datarate |
olav | 0:4c1fcbfcc7bf | 29 | */ |
olav | 0:4c1fcbfcc7bf | 30 | #define LORAWAN_DEFAULT_DATARATE DR_0 |
olav | 0:4c1fcbfcc7bf | 31 | |
olav | 0:4c1fcbfcc7bf | 32 | /*! |
olav | 0:4c1fcbfcc7bf | 33 | * LoRaWAN confirmed messages |
olav | 0:4c1fcbfcc7bf | 34 | */ |
olav | 0:4c1fcbfcc7bf | 35 | #define LORAWAN_CONFIRMED_MSG_ON false |
olav | 0:4c1fcbfcc7bf | 36 | |
olav | 0:4c1fcbfcc7bf | 37 | #define LORAWAN_ADR_ON 1 |
olav | 0:4c1fcbfcc7bf | 38 | |
olav | 0:4c1fcbfcc7bf | 39 | #define LORAWAN_DUTYCYCLE_ON false |
olav | 0:4c1fcbfcc7bf | 40 | |
olav | 0:4c1fcbfcc7bf | 41 | #define LORAWAN_APP_PORT 15 |
olav | 0:4c1fcbfcc7bf | 42 | |
olav | 0:4c1fcbfcc7bf | 43 | /*! |
olav | 0:4c1fcbfcc7bf | 44 | * User application data buffer size |
olav | 0:4c1fcbfcc7bf | 45 | */ |
olav | 0:4c1fcbfcc7bf | 46 | #if ( LORAWAN_CONFIRMED_MSG_ON == 1 ) |
olav | 0:4c1fcbfcc7bf | 47 | #define LORAWAN_APP_DATA_SIZE 6 |
olav | 0:4c1fcbfcc7bf | 48 | |
olav | 0:4c1fcbfcc7bf | 49 | #else |
olav | 0:4c1fcbfcc7bf | 50 | #define LORAWAN_APP_DATA_SIZE 1 |
olav | 0:4c1fcbfcc7bf | 51 | |
olav | 0:4c1fcbfcc7bf | 52 | #endif |
olav | 0:4c1fcbfcc7bf | 53 | |
olav | 0:4c1fcbfcc7bf | 54 | #if( OVER_THE_AIR_ACTIVATION != 0 ) |
olav | 0:4c1fcbfcc7bf | 55 | |
olav | 0:4c1fcbfcc7bf | 56 | static uint8_t DevEui[] = LORAWAN_DEVICE_EUI; |
olav | 0:4c1fcbfcc7bf | 57 | static uint8_t AppEui[] = LORAWAN_APPLICATION_EUI; |
olav | 0:4c1fcbfcc7bf | 58 | static uint8_t AppKey[] = LORAWAN_APPLICATION_KEY; |
olav | 0:4c1fcbfcc7bf | 59 | |
olav | 0:4c1fcbfcc7bf | 60 | #else |
olav | 0:4c1fcbfcc7bf | 61 | |
olav | 0:4c1fcbfcc7bf | 62 | static uint8_t NwkSKey[] = LORAWAN_NWKSKEY; |
olav | 0:4c1fcbfcc7bf | 63 | static uint8_t AppSKey[] = LORAWAN_APPSKEY; |
olav | 0:4c1fcbfcc7bf | 64 | |
olav | 0:4c1fcbfcc7bf | 65 | /*! |
olav | 0:4c1fcbfcc7bf | 66 | * Device address |
olav | 0:4c1fcbfcc7bf | 67 | */ |
olav | 0:4c1fcbfcc7bf | 68 | static uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS; |
olav | 0:4c1fcbfcc7bf | 69 | |
olav | 0:4c1fcbfcc7bf | 70 | #endif |
olav | 0:4c1fcbfcc7bf | 71 | |
olav | 0:4c1fcbfcc7bf | 72 | /*! |
olav | 0:4c1fcbfcc7bf | 73 | * Application port |
olav | 0:4c1fcbfcc7bf | 74 | */ |
olav | 0:4c1fcbfcc7bf | 75 | static uint8_t AppPort = LORAWAN_APP_PORT; |
olav | 0:4c1fcbfcc7bf | 76 | |
olav | 0:4c1fcbfcc7bf | 77 | /*! |
olav | 0:4c1fcbfcc7bf | 78 | * User application data size |
olav | 0:4c1fcbfcc7bf | 79 | */ |
olav | 0:4c1fcbfcc7bf | 80 | static uint8_t AppDataSize = LORAWAN_APP_DATA_SIZE; |
olav | 0:4c1fcbfcc7bf | 81 | |
olav | 0:4c1fcbfcc7bf | 82 | /*! |
olav | 0:4c1fcbfcc7bf | 83 | * User application data buffer size |
olav | 0:4c1fcbfcc7bf | 84 | */ |
olav | 0:4c1fcbfcc7bf | 85 | #define LORAWAN_APP_DATA_MAX_SIZE 64 |
olav | 0:4c1fcbfcc7bf | 86 | |
olav | 0:4c1fcbfcc7bf | 87 | /*! |
olav | 0:4c1fcbfcc7bf | 88 | * User application data |
olav | 0:4c1fcbfcc7bf | 89 | */ |
olav | 0:4c1fcbfcc7bf | 90 | static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE]; |
olav | 0:4c1fcbfcc7bf | 91 | |
olav | 0:4c1fcbfcc7bf | 92 | /*! |
olav | 0:4c1fcbfcc7bf | 93 | * Indicates if the node is sending confirmed or unconfirmed messages |
olav | 0:4c1fcbfcc7bf | 94 | */ |
olav | 0:4c1fcbfcc7bf | 95 | static uint8_t IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON; |
olav | 0:4c1fcbfcc7bf | 96 | |
olav | 0:4c1fcbfcc7bf | 97 | /*! |
olav | 0:4c1fcbfcc7bf | 98 | * Defines the application data transmission duty cycle |
olav | 0:4c1fcbfcc7bf | 99 | */ |
olav | 0:4c1fcbfcc7bf | 100 | static uint32_t TxDutyCycleTime; |
olav | 0:4c1fcbfcc7bf | 101 | |
olav | 0:4c1fcbfcc7bf | 102 | /*! |
olav | 0:4c1fcbfcc7bf | 103 | * Timer to handle the application data transmission duty cycle |
olav | 0:4c1fcbfcc7bf | 104 | */ |
olav | 0:4c1fcbfcc7bf | 105 | static TimerEvent_t TxNextPacketTimer; |
olav | 0:4c1fcbfcc7bf | 106 | |
olav | 0:4c1fcbfcc7bf | 107 | /*! |
olav | 0:4c1fcbfcc7bf | 108 | * Indicates if a new packet can be sent |
olav | 0:4c1fcbfcc7bf | 109 | */ |
olav | 0:4c1fcbfcc7bf | 110 | static bool NextTx = true; |
olav | 0:4c1fcbfcc7bf | 111 | |
olav | 0:4c1fcbfcc7bf | 112 | /*! |
olav | 0:4c1fcbfcc7bf | 113 | * Device states |
olav | 0:4c1fcbfcc7bf | 114 | */ |
olav | 0:4c1fcbfcc7bf | 115 | static enum eDevicState |
olav | 0:4c1fcbfcc7bf | 116 | { |
olav | 0:4c1fcbfcc7bf | 117 | DEVICE_STATE_INIT, |
olav | 0:4c1fcbfcc7bf | 118 | DEVICE_STATE_JOIN, |
olav | 0:4c1fcbfcc7bf | 119 | DEVICE_STATE_SEND, |
olav | 0:4c1fcbfcc7bf | 120 | DEVICE_STATE_CYCLE, |
olav | 0:4c1fcbfcc7bf | 121 | DEVICE_STATE_SLEEP |
olav | 0:4c1fcbfcc7bf | 122 | }DeviceState; |
olav | 0:4c1fcbfcc7bf | 123 | |
olav | 0:4c1fcbfcc7bf | 124 | /*! |
olav | 0:4c1fcbfcc7bf | 125 | * Strucure containing the Downlink status |
olav | 0:4c1fcbfcc7bf | 126 | */ |
olav | 0:4c1fcbfcc7bf | 127 | struct sLoRaMacDownlinkStatus |
olav | 0:4c1fcbfcc7bf | 128 | { |
olav | 0:4c1fcbfcc7bf | 129 | int16_t Rssi; |
olav | 0:4c1fcbfcc7bf | 130 | int8_t Snr; |
olav | 0:4c1fcbfcc7bf | 131 | uint16_t DownlinkCounter; |
olav | 0:4c1fcbfcc7bf | 132 | bool RxData; |
olav | 0:4c1fcbfcc7bf | 133 | uint8_t Port; |
olav | 0:4c1fcbfcc7bf | 134 | uint8_t *Buffer; |
olav | 0:4c1fcbfcc7bf | 135 | uint8_t BufferSize; |
olav | 0:4c1fcbfcc7bf | 136 | }LoRaMacDownlinkStatus; |
olav | 0:4c1fcbfcc7bf | 137 | |
olav | 0:4c1fcbfcc7bf | 138 | /*! |
olav | 0:4c1fcbfcc7bf | 139 | * Strucure containing the Uplink status |
olav | 0:4c1fcbfcc7bf | 140 | */ |
olav | 0:4c1fcbfcc7bf | 141 | struct sLoRaMacUplinkStatus |
olav | 0:4c1fcbfcc7bf | 142 | { |
olav | 0:4c1fcbfcc7bf | 143 | uint8_t Acked; |
olav | 0:4c1fcbfcc7bf | 144 | int8_t Datarate; |
olav | 0:4c1fcbfcc7bf | 145 | uint16_t UplinkCounter; |
olav | 0:4c1fcbfcc7bf | 146 | uint8_t Port; |
olav | 0:4c1fcbfcc7bf | 147 | uint8_t *Buffer; |
olav | 0:4c1fcbfcc7bf | 148 | uint8_t BufferSize; |
olav | 0:4c1fcbfcc7bf | 149 | }LoRaMacUplinkStatus; |
olav | 0:4c1fcbfcc7bf | 150 | |
olav | 0:4c1fcbfcc7bf | 151 | MibRequestConfirm_t mibReq; |
olav | 0:4c1fcbfcc7bf | 152 | |
haaspors | 2:ce7cea075e95 | 153 | |
haaspors | 2:ce7cea075e95 | 154 | /* BLE stuff */ |
haaspors | 2:ce7cea075e95 | 155 | const uint16_t customServiceUUID = 0xA000; |
haaspors | 2:ce7cea075e95 | 156 | const static char DEVICE_NAME[] = "TD Test Device"; |
haaspors | 2:ce7cea075e95 | 157 | |
haaspors | 2:ce7cea075e95 | 158 | #if( OVER_THE_AIR_ACTIVATION != 0 ) |
haaspors | 2:ce7cea075e95 | 159 | const uint16_t DevEuiUUID = 0xA001; |
haaspors | 2:ce7cea075e95 | 160 | const uint16_t AppEuiUUID = 0xA002; |
haaspors | 2:ce7cea075e95 | 161 | const uint16_t AppKeyUUID = 0xA003; |
haaspors | 2:ce7cea075e95 | 162 | |
haaspors | 2:ce7cea075e95 | 163 | ReadWriteArrayGattCharacteristic<uint8_t, sizeof(DevEui)> DevEuiChar(DevEuiUUID, DevEui); |
haaspors | 2:ce7cea075e95 | 164 | ReadWriteArrayGattCharacteristic<uint8_t, sizeof(AppEui)> AppEuiChar(AppEuiUUID, AppEui); |
haaspors | 2:ce7cea075e95 | 165 | WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(AppKey)> AppKeyChar(AppKeyUUID, AppKey); |
haaspors | 2:ce7cea075e95 | 166 | |
haaspors | 2:ce7cea075e95 | 167 | GattCharacteristic *characteristics[] = {&DevEuiChar, &AppEuiChar, &AppKeyChar}; |
haaspors | 2:ce7cea075e95 | 168 | #else |
haaspors | 2:ce7cea075e95 | 169 | const uint16_t DevAddrUUID = 0xA004; |
haaspors | 2:ce7cea075e95 | 170 | const uint16_t NwkSKeyUUID = 0xA005; |
haaspors | 2:ce7cea075e95 | 171 | const uint16_t AppSKeyUUID = 0xA006; |
haaspors | 2:ce7cea075e95 | 172 | |
haaspors | 2:ce7cea075e95 | 173 | ReadWriteGattCharacteristic<uint32_t> DevAddrChar(DevAddrUUID, &DevAddr); |
haaspors | 2:ce7cea075e95 | 174 | WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(NwkSKey)> NwkSKeyChar(NwkSKeyUUID, NwkSKey); |
haaspors | 2:ce7cea075e95 | 175 | WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(AppSKey)> AppSKeyChar(AppSKeyUUID, AppSKey); |
haaspors | 2:ce7cea075e95 | 176 | |
haaspors | 2:ce7cea075e95 | 177 | GattCharacteristic *characteristics[] = {&DevAddrChar, &NwkSKeyChar, &AppSKeyChar}; |
haaspors | 2:ce7cea075e95 | 178 | #endif |
haaspors | 2:ce7cea075e95 | 179 | GattService customService(customServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *)); |
haaspors | 2:ce7cea075e95 | 180 | |
haaspors | 2:ce7cea075e95 | 181 | |
haaspors | 2:ce7cea075e95 | 182 | /* I/O stuff */ |
olav | 0:4c1fcbfcc7bf | 183 | InterruptIn button(BUTTON3); |
olav | 0:4c1fcbfcc7bf | 184 | DigitalOut led1(LED1); |
olav | 0:4c1fcbfcc7bf | 185 | DigitalOut led2(LED2); |
olav | 0:4c1fcbfcc7bf | 186 | |
olav | 0:4c1fcbfcc7bf | 187 | /*! |
olav | 0:4c1fcbfcc7bf | 188 | * Indicates if the MAC layer network join status has changed. |
olav | 0:4c1fcbfcc7bf | 189 | */ |
olav | 0:4c1fcbfcc7bf | 190 | static bool IsNetworkJoinedStatusUpdate = false; |
olav | 0:4c1fcbfcc7bf | 191 | |
olav | 0:4c1fcbfcc7bf | 192 | static void PrepareTxFrame( uint8_t port ) |
olav | 0:4c1fcbfcc7bf | 193 | { |
olav | 0:4c1fcbfcc7bf | 194 | switch( port ) |
olav | 0:4c1fcbfcc7bf | 195 | { |
olav | 0:4c1fcbfcc7bf | 196 | case 15: |
olav | 0:4c1fcbfcc7bf | 197 | {} |
olav | 0:4c1fcbfcc7bf | 198 | default: |
olav | 0:4c1fcbfcc7bf | 199 | { |
olav | 0:4c1fcbfcc7bf | 200 | AppData[0] = 1; |
olav | 0:4c1fcbfcc7bf | 201 | if( IsTxConfirmed == true ) |
olav | 0:4c1fcbfcc7bf | 202 | { |
olav | 0:4c1fcbfcc7bf | 203 | AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8; |
olav | 0:4c1fcbfcc7bf | 204 | AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter; |
olav | 0:4c1fcbfcc7bf | 205 | AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8; |
olav | 0:4c1fcbfcc7bf | 206 | AppData[4] = LoRaMacDownlinkStatus.Rssi; |
olav | 0:4c1fcbfcc7bf | 207 | AppData[5] = LoRaMacDownlinkStatus.Snr; |
olav | 0:4c1fcbfcc7bf | 208 | |
olav | 0:4c1fcbfcc7bf | 209 | AppData[6] = 1; |
olav | 0:4c1fcbfcc7bf | 210 | } |
olav | 0:4c1fcbfcc7bf | 211 | else |
olav | 0:4c1fcbfcc7bf | 212 | { |
olav | 0:4c1fcbfcc7bf | 213 | AppData[1] = 1; |
olav | 0:4c1fcbfcc7bf | 214 | } |
olav | 0:4c1fcbfcc7bf | 215 | } |
olav | 0:4c1fcbfcc7bf | 216 | break; |
olav | 0:4c1fcbfcc7bf | 217 | } |
olav | 0:4c1fcbfcc7bf | 218 | } |
olav | 0:4c1fcbfcc7bf | 219 | |
olav | 0:4c1fcbfcc7bf | 220 | /*! |
olav | 0:4c1fcbfcc7bf | 221 | * \brief MCPS-Confirm event function |
olav | 0:4c1fcbfcc7bf | 222 | * |
olav | 0:4c1fcbfcc7bf | 223 | * \param [IN] McpsConfirm - Pointer to the confirm structure, |
olav | 0:4c1fcbfcc7bf | 224 | * containing confirm attributes. |
olav | 0:4c1fcbfcc7bf | 225 | */ |
olav | 0:4c1fcbfcc7bf | 226 | static void McpsConfirm( McpsConfirm_t *McpsConfirm ) |
olav | 0:4c1fcbfcc7bf | 227 | { |
olav | 0:4c1fcbfcc7bf | 228 | if( McpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) |
olav | 0:4c1fcbfcc7bf | 229 | { |
olav | 0:4c1fcbfcc7bf | 230 | switch( McpsConfirm->McpsRequest ) |
olav | 0:4c1fcbfcc7bf | 231 | { |
olav | 0:4c1fcbfcc7bf | 232 | case MCPS_UNCONFIRMED: |
olav | 0:4c1fcbfcc7bf | 233 | { |
olav | 0:4c1fcbfcc7bf | 234 | // Check Datarate |
olav | 0:4c1fcbfcc7bf | 235 | // Check TxPower |
olav | 0:4c1fcbfcc7bf | 236 | break; |
olav | 0:4c1fcbfcc7bf | 237 | } |
olav | 0:4c1fcbfcc7bf | 238 | case MCPS_CONFIRMED: |
olav | 0:4c1fcbfcc7bf | 239 | { |
olav | 0:4c1fcbfcc7bf | 240 | // Check Datarate |
olav | 0:4c1fcbfcc7bf | 241 | // Check TxPower |
olav | 0:4c1fcbfcc7bf | 242 | // Check AckReceived |
olav | 0:4c1fcbfcc7bf | 243 | // Check NbRetries |
olav | 0:4c1fcbfcc7bf | 244 | break; |
olav | 0:4c1fcbfcc7bf | 245 | } |
olav | 0:4c1fcbfcc7bf | 246 | case MCPS_PROPRIETARY: |
olav | 0:4c1fcbfcc7bf | 247 | { |
olav | 0:4c1fcbfcc7bf | 248 | break; |
olav | 0:4c1fcbfcc7bf | 249 | } |
olav | 0:4c1fcbfcc7bf | 250 | default: |
olav | 0:4c1fcbfcc7bf | 251 | break; |
olav | 0:4c1fcbfcc7bf | 252 | } |
olav | 0:4c1fcbfcc7bf | 253 | } |
olav | 0:4c1fcbfcc7bf | 254 | NextTx = true; |
olav | 0:4c1fcbfcc7bf | 255 | } |
olav | 0:4c1fcbfcc7bf | 256 | |
olav | 0:4c1fcbfcc7bf | 257 | /*! |
olav | 0:4c1fcbfcc7bf | 258 | * \brief MCPS-Indication event function |
olav | 0:4c1fcbfcc7bf | 259 | * |
olav | 0:4c1fcbfcc7bf | 260 | * \param [IN] McpsIndication - Pointer to the indication structure, |
olav | 0:4c1fcbfcc7bf | 261 | * containing indication attributes. |
olav | 0:4c1fcbfcc7bf | 262 | */ |
olav | 0:4c1fcbfcc7bf | 263 | static void McpsIndication( McpsIndication_t *McpsIndication ) |
olav | 0:4c1fcbfcc7bf | 264 | { |
olav | 0:4c1fcbfcc7bf | 265 | printf("Downstream message! \r\n"); |
olav | 0:4c1fcbfcc7bf | 266 | if( McpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK ) |
olav | 0:4c1fcbfcc7bf | 267 | { |
olav | 0:4c1fcbfcc7bf | 268 | printf("Something fishy %d \r\n", McpsIndication->Status); |
olav | 0:4c1fcbfcc7bf | 269 | return; |
olav | 0:4c1fcbfcc7bf | 270 | } |
olav | 0:4c1fcbfcc7bf | 271 | |
olav | 0:4c1fcbfcc7bf | 272 | switch( McpsIndication->McpsIndication ) |
olav | 0:4c1fcbfcc7bf | 273 | { |
olav | 0:4c1fcbfcc7bf | 274 | case MCPS_UNCONFIRMED: |
olav | 0:4c1fcbfcc7bf | 275 | { |
olav | 0:4c1fcbfcc7bf | 276 | break; |
olav | 0:4c1fcbfcc7bf | 277 | } |
olav | 0:4c1fcbfcc7bf | 278 | case MCPS_CONFIRMED: |
olav | 0:4c1fcbfcc7bf | 279 | { |
olav | 0:4c1fcbfcc7bf | 280 | break; |
olav | 0:4c1fcbfcc7bf | 281 | } |
olav | 0:4c1fcbfcc7bf | 282 | case MCPS_PROPRIETARY: |
olav | 0:4c1fcbfcc7bf | 283 | { |
olav | 0:4c1fcbfcc7bf | 284 | break; |
olav | 0:4c1fcbfcc7bf | 285 | } |
olav | 0:4c1fcbfcc7bf | 286 | case MCPS_MULTICAST: |
olav | 0:4c1fcbfcc7bf | 287 | { |
olav | 0:4c1fcbfcc7bf | 288 | break; |
olav | 0:4c1fcbfcc7bf | 289 | } |
olav | 0:4c1fcbfcc7bf | 290 | default: |
olav | 0:4c1fcbfcc7bf | 291 | break; |
olav | 0:4c1fcbfcc7bf | 292 | } |
olav | 0:4c1fcbfcc7bf | 293 | |
olav | 0:4c1fcbfcc7bf | 294 | // Check Multicast |
olav | 0:4c1fcbfcc7bf | 295 | // Check Port |
olav | 0:4c1fcbfcc7bf | 296 | // Check Datarate |
olav | 0:4c1fcbfcc7bf | 297 | // Check FramePending |
olav | 0:4c1fcbfcc7bf | 298 | // Check Buffer |
olav | 0:4c1fcbfcc7bf | 299 | // Check BufferSize |
olav | 0:4c1fcbfcc7bf | 300 | // Check Rssi |
olav | 0:4c1fcbfcc7bf | 301 | // Check Snr |
olav | 0:4c1fcbfcc7bf | 302 | // Check RxSlot |
olav | 0:4c1fcbfcc7bf | 303 | |
olav | 0:4c1fcbfcc7bf | 304 | LoRaMacDownlinkStatus.Rssi = McpsIndication->Rssi; |
olav | 0:4c1fcbfcc7bf | 305 | if( McpsIndication->Snr & 0x80 ) // The SNR sign bit is 1 |
olav | 0:4c1fcbfcc7bf | 306 | { |
olav | 0:4c1fcbfcc7bf | 307 | // Invert and divide by 4 |
olav | 0:4c1fcbfcc7bf | 308 | LoRaMacDownlinkStatus.Snr = ( ( ~McpsIndication->Snr + 1 ) & 0xFF ) >> 2; |
olav | 0:4c1fcbfcc7bf | 309 | LoRaMacDownlinkStatus.Snr = -LoRaMacDownlinkStatus.Snr; |
olav | 0:4c1fcbfcc7bf | 310 | } |
olav | 0:4c1fcbfcc7bf | 311 | else |
olav | 0:4c1fcbfcc7bf | 312 | { |
olav | 0:4c1fcbfcc7bf | 313 | // Divide by 4 |
olav | 0:4c1fcbfcc7bf | 314 | LoRaMacDownlinkStatus.Snr = ( McpsIndication->Snr & 0xFF ) >> 2; |
olav | 0:4c1fcbfcc7bf | 315 | } |
olav | 0:4c1fcbfcc7bf | 316 | LoRaMacDownlinkStatus.DownlinkCounter++; |
olav | 0:4c1fcbfcc7bf | 317 | LoRaMacDownlinkStatus.RxData = McpsIndication->RxData; |
olav | 0:4c1fcbfcc7bf | 318 | LoRaMacDownlinkStatus.Port = McpsIndication->Port; |
olav | 0:4c1fcbfcc7bf | 319 | LoRaMacDownlinkStatus.Buffer = McpsIndication->Buffer; |
olav | 0:4c1fcbfcc7bf | 320 | LoRaMacDownlinkStatus.BufferSize = McpsIndication->BufferSize; |
olav | 0:4c1fcbfcc7bf | 321 | |
olav | 0:4c1fcbfcc7bf | 322 | if( McpsIndication->RxData == true ) |
olav | 0:4c1fcbfcc7bf | 323 | { |
olav | 0:4c1fcbfcc7bf | 324 | printf("Got a nice thingie! \r\n"); |
olav | 0:4c1fcbfcc7bf | 325 | switch( McpsIndication->Port ) |
olav | 0:4c1fcbfcc7bf | 326 | { |
olav | 0:4c1fcbfcc7bf | 327 | case 1: |
olav | 0:4c1fcbfcc7bf | 328 | printf("Logic for port1 %u\r\n", McpsIndication->Buffer[0]); |
olav | 0:4c1fcbfcc7bf | 329 | if( McpsIndication->BufferSize == 1 ) |
olav | 0:4c1fcbfcc7bf | 330 | { |
olav | 0:4c1fcbfcc7bf | 331 | led1 = !McpsIndication->Buffer[0]; |
olav | 0:4c1fcbfcc7bf | 332 | } |
olav | 0:4c1fcbfcc7bf | 333 | break; |
olav | 0:4c1fcbfcc7bf | 334 | case 2: |
olav | 0:4c1fcbfcc7bf | 335 | printf("Logic for port2 %u\r\n", McpsIndication->Buffer[0]); |
olav | 0:4c1fcbfcc7bf | 336 | if( McpsIndication->BufferSize == 1 ) |
olav | 0:4c1fcbfcc7bf | 337 | { |
olav | 0:4c1fcbfcc7bf | 338 | led2 = !McpsIndication->Buffer[0]; |
olav | 0:4c1fcbfcc7bf | 339 | } |
olav | 0:4c1fcbfcc7bf | 340 | break; |
olav | 0:4c1fcbfcc7bf | 341 | default: |
olav | 0:4c1fcbfcc7bf | 342 | break; |
olav | 0:4c1fcbfcc7bf | 343 | } |
olav | 0:4c1fcbfcc7bf | 344 | } |
olav | 0:4c1fcbfcc7bf | 345 | } |
olav | 0:4c1fcbfcc7bf | 346 | |
olav | 0:4c1fcbfcc7bf | 347 | /*! |
olav | 0:4c1fcbfcc7bf | 348 | * \brief MLME-Confirm event function |
olav | 0:4c1fcbfcc7bf | 349 | * |
olav | 0:4c1fcbfcc7bf | 350 | * \param [IN] MlmeConfirm - Pointer to the confirm structure, |
olav | 0:4c1fcbfcc7bf | 351 | * containing confirm attributes. |
olav | 0:4c1fcbfcc7bf | 352 | */ |
olav | 0:4c1fcbfcc7bf | 353 | static void MlmeConfirm( MlmeConfirm_t *MlmeConfirm ) |
olav | 0:4c1fcbfcc7bf | 354 | { |
olav | 0:4c1fcbfcc7bf | 355 | if( MlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) |
olav | 0:4c1fcbfcc7bf | 356 | { |
olav | 0:4c1fcbfcc7bf | 357 | switch( MlmeConfirm->MlmeRequest ) |
olav | 0:4c1fcbfcc7bf | 358 | { |
olav | 0:4c1fcbfcc7bf | 359 | case MLME_JOIN: |
olav | 0:4c1fcbfcc7bf | 360 | { |
olav | 0:4c1fcbfcc7bf | 361 | printf("We joined! \r\n"); |
olav | 0:4c1fcbfcc7bf | 362 | // Status is OK, node has joined the network |
olav | 0:4c1fcbfcc7bf | 363 | IsNetworkJoinedStatusUpdate = true; |
olav | 0:4c1fcbfcc7bf | 364 | break; |
olav | 0:4c1fcbfcc7bf | 365 | } |
olav | 0:4c1fcbfcc7bf | 366 | default: |
olav | 0:4c1fcbfcc7bf | 367 | break; |
olav | 0:4c1fcbfcc7bf | 368 | } |
olav | 0:4c1fcbfcc7bf | 369 | } |
olav | 0:4c1fcbfcc7bf | 370 | NextTx = true; |
olav | 0:4c1fcbfcc7bf | 371 | } |
olav | 0:4c1fcbfcc7bf | 372 | |
olav | 0:4c1fcbfcc7bf | 373 | /*! |
olav | 0:4c1fcbfcc7bf | 374 | * \brief Prepares the payload of the frame |
olav | 0:4c1fcbfcc7bf | 375 | * |
olav | 0:4c1fcbfcc7bf | 376 | * \retval [0: frame could be send, 1: error] |
olav | 0:4c1fcbfcc7bf | 377 | */ |
olav | 0:4c1fcbfcc7bf | 378 | static bool SendFrame( void ) |
olav | 0:4c1fcbfcc7bf | 379 | { |
olav | 0:4c1fcbfcc7bf | 380 | printf("Sending!\r\n"); |
olav | 0:4c1fcbfcc7bf | 381 | McpsReq_t mcpsReq; |
olav | 0:4c1fcbfcc7bf | 382 | LoRaMacTxInfo_t txInfo; |
olav | 0:4c1fcbfcc7bf | 383 | |
olav | 0:4c1fcbfcc7bf | 384 | if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK ) |
olav | 0:4c1fcbfcc7bf | 385 | { |
olav | 0:4c1fcbfcc7bf | 386 | printf("Flush mac\r\n"); |
olav | 0:4c1fcbfcc7bf | 387 | // Send empty frame in order to flush MAC commands |
olav | 0:4c1fcbfcc7bf | 388 | mcpsReq.Type = MCPS_UNCONFIRMED; |
olav | 0:4c1fcbfcc7bf | 389 | mcpsReq.Req.Unconfirmed.fBuffer = NULL; |
olav | 0:4c1fcbfcc7bf | 390 | mcpsReq.Req.Unconfirmed.fBufferSize = 0; |
olav | 0:4c1fcbfcc7bf | 391 | mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE; |
olav | 0:4c1fcbfcc7bf | 392 | } |
olav | 0:4c1fcbfcc7bf | 393 | else |
olav | 0:4c1fcbfcc7bf | 394 | { |
olav | 0:4c1fcbfcc7bf | 395 | if( IsTxConfirmed == false ) |
olav | 0:4c1fcbfcc7bf | 396 | { |
olav | 0:4c1fcbfcc7bf | 397 | mcpsReq.Type = MCPS_UNCONFIRMED; |
olav | 0:4c1fcbfcc7bf | 398 | mcpsReq.Req.Unconfirmed.fPort = AppPort; |
olav | 0:4c1fcbfcc7bf | 399 | mcpsReq.Req.Unconfirmed.fBuffer = AppData; |
olav | 0:4c1fcbfcc7bf | 400 | mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize; |
olav | 0:4c1fcbfcc7bf | 401 | mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE; |
olav | 0:4c1fcbfcc7bf | 402 | } |
olav | 0:4c1fcbfcc7bf | 403 | else |
olav | 0:4c1fcbfcc7bf | 404 | { |
olav | 0:4c1fcbfcc7bf | 405 | mcpsReq.Type = MCPS_CONFIRMED; |
olav | 0:4c1fcbfcc7bf | 406 | mcpsReq.Req.Confirmed.fPort = AppPort; |
olav | 0:4c1fcbfcc7bf | 407 | mcpsReq.Req.Confirmed.fBuffer = AppData; |
olav | 0:4c1fcbfcc7bf | 408 | mcpsReq.Req.Confirmed.fBufferSize = AppDataSize; |
olav | 0:4c1fcbfcc7bf | 409 | mcpsReq.Req.Confirmed.NbTrials = 8; |
olav | 0:4c1fcbfcc7bf | 410 | mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE; |
olav | 0:4c1fcbfcc7bf | 411 | } |
olav | 0:4c1fcbfcc7bf | 412 | } |
olav | 0:4c1fcbfcc7bf | 413 | if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK ) |
olav | 0:4c1fcbfcc7bf | 414 | { |
olav | 0:4c1fcbfcc7bf | 415 | return false; |
olav | 0:4c1fcbfcc7bf | 416 | } |
olav | 0:4c1fcbfcc7bf | 417 | |
olav | 0:4c1fcbfcc7bf | 418 | return true; |
olav | 0:4c1fcbfcc7bf | 419 | } |
olav | 0:4c1fcbfcc7bf | 420 | |
olav | 0:4c1fcbfcc7bf | 421 | /*! |
olav | 0:4c1fcbfcc7bf | 422 | * \brief Function executed on TxNextPacket Timeout event |
olav | 0:4c1fcbfcc7bf | 423 | */ |
olav | 0:4c1fcbfcc7bf | 424 | static void OnTxNextPacketTimerEvent( void ) |
olav | 0:4c1fcbfcc7bf | 425 | { |
olav | 0:4c1fcbfcc7bf | 426 | LoRaMacStatus_t status; |
olav | 0:4c1fcbfcc7bf | 427 | status = LoRaMacMibGetRequestConfirm( &mibReq ); |
olav | 0:4c1fcbfcc7bf | 428 | |
olav | 0:4c1fcbfcc7bf | 429 | TimerStop( &TxNextPacketTimer ); |
olav | 0:4c1fcbfcc7bf | 430 | |
olav | 0:4c1fcbfcc7bf | 431 | if( status == LORAMAC_STATUS_OK ) |
olav | 0:4c1fcbfcc7bf | 432 | { |
olav | 0:4c1fcbfcc7bf | 433 | if( mibReq.Param.IsNetworkJoined == true ) |
olav | 0:4c1fcbfcc7bf | 434 | { |
olav | 0:4c1fcbfcc7bf | 435 | //DeviceState = DEVICE_STATE_SEND; |
olav | 0:4c1fcbfcc7bf | 436 | DeviceState = DEVICE_STATE_SLEEP; |
olav | 0:4c1fcbfcc7bf | 437 | NextTx = true; |
olav | 0:4c1fcbfcc7bf | 438 | } |
olav | 0:4c1fcbfcc7bf | 439 | else |
olav | 0:4c1fcbfcc7bf | 440 | { |
olav | 0:4c1fcbfcc7bf | 441 | DeviceState = DEVICE_STATE_JOIN; |
olav | 0:4c1fcbfcc7bf | 442 | } |
olav | 0:4c1fcbfcc7bf | 443 | } |
olav | 0:4c1fcbfcc7bf | 444 | } |
olav | 0:4c1fcbfcc7bf | 445 | |
haaspors | 2:ce7cea075e95 | 446 | /* |
haaspors | 2:ce7cea075e95 | 447 | * Restart advertising when phone app disconnects |
haaspors | 2:ce7cea075e95 | 448 | */ |
haaspors | 2:ce7cea075e95 | 449 | void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) |
haaspors | 2:ce7cea075e95 | 450 | { |
haaspors | 2:ce7cea075e95 | 451 | BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising(); |
haaspors | 2:ce7cea075e95 | 452 | } |
haaspors | 2:ce7cea075e95 | 453 | |
haaspors | 2:ce7cea075e95 | 454 | /* |
haaspors | 2:ce7cea075e95 | 455 | * Handle writes to writeCharacteristic |
haaspors | 2:ce7cea075e95 | 456 | */ |
haaspors | 2:ce7cea075e95 | 457 | void writeCharCallback(const GattWriteCallbackParams *params) |
haaspors | 2:ce7cea075e95 | 458 | { |
haaspors | 2:ce7cea075e95 | 459 | /* Restart the lora stack */ |
haaspors | 2:ce7cea075e95 | 460 | #if( OVER_THE_AIR_ACTIVATION != 0 ) |
haaspors | 2:ce7cea075e95 | 461 | if (params->handle == AppKeyChar.getValueHandle()) { |
haaspors | 2:ce7cea075e95 | 462 | printf("Value written, device state set to JOIN\r\n"); |
haaspors | 2:ce7cea075e95 | 463 | memcpy(AppKey, params->data, params->len); |
haaspors | 2:ce7cea075e95 | 464 | DeviceState = DEVICE_STATE_JOIN; |
haaspors | 2:ce7cea075e95 | 465 | } else if (params->handle == AppEuiChar.getValueHandle()) { |
haaspors | 2:ce7cea075e95 | 466 | memcpy(AppEui, params->data, params->len); |
haaspors | 2:ce7cea075e95 | 467 | } else if (params->handle == DevEuiChar.getValueHandle()) { |
haaspors | 2:ce7cea075e95 | 468 | memcpy(DevEui, params->data, params->len); |
haaspors | 2:ce7cea075e95 | 469 | } |
haaspors | 2:ce7cea075e95 | 470 | #else |
haaspors | 2:ce7cea075e95 | 471 | printf("Value written, device state set to JOIN\r\n"); |
haaspors | 2:ce7cea075e95 | 472 | DeviceState = DEVICE_STATE_JOIN; |
haaspors | 2:ce7cea075e95 | 473 | #endif |
haaspors | 2:ce7cea075e95 | 474 | BLE::Instance(BLE::DEFAULT_INSTANCE).updateCharacteristicValue(params->handle, params->data, params->len); |
haaspors | 2:ce7cea075e95 | 475 | } |
haaspors | 2:ce7cea075e95 | 476 | |
haaspors | 2:ce7cea075e95 | 477 | /* |
haaspors | 2:ce7cea075e95 | 478 | * Initialization callback |
haaspors | 2:ce7cea075e95 | 479 | */ |
haaspors | 2:ce7cea075e95 | 480 | void bleInitComplete(BLE::InitializationCompleteCallbackContext * params) |
haaspors | 2:ce7cea075e95 | 481 | { |
haaspors | 2:ce7cea075e95 | 482 | const uint16_t uuid16_list[] = { customServiceUUID, DFUServiceShortUUID }; |
haaspors | 2:ce7cea075e95 | 483 | BLE &ble = params->ble; |
haaspors | 2:ce7cea075e95 | 484 | ble_error_t error = params->error; |
haaspors | 2:ce7cea075e95 | 485 | |
haaspors | 2:ce7cea075e95 | 486 | if (error != BLE_ERROR_NONE) { |
haaspors | 2:ce7cea075e95 | 487 | return; |
haaspors | 2:ce7cea075e95 | 488 | } |
haaspors | 2:ce7cea075e95 | 489 | |
haaspors | 2:ce7cea075e95 | 490 | ble.gap().onDisconnection(disconnectionCallback); |
haaspors | 2:ce7cea075e95 | 491 | ble.gattServer().onDataWritten(writeCharCallback); |
haaspors | 2:ce7cea075e95 | 492 | |
haaspors | 2:ce7cea075e95 | 493 | /* Setup advertising, BLE only */ |
haaspors | 2:ce7cea075e95 | 494 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); |
haaspors | 2:ce7cea075e95 | 495 | ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
haaspors | 2:ce7cea075e95 | 496 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); |
haaspors | 2:ce7cea075e95 | 497 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); |
haaspors | 2:ce7cea075e95 | 498 | ble.gap().setAdvertisingInterval(100); |
haaspors | 2:ce7cea075e95 | 499 | |
haaspors | 2:ce7cea075e95 | 500 | ble.addService(customService); |
haaspors | 2:ce7cea075e95 | 501 | static DFUService dfu(ble); |
haaspors | 2:ce7cea075e95 | 502 | |
haaspors | 2:ce7cea075e95 | 503 | /* Start advertising */ |
haaspors | 2:ce7cea075e95 | 504 | ble.gap().startAdvertising(); |
haaspors | 2:ce7cea075e95 | 505 | } |
haaspors | 2:ce7cea075e95 | 506 | |
olav | 0:4c1fcbfcc7bf | 507 | void buttonPressedCallback(void) |
olav | 0:4c1fcbfcc7bf | 508 | { |
olav | 0:4c1fcbfcc7bf | 509 | printf("Button pressed \r\n"); |
olav | 0:4c1fcbfcc7bf | 510 | PrepareTxFrame( AppPort ); |
olav | 0:4c1fcbfcc7bf | 511 | NextTx = SendFrame( ); |
olav | 0:4c1fcbfcc7bf | 512 | printf("res: %d \r\n",NextTx); |
olav | 0:4c1fcbfcc7bf | 513 | } |
olav | 0:4c1fcbfcc7bf | 514 | |
olav | 0:4c1fcbfcc7bf | 515 | int main( void ) |
olav | 0:4c1fcbfcc7bf | 516 | { |
olav | 0:4c1fcbfcc7bf | 517 | printf("Hello world! \r\n"); |
haaspors | 2:ce7cea075e95 | 518 | |
olav | 0:4c1fcbfcc7bf | 519 | LoRaMacPrimitives_t LoRaMacPrimitives; |
olav | 0:4c1fcbfcc7bf | 520 | LoRaMacCallback_t LoRaMacCallbacks; |
haaspors | 2:ce7cea075e95 | 521 | BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); |
olav | 0:4c1fcbfcc7bf | 522 | |
olav | 0:4c1fcbfcc7bf | 523 | BoardInit( ); |
haaspors | 2:ce7cea075e95 | 524 | |
haaspors | 2:ce7cea075e95 | 525 | ble.init(bleInitComplete); |
haaspors | 2:ce7cea075e95 | 526 | |
haaspors | 2:ce7cea075e95 | 527 | button.fall(buttonPressedCallback); |
olav | 0:4c1fcbfcc7bf | 528 | |
haaspors | 2:ce7cea075e95 | 529 | /* SpinWait for initialization to complete. This is necessary because the |
haaspors | 2:ce7cea075e95 | 530 | * BLE object is used in the main loop below. */ |
haaspors | 2:ce7cea075e95 | 531 | while (ble.hasInitialized() == false) { /* spin loop */ } |
haaspors | 2:ce7cea075e95 | 532 | |
olav | 0:4c1fcbfcc7bf | 533 | DeviceState = DEVICE_STATE_INIT; |
olav | 0:4c1fcbfcc7bf | 534 | while( 1 ) |
olav | 0:4c1fcbfcc7bf | 535 | { |
olav | 0:4c1fcbfcc7bf | 536 | if (DeviceState != DEVICE_STATE_SLEEP) |
olav | 0:4c1fcbfcc7bf | 537 | printf("State: %d \r\n", DeviceState); |
olav | 0:4c1fcbfcc7bf | 538 | |
olav | 0:4c1fcbfcc7bf | 539 | if( IsNetworkJoinedStatusUpdate == true ) |
olav | 0:4c1fcbfcc7bf | 540 | { |
olav | 0:4c1fcbfcc7bf | 541 | printf("Joined okay \r\n"); |
olav | 0:4c1fcbfcc7bf | 542 | IsNetworkJoinedStatusUpdate = false; |
olav | 0:4c1fcbfcc7bf | 543 | mibReq.Type = MIB_NETWORK_JOINED; |
olav | 0:4c1fcbfcc7bf | 544 | LoRaMacMibGetRequestConfirm( &mibReq ); |
olav | 0:4c1fcbfcc7bf | 545 | } |
olav | 0:4c1fcbfcc7bf | 546 | switch( DeviceState ) |
olav | 0:4c1fcbfcc7bf | 547 | { |
olav | 0:4c1fcbfcc7bf | 548 | case DEVICE_STATE_INIT: |
olav | 0:4c1fcbfcc7bf | 549 | { |
olav | 0:4c1fcbfcc7bf | 550 | LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm; |
olav | 0:4c1fcbfcc7bf | 551 | LoRaMacPrimitives.MacMcpsIndication = McpsIndication; |
olav | 0:4c1fcbfcc7bf | 552 | LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm; |
olav | 0:4c1fcbfcc7bf | 553 | LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel; |
olav | 0:4c1fcbfcc7bf | 554 | LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks ); |
olav | 0:4c1fcbfcc7bf | 555 | |
olav | 0:4c1fcbfcc7bf | 556 | TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent ); |
olav | 0:4c1fcbfcc7bf | 557 | mibReq.Type = MIB_ADR; |
olav | 0:4c1fcbfcc7bf | 558 | mibReq.Param.AdrEnable = LORAWAN_ADR_ON; |
olav | 0:4c1fcbfcc7bf | 559 | LoRaMacMibSetRequestConfirm( &mibReq ); |
olav | 0:4c1fcbfcc7bf | 560 | |
olav | 0:4c1fcbfcc7bf | 561 | mibReq.Type = MIB_PUBLIC_NETWORK; |
olav | 0:4c1fcbfcc7bf | 562 | mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK; |
olav | 0:4c1fcbfcc7bf | 563 | LoRaMacMibSetRequestConfirm( &mibReq ); |
olav | 0:4c1fcbfcc7bf | 564 | |
olav | 0:4c1fcbfcc7bf | 565 | LoRaMacTestSetDutyCycleOn( false ); |
olav | 0:4c1fcbfcc7bf | 566 | |
olav | 0:4c1fcbfcc7bf | 567 | DeviceState = DEVICE_STATE_JOIN; |
olav | 0:4c1fcbfcc7bf | 568 | break; |
olav | 0:4c1fcbfcc7bf | 569 | } |
olav | 0:4c1fcbfcc7bf | 570 | case DEVICE_STATE_JOIN: |
olav | 0:4c1fcbfcc7bf | 571 | { |
olav | 0:4c1fcbfcc7bf | 572 | #if( OVER_THE_AIR_ACTIVATION != 0 ) |
olav | 0:4c1fcbfcc7bf | 573 | MlmeReq_t mlmeReq; |
olav | 0:4c1fcbfcc7bf | 574 | |
olav | 0:4c1fcbfcc7bf | 575 | mlmeReq.Type = MLME_JOIN; |
olav | 0:4c1fcbfcc7bf | 576 | |
olav | 0:4c1fcbfcc7bf | 577 | mlmeReq.Req.Join.DevEui = DevEui; |
olav | 0:4c1fcbfcc7bf | 578 | mlmeReq.Req.Join.AppEui = AppEui; |
olav | 0:4c1fcbfcc7bf | 579 | mlmeReq.Req.Join.AppKey = AppKey; |
olav | 0:4c1fcbfcc7bf | 580 | |
olav | 0:4c1fcbfcc7bf | 581 | if( NextTx == true ) |
olav | 0:4c1fcbfcc7bf | 582 | { |
olav | 0:4c1fcbfcc7bf | 583 | LoRaMacMlmeRequest( &mlmeReq ); |
olav | 0:4c1fcbfcc7bf | 584 | } |
olav | 0:4c1fcbfcc7bf | 585 | |
olav | 0:4c1fcbfcc7bf | 586 | // Schedule next packet transmission |
olav | 0:4c1fcbfcc7bf | 587 | TxDutyCycleTime = OVER_THE_AIR_ACTIVATION_DUTYCYCLE; |
olav | 0:4c1fcbfcc7bf | 588 | DeviceState = DEVICE_STATE_CYCLE; |
olav | 0:4c1fcbfcc7bf | 589 | |
olav | 0:4c1fcbfcc7bf | 590 | #else |
olav | 0:4c1fcbfcc7bf | 591 | mibReq.Type = MIB_NET_ID; |
olav | 0:4c1fcbfcc7bf | 592 | mibReq.Param.NetID = LORAWAN_NETWORK_ID; |
olav | 0:4c1fcbfcc7bf | 593 | LoRaMacMibSetRequestConfirm( &mibReq ); |
olav | 0:4c1fcbfcc7bf | 594 | |
olav | 0:4c1fcbfcc7bf | 595 | mibReq.Type = MIB_DEV_ADDR; |
olav | 0:4c1fcbfcc7bf | 596 | mibReq.Param.DevAddr = DevAddr; |
olav | 0:4c1fcbfcc7bf | 597 | LoRaMacMibSetRequestConfirm( &mibReq ); |
olav | 0:4c1fcbfcc7bf | 598 | |
olav | 0:4c1fcbfcc7bf | 599 | mibReq.Type = MIB_NWK_SKEY; |
olav | 0:4c1fcbfcc7bf | 600 | mibReq.Param.NwkSKey = NwkSKey; |
olav | 0:4c1fcbfcc7bf | 601 | LoRaMacMibSetRequestConfirm( &mibReq ); |
olav | 0:4c1fcbfcc7bf | 602 | |
olav | 0:4c1fcbfcc7bf | 603 | mibReq.Type = MIB_APP_SKEY; |
olav | 0:4c1fcbfcc7bf | 604 | mibReq.Param.AppSKey = AppSKey; |
olav | 0:4c1fcbfcc7bf | 605 | LoRaMacMibSetRequestConfirm( &mibReq ); |
olav | 0:4c1fcbfcc7bf | 606 | |
olav | 0:4c1fcbfcc7bf | 607 | mibReq.Type = MIB_NETWORK_JOINED; |
olav | 0:4c1fcbfcc7bf | 608 | mibReq.Param.IsNetworkJoined = true; |
olav | 0:4c1fcbfcc7bf | 609 | LoRaMacMibSetRequestConfirm( &mibReq ); |
olav | 0:4c1fcbfcc7bf | 610 | |
olav | 0:4c1fcbfcc7bf | 611 | DeviceState = DEVICE_STATE_SEND; |
olav | 0:4c1fcbfcc7bf | 612 | #endif |
olav | 0:4c1fcbfcc7bf | 613 | IsNetworkJoinedStatusUpdate = true; |
olav | 0:4c1fcbfcc7bf | 614 | break; |
olav | 0:4c1fcbfcc7bf | 615 | } |
olav | 0:4c1fcbfcc7bf | 616 | case DEVICE_STATE_SEND: |
olav | 0:4c1fcbfcc7bf | 617 | { |
olav | 0:4c1fcbfcc7bf | 618 | if( NextTx == true ) |
olav | 0:4c1fcbfcc7bf | 619 | { |
olav | 0:4c1fcbfcc7bf | 620 | printf("Send a frame! \r\n"); |
olav | 0:4c1fcbfcc7bf | 621 | PrepareTxFrame( AppPort ); |
olav | 0:4c1fcbfcc7bf | 622 | |
olav | 0:4c1fcbfcc7bf | 623 | NextTx = SendFrame( ); |
olav | 0:4c1fcbfcc7bf | 624 | |
olav | 0:4c1fcbfcc7bf | 625 | } |
olav | 0:4c1fcbfcc7bf | 626 | |
olav | 0:4c1fcbfcc7bf | 627 | // Schedule next packet transmission |
olav | 0:4c1fcbfcc7bf | 628 | TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); |
olav | 0:4c1fcbfcc7bf | 629 | |
olav | 0:4c1fcbfcc7bf | 630 | DeviceState = DEVICE_STATE_CYCLE; |
olav | 0:4c1fcbfcc7bf | 631 | break; |
olav | 0:4c1fcbfcc7bf | 632 | } |
olav | 0:4c1fcbfcc7bf | 633 | case DEVICE_STATE_CYCLE: |
olav | 0:4c1fcbfcc7bf | 634 | { |
olav | 0:4c1fcbfcc7bf | 635 | // Schedule next packet transmission |
olav | 0:4c1fcbfcc7bf | 636 | printf("Do some cycling .. \r\n"); |
olav | 0:4c1fcbfcc7bf | 637 | TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime ); |
olav | 0:4c1fcbfcc7bf | 638 | TimerStart( &TxNextPacketTimer ); |
olav | 0:4c1fcbfcc7bf | 639 | |
olav | 0:4c1fcbfcc7bf | 640 | DeviceState = DEVICE_STATE_SLEEP; |
olav | 0:4c1fcbfcc7bf | 641 | break; |
olav | 0:4c1fcbfcc7bf | 642 | } |
olav | 0:4c1fcbfcc7bf | 643 | case DEVICE_STATE_SLEEP: |
olav | 0:4c1fcbfcc7bf | 644 | { |
olav | 0:4c1fcbfcc7bf | 645 | // Wake up through events |
haaspors | 2:ce7cea075e95 | 646 | ble.waitForEvent(); |
olav | 0:4c1fcbfcc7bf | 647 | break; |
olav | 0:4c1fcbfcc7bf | 648 | } |
olav | 0:4c1fcbfcc7bf | 649 | default: |
olav | 0:4c1fcbfcc7bf | 650 | { |
olav | 0:4c1fcbfcc7bf | 651 | DeviceState = DEVICE_STATE_INIT; |
olav | 0:4c1fcbfcc7bf | 652 | break; |
olav | 0:4c1fcbfcc7bf | 653 | } |
olav | 0:4c1fcbfcc7bf | 654 | } |
olav | 0:4c1fcbfcc7bf | 655 | } |
olav | 0:4c1fcbfcc7bf | 656 | } |