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 #if defined( USE_RADIO_DEBUG ) && defined( USE_DEBUG_PINS ) 01122 GpioWrite( &DbgPin5, 0 ); 01123 #endif 01124 } 01125 01126 static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) 01127 { 01128 LoRaMacHeader_t macHdr; 01129 LoRaMacFrameCtrl_t fCtrl; 01130 bool skipIndication = false; 01131 01132 uint8_t pktHeaderLen = 0; 01133 uint32_t address = 0; 01134 uint8_t appPayloadStartIndex = 0; 01135 uint8_t port = 0xFF; 01136 uint8_t frameLen = 0; 01137 uint32_t mic = 0; 01138 uint32_t micRx = 0; 01139 01140 uint16_t sequenceCounter = 0; 01141 uint16_t sequenceCounterPrev = 0; 01142 uint16_t sequenceCounterDiff = 0; 01143 uint32_t downLinkCounter = 0; 01144 01145 MulticastParams_t *curMulticastParams = NULL; 01146 uint8_t *nwkSKey = LoRaMacNwkSKey; 01147 uint8_t *appSKey = LoRaMacAppSKey; 01148 01149 uint8_t multicast = 0; 01150 01151 bool isMicOk = false; 01152 01153 McpsConfirm.AckReceived = false; 01154 McpsIndication.Rssi = rssi; 01155 McpsIndication.Snr = snr; 01156 McpsIndication.RxSlot = RxSlot; 01157 McpsIndication.Port = 0; 01158 McpsIndication.Multicast = 0; 01159 McpsIndication.FramePending = 0; 01160 McpsIndication.Buffer = NULL; 01161 McpsIndication.BufferSize = 0; 01162 McpsIndication.RxData = false; 01163 McpsIndication.AckReceived = false; 01164 McpsIndication.DownLinkCounter = 0; 01165 McpsIndication.McpsIndication = MCPS_UNCONFIRMED ; 01166 01167 Radio.Sleep( ); 01168 TimerStop( &RxWindowTimer2 ); 01169 01170 macHdr.Value = payload[pktHeaderLen++]; 01171 01172 switch( macHdr.Bits.MType ) 01173 { 01174 case FRAME_TYPE_JOIN_ACCEPT : 01175 if( IsLoRaMacNetworkJoined == true ) 01176 { 01177 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 01178 PrepareRxDoneAbort( ); 01179 return; 01180 } 01181 LoRaMacJoinDecrypt ( payload + 1, size - 1, LoRaMacAppKey, LoRaMacRxPayload + 1 ); 01182 01183 LoRaMacRxPayload[0] = macHdr.Value ; 01184 01185 LoRaMacJoinComputeMic ( LoRaMacRxPayload, size - LORAMAC_MFR_LEN, LoRaMacAppKey, &mic ); 01186 01187 micRx |= ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN]; 01188 micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 1] << 8 ); 01189 micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 2] << 16 ); 01190 micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 3] << 24 ); 01191 01192 if( micRx == mic ) 01193 { 01194 LoRaMacJoinComputeSKeys ( LoRaMacAppKey, LoRaMacRxPayload + 1, LoRaMacDevNonce, LoRaMacNwkSKey, LoRaMacAppSKey ); 01195 01196 LoRaMacNetID = ( uint32_t )LoRaMacRxPayload[4]; 01197 LoRaMacNetID |= ( ( uint32_t )LoRaMacRxPayload[5] << 8 ); 01198 LoRaMacNetID |= ( ( uint32_t )LoRaMacRxPayload[6] << 16 ); 01199 01200 LoRaMacDevAddr = ( uint32_t )LoRaMacRxPayload[7]; 01201 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[8] << 8 ); 01202 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[9] << 16 ); 01203 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[10] << 24 ); 01204 01205 // DLSettings 01206 LoRaMacParams.Rx1DrOffset = ( LoRaMacRxPayload[11] >> 4 ) & 0x07; 01207 LoRaMacParams.Rx2Channel .Datarate = LoRaMacRxPayload[11] & 0x0F; 01208 01209 // RxDelay 01210 LoRaMacParams.ReceiveDelay1 = ( LoRaMacRxPayload[12] & 0x0F ); 01211 if( LoRaMacParams.ReceiveDelay1 == 0 ) 01212 { 01213 LoRaMacParams.ReceiveDelay1 = 1; 01214 } 01215 LoRaMacParams.ReceiveDelay1 *= 1e3; 01216 LoRaMacParams.ReceiveDelay2 = LoRaMacParams.ReceiveDelay1 + 1e3; 01217 01218 #if !( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) ) 01219 //CFList 01220 if( ( size - 1 ) > 16 ) 01221 { 01222 ChannelParams_t param; 01223 param.DrRange .Value = ( DR_5 << 4 ) | DR_0; 01224 01225 LoRaMacState |= LORAMAC_TX_CONFIG; 01226 for( uint8_t i = 3, j = 0; i < ( 5 + 3 ); i++, j += 3 ) 01227 { 01228 param.Frequency = ( ( uint32_t )LoRaMacRxPayload[13 + j] | ( ( uint32_t )LoRaMacRxPayload[14 + j] << 8 ) | ( ( uint32_t )LoRaMacRxPayload[15 + j] << 16 ) ) * 100; 01229 if( param.Frequency != 0 ) 01230 { 01231 LoRaMacChannelAdd( i, param ); 01232 } 01233 else 01234 { 01235 LoRaMacChannelRemove( i ); 01236 } 01237 } 01238 LoRaMacState &= ~LORAMAC_TX_CONFIG; 01239 } 01240 #endif 01241 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK ; 01242 IsLoRaMacNetworkJoined = true; 01243 LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate ; 01244 } 01245 else 01246 { 01247 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL ; 01248 } 01249 break; 01250 case FRAME_TYPE_DATA_CONFIRMED_DOWN : 01251 case FRAME_TYPE_DATA_UNCONFIRMED_DOWN : 01252 { 01253 address = payload[pktHeaderLen++]; 01254 address |= ( (uint32_t)payload[pktHeaderLen++] << 8 ); 01255 address |= ( (uint32_t)payload[pktHeaderLen++] << 16 ); 01256 address |= ( (uint32_t)payload[pktHeaderLen++] << 24 ); 01257 01258 if( address != LoRaMacDevAddr ) 01259 { 01260 curMulticastParams = MulticastChannels; 01261 while( curMulticastParams != NULL ) 01262 { 01263 if( address == curMulticastParams->Address ) 01264 { 01265 multicast = 1; 01266 nwkSKey = curMulticastParams->NwkSKey ; 01267 appSKey = curMulticastParams->AppSKey ; 01268 downLinkCounter = curMulticastParams->DownLinkCounter ; 01269 break; 01270 } 01271 curMulticastParams = curMulticastParams->Next ; 01272 } 01273 if( multicast == 0 ) 01274 { 01275 // We are not the destination of this frame. 01276 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL ; 01277 PrepareRxDoneAbort( ); 01278 return; 01279 } 01280 } 01281 else 01282 { 01283 multicast = 0; 01284 nwkSKey = LoRaMacNwkSKey; 01285 appSKey = LoRaMacAppSKey; 01286 downLinkCounter = DownLinkCounter; 01287 } 01288 01289 fCtrl.Value = payload[pktHeaderLen++]; 01290 01291 sequenceCounter = ( uint16_t )payload[pktHeaderLen++]; 01292 sequenceCounter |= ( uint16_t )payload[pktHeaderLen++] << 8; 01293 01294 appPayloadStartIndex = 8 + fCtrl.Bits.FOptsLen ; 01295 01296 micRx |= ( uint32_t )payload[size - LORAMAC_MFR_LEN]; 01297 micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 1] << 8 ); 01298 micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 2] << 16 ); 01299 micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 3] << 24 ); 01300 01301 sequenceCounterPrev = ( uint16_t )downLinkCounter; 01302 sequenceCounterDiff = ( sequenceCounter - sequenceCounterPrev ); 01303 01304 if( sequenceCounterDiff < ( 1 << 15 ) ) 01305 { 01306 downLinkCounter += sequenceCounterDiff; 01307 LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounter, &mic ); 01308 if( micRx == mic ) 01309 { 01310 isMicOk = true; 01311 } 01312 } 01313 else 01314 { 01315 // check for sequence roll-over 01316 uint32_t downLinkCounterTmp = downLinkCounter + 0x10000 + ( int16_t )sequenceCounterDiff; 01317 LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounterTmp, &mic ); 01318 if( micRx == mic ) 01319 { 01320 isMicOk = true; 01321 downLinkCounter = downLinkCounterTmp; 01322 } 01323 } 01324 01325 // Check for a the maximum allowed counter difference 01326 if( sequenceCounterDiff >= MAX_FCNT_GAP ) 01327 { 01328 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS ; 01329 McpsIndication.DownLinkCounter = downLinkCounter; 01330 PrepareRxDoneAbort( ); 01331 return; 01332 } 01333 01334 if( isMicOk == true ) 01335 { 01336 #if defined( USE_RADIO_DEBUG ) && defined( USE_DEBUG_PINS ) 01337 GpioWrite( &DbgPin5, 1 ); 01338 #endif 01339 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_OK ; 01340 McpsIndication.Multicast = multicast; 01341 McpsIndication.FramePending = fCtrl.Bits.FPending ; 01342 McpsIndication.Buffer = NULL; 01343 McpsIndication.BufferSize = 0; 01344 McpsIndication.DownLinkCounter = downLinkCounter; 01345 01346 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK ; 01347 01348 AdrAckCounter = 0; 01349 MacCommandsBufferToRepeatIndex = 0; 01350 01351 // Update 32 bits downlink counter 01352 if( multicast == 1 ) 01353 { 01354 McpsIndication.McpsIndication = MCPS_MULTICAST ; 01355 01356 if( ( curMulticastParams->DownLinkCounter == downLinkCounter ) && 01357 ( curMulticastParams->DownLinkCounter != 0 ) ) 01358 { 01359 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED ; 01360 McpsIndication.DownLinkCounter = downLinkCounter; 01361 PrepareRxDoneAbort( ); 01362 return; 01363 } 01364 curMulticastParams->DownLinkCounter = downLinkCounter; 01365 } 01366 else 01367 { 01368 if( macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN ) 01369 { 01370 SrvAckRequested = true; 01371 McpsIndication.McpsIndication = MCPS_CONFIRMED ; 01372 01373 if( ( DownLinkCounter == downLinkCounter ) && 01374 ( DownLinkCounter != 0 ) ) 01375 { 01376 // Duplicated confirmed downlink. Skip indication. 01377 // In this case, the MAC layer shall accept the MAC commands 01378 // which are included in the downlink retransmission. 01379 // It should not provide the same frame to the application 01380 // layer again. 01381 skipIndication = true; 01382 } 01383 } 01384 else 01385 { 01386 SrvAckRequested = false; 01387 McpsIndication.McpsIndication = MCPS_UNCONFIRMED ; 01388 01389 if( ( DownLinkCounter == downLinkCounter ) && 01390 ( DownLinkCounter != 0 ) ) 01391 { 01392 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED ; 01393 McpsIndication.DownLinkCounter = downLinkCounter; 01394 PrepareRxDoneAbort( ); 01395 return; 01396 } 01397 } 01398 DownLinkCounter = downLinkCounter; 01399 } 01400 01401 // This must be done before parsing the payload and the MAC commands. 01402 // We need to reset the MacCommandsBufferIndex here, since we need 01403 // to take retransmissions and repititions into account. Error cases 01404 // will be handled in function OnMacStateCheckTimerEvent. 01405 if( McpsConfirm.McpsRequest == MCPS_CONFIRMED ) 01406 { 01407 if( fCtrl.Bits.Ack == 1 ) 01408 {// Reset MacCommandsBufferIndex when we have received an ACK. 01409 MacCommandsBufferIndex = 0; 01410 } 01411 } 01412 else 01413 {// Reset the variable if we have received any valid frame. 01414 MacCommandsBufferIndex = 0; 01415 } 01416 01417 // Process payload and MAC commands 01418 if( ( ( size - 4 ) - appPayloadStartIndex ) > 0 ) 01419 { 01420 port = payload[appPayloadStartIndex++]; 01421 frameLen = ( size - 4 ) - appPayloadStartIndex; 01422 01423 McpsIndication.Port = port; 01424 01425 if( port == 0 ) 01426 { 01427 // Only allow frames which do not have fOpts 01428 if( fCtrl.Bits.FOptsLen == 0 ) 01429 { 01430 LoRaMacPayloadDecrypt ( payload + appPayloadStartIndex, 01431 frameLen, 01432 nwkSKey, 01433 address, 01434 DOWN_LINK, 01435 downLinkCounter, 01436 LoRaMacRxPayload ); 01437 01438 // Decode frame payload MAC commands 01439 ProcessMacCommands( LoRaMacRxPayload, 0, frameLen, snr ); 01440 } 01441 else 01442 { 01443 skipIndication = true; 01444 } 01445 } 01446 else 01447 { 01448 if( fCtrl.Bits.FOptsLen > 0 ) 01449 { 01450 // Decode Options field MAC commands. Omit the fPort. 01451 ProcessMacCommands( payload, 8, appPayloadStartIndex - 1, snr ); 01452 } 01453 01454 LoRaMacPayloadDecrypt ( payload + appPayloadStartIndex, 01455 frameLen, 01456 appSKey, 01457 address, 01458 DOWN_LINK, 01459 downLinkCounter, 01460 LoRaMacRxPayload ); 01461 01462 if( skipIndication == false ) 01463 { 01464 McpsIndication.Buffer = LoRaMacRxPayload; 01465 McpsIndication.BufferSize = frameLen; 01466 McpsIndication.RxData = true; 01467 } 01468 } 01469 } 01470 else 01471 { 01472 if( fCtrl.Bits.FOptsLen > 0 ) 01473 { 01474 // Decode Options field MAC commands 01475 ProcessMacCommands( payload, 8, appPayloadStartIndex, snr ); 01476 } 01477 } 01478 01479 if( skipIndication == false ) 01480 { 01481 // Check if the frame is an acknowledgement 01482 if( fCtrl.Bits.Ack == 1 ) 01483 { 01484 McpsConfirm.AckReceived = true; 01485 McpsIndication.AckReceived = true; 01486 01487 // Stop the AckTimeout timer as no more retransmissions 01488 // are needed. 01489 TimerStop( &AckTimeoutTimer ); 01490 } 01491 else 01492 { 01493 McpsConfirm.AckReceived = false; 01494 01495 if( AckTimeoutRetriesCounter > AckTimeoutRetries ) 01496 { 01497 // Stop the AckTimeout timer as no more retransmissions 01498 // are needed. 01499 TimerStop( &AckTimeoutTimer ); 01500 } 01501 } 01502 } 01503 // Provide always an indication, skip the callback to the user application, 01504 // in case of a confirmed downlink retransmission. 01505 LoRaMacFlags.Bits.McpsInd = 1; 01506 LoRaMacFlags.Bits.McpsIndSkip = skipIndication; 01507 } 01508 else 01509 { 01510 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL ; 01511 01512 PrepareRxDoneAbort( ); 01513 return; 01514 } 01515 } 01516 break; 01517 case FRAME_TYPE_PROPRIETARY : 01518 { 01519 memcpy1( LoRaMacRxPayload, &payload[pktHeaderLen], size ); 01520 01521 McpsIndication.McpsIndication = MCPS_PROPRIETARY ; 01522 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_OK ; 01523 McpsIndication.Buffer = LoRaMacRxPayload; 01524 McpsIndication.BufferSize = size - pktHeaderLen; 01525 01526 LoRaMacFlags.Bits.McpsInd = 1; 01527 break; 01528 } 01529 default: 01530 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 01531 PrepareRxDoneAbort( ); 01532 break; 01533 } 01534 LoRaMacFlags.Bits.MacDone = 1; 01535 01536 // Trig OnMacCheckTimerEvent call as soon as possible 01537 TimerSetValue( &MacStateCheckTimer, 1 ); 01538 TimerStart( &MacStateCheckTimer ); 01539 #if defined( USE_RADIO_DEBUG ) && defined( USE_DEBUG_PINS ) 01540 GpioWrite( &DbgPin5, 0 ); 01541 #endif 01542 } 01543 01544 static void OnRadioTxTimeout( void ) 01545 { 01546 if( LoRaMacDeviceClass != CLASS_C ) 01547 { 01548 Radio.Sleep( ); 01549 } 01550 else 01551 { 01552 OnRxWindow2TimerEvent( ); 01553 } 01554 01555 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ; 01556 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ; 01557 LoRaMacFlags.Bits.MacDone = 1; 01558 } 01559 01560 static void OnRadioRxError( void ) 01561 { 01562 if( LoRaMacDeviceClass != CLASS_C ) 01563 { 01564 Radio.Sleep( ); 01565 } 01566 else 01567 { 01568 OnRxWindow2TimerEvent( ); 01569 } 01570 01571 if( RxSlot == 0 ) 01572 { 01573 if( NodeAckRequested == true ) 01574 { 01575 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR ; 01576 } 01577 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR ; 01578 01579 if( TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay ) 01580 { 01581 LoRaMacFlags.Bits.MacDone = 1; 01582 } 01583 } 01584 else 01585 { 01586 if( NodeAckRequested == true ) 01587 { 01588 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR ; 01589 } 01590 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR ; 01591 LoRaMacFlags.Bits.MacDone = 1; 01592 } 01593 } 01594 01595 static void OnRadioRxTimeout( void ) 01596 { 01597 if( LoRaMacDeviceClass != CLASS_C ) 01598 { 01599 Radio.Sleep( ); 01600 } 01601 else 01602 { 01603 OnRxWindow2TimerEvent( ); 01604 } 01605 01606 if( RxSlot == 1 ) 01607 { 01608 if( NodeAckRequested == true ) 01609 { 01610 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT ; 01611 } 01612 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT ; 01613 LoRaMacFlags.Bits.MacDone = 1; 01614 } 01615 } 01616 01617 static void OnMacStateCheckTimerEvent( void ) 01618 { 01619 TimerStop( &MacStateCheckTimer ); 01620 bool txTimeout = false; 01621 01622 if( LoRaMacFlags.Bits.MacDone == 1 ) 01623 { 01624 if( ( LoRaMacState & LORAMAC_RX_ABORT ) == LORAMAC_RX_ABORT ) 01625 { 01626 LoRaMacState &= ~LORAMAC_RX_ABORT; 01627 LoRaMacState &= ~LORAMAC_TX_RUNNING; 01628 } 01629 01630 if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( LoRaMacFlags.Bits.McpsReq == 1 ) ) ) 01631 { 01632 if( ( McpsConfirm.Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) || 01633 ( MlmeConfirm.Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) ) 01634 { 01635 // Stop transmit cycle due to tx timeout. 01636 LoRaMacState &= ~LORAMAC_TX_RUNNING; 01637 MacCommandsBufferIndex = 0; 01638 McpsConfirm.NbRetries = AckTimeoutRetriesCounter; 01639 McpsConfirm.AckReceived = false; 01640 McpsConfirm.TxTimeOnAir = 0; 01641 txTimeout = true; 01642 } 01643 } 01644 01645 if( ( NodeAckRequested == false ) && ( txTimeout == false ) ) 01646 { 01647 if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( LoRaMacFlags.Bits.McpsReq == 1 ) ) ) 01648 { 01649 if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) && ( MlmeConfirm.MlmeRequest == MLME_JOIN ) ) 01650 {// Procedure for the join request 01651 MlmeConfirm.NbRetries = JoinRequestTrials; 01652 01653 if( MlmeConfirm.Status == LORAMAC_EVENT_INFO_STATUS_OK ) 01654 {// Node joined successfully 01655 UpLinkCounter = 0; 01656 ChannelsNbRepCounter = 0; 01657 LoRaMacState &= ~LORAMAC_TX_RUNNING; 01658 } 01659 else 01660 { 01661 if( JoinRequestTrials >= MaxJoinRequestTrials ) 01662 { 01663 LoRaMacState &= ~LORAMAC_TX_RUNNING; 01664 } 01665 else 01666 { 01667 LoRaMacFlags.Bits.MacDone = 0; 01668 // Sends the same frame again 01669 OnTxDelayedTimerEvent( ); 01670 } 01671 } 01672 } 01673 else 01674 {// Procedure for all other frames 01675 if( ( ChannelsNbRepCounter >= LoRaMacParams.ChannelsNbRep ) || ( LoRaMacFlags.Bits.McpsInd == 1 ) ) 01676 { 01677 if( LoRaMacFlags.Bits.McpsInd == 0 ) 01678 { // Maximum repititions without downlink. Reset MacCommandsBufferIndex. Increase ADR Ack counter. 01679 // Only process the case when the MAC did not receive a downlink. 01680 MacCommandsBufferIndex = 0; 01681 AdrAckCounter++; 01682 } 01683 01684 ChannelsNbRepCounter = 0; 01685 01686 if( IsUpLinkCounterFixed == false ) 01687 { 01688 UpLinkCounter++; 01689 } 01690 01691 LoRaMacState &= ~LORAMAC_TX_RUNNING; 01692 } 01693 else 01694 { 01695 LoRaMacFlags.Bits.MacDone = 0; 01696 // Sends the same frame again 01697 OnTxDelayedTimerEvent( ); 01698 } 01699 } 01700 } 01701 } 01702 01703 if( LoRaMacFlags.Bits.McpsInd == 1 ) 01704 {// Procedure if we received a frame 01705 if( ( McpsConfirm.AckReceived == true ) || ( AckTimeoutRetriesCounter > AckTimeoutRetries ) ) 01706 { 01707 AckTimeoutRetry = false; 01708 NodeAckRequested = false; 01709 if( IsUpLinkCounterFixed == false ) 01710 { 01711 UpLinkCounter++; 01712 } 01713 McpsConfirm.NbRetries = AckTimeoutRetriesCounter; 01714 01715 LoRaMacState &= ~LORAMAC_TX_RUNNING; 01716 } 01717 } 01718 01719 if( ( AckTimeoutRetry == true ) && ( ( LoRaMacState & LORAMAC_TX_DELAYED ) == 0 ) ) 01720 {// Retransmissions procedure for confirmed uplinks 01721 AckTimeoutRetry = false; 01722 if( ( AckTimeoutRetriesCounter < AckTimeoutRetries ) && ( AckTimeoutRetriesCounter <= MAX_ACK_RETRIES ) ) 01723 { 01724 AckTimeoutRetriesCounter++; 01725 01726 if( ( AckTimeoutRetriesCounter % 2 ) == 1 ) 01727 { 01728 LoRaMacParams.ChannelsDatarate = MAX( LoRaMacParams.ChannelsDatarate - 1, LORAMAC_TX_MIN_DATARATE ); 01729 } 01730 // Try to send the frame again 01731 if( ScheduleTx( ) == LORAMAC_STATUS_OK ) 01732 { 01733 LoRaMacFlags.Bits.MacDone = 0; 01734 } 01735 else 01736 { 01737 // The DR is not applicable for the payload size 01738 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR ; 01739 01740 MacCommandsBufferIndex = 0; 01741 LoRaMacState &= ~LORAMAC_TX_RUNNING; 01742 NodeAckRequested = false; 01743 McpsConfirm.AckReceived = false; 01744 McpsConfirm.NbRetries = AckTimeoutRetriesCounter; 01745 McpsConfirm.Datarate = LoRaMacParams.ChannelsDatarate ; 01746 if( IsUpLinkCounterFixed == false ) 01747 { 01748 UpLinkCounter++; 01749 } 01750 } 01751 } 01752 else 01753 { 01754 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 01755 // Re-enable default channels LC1, LC2, LC3 01756 LoRaMacParams.ChannelsMask [0] = LoRaMacParams.ChannelsMask [0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) ); 01757 #elif defined( USE_BAND_470 ) 01758 // Re-enable default channels 01759 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask ) ); 01760 #elif defined( USE_BAND_915 ) 01761 // Re-enable default channels 01762 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask ) ); 01763 #elif defined( USE_BAND_915_HYBRID ) 01764 // Re-enable default channels 01765 ReenableChannels( LoRaMacParamsDefaults.ChannelsMask [4], LoRaMacParams.ChannelsMask ); 01766 #else 01767 #error "Please define a frequency band in the compiler options." 01768 #endif 01769 LoRaMacState &= ~LORAMAC_TX_RUNNING; 01770 01771 MacCommandsBufferIndex = 0; 01772 NodeAckRequested = false; 01773 McpsConfirm.AckReceived = false; 01774 McpsConfirm.NbRetries = AckTimeoutRetriesCounter; 01775 if( IsUpLinkCounterFixed == false ) 01776 { 01777 UpLinkCounter++; 01778 } 01779 } 01780 } 01781 } 01782 // Handle reception for Class B and Class C 01783 if( ( LoRaMacState & LORAMAC_RX ) == LORAMAC_RX ) 01784 { 01785 LoRaMacState &= ~LORAMAC_RX; 01786 } 01787 if( LoRaMacState == LORAMAC_IDLE ) 01788 { 01789 if( LoRaMacFlags.Bits.McpsReq == 1 ) 01790 { 01791 LoRaMacPrimitives->MacMcpsConfirm( &McpsConfirm ); 01792 LoRaMacFlags.Bits.McpsReq = 0; 01793 } 01794 01795 if( LoRaMacFlags.Bits.MlmeReq == 1 ) 01796 { 01797 LoRaMacPrimitives->MacMlmeConfirm( &MlmeConfirm ); 01798 LoRaMacFlags.Bits.MlmeReq = 0; 01799 } 01800 01801 // Procedure done. Reset variables. 01802 LoRaMacFlags.Bits.MacDone = 0; 01803 } 01804 else 01805 { 01806 // Operation not finished restart timer 01807 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); 01808 TimerStart( &MacStateCheckTimer ); 01809 } 01810 01811 if( LoRaMacFlags.Bits.McpsInd == 1 ) 01812 { 01813 if( LoRaMacDeviceClass == CLASS_C ) 01814 {// Activate RX2 window for Class C 01815 OnRxWindow2TimerEvent( ); 01816 } 01817 if( LoRaMacFlags.Bits.McpsIndSkip == 0 ) 01818 { 01819 LoRaMacPrimitives->MacMcpsIndication( &McpsIndication ); 01820 } 01821 LoRaMacFlags.Bits.McpsIndSkip = 0; 01822 LoRaMacFlags.Bits.McpsInd = 0; 01823 } 01824 } 01825 01826 static void OnTxDelayedTimerEvent( void ) 01827 { 01828 LoRaMacHeader_t macHdr; 01829 LoRaMacFrameCtrl_t fCtrl; 01830 01831 TimerStop( &TxDelayedTimer ); 01832 LoRaMacState &= ~LORAMAC_TX_DELAYED; 01833 01834 if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) && ( MlmeConfirm.MlmeRequest == MLME_JOIN ) ) 01835 { 01836 ResetMacParameters( ); 01837 // Add a +1, since we start to count from 0 01838 LoRaMacParams.ChannelsDatarate = AlternateDatarate( JoinRequestTrials + 1 ); 01839 01840 macHdr.Value = 0; 01841 macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ ; 01842 01843 fCtrl.Value = 0; 01844 fCtrl.Bits.Adr = AdrCtrlOn; 01845 01846 /* In case of join request retransmissions, the stack must prepare 01847 * the frame again, because the network server keeps track of the random 01848 * LoRaMacDevNonce values to prevent reply attacks. */ 01849 PrepareFrame( &macHdr, &fCtrl, 0, NULL, 0 ); 01850 } 01851 01852 ScheduleTx( ); 01853 } 01854 01855 static void OnRxWindow1TimerEvent( void ) 01856 { 01857 TimerStop( &RxWindowTimer1 ); 01858 RxSlot = 0; 01859 01860 if( LoRaMacDeviceClass == CLASS_C ) 01861 { 01862 Radio.Standby( ); 01863 } 01864 01865 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 01866 RxWindowSetup( Channels[Channel].Frequency, RxWindowsParams[0].Datarate, RxWindowsParams[0].Bandwidth, RxWindowsParams[0].RxWindowTimeout, false ); 01867 #elif defined( USE_BAND_470 ) 01868 RxWindowSetup( LORAMAC_FIRST_RX1_CHANNEL + ( Channel % 48 ) * LORAMAC_STEPWIDTH_RX1_CHANNEL, RxWindowsParams[0].Datarate, RxWindowsParams[0].Bandwidth, RxWindowsParams[0].RxWindowTimeout, false ); 01869 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) ) 01870 RxWindowSetup( LORAMAC_FIRST_RX1_CHANNEL + ( Channel % 8 ) * LORAMAC_STEPWIDTH_RX1_CHANNEL, RxWindowsParams[0].Datarate, RxWindowsParams[0].Bandwidth, RxWindowsParams[0].RxWindowTimeout, false ); 01871 #else 01872 #error "Please define a frequency band in the compiler options." 01873 #endif 01874 } 01875 01876 static void OnRxWindow2TimerEvent( void ) 01877 { 01878 bool rxContinuousMode = false; 01879 01880 TimerStop( &RxWindowTimer2 ); 01881 01882 if( LoRaMacDeviceClass == CLASS_C ) 01883 { 01884 rxContinuousMode = true; 01885 } 01886 if( RxWindowSetup( LoRaMacParams.Rx2Channel .Frequency , RxWindowsParams[1].Datarate, RxWindowsParams[1].Bandwidth, RxWindowsParams[1].RxWindowTimeout, rxContinuousMode ) == true ) 01887 { 01888 RxSlot = 1; 01889 } 01890 } 01891 01892 static void OnAckTimeoutTimerEvent( void ) 01893 { 01894 TimerStop( &AckTimeoutTimer ); 01895 01896 if( NodeAckRequested == true ) 01897 { 01898 AckTimeoutRetry = true; 01899 LoRaMacState &= ~LORAMAC_ACK_REQ; 01900 } 01901 if( LoRaMacDeviceClass == CLASS_C ) 01902 { 01903 LoRaMacFlags.Bits.MacDone = 1; 01904 } 01905 } 01906 01907 static bool SetNextChannel( TimerTime_t* time ) 01908 { 01909 uint8_t nbEnabledChannels = 0; 01910 uint8_t delayTx = 0; 01911 uint8_t enabledChannels[LORA_MAX_NB_CHANNELS]; 01912 TimerTime_t nextTxDelay = ( TimerTime_t )( -1 ); 01913 01914 memset1( enabledChannels, 0, LORA_MAX_NB_CHANNELS ); 01915 01916 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 01917 if( CountNbEnabled125kHzChannels( ChannelsMaskRemaining ) == 0 ) 01918 { // Restore default channels 01919 memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) LoRaMacParams.ChannelsMask , 8 ); 01920 } 01921 if( ( LoRaMacParams.ChannelsDatarate >= DR_4 ) && ( ( ChannelsMaskRemaining[4] & 0x00FF ) == 0 ) ) 01922 { // Make sure, that the channels are activated 01923 ChannelsMaskRemaining[4] = LoRaMacParams.ChannelsMask [4]; 01924 } 01925 #elif defined( USE_BAND_470 ) 01926 if( ( CountBits( LoRaMacParams.ChannelsMask [0], 16 ) == 0 ) && 01927 ( CountBits( LoRaMacParams.ChannelsMask [1], 16 ) == 0 ) && 01928 ( CountBits( LoRaMacParams.ChannelsMask [2], 16 ) == 0 ) && 01929 ( CountBits( LoRaMacParams.ChannelsMask [3], 16 ) == 0 ) && 01930 ( CountBits( LoRaMacParams.ChannelsMask [4], 16 ) == 0 ) && 01931 ( CountBits( LoRaMacParams.ChannelsMask [5], 16 ) == 0 ) ) 01932 { 01933 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask ) ); 01934 } 01935 #else 01936 if( CountBits( LoRaMacParams.ChannelsMask [0], 16 ) == 0 ) 01937 { 01938 // Re-enable default channels, if no channel is enabled 01939 LoRaMacParams.ChannelsMask [0] = LoRaMacParams.ChannelsMask [0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) ); 01940 } 01941 #endif 01942 01943 // Update Aggregated duty cycle 01944 if( AggregatedTimeOff <= TimerGetElapsedTime( AggregatedLastTxDoneTime ) ) 01945 { 01946 AggregatedTimeOff = 0; 01947 01948 // Update bands Time OFF 01949 for( uint8_t i = 0; i < LORA_MAX_NB_BANDS; i++ ) 01950 { 01951 if( ( IsLoRaMacNetworkJoined == false ) || ( DutyCycleOn == true ) ) 01952 { 01953 if( Bands[i].TimeOff <= TimerGetElapsedTime( Bands[i].LastTxDoneTime ) ) 01954 { 01955 Bands[i].TimeOff = 0; 01956 } 01957 if( Bands[i].TimeOff != 0 ) 01958 { 01959 nextTxDelay = MIN( Bands[i].TimeOff - TimerGetElapsedTime( Bands[i].LastTxDoneTime ), nextTxDelay ); 01960 } 01961 } 01962 else 01963 { 01964 if( DutyCycleOn == false ) 01965 { 01966 Bands[i].TimeOff = 0; 01967 } 01968 } 01969 } 01970 01971 // Search how many channels are enabled 01972 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ ) 01973 { 01974 for( uint8_t j = 0; j < 16; j++ ) 01975 { 01976 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 01977 if( ( ChannelsMaskRemaining[k] & ( 1 << j ) ) != 0 ) 01978 #else 01979 if( ( LoRaMacParams.ChannelsMask [k] & ( 1 << j ) ) != 0 ) 01980 #endif 01981 { 01982 if( Channels[i + j].Frequency == 0 ) 01983 { // Check if the channel is enabled 01984 continue; 01985 } 01986 #if defined( USE_BAND_868 ) || defined( USE_BAND_433 ) || defined( USE_BAND_780 ) 01987 if( IsLoRaMacNetworkJoined == false ) 01988 { 01989 if( ( JOIN_CHANNELS & ( 1 << j ) ) == 0 ) 01990 { 01991 continue; 01992 } 01993 } 01994 #endif 01995 if( ( ( Channels[i + j].DrRange.Fields.Min <= LoRaMacParams.ChannelsDatarate ) && 01996 ( LoRaMacParams.ChannelsDatarate <= Channels[i + j].DrRange .Fields.Max ) ) == false ) 01997 { // Check if the current channel selection supports the given datarate 01998 continue; 01999 } 02000 if( Bands[Channels[i + j].Band].TimeOff > 0 ) 02001 { // Check if the band is available for transmission 02002 delayTx++; 02003 continue; 02004 } 02005 enabledChannels[nbEnabledChannels++] = i + j; 02006 } 02007 } 02008 } 02009 } 02010 else 02011 { 02012 delayTx++; 02013 nextTxDelay = AggregatedTimeOff - TimerGetElapsedTime( AggregatedLastTxDoneTime ); 02014 } 02015 02016 if( nbEnabledChannels > 0 ) 02017 { 02018 Channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )]; 02019 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 02020 if( Channel < ( LORA_MAX_NB_CHANNELS - 8 ) ) 02021 { 02022 DisableChannelInMask( Channel, ChannelsMaskRemaining ); 02023 } 02024 #endif 02025 *time = 0; 02026 return true; 02027 } 02028 else 02029 { 02030 if( delayTx > 0 ) 02031 { 02032 // Delay transmission due to AggregatedTimeOff or to a band time off 02033 *time = nextTxDelay; 02034 return true; 02035 } 02036 // Datarate not supported by any channel 02037 *time = 0; 02038 return false; 02039 } 02040 } 02041 02042 static bool RxWindowSetup( uint32_t freq, int8_t datarate, uint32_t bandwidth, uint16_t timeout, bool rxContinuous ) 02043 { 02044 uint8_t downlinkDatarate = Datarates[datarate]; 02045 RadioModems_t modem; 02046 02047 if( Radio.GetStatus( ) == RF_IDLE ) 02048 { 02049 Radio.SetChannel( freq ); 02050 02051 // Store downlink datarate 02052 McpsIndication.RxDatarate = ( uint8_t ) datarate; 02053 02054 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 02055 if( datarate == DR_7 ) 02056 { 02057 modem = MODEM_FSK; 02058 Radio.SetRxConfig( modem, 50e3, downlinkDatarate * 1e3, 0, 83.333e3, 5, timeout, false, 0, true, 0, 0, false, rxContinuous ); 02059 } 02060 else 02061 { 02062 modem = MODEM_LORA; 02063 Radio.SetRxConfig( modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous ); 02064 } 02065 #elif defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 02066 modem = MODEM_LORA; 02067 Radio.SetRxConfig( modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous ); 02068 #endif 02069 02070 if( RepeaterSupport == true ) 02071 { 02072 Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarateRepeater[datarate] + LORA_MAC_FRMPAYLOAD_OVERHEAD ); 02073 } 02074 else 02075 { 02076 Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarate[datarate] + LORA_MAC_FRMPAYLOAD_OVERHEAD ); 02077 } 02078 02079 if( rxContinuous == false ) 02080 { 02081 Radio.Rx( LoRaMacParams.MaxRxWindow ); 02082 } 02083 else 02084 { 02085 Radio.Rx( 0 ); // Continuous mode 02086 } 02087 return true; 02088 } 02089 return false; 02090 } 02091 02092 static bool Rx2FreqInRange( uint32_t freq ) 02093 { 02094 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 02095 if( Radio.CheckRfFrequency( freq ) == true ) 02096 #elif defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 02097 if( ( Radio.CheckRfFrequency( freq ) == true ) && 02098 ( freq >= LORAMAC_FIRST_RX1_CHANNEL ) && 02099 ( freq <= LORAMAC_LAST_RX1_CHANNEL ) && 02100 ( ( ( freq - ( uint32_t ) LORAMAC_FIRST_RX1_CHANNEL ) % ( uint32_t ) LORAMAC_STEPWIDTH_RX1_CHANNEL ) == 0 ) ) 02101 #endif 02102 { 02103 return true; 02104 } 02105 return false; 02106 } 02107 02108 static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen ) 02109 { 02110 uint16_t maxN = 0; 02111 uint16_t payloadSize = 0; 02112 02113 // Get the maximum payload length 02114 if( RepeaterSupport == true ) 02115 { 02116 maxN = MaxPayloadOfDatarateRepeater[datarate]; 02117 } 02118 else 02119 { 02120 maxN = MaxPayloadOfDatarate[datarate]; 02121 } 02122 02123 // Calculate the resulting payload size 02124 payloadSize = ( lenN + fOptsLen ); 02125 02126 // Validation of the application payload size 02127 if( ( payloadSize <= maxN ) && ( payloadSize <= LORAMAC_PHY_MAXPAYLOAD ) ) 02128 { 02129 return true; 02130 } 02131 return false; 02132 } 02133 02134 static uint8_t CountBits( uint16_t mask, uint8_t nbBits ) 02135 { 02136 uint8_t nbActiveBits = 0; 02137 02138 for( uint8_t j = 0; j < nbBits; j++ ) 02139 { 02140 if( ( mask & ( 1 << j ) ) == ( 1 << j ) ) 02141 { 02142 nbActiveBits++; 02143 } 02144 } 02145 return nbActiveBits; 02146 } 02147 02148 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 02149 static uint8_t CountNbEnabled125kHzChannels( uint16_t *channelsMask ) 02150 { 02151 uint8_t nb125kHzChannels = 0; 02152 02153 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS - 8; i += 16, k++ ) 02154 { 02155 nb125kHzChannels += CountBits( channelsMask[k], 16 ); 02156 } 02157 02158 return nb125kHzChannels; 02159 } 02160 02161 #if defined( USE_BAND_915_HYBRID ) 02162 static void ReenableChannels( uint16_t mask, uint16_t* channelsMask ) 02163 { 02164 uint16_t blockMask = mask; 02165 02166 for( uint8_t i = 0, j = 0; i < 4; i++, j += 2 ) 02167 { 02168 channelsMask[i] = 0; 02169 if( ( blockMask & ( 1 << j ) ) != 0 ) 02170 { 02171 channelsMask[i] |= 0x00FF; 02172 } 02173 if( ( blockMask & ( 1 << ( j + 1 ) ) ) != 0 ) 02174 { 02175 channelsMask[i] |= 0xFF00; 02176 } 02177 } 02178 channelsMask[4] = blockMask; 02179 channelsMask[5] = 0x0000; 02180 } 02181 02182 static bool ValidateChannelMask( uint16_t* channelsMask ) 02183 { 02184 bool chanMaskState = false; 02185 uint16_t block1 = 0; 02186 uint16_t block2 = 0; 02187 uint8_t index = 0; 02188 02189 for( uint8_t i = 0; i < 4; i++ ) 02190 { 02191 block1 = channelsMask[i] & 0x00FF; 02192 block2 = channelsMask[i] & 0xFF00; 02193 02194 if( ( CountBits( block1, 16 ) > 5 ) && ( chanMaskState == false ) ) 02195 { 02196 channelsMask[i] &= block1; 02197 channelsMask[4] = 1 << ( i * 2 ); 02198 chanMaskState = true; 02199 index = i; 02200 } 02201 else if( ( CountBits( block2, 16 ) > 5 ) && ( chanMaskState == false ) ) 02202 { 02203 channelsMask[i] &= block2; 02204 channelsMask[4] = 1 << ( i * 2 + 1 ); 02205 chanMaskState = true; 02206 index = i; 02207 } 02208 } 02209 02210 // Do only change the channel mask, if we have found a valid block. 02211 if( chanMaskState == true ) 02212 { 02213 for( uint8_t i = 0; i < 4; i++ ) 02214 { 02215 if( i != index ) 02216 { 02217 channelsMask[i] = 0; 02218 } 02219 } 02220 } 02221 return chanMaskState; 02222 } 02223 #endif 02224 #endif 02225 02226 static bool ValidateDatarate( int8_t datarate, uint16_t* channelsMask ) 02227 { 02228 if( ValueInRange( datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == false ) 02229 { 02230 return false; 02231 } 02232 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ ) 02233 { 02234 for( uint8_t j = 0; j < 16; j++ ) 02235 { 02236 if( ( ( channelsMask[k] & ( 1 << j ) ) != 0 ) ) 02237 {// Check datarate validity for enabled channels 02238 if( ValueInRange( datarate, Channels[i + j].DrRange.Fields.Min, Channels[i + j].DrRange .Fields.Max ) == true ) 02239 { 02240 // At least 1 channel has been found we can return OK. 02241 return true; 02242 } 02243 } 02244 } 02245 } 02246 return false; 02247 } 02248 02249 static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower ) 02250 { 02251 int8_t resultTxPower = txPower; 02252 02253 // Limit tx power to the band max 02254 resultTxPower = MAX( txPower, maxBandTxPower ); 02255 02256 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 02257 if( ( LoRaMacParams.ChannelsDatarate == DR_4 ) || 02258 ( ( LoRaMacParams.ChannelsDatarate >= DR_8 ) && ( LoRaMacParams.ChannelsDatarate <= DR_13 ) ) ) 02259 {// Limit tx power to max 26dBm 02260 resultTxPower = MAX( txPower, TX_POWER_26_DBM ); 02261 } 02262 else 02263 { 02264 if( CountNbEnabled125kHzChannels( LoRaMacParams.ChannelsMask ) < 50 ) 02265 {// Limit tx power to max 21dBm 02266 resultTxPower = MAX( txPower, TX_POWER_20_DBM ); 02267 } 02268 } 02269 #endif 02270 return resultTxPower; 02271 } 02272 02273 static bool ValueInRange( int8_t value, int8_t min, int8_t max ) 02274 { 02275 if( ( value >= min ) && ( value <= max ) ) 02276 { 02277 return true; 02278 } 02279 return false; 02280 } 02281 02282 static bool DisableChannelInMask( uint8_t id, uint16_t* mask ) 02283 { 02284 uint8_t index = 0; 02285 index = id / 16; 02286 02287 if( ( index > 4 ) || ( id >= LORA_MAX_NB_CHANNELS ) ) 02288 { 02289 return false; 02290 } 02291 02292 // Deactivate channel 02293 mask[index] &= ~( 1 << ( id % 16 ) ); 02294 02295 return true; 02296 } 02297 02298 static bool AdrNextDr( bool adrEnabled, bool updateChannelMask, int8_t* datarateOut ) 02299 { 02300 bool adrAckReq = false; 02301 int8_t datarate = LoRaMacParams.ChannelsDatarate ; 02302 02303 if( adrEnabled == true ) 02304 { 02305 if( datarate == LORAMAC_TX_MIN_DATARATE ) 02306 { 02307 AdrAckCounter = 0; 02308 adrAckReq = false; 02309 } 02310 else 02311 { 02312 if( AdrAckCounter >= ADR_ACK_LIMIT ) 02313 { 02314 adrAckReq = true; 02315 LoRaMacParams.ChannelsTxPower = LORAMAC_MAX_TX_POWER; 02316 } 02317 else 02318 { 02319 adrAckReq = false; 02320 } 02321 if( AdrAckCounter >= ( ADR_ACK_LIMIT + ADR_ACK_DELAY ) ) 02322 { 02323 if( ( AdrAckCounter % ADR_ACK_DELAY ) == 1 ) 02324 { 02325 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 02326 if( datarate > LORAMAC_TX_MIN_DATARATE ) 02327 { 02328 datarate--; 02329 } 02330 if( datarate == LORAMAC_TX_MIN_DATARATE ) 02331 { 02332 if( updateChannelMask == true ) 02333 { 02334 // Re-enable default channels LC1, LC2, LC3 02335 LoRaMacParams.ChannelsMask [0] = LoRaMacParams.ChannelsMask [0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) ); 02336 } 02337 } 02338 #elif defined( USE_BAND_470 ) 02339 if( datarate > LORAMAC_TX_MIN_DATARATE ) 02340 { 02341 datarate--; 02342 } 02343 if( datarate == LORAMAC_TX_MIN_DATARATE ) 02344 { 02345 if( updateChannelMask == true ) 02346 { 02347 // Re-enable default channels 02348 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask ) ); 02349 } 02350 } 02351 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 02352 if( ( datarate > LORAMAC_TX_MIN_DATARATE ) && ( datarate == DR_8 ) ) 02353 { 02354 datarate = DR_4; 02355 } 02356 else if( datarate > LORAMAC_TX_MIN_DATARATE ) 02357 { 02358 datarate--; 02359 } 02360 if( datarate == LORAMAC_TX_MIN_DATARATE ) 02361 { 02362 if( updateChannelMask == true ) 02363 { 02364 #if defined( USE_BAND_915 ) 02365 // Re-enable default channels 02366 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask ) ); 02367 #else // defined( USE_BAND_915_HYBRID ) 02368 // Re-enable default channels 02369 ReenableChannels( LoRaMacParamsDefaults.ChannelsMask [4], LoRaMacParams.ChannelsMask ); 02370 #endif 02371 } 02372 } 02373 #else 02374 #error "Please define a frequency band in the compiler options." 02375 #endif 02376 } 02377 } 02378 } 02379 } 02380 02381 *datarateOut = datarate; 02382 02383 return adrAckReq; 02384 } 02385 02386 static LoRaMacStatus_t AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 ) 02387 { 02388 LoRaMacStatus_t status = LORAMAC_STATUS_BUSY ; 02389 // The maximum buffer length must take MAC commands to re-send into account. 02390 uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH - MacCommandsBufferToRepeatIndex; 02391 02392 switch( cmd ) 02393 { 02394 case MOTE_MAC_LINK_CHECK_REQ : 02395 if( MacCommandsBufferIndex < bufLen ) 02396 { 02397 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02398 // No payload for this command 02399 status = LORAMAC_STATUS_OK ; 02400 } 02401 break; 02402 case MOTE_MAC_LINK_ADR_ANS : 02403 if( MacCommandsBufferIndex < ( bufLen - 1 ) ) 02404 { 02405 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02406 // Margin 02407 MacCommandsBuffer[MacCommandsBufferIndex++] = p1; 02408 status = LORAMAC_STATUS_OK ; 02409 } 02410 break; 02411 case MOTE_MAC_DUTY_CYCLE_ANS : 02412 if( MacCommandsBufferIndex < bufLen ) 02413 { 02414 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02415 // No payload for this answer 02416 status = LORAMAC_STATUS_OK ; 02417 } 02418 break; 02419 case MOTE_MAC_RX_PARAM_SETUP_ANS : 02420 if( MacCommandsBufferIndex < ( bufLen - 1 ) ) 02421 { 02422 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02423 // Status: Datarate ACK, Channel ACK 02424 MacCommandsBuffer[MacCommandsBufferIndex++] = p1; 02425 status = LORAMAC_STATUS_OK ; 02426 } 02427 break; 02428 case MOTE_MAC_DEV_STATUS_ANS : 02429 if( MacCommandsBufferIndex < ( bufLen - 2 ) ) 02430 { 02431 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02432 // 1st byte Battery 02433 // 2nd byte Margin 02434 MacCommandsBuffer[MacCommandsBufferIndex++] = p1; 02435 MacCommandsBuffer[MacCommandsBufferIndex++] = p2; 02436 status = LORAMAC_STATUS_OK ; 02437 } 02438 break; 02439 case MOTE_MAC_NEW_CHANNEL_ANS : 02440 if( MacCommandsBufferIndex < ( bufLen - 1 ) ) 02441 { 02442 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02443 // Status: Datarate range OK, Channel frequency OK 02444 MacCommandsBuffer[MacCommandsBufferIndex++] = p1; 02445 status = LORAMAC_STATUS_OK ; 02446 } 02447 break; 02448 case MOTE_MAC_RX_TIMING_SETUP_ANS : 02449 if( MacCommandsBufferIndex < bufLen ) 02450 { 02451 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; 02452 // No payload for this answer 02453 status = LORAMAC_STATUS_OK ; 02454 } 02455 break; 02456 default: 02457 return LORAMAC_STATUS_SERVICE_UNKNOWN ; 02458 } 02459 if( status == LORAMAC_STATUS_OK ) 02460 { 02461 MacCommandsInNextTx = true; 02462 } 02463 return status; 02464 } 02465 02466 static uint8_t ParseMacCommandsToRepeat( uint8_t* cmdBufIn, uint8_t length, uint8_t* cmdBufOut ) 02467 { 02468 uint8_t i = 0; 02469 uint8_t cmdCount = 0; 02470 02471 if( ( cmdBufIn == NULL ) || ( cmdBufOut == NULL ) ) 02472 { 02473 return 0; 02474 } 02475 02476 for( i = 0; i < length; i++ ) 02477 { 02478 switch( cmdBufIn[i] ) 02479 { 02480 // STICKY 02481 case MOTE_MAC_RX_PARAM_SETUP_ANS : 02482 { 02483 cmdBufOut[cmdCount++] = cmdBufIn[i++]; 02484 cmdBufOut[cmdCount++] = cmdBufIn[i]; 02485 break; 02486 } 02487 case MOTE_MAC_RX_TIMING_SETUP_ANS : 02488 { 02489 cmdBufOut[cmdCount++] = cmdBufIn[i]; 02490 break; 02491 } 02492 // NON-STICKY 02493 case MOTE_MAC_DEV_STATUS_ANS : 02494 { // 2 bytes payload 02495 i += 2; 02496 break; 02497 } 02498 case MOTE_MAC_LINK_ADR_ANS : 02499 case MOTE_MAC_NEW_CHANNEL_ANS : 02500 { // 1 byte payload 02501 i++; 02502 break; 02503 } 02504 case MOTE_MAC_DUTY_CYCLE_ANS : 02505 case MOTE_MAC_LINK_CHECK_REQ : 02506 { // 0 byte payload 02507 break; 02508 } 02509 default: 02510 break; 02511 } 02512 } 02513 02514 return cmdCount; 02515 } 02516 02517 static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr ) 02518 { 02519 while( macIndex < commandsSize ) 02520 { 02521 // Decode Frame MAC commands 02522 switch( payload[macIndex++] ) 02523 { 02524 case SRV_MAC_LINK_CHECK_ANS : 02525 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK ; 02526 MlmeConfirm.DemodMargin = payload[macIndex++]; 02527 MlmeConfirm.NbGateways = payload[macIndex++]; 02528 break; 02529 case SRV_MAC_LINK_ADR_REQ : 02530 { 02531 uint8_t i; 02532 uint8_t status = 0x07; 02533 uint16_t chMask; 02534 int8_t txPower = 0; 02535 int8_t datarate = 0; 02536 uint8_t nbRep = 0; 02537 uint8_t chMaskCntl = 0; 02538 uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 }; 02539 02540 // Initialize local copy of the channels mask array 02541 for( i = 0; i < 6; i++ ) 02542 { 02543 channelsMask[i] = LoRaMacParams.ChannelsMask [i]; 02544 } 02545 datarate = payload[macIndex++]; 02546 txPower = datarate & 0x0F; 02547 datarate = ( datarate >> 4 ) & 0x0F; 02548 02549 if( ( AdrCtrlOn == false ) && 02550 ( ( LoRaMacParams.ChannelsDatarate != datarate ) || ( LoRaMacParams.ChannelsTxPower != txPower ) ) ) 02551 { // ADR disabled don't handle ADR requests if server tries to change datarate or txpower 02552 // Answer the server with fail status 02553 // Power ACK = 0 02554 // Data rate ACK = 0 02555 // Channel mask = 0 02556 AddMacCommand( MOTE_MAC_LINK_ADR_ANS , 0, 0 ); 02557 macIndex += 3; // Skip over the remaining bytes of the request 02558 break; 02559 } 02560 chMask = ( uint16_t )payload[macIndex++]; 02561 chMask |= ( uint16_t )payload[macIndex++] << 8; 02562 02563 nbRep = payload[macIndex++]; 02564 chMaskCntl = ( nbRep >> 4 ) & 0x07; 02565 nbRep &= 0x0F; 02566 if( nbRep == 0 ) 02567 { 02568 nbRep = 1; 02569 } 02570 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 02571 if( ( chMaskCntl == 0 ) && ( chMask == 0 ) ) 02572 { 02573 status &= 0xFE; // Channel mask KO 02574 } 02575 else if( ( ( chMaskCntl >= 1 ) && ( chMaskCntl <= 5 )) || 02576 ( chMaskCntl >= 7 ) ) 02577 { 02578 // RFU 02579 status &= 0xFE; // Channel mask KO 02580 } 02581 else 02582 { 02583 for( i = 0; i < LORA_MAX_NB_CHANNELS; i++ ) 02584 { 02585 if( chMaskCntl == 6 ) 02586 { 02587 if( Channels[i].Frequency != 0 ) 02588 { 02589 chMask |= 1 << i; 02590 } 02591 } 02592 else 02593 { 02594 if( ( ( chMask & ( 1 << i ) ) != 0 ) && 02595 ( Channels[i].Frequency == 0 ) ) 02596 {// Trying to enable an undefined channel 02597 status &= 0xFE; // Channel mask KO 02598 } 02599 } 02600 } 02601 channelsMask[0] = chMask; 02602 } 02603 #elif defined( USE_BAND_470 ) 02604 if( chMaskCntl == 6 ) 02605 { 02606 // Enable all 125 kHz channels 02607 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ ) 02608 { 02609 for( uint8_t j = 0; j < 16; j++ ) 02610 { 02611 if( Channels[i + j].Frequency != 0 ) 02612 { 02613 channelsMask[k] |= 1 << j; 02614 } 02615 } 02616 } 02617 } 02618 else if( chMaskCntl == 7 ) 02619 { 02620 status &= 0xFE; // Channel mask KO 02621 } 02622 else 02623 { 02624 for( uint8_t i = 0; i < 16; i++ ) 02625 { 02626 if( ( ( chMask & ( 1 << i ) ) != 0 ) && 02627 ( Channels[chMaskCntl * 16 + i].Frequency == 0 ) ) 02628 {// Trying to enable an undefined channel 02629 status &= 0xFE; // Channel mask KO 02630 } 02631 } 02632 channelsMask[chMaskCntl] = chMask; 02633 } 02634 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 02635 if( chMaskCntl == 6 ) 02636 { 02637 // Enable all 125 kHz channels 02638 channelsMask[0] = 0xFFFF; 02639 channelsMask[1] = 0xFFFF; 02640 channelsMask[2] = 0xFFFF; 02641 channelsMask[3] = 0xFFFF; 02642 // Apply chMask to channels 64 to 71 02643 channelsMask[4] = chMask; 02644 } 02645 else if( chMaskCntl == 7 ) 02646 { 02647 // Disable all 125 kHz channels 02648 channelsMask[0] = 0x0000; 02649 channelsMask[1] = 0x0000; 02650 channelsMask[2] = 0x0000; 02651 channelsMask[3] = 0x0000; 02652 // Apply chMask to channels 64 to 71 02653 channelsMask[4] = chMask; 02654 } 02655 else if( chMaskCntl == 5 ) 02656 { 02657 // RFU 02658 status &= 0xFE; // Channel mask KO 02659 } 02660 else 02661 { 02662 channelsMask[chMaskCntl] = chMask; 02663 02664 // FCC 15.247 paragraph F mandates to hop on at least 2 125 kHz channels 02665 if( ( datarate < DR_4 ) && ( CountNbEnabled125kHzChannels( channelsMask ) < 2 ) ) 02666 { 02667 status &= 0xFE; // Channel mask KO 02668 } 02669 02670 #if defined( USE_BAND_915_HYBRID ) 02671 if( ValidateChannelMask( channelsMask ) == false ) 02672 { 02673 status &= 0xFE; // Channel mask KO 02674 } 02675 #endif 02676 } 02677 #else 02678 #error "Please define a frequency band in the compiler options." 02679 #endif 02680 if( ValidateDatarate( datarate, channelsMask ) == false ) 02681 { 02682 status &= 0xFD; // Datarate KO 02683 } 02684 02685 // 02686 // Remark MaxTxPower = 0 and MinTxPower = 5 02687 // 02688 if( ValueInRange( txPower, LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) == false ) 02689 { 02690 status &= 0xFB; // TxPower KO 02691 } 02692 if( ( status & 0x07 ) == 0x07 ) 02693 { 02694 LoRaMacParams.ChannelsDatarate = datarate; 02695 LoRaMacParams.ChannelsTxPower = txPower; 02696 02697 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )channelsMask, sizeof( LoRaMacParams.ChannelsMask ) ); 02698 02699 LoRaMacParams.ChannelsNbRep = nbRep; 02700 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 02701 // Reset ChannelsMaskRemaining to the new ChannelsMask 02702 ChannelsMaskRemaining[0] &= channelsMask[0]; 02703 ChannelsMaskRemaining[1] &= channelsMask[1]; 02704 ChannelsMaskRemaining[2] &= channelsMask[2]; 02705 ChannelsMaskRemaining[3] &= channelsMask[3]; 02706 ChannelsMaskRemaining[4] = channelsMask[4]; 02707 ChannelsMaskRemaining[5] = channelsMask[5]; 02708 #endif 02709 } 02710 AddMacCommand( MOTE_MAC_LINK_ADR_ANS , status, 0 ); 02711 } 02712 break; 02713 case SRV_MAC_DUTY_CYCLE_REQ : 02714 MaxDCycle = payload[macIndex++]; 02715 AggregatedDCycle = 1 << MaxDCycle; 02716 AddMacCommand( MOTE_MAC_DUTY_CYCLE_ANS , 0, 0 ); 02717 break; 02718 case SRV_MAC_RX_PARAM_SETUP_REQ : 02719 { 02720 uint8_t status = 0x07; 02721 int8_t datarate = 0; 02722 int8_t drOffset = 0; 02723 uint32_t freq = 0; 02724 02725 drOffset = ( payload[macIndex] >> 4 ) & 0x07; 02726 datarate = payload[macIndex] & 0x0F; 02727 macIndex++; 02728 02729 freq = ( uint32_t )payload[macIndex++]; 02730 freq |= ( uint32_t )payload[macIndex++] << 8; 02731 freq |= ( uint32_t )payload[macIndex++] << 16; 02732 freq *= 100; 02733 02734 if( Rx2FreqInRange( freq ) == false ) 02735 { 02736 status &= 0xFE; // Channel frequency KO 02737 } 02738 02739 if( ValueInRange( datarate, LORAMAC_RX_MIN_DATARATE, LORAMAC_RX_MAX_DATARATE ) == false ) 02740 { 02741 status &= 0xFD; // Datarate KO 02742 } 02743 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) ) 02744 if( ( ValueInRange( datarate, DR_5, DR_7 ) == true ) || 02745 ( datarate > DR_13 ) ) 02746 { 02747 status &= 0xFD; // Datarate KO 02748 } 02749 #endif 02750 if( ValueInRange( drOffset, LORAMAC_MIN_RX1_DR_OFFSET, LORAMAC_MAX_RX1_DR_OFFSET ) == false ) 02751 { 02752 status &= 0xFB; // Rx1DrOffset range KO 02753 } 02754 02755 if( ( status & 0x07 ) == 0x07 ) 02756 { 02757 LoRaMacParams.Rx2Channel .Datarate = datarate; 02758 LoRaMacParams.Rx2Channel .Frequency = freq; 02759 LoRaMacParams.Rx1DrOffset = drOffset; 02760 } 02761 AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS , status, 0 ); 02762 } 02763 break; 02764 case SRV_MAC_DEV_STATUS_REQ : 02765 { 02766 uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE ; 02767 if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->GetBatteryLevel != NULL ) ) 02768 { 02769 batteryLevel = LoRaMacCallbacks->GetBatteryLevel( ); 02770 } 02771 AddMacCommand( MOTE_MAC_DEV_STATUS_ANS , batteryLevel, snr ); 02772 break; 02773 } 02774 case SRV_MAC_NEW_CHANNEL_REQ : 02775 { 02776 uint8_t status = 0x03; 02777 02778 #if defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 02779 status &= 0xFC; // Channel frequency and datarate KO 02780 macIndex += 5; 02781 #else 02782 int8_t channelIndex = 0; 02783 ChannelParams_t chParam; 02784 02785 channelIndex = payload[macIndex++]; 02786 chParam.Frequency = ( uint32_t )payload[macIndex++]; 02787 chParam.Frequency |= ( uint32_t )payload[macIndex++] << 8; 02788 chParam.Frequency |= ( uint32_t )payload[macIndex++] << 16; 02789 chParam.Frequency *= 100; 02790 chParam.DrRange .Value = payload[macIndex++]; 02791 02792 LoRaMacState |= LORAMAC_TX_CONFIG; 02793 if( chParam.Frequency == 0 ) 02794 { 02795 if( channelIndex < 3 ) 02796 { 02797 status &= 0xFC; 02798 } 02799 else 02800 { 02801 if( LoRaMacChannelRemove( channelIndex ) != LORAMAC_STATUS_OK ) 02802 { 02803 status &= 0xFC; 02804 } 02805 } 02806 } 02807 else 02808 { 02809 switch( LoRaMacChannelAdd( channelIndex, chParam ) ) 02810 { 02811 case LORAMAC_STATUS_OK : 02812 { 02813 break; 02814 } 02815 case LORAMAC_STATUS_FREQUENCY_INVALID : 02816 { 02817 status &= 0xFE; 02818 break; 02819 } 02820 case LORAMAC_STATUS_DATARATE_INVALID : 02821 { 02822 status &= 0xFD; 02823 break; 02824 } 02825 case LORAMAC_STATUS_FREQ_AND_DR_INVALID : 02826 { 02827 status &= 0xFC; 02828 break; 02829 } 02830 default: 02831 { 02832 status &= 0xFC; 02833 break; 02834 } 02835 } 02836 } 02837 LoRaMacState &= ~LORAMAC_TX_CONFIG; 02838 #endif 02839 AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS , status, 0 ); 02840 } 02841 break; 02842 case SRV_MAC_RX_TIMING_SETUP_REQ : 02843 { 02844 uint8_t delay = payload[macIndex++] & 0x0F; 02845 02846 if( delay == 0 ) 02847 { 02848 delay++; 02849 } 02850 LoRaMacParams.ReceiveDelay1 = delay * 1e3; 02851 LoRaMacParams.ReceiveDelay2 = LoRaMacParams.ReceiveDelay1 + 1e3; 02852 AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS , 0, 0 ); 02853 } 02854 break; 02855 default: 02856 // Unknown command. ABORT MAC commands processing 02857 return; 02858 } 02859 } 02860 } 02861 02862 LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) 02863 { 02864 LoRaMacFrameCtrl_t fCtrl; 02865 LoRaMacStatus_t status = LORAMAC_STATUS_PARAMETER_INVALID ; 02866 02867 fCtrl.Value = 0; 02868 fCtrl.Bits.FOptsLen = 0; 02869 fCtrl.Bits.FPending = 0; 02870 fCtrl.Bits.Ack = false; 02871 fCtrl.Bits.AdrAckReq = false; 02872 fCtrl.Bits.Adr = AdrCtrlOn; 02873 02874 // Prepare the frame 02875 status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize ); 02876 02877 // Validate status 02878 if( status != LORAMAC_STATUS_OK ) 02879 { 02880 return status; 02881 } 02882 02883 // Reset confirm parameters 02884 McpsConfirm.NbRetries = 0; 02885 McpsConfirm.AckReceived = false; 02886 McpsConfirm.UpLinkCounter = UpLinkCounter; 02887 02888 status = ScheduleTx( ); 02889 02890 return status; 02891 } 02892 02893 static LoRaMacStatus_t ScheduleTx( void ) 02894 { 02895 TimerTime_t dutyCycleTimeOff = 0; 02896 02897 // Check if the device is off 02898 if( MaxDCycle == 255 ) 02899 { 02900 return LORAMAC_STATUS_DEVICE_OFF ; 02901 } 02902 if( MaxDCycle == 0 ) 02903 { 02904 AggregatedTimeOff = 0; 02905 } 02906 02907 // Select channel 02908 while( SetNextChannel( &dutyCycleTimeOff ) == false ) 02909 { 02910 // Set the default datarate 02911 LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate ; 02912 02913 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 02914 // Re-enable default channels LC1, LC2, LC3 02915 LoRaMacParams.ChannelsMask [0] = LoRaMacParams.ChannelsMask [0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) ); 02916 #endif 02917 } 02918 02919 // Compute Rx1 windows parameters 02920 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) ) 02921 RxWindowsParams[0] = ComputeRxWindowParameters( DatarateOffsets[LoRaMacParams.ChannelsDatarate ][LoRaMacParams.Rx1DrOffset ], LoRaMacParams.SystemMaxRxError ); 02922 #else 02923 RxWindowsParams[0] = ComputeRxWindowParameters( MAX( DR_0, LoRaMacParams.ChannelsDatarate - LoRaMacParams.Rx1DrOffset ), LoRaMacParams.SystemMaxRxError ); 02924 #endif 02925 // Compute Rx2 windows parameters 02926 RxWindowsParams[1] = ComputeRxWindowParameters( LoRaMacParams.Rx2Channel .Datarate , LoRaMacParams.SystemMaxRxError ); 02927 02928 if( IsLoRaMacNetworkJoined == false ) 02929 { 02930 RxWindow1Delay = LoRaMacParams.JoinAcceptDelay1 + RxWindowsParams[0].RxOffset; 02931 RxWindow2Delay = LoRaMacParams.JoinAcceptDelay2 + RxWindowsParams[1].RxOffset; 02932 } 02933 else 02934 { 02935 if( ValidatePayloadLength( LoRaMacTxPayloadLen, LoRaMacParams.ChannelsDatarate , MacCommandsBufferIndex ) == false ) 02936 { 02937 return LORAMAC_STATUS_LENGTH_ERROR ; 02938 } 02939 RxWindow1Delay = LoRaMacParams.ReceiveDelay1 + RxWindowsParams[0].RxOffset; 02940 RxWindow2Delay = LoRaMacParams.ReceiveDelay2 + RxWindowsParams[1].RxOffset; 02941 } 02942 02943 // Schedule transmission of frame 02944 if( dutyCycleTimeOff == 0 ) 02945 { 02946 // Try to send now 02947 return SendFrameOnChannel( Channels[Channel] ); 02948 } 02949 else 02950 { 02951 // Send later - prepare timer 02952 LoRaMacState |= LORAMAC_TX_DELAYED; 02953 TimerSetValue( &TxDelayedTimer, dutyCycleTimeOff ); 02954 TimerStart( &TxDelayedTimer ); 02955 02956 return LORAMAC_STATUS_OK ; 02957 } 02958 } 02959 02960 static uint16_t JoinDutyCycle( void ) 02961 { 02962 uint16_t dutyCycle = 0; 02963 TimerTime_t timeElapsed = TimerGetElapsedTime( LoRaMacInitializationTime ); 02964 02965 if( timeElapsed < 3600e3 ) 02966 { 02967 dutyCycle = BACKOFF_DC_1_HOUR; 02968 } 02969 else if( timeElapsed < ( 3600e3 + 36000e3 ) ) 02970 { 02971 dutyCycle = BACKOFF_DC_10_HOURS; 02972 } 02973 else 02974 { 02975 dutyCycle = BACKOFF_DC_24_HOURS; 02976 } 02977 return dutyCycle; 02978 } 02979 02980 static void CalculateBackOff( uint8_t channel ) 02981 { 02982 uint16_t dutyCycle = Bands[Channels[channel].Band ].DCycle ; 02983 uint16_t joinDutyCycle = 0; 02984 02985 // Reset time-off to initial value. 02986 Bands[Channels[channel].Band ].TimeOff = 0; 02987 02988 if( IsLoRaMacNetworkJoined == false ) 02989 { 02990 // The node has not joined yet. Apply join duty cycle to all regions. 02991 joinDutyCycle = JoinDutyCycle( ); 02992 dutyCycle = MAX( dutyCycle, joinDutyCycle ); 02993 02994 // Update Band time-off. 02995 Bands[Channels[channel].Band ].TimeOff = TxTimeOnAir * dutyCycle - TxTimeOnAir; 02996 } 02997 else 02998 { 02999 if( DutyCycleOn == true ) 03000 { 03001 Bands[Channels[channel].Band ].TimeOff = TxTimeOnAir * dutyCycle - TxTimeOnAir; 03002 } 03003 } 03004 03005 // Update Aggregated Time OFF 03006 AggregatedTimeOff = AggregatedTimeOff + ( TxTimeOnAir * AggregatedDCycle - TxTimeOnAir ); 03007 } 03008 03009 static int8_t AlternateDatarate( uint16_t nbTrials ) 03010 { 03011 int8_t datarate = LORAMAC_TX_MIN_DATARATE; 03012 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 03013 #if defined( USE_BAND_915 ) 03014 // Re-enable 500 kHz default channels 03015 LoRaMacParams.ChannelsMask [4] = 0x00FF; 03016 #else // defined( USE_BAND_915_HYBRID ) 03017 // Re-enable 500 kHz default channels 03018 ReenableChannels( LoRaMacParamsDefaults.ChannelsMask [4], LoRaMacParams.ChannelsMask ); 03019 #endif 03020 03021 if( ( nbTrials & 0x01 ) == 0x01 ) 03022 { 03023 datarate = DR_4; 03024 } 03025 else 03026 { 03027 datarate = DR_0; 03028 } 03029 #else 03030 if( ( nbTrials % 48 ) == 0 ) 03031 { 03032 datarate = DR_0; 03033 } 03034 else if( ( nbTrials % 32 ) == 0 ) 03035 { 03036 datarate = DR_1; 03037 } 03038 else if( ( nbTrials % 24 ) == 0 ) 03039 { 03040 datarate = DR_2; 03041 } 03042 else if( ( nbTrials % 16 ) == 0 ) 03043 { 03044 datarate = DR_3; 03045 } 03046 else if( ( nbTrials % 8 ) == 0 ) 03047 { 03048 datarate = DR_4; 03049 } 03050 else 03051 { 03052 datarate = DR_5; 03053 } 03054 #endif 03055 return datarate; 03056 } 03057 03058 static void ResetMacParameters( void ) 03059 { 03060 IsLoRaMacNetworkJoined = false; 03061 03062 // Counters 03063 UpLinkCounter = 0; 03064 DownLinkCounter = 0; 03065 AdrAckCounter = 0; 03066 03067 ChannelsNbRepCounter = 0; 03068 03069 AckTimeoutRetries = 1; 03070 AckTimeoutRetriesCounter = 1; 03071 AckTimeoutRetry = false; 03072 03073 MaxDCycle = 0; 03074 AggregatedDCycle = 1; 03075 03076 MacCommandsBufferIndex = 0; 03077 MacCommandsBufferToRepeatIndex = 0; 03078 03079 IsRxWindowsEnabled = true; 03080 03081 LoRaMacParams.ChannelsTxPower = LoRaMacParamsDefaults.ChannelsTxPower ; 03082 LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate ; 03083 03084 LoRaMacParams.Rx1DrOffset = LoRaMacParamsDefaults.Rx1DrOffset ; 03085 LoRaMacParams.Rx2Channel = LoRaMacParamsDefaults.Rx2Channel ; 03086 03087 memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask , ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask ) ); 03088 03089 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 03090 memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask ) ); 03091 #endif 03092 03093 03094 NodeAckRequested = false; 03095 SrvAckRequested = false; 03096 MacCommandsInNextTx = false; 03097 03098 // Reset Multicast downlink counters 03099 MulticastParams_t *cur = MulticastChannels; 03100 while( cur != NULL ) 03101 { 03102 cur->DownLinkCounter = 0; 03103 cur = cur->Next ; 03104 } 03105 03106 // Initialize channel index. 03107 Channel = LORA_MAX_NB_CHANNELS; 03108 } 03109 03110 LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) 03111 { 03112 uint16_t i; 03113 uint8_t pktHeaderLen = 0; 03114 uint32_t mic = 0; 03115 const void* payload = fBuffer; 03116 uint8_t framePort = fPort; 03117 03118 LoRaMacBufferPktLen = 0; 03119 03120 NodeAckRequested = false; 03121 03122 if( fBuffer == NULL ) 03123 { 03124 fBufferSize = 0; 03125 } 03126 03127 LoRaMacTxPayloadLen = fBufferSize; 03128 03129 LoRaMacBuffer[pktHeaderLen++] = macHdr->Value ; 03130 03131 switch( macHdr->Bits.MType ) 03132 { 03133 case FRAME_TYPE_JOIN_REQ : 03134 LoRaMacBufferPktLen = pktHeaderLen; 03135 03136 memcpyr( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacAppEui, 8 ); 03137 LoRaMacBufferPktLen += 8; 03138 memcpyr( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacDevEui, 8 ); 03139 LoRaMacBufferPktLen += 8; 03140 03141 LoRaMacDevNonce = Radio.Random( ); 03142 03143 LoRaMacBuffer[LoRaMacBufferPktLen++] = LoRaMacDevNonce & 0xFF; 03144 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( LoRaMacDevNonce >> 8 ) & 0xFF; 03145 03146 LoRaMacJoinComputeMic ( LoRaMacBuffer, LoRaMacBufferPktLen & 0xFF, LoRaMacAppKey, &mic ); 03147 03148 LoRaMacBuffer[LoRaMacBufferPktLen++] = mic & 0xFF; 03149 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 8 ) & 0xFF; 03150 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 16 ) & 0xFF; 03151 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 24 ) & 0xFF; 03152 03153 break; 03154 case FRAME_TYPE_DATA_CONFIRMED_UP : 03155 NodeAckRequested = true; 03156 //Intentional fallthrough 03157 case FRAME_TYPE_DATA_UNCONFIRMED_UP : 03158 if( IsLoRaMacNetworkJoined == false ) 03159 { 03160 return LORAMAC_STATUS_NO_NETWORK_JOINED ; // No network has been joined yet 03161 } 03162 03163 fCtrl->Bits.AdrAckReq = AdrNextDr( fCtrl->Bits.Adr , true, &LoRaMacParams.ChannelsDatarate ); 03164 03165 if( SrvAckRequested == true ) 03166 { 03167 SrvAckRequested = false; 03168 fCtrl->Bits.Ack = 1; 03169 } 03170 03171 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr ) & 0xFF; 03172 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 8 ) & 0xFF; 03173 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 16 ) & 0xFF; 03174 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 24 ) & 0xFF; 03175 03176 LoRaMacBuffer[pktHeaderLen++] = fCtrl->Value ; 03177 03178 LoRaMacBuffer[pktHeaderLen++] = UpLinkCounter & 0xFF; 03179 LoRaMacBuffer[pktHeaderLen++] = ( UpLinkCounter >> 8 ) & 0xFF; 03180 03181 // Copy the MAC commands which must be re-send into the MAC command buffer 03182 memcpy1( &MacCommandsBuffer[MacCommandsBufferIndex], MacCommandsBufferToRepeat, MacCommandsBufferToRepeatIndex ); 03183 MacCommandsBufferIndex += MacCommandsBufferToRepeatIndex; 03184 03185 if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) ) 03186 { 03187 if( ( MacCommandsBufferIndex <= LORA_MAC_COMMAND_MAX_LENGTH ) && ( MacCommandsInNextTx == true ) ) 03188 { 03189 fCtrl->Bits.FOptsLen += MacCommandsBufferIndex; 03190 03191 // Update FCtrl field with new value of OptionsLength 03192 LoRaMacBuffer[0x05] = fCtrl->Value ; 03193 for( i = 0; i < MacCommandsBufferIndex; i++ ) 03194 { 03195 LoRaMacBuffer[pktHeaderLen++] = MacCommandsBuffer[i]; 03196 } 03197 } 03198 } 03199 else 03200 { 03201 if( ( MacCommandsBufferIndex > 0 ) && ( MacCommandsInNextTx ) ) 03202 { 03203 LoRaMacTxPayloadLen = MacCommandsBufferIndex; 03204 payload = MacCommandsBuffer; 03205 framePort = 0; 03206 } 03207 } 03208 MacCommandsInNextTx = false; 03209 // Store MAC commands which must be re-send in case the device does not receive a downlink anymore 03210 MacCommandsBufferToRepeatIndex = ParseMacCommandsToRepeat( MacCommandsBuffer, MacCommandsBufferIndex, MacCommandsBufferToRepeat ); 03211 if( MacCommandsBufferToRepeatIndex > 0 ) 03212 { 03213 MacCommandsInNextTx = true; 03214 } 03215 03216 if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) ) 03217 { 03218 LoRaMacBuffer[pktHeaderLen++] = framePort; 03219 03220 if( framePort == 0 ) 03221 { 03222 LoRaMacPayloadEncrypt ( (uint8_t* ) payload, LoRaMacTxPayloadLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &LoRaMacBuffer[pktHeaderLen] ); 03223 } 03224 else 03225 { 03226 LoRaMacPayloadEncrypt ( (uint8_t* ) payload, LoRaMacTxPayloadLen, LoRaMacAppSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &LoRaMacBuffer[pktHeaderLen] ); 03227 } 03228 } 03229 LoRaMacBufferPktLen = pktHeaderLen + LoRaMacTxPayloadLen; 03230 03231 LoRaMacComputeMic( LoRaMacBuffer, LoRaMacBufferPktLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &mic ); 03232 03233 LoRaMacBuffer[LoRaMacBufferPktLen + 0] = mic & 0xFF; 03234 LoRaMacBuffer[LoRaMacBufferPktLen + 1] = ( mic >> 8 ) & 0xFF; 03235 LoRaMacBuffer[LoRaMacBufferPktLen + 2] = ( mic >> 16 ) & 0xFF; 03236 LoRaMacBuffer[LoRaMacBufferPktLen + 3] = ( mic >> 24 ) & 0xFF; 03237 03238 LoRaMacBufferPktLen += LORAMAC_MFR_LEN; 03239 03240 break; 03241 case FRAME_TYPE_PROPRIETARY : 03242 if( ( fBuffer != NULL ) && ( LoRaMacTxPayloadLen > 0 ) ) 03243 { 03244 memcpy1( LoRaMacBuffer + pktHeaderLen, ( uint8_t* ) fBuffer, LoRaMacTxPayloadLen ); 03245 LoRaMacBufferPktLen = pktHeaderLen + LoRaMacTxPayloadLen; 03246 } 03247 break; 03248 default: 03249 return LORAMAC_STATUS_SERVICE_UNKNOWN ; 03250 } 03251 03252 return LORAMAC_STATUS_OK ; 03253 } 03254 03255 LoRaMacStatus_t SendFrameOnChannel( ChannelParams_t channel ) 03256 { 03257 int8_t datarate = Datarates[LoRaMacParams.ChannelsDatarate ]; 03258 int8_t txPowerIndex = 0; 03259 int8_t txPower = 0; 03260 03261 txPowerIndex = LimitTxPower( LoRaMacParams.ChannelsTxPower , Bands[channel.Band ].TxMaxPower ); 03262 txPower = TxPowers[txPowerIndex]; 03263 03264 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 03265 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 03266 McpsConfirm.Datarate = LoRaMacParams.ChannelsDatarate ; 03267 McpsConfirm.TxPower = txPowerIndex; 03268 McpsConfirm.UpLinkFrequency = channel.Frequency ; 03269 03270 Radio.SetChannel( channel.Frequency ); 03271 03272 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 03273 if( LoRaMacParams.ChannelsDatarate == DR_7 ) 03274 { // High Speed FSK channel 03275 Radio.SetMaxPayloadLength( MODEM_FSK, LoRaMacBufferPktLen ); 03276 Radio.SetTxConfig( MODEM_FSK, txPower, 25e3, 0, datarate * 1e3, 0, 5, false, true, 0, 0, false, 3e3 ); 03277 TxTimeOnAir = Radio.TimeOnAir( MODEM_FSK, LoRaMacBufferPktLen ); 03278 03279 } 03280 else if( LoRaMacParams.ChannelsDatarate == DR_6 ) 03281 { // High speed LoRa channel 03282 Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen ); 03283 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 1, datarate, 1, 8, false, true, 0, 0, false, 3e3 ); 03284 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen ); 03285 } 03286 else 03287 { // Normal LoRa channel 03288 Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen ); 03289 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e3 ); 03290 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen ); 03291 } 03292 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 03293 Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen ); 03294 if( LoRaMacParams.ChannelsDatarate >= DR_4 ) 03295 { // High speed LoRa channel BW500 kHz 03296 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 2, datarate, 1, 8, false, true, 0, 0, false, 3e3 ); 03297 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen ); 03298 } 03299 else 03300 { // Normal LoRa channel 03301 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e3 ); 03302 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen ); 03303 } 03304 #elif defined( USE_BAND_470 ) 03305 Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen ); 03306 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e3 ); 03307 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen ); 03308 #else 03309 #error "Please define a frequency band in the compiler options." 03310 #endif 03311 03312 // Store the time on air 03313 McpsConfirm.TxTimeOnAir = TxTimeOnAir; 03314 MlmeConfirm.TxTimeOnAir = TxTimeOnAir; 03315 03316 // Starts the MAC layer status check timer 03317 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); 03318 TimerStart( &MacStateCheckTimer ); 03319 03320 if( IsLoRaMacNetworkJoined == false ) 03321 { 03322 JoinRequestTrials++; 03323 } 03324 03325 // Send now 03326 Radio.Send( LoRaMacBuffer, LoRaMacBufferPktLen ); 03327 03328 LoRaMacState |= LORAMAC_TX_RUNNING; 03329 03330 return LORAMAC_STATUS_OK ; 03331 } 03332 03333 LoRaMacStatus_t SetTxContinuousWave( uint16_t timeout ) 03334 { 03335 int8_t txPowerIndex = 0; 03336 int8_t txPower = 0; 03337 03338 txPowerIndex = LimitTxPower( LoRaMacParams.ChannelsTxPower , Bands[Channels[Channel].Band ].TxMaxPower ); 03339 txPower = TxPowers[txPowerIndex]; 03340 03341 // Starts the MAC layer status check timer 03342 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); 03343 TimerStart( &MacStateCheckTimer ); 03344 03345 Radio.SetTxContinuousWave( Channels[Channel].Frequency, txPower, timeout ); 03346 03347 LoRaMacState |= LORAMAC_TX_RUNNING; 03348 03349 return LORAMAC_STATUS_OK ; 03350 } 03351 03352 LoRaMacStatus_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power ) 03353 { 03354 Radio.SetTxContinuousWave( frequency, power, timeout ); 03355 03356 // Starts the MAC layer status check timer 03357 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); 03358 TimerStart( &MacStateCheckTimer ); 03359 03360 LoRaMacState |= LORAMAC_TX_RUNNING; 03361 03362 return LORAMAC_STATUS_OK ; 03363 } 03364 03365 LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t *primitives, LoRaMacCallback_t *callbacks ) 03366 { 03367 if( primitives == NULL ) 03368 { 03369 return LORAMAC_STATUS_PARAMETER_INVALID ; 03370 } 03371 03372 if( ( primitives->MacMcpsConfirm == NULL ) || 03373 ( primitives->MacMcpsIndication == NULL ) || 03374 ( primitives->MacMlmeConfirm == NULL ) ) 03375 { 03376 return LORAMAC_STATUS_PARAMETER_INVALID ; 03377 } 03378 03379 LoRaMacPrimitives = primitives; 03380 LoRaMacCallbacks = callbacks; 03381 03382 LoRaMacFlags.Value = 0; 03383 03384 LoRaMacDeviceClass = CLASS_A ; 03385 LoRaMacState = LORAMAC_IDLE; 03386 03387 JoinRequestTrials = 0; 03388 MaxJoinRequestTrials = 1; 03389 RepeaterSupport = false; 03390 03391 // Reset duty cycle times 03392 AggregatedLastTxDoneTime = 0; 03393 AggregatedTimeOff = 0; 03394 03395 // Duty cycle 03396 #if defined( USE_BAND_433 ) 03397 DutyCycleOn = true; 03398 #elif defined( USE_BAND_470 ) 03399 DutyCycleOn = false; 03400 #elif defined( USE_BAND_780 ) 03401 DutyCycleOn = true; 03402 #elif defined( USE_BAND_868 ) 03403 DutyCycleOn = true; 03404 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 03405 DutyCycleOn = false; 03406 #else 03407 #error "Please define a frequency band in the compiler options." 03408 #endif 03409 03410 // Reset to defaults 03411 LoRaMacParamsDefaults.ChannelsTxPower = LORAMAC_DEFAULT_TX_POWER; 03412 LoRaMacParamsDefaults.ChannelsDatarate = LORAMAC_DEFAULT_DATARATE; 03413 03414 LoRaMacParamsDefaults.SystemMaxRxError = 10; 03415 LoRaMacParamsDefaults.MinRxSymbols = 6; 03416 LoRaMacParamsDefaults.MaxRxWindow = MAX_RX_WINDOW; 03417 LoRaMacParamsDefaults.ReceiveDelay1 = RECEIVE_DELAY1; 03418 LoRaMacParamsDefaults.ReceiveDelay2 = RECEIVE_DELAY2; 03419 LoRaMacParamsDefaults.JoinAcceptDelay1 = JOIN_ACCEPT_DELAY1; 03420 LoRaMacParamsDefaults.JoinAcceptDelay2 = JOIN_ACCEPT_DELAY2; 03421 03422 LoRaMacParamsDefaults.ChannelsNbRep = 1; 03423 LoRaMacParamsDefaults.Rx1DrOffset = 0; 03424 03425 LoRaMacParamsDefaults.Rx2Channel = ( Rx2ChannelParams_t )RX_WND_2_CHANNEL; 03426 03427 // Channel mask 03428 #if defined( USE_BAND_433 ) 03429 LoRaMacParamsDefaults.ChannelsMask [0] = LC( 1 ) + LC( 2 ) + LC( 3 ); 03430 #elif defined ( USE_BAND_470 ) 03431 LoRaMacParamsDefaults.ChannelsMask [0] = 0xFFFF; 03432 LoRaMacParamsDefaults.ChannelsMask [1] = 0xFFFF; 03433 LoRaMacParamsDefaults.ChannelsMask [2] = 0xFFFF; 03434 LoRaMacParamsDefaults.ChannelsMask [3] = 0xFFFF; 03435 LoRaMacParamsDefaults.ChannelsMask [4] = 0xFFFF; 03436 LoRaMacParamsDefaults.ChannelsMask [5] = 0xFFFF; 03437 #elif defined( USE_BAND_780 ) 03438 LoRaMacParamsDefaults.ChannelsMask [0] = LC( 1 ) + LC( 2 ) + LC( 3 ); 03439 #elif defined( USE_BAND_868 ) 03440 LoRaMacParamsDefaults.ChannelsMask [0] = LC( 1 ) + LC( 2 ) + LC( 3 ); 03441 #elif defined( USE_BAND_915 ) 03442 LoRaMacParamsDefaults.ChannelsMask [0] = 0xFFFF; 03443 LoRaMacParamsDefaults.ChannelsMask [1] = 0xFFFF; 03444 LoRaMacParamsDefaults.ChannelsMask [2] = 0xFFFF; 03445 LoRaMacParamsDefaults.ChannelsMask [3] = 0xFFFF; 03446 LoRaMacParamsDefaults.ChannelsMask [4] = 0x00FF; 03447 LoRaMacParamsDefaults.ChannelsMask [5] = 0x0000; 03448 #elif defined( USE_BAND_915_HYBRID ) 03449 LoRaMacParamsDefaults.ChannelsMask [0] = 0x00FF; 03450 LoRaMacParamsDefaults.ChannelsMask [1] = 0x0000; 03451 LoRaMacParamsDefaults.ChannelsMask [2] = 0x0000; 03452 LoRaMacParamsDefaults.ChannelsMask [3] = 0x0000; 03453 LoRaMacParamsDefaults.ChannelsMask [4] = 0x0001; 03454 LoRaMacParamsDefaults.ChannelsMask [5] = 0x0000; 03455 #else 03456 #error "Please define a frequency band in the compiler options." 03457 #endif 03458 03459 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 03460 // 125 kHz channels 03461 for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS - 8; i++ ) 03462 { 03463 Channels[i].Frequency = 902.3e6 + i * 200e3; 03464 Channels[i].DrRange .Value = ( DR_3 << 4 ) | DR_0; 03465 Channels[i].Band = 0; 03466 } 03467 // 500 kHz channels 03468 for( uint8_t i = LORA_MAX_NB_CHANNELS - 8; i < LORA_MAX_NB_CHANNELS; i++ ) 03469 { 03470 Channels[i].Frequency = 903.0e6 + ( i - ( LORA_MAX_NB_CHANNELS - 8 ) ) * 1.6e6; 03471 Channels[i].DrRange .Value = ( DR_4 << 4 ) | DR_4; 03472 Channels[i].Band = 0; 03473 } 03474 #elif defined( USE_BAND_470 ) 03475 // 125 kHz channels 03476 for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS; i++ ) 03477 { 03478 Channels[i].Frequency = 470.3e6 + i * 200e3; 03479 Channels[i].DrRange .Value = ( DR_5 << 4 ) | DR_0; 03480 Channels[i].Band = 0; 03481 } 03482 #endif 03483 03484 // Init parameters which are not set in function ResetMacParameters 03485 LoRaMacParams.SystemMaxRxError = LoRaMacParamsDefaults.SystemMaxRxError ; 03486 LoRaMacParams.MinRxSymbols = LoRaMacParamsDefaults.MinRxSymbols ; 03487 LoRaMacParams.MaxRxWindow = LoRaMacParamsDefaults.MaxRxWindow ; 03488 LoRaMacParams.ReceiveDelay1 = LoRaMacParamsDefaults.ReceiveDelay1 ; 03489 LoRaMacParams.ReceiveDelay2 = LoRaMacParamsDefaults.ReceiveDelay2 ; 03490 LoRaMacParams.JoinAcceptDelay1 = LoRaMacParamsDefaults.JoinAcceptDelay1 ; 03491 LoRaMacParams.JoinAcceptDelay2 = LoRaMacParamsDefaults.JoinAcceptDelay2 ; 03492 LoRaMacParams.ChannelsNbRep = LoRaMacParamsDefaults.ChannelsNbRep ; 03493 03494 ResetMacParameters( ); 03495 03496 // Initialize timers 03497 TimerInit( &MacStateCheckTimer, OnMacStateCheckTimerEvent ); 03498 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); 03499 03500 TimerInit( &TxDelayedTimer, OnTxDelayedTimerEvent ); 03501 TimerInit( &RxWindowTimer1, OnRxWindow1TimerEvent ); 03502 TimerInit( &RxWindowTimer2, OnRxWindow2TimerEvent ); 03503 TimerInit( &AckTimeoutTimer, OnAckTimeoutTimerEvent ); 03504 03505 // Store the current initialization time 03506 LoRaMacInitializationTime = TimerGetCurrentTime( ); 03507 03508 // Initialize Radio driver 03509 RadioEvents.TxDone = OnRadioTxDone; 03510 RadioEvents.RxDone = OnRadioRxDone; 03511 RadioEvents.RxError = OnRadioRxError; 03512 RadioEvents.TxTimeout = OnRadioTxTimeout; 03513 RadioEvents.RxTimeout = OnRadioRxTimeout; 03514 Radio.Init( &RadioEvents ); 03515 03516 // Random seed initialization 03517 srand1( Radio.Random( ) ); 03518 03519 PublicNetwork = true; 03520 Radio.SetPublicNetwork( PublicNetwork ); 03521 Radio.Sleep( ); 03522 03523 return LORAMAC_STATUS_OK ; 03524 } 03525 03526 LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t * txInfo ) 03527 { 03528 int8_t datarate = LoRaMacParamsDefaults.ChannelsDatarate ; 03529 uint8_t fOptLen = MacCommandsBufferIndex + MacCommandsBufferToRepeatIndex; 03530 03531 if( txInfo == NULL ) 03532 { 03533 return LORAMAC_STATUS_PARAMETER_INVALID ; 03534 } 03535 03536 AdrNextDr( AdrCtrlOn, false, &datarate ); 03537 03538 if( RepeaterSupport == true ) 03539 { 03540 txInfo->CurrentPayloadSize = MaxPayloadOfDatarateRepeater[datarate]; 03541 } 03542 else 03543 { 03544 txInfo->CurrentPayloadSize = MaxPayloadOfDatarate[datarate]; 03545 } 03546 03547 if( txInfo->CurrentPayloadSize >= fOptLen ) 03548 { 03549 txInfo->MaxPossiblePayload = txInfo->CurrentPayloadSize - fOptLen; 03550 } 03551 else 03552 { 03553 return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR ; 03554 } 03555 03556 if( ValidatePayloadLength( size, datarate, 0 ) == false ) 03557 { 03558 return LORAMAC_STATUS_LENGTH_ERROR ; 03559 } 03560 03561 if( ValidatePayloadLength( size, datarate, fOptLen ) == false ) 03562 { 03563 return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR ; 03564 } 03565 03566 return LORAMAC_STATUS_OK ; 03567 } 03568 03569 LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet ) 03570 { 03571 LoRaMacStatus_t status = LORAMAC_STATUS_OK ; 03572 03573 if( mibGet == NULL ) 03574 { 03575 return LORAMAC_STATUS_PARAMETER_INVALID ; 03576 } 03577 03578 switch( mibGet->Type ) 03579 { 03580 case MIB_DEVICE_CLASS : 03581 { 03582 mibGet->Param .Class = LoRaMacDeviceClass; 03583 break; 03584 } 03585 case MIB_NETWORK_JOINED : 03586 { 03587 mibGet->Param .IsNetworkJoined = IsLoRaMacNetworkJoined; 03588 break; 03589 } 03590 case MIB_ADR : 03591 { 03592 mibGet->Param .AdrEnable = AdrCtrlOn; 03593 break; 03594 } 03595 case MIB_NET_ID : 03596 { 03597 mibGet->Param .NetID = LoRaMacNetID; 03598 break; 03599 } 03600 case MIB_DEV_ADDR : 03601 { 03602 mibGet->Param .DevAddr = LoRaMacDevAddr; 03603 break; 03604 } 03605 case MIB_NWK_SKEY : 03606 { 03607 mibGet->Param .NwkSKey = LoRaMacNwkSKey; 03608 break; 03609 } 03610 case MIB_APP_SKEY : 03611 { 03612 mibGet->Param .AppSKey = LoRaMacAppSKey; 03613 break; 03614 } 03615 case MIB_PUBLIC_NETWORK : 03616 { 03617 mibGet->Param .EnablePublicNetwork = PublicNetwork; 03618 break; 03619 } 03620 case MIB_REPEATER_SUPPORT : 03621 { 03622 mibGet->Param .EnableRepeaterSupport = RepeaterSupport; 03623 break; 03624 } 03625 case MIB_CHANNELS : 03626 { 03627 mibGet->Param .ChannelList = Channels; 03628 break; 03629 } 03630 case MIB_RX2_CHANNEL : 03631 { 03632 mibGet->Param .Rx2Channel = LoRaMacParams.Rx2Channel ; 03633 break; 03634 } 03635 case MIB_RX2_DEFAULT_CHANNEL : 03636 { 03637 mibGet->Param .Rx2Channel = LoRaMacParamsDefaults.Rx2Channel ; 03638 break; 03639 } 03640 case MIB_CHANNELS_DEFAULT_MASK : 03641 { 03642 mibGet->Param .ChannelsDefaultMask = LoRaMacParamsDefaults.ChannelsMask ; 03643 break; 03644 } 03645 case MIB_CHANNELS_MASK : 03646 { 03647 mibGet->Param .ChannelsMask = LoRaMacParams.ChannelsMask ; 03648 break; 03649 } 03650 case MIB_CHANNELS_NB_REP : 03651 { 03652 mibGet->Param .ChannelNbRep = LoRaMacParams.ChannelsNbRep ; 03653 break; 03654 } 03655 case MIB_MAX_RX_WINDOW_DURATION : 03656 { 03657 mibGet->Param .MaxRxWindow = LoRaMacParams.MaxRxWindow ; 03658 break; 03659 } 03660 case MIB_RECEIVE_DELAY_1 : 03661 { 03662 mibGet->Param .ReceiveDelay1 = LoRaMacParams.ReceiveDelay1 ; 03663 break; 03664 } 03665 case MIB_RECEIVE_DELAY_2 : 03666 { 03667 mibGet->Param .ReceiveDelay2 = LoRaMacParams.ReceiveDelay2 ; 03668 break; 03669 } 03670 case MIB_JOIN_ACCEPT_DELAY_1 : 03671 { 03672 mibGet->Param .JoinAcceptDelay1 = LoRaMacParams.JoinAcceptDelay1 ; 03673 break; 03674 } 03675 case MIB_JOIN_ACCEPT_DELAY_2 : 03676 { 03677 mibGet->Param .JoinAcceptDelay2 = LoRaMacParams.JoinAcceptDelay2 ; 03678 break; 03679 } 03680 case MIB_CHANNELS_DEFAULT_DATARATE : 03681 { 03682 mibGet->Param .ChannelsDefaultDatarate = LoRaMacParamsDefaults.ChannelsDatarate ; 03683 break; 03684 } 03685 case MIB_CHANNELS_DATARATE : 03686 { 03687 mibGet->Param .ChannelsDatarate = LoRaMacParams.ChannelsDatarate ; 03688 break; 03689 } 03690 case MIB_CHANNELS_DEFAULT_TX_POWER : 03691 { 03692 mibGet->Param .ChannelsDefaultTxPower = LoRaMacParamsDefaults.ChannelsTxPower ; 03693 break; 03694 } 03695 case MIB_CHANNELS_TX_POWER : 03696 { 03697 mibGet->Param .ChannelsTxPower = LoRaMacParams.ChannelsTxPower ; 03698 break; 03699 } 03700 case MIB_UPLINK_COUNTER : 03701 { 03702 mibGet->Param .UpLinkCounter = UpLinkCounter; 03703 break; 03704 } 03705 case MIB_DOWNLINK_COUNTER : 03706 { 03707 mibGet->Param .DownLinkCounter = DownLinkCounter; 03708 break; 03709 } 03710 case MIB_MULTICAST_CHANNEL : 03711 { 03712 mibGet->Param .MulticastList = MulticastChannels; 03713 break; 03714 } 03715 case MIB_SYSTEM_MAX_RX_ERROR : 03716 { 03717 mibGet->Param .SystemMaxRxError = LoRaMacParams.SystemMaxRxError ; 03718 break; 03719 } 03720 case MIB_MIN_RX_SYMBOLS : 03721 { 03722 mibGet->Param .MinRxSymbols = LoRaMacParams.MinRxSymbols ; 03723 break; 03724 } 03725 default: 03726 status = LORAMAC_STATUS_SERVICE_UNKNOWN ; 03727 break; 03728 } 03729 03730 return status; 03731 } 03732 03733 LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ) 03734 { 03735 LoRaMacStatus_t status = LORAMAC_STATUS_OK ; 03736 03737 if( mibSet == NULL ) 03738 { 03739 return LORAMAC_STATUS_PARAMETER_INVALID ; 03740 } 03741 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) 03742 { 03743 return LORAMAC_STATUS_BUSY ; 03744 } 03745 03746 switch( mibSet->Type ) 03747 { 03748 case MIB_DEVICE_CLASS : 03749 { 03750 LoRaMacDeviceClass = mibSet->Param .Class ; 03751 switch( LoRaMacDeviceClass ) 03752 { 03753 case CLASS_A : 03754 { 03755 // Set the radio into sleep to setup a defined state 03756 Radio.Sleep( ); 03757 break; 03758 } 03759 case CLASS_B : 03760 { 03761 break; 03762 } 03763 case CLASS_C : 03764 { 03765 // Set the NodeAckRequested indicator to default 03766 NodeAckRequested = false; 03767 OnRxWindow2TimerEvent( ); 03768 break; 03769 } 03770 } 03771 break; 03772 } 03773 case MIB_NETWORK_JOINED : 03774 { 03775 IsLoRaMacNetworkJoined = mibSet->Param .IsNetworkJoined ; 03776 break; 03777 } 03778 case MIB_ADR : 03779 { 03780 AdrCtrlOn = mibSet->Param .AdrEnable ; 03781 break; 03782 } 03783 case MIB_NET_ID : 03784 { 03785 LoRaMacNetID = mibSet->Param .NetID ; 03786 break; 03787 } 03788 case MIB_DEV_ADDR : 03789 { 03790 LoRaMacDevAddr = mibSet->Param .DevAddr ; 03791 break; 03792 } 03793 case MIB_NWK_SKEY : 03794 { 03795 if( mibSet->Param .NwkSKey != NULL ) 03796 { 03797 memcpy1( LoRaMacNwkSKey, mibSet->Param .NwkSKey , 03798 sizeof( LoRaMacNwkSKey ) ); 03799 } 03800 else 03801 { 03802 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03803 } 03804 break; 03805 } 03806 case MIB_APP_SKEY : 03807 { 03808 if( mibSet->Param .AppSKey != NULL ) 03809 { 03810 memcpy1( LoRaMacAppSKey, mibSet->Param .AppSKey , 03811 sizeof( LoRaMacAppSKey ) ); 03812 } 03813 else 03814 { 03815 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03816 } 03817 break; 03818 } 03819 case MIB_PUBLIC_NETWORK : 03820 { 03821 PublicNetwork = mibSet->Param .EnablePublicNetwork ; 03822 Radio.SetPublicNetwork( PublicNetwork ); 03823 break; 03824 } 03825 case MIB_REPEATER_SUPPORT : 03826 { 03827 RepeaterSupport = mibSet->Param .EnableRepeaterSupport ; 03828 break; 03829 } 03830 case MIB_RX2_CHANNEL : 03831 { 03832 LoRaMacParams.Rx2Channel = mibSet->Param .Rx2Channel ; 03833 break; 03834 } 03835 case MIB_RX2_DEFAULT_CHANNEL : 03836 { 03837 LoRaMacParamsDefaults.Rx2Channel = mibSet->Param .Rx2DefaultChannel ; 03838 break; 03839 } 03840 case MIB_CHANNELS_DEFAULT_MASK : 03841 { 03842 if( mibSet->Param .ChannelsDefaultMask ) 03843 { 03844 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 03845 bool chanMaskState = true; 03846 03847 #if defined( USE_BAND_915_HYBRID ) 03848 chanMaskState = ValidateChannelMask( mibSet->Param .ChannelsDefaultMask ); 03849 #endif 03850 if( chanMaskState == true ) 03851 { 03852 if( ( CountNbEnabled125kHzChannels( mibSet->Param .ChannelsMask ) < 2 ) && 03853 ( CountNbEnabled125kHzChannels( mibSet->Param .ChannelsMask ) > 0 ) ) 03854 { 03855 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03856 } 03857 else 03858 { 03859 memcpy1( ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask , 03860 ( uint8_t* ) mibSet->Param .ChannelsDefaultMask , sizeof( LoRaMacParamsDefaults.ChannelsMask ) ); 03861 for ( uint8_t i = 0; i < sizeof( LoRaMacParamsDefaults.ChannelsMask ) / 2; i++ ) 03862 { 03863 // Disable channels which are no longer available 03864 ChannelsMaskRemaining[i] &= LoRaMacParamsDefaults.ChannelsMask [i]; 03865 } 03866 } 03867 } 03868 else 03869 { 03870 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03871 } 03872 #elif defined( USE_BAND_470 ) 03873 memcpy1( ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask , 03874 ( uint8_t* ) mibSet->Param .ChannelsDefaultMask , sizeof( LoRaMacParamsDefaults.ChannelsMask ) ); 03875 #else 03876 memcpy1( ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask , 03877 ( uint8_t* ) mibSet->Param .ChannelsDefaultMask , 2 ); 03878 #endif 03879 } 03880 else 03881 { 03882 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03883 } 03884 break; 03885 } 03886 case MIB_CHANNELS_MASK : 03887 { 03888 if( mibSet->Param .ChannelsMask ) 03889 { 03890 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 03891 bool chanMaskState = true; 03892 03893 #if defined( USE_BAND_915_HYBRID ) 03894 chanMaskState = ValidateChannelMask( mibSet->Param .ChannelsMask ); 03895 #endif 03896 if( chanMaskState == true ) 03897 { 03898 if( ( CountNbEnabled125kHzChannels( mibSet->Param .ChannelsMask ) < 2 ) && 03899 ( CountNbEnabled125kHzChannels( mibSet->Param .ChannelsMask ) > 0 ) ) 03900 { 03901 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03902 } 03903 else 03904 { 03905 memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask , 03906 ( uint8_t* ) mibSet->Param .ChannelsMask , sizeof( LoRaMacParams.ChannelsMask ) ); 03907 for ( uint8_t i = 0; i < sizeof( LoRaMacParams.ChannelsMask ) / 2; i++ ) 03908 { 03909 // Disable channels which are no longer available 03910 ChannelsMaskRemaining[i] &= LoRaMacParams.ChannelsMask [i]; 03911 } 03912 } 03913 } 03914 else 03915 { 03916 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03917 } 03918 #elif defined( USE_BAND_470 ) 03919 memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask , 03920 ( uint8_t* ) mibSet->Param .ChannelsMask , sizeof( LoRaMacParams.ChannelsMask ) ); 03921 #else 03922 memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask , 03923 ( uint8_t* ) mibSet->Param .ChannelsMask , 2 ); 03924 #endif 03925 } 03926 else 03927 { 03928 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03929 } 03930 break; 03931 } 03932 case MIB_CHANNELS_NB_REP : 03933 { 03934 if( ( mibSet->Param .ChannelNbRep >= 1 ) && 03935 ( mibSet->Param .ChannelNbRep <= 15 ) ) 03936 { 03937 LoRaMacParams.ChannelsNbRep = mibSet->Param .ChannelNbRep ; 03938 } 03939 else 03940 { 03941 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03942 } 03943 break; 03944 } 03945 case MIB_MAX_RX_WINDOW_DURATION : 03946 { 03947 LoRaMacParams.MaxRxWindow = mibSet->Param .MaxRxWindow ; 03948 break; 03949 } 03950 case MIB_RECEIVE_DELAY_1 : 03951 { 03952 LoRaMacParams.ReceiveDelay1 = mibSet->Param .ReceiveDelay1 ; 03953 break; 03954 } 03955 case MIB_RECEIVE_DELAY_2 : 03956 { 03957 LoRaMacParams.ReceiveDelay2 = mibSet->Param .ReceiveDelay2 ; 03958 break; 03959 } 03960 case MIB_JOIN_ACCEPT_DELAY_1 : 03961 { 03962 LoRaMacParams.JoinAcceptDelay1 = mibSet->Param .JoinAcceptDelay1 ; 03963 break; 03964 } 03965 case MIB_JOIN_ACCEPT_DELAY_2 : 03966 { 03967 LoRaMacParams.JoinAcceptDelay2 = mibSet->Param .JoinAcceptDelay2 ; 03968 break; 03969 } 03970 case MIB_CHANNELS_DEFAULT_DATARATE : 03971 { 03972 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 03973 if( ValueInRange( mibSet->Param .ChannelsDefaultDatarate , 03974 DR_0, DR_5 ) ) 03975 { 03976 LoRaMacParamsDefaults.ChannelsDatarate = mibSet->Param .ChannelsDefaultDatarate ; 03977 } 03978 #else 03979 if( ValueInRange( mibSet->Param .ChannelsDefaultDatarate , 03980 LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) ) 03981 { 03982 LoRaMacParamsDefaults.ChannelsDatarate = mibSet->Param .ChannelsDefaultDatarate ; 03983 } 03984 #endif 03985 else 03986 { 03987 status = LORAMAC_STATUS_PARAMETER_INVALID ; 03988 } 03989 break; 03990 } 03991 case MIB_CHANNELS_DATARATE : 03992 { 03993 if( ValueInRange( mibSet->Param .ChannelsDatarate , 03994 LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) ) 03995 { 03996 LoRaMacParams.ChannelsDatarate = mibSet->Param .ChannelsDatarate ; 03997 } 03998 else 03999 { 04000 status = LORAMAC_STATUS_PARAMETER_INVALID ; 04001 } 04002 break; 04003 } 04004 case MIB_CHANNELS_DEFAULT_TX_POWER : 04005 { 04006 if( ValueInRange( mibSet->Param .ChannelsDefaultTxPower , 04007 LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) ) 04008 { 04009 LoRaMacParamsDefaults.ChannelsTxPower = mibSet->Param .ChannelsDefaultTxPower ; 04010 } 04011 else 04012 { 04013 status = LORAMAC_STATUS_PARAMETER_INVALID ; 04014 } 04015 break; 04016 } 04017 case MIB_CHANNELS_TX_POWER : 04018 { 04019 if( ValueInRange( mibSet->Param .ChannelsTxPower , 04020 LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) ) 04021 { 04022 LoRaMacParams.ChannelsTxPower = mibSet->Param .ChannelsTxPower ; 04023 } 04024 else 04025 { 04026 status = LORAMAC_STATUS_PARAMETER_INVALID ; 04027 } 04028 break; 04029 } 04030 case MIB_UPLINK_COUNTER : 04031 { 04032 UpLinkCounter = mibSet->Param .UpLinkCounter ; 04033 break; 04034 } 04035 case MIB_DOWNLINK_COUNTER : 04036 { 04037 DownLinkCounter = mibSet->Param .DownLinkCounter ; 04038 break; 04039 } 04040 case MIB_SYSTEM_MAX_RX_ERROR : 04041 { 04042 LoRaMacParams.SystemMaxRxError = LoRaMacParamsDefaults.SystemMaxRxError = mibSet->Param .SystemMaxRxError ; 04043 break; 04044 } 04045 case MIB_MIN_RX_SYMBOLS : 04046 { 04047 LoRaMacParams.MinRxSymbols = LoRaMacParamsDefaults.MinRxSymbols = mibSet->Param .MinRxSymbols ; 04048 break; 04049 } 04050 default: 04051 status = LORAMAC_STATUS_SERVICE_UNKNOWN ; 04052 break; 04053 } 04054 04055 return status; 04056 } 04057 04058 LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params ) 04059 { 04060 #if defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) 04061 return LORAMAC_STATUS_PARAMETER_INVALID ; 04062 #else 04063 bool datarateInvalid = false; 04064 bool frequencyInvalid = false; 04065 uint8_t band = 0; 04066 04067 // The id must not exceed LORA_MAX_NB_CHANNELS 04068 if( id >= LORA_MAX_NB_CHANNELS ) 04069 { 04070 return LORAMAC_STATUS_PARAMETER_INVALID ; 04071 } 04072 // Validate if the MAC is in a correct state 04073 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) 04074 { 04075 if( ( LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) 04076 { 04077 return LORAMAC_STATUS_BUSY ; 04078 } 04079 } 04080 // Validate the datarate 04081 if( ( params.DrRange .Fields.Min > params.DrRange .Fields.Max ) || 04082 ( ValueInRange( params.DrRange .Fields.Min , LORAMAC_TX_MIN_DATARATE, 04083 LORAMAC_TX_MAX_DATARATE ) == false ) || 04084 ( ValueInRange( params.DrRange .Fields.Max , LORAMAC_TX_MIN_DATARATE, 04085 LORAMAC_TX_MAX_DATARATE ) == false ) ) 04086 { 04087 datarateInvalid = true; 04088 } 04089 04090 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 04091 if( id < 3 ) 04092 { 04093 if( params.Frequency != Channels[id].Frequency ) 04094 { 04095 frequencyInvalid = true; 04096 } 04097 04098 if( params.DrRange .Fields.Min > DR_0 ) 04099 { 04100 datarateInvalid = true; 04101 } 04102 if( ValueInRange( params.DrRange .Fields.Max , DR_5, LORAMAC_TX_MAX_DATARATE ) == false ) 04103 { 04104 datarateInvalid = true; 04105 } 04106 } 04107 #endif 04108 04109 // Validate the frequency 04110 if( ( Radio.CheckRfFrequency( params.Frequency ) == true ) && ( params.Frequency > 0 ) && ( frequencyInvalid == false ) ) 04111 { 04112 #if defined( USE_BAND_868 ) 04113 if( ( params.Frequency >= 863000000 ) && ( params.Frequency < 865000000 ) ) 04114 { 04115 band = BAND_G1_2; 04116 } 04117 else if( ( params.Frequency >= 865000000 ) && ( params.Frequency <= 868000000 ) ) 04118 { 04119 band = BAND_G1_0; 04120 } 04121 else if( ( params.Frequency > 868000000 ) && ( params.Frequency <= 868600000 ) ) 04122 { 04123 band = BAND_G1_1; 04124 } 04125 else if( ( params.Frequency >= 868700000 ) && ( params.Frequency <= 869200000 ) ) 04126 { 04127 band = BAND_G1_2; 04128 } 04129 else if( ( params.Frequency >= 869400000 ) && ( params.Frequency <= 869650000 ) ) 04130 { 04131 band = BAND_G1_3; 04132 } 04133 else if( ( params.Frequency >= 869700000 ) && ( params.Frequency <= 870000000 ) ) 04134 { 04135 band = BAND_G1_4; 04136 } 04137 else 04138 { 04139 frequencyInvalid = true; 04140 } 04141 #endif 04142 } 04143 else 04144 { 04145 frequencyInvalid = true; 04146 } 04147 04148 if( ( datarateInvalid == true ) && ( frequencyInvalid == true ) ) 04149 { 04150 return LORAMAC_STATUS_FREQ_AND_DR_INVALID ; 04151 } 04152 if( datarateInvalid == true ) 04153 { 04154 return LORAMAC_STATUS_DATARATE_INVALID ; 04155 } 04156 if( frequencyInvalid == true ) 04157 { 04158 return LORAMAC_STATUS_FREQUENCY_INVALID ; 04159 } 04160 04161 // Every parameter is valid, activate the channel 04162 Channels[id] = params; 04163 Channels[id].Band = band; 04164 LoRaMacParams.ChannelsMask [0] |= ( 1 << id ); 04165 04166 return LORAMAC_STATUS_OK ; 04167 #endif 04168 } 04169 04170 LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id ) 04171 { 04172 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 04173 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) 04174 { 04175 if( ( LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) 04176 { 04177 return LORAMAC_STATUS_BUSY ; 04178 } 04179 } 04180 04181 if( ( id < 3 ) || ( id >= LORA_MAX_NB_CHANNELS ) ) 04182 { 04183 return LORAMAC_STATUS_PARAMETER_INVALID ; 04184 } 04185 else 04186 { 04187 // Remove the channel from the list of channels 04188 Channels[id] = ( ChannelParams_t ){ 0, { 0 }, 0 }; 04189 04190 // Disable the channel as it doesn't exist anymore 04191 if( DisableChannelInMask( id, LoRaMacParams.ChannelsMask ) == false ) 04192 { 04193 return LORAMAC_STATUS_PARAMETER_INVALID ; 04194 } 04195 } 04196 return LORAMAC_STATUS_OK ; 04197 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) || defined( USE_BAND_470 ) ) 04198 return LORAMAC_STATUS_PARAMETER_INVALID ; 04199 #endif 04200 } 04201 04202 LoRaMacStatus_t LoRaMacMulticastChannelLink( MulticastParams_t *channelParam ) 04203 { 04204 if( channelParam == NULL ) 04205 { 04206 return LORAMAC_STATUS_PARAMETER_INVALID ; 04207 } 04208 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) 04209 { 04210 return LORAMAC_STATUS_BUSY ; 04211 } 04212 04213 // Reset downlink counter 04214 channelParam->DownLinkCounter = 0; 04215 04216 if( MulticastChannels == NULL ) 04217 { 04218 // New node is the fist element 04219 MulticastChannels = channelParam; 04220 } 04221 else 04222 { 04223 MulticastParams_t *cur = MulticastChannels; 04224 04225 // Search the last node in the list 04226 while( cur->Next != NULL ) 04227 { 04228 cur = cur->Next ; 04229 } 04230 // This function always finds the last node 04231 cur->Next = channelParam; 04232 } 04233 04234 return LORAMAC_STATUS_OK ; 04235 } 04236 04237 LoRaMacStatus_t LoRaMacMulticastChannelUnlink( MulticastParams_t *channelParam ) 04238 { 04239 if( channelParam == NULL ) 04240 { 04241 return LORAMAC_STATUS_PARAMETER_INVALID ; 04242 } 04243 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) 04244 { 04245 return LORAMAC_STATUS_BUSY ; 04246 } 04247 04248 if( MulticastChannels != NULL ) 04249 { 04250 if( MulticastChannels == channelParam ) 04251 { 04252 // First element 04253 MulticastChannels = channelParam->Next ; 04254 } 04255 else 04256 { 04257 MulticastParams_t *cur = MulticastChannels; 04258 04259 // Search the node in the list 04260 while( cur->Next && cur->Next != channelParam ) 04261 { 04262 cur = cur->Next ; 04263 } 04264 // If we found the node, remove it 04265 if( cur->Next ) 04266 { 04267 cur->Next = channelParam->Next ; 04268 } 04269 } 04270 channelParam->Next = NULL; 04271 } 04272 04273 return LORAMAC_STATUS_OK ; 04274 } 04275 04276 LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) 04277 { 04278 LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN ; 04279 LoRaMacHeader_t macHdr; 04280 04281 if( mlmeRequest == NULL ) 04282 { 04283 return LORAMAC_STATUS_PARAMETER_INVALID ; 04284 } 04285 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) 04286 { 04287 return LORAMAC_STATUS_BUSY ; 04288 } 04289 04290 memset1( ( uint8_t* ) &MlmeConfirm, 0, sizeof( MlmeConfirm ) ); 04291 04292 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 04293 04294 switch( mlmeRequest->Type ) 04295 { 04296 case MLME_JOIN : 04297 { 04298 if( ( LoRaMacState & LORAMAC_TX_DELAYED ) == LORAMAC_TX_DELAYED ) 04299 { 04300 return LORAMAC_STATUS_BUSY ; 04301 } 04302 04303 if( ( mlmeRequest->Req.Join .DevEui == NULL ) || 04304 ( mlmeRequest->Req.Join .AppEui == NULL ) || 04305 ( mlmeRequest->Req.Join .AppKey == NULL ) || 04306 ( mlmeRequest->Req.Join .NbTrials == 0 ) ) 04307 { 04308 return LORAMAC_STATUS_PARAMETER_INVALID ; 04309 } 04310 04311 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) ) 04312 // Enables at least the usage of the 2 datarates. 04313 if( mlmeRequest->Req.Join .NbTrials < 2 ) 04314 { 04315 mlmeRequest->Req.Join .NbTrials = 2; 04316 } 04317 #else 04318 // Enables at least the usage of all datarates. 04319 if( mlmeRequest->Req.Join .NbTrials < 48 ) 04320 { 04321 mlmeRequest->Req.Join .NbTrials = 48; 04322 } 04323 #endif 04324 04325 LoRaMacFlags.Bits.MlmeReq = 1; 04326 MlmeConfirm.MlmeRequest = mlmeRequest->Type ; 04327 04328 LoRaMacDevEui = mlmeRequest->Req.Join .DevEui ; 04329 LoRaMacAppEui = mlmeRequest->Req.Join .AppEui ; 04330 LoRaMacAppKey = mlmeRequest->Req.Join .AppKey ; 04331 MaxJoinRequestTrials = mlmeRequest->Req.Join .NbTrials ; 04332 04333 // Reset variable JoinRequestTrials 04334 JoinRequestTrials = 0; 04335 04336 // Setup header information 04337 macHdr.Value = 0; 04338 macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ ; 04339 04340 ResetMacParameters( ); 04341 04342 // Add a +1, since we start to count from 0 04343 LoRaMacParams.ChannelsDatarate = AlternateDatarate( JoinRequestTrials + 1 ); 04344 04345 status = Send( &macHdr, 0, NULL, 0 ); 04346 break; 04347 } 04348 case MLME_LINK_CHECK : 04349 { 04350 LoRaMacFlags.Bits.MlmeReq = 1; 04351 // LoRaMac will send this command piggy-pack 04352 MlmeConfirm.MlmeRequest = mlmeRequest->Type ; 04353 04354 status = AddMacCommand( MOTE_MAC_LINK_CHECK_REQ , 0, 0 ); 04355 break; 04356 } 04357 case MLME_TXCW : 04358 { 04359 MlmeConfirm.MlmeRequest = mlmeRequest->Type ; 04360 LoRaMacFlags.Bits.MlmeReq = 1; 04361 status = SetTxContinuousWave( mlmeRequest->Req.TxCw .Timeout ); 04362 break; 04363 } 04364 case MLME_TXCW_1 : 04365 { 04366 MlmeConfirm.MlmeRequest = mlmeRequest->Type ; 04367 LoRaMacFlags.Bits.MlmeReq = 1; 04368 status = SetTxContinuousWave1( mlmeRequest->Req.TxCw .Timeout , mlmeRequest->Req.TxCw .Frequency , mlmeRequest->Req.TxCw .Power ); 04369 break; 04370 } 04371 default: 04372 break; 04373 } 04374 04375 if( status != LORAMAC_STATUS_OK ) 04376 { 04377 NodeAckRequested = false; 04378 LoRaMacFlags.Bits.MlmeReq = 0; 04379 } 04380 04381 return status; 04382 } 04383 04384 LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) 04385 { 04386 LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN ; 04387 LoRaMacHeader_t macHdr; 04388 uint8_t fPort = 0; 04389 void *fBuffer; 04390 uint16_t fBufferSize; 04391 int8_t datarate; 04392 bool readyToSend = false; 04393 04394 if( mcpsRequest == NULL ) 04395 { 04396 return LORAMAC_STATUS_PARAMETER_INVALID ; 04397 } 04398 if( ( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) || 04399 ( ( LoRaMacState & LORAMAC_TX_DELAYED ) == LORAMAC_TX_DELAYED ) ) 04400 { 04401 return LORAMAC_STATUS_BUSY ; 04402 } 04403 04404 macHdr.Value = 0; 04405 memset1 ( ( uint8_t* ) &McpsConfirm, 0, sizeof( McpsConfirm ) ); 04406 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 04407 04408 switch( mcpsRequest->Type ) 04409 { 04410 case MCPS_UNCONFIRMED : 04411 { 04412 readyToSend = true; 04413 AckTimeoutRetries = 1; 04414 04415 macHdr.Bits.MType = FRAME_TYPE_DATA_UNCONFIRMED_UP ; 04416 fPort = mcpsRequest->Req.Unconfirmed .fPort ; 04417 fBuffer = mcpsRequest->Req.Unconfirmed .fBuffer ; 04418 fBufferSize = mcpsRequest->Req.Unconfirmed .fBufferSize ; 04419 datarate = mcpsRequest->Req.Unconfirmed .Datarate ; 04420 break; 04421 } 04422 case MCPS_CONFIRMED : 04423 { 04424 readyToSend = true; 04425 AckTimeoutRetriesCounter = 1; 04426 AckTimeoutRetries = mcpsRequest->Req.Confirmed .NbTrials ; 04427 04428 macHdr.Bits.MType = FRAME_TYPE_DATA_CONFIRMED_UP ; 04429 fPort = mcpsRequest->Req.Confirmed .fPort ; 04430 fBuffer = mcpsRequest->Req.Confirmed .fBuffer ; 04431 fBufferSize = mcpsRequest->Req.Confirmed .fBufferSize ; 04432 datarate = mcpsRequest->Req.Confirmed .Datarate ; 04433 break; 04434 } 04435 case MCPS_PROPRIETARY : 04436 { 04437 readyToSend = true; 04438 AckTimeoutRetries = 1; 04439 04440 macHdr.Bits.MType = FRAME_TYPE_PROPRIETARY ; 04441 fBuffer = mcpsRequest->Req.Proprietary .fBuffer ; 04442 fBufferSize = mcpsRequest->Req.Proprietary .fBufferSize ; 04443 datarate = mcpsRequest->Req.Proprietary .Datarate ; 04444 break; 04445 } 04446 default: 04447 break; 04448 } 04449 04450 if( readyToSend == true ) 04451 { 04452 if( AdrCtrlOn == false ) 04453 { 04454 if( ValueInRange( datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == true ) 04455 { 04456 LoRaMacParams.ChannelsDatarate = datarate; 04457 } 04458 else 04459 { 04460 return LORAMAC_STATUS_PARAMETER_INVALID ; 04461 } 04462 } 04463 04464 status = Send( &macHdr, fPort, fBuffer, fBufferSize ); 04465 if( status == LORAMAC_STATUS_OK ) 04466 { 04467 McpsConfirm.McpsRequest = mcpsRequest->Type ; 04468 LoRaMacFlags.Bits.McpsReq = 1; 04469 } 04470 else 04471 { 04472 NodeAckRequested = false; 04473 } 04474 } 04475 04476 return status; 04477 } 04478 04479 void LoRaMacTestRxWindowsOn( bool enable ) 04480 { 04481 IsRxWindowsEnabled = enable; 04482 } 04483 04484 void LoRaMacTestSetMic( uint16_t txPacketCounter ) 04485 { 04486 UpLinkCounter = txPacketCounter; 04487 IsUpLinkCounterFixed = true; 04488 } 04489 04490 void LoRaMacTestSetDutyCycleOn( bool enable ) 04491 { 04492 #if ( defined( USE_BAND_868 ) || defined( USE_BAND_433 ) || defined( USE_BAND_780 ) ) 04493 DutyCycleOn = enable; 04494 #else 04495 DutyCycleOn = false; 04496 #endif 04497 } 04498 04499 void LoRaMacTestSetChannel( uint8_t channel ) 04500 { 04501 Channel = channel; 04502 } 04503 04504 static RxConfigParams_t ComputeRxWindowParameters( int8_t datarate, uint32_t rxError ) 04505 { 04506 RxConfigParams_t rxConfigParams = { 0, 0, 0, 0 }; 04507 double tSymbol = 0.0; 04508 04509 rxConfigParams.Datarate = datarate; 04510 switch( Bandwidths[datarate] ) 04511 { 04512 default: 04513 case 125000: 04514 rxConfigParams.Bandwidth = 0; 04515 break; 04516 case 250000: 04517 rxConfigParams.Bandwidth = 1; 04518 break; 04519 case 500000: 04520 rxConfigParams.Bandwidth = 2; 04521 break; 04522 } 04523 04524 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 ) 04525 if( datarate == DR_7 ) 04526 { // FSK 04527 tSymbol = ( 1.0 / ( double )Datarates[datarate] ) * 8.0; // 1 symbol equals 1 byte 04528 } 04529 else 04530 #endif 04531 { // LoRa 04532 tSymbol = ( ( double )( 1 << Datarates[datarate] ) / ( double )Bandwidths[datarate] ) * 1e3; 04533 } 04534 04535 rxConfigParams.RxWindowTimeout = MAX( ( uint32_t )ceil( ( ( 2 * LoRaMacParams.MinRxSymbols - 8 ) * tSymbol + 2 * rxError ) / tSymbol ), LoRaMacParams.MinRxSymbols ); // Computed number of symbols 04536 04537 rxConfigParams.RxOffset = ( int32_t )ceil( ( 4.0 * tSymbol ) - ( ( rxConfigParams.RxWindowTimeout * tSymbol ) / 2.0 ) - RADIO_WAKEUP_TIME ); 04538 04539 return rxConfigParams; 04540 }
Generated on Thu Jul 14 2022 22:47:19 by
