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