mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 08:36:24 +08:00
Implements basic TCP connection logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@326 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
############################################################
|
||||
|
||||
-include $(TOPDIR)/Make.defs
|
||||
CFLAGS += -I./uip
|
||||
|
||||
MKDEP = $(TOPDIR)/tools/mkdeps.sh
|
||||
|
||||
|
||||
+21
-4
@@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* bind.c
|
||||
* net/bind.c
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
@@ -82,9 +82,14 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)
|
||||
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
FAR struct socket *psock = sockfd_socket(sockfd);
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
FAR const struct sockaddr_in6 *inaddr = (const struct sockaddr_in6 *)addr;
|
||||
#else
|
||||
FAR const struct sockaddr_in *inaddr = (const struct sockaddr_in *)addr;
|
||||
#endif
|
||||
int err;
|
||||
|
||||
/* Verify that the sockfd corresponds to valid, allocated socket */
|
||||
@@ -95,16 +100,28 @@ int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Verify that a valid address has been provided */
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
if (addr->sa_family != AF_INET6 || addrlen < sizeof(struct sockaddr_in6))
|
||||
#else
|
||||
if (addr->sa_family != AF_INET || addrlen < sizeof(struct sockaddr_in))
|
||||
#endif
|
||||
{
|
||||
err = EBADF;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Perform the binding depending on the protocol type */
|
||||
switch (psock->s_type)
|
||||
{
|
||||
case SOCK_STREAM:
|
||||
/* Put TCP/IP binding logic here */
|
||||
#warning Put TCP/IP binding logic here
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
case SOCK_DGRAM:
|
||||
/* Put UDP binding logic here */
|
||||
#warning Put UDP binding logic here
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
||||
+71
-3
@@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* connect.c
|
||||
* net/connect.c
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
@@ -44,6 +44,8 @@
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "net_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Global Functions
|
||||
****************************************************************************/
|
||||
@@ -117,9 +119,75 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
|
||||
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
*get_errno_ptr() = ENOSYS;
|
||||
FAR struct socket *psock = sockfd_socket(sockfd);
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
FAR const struct sockaddr_in6 *inaddr = (const struct sockaddr_in6 *)addr;
|
||||
#else
|
||||
FAR const struct sockaddr_in *inaddr = (const struct sockaddr_in *)addr;
|
||||
#endif
|
||||
int err;
|
||||
|
||||
/* Verify that the sockfd corresponds to valid, allocated socket */
|
||||
|
||||
if (!psock || psock->s_crefs <= 0)
|
||||
{
|
||||
err = EBADF;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Verify that a valid address has been provided */
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
if (addr->sa_family != AF_INET6 || addrlen < sizeof(struct sockaddr_in6))
|
||||
#else
|
||||
if (addr->sa_family != AF_INET || addrlen < sizeof(struct sockaddr_in))
|
||||
#endif
|
||||
{
|
||||
err = EBADF;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Perform the binding depending on the protocol type */
|
||||
switch (psock->s_type)
|
||||
{
|
||||
case SOCK_STREAM:
|
||||
{
|
||||
int ret = uip_tcpconnect(psock->s_conn, inaddr);
|
||||
if (ret < 0)
|
||||
{
|
||||
err = -ret;
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
case SOCK_DGRAM:
|
||||
#warning Put UDP connect logic here
|
||||
#if 0
|
||||
{
|
||||
int ret = uip_udpconnect(psock->s_conn, inaddr);
|
||||
if (ret < 0)
|
||||
{
|
||||
err = -ret;
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
err = EBADF;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
err = ENOSYS;
|
||||
/*return OK;*/
|
||||
|
||||
errout:
|
||||
*get_errno_ptr() = err;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
|
||||
#include <nuttx/net.h>
|
||||
|
||||
#include "net_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
+13
-3
@@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* socket.c
|
||||
* net/socket.c
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
@@ -129,15 +129,25 @@ int socket(int domain, int type, int protocol)
|
||||
|
||||
/* Initialize the socket structure */
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
psock = sockfd_socket(sockfd);
|
||||
if (psock)
|
||||
{
|
||||
/* Save the protocol type */
|
||||
|
||||
psock->s_type = type;
|
||||
|
||||
/* Allocate a TCP connection structure */
|
||||
|
||||
psock->s_conn = uip_tcpalloc();
|
||||
if (!psock->s_conn)
|
||||
{
|
||||
/* Failed to reserve a connection structure */
|
||||
|
||||
sockfd_release(sockfd);
|
||||
err = ENFILE;
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return sockfd;
|
||||
|
||||
|
||||
+1
-1
@@ -34,5 +34,5 @@
|
||||
############################################################################
|
||||
|
||||
UIP_ASRCS =
|
||||
UIP_CSRCS = psock.c uip-arp.c uip.c uip-fw.c uip-neighbor.c uip-split.c uip-wait.c
|
||||
UIP_CSRCS = psock.c uip-arp.c uip.c uip-fw.c uip-neighbor.c uip-split.c uip-tcpconn.c uip-wait.c
|
||||
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/****************************************************************************
|
||||
* net/uip/uip-internal.h
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* This logic was leveraged from uIP which also has a BSD-style license:
|
||||
*
|
||||
* Author Adam Dunkels <adam@dunkels.com>
|
||||
* Copyright (c) 2001-2003, Adam Dunkels.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __UIP_INTERNAL_H
|
||||
#define __UIP_INTERNAL_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Macro Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* g_tcp_sequence[] is used to generate TCP sequence numbers */
|
||||
|
||||
extern uint8 g_tcp_sequence[4];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C" {
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/* Defined in uip_tcpconn.c *************************************************/
|
||||
|
||||
EXTERN void uip_tcpinit(void);
|
||||
EXTERN struct uip_conn *uip_tcpactive(struct uip_tcpip_hdr *buf);
|
||||
EXTERN void uip_tcpnextsequence(void);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __UIP_INTERNAL_H */
|
||||
@@ -0,0 +1,405 @@
|
||||
/****************************************************************************
|
||||
* uip_tcpbind.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 Gregory Nutt 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Compilation Switches
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#ifdef CONFIG_NET
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include <net/uip/uipopt.h>
|
||||
#include <net/uip/uip.h>
|
||||
#include <net/uip/uip-arch.h>
|
||||
|
||||
#include "uip-internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* g_tcp_sequence[] is used to generate TCP sequence numbers */
|
||||
|
||||
uint8 g_tcp_sequence[4];
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* The array containing all uIP connections. */
|
||||
|
||||
static struct uip_conn g_tcp_connections[UIP_CONNS];
|
||||
|
||||
/* Last port used by a TCP connection connection. */
|
||||
|
||||
static uint16 g_last_tcp_port;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Given a port number, find the socket bound to the port number.
|
||||
* Primary use: to determine if a port number is available.
|
||||
*/
|
||||
|
||||
static struct uip_conn *uip_find_conn(uint16 portno)
|
||||
{
|
||||
struct uip_conn *conn;
|
||||
int i;
|
||||
|
||||
/* Check if this port number is already in use, and if so try to find
|
||||
* another one.
|
||||
*/
|
||||
|
||||
for (i = 0; i < UIP_CONNS; i++)
|
||||
{
|
||||
conn = &g_tcp_connections[i];
|
||||
if (conn->tcpstateflags != UIP_CLOSED && conn->lport == htons(g_last_tcp_port))
|
||||
{
|
||||
/* The portnumber is in use */
|
||||
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: uip_tcpinit()
|
||||
*
|
||||
* Description:
|
||||
* Initialize the TCP/IP connection structures. Called only from the UIP
|
||||
* layer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void uip_tcpinit(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < UIP_CONNS; i++)
|
||||
{
|
||||
g_tcp_connections[i].tcpstateflags = UIP_CLOSED;
|
||||
}
|
||||
|
||||
g_last_tcp_port = 1024;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: uip_tcpalloc()
|
||||
*
|
||||
* Description:
|
||||
* Find a free TCP/IP connection structure and allocate it
|
||||
* for use. This is normally something done by the implementation of the
|
||||
* socket() API but is also called from the interrupt level when a TCP
|
||||
* packet is received while "listening"
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct uip_conn *uip_tcpalloc(void)
|
||||
{
|
||||
#if 0 /* Revisit */
|
||||
struct uip_conn *oldest = NULL;
|
||||
#endif
|
||||
irqstate_t flags;
|
||||
unsigned int i;
|
||||
|
||||
/* Because this routine is called from both interrupt level and
|
||||
* and from user level, we have not option but to disable interrupts
|
||||
* while accessing g_tcp_connections[];
|
||||
*/
|
||||
|
||||
flags = irqsave();
|
||||
|
||||
/* Check if there are any available connections. */
|
||||
|
||||
for (i = 0; i < UIP_CONNS; i++)
|
||||
{
|
||||
/* First, check if any connections structures are marked as
|
||||
* CLOSED in the table of pre-allocated connection structures.
|
||||
*/
|
||||
|
||||
if (g_tcp_connections[i].tcpstateflags == UIP_CLOSED)
|
||||
{
|
||||
/* We found an unused structure. Mark as allocated, but not
|
||||
* initialized.
|
||||
*/
|
||||
|
||||
memset(&g_tcp_connections[i], 0, sizeof(struct uip_conn));
|
||||
g_tcp_connections[i].tcpstateflags = UIP_ALLOCATED;
|
||||
|
||||
irqrestore(flags);
|
||||
return &g_tcp_connections[i];
|
||||
}
|
||||
|
||||
#if 0 /* Revisit */
|
||||
/* As a fallback, check for connection structures in the TIME_WAIT
|
||||
* state. If no CLOSED connections are found, then take the oldest
|
||||
*/
|
||||
|
||||
if (g_tcp_connections[i].tcpstateflags == UIP_TIME_WAIT)
|
||||
{
|
||||
if (!oldest || g_tcp_connections[i].timer > oldest->timer)
|
||||
{
|
||||
oldest = &g_tcp_connections[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return oldest;
|
||||
#else
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: uip_tcpfree()
|
||||
*
|
||||
* Description:
|
||||
* Free a connection structure that is no longer in use. This should be
|
||||
* done by the implementation of close()
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void uip_tcpfree(struct uip_conn *conn)
|
||||
{
|
||||
/* this action is atomic and should require no special protetion */
|
||||
|
||||
conn->tcpstateflags = UIP_CLOSED;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: uip_tcpactive()
|
||||
*
|
||||
* Description:
|
||||
* Find a connection structure that is the appropriate
|
||||
* connection to be used withi the provided TCP/IP header
|
||||
*
|
||||
* Assumptions:
|
||||
* This function is called from UIP logic at interrupt level
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct uip_conn *uip_tcpactive(struct uip_tcpip_hdr *buf)
|
||||
{
|
||||
struct uip_conn *conn;
|
||||
for (conn = g_tcp_connections; conn <= &g_tcp_connections[UIP_CONNS - 1]; conn++)
|
||||
{
|
||||
/* Find an open connection matching the tcp input */
|
||||
|
||||
if (conn->tcpstateflags != UIP_CLOSED &&
|
||||
buf->destport == conn->lport && buf->srcport == conn->rport &&
|
||||
uip_ipaddr_cmp(buf->srcipaddr, conn->ripaddr))
|
||||
{
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: uip_tcppoll()
|
||||
*
|
||||
* Description:
|
||||
* Periodic processing for a 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(unsigned int conn)
|
||||
{
|
||||
uip_conn = &g_tcp_connections[conn];
|
||||
uip_interrupt(UIP_TIMER);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: uip_tcpactive()
|
||||
*
|
||||
* Description:
|
||||
* Increment the TCP/IP sequence number
|
||||
*
|
||||
* Assumptions:
|
||||
* This function is called from the interrupt level
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void uip_tcpnextsequence(void)
|
||||
{
|
||||
/* This inplements a byte-by-byte big-endian increment */
|
||||
|
||||
if (++g_tcp_sequence[3] == 0)
|
||||
{
|
||||
if (++g_tcp_sequence[2] == 0)
|
||||
{
|
||||
if (++g_tcp_sequence[1] == 0)
|
||||
{
|
||||
++g_tcp_sequence[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: uip_tcpbind()
|
||||
*
|
||||
* Description:
|
||||
* This function implements the UIP specific parts of the standard TCP
|
||||
* bind() operation.
|
||||
*
|
||||
* Assumptions:
|
||||
* This function is called from normal user level code.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
int uip_tcpbind(struct uip_conn *conn, const struct sockaddr_in6 *addr)
|
||||
#else
|
||||
int uip_tcpbind(struct uip_conn *conn, const struct sockaddr_in *addr)
|
||||
#endif
|
||||
{
|
||||
#warning "Need to implement bind logic"
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: uip_tcpbind()
|
||||
*
|
||||
* Description:
|
||||
* This function implements the UIP specific parts of the standard
|
||||
* TCP connect() operation: It connects to a remote host using TCP.
|
||||
*
|
||||
* This function is used to start a new connection to the specified
|
||||
* port on the specied host. It uses the connection structure that was
|
||||
* allocated by a preceding socket() call. It sets the connection to
|
||||
* the SYN_SENT state and sets the retransmission timer to 0. This will
|
||||
* cause a TCP SYN segment to be sent out the next time this connection
|
||||
* is periodically processed, which usually is done within 0.5 seconds
|
||||
* after the call to uip_tcpconnect().
|
||||
*
|
||||
* Assumptions:
|
||||
* This function is called from normal user level code.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
int uip_tcpconnect(struct uip_conn *conn, const struct sockaddr_in6 *addr )
|
||||
#else
|
||||
int uip_tcpconnect(struct uip_conn *conn, const struct sockaddr_in *addr )
|
||||
#endif
|
||||
{
|
||||
uint16 port;
|
||||
int i;
|
||||
|
||||
/* If the TCP port has not alread been bound to a local port, then select
|
||||
* one now.
|
||||
*/
|
||||
|
||||
port = ntohs(conn->lport);
|
||||
if (port == 0)
|
||||
{
|
||||
/* No local port assigned. Loop until we find a valid listen port number\
|
||||
* that is not being used by any other connection.
|
||||
*/
|
||||
|
||||
do
|
||||
{
|
||||
/* Guess that the next available port number will be the one after
|
||||
* the last port number assigned.
|
||||
*/
|
||||
#warning "This need protection from other threads and from interrupts"
|
||||
port = ++g_last_tcp_port;
|
||||
|
||||
/* Make sure that the port number is within range */
|
||||
|
||||
if (g_last_tcp_port >= 32000)
|
||||
{
|
||||
g_last_tcp_port = 4096;
|
||||
}
|
||||
}
|
||||
while (uip_find_conn(g_last_tcp_port));
|
||||
}
|
||||
|
||||
/* Initialize and return the connection structure, bind it to the port number */
|
||||
|
||||
conn->tcpstateflags = UIP_SYN_SENT;
|
||||
|
||||
conn->snd_nxt[0] = g_tcp_sequence[0];
|
||||
conn->snd_nxt[1] = g_tcp_sequence[1];
|
||||
conn->snd_nxt[2] = g_tcp_sequence[2];
|
||||
conn->snd_nxt[3] = g_tcp_sequence[3];
|
||||
|
||||
conn->initialmss = conn->mss = UIP_TCP_MSS;
|
||||
|
||||
conn->len = 1; /* TCP length of the SYN is one. */
|
||||
conn->nrtx = 0;
|
||||
conn->timer = 1; /* Send the SYN next time around. */
|
||||
conn->rto = UIP_RTO;
|
||||
conn->sa = 0;
|
||||
conn->sv = 16; /* Initial value of the RTT variance. */
|
||||
conn->lport = htons(port);
|
||||
|
||||
/* The sockaddr port is 16 bits and already in network order */
|
||||
|
||||
conn->rport = addr->sin_port;
|
||||
|
||||
/* The sockaddr address is 32-bits in network order. */
|
||||
|
||||
uip_ipaddr_copy(&conn->ripaddr, addr->sin_addr.s_addr);
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET */
|
||||
@@ -0,0 +1,170 @@
|
||||
/************************************************************
|
||||
* uip-udpconn.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 Gregory Nutt 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.
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Compilation Switches
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Included Files
|
||||
************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#if defined(CONFIG_NET) && defined(CONFIG_NET_UDP)
|
||||
|
||||
/************************************************************
|
||||
* Private Functions
|
||||
************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Public Functions
|
||||
************************************************************/
|
||||
|
||||
struct uip_udp_conn *uip_udpalloc(void);
|
||||
void uip_udpfree(struct uip_udp_conn *conn);
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
int uip_udpbind(struct uip_udp_conn *conn, const struct sockaddr_in6 *addr);
|
||||
#else
|
||||
int uip_udpbind(struct uip_udp_conn *conn, const struct sockaddr_in *addr);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in6 *addr )
|
||||
#else
|
||||
int uip_udpbind(struct uip_udp_conn *conn, const struct sockaddr_in *addr)
|
||||
#endif
|
||||
{
|
||||
uint16 ipaddr[2];
|
||||
|
||||
if (pdhcpc->state == STATE_INITIAL)
|
||||
{
|
||||
uip_ipaddr(ipaddr, 0,0,0,0);
|
||||
uip_sethostaddr(ipaddr);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Set up a new UDP connection.
|
||||
*
|
||||
* 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_udp_bind() call, after the uip_udp_new() function has been
|
||||
* called.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* uip_ipaddr_t addr;
|
||||
* struct uip_udp_conn *c;
|
||||
*
|
||||
* uip_ipaddr(&addr, 192,168,2,1);
|
||||
* c = uip_udp_new(&addr, HTONS(12345));
|
||||
* if(c != NULL) {
|
||||
* uip_udp_bind(c, HTONS(12344));
|
||||
* }
|
||||
*
|
||||
* ripaddr The IP address of the remote host.
|
||||
*
|
||||
* rport The remote port number in network byte order.
|
||||
*
|
||||
* Return: The uip_udp_conn structure for the new connection or NULL
|
||||
* if no connection could be allocated.
|
||||
*/
|
||||
|
||||
struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, uint16 rport)
|
||||
{
|
||||
struct uip_udp_conn *conn;
|
||||
int i;
|
||||
|
||||
/* Find an unused local port number. Loop until we find a valid listen port
|
||||
* number that is not being used by any other connection.
|
||||
*/
|
||||
|
||||
do
|
||||
{
|
||||
/* Guess that the next available port number will be the one after
|
||||
* the last port number assigned.
|
||||
*/
|
||||
|
||||
++g_last_udp_port;
|
||||
|
||||
/* Make sure that the port number is within range */
|
||||
if (g_last_udp_port >= 32000)
|
||||
{
|
||||
g_last_udp_port = 4096;
|
||||
}
|
||||
}
|
||||
while (uip_find_udp_conn(g_last_udp_port));
|
||||
|
||||
/* Now find an available UDP connection structure */
|
||||
|
||||
conn = 0;
|
||||
for (i = 0; i < UIP_UDP_CONNS; i++)
|
||||
{
|
||||
if (uip_udp_conns[c].lport == 0)
|
||||
{
|
||||
conn = &uip_udp_conns[c];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return an error if no connection is available */
|
||||
|
||||
if (conn == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize and return the connection structure, bind it to the port number */
|
||||
|
||||
conn->lport = HTONS(g_last_udp_port);
|
||||
conn->rport = rport;
|
||||
|
||||
if (ripaddr == NULL)
|
||||
{
|
||||
memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
uip_ipaddr_copy(&conn->ripaddr, ripaddr);
|
||||
}
|
||||
|
||||
conn->ttl = UIP_TTL;
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET */
|
||||
+224
-333
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user