From 688867a9c58bb01588d469a2175be8d9a049f66b Mon Sep 17 00:00:00 2001 From: lezhan Date: Fri, 12 Apr 2024 07:10:18 +0000 Subject: [PATCH] [cli] Update command "br scan" to allow network interface selection for mDNS binding. Within the OTBR practice application, the BR host will have several interfaces. When users want to discover the border router using mDNS, they will need to choose the specific interface. This change introduces a new option for the CLI command `br scan`. User can now specify a network interface using the syntax `br scan --netif . The chosen interface will be used for mDNS binding through socket options. --- include/commissioner/error.hpp | 5 +++++ src/app/cli/interpreter.cpp | 20 +++++++++++--------- src/common/error.cpp | 2 ++ src/common/error_macros.hpp | 5 +++++ 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/include/commissioner/error.hpp b/include/commissioner/error.hpp index 5771eed5..73addf42 100644 --- a/include/commissioner/error.hpp +++ b/include/commissioner/error.hpp @@ -161,6 +161,11 @@ enum class ErrorCode : int * The error is out of the address space of OT Commissioner. */ kUnknown = 19, + + /** + * The error occurs when attempting to bind a network interface to an mDNS socket." + */ + kSocketBindError = 20, }; /** diff --git a/src/app/cli/interpreter.cpp b/src/app/cli/interpreter.cpp index f39441aa..b2be1079 100644 --- a/src/app/cli/interpreter.cpp +++ b/src/app/cli/interpreter.cpp @@ -1433,28 +1433,30 @@ Interpreter::Value Interpreter::ProcessBr(const Expression &aExpr) nlohmann::json baJson; char mdnsSendBuffer[kMdnsBufferSize]; - if (mContext.mCommandKeys.size() == 2 && mContext.mCommandKeys[0] == "--timeout") - { + auto it = std::find(mContext.mCommandKeys.begin(), mContext.mCommandKeys.end(), "--timeout"); + + if (it != mContext.mCommandKeys.end()) { try { - scanTimeout = stol(mContext.mCommandKeys[1]); + scanTimeout = stol(mContext.mCommandKeys[std::distance(mContext.mCommandKeys.begin(), it) + 1]); } catch (...) { - ExitNow(value = ERROR_INVALID_ARGS("Imparsable timeout value '{}'", aExpr[3])); + ExitNow(value = ERROR_INVALID_ARGS("Imparsable timeout value '{}'", mContext.mCommandKeys[std::distance(mContext.mCommandKeys.begin(), it)])); } } - if (mContext.mCommandKeys.size() == 2 && mContext.mCommandKeys[0] == "--netif") - { - netIf = mContext.mCommandKeys[1]; + it = std::find(mContext.mCommandKeys.begin(), mContext.mCommandKeys.end(), "--netif"); + + if (it != mContext.mCommandKeys.end()) { + netIf = mContext.mCommandKeys[std::distance(mContext.mCommandKeys.begin(), it) + 1]; } // Open IPv4 mDNS socket mdnsSocket = mdns_socket_open_ipv4(); VerifyOrExit(mdnsSocket >= 0, value = ERROR_IO_ERROR("failed to open mDNS IPv4 socket")); - if (netIf != "" && setsockopt(mdnsSocket, SOL_SOCKET, SO_BINDTODEVICE, &netIf[0], sizeof(netIf)) < 0) { - ExitNow(value = ERROR_IO_ERROR("failed to bind network interface: {}", netIf)); + if (!netIf.empty() && setsockopt(mdnsSocket, SOL_SOCKET, SO_BINDTODEVICE, netIf.c_str(), netIf.size()) < 0) { + ExitNow(value = ERROR_SOCKET_BIND_ERROR("failed to bind network interface: {}", netIf)); } fdgMdnsSocket.mFD = mdnsSocket; diff --git a/src/common/error.cpp b/src/common/error.cpp index 37c0f6ac..69dd98e0 100644 --- a/src/common/error.cpp +++ b/src/common/error.cpp @@ -86,6 +86,8 @@ static std::string ErrorCodeToString(ErrorCode code) return "REGISTRY_ERROR"; case ErrorCode::kUnknown: return "UNKNOWN"; + case ErrorCode::kSocketBindError: + return "SOCKET_BIND_ERROR"; default: VerifyOrDie(false); diff --git a/src/common/error_macros.hpp b/src/common/error_macros.hpp index 9eea79ec..ebd16d84 100644 --- a/src/common/error_macros.hpp +++ b/src/common/error_macros.hpp @@ -137,5 +137,10 @@ { \ ErrorCode::kUnknown, fmt::format(FMT_STRING((aFormat)), ##__VA_ARGS__) \ } +#define ERROR_SOCKET_BIND_ERROR(aFormat, ...) \ + Error \ + { \ + ErrorCode::kSocketBindError, fmt::format(FMT_STRING((aFormat)), ##__VA_ARGS__) \ + } #endif // ERROR_MACROS_HPP_