1 /*
2  * Copyright (c) 2019 Linumiz
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "eswifi_log.h"
8 LOG_MODULE_DECLARE(LOG_MODULE_NAME);
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/device.h>
12 #include <string.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <errno.h>
16 
17 #include <zephyr/net/socket_offload.h>
18 #include <zephyr/net/tls_credentials.h>
19 
20 #include "sockets_internal.h"
21 #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
22 #include "tls_internal.h"
23 #endif
24 #include "eswifi.h"
25 #include <zephyr/net/net_pkt.h>
26 
27 /* Increment by 1 to make sure we do not store the value of 0, which has
28  * a special meaning in the fdtable subsys.
29  */
30 #define SD_TO_OBJ(sd) ((void *)(sd + 1))
31 #define OBJ_TO_SD(obj) (((int)obj) - 1)
32 /* Default socket context (50CE) */
33 #define ESWIFI_INIT_CONTEXT	INT_TO_POINTER(0x50CE)
34 
35 static struct eswifi_dev *eswifi;
36 static const struct socket_op_vtable eswifi_socket_fd_op_vtable;
37 
__process_received(struct net_context * context,struct net_pkt * pkt,union net_ip_header * ip_hdr,union net_proto_header * proto_hdr,int status,void * user_data)38 static void __process_received(struct net_context *context,
39 			      struct net_pkt *pkt,
40 			      union net_ip_header *ip_hdr,
41 			      union net_proto_header *proto_hdr,
42 			      int status,
43 			      void *user_data)
44 {
45 	struct eswifi_off_socket *socket = user_data;
46 
47 	if (!pkt) {
48 		k_fifo_cancel_wait(&socket->fifo);
49 		return;
50 	}
51 
52 	k_fifo_put(&socket->fifo, pkt);
53 }
54 
eswifi_socket_connect(void * obj,const struct sockaddr * addr,socklen_t addrlen)55 static int eswifi_socket_connect(void *obj, const struct sockaddr *addr,
56 				 socklen_t addrlen)
57 {
58 	int sock = OBJ_TO_SD(obj);
59 	struct eswifi_off_socket *socket;
60 	int ret;
61 
62 	if ((addrlen == 0) || (addr == NULL) ||
63 	    (sock >= ESWIFI_OFFLOAD_MAX_SOCKETS)) {
64 		return -EINVAL;
65 	}
66 
67 	if (addr->sa_family != AF_INET) {
68 		LOG_ERR("Only AF_INET is supported!");
69 		return -EPFNOSUPPORT;
70 	}
71 
72 	eswifi_lock(eswifi);
73 	socket = &eswifi->socket[sock];
74 
75 	if (socket->state != ESWIFI_SOCKET_STATE_NONE) {
76 		eswifi_unlock(eswifi);
77 		return -EBUSY;
78 	}
79 
80 	socket->peer_addr = *addr;
81 	socket->state = ESWIFI_SOCKET_STATE_CONNECTING;
82 
83 	ret = __eswifi_off_start_client(eswifi, socket);
84 	if (!ret) {
85 		socket->state = ESWIFI_SOCKET_STATE_CONNECTED;
86 	} else {
87 		socket->state = ESWIFI_SOCKET_STATE_NONE;
88 	}
89 
90 	eswifi_unlock(eswifi);
91 	return ret;
92 }
93 
eswifi_socket_listen(void * obj,int backlog)94 static int eswifi_socket_listen(void *obj, int backlog)
95 {
96 	struct eswifi_off_socket *socket;
97 	int sock = OBJ_TO_SD(obj);
98 	int ret;
99 
100 	eswifi_lock(eswifi);
101 	socket = &eswifi->socket[sock];
102 
103 	ret = __eswifi_listen(eswifi, socket, backlog);
104 	eswifi_unlock(eswifi);
105 
106 	return ret;
107 }
108 
__eswifi_socket_accept_cb(struct net_context * context,struct sockaddr * addr,unsigned int len,int val,void * data)109 void __eswifi_socket_accept_cb(struct net_context *context, struct sockaddr *addr,
110 			       unsigned int len, int val, void *data)
111 {
112 	struct sockaddr *addr_target = data;
113 
114 	memcpy(addr_target, addr, len);
115 }
116 
__eswifi_socket_accept(void * obj,struct sockaddr * addr,socklen_t * addrlen)117 static int __eswifi_socket_accept(void *obj, struct sockaddr *addr,
118 				  socklen_t *addrlen)
119 {
120 	int sock = OBJ_TO_SD(obj);
121 	struct eswifi_off_socket *socket;
122 	int ret;
123 
124 	if ((addrlen == NULL) || (addr == NULL) ||
125 	    (sock >= ESWIFI_OFFLOAD_MAX_SOCKETS)) {
126 		return -EINVAL;
127 	}
128 
129 	eswifi_lock(eswifi);
130 	socket = &eswifi->socket[sock];
131 
132 	ret = __eswifi_accept(eswifi, socket);
133 	socket->accept_cb = __eswifi_socket_accept_cb;
134 	socket->accept_data = addr;
135 	k_sem_reset(&socket->accept_sem);
136 	eswifi_unlock(eswifi);
137 
138 	*addrlen = sizeof(struct sockaddr_in);
139 
140 	k_sem_take(&socket->accept_sem, K_FOREVER);
141 
142 	return 0;
143 }
144 
eswifi_socket_accept(void * obj,struct sockaddr * addr,socklen_t * addrlen)145 static int eswifi_socket_accept(void *obj, struct sockaddr *addr,
146 				socklen_t *addrlen)
147 {
148 	int fd = zvfs_reserve_fd();
149 	int sock;
150 
151 	if (fd < 0) {
152 		return -1;
153 	}
154 
155 	sock = __eswifi_socket_accept(obj, addr, addrlen);
156 	if (sock < 0) {
157 		zvfs_free_fd(fd);
158 		return -1;
159 	}
160 
161 	zvfs_finalize_typed_fd(fd, SD_TO_OBJ(sock),
162 			    (const struct fd_op_vtable *)&eswifi_socket_fd_op_vtable,
163 			    ZVFS_MODE_IFSOCK);
164 
165 	return fd;
166 }
167 
168 #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
map_credentials(int sd,const void * optval,socklen_t optlen)169 static int map_credentials(int sd, const void *optval, socklen_t optlen)
170 {
171 	sec_tag_t *sec_tags = (sec_tag_t *)optval;
172 	int ret = 0;
173 	int tags_len;
174 	sec_tag_t tag;
175 	int id;
176 	int i, bytes;
177 	struct tls_credential *cert;
178 
179 	if ((optlen % sizeof(sec_tag_t)) != 0 || (optlen == 0)) {
180 		return -EINVAL;
181 	}
182 
183 	tags_len = optlen / sizeof(sec_tag_t);
184 	/* For each tag, retrieve the credentials value and type: */
185 	for (i = 0; i < tags_len; i++) {
186 		tag = sec_tags[i];
187 		cert = credential_next_get(tag, NULL);
188 		while (cert != NULL) {
189 			/* Map Zephyr cert types to Simplelink cert options: */
190 			switch (cert->type) {
191 			case TLS_CREDENTIAL_CA_CERTIFICATE:
192 				id = 0;
193 				break;
194 			case TLS_CREDENTIAL_SERVER_CERTIFICATE:
195 				id = 1;
196 				break;
197 			case TLS_CREDENTIAL_PRIVATE_KEY:
198 				id = 2;
199 				break;
200 			case TLS_CREDENTIAL_NONE:
201 			case TLS_CREDENTIAL_PSK:
202 			case TLS_CREDENTIAL_PSK_ID:
203 			default:
204 				/* Not handled */
205 				return -EINVAL;
206 			}
207 
208 			snprintk(eswifi->buf, sizeof(eswifi->buf),
209 				 "PG=%d,%d,%d\r", 0, id, cert->len);
210 			bytes = strlen(eswifi->buf);
211 			memcpy(&eswifi->buf[bytes], cert->buf, cert->len);
212 			bytes += cert->len;
213 			LOG_DBG("cert write len %d\n", cert->len);
214 			ret = eswifi_request(eswifi, eswifi->buf, bytes + 1,
215 				     eswifi->buf, sizeof(eswifi->buf));
216 			LOG_DBG("cert write err %d\n", ret);
217 			if (ret < 0) {
218 				return ret;
219 			}
220 
221 			snprintk(eswifi->buf, sizeof(eswifi->buf), "PF=0,0\r");
222 			ret = eswifi_at_cmd(eswifi, eswifi->buf);
223 			if (ret < 0) {
224 				return ret;
225 			}
226 
227 			cert = credential_next_get(tag, cert);
228 		}
229 	}
230 
231 	return 0;
232 }
233 #else
map_credentials(int sd,const void * optval,socklen_t optlen)234 static int map_credentials(int sd, const void *optval, socklen_t optlen)
235 {
236 	return 0;
237 }
238 #endif
239 
eswifi_socket_setsockopt(void * obj,int level,int optname,const void * optval,socklen_t optlen)240 static int eswifi_socket_setsockopt(void *obj, int level, int optname,
241 				    const void *optval, socklen_t optlen)
242 {
243 	int sd = OBJ_TO_SD(obj);
244 	int ret;
245 
246 	if (IS_ENABLED(CONFIG_NET_SOCKETS_SOCKOPT_TLS) && level == SOL_TLS) {
247 		switch (optname) {
248 		case TLS_SEC_TAG_LIST:
249 			ret = map_credentials(sd, optval, optlen);
250 			break;
251 		case TLS_HOSTNAME:
252 		case TLS_PEER_VERIFY:
253 			ret = 0;
254 			break;
255 		default:
256 			return -EINVAL;
257 		}
258 	} else {
259 		return -EINVAL;
260 	}
261 
262 	return ret;
263 }
264 
eswifi_socket_send(void * obj,const void * buf,size_t len,int flags)265 static ssize_t eswifi_socket_send(void *obj, const void *buf, size_t len,
266 				  int flags)
267 {
268 	int sock = OBJ_TO_SD(obj);
269 	struct eswifi_off_socket *socket;
270 	int ret;
271 	int offset;
272 
273 	if (!buf) {
274 		return -EINVAL;
275 	}
276 
277 	eswifi_lock(eswifi);
278 	socket = &eswifi->socket[sock];
279 
280 	if (socket->state != ESWIFI_SOCKET_STATE_CONNECTED) {
281 		eswifi_unlock(eswifi);
282 		return -ENOTCONN;
283 	}
284 
285 	__select_socket(eswifi, socket->index);
286 
287 	/* header */
288 	snprintk(eswifi->buf, sizeof(eswifi->buf), "S3=%u\r", len);
289 	offset = strlen(eswifi->buf);
290 
291 	/* copy payload */
292 	memcpy(&eswifi->buf[offset], buf, len);
293 	offset += len;
294 
295 	ret = eswifi_request(eswifi, eswifi->buf, offset + 1, eswifi->buf,
296 				sizeof(eswifi->buf));
297 	if (ret < 0) {
298 		LOG_DBG("Unable to send data");
299 		ret = -EIO;
300 	} else {
301 		ret = len;
302 	}
303 
304 	eswifi_unlock(eswifi);
305 	return ret;
306 }
307 
eswifi_socket_sendto(void * obj,const void * buf,size_t len,int flags,const struct sockaddr * to,socklen_t tolen)308 static ssize_t eswifi_socket_sendto(void *obj, const void *buf, size_t len,
309 				    int flags, const struct sockaddr *to,
310 				    socklen_t tolen)
311 {
312 	if (to != NULL) {
313 		errno = EOPNOTSUPP;
314 		return -1;
315 	}
316 
317 	return eswifi_socket_send(obj, buf, len, flags);
318 }
319 
eswifi_socket_recv(void * obj,void * buf,size_t max_len,int flags)320 static ssize_t eswifi_socket_recv(void *obj, void *buf, size_t max_len,
321 				  int flags)
322 {
323 	int sock = OBJ_TO_SD(obj);
324 	struct eswifi_off_socket *socket;
325 	int len = 0, ret = 0;
326 	struct net_pkt *pkt;
327 
328 	if ((max_len == 0) || (buf == NULL) ||
329 	    (sock >= ESWIFI_OFFLOAD_MAX_SOCKETS)) {
330 		return -EINVAL;
331 	}
332 
333 	eswifi_lock(eswifi);
334 	socket = &eswifi->socket[sock];
335 
336 	if (socket->prev_pkt_rem) {
337 		pkt = socket->prev_pkt_rem;
338 		goto skip_wait;
339 	}
340 
341 	ret = k_work_reschedule_for_queue(&eswifi->work_q, &socket->read_work, K_NO_WAIT);
342 	if (ret < 0) {
343 		LOG_ERR("Rescheduling socket read error");
344 		errno = -ret;
345 		len = -1;
346 	}
347 
348 	if (flags & ZSOCK_MSG_DONTWAIT) {
349 		pkt = k_fifo_get(&socket->fifo, K_NO_WAIT);
350 		if (!pkt) {
351 			errno = EAGAIN;
352 			len = -1;
353 			goto done;
354 		}
355 	} else {
356 		eswifi_unlock(eswifi);
357 		pkt = k_fifo_get(&socket->fifo, K_FOREVER);
358 		if (!pkt) {
359 			return 0; /* EOF */
360 		}
361 		eswifi_lock(eswifi);
362 	}
363 
364 skip_wait:
365 	len = net_pkt_remaining_data(pkt);
366 	if (len > max_len) {
367 		len = max_len;
368 		socket->prev_pkt_rem = pkt;
369 	} else {
370 		socket->prev_pkt_rem = NULL;
371 	}
372 
373 	ret = net_pkt_read(pkt, buf, len);
374 
375 	if (!socket->prev_pkt_rem) {
376 		net_pkt_unref(pkt);
377 	}
378 
379 done:
380 	LOG_DBG("read %d %d %p", len, ret, pkt);
381 	eswifi_unlock(eswifi);
382 	if (ret) {
383 		len = 0;
384 	}
385 
386 	return len;
387 }
388 
eswifi_socket_recvfrom(void * obj,void * buf,size_t len,int flags,struct sockaddr * from,socklen_t * fromlen)389 static ssize_t eswifi_socket_recvfrom(void *obj, void *buf, size_t len,
390 				      int flags, struct sockaddr *from,
391 				      socklen_t *fromlen)
392 {
393 	if (fromlen != NULL) {
394 		errno = EOPNOTSUPP;
395 		return -1;
396 	}
397 
398 	return eswifi_socket_recv(obj, buf, len, flags);
399 }
400 
eswifi_socket_close(void * obj)401 static int eswifi_socket_close(void *obj)
402 {
403 	int sock = OBJ_TO_SD(obj);
404 	struct eswifi_off_socket *socket;
405 	struct net_pkt *pkt;
406 	int ret;
407 
408 	if (sock >= ESWIFI_OFFLOAD_MAX_SOCKETS) {
409 		return -EINVAL;
410 	}
411 
412 	eswifi_lock(eswifi);
413 
414 	socket = &eswifi->socket[sock];
415 	ret = __eswifi_socket_free(eswifi, socket);
416 	if (ret) {
417 		goto done;
418 	}
419 
420 	/* consume all net pkt */
421 	while (1) {
422 		pkt = k_fifo_get(&socket->fifo, K_NO_WAIT);
423 		if (!pkt) {
424 			break;
425 		}
426 		net_pkt_unref(pkt);
427 	}
428 
429 	if (--socket->usage <= 0) {
430 		socket->context = NULL;
431 	}
432 
433 done:
434 	eswifi_unlock(eswifi);
435 	return ret;
436 }
437 
eswifi_socket_open(int family,int type,int proto)438 static int eswifi_socket_open(int family, int type, int proto)
439 {
440 	struct eswifi_off_socket *socket = NULL;
441 	int idx;
442 
443 	eswifi_lock(eswifi);
444 
445 	idx = __eswifi_socket_new(eswifi, family, type, proto, ESWIFI_INIT_CONTEXT);
446 	if (idx < 0) {
447 		goto unlock;
448 	}
449 
450 	socket = &eswifi->socket[idx];
451 	k_fifo_init(&socket->fifo);
452 	k_sem_init(&socket->read_sem, 0, 200);
453 	k_sem_init(&socket->accept_sem, 1, 1);
454 	socket->prev_pkt_rem = NULL;
455 	socket->recv_cb = __process_received;
456 	socket->recv_data = socket;
457 
458 	k_work_reschedule_for_queue(&eswifi->work_q, &socket->read_work,
459 				    K_MSEC(500));
460 
461 unlock:
462 	eswifi_unlock(eswifi);
463 	return idx;
464 }
465 
eswifi_socket_poll(struct zsock_pollfd * fds,int nfds,int msecs)466 static int eswifi_socket_poll(struct zsock_pollfd *fds, int nfds, int msecs)
467 {
468 	struct eswifi_off_socket *socket;
469 	k_timeout_t timeout;
470 	int sock, ret;
471 	void *obj;
472 
473 	if (nfds != 1) {
474 		errno = EINVAL;
475 		return -1;
476 	}
477 
478 	obj = zvfs_get_fd_obj(fds[0].fd,
479 			   (const struct fd_op_vtable *)
480 						&eswifi_socket_fd_op_vtable,
481 			   0);
482 	if (obj != NULL) {
483 		sock = OBJ_TO_SD(obj);
484 	} else {
485 		errno = EINVAL;
486 		return -1;
487 	}
488 
489 	if (sock >= ESWIFI_OFFLOAD_MAX_SOCKETS) {
490 		errno = EINVAL;
491 		return -1;
492 	}
493 
494 	if (!(fds[0].events & ZSOCK_POLLIN)) {
495 		errno = ENOTSUP;
496 		return -1;
497 	}
498 
499 	eswifi_lock(eswifi);
500 	socket = &eswifi->socket[sock];
501 
502 	ret = k_work_reschedule_for_queue(&eswifi->work_q, &socket->read_work, K_NO_WAIT);
503 	if (ret < 0) {
504 		LOG_ERR("Rescheduling socket read error");
505 		errno = -ret;
506 		eswifi_unlock(eswifi);
507 		return -1;
508 	}
509 
510 	eswifi_unlock(eswifi);
511 
512 	if (socket->state != ESWIFI_SOCKET_STATE_CONNECTED) {
513 		errno = EINVAL;
514 		return -1;
515 	}
516 
517 	if (!k_fifo_is_empty(&socket->fifo)) {
518 		goto done;
519 	}
520 
521 	if (msecs == SYS_FOREVER_MS) {
522 		timeout = K_FOREVER;
523 	} else {
524 		timeout = K_MSEC(msecs);
525 	}
526 
527 	ret = k_sem_take(&socket->read_sem, timeout);
528 	if (ret) {
529 		errno = ETIMEDOUT;
530 		return -1;
531 	}
532 
533 done:
534 	fds[0].revents = ZSOCK_POLLIN;
535 
536 	/* Report one event */
537 	return 1;
538 }
539 
eswifi_socket_bind(void * obj,const struct sockaddr * addr,socklen_t addrlen)540 static int eswifi_socket_bind(void *obj, const struct sockaddr *addr,
541 			      socklen_t addrlen)
542 {
543 	int sock = OBJ_TO_SD(obj);
544 	struct eswifi_off_socket *socket;
545 	int ret;
546 
547 	if ((addrlen == 0) || (addr == NULL) ||
548 	    (sock >= ESWIFI_OFFLOAD_MAX_SOCKETS)) {
549 		return -EINVAL;
550 	}
551 
552 	eswifi_lock(eswifi);
553 	socket = &eswifi->socket[sock];
554 	ret = __eswifi_bind(eswifi, socket, addr, addrlen);
555 	eswifi_unlock(eswifi);
556 
557 	return ret;
558 }
559 
eswifi_socket_is_supported(int family,int type,int proto)560 static bool eswifi_socket_is_supported(int family, int type, int proto)
561 {
562 	enum eswifi_transport_type eswifi_socket_type;
563 	int err;
564 
565 	if (family != AF_INET) {
566 		return false;
567 	}
568 
569 	if (type != SOCK_DGRAM &&
570 	    type != SOCK_STREAM) {
571 		return false;
572 	}
573 
574 	err = eswifi_socket_type_from_zephyr(proto, &eswifi_socket_type);
575 	if (err) {
576 		return false;
577 	}
578 
579 	return true;
580 }
581 
eswifi_socket_create(int family,int type,int proto)582 int eswifi_socket_create(int family, int type, int proto)
583 {
584 	int fd = zvfs_reserve_fd();
585 	int sock;
586 
587 	if (fd < 0) {
588 		return -1;
589 	}
590 
591 	sock = eswifi_socket_open(family, type, proto);
592 	if (sock < 0) {
593 		zvfs_free_fd(fd);
594 		return -1;
595 	}
596 
597 	zvfs_finalize_typed_fd(fd, SD_TO_OBJ(sock),
598 			    (const struct fd_op_vtable *)&eswifi_socket_fd_op_vtable,
599 			    ZVFS_MODE_IFSOCK);
600 
601 	return fd;
602 }
603 
eswifi_socket_ioctl(void * obj,unsigned int request,va_list args)604 static int eswifi_socket_ioctl(void *obj, unsigned int request, va_list args)
605 {
606 	switch (request) {
607 	case ZFD_IOCTL_POLL_PREPARE:
608 		return -EXDEV;
609 
610 	case ZFD_IOCTL_POLL_UPDATE:
611 		return -EOPNOTSUPP;
612 
613 	case ZFD_IOCTL_POLL_OFFLOAD: {
614 		struct zsock_pollfd *fds;
615 		int nfds;
616 		int timeout;
617 
618 		fds = va_arg(args, struct zsock_pollfd *);
619 		nfds = va_arg(args, int);
620 		timeout = va_arg(args, int);
621 
622 		return eswifi_socket_poll(fds, nfds, timeout);
623 	}
624 
625 	default:
626 		errno = EINVAL;
627 		return -1;
628 	}
629 }
630 
eswifi_socket_read(void * obj,void * buffer,size_t count)631 static ssize_t eswifi_socket_read(void *obj, void *buffer, size_t count)
632 {
633 	return eswifi_socket_recvfrom(obj, buffer, count, 0, NULL, 0);
634 }
635 
eswifi_socket_write(void * obj,const void * buffer,size_t count)636 static ssize_t eswifi_socket_write(void *obj, const void *buffer,
637 				   size_t count)
638 {
639 	return eswifi_socket_sendto(obj, buffer, count, 0, NULL, 0);
640 }
641 
642 static const struct socket_op_vtable eswifi_socket_fd_op_vtable = {
643 	.fd_vtable = {
644 		.read = eswifi_socket_read,
645 		.write = eswifi_socket_write,
646 		.close = eswifi_socket_close,
647 		.ioctl = eswifi_socket_ioctl,
648 	},
649 	.bind = eswifi_socket_bind,
650 	.connect = eswifi_socket_connect,
651 	.listen = eswifi_socket_listen,
652 	.accept = eswifi_socket_accept,
653 	.sendto = eswifi_socket_sendto,
654 	.recvfrom = eswifi_socket_recvfrom,
655 	.setsockopt = eswifi_socket_setsockopt,
656 };
657 
658 #ifdef CONFIG_NET_SOCKETS_OFFLOAD
659 NET_SOCKET_OFFLOAD_REGISTER(eswifi, CONFIG_NET_SOCKETS_OFFLOAD_PRIORITY, AF_UNSPEC,
660 			    eswifi_socket_is_supported, eswifi_socket_create);
661 #endif
662 
eswifi_off_getaddrinfo(const char * node,const char * service,const struct zsock_addrinfo * hints,struct zsock_addrinfo ** res)663 static int eswifi_off_getaddrinfo(const char *node, const char *service,
664 				  const struct zsock_addrinfo *hints,
665 				  struct zsock_addrinfo **res)
666 {
667 	struct sockaddr_in *ai_addr;
668 	struct zsock_addrinfo *ai;
669 	unsigned long port = 0;
670 	char *rsp;
671 	int err;
672 
673 	if (!node) {
674 		return DNS_EAI_NONAME;
675 	}
676 
677 	if (service) {
678 		port = strtol(service, NULL, 10);
679 		if (port < 1 || port > USHRT_MAX) {
680 			return DNS_EAI_SERVICE;
681 		}
682 	}
683 
684 	if (!res) {
685 		return DNS_EAI_NONAME;
686 	}
687 
688 	if (hints && hints->ai_family != AF_INET) {
689 		return DNS_EAI_FAIL;
690 	}
691 
692 	eswifi_lock(eswifi);
693 
694 	/* DNS lookup */
695 	snprintk(eswifi->buf, sizeof(eswifi->buf), "D0=%s\r", node);
696 	err = eswifi_at_cmd_rsp(eswifi, eswifi->buf, &rsp);
697 	if (err < 0) {
698 		err = DNS_EAI_FAIL;
699 		goto done_unlock;
700 	}
701 
702 	/* Allocate out res (addrinfo) struct.	Just one. */
703 	*res = calloc(1, sizeof(struct zsock_addrinfo));
704 	ai = *res;
705 	if (!ai) {
706 		err = DNS_EAI_MEMORY;
707 		goto done_unlock;
708 	}
709 
710 	/* Now, alloc the embedded sockaddr struct: */
711 	ai_addr = calloc(1, sizeof(*ai_addr));
712 	if (!ai_addr) {
713 		free(*res);
714 		err = DNS_EAI_MEMORY;
715 		goto done_unlock;
716 	}
717 
718 	ai->ai_family = AF_INET;
719 	ai->ai_socktype = hints ? hints->ai_socktype : SOCK_STREAM;
720 	ai->ai_protocol = ai->ai_socktype == SOCK_STREAM ? IPPROTO_TCP : IPPROTO_UDP;
721 
722 	ai_addr->sin_family = ai->ai_family;
723 	ai_addr->sin_port = htons(port);
724 
725 	if (!net_ipaddr_parse(rsp, strlen(rsp), (struct sockaddr *)ai_addr)) {
726 		free(ai_addr);
727 		free(*res);
728 		err = DNS_EAI_FAIL;
729 		goto done_unlock;
730 	}
731 
732 	ai->ai_addrlen = sizeof(*ai_addr);
733 	ai->ai_addr = (struct sockaddr *)ai_addr;
734 	err = 0;
735 
736 done_unlock:
737 	eswifi_unlock(eswifi);
738 	return err;
739 }
740 
eswifi_off_freeaddrinfo(struct zsock_addrinfo * res)741 static void eswifi_off_freeaddrinfo(struct zsock_addrinfo *res)
742 {
743 	__ASSERT_NO_MSG(res);
744 
745 	free(res->ai_addr);
746 	free(res);
747 }
748 
749 const struct socket_dns_offload eswifi_dns_ops = {
750 	.getaddrinfo = eswifi_off_getaddrinfo,
751 	.freeaddrinfo = eswifi_off_freeaddrinfo,
752 };
753 
eswifi_socket_offload_init(struct eswifi_dev * leswifi)754 int eswifi_socket_offload_init(struct eswifi_dev *leswifi)
755 {
756 	eswifi = leswifi;
757 
758 	socket_offload_dns_register(&eswifi_dns_ops);
759 
760 	return 0;
761 }
762