1 /*
2 * Copyright (c) 2006-2024 RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2018-06-06 chenyong first version
9 * 2022-06-02 xianxistu add implement about "AT server"
10 */
11
12 #include <at.h>
13 #ifdef AT_USING_SOCKET_SERVER
14 #include <stdio.h>
15 #endif
16 #include <stdlib.h>
17 #include <string.h>
18 #include <ctype.h>
19 #include <sys/time.h>
20 #include <sys/errno.h>
21
22 #include <at_socket.h>
23 #include <at_device.h>
24
25 #ifdef SAL_USING_POSIX
26 #include <poll.h>
27 #endif
28
29 #include <arpa/inet.h>
30 #include <netdev.h>
31
32 #define LOG_TAG "at.skt"
33 #include <at_log.h>
34
35 #ifdef AT_USING_SOCKET
36
37 #define HTONS_PORT(x) ((((x) & 0x00ffUL) << 8) | (((x) & 0xff00UL) >> 8))
38 #define NIPQUAD(addr) \
39 ((unsigned char *)&addr)[0], \
40 ((unsigned char *)&addr)[1], \
41 ((unsigned char *)&addr)[2], \
42 ((unsigned char *)&addr)[3]
43
44 /* The maximum number of sockets structure */
45 #ifndef AT_SOCKETS_NUM
46 #define AT_SOCKETS_NUM AT_DEVICE_SOCKETS_NUM
47 #endif
48
49 typedef enum {
50 AT_EVENT_SEND,
51 AT_EVENT_RECV,
52 AT_EVENT_ERROR,
53 } at_event_t;
54
55 #ifdef AT_USING_SOCKET_SERVER
56 static void at_connect_notice_cb(struct at_socket *sock, at_socket_evt_t event, const char *buff, size_t bfsz);
57 #endif
58
59 static rt_mutex_t at_slock = RT_NULL;
60
61 /* the global of sockets list */
62 static rt_slist_t _socket_list = RT_SLIST_OBJECT_INIT(_socket_list);
63
at_get_socket(int socket)64 struct at_socket *at_get_socket(int socket)
65 {
66 rt_base_t level;
67 rt_slist_t *node = RT_NULL;
68 struct at_socket *at_sock = RT_NULL;
69
70 level = rt_hw_interrupt_disable();
71
72 rt_slist_for_each(node, &_socket_list)
73 {
74 at_sock = rt_slist_entry(node, struct at_socket, list);
75 if (at_sock && socket == at_sock->socket)
76 {
77 if (at_sock->magic == AT_SOCKET_MAGIC)
78 {
79 rt_hw_interrupt_enable(level);
80 return at_sock;
81 }
82 }
83 }
84
85 rt_hw_interrupt_enable(level);
86
87 return RT_NULL;
88 }
89
90 #ifdef AT_USING_SOCKET_SERVER
at_get_base_socket(int base_socket)91 struct at_socket *at_get_base_socket(int base_socket)
92 {
93 rt_base_t level;
94 rt_slist_t *node = RT_NULL;
95 struct at_socket *at_sock = RT_NULL;
96
97 level = rt_hw_interrupt_disable();
98
99 rt_slist_for_each(node, &_socket_list)
100 {
101 at_sock = rt_slist_entry(node, struct at_socket, list);
102 if (at_sock && base_socket == (int)at_sock->user_data && at_sock->state != AT_SOCKET_LISTEN)
103 {
104 if (at_sock->magic == AT_SOCKET_MAGIC)
105 {
106 rt_hw_interrupt_enable(level);
107 return at_sock;
108 }
109 }
110 }
111
112 rt_hw_interrupt_enable(level);
113
114 return RT_NULL;
115 }
116 #endif
117
118 /* get a block to the AT socket receive list*/
at_recvpkt_put(rt_slist_t * rlist,const char * ptr,size_t length)119 static rt_err_t at_recvpkt_put(rt_slist_t *rlist, const char *ptr, size_t length)
120 {
121 at_recv_pkt_t pkt = RT_NULL;
122
123 pkt = (at_recv_pkt_t) rt_calloc(1, sizeof(struct at_recv_pkt));
124 if (pkt == RT_NULL)
125 {
126 LOG_E("No memory for receive packet table!");
127 return -RT_ENOMEM;
128 }
129
130 pkt->bfsz_totle = length;
131 pkt->bfsz_index = 0;
132 pkt->buff = (char *) ptr;
133
134 rt_slist_append(rlist, &pkt->list);
135
136 return RT_EOK;
137 }
138
139 /* delete and free all receive buffer list */
at_recvpkt_all_delete(rt_slist_t * rlist)140 static int at_recvpkt_all_delete(rt_slist_t *rlist)
141 {
142 at_recv_pkt_t pkt = RT_NULL;
143 rt_slist_t *node = RT_NULL;
144
145 if (rt_slist_isempty(rlist))
146 {
147 return 0;
148 }
149
150 for(node = rt_slist_first(rlist); node;)
151 {
152 pkt = rt_slist_entry(node, struct at_recv_pkt, list);
153 node = rt_slist_next(node);
154 if (pkt && pkt->buff)
155 {
156 rt_free(pkt->buff);
157 }
158 if (pkt)
159 {
160 rt_free(pkt);
161 pkt = RT_NULL;
162 }
163 }
164
165 return 0;
166 }
167
168 /* delete and free specified list block */
at_recvpkt_node_delete(rt_slist_t * rlist,rt_slist_t * node)169 static int at_recvpkt_node_delete(rt_slist_t *rlist, rt_slist_t *node)
170 {
171 at_recv_pkt_t pkt = RT_NULL;
172
173 if (rt_slist_isempty(rlist))
174 {
175 return 0;
176 }
177
178 rt_slist_remove(rlist, node);
179
180 pkt = rt_slist_entry(node, struct at_recv_pkt, list);
181 if (pkt && pkt->buff)
182 {
183 rt_free(pkt->buff);
184 }
185 if (pkt)
186 {
187 rt_free(pkt);
188 pkt = RT_NULL;
189 }
190
191 return 0;
192 }
193
194 /* get a block from AT socket receive buffer list */
at_recvpkt_get(rt_slist_t * rlist,char * mem,size_t len)195 static size_t at_recvpkt_get(rt_slist_t *rlist, char *mem, size_t len)
196 {
197 rt_slist_t *node = RT_NULL;
198 rt_slist_t *free_node = RT_NULL;
199 at_recv_pkt_t pkt = RT_NULL;
200 size_t content_pos = 0, page_pos = 0;
201
202 if (rt_slist_isempty(rlist))
203 {
204 return 0;
205 }
206
207 for (node = rt_slist_first(rlist); node;)
208 {
209 pkt = rt_slist_entry(node, struct at_recv_pkt, list);
210
211 free_node = node;
212 node = rt_slist_next(node);
213
214 if (!pkt) continue;
215
216 page_pos = pkt->bfsz_totle - pkt->bfsz_index;
217
218 if (page_pos >= len - content_pos)
219 {
220 rt_memcpy((char *) mem + content_pos, pkt->buff + pkt->bfsz_index, len - content_pos);
221 pkt->bfsz_index += len - content_pos;
222 if (pkt->bfsz_index == pkt->bfsz_totle)
223 {
224 at_recvpkt_node_delete(rlist, free_node);
225 }
226 content_pos = len;
227 break;
228 }
229 else
230 {
231 rt_memcpy((char *) mem + content_pos, pkt->buff + pkt->bfsz_index, page_pos);
232 content_pos += page_pos;
233 pkt->bfsz_index += page_pos;
234 at_recvpkt_node_delete(rlist, free_node);
235 }
236 }
237
238 return content_pos;
239 }
240
at_do_event_changes(struct at_socket * sock,at_event_t event,rt_bool_t is_plus)241 static void at_do_event_changes(struct at_socket *sock, at_event_t event, rt_bool_t is_plus)
242 {
243 switch (event)
244 {
245 case AT_EVENT_SEND:
246 {
247 if (is_plus)
248 {
249 sock->sendevent = 1;
250
251 #ifdef SAL_USING_POSIX
252 rt_wqueue_wakeup(&sock->wait_head, (void*) POLLOUT);
253 #endif
254 }
255 else if (sock->sendevent)
256 {
257 sock->sendevent = 0;
258 }
259 break;
260 }
261 case AT_EVENT_RECV:
262 {
263 if (is_plus)
264 {
265 sock->rcvevent++;
266
267 #ifdef SAL_USING_POSIX
268 rt_wqueue_wakeup(&sock->wait_head, (void*) POLLIN);
269 #endif
270 }
271 else if (sock->rcvevent)
272 {
273 sock->rcvevent --;
274 }
275 break;
276 }
277 case AT_EVENT_ERROR:
278 {
279 if (is_plus)
280 {
281 sock->errevent++;
282
283 #ifdef SAL_USING_POSIX
284 rt_wqueue_wakeup(&sock->wait_head, (void*) POLLERR);
285 #endif
286 }
287 else if (sock->errevent)
288 {
289 sock->errevent --;
290 }
291 break;
292 }
293 default:
294 LOG_E("Not supported event (%d)", event);
295 }
296 }
297
at_do_event_clean(struct at_socket * sock,at_event_t event)298 static void at_do_event_clean(struct at_socket *sock, at_event_t event)
299 {
300 switch (event)
301 {
302 case AT_EVENT_SEND:
303 {
304 sock->sendevent = 0;
305 break;
306 }
307 case AT_EVENT_RECV:
308 {
309 sock->rcvevent = 0;
310 break;
311 }
312 case AT_EVENT_ERROR:
313 {
314 sock->errevent = 0;
315 break;
316 }
317 default:
318 LOG_E("Not supported event (%d)", event);
319 }
320 }
321
free_socket(struct at_socket * sock)322 static int free_socket(struct at_socket *sock)
323 {
324 if (at_slock == RT_NULL)
325 {
326 /* create AT socket lock */
327 at_slock = rt_mutex_create("at_slock", RT_IPC_FLAG_PRIO);
328 if (at_slock == RT_NULL)
329 {
330 LOG_E("No memory for socket allocation lock!");
331 return RT_NULL;
332 }
333 }
334
335 rt_mutex_take(at_slock, RT_WAITING_FOREVER);
336 if (sock->recv_notice)
337 {
338 rt_sem_delete(sock->recv_notice);
339 }
340
341 if (sock->recv_lock)
342 {
343 rt_mutex_delete(sock->recv_lock);
344 }
345
346 if (!rt_slist_isempty(&sock->recvpkt_list))
347 {
348 at_recvpkt_all_delete(&sock->recvpkt_list);
349 }
350
351 /* delect socket from socket list */
352 {
353 rt_base_t level;
354 rt_slist_t *node = RT_NULL;
355 struct at_socket *at_sock = RT_NULL;
356
357 level = rt_hw_interrupt_disable();
358
359 rt_slist_for_each(node, &_socket_list)
360 {
361 at_sock = rt_slist_entry(node, struct at_socket, list);
362 if (at_sock && sock->socket == at_sock->socket)
363 {
364 if (at_sock->magic == AT_SOCKET_MAGIC)
365 {
366 rt_slist_remove(&_socket_list, &at_sock->list);
367 break;
368 }
369 }
370 }
371
372 rt_hw_interrupt_enable(level);
373 }
374
375 rt_memset(sock, RT_NULL, sizeof(struct at_socket));
376 rt_mutex_release(at_slock);
377 return 0;
378 }
379
alloc_socket_by_device(struct at_device * device,enum at_socket_type type)380 static struct at_socket *alloc_socket_by_device(struct at_device *device, enum at_socket_type type)
381 {
382 rt_base_t level;
383 struct at_socket *sock = RT_NULL;
384 char name[RT_NAME_MAX] = {0};
385 int idx = 0;
386
387 if (at_slock == RT_NULL)
388 {
389 /* create AT socket lock */
390 at_slock = rt_mutex_create("at_slock", RT_IPC_FLAG_PRIO);
391 if (at_slock == RT_NULL)
392 {
393 LOG_E("No memory for socket allocation lock!");
394 return RT_NULL;
395 }
396 }
397
398 rt_mutex_take(at_slock, RT_WAITING_FOREVER);
399
400 /* find an empty at socket entry */
401 if (device->class->socket_ops->at_socket != RT_NULL)
402 {
403 idx = device->class->socket_ops->at_socket(device, type);
404 }
405 else
406 {
407 for (idx = 0; idx < device->class->socket_num && device->sockets[idx].magic == AT_SOCKET_MAGIC; idx++);
408 }
409
410 /* can't find an empty protocol family entry */
411 if (idx < 0 || idx >= device->class->socket_num)
412 {
413 LOG_E("can't find an empty protocol family entry.");
414 goto __err;
415 }
416
417 sock = &(device->sockets[idx]);
418 /* the socket descriptor is the number of sockte lists */
419 sock->socket = idx;
420 /* the socket operations is the specify operations of the device */
421 sock->ops = device->class->socket_ops;
422 /* the user-data is the at device socket descriptor */
423 sock->user_data = (void *) idx;
424 sock->device = (void *) device;
425 sock->magic = AT_SOCKET_MAGIC;
426 sock->state = AT_SOCKET_NONE;
427 sock->rcvevent = RT_NULL;
428 sock->sendevent = RT_NULL;
429 sock->errevent = RT_NULL;
430
431 rt_slist_init(&(sock->list));
432 level = rt_hw_interrupt_disable();
433 rt_slist_insert(&_socket_list, &(sock->list));
434 rt_hw_interrupt_enable(level);
435
436 rt_slist_init(&sock->recvpkt_list);
437 #ifdef SAL_USING_POSIX
438 rt_wqueue_init(&sock->wait_head);
439 #endif
440
441 rt_snprintf(name, RT_NAME_MAX, "%s%d", "at_skt", idx);
442 /* create AT socket receive semaphore */
443 if ((sock->recv_notice = rt_sem_create(name, 0, RT_IPC_FLAG_FIFO)) == RT_NULL)
444 {
445 LOG_E("No memory socket receive notic semaphore create.");
446 goto __err;
447 }
448 /* set AT socket receive semaphore 'max_value' to 1 */
449 rt_sem_control(sock->recv_notice, RT_IPC_CMD_SET_VLIMIT, (void *)1);
450
451 rt_snprintf(name, RT_NAME_MAX, "%s%d", "at_skt", idx);
452 /* create AT socket receive ring buffer lock */
453 if((sock->recv_lock = rt_mutex_create(name, RT_IPC_FLAG_PRIO)) == RT_NULL)
454 {
455 LOG_E("No memory for socket receive mutex create.");
456 goto __err;
457 }
458
459 rt_mutex_release(at_slock);
460 return sock;
461
462 __err:
463 rt_mutex_release(at_slock);
464 if(sock != RT_NULL)
465 {
466 free_socket(sock);
467 }
468 return RT_NULL;
469 }
470
alloc_socket(enum at_socket_type type)471 static struct at_socket *alloc_socket(enum at_socket_type type)
472 {
473 extern struct netdev *netdev_default;
474 struct netdev *netdev = RT_NULL;
475 struct at_device *device = RT_NULL;
476
477 if (netdev_default && netdev_is_up(netdev_default) &&
478 netdev_family_get(netdev_default) == AF_AT)
479 {
480 netdev = netdev_default;
481 }
482 else
483 {
484 /* get network interface device by protocol family AF_AT */
485 netdev = netdev_get_by_family(AF_AT);
486 if (netdev == RT_NULL)
487 {
488 return RT_NULL;
489 }
490 }
491
492 device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, netdev->name);
493 if (device == RT_NULL)
494 {
495 return RT_NULL;
496 }
497
498 return alloc_socket_by_device(device, type);
499 }
500
501 static void at_recv_notice_cb(struct at_socket *sock, at_socket_evt_t event, const char *buff, size_t bfsz);
502 static void at_closed_notice_cb(struct at_socket *sock, at_socket_evt_t event, const char *buff, size_t bfsz);
503
at_socket(int domain,int type,int protocol)504 int at_socket(int domain, int type, int protocol)
505 {
506 struct at_socket *sock = RT_NULL;
507 enum at_socket_type socket_type;
508
509 /* check socket family protocol */
510 if(domain != AF_INET && domain != AF_AT)
511 {
512 rt_set_errno(EAFNOSUPPORT);
513 return -1;
514 }
515
516 /*TODO check protocol*/
517
518 switch(type)
519 {
520 case SOCK_STREAM:
521 socket_type = AT_SOCKET_TCP;
522 break;
523
524 case SOCK_DGRAM:
525 socket_type = AT_SOCKET_UDP;
526 break;
527
528 default :
529 LOG_E("Don't support socket type (%d)!", type);
530 rt_set_errno(EPROTOTYPE);
531 return -1;
532 }
533
534 /* allocate and initialize a new AT socket */
535 sock = alloc_socket(socket_type);
536 if (sock == RT_NULL)
537 {
538 LOG_E("Failed to allocate socket");
539 rt_set_errno(EIO);
540 return -1;
541 }
542 sock->type = socket_type;
543 sock->state = AT_SOCKET_OPEN;
544
545 /* set AT socket receive data callback function */
546 sock->ops->at_set_event_cb(AT_SOCKET_EVT_RECV, at_recv_notice_cb);
547 sock->ops->at_set_event_cb(AT_SOCKET_EVT_CLOSED, at_closed_notice_cb);
548 #ifdef AT_USING_SOCKET_SERVER
549 sock->ops->at_set_event_cb(AT_SOCKET_EVT_CONNECTED, at_connect_notice_cb);
550 #endif
551
552 return sock->socket;
553 }
554
at_closesocket(int socket)555 int at_closesocket(int socket)
556 {
557 struct at_socket *sock = RT_NULL;
558 enum at_socket_state last_state;
559
560 /* deal with TCP server actively disconnect */
561 rt_thread_delay(rt_tick_from_millisecond(100));
562
563 sock = at_get_socket(socket);
564 if (sock == RT_NULL)
565 {
566 rt_set_errno(ENXIO);
567 return -1;
568 }
569
570 last_state = sock->state;
571
572 /* the rt_at_socket_close is need some time, so change state in advance */
573 sock->state = AT_SOCKET_CLOSED;
574
575 if (last_state != AT_SOCKET_CLOSED)
576 {
577 if (sock->ops->at_closesocket(sock) != 0)
578 {
579 free_socket(sock);
580 rt_set_errno(EIO);
581 return -1;
582 }
583 }
584
585 free_socket(sock);
586 return 0;
587 }
588
at_shutdown(int socket,int how)589 int at_shutdown(int socket, int how)
590 {
591 struct at_socket *sock = RT_NULL;
592 enum at_socket_state last_state;
593
594 sock = at_get_socket(socket);
595 if (sock == RT_NULL)
596 {
597 rt_set_errno(ENXIO);
598 return -1;
599 }
600
601 last_state = sock->state;
602
603 /* the rt_at_socket_close is need some time, so change state in advance */
604 sock->state = AT_SOCKET_CLOSED;
605
606 if (last_state != AT_SOCKET_CLOSED)
607 {
608 if (sock->ops->at_closesocket(sock) != 0)
609 {
610 free_socket(sock);
611 rt_set_errno(EIO);
612 return -1;
613 }
614 }
615
616 free_socket(sock);
617 return 0;
618 }
619
620 /* get IP address and port by socketaddr structure information */
socketaddr_to_ipaddr_port(const struct sockaddr * sockaddr,ip_addr_t * addr,uint16_t * port)621 static int socketaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t *addr, uint16_t *port)
622 {
623 const struct sockaddr_in* sin = (const struct sockaddr_in*) (const void *) sockaddr;
624
625 #if NETDEV_IPV4 && NETDEV_IPV6
626 addr->u_addr.ip4.addr = sin->sin_addr.s_addr;
627 addr->type = IPADDR_TYPE_V4;
628 #elif NETDEV_IPV4
629 addr->addr = sin->sin_addr.s_addr;
630 #elif NETDEV_IPV6
631 #error "not support IPV6."
632 #endif /* NETDEV_IPV4 && NETDEV_IPV6 */
633
634 *port = (uint16_t) HTONS_PORT(sin->sin_port);
635
636 return 0;
637 }
638
639 #ifdef AT_USING_SOCKET_SERVER
640 /* set socketaddr structure information by IP address and port */
ipaddr_port_to_socketaddr(struct sockaddr * sockaddr,ip_addr_t * addr,uint16_t * port)641 static int ipaddr_port_to_socketaddr(struct sockaddr *sockaddr, ip_addr_t *addr, uint16_t *port)
642 {
643 struct sockaddr_in* sin = (struct sockaddr_in*) (void *) sockaddr;
644
645 #if NETDEV_IPV4 && NETDEV_IPV6
646 sin->sin_addr.s_addr = addr->u_addr.ip4.addr;
647 #elif NETDEV_IPV4
648 sin->sin_addr.s_addr = addr->addr;
649 #elif NETDEV_IPV6
650 #error "not support IPV6."
651 #endif /* NETDEV_IPV4 && NETDEV_IPV6 */
652
653 sin->sin_port = (uint16_t) HTONS_PORT(*port);
654
655 return 0;
656 }
657 #endif
658
at_bind(int socket,const struct sockaddr * name,socklen_t namelen)659 int at_bind(int socket, const struct sockaddr *name, socklen_t namelen)
660 {
661 struct at_socket *sock = RT_NULL;
662 struct at_device *device = RT_NULL;
663 ip_addr_t input_ipaddr, local_ipaddr;
664 uint16_t port = 0;
665
666 if (name == NULL || namelen == 0)
667 {
668 rt_set_errno(EINVAL);
669 return -1;
670 }
671
672 sock = at_get_socket(socket);
673 if (sock == RT_NULL)
674 {
675 rt_set_errno(ENXIO);
676 return -1;
677 }
678
679 /* get current device ip address */
680 device = (struct at_device *) sock->device;
681 ip_addr_copy(local_ipaddr, device->netdev->ip_addr);
682
683 /* prase ip address and port from sockaddr structure */
684 socketaddr_to_ipaddr_port(name, &input_ipaddr, &port);
685
686 /* input ip address is different from device ip address */
687 if (ip_addr_cmp(&input_ipaddr, &local_ipaddr) != 0)
688 {
689 struct at_socket *new_sock = RT_NULL;
690 struct at_device *new_device = RT_NULL;
691 enum at_socket_type type = sock->type;
692
693 /* close old socket */
694 if (at_closesocket(socket) < 0)
695 {
696 free_socket(sock);
697 rt_set_errno(EIO);
698 return -1;
699 }
700
701 extern struct at_device *at_device_get_by_ipaddr(ip_addr_t *ip_addr);
702 new_device = at_device_get_by_ipaddr(&input_ipaddr);
703 if (new_device == RT_NULL)
704 {
705 rt_set_errno(EHOSTUNREACH);
706 return -1;
707 }
708
709 /* allocate new socket */
710 new_sock = alloc_socket_by_device(new_device, type);
711 if (new_sock == RT_NULL)
712 {
713 rt_set_errno(EIO);
714 return -1;
715 }
716 new_sock->type = type;
717 new_sock->state = AT_SOCKET_OPEN;
718 }
719
720 #ifdef AT_USING_SOCKET_SERVER
721 /* store 'port' into at_socket */
722 sock->listen.port = port;
723 #endif
724
725 return 0;
726 }
727
728 /* ipaddr structure change to IP address */
ipaddr_to_ipstr(const struct sockaddr * sockaddr,char * ipstr)729 static int ipaddr_to_ipstr(const struct sockaddr *sockaddr, char *ipstr)
730 {
731 struct sockaddr_in *sin = (struct sockaddr_in *) sockaddr;
732
733 /* change network ip_addr to ip string */
734 rt_snprintf(ipstr, 16, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr));
735
736 return 0;
737 }
738
739 #ifdef AT_USING_SOCKET_SERVER
at_connect_notice_cb(struct at_socket * sock,at_socket_evt_t event,const char * buff,size_t bfsz)740 static void at_connect_notice_cb(struct at_socket *sock, at_socket_evt_t event, const char *buff, size_t bfsz)
741 {
742 RT_ASSERT(buff);
743 RT_ASSERT(sock == RT_NULL);
744 RT_ASSERT(event == AT_SOCKET_EVT_CONNECTED);
745
746 int new_socket;
747 struct at_socket *new_sock = RT_NULL;
748 rt_base_t level;
749 rt_slist_t *node = RT_NULL;
750 struct at_socket *at_sock = RT_NULL;
751 char *socket_info = RT_NULL;
752 int base_socket = 0;
753
754 /* avoid use bottom driver to alloc "socket" */
755 new_socket = at_socket(AF_AT, SOCK_STREAM, 0);
756 if (new_socket == -1)
757 {
758 return;
759 }
760 new_sock = at_get_socket(new_socket);
761 new_sock->state = AT_SOCKET_CONNECT;
762 rt_sscanf(buff, "SOCKET:%d", &base_socket);
763 LOG_D("ACCEPT BASE SOCKET: %d", base_socket);
764 new_sock->user_data = (void *)base_socket;
765
766 /* find out the listen socket */
767 level = rt_hw_interrupt_disable();
768 rt_slist_for_each(node, &_socket_list)
769 {
770 at_sock = rt_slist_entry(node, struct at_socket, list);
771 if (at_sock && at_sock->magic == AT_SOCKET_MAGIC && at_sock->listen.is_listen == RT_TRUE)
772 {
773 break;
774 }
775 at_sock = RT_NULL;
776 }
777 rt_hw_interrupt_enable(level);
778
779 if (at_sock == RT_NULL)
780 {
781 at_closesocket(new_socket);
782 return;
783 }
784
785 /* put incoming "socket" to the listen socket receiver packet list */
786 socket_info = rt_malloc(AT_SOCKET_INFO_LEN);
787 rt_memset(socket_info, 0, AT_SOCKET_INFO_LEN);
788 rt_sprintf(socket_info, "SOCKET:%d", new_sock->socket);
789
790 /* wakeup the "accept" function */
791 rt_mutex_take(at_sock->recv_lock, RT_WAITING_FOREVER);
792 if (at_recvpkt_put(&(at_sock->recvpkt_list), socket_info, AT_SOCKET_INFO_LEN) != RT_EOK)
793 {
794 at_closesocket(new_socket);
795 rt_free(socket_info);
796 rt_mutex_release(at_sock->recv_lock);
797 return;
798 }
799 rt_mutex_release(at_sock->recv_lock);
800 rt_sem_release(at_sock->recv_notice);
801
802 at_do_event_changes(at_sock, AT_EVENT_RECV, RT_TRUE);
803 }
804 #endif
805
at_recv_notice_cb(struct at_socket * sock,at_socket_evt_t event,const char * buff,size_t bfsz)806 static void at_recv_notice_cb(struct at_socket *sock, at_socket_evt_t event, const char *buff, size_t bfsz)
807 {
808 RT_ASSERT(buff);
809 RT_ASSERT(event == AT_SOCKET_EVT_RECV);
810
811 /* check the socket object status */
812 if (sock->magic != AT_SOCKET_MAGIC || sock->state == AT_SOCKET_CLOSED)
813 {
814 rt_free((void *)buff);
815 return;
816 }
817
818 /* put receive buffer to receiver packet list */
819 rt_mutex_take(sock->recv_lock, RT_WAITING_FOREVER);
820 if (at_recvpkt_put(&(sock->recvpkt_list), buff, bfsz) != RT_EOK)
821 {
822 rt_free((void *)buff);
823 rt_mutex_release(sock->recv_lock);
824 return;
825 }
826 rt_mutex_release(sock->recv_lock);
827
828 rt_sem_release(sock->recv_notice);
829
830 at_do_event_changes(sock, AT_EVENT_RECV, RT_TRUE);
831 }
832
at_closed_notice_cb(struct at_socket * sock,at_socket_evt_t event,const char * buff,size_t bfsz)833 static void at_closed_notice_cb(struct at_socket *sock, at_socket_evt_t event, const char *buff, size_t bfsz)
834 {
835 RT_ASSERT(event == AT_SOCKET_EVT_CLOSED);
836
837 /* check the socket object status */
838 if (sock->magic != AT_SOCKET_MAGIC)
839 {
840 return;
841 }
842
843 at_do_event_changes(sock, AT_EVENT_RECV, RT_TRUE);
844 at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE);
845
846 sock->state = AT_SOCKET_CLOSED;
847 rt_sem_release(sock->recv_notice);
848 }
849
850 #ifdef AT_USING_SOCKET_SERVER
at_listen(int socket,int backlog)851 int at_listen(int socket, int backlog)
852 {
853 struct at_socket *sock = RT_NULL;
854 int result = 0;
855
856 sock = at_get_socket(socket);
857 if (sock == RT_NULL)
858 {
859 rt_set_errno(ENXIO);
860 return -1;
861 }
862
863 if (sock->state != AT_SOCKET_OPEN)
864 {
865 LOG_E("Socket(%d) connect state is %d.", sock->socket, sock->state);
866 rt_set_errno(ENETUNREACH);
867 result = -1;
868 goto __exit;
869 }
870
871 if (sock->ops->at_listen(sock, backlog) < 0)
872 {
873 rt_set_errno(EIO);
874 result = -1;
875 goto __exit;
876 }
877
878 sock->listen.is_listen = RT_TRUE;
879 sock->state = AT_SOCKET_LISTEN;
880
881 __exit:
882 if (result < 0)
883 {
884 at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE);
885 }
886
887 return result;
888 }
889 #endif
890
at_connect(int socket,const struct sockaddr * name,socklen_t namelen)891 int at_connect(int socket, const struct sockaddr *name, socklen_t namelen)
892 {
893 struct at_socket *sock = RT_NULL;
894 ip_addr_t remote_addr;
895 uint16_t remote_port = 0;
896 char ipstr[16] = { 0 };
897 int result = 0;
898
899 if (name == RT_NULL || namelen == 0)
900 {
901 rt_set_errno(EINVAL);
902 return -1;
903 }
904
905 sock = at_get_socket(socket);
906 if (sock == RT_NULL)
907 {
908 rt_set_errno(ENXIO);
909 return -1;
910 }
911
912 if (sock->state != AT_SOCKET_OPEN)
913 {
914 LOG_E("Socket(%d) connect state is %d.", sock->socket, sock->state);
915 rt_set_errno(EPERM);
916 result = -1;
917 goto __exit;
918 }
919
920 /* get IP address and port by socketaddr structure */
921 socketaddr_to_ipaddr_port(name, &remote_addr, &remote_port);
922 ipaddr_to_ipstr(name, ipstr);
923
924 if (sock->ops->at_connect(sock, ipstr, remote_port, sock->type, RT_TRUE) < 0)
925 {
926 rt_set_errno(EIO);
927 result = -1;
928 goto __exit;
929 }
930
931 sock->state = AT_SOCKET_CONNECT;
932
933 __exit:
934 if (result < 0)
935 {
936 at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE);
937 }
938 else
939 {
940 at_do_event_changes(sock, AT_EVENT_SEND, RT_TRUE);
941 }
942
943 return result;
944 }
945
946 #ifdef AT_USING_SOCKET_SERVER
at_accept(int socket,struct sockaddr * name,socklen_t * namelen)947 int at_accept(int socket, struct sockaddr *name, socklen_t *namelen)
948 {
949 struct at_socket *sock = RT_NULL;
950 struct at_socket *new_sock = RT_NULL;
951 char receive_buff[AT_SOCKET_INFO_LEN];
952 ip_addr_t remote_addr;
953 uint16_t remote_port = 0;
954 int new_socket = -1;
955 int result = 0;
956
957 sock = at_get_socket(socket);
958 if (sock == RT_NULL)
959 {
960 rt_set_errno(ENXIO);
961 return -1;
962 }
963
964 if (sock->state != AT_SOCKET_LISTEN)
965 {
966 LOG_E("Socket(%d) connect state is %d.", sock->socket, sock->state);
967 rt_set_errno(EIO);
968 result = -1;
969 goto __exit;
970 }
971
972 /* wait the receive semaphore, waiting for info */
973 if (rt_sem_take(sock->recv_notice, RT_WAITING_FOREVER) != RT_EOK)
974 {
975 rt_set_errno(EAGAIN);
976 result = -1;
977 goto __exit;
978 }
979 else
980 {
981 /* get receive buffer to receiver ring buffer */
982 rt_mutex_take(sock->recv_lock, RT_WAITING_FOREVER);
983 at_recvpkt_get(&(sock->recvpkt_list), (char *) &receive_buff, AT_SOCKET_INFO_LEN);
984 rt_mutex_release(sock->recv_lock);
985 at_do_event_changes(sock, AT_EVENT_RECV, RT_FALSE);
986 }
987
988 rt_sscanf(&receive_buff[0], "SOCKET:%d", &new_socket);
989 new_sock = at_get_socket(new_socket);
990 ip4_addr_set_any(&remote_addr);
991 ipaddr_port_to_socketaddr(name, &remote_addr, &remote_port);
992 LOG_D("Accept: [socket :%d, base_socket:%d]", new_socket, (int)new_sock->user_data);
993
994 __exit:
995 if (result < 0)
996 {
997 at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE);
998 }
999
1000 return new_sock->socket;
1001 }
1002 #endif
1003
at_recvfrom(int socket,void * mem,size_t len,int flags,struct sockaddr * from,socklen_t * fromlen)1004 int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
1005 {
1006 struct at_socket *sock = RT_NULL;
1007 int timeout, result = 0;
1008 size_t recv_len = 0;
1009
1010 if (mem == RT_NULL || len == 0)
1011 {
1012 /* if the requested number of bytes to receive from a stream socket was 0. */
1013 rt_set_errno(EFAULT);
1014 return -1;
1015 }
1016
1017 sock = at_get_socket(socket);
1018 if (sock == RT_NULL)
1019 {
1020 rt_set_errno(ENXIO);
1021 return -1;
1022 }
1023
1024 /* if the socket type is UDP, need to connect socket first */
1025 if (sock->type == AT_SOCKET_UDP)
1026 {
1027 if (from == RT_NULL || fromlen == 0)
1028 {
1029 rt_set_errno(EFAULT);
1030 return -1;
1031 }
1032
1033 if(sock->state == AT_SOCKET_CONNECT && rt_memcmp(&sock->last_udp_adr, from, sizeof(struct sockaddr)) != 0)
1034 {
1035 if (sock->ops->at_closesocket(sock) != 0)
1036 {
1037 free_socket(sock);
1038 rt_set_errno(EIO);
1039 goto __exit;
1040 }
1041 sock->state = AT_SOCKET_OPEN;
1042 }
1043
1044 if (sock->state == AT_SOCKET_OPEN)
1045 {
1046 ip_addr_t remote_addr;
1047 uint16_t remote_port = 0;
1048 char ipstr[16] = { 0 };
1049
1050 socketaddr_to_ipaddr_port(from, &remote_addr, &remote_port);
1051 ipaddr_to_ipstr(from, ipstr);
1052
1053 if (sock->ops->at_connect(sock, ipstr, remote_port, sock->type, RT_TRUE) < 0)
1054 {
1055 at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE);
1056 rt_set_errno(EIO);
1057 /* socket shutdown */
1058 goto __exit;
1059 }
1060
1061 rt_memcpy(&sock->last_udp_adr, from, sizeof(struct sockaddr));
1062 sock->state = AT_SOCKET_CONNECT;
1063 }
1064 }
1065
1066 while (1)
1067 {
1068 /* receive packet list last transmission of remaining data */
1069 rt_mutex_take(sock->recv_lock, RT_WAITING_FOREVER);
1070 recv_len = at_recvpkt_get(&(sock->recvpkt_list), (char *)mem, len);
1071 rt_mutex_release(sock->recv_lock);
1072 if (recv_len > 0)
1073 {
1074 if (rt_slist_isempty(&sock->recvpkt_list))
1075 {
1076 at_do_event_clean(sock, AT_EVENT_RECV);
1077 }
1078 result = recv_len;
1079 goto __exit;
1080 }
1081
1082 if (sock->state == AT_SOCKET_CLOSED)
1083 {
1084 /* socket passively closed, receive function return 0 */
1085 result = 0;
1086 goto __exit;
1087 }
1088
1089 if (flags & MSG_DONTWAIT)
1090 {
1091 rt_set_errno(EAGAIN);
1092 result = -1;
1093 goto __exit;
1094 }
1095
1096 /* set AT socket receive timeout */
1097 if (sock->recv_timeout == 0)
1098 {
1099 timeout = RT_WAITING_FOREVER;
1100 }
1101 else
1102 {
1103 timeout = rt_tick_from_millisecond(sock->recv_timeout);
1104 }
1105 if (rt_sem_take(sock->recv_notice, timeout) != RT_EOK)
1106 {
1107 LOG_D("AT socket (%d) receive timeout (%d)!", socket, timeout);
1108 rt_set_errno(EAGAIN);
1109 result = -1;
1110 goto __exit;
1111 }
1112 }
1113
1114 __exit:
1115 if (result <= 0)
1116 {
1117 at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE);
1118 }
1119
1120 return result;
1121 }
1122
at_recv(int s,void * mem,size_t len,int flags)1123 int at_recv(int s, void *mem, size_t len, int flags)
1124 {
1125 return at_recvfrom(s, mem, len, flags, RT_NULL, RT_NULL);
1126 }
1127
at_sendto(int socket,const void * data,size_t size,int flags,const struct sockaddr * to,socklen_t tolen)1128 int at_sendto(int socket, const void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)
1129 {
1130 struct at_socket *sock = RT_NULL;
1131 int len = 0, result = 0;
1132
1133 if (data == RT_NULL || size == 0)
1134 {
1135 LOG_E("AT sendto input data or size error!");
1136 rt_set_errno(EFAULT);
1137 return -1;
1138 }
1139
1140 sock = at_get_socket(socket);
1141 if (sock == RT_NULL)
1142 {
1143 rt_set_errno(ENXIO);
1144 return -1;
1145 }
1146
1147 switch (sock->type)
1148 {
1149 case AT_SOCKET_TCP:
1150 if (sock->state == AT_SOCKET_CLOSED)
1151 {
1152 /* socket passively closed, transmit function return 0 */
1153 result = 0;
1154 goto __exit;
1155 }
1156 else if (sock->state != AT_SOCKET_CONNECT)
1157 {
1158 LOG_E("send data error, current socket (%d) state (%d) is error.", socket, sock->state);
1159 rt_set_errno(ENETUNREACH);
1160 result = -1;
1161 goto __exit;
1162 }
1163
1164 if ((len = sock->ops->at_send(sock, (const char *) data, size, sock->type)) < 0)
1165 {
1166 rt_set_errno(EIO);
1167 result = -1;
1168 goto __exit;
1169 }
1170 break;
1171
1172 case AT_SOCKET_UDP:
1173 if (to == RT_NULL || tolen == 0)
1174 {
1175 rt_set_errno(EFAULT);
1176 result = -1;
1177 goto __exit;
1178 }
1179
1180 /* Inconsistent with the last UDP sending address, reconnect to a new address */
1181 if(sock->state == AT_SOCKET_CONNECT && rt_memcmp(&sock->last_udp_adr, to, sizeof(struct sockaddr)) != 0)
1182 {
1183 if (sock->ops->at_closesocket(sock) != 0)
1184 {
1185 free_socket(sock);
1186 rt_set_errno(EIO);
1187 goto __exit;
1188 }
1189 sock->state = AT_SOCKET_OPEN;
1190 }
1191
1192 if (sock->state == AT_SOCKET_OPEN)
1193 {
1194 ip_addr_t remote_addr;
1195 uint16_t remote_port = 0;
1196 char ipstr[16] = { 0 };
1197
1198 socketaddr_to_ipaddr_port(to, &remote_addr, &remote_port);
1199 ipaddr_to_ipstr(to, ipstr);
1200
1201 if (sock->ops->at_connect(sock, ipstr, remote_port, sock->type, RT_TRUE) < 0)
1202 {
1203 rt_set_errno(EIO);
1204 result = -1;
1205 goto __exit;
1206 }
1207
1208 rt_memcpy(&sock->last_udp_adr, to, sizeof(struct sockaddr));
1209 sock->state = AT_SOCKET_CONNECT;
1210 }
1211
1212 if ((len = sock->ops->at_send(sock, (char *) data, size, sock->type)) < 0)
1213 {
1214 rt_set_errno(EIO);
1215 result = -1;
1216 goto __exit;
1217 }
1218 break;
1219
1220 default:
1221 LOG_E("Socket (%d) type %d is not support.", socket, sock->type);
1222 rt_set_errno(EPERM);
1223 result = -1;
1224 goto __exit;
1225 }
1226
1227 __exit:
1228 if (result < 0)
1229 {
1230 at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE);
1231 }
1232 else
1233 {
1234 result = len;
1235 }
1236
1237 return result;
1238 }
1239
at_send(int socket,const void * data,size_t size,int flags)1240 int at_send(int socket, const void *data, size_t size, int flags)
1241 {
1242 return at_sendto(socket, data, size, flags, RT_NULL, 0);
1243 }
1244
at_getsockopt(int socket,int level,int optname,void * optval,socklen_t * optlen)1245 int at_getsockopt(int socket, int level, int optname, void *optval, socklen_t *optlen)
1246 {
1247 struct at_socket *sock;
1248 int32_t timeout;
1249
1250 if (optval == RT_NULL || optlen == RT_NULL)
1251 {
1252 LOG_E("AT getsocketopt input option value or option length error!");
1253 rt_set_errno(EFAULT);
1254 return -1;
1255 }
1256
1257 sock = at_get_socket(socket);
1258 if (sock == RT_NULL)
1259 {
1260 rt_set_errno(ENXIO);
1261 return -1;
1262 }
1263
1264 switch (level)
1265 {
1266 case SOL_SOCKET:
1267 switch (optname)
1268 {
1269 case SO_RCVTIMEO:
1270 timeout = sock->recv_timeout;
1271 ((struct timeval *)(optval))->tv_sec = (timeout) / 1000U;
1272 ((struct timeval *)(optval))->tv_usec = (timeout % 1000U) * 1000U;
1273 break;
1274
1275 case SO_SNDTIMEO:
1276 timeout = sock->send_timeout;
1277 ((struct timeval *) optval)->tv_sec = timeout / 1000U;
1278 ((struct timeval *) optval)->tv_usec = (timeout % 1000U) * 1000U;
1279 break;
1280
1281 default:
1282 LOG_E("AT socket (%d) not support option name : %d.", socket, optname);
1283 rt_set_errno(EPERM);
1284 return -1;
1285 }
1286 break;
1287
1288 default:
1289 LOG_E("AT socket (%d) not support option level : %d.", socket, level);
1290 rt_set_errno(EPERM);
1291 return -1;
1292 }
1293
1294 return 0;
1295 }
1296
at_setsockopt(int socket,int level,int optname,const void * optval,socklen_t optlen)1297 int at_setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen)
1298 {
1299 struct at_socket *sock;
1300
1301 if (optval == RT_NULL)
1302 {
1303 LOG_E("AT setsockopt input option value error!");
1304 rt_set_errno(EFAULT);
1305 return -1;
1306 }
1307
1308 sock = at_get_socket(socket);
1309 if (sock == RT_NULL)
1310 {
1311 rt_set_errno(ENXIO);
1312 return -1;
1313 }
1314
1315 switch (level)
1316 {
1317 case SOL_SOCKET:
1318 switch (optname)
1319 {
1320 case SO_RCVTIMEO:
1321 sock->recv_timeout = ((const struct timeval *) optval)->tv_sec * 1000
1322 + ((const struct timeval *) optval)->tv_usec / 1000;
1323 break;
1324
1325 case SO_SNDTIMEO:
1326 sock->send_timeout = ((const struct timeval *) optval)->tv_sec * 1000
1327 + ((const struct timeval *) optval)->tv_usec / 1000;
1328 break;
1329
1330 default:
1331 LOG_E("AT socket (%d) not support option name : %d.", socket, optname);
1332 rt_set_errno(EPERM);
1333 return -1;
1334 }
1335 break;
1336 case IPPROTO_TCP:
1337 switch (optname)
1338 {
1339 case TCP_NODELAY:
1340 break;
1341 }
1342 break;
1343 default:
1344 LOG_E("AT socket (%d) not support option level : %d.", socket, level);
1345 rt_set_errno(EPERM);
1346 return -1;
1347 }
1348
1349 return 0;
1350 }
1351
ipstr_atol(const char * nptr)1352 static uint32_t ipstr_atol(const char* nptr)
1353 {
1354 uint32_t total = 0;
1355 char sign = '+';
1356 /* jump space */
1357 while (isspace(*nptr))
1358 {
1359 ++nptr;
1360 }
1361 if (*nptr == '-' || *nptr == '+')
1362 {
1363 sign = *nptr++;
1364 }
1365 while (isdigit(*nptr))
1366 {
1367 total = 10 * total + ((*nptr++) - '0');
1368 }
1369 return (sign == '-') ? -total : total;
1370 }
1371
1372 /* IP address to unsigned int type */
ipstr_to_u32(char * ipstr)1373 static uint32_t ipstr_to_u32(char *ipstr)
1374 {
1375 char ipBytes[4] = { 0 };
1376 uint32_t i;
1377
1378 for (i = 0; i < 4; i++, ipstr++)
1379 {
1380 ipBytes[i] = (char) ipstr_atol(ipstr);
1381 if ((ipstr = strchr(ipstr, '.')) == RT_NULL)
1382 {
1383 break;
1384 }
1385 }
1386 return *(uint32_t *) ipBytes;
1387 }
1388
1389 /**
1390 * @brief resolves a domain name via AT device and returns its IP address.
1391 * @note function uses static global mutex internally, which will cause multiple AT devices to block and wait while performing DNS resolution.
1392 * @param name Pointer to a string containing the domain name.
1393 * @param addr Pointer to a structure where the IP address information is stored.
1394 * @return int Returns 0 on success or -1/-2 on failure
1395 * -1: domain failed
1396 * -2: HOST_NOT_FOUND
1397 */
_gethostbyname_by_device(const char * name,ip_addr_t * addr)1398 static int _gethostbyname_by_device(const char *name, ip_addr_t *addr)
1399 {
1400 static rt_mutex_t at_dlock = RT_NULL;
1401
1402 struct at_device *device = RT_NULL;
1403 char ipstr[16] = { 0 };
1404 size_t idx = 0;
1405
1406 device = at_device_get_first_initialized();
1407 if (device == RT_NULL)
1408 {
1409 return -1;
1410 }
1411
1412 if (!netdev_is_link_up(device->netdev))
1413 {
1414 return -1;
1415 }
1416
1417 for (idx = 0; idx < strlen(name) && !isalpha(name[idx]); idx++);
1418
1419 if (idx < strlen(name))
1420 {
1421 if (at_dlock == RT_NULL)
1422 {
1423 at_dlock = rt_mutex_create("at_dlock", RT_IPC_FLAG_PRIO);
1424 if (at_dlock == RT_NULL)
1425 {
1426 return -1;
1427 }
1428 }
1429
1430 rt_mutex_take(at_dlock, RT_WAITING_FOREVER);
1431 if (device->class->socket_ops->at_domain_resolve(name, ipstr) < 0)
1432 {
1433 rt_mutex_release(at_dlock);
1434 return -2;
1435 }
1436 rt_mutex_release(at_dlock);
1437 }
1438 else
1439 {
1440 strncpy(ipstr, name, strlen(name));
1441 }
1442
1443 #if NETDEV_IPV4 && NETDEV_IPV6
1444 addr.type = IPADDR_TYPE_V4;
1445 if (inet_aton(ipstr, addr) == 0)
1446 {
1447 return -1;
1448 }
1449 #elif NETDEV_IPV4
1450 if (inet_aton(ipstr, addr) == 0)
1451 {
1452 return -1;
1453 }
1454 #elif NETDEV_IPV6
1455 #error "not support IPV6."
1456 #endif /* NETDEV_IPV4 && NETDEV_IPV6 */
1457
1458 return 0;
1459 }
1460
at_gethostbyname(const char * name)1461 struct hostent *at_gethostbyname(const char *name)
1462 {
1463 ip_addr_t addr = {0};
1464 /* buffer variables for at_gethostbyname() */
1465 static struct hostent s_hostent;
1466 static char *s_aliases;
1467 static ip_addr_t s_hostent_addr;
1468 static ip_addr_t *s_phostent_addr[2];
1469 static char s_hostname[DNS_MAX_NAME_LENGTH + 1];
1470
1471 if (name == RT_NULL)
1472 {
1473 LOG_E("AT gethostbyname input name error!");
1474 return RT_NULL;
1475 }
1476
1477 if (strlen(name) > DNS_MAX_NAME_LENGTH)
1478 {
1479 return RT_NULL;
1480 }
1481
1482 if (_gethostbyname_by_device(name, &addr) != 0)
1483 {
1484 return RT_NULL;
1485 }
1486
1487 /* fill hostent structure */
1488 s_hostent_addr = addr;
1489 s_phostent_addr[0] = &s_hostent_addr;
1490 s_phostent_addr[1] = RT_NULL;
1491 strncpy(s_hostname, name, strlen(name));
1492 s_hostname[strlen(name)] = 0;
1493 s_aliases = RT_NULL;
1494
1495 s_hostent.h_name = s_hostname;
1496 s_hostent.h_aliases = &s_aliases;
1497 s_hostent.h_addrtype = AF_AT;
1498 s_hostent.h_length = sizeof(ip_addr_t);
1499 s_hostent.h_addr_list = (char**) &s_phostent_addr;
1500
1501 return &s_hostent;
1502 }
1503
at_gethostbyname_r(const char * name,struct hostent * ret,char * buf,size_t buflen,struct hostent ** result,int * h_errnop)1504 int at_gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop)
1505 {
1506 struct gethostbyname_r_helper
1507 {
1508 ip_addr_t *addr_list[2];
1509 ip_addr_t addr;
1510 char *aliases;
1511 };
1512
1513 char *hostname = RT_NULL;
1514 int lh_errno = 0;
1515 int domain_err = 0;
1516 size_t namelen = 0;
1517 struct gethostbyname_r_helper *h = RT_NULL;
1518
1519 if (h_errnop == RT_NULL)
1520 {
1521 h_errnop = &lh_errno;
1522 }
1523
1524 if ((name == RT_NULL) || (ret == RT_NULL) || (buf == RT_NULL))
1525 {
1526 *h_errnop = EINVAL;
1527 return -1;
1528 }
1529
1530 if (result == RT_NULL)
1531 {
1532 *h_errnop = EINVAL;
1533 return -1;
1534 }
1535
1536 *result = RT_NULL;
1537
1538 namelen = strlen(name);
1539 if (buflen < (sizeof(struct gethostbyname_r_helper) + (namelen + 1)))
1540 {
1541 *h_errnop = ERANGE;
1542 return -1;
1543 }
1544
1545 h = (struct gethostbyname_r_helper *)buf;
1546 hostname = ((char *)h) + sizeof(struct gethostbyname_r_helper);
1547
1548 domain_err = _gethostbyname_by_device(name, &h->addr);
1549 if (domain_err != 0)
1550 {
1551 if (domain_err == -2)
1552 {
1553 *h_errnop = HOST_NOT_FOUND;
1554 }
1555
1556 *h_errnop = NO_DATA;
1557 return -1;
1558 }
1559
1560 rt_memcpy(hostname, name, namelen);
1561 hostname[namelen] = 0;
1562
1563 h->addr_list[0] = &h->addr;
1564 h->addr_list[1] = NULL;
1565 h->aliases = NULL;
1566
1567 ret->h_name = hostname;
1568 ret->h_aliases = &h->aliases;
1569 ret->h_addrtype = AF_INET;
1570 ret->h_length = sizeof(ip_addr_t);
1571 ret->h_addr_list = (char **)&h->addr_list;
1572
1573 *result = ret;
1574 return 0;
1575 }
1576
at_getaddrinfo(const char * nodename,const char * servname,const struct addrinfo * hints,struct addrinfo ** res)1577 int at_getaddrinfo(const char *nodename, const char *servname,
1578 const struct addrinfo *hints, struct addrinfo **res)
1579 {
1580 int port_nr = 0;
1581 ip_addr_t addr = {0};
1582 struct addrinfo *ai;
1583 struct sockaddr_storage *sa;
1584 size_t total_size = 0;
1585 size_t namelen = 0;
1586 int ai_family = 0;
1587
1588 if (res == RT_NULL)
1589 {
1590 return EAI_FAIL;
1591 }
1592 *res = RT_NULL;
1593
1594 if ((nodename == RT_NULL) && (servname == RT_NULL))
1595 {
1596 return EAI_NONAME;
1597 }
1598
1599 if (hints != RT_NULL)
1600 {
1601 ai_family = hints->ai_family;
1602 if (hints->ai_family != AF_AT && hints->ai_family != AF_INET && hints->ai_family != AF_UNSPEC)
1603 {
1604 return EAI_FAMILY;
1605 }
1606 }
1607 else
1608 {
1609 ai_family = AF_UNSPEC;
1610 }
1611
1612 if (servname != RT_NULL)
1613 {
1614 /* service name specified: convert to port number */
1615 port_nr = atoi(servname);
1616 if ((port_nr <= 0) || (port_nr > 0xffff))
1617 {
1618 return EAI_SERVICE;
1619 }
1620 }
1621
1622 if (nodename != RT_NULL)
1623 {
1624 /* service location specified, try to resolve */
1625 if ((hints != RT_NULL) && (hints->ai_flags & AI_NUMERICHOST))
1626 {
1627 if (ai_family == AF_AT || ai_family == AF_INET)
1628 {
1629 return EAI_NONAME;
1630 }
1631
1632 /* no DNS lookup, just parse for an address string */
1633 if (!inet_aton(nodename, &addr))
1634 {
1635 return EAI_NONAME;
1636 }
1637
1638 }
1639 else
1640 {
1641 int domain_err = 0;
1642 domain_err = _gethostbyname_by_device(nodename, &addr);
1643 if (domain_err != 0)
1644 {
1645 if (domain_err == -2)
1646 {
1647 return HOST_NOT_FOUND;
1648 }
1649
1650 return NO_DATA;
1651 }
1652 }
1653 }
1654 else
1655 {
1656 /* service location specified, use loopback address */
1657 inet_aton("127.0.0.1", &addr);
1658 }
1659
1660 total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_storage);
1661 if (nodename != RT_NULL)
1662 {
1663 namelen = strlen(nodename);
1664 if (namelen == 0 || namelen > DNS_MAX_NAME_LENGTH)
1665 {
1666 /* invalid name length */
1667 return EAI_FAIL;
1668 }
1669
1670 total_size += namelen + 1;
1671 }
1672 /* If this fails, please report to lwip-devel! :-) */
1673 if (total_size > sizeof(struct addrinfo) + sizeof(struct sockaddr_storage) + DNS_MAX_NAME_LENGTH + 1)
1674 {
1675 return EAI_FAIL;
1676 }
1677
1678 ai = (struct addrinfo *) rt_malloc(total_size);
1679 if (ai == RT_NULL)
1680 {
1681 return EAI_MEMORY;
1682 }
1683 rt_memset(ai, RT_NULL, total_size);
1684 /* cast through void* to get rid of alignment warnings */
1685 sa = (struct sockaddr_storage *) (void *) ((uint8_t *) ai + sizeof(struct addrinfo));
1686 struct sockaddr_in *sa4 = (struct sockaddr_in *) sa;
1687 /* set up sockaddr */
1688 #if NETDEV_IPV4 && NETDEV_IPV6
1689 sa4->sin_addr.s_addr = addr.u_addr.ip4.addr;
1690 sa4->type = IPADDR_TYPE_V4;
1691 #elif NETDEV_IPV4
1692 sa4->sin_addr.s_addr = addr.addr;
1693 #elif NETDEV_IPV6
1694 #error "not support IPV6."
1695 #endif /* NETDEV_IPV4 && NETDEV_IPV6 */
1696 sa4->sin_family = AF_INET;
1697 sa4->sin_len = sizeof(struct sockaddr_in);
1698 sa4->sin_port = htons((uint16_t)port_nr);
1699 ai->ai_family = AF_INET;
1700
1701 /* set up addrinfo */
1702 if (hints != RT_NULL)
1703 {
1704 /* copy socktype & protocol from hints if specified */
1705 ai->ai_socktype = hints->ai_socktype;
1706 ai->ai_protocol = hints->ai_protocol;
1707 }
1708 if (nodename != RT_NULL)
1709 {
1710 /* copy nodename to canonname if specified */
1711 ai->ai_canonname = ((char *) ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_storage));
1712 rt_memcpy(ai->ai_canonname, nodename, namelen);
1713 ai->ai_canonname[namelen] = 0;
1714 }
1715 ai->ai_addrlen = sizeof(struct sockaddr_storage);
1716 ai->ai_addr = (struct sockaddr *) sa;
1717
1718 *res = ai;
1719
1720 return 0;
1721 }
1722
at_freeaddrinfo(struct addrinfo * ai)1723 void at_freeaddrinfo(struct addrinfo *ai)
1724 {
1725 struct addrinfo *next;
1726
1727 while (ai != NULL)
1728 {
1729 next = ai->ai_next;
1730 rt_free(ai);
1731 ai = next;
1732 }
1733 }
1734
1735 #endif /* AT_USING_SOCKET */
1736