Update LoRaMac-node to Version 4.4.4,fix Security breach found by Tencent Blade Team please refer to security advisory - CVE-2020-11068
fix Security breach found by Tencent Blade Team please refer to security advisory - CVE-2020-11068
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -36,6 +36,15 @@
|
||||
* layer and the supported features.
|
||||
* \{
|
||||
*
|
||||
* \example classA/B-L072Z-LRWAN1/main.c
|
||||
* LoRaWAN class A application example for the B-L072Z-LRWAN1.
|
||||
*
|
||||
* \example classB/B-L072Z-LRWAN1/main.c
|
||||
* LoRaWAN class B application example for the B-L072Z-LRWAN1.
|
||||
*
|
||||
* \example classC/B-L072Z-LRWAN1/main.c
|
||||
* LoRaWAN class C application example for the B-L072Z-LRWAN1.
|
||||
*
|
||||
* \example classA/NAMote72/main.c
|
||||
* LoRaWAN class A application example for the NAMote72.
|
||||
*
|
||||
@@ -63,10 +72,60 @@
|
||||
* \example classC/NucleoL152/main.c
|
||||
* LoRaWAN class C application example for the NucleoL152.
|
||||
*
|
||||
* \example classA/NucleoL476/main.c
|
||||
* LoRaWAN class A application example for the NucleoL476.
|
||||
*
|
||||
* \example classB/NucleoL476/main.c
|
||||
* LoRaWAN class B application example for the NucleoL476.
|
||||
*
|
||||
* \example classC/NucleoL476/main.c
|
||||
* LoRaWAN class C application example for the NucleoL476.
|
||||
*
|
||||
* \example classA/SAMR34/main.c
|
||||
* LoRaWAN class A application example for the SAMR34.
|
||||
*
|
||||
* \example classB/SAMR34/main.c
|
||||
* LoRaWAN class B application example for the SAMR34.
|
||||
*
|
||||
* \example classC/SAMR34/main.c
|
||||
* LoRaWAN class C application example for the SAMR34.
|
||||
*
|
||||
* \example classA/SKiM880B/main.c
|
||||
* LoRaWAN class A application example for the SKiM880B.
|
||||
*
|
||||
* \example classB/SKiM880B/main.c
|
||||
* LoRaWAN class B application example for the SKiM880B.
|
||||
*
|
||||
* \example classC/SKiM880B/main.c
|
||||
* LoRaWAN class C application example for the SKiM880B.
|
||||
*
|
||||
* \example classA/SKiM881AXL/main.c
|
||||
* LoRaWAN class A application example for the SKiM881AXL.
|
||||
*
|
||||
* \example classB/SKiM881AXL/main.c
|
||||
* LoRaWAN class B application example for the SKiM881AXL.
|
||||
*
|
||||
* \example classC/SKiM881AXL/main.c
|
||||
* LoRaWAN class C application example for the SKiM881AXL.
|
||||
*
|
||||
* \example classA/SKiM980A/main.c
|
||||
* LoRaWAN class A application example for the SKiM980A.
|
||||
*
|
||||
* \example classB/SKiM980A/main.c
|
||||
* LoRaWAN class B application example for the SKiM980A.
|
||||
*
|
||||
* \example classC/SKiM980A/main.c
|
||||
* LoRaWAN class C application example for the SKiM980A.
|
||||
*
|
||||
*/
|
||||
#ifndef __LORAMAC_H__
|
||||
#define __LORAMAC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "utilities.h"
|
||||
@@ -90,24 +149,11 @@
|
||||
*/
|
||||
#define DOWN_LINK 1
|
||||
|
||||
/*!
|
||||
* Sets the length of the LoRaMAC footer field.
|
||||
* Mainly indicates the MIC field length
|
||||
*/
|
||||
#define LORAMAC_MFR_LEN 4
|
||||
|
||||
/*!
|
||||
* LoRaMac MLME-Confirm queue length
|
||||
*/
|
||||
#define LORA_MAC_MLME_CONFIRM_QUEUE_LEN 5
|
||||
|
||||
/*!
|
||||
* FRMPayload overhead to be used when setting the Radio.SetMaxPayloadLength
|
||||
* in RxWindowSetup function.
|
||||
* Maximum PHYPayload = MaxPayloadOfDatarate/MaxPayloadOfDatarateRepeater + LORA_MAC_FRMPAYLOAD_OVERHEAD
|
||||
*/
|
||||
#define LORA_MAC_FRMPAYLOAD_OVERHEAD 13 // MHDR(1) + FHDR(7) + Port(1) + MIC(4)
|
||||
|
||||
/*!
|
||||
* Maximum number of multicast context
|
||||
*/
|
||||
@@ -116,34 +162,7 @@
|
||||
/*!
|
||||
* Start value for multicast keys enumeration
|
||||
*/
|
||||
#define LORAMAC_CRYPTO_MULITCAST_KEYS 127
|
||||
|
||||
/*!
|
||||
* LoRaWAN devices classes definition
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 2.1
|
||||
*/
|
||||
typedef enum eDeviceClass
|
||||
{
|
||||
/*!
|
||||
* LoRaWAN device class A
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 3
|
||||
*/
|
||||
CLASS_A = 0x00,
|
||||
/*!
|
||||
* LoRaWAN device class B
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 8
|
||||
*/
|
||||
CLASS_B = 0x01,
|
||||
/*!
|
||||
* LoRaWAN device class C
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 17
|
||||
*/
|
||||
CLASS_C = 0x02,
|
||||
}DeviceClass_t;
|
||||
#define LORAMAC_CRYPTO_MULTICAST_KEYS 127
|
||||
|
||||
/*!
|
||||
* End-Device activation type
|
||||
@@ -164,7 +183,6 @@ typedef enum eActivationType
|
||||
ACTIVATION_TYPE_OTAA = 2,
|
||||
}ActivationType_t;
|
||||
|
||||
|
||||
/*!
|
||||
* LoRaMAC channels parameters definition
|
||||
*/
|
||||
@@ -222,9 +240,9 @@ typedef struct sChannelParams
|
||||
}ChannelParams_t;
|
||||
|
||||
/*!
|
||||
* LoRaMAC receive window 2 channel parameters
|
||||
* LoRaMAC receive window channel parameters
|
||||
*/
|
||||
typedef struct sRx2ChannelParams
|
||||
typedef struct sRxChannelParams
|
||||
{
|
||||
/*!
|
||||
* Frequency in Hz
|
||||
@@ -238,7 +256,7 @@ typedef struct sRx2ChannelParams
|
||||
* The allowed ranges are region specific. Please refer to \ref DR_0 to \ref DR_15 for details.
|
||||
*/
|
||||
uint8_t Datarate;
|
||||
}Rx2ChannelParams_t;
|
||||
}RxChannelParams_t;
|
||||
|
||||
/*!
|
||||
* LoRaMAC receive window enumeration
|
||||
@@ -257,14 +275,22 @@ typedef enum eLoRaMacRxSlot
|
||||
* LoRaMAC receive window 2 for class c - continuous listening
|
||||
*/
|
||||
RX_SLOT_WIN_CLASS_C,
|
||||
/*!
|
||||
* LoRaMAC class c multicast downlink
|
||||
*/
|
||||
RX_SLOT_WIN_CLASS_C_MULTICAST,
|
||||
/*!
|
||||
* LoRaMAC class b ping slot window
|
||||
*/
|
||||
RX_SLOT_WIN_PING_SLOT,
|
||||
RX_SLOT_WIN_CLASS_B_PING_SLOT,
|
||||
/*!
|
||||
* LoRaMAC class b multicast slot window
|
||||
*/
|
||||
RX_SLOT_WIN_MULTICAST_SLOT,
|
||||
RX_SLOT_WIN_CLASS_B_MULTICAST_SLOT,
|
||||
/*!
|
||||
* LoRaMAC no active receive window
|
||||
*/
|
||||
RX_SLOT_NONE,
|
||||
}LoRaMacRxSlot_t;
|
||||
|
||||
/*!
|
||||
@@ -328,14 +354,6 @@ typedef struct sLoRaMacCtxs
|
||||
* \brief Size of MLME Confirm queue module context
|
||||
*/
|
||||
size_t ConfirmQueueNvmCtxSize;
|
||||
/*!
|
||||
* \brief Pointer to FCnt handler module context
|
||||
*/
|
||||
void* FCntHandlerNvmCtx;
|
||||
/*!
|
||||
* \brief Size of FCnt handler module context
|
||||
*/
|
||||
size_t FCntHandlerNvmCtxSize;
|
||||
}LoRaMacCtxs_t;
|
||||
|
||||
/*!
|
||||
@@ -393,7 +411,11 @@ typedef struct sLoRaMacParams
|
||||
/*!
|
||||
* LoRaMAC 2nd reception window settings
|
||||
*/
|
||||
Rx2ChannelParams_t Rx2Channel;
|
||||
RxChannelParams_t Rx2Channel;
|
||||
/*!
|
||||
* LoRaMAC continuous reception window settings
|
||||
*/
|
||||
RxChannelParams_t RxCChannel;
|
||||
/*!
|
||||
* Uplink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*/
|
||||
@@ -410,44 +432,8 @@ typedef struct sLoRaMacParams
|
||||
* Antenna gain of the node
|
||||
*/
|
||||
float AntennaGain;
|
||||
/*!
|
||||
* Indicates if the node supports repeaters
|
||||
*/
|
||||
bool RepeaterSupport;
|
||||
}LoRaMacParams_t;
|
||||
|
||||
/*!
|
||||
* Multicast channel
|
||||
*/
|
||||
typedef struct sMulticastChannel
|
||||
{
|
||||
/*
|
||||
* Address identifier
|
||||
*/
|
||||
AddressIdentifier_t AddrID;
|
||||
/*!
|
||||
* Address
|
||||
*/
|
||||
uint32_t Address;
|
||||
/*!
|
||||
* True if the entry is active
|
||||
*/
|
||||
bool IsEnabled;
|
||||
/*!
|
||||
* Reception frequency of the ping slot windows
|
||||
*/
|
||||
uint32_t Frequency;
|
||||
/*!
|
||||
* Datarate of the ping slot
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
* This parameter is necessary for class b operation. It defines the
|
||||
* periodicity of the multicast downlink slots
|
||||
*/
|
||||
uint16_t Periodicity;
|
||||
}MulticastChannel_t;
|
||||
|
||||
/*!
|
||||
* LoRaMAC data structure for a PingSlotInfoReq \ref MLME_PING_SLOT_INFO
|
||||
*
|
||||
@@ -487,7 +473,7 @@ typedef struct sBeaconInfo
|
||||
* Timestamp in seconds since 00:00:00, Sunday 6th of January 1980
|
||||
* (start of the GPS epoch) modulo 2^32
|
||||
*/
|
||||
uint32_t Time;
|
||||
SysTime_t Time;
|
||||
/*!
|
||||
* Frequency
|
||||
*/
|
||||
@@ -616,23 +602,27 @@ typedef union eLoRaMacFlags_t
|
||||
/*!
|
||||
* MCPS-Req pending
|
||||
*/
|
||||
uint8_t McpsReq : 1;
|
||||
uint8_t McpsReq : 1;
|
||||
/*!
|
||||
* MCPS-Ind pending
|
||||
*/
|
||||
uint8_t McpsInd : 1;
|
||||
uint8_t McpsInd : 1;
|
||||
/*!
|
||||
* MLME-Req pending
|
||||
*/
|
||||
uint8_t MlmeReq : 1;
|
||||
uint8_t MlmeReq : 1;
|
||||
/*!
|
||||
* MLME-Ind pending
|
||||
*/
|
||||
uint8_t MlmeInd : 1;
|
||||
uint8_t MlmeInd : 1;
|
||||
/*!
|
||||
* MLME-Ind to schedule an uplink pending
|
||||
*/
|
||||
uint8_t MlmeSchedUplinkInd : 1;
|
||||
/*!
|
||||
* MAC cycle done
|
||||
*/
|
||||
uint8_t MacDone : 1;
|
||||
uint8_t MacDone : 1;
|
||||
}Bits;
|
||||
}LoRaMacFlags_t;
|
||||
|
||||
@@ -679,6 +669,19 @@ typedef enum eMcps
|
||||
MCPS_PROPRIETARY,
|
||||
}Mcps_t;
|
||||
|
||||
/*!
|
||||
* Structure which defines return parameters for requests.
|
||||
*/
|
||||
typedef struct sRequestReturnParam
|
||||
{
|
||||
/*!
|
||||
* This value reports the time in milliseconds which
|
||||
* an application must wait before its possible to send
|
||||
* the next uplink.
|
||||
*/
|
||||
TimerTime_t DutyCycleWaitTime;
|
||||
}RequestReturnParam_t;
|
||||
|
||||
/*!
|
||||
* LoRaMAC MCPS-Request for an unconfirmed frame
|
||||
*/
|
||||
@@ -799,6 +802,11 @@ typedef struct sMcpsReq
|
||||
*/
|
||||
McpsReqProprietary_t Proprietary;
|
||||
}Req;
|
||||
|
||||
/*!
|
||||
* MCPS-Request return parameters
|
||||
*/
|
||||
RequestReturnParam_t ReqReturn;
|
||||
}McpsReq_t;
|
||||
|
||||
/*!
|
||||
@@ -909,6 +917,10 @@ typedef struct sMcpsIndication
|
||||
* The device address of the frame
|
||||
*/
|
||||
uint32_t DevAddress;
|
||||
/*!
|
||||
* Set if a DeviceTimeAns MAC command was received.
|
||||
*/
|
||||
bool DeviceTimeAnsReceived;
|
||||
}McpsIndication_t;
|
||||
|
||||
/*!
|
||||
@@ -937,6 +949,10 @@ typedef struct sMcpsIndication
|
||||
*/
|
||||
typedef enum eMlme
|
||||
{
|
||||
/*!
|
||||
* An unknown MLME service
|
||||
*/
|
||||
MLME_UNKNOWN,
|
||||
/*!
|
||||
* Initiates the Over-the-Air activation
|
||||
*
|
||||
@@ -1033,18 +1049,6 @@ typedef enum eMlme
|
||||
*/
|
||||
typedef struct sMlmeReqJoin
|
||||
{
|
||||
/*!
|
||||
* Globally unique end-device identifier
|
||||
*
|
||||
* LoRaWAN Specification V1.1.0, chapter 6.1.1.2
|
||||
*/
|
||||
uint8_t* DevEui;
|
||||
/*!
|
||||
* Join Sever identifier
|
||||
*
|
||||
* LoRaWAN Specification V1.1.0, chapter 6.1.1.1
|
||||
*/
|
||||
uint8_t* JoinEui;
|
||||
/*!
|
||||
* Datarate used for join request.
|
||||
*/
|
||||
@@ -1105,7 +1109,7 @@ typedef struct sMlmeReqDeriveMcSessionKeyPair
|
||||
/*!
|
||||
* Address identifier to select the multicast group
|
||||
*/
|
||||
AddressIdentifier_t AddrID;
|
||||
AddressIdentifier_t GroupID;
|
||||
}MlmeReqDeriveMcSessionKeyPair_t;
|
||||
|
||||
/*!
|
||||
@@ -1144,6 +1148,11 @@ typedef struct sMlmeReq
|
||||
*/
|
||||
MlmeReqDeriveMcSessionKeyPair_t DeriveMcSessionKeyPair;
|
||||
}Req;
|
||||
|
||||
/*!
|
||||
* MLME-Request return parameters
|
||||
*/
|
||||
RequestReturnParam_t ReqReturn;
|
||||
}MlmeReq_t;
|
||||
|
||||
/*!
|
||||
@@ -1216,6 +1225,9 @@ typedef struct sMlmeIndication
|
||||
* ----------------------------------------------| :-: | :-:
|
||||
* \ref MIB_DEVICE_CLASS | YES | YES
|
||||
* \ref MIB_NETWORK_ACTIVATION | YES | YES
|
||||
* \ref MIB_DEV_EUI | YES | YES
|
||||
* \ref MIB_JOIN_EUI | YES | YES
|
||||
* \ref MIB_SE_PIN | YES | YES
|
||||
* \ref MIB_ADR | YES | YES
|
||||
* \ref MIB_NET_ID | YES | YES
|
||||
* \ref MIB_DEV_ADDR | YES | YES
|
||||
@@ -1241,9 +1253,11 @@ typedef struct sMlmeIndication
|
||||
* \ref MIB_MC_APP_S_KEY_3 | NO | YES
|
||||
* \ref MIB_MC_NWK_S_KEY_3 | NO | YES
|
||||
* \ref MIB_PUBLIC_NETWORK | YES | YES
|
||||
* \ref MIB_REPEATER_SUPPORT | YES | YES
|
||||
* \ref MIB_CHANNELS | YES | NO
|
||||
* \ref MIB_RX2_CHANNEL | YES | YES
|
||||
* \ref MIB_RX2_DFAULT_CHANNEL | YES | YES
|
||||
* \ref MIB_RXC_CHANNEL | YES | YES
|
||||
* \ref MIB_RXC_DFAULT_CHANNEL | YES | YES
|
||||
* \ref MIB_CHANNELS_MASK | YES | YES
|
||||
* \ref MIB_CHANNELS_DEFAULT_MASK | YES | YES
|
||||
* \ref MIB_CHANNELS_NB_TRANS | YES | YES
|
||||
@@ -1273,7 +1287,8 @@ typedef struct sMlmeIndication
|
||||
* \ref MIB_ANTENNA_GAIN | YES | YES
|
||||
* \ref MIB_DEFAULT_ANTENNA_GAIN | YES | YES
|
||||
* \ref MIB_NVM_CTXS | YES | YES
|
||||
* \ref MIB_ABP_LORAWAN_VERSION | YES | YES
|
||||
* \ref MIB_ABP_LORAWAN_VERSION | NO | YES
|
||||
* \ref MIB_LORAWAN_VERSION | YES | NO
|
||||
*
|
||||
* The following table provides links to the function implementations of the
|
||||
* related MIB primitives:
|
||||
@@ -1297,6 +1312,22 @@ typedef enum eMib
|
||||
* LoRaWAN Specification V1.0.2
|
||||
*/
|
||||
MIB_NETWORK_ACTIVATION,
|
||||
/*!
|
||||
* LoRaWAN device EUI
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2
|
||||
*/
|
||||
MIB_DEV_EUI,
|
||||
/*!
|
||||
* LoRaWAN join EUI
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2
|
||||
*/
|
||||
MIB_JOIN_EUI,
|
||||
/*!
|
||||
* Secure-element pin
|
||||
*/
|
||||
MIB_SE_PIN,
|
||||
/*!
|
||||
* Adaptive data rate
|
||||
*
|
||||
@@ -1451,14 +1482,6 @@ typedef enum eMib
|
||||
* [true: public network, false: private network]
|
||||
*/
|
||||
MIB_PUBLIC_NETWORK,
|
||||
/*!
|
||||
* Support the operation with repeaters
|
||||
*
|
||||
* LoRaWAN Regional Parameters V1.0.2rB
|
||||
*
|
||||
* [true: repeater support enabled, false: repeater support disabled]
|
||||
*/
|
||||
MIB_REPEATER_SUPPORT,
|
||||
/*!
|
||||
* Communication channels. A get request will return a
|
||||
* pointer which references the first entry of the channel list. The
|
||||
@@ -1479,6 +1502,18 @@ typedef enum eMib
|
||||
* LoRaWAN Specification V1.0.2, chapter 3.3.2
|
||||
*/
|
||||
MIB_RX2_DEFAULT_CHANNEL,
|
||||
/*!
|
||||
* Set receive window C channel
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 3.3.1
|
||||
*/
|
||||
MIB_RXC_CHANNEL,
|
||||
/*!
|
||||
* Set receive window C channel
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 3.3.2
|
||||
*/
|
||||
MIB_RXC_DEFAULT_CHANNEL,
|
||||
/*!
|
||||
* LoRaWAN channels mask
|
||||
*
|
||||
@@ -1575,7 +1610,7 @@ typedef enum eMib
|
||||
* The antenna gain is used to calculate the TX power of the node.
|
||||
* The formula is:
|
||||
* radioTxPower = ( int8_t )floor( maxEirp - antennaGain )
|
||||
*
|
||||
*
|
||||
* \remark The antenna gain value is referenced to the isotropic antenna.
|
||||
* The value is in dBi.
|
||||
* MIB_ANTENNA_GAIN[dBi] = measuredAntennaGain[dBd] + 2.15
|
||||
@@ -1586,7 +1621,7 @@ typedef enum eMib
|
||||
* The antenna gain is used to calculate the TX power of the node.
|
||||
* The formula is:
|
||||
* radioTxPower = ( int8_t )floor( maxEirp - antennaGain )
|
||||
*
|
||||
*
|
||||
* \remark The antenna gain value is referenced to the isotropic antenna.
|
||||
* The value is in dBi.
|
||||
* MIB_DEFAULT_ANTENNA_GAIN[dBi] = measuredAntennaGain[dBd] + 2.15
|
||||
@@ -1600,6 +1635,10 @@ typedef enum eMib
|
||||
* LoRaWAN MAC layer operating version when activated by ABP.
|
||||
*/
|
||||
MIB_ABP_LORAWAN_VERSION,
|
||||
/*!
|
||||
* LoRaWAN MAC and regional parameter version.
|
||||
*/
|
||||
MIB_LORAWAN_VERSION,
|
||||
/*!
|
||||
* Beacon interval in ms
|
||||
*/
|
||||
@@ -1677,6 +1716,24 @@ typedef union uMibParam
|
||||
* Related MIB type: \ref MIB_NETWORK_ACTIVATION
|
||||
*/
|
||||
ActivationType_t NetworkActivation;
|
||||
/*!
|
||||
* LoRaWAN device EUI
|
||||
*
|
||||
* Related MIB type: \ref MIB_DEV_EUI
|
||||
*/
|
||||
uint8_t* DevEui;
|
||||
/*!
|
||||
* LoRaWAN Join server EUI
|
||||
*
|
||||
* Related MIB type: \ref MIB_JOIN_EUI
|
||||
*/
|
||||
uint8_t* JoinEui;
|
||||
/*!
|
||||
* Secure-element pin
|
||||
*
|
||||
* Related MIB type: \ref MIB_SE_PIN
|
||||
*/
|
||||
uint8_t* SePin;
|
||||
/*!
|
||||
* Activation state of ADR
|
||||
*
|
||||
@@ -1827,12 +1884,6 @@ typedef union uMibParam
|
||||
* Related MIB type: \ref MIB_PUBLIC_NETWORK
|
||||
*/
|
||||
bool EnablePublicNetwork;
|
||||
/*!
|
||||
* Enable or disable repeater support
|
||||
*
|
||||
* Related MIB type: \ref MIB_REPEATER_SUPPORT
|
||||
*/
|
||||
bool EnableRepeaterSupport;
|
||||
/*!
|
||||
* LoRaWAN Channel
|
||||
*
|
||||
@@ -1844,13 +1895,25 @@ typedef union uMibParam
|
||||
*
|
||||
* Related MIB type: \ref MIB_RX2_CHANNEL
|
||||
*/
|
||||
Rx2ChannelParams_t Rx2Channel;
|
||||
RxChannelParams_t Rx2Channel;
|
||||
/*!
|
||||
* Channel for the receive window 2
|
||||
*
|
||||
* Related MIB type: \ref MIB_RX2_DEFAULT_CHANNEL
|
||||
*/
|
||||
Rx2ChannelParams_t Rx2DefaultChannel;
|
||||
RxChannelParams_t Rx2DefaultChannel;
|
||||
/*!
|
||||
* Channel for the receive window C
|
||||
*
|
||||
* Related MIB type: \ref MIB_RXC_CHANNEL
|
||||
*/
|
||||
RxChannelParams_t RxCChannel;
|
||||
/*!
|
||||
* Channel for the receive window C
|
||||
*
|
||||
* Related MIB type: \ref MIB_RXC_DEFAULT_CHANNEL
|
||||
*/
|
||||
RxChannelParams_t RxCDefaultChannel;
|
||||
/*!
|
||||
* Channel mask
|
||||
*
|
||||
@@ -1928,7 +1991,7 @@ typedef union uMibParam
|
||||
*
|
||||
* Related MIB type: \ref MIB_MULTICAST_CHANNEL
|
||||
*/
|
||||
MulticastChannel_t MulticastChannel;
|
||||
McChannelParams_t MulticastChannel;
|
||||
/*!
|
||||
* System overall timing error in milliseconds.
|
||||
*
|
||||
@@ -1965,6 +2028,16 @@ typedef union uMibParam
|
||||
* Related MIB type: \ref MIB_ABP_LORAWAN_VERSION
|
||||
*/
|
||||
Version_t AbpLrWanVersion;
|
||||
/*
|
||||
* LoRaWAN MAC regional parameter version.
|
||||
*
|
||||
* Related MIB type: \ref MIB_LORAWAN_VERSION
|
||||
*/
|
||||
struct sLrWanVersion
|
||||
{
|
||||
Version_t LoRaWan;
|
||||
Version_t LoRaWanRegion;
|
||||
}LrWanVersion;
|
||||
/*!
|
||||
* Beacon interval in ms
|
||||
*
|
||||
@@ -2131,7 +2204,17 @@ typedef enum eLoRaMacStatus
|
||||
*/
|
||||
LORAMAC_STATUS_SKIPPED_APP_DATA,
|
||||
/*!
|
||||
* ToDo
|
||||
* An MCPS or MLME request can return this status. In this case,
|
||||
* the MAC cannot send the frame, as the duty cycle limits all
|
||||
* available bands. When a request returns this value, the
|
||||
* variable "DutyCycleWaitTime" in "ReqReturn" of the input
|
||||
* parameters contains the remaining time to wait. If the
|
||||
* value is constant and does not change, the expected time
|
||||
* on air for this frame is exceeding the maximum permitted
|
||||
* time according to the duty cycle time period, defined
|
||||
* in Region.h, DUTY_CYCLE_TIME_PERIOD. By default this time
|
||||
* is 1 hour, and a band with 1% duty cycle is then allowed
|
||||
* to use an air time of 36 seconds.
|
||||
*/
|
||||
LORAMAC_STATUS_DUTYCYCLE_RESTRICTED,
|
||||
/*!
|
||||
@@ -2175,7 +2258,11 @@ typedef enum eLoRaMacStatus
|
||||
*/
|
||||
LORAMAC_STATUS_CONFIRM_QUEUE_ERROR,
|
||||
/*!
|
||||
* Undefined error occured
|
||||
* The multicast group doesn't exist
|
||||
*/
|
||||
LORAMAC_STATUS_MC_GROUP_UNDEFINED,
|
||||
/*!
|
||||
* Undefined error occurred
|
||||
*/
|
||||
LORAMAC_STATUS_ERROR
|
||||
}LoRaMacStatus_t;
|
||||
@@ -2260,10 +2347,6 @@ typedef enum LoRaMacNvmCtxModule_e
|
||||
* Context for the confirm queue
|
||||
*/
|
||||
LORAMAC_NVMCTXMODULE_CONFIRM_QUEUE,
|
||||
/*!
|
||||
* Context for the frame count handler
|
||||
*/
|
||||
LORAMAC_NVMCTXMODULE_FCNT_HANDLER
|
||||
}LoRaMacNvmCtxModule_t;
|
||||
|
||||
|
||||
@@ -2328,7 +2411,7 @@ typedef struct sLoRaMacCallback
|
||||
/*!
|
||||
*\brief Will be called each time a Radio IRQ is handled by the MAC
|
||||
* layer.
|
||||
*
|
||||
*
|
||||
*\warning Runs in a IRQ context. Should only change variables state.
|
||||
*/
|
||||
void ( *MacProcessNotify )( void );
|
||||
@@ -2382,6 +2465,13 @@ LoRaMacStatus_t LoRaMacStart( void );
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacStop( void );
|
||||
|
||||
/*!
|
||||
* \brief Returns a value indicating if the MAC layer is busy or not.
|
||||
*
|
||||
* \retval isBusy Mac layer is busy.
|
||||
*/
|
||||
bool LoRaMacIsBusy( void );
|
||||
|
||||
/*!
|
||||
* Processes the LoRaMac events.
|
||||
*
|
||||
@@ -2449,18 +2539,60 @@ LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params );
|
||||
LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id );
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC multicast channel setting service
|
||||
* \brief LoRaMAC multicast channel setup service
|
||||
*
|
||||
* \details Sets a multicast channel.
|
||||
* \details Sets up a multicast channel.
|
||||
*
|
||||
* \param [IN] channel - Multicast channel to set.
|
||||
*
|
||||
* \retval LoRaMacStatus_t Status of the operation. Possible returns are:
|
||||
* \ref LORAMAC_STATUS_OK,
|
||||
* \ref LORAMAC_STATUS_BUSY,
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID.
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID,
|
||||
* \ref LORAMAC_STATUS_MC_GROUP_UNDEFINED.
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacMulticastChannelSet( MulticastChannel_t channel );
|
||||
LoRaMacStatus_t LoRaMacMcChannelSetup( McChannelParams_t *channel );
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC multicast channel removal service
|
||||
*
|
||||
* \details Removes/Disables a multicast channel.
|
||||
*
|
||||
* \param [IN] groupID - Multicast channel ID to be removed/disabled
|
||||
*
|
||||
* \retval LoRaMacStatus_t Status of the operation. Possible returns are:
|
||||
* \ref LORAMAC_STATUS_OK,
|
||||
* \ref LORAMAC_STATUS_BUSY,
|
||||
* \ref LORAMAC_STATUS_MC_GROUP_UNDEFINED.
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacMcChannelDelete( AddressIdentifier_t groupID );
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC multicast channel get groupId from MC address.
|
||||
*
|
||||
* \param [IN] mcAddress - Multicast address to be checked
|
||||
*
|
||||
* \retval groupID Multicast channel ID associated to the address.
|
||||
* Returns 0xFF if the address isn't found.
|
||||
*/
|
||||
uint8_t LoRaMacMcChannelGetGroupId( uint32_t mcAddress );
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC multicast channel Rx parameters setup service
|
||||
*
|
||||
* \details Sets up a multicast channel reception parameters.
|
||||
*
|
||||
* \param [IN] groupID - Multicast channel ID
|
||||
* \param [IN] rxParams - Reception parameters
|
||||
* \param [OUT] status - Status mask [UNDEF_ID | FREQ_ERR | DR_ERR | GROUP_ID]
|
||||
*
|
||||
* \retval LoRaMacStatus_t Status of the operation. Possible returns are:
|
||||
* \ref LORAMAC_STATUS_OK,
|
||||
* \ref LORAMAC_STATUS_BUSY,
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID,
|
||||
* \ref LORAMAC_STATUS_MC_GROUP_UNDEFINED.
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacMcChannelSetupRxParams( AddressIdentifier_t groupID, McRxParams_t *rxParams, uint8_t *status );
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC MIB-Get
|
||||
@@ -2526,32 +2658,15 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet );
|
||||
*
|
||||
* \details The Mac layer management entity handles management services. The
|
||||
* following code-snippet shows how to use the API to perform a
|
||||
* network join request.
|
||||
* network join request. Please note that for a join request, the
|
||||
* DevEUI and the JoinEUI must be set previously via the MIB. Please
|
||||
* also refer to the sample implementations.
|
||||
*
|
||||
* \code
|
||||
* static uint8_t DevEui[] =
|
||||
* {
|
||||
* 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
* };
|
||||
* static uint8_t JoinEui[] =
|
||||
* {
|
||||
* 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
* };
|
||||
* static uint8_t NwkKey[] =
|
||||
* {
|
||||
* 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
|
||||
* 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
|
||||
* };
|
||||
* static uint8_t AppKey[] =
|
||||
* {
|
||||
* 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
|
||||
* 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
|
||||
* };
|
||||
*
|
||||
* MlmeReq_t mlmeReq;
|
||||
* mlmeReq.Type = MLME_JOIN;
|
||||
* mlmeReq.Req.Join.DevEui = DevEui;
|
||||
* mlmeReq.Req.Join.JoinEui = JoinEui;
|
||||
* mlmeReq.Req.Join.Datarate = LORAWAN_DEFAULT_DATARATE;
|
||||
*
|
||||
* if( LoRaMacMlmeRequest( &mlmeReq ) == LORAMAC_STATUS_OK )
|
||||
* {
|
||||
@@ -2605,6 +2720,18 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest );
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t* mcpsRequest );
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC deinitialization
|
||||
*
|
||||
* \details This function stops the timers, re-initializes MAC & regional parameters to default
|
||||
* and sets radio into sleep state.
|
||||
*
|
||||
* \retval LoRaMacStatus_t Status of the operation. Possible returns are:
|
||||
* \ref LORAMAC_STATUS_OK,
|
||||
* \ref LORAMAC_STATUS_BUSY
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacDeInitialization( void );
|
||||
|
||||
/*!
|
||||
* Automatically add the Region.h file at the end of LoRaMac.h file.
|
||||
* This is required because Region.h uses definitions from LoRaMac.h
|
||||
@@ -2613,4 +2740,8 @@ LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t* mcpsRequest );
|
||||
|
||||
/*! \} defgroup LORAMAC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LORAMAC_H__
|
||||
|
@@ -65,10 +65,6 @@ static bool CalcNextV10X( CalcNextAdrParams_t* adrNext, int8_t* drOut, int8_t* t
|
||||
if( adrNext->AdrAckCounter >= adrNext->AdrAckLimit )
|
||||
{
|
||||
adrAckReq = true;
|
||||
// Set TX Power to maximum
|
||||
getPhy.Attribute = PHY_MAX_TX_POWER;
|
||||
phyParam = RegionGetPhyParam( adrNext->Region, &getPhy );
|
||||
txPower = phyParam.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -76,6 +72,11 @@ static bool CalcNextV10X( CalcNextAdrParams_t* adrNext, int8_t* drOut, int8_t* t
|
||||
}
|
||||
if( adrNext->AdrAckCounter >= ( adrNext->AdrAckLimit + adrNext->AdrAckDelay ) )
|
||||
{
|
||||
// Set TX Power to maximum
|
||||
getPhy.Attribute = PHY_MAX_TX_POWER;
|
||||
phyParam = RegionGetPhyParam( adrNext->Region, &getPhy );
|
||||
txPower = phyParam.Value;
|
||||
|
||||
if( ( adrNext->AdrAckCounter % adrNext->AdrAckDelay ) == 1 )
|
||||
{
|
||||
// Decrease the datarate
|
||||
|
@@ -37,6 +37,11 @@
|
||||
#ifndef __LORAMACADR_H__
|
||||
#define __LORAMACADR_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*! \} defgroup LORAMACADR */
|
||||
|
||||
/*
|
||||
@@ -101,4 +106,8 @@ typedef struct sCalcNextAdrParams
|
||||
*/
|
||||
bool LoRaMacAdrCalcNext( CalcNextAdrParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LORAMACADR_H__
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,11 @@
|
||||
#ifndef __LORAMACCLASSB_H__
|
||||
#define __LORAMACCLASSB_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "systime.h"
|
||||
#include "LoRaMacTypes.h"
|
||||
|
||||
@@ -121,42 +126,15 @@ typedef enum ePingSlotState
|
||||
*/
|
||||
typedef struct sPingSlotContext
|
||||
{
|
||||
struct sPingSlotCtrl
|
||||
{
|
||||
/*!
|
||||
* Set when the server assigned a ping slot to the node
|
||||
*/
|
||||
uint8_t Assigned : 1;
|
||||
/*!
|
||||
* Set when a custom frequency is used
|
||||
*/
|
||||
uint8_t CustomFreq : 1;
|
||||
}Ctrl;
|
||||
|
||||
/*!
|
||||
* Ping slot length time in ms
|
||||
*/
|
||||
uint32_t PingSlotWindow;
|
||||
/*!
|
||||
* Number of ping slots
|
||||
*/
|
||||
uint8_t PingNb;
|
||||
/*!
|
||||
* Period of the ping slots
|
||||
*/
|
||||
uint16_t PingPeriod;
|
||||
/*!
|
||||
* Ping offset
|
||||
*/
|
||||
uint16_t PingOffset;
|
||||
/*!
|
||||
* Reception frequency of the ping slot windows
|
||||
*/
|
||||
uint32_t Frequency;
|
||||
/*!
|
||||
* Datarate of the ping slot
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
* Current symbol timeout. The node enlarges this variable in case of beacon
|
||||
* loss.
|
||||
@@ -184,10 +162,6 @@ typedef struct sBeaconContext
|
||||
* Set if the node has acquired the beacon
|
||||
*/
|
||||
uint8_t BeaconAcquired : 1;
|
||||
/*!
|
||||
* Set if the node has a custom frequency for beaconing and ping slots
|
||||
*/
|
||||
uint8_t CustomFreq : 1;
|
||||
/*!
|
||||
* Set if a beacon delay was set for the beacon acquisition
|
||||
*/
|
||||
@@ -205,10 +179,7 @@ typedef struct sBeaconContext
|
||||
*/
|
||||
uint8_t ResumeBeaconing : 1;
|
||||
}Ctrl;
|
||||
/*!
|
||||
* Beacon reception frequency
|
||||
*/
|
||||
uint32_t Frequency;
|
||||
|
||||
/*!
|
||||
* Current temperature
|
||||
*/
|
||||
@@ -216,15 +187,15 @@ typedef struct sBeaconContext
|
||||
/*!
|
||||
* Beacon time received with the beacon frame
|
||||
*/
|
||||
TimerTime_t BeaconTime;
|
||||
SysTime_t BeaconTime;
|
||||
/*!
|
||||
* Time when the last beacon was received
|
||||
*/
|
||||
TimerTime_t LastBeaconRx;
|
||||
SysTime_t LastBeaconRx;
|
||||
/*!
|
||||
* Time when the next beacon will be received
|
||||
*/
|
||||
TimerTime_t NextBeaconRx;
|
||||
SysTime_t NextBeaconRx;
|
||||
/*!
|
||||
* This is the time where the RX window will be opened.
|
||||
* Its base is NextBeaconRx with temperature compensations
|
||||
@@ -265,7 +236,7 @@ typedef struct sLoRaMacClassBCallback
|
||||
/*!
|
||||
*\brief Will be called each time a Radio IRQ is handled by the MAC
|
||||
* layer.
|
||||
*
|
||||
*
|
||||
*\warning Runs in a IRQ context. Should only change variables state.
|
||||
*/
|
||||
void ( *MacProcessNotify )( void );
|
||||
@@ -314,7 +285,7 @@ typedef struct sLoRaMacClassBParams
|
||||
* Signature of callback function to be called by this module when the
|
||||
* non-volatile needs to be saved.
|
||||
*/
|
||||
typedef void ( *EventNvmCtxChanged )( void );
|
||||
typedef void ( *LoRaMacClassBNvmEvent )( void );
|
||||
|
||||
/*!
|
||||
* \brief Initialize LoRaWAN Class B
|
||||
@@ -323,7 +294,7 @@ typedef void ( *EventNvmCtxChanged )( void );
|
||||
* \param [IN] callbacks Contains the callback which the Class B implementation needs
|
||||
* \param [IN] callback function which will be called when the non-volatile context needs to be saved.
|
||||
*/
|
||||
void LoRaMacClassBInit( LoRaMacClassBParams_t *classBParams, LoRaMacClassBCallback_t *callbacks, EventNvmCtxChanged classBNvmCtxChanged );
|
||||
void LoRaMacClassBInit( LoRaMacClassBParams_t *classBParams, LoRaMacClassBCallback_t *callbacks, LoRaMacClassBNvmEvent classBNvmCtxChanged );
|
||||
|
||||
/*!
|
||||
* Restores the internal non-volatile context from passed pointer.
|
||||
@@ -561,4 +532,8 @@ void LoRaMacClassBSetMulticastPeriodicity( MulticastCtx_t* multicastChannel );
|
||||
|
||||
void LoRaMacClassBProcess( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LORAMACCLASSB_H__
|
||||
|
@@ -36,6 +36,11 @@
|
||||
#ifndef __LORAMACCLASSBCONFIG_H__
|
||||
#define __LORAMACCLASSBCONFIG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Defines the beacon interval in ms
|
||||
*/
|
||||
@@ -112,4 +117,8 @@
|
||||
*/
|
||||
#define CLASSB_WINDOW_MOVE_EXPANSION_FACTOR 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LORAMACCLASSBCONFIG_H__
|
||||
|
@@ -17,27 +17,23 @@ License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Daniel Jaeckle ( STACKFORCE ), Johannes Bruder ( STACKFORCE )
|
||||
*/
|
||||
#include <stddef.h>
|
||||
|
||||
#include "utilities.h"
|
||||
#include "LoRaMacCommands.h"
|
||||
#include "LoRaMacConfirmQueue.h"
|
||||
|
||||
/*
|
||||
/*!
|
||||
* Number of MAC Command slots
|
||||
*/
|
||||
#define NUM_OF_MAC_COMMANDS 15
|
||||
|
||||
/*
|
||||
/*!
|
||||
* Size of the CID field of MAC commands
|
||||
*/
|
||||
#define CID_FIELD_SIZE 1
|
||||
#define CID_FIELD_SIZE 1
|
||||
|
||||
/*
|
||||
* List of all stick MAC command answers which will be deleted after a receiving downlink
|
||||
*/
|
||||
const uint8_t CIDsStickyAnsCmds[] = { MOTE_MAC_DL_CHANNEL_ANS, MOTE_MAC_RX_PARAM_SETUP_ANS, MOTE_MAC_RX_TIMING_SETUP_ANS };
|
||||
|
||||
/*
|
||||
/*!
|
||||
* Mac Commands list structure
|
||||
*/
|
||||
typedef struct sMacCommandsList
|
||||
@@ -52,7 +48,7 @@ typedef struct sMacCommandsList
|
||||
MacCommand_t* Last;
|
||||
} MacCommandsList_t;
|
||||
|
||||
/*
|
||||
/*!
|
||||
* LoRaMac Commands Context structure
|
||||
*/
|
||||
typedef struct sLoRaMacCommandsCtx
|
||||
@@ -71,27 +67,27 @@ typedef struct sLoRaMacCommandsCtx
|
||||
size_t SerializedCmdsSize;
|
||||
} LoRaMacCommandsCtx_t;
|
||||
|
||||
/*
|
||||
/*!
|
||||
* Callback function to notify the upper layer about context change
|
||||
*/
|
||||
static EventNvmCtxChanged CommandsNvmCtxChanged;
|
||||
static LoRaMacCommandsNvmEvent CommandsNvmCtxChanged;
|
||||
|
||||
/*
|
||||
/*!
|
||||
* Non-volatile module context.
|
||||
*/
|
||||
static LoRaMacCommandsCtx_t NvmCtx;
|
||||
|
||||
/* Memory management functions */
|
||||
|
||||
/*
|
||||
/*!
|
||||
* \brief Determines if a MAC command slot is free
|
||||
*
|
||||
* \param[IN] slot - Slot to check
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
bool isSlotFree( const MacCommand_t* slot )
|
||||
static bool IsSlotFree( const MacCommand_t* slot )
|
||||
{
|
||||
uint8_t* mem = (uint8_t*) slot;
|
||||
uint8_t* mem = ( uint8_t* )slot;
|
||||
|
||||
for( uint16_t size = 0; size < sizeof( MacCommand_t ); size++ )
|
||||
{
|
||||
@@ -103,114 +99,112 @@ bool isSlotFree( const MacCommand_t* slot )
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
/*!
|
||||
* \brief Allocates a new MAC command memory slot
|
||||
*
|
||||
* \retval - Pointer to slot
|
||||
*/
|
||||
MacCommand_t* mallocNewMacCommandSlot( )
|
||||
static MacCommand_t* MallocNewMacCommandSlot( void )
|
||||
{
|
||||
uint8_t itr = 0;
|
||||
|
||||
while( isSlotFree( ( const MacCommand_t* ) &NvmCtx.MacCommandSlots[itr]) == false )
|
||||
while( IsSlotFree( ( const MacCommand_t* )&NvmCtx.MacCommandSlots[itr] ) == false )
|
||||
{
|
||||
itr++;
|
||||
if( itr == NUM_OF_MAC_COMMANDS )
|
||||
{
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return &NvmCtx.MacCommandSlots[itr];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/*!
|
||||
* \brief Free memory slot
|
||||
*
|
||||
* \param[IN] slot - Slot to free
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
bool freeMacCommandSlot( MacCommand_t* slot )
|
||||
static bool FreeMacCommandSlot( MacCommand_t* slot )
|
||||
{
|
||||
if( slot == 0 )
|
||||
if( slot == NULL )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
memset1( (uint8_t*) slot, 0x00, sizeof( MacCommand_t ));
|
||||
memset1( ( uint8_t* )slot, 0x00, sizeof( MacCommand_t ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Linked list functions */
|
||||
|
||||
/*
|
||||
/*!
|
||||
* \brief Initialize list
|
||||
*
|
||||
* \param[IN] list - List that shall be initialized
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
static bool linkedListInit( MacCommandsList_t* list )
|
||||
static bool LinkedListInit( MacCommandsList_t* list )
|
||||
{
|
||||
if( list == 0 )
|
||||
if( list == NULL )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
list->First = 0;
|
||||
list->Last = 0;
|
||||
list->First = NULL;
|
||||
list->Last = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
/*!
|
||||
* \brief Add an element to the list
|
||||
*
|
||||
* \param[IN] list - List where the element shall be added.
|
||||
* \param[IN] element - Element to add
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
static bool linkedListAdd( MacCommandsList_t* list, MacCommand_t* element )
|
||||
static bool LinkedListAdd( MacCommandsList_t* list, MacCommand_t* element )
|
||||
{
|
||||
if( ( list == 0 ) && ( element == 0 ) )
|
||||
if( ( list == NULL ) || ( element == NULL ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check if this is the first entry to enter the list. */
|
||||
if( list->First == 0 )
|
||||
// Check if this is the first entry to enter the list.
|
||||
if( list->First == NULL )
|
||||
{
|
||||
list->First = element;
|
||||
}
|
||||
|
||||
/* Check if the last entry exists and update its next point. */
|
||||
// Check if the last entry exists and update its next point.
|
||||
if( list->Last )
|
||||
{
|
||||
list->Last->Next = element;
|
||||
}
|
||||
|
||||
/* Update the next point of this entry. */
|
||||
element->Next = 0;
|
||||
// Update the next point of this entry.
|
||||
element->Next = NULL;
|
||||
|
||||
/* Update the last entry of the list. */
|
||||
// Update the last entry of the list.
|
||||
list->Last = element;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
/*!
|
||||
* \brief Return the previous element in the list.
|
||||
*
|
||||
* \param[IN] list - List
|
||||
* \param[IN] element - Element where the previous element shall be searched
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
static MacCommand_t* linkedListGetPrevious( MacCommandsList_t* list, MacCommand_t* element )
|
||||
static MacCommand_t* LinkedListGetPrevious( MacCommandsList_t* list, MacCommand_t* element )
|
||||
{
|
||||
if( ( list == 0 ) && ( element == 0 ) )
|
||||
if( ( list == NULL ) || ( element == NULL ) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -220,14 +214,11 @@ static MacCommand_t* linkedListGetPrevious( MacCommandsList_t* list, MacCommand_
|
||||
// Start at the head of the list
|
||||
curElement = list->First;
|
||||
|
||||
/*
|
||||
* When current element is the first of the list, there's no previous element so we can return NULL immediately.
|
||||
*/
|
||||
if( element != curElement)
|
||||
// When current element is the first of the list, there's no previous element so we can return NULL immediately.
|
||||
if( element != curElement )
|
||||
{
|
||||
|
||||
// Loop through all elements until the end is reached or the next of current is the current element.
|
||||
while(curElement && (curElement->Next != element))
|
||||
while( ( curElement != NULL ) && ( curElement->Next != element ) )
|
||||
{
|
||||
curElement = curElement->Next;
|
||||
}
|
||||
@@ -240,21 +231,21 @@ static MacCommand_t* linkedListGetPrevious( MacCommandsList_t* list, MacCommand_
|
||||
return curElement;
|
||||
}
|
||||
|
||||
/*
|
||||
/*!
|
||||
* \brief Remove an element from the list
|
||||
*
|
||||
* \param[IN] list - List where the element shall be removed from.
|
||||
* \param[IN] element - Element to remove
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
static bool linkedListRemove( MacCommandsList_t* list, MacCommand_t* element )
|
||||
static bool LinkedListRemove( MacCommandsList_t* list, MacCommand_t* element )
|
||||
{
|
||||
if( ( list == 0 ) && ( element == 0 ) )
|
||||
if( ( list == NULL ) || ( element == NULL ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MacCommand_t* PrevElement = linkedListGetPrevious( list, element );
|
||||
MacCommand_t* PrevElement = LinkedListGetPrevious( list, element );
|
||||
|
||||
if( list->First == element )
|
||||
{
|
||||
@@ -266,12 +257,12 @@ static bool linkedListRemove( MacCommandsList_t* list, MacCommand_t* element )
|
||||
list->Last = PrevElement;
|
||||
}
|
||||
|
||||
if( PrevElement )
|
||||
if( PrevElement != NULL )
|
||||
{
|
||||
PrevElement->Next = element->Next;
|
||||
}
|
||||
|
||||
element->Next = 0;
|
||||
element->Next = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -290,6 +281,7 @@ static bool IsSticky( uint8_t cid )
|
||||
case MOTE_MAC_DL_CHANNEL_ANS:
|
||||
case MOTE_MAC_RX_PARAM_SETUP_ANS:
|
||||
case MOTE_MAC_RX_TIMING_SETUP_ANS:
|
||||
case MOTE_MAC_TX_PARAM_SETUP_ANS:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -307,13 +299,12 @@ static void NvmCtxCallback( void )
|
||||
}
|
||||
}
|
||||
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsInit( EventNvmCtxChanged commandsNvmCtxChanged )
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsInit( LoRaMacCommandsNvmEvent commandsNvmCtxChanged )
|
||||
{
|
||||
|
||||
// Initialize with default
|
||||
memset1( (uint8_t*)&NvmCtx, 0, sizeof( NvmCtx ) );
|
||||
memset1( ( uint8_t* )&NvmCtx, 0, sizeof( NvmCtx ) );
|
||||
|
||||
linkedListInit( &NvmCtx.MacCommandList );
|
||||
LinkedListInit( &NvmCtx.MacCommandList );
|
||||
|
||||
// Assign callback
|
||||
CommandsNvmCtxChanged = commandsNvmCtxChanged;
|
||||
@@ -326,7 +317,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsRestoreNvmCtx( void* commandsNvmCtx )
|
||||
// Restore module context
|
||||
if( commandsNvmCtx != NULL )
|
||||
{
|
||||
memcpy1( ( uint8_t* ) &NvmCtx, ( uint8_t* ) commandsNvmCtx, sizeof( NvmCtx ) );
|
||||
memcpy1( ( uint8_t* )&NvmCtx, ( uint8_t* )commandsNvmCtx, sizeof( NvmCtx ) );
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
}
|
||||
else
|
||||
@@ -341,24 +332,24 @@ void* LoRaMacCommandsGetNvmCtx( size_t* commandsNvmCtxSize )
|
||||
return &NvmCtx;
|
||||
}
|
||||
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsAddCmd( uint8_t cid, uint8_t* payload, size_t payloadSize )
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsAddCmd( uint8_t cid, uint8_t* payload, size_t payloadSize )
|
||||
{
|
||||
if( payload == 0 )
|
||||
if( payload == NULL )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR_NPE;
|
||||
}
|
||||
MacCommand_t* newCmd;
|
||||
|
||||
// Allocate a memory slot
|
||||
newCmd = mallocNewMacCommandSlot( );
|
||||
newCmd = MallocNewMacCommandSlot( );
|
||||
|
||||
if( newCmd == 0 )
|
||||
if( newCmd == NULL )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR_MEMORY;
|
||||
}
|
||||
|
||||
// Add it to the list of Mac commands
|
||||
if( linkedListAdd( &NvmCtx.MacCommandList, newCmd ) == false )
|
||||
if( LinkedListAdd( &NvmCtx.MacCommandList, newCmd ) == false )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR;
|
||||
}
|
||||
@@ -366,7 +357,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsAddCmd( uint8_t cid, uint8_t* payload, si
|
||||
// Set Values
|
||||
newCmd->CID = cid;
|
||||
newCmd->PayloadSize = payloadSize;
|
||||
memcpy1( ( uint8_t* ) newCmd->Payload, payload, payloadSize );
|
||||
memcpy1( ( uint8_t* )newCmd->Payload, payload, payloadSize );
|
||||
newCmd->IsSticky = IsSticky( cid );
|
||||
|
||||
NvmCtx.SerializedCmdsSize += ( CID_FIELD_SIZE + payloadSize );
|
||||
@@ -384,7 +375,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveCmd( MacCommand_t* macCmd )
|
||||
}
|
||||
|
||||
// Remove the Mac command element from MacCommandList
|
||||
if( linkedListRemove( &NvmCtx.MacCommandList, macCmd ) == false )
|
||||
if( LinkedListRemove( &NvmCtx.MacCommandList, macCmd ) == false )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR_CMD_NOT_FOUND;
|
||||
}
|
||||
@@ -392,7 +383,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveCmd( MacCommand_t* macCmd )
|
||||
NvmCtx.SerializedCmdsSize -= ( CID_FIELD_SIZE + macCmd->PayloadSize );
|
||||
|
||||
// Free the MacCommand Slot
|
||||
if( freeMacCommandSlot( macCmd ) == false )
|
||||
if( FreeMacCommandSlot( macCmd ) == false )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR;
|
||||
}
|
||||
@@ -410,19 +401,19 @@ LoRaMacCommandStatus_t LoRaMacCommandsGetCmd( uint8_t cid, MacCommand_t** macCmd
|
||||
curElement = NvmCtx.MacCommandList.First;
|
||||
|
||||
// Loop through all elements until we find the element with the given CID
|
||||
while(curElement && ( curElement->CID != cid ) )
|
||||
while( ( curElement != NULL ) && ( curElement->CID != cid ) )
|
||||
{
|
||||
curElement = curElement->Next;
|
||||
}
|
||||
|
||||
// Update the pointer anyway
|
||||
*macCmd = curElement;
|
||||
|
||||
// Handle error in case if we reached the end without finding it.
|
||||
if( curElement == NULL )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR_CMD_NOT_FOUND;
|
||||
}
|
||||
|
||||
*macCmd = curElement;
|
||||
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -435,7 +426,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveNoneStickyCmds( void )
|
||||
curElement = NvmCtx.MacCommandList.First;
|
||||
|
||||
// Loop through all elements
|
||||
while( curElement )
|
||||
while( curElement != NULL )
|
||||
{
|
||||
if( curElement->IsSticky == false )
|
||||
{
|
||||
@@ -466,16 +457,9 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveStickyAnsCmds( void )
|
||||
while( curElement != NULL )
|
||||
{
|
||||
nexElement = curElement->Next;
|
||||
if( curElement->IsSticky == true )
|
||||
if( IsSticky( curElement->CID ) == true )
|
||||
{
|
||||
for( uint8_t i = 0; i < sizeof( CIDsStickyAnsCmds ); i++)
|
||||
{
|
||||
if( curElement->CID == CIDsStickyAnsCmds[i] )
|
||||
{
|
||||
LoRaMacCommandsRemoveCmd( curElement );
|
||||
break;
|
||||
}
|
||||
}
|
||||
LoRaMacCommandsRemoveCmd( curElement );
|
||||
}
|
||||
curElement = nexElement;
|
||||
}
|
||||
@@ -493,28 +477,28 @@ LoRaMacCommandStatus_t LoRaMacCommandsGetSizeSerializedCmds( size_t* size )
|
||||
}
|
||||
*size = NvmCtx.SerializedCmdsSize;
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsSerializeCmds( size_t availableSize, size_t* effectiveSize, uint8_t* buffer )
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsSerializeCmds( size_t availableSize, size_t* effectiveSize, uint8_t* buffer )
|
||||
{
|
||||
MacCommand_t* curElement = NvmCtx.MacCommandList.First;
|
||||
MacCommand_t* nextElement;
|
||||
uint8_t itr = 0;
|
||||
|
||||
if( ( buffer == NULL ) || ( effectiveSize == NULL ) )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR_NPE;
|
||||
}
|
||||
MacCommand_t* curElement;
|
||||
curElement = NvmCtx.MacCommandList.First;
|
||||
uint8_t itr = 0;
|
||||
|
||||
// Loop through all elements
|
||||
while( curElement )
|
||||
// Loop through all elements which fits into the buffer
|
||||
while( curElement != NULL )
|
||||
{
|
||||
// If the next MAC command still fits into the buffer, add it.
|
||||
if( ( availableSize - itr ) >= ( CID_FIELD_SIZE + curElement->PayloadSize ) )
|
||||
{
|
||||
buffer[itr++] = curElement->CID;
|
||||
memcpy1( &buffer[itr], curElement->Payload, curElement->PayloadSize );
|
||||
itr = itr + curElement->PayloadSize;
|
||||
itr += curElement->PayloadSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -523,6 +507,18 @@ LoRaMacCommandStatus_t LoRaMacCommandsSerializeCmds( size_t availableSize, size_
|
||||
curElement = curElement->Next;
|
||||
}
|
||||
|
||||
// Remove all commands which do not fit into the buffer
|
||||
while( curElement != NULL )
|
||||
{
|
||||
// Store the next element before removing the current one
|
||||
nextElement = curElement->Next;
|
||||
LoRaMacCommandsRemoveCmd( curElement );
|
||||
curElement = nextElement;
|
||||
}
|
||||
|
||||
// Fetch the effective size of the mac commands
|
||||
LoRaMacCommandsGetSizeSerializedCmds( effectiveSize );
|
||||
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -538,7 +534,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsStickyCmdsPending( bool* cmdsPending )
|
||||
*cmdsPending = false;
|
||||
|
||||
// Loop through all elements
|
||||
while( curElement )
|
||||
while( curElement != NULL )
|
||||
{
|
||||
if( curElement->IsSticky == true )
|
||||
{
|
||||
@@ -551,3 +547,103 @@ LoRaMacCommandStatus_t LoRaMacCommandsStickyCmdsPending( bool* cmdsPending )
|
||||
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
}
|
||||
|
||||
uint8_t LoRaMacCommandsGetCmdSize( uint8_t cid )
|
||||
{
|
||||
uint8_t cidSize = 0;
|
||||
|
||||
// Decode Frame MAC commands
|
||||
switch( cid )
|
||||
{
|
||||
case SRV_MAC_LINK_CHECK_ANS:
|
||||
{
|
||||
// cid + Margin + GwCnt
|
||||
cidSize = 3;
|
||||
break;
|
||||
}
|
||||
case SRV_MAC_LINK_ADR_REQ:
|
||||
{
|
||||
// cid + DataRate_TXPower + ChMask (2) + Redundancy
|
||||
cidSize = 5;
|
||||
break;
|
||||
}
|
||||
case SRV_MAC_DUTY_CYCLE_REQ:
|
||||
{
|
||||
// cid + DutyCyclePL
|
||||
cidSize = 2;
|
||||
break;
|
||||
}
|
||||
case SRV_MAC_RX_PARAM_SETUP_REQ:
|
||||
{
|
||||
// cid + DLsettings + Frequency (3)
|
||||
cidSize = 5;
|
||||
break;
|
||||
}
|
||||
case SRV_MAC_DEV_STATUS_REQ:
|
||||
{
|
||||
// cid
|
||||
cidSize = 1;
|
||||
break;
|
||||
}
|
||||
case SRV_MAC_NEW_CHANNEL_REQ:
|
||||
{
|
||||
// cid + ChIndex + Frequency (3) + DrRange
|
||||
cidSize = 6;
|
||||
break;
|
||||
}
|
||||
case SRV_MAC_RX_TIMING_SETUP_REQ:
|
||||
{
|
||||
// cid + Settings
|
||||
cidSize = 2;
|
||||
break;
|
||||
}
|
||||
case SRV_MAC_TX_PARAM_SETUP_REQ:
|
||||
{
|
||||
// cid + EIRP_DwellTime
|
||||
cidSize = 2;
|
||||
break;
|
||||
}
|
||||
case SRV_MAC_DL_CHANNEL_REQ:
|
||||
{
|
||||
// cid + ChIndex + Frequency (3)
|
||||
cidSize = 5;
|
||||
break;
|
||||
}
|
||||
case SRV_MAC_DEVICE_TIME_ANS:
|
||||
{
|
||||
// cid + Seconds (4) + Fractional seconds (1)
|
||||
cidSize = 6;
|
||||
break;
|
||||
}
|
||||
case SRV_MAC_PING_SLOT_INFO_ANS:
|
||||
{
|
||||
// cid
|
||||
cidSize = 1;
|
||||
break;
|
||||
}
|
||||
case SRV_MAC_PING_SLOT_CHANNEL_REQ:
|
||||
{
|
||||
// cid + Frequency (3) + DR
|
||||
cidSize = 5;
|
||||
break;
|
||||
}
|
||||
case SRV_MAC_BEACON_TIMING_ANS:
|
||||
{
|
||||
// cid + TimingDelay (2) + Channel
|
||||
cidSize = 4;
|
||||
break;
|
||||
}
|
||||
case SRV_MAC_BEACON_FREQ_REQ:
|
||||
{
|
||||
// cid + Frequency (3)
|
||||
cidSize = 4;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// Unknown command. ABORT MAC commands processing
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cidSize;
|
||||
}
|
||||
|
@@ -35,6 +35,11 @@
|
||||
#ifndef __LORAMAC_COMMANDS_H__
|
||||
#define __LORAMAC_COMMANDS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "LoRaMacTypes.h"
|
||||
@@ -109,7 +114,7 @@ typedef enum eLoRaMacCommandsStatus
|
||||
* Signature of callback function to be called by this module when the
|
||||
* non-volatile needs to be saved.
|
||||
*/
|
||||
typedef void ( *EventNvmCtxChanged )( void );
|
||||
typedef void ( *LoRaMacCommandsNvmEvent )( void );
|
||||
|
||||
/*!
|
||||
* \brief Initialization of LoRaMac MAC commands module
|
||||
@@ -119,7 +124,7 @@ typedef void ( *EventNvmCtxChanged )( void );
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsInit( EventNvmCtxChanged commandsNvmCtxChanged );
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsInit( LoRaMacCommandsNvmEvent commandsNvmCtxChanged );
|
||||
|
||||
/*!
|
||||
* Restores the internal non-volatile context from passed pointer.
|
||||
@@ -212,7 +217,20 @@ LoRaMacCommandStatus_t LoRaMacCommandsSerializeCmds( size_t availableSize, size_
|
||||
*/
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsStickyCmdsPending( bool* cmdsPending );
|
||||
|
||||
/*!
|
||||
* \brief Get the MAC command size with corresponding CID.
|
||||
*
|
||||
* \param[IN] cid - MAC command identifier
|
||||
*
|
||||
* \retval Size of the command.
|
||||
*/
|
||||
uint8_t LoRaMacCommandsGetCmdSize( uint8_t cid );
|
||||
|
||||
/*! \} addtogroup LORAMAC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LORAMAC_COMMANDS_H__
|
||||
|
||||
|
@@ -66,7 +66,7 @@ typedef struct sLoRaMacConfirmQueueCtx
|
||||
/*
|
||||
* Callback function to notify the upper layer about context change
|
||||
*/
|
||||
EventNvmCtxChanged EventNvmCtxChanged;
|
||||
LoRaMacConfirmQueueNvmEvent LoRaMacConfirmQueueNvmEvent;
|
||||
/*!
|
||||
* Non-volatile module context.
|
||||
*/
|
||||
@@ -112,26 +112,47 @@ static MlmeConfirmQueue_t* DecreaseBufferPointer( MlmeConfirmQueue_t* bufferPoin
|
||||
return bufferPointer;
|
||||
}
|
||||
|
||||
static bool IsListEmpty( uint8_t count )
|
||||
{
|
||||
if( count == 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsListFull( uint8_t count )
|
||||
{
|
||||
if( count >= LORA_MAC_MLME_CONFIRM_QUEUE_LEN )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static MlmeConfirmQueue_t* GetElement( Mlme_t request, MlmeConfirmQueue_t* bufferStart, MlmeConfirmQueue_t* bufferEnd )
|
||||
{
|
||||
MlmeConfirmQueue_t* element = bufferStart;
|
||||
|
||||
while( element != bufferEnd )
|
||||
if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == true )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for( uint8_t elementCnt = 0; elementCnt < ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt; elementCnt++ )
|
||||
{
|
||||
if( element->Request == request )
|
||||
{
|
||||
// We have found the element
|
||||
return element;
|
||||
}
|
||||
else
|
||||
{
|
||||
element = IncreaseBufferPointer( element );
|
||||
}
|
||||
element = IncreaseBufferPointer( element );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives, EventNvmCtxChanged confirmQueueNvmCtxChanged )
|
||||
void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives, LoRaMacConfirmQueueNvmEvent confirmQueueNvmCtxChanged )
|
||||
{
|
||||
ConfirmQueueCtx.Primitives = primitives;
|
||||
|
||||
@@ -151,7 +172,7 @@ void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives, EventNvmCtxChange
|
||||
ConfirmQueueCtx.ConfirmQueueNvmCtx->CommonStatus = LORAMAC_EVENT_INFO_STATUS_ERROR;
|
||||
|
||||
// Assign callback
|
||||
ConfirmQueueCtx.EventNvmCtxChanged = confirmQueueNvmCtxChanged;
|
||||
ConfirmQueueCtx.LoRaMacConfirmQueueNvmEvent = confirmQueueNvmCtxChanged;
|
||||
}
|
||||
|
||||
bool LoRaMacConfirmQueueRestoreNvmCtx( void* confirmQueueNvmCtx )
|
||||
@@ -176,7 +197,7 @@ void* LoRaMacConfirmQueueGetNvmCtx( size_t* confirmQueueNvmCtxSize )
|
||||
|
||||
bool LoRaMacConfirmQueueAdd( MlmeConfirmQueue_t* mlmeConfirm )
|
||||
{
|
||||
if( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt >= LORA_MAC_MLME_CONFIRM_QUEUE_LEN )
|
||||
if( IsListFull( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == true )
|
||||
{
|
||||
// Protect the buffer against overwrites
|
||||
return false;
|
||||
@@ -197,7 +218,7 @@ bool LoRaMacConfirmQueueAdd( MlmeConfirmQueue_t* mlmeConfirm )
|
||||
|
||||
bool LoRaMacConfirmQueueRemoveLast( void )
|
||||
{
|
||||
if( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt == 0 )
|
||||
if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == true )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -212,7 +233,7 @@ bool LoRaMacConfirmQueueRemoveLast( void )
|
||||
|
||||
bool LoRaMacConfirmQueueRemoveFirst( void )
|
||||
{
|
||||
if( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt == 0 )
|
||||
if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == true )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -229,7 +250,7 @@ void LoRaMacConfirmQueueSetStatus( LoRaMacEventInfoStatus_t status, Mlme_t reque
|
||||
{
|
||||
MlmeConfirmQueue_t* element = NULL;
|
||||
|
||||
if( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt > 0 )
|
||||
if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == false )
|
||||
{
|
||||
element = GetElement( request, ConfirmQueueCtx.BufferStart, ConfirmQueueCtx.BufferEnd );
|
||||
if( element != NULL )
|
||||
@@ -244,7 +265,7 @@ LoRaMacEventInfoStatus_t LoRaMacConfirmQueueGetStatus( Mlme_t request )
|
||||
{
|
||||
MlmeConfirmQueue_t* element = NULL;
|
||||
|
||||
if( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt > 0 )
|
||||
if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == false )
|
||||
{
|
||||
element = GetElement( request, ConfirmQueueCtx.BufferStart, ConfirmQueueCtx.BufferEnd );
|
||||
if( element != NULL )
|
||||
@@ -261,7 +282,7 @@ void LoRaMacConfirmQueueSetStatusCmn( LoRaMacEventInfoStatus_t status )
|
||||
|
||||
ConfirmQueueCtx.ConfirmQueueNvmCtx->CommonStatus = status;
|
||||
|
||||
if( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt > 0 )
|
||||
if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == false )
|
||||
{
|
||||
do
|
||||
{
|
||||
@@ -333,7 +354,7 @@ uint8_t LoRaMacConfirmQueueGetCnt( void )
|
||||
|
||||
bool LoRaMacConfirmQueueIsFull( void )
|
||||
{
|
||||
if( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt >= LORA_MAC_MLME_CONFIRM_QUEUE_LEN )
|
||||
if( IsListFull( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == true )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@@ -39,6 +39,11 @@
|
||||
#ifndef __LORAMAC_CONFIRMQUEUE_H__
|
||||
#define __LORAMAC_CONFIRMQUEUE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -77,7 +82,7 @@ typedef struct sMlmeConfirmQueue
|
||||
* Signature of callback function to be called by this module when the
|
||||
* non-volatile needs to be saved.
|
||||
*/
|
||||
typedef void ( *EventNvmCtxChanged )( void );
|
||||
typedef void ( *LoRaMacConfirmQueueNvmEvent )( void );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the confirm queue
|
||||
@@ -87,7 +92,7 @@ typedef void ( *EventNvmCtxChanged )( void );
|
||||
* \param [IN] confirmQueueNvmCtxChanged - Callback function which will be called when the
|
||||
* non-volatile context needs to be saved.
|
||||
*/
|
||||
void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives, EventNvmCtxChanged confirmQueueNvmCtxChanged );
|
||||
void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives, LoRaMacConfirmQueueNvmEvent confirmQueueNvmCtxChanged );
|
||||
|
||||
/*!
|
||||
* Restores the internal non-volatile context from passed pointer.
|
||||
@@ -192,4 +197,8 @@ uint8_t LoRaMacConfirmQueueGetCnt( void );
|
||||
*/
|
||||
bool LoRaMacConfirmQueueIsFull( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LORAMAC_CONFIRMQUEUE_H__
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,11 @@
|
||||
#ifndef __LORAMAC_CRYPTO_H__
|
||||
#define __LORAMAC_CRYPTO_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
@@ -44,6 +49,26 @@
|
||||
#include "LoRaMacTypes.h"
|
||||
#include "LoRaMacMessageTypes.h"
|
||||
|
||||
/*!
|
||||
* Indicates if LoRaWAN 1.1.x crypto scheme is enabled
|
||||
*/
|
||||
#define USE_LRWAN_1_1_X_CRYPTO 0
|
||||
|
||||
/*!
|
||||
* Indicates if a random devnonce must be used or not
|
||||
*/
|
||||
#define USE_RANDOM_DEV_NONCE 1
|
||||
|
||||
/*!
|
||||
* Indicates if JoinNonce is counter based and requires to be checked
|
||||
*/
|
||||
#define USE_JOIN_NONCE_COUNTER_CHECK 0
|
||||
|
||||
/*!
|
||||
* Initial value of the frame counters
|
||||
*/
|
||||
#define FCNT_DOWN_INITAL_VALUE 0xFFFFFFFF
|
||||
|
||||
/*!
|
||||
* LoRaMac Cryto Status
|
||||
*/
|
||||
@@ -70,9 +95,21 @@ typedef enum eLoRaMacCryptoStatus
|
||||
*/
|
||||
LORAMAC_CRYPTO_FAIL_RJCOUNT0_OVERFLOW,
|
||||
/*!
|
||||
* FCntUp/Down check failed
|
||||
* FCNT_ID is not supported
|
||||
*/
|
||||
LORAMAC_CRYPTO_FAIL_FCNT,
|
||||
LORAMAC_CRYPTO_FAIL_FCNT_ID,
|
||||
/*!
|
||||
* FCntUp/Down check failed (new FCnt is smaller than previous one)
|
||||
*/
|
||||
LORAMAC_CRYPTO_FAIL_FCNT_SMALLER,
|
||||
/*!
|
||||
* FCntUp/Down check failed (duplicated)
|
||||
*/
|
||||
LORAMAC_CRYPTO_FAIL_FCNT_DUPLICATED,
|
||||
/*!
|
||||
* MAX_GAP_FCNT check failed
|
||||
*/
|
||||
LORAMAC_CRYPTO_FAIL_MAX_GAP_FCNT,
|
||||
/*!
|
||||
* Not allowed parameter value
|
||||
*/
|
||||
@@ -125,7 +162,7 @@ typedef enum eLoRaMacCryptoStatus
|
||||
* crypto module context.
|
||||
*
|
||||
*/
|
||||
typedef void ( *EventNvmCtxChanged )( void );
|
||||
typedef void ( *LoRaMacCryptoNvmEvent )( void );
|
||||
|
||||
/*!
|
||||
* Initialization of LoRaMac Crypto module
|
||||
@@ -135,11 +172,11 @@ typedef void ( *EventNvmCtxChanged )( void );
|
||||
* non-volatile context have to be stored.
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoInit( EventNvmCtxChanged cryptoNvmCtxChanged );
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmEvent cryptoNvmCtxChanged );
|
||||
|
||||
/*!
|
||||
* Sets the LoRaWAN specification version to be used.
|
||||
*
|
||||
*
|
||||
* \warning This function should be used for ABP only. In case of OTA the version will be set automatically.
|
||||
*
|
||||
* \param[IN] version - LoRaWAN specification version to be used.
|
||||
@@ -164,6 +201,34 @@ LoRaMacCryptoStatus_t LoRaMacCryptoRestoreNvmCtx( void* cryptoNvmCtx );
|
||||
*/
|
||||
void* LoRaMacCryptoGetNvmCtx( size_t* cryptoNvmCtxSize );
|
||||
|
||||
/*!
|
||||
* Returns updated fCntID downlink counter value.
|
||||
*
|
||||
* \param[IN] fCntID - Frame counter identifier
|
||||
* \param[IN] maxFcntGap - Maximum allowed frame counter difference (only necessary for L2 LW1.0.x)
|
||||
* \param[IN] frameFcnt - Received frame counter (used to update current counter value)
|
||||
* \param[OUT] currentDown - Current downlink counter value
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntDown( FCntIdentifier_t fCntID, uint16_t maxFCntGap, uint32_t frameFcnt, uint32_t* currentDown );
|
||||
|
||||
/*!
|
||||
* Returns updated fCntUp uplink counter value.
|
||||
*
|
||||
* \param[IN] currentUp - Uplink counter value
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntUp( uint32_t* currentUp );
|
||||
|
||||
/*!
|
||||
* Provides multicast context.
|
||||
*
|
||||
* \param[IN] multicastList - Pointer to the multicast context list
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoSetMulticastReference( MulticastCtx_t* multicastList );
|
||||
|
||||
/*!
|
||||
* Sets a key
|
||||
*
|
||||
@@ -235,16 +300,28 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr,
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoUnsecureMessage( AddressIdentifier_t addrID, uint32_t address, FCntIdentifier_t fCntID, uint32_t fCntDown, LoRaMacMessageData_t* macMsg );
|
||||
|
||||
/*!
|
||||
* Derives the McKEKey from the AppKey or NwkKey.
|
||||
* Derives the McRootKey from the AppKey.
|
||||
*
|
||||
* McKEKey = aes128_encrypt(NwkKey or AppKey , nonce | DevEUI | pad16)
|
||||
* 1.0.x
|
||||
* McRootKey = aes128_encrypt(AppKey, 0x00 | pad16)
|
||||
*
|
||||
* \param[IN] keyID - Key identifier of the root key to use to perform the derivation ( NwkKey or AppKey )
|
||||
* \param[IN] nonce - Nonce value ( nonce <= 15)
|
||||
* \param[IN] devEUI - DevEUI Value
|
||||
* 1.1.x
|
||||
* McRootKey = aes128_encrypt(AppKey, 0x20 | pad16)
|
||||
*
|
||||
* \param[IN] keyID - Key identifier of the root key to use to perform the derivation ( AppKey )
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcKEKey( KeyIdentifier_t keyID, uint16_t nonce, uint8_t* devEUI );
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcRootKey( KeyIdentifier_t keyID );
|
||||
|
||||
/*!
|
||||
* Derives the McKEKey from the McRootKey.
|
||||
*
|
||||
* McKEKey = aes128_encrypt(McRootKey , 0x00 | pad16)
|
||||
*
|
||||
* \param[IN] keyID - Key identifier of the root key to use to perform the derivation ( McRootKey )
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcKEKey( KeyIdentifier_t keyID );
|
||||
|
||||
/*!
|
||||
* Derives a Multicast group key pair ( McAppSKey, McNwkSKey ) from McKey
|
||||
@@ -260,4 +337,8 @@ LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcSessionKeyPair( AddressIdentifier_t a
|
||||
|
||||
/*! \} addtogroup LORAMAC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LORAMAC_CRYPTO_H__
|
||||
|
@@ -1,319 +0,0 @@
|
||||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
Description: LoRa MAC layer frame counter handling implementation
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Daniel Jaeckle ( STACKFORCE ), Johannes Bruder ( STACKFORCE )
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "utilities.h"
|
||||
#include "LoRaMacFCntHandler.h"
|
||||
|
||||
/*
|
||||
* Initial value of the frame counters
|
||||
*/
|
||||
#define FCNT_DOWN_INITAL_VALUE 0xFFFFFFFF
|
||||
|
||||
|
||||
/*!
|
||||
* LoRaWAN Frame counter list.
|
||||
*/
|
||||
typedef struct sFCntList
|
||||
{
|
||||
/*
|
||||
* Uplink frame counter which is incremented with each uplink.
|
||||
*/
|
||||
uint32_t FCntUp;
|
||||
/*
|
||||
* Network downlink frame counter which is incremented with each downlink on FPort 0
|
||||
* or when the FPort field is missing.
|
||||
*/
|
||||
uint32_t NFCntDown;
|
||||
/*
|
||||
* Application downlink frame counter which is incremented with each downlink
|
||||
* on a port different than 0.
|
||||
*/
|
||||
uint32_t AFCntDown;
|
||||
/*
|
||||
* In case if the device is connected to a LoRaWAN 1.0 Server,
|
||||
* this counter is used for every kind of downlink frame.
|
||||
*/
|
||||
uint32_t FCntDown;
|
||||
/*!
|
||||
* Multicast downlink counter for index 0
|
||||
*/
|
||||
uint32_t McFCntDown0;
|
||||
/*!
|
||||
* Multicast downlink counter for index 1
|
||||
*/
|
||||
uint32_t McFCntDown1;
|
||||
/*!
|
||||
* Multicast downlink counter for index 2
|
||||
*/
|
||||
uint32_t McFCntDown2;
|
||||
/*!
|
||||
* Multicast downlink counter for index 3
|
||||
*/
|
||||
uint32_t McFCntDown3;
|
||||
}FCntList_t;
|
||||
|
||||
|
||||
/*
|
||||
* LoRaMac Commands Context structure
|
||||
*/
|
||||
typedef struct sLoRaMacFCntHandlerNvmCtx
|
||||
{
|
||||
/*
|
||||
* Frame counter list
|
||||
*/
|
||||
FCntList_t FCntList;
|
||||
} LoRaMacFCntHandlerNvmCtx_t;
|
||||
|
||||
/*
|
||||
* Non-volatile module context.
|
||||
*/
|
||||
static LoRaMacFCntHandlerNvmCtx_t FCntHandlerNvmCtx;
|
||||
|
||||
/*
|
||||
* Callback function to notify the upper layer about context change
|
||||
*/
|
||||
static EventNvmCtxChanged FCntHandlerNvmCtxChanged;
|
||||
|
||||
/*
|
||||
* \brief Wrapper function for the NvmCtx
|
||||
*/
|
||||
static void NvmCtxChanged( void )
|
||||
{
|
||||
if( FCntHandlerNvmCtxChanged != NULL )
|
||||
{
|
||||
FCntHandlerNvmCtxChanged( );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacFCntHandlerInit( EventNvmCtxChanged fCntHandlerNvmCtxChanged )
|
||||
{
|
||||
// Initialize with default
|
||||
LoRaMacResetFCnts( );
|
||||
|
||||
// Assign callback
|
||||
FCntHandlerNvmCtxChanged = fCntHandlerNvmCtxChanged;
|
||||
|
||||
return LORAMAC_FCNT_HANDLER_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacFCntHandlerRestoreNvmCtx( void* fCntHandlerNvmCtx )
|
||||
{
|
||||
// Restore module context
|
||||
if( fCntHandlerNvmCtx != NULL )
|
||||
{
|
||||
memcpy1( ( uint8_t* ) &FCntHandlerNvmCtx, ( uint8_t* ) fCntHandlerNvmCtx, sizeof( FCntHandlerNvmCtx ) );
|
||||
return LORAMAC_FCNT_HANDLER_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LORAMAC_FCNT_HANDLER_ERROR_NPE;
|
||||
}
|
||||
}
|
||||
|
||||
void* LoRaMacFCntHandlerGetNvmCtx( size_t* fCntHandlerNvmCtxSize )
|
||||
{
|
||||
*fCntHandlerNvmCtxSize = sizeof( FCntHandlerNvmCtx );
|
||||
return &FCntHandlerNvmCtx;
|
||||
}
|
||||
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacGetFCntDown( AddressIdentifier_t addrID, FType_t fType, LoRaMacMessageData_t* macMsg, Version_t lrWanVersion,
|
||||
uint16_t maxFCntGap, FCntIdentifier_t* fCntID, uint32_t* currentDown )
|
||||
{
|
||||
uint32_t previousDown = 0;
|
||||
int32_t fCntDiff = 0;
|
||||
|
||||
if( ( macMsg == NULL ) || ( fCntID == NULL ) ||
|
||||
( currentDown == NULL ) )
|
||||
{
|
||||
return LORAMAC_FCNT_HANDLER_ERROR_NPE;
|
||||
}
|
||||
|
||||
// Determine the frame counter identifier and choose counter from FCntList
|
||||
switch( addrID )
|
||||
{
|
||||
case UNICAST_DEV_ADDR:
|
||||
if( lrWanVersion.Fields.Minor == 1 )
|
||||
{
|
||||
if( ( fType == FRAME_TYPE_A ) || ( fType == FRAME_TYPE_D ) )
|
||||
{
|
||||
*fCntID = A_FCNT_DOWN;
|
||||
previousDown = FCntHandlerNvmCtx.FCntList.AFCntDown;
|
||||
}
|
||||
else
|
||||
{
|
||||
*fCntID = N_FCNT_DOWN;
|
||||
previousDown = FCntHandlerNvmCtx.FCntList.NFCntDown;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // For LoRaWAN 1.0.X
|
||||
*fCntID = FCNT_DOWN;
|
||||
previousDown = FCntHandlerNvmCtx.FCntList.FCntDown;
|
||||
}
|
||||
break;
|
||||
case MULTICAST_0_ADDR:
|
||||
*fCntID = MC_FCNT_DOWN_0;
|
||||
previousDown = FCntHandlerNvmCtx.FCntList.McFCntDown0;
|
||||
break;
|
||||
case MULTICAST_1_ADDR:
|
||||
*fCntID = MC_FCNT_DOWN_1;
|
||||
previousDown = FCntHandlerNvmCtx.FCntList.McFCntDown1;
|
||||
break;
|
||||
case MULTICAST_2_ADDR:
|
||||
*fCntID = MC_FCNT_DOWN_2;
|
||||
previousDown = FCntHandlerNvmCtx.FCntList.McFCntDown3;
|
||||
break;
|
||||
case MULTICAST_3_ADDR:
|
||||
*fCntID = MC_FCNT_DOWN_3;
|
||||
previousDown = FCntHandlerNvmCtx.FCntList.McFCntDown3;
|
||||
break;
|
||||
default:
|
||||
return LORAMAC_FCNT_HANDLER_ERROR;
|
||||
}
|
||||
|
||||
// For LoRaWAN 1.0.X only, allow downlink frames of 0
|
||||
if( previousDown == FCNT_DOWN_INITAL_VALUE )
|
||||
{
|
||||
*currentDown = macMsg->FHDR.FCnt;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add difference, consider roll-over
|
||||
fCntDiff = ( int32_t )macMsg->FHDR.FCnt - ( int32_t )( previousDown & 0x0000FFFF );
|
||||
|
||||
if( fCntDiff > 0 )
|
||||
{ // Positive difference
|
||||
*currentDown = previousDown + fCntDiff;
|
||||
}
|
||||
else if( fCntDiff == 0 )
|
||||
{ // Duplicate FCnt value, keep the current value.
|
||||
*currentDown = previousDown;
|
||||
return LORAMAC_FCNT_HANDLER_CHECK_FAIL;
|
||||
}
|
||||
else
|
||||
{ // Negative difference, assume a roll-over of one uint16_t
|
||||
*currentDown = ( previousDown & 0xFFFF0000 ) + 0x10000 + macMsg->FHDR.FCnt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// For LoRaWAN 1.0.X only, check maxFCntGap
|
||||
if( lrWanVersion.Fields.Minor == 0 )
|
||||
{
|
||||
if( ( ( int32_t )*currentDown - ( int32_t )previousDown ) >= maxFCntGap )
|
||||
{
|
||||
return LORAMAC_FCNT_HANDLER_MAX_GAP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return LORAMAC_FCNT_HANDLER_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacSetFCntDown( FCntIdentifier_t fCntID, uint32_t currentDown )
|
||||
{
|
||||
switch( fCntID )
|
||||
{
|
||||
case FCNT_UP:
|
||||
return LORAMAC_FCNT_HANDLER_ERROR_INVALID_FCNT_ID;
|
||||
case N_FCNT_DOWN:
|
||||
FCntHandlerNvmCtx.FCntList.NFCntDown = currentDown;
|
||||
break;
|
||||
case A_FCNT_DOWN:
|
||||
FCntHandlerNvmCtx.FCntList.AFCntDown = currentDown;
|
||||
break;
|
||||
case FCNT_DOWN:
|
||||
FCntHandlerNvmCtx.FCntList.FCntDown = currentDown;
|
||||
break;
|
||||
case MC_FCNT_DOWN_0:
|
||||
FCntHandlerNvmCtx.FCntList.McFCntDown0 = currentDown;
|
||||
break;
|
||||
case MC_FCNT_DOWN_1:
|
||||
FCntHandlerNvmCtx.FCntList.McFCntDown1 = currentDown;
|
||||
break;
|
||||
case MC_FCNT_DOWN_2:
|
||||
FCntHandlerNvmCtx.FCntList.McFCntDown2 = currentDown;
|
||||
break;
|
||||
case MC_FCNT_DOWN_3:
|
||||
FCntHandlerNvmCtx.FCntList.McFCntDown3 = currentDown;
|
||||
break;
|
||||
default:
|
||||
return LORAMAC_FCNT_HANDLER_ERROR;
|
||||
}
|
||||
|
||||
NvmCtxChanged( );
|
||||
|
||||
return LORAMAC_FCNT_HANDLER_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacGetFCntUp( uint32_t* currentUp )
|
||||
{
|
||||
if( currentUp == NULL )
|
||||
{
|
||||
return LORAMAC_FCNT_HANDLER_ERROR_NPE;
|
||||
}
|
||||
|
||||
*currentUp = FCntHandlerNvmCtx.FCntList.FCntUp + 1;
|
||||
|
||||
return LORAMAC_FCNT_HANDLER_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacSetFCntUp( uint32_t currentUp )
|
||||
{
|
||||
FCntHandlerNvmCtx.FCntList.FCntUp = currentUp;
|
||||
|
||||
NvmCtxChanged( );
|
||||
|
||||
return LORAMAC_FCNT_HANDLER_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacResetFCnts( void )
|
||||
{
|
||||
|
||||
FCntHandlerNvmCtx.FCntList.FCntUp = 0;
|
||||
FCntHandlerNvmCtx.FCntList.NFCntDown = FCNT_DOWN_INITAL_VALUE;
|
||||
FCntHandlerNvmCtx.FCntList.AFCntDown = FCNT_DOWN_INITAL_VALUE;
|
||||
FCntHandlerNvmCtx.FCntList.FCntDown = FCNT_DOWN_INITAL_VALUE;
|
||||
|
||||
FCntHandlerNvmCtx.FCntList.McFCntDown0 = FCNT_DOWN_INITAL_VALUE;
|
||||
FCntHandlerNvmCtx.FCntList.McFCntDown1 = FCNT_DOWN_INITAL_VALUE;
|
||||
FCntHandlerNvmCtx.FCntList.McFCntDown2 = FCNT_DOWN_INITAL_VALUE;
|
||||
FCntHandlerNvmCtx.FCntList.McFCntDown3 = FCNT_DOWN_INITAL_VALUE;
|
||||
|
||||
NvmCtxChanged( );
|
||||
|
||||
return LORAMAC_FCNT_HANDLER_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacFCntHandlerSetMulticastReference( MulticastCtx_t* multicastList )
|
||||
{
|
||||
if( multicastList == NULL )
|
||||
{
|
||||
return LORAMAC_FCNT_HANDLER_ERROR_NPE;
|
||||
}
|
||||
|
||||
multicastList[0].DownLinkCounter = &FCntHandlerNvmCtx.FCntList.McFCntDown0;
|
||||
multicastList[1].DownLinkCounter = &FCntHandlerNvmCtx.FCntList.McFCntDown1;
|
||||
multicastList[2].DownLinkCounter = &FCntHandlerNvmCtx.FCntList.McFCntDown2;
|
||||
multicastList[3].DownLinkCounter = &FCntHandlerNvmCtx.FCntList.McFCntDown3;
|
||||
|
||||
return LORAMAC_FCNT_HANDLER_SUCCESS;
|
||||
}
|
@@ -1,170 +0,0 @@
|
||||
/*!
|
||||
* \file LoRaMacFCntHandler.h
|
||||
*
|
||||
* \brief LoRa MAC layer frame counter handling
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* addtogroup LORAMAC
|
||||
* \{
|
||||
*
|
||||
*/
|
||||
#ifndef __LORAMAC_FCNT_HANDLER_H__
|
||||
#define __LORAMAC_FCNT_HANDLER_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "LoRaMacTypes.h"
|
||||
#include "LoRaMacMessageTypes.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac FCnt Handler Status
|
||||
*/
|
||||
typedef enum eLoRaMacFCntHandlerStatus
|
||||
{
|
||||
/*!
|
||||
* No error occurred
|
||||
*/
|
||||
LORAMAC_FCNT_HANDLER_SUCCESS = 0,
|
||||
/*!
|
||||
* FCntUp/Down check failed
|
||||
*/
|
||||
LORAMAC_FCNT_HANDLER_CHECK_FAIL,
|
||||
/*!
|
||||
* The status idicates that the node has lost MAX_FCNT_GAP or more frames
|
||||
*/
|
||||
LORAMAC_FCNT_HANDLER_MAX_GAP_FAIL,
|
||||
/*!
|
||||
* Invalid frame counter identifier exception
|
||||
*/
|
||||
LORAMAC_FCNT_HANDLER_ERROR_INVALID_FCNT_ID,
|
||||
/*!
|
||||
* Null pointer exception
|
||||
*/
|
||||
LORAMAC_FCNT_HANDLER_ERROR_NPE,
|
||||
/*!
|
||||
* Undefined Error occurred
|
||||
*/
|
||||
LORAMAC_FCNT_HANDLER_ERROR,
|
||||
}LoRaMacFCntHandlerStatus_t;
|
||||
|
||||
/*!
|
||||
* Signature of callback function to be called by this module when the
|
||||
* non-volatile needs to be saved.
|
||||
*/
|
||||
typedef void ( *EventNvmCtxChanged )( void );
|
||||
|
||||
/*!
|
||||
* \brief Initialization of LoRaMac FCnt Handler module
|
||||
*
|
||||
* \param[IN] fCntHandlerNvmCtxChanged - Callback function which will be called when the
|
||||
* non-volatile context needs to be saved.
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacFCntHandlerInit( EventNvmCtxChanged fCntHandlerNvmCtxChanged );
|
||||
|
||||
/*!
|
||||
* Restores the internal non-volatile context from passed pointer.
|
||||
*
|
||||
* \param[IN] fCntHandlerNvmCtx - Pointer to non-volatile FCnt handler module context to be restored.
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacFCntHandlerRestoreNvmCtx( void* fCntHandlerNvmCtx );
|
||||
|
||||
/*!
|
||||
* Returns a pointer to the internal non-volatile context.
|
||||
*
|
||||
* \param[IN] fCntHandlerNvmCtxSize - Size of the module non-volatile context
|
||||
*
|
||||
* \retval - Points to a structure where the module store its non-volatile context
|
||||
*/
|
||||
void* LoRaMacFCntHandlerGetNvmCtx( size_t* fCntHandlerNvmCtxSize );
|
||||
|
||||
/*!
|
||||
* Computes next 32 bit downlink counter value and determines the frame counter ID.
|
||||
*
|
||||
* \param[IN] addrID - Address identifier
|
||||
* \param[IN] fType - Frame type
|
||||
* \param[IN] macMsg - Data message object, holding the current 16 bit transmitted frame counter
|
||||
* \param[IN] lrWanVersion - LoRaWAN version
|
||||
* \param[IN] maxFCntGap - Maximum allowed frame counter difference (only for 1.0.X necessary)
|
||||
* \param[OUT] fCntID - Frame counter identifier
|
||||
* \param[OUT] currentDown - Current downlink counter value
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacGetFCntDown( AddressIdentifier_t addrID, FType_t fType, LoRaMacMessageData_t* macMsg, Version_t lrWanVersion,
|
||||
uint16_t maxFCntGap, FCntIdentifier_t* fCntID, uint32_t* currentDown );
|
||||
|
||||
/*!
|
||||
* Sets the downlink counter value according to the counter ID.
|
||||
*
|
||||
* \param[IN] fCntID - Frame counter identifier
|
||||
* \param[IN] currentDown - Current downlink counter value
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacSetFCntDown( FCntIdentifier_t fCntID, uint32_t currentDown );
|
||||
|
||||
/*!
|
||||
* Computes next uplink counter value.
|
||||
*
|
||||
* \param[OUT] currentUp - Current uplink counter value
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacGetFCntUp( uint32_t* currentUp );
|
||||
|
||||
/*!
|
||||
* Sets the uplink counter value according to the counter ID.
|
||||
*
|
||||
* \param[IN] currentUp - Current uplink counter value
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacSetFCntUp( uint32_t currentUp );
|
||||
|
||||
/*!
|
||||
* Resets the value of FCntUp, NFCntDown, AFCntDown and FCntDown to zero
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacResetFCnts( void );
|
||||
|
||||
/*!
|
||||
* Sets the reference to the multicast downlink counter
|
||||
*
|
||||
* \param[IN] multicastList Pointer to the multicast list
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacFCntHandlerSetMulticastReference( MulticastCtx_t* multicastList );
|
||||
|
||||
/*! \} addtogroup LORAMAC */
|
||||
|
||||
#endif // __LORAMAC_FCNT_HANDLER_H__
|
||||
|
@@ -37,23 +37,160 @@
|
||||
#ifndef __LORAMAC_HEADER_TYPES_H__
|
||||
#define __LORAMAC_HEADER_TYPES_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*! Frame header (FHDR) maximum field size */
|
||||
#define LORAMAC_FHDR_MAX_FIELD_SIZE 22
|
||||
/*! MAC header field size */
|
||||
#define LORAMAC_MHDR_FIELD_SIZE 1
|
||||
|
||||
/*! ReJoinType field size */
|
||||
#define LORAMAC_JOIN_TYPE_FIELD_SIZE 1
|
||||
|
||||
/*! Join EUI field size */
|
||||
#define LORAMAC_JOIN_EUI_FIELD_SIZE 8
|
||||
|
||||
/*! Device EUI field size */
|
||||
#define LORAMAC_DEV_EUI_FIELD_SIZE 8
|
||||
|
||||
/*! End-device nonce field size */
|
||||
#define LORAMAC_DEV_NONCE_FIELD_SIZE 2
|
||||
|
||||
/*! Join-server nonce field size */
|
||||
#define LORAMAC_JOIN_NONCE_FIELD_SIZE 3
|
||||
|
||||
/*! RJcount0 field size */
|
||||
#define LORAMAC_RJCOUNT_0_FIELD_SIZE 2
|
||||
|
||||
/*! RJcount1 field size */
|
||||
#define LORAMAC_RJCOUNT_1_FIELD_SIZE 2
|
||||
|
||||
/*! Network ID field size */
|
||||
#define LORAMAC_NET_ID_FIELD_SIZE 3
|
||||
|
||||
/*! Device address field size */
|
||||
#define LORAMAC_DEV_ADDR_FIELD_SIZE 4
|
||||
|
||||
/*! DLSettings field size */
|
||||
#define LORAMAC_DL_SETTINGS_FIELD_SIZE 1
|
||||
|
||||
/*! RxDelay field size */
|
||||
#define LORAMAC_RX_DELAY_FIELD_SIZE 1
|
||||
|
||||
/*! CFList field size */
|
||||
#define LORAMAC_CF_LIST_FIELD_SIZE 16
|
||||
|
||||
/*! FHDR Device address field size */
|
||||
#define LORAMAC_FHDR_DEV_ADD_FIELD_SIZE 4
|
||||
#define LORAMAC_FHDR_DEV_ADDR_FIELD_SIZE LORAMAC_DEV_ADDR_FIELD_SIZE
|
||||
|
||||
/*! FHDR Frame control field size */
|
||||
#define LORAMAC_FHDR_F_CTRL_FIELD_SIZE 1
|
||||
#define LORAMAC_FHDR_F_CTRL_FIELD_SIZE 1
|
||||
|
||||
/*! FHDR Frame control field size */
|
||||
#define LORAMAC_FHDR_F_CNT_FIELD_SIZE 2
|
||||
#define LORAMAC_FHDR_F_CNT_FIELD_SIZE 2
|
||||
|
||||
/*! FOpts maximum field size */
|
||||
#define LORAMAC_FHDR_F_OPTS_MAX_FIELD_SIZE 15
|
||||
#define LORAMAC_FHDR_F_OPTS_MAX_FIELD_SIZE 15
|
||||
|
||||
/*! Port field size */
|
||||
#define LORAMAC_F_PORT_FIELD_SIZE 1
|
||||
|
||||
/*! Port field size */
|
||||
#define LORAMAC_MAC_PAYLOAD_FIELD_MAX_SIZE 242
|
||||
|
||||
/*! MIC field size */
|
||||
#define LORAMAC_MIC_FIELD_SIZE 4
|
||||
|
||||
/*!
|
||||
* JoinRequest frame size
|
||||
*
|
||||
* MHDR(1) + JoinEUI(8) + DevEUI(8) + DevNonce(2) + MIC(4)
|
||||
*/
|
||||
#define LORAMAC_JOIN_REQ_MSG_SIZE ( LORAMAC_MHDR_FIELD_SIZE + LORAMAC_JOIN_EUI_FIELD_SIZE + \
|
||||
LORAMAC_DEV_EUI_FIELD_SIZE + LORAMAC_DEV_NONCE_FIELD_SIZE + \
|
||||
LORAMAC_MIC_FIELD_SIZE )
|
||||
|
||||
/*!
|
||||
* ReJoinRequest type 1 frame size
|
||||
*
|
||||
* MHDR(1) + ReJoinType(1) + JoinEUI(8) + DevEUI(8) + RJcount1(2) + MIC(4)
|
||||
*/
|
||||
#define LORAMAC_RE_JOIN_1_MSG_SIZE ( LORAMAC_MHDR_FIELD_SIZE + LORAMAC_JOIN_TYPE_FIELD_SIZE + \
|
||||
LORAMAC_JOIN_EUI_FIELD_SIZE + LORAMAC_DEV_EUI_FIELD_SIZE + \
|
||||
LORAMAC_RJCOUNT_1_FIELD_SIZE + \
|
||||
LORAMAC_MIC_FIELD_SIZE )
|
||||
|
||||
/*!
|
||||
* ReJoinRequest type 0 or 2 frame size
|
||||
*
|
||||
* MHDR(1) + ReJoinType(1) + NetID(3) + DevEUI(8) + RJcount0(2) + MIC(4)
|
||||
*/
|
||||
#define LORAMAC_RE_JOIN_0_2_MSG_SIZE ( LORAMAC_MHDR_FIELD_SIZE + LORAMAC_JOIN_TYPE_FIELD_SIZE + \
|
||||
LORAMAC_NET_ID_FIELD_SIZE + LORAMAC_DEV_EUI_FIELD_SIZE + \
|
||||
LORAMAC_RJCOUNT_0_FIELD_SIZE + \
|
||||
LORAMAC_MIC_FIELD_SIZE )
|
||||
|
||||
/*!
|
||||
* JoinAccept frame minimum size
|
||||
*
|
||||
* MHDR(1) + AppNonce(3) + NetID(3) + DevAddr(4) + DLSettings(1) + RxDelay(1) + MIC(4)
|
||||
*/
|
||||
#define LORAMAC_JOIN_ACCEPT_FRAME_MIN_SIZE ( LORAMAC_MHDR_FIELD_SIZE + LORAMAC_JOIN_NONCE_FIELD_SIZE + \
|
||||
LORAMAC_NET_ID_FIELD_SIZE + LORAMAC_DEV_ADDR_FIELD_SIZE + \
|
||||
LORAMAC_DL_SETTINGS_FIELD_SIZE + LORAMAC_RX_DELAY_FIELD_SIZE + \
|
||||
LORAMAC_MIC_FIELD_SIZE )
|
||||
|
||||
/*!
|
||||
* JoinAccept frame maximum size
|
||||
*
|
||||
* MHDR(1) + AppNonce(3) + NetID(3) + DevAddr(4) + DLSettings(1) + RxDelay(1) + CFList(16) + MIC(4)
|
||||
*/
|
||||
#define LORAMAC_JOIN_ACCEPT_FRAME_MAX_SIZE ( LORAMAC_MHDR_FIELD_SIZE + LORAMAC_JOIN_NONCE_FIELD_SIZE + \
|
||||
LORAMAC_NET_ID_FIELD_SIZE + LORAMAC_DEV_ADDR_FIELD_SIZE + \
|
||||
LORAMAC_DL_SETTINGS_FIELD_SIZE + LORAMAC_RX_DELAY_FIELD_SIZE + \
|
||||
LORAMAC_CF_LIST_FIELD_SIZE + LORAMAC_MIC_FIELD_SIZE )
|
||||
|
||||
/*!
|
||||
* MIC computation offset
|
||||
* \remark required for 1.1.x support
|
||||
*/
|
||||
#define JOIN_ACCEPT_MIC_COMPUTATION_OFFSET \
|
||||
( LORAMAC_MHDR_FIELD_SIZE + LORAMAC_JOIN_TYPE_FIELD_SIZE + LORAMAC_JOIN_EUI_FIELD_SIZE + \
|
||||
LORAMAC_DEV_NONCE_FIELD_SIZE )
|
||||
|
||||
/*!
|
||||
* FRMPayload overhead to be used when setting the Radio.SetMaxPayloadLength
|
||||
*
|
||||
* Overhead to be used when setting the Radio.SetMaxPayloadLength in RxWindowSetup function.
|
||||
*
|
||||
* MHDR(1) + FHDR(7) + Port(1) + MIC(4)
|
||||
*
|
||||
* Maximum PHYPayload = MaxPayloadOfDatarate + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE
|
||||
*/
|
||||
#define LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE ( LORAMAC_MHDR_FIELD_SIZE + ( LORAMAC_FHDR_DEV_ADDR_FIELD_SIZE + \
|
||||
LORAMAC_FHDR_F_CTRL_FIELD_SIZE + LORAMAC_FHDR_F_CNT_FIELD_SIZE ) + \
|
||||
LORAMAC_F_PORT_FIELD_SIZE + LORAMAC_MIC_FIELD_SIZE )
|
||||
|
||||
/*!
|
||||
* FRMPayload minimum size
|
||||
*
|
||||
* MHDR(1) + FHDR(7) + MIC(4)
|
||||
*/
|
||||
#define LORAMAC_FRAME_PAYLOAD_MIN_SIZE ( LORAMAC_MHDR_FIELD_SIZE + ( LORAMAC_FHDR_DEV_ADDR_FIELD_SIZE + \
|
||||
LORAMAC_FHDR_F_CTRL_FIELD_SIZE + LORAMAC_FHDR_F_CNT_FIELD_SIZE ) + \
|
||||
LORAMAC_MIC_FIELD_SIZE )
|
||||
/*!
|
||||
* FRMPayload maximum possible size
|
||||
*
|
||||
* MHDR(1) + FHDR(7) + Port(1) + MACPayload(242) + MIC(4)
|
||||
*/
|
||||
#define LORAMAC_FRAME_PAYLOAD_MAX_SIZE ( LORAMAC_MHDR_FIELD_SIZE + ( LORAMAC_FHDR_DEV_ADDR_FIELD_SIZE + \
|
||||
LORAMAC_FHDR_F_CTRL_FIELD_SIZE + LORAMAC_FHDR_F_CNT_FIELD_SIZE ) + \
|
||||
LORAMAC_F_PORT_FIELD_SIZE + LORAMAC_MAC_PAYLOAD_FIELD_MAX_SIZE + \
|
||||
LORAMAC_MIC_FIELD_SIZE )
|
||||
|
||||
/*!
|
||||
* LoRaMAC field definition of DLSettings
|
||||
@@ -183,4 +320,8 @@ typedef struct sLoRaMacFrameHeader
|
||||
|
||||
/*! \} addtogroup LORAMAC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LORAMAC_HEADER_TYPES_H__
|
||||
|
@@ -37,43 +37,14 @@
|
||||
#ifndef __LORAMAC_MESSAGE_TYPES_H__
|
||||
#define __LORAMAC_MESSAGE_TYPES_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "LoRaMacHeaderTypes.h"
|
||||
|
||||
|
||||
/*! MAC header field size */
|
||||
#define LORAMAC_MHDR_FIELD_SIZE 1
|
||||
|
||||
/*! Join EUI field size */
|
||||
#define LORAMAC_JOIN_EUI_FIELD_SIZE 8
|
||||
|
||||
/*! Device EUI field size */
|
||||
#define LORAMAC_DEV_EUI_FIELD_SIZE 8
|
||||
|
||||
/*! Join-server nonce field size */
|
||||
#define LORAMAC_JOIN_NONCE_FIELD_SIZE 3
|
||||
|
||||
/*! Network ID field size */
|
||||
#define LORAMAC_NET_ID_FIELD_SIZE 3
|
||||
|
||||
/*! Port field size */
|
||||
#define LORAMAC_F_PORT_FIELD_SIZE 1
|
||||
|
||||
/*! CFList field size */
|
||||
#define LORAMAC_C_FLIST_FIELD_SIZE 16
|
||||
|
||||
/*! MIC field size */
|
||||
#define LORAMAC_MIC_FIELD_SIZE 4
|
||||
|
||||
/*! Join-request message size */
|
||||
#define LORAMAC_JOIN_REQ_MSG_SIZE 23
|
||||
|
||||
/*! ReJoin-request type 1 message size */
|
||||
#define LORAMAC_RE_JOIN_1_MSG_SIZE 24
|
||||
|
||||
/*! ReJoin-request type 0 or 2 message size */
|
||||
#define LORAMAC_RE_JOIN_0_2_MSG_SIZE 19
|
||||
|
||||
/*!
|
||||
* LoRaMac type for Join-request message
|
||||
*/
|
||||
@@ -324,4 +295,8 @@ typedef struct sLoRaMacMessage
|
||||
|
||||
/*! \} addtogroup LORAMAC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LORAMAC_MESSAGE_TYPES_H__
|
||||
|
@@ -47,10 +47,10 @@ LoRaMacParserStatus_t LoRaMacParserJoinAccept( LoRaMacMessageJoinAccept_t* macMs
|
||||
|
||||
macMsg->RxDelay = macMsg->Buffer[bufItr++];
|
||||
|
||||
if( ( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE - bufItr ) == LORAMAC_C_FLIST_FIELD_SIZE )
|
||||
if( ( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE - bufItr ) == LORAMAC_CF_LIST_FIELD_SIZE )
|
||||
{
|
||||
memcpy1( macMsg->CFList, &macMsg->Buffer[bufItr], LORAMAC_C_FLIST_FIELD_SIZE );
|
||||
bufItr = bufItr + LORAMAC_C_FLIST_FIELD_SIZE;
|
||||
memcpy1( macMsg->CFList, &macMsg->Buffer[bufItr], LORAMAC_CF_LIST_FIELD_SIZE );
|
||||
bufItr = bufItr + LORAMAC_CF_LIST_FIELD_SIZE;
|
||||
}
|
||||
else if( ( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE - bufItr ) > 0 )
|
||||
{
|
||||
|
@@ -37,6 +37,11 @@
|
||||
#ifndef __LORAMAC_PARSER_H__
|
||||
#define __LORAMAC_PARSER_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "LoRaMacMessageTypes.h"
|
||||
|
||||
@@ -82,5 +87,9 @@ LoRaMacParserStatus_t LoRaMacParserData( LoRaMacMessageData_t *macMsg );
|
||||
|
||||
/*! \} addtogroup LORAMAC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LORAMAC_PARSER_H__
|
||||
|
||||
|
@@ -107,7 +107,7 @@ LoRaMacSerializerStatus_t LoRaMacSerializerReJoinType0or2( LoRaMacMessageReJoinT
|
||||
|
||||
macMsg->Buffer[bufItr++] = macMsg->ReJoinType;
|
||||
|
||||
memcpyr( &macMsg->Buffer[bufItr], macMsg->NetID, LORAMAC_NET_ID_FIELD_SIZE );
|
||||
memcpy1( &macMsg->Buffer[bufItr], macMsg->NetID, LORAMAC_NET_ID_FIELD_SIZE );
|
||||
bufItr += LORAMAC_NET_ID_FIELD_SIZE;
|
||||
|
||||
memcpyr( &macMsg->Buffer[bufItr], macMsg->DevEUI, LORAMAC_DEV_EUI_FIELD_SIZE );
|
||||
@@ -130,23 +130,23 @@ LoRaMacSerializerStatus_t LoRaMacSerializerData( LoRaMacMessageData_t* macMsg )
|
||||
|
||||
// Check macMsg->BufSize
|
||||
uint16_t computedBufSize = LORAMAC_MHDR_FIELD_SIZE
|
||||
+ LORAMAC_FHDR_DEV_ADD_FIELD_SIZE
|
||||
+ LORAMAC_FHDR_DEV_ADDR_FIELD_SIZE
|
||||
+ LORAMAC_FHDR_F_CTRL_FIELD_SIZE
|
||||
+ LORAMAC_FHDR_F_CNT_FIELD_SIZE;
|
||||
|
||||
if( macMsg->FRMPayloadSize == 0 )
|
||||
computedBufSize += macMsg->FHDR.FCtrl.Bits.FOptsLen;
|
||||
|
||||
if( macMsg->FRMPayloadSize > 0 )
|
||||
{
|
||||
if( macMsg->BufSize < computedBufSize )
|
||||
{
|
||||
return LORAMAC_SERIALIZER_ERROR_BUF_SIZE;
|
||||
}
|
||||
computedBufSize += LORAMAC_F_PORT_FIELD_SIZE;
|
||||
}
|
||||
else
|
||||
{ //If FRMPayload >0, FPort field is present.
|
||||
if( macMsg->BufSize < computedBufSize + macMsg->FHDR.FCtrl.Bits.FOptsLen + macMsg->FRMPayloadSize + LORAMAC_F_PORT_FIELD_SIZE )
|
||||
{
|
||||
return LORAMAC_SERIALIZER_ERROR_BUF_SIZE;
|
||||
}
|
||||
|
||||
computedBufSize += macMsg->FRMPayloadSize;
|
||||
computedBufSize += LORAMAC_MIC_FIELD_SIZE;
|
||||
|
||||
if( macMsg->BufSize < computedBufSize )
|
||||
{
|
||||
return LORAMAC_SERIALIZER_ERROR_BUF_SIZE;
|
||||
}
|
||||
|
||||
macMsg->Buffer[bufItr++] = macMsg->MHDR.Value;
|
||||
|
@@ -36,6 +36,11 @@
|
||||
*/
|
||||
#ifndef __LORAMAC_SERIALIZER_H__
|
||||
#define __LORAMAC_SERIALIZER_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include "LoRaMacMessageTypes.h"
|
||||
|
||||
@@ -97,5 +102,9 @@ LoRaMacSerializerStatus_t LoRaMacSerializerData( LoRaMacMessageData_t* macMsg );
|
||||
|
||||
/*! \} addtogroup LORAMAC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LORAMAC_SERIALIZER_H__
|
||||
|
||||
|
@@ -36,6 +36,11 @@
|
||||
#ifndef __LORAMACTEST_H__
|
||||
#define __LORAMACTEST_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \brief Enabled or disables the duty cycle
|
||||
*
|
||||
@@ -48,4 +53,8 @@ void LoRaMacTestSetDutyCycleOn( bool enable );
|
||||
|
||||
/*! \} defgroup LORAMACTEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LORAMACTEST_H__
|
||||
|
@@ -35,6 +35,11 @@
|
||||
#ifndef __LORAMAC_TYPES_H__
|
||||
#define __LORAMAC_TYPES_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "timer.h"
|
||||
@@ -47,7 +52,34 @@
|
||||
/*!
|
||||
* Start value for multicast keys enumeration
|
||||
*/
|
||||
#define LORAMAC_CRYPTO_MULITCAST_KEYS 127
|
||||
#define LORAMAC_CRYPTO_MULTICAST_KEYS 127
|
||||
|
||||
/*!
|
||||
* LoRaWAN devices classes definition
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 2.1
|
||||
*/
|
||||
typedef enum DeviceClass_e
|
||||
{
|
||||
/*!
|
||||
* LoRaWAN device class A
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 3
|
||||
*/
|
||||
CLASS_A = 0x00,
|
||||
/*!
|
||||
* LoRaWAN device class B
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 8
|
||||
*/
|
||||
CLASS_B = 0x01,
|
||||
/*!
|
||||
* LoRaWAN device class C
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 17
|
||||
*/
|
||||
CLASS_C = 0x02,
|
||||
}DeviceClass_t;
|
||||
|
||||
/*!
|
||||
* LoRaWAN Frame type enumeration to differ between the possible data up/down frame configurations.
|
||||
@@ -162,10 +194,14 @@ typedef enum eKeyIdentifier
|
||||
* Application session key
|
||||
*/
|
||||
APP_S_KEY,
|
||||
/*!
|
||||
* Multicast root key
|
||||
*/
|
||||
MC_ROOT_KEY,
|
||||
/*!
|
||||
* Multicast key encryption key
|
||||
*/
|
||||
MC_KE_KEY = LORAMAC_CRYPTO_MULITCAST_KEYS,
|
||||
MC_KE_KEY = LORAMAC_CRYPTO_MULTICAST_KEYS,
|
||||
/*!
|
||||
* Multicast root key index 0
|
||||
*/
|
||||
@@ -251,40 +287,121 @@ typedef enum eAddressIdentifier
|
||||
UNICAST_DEV_ADDR = 4,
|
||||
}AddressIdentifier_t;
|
||||
|
||||
/*!
|
||||
* Multicast context
|
||||
/*
|
||||
* Multicast Rx window parameters
|
||||
*/
|
||||
typedef struct sMulticastCtx
|
||||
typedef union uMcRxParams
|
||||
{
|
||||
struct
|
||||
{
|
||||
/*!
|
||||
* Reception frequency of the ping slot windows
|
||||
*/
|
||||
uint32_t Frequency;
|
||||
/*!
|
||||
* Datarate of the ping slot
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
* This parameter is necessary for class B operation. It defines the
|
||||
* periodicity of the multicast downlink slots
|
||||
*/
|
||||
uint16_t Periodicity;
|
||||
}ClassB;
|
||||
struct
|
||||
{
|
||||
/*!
|
||||
* Reception frequency of the ping slot windows
|
||||
*/
|
||||
uint32_t Frequency;
|
||||
/*!
|
||||
* Datarate of the ping slot
|
||||
*/
|
||||
int8_t Datarate;
|
||||
}ClassC;
|
||||
}McRxParams_t;
|
||||
|
||||
/*!
|
||||
* Multicast channel
|
||||
*/
|
||||
typedef struct sMcChannelParams
|
||||
{
|
||||
/*!
|
||||
* Indicate if the multicast channel is being setup remotely or locally.
|
||||
* Indicates which set of keys are to be used. \ref uMcKeys
|
||||
*/
|
||||
bool IsRemotelySetup;
|
||||
/*!
|
||||
* Multicats channel LoRaWAN class B or C
|
||||
*/
|
||||
DeviceClass_t Class;
|
||||
/*!
|
||||
* True if the entry is active
|
||||
*/
|
||||
bool IsEnabled;
|
||||
/*
|
||||
* Address identifier
|
||||
*/
|
||||
AddressIdentifier_t AddrID;
|
||||
AddressIdentifier_t GroupID;
|
||||
/*!
|
||||
* Address
|
||||
*/
|
||||
uint32_t Address;
|
||||
/*!
|
||||
* Multicast keys
|
||||
*/
|
||||
union uMcKeys
|
||||
{
|
||||
/*!
|
||||
* Encrypted multicast key - Used when IsRemotelySetup equals `true`.
|
||||
* MC_KEY is decrypted and then the session keys ar derived.
|
||||
*/
|
||||
uint8_t *McKeyE;
|
||||
/*!
|
||||
* Multicast Session keys - Used when IsRemotelySetup equals `false`
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/*!
|
||||
* Multicast application session key
|
||||
*/
|
||||
uint8_t *McAppSKey;
|
||||
/*!
|
||||
* Multicast network session key
|
||||
*/
|
||||
uint8_t *McNwkSKey;
|
||||
}Session;
|
||||
}McKeys;
|
||||
/*!
|
||||
* Minimum multicast frame counter value
|
||||
*/
|
||||
uint32_t FCountMin;
|
||||
/*!
|
||||
* Maximum multicast frame counter value
|
||||
*/
|
||||
uint32_t FCountMax;
|
||||
/*!
|
||||
* Multicast reception parameters
|
||||
*/
|
||||
McRxParams_t RxParams;
|
||||
}McChannelParams_t;
|
||||
|
||||
/*!
|
||||
* Multicast context
|
||||
*/
|
||||
typedef struct sMulticastCtx
|
||||
{
|
||||
/*!
|
||||
* Multicast channel parameters
|
||||
*/
|
||||
McChannelParams_t ChannelParams;
|
||||
/*!
|
||||
* Downlink counter
|
||||
*/
|
||||
uint32_t* DownLinkCounter;
|
||||
/*!
|
||||
* True if the entry is active
|
||||
/*
|
||||
* Following parameters are only used for ClassB multicast channels
|
||||
*/
|
||||
bool IsEnabled;
|
||||
/*!
|
||||
* Reception frequency of the ping slot windows
|
||||
*/
|
||||
uint32_t Frequency;
|
||||
/*!
|
||||
* Datarate of the ping slot
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
* This parameter is necessary for class b operation. It defines the
|
||||
* periodicity of the multicast downlink slots
|
||||
*/
|
||||
uint16_t Periodicity;
|
||||
/*!
|
||||
* Number of multicast slots. The variable can be
|
||||
* calculated as follows:
|
||||
@@ -475,17 +592,24 @@ typedef struct sBand
|
||||
*/
|
||||
int8_t TxMaxPower;
|
||||
/*!
|
||||
* Time stamp of the last JoinReq Tx frame.
|
||||
* The last time the band has been
|
||||
* synchronized with the current time
|
||||
*/
|
||||
TimerTime_t LastJoinTxDoneTime;
|
||||
TimerTime_t LastBandUpdateTime;
|
||||
/*!
|
||||
* Time stamp of the last Tx frame
|
||||
* Current time credits which are available. This
|
||||
* is a value in ms
|
||||
*/
|
||||
TimerTime_t LastTxDoneTime;
|
||||
TimerTime_t TimeCredits;
|
||||
/*!
|
||||
* Holds the time where the device is off
|
||||
* Maximum time credits which are available. This
|
||||
* is a value in ms
|
||||
*/
|
||||
TimerTime_t TimeOff;
|
||||
TimerTime_t MaxTimeCredits;
|
||||
/*!
|
||||
* Set to true when the band is ready for use.
|
||||
*/
|
||||
bool ReadyForTransmission;
|
||||
}Band_t;
|
||||
|
||||
/*!
|
||||
@@ -548,5 +672,9 @@ typedef enum eLoRaMacBatteryLevel
|
||||
BAT_LEVEL_NO_MEASURE = 0xFF,
|
||||
}LoRaMacBatteryLevel_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LORAMAC_TYPES_H__
|
||||
|
||||
|
@@ -51,7 +51,6 @@
|
||||
#define AS923_TX_PARAM_SETUP_REQ( ) AS923_CASE { return RegionAS923TxParamSetupReq( txParamSetupReq ); }
|
||||
#define AS923_DL_CHANNEL_REQ( ) AS923_CASE { return RegionAS923DlChannelReq( dlChannelReq ); }
|
||||
#define AS923_ALTERNATE_DR( ) AS923_CASE { return RegionAS923AlternateDr( currentDr, type ); }
|
||||
#define AS923_CALC_BACKOFF( ) AS923_CASE { RegionAS923CalcBackOff( calcBackOff ); break; }
|
||||
#define AS923_NEXT_CHANNEL( ) AS923_CASE { return RegionAS923NextChannel( nextChanParams, channel, time, aggregatedTimeOff ); }
|
||||
#define AS923_CHANNEL_ADD( ) AS923_CASE { return RegionAS923ChannelAdd( channelAdd ); }
|
||||
#define AS923_CHANNEL_REMOVE( ) AS923_CASE { return RegionAS923ChannelsRemove( channelRemove ); }
|
||||
@@ -76,7 +75,6 @@
|
||||
#define AS923_TX_PARAM_SETUP_REQ( )
|
||||
#define AS923_DL_CHANNEL_REQ( )
|
||||
#define AS923_ALTERNATE_DR( )
|
||||
#define AS923_CALC_BACKOFF( )
|
||||
#define AS923_NEXT_CHANNEL( )
|
||||
#define AS923_CHANNEL_ADD( )
|
||||
#define AS923_CHANNEL_REMOVE( )
|
||||
@@ -105,7 +103,6 @@
|
||||
#define AU915_TX_PARAM_SETUP_REQ( ) AU915_CASE { return RegionAU915TxParamSetupReq( txParamSetupReq ); }
|
||||
#define AU915_DL_CHANNEL_REQ( ) AU915_CASE { return RegionAU915DlChannelReq( dlChannelReq ); }
|
||||
#define AU915_ALTERNATE_DR( ) AU915_CASE { return RegionAU915AlternateDr( currentDr, type ); }
|
||||
#define AU915_CALC_BACKOFF( ) AU915_CASE { RegionAU915CalcBackOff( calcBackOff ); break; }
|
||||
#define AU915_NEXT_CHANNEL( ) AU915_CASE { return RegionAU915NextChannel( nextChanParams, channel, time, aggregatedTimeOff ); }
|
||||
#define AU915_CHANNEL_ADD( ) AU915_CASE { return RegionAU915ChannelAdd( channelAdd ); }
|
||||
#define AU915_CHANNEL_REMOVE( ) AU915_CASE { return RegionAU915ChannelsRemove( channelRemove ); }
|
||||
@@ -130,7 +127,6 @@
|
||||
#define AU915_TX_PARAM_SETUP_REQ( )
|
||||
#define AU915_DL_CHANNEL_REQ( )
|
||||
#define AU915_ALTERNATE_DR( )
|
||||
#define AU915_CALC_BACKOFF( )
|
||||
#define AU915_NEXT_CHANNEL( )
|
||||
#define AU915_CHANNEL_ADD( )
|
||||
#define AU915_CHANNEL_REMOVE( )
|
||||
@@ -159,7 +155,6 @@
|
||||
#define CN470_TX_PARAM_SETUP_REQ( ) CN470_CASE { return RegionCN470TxParamSetupReq( txParamSetupReq ); }
|
||||
#define CN470_DL_CHANNEL_REQ( ) CN470_CASE { return RegionCN470DlChannelReq( dlChannelReq ); }
|
||||
#define CN470_ALTERNATE_DR( ) CN470_CASE { return RegionCN470AlternateDr( currentDr, type ); }
|
||||
#define CN470_CALC_BACKOFF( ) CN470_CASE { RegionCN470CalcBackOff( calcBackOff ); break; }
|
||||
#define CN470_NEXT_CHANNEL( ) CN470_CASE { return RegionCN470NextChannel( nextChanParams, channel, time, aggregatedTimeOff ); }
|
||||
#define CN470_CHANNEL_ADD( ) CN470_CASE { return RegionCN470ChannelAdd( channelAdd ); }
|
||||
#define CN470_CHANNEL_REMOVE( ) CN470_CASE { return RegionCN470ChannelsRemove( channelRemove ); }
|
||||
@@ -184,7 +179,6 @@
|
||||
#define CN470_TX_PARAM_SETUP_REQ( )
|
||||
#define CN470_DL_CHANNEL_REQ( )
|
||||
#define CN470_ALTERNATE_DR( )
|
||||
#define CN470_CALC_BACKOFF( )
|
||||
#define CN470_NEXT_CHANNEL( )
|
||||
#define CN470_CHANNEL_ADD( )
|
||||
#define CN470_CHANNEL_REMOVE( )
|
||||
@@ -213,7 +207,6 @@
|
||||
#define CN779_TX_PARAM_SETUP_REQ( ) CN779_CASE { return RegionCN779TxParamSetupReq( txParamSetupReq ); }
|
||||
#define CN779_DL_CHANNEL_REQ( ) CN779_CASE { return RegionCN779DlChannelReq( dlChannelReq ); }
|
||||
#define CN779_ALTERNATE_DR( ) CN779_CASE { return RegionCN779AlternateDr( currentDr, type ); }
|
||||
#define CN779_CALC_BACKOFF( ) CN779_CASE { RegionCN779CalcBackOff( calcBackOff ); break; }
|
||||
#define CN779_NEXT_CHANNEL( ) CN779_CASE { return RegionCN779NextChannel( nextChanParams, channel, time, aggregatedTimeOff ); }
|
||||
#define CN779_CHANNEL_ADD( ) CN779_CASE { return RegionCN779ChannelAdd( channelAdd ); }
|
||||
#define CN779_CHANNEL_REMOVE( ) CN779_CASE { return RegionCN779ChannelsRemove( channelRemove ); }
|
||||
@@ -238,7 +231,6 @@
|
||||
#define CN779_TX_PARAM_SETUP_REQ( )
|
||||
#define CN779_DL_CHANNEL_REQ( )
|
||||
#define CN779_ALTERNATE_DR( )
|
||||
#define CN779_CALC_BACKOFF( )
|
||||
#define CN779_NEXT_CHANNEL( )
|
||||
#define CN779_CHANNEL_ADD( )
|
||||
#define CN779_CHANNEL_REMOVE( )
|
||||
@@ -267,7 +259,6 @@
|
||||
#define EU433_TX_PARAM_SETUP_REQ( ) EU433_CASE { return RegionEU433TxParamSetupReq( txParamSetupReq ); }
|
||||
#define EU433_DL_CHANNEL_REQ( ) EU433_CASE { return RegionEU433DlChannelReq( dlChannelReq ); }
|
||||
#define EU433_ALTERNATE_DR( ) EU433_CASE { return RegionEU433AlternateDr( currentDr, type ); }
|
||||
#define EU433_CALC_BACKOFF( ) EU433_CASE { RegionEU433CalcBackOff( calcBackOff ); break; }
|
||||
#define EU433_NEXT_CHANNEL( ) EU433_CASE { return RegionEU433NextChannel( nextChanParams, channel, time, aggregatedTimeOff ); }
|
||||
#define EU433_CHANNEL_ADD( ) EU433_CASE { return RegionEU433ChannelAdd( channelAdd ); }
|
||||
#define EU433_CHANNEL_REMOVE( ) EU433_CASE { return RegionEU433ChannelsRemove( channelRemove ); }
|
||||
@@ -292,7 +283,6 @@
|
||||
#define EU433_TX_PARAM_SETUP_REQ( )
|
||||
#define EU433_DL_CHANNEL_REQ( )
|
||||
#define EU433_ALTERNATE_DR( )
|
||||
#define EU433_CALC_BACKOFF( )
|
||||
#define EU433_NEXT_CHANNEL( )
|
||||
#define EU433_CHANNEL_ADD( )
|
||||
#define EU433_CHANNEL_REMOVE( )
|
||||
@@ -321,7 +311,6 @@
|
||||
#define EU868_TX_PARAM_SETUP_REQ( ) EU868_CASE { return RegionEU868TxParamSetupReq( txParamSetupReq ); }
|
||||
#define EU868_DL_CHANNEL_REQ( ) EU868_CASE { return RegionEU868DlChannelReq( dlChannelReq ); }
|
||||
#define EU868_ALTERNATE_DR( ) EU868_CASE { return RegionEU868AlternateDr( currentDr, type ); }
|
||||
#define EU868_CALC_BACKOFF( ) EU868_CASE { RegionEU868CalcBackOff( calcBackOff ); break; }
|
||||
#define EU868_NEXT_CHANNEL( ) EU868_CASE { return RegionEU868NextChannel( nextChanParams, channel, time, aggregatedTimeOff ); }
|
||||
#define EU868_CHANNEL_ADD( ) EU868_CASE { return RegionEU868ChannelAdd( channelAdd ); }
|
||||
#define EU868_CHANNEL_REMOVE( ) EU868_CASE { return RegionEU868ChannelsRemove( channelRemove ); }
|
||||
@@ -346,7 +335,6 @@
|
||||
#define EU868_TX_PARAM_SETUP_REQ( )
|
||||
#define EU868_DL_CHANNEL_REQ( )
|
||||
#define EU868_ALTERNATE_DR( )
|
||||
#define EU868_CALC_BACKOFF( )
|
||||
#define EU868_NEXT_CHANNEL( )
|
||||
#define EU868_CHANNEL_ADD( )
|
||||
#define EU868_CHANNEL_REMOVE( )
|
||||
@@ -375,7 +363,6 @@
|
||||
#define KR920_TX_PARAM_SETUP_REQ( ) KR920_CASE { return RegionKR920TxParamSetupReq( txParamSetupReq ); }
|
||||
#define KR920_DL_CHANNEL_REQ( ) KR920_CASE { return RegionKR920DlChannelReq( dlChannelReq ); }
|
||||
#define KR920_ALTERNATE_DR( ) KR920_CASE { return RegionKR920AlternateDr( currentDr, type ); }
|
||||
#define KR920_CALC_BACKOFF( ) KR920_CASE { RegionKR920CalcBackOff( calcBackOff ); break; }
|
||||
#define KR920_NEXT_CHANNEL( ) KR920_CASE { return RegionKR920NextChannel( nextChanParams, channel, time, aggregatedTimeOff ); }
|
||||
#define KR920_CHANNEL_ADD( ) KR920_CASE { return RegionKR920ChannelAdd( channelAdd ); }
|
||||
#define KR920_CHANNEL_REMOVE( ) KR920_CASE { return RegionKR920ChannelsRemove( channelRemove ); }
|
||||
@@ -400,7 +387,6 @@
|
||||
#define KR920_TX_PARAM_SETUP_REQ( )
|
||||
#define KR920_DL_CHANNEL_REQ( )
|
||||
#define KR920_ALTERNATE_DR( )
|
||||
#define KR920_CALC_BACKOFF( )
|
||||
#define KR920_NEXT_CHANNEL( )
|
||||
#define KR920_CHANNEL_ADD( )
|
||||
#define KR920_CHANNEL_REMOVE( )
|
||||
@@ -429,7 +415,6 @@
|
||||
#define IN865_TX_PARAM_SETUP_REQ( ) IN865_CASE { return RegionIN865TxParamSetupReq( txParamSetupReq ); }
|
||||
#define IN865_DL_CHANNEL_REQ( ) IN865_CASE { return RegionIN865DlChannelReq( dlChannelReq ); }
|
||||
#define IN865_ALTERNATE_DR( ) IN865_CASE { return RegionIN865AlternateDr( currentDr, type ); }
|
||||
#define IN865_CALC_BACKOFF( ) IN865_CASE { RegionIN865CalcBackOff( calcBackOff ); break; }
|
||||
#define IN865_NEXT_CHANNEL( ) IN865_CASE { return RegionIN865NextChannel( nextChanParams, channel, time, aggregatedTimeOff ); }
|
||||
#define IN865_CHANNEL_ADD( ) IN865_CASE { return RegionIN865ChannelAdd( channelAdd ); }
|
||||
#define IN865_CHANNEL_REMOVE( ) IN865_CASE { return RegionIN865ChannelsRemove( channelRemove ); }
|
||||
@@ -454,7 +439,6 @@
|
||||
#define IN865_TX_PARAM_SETUP_REQ( )
|
||||
#define IN865_DL_CHANNEL_REQ( )
|
||||
#define IN865_ALTERNATE_DR( )
|
||||
#define IN865_CALC_BACKOFF( )
|
||||
#define IN865_NEXT_CHANNEL( )
|
||||
#define IN865_CHANNEL_ADD( )
|
||||
#define IN865_CHANNEL_REMOVE( )
|
||||
@@ -483,7 +467,6 @@
|
||||
#define US915_TX_PARAM_SETUP_REQ( ) US915_CASE { return RegionUS915TxParamSetupReq( txParamSetupReq ); }
|
||||
#define US915_DL_CHANNEL_REQ( ) US915_CASE { return RegionUS915DlChannelReq( dlChannelReq ); }
|
||||
#define US915_ALTERNATE_DR( ) US915_CASE { return RegionUS915AlternateDr( currentDr, type ); }
|
||||
#define US915_CALC_BACKOFF( ) US915_CASE { RegionUS915CalcBackOff( calcBackOff ); break; }
|
||||
#define US915_NEXT_CHANNEL( ) US915_CASE { return RegionUS915NextChannel( nextChanParams, channel, time, aggregatedTimeOff ); }
|
||||
#define US915_CHANNEL_ADD( ) US915_CASE { return RegionUS915ChannelAdd( channelAdd ); }
|
||||
#define US915_CHANNEL_REMOVE( ) US915_CASE { return RegionUS915ChannelsRemove( channelRemove ); }
|
||||
@@ -508,7 +491,6 @@
|
||||
#define US915_TX_PARAM_SETUP_REQ( )
|
||||
#define US915_DL_CHANNEL_REQ( )
|
||||
#define US915_ALTERNATE_DR( )
|
||||
#define US915_CALC_BACKOFF( )
|
||||
#define US915_NEXT_CHANNEL( )
|
||||
#define US915_CHANNEL_ADD( )
|
||||
#define US915_CHANNEL_REMOVE( )
|
||||
@@ -537,7 +519,6 @@
|
||||
#define RU864_TX_PARAM_SETUP_REQ( ) RU864_CASE { return RegionRU864TxParamSetupReq( txParamSetupReq ); }
|
||||
#define RU864_DL_CHANNEL_REQ( ) RU864_CASE { return RegionRU864DlChannelReq( dlChannelReq ); }
|
||||
#define RU864_ALTERNATE_DR( ) RU864_CASE { return RegionRU864AlternateDr( currentDr, type ); }
|
||||
#define RU864_CALC_BACKOFF( ) RU864_CASE { RegionRU864CalcBackOff( calcBackOff ); break; }
|
||||
#define RU864_NEXT_CHANNEL( ) RU864_CASE { return RegionRU864NextChannel( nextChanParams, channel, time, aggregatedTimeOff ); }
|
||||
#define RU864_CHANNEL_ADD( ) RU864_CASE { return RegionRU864ChannelAdd( channelAdd ); }
|
||||
#define RU864_CHANNEL_REMOVE( ) RU864_CASE { return RegionRU864ChannelsRemove( channelRemove ); }
|
||||
@@ -562,7 +543,6 @@
|
||||
#define RU864_TX_PARAM_SETUP_REQ( )
|
||||
#define RU864_DL_CHANNEL_REQ( )
|
||||
#define RU864_ALTERNATE_DR( )
|
||||
#define RU864_CALC_BACKOFF( )
|
||||
#define RU864_NEXT_CHANNEL( )
|
||||
#define RU864_CHANNEL_ADD( )
|
||||
#define RU864_CHANNEL_REMOVE( )
|
||||
@@ -929,27 +909,6 @@ int8_t RegionAlternateDr( LoRaMacRegion_t region, int8_t currentDr, AlternateDrT
|
||||
}
|
||||
}
|
||||
|
||||
void RegionCalcBackOff( LoRaMacRegion_t region, CalcBackOffParams_t* calcBackOff )
|
||||
{
|
||||
switch( region )
|
||||
{
|
||||
AS923_CALC_BACKOFF( );
|
||||
AU915_CALC_BACKOFF( );
|
||||
CN470_CALC_BACKOFF( );
|
||||
CN779_CALC_BACKOFF( );
|
||||
EU433_CALC_BACKOFF( );
|
||||
EU868_CALC_BACKOFF( );
|
||||
KR920_CALC_BACKOFF( );
|
||||
IN865_CALC_BACKOFF( );
|
||||
US915_CALC_BACKOFF( );
|
||||
RU864_CALC_BACKOFF( );
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionNextChannel( LoRaMacRegion_t region, NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff )
|
||||
{
|
||||
switch( region )
|
||||
@@ -1075,3 +1034,13 @@ void RegionRxBeaconSetup( LoRaMacRegion_t region, RxBeaconSetup_t* rxBeaconSetup
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Version_t RegionGetVersion( void )
|
||||
{
|
||||
Version_t version;
|
||||
|
||||
version.Value = REGION_VERSION;
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
|
@@ -52,17 +52,32 @@
|
||||
#ifndef __REGION_H__
|
||||
#define __REGION_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "utilities.h"
|
||||
#include "LoRaMac.h"
|
||||
#include "timer.h"
|
||||
#include "RegionCommon.h"
|
||||
|
||||
/*!
|
||||
* Macro to compute bit of a channel index.
|
||||
*/
|
||||
#define LC( channelIndex ) ( uint16_t )( 1 << ( channelIndex - 1 ) )
|
||||
|
||||
#ifndef REGION_VERSION
|
||||
/*!
|
||||
* Regional parameters version definition.
|
||||
*/
|
||||
#define REGION_VERSION 0x00010003
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* Region | SF
|
||||
* ------------ | :-----:
|
||||
@@ -476,7 +491,7 @@
|
||||
* EU868 | -
|
||||
* IN865 | Max EIRP - 18
|
||||
* KR920 | -
|
||||
* US915 | Max ERP - 16
|
||||
* US915 | Max ERP - 18
|
||||
* RU864 | -
|
||||
*/
|
||||
#define TX_POWER_9 9
|
||||
@@ -492,28 +507,72 @@
|
||||
* EU868 | -
|
||||
* IN865 | Max EIRP - 20
|
||||
* KR920 | -
|
||||
* US915 | Max ERP - 10
|
||||
* US915 | Max ERP - 20
|
||||
* RU864 | -
|
||||
*/
|
||||
#define TX_POWER_10 10
|
||||
|
||||
/*!
|
||||
* RFU
|
||||
* Region | dBM
|
||||
* ------------ | :-----:
|
||||
* AS923 | -
|
||||
* AU915 | Max EIRP - 22
|
||||
* CN470 | -
|
||||
* CN779 | -
|
||||
* EU433 | -
|
||||
* EU868 | -
|
||||
* IN865 | -
|
||||
* KR920 | -
|
||||
* US915 | Max ERP - 22
|
||||
* RU864 | -
|
||||
*/
|
||||
#define TX_POWER_11 11
|
||||
|
||||
/*!
|
||||
* RFU
|
||||
* Region | dBM
|
||||
* ------------ | :-----:
|
||||
* AS923 | -
|
||||
* AU915 | Max EIRP - 24
|
||||
* CN470 | -
|
||||
* CN779 | -
|
||||
* EU433 | -
|
||||
* EU868 | -
|
||||
* IN865 | -
|
||||
* KR920 | -
|
||||
* US915 | Max ERP - 24
|
||||
* RU864 | -
|
||||
*/
|
||||
#define TX_POWER_12 12
|
||||
|
||||
/*!
|
||||
* RFU
|
||||
* Region | dBM
|
||||
* ------------ | :-----:
|
||||
* AS923 | -
|
||||
* AU915 | Max EIRP - 26
|
||||
* CN470 | -
|
||||
* CN779 | -
|
||||
* EU433 | -
|
||||
* EU868 | -
|
||||
* IN865 | -
|
||||
* KR920 | -
|
||||
* US915 | Max ERP - 26
|
||||
* RU864 | -
|
||||
*/
|
||||
#define TX_POWER_13 13
|
||||
|
||||
/*!
|
||||
* RFU
|
||||
* Region | dBM
|
||||
* ------------ | :-----:
|
||||
* AS923 | -
|
||||
* AU915 | Max EIRP - 28
|
||||
* CN470 | -
|
||||
* CN779 | -
|
||||
* EU433 | -
|
||||
* EU868 | -
|
||||
* IN865 | -
|
||||
* KR920 | -
|
||||
* US915 | Max ERP - 28
|
||||
* RU864 | -
|
||||
*/
|
||||
#define TX_POWER_14 14
|
||||
|
||||
@@ -529,6 +588,11 @@
|
||||
*/
|
||||
typedef enum ePhyAttribute
|
||||
{
|
||||
/*!
|
||||
* Frequency. It is available
|
||||
* to perform a verification with RegionVerify().
|
||||
*/
|
||||
PHY_FREQUENCY,
|
||||
/*!
|
||||
* Minimum RX datarate.
|
||||
*/
|
||||
@@ -585,10 +649,6 @@ typedef enum ePhyAttribute
|
||||
* Maximum payload possible.
|
||||
*/
|
||||
PHY_MAX_PAYLOAD,
|
||||
/*!
|
||||
* Maximum payload possible when repeater support is enabled.
|
||||
*/
|
||||
PHY_MAX_PAYLOAD_REPEATER,
|
||||
/*!
|
||||
* Duty cycle.
|
||||
*/
|
||||
@@ -743,10 +803,26 @@ typedef enum ePhyAttribute
|
||||
* The number of channels for the beacon reception.
|
||||
*/
|
||||
PHY_BEACON_NB_CHANNELS,
|
||||
/*!
|
||||
* Ping slot channel frequency.
|
||||
*/
|
||||
PHY_PING_SLOT_CHANNEL_FREQ,
|
||||
/*!
|
||||
* The datarate of a ping slot channel.
|
||||
*/
|
||||
PHY_PING_SLOT_CHANNEL_DR
|
||||
PHY_PING_SLOT_CHANNEL_DR,
|
||||
/*
|
||||
* The number of channels for the ping slot reception.
|
||||
*/
|
||||
PHY_PING_SLOT_NB_CHANNELS,
|
||||
/*!
|
||||
* The equivalent spreading factor value from datarate
|
||||
*/
|
||||
PHY_SF_FROM_DR,
|
||||
/*!
|
||||
* The equivalent bandwith index from datarate
|
||||
*/
|
||||
PHY_BW_FROM_DR,
|
||||
}PhyAttribute_t;
|
||||
|
||||
/*!
|
||||
@@ -754,6 +830,10 @@ typedef enum ePhyAttribute
|
||||
*/
|
||||
typedef enum eInitType
|
||||
{
|
||||
/*!
|
||||
* Initializes the band definitions.
|
||||
*/
|
||||
INIT_TYPE_BANDS,
|
||||
/*!
|
||||
* Initializes the region specific data to defaults, according to the
|
||||
* LoRaWAN specification.
|
||||
@@ -825,6 +905,10 @@ typedef union uPhyParam
|
||||
* Beacon format
|
||||
*/
|
||||
BeaconFormat_t BeaconFormat;
|
||||
/*!
|
||||
* Duty Cycle Period
|
||||
*/
|
||||
TimerTime_t DutyCycleTimePeriod;
|
||||
}PhyParam_t;
|
||||
|
||||
/*!
|
||||
@@ -839,23 +923,29 @@ typedef struct sGetPhyParams
|
||||
/*!
|
||||
* Datarate.
|
||||
* The parameter is needed for the following queries:
|
||||
* PHY_MAX_PAYLOAD, PHY_MAX_PAYLOAD_REPEATER, PHY_NEXT_LOWER_TX_DR.
|
||||
* PHY_MAX_PAYLOAD, PHY_NEXT_LOWER_TX_DR, PHY_SF_FROM_DR, PHY_BW_FROM_DR.
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
* Uplink dwell time. This parameter must be set to query:
|
||||
* PHY_MAX_PAYLOAD, PHY_MAX_PAYLOAD_REPEATER, PHY_MIN_TX_DR.
|
||||
* PHY_MAX_PAYLOAD, PHY_MIN_TX_DR.
|
||||
* The parameter is needed for the following queries:
|
||||
* PHY_MIN_TX_DR, PHY_MAX_PAYLOAD, PHY_MAX_PAYLOAD_REPEATER, PHY_NEXT_LOWER_TX_DR.
|
||||
* PHY_MIN_TX_DR, PHY_MAX_PAYLOAD, PHY_NEXT_LOWER_TX_DR.
|
||||
*/
|
||||
uint8_t UplinkDwellTime;
|
||||
/*!
|
||||
* Downlink dwell time. This parameter must be set to query:
|
||||
* PHY_MAX_PAYLOAD, PHY_MAX_PAYLOAD_REPEATER, PHY_MIN_RX_DR.
|
||||
* PHY_MAX_PAYLOAD, PHY_MIN_RX_DR.
|
||||
* The parameter is needed for the following queries:
|
||||
* PHY_MIN_RX_DR, PHY_MAX_PAYLOAD, PHY_MAX_PAYLOAD_REPEATER.
|
||||
* PHY_MIN_RX_DR, PHY_MAX_PAYLOAD.
|
||||
*/
|
||||
uint8_t DownlinkDwellTime;
|
||||
/*!
|
||||
* Specification of the downlink channel. Used in Class B only.
|
||||
* The parameter is needed for the following queries:
|
||||
* PHY_BEACON_CHANNEL_FREQ, PHY_PING_SLOT_CHANNEL_FREQ
|
||||
*/
|
||||
uint8_t Channel;
|
||||
}GetPhyParams_t;
|
||||
|
||||
/*!
|
||||
@@ -875,6 +965,14 @@ typedef struct sSetBandTxDoneParams
|
||||
* Last TX done time.
|
||||
*/
|
||||
TimerTime_t LastTxDoneTime;
|
||||
/*!
|
||||
* Time-on-air of the last transmission.
|
||||
*/
|
||||
TimerTime_t LastTxAirTime;
|
||||
/*!
|
||||
* Elapsed time since initialization.
|
||||
*/
|
||||
SysTime_t ElapsedTimeSinceStartUp;
|
||||
}SetBandTxDoneParams_t;
|
||||
|
||||
/*!
|
||||
@@ -909,6 +1007,10 @@ typedef struct sGetNvmCtxParams
|
||||
*/
|
||||
typedef union uVerifyParams
|
||||
{
|
||||
/*!
|
||||
* Channel frequency to verify
|
||||
*/
|
||||
uint32_t Frequency;
|
||||
/*!
|
||||
* TX power to verify.
|
||||
*/
|
||||
@@ -1004,10 +1106,6 @@ typedef struct sRxConfigParams
|
||||
* Downlink dwell time.
|
||||
*/
|
||||
uint8_t DownlinkDwellTime;
|
||||
/*!
|
||||
* Set to true, if a repeater is supported.
|
||||
*/
|
||||
bool RepeaterSupport;
|
||||
/*!
|
||||
* Set to true, if RX should be continuous.
|
||||
*/
|
||||
@@ -1171,37 +1269,6 @@ typedef enum eAlternateDrType
|
||||
ALTERNATE_DR_RESTORE
|
||||
}AlternateDrType_t;
|
||||
|
||||
/*!
|
||||
* Parameter structure for the function RegionCalcBackOff.
|
||||
*/
|
||||
typedef struct sCalcBackOffParams
|
||||
{
|
||||
/*!
|
||||
* Set to true, if the node has already joined a network, otherwise false.
|
||||
*/
|
||||
bool Joined;
|
||||
/*!
|
||||
* Joined Set to true, if the last uplink was a join request
|
||||
*/
|
||||
bool LastTxIsJoinRequest;
|
||||
/*!
|
||||
* Set to true, if the duty cycle is enabled, otherwise false.
|
||||
*/
|
||||
bool DutyCycleEnabled;
|
||||
/*!
|
||||
* Current channel index.
|
||||
*/
|
||||
uint8_t Channel;
|
||||
/*!
|
||||
* Elapsed time since the start of the node.
|
||||
*/
|
||||
SysTime_t ElapsedTime;
|
||||
/*!
|
||||
* Time-on-air of the last transmission.
|
||||
*/
|
||||
TimerTime_t TxTimeOnAir;
|
||||
}CalcBackOffParams_t;
|
||||
|
||||
/*!
|
||||
* Parameter structure for the function RegionNextChannel.
|
||||
*/
|
||||
@@ -1227,6 +1294,18 @@ typedef struct sNextChanParams
|
||||
* Set to true, if the duty cycle is enabled, otherwise false.
|
||||
*/
|
||||
bool DutyCycleEnabled;
|
||||
/*!
|
||||
* Elapsed time since the start of the node.
|
||||
*/
|
||||
SysTime_t ElapsedTimeSinceStartUp;
|
||||
/*!
|
||||
* Joined Set to true, if the last uplink was a join request
|
||||
*/
|
||||
bool LastTxIsJoinRequest;
|
||||
/*!
|
||||
* Payload length of the next frame
|
||||
*/
|
||||
uint16_t PktLen;
|
||||
}NextChanParams_t;
|
||||
|
||||
/*!
|
||||
@@ -1552,15 +1631,6 @@ uint8_t RegionDlChannelReq( LoRaMacRegion_t region, DlChannelReqParams_t* dlChan
|
||||
*/
|
||||
int8_t RegionAlternateDr( LoRaMacRegion_t region, int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] region LoRaWAN region.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionCalcBackOff( LoRaMacRegion_t region, CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
@@ -1630,6 +1700,17 @@ uint8_t RegionApplyDrOffset( LoRaMacRegion_t region, uint8_t downlinkDwellTime,
|
||||
*/
|
||||
void RegionRxBeaconSetup( LoRaMacRegion_t region, RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*!
|
||||
* \brief Gets the version of the regional parameters implementation.
|
||||
*
|
||||
* \retval Version of the regional parameters.
|
||||
*/
|
||||
Version_t RegionGetVersion( void );
|
||||
|
||||
/*! \} defgroup REGION */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __REGION_H__
|
||||
|
@@ -119,45 +119,21 @@ static bool VerifyRfFreq( uint32_t freq )
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx )
|
||||
static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTransmission = 0;
|
||||
int8_t phyDr = DataratesAS923[datarate];
|
||||
uint32_t bandwidth = GetBandwidth( datarate );
|
||||
TimerTime_t timeOnAir = 0;
|
||||
|
||||
for( uint8_t i = 0, k = 0; i < AS923_MAX_NB_CHANNELS; i += 16, k++ )
|
||||
{
|
||||
for( uint8_t j = 0; j < 16; j++ )
|
||||
{
|
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 )
|
||||
{
|
||||
if( channels[i + j].Frequency == 0 )
|
||||
{ // Check if the channel is enabled
|
||||
continue;
|
||||
}
|
||||
if( joined == false )
|
||||
{
|
||||
if( ( AS923_JOIN_CHANNELS & ( 1 << j ) ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min,
|
||||
channels[i + j].DrRange.Fields.Max ) == false )
|
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue;
|
||||
}
|
||||
if( bands[channels[i + j].Band].TimeOff > 0 )
|
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++;
|
||||
continue;
|
||||
}
|
||||
enabledChannels[nbEnabledChannels++] = i + j;
|
||||
}
|
||||
}
|
||||
if( datarate == DR_7 )
|
||||
{ // High Speed FSK channel
|
||||
timeOnAir = Radio.TimeOnAir( MODEM_FSK, bandwidth, phyDr * 1000, 0, 5, false, pktLen, true );
|
||||
}
|
||||
|
||||
*delayTx = delayTransmission;
|
||||
return nbEnabledChannels;
|
||||
else
|
||||
{
|
||||
timeOnAir = Radio.TimeOnAir( MODEM_LORA, bandwidth, phyDr, 1, 8, false, pktLen, true );
|
||||
}
|
||||
return timeOnAir;
|
||||
}
|
||||
|
||||
PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy )
|
||||
@@ -239,18 +215,6 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy )
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_PAYLOAD_REPEATER:
|
||||
{
|
||||
if( getPhy->UplinkDwellTime == 0 )
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterDwell0AS923[getPhy->Datarate];
|
||||
}
|
||||
else
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateDwell1UpAS923[getPhy->Datarate];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PHY_DUTY_CYCLE:
|
||||
{
|
||||
phyParam.Value = AS923_DUTY_CYCLE_ENABLED;
|
||||
@@ -363,11 +327,26 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = AS923_BEACON_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_FREQ:
|
||||
{
|
||||
phyParam.Value = AS923_PING_SLOT_CHANNEL_FREQ;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_DR:
|
||||
{
|
||||
phyParam.Value = AS923_PING_SLOT_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_SF_FROM_DR:
|
||||
{
|
||||
phyParam.Value = DataratesAS923[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_BW_FROM_DR:
|
||||
{
|
||||
phyParam.Value = GetBandwidth( getPhy->Datarate );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
@@ -379,7 +358,8 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy )
|
||||
|
||||
void RegionAS923SetBandTxDone( SetBandTxDoneParams_t* txDone )
|
||||
{
|
||||
RegionCommonSetBandTxDone( txDone->Joined, &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxDoneTime );
|
||||
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band],
|
||||
txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );
|
||||
}
|
||||
|
||||
void RegionAS923InitDefaults( InitDefaultsParams_t* params )
|
||||
@@ -391,10 +371,14 @@ void RegionAS923InitDefaults( InitDefaultsParams_t* params )
|
||||
|
||||
switch( params->Type )
|
||||
{
|
||||
case INIT_TYPE_INIT:
|
||||
case INIT_TYPE_BANDS:
|
||||
{
|
||||
// Initialize bands
|
||||
memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * AS923_MAX_NB_BANDS );
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_INIT:
|
||||
{
|
||||
|
||||
// Channels
|
||||
NvmCtx.Channels[0] = ( ChannelParams_t ) AS923_LC1;
|
||||
@@ -402,6 +386,7 @@ void RegionAS923InitDefaults( InitDefaultsParams_t* params )
|
||||
|
||||
// Initialize the channels default mask
|
||||
NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 );
|
||||
|
||||
// Update the channels mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 1 );
|
||||
break;
|
||||
@@ -418,6 +403,10 @@ void RegionAS923InitDefaults( InitDefaultsParams_t* params )
|
||||
{
|
||||
// Restore channels default mask
|
||||
NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0];
|
||||
|
||||
// Channels
|
||||
NvmCtx.Channels[0] = ( ChannelParams_t ) AS923_LC1;
|
||||
NvmCtx.Channels[1] = ( ChannelParams_t ) AS923_LC2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -437,6 +426,10 @@ bool RegionAS923Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute )
|
||||
{
|
||||
switch( phyAttribute )
|
||||
{
|
||||
case PHY_FREQUENCY:
|
||||
{
|
||||
return VerifyRfFreq( verify->Frequency );
|
||||
}
|
||||
case PHY_TX_DR:
|
||||
{
|
||||
if( verify->DatarateParams.UplinkDwellTime == 0 )
|
||||
@@ -581,7 +574,6 @@ bool RegionAS923RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
{
|
||||
RadioModems_t modem;
|
||||
int8_t dr = rxConfig->Datarate;
|
||||
uint8_t maxPayload = 0;
|
||||
int8_t phyDr = 0;
|
||||
uint32_t frequency = rxConfig->Frequency;
|
||||
|
||||
@@ -618,17 +610,7 @@ bool RegionAS923RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
Radio.SetRxConfig( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
|
||||
}
|
||||
|
||||
// Check for repeater support
|
||||
if( rxConfig->RepeaterSupport == true )
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateRepeaterDwell0AS923[dr];
|
||||
}
|
||||
else
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateDwell0AS923[dr];
|
||||
}
|
||||
|
||||
Radio.SetMaxPayloadLength( modem, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
|
||||
Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarateDwell0AS923[dr] + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE );
|
||||
|
||||
*datarate = (uint8_t) dr;
|
||||
return true;
|
||||
@@ -651,18 +633,19 @@ bool RegionAS923TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime
|
||||
if( txConfig->Datarate == DR_7 )
|
||||
{ // High Speed FSK channel
|
||||
modem = MODEM_FSK;
|
||||
Radio.SetTxConfig( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 4000 );
|
||||
}
|
||||
else
|
||||
{
|
||||
modem = MODEM_LORA;
|
||||
Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 );
|
||||
}
|
||||
|
||||
// Update time-on-air
|
||||
*txTimeOnAir = GetTimeOnAir( txConfig->Datarate, txConfig->PktLen );
|
||||
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( modem, txConfig->PktLen );
|
||||
// Get the time-on-air of the next tx frame
|
||||
*txTimeOnAir = Radio.TimeOnAir( modem, txConfig->PktLen );
|
||||
|
||||
*txPower = txPowerLimited;
|
||||
return true;
|
||||
@@ -888,55 +871,45 @@ int8_t RegionAS923AlternateDr( int8_t currentDr, AlternateDrType_t type )
|
||||
return AS923_DWELL_LIMIT_DATARATE;
|
||||
}
|
||||
|
||||
void RegionAS923CalcBackOff( CalcBackOffParams_t* calcBackOff )
|
||||
{
|
||||
RegionCommonCalcBackOffParams_t calcBackOffParams;
|
||||
|
||||
calcBackOffParams.Channels = NvmCtx.Channels;
|
||||
calcBackOffParams.Bands = NvmCtx.Bands;
|
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest;
|
||||
calcBackOffParams.Joined = calcBackOff->Joined;
|
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled;
|
||||
calcBackOffParams.Channel = calcBackOff->Channel;
|
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime;
|
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir;
|
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams );
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionAS923NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff )
|
||||
{
|
||||
uint8_t channelNext = 0;
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTx = 0;
|
||||
uint8_t nbRestrictedChannels = 0;
|
||||
uint8_t enabledChannels[AS923_MAX_NB_CHANNELS] = { 0 };
|
||||
TimerTime_t nextTxDelay = 0;
|
||||
RegionCommonIdentifyChannelsParam_t identifyChannelsParam;
|
||||
RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams;
|
||||
LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
|
||||
if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 )
|
||||
{ // Reactivate default channels
|
||||
NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 );
|
||||
}
|
||||
|
||||
if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) )
|
||||
{
|
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0;
|
||||
// Search how many channels are enabled
|
||||
countChannelsParams.Joined = nextChanParams->Joined;
|
||||
countChannelsParams.Datarate = nextChanParams->Datarate;
|
||||
countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask;
|
||||
countChannelsParams.Channels = NvmCtx.Channels;
|
||||
countChannelsParams.Bands = NvmCtx.Bands;
|
||||
countChannelsParams.MaxNbChannels = AS923_MAX_NB_CHANNELS;
|
||||
countChannelsParams.JoinChannels = AS923_JOIN_CHANNELS;
|
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, NvmCtx.Bands, AS923_MAX_NB_BANDS );
|
||||
identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff;
|
||||
identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx;
|
||||
identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;
|
||||
identifyChannelsParam.MaxBands = AS923_MAX_NB_BANDS;
|
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Joined, nextChanParams->Datarate,
|
||||
NvmCtx.ChannelsMask, NvmCtx.Channels,
|
||||
NvmCtx.Bands, enabledChannels, &delayTx );
|
||||
}
|
||||
else
|
||||
{
|
||||
delayTx++;
|
||||
nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx );
|
||||
}
|
||||
identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;
|
||||
identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;
|
||||
identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );
|
||||
|
||||
if( nbEnabledChannels > 0 )
|
||||
identifyChannelsParam.CountNbOfEnabledChannelsParam = &countChannelsParams;
|
||||
|
||||
status = RegionCommonIdentifyChannels( &identifyChannelsParam, aggregatedTimeOff, enabledChannels,
|
||||
&nbEnabledChannels, &nbRestrictedChannels, time );
|
||||
|
||||
if( status == LORAMAC_STATUS_OK )
|
||||
{
|
||||
for( uint8_t i = 0, j = randr( 0, nbEnabledChannels - 1 ); i < AS923_MAX_NB_CHANNELS; i++ )
|
||||
{
|
||||
@@ -949,25 +922,19 @@ LoRaMacStatus_t RegionAS923NextChannel( NextChanParams_t* nextChanParams, uint8_
|
||||
{
|
||||
// Free channel found
|
||||
*channel = channelNext;
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_OK;
|
||||
}
|
||||
}
|
||||
return LORAMAC_STATUS_NO_FREE_CHANNEL_FOUND;
|
||||
// Even if one or more channels are available according to the channel plan, no free channel
|
||||
// was found during the LBT procedure.
|
||||
status = LORAMAC_STATUS_NO_FREE_CHANNEL_FOUND;
|
||||
}
|
||||
else
|
||||
else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND )
|
||||
{
|
||||
if( delayTx > 0 )
|
||||
{
|
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay;
|
||||
return LORAMAC_STATUS_DUTYCYCLE_RESTRICTED;
|
||||
}
|
||||
// Datarate not supported by any channel, restore defaults
|
||||
NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 );
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionAS923ChannelAdd( ChannelAddParams_t* channelAdd )
|
||||
|
@@ -37,6 +37,11 @@
|
||||
#ifndef __REGION_AS923_H__
|
||||
#define __REGION_AS923_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
@@ -212,6 +217,11 @@
|
||||
*/
|
||||
#define AS923_BEACON_CHANNEL_FREQ 923400000
|
||||
|
||||
/*!
|
||||
* Ping slot channel frequency
|
||||
*/
|
||||
#define AS923_PING_SLOT_CHANNEL_FREQ 923400000
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
@@ -249,9 +259,9 @@
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
* Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission }
|
||||
*/
|
||||
#define AS923_BAND0 { 100, AS923_MAX_TX_POWER, 0, 0, 0 } // 1.0 %
|
||||
#define AS923_BAND0 { 100, AS923_MAX_TX_POWER, 0, 0, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1
|
||||
@@ -291,27 +301,20 @@ static const uint8_t DataratesAS923[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
|
||||
static const uint32_t BandwidthsAS923[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
* Maximum payload with respect to the datarate index.
|
||||
* The table is valid for the dwell time configuration of 0 for uplinks and downlinks.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateDwell0AS923[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
* The table is valid for the dwell time configuration of 0 for uplinks and downlinks. The table provides
|
||||
* repeater support.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterDwell0AS923[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with and without repeater.
|
||||
* The table proides repeater support. The table is only valid for uplinks.
|
||||
* Maximum payload with respect to the datarate index.
|
||||
* The table is only valid for uplinks.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateDwell1UpAS923[] = { 0, 0, 11, 53, 125, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with and without repeater.
|
||||
* The table proides repeater support. The table is only valid for downlinks.
|
||||
* Maximum payload with respect to the datarate index.
|
||||
* The table is only valid for downlinks.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateDwell1DownAS923[] = { 0, 0, 11, 53, 126, 242, 242, 242 };
|
||||
|
||||
@@ -475,13 +478,6 @@ uint8_t RegionAS923DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
*/
|
||||
int8_t RegionAS923AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionAS923CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
@@ -543,4 +539,8 @@ uint8_t RegionAS923ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d
|
||||
|
||||
/*! \} defgroup REGIONAS923 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __REGION_AS923_H__
|
||||
|
@@ -140,38 +140,12 @@ static bool VerifyRfFreq( uint32_t freq )
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx )
|
||||
static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTransmission = 0;
|
||||
int8_t phyDr = DataratesAU915[datarate];
|
||||
uint32_t bandwidth = GetBandwidth( datarate );
|
||||
|
||||
for( uint8_t i = 0, k = 0; i < AU915_MAX_NB_CHANNELS; i += 16, k++ )
|
||||
{
|
||||
for( uint8_t j = 0; j < 16; j++ )
|
||||
{
|
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 )
|
||||
{
|
||||
if( channels[i + j].Frequency == 0 )
|
||||
{ // Check if the channel is enabled
|
||||
continue;
|
||||
}
|
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min,
|
||||
channels[i + j].DrRange.Fields.Max ) == false )
|
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue;
|
||||
}
|
||||
if( bands[channels[i + j].Band].TimeOff > 0 )
|
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++;
|
||||
continue;
|
||||
}
|
||||
enabledChannels[nbEnabledChannels++] = i + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*delayTx = delayTransmission;
|
||||
return nbEnabledChannels;
|
||||
return Radio.TimeOnAir( MODEM_LORA, bandwidth, phyDr, 1, 8, false, pktLen, true );
|
||||
}
|
||||
|
||||
PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy )
|
||||
@@ -253,18 +227,6 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy )
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_PAYLOAD_REPEATER:
|
||||
{
|
||||
if( getPhy->UplinkDwellTime == 0)
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterDwell0AU915[getPhy->Datarate];
|
||||
}
|
||||
else
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterDwell1AU915[getPhy->Datarate];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PHY_DUTY_CYCLE:
|
||||
{
|
||||
phyParam.Value = AU915_DUTY_CYCLE_ENABLED;
|
||||
@@ -360,6 +322,11 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.fValue = AU915_DEFAULT_ANTENNA_GAIN;
|
||||
break;
|
||||
}
|
||||
case PHY_BEACON_CHANNEL_FREQ:
|
||||
{
|
||||
phyParam.Value = AU915_BEACON_CHANNEL_FREQ + ( getPhy->Channel * AU915_BEACON_CHANNEL_STEPWIDTH );
|
||||
break;
|
||||
}
|
||||
case PHY_BEACON_FORMAT:
|
||||
{
|
||||
phyParam.BeaconFormat.BeaconSize = AU915_BEACON_SIZE;
|
||||
@@ -382,11 +349,26 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = AU915_BEACON_NB_CHANNELS;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_FREQ:
|
||||
{
|
||||
phyParam.Value = AU915_PING_SLOT_CHANNEL_FREQ + ( getPhy->Channel * AU915_BEACON_CHANNEL_STEPWIDTH );
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_DR:
|
||||
{
|
||||
phyParam.Value = AU915_PING_SLOT_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_SF_FROM_DR:
|
||||
{
|
||||
phyParam.Value = DataratesAU915[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_BW_FROM_DR:
|
||||
{
|
||||
phyParam.Value = GetBandwidth( getPhy->Datarate );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
@@ -398,7 +380,8 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy )
|
||||
|
||||
void RegionAU915SetBandTxDone( SetBandTxDoneParams_t* txDone )
|
||||
{
|
||||
RegionCommonSetBandTxDone( txDone->Joined, &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxDoneTime );
|
||||
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band],
|
||||
txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );
|
||||
}
|
||||
|
||||
void RegionAU915InitDefaults( InitDefaultsParams_t* params )
|
||||
@@ -410,11 +393,28 @@ void RegionAU915InitDefaults( InitDefaultsParams_t* params )
|
||||
|
||||
switch( params->Type )
|
||||
{
|
||||
case INIT_TYPE_INIT:
|
||||
case INIT_TYPE_BANDS:
|
||||
{
|
||||
// Initialize bands
|
||||
memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * AU915_MAX_NB_BANDS );
|
||||
|
||||
// Initialize channels default mask
|
||||
NvmCtx.ChannelsDefaultMask[0] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[1] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[2] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[3] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[4] = 0x00FF;
|
||||
NvmCtx.ChannelsDefaultMask[5] = 0x0000;
|
||||
|
||||
// Copy channels default mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 );
|
||||
|
||||
// Copy into channels mask remaining
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMaskRemaining, NvmCtx.ChannelsMask, 6 );
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_INIT:
|
||||
{
|
||||
// Channels
|
||||
// 125 kHz channels
|
||||
for( uint8_t i = 0; i < AU915_MAX_NB_CHANNELS - 8; i++ )
|
||||
@@ -430,20 +430,6 @@ void RegionAU915InitDefaults( InitDefaultsParams_t* params )
|
||||
NvmCtx.Channels[i].DrRange.Value = ( DR_6 << 4 ) | DR_6;
|
||||
NvmCtx.Channels[i].Band = 0;
|
||||
}
|
||||
|
||||
// Initialize channels default mask
|
||||
NvmCtx.ChannelsDefaultMask[0] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[1] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[2] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[3] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[4] = 0x00FF;
|
||||
NvmCtx.ChannelsDefaultMask[5] = 0x0000;
|
||||
|
||||
// Copy channels default mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 );
|
||||
|
||||
// Copy into channels mask remaining
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMaskRemaining, NvmCtx.ChannelsMask, 6 );
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_RESTORE_CTX:
|
||||
@@ -482,6 +468,10 @@ bool RegionAU915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute )
|
||||
{
|
||||
switch( phyAttribute )
|
||||
{
|
||||
case PHY_FREQUENCY:
|
||||
{
|
||||
return VerifyRfFreq( verify->Frequency );
|
||||
}
|
||||
case PHY_TX_DR:
|
||||
case PHY_DEF_TX_DR:
|
||||
{
|
||||
@@ -592,7 +582,6 @@ void RegionAU915ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols
|
||||
bool RegionAU915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
{
|
||||
int8_t dr = rxConfig->Datarate;
|
||||
uint8_t maxPayload = 0;
|
||||
int8_t phyDr = 0;
|
||||
uint32_t frequency = rxConfig->Frequency;
|
||||
|
||||
@@ -615,15 +604,7 @@ bool RegionAU915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
// Radio configuration
|
||||
Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
|
||||
|
||||
if( rxConfig->RepeaterSupport == true )
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateRepeaterDwell0AU915[dr];
|
||||
}
|
||||
else
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateDwell0AU915[dr];
|
||||
}
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, MaxPayloadOfDatarateDwell0AU915[dr] + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE );
|
||||
|
||||
*datarate = (uint8_t) dr;
|
||||
return true;
|
||||
@@ -642,14 +623,14 @@ bool RegionAU915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime
|
||||
// Setup the radio frequency
|
||||
Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency );
|
||||
|
||||
Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 );
|
||||
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, txConfig->PktLen );
|
||||
// Update time-on-air
|
||||
*txTimeOnAir = GetTimeOnAir( txConfig->Datarate, txConfig->PktLen );
|
||||
|
||||
*txTimeOnAir = Radio.TimeOnAir( MODEM_LORA, txConfig->PktLen );
|
||||
*txPower = txPowerLimited;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -880,28 +861,14 @@ int8_t RegionAU915AlternateDr( int8_t currentDr, AlternateDrType_t type )
|
||||
return currentDr;
|
||||
}
|
||||
|
||||
void RegionAU915CalcBackOff( CalcBackOffParams_t* calcBackOff )
|
||||
{
|
||||
RegionCommonCalcBackOffParams_t calcBackOffParams;
|
||||
|
||||
calcBackOffParams.Channels = NvmCtx.Channels;
|
||||
calcBackOffParams.Bands = NvmCtx.Bands;
|
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest;
|
||||
calcBackOffParams.Joined = calcBackOff->Joined;
|
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled;
|
||||
calcBackOffParams.Channel = calcBackOff->Channel;
|
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime;
|
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir;
|
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams );
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionAU915NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTx = 0;
|
||||
uint8_t nbRestrictedChannels = 0;
|
||||
uint8_t enabledChannels[AU915_MAX_NB_CHANNELS] = { 0 };
|
||||
TimerTime_t nextTxDelay = 0;
|
||||
RegionCommonIdentifyChannelsParam_t identifyChannelsParam;
|
||||
RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams;
|
||||
LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
|
||||
// Count 125kHz channels
|
||||
if( RegionCommonCountChannels( NvmCtx.ChannelsMaskRemaining, 0, 4 ) == 0 )
|
||||
@@ -917,47 +884,37 @@ LoRaMacStatus_t RegionAU915NextChannel( NextChanParams_t* nextChanParams, uint8_
|
||||
}
|
||||
}
|
||||
|
||||
if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) )
|
||||
{
|
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0;
|
||||
// Search how many channels are enabled
|
||||
countChannelsParams.Joined = nextChanParams->Joined;
|
||||
countChannelsParams.Datarate = nextChanParams->Datarate;
|
||||
countChannelsParams.ChannelsMask = NvmCtx.ChannelsMaskRemaining;
|
||||
countChannelsParams.Channels = NvmCtx.Channels;
|
||||
countChannelsParams.Bands = NvmCtx.Bands;
|
||||
countChannelsParams.MaxNbChannels = AU915_MAX_NB_CHANNELS;
|
||||
countChannelsParams.JoinChannels = 0;
|
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, NvmCtx.Bands, AU915_MAX_NB_BANDS );
|
||||
identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff;
|
||||
identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx;
|
||||
identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;
|
||||
identifyChannelsParam.MaxBands = AU915_MAX_NB_BANDS;
|
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Datarate,
|
||||
NvmCtx.ChannelsMaskRemaining, NvmCtx.Channels,
|
||||
NvmCtx.Bands, enabledChannels, &delayTx );
|
||||
}
|
||||
else
|
||||
{
|
||||
delayTx++;
|
||||
nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx );
|
||||
}
|
||||
identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;
|
||||
identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;
|
||||
identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );
|
||||
|
||||
if( nbEnabledChannels > 0 )
|
||||
identifyChannelsParam.CountNbOfEnabledChannelsParam = &countChannelsParams;
|
||||
|
||||
status = RegionCommonIdentifyChannels( &identifyChannelsParam, aggregatedTimeOff, enabledChannels,
|
||||
&nbEnabledChannels, &nbRestrictedChannels, time );
|
||||
|
||||
if( status == LORAMAC_STATUS_OK )
|
||||
{
|
||||
// We found a valid channel
|
||||
*channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
|
||||
// Disable the channel in the mask
|
||||
RegionCommonChanDisable( NvmCtx.ChannelsMaskRemaining, *channel, AU915_MAX_NB_CHANNELS - 8 );
|
||||
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( delayTx > 0 )
|
||||
{
|
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay;
|
||||
return LORAMAC_STATUS_DUTYCYCLE_RESTRICTED;
|
||||
}
|
||||
// Datarate not supported by any channel
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionAU915ChannelAdd( ChannelAddParams_t* channelAdd )
|
||||
|
@@ -37,6 +37,11 @@
|
||||
#ifndef __REGION_AU915_H__
|
||||
#define __REGION_AU915_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
@@ -93,7 +98,7 @@
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node
|
||||
*/
|
||||
#define AU915_MIN_TX_POWER TX_POWER_10
|
||||
#define AU915_MIN_TX_POWER TX_POWER_14
|
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node
|
||||
@@ -203,6 +208,11 @@
|
||||
*/
|
||||
#define AU915_BEACON_CHANNEL_STEPWIDTH 600000
|
||||
|
||||
/*!
|
||||
* Ping slot channel frequency
|
||||
*/
|
||||
#define AU915_PING_SLOT_CHANNEL_FREQ 923300000
|
||||
|
||||
/*!
|
||||
* Number of possible beacon channels
|
||||
*/
|
||||
@@ -226,7 +236,7 @@
|
||||
/*!
|
||||
* Datarate of the beacon channel
|
||||
*/
|
||||
#define AU915_BEACON_CHANNEL_DR DR_10
|
||||
#define AU915_BEACON_CHANNEL_DR DR_8
|
||||
|
||||
/*!
|
||||
* Bandwith of the beacon channel
|
||||
@@ -236,7 +246,7 @@
|
||||
/*!
|
||||
* Ping slot channel datarate
|
||||
*/
|
||||
#define AU915_PING_SLOT_CHANNEL_DR DR_10
|
||||
#define AU915_PING_SLOT_CHANNEL_DR DR_8
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of bands
|
||||
@@ -245,9 +255,9 @@
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
* Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission }
|
||||
*/
|
||||
#define AU915_BAND0 { 1, AU915_MAX_TX_POWER, 0, 0, 0 } // 100.0 %
|
||||
#define AU915_BAND0 { 1, AU915_MAX_TX_POWER, 0, 0, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* Defines the first channel for RX window 1 for US band
|
||||
@@ -289,30 +299,16 @@ static const int8_t DatarateOffsetsAU915[7][6] =
|
||||
};
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
* Maximum payload with respect to the datarate index.
|
||||
* The table is valid for the dwell time configuration of 0 for uplinks.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateDwell0AU915[] = { 51, 51, 51, 115, 242, 242, 242, 242, 0, 53, 129, 242, 242, 242, 242 };
|
||||
static const uint8_t MaxPayloadOfDatarateDwell0AU915[] = { 51, 51, 51, 115, 242, 242, 242, 0, 53, 129, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
* The table is valid for the dwell time configuration of 0 for uplinks. The table provides
|
||||
* repeater support.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterDwell0AU915[] = { 51, 51, 51, 115, 222, 222, 222, 0, 33, 109, 222, 222, 222, 222 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
* Maximum payload with respect to the datarate index.
|
||||
* The table is valid for the dwell time configuration of 1 for uplinks.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateDwell1AU915[] = { 0, 0, 11, 53, 125, 242, 242, 0, 53, 129, 129, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
* The table is valid for the dwell time configuration of 1 for uplinks. The table provides
|
||||
* repeater support.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterDwell1AU915[] = { 0, 0, 11, 53, 125, 242, 242, 0, 33, 119, 129, 242, 242, 242, 242 };
|
||||
static const uint8_t MaxPayloadOfDatarateDwell1AU915[] = { 0, 0, 11, 53, 125, 242, 242, 0, 53, 129, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
@@ -469,13 +465,6 @@ uint8_t RegionAU915DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
*/
|
||||
int8_t RegionAU915AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionAU915CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
@@ -537,4 +526,8 @@ uint8_t RegionAU915ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d
|
||||
|
||||
/*! \} defgroup REGIONAU915 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __REGION_AU915_H__
|
||||
|
@@ -128,38 +128,12 @@ static bool VerifyRfFreq( uint32_t freq )
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx )
|
||||
static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTransmission = 0;
|
||||
int8_t phyDr = DataratesCN470[datarate];
|
||||
uint32_t bandwidth = GetBandwidth( datarate );
|
||||
|
||||
for( uint8_t i = 0, k = 0; i < CN470_MAX_NB_CHANNELS; i += 16, k++ )
|
||||
{
|
||||
for( uint8_t j = 0; j < 16; j++ )
|
||||
{
|
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 )
|
||||
{
|
||||
if( channels[i + j].Frequency == 0 )
|
||||
{ // Check if the channel is enabled
|
||||
continue;
|
||||
}
|
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min,
|
||||
channels[i + j].DrRange.Fields.Max ) == false )
|
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue;
|
||||
}
|
||||
if( bands[channels[i + j].Band].TimeOff > 0 )
|
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++;
|
||||
continue;
|
||||
}
|
||||
enabledChannels[nbEnabledChannels++] = i + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*delayTx = delayTransmission;
|
||||
return nbEnabledChannels;
|
||||
return Radio.TimeOnAir( MODEM_LORA, bandwidth, phyDr, 1, 8, false, pktLen, true );
|
||||
}
|
||||
|
||||
PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy )
|
||||
@@ -213,11 +187,6 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = MaxPayloadOfDatarateCN470[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_PAYLOAD_REPEATER:
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterCN470[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_DUTY_CYCLE:
|
||||
{
|
||||
phyParam.Value = CN470_DUTY_CYCLE_ENABLED;
|
||||
@@ -309,6 +278,11 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.fValue = CN470_DEFAULT_ANTENNA_GAIN;
|
||||
break;
|
||||
}
|
||||
case PHY_BEACON_CHANNEL_FREQ:
|
||||
{
|
||||
phyParam.Value = CN470_BEACON_CHANNEL_FREQ;
|
||||
break;
|
||||
}
|
||||
case PHY_BEACON_FORMAT:
|
||||
{
|
||||
phyParam.BeaconFormat.BeaconSize = CN470_BEACON_SIZE;
|
||||
@@ -331,11 +305,26 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = CN470_BEACON_NB_CHANNELS;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_FREQ:
|
||||
{
|
||||
phyParam.Value = CN470_PING_SLOT_CHANNEL_FREQ;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_DR:
|
||||
{
|
||||
phyParam.Value = CN470_PING_SLOT_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_SF_FROM_DR:
|
||||
{
|
||||
phyParam.Value = DataratesCN470[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_BW_FROM_DR:
|
||||
{
|
||||
phyParam.Value = GetBandwidth( getPhy->Datarate );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
@@ -347,7 +336,8 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy )
|
||||
|
||||
void RegionCN470SetBandTxDone( SetBandTxDoneParams_t* txDone )
|
||||
{
|
||||
RegionCommonSetBandTxDone( txDone->Joined, &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxDoneTime );
|
||||
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band],
|
||||
txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );
|
||||
}
|
||||
|
||||
void RegionCN470InitDefaults( InitDefaultsParams_t* params )
|
||||
@@ -359,11 +349,14 @@ void RegionCN470InitDefaults( InitDefaultsParams_t* params )
|
||||
|
||||
switch( params->Type )
|
||||
{
|
||||
case INIT_TYPE_INIT:
|
||||
case INIT_TYPE_BANDS:
|
||||
{
|
||||
// Initialize bands
|
||||
memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * CN470_MAX_NB_BANDS );
|
||||
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_INIT:
|
||||
{
|
||||
// Channels
|
||||
// 125 kHz channels
|
||||
for( uint8_t i = 0; i < CN470_MAX_NB_CHANNELS; i++ )
|
||||
@@ -374,21 +367,13 @@ void RegionCN470InitDefaults( InitDefaultsParams_t* params )
|
||||
}
|
||||
|
||||
// Initialize the channels default mask
|
||||
#if 0
|
||||
NvmCtx.ChannelsDefaultMask[0] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[1] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[2] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[3] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[4] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[5] = 0xFFFF;
|
||||
#else
|
||||
NvmCtx.ChannelsDefaultMask[0] = 0x00FF;
|
||||
NvmCtx.ChannelsDefaultMask[1] = 0x0000;
|
||||
NvmCtx.ChannelsDefaultMask[2] = 0x0000;
|
||||
NvmCtx.ChannelsDefaultMask[3] = 0x0000;
|
||||
NvmCtx.ChannelsDefaultMask[4] = 0x0000;
|
||||
NvmCtx.ChannelsDefaultMask[5] = 0x0000;
|
||||
#endif
|
||||
|
||||
// Update the channels mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 );
|
||||
break;
|
||||
@@ -424,6 +409,10 @@ bool RegionCN470Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute )
|
||||
{
|
||||
switch( phyAttribute )
|
||||
{
|
||||
case PHY_FREQUENCY:
|
||||
{
|
||||
return VerifyRfFreq( verify->Frequency );
|
||||
}
|
||||
case PHY_TX_DR:
|
||||
case PHY_DEF_TX_DR:
|
||||
{
|
||||
@@ -506,7 +495,6 @@ void RegionCN470ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols
|
||||
bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
{
|
||||
int8_t dr = rxConfig->Datarate;
|
||||
uint8_t maxPayload = 0;
|
||||
int8_t phyDr = 0;
|
||||
uint32_t frequency = rxConfig->Frequency;
|
||||
|
||||
@@ -529,15 +517,7 @@ bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
// Radio configuration
|
||||
Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
|
||||
|
||||
if( rxConfig->RepeaterSupport == true )
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateRepeaterCN470[dr];
|
||||
}
|
||||
else
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateCN470[dr];
|
||||
}
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, MaxPayloadOfDatarateCN470[dr] + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE );
|
||||
|
||||
*datarate = (uint8_t) dr;
|
||||
return true;
|
||||
@@ -555,11 +535,11 @@ bool RegionCN470TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime
|
||||
// Setup the radio frequency
|
||||
Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency );
|
||||
|
||||
Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, 0, phyDr, 1, 8, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, 0, phyDr, 1, 8, false, true, 0, 0, false, 4000 );
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, txConfig->PktLen );
|
||||
// Get the time-on-air of the next tx frame
|
||||
*txTimeOnAir = Radio.TimeOnAir( MODEM_LORA, txConfig->PktLen );
|
||||
// Update time-on-air
|
||||
*txTimeOnAir = GetTimeOnAir( txConfig->Datarate, txConfig->PktLen );
|
||||
*txPower = txPowerLimited;
|
||||
|
||||
return true;
|
||||
@@ -708,28 +688,14 @@ int8_t RegionCN470AlternateDr( int8_t currentDr, AlternateDrType_t type )
|
||||
return currentDr;
|
||||
}
|
||||
|
||||
void RegionCN470CalcBackOff( CalcBackOffParams_t* calcBackOff )
|
||||
{
|
||||
RegionCommonCalcBackOffParams_t calcBackOffParams;
|
||||
|
||||
calcBackOffParams.Channels = NvmCtx.Channels;
|
||||
calcBackOffParams.Bands = NvmCtx.Bands;
|
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest;
|
||||
calcBackOffParams.Joined = calcBackOff->Joined;
|
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled;
|
||||
calcBackOffParams.Channel = calcBackOff->Channel;
|
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime;
|
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir;
|
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams );
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionCN470NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTx = 0;
|
||||
uint8_t nbRestrictedChannels = 0;
|
||||
uint8_t enabledChannels[CN470_MAX_NB_CHANNELS] = { 0 };
|
||||
TimerTime_t nextTxDelay = 0;
|
||||
RegionCommonIdentifyChannelsParam_t identifyChannelsParam;
|
||||
RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams;
|
||||
LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
|
||||
// Count 125kHz channels
|
||||
if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 6 ) == 0 )
|
||||
@@ -742,45 +708,35 @@ LoRaMacStatus_t RegionCN470NextChannel( NextChanParams_t* nextChanParams, uint8_
|
||||
NvmCtx.ChannelsMask[5] = 0xFFFF;
|
||||
}
|
||||
|
||||
if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) )
|
||||
{
|
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0;
|
||||
// Search how many channels are enabled
|
||||
countChannelsParams.Joined = nextChanParams->Joined;
|
||||
countChannelsParams.Datarate = nextChanParams->Datarate;
|
||||
countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask;
|
||||
countChannelsParams.Channels = NvmCtx.Channels;
|
||||
countChannelsParams.Bands = NvmCtx.Bands;
|
||||
countChannelsParams.MaxNbChannels = CN470_MAX_NB_CHANNELS;
|
||||
countChannelsParams.JoinChannels = 0;
|
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, NvmCtx.Bands, CN470_MAX_NB_BANDS );
|
||||
identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff;
|
||||
identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx;
|
||||
identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;
|
||||
identifyChannelsParam.MaxBands = CN470_MAX_NB_BANDS;
|
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Datarate,
|
||||
NvmCtx.ChannelsMask, NvmCtx.Channels,
|
||||
NvmCtx.Bands, enabledChannels, &delayTx );
|
||||
}
|
||||
else
|
||||
{
|
||||
delayTx++;
|
||||
nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx );
|
||||
}
|
||||
identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;
|
||||
identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;
|
||||
identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );
|
||||
|
||||
if( nbEnabledChannels > 0 )
|
||||
identifyChannelsParam.CountNbOfEnabledChannelsParam = &countChannelsParams;
|
||||
|
||||
status = RegionCommonIdentifyChannels( &identifyChannelsParam, aggregatedTimeOff, enabledChannels,
|
||||
&nbEnabledChannels, &nbRestrictedChannels, time );
|
||||
|
||||
if( status == LORAMAC_STATUS_OK )
|
||||
{
|
||||
// We found a valid channel
|
||||
*channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
|
||||
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( delayTx > 0 )
|
||||
{
|
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay;
|
||||
return LORAMAC_STATUS_DUTYCYCLE_RESTRICTED;
|
||||
}
|
||||
// Datarate not supported by any channel
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionCN470ChannelAdd( ChannelAddParams_t* channelAdd )
|
||||
|
@@ -37,6 +37,11 @@
|
||||
#ifndef __REGION_CN470_H__
|
||||
#define __REGION_CN470_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
@@ -187,6 +192,11 @@
|
||||
*/
|
||||
#define CN470_BEACON_CHANNEL_STEPWIDTH 200000
|
||||
|
||||
/*!
|
||||
* Ping slot channel frequency
|
||||
*/
|
||||
#define CN470_PING_SLOT_CHANNEL_FREQ 508300000
|
||||
|
||||
/*!
|
||||
* Number of possible beacon channels
|
||||
*/
|
||||
@@ -229,9 +239,9 @@
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
* Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission }
|
||||
*/
|
||||
#define CN470_BAND0 { 1, CN470_MAX_TX_POWER, 0, 0, 0 } // 100.0 %
|
||||
#define CN470_BAND0 { 1, CN470_MAX_TX_POWER, 0, 0, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* Defines the first channel for RX window 1 for CN470 band
|
||||
@@ -259,14 +269,9 @@ static const uint8_t DataratesCN470[] = { 12, 11, 10, 9, 8, 7 };
|
||||
static const uint32_t BandwidthsCN470[] = { 125000, 125000, 125000, 125000, 125000, 125000 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
* Maximum payload with respect to the datarate index.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateCN470[] = { 51, 51, 51, 115, 222, 222 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterCN470[] = { 51, 51, 51, 115, 222, 222 };
|
||||
static const uint8_t MaxPayloadOfDatarateCN470[] = { 51, 51, 51, 115, 242, 242 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
@@ -423,13 +428,6 @@ uint8_t RegionCN470DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
*/
|
||||
int8_t RegionCN470AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionCN470CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
@@ -491,4 +489,8 @@ uint8_t RegionCN470ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d
|
||||
|
||||
/*! \} defgroup REGIONCN470 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __REGION_CN470_H__
|
||||
|
@@ -119,45 +119,21 @@ static bool VerifyRfFreq( uint32_t freq )
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx )
|
||||
static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTransmission = 0;
|
||||
int8_t phyDr = DataratesCN779[datarate];
|
||||
uint32_t bandwidth = GetBandwidth( datarate );
|
||||
TimerTime_t timeOnAir = 0;
|
||||
|
||||
for( uint8_t i = 0, k = 0; i < CN779_MAX_NB_CHANNELS; i += 16, k++ )
|
||||
{
|
||||
for( uint8_t j = 0; j < 16; j++ )
|
||||
{
|
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 )
|
||||
{
|
||||
if( channels[i + j].Frequency == 0 )
|
||||
{ // Check if the channel is enabled
|
||||
continue;
|
||||
}
|
||||
if( joined == false )
|
||||
{
|
||||
if( ( CN779_JOIN_CHANNELS & ( 1 << j ) ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min,
|
||||
channels[i + j].DrRange.Fields.Max ) == false )
|
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue;
|
||||
}
|
||||
if( bands[channels[i + j].Band].TimeOff > 0 )
|
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++;
|
||||
continue;
|
||||
}
|
||||
enabledChannels[nbEnabledChannels++] = i + j;
|
||||
}
|
||||
}
|
||||
if( datarate == DR_7 )
|
||||
{ // High Speed FSK channel
|
||||
timeOnAir = Radio.TimeOnAir( MODEM_FSK, bandwidth, phyDr * 1000, 0, 5, false, pktLen, true );
|
||||
}
|
||||
|
||||
*delayTx = delayTransmission;
|
||||
return nbEnabledChannels;
|
||||
else
|
||||
{
|
||||
timeOnAir = Radio.TimeOnAir( MODEM_LORA, bandwidth, phyDr, 1, 8, false, pktLen, true );
|
||||
}
|
||||
return timeOnAir;
|
||||
}
|
||||
|
||||
PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy )
|
||||
@@ -211,11 +187,6 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = MaxPayloadOfDatarateCN779[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_PAYLOAD_REPEATER:
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterCN779[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_DUTY_CYCLE:
|
||||
{
|
||||
phyParam.Value = CN779_DUTY_CYCLE_ENABLED;
|
||||
@@ -324,11 +295,26 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = CN779_BEACON_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_FREQ:
|
||||
{
|
||||
phyParam.Value = CN779_PING_SLOT_CHANNEL_FREQ;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_DR:
|
||||
{
|
||||
phyParam.Value = CN779_PING_SLOT_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_SF_FROM_DR:
|
||||
{
|
||||
phyParam.Value = DataratesCN779[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_BW_FROM_DR:
|
||||
{
|
||||
phyParam.Value = GetBandwidth( getPhy->Datarate );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
@@ -340,7 +326,8 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy )
|
||||
|
||||
void RegionCN779SetBandTxDone( SetBandTxDoneParams_t* txDone )
|
||||
{
|
||||
RegionCommonSetBandTxDone( txDone->Joined, &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxDoneTime );
|
||||
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band],
|
||||
txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );
|
||||
}
|
||||
|
||||
void RegionCN779InitDefaults( InitDefaultsParams_t* params )
|
||||
@@ -352,10 +339,14 @@ void RegionCN779InitDefaults( InitDefaultsParams_t* params )
|
||||
|
||||
switch( params->Type )
|
||||
{
|
||||
case INIT_TYPE_INIT:
|
||||
case INIT_TYPE_BANDS:
|
||||
{
|
||||
// Initialize bands
|
||||
memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * CN779_MAX_NB_BANDS );
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_INIT:
|
||||
{
|
||||
|
||||
// Channels
|
||||
NvmCtx.Channels[0] = ( ChannelParams_t ) CN779_LC1;
|
||||
@@ -364,6 +355,7 @@ void RegionCN779InitDefaults( InitDefaultsParams_t* params )
|
||||
|
||||
// Initialize the channels default mask
|
||||
NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
|
||||
|
||||
// Update the channels mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 1 );
|
||||
break;
|
||||
@@ -380,6 +372,11 @@ void RegionCN779InitDefaults( InitDefaultsParams_t* params )
|
||||
{
|
||||
// Restore channels default mask
|
||||
NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0];
|
||||
|
||||
// Channels
|
||||
NvmCtx.Channels[0] = ( ChannelParams_t ) CN779_LC1;
|
||||
NvmCtx.Channels[1] = ( ChannelParams_t ) CN779_LC2;
|
||||
NvmCtx.Channels[2] = ( ChannelParams_t ) CN779_LC3;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -399,6 +396,10 @@ bool RegionCN779Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute )
|
||||
{
|
||||
switch( phyAttribute )
|
||||
{
|
||||
case PHY_FREQUENCY:
|
||||
{
|
||||
return VerifyRfFreq( verify->Frequency );
|
||||
}
|
||||
case PHY_TX_DR:
|
||||
{
|
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, CN779_TX_MIN_DATARATE, CN779_TX_MAX_DATARATE );
|
||||
@@ -529,7 +530,6 @@ bool RegionCN779RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
{
|
||||
RadioModems_t modem;
|
||||
int8_t dr = rxConfig->Datarate;
|
||||
uint8_t maxPayload = 0;
|
||||
int8_t phyDr = 0;
|
||||
uint32_t frequency = rxConfig->Frequency;
|
||||
|
||||
@@ -566,15 +566,7 @@ bool RegionCN779RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
Radio.SetRxConfig( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
|
||||
}
|
||||
|
||||
if( rxConfig->RepeaterSupport == true )
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateRepeaterCN779[dr];
|
||||
}
|
||||
else
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateCN779[dr];
|
||||
}
|
||||
Radio.SetMaxPayloadLength( modem, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
|
||||
Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarateCN779[dr] + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE );
|
||||
|
||||
*datarate = (uint8_t) dr;
|
||||
return true;
|
||||
@@ -597,18 +589,19 @@ bool RegionCN779TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime
|
||||
if( txConfig->Datarate == DR_7 )
|
||||
{ // High Speed FSK channel
|
||||
modem = MODEM_FSK;
|
||||
Radio.SetTxConfig( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 4000 );
|
||||
}
|
||||
else
|
||||
{
|
||||
modem = MODEM_LORA;
|
||||
Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 );
|
||||
}
|
||||
|
||||
// Update time-on-air
|
||||
*txTimeOnAir = GetTimeOnAir( txConfig->Datarate, txConfig->PktLen );
|
||||
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( modem, txConfig->PktLen );
|
||||
// Get the time-on-air of the next tx frame
|
||||
*txTimeOnAir = Radio.TimeOnAir( modem, txConfig->PktLen );
|
||||
|
||||
*txPower = txPowerLimited;
|
||||
return true;
|
||||
@@ -832,74 +825,54 @@ int8_t RegionCN779AlternateDr( int8_t currentDr, AlternateDrType_t type )
|
||||
return currentDr;
|
||||
}
|
||||
|
||||
void RegionCN779CalcBackOff( CalcBackOffParams_t* calcBackOff )
|
||||
{
|
||||
RegionCommonCalcBackOffParams_t calcBackOffParams;
|
||||
|
||||
calcBackOffParams.Channels = NvmCtx.Channels;
|
||||
calcBackOffParams.Bands = NvmCtx.Bands;
|
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest;
|
||||
calcBackOffParams.Joined = calcBackOff->Joined;
|
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled;
|
||||
calcBackOffParams.Channel = calcBackOff->Channel;
|
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime;
|
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir;
|
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams );
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionCN779NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTx = 0;
|
||||
uint8_t nbRestrictedChannels = 0;
|
||||
uint8_t enabledChannels[CN779_MAX_NB_CHANNELS] = { 0 };
|
||||
TimerTime_t nextTxDelay = 0;
|
||||
RegionCommonIdentifyChannelsParam_t identifyChannelsParam;
|
||||
RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams;
|
||||
LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
|
||||
if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 )
|
||||
{ // Reactivate default channels
|
||||
NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 );
|
||||
}
|
||||
|
||||
if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) )
|
||||
{
|
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0;
|
||||
// Search how many channels are enabled
|
||||
countChannelsParams.Joined = nextChanParams->Joined;
|
||||
countChannelsParams.Datarate = nextChanParams->Datarate;
|
||||
countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask;
|
||||
countChannelsParams.Channels = NvmCtx.Channels;
|
||||
countChannelsParams.Bands = NvmCtx.Bands;
|
||||
countChannelsParams.MaxNbChannels = CN779_MAX_NB_CHANNELS;
|
||||
countChannelsParams.JoinChannels = CN779_JOIN_CHANNELS;
|
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, NvmCtx.Bands, CN779_MAX_NB_BANDS );
|
||||
identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff;
|
||||
identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx;
|
||||
identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;
|
||||
identifyChannelsParam.MaxBands = CN779_MAX_NB_BANDS;
|
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Joined, nextChanParams->Datarate,
|
||||
NvmCtx.ChannelsMask, NvmCtx.Channels,
|
||||
NvmCtx.Bands, enabledChannels, &delayTx );
|
||||
}
|
||||
else
|
||||
{
|
||||
delayTx++;
|
||||
nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx );
|
||||
}
|
||||
identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;
|
||||
identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;
|
||||
identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );
|
||||
|
||||
if( nbEnabledChannels > 0 )
|
||||
identifyChannelsParam.CountNbOfEnabledChannelsParam = &countChannelsParams;
|
||||
|
||||
status = RegionCommonIdentifyChannels( &identifyChannelsParam, aggregatedTimeOff, enabledChannels,
|
||||
&nbEnabledChannels, &nbRestrictedChannels, time );
|
||||
|
||||
if( status == LORAMAC_STATUS_OK )
|
||||
{
|
||||
// We found a valid channel
|
||||
*channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
|
||||
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_OK;
|
||||
}
|
||||
else
|
||||
else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND )
|
||||
{
|
||||
if( delayTx > 0 )
|
||||
{
|
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay;
|
||||
return LORAMAC_STATUS_DUTYCYCLE_RESTRICTED;
|
||||
}
|
||||
// Datarate not supported by any channel, restore defaults
|
||||
NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 );
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionCN779ChannelAdd( ChannelAddParams_t* channelAdd )
|
||||
|
@@ -37,6 +37,11 @@
|
||||
#ifndef __REGION_CN779_H__
|
||||
#define __REGION_CN779_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
@@ -199,6 +204,11 @@
|
||||
*/
|
||||
#define CN779_BEACON_CHANNEL_FREQ 785000000
|
||||
|
||||
/*!
|
||||
* Ping slot channel frequency
|
||||
*/
|
||||
#define CN779_PING_SLOT_CHANNEL_FREQ 785000000
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
@@ -236,9 +246,9 @@
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
* Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission }
|
||||
*/
|
||||
#define CN779_BAND0 { 100, CN779_MAX_TX_POWER, 0, 0, 0 } // 1.0 %
|
||||
#define CN779_BAND0 { 100, CN779_MAX_TX_POWER, 0, 0, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1
|
||||
@@ -273,15 +283,10 @@ static const uint8_t DataratesCN779[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
|
||||
static const uint32_t BandwidthsCN779[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
* Maximum payload with respect to the datarate index.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateCN779[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterCN779[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
@@ -437,13 +442,6 @@ uint8_t RegionCN779DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
*/
|
||||
int8_t RegionCN779AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionCN779CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
@@ -505,4 +503,8 @@ uint8_t RegionCN779ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d
|
||||
|
||||
/*! \} defgroup REGIONCN779 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __REGION_CN779_H__
|
||||
|
@@ -33,9 +33,108 @@
|
||||
#include "utilities.h"
|
||||
#include "RegionCommon.h"
|
||||
|
||||
#define BACKOFF_DC_1_HOUR 100
|
||||
#define BACKOFF_DC_10_HOURS 1000
|
||||
#define BACKOFF_DC_24_HOURS 10000
|
||||
#define BACKOFF_DC_1_HOUR 100
|
||||
#define BACKOFF_DC_10_HOURS 1000
|
||||
#define BACKOFF_DC_24_HOURS 10000
|
||||
#define BACKOFF_DC_TIMER_PERIOD_FACTOR 100
|
||||
|
||||
#ifndef DUTY_CYCLE_TIME_PERIOD
|
||||
/*!
|
||||
* Default duty cycle time period is 1 hour = 3600000 ms
|
||||
*/
|
||||
#define DUTY_CYCLE_TIME_PERIOD 3600000
|
||||
#endif
|
||||
|
||||
static uint16_t GetDutyCycle( Band_t* band, bool joined, SysTime_t elapsedTimeSinceStartup )
|
||||
{
|
||||
uint16_t joinDutyCycle = RegionCommonGetJoinDc( elapsedTimeSinceStartup );
|
||||
uint16_t dutyCycle = band->DCycle;
|
||||
|
||||
if( joined == false )
|
||||
{
|
||||
// Get the join duty cycle which depends on the runtime
|
||||
joinDutyCycle = RegionCommonGetJoinDc( elapsedTimeSinceStartup );
|
||||
// Take the most restrictive duty cycle
|
||||
dutyCycle = MAX( dutyCycle, joinDutyCycle );
|
||||
}
|
||||
|
||||
// Prevent value of 0
|
||||
if( dutyCycle == 0 )
|
||||
{
|
||||
dutyCycle = 1;
|
||||
}
|
||||
|
||||
return dutyCycle;
|
||||
}
|
||||
|
||||
static uint16_t SetMaxTimeCredits( Band_t* band, bool joined, SysTime_t elapsedTimeSinceStartup )
|
||||
{
|
||||
uint16_t dutyCycle = band->DCycle;
|
||||
uint8_t timePeriodFactor = 1;
|
||||
|
||||
// Get the band duty cycle. If not joined, the function either returns the join duty cycle
|
||||
// or the band duty cycle, whichever is more restrictive.
|
||||
dutyCycle = GetDutyCycle( band, joined, elapsedTimeSinceStartup );
|
||||
|
||||
if( joined == false )
|
||||
{
|
||||
// Apply a factor to increase the maximum time period of observation
|
||||
timePeriodFactor = dutyCycle / BACKOFF_DC_TIMER_PERIOD_FACTOR;
|
||||
}
|
||||
|
||||
// Setup the maximum allowed credits
|
||||
band->MaxTimeCredits = DUTY_CYCLE_TIME_PERIOD * timePeriodFactor;
|
||||
|
||||
// In case if it is the first time, update also the current
|
||||
// time credits
|
||||
if( band->LastBandUpdateTime == 0 )
|
||||
{
|
||||
band->TimeCredits = band->MaxTimeCredits;
|
||||
}
|
||||
|
||||
return dutyCycle;
|
||||
}
|
||||
|
||||
static uint16_t UpdateTimeCredits( Band_t* band, bool joined, bool dutyCycleEnabled,
|
||||
bool lastTxIsJoinRequest, SysTime_t elapsedTimeSinceStartup,
|
||||
TimerTime_t currentTime )
|
||||
{
|
||||
uint16_t dutyCycle = SetMaxTimeCredits( band, joined, elapsedTimeSinceStartup );
|
||||
|
||||
if( joined == false )
|
||||
{
|
||||
if( ( dutyCycleEnabled == false ) &&
|
||||
( lastTxIsJoinRequest == false ) )
|
||||
{
|
||||
// This is the case when the duty cycle is off and the last uplink frame was not a join.
|
||||
// This could happen in case of a rejoin, e.g. in compliance test mode.
|
||||
// In this special case we have to set the time off to 0, since the join duty cycle shall only
|
||||
// be applied after the first join request.
|
||||
band->TimeCredits = band->MaxTimeCredits;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( dutyCycleEnabled == false )
|
||||
{
|
||||
band->TimeCredits = band->MaxTimeCredits;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the difference between now and the last update
|
||||
band->TimeCredits += TimerGetElapsedTime( band->LastBandUpdateTime );
|
||||
|
||||
// Limit band credits to maximum
|
||||
if( band->TimeCredits > band->MaxTimeCredits )
|
||||
{
|
||||
band->TimeCredits = band->MaxTimeCredits;
|
||||
}
|
||||
|
||||
// Synchronize update time
|
||||
band->LastBandUpdateTime = currentTime;
|
||||
|
||||
return dutyCycle;
|
||||
}
|
||||
|
||||
static uint8_t CountChannels( uint16_t mask, uint8_t nbBits )
|
||||
{
|
||||
@@ -147,62 +246,87 @@ void RegionCommonChanMaskCopy( uint16_t* channelsMaskDest, uint16_t* channelsMas
|
||||
}
|
||||
}
|
||||
|
||||
void RegionCommonSetBandTxDone( bool joined, Band_t* band, TimerTime_t lastTxDone )
|
||||
void RegionCommonSetBandTxDone( Band_t* band, TimerTime_t lastTxAirTime, bool joined, SysTime_t elapsedTimeSinceStartup )
|
||||
{
|
||||
if( joined == true )
|
||||
// Get the band duty cycle. If not joined, the function either returns the join duty cycle
|
||||
// or the band duty cycle, whichever is more restrictive.
|
||||
uint16_t dutyCycle = GetDutyCycle( band, joined, elapsedTimeSinceStartup );
|
||||
|
||||
// Reduce with transmission time
|
||||
if( band->TimeCredits > ( lastTxAirTime * dutyCycle ) )
|
||||
{
|
||||
band->LastTxDoneTime = lastTxDone;
|
||||
// Reduce time credits by the time of air
|
||||
band->TimeCredits -= ( lastTxAirTime * dutyCycle );
|
||||
}
|
||||
else
|
||||
{
|
||||
band->LastTxDoneTime = lastTxDone;
|
||||
band->LastJoinTxDoneTime = lastTxDone;
|
||||
band->TimeCredits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
TimerTime_t RegionCommonUpdateBandTimeOff( bool joined, bool dutyCycle, Band_t* bands, uint8_t nbBands )
|
||||
TimerTime_t RegionCommonUpdateBandTimeOff( bool joined, Band_t* bands,
|
||||
uint8_t nbBands, bool dutyCycleEnabled,
|
||||
bool lastTxIsJoinRequest, SysTime_t elapsedTimeSinceStartup,
|
||||
TimerTime_t expectedTimeOnAir )
|
||||
{
|
||||
TimerTime_t nextTxDelay = ( TimerTime_t )( -1 );
|
||||
TimerTime_t minTimeToWait = TIMERTIME_T_MAX;
|
||||
TimerTime_t currentTime = TimerGetCurrentTime( );
|
||||
TimerTime_t creditCosts = 0;
|
||||
uint16_t dutyCycle = 1;
|
||||
uint8_t validBands = 0;
|
||||
|
||||
// Update bands Time OFF
|
||||
for( uint8_t i = 0; i < nbBands; i++ )
|
||||
{
|
||||
if( joined == false )
|
||||
{
|
||||
TimerTime_t txDoneTime = MAX( TimerGetElapsedTime( bands[i].LastJoinTxDoneTime ),
|
||||
( dutyCycle == true ) ? TimerGetElapsedTime( bands[i].LastTxDoneTime ) : 0 );
|
||||
// Synchronization of bands and credits
|
||||
dutyCycle = UpdateTimeCredits( &bands[i], joined, dutyCycleEnabled,
|
||||
lastTxIsJoinRequest, elapsedTimeSinceStartup,
|
||||
currentTime );
|
||||
|
||||
if( bands[i].TimeOff <= txDoneTime )
|
||||
{
|
||||
bands[i].TimeOff = 0;
|
||||
}
|
||||
if( bands[i].TimeOff != 0 )
|
||||
{
|
||||
nextTxDelay = MIN( bands[i].TimeOff - txDoneTime, nextTxDelay );
|
||||
}
|
||||
// Calculate the credit costs for the next transmission
|
||||
// with the duty cycle and the expected time on air
|
||||
creditCosts = expectedTimeOnAir * dutyCycle;
|
||||
|
||||
// Check if the band is ready for transmission. Its ready,
|
||||
// when the duty cycle is off, or the TimeCredits of the band
|
||||
// is higher than the credit costs for the transmission.
|
||||
if( ( bands[i].TimeCredits > creditCosts ) ||
|
||||
( dutyCycleEnabled == false ) )
|
||||
{
|
||||
bands[i].ReadyForTransmission = true;
|
||||
// This band is a potential candidate for an
|
||||
// upcoming transmission, so increase the counter.
|
||||
validBands++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( dutyCycle == true )
|
||||
// In this case, the band has not enough credits
|
||||
// for the next transmission.
|
||||
bands[i].ReadyForTransmission = false;
|
||||
|
||||
if( bands[i].MaxTimeCredits > creditCosts )
|
||||
{
|
||||
if( bands[i].TimeOff <= TimerGetElapsedTime( bands[i].LastTxDoneTime ) )
|
||||
{
|
||||
bands[i].TimeOff = 0;
|
||||
}
|
||||
if( bands[i].TimeOff != 0 )
|
||||
{
|
||||
nextTxDelay = MIN( bands[i].TimeOff - TimerGetElapsedTime( bands[i].LastTxDoneTime ),
|
||||
nextTxDelay );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nextTxDelay = 0;
|
||||
bands[i].TimeOff = 0;
|
||||
// The band can only be taken into account, if the maximum credits
|
||||
// of the band are higher than the credit costs.
|
||||
// We calculate the minTimeToWait among the bands which are not
|
||||
// ready for transmission and which are potentially available
|
||||
// for a transmission in the future.
|
||||
minTimeToWait = MIN( minTimeToWait, ( creditCosts - bands[i].TimeCredits ) );
|
||||
// This band is a potential candidate for an
|
||||
// upcoming transmission (even if its time credits are not enough
|
||||
// at the moment), so increase the counter.
|
||||
validBands++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nextTxDelay;
|
||||
|
||||
|
||||
if( validBands == 0 )
|
||||
{
|
||||
// There is no valid band available to handle a transmission
|
||||
// in the given DUTY_CYCLE_TIME_PERIOD.
|
||||
return TIMERTIME_T_MAX;
|
||||
}
|
||||
return minTimeToWait;
|
||||
}
|
||||
|
||||
uint8_t RegionCommonParseLinkAdrReq( uint8_t* payload, RegionCommonLinkAdrParams_t* linkAdrParams )
|
||||
@@ -311,50 +435,6 @@ int8_t RegionCommonComputeTxPower( int8_t txPowerIndex, float maxEirp, float ant
|
||||
return phyTxPower;
|
||||
}
|
||||
|
||||
void RegionCommonCalcBackOff( RegionCommonCalcBackOffParams_t* calcBackOffParams )
|
||||
{
|
||||
uint8_t bandIdx = calcBackOffParams->Channels[calcBackOffParams->Channel].Band;
|
||||
uint16_t dutyCycle = calcBackOffParams->Bands[bandIdx].DCycle;
|
||||
uint16_t joinDutyCycle = 0;
|
||||
|
||||
// Reset time-off to initial value.
|
||||
calcBackOffParams->Bands[bandIdx].TimeOff = 0;
|
||||
|
||||
if( calcBackOffParams->Joined == false )
|
||||
{
|
||||
// Get the join duty cycle
|
||||
joinDutyCycle = RegionCommonGetJoinDc( calcBackOffParams->ElapsedTime );
|
||||
// Apply the most restricting duty cycle
|
||||
dutyCycle = MAX( dutyCycle, joinDutyCycle );
|
||||
// Reset the timeoff if the last frame was not a join request and when the duty cycle is not enabled
|
||||
if( ( calcBackOffParams->DutyCycleEnabled == false ) && ( calcBackOffParams->LastTxIsJoinRequest == false ) )
|
||||
{
|
||||
// This is the case when the duty cycle is off and the last uplink frame was not a join.
|
||||
// This could happen in case of a rejoin, e.g. in compliance test mode.
|
||||
// In this special case we have to set the time off to 0, since the join duty cycle shall only
|
||||
// be applied after the first join request.
|
||||
calcBackOffParams->Bands[bandIdx].TimeOff = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Apply band time-off.
|
||||
calcBackOffParams->Bands[bandIdx].TimeOff = calcBackOffParams->TxTimeOnAir * dutyCycle - calcBackOffParams->TxTimeOnAir;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( calcBackOffParams->DutyCycleEnabled == true )
|
||||
{
|
||||
calcBackOffParams->Bands[bandIdx].TimeOff = calcBackOffParams->TxTimeOnAir * dutyCycle - calcBackOffParams->TxTimeOnAir;
|
||||
}
|
||||
else
|
||||
{
|
||||
calcBackOffParams->Bands[bandIdx].TimeOff = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RegionCommonRxBeaconSetup( RegionCommonRxBeaconSetupParams_t* rxBeaconSetupParams )
|
||||
{
|
||||
bool rxContinuous = true;
|
||||
@@ -382,3 +462,90 @@ void RegionCommonRxBeaconSetup( RegionCommonRxBeaconSetupParams_t* rxBeaconSetup
|
||||
|
||||
Radio.Rx( rxBeaconSetupParams->RxTime );
|
||||
}
|
||||
|
||||
void RegionCommonCountNbOfEnabledChannels( RegionCommonCountNbOfEnabledChannelsParams_t* countNbOfEnabledChannelsParams,
|
||||
uint8_t* enabledChannels, uint8_t* nbEnabledChannels, uint8_t* nbRestrictedChannels )
|
||||
{
|
||||
uint8_t nbChannelCount = 0;
|
||||
uint8_t nbRestrictedChannelsCount = 0;
|
||||
|
||||
for( uint8_t i = 0, k = 0; i < countNbOfEnabledChannelsParams->MaxNbChannels; i += 16, k++ )
|
||||
{
|
||||
for( uint8_t j = 0; j < 16; j++ )
|
||||
{
|
||||
if( ( countNbOfEnabledChannelsParams->ChannelsMask[k] & ( 1 << j ) ) != 0 )
|
||||
{
|
||||
if( countNbOfEnabledChannelsParams->Channels[i + j].Frequency == 0 )
|
||||
{ // Check if the channel is enabled
|
||||
continue;
|
||||
}
|
||||
if( ( countNbOfEnabledChannelsParams->Joined == false ) &&
|
||||
( countNbOfEnabledChannelsParams->JoinChannels > 0 ) )
|
||||
{
|
||||
if( ( countNbOfEnabledChannelsParams->JoinChannels & ( 1 << j ) ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( RegionCommonValueInRange( countNbOfEnabledChannelsParams->Datarate,
|
||||
countNbOfEnabledChannelsParams->Channels[i + j].DrRange.Fields.Min,
|
||||
countNbOfEnabledChannelsParams->Channels[i + j].DrRange.Fields.Max ) == false )
|
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue;
|
||||
}
|
||||
if( countNbOfEnabledChannelsParams->Bands[countNbOfEnabledChannelsParams->Channels[i + j].Band].ReadyForTransmission == false )
|
||||
{ // Check if the band is available for transmission
|
||||
nbRestrictedChannelsCount++;
|
||||
continue;
|
||||
}
|
||||
enabledChannels[nbChannelCount++] = i + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
*nbEnabledChannels = nbChannelCount;
|
||||
*nbRestrictedChannels = nbRestrictedChannelsCount;
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionCommonIdentifyChannels( RegionCommonIdentifyChannelsParam_t* identifyChannelsParam,
|
||||
TimerTime_t* aggregatedTimeOff, uint8_t* enabledChannels,
|
||||
uint8_t* nbEnabledChannels, uint8_t* nbRestrictedChannels,
|
||||
TimerTime_t* nextTxDelay )
|
||||
{
|
||||
TimerTime_t elapsed = TimerGetElapsedTime( identifyChannelsParam->LastAggrTx );
|
||||
*nextTxDelay = identifyChannelsParam->AggrTimeOff - elapsed;
|
||||
*nbRestrictedChannels = 1;
|
||||
*nbEnabledChannels = 0;
|
||||
|
||||
if( ( identifyChannelsParam->LastAggrTx == 0 ) ||
|
||||
( identifyChannelsParam->AggrTimeOff <= elapsed ) )
|
||||
{
|
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0;
|
||||
|
||||
// Update bands Time OFF
|
||||
*nextTxDelay = RegionCommonUpdateBandTimeOff( identifyChannelsParam->CountNbOfEnabledChannelsParam->Joined,
|
||||
identifyChannelsParam->CountNbOfEnabledChannelsParam->Bands,
|
||||
identifyChannelsParam->MaxBands,
|
||||
identifyChannelsParam->DutyCycleEnabled,
|
||||
identifyChannelsParam->LastTxIsJoinRequest,
|
||||
identifyChannelsParam->ElapsedTimeSinceStartUp,
|
||||
identifyChannelsParam->ExpectedTimeOnAir );
|
||||
|
||||
RegionCommonCountNbOfEnabledChannels( identifyChannelsParam->CountNbOfEnabledChannelsParam, enabledChannels,
|
||||
nbEnabledChannels, nbRestrictedChannels );
|
||||
}
|
||||
|
||||
if( *nbEnabledChannels > 0 )
|
||||
{
|
||||
*nextTxDelay = 0;
|
||||
return LORAMAC_STATUS_OK;
|
||||
}
|
||||
else if( *nbRestrictedChannels > 0 )
|
||||
{
|
||||
return LORAMAC_STATUS_DUTYCYCLE_RESTRICTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
}
|
||||
}
|
||||
|
@@ -37,9 +37,23 @@
|
||||
#ifndef __REGIONCOMMON_H__
|
||||
#define __REGIONCOMMON_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "LoRaMacTypes.h"
|
||||
#include "LoRaMacHeaderTypes.h"
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
* Default ping slots periodicity
|
||||
*
|
||||
* Periodicity is equal to 2^REGION_COMMON_DEFAULT_PING_SLOT_PERIODICITY seconds.
|
||||
* Example: 2^7 = 128 seconds. The end-device will open an Rx slot every 128 seconds.
|
||||
*/
|
||||
#define REGION_COMMON_DEFAULT_PING_SLOT_PERIODICITY 7
|
||||
|
||||
typedef struct sRegionCommonLinkAdrParams
|
||||
{
|
||||
/*!
|
||||
@@ -132,42 +146,6 @@ typedef struct sRegionCommonLinkAdrReqVerifyParams
|
||||
int8_t MaxTxPower;
|
||||
}RegionCommonLinkAdrReqVerifyParams_t;
|
||||
|
||||
typedef struct sRegionCommonCalcBackOffParams
|
||||
{
|
||||
/*!
|
||||
* A pointer to region specific channels.
|
||||
*/
|
||||
ChannelParams_t* Channels;
|
||||
/*!
|
||||
* A pointer to region specific bands.
|
||||
*/
|
||||
Band_t* Bands;
|
||||
/*!
|
||||
* Set to true, if the last uplink was a join request.
|
||||
*/
|
||||
bool LastTxIsJoinRequest;
|
||||
/*!
|
||||
* Set to true, if the node is joined.
|
||||
*/
|
||||
bool Joined;
|
||||
/*!
|
||||
* Set to true, if the duty cycle is enabled.
|
||||
*/
|
||||
bool DutyCycleEnabled;
|
||||
/*!
|
||||
* The current channel.
|
||||
*/
|
||||
uint8_t Channel;
|
||||
/*!
|
||||
* The elapsed time since initialization.
|
||||
*/
|
||||
SysTime_t ElapsedTime;
|
||||
/*!
|
||||
* The time on air of the last Tx frame.
|
||||
*/
|
||||
TimerTime_t TxTimeOnAir;
|
||||
}RegionCommonCalcBackOffParams_t;
|
||||
|
||||
typedef struct sRegionCommonRxBeaconSetupParams
|
||||
{
|
||||
/*!
|
||||
@@ -200,6 +178,90 @@ typedef struct sRegionCommonRxBeaconSetupParams
|
||||
uint16_t SymbolTimeout;
|
||||
}RegionCommonRxBeaconSetupParams_t;
|
||||
|
||||
typedef struct sRegionCommonCountNbOfEnabledChannelsParams
|
||||
{
|
||||
/*!
|
||||
* Set to true, if the device is joined.
|
||||
*/
|
||||
bool Joined;
|
||||
/*!
|
||||
* The datarate to count the available channels.
|
||||
*/
|
||||
uint8_t Datarate;
|
||||
/*!
|
||||
* A pointer to the channels mask to verify.
|
||||
*/
|
||||
uint16_t* ChannelsMask;
|
||||
/*!
|
||||
* A pointer to the channels.
|
||||
*/
|
||||
ChannelParams_t* Channels;
|
||||
/*!
|
||||
* A pointer to the bands.
|
||||
*/
|
||||
Band_t* Bands;
|
||||
/*!
|
||||
* The number of available channels.
|
||||
*/
|
||||
uint16_t MaxNbChannels;
|
||||
/*!
|
||||
* A bitmask containing the join channels.
|
||||
*/
|
||||
uint16_t JoinChannels;
|
||||
}RegionCommonCountNbOfEnabledChannelsParams_t;
|
||||
|
||||
typedef struct sRegionCommonIdentifyChannelsParam
|
||||
{
|
||||
/*!
|
||||
* Aggregated time-off time.
|
||||
*/
|
||||
TimerTime_t AggrTimeOff;
|
||||
/*!
|
||||
* Time of the last aggregated TX.
|
||||
*/
|
||||
TimerTime_t LastAggrTx;
|
||||
/*!
|
||||
* Set to true, if the duty cycle is enabled, otherwise false.
|
||||
*/
|
||||
bool DutyCycleEnabled;
|
||||
/*!
|
||||
* Maximum number of bands.
|
||||
*/
|
||||
uint8_t MaxBands;
|
||||
/*!
|
||||
* Elapsed time since the start of the node.
|
||||
*/
|
||||
SysTime_t ElapsedTimeSinceStartUp;
|
||||
/*!
|
||||
* Joined Set to true, if the last uplink was a join request
|
||||
*/
|
||||
bool LastTxIsJoinRequest;
|
||||
/*!
|
||||
* Expected time-on-air
|
||||
*/
|
||||
TimerTime_t ExpectedTimeOnAir;
|
||||
/*!
|
||||
* Pointer to a structure of RegionCommonCountNbOfEnabledChannelsParams_t.
|
||||
*/
|
||||
RegionCommonCountNbOfEnabledChannelsParams_t* CountNbOfEnabledChannelsParam;
|
||||
}RegionCommonIdentifyChannelsParam_t;
|
||||
|
||||
typedef struct sRegionCommonSetDutyCycleParams
|
||||
{
|
||||
/*!
|
||||
* Duty cycle period.
|
||||
*/
|
||||
TimerTime_t DutyCycleTimePeriod;
|
||||
/*!
|
||||
* Number of bands available.
|
||||
*/
|
||||
uint8_t MaxBands;
|
||||
/*!
|
||||
* A pointer to the bands.
|
||||
*/
|
||||
Band_t* Bands;
|
||||
}RegionCommonSetDutyCycleParams_t;
|
||||
|
||||
/*!
|
||||
* \brief Calculates the join duty cycle.
|
||||
* This is a generic function and valid for all regions.
|
||||
@@ -289,13 +351,15 @@ void RegionCommonChanMaskCopy( uint16_t* channelsMaskDest, uint16_t* channelsMas
|
||||
* \brief Sets the last tx done property.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [IN] joined Set to true, if the node has joined the network
|
||||
*
|
||||
* \param [IN] band The band to be updated.
|
||||
*
|
||||
* \param [IN] lastTxDone The time of the last TX done.
|
||||
* \param [IN] lastTxAirTime The time on air of the last TX frame.
|
||||
*
|
||||
* \param [IN] joined Set to true if the device has joined.
|
||||
*
|
||||
* \param [IN] elapsedTimeSinceStartup Elapsed time since initialization.
|
||||
*/
|
||||
void RegionCommonSetBandTxDone( bool joined, Band_t* band, TimerTime_t lastTxDone );
|
||||
void RegionCommonSetBandTxDone( Band_t* band, TimerTime_t lastTxAirTime, bool joined, SysTime_t elapsedTimeSinceStartup );
|
||||
|
||||
/*!
|
||||
* \brief Updates the time-offs of the bands.
|
||||
@@ -303,15 +367,24 @@ void RegionCommonSetBandTxDone( bool joined, Band_t* band, TimerTime_t lastTxDon
|
||||
*
|
||||
* \param [IN] joined Set to true, if the node has joined the network
|
||||
*
|
||||
* \param [IN] dutyCycle Set to true, if the duty cycle is enabled.
|
||||
*
|
||||
* \param [IN] bands A pointer to the bands.
|
||||
*
|
||||
* \param [IN] nbBands The number of bands available.
|
||||
*
|
||||
* \param [IN] dutyCycleEnabled Set to true, if the duty cycle is enabled.
|
||||
*
|
||||
* \param [IN] lastTxIsJoinRequest Set to true, if the last TX is a join request.
|
||||
*
|
||||
* \param [IN] elapsedTimeSinceStartup Elapsed time since start up.
|
||||
*
|
||||
* \param [IN] expectedTimeOnAir Expected time on air for the next transmission.
|
||||
*
|
||||
* \retval Returns the time which must be waited to perform the next uplink.
|
||||
*/
|
||||
TimerTime_t RegionCommonUpdateBandTimeOff( bool joined, bool dutyCycle, Band_t* bands, uint8_t nbBands );
|
||||
TimerTime_t RegionCommonUpdateBandTimeOff( bool joined, Band_t* bands,
|
||||
uint8_t nbBands, bool dutyCycleEnabled,
|
||||
bool lastTxIsJoinRequest, SysTime_t elapsedTimeSinceStartup,
|
||||
TimerTime_t expectedTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief Parses the parameter of an LinkAdrRequest.
|
||||
@@ -385,7 +458,7 @@ void RegionCommonComputeRxWindowParameters( double tSymbol, uint8_t minRxSymbols
|
||||
|
||||
/*!
|
||||
* \brief Computes the txPower, based on the max EIRP and the antenna gain.
|
||||
*
|
||||
*
|
||||
* \remark US915 region uses a conducted power as input value for maxEirp.
|
||||
* Thus, the antennaGain parameter must be set to 0.
|
||||
*
|
||||
@@ -400,13 +473,6 @@ void RegionCommonComputeRxWindowParameters( double tSymbol, uint8_t minRxSymbols
|
||||
*/
|
||||
int8_t RegionCommonComputeTxPower( int8_t txPowerIndex, float maxEirp, float antennaGain );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the duty cycle for the current band.
|
||||
*
|
||||
* \param [IN] calcBackOffParams A pointer to the input parameters.
|
||||
*/
|
||||
void RegionCommonCalcBackOff( RegionCommonCalcBackOffParams_t* calcBackOffParams );
|
||||
|
||||
/*!
|
||||
* \brief Sets up the radio into RX beacon mode.
|
||||
*
|
||||
@@ -414,6 +480,52 @@ void RegionCommonCalcBackOff( RegionCommonCalcBackOffParams_t* calcBackOffParams
|
||||
*/
|
||||
void RegionCommonRxBeaconSetup( RegionCommonRxBeaconSetupParams_t* rxBeaconSetupParams );
|
||||
|
||||
/*!
|
||||
* \brief Counts the number of enabled channels.
|
||||
*
|
||||
* \param [IN] countNbOfEnabledChannelsParams A pointer to the input parameters.
|
||||
*
|
||||
* \param [OUT] enabledChannels A pointer to an array of size XX_MAX_NB_CHANNELS. The function
|
||||
* stores the available channels into this array.
|
||||
*
|
||||
* \param [OUT] nbEnabledChannels The number of available channels found.
|
||||
*
|
||||
* \param [OUT] nbRestrictedChannels It contains the number of channel
|
||||
* which are available, but restricted due to duty cycle.
|
||||
*/
|
||||
void RegionCommonCountNbOfEnabledChannels( RegionCommonCountNbOfEnabledChannelsParams_t* countNbOfEnabledChannelsParams,
|
||||
uint8_t* enabledChannels, uint8_t* nbEnabledChannels, uint8_t* nbRestrictedChannels );
|
||||
|
||||
/*!
|
||||
* \brief Identifies all channels which are available currently.
|
||||
*
|
||||
* \param [IN] identifyChannelsParam A pointer to the input parameters.
|
||||
*
|
||||
* \param [OUT] aggregatedTimeOff The new value of the aggregatedTimeOff. The function
|
||||
* may resets it to 0.
|
||||
*
|
||||
* \param [OUT] enabledChannels A pointer to an array of size XX_MAX_NB_CHANNELS. The function
|
||||
* stores the available channels into this array.
|
||||
*
|
||||
* \param [OUT] nbEnabledChannels The number of available channels found.
|
||||
*
|
||||
* \param [OUT] nbRestrictedChannels It contains the number of channel
|
||||
* which are available, but restricted due to duty cycle.
|
||||
*
|
||||
* \param [OUT] nextTxDelay Holds the time which has to be waited for the next possible
|
||||
* uplink transmission.
|
||||
*
|
||||
*\retval Status of the operation.
|
||||
*/
|
||||
LoRaMacStatus_t RegionCommonIdentifyChannels( RegionCommonIdentifyChannelsParam_t* identifyChannelsParam,
|
||||
TimerTime_t* aggregatedTimeOff, uint8_t* enabledChannels,
|
||||
uint8_t* nbEnabledChannels, uint8_t* nbRestrictedChannels,
|
||||
TimerTime_t* nextTxDelay );
|
||||
|
||||
/*! \} defgroup REGIONCOMMON */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __REGIONCOMMON_H__
|
||||
|
@@ -119,45 +119,21 @@ static bool VerifyRfFreq( uint32_t freq )
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx )
|
||||
static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTransmission = 0;
|
||||
int8_t phyDr = DataratesEU433[datarate];
|
||||
uint32_t bandwidth = GetBandwidth( datarate );
|
||||
TimerTime_t timeOnAir = 0;
|
||||
|
||||
for( uint8_t i = 0, k = 0; i < EU433_MAX_NB_CHANNELS; i += 16, k++ )
|
||||
{
|
||||
for( uint8_t j = 0; j < 16; j++ )
|
||||
{
|
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 )
|
||||
{
|
||||
if( channels[i + j].Frequency == 0 )
|
||||
{ // Check if the channel is enabled
|
||||
continue;
|
||||
}
|
||||
if( joined == false )
|
||||
{
|
||||
if( ( EU433_JOIN_CHANNELS & ( 1 << j ) ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min,
|
||||
channels[i + j].DrRange.Fields.Max ) == false )
|
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue;
|
||||
}
|
||||
if( bands[channels[i + j].Band].TimeOff > 0 )
|
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++;
|
||||
continue;
|
||||
}
|
||||
enabledChannels[nbEnabledChannels++] = i + j;
|
||||
}
|
||||
}
|
||||
if( datarate == DR_7 )
|
||||
{ // High Speed FSK channel
|
||||
timeOnAir = Radio.TimeOnAir( MODEM_FSK, bandwidth, phyDr * 1000, 0, 5, false, pktLen, true );
|
||||
}
|
||||
|
||||
*delayTx = delayTransmission;
|
||||
return nbEnabledChannels;
|
||||
else
|
||||
{
|
||||
timeOnAir = Radio.TimeOnAir( MODEM_LORA, bandwidth, phyDr, 1, 8, false, pktLen, true );
|
||||
}
|
||||
return timeOnAir;
|
||||
}
|
||||
|
||||
PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy )
|
||||
@@ -211,11 +187,6 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = MaxPayloadOfDatarateEU433[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_PAYLOAD_REPEATER:
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterEU433[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_DUTY_CYCLE:
|
||||
{
|
||||
phyParam.Value = EU433_DUTY_CYCLE_ENABLED;
|
||||
@@ -324,11 +295,26 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = EU433_BEACON_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_FREQ:
|
||||
{
|
||||
phyParam.Value = EU433_PING_SLOT_CHANNEL_FREQ;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_DR:
|
||||
{
|
||||
phyParam.Value = EU433_PING_SLOT_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_SF_FROM_DR:
|
||||
{
|
||||
phyParam.Value = DataratesEU433[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_BW_FROM_DR:
|
||||
{
|
||||
phyParam.Value = GetBandwidth( getPhy->Datarate );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
@@ -340,7 +326,8 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy )
|
||||
|
||||
void RegionEU433SetBandTxDone( SetBandTxDoneParams_t* txDone )
|
||||
{
|
||||
RegionCommonSetBandTxDone( txDone->Joined, &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxDoneTime );
|
||||
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band],
|
||||
txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );
|
||||
}
|
||||
|
||||
void RegionEU433InitDefaults( InitDefaultsParams_t* params )
|
||||
@@ -352,10 +339,14 @@ void RegionEU433InitDefaults( InitDefaultsParams_t* params )
|
||||
|
||||
switch( params->Type )
|
||||
{
|
||||
case INIT_TYPE_INIT:
|
||||
case INIT_TYPE_BANDS:
|
||||
{
|
||||
// Initialize bands
|
||||
memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * EU433_MAX_NB_BANDS );
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_INIT:
|
||||
{
|
||||
|
||||
// Channels
|
||||
NvmCtx.Channels[0] = ( ChannelParams_t ) EU433_LC1;
|
||||
@@ -364,6 +355,7 @@ void RegionEU433InitDefaults( InitDefaultsParams_t* params )
|
||||
|
||||
// Initialize the channels default mask
|
||||
NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
|
||||
|
||||
// Update the channels mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 1 );
|
||||
break;
|
||||
@@ -380,6 +372,11 @@ void RegionEU433InitDefaults( InitDefaultsParams_t* params )
|
||||
{
|
||||
// Restore channels default mask
|
||||
NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0];
|
||||
|
||||
// Channels
|
||||
NvmCtx.Channels[0] = ( ChannelParams_t ) EU433_LC1;
|
||||
NvmCtx.Channels[1] = ( ChannelParams_t ) EU433_LC2;
|
||||
NvmCtx.Channels[2] = ( ChannelParams_t ) EU433_LC3;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -399,6 +396,10 @@ bool RegionEU433Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute )
|
||||
{
|
||||
switch( phyAttribute )
|
||||
{
|
||||
case PHY_FREQUENCY:
|
||||
{
|
||||
return VerifyRfFreq( verify->Frequency );
|
||||
}
|
||||
case PHY_TX_DR:
|
||||
{
|
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, EU433_TX_MIN_DATARATE, EU433_TX_MAX_DATARATE );
|
||||
@@ -529,7 +530,6 @@ bool RegionEU433RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
{
|
||||
RadioModems_t modem;
|
||||
int8_t dr = rxConfig->Datarate;
|
||||
uint8_t maxPayload = 0;
|
||||
int8_t phyDr = 0;
|
||||
uint32_t frequency = rxConfig->Frequency;
|
||||
|
||||
@@ -566,15 +566,7 @@ bool RegionEU433RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
Radio.SetRxConfig( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
|
||||
}
|
||||
|
||||
if( rxConfig->RepeaterSupport == true )
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateRepeaterEU433[dr];
|
||||
}
|
||||
else
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateEU433[dr];
|
||||
}
|
||||
Radio.SetMaxPayloadLength( modem, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
|
||||
Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarateEU433[dr] + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE );
|
||||
|
||||
*datarate = (uint8_t) dr;
|
||||
return true;
|
||||
@@ -597,18 +589,19 @@ bool RegionEU433TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime
|
||||
if( txConfig->Datarate == DR_7 )
|
||||
{ // High Speed FSK channel
|
||||
modem = MODEM_FSK;
|
||||
Radio.SetTxConfig( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 4000 );
|
||||
}
|
||||
else
|
||||
{
|
||||
modem = MODEM_LORA;
|
||||
Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 );
|
||||
}
|
||||
|
||||
// Update time-on-air
|
||||
*txTimeOnAir = GetTimeOnAir( txConfig->Datarate, txConfig->PktLen );
|
||||
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( modem, txConfig->PktLen );
|
||||
// Get the time-on-air of the next tx frame
|
||||
*txTimeOnAir = Radio.TimeOnAir( modem, txConfig->PktLen );
|
||||
|
||||
*txPower = txPowerLimited;
|
||||
return true;
|
||||
@@ -832,74 +825,54 @@ int8_t RegionEU433AlternateDr( int8_t currentDr, AlternateDrType_t type )
|
||||
return currentDr;
|
||||
}
|
||||
|
||||
void RegionEU433CalcBackOff( CalcBackOffParams_t* calcBackOff )
|
||||
{
|
||||
RegionCommonCalcBackOffParams_t calcBackOffParams;
|
||||
|
||||
calcBackOffParams.Channels = NvmCtx.Channels;
|
||||
calcBackOffParams.Bands = NvmCtx.Bands;
|
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest;
|
||||
calcBackOffParams.Joined = calcBackOff->Joined;
|
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled;
|
||||
calcBackOffParams.Channel = calcBackOff->Channel;
|
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime;
|
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir;
|
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams );
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionEU433NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTx = 0;
|
||||
uint8_t nbRestrictedChannels = 0;
|
||||
uint8_t enabledChannels[EU433_MAX_NB_CHANNELS] = { 0 };
|
||||
TimerTime_t nextTxDelay = 0;
|
||||
RegionCommonIdentifyChannelsParam_t identifyChannelsParam;
|
||||
RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams;
|
||||
LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
|
||||
if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 )
|
||||
{ // Reactivate default channels
|
||||
NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 );
|
||||
}
|
||||
|
||||
if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) )
|
||||
{
|
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0;
|
||||
// Search how many channels are enabled
|
||||
countChannelsParams.Joined = nextChanParams->Joined;
|
||||
countChannelsParams.Datarate = nextChanParams->Datarate;
|
||||
countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask;
|
||||
countChannelsParams.Channels = NvmCtx.Channels;
|
||||
countChannelsParams.Bands = NvmCtx.Bands;
|
||||
countChannelsParams.MaxNbChannels = EU433_MAX_NB_CHANNELS;
|
||||
countChannelsParams.JoinChannels = EU433_JOIN_CHANNELS;
|
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, NvmCtx.Bands, EU433_MAX_NB_BANDS );
|
||||
identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff;
|
||||
identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx;
|
||||
identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;
|
||||
identifyChannelsParam.MaxBands = EU433_MAX_NB_BANDS;
|
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Joined, nextChanParams->Datarate,
|
||||
NvmCtx.ChannelsMask, NvmCtx.Channels,
|
||||
NvmCtx.Bands, enabledChannels, &delayTx );
|
||||
}
|
||||
else
|
||||
{
|
||||
delayTx++;
|
||||
nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx );
|
||||
}
|
||||
identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;
|
||||
identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;
|
||||
identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );
|
||||
|
||||
if( nbEnabledChannels > 0 )
|
||||
identifyChannelsParam.CountNbOfEnabledChannelsParam = &countChannelsParams;
|
||||
|
||||
status = RegionCommonIdentifyChannels( &identifyChannelsParam, aggregatedTimeOff, enabledChannels,
|
||||
&nbEnabledChannels, &nbRestrictedChannels, time );
|
||||
|
||||
if( status == LORAMAC_STATUS_OK )
|
||||
{
|
||||
// We found a valid channel
|
||||
*channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
|
||||
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_OK;
|
||||
}
|
||||
else
|
||||
else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND )
|
||||
{
|
||||
if( delayTx > 0 )
|
||||
{
|
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay;
|
||||
return LORAMAC_STATUS_DUTYCYCLE_RESTRICTED;
|
||||
}
|
||||
// Datarate not supported by any channel, restore defaults
|
||||
NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 );
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionEU433ChannelAdd( ChannelAddParams_t* channelAdd )
|
||||
|
@@ -37,6 +37,11 @@
|
||||
#ifndef __REGION_EU433_H__
|
||||
#define __REGION_EU433_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
@@ -204,6 +209,11 @@
|
||||
*/
|
||||
#define EU433_BEACON_CHANNEL_FREQ 434665000
|
||||
|
||||
/*!
|
||||
* Ping slot channel frequency
|
||||
*/
|
||||
#define EU433_PING_SLOT_CHANNEL_FREQ 434665000
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
@@ -236,9 +246,9 @@
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
* Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission }
|
||||
*/
|
||||
#define EU433_BAND0 { 100, EU433_MAX_TX_POWER, 0, 0, 0 } // 1.0 %
|
||||
#define EU433_BAND0 { 100, EU433_MAX_TX_POWER, 0, 0, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1
|
||||
@@ -274,15 +284,10 @@ static const uint8_t DataratesEU433[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
|
||||
static const uint32_t BandwidthsEU433[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
* Maximum payload with respect to the datarate index.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateEU433[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterEU433[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
@@ -438,13 +443,6 @@ uint8_t RegionEU433DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
*/
|
||||
int8_t RegionEU433AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionEU433CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
@@ -502,8 +500,12 @@ uint8_t RegionEU433ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d
|
||||
*
|
||||
* \param [IN] rxBeaconSetup Pointer to the function parameters
|
||||
*/
|
||||
void RegionEU433RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
void RegionEU433RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*! \} defgroup REGIONEU433 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __REGION_EU433_H__
|
||||
|
@@ -127,7 +127,7 @@ static bool VerifyRfFreq( uint32_t freq, uint8_t *band )
|
||||
}
|
||||
else if( ( freq >= 868700000 ) && ( freq <= 869200000 ) )
|
||||
{
|
||||
*band = 2;
|
||||
*band = 5;
|
||||
}
|
||||
else if( ( freq >= 869400000 ) && ( freq <= 869650000 ) )
|
||||
{
|
||||
@@ -144,45 +144,21 @@ static bool VerifyRfFreq( uint32_t freq, uint8_t *band )
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx )
|
||||
static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTransmission = 0;
|
||||
int8_t phyDr = DataratesEU868[datarate];
|
||||
uint32_t bandwidth = GetBandwidth( datarate );
|
||||
TimerTime_t timeOnAir = 0;
|
||||
|
||||
for( uint8_t i = 0, k = 0; i < EU868_MAX_NB_CHANNELS; i += 16, k++ )
|
||||
{
|
||||
for( uint8_t j = 0; j < 16; j++ )
|
||||
{
|
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 )
|
||||
{
|
||||
if( channels[i + j].Frequency == 0 )
|
||||
{ // Check if the channel is enabled
|
||||
continue;
|
||||
}
|
||||
if( joined == false )
|
||||
{
|
||||
if( ( EU868_JOIN_CHANNELS & ( 1 << j ) ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min,
|
||||
channels[i + j].DrRange.Fields.Max ) == false )
|
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue;
|
||||
}
|
||||
if( bands[channels[i + j].Band].TimeOff > 0 )
|
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++;
|
||||
continue;
|
||||
}
|
||||
enabledChannels[nbEnabledChannels++] = i + j;
|
||||
}
|
||||
}
|
||||
if( datarate == DR_7 )
|
||||
{ // High Speed FSK channel
|
||||
timeOnAir = Radio.TimeOnAir( MODEM_FSK, bandwidth, phyDr * 1000, 0, 5, false, pktLen, true );
|
||||
}
|
||||
|
||||
*delayTx = delayTransmission;
|
||||
return nbEnabledChannels;
|
||||
else
|
||||
{
|
||||
timeOnAir = Radio.TimeOnAir( MODEM_LORA, bandwidth, phyDr, 1, 8, false, pktLen, true );
|
||||
}
|
||||
return timeOnAir;
|
||||
}
|
||||
|
||||
PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy )
|
||||
@@ -236,11 +212,6 @@ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = MaxPayloadOfDatarateEU868[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_PAYLOAD_REPEATER:
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterEU868[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_DUTY_CYCLE:
|
||||
{
|
||||
phyParam.Value = EU868_DUTY_CYCLE_ENABLED;
|
||||
@@ -349,11 +320,26 @@ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = EU868_BEACON_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_FREQ:
|
||||
{
|
||||
phyParam.Value = EU868_PING_SLOT_CHANNEL_FREQ;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_DR:
|
||||
{
|
||||
phyParam.Value = EU868_PING_SLOT_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_SF_FROM_DR:
|
||||
{
|
||||
phyParam.Value = DataratesEU868[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_BW_FROM_DR:
|
||||
{
|
||||
phyParam.Value = GetBandwidth( getPhy->Datarate );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
@@ -365,7 +351,8 @@ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy )
|
||||
|
||||
void RegionEU868SetBandTxDone( SetBandTxDoneParams_t* txDone )
|
||||
{
|
||||
RegionCommonSetBandTxDone( txDone->Joined, &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxDoneTime );
|
||||
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band],
|
||||
txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );
|
||||
}
|
||||
|
||||
void RegionEU868InitDefaults( InitDefaultsParams_t* params )
|
||||
@@ -377,14 +364,19 @@ void RegionEU868InitDefaults( InitDefaultsParams_t* params )
|
||||
EU868_BAND2,
|
||||
EU868_BAND3,
|
||||
EU868_BAND4,
|
||||
EU868_BAND5,
|
||||
};
|
||||
|
||||
switch( params->Type )
|
||||
{
|
||||
case INIT_TYPE_INIT:
|
||||
case INIT_TYPE_BANDS:
|
||||
{
|
||||
// Initialize bands
|
||||
memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * EU868_MAX_NB_BANDS );
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_INIT:
|
||||
{
|
||||
|
||||
// Channels
|
||||
NvmCtx.Channels[0] = ( ChannelParams_t ) EU868_LC1;
|
||||
@@ -393,6 +385,7 @@ void RegionEU868InitDefaults( InitDefaultsParams_t* params )
|
||||
|
||||
// Initialize the channels default mask
|
||||
NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
|
||||
|
||||
// Update the channels mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 1 );
|
||||
break;
|
||||
@@ -409,6 +402,11 @@ void RegionEU868InitDefaults( InitDefaultsParams_t* params )
|
||||
{
|
||||
// Restore channels default mask
|
||||
NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0];
|
||||
|
||||
// Channels
|
||||
NvmCtx.Channels[0] = ( ChannelParams_t ) EU868_LC1;
|
||||
NvmCtx.Channels[1] = ( ChannelParams_t ) EU868_LC2;
|
||||
NvmCtx.Channels[2] = ( ChannelParams_t ) EU868_LC3;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -428,6 +426,11 @@ bool RegionEU868Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute )
|
||||
{
|
||||
switch( phyAttribute )
|
||||
{
|
||||
case PHY_FREQUENCY:
|
||||
{
|
||||
uint8_t band = 0;
|
||||
return VerifyRfFreq( verify->Frequency, &band );
|
||||
}
|
||||
case PHY_TX_DR:
|
||||
{
|
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, EU868_TX_MIN_DATARATE, EU868_TX_MAX_DATARATE );
|
||||
@@ -558,7 +561,6 @@ bool RegionEU868RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
{
|
||||
RadioModems_t modem;
|
||||
int8_t dr = rxConfig->Datarate;
|
||||
uint8_t maxPayload = 0;
|
||||
int8_t phyDr = 0;
|
||||
uint32_t frequency = rxConfig->Frequency;
|
||||
|
||||
@@ -595,16 +597,7 @@ bool RegionEU868RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
Radio.SetRxConfig( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
|
||||
}
|
||||
|
||||
if( rxConfig->RepeaterSupport == true )
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateRepeaterEU868[dr];
|
||||
}
|
||||
else
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateEU868[dr];
|
||||
}
|
||||
|
||||
Radio.SetMaxPayloadLength( modem, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
|
||||
Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarateEU868[dr] + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE );
|
||||
|
||||
*datarate = (uint8_t) dr;
|
||||
return true;
|
||||
@@ -627,18 +620,19 @@ bool RegionEU868TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime
|
||||
if( txConfig->Datarate == DR_7 )
|
||||
{ // High Speed FSK channel
|
||||
modem = MODEM_FSK;
|
||||
Radio.SetTxConfig( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 4000 );
|
||||
}
|
||||
else
|
||||
{
|
||||
modem = MODEM_LORA;
|
||||
Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 );
|
||||
}
|
||||
|
||||
// Update time-on-air
|
||||
*txTimeOnAir = GetTimeOnAir( txConfig->Datarate, txConfig->PktLen );
|
||||
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( modem, txConfig->PktLen );
|
||||
// Get the time-on-air of the next tx frame
|
||||
*txTimeOnAir = Radio.TimeOnAir( modem, txConfig->PktLen );
|
||||
|
||||
*txPower = txPowerLimited;
|
||||
return true;
|
||||
@@ -864,74 +858,54 @@ int8_t RegionEU868AlternateDr( int8_t currentDr, AlternateDrType_t type )
|
||||
return currentDr;
|
||||
}
|
||||
|
||||
void RegionEU868CalcBackOff( CalcBackOffParams_t* calcBackOff )
|
||||
{
|
||||
RegionCommonCalcBackOffParams_t calcBackOffParams;
|
||||
|
||||
calcBackOffParams.Channels = NvmCtx.Channels;
|
||||
calcBackOffParams.Bands = NvmCtx.Bands;
|
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest;
|
||||
calcBackOffParams.Joined = calcBackOff->Joined;
|
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled;
|
||||
calcBackOffParams.Channel = calcBackOff->Channel;
|
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime;
|
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir;
|
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams );
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionEU868NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTx = 0;
|
||||
uint8_t nbRestrictedChannels = 0;
|
||||
uint8_t enabledChannels[EU868_MAX_NB_CHANNELS] = { 0 };
|
||||
TimerTime_t nextTxDelay = 0;
|
||||
RegionCommonIdentifyChannelsParam_t identifyChannelsParam;
|
||||
RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams;
|
||||
LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
|
||||
if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 )
|
||||
{ // Reactivate default channels
|
||||
NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 );
|
||||
}
|
||||
|
||||
if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) )
|
||||
{
|
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0;
|
||||
// Search how many channels are enabled
|
||||
countChannelsParams.Joined = nextChanParams->Joined;
|
||||
countChannelsParams.Datarate = nextChanParams->Datarate;
|
||||
countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask;
|
||||
countChannelsParams.Channels = NvmCtx.Channels;
|
||||
countChannelsParams.Bands = NvmCtx.Bands;
|
||||
countChannelsParams.MaxNbChannels = EU868_MAX_NB_CHANNELS;
|
||||
countChannelsParams.JoinChannels = EU868_JOIN_CHANNELS;
|
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, NvmCtx.Bands, EU868_MAX_NB_BANDS );
|
||||
identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff;
|
||||
identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx;
|
||||
identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;
|
||||
identifyChannelsParam.MaxBands = EU868_MAX_NB_BANDS;
|
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Joined, nextChanParams->Datarate,
|
||||
NvmCtx.ChannelsMask, NvmCtx.Channels,
|
||||
NvmCtx.Bands, enabledChannels, &delayTx );
|
||||
}
|
||||
else
|
||||
{
|
||||
delayTx++;
|
||||
nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx );
|
||||
}
|
||||
identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;
|
||||
identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;
|
||||
identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );
|
||||
|
||||
if( nbEnabledChannels > 0 )
|
||||
identifyChannelsParam.CountNbOfEnabledChannelsParam = &countChannelsParams;
|
||||
|
||||
status = RegionCommonIdentifyChannels( &identifyChannelsParam, aggregatedTimeOff, enabledChannels,
|
||||
&nbEnabledChannels, &nbRestrictedChannels, time );
|
||||
|
||||
if( status == LORAMAC_STATUS_OK )
|
||||
{
|
||||
// We found a valid channel
|
||||
*channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
|
||||
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_OK;
|
||||
}
|
||||
else
|
||||
else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND )
|
||||
{
|
||||
if( delayTx > 0 )
|
||||
{
|
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay;
|
||||
return LORAMAC_STATUS_DUTYCYCLE_RESTRICTED;
|
||||
}
|
||||
// Datarate not supported by any channel, restore defaults
|
||||
NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 );
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionEU868ChannelAdd( ChannelAddParams_t* channelAdd )
|
||||
|
@@ -37,6 +37,11 @@
|
||||
#ifndef __REGION_EU868_H__
|
||||
#define __REGION_EU868_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
@@ -196,6 +201,11 @@
|
||||
*/
|
||||
#define EU868_BEACON_CHANNEL_FREQ 869525000
|
||||
|
||||
/*!
|
||||
* Ping slot channel frequency
|
||||
*/
|
||||
#define EU868_PING_SLOT_CHANNEL_FREQ 869525000
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
@@ -229,37 +239,44 @@
|
||||
/*!
|
||||
* Maximum number of bands
|
||||
*/
|
||||
#define EU868_MAX_NB_BANDS 5
|
||||
#define EU868_MAX_NB_BANDS 6
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
* Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission }
|
||||
*/
|
||||
#define EU868_BAND0 { 100 , EU868_MAX_TX_POWER, 0, 0, 0 } // 1.0 %
|
||||
#define EU868_BAND0 { 100 , EU868_MAX_TX_POWER, 0, 0, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* Band 1 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
* Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission }
|
||||
*/
|
||||
#define EU868_BAND1 { 100 , EU868_MAX_TX_POWER, 0, 0, 0 } // 1.0 %
|
||||
#define EU868_BAND1 { 100 , EU868_MAX_TX_POWER, 0, 0, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* Band 2 definition
|
||||
* Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
* Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission }
|
||||
*/
|
||||
#define EU868_BAND2 { 1000, EU868_MAX_TX_POWER, 0, 0, 0 } // 0.1 %
|
||||
#define EU868_BAND2 { 1000, EU868_MAX_TX_POWER, 0, 0, 0, 0 } // 0.1 %
|
||||
|
||||
/*!
|
||||
* Band 3 definition
|
||||
* Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
* Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission }
|
||||
*/
|
||||
#define EU868_BAND3 { 10 , EU868_MAX_TX_POWER, 0, 0, 0 } // 10.0 %
|
||||
#define EU868_BAND3 { 10 , EU868_MAX_TX_POWER, 0, 0, 0, 0 } // 10.0 %
|
||||
|
||||
/*!
|
||||
* Band 4 definition
|
||||
* Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
* Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission }
|
||||
*/
|
||||
#define EU868_BAND4 { 100 , EU868_MAX_TX_POWER, 0, 0, 0 } // 1.0 %
|
||||
#define EU868_BAND4 { 100 , EU868_MAX_TX_POWER, 0, 0, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* Band 5 definition
|
||||
* Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff,
|
||||
* DutyCycleTimePeriod, MaxAllowedTimeOnAir, AggregatedTimeOnAir, StartTimeOfPeriod }
|
||||
*/
|
||||
#define EU868_BAND5 { 1000, EU868_MAX_TX_POWER, 0, 0, 0, 0 } // 0.1 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1
|
||||
@@ -295,15 +312,10 @@ static const uint8_t DataratesEU868[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
|
||||
static const uint32_t BandwidthsEU868[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
* Maximum payload with respect to the datarate index.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateEU868[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterEU868[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
@@ -459,13 +471,6 @@ uint8_t RegionEU868DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
*/
|
||||
int8_t RegionEU868AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionEU868CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
@@ -527,4 +532,8 @@ void RegionEU868RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*! \} defgroup REGIONEU868 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __REGION_EU868_H__
|
||||
|
@@ -123,45 +123,21 @@ static bool VerifyRfFreq( uint32_t freq )
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx )
|
||||
static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTransmission = 0;
|
||||
int8_t phyDr = DataratesIN865[datarate];
|
||||
uint32_t bandwidth = GetBandwidth( datarate );
|
||||
TimerTime_t timeOnAir = 0;
|
||||
|
||||
for( uint8_t i = 0, k = 0; i < IN865_MAX_NB_CHANNELS; i += 16, k++ )
|
||||
{
|
||||
for( uint8_t j = 0; j < 16; j++ )
|
||||
{
|
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 )
|
||||
{
|
||||
if( channels[i + j].Frequency == 0 )
|
||||
{ // Check if the channel is enabled
|
||||
continue;
|
||||
}
|
||||
if( joined == false )
|
||||
{
|
||||
if( ( IN865_JOIN_CHANNELS & ( 1 << j ) ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min,
|
||||
channels[i + j].DrRange.Fields.Max ) == false )
|
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue;
|
||||
}
|
||||
if( bands[channels[i + j].Band].TimeOff > 0 )
|
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++;
|
||||
continue;
|
||||
}
|
||||
enabledChannels[nbEnabledChannels++] = i + j;
|
||||
}
|
||||
}
|
||||
if( datarate == DR_7 )
|
||||
{ // High Speed FSK channel
|
||||
timeOnAir = Radio.TimeOnAir( MODEM_FSK, bandwidth, phyDr * 1000, 0, 5, false, pktLen, true );
|
||||
}
|
||||
|
||||
*delayTx = delayTransmission;
|
||||
return nbEnabledChannels;
|
||||
else
|
||||
{
|
||||
timeOnAir = Radio.TimeOnAir( MODEM_LORA, bandwidth, phyDr, 1, 8, false, pktLen, true );
|
||||
}
|
||||
return timeOnAir;
|
||||
}
|
||||
|
||||
PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy )
|
||||
@@ -215,11 +191,6 @@ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = MaxPayloadOfDatarateIN865[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_PAYLOAD_REPEATER:
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterIN865[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_DUTY_CYCLE:
|
||||
{
|
||||
phyParam.Value = IN865_DUTY_CYCLE_ENABLED;
|
||||
@@ -328,11 +299,26 @@ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = IN865_BEACON_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_FREQ:
|
||||
{
|
||||
phyParam.Value = IN865_PING_SLOT_CHANNEL_FREQ;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_DR:
|
||||
{
|
||||
phyParam.Value = IN865_PING_SLOT_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_SF_FROM_DR:
|
||||
{
|
||||
phyParam.Value = DataratesIN865[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_BW_FROM_DR:
|
||||
{
|
||||
phyParam.Value = GetBandwidth( getPhy->Datarate );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
@@ -344,7 +330,8 @@ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy )
|
||||
|
||||
void RegionIN865SetBandTxDone( SetBandTxDoneParams_t* txDone )
|
||||
{
|
||||
RegionCommonSetBandTxDone( txDone->Joined, &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxDoneTime );
|
||||
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band],
|
||||
txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );
|
||||
}
|
||||
|
||||
void RegionIN865InitDefaults( InitDefaultsParams_t* params )
|
||||
@@ -356,10 +343,14 @@ void RegionIN865InitDefaults( InitDefaultsParams_t* params )
|
||||
|
||||
switch( params->Type )
|
||||
{
|
||||
case INIT_TYPE_INIT:
|
||||
case INIT_TYPE_BANDS:
|
||||
{
|
||||
// Initialize bands
|
||||
memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * IN865_MAX_NB_BANDS );
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_INIT:
|
||||
{
|
||||
|
||||
// Channels
|
||||
NvmCtx.Channels[0] = ( ChannelParams_t ) IN865_LC1;
|
||||
@@ -384,6 +375,11 @@ void RegionIN865InitDefaults( InitDefaultsParams_t* params )
|
||||
{
|
||||
// Restore channels default mask
|
||||
NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0];
|
||||
|
||||
// Channels
|
||||
NvmCtx.Channels[0] = ( ChannelParams_t ) IN865_LC1;
|
||||
NvmCtx.Channels[1] = ( ChannelParams_t ) IN865_LC2;
|
||||
NvmCtx.Channels[2] = ( ChannelParams_t ) IN865_LC3;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -403,6 +399,10 @@ bool RegionIN865Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute )
|
||||
{
|
||||
switch( phyAttribute )
|
||||
{
|
||||
case PHY_FREQUENCY:
|
||||
{
|
||||
return VerifyRfFreq( verify->Frequency );
|
||||
}
|
||||
case PHY_TX_DR:
|
||||
{
|
||||
if( verify->DatarateParams.Datarate == DR_6 )
|
||||
@@ -547,7 +547,6 @@ bool RegionIN865RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
{
|
||||
RadioModems_t modem;
|
||||
int8_t dr = rxConfig->Datarate;
|
||||
uint8_t maxPayload = 0;
|
||||
int8_t phyDr = 0;
|
||||
uint32_t frequency = rxConfig->Frequency;
|
||||
|
||||
@@ -584,15 +583,7 @@ bool RegionIN865RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
Radio.SetRxConfig( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
|
||||
}
|
||||
|
||||
if( rxConfig->RepeaterSupport == true )
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateRepeaterIN865[dr];
|
||||
}
|
||||
else
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateIN865[dr];
|
||||
}
|
||||
Radio.SetMaxPayloadLength( modem, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
|
||||
Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarateIN865[dr] + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE );
|
||||
|
||||
*datarate = (uint8_t) dr;
|
||||
return true;
|
||||
@@ -615,18 +606,19 @@ bool RegionIN865TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime
|
||||
if( txConfig->Datarate == DR_7 )
|
||||
{ // High Speed FSK channel
|
||||
modem = MODEM_FSK;
|
||||
Radio.SetTxConfig( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 4000 );
|
||||
}
|
||||
else
|
||||
{
|
||||
modem = MODEM_LORA;
|
||||
Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 );
|
||||
}
|
||||
|
||||
// Update time-on-air
|
||||
*txTimeOnAir = GetTimeOnAir( txConfig->Datarate, txConfig->PktLen );
|
||||
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( modem, txConfig->PktLen );
|
||||
// Get the time-on-air of the next tx frame
|
||||
*txTimeOnAir = Radio.TimeOnAir( modem, txConfig->PktLen );
|
||||
|
||||
*txPower = txPowerLimited;
|
||||
return true;
|
||||
@@ -857,74 +849,54 @@ int8_t RegionIN865AlternateDr( int8_t currentDr, AlternateDrType_t type )
|
||||
return currentDr;
|
||||
}
|
||||
|
||||
void RegionIN865CalcBackOff( CalcBackOffParams_t* calcBackOff )
|
||||
{
|
||||
RegionCommonCalcBackOffParams_t calcBackOffParams;
|
||||
|
||||
calcBackOffParams.Channels = NvmCtx.Channels;
|
||||
calcBackOffParams.Bands = NvmCtx.Bands;
|
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest;
|
||||
calcBackOffParams.Joined = calcBackOff->Joined;
|
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled;
|
||||
calcBackOffParams.Channel = calcBackOff->Channel;
|
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime;
|
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir;
|
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams );
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionIN865NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTx = 0;
|
||||
uint8_t nbRestrictedChannels = 0;
|
||||
uint8_t enabledChannels[IN865_MAX_NB_CHANNELS] = { 0 };
|
||||
TimerTime_t nextTxDelay = 0;
|
||||
RegionCommonIdentifyChannelsParam_t identifyChannelsParam;
|
||||
RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams;
|
||||
LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
|
||||
if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 )
|
||||
{ // Reactivate default channels
|
||||
NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 );
|
||||
}
|
||||
|
||||
if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) )
|
||||
{
|
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0;
|
||||
// Search how many channels are enabled
|
||||
countChannelsParams.Joined = nextChanParams->Joined;
|
||||
countChannelsParams.Datarate = nextChanParams->Datarate;
|
||||
countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask;
|
||||
countChannelsParams.Channels = NvmCtx.Channels;
|
||||
countChannelsParams.Bands = NvmCtx.Bands;
|
||||
countChannelsParams.MaxNbChannels = IN865_MAX_NB_CHANNELS;
|
||||
countChannelsParams.JoinChannels = IN865_JOIN_CHANNELS;
|
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, NvmCtx.Bands, IN865_MAX_NB_BANDS );
|
||||
identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff;
|
||||
identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx;
|
||||
identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;
|
||||
identifyChannelsParam.MaxBands = IN865_MAX_NB_BANDS;
|
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Joined, nextChanParams->Datarate,
|
||||
NvmCtx.ChannelsMask, NvmCtx.Channels,
|
||||
NvmCtx.Bands, enabledChannels, &delayTx );
|
||||
}
|
||||
else
|
||||
{
|
||||
delayTx++;
|
||||
nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx );
|
||||
}
|
||||
identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;
|
||||
identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;
|
||||
identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );
|
||||
|
||||
if( nbEnabledChannels > 0 )
|
||||
identifyChannelsParam.CountNbOfEnabledChannelsParam = &countChannelsParams;
|
||||
|
||||
status = RegionCommonIdentifyChannels( &identifyChannelsParam, aggregatedTimeOff, enabledChannels,
|
||||
&nbEnabledChannels, &nbRestrictedChannels, time );
|
||||
|
||||
if( status == LORAMAC_STATUS_OK )
|
||||
{
|
||||
// We found a valid channel
|
||||
*channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
|
||||
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_OK;
|
||||
}
|
||||
else
|
||||
else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND )
|
||||
{
|
||||
if( delayTx > 0 )
|
||||
{
|
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay;
|
||||
return LORAMAC_STATUS_DUTYCYCLE_RESTRICTED;
|
||||
}
|
||||
// Datarate not supported by any channel, restore defaults
|
||||
NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 );
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionIN865ChannelAdd( ChannelAddParams_t* channelAdd )
|
||||
|
@@ -37,6 +37,11 @@
|
||||
#ifndef __REGION_IN865_H__
|
||||
#define __REGION_IN865_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
@@ -132,7 +137,7 @@
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle
|
||||
*/
|
||||
#define IN865_DUTY_CYCLE_ENABLED 1
|
||||
#define IN865_DUTY_CYCLE_ENABLED 0
|
||||
|
||||
/*!
|
||||
* Maximum RX window duration
|
||||
@@ -196,6 +201,11 @@
|
||||
*/
|
||||
#define IN865_BEACON_CHANNEL_FREQ 866550000
|
||||
|
||||
/*!
|
||||
* Ping slot channel frequency
|
||||
*/
|
||||
#define IN865_PING_SLOT_CHANNEL_FREQ 866550000
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
@@ -233,9 +243,9 @@
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
* Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission }
|
||||
*/
|
||||
#define IN865_BAND0 { 1 , IN865_MAX_TX_POWER, 0, 0, 0 } // 100.0 %
|
||||
#define IN865_BAND0 { 1 , IN865_MAX_TX_POWER, 0, 0, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1
|
||||
@@ -271,15 +281,10 @@ static const uint8_t DataratesIN865[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
|
||||
static const uint32_t BandwidthsIN865[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
* Maximum payload with respect to the datarate index.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateIN865[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterIN865[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
|
||||
|
||||
/*!
|
||||
* Effective datarate offsets for receive window 1.
|
||||
*/
|
||||
@@ -440,13 +445,6 @@ uint8_t RegionIN865DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
*/
|
||||
int8_t RegionIN865AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionIN865CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
@@ -508,4 +506,8 @@ uint8_t RegionIN865ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d
|
||||
|
||||
/*! \} defgroup REGIONIN865 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __REGION_IN865_H__
|
||||
|
@@ -138,45 +138,12 @@ static bool VerifyRfFreq( uint32_t freq )
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx )
|
||||
static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTransmission = 0;
|
||||
int8_t phyDr = DataratesKR920[datarate];
|
||||
uint32_t bandwidth = GetBandwidth( datarate );
|
||||
|
||||
for( uint8_t i = 0, k = 0; i < KR920_MAX_NB_CHANNELS; i += 16, k++ )
|
||||
{
|
||||
for( uint8_t j = 0; j < 16; j++ )
|
||||
{
|
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 )
|
||||
{
|
||||
if( channels[i + j].Frequency == 0 )
|
||||
{ // Check if the channel is enabled
|
||||
continue;
|
||||
}
|
||||
if( joined == false )
|
||||
{
|
||||
if( ( KR920_JOIN_CHANNELS & ( 1 << j ) ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min,
|
||||
channels[i + j].DrRange.Fields.Max ) == false )
|
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue;
|
||||
}
|
||||
if( bands[channels[i + j].Band].TimeOff > 0 )
|
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++;
|
||||
continue;
|
||||
}
|
||||
enabledChannels[nbEnabledChannels++] = i + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*delayTx = delayTransmission;
|
||||
return nbEnabledChannels;
|
||||
return Radio.TimeOnAir( MODEM_LORA, bandwidth, phyDr, 1, 8, false, pktLen, true );
|
||||
}
|
||||
|
||||
PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy )
|
||||
@@ -230,11 +197,6 @@ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = MaxPayloadOfDatarateKR920[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_PAYLOAD_REPEATER:
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterKR920[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_DUTY_CYCLE:
|
||||
{
|
||||
phyParam.Value = KR920_DUTY_CYCLE_ENABLED;
|
||||
@@ -347,11 +309,26 @@ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = KR920_BEACON_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_FREQ:
|
||||
{
|
||||
phyParam.Value = KR920_PING_SLOT_CHANNEL_FREQ;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_DR:
|
||||
{
|
||||
phyParam.Value = KR920_PING_SLOT_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_SF_FROM_DR:
|
||||
{
|
||||
phyParam.Value = DataratesKR920[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_BW_FROM_DR:
|
||||
{
|
||||
phyParam.Value = GetBandwidth( getPhy->Datarate );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
@@ -363,7 +340,8 @@ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy )
|
||||
|
||||
void RegionKR920SetBandTxDone( SetBandTxDoneParams_t* txDone )
|
||||
{
|
||||
RegionCommonSetBandTxDone( txDone->Joined, &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxDoneTime );
|
||||
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band],
|
||||
txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );
|
||||
}
|
||||
|
||||
void RegionKR920InitDefaults( InitDefaultsParams_t* params )
|
||||
@@ -375,10 +353,14 @@ void RegionKR920InitDefaults( InitDefaultsParams_t* params )
|
||||
|
||||
switch( params->Type )
|
||||
{
|
||||
case INIT_TYPE_INIT:
|
||||
case INIT_TYPE_BANDS:
|
||||
{
|
||||
// Initialize bands
|
||||
memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * KR920_MAX_NB_BANDS );
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_INIT:
|
||||
{
|
||||
|
||||
// Channels
|
||||
NvmCtx.Channels[0] = ( ChannelParams_t ) KR920_LC1;
|
||||
@@ -387,6 +369,7 @@ void RegionKR920InitDefaults( InitDefaultsParams_t* params )
|
||||
|
||||
// Initialize the channels default mask
|
||||
NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
|
||||
|
||||
// Update the channels mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 1 );
|
||||
break;
|
||||
@@ -403,6 +386,11 @@ void RegionKR920InitDefaults( InitDefaultsParams_t* params )
|
||||
{
|
||||
// Restore channels default mask
|
||||
NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0];
|
||||
|
||||
// Channels
|
||||
NvmCtx.Channels[0] = ( ChannelParams_t ) KR920_LC1;
|
||||
NvmCtx.Channels[1] = ( ChannelParams_t ) KR920_LC2;
|
||||
NvmCtx.Channels[2] = ( ChannelParams_t ) KR920_LC3;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -422,6 +410,10 @@ bool RegionKR920Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute )
|
||||
{
|
||||
switch( phyAttribute )
|
||||
{
|
||||
case PHY_FREQUENCY:
|
||||
{
|
||||
return VerifyRfFreq( verify->Frequency );
|
||||
}
|
||||
case PHY_TX_DR:
|
||||
{
|
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, KR920_TX_MIN_DATARATE, KR920_TX_MAX_DATARATE );
|
||||
@@ -544,7 +536,6 @@ void RegionKR920ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols
|
||||
bool RegionKR920RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
{
|
||||
int8_t dr = rxConfig->Datarate;
|
||||
uint8_t maxPayload = 0;
|
||||
int8_t phyDr = 0;
|
||||
uint32_t frequency = rxConfig->Frequency;
|
||||
|
||||
@@ -571,8 +562,7 @@ bool RegionKR920RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
|
||||
// Radio configuration
|
||||
Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
|
||||
maxPayload = MaxPayloadOfDatarateKR920[dr];
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, MaxPayloadOfDatarateKR920[dr] + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE );
|
||||
|
||||
*datarate = (uint8_t) dr;
|
||||
return true;
|
||||
@@ -596,12 +586,12 @@ bool RegionKR920TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime
|
||||
// Setup the radio frequency
|
||||
Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency );
|
||||
|
||||
Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 );
|
||||
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, txConfig->PktLen );
|
||||
// Get the time-on-air of the next tx frame
|
||||
*txTimeOnAir = Radio.TimeOnAir( MODEM_LORA, txConfig->PktLen );
|
||||
// Update time-on-air
|
||||
*txTimeOnAir = GetTimeOnAir( txConfig->Datarate, txConfig->PktLen );
|
||||
|
||||
*txPower = txPowerLimited;
|
||||
return true;
|
||||
@@ -825,55 +815,45 @@ int8_t RegionKR920AlternateDr( int8_t currentDr, AlternateDrType_t type )
|
||||
return currentDr;
|
||||
}
|
||||
|
||||
void RegionKR920CalcBackOff( CalcBackOffParams_t* calcBackOff )
|
||||
{
|
||||
RegionCommonCalcBackOffParams_t calcBackOffParams;
|
||||
|
||||
calcBackOffParams.Channels = NvmCtx.Channels;
|
||||
calcBackOffParams.Bands = NvmCtx.Bands;
|
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest;
|
||||
calcBackOffParams.Joined = calcBackOff->Joined;
|
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled;
|
||||
calcBackOffParams.Channel = calcBackOff->Channel;
|
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime;
|
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir;
|
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams );
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionKR920NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff )
|
||||
{
|
||||
uint8_t channelNext = 0;
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTx = 0;
|
||||
uint8_t nbRestrictedChannels = 0;
|
||||
uint8_t enabledChannels[KR920_MAX_NB_CHANNELS] = { 0 };
|
||||
TimerTime_t nextTxDelay = 0;
|
||||
RegionCommonIdentifyChannelsParam_t identifyChannelsParam;
|
||||
RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams;
|
||||
LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
|
||||
if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 )
|
||||
{ // Reactivate default channels
|
||||
NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 );
|
||||
}
|
||||
|
||||
if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) )
|
||||
{
|
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0;
|
||||
// Search how many channels are enabled
|
||||
countChannelsParams.Joined = nextChanParams->Joined;
|
||||
countChannelsParams.Datarate = nextChanParams->Datarate;
|
||||
countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask;
|
||||
countChannelsParams.Channels = NvmCtx.Channels;
|
||||
countChannelsParams.Bands = NvmCtx.Bands;
|
||||
countChannelsParams.MaxNbChannels = KR920_MAX_NB_CHANNELS;
|
||||
countChannelsParams.JoinChannels = KR920_JOIN_CHANNELS;
|
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, NvmCtx.Bands, KR920_MAX_NB_BANDS );
|
||||
identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff;
|
||||
identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx;
|
||||
identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;
|
||||
identifyChannelsParam.MaxBands = KR920_MAX_NB_BANDS;
|
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Joined, nextChanParams->Datarate,
|
||||
NvmCtx.ChannelsMask, NvmCtx.Channels,
|
||||
NvmCtx.Bands, enabledChannels, &delayTx );
|
||||
}
|
||||
else
|
||||
{
|
||||
delayTx++;
|
||||
nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx );
|
||||
}
|
||||
identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;
|
||||
identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;
|
||||
identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );
|
||||
|
||||
if( nbEnabledChannels > 0 )
|
||||
identifyChannelsParam.CountNbOfEnabledChannelsParam = &countChannelsParams;
|
||||
|
||||
status = RegionCommonIdentifyChannels( &identifyChannelsParam, aggregatedTimeOff, enabledChannels,
|
||||
&nbEnabledChannels, &nbRestrictedChannels, time );
|
||||
|
||||
if( status == LORAMAC_STATUS_OK )
|
||||
{
|
||||
for( uint8_t i = 0, j = randr( 0, nbEnabledChannels - 1 ); i < KR920_MAX_NB_CHANNELS; i++ )
|
||||
{
|
||||
@@ -886,25 +866,19 @@ LoRaMacStatus_t RegionKR920NextChannel( NextChanParams_t* nextChanParams, uint8_
|
||||
{
|
||||
// Free channel found
|
||||
*channel = channelNext;
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_OK;
|
||||
}
|
||||
}
|
||||
return LORAMAC_STATUS_NO_FREE_CHANNEL_FOUND;
|
||||
// Even if one or more channels are available according to the channel plan, no free channel
|
||||
// was found during the LBT procedure.
|
||||
status = LORAMAC_STATUS_NO_FREE_CHANNEL_FOUND;
|
||||
}
|
||||
else
|
||||
else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND )
|
||||
{
|
||||
if( delayTx > 0 )
|
||||
{
|
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay;
|
||||
return LORAMAC_STATUS_DUTYCYCLE_RESTRICTED;
|
||||
}
|
||||
// Datarate not supported by any channel, restore defaults
|
||||
NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 );
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionKR920ChannelAdd( ChannelAddParams_t* channelAdd )
|
||||
|
@@ -37,6 +37,11 @@
|
||||
#ifndef __REGION_KR920_H__
|
||||
#define __REGION_KR920_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
@@ -201,6 +206,11 @@
|
||||
*/
|
||||
#define KR920_BEACON_CHANNEL_FREQ 923100000
|
||||
|
||||
/*!
|
||||
* Ping slot channel frequency
|
||||
*/
|
||||
#define KR920_PING_SLOT_CHANNEL_FREQ 923100000
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
@@ -238,9 +248,9 @@
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
* Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission }
|
||||
*/
|
||||
#define KR920_BAND0 { 1 , KR920_MAX_TX_POWER, 0, 0, 0 } // 100.0 %
|
||||
#define KR920_BAND0 { 1 , KR920_MAX_TX_POWER, 0, 0, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1
|
||||
@@ -286,15 +296,10 @@ static const uint8_t DataratesKR920[] = { 12, 11, 10, 9, 8, 7 };
|
||||
static const uint32_t BandwidthsKR920[] = { 125000, 125000, 125000, 125000, 125000, 125000 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with and without a repeater.
|
||||
* Maximum payload with respect to the datarate index.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateKR920[] = { 51, 51, 51, 115, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterKR920[] = { 51, 51, 51, 115, 222, 222 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
@@ -450,13 +455,6 @@ uint8_t RegionKR920DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
*/
|
||||
int8_t RegionKR920AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionKR920CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
@@ -518,4 +516,8 @@ uint8_t RegionKR920ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d
|
||||
|
||||
/*! \} defgroup REGIONKR920 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __REGION_KR920_H__
|
||||
|
@@ -120,45 +120,21 @@ static bool VerifyRfFreq( uint32_t freq )
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx )
|
||||
static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTransmission = 0;
|
||||
int8_t phyDr = DataratesRU864[datarate];
|
||||
uint32_t bandwidth = GetBandwidth( datarate );
|
||||
TimerTime_t timeOnAir = 0;
|
||||
|
||||
for( uint8_t i = 0, k = 0; i < RU864_MAX_NB_CHANNELS; i += 16, k++ )
|
||||
{
|
||||
for( uint8_t j = 0; j < 16; j++ )
|
||||
{
|
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 )
|
||||
{
|
||||
if( channels[i + j].Frequency == 0 )
|
||||
{ // Check if the channel is enabled
|
||||
continue;
|
||||
}
|
||||
if( joined == false )
|
||||
{
|
||||
if( ( RU864_JOIN_CHANNELS & ( 1 << j ) ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min,
|
||||
channels[i + j].DrRange.Fields.Max ) == false )
|
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue;
|
||||
}
|
||||
if( bands[channels[i + j].Band].TimeOff > 0 )
|
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++;
|
||||
continue;
|
||||
}
|
||||
enabledChannels[nbEnabledChannels++] = i + j;
|
||||
}
|
||||
}
|
||||
if( datarate == DR_7 )
|
||||
{ // High Speed FSK channel
|
||||
timeOnAir = Radio.TimeOnAir( MODEM_FSK, bandwidth, phyDr * 1000, 0, 5, false, pktLen, true );
|
||||
}
|
||||
|
||||
*delayTx = delayTransmission;
|
||||
return nbEnabledChannels;
|
||||
else
|
||||
{
|
||||
timeOnAir = Radio.TimeOnAir( MODEM_LORA, bandwidth, phyDr, 1, 8, false, pktLen, true );
|
||||
}
|
||||
return timeOnAir;
|
||||
}
|
||||
|
||||
PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy )
|
||||
@@ -187,6 +163,11 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, RU864_TX_MIN_DATARATE );
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_TX_POWER:
|
||||
{
|
||||
phyParam.Value = RU864_MAX_TX_POWER;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_TX_POWER:
|
||||
{
|
||||
phyParam.Value = RU864_DEFAULT_TX_POWER;
|
||||
@@ -207,11 +188,6 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = MaxPayloadOfDatarateRU864[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_PAYLOAD_REPEATER:
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterRU864[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_DUTY_CYCLE:
|
||||
{
|
||||
phyParam.Value = RU864_DUTY_CYCLE_ENABLED;
|
||||
@@ -320,6 +296,26 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = RU864_BEACON_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_FREQ:
|
||||
{
|
||||
phyParam.Value = RU864_PING_SLOT_CHANNEL_FREQ;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_DR:
|
||||
{
|
||||
phyParam.Value = RU864_PING_SLOT_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_SF_FROM_DR:
|
||||
{
|
||||
phyParam.Value = DataratesRU864[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_BW_FROM_DR:
|
||||
{
|
||||
phyParam.Value = GetBandwidth( getPhy->Datarate );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
@@ -331,7 +327,8 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy )
|
||||
|
||||
void RegionRU864SetBandTxDone( SetBandTxDoneParams_t* txDone )
|
||||
{
|
||||
RegionCommonSetBandTxDone( txDone->Joined, &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxDoneTime );
|
||||
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band],
|
||||
txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );
|
||||
}
|
||||
|
||||
void RegionRU864InitDefaults( InitDefaultsParams_t* params )
|
||||
@@ -343,10 +340,14 @@ void RegionRU864InitDefaults( InitDefaultsParams_t* params )
|
||||
|
||||
switch( params->Type )
|
||||
{
|
||||
case INIT_TYPE_INIT:
|
||||
case INIT_TYPE_BANDS:
|
||||
{
|
||||
// Initialize bands
|
||||
memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * RU864_MAX_NB_BANDS );
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_INIT:
|
||||
{
|
||||
|
||||
// Channels
|
||||
NvmCtx.Channels[0] = ( ChannelParams_t ) RU864_LC1;
|
||||
@@ -370,6 +371,10 @@ void RegionRU864InitDefaults( InitDefaultsParams_t* params )
|
||||
{
|
||||
// Restore channels default mask
|
||||
NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0];
|
||||
|
||||
// Channels
|
||||
NvmCtx.Channels[0] = ( ChannelParams_t ) RU864_LC1;
|
||||
NvmCtx.Channels[1] = ( ChannelParams_t ) RU864_LC2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -389,6 +394,10 @@ bool RegionRU864Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute )
|
||||
{
|
||||
switch( phyAttribute )
|
||||
{
|
||||
case PHY_FREQUENCY:
|
||||
{
|
||||
return VerifyRfFreq( verify->Frequency );
|
||||
}
|
||||
case PHY_TX_DR:
|
||||
{
|
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, RU864_TX_MIN_DATARATE, RU864_TX_MAX_DATARATE );
|
||||
@@ -519,7 +528,6 @@ bool RegionRU864RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
{
|
||||
RadioModems_t modem;
|
||||
int8_t dr = rxConfig->Datarate;
|
||||
uint8_t maxPayload = 0;
|
||||
int8_t phyDr = 0;
|
||||
uint32_t frequency = rxConfig->Frequency;
|
||||
|
||||
@@ -556,16 +564,7 @@ bool RegionRU864RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
Radio.SetRxConfig( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
|
||||
}
|
||||
|
||||
if( rxConfig->RepeaterSupport == true )
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateRepeaterRU864[dr];
|
||||
}
|
||||
else
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateRU864[dr];
|
||||
}
|
||||
|
||||
Radio.SetMaxPayloadLength( modem, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
|
||||
Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarateRU864[dr] + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE );
|
||||
|
||||
*datarate = (uint8_t) dr;
|
||||
return true;
|
||||
@@ -588,18 +587,19 @@ bool RegionRU864TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime
|
||||
if( txConfig->Datarate == DR_7 )
|
||||
{ // High Speed FSK channel
|
||||
modem = MODEM_FSK;
|
||||
Radio.SetTxConfig( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 4000 );
|
||||
}
|
||||
else
|
||||
{
|
||||
modem = MODEM_LORA;
|
||||
Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 );
|
||||
}
|
||||
|
||||
// Update time-on-air
|
||||
*txTimeOnAir = GetTimeOnAir( txConfig->Datarate, txConfig->PktLen );
|
||||
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( modem, txConfig->PktLen );
|
||||
// Get the time-on-air of the next tx frame
|
||||
*txTimeOnAir = Radio.TimeOnAir( modem, txConfig->PktLen );
|
||||
|
||||
*txPower = txPowerLimited;
|
||||
return true;
|
||||
@@ -823,74 +823,54 @@ int8_t RegionRU864AlternateDr( int8_t currentDr, AlternateDrType_t type )
|
||||
return currentDr;
|
||||
}
|
||||
|
||||
void RegionRU864CalcBackOff( CalcBackOffParams_t* calcBackOff )
|
||||
{
|
||||
RegionCommonCalcBackOffParams_t calcBackOffParams;
|
||||
|
||||
calcBackOffParams.Channels = NvmCtx.Channels;
|
||||
calcBackOffParams.Bands = NvmCtx.Bands;
|
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest;
|
||||
calcBackOffParams.Joined = calcBackOff->Joined;
|
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled;
|
||||
calcBackOffParams.Channel = calcBackOff->Channel;
|
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime;
|
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir;
|
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams );
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionRU864NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTx = 0;
|
||||
uint8_t nbRestrictedChannels = 0;
|
||||
uint8_t enabledChannels[RU864_MAX_NB_CHANNELS] = { 0 };
|
||||
TimerTime_t nextTxDelay = 0;
|
||||
RegionCommonIdentifyChannelsParam_t identifyChannelsParam;
|
||||
RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams;
|
||||
LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
|
||||
if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 )
|
||||
{ // Reactivate default channels
|
||||
NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 );
|
||||
}
|
||||
|
||||
if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) )
|
||||
{
|
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0;
|
||||
// Search how many channels are enabled
|
||||
countChannelsParams.Joined = nextChanParams->Joined;
|
||||
countChannelsParams.Datarate = nextChanParams->Datarate;
|
||||
countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask;
|
||||
countChannelsParams.Channels = NvmCtx.Channels;
|
||||
countChannelsParams.Bands = NvmCtx.Bands;
|
||||
countChannelsParams.MaxNbChannels = RU864_MAX_NB_CHANNELS;
|
||||
countChannelsParams.JoinChannels = RU864_JOIN_CHANNELS;
|
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, NvmCtx.Bands, RU864_MAX_NB_BANDS );
|
||||
identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff;
|
||||
identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx;
|
||||
identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;
|
||||
identifyChannelsParam.MaxBands = RU864_MAX_NB_BANDS;
|
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Joined, nextChanParams->Datarate,
|
||||
NvmCtx.ChannelsMask, NvmCtx.Channels,
|
||||
NvmCtx.Bands, enabledChannels, &delayTx );
|
||||
}
|
||||
else
|
||||
{
|
||||
delayTx++;
|
||||
nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx );
|
||||
}
|
||||
identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;
|
||||
identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;
|
||||
identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );
|
||||
|
||||
if( nbEnabledChannels > 0 )
|
||||
identifyChannelsParam.CountNbOfEnabledChannelsParam = &countChannelsParams;
|
||||
|
||||
status = RegionCommonIdentifyChannels( &identifyChannelsParam, aggregatedTimeOff, enabledChannels,
|
||||
&nbEnabledChannels, &nbRestrictedChannels, time );
|
||||
|
||||
if( status == LORAMAC_STATUS_OK )
|
||||
{
|
||||
// We found a valid channel
|
||||
*channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
|
||||
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_OK;
|
||||
}
|
||||
else
|
||||
else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND )
|
||||
{
|
||||
if( delayTx > 0 )
|
||||
{
|
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay;
|
||||
return LORAMAC_STATUS_DUTYCYCLE_RESTRICTED;
|
||||
}
|
||||
// Datarate not supported by any channel, restore defaults
|
||||
NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 );
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionRU864ChannelAdd( ChannelAddParams_t* channelAdd )
|
||||
|
@@ -35,6 +35,11 @@
|
||||
#ifndef __REGION_RU864_H__
|
||||
#define __REGION_RU864_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "LoRaMac.h"
|
||||
|
||||
/*!
|
||||
@@ -194,6 +199,11 @@
|
||||
*/
|
||||
#define RU864_BEACON_CHANNEL_FREQ 869100000
|
||||
|
||||
/*!
|
||||
* Ping slot channel frequency
|
||||
*/
|
||||
#define RU864_PING_SLOT_CHANNEL_FREQ 868900000
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
@@ -219,6 +229,11 @@
|
||||
*/
|
||||
#define RU864_BEACON_CHANNEL_BW 0
|
||||
|
||||
/*!
|
||||
* Datarate of the ping slot channel
|
||||
*/
|
||||
#define RU864_PING_SLOT_CHANNEL_DR DR_3
|
||||
|
||||
/*!
|
||||
* Maximum number of bands
|
||||
*/
|
||||
@@ -226,9 +241,9 @@
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
* Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission }
|
||||
*/
|
||||
#define RU864_BAND0 { 100 , RU864_MAX_TX_POWER, 0, 0, 0 } // 1.0 %
|
||||
#define RU864_BAND0 { 100 , RU864_MAX_TX_POWER, 0, 0, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1
|
||||
@@ -259,15 +274,10 @@ static const uint8_t DataratesRU864[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
|
||||
static const uint32_t BandwidthsRU864[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
* Maximum payload with respect to the datarate index.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRU864[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterRU864[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
@@ -423,13 +433,6 @@ uint8_t RegionRU864DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
*/
|
||||
int8_t RegionRU864AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionRU864CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
@@ -491,4 +494,8 @@ void RegionRU864RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*! \} defgroup REGIONRU864 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __REGION_RU864_H__
|
||||
|
@@ -254,38 +254,12 @@ static bool VerifyRfFreq( uint32_t freq )
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx )
|
||||
static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTransmission = 0;
|
||||
int8_t phyDr = DataratesUS915[datarate];
|
||||
uint32_t bandwidth = GetBandwidth( datarate );
|
||||
|
||||
for( uint8_t i = 0, k = 0; i < US915_MAX_NB_CHANNELS; i += 16, k++ )
|
||||
{
|
||||
for( uint8_t j = 0; j < 16; j++ )
|
||||
{
|
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 )
|
||||
{
|
||||
if( channels[i + j].Frequency == 0 )
|
||||
{ // Check if the channel is enabled
|
||||
continue;
|
||||
}
|
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min,
|
||||
channels[i + j].DrRange.Fields.Max ) == false )
|
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue;
|
||||
}
|
||||
if( bands[channels[i + j].Band].TimeOff > 0 )
|
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++;
|
||||
continue;
|
||||
}
|
||||
enabledChannels[nbEnabledChannels++] = i + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*delayTx = delayTransmission;
|
||||
return nbEnabledChannels;
|
||||
return Radio.TimeOnAir( MODEM_LORA, bandwidth, phyDr, 1, 8, false, pktLen, true );
|
||||
}
|
||||
|
||||
PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy )
|
||||
@@ -339,11 +313,6 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = MaxPayloadOfDatarateUS915[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_PAYLOAD_REPEATER:
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterUS915[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_DUTY_CYCLE:
|
||||
{
|
||||
phyParam.Value = US915_DUTY_CYCLE_ENABLED;
|
||||
@@ -427,7 +396,7 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy )
|
||||
}
|
||||
case PHY_DEF_MAX_EIRP:
|
||||
{
|
||||
phyParam.fValue = US915_DEFAULT_MAX_ERP + 2.15;
|
||||
phyParam.fValue = US915_DEFAULT_MAX_ERP + 2.15f;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_ANTENNA_GAIN:
|
||||
@@ -437,7 +406,7 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy )
|
||||
}
|
||||
case PHY_BEACON_CHANNEL_FREQ:
|
||||
{
|
||||
phyParam.Value = US915_BEACON_CHANNEL_FREQ;
|
||||
phyParam.Value = US915_BEACON_CHANNEL_FREQ + ( getPhy->Channel * US915_BEACON_CHANNEL_STEPWIDTH );
|
||||
break;
|
||||
}
|
||||
case PHY_BEACON_FORMAT:
|
||||
@@ -462,11 +431,26 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy )
|
||||
phyParam.Value = US915_BEACON_NB_CHANNELS;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_FREQ:
|
||||
{
|
||||
phyParam.Value = US915_PING_SLOT_CHANNEL_FREQ + ( getPhy->Channel * US915_BEACON_CHANNEL_STEPWIDTH );
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_DR:
|
||||
{
|
||||
phyParam.Value = US915_PING_SLOT_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_SF_FROM_DR:
|
||||
{
|
||||
phyParam.Value = DataratesUS915[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_BW_FROM_DR:
|
||||
{
|
||||
phyParam.Value = GetBandwidth( getPhy->Datarate );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
@@ -478,7 +462,8 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy )
|
||||
|
||||
void RegionUS915SetBandTxDone( SetBandTxDoneParams_t* txDone )
|
||||
{
|
||||
RegionCommonSetBandTxDone( txDone->Joined, &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxDoneTime );
|
||||
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band],
|
||||
txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );
|
||||
}
|
||||
|
||||
void RegionUS915InitDefaults( InitDefaultsParams_t* params )
|
||||
@@ -490,7 +475,7 @@ void RegionUS915InitDefaults( InitDefaultsParams_t* params )
|
||||
|
||||
switch( params->Type )
|
||||
{
|
||||
case INIT_TYPE_INIT:
|
||||
case INIT_TYPE_BANDS:
|
||||
{
|
||||
// Initialize bands
|
||||
memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * US915_MAX_NB_BANDS );
|
||||
@@ -501,6 +486,23 @@ void RegionUS915InitDefaults( InitDefaultsParams_t* params )
|
||||
// Initialize the join trials counter
|
||||
NvmCtx.JoinTrialsCounter = 0;
|
||||
|
||||
// ChannelsMask
|
||||
NvmCtx.ChannelsDefaultMask[0] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[1] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[2] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[3] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[4] = 0x00FF;
|
||||
NvmCtx.ChannelsDefaultMask[5] = 0x0000;
|
||||
|
||||
// Copy channels default mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 );
|
||||
|
||||
// Copy into channels mask remaining
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMaskRemaining, NvmCtx.ChannelsMask, 6 );
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_INIT:
|
||||
{
|
||||
// Channels
|
||||
// 125 kHz channels
|
||||
for( uint8_t i = 0; i < US915_MAX_NB_CHANNELS - 8; i++ )
|
||||
@@ -516,20 +518,6 @@ void RegionUS915InitDefaults( InitDefaultsParams_t* params )
|
||||
NvmCtx.Channels[i].DrRange.Value = ( DR_4 << 4 ) | DR_4;
|
||||
NvmCtx.Channels[i].Band = 0;
|
||||
}
|
||||
|
||||
// ChannelsMask
|
||||
NvmCtx.ChannelsDefaultMask[0] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[1] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[2] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[3] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[4] = 0x00FF;
|
||||
NvmCtx.ChannelsDefaultMask[5] = 0x0000;
|
||||
|
||||
// Copy channels default mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 );
|
||||
|
||||
// Copy into channels mask remaining
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMaskRemaining, NvmCtx.ChannelsMask, 6 );
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_RESTORE_CTX:
|
||||
@@ -568,6 +556,10 @@ bool RegionUS915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute )
|
||||
{
|
||||
switch( phyAttribute )
|
||||
{
|
||||
case PHY_FREQUENCY:
|
||||
{
|
||||
return VerifyRfFreq( verify->Frequency );
|
||||
}
|
||||
case PHY_TX_DR:
|
||||
{
|
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, US915_TX_MIN_DATARATE, US915_TX_MAX_DATARATE );
|
||||
@@ -676,7 +668,6 @@ void RegionUS915ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols
|
||||
bool RegionUS915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
{
|
||||
int8_t dr = rxConfig->Datarate;
|
||||
uint8_t maxPayload = 0;
|
||||
int8_t phyDr = 0;
|
||||
uint32_t frequency = rxConfig->Frequency;
|
||||
|
||||
@@ -699,15 +690,7 @@ bool RegionUS915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
// Radio configuration
|
||||
Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
|
||||
|
||||
if( rxConfig->RepeaterSupport == true )
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateRepeaterUS915[dr];
|
||||
}
|
||||
else
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateUS915[dr];
|
||||
}
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, MaxPayloadOfDatarateUS915[dr] + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE );
|
||||
|
||||
*datarate = (uint8_t) dr;
|
||||
return true;
|
||||
@@ -726,14 +709,15 @@ bool RegionUS915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime
|
||||
// Setup the radio frequency
|
||||
Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency );
|
||||
|
||||
Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 );
|
||||
Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 );
|
||||
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, txConfig->PktLen );
|
||||
// Get the time-on-air of the next tx frame
|
||||
*txTimeOnAir = Radio.TimeOnAir( MODEM_LORA, txConfig->PktLen );
|
||||
*txPower = txPowerLimited;
|
||||
|
||||
// Update time-on-air
|
||||
*txTimeOnAir = GetTimeOnAir( txConfig->Datarate, txConfig->PktLen );
|
||||
|
||||
*txPower = txPowerLimited;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -969,29 +953,15 @@ int8_t RegionUS915AlternateDr( int8_t currentDr, AlternateDrType_t type )
|
||||
return currentDr;
|
||||
}
|
||||
|
||||
void RegionUS915CalcBackOff( CalcBackOffParams_t* calcBackOff )
|
||||
{
|
||||
RegionCommonCalcBackOffParams_t calcBackOffParams;
|
||||
|
||||
calcBackOffParams.Channels = NvmCtx.Channels;
|
||||
calcBackOffParams.Bands = NvmCtx.Bands;
|
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest;
|
||||
calcBackOffParams.Joined = calcBackOff->Joined;
|
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled;
|
||||
calcBackOffParams.Channel = calcBackOff->Channel;
|
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime;
|
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir;
|
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams );
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionUS915NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTx = 0;
|
||||
uint8_t nbRestrictedChannels = 0;
|
||||
uint8_t enabledChannels[US915_MAX_NB_CHANNELS] = { 0 };
|
||||
TimerTime_t nextTxDelay = 0;
|
||||
uint8_t newChannelIndex;
|
||||
uint8_t newChannelIndex = 0;
|
||||
RegionCommonIdentifyChannelsParam_t identifyChannelsParam;
|
||||
RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams;
|
||||
LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
|
||||
// Count 125kHz channels
|
||||
if( RegionCommonCountChannels( NvmCtx.ChannelsMaskRemaining, 0, 4 ) == 0 )
|
||||
@@ -1009,26 +979,30 @@ LoRaMacStatus_t RegionUS915NextChannel( NextChanParams_t* nextChanParams, uint8_
|
||||
}
|
||||
}
|
||||
|
||||
if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) )
|
||||
{
|
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0;
|
||||
// Search how many channels are enabled
|
||||
countChannelsParams.Joined = nextChanParams->Joined;
|
||||
countChannelsParams.Datarate = nextChanParams->Datarate;
|
||||
countChannelsParams.ChannelsMask = NvmCtx.ChannelsMaskRemaining;
|
||||
countChannelsParams.Channels = NvmCtx.Channels;
|
||||
countChannelsParams.Bands = NvmCtx.Bands;
|
||||
countChannelsParams.MaxNbChannels = US915_MAX_NB_CHANNELS;
|
||||
countChannelsParams.JoinChannels = 0;
|
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, NvmCtx.Bands, US915_MAX_NB_BANDS );
|
||||
identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff;
|
||||
identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx;
|
||||
identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;
|
||||
identifyChannelsParam.MaxBands = US915_MAX_NB_BANDS;
|
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Datarate,
|
||||
NvmCtx.ChannelsMaskRemaining, NvmCtx.Channels,
|
||||
NvmCtx.Bands, enabledChannels, &delayTx );
|
||||
}
|
||||
else
|
||||
{
|
||||
delayTx++;
|
||||
nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx );
|
||||
}
|
||||
identifyChannelsParam.CountNbOfEnabledChannelsParam = &countChannelsParams;
|
||||
|
||||
if( nbEnabledChannels > 0 )
|
||||
identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;
|
||||
identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;
|
||||
identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );
|
||||
|
||||
status = RegionCommonIdentifyChannels( &identifyChannelsParam, aggregatedTimeOff, enabledChannels,
|
||||
&nbEnabledChannels, &nbRestrictedChannels, time );
|
||||
|
||||
if( status == LORAMAC_STATUS_OK )
|
||||
{
|
||||
if( nextChanParams->Joined == true )
|
||||
{
|
||||
@@ -1066,22 +1040,8 @@ LoRaMacStatus_t RegionUS915NextChannel( NextChanParams_t* nextChanParams, uint8_
|
||||
|
||||
// Disable the channel in the mask
|
||||
RegionCommonChanDisable( NvmCtx.ChannelsMaskRemaining, *channel, US915_MAX_NB_CHANNELS );
|
||||
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( delayTx > 0 )
|
||||
{
|
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay;
|
||||
return LORAMAC_STATUS_DUTYCYCLE_RESTRICTED;
|
||||
}
|
||||
// Datarate not supported by any channel
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionUS915ChannelAdd( ChannelAddParams_t* channelAdd )
|
||||
|
@@ -37,6 +37,11 @@
|
||||
#ifndef __REGION_US915_H__
|
||||
#define __REGION_US915_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
@@ -87,7 +92,7 @@
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node
|
||||
*/
|
||||
#define US915_MIN_TX_POWER TX_POWER_10
|
||||
#define US915_MIN_TX_POWER TX_POWER_14
|
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node
|
||||
@@ -182,6 +187,11 @@
|
||||
*/
|
||||
#define US915_BEACON_CHANNEL_STEPWIDTH 600000
|
||||
|
||||
/*!
|
||||
* Ping slot channel frequency
|
||||
*/
|
||||
#define US915_PING_SLOT_CHANNEL_FREQ 923300000
|
||||
|
||||
/*!
|
||||
* Number of possible beacon channels
|
||||
*/
|
||||
@@ -224,9 +234,9 @@
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
* Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission }
|
||||
*/
|
||||
#define US915_BAND0 { 1, US915_MAX_TX_POWER, 0, 0, 0 } // 100.0 %
|
||||
#define US915_BAND0 { 1, US915_MAX_TX_POWER, 0, 0, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* Defines the first channel for RX window 1 for US band
|
||||
@@ -266,15 +276,10 @@ static const int8_t DatarateOffsetsUS915[5][4] =
|
||||
};
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
* Maximum payload with respect to the datarate index.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateUS915[] = { 11, 53, 125, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterUS915[] = { 11, 53, 125, 242, 242, 0, 0, 0, 33, 109, 222, 222, 222, 222, 0, 0 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
@@ -432,13 +437,6 @@ uint8_t RegionUS915DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
*/
|
||||
int8_t RegionUS915AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionUS915CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
@@ -496,8 +494,12 @@ uint8_t RegionUS915ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d
|
||||
*
|
||||
* \param [IN] rxBeaconSetup Pointer to the function parameters
|
||||
*/
|
||||
void RegionUS915RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
void RegionUS915RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*! \} defgroup REGIONUS915 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __REGION_US915_H__
|
||||
|
@@ -30,13 +30,37 @@
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* \defgroup SECUREELEMENT Secure Element API Definition
|
||||
*
|
||||
* \{
|
||||
*
|
||||
*/
|
||||
#ifndef __SECURE_ELEMENT_H__
|
||||
#define __SECURE_ELEMENT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "LoRaMacCrypto.h"
|
||||
|
||||
/*!
|
||||
* Secure-element keys size in bytes
|
||||
*/
|
||||
#define SE_KEY_SIZE 16
|
||||
|
||||
/*!
|
||||
* Secure-element EUI size in bytes
|
||||
*/
|
||||
#define SE_EUI_SIZE 8
|
||||
|
||||
/*!
|
||||
* Secure-element pin size in bytes
|
||||
*/
|
||||
#define SE_PIN_SIZE 4
|
||||
|
||||
/*!
|
||||
* Return values.
|
||||
*/
|
||||
@@ -70,6 +94,10 @@ typedef enum eSecureElementStatus
|
||||
* Undefined Error occurred
|
||||
*/
|
||||
SECURE_ELEMENT_ERROR,
|
||||
/*!
|
||||
* Failed to encrypt
|
||||
*/
|
||||
SECURE_ELEMENT_FAIL_ENCRYPT,
|
||||
}SecureElementStatus_t;
|
||||
|
||||
/*!
|
||||
@@ -77,7 +105,7 @@ typedef enum eSecureElementStatus
|
||||
* non volatile context have to be stored.
|
||||
*
|
||||
*/
|
||||
typedef void ( *EventNvmCtxChanged )( void );
|
||||
typedef void ( *SecureElementNvmEvent )( void );
|
||||
|
||||
/*!
|
||||
* Initialization of Secure Element driver
|
||||
@@ -86,7 +114,7 @@ typedef void ( *EventNvmCtxChanged )( void );
|
||||
* non-volatile context have to be stored.
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementInit( EventNvmCtxChanged seNvmCtxChanged );
|
||||
SecureElementStatus_t SecureElementInit( SecureElementNvmEvent seNvmCtxChanged );
|
||||
|
||||
/*!
|
||||
* Restores the internal nvm context from passed pointer.
|
||||
@@ -114,15 +142,16 @@ void* SecureElementGetNvmCtx( size_t* seNvmCtxSize );
|
||||
SecureElementStatus_t SecureElementSetKey( KeyIdentifier_t keyID, uint8_t* key );
|
||||
|
||||
/*!
|
||||
* Computes a CMAC
|
||||
* Computes a CMAC of a message using provided initial Bx block
|
||||
*
|
||||
* \param[IN] micBxBuffer - Buffer containing the initial Bx block
|
||||
* \param[IN] buffer - Data buffer
|
||||
* \param[IN] size - Data buffer size
|
||||
* \param[IN] keyID - Key identifier to determine the AES key to be used
|
||||
* \param[OUT] cmac - Computed cmac
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementComputeAesCmac( uint8_t* buffer, uint16_t size, KeyIdentifier_t keyID, uint32_t* cmac );
|
||||
SecureElementStatus_t SecureElementComputeAesCmac( uint8_t* micBxBuffer, uint8_t* buffer, uint16_t size, KeyIdentifier_t keyID, uint32_t* cmac );
|
||||
|
||||
/*!
|
||||
* Verifies a CMAC (computes and compare with expected cmac)
|
||||
@@ -157,6 +186,22 @@ SecureElementStatus_t SecureElementAesEncrypt( uint8_t* buffer, uint16_t size, K
|
||||
*/
|
||||
SecureElementStatus_t SecureElementDeriveAndStoreKey( Version_t version, uint8_t* input, KeyIdentifier_t rootKeyID, KeyIdentifier_t targetKeyID );
|
||||
|
||||
/*!
|
||||
* Process JoinAccept message.
|
||||
*
|
||||
* \param[IN] encJoinAccept - Received encrypted JoinAccept message
|
||||
* \param[IN] encJoinAcceptSize - Received encrypted JoinAccept message Size
|
||||
* \param[OUT] decJoinAccept - Decrypted and validated JoinAccept message
|
||||
* \param[OUT] versionMinor - Detected LoRaWAN specification version minor field.
|
||||
* - 0 -> LoRaWAN 1.0.x
|
||||
* - 1 -> LoRaWAN 1.1.x
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementProcessJoinAccept( JoinReqIdentifier_t joinReqType, uint8_t* joinEui,
|
||||
uint16_t devNonce, uint8_t* encJoinAccept,
|
||||
uint8_t encJoinAcceptSize, uint8_t* decJoinAccept,
|
||||
uint8_t* versionMinor );
|
||||
|
||||
/*!
|
||||
* Generates a random number
|
||||
*
|
||||
@@ -165,4 +210,55 @@ SecureElementStatus_t SecureElementDeriveAndStoreKey( Version_t version, uint8_t
|
||||
*/
|
||||
SecureElementStatus_t SecureElementRandomNumber( uint32_t* randomNum );
|
||||
|
||||
/*!
|
||||
* Sets the DevEUI
|
||||
*
|
||||
* \param[IN] devEui - Pointer to the 8-byte devEUI
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementSetDevEui( uint8_t* devEui );
|
||||
|
||||
/*!
|
||||
* Gets the DevEUI
|
||||
*
|
||||
* \retval - Pointer to the 8-byte devEUI
|
||||
*/
|
||||
uint8_t* SecureElementGetDevEui( void );
|
||||
|
||||
/*!
|
||||
* Sets the JoinEUI
|
||||
*
|
||||
* \param[IN] joinEui - Pointer to the 8-byte joinEui
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementSetJoinEui( uint8_t* joinEui );
|
||||
|
||||
/*!
|
||||
* Gets the DevEUI
|
||||
*
|
||||
* \retval - Pointer to the 8-byte joinEui
|
||||
*/
|
||||
uint8_t* SecureElementGetJoinEui( void );
|
||||
|
||||
/*!
|
||||
* Sets the pin
|
||||
*
|
||||
* \param[IN] pin - Pointer to the 4-byte pin
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementSetPin( uint8_t* pin );
|
||||
|
||||
/*!
|
||||
* Gets the Pin
|
||||
*
|
||||
* \retval - Pointer to the 4-byte pin
|
||||
*/
|
||||
uint8_t* SecureElementGetPin( void );
|
||||
|
||||
/*! \} defgroup SECUREELEMENT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __SECURE_ELEMENT_H__
|
||||
|
Reference in New Issue
Block a user