1 |
/* |
/* |
2 |
* Copyright (c) 2001-2003 Swedish Institute of Computer Science. |
* Copyright (c) 2001-2003 Swedish Institute of Computer Science. |
3 |
* All rights reserved. |
* All rights reserved. |
4 |
* |
* |
5 |
* Redistribution and use in source and binary forms, with or without modification, |
* Redistribution and use in source and binary forms, with or without modification, |
6 |
* are permitted provided that the following conditions are met: |
* are permitted provided that the following conditions are met: |
7 |
* |
* |
8 |
* 1. Redistributions of source code must retain the above copyright notice, |
* 1. Redistributions of source code must retain the above copyright notice, |
11 |
* this list of conditions and the following disclaimer in the documentation |
* this list of conditions and the following disclaimer in the documentation |
12 |
* and/or other materials provided with the distribution. |
* and/or other materials provided with the distribution. |
13 |
* 3. The name of the author may not be used to endorse or promote products |
* 3. The name of the author may not be used to endorse or promote products |
14 |
* derived from this software without specific prior written permission. |
* derived from this software without specific prior written permission. |
15 |
* |
* |
16 |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
17 |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
18 |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT |
19 |
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
20 |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT |
21 |
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
24 |
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
25 |
* OF SUCH DAMAGE. |
* OF SUCH DAMAGE. |
26 |
* |
* |
27 |
* This file is part of the lwIP TCP/IP stack. |
* This file is part of the lwIP TCP/IP stack. |
28 |
* |
* |
29 |
* Author: Adam Dunkels <adam@sics.se> |
* Author: Adam Dunkels <adam@sics.se> |
30 |
* |
* |
31 |
* Improved by Marc Boucher <marc@mbsi.ca> and David Haas <dhaas@alum.rpi.edu> |
* Improved by Marc Boucher <marc@mbsi.ca> and David Haas <dhaas@alum.rpi.edu> |
51 |
int err; |
int err; |
52 |
}; |
}; |
53 |
|
|
54 |
struct lwip_select_cb |
struct lwip_select_cb |
55 |
{ |
{ |
56 |
struct lwip_select_cb *next; |
struct lwip_select_cb *next; |
57 |
fd_set *readset; |
fd_set *readset; |
104 |
get_socket(int s) |
get_socket(int s) |
105 |
{ |
{ |
106 |
struct lwip_socket *sock; |
struct lwip_socket *sock; |
107 |
|
|
108 |
if ((s < 0) || (s > NUM_SOCKETS)) { |
if ((s < 0) || (s > NUM_SOCKETS)) { |
109 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s)); |
110 |
set_errno(EBADF); |
set_errno(EBADF); |
111 |
return NULL; |
return NULL; |
112 |
} |
} |
113 |
|
|
114 |
sock = &sockets[s]; |
sock = &sockets[s]; |
115 |
|
|
116 |
if (!sock->conn) { |
if (!sock->conn) { |
132 |
|
|
133 |
/* Protect socket array */ |
/* Protect socket array */ |
134 |
sys_sem_wait(socksem); |
sys_sem_wait(socksem); |
135 |
|
|
136 |
/* allocate a new socket identifier */ |
/* allocate a new socket identifier */ |
137 |
for(i = 0; i < NUM_SOCKETS; ++i) { |
for(i = 0; i < NUM_SOCKETS; ++i) { |
138 |
if (!sockets[i].conn) { |
if (!sockets[i].conn) { |
166 |
if (!sock) { |
if (!sock) { |
167 |
return -1; |
return -1; |
168 |
} |
} |
169 |
|
|
170 |
newconn = netconn_accept(sock->conn); |
newconn = netconn_accept(sock->conn); |
171 |
|
|
172 |
/* get the IP address and port of the remote host */ |
/* get the IP address and port of the remote host */ |
173 |
netconn_peer(newconn, &naddr, &port); |
netconn_peer(newconn, &naddr, &port); |
174 |
|
|
175 |
memset(&sin, 0, sizeof(sin)); |
memset(&sin, 0, sizeof(sin)); |
176 |
sin.sin_len = sizeof(sin); |
sin.sin_len = sizeof(sin); |
177 |
sin.sin_family = AF_INET; |
sin.sin_family = AF_INET; |
184 |
memcpy(addr, &sin, *addrlen); |
memcpy(addr, &sin, *addrlen); |
185 |
|
|
186 |
newsock = alloc_socket(newconn); |
newsock = alloc_socket(newconn); |
187 |
if (newsock == -1) { |
if (newsock == -1) { |
188 |
netconn_delete(newconn); |
netconn_delete(newconn); |
189 |
sock_set_errno(sock, ENOBUFS); |
sock_set_errno(sock, ENOBUFS); |
190 |
return -1; |
return -1; |
191 |
} |
} |
192 |
newconn->callback = event_callback; |
newconn->callback = event_callback; |
193 |
sock = get_socket(newsock); |
sock = get_socket(newsock); |
194 |
|
|
195 |
sys_sem_wait(socksem); |
sys_sem_wait(socksem); |
196 |
sock->rcvevent += -1 - newconn->socket; |
sock->rcvevent += -1 - newconn->socket; |
197 |
newconn->socket = newsock; |
newconn->socket = newsock; |
199 |
|
|
200 |
#if SOCKETS_DEBUG |
#if SOCKETS_DEBUG |
201 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock)); |
202 |
ip_addr_debug_print(&naddr); |
ip_addr_debug_print(SOCKETS_DEBUG, &naddr); |
203 |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", port)); |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", port)); |
204 |
#endif |
#endif |
205 |
|
|
206 |
sock_set_errno(sock, 0); |
sock_set_errno(sock, 0); |
207 |
return newsock; |
return newsock; |
208 |
} |
} |
214 |
struct ip_addr local_addr; |
struct ip_addr local_addr; |
215 |
u16_t local_port; |
u16_t local_port; |
216 |
err_t err; |
err_t err; |
217 |
|
|
218 |
sock = get_socket(s); |
sock = get_socket(s); |
219 |
if (!sock) { |
if (!sock) { |
220 |
return -1; |
return -1; |
221 |
} |
} |
222 |
|
|
223 |
local_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr; |
local_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr; |
224 |
local_port = ((struct sockaddr_in *)name)->sin_port; |
local_port = ((struct sockaddr_in *)name)->sin_port; |
225 |
|
|
226 |
#if SOCKETS_DEBUG |
#if SOCKETS_DEBUG |
227 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s)); |
228 |
ip_addr_debug_print(&local_addr); |
ip_addr_debug_print(SOCKETS_DEBUG, &local_addr); |
229 |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(local_port))); |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(local_port))); |
230 |
#endif |
#endif |
231 |
|
|
232 |
err = netconn_bind(sock->conn, &local_addr, ntohs(local_port)); |
err = netconn_bind(sock->conn, &local_addr, ntohs(local_port)); |
233 |
|
|
234 |
if (err != ERR_OK) { |
if (err != ERR_OK) { |
246 |
lwip_close(int s) |
lwip_close(int s) |
247 |
{ |
{ |
248 |
struct lwip_socket *sock; |
struct lwip_socket *sock; |
249 |
|
|
250 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s)); |
251 |
if (!socksem) |
if (!socksem) |
252 |
socksem = sys_sem_new(1); |
socksem = sys_sem_new(1); |
253 |
|
|
254 |
/* We cannot allow multiple closes of the same socket. */ |
/* We cannot allow multiple closes of the same socket. */ |
255 |
sys_sem_wait(socksem); |
sys_sem_wait(socksem); |
256 |
|
|
257 |
sock = get_socket(s); |
sock = get_socket(s); |
258 |
if (!sock) { |
if (!sock) { |
259 |
sys_sem_signal(socksem); |
sys_sem_signal(socksem); |
260 |
return -1; |
return -1; |
261 |
} |
} |
262 |
|
|
263 |
netconn_delete(sock->conn); |
netconn_delete(sock->conn); |
264 |
if (sock->lastdata) { |
if (sock->lastdata) { |
265 |
netbuf_delete(sock->lastdata); |
netbuf_delete(sock->lastdata); |
282 |
if (!sock) { |
if (!sock) { |
283 |
return -1; |
return -1; |
284 |
} |
} |
285 |
|
|
286 |
if (((struct sockaddr_in *)name)->sin_family == AF_UNSPEC) { |
if (((struct sockaddr_in *)name)->sin_family == AF_UNSPEC) { |
287 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); |
288 |
err = netconn_disconnect(sock->conn); |
err = netconn_disconnect(sock->conn); |
295 |
|
|
296 |
#if SOCKETS_DEBUG |
#if SOCKETS_DEBUG |
297 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); |
298 |
ip_addr_debug_print(&remote_addr); |
ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr); |
299 |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(remote_port))); |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(remote_port))); |
300 |
#endif |
#endif |
301 |
|
|
302 |
err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port)); |
err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port)); |
303 |
} |
} |
304 |
|
|
316 |
int |
int |
317 |
lwip_listen(int s, int backlog) |
lwip_listen(int s, int backlog) |
318 |
{ |
{ |
319 |
struct lwip_socket *sock; |
struct lwip_socket *sock; |
320 |
err_t err; |
err_t err; |
321 |
|
|
322 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); |
323 |
sock = get_socket(s); |
sock = get_socket(s); |
324 |
if (!sock) { |
if (!sock) { |
325 |
return -1; |
return -1; |
326 |
} |
} |
327 |
|
|
328 |
err = netconn_listen(sock->conn); |
err = netconn_listen(sock->conn); |
329 |
|
|
330 |
if (err != ERR_OK) { |
if (err != ERR_OK) { |
347 |
struct ip_addr *addr; |
struct ip_addr *addr; |
348 |
u16_t port; |
u16_t port; |
349 |
|
|
350 |
|
|
351 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %d, 0x%x, ..)\n", s, mem, len, flags)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %d, 0x%x, ..)\n", s, mem, len, flags)); |
352 |
sock = get_socket(s); |
sock = get_socket(s); |
353 |
if (!sock) { |
if (!sock) { |
355 |
} |
} |
356 |
|
|
357 |
/* Check if there is data left from the last recv operation. */ |
/* Check if there is data left from the last recv operation. */ |
358 |
if (sock->lastdata) { |
if (sock->lastdata) { |
359 |
buf = sock->lastdata; |
buf = sock->lastdata; |
360 |
} else { |
} else { |
361 |
/* If this is non-blocking call, then check first */ |
/* If this is non-blocking call, then check first */ |
366 |
sock_set_errno(sock, EWOULDBLOCK); |
sock_set_errno(sock, EWOULDBLOCK); |
367 |
return -1; |
return -1; |
368 |
} |
} |
369 |
|
|
370 |
/* No data was left from the previous operation, so we try to get |
/* No data was left from the previous operation, so we try to get |
371 |
some from the network. */ |
some from the network. */ |
372 |
buf = netconn_recv(sock->conn); |
buf = netconn_recv(sock->conn); |
373 |
|
|
374 |
if (!buf) { |
if (!buf) { |
375 |
/* We should really do some error checking here. */ |
/* We should really do some error checking here. */ |
376 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL!\n", s)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL!\n", s)); |
378 |
return 0; |
return 0; |
379 |
} |
} |
380 |
} |
} |
381 |
|
|
382 |
buflen = netbuf_len(buf); |
buflen = netbuf_len(buf); |
383 |
|
|
384 |
buflen -= sock->lastoffset; |
buflen -= sock->lastoffset; |
385 |
|
|
386 |
if (len > buflen) { |
if (len > buflen) { |
387 |
copylen = buflen; |
copylen = buflen; |
388 |
} else { |
} else { |
389 |
copylen = len; |
copylen = len; |
390 |
} |
} |
391 |
|
|
392 |
/* copy the contents of the received buffer into |
/* copy the contents of the received buffer into |
393 |
the supplied memory pointer mem */ |
the supplied memory pointer mem */ |
394 |
netbuf_copy_partial(buf, mem, copylen, sock->lastoffset); |
netbuf_copy_partial(buf, mem, copylen, sock->lastoffset); |
413 |
|
|
414 |
#if SOCKETS_DEBUG |
#if SOCKETS_DEBUG |
415 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); |
416 |
ip_addr_debug_print(addr); |
ip_addr_debug_print(SOCKETS_DEBUG, addr); |
417 |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen)); |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen)); |
418 |
#endif |
#endif |
419 |
} else { |
} else { |
420 |
#if SOCKETS_DEBUG > 0 |
#if SOCKETS_DEBUG > 0 |
421 |
addr = netbuf_fromaddr(buf); |
addr = netbuf_fromaddr(buf); |
422 |
port = netbuf_fromport(buf); |
port = netbuf_fromport(buf); |
423 |
|
|
424 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); |
425 |
ip_addr_debug_print(addr); |
ip_addr_debug_print(SOCKETS_DEBUG, addr); |
426 |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen)); |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen)); |
427 |
#endif |
#endif |
428 |
|
|
429 |
} |
} |
430 |
|
|
431 |
/* If this is a TCP socket, check if there is data left in the |
/* If this is a TCP socket, check if there is data left in the |
432 |
buffer. If so, it should be saved in the sock structure for next |
buffer. If so, it should be saved in the sock structure for next |
433 |
time around. */ |
time around. */ |
440 |
netbuf_delete(buf); |
netbuf_delete(buf); |
441 |
} |
} |
442 |
|
|
443 |
|
|
444 |
sock_set_errno(sock, 0); |
sock_set_errno(sock, 0); |
445 |
return copylen; |
return copylen; |
446 |
} |
} |
469 |
sock = get_socket(s); |
sock = get_socket(s); |
470 |
if (!sock) { |
if (!sock) { |
471 |
return -1; |
return -1; |
472 |
} |
} |
473 |
|
|
474 |
switch (netconn_type(sock->conn)) { |
switch (netconn_type(sock->conn)) { |
475 |
case NETCONN_UDP: |
case NETCONN_UDP: |
476 |
/* create a buffer */ |
/* create a buffer */ |
481 |
sock_set_errno(sock, ENOBUFS); |
sock_set_errno(sock, ENOBUFS); |
482 |
return -1; |
return -1; |
483 |
} |
} |
484 |
|
|
485 |
/* make the buffer point to the data that should |
/* make the buffer point to the data that should |
486 |
be sent */ |
be sent */ |
487 |
netbuf_ref(buf, data, size); |
netbuf_ref(buf, data, size); |
502 |
if (err != ERR_OK) { |
if (err != ERR_OK) { |
503 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d\n", s, err)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d\n", s, err)); |
504 |
sock_set_errno(sock, err_to_errno(err)); |
sock_set_errno(sock, err_to_errno(err)); |
505 |
return -1; |
return -1; |
506 |
} |
} |
507 |
|
|
508 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ok size=%d\n", s, size)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ok size=%d\n", s, size)); |
523 |
if (!sock) { |
if (!sock) { |
524 |
return -1; |
return -1; |
525 |
} |
} |
526 |
|
|
527 |
/* get the peer if currently connected */ |
/* get the peer if currently connected */ |
528 |
connected = (netconn_peer(sock->conn, &addr, &port) == ERR_OK); |
connected = (netconn_peer(sock->conn, &addr, &port) == ERR_OK); |
529 |
|
|
530 |
remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr; |
remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr; |
531 |
remote_port = ((struct sockaddr_in *)to)->sin_port; |
remote_port = ((struct sockaddr_in *)to)->sin_port; |
532 |
|
|
533 |
#if SOCKETS_DEBUG |
#if SOCKETS_DEBUG |
534 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, size=%d, flags=0x%x to=", s, data, size, flags)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, size=%d, flags=0x%x to=", s, data, size, flags)); |
535 |
ip_addr_debug_print(&remote_addr); |
ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr); |
536 |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", ntohs(remote_port))); |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", ntohs(remote_port))); |
537 |
#endif |
#endif |
538 |
|
|
539 |
netconn_connect(sock->conn, &remote_addr, ntohs(remote_port)); |
netconn_connect(sock->conn, &remote_addr, ntohs(remote_port)); |
540 |
|
|
541 |
ret = lwip_send(s, data, size, flags); |
ret = lwip_send(s, data, size, flags); |
542 |
|
|
543 |
/* reset the remote address and port number |
/* reset the remote address and port number |
607 |
FD_ZERO(&lreadset); |
FD_ZERO(&lreadset); |
608 |
FD_ZERO(&lwriteset); |
FD_ZERO(&lwriteset); |
609 |
FD_ZERO(&lexceptset); |
FD_ZERO(&lexceptset); |
610 |
|
|
611 |
/* Go through each socket in each list to count number of sockets which |
/* Go through each socket in each list to count number of sockets which |
612 |
currently match */ |
currently match */ |
613 |
for(i = 0; i < maxfdp1; i++) |
for(i = 0; i < maxfdp1; i++) |
662 |
select_cb.writeset = writeset; |
select_cb.writeset = writeset; |
663 |
select_cb.exceptset = exceptset; |
select_cb.exceptset = exceptset; |
664 |
select_cb.sem_signalled = 0; |
select_cb.sem_signalled = 0; |
665 |
|
|
666 |
/* Protect ourselves searching through the list */ |
/* Protect ourselves searching through the list */ |
667 |
if (!selectsem) |
if (!selectsem) |
668 |
selectsem = sys_sem_new(1); |
selectsem = sys_sem_new(1); |
669 |
sys_sem_wait(selectsem); |
sys_sem_wait(selectsem); |
670 |
|
|
671 |
if (readset) |
if (readset) |
672 |
lreadset = *readset; |
lreadset = *readset; |
673 |
else |
else |
680 |
lexceptset = *exceptset; |
lexceptset = *exceptset; |
681 |
else |
else |
682 |
FD_ZERO(&lexceptset); |
FD_ZERO(&lexceptset); |
683 |
|
|
684 |
/* Go through each socket in each list to count number of sockets which |
/* Go through each socket in each list to count number of sockets which |
685 |
currently match */ |
currently match */ |
686 |
nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset); |
nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset); |
687 |
|
|
688 |
/* If we don't have any current events, then suspend if we are supposed to */ |
/* If we don't have any current events, then suspend if we are supposed to */ |
689 |
if (!nready) |
if (!nready) |
690 |
{ |
{ |
703 |
|
|
704 |
return 0; |
return 0; |
705 |
} |
} |
706 |
|
|
707 |
/* add our semaphore to list */ |
/* add our semaphore to list */ |
708 |
/* We don't actually need any dynamic memory. Our entry on the |
/* We don't actually need any dynamic memory. Our entry on the |
709 |
* list is only valid while we are in this function, so it's ok |
* list is only valid while we are in this function, so it's ok |
738 |
p_selcb->next = select_cb.next; |
p_selcb->next = select_cb.next; |
739 |
break; |
break; |
740 |
} |
} |
741 |
|
|
742 |
sys_sem_signal(selectsem); |
sys_sem_signal(selectsem); |
743 |
|
|
744 |
sys_sem_free(select_cb.sem); |
sys_sem_free(select_cb.sem); |
745 |
if (i == 0) /* Timeout */ |
if (i == 0) /* Timeout */ |
746 |
{ |
{ |
775 |
} |
} |
776 |
else |
else |
777 |
sys_sem_signal(selectsem); |
sys_sem_signal(selectsem); |
778 |
|
|
779 |
if (readset) |
if (readset) |
780 |
*readset = lreadset; |
*readset = lreadset; |
781 |
if (writeset) |
if (writeset) |
782 |
*writeset = lwriteset; |
*writeset = lwriteset; |
783 |
if (exceptset) |
if (exceptset) |
784 |
*exceptset = lexceptset; |
*exceptset = lexceptset; |
785 |
|
|
786 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); |
787 |
set_errno(0); |
set_errno(0); |
788 |
|
|
796 |
int s; |
int s; |
797 |
struct lwip_socket *sock; |
struct lwip_socket *sock; |
798 |
struct lwip_select_cb *scb; |
struct lwip_select_cb *scb; |
799 |
|
|
800 |
/* Get socket */ |
/* Get socket */ |
801 |
if (conn) |
if (conn) |
802 |
{ |
{ |
812 |
conn->socket--; |
conn->socket--; |
813 |
return; |
return; |
814 |
} |
} |
815 |
|
|
816 |
sock = get_socket(s); |
sock = get_socket(s); |
817 |
if (!sock) |
if (!sock) |
818 |
return; |
return; |
822 |
|
|
823 |
if (!selectsem) |
if (!selectsem) |
824 |
selectsem = sys_sem_new(1); |
selectsem = sys_sem_new(1); |
825 |
|
|
826 |
sys_sem_wait(selectsem); |
sys_sem_wait(selectsem); |
827 |
/* Set event as required */ |
/* Set event as required */ |
828 |
switch (evt) |
switch (evt) |
841 |
break; |
break; |
842 |
} |
} |
843 |
sys_sem_signal(selectsem); |
sys_sem_signal(selectsem); |
844 |
|
|
845 |
/* Now decide if anyone is waiting for this socket */ |
/* Now decide if anyone is waiting for this socket */ |
846 |
/* NOTE: This code is written this way to protect the select link list |
/* NOTE: This code is written this way to protect the select link list |
847 |
but to avoid a deadlock situation by releasing socksem before |
but to avoid a deadlock situation by releasing socksem before |
875 |
break; |
break; |
876 |
} |
} |
877 |
} |
} |
878 |
|
|
879 |
} |
} |
880 |
|
|
881 |
/*-----------------------------------------------------------------------------------*/ |
/*-----------------------------------------------------------------------------------*/ |
897 |
if (!sock) { |
if (!sock) { |
898 |
return -1; |
return -1; |
899 |
} |
} |
900 |
|
|
901 |
memset(&sin, 0, sizeof(sin)); |
memset(&sin, 0, sizeof(sin)); |
902 |
sin.sin_len = sizeof(sin); |
sin.sin_len = sizeof(sin); |
903 |
sin.sin_family = AF_INET; |
sin.sin_family = AF_INET; |
904 |
|
|
905 |
/* get the IP address and port of the remote host */ |
/* get the IP address and port of the remote host */ |
906 |
netconn_peer(sock->conn, &naddr, &sin.sin_port); |
netconn_peer(sock->conn, &naddr, &sin.sin_port); |
907 |
|
|
908 |
#if SOCKETS_DEBUG |
#if SOCKETS_DEBUG |
909 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getpeername(%d, addr=", s)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getpeername(%d, addr=", s)); |
910 |
ip_addr_debug_print(&naddr); |
ip_addr_debug_print(SOCKETS_DEBUG, &naddr); |
911 |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port)); |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port)); |
912 |
#endif |
#endif |
913 |
|
|
914 |
sin.sin_port = htons(sin.sin_port); |
sin.sin_port = htons(sin.sin_port); |
915 |
sin.sin_addr.s_addr = naddr.addr; |
sin.sin_addr.s_addr = naddr.addr; |
916 |
|
|
932 |
if (!sock) { |
if (!sock) { |
933 |
return -1; |
return -1; |
934 |
} |
} |
935 |
|
|
936 |
memset(&sin, 0, sizeof(sin)); |
memset(&sin, 0, sizeof(sin)); |
937 |
sin.sin_len = sizeof(sin); |
sin.sin_len = sizeof(sin); |
938 |
sin.sin_family = AF_INET; |
sin.sin_family = AF_INET; |
942 |
|
|
943 |
#if SOCKETS_DEBUG |
#if SOCKETS_DEBUG |
944 |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockname(%d, addr=", s)); |
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockname(%d, addr=", s)); |
945 |
ip_addr_debug_print(naddr); |
ip_addr_debug_print(SOCKETS_DEBUG, naddr); |
946 |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port)); |
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port)); |
947 |
#endif |
#endif |
948 |
|
|
949 |
sin.sin_port = htons(sin.sin_port); |
sin.sin_port = htons(sin.sin_port); |
950 |
sin.sin_addr.s_addr = naddr->addr; |
sin.sin_addr.s_addr = naddr->addr; |
951 |
|
|