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