xref: /nrf52832-nimble/rt-thread/components/net/sal_socket/impl/af_inet_lwip.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-05-17     ChenYong     First version
9*10465441SEvalZero  */
10*10465441SEvalZero 
11*10465441SEvalZero #include <rtthread.h>
12*10465441SEvalZero 
13*10465441SEvalZero #include <lwip/sockets.h>
14*10465441SEvalZero #include <lwip/netdb.h>
15*10465441SEvalZero #include <lwip/api.h>
16*10465441SEvalZero #include <lwip/init.h>
17*10465441SEvalZero 
18*10465441SEvalZero #ifdef SAL_USING_POSIX
19*10465441SEvalZero #include <dfs_poll.h>
20*10465441SEvalZero #endif
21*10465441SEvalZero 
22*10465441SEvalZero #include <sal.h>
23*10465441SEvalZero #include <af_inet.h>
24*10465441SEvalZero 
25*10465441SEvalZero #if LWIP_VERSION < 0x2000000
26*10465441SEvalZero #define SELWAIT_T int
27*10465441SEvalZero #else
28*10465441SEvalZero #ifndef SELWAIT_T
29*10465441SEvalZero #define SELWAIT_T u8_t
30*10465441SEvalZero #endif
31*10465441SEvalZero #endif
32*10465441SEvalZero 
33*10465441SEvalZero #ifdef SAL_USING_LWIP
34*10465441SEvalZero 
35*10465441SEvalZero #ifdef SAL_USING_POSIX
36*10465441SEvalZero 
37*10465441SEvalZero #if LWIP_VERSION >= 0x20100ff
38*10465441SEvalZero #include <lwip/priv/sockets_priv.h>
39*10465441SEvalZero #else /* LWIP_VERSION < 0x20100ff */
40*10465441SEvalZero /*
41*10465441SEvalZero  * Re-define lwip socket
42*10465441SEvalZero  *
43*10465441SEvalZero  * NOTE: please make sure the definitions same in lwip::net_socket.c
44*10465441SEvalZero  */
45*10465441SEvalZero struct lwip_sock {
46*10465441SEvalZero     /** sockets currently are built on netconns, each socket has one netconn */
47*10465441SEvalZero     struct netconn *conn;
48*10465441SEvalZero     /** data that was left from the previous read */
49*10465441SEvalZero     void *lastdata;
50*10465441SEvalZero     /** offset in the data that was left from the previous read */
51*10465441SEvalZero     u16_t lastoffset;
52*10465441SEvalZero     /** number of times data was received, set by event_callback(),
53*10465441SEvalZero      tested by the receive and select functions */
54*10465441SEvalZero     s16_t rcvevent;
55*10465441SEvalZero     /** number of times data was ACKed (free send buffer), set by event_callback(),
56*10465441SEvalZero      tested by select */
57*10465441SEvalZero     u16_t sendevent;
58*10465441SEvalZero     /** error happened for this socket, set by event_callback(), tested by select */
59*10465441SEvalZero     u16_t errevent;
60*10465441SEvalZero    /** last error that occurred on this socket */
61*10465441SEvalZero #if LWIP_VERSION < 0x2000000
62*10465441SEvalZero    int err;
63*10465441SEvalZero #else
64*10465441SEvalZero    u8_t err;
65*10465441SEvalZero #endif
66*10465441SEvalZero     /** counter of how many threads are waiting for this socket using select */
67*10465441SEvalZero     SELWAIT_T select_waiting;
68*10465441SEvalZero 
69*10465441SEvalZero     rt_wqueue_t wait_head;
70*10465441SEvalZero };
71*10465441SEvalZero #endif /* LWIP_VERSION >= 0x20100ff */
72*10465441SEvalZero 
73*10465441SEvalZero extern struct lwip_sock *lwip_tryget_socket(int s);
74*10465441SEvalZero 
event_callback(struct netconn * conn,enum netconn_evt evt,u16_t len)75*10465441SEvalZero static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
76*10465441SEvalZero {
77*10465441SEvalZero     int s;
78*10465441SEvalZero     struct lwip_sock *sock;
79*10465441SEvalZero     uint32_t event = 0;
80*10465441SEvalZero     SYS_ARCH_DECL_PROTECT(lev);
81*10465441SEvalZero 
82*10465441SEvalZero     LWIP_UNUSED_ARG(len);
83*10465441SEvalZero 
84*10465441SEvalZero     /* Get socket */
85*10465441SEvalZero     if (conn)
86*10465441SEvalZero     {
87*10465441SEvalZero         s = conn->socket;
88*10465441SEvalZero         if (s < 0)
89*10465441SEvalZero         {
90*10465441SEvalZero             /* Data comes in right away after an accept, even though
91*10465441SEvalZero              * the server task might not have created a new socket yet.
92*10465441SEvalZero              * Just count down (or up) if that's the case and we
93*10465441SEvalZero              * will use the data later. Note that only receive events
94*10465441SEvalZero              * can happen before the new socket is set up. */
95*10465441SEvalZero             SYS_ARCH_PROTECT(lev);
96*10465441SEvalZero             if (conn->socket < 0)
97*10465441SEvalZero             {
98*10465441SEvalZero                 if (evt == NETCONN_EVT_RCVPLUS)
99*10465441SEvalZero                 {
100*10465441SEvalZero                     conn->socket--;
101*10465441SEvalZero                 }
102*10465441SEvalZero                 SYS_ARCH_UNPROTECT(lev);
103*10465441SEvalZero                 return;
104*10465441SEvalZero             }
105*10465441SEvalZero             s = conn->socket;
106*10465441SEvalZero             SYS_ARCH_UNPROTECT(lev);
107*10465441SEvalZero         }
108*10465441SEvalZero 
109*10465441SEvalZero         sock = lwip_tryget_socket(s);
110*10465441SEvalZero         if (!sock)
111*10465441SEvalZero         {
112*10465441SEvalZero             return;
113*10465441SEvalZero         }
114*10465441SEvalZero     }
115*10465441SEvalZero     else
116*10465441SEvalZero     {
117*10465441SEvalZero         return;
118*10465441SEvalZero     }
119*10465441SEvalZero 
120*10465441SEvalZero     SYS_ARCH_PROTECT(lev);
121*10465441SEvalZero     /* Set event as required */
122*10465441SEvalZero     switch (evt)
123*10465441SEvalZero     {
124*10465441SEvalZero     case NETCONN_EVT_RCVPLUS:
125*10465441SEvalZero         sock->rcvevent++;
126*10465441SEvalZero         break;
127*10465441SEvalZero     case NETCONN_EVT_RCVMINUS:
128*10465441SEvalZero         sock->rcvevent--;
129*10465441SEvalZero         break;
130*10465441SEvalZero     case NETCONN_EVT_SENDPLUS:
131*10465441SEvalZero         sock->sendevent = 1;
132*10465441SEvalZero         break;
133*10465441SEvalZero     case NETCONN_EVT_SENDMINUS:
134*10465441SEvalZero         sock->sendevent = 0;
135*10465441SEvalZero         break;
136*10465441SEvalZero     case NETCONN_EVT_ERROR:
137*10465441SEvalZero         sock->errevent = 1;
138*10465441SEvalZero         break;
139*10465441SEvalZero     default:
140*10465441SEvalZero         LWIP_ASSERT("unknown event", 0);
141*10465441SEvalZero         break;
142*10465441SEvalZero     }
143*10465441SEvalZero 
144*10465441SEvalZero #if LWIP_VERSION >= 0x20100ff
145*10465441SEvalZero     if ((void*)(sock->lastdata.pbuf) || (sock->rcvevent > 0))
146*10465441SEvalZero #else
147*10465441SEvalZero     if ((void*)(sock->lastdata) || (sock->rcvevent > 0))
148*10465441SEvalZero #endif
149*10465441SEvalZero         event |= POLLIN;
150*10465441SEvalZero     if (sock->sendevent)
151*10465441SEvalZero         event |= POLLOUT;
152*10465441SEvalZero     if (sock->errevent)
153*10465441SEvalZero         event |= POLLERR;
154*10465441SEvalZero 
155*10465441SEvalZero     SYS_ARCH_UNPROTECT(lev);
156*10465441SEvalZero 
157*10465441SEvalZero     if (event)
158*10465441SEvalZero     {
159*10465441SEvalZero         rt_wqueue_wakeup(&sock->wait_head, (void*) event);
160*10465441SEvalZero     }
161*10465441SEvalZero }
162*10465441SEvalZero #endif /* SAL_USING_POSIX */
163*10465441SEvalZero 
inet_socket(int domain,int type,int protocol)164*10465441SEvalZero static int inet_socket(int domain, int type, int protocol)
165*10465441SEvalZero {
166*10465441SEvalZero #ifdef SAL_USING_POSIX
167*10465441SEvalZero     int socket;
168*10465441SEvalZero 
169*10465441SEvalZero     socket = lwip_socket(domain, type, protocol);
170*10465441SEvalZero     if (socket >= 0)
171*10465441SEvalZero     {
172*10465441SEvalZero         struct lwip_sock *lwsock;
173*10465441SEvalZero 
174*10465441SEvalZero         lwsock = lwip_tryget_socket(socket);
175*10465441SEvalZero         lwsock->conn->callback = event_callback;
176*10465441SEvalZero 
177*10465441SEvalZero         rt_wqueue_init(&lwsock->wait_head);
178*10465441SEvalZero     }
179*10465441SEvalZero 
180*10465441SEvalZero     return socket;
181*10465441SEvalZero #else
182*10465441SEvalZero     return lwip_socket(domain, type, protocol);
183*10465441SEvalZero #endif /* SAL_USING_POSIX */
184*10465441SEvalZero }
185*10465441SEvalZero 
inet_accept(int socket,struct sockaddr * addr,socklen_t * addrlen)186*10465441SEvalZero static int inet_accept(int socket, struct sockaddr *addr, socklen_t *addrlen)
187*10465441SEvalZero {
188*10465441SEvalZero #ifdef SAL_USING_POSIX
189*10465441SEvalZero     int new_socket;
190*10465441SEvalZero 
191*10465441SEvalZero     new_socket = lwip_accept(socket, addr, addrlen);
192*10465441SEvalZero     if (new_socket >= 0)
193*10465441SEvalZero     {
194*10465441SEvalZero         struct lwip_sock *lwsock;
195*10465441SEvalZero 
196*10465441SEvalZero         lwsock = lwip_tryget_socket(new_socket);
197*10465441SEvalZero 
198*10465441SEvalZero         rt_wqueue_init(&lwsock->wait_head);
199*10465441SEvalZero     }
200*10465441SEvalZero 
201*10465441SEvalZero     return new_socket;
202*10465441SEvalZero #else
203*10465441SEvalZero     return lwip_accept(socket, addr, addrlen);
204*10465441SEvalZero #endif /* SAL_USING_POSIX */
205*10465441SEvalZero }
206*10465441SEvalZero 
inet_getsockname(int socket,struct sockaddr * name,socklen_t * namelen)207*10465441SEvalZero static int inet_getsockname(int socket, struct sockaddr *name, socklen_t *namelen)
208*10465441SEvalZero {
209*10465441SEvalZero #if LWIP_VERSION_MAJOR < 2U
210*10465441SEvalZero     rt_kprintf("ERROR: Your lwIP version is not supported. Please using lwIP 2.0.0+.\n");
211*10465441SEvalZero     RT_ASSERT(LWIP_VERSION_MAJOR >= 2U);
212*10465441SEvalZero #endif
213*10465441SEvalZero 
214*10465441SEvalZero     return lwip_getsockname(socket, name, namelen);
215*10465441SEvalZero }
216*10465441SEvalZero 
217*10465441SEvalZero #ifdef SAL_USING_POSIX
inet_poll(struct dfs_fd * file,struct rt_pollreq * req)218*10465441SEvalZero static int inet_poll(struct dfs_fd *file, struct rt_pollreq *req)
219*10465441SEvalZero {
220*10465441SEvalZero     int mask = 0;
221*10465441SEvalZero     struct lwip_sock *sock;
222*10465441SEvalZero     struct sal_socket *sal_sock;
223*10465441SEvalZero 
224*10465441SEvalZero     sal_sock = sal_get_socket((int) file->data);
225*10465441SEvalZero     if(!sal_sock)
226*10465441SEvalZero     {
227*10465441SEvalZero         return -1;
228*10465441SEvalZero     }
229*10465441SEvalZero 
230*10465441SEvalZero     sock = lwip_tryget_socket((int)sal_sock->user_data);
231*10465441SEvalZero     if (sock != NULL)
232*10465441SEvalZero     {
233*10465441SEvalZero         rt_base_t level;
234*10465441SEvalZero 
235*10465441SEvalZero         rt_poll_add(&sock->wait_head, req);
236*10465441SEvalZero 
237*10465441SEvalZero         level = rt_hw_interrupt_disable();
238*10465441SEvalZero 
239*10465441SEvalZero #if LWIP_VERSION >= 0x20100ff
240*10465441SEvalZero         if ((void*)(sock->lastdata.pbuf) || sock->rcvevent)
241*10465441SEvalZero #else
242*10465441SEvalZero         if ((void*)(sock->lastdata) || sock->rcvevent)
243*10465441SEvalZero #endif
244*10465441SEvalZero         {
245*10465441SEvalZero             mask |= POLLIN;
246*10465441SEvalZero         }
247*10465441SEvalZero         if (sock->sendevent)
248*10465441SEvalZero         {
249*10465441SEvalZero             mask |= POLLOUT;
250*10465441SEvalZero         }
251*10465441SEvalZero         if (sock->errevent)
252*10465441SEvalZero         {
253*10465441SEvalZero             mask |= POLLERR;
254*10465441SEvalZero         }
255*10465441SEvalZero         rt_hw_interrupt_enable(level);
256*10465441SEvalZero     }
257*10465441SEvalZero 
258*10465441SEvalZero     return mask;
259*10465441SEvalZero }
260*10465441SEvalZero #endif
261*10465441SEvalZero 
262*10465441SEvalZero static const struct sal_socket_ops lwip_socket_ops =
263*10465441SEvalZero {
264*10465441SEvalZero     inet_socket,
265*10465441SEvalZero     lwip_close,
266*10465441SEvalZero     lwip_bind,
267*10465441SEvalZero     lwip_listen,
268*10465441SEvalZero     lwip_connect,
269*10465441SEvalZero     inet_accept,
270*10465441SEvalZero     (int (*)(int, const void *, size_t, int, const struct sockaddr *, socklen_t))lwip_sendto,
271*10465441SEvalZero     (int (*)(int, void *, size_t, int, struct sockaddr *, socklen_t *))lwip_recvfrom,
272*10465441SEvalZero     lwip_getsockopt,
273*10465441SEvalZero     //TODO fix on 1.4.1
274*10465441SEvalZero     lwip_setsockopt,
275*10465441SEvalZero     lwip_shutdown,
276*10465441SEvalZero     lwip_getpeername,
277*10465441SEvalZero     inet_getsockname,
278*10465441SEvalZero     lwip_ioctl,
279*10465441SEvalZero #ifdef SAL_USING_POSIX
280*10465441SEvalZero     inet_poll,
281*10465441SEvalZero #endif
282*10465441SEvalZero };
283*10465441SEvalZero 
inet_create(struct sal_socket * socket,int type,int protocol)284*10465441SEvalZero static int inet_create(struct sal_socket *socket, int type, int protocol)
285*10465441SEvalZero {
286*10465441SEvalZero     RT_ASSERT(socket);
287*10465441SEvalZero 
288*10465441SEvalZero     //TODO Check type & protocol
289*10465441SEvalZero 
290*10465441SEvalZero     socket->ops = &lwip_socket_ops;
291*10465441SEvalZero 
292*10465441SEvalZero     return 0;
293*10465441SEvalZero }
294*10465441SEvalZero 
295*10465441SEvalZero static struct sal_proto_ops lwip_proto_ops =
296*10465441SEvalZero {
297*10465441SEvalZero     lwip_gethostbyname,
298*10465441SEvalZero     lwip_gethostbyname_r,
299*10465441SEvalZero     lwip_getaddrinfo,
300*10465441SEvalZero     lwip_freeaddrinfo,
301*10465441SEvalZero };
302*10465441SEvalZero 
303*10465441SEvalZero static const struct sal_proto_family lwip_inet_family =
304*10465441SEvalZero {
305*10465441SEvalZero     AF_INET,
306*10465441SEvalZero     AF_INET,
307*10465441SEvalZero     inet_create,
308*10465441SEvalZero     &lwip_proto_ops,
309*10465441SEvalZero };
310*10465441SEvalZero 
lwip_inet_init(void)311*10465441SEvalZero int lwip_inet_init(void)
312*10465441SEvalZero {
313*10465441SEvalZero     sal_proto_family_register(&lwip_inet_family);
314*10465441SEvalZero 
315*10465441SEvalZero     return 0;
316*10465441SEvalZero }
317*10465441SEvalZero INIT_COMPONENT_EXPORT(lwip_inet_init);
318*10465441SEvalZero 
319*10465441SEvalZero #endif /* SAL_USING_LWIP */
320