xref: /nrf52832-nimble/rt-thread/components/net/at/at_socket/at_socket.c (revision 104654410c56c573564690304ae786df310c91fc)
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