Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of LoRaWAN-lib by
LoRaMac.cpp
00001 /* 00002 / _____) _ | | 00003 ( (____ _____ ____ _| |_ _____ ____| |__ 00004 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00005 _____) ) ____| | | || |_| ____( (___| | | | 00006 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00007 (C)2013 Semtech 00008 ___ _____ _ ___ _ _____ ___ ___ ___ ___ 00009 / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 00010 \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 00011 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 00012 embedded.connectivity.solutions=============== 00013 00014 Description: LoRa MAC layer implementation 00015 00016 License: Revised BSD License, see LICENSE.TXT file include in the project 00017 00018 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jäckle ( STACKFORCE ) 00019 */ 00020 #include "board.h" 00021 00022 #include "LoRaMacCrypto.h" 00023 #include "LoRaMac.h" 00024 #include "LoRaMacTest.h" 00025 00026 /*! 00027 * Maximum PHY layer payload size 00028 */ 00029 #define LORAMAC_PHY_MAXPAYLOAD 255 00030 00031 /*! 00032 * Maximum MAC commands buffer size 00033 */ 00034 #define LORA_MAC_COMMAND_MAX_LENGTH 15 00035 00036 /*! 00037 * FRMPayload overhead to be used when setting the Radio.SetMaxPayloadLength 00038 * in RxWindowSetup function. 00039 * Maximum PHYPayload = MaxPayloadOfDatarate/MaxPayloadOfDatarateRepeater + LORA_MAC_FRMPAYLOAD_OVERHEAD 00040 */ 00041 #define LORA_MAC_FRMPAYLOAD_OVERHEAD 13 // MHDR(1) + FHDR(7) + Port(1) + MIC(4) 00042 00043 /*! 00044 * Device IEEE EUI 00045 */ 00046 static uint8_t *LoRaMacDevEui; 00047 00048 /*! 00049 * Application IEEE EUI 00050 */ 00051 static uint8_t *LoRaMacAppEui; 00052 00053 /*! 00054 * AES encryption/decryption cipher application key 00055 */ 00056 static uint8_t *LoRaMacAppKey; 00057 00058 /*! 00059 * AES encryption/decryption cipher network session key 00060 */ 00061 static uint8_t LoRaMacNwkSKey[] = 00062 { 00063 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00064 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00065 }; 00066 00067 /*! 00068 * AES encryption/decryption cipher application session key 00069 */ 00070 static uint8_t LoRaMacAppSKey[] = 00071 { 00072 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00073 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00074 }; 00075 00076 /*! 00077 * Device nonce is a random value extracted by issuing a sequence of RSSI 00078 * measurements 00079 */ 00080 static uint16_t LoRaMacDevNonce; 00081 00082 /*! 00083 * Network ID ( 3 bytes ) 00084 */ 00085 static uint32_t LoRaMacNetID; 00086 00087 /*! 00088 * Mote Address 00089 */ 00090 static uint32_t LoRaMacDevAddr; 00091 00092 /*! 00093 * Multicast channels linked list 00094 */ 00095 static MulticastParams_t *MulticastChannels = NULL; 00096 00097 /*! 00098 * Actual device class 00099 */ 00100 static DeviceClass_t LoRaMacDeviceClass; 00101 00102 /*! 00103 * Indicates if the node is connected to a private or public network 00104 */ 00105 static bool PublicNetwork; 00106 00107 /*! 00108 * Indicates if the node supports repeaters 00109 */ 00110 static bool RepeaterSupport; 00111 00112 /*! 00113 * Buffer containing the data to be sent or received. 00114 */ 00115 static uint8_t LoRaMacBuffer[LORAMAC_PHY_MAXPAYLOAD]; 00116 00117 /*! 00118 * Length of packet in LoRaMacBuffer 00119 */ 00120 static uint16_t LoRaMacBufferPktLen = 0; 00121 00122 /*! 00123 * Buffer containing the upper layer data. 00124 */ 00125 static uint8_t LoRaMacPayload[LORAMAC_PHY_MAXPAYLOAD]; 00126 static uint8_t LoRaMacRxPayload[LORAMAC_PHY_MAXPAYLOAD]; 00127 00128 /*! 00129 * LoRaMAC frame counter. Each time a packet is sent the counter is incremented. 00130 * Only the 16 LSB bits are sent 00131 */ 00132 static uint32_t UpLinkCounter = 1; 00133 00134 /*! 00135 * LoRaMAC frame counter. Each time a packet is received the counter is incremented. 00136 * Only the 16 LSB bits are received 00137 */ 00138 static uint32_t DownLinkCounter = 0; 00139 00140 /*! 00141 * IsPacketCounterFixed enables the MIC field tests by fixing the 00142 * UpLinkCounter value 00143 */ 00144 static bool IsUpLinkCounterFixed = false; 00145 00146 /*! 00147 * Used for test purposes. Disables the opening of the reception windows. 00148 */ 00149 static bool IsRxWindowsEnabled = true; 00150 00151 /*! 00152 * Indicates if the MAC layer has already joined a network. 00153 */ 00154 static bool IsLoRaMacNetworkJoined = false; 00155 00156 /*! 00157 * LoRaMac ADR control status 00158 */ 00159 static bool AdrCtrlOn = false; 00160 00161 /*! 00162 * Counts the number of missed ADR acknowledgements 00163 */ 00164 static uint32_t AdrAckCounter = 0; 00165 00166 /*! 00167 * If the node has sent a FRAME_TYPE_DATA_CONFIRMED_UP this variable indicates 00168 * if the nodes needs to manage the server acknowledgement. 00169 */ 00170 static bool NodeAckRequested = false; 00171 00172 /*! 00173 * If the server has sent a FRAME_TYPE_DATA_CONFIRMED_DOWN this variable indicates 00174 * if the ACK bit must be set for the next transmission 00175 */ 00176 static bool SrvAckRequested = false; 00177 00178 /*! 00179 * Indicates if the MAC layer wants to send MAC commands 00180 */ 00181 static bool MacCommandsInNextTx = false; 00182 00183 /*! 00184 * Contains the current MacCommandsBuffer index 00185 */ 00186 static uint8_t MacCommandsBufferIndex = 0; 00187 00188 /*! 00189 * Buffer containing the MAC layer commands 00190 */ 00191 static uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH]; 00192 00193 #if defined( USE_BAND_433 ) 00194 /*! 00195 * Data rates table definition 00196 */ 00197 const uint8_t Datarates[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; 00198 00199 /*! 00200 * Maximum payload with respect to the datarate index. Cannot operate with repeater. 00201 */ 00202 const uint8_t MaxPayloadOfDatarate[] = { 59, 59, 59, 123, 250, 250, 250, 250 }; 00203 00204 /*! 00205 * Maximum payload with respect to the datarate index. Can operate with repeater. 00206 */ 00207 const uint8_t MaxPayloadOfDatarateRepeater[] = { 59, 59, 59, 123, 230, 230, 230, 230 }; 00208 00209 /*! 00210 * Tx output powers table definition 00211 */ 00212 const int8_t TxPowers[] = { 20, 14, 11, 8, 5, 2 }; 00213 00214 /*! 00215 * LoRaMac bands 00216 */ 00217 static Band_t Bands[LORA_MAX_NB_BANDS] = 00218 { 00219 BAND0, 00220 }; 00221 00222 /*! 00223 * LoRaMAC channels 00224 */ 00225 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] = 00226 { 00227 LC1, 00228 LC2, 00229 LC3, 00230 }; 00231 #elif defined( USE_BAND_780 ) 00232 /*! 00233 * Data rates table definition 00234 */ 00235 const uint8_t Datarates[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; 00236 00237 /*! 00238 * Maximum payload with respect to the datarate index. Cannot operate with repeater. 00239 */ 00240 const uint8_t MaxPayloadOfDatarate[] = { 59, 59, 59, 123, 250, 250, 250, 250 }; 00241 00242 /*! 00243 * Maximum payload with respect to the datarate index. Can operate with repeater. 00244 */ 00245 const uint8_t MaxPayloadOfDatarateRepeater[] = { 59, 59, 59, 123, 230, 230, 230, 230 }; 00246 00247 /*! 00248 * Tx output powers table definition 00249 */ 00250 const int8_t TxPowers[] = { 20, 14, 11, 8, 5, 2 }; 00251 00252 /*! 00253 * LoRaMac bands 00254 */ 00255 static Band_t Bands[LORA_MAX_NB_BANDS] = 00256 { 00257 BAND0, 00258 }; 00259 00260 /*! 00261 * LoRaMAC channels 00262 */ 00263 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] = 00264 { 00265 LC1, 00266 LC2, 00267 LC3, 00268 }; 00269 #elif defined( USE_BAND_868 ) 00270 /*! 00271 * Data rates table definition 00272 */ 00273 const uint8_t Datarates[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; 00274 00275 /*! 00276 * Maximum payload with respect to the datarate index. Cannot operate with repeater. 00277 */ 00278 const uint8_t MaxPayloadOfDatarate[] = { 51, 51, 51, 115, 242, 242, 242, 242 }; 00279 00280 /*! 00281 * Maximum payload with respect to the datarate index. Can operate with repeater. 00282 */ 00283 const uint8_t MaxPayloadOfDatarateRepeater[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; 00284 00285 /*! 00286 * Tx output powers table definition 00287 */ 00288 const int8_t TxPowers[] = { 20, 14, 11, 8, 5, 2 }; 00289 00290 /*! 00291 * LoRaMac bands 00292 */ 00293 static Band_t Bands[LORA_MAX_NB_BANDS] = 00294 { 00295 BAND0, 00296 BAND1, 00297 BAND2, 00298 BAND3, 00299 BAND4, 00300 }; 00301 00302 /*! 00303 * LoRaMAC channels 00304 */ 00305 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] = 00306 { 00307 LC1, 00308 LC2, 00309 LC3, 00310 }; 00311 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 00312 /*! 00313 * Data rates table definition 00314 */ 00315 const uint8_t Datarates[] = { 10, 9, 8, 7, 8, 0, 0, 0, 12, 11, 10, 9, 8, 7, 0, 0 }; 00316 00317 /*! 00318 * Up/Down link data rates offset definition 00319 */ 00320 const int8_t datarateOffsets[16][4] = 00321 { 00322 { DR_10, DR_9 , DR_8 , DR_8 }, // DR_0 00323 { DR_11, DR_10, DR_9 , DR_8 }, // DR_1 00324 { DR_12, DR_11, DR_10, DR_9 }, // DR_2 00325 { DR_13, DR_12, DR_11, DR_10 }, // DR_3 00326 { DR_13, DR_13, DR_12, DR_11 }, // DR_4 00327 { 0xFF , 0xFF , 0xFF , 0xFF }, 00328 { 0xFF , 0xFF , 0xFF , 0xFF }, 00329 { 0xFF , 0xFF , 0xFF , 0xFF }, 00330 { DR_8 , DR_8 , DR_8 , DR_8 }, 00331 { DR_9 , DR_8 , DR_8 , DR_8 }, 00332 { DR_10, DR_9 , DR_8 , DR_8 }, 00333 { DR_11, DR_10, DR_9 , DR_8 }, 00334 { DR_12, DR_11, DR_10, DR_9 }, 00335 { DR_13, DR_12, DR_11, DR_10 }, 00336 { 0xFF , 0xFF , 0xFF , 0xFF }, 00337 { 0xFF , 0xFF , 0xFF , 0xFF }, 00338 }; 00339 00340 /*! 00341 * Maximum payload with respect to the datarate index. Cannot operate with repeater. 00342 */ 00343 const uint8_t MaxPayloadOfDatarate[] = { 11, 53, 129, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 }; 00344 00345 /*! 00346 * Maximum payload with respect to the datarate index. Can operate with repeater. 00347 */ 00348 const uint8_t MaxPayloadOfDatarateRepeater[] = { 11, 53, 129, 242, 242, 0, 0, 0, 33, 103, 222, 222, 222, 222, 0, 0 }; 00349 00350 /*! 00351 * Tx output powers table definition 00352 */ 00353 const int8_t TxPowers[] = { 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10 }; 00354 00355 /*! 00356 * LoRaMac bands 00357 */ 00358 static Band_t Bands[LORA_MAX_NB_BANDS] = 00359 { 00360 BAND0, 00361 }; 00362 00363 /*! 00364 * LoRaMAC channels 00365 */ 00366 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS]; 00367 00368 /*! 00369 * Contains the channels which remain to be applied. 00370 */ 00371 static uint16_t ChannelsMaskRemaining[6]; 00372 #else 00373 #error "Please define a frequency band in the compiler options." 00374 #endif 00375 00376 /*! 00377 * LoRaMAC 2nd reception window settings 00378 */ 00379 static Rx2ChannelParams_t Rx2Channel = RX_WND_2_CHANNEL; 00380 00381 /*! 00382 * Datarate offset between uplink and downlink on first window 00383 */ 00384 static uint8_t Rx1DrOffset = 0; 00385 00386 /*! 00387 * Mask indicating which channels are enabled 00388 */ 00389 static uint16_t ChannelsMask[6]; 00390 00391 /*! 00392 * Channels Tx output power 00393 */ 00394 static int8_t ChannelsTxPower = LORAMAC_DEFAULT_TX_POWER; 00395 00396 /*! 00397 * Channels datarate 00398 */ 00399 static int8_t ChannelsDatarate = LORAMAC_DEFAULT_DATARATE; 00400 00401 /*! 00402 * Channels default datarate 00403 */ 00404 static int8_t ChannelsDefaultDatarate = LORAMAC_DEFAULT_DATARATE; 00405 00406 /*! 00407 * Number of uplink messages repetitions [1:15] (unconfirmed messages only) 00408 */ 00409 static uint8_t ChannelsNbRep = 1; 00410 00411 /*! 00412 * Uplink messages repetitions counter 00413 */ 00414 static uint8_t ChannelsNbRepCounter = 0; 00415 00416 /*! 00417 * Maximum duty cycle 00418 * \remark Possibility to shutdown the device. 00419 */ 00420 static uint8_t MaxDCycle = 0; 00421 00422 /*! 00423 * Aggregated duty cycle management 00424 */ 00425 static uint16_t AggregatedDCycle; 00426 static TimerTime_t AggregatedLastTxDoneTime; 00427 static TimerTime_t AggregatedTimeOff; 00428 00429 /*! 00430 * Enables/Disables duty cycle management (Test only) 00431 */ 00432 static bool DutyCycleOn; 00433 00434 /*! 00435 * Current channel index 00436 */ 00437 uint8_t Channel; 00438 uint8_t Hard_channel = 8; 00439 int Force_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 } 01394 01395 LoRaMacState &= ~MAC_TX_RUNNING; 01396 } 01397 else 01398 { 01399 LoRaMacFlags.Bits.MacDone = 0; 01400 // Sends the same frame again 01401 ScheduleTx( ); 01402 } 01403 } 01404 } 01405 01406 if( LoRaMacFlags.Bits.McpsInd == 1 ) 01407 { 01408 if( ( McpsConfirm.AckReceived == true ) || ( AckTimeoutRetriesCounter > AckTimeoutRetries ) ) 01409 { 01410 AckTimeoutRetry = false; 01411 NodeAckRequested = false; 01412 if( IsUpLinkCounterFixed == false ) 01413 { 01414 UpLinkCounter++; 01415 } 01416 McpsConfirm.NbRetries = AckTimeoutRetriesCounter; 01417 01418 LoRaMacState &= ~MAC_TX_RUNNING; 01419 } 01420 } 01421 01422 if( ( AckTimeoutRetry == true ) && ( ( LoRaMacState & MAC_TX_DELAYED ) == 0 ) ) 01423 { 01424 AckTimeoutRetry = false; 01425 if( ( AckTimeoutRetriesCounter < AckTimeoutRetries ) && ( AckTimeoutRetriesCounter <= MAX_ACK_RETRIES ) ) 01426 { 01427 AckTimeoutRetriesCounter++; 01428 01429 if( ( AckTimeoutRetriesCounter % 2 ) == 1 ) 01430 { 01431 ChannelsDatarate = MAX( ChannelsDatarate - 1, LORAMAC_TX_MIN_DATARATE ); 01432 } 01433 LoRaMacFlags.Bits.MacDone = 0; 01434 // Sends the same frame again 01435 ScheduleTx( ); 01436 } 01437 else 01438 { 01439 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 01440 // Re-enable default channels LC1, LC2, LC3 01441 ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) ); 01442 #elif defined( USE_BAND_915 ) 01443 // Re-enable default channels 01444 ChannelsMask[0] = 0xFFFF; 01445 ChannelsMask[1] = 0xFFFF; 01446 ChannelsMask[2] = 0xFFFF; 01447 ChannelsMask[3] = 0xFFFF; 01448 ChannelsMask[4] = 0x00FF; 01449 ChannelsMask[5] = 0x0000; 01450 #elif defined( USE_BAND_915_HYBRID ) 01451 // Re-enable default channels 01452 ReenableChannels( ChannelsMask[4], ChannelsMask ); 01453 #else 01454 #error "Please define a frequency band in the compiler options." 01455 #endif 01456 LoRaMacState &= ~MAC_TX_RUNNING; 01457 01458 NodeAckRequested = false; 01459 McpsConfirm.AckReceived = false; 01460 McpsConfirm.NbRetries = AckTimeoutRetriesCounter; 01461 if( IsUpLinkCounterFixed == false ) 01462 { 01463 UpLinkCounter++; 01464 } 01465 } 01466 } 01467 } 01468 // Handle reception for Class B and Class C 01469 if( ( LoRaMacState & MAC_RX ) == MAC_RX ) 01470 { 01471 LoRaMacState &= ~MAC_RX; 01472 } 01473 if( LoRaMacState == MAC_IDLE ) 01474 { 01475 if( LoRaMacFlags.Bits.McpsReq == 1 ) 01476 { 01477 LoRaMacPrimitives->MacMcpsConfirm( &McpsConfirm ); 01478 LoRaMacFlags.Bits.McpsReq = 0; 01479 } 01480 01481 if( LoRaMacFlags.Bits.MlmeReq == 1 ) 01482 { 01483 LoRaMacPrimitives->MacMlmeConfirm( &MlmeConfirm ); 01484 LoRaMacFlags.Bits.MlmeReq = 0; 01485 } 01486 01487 LoRaMacFlags.Bits.MacDone = 0; 01488 } 01489 else 01490 { 01491 // Operation not finished restart timer 01492 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); 01493 TimerStart( &MacStateCheckTimer ); 01494 } 01495 01496 if( LoRaMacFlags.Bits.McpsInd == 1 ) 01497 { 01498 LoRaMacPrimitives->MacMcpsIndication( &McpsIndication ); 01499 LoRaMacFlags.Bits.McpsInd = 0; 01500 } 01501 } 01502 01503 static void OnTxDelayedTimerEvent( void ) 01504 { 01505 TimerStop( &TxDelayedTimer ); 01506 LoRaMacState &= ~MAC_TX_DELAYED; 01507 01508 ScheduleTx( ); 01509 } 01510 01511 static void OnRxWindow1TimerEvent( void ) 01512 { 01513 uint16_t symbTimeout = 5; // DR_2, DR_1, DR_0 01514 int8_t datarate = 0; 01515 uint32_t bandwidth = 0; // LoRa 125 kHz 01516 01517 TimerStop( &RxWindowTimer1 ); 01518 RxSlot = 0; 01519 01520 if( LoRaMacDeviceClass == CLASS_C ) 01521 { 01522 Radio.Standby( ); 01523 } 01524 01525 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 01526 datarate = ChannelsDatarate - Rx1DrOffset; 01527 if( datarate < 0 ) 01528 { 01529 datarate = DR_0; 01530 } 01531 01532 // For higher datarates, we increase the number of symbols generating a Rx Timeout 01533 if( ( datarate == DR_3 ) || ( datarate == DR_4 ) ) 01534 { // DR_4, DR_3 01535 symbTimeout = 8; 01536 } 01537 else if( datarate == DR_5 ) 01538 { 01539 symbTimeout = 10; 01540 } 01541 else if( datarate == DR_6 ) 01542 {// LoRa 250 kHz 01543 bandwidth = 1; 01544 symbTimeout = 14; 01545 } 01546 RxWindowSetup( Channels[Channel].Frequency, datarate, bandwidth, symbTimeout, false ); 01547 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) ) 01548 datarate = datarateOffsets[ChannelsDatarate][Rx1DrOffset]; 01549 if( datarate < 0 ) 01550 { 01551 datarate = DR_0; 01552 } 01553 // For higher datarates, we increase the number of symbols generating a Rx Timeout 01554 switch( datarate ) 01555 { 01556 case DR_0: // SF10 - BW125 01557 symbTimeout = 5; 01558 break; 01559 01560 case DR_1: // SF9 - BW125 01561 case DR_2: // SF8 - BW125 01562 case DR_8: // SF12 - BW500 01563 case DR_9: // SF11 - BW500 01564 case DR_10: // SF10 - BW500 01565 symbTimeout = 8; 01566 break; 01567 01568 case DR_3: // SF7 - BW125 01569 case DR_11: // SF9 - BW500 01570 symbTimeout = 10; 01571 break; 01572 01573 case DR_4: // SF8 - BW500 01574 case DR_12: // SF8 - BW500 01575 symbTimeout = 14; 01576 break; 01577 01578 case DR_13: // SF7 - BW500 01579 symbTimeout = 16; 01580 break; 01581 default: 01582 break; 01583 } 01584 if( datarate >= DR_4 ) 01585 {// LoRa 500 kHz 01586 bandwidth = 2; 01587 } 01588 RxWindowSetup( 923.3e6 + ( Channel % 8 ) * 600e3, datarate, bandwidth, symbTimeout, false ); 01589 #else 01590 #error "Please define a frequency band in the compiler options." 01591 #endif 01592 } 01593 01594 static void OnRxWindow2TimerEvent( void ) 01595 { 01596 uint16_t symbTimeout = 5; // DR_2, DR_1, DR_0 01597 uint32_t bandwidth = 0; // LoRa 125 kHz 01598 01599 TimerStop( &RxWindowTimer2 ); 01600 RxSlot = 1; 01601 01602 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 01603 // For higher datarates, we increase the number of symbols generating a Rx Timeout 01604 if( ( Rx2Channel.Datarate == DR_3 ) || ( Rx2Channel.Datarate == DR_4 ) ) 01605 { // DR_4, DR_3 01606 symbTimeout = 8; 01607 } 01608 else if( Rx2Channel.Datarate == DR_5 ) 01609 { 01610 symbTimeout = 10; 01611 } 01612 else if( Rx2Channel.Datarate == DR_6 ) 01613 {// LoRa 250 kHz 01614 bandwidth = 1; 01615 symbTimeout = 14; 01616 } 01617 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) ) 01618 // For higher datarates, we increase the number of symbols generating a Rx Timeout 01619 switch( Rx2Channel.Datarate ) 01620 { 01621 case DR_0: // SF10 - BW125 01622 symbTimeout = 5; 01623 break; 01624 01625 case DR_1: // SF9 - BW125 01626 case DR_2: // SF8 - BW125 01627 case DR_8: // SF12 - BW500 01628 case DR_9: // SF11 - BW500 01629 case DR_10: // SF10 - BW500 01630 symbTimeout = 8; 01631 break; 01632 01633 case DR_3: // SF7 - BW125 01634 case DR_11: // SF9 - BW500 01635 symbTimeout = 10; 01636 break; 01637 01638 case DR_4: // SF8 - BW500 01639 case DR_12: // SF8 - BW500 01640 symbTimeout = 14; 01641 break; 01642 01643 case DR_13: // SF7 - BW500 01644 symbTimeout = 16; 01645 break; 01646 default: 01647 break; 01648 } 01649 if( Rx2Channel.Datarate >= DR_4 ) 01650 {// LoRa 500 kHz 01651 bandwidth = 2; 01652 } 01653 #else 01654 #error "Please define a frequency band in the compiler options." 01655 #endif 01656 if( LoRaMacDeviceClass != CLASS_C ) 01657 { 01658 RxWindowSetup( Rx2Channel.Frequency , Rx2Channel.Datarate , bandwidth, symbTimeout, false ); 01659 } 01660 else 01661 { 01662 RxWindowSetup( Rx2Channel.Frequency , Rx2Channel.Datarate , bandwidth, symbTimeout, true ); 01663 } 01664 } 01665 01666 static void OnAckTimeoutTimerEvent( void ) 01667 { 01668 TimerStop( &AckTimeoutTimer ); 01669 01670 if( NodeAckRequested == true ) 01671 { 01672 AckTimeoutRetry = true; 01673 LoRaMacState &= ~MAC_ACK_REQ; 01674 } 01675 if( LoRaMacDeviceClass == CLASS_C ) 01676 { 01677 LoRaMacFlags.Bits.MacDone = 1; 01678 } 01679 } 01680 01681 static bool SetNextChannel( TimerTime_t* time ) 01682 { 01683 uint8_t nbEnabledChannels = 0; 01684 uint8_t delayTx = 0; 01685 uint8_t enabledChannels[LORA_MAX_NB_CHANNELS]; 01686 TimerTime_t nextTxDelay = ( TimerTime_t )( -1 ); 01687 01688 memset1( enabledChannels, 0, LORA_MAX_NB_CHANNELS ); 01689 01690 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 01691 if( CountNbEnabled125kHzChannels( ChannelsMaskRemaining ) == 0 ) 01692 { // Restore default channels 01693 memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) ChannelsMask, 8 ); 01694 } 01695 if( ( ChannelsDatarate >= DR_4 ) && ( ( ChannelsMaskRemaining[4] & 0x00FF ) == 0 ) ) 01696 { // Make sure, that the channels are activated 01697 ChannelsMaskRemaining[4] = ChannelsMask[4]; 01698 } 01699 #else 01700 if( CountBits( ChannelsMask[0], 16 ) == 0 ) 01701 { 01702 // Re-enable default channels, if no channel is enabled 01703 ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) ); 01704 } 01705 #endif 01706 01707 // Update Aggregated duty cycle 01708 if( AggregatedTimeOff <= TimerGetElapsedTime( AggregatedLastTxDoneTime ) ) 01709 { 01710 AggregatedTimeOff = 0; 01711 01712 // Update bands Time OFF 01713 for( uint8_t i = 0; i < LORA_MAX_NB_BANDS; i++ ) 01714 { 01715 if( DutyCycleOn == true ) 01716 { 01717 if( Bands[i].TimeOff <= TimerGetElapsedTime( Bands[i].LastTxDoneTime ) ) 01718 { 01719 Bands[i].TimeOff = 0; 01720 } 01721 if( Bands[i].TimeOff != 0 ) 01722 { 01723 nextTxDelay = MIN( Bands[i].TimeOff - 01724 TimerGetElapsedTime( Bands[i].LastTxDoneTime ), 01725 nextTxDelay ); 01726 } 01727 } 01728 else 01729 { 01730 nextTxDelay = 0; 01731 Bands[i].TimeOff = 0; 01732 } 01733 } 01734 01735 // Search how many channels are enabled 01736 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ ) 01737 { 01738 for( uint8_t j = 0; j < 16; j++ ) 01739 { 01740 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 01741 if( ( ChannelsMaskRemaining[k] & ( 1 << j ) ) != 0 ) 01742 #else 01743 if( ( ChannelsMask[k] & ( 1 << j ) ) != 0 ) 01744 #endif 01745 { 01746 if( Channels[i + j].Frequency == 0 ) 01747 { // Check if the channel is enabled 01748 continue; 01749 } 01750 #if defined( USE_BAND_868 ) || defined( USE_BAND_433 ) || defined( USE_BAND_780 ) 01751 if( IsLoRaMacNetworkJoined == false ) 01752 { 01753 if( ( JOIN_CHANNELS & ( 1 << j ) ) == 0 ) 01754 { 01755 continue; 01756 } 01757 } 01758 #endif 01759 if( ( ( Channels[i + j].DrRange.Fields.Min <= ChannelsDatarate ) && 01760 ( ChannelsDatarate <= Channels[i + j].DrRange .Fields.Max ) ) == false ) 01761 { // Check if the current channel selection supports the given datarate 01762 continue; 01763 } 01764 if( Bands[Channels[i + j].Band].TimeOff > 0 ) 01765 { // Check if the band is available for transmission 01766 delayTx++; 01767 continue; 01768 } 01769 enabledChannels[nbEnabledChannels++] = i + j; 01770 } 01771 } 01772 } 01773 } 01774 else 01775 { 01776 delayTx++; 01777 nextTxDelay = AggregatedTimeOff - TimerGetElapsedTime( AggregatedLastTxDoneTime ); 01778 } 01779 01780 if( nbEnabledChannels > 0 ) 01781 { 01782 Channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )]; 01783 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 01784 if( Channel < ( LORA_MAX_NB_CHANNELS - 8 ) ) 01785 { 01786 DisableChannelInMask( Channel, ChannelsMaskRemaining ); 01787 } 01788 #endif 01789 *time = 0; 01790 if (Force_channel) 01791 { 01792 // Hard_channel = Hard_channel+1; 01793 Hard_channel = 1; 01794 if (Hard_channel > 32) 01795 { 01796 printf ("channel wrap\r\n"); 01797 Hard_channel = 8; 01798 } 01799 Channel = Hard_channel; 01800 printf("Channel = changed to %d\r\n", Channel); 01801 } 01802 return true; 01803 } 01804 else 01805 { 01806 if( delayTx > 0 ) 01807 { 01808 // Delay transmission due to AggregatedTimeOff or to a band time off 01809 *time = nextTxDelay; 01810 return true; 01811 } 01812 // Datarate not supported by any channel 01813 *time = 0; 01814 return false; 01815 } 01816 } 01817 01818 static void SetPublicNetwork( bool enable ) 01819 { 01820 PublicNetwork = enable; 01821 Radio.SetModem( MODEM_LORA ); 01822 if( PublicNetwork == true ) 01823 { 01824 // Change LoRa modem SyncWord 01825 Radio.Write( REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD ); 01826 } 01827 else 01828 { 01829 // Change LoRa modem SyncWord 01830 Radio.Write( REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD ); 01831 } 01832 } 01833 01834 static void RxWindowSetup( uint32_t freq, int8_t datarate, uint32_t bandwidth, uint16_t timeout, bool rxContinuous ) 01835 { 01836 uint8_t downlinkDatarate = Datarates[datarate]; 01837 RadioModems_t modem; 01838 01839 if( Radio.GetStatus( ) == RF_IDLE ) 01840 { 01841 Radio.SetChannel( freq ); 01842 01843 // Store downlink datarate 01844 McpsIndication.RxDatarate = ( uint8_t ) datarate; 01845 01846 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 01847 if( datarate == DR_7 ) 01848 { 01849 modem = MODEM_FSK; 01850 Radio.SetRxConfig( modem, 50e3, downlinkDatarate * 1e3, 0, 83.333e3, 5, 0, false, 0, true, 0, 0, false, rxContinuous ); 01851 } 01852 else 01853 { 01854 modem = MODEM_LORA; 01855 Radio.SetRxConfig( modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous ); 01856 } 01857 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 01858 modem = MODEM_LORA; 01859 Radio.SetRxConfig( modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous ); 01860 #endif 01861 01862 if( RepeaterSupport == true ) 01863 { 01864 Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarateRepeater[datarate] + LORA_MAC_FRMPAYLOAD_OVERHEAD ); 01865 } 01866 else 01867 { 01868 Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarate[datarate] + LORA_MAC_FRMPAYLOAD_OVERHEAD ); 01869 } 01870 01871 if( rxContinuous == false ) 01872 { 01873 Radio.Rx( MaxRxWindow ); 01874 } 01875 else 01876 { 01877 Radio.Rx( 0 ); // Continuous mode 01878 } 01879 } 01880 } 01881 01882 static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen ) 01883 { 01884 uint16_t maxN = 0; 01885 uint16_t payloadSize = 0; 01886 01887 // Get the maximum payload length 01888 if( RepeaterSupport == true ) 01889 { 01890 maxN = MaxPayloadOfDatarateRepeater[datarate]; 01891 } 01892 else 01893 { 01894 maxN = MaxPayloadOfDatarate[datarate]; 01895 } 01896 01897 // Calculate the resulting payload size 01898 payloadSize = ( lenN + fOptsLen ); 01899 01900 // Validation of the application payload size 01901 if( ( payloadSize <= maxN ) && ( payloadSize <= LORAMAC_PHY_MAXPAYLOAD ) ) 01902 { 01903 return true; 01904 } 01905 return false; 01906 } 01907 01908 static uint8_t CountBits( uint16_t mask, uint8_t nbBits ) 01909 { 01910 uint8_t nbActiveBits = 0; 01911 01912 for( uint8_t j = 0; j < nbBits; j++ ) 01913 { 01914 if( ( mask & ( 1 << j ) ) == ( 1 << j ) ) 01915 { 01916 nbActiveBits++; 01917 } 01918 } 01919 return nbActiveBits; 01920 } 01921 01922 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 01923 static uint8_t CountNbEnabled125kHzChannels( uint16_t *channelsMask ) 01924 { 01925 uint8_t nb125kHzChannels = 0; 01926 01927 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS - 8; i += 16, k++ ) 01928 { 01929 nb125kHzChannels += CountBits( channelsMask[k], 16 ); 01930 } 01931 01932 return nb125kHzChannels; 01933 } 01934 01935 #if defined( USE_BAND_915_HYBRID ) 01936 static void ReenableChannels( uint16_t mask, uint16_t* channelMask ) 01937 { 01938 uint16_t blockMask = mask; 01939 01940 for( uint8_t i = 0, j = 0; i < 4; i++, j += 2 ) 01941 { 01942 channelMask[i] = 0; 01943 if( ( blockMask & ( 1 << j ) ) != 0 ) 01944 { 01945 channelMask[i] |= 0x00FF; 01946 } 01947 if( ( blockMask & ( 1 << ( j + 1 ) ) ) != 0 ) 01948 { 01949 channelMask[i] |= 0xFF00; 01950 } 01951 } 01952 channelMask[4] = blockMask; 01953 channelMask[5] = 0x0000; 01954 } 01955 01956 static bool ValidateChannelMask( uint16_t* channelMask ) 01957 { 01958 bool chanMaskState = false; 01959 uint16_t block1 = 0; 01960 uint16_t block2 = 0; 01961 uint8_t index = 0; 01962 01963 for( uint8_t i = 0; i < 4; i++ ) 01964 { 01965 block1 = channelMask[i] & 0x00FF; 01966 block2 = channelMask[i] & 0xFF00; 01967 01968 if( ( CountBits( block1, 16 ) > 5 ) && ( chanMaskState == false ) ) 01969 { 01970 channelMask[i] &= block1; 01971 channelMask[4] = 1 << ( i * 2 ); 01972 chanMaskState = true; 01973 index = i; 01974 } 01975 else if( ( CountBits( block2, 16 ) > 5 ) && ( chanMaskState == false ) ) 01976 { 01977 channelMask[i] &= block2; 01978 channelMask[4] = 1 << ( i * 2 + 1 ); 01979 chanMaskState = true; 01980 index = i; 01981 } 01982 } 01983 01984 // Do only change the channel mask, if we have found a valid block. 01985 if( chanMaskState == true ) 01986 { 01987 for( uint8_t i = 0; i < 4; i++ ) 01988 { 01989 if( i != index ) 01990 { 01991 channelMask[i] = 0; 01992 } 01993 } 01994 } 01995 return chanMaskState; 01996 } 01997 #endif 01998 #endif 01999 02000 static int8_t LimitTxPower( int8_t txPower ) 02001 { 02002 int8_t resultTxPower = txPower; 02003 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 02004 if( ( ChannelsDatarate == DR_4 ) || 02005 ( ( ChannelsDatarate >= DR_8 ) && ( ChannelsDatarate <= DR_13 ) ) ) 02006 {// Limit tx power to max 26dBm 02007 resultTxPower = MAX( txPower, TX_POWER_26_DBM ); 02008 } 02009 else 02010 { 02011 if( CountNbEnabled125kHzChannels( ChannelsMask ) < 50 ) 02012 {// Limit tx power to max 21dBm 02013 resultTxPower = MAX( txPower, TX_POWER_20_DBM ); 02014 } 02015 } 02016 #endif 02017 return resultTxPower; 02018 } 02019 02020 static bool ValueInRange( int8_t value, int8_t min, int8_t max ) 02021 { 02022 if( ( value >= min ) && ( value <= max ) ) 02023 { 02024 return true; 02025 } 02026 return false; 02027 } 02028 02029 static bool DisableChannelInMask( uint8_t id, uint16_t* mask ) 02030 { 02031 uint8_t index = 0; 02032 index = id / 16; 02033 02034 if( ( index > 4 ) || ( id >= LORA_MAX_NB_CHANNELS ) ) 02035 { 02036 return false; 02037 } 02038 02039 // Deactivate channel 02040 mask[index] &= ~( 1 << ( id % 16 ) ); 02041 02042 return true; 02043 } 02044 02045 static bool AdrNextDr( bool adrEnabled, bool updateChannelMask, int8_t* datarateOut ) 02046 { 02047 bool adrAckReq = false; 02048 int8_t datarate = ChannelsDatarate; 02049 02050 if( adrEnabled == true ) 02051 { 02052 if( datarate == LORAMAC_TX_MIN_DATARATE ) 02053 { 02054 AdrAckCounter = 0; 02055 adrAckReq = false; 02056 } 02057 else 02058 { 02059 if( AdrAckCounter >= ADR_ACK_LIMIT ) 02060 { 02061 adrAckReq = true; 02062 } 02063 else 02064 { 02065 adrAckReq = false; 02066 } 02067 if( AdrAckCounter >= ( ADR_ACK_LIMIT + ADR_ACK_DELAY ) ) 02068 { 02069 if( ( ( AdrAckCounter - ADR_ACK_DELAY ) % ADR_ACK_LIMIT ) == 0 ) 02070 { 02071 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 02072 if( datarate > LORAMAC_TX_MIN_DATARATE ) 02073 { 02074 datarate--; 02075 } 02076 if( datarate == LORAMAC_TX_MIN_DATARATE ) 02077 { 02078 if( updateChannelMask == true ) 02079 { 02080 02081 // Re-enable default channels LC1, LC2, LC3 02082 ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) ); 02083 } 02084 } 02085 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 02086 if( ( datarate > LORAMAC_TX_MIN_DATARATE ) && ( datarate == DR_8 ) ) 02087 { 02088 datarate = DR_4; 02089 } 02090 else if( datarate > LORAMAC_TX_MIN_DATARATE ) 02091 { 02092 datarate--; 02093 } 02094 if( datarate == LORAMAC_TX_MIN_DATARATE ) 02095 { 02096 if( updateChannelMask == true ) 02097 { 02098 #if defined( USE_BAND_915 ) 02099 // Re-enable default channels 02100 ChannelsMask[0] = 0xFFFF; 02101 ChannelsMask[1] = 0xFFFF; 02102 ChannelsMask[2] = 0xFFFF; 02103 ChannelsMask[3] = 0xFFFF; 02104 ChannelsMask[4] = 0x00FF; 02105 ChannelsMask[5] = 0x0000; 02106 #else // defined( USE_BAND_915_HYBRID ) 02107 // Re-enable default channels 02108 ReenableChannels( ChannelsMask[4], ChannelsMask ); 02109 #endif 02110 } 02111 } 02112 #else 02113 #error "Please define a frequency band in the compiler options." 02114 #endif 02115 } 02116 } 02117 } 02118 } 02119 02120 *datarateOut = datarate; 02121 02122 return adrAckReq; 02123 } 02124 02125 static LoRaMacStatus_t AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 ) 02126 { 02127 LoRaMacStatus_t status = LORAMAC_STATUS_BUSY ; 02128 02129 switch( cmd ) 02130 { 02131 case MOTE_MAC_LINK_CHECK_REQ : 02132 if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH ) 02133 { 02134 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02135 // No payload for this command 02136 status = LORAMAC_STATUS_OK ; 02137 } 02138 break; 02139 case MOTE_MAC_LINK_ADR_ANS : 02140 if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) ) 02141 { 02142 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02143 // Margin 02144 MacCommandsBuffer[MacCommandsBufferIndex++] = p1; 02145 status = LORAMAC_STATUS_OK ; 02146 } 02147 break; 02148 case MOTE_MAC_DUTY_CYCLE_ANS : 02149 if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH ) 02150 { 02151 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02152 // No payload for this answer 02153 status = LORAMAC_STATUS_OK ; 02154 } 02155 break; 02156 case MOTE_MAC_RX_PARAM_SETUP_ANS : 02157 if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) ) 02158 { 02159 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02160 // Status: Datarate ACK, Channel ACK 02161 MacCommandsBuffer[MacCommandsBufferIndex++] = p1; 02162 status = LORAMAC_STATUS_OK ; 02163 } 02164 break; 02165 case MOTE_MAC_DEV_STATUS_ANS : 02166 if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 2 ) ) 02167 { 02168 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02169 // 1st byte Battery 02170 // 2nd byte Margin 02171 MacCommandsBuffer[MacCommandsBufferIndex++] = p1; 02172 MacCommandsBuffer[MacCommandsBufferIndex++] = p2; 02173 status = LORAMAC_STATUS_OK ; 02174 } 02175 break; 02176 case MOTE_MAC_NEW_CHANNEL_ANS : 02177 if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) ) 02178 { 02179 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02180 // Status: Datarate range OK, Channel frequency OK 02181 MacCommandsBuffer[MacCommandsBufferIndex++] = p1; 02182 status = LORAMAC_STATUS_OK ; 02183 } 02184 break; 02185 case MOTE_MAC_RX_TIMING_SETUP_ANS : 02186 if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH ) 02187 { 02188 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02189 // No payload for this answer 02190 status = LORAMAC_STATUS_OK ; 02191 } 02192 break; 02193 default: 02194 return LORAMAC_STATUS_SERVICE_UNKNOWN ; 02195 } 02196 if( status == LORAMAC_STATUS_OK ) 02197 { 02198 MacCommandsInNextTx = true; 02199 } 02200 return status; 02201 } 02202 02203 static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr ) 02204 { 02205 while( macIndex < commandsSize ) 02206 { 02207 // Decode Frame MAC commands 02208 switch( payload[macIndex++] ) 02209 { 02210 case SRV_MAC_LINK_CHECK_ANS : 02211 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK ; 02212 MlmeConfirm.DemodMargin = payload[macIndex++]; 02213 MlmeConfirm.NbGateways = payload[macIndex++]; 02214 break; 02215 case SRV_MAC_LINK_ADR_REQ : 02216 { 02217 uint8_t i; 02218 uint8_t status = 0x07; 02219 uint16_t chMask; 02220 int8_t txPower = 0; 02221 int8_t datarate = 0; 02222 uint8_t nbRep = 0; 02223 uint8_t chMaskCntl = 0; 02224 uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 }; 02225 02226 // Initialize local copy of the channels mask array 02227 for( i = 0; i < 6; i++ ) 02228 { 02229 channelsMask[i] = ChannelsMask[i]; 02230 } 02231 datarate = payload[macIndex++]; 02232 txPower = datarate & 0x0F; 02233 datarate = ( datarate >> 4 ) & 0x0F; 02234 02235 if( ( AdrCtrlOn == false ) && 02236 ( ( ChannelsDatarate != datarate ) || ( ChannelsTxPower != txPower ) ) ) 02237 { // ADR disabled don't handle ADR requests if server tries to change datarate or txpower 02238 // Answer the server with fail status 02239 // Power ACK = 0 02240 // Data rate ACK = 0 02241 // Channel mask = 0 02242 AddMacCommand( MOTE_MAC_LINK_ADR_ANS , 0, 0 ); 02243 macIndex += 3; // Skip over the remaining bytes of the request 02244 break; 02245 } 02246 chMask = ( uint16_t )payload[macIndex++]; 02247 chMask |= ( uint16_t )payload[macIndex++] << 8; 02248 02249 nbRep = payload[macIndex++]; 02250 chMaskCntl = ( nbRep >> 4 ) & 0x07; 02251 nbRep &= 0x0F; 02252 if( nbRep == 0 ) 02253 { 02254 nbRep = 1; 02255 } 02256 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 02257 if( ( chMaskCntl == 0 ) && ( chMask == 0 ) ) 02258 { 02259 status &= 0xFE; // Channel mask KO 02260 } 02261 else if( ( ( chMaskCntl >= 1 ) && ( chMaskCntl <= 5 )) || 02262 ( chMaskCntl >= 7 ) ) 02263 { 02264 // RFU 02265 status &= 0xFE; // Channel mask KO 02266 } 02267 else 02268 { 02269 for( i = 0; i < LORA_MAX_NB_CHANNELS; i++ ) 02270 { 02271 if( chMaskCntl == 6 ) 02272 { 02273 if( Channels[i].Frequency != 0 ) 02274 { 02275 chMask |= 1 << i; 02276 } 02277 } 02278 else 02279 { 02280 if( ( ( chMask & ( 1 << i ) ) != 0 ) && 02281 ( Channels[i].Frequency == 0 ) ) 02282 {// Trying to enable an undefined channel 02283 status &= 0xFE; // Channel mask KO 02284 } 02285 } 02286 } 02287 channelsMask[0] = chMask; 02288 } 02289 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 02290 if( chMaskCntl == 6 ) 02291 { 02292 // Enable all 125 kHz channels 02293 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS - 8; i += 16, k++ ) 02294 { 02295 for( uint8_t j = 0; j < 16; j++ ) 02296 { 02297 if( Channels[i + j].Frequency != 0 ) 02298 { 02299 channelsMask[k] |= 1 << j; 02300 } 02301 } 02302 } 02303 } 02304 else if( chMaskCntl == 7 ) 02305 { 02306 // Disable all 125 kHz channels 02307 channelsMask[0] = 0x0000; 02308 channelsMask[1] = 0x0000; 02309 channelsMask[2] = 0x0000; 02310 channelsMask[3] = 0x0000; 02311 } 02312 else if( chMaskCntl == 5 ) 02313 { 02314 // RFU 02315 status &= 0xFE; // Channel mask KO 02316 } 02317 else 02318 { 02319 for( uint8_t i = 0; i < 16; i++ ) 02320 { 02321 if( ( ( chMask & ( 1 << i ) ) != 0 ) && 02322 ( Channels[chMaskCntl * 16 + i].Frequency == 0 ) ) 02323 {// Trying to enable an undefined channel 02324 status &= 0xFE; // Channel mask KO 02325 } 02326 } 02327 channelsMask[chMaskCntl] = chMask; 02328 02329 if( CountNbEnabled125kHzChannels( channelsMask ) < 6 ) 02330 { 02331 status &= 0xFE; // Channel mask KO 02332 } 02333 02334 #if defined( USE_BAND_915_HYBRID ) 02335 if( ValidateChannelMask( channelsMask ) == false ) 02336 { 02337 status &= 0xFE; // Channel mask KO 02338 } 02339 #endif 02340 } 02341 #else 02342 #error "Please define a frequency band in the compiler options." 02343 #endif 02344 if( ValueInRange( datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == false ) 02345 { 02346 status &= 0xFD; // Datarate KO 02347 } 02348 02349 // 02350 // Remark MaxTxPower = 0 and MinTxPower = 5 02351 // 02352 if( ValueInRange( txPower, LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) == false ) 02353 { 02354 status &= 0xFB; // TxPower KO 02355 } 02356 if( ( status & 0x07 ) == 0x07 ) 02357 { 02358 ChannelsDatarate = datarate; 02359 ChannelsTxPower = txPower; 02360 02361 ChannelsMask[0] = channelsMask[0]; 02362 ChannelsMask[1] = channelsMask[1]; 02363 ChannelsMask[2] = channelsMask[2]; 02364 ChannelsMask[3] = channelsMask[3]; 02365 ChannelsMask[4] = channelsMask[4]; 02366 ChannelsMask[5] = channelsMask[5]; 02367 02368 ChannelsNbRep = nbRep; 02369 } 02370 AddMacCommand( MOTE_MAC_LINK_ADR_ANS , status, 0 ); 02371 } 02372 break; 02373 case SRV_MAC_DUTY_CYCLE_REQ : 02374 MaxDCycle = payload[macIndex++]; 02375 AggregatedDCycle = 1 << MaxDCycle; 02376 AddMacCommand( MOTE_MAC_DUTY_CYCLE_ANS , 0, 0 ); 02377 break; 02378 case SRV_MAC_RX_PARAM_SETUP_REQ : 02379 { 02380 uint8_t status = 0x07; 02381 int8_t datarate = 0; 02382 int8_t drOffset = 0; 02383 uint32_t freq = 0; 02384 02385 drOffset = ( payload[macIndex] >> 4 ) & 0x07; 02386 datarate = payload[macIndex] & 0x0F; 02387 macIndex++; 02388 02389 freq = ( uint32_t )payload[macIndex++]; 02390 freq |= ( uint32_t )payload[macIndex++] << 8; 02391 freq |= ( uint32_t )payload[macIndex++] << 16; 02392 freq *= 100; 02393 02394 if( Radio.CheckRfFrequency( freq ) == false ) 02395 { 02396 status &= 0xFE; // Channel frequency KO 02397 } 02398 02399 if( ValueInRange( datarate, LORAMAC_RX_MIN_DATARATE, LORAMAC_RX_MAX_DATARATE ) == false ) 02400 { 02401 status &= 0xFD; // Datarate KO 02402 } 02403 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) ) 02404 if( ( ValueInRange( datarate, DR_5, DR_7 ) == true ) || 02405 ( datarate > DR_13 ) ) 02406 { 02407 status &= 0xFD; // Datarate KO 02408 } 02409 #endif 02410 if( ValueInRange( drOffset, LORAMAC_MIN_RX1_DR_OFFSET, LORAMAC_MAX_RX1_DR_OFFSET ) == false ) 02411 { 02412 status &= 0xFB; // Rx1DrOffset range KO 02413 } 02414 02415 if( ( status & 0x07 ) == 0x07 ) 02416 { 02417 Rx2Channel.Datarate = datarate; 02418 Rx2Channel.Frequency = freq; 02419 Rx1DrOffset = drOffset; 02420 } 02421 AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS , status, 0 ); 02422 } 02423 break; 02424 case SRV_MAC_DEV_STATUS_REQ : 02425 { 02426 uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE ; 02427 if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->GetBatteryLevel != NULL ) ) 02428 { 02429 batteryLevel = LoRaMacCallbacks->GetBatteryLevel( ); 02430 } 02431 AddMacCommand( MOTE_MAC_DEV_STATUS_ANS , batteryLevel, snr ); 02432 break; 02433 } 02434 case SRV_MAC_NEW_CHANNEL_REQ : 02435 { 02436 uint8_t status = 0x03; 02437 02438 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) ) 02439 status &= 0xFC; // Channel frequency and datarate KO 02440 macIndex += 5; 02441 #else 02442 int8_t channelIndex = 0; 02443 ChannelParams_t chParam; 02444 02445 channelIndex = payload[macIndex++]; 02446 chParam.Frequency = ( uint32_t )payload[macIndex++]; 02447 chParam.Frequency |= ( uint32_t )payload[macIndex++] << 8; 02448 chParam.Frequency |= ( uint32_t )payload[macIndex++] << 16; 02449 chParam.Frequency *= 100; 02450 chParam.DrRange .Value = payload[macIndex++]; 02451 02452 LoRaMacState |= MAC_TX_CONFIG; 02453 if( chParam.Frequency == 0 ) 02454 { 02455 if( channelIndex < 3 ) 02456 { 02457 status &= 0xFC; 02458 } 02459 else 02460 { 02461 if( LoRaMacChannelRemove( channelIndex ) != LORAMAC_STATUS_OK ) 02462 { 02463 status &= 0xFC; 02464 } 02465 } 02466 } 02467 else 02468 { 02469 switch( LoRaMacChannelAdd( channelIndex, chParam ) ) 02470 { 02471 case LORAMAC_STATUS_OK : 02472 { 02473 break; 02474 } 02475 case LORAMAC_STATUS_FREQUENCY_INVALID : 02476 { 02477 status &= 0xFE; 02478 break; 02479 } 02480 case LORAMAC_STATUS_DATARATE_INVALID : 02481 { 02482 status &= 0xFD; 02483 break; 02484 } 02485 case LORAMAC_STATUS_FREQ_AND_DR_INVALID : 02486 { 02487 status &= 0xFC; 02488 break; 02489 } 02490 default: 02491 { 02492 status &= 0xFC; 02493 break; 02494 } 02495 } 02496 } 02497 LoRaMacState &= ~MAC_TX_CONFIG; 02498 #endif 02499 AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS , status, 0 ); 02500 } 02501 break; 02502 case SRV_MAC_RX_TIMING_SETUP_REQ : 02503 { 02504 uint8_t delay = payload[macIndex++] & 0x0F; 02505 02506 if( delay == 0 ) 02507 { 02508 delay++; 02509 } 02510 ReceiveDelay1 = delay * 1e6; 02511 ReceiveDelay2 = ReceiveDelay1 + 1e6; 02512 AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS , 0, 0 ); 02513 } 02514 break; 02515 default: 02516 // Unknown command. ABORT MAC commands processing 02517 return; 02518 } 02519 } 02520 } 02521 02522 LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) 02523 { 02524 LoRaMacFrameCtrl_t fCtrl; 02525 LoRaMacStatus_t status = LORAMAC_STATUS_PARAMETER_INVALID ; 02526 02527 fCtrl.Value = 0; 02528 fCtrl.Bits.FOptsLen = 0; 02529 fCtrl.Bits.FPending = 0; 02530 fCtrl.Bits.Ack = false; 02531 fCtrl.Bits.AdrAckReq = false; 02532 fCtrl.Bits.Adr = AdrCtrlOn; 02533 02534 // Prepare the frame 02535 status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize ); 02536 02537 // Validate status 02538 if( status != LORAMAC_STATUS_OK ) 02539 { 02540 return status; 02541 } 02542 02543 // Reset confirm parameters 02544 McpsConfirm.NbRetries = 0; 02545 McpsConfirm.AckReceived = false; 02546 McpsConfirm.UpLinkCounter = UpLinkCounter; 02547 02548 status = ScheduleTx( ); 02549 02550 return status; 02551 } 02552 02553 static LoRaMacStatus_t ScheduleTx( ) 02554 { 02555 TimerTime_t dutyCycleTimeOff = 0; 02556 02557 // Check if the device is off 02558 if( MaxDCycle == 255 ) 02559 { 02560 return LORAMAC_STATUS_DEVICE_OFF ; 02561 } 02562 if( MaxDCycle == 0 ) 02563 { 02564 AggregatedTimeOff = 0; 02565 } 02566 02567 CalculateBackOff( LastTxChannel ); 02568 02569 // Select channel 02570 while( SetNextChannel( &dutyCycleTimeOff ) == false ) 02571 { 02572 // Set the default datarate 02573 ChannelsDatarate = ChannelsDefaultDatarate; 02574 02575 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 02576 // Re-enable default channels LC1, LC2, LC3 02577 ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) ); 02578 #endif 02579 } 02580 02581 // Schedule transmission of frame 02582 if( dutyCycleTimeOff == 0 ) 02583 { 02584 // Try to send now 02585 return SendFrameOnChannel( Channels[Channel] ); 02586 } 02587 else 02588 { 02589 // Send later - prepare timer 02590 LoRaMacState |= MAC_TX_DELAYED; 02591 TimerSetValue( &TxDelayedTimer, dutyCycleTimeOff ); 02592 TimerStart( &TxDelayedTimer ); 02593 02594 return LORAMAC_STATUS_OK ; 02595 } 02596 } 02597 02598 static void CalculateBackOff( uint8_t channel ) 02599 { 02600 uint16_t dutyCycle = Bands[Channels[channel].Band ].DCycle ; 02601 02602 if( IsLoRaMacNetworkJoined == false ) 02603 { 02604 #if defined( USE_BAND_868 ) || defined( USE_BAND_433 ) || defined( USE_BAND_780 ) 02605 dutyCycle = JOIN_DC; 02606 #endif 02607 } 02608 02609 // Update Band Time OFF 02610 if( DutyCycleOn == true ) 02611 { 02612 Bands[Channels[channel].Band ].TimeOff = TxTimeOnAir * dutyCycle - TxTimeOnAir; 02613 } 02614 else 02615 { 02616 Bands[Channels[channel].Band ].TimeOff = 0; 02617 } 02618 // Update Aggregated Time OFF 02619 AggregatedTimeOff = AggregatedTimeOff + ( TxTimeOnAir * AggregatedDCycle - TxTimeOnAir ); 02620 } 02621 02622 LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) 02623 { 02624 uint16_t i; 02625 uint8_t pktHeaderLen = 0; 02626 uint32_t mic = 0; 02627 const void* payload = fBuffer; 02628 uint8_t payloadSize = fBufferSize; 02629 uint8_t framePort = fPort; 02630 02631 LoRaMacBufferPktLen = 0; 02632 02633 NodeAckRequested = false; 02634 02635 if( fBuffer == NULL ) 02636 { 02637 fBufferSize = 0; 02638 } 02639 02640 LoRaMacBuffer[pktHeaderLen++] = macHdr->Value ; 02641 02642 switch( macHdr->Bits.MType ) 02643 { 02644 case FRAME_TYPE_JOIN_REQ : 02645 RxWindow1Delay = JoinAcceptDelay1 - RADIO_WAKEUP_TIME; 02646 RxWindow2Delay = JoinAcceptDelay2 - RADIO_WAKEUP_TIME; 02647 02648 LoRaMacBufferPktLen = pktHeaderLen; 02649 02650 memcpyr( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacAppEui, 8 ); 02651 LoRaMacBufferPktLen += 8; 02652 memcpyr( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacDevEui, 8 ); 02653 LoRaMacBufferPktLen += 8; 02654 02655 LoRaMacDevNonce = Radio.Random( ); 02656 02657 LoRaMacBuffer[LoRaMacBufferPktLen++] = LoRaMacDevNonce & 0xFF; 02658 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( LoRaMacDevNonce >> 8 ) & 0xFF; 02659 02660 LoRaMacJoinComputeMic ( LoRaMacBuffer, LoRaMacBufferPktLen & 0xFF, LoRaMacAppKey, &mic ); 02661 02662 LoRaMacBuffer[LoRaMacBufferPktLen++] = mic & 0xFF; 02663 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 8 ) & 0xFF; 02664 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 16 ) & 0xFF; 02665 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 24 ) & 0xFF; 02666 02667 break; 02668 case FRAME_TYPE_DATA_CONFIRMED_UP : 02669 NodeAckRequested = true; 02670 //Intentional falltrough 02671 case FRAME_TYPE_DATA_UNCONFIRMED_UP : 02672 if( IsLoRaMacNetworkJoined == false ) 02673 { 02674 return LORAMAC_STATUS_NO_NETWORK_JOINED ; // No network has been joined yet 02675 } 02676 02677 fCtrl->Bits.AdrAckReq = AdrNextDr( fCtrl->Bits.Adr , true, &ChannelsDatarate ); 02678 02679 if( ValidatePayloadLength( fBufferSize, ChannelsDatarate, MacCommandsBufferIndex ) == false ) 02680 { 02681 return LORAMAC_STATUS_LENGTH_ERROR ; 02682 } 02683 02684 RxWindow1Delay = ReceiveDelay1 - RADIO_WAKEUP_TIME; 02685 RxWindow2Delay = ReceiveDelay2 - RADIO_WAKEUP_TIME; 02686 02687 if( SrvAckRequested == true ) 02688 { 02689 SrvAckRequested = false; 02690 fCtrl->Bits.Ack = 1; 02691 } 02692 02693 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr ) & 0xFF; 02694 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 8 ) & 0xFF; 02695 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 16 ) & 0xFF; 02696 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 24 ) & 0xFF; 02697 02698 LoRaMacBuffer[pktHeaderLen++] = fCtrl->Value ; 02699 02700 LoRaMacBuffer[pktHeaderLen++] = UpLinkCounter & 0xFF; 02701 LoRaMacBuffer[pktHeaderLen++] = ( UpLinkCounter >> 8 ) & 0xFF; 02702 02703 if( ( payload != NULL ) && ( payloadSize > 0 ) ) 02704 { 02705 if( ( MacCommandsBufferIndex <= LORA_MAC_COMMAND_MAX_LENGTH ) && ( MacCommandsInNextTx == true ) ) 02706 { 02707 fCtrl->Bits.FOptsLen += MacCommandsBufferIndex; 02708 02709 // Update FCtrl field with new value of OptionsLength 02710 LoRaMacBuffer[0x05] = fCtrl->Value ; 02711 for( i = 0; i < MacCommandsBufferIndex; i++ ) 02712 { 02713 LoRaMacBuffer[pktHeaderLen++] = MacCommandsBuffer[i]; 02714 } 02715 } 02716 } 02717 else 02718 { 02719 if( ( MacCommandsBufferIndex > 0 ) && ( MacCommandsInNextTx ) ) 02720 { 02721 payloadSize = MacCommandsBufferIndex; 02722 payload = MacCommandsBuffer; 02723 framePort = 0; 02724 } 02725 } 02726 MacCommandsInNextTx = false; 02727 MacCommandsBufferIndex = 0; 02728 02729 if( ( payload != NULL ) && ( payloadSize > 0 ) ) 02730 { 02731 LoRaMacBuffer[pktHeaderLen++] = framePort; 02732 02733 if( framePort == 0 ) 02734 { 02735 LoRaMacPayloadEncrypt ( (uint8_t* ) payload, payloadSize, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, LoRaMacPayload ); 02736 } 02737 else 02738 { 02739 LoRaMacPayloadEncrypt ( (uint8_t* ) payload, payloadSize, LoRaMacAppSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, LoRaMacPayload ); 02740 } 02741 memcpy1( LoRaMacBuffer + pktHeaderLen, LoRaMacPayload, payloadSize ); 02742 } 02743 LoRaMacBufferPktLen = pktHeaderLen + payloadSize; 02744 02745 LoRaMacComputeMic( LoRaMacBuffer, LoRaMacBufferPktLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &mic ); 02746 02747 LoRaMacBuffer[LoRaMacBufferPktLen + 0] = mic & 0xFF; 02748 LoRaMacBuffer[LoRaMacBufferPktLen + 1] = ( mic >> 8 ) & 0xFF; 02749 LoRaMacBuffer[LoRaMacBufferPktLen + 2] = ( mic >> 16 ) & 0xFF; 02750 LoRaMacBuffer[LoRaMacBufferPktLen + 3] = ( mic >> 24 ) & 0xFF; 02751 02752 LoRaMacBufferPktLen += LORAMAC_MFR_LEN; 02753 02754 break; 02755 case FRAME_TYPE_PROPRIETARY : 02756 if( ( fBuffer != NULL ) && ( fBufferSize > 0 ) ) 02757 { 02758 memcpy1( LoRaMacBuffer + pktHeaderLen, ( uint8_t* ) fBuffer, fBufferSize ); 02759 LoRaMacBufferPktLen = pktHeaderLen + fBufferSize; 02760 } 02761 break; 02762 default: 02763 return LORAMAC_STATUS_SERVICE_UNKNOWN ; 02764 } 02765 02766 return LORAMAC_STATUS_OK ; 02767 } 02768 02769 int do_high_power; 02770 02771 02772 LoRaMacStatus_t SendFrameOnChannel( ChannelParams_t channel ) 02773 { 02774 int8_t datarate = Datarates[ChannelsDatarate]; 02775 if (Force_channel) 02776 { 02777 // printf("force DR\n"); 02778 // datarate = DR_1; 02779 } 02780 int8_t txPowerIndex = 0; 02781 int8_t txPower = 0; 02782 02783 txPowerIndex = LimitTxPower( ChannelsTxPower ); 02784 txPower = TxPowers[txPowerIndex]; 02785 if (do_high_power) 02786 { 02787 txPower = 30; 02788 02789 } 02790 02791 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 02792 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 02793 McpsConfirm.Datarate = ChannelsDatarate; 02794 McpsConfirm.TxPower = txPowerIndex; 02795 02796 Radio.SetChannel( channel.Frequency ); 02797 02798 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 02799 if( ChannelsDatarate == DR_7 ) 02800 { // High Speed FSK channel 02801 Radio.SetMaxPayloadLength( MODEM_FSK, LoRaMacBufferPktLen ); 02802 Radio.SetTxConfig( MODEM_FSK, txPower, 25e3, 0, datarate * 1e3, 0, 5, false, true, 0, 0, false, 3e6 ); 02803 TxTimeOnAir = Radio.TimeOnAir( MODEM_FSK, LoRaMacBufferPktLen ); 02804 02805 } 02806 else if( ChannelsDatarate == DR_6 ) 02807 { // High speed LoRa channel 02808 Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen ); 02809 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 1, datarate, 1, 8, false, true, 0, 0, false, 3e6 ); 02810 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen ); 02811 } 02812 else 02813 { // Normal LoRa channel 02814 Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen ); 02815 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e6 ); 02816 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen ); 02817 } 02818 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 02819 Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen ); 02820 if( ChannelsDatarate >= DR_4 ) 02821 { // High speed LoRa channel BW500 kHz 02822 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 2, datarate, 1, 8, false, true, 0, 0, false, 3e6 ); 02823 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen ); 02824 } 02825 else 02826 { // Normal LoRa channel 02827 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e6 ); 02828 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen ); 02829 } 02830 #else 02831 #error "Please define a frequency band in the compiler options." 02832 #endif 02833 02834 // Store the time on air 02835 McpsConfirm.TxTimeOnAir = TxTimeOnAir; 02836 MlmeConfirm.TxTimeOnAir = TxTimeOnAir; 02837 02838 // Starts the MAC layer status check timer 02839 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); 02840 TimerStart( &MacStateCheckTimer ); 02841 02842 // Send now 02843 Radio.Send( LoRaMacBuffer, LoRaMacBufferPktLen ); 02844 02845 LoRaMacState |= MAC_TX_RUNNING; 02846 02847 return LORAMAC_STATUS_OK ; 02848 } 02849 02850 LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t *primitives, LoRaMacCallback_t *callbacks ) 02851 { 02852 if( primitives == NULL ) 02853 { 02854 return LORAMAC_STATUS_PARAMETER_INVALID ; 02855 } 02856 02857 if( ( primitives->MacMcpsConfirm == NULL ) || 02858 ( primitives->MacMcpsIndication == NULL ) || 02859 ( primitives->MacMlmeConfirm == NULL )) 02860 { 02861 return LORAMAC_STATUS_PARAMETER_INVALID ; 02862 } 02863 02864 LoRaMacPrimitives = primitives; 02865 LoRaMacCallbacks = callbacks; 02866 02867 LoRaMacFlags.Value = 0; 02868 02869 LoRaMacDeviceClass = CLASS_A ; 02870 02871 UpLinkCounter = 1; 02872 DownLinkCounter = 0; 02873 AdrAckCounter = 0; 02874 02875 RepeaterSupport = false; 02876 IsRxWindowsEnabled = true; 02877 IsLoRaMacNetworkJoined = false; 02878 LoRaMacState = MAC_IDLE; 02879 02880 #if defined( USE_BAND_433 ) 02881 ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); 02882 #elif defined( USE_BAND_780 ) 02883 ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); 02884 #elif defined( USE_BAND_868 ) 02885 ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); 02886 #elif defined( USE_BAND_915 ) 02887 ChannelsMask[0] = 0xFFFF; 02888 ChannelsMask[1] = 0xFFFF; 02889 ChannelsMask[2] = 0xFFFF; 02890 ChannelsMask[3] = 0xFFFF; 02891 ChannelsMask[4] = 0x00FF; 02892 ChannelsMask[5] = 0x0000; 02893 02894 memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) ChannelsMask, sizeof( ChannelsMask ) ); 02895 #elif defined( USE_BAND_915_HYBRID ) 02896 ChannelsMask[0] = 0x00FF; 02897 ChannelsMask[1] = 0x0000; 02898 ChannelsMask[2] = 0x0000; 02899 ChannelsMask[3] = 0x0000; 02900 ChannelsMask[4] = 0x0001; 02901 ChannelsMask[5] = 0x0000; 02902 02903 memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) ChannelsMask, sizeof( ChannelsMask ) ); 02904 #else 02905 #error "Please define a frequency band in the compiler options." 02906 #endif 02907 02908 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 02909 // 125 kHz channels 02910 for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS - 8; i++ ) 02911 { 02912 Channels[i].Frequency = 902.3e6 + i * 200e3; 02913 Channels[i].DrRange .Value = ( DR_3 << 4 ) | DR_0; 02914 Channels[i].Band = 0; 02915 } 02916 // 500 kHz channels 02917 for( uint8_t i = LORA_MAX_NB_CHANNELS - 8; i < LORA_MAX_NB_CHANNELS; i++ ) 02918 { 02919 Channels[i].Frequency = 903.0e6 + ( i - ( LORA_MAX_NB_CHANNELS - 8 ) ) * 1.6e6; 02920 Channels[i].DrRange .Value = ( DR_4 << 4 ) | DR_4; 02921 Channels[i].Band = 0; 02922 } 02923 #endif 02924 02925 ChannelsTxPower = LORAMAC_DEFAULT_TX_POWER; 02926 ChannelsDefaultDatarate = ChannelsDatarate = LORAMAC_DEFAULT_DATARATE; 02927 ChannelsNbRep = 1; 02928 ChannelsNbRepCounter = 0; 02929 02930 MaxDCycle = 0; 02931 AggregatedDCycle = 1; 02932 AggregatedLastTxDoneTime = 0; 02933 AggregatedTimeOff = 0; 02934 02935 #if defined( USE_BAND_433 ) 02936 DutyCycleOn = false; 02937 #elif defined( USE_BAND_780 ) 02938 DutyCycleOn = false; 02939 #elif defined( USE_BAND_868 ) 02940 DutyCycleOn = true; 02941 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 02942 DutyCycleOn = false; 02943 #else 02944 #error "Please define a frequency band in the compiler options." 02945 #endif 02946 02947 MaxRxWindow = MAX_RX_WINDOW; 02948 ReceiveDelay1 = RECEIVE_DELAY1; 02949 ReceiveDelay2 = RECEIVE_DELAY2; 02950 JoinAcceptDelay1 = JOIN_ACCEPT_DELAY1; 02951 JoinAcceptDelay2 = JOIN_ACCEPT_DELAY2; 02952 02953 TimerInit( &MacStateCheckTimer, OnMacStateCheckTimerEvent ); 02954 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); 02955 02956 TimerInit( &TxDelayedTimer, OnTxDelayedTimerEvent ); 02957 TimerInit( &RxWindowTimer1, OnRxWindow1TimerEvent ); 02958 TimerInit( &RxWindowTimer2, OnRxWindow2TimerEvent ); 02959 TimerInit( &AckTimeoutTimer, OnAckTimeoutTimerEvent ); 02960 02961 // Initialize Radio driver 02962 RadioEvents.TxDone = OnRadioTxDone; 02963 RadioEvents.RxDone = OnRadioRxDone; 02964 RadioEvents.RxError = OnRadioRxError; 02965 RadioEvents.TxTimeout = OnRadioTxTimeout; 02966 RadioEvents.RxTimeout = OnRadioRxTimeout; 02967 Radio.Init( &RadioEvents ); 02968 02969 // Random seed initialization 02970 srand1( Radio.Random( ) ); 02971 02972 // Initialize channel index. 02973 Channel = LORA_MAX_NB_CHANNELS; 02974 02975 PublicNetwork = true; 02976 SetPublicNetwork( PublicNetwork ); 02977 Radio.Sleep( ); 02978 02979 return LORAMAC_STATUS_OK ; 02980 } 02981 02982 LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t * txInfo ) 02983 { 02984 int8_t datarate = ChannelsDefaultDatarate; 02985 02986 if( txInfo == NULL ) 02987 { 02988 return LORAMAC_STATUS_PARAMETER_INVALID ; 02989 } 02990 02991 AdrNextDr( AdrCtrlOn, false, &datarate ); 02992 02993 if( RepeaterSupport == true ) 02994 { 02995 txInfo->CurrentPayloadSize = MaxPayloadOfDatarateRepeater[datarate]; 02996 } 02997 else 02998 { 02999 txInfo->CurrentPayloadSize = MaxPayloadOfDatarate[datarate]; 03000 } 03001 03002 if( txInfo->CurrentPayloadSize >= MacCommandsBufferIndex ) 03003 { 03004 txInfo->MaxPossiblePayload = txInfo->CurrentPayloadSize - MacCommandsBufferIndex; 03005 } 03006 else 03007 { 03008 return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR ; 03009 } 03010 03011 if( ValidatePayloadLength( size, datarate, 0 ) == false ) 03012 { 03013 return LORAMAC_STATUS_LENGTH_ERROR ; 03014 } 03015 03016 if( ValidatePayloadLength( size, datarate, MacCommandsBufferIndex ) == false ) 03017 { 03018 return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR ; 03019 } 03020 03021 return LORAMAC_STATUS_OK ; 03022 } 03023 03024 LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet ) 03025 { 03026 LoRaMacStatus_t status = LORAMAC_STATUS_OK ; 03027 03028 if( mibGet == NULL ) 03029 { 03030 return LORAMAC_STATUS_PARAMETER_INVALID ; 03031 } 03032 03033 switch( mibGet->Type ) 03034 { 03035 case MIB_DEVICE_CLASS : 03036 { 03037 mibGet->Param .Class = LoRaMacDeviceClass; 03038 break; 03039 } 03040 case MIB_NETWORK_JOINED : 03041 { 03042 mibGet->Param .IsNetworkJoined = IsLoRaMacNetworkJoined; 03043 break; 03044 } 03045 case MIB_ADR : 03046 { 03047 mibGet->Param .AdrEnable = AdrCtrlOn; 03048 break; 03049 } 03050 case MIB_NET_ID : 03051 { 03052 mibGet->Param .NetID = LoRaMacNetID; 03053 break; 03054 } 03055 case MIB_DEV_ADDR : 03056 { 03057 mibGet->Param .DevAddr = LoRaMacDevAddr; 03058 break; 03059 } 03060 case MIB_NWK_SKEY : 03061 { 03062 mibGet->Param .NwkSKey = LoRaMacNwkSKey; 03063 break; 03064 } 03065 case MIB_APP_SKEY : 03066 { 03067 mibGet->Param .AppSKey = LoRaMacAppSKey; 03068 break; 03069 } 03070 case MIB_PUBLIC_NETWORK : 03071 { 03072 mibGet->Param .EnablePublicNetwork = PublicNetwork; 03073 break; 03074 } 03075 case MIB_REPEATER_SUPPORT : 03076 { 03077 mibGet->Param .EnableRepeaterSupport = RepeaterSupport; 03078 break; 03079 } 03080 case MIB_CHANNELS : 03081 { 03082 mibGet->Param .ChannelList = Channels; 03083 break; 03084 } 03085 case MIB_RX2_CHANNEL : 03086 { 03087 mibGet->Param .Rx2Channel = Rx2Channel; 03088 break; 03089 } 03090 case MIB_CHANNELS_MASK : 03091 { 03092 mibGet->Param .ChannelsMask = ChannelsMask; 03093 break; 03094 } 03095 case MIB_CHANNELS_NB_REP : 03096 { 03097 mibGet->Param .ChannelNbRep = ChannelsNbRep; 03098 break; 03099 } 03100 case MIB_MAX_RX_WINDOW_DURATION : 03101 { 03102 mibGet->Param .MaxRxWindow = MaxRxWindow; 03103 break; 03104 } 03105 case MIB_RECEIVE_DELAY_1 : 03106 { 03107 mibGet->Param .ReceiveDelay1 = ReceiveDelay1; 03108 break; 03109 } 03110 case MIB_RECEIVE_DELAY_2 : 03111 { 03112 mibGet->Param .ReceiveDelay2 = ReceiveDelay2; 03113 break; 03114 } 03115 case MIB_JOIN_ACCEPT_DELAY_1 : 03116 { 03117 mibGet->Param .JoinAcceptDelay1 = JoinAcceptDelay1; 03118 break; 03119 } 03120 case MIB_JOIN_ACCEPT_DELAY_2 : 03121 { 03122 mibGet->Param .JoinAcceptDelay2 = JoinAcceptDelay2; 03123 break; 03124 } 03125 case MIB_CHANNELS_DEFAULT_DATARATE : 03126 { 03127 mibGet->Param .ChannelsDefaultDatarate = ChannelsDefaultDatarate; 03128 break; 03129 } 03130 case MIB_CHANNELS_DATARATE : 03131 { 03132 mibGet->Param .ChannelsDatarate = ChannelsDatarate; 03133 break; 03134 } 03135 case MIB_CHANNELS_TX_POWER : 03136 { 03137 mibGet->Param .ChannelsTxPower = ChannelsTxPower; 03138 break; 03139 } 03140 case MIB_UPLINK_COUNTER : 03141 { 03142 mibGet->Param .UpLinkCounter = UpLinkCounter; 03143 break; 03144 } 03145 case MIB_DOWNLINK_COUNTER : 03146 { 03147 mibGet->Param .DownLinkCounter = DownLinkCounter; 03148 break; 03149 } 03150 case MIB_MULTICAST_CHANNEL : 03151 { 03152 mibGet->Param .MulticastList = MulticastChannels; 03153 break; 03154 } 03155 default: 03156 status = LORAMAC_STATUS_SERVICE_UNKNOWN ; 03157 break; 03158 } 03159 03160 return status; 03161 } 03162 03163 LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ) 03164 { 03165 LoRaMacStatus_t status = LORAMAC_STATUS_OK ; 03166 03167 if( mibSet == NULL ) 03168 { 03169 return LORAMAC_STATUS_PARAMETER_INVALID ; 03170 } 03171 if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING ) 03172 { 03173 return LORAMAC_STATUS_BUSY ; 03174 } 03175 03176 switch( mibSet->Type ) 03177 { 03178 case MIB_DEVICE_CLASS : 03179 { 03180 LoRaMacDeviceClass = mibSet->Param .Class ; 03181 switch( LoRaMacDeviceClass ) 03182 { 03183 case CLASS_A : 03184 { 03185 // Set the radio into sleep to setup a defined state 03186 Radio.Sleep( ); 03187 break; 03188 } 03189 case CLASS_B : 03190 { 03191 break; 03192 } 03193 case CLASS_C : 03194 { 03195 // Set the NodeAckRequested indicator to default 03196 NodeAckRequested = false; 03197 OnRxWindow2TimerEvent( ); 03198 break; 03199 } 03200 } 03201 break; 03202 } 03203 case MIB_NETWORK_JOINED : 03204 { 03205 IsLoRaMacNetworkJoined = mibSet->Param .IsNetworkJoined ; 03206 break; 03207 } 03208 case MIB_ADR : 03209 { 03210 AdrCtrlOn = mibSet->Param .AdrEnable ; 03211 break; 03212 } 03213 case MIB_NET_ID : 03214 { 03215 LoRaMacNetID = mibSet->Param .NetID ; 03216 break; 03217 } 03218 case MIB_DEV_ADDR : 03219 { 03220 LoRaMacDevAddr = mibSet->Param .DevAddr ; 03221 break; 03222 } 03223 case MIB_NWK_SKEY : 03224 { 03225 if( mibSet->Param .NwkSKey != NULL ) 03226 { 03227 memcpy1( LoRaMacNwkSKey, mibSet->Param .NwkSKey , 03228 sizeof( LoRaMacNwkSKey ) ); 03229 } 03230 else 03231 { 03232 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03233 } 03234 break; 03235 } 03236 case MIB_APP_SKEY : 03237 { 03238 if( mibSet->Param .AppSKey != NULL ) 03239 { 03240 memcpy1( LoRaMacAppSKey, mibSet->Param .AppSKey , 03241 sizeof( LoRaMacAppSKey ) ); 03242 } 03243 else 03244 { 03245 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03246 } 03247 break; 03248 } 03249 case MIB_PUBLIC_NETWORK : 03250 { 03251 SetPublicNetwork( mibSet->Param .EnablePublicNetwork ); 03252 break; 03253 } 03254 case MIB_REPEATER_SUPPORT : 03255 { 03256 RepeaterSupport = mibSet->Param .EnableRepeaterSupport ; 03257 break; 03258 } 03259 case MIB_RX2_CHANNEL : 03260 { 03261 Rx2Channel = mibSet->Param .Rx2Channel ; 03262 break; 03263 } 03264 case MIB_CHANNELS_MASK : 03265 { 03266 if( mibSet->Param .ChannelsMask ) 03267 { 03268 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 03269 bool chanMaskState = true; 03270 03271 #if defined( USE_BAND_915_HYBRID ) 03272 chanMaskState = ValidateChannelMask( mibSet->Param .ChannelsMask ); 03273 #endif 03274 if( chanMaskState == true ) 03275 { 03276 if( ( CountNbEnabled125kHzChannels( mibSet->Param .ChannelsMask ) < 6 ) && 03277 ( CountNbEnabled125kHzChannels( mibSet->Param .ChannelsMask ) > 0 ) ) 03278 { 03279 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03280 } 03281 else 03282 { 03283 memcpy1( ( uint8_t* ) ChannelsMask, 03284 ( uint8_t* ) mibSet->Param .ChannelsMask , sizeof( ChannelsMask ) ); 03285 for ( uint8_t i = 0; i < sizeof( ChannelsMask ) / 2; i++ ) 03286 { 03287 // Disable channels which are no longer available 03288 ChannelsMaskRemaining[i] &= ChannelsMask[i]; 03289 } 03290 } 03291 } 03292 else 03293 { 03294 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03295 } 03296 #else 03297 memcpy1( ( uint8_t* ) ChannelsMask, 03298 ( uint8_t* ) mibSet->Param .ChannelsMask , 2 ); 03299 #endif 03300 } 03301 else 03302 { 03303 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03304 } 03305 break; 03306 } 03307 case MIB_CHANNELS_NB_REP : 03308 { 03309 if( ( mibSet->Param .ChannelNbRep >= 1 ) && 03310 ( mibSet->Param .ChannelNbRep <= 15 ) ) 03311 { 03312 ChannelsNbRep = mibSet->Param .ChannelNbRep ; 03313 } 03314 else 03315 { 03316 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03317 } 03318 break; 03319 } 03320 case MIB_MAX_RX_WINDOW_DURATION : 03321 { 03322 MaxRxWindow = mibSet->Param .MaxRxWindow ; 03323 break; 03324 } 03325 case MIB_RECEIVE_DELAY_1 : 03326 { 03327 ReceiveDelay1 = mibSet->Param .ReceiveDelay1 ; 03328 break; 03329 } 03330 case MIB_RECEIVE_DELAY_2 : 03331 { 03332 ReceiveDelay2 = mibSet->Param .ReceiveDelay2 ; 03333 break; 03334 } 03335 case MIB_JOIN_ACCEPT_DELAY_1 : 03336 { 03337 JoinAcceptDelay1 = mibSet->Param .JoinAcceptDelay1 ; 03338 break; 03339 } 03340 case MIB_JOIN_ACCEPT_DELAY_2 : 03341 { 03342 JoinAcceptDelay2 = mibSet->Param .JoinAcceptDelay2 ; 03343 break; 03344 } 03345 case MIB_CHANNELS_DEFAULT_DATARATE : 03346 { 03347 if( ValueInRange( mibSet->Param .ChannelsDefaultDatarate , 03348 LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) ) 03349 { 03350 ChannelsDefaultDatarate = mibSet->Param .ChannelsDefaultDatarate ; 03351 } 03352 else 03353 { 03354 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03355 } 03356 break; 03357 } 03358 case MIB_CHANNELS_DATARATE : 03359 { 03360 if( ValueInRange( mibSet->Param .ChannelsDatarate , 03361 LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) ) 03362 { 03363 ChannelsDatarate = mibSet->Param .ChannelsDatarate ; 03364 } 03365 else 03366 { 03367 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03368 } 03369 break; 03370 } 03371 case MIB_CHANNELS_TX_POWER : 03372 { 03373 if( ValueInRange( mibSet->Param .ChannelsTxPower , 03374 LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) ) 03375 { 03376 ChannelsTxPower = mibSet->Param .ChannelsTxPower ; 03377 } 03378 else 03379 { 03380 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03381 } 03382 break; 03383 } 03384 case MIB_UPLINK_COUNTER : 03385 { 03386 UpLinkCounter = mibSet->Param .UpLinkCounter ; 03387 break; 03388 } 03389 case MIB_DOWNLINK_COUNTER : 03390 { 03391 DownLinkCounter = mibSet->Param .DownLinkCounter ; 03392 break; 03393 } 03394 default: 03395 status = LORAMAC_STATUS_SERVICE_UNKNOWN ; 03396 break; 03397 } 03398 03399 return status; 03400 } 03401 03402 LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params ) 03403 { 03404 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) ) 03405 return LORAMAC_STATUS_PARAMETER_INVALID ; 03406 #else 03407 bool datarateInvalid = false; 03408 bool frequencyInvalid = false; 03409 uint8_t band = 0; 03410 03411 // The id must not exceed LORA_MAX_NB_CHANNELS 03412 if( id >= LORA_MAX_NB_CHANNELS ) 03413 { 03414 return LORAMAC_STATUS_PARAMETER_INVALID ; 03415 } 03416 // Validate if the MAC is in a correct state 03417 if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING ) 03418 { 03419 if( ( LoRaMacState & MAC_TX_CONFIG ) != MAC_TX_CONFIG ) 03420 { 03421 return LORAMAC_STATUS_BUSY ; 03422 } 03423 } 03424 // Validate the datarate 03425 if( ( params.DrRange .Fields.Min > params.DrRange .Fields.Max ) || 03426 ( ValueInRange( params.DrRange .Fields.Min , LORAMAC_TX_MIN_DATARATE, 03427 LORAMAC_TX_MAX_DATARATE ) == false ) || 03428 ( ValueInRange( params.DrRange .Fields.Max , LORAMAC_TX_MIN_DATARATE, 03429 LORAMAC_TX_MAX_DATARATE ) == false ) ) 03430 { 03431 datarateInvalid = true; 03432 } 03433 03434 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 03435 if( id < 3 ) 03436 { 03437 if( params.Frequency != Channels[id].Frequency ) 03438 { 03439 frequencyInvalid = true; 03440 } 03441 03442 if( params.DrRange .Fields.Min > ChannelsDefaultDatarate ) 03443 { 03444 datarateInvalid = true; 03445 } 03446 if( ValueInRange( params.DrRange .Fields.Max , DR_5, LORAMAC_TX_MAX_DATARATE ) == false ) 03447 { 03448 datarateInvalid = true; 03449 } 03450 } 03451 #endif 03452 03453 // Validate the frequency 03454 if( ( Radio.CheckRfFrequency( params.Frequency ) == true ) && ( params.Frequency > 0 ) && ( frequencyInvalid == false ) ) 03455 { 03456 #if defined( USE_BAND_868 ) 03457 if( ( params.Frequency >= 865000000 ) && ( params.Frequency <= 868000000 ) ) 03458 { 03459 band = BAND_G1_0; 03460 } 03461 else if( ( params.Frequency > 868000000 ) && ( params.Frequency <= 868600000 ) ) 03462 { 03463 band = BAND_G1_1; 03464 } 03465 else if( ( params.Frequency >= 868700000 ) && ( params.Frequency <= 869200000 ) ) 03466 { 03467 band = BAND_G1_2; 03468 } 03469 else if( ( params.Frequency >= 869400000 ) && ( params.Frequency <= 869650000 ) ) 03470 { 03471 band = BAND_G1_3; 03472 } 03473 else if( ( params.Frequency >= 869700000 ) && ( params.Frequency <= 870000000 ) ) 03474 { 03475 band = BAND_G1_4; 03476 } 03477 else 03478 { 03479 frequencyInvalid = true; 03480 } 03481 #endif 03482 } 03483 else 03484 { 03485 frequencyInvalid = true; 03486 } 03487 03488 if( ( datarateInvalid == true ) && ( frequencyInvalid == true ) ) 03489 { 03490 return LORAMAC_STATUS_FREQ_AND_DR_INVALID ; 03491 } 03492 if( datarateInvalid == true ) 03493 { 03494 return LORAMAC_STATUS_DATARATE_INVALID ; 03495 } 03496 if( frequencyInvalid == true ) 03497 { 03498 return LORAMAC_STATUS_FREQUENCY_INVALID ; 03499 } 03500 03501 // Every parameter is valid, activate the channel 03502 Channels[id] = params; 03503 Channels[id].Band = band; 03504 ChannelsMask[0] |= ( 1 << id ); 03505 03506 return LORAMAC_STATUS_OK ; 03507 #endif 03508 } 03509 03510 LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id ) 03511 { 03512 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 03513 if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING ) 03514 { 03515 if( ( LoRaMacState & MAC_TX_CONFIG ) != MAC_TX_CONFIG ) 03516 { 03517 return LORAMAC_STATUS_BUSY ; 03518 } 03519 } 03520 03521 if( ( id < 3 ) || ( id >= LORA_MAX_NB_CHANNELS ) ) 03522 { 03523 return LORAMAC_STATUS_PARAMETER_INVALID ; 03524 } 03525 else 03526 { 03527 // Remove the channel from the list of channels 03528 Channels[id] = ( ChannelParams_t ){ 0, { 0 }, 0 }; 03529 03530 // Disable the channel as it doesn't exist anymore 03531 if( DisableChannelInMask( id, ChannelsMask ) == false ) 03532 { 03533 return LORAMAC_STATUS_PARAMETER_INVALID ; 03534 } 03535 } 03536 return LORAMAC_STATUS_OK ; 03537 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) ) 03538 return LORAMAC_STATUS_PARAMETER_INVALID ; 03539 #endif 03540 } 03541 03542 LoRaMacStatus_t LoRaMacMulticastChannelLink( MulticastParams_t *channelParam ) 03543 { 03544 if( channelParam == NULL ) 03545 { 03546 return LORAMAC_STATUS_PARAMETER_INVALID ; 03547 } 03548 if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING ) 03549 { 03550 return LORAMAC_STATUS_BUSY ; 03551 } 03552 03553 // Reset downlink counter 03554 channelParam->DownLinkCounter = 0; 03555 03556 if( MulticastChannels == NULL ) 03557 { 03558 // New node is the fist element 03559 MulticastChannels = channelParam; 03560 } 03561 else 03562 { 03563 MulticastParams_t *cur = MulticastChannels; 03564 03565 // Search the last node in the list 03566 while( cur->Next != NULL ) 03567 { 03568 cur = cur->Next ; 03569 } 03570 // This function always finds the last node 03571 cur->Next = channelParam; 03572 } 03573 03574 return LORAMAC_STATUS_OK ; 03575 } 03576 03577 LoRaMacStatus_t LoRaMacMulticastChannelUnlink( MulticastParams_t *channelParam ) 03578 { 03579 if( channelParam == NULL ) 03580 { 03581 return LORAMAC_STATUS_PARAMETER_INVALID ; 03582 } 03583 if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING ) 03584 { 03585 return LORAMAC_STATUS_BUSY ; 03586 } 03587 03588 if( MulticastChannels != NULL ) 03589 { 03590 if( MulticastChannels == channelParam ) 03591 { 03592 // First element 03593 MulticastChannels = channelParam->Next ; 03594 } 03595 else 03596 { 03597 MulticastParams_t *cur = MulticastChannels; 03598 03599 // Search the node in the list 03600 while( cur->Next && cur->Next != channelParam ) 03601 { 03602 cur = cur->Next ; 03603 } 03604 // If we found the node, remove it 03605 if( cur->Next ) 03606 { 03607 cur->Next = channelParam->Next ; 03608 } 03609 } 03610 channelParam->Next = NULL; 03611 } 03612 03613 return LORAMAC_STATUS_OK ; 03614 } 03615 03616 LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) 03617 { 03618 LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN ; 03619 LoRaMacHeader_t macHdr; 03620 03621 if( mlmeRequest == NULL ) 03622 { 03623 return LORAMAC_STATUS_PARAMETER_INVALID ; 03624 } 03625 if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING ) 03626 { 03627 return LORAMAC_STATUS_BUSY ; 03628 } 03629 03630 memset1( ( uint8_t* ) &MlmeConfirm, 0, sizeof( MlmeConfirm ) ); 03631 03632 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 03633 03634 switch( mlmeRequest->Type ) 03635 { 03636 case MLME_JOIN : 03637 { 03638 if( ( LoRaMacState & MAC_TX_DELAYED ) == MAC_TX_DELAYED ) 03639 { 03640 return LORAMAC_STATUS_BUSY ; 03641 } 03642 03643 MlmeConfirm.MlmeRequest = mlmeRequest->Type ; 03644 03645 if( ( mlmeRequest->Req.Join .DevEui == NULL ) || 03646 ( mlmeRequest->Req.Join .AppEui == NULL ) || 03647 ( mlmeRequest->Req.Join .AppKey == NULL ) ) 03648 { 03649 return LORAMAC_STATUS_PARAMETER_INVALID ; 03650 } 03651 03652 LoRaMacFlags.Bits.MlmeReq = 1; 03653 03654 LoRaMacDevEui = mlmeRequest->Req.Join .DevEui ; 03655 LoRaMacAppEui = mlmeRequest->Req.Join .AppEui ; 03656 LoRaMacAppKey = mlmeRequest->Req.Join .AppKey ; 03657 03658 macHdr.Value = 0; 03659 macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ ; 03660 03661 IsLoRaMacNetworkJoined = false; 03662 03663 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 03664 #if defined( USE_BAND_915 ) 03665 // Re-enable 500 kHz default channels 03666 ChannelsMask[4] = 0x00FF; 03667 #else // defined( USE_BAND_915_HYBRID ) 03668 // Re-enable 500 kHz default channels 03669 ChannelsMask[4] = 0x0001; 03670 #endif 03671 03672 static uint8_t drSwitch = 0; 03673 03674 if( ( ++drSwitch & 0x01 ) == 0x01 ) 03675 { 03676 ChannelsDatarate = DR_0; 03677 } 03678 else 03679 { 03680 ChannelsDatarate = DR_4; 03681 } 03682 #endif 03683 03684 status = Send( &macHdr, 0, NULL, 0 ); 03685 break; 03686 } 03687 case MLME_LINK_CHECK : 03688 { 03689 LoRaMacFlags.Bits.MlmeReq = 1; 03690 // LoRaMac will send this command piggy-pack 03691 MlmeConfirm.MlmeRequest = mlmeRequest->Type ; 03692 03693 status = AddMacCommand( MOTE_MAC_LINK_CHECK_REQ , 0, 0 ); 03694 break; 03695 } 03696 default: 03697 break; 03698 } 03699 03700 if( status != LORAMAC_STATUS_OK ) 03701 { 03702 NodeAckRequested = false; 03703 LoRaMacFlags.Bits.MlmeReq = 0; 03704 } 03705 03706 return status; 03707 } 03708 03709 LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) 03710 { 03711 LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN ; 03712 LoRaMacHeader_t macHdr; 03713 uint8_t fPort = 0; 03714 void *fBuffer; 03715 uint16_t fBufferSize; 03716 int8_t datarate; 03717 bool readyToSend = false; 03718 03719 if( mcpsRequest == NULL ) 03720 { 03721 return LORAMAC_STATUS_PARAMETER_INVALID ; 03722 } 03723 if( ( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING ) || 03724 ( ( LoRaMacState & MAC_TX_DELAYED ) == MAC_TX_DELAYED ) ) 03725 { 03726 return LORAMAC_STATUS_BUSY ; 03727 } 03728 03729 macHdr.Value = 0; 03730 memset1 ( ( uint8_t* ) &McpsConfirm, 0, sizeof( McpsConfirm ) ); 03731 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 03732 03733 switch( mcpsRequest->Type ) 03734 { 03735 case MCPS_UNCONFIRMED : 03736 { 03737 readyToSend = true; 03738 AckTimeoutRetries = 1; 03739 03740 macHdr.Bits.MType = FRAME_TYPE_DATA_UNCONFIRMED_UP ; 03741 fPort = mcpsRequest->Req.Unconfirmed .fPort ; 03742 fBuffer = mcpsRequest->Req.Unconfirmed .fBuffer ; 03743 fBufferSize = mcpsRequest->Req.Unconfirmed .fBufferSize ; 03744 datarate = mcpsRequest->Req.Unconfirmed .Datarate ; 03745 break; 03746 } 03747 case MCPS_CONFIRMED : 03748 { 03749 readyToSend = true; 03750 AckTimeoutRetriesCounter = 1; 03751 AckTimeoutRetries = mcpsRequest->Req.Confirmed .NbTrials ; 03752 03753 macHdr.Bits.MType = FRAME_TYPE_DATA_CONFIRMED_UP ; 03754 fPort = mcpsRequest->Req.Confirmed .fPort ; 03755 fBuffer = mcpsRequest->Req.Confirmed .fBuffer ; 03756 fBufferSize = mcpsRequest->Req.Confirmed .fBufferSize ; 03757 datarate = mcpsRequest->Req.Confirmed .Datarate ; 03758 break; 03759 } 03760 case MCPS_PROPRIETARY : 03761 { 03762 readyToSend = true; 03763 AckTimeoutRetries = 1; 03764 03765 macHdr.Bits.MType = FRAME_TYPE_PROPRIETARY ; 03766 fBuffer = mcpsRequest->Req.Proprietary .fBuffer ; 03767 fBufferSize = mcpsRequest->Req.Proprietary .fBufferSize ; 03768 datarate = mcpsRequest->Req.Proprietary .Datarate ; 03769 break; 03770 } 03771 default: 03772 break; 03773 } 03774 03775 if( readyToSend == true ) 03776 { 03777 if( AdrCtrlOn == false ) 03778 { 03779 if( ValueInRange( datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == true ) 03780 { 03781 ChannelsDatarate = datarate; 03782 } 03783 else 03784 { 03785 return LORAMAC_STATUS_PARAMETER_INVALID ; 03786 } 03787 } 03788 03789 status = Send( &macHdr, fPort, fBuffer, fBufferSize ); 03790 if( status == LORAMAC_STATUS_OK ) 03791 { 03792 McpsConfirm.McpsRequest = mcpsRequest->Type ; 03793 LoRaMacFlags.Bits.McpsReq = 1; 03794 } 03795 else 03796 { 03797 NodeAckRequested = false; 03798 } 03799 } 03800 03801 return status; 03802 } 03803 03804 void LoRaMacTestRxWindowsOn ( bool enable ) 03805 { 03806 IsRxWindowsEnabled = enable; 03807 } 03808 03809 void LoRaMacTestSetMic ( uint16_t txPacketCounter ) 03810 { 03811 UpLinkCounter = txPacketCounter; 03812 IsUpLinkCounterFixed = true; 03813 } 03814 03815 void LoRaMacTestSetDutyCycleOn ( bool enable ) 03816 { 03817 DutyCycleOn = enable; 03818 }
Generated on Thu Jul 14 2022 07:48:32 by
