Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of LoRaWAN-lib by
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
