drivers: wifi: simplelink: reimplement getaddrinfo
Reimplement getaddrinfo to call SlNetUtil_getAddrInfo from the TI HAL for a more robust implementation that supports both client and server modes, and performs better error-checking. Fixes #11890 Signed-off-by: Vincent Wan <vwan@ti.com>
This commit is contained in:
parent
eb2a705497
commit
23b54832f8
2 changed files with 145 additions and 76 deletions
|
@ -18,6 +18,8 @@ LOG_MODULE_DECLARE(LOG_MODULE_NAME);
|
|||
#include <errno.h>
|
||||
#include <ti/drivers/net/wifi/simplelink.h>
|
||||
#include <ti/drivers/net/wifi/source/driver.h>
|
||||
#include <ti/net/slnetutils.h>
|
||||
#include <ti/net/slnetif.h>
|
||||
#include "simplelink_support.h"
|
||||
|
||||
#include "sockets_internal.h"
|
||||
|
@ -37,9 +39,6 @@ LOG_MODULE_DECLARE(LOG_MODULE_NAME);
|
|||
#define SD_TO_OBJ(sd) ((void *)(sd + 1))
|
||||
#define OBJ_TO_SD(obj) (((int)obj) - 1)
|
||||
|
||||
/* Mutex for getaddrinfo() calls: */
|
||||
K_MUTEX_DEFINE(ga_mutex);
|
||||
|
||||
static int simplelink_socket_accept(void *obj, struct sockaddr *addr,
|
||||
socklen_t *addrlen);
|
||||
|
||||
|
@ -974,64 +973,15 @@ static ssize_t simplelink_sendmsg(void *obj, const struct msghdr *msg,
|
|||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Later SimpleLink SDK versions implement the full getaddrinfo semantics,
|
||||
* returning potentially multiple IP addresses.
|
||||
* This version implements a simple gethostbyname() API for client only.
|
||||
*/
|
||||
static int simplelink_getaddrinfo(const char *node, const char *service,
|
||||
const struct zsock_addrinfo *hints,
|
||||
struct zsock_addrinfo **res)
|
||||
/* Adds address info entry to a list */
|
||||
static int set_addr_info(const struct SlNetUtil_addrInfo_t *sl_ai,
|
||||
struct zsock_addrinfo **res)
|
||||
{
|
||||
_u8 sl_family = SL_AF_INET;
|
||||
unsigned long port = 0;
|
||||
int socktype = SOCK_STREAM;
|
||||
int proto = IPPROTO_TCP;
|
||||
struct zsock_addrinfo *ai;
|
||||
struct sockaddr *ai_addr;
|
||||
_i16 retval;
|
||||
_u32 ipaddr[4];
|
||||
int retval = 0;
|
||||
|
||||
/* Check args: */
|
||||
if (!node) {
|
||||
retval = DNS_EAI_NONAME;
|
||||
goto exit;
|
||||
}
|
||||
if (service) {
|
||||
port = strtol(service, NULL, 10);
|
||||
if (port < 1 || port > USHRT_MAX) {
|
||||
retval = DNS_EAI_SERVICE;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
if (!res) {
|
||||
retval = DNS_EAI_NONAME;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* See if any hints for family; otherwise, default to AF_INET. */
|
||||
if (hints) {
|
||||
/* Note: SimpleLink SDK doesn't support AF_UNSPEC: */
|
||||
sl_family = (hints->ai_family == AF_INET6 ?
|
||||
SL_AF_INET6 : SL_AF_INET);
|
||||
}
|
||||
|
||||
/* Now, try to resolve host name: */
|
||||
k_mutex_lock(&ga_mutex, K_FOREVER);
|
||||
retval = sl_NetAppDnsGetHostByName((signed char *)node, strlen(node),
|
||||
ipaddr, sl_family);
|
||||
k_mutex_unlock(&ga_mutex);
|
||||
|
||||
if (retval < 0) {
|
||||
LOG_ERR("Could not resolve name: %s, retval: %d",
|
||||
node, retval);
|
||||
retval = DNS_EAI_NONAME;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Allocate out res (addrinfo) struct. Just one. */
|
||||
*res = calloc(1, sizeof(struct zsock_addrinfo));
|
||||
ai = *res;
|
||||
ai = calloc(1, sizeof(struct zsock_addrinfo));
|
||||
if (!ai) {
|
||||
retval = DNS_EAI_MEMORY;
|
||||
goto exit;
|
||||
|
@ -1040,44 +990,127 @@ static int simplelink_getaddrinfo(const char *node, const char *service,
|
|||
ai_addr = calloc(1, sizeof(struct sockaddr));
|
||||
if (!ai_addr) {
|
||||
retval = DNS_EAI_MEMORY;
|
||||
free(*res);
|
||||
free(ai);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now, fill in the fields of res (addrinfo struct): */
|
||||
ai->ai_family = (sl_family == SL_AF_INET6 ? AF_INET6 : AF_INET);
|
||||
if (hints) {
|
||||
socktype = hints->ai_socktype;
|
||||
}
|
||||
ai->ai_socktype = socktype;
|
||||
|
||||
if (socktype == SOCK_DGRAM) {
|
||||
proto = IPPROTO_UDP;
|
||||
}
|
||||
ai->ai_protocol = proto;
|
||||
ai->ai_family = (sl_ai->ai_family == SL_AF_INET6 ? AF_INET6 : AF_INET);
|
||||
ai->ai_socktype = (sl_ai->ai_socktype == SLNETSOCK_SOCK_DGRAM ?
|
||||
SOCK_DGRAM : SOCK_STREAM);
|
||||
ai->ai_protocol = (sl_ai->ai_protocol == SLNETSOCK_PROTO_UDP ?
|
||||
IPPROTO_UDP : IPPROTO_TCP);
|
||||
|
||||
/* Fill sockaddr struct fields based on family: */
|
||||
if (ai->ai_family == AF_INET) {
|
||||
SlNetSock_AddrIn_t *sl_addr =
|
||||
(SlNetSock_AddrIn_t *)sl_ai->ai_addr;
|
||||
|
||||
net_sin(ai_addr)->sin_family = ai->ai_family;
|
||||
net_sin(ai_addr)->sin_addr.s_addr = htonl(ipaddr[0]);
|
||||
net_sin(ai_addr)->sin_port = htons(port);
|
||||
net_sin(ai_addr)->sin_addr.s_addr = sl_addr->sin_addr.s_addr;
|
||||
net_sin(ai_addr)->sin_port = sl_addr->sin_port;
|
||||
ai->ai_addrlen = sizeof(struct sockaddr_in);
|
||||
} else {
|
||||
SlNetSock_AddrIn6_t *sl_addr =
|
||||
(SlNetSock_AddrIn6_t *)sl_ai->ai_addr;
|
||||
|
||||
net_sin6(ai_addr)->sin6_family = ai->ai_family;
|
||||
net_sin6(ai_addr)->sin6_addr.s6_addr32[0] = htonl(ipaddr[0]);
|
||||
net_sin6(ai_addr)->sin6_addr.s6_addr32[1] = htonl(ipaddr[1]);
|
||||
net_sin6(ai_addr)->sin6_addr.s6_addr32[2] = htonl(ipaddr[2]);
|
||||
net_sin6(ai_addr)->sin6_addr.s6_addr32[3] = htonl(ipaddr[3]);
|
||||
net_sin6(ai_addr)->sin6_port = htons(port);
|
||||
net_sin6(ai_addr)->sin6_addr.s6_addr32[0] =
|
||||
sl_addr->sin6_addr._S6_un._S6_u32[0];
|
||||
net_sin6(ai_addr)->sin6_addr.s6_addr32[1] =
|
||||
sl_addr->sin6_addr._S6_un._S6_u32[1];
|
||||
net_sin6(ai_addr)->sin6_addr.s6_addr32[2] =
|
||||
sl_addr->sin6_addr._S6_un._S6_u32[2];
|
||||
net_sin6(ai_addr)->sin6_addr.s6_addr32[3] =
|
||||
sl_addr->sin6_addr._S6_un._S6_u32[3];
|
||||
net_sin6(ai_addr)->sin6_port = sl_addr->sin6_port;
|
||||
ai->ai_addrlen = sizeof(struct sockaddr_in6);
|
||||
}
|
||||
ai->ai_addr = ai_addr;
|
||||
ai->ai_next = *res;
|
||||
*res = ai;
|
||||
|
||||
exit:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int simplelink_getaddrinfo(const char *node, const char *service,
|
||||
const struct zsock_addrinfo *hints,
|
||||
struct zsock_addrinfo **res)
|
||||
{
|
||||
int32_t retval;
|
||||
struct SlNetUtil_addrInfo_t sl_hints;
|
||||
struct SlNetUtil_addrInfo_t *sl_res, *sl_ai;
|
||||
|
||||
/* Initialize sl_hints to the defaults */
|
||||
memset(&sl_hints, 0, sizeof(sl_hints));
|
||||
|
||||
/* Check args: */
|
||||
if (!res) {
|
||||
retval = DNS_EAI_NONAME;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (hints) {
|
||||
/*
|
||||
* SlNetUtil only supports AI_NUMERICHOST and AI_PASSIVE, so
|
||||
* the rest are ignored.
|
||||
*/
|
||||
sl_hints.ai_flags |= ((hints->ai_flags & AI_PASSIVE) ?
|
||||
SLNETUTIL_AI_PASSIVE : 0);
|
||||
sl_hints.ai_flags |= ((hints->ai_flags & AI_NUMERICHOST) ?
|
||||
SLNETUTIL_AI_NUMERICHOST : 0);
|
||||
if (hints->ai_family == AF_UNSPEC) {
|
||||
sl_hints.ai_family = SLNETSOCK_AF_UNSPEC;
|
||||
} else {
|
||||
sl_hints.ai_family = (hints->ai_family == AF_INET6 ?
|
||||
SLNETSOCK_AF_INET6 : SLNETSOCK_AF_INET);
|
||||
}
|
||||
if (hints->ai_socktype == 0) {
|
||||
sl_hints.ai_socktype = 0;
|
||||
} else {
|
||||
sl_hints.ai_socktype =
|
||||
(hints->ai_socktype == SOCK_DGRAM ?
|
||||
SLNETSOCK_SOCK_DGRAM : SLNETSOCK_SOCK_STREAM);
|
||||
}
|
||||
if (hints->ai_protocol == 0) {
|
||||
sl_hints.ai_protocol = 0;
|
||||
} else {
|
||||
sl_hints.ai_protocol =
|
||||
(hints->ai_protocol == IPPROTO_UDP ?
|
||||
SLNETSOCK_PROTO_UDP : SLNETSOCK_PROTO_TCP);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Now, try to resolve host name: */
|
||||
retval = SlNetUtil_getAddrInfo(SLNETIF_ID_1, node,
|
||||
service, &sl_hints, &sl_res);
|
||||
|
||||
if (retval < 0) {
|
||||
LOG_ERR("Could not resolve name: %s, retval: %d",
|
||||
node, retval);
|
||||
retval = DNS_EAI_NONAME;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
sl_ai = sl_res;
|
||||
*res = NULL;
|
||||
while (sl_ai != NULL) {
|
||||
retval = set_addr_info(sl_ai, res);
|
||||
if (retval < 0) {
|
||||
LOG_ERR("Unable to set address info, retval: %d",
|
||||
retval);
|
||||
goto exit;
|
||||
}
|
||||
sl_ai = sl_ai->ai_next;
|
||||
}
|
||||
SlNetUtil_freeAddrInfo(sl_res);
|
||||
exit:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void simplelink_freeaddrinfo(struct zsock_addrinfo *res)
|
||||
{
|
||||
__ASSERT_NO_MSG(res);
|
||||
|
@ -1243,7 +1276,6 @@ NET_SOCKET_REGISTER(simplelink, AF_UNSPEC, simplelink_is_supported,
|
|||
|
||||
void simplelink_sockets_init(void)
|
||||
{
|
||||
k_mutex_init(&ga_mutex);
|
||||
}
|
||||
|
||||
const struct socket_dns_offload simplelink_dns_ops = {
|
||||
|
|
|
@ -15,6 +15,9 @@ LOG_MODULE_DECLARE(LOG_MODULE_NAME);
|
|||
#include <stdint.h>
|
||||
|
||||
#include <ti/drivers/net/wifi/simplelink.h>
|
||||
#include <ti/net/slnetif.h>
|
||||
#include <ti/net/slnetutils.h>
|
||||
#include <ti/drivers/net/wifi/slnetifwifi.h>
|
||||
#include <CC3220SF_LAUNCHXL.h>
|
||||
|
||||
#include "simplelink_support.h"
|
||||
|
@ -34,6 +37,9 @@ LOG_MODULE_DECLARE(LOG_MODULE_NAME);
|
|||
#define CHANNEL_MASK_ALL (0x1FFF)
|
||||
#define RSSI_TH_MAX (-95)
|
||||
|
||||
#define SLNET_IF_WIFI_PRIO (5)
|
||||
#define SLNET_IF_WIFI_NAME "CC32xx"
|
||||
|
||||
enum status_bits {
|
||||
/* Network Processor is powered up */
|
||||
STATUS_BIT_NWP_INIT = 0,
|
||||
|
@ -65,6 +71,20 @@ struct sl_connect_state sl_conn;
|
|||
/* Network Coprocessor state, including role and connection state: */
|
||||
static struct nwp_status nwp;
|
||||
|
||||
/* Minimal configuration of SlNetIfWifi for Zephyr */
|
||||
static SlNetIf_Config_t slnetifwifi_config_zephyr = {
|
||||
.sockCreate = SlNetIfWifi_socket,
|
||||
.sockClose = SlNetIfWifi_close,
|
||||
.sockSelect = SlNetIfWifi_select,
|
||||
.sockSetOpt = SlNetIfWifi_setSockOpt,
|
||||
.sockGetOpt = SlNetIfWifi_getSockOpt,
|
||||
.sockRecvFrom = SlNetIfWifi_recvFrom,
|
||||
.sockSendTo = SlNetIfWifi_sendTo,
|
||||
.utilGetHostByName = SlNetIfWifi_getHostByName,
|
||||
.ifGetIPAddr = SlNetIfWifi_getIPAddr,
|
||||
.ifGetConnectionStatus = SlNetIfWifi_getConnectionStatus
|
||||
};
|
||||
|
||||
/* Configure the device to a default state, resetting previous parameters .*/
|
||||
static int32_t configure_simplelink(void)
|
||||
{
|
||||
|
@ -442,6 +462,23 @@ void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *netapp_event)
|
|||
netapp_event->Id);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((netapp_event->Id == SL_NETAPP_EVENT_IPV4_ACQUIRED) ||
|
||||
(netapp_event->Id == SL_NETAPP_EVENT_IPV6_ACQUIRED)) {
|
||||
/* Initialize SlNetSock layer for getaddrinfo */
|
||||
SlNetIf_init(0);
|
||||
/*
|
||||
* We are only using SlNetSock to support getaddrinfo()
|
||||
* for the WiFi interface, so hardcoding the interface
|
||||
* id to 1 here.
|
||||
*/
|
||||
SlNetIf_add(SLNETIF_ID_1, SLNET_IF_WIFI_NAME,
|
||||
(const SlNetIf_Config_t *)&slnetifwifi_config_zephyr,
|
||||
SLNET_IF_WIFI_PRIO);
|
||||
|
||||
SlNetSock_init(0);
|
||||
SlNetUtil_init(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue