Skip to content

Commit

Permalink
[cli] update borderagent discover to allow network interface select…
Browse files Browse the repository at this point in the history
…ion for mDNS binding (#259)

Within the OTBR practice application, the BR host will have several
interfaces. When users want to discover the border agent using mDNS,
they'll need to choose the specific interface the border agent is
bound to.

This change introduces a new option for the CLI command `borderagent
dicover`. Users can now specify a network interface using the syntax
`borderagent discover <timeout> <network interface>`. The chosen
interface will be used for mDNS binding through socket options.
  • Loading branch information
ZhangLe2016 authored Apr 29, 2024
1 parent 4543bd1 commit 3d33a42
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 9 deletions.
4 changes: 2 additions & 2 deletions src/app/border_agent_functions_mock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ void ClearBorderAgentFunctionsMock()
gBorderAgentFunctionsMock = nullptr;
}

Error DiscoverBorderAgent(BorderAgentHandler aBorderAgentHandler, size_t aTimeout)
Error DiscoverBorderAgent(BorderAgentHandler aBorderAgentHandler, size_t aTimeout, const std::string &aNetIf)
{
return gBorderAgentFunctionsMock->DiscoverBorderAgent(aBorderAgentHandler, aTimeout);
return gBorderAgentFunctionsMock->DiscoverBorderAgent(aBorderAgentHandler, aTimeout, aNetIf);
}

} // namespace commissioner
Expand Down
2 changes: 1 addition & 1 deletion src/app/border_agent_functions_mock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class BorderAgentFunctionsMock
public:
virtual ~BorderAgentFunctionsMock() = default;

MOCK_METHOD(Error, DiscoverBorderAgent, (BorderAgentHandler, size_t));
MOCK_METHOD(Error, DiscoverBorderAgent, (BorderAgentHandler, size_t, const std::string &));
};

void SetBorderAgentFunctionsMock(ot::commissioner::BorderAgentFunctionsMock *ptr);
Expand Down
19 changes: 18 additions & 1 deletion src/app/br_discover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
#include "br_discover.hpp"

#include <chrono>
#ifdef __linux__
#include <sys/socket.h>
#else // __NetBSD__ || __FreeBSD__ || __APPLE__
#include <netinet/in.h>
#endif
#include <thread>

#include "common/error_macros.hpp"
Expand All @@ -38,20 +43,32 @@ namespace ot {

namespace commissioner {

Error DiscoverBorderAgent(BorderAgentHandler aBorderAgentHandler, size_t aTimeout)
Error DiscoverBorderAgent(BorderAgentHandler aBorderAgentHandler, size_t aTimeout, const std::string &aNetIf)
{
static constexpr size_t kDefaultBufferSize = 1024 * 16;
static constexpr mdns_record_type_t kMdnsQueryType = MDNS_RECORDTYPE_PTR;
static const char *kServiceName = "_meshcop._udp.local";

Error error;
uint8_t buf[kDefaultBufferSize];
int rval = 0;

auto begin = std::chrono::system_clock::now();

int socket = mdns_socket_open_ipv4();
VerifyOrExit(socket >= 0, error = ERROR_IO_ERROR("failed to open mDNS IPv4 socket"));

if (!aNetIf.empty())
{
#ifdef __linux__
rval = setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, aNetIf.c_str(), aNetIf.size());
#else // __NetBSD__ || __FreeBSD__ || __APPLE__
rval = setsockopt(socket, IPPROTO_IPV6, IP_BOUND_IF, aNetIf.c_str(), aNetIf.size());
#endif // __linux__
VerifyOrExit(rval == 0,
error = ERROR_INVALID_ARGS("failed to bind network interface {}: {}", aNetIf, strerror(errno)));
}

if (mdns_query_send(socket, kMdnsQueryType, kServiceName, strlen(kServiceName), buf, sizeof(buf)) != 0)
{
ExitNow(error = ERROR_IO_ERROR("failed to send mDNS query"));
Expand Down
4 changes: 3 additions & 1 deletion src/app/br_discover.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@ using BorderAgentHandler = std::function<void(const BorderAgent *aBorderAgent, c
* @param[in] aBorderAgentHandler The handler of a single Border Agent response.
* @param[in] aTimeout The time to wait for mDNS responses. Any
* response not within the interval is ignored.
* @param[in] aNetIf The specified network interface for mDNS binding. Can be an empty string
*
*
*/
Error DiscoverBorderAgent(BorderAgentHandler aBorderAgentHandler, size_t aTimeout);
Error DiscoverBorderAgent(BorderAgentHandler aBorderAgentHandler, size_t aTimeout, const std::string &aNetIf);

} // namespace commissioner

Expand Down
2 changes: 1 addition & 1 deletion src/app/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ The command `borderagent` provides access to Border Agent information and scans
```shell
> help borderagent
usage:
borderagent discover [<timeout-in-milliseconds>]
borderagent discover [<timeout-in-milliseconds>] [<specified-network-interface>]
borderagent get locator
[done]
>
Expand Down
10 changes: 8 additions & 2 deletions src/app/cli/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1813,14 +1813,20 @@ Interpreter::Value Interpreter::ProcessBorderAgent(const Expression &aExpr)

if (CaseInsensitiveEqual(aExpr[1], "discover"))
{
uint64_t timeout = 4000;
uint64_t timeout = 4000;
std::string netIf = "";

if (aExpr.size() >= 3)
{
SuccessOrExit(value = ParseInteger(timeout, aExpr[2]));
}

SuccessOrExit(value = DiscoverBorderAgent(BorderAgentHandler, static_cast<size_t>(timeout)));
if (aExpr.size() == 4)
{
netIf = aExpr[3];
}

SuccessOrExit(value = DiscoverBorderAgent(BorderAgentHandler, static_cast<size_t>(timeout), netIf));
}
else if (CaseInsensitiveEqual(aExpr[1], "get"))
{
Expand Down
2 changes: 1 addition & 1 deletion src/app/cli/interpreter_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1629,7 +1629,7 @@ TEST_F(InterpreterTestSuite, PC_BorderagentDiscover)
BorderAgentFunctionsMock bafm;
SetBorderAgentFunctionsMock(&bafm);

EXPECT_CALL(bafm, DiscoverBorderAgent(_, _)).WillOnce(Return(Error{}));
EXPECT_CALL(bafm, DiscoverBorderAgent(_, _, _)).WillOnce(Return(Error{}));

Interpreter::Expression expr;
Interpreter::Value value;
Expand Down

0 comments on commit 3d33a42

Please sign in to comment.