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