Verified recvfrom()
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@402 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
ef651cc6bc
commit
2ce5085cc8
14
ChangeLog
14
ChangeLog
@ -215,7 +215,7 @@
|
||||
* Added listen() and accept()
|
||||
* Added DM90x0 ethernet driver
|
||||
* ARP timer is now built into the network layer
|
||||
* Basic client functionality verified: socket(), bind(), connect(), recv(), send().
|
||||
* Basic client functionality verified: TCP socket(), bind(), connect(), recv(), send().
|
||||
|
||||
0.3.1 2007-11-19 Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
@ -223,12 +223,12 @@
|
||||
* Corrected a TCP problem where packets were dropped because there was no
|
||||
recv() in place but the packet was being ACKed. There are still TCP
|
||||
recv buffering issues, but this is part of a larger buffering issue.
|
||||
* Basic server functionality verified: listen(), accept()
|
||||
* Basic server functionality verified: TCP listen(), accept()
|
||||
* Fix DM90x0 driver problem that caused TX overruns
|
||||
* Add strncmp()
|
||||
* Added TCP/IP read-ahead buffer to minimize failed ACKs and packet loss.
|
||||
|
||||
0.3.2 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
0.3.2 2007-11-23 Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
* Add strcat() and strncat()
|
||||
* Integrated uIP micro webserver
|
||||
@ -239,4 +239,10 @@
|
||||
* Moved urgent data info into device structure.
|
||||
* TCP and ICMP protocols can now be disabled.
|
||||
* Added UDP test in examples/udp
|
||||
* Verified/debugged UDP send logic using examples/udp
|
||||
* Verified/debugged UDP socket(), bind(), sendto() and recvfrom() logic
|
||||
using examples/udp
|
||||
* recvfrom() and accept() now correctly return the remote address.
|
||||
* Fixed computation error in ntohl().
|
||||
|
||||
0.3.3 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
<tr align="center" bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
||||
<p>Last Updated: November 20, 2007</p>
|
||||
<p>Last Updated: November 23, 2007</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -183,27 +183,36 @@
|
||||
</table>
|
||||
|
||||
<p>
|
||||
The 13th release of NuttX (nuttx-0.3.0) is available for download
|
||||
from the <a href="http://sourceforge.net/project/showfiles.php?group_id=189573">SourceForge</a>
|
||||
website.
|
||||
The change log associated with the release is available <a href="#currentrelease">here</a>.
|
||||
Unreleased changes after this release are avalable in CVS.
|
||||
These unreleased changes are listed <a href="#pendingchanges">here</a>.
|
||||
The 14th release of NuttX (nuttx-0.3.2) is available for download
|
||||
from the <a href="http://sourceforge.net/project/showfiles.php?group_id=189573">SourceForge</a>
|
||||
website.
|
||||
The change log associated with the release is available <a href="#currentrelease">here</a>.
|
||||
Unreleased changes after this release are avalable in CVS.
|
||||
These unreleased changes are listed <a href="#pendingchanges">here</a>.
|
||||
</p>
|
||||
<p>
|
||||
NuttX 0.3.1 is the second release containing the integration of a network
|
||||
NuttX 0.3.2 is the 3rd release containing the integration of a network
|
||||
subsystem and the uIP TCP/IP, UDP, and ICMP stacks based on
|
||||
<a href="http://www.sics.se/~adam/uip/index.php/Main_Page">uIP</a>
|
||||
into NuttX.
|
||||
</p>
|
||||
<p>
|
||||
Many network-related problems have been fixed from version 0.3.0
|
||||
Many network-related problems have been fixed from version 0.3.1
|
||||
and the implementation has matured significantly.
|
||||
However, the level of network reliability is probably still at the
|
||||
pre-alpha or early level.
|
||||
It is sufficiently complete that you may begin to perform some network
|
||||
integration and is exepcted to achieve beta level of reliability over
|
||||
the next few releases.
|
||||
Changes in this release include:
|
||||
</p>
|
||||
<ul>
|
||||
<li>TCP-related bug-fixes,</li>
|
||||
<li>TCP performance improvements,</li>
|
||||
<li>Initial UDP integration, and</li>
|
||||
<li>Initial uIP micro webserver integration
|
||||
</ul>
|
||||
</p>
|
||||
See the ChangeLog for a complete list of changes.
|
||||
</p>
|
||||
<p>
|
||||
The level of network reliability is a a strong alpha level is expected to
|
||||
achieve beta level of reliability over the next few releases.
|
||||
</p>
|
||||
<p>
|
||||
The baseline functionality of NuttX continues to mature and remains at
|
||||
@ -667,17 +676,7 @@ Other memory:
|
||||
* Added DM90x0 ethernet driver
|
||||
* ARP timer is now built into the network layer
|
||||
* Basic client functionality verified: socket(), bind(), connect(), recv(), send().
|
||||
</pre></ul>
|
||||
|
||||
<table width ="100%">
|
||||
<tr bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<a name="currentrelease">ChangeLog for Current Release</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<pre><ul>
|
||||
0.3.1 2007-11-19 Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
* Separated net/uip/uip.c into several functions in several files.
|
||||
@ -693,7 +692,7 @@ Other memory:
|
||||
<table width ="100%">
|
||||
<tr bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<a name="pendingchanges">Unreleased Changes</a>
|
||||
<a name="currentrelease">ChangeLog for Current Release</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -710,7 +709,22 @@ Other memory:
|
||||
* Moved urgent data info into device structure.
|
||||
* TCP and ICMP protocols can now be disabled.
|
||||
* Added UDP test in examples/udp
|
||||
* Verified/debugged UDP send logic using examples/udp
|
||||
* Verified/debugged UDP socket(), bind(), sendto() and recvfrom() logic
|
||||
using examples/udp
|
||||
* recvfrom() and accept() now correctly return the remote address.
|
||||
* Fixed computation error in ntohl().
|
||||
</pre></ul>
|
||||
|
||||
<table width ="100%">
|
||||
<tr bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<a name="pendingchanges">Unreleased Changes</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<pre><ul>
|
||||
0.3.3 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
</pre></ul>
|
||||
|
||||
<table width ="100%">
|
||||
|
24
ReleaseNotes
24
ReleaseNotes
@ -1,23 +1,27 @@
|
||||
nuttx-0.3.1
|
||||
nuttx-0.3.2
|
||||
^^^^^^^^^^^
|
||||
|
||||
This is the 13th release of NuttX and the second release containing
|
||||
This is the 14th release of NuttX and the 3rd release containing
|
||||
the integration of a network subsystem and the uIP TCP/IP, UDP, and
|
||||
ICMP stacks into NuttX (see http://www.sics.se/~adam/uip/index.php/Main_Page).
|
||||
|
||||
Many network-related problems have been fixed and the implementation
|
||||
has matured significantly. However, the level of network reliability
|
||||
is probably still at the pre-alpha or early level. It is sufficiently
|
||||
complete that you may begin to perform some network integration and
|
||||
is exepcted to achieve beta level of reliability over the next few
|
||||
releases.
|
||||
has matured significantly. This release consists of:
|
||||
|
||||
The baseline functionality of NuttX continues to mature and remains at
|
||||
post-beta (as long as the network is not used).
|
||||
o TCP-related bug-fixes
|
||||
o TCP performance improvements
|
||||
o Initial UDP integration
|
||||
o Initial uIP micro webserver integration
|
||||
|
||||
See the ChangeLog for a complete list of changes.
|
||||
|
||||
The level of network reliability is at alpha level is expected to
|
||||
achieve beta level of reliability over the next few releases.
|
||||
|
||||
The baseline functionality of NuttX continues to mature and remains at
|
||||
post-beta.
|
||||
|
||||
This release has been verified only on the Neuros OSD (DM320 ARM9)
|
||||
platform using the DM90x0 driver.
|
||||
|
||||
This tarball contains a complete CVS snapshot from November 19, 2007.
|
||||
This tarball contains a complete CVS snapshot from November 23, 2007.
|
||||
|
2
TODO
2
TODO
@ -29,7 +29,6 @@ o C++ Support
|
||||
- Need to call static constructors
|
||||
|
||||
o Network
|
||||
- UDP is untested.
|
||||
- Did not implement send() and sendto() timeouts. Option is setable via setsockopt,
|
||||
but is not implemented.
|
||||
- uIP's netutils/telnetd (and maybe others) are seriously broken.
|
||||
@ -37,7 +36,6 @@ o Network
|
||||
- uIP's netutils/webserver hangs
|
||||
- uIP's netutils/smtp, dpcpc, resolv, webclient -- untested
|
||||
- Should implement SOCK_RAW
|
||||
- accept() and recvfrom() need to return connection address
|
||||
- Performance Improvements (uIP is not very fast):
|
||||
Need to extend logic so that uIP can have more than on packet in flight and to
|
||||
handle deferred acknowledgements.
|
||||
|
@ -83,6 +83,7 @@ void recv_server(void)
|
||||
{
|
||||
struct sockaddr_in server;
|
||||
struct sockaddr_in client;
|
||||
uint32 tmpaddr;
|
||||
unsigned char inbuf[1024];
|
||||
int sockfd;
|
||||
int nbytes;
|
||||
@ -128,7 +129,13 @@ void recv_server(void)
|
||||
addrlen = sizeof(struct sockaddr_in);
|
||||
nbytes = recvfrom(sockfd, inbuf, 1024, 0,
|
||||
(struct sockaddr*)&client, &addrlen);
|
||||
message("server: %d. Recieved %d bytes\n", offset, nbytes);
|
||||
|
||||
tmpaddr = ntohl(client.sin_addr.s_addr);
|
||||
message("server: %d. Received %d bytes from %d.%d.%d.%d:%d\n",
|
||||
offset, nbytes,
|
||||
tmpaddr >> 24, (tmpaddr >> 16) & 0xff,
|
||||
(tmpaddr >> 8) & 0xff, tmpaddr & 0xff,
|
||||
ntohs(client.sin_port));
|
||||
|
||||
if (nbytes < 0)
|
||||
{
|
||||
|
@ -74,7 +74,7 @@ int open(const char *path, int oflags, ...)
|
||||
struct filelist *list;
|
||||
FAR struct inode *inode;
|
||||
const char *relpath = NULL;
|
||||
#ifdef CONFIG_FILE_MODE
|
||||
#if defined(CONFIG_FILE_MODE) || !defined(CONFIG_DISABLE_MOUNTPOINT)
|
||||
mode_t mode = 0666;
|
||||
#endif
|
||||
int ret;
|
||||
|
@ -53,7 +53,10 @@ uint32 htonl(uint32 hl)
|
||||
#ifdef CONFIG_ENDIAN_BIG
|
||||
return hl;
|
||||
#else
|
||||
return (uint32)htons((uint16)((hl) << 16)) | (uint32)htons((uint16)((hl) & 0xffff));
|
||||
return (( (hl) >> 24) |
|
||||
(((hl) >> 8) & 0x0000ff00) |
|
||||
(((hl) << 8) & 0x00ff0000) |
|
||||
( (hl) << 24));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
48
net/accept.c
48
net/accept.c
@ -52,6 +52,10 @@
|
||||
|
||||
#include "net-internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
@ -76,6 +80,47 @@ struct accept_s
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: accept_tcpsender
|
||||
*
|
||||
* Description:
|
||||
* Getting the sender's address from the UDP packet
|
||||
*
|
||||
* Parameters:
|
||||
* conn - The newly accepted TCP connection
|
||||
* pstate - the recvfrom state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Running at the interrupt level
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_TCP
|
||||
static inline void accept_tcpsender(struct uip_conn *conn, struct accept_s *pstate)
|
||||
{
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
FAR struct sockaddr_in6 *addr = pstate->acpt_addr;
|
||||
#else
|
||||
FAR struct sockaddr_in *addr = pstate->acpt_addr;
|
||||
#endif
|
||||
|
||||
if (addr)
|
||||
{
|
||||
addr->sin_family = AF_INET;
|
||||
addr->sin_port = conn->rport;
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
uip_ipaddr_copy(addr->sin_addr.s_addr, conn->ripaddr);
|
||||
#else
|
||||
uip_ipaddr_copy(addr->sin_addr.s_addr, conn->ripaddr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: accept_interrupt
|
||||
*
|
||||
@ -102,7 +147,8 @@ static int accept_interrupt(struct uip_conn *listener, struct uip_conn *conn)
|
||||
if (pstate)
|
||||
{
|
||||
/* Get the connection address */
|
||||
#warning "need to return the address of the connection"
|
||||
|
||||
accept_tcpsender(conn, pstate);
|
||||
|
||||
/* Save the connection structure */
|
||||
|
||||
|
163
net/recvfrom.c
163
net/recvfrom.c
@ -59,6 +59,9 @@
|
||||
|
||||
#define TCP_TIMEO 10 /* Deciseconds after data received before recv() returns */
|
||||
|
||||
#define UDPBUF ((struct uip_udpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
|
||||
#define TCPBUF ((struct uip_tcpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
@ -67,14 +70,19 @@
|
||||
struct recvfrom_s
|
||||
{
|
||||
#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
|
||||
FAR struct socket *rf_sock; /* The parent socket structure */
|
||||
uint32 rf_starttime; /* rcv start time for determining timeout */
|
||||
FAR struct socket *rf_sock; /* The parent socket structure */
|
||||
uint32 rf_starttime; /* rcv start time for determining timeout */
|
||||
#endif
|
||||
sem_t rf_sem; /* Semaphore signals recv completion */
|
||||
size_t rf_buflen; /* Length of receive buffer */
|
||||
char *rf_buffer; /* Pointer to receive buffer */
|
||||
size_t rf_recvlen; /* The received length */
|
||||
int rf_result; /* OK on success, otherwise a negated errno. */
|
||||
sem_t rf_sem; /* Semaphore signals recv completion */
|
||||
size_t rf_buflen; /* Length of receive buffer */
|
||||
char *rf_buffer; /* Pointer to receive buffer */
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
FAR struct sockaddr_in6 *rf_from; /* Address of sender */
|
||||
#else
|
||||
FAR struct sockaddr_in *rf_from; /* Address of sender */
|
||||
#endif
|
||||
size_t rf_recvlen; /* The received length */
|
||||
int rf_result; /* OK:success, failure:negated errno */
|
||||
};
|
||||
#endif /* CONFIG_NET_UDP || CONFIG_NET_TCP */
|
||||
|
||||
@ -286,6 +294,47 @@ static int recvfrom_timeout(struct recvfrom_s *pstate)
|
||||
#endif /* CONFIG_NET_SOCKOPTS && !CONFIG_DISABLE_CLOCK */
|
||||
#endif /* CONFIG_NET_UDP || CONFIG_NET_TCP */
|
||||
|
||||
/****************************************************************************
|
||||
* Function: recvfrom_tcpsender
|
||||
*
|
||||
* Description:
|
||||
* Getting the sender's address from the UDP packet
|
||||
*
|
||||
* Parameters:
|
||||
* dev - The device driver data structure
|
||||
* pstate - the recvfrom state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Running at the interrupt level
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_TCP
|
||||
static inline void recvfrom_tcpsender(struct uip_driver_s *dev, struct recvfrom_s *pstate)
|
||||
{
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
FAR struct sockaddr_in6 *infrom = pstate->rf_from;
|
||||
#else
|
||||
FAR struct sockaddr_in *infrom = pstate->rf_from;
|
||||
#endif
|
||||
|
||||
if (infrom)
|
||||
{
|
||||
infrom->sin_family = AF_INET;
|
||||
infrom->sin_port = TCPBUF->srcport;
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
uip_ipaddr_copy(infrom->sin_addr.s_addr, TCPBUF->srcipaddr);
|
||||
#else
|
||||
uip_ipaddr_copy(infrom->sin_addr.s_addr, uip_ip4addr_conv(TCPBUF->srcipaddr));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: recvfrom_tcpinterrupt
|
||||
*
|
||||
@ -326,6 +375,10 @@ static uint8 recvfrom_tcpinterrupt(struct uip_driver_s *dev,
|
||||
|
||||
recvfrom_newdata(dev, pstate);
|
||||
|
||||
/* Save the sender's address in the caller's 'from' location */
|
||||
|
||||
recvfrom_tcpsender(dev, pstate);
|
||||
|
||||
/* If the user buffer has been filled, then we are finished. */
|
||||
|
||||
if (pstate->rf_buflen == 0)
|
||||
@ -415,6 +468,47 @@ static uint8 recvfrom_tcpinterrupt(struct uip_driver_s *dev,
|
||||
}
|
||||
#endif /* CONFIG_NET_TCP */
|
||||
|
||||
/****************************************************************************
|
||||
* Function: recvfrom_udpsender
|
||||
*
|
||||
* Description:
|
||||
* Getting the sender's address from the UDP packet
|
||||
*
|
||||
* Parameters:
|
||||
* dev - The device driver data structure
|
||||
* pstate - the recvfrom state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Running at the interrupt level
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
static inline void recvfrom_udpsender(struct uip_driver_s *dev, struct recvfrom_s *pstate)
|
||||
{
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
FAR struct sockaddr_in6 *infrom = pstate->rf_from;
|
||||
#else
|
||||
FAR struct sockaddr_in *infrom = pstate->rf_from;
|
||||
#endif
|
||||
|
||||
if (infrom)
|
||||
{
|
||||
infrom->sin_family = AF_INET;
|
||||
infrom->sin_port = UDPBUF->srcport;
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
uip_ipaddr_copy(infrom->sin_addr.s_addr, UDPBUF->srcipaddr);
|
||||
#else
|
||||
uip_ipaddr_copy(infrom->sin_addr.s_addr, uip_ip4addr_conv(UDPBUF->srcipaddr));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: recvfrom_udpinterrupt
|
||||
*
|
||||
@ -457,13 +551,17 @@ static void recvfrom_udpinterrupt(struct uip_driver_s *dev,
|
||||
|
||||
/* We are finished. */
|
||||
|
||||
vdbg("UDP resume\n");
|
||||
vdbg("UDP done\n");
|
||||
|
||||
/* Don't allow any further UDP call backs. */
|
||||
|
||||
conn->private = NULL;
|
||||
conn->event = NULL;
|
||||
|
||||
/* Save the sender's address in the caller's 'from' location */
|
||||
|
||||
recvfrom_udpsender(dev, pstate);
|
||||
|
||||
/* Wake up the waiting thread, returning the number of bytes
|
||||
* actually read.
|
||||
*/
|
||||
@ -539,6 +637,11 @@ static void recvfrom_udpinterrupt(struct uip_driver_s *dev,
|
||||
|
||||
#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP)
|
||||
static void recvfrom_init(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
FAR struct sockaddr_in6 *infrom,
|
||||
#else
|
||||
FAR struct sockaddr_in *infrom,
|
||||
#endif
|
||||
struct recvfrom_s *pstate)
|
||||
{
|
||||
/* Initialize the state structure. */
|
||||
@ -547,6 +650,7 @@ static void recvfrom_init(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
(void)sem_init(&pstate->rf_sem, 0, 0); /* Doesn't really fail */
|
||||
pstate->rf_buflen = len;
|
||||
pstate->rf_buffer = buf;
|
||||
pstate->rf_from = infrom;
|
||||
|
||||
#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
|
||||
/* Set up the start time for the timeout */
|
||||
@ -630,13 +734,13 @@ static ssize_t recvfrom_result(int result, struct recvfrom_s *pstate)
|
||||
#ifdef CONFIG_NET_UDP
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
FAR const struct sockaddr_in6 *infrom )
|
||||
FAR struct sockaddr_in6 *infrom )
|
||||
#else
|
||||
static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
FAR const struct sockaddr_in *infrom )
|
||||
FAR struct sockaddr_in *infrom )
|
||||
#endif
|
||||
{
|
||||
struct uip_udp_conn *udp_conn;
|
||||
struct uip_udp_conn *udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
struct recvfrom_s state;
|
||||
irqstate_t save;
|
||||
int ret;
|
||||
@ -649,11 +753,11 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
*/
|
||||
|
||||
save = irqsave();
|
||||
recvfrom_init(psock, buf, len, &state);
|
||||
recvfrom_init(psock, buf, len, infrom, &state);
|
||||
|
||||
/* Setup the UDP socket */
|
||||
/* Setup the UDP remote connection */
|
||||
|
||||
ret = uip_udpconnect(psock->s_conn, NULL);
|
||||
ret = uip_udpconnect(udp_conn, infrom);
|
||||
if (ret < 0)
|
||||
{
|
||||
irqrestore(save);
|
||||
@ -662,13 +766,12 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
|
||||
/* Set up the callback in the connection */
|
||||
|
||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
udp_conn->private = (void*)&state;
|
||||
udp_conn->event = recvfrom_udpinterrupt;
|
||||
|
||||
/* Enable the UDP socket */
|
||||
|
||||
uip_udpenable(psock->s_conn);
|
||||
uip_udpenable(udp_conn);
|
||||
|
||||
/* Wait for either the receive to complete or for an error/timeout to occur.
|
||||
* NOTES: (1) sem_wait will also terminate if a signal is received, (2)
|
||||
@ -680,12 +783,11 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
|
||||
/* Make sure that no further interrupts are processed */
|
||||
|
||||
uip_udpdisable(psock->s_conn);
|
||||
uip_udpdisable(udp_conn);
|
||||
udp_conn->private = NULL;
|
||||
udp_conn->event = NULL;
|
||||
irqrestore(save);
|
||||
|
||||
#warning "Needs to return server address"
|
||||
return recvfrom_result(ret, &state);
|
||||
}
|
||||
#endif /* CONFIG_NET_UDP */
|
||||
@ -713,10 +815,10 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
#ifdef CONFIG_NET_TCP
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
FAR const struct sockaddr_in6 *infrom )
|
||||
FAR struct sockaddr_in6 *infrom )
|
||||
#else
|
||||
static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
FAR const struct sockaddr_in *infrom )
|
||||
FAR struct sockaddr_in *infrom )
|
||||
#endif
|
||||
{
|
||||
struct uip_conn *conn;
|
||||
@ -740,7 +842,7 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
*/
|
||||
|
||||
save = irqsave();
|
||||
recvfrom_init(psock, buf, len, &state);
|
||||
recvfrom_init(psock, buf, len, infrom, &state);
|
||||
|
||||
#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
|
||||
|
||||
@ -776,7 +878,6 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
}
|
||||
irqrestore(save);
|
||||
|
||||
#warning "Needs to return server address"
|
||||
return recvfrom_result(ret, &state);
|
||||
}
|
||||
#endif /* CONFIG_NET_TCP */
|
||||
@ -837,16 +938,16 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags, FAR struct sockaddr *from,
|
||||
FAR socklen_t *fromlen)
|
||||
ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags,
|
||||
FAR struct sockaddr *from, FAR socklen_t *fromlen)
|
||||
{
|
||||
FAR struct socket *psock;
|
||||
|
||||
#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP)
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
FAR const struct sockaddr_in6 *infrom = (const struct sockaddr_in6 *)from;
|
||||
FAR struct sockaddr_in6 *infrom = (struct sockaddr_in6 *)from;
|
||||
#else
|
||||
FAR const struct sockaddr_in *infrom = (const struct sockaddr_in *)from;
|
||||
FAR struct sockaddr_in *infrom = (struct sockaddr_in *)from;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -871,17 +972,19 @@ ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags, FAR struct so
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* If a 'from' address has been provided, verify that it is valid */
|
||||
/* If a 'from' address has been provided, verify that it is large
|
||||
* enough to hold this address family.
|
||||
*/
|
||||
|
||||
if (from)
|
||||
{
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
if (from->sa_family != AF_INET6 || *fromlen < sizeof(struct sockaddr_in6))
|
||||
if (*fromlen < sizeof(struct sockaddr_in6))
|
||||
#else
|
||||
if (from->sa_family != AF_INET || *fromlen < sizeof(struct sockaddr_in))
|
||||
if (*fromlen < sizeof(struct sockaddr_in))
|
||||
#endif
|
||||
{
|
||||
err = EBADF;
|
||||
err = EINVAL;
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* uip-udpconn.c
|
||||
* net/uip/uip-udpconn.c
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
@ -52,6 +52,8 @@
|
||||
#include <semaphore.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include <net/uip/uipopt.h>
|
||||
@ -118,7 +120,7 @@ static inline void _uip_semtake(sem_t *sem)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static struct uip_udp_conn *uip_find_conn( uint16 portno )
|
||||
static struct uip_udp_conn *uip_find_conn(uint16 portno)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -234,6 +236,7 @@ void uip_udpfree(struct uip_udp_conn *conn)
|
||||
struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf)
|
||||
{
|
||||
struct uip_udp_conn *conn = (struct uip_udp_conn *)g_active_udp_connections.head;
|
||||
|
||||
while (conn)
|
||||
{
|
||||
/* If the local UDP port is non-zero, the connection is considered
|
||||
@ -252,7 +255,6 @@ struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf)
|
||||
uiphdr_ipaddr_cmp(buf->srcipaddr, &conn->ripaddr)))
|
||||
{
|
||||
/* Matching connection found.. return a reference to it */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -261,7 +263,7 @@ struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf)
|
||||
conn = (struct uip_udp_conn *)conn->node.flink;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return conn;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -307,13 +309,29 @@ int uip_udpbind(struct uip_udp_conn *conn, const struct sockaddr_in *addr)
|
||||
#endif
|
||||
{
|
||||
int ret = -EADDRINUSE;
|
||||
irqstate_t flags = irqsave();
|
||||
if (!uip_find_conn(g_last_udp_port))
|
||||
irqstate_t flags;
|
||||
|
||||
/* Never set lport to zero! */
|
||||
|
||||
if (addr->sin_port)
|
||||
{
|
||||
conn->lport = HTONS(g_last_udp_port);
|
||||
ret = OK;
|
||||
/* Interrupts must be disabled while access the UDP connection list */
|
||||
|
||||
flags = irqsave();
|
||||
|
||||
/* Is any other UDP connection bound to this port? */
|
||||
|
||||
if (!uip_find_conn(addr->sin_port))
|
||||
{
|
||||
/* No.. then bind the socket to the port */
|
||||
|
||||
conn->lport = addr->sin_port;
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
}
|
||||
irqrestore(flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -367,7 +385,7 @@ int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *addr)
|
||||
g_last_udp_port = 4096;
|
||||
}
|
||||
}
|
||||
while (uip_find_conn(g_last_udp_port));
|
||||
while (uip_find_conn(htons(g_last_udp_port)));
|
||||
|
||||
/* Initialize and return the connection structure, bind it to the
|
||||
* port number
|
||||
@ -406,7 +424,7 @@ int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *addr)
|
||||
void uip_udpenable(struct uip_udp_conn *conn)
|
||||
{
|
||||
/* Add the connection structure to the active connectionlist. This list
|
||||
* is modifiable from interrupt level, we we must diable interrupts to
|
||||
* is modifiable from interrupt level, we we must disable interrupts to
|
||||
* access it safely.
|
||||
*/
|
||||
|
||||
@ -417,8 +435,8 @@ void uip_udpenable(struct uip_udp_conn *conn)
|
||||
|
||||
void uip_udpdisable(struct uip_udp_conn *conn)
|
||||
{
|
||||
/* Remove the connection structure to the active connectionlist. This list
|
||||
* is modifiable from interrupt level, we we must diable interrupts to
|
||||
/* Remove the connection structure from the active connectionlist. This list
|
||||
* is modifiable from interrupt level, we we must disable interrupts to
|
||||
* access it safely.
|
||||
*/
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user