mirror of
https://github.com/espressif/openthread.git
synced 2026-09-18 07:00:08 +00:00
[simul-platform] enhance radio nodeidfilter command (#8740)
This commit updates the custom CLI command `nodeidfilter` defined for simulation platform enabling filtering at radio level. This commit enhances this command so it can be used as both a deny-list or an allow-list. It also adds support to output the list and filter mode when no arg is given.
This commit is contained in:
@@ -76,9 +76,17 @@ static const otCliCommand kCommands[] = {
|
|||||||
#if OPENTHREAD_EXAMPLES_SIMULATION
|
#if OPENTHREAD_EXAMPLES_SIMULATION
|
||||||
/*
|
/*
|
||||||
* The CLI command `nodeidfilter` only works for simulation in real time.
|
* The CLI command `nodeidfilter` only works for simulation in real time.
|
||||||
|
*
|
||||||
|
* It can be used either as an allow list or a deny list. Once the filter is cleared, the first `nodeidfilter allow`
|
||||||
|
* or `nodeidfilter deny` will determine whether it is set up as an allow or deny list. Subsequent calls should
|
||||||
|
* use the same sub-command to add new node IDs, e.g., if we first call `nodeidfilter allow` (which sets the filter
|
||||||
|
* up as an allow list), a subsequent `nodeidfilter deny` will result in `InvalidState` error.
|
||||||
|
*
|
||||||
* The usage of the command `nodeidfilter`:
|
* The usage of the command `nodeidfilter`:
|
||||||
* - `nodeidfilter deny <nodeid>`: It denies the connection to a specified node.
|
* - `nodeidfilter deny <nodeid>` : It denies the connection to a specified node (use as deny-list).
|
||||||
* - `nodeidfilter clear`: It restores the filter state to default.
|
* - `nodeidfilter allow <nodeid> : It allows the connection to a specified node (use as allow-list).
|
||||||
|
* - `nodeidfilter clear` : It restores the filter state to default.
|
||||||
|
* - `nodeidfilter` : Outputs filter mode (allow-list or deny-list) and filtered node IDs.
|
||||||
*/
|
*/
|
||||||
{"nodeidfilter", ProcessNodeIdFilter},
|
{"nodeidfilter", ProcessNodeIdFilter},
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <openthread/cli.h>
|
||||||
#include <openthread/dataset.h>
|
#include <openthread/dataset.h>
|
||||||
#include <openthread/link.h>
|
#include <openthread/link.h>
|
||||||
#include <openthread/random_noncrypto.h>
|
#include <openthread/random_noncrypto.h>
|
||||||
@@ -169,39 +170,90 @@ static otRadioKeyType sKeyType;
|
|||||||
static int8_t GetRssi(uint16_t aChannel);
|
static int8_t GetRssi(uint16_t aChannel);
|
||||||
|
|
||||||
#if OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
|
#if OPENTHREAD_SIMULATION_VIRTUAL_TIME == 0
|
||||||
static uint8_t sDeniedNodeIdsBitVector[(MAX_NETWORK_SIZE + 7) / 8];
|
|
||||||
|
static enum {
|
||||||
|
kFilterOff,
|
||||||
|
kFilterDenyList,
|
||||||
|
kFilterAllowList,
|
||||||
|
} sFilterMode = kFilterOff;
|
||||||
|
|
||||||
|
static uint8_t sFilterNodeIdsBitVector[(MAX_NETWORK_SIZE + 7) / 8];
|
||||||
|
|
||||||
|
static bool FilterContainsId(uint16_t aNodeId)
|
||||||
|
{
|
||||||
|
uint16_t index = aNodeId - 1;
|
||||||
|
|
||||||
|
return (sFilterNodeIdsBitVector[index / 8] & (0x80 >> (index % 8))) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
static bool NodeIdFilterIsConnectable(uint16_t aNodeId)
|
static bool NodeIdFilterIsConnectable(uint16_t aNodeId)
|
||||||
{
|
{
|
||||||
uint16_t index = aNodeId - 1;
|
bool isConnectable = true;
|
||||||
|
|
||||||
return (sDeniedNodeIdsBitVector[index / 8] & (0x80 >> (index % 8))) == 0;
|
switch (sFilterMode)
|
||||||
|
{
|
||||||
|
case kFilterOff:
|
||||||
|
break;
|
||||||
|
case kFilterDenyList:
|
||||||
|
isConnectable = !FilterContainsId(aNodeId);
|
||||||
|
break;
|
||||||
|
case kFilterAllowList:
|
||||||
|
isConnectable = FilterContainsId(aNodeId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isConnectable;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NodeIdFilterDeny(uint16_t aNodeId)
|
static void AddNodeIdToFilter(uint16_t aNodeId)
|
||||||
{
|
{
|
||||||
uint16_t index = aNodeId - 1;
|
uint16_t index = aNodeId - 1;
|
||||||
|
|
||||||
sDeniedNodeIdsBitVector[index / 8] |= 0x80 >> (index % 8);
|
sFilterNodeIdsBitVector[index / 8] |= 0x80 >> (index % 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NodeIdFilterClear(void) { memset(sDeniedNodeIdsBitVector, 0, sizeof(sDeniedNodeIdsBitVector)); }
|
OT_TOOL_WEAK void otCliOutputFormat(const char *aFmt, ...) { OT_UNUSED_VARIABLE(aFmt); }
|
||||||
|
|
||||||
otError ProcessNodeIdFilter(void *aContext, uint8_t aArgsLength, char *aArgs[])
|
otError ProcessNodeIdFilter(void *aContext, uint8_t aArgsLength, char *aArgs[])
|
||||||
{
|
{
|
||||||
OT_UNUSED_VARIABLE(aContext);
|
OT_UNUSED_VARIABLE(aContext);
|
||||||
|
|
||||||
otError error = OT_ERROR_NONE;
|
otError error = OT_ERROR_NONE;
|
||||||
|
bool deny = false;
|
||||||
|
|
||||||
otEXPECT_ACTION(aArgsLength > 0, error = OT_ERROR_INVALID_COMMAND);
|
if (aArgsLength == 0)
|
||||||
|
{
|
||||||
|
switch (sFilterMode)
|
||||||
|
{
|
||||||
|
case kFilterOff:
|
||||||
|
otCliOutputFormat("off");
|
||||||
|
break;
|
||||||
|
case kFilterDenyList:
|
||||||
|
otCliOutputFormat("deny-list");
|
||||||
|
break;
|
||||||
|
case kFilterAllowList:
|
||||||
|
otCliOutputFormat("allow-list");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(aArgs[0], "clear"))
|
for (uint16_t nodeId = 0; nodeId <= MAX_NETWORK_SIZE; nodeId++)
|
||||||
|
{
|
||||||
|
if (FilterContainsId(nodeId))
|
||||||
|
{
|
||||||
|
otCliOutputFormat(" %d", nodeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
otCliOutputFormat("\r\n");
|
||||||
|
}
|
||||||
|
else if (!strcmp(aArgs[0], "clear"))
|
||||||
{
|
{
|
||||||
otEXPECT_ACTION(aArgsLength == 1, error = OT_ERROR_INVALID_ARGS);
|
otEXPECT_ACTION(aArgsLength == 1, error = OT_ERROR_INVALID_ARGS);
|
||||||
|
|
||||||
NodeIdFilterClear();
|
memset(sFilterNodeIdsBitVector, 0, sizeof(sFilterNodeIdsBitVector));
|
||||||
|
sFilterMode = kFilterOff;
|
||||||
}
|
}
|
||||||
else if (!strcmp(aArgs[0], "deny"))
|
else if ((deny = !strcmp(aArgs[0], "deny")) || !strcmp(aArgs[0], "allow"))
|
||||||
{
|
{
|
||||||
uint16_t nodeId;
|
uint16_t nodeId;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
@@ -213,7 +265,10 @@ otError ProcessNodeIdFilter(void *aContext, uint8_t aArgsLength, char *aArgs[])
|
|||||||
otEXPECT_ACTION(*endptr == '\0', error = OT_ERROR_INVALID_ARGS);
|
otEXPECT_ACTION(*endptr == '\0', error = OT_ERROR_INVALID_ARGS);
|
||||||
otEXPECT_ACTION(1 <= nodeId && nodeId <= MAX_NETWORK_SIZE, error = OT_ERROR_INVALID_ARGS);
|
otEXPECT_ACTION(1 <= nodeId && nodeId <= MAX_NETWORK_SIZE, error = OT_ERROR_INVALID_ARGS);
|
||||||
|
|
||||||
NodeIdFilterDeny(nodeId);
|
otEXPECT_ACTION(sFilterMode != (deny ? kFilterAllowList : kFilterDenyList), error = OT_ERROR_INVALID_STATE);
|
||||||
|
|
||||||
|
AddNodeIdToFilter(nodeId);
|
||||||
|
sFilterMode = deny ? kFilterDenyList : kFilterAllowList;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -723,6 +723,18 @@ class Node(object):
|
|||||||
def set_macfilter_lqi_to_node(self, node, lqi):
|
def set_macfilter_lqi_to_node(self, node, lqi):
|
||||||
self._cli_no_output('macfilter rss add-lqi', node.get_ext_addr(), lqi)
|
self._cli_no_output('macfilter rss add-lqi', node.get_ext_addr(), lqi)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------------------------------------------
|
||||||
|
# Radio nodeidfilter
|
||||||
|
|
||||||
|
def nodeidfilter_clear(self, node):
|
||||||
|
self._cli_no_output('nodeidfilter clear')
|
||||||
|
|
||||||
|
def nodeidfilter_allow(self, node):
|
||||||
|
self._cli_no_output('nodeidfilter allow', node.index)
|
||||||
|
|
||||||
|
def nodeidfilter_deny(self, node):
|
||||||
|
self._cli_no_output('nodeidfilter deny', node.index)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------------------------------------------
|
||||||
# Parsing helpers
|
# Parsing helpers
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user