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