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 listen() and accept()
|
||||||
* Added DM90x0 ethernet driver
|
* Added DM90x0 ethernet driver
|
||||||
* ARP timer is now built into the network layer
|
* 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>
|
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
|
* 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() in place but the packet was being ACKed. There are still TCP
|
||||||
recv buffering issues, but this is part of a larger buffering issue.
|
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
|
* Fix DM90x0 driver problem that caused TX overruns
|
||||||
* Add strncmp()
|
* Add strncmp()
|
||||||
* Added TCP/IP read-ahead buffer to minimize failed ACKs and packet loss.
|
* 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()
|
* Add strcat() and strncat()
|
||||||
* Integrated uIP micro webserver
|
* Integrated uIP micro webserver
|
||||||
@ -239,4 +239,10 @@
|
|||||||
* Moved urgent data info into device structure.
|
* Moved urgent data info into device structure.
|
||||||
* TCP and ICMP protocols can now be disabled.
|
* TCP and ICMP protocols can now be disabled.
|
||||||
* Added UDP test in examples/udp
|
* 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">
|
<tr align="center" bgcolor="#e4e4e4">
|
||||||
<td>
|
<td>
|
||||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -183,27 +183,36 @@
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The 13th release of NuttX (nuttx-0.3.0) is available for download
|
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>
|
from the <a href="http://sourceforge.net/project/showfiles.php?group_id=189573">SourceForge</a>
|
||||||
website.
|
website.
|
||||||
The change log associated with the release is available <a href="#currentrelease">here</a>.
|
The change log associated with the release is available <a href="#currentrelease">here</a>.
|
||||||
Unreleased changes after this release are avalable in CVS.
|
Unreleased changes after this release are avalable in CVS.
|
||||||
These unreleased changes are listed <a href="#pendingchanges">here</a>.
|
These unreleased changes are listed <a href="#pendingchanges">here</a>.
|
||||||
</p>
|
</p>
|
||||||
<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
|
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>
|
<a href="http://www.sics.se/~adam/uip/index.php/Main_Page">uIP</a>
|
||||||
into NuttX.
|
into NuttX.
|
||||||
</p>
|
</p>
|
||||||
<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.
|
and the implementation has matured significantly.
|
||||||
However, the level of network reliability is probably still at the
|
Changes in this release include:
|
||||||
pre-alpha or early level.
|
</p>
|
||||||
It is sufficiently complete that you may begin to perform some network
|
<ul>
|
||||||
integration and is exepcted to achieve beta level of reliability over
|
<li>TCP-related bug-fixes,</li>
|
||||||
the next few releases.
|
<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>
|
||||||
<p>
|
<p>
|
||||||
The baseline functionality of NuttX continues to mature and remains at
|
The baseline functionality of NuttX continues to mature and remains at
|
||||||
@ -667,17 +676,7 @@ Other memory:
|
|||||||
* Added DM90x0 ethernet driver
|
* Added DM90x0 ethernet driver
|
||||||
* ARP timer is now built into the network layer
|
* ARP timer is now built into the network layer
|
||||||
* Basic client functionality verified: socket(), bind(), connect(), recv(), send().
|
* 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>
|
0.3.1 2007-11-19 Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
|
||||||
* Separated net/uip/uip.c into several functions in several files.
|
* Separated net/uip/uip.c into several functions in several files.
|
||||||
@ -693,7 +692,7 @@ Other memory:
|
|||||||
<table width ="100%">
|
<table width ="100%">
|
||||||
<tr bgcolor="#e4e4e4">
|
<tr bgcolor="#e4e4e4">
|
||||||
<td>
|
<td>
|
||||||
<a name="pendingchanges">Unreleased Changes</a>
|
<a name="currentrelease">ChangeLog for Current Release</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -710,7 +709,22 @@ Other memory:
|
|||||||
* Moved urgent data info into device structure.
|
* Moved urgent data info into device structure.
|
||||||
* TCP and ICMP protocols can now be disabled.
|
* TCP and ICMP protocols can now be disabled.
|
||||||
* Added UDP test in examples/udp
|
* 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>
|
</pre></ul>
|
||||||
|
|
||||||
<table width ="100%">
|
<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
|
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).
|
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
|
Many network-related problems have been fixed and the implementation
|
||||||
has matured significantly. However, the level of network reliability
|
has matured significantly. This release consists of:
|
||||||
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.
|
|
||||||
|
|
||||||
The baseline functionality of NuttX continues to mature and remains at
|
o TCP-related bug-fixes
|
||||||
post-beta (as long as the network is not used).
|
o TCP performance improvements
|
||||||
|
o Initial UDP integration
|
||||||
|
o Initial uIP micro webserver integration
|
||||||
|
|
||||||
See the ChangeLog for a complete list of changes.
|
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)
|
This release has been verified only on the Neuros OSD (DM320 ARM9)
|
||||||
platform using the DM90x0 driver.
|
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
|
- Need to call static constructors
|
||||||
|
|
||||||
o Network
|
o Network
|
||||||
- UDP is untested.
|
|
||||||
- Did not implement send() and sendto() timeouts. Option is setable via setsockopt,
|
- Did not implement send() and sendto() timeouts. Option is setable via setsockopt,
|
||||||
but is not implemented.
|
but is not implemented.
|
||||||
- uIP's netutils/telnetd (and maybe others) are seriously broken.
|
- uIP's netutils/telnetd (and maybe others) are seriously broken.
|
||||||
@ -37,7 +36,6 @@ o Network
|
|||||||
- uIP's netutils/webserver hangs
|
- uIP's netutils/webserver hangs
|
||||||
- uIP's netutils/smtp, dpcpc, resolv, webclient -- untested
|
- uIP's netutils/smtp, dpcpc, resolv, webclient -- untested
|
||||||
- Should implement SOCK_RAW
|
- Should implement SOCK_RAW
|
||||||
- accept() and recvfrom() need to return connection address
|
|
||||||
- Performance Improvements (uIP is not very fast):
|
- Performance Improvements (uIP is not very fast):
|
||||||
Need to extend logic so that uIP can have more than on packet in flight and to
|
Need to extend logic so that uIP can have more than on packet in flight and to
|
||||||
handle deferred acknowledgements.
|
handle deferred acknowledgements.
|
||||||
|
@ -83,6 +83,7 @@ void recv_server(void)
|
|||||||
{
|
{
|
||||||
struct sockaddr_in server;
|
struct sockaddr_in server;
|
||||||
struct sockaddr_in client;
|
struct sockaddr_in client;
|
||||||
|
uint32 tmpaddr;
|
||||||
unsigned char inbuf[1024];
|
unsigned char inbuf[1024];
|
||||||
int sockfd;
|
int sockfd;
|
||||||
int nbytes;
|
int nbytes;
|
||||||
@ -128,7 +129,13 @@ void recv_server(void)
|
|||||||
addrlen = sizeof(struct sockaddr_in);
|
addrlen = sizeof(struct sockaddr_in);
|
||||||
nbytes = recvfrom(sockfd, inbuf, 1024, 0,
|
nbytes = recvfrom(sockfd, inbuf, 1024, 0,
|
||||||
(struct sockaddr*)&client, &addrlen);
|
(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)
|
if (nbytes < 0)
|
||||||
{
|
{
|
||||||
|
@ -74,7 +74,7 @@ int open(const char *path, int oflags, ...)
|
|||||||
struct filelist *list;
|
struct filelist *list;
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
const char *relpath = NULL;
|
const char *relpath = NULL;
|
||||||
#ifdef CONFIG_FILE_MODE
|
#if defined(CONFIG_FILE_MODE) || !defined(CONFIG_DISABLE_MOUNTPOINT)
|
||||||
mode_t mode = 0666;
|
mode_t mode = 0666;
|
||||||
#endif
|
#endif
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -53,7 +53,10 @@ uint32 htonl(uint32 hl)
|
|||||||
#ifdef CONFIG_ENDIAN_BIG
|
#ifdef CONFIG_ENDIAN_BIG
|
||||||
return hl;
|
return hl;
|
||||||
#else
|
#else
|
||||||
return (uint32)htons((uint16)((hl) << 16)) | (uint32)htons((uint16)((hl) & 0xffff));
|
return (( (hl) >> 24) |
|
||||||
|
(((hl) >> 8) & 0x0000ff00) |
|
||||||
|
(((hl) << 8) & 0x00ff0000) |
|
||||||
|
( (hl) << 24));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
48
net/accept.c
48
net/accept.c
@ -52,6 +52,10 @@
|
|||||||
|
|
||||||
#include "net-internal.h"
|
#include "net-internal.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -76,6 +80,47 @@ struct accept_s
|
|||||||
* Private Functions
|
* 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
|
* Function: accept_interrupt
|
||||||
*
|
*
|
||||||
@ -102,7 +147,8 @@ static int accept_interrupt(struct uip_conn *listener, struct uip_conn *conn)
|
|||||||
if (pstate)
|
if (pstate)
|
||||||
{
|
{
|
||||||
/* Get the connection address */
|
/* Get the connection address */
|
||||||
#warning "need to return the address of the connection"
|
|
||||||
|
accept_tcpsender(conn, pstate);
|
||||||
|
|
||||||
/* Save the connection structure */
|
/* 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 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
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -67,14 +70,19 @@
|
|||||||
struct recvfrom_s
|
struct recvfrom_s
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
|
#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
|
||||||
FAR struct socket *rf_sock; /* The parent socket structure */
|
FAR struct socket *rf_sock; /* The parent socket structure */
|
||||||
uint32 rf_starttime; /* rcv start time for determining timeout */
|
uint32 rf_starttime; /* rcv start time for determining timeout */
|
||||||
#endif
|
#endif
|
||||||
sem_t rf_sem; /* Semaphore signals recv completion */
|
sem_t rf_sem; /* Semaphore signals recv completion */
|
||||||
size_t rf_buflen; /* Length of receive buffer */
|
size_t rf_buflen; /* Length of receive buffer */
|
||||||
char *rf_buffer; /* Pointer to receive buffer */
|
char *rf_buffer; /* Pointer to receive buffer */
|
||||||
size_t rf_recvlen; /* The received length */
|
#ifdef CONFIG_NET_IPv6
|
||||||
int rf_result; /* OK on success, otherwise a negated errno. */
|
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 */
|
#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_SOCKOPTS && !CONFIG_DISABLE_CLOCK */
|
||||||
#endif /* CONFIG_NET_UDP || CONFIG_NET_TCP */
|
#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
|
* Function: recvfrom_tcpinterrupt
|
||||||
*
|
*
|
||||||
@ -326,6 +375,10 @@ static uint8 recvfrom_tcpinterrupt(struct uip_driver_s *dev,
|
|||||||
|
|
||||||
recvfrom_newdata(dev, pstate);
|
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 the user buffer has been filled, then we are finished. */
|
||||||
|
|
||||||
if (pstate->rf_buflen == 0)
|
if (pstate->rf_buflen == 0)
|
||||||
@ -415,6 +468,47 @@ static uint8 recvfrom_tcpinterrupt(struct uip_driver_s *dev,
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_TCP */
|
#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
|
* Function: recvfrom_udpinterrupt
|
||||||
*
|
*
|
||||||
@ -457,13 +551,17 @@ static void recvfrom_udpinterrupt(struct uip_driver_s *dev,
|
|||||||
|
|
||||||
/* We are finished. */
|
/* We are finished. */
|
||||||
|
|
||||||
vdbg("UDP resume\n");
|
vdbg("UDP done\n");
|
||||||
|
|
||||||
/* Don't allow any further UDP call backs. */
|
/* Don't allow any further UDP call backs. */
|
||||||
|
|
||||||
conn->private = NULL;
|
conn->private = NULL;
|
||||||
conn->event = 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
|
/* Wake up the waiting thread, returning the number of bytes
|
||||||
* actually read.
|
* actually read.
|
||||||
*/
|
*/
|
||||||
@ -539,6 +637,11 @@ static void recvfrom_udpinterrupt(struct uip_driver_s *dev,
|
|||||||
|
|
||||||
#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP)
|
#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP)
|
||||||
static void recvfrom_init(FAR struct socket *psock, FAR void *buf, size_t len,
|
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)
|
struct recvfrom_s *pstate)
|
||||||
{
|
{
|
||||||
/* Initialize the state structure. */
|
/* 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 */
|
(void)sem_init(&pstate->rf_sem, 0, 0); /* Doesn't really fail */
|
||||||
pstate->rf_buflen = len;
|
pstate->rf_buflen = len;
|
||||||
pstate->rf_buffer = buf;
|
pstate->rf_buffer = buf;
|
||||||
|
pstate->rf_from = infrom;
|
||||||
|
|
||||||
#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
|
#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
|
||||||
/* Set up the start time for the timeout */
|
/* 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_UDP
|
||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
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
|
#else
|
||||||
static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
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
|
#endif
|
||||||
{
|
{
|
||||||
struct uip_udp_conn *udp_conn;
|
struct uip_udp_conn *udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
||||||
struct recvfrom_s state;
|
struct recvfrom_s state;
|
||||||
irqstate_t save;
|
irqstate_t save;
|
||||||
int ret;
|
int ret;
|
||||||
@ -649,11 +753,11 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
save = irqsave();
|
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)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
irqrestore(save);
|
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 */
|
/* Set up the callback in the connection */
|
||||||
|
|
||||||
udp_conn = (struct uip_udp_conn *)psock->s_conn;
|
|
||||||
udp_conn->private = (void*)&state;
|
udp_conn->private = (void*)&state;
|
||||||
udp_conn->event = recvfrom_udpinterrupt;
|
udp_conn->event = recvfrom_udpinterrupt;
|
||||||
|
|
||||||
/* Enable the UDP socket */
|
/* 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.
|
/* 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)
|
* 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 */
|
/* Make sure that no further interrupts are processed */
|
||||||
|
|
||||||
uip_udpdisable(psock->s_conn);
|
uip_udpdisable(udp_conn);
|
||||||
udp_conn->private = NULL;
|
udp_conn->private = NULL;
|
||||||
udp_conn->event = NULL;
|
udp_conn->event = NULL;
|
||||||
irqrestore(save);
|
irqrestore(save);
|
||||||
|
|
||||||
#warning "Needs to return server address"
|
|
||||||
return recvfrom_result(ret, &state);
|
return recvfrom_result(ret, &state);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_UDP */
|
#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_TCP
|
||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
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
|
#else
|
||||||
static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
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
|
#endif
|
||||||
{
|
{
|
||||||
struct uip_conn *conn;
|
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();
|
save = irqsave();
|
||||||
recvfrom_init(psock, buf, len, &state);
|
recvfrom_init(psock, buf, len, infrom, &state);
|
||||||
|
|
||||||
#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
|
#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);
|
irqrestore(save);
|
||||||
|
|
||||||
#warning "Needs to return server address"
|
|
||||||
return recvfrom_result(ret, &state);
|
return recvfrom_result(ret, &state);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_TCP */
|
#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,
|
ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags,
|
||||||
FAR socklen_t *fromlen)
|
FAR struct sockaddr *from, FAR socklen_t *fromlen)
|
||||||
{
|
{
|
||||||
FAR struct socket *psock;
|
FAR struct socket *psock;
|
||||||
|
|
||||||
#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP)
|
#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP)
|
||||||
#ifdef CONFIG_NET_IPv6
|
#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
|
#else
|
||||||
FAR const struct sockaddr_in *infrom = (const struct sockaddr_in *)from;
|
FAR struct sockaddr_in *infrom = (struct sockaddr_in *)from;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -871,17 +972,19 @@ ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags, FAR struct so
|
|||||||
goto errout;
|
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)
|
if (from)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
if (from->sa_family != AF_INET6 || *fromlen < sizeof(struct sockaddr_in6))
|
if (*fromlen < sizeof(struct sockaddr_in6))
|
||||||
#else
|
#else
|
||||||
if (from->sa_family != AF_INET || *fromlen < sizeof(struct sockaddr_in))
|
if (*fromlen < sizeof(struct sockaddr_in))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
err = EBADF;
|
err = EINVAL;
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* uip-udpconn.c
|
* net/uip/uip-udpconn.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
@ -52,6 +52,8 @@
|
|||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
#include <arch/irq.h>
|
#include <arch/irq.h>
|
||||||
|
|
||||||
#include <net/uip/uipopt.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;
|
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 *uip_udpactive(struct uip_udpip_hdr *buf)
|
||||||
{
|
{
|
||||||
struct uip_udp_conn *conn = (struct uip_udp_conn *)g_active_udp_connections.head;
|
struct uip_udp_conn *conn = (struct uip_udp_conn *)g_active_udp_connections.head;
|
||||||
|
|
||||||
while (conn)
|
while (conn)
|
||||||
{
|
{
|
||||||
/* If the local UDP port is non-zero, the connection is considered
|
/* 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)))
|
uiphdr_ipaddr_cmp(buf->srcipaddr, &conn->ripaddr)))
|
||||||
{
|
{
|
||||||
/* Matching connection found.. return a reference to it */
|
/* Matching connection found.. return a reference to it */
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +263,7 @@ struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf)
|
|||||||
conn = (struct uip_udp_conn *)conn->node.flink;
|
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
|
#endif
|
||||||
{
|
{
|
||||||
int ret = -EADDRINUSE;
|
int ret = -EADDRINUSE;
|
||||||
irqstate_t flags = irqsave();
|
irqstate_t flags;
|
||||||
if (!uip_find_conn(g_last_udp_port))
|
|
||||||
|
/* Never set lport to zero! */
|
||||||
|
|
||||||
|
if (addr->sin_port)
|
||||||
{
|
{
|
||||||
conn->lport = HTONS(g_last_udp_port);
|
/* Interrupts must be disabled while access the UDP connection list */
|
||||||
ret = OK;
|
|
||||||
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,7 +385,7 @@ int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *addr)
|
|||||||
g_last_udp_port = 4096;
|
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
|
/* Initialize and return the connection structure, bind it to the
|
||||||
* port number
|
* 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)
|
void uip_udpenable(struct uip_udp_conn *conn)
|
||||||
{
|
{
|
||||||
/* Add the connection structure to the active connectionlist. This list
|
/* 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.
|
* access it safely.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -417,8 +435,8 @@ void uip_udpenable(struct uip_udp_conn *conn)
|
|||||||
|
|
||||||
void uip_udpdisable(struct uip_udp_conn *conn)
|
void uip_udpdisable(struct uip_udp_conn *conn)
|
||||||
{
|
{
|
||||||
/* Remove the connection structure to the active connectionlist. This list
|
/* Remove the connection structure from 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.
|
* access it safely.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user