97 |
#define sock_set_errno(sk, e) do { \ |
#define sock_set_errno(sk, e) do { \ |
98 |
sk->err = (e); \ |
sk->err = (e); \ |
99 |
set_errno(sk->err); \ |
set_errno(sk->err); \ |
100 |
} while(0) |
} while (0) |
101 |
|
|
102 |
/*-----------------------------------------------------------------------------------*/ |
/*-----------------------------------------------------------------------------------*/ |
103 |
static struct lwip_socket * |
static struct lwip_socket * |
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 |
DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s)); |
DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s)); |
110 |
set_errno(EBADF); |
set_errno(EBADF); |
111 |
return NULL; |
return NULL; |
113 |
|
|
114 |
sock = &sockets[s]; |
sock = &sockets[s]; |
115 |
|
|
116 |
if(!sock->conn) { |
if (!sock->conn) { |
117 |
DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s)); |
DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s)); |
118 |
set_errno(EBADF); |
set_errno(EBADF); |
119 |
return NULL; |
return NULL; |
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) { |
139 |
sockets[i].conn = newconn; |
sockets[i].conn = newconn; |
140 |
sockets[i].lastdata = NULL; |
sockets[i].lastdata = NULL; |
141 |
sockets[i].lastoffset = 0; |
sockets[i].lastoffset = 0; |
163 |
|
|
164 |
DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); |
165 |
sock = get_socket(s); |
sock = get_socket(s); |
166 |
if(!sock) { |
if (!sock) { |
167 |
return -1; |
return -1; |
168 |
} |
} |
169 |
|
|
178 |
sin.sin_port = htons(port); |
sin.sin_port = htons(port); |
179 |
sin.sin_addr.s_addr = naddr.addr; |
sin.sin_addr.s_addr = naddr.addr; |
180 |
|
|
181 |
if(*addrlen > sizeof(sin)) |
if (*addrlen > sizeof(sin)) |
182 |
*addrlen = sizeof(sin); |
*addrlen = sizeof(sin); |
183 |
|
|
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; |
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 |
|
|
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) { |
235 |
DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); |
236 |
sock_set_errno(sock, err_to_errno(err)); |
sock_set_errno(sock, err_to_errno(err)); |
237 |
return -1; |
return -1; |
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); |
266 |
} |
} |
267 |
sock->lastdata = NULL; |
sock->lastdata = NULL; |
279 |
err_t err; |
err_t err; |
280 |
|
|
281 |
sock = get_socket(s); |
sock = get_socket(s); |
282 |
if(!sock) { |
if (!sock) { |
283 |
return -1; |
return -1; |
284 |
} |
} |
285 |
|
|
302 |
err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port)); |
err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port)); |
303 |
} |
} |
304 |
|
|
305 |
if(err != ERR_OK) { |
if (err != ERR_OK) { |
306 |
DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); |
307 |
sock_set_errno(sock, err_to_errno(err)); |
sock_set_errno(sock, err_to_errno(err)); |
308 |
return -1; |
return -1; |
321 |
|
|
322 |
DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); |
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) { |
331 |
DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); |
332 |
sock_set_errno(sock, err_to_errno(err)); |
sock_set_errno(sock, err_to_errno(err)); |
333 |
return -1; |
return -1; |
350 |
|
|
351 |
DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %d, 0x%x, ..)\n", s, mem, len, flags)); |
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) { |
354 |
return -1; |
return -1; |
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 */ |
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 |
DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL!\n", s)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL!\n", s)); |
377 |
sock_set_errno(sock, 0); |
sock_set_errno(sock, 0); |
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; |
394 |
netbuf_copy_partial(buf, mem, copylen, sock->lastoffset); |
netbuf_copy_partial(buf, mem, copylen, sock->lastoffset); |
395 |
|
|
396 |
/* Check to see from where the data was. */ |
/* Check to see from where the data was. */ |
397 |
if(from && fromlen) { |
if (from && fromlen) { |
398 |
struct sockaddr_in sin; |
struct sockaddr_in sin; |
399 |
|
|
400 |
addr = netbuf_fromaddr(buf); |
addr = netbuf_fromaddr(buf); |
406 |
sin.sin_port = htons(port); |
sin.sin_port = htons(port); |
407 |
sin.sin_addr.s_addr = addr->addr; |
sin.sin_addr.s_addr = addr->addr; |
408 |
|
|
409 |
if(*fromlen > sizeof(sin)) |
if (*fromlen > sizeof(sin)) |
410 |
*fromlen = sizeof(sin); |
*fromlen = sizeof(sin); |
411 |
|
|
412 |
memcpy(from, &sin, *fromlen); |
memcpy(from, &sin, *fromlen); |
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. */ |
434 |
if(netconn_type(sock->conn) == NETCONN_TCP && buflen - copylen > 0) { |
if (netconn_type(sock->conn) == NETCONN_TCP && buflen - copylen > 0) { |
435 |
sock->lastdata = buf; |
sock->lastdata = buf; |
436 |
sock->lastoffset += copylen; |
sock->lastoffset += copylen; |
437 |
} else { |
} else { |
467 |
DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%d, flags=0x%x)\n", s, data, size, flags)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%d, flags=0x%x)\n", s, data, size, flags)); |
468 |
|
|
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 */ |
477 |
buf = netbuf_new(); |
buf = netbuf_new(); |
478 |
|
|
479 |
if(!buf) { |
if (!buf) { |
480 |
DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ENOBUFS\n", s)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ENOBUFS\n", s)); |
481 |
sock_set_errno(sock, ENOBUFS); |
sock_set_errno(sock, ENOBUFS); |
482 |
return -1; |
return -1; |
499 |
err = ERR_ARG; |
err = ERR_ARG; |
500 |
break; |
break; |
501 |
} |
} |
502 |
if(err != ERR_OK) { |
if (err != ERR_OK) { |
503 |
DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d\n", s, err)); |
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; |
520 |
int ret,connected; |
int ret,connected; |
521 |
|
|
522 |
sock = get_socket(s); |
sock = get_socket(s); |
523 |
if(!sock) { |
if (!sock) { |
524 |
return -1; |
return -1; |
525 |
} |
} |
526 |
|
|
542 |
|
|
543 |
/* reset the remote address and port number |
/* reset the remote address and port number |
544 |
of the connection */ |
of the connection */ |
545 |
if(connected) |
if (connected) |
546 |
netconn_connect(sock->conn, &addr, port); |
netconn_connect(sock->conn, &addr, port); |
547 |
else |
else |
548 |
netconn_disconnect(sock->conn); |
netconn_disconnect(sock->conn); |
556 |
int i; |
int i; |
557 |
|
|
558 |
/* create a netconn */ |
/* create a netconn */ |
559 |
switch(type) { |
switch (type) { |
560 |
case SOCK_DGRAM: |
case SOCK_DGRAM: |
561 |
conn = netconn_new_with_callback(NETCONN_UDP, event_callback); |
conn = netconn_new_with_callback(NETCONN_UDP, event_callback); |
562 |
DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); |
571 |
return -1; |
return -1; |
572 |
} |
} |
573 |
|
|
574 |
if(!conn) { |
if (!conn) { |
575 |
DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n")); |
DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n")); |
576 |
set_errno(ENOBUFS); |
set_errno(ENOBUFS); |
577 |
return -1; |
return -1; |
579 |
|
|
580 |
i = alloc_socket(conn); |
i = alloc_socket(conn); |
581 |
|
|
582 |
if(i == -1) { |
if (i == -1) { |
583 |
netconn_delete(conn); |
netconn_delete(conn); |
584 |
set_errno(ENOBUFS); |
set_errno(ENOBUFS); |
585 |
return -1; |
return -1; |
612 |
currently match */ |
currently match */ |
613 |
for(i = 0; i < maxfdp1; i++) |
for(i = 0; i < maxfdp1; i++) |
614 |
{ |
{ |
615 |
if(FD_ISSET(i, readset)) |
if (FD_ISSET(i, readset)) |
616 |
{ |
{ |
617 |
/* See if netconn of this socket is ready for read */ |
/* See if netconn of this socket is ready for read */ |
618 |
p_sock = get_socket(i); |
p_sock = get_socket(i); |
623 |
nready++; |
nready++; |
624 |
} |
} |
625 |
} |
} |
626 |
if(FD_ISSET(i, writeset)) |
if (FD_ISSET(i, writeset)) |
627 |
{ |
{ |
628 |
/* See if netconn of this socket is ready for write */ |
/* See if netconn of this socket is ready for write */ |
629 |
p_sock = get_socket(i); |
p_sock = get_socket(i); |
888 |
struct ip_addr naddr; |
struct ip_addr naddr; |
889 |
|
|
890 |
sock = get_socket(s); |
sock = get_socket(s); |
891 |
if(!sock) { |
if (!sock) { |
892 |
return -1; |
return -1; |
893 |
} |
} |
894 |
|
|
908 |
sin.sin_port = htons(sin.sin_port); |
sin.sin_port = htons(sin.sin_port); |
909 |
sin.sin_addr.s_addr = naddr.addr; |
sin.sin_addr.s_addr = naddr.addr; |
910 |
|
|
911 |
if(*namelen > sizeof(sin)) |
if (*namelen > sizeof(sin)) |
912 |
*namelen = sizeof(sin); |
*namelen = sizeof(sin); |
913 |
|
|
914 |
memcpy(name, &sin, *namelen); |
memcpy(name, &sin, *namelen); |
923 |
struct ip_addr *naddr; |
struct ip_addr *naddr; |
924 |
|
|
925 |
sock = get_socket(s); |
sock = get_socket(s); |
926 |
if(!sock) { |
if (!sock) { |
927 |
return -1; |
return -1; |
928 |
} |
} |
929 |
|
|
943 |
sin.sin_port = htons(sin.sin_port); |
sin.sin_port = htons(sin.sin_port); |
944 |
sin.sin_addr.s_addr = naddr->addr; |
sin.sin_addr.s_addr = naddr->addr; |
945 |
|
|
946 |
if(*namelen > sizeof(sin)) |
if (*namelen > sizeof(sin)) |
947 |
*namelen = sizeof(sin); |
*namelen = sizeof(sin); |
948 |
|
|
949 |
memcpy(name, &sin, *namelen); |
memcpy(name, &sin, *namelen); |
956 |
int err = ENOSYS; |
int err = ENOSYS; |
957 |
struct lwip_socket *sock = get_socket(s); |
struct lwip_socket *sock = get_socket(s); |
958 |
|
|
959 |
if(!sock) { |
if (!sock) { |
960 |
return -1; |
return -1; |
961 |
} |
} |
962 |
|
|
963 |
if(level == SOL_SOCKET) { |
if (level == SOL_SOCKET) { |
964 |
switch(optname) { |
switch (optname) { |
965 |
case SO_ERROR: |
case SO_ERROR: |
966 |
if(!optval || !optlen || (*optlen != sizeof(int))) { |
if (!optval || !optlen || (*optlen != sizeof(int))) { |
967 |
err = EINVAL; |
err = EINVAL; |
968 |
break; |
break; |
969 |
} |
} |
988 |
struct lwip_socket *sock = get_socket(s); |
struct lwip_socket *sock = get_socket(s); |
989 |
int err = ENOSYS; |
int err = ENOSYS; |
990 |
|
|
991 |
if(!sock) { |
if (!sock) { |
992 |
return -1; |
return -1; |
993 |
} |
} |
994 |
|
|
995 |
if(level == SOL_SOCKET) { |
if (level == SOL_SOCKET) { |
996 |
switch(optname) { |
switch (optname) { |
997 |
case SO_REUSEADDR: |
case SO_REUSEADDR: |
998 |
DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, SO_REUSEADDR, ..)\n", s)); |
DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, SO_REUSEADDR, ..)\n", s)); |
999 |
/* XXX just pretend we support this for now */ |
/* XXX just pretend we support this for now */ |
1015 |
{ |
{ |
1016 |
struct lwip_socket *sock = get_socket(s); |
struct lwip_socket *sock = get_socket(s); |
1017 |
|
|
1018 |
if(!sock) { |
if (!sock) { |
1019 |
return -1; |
return -1; |
1020 |
} |
} |
1021 |
|
|
1022 |
switch(cmd) { |
switch (cmd) { |
1023 |
case FIONREAD: |
case FIONREAD: |
1024 |
if(!argp) { |
if (!argp) { |
1025 |
sock_set_errno(sock, EINVAL); |
sock_set_errno(sock, EINVAL); |
1026 |
return -1; |
return -1; |
1027 |
} |
} |
1033 |
return 0; |
return 0; |
1034 |
|
|
1035 |
case FIONBIO: |
case FIONBIO: |
1036 |
if(argp && *(u32_t*)argp) |
if (argp && *(u32_t*)argp) |
1037 |
sock->flags |= O_NONBLOCK; |
sock->flags |= O_NONBLOCK; |
1038 |
else |
else |
1039 |
sock->flags &= ~O_NONBLOCK; |
sock->flags &= ~O_NONBLOCK; |