diff --git a/src/cli/BUILD.gn b/src/cli/BUILD.gn index 01be88e16..db116c58f 100644 --- a/src/cli/BUILD.gn +++ b/src/cli/BUILD.gn @@ -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", diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt index 2768689b8..a94d3e0f6 100644 --- a/src/cli/CMakeLists.txt +++ b/src/cli/CMakeLists.txt @@ -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 diff --git a/src/cli/Makefile.am b/src/cli/Makefile.am index e5d006288..f17f54427 100644 --- a/src/cli/Makefile.am +++ b/src/cli/Makefile.am @@ -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 \ diff --git a/src/cli/README.md b/src/cli/README.md index 1f51c47d1..15a638459 100644 --- a/src/cli/README.md +++ b/src/cli/README.md @@ -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 ``` diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 5e27f1334..af5bc6a5c 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -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(Arg aArgs[]) #endif #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE -template <> otError Interpreter::Process(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(Arg aArgs[]) { return mMacFilter.Process(aArgs); } +#endif template <> otError Interpreter::Process(Arg aArgs[]) { diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp index 2f78fdafa..26c261447 100644 --- a/src/cli/cli.hpp +++ b/src/cli/cli.hpp @@ -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 diff --git a/src/cli/cli_mac_filter.cpp b/src/cli/cli_mac_filter.cpp new file mode 100644 index 000000000..6525a20aa --- /dev/null +++ b/src/cli/cli_mac_filter.cpp @@ -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(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(index)); + ExitNow(); + } + } + + error = OT_ERROR_INVALID_COMMAND; + } + +exit: + return error; +} + +template <> otError MacFilter::Process(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 \ + } + + 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 diff --git a/src/cli/cli_mac_filter.hpp b/src/cli/cli_mac_filter.hpp new file mode 100644 index 000000000..da2c8980e --- /dev/null +++ b/src/cli/cli_mac_filter.hpp @@ -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 + +#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; + + template 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_ diff --git a/tests/scripts/expect/cli-macfilter.exp b/tests/scripts/expect/cli-macfilter.exp index 21456b35a..1827a6ed2 100755 --- a/tests/scripts/expect/cli-macfilter.exp +++ b/tests/scripts/expect/cli-macfilter.exp @@ -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"