520 lines
19 KiB
C
520 lines
19 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 */
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
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;
|
|
|
|
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;
|
|
|
|
/* Private define ------------------------------------------------------------*/
|
|
/*!
|
|
* 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
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
/*!
|
|
* 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);
|
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
static LmhpRemoteMcastSetupState_t LmhpRemoteMcastSetupState =
|
|
{
|
|
.Initialized = false,
|
|
.IsRunning = false,
|
|
.SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_IDLE,
|
|
};
|
|
|
|
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 */
|
|
};
|
|
|
|
/* Exported functions ---------------------------------------------------------*/
|
|
LmhPackage_t *LmhpRemoteMcastSetupPackageFactory(void)
|
|
{
|
|
return &LmhpRemoteMcastSetupPackage;
|
|
}
|
|
|
|
/* Private functions ---------------------------------------------------------*/
|
|
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);
|
|
}
|
|
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;
|
|
}
|
|
break;
|
|
case REMOTE_MCAST_SETUP_SESSION_STATE_IDLE:
|
|
/* Intentional fall through */
|
|
default:
|
|
/* Nothing to do. */
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void LmhpRemoteMcastSetupOnMcpsIndication(McpsIndication_t *mcpsIndication)
|
|
{
|
|
uint8_t cmdIndex = 0;
|
|
uint8_t dataBufferIndex = 0;
|
|
uint8_t id = 0xFF;
|
|
|
|
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:
|
|
{
|
|
uint8_t status = 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
|
|
}
|
|
};
|
|
if (LoRaMacMcChannelSetup(&channel) != LORAMAC_STATUS_OK)
|
|
{
|
|
status |= 0x04; /* IDerror bit */
|
|
}
|
|
else
|
|
{
|
|
McSessionData[id].McGroupData.McGroupEnabled = true;
|
|
}
|
|
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_MC_GROUP_SETUP_ANS;
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = status;
|
|
|
|
break;
|
|
}
|
|
case REMOTE_MCAST_SETUP_MC_GROUP_DELETE_REQ:
|
|
{
|
|
uint8_t status = id = mcpsIndication->Buffer[cmdIndex++] & 0x03;
|
|
|
|
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;
|
|
id = mcpsIndication->Buffer[cmdIndex++] & 0x03;
|
|
int32_t timeToSessionStart = 0;
|
|
|
|
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 epcoh 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();
|
|
|
|
if ((McSessionData[id].SessionTime - curTime.Seconds) > 0)
|
|
{
|
|
timeToSessionStart = McSessionData[id].SessionTime - curTime.Seconds;
|
|
/* 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 |= 0x20;
|
|
}
|
|
}
|
|
LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = status;
|
|
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;
|
|
LmhpRemoteMcastSetupProcess();
|
|
}
|
|
|
|
static void OnSessionStopTimer(void *context)
|
|
{
|
|
TimerStop(&SessionStopTimer);
|
|
LmhpRemoteMcastSetupState.SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_STOP;
|
|
}
|