net: Enable TCP support
User can enable TCP server (listening socket) support in the IP stack. This commit does not yet have TCP client (connecting socket) support. Change-Id: I75dd02a81addc1d1e026463b53631d56378157df Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
parent
d0ba82a581
commit
ad2e661569
32 changed files with 967 additions and 317 deletions
|
@ -106,6 +106,9 @@ struct ip_buf {
|
|||
void *uip_udp_conn;
|
||||
linkaddr_t dest;
|
||||
linkaddr_t src;
|
||||
#if defined(CONFIG_NETWORKING_WITH_TCP)
|
||||
int8_t sent_status; /* tells if the TCP packet was sent ok or not */
|
||||
#endif
|
||||
|
||||
/* Neighbor discovery vars. Note that we are using void pointers here
|
||||
* so that we do not need to include Contiki headers in this file.
|
||||
|
@ -203,6 +206,7 @@ struct ip_buf {
|
|||
#define ip_buf_ll_dest(buf) (((struct ip_buf *)net_buf_user_data((buf)))->dest)
|
||||
#define ip_buf_context(buf) (((struct ip_buf *)net_buf_user_data((buf)))->context)
|
||||
#define ip_buf_type(ptr) (((struct ip_buf *)net_buf_user_data((ptr)))->type)
|
||||
#define ip_buf_sent_status(ptr) (((struct ip_buf *)net_buf_user_data((ptr)))->sent_status)
|
||||
/* @endcond */
|
||||
|
||||
/** NET_BUF_IP
|
||||
|
|
|
@ -42,6 +42,12 @@ extern "C" {
|
|||
#define NET_PRINT(...)
|
||||
#endif /* CONFIG_NETWORKING_WITH_LOGGING */
|
||||
|
||||
enum net_tcp_type {
|
||||
NET_TCP_TYPE_UNKNOWN = 0,
|
||||
NET_TCP_TYPE_SERVER,
|
||||
NET_TCP_TYPE_CLIENT,
|
||||
};
|
||||
|
||||
struct net_buf;
|
||||
struct net_context;
|
||||
|
||||
|
|
|
@ -105,6 +105,13 @@ struct net_tuple {
|
|||
enum ip_protocol ip_proto;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_NETWORKING_WITH_TCP)
|
||||
enum tcp_event_type {
|
||||
TCP_READ_EVENT = 1,
|
||||
TCP_WRITE_EVENT,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -115,6 +115,24 @@ config NETWORKING_IPV6_NO_ND
|
|||
slip and tun device.
|
||||
endif
|
||||
|
||||
config NETWORKING_WITH_TCP
|
||||
bool
|
||||
prompt "Enable TCP protocol"
|
||||
depends on NETWORKING
|
||||
default n
|
||||
help
|
||||
Enable Transmission and Control Protocol (TCP) support.
|
||||
|
||||
config TCP_MSS
|
||||
int
|
||||
prompt "TCP maximum segment size"
|
||||
depends on NETWORKING_WITH_TCP
|
||||
default 0
|
||||
help
|
||||
Tweak the TCP maximum segment size. Normally one should
|
||||
not change this but let the IP stack to calculate a best
|
||||
size for it.
|
||||
|
||||
config NETWORKING_WITH_RPL
|
||||
bool
|
||||
prompt "Enable RPL (ripple) IPv6 mesh routing protocol"
|
||||
|
|
|
@ -39,6 +39,12 @@ config NETWORK_IP_STACK_DEBUG_FULL
|
|||
bool "Print both messages and annotations"
|
||||
endchoice
|
||||
|
||||
config NETWORK_IP_STACK_DEBUG_CONTEXT
|
||||
bool "Debug network context allocation"
|
||||
default n
|
||||
help
|
||||
Enables printing of network context allocations and frees.
|
||||
|
||||
config NETWORK_IP_STACK_DEBUG_NET_BUF
|
||||
bool "Debug network buffer allocation"
|
||||
default n
|
||||
|
@ -51,6 +57,13 @@ config NETWORK_IP_STACK_DEBUG_RECV_SEND
|
|||
help
|
||||
Enables generic debug printing when receiving and sending data.
|
||||
|
||||
config NETWORK_IP_STACK_DEBUG_TCP_PSOCK
|
||||
bool "Debug network TCP protosockets"
|
||||
depends on NETWORKING_WITH_TCP
|
||||
default n
|
||||
help
|
||||
Enables debugging the protosockets used in TCP engine.
|
||||
|
||||
config NETWORK_IP_STACK_DEBUG_IPV6
|
||||
bool "Debug core IPv6"
|
||||
depends on NETWORKING_WITH_IPV6
|
||||
|
|
|
@ -52,6 +52,8 @@ obj-$(CONFIG_NETWORKING_WITH_IPV4) += \
|
|||
contiki/ipv4/uip.o \
|
||||
contiki/ipv4/uip-neighbor.o
|
||||
|
||||
obj-$(CONFIG_NETWORKING_WITH_TCP) += contiki/ip/psock.o
|
||||
|
||||
# RPL (RFC 6550) support
|
||||
ifeq ($(CONFIG_NETWORKING_WITH_RPL),y)
|
||||
ccflags-y += -DUIP_CONF_IPV6_RPL=1
|
||||
|
|
|
@ -45,8 +45,15 @@ typedef unsigned int uip_stats_t;
|
|||
/* The actual MTU size is defined in uipopt.h */
|
||||
#define UIP_CONF_BUFFER_SIZE UIP_LINK_MTU
|
||||
|
||||
/* No TCP yet */
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
#define UIP_CONF_TCP 1
|
||||
|
||||
#if CONFIG_TCP_MSS > 0
|
||||
#define UIP_CONF_TCP_MSS CONFIG_TCP_MSS
|
||||
#endif /* CONFIG_TCP_MSS */
|
||||
#else
|
||||
#define UIP_CONF_TCP 0
|
||||
#endif
|
||||
|
||||
/* We do not want to be a router */
|
||||
#define UIP_CONF_ROUTER 0
|
||||
|
|
|
@ -34,7 +34,14 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include "net/ip/psock.h"
|
||||
#include <net/ip_buf.h>
|
||||
|
||||
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_TCP_PSOCK
|
||||
#define DEBUG 1
|
||||
#endif
|
||||
#include "contiki/ip/uip-debug.h"
|
||||
|
||||
#include "contiki/ip/psock.h"
|
||||
|
||||
#define STATE_NONE 0
|
||||
#define STATE_ACKED 1
|
||||
|
@ -80,6 +87,8 @@ buf_bufdata(struct psock_buf *buf, uint16_t len,
|
|||
uint8_t **dataptr, uint16_t *datalen)
|
||||
{
|
||||
if(*datalen < buf->left) {
|
||||
PRINTF("%d: *datalen(%d) < left(%d), copy buf->ptr(%p) <- *dataptr(%p)\n",
|
||||
__LINE__, *datalen, buf->left, buf->ptr, *dataptr);
|
||||
memcpy(buf->ptr, *dataptr, *datalen);
|
||||
buf->ptr += *datalen;
|
||||
buf->left -= *datalen;
|
||||
|
@ -87,6 +96,8 @@ buf_bufdata(struct psock_buf *buf, uint16_t len,
|
|||
*datalen = 0;
|
||||
return BUF_NOT_FULL;
|
||||
} else if(*datalen == buf->left) {
|
||||
PRINTF("%d: *datalen(%d) == left(%d), copy buf->ptr(%p) <- *dataptr(%p)\n",
|
||||
__LINE__, *datalen, buf->left, buf->ptr, *dataptr);
|
||||
memcpy(buf->ptr, *dataptr, *datalen);
|
||||
buf->ptr += *datalen;
|
||||
buf->left = 0;
|
||||
|
@ -94,6 +105,8 @@ buf_bufdata(struct psock_buf *buf, uint16_t len,
|
|||
*datalen = 0;
|
||||
return BUF_FULL;
|
||||
} else {
|
||||
PRINTF("%d: *datalen(%d) > left(%d), copy buf->ptr(%p) <- buf->left(%p)\n",
|
||||
__LINE__, *datalen, buf->left, buf->ptr, buf->left);
|
||||
memcpy(buf->ptr, *dataptr, buf->left);
|
||||
buf->ptr += buf->left;
|
||||
*datalen -= buf->left;
|
||||
|
@ -133,18 +146,24 @@ data_is_sent_and_acked(CC_REGISTER_ARG struct psock *s)
|
|||
/* If data has previously been sent, and the data has been acked, we
|
||||
increase the send pointer and call send_data() to send more
|
||||
data. */
|
||||
if(s->state != STATE_DATA_SENT || uip_rexmit()) {
|
||||
if(s->sendlen > uip_mss()) {
|
||||
uip_send(s->sendptr, uip_mss());
|
||||
PRINTF("%s: psock %p buf %p data[%p..%p] sendptr %p sendlen %d mss %d\n",
|
||||
__func__, s, s->net_buf, ip_buf_appdata(s->net_buf),
|
||||
ip_buf_appdata(s->net_buf) + ip_buf_appdatalen(s->net_buf),
|
||||
s->sendptr, s->sendlen,
|
||||
uip_mss(s->net_buf));
|
||||
|
||||
if(s->state != STATE_DATA_SENT || uip_rexmit(s->net_buf)) {
|
||||
if(s->sendlen > uip_mss(s->net_buf)) {
|
||||
uip_send(s->net_buf, s->sendptr, uip_mss(s->net_buf));
|
||||
} else {
|
||||
uip_send(s->sendptr, s->sendlen);
|
||||
uip_send(s->net_buf, s->sendptr, s->sendlen);
|
||||
}
|
||||
s->state = STATE_DATA_SENT;
|
||||
return 0;
|
||||
} else if(s->state == STATE_DATA_SENT && uip_acked()) {
|
||||
if(s->sendlen > uip_mss()) {
|
||||
s->sendlen -= uip_mss();
|
||||
s->sendptr += uip_mss();
|
||||
} else if(s->state == STATE_DATA_SENT && uip_acked(s->net_buf)) {
|
||||
if(s->sendlen > uip_mss(s->net_buf)) {
|
||||
s->sendlen -= uip_mss(s->net_buf);
|
||||
s->sendptr += uip_mss(s->net_buf);
|
||||
} else {
|
||||
s->sendptr += s->sendlen;
|
||||
s->sendlen = 0;
|
||||
|
@ -155,20 +174,23 @@ data_is_sent_and_acked(CC_REGISTER_ARG struct psock *s)
|
|||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PT_THREAD(psock_send(CC_REGISTER_ARG struct psock *s, const uint8_t *buf,
|
||||
unsigned int len))
|
||||
PT_THREAD(psock_send(CC_REGISTER_ARG struct psock *s, struct net_buf *net_buf))
|
||||
{
|
||||
PT_BEGIN(&s->psockpt);
|
||||
|
||||
PRINTF("%s: psock %p buf %p len %d\n", __func__, s, net_buf,
|
||||
ip_buf_appdatalen(net_buf));
|
||||
|
||||
/* If there is no data to send, we exit immediately. */
|
||||
if(len == 0) {
|
||||
if(ip_buf_appdatalen(net_buf) == 0) {
|
||||
PT_EXIT(&s->psockpt);
|
||||
}
|
||||
|
||||
/* Save the length of and a pointer to the data that is to be
|
||||
sent. */
|
||||
s->sendptr = buf;
|
||||
s->sendlen = len;
|
||||
s->sendptr = ip_buf_appdata(net_buf);
|
||||
s->sendlen = ip_buf_appdatalen(net_buf);
|
||||
s->net_buf = net_buf;
|
||||
|
||||
s->state = STATE_NONE;
|
||||
|
||||
|
@ -203,19 +225,20 @@ PT_THREAD(psock_generator_send(CC_REGISTER_ARG struct psock *s,
|
|||
/* Call the generator function to generate the data in the
|
||||
uip_appdata buffer. */
|
||||
s->sendlen = generate(arg);
|
||||
s->sendptr = uip_appdata;
|
||||
s->sendptr = uip_appdata(s->net_buf);
|
||||
|
||||
if(s->sendlen > uip_mss()) {
|
||||
uip_send(s->sendptr, uip_mss());
|
||||
if(s->sendlen > uip_mss(s->net_buf)) {
|
||||
uip_send(s->net_buf, s->sendptr, uip_mss(s->net_buf));
|
||||
} else {
|
||||
uip_send(s->sendptr, s->sendlen);
|
||||
uip_send(s->net_buf, s->sendptr, s->sendlen);
|
||||
}
|
||||
s->state = STATE_DATA_SENT;
|
||||
|
||||
/* Wait until all data is sent and acknowledged. */
|
||||
// if (!s->sendlen) break; //useful debugging aid
|
||||
PT_YIELD_UNTIL(&s->psockpt, uip_acked() || uip_rexmit());
|
||||
} while(!uip_acked());
|
||||
PT_YIELD_UNTIL(&s->psockpt, uip_acked(s->net_buf) || \
|
||||
uip_rexmit(s->net_buf));
|
||||
} while(!uip_acked(s->net_buf));
|
||||
|
||||
s->state = STATE_NONE;
|
||||
|
||||
|
@ -239,7 +262,7 @@ psock_newdata(struct psock *s)
|
|||
/* All data in uip_appdata buffer already consumed. */
|
||||
s->state = STATE_BLOCKED_NEWDATA;
|
||||
return 0;
|
||||
} else if(uip_newdata()) {
|
||||
} else if(uip_newdata(s->net_buf)) {
|
||||
/* There is new data that has not been consumed. */
|
||||
return 1;
|
||||
} else {
|
||||
|
@ -261,8 +284,8 @@ PT_THREAD(psock_readto(CC_REGISTER_ARG struct psock *psock, unsigned char c))
|
|||
if(psock->readlen == 0) {
|
||||
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
|
||||
psock->state = STATE_READ;
|
||||
psock->readptr = (uint8_t *)uip_appdata;
|
||||
psock->readlen = uip_datalen();
|
||||
psock->readptr = (uint8_t *)uip_appdata(psock->net_buf);
|
||||
psock->readlen = uip_datalen(psock->net_buf);
|
||||
}
|
||||
} while(buf_bufto(&psock->buf, c,
|
||||
&psock->readptr,
|
||||
|
@ -289,8 +312,8 @@ PT_THREAD(psock_readbuf_len(CC_REGISTER_ARG struct psock *psock, uint16_t len))
|
|||
if(psock->readlen == 0) {
|
||||
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
|
||||
psock->state = STATE_READ;
|
||||
psock->readptr = (uint8_t *)uip_appdata;
|
||||
psock->readlen = uip_datalen();
|
||||
psock->readptr = (uint8_t *)uip_appdata(psock->net_buf);
|
||||
psock->readlen = uip_datalen(psock->net_buf);
|
||||
}
|
||||
} while(buf_bufdata(&psock->buf, psock->bufsize,
|
||||
&psock->readptr, &psock->readlen) == BUF_NOT_FULL &&
|
||||
|
@ -305,14 +328,14 @@ PT_THREAD(psock_readbuf_len(CC_REGISTER_ARG struct psock *psock, uint16_t len))
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
psock_init(CC_REGISTER_ARG struct psock *psock,
|
||||
uint8_t *buffer, unsigned int buffersize)
|
||||
psock_init(CC_REGISTER_ARG struct psock *psock, struct net_buf *net_buf)
|
||||
{
|
||||
psock->state = STATE_NONE;
|
||||
psock->readlen = 0;
|
||||
psock->bufptr = buffer;
|
||||
psock->bufsize = buffersize;
|
||||
buf_setup(&psock->buf, buffer, buffersize);
|
||||
psock->bufptr = ip_buf_appdata(net_buf);
|
||||
psock->bufsize = ip_buf_appdatalen(net_buf);
|
||||
psock->net_buf = net_buf;
|
||||
buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
|
||||
PT_INIT(&psock->pt);
|
||||
PT_INIT(&psock->psockpt);
|
||||
}
|
||||
|
|
|
@ -127,9 +127,11 @@ struct psock {
|
|||
unsigned int bufsize; /* The size of the input buffer. */
|
||||
|
||||
unsigned char state; /* The state of the protosocket. */
|
||||
|
||||
struct net_buf *net_buf; /* contains conn state etc. */
|
||||
};
|
||||
|
||||
void psock_init(struct psock *psock, uint8_t *buffer, unsigned int buffersize);
|
||||
void psock_init(struct psock *psock, struct net_buf *net_buf);
|
||||
/**
|
||||
* Initialize a protosocket.
|
||||
*
|
||||
|
@ -140,15 +142,12 @@ void psock_init(struct psock *psock, uint8_t *buffer, unsigned int buffersize);
|
|||
* \param psock (struct psock *) A pointer to the protosocket to be
|
||||
* initialized
|
||||
*
|
||||
* \param buffer (uint8_t *) A pointer to the input buffer for the
|
||||
* protosocket.
|
||||
*
|
||||
* \param buffersize (unsigned int) The size of the input buffer.
|
||||
* \param buffer (struct net_buf *) A Pointer to network buffer to send.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define PSOCK_INIT(psock, buffer, buffersize) \
|
||||
psock_init(psock, buffer, buffersize)
|
||||
#define PSOCK_INIT(psock, net_buf) \
|
||||
psock_init(psock, net_buf)
|
||||
|
||||
/**
|
||||
* Start the protosocket protothread in a function.
|
||||
|
@ -163,7 +162,7 @@ void psock_init(struct psock *psock, uint8_t *buffer, unsigned int buffersize);
|
|||
*/
|
||||
#define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt))
|
||||
|
||||
PT_THREAD(psock_send(struct psock *psock, const uint8_t *buf, unsigned int len));
|
||||
PT_THREAD(psock_send(struct psock *psock, struct net_buf *buf));
|
||||
/**
|
||||
* Send data.
|
||||
*
|
||||
|
@ -174,15 +173,12 @@ PT_THREAD(psock_send(struct psock *psock, const uint8_t *buf, unsigned int len))
|
|||
* \param psock (struct psock *) A pointer to the protosocket over which
|
||||
* data is to be sent.
|
||||
*
|
||||
* \param data (uint8_t *) A pointer to the data that is to be sent.
|
||||
*
|
||||
* \param datalen (unsigned int) The length of the data that is to be
|
||||
* sent.
|
||||
* \param buf (struct net_buf *) A pointer to the buffer that is to be sent.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define PSOCK_SEND(psock, data, datalen) \
|
||||
PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, data, datalen))
|
||||
#define PSOCK_SEND(psock, buf) \
|
||||
PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, buf))
|
||||
|
||||
/**
|
||||
* \brief Send a null-terminated string.
|
||||
|
|
|
@ -75,7 +75,7 @@ static void
|
|||
init_simple_udp(void)
|
||||
{
|
||||
if(started == 0) {
|
||||
process_start(&simple_udp_process, NULL);
|
||||
process_start(&simple_udp_process, NULL, NULL);
|
||||
started = 1;
|
||||
}
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ simple_udp_unregister(struct simple_udp_connection *c)
|
|||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(simple_udp_process, ev, data, buf)
|
||||
PROCESS_THREAD(simple_udp_process, ev, data, buf, user_data)
|
||||
{
|
||||
struct simple_udp_connection *c;
|
||||
PROCESS_BEGIN();
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_RECV_SEND
|
||||
#define TCPIP_CONF_ANNOTATE_TRANSMISSIONS 1
|
||||
#define DEBUG 1
|
||||
#endif
|
||||
#include "contiki/ip/uip-debug.h"
|
||||
|
@ -218,7 +219,8 @@ packet_input(struct net_buf *buf)
|
|||
#if UIP_TCP
|
||||
#if UIP_ACTIVE_OPEN
|
||||
struct uip_conn *
|
||||
tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
|
||||
tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate,
|
||||
struct process *process)
|
||||
{
|
||||
struct uip_conn *c;
|
||||
|
||||
|
@ -227,7 +229,7 @@ tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
c->appstate.p = PROCESS_CURRENT();
|
||||
c->appstate.p = process;
|
||||
c->appstate.state = appstate;
|
||||
|
||||
tcpip_poll_tcp(c);
|
||||
|
@ -237,7 +239,7 @@ tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
|
|||
#endif /* UIP_ACTIVE_OPEN */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
tcp_unlisten(uint16_t port)
|
||||
tcp_unlisten(uint16_t port, struct process *handler)
|
||||
{
|
||||
static unsigned char i;
|
||||
struct listenport *l;
|
||||
|
@ -245,7 +247,7 @@ tcp_unlisten(uint16_t port)
|
|||
l = s.listenports;
|
||||
for(i = 0; i < UIP_LISTENPORTS; ++i) {
|
||||
if(l->port == port &&
|
||||
l->p == PROCESS_CURRENT()) {
|
||||
l->p == handler) {
|
||||
l->port = 0;
|
||||
uip_unlisten(port);
|
||||
break;
|
||||
|
@ -255,7 +257,7 @@ tcp_unlisten(uint16_t port)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
tcp_listen(uint16_t port)
|
||||
tcp_listen(uint16_t port, struct process *handler)
|
||||
{
|
||||
static unsigned char i;
|
||||
struct listenport *l;
|
||||
|
@ -264,7 +266,7 @@ tcp_listen(uint16_t port)
|
|||
for(i = 0; i < UIP_LISTENPORTS; ++i) {
|
||||
if(l->port == 0) {
|
||||
l->port = port;
|
||||
l->p = PROCESS_CURRENT();
|
||||
l->p = handler;
|
||||
uip_listen(port);
|
||||
break;
|
||||
}
|
||||
|
@ -518,7 +520,11 @@ eventhandler(process_event_t ev, process_data_t data, struct net_buf *buf)
|
|||
#endif /* UIP_UDP */
|
||||
|
||||
case PACKET_INPUT:
|
||||
packet_input(buf);
|
||||
if (!packet_input(buf)) {
|
||||
PRINTF("Packet %p was not sent and must be discarded by caller\n", buf);
|
||||
} else {
|
||||
PRINTF("Packet %p was sent ok\n", buf);
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
@ -700,6 +706,26 @@ tcpip_ipv6_output(struct net_buf *buf)
|
|||
uip_len(buf) = 0;
|
||||
uip_ext_len(buf) = 0;
|
||||
return 0; /* packet was discarded */
|
||||
#else /* UIP_ND6_SEND_NA */
|
||||
int uiplen = uip_len(buf);
|
||||
int extlen = uip_ext_len(buf);
|
||||
|
||||
/* Neighbor discovery is not there. Just try to send the packet. */
|
||||
ret = tcpip_output(buf, NULL);
|
||||
if (ret) {
|
||||
/* We must set the length back as these were overwritten
|
||||
* by other part of the stack. If we do not do this then
|
||||
* there will be a double memory free in the caller.
|
||||
* FIXME properly later!
|
||||
*/
|
||||
uip_len(buf) = uiplen;
|
||||
uip_ext_len(buf) = extlen;
|
||||
} else {
|
||||
uip_len(buf) = 0;
|
||||
uip_ext_len(buf) = 0;
|
||||
}
|
||||
return ret;
|
||||
|
||||
#endif /* UIP_ND6_SEND_NA */
|
||||
} else {
|
||||
#if UIP_ND6_SEND_NA
|
||||
|
@ -810,7 +836,7 @@ tcpip_poll_tcp(struct uip_conn *conn)
|
|||
void
|
||||
tcpip_uipcall(struct net_buf *buf)
|
||||
{
|
||||
uip_udp_appstate_t *ts;
|
||||
struct tcpip_uipstate *ts;
|
||||
|
||||
#if UIP_UDP
|
||||
if(uip_conn(buf) != NULL) {
|
||||
|
@ -852,7 +878,7 @@ tcpip_uipcall(struct net_buf *buf)
|
|||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(tcpip_process, ev, data, buf)
|
||||
PROCESS_THREAD(tcpip_process, ev, data, buf, user_data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ CCIF void tcp_attach(struct uip_conn *conn,
|
|||
* \param port The port number in network byte order.
|
||||
*
|
||||
*/
|
||||
CCIF void tcp_listen(uint16_t port);
|
||||
CCIF void tcp_listen(uint16_t port, struct process *handler);
|
||||
|
||||
/**
|
||||
* Close a listening TCP port.
|
||||
|
@ -141,7 +141,7 @@ CCIF void tcp_listen(uint16_t port);
|
|||
* \param port The port number in network byte order.
|
||||
*
|
||||
*/
|
||||
CCIF void tcp_unlisten(uint16_t port);
|
||||
CCIF void tcp_unlisten(uint16_t port, struct process *handler);
|
||||
|
||||
/**
|
||||
* Open a TCP connection to the specified IP address and port.
|
||||
|
@ -167,7 +167,7 @@ CCIF void tcp_unlisten(uint16_t port);
|
|||
*
|
||||
*/
|
||||
CCIF struct uip_conn *tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port,
|
||||
void *appstate);
|
||||
void *appstate, struct process *process);
|
||||
|
||||
/**
|
||||
* Cause a specified TCP connection to be polled.
|
||||
|
|
|
@ -53,7 +53,7 @@ init(void)
|
|||
static uint8_t inited = 0;
|
||||
if(!inited) {
|
||||
inited = 1;
|
||||
process_start(&udp_socket_process, NULL);
|
||||
process_start(&udp_socket_process, NULL, NULL);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -152,7 +152,7 @@ udp_socket_sendto(struct net_buf *buf, struct udp_socket *c,
|
|||
return -1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(udp_socket_process, ev, data, buf)
|
||||
PROCESS_THREAD(udp_socket_process, ev, data, buf, user_data)
|
||||
{
|
||||
struct udp_socket *c;
|
||||
PROCESS_BEGIN();
|
||||
|
|
|
@ -12,7 +12,6 @@ MEMB(packets_memb, struct uip_packetqueue_packet, MAX_NUM_QUEUED_PACKETS);
|
|||
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_PACKET_QUEUE
|
||||
#define DEBUG 1
|
||||
#endif
|
||||
|
||||
#include "contiki/ip/uip-debug.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -1588,6 +1588,12 @@ uint8_t uip_process(struct net_buf *buf, uint8_t flag);
|
|||
#define UIP_UDP_TIMER 5
|
||||
#endif /* UIP_UDP */
|
||||
|
||||
#if UIP_TCP
|
||||
#define UIP_TCP_SEND_CONN 6 /* Tells uIP that a TCP segment
|
||||
should be constructed in the
|
||||
uip_buf buffer. */
|
||||
#endif
|
||||
|
||||
/* The TCP states used in the uip_conn->tcpstateflags. */
|
||||
#define UIP_CLOSED 0
|
||||
#define UIP_SYN_RCVD 1
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
|
||||
#include <net/ip_buf.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Variable definitions. */
|
||||
|
||||
|
@ -666,13 +667,13 @@ uip_reass(void)
|
|||
/*---------------------------------------------------------------------------*/
|
||||
#if UIP_TCP
|
||||
static void
|
||||
uip_add_rcv_nxt(uint16_t n)
|
||||
uip_add_rcv_nxt(struct net_buf *buf, uint16_t n)
|
||||
{
|
||||
uip_add32(uip_conn->rcv_nxt, n);
|
||||
uip_conn->rcv_nxt[0] = uip_acc32[0];
|
||||
uip_conn->rcv_nxt[1] = uip_acc32[1];
|
||||
uip_conn->rcv_nxt[2] = uip_acc32[2];
|
||||
uip_conn->rcv_nxt[3] = uip_acc32[3];
|
||||
uip_add32(uip_conn(buf)->rcv_nxt, n);
|
||||
uip_conn(buf)->rcv_nxt[0] = uip_acc32[0];
|
||||
uip_conn(buf)->rcv_nxt[1] = uip_acc32[1];
|
||||
uip_conn(buf)->rcv_nxt[2] = uip_acc32[2];
|
||||
uip_conn(buf)->rcv_nxt[3] = uip_acc32[3];
|
||||
}
|
||||
#endif /* UIP_TCP */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -680,7 +681,7 @@ uint8_t
|
|||
uip_process(struct net_buf *buf, uint8_t flag)
|
||||
{
|
||||
#if UIP_TCP
|
||||
register struct uip_conn *uip_connr = uip_conn;
|
||||
register struct uip_conn *uip_connr = uip_conn(buf);
|
||||
#endif
|
||||
|
||||
#if UIP_UDP
|
||||
|
@ -689,30 +690,58 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
goto udp_send;
|
||||
}
|
||||
#endif /* UIP_UDP */
|
||||
|
||||
#if UIP_TCP
|
||||
if(flag != UIP_TCP_SEND_CONN) {
|
||||
#endif
|
||||
uip_sappdata(buf) = uip_appdata(buf) = &uip_buf(buf)[UIP_IPTCPH_LEN + UIP_LLH_LEN];
|
||||
|
||||
#if UIP_TCP
|
||||
}
|
||||
#endif
|
||||
/* Check if we were invoked because of a poll request for a
|
||||
particular connection. */
|
||||
if(flag == UIP_POLL_REQUEST) {
|
||||
#if UIP_TCP
|
||||
if(flag == UIP_POLL_REQUEST || flag == UIP_TCP_SEND_CONN) {
|
||||
if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
|
||||
!uip_outstanding(uip_connr)) {
|
||||
uip_flags = UIP_POLL;
|
||||
UIP_APPCALL();
|
||||
goto appsend;
|
||||
#if UIP_ACTIVE_OPEN && UIP_TCP
|
||||
if (flag == UIP_POLL) {
|
||||
uip_flags(buf) = UIP_POLL;
|
||||
}
|
||||
UIP_APPCALL(buf);
|
||||
goto appsend;
|
||||
#if UIP_ACTIVE_OPEN
|
||||
} else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
|
||||
/* In the SYN_SENT state, we retransmit out SYN. */
|
||||
BUF->flags = 0;
|
||||
BUF(buf)->flags = 0;
|
||||
goto tcp_send_syn;
|
||||
#endif /* UIP_ACTIVE_OPEN */
|
||||
}
|
||||
#endif /* UIP_TCP */
|
||||
if (flag == UIP_TCP_SEND_CONN) {
|
||||
switch (uip_connr->tcpstateflags & UIP_TS_MASK) {
|
||||
case UIP_CLOSED:
|
||||
case UIP_FIN_WAIT_1:
|
||||
case UIP_FIN_WAIT_2:
|
||||
case UIP_CLOSING:
|
||||
case UIP_TIME_WAIT:
|
||||
ip_buf_sent_status(buf) = -ECONNABORTED;
|
||||
goto drop;
|
||||
}
|
||||
if (uip_outstanding(uip_connr)) {
|
||||
ip_buf_sent_status(buf) = -EAGAIN;
|
||||
PRINTF("Retry to send packet len %d, outstanding data len %d\n",
|
||||
uip_len(buf), uip_outstanding(uip_connr));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
goto drop;
|
||||
}
|
||||
#else /* TCP */
|
||||
if(flag == UIP_POLL_REQUEST) {
|
||||
goto drop;
|
||||
}
|
||||
#endif /* UIP_TCP */
|
||||
|
||||
/* Check if we were invoked because of the periodic timer firing. */
|
||||
} else if(flag == UIP_TIMER) {
|
||||
if(flag == UIP_TIMER) {
|
||||
#if UIP_REASSEMBLY
|
||||
if(uip_reasstmr != 0) {
|
||||
--uip_reasstmr;
|
||||
|
@ -758,11 +787,11 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
/* We call UIP_APPCALL() with uip_flags set to
|
||||
UIP_TIMEDOUT to inform the application that the
|
||||
connection has timed out. */
|
||||
uip_flags = UIP_TIMEDOUT;
|
||||
UIP_APPCALL();
|
||||
uip_flags(buf) = UIP_TIMEDOUT;
|
||||
UIP_APPCALL(buf);
|
||||
|
||||
/* We also send a reset packet to the remote host. */
|
||||
BUF->flags = TCP_RST | TCP_ACK;
|
||||
BUF(buf)->flags = TCP_RST | TCP_ACK;
|
||||
goto tcp_send_nodata;
|
||||
}
|
||||
|
||||
|
@ -797,8 +826,8 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
to do the actual retransmit after which we jump into
|
||||
the code for sending out the packet (the apprexmit
|
||||
label). */
|
||||
uip_flags = UIP_REXMIT;
|
||||
UIP_APPCALL();
|
||||
uip_flags(buf) = UIP_REXMIT;
|
||||
UIP_APPCALL(buf);
|
||||
goto apprexmit;
|
||||
|
||||
case UIP_FIN_WAIT_1:
|
||||
|
@ -812,8 +841,8 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
} else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
|
||||
/* If there was no need for a retransmission, we poll the
|
||||
application for new data. */
|
||||
uip_flags = UIP_POLL;
|
||||
UIP_APPCALL();
|
||||
uip_flags(buf) = UIP_POLL;
|
||||
UIP_APPCALL(buf);
|
||||
goto appsend;
|
||||
}
|
||||
}
|
||||
|
@ -842,7 +871,7 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/* Check validity of the IP header. */
|
||||
if((BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */
|
||||
if((BUF(buf)->vtc & 0xf0) != 0x60) { /* IP version and header length. */
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
UIP_STAT(++uip_stat.ip.vhlerr);
|
||||
UIP_LOG("ipv6: invalid version.");
|
||||
|
@ -966,7 +995,7 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
#if UIP_TCP
|
||||
if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so,
|
||||
if(BUF(buf)->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so,
|
||||
proceed with TCP input
|
||||
processing. */
|
||||
goto tcp_input;
|
||||
|
@ -1248,7 +1277,7 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
|
||||
/* Start of TCP input header processing code. */
|
||||
|
||||
if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
|
||||
if(uip_tcpchksum(buf) != 0xffff) { /* Compute and check the TCP
|
||||
checksum. */
|
||||
UIP_STAT(++uip_stat.tcp.drop);
|
||||
UIP_STAT(++uip_stat.tcp.chkerr);
|
||||
|
@ -1257,7 +1286,7 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
}
|
||||
|
||||
/* Make sure that the TCP port number is not zero. */
|
||||
if(BUF->destport == 0 || BUF->srcport == 0) {
|
||||
if(BUF(buf)->destport == 0 || BUF(buf)->srcport == 0) {
|
||||
UIP_LOG("tcp: zero port.");
|
||||
goto drop;
|
||||
}
|
||||
|
@ -1267,9 +1296,9 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
|
||||
++uip_connr) {
|
||||
if(uip_connr->tcpstateflags != UIP_CLOSED &&
|
||||
BUF->destport == uip_connr->lport &&
|
||||
BUF->srcport == uip_connr->rport &&
|
||||
uip_ipaddr_cmp(&BUF->srcipaddr, &uip_connr->ripaddr)) {
|
||||
BUF(buf)->destport == uip_connr->lport &&
|
||||
BUF(buf)->srcport == uip_connr->rport &&
|
||||
uip_ipaddr_cmp(&BUF(buf)->srcipaddr, &uip_connr->ripaddr)) {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
@ -1278,11 +1307,11 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
either this packet is an old duplicate, or this is a SYN packet
|
||||
destined for a connection in LISTEN. If the SYN flag isn't set,
|
||||
it is an old packet and we send a RST. */
|
||||
if((BUF->flags & TCP_CTL) != TCP_SYN) {
|
||||
if((BUF(buf)->flags & TCP_CTL) != TCP_SYN) {
|
||||
goto reset;
|
||||
}
|
||||
|
||||
tmp16 = BUF->destport;
|
||||
tmp16 = BUF(buf)->destport;
|
||||
/* Next, check listening connections. */
|
||||
for(c = 0; c < UIP_LISTENPORTS; ++c) {
|
||||
if(tmp16 == uip_listenports[c]) {
|
||||
|
@ -1295,52 +1324,52 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
|
||||
reset:
|
||||
/* We do not send resets in response to resets. */
|
||||
if(BUF->flags & TCP_RST) {
|
||||
if(BUF(buf)->flags & TCP_RST) {
|
||||
goto drop;
|
||||
}
|
||||
|
||||
UIP_STAT(++uip_stat.tcp.rst);
|
||||
|
||||
BUF->flags = TCP_RST | TCP_ACK;
|
||||
uip_len = UIP_IPTCPH_LEN;
|
||||
BUF->tcpoffset = 5 << 4;
|
||||
BUF(buf)->flags = TCP_RST | TCP_ACK;
|
||||
uip_len(buf) = UIP_IPTCPH_LEN;
|
||||
BUF(buf)->tcpoffset = 5 << 4;
|
||||
|
||||
/* Flip the seqno and ackno fields in the TCP header. */
|
||||
c = BUF->seqno[3];
|
||||
BUF->seqno[3] = BUF->ackno[3];
|
||||
BUF->ackno[3] = c;
|
||||
c = BUF(buf)->seqno[3];
|
||||
BUF(buf)->seqno[3] = BUF(buf)->ackno[3];
|
||||
BUF(buf)->ackno[3] = c;
|
||||
|
||||
c = BUF->seqno[2];
|
||||
BUF->seqno[2] = BUF->ackno[2];
|
||||
BUF->ackno[2] = c;
|
||||
c = BUF(buf)->seqno[2];
|
||||
BUF(buf)->seqno[2] = BUF(buf)->ackno[2];
|
||||
BUF(buf)->ackno[2] = c;
|
||||
|
||||
c = BUF->seqno[1];
|
||||
BUF->seqno[1] = BUF->ackno[1];
|
||||
BUF->ackno[1] = c;
|
||||
c = BUF(buf)->seqno[1];
|
||||
BUF(buf)->seqno[1] = BUF(buf)->ackno[1];
|
||||
BUF(buf)->ackno[1] = c;
|
||||
|
||||
c = BUF->seqno[0];
|
||||
BUF->seqno[0] = BUF->ackno[0];
|
||||
BUF->ackno[0] = c;
|
||||
c = BUF(buf)->seqno[0];
|
||||
BUF(buf)->seqno[0] = BUF(buf)->ackno[0];
|
||||
BUF(buf)->ackno[0] = c;
|
||||
|
||||
/* We also have to increase the sequence number we are
|
||||
acknowledging. If the least significant byte overflowed, we need
|
||||
to propagate the carry to the other bytes as well. */
|
||||
if(++BUF->ackno[3] == 0) {
|
||||
if(++BUF->ackno[2] == 0) {
|
||||
if(++BUF->ackno[1] == 0) {
|
||||
++BUF->ackno[0];
|
||||
if(++BUF(buf)->ackno[3] == 0) {
|
||||
if(++BUF(buf)->ackno[2] == 0) {
|
||||
if(++BUF(buf)->ackno[1] == 0) {
|
||||
++BUF(buf)->ackno[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Swap port numbers. */
|
||||
tmp16 = BUF->srcport;
|
||||
BUF->srcport = BUF->destport;
|
||||
BUF->destport = tmp16;
|
||||
tmp16 = BUF(buf)->srcport;
|
||||
BUF(buf)->srcport = BUF(buf)->destport;
|
||||
BUF(buf)->destport = tmp16;
|
||||
|
||||
/* Swap IP addresses. */
|
||||
uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
|
||||
uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
|
||||
uip_ipaddr_copy(&BUF(buf)->destipaddr, &BUF(buf)->srcipaddr);
|
||||
uip_ipaddr_copy(&BUF(buf)->srcipaddr, &uip_hostaddr);
|
||||
|
||||
/* And send out the RST packet! */
|
||||
goto tcp_send_noconn;
|
||||
|
@ -1349,6 +1378,7 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
with a connection in LISTEN. In that case, we should create a new
|
||||
connection and send a SYNACK in return. */
|
||||
found_listen:
|
||||
PRINTF("In found listen\n");
|
||||
/* First we check if there are any connections avaliable. Unused
|
||||
connections are kept in the same table as used connections, but
|
||||
unused ones have the tcpstate set to CLOSED. Also, connections in
|
||||
|
@ -1377,16 +1407,16 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
UIP_LOG("tcp: found no unused connections.");
|
||||
goto drop;
|
||||
}
|
||||
uip_conn = uip_connr;
|
||||
uip_set_conn(buf) = uip_connr;
|
||||
|
||||
/* Fill in the necessary fields for the new connection. */
|
||||
uip_connr->rto = uip_connr->timer = UIP_RTO;
|
||||
uip_connr->sa = 0;
|
||||
uip_connr->sv = 4;
|
||||
uip_connr->nrtx = 0;
|
||||
uip_connr->lport = BUF->destport;
|
||||
uip_connr->rport = BUF->srcport;
|
||||
uip_ipaddr_copy(&uip_connr->ripaddr, &BUF->srcipaddr);
|
||||
uip_connr->lport = BUF(buf)->destport;
|
||||
uip_connr->rport = BUF(buf)->srcport;
|
||||
uip_ipaddr_copy(&uip_connr->ripaddr, &BUF(buf)->srcipaddr);
|
||||
uip_connr->tcpstateflags = UIP_SYN_RCVD;
|
||||
|
||||
uip_connr->snd_nxt[0] = iss[0];
|
||||
|
@ -1396,16 +1426,16 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
uip_connr->len = 1;
|
||||
|
||||
/* rcv_nxt should be the seqno from the incoming packet + 1. */
|
||||
uip_connr->rcv_nxt[3] = BUF->seqno[3];
|
||||
uip_connr->rcv_nxt[2] = BUF->seqno[2];
|
||||
uip_connr->rcv_nxt[1] = BUF->seqno[1];
|
||||
uip_connr->rcv_nxt[0] = BUF->seqno[0];
|
||||
uip_add_rcv_nxt(1);
|
||||
uip_connr->rcv_nxt[3] = BUF(buf)->seqno[3];
|
||||
uip_connr->rcv_nxt[2] = BUF(buf)->seqno[2];
|
||||
uip_connr->rcv_nxt[1] = BUF(buf)->seqno[1];
|
||||
uip_connr->rcv_nxt[0] = BUF(buf)->seqno[0];
|
||||
uip_add_rcv_nxt(buf, 1);
|
||||
|
||||
/* Parse the TCP MSS option, if present. */
|
||||
if((BUF->tcpoffset & 0xf0) > 0x50) {
|
||||
for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
|
||||
opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
|
||||
if((BUF(buf)->tcpoffset & 0xf0) > 0x50) {
|
||||
for(c = 0; c < ((BUF(buf)->tcpoffset >> 4) - 5) << 2 ;) {
|
||||
opt = uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
|
||||
if(opt == TCP_OPT_END) {
|
||||
/* End of options. */
|
||||
break;
|
||||
|
@ -1413,10 +1443,10 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
++c;
|
||||
/* NOP option. */
|
||||
} else if(opt == TCP_OPT_MSS &&
|
||||
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
|
||||
uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
|
||||
/* An MSS option with the right option length. */
|
||||
tmp16 = ((uint16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
|
||||
(uint16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
|
||||
tmp16 = ((uint16_t)uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
|
||||
(uint16_t)uip_buf(buf)[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
|
||||
uip_connr->initialmss = uip_connr->mss =
|
||||
tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
|
||||
|
||||
|
@ -1425,12 +1455,12 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
} else {
|
||||
/* All other options have a length field, so that we easily
|
||||
can skip past them. */
|
||||
if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
|
||||
if(uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
|
||||
/* If the length field is zero, the options are malformed
|
||||
and we don't process them further. */
|
||||
break;
|
||||
}
|
||||
c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
|
||||
c += uip_buf(buf)[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1444,41 +1474,50 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
BUF->flags |= TCP_SYN;
|
||||
#else /* UIP_ACTIVE_OPEN */
|
||||
tcp_send_synack:
|
||||
BUF->flags = TCP_SYN | TCP_ACK;
|
||||
BUF(buf)->flags = TCP_SYN | TCP_ACK;
|
||||
#endif /* UIP_ACTIVE_OPEN */
|
||||
|
||||
/* We send out the TCP Maximum Segment Size option with our
|
||||
SYNACK. */
|
||||
BUF->optdata[0] = TCP_OPT_MSS;
|
||||
BUF->optdata[1] = TCP_OPT_MSS_LEN;
|
||||
BUF->optdata[2] = (UIP_TCP_MSS) / 256;
|
||||
BUF->optdata[3] = (UIP_TCP_MSS) & 255;
|
||||
uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
|
||||
BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
|
||||
BUF(buf)->optdata[0] = TCP_OPT_MSS;
|
||||
BUF(buf)->optdata[1] = TCP_OPT_MSS_LEN;
|
||||
BUF(buf)->optdata[2] = (UIP_TCP_MSS) / 256;
|
||||
BUF(buf)->optdata[3] = (UIP_TCP_MSS) & 255;
|
||||
uip_len(buf) = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
|
||||
BUF(buf)->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
|
||||
goto tcp_send;
|
||||
|
||||
/* This label will be jumped to if we found an active connection. */
|
||||
found:
|
||||
uip_conn = uip_connr;
|
||||
uip_flags = 0;
|
||||
PRINTF("In found\n");
|
||||
uip_set_conn(buf) = uip_connr;
|
||||
uip_flags(buf) = 0;
|
||||
/* We do a very naive form of TCP reset processing; we just accept
|
||||
any RST and kill our connection. We should in fact check if the
|
||||
sequence number of this reset is within our advertised window
|
||||
before we accept the reset. */
|
||||
if(BUF->flags & TCP_RST) {
|
||||
if(BUF(buf)->flags & TCP_RST) {
|
||||
uip_connr->tcpstateflags = UIP_CLOSED;
|
||||
UIP_LOG("tcp: got reset, aborting connection.");
|
||||
uip_flags = UIP_ABORT;
|
||||
UIP_APPCALL();
|
||||
uip_flags(buf) = UIP_ABORT;
|
||||
UIP_APPCALL(buf);
|
||||
goto drop;
|
||||
}
|
||||
/* Calculate the length of the data, if the application has sent
|
||||
any data to us. */
|
||||
c = (BUF->tcpoffset >> 4) << 2;
|
||||
/* uip_len will contain the length of the actual TCP data. This is
|
||||
calculated by subtracing the length of the TCP header (in
|
||||
c) and the length of the IP header (20 bytes). */
|
||||
uip_len = uip_len - c - UIP_IPH_LEN;
|
||||
|
||||
if (flag != UIP_TCP_SEND_CONN) {
|
||||
/* If flag is set to UIP_TCP_SEND_CONN, then it means that we are
|
||||
* trying to send the actual packet coming from user. In this case
|
||||
* do not mess with the packet length.
|
||||
*/
|
||||
|
||||
/* Calculate the length of the data, if the application has sent
|
||||
any data to us. */
|
||||
c = (BUF(buf)->tcpoffset >> 4) << 2;
|
||||
/* uip_len will contain the length of the actual TCP data. This is
|
||||
calculated by subtracing the length of the TCP header (in
|
||||
c) and the length of the IP header (20 bytes). */
|
||||
uip_len(buf) = uip_len(buf) - c - UIP_IPH_LEN;
|
||||
}
|
||||
|
||||
/* First, check if the sequence number of the incoming packet is
|
||||
what we're expecting next. If not, we send out an ACK with the
|
||||
|
@ -1486,14 +1525,14 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
receive a SYN, in which case we should retransmit our SYNACK
|
||||
(which is done futher down). */
|
||||
if(!((((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
|
||||
((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
|
||||
((BUF(buf)->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
|
||||
(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
|
||||
((BUF->flags & TCP_CTL) == TCP_SYN)))) {
|
||||
if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
|
||||
(BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
|
||||
BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
|
||||
BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
|
||||
BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
|
||||
((BUF(buf)->flags & TCP_CTL) == TCP_SYN)))) {
|
||||
if((uip_len(buf) > 0 || ((BUF(buf)->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
|
||||
(BUF(buf)->seqno[0] != uip_connr->rcv_nxt[0] ||
|
||||
BUF(buf)->seqno[1] != uip_connr->rcv_nxt[1] ||
|
||||
BUF(buf)->seqno[2] != uip_connr->rcv_nxt[2] ||
|
||||
BUF(buf)->seqno[3] != uip_connr->rcv_nxt[3])) {
|
||||
goto tcp_send_ack;
|
||||
}
|
||||
}
|
||||
|
@ -1502,13 +1541,13 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
data. If so, we update the sequence number, reset the length of
|
||||
the outstanding data, calculate RTT estimations, and reset the
|
||||
retransmission timer. */
|
||||
if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
|
||||
if((BUF(buf)->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
|
||||
uip_add32(uip_connr->snd_nxt, uip_connr->len);
|
||||
|
||||
if(BUF->ackno[0] == uip_acc32[0] &&
|
||||
BUF->ackno[1] == uip_acc32[1] &&
|
||||
BUF->ackno[2] == uip_acc32[2] &&
|
||||
BUF->ackno[3] == uip_acc32[3]) {
|
||||
if(BUF(buf)->ackno[0] == uip_acc32[0] &&
|
||||
BUF(buf)->ackno[1] == uip_acc32[1] &&
|
||||
BUF(buf)->ackno[2] == uip_acc32[2] &&
|
||||
BUF(buf)->ackno[3] == uip_acc32[3]) {
|
||||
/* Update sequence number. */
|
||||
uip_connr->snd_nxt[0] = uip_acc32[0];
|
||||
uip_connr->snd_nxt[1] = uip_acc32[1];
|
||||
|
@ -1531,7 +1570,7 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
|
||||
}
|
||||
/* Set the acknowledged flag. */
|
||||
uip_flags = UIP_ACKDATA;
|
||||
uip_flags(buf) = UIP_ACKDATA;
|
||||
/* Reset the retransmission timer. */
|
||||
uip_connr->timer = uip_connr->rto;
|
||||
|
||||
|
@ -1552,20 +1591,20 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
we are waiting for an ACK that acknowledges the data we sent
|
||||
out the last time. Therefore, we want to have the UIP_ACKDATA
|
||||
flag set. If so, we enter the ESTABLISHED state. */
|
||||
if(uip_flags & UIP_ACKDATA) {
|
||||
if(uip_flags(buf) & UIP_ACKDATA) {
|
||||
uip_connr->tcpstateflags = UIP_ESTABLISHED;
|
||||
uip_flags = UIP_CONNECTED;
|
||||
uip_flags(buf) = UIP_CONNECTED;
|
||||
uip_connr->len = 0;
|
||||
if(uip_len > 0) {
|
||||
uip_flags |= UIP_NEWDATA;
|
||||
uip_add_rcv_nxt(uip_len);
|
||||
if(uip_len(buf) > 0) {
|
||||
uip_flags(buf) |= UIP_NEWDATA;
|
||||
uip_add_rcv_nxt(buf, uip_len(buf));
|
||||
}
|
||||
uip_slen = 0;
|
||||
UIP_APPCALL();
|
||||
uip_slen(buf) = 0;
|
||||
UIP_APPCALL(buf);
|
||||
goto appsend;
|
||||
}
|
||||
/* We need to retransmit the SYNACK */
|
||||
if((BUF->flags & TCP_CTL) == TCP_SYN) {
|
||||
if((BUF(buf)->flags & TCP_CTL) == TCP_SYN) {
|
||||
goto tcp_send_synack;
|
||||
}
|
||||
goto drop;
|
||||
|
@ -1618,7 +1657,7 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
uip_add_rcv_nxt(1);
|
||||
uip_flags = UIP_CONNECTED | UIP_NEWDATA;
|
||||
uip_connr->len = 0;
|
||||
uip_len = 0;
|
||||
uip_len(buf) = 0;
|
||||
uip_slen = 0;
|
||||
UIP_APPCALL();
|
||||
goto appsend;
|
||||
|
@ -1643,27 +1682,27 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
state. We require that there is no outstanding data; otherwise the
|
||||
sequence numbers will be screwed up. */
|
||||
|
||||
if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
|
||||
if(BUF(buf)->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
|
||||
if(uip_outstanding(uip_connr)) {
|
||||
goto drop;
|
||||
}
|
||||
uip_add_rcv_nxt(1 + uip_len);
|
||||
uip_flags |= UIP_CLOSE;
|
||||
if(uip_len > 0) {
|
||||
uip_flags |= UIP_NEWDATA;
|
||||
uip_add_rcv_nxt(buf, 1 + uip_len(buf));
|
||||
uip_flags(buf) |= UIP_CLOSE;
|
||||
if(uip_len(buf) > 0) {
|
||||
uip_flags(buf) |= UIP_NEWDATA;
|
||||
}
|
||||
UIP_APPCALL();
|
||||
UIP_APPCALL(buf);
|
||||
uip_connr->len = 1;
|
||||
uip_connr->tcpstateflags = UIP_LAST_ACK;
|
||||
uip_connr->nrtx = 0;
|
||||
tcp_send_finack:
|
||||
BUF->flags = TCP_FIN | TCP_ACK;
|
||||
BUF(buf)->flags = TCP_FIN | TCP_ACK;
|
||||
goto tcp_send_nodata;
|
||||
}
|
||||
|
||||
/* Check the URG flag. If this is set, the segment carries urgent
|
||||
data that we must pass to the application. */
|
||||
if((BUF->flags & TCP_URG) != 0) {
|
||||
if((BUF(buf)->flags & TCP_URG) != 0) {
|
||||
#if UIP_URGDATA > 0
|
||||
uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
|
||||
if(uip_urglen > uip_len) {
|
||||
|
@ -1677,8 +1716,8 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
} else {
|
||||
uip_urglen = 0;
|
||||
#else /* UIP_URGDATA > 0 */
|
||||
uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
|
||||
uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
|
||||
uip_appdata(buf) = ((char *)uip_appdata(buf)) + ((BUF(buf)->urgp[0] << 8) | BUF(buf)->urgp[1]);
|
||||
uip_len(buf) -= (BUF(buf)->urgp[0] << 8) | BUF(buf)->urgp[1];
|
||||
#endif /* UIP_URGDATA > 0 */
|
||||
}
|
||||
|
||||
|
@ -1687,9 +1726,9 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
we acknowledge. If the application has stopped the dataflow
|
||||
using uip_stop(), we must not accept any data packets from the
|
||||
remote host. */
|
||||
if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
|
||||
uip_flags |= UIP_NEWDATA;
|
||||
uip_add_rcv_nxt(uip_len);
|
||||
if(uip_len(buf) > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
|
||||
uip_flags(buf) |= UIP_NEWDATA;
|
||||
uip_add_rcv_nxt(buf, uip_len(buf));
|
||||
}
|
||||
|
||||
/* Check if the available buffer space advertised by the other end
|
||||
|
@ -1704,7 +1743,7 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
and the application will retransmit it. This is called the
|
||||
"persistent timer" and uses the retransmission mechanim.
|
||||
*/
|
||||
tmp16 = ((uint16_t)BUF->wnd[0] << 8) + (uint16_t)BUF->wnd[1];
|
||||
tmp16 = ((uint16_t)BUF(buf)->wnd[0] << 8) + (uint16_t)BUF(buf)->wnd[1];
|
||||
if(tmp16 > uip_connr->initialmss ||
|
||||
tmp16 == 0) {
|
||||
tmp16 = uip_connr->initialmss;
|
||||
|
@ -1727,34 +1766,39 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
put into the uip_appdata and the length of the data should be
|
||||
put into uip_len. If the application don't have any data to
|
||||
send, uip_len must be set to 0. */
|
||||
if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
|
||||
uip_slen = 0;
|
||||
UIP_APPCALL();
|
||||
if(uip_flags(buf) & (UIP_NEWDATA | UIP_ACKDATA)) {
|
||||
if(flag != UIP_TCP_SEND_CONN) {
|
||||
/* Do not reset the slen because we are being called
|
||||
* directly by the application.
|
||||
*/
|
||||
uip_slen(buf) = 0;
|
||||
}
|
||||
UIP_APPCALL(buf);
|
||||
|
||||
appsend:
|
||||
|
||||
if(uip_flags & UIP_ABORT) {
|
||||
uip_slen = 0;
|
||||
if(uip_flags(buf) & UIP_ABORT) {
|
||||
uip_slen(buf) = 0;
|
||||
uip_connr->tcpstateflags = UIP_CLOSED;
|
||||
BUF->flags = TCP_RST | TCP_ACK;
|
||||
BUF(buf)->flags = TCP_RST | TCP_ACK;
|
||||
goto tcp_send_nodata;
|
||||
}
|
||||
|
||||
if(uip_flags & UIP_CLOSE) {
|
||||
uip_slen = 0;
|
||||
if(uip_flags(buf) & UIP_CLOSE) {
|
||||
uip_slen(buf) = 0;
|
||||
uip_connr->len = 1;
|
||||
uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
|
||||
uip_connr->nrtx = 0;
|
||||
BUF->flags = TCP_FIN | TCP_ACK;
|
||||
BUF(buf)->flags = TCP_FIN | TCP_ACK;
|
||||
goto tcp_send_nodata;
|
||||
}
|
||||
|
||||
/* If uip_slen > 0, the application has data to be sent. */
|
||||
if(uip_slen > 0) {
|
||||
if(uip_slen(buf) > 0) {
|
||||
|
||||
/* If the connection has acknowledged data, the contents of
|
||||
the ->len variable should be discarded. */
|
||||
if((uip_flags & UIP_ACKDATA) != 0) {
|
||||
if((uip_flags(buf) & UIP_ACKDATA) != 0) {
|
||||
uip_connr->len = 0;
|
||||
}
|
||||
|
||||
|
@ -1766,40 +1810,40 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
/* The application cannot send more than what is allowed by
|
||||
the mss (the minumum of the MSS and the available
|
||||
window). */
|
||||
if(uip_slen > uip_connr->mss) {
|
||||
uip_slen = uip_connr->mss;
|
||||
if(uip_slen(buf) > uip_connr->mss) {
|
||||
uip_slen(buf) = uip_connr->mss;
|
||||
}
|
||||
|
||||
/* Remember how much data we send out now so that we know
|
||||
when everything has been acknowledged. */
|
||||
uip_connr->len = uip_slen;
|
||||
uip_connr->len = uip_slen(buf);
|
||||
} else {
|
||||
|
||||
/* If the application already had unacknowledged data, we
|
||||
make sure that the application does not send (i.e.,
|
||||
retransmit) out more than it previously sent out. */
|
||||
uip_slen = uip_connr->len;
|
||||
uip_slen(buf) = uip_connr->len;
|
||||
}
|
||||
}
|
||||
uip_connr->nrtx = 0;
|
||||
apprexmit:
|
||||
uip_appdata = uip_sappdata;
|
||||
uip_appdata(buf) = uip_sappdata(buf);
|
||||
|
||||
/* If the application has data to be sent, or if the incoming
|
||||
packet had new data in it, we must send out a packet. */
|
||||
if(uip_slen > 0 && uip_connr->len > 0) {
|
||||
if(uip_slen(buf) > 0 && uip_connr->len > 0) {
|
||||
/* Add the length of the IP and TCP headers. */
|
||||
uip_len = uip_connr->len + UIP_TCPIP_HLEN;
|
||||
uip_len(buf) = uip_connr->len + UIP_TCPIP_HLEN;
|
||||
/* We always set the ACK flag in response packets. */
|
||||
BUF->flags = TCP_ACK | TCP_PSH;
|
||||
BUF(buf)->flags = TCP_ACK | TCP_PSH;
|
||||
/* Send the packet. */
|
||||
goto tcp_send_noopts;
|
||||
}
|
||||
/* If there is no data to send, just send out a pure ACK if
|
||||
there is newdata. */
|
||||
if(uip_flags & UIP_NEWDATA) {
|
||||
uip_len = UIP_TCPIP_HLEN;
|
||||
BUF->flags = TCP_ACK;
|
||||
if(uip_flags(buf) & UIP_NEWDATA) {
|
||||
uip_len(buf) = UIP_TCPIP_HLEN;
|
||||
BUF(buf)->flags = TCP_ACK;
|
||||
goto tcp_send_noopts;
|
||||
}
|
||||
}
|
||||
|
@ -1807,10 +1851,10 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
case UIP_LAST_ACK:
|
||||
/* We can close this connection if the peer has acknowledged our
|
||||
FIN. This is indicated by the UIP_ACKDATA flag. */
|
||||
if(uip_flags & UIP_ACKDATA) {
|
||||
if(uip_flags(buf) & UIP_ACKDATA) {
|
||||
uip_connr->tcpstateflags = UIP_CLOSED;
|
||||
uip_flags = UIP_CLOSE;
|
||||
UIP_APPCALL();
|
||||
uip_flags(buf) = UIP_CLOSE;
|
||||
UIP_APPCALL(buf);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1818,44 +1862,44 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
/* The application has closed the connection, but the remote host
|
||||
hasn't closed its end yet. Thus we do nothing but wait for a
|
||||
FIN from the other side. */
|
||||
if(uip_len > 0) {
|
||||
uip_add_rcv_nxt(uip_len);
|
||||
if(uip_len(buf) > 0) {
|
||||
uip_add_rcv_nxt(buf, uip_len(buf));
|
||||
}
|
||||
if(BUF->flags & TCP_FIN) {
|
||||
if(uip_flags & UIP_ACKDATA) {
|
||||
if(BUF(buf)->flags & TCP_FIN) {
|
||||
if(uip_flags(buf) & UIP_ACKDATA) {
|
||||
uip_connr->tcpstateflags = UIP_TIME_WAIT;
|
||||
uip_connr->timer = 0;
|
||||
uip_connr->len = 0;
|
||||
} else {
|
||||
uip_connr->tcpstateflags = UIP_CLOSING;
|
||||
}
|
||||
uip_add_rcv_nxt(1);
|
||||
uip_flags = UIP_CLOSE;
|
||||
UIP_APPCALL();
|
||||
uip_add_rcv_nxt(buf, 1);
|
||||
uip_flags(buf) = UIP_CLOSE;
|
||||
UIP_APPCALL(buf);
|
||||
goto tcp_send_ack;
|
||||
} else if(uip_flags & UIP_ACKDATA) {
|
||||
} else if(uip_flags(buf) & UIP_ACKDATA) {
|
||||
uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
|
||||
uip_connr->len = 0;
|
||||
goto drop;
|
||||
}
|
||||
if(uip_len > 0) {
|
||||
if(uip_len(buf) > 0) {
|
||||
goto tcp_send_ack;
|
||||
}
|
||||
goto drop;
|
||||
|
||||
case UIP_FIN_WAIT_2:
|
||||
if(uip_len > 0) {
|
||||
uip_add_rcv_nxt(uip_len);
|
||||
if(uip_len(buf) > 0) {
|
||||
uip_add_rcv_nxt(buf, uip_len(buf));
|
||||
}
|
||||
if(BUF->flags & TCP_FIN) {
|
||||
if(BUF(buf)->flags & TCP_FIN) {
|
||||
uip_connr->tcpstateflags = UIP_TIME_WAIT;
|
||||
uip_connr->timer = 0;
|
||||
uip_add_rcv_nxt(1);
|
||||
uip_flags = UIP_CLOSE;
|
||||
UIP_APPCALL();
|
||||
uip_add_rcv_nxt(buf, 1);
|
||||
uip_flags(buf) = UIP_CLOSE;
|
||||
UIP_APPCALL(buf);
|
||||
goto tcp_send_ack;
|
||||
}
|
||||
if(uip_len > 0) {
|
||||
if(uip_len(buf) > 0) {
|
||||
goto tcp_send_ack;
|
||||
}
|
||||
goto drop;
|
||||
|
@ -1864,7 +1908,7 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
goto tcp_send_ack;
|
||||
|
||||
case UIP_CLOSING:
|
||||
if(uip_flags & UIP_ACKDATA) {
|
||||
if(uip_flags(buf) & UIP_ACKDATA) {
|
||||
uip_connr->tcpstateflags = UIP_TIME_WAIT;
|
||||
uip_connr->timer = 0;
|
||||
}
|
||||
|
@ -1874,63 +1918,74 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
/* We jump here when we are ready to send the packet, and just want
|
||||
to set the appropriate TCP sequence numbers in the TCP header. */
|
||||
tcp_send_ack:
|
||||
BUF->flags = TCP_ACK;
|
||||
PRINTF("In tcp_send_ack\n");
|
||||
BUF(buf)->flags = TCP_ACK;
|
||||
|
||||
tcp_send_nodata:
|
||||
uip_len = UIP_IPTCPH_LEN;
|
||||
if (flag != UIP_TCP_SEND_CONN) {
|
||||
PRINTF("In tcp_send_nodata\n");
|
||||
uip_len(buf) = UIP_IPTCPH_LEN;
|
||||
}
|
||||
|
||||
tcp_send_noopts:
|
||||
BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
|
||||
BUF(buf)->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
|
||||
|
||||
/* We're done with the input processing. We are now ready to send a
|
||||
reply. Our job is to fill in all the fields of the TCP and IP
|
||||
headers before calculating the checksum and finally send the
|
||||
packet. */
|
||||
tcp_send:
|
||||
BUF->ackno[0] = uip_connr->rcv_nxt[0];
|
||||
BUF->ackno[1] = uip_connr->rcv_nxt[1];
|
||||
BUF->ackno[2] = uip_connr->rcv_nxt[2];
|
||||
BUF->ackno[3] = uip_connr->rcv_nxt[3];
|
||||
PRINTF("In tcp_send\n");
|
||||
|
||||
BUF->seqno[0] = uip_connr->snd_nxt[0];
|
||||
BUF->seqno[1] = uip_connr->snd_nxt[1];
|
||||
BUF->seqno[2] = uip_connr->snd_nxt[2];
|
||||
BUF->seqno[3] = uip_connr->snd_nxt[3];
|
||||
BUF(buf)->ackno[0] = uip_connr->rcv_nxt[0];
|
||||
BUF(buf)->ackno[1] = uip_connr->rcv_nxt[1];
|
||||
BUF(buf)->ackno[2] = uip_connr->rcv_nxt[2];
|
||||
BUF(buf)->ackno[3] = uip_connr->rcv_nxt[3];
|
||||
|
||||
BUF->srcport = uip_connr->lport;
|
||||
BUF->destport = uip_connr->rport;
|
||||
BUF(buf)->seqno[0] = uip_connr->snd_nxt[0];
|
||||
BUF(buf)->seqno[1] = uip_connr->snd_nxt[1];
|
||||
BUF(buf)->seqno[2] = uip_connr->snd_nxt[2];
|
||||
BUF(buf)->seqno[3] = uip_connr->snd_nxt[3];
|
||||
|
||||
uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
|
||||
uip_ipaddr_copy(&BUF->destipaddr, &uip_connr->ripaddr);
|
||||
BUF(buf)->srcport = uip_connr->lport;
|
||||
BUF(buf)->destport = uip_connr->rport;
|
||||
|
||||
uip_ipaddr_copy(&BUF(buf)->srcipaddr, &uip_hostaddr);
|
||||
uip_ipaddr_copy(&BUF(buf)->destipaddr, &uip_connr->ripaddr);
|
||||
PRINTF("Sending TCP packet to ");
|
||||
PRINT6ADDR(&BUF(buf)->destipaddr);
|
||||
PRINTF(" from ");
|
||||
PRINT6ADDR(&BUF(buf)->srcipaddr);
|
||||
PRINTF("\n");
|
||||
|
||||
if(uip_connr->tcpstateflags & UIP_STOPPED) {
|
||||
/* If the connection has issued uip_stop(), we advertise a zero
|
||||
window so that the remote host will stop sending data. */
|
||||
BUF->wnd[0] = BUF->wnd[1] = 0;
|
||||
BUF(buf)->wnd[0] = BUF(buf)->wnd[1] = 0;
|
||||
} else {
|
||||
BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
|
||||
BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
|
||||
BUF(buf)->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
|
||||
BUF(buf)->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
|
||||
}
|
||||
|
||||
tcp_send_noconn:
|
||||
BUF->proto = UIP_PROTO_TCP;
|
||||
BUF(buf)->proto = UIP_PROTO_TCP;
|
||||
|
||||
BUF->ttl = UIP_TTL;
|
||||
BUF(buf)->ttl = UIP_TTL;
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/* For IPv6, the IP length field does not include the IPv6 IP header
|
||||
length. */
|
||||
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
BUF->len[0] = (uip_len >> 8);
|
||||
BUF->len[1] = (uip_len & 0xff);
|
||||
BUF(buf)->len[0] = (uip_len(buf) >> 8);
|
||||
BUF(buf)->len[1] = (uip_len(buf) & 0xff);
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
BUF->urgp[0] = BUF->urgp[1] = 0;
|
||||
BUF(buf)->urgp[0] = BUF(buf)->urgp[1] = 0;
|
||||
|
||||
/* Calculate TCP checksum. */
|
||||
BUF->tcpchksum = 0;
|
||||
BUF->tcpchksum = ~(uip_tcpchksum());
|
||||
BUF(buf)->tcpchksum = 0;
|
||||
BUF(buf)->tcpchksum = ~(uip_tcpchksum(buf));
|
||||
#endif
|
||||
|
||||
ip_send_nolen:
|
||||
|
@ -1980,19 +2035,42 @@ uip_htonl(uint32_t val)
|
|||
return UIP_HTONL(val);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if UIP_TCP
|
||||
void
|
||||
uip_send(struct net_buf *buf, const void *data, int len)
|
||||
{
|
||||
int copylen;
|
||||
#define MIN(a,b) ((a) < (b)? (a): (b))
|
||||
copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN -
|
||||
(int)((char *)uip_sappdata(buf) - (char *)&uip_buf(buf)[UIP_LLH_LEN + UIP_TCPIP_HLEN]));
|
||||
uip_sappdata(buf) = ip_buf_appdata(buf);
|
||||
|
||||
if(uip_sappdata(buf) != NULL) {
|
||||
copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN -
|
||||
(int)((char *)uip_sappdata(buf) -
|
||||
(char *)&uip_buf(buf)[UIP_LLH_LEN + UIP_TCPIP_HLEN]));
|
||||
} else {
|
||||
copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN);
|
||||
}
|
||||
if(copylen > 0) {
|
||||
uip_slen(buf) = copylen;
|
||||
if(data != uip_sappdata(buf)) {
|
||||
memcpy(uip_sappdata(buf), (data), uip_slen(buf));
|
||||
if(uip_sappdata(buf) == NULL) {
|
||||
memmove((char *)&uip_buf(buf)[UIP_LLH_LEN + UIP_TCPIP_HLEN],
|
||||
(data), uip_slen(buf));
|
||||
} else {
|
||||
memmove(uip_sappdata(buf), (data), uip_slen(buf));
|
||||
}
|
||||
}
|
||||
if (uip_process(buf, UIP_TCP_SEND_CONN)) {
|
||||
int ret = tcpip_output(buf, NULL);
|
||||
if (!ret) {
|
||||
PRINTF("Packet %p sending failed.\n", buf);
|
||||
ip_buf_unref(buf);
|
||||
} else {
|
||||
ip_buf_sent_status(buf) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @}*/
|
||||
|
|
|
@ -72,6 +72,8 @@
|
|||
*/
|
||||
|
||||
#include <net/ip_buf.h>
|
||||
#include <net/net_ip.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "contiki/ip/uip.h"
|
||||
#include "contiki/ip/uipopt.h"
|
||||
|
@ -454,6 +456,16 @@ uip_init(void)
|
|||
}
|
||||
for(c = 0; c < UIP_CONNS; ++c) {
|
||||
uip_conns[c].tcpstateflags = UIP_CLOSED;
|
||||
uip_conns[c].len = 0;
|
||||
}
|
||||
|
||||
{
|
||||
/* Randomise initial seq number */
|
||||
uint32_t c = clock_get_cycle();
|
||||
iss[0] = c & 0xff;
|
||||
iss[1] = (c & 0xff00) >> 8;
|
||||
iss[2] = (c & 0xff0000) >> 16;
|
||||
iss[3] = (c & 0xff000000) >> 24;
|
||||
}
|
||||
#endif /* UIP_TCP */
|
||||
|
||||
|
@ -973,15 +985,22 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
goto udp_send;
|
||||
}
|
||||
#endif /* UIP_UDP */
|
||||
uip_sappdata(buf) = uip_appdata(buf) = &uip_buf(buf)[UIP_IPTCPH_LEN + UIP_LLH_LEN];
|
||||
|
||||
#if UIP_TCP
|
||||
if(flag != UIP_TCP_SEND_CONN) {
|
||||
#endif
|
||||
uip_sappdata(buf) = uip_appdata(buf) = &uip_buf(buf)[UIP_IPTCPH_LEN + UIP_LLH_LEN];
|
||||
#if UIP_TCP
|
||||
}
|
||||
#endif
|
||||
/* Check if we were invoked because of a poll request for a
|
||||
particular connection. */
|
||||
if(flag == UIP_POLL_REQUEST) {
|
||||
#if UIP_TCP
|
||||
if(flag == UIP_POLL_REQUEST || flag == UIP_TCP_SEND_CONN) {
|
||||
if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
|
||||
!uip_outstanding(uip_connr)) {
|
||||
uip_flags(buf) = UIP_POLL;
|
||||
if (flag == UIP_POLL) {
|
||||
uip_flags(buf) = UIP_POLL;
|
||||
}
|
||||
UIP_APPCALL(buf);
|
||||
goto appsend;
|
||||
#if UIP_ACTIVE_OPEN
|
||||
|
@ -991,10 +1010,32 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
goto tcp_send_syn;
|
||||
#endif /* UIP_ACTIVE_OPEN */
|
||||
}
|
||||
if (flag == UIP_TCP_SEND_CONN) {
|
||||
switch (uip_connr->tcpstateflags & UIP_TS_MASK) {
|
||||
case UIP_CLOSED:
|
||||
case UIP_FIN_WAIT_1:
|
||||
case UIP_FIN_WAIT_2:
|
||||
case UIP_CLOSING:
|
||||
case UIP_TIME_WAIT:
|
||||
ip_buf_sent_status(buf) = -ECONNABORTED;
|
||||
goto drop;
|
||||
}
|
||||
if (uip_outstanding(uip_connr)) {
|
||||
ip_buf_sent_status(buf) = -EAGAIN;
|
||||
PRINTF("Retry to send packet len %d, outstanding data len %d\n",
|
||||
uip_len(buf), uip_outstanding(uip_connr));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
goto drop;
|
||||
}
|
||||
#else /* TCP */
|
||||
if(flag == UIP_POLL_REQUEST) {
|
||||
goto drop;
|
||||
}
|
||||
#endif /* UIP_TCP */
|
||||
/* Check if we were invoked because of the perodic timer fireing. */
|
||||
} else if(flag == UIP_TIMER) {
|
||||
if(flag == UIP_TIMER) {
|
||||
/* Reset the length variables. */
|
||||
#if UIP_TCP
|
||||
uip_len(buf) = 0;
|
||||
|
@ -1843,8 +1884,8 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
#if UIP_ACTIVE_OPEN
|
||||
tcp_send_synack:
|
||||
UIP_TCP_BUF(buf)->flags = TCP_ACK;
|
||||
|
||||
tcp_send_syn:
|
||||
|
||||
tcp_send_syn:
|
||||
UIP_TCP_BUF(buf)->flags |= TCP_SYN;
|
||||
#else /* UIP_ACTIVE_OPEN */
|
||||
tcp_send_synack:
|
||||
|
@ -1877,13 +1918,21 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
UIP_APPCALL(buf);
|
||||
goto drop;
|
||||
}
|
||||
/* Calculate the length of the data, if the application has sent
|
||||
any data to us. */
|
||||
c = (UIP_TCP_BUF(buf)->tcpoffset >> 4) << 2;
|
||||
/* uip_len will contain the length of the actual TCP data. This is
|
||||
calculated by subtracing the length of the TCP header (in
|
||||
c) and the length of the IP header (20 bytes). */
|
||||
uip_len(buf) = uip_len(buf) - c - UIP_IPH_LEN;
|
||||
|
||||
if (flag != UIP_TCP_SEND_CONN) {
|
||||
/* If flag is set to UIP_TCP_SEND_CONN, then it means that we are
|
||||
* trying to send the actual packet coming from user. In this case
|
||||
* do not mess with the packet length.
|
||||
*/
|
||||
|
||||
/* Calculate the length of the data, if the application has sent
|
||||
any data to us. */
|
||||
c = (UIP_TCP_BUF(buf)->tcpoffset >> 4) << 2;
|
||||
/* uip_len will contain the length of the actual TCP data. This is
|
||||
calculated by subtracing the length of the TCP header (in
|
||||
c) and the length of the IP header (20 bytes). */
|
||||
uip_len(buf) = uip_len(buf) - c - UIP_IPH_LEN;
|
||||
}
|
||||
|
||||
/* First, check if the sequence number of the incoming packet is
|
||||
what we're expecting next. If not, we send out an ACK with the
|
||||
|
@ -1903,8 +1952,10 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
if((UIP_TCP_BUF(buf)->flags & TCP_SYN)) {
|
||||
if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) {
|
||||
goto tcp_send_synack;
|
||||
#if UIP_ACTIVE_OPEN
|
||||
} else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
|
||||
goto tcp_send_syn;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
goto tcp_send_ack;
|
||||
|
@ -2141,11 +2192,16 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
put into uip_len. If the application don't have any data to
|
||||
send, uip_len must be set to 0. */
|
||||
if(uip_flags(buf) & (UIP_NEWDATA | UIP_ACKDATA)) {
|
||||
uip_slen(buf) = 0;
|
||||
if(flag != UIP_TCP_SEND_CONN) {
|
||||
/* Do not reset the slen because we are being called
|
||||
* directly by the application.
|
||||
*/
|
||||
uip_slen(buf) = 0;
|
||||
}
|
||||
UIP_APPCALL(buf);
|
||||
|
||||
appsend:
|
||||
|
||||
|
||||
if(uip_flags(buf) & UIP_ABORT) {
|
||||
uip_slen(buf) = 0;
|
||||
uip_connr->tcpstateflags = UIP_CLOSED;
|
||||
|
@ -2287,10 +2343,14 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
/* We jump here when we are ready to send the packet, and just want
|
||||
to set the appropriate TCP sequence numbers in the TCP header. */
|
||||
tcp_send_ack:
|
||||
PRINTF("In tcp_send_ack\n");
|
||||
UIP_TCP_BUF(buf)->flags = TCP_ACK;
|
||||
|
||||
tcp_send_nodata:
|
||||
uip_len(buf) = UIP_IPTCPH_LEN;
|
||||
if (flag != UIP_TCP_SEND_CONN) {
|
||||
PRINTF("In tcp_send_nodata\n");
|
||||
uip_len(buf) = UIP_IPTCPH_LEN;
|
||||
}
|
||||
|
||||
tcp_send_noopts:
|
||||
UIP_TCP_BUF(buf)->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
|
||||
|
@ -2318,9 +2378,9 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
uip_ipaddr_copy(&UIP_IP_BUF(buf)->destipaddr, &uip_connr->ripaddr);
|
||||
uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &UIP_IP_BUF(buf)->destipaddr);
|
||||
PRINTF("Sending TCP packet to ");
|
||||
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr);
|
||||
PRINTF(" from ");
|
||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||
PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr);
|
||||
PRINTF("\n");
|
||||
|
||||
if(uip_connr->tcpstateflags & UIP_STOPPED) {
|
||||
|
@ -2360,6 +2420,7 @@ uip_process(struct net_buf *buf, uint8_t flag)
|
|||
UIP_STAT(++uip_stat.ip.sent);
|
||||
/* Return and let the caller do the actual transmission. */
|
||||
uip_flags(buf) = 0;
|
||||
buf->len = uip_len(buf);
|
||||
return 1;
|
||||
|
||||
drop:
|
||||
|
@ -2389,6 +2450,8 @@ uip_send(struct net_buf *buf, const void *data, int len)
|
|||
int copylen;
|
||||
#define MIN(a,b) ((a) < (b)? (a): (b))
|
||||
|
||||
uip_sappdata(buf) = ip_buf_appdata(buf);
|
||||
|
||||
if(uip_sappdata(buf) != NULL) {
|
||||
copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN -
|
||||
(int)((char *)uip_sappdata(buf) -
|
||||
|
@ -2400,12 +2463,21 @@ uip_send(struct net_buf *buf, const void *data, int len)
|
|||
uip_slen(buf) = copylen;
|
||||
if(data != uip_sappdata(buf)) {
|
||||
if(uip_sappdata(buf) == NULL) {
|
||||
memcpy((char *)&uip_buf(buf)[UIP_LLH_LEN + UIP_TCPIP_HLEN],
|
||||
memmove((char *)&uip_buf(buf)[UIP_LLH_LEN + UIP_TCPIP_HLEN],
|
||||
(data), uip_slen(buf));
|
||||
} else {
|
||||
memcpy(uip_sappdata(buf), (data), uip_slen(buf));
|
||||
memmove(uip_sappdata(buf), (data), uip_slen(buf));
|
||||
}
|
||||
}
|
||||
if (uip_process(buf, UIP_TCP_SEND_CONN)) {
|
||||
int ret = tcpip_ipv6_output(buf);
|
||||
if (!ret) {
|
||||
PRINTF("Packet %p sending failed.\n", buf);
|
||||
ip_buf_unref(buf);
|
||||
} else {
|
||||
ip_buf_sent_status(buf) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* UIP_TCP */
|
||||
|
|
|
@ -261,7 +261,7 @@ slip_poll_handler(uint8_t *outbuf, uint16_t blen)
|
|||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(slip_process, ev, data, not_used)
|
||||
PROCESS_THREAD(slip_process, ev, data, not_used, user_data)
|
||||
{
|
||||
struct net_buf *buf;
|
||||
|
||||
|
@ -468,7 +468,7 @@ void slip_start(void)
|
|||
|
||||
uart_pipe_register(buf, sizeof(buf), recv_cb);
|
||||
|
||||
process_start(&slip_process, NULL);
|
||||
process_start(&slip_process, NULL, NULL);
|
||||
}
|
||||
|
||||
#endif /* defined(CONFIG_NETWORKING_UART) */
|
||||
|
|
|
@ -65,7 +65,7 @@ void uip_log(char *msg);
|
|||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(ctimer_process, "Ctimer process");
|
||||
PROCESS_THREAD(ctimer_process, ev, data, buf)
|
||||
PROCESS_THREAD(ctimer_process, ev, data, buf, user_data)
|
||||
{
|
||||
struct ctimer *c;
|
||||
PROCESS_BEGIN();
|
||||
|
@ -97,7 +97,7 @@ ctimer_init(void)
|
|||
{
|
||||
initialized = 0;
|
||||
list_init(ctimer_list);
|
||||
process_start(&ctimer_process, NULL);
|
||||
process_start(&ctimer_process, NULL, NULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
|
|
@ -86,7 +86,7 @@ update_time(void)
|
|||
net_timer_check();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(etimer_process, ev, data, buf)
|
||||
PROCESS_THREAD(etimer_process, ev, data, buf, user_data)
|
||||
{
|
||||
struct etimer *t;
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ process_alloc_event(void)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
process_start(struct process *p, process_data_t data)
|
||||
process_start(struct process *p, process_data_t data, void *user_data)
|
||||
{
|
||||
struct process *q;
|
||||
|
||||
|
@ -118,6 +118,7 @@ process_start(struct process *p, process_data_t data)
|
|||
p->next = process_list;
|
||||
process_list = p;
|
||||
p->state = PROCESS_STATE_RUNNING;
|
||||
p->user_data = user_data;
|
||||
PT_INIT(&p->pt);
|
||||
|
||||
PRINTF("process: starting '%s'\n", PROCESS_NAME_STRING(p));
|
||||
|
@ -159,7 +160,7 @@ exit_process(struct process *p, struct process *fromprocess, struct net_buf *buf
|
|||
if(p->thread != NULL && p != fromprocess) {
|
||||
/* Post the exit event to the process that is about to exit. */
|
||||
process_current = p;
|
||||
p->thread(&p->pt, PROCESS_EVENT_EXIT, NULL, buf);
|
||||
p->thread(&p->pt, PROCESS_EVENT_EXIT, NULL, buf, p->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,7 +196,7 @@ call_process(struct process *p, process_event_t ev, process_data_t data,
|
|||
PRINTF("process: calling process '%s' with event %d buf %p\n", PROCESS_NAME_STRING(p), ev, buf);
|
||||
process_current = p;
|
||||
p->state = PROCESS_STATE_CALLED;
|
||||
ret = p->thread(&p->pt, ev, data, buf);
|
||||
ret = p->thread(&p->pt, ev, data, buf, p->user_data);
|
||||
if(ret == PT_EXITED ||
|
||||
ret == PT_ENDED ||
|
||||
ev == PROCESS_EVENT_EXIT) {
|
||||
|
|
|
@ -273,11 +273,12 @@ typedef unsigned char process_num_events_t;
|
|||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define PROCESS_THREAD(name, ev, data, buf) \
|
||||
#define PROCESS_THREAD(name, ev, data, buf, user_data) \
|
||||
static PT_THREAD(process_thread_##name(struct pt *process_pt, \
|
||||
process_event_t ev, \
|
||||
process_data_t data, \
|
||||
struct net_buf *buf))
|
||||
struct net_buf *buf, \
|
||||
void *user_data))
|
||||
|
||||
/**
|
||||
* Declare the name of a process.
|
||||
|
@ -305,11 +306,11 @@ static PT_THREAD(process_thread_##name(struct pt *process_pt, \
|
|||
#if PROCESS_CONF_NO_PROCESS_NAMES
|
||||
#define PROCESS(name, strname) \
|
||||
PROCESS_THREAD(name, ev, data); \
|
||||
struct process name = { NULL, \
|
||||
struct process name = { NULL, \
|
||||
process_thread_##name }
|
||||
#else
|
||||
#define PROCESS(name, strname) \
|
||||
PROCESS_THREAD(name, ev, data, buf); \
|
||||
PROCESS_THREAD(name, ev, data, buf, user_data); \
|
||||
struct process name = { NULL, strname, \
|
||||
process_thread_##name }
|
||||
#endif
|
||||
|
@ -325,9 +326,10 @@ struct process {
|
|||
#define PROCESS_NAME_STRING(process) (process)->name
|
||||
#endif
|
||||
PT_THREAD((* thread)(struct pt *, process_event_t, process_data_t,
|
||||
struct net_buf *));
|
||||
struct net_buf *, void *user_data));
|
||||
struct pt pt;
|
||||
unsigned char state, needspoll;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -344,7 +346,7 @@ struct process {
|
|||
* process
|
||||
*
|
||||
*/
|
||||
CCIF void process_start(struct process *p, process_data_t data);
|
||||
CCIF void process_start(struct process *p, process_data_t data, void *user_data);
|
||||
|
||||
/**
|
||||
* Post an asynchronous event.
|
||||
|
|
|
@ -434,10 +434,10 @@ coap_context_init(void)
|
|||
|
||||
coap_context_event = process_alloc_event();
|
||||
|
||||
process_start(&coap_context_process, NULL);
|
||||
process_start(&coap_context_process, NULL, NULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(coap_context_process, ev, data, buf)
|
||||
PROCESS_THREAD(coap_context_process, ev, data, buf, user_data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
|
|
|
@ -311,7 +311,7 @@ void
|
|||
coap_init_engine(void)
|
||||
{
|
||||
coap_context_init();
|
||||
process_start(&coap_engine, NULL);
|
||||
process_start(&coap_engine, NULL, NULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -347,7 +347,7 @@ coap_context_t *coap_init_server(uip_ipaddr_t *server_addr,
|
|||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(coap_engine, ev, data, buf)
|
||||
PROCESS_THREAD(coap_engine, ev, data, buf, user_data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
#if 0
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_CONTEXT
|
||||
#define DEBUG 1
|
||||
#endif
|
||||
#include "contiki/ip/uip-debug.h"
|
||||
|
||||
#include <nanokernel.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
@ -28,12 +33,22 @@
|
|||
#include <net/net_ip.h>
|
||||
#include <net/net_socket.h>
|
||||
|
||||
#include "ip/simple-udp.h"
|
||||
#include "contiki/ip/simple-udp.h"
|
||||
#include "contiki/ipv6/uip-ds6.h"
|
||||
|
||||
#include "contiki/os/lib/random.h"
|
||||
#include "contiki/ipv6/uip-ds6.h"
|
||||
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
#include "contiki/os/sys/process.h"
|
||||
#include "contiki/ip/psock.h"
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_NETWORK_IP_STACK_DEBUG_CONTEXT)
|
||||
#undef NET_DBG
|
||||
#define NET_DBG(...)
|
||||
#endif
|
||||
|
||||
int net_context_get_receiver_registered(struct net_context *context);
|
||||
|
||||
struct net_context {
|
||||
|
@ -46,6 +61,15 @@ struct net_context {
|
|||
/* Application connection data */
|
||||
union {
|
||||
struct simple_udp_connection udp;
|
||||
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
struct {
|
||||
/* Proto socket that handles one TCP connection. */
|
||||
struct psock ps;
|
||||
struct process tcp;
|
||||
enum net_tcp_type tcp_type;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
bool receiver_registered;
|
||||
|
@ -188,6 +212,13 @@ void net_context_put(struct net_context *context)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
if (context->tcp_type == NET_TCP_TYPE_SERVER) {
|
||||
tcp_unlisten(UIP_HTONS(context->tuple.local_port),
|
||||
&context->tcp);
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(&context->tuple, 0, sizeof(context->tuple));
|
||||
memset(&context->udp, 0, sizeof(context->udp));
|
||||
context->receiver_registered = false;
|
||||
|
@ -222,6 +253,199 @@ net_context_get_udp_connection(struct net_context *context)
|
|||
return &context->udp;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
static int handle_tcp_connection(struct psock *p, enum tcp_event_type type,
|
||||
struct net_buf *buf)
|
||||
{
|
||||
PSOCK_BEGIN(p);
|
||||
|
||||
if (type == TCP_WRITE_EVENT) {
|
||||
NET_DBG("Trying to send %d bytes data\n", uip_appdatalen(buf));
|
||||
PSOCK_SEND(p, buf);
|
||||
}
|
||||
|
||||
PSOCK_END(p);
|
||||
}
|
||||
|
||||
int net_context_tcp_send(struct net_buf *buf)
|
||||
{
|
||||
/* Prepare data to be sent */
|
||||
process_post_synch(&ip_buf_context(buf)->tcp,
|
||||
tcpip_event,
|
||||
INT_TO_POINTER(TCP_WRITE_EVENT),
|
||||
buf);
|
||||
|
||||
|
||||
return ip_buf_sent_status(buf);
|
||||
}
|
||||
|
||||
/* This is called by contiki/ip/tcpip.c:tcpip_uipcall() when packet
|
||||
* is processed.
|
||||
*/
|
||||
PROCESS_THREAD(tcp, ev, data, buf, user_data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
while(1) {
|
||||
PROCESS_YIELD_UNTIL(ev == tcpip_event);
|
||||
|
||||
if (POINTER_TO_INT(data) == TCP_WRITE_EVENT) {
|
||||
/* We want to send data to peer. */
|
||||
struct net_context *context = user_data;
|
||||
|
||||
if (!context) {
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
context = user_data;
|
||||
if (!context || !buf) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!context->ps.net_buf ||
|
||||
context->ps.net_buf != buf) {
|
||||
NET_DBG("psock init %p buf %p\n",
|
||||
&context->ps, buf);
|
||||
PSOCK_INIT(&context->ps, buf);
|
||||
}
|
||||
|
||||
handle_tcp_connection(&context->ps,
|
||||
POINTER_TO_INT(data),
|
||||
buf);
|
||||
|
||||
PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);
|
||||
|
||||
if (POINTER_TO_INT(data) != TCP_WRITE_EVENT) {
|
||||
goto read_data;
|
||||
}
|
||||
} while(!(uip_closed(buf) ||
|
||||
uip_aborted(buf) ||
|
||||
uip_timedout(buf)));
|
||||
|
||||
context = user_data;
|
||||
|
||||
if (context &&
|
||||
context->tcp_type == NET_TCP_TYPE_CLIENT) {
|
||||
NET_DBG("\nConnection closed.\n");
|
||||
ip_buf_sent_status(buf) = -ECONNRESET;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
read_data:
|
||||
/* We are receiving data from peer. */
|
||||
if (buf && uip_newdata(buf)) {
|
||||
struct net_buf *clone;
|
||||
|
||||
if (!uip_len(buf)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Note that uIP stack will reuse the buffer when
|
||||
* sending ACK to peer host. The sending will happen
|
||||
* right after this function returns. Because of this
|
||||
* we cannot use the same buffer to pass data to
|
||||
* application.
|
||||
*/
|
||||
clone = net_buf_clone(buf);
|
||||
if (!clone) {
|
||||
NET_ERR("No enough RX buffers, "
|
||||
"packet %p discarded\n", buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
ip_buf_appdata(clone) = uip_buf(clone) +
|
||||
(ip_buf_appdata(buf) - (void *)uip_buf(buf));
|
||||
ip_buf_appdatalen(clone) = uip_len(buf);
|
||||
ip_buf_len(clone) = ip_buf_len(buf);
|
||||
ip_buf_context(clone) = user_data;
|
||||
uip_set_conn(clone) = uip_conn(buf);
|
||||
uip_flags(clone) = uip_flags(buf);
|
||||
uip_flags(clone) |= UIP_CONNECTED;
|
||||
|
||||
NET_DBG("packet received context %p buf %p len %d "
|
||||
"appdata %p appdatalen %d\n",
|
||||
ip_buf_context(clone),
|
||||
clone,
|
||||
ip_buf_len(clone),
|
||||
ip_buf_appdata(clone),
|
||||
ip_buf_appdatalen(clone));
|
||||
|
||||
nano_fifo_put(net_context_get_queue(user_data), clone);
|
||||
|
||||
/* We let the application to read the data now */
|
||||
fiber_yield();
|
||||
}
|
||||
}
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
|
||||
int net_context_tcp_init(struct net_context *context,
|
||||
enum net_tcp_type tcp_type)
|
||||
{
|
||||
if (!context || context->tuple.ip_proto != IPPROTO_TCP) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (context->receiver_registered) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
context->receiver_registered = true;
|
||||
|
||||
if (context->tcp_type == NET_TCP_TYPE_UNKNOWN) {
|
||||
/* This is the first call to this init func.
|
||||
* If we are called by net_receive() first, then
|
||||
* we are working as a server, if net_send() called
|
||||
* us first, then we are the client.
|
||||
*/
|
||||
context->tcp_type = tcp_type;
|
||||
}
|
||||
|
||||
context->tcp.thread = process_thread_tcp;
|
||||
|
||||
if (context->tcp_type == NET_TCP_TYPE_SERVER) {
|
||||
context->tcp.name = "TCP server";
|
||||
|
||||
NET_DBG("Listen to TCP port %d\n", context->tuple.local_port);
|
||||
tcp_listen(UIP_HTONS(context->tuple.local_port),
|
||||
&context->tcp);
|
||||
#if UIP_ACTIVE_OPEN
|
||||
} else {
|
||||
context->tcp.name = "TCP client";
|
||||
|
||||
#ifdef CONFIG_NETWORKING_WITH_IPV6
|
||||
NET_DBG("Connecting to ");
|
||||
PRINT6ADDR((const uip_ipaddr_t *)&context->tuple.remote_addr->in6_addr);
|
||||
PRINTF(" port %d\n", context->tuple.remote_port);
|
||||
|
||||
tcp_connect((uip_ipaddr_t *)
|
||||
&context->tuple.remote_addr->in6_addr,
|
||||
UIP_HTONS(context->tuple.remote_port),
|
||||
context, &context->tcp);
|
||||
#else /* CONFIG_NETWORKING_WITH_IPV6 */
|
||||
NET_DBG("Connecting to ");
|
||||
PRINT6ADDR((const uip_ipaddr_t *)&context->tuple.remote_addr->in_addr);
|
||||
PRINTF(" port %d\n", context->tuple.remote_port);
|
||||
|
||||
tcp_connect((uip_ipaddr_t *)
|
||||
&context->tuple.remote_addr->in_addr,
|
||||
UIP_HTONS(context->tuple.remote_port),
|
||||
context, &context->tcp);
|
||||
#endif /* CONFIG_NETWORKING_WITH_IPV6 */
|
||||
#endif /* UIP_ACTIVE_OPEN */
|
||||
}
|
||||
|
||||
context->tcp.next = NULL;
|
||||
process_start(&context->tcp, NULL, context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* TCP */
|
||||
|
||||
void net_context_init(void)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -65,6 +65,9 @@ struct simple_udp_connection *
|
|||
net_context_get_udp_connection(struct net_context *context);
|
||||
int net_context_get_receiver_registered(struct net_context *context);
|
||||
void net_context_set_receiver_registered(struct net_context *context);
|
||||
int net_context_tcp_init(struct net_context *context,
|
||||
enum net_tcp_type);
|
||||
int net_context_tcp_send(struct net_buf *buf);
|
||||
|
||||
/* Stacks for the tx & rx fibers.
|
||||
* FIXME: stack size needs fine-tuning
|
||||
|
@ -102,6 +105,22 @@ int net_send(struct net_buf *buf)
|
|||
return -ENODATA;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
net_context_tcp_init(ip_buf_context(buf), NET_TCP_TYPE_CLIENT);
|
||||
if (ip_buf_context(buf)) {
|
||||
if (net_context_get_tuple(ip_buf_context(buf))->ip_proto ==
|
||||
IPPROTO_TCP) {
|
||||
if (uip_conn(buf) && uip_conn(buf)->len > 0) {
|
||||
/* There is already pending packet to be sent.
|
||||
* Application needs to try to send data
|
||||
* a bit later.
|
||||
*/
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nano_fifo_put(&netdev.tx_queue, buf);
|
||||
|
||||
return 0;
|
||||
|
@ -154,6 +173,21 @@ static void stats(void)
|
|||
STAT(ip.chkerr),
|
||||
STAT(ip.protoerr));
|
||||
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
NET_DBG("TCP recv %d\tsent\t%d\tdrop\t%d\n",
|
||||
STAT(tcp.recv),
|
||||
STAT(tcp.sent),
|
||||
STAT(tcp.drop));
|
||||
NET_DBG("TCP chkerr %d\tackerr\t%d\trst\t%d\n",
|
||||
STAT(tcp.chkerr),
|
||||
STAT(tcp.ackerr),
|
||||
STAT(tcp.rst));
|
||||
NET_DBG("TCP rexmit %d\tsyndrop\t%d\tsynrst\t%d\n",
|
||||
STAT(tcp.rexmit),
|
||||
STAT(tcp.syndrop),
|
||||
STAT(tcp.synrst));
|
||||
#endif
|
||||
|
||||
NET_DBG("ICMP recv %d\tsent\t%d\tdrop\t%d\n",
|
||||
STAT(icmp.recv),
|
||||
STAT(icmp.sent),
|
||||
|
@ -308,6 +342,87 @@ static inline int udp_prepare_and_send(struct net_context *context,
|
|||
return !ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
/* Switch the ports and addresses. Returns 1 if packet was sent properly,
|
||||
* in this case it is the caller that needs to release the net_buf.
|
||||
* If 0 is returned, then uIP stack has released the net_buf already
|
||||
* because there was an some net related error when sending the buffer.
|
||||
*/
|
||||
static inline int tcp_prepare_and_send(struct net_context *context,
|
||||
struct net_buf *buf)
|
||||
{
|
||||
#ifdef CONFIG_NETWORKING_IPV6_NO_ND
|
||||
uip_ds6_route_t *route_old, *route_new = NULL;
|
||||
uip_ds6_nbr_t *nbr;
|
||||
#endif
|
||||
uip_ipaddr_t tmp;
|
||||
uint16_t port;
|
||||
int ret;
|
||||
|
||||
uip_len(buf) = uip_slen(buf) = ip_buf_len(buf);
|
||||
uip_flags(buf) |= UIP_NEWDATA;
|
||||
port = NET_BUF_UDP(buf)->srcport;
|
||||
NET_BUF_UDP(buf)->srcport = NET_BUF_UDP(buf)->destport;
|
||||
NET_BUF_UDP(buf)->destport = port;
|
||||
|
||||
uip_ipaddr_copy(&tmp, &NET_BUF_IP(buf)->srcipaddr);
|
||||
uip_ipaddr_copy(&NET_BUF_IP(buf)->srcipaddr,
|
||||
&NET_BUF_IP(buf)->destipaddr);
|
||||
uip_ipaddr_copy(&NET_BUF_IP(buf)->destipaddr, &tmp);
|
||||
|
||||
#ifdef CONFIG_NETWORKING_IPV6_NO_ND
|
||||
/* The peer needs to be in neighbor cache before route can be added.
|
||||
*/
|
||||
nbr = uip_ds6_nbr_lookup((uip_ipaddr_t *)&NET_BUF_IP(buf)->destipaddr);
|
||||
if (!nbr) {
|
||||
const uip_lladdr_t *lladdr =
|
||||
(const uip_lladdr_t *)&ip_buf_ll_src(buf);
|
||||
nbr = uip_ds6_nbr_add(
|
||||
(uip_ipaddr_t *)&NET_BUF_IP(buf)->destipaddr,
|
||||
lladdr, 0, NBR_REACHABLE);
|
||||
if (!nbr) {
|
||||
NET_DBG("Cannot add peer ");
|
||||
PRINT6ADDR(&NET_BUF_IP(buf)->destipaddr);
|
||||
PRINT(" to neighbor cache\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Temporarily add route to peer, delete the route after
|
||||
* sending the packet. Check if there was already a
|
||||
* route and do not remove it if there was existing
|
||||
* route to this peer.
|
||||
*/
|
||||
route_old = uip_ds6_route_lookup(&NET_BUF_IP(buf)->destipaddr);
|
||||
if (!route_old) {
|
||||
route_new = uip_ds6_route_add(&NET_BUF_IP(buf)->destipaddr,
|
||||
128,
|
||||
&NET_BUF_IP(buf)->destipaddr);
|
||||
if (!route_new) {
|
||||
NET_DBG("Cannot add route to peer ");
|
||||
PRINT6ADDR(&NET_BUF_IP(buf)->destipaddr);
|
||||
PRINT("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
NET_DBG("Packet output len %d\n", uip_len(buf));
|
||||
|
||||
ret = net_context_tcp_send(buf);
|
||||
if (ret && ret != -EAGAIN) {
|
||||
NET_DBG("Packet could not be sent properly.\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETWORKING_IPV6_NO_ND
|
||||
if (!route_old && route_new) {
|
||||
/* This will also remove the neighbor cache entry */
|
||||
uip_ds6_route_rm(route_new);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Application wants to send a reply */
|
||||
int net_reply(struct net_context *context, struct net_buf *buf)
|
||||
{
|
||||
|
@ -335,8 +450,13 @@ int net_reply(struct net_context *context, struct net_buf *buf)
|
|||
ret = udp_prepare_and_send(context, buf);
|
||||
break;
|
||||
case IPPROTO_TCP:
|
||||
NET_DBG("TCP not yet supported\n");
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
ret = tcp_prepare_and_send(context, buf);
|
||||
#else
|
||||
NET_DBG("TCP not supported\n");
|
||||
return -EINVAL;
|
||||
#endif
|
||||
break;
|
||||
case IPPROTO_ICMPV6:
|
||||
NET_DBG("ICMPv6 not yet supported\n");
|
||||
return -EINVAL;
|
||||
|
@ -446,8 +566,18 @@ struct net_buf *net_receive(struct net_context *context, int32_t timeout)
|
|||
reserve = UIP_IPUDPH_LEN + UIP_LLH_LEN;
|
||||
break;
|
||||
case IPPROTO_TCP:
|
||||
NET_DBG("TCP not yet supported\n");
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
ret = net_context_tcp_init(context, NET_TCP_TYPE_SERVER);
|
||||
if (ret) {
|
||||
NET_DBG("TCP connection init failed\n");
|
||||
ret = -ENOENT;
|
||||
break;
|
||||
}
|
||||
ret = 0;
|
||||
#else
|
||||
NET_DBG("TCP not supported\n");
|
||||
ret = -EINVAL;
|
||||
#endif
|
||||
break;
|
||||
case IPPROTO_ICMPV6:
|
||||
NET_DBG("ICMPv6 not yet supported\n");
|
||||
|
@ -480,6 +610,14 @@ struct net_buf *net_receive(struct net_context *context, int32_t timeout)
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
if (tuple->ip_proto == IPPROTO_TCP &&
|
||||
(ip_buf_appdata(buf) > (void *)buf->data)) {
|
||||
/* We need to skip the TCP header + possible extensions */
|
||||
reserve = ip_buf_appdata(buf) - (void *)buf->data;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (buf && reserve) {
|
||||
ip_buf_appdatalen(buf) = ip_buf_len(buf) - reserve;
|
||||
ip_buf_appdata(buf) = &uip_buf(buf)[reserve];
|
||||
|
@ -573,8 +711,26 @@ static int check_and_send_packet(struct net_buf *buf)
|
|||
uip_appdatalen(buf));
|
||||
break;
|
||||
case IPPROTO_TCP:
|
||||
NET_DBG("TCP not yet supported\n");
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
if (ip_buf_appdatalen(buf) == 0) {
|
||||
/* User application has not set the application data
|
||||
* length. The buffer will be discarded if we do not
|
||||
* set the value correctly.
|
||||
*/
|
||||
uip_appdatalen(buf) = buf->len -
|
||||
(UIP_IPTCPH_LEN + UIP_LLH_LEN);
|
||||
}
|
||||
if (uip_len(buf) == 0) {
|
||||
uip_len(buf) = buf->len;
|
||||
}
|
||||
ret = net_context_tcp_send(buf);
|
||||
if (ret && ret != -EAGAIN) {
|
||||
NET_DBG("Packet could not be sent properly.\n");
|
||||
}
|
||||
#else
|
||||
NET_DBG("TCP not supported\n");
|
||||
ret = -EINVAL;
|
||||
#endif
|
||||
break;
|
||||
case IPPROTO_ICMPV6:
|
||||
NET_DBG("ICMPv6 not yet supported\n");
|
||||
|
@ -812,10 +968,10 @@ static int network_initialization(void)
|
|||
process_init();
|
||||
tcpip_set_outputfunc(net_tcpip_output);
|
||||
|
||||
process_start(&tcpip_process, NULL);
|
||||
process_start(&simple_udp_process, NULL);
|
||||
process_start(&etimer_process, NULL);
|
||||
process_start(&ctimer_process, NULL);
|
||||
process_start(&tcpip_process, NULL, NULL);
|
||||
process_start(&simple_udp_process, NULL, NULL);
|
||||
process_start(&etimer_process, NULL, NULL);
|
||||
process_start(&ctimer_process, NULL, NULL);
|
||||
|
||||
slip_start();
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ rest_init_engine(void)
|
|||
REST.init();
|
||||
|
||||
/*Start REST engine process */
|
||||
process_start(&rest_engine_process, NULL);
|
||||
process_start(&rest_engine_process, NULL, NULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -175,7 +175,7 @@ rest_invoke_restful_service(void *request, void *response, uint8_t *buffer,
|
|||
return found & allowed;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(rest_engine_process, ev, data, buf)
|
||||
PROCESS_THREAD(rest_engine_process, ev, data, buf, user_data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
|
|
|
@ -3791,7 +3791,7 @@ dtls_new_context(void *app_data) {
|
|||
LIST_STRUCT_INIT(c, peers);
|
||||
/* LIST_STRUCT_INIT(c, key_store); */
|
||||
|
||||
process_start(&dtls_retransmit_process, (char *)c);
|
||||
process_start(&dtls_retransmit_process, (char *)c, NULL);
|
||||
PROCESS_CONTEXT_BEGIN(&dtls_retransmit_process);
|
||||
/* the retransmit timer must be initialized to some large value */
|
||||
etimer_set(&c->retransmit_timer, 0xFFFF, &dtls_retransmit_process);
|
||||
|
@ -3992,7 +3992,7 @@ dtls_check_retransmit(dtls_context_t *context, clock_time_t *next) {
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* message retransmission */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(dtls_retransmit_process, ev, data, buf)
|
||||
PROCESS_THREAD(dtls_retransmit_process, ev, data, buf, user_data)
|
||||
{
|
||||
clock_time_t now;
|
||||
netq_t *node;
|
||||
|
|
|
@ -683,7 +683,7 @@ static dtls_handler_t cb = {
|
|||
PROCESS(server_process, "DTLS server process");
|
||||
AUTOSTART_PROCESSES(&server_process);
|
||||
|
||||
PROCESS_THREAD(server_process, ev, data)
|
||||
PROCESS_THREAD(server_process, ev, data, user_data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
|
|
|
@ -273,7 +273,7 @@ void toggle_observation(coap_context_t *coap_ctx)
|
|||
#endif
|
||||
|
||||
PROCESS(coap_observe_client_process, "CoAP observe client process");
|
||||
PROCESS_THREAD(coap_observe_client_process, ev, data, buf)
|
||||
PROCESS_THREAD(coap_observe_client_process, ev, data, buf, user_data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
|
|
|
@ -219,6 +219,7 @@ static inline bool get_context(struct net_context **unicast,
|
|||
static struct net_addr any_addr;
|
||||
static struct net_addr peer_addr;
|
||||
static struct net_addr my_addr;
|
||||
int proto = IPPROTO_UDP;
|
||||
|
||||
#if defined(CONFIG_NETWORKING_WITH_IPV6)
|
||||
static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
|
||||
|
@ -254,7 +255,11 @@ static inline bool get_context(struct net_context **unicast,
|
|||
my_addr.family = AF_INET;
|
||||
#endif
|
||||
|
||||
*unicast = net_context_get(IPPROTO_UDP,
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
proto = IPPROTO_TCP;
|
||||
#endif /* CONFIG_NETWORKING_WITH_TCP */
|
||||
|
||||
*unicast = net_context_get(proto,
|
||||
&peer_addr, PEER_PORT,
|
||||
&my_addr, MY_PORT);
|
||||
if (!*unicast) {
|
||||
|
|
|
@ -150,6 +150,7 @@ static inline bool get_context(struct net_context **recv,
|
|||
static struct net_addr mcast_addr;
|
||||
static struct net_addr any_addr;
|
||||
static struct net_addr my_addr;
|
||||
int proto = IPPROTO_UDP;
|
||||
|
||||
#if defined(CONFIG_NETWORKING_WITH_IPV6)
|
||||
static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
|
||||
|
@ -178,7 +179,11 @@ static inline bool get_context(struct net_context **recv,
|
|||
my_addr.family = AF_INET;
|
||||
#endif
|
||||
|
||||
*recv = net_context_get(IPPROTO_UDP,
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
proto = IPPROTO_TCP;
|
||||
#endif /* CONFIG_NETWORKING_WITH_TCP */
|
||||
|
||||
*recv = net_context_get(proto,
|
||||
&any_addr, 0,
|
||||
&my_addr, MY_PORT);
|
||||
if (!*recv) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue