mirror of
https://github.com/espressif/openthread.git
synced 2026-07-28 14:47:46 +00:00
[cli] add CLI MacFilter sub-module (#9088)
This commit adds `MacFilter` CLI sub-module that implements all "macfilter" sub-commands. It also simplifies the implementation by adding a common `OutputFilter()` method that can output either the Address filter, the RSS filter, or both.
This commit is contained in:
@@ -47,6 +47,8 @@ openthread_cli_sources = [
|
||||
"cli_history.hpp",
|
||||
"cli_joiner.cpp",
|
||||
"cli_joiner.hpp",
|
||||
"cli_mac_filter.cpp",
|
||||
"cli_mac_filter.hpp",
|
||||
"cli_network_data.cpp",
|
||||
"cli_network_data.hpp",
|
||||
"cli_output.cpp",
|
||||
|
||||
@@ -41,6 +41,7 @@ set(COMMON_SOURCES
|
||||
cli_dns.cpp
|
||||
cli_history.cpp
|
||||
cli_joiner.cpp
|
||||
cli_mac_filter.cpp
|
||||
cli_network_data.cpp
|
||||
cli_output.cpp
|
||||
cli_srp_client.cpp
|
||||
|
||||
@@ -161,6 +161,7 @@ SOURCES_COMMON = \
|
||||
cli_dns.cpp \
|
||||
cli_history.cpp \
|
||||
cli_joiner.cpp \
|
||||
cli_mac_filter.cpp \
|
||||
cli_network_data.cpp \
|
||||
cli_output.cpp \
|
||||
cli_srp_client.cpp \
|
||||
@@ -193,6 +194,7 @@ noinst_HEADERS = \
|
||||
cli_dns.hpp \
|
||||
cli_history.hpp \
|
||||
cli_joiner.hpp \
|
||||
cli_mac_filter.hpp \
|
||||
cli_network_data.hpp \
|
||||
cli_output.hpp \
|
||||
cli_srp_client.hpp \
|
||||
|
||||
+1
-1
@@ -3551,7 +3551,7 @@ Address Mode: Allowlist
|
||||
0f6127e33af6b402
|
||||
RssIn List:
|
||||
0f6127e33af6b403 : rss -95 (lqi 1)
|
||||
Default rss : -50 (lqi 3)
|
||||
Default rss: -50 (lqi 3)
|
||||
Done
|
||||
```
|
||||
|
||||
|
||||
+5
-247
@@ -109,6 +109,9 @@ Interpreter::Interpreter(Instance *aInstance, otCliOutputCallback aCallback, voi
|
||||
, mDataset(aInstance, *this)
|
||||
, mNetworkData(aInstance, *this)
|
||||
, mUdp(aInstance, *this)
|
||||
#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
|
||||
, mMacFilter(aInstance, *this)
|
||||
#endif
|
||||
#if OPENTHREAD_CLI_DNS_ENABLE
|
||||
, mDns(aInstance, *this)
|
||||
#endif
|
||||
@@ -7081,253 +7084,8 @@ template <> otError Interpreter::Process<Cmd("joinerport")>(Arg aArgs[])
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
|
||||
template <> otError Interpreter::Process<Cmd("macfilter")>(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
if (aArgs[0].IsEmpty())
|
||||
{
|
||||
PrintMacFilter();
|
||||
}
|
||||
else if (aArgs[0] == "addr")
|
||||
{
|
||||
error = ProcessMacFilterAddress(aArgs + 1);
|
||||
}
|
||||
else if (aArgs[0] == "rss")
|
||||
{
|
||||
error = ProcessMacFilterRss(aArgs + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = OT_ERROR_INVALID_COMMAND;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void Interpreter::PrintMacFilter(void)
|
||||
{
|
||||
otMacFilterEntry entry;
|
||||
otMacFilterIterator iterator = OT_MAC_FILTER_ITERATOR_INIT;
|
||||
|
||||
OutputLine("Address Mode: %s", MacFilterAddressModeToString(otLinkFilterGetAddressMode(GetInstancePtr())));
|
||||
|
||||
while (otLinkFilterGetNextAddress(GetInstancePtr(), &iterator, &entry) == OT_ERROR_NONE)
|
||||
{
|
||||
OutputMacFilterEntry(entry);
|
||||
}
|
||||
|
||||
iterator = OT_MAC_FILTER_ITERATOR_INIT;
|
||||
OutputLine("RssIn List:");
|
||||
|
||||
while (otLinkFilterGetNextRssIn(GetInstancePtr(), &iterator, &entry) == OT_ERROR_NONE)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
for (; i < OT_EXT_ADDRESS_SIZE; i++)
|
||||
{
|
||||
if (entry.mExtAddress.m8[i] != 0xff)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == OT_EXT_ADDRESS_SIZE)
|
||||
{
|
||||
OutputLine("Default rss : %d (lqi %u)", entry.mRssIn,
|
||||
otLinkConvertRssToLinkQuality(GetInstancePtr(), entry.mRssIn));
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputMacFilterEntry(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
otError Interpreter::ProcessMacFilterAddress(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otExtAddress extAddr;
|
||||
|
||||
if (aArgs[0].IsEmpty())
|
||||
{
|
||||
otMacFilterIterator iterator = OT_MAC_FILTER_ITERATOR_INIT;
|
||||
otMacFilterEntry entry;
|
||||
|
||||
OutputLine("%s", MacFilterAddressModeToString(otLinkFilterGetAddressMode(GetInstancePtr())));
|
||||
|
||||
while (otLinkFilterGetNextAddress(GetInstancePtr(), &iterator, &entry) == OT_ERROR_NONE)
|
||||
{
|
||||
OutputMacFilterEntry(entry);
|
||||
}
|
||||
}
|
||||
else if (aArgs[0] == "disable")
|
||||
{
|
||||
VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
otLinkFilterSetAddressMode(GetInstancePtr(), OT_MAC_FILTER_ADDRESS_MODE_DISABLED);
|
||||
}
|
||||
else if (aArgs[0] == "allowlist")
|
||||
{
|
||||
VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
otLinkFilterSetAddressMode(GetInstancePtr(), OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST);
|
||||
}
|
||||
else if (aArgs[0] == "denylist")
|
||||
{
|
||||
VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
otLinkFilterSetAddressMode(GetInstancePtr(), OT_MAC_FILTER_ADDRESS_MODE_DENYLIST);
|
||||
}
|
||||
else if (aArgs[0] == "add")
|
||||
{
|
||||
SuccessOrExit(error = aArgs[1].ParseAsHexString(extAddr.m8));
|
||||
error = otLinkFilterAddAddress(GetInstancePtr(), &extAddr);
|
||||
|
||||
VerifyOrExit(error == OT_ERROR_NONE || error == OT_ERROR_ALREADY);
|
||||
|
||||
if (!aArgs[2].IsEmpty())
|
||||
{
|
||||
int8_t rss;
|
||||
|
||||
SuccessOrExit(error = aArgs[2].ParseAsInt8(rss));
|
||||
SuccessOrExit(error = otLinkFilterAddRssIn(GetInstancePtr(), &extAddr, rss));
|
||||
}
|
||||
}
|
||||
else if (aArgs[0] == "remove")
|
||||
{
|
||||
SuccessOrExit(error = aArgs[1].ParseAsHexString(extAddr.m8));
|
||||
otLinkFilterRemoveAddress(GetInstancePtr(), &extAddr);
|
||||
}
|
||||
else if (aArgs[0] == "clear")
|
||||
{
|
||||
otLinkFilterClearAddresses(GetInstancePtr());
|
||||
}
|
||||
else
|
||||
{
|
||||
error = OT_ERROR_INVALID_COMMAND;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Interpreter::ProcessMacFilterRss(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otMacFilterEntry entry;
|
||||
otMacFilterIterator iterator = OT_MAC_FILTER_ITERATOR_INIT;
|
||||
otExtAddress extAddr;
|
||||
int8_t rss;
|
||||
|
||||
if (aArgs[0].IsEmpty())
|
||||
{
|
||||
while (otLinkFilterGetNextRssIn(GetInstancePtr(), &iterator, &entry) == OT_ERROR_NONE)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
for (; i < OT_EXT_ADDRESS_SIZE; i++)
|
||||
{
|
||||
if (entry.mExtAddress.m8[i] != 0xff)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == OT_EXT_ADDRESS_SIZE)
|
||||
{
|
||||
OutputLine("Default rss: %d (lqi %u)", entry.mRssIn,
|
||||
otLinkConvertRssToLinkQuality(GetInstancePtr(), entry.mRssIn));
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputMacFilterEntry(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (aArgs[0] == "add-lqi")
|
||||
{
|
||||
uint8_t linkQuality;
|
||||
|
||||
SuccessOrExit(error = aArgs[2].ParseAsUint8(linkQuality));
|
||||
VerifyOrExit(linkQuality <= 3, error = OT_ERROR_INVALID_ARGS);
|
||||
rss = otLinkConvertLinkQualityToRss(GetInstancePtr(), linkQuality);
|
||||
|
||||
if (aArgs[1] == "*")
|
||||
{
|
||||
otLinkFilterSetDefaultRssIn(GetInstancePtr(), rss);
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = aArgs[1].ParseAsHexString(extAddr.m8));
|
||||
error = otLinkFilterAddRssIn(GetInstancePtr(), &extAddr, rss);
|
||||
}
|
||||
}
|
||||
else if (aArgs[0] == "add")
|
||||
{
|
||||
SuccessOrExit(error = aArgs[2].ParseAsInt8(rss));
|
||||
|
||||
if (aArgs[1] == "*")
|
||||
{
|
||||
otLinkFilterSetDefaultRssIn(GetInstancePtr(), rss);
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = aArgs[1].ParseAsHexString(extAddr.m8));
|
||||
error = otLinkFilterAddRssIn(GetInstancePtr(), &extAddr, rss);
|
||||
}
|
||||
}
|
||||
else if (aArgs[0] == "remove")
|
||||
{
|
||||
if (aArgs[1] == "*")
|
||||
{
|
||||
otLinkFilterClearDefaultRssIn(GetInstancePtr());
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = aArgs[1].ParseAsHexString(extAddr.m8));
|
||||
otLinkFilterRemoveRssIn(GetInstancePtr(), &extAddr);
|
||||
}
|
||||
}
|
||||
else if (aArgs[0] == "clear")
|
||||
{
|
||||
otLinkFilterClearAllRssIn(GetInstancePtr());
|
||||
}
|
||||
else
|
||||
{
|
||||
error = OT_ERROR_INVALID_COMMAND;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Interpreter::OutputMacFilterEntry(const otMacFilterEntry &aEntry)
|
||||
{
|
||||
OutputExtAddress(aEntry.mExtAddress);
|
||||
|
||||
if (aEntry.mRssIn != OT_MAC_FILTER_FIXED_RSS_DISABLED)
|
||||
{
|
||||
OutputFormat(" : rss %d (lqi %d)", aEntry.mRssIn,
|
||||
otLinkConvertRssToLinkQuality(GetInstancePtr(), aEntry.mRssIn));
|
||||
}
|
||||
|
||||
OutputNewLine();
|
||||
}
|
||||
|
||||
const char *Interpreter::MacFilterAddressModeToString(otMacFilterAddressMode aMode)
|
||||
{
|
||||
static const char *const kModeStrings[] = {
|
||||
"Disabled", // (0) OT_MAC_FILTER_ADDRESS_MODE_DISABLED
|
||||
"Allowlist", // (1) OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST
|
||||
"Denylist", // (2) OT_MAC_FILTER_ADDRESS_MODE_DENYLIST
|
||||
};
|
||||
|
||||
static_assert(0 == OT_MAC_FILTER_ADDRESS_MODE_DISABLED, "OT_MAC_FILTER_ADDRESS_MODE_DISABLED value is incorrect");
|
||||
static_assert(1 == OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST, "OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST value is incorrect");
|
||||
static_assert(2 == OT_MAC_FILTER_ADDRESS_MODE_DENYLIST, "OT_MAC_FILTER_ADDRESS_MODE_DENYLIST value is incorrect");
|
||||
|
||||
return Stringify(aMode, kModeStrings);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
|
||||
template <> otError Interpreter::Process<Cmd("macfilter")>(Arg aArgs[]) { return mMacFilter.Process(aArgs); }
|
||||
#endif
|
||||
|
||||
template <> otError Interpreter::Process<Cmd("mac")>(Arg aArgs[])
|
||||
{
|
||||
|
||||
+5
-8
@@ -64,6 +64,7 @@
|
||||
#include "cli/cli_dns.hpp"
|
||||
#include "cli/cli_history.hpp"
|
||||
#include "cli/cli_joiner.hpp"
|
||||
#include "cli/cli_mac_filter.hpp"
|
||||
#include "cli/cli_network_data.hpp"
|
||||
#include "cli/cli_output.hpp"
|
||||
#include "cli/cli_srp_client.hpp"
|
||||
@@ -430,14 +431,6 @@ private:
|
||||
void OutputMultiRadioInfo(const otMultiRadioNeighborInfo &aMultiRadioInfo);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
|
||||
void PrintMacFilter(void);
|
||||
otError ProcessMacFilterAddress(Arg aArgs[]);
|
||||
otError ProcessMacFilterRss(Arg aArgs[]);
|
||||
void OutputMacFilterEntry(const otMacFilterEntry &aEntry);
|
||||
static const char *MacFilterAddressModeToString(otMacFilterAddressMode aMode);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
|
||||
static void HandlePingReply(const otPingSenderReply *aReply, void *aContext);
|
||||
static void HandlePingStatistics(const otPingSenderStatistics *aStatistics, void *aContext);
|
||||
@@ -548,6 +541,10 @@ private:
|
||||
NetworkData mNetworkData;
|
||||
UdpExample mUdp;
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
|
||||
MacFilter mMacFilter;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CLI_DNS_ENABLE
|
||||
Dns mDns;
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (c) 2023, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements CLI for MAC Filter.
|
||||
*/
|
||||
|
||||
#include "cli_mac_filter.hpp"
|
||||
|
||||
#include "cli/cli.hpp"
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
|
||||
|
||||
namespace ot {
|
||||
namespace Cli {
|
||||
|
||||
void MacFilter::OutputFilter(uint8_t aFilters)
|
||||
{
|
||||
otMacFilterEntry entry;
|
||||
otMacFilterIterator iterator;
|
||||
|
||||
if (aFilters & kAddressFilter)
|
||||
{
|
||||
if ((aFilters & ~kAddressFilter) != 0)
|
||||
{
|
||||
OutputFormat("Address Mode: ");
|
||||
}
|
||||
|
||||
OutputLine("%s", AddressModeToString(otLinkFilterGetAddressMode(GetInstancePtr())));
|
||||
|
||||
iterator = OT_MAC_FILTER_ITERATOR_INIT;
|
||||
|
||||
while (otLinkFilterGetNextAddress(GetInstancePtr(), &iterator, &entry) == OT_ERROR_NONE)
|
||||
{
|
||||
OutputEntry(entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (aFilters & kRssFilter)
|
||||
{
|
||||
if ((aFilters & ~kRssFilter) != 0)
|
||||
{
|
||||
OutputLine("RssIn List:");
|
||||
}
|
||||
|
||||
iterator = OT_MAC_FILTER_ITERATOR_INIT;
|
||||
|
||||
while (otLinkFilterGetNextRssIn(GetInstancePtr(), &iterator, &entry) == OT_ERROR_NONE)
|
||||
{
|
||||
if (IsDefaultRss(entry.mExtAddress))
|
||||
{
|
||||
OutputLine("Default rss: %d (lqi %u)", entry.mRssIn,
|
||||
otLinkConvertRssToLinkQuality(GetInstancePtr(), entry.mRssIn));
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputEntry(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MacFilter::IsDefaultRss(const otExtAddress &aExtAddress)
|
||||
{
|
||||
// In default RSS entry, the extended address will be all `0xff`.
|
||||
|
||||
bool isDefault = true;
|
||||
|
||||
for (uint8_t byte : aExtAddress.m8)
|
||||
{
|
||||
if (byte != 0xff)
|
||||
{
|
||||
isDefault = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return isDefault;
|
||||
}
|
||||
|
||||
const char *MacFilter::AddressModeToString(otMacFilterAddressMode aMode)
|
||||
{
|
||||
static const char *const kModeStrings[] = {
|
||||
"Disabled", // (0) OT_MAC_FILTER_ADDRESS_MODE_DISABLED
|
||||
"Allowlist", // (1) OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST
|
||||
"Denylist", // (2) OT_MAC_FILTER_ADDRESS_MODE_DENYLIST
|
||||
};
|
||||
|
||||
static_assert(0 == OT_MAC_FILTER_ADDRESS_MODE_DISABLED, "OT_MAC_FILTER_ADDRESS_MODE_DISABLED value is incorrect");
|
||||
static_assert(1 == OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST, "OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST value is incorrect");
|
||||
static_assert(2 == OT_MAC_FILTER_ADDRESS_MODE_DENYLIST, "OT_MAC_FILTER_ADDRESS_MODE_DENYLIST value is incorrect");
|
||||
|
||||
return Stringify(aMode, kModeStrings);
|
||||
}
|
||||
|
||||
void MacFilter::OutputEntry(const otMacFilterEntry &aEntry)
|
||||
{
|
||||
OutputExtAddress(aEntry.mExtAddress);
|
||||
|
||||
if (aEntry.mRssIn != OT_MAC_FILTER_FIXED_RSS_DISABLED)
|
||||
{
|
||||
OutputFormat(" : rss %d (lqi %d)", aEntry.mRssIn,
|
||||
otLinkConvertRssToLinkQuality(GetInstancePtr(), aEntry.mRssIn));
|
||||
}
|
||||
|
||||
OutputNewLine();
|
||||
}
|
||||
|
||||
template <> otError MacFilter::Process<Cmd("addr")>(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otExtAddress extAddr;
|
||||
|
||||
if (aArgs[0].IsEmpty())
|
||||
{
|
||||
OutputFilter(kAddressFilter);
|
||||
}
|
||||
else if (aArgs[0] == "add")
|
||||
{
|
||||
SuccessOrExit(error = aArgs[1].ParseAsHexString(extAddr.m8));
|
||||
error = otLinkFilterAddAddress(GetInstancePtr(), &extAddr);
|
||||
|
||||
VerifyOrExit(error == OT_ERROR_NONE || error == OT_ERROR_ALREADY);
|
||||
|
||||
if (!aArgs[2].IsEmpty())
|
||||
{
|
||||
int8_t rss;
|
||||
|
||||
SuccessOrExit(error = aArgs[2].ParseAsInt8(rss));
|
||||
SuccessOrExit(error = otLinkFilterAddRssIn(GetInstancePtr(), &extAddr, rss));
|
||||
}
|
||||
}
|
||||
else if (aArgs[0] == "remove")
|
||||
{
|
||||
SuccessOrExit(error = aArgs[1].ParseAsHexString(extAddr.m8));
|
||||
otLinkFilterRemoveAddress(GetInstancePtr(), &extAddr);
|
||||
}
|
||||
else if (aArgs[0] == "clear")
|
||||
{
|
||||
otLinkFilterClearAddresses(GetInstancePtr());
|
||||
}
|
||||
else
|
||||
{
|
||||
static const char *const kModeCommands[] = {
|
||||
"disable", // (0) OT_MAC_FILTER_ADDRESS_MODE_DISABLED
|
||||
"allowlist", // (1) OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST
|
||||
"denylist", // (2) OT_MAC_FILTER_ADDRESS_MODE_DENYLIST
|
||||
};
|
||||
|
||||
for (uint8_t index = 0; index < OT_ARRAY_LENGTH(kModeCommands); index++)
|
||||
{
|
||||
if (aArgs[0] == kModeCommands[index])
|
||||
{
|
||||
VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
otLinkFilterSetAddressMode(GetInstancePtr(), static_cast<otMacFilterAddressMode>(index));
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
error = OT_ERROR_INVALID_COMMAND;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError MacFilter::Process<Cmd("rss")>(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otExtAddress extAddr;
|
||||
int8_t rss;
|
||||
|
||||
if (aArgs[0].IsEmpty())
|
||||
{
|
||||
OutputFilter(kRssFilter);
|
||||
}
|
||||
else if (aArgs[0] == "add-lqi")
|
||||
{
|
||||
uint8_t linkQuality;
|
||||
|
||||
SuccessOrExit(error = aArgs[2].ParseAsUint8(linkQuality));
|
||||
VerifyOrExit(linkQuality <= 3, error = OT_ERROR_INVALID_ARGS);
|
||||
rss = otLinkConvertLinkQualityToRss(GetInstancePtr(), linkQuality);
|
||||
|
||||
if (aArgs[1] == "*")
|
||||
{
|
||||
otLinkFilterSetDefaultRssIn(GetInstancePtr(), rss);
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = aArgs[1].ParseAsHexString(extAddr.m8));
|
||||
error = otLinkFilterAddRssIn(GetInstancePtr(), &extAddr, rss);
|
||||
}
|
||||
}
|
||||
else if (aArgs[0] == "add")
|
||||
{
|
||||
SuccessOrExit(error = aArgs[2].ParseAsInt8(rss));
|
||||
|
||||
if (aArgs[1] == "*")
|
||||
{
|
||||
otLinkFilterSetDefaultRssIn(GetInstancePtr(), rss);
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = aArgs[1].ParseAsHexString(extAddr.m8));
|
||||
error = otLinkFilterAddRssIn(GetInstancePtr(), &extAddr, rss);
|
||||
}
|
||||
}
|
||||
else if (aArgs[0] == "remove")
|
||||
{
|
||||
if (aArgs[1] == "*")
|
||||
{
|
||||
otLinkFilterClearDefaultRssIn(GetInstancePtr());
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = aArgs[1].ParseAsHexString(extAddr.m8));
|
||||
otLinkFilterRemoveRssIn(GetInstancePtr(), &extAddr);
|
||||
}
|
||||
}
|
||||
else if (aArgs[0] == "clear")
|
||||
{
|
||||
otLinkFilterClearAllRssIn(GetInstancePtr());
|
||||
}
|
||||
else
|
||||
{
|
||||
error = OT_ERROR_INVALID_COMMAND;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError MacFilter::Process(Arg aArgs[])
|
||||
{
|
||||
#define CmdEntry(aCommandString) \
|
||||
{ \
|
||||
aCommandString, &MacFilter::Process<Cmd(aCommandString)> \
|
||||
}
|
||||
|
||||
static constexpr Command kCommands[] = {
|
||||
CmdEntry("addr"),
|
||||
CmdEntry("rss"),
|
||||
};
|
||||
|
||||
#undef CmdEntry
|
||||
|
||||
static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted");
|
||||
|
||||
otError error = OT_ERROR_INVALID_COMMAND;
|
||||
const Command *command;
|
||||
|
||||
if (aArgs[0].IsEmpty())
|
||||
{
|
||||
OutputFilter(kAddressFilter | kRssFilter);
|
||||
ExitNow(error = OT_ERROR_NONE);
|
||||
}
|
||||
|
||||
command = BinarySearch::Find(aArgs[0].GetCString(), kCommands);
|
||||
VerifyOrExit(command != nullptr);
|
||||
|
||||
error = (this->*command->mHandler)(aArgs + 1);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace Cli
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2023, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file contains definitions for CLI to MAC Filter.
|
||||
*/
|
||||
|
||||
#ifndef CLI_MAC_FILTER_HPP_
|
||||
#define CLI_MAC_FILTER_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
|
||||
|
||||
#include <openthread/link.h>
|
||||
|
||||
#include "cli/cli_config.h"
|
||||
#include "cli/cli_output.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Cli {
|
||||
|
||||
/**
|
||||
* This class implements the MAC Filter CLI interpreter.
|
||||
*
|
||||
*/
|
||||
class MacFilter : private Output
|
||||
{
|
||||
public:
|
||||
typedef Utils::CmdLineParser::Arg Arg;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread Instance.
|
||||
* @param[in] aOutputImplementer An `OutputImplementer`.
|
||||
*
|
||||
*/
|
||||
MacFilter(otInstance *aInstance, OutputImplementer &aOutputImplementer)
|
||||
: Output(aInstance, aOutputImplementer)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method interprets a list of CLI arguments.
|
||||
*
|
||||
* @param[in] aArgs A pointer an array of command line arguments.
|
||||
*
|
||||
* @reval OT_ERROR_NONE Successfully executed the CLI command.
|
||||
* @retval OT_ERROR_INVALID_COMMAND Invalid or unknown CLI command.
|
||||
* @retavl OT_ERROR_INVALID_ARGS Invalid arguments.
|
||||
* @retval ... Error handling the command.
|
||||
*
|
||||
*/
|
||||
otError Process(Arg aArgs[]);
|
||||
|
||||
private:
|
||||
static constexpr uint8_t kIndentSize = 4;
|
||||
|
||||
using Command = CommandEntry<MacFilter>;
|
||||
|
||||
template <CommandId kCommandId> otError Process(Arg aArgs[]);
|
||||
|
||||
// For use as input to `OutputFilter()`
|
||||
static constexpr uint8_t kAddressFilter = (1U << 0);
|
||||
static constexpr uint8_t kRssFilter = (1U << 1);
|
||||
|
||||
void OutputFilter(uint8_t aFilters);
|
||||
void OutputEntry(const otMacFilterEntry &aEntry);
|
||||
static bool IsDefaultRss(const otExtAddress &aExtAddress);
|
||||
static const char *AddressModeToString(otMacFilterAddressMode aMode);
|
||||
};
|
||||
|
||||
} // namespace Cli
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CLI_DNS_ENABLE
|
||||
|
||||
#endif // CLI_MAC_FILTER_HPP_
|
||||
@@ -114,7 +114,7 @@ send "macfilter\n"
|
||||
expect "Address Mode: Disabled"
|
||||
expect "RssIn List:"
|
||||
expect -re {aabbccddeeff0011 : rss -?\d+ \(lqi 3\)}
|
||||
expect -re {Default rss : -?\d+ \(lqi 2\)}
|
||||
expect -re {Default rss: -?\d+ \(lqi 2\)}
|
||||
expect_line "Done"
|
||||
|
||||
send "macfilter rss remove *\n"
|
||||
|
||||
Reference in New Issue
Block a user