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