From a353ca0464faee54a890da0f19af3d789f69cdb3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 22 May 2026 08:11:49 +0000 Subject: [PATCH 1/2] Initial plan From fe10ea4627f47c4281dbf0faa489d8c4faca1d2a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 22 May 2026 08:14:15 +0000 Subject: [PATCH 2/2] Fix XGETADDRINFO iteration address selection --- app/src/sm_at_socket.c | 4 +- app/tests/at_socket/src/test_at_socket.c | 71 ++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/app/src/sm_at_socket.c b/app/src/sm_at_socket.c index e77ebe18..233f24ad 100644 --- a/app/src/sm_at_socket.c +++ b/app/src/sm_at_socket.c @@ -2211,13 +2211,13 @@ STATIC int handle_at_getaddrinfo(enum at_parser_cmd_type cmd_type, struct at_par for (res = result; res != NULL; res = res->ai_next) { if (res->ai_family == NRF_AF_INET) { struct nrf_sockaddr_in *host = - (struct nrf_sockaddr_in *)result->ai_addr; + (struct nrf_sockaddr_in *)res->ai_addr; nrf_inet_ntop(NRF_AF_INET, &host->sin_addr, hostname, sizeof(hostname)); } else if (res->ai_family == NRF_AF_INET6) { struct nrf_sockaddr_in6 *host = - (struct nrf_sockaddr_in6 *)result->ai_addr; + (struct nrf_sockaddr_in6 *)res->ai_addr; nrf_inet_ntop(NRF_AF_INET6, &host->sin6_addr, hostname, sizeof(hostname)); diff --git a/app/tests/at_socket/src/test_at_socket.c b/app/tests/at_socket/src/test_at_socket.c index b1658865..941423d2 100644 --- a/app/tests/at_socket/src/test_at_socket.c +++ b/app/tests/at_socket/src/test_at_socket.c @@ -2544,6 +2544,21 @@ static const char *mock_nrf_inet_ntop_ipv6_callback(int af, const void *src, cha return dst; } +/* Helper callback for mocking nrf_inet_ntop with multiple IPv4 addresses */ +static const char *mock_nrf_inet_ntop_ipv4_multi_callback(int af, const void *src, char *dst, + nrf_socklen_t size, int num_calls) +{ + const struct nrf_in_addr *addr = src; + + if (af == NRF_AF_INET && addr->s_addr == net_htonl(0xC0A80001)) { + strcpy(dst, "192.168.0.1"); + } else if (af == NRF_AF_INET && addr->s_addr == net_htonl(0x0A000002)) { + strcpy(dst, "10.0.0.2"); + } + + return dst; +} + /* Helper callback for mocking successful nrf_getaddrinfo (IPv4) */ static int mock_nrf_getaddrinfo_ipv4_callback(const char *nodename, const char *servname, const struct nrf_addrinfo *hints, @@ -2571,6 +2586,41 @@ static int mock_nrf_getaddrinfo_ipv4_callback(const char *nodename, const char * return 0; } +/* Helper callback for mocking successful nrf_getaddrinfo (multiple IPv4 results) */ +static int mock_nrf_getaddrinfo_ipv4_multi_callback(const char *nodename, const char *servname, + const struct nrf_addrinfo *hints, + struct nrf_addrinfo **res, int num_calls) +{ + static struct { + struct nrf_addrinfo ai[2]; + struct nrf_sockaddr_in sa[2]; + } result; + + memset(&result, 0, sizeof(result)); + + result.sa[0].sin_family = NRF_AF_INET; + result.sa[0].sin_addr.s_addr = net_htonl(0xC0A80001); /* 192.168.0.1 */ + result.sa[1].sin_family = NRF_AF_INET; + result.sa[1].sin_addr.s_addr = net_htonl(0x0A000002); /* 10.0.0.2 */ + + result.ai[0].ai_family = NRF_AF_INET; + result.ai[0].ai_socktype = NRF_SOCK_STREAM; + result.ai[0].ai_protocol = NRF_IPPROTO_TCP; + result.ai[0].ai_addrlen = sizeof(result.sa[0]); + result.ai[0].ai_addr = (struct nrf_sockaddr *)&result.sa[0]; + result.ai[0].ai_next = &result.ai[1]; + + result.ai[1].ai_family = NRF_AF_INET; + result.ai[1].ai_socktype = NRF_SOCK_STREAM; + result.ai[1].ai_protocol = NRF_IPPROTO_TCP; + result.ai[1].ai_addrlen = sizeof(result.sa[1]); + result.ai[1].ai_addr = (struct nrf_sockaddr *)&result.sa[1]; + result.ai[1].ai_next = NULL; + + *res = &result.ai[0]; + return 0; +} + /* Helper callback for mocking successful nrf_getaddrinfo (IPv6) */ static int mock_nrf_getaddrinfo_ipv6_callback(const char *nodename, const char *servname, const struct nrf_addrinfo *hints, @@ -2626,6 +2676,27 @@ void test_xgetaddrinfo_ipv4(void) TEST_ASSERT_TRUE(strstr(response, "OK") != NULL); } +/* + * Test: Resolve hostname via AT#XGETADDRINFO command with multiple IPv4 results + * - Command: AT#XGETADDRINFO="hostname" + * - Tests: Iteration uses each addrinfo entry address + */ +void test_xgetaddrinfo_ipv4_multiple_results(void) +{ + const char *response; + + __cmock_nrf_getaddrinfo_Stub(mock_nrf_getaddrinfo_ipv4_multi_callback); + __cmock_nrf_inet_ntop_Stub(mock_nrf_inet_ntop_ipv4_multi_callback); + __cmock_nrf_freeaddrinfo_Expect(NULL); + __cmock_nrf_freeaddrinfo_IgnoreArg_ai(); + + send_at_command("AT#XGETADDRINFO=\"example.com\"\r\n"); + + response = get_captured_response(); + TEST_ASSERT_TRUE(strstr(response, "#XGETADDRINFO: \"192.168.0.1 10.0.0.2\"") != NULL); + TEST_ASSERT_TRUE(strstr(response, "OK") != NULL); +} + /* * Test: Resolve hostname via AT#XGETADDRINFO command (IPv6) * - Command: AT#XGETADDRINFO="hostname",2