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