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) (((intptr_t)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 	intptr_t 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 	intptr_t 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,size_t len,int val,void * data)109 void __eswifi_socket_accept_cb(struct net_context *context, struct sockaddr *addr,
110 			       size_t 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 	intptr_t 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 	intptr_t 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 	intptr_t 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 	intptr_t 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 	intptr_t 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 	intptr_t 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 	intptr_t sock;
471 	int ret;
472 	void *obj;
473 
474 	if (nfds != 1) {
475 		errno = EINVAL;
476 		return -1;
477 	}
478 
479 	obj = zvfs_get_fd_obj(fds[0].fd,
480 			   (const struct fd_op_vtable *)
481 						&eswifi_socket_fd_op_vtable,
482 			   0);
483 	if (obj != NULL) {
484 		sock = OBJ_TO_SD(obj);
485 	} else {
486 		errno = EINVAL;
487 		return -1;
488 	}
489 
490 	if (sock >= ESWIFI_OFFLOAD_MAX_SOCKETS) {
491 		errno = EINVAL;
492 		return -1;
493 	}
494 
495 	if (!(fds[0].events & ZSOCK_POLLIN)) {
496 		errno = ENOTSUP;
497 		return -1;
498 	}
499 
500 	eswifi_lock(eswifi);
501 	socket = &eswifi->socket[sock];
502 
503 	ret = k_work_reschedule_for_queue(&eswifi->work_q, &socket->read_work, K_NO_WAIT);
504 	if (ret < 0) {
505 		LOG_ERR("Rescheduling socket read error");
506 		errno = -ret;
507 		eswifi_unlock(eswifi);
508 		return -1;
509 	}
510 
511 	eswifi_unlock(eswifi);
512 
513 	if (socket->state != ESWIFI_SOCKET_STATE_CONNECTED) {
514 		errno = EINVAL;
515 		return -1;
516 	}
517 
518 	if (!k_fifo_is_empty(&socket->fifo)) {
519 		goto done;
520 	}
521 
522 	if (msecs == SYS_FOREVER_MS) {
523 		timeout = K_FOREVER;
524 	} else {
525 		timeout = K_MSEC(msecs);
526 	}
527 
528 	ret = k_sem_take(&socket->read_sem, timeout);
529 	if (ret) {
530 		errno = ETIMEDOUT;
531 		return -1;
532 	}
533 
534 done:
535 	fds[0].revents = ZSOCK_POLLIN;
536 
537 	/* Report one event */
538 	return 1;
539 }
540 
eswifi_socket_bind(void * obj,const struct sockaddr * addr,socklen_t addrlen)541 static int eswifi_socket_bind(void *obj, const struct sockaddr *addr,
542 			      socklen_t addrlen)
543 {
544 	intptr_t sock = OBJ_TO_SD(obj);
545 	struct eswifi_off_socket *socket;
546 	int ret;
547 
548 	if ((addrlen == 0) || (addr == NULL) ||
549 	    (sock >= ESWIFI_OFFLOAD_MAX_SOCKETS)) {
550 		return -EINVAL;
551 	}
552 
553 	eswifi_lock(eswifi);
554 	socket = &eswifi->socket[sock];
555 	ret = __eswifi_bind(eswifi, socket, addr, addrlen);
556 	eswifi_unlock(eswifi);
557 
558 	return ret;
559 }
560 
eswifi_socket_is_supported(int family,int type,int proto)561 static bool eswifi_socket_is_supported(int family, int type, int proto)
562 {
563 	enum eswifi_transport_type eswifi_socket_type;
564 	int err;
565 
566 	if (family != AF_INET) {
567 		return false;
568 	}
569 
570 	if (type != SOCK_DGRAM &&
571 	    type != SOCK_STREAM) {
572 		return false;
573 	}
574 
575 	err = eswifi_socket_type_from_zephyr(proto, &eswifi_socket_type);
576 	if (err) {
577 		return false;
578 	}
579 
580 	return true;
581 }
582 
eswifi_socket_create(int family,int type,int proto)583 int eswifi_socket_create(int family, int type, int proto)
584 {
585 	int fd = zvfs_reserve_fd();
586 	intptr_t sock;
587 
588 	if (fd < 0) {
589 		return -1;
590 	}
591 
592 	sock = eswifi_socket_open(family, type, proto);
593 	if (sock < 0) {
594 		zvfs_free_fd(fd);
595 		return -1;
596 	}
597 
598 	zvfs_finalize_typed_fd(fd, SD_TO_OBJ(sock),
599 			    (const struct fd_op_vtable *)&eswifi_socket_fd_op_vtable,
600 			    ZVFS_MODE_IFSOCK);
601 
602 	return fd;
603 }
604 
eswifi_socket_ioctl(void * obj,unsigned int request,va_list args)605 static int eswifi_socket_ioctl(void *obj, unsigned int request, va_list args)
606 {
607 	switch (request) {
608 	case ZFD_IOCTL_POLL_PREPARE:
609 		return -EXDEV;
610 
611 	case ZFD_IOCTL_POLL_UPDATE:
612 		return -EOPNOTSUPP;
613 
614 	case ZFD_IOCTL_POLL_OFFLOAD: {
615 		struct zsock_pollfd *fds;
616 		int nfds;
617 		int timeout;
618 
619 		fds = va_arg(args, struct zsock_pollfd *);
620 		nfds = va_arg(args, int);
621 		timeout = va_arg(args, int);
622 
623 		return eswifi_socket_poll(fds, nfds, timeout);
624 	}
625 
626 	default:
627 		errno = EINVAL;
628 		return -1;
629 	}
630 }
631 
eswifi_socket_read(void * obj,void * buffer,size_t count)632 static ssize_t eswifi_socket_read(void *obj, void *buffer, size_t count)
633 {
634 	return eswifi_socket_recvfrom(obj, buffer, count, 0, NULL, 0);
635 }
636 
eswifi_socket_write(void * obj,const void * buffer,size_t count)637 static ssize_t eswifi_socket_write(void *obj, const void *buffer,
638 				   size_t count)
639 {
640 	return eswifi_socket_sendto(obj, buffer, count, 0, NULL, 0);
641 }
642 
643 static const struct socket_op_vtable eswifi_socket_fd_op_vtable = {
644 	.fd_vtable = {
645 		.read = eswifi_socket_read,
646 		.write = eswifi_socket_write,
647 		.close = eswifi_socket_close,
648 		.ioctl = eswifi_socket_ioctl,
649 	},
650 	.bind = eswifi_socket_bind,
651 	.connect = eswifi_socket_connect,
652 	.listen = eswifi_socket_listen,
653 	.accept = eswifi_socket_accept,
654 	.sendto = eswifi_socket_sendto,
655 	.recvfrom = eswifi_socket_recvfrom,
656 	.setsockopt = eswifi_socket_setsockopt,
657 };
658 
659 #ifdef CONFIG_NET_SOCKETS_OFFLOAD
660 NET_SOCKET_OFFLOAD_REGISTER(eswifi, CONFIG_NET_SOCKETS_OFFLOAD_PRIORITY, AF_UNSPEC,
661 			    eswifi_socket_is_supported, eswifi_socket_create);
662 #endif
663 
eswifi_off_getaddrinfo(const char * node,const char * service,const struct zsock_addrinfo * hints,struct zsock_addrinfo ** res)664 static int eswifi_off_getaddrinfo(const char *node, const char *service,
665 				  const struct zsock_addrinfo *hints,
666 				  struct zsock_addrinfo **res)
667 {
668 	struct sockaddr_in *ai_addr;
669 	struct zsock_addrinfo *ai;
670 	unsigned long port = 0;
671 	char *rsp;
672 	int err;
673 
674 	if (!node) {
675 		return DNS_EAI_NONAME;
676 	}
677 
678 	if (service) {
679 		port = strtol(service, NULL, 10);
680 		if (port < 1 || port > USHRT_MAX) {
681 			return DNS_EAI_SERVICE;
682 		}
683 	}
684 
685 	if (!res) {
686 		return DNS_EAI_NONAME;
687 	}
688 
689 	if (hints && hints->ai_family != AF_INET) {
690 		return DNS_EAI_FAIL;
691 	}
692 
693 	eswifi_lock(eswifi);
694 
695 	/* DNS lookup */
696 	snprintk(eswifi->buf, sizeof(eswifi->buf), "D0=%s\r", node);
697 	err = eswifi_at_cmd_rsp(eswifi, eswifi->buf, &rsp);
698 	if (err < 0) {
699 		err = DNS_EAI_FAIL;
700 		goto done_unlock;
701 	}
702 
703 	/* Allocate out res (addrinfo) struct.	Just one. */
704 	*res = calloc(1, sizeof(struct zsock_addrinfo));
705 	ai = *res;
706 	if (!ai) {
707 		err = DNS_EAI_MEMORY;
708 		goto done_unlock;
709 	}
710 
711 	/* Now, alloc the embedded sockaddr struct: */
712 	ai_addr = calloc(1, sizeof(*ai_addr));
713 	if (!ai_addr) {
714 		free(*res);
715 		err = DNS_EAI_MEMORY;
716 		goto done_unlock;
717 	}
718 
719 	ai->ai_family = AF_INET;
720 	ai->ai_socktype = hints ? hints->ai_socktype : SOCK_STREAM;
721 	ai->ai_protocol = ai->ai_socktype == SOCK_STREAM ? IPPROTO_TCP : IPPROTO_UDP;
722 
723 	ai_addr->sin_family = ai->ai_family;
724 	ai_addr->sin_port = htons(port);
725 
726 	if (!net_ipaddr_parse(rsp, strlen(rsp), (struct sockaddr *)ai_addr)) {
727 		free(ai_addr);
728 		free(*res);
729 		err = DNS_EAI_FAIL;
730 		goto done_unlock;
731 	}
732 
733 	ai->ai_addrlen = sizeof(*ai_addr);
734 	ai->ai_addr = (struct sockaddr *)ai_addr;
735 	err = 0;
736 
737 done_unlock:
738 	eswifi_unlock(eswifi);
739 	return err;
740 }
741 
eswifi_off_freeaddrinfo(struct zsock_addrinfo * res)742 static void eswifi_off_freeaddrinfo(struct zsock_addrinfo *res)
743 {
744 	__ASSERT_NO_MSG(res);
745 
746 	free(res->ai_addr);
747 	free(res);
748 }
749 
750 const struct socket_dns_offload eswifi_dns_ops = {
751 	.getaddrinfo = eswifi_off_getaddrinfo,
752 	.freeaddrinfo = eswifi_off_freeaddrinfo,
753 };
754 
eswifi_socket_offload_init(struct eswifi_dev * leswifi)755 int eswifi_socket_offload_init(struct eswifi_dev *leswifi)
756 {
757 	eswifi = leswifi;
758 
759 	socket_offload_dns_register(&eswifi_dns_ops);
760 
761 	return 0;
762 }
763