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