531 lines
21 KiB
C
531 lines
21 KiB
C
/*!
|
|
* \file LmhpRemoteMcastSetup.c
|
|
*
|
|
* \brief Implements the LoRa-Alliance remote multicast setup package
|
|
* Specification: https://lora-alliance.org/sites/default/files/2018-09/remote_multicast_setup_v1.0.0.pdf
|
|
*
|
|
* \copyright Revised BSD License, see section \ref LICENSE.
|
|
*
|
|
* \code
|
|
* ______ _
|
|
* / _____) _ | |
|
|
* ( (____ _____ ____ _| |_ _____ ____| |__
|
|
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
|
* _____) ) ____| | | || |_| ____( (___| | | |
|
|
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
|
* (C)2013-2018 Semtech
|
|
*
|
|
* \endcode
|
|
*
|
|
* \author Miguel Luis ( Semtech )
|
|
*/
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* Portions COPYRIGHT 2020 STMicroelectronics
|
|
*
|
|
* @file LmhpRemoteMcastSetup.c
|
|
* @author MCD Application Team
|
|
* @brief Remote Multicast Package definition
|
|
******************************************************************************
|
|
*/
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "LmHandler.h"
|
|
#include "LmhpRemoteMcastSetup.h"
|
|
#include "mw_log_conf.h" /* needed for MW_LOG */
|
|
|
|
/*!
|
|
* LoRaWAN Application Layer Remote multicast setup Specification
|
|
*/
|
|
#define REMOTE_MCAST_SETUP_PORT 200
|
|
|
|
#define REMOTE_MCAST_SETUP_ID 2
|
|
#define REMOTE_MCAST_SETUP_VERSION 1
|
|
|
|
typedef enum LmhpRemoteMcastSetupSessionStates_e
|
|
{
|
|
REMOTE_MCAST_SETUP_SESSION_STATE_IDLE,
|
|
REMOTE_MCAST_SETUP_SESSION_STATE_START,
|
|
REMOTE_MCAST_SETUP_SESSION_STATE_STOP,
|
|
}LmhpRemoteMcastSetupSessionStates_t;
|
|
|
|
/*!
|
|
* Package current context
|
|
*/
|
|
typedef struct LmhpRemoteMcastSetupState_s
|
|
{
|
|
bool Initialized;
|
|
bool IsRunning;
|
|
LmhpRemoteMcastSetupSessionStates_t SessionState;
|
|
uint8_t DataBufferMaxSize;
|
|
uint8_t *DataBuffer;
|
|
}LmhpRemoteMcastSetupState_t;
|
|
|
|
typedef enum LmhpRemoteMcastSetupMoteCmd_e
|
|
{
|
|
REMOTE_MCAST_SETUP_PKG_VERSION_ANS = 0x00,
|
|
REMOTE_MCAST_SETUP_MC_GROUP_STATUS_ANS = 0x01,
|
|
REMOTE_MCAST_SETUP_MC_GROUP_SETUP_ANS = 0x02,
|
|
REMOTE_MCAST_SETUP_MC_GROUP_DELETE_ANS = 0x03,
|
|
REMOTE_MCAST_SETUP_MC_GROUP_CLASS_C_SESSION_ANS = 0x04,
|
|
REMOTE_MCAST_SETUP_MC_GROUP_CLASS_B_SESSION_ANS = 0x05,
|
|
}LmhpRemoteMcastSetupMoteCmd_t;
|
|
|
|
typedef enum LmhpRemoteMcastSetupSrvCmd_e
|
|
{
|
|
REMOTE_MCAST_SETUP_PKG_VERSION_REQ = 0x00,
|
|
REMOTE_MCAST_SETUP_MC_GROUP_STATUS_REQ = 0x01,
|
|
REMOTE_MCAST_SETUP_MC_GROUP_SETUP_REQ = 0x02,
|
|
REMOTE_MCAST_SETUP_MC_GROUP_DELETE_REQ = 0x03,
|
|
REMOTE_MCAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ = 0x04,
|
|
REMOTE_MCAST_SETUP_MC_GROUP_CLASS_B_SESSION_REQ = 0x05,
|
|
}LmhpRemoteMcastSetupSrvCmd_t;
|
|
|
|
/*!
|
|
* Initializes the package with provided parameters
|
|
*
|
|
* \param [IN] params Pointer to the package parameters
|
|
* \param [IN] dataBuffer Pointer to main application buffer
|
|
* \param [IN] dataBufferMaxSize Main application buffer maximum size
|
|
*/
|
|
static void LmhpRemoteMcastSetupInit( void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize );
|
|
|
|
/*!
|
|
* Returns the current package initialization status.
|
|
*
|
|
* \retval status Package initialization status
|
|
* [true: Initialized, false: Not initialized]
|
|
*/
|
|
static bool LmhpRemoteMcastSetupIsInitialized( void );
|
|
|
|
/*!
|
|
* Returns the package operation status.
|
|
*
|
|
* \retval status Package operation status
|
|
* [true: Running, false: Not running]
|
|
*/
|
|
static bool LmhpRemoteMcastSetupIsRunning( void );
|
|
|
|
/*!
|
|
* Processes the internal package events.
|
|
*/
|
|
static void LmhpRemoteMcastSetupProcess( void );
|
|
|
|
/*!
|
|
* Processes the MCPS Indication
|
|
*
|
|
* \param [IN] mcpsIndication MCPS indication primitive data
|
|
*/
|
|
static void LmhpRemoteMcastSetupOnMcpsIndication( McpsIndication_t *mcpsIndication );
|
|
|
|
static void OnSessionStartTimer( void *context );
|
|
|
|
static void OnSessionStopTimer( void *context );
|
|
|
|
static LmhpRemoteMcastSetupState_t LmhpRemoteMcastSetupState =
|
|
{
|
|
.Initialized = false,
|
|
.IsRunning = false,
|
|
.SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_IDLE,
|
|
};
|
|
|
|
typedef struct McGroupData_s
|
|
{
|
|
uint8_t McGroupEnabled;
|
|
union
|
|
{
|
|
uint8_t Value;
|
|
struct
|
|
{
|
|
uint8_t McGroupId: 2;
|
|
uint8_t RFU: 6;
|
|
}Fields;
|
|
}IdHeader;
|
|
uint32_t McAddr;
|
|
uint8_t McKeyEncrypted[16];
|
|
uint32_t McFCountMin;
|
|
uint32_t McFCountMax;
|
|
}McGroupData_t;
|
|
|
|
typedef enum eSessionState
|
|
{
|
|
SESSION_STOPPED,
|
|
SESSION_STARTED
|
|
}SessionState_t;
|
|
|
|
typedef struct McSessionData_s
|
|
{
|
|
McGroupData_t McGroupData;
|
|
SessionState_t SessionState;
|
|
uint32_t SessionTime;
|
|
uint8_t SessionTimeout;
|
|
McRxParams_t RxParams;
|
|
}McSessionData_t;
|
|
|
|
static McSessionData_t McSessionData[LORAMAC_MAX_MC_CTX];
|
|
|
|
/*!
|
|
* Session start timer
|
|
*/
|
|
static TimerEvent_t SessionStartTimer;
|
|
|
|
/*!
|
|
* Session start timer
|
|
*/
|
|
static TimerEvent_t SessionStopTimer;
|
|
|
|
static LmhPackage_t LmhpRemoteMcastSetupPackage =
|
|
{
|
|
.Port = REMOTE_MCAST_SETUP_PORT,
|
|
.Init = LmhpRemoteMcastSetupInit,
|
|
.IsInitialized = LmhpRemoteMcastSetupIsInitialized,
|
|
.IsRunning = LmhpRemoteMcastSetupIsRunning,
|
|
.Process = LmhpRemoteMcastSetupProcess,
|
|
.OnMcpsConfirmProcess = NULL, // Not used in this package
|
|
.OnMcpsIndicationProcess = LmhpRemoteMcastSetupOnMcpsIndication,
|
|
.OnMlmeConfirmProcess = NULL, // Not used in this package
|
|
.OnJoinRequest = NULL, // To be initialized by LmHandler
|
|
.OnSendRequest = NULL, // To be initialized by LmHandler
|
|
.OnDeviceTimeRequest = NULL, // To be initialized by LmHandler
|
|
.OnSysTimeUpdate = NULL, // To be initialized by LmHandler
|
|
.OnPackageProcessEvent = NULL, // To be initialized by LmHandler
|
|
};
|
|
|
|
LmhPackage_t *LmhpRemoteMcastSetupPackageFactory( void )
|
|
{
|
|
return &LmhpRemoteMcastSetupPackage;
|
|
}
|
|
|
|
static void LmhpRemoteMcastSetupInit( void * params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize )
|
|
{
|
|
if( dataBuffer != NULL )
|
|
{
|
|
LmhpRemoteMcastSetupState.DataBuffer = dataBuffer;
|
|
LmhpRemoteMcastSetupState.DataBufferMaxSize = dataBufferMaxSize;
|
|
LmhpRemoteMcastSetupState.Initialized = true;
|
|
LmhpRemoteMcastSetupState.IsRunning = true;
|
|
TimerInit( &SessionStartTimer, OnSessionStartTimer );
|
|
TimerInit( &SessionStopTimer, OnSessionStopTimer );
|
|
}
|
|
else
|
|
{
|
|
LmhpRemoteMcastSetupState.IsRunning = false;
|
|
LmhpRemoteMcastSetupState.Initialized = false;
|
|
}
|
|
|
|
for (uint8_t id = 0; id < LORAMAC_MAX_MC_CTX; id++)
|
|
{
|
|
McSessionData[id].McGroupData.McGroupEnabled = false;
|
|
}
|
|
}
|
|
|
|
static bool LmhpRemoteMcastSetupIsInitialized( void )
|
|
{
|
|
return LmhpRemoteMcastSetupState.Initialized;
|
|
}
|
|
|
|
static bool LmhpRemoteMcastSetupIsRunning( void )
|
|
{
|
|
if( LmhpRemoteMcastSetupState.Initialized == false )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return LmhpRemoteMcastSetupState.IsRunning;
|
|
}
|
|
|
|
static void LmhpRemoteMcastSetupProcess( void )
|
|
{
|
|
LmhpRemoteMcastSetupSessionStates_t state;
|
|
|
|
CRITICAL_SECTION_BEGIN( );
|
|
state = LmhpRemoteMcastSetupState.SessionState;
|
|
CRITICAL_SECTION_END( );
|
|
|
|
switch( state )
|
|
{
|
|
case REMOTE_MCAST_SETUP_SESSION_STATE_START:
|
|
// Switch to Class C
|
|
|
|
if ( LmHandlerRequestClass( CLASS_C ) == LORAMAC_HANDLER_SUCCESS )
|
|
{
|
|
LmhpRemoteMcastSetupState.SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_IDLE;
|
|
|
|
TimerSetValue( &SessionStopTimer, ( 1 << McSessionData[0].SessionTimeout ) * 1000 );
|
|
TimerStart(&SessionStopTimer);
|
|
}
|
|
else
|
|
{
|
|
TimerSetValue( &SessionStartTimer, 1000 );
|
|
TimerStart(&SessionStartTimer);
|
|
}
|
|
break;
|
|
case REMOTE_MCAST_SETUP_SESSION_STATE_STOP:
|
|
// Switch back to Class A
|
|
if ( LmHandlerRequestClass( CLASS_A ) == LORAMAC_HANDLER_SUCCESS )
|
|
{
|
|
LmhpRemoteMcastSetupState.SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_IDLE;
|
|
}
|
|
else
|
|
{
|
|
TimerSetValue( &SessionStopTimer, 1000 );
|
|
TimerStart(&SessionStopTimer);
|
|
}
|
|
break;
|
|
case REMOTE_MCAST_SETUP_SESSION_STATE_IDLE:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void LmhpRemoteMcastSetupOnMcpsIndication( McpsIndication_t *mcpsIndication )
|
|
{
|
|
uint8_t cmdIndex = 0;
|
|
uint8_t dataBufferIndex = 0;
|
|
uint8_t id = 0xFF;
|
|
|
|
if( mcpsIndication->Port != REMOTE_MCAST_SETUP_PORT )
|
|
{
|
|
return;
|
|
}
|
|
|
|
while( cmdIndex < mcpsIndication->BufferSize )
|
|
{
|
|
switch( mcpsIndication->Buffer[cmdIndex++] )
|
|
{
|
|
case REMOTE_MCAST_SETUP_PKG_VERSION_REQ:
|
|
{
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_PKG_VERSION_ANS;
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_ID;
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_VERSION;
|
|
break;
|
|
}
|
|
case REMOTE_MCAST_SETUP_MC_GROUP_STATUS_REQ:
|
|
{
|
|
uint8_t nbAvailableGroups = 0;
|
|
uint8_t reqGroupMask = mcpsIndication->Buffer[cmdIndex++] & 0x0F;
|
|
uint8_t AnsGroupMask = 0x00;
|
|
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_MC_GROUP_STATUS_ANS;
|
|
|
|
/* move index to the next first optional list */
|
|
dataBufferIndex++;
|
|
for (id = 0; id < LORAMAC_MAX_MC_CTX; id++)
|
|
{
|
|
if( McSessionData[id].McGroupData.McGroupEnabled )
|
|
{
|
|
nbAvailableGroups++;
|
|
|
|
/* If multicast group defined in the input bit mask */
|
|
if( ( reqGroupMask & ( 1 << id ) ) != 0 )
|
|
{
|
|
AnsGroupMask |= (1 << id);
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = id;
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (McSessionData[id].McGroupData.McAddr >> 0) & 0xFF;
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (McSessionData[id].McGroupData.McAddr >> 8) & 0xFF;
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (McSessionData[id].McGroupData.McAddr >> 16) & 0xFF;
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (McSessionData[id].McGroupData.McAddr >> 24) & 0xFF;
|
|
}
|
|
}
|
|
}
|
|
/* set the status bit */
|
|
LmhpRemoteMcastSetupState.DataBuffer[1] = (nbAvailableGroups & 0x07) << 4 | (AnsGroupMask & 0x0F);
|
|
|
|
break;
|
|
}
|
|
case REMOTE_MCAST_SETUP_MC_GROUP_SETUP_REQ:
|
|
{
|
|
id = mcpsIndication->Buffer[cmdIndex++] & 0x03;
|
|
McSessionData[id].McGroupData.IdHeader.Value = id;
|
|
|
|
McSessionData[id].McGroupData.McAddr = ( mcpsIndication->Buffer[cmdIndex++] << 0 ) & 0x000000FF;
|
|
McSessionData[id].McGroupData.McAddr += ( mcpsIndication->Buffer[cmdIndex++] << 8 ) & 0x0000FF00;
|
|
McSessionData[id].McGroupData.McAddr += ( mcpsIndication->Buffer[cmdIndex++] << 16 ) & 0x00FF0000;
|
|
McSessionData[id].McGroupData.McAddr += ( mcpsIndication->Buffer[cmdIndex++] << 24 ) & 0xFF000000;
|
|
|
|
for( int8_t i = 0; i < 16; i++ )
|
|
{
|
|
McSessionData[id].McGroupData.McKeyEncrypted[i] = mcpsIndication->Buffer[cmdIndex++];
|
|
}
|
|
|
|
McSessionData[id].McGroupData.McFCountMin = ( mcpsIndication->Buffer[cmdIndex++] << 0 ) & 0x000000FF;
|
|
McSessionData[id].McGroupData.McFCountMin += ( mcpsIndication->Buffer[cmdIndex++] << 8 ) & 0x0000FF00;
|
|
McSessionData[id].McGroupData.McFCountMin += ( mcpsIndication->Buffer[cmdIndex++] << 16 ) & 0x00FF0000;
|
|
McSessionData[id].McGroupData.McFCountMin += ( mcpsIndication->Buffer[cmdIndex++] << 24 ) & 0xFF000000;
|
|
|
|
McSessionData[id].McGroupData.McFCountMax = ( mcpsIndication->Buffer[cmdIndex++] << 0 ) & 0x000000FF;
|
|
McSessionData[id].McGroupData.McFCountMax += ( mcpsIndication->Buffer[cmdIndex++] << 8 ) & 0x0000FF00;
|
|
McSessionData[id].McGroupData.McFCountMax += ( mcpsIndication->Buffer[cmdIndex++] << 16 ) & 0x00FF0000;
|
|
McSessionData[id].McGroupData.McFCountMax += ( mcpsIndication->Buffer[cmdIndex++] << 24 ) & 0xFF000000;
|
|
|
|
McChannelParams_t channel =
|
|
{
|
|
.IsRemotelySetup = true,
|
|
.Class = CLASS_C, // Field not used for multicast channel setup. Must be initialized to something
|
|
.IsEnabled = true,
|
|
.GroupID = ( AddressIdentifier_t )McSessionData[id].McGroupData.IdHeader.Fields.McGroupId,
|
|
.Address = McSessionData[id].McGroupData.McAddr,
|
|
.McKeys.McKeyE = McSessionData[id].McGroupData.McKeyEncrypted,
|
|
.FCountMin = McSessionData[id].McGroupData.McFCountMin,
|
|
.FCountMax = McSessionData[id].McGroupData.McFCountMax,
|
|
.RxParams.ClassC = // Field not used for multicast channel setup. Must be initialized to something
|
|
{
|
|
.Frequency = 0,
|
|
.Datarate = 0
|
|
}
|
|
};
|
|
uint8_t idError = 0x01; // One bit value
|
|
if( LoRaMacMcChannelSetup( &channel ) == LORAMAC_STATUS_OK )
|
|
{
|
|
idError = 0x00;
|
|
McSessionData[id].McGroupData.McGroupEnabled = true;
|
|
}
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_MC_GROUP_SETUP_ANS;
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = ( idError << 2 ) | McSessionData[id].McGroupData.IdHeader.Fields.McGroupId;
|
|
break;
|
|
}
|
|
case REMOTE_MCAST_SETUP_MC_GROUP_DELETE_REQ:
|
|
{
|
|
uint8_t status = 0x00;
|
|
id = mcpsIndication->Buffer[cmdIndex++] & 0x03;
|
|
|
|
status = id;
|
|
McSessionData[id].McGroupData.IdHeader.Value = 0;
|
|
McSessionData[id].McGroupData.McAddr = 0;
|
|
UTIL_MEM_set_8( McSessionData[id].McGroupData.McKeyEncrypted, 0x00, 16 );
|
|
McSessionData[id].McGroupData.McFCountMin = 0;
|
|
McSessionData[id].McGroupData.McFCountMax = 0;
|
|
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_MC_GROUP_DELETE_ANS;
|
|
|
|
if( LoRaMacMcChannelDelete( ( AddressIdentifier_t )id ) != LORAMAC_STATUS_OK )
|
|
{
|
|
status |= 0x04; // McGroupUndefined bit set
|
|
}
|
|
else
|
|
{
|
|
McSessionData[id].McGroupData.McGroupEnabled = false;
|
|
}
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = status;
|
|
break;
|
|
}
|
|
case REMOTE_MCAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ:
|
|
{
|
|
uint8_t status = 0x00;
|
|
int32_t timeToSessionStart = 0;
|
|
id = mcpsIndication->Buffer[cmdIndex++] & 0x03;
|
|
|
|
McSessionData[id].SessionTime = ( mcpsIndication->Buffer[cmdIndex++] << 0 ) & 0x000000FF;
|
|
McSessionData[id].SessionTime += ( mcpsIndication->Buffer[cmdIndex++] << 8 ) & 0x0000FF00;
|
|
McSessionData[id].SessionTime += ( mcpsIndication->Buffer[cmdIndex++] << 16 ) & 0x00FF0000;
|
|
McSessionData[id].SessionTime += ( mcpsIndication->Buffer[cmdIndex++] << 24 ) & 0xFF000000;
|
|
|
|
// Add Unix to Gps epoch offset. The system time is based on Unix time.
|
|
McSessionData[id].SessionTime += UNIX_GPS_EPOCH_OFFSET;
|
|
|
|
McSessionData[id].SessionTimeout = mcpsIndication->Buffer[cmdIndex++] & 0x0F;
|
|
|
|
McSessionData[id].RxParams.ClassC.Frequency = ( mcpsIndication->Buffer[cmdIndex++] << 0 ) & 0x000000FF;
|
|
McSessionData[id].RxParams.ClassC.Frequency |= ( mcpsIndication->Buffer[cmdIndex++] << 8 ) & 0x0000FF00;
|
|
McSessionData[id].RxParams.ClassC.Frequency |= ( mcpsIndication->Buffer[cmdIndex++] << 16 ) & 0x00FF0000;
|
|
McSessionData[id].RxParams.ClassC.Frequency *= 100;
|
|
|
|
McSessionData[id].RxParams.ClassC.Datarate = mcpsIndication->Buffer[cmdIndex++];
|
|
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_MC_GROUP_CLASS_C_SESSION_ANS;
|
|
if( LoRaMacMcChannelSetupRxParams( ( AddressIdentifier_t )id, &McSessionData[id].RxParams, &status ) == LORAMAC_STATUS_OK )
|
|
{
|
|
SysTime_t curTime = { .Seconds = 0, .SubSeconds = 0 };
|
|
curTime = SysTimeGet( );
|
|
|
|
timeToSessionStart = McSessionData[id].SessionTime - curTime.Seconds;
|
|
if( timeToSessionStart > 0 )
|
|
{
|
|
// Start session start timer
|
|
TimerSetValue( &SessionStartTimer, timeToSessionStart * 1000 );
|
|
TimerStart( &SessionStartTimer );
|
|
|
|
MW_LOG(TS_OFF, VLEVEL_M, "Time2SessionStart: %d ms\r\n", timeToSessionStart * 1000);
|
|
}
|
|
else
|
|
{
|
|
// Session start time before current device time
|
|
status |= 0x10;
|
|
}
|
|
}
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = status;
|
|
if( status == 0x00 )
|
|
{
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (timeToSessionStart >> 0) & 0xFF;
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (timeToSessionStart >> 8) & 0xFF;
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (timeToSessionStart >> 16) & 0xFF;
|
|
}
|
|
break;
|
|
}
|
|
case REMOTE_MCAST_SETUP_MC_GROUP_CLASS_B_SESSION_REQ:
|
|
{
|
|
// implement command prosessing and handling
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( dataBufferIndex != 0 )
|
|
{
|
|
// Answer commands
|
|
LmHandlerAppData_t appData =
|
|
{
|
|
.Buffer = LmhpRemoteMcastSetupState.DataBuffer,
|
|
.BufferSize = dataBufferIndex,
|
|
.Port = REMOTE_MCAST_SETUP_PORT
|
|
};
|
|
|
|
bool current_dutycycle;
|
|
LmHandlerGetDutyCycleEnable( ¤t_dutycycle );
|
|
|
|
/* force Duty Cycle OFF to this Send */
|
|
LmHandlerSetDutyCycleEnable( false );
|
|
LmhpRemoteMcastSetupPackage.OnSendRequest( &appData, LORAMAC_HANDLER_UNCONFIRMED_MSG, NULL, true );
|
|
|
|
/* restore initial Duty Cycle */
|
|
LmHandlerSetDutyCycleEnable( current_dutycycle );
|
|
|
|
if (id != 0xFF && id < LORAMAC_MAX_MC_CTX)
|
|
{
|
|
MW_LOG(TS_OFF, VLEVEL_M, "ID : %d\r\n", McSessionData[id].McGroupData.IdHeader.Fields.McGroupId);
|
|
MW_LOG(TS_OFF, VLEVEL_M, "McAddr : %08X\r\n", McSessionData[id].McGroupData.McAddr);
|
|
MW_LOG(TS_OFF, VLEVEL_M, "McKey : %02X", McSessionData[id].McGroupData.McKeyEncrypted[0]);
|
|
for ( int i = 1; i < 16; i++ )
|
|
{
|
|
MW_LOG(TS_OFF, VLEVEL_M, "-%02X", McSessionData[id].McGroupData.McKeyEncrypted[i]);
|
|
}
|
|
MW_LOG(TS_OFF, VLEVEL_M, "\r\n");
|
|
MW_LOG(TS_OFF, VLEVEL_M, "McFCountMin : %u\r\n", McSessionData[id].McGroupData.McFCountMin);
|
|
MW_LOG(TS_OFF, VLEVEL_M, "McFCountMax : %u\r\n", McSessionData[id].McGroupData.McFCountMax);
|
|
MW_LOG(TS_OFF, VLEVEL_M, "SessionTime : %u\r\n", McSessionData[id].SessionTime);
|
|
MW_LOG(TS_OFF, VLEVEL_M, "SessionTimeT: %d s\r\n", (1 << McSessionData[id].SessionTimeout));
|
|
MW_LOG(TS_OFF, VLEVEL_M, "Rx Freq : %u\r\n", McSessionData[id].RxParams.ClassC.Frequency);
|
|
MW_LOG(TS_OFF, VLEVEL_M, "Rx DR : DR_%d\r\n", McSessionData[id].RxParams.ClassC.Datarate);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void OnSessionStartTimer( void *context )
|
|
{
|
|
TimerStop( &SessionStartTimer );
|
|
LmhpRemoteMcastSetupState.SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_START;
|
|
LmhpRemoteMcastSetupPackage.OnPackageProcessEvent();
|
|
}
|
|
|
|
static void OnSessionStopTimer( void *context )
|
|
{
|
|
TimerStop( &SessionStopTimer );
|
|
LmhpRemoteMcastSetupState.SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_STOP;
|
|
LmhpRemoteMcastSetupPackage.OnPackageProcessEvent();
|
|
}
|