Basic TCP send functional

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@371 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2007-11-05 23:04:16 +00:00
parent 77119d8359
commit 44778c69bd
19 changed files with 1646 additions and 1273 deletions
+20 -33
View File
@@ -112,6 +112,25 @@ static inline int uip_comparemac(struct uip_eth_addr *paddr1, struct uip_eth_add
}
#endif
static int sim_uiptxpoll(struct uip_driver_s *dev)
{
/* If the polling resulted in data that should be sent out on the network,
* the field d_len is set to a value > 0.
*/
if (g_sim_dev.d_len > 0)
{
uip_arp_out(&g_sim_dev);
tapdev_send(g_sim_dev.d_buf, g_sim_dev.d_len);
}
/* If zero is returned, the polling will continue until all connections have
* been examined.
*/
return 0;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -182,39 +201,7 @@ void uipdriver_loop(void)
else if (timer_expired(&g_periodic_timer))
{
timer_reset(&g_periodic_timer);
for(i = 0; i < UIP_CONNS; i++)
{
uip_tcppoll(&g_sim_dev,i);
/* If the above function invocation resulted in data that
* should be sent out on the network, the global variable
* d_len is set to a value > 0.
*/
if (g_sim_dev.d_len > 0)
{
uip_arp_out(&g_sim_dev);
tapdev_send(g_sim_dev.d_buf, g_sim_dev.d_len);
}
}
#ifdef CONFIG_NET_UDP
for(i = 0; i < UIP_UDP_CONNS; i++)
{
uip_udppoll(&g_sim_dev,i);
/* If the above function invocation resulted in data that
* should be sent out on the network, the global variable
* d_len is set to a value > 0.
*/
if (g_sim_dev.d_len > 0)
{
uip_arp_out(&g_sim_dev);
tapdev_send(g_sim_dev.d_buf, g_sim_dev.d_len);
}
}
#endif /* CONFIG_NET_UDP */
uip_poll(&g_sim_dev, sim_uiptxpoll, UIP_TIMER);
}
sched_unlock();
}
+2 -1
View File
@@ -211,7 +211,8 @@ defconfig -- This is a configuration file similar to the Linux
TCP/IP and UDP support via uIP
CONFIG_NET - Enable or disable all network features
CONFIG_NET_IPv6 - Build in support for IPv6
CONFIG_NSOCKET_DESCRIPTORS - Maximum number of socket descriptors per task/thread.
CONFIG_NSOCKET_DESCRIPTORS - Maximum number of socket descriptors
per task/thread.
CONFIG_NET_MAX_CONNECTIONS - Maximum number of TCP connections (all tasks)
CONFIG_NET_MAX_LISTENPORTS - Maximum number of listening TCP ports (all tasks)
CONFIG_NET_SOCKOPTS - Enable or disable support for socket options
+25 -59
View File
@@ -44,14 +44,7 @@
#include <nuttx/config.h>
#if defined(CONFIG_NET) && defined(CONFIG_NET_DM90x0)
/* Force debug on for this file */
#undef CONFIG_DEBUG
#define CONFIG_DEBUG 1
#undef CONFIG_DEBUG_VERBOSE
#define CONFIG_DEBUG_VERBOSE 1
/* Only one hardware interface supported at present (althought there are
/* Only one hardware interface supported at present (although there are
* hooks throughout the design to that extending the support to multiple
* interfaces should not be that difficult)
*/
@@ -382,7 +375,7 @@ static boolean dm9x_rxchecksumready(uint8);
/* Common TX logic */
static int dm9x_transmit(struct dm9x_driver_s *dm9x);
static int dm9x_uiptxpoll(struct dm9x_driver_s *dm9x);
static int dm9x_uiptxpoll(struct uip_driver_s *dev);
/* Interrupt handling */
@@ -816,7 +809,7 @@ static int dm9x_transmit(struct dm9x_driver_s *dm9x)
*
* Description:
* The transmitter is available, check if uIP has any outgoing packets ready
* to send. This may be called:
* to send. This is a callback from uip_poll(). uip_poll() may be called:
*
* 1. When the preceding TX packet send is complete,
* 2. When the preceding TX packet send timesout and the DM90x0 is reset
@@ -832,67 +825,40 @@ static int dm9x_transmit(struct dm9x_driver_s *dm9x)
*
****************************************************************************/
static int dm9x_uiptxpoll(struct dm9x_driver_s *dm9x)
static int dm9x_uiptxpoll(struct uip_driver_s *dev)
{
int i;
struct dm9x_driver_s *dm9x = (struct dm9x_driver_s *)dev->d_private;
for(i = 0; i < UIP_CONNS; i++)
/* If the polling resulted in data that should be sent out on the network,
* the field d_len is set to a value > 0.
*/
if (dm9x->dev.d_len > 0)
{
uip_tcppoll(&dm9x->dev, i);
uip_arp_out(&dm9x->dev);
dm9x_transmit(dm9x);
/* If the above function invocation resulted in data that
* should be sent out on the network, the global variable
* d_len is set to a value > 0.
/* Check if there is room in the DM90x0 to hold another packet. In 100M mode,
* that can be 2 packets, otherwise it is a single packet.
*/
if (dm9x->dev.d_len > 0)
if (dm9x->ntxpending > 1 || !dm9x->b100M)
{
uip_arp_out(&dm9x->dev);
dm9x_transmit(dm9x);
/* Returning a non-zero value will terminate the poll operation */
/* Check if there is room in the DM90x0 to hold another packet. In 100M mode,
* that can be 2 packets, otherwise it is a single packet.
*/
if (dm9x->ntxpending > 1 || !dm9x->b100M)
{
return OK;
}
return 1;
}
}
#ifdef CONFIG_NET_UDP
for(i = 0; i < UIP_UDP_CONNS; i++)
{
uip_udppoll(&dm9x->dev,i);
/* If zero is returned, the polling will continue until all connections have
* been examined.
*/
/* If the above function invocation resulted in data that
* should be sent out on the network, the global variable
* d_len is set to a value > 0.
*/
if (dm9x->dev.d_len > 0)
{
uip_arp_out(&dm9x->dev);
dm9x_transmit(dm9x);
/* Check if there is room in the DM90x0 to hold another packet. In 100M mode,
* that can be 2 packets, otherwise it is a single packet.
*/
if (dm9x->ntxpending > 1 || !dm9x->b100M)
{
return OK;
}
}
}
#endif /* CONFIG_NET_UDP */
return OK;
return 0;
}
/****************************************************************************
* Function: dm9x_uiptxpoll
* Function: dm9x_receive
*
* Description:
* An interrupt was received indicating the availability of a new RX packet
@@ -1106,7 +1072,7 @@ static void dm9x_txdone(struct dm9x_driver_s *dm9x)
/* Then poll uIP for new XMIT data */
(void)dm9x_uiptxpoll(dm9x);
(void)uip_poll(&dm9x->dev, dm9x_uiptxpoll, UIP_POLL);
}
/****************************************************************************
@@ -1263,7 +1229,7 @@ static void dm9x_txtimeout(int argc, uint32 arg, ...)
/* Then poll uIP for new XMIT data */
(void)dm9x_uiptxpoll(dm9x);
(void)uip_poll(&dm9x->dev, dm9x_uiptxpoll, UIP_POLL);
}
/****************************************************************************
@@ -1307,7 +1273,7 @@ static void dm9x_polltimer(int argc, uint32 arg, ...)
{
/* If so, poll uIP for new XMIT data */
(void)dm9x_uiptxpoll(dm9x);
(void)uip_poll(&dm9x->dev, dm9x_uiptxpoll, UIP_TIMER);
}
/* Setup the watchdog poll timer again */
+1 -1
View File
@@ -93,7 +93,7 @@ void send_client(void)
printf("client: connect failure: %d\n", errno);
exit(1);
}
printf("clilent: Connected\n");
printf("client: Connected\n");
/* Initialize the buffer */
+45 -6
View File
@@ -61,7 +61,10 @@ void recv_server(void)
socklen_t addrlen;
int nbytesread;
#ifndef CONFIG_NETTEST_PERFORMANCE
int totalbytesread;
int nbytessent;
int ch;
int i;
#endif
int optval;
@@ -130,19 +133,55 @@ void recv_server(void)
}
}
#else
/* Receive and echo own message */
/* Receive canned message */
nbytesread = recv(acceptsd, buffer, 1024, 0);
if (nbytesread <= 0)
totalbytesread = 0;
while (totalbytesread < SENDSIZE)
{
printf("server: recv failed: %d\n", errno);
printf("server: Reading...\n");
nbytesread = recv(acceptsd, &buffer[totalbytesread], 1024 - totalbytesread, 0);
if (nbytesread <= 0)
{
printf("server: recv failed: %d\n", errno);
close(listensd);
close(acceptsd);
exit(-1);
}
totalbytesread += nbytesread;
printf("server: Received %d of %d bytes\n", totalbytesread, SENDSIZE);
}
/* Verify the message */
if (totalbytesread != SENDSIZE)
{
printf("server: Received %d / Expected %d bytes\n", totalbytesread, SENDSIZE);
close(listensd);
close(acceptsd);
exit(-1);
}
printf("server: Received %d bytes\n", nbytesread);
nbytessent = send(acceptsd, buffer, nbytesread, 0);
ch = 0x20;
for (i = 0; i < SENDSIZE; i++ )
{
if (buffer[i] != ch)
{
printf("server: Byte %d is %02x / Expected %02x\n", i, buffer[i], ch);
close(listensd);
close(acceptsd);
exit(-1);
}
if (++ch > 0x7e)
{
ch = 0x20;
}
}
/* Then send the same data back to the client */
nbytessent = send(acceptsd, buffer, totalbytesread, 0);
if (nbytessent <= 0)
{
printf("server: send failed: %d\n", errno);
+52 -74
View File
@@ -65,14 +65,12 @@
* the macrose defined in this file.
*/
#define UIP_DATA 1 /* Tells uIP that there is incoming data in the d_buf buffer. The
#define UIP_DATA 1 /* There is incoming data in the d_buf buffer. The
* length of the data is stored in the field d_len. */
#define UIP_TIMER 2 /* Tells uIP that the periodic timer has fired. */
#define UIP_POLL_REQUEST 3 /* Tells uIP that a connection should be polled. */
#define UIP_UDP_SEND_CONN 4 /* Tells uIP that a UDP datagram should be constructed in the
* d_buf buffer. */
#define UIP_TIMER 2 /* TCP periodic timer has fired */
#define UIP_POLL_REQUEST 3 /* Poll TCP connection */
#ifdef CONFIG_NET_UDP
# define UIP_UDP_TIMER 5
# define UIP_UDP_POLL 4 /* Poll UDP connection */
#endif /* CONFIG_NET_UDP */
/****************************************************************************
@@ -228,97 +226,77 @@ struct uip_driver_s
* uip_input();
* if(dev->d_len > 0) {
* uip_arp_out();
* ethernet_devicedriver_send();
* devicedriver_send();
* }
* } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
* uip_arp_arpin();
* if(dev->d_len > 0) {
* ethernet_devicedriver_send();
* devicedriver_send();
* }
* }
*/
#define uip_input(dev) uip_interrupt(dev,UIP_DATA)
/* Periodic processing for a connection identified by its number.
/* Polling of connections.
*
* This function does the necessary periodic processing (timers,
* polling) for a uIP TCP conneciton, and should be called when the
* periodic uIP timer goes off. It should be called for every
* connection, regardless of whether they are open of closed.
* This function will traverse each active uIP connection structure and
* perform uip_interrupt with the specified event. After each polling each
* active uIP connection structure, this function will call the provided
* callback function if the poll resulted in new data to be send. The poll
* will continue until all connections have been polled or until the user-
* suplied function returns a non-zero value (which is would do only if
* it cannot accept further write data).
*
* When the function returns, it may have an outbound packet waiting
* for service in the uIP packet buffer, and if so the d_len field
* is set to a value larger than zero. The device driver
* should be called to send out the packet.
* This function should be called periodically with event == UIP_TIMER for
* periodic processing. This function may also be called with UIP_POLL to
* perform necessary periodic processing of TCP connections.
*
* The ususal way of calling the function is through a for() loop like
* this:
* This function is called from the CAN device driver and may be called from
* the timer interrupt/watchdog handle level.
*
* for(i = 0; i < UIP_CONNS; ++i)
* When the callback function is called, there may be an outbound packet
* waiting for service in the uIP packet buffer, and if so the d_len field
* is set to a value larger than zero. The device driver should be called to
* send out the packet.
*
* Example:
* int driver_callback(struct uip_driver_dev *dev)
* {
* if (dev->d_len > 0)
* {
* uip_tcppoll(dev,i);
* if (dev->d_len > 0)
* {
* devicedriver_send();
* }
* devicedriver_send();
* return 1; <-- Terminates polling if necessary
* }
* return 0;
* }
*
* Note: If you are writing a uIP device driver that needs ARP
* (Address Resolution Protocol), e.g., when running uIP over
* Ethernet, you will need to call the uip_arp_out() function before
* calling the device driver:
* ...
* uip_poll(dev, driver_callback, UIP_TIMER);
*
* for(i = 0; i < UIP_CONNS; ++i)
* Note: If you are writing a uIP device driver that needs ARP (Address
* Resolution Protocol), e.g., when running uIP over Ethernet, you will
* need to call the uip_arp_out() function in the callback function
* before sending the packet:
*
* int driver_callback(struct uip_driver_dev *dev)
* {
* if (dev->d_len > 0)
* {
* uip_tcppoll(dev,i);
* if (dev->d_len > 0)
* {
* uip_arp_out();
* ethernet_devicedriver_send();
* }
* uip_arp_out();
* devicedriver_send();
* return 1; <-- Terminates polling if necessary
* }
*
* conn The number of the connection which is to be periodically polled.
* return 0;
* }
*/
extern void uip_tcppoll(struct uip_driver_s *dev, unsigned int conn);
typedef int (*uip_poll_callback_t)(struct uip_driver_s *dev);
extern int uip_poll(struct uip_driver_s *dev, uip_poll_callback_t callback, int event);
#ifdef CONFIG_NET_UDP
/* Periodic processing for a UDP connection identified by its number.
*
* This function is essentially the same as uip_tcppoll(), but for
* UDP connections. It is called in a similar fashion as the
* uip_tcppoll() function:
*
* for(i = 0; i < UIP_UDP_CONNS; i++)
* {
* uip_udppoll(dev,i);
* if(dev->d_len > 0)
* {
* devicedriver_send();
* }
* }
*
* Note: As for the uip_tcppoll() function, special care has to be
* taken when using uIP together with ARP and Ethernet:
*
* for(i = 0; i < UIP_UDP_CONNS; i++)
* {
* uip_udppoll(dev,i);
* if(dev->d_len > 0)
* {
* uip_arp_out();
* ethernet_devicedriver_send();
* }
* }
*
* conn The number of the UDP connection to be processed.
*/
/* uip_poll helper functions */
extern void uip_udppoll(struct uip_driver_s *dev, unsigned int conn);
#endif /* CONFIG_NET_UDP */
#define uip_periodic(dev,cb) uip_poll(dev,db,UIP_TIMER);
/* Architecure support
*
@@ -326,7 +304,7 @@ extern void uip_udppoll(struct uip_driver_s *dev, unsigned int conn);
* interrupt level by a device driver.
*/
extern void uip_interrupt(struct uip_driver_s *dev, uint8 flag);
extern void uip_interrupt(struct uip_driver_s *dev, uint8 event);
/* By defining UIP_ARCH_CHKSUM, the architecture can replace the following
* functions with hardware assisted solutions.
+12 -12
View File
@@ -448,7 +448,7 @@ extern void *uip_urgdata;
*/
#if UIP_URGDATA > 0
extern uint16 uip_urglen, uip_surglen;
extern uint16 uip_urglen; /* Length of (received) urgent data */
#endif /* UIP_URGDATA > 0 */
/* Pointer to the current TCP connection.
@@ -598,7 +598,7 @@ int uip_unlisten(uint16 port);
*
* Note: This function does not guarantee that the sent data will
* arrive at the destination. If the data is lost in the network, the
* application will be invoked with the uip_rexmit() event being
* application will be invoked with the uip_rexmit_event() event being
* set. The application will then have to resend the data using this
* function.
*
@@ -686,7 +686,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
* avaliable through the d_len element.
*/
#define uip_newdata() (uip_flags & UIP_NEWDATA)
#define uip_newdata_event() (uip_flags & UIP_NEWDATA)
/* Has previously sent data been acknowledged?
*
@@ -695,17 +695,17 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
* can send new data.
*/
#define uip_acked() (uip_flags & UIP_ACKDATA)
#define uip_ack_event() (uip_flags & UIP_ACKDATA)
/* Has the connection just been connected?
*
* Reduces to non-zero if the current connection has been connected to
* Reduces to non-zero if the current connenetutils/telnetd/telnetd.cction has been connected to
* a remote host. This will happen both if the connection has been
* actively opened (with uip_connect()) or passively opened (with
* uip_listen()).
*/
#define uip_connected() (uip_flags & UIP_CONNECTED)
#define uip_connected_event() (uip_flags & UIP_CONNECTED)
/* Has the connection been closed by the other end?
*
@@ -713,7 +713,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
* host. The application may then do the necessary clean-ups.
*/
#define uip_closed() (uip_flags & UIP_CLOSE)
#define uip_close_event() (uip_flags & UIP_CLOSE)
/* Has the connection been aborted by the other end?
*
@@ -721,7 +721,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
* remote host.
*/
#define uip_aborted() (uip_flags & UIP_ABORT)
#define uip_abort_event() (uip_flags & UIP_ABORT)
/* Has the connection timed out?
*
@@ -729,7 +729,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
* retransmissions.
*/
#define uip_timedout() (uip_flags & UIP_TIMEDOUT)
#define uip_timeout_event() (uip_flags & UIP_TIMEDOUT)
/* Do we need to retransmit previously data?
*
@@ -739,7 +739,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
* time, using the uip_send() function.
*/
#define uip_rexmit() (uip_flags & UIP_REXMIT)
#define uip_rexmit_event() (uip_flags & UIP_REXMIT)
/* Is the connection being polled by uIP?
*
@@ -751,7 +751,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
* wait for the remote host to send data.
*/
#define uip_poll() (uip_flags & UIP_POLL)
#define uip_poll_event() (uip_flags & UIP_POLL)
/* Get the initial maxium segment size (MSS) of the current
* connection.
@@ -768,7 +768,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
* uip_initialmss()).
*/
#define uip_mss() (uip_conn->mss)
#define uip_mss() (uip_conn->mss)
/* Bind a UDP connection to a local address */
+13 -1
View File
@@ -42,7 +42,10 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <debug.h>
#include <arch/irq.h>
#include "net-internal.h"
@@ -186,6 +189,8 @@ static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private)
{
struct tcp_connect_s *pstate = (struct tcp_connect_s *)private;
vdbg("Interrupt uip_flags=%02x\n", uip_flags);
/* 'private' might be null in some race conditions (?) */
if (pstate)
@@ -209,6 +214,7 @@ static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private)
{
/* Indicate that remote host refused the connection */
vdbg("ECONNREFUSED\n");
pstate->tc_result = -ECONNREFUSED;
}
@@ -218,7 +224,8 @@ static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private)
{
/* Indicate that the remote host is unreachable (or should this be timedout?) */
pstate->tc_result = -ECONNREFUSED;
vdbg("ETIMEDOUT\n");
pstate->tc_result = -ETIMEDOUT;
}
/* UIP_CONNECTED: The socket is successfully connected */
@@ -227,6 +234,7 @@ static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private)
{
/* Indicate that the socket is no longer connected */
vdbg("Connected\n");
pstate->tc_result = OK;
}
@@ -461,6 +469,8 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
case SOCK_STREAM:
{
dbg("TCP\n");
/* Verify that the socket is not already connected */
if (_SS_ISCONNECTED(psock->s_flags))
@@ -483,6 +493,8 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
#ifdef CONFIG_NET_UDP
case SOCK_DGRAM:
{
dbg("UDP\n");
ret = uip_udpconnect(psock->s_conn, inaddr);
if (ret < 0)
{
+26 -5
View File
@@ -42,8 +42,11 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <arch/irq.h>
#include <nuttx/clock.h>
#include <net/uip/uip-arch.h>
@@ -104,6 +107,8 @@ static void recvfrom_interrupt(struct uip_driver_s *dev, void *private)
#endif
size_t recvlen;
vdbg("Interrupt uip_flags: %02x\n", uip_flags);
/* 'private' might be null in some race conditions (?) */
if (pstate)
@@ -116,9 +121,10 @@ static void recvfrom_interrupt(struct uip_driver_s *dev, void *private)
/* If new data is available, then complete the read action. */
if (uip_newdata())
if (uip_newdata_event())
{
/* Get the length of the data to return */
if (dev->d_len > pstate->rf_buflen)
{
recvlen = pstate->rf_buflen;
@@ -131,6 +137,7 @@ static void recvfrom_interrupt(struct uip_driver_s *dev, void *private)
/* Copy the new appdata into the user buffer */
memcpy(pstate->rf_buffer, dev->d_appdata, recvlen);
vdbg("Received %d bytes (of %d)\n", recvlen, dev->d_len);
/* Update the accumulated size of the data read */
@@ -139,14 +146,16 @@ static void recvfrom_interrupt(struct uip_driver_s *dev, void *private)
pstate->rf_buflen -= recvlen;
/* Are we finished? If this is a UDP socket or if the user
* buffer has been filled, then we are finished.
*/
* buffer has been filled, then we are finished.
*/
#ifdef CONFIG_NET_UDP
if (psock->s_type == SOCK_DGRAM)
{
struct uip_udp_conn *udp_conn;
vdbg("UDP complete\n");
/* Don't allow any further UDP call backs. */
udp_conn = (struct uip_udp_conn *)psock->s_conn;
@@ -165,6 +174,8 @@ static void recvfrom_interrupt(struct uip_driver_s *dev, void *private)
{
struct uip_conn *conn;
vdbg("TCP complete\n");
/* The TCP receive buffer is full. Return now, perhaps truncating
* the received data (need to fix that).
*
@@ -183,8 +194,8 @@ static void recvfrom_interrupt(struct uip_driver_s *dev, void *private)
}
/* Reset the timeout. We will want a short timeout to terminate
* the TCP receive.
*/
* the TCP receive.
*/
#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
pstate->rf_starttime = g_system_timer;
@@ -195,6 +206,8 @@ static void recvfrom_interrupt(struct uip_driver_s *dev, void *private)
else if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
{
vdbg("Receive error\n");
/* Stop further callbacks */
#ifdef CONFIG_NET_UDP
@@ -267,6 +280,8 @@ static void recvfrom_interrupt(struct uip_driver_s *dev, void *private)
{
struct uip_udp_conn *udp_conn;
vdbg("UDP timeout\n");
/* Stop further callbacks */
udp_conn = (struct uip_udp_conn *)psock->s_conn;
@@ -282,6 +297,8 @@ static void recvfrom_interrupt(struct uip_driver_s *dev, void *private)
{
struct uip_conn *conn;
vdbg("TCP timeout\n");
conn = (struct uip_conn *)psock->s_conn;
conn->data_private = NULL;
conn->data_event = NULL;
@@ -463,7 +480,9 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
* and automatically re-enabled when the task restarts.
*/
vdbg("Receiving UDP ...\n");
ret = sem_wait(&state. rf_sem);
vdbg("Received\n");
/* Make sure that no further interrupts are processed */
@@ -540,7 +559,9 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
* and automatically re-enabled when the task restarts.
*/
vdbg("Receiving UDP ...\n");
ret = sem_wait(&state.rf_sem);
vdbg("Received\n");
/* Make sure that no further interrupts are processed */
+15 -2
View File
@@ -42,8 +42,11 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <arch/irq.h>
#include "net-internal.h"
@@ -101,11 +104,13 @@ static void send_interrupt(struct uip_driver_s *dev, void *private)
struct send_s *pstate = (struct send_s *)private;
struct uip_conn *conn;
vdbg("Interrupt uip_flags: %02x state: %d\n", uip_flags, pstate->snd_state);
/* If the data has not been sent OR if it needs to be retransmitted,
* then send it now.
*/
if (pstate->snd_state != STATE_DATA_SENT || uip_rexmit())
if (pstate->snd_state != STATE_DATA_SENT || uip_rexmit_event())
{
if (pstate->snd_buflen > uip_mss())
{
@@ -117,11 +122,12 @@ static void send_interrupt(struct uip_driver_s *dev, void *private)
}
pstate->snd_state = STATE_DATA_SENT;
vdbg("state: STATE_DATA_SENT(%d)\n", STATE_DATA_SENT);
}
/* Check if all data has been sent and acknowledged */
else if (pstate->snd_state == STATE_DATA_SENT && uip_acked())
else if (pstate->snd_state == STATE_DATA_SENT && uip_ack_event())
{
/* Yes.. the data has been sent AND acknowledge */
@@ -136,9 +142,12 @@ static void send_interrupt(struct uip_driver_s *dev, void *private)
/* Send again on the next poll */
pstate->snd_state = STATE_POLLWAIT;
vdbg("state: STATE_POLLWAIT(%d)\n", STATE_POLLWAIT);
}
else
{
vdbg("state: Data sent\n");
/* All data has been sent */
pstate->snd_sent += pstate->snd_buflen;
@@ -163,6 +172,8 @@ static void send_interrupt(struct uip_driver_s *dev, void *private)
else if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
{
vdbg("state: TCP failure\n");
/* Stop further callbacks */
conn = (struct uip_conn *)pstate->snd_sock->s_conn;
@@ -305,12 +316,14 @@ ssize_t send(int sockfd, const void *buf, size_t len, int flags)
* automatically re-enabled when the task restarts.
*/
vdbg("Sending %d bytes...\n", len);
ret = sem_wait(&state. snd_sem);
/* Make sure that no further interrupts are processed */
conn->data_private = NULL;
conn->data_event = NULL;
vdbg("Sent\n");
}
sem_destroy(&state. snd_sem);
+1 -1
View File
@@ -35,5 +35,5 @@
UIP_ASRCS =
UIP_CSRCS = uip-arp.c uip.c uip-send.c uip-fw.c uip-neighbor.c uip-split.c \
uip-tcpconn.c uip-udpconn.c uip-listen.c
uip-tcpconn.c uip-udpconn.c uip-listen.c uip-poll.c
+10 -6
View File
@@ -52,6 +52,9 @@
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifdef CONFIG_NET
#include <sys/types.h>
#include <sys/ioctl.h>
@@ -144,13 +147,13 @@ static void uip_arp_dump(struct arp_hdr *arp)
vdbg(" Sender MAC: %02x:%02x:%02x:%02x:%02x:%02x IP: %d.%d.%d.%d\n",
arp->ah_shwaddr[0], arp->ah_shwaddr[1], arp->ah_shwaddr[2],
arp->ah_shwaddr[3], arp->ah_shwaddr[4], arp->ah_shwaddr[5],
arp->ah_sipaddr[0] >> 8, arp->ah_sipaddr[0] & 0xff,
arp->ah_sipaddr[1] >> 8, arp->ah_sipaddr[1] & 0xff);
arp->ah_sipaddr[0] & 0xff, arp->ah_sipaddr[0] >> 8,
arp->ah_sipaddr[1] & 0xff, arp->ah_sipaddr[1] >> 8);
vdbg(" Dest MAC: %02x:%02x:%02x:%02x:%02x:%02x IP: %d.%d.%d.%d\n",
arp->ah_dhwaddr[0], arp->ah_dhwaddr[1], arp->ah_dhwaddr[2],
arp->ah_dhwaddr[3], arp->ah_dhwaddr[4], arp->ah_dhwaddr[5],
arp->ah_dipaddr[0] >> 8, arp->ah_dipaddr[0] & 0xff,
arp->ah_dipaddr[1] >> 8, arp->ah_dipaddr[1] & 0xff);
arp->ah_dipaddr[0] & 0xff, arp->ah_dipaddr[0] >> 8,
arp->ah_dipaddr[1] & 0xff, arp->ah_dipaddr[1] >> 8);
}
#else
# define uip_arp_dump(arp)
@@ -324,6 +327,7 @@ void uip_arp_ipin(void)
void uip_arp_arpin(struct uip_driver_s *dev)
{
in_addr_t ipaddr;
if (dev->d_len < (sizeof(struct arp_hdr) + UIP_LLH_LEN))
{
dev->d_len = 0;
@@ -357,8 +361,7 @@ void uip_arp_arpin(struct uip_driver_s *dev)
ARPBUF->ah_dipaddr[0] = ARPBUF->ah_sipaddr[0];
ARPBUF->ah_dipaddr[1] = ARPBUF->ah_sipaddr[1];
ARPBUF->ah_sipaddr[0] = dev->d_ipaddr >> 16;
ARPBUF->ah_sipaddr[1] = dev->d_ipaddr & 0xffff;
uiphdr_ipaddr_copy(ARPBUF->ah_sipaddr, &dev->d_ipaddr);
uip_arp_dump(ARPBUF);
ETHBUF->type = HTONS(UIP_ETHTYPE_ARP);
@@ -503,3 +506,4 @@ void uip_arp_out(struct uip_driver_s *dev)
ETHBUF->type = HTONS(UIP_ETHTYPE_IP);
dev->d_len += UIP_LLH_LEN;
}
#endif /* CONFIG_NET */
+2
View File
@@ -78,6 +78,7 @@ extern "C" {
EXTERN void uip_tcpinit(void);
EXTERN struct uip_conn *uip_tcpactive(struct uip_tcpip_hdr *buf);
EXTERN struct uip_conn *uip_nexttcpconn(struct uip_conn *conn);
EXTERN struct uip_conn *uip_tcplistener(uint16 portno);
EXTERN struct uip_conn *uip_tcpaccept(struct uip_tcpip_hdr *buf);
EXTERN void uip_tcpnextsequence(void);
@@ -86,6 +87,7 @@ EXTERN void uip_tcpnextsequence(void);
EXTERN void uip_udpinit(void);
EXTERN struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf);
EXTERN struct uip_udp_conn *uip_nextudpconn(struct uip_udp_conn *conn);
/* Defined in uip_listen.c **************************************************/
+161
View File
@@ -0,0 +1,161 @@
/****************************************************************************
* net/uip/uip-poll.c
*
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifdef CONFIG_NET
#include <sys/types.h>
#include <debug.h>
#include <net/uip/uipopt.h>
#include <net/uip/uip.h>
#include <net/uip/uip-arch.h>
#include "uip-internal.h"
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: uip_udppoll()
*
* Description:
* Periodic processing for a UDP connection identified by its number.
* This function does the necessary periodic processing (timers,
* polling) for a uIP TCP conneciton, and should be called by the UIP
* device driver when the periodic uIP timer goes off. It should be
* called for every connection, regardless of whether they are open of
* closed.
*
* Assumptions:
* This function is called from the CAN device driver may be called from
* the timer interrupt/watchdog handle level.
*
****************************************************************************/
static inline void uip_udppoll(struct uip_driver_s *dev, unsigned int conn)
{
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Function: uip-poll
*
* Description:
* This function will traverse each active uIP connection structure and
* perform uip_interrupt with the specified event. After each polling each
* active uIP connection structure, this function will call the provided
* callback function if the poll resulted in new data to be send. The poll
* will continue until all connections have been polled or until the user-
* suplied function returns a non-zero value (which is would do only if
* it cannot accept further write data).
*
* This function should be called periodically with event == UIP_TIMER for
* periodic processing. This function may also be called with UIP_POLL to
* perform necessary periodic processing of TCP connections.
*
* When the callback function is called, there may be an outbound packet
* waiting for service in the uIP packet buffer, and if so the d_len field
* is set to a value larger than zero. The device driver should be called to
* send out the packet.
*
* Assumptions:
* This function is called from the CAN device driver and may be called from
* the timer interrupt/watchdog handle level.
*
****************************************************************************/
int uip_poll(struct uip_driver_s *dev, uip_poll_callback_t callback, int event)
{
struct uip_conn *conn;
#ifdef CONFIG_NET_UDP
struct uip_udp_conn *udp_conn;
#endif
irqstate_t flags;
/* Interrupts must be disabled while traversing the active connection list */
flags = irqsave();
/* Traverse all of the active TCP connections and perform the poll action */
conn = NULL;
while ((conn = uip_nexttcpconn(uip_conn)))
{
uip_conn = conn;
uip_interrupt(dev, event);
if (callback(dev))
{
irqrestore(flags);
return 1;
}
}
uip_conn = NULL;
#ifdef CONFIG_NET_UDP
/* Traverse all of the allocated UDP connections and perform a poll action */
udp_conn = NULL;
while ((udp_conn = uip_nextudpconn(uip_udp_conn)))
{
uip_udp_conn = udp_conn;
uip_interrupt(dev, UIP_UDP_POLL);
if (callback(dev))
{
irqrestore(flags);
return 1;
}
}
uip_udp_conn = NULL;
#endif /* CONFIG_NET_UDP */
irqrestore(flags);
return 0;
}
#endif /* CONFIG_NET */
+41 -26
View File
@@ -50,6 +50,8 @@
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <arch/irq.h>
#include <net/uip/uipopt.h>
@@ -316,14 +318,26 @@ void uip_tcpfree(struct uip_conn *conn)
struct uip_conn *uip_tcpactive(struct uip_tcpip_hdr *buf)
{
struct uip_conn *conn = (struct uip_conn *)g_active_tcp_connections.head;
struct uip_conn *conn = (struct uip_conn *)g_active_tcp_connections.head;
in_addr_t srcipaddr = uip_ip4addr_conv(buf->srcipaddr);
vdbg("BUF: destport: %04x srcport: %04x IP: %d.%d.%d.%d\n",
buf->destport, buf->srcport,
(srcipaddr >> 24) & 0xff, (srcipaddr >> 16) & 0xff,
(srcipaddr >> 8) & 0xff, srcipaddr & 0xff);
while (conn)
{
/* Find an open connection matching the tcp input */
vdbg("conn: lport: %04x rport: %04x IP: %d.%d.%d.%d\n",
conn->lport, conn->rport,
(conn->ripaddr >> 24) & 0xff, (conn->ripaddr >> 16) & 0xff,
(conn->ripaddr >> 8) & 0xff, conn->ripaddr & 0xff);
if (conn->tcpstateflags != UIP_CLOSED &&
buf->destport == conn->lport && buf->srcport == conn->rport &&
uip_ipaddr_cmp(buf->srcipaddr, conn->ripaddr))
buf->destport == conn->lport && buf->srcport == conn->rport &&
uip_ipaddr_cmp(srcipaddr, conn->ripaddr))
{
/* Matching connection found.. break out of the loop and return a
* reference to it.
@@ -340,6 +354,30 @@ struct uip_conn *uip_tcpactive(struct uip_tcpip_hdr *buf)
return conn;
}
/****************************************************************************
* Name: uip_nexttcpconn()
*
* Description:
* Traverse the list of active TCP connections
*
* Assumptions:
* This function is called from UIP logic at interrupt level (or with
* interrupts disabled).
*
****************************************************************************/
struct uip_conn *uip_nexttcpconn(struct uip_conn *conn)
{
if (!conn)
{
return (struct uip_conn *)g_active_tcp_connections.head;
}
else
{
return (struct uip_conn *)conn->node.flink;
}
}
/****************************************************************************
* Name: uip_tcplistener()
*
@@ -417,29 +455,6 @@ struct uip_conn *uip_tcpaccept(struct uip_tcpip_hdr *buf)
return conn;
}
/****************************************************************************
* Name: uip_tcppoll()
*
* Description:
* Periodic processing for a TCP connection identified by its number.
* This function does the necessary periodic processing (timers,
* polling) for a uIP TCP conneciton, and should be called by the UIP
* device driver when the periodic uIP timer goes off. It should be
* called for every connection, regardless of whether they are open of
* closed.
*
* Assumptions:
* This function is called from the CAN device driver may be called from
* the timer interrupt/watchdog handle level.
*
****************************************************************************/
void uip_tcppoll(struct uip_driver_s *dev, unsigned int conn)
{
uip_conn = &g_tcp_connections[conn];
uip_interrupt(dev, UIP_TIMER);
}
/****************************************************************************
* Name: uip_tcpnextsequence()
*
+19 -18
View File
@@ -249,7 +249,7 @@ struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf)
(conn->rport == 0 || buf->srcport == conn->rport) &&
(uip_ipaddr_cmp(conn->ripaddr, all_zeroes_addr) ||
uip_ipaddr_cmp(conn->ripaddr, all_ones_addr) ||
uip_ipaddr_cmp(buf->srcipaddr, conn->ripaddr)))
uiphdr_ipaddr_cmp(buf->srcipaddr, conn->ripaddr)))
{
/* Matching connection found.. return a reference to it */
@@ -265,26 +265,27 @@ struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf)
}
/****************************************************************************
* Name: uip_udppoll()
* Name: uip_nextudpconn()
*
* Description:
* Periodic processing for a UDP connection identified by its number.
* This function does the necessary periodic processing (timers,
* polling) for a uIP TCP conneciton, and should be called by the UIP
* device driver when the periodic uIP timer goes off. It should be
* called for every connection, regardless of whether they are open of
* closed.
* Traverse the list of allocated UDP connections
*
* Assumptions:
* This function is called from the CAN device driver may be called from
* the timer interrupt/watchdog handle level.
* This function is called from UIP logic at interrupt level (or with
* interrupts disabled).
*
****************************************************************************/
void uip_udppoll(struct uip_driver_s *dev, unsigned int conn)
struct uip_udp_conn *uip_nextudpconn(struct uip_udp_conn *conn)
{
uip_udp_conn = &g_udp_connections[conn];
uip_interrupt(dev, UIP_UDP_TIMER);
if (!conn)
{
return (struct uip_udp_conn *)g_active_udp_connections.head;
}
else
{
return (struct uip_udp_conn *)conn->node.flink;
}
}
/****************************************************************************
@@ -320,11 +321,11 @@ int uip_udpbind(struct uip_udp_conn *conn, const struct sockaddr_in *addr)
* Name: uip_udpconnect()
*
* Description:
* This function sets up a new UDP connection. The function will
* automatically allocate an unused local port for the new
* connection. However, another port can be chosen by using the
* uip_udpbind() call, after the uip_udpconnect() function has been
* called.
* This function sets up a new UDP connection. The function will
* automatically allocate an unused local port for the new
* connection. However, another port can be chosen by using the
* uip_udpbind() call, after the uip_udpconnect() function has been
* called.
*
* uip_udpenable() must be called before the connection is made active (i.e.,
* is eligible for callbacks.
+1187 -1015
View File
File diff suppressed because it is too large Load Diff
+6 -5
View File
@@ -306,7 +306,7 @@ void uip_interrupt_event(struct uip_driver_s *dev, void *private)
{
#warning OBSOLETE -- needs to be redesigned
unsigned int i;
if (uip_connected())
if (uip_connected_event())
{
for (i = 0; i < TELNETD_CONF_NUMLINES; ++i)
{
@@ -325,22 +325,23 @@ void uip_interrupt_event(struct uip_driver_s *dev, void *private)
return;
}
if (uip_closed() || uip_aborted() || uip_timedout())
if (uip_close_event() || uip_abort_event() || uip_timeout_event())
{
closed();
}
if (uip_acked())
if (uip_ack_event())
{
acked();
}
if (uip_newdata())
if (uip_newdata_event())
{
newdata(dev);
}
if (uip_rexmit() || uip_newdata() || uip_acked() || uip_connected() || uip_poll())
if (uip_rexmit_event() || uip_newdata_event() || uip_ack_event() ||
uip_connected_event() || uip_poll_event())
{
senddata(dev);
}
+8 -8
View File
@@ -407,7 +407,7 @@ static void newdata(struct uip_driver_s *dev)
void uip_interrupt_event(struct uip_driver_s *dev)
{
#warning OBSOLETE -- needs to be redesigned
if (uip_connected())
if (uip_connected_event())
{
s.timer = 0;
s.state = WEBCLIENT_STATE_STATUSLINE;
@@ -423,33 +423,33 @@ void uip_interrupt_event(struct uip_driver_s *dev)
return;
}
if (uip_aborted())
if (uip_abort_event())
{
webclient_aborted();
}
if (uip_timedout())
if (uip_timeout_event())
{
webclient_timedout();
}
if (uip_acked())
if (uip_ack_event())
{
s.timer = 0;
acked();
}
if (uip_newdata())
if (uip_newdata_event())
{
s.timer = 0;
newdata(dev);
}
if (uip_rexmit() || uip_newdata() || uip_acked())
if (uip_rexmit_event() || uip_newdata_event() || uip_ack_event())
{
senddata(dev);
}
else if (uip_poll())
else if (uip_poll_event())
{
++s.timer;
if (s.timer == WEBCLIENT_TIMEOUT)
@@ -460,7 +460,7 @@ void uip_interrupt_event(struct uip_driver_s *dev)
}
}
if (uip_closed())
if (uip_close_event())
{
if (s.httpflag != HTTPFLAG_MOVED)
{