Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: LoRaWAN-SanJose_Bootcamp LoRaWAN-grove-cayenne LoRaWAN-classC-demo LoRaWAN-grove-cayenne ... more
mac/LoRaMac1v1.cpp@7:4b6f960dcca2, 2018-05-04 (annotated)
- Committer:
- Wayne Roberts
- Date:
- Fri May 04 11:00:06 2018 -0700
- Revision:
- 7:4b6f960dcca2
- Parent:
- 5:4e9d41359897
- Child:
- 8:5a5ea7cc946f
Add class-C support, and LBT
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| Wayne Roberts |
0:6b3ac9c5a042 | 1 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2 | #include "LoRaMacPrivate.h" |
| Wayne Roberts |
0:6b3ac9c5a042 | 3 | #include "LoRaMacCrypto.h" |
| Wayne Roberts |
0:6b3ac9c5a042 | 4 | |
| Wayne Roberts |
3:eb174e10afbb | 5 | //#define ADR_ACK_LIMIT 64 |
| Wayne Roberts |
3:eb174e10afbb | 6 | //#define ADR_ACK_DELAY 32 |
| Wayne Roberts |
0:6b3ac9c5a042 | 7 | #define LORA_MAC_FRMPAYLOAD_OVERHEAD 13 // MHDR(1) + FHDR(7) + Port(1) + MIC(4) |
| Wayne Roberts |
0:6b3ac9c5a042 | 8 | #define RECEIVE_DELAY1_us 1000000 |
| Wayne Roberts |
0:6b3ac9c5a042 | 9 | #define LORAMAC_MFR_LEN 4 |
| Wayne Roberts |
0:6b3ac9c5a042 | 10 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 11 | /*! |
| Wayne Roberts |
0:6b3ac9c5a042 | 12 | * LoRaMAC Battery level indicator |
| Wayne Roberts |
0:6b3ac9c5a042 | 13 | */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 14 | typedef enum eLoRaMacBatteryLevel |
| Wayne Roberts |
0:6b3ac9c5a042 | 15 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 16 | /*! |
| Wayne Roberts |
0:6b3ac9c5a042 | 17 | * External power source |
| Wayne Roberts |
0:6b3ac9c5a042 | 18 | */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 19 | BAT_LEVEL_EXT_SRC = 0x00, |
| Wayne Roberts |
0:6b3ac9c5a042 | 20 | /*! |
| Wayne Roberts |
0:6b3ac9c5a042 | 21 | * Battery level empty |
| Wayne Roberts |
0:6b3ac9c5a042 | 22 | */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 23 | BAT_LEVEL_EMPTY = 0x01, |
| Wayne Roberts |
0:6b3ac9c5a042 | 24 | /*! |
| Wayne Roberts |
0:6b3ac9c5a042 | 25 | * Battery level full |
| Wayne Roberts |
0:6b3ac9c5a042 | 26 | */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 27 | BAT_LEVEL_FULL = 0xFE, |
| Wayne Roberts |
0:6b3ac9c5a042 | 28 | /*! |
| Wayne Roberts |
0:6b3ac9c5a042 | 29 | * Battery level - no measurement available |
| Wayne Roberts |
0:6b3ac9c5a042 | 30 | */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 31 | BAT_LEVEL_NO_MEASURE = 0xFF, |
| Wayne Roberts |
0:6b3ac9c5a042 | 32 | }LoRaMacBatteryLevel_t; |
| Wayne Roberts |
0:6b3ac9c5a042 | 33 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 34 | /*! |
| Wayne Roberts |
0:6b3ac9c5a042 | 35 | * LoRaMac internal state |
| Wayne Roberts |
0:6b3ac9c5a042 | 36 | */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 37 | flags_t flags; |
| Wayne Roberts |
0:6b3ac9c5a042 | 38 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 39 | void (*function_pending)(void); // one-shot |
| Wayne Roberts |
0:6b3ac9c5a042 | 40 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 41 | /*! |
| Wayne Roberts |
0:6b3ac9c5a042 | 42 | * Current channel index |
| Wayne Roberts |
0:6b3ac9c5a042 | 43 | */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 44 | uint8_t Channel; |
| Wayne Roberts |
0:6b3ac9c5a042 | 45 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 46 | static MlmeIndication_t MlmeIndication; |
| Wayne Roberts |
0:6b3ac9c5a042 | 47 | static MlmeConfirm_t MlmeConfirm; |
| Wayne Roberts |
0:6b3ac9c5a042 | 48 | static McpsIndication_t McpsIndication; |
| Wayne Roberts |
0:6b3ac9c5a042 | 49 | static McpsConfirm_t McpsConfirm; |
| Wayne Roberts |
0:6b3ac9c5a042 | 50 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 51 | uint32_t LoRaMacDevAddr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 52 | uint32_t LoRaMacNetID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 53 | static skey_t keys; |
| Wayne Roberts |
0:6b3ac9c5a042 | 54 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 55 | uint8_t MacCommandsBufferToRepeatIndex; |
| Wayne Roberts |
0:6b3ac9c5a042 | 56 | uint8_t MacCommandsBufferIndex; |
| Wayne Roberts |
0:6b3ac9c5a042 | 57 | uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 58 | static uint8_t MacCommandsBufferToRepeat[LORA_MAC_COMMAND_MAX_LENGTH]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 59 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 60 | LoRaMacParams_t LoRaMacParams; |
| Wayne Roberts |
0:6b3ac9c5a042 | 61 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 62 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 63 | static const uint8_t *LoRaMacDevEui; |
| Wayne Roberts |
0:6b3ac9c5a042 | 64 | static const uint8_t *LoRaMacJoinEui; |
| Wayne Roberts |
0:6b3ac9c5a042 | 65 | static const uint8_t *RootNwkKey; |
| Wayne Roberts |
0:6b3ac9c5a042 | 66 | static const uint8_t *RootAppKey; |
| Wayne Roberts |
0:6b3ac9c5a042 | 67 | static uint8_t MaxJoinRequestTrials; |
| Wayne Roberts |
0:6b3ac9c5a042 | 68 | static uint8_t JSEncKey[16]; // TODO move to keys |
| Wayne Roberts |
0:6b3ac9c5a042 | 69 | static uint8_t JSIntKey[16]; // TODO move to keys |
| Wayne Roberts |
0:6b3ac9c5a042 | 70 | static uint8_t JoinReqType; |
| Wayne Roberts |
0:6b3ac9c5a042 | 71 | static uint16_t LoRaMacDevNonce; |
| Wayne Roberts |
0:6b3ac9c5a042 | 72 | uint16_t RJcount0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 73 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 74 | static uint32_t FCntUp; |
| Wayne Roberts |
0:6b3ac9c5a042 | 75 | static uint32_t NFCntDown; /**< set to next expected value */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 76 | static uint32_t AFCntDown; /**< set to next expected value */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 77 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 78 | |
| Wayne Roberts |
3:eb174e10afbb | 79 | static uint16_t ADR_ACK_LIMIT; |
| Wayne Roberts |
3:eb174e10afbb | 80 | static uint16_t ADR_ACK_DELAY; |
| Wayne Roberts |
3:eb174e10afbb | 81 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 82 | DeviceClass_t LoRaMacDeviceClass; |
| Wayne Roberts |
0:6b3ac9c5a042 | 83 | uint8_t tx_buf_len; |
| Wayne Roberts |
0:6b3ac9c5a042 | 84 | const LoRaMacHeader_t* uplinkMHDR = (LoRaMacHeader_t*)&Radio::radio.tx_buf[0]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 85 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 86 | static uint32_t RxWindow1Delay_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 87 | static uint32_t RxWindow2Delay_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 88 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 89 | LoRaMacHeader_t last_up_macHdr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 90 | static uint8_t rxFRMPayload[244]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 91 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 92 | static const LoRaMacPrimitives_t *LoRaMacPrimitives; |
| Wayne Roberts |
0:6b3ac9c5a042 | 93 | static const LoRaMacCallback_t *LoRaMacCallbacks; |
| Wayne Roberts |
0:6b3ac9c5a042 | 94 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 95 | /*! |
| Wayne Roberts |
0:6b3ac9c5a042 | 96 | * LoRaMAC frame counter. Each time a packet is received the counter is incremented. |
| Wayne Roberts |
0:6b3ac9c5a042 | 97 | * Only the 16 LSB bits are received |
| Wayne Roberts |
0:6b3ac9c5a042 | 98 | */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 99 | static uint16_t ConfFCntDown; |
| Wayne Roberts |
0:6b3ac9c5a042 | 100 | static uint16_t ConfFCntUp; |
| Wayne Roberts |
0:6b3ac9c5a042 | 101 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 102 | static void PrepareRxDoneAbort(LoRaMacEventInfoStatus_t); |
| Wayne Roberts |
0:6b3ac9c5a042 | 103 | |
| Wayne Roberts |
7:4b6f960dcca2 | 104 | void OnRadioRxTimeout(void); |
| Wayne Roberts |
7:4b6f960dcca2 | 105 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 106 | LoRaMacStatus_t |
| Wayne Roberts |
0:6b3ac9c5a042 | 107 | AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 108 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 109 | LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 110 | // The maximum buffer length must take MAC commands to re-send into account. |
| Wayne Roberts |
0:6b3ac9c5a042 | 111 | uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH - MacCommandsBufferToRepeatIndex; |
| Wayne Roberts |
0:6b3ac9c5a042 | 112 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 113 | MAC_PRINTF("AddMacCommand(%02x, %02x, %02x)\r\n", cmd, p1, p2); |
| Wayne Roberts |
0:6b3ac9c5a042 | 114 | switch( cmd ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 115 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 116 | case MOTE_MAC_LINK_CHECK_REQ: |
| Wayne Roberts |
0:6b3ac9c5a042 | 117 | case MOTE_MAC_DEVICE_TIME_REQ: |
| Wayne Roberts |
0:6b3ac9c5a042 | 118 | if( MacCommandsBufferIndex < bufLen ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 119 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 120 | MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; |
| Wayne Roberts |
0:6b3ac9c5a042 | 121 | // No payload for this command |
| Wayne Roberts |
0:6b3ac9c5a042 | 122 | status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 123 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 124 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 125 | case MOTE_MAC_LINK_ADR_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 126 | if( MacCommandsBufferIndex < ( bufLen - 1 ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 127 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 128 | MAC_PRINTF("LINK_ADR_ANS %02x ", p1); |
| Wayne Roberts |
0:6b3ac9c5a042 | 129 | MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; |
| Wayne Roberts |
0:6b3ac9c5a042 | 130 | // Margin |
| Wayne Roberts |
0:6b3ac9c5a042 | 131 | MacCommandsBuffer[MacCommandsBufferIndex++] = p1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 132 | status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 133 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 134 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 135 | case MOTE_MAC_DUTY_CYCLE_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 136 | if( MacCommandsBufferIndex < bufLen ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 137 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 138 | MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; |
| Wayne Roberts |
0:6b3ac9c5a042 | 139 | // No payload for this answer |
| Wayne Roberts |
0:6b3ac9c5a042 | 140 | status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 141 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 142 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 143 | case MOTE_MAC_RX_PARAM_SETUP_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 144 | if( MacCommandsBufferIndex < ( bufLen - 1 ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 145 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 146 | MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; |
| Wayne Roberts |
0:6b3ac9c5a042 | 147 | // Status: Datarate ACK, Channel ACK |
| Wayne Roberts |
0:6b3ac9c5a042 | 148 | MacCommandsBuffer[MacCommandsBufferIndex++] = p1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 149 | status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 150 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 151 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 152 | case MOTE_MAC_DEV_STATUS_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 153 | if( MacCommandsBufferIndex < ( bufLen - 2 ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 154 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 155 | MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; |
| Wayne Roberts |
0:6b3ac9c5a042 | 156 | // 1st byte Battery |
| Wayne Roberts |
0:6b3ac9c5a042 | 157 | // 2nd byte Margin |
| Wayne Roberts |
0:6b3ac9c5a042 | 158 | MacCommandsBuffer[MacCommandsBufferIndex++] = p1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 159 | MacCommandsBuffer[MacCommandsBufferIndex++] = p2; |
| Wayne Roberts |
0:6b3ac9c5a042 | 160 | status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 161 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 162 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 163 | case MOTE_MAC_NEW_CHANNEL_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 164 | if( MacCommandsBufferIndex < ( bufLen - 1 ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 165 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 166 | MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; |
| Wayne Roberts |
0:6b3ac9c5a042 | 167 | // Status: Datarate range OK, Channel frequency OK |
| Wayne Roberts |
0:6b3ac9c5a042 | 168 | MacCommandsBuffer[MacCommandsBufferIndex++] = p1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 169 | status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 170 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 171 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 172 | case MOTE_MAC_RX_TIMING_SETUP_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 173 | if( MacCommandsBufferIndex < bufLen ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 174 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 175 | MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; |
| Wayne Roberts |
0:6b3ac9c5a042 | 176 | // No payload for this answer |
| Wayne Roberts |
0:6b3ac9c5a042 | 177 | status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 178 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 179 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 180 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 181 | case MOTE_MAC_REKEY_IND: |
| Wayne Roberts |
0:6b3ac9c5a042 | 182 | if( MacCommandsBufferIndex < bufLen-1 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 183 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 184 | MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; |
| Wayne Roberts |
0:6b3ac9c5a042 | 185 | // minor version: |
| Wayne Roberts |
0:6b3ac9c5a042 | 186 | if (RootAppKey == NULL) |
| Wayne Roberts |
0:6b3ac9c5a042 | 187 | MacCommandsBuffer[MacCommandsBufferIndex++] = 0; // lorawan1v0 |
| Wayne Roberts |
0:6b3ac9c5a042 | 188 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 189 | MacCommandsBuffer[MacCommandsBufferIndex++] = 1; // lorawan1v1 |
| Wayne Roberts |
0:6b3ac9c5a042 | 190 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 191 | status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 192 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 193 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 194 | case MOTE_MAC_REJOIN_PARAM_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 195 | if( MacCommandsBufferIndex < bufLen-1 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 196 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 197 | MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; |
| Wayne Roberts |
0:6b3ac9c5a042 | 198 | MacCommandsBuffer[MacCommandsBufferIndex++] = p1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 199 | status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 200 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 201 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 202 | #else |
| Wayne Roberts |
0:6b3ac9c5a042 | 203 | case MOTE_MAC_RESET_IND: |
| Wayne Roberts |
0:6b3ac9c5a042 | 204 | if( MacCommandsBufferIndex < bufLen-1 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 205 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 206 | MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; |
| Wayne Roberts |
0:6b3ac9c5a042 | 207 | // minor version: |
| Wayne Roberts |
0:6b3ac9c5a042 | 208 | MacCommandsBuffer[MacCommandsBufferIndex++] = p1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 209 | status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 210 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 211 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 212 | #endif /* !LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
7:4b6f960dcca2 | 213 | case MOTE_MAC_MODE_IND: |
| Wayne Roberts |
7:4b6f960dcca2 | 214 | if( MacCommandsBufferIndex < bufLen-1 ) |
| Wayne Roberts |
7:4b6f960dcca2 | 215 | { |
| Wayne Roberts |
7:4b6f960dcca2 | 216 | MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; |
| Wayne Roberts |
7:4b6f960dcca2 | 217 | MacCommandsBuffer[MacCommandsBufferIndex++] = p1; |
| Wayne Roberts |
7:4b6f960dcca2 | 218 | status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
7:4b6f960dcca2 | 219 | } |
| Wayne Roberts |
7:4b6f960dcca2 | 220 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 221 | default: |
| Wayne Roberts |
0:6b3ac9c5a042 | 222 | MAC_PRINTF("unknown-addCmd %02x\r\n", cmd); |
| Wayne Roberts |
0:6b3ac9c5a042 | 223 | return LORAMAC_STATUS_SERVICE_UNKNOWN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 224 | } // ..switch( cmd ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 225 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 226 | if( status == LORAMAC_STATUS_OK ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 227 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 228 | flags.MacCommandsInNextTx = true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 229 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 230 | return status; |
| Wayne Roberts |
0:6b3ac9c5a042 | 231 | } // ..AddMacCommand() |
| Wayne Roberts |
0:6b3ac9c5a042 | 232 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 233 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 234 | LoRaMacStatus_t SetTxContinuousWave( uint16_t timeout ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 235 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 236 | int8_t txPowerIndex = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 237 | int8_t txPower = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 238 | |
| Wayne Roberts |
3:eb174e10afbb | 239 | txPowerIndex = region_LimitTxPower( LoRaMacParams.ChannelsTxPower ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 240 | txPower = TxPowers[txPowerIndex]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 241 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 242 | Radio::SetTxContinuousWave( Channels[Channel].FreqHz, txPower, timeout ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 243 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 244 | flags.uplink_in_progress = 1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 245 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 246 | return LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 247 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 248 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 249 | __attribute__((weak)) LoRaMacStatus_t |
| Wayne Roberts |
0:6b3ac9c5a042 | 250 | LoRaMacMlmeRequestClassB( const MlmeReq_t *mlmeRequest ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 251 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 252 | return LORAMAC_STATUS_SERVICE_UNKNOWN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 253 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 254 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 255 | __attribute__((weak)) LoRaMacStatus_t |
| Wayne Roberts |
0:6b3ac9c5a042 | 256 | AddMacCommandClassB( uint8_t cmd, uint8_t p1, uint8_t p2 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 257 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 258 | return LORAMAC_STATUS_SERVICE_UNKNOWN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 259 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 260 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 261 | __attribute__((weak)) void |
| Wayne Roberts |
0:6b3ac9c5a042 | 262 | ResetMacParametersClassB() |
| Wayne Roberts |
0:6b3ac9c5a042 | 263 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 264 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 265 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 266 | static void ResetMacParameters( void ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 267 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 268 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 269 | flags.IsLoRaMacNetworkJoined = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 270 | NFCntDown = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 271 | AFCntDown = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 272 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 273 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 274 | #ifdef DUTY_ENABLE |
| Wayne Roberts |
0:6b3ac9c5a042 | 275 | DutyInit(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 276 | #endif /* DUTY_ENABLE */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 277 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 278 | MacCommandsBufferIndex = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 279 | MacCommandsBufferToRepeatIndex = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 280 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 281 | //IsRxWindowsEnabled = true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 282 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 283 | LoRaMacParams.ChannelsTxPower = LoRaMacParamsDefaults.ChannelsTxPower; |
| Wayne Roberts |
0:6b3ac9c5a042 | 284 | LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate; |
| Wayne Roberts |
0:6b3ac9c5a042 | 285 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 286 | LoRaMacParams.MaxRxWindow_us = LoRaMacParamsDefaults.MaxRxWindow_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 287 | LoRaMacParams.ReceiveDelay1_us = LoRaMacParamsDefaults.ReceiveDelay1_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 288 | LoRaMacParams.ReceiveDelay2_us = LoRaMacParamsDefaults.ReceiveDelay2_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 289 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 290 | LoRaMacParams.JoinAcceptDelay1_us = LoRaMacParamsDefaults.JoinAcceptDelay1_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 291 | LoRaMacParams.JoinAcceptDelay2_us = LoRaMacParamsDefaults.JoinAcceptDelay2_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 292 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 293 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 294 | LoRaMacParams.Rx1DrOffset = LoRaMacParamsDefaults.Rx1DrOffset; |
| Wayne Roberts |
0:6b3ac9c5a042 | 295 | LoRaMacParams.NbTrans = LoRaMacParamsDefaults.NbTrans; |
| Wayne Roberts |
0:6b3ac9c5a042 | 296 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 297 | LoRaMacParams.Rx2Channel = LoRaMacParamsDefaults.Rx2Channel; |
| Wayne Roberts |
0:6b3ac9c5a042 | 298 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 299 | memcpy( ( uint8_t* ) LoRaMacParams.ChannelsMask, ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) ); |
| Wayne Roberts |
3:eb174e10afbb | 300 | LoRaMacParams.NbEnabledChannels = LoRaMacParamsDefaults.NbEnabledChannels; |
| Wayne Roberts |
0:6b3ac9c5a042 | 301 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 302 | #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 303 | memcpy( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 304 | #endif |
| Wayne Roberts |
0:6b3ac9c5a042 | 305 | |
| Wayne Roberts |
7:4b6f960dcca2 | 306 | LoRaMacParams.MaxListenTime = LoRaMacParamsDefaults.MaxListenTime; |
| Wayne Roberts |
7:4b6f960dcca2 | 307 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 308 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 309 | flags.SrvAckRequested = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 310 | flags.MacCommandsInNextTx = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 311 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 312 | // Initialize channel index. |
| Wayne Roberts |
0:6b3ac9c5a042 | 313 | Channel = LORA_MAX_NB_CHANNELS; |
| Wayne Roberts |
0:6b3ac9c5a042 | 314 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 315 | ResetMacParametersClassB(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 316 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 317 | } // ..ResetMacParameters() |
| Wayne Roberts |
0:6b3ac9c5a042 | 318 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 319 | static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 320 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 321 | uint16_t maxN = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 322 | uint8_t payloadSize; |
| Wayne Roberts |
0:6b3ac9c5a042 | 323 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 324 | // Get the maximum payload length |
| Wayne Roberts |
0:6b3ac9c5a042 | 325 | maxN = MaxPayloadOfDatarate[datarate]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 326 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 327 | // Calculate the resulting payload size |
| Wayne Roberts |
0:6b3ac9c5a042 | 328 | payloadSize = ( lenN + fOptsLen ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 329 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 330 | // Validation of the application payload size |
| Wayne Roberts |
0:6b3ac9c5a042 | 331 | if( payloadSize <= maxN ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 332 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 333 | return true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 334 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 335 | return false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 336 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 337 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 338 | static uint8_t ParseMacCommandsToRepeat( uint8_t* cmdBufIn, uint8_t length, uint8_t* cmdBufOut ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 339 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 340 | uint8_t i = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 341 | uint8_t cmdCount = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 342 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 343 | if( ( cmdBufIn == NULL ) || ( cmdBufOut == NULL ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 344 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 345 | return 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 346 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 347 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 348 | for( i = 0; i < length; i++ ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 349 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 350 | switch( cmdBufIn[i] ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 351 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 352 | // STICKY |
| Wayne Roberts |
0:6b3ac9c5a042 | 353 | case MOTE_MAC_RX_PARAM_SETUP_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 354 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 355 | cmdBufOut[cmdCount++] = cmdBufIn[i++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 356 | cmdBufOut[cmdCount++] = cmdBufIn[i]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 357 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 358 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 359 | case MOTE_MAC_RX_TIMING_SETUP_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 360 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 361 | cmdBufOut[cmdCount++] = cmdBufIn[i]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 362 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 363 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 364 | // NON-STICKY |
| Wayne Roberts |
0:6b3ac9c5a042 | 365 | case MOTE_MAC_DEV_STATUS_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 366 | { // 2 bytes payload |
| Wayne Roberts |
0:6b3ac9c5a042 | 367 | i += 2; |
| Wayne Roberts |
0:6b3ac9c5a042 | 368 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 369 | } |
| Wayne Roberts |
7:4b6f960dcca2 | 370 | case MOTE_MAC_MODE_IND: |
| Wayne Roberts |
0:6b3ac9c5a042 | 371 | case MOTE_MAC_LINK_ADR_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 372 | case MOTE_MAC_NEW_CHANNEL_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 373 | { // 1 byte payload |
| Wayne Roberts |
0:6b3ac9c5a042 | 374 | i++; |
| Wayne Roberts |
0:6b3ac9c5a042 | 375 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 376 | } |
| Wayne Roberts |
3:eb174e10afbb | 377 | case SRV_MAC_ADR_PARAM_SETUP_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 378 | case MOTE_MAC_DUTY_CYCLE_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 379 | case MOTE_MAC_LINK_CHECK_REQ: |
| Wayne Roberts |
0:6b3ac9c5a042 | 380 | { // 0 byte payload |
| Wayne Roberts |
0:6b3ac9c5a042 | 381 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 382 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 383 | default: |
| Wayne Roberts |
0:6b3ac9c5a042 | 384 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 385 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 386 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 387 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 388 | return cmdCount; |
| Wayne Roberts |
7:4b6f960dcca2 | 389 | } // ..ParseMacCommandsToRepeat() |
| Wayne Roberts |
0:6b3ac9c5a042 | 390 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 391 | LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 392 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 393 | uint32_t fcnt_up; |
| Wayne Roberts |
0:6b3ac9c5a042 | 394 | uint16_t i; |
| Wayne Roberts |
0:6b3ac9c5a042 | 395 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 396 | uint32_t mic = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 397 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 398 | const void* payload = fBuffer; |
| Wayne Roberts |
0:6b3ac9c5a042 | 399 | uint8_t framePort = fPort; |
| Wayne Roberts |
0:6b3ac9c5a042 | 400 | uint8_t LoRaMacTxPayloadLen = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 401 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 402 | tx_buf_len = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 403 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 404 | if( fBuffer == NULL ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 405 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 406 | fBufferSize = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 407 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 408 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 409 | LoRaMacTxPayloadLen = fBufferSize; |
| Wayne Roberts |
0:6b3ac9c5a042 | 410 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 411 | Radio::radio.tx_buf[tx_buf_len++] = macHdr->Value; |
| Wayne Roberts |
0:6b3ac9c5a042 | 412 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 413 | switch( macHdr->Bits.MType ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 414 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 415 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 416 | case FRAME_TYPE_JOIN_REQ: |
| Wayne Roberts |
0:6b3ac9c5a042 | 417 | if (LoRaMacJoinEui == NULL || LoRaMacDevEui == NULL) |
| Wayne Roberts |
0:6b3ac9c5a042 | 418 | return LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 419 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 420 | RxWindow1Delay_us = LoRaMacParams.JoinAcceptDelay1_us - RADIO_WAKEUP_TIME_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 421 | RxWindow2Delay_us = LoRaMacParams.JoinAcceptDelay2_us - RADIO_WAKEUP_TIME_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 422 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 423 | memcpyr( Radio::radio.tx_buf + tx_buf_len, LoRaMacJoinEui, 8 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 424 | tx_buf_len += 8; |
| Wayne Roberts |
0:6b3ac9c5a042 | 425 | memcpyr( Radio::radio.tx_buf + tx_buf_len, LoRaMacDevEui, 8 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 426 | tx_buf_len += 8; |
| Wayne Roberts |
0:6b3ac9c5a042 | 427 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 428 | if (RootAppKey == NULL) |
| Wayne Roberts |
0:6b3ac9c5a042 | 429 | LoRaMacDevNonce = Radio::Random(); /* lorawan 1.0 */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 430 | else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 431 | LoRaMacDevNonce = eeprom_read(EEPROM_DEVNONCE); |
| Wayne Roberts |
0:6b3ac9c5a042 | 432 | /* joinReq DevNonce value is never re-used in 1v1 */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 433 | if (eeprom_increment_value(EEPROM_DEVNONCE) < 0) |
| Wayne Roberts |
0:6b3ac9c5a042 | 434 | return LORAMAC_STATUS_EEPROM_FAIL; |
| Wayne Roberts |
0:6b3ac9c5a042 | 435 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 436 | MAC_PRINTF("DevNonce:%u ", LoRaMacDevNonce); |
| Wayne Roberts |
0:6b3ac9c5a042 | 437 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 438 | Radio::radio.tx_buf[tx_buf_len++] = LoRaMacDevNonce & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 439 | Radio::radio.tx_buf[tx_buf_len++] = ( LoRaMacDevNonce >> 8 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 440 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 441 | if (LoRaMacJoinComputeMic(false, Radio::radio.tx_buf, tx_buf_len & 0xFF, RootNwkKey, &mic) < 0) |
| Wayne Roberts |
0:6b3ac9c5a042 | 442 | return LORAMAC_STATUS_SERVICE_UNKNOWN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 443 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 444 | Radio::radio.tx_buf[tx_buf_len++] = mic & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 445 | Radio::radio.tx_buf[tx_buf_len++] = ( mic >> 8 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 446 | Radio::radio.tx_buf[tx_buf_len++] = ( mic >> 16 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 447 | Radio::radio.tx_buf[tx_buf_len++] = ( mic >> 24 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 448 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 449 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 450 | case FRAME_TYPE_REJOIN_REQ: |
| Wayne Roberts |
0:6b3ac9c5a042 | 451 | RxWindow1Delay_us = LoRaMacParams.JoinAcceptDelay1_us - RADIO_WAKEUP_TIME_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 452 | RxWindow2Delay_us = LoRaMacParams.JoinAcceptDelay2_us - RADIO_WAKEUP_TIME_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 453 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 454 | Radio::radio.tx_buf[tx_buf_len++] = JoinReqType; |
| Wayne Roberts |
0:6b3ac9c5a042 | 455 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 456 | tx_buf_len = tx_buf_len; |
| Wayne Roberts |
0:6b3ac9c5a042 | 457 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 458 | if (JoinReqType == 0 || JoinReqType == 2) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 459 | LoRaMacDevNonce = RJcount0++; |
| Wayne Roberts |
0:6b3ac9c5a042 | 460 | /* NetID + DevEUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 461 | Radio::radio.tx_buf[tx_buf_len++] = ( LoRaMacNetID ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 462 | Radio::radio.tx_buf[tx_buf_len++] = ( LoRaMacNetID >> 8 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 463 | Radio::radio.tx_buf[tx_buf_len++] = ( LoRaMacNetID >> 16 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 464 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 465 | memcpyr( Radio::radio.tx_buf + tx_buf_len, LoRaMacDevEui, 8 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 466 | tx_buf_len += 8; |
| Wayne Roberts |
0:6b3ac9c5a042 | 467 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 468 | Radio::radio.tx_buf[tx_buf_len++] = LoRaMacDevNonce & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 469 | Radio::radio.tx_buf[tx_buf_len++] = ( LoRaMacDevNonce >> 8 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 470 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 471 | if (LoRaMacJoinComputeMic(false, Radio::radio.tx_buf, tx_buf_len & 0xFF, keys.SNwkSIntKey, &mic) < 0) |
| Wayne Roberts |
0:6b3ac9c5a042 | 472 | return LORAMAC_STATUS_SERVICE_UNKNOWN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 473 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 474 | } else if (JoinReqType == 1) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 475 | /* JoinEUI + DevEUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 476 | LoRaMacDevNonce = eeprom_read(EEPROM_RJCOUNT1); |
| Wayne Roberts |
0:6b3ac9c5a042 | 477 | if (eeprom_increment_value(EEPROM_RJCOUNT1) < 0) |
| Wayne Roberts |
0:6b3ac9c5a042 | 478 | return LORAMAC_STATUS_EEPROM_FAIL; |
| Wayne Roberts |
0:6b3ac9c5a042 | 479 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 480 | memcpyr( Radio::radio.tx_buf + tx_buf_len, LoRaMacJoinEui, 8 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 481 | tx_buf_len += 8; |
| Wayne Roberts |
0:6b3ac9c5a042 | 482 | memcpyr( Radio::radio.tx_buf + tx_buf_len, LoRaMacDevEui, 8 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 483 | tx_buf_len += 8; |
| Wayne Roberts |
0:6b3ac9c5a042 | 484 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 485 | Radio::radio.tx_buf[tx_buf_len++] = LoRaMacDevNonce & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 486 | Radio::radio.tx_buf[tx_buf_len++] = ( LoRaMacDevNonce >> 8 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 487 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 488 | //print_buf(JSIntKey, 16, "JSIntKey"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 489 | if (LoRaMacJoinComputeMic(false, Radio::radio.tx_buf, tx_buf_len & 0xFF, JSIntKey, &mic) < 0) |
| Wayne Roberts |
0:6b3ac9c5a042 | 490 | return LORAMAC_STATUS_SERVICE_UNKNOWN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 491 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 492 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 493 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 494 | Radio::radio.tx_buf[tx_buf_len++] = mic & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 495 | Radio::radio.tx_buf[tx_buf_len++] = ( mic >> 8 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 496 | Radio::radio.tx_buf[tx_buf_len++] = ( mic >> 16 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 497 | Radio::radio.tx_buf[tx_buf_len++] = ( mic >> 24 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 498 | MAC_PRINTF("up-rejoin-frame len%u type%u\r\n", tx_buf_len, JoinReqType); |
| Wayne Roberts |
0:6b3ac9c5a042 | 499 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 500 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 501 | case FRAME_TYPE_DATA_CONFIRMED_UP: |
| Wayne Roberts |
0:6b3ac9c5a042 | 502 | //Intentional fallthrough |
| Wayne Roberts |
0:6b3ac9c5a042 | 503 | case FRAME_TYPE_DATA_UNCONFIRMED_UP: |
| Wayne Roberts |
0:6b3ac9c5a042 | 504 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 505 | if (!flags.IsLoRaMacNetworkJoined) |
| Wayne Roberts |
0:6b3ac9c5a042 | 506 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 507 | return LORAMAC_STATUS_NO_NETWORK_JOINED; // No network has been joined yet |
| Wayne Roberts |
0:6b3ac9c5a042 | 508 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 509 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 510 | if (flags.OptNeg && flags.need_ReKeyConf) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 511 | /* lorawan1v1 need rekeying confirmation */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 512 | LoRaMacStatus_t s = AddMacCommand(MOTE_MAC_REKEY_IND, 0, 0); |
| Wayne Roberts |
0:6b3ac9c5a042 | 513 | if (s != LORAMAC_STATUS_OK) |
| Wayne Roberts |
0:6b3ac9c5a042 | 514 | return s; |
| Wayne Roberts |
3:eb174e10afbb | 515 | if (McpsIndication.ADR_ACK_CNT > ADR_ACK_DELAY) { |
| Wayne Roberts |
3:eb174e10afbb | 516 | /* give up sending rekey indication, try joining again */ |
| Wayne Roberts |
3:eb174e10afbb | 517 | flags.IsLoRaMacNetworkJoined = false; |
| Wayne Roberts |
3:eb174e10afbb | 518 | return LORAMAC_STATUS_NO_NETWORK_JOINED; |
| Wayne Roberts |
3:eb174e10afbb | 519 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 520 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 521 | fcnt_up = FCntUp; |
| Wayne Roberts |
0:6b3ac9c5a042 | 522 | #else |
| Wayne Roberts |
0:6b3ac9c5a042 | 523 | if (flags.need_ResetConf) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 524 | LoRaMacStatus_t s = AddMacCommand(MOTE_MAC_RESET_IND, flags.OptNeg, 0); |
| Wayne Roberts |
0:6b3ac9c5a042 | 525 | if (s != LORAMAC_STATUS_OK) |
| Wayne Roberts |
0:6b3ac9c5a042 | 526 | return s; |
| Wayne Roberts |
0:6b3ac9c5a042 | 527 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 528 | fcnt_up = eeprom_read(EEPROM_FCNTUP); |
| Wayne Roberts |
0:6b3ac9c5a042 | 529 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 530 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 531 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 532 | if( ValidatePayloadLength( LoRaMacTxPayloadLen, LoRaMacParams.ChannelsDatarate, MacCommandsBufferIndex ) == false ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 533 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 534 | MAC_PRINTF("LoRaMacTxPayloadLen%u, FOptsLen%u\r\n", LoRaMacTxPayloadLen, MacCommandsBufferIndex); |
| Wayne Roberts |
0:6b3ac9c5a042 | 535 | return LORAMAC_STATUS_LENGTH_ERROR; |
| Wayne Roberts |
0:6b3ac9c5a042 | 536 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 537 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 538 | RxWindow1Delay_us = LoRaMacParams.ReceiveDelay1_us - RADIO_WAKEUP_TIME_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 539 | RxWindow2Delay_us = LoRaMacParams.ReceiveDelay2_us - RADIO_WAKEUP_TIME_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 540 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 541 | if( flags.SrvAckRequested == true ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 542 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 543 | flags.SrvAckRequested = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 544 | fCtrl->Bits.Ack = 1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 545 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 546 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 547 | Radio::radio.tx_buf[tx_buf_len++] = ( LoRaMacDevAddr ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 548 | Radio::radio.tx_buf[tx_buf_len++] = ( LoRaMacDevAddr >> 8 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 549 | Radio::radio.tx_buf[tx_buf_len++] = ( LoRaMacDevAddr >> 16 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 550 | Radio::radio.tx_buf[tx_buf_len++] = ( LoRaMacDevAddr >> 24 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 551 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 552 | Radio::radio.tx_buf[tx_buf_len++] = fCtrl->Value; |
| Wayne Roberts |
0:6b3ac9c5a042 | 553 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 554 | // FCntUp will be inserted in SendFrameOnChannel(), where MIC is inserted also |
| Wayne Roberts |
0:6b3ac9c5a042 | 555 | tx_buf_len += 2; |
| Wayne Roberts |
0:6b3ac9c5a042 | 556 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 557 | ConfFCntUp = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 558 | if (flags.OptNeg) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 559 | if (macHdr->Bits.MType == FRAME_TYPE_DATA_CONFIRMED_UP) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 560 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 561 | ConfFCntUp = FCntUp; |
| Wayne Roberts |
0:6b3ac9c5a042 | 562 | #else |
| Wayne Roberts |
0:6b3ac9c5a042 | 563 | ConfFCntUp = eeprom_read(EEPROM_FCNTUP); |
| Wayne Roberts |
0:6b3ac9c5a042 | 564 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 565 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 566 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 567 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 568 | // Copy the MAC commands which must be re-send into the MAC command buffer |
| Wayne Roberts |
0:6b3ac9c5a042 | 569 | memcpy( &MacCommandsBuffer[MacCommandsBufferIndex], MacCommandsBufferToRepeat, MacCommandsBufferToRepeatIndex ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 570 | MacCommandsBufferIndex += MacCommandsBufferToRepeatIndex; |
| Wayne Roberts |
0:6b3ac9c5a042 | 571 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 572 | if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 573 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 574 | if( ( MacCommandsBufferIndex <= LORA_MAC_COMMAND_MAX_LENGTH ) && ( flags.MacCommandsInNextTx == true ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 575 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 576 | MAC_PRINTF("uplink mac-cmds %u into FOpts at %u ", MacCommandsBufferIndex, tx_buf_len); |
| Wayne Roberts |
0:6b3ac9c5a042 | 577 | fCtrl->Bits.FOptsLen += MacCommandsBufferIndex; |
| Wayne Roberts |
0:6b3ac9c5a042 | 578 | // Update FCtrl field with new value of OptionsLength |
| Wayne Roberts |
0:6b3ac9c5a042 | 579 | Radio::radio.tx_buf[0x05] = fCtrl->Value; |
| Wayne Roberts |
0:6b3ac9c5a042 | 580 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 581 | /* lorawan1v1: encode FOpts using NWkSEncKey */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 582 | if (flags.OptNeg) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 583 | LoRaMacEncrypt(0, MacCommandsBuffer, MacCommandsBufferIndex, keys.NwkSEncKey, LoRaMacDevAddr, UP_LINK, fcnt_up, Radio::radio.tx_buf + tx_buf_len); |
| Wayne Roberts |
0:6b3ac9c5a042 | 584 | tx_buf_len += MacCommandsBufferIndex; |
| Wayne Roberts |
0:6b3ac9c5a042 | 585 | } else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 586 | for( i = 0; i < MacCommandsBufferIndex; i++ ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 587 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 588 | Radio::radio.tx_buf[tx_buf_len++] = MacCommandsBuffer[i]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 589 | MAC_PRINTF("%02x ", MacCommandsBuffer[i]); |
| Wayne Roberts |
0:6b3ac9c5a042 | 590 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 591 | MAC_PRINTF(" fCtrl->Value:%02x\r\n", Radio::radio.tx_buf[0x05]); |
| Wayne Roberts |
0:6b3ac9c5a042 | 592 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 593 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 594 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 595 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 596 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 597 | if( ( MacCommandsBufferIndex > 0 ) && ( flags.MacCommandsInNextTx ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 598 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 599 | MAC_PRINTF("uplink mac-cmds %u port0 ", MacCommandsBufferIndex); |
| Wayne Roberts |
0:6b3ac9c5a042 | 600 | for (i = 0; i < MacCommandsBufferIndex; i++) |
| Wayne Roberts |
0:6b3ac9c5a042 | 601 | MAC_PRINTF("%02x ", MacCommandsBuffer[i]); |
| Wayne Roberts |
0:6b3ac9c5a042 | 602 | MAC_PRINTF("\r\n"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 603 | LoRaMacTxPayloadLen = MacCommandsBufferIndex; |
| Wayne Roberts |
0:6b3ac9c5a042 | 604 | payload = MacCommandsBuffer; |
| Wayne Roberts |
0:6b3ac9c5a042 | 605 | framePort = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 606 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 607 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 608 | flags.MacCommandsInNextTx = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 609 | // Store MAC commands which must be re-send in case the device does not receive a downlink anymore |
| Wayne Roberts |
0:6b3ac9c5a042 | 610 | MacCommandsBufferToRepeatIndex = ParseMacCommandsToRepeat( MacCommandsBuffer, MacCommandsBufferIndex, MacCommandsBufferToRepeat ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 611 | if( MacCommandsBufferToRepeatIndex > 0 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 612 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 613 | flags.MacCommandsInNextTx = true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 614 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 615 | MacCommandsBufferIndex = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 616 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 617 | if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 618 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 619 | const uint8_t* keyPtr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 620 | Radio::radio.tx_buf[tx_buf_len++] = framePort; |
| Wayne Roberts |
0:6b3ac9c5a042 | 621 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 622 | if( framePort == 0 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 623 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 624 | DEBUG_CRYPT_BUF(keys.NwkSEncKey, 16, "NwkSEncKey", 0); |
| Wayne Roberts |
0:6b3ac9c5a042 | 625 | keyPtr = keys.NwkSEncKey; |
| Wayne Roberts |
0:6b3ac9c5a042 | 626 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 627 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 628 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 629 | DEBUG_CRYPT_BUF(keys.AppSKey, 16, "AppSKey", 0); |
| Wayne Roberts |
0:6b3ac9c5a042 | 630 | keyPtr = keys.AppSKey; |
| Wayne Roberts |
0:6b3ac9c5a042 | 631 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 632 | LoRaMacEncrypt(1, (uint8_t* ) payload, LoRaMacTxPayloadLen, keyPtr, LoRaMacDevAddr, UP_LINK, fcnt_up, Radio::radio.tx_buf + tx_buf_len); |
| Wayne Roberts |
0:6b3ac9c5a042 | 633 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 634 | tx_buf_len = tx_buf_len + LoRaMacTxPayloadLen; |
| Wayne Roberts |
0:6b3ac9c5a042 | 635 | /* mic cacluation in SendFrameOnChannel() */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 636 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 637 | case FRAME_TYPE_PROPRIETARY: |
| Wayne Roberts |
0:6b3ac9c5a042 | 638 | if( ( fBuffer != NULL ) && ( LoRaMacTxPayloadLen > 0 ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 639 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 640 | memcpy( Radio::radio.tx_buf + tx_buf_len, ( uint8_t* ) fBuffer, LoRaMacTxPayloadLen ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 641 | tx_buf_len = tx_buf_len + LoRaMacTxPayloadLen; |
| Wayne Roberts |
0:6b3ac9c5a042 | 642 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 643 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 644 | default: |
| Wayne Roberts |
0:6b3ac9c5a042 | 645 | return LORAMAC_STATUS_SERVICE_UNKNOWN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 646 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 647 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 648 | flags.uplink_mtype = macHdr->Bits.MType; |
| Wayne Roberts |
0:6b3ac9c5a042 | 649 | flags.uplink_in_progress = LoRaMacParams.NbTrans; |
| Wayne Roberts |
0:6b3ac9c5a042 | 650 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 651 | return LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 652 | } // ..PrepareFrame() |
| Wayne Roberts |
0:6b3ac9c5a042 | 653 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 654 | LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 655 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 656 | LoRaMacFrameCtrl_t fCtrl; |
| Wayne Roberts |
0:6b3ac9c5a042 | 657 | LoRaMacStatus_t status = LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 658 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 659 | fCtrl.Value = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 660 | fCtrl.Bits.FOptsLen = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 661 | if( LoRaMacDeviceClass == CLASS_B ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 662 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 663 | fCtrl.Bits.FPending = 1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 664 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 665 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 666 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 667 | fCtrl.Bits.FPending = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 668 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 669 | fCtrl.Bits.Ack = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 670 | fCtrl.Bits.AdrAckReq = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 671 | fCtrl.Bits.Adr = flags.AdrCtrlOn; |
| Wayne Roberts |
0:6b3ac9c5a042 | 672 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 673 | // Prepare the frame |
| Wayne Roberts |
0:6b3ac9c5a042 | 674 | status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 675 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 676 | // Validate status |
| Wayne Roberts |
0:6b3ac9c5a042 | 677 | if( status != LORAMAC_STATUS_OK ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 678 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 679 | return status; |
| Wayne Roberts |
0:6b3ac9c5a042 | 680 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 681 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 682 | // Reset confirm parameters |
| Wayne Roberts |
0:6b3ac9c5a042 | 683 | McpsConfirm.NbRetries = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 684 | McpsConfirm.AckReceived = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 685 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 686 | status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 687 | if (flags.rxing) |
| Wayne Roberts |
0:6b3ac9c5a042 | 688 | function_pending = region_ScheduleTx; |
| Wayne Roberts |
0:6b3ac9c5a042 | 689 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 690 | region_ScheduleTx( ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 691 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 692 | return status; |
| Wayne Roberts |
0:6b3ac9c5a042 | 693 | } // ..Send() |
| Wayne Roberts |
0:6b3ac9c5a042 | 694 | |
| Wayne Roberts |
5:4e9d41359897 | 695 | LoRaMacStatus_t waitingFor; |
| Wayne Roberts |
5:4e9d41359897 | 696 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 697 | LoRaMacStatus_t |
| Wayne Roberts |
0:6b3ac9c5a042 | 698 | LoRaMacMlmeRequest( const MlmeReq_t *mlmeRequest ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 699 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 700 | LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 701 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 702 | LoRaMacHeader_t macHdr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 703 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 704 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 705 | if( mlmeRequest == NULL ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 706 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 707 | return LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 708 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 709 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 710 | if (flags.uplink_in_progress > 0) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 711 | MAC_PRINTF("LoRaMacMlmeRequest() BUSY\r\n"); |
| Wayne Roberts |
5:4e9d41359897 | 712 | return waitingFor; |
| Wayne Roberts |
0:6b3ac9c5a042 | 713 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 714 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 715 | MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_MLMEREQ; |
| Wayne Roberts |
0:6b3ac9c5a042 | 716 | MlmeIndication.MlmeIndication = mlmeRequest->Type; |
| Wayne Roberts |
0:6b3ac9c5a042 | 717 | |
| Wayne Roberts |
5:4e9d41359897 | 718 | waitingFor = LORAMAC_STATUS_WAITING_FOR_TXSTART; |
| Wayne Roberts |
5:4e9d41359897 | 719 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 720 | MAC_PRINTF("LoRaMacMlmeRequest() "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 721 | switch( mlmeRequest->Type ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 722 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 723 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 724 | case MLME_JOIN: |
| Wayne Roberts |
0:6b3ac9c5a042 | 725 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 726 | if( ( mlmeRequest->Req.Join.DevEui == NULL ) || |
| Wayne Roberts |
0:6b3ac9c5a042 | 727 | ( mlmeRequest->Req.Join.JoinEui == NULL ) || |
| Wayne Roberts |
0:6b3ac9c5a042 | 728 | ( mlmeRequest->Req.Join.NwkKey == NULL ) || |
| Wayne Roberts |
0:6b3ac9c5a042 | 729 | ( mlmeRequest->Req.Join.NbTrials == 0 ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 730 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 731 | return LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 732 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 733 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 734 | LoRaMacDevEui = mlmeRequest->Req.Join.DevEui; |
| Wayne Roberts |
0:6b3ac9c5a042 | 735 | LoRaMacJoinEui = mlmeRequest->Req.Join.JoinEui; |
| Wayne Roberts |
0:6b3ac9c5a042 | 736 | RootNwkKey = mlmeRequest->Req.Join.NwkKey; |
| Wayne Roberts |
0:6b3ac9c5a042 | 737 | RootAppKey = mlmeRequest->Req.Join.AppKey; |
| Wayne Roberts |
0:6b3ac9c5a042 | 738 | MaxJoinRequestTrials = mlmeRequest->Req.Join.NbTrials; |
| Wayne Roberts |
0:6b3ac9c5a042 | 739 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 740 | /*if (RootAppKey != NULL) {*/ |
| Wayne Roberts |
0:6b3ac9c5a042 | 741 | LoRaMacGenerateJoinKey(0x05, RootNwkKey, LoRaMacDevEui, JSEncKey); |
| Wayne Roberts |
0:6b3ac9c5a042 | 742 | //print_buf(JSEncKey, 16, "new-JSEncKey"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 743 | LoRaMacGenerateJoinKey(0x06, RootNwkKey, LoRaMacDevEui, JSIntKey); |
| Wayne Roberts |
0:6b3ac9c5a042 | 744 | //print_buf(JSIntKey, 16, "new-JSIntKey"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 745 | /*}*/ |
| Wayne Roberts |
0:6b3ac9c5a042 | 746 | JoinReqType = 0xff; |
| Wayne Roberts |
0:6b3ac9c5a042 | 747 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 748 | // Reset variable JoinRequestTrials |
| Wayne Roberts |
0:6b3ac9c5a042 | 749 | MlmeIndication.JoinRequestTrials = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 750 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 751 | // Setup header information |
| Wayne Roberts |
0:6b3ac9c5a042 | 752 | macHdr.Value = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 753 | macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ; |
| Wayne Roberts |
0:6b3ac9c5a042 | 754 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 755 | ResetMacParameters( ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 756 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 757 | // Add a +1, since we start to count from 0 |
| Wayne Roberts |
3:eb174e10afbb | 758 | LoRaMacParams.ChannelsDatarate = region_AlternateDatarate( MlmeIndication.JoinRequestTrials + 1 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 759 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 760 | status = Send( &macHdr, 0, NULL, 0 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 761 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 762 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 763 | case MLME_REJOIN_1: |
| Wayne Roberts |
0:6b3ac9c5a042 | 764 | if ( mlmeRequest->Req.Join.JoinEui == NULL ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 765 | return LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 766 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 767 | LoRaMacJoinEui = mlmeRequest->Req.Join.JoinEui; |
| Wayne Roberts |
0:6b3ac9c5a042 | 768 | JoinReqType = 0x01; |
| Wayne Roberts |
0:6b3ac9c5a042 | 769 | // fall-thru |
| Wayne Roberts |
0:6b3ac9c5a042 | 770 | case MLME_REJOIN_0: |
| Wayne Roberts |
0:6b3ac9c5a042 | 771 | case MLME_REJOIN_2: // Type2 can only be sent via mac-command |
| Wayne Roberts |
0:6b3ac9c5a042 | 772 | if( ( mlmeRequest->Req.Join.DevEui == NULL ) || |
| Wayne Roberts |
0:6b3ac9c5a042 | 773 | ( mlmeRequest->Req.Join.NwkKey == NULL ) || |
| Wayne Roberts |
0:6b3ac9c5a042 | 774 | ( mlmeRequest->Req.Join.NbTrials == 0 ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 775 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 776 | MAC_PRINTF(" (missing %p %p %d)\n", |
| Wayne Roberts |
0:6b3ac9c5a042 | 777 | mlmeRequest->Req.Join.DevEui, |
| Wayne Roberts |
0:6b3ac9c5a042 | 778 | mlmeRequest->Req.Join.NwkKey, |
| Wayne Roberts |
0:6b3ac9c5a042 | 779 | mlmeRequest->Req.Join.NbTrials |
| Wayne Roberts |
0:6b3ac9c5a042 | 780 | ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 781 | return LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 782 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 783 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 784 | RootNwkKey = mlmeRequest->Req.Join.NwkKey; |
| Wayne Roberts |
0:6b3ac9c5a042 | 785 | LoRaMacDevEui = mlmeRequest->Req.Join.DevEui; |
| Wayne Roberts |
0:6b3ac9c5a042 | 786 | LoRaMacGenerateJoinKey(0x05, RootNwkKey, LoRaMacDevEui, JSEncKey); |
| Wayne Roberts |
0:6b3ac9c5a042 | 787 | LoRaMacGenerateJoinKey(0x06, RootNwkKey, LoRaMacDevEui, JSIntKey); |
| Wayne Roberts |
0:6b3ac9c5a042 | 788 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 789 | RootAppKey = mlmeRequest->Req.Join.AppKey; |
| Wayne Roberts |
0:6b3ac9c5a042 | 790 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 791 | macHdr.Value = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 792 | macHdr.Bits.MType = FRAME_TYPE_REJOIN_REQ; |
| Wayne Roberts |
0:6b3ac9c5a042 | 793 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 794 | if (mlmeRequest->Type == MLME_REJOIN_0) |
| Wayne Roberts |
0:6b3ac9c5a042 | 795 | JoinReqType = 0x00; |
| Wayne Roberts |
0:6b3ac9c5a042 | 796 | else if (mlmeRequest->Type == MLME_REJOIN_2) |
| Wayne Roberts |
0:6b3ac9c5a042 | 797 | JoinReqType = 0x02; |
| Wayne Roberts |
0:6b3ac9c5a042 | 798 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 799 | MaxJoinRequestTrials = mlmeRequest->Req.Join.NbTrials; |
| Wayne Roberts |
0:6b3ac9c5a042 | 800 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 801 | status = Send( &macHdr, 0, NULL, 0 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 802 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 803 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 804 | case MLME_LINK_CHECK: |
| Wayne Roberts |
0:6b3ac9c5a042 | 805 | status = AddMacCommand( MOTE_MAC_LINK_CHECK_REQ, 0, 0 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 806 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 807 | case MLME_TIME_REQ: |
| Wayne Roberts |
0:6b3ac9c5a042 | 808 | status = AddMacCommand( MOTE_MAC_DEVICE_TIME_REQ, 0, 0 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 809 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 810 | case MLME_TXCW: |
| Wayne Roberts |
0:6b3ac9c5a042 | 811 | status = SetTxContinuousWave( mlmeRequest->Req.TxCw.Timeout ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 812 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 813 | case MLME_PING_SLOT_INFO: |
| Wayne Roberts |
0:6b3ac9c5a042 | 814 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 815 | uint8_t value = mlmeRequest->Req.PingSlotInfo.Value; |
| Wayne Roberts |
0:6b3ac9c5a042 | 816 | status = LoRaMacMlmeRequestClassB(mlmeRequest); |
| Wayne Roberts |
0:6b3ac9c5a042 | 817 | if (status == LORAMAC_STATUS_OK) |
| Wayne Roberts |
0:6b3ac9c5a042 | 818 | status = AddMacCommandClassB( MOTE_MAC_PING_SLOT_INFO_REQ, value, 0 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 819 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 820 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 821 | case MLME_BEACON_ACQUISITION: |
| Wayne Roberts |
0:6b3ac9c5a042 | 822 | case MLME_BEACON_TIMING: |
| Wayne Roberts |
0:6b3ac9c5a042 | 823 | status = LoRaMacMlmeRequestClassB(mlmeRequest); |
| Wayne Roberts |
0:6b3ac9c5a042 | 824 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 825 | default: |
| Wayne Roberts |
0:6b3ac9c5a042 | 826 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 827 | } // ...switch( mlmeRequest->Type ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 828 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 829 | if( status != LORAMAC_STATUS_OK ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 830 | MlmeConfirm.MlmeRequest = MLME_NONE; |
| Wayne Roberts |
0:6b3ac9c5a042 | 831 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 832 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 833 | MlmeConfirm.MlmeRequest = mlmeRequest->Type; |
| Wayne Roberts |
0:6b3ac9c5a042 | 834 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 835 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 836 | return status; |
| Wayne Roberts |
0:6b3ac9c5a042 | 837 | } // ..LoRaMacMlmeRequest() |
| Wayne Roberts |
0:6b3ac9c5a042 | 838 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 839 | LoRaMacStatus_t |
| Wayne Roberts |
0:6b3ac9c5a042 | 840 | LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 841 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 842 | LoRaMacStatus_t status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 843 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 844 | switch( mibGet->Type ) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 845 | case MIB_APP_SKEY: |
| Wayne Roberts |
0:6b3ac9c5a042 | 846 | mibGet->Param.key = keys.AppSKey; |
| Wayne Roberts |
0:6b3ac9c5a042 | 847 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 848 | case MIB_FNwkSIntKey: |
| Wayne Roberts |
0:6b3ac9c5a042 | 849 | mibGet->Param.key = keys.FNwkSIntKey; |
| Wayne Roberts |
0:6b3ac9c5a042 | 850 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 851 | case MIB_SNwkSIntKey: |
| Wayne Roberts |
0:6b3ac9c5a042 | 852 | mibGet->Param.key = keys.SNwkSIntKey; |
| Wayne Roberts |
0:6b3ac9c5a042 | 853 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 854 | case MIB_NwkSEncKey: |
| Wayne Roberts |
0:6b3ac9c5a042 | 855 | mibGet->Param.key = keys.NwkSEncKey; |
| Wayne Roberts |
0:6b3ac9c5a042 | 856 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 857 | case MIB_NwkSKey: |
| Wayne Roberts |
0:6b3ac9c5a042 | 858 | /* lorawan 1.0 */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 859 | mibGet->Param.key = keys.FNwkSIntKey; |
| Wayne Roberts |
0:6b3ac9c5a042 | 860 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 861 | case MIB_RX2_CHANNEL: |
| Wayne Roberts |
0:6b3ac9c5a042 | 862 | mibGet->Param.Rx2Channel = LoRaMacParams.Rx2Channel; |
| Wayne Roberts |
0:6b3ac9c5a042 | 863 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 864 | case MIB_DEVICE_CLASS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 865 | mibGet->Param.Class = LoRaMacDeviceClass; |
| Wayne Roberts |
0:6b3ac9c5a042 | 866 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 867 | case MIB_ADR: |
| Wayne Roberts |
0:6b3ac9c5a042 | 868 | mibGet->Param.AdrEnable = flags.AdrCtrlOn; |
| Wayne Roberts |
0:6b3ac9c5a042 | 869 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 870 | case MIB_DEV_ADDR: |
| Wayne Roberts |
0:6b3ac9c5a042 | 871 | mibGet->Param.DevAddr = LoRaMacDevAddr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 872 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 873 | case MIB_PUBLIC_NETWORK: |
| Wayne Roberts |
0:6b3ac9c5a042 | 874 | mibGet->Param.EnablePublicNetwork = flags.PublicNetwork; |
| Wayne Roberts |
0:6b3ac9c5a042 | 875 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 876 | case MIB_CHANNELS_MASK: |
| Wayne Roberts |
0:6b3ac9c5a042 | 877 | mibGet->Param.ChannelsMask = LoRaMacParams.ChannelsMask; |
| Wayne Roberts |
3:eb174e10afbb | 878 | LoRaMacParams.NbEnabledChannels = region_CountNbEnabledChannels(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 879 | break; |
| Wayne Roberts |
7:4b6f960dcca2 | 880 | case MIB_MAX_LISTEN_TIME: |
| Wayne Roberts |
7:4b6f960dcca2 | 881 | mibGet->Param.MaxListenTime = LoRaMacParams.MaxListenTime; |
| Wayne Roberts |
7:4b6f960dcca2 | 882 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 883 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 884 | case MIB_NETWORK_JOINED: |
| Wayne Roberts |
0:6b3ac9c5a042 | 885 | mibGet->Param.IsNetworkJoined = flags.IsLoRaMacNetworkJoined; |
| Wayne Roberts |
0:6b3ac9c5a042 | 886 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 887 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 888 | } // ..switch( mibGet->Type ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 889 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 890 | return status; |
| Wayne Roberts |
0:6b3ac9c5a042 | 891 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 892 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 893 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 894 | LoRaMacStatus_t |
| Wayne Roberts |
0:6b3ac9c5a042 | 895 | LoRaMacQueryTxPossible(uint8_t size, LoRaMacTxInfo_t* txInfo) |
| Wayne Roberts |
0:6b3ac9c5a042 | 896 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 897 | int8_t datarate = LoRaMacParamsDefaults.ChannelsDatarate; |
| Wayne Roberts |
0:6b3ac9c5a042 | 898 | uint8_t fOptLen = MacCommandsBufferIndex + MacCommandsBufferToRepeatIndex; |
| Wayne Roberts |
0:6b3ac9c5a042 | 899 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 900 | if( txInfo == NULL ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 901 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 902 | return LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 903 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 904 | |
| Wayne Roberts |
3:eb174e10afbb | 905 | //AdrNextDr( flags.AdrCtrlOn, false, &datarate ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 906 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 907 | txInfo->CurrentPayloadSize = MaxPayloadOfDatarate[datarate]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 908 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 909 | if( txInfo->CurrentPayloadSize >= fOptLen ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 910 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 911 | txInfo->MaxPossiblePayload = txInfo->CurrentPayloadSize - fOptLen; |
| Wayne Roberts |
0:6b3ac9c5a042 | 912 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 913 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 914 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 915 | return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR; |
| Wayne Roberts |
0:6b3ac9c5a042 | 916 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 917 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 918 | if( ValidatePayloadLength( size, datarate, 0 ) == false ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 919 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 920 | return LORAMAC_STATUS_LENGTH_ERROR; |
| Wayne Roberts |
0:6b3ac9c5a042 | 921 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 922 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 923 | if( ValidatePayloadLength( size, datarate, fOptLen ) == false ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 924 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 925 | return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR; |
| Wayne Roberts |
0:6b3ac9c5a042 | 926 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 927 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 928 | return LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 929 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 930 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 931 | LoRaMacStatus_t |
| Wayne Roberts |
0:6b3ac9c5a042 | 932 | LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 933 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 934 | LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 935 | LoRaMacHeader_t macHdr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 936 | uint8_t fPort = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 937 | void *fBuffer; |
| Wayne Roberts |
0:6b3ac9c5a042 | 938 | uint16_t fBufferSize; |
| Wayne Roberts |
0:6b3ac9c5a042 | 939 | int8_t datarate; |
| Wayne Roberts |
0:6b3ac9c5a042 | 940 | bool readyToSend = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 941 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 942 | if( mcpsRequest == NULL ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 943 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 944 | return LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 945 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 946 | if (flags.uplink_in_progress > 0) { |
| Wayne Roberts |
7:4b6f960dcca2 | 947 | MAC_PRINTF("LoRaMacMcpsRequest() in_progress BUSY%u\r\n", flags.uplink_in_progress); |
| Wayne Roberts |
5:4e9d41359897 | 948 | return waitingFor; |
| Wayne Roberts |
0:6b3ac9c5a042 | 949 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 950 | if (ConfFCntUp > 0) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 951 | // unacknowledged confirmed uplink pending, must resend previous uplink |
| Wayne Roberts |
0:6b3ac9c5a042 | 952 | MAC_PRINTF("LoRaMacMcpsRequest() ConfFCntUp%u\r\n", ConfFCntUp); |
| Wayne Roberts |
0:6b3ac9c5a042 | 953 | return LORAMAC_STATUS_BUSY_UPCONF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 954 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 955 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 956 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 957 | if (!flags.IsLoRaMacNetworkJoined) |
| Wayne Roberts |
0:6b3ac9c5a042 | 958 | return LORAMAC_STATUS_NO_NETWORK_JOINED; |
| Wayne Roberts |
0:6b3ac9c5a042 | 959 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 960 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 961 | macHdr.Value = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 962 | memset ( ( uint8_t* ) &McpsConfirm, 0, sizeof( McpsConfirm ) ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 963 | McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_MCPSREQ; |
| Wayne Roberts |
0:6b3ac9c5a042 | 964 | McpsConfirm.McpsRequest = mcpsRequest->Type; |
| Wayne Roberts |
0:6b3ac9c5a042 | 965 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 966 | datarate = mcpsRequest->Req.Datarate; |
| Wayne Roberts |
0:6b3ac9c5a042 | 967 | fBufferSize = mcpsRequest->Req.fBufferSize; |
| Wayne Roberts |
0:6b3ac9c5a042 | 968 | fBuffer = mcpsRequest->Req.fBuffer; |
| Wayne Roberts |
0:6b3ac9c5a042 | 969 | readyToSend = true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 970 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 971 | switch( mcpsRequest->Type ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 972 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 973 | case MCPS_UNCONFIRMED: |
| Wayne Roberts |
0:6b3ac9c5a042 | 974 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 975 | macHdr.Bits.MType = FRAME_TYPE_DATA_UNCONFIRMED_UP; |
| Wayne Roberts |
0:6b3ac9c5a042 | 976 | fPort = mcpsRequest->Req.fPort; |
| Wayne Roberts |
0:6b3ac9c5a042 | 977 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 978 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 979 | case MCPS_CONFIRMED: |
| Wayne Roberts |
0:6b3ac9c5a042 | 980 | { |
| Wayne Roberts |
3:eb174e10afbb | 981 | //AckTimeoutRetriesCounter = 1; |
| Wayne Roberts |
3:eb174e10afbb | 982 | //AckTimeoutRetries = mcpsRequest->Req.NbTrials; |
| Wayne Roberts |
0:6b3ac9c5a042 | 983 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 984 | macHdr.Bits.MType = FRAME_TYPE_DATA_CONFIRMED_UP; |
| Wayne Roberts |
0:6b3ac9c5a042 | 985 | fPort = mcpsRequest->Req.fPort; |
| Wayne Roberts |
0:6b3ac9c5a042 | 986 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 987 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 988 | case MCPS_PROPRIETARY: |
| Wayne Roberts |
0:6b3ac9c5a042 | 989 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 990 | macHdr.Bits.MType = FRAME_TYPE_PROPRIETARY; |
| Wayne Roberts |
0:6b3ac9c5a042 | 991 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 992 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 993 | default: |
| Wayne Roberts |
0:6b3ac9c5a042 | 994 | readyToSend = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 995 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 996 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 997 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 998 | if( readyToSend == true ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 999 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1000 | if( flags.AdrCtrlOn == false ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1001 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1002 | if( ValueInRange( datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == true ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1003 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1004 | LoRaMacParams.ChannelsDatarate = datarate; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1005 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1006 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1007 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1008 | return LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1009 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1010 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1011 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1012 | status = Send( &macHdr, fPort, fBuffer, fBufferSize ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1013 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1014 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1015 | return status; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1016 | } // ..LoRaMacMcpsRequest() |
| Wayne Roberts |
0:6b3ac9c5a042 | 1017 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1018 | __attribute__((weak)) LoRaMacStatus_t |
| Wayne Roberts |
0:6b3ac9c5a042 | 1019 | SwitchClassB( DeviceClass_t deviceClass ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1020 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1021 | return LORAMAC_STATUS_DEVICE_OFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1022 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1023 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1024 | void |
| Wayne Roberts |
0:6b3ac9c5a042 | 1025 | RxWindowSetup( unsigned freq, int8_t datarate, unsigned bandwidth, uint16_t timeout) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1026 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1027 | uint8_t downlinkDatarate = Datarates[datarate]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1028 | RadioModems_t modem; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1029 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1030 | MAC_PRINTF(" rxwin-dr%u-sf%u ", datarate, downlinkDatarate); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1031 | Radio::SetChannel( freq ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1032 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1033 | // Store downlink datarate |
| Wayne Roberts |
0:6b3ac9c5a042 | 1034 | McpsIndication.RxDatarate = ( uint8_t ) datarate; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1035 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1036 | #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868) || defined(USE_BAND_ARIB_8CH) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1037 | if( datarate == DR_7 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1038 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1039 | modem = MODEM_FSK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1040 | Radio::SetRxConfig( modem, 50e3, downlinkDatarate * 1e3, 0, 83.333e3, 5, 0, false, 0, true, false); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1041 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1042 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1043 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1044 | modem = MODEM_LORA; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1045 | Radio::SetRxConfig( modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, true); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1046 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1047 | #elif defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1048 | modem = MODEM_LORA; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1049 | Radio::SetRxConfig( modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, true); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1050 | #endif |
| Wayne Roberts |
0:6b3ac9c5a042 | 1051 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1052 | Radio::SetRxMaxPayloadLength( modem, MaxPayloadOfDatarate[datarate] + LORA_MAC_FRMPAYLOAD_OVERHEAD ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1053 | } //..RxWindowSetup() |
| Wayne Roberts |
0:6b3ac9c5a042 | 1054 | |
| Wayne Roberts |
7:4b6f960dcca2 | 1055 | LowPowerTimeout RxWindowEvent1; |
| Wayne Roberts |
7:4b6f960dcca2 | 1056 | LowPowerTimeout RxWindowEvent2; |
| Wayne Roberts |
7:4b6f960dcca2 | 1057 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1058 | static void RxWindow2Start( void ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1059 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1060 | /* TODO: join accept rx2 channel unique */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1061 | if (LoRaMacDeviceClass == CLASS_C) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1062 | Radio::Rx( 0 ); // Continuous mode |
| Wayne Roberts |
0:6b3ac9c5a042 | 1063 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1064 | Radio::Rx( LoRaMacParams.MaxRxWindow_us ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1065 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1066 | McpsIndication.RxSlot = 2; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1067 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1068 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1069 | static void mlme_confirm(LoRaMacEventInfoStatus_t status) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1070 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1071 | MlmeConfirm.Status = status; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1072 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1073 | if (MlmeConfirm.MlmeRequest != MLME_NONE) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1074 | if (LoRaMacPrimitives->MacMlmeConfirm != NULL) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1075 | LoRaMacPrimitives->MacMlmeConfirm( &MlmeConfirm ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1076 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1077 | MlmeConfirm.MlmeRequest = MLME_NONE; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1078 | MlmeIndication.MlmeIndication = MLME_NONE; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1079 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1080 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1081 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1082 | static void mcps_confirm(LoRaMacEventInfoStatus_t status) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1083 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1084 | McpsConfirm.Status = status; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1085 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1086 | if (McpsConfirm.McpsRequest != MCPS_NONE) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1087 | if (LoRaMacPrimitives->MacMcpsConfirm) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1088 | LoRaMacPrimitives->MacMcpsConfirm( &McpsConfirm ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1089 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1090 | McpsConfirm.McpsRequest = MCPS_NONE; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1091 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1092 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1093 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1094 | #if defined(LORAWAN_JOIN_EUI) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1095 | static struct { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1096 | bool forced; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1097 | uint8_t dr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1098 | uint8_t type; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1099 | uint8_t retries; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1100 | uint8_t Period; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1101 | LowPowerTimeout event; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1102 | struct { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1103 | uint8_t MaxTimeN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1104 | uint8_t MaxCountN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1105 | unsigned uplinks_since; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1106 | bool enabled; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1107 | } type0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1108 | } rejoin; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1109 | void _rejoin_retry(void); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1110 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1111 | void rejoin_retry() |
| Wayne Roberts |
0:6b3ac9c5a042 | 1112 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1113 | LoRaMacStatus_t status; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1114 | LoRaMacHeader_t macHdr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1115 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1116 | macHdr.Value = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1117 | macHdr.Bits.MType = FRAME_TYPE_REJOIN_REQ; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1118 | LoRaMacParams.ChannelsDatarate = rejoin.dr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1119 | JoinReqType = rejoin.type; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1120 | status = Send( &macHdr, 0, NULL, 0 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1121 | if (status != LORAMAC_STATUS_OK) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1122 | MAC_PRINTF("rejoin-send-failed%d ", status); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1123 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1124 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1125 | MAC_PRINTF("Rejoin%u ", JoinReqType); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1126 | if (rejoin.forced) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1127 | if (--rejoin.retries > 0) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1128 | us_timestamp_t period_us = (1 << rejoin.Period) + random_at_most(32000000); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1129 | rejoin.event.attach_us(_rejoin_retry, period_us); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1130 | MAC_PRINTF("try%u", rejoin.retries); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1131 | } else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1132 | rejoin.forced = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1133 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1134 | MAC_PRINTF("\r\n"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1135 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1136 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1137 | void _rejoin_retry() |
| Wayne Roberts |
0:6b3ac9c5a042 | 1138 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1139 | if (flags.uplink_in_progress > 0) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1140 | function_pending = rejoin_retry; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1141 | } else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1142 | rejoin_retry(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1143 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1144 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1145 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1146 | void |
| Wayne Roberts |
0:6b3ac9c5a042 | 1147 | finish_uplink(LoRaMacEventInfoStatus_t status) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1148 | { |
| Wayne Roberts |
3:eb174e10afbb | 1149 | if ((flags.uplink_in_progress > 0 && McpsIndication.RxSlot == 2) || status == LORAMAC_EVENT_INFO_STATUS_OK) { |
| Wayne Roberts |
7:4b6f960dcca2 | 1150 | if ((uplinkMHDR->Bits.MType == FRAME_TYPE_DATA_CONFIRMED_UP && status == LORAMAC_EVENT_INFO_STATUS_OK) || uplinkMHDR->Bits.MType != FRAME_TYPE_DATA_CONFIRMED_UP) { |
| Wayne Roberts |
3:eb174e10afbb | 1151 | flags.uplink_in_progress--; |
| Wayne Roberts |
7:4b6f960dcca2 | 1152 | } |
| Wayne Roberts |
3:eb174e10afbb | 1153 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1154 | if (flags.uplink_in_progress > 0) { |
| Wayne Roberts |
3:eb174e10afbb | 1155 | McpsIndication.Status = status; |
| Wayne Roberts |
3:eb174e10afbb | 1156 | if (LoRaMacPrimitives->MacMcpsIndication != NULL) |
| Wayne Roberts |
3:eb174e10afbb | 1157 | LoRaMacPrimitives->MacMcpsIndication( &McpsIndication ); |
| Wayne Roberts |
3:eb174e10afbb | 1158 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1159 | if (flags.rxing) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1160 | function_pending = region_ScheduleTx; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1161 | else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1162 | region_ScheduleTx( ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1163 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1164 | } else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1165 | region_session_start(status); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1166 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1167 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1168 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 1169 | LoRaMacHeader_t macHdr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1170 | macHdr.Value = Radio::radio.tx_buf[0]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1171 | if (macHdr.Bits.MType != FRAME_TYPE_REJOIN_REQ) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1172 | if (rejoin.type0.enabled && --rejoin.type0.uplinks_since == 0) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1173 | rejoin.type0.uplinks_since = 1 << (rejoin.type0.MaxCountN + 4); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1174 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1175 | rejoin.type = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1176 | rejoin_retry(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1177 | return; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1178 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1179 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1180 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1181 | |
| Wayne Roberts |
5:4e9d41359897 | 1182 | waitingFor = LORAMAC_STATUS_OK; |
| Wayne Roberts |
5:4e9d41359897 | 1183 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1184 | if (function_pending != NULL) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1185 | function_pending(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1186 | function_pending = NULL; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1187 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1188 | } // ..finish_uplink() |
| Wayne Roberts |
0:6b3ac9c5a042 | 1189 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1190 | LowPowerTimeout TxDelayedEvent; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1191 | |
| Wayne Roberts |
4:e4bfe9183f94 | 1192 | void OnTxDelayedIsr() |
| Wayne Roberts |
4:e4bfe9183f94 | 1193 | { |
| Wayne Roberts |
4:e4bfe9183f94 | 1194 | flags.OnTxDelayed = true; |
| Wayne Roberts |
4:e4bfe9183f94 | 1195 | } |
| Wayne Roberts |
4:e4bfe9183f94 | 1196 | |
| Wayne Roberts |
4:e4bfe9183f94 | 1197 | static void OnTxDelayedTimerEvent() |
| Wayne Roberts |
0:6b3ac9c5a042 | 1198 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1199 | MAC_PRINTF("OnTxDelayedTimerEvent() "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1200 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 1201 | LoRaMacHeader_t macHdr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1202 | LoRaMacFrameCtrl_t fCtrl; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1203 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1204 | if (!flags.IsLoRaMacNetworkJoined) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1205 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1206 | // Add a +1, since we start to count from 0 |
| Wayne Roberts |
3:eb174e10afbb | 1207 | LoRaMacParams.ChannelsDatarate = region_AlternateDatarate( MlmeIndication.JoinRequestTrials + 1 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1208 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1209 | macHdr.Value = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1210 | macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1211 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1212 | fCtrl.Value = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1213 | fCtrl.Bits.Adr = flags.AdrCtrlOn; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1214 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1215 | /* In case of join request retransmissions, the stack must prepare |
| Wayne Roberts |
0:6b3ac9c5a042 | 1216 | * the frame again, because the network server keeps track of the random |
| Wayne Roberts |
0:6b3ac9c5a042 | 1217 | * LoRaMacDevNonce values to prevent reply attacks. */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1218 | PrepareFrame( &macHdr, &fCtrl, 0, NULL, 0 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1219 | /* TODO PrepareFrame() != LORAMAC_STATUS_OK */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1220 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1221 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1222 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1223 | if (flags.rxing) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1224 | function_pending = region_ScheduleTx; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1225 | else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1226 | region_ScheduleTx( ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1227 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1228 | } // ..OnTxDelayedTimerEvent() |
| Wayne Roberts |
0:6b3ac9c5a042 | 1229 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1230 | static void RxWindow2Setup(void) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1231 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1232 | MAC_PRINTF("RxWindow2Setup %uhz dr%u", LoRaMacParams.Rx2Channel.FrequencyHz, LoRaMacParams.Rx2Channel.Datarate); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1233 | RxWindowSetup( |
| Wayne Roberts |
0:6b3ac9c5a042 | 1234 | LoRaMacParams.Rx2Channel.FrequencyHz, |
| Wayne Roberts |
0:6b3ac9c5a042 | 1235 | LoRaMacParams.Rx2Channel.Datarate, |
| Wayne Roberts |
0:6b3ac9c5a042 | 1236 | region_GetRxBandwidth( LoRaMacParams.Rx2Channel.Datarate ), |
| Wayne Roberts |
0:6b3ac9c5a042 | 1237 | region_GetRxSymbolTimeout( LoRaMacParams.Rx2Channel.Datarate ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1238 | ); |
| Wayne Roberts |
5:4e9d41359897 | 1239 | |
| Wayne Roberts |
5:4e9d41359897 | 1240 | waitingFor = LORAMAC_STATUS_WAITING_FOR_RX2; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1241 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1242 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1243 | static void |
| Wayne Roberts |
0:6b3ac9c5a042 | 1244 | PrepareRxDoneAbort(LoRaMacEventInfoStatus_t status) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1245 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1246 | MAC_PRINTF("rxAbort "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1247 | if( ( McpsIndication.RxSlot == 1 ) && ( LoRaMacDeviceClass == CLASS_C ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1248 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1249 | RxWindow2Setup(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1250 | RxWindow2Start(); // start continuous rx2 reception |
| Wayne Roberts |
0:6b3ac9c5a042 | 1251 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1252 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1253 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 1254 | if (!flags.IsLoRaMacNetworkJoined && LoRaMacJoinEui != NULL && LoRaMacDevEui == NULL) { |
| Wayne Roberts |
4:e4bfe9183f94 | 1255 | TxDelayedEvent.attach_us(OnTxDelayedIsr, 1000000); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1256 | MAC_PRINTF("RxDoneAbort-join-tx-delay"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1257 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1258 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1259 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1260 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1261 | McpsIndication.Status = status; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1262 | if (LoRaMacPrimitives->MacMcpsIndication != NULL) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1263 | LoRaMacPrimitives->MacMcpsIndication( &McpsIndication ); // RxAbort |
| Wayne Roberts |
0:6b3ac9c5a042 | 1264 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1265 | mcps_confirm(status); // RXAbort |
| Wayne Roberts |
0:6b3ac9c5a042 | 1266 | mlme_confirm(status); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1267 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1268 | finish_uplink(status); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1269 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1270 | MAC_PRINTF("\r\n"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1271 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1272 | } // ..PrepareRxDoneAbort() |
| Wayne Roberts |
0:6b3ac9c5a042 | 1273 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1274 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1275 | static LoRaMacStatus_t SwitchClass( DeviceClass_t deviceClass ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1276 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1277 | LoRaMacStatus_t status = LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1278 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1279 | switch( LoRaMacDeviceClass ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1280 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1281 | case CLASS_A: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1282 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1283 | MAC_PRINTF("CLASS_A "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1284 | if (deviceClass == CLASS_B) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1285 | status = SwitchClassB(deviceClass); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1286 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1287 | if (deviceClass == CLASS_C) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1288 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1289 | MAC_PRINTF("->C "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1290 | LoRaMacDeviceClass = deviceClass; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1291 | RxWindow2Setup(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1292 | RxWindow2Start(); // continuous rx2 reception |
| Wayne Roberts |
7:4b6f960dcca2 | 1293 | if (flags.OptNeg) { |
| Wayne Roberts |
7:4b6f960dcca2 | 1294 | AddMacCommand(MOTE_MAC_MODE_IND, LoRaMacDeviceClass, 0); |
| Wayne Roberts |
7:4b6f960dcca2 | 1295 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1296 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1297 | status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1298 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1299 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1300 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1301 | case CLASS_B: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1302 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1303 | MAC_PRINTF("CLASS_B "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1304 | if( deviceClass == CLASS_A ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1305 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1306 | MAC_PRINTF("->A "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1307 | LoRaMacDeviceClass = deviceClass; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1308 | status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1309 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1310 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1311 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1312 | case CLASS_C: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1313 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1314 | MAC_PRINTF("CLASS_C "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1315 | if( deviceClass == CLASS_A ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1316 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1317 | MAC_PRINTF("->A "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1318 | LoRaMacDeviceClass = deviceClass; |
| Wayne Roberts |
7:4b6f960dcca2 | 1319 | if (flags.OptNeg) { |
| Wayne Roberts |
7:4b6f960dcca2 | 1320 | AddMacCommand(MOTE_MAC_MODE_IND, LoRaMacDeviceClass, 0); |
| Wayne Roberts |
7:4b6f960dcca2 | 1321 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1322 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1323 | // Set the radio into sleep to setup a defined state |
| Wayne Roberts |
0:6b3ac9c5a042 | 1324 | Radio::Sleep( ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1325 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1326 | status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1327 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1328 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1329 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1330 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1331 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1332 | MAC_PRINTF("\r\n"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1333 | return status; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1334 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1335 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1336 | LoRaMacStatus_t |
| Wayne Roberts |
0:6b3ac9c5a042 | 1337 | LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1338 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1339 | LoRaMacStatus_t status = LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1340 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1341 | if (mibSet == NULL) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1342 | return LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1343 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1344 | if (flags.uplink_in_progress > 0) |
| Wayne Roberts |
5:4e9d41359897 | 1345 | return waitingFor; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1346 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1347 | switch (mibSet->Type) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1348 | case MIB_CHANNELS_MASK: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1349 | if( mibSet->Param.ChannelsMask ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1350 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1351 | #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1352 | bool chanMaskState = true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1353 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1354 | #if defined( USE_BAND_915_HYBRID ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1355 | chanMaskState = ValidateChannelMask( mibSet->Param.ChannelsMask ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1356 | #endif |
| Wayne Roberts |
0:6b3ac9c5a042 | 1357 | if( chanMaskState == true ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1358 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1359 | if( ( CountNbEnabled125kHzChannels( mibSet->Param.ChannelsMask ) < 2 ) && |
| Wayne Roberts |
0:6b3ac9c5a042 | 1360 | ( CountNbEnabled125kHzChannels( mibSet->Param.ChannelsMask ) > 0 ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1361 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1362 | status = LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1363 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1364 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1365 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1366 | memcpy( ( uint8_t* ) LoRaMacParams.ChannelsMask, |
| Wayne Roberts |
0:6b3ac9c5a042 | 1367 | ( uint8_t* ) mibSet->Param.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1368 | for ( uint8_t i = 0; i < sizeof( LoRaMacParams.ChannelsMask ) / 2; i++ ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1369 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1370 | // Disable channels which are no longer available |
| Wayne Roberts |
0:6b3ac9c5a042 | 1371 | ChannelsMaskRemaining[i] &= LoRaMacParams.ChannelsMask[i]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1372 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1373 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1374 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1375 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1376 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1377 | status = LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1378 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1379 | #elif defined( USE_BAND_470 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1380 | memcpy( ( uint8_t* ) LoRaMacParams.ChannelsMask, |
| Wayne Roberts |
0:6b3ac9c5a042 | 1381 | ( uint8_t* ) mibSet->Param.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1382 | #else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1383 | memcpy( ( uint8_t* ) LoRaMacParams.ChannelsMask, |
| Wayne Roberts |
0:6b3ac9c5a042 | 1384 | ( uint8_t* ) mibSet->Param.ChannelsMask, 2 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1385 | #endif |
| Wayne Roberts |
3:eb174e10afbb | 1386 | LoRaMacParams.NbEnabledChannels = region_CountNbEnabledChannels(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1387 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1388 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1389 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1390 | status = LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1391 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1392 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1393 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 1394 | /* values which cannot be set in OTA */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1395 | case MIB_NwkSKey: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1396 | case MIB_SNwkSIntKey: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1397 | case MIB_NwkSEncKey: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1398 | case MIB_FNwkSIntKey: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1399 | case MIB_APP_SKEY: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1400 | case MIB_DEV_ADDR: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1401 | case MIB_NETWORK_JOINED: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1402 | #endif |
| Wayne Roberts |
0:6b3ac9c5a042 | 1403 | case MIB_RX2_CHANNEL: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1404 | return LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1405 | case MIB_DEVICE_CLASS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1406 | status = SwitchClass(mibSet->Param.Class); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1407 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1408 | case MIB_ADR: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1409 | flags.AdrCtrlOn = mibSet->Param.AdrEnable; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1410 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1411 | case MIB_PUBLIC_NETWORK: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1412 | flags.PublicNetwork = mibSet->Param.EnablePublicNetwork; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1413 | Radio::SetPublicNetwork( flags.PublicNetwork ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1414 | break; |
| Wayne Roberts |
7:4b6f960dcca2 | 1415 | case MIB_MAX_LISTEN_TIME: |
| Wayne Roberts |
7:4b6f960dcca2 | 1416 | LoRaMacParams.MaxListenTime = mibSet->Param.MaxListenTime; |
| Wayne Roberts |
7:4b6f960dcca2 | 1417 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1418 | #ifndef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 1419 | case MIB_SNwkSIntKey: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1420 | flags.have_SNwkSIntKey = 1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1421 | memcpy( keys.SNwkSIntKey, mibSet->Param.key, sizeof(keys.SNwkSIntKey) ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1422 | if (flags.have_NwkSEncKey) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1423 | flags.OptNeg = 1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1424 | flags.need_ResetConf = 1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1425 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1426 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1427 | case MIB_NwkSEncKey: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1428 | flags.have_NwkSEncKey = 1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1429 | memcpy( keys.NwkSEncKey, mibSet->Param.key, sizeof(keys.NwkSEncKey) ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1430 | if (flags.have_SNwkSIntKey) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1431 | flags.OptNeg = 1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1432 | flags.need_ResetConf = 1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1433 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1434 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1435 | case MIB_APP_SKEY: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1436 | memcpy( keys.AppSKey, mibSet->Param.key, sizeof( keys.AppSKey ) ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1437 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1438 | case MIB_FNwkSIntKey: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1439 | memcpy( keys.FNwkSIntKey, mibSet->Param.key, sizeof( keys.FNwkSIntKey ) ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1440 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1441 | case MIB_NwkSKey: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1442 | /* lorawan 1.0 ABP */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1443 | memcpy( keys.FNwkSIntKey, mibSet->Param.key, sizeof( keys.FNwkSIntKey ) ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1444 | memcpy( keys.SNwkSIntKey, mibSet->Param.key, sizeof( keys.SNwkSIntKey) ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1445 | memcpy( keys.NwkSEncKey, mibSet->Param.key, sizeof( keys.NwkSEncKey) ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1446 | flags.OptNeg = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1447 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1448 | case MIB_DEV_ADDR: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1449 | LoRaMacDevAddr = mibSet->Param.DevAddr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1450 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1451 | #endif /* !LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1452 | } // ..switch( mibSet->Type ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1453 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1454 | return status; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1455 | } // ..LoRaMacMibSetRequestConfirm() |
| Wayne Roberts |
0:6b3ac9c5a042 | 1456 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1457 | __attribute__((weak)) LoRaMacStatus_t |
| Wayne Roberts |
0:6b3ac9c5a042 | 1458 | LoRaMacClassBInitialization( void ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1459 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1460 | return LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1461 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1462 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1463 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1464 | static void RxWindow1Start( void ) |
| dudmuck | 2:c9c736b3e4eb | 1465 | { |
| Wayne Roberts |
7:4b6f960dcca2 | 1466 | if (LoRaMacDeviceClass == CLASS_C) { |
| Wayne Roberts |
7:4b6f960dcca2 | 1467 | Radio::Standby(); |
| Wayne Roberts |
7:4b6f960dcca2 | 1468 | region_rx1_setup(Channel); |
| Wayne Roberts |
7:4b6f960dcca2 | 1469 | } |
| Wayne Roberts |
7:4b6f960dcca2 | 1470 | |
| Wayne Roberts |
7:4b6f960dcca2 | 1471 | Radio::Rx( LoRaMacParams.MaxRxWindow_us ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1472 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1473 | McpsIndication.RxSlot = 1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1474 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1475 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1476 | volatile us_timestamp_t tx_done_at; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1477 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1478 | static void OnRadioTxDone( us_timestamp_t at_us ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1479 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1480 | if ((RxWindow1Delay_us < 100000 || RxWindow1Delay_us > 10000000) || |
| Wayne Roberts |
0:6b3ac9c5a042 | 1481 | (RxWindow2Delay_us < 100000 || RxWindow2Delay_us > 10000000)) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1482 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1483 | PrepareRxDoneAbort(LORAMAC_EVENT_INFO_BAD_RX_DELAY); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1484 | return; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1485 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1486 | // Setup timers |
| Wayne Roberts |
0:6b3ac9c5a042 | 1487 | RxWindowEvent1.attach_us(RxWindow1Start, RxWindow1Delay_us); |
| Wayne Roberts |
7:4b6f960dcca2 | 1488 | waitingFor = LORAMAC_STATUS_WAITING_FOR_RX1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1489 | McpsIndication.RxSlot = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1490 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1491 | tx_done_at = at_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1492 | |
| Wayne Roberts |
7:4b6f960dcca2 | 1493 | if (LoRaMacDeviceClass != CLASS_C) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1494 | { |
| Wayne Roberts |
7:4b6f960dcca2 | 1495 | RxWindowEvent2.attach_us(RxWindow2Start, RxWindow2Delay_us); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1496 | region_rx1_setup(Channel); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1497 | Radio::Sleep( ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1498 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1499 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1500 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1501 | RxWindow2Setup(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1502 | RxWindow2Start(); |
| Wayne Roberts |
7:4b6f960dcca2 | 1503 | // simulate timeout to complete uplink |
| Wayne Roberts |
7:4b6f960dcca2 | 1504 | RxWindowEvent2.attach_us(OnRadioRxTimeout, RxWindow2Delay_us + 256000); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1505 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1506 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1507 | // Store last tx channel |
| Wayne Roberts |
0:6b3ac9c5a042 | 1508 | //LastTxChannel = Channel; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1509 | #ifdef DUTY_ENABLE |
| Wayne Roberts |
0:6b3ac9c5a042 | 1510 | DutyTxDone(at_us); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1511 | #endif /* DUTY_ENABLE */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1512 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1513 | } // ..OnRadioTxDone() |
| Wayne Roberts |
0:6b3ac9c5a042 | 1514 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1515 | static void OnRadioTxTimeout( void ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1516 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1517 | if( LoRaMacDeviceClass != CLASS_C ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1518 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1519 | Radio::Sleep( ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1520 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1521 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1522 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1523 | RxWindow2Setup(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1524 | RxWindow2Start(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1525 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1526 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1527 | finish_uplink(LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1528 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1529 | mcps_confirm(LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1530 | mlme_confirm(LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1531 | } // ..OnRadioTxTimeout() |
| Wayne Roberts |
0:6b3ac9c5a042 | 1532 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1533 | __attribute__((weak)) bool |
| Wayne Roberts |
0:6b3ac9c5a042 | 1534 | beacon_rx_done_payload(uint8_t* payload, uint16_t size) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1535 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1536 | return false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1537 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1538 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1539 | static void |
| Wayne Roberts |
0:6b3ac9c5a042 | 1540 | print_mtype(uint8_t mt) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1541 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1542 | #ifdef MAC_DEBUG |
| Wayne Roberts |
0:6b3ac9c5a042 | 1543 | const char* cp; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1544 | switch (mt) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1545 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 1546 | case FRAME_TYPE_JOIN_REQ: cp = "JOIN_REQ "; break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1547 | case FRAME_TYPE_JOIN_ACCEPT: cp = "JOIN_ACC "; break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1548 | case FRAME_TYPE_REJOIN_REQ: cp = "REJOIN_REQ"; break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1549 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1550 | case FRAME_TYPE_DATA_UNCONFIRMED_UP: cp = "UNCONF_UP"; break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1551 | case FRAME_TYPE_DATA_UNCONFIRMED_DOWN: cp = "UNCONF_DN"; break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1552 | case FRAME_TYPE_DATA_CONFIRMED_UP: cp = "CONF_UP"; break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1553 | case FRAME_TYPE_DATA_CONFIRMED_DOWN: cp = "CONF_DN"; break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1554 | case FRAME_TYPE_PROPRIETARY: cp = "P"; break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1555 | default: return; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1556 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1557 | MAC_PRINTF("MTYPE_%s ", cp); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1558 | #endif /* MAC_DEBUG */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1559 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1560 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1561 | /* bool a: true=AFCntDown, false=NFCntDown */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1562 | uint32_t get_fcntdwn(bool a) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1563 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1564 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 1565 | if (a) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1566 | return AFCntDown; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1567 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1568 | return NFCntDown; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1569 | #else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1570 | if (a) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1571 | return eeprom_read(EEPROM_AFCNTDWN); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1572 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1573 | return eeprom_read(EEPROM_NFCNTDWN); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1574 | #endif |
| Wayne Roberts |
0:6b3ac9c5a042 | 1575 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1576 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1577 | __attribute__((weak)) bool |
| Wayne Roberts |
0:6b3ac9c5a042 | 1578 | ProcessMacCommandsClassB(uint8_t* payload, uint8_t* macIndex) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1579 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1580 | return false; /* false: not taken */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1581 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1582 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1583 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1584 | static bool ValidateDatarate( int8_t datarate, uint16_t* channelsMask ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1585 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1586 | if( ValueInRange( datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == false ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1587 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1588 | return false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1589 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1590 | for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1591 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1592 | for( uint8_t j = 0; j < 16; j++ ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1593 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1594 | if( ( ( channelsMask[k] & ( 1 << j ) ) != 0 ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1595 | {// Check datarate validity for enabled channels |
| Wayne Roberts |
0:6b3ac9c5a042 | 1596 | if( ValueInRange( datarate, Channels[i + j].DrRange.Fields.Min, Channels[i + j].DrRange.Fields.Max ) == true ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1597 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1598 | // At least 1 channel has been found we can return OK. |
| Wayne Roberts |
0:6b3ac9c5a042 | 1599 | return true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1600 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1601 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1602 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1603 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1604 | return false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1605 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1606 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1607 | static bool Rx2FreqInRange( uint32_t freq ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1608 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1609 | #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) || defined (USE_BAND_ARIB_8CH) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1610 | if( Radio::CheckRfFrequency( freq ) == true ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1611 | #elif defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1612 | if( ( Radio::CheckRfFrequency( freq ) == true ) && |
| Wayne Roberts |
0:6b3ac9c5a042 | 1613 | ( freq >= LORAMAC_FIRST_RX1_CHANNEL ) && |
| Wayne Roberts |
0:6b3ac9c5a042 | 1614 | ( freq <= LORAMAC_LAST_RX1_CHANNEL ) && |
| Wayne Roberts |
0:6b3ac9c5a042 | 1615 | ( ( ( freq - ( uint32_t ) LORAMAC_FIRST_RX1_CHANNEL ) % ( uint32_t ) LORAMAC_STEPWIDTH_RX1_CHANNEL ) == 0 ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1616 | #endif |
| Wayne Roberts |
0:6b3ac9c5a042 | 1617 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1618 | return true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1619 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1620 | return false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1621 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1622 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1623 | __attribute__((weak)) void |
| Wayne Roberts |
0:6b3ac9c5a042 | 1624 | deviceTimeClassB(uint32_t secs, uint32_t subsecs) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1625 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1626 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1627 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1628 | /* return -1 for unknown mac cmd */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1629 | static int |
| Wayne Roberts |
0:6b3ac9c5a042 | 1630 | ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr, us_timestamp_t us_rxDone_at ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1631 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1632 | uint8_t buf[2]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1633 | int ret = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1634 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1635 | MACC_PRINTF("ProcessMacCommands(, %u, %u,,) ", macIndex, commandsSize); |
| Wayne Roberts |
3:eb174e10afbb | 1636 | while (macIndex < commandsSize) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1637 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1638 | MACC_PRINTF("ProcessMacCommands %u(0x%02x): ", macIndex, payload[macIndex]); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1639 | // Decode Frame MAC commands |
| Wayne Roberts |
3:eb174e10afbb | 1640 | switch (payload[macIndex++]) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1641 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1642 | case SRV_MAC_LINK_CHECK_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1643 | MACC_PRINTF("LINK_CHECK_ANS "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1644 | buf[0] = payload[macIndex++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1645 | buf[1] = payload[macIndex++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1646 | MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1647 | MlmeConfirm.fields.link.DemodMargin = buf[0]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1648 | MlmeConfirm.fields.link.NbGateways = buf[1]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1649 | break; |
| Wayne Roberts |
7:4b6f960dcca2 | 1650 | case SRV_MAC_MODE_CONF: |
| Wayne Roberts |
7:4b6f960dcca2 | 1651 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1652 | case SRV_MAC_LINK_ADR_REQ: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1653 | MACC_PRINTF("LINK_ADR_REQ "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1654 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1655 | uint8_t i; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1656 | int8_t txPower = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1657 | uint8_t Redundancy = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1658 | adr_t adr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1659 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1660 | adr.status = 0x07; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1661 | // Initialize local copy of the channels mask array |
| Wayne Roberts |
0:6b3ac9c5a042 | 1662 | for( i = 0; i < 6; i++ ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1663 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1664 | adr.channelsMask[i] = LoRaMacParams.ChannelsMask[i]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1665 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1666 | adr.datarate = payload[macIndex++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1667 | txPower = adr.datarate & 0x0F; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1668 | adr.datarate = ( adr.datarate >> 4 ) & 0x0F; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1669 | MACC_PRINTF("dr%u power%u ", adr.datarate, txPower); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1670 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1671 | if( ( flags.AdrCtrlOn == false ) && |
| Wayne Roberts |
0:6b3ac9c5a042 | 1672 | ( ( LoRaMacParams.ChannelsDatarate != adr.datarate ) || ( LoRaMacParams.ChannelsTxPower != txPower ) ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1673 | { // ADR disabled don't handle ADR requests if server tries to change datarate or txpower |
| Wayne Roberts |
0:6b3ac9c5a042 | 1674 | MACC_PRINTF("AdrCtrlOn:%u dr%u != dr%u, %d != %d\r\n", flags.AdrCtrlOn, |
| Wayne Roberts |
0:6b3ac9c5a042 | 1675 | LoRaMacParams.ChannelsDatarate, adr.datarate, |
| Wayne Roberts |
0:6b3ac9c5a042 | 1676 | LoRaMacParams.ChannelsTxPower, txPower |
| Wayne Roberts |
0:6b3ac9c5a042 | 1677 | ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1678 | // Answer the server with fail status |
| Wayne Roberts |
0:6b3ac9c5a042 | 1679 | // Power ACK = 0 |
| Wayne Roberts |
0:6b3ac9c5a042 | 1680 | // Data rate ACK = 0 |
| Wayne Roberts |
0:6b3ac9c5a042 | 1681 | // Channel mask = 0 |
| Wayne Roberts |
0:6b3ac9c5a042 | 1682 | AddMacCommand( MOTE_MAC_LINK_ADR_ANS, 0, 0 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1683 | macIndex += 3; // Skip over the remaining bytes of the request |
| Wayne Roberts |
0:6b3ac9c5a042 | 1684 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1685 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1686 | adr.chMask = ( uint16_t )payload[macIndex++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1687 | adr.chMask |= ( uint16_t )payload[macIndex++] << 8; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1688 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1689 | Redundancy = payload[macIndex++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1690 | adr.chMaskCntl = ( Redundancy >> 4 ) & 0x07; |
| Wayne Roberts |
3:eb174e10afbb | 1691 | if ((Redundancy & 0x0f) > 0) |
| Wayne Roberts |
3:eb174e10afbb | 1692 | LoRaMacParams.NbTrans = Redundancy & 0x0f; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1693 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1694 | MACC_PRINTF("chMask:%04x chMaskCntl:%x nbTrans:%u ", adr.chMask, adr.chMaskCntl, LoRaMacParams.NbTrans); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1695 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1696 | region_adr_request(&adr); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1697 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1698 | if( ValidateDatarate( adr.datarate, adr.channelsMask ) == false ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1699 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1700 | MACC_PRINTF("badDr "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1701 | adr.status &= 0xFD; // Datarate KO |
| Wayne Roberts |
0:6b3ac9c5a042 | 1702 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1703 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1704 | // |
| Wayne Roberts |
0:6b3ac9c5a042 | 1705 | // Remark MaxTxPower = 0 and MinTxPower = 5 |
| Wayne Roberts |
0:6b3ac9c5a042 | 1706 | // |
| Wayne Roberts |
0:6b3ac9c5a042 | 1707 | if( ValueInRange( txPower, LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) == false ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1708 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1709 | MACC_PRINTF("badPower(max:%d given:%d min:%d) ", LORAMAC_MAX_TX_POWER, txPower, LORAMAC_MIN_TX_POWER); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1710 | adr.status &= 0xFB; // TxPower KO |
| Wayne Roberts |
0:6b3ac9c5a042 | 1711 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1712 | MACC_PRINTF("status:%x (idx %u) ", adr.status, macIndex); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1713 | if( ( adr.status & 0x07 ) == 0x07 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1714 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1715 | LoRaMacParams.ChannelsDatarate = adr.datarate; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1716 | LoRaMacParams.ChannelsTxPower = txPower; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1717 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1718 | memcpy( ( uint8_t* )LoRaMacParams.ChannelsMask, ( uint8_t* )adr.channelsMask, sizeof( LoRaMacParams.ChannelsMask ) ); |
| Wayne Roberts |
3:eb174e10afbb | 1719 | LoRaMacParams.NbEnabledChannels = region_CountNbEnabledChannels(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1720 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1721 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1722 | AddMacCommand( MOTE_MAC_LINK_ADR_ANS, adr.status, 0 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1723 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1724 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1725 | case SRV_MAC_RX_PARAM_SETUP_REQ: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1726 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1727 | uint8_t status = 0x07; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1728 | int8_t datarate = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1729 | int8_t drOffset = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1730 | uint32_t freq = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1731 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1732 | drOffset = ( payload[macIndex] >> 4 ) & 0x07; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1733 | datarate = payload[macIndex] & 0x0F; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1734 | macIndex++; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1735 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1736 | freq = ( uint32_t )payload[macIndex++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1737 | freq |= ( uint32_t )payload[macIndex++] << 8; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1738 | freq |= ( uint32_t )payload[macIndex++] << 16; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1739 | freq *= 100; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1740 | MACC_PRINTF("RX_PARAM_SETUP_REQ %uhz drOffset:%u dr%u ", freq, drOffset, datarate); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1741 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1742 | if( Rx2FreqInRange( freq ) == false ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1743 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1744 | status &= 0xFE; // Channel frequency KO |
| Wayne Roberts |
0:6b3ac9c5a042 | 1745 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1746 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1747 | if( ValueInRange( datarate, LORAMAC_RX_MIN_DATARATE, LORAMAC_RX_MAX_DATARATE ) == false ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1748 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1749 | status &= 0xFD; // Datarate KO |
| Wayne Roberts |
0:6b3ac9c5a042 | 1750 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1751 | #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1752 | if( ( ValueInRange( datarate, DR_5, DR_7 ) == true ) || |
| Wayne Roberts |
0:6b3ac9c5a042 | 1753 | ( datarate > DR_13 ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1754 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1755 | status &= 0xFD; // Datarate KO |
| Wayne Roberts |
0:6b3ac9c5a042 | 1756 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1757 | #endif |
| Wayne Roberts |
0:6b3ac9c5a042 | 1758 | if( ValueInRange( drOffset, LORAMAC_MIN_RX1_DR_OFFSET, LORAMAC_MAX_RX1_DR_OFFSET ) == false ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1759 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1760 | status &= 0xFB; // Rx1DrOffset range KO |
| Wayne Roberts |
0:6b3ac9c5a042 | 1761 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1762 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1763 | MACC_PRINTF("status:0x%02x ", status); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1764 | if( ( status & 0x07 ) == 0x07 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1765 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1766 | LoRaMacParams.Rx2Channel.Datarate = datarate; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1767 | LoRaMacParams.Rx2Channel.FrequencyHz = freq; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1768 | LoRaMacParams.Rx1DrOffset = drOffset; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1769 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1770 | AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS, status, 0 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1771 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1772 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1773 | case SRV_MAC_DEV_STATUS_REQ: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1774 | MACC_PRINTF("DEV_STATUS_REQ "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1775 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1776 | uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1777 | if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->GetBatteryLevel != NULL ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1778 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1779 | batteryLevel = LoRaMacCallbacks->GetBatteryLevel( ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1780 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1781 | AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, batteryLevel, snr ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1782 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1783 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1784 | case SRV_MAC_NEW_CHANNEL_REQ: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1785 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1786 | uint8_t status = 0x03; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1787 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1788 | #if defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1789 | status &= 0xFC; // Channel frequency and datarate KO |
| Wayne Roberts |
0:6b3ac9c5a042 | 1790 | macIndex += 5; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1791 | #else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1792 | int8_t channelIndex = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1793 | ChannelParams_t chParam; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1794 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1795 | channelIndex = payload[macIndex++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1796 | chParam.FreqHz = ( uint32_t )payload[macIndex++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1797 | chParam.FreqHz |= ( uint32_t )payload[macIndex++] << 8; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1798 | chParam.FreqHz |= ( uint32_t )payload[macIndex++] << 16; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1799 | chParam.FreqHz *= 100; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1800 | chParam.DrRange.Value = payload[macIndex++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1801 | MACC_PRINTF("NEW_CHANNEL_REQ ch%u %uhz drRange:%02x ", channelIndex, chParam.Frequency, chParam.DrRange.Value); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1802 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1803 | if( chParam.FreqHz == 0 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1804 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1805 | if( channelIndex < 3 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1806 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1807 | status &= 0xFC; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1808 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1809 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1810 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1811 | if( LoRaMacChannelRemove( channelIndex ) != LORAMAC_STATUS_OK ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1812 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1813 | status &= 0xFC; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1814 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1815 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1816 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1817 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1818 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1819 | switch( LoRaMacChannelAdd( channelIndex, chParam ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1820 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1821 | case LORAMAC_STATUS_OK: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1822 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1823 | MACC_PRINTF("add-ok "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1824 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1825 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1826 | case LORAMAC_STATUS_FREQUENCY_INVALID: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1827 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1828 | MACC_PRINTF("add-bad-freq "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1829 | status &= 0xFE; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1830 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1831 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1832 | case LORAMAC_STATUS_DATARATE_INVALID: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1833 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1834 | MACC_PRINTF("add-bad-dr "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1835 | status &= 0xFD; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1836 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1837 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1838 | case LORAMAC_STATUS_FREQ_AND_DR_INVALID: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1839 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1840 | MACC_PRINTF("add-bad-both "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1841 | status &= 0xFC; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1842 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1843 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1844 | default: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1845 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1846 | MACC_PRINTF("add-bad-? "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1847 | status &= 0xFC; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1848 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1849 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1850 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1851 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1852 | #endif |
| Wayne Roberts |
0:6b3ac9c5a042 | 1853 | MACC_PRINTF("status:%x ", status); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1854 | AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS, status, 0 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1855 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1856 | break; |
| Wayne Roberts |
3:eb174e10afbb | 1857 | case SRV_MAC_ADR_PARAM_SETUP_REQ: |
| Wayne Roberts |
3:eb174e10afbb | 1858 | MACC_PRINTF("ADR_PARAM_SETUP_REQ"); |
| Wayne Roberts |
3:eb174e10afbb | 1859 | { |
| Wayne Roberts |
3:eb174e10afbb | 1860 | uint8_t exps = payload[macIndex++] & 0x0F; |
| Wayne Roberts |
3:eb174e10afbb | 1861 | ADR_ACK_LIMIT = 1 << (exps >> 4); |
| Wayne Roberts |
3:eb174e10afbb | 1862 | ADR_ACK_DELAY = 1 << (exps & 0x0f); |
| Wayne Roberts |
3:eb174e10afbb | 1863 | } |
| Wayne Roberts |
3:eb174e10afbb | 1864 | AddMacCommand(SRV_MAC_ADR_PARAM_SETUP_ANS, 0, 0); |
| Wayne Roberts |
3:eb174e10afbb | 1865 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1866 | case SRV_MAC_RX_TIMING_SETUP_REQ: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1867 | MACC_PRINTF("RX_TIMING_SETUP_REQ"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1868 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1869 | uint8_t delay = payload[macIndex++] & 0x0F; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1870 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1871 | if( delay == 0 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1872 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1873 | delay++; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1874 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1875 | LoRaMacParams.ReceiveDelay1_us = delay * 1e6; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1876 | LoRaMacParams.ReceiveDelay2_us = LoRaMacParams.ReceiveDelay1_us + 1e6; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1877 | AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1878 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1879 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1880 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 1881 | case SRV_MAC_REKEY_CONF: |
| Wayne Roberts |
3:eb174e10afbb | 1882 | macIndex++; //TODO server_version = payload[macIndex++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1883 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1884 | flags.need_ReKeyConf = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1885 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1886 | case SRV_MAC_FORCE_REJOIN_REQ: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1887 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1888 | uint16_t cmd_payload = payload[macIndex++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1889 | cmd_payload |= payload[macIndex++] << 8; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1890 | rejoin.type = (cmd_payload >> 4) & 7; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1891 | if (rejoin.type == 2) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1892 | JoinReqType = 2; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1893 | else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1894 | JoinReqType = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1895 | rejoin.type = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1896 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1897 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1898 | rejoin.dr = cmd_payload & 0x0f; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1899 | LoRaMacParams.ChannelsDatarate = rejoin.dr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1900 | rejoin.retries = 1 + ((cmd_payload >> 8) & 7); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1901 | MAC_PRINTF("FORCE_REJOIN 0x%04x dr%u type%u tries%u ", cmd_payload, LoRaMacParams.ChannelsDatarate, JoinReqType, rejoin.retries); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1902 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1903 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1904 | rejoin.Period = (cmd_payload >> 11) & 7; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1905 | /* first forced-rejoin attempt must be immediate */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1906 | rejoin.event.attach_us(_rejoin_retry, 50000); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1907 | rejoin.forced = true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1908 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1909 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1910 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1911 | case SRV_MAC_REJOIN_PARAM_REQ: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1912 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1913 | uint8_t p = payload[macIndex++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1914 | rejoin.type0.MaxTimeN = p >> 4; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1915 | rejoin.type0.MaxCountN = p & 0xf; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1916 | rejoin.type0.enabled = true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1917 | MACC_PRINTF("REJOIN_PARAM MaxTimeN%u MaxCountN%u ", rejoin.type0.MaxTimeN, rejoin.type0.MaxCountN); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1918 | rejoin.type0.uplinks_since = 1 << (rejoin.type0.MaxCountN + 4); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1919 | AddMacCommand(MOTE_MAC_REJOIN_PARAM_ANS, 0, 0); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1920 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1921 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1922 | #else |
| Wayne Roberts |
0:6b3ac9c5a042 | 1923 | case SRV_MAC_RESET_CONF: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1924 | macIndex++; //TODO server_version = payload[macIndex++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1925 | flags.need_ResetConf = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1926 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1927 | #endif /* !LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1928 | case SRV_MAC_DEVICE_TIME_ANS: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1929 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1930 | uint32_t subusecs, secs; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1931 | us_timestamp_t us_since_tx_done; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1932 | secs = payload[macIndex++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1933 | secs += payload[macIndex++] << 8; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1934 | secs += payload[macIndex++] << 16; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1935 | secs += payload[macIndex++] << 24; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1936 | subusecs = payload[macIndex++] * 3906.5; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1937 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1938 | //MAC_PRINTF("secs:%u, subusecs:%u\r\n", secs, subusecs); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1939 | deviceTimeClassB(secs, subusecs); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1940 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1941 | us_since_tx_done = Radio::lpt.read_us() - tx_done_at; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1942 | MlmeConfirm.fields.time.uSeconds += us_since_tx_done; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1943 | while (us_since_tx_done >= 1000000) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1944 | MlmeConfirm.fields.time.Seconds++; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1945 | us_since_tx_done -= 1000000; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1946 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1947 | MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1948 | MlmeConfirm.fields.time.Seconds = secs; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1949 | MlmeConfirm.fields.time.uSeconds = subusecs; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1950 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1951 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1952 | default: |
| Wayne Roberts |
0:6b3ac9c5a042 | 1953 | --macIndex; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1954 | if (ProcessMacCommandsClassB(payload, &macIndex)) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1955 | /* mac command was taken */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1956 | //MACC_PRINTF("B-cont\r\n"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1957 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1958 | #ifdef DUTY_ENABLE |
| Wayne Roberts |
0:6b3ac9c5a042 | 1959 | else if (ProcessMacCommandsDuty(payload, &macIndex)) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1960 | /* mac command was taken */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1961 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1962 | #endif /* DUTY_ENABLE */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1963 | else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1964 | ret = -1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1965 | MAC_PRINTF("[31munknown mac:0x%02x at %u[0m\r\n", payload[macIndex-1], macIndex-1); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1966 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 1967 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1968 | } // ..switch(payload[macIndex++]) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1969 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1970 | MACC_PRINTF("\r\n"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1971 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1972 | } // ..while( macIndex < commandsSize ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1973 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1974 | return ret; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1975 | } // ..ProcessMacCommands() |
| Wayne Roberts |
0:6b3ac9c5a042 | 1976 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1977 | #define MAX_FCNT_GAP 0x4000 |
| Wayne Roberts |
0:6b3ac9c5a042 | 1978 | /* return: true == send downlink ack */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 1979 | static int |
| Wayne Roberts |
0:6b3ac9c5a042 | 1980 | rx_downlink(uint8_t pktHeaderLen, uint8_t* rx_payload, uint16_t rx_size, int8_t snr, us_timestamp_t us_rxDone_at) |
| Wayne Roberts |
0:6b3ac9c5a042 | 1981 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 1982 | LoRaMacHeader_t macHdr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1983 | LoRaMacFrameCtrl_t fCtrl; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1984 | uint32_t myFCntDwn32, rxFCnt32; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1985 | uint8_t rxFPort; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1986 | uint16_t rxFCnt16; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1987 | uint32_t address; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1988 | uint32_t mic, micRx; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1989 | uint8_t appPayloadStartIndex = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1990 | bool skipIndication = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1991 | uint8_t frameLen = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1992 | bool is_AFCntDown; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1993 | block_t block; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1994 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1995 | macHdr.Value = rx_payload[0]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1996 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 1997 | address = rx_payload[pktHeaderLen++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 1998 | address |= ( (uint32_t)rx_payload[pktHeaderLen++] << 8 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 1999 | address |= ( (uint32_t)rx_payload[pktHeaderLen++] << 16 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2000 | address |= ( (uint32_t)rx_payload[pktHeaderLen++] << 24 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2001 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2002 | fCtrl.Value = rx_payload[pktHeaderLen++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2003 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2004 | rxFCnt16 = ( uint16_t )rx_payload[pktHeaderLen++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2005 | rxFCnt16 |= ( uint16_t )rx_payload[pktHeaderLen++] << 8; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2006 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2007 | is_AFCntDown = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2008 | if (( ( rx_size - 4 ) - (8 + fCtrl.Bits.FOptsLen) ) > 0) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2009 | appPayloadStartIndex = 8 + fCtrl.Bits.FOptsLen; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2010 | rxFPort = rx_payload[appPayloadStartIndex++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2011 | if (flags.OptNeg && rxFPort > 0) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2012 | is_AFCntDown = true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2013 | } /* else no payload/fport present */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2014 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2015 | myFCntDwn32 = get_fcntdwn(is_AFCntDown); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2016 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2017 | McpsIndication.expectedFCntDown = myFCntDwn32; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2018 | McpsIndication.receivedFCntDown = rxFCnt16; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2019 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2020 | rxFCnt32 = (myFCntDwn32 & 0xffff0000) | rxFCnt16; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2021 | DEBUG_MIC_DOWN(" rxFCnt32:%" PRIu32" ", rxFCnt32); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2022 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2023 | micRx = ( uint32_t )rx_payload[rx_size - LORAMAC_MFR_LEN]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2024 | micRx |= ( ( uint32_t )rx_payload[rx_size - LORAMAC_MFR_LEN + 1] << 8 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2025 | micRx |= ( ( uint32_t )rx_payload[rx_size - LORAMAC_MFR_LEN + 2] << 16 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2026 | micRx |= ( ( uint32_t )rx_payload[rx_size - LORAMAC_MFR_LEN + 3] << 24 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2027 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2028 | block.b.header = 0x49; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2029 | if (flags.OptNeg) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2030 | block.b.confFCnt = ConfFCntUp; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2031 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 2032 | block.b.confFCnt = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2033 | block.b.dr = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2034 | block.b.ch = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2035 | block.b.dir = DOWN_LINK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2036 | block.b.DevAddr = address; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2037 | block.b.FCnt = rxFCnt32; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2038 | block.b.zero8 = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2039 | block.b.lenMsg = rx_size - LORAMAC_MFR_LEN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2040 | mic = LoRaMacComputeMic(&block, rx_payload, keys.SNwkSIntKey); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2041 | if (micRx != mic) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2042 | bool ignore_rx = true; |
| Wayne Roberts |
3:eb174e10afbb | 2043 | PrepareRxDoneAbort(LORAMAC_EVENT_INFO_STATUS_MIC_FAIL); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2044 | MAC_PRINTF("\e[31mmicFail"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2045 | if (flags.OptNeg) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2046 | block.b.confFCnt = ConfFCntUp - 1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2047 | mic = LoRaMacComputeMic(&block, rx_payload, keys.SNwkSIntKey); |
| Wayne Roberts |
3:eb174e10afbb | 2048 | if (micRx == mic) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2049 | ignore_rx = false; |
| Wayne Roberts |
3:eb174e10afbb | 2050 | else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2051 | block.b.confFCnt = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2052 | mic = LoRaMacComputeMic(&block, rx_payload, keys.SNwkSIntKey); |
| Wayne Roberts |
3:eb174e10afbb | 2053 | if (micRx == mic) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2054 | ignore_rx = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2055 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2056 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2057 | if (ignore_rx) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2058 | MAC_PRINTF("\e[0m\r\n"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2059 | return -1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2060 | } else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2061 | McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2062 | if (LoRaMacPrimitives->MacMcpsIndication != NULL) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2063 | LoRaMacPrimitives->MacMcpsIndication( &McpsIndication ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2064 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2065 | } else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2066 | /* downlink with good MIC means previous confirmed uplink was receied */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2067 | ConfFCntUp = 0; |
| Wayne Roberts |
7:4b6f960dcca2 | 2068 | if (McpsIndication.RxSlot == 1) { // no need for RX2 with good mic on rx1 |
| Wayne Roberts |
0:6b3ac9c5a042 | 2069 | RxWindowEvent2.detach(); |
| Wayne Roberts |
7:4b6f960dcca2 | 2070 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2071 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2072 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2073 | McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2074 | //McpsIndication.Multicast = 0;//multicast; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2075 | McpsIndication.FramePending = fCtrl.Bits.FPending; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2076 | McpsIndication.Buffer = NULL; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2077 | McpsIndication.BufferSize = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2078 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2079 | MacCommandsBufferToRepeatIndex = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2080 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2081 | if (macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2082 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2083 | flags.SrvAckRequested = true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2084 | McpsIndication.McpsIndication = MCPS_CONFIRMED; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2085 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2086 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 2087 | if (flags.IsLoRaMacNetworkJoined) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2088 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2089 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2090 | if (flags.OptNeg) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2091 | ConfFCntDown = rxFCnt16; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2092 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2093 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 2094 | { // FRAME_TYPE_DATA_UNCONFIRMED_DOWN: |
| Wayne Roberts |
0:6b3ac9c5a042 | 2095 | ConfFCntDown = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2096 | flags.SrvAckRequested = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2097 | McpsIndication.McpsIndication = MCPS_UNCONFIRMED; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2098 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2099 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2100 | if (fCtrl.Bits.FOptsLen > 0) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2101 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2102 | // Decode Options field MAC commands |
| Wayne Roberts |
0:6b3ac9c5a042 | 2103 | if (flags.OptNeg) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2104 | uint32_t FCnt32; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2105 | bool fromStored; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2106 | uint8_t macDecrypt[16]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2107 | DEBUG_CRYPT_BUF(keys.NwkSEncKey, 16, "NwkSEncKey", 0); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2108 | if (appPayloadStartIndex > 0) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2109 | /* rx header has AFCntDown: not for use with FOpts */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2110 | FCnt32 = get_fcntdwn(false); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2111 | fromStored = true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2112 | } else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2113 | /* NFCntDown received in rx header */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2114 | FCnt32 = (get_fcntdwn(false) & 0xffff0000) | rxFCnt16; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2115 | fromStored = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2116 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2117 | DEBUG_CRYPT("FCnt32:%" PRIu32" ", FCnt32); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2118 | DEBUG_CRYPT_BUF(rx_payload+8, fCtrl.Bits.FOptsLen, "FOpts-rx", 0); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2119 | LoRaMacEncrypt(0, rx_payload+8, fCtrl.Bits.FOptsLen, keys.NwkSEncKey, LoRaMacDevAddr, DOWN_LINK, FCnt32, macDecrypt); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2120 | DEBUG_CRYPT_BUF(macDecrypt, fCtrl.Bits.FOptsLen, "FOpts-decrypt", 0); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2121 | if (ProcessMacCommands(macDecrypt, 0, fCtrl.Bits.FOptsLen, snr, us_rxDone_at) < 0) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2122 | if (fromStored) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2123 | MAC_PRINTF("fromStored-"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2124 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2125 | MAC_PRINTF("FCnt32:%lu ", FCnt32); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2126 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2127 | } else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2128 | MAC_PRINTF("ProcessMacCommands-FOpts "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2129 | ProcessMacCommands( rx_payload, 8, fCtrl.Bits.FOptsLen + 8, snr, us_rxDone_at ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2130 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2131 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2132 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2133 | if (appPayloadStartIndex > 0) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2134 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2135 | frameLen = ( rx_size - 4 ) - appPayloadStartIndex; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2136 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2137 | McpsIndication.Port = rxFPort; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2138 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2139 | if (rxFPort == 0) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2140 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2141 | if( ( fCtrl.Bits.FOptsLen == 0 ) /*&& ( multicast == 0 )*/ ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2142 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2143 | uint8_t macDecrypt[16]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2144 | LoRaMacPayloadDecrypt(rx_payload + appPayloadStartIndex, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2145 | frameLen, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2146 | keys.NwkSEncKey, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2147 | address, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2148 | DOWN_LINK, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2149 | rxFCnt32, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2150 | macDecrypt |
| Wayne Roberts |
0:6b3ac9c5a042 | 2151 | ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2152 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2153 | // Decode frame payload MAC commands |
| Wayne Roberts |
0:6b3ac9c5a042 | 2154 | MAC_PRINTF("ProcessMacCommands-payload "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2155 | if (ProcessMacCommands( macDecrypt, 0, frameLen, snr, us_rxDone_at ) < 0) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2156 | MAC_PRINTF(" rxFCnt32:%" PRIu32 " ", rxFCnt32); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2157 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2158 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2159 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 2160 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2161 | skipIndication = true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2162 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2163 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2164 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 2165 | { /* rxFPort > 0 */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2166 | MAC_PRINTF("rxFCnt32:%" PRIu32" %08" PRIx32" ", rxFCnt32, address); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2167 | MAC_PRINTF("FCntDown%" PRIu32 " ", rxFCnt32); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2168 | DEBUG_CRYPT(" addr%" PRIx32" len%u\r\n", address, frameLen); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2169 | DEBUG_CRYPT_BUF(rx_payload + appPayloadStartIndex, frameLen, "rxEncd", 0); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2170 | DEBUG_CRYPT_BUF(keys.AppSKey, 16, "AppSKey", 0); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2171 | LoRaMacPayloadDecrypt(rx_payload + appPayloadStartIndex, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2172 | frameLen, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2173 | keys.AppSKey, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2174 | address, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2175 | DOWN_LINK, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2176 | rxFCnt32, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2177 | rxFRMPayload |
| Wayne Roberts |
0:6b3ac9c5a042 | 2178 | ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2179 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2180 | if( skipIndication == false ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2181 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2182 | McpsIndication.Buffer = rxFRMPayload; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2183 | McpsIndication.BufferSize = frameLen; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2184 | McpsIndication.RxData = true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2185 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2186 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2187 | } // ..if have payload |
| Wayne Roberts |
0:6b3ac9c5a042 | 2188 | |
| Wayne Roberts |
3:eb174e10afbb | 2189 | if (!skipIndication) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2190 | { |
| Wayne Roberts |
3:eb174e10afbb | 2191 | McpsIndication.AckReceived = fCtrl.Bits.Ack; |
| Wayne Roberts |
3:eb174e10afbb | 2192 | McpsConfirm.AckReceived = fCtrl.Bits.Ack; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2193 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2194 | if (LoRaMacPrimitives->MacMcpsIndication != NULL) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2195 | LoRaMacPrimitives->MacMcpsIndication( &McpsIndication ); // RxDone |
| Wayne Roberts |
0:6b3ac9c5a042 | 2196 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2197 | |
| Wayne Roberts |
3:eb174e10afbb | 2198 | if (McpsIndication.RxSlot == 1 || McpsIndication.RxSlot == 2) |
| Wayne Roberts |
3:eb174e10afbb | 2199 | McpsIndication.ADR_ACK_CNT = 0; |
| Wayne Roberts |
3:eb174e10afbb | 2200 | |
| Wayne Roberts |
3:eb174e10afbb | 2201 | /* set FCntDwn to next expected value, if last NbTrans */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2202 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
3:eb174e10afbb | 2203 | if (flags.uplink_in_progress <= 1 && last_up_macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_UP) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2204 | if (fCtrl.Bits.Ack) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2205 | FCntUp++; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2206 | } else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2207 | MAC_PRINTF("\e[31mrx-!ack\e[0m\n"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2208 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2209 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2210 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2211 | if (is_AFCntDown) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2212 | AFCntDown = rxFCnt32 + 1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2213 | } else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2214 | NFCntDown = rxFCnt32 + 1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2215 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2216 | #else |
| Wayne Roberts |
3:eb174e10afbb | 2217 | /* if last NbTrans confirmed uplink ack'd ok: increment FCntUp */ |
| Wayne Roberts |
3:eb174e10afbb | 2218 | if (flags.uplink_in_progress <= 1 && fCtrl.Bits.Ack && last_up_macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_UP) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2219 | eeprom_increment_value(EEPROM_FCNTUP); /* TODO handle ee-failure return */ |
| Wayne Roberts |
3:eb174e10afbb | 2220 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2221 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2222 | if (is_AFCntDown) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2223 | eeprom_write_word(EEPROM_AFCNTDWN, rxFCnt32 + 1); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2224 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 2225 | eeprom_write_word(EEPROM_NFCNTDWN, rxFCnt32 + 1); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2226 | #endif /* !LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2227 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2228 | return 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2229 | } // ...rx_downlink() |
| Wayne Roberts |
0:6b3ac9c5a042 | 2230 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2231 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2232 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 2233 | typedef union { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2234 | struct { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2235 | uint8_t mhdr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2236 | unsigned int joinNonce : 24; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2237 | unsigned int Home_NetID : 24; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2238 | uint32_t DevAddr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2239 | struct { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2240 | uint8_t RX2dr : 4; // 0,1,2,3 |
| Wayne Roberts |
0:6b3ac9c5a042 | 2241 | uint8_t RX1DRoffset : 3; // 4,5,6 |
| Wayne Roberts |
0:6b3ac9c5a042 | 2242 | uint8_t OptNeg : 1; // 7 |
| Wayne Roberts |
0:6b3ac9c5a042 | 2243 | } DLSettings; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2244 | uint8_t RxDelay; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2245 | } __attribute__((packed)) fields; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2246 | uint8_t octets[13]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2247 | } joinAccept_t; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2248 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2249 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2250 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2251 | #define JOIN_ACCEPT_MAX_SIZE 34 |
| Wayne Roberts |
0:6b3ac9c5a042 | 2252 | static void |
| Wayne Roberts |
0:6b3ac9c5a042 | 2253 | OnRadioRxDone(uint8_t *rx_payload, uint16_t rx_size, int16_t rssi, int8_t snr, us_timestamp_t us_rxDone_at) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2254 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2255 | LoRaMacEventInfoStatus_t status = LORAMAC_EVENT_INFO_STATUS_UNKNOWN_MTYPE; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2256 | LoRaMacHeader_t macHdr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2257 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 2258 | uint8_t _jaDecrypted[JOIN_ACCEPT_MAX_SIZE]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2259 | uint32_t mic, micRx; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2260 | const uint8_t* key; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2261 | const joinAccept_t* ja; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2262 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2263 | uint8_t pktHeaderLen = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2264 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2265 | McpsConfirm.AckReceived = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2266 | McpsIndication.Rssi = rssi; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2267 | McpsIndication.Snr = snr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2268 | McpsIndication.Port = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2269 | //McpsIndication.Multicast = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2270 | McpsIndication.FramePending = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2271 | McpsIndication.Buffer = NULL; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2272 | McpsIndication.BufferSize = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2273 | McpsIndication.RxData = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2274 | McpsIndication.AckReceived = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2275 | McpsIndication.McpsIndication = MCPS_UNCONFIRMED; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2276 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2277 | if (MlmeConfirm.Status == LORAMAC_EVENT_INFO_STATUS_SENDING) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2278 | /* when regular downlink is sent in response to rejoin request */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2279 | MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2280 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2281 | |
| Wayne Roberts |
7:4b6f960dcca2 | 2282 | if (LoRaMacDeviceClass != CLASS_C) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2283 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2284 | Radio::Sleep( ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2285 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2286 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2287 | MAC_PRINTF("OnRadioRxDone(%u) RxSlot%d ", rx_size, McpsIndication.RxSlot); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2288 | if (beacon_rx_done_payload(rx_payload, rx_size)) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2289 | return; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2290 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2291 | macHdr.Value = rx_payload[pktHeaderLen++]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2292 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2293 | MAC_PRINTF(" rx-"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2294 | print_mtype(macHdr.Bits.MType); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2295 | switch (macHdr.Bits.MType) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2296 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2297 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 2298 | case FRAME_TYPE_JOIN_ACCEPT: |
| Wayne Roberts |
0:6b3ac9c5a042 | 2299 | /* always permitting join accept because it might be due to rejoin */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2300 | if (rx_size >= JOIN_ACCEPT_MAX_SIZE) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2301 | printf("joinAccept overSize %u\r\n", rx_size); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2302 | return; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2303 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2304 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2305 | DEBUG_CRYPT_BUF(rx_payload, rx_size, "rxBuf", 0); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2306 | MAC_PRINTF("JoinReqType:%02x ", JoinReqType); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2307 | if (JoinReqType == 0xff) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2308 | DEBUG_CRYPT_BUF(RootNwkKey, 16, "NwkKey", 0); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2309 | key = RootNwkKey; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2310 | } else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2311 | key = JSEncKey; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2312 | DEBUG_CRYPT_BUF(JSEncKey, 16, "JSEncKey", 0); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2313 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2314 | LoRaMacJoinDecrypt( rx_payload + 1, rx_size - 1, key, &_jaDecrypted[1]); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2315 | DEBUG_CRYPT_BUF(_jaDecrypted, rx_size, "macbuf", 0); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2316 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2317 | _jaDecrypted[0] = macHdr.Value; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2318 | ja = (joinAccept_t*)_jaDecrypted; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2319 | flags.OptNeg = ja->fields.DLSettings.OptNeg; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2320 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2321 | if (flags.OptNeg) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2322 | uint8_t micBuf[40]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2323 | uint8_t* ptr = micBuf; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2324 | if (RootAppKey == NULL) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2325 | MAC_PRINTF("OptNeg-without-AppKey "); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2326 | PrepareRxDoneAbort(LORAMAC_EVENT_INFO_STATUS_NO_APPKEY); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2327 | return; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2328 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2329 | *ptr++ = JoinReqType; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2330 | memcpyr(ptr, LoRaMacJoinEui, 8); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2331 | ptr += 8; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2332 | *ptr++ = LoRaMacDevNonce & 0xff; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2333 | *ptr++ = LoRaMacDevNonce >> 8; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2334 | memcpy(ptr, _jaDecrypted, rx_size - LORAMAC_MFR_LEN); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2335 | ptr += rx_size - LORAMAC_MFR_LEN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2336 | DEBUG_MIC_BUF_DOWN(JSIntKey, 16, "JSIntKey", ROW_MIC); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2337 | DEBUG_MIC_BUF_DOWN(micBuf, ptr - micBuf, "jaMic-in", ROW_MIC+1); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2338 | if (LoRaMacJoinComputeMic(false, micBuf, ptr - micBuf, JSIntKey, &mic ) < 0) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2339 | MAC_PRINTF("cryptFail\r\n"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2340 | return; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2341 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2342 | } else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2343 | if (LoRaMacJoinComputeMic(false, _jaDecrypted, rx_size - LORAMAC_MFR_LEN, RootNwkKey, &mic ) < 0) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2344 | MAC_PRINTF("cryptFail\r\n"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2345 | return; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2346 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2347 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2348 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2349 | micRx = ( uint32_t )_jaDecrypted[rx_size - LORAMAC_MFR_LEN]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2350 | micRx |= ( ( uint32_t )_jaDecrypted[rx_size - LORAMAC_MFR_LEN + 1] << 8 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2351 | micRx |= ( ( uint32_t )_jaDecrypted[rx_size - LORAMAC_MFR_LEN + 2] << 16 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2352 | micRx |= ( ( uint32_t )_jaDecrypted[rx_size - LORAMAC_MFR_LEN + 3] << 24 ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2353 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2354 | MAC_PRINTF("JOIN_ACCEPT %u,OptNeg%" PRIu32" ", rx_size, flags.OptNeg); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2355 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2356 | if (micRx == mic) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2357 | { |
| Wayne Roberts |
7:4b6f960dcca2 | 2358 | if (McpsIndication.RxSlot == 1) { // no need for RX2 with good mic on rx1 |
| Wayne Roberts |
0:6b3ac9c5a042 | 2359 | RxWindowEvent2.detach(); |
| Wayne Roberts |
7:4b6f960dcca2 | 2360 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2361 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2362 | #ifdef LORAWAN_ROOT_APPKEY |
| Wayne Roberts |
0:6b3ac9c5a042 | 2363 | if (flags.OptNeg) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2364 | MlmeConfirm.fields.join.myJoinNonce = eeprom_read(EEPROM_JOINNONCE); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2365 | MlmeConfirm.fields.join.rxJoinNonce = ja->fields.joinNonce; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2366 | if (MlmeConfirm.fields.join.rxJoinNonce <= MlmeConfirm.fields.join.myJoinNonce) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2367 | /* replay attack */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2368 | PrepareRxDoneAbort(LORAMAC_EVENT_INFO_STATUS_JOINNONCE); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2369 | return; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2370 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2371 | flags.need_ReKeyConf = 1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2372 | LoRaMacJoinComputeSKeys_1v1( RootNwkKey, RootAppKey, _jaDecrypted+1, LoRaMacJoinEui, LoRaMacDevNonce, &keys); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2373 | eeprom_write_word(EEPROM_JOINNONCE, MlmeConfirm.fields.join.rxJoinNonce); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2374 | } else |
| Wayne Roberts |
0:6b3ac9c5a042 | 2375 | #endif /* LORAWAN_ROOT_APPKEY */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2376 | LoRaMacJoinComputeSKeys_1v0( RootNwkKey, _jaDecrypted+1, LoRaMacDevNonce, &keys); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2377 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2378 | DEBUG_CRYPT_BUF(keys.AppSKey , 16, "create-AppSKey", 0); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2379 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2380 | LoRaMacNetID = ja->fields.Home_NetID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2381 | LoRaMacDevAddr = ja->fields.DevAddr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2382 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2383 | // DLSettings |
| Wayne Roberts |
0:6b3ac9c5a042 | 2384 | LoRaMacParams.Rx1DrOffset = ja->fields.DLSettings.RX1DRoffset; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2385 | LoRaMacParams.Rx2Channel.Datarate = ja->fields.DLSettings.RX2dr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2386 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2387 | // RxDelay |
| Wayne Roberts |
0:6b3ac9c5a042 | 2388 | LoRaMacParams.ReceiveDelay1_us = (ja->fields.RxDelay & 0x0f) * 1000000; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2389 | if( LoRaMacParams.ReceiveDelay1_us == 0 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2390 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2391 | LoRaMacParams.ReceiveDelay1_us = 1000000; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2392 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2393 | LoRaMacParams.ReceiveDelay2_us = LoRaMacParams.ReceiveDelay1_us + 1000000; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2394 | MAC_PRINTF("rx1droffset:%u, rx2dr%u rxDelays:%" PRIu32" %" PRIu32", devaddr:%08" PRIx32" ", |
| Wayne Roberts |
0:6b3ac9c5a042 | 2395 | LoRaMacParams.Rx1DrOffset, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2396 | LoRaMacParams.Rx2Channel.Datarate, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2397 | LoRaMacParams.ReceiveDelay1_us, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2398 | LoRaMacParams.ReceiveDelay2_us, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2399 | LoRaMacDevAddr |
| Wayne Roberts |
0:6b3ac9c5a042 | 2400 | ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2401 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2402 | #if !( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) ) // TODO |
| Wayne Roberts |
0:6b3ac9c5a042 | 2403 | //CFList |
| Wayne Roberts |
0:6b3ac9c5a042 | 2404 | if( ( rx_size - 1 ) > 16 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2405 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2406 | ChannelParams_t param; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2407 | param.DrRange.Value = ( LORAMAC_TX_MAX_DATARATE << 4 ) | LORAMAC_TX_MIN_DATARATE; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2408 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2409 | for( uint8_t i = 3, j = 0; i < ( 5 + 3 ); i++, j += 3 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2410 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2411 | param.FreqHz = ( ( uint32_t )_jaDecrypted[13 + j] | ( ( uint32_t )_jaDecrypted[14 + j] << 8 ) | ( ( uint32_t )_jaDecrypted[15 + j] << 16 ) ) * 100; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2412 | if( param.FreqHz != 0 ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2413 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2414 | LoRaMacChannelAdd( i, param ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2415 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2416 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 2417 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2418 | LoRaMacChannelRemove( i ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2419 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2420 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2421 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2422 | #endif |
| Wayne Roberts |
0:6b3ac9c5a042 | 2423 | status = LORAMAC_EVENT_INFO_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2424 | flags.IsLoRaMacNetworkJoined = true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2425 | LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2426 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2427 | MAC_PRINTF("JoinReqType%x\r\n", JoinReqType); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2428 | FCntUp = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2429 | NFCntDown = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2430 | AFCntDown = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2431 | ConfFCntDown = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2432 | RJcount0 = 0; |
| Wayne Roberts |
3:eb174e10afbb | 2433 | McpsIndication.ADR_ACK_CNT = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2434 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2435 | rejoin.event.detach(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2436 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2437 | // must always notify application layer |
| Wayne Roberts |
0:6b3ac9c5a042 | 2438 | MlmeConfirm.MlmeRequest = MLME_JOIN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2439 | region_session_start(LORAMAC_EVENT_INFO_STATUS_OK); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2440 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2441 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 2442 | { /* join-accept mic fail */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2443 | status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL; |
| dudmuck | 2:c9c736b3e4eb | 2444 | MAC_PRINTF("ja-mic-fail rx:%" PRIx32 " calc:%" PRIx32" size:%d\r\n", micRx, mic, rx_size); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2445 | if (MlmeIndication.MlmeIndication != MLME_NONE) { |
| dudmuck | 2:c9c736b3e4eb | 2446 | MlmeIndication.Status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2447 | if (LoRaMacPrimitives->MacMlmeIndication != NULL) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2448 | LoRaMacPrimitives->MacMlmeIndication(&MlmeIndication); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2449 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2450 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2451 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2452 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2453 | case FRAME_TYPE_DATA_CONFIRMED_DOWN: |
| Wayne Roberts |
0:6b3ac9c5a042 | 2454 | case FRAME_TYPE_DATA_UNCONFIRMED_DOWN: |
| Wayne Roberts |
0:6b3ac9c5a042 | 2455 | if (rx_downlink(pktHeaderLen, rx_payload, rx_size, snr, us_rxDone_at) == 0) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2456 | status = LORAMAC_EVENT_INFO_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2457 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2458 | case FRAME_TYPE_PROPRIETARY: |
| Wayne Roberts |
0:6b3ac9c5a042 | 2459 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2460 | McpsIndication.McpsIndication = MCPS_PROPRIETARY; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2461 | McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2462 | McpsIndication.Buffer = Radio::radio.rx_buf; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2463 | McpsIndication.BufferSize = rx_size - pktHeaderLen; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2464 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2465 | if (LoRaMacPrimitives->MacMcpsIndication != NULL) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2466 | LoRaMacPrimitives->MacMcpsIndication( &McpsIndication ); // RxDone |
| Wayne Roberts |
0:6b3ac9c5a042 | 2467 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2468 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2469 | default: |
| Wayne Roberts |
0:6b3ac9c5a042 | 2470 | MAC_PRINTF("unknown frame type:%02x\r\n", macHdr.Value); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2471 | PrepareRxDoneAbort(LORAMAC_EVENT_INFO_STATUS_UNKNOWN_MTYPE); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2472 | break; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2473 | } // ..switch( macHdr.Bits.MType ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2474 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2475 | if (LoRaMacDeviceClass == CLASS_C) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2476 | if (McpsIndication.RxSlot == 1) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2477 | RxWindow2Setup(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2478 | RxWindow2Start(); // immiediately to continuous rx2 reception |
| Wayne Roberts |
7:4b6f960dcca2 | 2479 | } else if (McpsIndication.RxSlot == 2) { |
| Wayne Roberts |
7:4b6f960dcca2 | 2480 | /* stop simulated rx timeout for classC rx2-continuous */ |
| Wayne Roberts |
7:4b6f960dcca2 | 2481 | RxWindowEvent2.detach(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2482 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2483 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2484 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2485 | { |
| Wayne Roberts |
7:4b6f960dcca2 | 2486 | if (flags.uplink_in_progress > 0) |
| Wayne Roberts |
7:4b6f960dcca2 | 2487 | finish_uplink(status); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2488 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2489 | mcps_confirm(status); // RxDone |
| Wayne Roberts |
0:6b3ac9c5a042 | 2490 | mlme_confirm(status); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2491 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2492 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2493 | MAC_PRINTF("\r\n"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2494 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2495 | flags.rxing = false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2496 | } // ..OnRadioRxDone() |
| Wayne Roberts |
0:6b3ac9c5a042 | 2497 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2498 | __attribute__((weak)) bool |
| Wayne Roberts |
0:6b3ac9c5a042 | 2499 | beacon_rx_timeout() |
| Wayne Roberts |
0:6b3ac9c5a042 | 2500 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2501 | return false; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2502 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2503 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2504 | void OnRadioRxTimeout( void ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2505 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2506 | MAC_PRINTF("OnRadioRxTimeout()%d ", McpsIndication.RxSlot); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2507 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 2508 | MAC_PRINTF(",%u ", flags.IsLoRaMacNetworkJoined); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2509 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2510 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2511 | if (beacon_rx_timeout()) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2512 | return; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2513 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2514 | if (McpsIndication.RxSlot == 1) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2515 | RxWindow2Setup(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2516 | |
| Wayne Roberts |
7:4b6f960dcca2 | 2517 | if (LoRaMacDeviceClass != CLASS_C) |
| Wayne Roberts |
7:4b6f960dcca2 | 2518 | Radio::Sleep(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2519 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2520 | if (McpsIndication.RxSlot == 2) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2521 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2522 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 2523 | if (flags.IsLoRaMacNetworkJoined) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2524 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2525 | if (uplinkMHDR->Bits.MType == FRAME_TYPE_DATA_UNCONFIRMED_UP) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2526 | /* sent once, stoping now */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2527 | mcps_confirm(LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2528 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2529 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2530 | mlme_confirm(LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2531 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 2532 | } else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2533 | if (++MlmeIndication.JoinRequestTrials < MaxJoinRequestTrials) { |
| Wayne Roberts |
4:e4bfe9183f94 | 2534 | TxDelayedEvent.attach_us(OnTxDelayedIsr, 1000000); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2535 | MAC_PRINTF("RxTImeout-join-tx-delay\r\n"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2536 | MAC_PRINTF("join-try%u of%u ", MlmeIndication.JoinRequestTrials, MaxJoinRequestTrials); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2537 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2538 | if (MlmeIndication.MlmeIndication != MLME_NONE) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2539 | MlmeIndication.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2540 | if (LoRaMacPrimitives->MacMlmeIndication) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2541 | LoRaMacPrimitives->MacMlmeIndication(&MlmeIndication); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2542 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2543 | } else { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2544 | mlme_confirm(LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2545 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2546 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2547 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2548 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2549 | finish_uplink(LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2550 | } // ..if (McpsIndication.RxSlot == 2) |
| Wayne Roberts |
7:4b6f960dcca2 | 2551 | |
| Wayne Roberts |
7:4b6f960dcca2 | 2552 | if (LoRaMacDeviceClass == CLASS_C) { |
| Wayne Roberts |
7:4b6f960dcca2 | 2553 | if (McpsIndication.RxSlot != 2) { |
| Wayne Roberts |
7:4b6f960dcca2 | 2554 | RxWindow2Start(); |
| Wayne Roberts |
7:4b6f960dcca2 | 2555 | } |
| Wayne Roberts |
7:4b6f960dcca2 | 2556 | } else |
| Wayne Roberts |
7:4b6f960dcca2 | 2557 | flags.rxing = false; |
| Wayne Roberts |
7:4b6f960dcca2 | 2558 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2559 | MAC_PRINTF("\r\n"); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2560 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2561 | } // ..OnRadioRxTimeout() |
| Wayne Roberts |
0:6b3ac9c5a042 | 2562 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2563 | __attribute__((weak)) void |
| Wayne Roberts |
0:6b3ac9c5a042 | 2564 | on_dio0_top_half(us_timestamp_t dio0_at) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2565 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2566 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2567 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2568 | static void OnRadioRxError( void ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2569 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2570 | if( LoRaMacDeviceClass != CLASS_C ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2571 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2572 | Radio::Sleep( ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2573 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2574 | else |
| Wayne Roberts |
0:6b3ac9c5a042 | 2575 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2576 | RxWindow2Setup(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2577 | RxWindow2Start(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2578 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2579 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2580 | if (McpsIndication.RxSlot == 2) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2581 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2582 | flags.uplink_in_progress = 0; // TODO check |
| Wayne Roberts |
0:6b3ac9c5a042 | 2583 | mlme_confirm(LORAMAC_EVENT_INFO_STATUS_RX2_ERROR); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2584 | mcps_confirm(LORAMAC_EVENT_INFO_STATUS_RX2_ERROR); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2585 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2586 | } // ..OnRadioRxError |
| Wayne Roberts |
0:6b3ac9c5a042 | 2587 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2588 | const RadioEvents_t RadioEvents = { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2589 | /* Dio0_top_half */ on_dio0_top_half, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2590 | /* TxDone */ OnRadioTxDone, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2591 | /* TxTimeout */ OnRadioTxTimeout, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2592 | /* RxDone */ OnRadioRxDone, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2593 | /* RxTimeout */ OnRadioRxTimeout, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2594 | /* RxError */ OnRadioRxError, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2595 | /* FhssChangeChannel */ NULL, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2596 | /* CadDone */ NULL |
| Wayne Roberts |
0:6b3ac9c5a042 | 2597 | }; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2598 | |
| dudmuck | 2:c9c736b3e4eb | 2599 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2600 | LoRaMacStatus_t |
| Wayne Roberts |
0:6b3ac9c5a042 | 2601 | LoRaMacInitialization( const LoRaMacPrimitives_t *primitives, const LoRaMacCallback_t *callbacks ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2602 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2603 | if( primitives == NULL ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2604 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2605 | return LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2606 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2607 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2608 | if( ( primitives->MacMcpsConfirm == NULL ) || |
| Wayne Roberts |
0:6b3ac9c5a042 | 2609 | ( primitives->MacMcpsIndication == NULL ) || |
| Wayne Roberts |
0:6b3ac9c5a042 | 2610 | ( primitives->MacMlmeConfirm == NULL ) || |
| Wayne Roberts |
0:6b3ac9c5a042 | 2611 | ( primitives->MacMlmeIndication == NULL ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2612 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2613 | return LORAMAC_STATUS_PARAMETER_INVALID; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2614 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2615 | |
| dudmuck | 2:c9c736b3e4eb | 2616 | if (targetCheckLSE() < 0) |
| dudmuck | 2:c9c736b3e4eb | 2617 | return LORAMAC_STATUS_LSE; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2618 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2619 | LoRaMacPrimitives = primitives; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2620 | LoRaMacCallbacks = callbacks; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2621 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2622 | LoRaMacDeviceClass = CLASS_A; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2623 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2624 | #ifdef DUTY_ENABLE |
| Wayne Roberts |
0:6b3ac9c5a042 | 2625 | DutyInit(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2626 | #endif /* DUTY_ENABLE */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2627 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2628 | region_mac_init(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2629 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2630 | ResetMacParameters( ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2631 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2632 | // Initialize Radio driver |
| Wayne Roberts |
0:6b3ac9c5a042 | 2633 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2634 | LoRaMacClassBInitialization(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2635 | Radio::Init( &RadioEvents ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2636 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2637 | // Random seed initialization |
| Wayne Roberts |
0:6b3ac9c5a042 | 2638 | srand(Radio::Random()); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2639 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2640 | flags.PublicNetwork = true; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2641 | Radio::SetPublicNetwork( flags.PublicNetwork ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2642 | Radio::Sleep( ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2643 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2644 | McpsIndication.RxSlot = -1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2645 | function_pending = NULL; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2646 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2647 | McpsConfirm.McpsRequest = MCPS_NONE; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2648 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2649 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 2650 | MaxJoinRequestTrials = 1; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2651 | #else |
| Wayne Roberts |
0:6b3ac9c5a042 | 2652 | flags.have_SNwkSIntKey = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2653 | flags.have_NwkSEncKey = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2654 | flags.OptNeg = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2655 | #endif /* !LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2656 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2657 | LoRaMacCryptoInit(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2658 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2659 | MlmeIndication.MlmeIndication = MLME_NONE; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2660 | |
| Wayne Roberts |
3:eb174e10afbb | 2661 | ADR_ACK_LIMIT = DEFAULT_ADR_ACK_LIMIT; |
| Wayne Roberts |
3:eb174e10afbb | 2662 | ADR_ACK_DELAY = DEFAULT_ADR_ACK_DELAY; |
| Wayne Roberts |
3:eb174e10afbb | 2663 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2664 | return LORAMAC_STATUS_OK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2665 | } // ..LoRaMacInitialization() |
| Wayne Roberts |
0:6b3ac9c5a042 | 2666 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2667 | void SendFrameOnChannel( uint8_t ch_num ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2668 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2669 | int8_t txPowerIndex = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2670 | int8_t txPower = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2671 | uint8_t tx_len = tx_buf_len; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2672 | uint32_t mic; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2673 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2674 | /* TODO: if beacon guard, defer until pingslot 0 */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2675 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2676 | last_up_macHdr.Value = Radio::radio.tx_buf[0]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2677 | if (last_up_macHdr.Bits.MType == FRAME_TYPE_DATA_UNCONFIRMED_UP || |
| Wayne Roberts |
0:6b3ac9c5a042 | 2678 | last_up_macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_UP) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2679 | { |
| Wayne Roberts |
3:eb174e10afbb | 2680 | LoRaMacFrameCtrl_t* fCtrl = (LoRaMacFrameCtrl_t*)&Radio::radio.tx_buf[5]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2681 | block_t block; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2682 | uint32_t fcnt_up; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2683 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 2684 | fcnt_up = FCntUp; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2685 | #else |
| Wayne Roberts |
0:6b3ac9c5a042 | 2686 | fcnt_up = eeprom_read(EEPROM_FCNTUP); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2687 | #endif /* LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
3:eb174e10afbb | 2688 | |
| Wayne Roberts |
3:eb174e10afbb | 2689 | fCtrl->Bits.AdrAckReq = false; |
| Wayne Roberts |
3:eb174e10afbb | 2690 | if (fCtrl->Bits.Adr) { |
| Wayne Roberts |
3:eb174e10afbb | 2691 | if (McpsIndication.ADR_ACK_CNT >= ADR_ACK_LIMIT) { |
| Wayne Roberts |
3:eb174e10afbb | 2692 | if (LoRaMacParamsDefaults.ChannelsDatarate > LORAMAC_TX_MIN_DATARATE || LoRaMacParams.ChannelsTxPower > LORAMAC_DEFAULT_TX_POWER || LoRaMacParams.NbEnabledChannels < LoRaMacParamsDefaults.NbEnabledChannels) |
| Wayne Roberts |
3:eb174e10afbb | 2693 | fCtrl->Bits.AdrAckReq = true; |
| Wayne Roberts |
3:eb174e10afbb | 2694 | |
| Wayne Roberts |
3:eb174e10afbb | 2695 | if (McpsIndication.ADR_ACK_CNT >= (ADR_ACK_LIMIT + ADR_ACK_DELAY)) { |
| Wayne Roberts |
3:eb174e10afbb | 2696 | /* if tx power less than default: increase tx power, otherwise decrease datarate */ |
| Wayne Roberts |
3:eb174e10afbb | 2697 | if (LoRaMacParams.ChannelsTxPower > LORAMAC_DEFAULT_TX_POWER) { |
| Wayne Roberts |
3:eb174e10afbb | 2698 | LoRaMacParams.ChannelsTxPower--; |
| Wayne Roberts |
3:eb174e10afbb | 2699 | } else if (LoRaMacParams.ChannelsDatarate > LORAMAC_TX_MIN_DATARATE) { |
| Wayne Roberts |
3:eb174e10afbb | 2700 | LoRaMacParams.ChannelsDatarate--; |
| Wayne Roberts |
3:eb174e10afbb | 2701 | McpsIndication.ADR_ACK_CNT -= ADR_ACK_DELAY; |
| Wayne Roberts |
3:eb174e10afbb | 2702 | } else { |
| Wayne Roberts |
3:eb174e10afbb | 2703 | memcpy(LoRaMacParams.ChannelsMask, LoRaMacParamsDefaults.ChannelsMask, sizeof(LoRaMacParams.ChannelsMask)); |
| Wayne Roberts |
3:eb174e10afbb | 2704 | LoRaMacParams.NbEnabledChannels = LoRaMacParamsDefaults.NbEnabledChannels; |
| Wayne Roberts |
3:eb174e10afbb | 2705 | } |
| Wayne Roberts |
3:eb174e10afbb | 2706 | } |
| Wayne Roberts |
3:eb174e10afbb | 2707 | } |
| Wayne Roberts |
3:eb174e10afbb | 2708 | } // ..if (fCtrl->Bits.Adr) |
| Wayne Roberts |
3:eb174e10afbb | 2709 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2710 | Radio::radio.tx_buf[6] = fcnt_up & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2711 | Radio::radio.tx_buf[7] = ( fcnt_up >> 8 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2712 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2713 | block.b.header = 0x49; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2714 | block.b.confFCnt = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2715 | block.b.dr = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2716 | block.b.ch = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2717 | block.b.dir = UP_LINK; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2718 | block.b.DevAddr = LoRaMacDevAddr; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2719 | block.b.FCnt = fcnt_up; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2720 | block.b.zero8 = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2721 | block.b.lenMsg = tx_len; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2722 | if (flags.OptNeg) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2723 | uint16_t cmacF, cmacS; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2724 | cmacF = LoRaMacComputeMic(&block, Radio::radio.tx_buf, keys.FNwkSIntKey); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2725 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2726 | block.b.confFCnt = ConfFCntDown; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2727 | block.b.dr = LoRaMacParams.ChannelsDatarate; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2728 | block.b.ch = ch_num; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2729 | cmacS = LoRaMacComputeMic(&block, Radio::radio.tx_buf, keys.SNwkSIntKey) & 0xffff; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2730 | mic = cmacS | (cmacF << 16); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2731 | ConfFCntDown = 0; /* single use */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2732 | } else |
| Wayne Roberts |
0:6b3ac9c5a042 | 2733 | mic = LoRaMacComputeMic(&block, Radio::radio.tx_buf, keys.FNwkSIntKey); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2734 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2735 | Radio::radio.tx_buf[tx_buf_len + 0] = mic & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2736 | Radio::radio.tx_buf[tx_buf_len + 1] = ( mic >> 8 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2737 | Radio::radio.tx_buf[tx_buf_len + 2] = ( mic >> 16 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2738 | Radio::radio.tx_buf[tx_buf_len + 3] = ( mic >> 24 ) & 0xFF; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2739 | tx_len += LORAMAC_MFR_LEN; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2740 | MAC_PRINTF("FCntUp%u ", fcnt_up); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2741 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2742 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 2743 | McpsConfirm.UpLinkCounter = FCntUp; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2744 | #else |
| Wayne Roberts |
0:6b3ac9c5a042 | 2745 | McpsConfirm.UpLinkCounter = eeprom_read(EEPROM_FCNTUP); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2746 | #endif /* !LORAWAN_JOIN_EUI */ |
| Wayne Roberts |
3:eb174e10afbb | 2747 | |
| Wayne Roberts |
3:eb174e10afbb | 2748 | if (flags.uplink_in_progress <= 1) |
| Wayne Roberts |
3:eb174e10afbb | 2749 | McpsIndication.ADR_ACK_CNT++; |
| Wayne Roberts |
3:eb174e10afbb | 2750 | |
| Wayne Roberts |
3:eb174e10afbb | 2751 | } // ..if sending (un)conf |
| Wayne Roberts |
3:eb174e10afbb | 2752 | |
| Wayne Roberts |
3:eb174e10afbb | 2753 | txPowerIndex = region_LimitTxPower( LoRaMacParams.ChannelsTxPower ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2754 | txPower = TxPowers[txPowerIndex]; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2755 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2756 | if (MlmeConfirm.MlmeRequest != MLME_NONE) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2757 | MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_SENDING; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2758 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2759 | if (McpsConfirm.McpsRequest != MCPS_NONE) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2760 | McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_SENDING; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2761 | McpsConfirm.Datarate = LoRaMacParams.ChannelsDatarate; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2762 | McpsConfirm.TxPower = txPowerIndex; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2763 | McpsConfirm.UpLinkFreqHz = Channels[ch_num].FreqHz; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2764 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2765 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2766 | Radio::SetChannel(Channels[ch_num].FreqHz); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2767 | if (MlmeIndication.MlmeIndication != MLME_NONE) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2768 | MlmeIndication.freqHz = Channels[ch_num].FreqHz; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2769 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2770 | region_tx_setup(txPower, tx_len); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2771 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2772 | // Store the time on air |
| Wayne Roberts |
0:6b3ac9c5a042 | 2773 | //McpsConfirm.TxTimeOnAir = TxTimeOnAir_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2774 | //MlmeConfirm.TxTimeOnAir = TxTimeOnAir_us; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2775 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2776 | // Send now |
| Wayne Roberts |
7:4b6f960dcca2 | 2777 | if (Radio::Send(tx_len, LoRaMacParams.MaxListenTime, REGION_LBT_CHANNEL_FREE_TIME_us, REGION_LBT_RSSI_THRESHOLD_DBM) < 0) { |
| Wayne Roberts |
7:4b6f960dcca2 | 2778 | mcps_confirm(LORAMAC_EVENT_INFO_STATUS_CHANNEL_BUSY); // SendFrame fail |
| Wayne Roberts |
7:4b6f960dcca2 | 2779 | return; |
| Wayne Roberts |
7:4b6f960dcca2 | 2780 | } |
| Wayne Roberts |
5:4e9d41359897 | 2781 | waitingFor = LORAMAC_STATUS_WAITING_FOR_TXDONE; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2782 | MAC_PRINTF(" sfoc %u, %" PRIu32"hz\r\n", tx_len, Channels[ch_num].FreqHz); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2783 | |
| Wayne Roberts |
3:eb174e10afbb | 2784 | /* if this is unconfirmed up, and last NbTrans */ |
| Wayne Roberts |
3:eb174e10afbb | 2785 | if (last_up_macHdr.Bits.MType == FRAME_TYPE_DATA_UNCONFIRMED_UP && flags.uplink_in_progress <= 1) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2786 | #ifdef LORAWAN_JOIN_EUI |
| Wayne Roberts |
0:6b3ac9c5a042 | 2787 | FCntUp++; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2788 | #else |
| Wayne Roberts |
0:6b3ac9c5a042 | 2789 | if (eeprom_increment_value(EEPROM_FCNTUP) < 0) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2790 | mcps_confirm(LORAMAC_EVENT_INFO_STATUS_INCR_FAIL); // SendFrame fail |
| Wayne Roberts |
0:6b3ac9c5a042 | 2791 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2792 | #endif |
| Wayne Roberts |
0:6b3ac9c5a042 | 2793 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2794 | } // ..SendFrameOnChannel() |
| Wayne Roberts |
0:6b3ac9c5a042 | 2795 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2796 | uint8_t CountBits( uint16_t mask, uint8_t nbBits ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2797 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2798 | uint8_t nbActiveBits = 0; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2799 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2800 | for( uint8_t j = 0; j < nbBits; j++ ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2801 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2802 | if( ( mask & ( 1 << j ) ) == ( 1 << j ) ) |
| Wayne Roberts |
0:6b3ac9c5a042 | 2803 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2804 | nbActiveBits++; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2805 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2806 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2807 | return nbActiveBits; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2808 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2809 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2810 | void LoRaMacPrintStatus() |
| Wayne Roberts |
0:6b3ac9c5a042 | 2811 | { |
| Wayne Roberts |
7:4b6f960dcca2 | 2812 | #ifdef MAC_DEBUG |
| Wayne Roberts |
7:4b6f960dcca2 | 2813 | switch (waitingFor) { |
| Wayne Roberts |
7:4b6f960dcca2 | 2814 | case LORAMAC_STATUS_WAITING_FOR_TXSTART: MAC_PRINTF("wait-TXSTART "); break; |
| Wayne Roberts |
7:4b6f960dcca2 | 2815 | case LORAMAC_STATUS_WAITING_FOR_TXDONE: MAC_PRINTF("wait-TXDONE "); break; |
| Wayne Roberts |
7:4b6f960dcca2 | 2816 | case LORAMAC_STATUS_WAITING_FOR_RX1: MAC_PRINTF("wait-RX1 "); break; |
| Wayne Roberts |
7:4b6f960dcca2 | 2817 | case LORAMAC_STATUS_WAITING_FOR_RX2: MAC_PRINTF("wait-RX2 "); break; |
| Wayne Roberts |
7:4b6f960dcca2 | 2818 | default: break; |
| Wayne Roberts |
7:4b6f960dcca2 | 2819 | } |
| Wayne Roberts |
7:4b6f960dcca2 | 2820 | if (flags.uplink_in_progress > 0) |
| Wayne Roberts |
7:4b6f960dcca2 | 2821 | MAC_PRINTF("uplink_in_progress:%u ", flags.uplink_in_progress); |
| Wayne Roberts |
7:4b6f960dcca2 | 2822 | MAC_PRINTF("ConfFCntUp%u\r\n", ConfFCntUp); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2823 | MAC_PRINTF("function_pending:%p\r\n", function_pending); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2824 | MAC_PRINTF("rx delays:%u, %u, %u, %u\r\n", |
| Wayne Roberts |
0:6b3ac9c5a042 | 2825 | RxWindow1Delay_us, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2826 | LoRaMacParams.ReceiveDelay1_us, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2827 | RxWindow2Delay_us, |
| Wayne Roberts |
0:6b3ac9c5a042 | 2828 | LoRaMacParams.ReceiveDelay2_us |
| Wayne Roberts |
0:6b3ac9c5a042 | 2829 | ); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2830 | if (flags.uplink_in_progress) { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2831 | MAC_PRINTF("since txDone:%u\r\n", Radio::lpt.read_us() - tx_done_at); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2832 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2833 | |
| Wayne Roberts |
7:4b6f960dcca2 | 2834 | MAC_PRINTF("class-"); |
| Wayne Roberts |
7:4b6f960dcca2 | 2835 | switch (LoRaMacDeviceClass) { |
| Wayne Roberts |
7:4b6f960dcca2 | 2836 | case CLASS_A: MAC_PRINTF("A "); break; |
| Wayne Roberts |
7:4b6f960dcca2 | 2837 | case CLASS_B: MAC_PRINTF("B "); break; |
| Wayne Roberts |
7:4b6f960dcca2 | 2838 | case CLASS_C: MAC_PRINTF("C "); break; |
| Wayne Roberts |
7:4b6f960dcca2 | 2839 | } |
| Wayne Roberts |
7:4b6f960dcca2 | 2840 | MAC_PRINTF("\r\n"); |
| Wayne Roberts |
7:4b6f960dcca2 | 2841 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2842 | Radio::PrintStatus(); |
| Wayne Roberts |
7:4b6f960dcca2 | 2843 | #endif /* MAC_DEBUG */ |
| Wayne Roberts |
0:6b3ac9c5a042 | 2844 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2845 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2846 | us_timestamp_t LoRaMacReadTimer() |
| Wayne Roberts |
0:6b3ac9c5a042 | 2847 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2848 | return Radio::lpt.read_us(); |
| Wayne Roberts |
0:6b3ac9c5a042 | 2849 | } |
| Wayne Roberts |
0:6b3ac9c5a042 | 2850 | |
| Wayne Roberts |
0:6b3ac9c5a042 | 2851 | int8_t |
| Wayne Roberts |
0:6b3ac9c5a042 | 2852 | LoRaMacGetRxSlot() |
| Wayne Roberts |
0:6b3ac9c5a042 | 2853 | { |
| Wayne Roberts |
0:6b3ac9c5a042 | 2854 | return McpsIndication.RxSlot; |
| Wayne Roberts |
0:6b3ac9c5a042 | 2855 | } |
| Wayne Roberts |
4:e4bfe9183f94 | 2856 | |
| Wayne Roberts |
4:e4bfe9183f94 | 2857 | void |
| Wayne Roberts |
4:e4bfe9183f94 | 2858 | LoRaMacUserContext() |
| Wayne Roberts |
4:e4bfe9183f94 | 2859 | { |
| Wayne Roberts |
4:e4bfe9183f94 | 2860 | Radio::UserContext(); |
| Wayne Roberts |
4:e4bfe9183f94 | 2861 | |
| Wayne Roberts |
4:e4bfe9183f94 | 2862 | if (flags.OnTxDelayed) { |
| Wayne Roberts |
4:e4bfe9183f94 | 2863 | OnTxDelayedTimerEvent(); |
| Wayne Roberts |
4:e4bfe9183f94 | 2864 | flags.OnTxDelayed = false; |
| Wayne Roberts |
4:e4bfe9183f94 | 2865 | } |
| Wayne Roberts |
4:e4bfe9183f94 | 2866 | } |
| Wayne Roberts |
4:e4bfe9183f94 | 2867 |