Skip to content

Commit

Permalink
net: openthread: rpc: add DNS client test commands to shell
Browse files Browse the repository at this point in the history
Add new 'ot test_*' commands for DNS client.

Signed-off-by: Konrad Derda <[email protected]>
  • Loading branch information
kderda committed Oct 14, 2024
1 parent 35844b4 commit 0d70f10
Showing 1 changed file with 267 additions and 0 deletions.
267 changes: 267 additions & 0 deletions samples/nrf_rpc/protocols_serialization/client/src/ot_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <openthread/udp.h>
#include <openthread/netdata.h>
#include <openthread/message.h>
#include <openthread/dns_client.h>

#include <string.h>

Expand Down Expand Up @@ -738,6 +739,253 @@ static int cmd_ot(const struct shell *sh, size_t argc, char *argv[])
return ot_cli_command_send(sh, argc, argv);
}

static int cmd_dns_client_config_get(const struct shell *sh, size_t argc, char *argv[])
{
const otDnsQueryConfig *config;
struct in6_addr in6_addr;
char addr_string[NET_IPV6_ADDR_LEN];

config = otDnsClientGetDefaultConfig(NULL);

memcpy(in6_addr.s6_addr, config->mServerSockAddr.mAddress.mFields.m8, OT_IP6_ADDRESS_SIZE);

if (!net_addr_ntop(AF_INET6, &in6_addr, addr_string, sizeof(addr_string))) {
shell_error(sh, "Failed to convert the IPv6 address");

return 0;
}

shell_print(sh, "Address: [%s]:%u", addr_string, config->mServerSockAddr.mPort);
shell_print(sh, "Response timeout: %u", config->mResponseTimeout);
shell_print(sh, "Max attempts: %u", config->mMaxTxAttempts);
shell_print(sh, "Recursion flag: %u", config->mRecursionFlag);
shell_print(sh, "NAT64 mode: %u", config->mNat64Mode);
shell_print(sh, "Service mode: %u", config->mServiceMode);
shell_print(sh, "Transport protocol: %u", config->mTransportProto);

return 0;
}

static int cmd_dns_client_config_set(const struct shell *sh, size_t argc, char *argv[])
{
struct in6_addr in6_addr;
otDnsQueryConfig config;
unsigned long port;
unsigned long timeout;
unsigned long attempts;
unsigned long recursion;
unsigned long nat_mode;
unsigned long service_mode;
unsigned long transport;
int err = 0;

if (net_addr_pton(AF_INET6, argv[1], &in6_addr)) {
shell_error(sh, "Invalid address");
return 0;
}

port = shell_strtoul(argv[2], 0, &err);
timeout = shell_strtoul(argv[3], 0, &err);
attempts = shell_strtoul(argv[4], 0, &err);
recursion = shell_strtoul(argv[5], 0, &err);
nat_mode = shell_strtoul(argv[6], 0, &err);
service_mode = shell_strtoul(argv[7], 0, &err);
transport = shell_strtoul(argv[8], 0, &err);

memcpy(config.mServerSockAddr.mAddress.mFields.m8, in6_addr.s6_addr, OT_IP6_ADDRESS_SIZE);

config.mServerSockAddr.mPort = (uint16_t)port;
config.mResponseTimeout = (uint32_t)timeout;
config.mMaxTxAttempts = (uint32_t)attempts;
config.mRecursionFlag = (otDnsRecursionFlag)recursion;
config.mNat64Mode = (otDnsNat64Mode)nat_mode;
config.mServiceMode = (otDnsServiceMode)service_mode;
config.mTransportProto = (otDnsTransportProto)transport;

otDnsClientSetDefaultConfig(NULL, &config);

return 0;
}

static void dns_resolve_cb(otError error, const otDnsAddressResponse *response, void *context)
{
const struct shell *sh = (const struct shell *)context;
char hostname[128];
otError getter_err;
uint16_t index = 0;
otIp6Address address;
uint32_t ttl;
char addr_string[NET_IPV6_ADDR_LEN];

shell_print(sh, "DNS resolve callback error: %u", error);

if (error == OT_ERROR_NONE) {
getter_err = otDnsAddressResponseGetHostName(response, hostname, sizeof(hostname));

if (getter_err == OT_ERROR_NONE) {
shell_print(sh, "Hostname %s", hostname);
} else {
shell_error(sh, "Hostname error: %u", getter_err);
}

while (otDnsAddressResponseGetAddress(response, index++, &address, &ttl) ==
OT_ERROR_NONE) {
if (!net_addr_ntop(AF_INET6, (struct in6_addr *)&address, addr_string,
sizeof(addr_string))) {
shell_error(sh, "Failed to convert the IPv6 address");
return;
}

shell_print(sh, "Address #%u: %s ttl: %u", index, addr_string, ttl);
}
}
}

static int cmd_dns_client_resolve(const struct shell *sh, size_t argc, char *argv[])
{
otError error;
otDnsQueryConfig config;

memcpy(&config, otDnsClientGetDefaultConfig(NULL), sizeof(otDnsQueryConfig));

if (net_addr_pton(AF_INET6, argv[2], (struct in6_addr *)&config.mServerSockAddr.mAddress)) {
shell_error(sh, "Invalid server address");
return 0;
}

if (strcmp(argv[0], "test_dns_client_resolve4") == 0) {
error = otDnsClientResolveIp4Address(NULL, argv[1], dns_resolve_cb, (void *)sh,
&config);
} else {
error = otDnsClientResolveAddress(NULL, argv[1], dns_resolve_cb, (void *)sh,
&config);
}

shell_print(sh, "Resolve requested, err: %u", error);

return 0;
}

static void print_service_info(const struct shell *sh, const otDnsServiceInfo *service_info)
{
char addr[INET6_ADDRSTRLEN];

net_addr_ntop(AF_INET6, (struct in6_addr *)&service_info->mHostAddress, addr, sizeof(addr));

shell_print(sh, "Port:%d, Priority:%d, Weight:%d, TTL:%u", service_info->mPort,
service_info->mPriority, service_info->mWeight, service_info->mTtl);
shell_print(sh, "Host: %s", service_info->mHostNameBuffer);
shell_print(sh, "Address: %s", addr);
shell_print(sh, "Address TTL: %u", service_info->mHostAddressTtl);
shell_print(sh, "TXT:");

shell_hexdump(sh, service_info->mTxtData, service_info->mTxtDataSize);

shell_print(sh, "TXT TTL: %u", service_info->mTxtDataTtl);
}


static void dns_service_cb(otError error, const otDnsServiceResponse *response, void *context)
{
const struct shell *sh = (const struct shell *)context;
char name[OT_DNS_MAX_NAME_SIZE];
char label[OT_DNS_MAX_LABEL_SIZE];
uint8_t txtBuffer[CONFIG_OPENTHREAD_RPC_DNS_MAX_TXT_DATA_SIZE];
otDnsServiceInfo service_info;

otDnsServiceResponseGetServiceName(response, label, sizeof(label), name, sizeof(name));

shell_print(sh, "DNS service resolution response for %s for service %s", label, name);

if (error == OT_ERROR_NONE) {
service_info.mHostNameBuffer = name;
service_info.mHostNameBufferSize = sizeof(name);
service_info.mTxtData = txtBuffer;
service_info.mTxtDataSize = sizeof(txtBuffer);
}

if (otDnsServiceResponseGetServiceInfo(response, &service_info) == OT_ERROR_NONE) {
print_service_info(sh, &service_info);
}
}

static int cmd_dns_client_service(const struct shell *sh, size_t argc, char *argv[])
{
otDnsQueryConfig config;
otError error;

memcpy(&config, otDnsClientGetDefaultConfig(NULL), sizeof(otDnsQueryConfig));

if (net_addr_pton(AF_INET6, argv[3], (struct in6_addr *)&config.mServerSockAddr.mAddress)) {
shell_error(sh, "Invalid server address");
return 0;
}

if (strcmp(argv[0], "test_dns_client_servicehost") == 0) {
error = otDnsClientResolveService(NULL, argv[1], argv[2], dns_service_cb,
(void *)sh, &config);
} else {
error = otDnsClientResolveServiceAndHostAddress(NULL, argv[1], argv[2],
dns_service_cb, (void *)sh,
&config);
}

shell_print(sh, "Service resolve requested, err: %u", error);

return 0;
}

static void dns_browse_cb(otError error, const otDnsBrowseResponse *response, void *context)
{
const struct shell *sh = (const struct shell *)context;
char name[OT_DNS_MAX_NAME_SIZE];
char label[OT_DNS_MAX_LABEL_SIZE];
uint8_t txtBuffer[CONFIG_OPENTHREAD_RPC_DNS_MAX_TXT_DATA_SIZE];
otDnsServiceInfo info;

otDnsBrowseResponseGetServiceName(response, name, sizeof(name));

shell_print(sh, "DNS browse response for: %s", name);

if (error == OT_ERROR_NONE) {
uint16_t index = 0;

while (otDnsBrowseResponseGetServiceInstance(response, index++, label,
sizeof(label)) == OT_ERROR_NONE) {
shell_print(sh, "%s", label);

info.mHostNameBuffer = name;
info.mHostNameBufferSize = sizeof(name);
info.mTxtData = txtBuffer;
info.mTxtDataSize = sizeof(txtBuffer);

if (otDnsBrowseResponseGetServiceInfo(response, label, &info) ==
OT_ERROR_NONE) {
print_service_info(sh, &info);
}
}
}
}

static int cmd_dns_client_browse(const struct shell *sh, size_t argc, char *argv[])
{
otDnsQueryConfig config;
otError error;

memcpy(&config, otDnsClientGetDefaultConfig(NULL), sizeof(otDnsQueryConfig));

if (net_addr_pton(AF_INET6, argv[2], (struct in6_addr *)&config.mServerSockAddr.mAddress)) {
shell_error(sh, "Invalid server address");
return 0;
}

error = otDnsClientBrowse(NULL, argv[1], dns_browse_cb, (void *)sh, &config);

shell_print(sh, "Browse requested, err: %u", error);

return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(
ot_cmds, SHELL_CMD_ARG(ifconfig, NULL, "Interface management", cmd_ifconfig, 1, 1),
SHELL_CMD_ARG(ipmaddr, NULL, "IPv6 multicast configuration", cmd_ipmaddr, 1, 2),
Expand All @@ -758,6 +1006,25 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
SHELL_CMD_ARG(test_coap_send, NULL, "Test CoAP send API", cmd_test_coap_send, 3, 0),
SHELL_CMD_ARG(test_coap_start, NULL, "Test CoAP start API", cmd_test_coap_start, 1, 0),
SHELL_CMD_ARG(test_coap_stop, NULL, "Test CoAP stop API", cmd_test_coap_stop, 1, 0),
SHELL_CMD_ARG(test_dns_client_config_get, NULL, "Get default config",
cmd_dns_client_config_get, 1, 0),
SHELL_CMD_ARG(test_dns_client_config_set, NULL,
"Set default config, args:\n"
"\t<address> <port> <timeout> <attempts> <recursion>"
" <nat mode> <service_mode> <transport>",
cmd_dns_client_config_set, 3, 6),
SHELL_CMD_ARG(test_dns_client_resolve, NULL, "Resolve IPv6 address, args: <name> <server>",
cmd_dns_client_resolve, 3, 0),
SHELL_CMD_ARG(test_dns_client_resolve4, NULL, "Resolve IPv4 address, args: <name> <server>",
cmd_dns_client_resolve, 3, 0),
SHELL_CMD_ARG(test_dns_client_service, NULL, "Service instance resolution, args: <instance>"
"<service> <server>",
cmd_dns_client_service, 4, 0),
SHELL_CMD_ARG(test_dns_client_servicehost, NULL, "Service instance resolution, args:"
" <instance> <service> <server>",
cmd_dns_client_service, 4, 0),
SHELL_CMD_ARG(test_dns_client_browse, NULL, "Service browsing, args <service> <server>",
cmd_dns_client_browse, 3, 0),
SHELL_SUBCMD_SET_END);

SHELL_CMD_ARG_REGISTER(ot, &ot_cmds,
Expand Down

0 comments on commit 0d70f10

Please sign in to comment.