669 lines
17 KiB
C
669 lines
17 KiB
C
/*!
|
|
* \file LoRaMacClassB.h
|
|
*
|
|
* \brief LoRa MAC Class B layer implementation
|
|
*
|
|
* \copyright Revised BSD License, see section \ref LICENSE.
|
|
*
|
|
* \code
|
|
* ______ _
|
|
* / _____) _ | |
|
|
* ( (____ _____ ____ _| |_ _____ ____| |__
|
|
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
|
* _____) ) ____| | | || |_| ____( (___| | | |
|
|
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
|
* (C)2013 Semtech
|
|
*
|
|
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
|
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
|
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
|
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
|
* embedded.connectivity.solutions===============
|
|
*
|
|
* \endcode
|
|
*
|
|
* \author Miguel Luis ( Semtech )
|
|
*
|
|
* \author Gregory Cristian ( Semtech )
|
|
*
|
|
* \author Daniel Jaeckle ( STACKFORCE )
|
|
*
|
|
* \defgroup LORAMACCLASSB LoRa MAC Class B layer implementation
|
|
* This module specifies the API implementation of the LoRaMAC Class B layer.
|
|
* This is a placeholder for a detailed description of the LoRaMac
|
|
* layer and the supported features.
|
|
* \{
|
|
*/
|
|
#ifndef __LORAMACCLASSB_H__
|
|
#define __LORAMACCLASSB_H__
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
#include "systime.h"
|
|
#include "LoRaMacTypes.h"
|
|
|
|
/*!
|
|
* States of the class B beacon acquisition and tracking
|
|
*/
|
|
typedef enum eBeaconState
|
|
{
|
|
/*!
|
|
* Initial state to acquire the beacon
|
|
*/
|
|
BEACON_STATE_ACQUISITION,
|
|
/*!
|
|
* Beacon acquisition state when a time reference is available
|
|
*/
|
|
BEACON_STATE_ACQUISITION_BY_TIME,
|
|
/*!
|
|
* Handles the state when the beacon reception fails
|
|
*/
|
|
BEACON_STATE_TIMEOUT,
|
|
/*!
|
|
* Handles the state when the beacon was missed due to an uplink
|
|
*/
|
|
BEACON_STATE_BEACON_MISSED,
|
|
/*!
|
|
* Reacquisition state which applies the algorithm to enlarge the reception
|
|
* windows
|
|
*/
|
|
BEACON_STATE_REACQUISITION,
|
|
/*!
|
|
* The node has locked a beacon successfully
|
|
*/
|
|
BEACON_STATE_LOCKED,
|
|
/*!
|
|
* The beacon state machine is stopped due to operations with higher priority
|
|
*/
|
|
BEACON_STATE_HALT,
|
|
/*!
|
|
* The node currently operates in the beacon window and is idle. In this
|
|
* state, the temperature measurement takes place
|
|
*/
|
|
BEACON_STATE_IDLE,
|
|
/*!
|
|
* The node operates in the guard time of class B
|
|
*/
|
|
BEACON_STATE_GUARD,
|
|
/*!
|
|
* The node is in receive mode to lock a beacon
|
|
*/
|
|
BEACON_STATE_RX,
|
|
/*!
|
|
* The nodes switches the device class
|
|
*/
|
|
BEACON_STATE_LOST,
|
|
}BeaconState_t;
|
|
|
|
/*!
|
|
* States of the class B ping slot mechanism
|
|
*/
|
|
typedef enum ePingSlotState
|
|
{
|
|
/*!
|
|
* Calculation of the ping slot offset
|
|
*/
|
|
PINGSLOT_STATE_CALC_PING_OFFSET,
|
|
/*!
|
|
* State to set the timer to open the next ping slot
|
|
*/
|
|
PINGSLOT_STATE_SET_TIMER,
|
|
/*!
|
|
* The node is in idle state
|
|
*/
|
|
PINGSLOT_STATE_IDLE,
|
|
/*!
|
|
* The node opens up a ping slot window
|
|
*/
|
|
PINGSLOT_STATE_RX,
|
|
}PingSlotState_t;
|
|
|
|
/*!
|
|
* Class B ping slot context structure
|
|
*/
|
|
typedef struct sPingSlotContext
|
|
{
|
|
|
|
/*!
|
|
* Ping slot length time in ms
|
|
*/
|
|
uint32_t PingSlotWindow;
|
|
/*!
|
|
* Ping offset
|
|
*/
|
|
uint16_t PingOffset;
|
|
/*!
|
|
* Current symbol timeout. The node enlarges this variable in case of beacon
|
|
* loss.
|
|
*/
|
|
uint16_t SymbolTimeout;
|
|
/*!
|
|
* The multicast channel which will be enabled next.
|
|
*/
|
|
MulticastCtx_t *NextMulticastChannel;
|
|
}PingSlotContext_t;
|
|
|
|
|
|
/*!
|
|
* Class B beacon context structure
|
|
*/
|
|
typedef struct sBeaconContext
|
|
{
|
|
struct sBeaconCtrl
|
|
{
|
|
/*!
|
|
* Set if the node receives beacons
|
|
*/
|
|
uint8_t BeaconMode : 1;
|
|
/*!
|
|
* Set if the node has acquired the beacon
|
|
*/
|
|
uint8_t BeaconAcquired : 1;
|
|
/*!
|
|
* Set if a beacon delay was set for the beacon acquisition
|
|
*/
|
|
uint8_t BeaconDelaySet : 1;
|
|
/*!
|
|
* Set if a beacon channel was set for the beacon acquisition
|
|
*/
|
|
uint8_t BeaconChannelSet : 1;
|
|
/*!
|
|
* Set if beacon acquisition is pending
|
|
*/
|
|
uint8_t AcquisitionPending : 1;
|
|
/*!
|
|
* Set if the beacon state machine will be resumed
|
|
*/
|
|
uint8_t ResumeBeaconing : 1;
|
|
}Ctrl;
|
|
|
|
/*!
|
|
* Current temperature
|
|
*/
|
|
float Temperature;
|
|
/*!
|
|
* Beacon time received with the beacon frame
|
|
*/
|
|
SysTime_t BeaconTime;
|
|
/*!
|
|
* Time when the last beacon was received
|
|
*/
|
|
SysTime_t LastBeaconRx;
|
|
/*!
|
|
* Time when the next beacon will be received
|
|
*/
|
|
SysTime_t NextBeaconRx;
|
|
/*!
|
|
* This is the time where the RX window will be opened.
|
|
* Its base is NextBeaconRx with temperature compensations
|
|
* and RX window movement.
|
|
*/
|
|
TimerTime_t NextBeaconRxAdjusted;
|
|
/*!
|
|
* Current symbol timeout. The node enlarges this variable in case of beacon
|
|
* loss.
|
|
*/
|
|
uint16_t SymbolTimeout;
|
|
/*!
|
|
* Specifies how much time the beacon window will be moved.
|
|
*/
|
|
TimerTime_t BeaconWindowMovement;
|
|
/*!
|
|
* Beacon timing channel for next beacon
|
|
*/
|
|
uint8_t BeaconTimingChannel;
|
|
/*!
|
|
* Delay for next beacon in ms
|
|
*/
|
|
TimerTime_t BeaconTimingDelay;
|
|
TimerTime_t TimeStamp;
|
|
}BeaconContext_t;
|
|
|
|
/*!
|
|
* Data structure which contains the callbacks
|
|
*/
|
|
typedef struct sLoRaMacClassBCallback
|
|
{
|
|
/*!
|
|
* \brief Measures the temperature level
|
|
*
|
|
* \retval Temperature level
|
|
*/
|
|
uint16_t ( *GetTemperatureLevel )( void );
|
|
/*!
|
|
*\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 );
|
|
}LoRaMacClassBCallback_t;
|
|
|
|
/*!
|
|
* Data structure which pointers to the properties LoRaMAC
|
|
*/
|
|
typedef struct sLoRaMacClassBParams
|
|
{
|
|
/*!
|
|
* Pointer to the MlmeIndication structure
|
|
*/
|
|
MlmeIndication_t *MlmeIndication;
|
|
/*!
|
|
* Pointer to the McpsIndication structure
|
|
*/
|
|
McpsIndication_t *McpsIndication;
|
|
/*!
|
|
* Pointer to the MlmeConfirm structure
|
|
*/
|
|
MlmeConfirm_t *MlmeConfirm;
|
|
/*!
|
|
* Pointer to the LoRaMacFlags structure
|
|
*/
|
|
LoRaMacFlags_t *LoRaMacFlags;
|
|
/*!
|
|
* Pointer to the LoRaMac device address
|
|
*/
|
|
uint32_t *LoRaMacDevAddr;
|
|
/*!
|
|
* Pointer to the LoRaMac region definition
|
|
*/
|
|
LoRaMacRegion_t *LoRaMacRegion;
|
|
/*!
|
|
* Pointer to the LoRaMacParams structure
|
|
*/
|
|
LoRaMacParams_t *LoRaMacParams;
|
|
/*!
|
|
* Pointer to the multicast channel list
|
|
*/
|
|
MulticastCtx_t *MulticastChannels;
|
|
}LoRaMacClassBParams_t;
|
|
|
|
/*!
|
|
* Signature of callback function to be called by this module when the
|
|
* non-volatile needs to be saved.
|
|
*/
|
|
typedef void ( *LoRaMacClassBNvmEvent )( void );
|
|
|
|
/*
|
|
* LoRaMac Class B Context structure for NVM parameters
|
|
* related to ping slots
|
|
*/
|
|
typedef struct sLoRaMacClassBPingSlotNvmCtx
|
|
{
|
|
struct sPingSlotCtrlNvm
|
|
{
|
|
/*!
|
|
* 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;
|
|
/*!
|
|
* Number of ping slots
|
|
*/
|
|
uint8_t PingNb;
|
|
/*!
|
|
* Period of the ping slots
|
|
*/
|
|
uint16_t PingPeriod;
|
|
/*!
|
|
* Reception frequency of the ping slot windows
|
|
*/
|
|
uint32_t Frequency;
|
|
/*!
|
|
* Datarate of the ping slot
|
|
*/
|
|
int8_t Datarate;
|
|
} LoRaMacClassBPingSlotNvmCtx_t;
|
|
|
|
/*
|
|
* LoRaMac Class B Context structure for NVM parameters
|
|
* related to beaconing
|
|
*/
|
|
typedef struct sLoRaMacClassBBeaconNvmCtx
|
|
{
|
|
struct sBeaconCtrlNvm
|
|
{
|
|
/*!
|
|
* Set if the node has a custom frequency for beaconing and ping slots
|
|
*/
|
|
uint8_t CustomFreq : 1;
|
|
}Ctrl;
|
|
/*!
|
|
* Beacon reception frequency
|
|
*/
|
|
uint32_t Frequency;
|
|
/*!
|
|
* State of the beaconing mechanism
|
|
*/
|
|
BeaconState_t BeaconState;
|
|
} LoRaMacClassBBeaconNvmCtx_t;
|
|
|
|
/*
|
|
* LoRaMac Class B Context structure
|
|
*/
|
|
typedef struct sLoRaMacClassBNvmCtx
|
|
{
|
|
/*!
|
|
* Class B ping slot context
|
|
*/
|
|
LoRaMacClassBPingSlotNvmCtx_t PingSlotCtx;
|
|
/*!
|
|
* Class B beacon context
|
|
*/
|
|
LoRaMacClassBBeaconNvmCtx_t BeaconCtx;
|
|
} LoRaMacClassBNvmCtx_t;
|
|
|
|
/*
|
|
* LoRaMac Class B Context structure
|
|
*/
|
|
typedef struct sLoRaMacClassBCtx
|
|
{
|
|
/*!
|
|
* Class B ping slot context
|
|
*/
|
|
PingSlotContext_t PingSlotCtx;
|
|
/*!
|
|
* Class B beacon context
|
|
*/
|
|
BeaconContext_t BeaconCtx;
|
|
/*!
|
|
* State of the beaconing mechanism
|
|
*/
|
|
BeaconState_t BeaconState;
|
|
/*!
|
|
* State of the ping slot mechanism
|
|
*/
|
|
PingSlotState_t PingSlotState;
|
|
/*!
|
|
* State of the multicast slot mechanism
|
|
*/
|
|
PingSlotState_t MulticastSlotState;
|
|
/*!
|
|
* Timer for CLASS B beacon acquisition and tracking.
|
|
*/
|
|
TimerEvent_t BeaconTimer;
|
|
/*!
|
|
* Timer for CLASS B ping slot timer.
|
|
*/
|
|
TimerEvent_t PingSlotTimer;
|
|
/*!
|
|
* Timer for CLASS B multicast ping slot timer.
|
|
*/
|
|
TimerEvent_t MulticastSlotTimer;
|
|
/*!
|
|
* Container for the callbacks related to class b.
|
|
*/
|
|
LoRaMacClassBCallback_t LoRaMacClassBCallbacks;
|
|
/*!
|
|
* Data structure which holds the parameters which needs to be set
|
|
* in class b operation.
|
|
*/
|
|
LoRaMacClassBParams_t LoRaMacClassBParams;
|
|
/*
|
|
* Callback function to notify the upper layer about context change
|
|
*/
|
|
LoRaMacClassBNvmEvent LoRaMacClassBNvmEvent;
|
|
/*!
|
|
* Non-volatile module context.
|
|
*/
|
|
LoRaMacClassBNvmCtx_t* NvmCtx;
|
|
} LoRaMacClassBCtx_t;
|
|
|
|
/*!
|
|
* \brief Initialize LoRaWAN Class B
|
|
*
|
|
* \param [IN] classBParams Information and feedback parameter
|
|
* \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, LoRaMacClassBNvmEvent classBNvmCtxChanged );
|
|
|
|
/*!
|
|
* Restores the internal non-volatile context from passed pointer.
|
|
*
|
|
* \param [IN] classBNvmCtx - Pointer to non-volatile class B module context to be restored.
|
|
*
|
|
* \retval - Status of the operation
|
|
*/
|
|
bool LoRaMacClassBRestoreNvmCtx( void* classBNvmCtx );
|
|
|
|
/*!
|
|
* Returns a pointer to the internal non-volatile context.
|
|
*
|
|
* \param [IN] classBNvmCtxSize - Size of the module non-volatile context
|
|
*
|
|
* \retval - Points to a structure where the module store its non-volatile context
|
|
*/
|
|
void* LoRaMacClassBGetNvmCtx( size_t* classBNvmCtxSize );
|
|
|
|
/*!
|
|
* \brief Set the state of the beacon state machine
|
|
*
|
|
* \param [IN] beaconState Beacon state.
|
|
*/
|
|
void LoRaMacClassBSetBeaconState( BeaconState_t beaconState );
|
|
|
|
/*!
|
|
* \brief Set the state of the ping slot state machine
|
|
*
|
|
* \param [IN] pingSlotState Ping slot state.
|
|
*/
|
|
void LoRaMacClassBSetPingSlotState( PingSlotState_t pingSlotState );
|
|
|
|
/*!
|
|
* \brief Set the state of the multicast slot state machine
|
|
*
|
|
* \param [IN] pingSlotState multicast slot state.
|
|
*/
|
|
void LoRaMacClassBSetMulticastSlotState( PingSlotState_t multicastSlotState );
|
|
|
|
/*!
|
|
* \brief Verifies if an acquisition procedure is in progress
|
|
*
|
|
* \retval [true, if the acquisition is in progress; false, if not]
|
|
*/
|
|
bool LoRaMacClassBIsAcquisitionInProgress( void );
|
|
|
|
/*!
|
|
* \brief State machine of the Class B for beaconing
|
|
*/
|
|
void LoRaMacClassBBeaconTimerEvent( void* context );
|
|
|
|
/*!
|
|
* \brief State machine of the Class B for ping slots
|
|
*/
|
|
void LoRaMacClassBPingSlotTimerEvent( void* context );
|
|
|
|
/*!
|
|
* \brief State machine of the Class B for multicast slots
|
|
*/
|
|
void LoRaMacClassBMulticastSlotTimerEvent( void* context );
|
|
|
|
/*!
|
|
* \brief Receives and decodes the beacon frame
|
|
*
|
|
* \param [IN] payload Pointer to the payload
|
|
* \param [IN] size Size of the payload
|
|
* \retval [true, if the node has received a beacon; false, if not]
|
|
*/
|
|
bool LoRaMacClassBRxBeacon( uint8_t *payload, uint16_t size );
|
|
|
|
/*!
|
|
* \brief The function validates, if the node expects a beacon
|
|
* at the current time.
|
|
*
|
|
* \retval [true, if the node expects a beacon; false, if not]
|
|
*/
|
|
bool LoRaMacClassBIsBeaconExpected( void );
|
|
|
|
/*!
|
|
* \brief The function validates, if the node expects a ping slot
|
|
* at the current time.
|
|
*
|
|
* \retval [true, if the node expects a ping slot; false, if not]
|
|
*/
|
|
bool LoRaMacClassBIsPingExpected( void );
|
|
|
|
/*!
|
|
* \brief The function validates, if the node expects a multicast slot
|
|
* at the current time.
|
|
*
|
|
* \retval [true, if the node expects a multicast slot; false, if not]
|
|
*/
|
|
bool LoRaMacClassBIsMulticastExpected( void );
|
|
|
|
/*!
|
|
* \brief Verifies if the acquisition pending bit is set
|
|
*
|
|
* \retval [true, if the bit is set; false, if not]
|
|
*/
|
|
bool LoRaMacClassBIsAcquisitionPending( void );
|
|
|
|
/*!
|
|
* \brief Verifies if the beacon mode active bit is set
|
|
*
|
|
* \retval [true, if the bit is set; false, if not]
|
|
*/
|
|
bool LoRaMacClassBIsBeaconModeActive( void );
|
|
|
|
/*!
|
|
* \brief Stops the beacon and ping slot operation
|
|
*/
|
|
void LoRaMacClassBHaltBeaconing( void );
|
|
|
|
/*!
|
|
* \brief Resumes the beacon and ping slot operation
|
|
*/
|
|
void LoRaMacClassBResumeBeaconing( void );
|
|
|
|
/*!
|
|
* \brief Sets the periodicity of the ping slots
|
|
*
|
|
* \param [IN] periodicity Periodicity
|
|
*/
|
|
void LoRaMacClassBSetPingSlotInfo( uint8_t periodicity );
|
|
|
|
/*!
|
|
* \brief Switches the device class
|
|
*
|
|
* \param [IN] nextClass Device class to switch to
|
|
*
|
|
* \retval LoRaMacStatus_t Status of the operation.
|
|
*/
|
|
LoRaMacStatus_t LoRaMacClassBSwitchClass( DeviceClass_t nextClass );
|
|
|
|
/*!
|
|
* \brief LoRaMAC ClassB MIB-Get
|
|
*
|
|
* \details The mac information base service to get attributes of the LoRaMac
|
|
* Class B layer.
|
|
*
|
|
* \param [IN] mibRequest - MIB-GET-Request to perform. Refer to \ref MibRequestConfirm_t.
|
|
*
|
|
* \retval LoRaMacStatus_t Status of the operation. Possible returns are:
|
|
* \ref LORAMAC_STATUS_OK,
|
|
* \ref LORAMAC_STATUS_SERVICE_UNKNOWN,
|
|
* \ref LORAMAC_STATUS_PARAMETER_INVALID.
|
|
*/
|
|
LoRaMacStatus_t LoRaMacClassBMibGetRequestConfirm( MibRequestConfirm_t *mibGet );
|
|
|
|
/*!
|
|
* \brief LoRaMAC Class B MIB-Set
|
|
*
|
|
* \details The mac information base service to set attributes of the LoRaMac
|
|
* Class B layer.
|
|
*
|
|
* \param [IN] mibRequest - MIB-SET-Request to perform. Refer to \ref MibRequestConfirm_t.
|
|
*
|
|
* \retval LoRaMacStatus_t Status of the operation. Possible returns are:
|
|
* \ref LORAMAC_STATUS_OK,
|
|
* \ref LORAMAC_STATUS_BUSY,
|
|
* \ref LORAMAC_STATUS_SERVICE_UNKNOWN,
|
|
* \ref LORAMAC_STATUS_PARAMETER_INVALID.
|
|
*/
|
|
LoRaMacStatus_t LoRaMacMibClassBSetRequestConfirm( MibRequestConfirm_t *mibSet );
|
|
|
|
/*!
|
|
* \brief This function handles the PING_SLOT_FREQ_ANS
|
|
*/
|
|
void LoRaMacClassBPingSlotInfoAns( void );
|
|
|
|
/*!
|
|
* \brief This function handles the PING_SLOT_CHANNEL_REQ
|
|
*
|
|
* \param [IN] datarate Device class to switch to
|
|
* \param [IN] frequency Device class to switch to
|
|
*
|
|
* \retval Status for the MAC answer.
|
|
*/
|
|
uint8_t LoRaMacClassBPingSlotChannelReq( uint8_t datarate, uint32_t frequency );
|
|
|
|
/*!
|
|
* \brief This function handles the BEACON_TIMING_ANS
|
|
*
|
|
* \param [IN] beaconTimingDelay The beacon timing delay
|
|
* \param [IN] beaconTimingChannel The beacon timing channel
|
|
* \param [IN] lastRxDone The time of the last frame reception
|
|
*/
|
|
void LoRaMacClassBBeaconTimingAns( uint16_t beaconTimingDelay, uint8_t beaconTimingChannel, TimerTime_t lastRxDone );
|
|
|
|
/*!
|
|
* \brief This function handles the ClassB DEVICE_TIME_ANS
|
|
*/
|
|
void LoRaMacClassBDeviceTimeAns( void );
|
|
|
|
/*!
|
|
* \brief This function handles the BEACON_FREQ_REQ
|
|
*
|
|
* \param [IN] frequency Frequency to set
|
|
*
|
|
* \retval [true, if MAC shall send an answer; false, if not]
|
|
*/
|
|
bool LoRaMacClassBBeaconFreqReq( uint32_t frequency );
|
|
|
|
/*!
|
|
* \brief Queries the ping slot window time
|
|
*
|
|
* \param [IN] txTimeOnAir TX time on air for the next uplink
|
|
*
|
|
* \retval Returns the time the uplink should be delayed
|
|
*/
|
|
TimerTime_t LoRaMacClassBIsUplinkCollision( TimerTime_t txTimeOnAir );
|
|
|
|
/*!
|
|
* \brief Stops the timers for the RX slots. This includes the
|
|
* timers for ping and multicast slots.
|
|
*/
|
|
void LoRaMacClassBStopRxSlots( void );
|
|
|
|
/*!
|
|
* \brief Starts the timers for the RX slots. This includes the
|
|
* timers for ping and multicast slots.
|
|
*/
|
|
void LoRaMacClassBStartRxSlots( void );
|
|
|
|
/*!
|
|
* \brief Starts the timers for the RX slots. This includes the
|
|
* timers for ping and multicast slots.
|
|
*
|
|
* \param [IN] periodicity Downlink periodicity
|
|
*
|
|
* \param [IN] multicastChannel Related multicast channel
|
|
*/
|
|
void LoRaMacClassBSetMulticastPeriodicity( MulticastCtx_t* multicastChannel );
|
|
|
|
void LoRaMacClassBProcess( void );
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif // __LORAMACCLASSB_H__
|