20171208
Fork of LoRaWAN-lib by
Embed:
(wiki syntax)
Show/hide line numbers
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 Sun Jul 24 2022 08:02:16 by 1.7.2