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