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:
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user