1*10465441SEvalZero /*
2*10465441SEvalZero * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero *
4*10465441SEvalZero * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero *
6*10465441SEvalZero * Change Logs:
7*10465441SEvalZero * Date Author Notes
8*10465441SEvalZero * 2018-06-06 chenyong first version
9*10465441SEvalZero */
10*10465441SEvalZero
11*10465441SEvalZero #include <at.h>
12*10465441SEvalZero #include <stdlib.h>
13*10465441SEvalZero #include <string.h>
14*10465441SEvalZero #include <ctype.h>
15*10465441SEvalZero #include <sys/time.h>
16*10465441SEvalZero
17*10465441SEvalZero #include <at_socket.h>
18*10465441SEvalZero
19*10465441SEvalZero #ifdef SAL_USING_POSIX
20*10465441SEvalZero #include <dfs_poll.h>
21*10465441SEvalZero #endif
22*10465441SEvalZero
23*10465441SEvalZero #define LOG_TAG "at.skt"
24*10465441SEvalZero #include <at_log.h>
25*10465441SEvalZero
26*10465441SEvalZero #ifdef AT_USING_SOCKET
27*10465441SEvalZero
28*10465441SEvalZero #define HTONS_PORT(x) ((((x) & 0x00ffUL) << 8) | (((x) & 0xff00UL) >> 8))
29*10465441SEvalZero #define NIPQUAD(addr) \
30*10465441SEvalZero ((unsigned char *)&addr)[0], \
31*10465441SEvalZero ((unsigned char *)&addr)[1], \
32*10465441SEvalZero ((unsigned char *)&addr)[2], \
33*10465441SEvalZero ((unsigned char *)&addr)[3]
34*10465441SEvalZero
35*10465441SEvalZero #if !defined(AT_DEVICE_SOCKETS_NUM) || defined(AT_DEVICE_NOT_SELECTED)
36*10465441SEvalZero #error The AT socket device is not selected, please select it through the env menuconfig.
37*10465441SEvalZero #endif
38*10465441SEvalZero
39*10465441SEvalZero /* The maximum number of sockets structure */
40*10465441SEvalZero #ifndef AT_SOCKETS_NUM
41*10465441SEvalZero #define AT_SOCKETS_NUM AT_DEVICE_SOCKETS_NUM
42*10465441SEvalZero #endif
43*10465441SEvalZero
44*10465441SEvalZero typedef enum {
45*10465441SEvalZero AT_EVENT_SEND,
46*10465441SEvalZero AT_EVENT_RECV,
47*10465441SEvalZero AT_EVENT_ERROR,
48*10465441SEvalZero } at_event_t;
49*10465441SEvalZero
50*10465441SEvalZero /* the global array of available sockets */
51*10465441SEvalZero static struct at_socket sockets[AT_SOCKETS_NUM] = { 0 };
52*10465441SEvalZero /* AT device socket options */
53*10465441SEvalZero static struct at_device_ops *at_dev_ops = RT_NULL;
54*10465441SEvalZero
at_get_socket(int socket)55*10465441SEvalZero struct at_socket *at_get_socket(int socket)
56*10465441SEvalZero {
57*10465441SEvalZero if (socket < 0 || socket >= AT_SOCKETS_NUM)
58*10465441SEvalZero {
59*10465441SEvalZero return RT_NULL;
60*10465441SEvalZero }
61*10465441SEvalZero
62*10465441SEvalZero /* check socket structure valid or not */
63*10465441SEvalZero if (sockets[socket].magic != AT_SOCKET_MAGIC)
64*10465441SEvalZero {
65*10465441SEvalZero return RT_NULL;
66*10465441SEvalZero }
67*10465441SEvalZero
68*10465441SEvalZero return &sockets[socket];
69*10465441SEvalZero }
70*10465441SEvalZero
71*10465441SEvalZero /* get a block to the AT socket receive list*/
at_recvpkt_put(rt_slist_t * rlist,const char * ptr,size_t length)72*10465441SEvalZero static size_t at_recvpkt_put(rt_slist_t *rlist, const char *ptr, size_t length)
73*10465441SEvalZero {
74*10465441SEvalZero at_recv_pkt_t pkt;
75*10465441SEvalZero
76*10465441SEvalZero pkt = (at_recv_pkt_t) rt_calloc(1, sizeof(struct at_recv_pkt));
77*10465441SEvalZero if (pkt == RT_NULL)
78*10465441SEvalZero {
79*10465441SEvalZero LOG_E("No memory for receive packet table!");
80*10465441SEvalZero return 0;
81*10465441SEvalZero }
82*10465441SEvalZero
83*10465441SEvalZero pkt->bfsz_totle = length;
84*10465441SEvalZero pkt->bfsz_index = 0;
85*10465441SEvalZero pkt->buff = (char *) ptr;
86*10465441SEvalZero
87*10465441SEvalZero rt_slist_append(rlist, &pkt->list);
88*10465441SEvalZero
89*10465441SEvalZero return length;
90*10465441SEvalZero }
91*10465441SEvalZero
92*10465441SEvalZero /* delete and free all receive buffer list */
at_recvpkt_all_delete(rt_slist_t * rlist)93*10465441SEvalZero static int at_recvpkt_all_delete(rt_slist_t *rlist)
94*10465441SEvalZero {
95*10465441SEvalZero at_recv_pkt_t pkt;
96*10465441SEvalZero rt_slist_t *node;
97*10465441SEvalZero
98*10465441SEvalZero if(rt_slist_isempty(rlist))
99*10465441SEvalZero return 0;
100*10465441SEvalZero
101*10465441SEvalZero for(node = rt_slist_first(rlist); node; node = rt_slist_next(node))
102*10465441SEvalZero {
103*10465441SEvalZero pkt = rt_slist_entry(node, struct at_recv_pkt, list);
104*10465441SEvalZero if (pkt->buff)
105*10465441SEvalZero {
106*10465441SEvalZero rt_free(pkt->buff);
107*10465441SEvalZero }
108*10465441SEvalZero if(pkt)
109*10465441SEvalZero {
110*10465441SEvalZero rt_free(pkt);
111*10465441SEvalZero pkt = RT_NULL;
112*10465441SEvalZero }
113*10465441SEvalZero }
114*10465441SEvalZero
115*10465441SEvalZero return 0;
116*10465441SEvalZero }
117*10465441SEvalZero
118*10465441SEvalZero /* delete and free specified list block */
at_recvpkt_node_delete(rt_slist_t * rlist,rt_slist_t * node)119*10465441SEvalZero static int at_recvpkt_node_delete(rt_slist_t *rlist, rt_slist_t *node)
120*10465441SEvalZero {
121*10465441SEvalZero at_recv_pkt_t pkt;
122*10465441SEvalZero
123*10465441SEvalZero if(rt_slist_isempty(rlist))
124*10465441SEvalZero return 0;
125*10465441SEvalZero
126*10465441SEvalZero rt_slist_remove(rlist, node);
127*10465441SEvalZero
128*10465441SEvalZero pkt= rt_slist_entry(node, struct at_recv_pkt, list);
129*10465441SEvalZero if (pkt->buff)
130*10465441SEvalZero {
131*10465441SEvalZero rt_free(pkt->buff);
132*10465441SEvalZero }
133*10465441SEvalZero if (pkt)
134*10465441SEvalZero {
135*10465441SEvalZero rt_free(pkt);
136*10465441SEvalZero pkt = RT_NULL;
137*10465441SEvalZero }
138*10465441SEvalZero
139*10465441SEvalZero return 0;
140*10465441SEvalZero }
141*10465441SEvalZero
142*10465441SEvalZero /* get a block from AT socket receive list */
at_recvpkt_get(rt_slist_t * rlist,char * mem,size_t len)143*10465441SEvalZero static size_t at_recvpkt_get(rt_slist_t *rlist, char *mem, size_t len)
144*10465441SEvalZero {
145*10465441SEvalZero rt_slist_t *node;
146*10465441SEvalZero at_recv_pkt_t pkt;
147*10465441SEvalZero size_t content_pos = 0, page_pos = 0;
148*10465441SEvalZero
149*10465441SEvalZero if(rt_slist_isempty(rlist))
150*10465441SEvalZero return 0;
151*10465441SEvalZero
152*10465441SEvalZero for (node = rt_slist_first(rlist); node; node = rt_slist_next(node))
153*10465441SEvalZero {
154*10465441SEvalZero pkt = rt_slist_entry(node, struct at_recv_pkt, list);
155*10465441SEvalZero
156*10465441SEvalZero page_pos = pkt->bfsz_totle - pkt->bfsz_index;
157*10465441SEvalZero
158*10465441SEvalZero if (page_pos >= len - content_pos)
159*10465441SEvalZero {
160*10465441SEvalZero memcpy((char *) mem + content_pos, pkt->buff + pkt->bfsz_index, len - content_pos);
161*10465441SEvalZero pkt->bfsz_index += len - content_pos;
162*10465441SEvalZero if (pkt->bfsz_index == pkt->bfsz_totle)
163*10465441SEvalZero {
164*10465441SEvalZero at_recvpkt_node_delete(rlist, node);
165*10465441SEvalZero }
166*10465441SEvalZero content_pos = len;
167*10465441SEvalZero break;
168*10465441SEvalZero }
169*10465441SEvalZero else
170*10465441SEvalZero {
171*10465441SEvalZero memcpy((char *) mem + content_pos, pkt->buff + pkt->bfsz_index, page_pos);
172*10465441SEvalZero content_pos += page_pos;
173*10465441SEvalZero pkt->bfsz_index += page_pos;
174*10465441SEvalZero at_recvpkt_node_delete(rlist, node);
175*10465441SEvalZero }
176*10465441SEvalZero }
177*10465441SEvalZero
178*10465441SEvalZero return content_pos;
179*10465441SEvalZero }
180*10465441SEvalZero
at_do_event_changes(struct at_socket * sock,at_event_t event,rt_bool_t is_plus)181*10465441SEvalZero static void at_do_event_changes(struct at_socket *sock, at_event_t event, rt_bool_t is_plus)
182*10465441SEvalZero {
183*10465441SEvalZero switch (event)
184*10465441SEvalZero {
185*10465441SEvalZero case AT_EVENT_SEND:
186*10465441SEvalZero {
187*10465441SEvalZero if (is_plus)
188*10465441SEvalZero {
189*10465441SEvalZero sock->sendevent = 1;
190*10465441SEvalZero
191*10465441SEvalZero #ifdef SAL_USING_POSIX
192*10465441SEvalZero rt_wqueue_wakeup(&sock->wait_head, (void*) POLLOUT);
193*10465441SEvalZero #endif
194*10465441SEvalZero
195*10465441SEvalZero }
196*10465441SEvalZero else if (sock->sendevent)
197*10465441SEvalZero {
198*10465441SEvalZero sock->sendevent = 0;
199*10465441SEvalZero }
200*10465441SEvalZero break;
201*10465441SEvalZero }
202*10465441SEvalZero case AT_EVENT_RECV:
203*10465441SEvalZero {
204*10465441SEvalZero if (is_plus)
205*10465441SEvalZero {
206*10465441SEvalZero sock->rcvevent++;
207*10465441SEvalZero
208*10465441SEvalZero #ifdef SAL_USING_POSIX
209*10465441SEvalZero rt_wqueue_wakeup(&sock->wait_head, (void*) POLLIN);
210*10465441SEvalZero #endif
211*10465441SEvalZero
212*10465441SEvalZero }
213*10465441SEvalZero else if (sock->rcvevent)
214*10465441SEvalZero {
215*10465441SEvalZero sock->rcvevent --;
216*10465441SEvalZero }
217*10465441SEvalZero break;
218*10465441SEvalZero }
219*10465441SEvalZero case AT_EVENT_ERROR:
220*10465441SEvalZero {
221*10465441SEvalZero if (is_plus)
222*10465441SEvalZero {
223*10465441SEvalZero sock->errevent++;
224*10465441SEvalZero
225*10465441SEvalZero #ifdef SAL_USING_POSIX
226*10465441SEvalZero rt_wqueue_wakeup(&sock->wait_head, (void*) POLLERR);
227*10465441SEvalZero #endif
228*10465441SEvalZero
229*10465441SEvalZero }
230*10465441SEvalZero else if (sock->errevent)
231*10465441SEvalZero {
232*10465441SEvalZero sock->errevent --;
233*10465441SEvalZero }
234*10465441SEvalZero break;
235*10465441SEvalZero }
236*10465441SEvalZero default:
237*10465441SEvalZero LOG_E("Not supported event (%d)", event);
238*10465441SEvalZero }
239*10465441SEvalZero }
240*10465441SEvalZero
at_do_event_clean(struct at_socket * sock,at_event_t event)241*10465441SEvalZero static void at_do_event_clean(struct at_socket *sock, at_event_t event)
242*10465441SEvalZero {
243*10465441SEvalZero switch (event)
244*10465441SEvalZero {
245*10465441SEvalZero case AT_EVENT_SEND:
246*10465441SEvalZero {
247*10465441SEvalZero sock->sendevent = 0;
248*10465441SEvalZero break;
249*10465441SEvalZero }
250*10465441SEvalZero case AT_EVENT_RECV:
251*10465441SEvalZero {
252*10465441SEvalZero sock->rcvevent = 0;
253*10465441SEvalZero break;
254*10465441SEvalZero }
255*10465441SEvalZero case AT_EVENT_ERROR:
256*10465441SEvalZero {
257*10465441SEvalZero sock->errevent = 0;
258*10465441SEvalZero break;
259*10465441SEvalZero }
260*10465441SEvalZero default:
261*10465441SEvalZero LOG_E("Not supported event (%d)", event);
262*10465441SEvalZero }
263*10465441SEvalZero }
264*10465441SEvalZero
alloc_socket(void)265*10465441SEvalZero static struct at_socket *alloc_socket(void)
266*10465441SEvalZero {
267*10465441SEvalZero static rt_mutex_t at_slock = RT_NULL;
268*10465441SEvalZero char name[RT_NAME_MAX];
269*10465441SEvalZero struct at_socket *sock;
270*10465441SEvalZero int idx;
271*10465441SEvalZero
272*10465441SEvalZero if(at_slock == RT_NULL)
273*10465441SEvalZero {
274*10465441SEvalZero /* create AT socket lock */
275*10465441SEvalZero at_slock = rt_mutex_create("at_s", RT_IPC_FLAG_FIFO);
276*10465441SEvalZero if (at_slock == RT_NULL)
277*10465441SEvalZero {
278*10465441SEvalZero LOG_E("No memory for AT socket lock!");
279*10465441SEvalZero return RT_NULL;
280*10465441SEvalZero }
281*10465441SEvalZero }
282*10465441SEvalZero
283*10465441SEvalZero rt_mutex_take(at_slock, RT_WAITING_FOREVER);
284*10465441SEvalZero
285*10465441SEvalZero /* find an empty at socket entry */
286*10465441SEvalZero for (idx = 0; idx < AT_SOCKETS_NUM && sockets[idx].magic; idx++);
287*10465441SEvalZero
288*10465441SEvalZero /* can't find an empty protocol family entry */
289*10465441SEvalZero if (idx == AT_SOCKETS_NUM)
290*10465441SEvalZero {
291*10465441SEvalZero goto __err;
292*10465441SEvalZero }
293*10465441SEvalZero
294*10465441SEvalZero sock = &(sockets[idx]);
295*10465441SEvalZero sock->magic = AT_SOCKET_MAGIC;
296*10465441SEvalZero sock->socket = idx;
297*10465441SEvalZero sock->state = AT_SOCKET_NONE;
298*10465441SEvalZero sock->rcvevent = RT_NULL;
299*10465441SEvalZero sock->sendevent = RT_NULL;
300*10465441SEvalZero sock->errevent = RT_NULL;
301*10465441SEvalZero rt_slist_init(&sock->recvpkt_list);
302*10465441SEvalZero
303*10465441SEvalZero rt_snprintf(name, RT_NAME_MAX, "%s%d", "at_sr", idx);
304*10465441SEvalZero /* create AT socket receive mailbox */
305*10465441SEvalZero if ((sock->recv_notice = rt_sem_create(name, 0, RT_IPC_FLAG_FIFO)) == RT_NULL)
306*10465441SEvalZero {
307*10465441SEvalZero goto __err;
308*10465441SEvalZero }
309*10465441SEvalZero
310*10465441SEvalZero rt_snprintf(name, RT_NAME_MAX, "%s%d", "at_sr", idx);
311*10465441SEvalZero /* create AT socket receive ring buffer lock */
312*10465441SEvalZero if((sock->recv_lock = rt_mutex_create(name, RT_IPC_FLAG_FIFO)) == RT_NULL)
313*10465441SEvalZero {
314*10465441SEvalZero goto __err;
315*10465441SEvalZero }
316*10465441SEvalZero
317*10465441SEvalZero rt_mutex_release(at_slock);
318*10465441SEvalZero return sock;
319*10465441SEvalZero
320*10465441SEvalZero __err:
321*10465441SEvalZero rt_mutex_release(at_slock);
322*10465441SEvalZero return RT_NULL;
323*10465441SEvalZero }
324*10465441SEvalZero
at_socket(int domain,int type,int protocol)325*10465441SEvalZero int at_socket(int domain, int type, int protocol)
326*10465441SEvalZero {
327*10465441SEvalZero struct at_socket *sock;
328*10465441SEvalZero enum at_socket_type socket_type;
329*10465441SEvalZero
330*10465441SEvalZero /* check socket family protocol */
331*10465441SEvalZero RT_ASSERT(domain == AF_AT||domain == AF_INET);
332*10465441SEvalZero
333*10465441SEvalZero //TODO check protocol
334*10465441SEvalZero
335*10465441SEvalZero switch(type)
336*10465441SEvalZero {
337*10465441SEvalZero case SOCK_STREAM:
338*10465441SEvalZero socket_type = AT_SOCKET_TCP;
339*10465441SEvalZero break;
340*10465441SEvalZero
341*10465441SEvalZero case SOCK_DGRAM:
342*10465441SEvalZero socket_type = AT_SOCKET_UDP;
343*10465441SEvalZero break;
344*10465441SEvalZero
345*10465441SEvalZero default :
346*10465441SEvalZero LOG_E("Don't support socket type (%d)!", type);
347*10465441SEvalZero return -1;
348*10465441SEvalZero }
349*10465441SEvalZero
350*10465441SEvalZero /* allocate and initialize a new AT socket */
351*10465441SEvalZero sock = alloc_socket();
352*10465441SEvalZero if(sock == RT_NULL)
353*10465441SEvalZero {
354*10465441SEvalZero LOG_E("Allocate a new AT socket failed!");
355*10465441SEvalZero return RT_NULL;
356*10465441SEvalZero }
357*10465441SEvalZero sock->type = socket_type;
358*10465441SEvalZero
359*10465441SEvalZero #ifdef SAL_USING_POSIX
360*10465441SEvalZero rt_wqueue_init(&sock->wait_head);
361*10465441SEvalZero #endif
362*10465441SEvalZero
363*10465441SEvalZero return sock->socket;
364*10465441SEvalZero }
365*10465441SEvalZero
free_socket(struct at_socket * sock)366*10465441SEvalZero static int free_socket(struct at_socket *sock)
367*10465441SEvalZero {
368*10465441SEvalZero if (sock->recv_notice)
369*10465441SEvalZero {
370*10465441SEvalZero rt_sem_delete(sock->recv_notice);
371*10465441SEvalZero }
372*10465441SEvalZero
373*10465441SEvalZero if (sock->recv_lock)
374*10465441SEvalZero {
375*10465441SEvalZero rt_mutex_delete(sock->recv_lock);
376*10465441SEvalZero }
377*10465441SEvalZero
378*10465441SEvalZero if (!rt_slist_isempty(&sock->recvpkt_list))
379*10465441SEvalZero {
380*10465441SEvalZero at_recvpkt_all_delete(&sock->recvpkt_list);
381*10465441SEvalZero }
382*10465441SEvalZero
383*10465441SEvalZero memset(sock, 0x00, sizeof(struct at_socket));
384*10465441SEvalZero
385*10465441SEvalZero return 0;
386*10465441SEvalZero }
387*10465441SEvalZero
at_closesocket(int socket)388*10465441SEvalZero int at_closesocket(int socket)
389*10465441SEvalZero {
390*10465441SEvalZero struct at_socket *sock;
391*10465441SEvalZero enum at_socket_state last_state;
392*10465441SEvalZero
393*10465441SEvalZero if (at_dev_ops == RT_NULL)
394*10465441SEvalZero {
395*10465441SEvalZero return -1;
396*10465441SEvalZero }
397*10465441SEvalZero
398*10465441SEvalZero /* deal with TCP server actively disconnect */
399*10465441SEvalZero rt_thread_delay(rt_tick_from_millisecond(100));
400*10465441SEvalZero
401*10465441SEvalZero sock = at_get_socket(socket);
402*10465441SEvalZero if (sock == RT_NULL)
403*10465441SEvalZero {
404*10465441SEvalZero return -1;
405*10465441SEvalZero }
406*10465441SEvalZero
407*10465441SEvalZero last_state = sock->state;
408*10465441SEvalZero
409*10465441SEvalZero /* the rt_at_socket_close is need some time, so change state in advance */
410*10465441SEvalZero sock->state = AT_SOCKET_CLOSED;
411*10465441SEvalZero
412*10465441SEvalZero if (last_state == AT_SOCKET_CONNECT)
413*10465441SEvalZero {
414*10465441SEvalZero if (at_dev_ops->at_closesocket(socket) != 0)
415*10465441SEvalZero {
416*10465441SEvalZero LOG_E("AT socket (%d) closesocket failed!", socket);
417*10465441SEvalZero free_socket(sock);
418*10465441SEvalZero return -1;
419*10465441SEvalZero }
420*10465441SEvalZero }
421*10465441SEvalZero
422*10465441SEvalZero free_socket(sock);
423*10465441SEvalZero return 0;
424*10465441SEvalZero }
425*10465441SEvalZero
at_shutdown(int socket,int how)426*10465441SEvalZero int at_shutdown(int socket, int how)
427*10465441SEvalZero {
428*10465441SEvalZero struct at_socket *sock;
429*10465441SEvalZero
430*10465441SEvalZero if (at_dev_ops == RT_NULL)
431*10465441SEvalZero {
432*10465441SEvalZero return -1;
433*10465441SEvalZero }
434*10465441SEvalZero
435*10465441SEvalZero sock = at_get_socket(socket);
436*10465441SEvalZero if (sock == RT_NULL)
437*10465441SEvalZero {
438*10465441SEvalZero return -1;
439*10465441SEvalZero }
440*10465441SEvalZero
441*10465441SEvalZero if (sock->state == AT_SOCKET_CONNECT)
442*10465441SEvalZero {
443*10465441SEvalZero if (at_dev_ops->at_closesocket(socket) != 0)
444*10465441SEvalZero {
445*10465441SEvalZero LOG_E("AT socket (%d) shutdown failed!", socket);
446*10465441SEvalZero free_socket(sock);
447*10465441SEvalZero return -1;
448*10465441SEvalZero }
449*10465441SEvalZero }
450*10465441SEvalZero
451*10465441SEvalZero free_socket(sock);
452*10465441SEvalZero return 0;
453*10465441SEvalZero }
454*10465441SEvalZero
at_bind(int socket,const struct sockaddr * name,socklen_t namelen)455*10465441SEvalZero int at_bind(int socket, const struct sockaddr *name, socklen_t namelen)
456*10465441SEvalZero {
457*10465441SEvalZero
458*10465441SEvalZero if (at_get_socket(socket) == RT_NULL)
459*10465441SEvalZero {
460*10465441SEvalZero return -1;
461*10465441SEvalZero }
462*10465441SEvalZero
463*10465441SEvalZero return 0;
464*10465441SEvalZero }
465*10465441SEvalZero
466*10465441SEvalZero /* get IP address and port by socketaddr structure information */
socketaddr_to_ipaddr_port(const struct sockaddr * sockaddr,ip_addr_t * addr,uint16_t * port)467*10465441SEvalZero static int socketaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t *addr, uint16_t *port)
468*10465441SEvalZero {
469*10465441SEvalZero const struct sockaddr_in* sin = (const struct sockaddr_in*) (const void *) sockaddr;
470*10465441SEvalZero
471*10465441SEvalZero (*addr).u_addr.ip4.addr = sin->sin_addr.s_addr;
472*10465441SEvalZero
473*10465441SEvalZero *port = (uint16_t) HTONS_PORT(sin->sin_port);
474*10465441SEvalZero
475*10465441SEvalZero return 0;
476*10465441SEvalZero }
477*10465441SEvalZero
478*10465441SEvalZero /* ipaddr structure change to IP address */
ipaddr_to_ipstr(const struct sockaddr * sockaddr,char * ipstr)479*10465441SEvalZero static int ipaddr_to_ipstr(const struct sockaddr *sockaddr, char *ipstr)
480*10465441SEvalZero {
481*10465441SEvalZero struct sockaddr_in *sin = (struct sockaddr_in *) sockaddr;
482*10465441SEvalZero
483*10465441SEvalZero /* change network ip_addr to ip string */
484*10465441SEvalZero rt_snprintf(ipstr, 16, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr));
485*10465441SEvalZero
486*10465441SEvalZero return 0;
487*10465441SEvalZero }
488*10465441SEvalZero
at_recv_notice_cb(int socket,at_socket_evt_t event,const char * buff,size_t bfsz)489*10465441SEvalZero static void at_recv_notice_cb(int socket, at_socket_evt_t event, const char *buff, size_t bfsz)
490*10465441SEvalZero {
491*10465441SEvalZero struct at_socket *sock;
492*10465441SEvalZero
493*10465441SEvalZero RT_ASSERT(buff);
494*10465441SEvalZero RT_ASSERT(bfsz);
495*10465441SEvalZero RT_ASSERT(event == AT_SOCKET_EVT_RECV);
496*10465441SEvalZero
497*10465441SEvalZero sock = at_get_socket(socket);
498*10465441SEvalZero if (sock == RT_NULL)
499*10465441SEvalZero return ;
500*10465441SEvalZero
501*10465441SEvalZero /* put receive buffer to receiver packet list */
502*10465441SEvalZero rt_mutex_take(sock->recv_lock, RT_WAITING_FOREVER);
503*10465441SEvalZero at_recvpkt_put(&(sock->recvpkt_list), buff, bfsz);
504*10465441SEvalZero rt_mutex_release(sock->recv_lock);
505*10465441SEvalZero
506*10465441SEvalZero rt_sem_release(sock->recv_notice);
507*10465441SEvalZero
508*10465441SEvalZero at_do_event_changes(sock, AT_EVENT_RECV, RT_TRUE);
509*10465441SEvalZero }
510*10465441SEvalZero
at_closed_notice_cb(int socket,at_socket_evt_t event,const char * buff,size_t bfsz)511*10465441SEvalZero static void at_closed_notice_cb(int socket, at_socket_evt_t event, const char *buff, size_t bfsz)
512*10465441SEvalZero {
513*10465441SEvalZero struct at_socket *sock;
514*10465441SEvalZero
515*10465441SEvalZero RT_ASSERT(event == AT_SOCKET_EVT_CLOSED);
516*10465441SEvalZero
517*10465441SEvalZero if ((sock = at_get_socket(socket)) == RT_NULL)
518*10465441SEvalZero return ;
519*10465441SEvalZero
520*10465441SEvalZero at_do_event_changes(sock, AT_EVENT_RECV, RT_TRUE);
521*10465441SEvalZero at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE);
522*10465441SEvalZero
523*10465441SEvalZero sock->state = AT_SOCKET_CLOSED;
524*10465441SEvalZero rt_sem_release(sock->recv_notice);
525*10465441SEvalZero }
526*10465441SEvalZero
at_connect(int socket,const struct sockaddr * name,socklen_t namelen)527*10465441SEvalZero int at_connect(int socket, const struct sockaddr *name, socklen_t namelen)
528*10465441SEvalZero {
529*10465441SEvalZero struct at_socket *sock;
530*10465441SEvalZero ip_addr_t remote_addr;
531*10465441SEvalZero uint16_t remote_port;
532*10465441SEvalZero char ipstr[16] = { 0 };
533*10465441SEvalZero int result = 0;
534*10465441SEvalZero
535*10465441SEvalZero if (at_dev_ops == RT_NULL)
536*10465441SEvalZero {
537*10465441SEvalZero return -1;
538*10465441SEvalZero }
539*10465441SEvalZero
540*10465441SEvalZero sock = at_get_socket(socket);
541*10465441SEvalZero if (sock == RT_NULL)
542*10465441SEvalZero {
543*10465441SEvalZero result = -1;
544*10465441SEvalZero goto __exit;
545*10465441SEvalZero }
546*10465441SEvalZero
547*10465441SEvalZero if (sock->state != AT_SOCKET_NONE)
548*10465441SEvalZero {
549*10465441SEvalZero LOG_E("Socket %d connect state is %d.", sock->socket, sock->state);
550*10465441SEvalZero result = -1;
551*10465441SEvalZero goto __exit;
552*10465441SEvalZero }
553*10465441SEvalZero
554*10465441SEvalZero /* get IP address and port by socketaddr structure */
555*10465441SEvalZero socketaddr_to_ipaddr_port(name, &remote_addr, &remote_port);
556*10465441SEvalZero ipaddr_to_ipstr(name, ipstr);
557*10465441SEvalZero
558*10465441SEvalZero if (at_dev_ops->at_connect(socket, ipstr, remote_port, sock->type, RT_TRUE) < 0)
559*10465441SEvalZero {
560*10465441SEvalZero LOG_E("AT socket(%d) connect failed!", socket);
561*10465441SEvalZero result = -1;
562*10465441SEvalZero goto __exit;
563*10465441SEvalZero }
564*10465441SEvalZero
565*10465441SEvalZero sock->state = AT_SOCKET_CONNECT;
566*10465441SEvalZero
567*10465441SEvalZero /* set AT socket receive data callback function */
568*10465441SEvalZero at_dev_ops->at_set_event_cb(AT_SOCKET_EVT_RECV, at_recv_notice_cb);
569*10465441SEvalZero at_dev_ops->at_set_event_cb(AT_SOCKET_EVT_CLOSED, at_closed_notice_cb);
570*10465441SEvalZero
571*10465441SEvalZero __exit:
572*10465441SEvalZero
573*10465441SEvalZero if (result < 0)
574*10465441SEvalZero {
575*10465441SEvalZero if (sock != RT_NULL)
576*10465441SEvalZero {
577*10465441SEvalZero at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE);
578*10465441SEvalZero }
579*10465441SEvalZero }
580*10465441SEvalZero
581*10465441SEvalZero if (sock)
582*10465441SEvalZero {
583*10465441SEvalZero at_do_event_changes(sock, AT_EVENT_SEND, RT_TRUE);
584*10465441SEvalZero }
585*10465441SEvalZero
586*10465441SEvalZero return result;
587*10465441SEvalZero }
588*10465441SEvalZero
at_recvfrom(int socket,void * mem,size_t len,int flags,struct sockaddr * from,socklen_t * fromlen)589*10465441SEvalZero int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
590*10465441SEvalZero {
591*10465441SEvalZero struct at_socket *sock;
592*10465441SEvalZero int timeout;
593*10465441SEvalZero int result = 0;
594*10465441SEvalZero size_t recv_len = 0;
595*10465441SEvalZero
596*10465441SEvalZero if (mem == RT_NULL || len == 0)
597*10465441SEvalZero {
598*10465441SEvalZero LOG_E("AT recvfrom input data or length error!");
599*10465441SEvalZero return -1;
600*10465441SEvalZero }
601*10465441SEvalZero
602*10465441SEvalZero if (at_dev_ops == RT_NULL)
603*10465441SEvalZero {
604*10465441SEvalZero return -1;
605*10465441SEvalZero }
606*10465441SEvalZero
607*10465441SEvalZero sock = at_get_socket(socket);
608*10465441SEvalZero if (sock == RT_NULL)
609*10465441SEvalZero {
610*10465441SEvalZero result = -1;
611*10465441SEvalZero goto __exit;
612*10465441SEvalZero }
613*10465441SEvalZero
614*10465441SEvalZero /* if the socket type is UDP, nead to connect socket first */
615*10465441SEvalZero if (from && sock->type == AT_SOCKET_UDP && sock->state == AT_SOCKET_NONE)
616*10465441SEvalZero {
617*10465441SEvalZero ip_addr_t remote_addr;
618*10465441SEvalZero uint16_t remote_port;
619*10465441SEvalZero char ipstr[16] = { 0 };
620*10465441SEvalZero
621*10465441SEvalZero socketaddr_to_ipaddr_port(from, &remote_addr, &remote_port);
622*10465441SEvalZero ipaddr_to_ipstr(from, ipstr);
623*10465441SEvalZero
624*10465441SEvalZero if (at_dev_ops->at_connect(socket, ipstr, remote_port, sock->type, RT_TRUE) < 0)
625*10465441SEvalZero {
626*10465441SEvalZero LOG_E("AT socket UDP connect failed!");
627*10465441SEvalZero result = -1;
628*10465441SEvalZero goto __exit;
629*10465441SEvalZero }
630*10465441SEvalZero sock->state = AT_SOCKET_CONNECT;
631*10465441SEvalZero /* set AT socket receive data callback function */
632*10465441SEvalZero at_dev_ops->at_set_event_cb(AT_SOCKET_EVT_RECV, at_recv_notice_cb);
633*10465441SEvalZero at_dev_ops->at_set_event_cb(AT_SOCKET_EVT_CLOSED, at_closed_notice_cb);
634*10465441SEvalZero }
635*10465441SEvalZero
636*10465441SEvalZero /* receive packet list last transmission of remaining data */
637*10465441SEvalZero rt_mutex_take(sock->recv_lock, RT_WAITING_FOREVER);
638*10465441SEvalZero if((recv_len = at_recvpkt_get(&(sock->recvpkt_list), (char *)mem, len)) > 0)
639*10465441SEvalZero {
640*10465441SEvalZero rt_mutex_release(sock->recv_lock);
641*10465441SEvalZero goto __exit;
642*10465441SEvalZero }
643*10465441SEvalZero rt_mutex_release(sock->recv_lock);
644*10465441SEvalZero
645*10465441SEvalZero /* socket passively closed, receive function return 0 */
646*10465441SEvalZero if (sock->state == AT_SOCKET_CLOSED)
647*10465441SEvalZero {
648*10465441SEvalZero result = 0;
649*10465441SEvalZero goto __exit;
650*10465441SEvalZero }
651*10465441SEvalZero else if (sock->state != AT_SOCKET_CONNECT)
652*10465441SEvalZero {
653*10465441SEvalZero LOG_E("received data error, current socket (%d) state (%d) is error.", socket, sock->state);
654*10465441SEvalZero result = -1;
655*10465441SEvalZero goto __exit;
656*10465441SEvalZero }
657*10465441SEvalZero
658*10465441SEvalZero /* non-blocking sockets receive data */
659*10465441SEvalZero if (flags & MSG_DONTWAIT)
660*10465441SEvalZero {
661*10465441SEvalZero goto __exit;
662*10465441SEvalZero }
663*10465441SEvalZero
664*10465441SEvalZero /* set AT socket receive timeout */
665*10465441SEvalZero if((timeout = sock->recv_timeout) == 0)
666*10465441SEvalZero {
667*10465441SEvalZero timeout = RT_WAITING_FOREVER;
668*10465441SEvalZero }
669*10465441SEvalZero else
670*10465441SEvalZero {
671*10465441SEvalZero timeout = rt_tick_from_millisecond(timeout);
672*10465441SEvalZero }
673*10465441SEvalZero
674*10465441SEvalZero while (1)
675*10465441SEvalZero {
676*10465441SEvalZero /* wait the receive semaphore */
677*10465441SEvalZero if (rt_sem_take(sock->recv_notice, timeout) < 0)
678*10465441SEvalZero {
679*10465441SEvalZero LOG_E("AT socket (%d) receive timeout (%d)!", socket, timeout);
680*10465441SEvalZero errno = EAGAIN;
681*10465441SEvalZero result = -1;
682*10465441SEvalZero goto __exit;
683*10465441SEvalZero }
684*10465441SEvalZero else
685*10465441SEvalZero {
686*10465441SEvalZero if (sock->state == AT_SOCKET_CONNECT)
687*10465441SEvalZero {
688*10465441SEvalZero /* get receive buffer to receiver ring buffer */
689*10465441SEvalZero rt_mutex_take(sock->recv_lock, RT_WAITING_FOREVER);
690*10465441SEvalZero recv_len = at_recvpkt_get(&(sock->recvpkt_list), (char *) mem, len);
691*10465441SEvalZero rt_mutex_release(sock->recv_lock);
692*10465441SEvalZero if (recv_len > 0)
693*10465441SEvalZero {
694*10465441SEvalZero break;
695*10465441SEvalZero }
696*10465441SEvalZero }
697*10465441SEvalZero else
698*10465441SEvalZero {
699*10465441SEvalZero LOG_D("received data exit, current socket (%d) is closed by remote.", socket);
700*10465441SEvalZero result = 0;
701*10465441SEvalZero goto __exit;
702*10465441SEvalZero }
703*10465441SEvalZero }
704*10465441SEvalZero }
705*10465441SEvalZero
706*10465441SEvalZero __exit:
707*10465441SEvalZero
708*10465441SEvalZero if (sock != RT_NULL)
709*10465441SEvalZero {
710*10465441SEvalZero if (recv_len > 0)
711*10465441SEvalZero {
712*10465441SEvalZero result = recv_len;
713*10465441SEvalZero at_do_event_changes(sock, AT_EVENT_RECV, RT_FALSE);
714*10465441SEvalZero errno = 0;
715*10465441SEvalZero if (!rt_slist_isempty(&sock->recvpkt_list))
716*10465441SEvalZero {
717*10465441SEvalZero at_do_event_changes(sock, AT_EVENT_RECV, RT_TRUE);
718*10465441SEvalZero }
719*10465441SEvalZero else
720*10465441SEvalZero {
721*10465441SEvalZero at_do_event_clean(sock, AT_EVENT_RECV);
722*10465441SEvalZero }
723*10465441SEvalZero }
724*10465441SEvalZero else
725*10465441SEvalZero {
726*10465441SEvalZero at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE);
727*10465441SEvalZero }
728*10465441SEvalZero }
729*10465441SEvalZero
730*10465441SEvalZero return result;
731*10465441SEvalZero }
732*10465441SEvalZero
at_recv(int s,void * mem,size_t len,int flags)733*10465441SEvalZero int at_recv(int s, void *mem, size_t len, int flags)
734*10465441SEvalZero {
735*10465441SEvalZero return at_recvfrom(s, mem, len, flags, RT_NULL, RT_NULL);
736*10465441SEvalZero }
737*10465441SEvalZero
at_sendto(int socket,const void * data,size_t size,int flags,const struct sockaddr * to,socklen_t tolen)738*10465441SEvalZero int at_sendto(int socket, const void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)
739*10465441SEvalZero {
740*10465441SEvalZero struct at_socket *sock;
741*10465441SEvalZero int len, result = 0;
742*10465441SEvalZero
743*10465441SEvalZero if (at_dev_ops == RT_NULL)
744*10465441SEvalZero {
745*10465441SEvalZero result = -1;
746*10465441SEvalZero goto __exit;
747*10465441SEvalZero }
748*10465441SEvalZero
749*10465441SEvalZero if (data == RT_NULL || size == 0)
750*10465441SEvalZero {
751*10465441SEvalZero LOG_E("AT sendto input data or size error!");
752*10465441SEvalZero result = -1;
753*10465441SEvalZero goto __exit;
754*10465441SEvalZero }
755*10465441SEvalZero
756*10465441SEvalZero sock = at_get_socket(socket);
757*10465441SEvalZero if (sock == RT_NULL)
758*10465441SEvalZero {
759*10465441SEvalZero result = -1;
760*10465441SEvalZero goto __exit;
761*10465441SEvalZero }
762*10465441SEvalZero
763*10465441SEvalZero switch (sock->type)
764*10465441SEvalZero {
765*10465441SEvalZero case AT_SOCKET_TCP:
766*10465441SEvalZero if (sock->state != AT_SOCKET_CONNECT)
767*10465441SEvalZero {
768*10465441SEvalZero LOG_E("send data error, current socket (%d) state (%d) is error.", socket, sock->state);
769*10465441SEvalZero result = -1;
770*10465441SEvalZero goto __exit;
771*10465441SEvalZero }
772*10465441SEvalZero
773*10465441SEvalZero if ((len = at_dev_ops->at_send(sock->socket, (const char *) data, size, sock->type)) < 0)
774*10465441SEvalZero {
775*10465441SEvalZero result = -1;
776*10465441SEvalZero goto __exit;
777*10465441SEvalZero }
778*10465441SEvalZero break;
779*10465441SEvalZero
780*10465441SEvalZero case AT_SOCKET_UDP:
781*10465441SEvalZero if (to && sock->state == AT_SOCKET_NONE)
782*10465441SEvalZero {
783*10465441SEvalZero ip_addr_t remote_addr;
784*10465441SEvalZero uint16_t remote_port;
785*10465441SEvalZero char ipstr[16] = { 0 };
786*10465441SEvalZero
787*10465441SEvalZero socketaddr_to_ipaddr_port(to, &remote_addr, &remote_port);
788*10465441SEvalZero ipaddr_to_ipstr(to, ipstr);
789*10465441SEvalZero
790*10465441SEvalZero if (at_dev_ops->at_connect(socket, ipstr, remote_port, sock->type, RT_TRUE) < 0)
791*10465441SEvalZero {
792*10465441SEvalZero LOG_E("AT socket (%d) UDP connect failed!", socket);
793*10465441SEvalZero result = -1;
794*10465441SEvalZero goto __exit;
795*10465441SEvalZero }
796*10465441SEvalZero sock->state = AT_SOCKET_CONNECT;
797*10465441SEvalZero /* set AT socket receive data callback function */
798*10465441SEvalZero at_dev_ops->at_set_event_cb(AT_SOCKET_EVT_RECV, at_recv_notice_cb);
799*10465441SEvalZero at_dev_ops->at_set_event_cb(AT_SOCKET_EVT_CLOSED, at_closed_notice_cb);
800*10465441SEvalZero }
801*10465441SEvalZero
802*10465441SEvalZero if ((len = at_dev_ops->at_send(sock->socket, (char *) data, size, sock->type)) < 0)
803*10465441SEvalZero {
804*10465441SEvalZero result = -1;
805*10465441SEvalZero goto __exit;
806*10465441SEvalZero }
807*10465441SEvalZero break;
808*10465441SEvalZero
809*10465441SEvalZero default:
810*10465441SEvalZero LOG_E("Socket (%d) type %d is not support.", socket, sock->type);
811*10465441SEvalZero result = -1;
812*10465441SEvalZero goto __exit;
813*10465441SEvalZero }
814*10465441SEvalZero
815*10465441SEvalZero __exit:
816*10465441SEvalZero
817*10465441SEvalZero if (result < 0)
818*10465441SEvalZero {
819*10465441SEvalZero if (sock != RT_NULL)
820*10465441SEvalZero {
821*10465441SEvalZero at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE);
822*10465441SEvalZero }
823*10465441SEvalZero }
824*10465441SEvalZero else
825*10465441SEvalZero {
826*10465441SEvalZero result = len;
827*10465441SEvalZero }
828*10465441SEvalZero
829*10465441SEvalZero return result;
830*10465441SEvalZero }
831*10465441SEvalZero
at_send(int socket,const void * data,size_t size,int flags)832*10465441SEvalZero int at_send(int socket, const void *data, size_t size, int flags)
833*10465441SEvalZero {
834*10465441SEvalZero return at_sendto(socket, data, size, flags, RT_NULL, 0);
835*10465441SEvalZero }
836*10465441SEvalZero
at_getsockopt(int socket,int level,int optname,void * optval,socklen_t * optlen)837*10465441SEvalZero int at_getsockopt(int socket, int level, int optname, void *optval, socklen_t *optlen)
838*10465441SEvalZero {
839*10465441SEvalZero struct at_socket *sock;
840*10465441SEvalZero int32_t timeout;
841*10465441SEvalZero
842*10465441SEvalZero if (optval == RT_NULL || optlen == RT_NULL)
843*10465441SEvalZero {
844*10465441SEvalZero LOG_E("AT getsocketopt input option value or option length error!");
845*10465441SEvalZero return -1;
846*10465441SEvalZero }
847*10465441SEvalZero
848*10465441SEvalZero sock = at_get_socket(socket);
849*10465441SEvalZero if (sock == RT_NULL)
850*10465441SEvalZero {
851*10465441SEvalZero return -1;
852*10465441SEvalZero }
853*10465441SEvalZero
854*10465441SEvalZero switch (level)
855*10465441SEvalZero {
856*10465441SEvalZero case SOL_SOCKET:
857*10465441SEvalZero switch (optname)
858*10465441SEvalZero {
859*10465441SEvalZero case SO_RCVTIMEO:
860*10465441SEvalZero timeout = sock->recv_timeout;
861*10465441SEvalZero ((struct timeval *)(optval))->tv_sec = (timeout) / 1000U;
862*10465441SEvalZero ((struct timeval *)(optval))->tv_usec = (timeout % 1000U) * 1000U;
863*10465441SEvalZero break;
864*10465441SEvalZero
865*10465441SEvalZero case SO_SNDTIMEO:
866*10465441SEvalZero timeout = sock->send_timeout;
867*10465441SEvalZero ((struct timeval *) optval)->tv_sec = timeout / 1000U;
868*10465441SEvalZero ((struct timeval *) optval)->tv_usec = (timeout % 1000U) * 1000U;
869*10465441SEvalZero break;
870*10465441SEvalZero
871*10465441SEvalZero default:
872*10465441SEvalZero LOG_E("AT socket (%d) not support option name : %d.", socket, optname);
873*10465441SEvalZero return -1;
874*10465441SEvalZero }
875*10465441SEvalZero break;
876*10465441SEvalZero
877*10465441SEvalZero default:
878*10465441SEvalZero LOG_E("AT socket (%d) not support option level : %d.", socket, level);
879*10465441SEvalZero return -1;
880*10465441SEvalZero }
881*10465441SEvalZero
882*10465441SEvalZero return 0;
883*10465441SEvalZero }
884*10465441SEvalZero
at_setsockopt(int socket,int level,int optname,const void * optval,socklen_t optlen)885*10465441SEvalZero int at_setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen)
886*10465441SEvalZero {
887*10465441SEvalZero struct at_socket *sock;
888*10465441SEvalZero
889*10465441SEvalZero if (optval == RT_NULL)
890*10465441SEvalZero {
891*10465441SEvalZero LOG_E("AT setsockopt input option value error!");
892*10465441SEvalZero return -1;
893*10465441SEvalZero }
894*10465441SEvalZero
895*10465441SEvalZero sock = at_get_socket(socket);
896*10465441SEvalZero if (sock == RT_NULL)
897*10465441SEvalZero {
898*10465441SEvalZero return -1;
899*10465441SEvalZero }
900*10465441SEvalZero
901*10465441SEvalZero switch (level)
902*10465441SEvalZero {
903*10465441SEvalZero case SOL_SOCKET:
904*10465441SEvalZero switch (optname)
905*10465441SEvalZero {
906*10465441SEvalZero case SO_RCVTIMEO:
907*10465441SEvalZero sock->recv_timeout = ((const struct timeval *) optval)->tv_sec * 1000
908*10465441SEvalZero + ((const struct timeval *) optval)->tv_usec / 1000;
909*10465441SEvalZero break;
910*10465441SEvalZero
911*10465441SEvalZero case SO_SNDTIMEO:
912*10465441SEvalZero sock->send_timeout = ((const struct timeval *) optval)->tv_sec * 1000
913*10465441SEvalZero + ((const struct timeval *) optval)->tv_usec / 1000;
914*10465441SEvalZero break;
915*10465441SEvalZero
916*10465441SEvalZero default:
917*10465441SEvalZero LOG_E("AT socket (%d) not support option name : %d.", socket, optname);
918*10465441SEvalZero return -1;
919*10465441SEvalZero }
920*10465441SEvalZero break;
921*10465441SEvalZero case IPPROTO_TCP:
922*10465441SEvalZero switch (optname)
923*10465441SEvalZero {
924*10465441SEvalZero case TCP_NODELAY:
925*10465441SEvalZero break;
926*10465441SEvalZero }
927*10465441SEvalZero break;
928*10465441SEvalZero default:
929*10465441SEvalZero LOG_E("AT socket (%d) not support option level : %d.", socket, level);
930*10465441SEvalZero return -1;
931*10465441SEvalZero }
932*10465441SEvalZero
933*10465441SEvalZero return 0;
934*10465441SEvalZero }
935*10465441SEvalZero
ipstr_atol(const char * nptr)936*10465441SEvalZero static uint32_t ipstr_atol(const char* nptr)
937*10465441SEvalZero {
938*10465441SEvalZero uint32_t total = 0;
939*10465441SEvalZero char sign = '+';
940*10465441SEvalZero /* jump space */
941*10465441SEvalZero while (isspace(*nptr))
942*10465441SEvalZero {
943*10465441SEvalZero ++nptr;
944*10465441SEvalZero }
945*10465441SEvalZero if (*nptr == '-' || *nptr == '+')
946*10465441SEvalZero {
947*10465441SEvalZero sign = *nptr++;
948*10465441SEvalZero }
949*10465441SEvalZero while (isdigit(*nptr))
950*10465441SEvalZero {
951*10465441SEvalZero total = 10 * total + ((*nptr++) - '0');
952*10465441SEvalZero }
953*10465441SEvalZero return (sign == '-') ? -total : total;
954*10465441SEvalZero }
955*10465441SEvalZero
956*10465441SEvalZero /* IP address to unsigned int type */
ipstr_to_u32(char * ipstr)957*10465441SEvalZero static uint32_t ipstr_to_u32(char *ipstr)
958*10465441SEvalZero {
959*10465441SEvalZero char ipBytes[4] = { 0 };
960*10465441SEvalZero uint32_t i;
961*10465441SEvalZero
962*10465441SEvalZero for (i = 0; i < 4; i++, ipstr++)
963*10465441SEvalZero {
964*10465441SEvalZero ipBytes[i] = (char) ipstr_atol(ipstr);
965*10465441SEvalZero if ((ipstr = strchr(ipstr, '.')) == RT_NULL)
966*10465441SEvalZero {
967*10465441SEvalZero break;
968*10465441SEvalZero }
969*10465441SEvalZero }
970*10465441SEvalZero return *(uint32_t *) ipBytes;
971*10465441SEvalZero }
972*10465441SEvalZero
at_gethostbyname(const char * name)973*10465441SEvalZero struct hostent *at_gethostbyname(const char *name)
974*10465441SEvalZero {
975*10465441SEvalZero ip_addr_t addr;
976*10465441SEvalZero char ipstr[16] = { 0 };
977*10465441SEvalZero /* buffer variables for at_gethostbyname() */
978*10465441SEvalZero static struct hostent s_hostent;
979*10465441SEvalZero static char *s_aliases;
980*10465441SEvalZero static ip_addr_t s_hostent_addr;
981*10465441SEvalZero static ip_addr_t *s_phostent_addr[2];
982*10465441SEvalZero static char s_hostname[DNS_MAX_NAME_LENGTH + 1];
983*10465441SEvalZero size_t idx = 0;
984*10465441SEvalZero
985*10465441SEvalZero if (name == RT_NULL)
986*10465441SEvalZero {
987*10465441SEvalZero LOG_E("AT gethostbyname input name error!");
988*10465441SEvalZero return RT_NULL;
989*10465441SEvalZero }
990*10465441SEvalZero
991*10465441SEvalZero if (at_dev_ops == RT_NULL)
992*10465441SEvalZero {
993*10465441SEvalZero return RT_NULL;
994*10465441SEvalZero }
995*10465441SEvalZero
996*10465441SEvalZero for (idx = 0; idx < strlen(name) && !isalpha(name[idx]); idx++);
997*10465441SEvalZero
998*10465441SEvalZero if (idx < strlen(name))
999*10465441SEvalZero {
1000*10465441SEvalZero if (at_dev_ops->at_domain_resolve(name, ipstr) < 0)
1001*10465441SEvalZero {
1002*10465441SEvalZero LOG_E("AT domain (%s) resolve error!", name);
1003*10465441SEvalZero return RT_NULL;
1004*10465441SEvalZero }
1005*10465441SEvalZero }
1006*10465441SEvalZero else
1007*10465441SEvalZero {
1008*10465441SEvalZero strncpy(ipstr, name, strlen(name));
1009*10465441SEvalZero }
1010*10465441SEvalZero
1011*10465441SEvalZero addr.u_addr.ip4.addr = ipstr_to_u32(ipstr);
1012*10465441SEvalZero
1013*10465441SEvalZero /* fill hostent structure */
1014*10465441SEvalZero s_hostent_addr = addr;
1015*10465441SEvalZero s_phostent_addr[0] = &s_hostent_addr;
1016*10465441SEvalZero s_phostent_addr[1] = RT_NULL;
1017*10465441SEvalZero strncpy(s_hostname, name, DNS_MAX_NAME_LENGTH);
1018*10465441SEvalZero s_hostname[DNS_MAX_NAME_LENGTH] = 0;
1019*10465441SEvalZero s_hostent.h_name = s_hostname;
1020*10465441SEvalZero s_aliases = RT_NULL;
1021*10465441SEvalZero s_hostent.h_aliases = &s_aliases;
1022*10465441SEvalZero s_hostent.h_addrtype = AF_AT;
1023*10465441SEvalZero s_hostent.h_length = sizeof(ip_addr_t);
1024*10465441SEvalZero s_hostent.h_addr_list = (char**) &s_phostent_addr;
1025*10465441SEvalZero
1026*10465441SEvalZero return &s_hostent;
1027*10465441SEvalZero }
1028*10465441SEvalZero
at_getaddrinfo(const char * nodename,const char * servname,const struct addrinfo * hints,struct addrinfo ** res)1029*10465441SEvalZero int at_getaddrinfo(const char *nodename, const char *servname,
1030*10465441SEvalZero const struct addrinfo *hints, struct addrinfo **res)
1031*10465441SEvalZero {
1032*10465441SEvalZero int port_nr = 0;
1033*10465441SEvalZero ip_addr_t addr;
1034*10465441SEvalZero struct addrinfo *ai;
1035*10465441SEvalZero struct sockaddr_storage *sa;
1036*10465441SEvalZero size_t total_size = 0;
1037*10465441SEvalZero size_t namelen = 0;
1038*10465441SEvalZero int ai_family = 0;
1039*10465441SEvalZero
1040*10465441SEvalZero if (res == RT_NULL)
1041*10465441SEvalZero {
1042*10465441SEvalZero return EAI_FAIL;
1043*10465441SEvalZero }
1044*10465441SEvalZero *res = RT_NULL;
1045*10465441SEvalZero
1046*10465441SEvalZero if (at_dev_ops == RT_NULL)
1047*10465441SEvalZero {
1048*10465441SEvalZero return EAI_FAIL;
1049*10465441SEvalZero }
1050*10465441SEvalZero
1051*10465441SEvalZero if ((nodename == RT_NULL) && (servname == RT_NULL))
1052*10465441SEvalZero {
1053*10465441SEvalZero return EAI_NONAME;
1054*10465441SEvalZero }
1055*10465441SEvalZero
1056*10465441SEvalZero if (hints != RT_NULL)
1057*10465441SEvalZero {
1058*10465441SEvalZero ai_family = hints->ai_family;
1059*10465441SEvalZero if (hints->ai_family != AF_AT && hints->ai_family != AF_INET && hints->ai_family != AF_UNSPEC)
1060*10465441SEvalZero {
1061*10465441SEvalZero return EAI_FAMILY;
1062*10465441SEvalZero }
1063*10465441SEvalZero }
1064*10465441SEvalZero
1065*10465441SEvalZero if (servname != RT_NULL)
1066*10465441SEvalZero {
1067*10465441SEvalZero /* service name specified: convert to port number */
1068*10465441SEvalZero port_nr = atoi(servname);
1069*10465441SEvalZero if ((port_nr <= 0) || (port_nr > 0xffff))
1070*10465441SEvalZero {
1071*10465441SEvalZero return EAI_SERVICE;
1072*10465441SEvalZero }
1073*10465441SEvalZero }
1074*10465441SEvalZero
1075*10465441SEvalZero if (nodename != RT_NULL)
1076*10465441SEvalZero {
1077*10465441SEvalZero /* service location specified, try to resolve */
1078*10465441SEvalZero if ((hints != RT_NULL) && (hints->ai_flags & AI_NUMERICHOST))
1079*10465441SEvalZero {
1080*10465441SEvalZero /* no DNS lookup, just parse for an address string */
1081*10465441SEvalZero if (!inet_aton(nodename, (ip4_addr_t * )&addr))
1082*10465441SEvalZero {
1083*10465441SEvalZero return EAI_NONAME;
1084*10465441SEvalZero }
1085*10465441SEvalZero
1086*10465441SEvalZero if (ai_family == AF_AT || ai_family == AF_INET)
1087*10465441SEvalZero {
1088*10465441SEvalZero return EAI_NONAME;
1089*10465441SEvalZero }
1090*10465441SEvalZero }
1091*10465441SEvalZero else
1092*10465441SEvalZero {
1093*10465441SEvalZero char ip_str[16] = { 0 };
1094*10465441SEvalZero size_t idx = 0;
1095*10465441SEvalZero
1096*10465441SEvalZero for (idx = 0; idx < strlen(nodename) && !isalpha(nodename[idx]); idx++);
1097*10465441SEvalZero
1098*10465441SEvalZero if(idx < strlen(nodename))
1099*10465441SEvalZero {
1100*10465441SEvalZero if (at_dev_ops->at_domain_resolve((char *) nodename, ip_str) != 0)
1101*10465441SEvalZero {
1102*10465441SEvalZero return EAI_FAIL;
1103*10465441SEvalZero }
1104*10465441SEvalZero }
1105*10465441SEvalZero else
1106*10465441SEvalZero {
1107*10465441SEvalZero strncpy(ip_str, nodename, strlen(nodename));
1108*10465441SEvalZero }
1109*10465441SEvalZero
1110*10465441SEvalZero addr.type = IPADDR_TYPE_V4;
1111*10465441SEvalZero if ((addr.u_addr.ip4.addr = ipstr_to_u32(ip_str)) == 0)
1112*10465441SEvalZero {
1113*10465441SEvalZero return EAI_FAIL;
1114*10465441SEvalZero }
1115*10465441SEvalZero }
1116*10465441SEvalZero }
1117*10465441SEvalZero else
1118*10465441SEvalZero {
1119*10465441SEvalZero /* to do service location specified, use loopback address */
1120*10465441SEvalZero }
1121*10465441SEvalZero
1122*10465441SEvalZero total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_storage);
1123*10465441SEvalZero if (nodename != RT_NULL)
1124*10465441SEvalZero {
1125*10465441SEvalZero namelen = strlen(nodename);
1126*10465441SEvalZero if (namelen > DNS_MAX_NAME_LENGTH)
1127*10465441SEvalZero {
1128*10465441SEvalZero /* invalid name length */
1129*10465441SEvalZero return EAI_FAIL;
1130*10465441SEvalZero }
1131*10465441SEvalZero RT_ASSERT(total_size + namelen + 1 > total_size);
1132*10465441SEvalZero total_size += namelen + 1;
1133*10465441SEvalZero }
1134*10465441SEvalZero /* If this fails, please report to lwip-devel! :-) */
1135*10465441SEvalZero RT_ASSERT(total_size <= sizeof(struct addrinfo) + sizeof(struct sockaddr_storage) + DNS_MAX_NAME_LENGTH + 1);
1136*10465441SEvalZero ai = (struct addrinfo *) rt_malloc(total_size);
1137*10465441SEvalZero if (ai == RT_NULL)
1138*10465441SEvalZero {
1139*10465441SEvalZero return EAI_MEMORY;
1140*10465441SEvalZero }
1141*10465441SEvalZero memset(ai, 0, total_size);
1142*10465441SEvalZero /* cast through void* to get rid of alignment warnings */
1143*10465441SEvalZero sa = (struct sockaddr_storage *) (void *) ((uint8_t *) ai + sizeof(struct addrinfo));
1144*10465441SEvalZero struct sockaddr_in *sa4 = (struct sockaddr_in *) sa;
1145*10465441SEvalZero /* set up sockaddr */
1146*10465441SEvalZero sa4->sin_addr.s_addr = addr.u_addr.ip4.addr;
1147*10465441SEvalZero sa4->sin_family = AF_INET;
1148*10465441SEvalZero sa4->sin_len = sizeof(struct sockaddr_in);
1149*10465441SEvalZero sa4->sin_port = htons((u16_t )port_nr);
1150*10465441SEvalZero ai->ai_family = AF_INET;
1151*10465441SEvalZero
1152*10465441SEvalZero /* set up addrinfo */
1153*10465441SEvalZero if (hints != RT_NULL)
1154*10465441SEvalZero {
1155*10465441SEvalZero /* copy socktype & protocol from hints if specified */
1156*10465441SEvalZero ai->ai_socktype = hints->ai_socktype;
1157*10465441SEvalZero ai->ai_protocol = hints->ai_protocol;
1158*10465441SEvalZero }
1159*10465441SEvalZero if (nodename != RT_NULL)
1160*10465441SEvalZero {
1161*10465441SEvalZero /* copy nodename to canonname if specified */
1162*10465441SEvalZero ai->ai_canonname = ((char *) ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_storage));
1163*10465441SEvalZero memcpy(ai->ai_canonname, nodename, namelen);
1164*10465441SEvalZero ai->ai_canonname[namelen] = 0;
1165*10465441SEvalZero }
1166*10465441SEvalZero ai->ai_addrlen = sizeof(struct sockaddr_storage);
1167*10465441SEvalZero ai->ai_addr = (struct sockaddr *) sa;
1168*10465441SEvalZero
1169*10465441SEvalZero *res = ai;
1170*10465441SEvalZero
1171*10465441SEvalZero return 0;
1172*10465441SEvalZero }
1173*10465441SEvalZero
at_freeaddrinfo(struct addrinfo * ai)1174*10465441SEvalZero void at_freeaddrinfo(struct addrinfo *ai)
1175*10465441SEvalZero {
1176*10465441SEvalZero struct addrinfo *next;
1177*10465441SEvalZero
1178*10465441SEvalZero while (ai != NULL)
1179*10465441SEvalZero {
1180*10465441SEvalZero next = ai->ai_next;
1181*10465441SEvalZero rt_free(ai);
1182*10465441SEvalZero ai = next;
1183*10465441SEvalZero }
1184*10465441SEvalZero }
1185*10465441SEvalZero
at_socket_device_register(const struct at_device_ops * ops)1186*10465441SEvalZero void at_socket_device_register(const struct at_device_ops *ops)
1187*10465441SEvalZero {
1188*10465441SEvalZero RT_ASSERT(ops);
1189*10465441SEvalZero RT_ASSERT(ops->at_connect);
1190*10465441SEvalZero RT_ASSERT(ops->at_closesocket);
1191*10465441SEvalZero RT_ASSERT(ops->at_send);
1192*10465441SEvalZero RT_ASSERT(ops->at_domain_resolve);
1193*10465441SEvalZero RT_ASSERT(ops->at_set_event_cb);
1194*10465441SEvalZero at_dev_ops = (struct at_device_ops *) ops;
1195*10465441SEvalZero }
1196*10465441SEvalZero
1197*10465441SEvalZero #endif /* AT_USING_SOCKET */
1198