Fork of Semtech LoRaWAN stack
Fork of LoRaWAN-lib by
Embed:
(wiki syntax)
Show/hide line numbers
LoRaMac.cpp
00001 /* 00002 / _____) _ | | 00003 ( (____ _____ ____ _| |_ _____ ____| |__ 00004 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00005 _____) ) ____| | | || |_| ____( (___| | | | 00006 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00007 (C)2013 Semtech 00008 ___ _____ _ ___ _ _____ ___ ___ ___ ___ 00009 / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 00010 \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 00011 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 00012 embedded.connectivity.solutions=============== 00013 00014 Description: LoRa MAC layer implementation 00015 00016 License: Revised BSD License, see LICENSE.TXT file include in the project 00017 00018 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel 00019 Jäckle ( STACKFORCE ) 00020 */ 00021 #include "board.h" 00022 00023 #include "LoRaMacCrypto.h" 00024 #include "LoRaMac.h" 00025 #include "LoRaMacTest.h" 00026 00027 /*! 00028 * Maximum PHY layer payload size 00029 */ 00030 #define LORAMAC_PHY_MAXPAYLOAD 255 00031 00032 /*! 00033 * Maximum MAC commands buffer size 00034 */ 00035 #define LORA_MAC_COMMAND_MAX_LENGTH 15 00036 00037 /*! 00038 * FRMPayload overhead to be used when setting the Radio.SetMaxPayloadLength 00039 * in RxWindowSetup function. 00040 * Maximum PHYPayload = MaxPayloadOfDatarate/MaxPayloadOfDatarateRepeater + 00041 * LORA_MAC_FRMPAYLOAD_OVERHEAD 00042 */ 00043 #define LORA_MAC_FRMPAYLOAD_OVERHEAD 13 // MHDR(1) + FHDR(7) + Port(1) + MIC(4) 00044 00045 /*! 00046 * Minimum number of available channels in Frequency Hopping Mode 00047 */ 00048 #define FRQ_HOP_CHNLS_MIN 50 00049 00050 /*! 00051 * Minimum number of available channels in Hybrid Mode 00052 */ 00053 #define HYBRD_CHNLS_MIN 4 00054 00055 /*! 00056 * Device IEEE EUI 00057 */ 00058 static uint8_t* LoRaMacDevEui; 00059 00060 /*! 00061 * Application IEEE EUI 00062 */ 00063 static uint8_t* LoRaMacAppEui; 00064 00065 /*! 00066 * AES encryption/decryption cipher application key 00067 */ 00068 static uint8_t* LoRaMacAppKey; 00069 00070 /*! 00071 * AES encryption/decryption cipher network session key 00072 */ 00073 static uint8_t LoRaMacNwkSKey[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00074 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 00075 00076 /*! 00077 * AES encryption/decryption cipher application session key 00078 */ 00079 static uint8_t LoRaMacAppSKey[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00080 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 00081 00082 /*! 00083 * Device nonce is a random value extracted by issuing a sequence of RSSI 00084 * measurements 00085 */ 00086 static uint16_t LoRaMacDevNonce; 00087 00088 /*! 00089 * Network ID ( 3 bytes ) 00090 */ 00091 static uint32_t LoRaMacNetID; 00092 00093 /*! 00094 * Mote Address 00095 */ 00096 static uint32_t LoRaMacDevAddr; 00097 00098 /*! 00099 * Multicast channels linked list 00100 */ 00101 static MulticastParams_t * MulticastChannels = NULL; 00102 00103 /*! 00104 * Actual device class 00105 */ 00106 static DeviceClass_t LoRaMacDeviceClass; 00107 00108 /*! 00109 * Indicates if the node is connected to a private or public network 00110 */ 00111 static bool PublicNetwork; 00112 00113 /*! 00114 * Indicates if the node supports repeaters 00115 */ 00116 static bool RepeaterSupport; 00117 00118 /*! 00119 * Buffer containing the data to be sent or received. 00120 */ 00121 static uint8_t LoRaMacBuffer[LORAMAC_PHY_MAXPAYLOAD]; 00122 00123 /*! 00124 * Length of packet in LoRaMacBuffer 00125 */ 00126 static uint16_t LoRaMacBufferPktLen = 0; 00127 00128 /*! 00129 * Buffer containing the upper layer data. 00130 */ 00131 static uint8_t LoRaMacPayload[LORAMAC_PHY_MAXPAYLOAD]; 00132 static uint8_t LoRaMacRxPayload[LORAMAC_PHY_MAXPAYLOAD]; 00133 00134 /*! 00135 * LoRaMAC frame counter. Each time a packet is sent the counter is incremented. 00136 * Only the 16 LSB bits are sent 00137 */ 00138 uint32_t UpLinkCounter = 1; 00139 00140 /*! 00141 * LoRaMAC frame counter. Each time a packet is received the counter is 00142 * incremented. 00143 * Only the 16 LSB bits are received 00144 */ 00145 uint32_t DownLinkCounter = 0; 00146 00147 /*! 00148 * IsPacketCounterFixed enables the MIC field tests by fixing the 00149 * UpLinkCounter value 00150 */ 00151 static bool IsUpLinkCounterFixed = false; 00152 00153 /*! 00154 * Used for test purposes. Disables the opening of the reception windows. 00155 */ 00156 static bool IsRxWindowsEnabled = true; 00157 00158 /*! 00159 * Indicates if the MAC layer has already joined a network. 00160 */ 00161 static bool IsLoRaMacNetworkJoined = false; 00162 00163 /*! 00164 * LoRaMac ADR control status 00165 */ 00166 static bool AdrCtrlOn = true; 00167 00168 /*! 00169 * Counts the number of missed ADR acknowledgements 00170 */ 00171 static uint32_t AdrAckCounter = 0; 00172 00173 /*! 00174 * If the node has sent a FRAME_TYPE_DATA_CONFIRMED_UP this variable indicates 00175 * if the nodes needs to manage the server acknowledgement. 00176 */ 00177 static bool NodeAckRequested = false; 00178 00179 /*! 00180 * If the server has sent a FRAME_TYPE_DATA_CONFIRMED_DOWN this variable 00181 * indicates 00182 * if the ACK bit must be set for the next transmission 00183 */ 00184 static bool SrvAckRequested = false; 00185 00186 /*! 00187 * Indicates if the MAC layer wants to send MAC commands 00188 */ 00189 static bool MacCommandsInNextTx = false; 00190 00191 /*! 00192 * Contains the current MacCommandsBuffer index 00193 */ 00194 static uint8_t MacCommandsBufferIndex = 0; 00195 00196 /*! 00197 * Contains the current MacCommandsBuffer index for MAC commands to repeat 00198 */ 00199 static uint8_t MacCommandsBufferToRepeatIndex = 0; 00200 00201 /*! 00202 * Buffer containing the MAC layer commands 00203 */ 00204 static uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH]; 00205 00206 /*! 00207 * Buffer containing the MAC layer commands which must be repeated 00208 */ 00209 static uint8_t MacCommandsBufferToRepeat[LORA_MAC_COMMAND_MAX_LENGTH]; 00210 00211 #if defined(USE_BAND_433) 00212 /*! 00213 * Data rates table definition 00214 */ 00215 const uint8_t Datarates[] = {12, 11, 10, 9, 8, 7, 7, 50}; 00216 00217 /*! 00218 * Maximum payload with respect to the datarate index. Cannot operate with 00219 * repeater. 00220 */ 00221 const uint8_t MaxPayloadOfDatarate[] = {59, 59, 59, 123, 250, 250, 250, 250}; 00222 00223 /*! 00224 * Maximum payload with respect to the datarate index. Can operate with 00225 * repeater. 00226 */ 00227 const uint8_t MaxPayloadOfDatarateRepeater[] = {59, 59, 59, 123, 230, 230, 230, 230}; 00228 00229 /*! 00230 * Tx output powers table definition 00231 */ 00232 const int8_t TxPowers[] = {20, 14, 11, 8, 5, 2}; 00233 00234 /*! 00235 * LoRaMac bands 00236 */ 00237 static Band_t Bands[LORA_MAX_NB_BANDS] = { 00238 BAND0, 00239 }; 00240 00241 /*! 00242 * LoRaMAC channels 00243 */ 00244 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] = { 00245 LC1, LC2, LC3, 00246 }; 00247 #elif defined(USE_BAND_780) 00248 /*! 00249 * Data rates table definition 00250 */ 00251 const uint8_t Datarates[] = {12, 11, 10, 9, 8, 7, 7, 50}; 00252 00253 /*! 00254 * Maximum payload with respect to the datarate index. Cannot operate with 00255 * repeater. 00256 */ 00257 const uint8_t MaxPayloadOfDatarate[] = {59, 59, 59, 123, 250, 250, 250, 250}; 00258 00259 /*! 00260 * Maximum payload with respect to the datarate index. Can operate with 00261 * repeater. 00262 */ 00263 const uint8_t MaxPayloadOfDatarateRepeater[] = {59, 59, 59, 123, 230, 230, 230, 230}; 00264 00265 /*! 00266 * Tx output powers table definition 00267 */ 00268 const int8_t TxPowers[] = {20, 14, 11, 8, 5, 2}; 00269 00270 /*! 00271 * LoRaMac bands 00272 */ 00273 static Band_t Bands[LORA_MAX_NB_BANDS] = { 00274 BAND0, 00275 }; 00276 00277 /*! 00278 * LoRaMAC channels 00279 */ 00280 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] = { 00281 LC1, LC2, LC3, 00282 }; 00283 #elif defined(USE_BAND_868) 00284 /*! 00285 * Data rates table definition 00286 */ 00287 const uint8_t Datarates[] = {12, 11, 10, 9, 8, 7, 7, 50}; 00288 00289 /*! 00290 * Maximum payload with respect to the datarate index. Cannot operate with 00291 * repeater. 00292 */ 00293 const uint8_t MaxPayloadOfDatarate[] = {51, 51, 51, 115, 242, 242, 242, 242}; 00294 00295 /*! 00296 * Maximum payload with respect to the datarate index. Can operate with 00297 * repeater. 00298 */ 00299 const uint8_t MaxPayloadOfDatarateRepeater[] = {51, 51, 51, 115, 222, 222, 222, 222}; 00300 00301 /*! 00302 * Tx output powers table definition 00303 */ 00304 const int8_t TxPowers[] = {20, 14, 11, 8, 5, 2}; 00305 00306 /*! 00307 * LoRaMac bands 00308 */ 00309 static Band_t Bands[LORA_MAX_NB_BANDS] = { 00310 BAND0, BAND1, BAND2, BAND3, BAND4, 00311 }; 00312 00313 /*! 00314 * LoRaMAC channels 00315 */ 00316 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] = { 00317 LC1, LC2, LC3, 00318 }; 00319 #elif defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 00320 /*! 00321 * Data rates table definition 00322 */ 00323 const uint8_t Datarates[] = {10, 9, 8, 7, 8, 0, 0, 0, 12, 11, 10, 9, 8, 7, 0, 0}; 00324 00325 /*! 00326 * Up/Down link data rates offset definition 00327 */ 00328 const uint8_t datarateOffsets[16][4] = { 00329 {DR_10, DR_9, DR_8, DR_8}, // DR_0 00330 {DR_11, DR_10, DR_9, DR_8}, // DR_1 00331 {DR_12, DR_11, DR_10, DR_9}, // DR_2 00332 {DR_13, DR_12, DR_11, DR_10}, // DR_3 00333 {DR_13, DR_13, DR_12, DR_11}, // DR_4 00334 {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}, 00335 {DR_8, DR_8, DR_8, DR_8}, {DR_9, DR_8, DR_8, DR_8}, {DR_10, DR_9, DR_8, DR_8}, 00336 {DR_11, DR_10, DR_9, DR_8}, {DR_12, DR_11, DR_10, DR_9}, {DR_13, DR_12, DR_11, DR_10}, 00337 {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}, 00338 }; 00339 00340 /*! 00341 * Maximum payload with respect to the datarate index. Cannot operate with 00342 * repeater. 00343 */ 00344 const uint8_t MaxPayloadOfDatarate[] = {11, 53, 126, 242, 242, 0, 0, 0, 00345 53, 129, 242, 242, 242, 242, 0, 0}; 00346 00347 /*! 00348 * Maximum payload with respect to the datarate index. Can operate with 00349 * repeater. 00350 */ 00351 const uint8_t MaxPayloadOfDatarateRepeater[] = {11, 53, 126, 242, 242, 0, 0, 0, 00352 33, 109, 222, 222, 222, 222, 0, 0}; 00353 00354 /*! 00355 * Tx output powers table definition 00356 */ 00357 const int8_t TxPowers[] = {30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2}; 00358 00359 /*! 00360 * LoRaMac bands 00361 */ 00362 static Band_t Bands[LORA_MAX_NB_BANDS] = { 00363 BAND0, 00364 }; 00365 00366 /*! 00367 * LoRaMAC channels 00368 */ 00369 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS]; 00370 00371 /*! 00372 * Contains the channels which remain to be applied. 00373 */ 00374 static uint16_t ChannelsMaskRemaining[6]; 00375 00376 #if defined(USE_BAND_915) 00377 /*! 00378 * Last join request sub-band 00379 */ 00380 static int8_t LastJoinBlock; 00381 00382 /*! 00383 * Next join sub-band block 00384 */ 00385 static uint8_t NextJoinBlock; 00386 00387 /*! 00388 * Mask of 125 KHz sub-bands not used for join transmit 00389 */ 00390 static uint8_t JoinBlocksRemaining; 00391 00392 /*! 00393 * Mask of 500 KHz sub-bands not used for join transmit 00394 */ 00395 static uint8_t Join500KHzRemaining; 00396 00397 #ifndef JOIN_BLOCK_ORDER 00398 #define JOIN_BLOCK_ORDER \ 00399 { -1, -1, -1, -1, -1, -1, -1, -1 } 00400 #endif 00401 00402 /*! 00403 * join sub-band block order 00404 */ 00405 static int8_t JoinBlock[8] = JOIN_BLOCK_ORDER; 00406 00407 #endif 00408 00409 /*! 00410 * Defines the first channel for RX window 2 for US band 00411 */ 00412 #define LORAMAC_FIRST_RX2_CHANNEL ((uint32_t)923.3e6) 00413 00414 /*! 00415 * Defines the last channel for RX window 2 for US band 00416 */ 00417 #define LORAMAC_LAST_RX2_CHANNEL ((uint32_t)927.5e6) 00418 00419 /*! 00420 * Defines the step width of the channels for RX window 2 00421 */ 00422 #define LORAMAC_STEPWIDTH_RX2_CHANNEL ((uint32_t)600e3) 00423 00424 #else 00425 #error "Please define a frequency band in the compiler options." 00426 #endif 00427 00428 /*! 00429 * LoRaMAC 2nd reception window settings 00430 */ 00431 static Rx2ChannelParams_t Rx2Channel = RX_WND_2_CHANNEL; 00432 00433 /*! 00434 * Datarate offset between uplink and downlink on first window 00435 */ 00436 static uint8_t Rx1DrOffset = 0; 00437 00438 /*! 00439 * Mask indicating which channels are enabled 00440 */ 00441 static uint16_t ChannelsMask[6]; 00442 00443 /*! 00444 * Channels Tx output power 00445 */ 00446 static int8_t ChannelsTxPower = LORAMAC_DEFAULT_TX_POWER; 00447 00448 /*! 00449 * Channels datarate 00450 */ 00451 static int8_t ChannelsDatarate = LORAMAC_DEFAULT_DATARATE; 00452 00453 /*! 00454 * Channels default datarate 00455 */ 00456 static int8_t ChannelsDefaultDatarate = LORAMAC_DEFAULT_DATARATE; 00457 00458 /*! 00459 * Number of uplink messages repetitions [1:15] (unconfirmed messages only) 00460 */ 00461 static uint8_t ChannelsNbRep = 1; 00462 00463 /*! 00464 * Uplink messages repetitions counter 00465 */ 00466 static uint8_t ChannelsNbRepCounter = 0; 00467 00468 /*! 00469 * Maximum duty cycle 00470 * \remark Possibility to shutdown the device. 00471 */ 00472 static uint8_t MaxDCycle = 0; 00473 00474 /*! 00475 * Aggregated duty cycle management 00476 */ 00477 static uint16_t AggregatedDCycle; 00478 static TimerTime_t AggregatedLastTxDoneTime; 00479 static TimerTime_t AggregatedTimeOff; 00480 00481 /*! 00482 * Enables/Disables duty cycle management (Test only) 00483 */ 00484 static bool DutyCycleOn; 00485 00486 /*! 00487 * Current channel index 00488 */ 00489 static uint8_t Channel; 00490 00491 static uint8_t LastTxChannel; 00492 00493 /*! 00494 * LoRaMac internal states 00495 */ 00496 enum eLoRaMacState { 00497 MAC_IDLE = 0x00000000, 00498 MAC_TX_RUNNING = 0x00000001, 00499 MAC_RX = 0x00000002, 00500 MAC_ACK_REQ = 0x00000004, 00501 MAC_ACK_RETRY = 0x00000008, 00502 MAC_TX_DELAYED = 0x00000010, 00503 MAC_TX_CONFIG = 0x00000020, 00504 MAC_RX_ABORT = 0x00000040, 00505 }; 00506 00507 /*! 00508 * LoRaMac internal state 00509 */ 00510 uint32_t LoRaMacState = MAC_IDLE; 00511 00512 /*! 00513 * LoRaMac timer used to check the LoRaMacState (runs every second) 00514 */ 00515 static TimerEvent_t MacStateCheckTimer; 00516 00517 /*! 00518 * LoRaMac upper layer event functions 00519 */ 00520 static LoRaMacPrimitives_t * LoRaMacPrimitives; 00521 00522 /*! 00523 * LoRaMac upper layer callback functions 00524 */ 00525 static LoRaMacCallback_t* LoRaMacCallbacks; 00526 00527 /*! 00528 * Radio events function pointer 00529 */ 00530 static RadioEvents_t RadioEvents; 00531 00532 /*! 00533 * LoRaMac duty cycle delayed Tx timer 00534 */ 00535 static TimerEvent_t TxDelayedTimer; 00536 00537 /*! 00538 * LoRaMac reception windows timers 00539 */ 00540 static TimerEvent_t RxWindowTimer1; 00541 static TimerEvent_t RxWindowTimer2; 00542 00543 /*! 00544 * LoRaMac reception windows delay from end of Tx 00545 */ 00546 static uint32_t ReceiveDelay1; 00547 static uint32_t ReceiveDelay2; 00548 static uint32_t JoinAcceptDelay1; 00549 static uint32_t JoinAcceptDelay2; 00550 00551 /*! 00552 * LoRaMac reception windows delay 00553 * \remark normal frame: RxWindowXDelay = ReceiveDelayX - RADIO_WAKEUP_TIME 00554 * join frame : RxWindowXDelay = JoinAcceptDelayX - RADIO_WAKEUP_TIME 00555 */ 00556 static uint32_t RxWindow1Delay; 00557 static uint32_t RxWindow2Delay; 00558 00559 /*! 00560 * LoRaMac maximum time a reception window stays open 00561 */ 00562 static uint32_t MaxRxWindow; 00563 00564 /*! 00565 * Acknowledge timeout timer. Used for packet retransmissions. 00566 */ 00567 static TimerEvent_t AckTimeoutTimer; 00568 00569 /*! 00570 * Number of trials to get a frame acknowledged 00571 */ 00572 static uint8_t AckTimeoutRetries = 1; 00573 00574 /*! 00575 * Number of trials to get a frame acknowledged 00576 */ 00577 static uint8_t AckTimeoutRetriesCounter = 1; 00578 00579 /*! 00580 * Indicates if the AckTimeout timer has expired or not 00581 */ 00582 static bool AckTimeoutRetry = false; 00583 00584 /*! 00585 * Last transmission time on air 00586 */ 00587 TimerTime_t TxTimeOnAir = 0; 00588 00589 /*! 00590 * Structure to hold an MCPS indication data. 00591 */ 00592 static McpsIndication_t McpsIndication; 00593 00594 /*! 00595 * Structure to hold MCPS confirm data. 00596 */ 00597 static McpsConfirm_t McpsConfirm; 00598 00599 /*! 00600 * Structure to hold MLME confirm data. 00601 */ 00602 static MlmeConfirm_t MlmeConfirm; 00603 00604 /*! 00605 * Holds the current rx window slot 00606 */ 00607 static uint8_t RxSlot = 0; 00608 00609 /*! 00610 * LoRaMac tx/rx operation state 00611 */ 00612 LoRaMacFlags_t LoRaMacFlags; 00613 00614 /*! 00615 * Join Retransmission back-off configuration 00616 */ 00617 LoRaMacRetransmissionDCycle_t JoinReTransmitDCycle[JOIN_NB_RETRANSMISSION_DCYCLES] = { 00618 JOIN_RETRANSMISSION_DCYCLE1, JOIN_RETRANSMISSION_DCYCLE2, JOIN_RETRANSMISSION_DCYCLE3}; 00619 00620 /*! 00621 * Uptime of the last sent join request 00622 */ 00623 static TimerTime_t LastJoinTxTime; 00624 00625 /*! 00626 * Aggregated join request time on air 00627 */ 00628 static TimerTime_t JoinAggTimeOnAir; 00629 00630 /*! 00631 * \brief Function to be executed on Radio Tx Done event 00632 */ 00633 static void OnRadioTxDone(void); 00634 00635 /*! 00636 * \brief This function prepares the MAC to abort the execution of function 00637 * OnRadioRxDone in case of a reception error. 00638 */ 00639 static void PrepareRxDoneAbort(void); 00640 00641 /*! 00642 * \brief Function to be executed on Radio Rx Done event 00643 */ 00644 static void OnRadioRxDone(uint8_t* payload, uint16_t size, int16_t rssi, int8_t snr); 00645 00646 /*! 00647 * \brief Function executed on Radio Tx Timeout event 00648 */ 00649 static void OnRadioTxTimeout(void); 00650 00651 /*! 00652 * \brief Function executed on Radio Rx error event 00653 */ 00654 static void OnRadioRxError(void); 00655 00656 /*! 00657 * \brief Function executed on Radio Rx Timeout event 00658 */ 00659 static void OnRadioRxTimeout(void); 00660 00661 /*! 00662 * \brief Function executed on Resend Frame timer event. 00663 */ 00664 static void OnMacStateCheckTimerEvent(void); 00665 00666 /*! 00667 * \brief Function executed on duty cycle delayed Tx timer event 00668 */ 00669 static void OnTxDelayedTimerEvent(void); 00670 00671 /*! 00672 * \brief Function executed on first Rx window timer event 00673 */ 00674 static void OnRxWindow1TimerEvent(void); 00675 00676 /*! 00677 * \brief Function executed on second Rx window timer event 00678 */ 00679 static void OnRxWindow2TimerEvent(void); 00680 00681 /*! 00682 * \brief Function executed on AckTimeout timer event 00683 */ 00684 static void OnAckTimeoutTimerEvent(void); 00685 00686 /*! 00687 * \brief Searches and set the next random available channel 00688 * 00689 * \param [OUT] Time to wait for the next transmission according to the duty 00690 * cycle. 00691 * 00692 * \retval status Function status [1: OK, 0: Unable to find a channel on the 00693 * current datarate] 00694 */ 00695 static bool SetNextChannel(TimerTime_t* time); 00696 00697 /*! 00698 * \brief Sets the network to public or private. Updates the sync byte. 00699 * 00700 * \param [IN] enable if true, it enables a public network 00701 */ 00702 static void SetPublicNetwork(bool enable); 00703 00704 /*! 00705 * \brief Initializes and opens the reception window 00706 * 00707 * \param [IN] freq window channel frequency 00708 * \param [IN] datarate window channel datarate 00709 * \param [IN] bandwidth window channel bandwidth 00710 * \param [IN] timeout window channel timeout 00711 */ 00712 static void RxWindowSetup(uint32_t freq, int8_t datarate, uint32_t bandwidth, uint16_t timeout, 00713 bool rxContinuous); 00714 00715 /*! 00716 * \brief Verifies if the RX window 2 frequency is in range 00717 * 00718 * \param [IN] freq window channel frequency 00719 * 00720 * \retval status Function status [1: OK, 0: Frequency not applicable] 00721 */ 00722 static bool Rx2FreqInRange(uint32_t freq); 00723 00724 /*! 00725 * \brief Adds a new MAC command to be sent. 00726 * 00727 * \Remark MAC layer internal function 00728 * 00729 * \param [in] cmd MAC command to be added 00730 * [MOTE_MAC_LINK_CHECK_REQ, 00731 * MOTE_MAC_LINK_ADR_ANS, 00732 * MOTE_MAC_DUTY_CYCLE_ANS, 00733 * MOTE_MAC_RX2_PARAM_SET_ANS, 00734 * MOTE_MAC_DEV_STATUS_ANS 00735 * MOTE_MAC_NEW_CHANNEL_ANS] 00736 * \param [in] p1 1st parameter ( optional depends on the command ) 00737 * \param [in] p2 2nd parameter ( optional depends on the command ) 00738 * 00739 * \retval status Function status [0: OK, 1: Unknown command, 2: Buffer full] 00740 */ 00741 static LoRaMacStatus_t AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p2); 00742 00743 /*! 00744 * \brief Parses the MAC commands which must be repeated. 00745 * 00746 * \Remark MAC layer internal function 00747 * 00748 * \param [IN] cmdBufIn Buffer which stores the MAC commands to send 00749 * \param [IN] length Length of the input buffer to parse 00750 * \param [OUT] cmdBufOut Buffer which stores the MAC commands which must be 00751 * repeated. 00752 * 00753 * \retval Size of the MAC commands to repeat. 00754 */ 00755 static uint8_t ParseMacCommandsToRepeat(uint8_t* cmdBufIn, uint8_t length, uint8_t* cmdBufOut); 00756 00757 /*! 00758 * \brief Validates if the payload fits into the frame, taking the datarate 00759 * into account. 00760 * 00761 * \details Refer to chapter 4.3.2 of the LoRaWAN specification, v1.0 00762 * 00763 * \param lenN Length of the application payload. The length depends on the 00764 * datarate and is region specific 00765 * 00766 * \param datarate Current datarate 00767 * 00768 * \param fOptsLen Length of the fOpts field 00769 * 00770 * \retval [false: payload does not fit into the frame, true: payload fits into 00771 * the frame] 00772 */ 00773 static bool ValidatePayloadLength(uint8_t lenN, int8_t datarate, uint8_t fOptsLen); 00774 00775 /*! 00776 * \brief Counts the number of bits in a mask. 00777 * 00778 * \param [IN] mask A mask from which the function counts the active bits. 00779 * \param [IN] nbBits The number of bits to check. 00780 * 00781 * \retval Number of enabled bits in the mask. 00782 */ 00783 static uint8_t CountBits(uint16_t mask, uint8_t nbBits); 00784 00785 #if defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 00786 /*! 00787 * \brief Counts the number of enabled 125 kHz channels in the channel mask. 00788 * This function can only be applied to US915 band. 00789 * 00790 * \param [IN] channelsMask Pointer to the first element of the channel mask 00791 * 00792 * \retval Number of enabled channels in the channel mask 00793 */ 00794 static uint8_t CountNbEnabled125kHzChannels(uint16_t* channelsMask); 00795 00796 #if defined(USE_BAND_915_HYBRID) 00797 /*! 00798 * \brief Validates the correctness of the channel mask for US915, hybrid mode. 00799 * 00800 * \param [IN] mask Block definition to set. 00801 * \param [OUT] channelsMask Pointer to the first element of the channel mask 00802 */ 00803 static void ReenableChannels(uint16_t mask, uint16_t* channelMask); 00804 00805 /*! 00806 * \brief Validates the correctness of the channel mask for US915, hybrid mode. 00807 * 00808 * \param [IN] channelsMask Pointer to the first element of the channel mask 00809 * 00810 * \retval [true: channel mask correct, false: channel mask not correct] 00811 */ 00812 static bool ValidateChannelMask(uint16_t* channelMask); 00813 #endif 00814 00815 #endif 00816 00817 /*! 00818 * \brief Limits the Tx power according to the number of enabled channels 00819 * 00820 * \retval Returns the maximum valid tx power 00821 */ 00822 static int8_t LimitTxPower(int8_t txPower); 00823 00824 /*! 00825 * \brief Verifies, if a value is in a given range. 00826 * 00827 * \param value Value to verify, if it is in range 00828 * 00829 * \param min Minimum possible value 00830 * 00831 * \param max Maximum possible value 00832 * 00833 * \retval Returns the maximum valid tx power 00834 */ 00835 static bool ValueInRange(int8_t value, int8_t min, int8_t max); 00836 00837 /*! 00838 * \brief Calculates the next datarate to set, when ADR is on or off 00839 * 00840 * \param [IN] adrEnabled Specify whether ADR is on or off 00841 * 00842 * \param [IN] isTx Set to true if called by transmit, set to false if a dry run 00843 * 00844 * \param [OUT] datarateOut Reports the datarate which will be used next 00845 * 00846 * \param [OUT] txpowerOut Reports the tx power which will be used next 00847 * 00848 * \retval Returns the state of ADR ack request 00849 */ 00850 static bool AdrNextDr(bool adrEnabled, bool isTx, int8_t* datarateOut, int8_t* txpowerOut); 00851 00852 /*! 00853 * \brief Disables channel in a specified channel mask 00854 * 00855 * \param [IN] id - Id of the channel 00856 * 00857 * \param [IN] mask - Pointer to the channel mask to edit 00858 * 00859 * \retval [true, if disable was successful, false if not] 00860 */ 00861 static bool DisableChannelInMask(uint8_t id, uint16_t* mask); 00862 00863 /*! 00864 * \brief Decodes MAC commands in the fOpts field and in the payload 00865 */ 00866 static void ProcessMacCommands(uint8_t* payload, uint8_t macIndex, uint8_t commandsSize, 00867 uint8_t snr); 00868 00869 /*! 00870 * \brief LoRaMAC layer generic send frame 00871 * 00872 * \param [IN] macHdr MAC header field 00873 * \param [IN] fPort MAC payload port 00874 * \param [IN] fBuffer MAC data buffer to be sent 00875 * \param [IN] fBufferSize MAC data buffer size 00876 * \retval status Status of the operation. 00877 */ 00878 LoRaMacStatus_t Send(LoRaMacHeader_t * macHdr, uint8_t fPort, void* fBuffer, uint16_t fBufferSize); 00879 00880 /*! 00881 * \brief LoRaMAC layer frame buffer initialization 00882 * 00883 * \param [IN] macHdr MAC header field 00884 * \param [IN] fCtrl MAC frame control field 00885 * \param [IN] fOpts MAC commands buffer 00886 * \param [IN] fPort MAC payload port 00887 * \param [IN] fBuffer MAC data buffer to be sent 00888 * \param [IN] fBufferSize MAC data buffer size 00889 * \retval status Status of the operation. 00890 */ 00891 LoRaMacStatus_t PrepareFrame(LoRaMacHeader_t * macHdr, LoRaMacFrameCtrl_t * fCtrl, uint8_t fPort, 00892 void* fBuffer, uint16_t fBufferSize); 00893 00894 /* 00895 * \brief Schedules the frame according to the duty cycle 00896 * 00897 * \retval Status of the operation 00898 */ 00899 static LoRaMacStatus_t ScheduleTx(void); 00900 00901 /* 00902 * \brief Calculates the back-off time for the band of a channel. 00903 * 00904 * \param [IN] channel The last Tx channel index 00905 */ 00906 static void CalculateBackOff(uint8_t channel); 00907 00908 /*! 00909 * \brief LoRaMAC layer prepared frame buffer transmission with channel 00910 * specification 00911 * 00912 * \remark PrepareFrame must be called at least once before calling this 00913 * function. 00914 * 00915 * \param [IN] channel Channel parameters 00916 * \retval status Status of the operation. 00917 */ 00918 LoRaMacStatus_t SendFrameOnChannel(ChannelParams_t channel); 00919 00920 static void OnRadioTxDone(void) { 00921 TimerTime_t curTime = TimerGetCurrentTime(); 00922 if (LoRaMacDeviceClass != CLASS_C ) { 00923 Radio.Sleep(); 00924 } 00925 else { 00926 OnRxWindow2TimerEvent(); 00927 } 00928 00929 // Store last Tx channel 00930 LastTxChannel = Channel; 00931 // Update last tx done time for the current channel 00932 Bands[Channels[LastTxChannel].Band ].LastTxDoneTime = curTime; 00933 // Update Aggregated last tx done time 00934 AggregatedLastTxDoneTime = curTime; 00935 00936 // Update join tx done and time on air 00937 if ((LoRaMacFlags.Bits.MlmeReq == 1) && (MlmeConfirm.MlmeRequest == MLME_JOIN )) { 00938 JoinAggTimeOnAir += TxTimeOnAir; 00939 LastJoinTxTime = curTime; 00940 } 00941 00942 if (IsRxWindowsEnabled == true) { 00943 TimerSetValue(&RxWindowTimer1, RxWindow1Delay); 00944 TimerStart(&RxWindowTimer1); 00945 if (LoRaMacDeviceClass != CLASS_C ) { 00946 TimerSetValue(&RxWindowTimer2, RxWindow2Delay); 00947 TimerStart(&RxWindowTimer2); 00948 } 00949 if ((LoRaMacDeviceClass == CLASS_C ) || (NodeAckRequested == true)) { 00950 TimerSetValue(&AckTimeoutTimer, 00951 RxWindow2Delay + ACK_TIMEOUT + randr(-ACK_TIMEOUT_RND, ACK_TIMEOUT_RND)); 00952 TimerStart(&AckTimeoutTimer); 00953 } 00954 } 00955 else { 00956 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK ; 00957 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT ; 00958 00959 if (LoRaMacFlags.Value == 0) { 00960 LoRaMacFlags.Bits.McpsReq = 1; 00961 } 00962 LoRaMacFlags.Bits.MacDone = 1; 00963 } 00964 00965 if (NodeAckRequested == false) { 00966 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK ; 00967 ChannelsNbRepCounter++; 00968 } 00969 } 00970 00971 static void PrepareRxDoneAbort(void) { 00972 LoRaMacState |= MAC_RX_ABORT; 00973 00974 if (NodeAckRequested) { 00975 OnAckTimeoutTimerEvent(); 00976 } 00977 00978 if ((RxSlot == 0) && (LoRaMacDeviceClass == CLASS_C )) { 00979 OnRxWindow2TimerEvent(); 00980 } 00981 00982 LoRaMacFlags.Bits.McpsInd = 1; 00983 LoRaMacFlags.Bits.MacDone = 1; 00984 00985 // Trig OnMacCheckTimerEvent call as soon as possible 00986 TimerSetValue(&MacStateCheckTimer, 1000); 00987 TimerStart(&MacStateCheckTimer); 00988 } 00989 00990 static void OnRadioRxDone(uint8_t* payload, uint16_t size, int16_t rssi, int8_t snr) { 00991 LoRaMacHeader_t macHdr; 00992 LoRaMacFrameCtrl_t fCtrl; 00993 bool skipIndication = false; 00994 00995 uint8_t pktHeaderLen = 0; 00996 uint32_t address = 0; 00997 uint8_t appPayloadStartIndex = 0; 00998 uint8_t port = 0xFF; 00999 uint8_t frameLen = 0; 01000 uint32_t mic = 0; 01001 uint32_t micRx = 0; 01002 01003 uint16_t sequenceCounter = 0; 01004 uint16_t sequenceCounterPrev = 0; 01005 uint16_t sequenceCounterDiff = 0; 01006 uint32_t downLinkCounter = 0; 01007 01008 MulticastParams_t * curMulticastParams = NULL; 01009 uint8_t* nwkSKey = LoRaMacNwkSKey; 01010 uint8_t* appSKey = LoRaMacAppSKey; 01011 01012 uint8_t multicast = 0; 01013 01014 bool isMicOk = false; 01015 01016 McpsConfirm.AckReceived = false; 01017 McpsIndication.Rssi = rssi; 01018 McpsIndication.Snr = snr; 01019 McpsIndication.RxSlot = RxSlot; 01020 McpsIndication.Port = 0; 01021 McpsIndication.Multicast = 0; 01022 McpsIndication.FramePending = 0; 01023 McpsIndication.Buffer = NULL; 01024 McpsIndication.BufferSize = 0; 01025 McpsIndication.RxData = false; 01026 McpsIndication.AckReceived = false; 01027 McpsIndication.DownLinkCounter = 0; 01028 McpsIndication.McpsIndication = MCPS_UNCONFIRMED ; 01029 01030 if (LoRaMacDeviceClass != CLASS_C ) { 01031 Radio.Sleep(); 01032 } 01033 TimerStop(&RxWindowTimer2); 01034 01035 macHdr.Value = payload[pktHeaderLen++]; 01036 01037 switch (macHdr.Bits.MType ) { 01038 case FRAME_TYPE_JOIN_ACCEPT : 01039 if (IsLoRaMacNetworkJoined == true) { 01040 break; 01041 } 01042 LoRaMacJoinDecrypt (payload + 1, size - 1, LoRaMacAppKey, LoRaMacRxPayload + 1); 01043 01044 LoRaMacRxPayload[0] = macHdr.Value ; 01045 01046 LoRaMacJoinComputeMic (LoRaMacRxPayload, size - LORAMAC_MFR_LEN, LoRaMacAppKey, &mic); 01047 01048 micRx |= (uint32_t)LoRaMacRxPayload[size - LORAMAC_MFR_LEN]; 01049 micRx |= ((uint32_t)LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 1] << 8); 01050 micRx |= ((uint32_t)LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 2] << 16); 01051 micRx |= ((uint32_t)LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 3] << 24); 01052 01053 if (micRx == mic) { 01054 LoRaMacJoinComputeSKeys (LoRaMacAppKey, LoRaMacRxPayload + 1, LoRaMacDevNonce, 01055 LoRaMacNwkSKey, LoRaMacAppSKey); 01056 01057 LoRaMacNetID = (uint32_t)LoRaMacRxPayload[4]; 01058 LoRaMacNetID |= ((uint32_t)LoRaMacRxPayload[5] << 8); 01059 LoRaMacNetID |= ((uint32_t)LoRaMacRxPayload[6] << 16); 01060 01061 LoRaMacDevAddr = (uint32_t)LoRaMacRxPayload[7]; 01062 LoRaMacDevAddr |= ((uint32_t)LoRaMacRxPayload[8] << 8); 01063 LoRaMacDevAddr |= ((uint32_t)LoRaMacRxPayload[9] << 16); 01064 LoRaMacDevAddr |= ((uint32_t)LoRaMacRxPayload[10] << 24); 01065 01066 // DLSettings 01067 Rx1DrOffset = (LoRaMacRxPayload[11] >> 4) & 0x07; 01068 Rx2Channel.Datarate = LoRaMacRxPayload[11] & 0x0F; 01069 // RxDelay 01070 ReceiveDelay1 = (LoRaMacRxPayload[12] & 0x0F); 01071 if (ReceiveDelay1 == 0) { 01072 ReceiveDelay1 = 1; 01073 } 01074 ReceiveDelay1 *= 1e6; 01075 ReceiveDelay2 = ReceiveDelay1 + 1e6; 01076 01077 #if !(defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID)) 01078 // CFList 01079 if ((size - 1) > 16) { 01080 ChannelParams_t param; 01081 param.DrRange .Value = (DR_5 << 4) | DR_0; 01082 01083 LoRaMacState |= MAC_TX_CONFIG; 01084 for (uint8_t i = 3, j = 0; i < (5 + 3); i++, j += 3) { 01085 param.Frequency = 01086 ((uint32_t)LoRaMacRxPayload[13 + j] | ((uint32_t)LoRaMacRxPayload[14 + j] << 8) | 01087 ((uint32_t)LoRaMacRxPayload[15 + j] << 16)) * 01088 100; 01089 LoRaMacChannelAdd(i, param); 01090 } 01091 LoRaMacState &= ~MAC_TX_CONFIG; 01092 } 01093 #endif 01094 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK ; 01095 IsLoRaMacNetworkJoined = true; 01096 01097 // Do not change the datarate 01098 // ChannelsDatarate = ChannelsDefaultDatarate; 01099 } 01100 else { 01101 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL ; 01102 } 01103 break; 01104 case FRAME_TYPE_DATA_CONFIRMED_DOWN : 01105 case FRAME_TYPE_DATA_UNCONFIRMED_DOWN : { 01106 address = payload[pktHeaderLen++]; 01107 address |= ((uint32_t)payload[pktHeaderLen++] << 8); 01108 address |= ((uint32_t)payload[pktHeaderLen++] << 16); 01109 address |= ((uint32_t)payload[pktHeaderLen++] << 24); 01110 01111 if (address != LoRaMacDevAddr) { 01112 curMulticastParams = MulticastChannels; 01113 while (curMulticastParams != NULL) { 01114 if (address == curMulticastParams->Address ) { 01115 multicast = 1; 01116 nwkSKey = curMulticastParams->NwkSKey ; 01117 appSKey = curMulticastParams->AppSKey ; 01118 downLinkCounter = curMulticastParams->DownLinkCounter ; 01119 break; 01120 } 01121 curMulticastParams = curMulticastParams->Next ; 01122 } 01123 if (multicast == 0) { 01124 // We are not the destination of this frame. 01125 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL ; 01126 PrepareRxDoneAbort(); 01127 return; 01128 } 01129 } 01130 else { 01131 multicast = 0; 01132 nwkSKey = LoRaMacNwkSKey; 01133 appSKey = LoRaMacAppSKey; 01134 downLinkCounter = DownLinkCounter; 01135 } 01136 01137 fCtrl.Value = payload[pktHeaderLen++]; 01138 01139 sequenceCounter = (uint16_t)payload[pktHeaderLen++]; 01140 sequenceCounter |= (uint16_t)payload[pktHeaderLen++] << 8; 01141 01142 appPayloadStartIndex = 8 + fCtrl.Bits.FOptsLen ; 01143 01144 micRx |= (uint32_t)payload[size - LORAMAC_MFR_LEN]; 01145 micRx |= ((uint32_t)payload[size - LORAMAC_MFR_LEN + 1] << 8); 01146 micRx |= ((uint32_t)payload[size - LORAMAC_MFR_LEN + 2] << 16); 01147 micRx |= ((uint32_t)payload[size - LORAMAC_MFR_LEN + 3] << 24); 01148 01149 sequenceCounterPrev = (uint16_t)downLinkCounter; 01150 sequenceCounterDiff = (sequenceCounter - sequenceCounterPrev); 01151 01152 if (sequenceCounterDiff < (1 << 15)) { 01153 downLinkCounter += sequenceCounterDiff; 01154 LoRaMacComputeMic(payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, 01155 downLinkCounter, &mic); 01156 if (micRx == mic) { 01157 isMicOk = true; 01158 } 01159 } 01160 else { 01161 // check for sequence roll-over 01162 uint32_t downLinkCounterTmp = downLinkCounter + 0x10000 + (int16_t)sequenceCounterDiff; 01163 LoRaMacComputeMic(payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, 01164 downLinkCounterTmp, &mic); 01165 if (micRx == mic) { 01166 isMicOk = true; 01167 downLinkCounter = downLinkCounterTmp; 01168 } 01169 } 01170 01171 // Check for a the maximum allowed counter difference 01172 if (sequenceCounterDiff >= MAX_FCNT_GAP) { 01173 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS ; 01174 McpsIndication.DownLinkCounter = downLinkCounter; 01175 PrepareRxDoneAbort(); 01176 return; 01177 } 01178 01179 if (isMicOk == true) { 01180 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_OK ; 01181 McpsIndication.Multicast = multicast; 01182 McpsIndication.FramePending = fCtrl.Bits.FPending ; 01183 McpsIndication.Buffer = NULL; 01184 McpsIndication.BufferSize = 0; 01185 McpsIndication.DownLinkCounter = downLinkCounter; 01186 01187 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK ; 01188 01189 MacCommandsBufferToRepeatIndex = 0; 01190 01191 // Update 32 bits downlink counter 01192 if (multicast == 1) { 01193 McpsIndication.McpsIndication = MCPS_MULTICAST ; 01194 01195 if ((curMulticastParams->DownLinkCounter == downLinkCounter) && 01196 (curMulticastParams->DownLinkCounter != 0)) { 01197 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED ; 01198 McpsIndication.DownLinkCounter = downLinkCounter; 01199 PrepareRxDoneAbort(); 01200 return; 01201 } 01202 curMulticastParams->DownLinkCounter = downLinkCounter; 01203 } 01204 else { 01205 if (macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN ) { 01206 SrvAckRequested = true; 01207 McpsIndication.McpsIndication = MCPS_CONFIRMED ; 01208 01209 if ((DownLinkCounter == downLinkCounter) && (DownLinkCounter != 0)) { 01210 // Duplicated confirmed downlink. Skip indication. 01211 skipIndication = true; 01212 } 01213 } 01214 else { 01215 SrvAckRequested = false; 01216 McpsIndication.McpsIndication = MCPS_UNCONFIRMED ; 01217 01218 if ((DownLinkCounter == downLinkCounter) && (DownLinkCounter != 0)) { 01219 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED ; 01220 McpsIndication.DownLinkCounter = downLinkCounter; 01221 PrepareRxDoneAbort(); 01222 return; 01223 } 01224 } 01225 DownLinkCounter = downLinkCounter; 01226 } 01227 01228 if (((size - 4) - appPayloadStartIndex) > 0) { 01229 port = payload[appPayloadStartIndex++]; 01230 frameLen = (size - 4) - appPayloadStartIndex; 01231 01232 McpsIndication.Port = port; 01233 01234 if (port == 0) { 01235 if (fCtrl.Bits.FOptsLen == 0) { 01236 LoRaMacPayloadDecrypt (payload + appPayloadStartIndex, frameLen, nwkSKey, address, 01237 DOWN_LINK, downLinkCounter, LoRaMacRxPayload); 01238 01239 // Decode frame payload MAC commands 01240 ProcessMacCommands(LoRaMacRxPayload, 0, frameLen, snr); 01241 } 01242 else { 01243 skipIndication = true; 01244 } 01245 } 01246 else { 01247 if (fCtrl.Bits.FOptsLen > 0) { 01248 // Decode Options field MAC commands. Omit the fPort. 01249 ProcessMacCommands(payload, 8, appPayloadStartIndex - 1, snr); 01250 } 01251 01252 LoRaMacPayloadDecrypt (payload + appPayloadStartIndex, frameLen, appSKey, address, 01253 DOWN_LINK, downLinkCounter, LoRaMacRxPayload); 01254 01255 if (skipIndication == false) { 01256 McpsIndication.Buffer = LoRaMacRxPayload; 01257 McpsIndication.BufferSize = frameLen; 01258 McpsIndication.RxData = true; 01259 } 01260 } 01261 } 01262 else { 01263 if (fCtrl.Bits.FOptsLen > 0) { 01264 // Decode Options field MAC commands 01265 ProcessMacCommands(payload, 8, appPayloadStartIndex, snr); 01266 } 01267 } 01268 01269 if (skipIndication == false) { 01270 // Check if the frame is an acknowledgement 01271 if (fCtrl.Bits.Ack == 1) { 01272 McpsConfirm.AckReceived = true; 01273 McpsIndication.AckReceived = true; 01274 01275 // Stop the AckTimeout timer as no more retransmissions 01276 // are needed. 01277 TimerStop(&AckTimeoutTimer); 01278 } 01279 else { 01280 McpsConfirm.AckReceived = false; 01281 01282 if (AckTimeoutRetriesCounter > AckTimeoutRetries) { 01283 // Stop the AckTimeout timer as no more retransmissions 01284 // are needed. 01285 TimerStop(&AckTimeoutTimer); 01286 } 01287 } 01288 LoRaMacFlags.Bits.McpsInd = 1; 01289 } 01290 } 01291 else { 01292 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL ; 01293 01294 PrepareRxDoneAbort(); 01295 return; 01296 } 01297 } break; 01298 case FRAME_TYPE_PROPRIETARY : { 01299 memcpy1(LoRaMacRxPayload, &payload[pktHeaderLen], size); 01300 01301 McpsIndication.McpsIndication = MCPS_PROPRIETARY ; 01302 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_OK ; 01303 McpsIndication.Buffer = LoRaMacRxPayload; 01304 McpsIndication.BufferSize = size - pktHeaderLen; 01305 01306 LoRaMacFlags.Bits.McpsInd = 1; 01307 break; 01308 } 01309 default: 01310 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 01311 PrepareRxDoneAbort(); 01312 break; 01313 } 01314 01315 if ((RxSlot == 0) && (LoRaMacDeviceClass == CLASS_C )) { 01316 OnRxWindow2TimerEvent(); 01317 } 01318 LoRaMacFlags.Bits.MacDone = 1; 01319 01320 // Trig OnMacCheckTimerEvent call as soon as possible 01321 TimerSetValue(&MacStateCheckTimer, 1000); 01322 TimerStart(&MacStateCheckTimer); 01323 } 01324 01325 static void OnRadioTxTimeout(void) { 01326 if (LoRaMacDeviceClass != CLASS_C ) { 01327 Radio.Sleep(); 01328 } 01329 else { 01330 OnRxWindow2TimerEvent(); 01331 } 01332 01333 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ; 01334 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ; 01335 LoRaMacFlags.Bits.MacDone = 1; 01336 } 01337 01338 static void OnRadioRxError(void) { 01339 if (LoRaMacDeviceClass != CLASS_C ) { 01340 Radio.Sleep(); 01341 } 01342 else { 01343 OnRxWindow2TimerEvent(); 01344 } 01345 01346 if (RxSlot == 1) { 01347 if (NodeAckRequested == true) { 01348 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR ; 01349 } 01350 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR ; 01351 LoRaMacFlags.Bits.MacDone = 1; 01352 } 01353 } 01354 01355 static void OnRadioRxTimeout(void) { 01356 if (LoRaMacDeviceClass != CLASS_C ) { 01357 Radio.Sleep(); 01358 } 01359 else { 01360 OnRxWindow2TimerEvent(); 01361 } 01362 01363 if (RxSlot == 1) { 01364 if (NodeAckRequested == true) { 01365 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT ; 01366 } 01367 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT ; 01368 LoRaMacFlags.Bits.MacDone = 1; 01369 } 01370 } 01371 01372 static void OnMacStateCheckTimerEvent(void) { 01373 TimerStop(&MacStateCheckTimer); 01374 bool txTimeout = false; 01375 bool txDone = false; 01376 01377 if (LoRaMacFlags.Bits.MacDone == 1) { 01378 if ((LoRaMacState & MAC_RX_ABORT) == MAC_RX_ABORT) { 01379 LoRaMacState &= ~MAC_RX_ABORT; 01380 LoRaMacState &= ~MAC_TX_RUNNING; 01381 } 01382 01383 if ((LoRaMacFlags.Bits.MlmeReq == 1) || ((LoRaMacFlags.Bits.McpsReq == 1))) { 01384 if ((McpsConfirm.Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) || 01385 (MlmeConfirm.Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT )) { 01386 // Stop transmit cycle due to tx timeout. 01387 LoRaMacState &= ~MAC_TX_RUNNING; 01388 McpsConfirm.NbRetries = AckTimeoutRetriesCounter; 01389 McpsConfirm.AckReceived = false; 01390 McpsConfirm.TxTimeOnAir = 0; 01391 txTimeout = true; 01392 } 01393 } 01394 01395 if ((NodeAckRequested == false) && (txTimeout == false)) { 01396 if (LoRaMacFlags.Bits.MlmeReq == 1) { 01397 if (MlmeConfirm.MlmeRequest == MLME_JOIN ) { 01398 if (MlmeConfirm.Status == LORAMAC_EVENT_INFO_STATUS_OK ) { 01399 UpLinkCounter = 0; 01400 } 01401 // Join messages aren't repeated automatically 01402 ChannelsNbRepCounter = ChannelsNbRep; 01403 } 01404 } 01405 if ((LoRaMacFlags.Bits.MlmeReq == 1) || ((LoRaMacFlags.Bits.McpsReq == 1))) { 01406 if ((ChannelsNbRepCounter >= ChannelsNbRep) || (LoRaMacFlags.Bits.McpsInd == 1)) { 01407 ChannelsNbRepCounter = 0; 01408 01409 txDone = true; 01410 LoRaMacState &= ~MAC_TX_RUNNING; 01411 } 01412 else { 01413 LoRaMacFlags.Bits.MacDone = 0; 01414 // Sends the same frame again 01415 ScheduleTx(); 01416 } 01417 } 01418 } 01419 01420 if (LoRaMacFlags.Bits.McpsInd == 1) { 01421 if ((McpsConfirm.AckReceived == true) || (AckTimeoutRetriesCounter > AckTimeoutRetries)) { 01422 AckTimeoutRetry = false; 01423 NodeAckRequested = false; 01424 txDone = true; 01425 McpsConfirm.NbRetries = AckTimeoutRetriesCounter; 01426 01427 LoRaMacState &= ~MAC_TX_RUNNING; 01428 } 01429 } 01430 01431 if ((AckTimeoutRetry == true) && ((LoRaMacState & MAC_TX_DELAYED) == 0)) { 01432 AckTimeoutRetry = false; 01433 if ((AckTimeoutRetriesCounter < AckTimeoutRetries) && 01434 (AckTimeoutRetriesCounter <= MAX_ACK_RETRIES)) { 01435 AckTimeoutRetriesCounter++; 01436 01437 if ((AckTimeoutRetriesCounter % 2) == 1) { 01438 ChannelsDatarate = MAX(ChannelsDatarate - 1, LORAMAC_TX_MIN_DATARATE); 01439 // Check if new datarate is valid for the Payload length 01440 if (ValidatePayloadLength(LoRaMacBufferPktLen - 13, ChannelsDatarate, 0) == false) { 01441 // If invalid payload length, then revert to previous datarate 01442 ChannelsDatarate++; 01443 } 01444 } 01445 LoRaMacFlags.Bits.MacDone = 0; 01446 // Sends the same frame again 01447 ScheduleTx(); 01448 } 01449 else { 01450 #if defined(USE_BAND_433) || defined(USE_BAND_780) || defined(USE_BAND_868) 01451 // Re-enable default channels LC1, LC2, LC3 01452 ChannelsMask[0] = ChannelsMask[0] | (LC(1) + LC(2) + LC(3)); 01453 #elif !defined(USE_BAND_915) && !defined(USE_BAND_915_HYBRID) 01454 #error "Please define a frequency band in the compiler options." 01455 #endif 01456 LoRaMacState &= ~MAC_TX_RUNNING; 01457 01458 NodeAckRequested = false; 01459 McpsConfirm.AckReceived = false; 01460 McpsConfirm.NbRetries = AckTimeoutRetriesCounter; 01461 txDone = true; 01462 } 01463 } 01464 01465 // Update uplink counter 01466 if ((txDone == true) && (IsUpLinkCounterFixed == false)) { 01467 UpLinkCounter++; 01468 01469 // Reset AdrAckCounter if downlink received 01470 if ((LoRaMacFlags.Bits.McpsInd == 1) || (UpLinkCounter == 1)) { 01471 AdrAckCounter = 0; 01472 } 01473 else { 01474 AdrAckCounter++; 01475 } 01476 } 01477 } 01478 // Handle reception for Class B and Class C 01479 if ((LoRaMacState & MAC_RX) == MAC_RX) { 01480 LoRaMacState &= ~MAC_RX; 01481 } 01482 01483 if (LoRaMacState == MAC_IDLE) { 01484 if (LoRaMacFlags.Bits.McpsReq == 1) { 01485 LoRaMacPrimitives->MacMcpsConfirm(&McpsConfirm); 01486 LoRaMacFlags.Bits.McpsReq = 0; 01487 } 01488 01489 if (LoRaMacFlags.Bits.MlmeReq == 1) { 01490 LoRaMacPrimitives->MacMlmeConfirm(&MlmeConfirm); 01491 LoRaMacFlags.Bits.MlmeReq = 0; 01492 } 01493 01494 LoRaMacFlags.Bits.MacDone = 0; 01495 } 01496 else { 01497 // Operation not finished restart timer 01498 TimerSetValue(&MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT); 01499 TimerStart(&MacStateCheckTimer); 01500 } 01501 01502 if (LoRaMacFlags.Bits.McpsInd == 1) { 01503 LoRaMacPrimitives->MacMcpsIndication(&McpsIndication); 01504 LoRaMacFlags.Bits.McpsInd = 0; 01505 } 01506 } 01507 01508 static void OnTxDelayedTimerEvent(void) { 01509 TimerStop(&TxDelayedTimer); 01510 LoRaMacState &= ~MAC_TX_DELAYED; 01511 01512 ScheduleTx(); 01513 } 01514 01515 static void OnRxWindow1TimerEvent(void) { 01516 uint16_t symbTimeout = 5; // DR_2, DR_1, DR_0 01517 int8_t datarate = 0; 01518 uint32_t bandwidth = 0; // LoRa 125 kHz 01519 01520 TimerStop(&RxWindowTimer1); 01521 RxSlot = 0; 01522 01523 if (LoRaMacDeviceClass == CLASS_C ) { 01524 Radio.Standby(); 01525 } 01526 01527 #if defined(USE_BAND_433) || defined(USE_BAND_780) || defined(USE_BAND_868) 01528 datarate = ChannelsDatarate - Rx1DrOffset; 01529 if (datarate < 0) { 01530 datarate = DR_0; 01531 } 01532 01533 // For higher datarates, we increase the number of symbols generating a Rx 01534 // Timeout 01535 if ((datarate == DR_3) || (datarate == DR_4)) { // DR_4, DR_3 01536 symbTimeout = 8; 01537 } 01538 else if (datarate == DR_5) { 01539 symbTimeout = 10; 01540 } 01541 else if (datarate == DR_6) { // LoRa 250 kHz 01542 bandwidth = 1; 01543 symbTimeout = 14; 01544 } 01545 RxWindowSetup(Channels[Channel].Frequency, datarate, bandwidth, symbTimeout, false); 01546 #elif (defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID)) 01547 datarate = datarateOffsets[ChannelsDatarate][Rx1DrOffset]; 01548 if (datarate < 0) { 01549 datarate = DR_0; 01550 } 01551 // For higher datarates, we increase the number of symbols generating a Rx 01552 // Timeout 01553 01554 symbTimeout = 10; 01555 // For low SF, we increase the number of symbols generating a Rx Timeout 01556 switch (datarate) { 01557 case DR_0: 01558 case DR_8: 01559 case DR_9: 01560 case DR_10: 01561 symbTimeout += 5; 01562 break; 01563 case DR_1: 01564 case DR_11: 01565 symbTimeout += 8; 01566 break; 01567 case DR_2: 01568 case DR_4: 01569 case DR_12: 01570 symbTimeout += 9; 01571 break; 01572 case DR_3: 01573 case DR_13: 01574 symbTimeout += 10; 01575 break; 01576 default: 01577 symbTimeout += 5; 01578 break; 01579 } 01580 01581 if (datarate >= DR_4) { // LoRa 500 kHz 01582 bandwidth = 2; 01583 } 01584 RxWindowSetup(923.3e6 + (Channel % 8) * 600e3, datarate, bandwidth, symbTimeout, false); 01585 #else 01586 #error "Please define a frequency band in the compiler options." 01587 #endif 01588 } 01589 01590 static void OnRxWindow2TimerEvent(void) { 01591 uint16_t symbTimeout = 5; // DR_2, DR_1, DR_0 01592 uint32_t bandwidth = 0; // LoRa 125 kHz 01593 01594 TimerStop(&RxWindowTimer2); 01595 RxSlot = 1; 01596 01597 #if defined(USE_BAND_433) || defined(USE_BAND_780) || defined(USE_BAND_868) 01598 // For higher datarates, we increase the number of symbols generating a Rx 01599 // Timeout 01600 if ((Rx2Channel.Datarate == DR_3) || (Rx2Channel.Datarate == DR_4)) { // DR_4, DR_3 01601 symbTimeout = 8; 01602 } 01603 else if (Rx2Channel.Datarate == DR_5) { 01604 symbTimeout = 10; 01605 } 01606 else if (Rx2Channel.Datarate == DR_6) { // LoRa 250 kHz 01607 bandwidth = 1; 01608 symbTimeout = 14; 01609 } 01610 #elif (defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID)) 01611 // For higher datarates, we increase the number of symbols generating a Rx 01612 // Timeout 01613 switch (Rx2Channel.Datarate ) { 01614 case DR_0: // SF10 - BW125 01615 symbTimeout = 5; 01616 break; 01617 01618 case DR_1: // SF9 - BW125 01619 case DR_2: // SF8 - BW125 01620 case DR_8: // SF12 - BW500 01621 case DR_9: // SF11 - BW500 01622 case DR_10: // SF10 - BW500 01623 symbTimeout = 8; 01624 break; 01625 01626 case DR_3: // SF7 - BW125 01627 case DR_11: // SF9 - BW500 01628 symbTimeout = 10; 01629 break; 01630 01631 case DR_4: // SF8 - BW500 01632 case DR_12: // SF8 - BW500 01633 symbTimeout = 14; 01634 break; 01635 01636 case DR_13: // SF7 - BW500 01637 symbTimeout = 16; 01638 break; 01639 default: 01640 break; 01641 } 01642 if (Rx2Channel.Datarate >= DR_4) { // LoRa 500 kHz 01643 bandwidth = 2; 01644 } 01645 #else 01646 #error "Please define a frequency band in the compiler options." 01647 #endif 01648 if (LoRaMacDeviceClass != CLASS_C ) { 01649 RxWindowSetup(Rx2Channel.Frequency , Rx2Channel.Datarate , bandwidth, symbTimeout, false); 01650 } 01651 else { 01652 RxWindowSetup(Rx2Channel.Frequency , Rx2Channel.Datarate , bandwidth, symbTimeout, true); 01653 } 01654 } 01655 01656 static void OnAckTimeoutTimerEvent(void) { 01657 TimerStop(&AckTimeoutTimer); 01658 01659 if (NodeAckRequested == true) { 01660 AckTimeoutRetry = true; 01661 LoRaMacState &= ~MAC_ACK_REQ; 01662 } 01663 if (LoRaMacDeviceClass == CLASS_C ) { 01664 LoRaMacFlags.Bits.MacDone = 1; 01665 } 01666 } 01667 01668 #if defined(USE_BAND_915) 01669 uint8_t GetNextJoinChannel(uint8_t* enabledChannels, uint8_t nbEnabledChannels) { 01670 int8_t channel = -1; 01671 uint8_t block; 01672 uint8_t i; 01673 01674 // Use 125KHz channel 01675 if (ChannelsDatarate < DR_4) { 01676 block = JoinBlock[NextJoinBlock]; 01677 NextJoinBlock = (NextJoinBlock + 1) % 8; 01678 01679 // If next block is greater than max block then randomly select the next 01680 // block 01681 if (block >= 8) 01682 block = randr(0, 7); 01683 01684 // Start search for next join channel at the selected block 01685 for (i = 0; (i < 8) && (channel == -1); i++) { 01686 uint8_t curBlock = (block + i) % 8; 01687 uint8_t chMask; 01688 01689 // Cycle through all blocks before using a previously used block 01690 if (((JoinBlocksRemaining & (1 << curBlock)) != 0)) { 01691 chMask = (ChannelsMaskRemaining[curBlock / 2] >> (curBlock & 1 ? 8 : 0)) & 0xff; 01692 if (chMask != 0) { 01693 channel = randr(0, 7); 01694 for (uint8_t i = 0; (i < 8); i++) { 01695 if ((chMask & (1 << channel)) != 0) { 01696 uint16_t chMaskTmp = (1 << channel); 01697 chMaskTmp = chMaskTmp << (curBlock & 1 ? 8 : 0); 01698 channel = channel + (curBlock * 8); 01699 JoinBlocksRemaining &= ~(1 << curBlock); 01700 ChannelsMaskRemaining[curBlock / 2] &= ~chMaskTmp; 01701 if ((JoinBlocksRemaining == 0)) { 01702 JoinBlocksRemaining = 0xFF; 01703 } 01704 break; 01705 } 01706 else { 01707 channel = (channel + 1) % 8; 01708 } 01709 } 01710 } 01711 } 01712 } 01713 01714 // No next channel case should never happen since ScheduleTx has already 01715 // checked for at least one enabled channel and if none re-enabled all 01716 // channels. 01717 // But if we find ourselves without a channel then randomly select one 01718 if (i >= 8) { 01719 channel = randr(0, 63); 01720 } 01721 } 01722 // Use 500 KHz channel 01723 else { 01724 channel = randr(0, 7); 01725 for (i = 0; i < 8; i++) { 01726 uint8_t curChannel = (channel + i) % 8; 01727 01728 if (((Join500KHzRemaining & (1 << curChannel)) != 0)) { 01729 Join500KHzRemaining &= ~(1 << curChannel); 01730 channel = 64 + curChannel; 01731 if (Join500KHzRemaining == 0) { 01732 Join500KHzRemaining = 0xFF; 01733 } 01734 break; 01735 } 01736 } 01737 } 01738 01739 for (i = 0; i < nbEnabledChannels; i++) { 01740 if (enabledChannels[i] == channel) 01741 break; 01742 } 01743 01744 if (i == nbEnabledChannels) { 01745 channel = enabledChannels[randr(0, nbEnabledChannels - 1)]; 01746 } 01747 01748 LastJoinBlock = channel / 8; 01749 01750 return channel; 01751 } 01752 #endif 01753 01754 static bool SetNextChannel(TimerTime_t* time) { 01755 uint8_t nbEnabledChannels = 0; 01756 uint8_t delayTx = 0; 01757 uint8_t enabledChannels[LORA_MAX_NB_CHANNELS]; 01758 TimerTime_t nextTxDelay = (TimerTime_t)(-1); 01759 01760 memset1(enabledChannels, 0, LORA_MAX_NB_CHANNELS); 01761 01762 #if defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 01763 if (CountNbEnabled125kHzChannels(ChannelsMaskRemaining) == 0) { // Restore default channels 01764 memcpy1((uint8_t*)ChannelsMaskRemaining, (uint8_t*)ChannelsMask, 8); 01765 } 01766 if ((ChannelsDatarate >= DR_4) && 01767 ((ChannelsMaskRemaining[4] & 0x00FF) == 0)) { // Make sure, that the channels are activated 01768 ChannelsMaskRemaining[4] = ChannelsMask[4]; 01769 } 01770 #else 01771 if (CountBits(ChannelsMask[0], 16) == 0) { 01772 // Re-enable default channels, if no channel is enabled 01773 ChannelsMask[0] = ChannelsMask[0] | (LC(1) + LC(2) + LC(3)); 01774 } 01775 #endif 01776 01777 // Update Aggregated duty cycle 01778 if (AggregatedTimeOff <= TimerGetElapsedTime(AggregatedLastTxDoneTime)) { 01779 AggregatedTimeOff = 0; 01780 01781 // Update bands Time OFF 01782 for (uint8_t i = 0; i < LORA_MAX_NB_BANDS; i++) { 01783 if (DutyCycleOn == true) { 01784 if (Bands[i].TimeOff <= TimerGetElapsedTime(Bands[i].LastTxDoneTime)) { 01785 Bands[i].TimeOff = 0; 01786 } 01787 if (Bands[i].TimeOff != 0) { 01788 nextTxDelay = 01789 MIN(Bands[i].TimeOff - TimerGetElapsedTime(Bands[i].LastTxDoneTime), nextTxDelay); 01790 } 01791 } 01792 else { 01793 nextTxDelay = 0; 01794 Bands[i].TimeOff = 0; 01795 } 01796 } 01797 01798 // Search how many channels are enabled 01799 for (uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++) { 01800 for (uint8_t j = 0; j < 16; j++) { 01801 #if defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 01802 if ((ChannelsMaskRemaining[k] & (1 << j)) != 0) 01803 #else 01804 if ((ChannelsMask[k] & (1 << j)) != 0) 01805 #endif 01806 { 01807 if (Channels[i + j].Frequency == 0) { // Check if the channel is enabled 01808 continue; 01809 } 01810 #if defined(USE_BAND_868) || defined(USE_BAND_433) || defined(USE_BAND_780) 01811 if (IsLoRaMacNetworkJoined == false) { 01812 if ((JOIN_CHANNELS & (1 << j)) == 0) { 01813 continue; 01814 } 01815 } 01816 #endif 01817 if (((Channels[i + j].DrRange.Fields.Min <= ChannelsDatarate) && 01818 (ChannelsDatarate <= Channels[i + j].DrRange .Fields.Max )) == 01819 false) { // Check if the current channel selection supports the 01820 // given datarate 01821 continue; 01822 } 01823 if (Bands[Channels[i + j].Band].TimeOff > 01824 0) { // Check if the band is available for transmission 01825 delayTx++; 01826 continue; 01827 } 01828 enabledChannels[nbEnabledChannels++] = i + j; 01829 } 01830 } 01831 } 01832 } 01833 else { 01834 delayTx++; 01835 nextTxDelay = AggregatedTimeOff - TimerGetElapsedTime(AggregatedLastTxDoneTime); 01836 } 01837 01838 if (nbEnabledChannels > 0) { 01839 #if defined(USE_BAND_915) 01840 if (IsLoRaMacNetworkJoined == false) { 01841 Channel = GetNextJoinChannel(enabledChannels, nbEnabledChannels); 01842 } 01843 // Send first uplink on channel from same sub-band as the join 01844 else if ((UpLinkCounter == 1) && (LastJoinBlock != -1)) { 01845 uint8_t i; 01846 uint8_t blockFirstChannel = LastJoinBlock * 8; 01847 01848 Channel = randr(blockFirstChannel, blockFirstChannel + 7); 01849 01850 // Check channel is enabled 01851 for (i = 0; i < nbEnabledChannels; i++) { 01852 if (Channel == enabledChannels[i]) 01853 break; 01854 } 01855 01856 // If channel is not enabled fallback to selecting from the list of 01857 // enabled channels 01858 if (i == nbEnabledChannels) { 01859 Channel = enabledChannels[randr(0, nbEnabledChannels - 1)]; 01860 } 01861 } 01862 else 01863 #endif 01864 { 01865 Channel = enabledChannels[randr(0, nbEnabledChannels - 1)]; 01866 } 01867 01868 #if defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 01869 if (Channel < (LORA_MAX_NB_CHANNELS - 8)) { 01870 DisableChannelInMask(Channel, ChannelsMaskRemaining); 01871 } 01872 #endif 01873 *time = 0; 01874 return true; 01875 } 01876 else { 01877 if (delayTx > 0) { 01878 // Delay transmission due to AggregatedTimeOff or to a band time off 01879 *time = nextTxDelay; 01880 return true; 01881 } 01882 // Datarate not supported by any channel 01883 *time = 0; 01884 return false; 01885 } 01886 } 01887 01888 static void SetPublicNetwork(bool enable) { 01889 PublicNetwork = enable; 01890 Radio.SetModem(MODEM_LORA); 01891 if (PublicNetwork == true) { 01892 // Change LoRa modem SyncWord 01893 Radio.Write(REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD); 01894 } 01895 else { 01896 // Change LoRa modem SyncWord 01897 Radio.Write(REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD); 01898 } 01899 } 01900 01901 static void RxWindowSetup(uint32_t freq, int8_t datarate, uint32_t bandwidth, uint16_t timeout, 01902 bool rxContinuous) { 01903 uint8_t downlinkDatarate = Datarates[datarate]; 01904 RadioModems_t modem; 01905 01906 if (Radio.GetStatus() == RF_IDLE) { 01907 Radio.SetChannel(freq); 01908 01909 // Store downlink datarate 01910 McpsIndication.RxDatarate = (uint8_t)datarate; 01911 01912 #if defined(USE_BAND_433) || defined(USE_BAND_780) || defined(USE_BAND_868) 01913 if (datarate == DR_7) { 01914 modem = MODEM_FSK; 01915 Radio.SetRxConfig(modem, 50e3, downlinkDatarate * 1e3, 0, 83.333e3, 5, 0, false, 0, true, 0, 01916 0, false, rxContinuous); 01917 } 01918 else { 01919 modem = MODEM_LORA; 01920 Radio.SetRxConfig(modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, 01921 true, rxContinuous); 01922 } 01923 #elif defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 01924 modem = MODEM_LORA; 01925 Radio.SetRxConfig(modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, 01926 true, rxContinuous); 01927 #endif 01928 01929 if (RepeaterSupport == true) { 01930 Radio.SetMaxPayloadLength( 01931 modem, MaxPayloadOfDatarateRepeater[datarate] + LORA_MAC_FRMPAYLOAD_OVERHEAD); 01932 } 01933 else { 01934 Radio.SetMaxPayloadLength(modem, 01935 MaxPayloadOfDatarate[datarate] + LORA_MAC_FRMPAYLOAD_OVERHEAD); 01936 } 01937 01938 if (rxContinuous == false) { 01939 Radio.Rx(MaxRxWindow); 01940 } 01941 else { 01942 Radio.Rx(0); // Continuous mode 01943 } 01944 } 01945 } 01946 01947 static bool Rx2FreqInRange(uint32_t freq) { 01948 #if defined(USE_BAND_433) || defined(USE_BAND_780) || defined(USE_BAND_868) 01949 if (Radio.CheckRfFrequency(freq) == true) 01950 #elif (defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID)) 01951 if ((Radio.CheckRfFrequency(freq) == true) && (freq >= LORAMAC_FIRST_RX2_CHANNEL) && 01952 (freq <= LORAMAC_LAST_RX2_CHANNEL) && (((freq - (uint32_t)LORAMAC_FIRST_RX2_CHANNEL) % 01953 (uint32_t)LORAMAC_STEPWIDTH_RX2_CHANNEL) == 0)) 01954 #endif 01955 { 01956 return true; 01957 } 01958 return false; 01959 } 01960 01961 static bool ValidatePayloadLength(uint8_t lenN, int8_t datarate, uint8_t fOptsLen) { 01962 uint16_t maxN = 0; 01963 uint16_t payloadSize = 0; 01964 01965 // Get the maximum payload length 01966 if (RepeaterSupport == true) { 01967 maxN = MaxPayloadOfDatarateRepeater[datarate]; 01968 } 01969 else { 01970 maxN = MaxPayloadOfDatarate[datarate]; 01971 } 01972 01973 // Calculate the resulting payload size 01974 payloadSize = (lenN + fOptsLen); 01975 01976 // Validation of the application payload size 01977 if ((payloadSize <= maxN) && (payloadSize <= LORAMAC_PHY_MAXPAYLOAD)) { 01978 return true; 01979 } 01980 return false; 01981 } 01982 01983 static uint8_t CountBits(uint16_t mask, uint8_t nbBits) { 01984 uint8_t nbActiveBits = 0; 01985 01986 for (uint8_t j = 0; j < nbBits; j++) { 01987 if ((mask & (1 << j)) == (1 << j)) { 01988 nbActiveBits++; 01989 } 01990 } 01991 return nbActiveBits; 01992 } 01993 01994 #if defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 01995 static uint8_t CountNbEnabled125kHzChannels(uint16_t* channelsMask) { 01996 uint8_t nb125kHzChannels = 0; 01997 01998 for (uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS - 8; i += 16, k++) { 01999 nb125kHzChannels += CountBits(channelsMask[k], 16); 02000 } 02001 02002 return nb125kHzChannels; 02003 } 02004 02005 #if defined(USE_BAND_915_HYBRID) 02006 static void ReenableChannels(uint16_t mask, uint16_t* channelMask) { 02007 uint16_t blockMask = mask; 02008 02009 for (uint8_t i = 0, j = 0; i < 4; i++, j += 2) { 02010 channelMask[i] = 0; 02011 if ((blockMask & (1 << j)) != 0) { 02012 channelMask[i] |= 0x00FF; 02013 } 02014 if ((blockMask & (1 << (j + 1))) != 0) { 02015 channelMask[i] |= 0xFF00; 02016 } 02017 } 02018 channelMask[4] = blockMask; 02019 channelMask[5] = 0x0000; 02020 } 02021 02022 static bool ValidateChannelMask(uint16_t* channelMask) { 02023 bool chanMaskState = false; 02024 uint16_t block1 = 0; 02025 uint16_t block2 = 0; 02026 uint8_t index = 0; 02027 02028 for (uint8_t i = 0; i < 4; i++) { 02029 block1 = channelMask[i] & 0x00FF; 02030 block2 = channelMask[i] & 0xFF00; 02031 02032 if ((CountBits(block1, 16) > 5) && (chanMaskState == false)) { 02033 channelMask[i] &= block1; 02034 channelMask[4] = 1 << (i * 2); 02035 chanMaskState = true; 02036 index = i; 02037 } 02038 else if ((CountBits(block2, 16) > 5) && (chanMaskState == false)) { 02039 channelMask[i] &= block2; 02040 channelMask[4] = 1 << (i * 2 + 1); 02041 chanMaskState = true; 02042 index = i; 02043 } 02044 } 02045 02046 // Do only change the channel mask, if we have found a valid block. 02047 if (chanMaskState == true) { 02048 for (uint8_t i = 0; i < 4; i++) { 02049 if (i != index) { 02050 channelMask[i] = 0; 02051 } 02052 } 02053 } 02054 return chanMaskState; 02055 } 02056 #endif 02057 #endif 02058 02059 static int8_t LimitTxPower(int8_t txPower) { 02060 int8_t resultTxPower = MAX(txPower, TX_POWER_30_DBM); 02061 02062 return resultTxPower; 02063 } 02064 02065 static bool ValueInRange(int8_t value, int8_t min, int8_t max) { 02066 if ((value >= min) && (value <= max)) { 02067 return true; 02068 } 02069 return false; 02070 } 02071 02072 static bool DisableChannelInMask(uint8_t id, uint16_t* mask) { 02073 uint8_t index = 0; 02074 index = id / 16; 02075 02076 if ((index > 4) || (id >= LORA_MAX_NB_CHANNELS)) { 02077 return false; 02078 } 02079 02080 // Deactivate channel 02081 mask[index] &= ~(1 << (id % 16)); 02082 02083 return true; 02084 } 02085 02086 static bool AdrNextDr(bool adrEnabled, bool isTx, int8_t* datarateOut, int8_t* txpowerOut) { 02087 bool adrAckReq = false; 02088 int8_t datarate = ChannelsDatarate; 02089 int8_t txpower = ChannelsTxPower; 02090 02091 if (adrEnabled == true) { 02092 /* Request ADR Ack Request (including at lowest available datarate) */ 02093 adrAckReq = AdrAckCounter >= ADR_ACK_LIMIT ? true : false; 02094 02095 if (AdrAckCounter >= (ADR_ACK_LIMIT + ADR_ACK_DELAY)) { 02096 // Step up power 02097 txpower = LORAMAC_DEFAULT_TX_POWER; 02098 02099 if ((AdrAckCounter % ADR_ACK_DELAY) == 0) { 02100 #if defined(USE_BAND_433) || defined(USE_BAND_780) || defined(USE_BAND_868) 02101 if (datarate > LORAMAC_TX_MIN_DATARATE) { 02102 datarate--; 02103 } 02104 02105 if (datarate == LORAMAC_TX_MIN_DATARATE) { 02106 if (isTx == true) { 02107 // Re-enable default channels LC1, LC2, LC3 02108 ChannelsMask[0] = ChannelsMask[0] | (LC(1) + LC(2) + LC(3)); 02109 } 02110 } 02111 #elif defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 02112 if (datarate > LORAMAC_TX_MIN_DATARATE) { 02113 if (datarate == DR_8) 02114 datarate = DR_4; 02115 else 02116 datarate--; 02117 } 02118 else if (isTx == true) { 02119 #if defined(USE_BAND_915) 02120 // Re-enable default channels 02121 ChannelsMask[0] = 0xFFFF; 02122 ChannelsMask[1] = 0xFFFF; 02123 ChannelsMask[2] = 0xFFFF; 02124 ChannelsMask[3] = 0xFFFF; 02125 ChannelsMask[4] = 0x00FF; 02126 ChannelsMask[5] = 0x0000; 02127 #else // defined( USE_BAND_915_HYBRID ) 02128 // Re-enable default channels 02129 ChannelsMask[0] = 0x00FF; 02130 ChannelsMask[1] = 0x0000; 02131 ChannelsMask[2] = 0x0000; 02132 ChannelsMask[3] = 0x0000; 02133 ChannelsMask[4] = 0x0001; 02134 ChannelsMask[5] = 0x0000; 02135 #endif 02136 } 02137 #else 02138 #error "Please define a frequency band in the compiler options." 02139 #endif 02140 } 02141 } 02142 } 02143 02144 if (datarateOut != NULL) 02145 *datarateOut = datarate; 02146 02147 if (txpowerOut != NULL) 02148 *txpowerOut = txpower; 02149 02150 return adrAckReq; 02151 } 02152 02153 static LoRaMacStatus_t AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p2) { 02154 LoRaMacStatus_t status = LORAMAC_STATUS_BUSY ; 02155 // The maximum buffer length must take MAC commands to re-send into account. 02156 uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH - MacCommandsBufferToRepeatIndex; 02157 02158 switch (cmd) { 02159 case MOTE_MAC_LINK_CHECK_REQ : 02160 if (MacCommandsBufferIndex < bufLen) { 02161 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02162 // No payload for this command 02163 status = LORAMAC_STATUS_OK ; 02164 } 02165 break; 02166 case MOTE_MAC_LINK_ADR_ANS : 02167 if (MacCommandsBufferIndex < (bufLen - 1)) { 02168 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02169 // Margin 02170 MacCommandsBuffer[MacCommandsBufferIndex++] = p1; 02171 status = LORAMAC_STATUS_OK ; 02172 } 02173 break; 02174 case MOTE_MAC_DUTY_CYCLE_ANS : 02175 if (MacCommandsBufferIndex < bufLen) { 02176 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02177 // No payload for this answer 02178 status = LORAMAC_STATUS_OK ; 02179 } 02180 break; 02181 case MOTE_MAC_RX_PARAM_SETUP_ANS : 02182 if (MacCommandsBufferIndex < (bufLen - 1)) { 02183 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02184 // Status: Datarate ACK, Channel ACK 02185 MacCommandsBuffer[MacCommandsBufferIndex++] = p1; 02186 status = LORAMAC_STATUS_OK ; 02187 } 02188 break; 02189 case MOTE_MAC_DEV_STATUS_ANS : 02190 if (MacCommandsBufferIndex < (bufLen - 2)) { 02191 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02192 // 1st byte Battery 02193 // 2nd byte Margin 02194 MacCommandsBuffer[MacCommandsBufferIndex++] = p1; 02195 MacCommandsBuffer[MacCommandsBufferIndex++] = p2; 02196 status = LORAMAC_STATUS_OK ; 02197 } 02198 break; 02199 case MOTE_MAC_NEW_CHANNEL_ANS : 02200 if (MacCommandsBufferIndex < (bufLen - 1)) { 02201 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02202 // Status: Datarate range OK, Channel frequency OK 02203 MacCommandsBuffer[MacCommandsBufferIndex++] = p1; 02204 status = LORAMAC_STATUS_OK ; 02205 } 02206 break; 02207 case MOTE_MAC_RX_TIMING_SETUP_ANS : 02208 if (MacCommandsBufferIndex < bufLen) { 02209 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02210 // No payload for this answer 02211 status = LORAMAC_STATUS_OK ; 02212 } 02213 break; 02214 default: 02215 return LORAMAC_STATUS_SERVICE_UNKNOWN ; 02216 } 02217 if (status == LORAMAC_STATUS_OK ) { 02218 MacCommandsInNextTx = true; 02219 } 02220 return status; 02221 } 02222 02223 static uint8_t ParseMacCommandsToRepeat(uint8_t* cmdBufIn, uint8_t length, uint8_t* cmdBufOut) { 02224 uint8_t i = 0; 02225 uint8_t cmdCount = 0; 02226 02227 if ((cmdBufIn == NULL) || (cmdBufOut == NULL)) { 02228 return 0; 02229 } 02230 02231 for (i = 0; i < length; i++) { 02232 switch (cmdBufIn[i]) { 02233 case MOTE_MAC_RX_PARAM_SETUP_ANS : { 02234 cmdBufOut[cmdCount++] = cmdBufIn[i++]; 02235 cmdBufOut[cmdCount++] = cmdBufIn[i++]; 02236 cmdBufOut[cmdCount++] = cmdBufIn[i]; 02237 break; 02238 } 02239 case MOTE_MAC_RX_TIMING_SETUP_ANS : { 02240 cmdBufOut[cmdCount++] = cmdBufIn[i]; 02241 break; 02242 } 02243 default: 02244 break; 02245 } 02246 } 02247 02248 return cmdCount; 02249 } 02250 02251 static void ProcessMacCommands(uint8_t* payload, uint8_t macIndex, uint8_t commandsSize, 02252 uint8_t snr) { 02253 uint8_t validLinkAdrCmds = 0; 02254 int8_t txPower = 0; 02255 int8_t datarate = 0; 02256 uint8_t nbRep = 0; 02257 uint16_t channelsMask[6] = {0, 0, 0, 0, 0, 0}; 02258 uint8_t LinkAdrMacCmdBufferIndex = 0; 02259 02260 while (macIndex < commandsSize) { 02261 // Decode Frame MAC commands 02262 switch (payload[macIndex++]) { 02263 case SRV_MAC_LINK_CHECK_ANS : 02264 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK ; 02265 MlmeConfirm.DemodMargin = payload[macIndex++]; 02266 MlmeConfirm.NbGateways = payload[macIndex++]; 02267 break; 02268 case SRV_MAC_LINK_ADR_REQ : { 02269 uint8_t chMaskCntl = 0; 02270 uint8_t status = 0x07; 02271 uint16_t chMask; 02272 02273 datarate = payload[macIndex++]; 02274 txPower = datarate & 0x0F; 02275 datarate = (datarate >> 4) & 0x0F; 02276 02277 if ((AdrCtrlOn == false) && 02278 ((ChannelsDatarate != datarate) || 02279 (ChannelsTxPower != txPower))) { // ADR disabled don't handle ADR 02280 // requests if server tries to 02281 // change datarate or txpower 02282 // Answer the server with fail status 02283 // Power ACK = 0 02284 // Data rate ACK = 0 02285 // Channel mask = 0 02286 AddMacCommand(MOTE_MAC_LINK_ADR_ANS , 0, 0); 02287 macIndex += 3; // Skip over the remaining bytes of the request 02288 break; 02289 } 02290 else if (validLinkAdrCmds++ == 0) { 02291 // Initialize local copy of the channels mask array 02292 for (uint8_t i = 0; i < 6; i++) { 02293 channelsMask[i] = ChannelsMask[i]; 02294 } 02295 } 02296 02297 chMask = (uint16_t)payload[macIndex++]; 02298 chMask |= (uint16_t)payload[macIndex++] << 8; 02299 02300 nbRep = payload[macIndex++]; 02301 chMaskCntl = (nbRep >> 4) & 0x07; 02302 nbRep &= 0x0F; 02303 if (nbRep == 0) { 02304 nbRep = 1; 02305 } 02306 #if defined(USE_BAND_433) || defined(USE_BAND_780) || defined(USE_BAND_868) 02307 if ((chMaskCntl == 0) && (chMask == 0)) { 02308 status &= 0xFE; // Channel mask KO 02309 } 02310 else if (((chMaskCntl >= 1) && (chMaskCntl <= 5)) || (chMaskCntl >= 7)) { 02311 // RFU 02312 status &= 0xFE; // Channel mask KO 02313 } 02314 else { 02315 for (i = 0; i < LORA_MAX_NB_CHANNELS; i++) { 02316 if (chMaskCntl == 6) { 02317 if (Channels[i].Frequency != 0) { 02318 chMask |= 1 << i; 02319 } 02320 } 02321 else { 02322 if (((chMask & (1 << i)) != 0) && 02323 (Channels[i].Frequency == 0)) { // Trying to enable an undefined channel 02324 status &= 0xFE; // Channel mask KO 02325 } 02326 } 02327 } 02328 channelsMask[0] = chMask; 02329 } 02330 #elif defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 02331 if (chMaskCntl < 4) { 02332 channelsMask[chMaskCntl] = chMask; 02333 } 02334 else if (chMaskCntl == 6) { 02335 // Enable all 125 kHz channels 02336 for (uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS - 8; i += 16, k++) { 02337 for (uint8_t j = 0; j < 16; j++) { 02338 if (Channels[i + j].Frequency != 0) { 02339 channelsMask[k] |= 1 << j; 02340 } 02341 } 02342 } 02343 // channel mask applied to 500 kHz channels 02344 channelsMask[4] = chMask; 02345 } 02346 else if (chMaskCntl == 7) { 02347 // Disable all 125 kHz channels 02348 channelsMask[0] = 0x0000; 02349 channelsMask[1] = 0x0000; 02350 channelsMask[2] = 0x0000; 02351 channelsMask[3] = 0x0000; 02352 02353 // channel mask applied to 500 kHz channels 02354 channelsMask[4] = chMask; 02355 } 02356 else { 02357 // RFU 02358 status &= 0xFE; // Channel mask KO 02359 } 02360 #else 02361 #error "Please define a frequency band in the compiler options." 02362 #endif 02363 if (ValueInRange(datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE) == false) { 02364 status &= 0xFD; // Datarate KO 02365 } 02366 02367 // 02368 // Remark MaxTxPower = 0 and MinTxPower = 5 02369 // 02370 if (ValueInRange(txPower, LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER) == false) { 02371 status &= 0xFB; // TxPower KO 02372 } 02373 02374 // Save the mac command status location for possible channel mask KO 02375 // later 02376 LinkAdrMacCmdBufferIndex = MacCommandsBufferIndex; 02377 02378 AddMacCommand(MOTE_MAC_LINK_ADR_ANS , status, 0); 02379 } break; 02380 case SRV_MAC_DUTY_CYCLE_REQ : 02381 MaxDCycle = payload[macIndex++]; 02382 AggregatedDCycle = 1 << MaxDCycle; 02383 AddMacCommand(MOTE_MAC_DUTY_CYCLE_ANS , 0, 0); 02384 break; 02385 case SRV_MAC_RX_PARAM_SETUP_REQ : { 02386 uint8_t status = 0x07; 02387 int8_t datarate = 0; 02388 int8_t drOffset = 0; 02389 uint32_t freq = 0; 02390 02391 drOffset = (payload[macIndex] >> 4) & 0x07; 02392 datarate = payload[macIndex] & 0x0F; 02393 macIndex++; 02394 02395 freq = (uint32_t)payload[macIndex++]; 02396 freq |= (uint32_t)payload[macIndex++] << 8; 02397 freq |= (uint32_t)payload[macIndex++] << 16; 02398 freq *= 100; 02399 02400 if (Rx2FreqInRange(freq) == false) { 02401 status &= 0xFE; // Channel frequency KO 02402 } 02403 02404 if (ValueInRange(datarate, LORAMAC_RX_MIN_DATARATE, LORAMAC_RX_MAX_DATARATE) == false) { 02405 status &= 0xFD; // Datarate KO 02406 } 02407 #if (defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID)) 02408 if ((ValueInRange(datarate, DR_5, DR_7) == true) || (datarate > DR_13)) { 02409 status &= 0xFD; // Datarate KO 02410 } 02411 #endif 02412 if (ValueInRange(drOffset, LORAMAC_MIN_RX1_DR_OFFSET, LORAMAC_MAX_RX1_DR_OFFSET) == false) { 02413 status &= 0xFB; // Rx1DrOffset range KO 02414 } 02415 02416 if ((status & 0x07) == 0x07) { 02417 Rx2Channel.Datarate = datarate; 02418 Rx2Channel.Frequency = freq; 02419 Rx1DrOffset = drOffset; 02420 } 02421 AddMacCommand(MOTE_MAC_RX_PARAM_SETUP_ANS , status, 0); 02422 } break; 02423 case SRV_MAC_DEV_STATUS_REQ : { 02424 uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE ; 02425 if ((LoRaMacCallbacks != NULL) && (LoRaMacCallbacks->GetBatteryLevel != NULL)) { 02426 batteryLevel = LoRaMacCallbacks->GetBatteryLevel(); 02427 } 02428 AddMacCommand(MOTE_MAC_DEV_STATUS_ANS , batteryLevel, snr); 02429 break; 02430 } 02431 case SRV_MAC_NEW_CHANNEL_REQ : { 02432 uint8_t status = 0x03; 02433 02434 #if (defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID)) 02435 status &= 0xFC; // Channel frequency and datarate KO 02436 macIndex += 5; 02437 #else 02438 int8_t channelIndex = 0; 02439 ChannelParams_t chParam; 02440 02441 channelIndex = payload[macIndex++]; 02442 chParam.Frequency = (uint32_t)payload[macIndex++]; 02443 chParam.Frequency |= (uint32_t)payload[macIndex++] << 8; 02444 chParam.Frequency |= (uint32_t)payload[macIndex++] << 16; 02445 chParam.Frequency *= 100; 02446 chParam.DrRange .Value = payload[macIndex++]; 02447 02448 LoRaMacState |= MAC_TX_CONFIG; 02449 if (chParam.Frequency == 0) { 02450 if (channelIndex < 3) { 02451 status &= 0xFC; 02452 } 02453 else { 02454 if (LoRaMacChannelRemove(channelIndex) != LORAMAC_STATUS_OK ) { 02455 status &= 0xFC; 02456 } 02457 } 02458 } 02459 else { 02460 switch (LoRaMacChannelAdd(channelIndex, chParam)) { 02461 case LORAMAC_STATUS_OK : { 02462 break; 02463 } 02464 case LORAMAC_STATUS_FREQUENCY_INVALID : { 02465 status &= 0xFE; 02466 break; 02467 } 02468 case LORAMAC_STATUS_DATARATE_INVALID : { 02469 status &= 0xFD; 02470 break; 02471 } 02472 case LORAMAC_STATUS_FREQ_AND_DR_INVALID : { 02473 status &= 0xFC; 02474 break; 02475 } 02476 default: { 02477 status &= 0xFC; 02478 break; 02479 } 02480 } 02481 } 02482 LoRaMacState &= ~MAC_TX_CONFIG; 02483 #endif 02484 AddMacCommand(MOTE_MAC_NEW_CHANNEL_ANS , status, 0); 02485 } break; 02486 case SRV_MAC_RX_TIMING_SETUP_REQ : { 02487 uint8_t delay = payload[macIndex++] & 0x0F; 02488 02489 if (delay == 0) { 02490 delay++; 02491 } 02492 ReceiveDelay1 = delay * 1e6; 02493 ReceiveDelay2 = ReceiveDelay1 + 1e6; 02494 AddMacCommand(MOTE_MAC_RX_TIMING_SETUP_ANS , 0, 0); 02495 } break; 02496 default: 02497 // Unknown command. ABORT MAC commands processing 02498 return; 02499 } 02500 } 02501 02502 // Process accumulated Link ADR channel mask changes 02503 if (validLinkAdrCmds > 0) { 02504 uint8_t drOkCounter = 0; 02505 uint8_t status = 0x07; 02506 02507 #if defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 02508 for (uint8_t i = 0; i < 6; i++) { 02509 for (uint8_t j = 0; j < 16; j++) { 02510 if ((channelsMask[i] & (1 << j)) != 0) { 02511 if ((Channels[i * 16 + j].Frequency == 0)) { 02512 status &= 0xFE; // Channel mask KO 02513 break; 02514 } 02515 else if ((datarate >= Channels[i * 16 + j].DrRange.Fields.Min) && 02516 (datarate <= Channels[i * 16 + j].DrRange .Fields.Max )) { 02517 drOkCounter++; 02518 } 02519 } 02520 } 02521 } 02522 02523 if (drOkCounter == 0) { 02524 status &= 0xFD; // Datarate KO 02525 } 02526 02527 if ((CountNbEnabled125kHzChannels(channelsMask) > 0) && 02528 (CountNbEnabled125kHzChannels(channelsMask) < HYBRD_CHNLS_MIN)) { 02529 status &= 0xFE; // Channel mask KO 02530 } 02531 02532 #if defined(USE_BAND_915_HYBRID) 02533 if (ValidateChannelMask(channelsMask) == false) { 02534 status &= 0xFE; // Channel mask KO 02535 } 02536 #endif 02537 02538 #endif 02539 if ((status & 0x07) == 0x07) { 02540 ChannelsDatarate = datarate; 02541 ChannelsDefaultDatarate = datarate; 02542 ChannelsTxPower = txPower; 02543 02544 ChannelsMask[0] = channelsMask[0]; 02545 ChannelsMask[1] = channelsMask[1]; 02546 ChannelsMask[2] = channelsMask[2]; 02547 ChannelsMask[3] = channelsMask[3]; 02548 ChannelsMask[4] = channelsMask[4]; 02549 ChannelsMask[5] = channelsMask[5]; 02550 02551 ChannelsNbRep = nbRep; 02552 02553 // Clear remaining channels mask 02554 memcpy1((uint8_t*)ChannelsMaskRemaining, (uint8_t*)ChannelsMask, 10); 02555 } 02556 // Channel Mask KO 02557 else { 02558 // Update the last Link ADR status with channel mask KO 02559 if ((LinkAdrMacCmdBufferIndex + 1) < LORA_MAC_COMMAND_MAX_LENGTH) 02560 MacCommandsBuffer[LinkAdrMacCmdBufferIndex + 1] &= status; 02561 } 02562 } 02563 } 02564 02565 LoRaMacStatus_t Send(LoRaMacHeader_t * macHdr, uint8_t fPort, void* fBuffer, uint16_t fBufferSize) { 02566 LoRaMacFrameCtrl_t fCtrl; 02567 LoRaMacStatus_t status = LORAMAC_STATUS_PARAMETER_INVALID ; 02568 02569 fCtrl.Value = 0; 02570 fCtrl.Bits.FOptsLen = 0; 02571 fCtrl.Bits.FPending = 0; 02572 fCtrl.Bits.Ack = false; 02573 fCtrl.Bits.AdrAckReq = false; 02574 fCtrl.Bits.Adr = AdrCtrlOn; 02575 02576 // Prepare the frame 02577 status = PrepareFrame(macHdr, &fCtrl, fPort, fBuffer, fBufferSize); 02578 02579 // Validate status 02580 if (status != LORAMAC_STATUS_OK ) { 02581 return status; 02582 } 02583 02584 // Reset confirm parameters 02585 McpsConfirm.NbRetries = 0; 02586 McpsConfirm.AckReceived = false; 02587 McpsConfirm.UpLinkCounter = UpLinkCounter; 02588 02589 status = ScheduleTx(); 02590 02591 return status; 02592 } 02593 02594 static LoRaMacStatus_t ScheduleTx() { 02595 TimerTime_t dutyCycleTimeOff = 0; 02596 02597 // Check if the device is off 02598 if (MaxDCycle == 255) { 02599 return LORAMAC_STATUS_DEVICE_OFF ; 02600 } 02601 if (MaxDCycle == 0) { 02602 AggregatedTimeOff = 0; 02603 } 02604 02605 CalculateBackOff(LastTxChannel); 02606 02607 // Select channel 02608 while (SetNextChannel(&dutyCycleTimeOff) == false) { 02609 // Set the default datarate 02610 ChannelsDatarate = ChannelsDefaultDatarate; 02611 02612 #if defined(USE_BAND_433) || defined(USE_BAND_780) || defined(USE_BAND_868) 02613 // Re-enable default channels LC1, LC2, LC3 02614 ChannelsMask[0] = ChannelsMask[0] | (LC(1) + LC(2) + LC(3)); 02615 #endif 02616 } 02617 02618 // Schedule transmission of frame 02619 if (dutyCycleTimeOff == 0) { 02620 // Try to send now 02621 return SendFrameOnChannel(Channels[Channel]); 02622 } 02623 else { 02624 // Send later - prepare timer 02625 LoRaMacState |= MAC_TX_DELAYED; 02626 TimerSetValue(&TxDelayedTimer, dutyCycleTimeOff); 02627 TimerStart(&TxDelayedTimer); 02628 02629 return LORAMAC_STATUS_OK ; 02630 } 02631 } 02632 02633 static void CalculateBackOff(uint8_t channel) { 02634 uint16_t dutyCycle = Bands[Channels[channel].Band ].DCycle ; 02635 02636 if (IsLoRaMacNetworkJoined == false) { 02637 #if defined(USE_BAND_868) || defined(USE_BAND_433) || defined(USE_BAND_780) 02638 dutyCycle = JOIN_DC; 02639 #endif 02640 } 02641 02642 // Update Band Time OFF 02643 if (DutyCycleOn == true) { 02644 Bands[Channels[channel].Band ].TimeOff = TxTimeOnAir * dutyCycle - TxTimeOnAir; 02645 } 02646 else { 02647 Bands[Channels[channel].Band ].TimeOff = 0; 02648 } 02649 // Update Aggregated Time OFF 02650 AggregatedTimeOff = AggregatedTimeOff + (TxTimeOnAir * AggregatedDCycle - TxTimeOnAir); 02651 } 02652 02653 LoRaMacStatus_t PrepareFrame(LoRaMacHeader_t * macHdr, LoRaMacFrameCtrl_t * fCtrl, uint8_t fPort, 02654 void* fBuffer, uint16_t fBufferSize) { 02655 uint16_t i; 02656 uint8_t pktHeaderLen = 0; 02657 uint32_t mic = 0; 02658 const void* payload = fBuffer; 02659 uint8_t payloadSize = fBufferSize; 02660 uint8_t framePort = fPort; 02661 02662 LoRaMacBufferPktLen = 0; 02663 02664 NodeAckRequested = false; 02665 02666 if (fBuffer == NULL) { 02667 fBufferSize = 0; 02668 } 02669 02670 LoRaMacBuffer[pktHeaderLen++] = macHdr->Value ; 02671 02672 switch (macHdr->Bits.MType ) { 02673 case FRAME_TYPE_JOIN_REQ : 02674 RxWindow1Delay = JoinAcceptDelay1 - RADIO_WAKEUP_TIME; 02675 RxWindow2Delay = JoinAcceptDelay2 - RADIO_WAKEUP_TIME; 02676 02677 LoRaMacBufferPktLen = pktHeaderLen; 02678 02679 memcpyr(LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacAppEui, 8); 02680 LoRaMacBufferPktLen += 8; 02681 memcpyr(LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacDevEui, 8); 02682 LoRaMacBufferPktLen += 8; 02683 02684 LoRaMacDevNonce = Radio.Random(); 02685 02686 LoRaMacBuffer[LoRaMacBufferPktLen++] = LoRaMacDevNonce & 0xFF; 02687 LoRaMacBuffer[LoRaMacBufferPktLen++] = (LoRaMacDevNonce >> 8) & 0xFF; 02688 02689 LoRaMacJoinComputeMic (LoRaMacBuffer, LoRaMacBufferPktLen & 0xFF, LoRaMacAppKey, &mic); 02690 02691 LoRaMacBuffer[LoRaMacBufferPktLen++] = mic & 0xFF; 02692 LoRaMacBuffer[LoRaMacBufferPktLen++] = (mic >> 8) & 0xFF; 02693 LoRaMacBuffer[LoRaMacBufferPktLen++] = (mic >> 16) & 0xFF; 02694 LoRaMacBuffer[LoRaMacBufferPktLen++] = (mic >> 24) & 0xFF; 02695 02696 break; 02697 case FRAME_TYPE_DATA_CONFIRMED_UP : 02698 NodeAckRequested = true; 02699 // Intentional falltrough 02700 case FRAME_TYPE_DATA_UNCONFIRMED_UP : 02701 if (IsLoRaMacNetworkJoined == false) { 02702 return LORAMAC_STATUS_NO_NETWORK_JOINED ; // No network has been joined 02703 // yet 02704 } 02705 02706 fCtrl->Bits.AdrAckReq = AdrNextDr(fCtrl->Bits.Adr , true, &ChannelsDatarate, &ChannelsTxPower); 02707 02708 if (ValidatePayloadLength(fBufferSize, ChannelsDatarate, MacCommandsBufferIndex) == false) { 02709 return LORAMAC_STATUS_LENGTH_ERROR ; 02710 } 02711 02712 RxWindow1Delay = ReceiveDelay1 - RADIO_WAKEUP_TIME; 02713 RxWindow2Delay = ReceiveDelay2 - RADIO_WAKEUP_TIME; 02714 02715 if (SrvAckRequested == true) { 02716 SrvAckRequested = false; 02717 fCtrl->Bits.Ack = 1; 02718 } 02719 02720 LoRaMacBuffer[pktHeaderLen++] = (LoRaMacDevAddr)&0xFF; 02721 LoRaMacBuffer[pktHeaderLen++] = (LoRaMacDevAddr >> 8) & 0xFF; 02722 LoRaMacBuffer[pktHeaderLen++] = (LoRaMacDevAddr >> 16) & 0xFF; 02723 LoRaMacBuffer[pktHeaderLen++] = (LoRaMacDevAddr >> 24) & 0xFF; 02724 02725 LoRaMacBuffer[pktHeaderLen++] = fCtrl->Value ; 02726 02727 LoRaMacBuffer[pktHeaderLen++] = UpLinkCounter & 0xFF; 02728 LoRaMacBuffer[pktHeaderLen++] = (UpLinkCounter >> 8) & 0xFF; 02729 02730 // Copy the MAC commands which must be re-send into the MAC command buffer 02731 memcpy1(&MacCommandsBuffer[MacCommandsBufferIndex], MacCommandsBufferToRepeat, 02732 MacCommandsBufferToRepeatIndex); 02733 MacCommandsBufferIndex += MacCommandsBufferToRepeatIndex; 02734 02735 if ((payload != NULL) && (payloadSize > 0)) { 02736 if ((MacCommandsBufferIndex <= LORA_MAC_COMMAND_MAX_LENGTH) && 02737 (MacCommandsInNextTx == true)) { 02738 fCtrl->Bits.FOptsLen += MacCommandsBufferIndex; 02739 02740 // Update FCtrl field with new value of OptionsLength 02741 LoRaMacBuffer[0x05] = fCtrl->Value ; 02742 for (i = 0; i < MacCommandsBufferIndex; i++) { 02743 LoRaMacBuffer[pktHeaderLen++] = MacCommandsBuffer[i]; 02744 } 02745 } 02746 } 02747 else { 02748 if ((MacCommandsBufferIndex > 0) && (MacCommandsInNextTx)) { 02749 payloadSize = MacCommandsBufferIndex; 02750 payload = MacCommandsBuffer; 02751 framePort = 0; 02752 } 02753 } 02754 MacCommandsInNextTx = false; 02755 // Store MAC commands which must be re-send in case the device does not 02756 // receive a downlink anymore 02757 MacCommandsBufferToRepeatIndex = ParseMacCommandsToRepeat( 02758 MacCommandsBuffer, MacCommandsBufferIndex, MacCommandsBufferToRepeat); 02759 if (MacCommandsBufferToRepeatIndex > 0) { 02760 MacCommandsInNextTx = true; 02761 } 02762 MacCommandsBufferIndex = 0; 02763 02764 if ((payload != NULL) && (payloadSize > 0)) { 02765 LoRaMacBuffer[pktHeaderLen++] = framePort; 02766 02767 if (framePort == 0) { 02768 LoRaMacPayloadEncrypt ((uint8_t*)payload, payloadSize, LoRaMacNwkSKey, LoRaMacDevAddr, 02769 UP_LINK, UpLinkCounter, LoRaMacPayload); 02770 } 02771 else { 02772 LoRaMacPayloadEncrypt ((uint8_t*)payload, payloadSize, LoRaMacAppSKey, LoRaMacDevAddr, 02773 UP_LINK, UpLinkCounter, LoRaMacPayload); 02774 } 02775 memcpy1(LoRaMacBuffer + pktHeaderLen, LoRaMacPayload, payloadSize); 02776 } 02777 LoRaMacBufferPktLen = pktHeaderLen + payloadSize; 02778 02779 LoRaMacComputeMic(LoRaMacBuffer, LoRaMacBufferPktLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, 02780 UpLinkCounter, &mic); 02781 02782 LoRaMacBuffer[LoRaMacBufferPktLen + 0] = mic & 0xFF; 02783 LoRaMacBuffer[LoRaMacBufferPktLen + 1] = (mic >> 8) & 0xFF; 02784 LoRaMacBuffer[LoRaMacBufferPktLen + 2] = (mic >> 16) & 0xFF; 02785 LoRaMacBuffer[LoRaMacBufferPktLen + 3] = (mic >> 24) & 0xFF; 02786 02787 LoRaMacBufferPktLen += LORAMAC_MFR_LEN; 02788 02789 break; 02790 case FRAME_TYPE_PROPRIETARY : 02791 if ((fBuffer != NULL) && (fBufferSize > 0)) { 02792 memcpy1(LoRaMacBuffer + pktHeaderLen, (uint8_t*)fBuffer, fBufferSize); 02793 LoRaMacBufferPktLen = pktHeaderLen + fBufferSize; 02794 } 02795 break; 02796 default: 02797 return LORAMAC_STATUS_SERVICE_UNKNOWN ; 02798 } 02799 02800 return LORAMAC_STATUS_OK ; 02801 } 02802 02803 LoRaMacStatus_t SendFrameOnChannel(ChannelParams_t channel) { 02804 int8_t datarate = Datarates[ChannelsDatarate]; 02805 int8_t txPowerIndex = 0; 02806 int8_t txPower = 0; 02807 02808 txPowerIndex = LimitTxPower(ChannelsTxPower); 02809 txPower = TxPowers[txPowerIndex]; 02810 02811 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 02812 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 02813 McpsConfirm.Datarate = ChannelsDatarate; 02814 McpsConfirm.TxPower = txPowerIndex; 02815 02816 Radio.SetChannel(channel.Frequency ); 02817 02818 // LOG("Radio TxPower=%u\r\n", txPower); 02819 #if defined(USE_BAND_433) || defined(USE_BAND_780) || defined(USE_BAND_868) 02820 if (ChannelsDatarate == DR_7) { // High Speed FSK channel 02821 Radio.SetMaxPayloadLength(MODEM_FSK, LoRaMacBufferPktLen); 02822 Radio.SetTxConfig(MODEM_FSK, txPower, 25e3, 0, datarate * 1e3, 0, 5, false, true, 0, 0, false, 02823 3e6); 02824 TxTimeOnAir = Radio.TimeOnAir(MODEM_FSK, LoRaMacBufferPktLen); 02825 } 02826 else if (ChannelsDatarate == DR_6) { // High speed LoRa channel 02827 Radio.SetMaxPayloadLength(MODEM_LORA, LoRaMacBufferPktLen); 02828 Radio.SetTxConfig(MODEM_LORA, txPower, 0, 1, datarate, 1, 8, false, true, 0, 0, false, 3e6); 02829 TxTimeOnAir = Radio.TimeOnAir(MODEM_LORA, LoRaMacBufferPktLen); 02830 } 02831 else { // Normal LoRa channel 02832 Radio.SetMaxPayloadLength(MODEM_LORA, LoRaMacBufferPktLen); 02833 Radio.SetTxConfig(MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e6); 02834 TxTimeOnAir = Radio.TimeOnAir(MODEM_LORA, LoRaMacBufferPktLen); 02835 } 02836 #elif defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 02837 Radio.SetMaxPayloadLength(MODEM_LORA, LoRaMacBufferPktLen); 02838 if (ChannelsDatarate >= DR_4) { // High speed LoRa channel BW500 kHz 02839 Radio.SetTxConfig(MODEM_LORA, txPower, 0, 2, datarate, 1, 8, false, true, 0, 0, false, 3e6); 02840 TxTimeOnAir = Radio.TimeOnAir(MODEM_LORA, LoRaMacBufferPktLen); 02841 } 02842 else { // Normal LoRa channel 02843 Radio.SetTxConfig(MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e6); 02844 TxTimeOnAir = Radio.TimeOnAir(MODEM_LORA, LoRaMacBufferPktLen); 02845 } 02846 #else 02847 #error "Please define a frequency band in the compiler options." 02848 #endif 02849 02850 // Store the time on air 02851 McpsConfirm.TxTimeOnAir = TxTimeOnAir; 02852 MlmeConfirm.TxTimeOnAir = TxTimeOnAir; 02853 02854 // Starts the MAC layer status check timer 02855 TimerSetValue(&MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT); 02856 TimerStart(&MacStateCheckTimer); 02857 02858 // Send now 02859 Radio.Send(LoRaMacBuffer, LoRaMacBufferPktLen); 02860 02861 LoRaMacState |= MAC_TX_RUNNING; 02862 02863 return LORAMAC_STATUS_OK ; 02864 } 02865 02866 LoRaMacStatus_t LoRaMacInitialization(LoRaMacPrimitives_t * primitives, 02867 LoRaMacCallback_t* callbacks) { 02868 if (primitives == NULL) { 02869 return LORAMAC_STATUS_PARAMETER_INVALID ; 02870 } 02871 02872 if ((primitives->MacMcpsConfirm == NULL) || (primitives->MacMcpsIndication == NULL) || 02873 (primitives->MacMlmeConfirm == NULL)) { 02874 return LORAMAC_STATUS_PARAMETER_INVALID ; 02875 } 02876 02877 LoRaMacPrimitives = primitives; 02878 LoRaMacCallbacks = callbacks; 02879 02880 LoRaMacFlags.Value = 0; 02881 02882 LoRaMacDeviceClass = CLASS_A ; 02883 02884 UpLinkCounter = 1; 02885 DownLinkCounter = 0; 02886 AdrAckCounter = 0; 02887 02888 ChannelsNbRepCounter = 0; 02889 02890 AckTimeoutRetries = 1; 02891 AckTimeoutRetriesCounter = 1; 02892 AckTimeoutRetry = false; 02893 02894 MaxDCycle = 0; 02895 AggregatedDCycle = 1; 02896 02897 MacCommandsBufferIndex = 0; 02898 MacCommandsBufferToRepeatIndex = 0; 02899 02900 IsRxWindowsEnabled = true; 02901 02902 RepeaterSupport = false; 02903 IsRxWindowsEnabled = true; 02904 IsLoRaMacNetworkJoined = false; 02905 LoRaMacState = MAC_IDLE; 02906 02907 NodeAckRequested = false; 02908 SrvAckRequested = false; 02909 MacCommandsInNextTx = false; 02910 02911 #if defined(USE_BAND_433) 02912 ChannelsMask[0] = LC(1) + LC(2) + LC(3); 02913 #elif defined(USE_BAND_780) 02914 ChannelsMask[0] = LC(1) + LC(2) + LC(3); 02915 #elif defined(USE_BAND_868) 02916 ChannelsMask[0] = LC(1) + LC(2) + LC(3); 02917 #elif defined(USE_BAND_915) 02918 ChannelsMask[0] = 0xFFFF; 02919 ChannelsMask[1] = 0xFFFF; 02920 ChannelsMask[2] = 0xFFFF; 02921 ChannelsMask[3] = 0xFFFF; 02922 ChannelsMask[4] = 0x00FF; 02923 ChannelsMask[5] = 0x0000; 02924 02925 memcpy1((uint8_t*)ChannelsMaskRemaining, (uint8_t*)ChannelsMask, sizeof(ChannelsMask)); 02926 #elif defined(USE_BAND_915_HYBRID) 02927 ChannelsMask[0] = 0x00FF; 02928 ChannelsMask[1] = 0x0000; 02929 ChannelsMask[2] = 0x0000; 02930 ChannelsMask[3] = 0x0000; 02931 ChannelsMask[4] = 0x0001; 02932 ChannelsMask[5] = 0x0000; 02933 02934 memcpy1((uint8_t*)ChannelsMaskRemaining, (uint8_t*)ChannelsMask, sizeof(ChannelsMask)); 02935 #else 02936 #error "Please define a frequency band in the compiler options." 02937 #endif 02938 02939 #if defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 02940 // 125 kHz channels 02941 for (uint8_t i = 0; i < LORA_MAX_NB_CHANNELS - 8; i++) { 02942 Channels[i].Frequency = 902.3e6 + i * 200e3; 02943 Channels[i].DrRange .Value = (DR_3 << 4) | DR_0; 02944 Channels[i].Band = 0; 02945 } 02946 // 500 kHz channels 02947 for (uint8_t i = LORA_MAX_NB_CHANNELS - 8; i < LORA_MAX_NB_CHANNELS; i++) { 02948 Channels[i].Frequency = 903.0e6 + (i - (LORA_MAX_NB_CHANNELS - 8)) * 1.6e6; 02949 Channels[i].DrRange .Value = (DR_4 << 4) | DR_4; 02950 Channels[i].Band = 0; 02951 } 02952 #endif 02953 02954 ChannelsTxPower = LORAMAC_DEFAULT_TX_POWER; 02955 ChannelsDefaultDatarate = ChannelsDatarate = LORAMAC_DEFAULT_DATARATE; 02956 ChannelsNbRep = 1; 02957 ChannelsNbRepCounter = 0; 02958 02959 Rx2Channel.Frequency = 923300000; 02960 Rx2Channel.Datarate = DR_8; 02961 Rx1DrOffset = 0; 02962 02963 MaxDCycle = 0; 02964 AggregatedDCycle = 1; 02965 AggregatedLastTxDoneTime = 0; 02966 AggregatedTimeOff = 0; 02967 02968 #if defined(USE_BAND_433) 02969 DutyCycleOn = false; 02970 #elif defined(USE_BAND_780) 02971 DutyCycleOn = false; 02972 #elif defined(USE_BAND_868) 02973 DutyCycleOn = true; 02974 #elif defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 02975 DutyCycleOn = false; 02976 #else 02977 #error "Please define a frequency band in the compiler options." 02978 #endif 02979 02980 MaxRxWindow = MAX_RX_WINDOW; 02981 ReceiveDelay1 = RECEIVE_DELAY1; 02982 ReceiveDelay2 = RECEIVE_DELAY2; 02983 JoinAcceptDelay1 = JOIN_ACCEPT_DELAY1; 02984 JoinAcceptDelay2 = JOIN_ACCEPT_DELAY2; 02985 02986 #if defined(USE_BAND_915) 02987 NextJoinBlock = 0; 02988 LastJoinBlock = -1; 02989 JoinBlocksRemaining = 0xff; 02990 Join500KHzRemaining = 0xff; 02991 #endif 02992 02993 LastJoinTxTime = 0; 02994 JoinAggTimeOnAir = 0; 02995 02996 TimerInit(&MacStateCheckTimer, OnMacStateCheckTimerEvent); 02997 TimerSetValue(&MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT); 02998 02999 TimerInit(&TxDelayedTimer, OnTxDelayedTimerEvent); 03000 TimerInit(&RxWindowTimer1, OnRxWindow1TimerEvent); 03001 TimerInit(&RxWindowTimer2, OnRxWindow2TimerEvent); 03002 TimerInit(&AckTimeoutTimer, OnAckTimeoutTimerEvent); 03003 03004 // Initialize Radio driver 03005 RadioEvents.TxDone = OnRadioTxDone; 03006 RadioEvents.RxDone = OnRadioRxDone; 03007 RadioEvents.RxError = OnRadioRxError; 03008 RadioEvents.TxTimeout = OnRadioTxTimeout; 03009 RadioEvents.RxTimeout = OnRadioRxTimeout; 03010 Radio.Init(&RadioEvents); 03011 03012 // Random seed initialization 03013 srand1(Radio.Random()); 03014 03015 // Initialize channel index. 03016 Channel = LORA_MAX_NB_CHANNELS; 03017 03018 PublicNetwork = true; 03019 SetPublicNetwork(PublicNetwork); 03020 Radio.Sleep(); 03021 03022 return LORAMAC_STATUS_OK ; 03023 } 03024 03025 LoRaMacStatus_t LoRaMacQueryTxPossible(uint8_t size, LoRaMacTxInfo_t * txInfo) { 03026 int8_t datarate = ChannelsDefaultDatarate; 03027 uint8_t fOptLen = MacCommandsBufferIndex + MacCommandsBufferToRepeatIndex; 03028 03029 if (txInfo == NULL) { 03030 return LORAMAC_STATUS_PARAMETER_INVALID ; 03031 } 03032 03033 AdrNextDr(AdrCtrlOn, false, &datarate, NULL); 03034 03035 if (RepeaterSupport == true) { 03036 txInfo->CurrentPayloadSize = MaxPayloadOfDatarateRepeater[datarate]; 03037 } 03038 else { 03039 txInfo->CurrentPayloadSize = MaxPayloadOfDatarate[datarate]; 03040 } 03041 03042 if (txInfo->CurrentPayloadSize >= fOptLen) { 03043 txInfo->MaxPossiblePayload = txInfo->CurrentPayloadSize - fOptLen; 03044 } 03045 else { 03046 return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR ; 03047 } 03048 03049 if (ValidatePayloadLength(size, datarate, 0) == false) { 03050 return LORAMAC_STATUS_LENGTH_ERROR ; 03051 } 03052 03053 if (ValidatePayloadLength(size, datarate, fOptLen) == false) { 03054 return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR ; 03055 } 03056 03057 return LORAMAC_STATUS_OK ; 03058 } 03059 03060 LoRaMacStatus_t LoRaMacMibGetRequestConfirm(MibRequestConfirm_t * mibGet) { 03061 LoRaMacStatus_t status = LORAMAC_STATUS_OK ; 03062 03063 if (mibGet == NULL) { 03064 return LORAMAC_STATUS_PARAMETER_INVALID ; 03065 } 03066 03067 switch (mibGet->Type ) { 03068 case MIB_DEVICE_CLASS : { 03069 mibGet->Param .Class = LoRaMacDeviceClass; 03070 break; 03071 } 03072 case MIB_NETWORK_JOINED : { 03073 mibGet->Param .IsNetworkJoined = IsLoRaMacNetworkJoined; 03074 break; 03075 } 03076 case MIB_ADR : { 03077 mibGet->Param .AdrEnable = AdrCtrlOn; 03078 break; 03079 } 03080 case MIB_NET_ID : { 03081 mibGet->Param .NetID = LoRaMacNetID; 03082 break; 03083 } 03084 case MIB_DEV_ADDR : { 03085 mibGet->Param .DevAddr = LoRaMacDevAddr; 03086 break; 03087 } 03088 case MIB_NWK_SKEY : { 03089 mibGet->Param .NwkSKey = LoRaMacNwkSKey; 03090 break; 03091 } 03092 case MIB_APP_SKEY : { 03093 mibGet->Param .AppSKey = LoRaMacAppSKey; 03094 break; 03095 } 03096 case MIB_PUBLIC_NETWORK : { 03097 mibGet->Param .EnablePublicNetwork = PublicNetwork; 03098 break; 03099 } 03100 case MIB_REPEATER_SUPPORT : { 03101 mibGet->Param .EnableRepeaterSupport = RepeaterSupport; 03102 break; 03103 } 03104 case MIB_CHANNELS : { 03105 mibGet->Param .ChannelList = Channels; 03106 break; 03107 } 03108 case MIB_RX2_CHANNEL : { 03109 mibGet->Param .Rx2Channel = Rx2Channel; 03110 break; 03111 } 03112 case MIB_CHANNELS_MASK : { 03113 mibGet->Param .ChannelsMask = ChannelsMask; 03114 break; 03115 } 03116 case MIB_CHANNELS_NB_REP : { 03117 mibGet->Param .ChannelNbRep = ChannelsNbRep; 03118 break; 03119 } 03120 case MIB_MAX_RX_WINDOW_DURATION : { 03121 mibGet->Param .MaxRxWindow = MaxRxWindow; 03122 break; 03123 } 03124 case MIB_RECEIVE_DELAY_1 : { 03125 mibGet->Param .ReceiveDelay1 = ReceiveDelay1; 03126 break; 03127 } 03128 case MIB_RECEIVE_DELAY_2 : { 03129 mibGet->Param .ReceiveDelay2 = ReceiveDelay2; 03130 break; 03131 } 03132 case MIB_JOIN_ACCEPT_DELAY_1 : { 03133 mibGet->Param .JoinAcceptDelay1 = JoinAcceptDelay1; 03134 break; 03135 } 03136 case MIB_JOIN_ACCEPT_DELAY_2 : { 03137 mibGet->Param .JoinAcceptDelay2 = JoinAcceptDelay2; 03138 break; 03139 } 03140 case MIB_CHANNELS_DEFAULT_DATARATE : { 03141 mibGet->Param .ChannelsDefaultDatarate = ChannelsDefaultDatarate; 03142 break; 03143 } 03144 case MIB_CHANNELS_DATARATE : { 03145 mibGet->Param .ChannelsDatarate = ChannelsDatarate; 03146 break; 03147 } 03148 case MIB_CHANNELS_TX_POWER : { 03149 mibGet->Param .ChannelsTxPower = ChannelsTxPower; 03150 break; 03151 } 03152 case MIB_UPLINK_COUNTER : { 03153 mibGet->Param .UpLinkCounter = UpLinkCounter; 03154 break; 03155 } 03156 case MIB_DOWNLINK_COUNTER : { 03157 mibGet->Param .DownLinkCounter = DownLinkCounter; 03158 break; 03159 } 03160 case MIB_MULTICAST_CHANNEL : { 03161 mibGet->Param .MulticastList = MulticastChannels; 03162 break; 03163 } 03164 default: 03165 status = LORAMAC_STATUS_SERVICE_UNKNOWN ; 03166 break; 03167 } 03168 03169 return status; 03170 } 03171 03172 LoRaMacStatus_t LoRaMacMibSetRequestConfirm(MibRequestConfirm_t * mibSet) { 03173 LoRaMacStatus_t status = LORAMAC_STATUS_OK ; 03174 03175 if (mibSet == NULL) { 03176 return LORAMAC_STATUS_PARAMETER_INVALID ; 03177 } 03178 if ((LoRaMacState & MAC_TX_RUNNING) == MAC_TX_RUNNING) { 03179 return LORAMAC_STATUS_BUSY ; 03180 } 03181 03182 switch (mibSet->Type ) { 03183 case MIB_DEVICE_CLASS : { 03184 LoRaMacDeviceClass = mibSet->Param .Class ; 03185 switch (LoRaMacDeviceClass) { 03186 case CLASS_A : { 03187 // Set the radio into sleep to setup a defined state 03188 Radio.Sleep(); 03189 break; 03190 } 03191 case CLASS_B : { 03192 break; 03193 } 03194 case CLASS_C : { 03195 // Set the NodeAckRequested indicator to default 03196 NodeAckRequested = false; 03197 OnRxWindow2TimerEvent(); 03198 break; 03199 } 03200 } 03201 break; 03202 } 03203 case MIB_NETWORK_JOINED : { 03204 IsLoRaMacNetworkJoined = mibSet->Param .IsNetworkJoined ; 03205 #if defined(USE_BAND_915) 03206 if (IsLoRaMacNetworkJoined == false) { 03207 NextJoinBlock = 0; 03208 JoinBlocksRemaining = 0xff; 03209 Join500KHzRemaining = 0xff; 03210 } 03211 #endif 03212 break; 03213 } 03214 case MIB_ADR : { 03215 AdrCtrlOn = mibSet->Param .AdrEnable ; 03216 break; 03217 } 03218 case MIB_NET_ID : { 03219 LoRaMacNetID = mibSet->Param .NetID ; 03220 break; 03221 } 03222 case MIB_DEV_ADDR : { 03223 LoRaMacDevAddr = mibSet->Param .DevAddr ; 03224 break; 03225 } 03226 case MIB_NWK_SKEY : { 03227 if (mibSet->Param .NwkSKey != NULL) { 03228 memcpy1(LoRaMacNwkSKey, mibSet->Param .NwkSKey , sizeof(LoRaMacNwkSKey)); 03229 } 03230 else { 03231 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03232 } 03233 break; 03234 } 03235 case MIB_APP_SKEY : { 03236 if (mibSet->Param .AppSKey != NULL) { 03237 memcpy1(LoRaMacAppSKey, mibSet->Param .AppSKey , sizeof(LoRaMacAppSKey)); 03238 } 03239 else { 03240 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03241 } 03242 break; 03243 } 03244 case MIB_PUBLIC_NETWORK : { 03245 SetPublicNetwork(mibSet->Param .EnablePublicNetwork ); 03246 break; 03247 } 03248 case MIB_REPEATER_SUPPORT : { 03249 RepeaterSupport = mibSet->Param .EnableRepeaterSupport ; 03250 break; 03251 } 03252 case MIB_RX2_CHANNEL : { 03253 Rx2Channel = mibSet->Param .Rx2Channel ; 03254 break; 03255 } 03256 case MIB_CHANNELS_MASK : { 03257 if (mibSet->Param .ChannelsMask ) { 03258 #if defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 03259 bool chanMaskState = true; 03260 03261 #if defined(USE_BAND_915_HYBRID) 03262 chanMaskState = ValidateChannelMask(mibSet->Param .ChannelsMask ); 03263 #endif 03264 if (chanMaskState == true) { 03265 if ((CountNbEnabled125kHzChannels(mibSet->Param .ChannelsMask ) < HYBRD_CHNLS_MIN) && 03266 (CountNbEnabled125kHzChannels(mibSet->Param .ChannelsMask ) > 0)) { 03267 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03268 } 03269 else { 03270 memcpy1((uint8_t*)ChannelsMask, (uint8_t*)mibSet->Param .ChannelsMask , 03271 sizeof(ChannelsMask)); 03272 for (uint8_t i = 0; i < sizeof(ChannelsMask) / 2; i++) { 03273 // Disable channels which are no longer available 03274 ChannelsMaskRemaining[i] &= ChannelsMask[i]; 03275 } 03276 } 03277 } 03278 else { 03279 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03280 } 03281 #else 03282 memcpy1((uint8_t*)ChannelsMask, (uint8_t*)mibSet->Param .ChannelsMask , 2); 03283 #endif 03284 } 03285 else { 03286 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03287 } 03288 break; 03289 } 03290 case MIB_CHANNELS_NB_REP : { 03291 if ((mibSet->Param .ChannelNbRep >= 1) && (mibSet->Param .ChannelNbRep <= 15)) { 03292 ChannelsNbRep = mibSet->Param .ChannelNbRep ; 03293 } 03294 else { 03295 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03296 } 03297 break; 03298 } 03299 case MIB_MAX_RX_WINDOW_DURATION : { 03300 MaxRxWindow = mibSet->Param .MaxRxWindow ; 03301 break; 03302 } 03303 case MIB_RECEIVE_DELAY_1 : { 03304 ReceiveDelay1 = mibSet->Param .ReceiveDelay1 ; 03305 break; 03306 } 03307 case MIB_RECEIVE_DELAY_2 : { 03308 ReceiveDelay2 = mibSet->Param .ReceiveDelay2 ; 03309 break; 03310 } 03311 case MIB_JOIN_ACCEPT_DELAY_1 : { 03312 JoinAcceptDelay1 = mibSet->Param .JoinAcceptDelay1 ; 03313 break; 03314 } 03315 case MIB_JOIN_ACCEPT_DELAY_2 : { 03316 JoinAcceptDelay2 = mibSet->Param .JoinAcceptDelay2 ; 03317 break; 03318 } 03319 case MIB_CHANNELS_DEFAULT_DATARATE : { 03320 if (ValueInRange(mibSet->Param .ChannelsDefaultDatarate , LORAMAC_TX_MIN_DATARATE, 03321 LORAMAC_TX_MAX_DATARATE)) { 03322 ChannelsDefaultDatarate = mibSet->Param .ChannelsDefaultDatarate ; 03323 } 03324 else { 03325 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03326 } 03327 break; 03328 } 03329 case MIB_CHANNELS_DATARATE : { 03330 if (ValueInRange(mibSet->Param .ChannelsDatarate , LORAMAC_TX_MIN_DATARATE, 03331 LORAMAC_TX_MAX_DATARATE)) { 03332 ChannelsDatarate = mibSet->Param .ChannelsDatarate ; 03333 } 03334 else { 03335 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03336 } 03337 break; 03338 } 03339 case MIB_CHANNELS_TX_POWER : { 03340 if (ValueInRange(mibSet->Param .ChannelsTxPower , LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER)) { 03341 #if defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 03342 int8_t txPower = LimitTxPower(mibSet->Param .ChannelsTxPower ); 03343 if (txPower == mibSet->Param .ChannelsTxPower ) { 03344 ChannelsTxPower = mibSet->Param .ChannelsTxPower ; 03345 } 03346 else { 03347 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03348 } 03349 #else 03350 ChannelsTxPower = mibSet->Param .ChannelsTxPower ; 03351 #endif 03352 } 03353 else { 03354 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03355 } 03356 break; 03357 } 03358 case MIB_UPLINK_COUNTER : { 03359 UpLinkCounter = mibSet->Param .UpLinkCounter ; 03360 break; 03361 } 03362 case MIB_DOWNLINK_COUNTER : { 03363 DownLinkCounter = mibSet->Param .DownLinkCounter ; 03364 break; 03365 } 03366 default: 03367 status = LORAMAC_STATUS_SERVICE_UNKNOWN ; 03368 break; 03369 } 03370 03371 return status; 03372 } 03373 03374 LoRaMacStatus_t LoRaMacChannelAdd(uint8_t id, ChannelParams_t params) { 03375 #if (defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID)) 03376 return LORAMAC_STATUS_PARAMETER_INVALID ; 03377 #else 03378 bool datarateInvalid = false; 03379 bool frequencyInvalid = false; 03380 uint8_t band = 0; 03381 03382 // The id must not exceed LORA_MAX_NB_CHANNELS 03383 if (id >= LORA_MAX_NB_CHANNELS) { 03384 return LORAMAC_STATUS_PARAMETER_INVALID ; 03385 } 03386 // Validate if the MAC is in a correct state 03387 if ((LoRaMacState & MAC_TX_RUNNING) == MAC_TX_RUNNING) { 03388 if ((LoRaMacState & MAC_TX_CONFIG) != MAC_TX_CONFIG) { 03389 return LORAMAC_STATUS_BUSY ; 03390 } 03391 } 03392 // Validate the datarate 03393 if ((params.DrRange .Fields.Min > params.DrRange .Fields.Max ) || 03394 (ValueInRange(params.DrRange .Fields.Min , LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE) == 03395 false) || 03396 (ValueInRange(params.DrRange .Fields.Max , LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE) == 03397 false)) { 03398 datarateInvalid = true; 03399 } 03400 03401 #if defined(USE_BAND_433) || defined(USE_BAND_780) || defined(USE_BAND_868) 03402 if (id < 3) { 03403 if (params.Frequency != Channels[id].Frequency ) { 03404 frequencyInvalid = true; 03405 } 03406 03407 if (params.DrRange .Fields.Min > ChannelsDefaultDatarate) { 03408 datarateInvalid = true; 03409 } 03410 if (ValueInRange(params.DrRange .Fields.Max , DR_5, LORAMAC_TX_MAX_DATARATE) == false) { 03411 datarateInvalid = true; 03412 } 03413 } 03414 #endif 03415 03416 // Validate the frequency 03417 if ((Radio.CheckRfFrequency(params.Frequency ) == true) && (params.Frequency > 0) && 03418 (frequencyInvalid == false)) { 03419 #if defined(USE_BAND_868) 03420 if ((params.Frequency >= 865000000) && (params.Frequency <= 868000000)) { 03421 band = BAND_G1_0; 03422 } 03423 else if ((params.Frequency > 868000000) && (params.Frequency <= 868600000)) { 03424 band = BAND_G1_1; 03425 } 03426 else if ((params.Frequency >= 868700000) && (params.Frequency <= 869200000)) { 03427 band = BAND_G1_2; 03428 } 03429 else if ((params.Frequency >= 869400000) && (params.Frequency <= 869650000)) { 03430 band = BAND_G1_3; 03431 } 03432 else if ((params.Frequency >= 869700000) && (params.Frequency <= 870000000)) { 03433 band = BAND_G1_4; 03434 } 03435 else { 03436 frequencyInvalid = true; 03437 } 03438 #endif 03439 } 03440 else { 03441 frequencyInvalid = true; 03442 } 03443 03444 if ((datarateInvalid == true) && (frequencyInvalid == true)) { 03445 return LORAMAC_STATUS_FREQ_AND_DR_INVALID ; 03446 } 03447 if (datarateInvalid == true) { 03448 return LORAMAC_STATUS_DATARATE_INVALID ; 03449 } 03450 if (frequencyInvalid == true) { 03451 return LORAMAC_STATUS_FREQUENCY_INVALID ; 03452 } 03453 03454 // Every parameter is valid, activate the channel 03455 Channels[id] = params; 03456 Channels[id].Band = band; 03457 ChannelsMask[0] |= (1 << id); 03458 03459 return LORAMAC_STATUS_OK ; 03460 #endif 03461 } 03462 03463 LoRaMacStatus_t LoRaMacChannelRemove(uint8_t id) { 03464 #if defined(USE_BAND_433) || defined(USE_BAND_780) || defined(USE_BAND_868) 03465 if ((LoRaMacState & MAC_TX_RUNNING) == MAC_TX_RUNNING) { 03466 if ((LoRaMacState & MAC_TX_CONFIG) != MAC_TX_CONFIG) { 03467 return LORAMAC_STATUS_BUSY ; 03468 } 03469 } 03470 03471 if ((id < 3) || (id >= LORA_MAX_NB_CHANNELS)) { 03472 return LORAMAC_STATUS_PARAMETER_INVALID ; 03473 } 03474 else { 03475 // Remove the channel from the list of channels 03476 Channels[id] = (ChannelParams_t ){0, {0}, 0}; 03477 03478 // Disable the channel as it doesn't exist anymore 03479 if (DisableChannelInMask(id, ChannelsMask) == false) { 03480 return LORAMAC_STATUS_PARAMETER_INVALID ; 03481 } 03482 } 03483 return LORAMAC_STATUS_OK ; 03484 #elif (defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID)) 03485 return LORAMAC_STATUS_PARAMETER_INVALID ; 03486 #endif 03487 } 03488 03489 LoRaMacStatus_t LoRaMacMulticastChannelLink(MulticastParams_t * channelParam) { 03490 if (channelParam == NULL) { 03491 return LORAMAC_STATUS_PARAMETER_INVALID ; 03492 } 03493 if ((LoRaMacState & MAC_TX_RUNNING) == MAC_TX_RUNNING) { 03494 return LORAMAC_STATUS_BUSY ; 03495 } 03496 03497 // Reset downlink counter 03498 channelParam->DownLinkCounter = 0; 03499 03500 if (MulticastChannels == NULL) { 03501 // New node is the fist element 03502 MulticastChannels = channelParam; 03503 } 03504 else { 03505 MulticastParams_t * cur = MulticastChannels; 03506 03507 // Search the last node in the list 03508 while (cur->Next != NULL) { 03509 cur = cur->Next ; 03510 } 03511 // This function always finds the last node 03512 cur->Next = channelParam; 03513 } 03514 03515 return LORAMAC_STATUS_OK ; 03516 } 03517 03518 LoRaMacStatus_t LoRaMacMulticastChannelUnlink(MulticastParams_t * channelParam) { 03519 if (channelParam == NULL) { 03520 return LORAMAC_STATUS_PARAMETER_INVALID ; 03521 } 03522 if ((LoRaMacState & MAC_TX_RUNNING) == MAC_TX_RUNNING) { 03523 return LORAMAC_STATUS_BUSY ; 03524 } 03525 03526 if (MulticastChannels != NULL) { 03527 if (MulticastChannels == channelParam) { 03528 // First element 03529 MulticastChannels = channelParam->Next ; 03530 } 03531 else { 03532 MulticastParams_t * cur = MulticastChannels; 03533 03534 // Search the node in the list 03535 while (cur->Next && cur->Next != channelParam) { 03536 cur = cur->Next ; 03537 } 03538 // If we found the node, remove it 03539 if (cur->Next ) { 03540 cur->Next = channelParam->Next ; 03541 } 03542 } 03543 channelParam->Next = NULL; 03544 } 03545 03546 return LORAMAC_STATUS_OK ; 03547 } 03548 03549 LoRaMacStatus_t LoRaMacMlmeRequest(MlmeReq_t * mlmeRequest) { 03550 LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN ; 03551 LoRaMacHeader_t macHdr; 03552 03553 if (mlmeRequest == NULL) { 03554 return LORAMAC_STATUS_PARAMETER_INVALID ; 03555 } 03556 if ((LoRaMacState & MAC_TX_RUNNING) == MAC_TX_RUNNING) { 03557 return LORAMAC_STATUS_BUSY ; 03558 } 03559 03560 memset1((uint8_t*)&MlmeConfirm, 0, sizeof(MlmeConfirm)); 03561 03562 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 03563 03564 switch (mlmeRequest->Type ) { 03565 case MLME_JOIN : { 03566 if ((LoRaMacState & MAC_TX_DELAYED) == MAC_TX_DELAYED) { 03567 return LORAMAC_STATUS_BUSY ; 03568 } 03569 03570 MlmeConfirm.MlmeRequest = mlmeRequest->Type ; 03571 03572 if ((mlmeRequest->Req.Join .DevEui == NULL) || (mlmeRequest->Req.Join .AppEui == NULL) || 03573 (mlmeRequest->Req.Join .AppKey == NULL)) { 03574 return LORAMAC_STATUS_PARAMETER_INVALID ; 03575 } 03576 03577 LoRaMacFlags.Bits.MlmeReq = 1; 03578 03579 LoRaMacDevEui = mlmeRequest->Req.Join .DevEui ; 03580 LoRaMacAppEui = mlmeRequest->Req.Join .AppEui ; 03581 LoRaMacAppKey = mlmeRequest->Req.Join .AppKey ; 03582 03583 // Disable join retransmission dutycycle as it does not currently 03584 // handle device reset 03585 #if 0 03586 if( LoRaMacCalcJoinBackOff( ) != 0 ) 03587 { 03588 return LORAMAC_STATUS_TX_DCYCLE_EXCEEDED ; 03589 } 03590 #endif 03591 03592 macHdr.Value = 0; 03593 macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ ; 03594 03595 #if defined(USE_BAND_915) 03596 if (IsLoRaMacNetworkJoined == true) { 03597 NextJoinBlock = 0; 03598 JoinBlocksRemaining = 0xff; 03599 Join500KHzRemaining = 0xff; 03600 IsLoRaMacNetworkJoined = false; 03601 } 03602 #endif 03603 03604 #if defined(USE_BAND_915) || defined(USE_BAND_915_HYBRID) 03605 #if defined(USE_BAND_915) 03606 // Re-enable 500 kHz default channels 03607 ChannelsMask[4] = 0x00FF; 03608 #else // defined( USE_BAND_915_HYBRID ) 03609 // Re-enable 500 kHz default channels 03610 ChannelsMask[4] = 0x0001; 03611 #endif 03612 03613 static uint8_t drSwitch = 0; 03614 03615 if ((++drSwitch & 0x01) == 0x01) { 03616 ChannelsDatarate = DR_0; 03617 } 03618 else { 03619 ChannelsDatarate = DR_4; 03620 } 03621 #endif 03622 03623 status = Send(&macHdr, 0, NULL, 0); 03624 break; 03625 } 03626 case MLME_LINK_CHECK : { 03627 LoRaMacFlags.Bits.MlmeReq = 1; 03628 // LoRaMac will send this command piggy-pack 03629 MlmeConfirm.MlmeRequest = mlmeRequest->Type ; 03630 03631 status = AddMacCommand(MOTE_MAC_LINK_CHECK_REQ , 0, 0); 03632 break; 03633 } 03634 default: 03635 break; 03636 } 03637 03638 if (status != LORAMAC_STATUS_OK ) { 03639 NodeAckRequested = false; 03640 LoRaMacFlags.Bits.MlmeReq = 0; 03641 } 03642 03643 return status; 03644 } 03645 03646 LoRaMacStatus_t LoRaMacMcpsRequest(McpsReq_t * mcpsRequest) { 03647 LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN ; 03648 LoRaMacHeader_t macHdr; 03649 uint8_t fPort = 0; 03650 void* fBuffer; 03651 uint16_t fBufferSize; 03652 int8_t datarate; 03653 bool readyToSend = false; 03654 03655 if (mcpsRequest == NULL) { 03656 return LORAMAC_STATUS_PARAMETER_INVALID ; 03657 } 03658 if (((LoRaMacState & MAC_TX_RUNNING) == MAC_TX_RUNNING) || 03659 ((LoRaMacState & MAC_TX_DELAYED) == MAC_TX_DELAYED)) { 03660 return LORAMAC_STATUS_BUSY ; 03661 } 03662 03663 macHdr.Value = 0; 03664 memset1((uint8_t*)&McpsConfirm, 0, sizeof(McpsConfirm)); 03665 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 03666 03667 switch (mcpsRequest->Type ) { 03668 case MCPS_UNCONFIRMED : { 03669 readyToSend = true; 03670 AckTimeoutRetries = 1; 03671 AckTimeoutRetriesCounter = 1; 03672 03673 macHdr.Bits.MType = FRAME_TYPE_DATA_UNCONFIRMED_UP ; 03674 fPort = mcpsRequest->Req.Unconfirmed .fPort ; 03675 fBuffer = mcpsRequest->Req.Unconfirmed .fBuffer ; 03676 fBufferSize = mcpsRequest->Req.Unconfirmed .fBufferSize ; 03677 datarate = mcpsRequest->Req.Unconfirmed .Datarate ; 03678 break; 03679 } 03680 case MCPS_CONFIRMED : { 03681 readyToSend = true; 03682 AckTimeoutRetriesCounter = 1; 03683 AckTimeoutRetries = mcpsRequest->Req.Confirmed .NbTrials ; 03684 03685 macHdr.Bits.MType = FRAME_TYPE_DATA_CONFIRMED_UP ; 03686 fPort = mcpsRequest->Req.Confirmed .fPort ; 03687 fBuffer = mcpsRequest->Req.Confirmed .fBuffer ; 03688 fBufferSize = mcpsRequest->Req.Confirmed .fBufferSize ; 03689 datarate = mcpsRequest->Req.Confirmed .Datarate ; 03690 break; 03691 } 03692 case MCPS_PROPRIETARY : { 03693 readyToSend = true; 03694 AckTimeoutRetries = 1; 03695 03696 macHdr.Bits.MType = FRAME_TYPE_PROPRIETARY ; 03697 fBuffer = mcpsRequest->Req.Proprietary .fBuffer ; 03698 fBufferSize = mcpsRequest->Req.Proprietary .fBufferSize ; 03699 datarate = mcpsRequest->Req.Proprietary .Datarate ; 03700 break; 03701 } 03702 default: 03703 break; 03704 } 03705 03706 if (readyToSend == true) { 03707 if (AdrCtrlOn == false) { 03708 if (ValueInRange(datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE) == true) { 03709 ChannelsDatarate = datarate; 03710 } 03711 else { 03712 return LORAMAC_STATUS_PARAMETER_INVALID ; 03713 } 03714 } 03715 03716 status = Send(&macHdr, fPort, fBuffer, fBufferSize); 03717 if (status == LORAMAC_STATUS_OK ) { 03718 McpsConfirm.McpsRequest = mcpsRequest->Type ; 03719 LoRaMacFlags.Bits.McpsReq = 1; 03720 } 03721 else { 03722 NodeAckRequested = false; 03723 } 03724 } 03725 03726 return status; 03727 } 03728 03729 TimerTime_t LoRaMacCalcJoinBackOff() { 03730 TimerTime_t timeOff = 0; 03731 TimerTime_t uptime; 03732 TimerTime_t currDCycleEndTime; 03733 TimerTime_t prevDCycleEndTime; 03734 TimerTime_t period; 03735 TimerTime_t onAirTimeMax; 03736 TimerTime_t lastJoinTime; 03737 TimerTime_t elapsedTime; 03738 uint8_t dcyclePeriod; 03739 03740 // Check retransmit duty-cycle is enabled 03741 if (JOIN_NB_RETRANSMISSION_DCYCLES == 0) 03742 return 0; 03743 03744 // Normalize system time values to seconds 03745 uptime = TimerGetCurrentTime() / 1e6; 03746 lastJoinTime = LastJoinTxTime / 1e6; 03747 03748 // Get dutycycle for current time 03749 prevDCycleEndTime = 0; 03750 currDCycleEndTime = 0; 03751 for (dcyclePeriod = 0; dcyclePeriod < JOIN_NB_RETRANSMISSION_DCYCLES; dcyclePeriod++) { 03752 prevDCycleEndTime = currDCycleEndTime; 03753 currDCycleEndTime += JoinReTransmitDCycle[dcyclePeriod].period; 03754 03755 bool isCurrentPeriod = uptime < currDCycleEndTime; 03756 03757 if (isCurrentPeriod || (dcyclePeriod == (JOIN_NB_RETRANSMISSION_DCYCLES - 1))) { 03758 period = JoinReTransmitDCycle[dcyclePeriod].period; 03759 onAirTimeMax = JoinReTransmitDCycle[dcyclePeriod].onAirTimeMax; 03760 if (isCurrentPeriod == true) 03761 break; 03762 } 03763 } 03764 03765 // Clear aggregate on air time if dutycycle period of last join has elapsed 03766 if (lastJoinTime < prevDCycleEndTime) { 03767 JoinAggTimeOnAir = 0; 03768 } 03769 else { 03770 elapsedTime = (uptime - prevDCycleEndTime) % period; 03771 03772 if (dcyclePeriod == JOIN_NB_RETRANSMISSION_DCYCLES) { 03773 if (((uptime - prevDCycleEndTime) / period) > ((lastJoinTime - prevDCycleEndTime) / period)) { 03774 JoinAggTimeOnAir = 0; 03775 } 03776 } 03777 } 03778 03779 if (JoinAggTimeOnAir >= onAirTimeMax) { 03780 // time off is remaining time until beginning of next period 03781 timeOff = (period - elapsedTime); 03782 } 03783 03784 if (timeOff > JOIN_RETRANSMISSION_DC_WAIT_MAX) 03785 timeOff = JOIN_RETRANSMISSION_DC_WAIT_MAX; 03786 03787 return (timeOff * 1e6); 03788 } 03789 03790 void LoRaMacTestRxWindowsOn (bool enable) { 03791 IsRxWindowsEnabled = enable; 03792 } 03793 03794 void LoRaMacTestSetMic (uint16_t txPacketCounter) { 03795 UpLinkCounter = txPacketCounter; 03796 IsUpLinkCounterFixed = true; 03797 } 03798 03799 void LoRaMacTestSetDutyCycleOn (bool enable) { 03800 DutyCycleOn = enable; 03801 }
Generated on Tue Jul 12 2022 16:32:55 by
1.7.2
