mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #14500 from brummer-simon/gnrc_tcp-replace_xtimer_with_evtimer
gnrc_tcp: Replace xtimer with evtimer
This commit is contained in:
commit
2cab6b9f18
@ -430,8 +430,7 @@ ifneq (,$(filter gnrc_tcp,$(USEMODULE)))
|
||||
USEMODULE += inet_csum
|
||||
USEMODULE += random
|
||||
USEMODULE += tcp
|
||||
USEMODULE += xtimer
|
||||
USEMODULE += core_mbox
|
||||
USEMODULE += evtimer_mbox
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_pktdump,$(USEMODULE)))
|
||||
|
@ -166,18 +166,18 @@ int gnrc_tcp_open_passive(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *local);
|
||||
* @param[in,out] tcb TCB holding the connection information.
|
||||
* @param[in] data Pointer to the data that should be transmitted.
|
||||
* @param[in] len Number of bytes that should be transmitted.
|
||||
* @param[in] user_timeout_duration_us If not zero and there was not data transmitted
|
||||
* the function returns after user_timeout_duration_us.
|
||||
* @param[in] user_timeout_duration_ms If not zero and there was not data transmitted
|
||||
* the function returns after user_timeout_duration_ms.
|
||||
* If zero, no timeout will be triggered.
|
||||
*
|
||||
* @return The number of successfully transmitted bytes.
|
||||
* @return -ENOTCONN if connection is not established.
|
||||
* @return -ECONNRESET if connection was reset by the peer.
|
||||
* @return -ECONNABORTED if the connection was aborted.
|
||||
* @return -ETIMEDOUT if @p user_timeout_duration_us expired.
|
||||
* @return -ETIMEDOUT if @p user_timeout_duration_ms expired.
|
||||
*/
|
||||
ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
|
||||
const uint32_t user_timeout_duration_us);
|
||||
const uint32_t user_timeout_duration_ms);
|
||||
|
||||
/**
|
||||
* @brief Receive Data from the peer.
|
||||
@ -193,11 +193,11 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
|
||||
* should be copied into.
|
||||
* @param[in] max_len Maximum amount to bytes that should be read
|
||||
* into @p data.
|
||||
* @param[in] user_timeout_duration_us Timeout for receive in microseconds.
|
||||
* @param[in] user_timeout_duration_ms Timeout for receive in milliseconds.
|
||||
* If zero and no data is available, the function
|
||||
* returns immediately. If not zero the function
|
||||
* blocks until data is available or
|
||||
* @p user_timeout_duration_us microseconds passed.
|
||||
* @p user_timeout_duration_ms milliseconds passed.
|
||||
*
|
||||
* @return The number of bytes read into @p data.
|
||||
* @return 0, if the connection is closing and no further data can be read.
|
||||
@ -205,10 +205,10 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
|
||||
* @return -EAGAIN if user_timeout_duration_us is zero and no data is available.
|
||||
* @return -ECONNRESET if connection was reset by the peer.
|
||||
* @return -ECONNABORTED if the connection was aborted.
|
||||
* @return -ETIMEDOUT if @p user_timeout_duration_us expired.
|
||||
* @return -ETIMEDOUT if @p user_timeout_duration_ms expired.
|
||||
*/
|
||||
ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
|
||||
const uint32_t user_timeout_duration_us);
|
||||
const uint32_t user_timeout_duration_ms);
|
||||
|
||||
/**
|
||||
* @brief Close a TCP connection.
|
||||
|
@ -48,22 +48,22 @@ extern "C" {
|
||||
* RTO <- SRTT + max (G, K*RTTVAR)
|
||||
*
|
||||
* where K is a constant, and G is clock granularity in seconds
|
||||
* ( @ref CONFIG_GNRC_TCP_RTO_GRANULARITY).
|
||||
* ( @ref CONFIG_GNRC_TCP_RTO_GRANULARITY_MS).
|
||||
* For more information refer to https://tools.ietf.org/html/rfc6298
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Timeout duration for user calls. Default is 2 minutes.
|
||||
* @brief Timeout duration in milliseconds for user calls. Default is 2 minutes.
|
||||
*/
|
||||
#ifndef CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION
|
||||
#define CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION (120U * US_PER_SEC)
|
||||
#ifndef CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION_MS
|
||||
#define CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION_MS (120U * MS_PER_SEC)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum segment lifetime (MSL). Default is 30 seconds.
|
||||
* @brief Maximum segment lifetime (MSL) in milliseconds. Default is 30 seconds.
|
||||
*/
|
||||
#ifndef CONFIG_GNRC_TCP_MSL
|
||||
#define CONFIG_GNRC_TCP_MSL (30U * US_PER_SEC)
|
||||
#ifndef CONFIG_GNRC_TCP_MSL_MS
|
||||
#define CONFIG_GNRC_TCP_MSL_MS (30U * MS_PER_SEC)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -109,28 +109,28 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Lower bound for RTO = 1 sec (see RFC 6298)
|
||||
* @brief Lower bound for RTO in milliseconds. Default is 1 sec (see RFC 6298)
|
||||
*
|
||||
* @note Retransmission Timeout (RTO) determines how long TCP waits for
|
||||
* acknowledgment (ACK) of transmitted segment. If the acknowledgment
|
||||
* isn't received within this time it is considered lost.
|
||||
*/
|
||||
#ifndef CONFIG_GNRC_TCP_RTO_LOWER_BOUND
|
||||
#define CONFIG_GNRC_TCP_RTO_LOWER_BOUND (1U * US_PER_SEC)
|
||||
#ifndef CONFIG_GNRC_TCP_RTO_LOWER_BOUND_MS
|
||||
#define CONFIG_GNRC_TCP_RTO_LOWER_BOUND_MS (1U * MS_PER_SEC)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Upper bound for RTO = 60 sec (see RFC 6298)
|
||||
* @brief Upper bound for RTO in milliseconds. Default is 60 sec (see RFC 6298)
|
||||
*/
|
||||
#ifndef CONFIG_GNRC_TCP_RTO_UPPER_BOUND
|
||||
#define CONFIG_GNRC_TCP_RTO_UPPER_BOUND (60U * US_PER_SEC)
|
||||
#ifndef CONFIG_GNRC_TCP_RTO_UPPER_BOUND_MS
|
||||
#define CONFIG_GNRC_TCP_RTO_UPPER_BOUND_MS (60U * MS_PER_SEC)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Assumes clock granularity for TCP of 10 ms (see RFC 6298)
|
||||
* @brief Clock granularity for TCP in milliseconds. Dedault is 10 milliseconds (see RFC 6298)
|
||||
*/
|
||||
#ifndef CONFIG_GNRC_TCP_RTO_GRANULARITY
|
||||
#define CONFIG_GNRC_TCP_RTO_GRANULARITY (10U * MS_PER_SEC)
|
||||
#ifndef CONFIG_GNRC_TCP_RTO_GRANULARITY_MS
|
||||
#define CONFIG_GNRC_TCP_RTO_GRANULARITY_MS (10U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -155,17 +155,17 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Lower bound for the duration between probes
|
||||
* @brief Lower bound for the duration between probes in milliseconds. Default is 1 seconds
|
||||
*/
|
||||
#ifndef CONFIG_GNRC_TCP_PROBE_LOWER_BOUND
|
||||
#define CONFIG_GNRC_TCP_PROBE_LOWER_BOUND (1U * US_PER_SEC)
|
||||
#ifndef CONFIG_GNRC_TCP_PROBE_LOWER_BOUND_MS
|
||||
#define CONFIG_GNRC_TCP_PROBE_LOWER_BOUND_MS (1U * MS_PER_SEC)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Upper bound for the duration between probes
|
||||
* @brief Upper bound for the duration between probes in milliseconds. Default is 60 seconds
|
||||
*/
|
||||
#ifndef CONFIG_GNRC_TCP_PROBE_UPPER_BOUND
|
||||
#define CONFIG_GNRC_TCP_PROBE_UPPER_BOUND (60U * US_PER_SEC)
|
||||
#ifndef CONFIG_GNRC_TCP_PROBE_UPPER_BOUND_MS
|
||||
#define CONFIG_GNRC_TCP_PROBE_UPPER_BOUND_MS (60U * MS_PER_SEC)
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -23,8 +23,9 @@
|
||||
#include <stdint.h>
|
||||
#include "kernel_types.h"
|
||||
#include "ringbuffer.h"
|
||||
#include "xtimer.h"
|
||||
#include "mutex.h"
|
||||
#include "evtimer_msg.h"
|
||||
#include "evtimer_mbox.h"
|
||||
#include "msg.h"
|
||||
#include "mbox.h"
|
||||
#include "net/gnrc/pkt.h"
|
||||
@ -67,11 +68,9 @@ typedef struct _transmission_control_block {
|
||||
int32_t srtt; /**< Smoothed round trip time */
|
||||
int32_t rto; /**< Retransmission timeout duration */
|
||||
uint8_t retries; /**< Number of retransmissions */
|
||||
xtimer_t timer_retransmit; /**< Retransmission timer */
|
||||
xtimer_t timer_misc; /**< General purpose timer */
|
||||
msg_t msg_retransmit; /**< Retransmission timer message */
|
||||
msg_t msg_misc; /**< General purpose timer message */
|
||||
gnrc_pktsnip_t *pkt_retransmit; /**< Pointer to packet in "retransmit queue" */
|
||||
evtimer_msg_event_t event_retransmit; /**< Retransmission event */
|
||||
evtimer_mbox_event_t event_misc; /**< General purpose event */
|
||||
gnrc_pktsnip_t *pkt_retransmit; /**< Pointer to packet in "retransmit queue" */
|
||||
mbox_t *mbox; /**< TCB mbox for synchronization */
|
||||
uint8_t *rcv_buf_raw; /**< Pointer to the receive buffer */
|
||||
ringbuffer_t rcv_buf; /**< Receive buffer data structure */
|
||||
|
@ -12,18 +12,18 @@ menuconfig KCONFIG_USEMODULE_GNRC_TCP
|
||||
|
||||
if KCONFIG_USEMODULE_GNRC_TCP
|
||||
|
||||
config GNRC_TCP_CONNECTION_TIMEOUT_DURATION
|
||||
int "Timeout duration for user calls in microseconds"
|
||||
default 120000000
|
||||
config GNRC_TCP_CONNECTION_TIMEOUT_DURATION_MS
|
||||
int "Timeout duration for user calls in milliseconds"
|
||||
default 120000
|
||||
help
|
||||
Timeout duration for user calls. Default value is 120000000 microseconds
|
||||
Timeout duration for user calls. Default value is 120000 milliseconds
|
||||
(2 minutes).
|
||||
|
||||
config GNRC_TCP_MSL
|
||||
int "Maximum segment lifetime (MSL) in microseconds"
|
||||
default 30000000
|
||||
config GNRC_TCP_MSL_MS
|
||||
int "Maximum segment lifetime (MSL) in milliseconds"
|
||||
default 30000
|
||||
help
|
||||
Maximum segment lifetime (MSL) in microseconds. Default value is 30
|
||||
Maximum segment lifetime (MSL) in milliseconds. Default value is 30
|
||||
seconds.
|
||||
|
||||
config GNRC_TCP_MSS
|
||||
@ -59,29 +59,29 @@ config GNRC_TCP_RCV_BUFFERS
|
||||
int "Number of preallocated receive buffers"
|
||||
default 1
|
||||
|
||||
config GNRC_TCP_RTO_LOWER_BOUND
|
||||
int "Lower bound for RTO in microseconds"
|
||||
default 1000000
|
||||
config GNRC_TCP_RTO_LOWER_BOUND_MS
|
||||
int "Lower bound for RTO in milliseconds"
|
||||
default 1000
|
||||
help
|
||||
Lower bound value for retransmission timeout (RTO) in microseconds.
|
||||
Default value is 1000000 microseconds (1 second). Retransmission
|
||||
Lower bound value for retransmission timeout (RTO) in milliseconds.
|
||||
Default value is 1000 milliseconds (1 second). Retransmission
|
||||
timeout determines how long TCP waits for acknowledgment (ACK) of
|
||||
transmitted segment. Refer to RFC 6298 for more information.
|
||||
|
||||
config GNRC_TCP_RTO_UPPER_BOUND
|
||||
int "Upper bound for RTO in microseconds"
|
||||
default 60000000
|
||||
config GNRC_TCP_RTO_UPPER_BOUND_MS
|
||||
int "Upper bound for RTO in milliseconds"
|
||||
default 60000
|
||||
help
|
||||
Upper bound value for retransmission timeout (RTO) in microseconds.
|
||||
Default value is 60000000 microseconds (60 seconds). Refer to RFC 6298
|
||||
Upper bound value for retransmission timeout (RTO) in milliseconds.
|
||||
Default value is 60000 milliseconds (60 seconds). Refer to RFC 6298
|
||||
for more information.
|
||||
|
||||
config GNRC_TCP_RTO_GRANULARITY
|
||||
int "Clock granularity for RTO in microseconds"
|
||||
default 10000
|
||||
config GNRC_TCP_RTO_GRANULARITY_MS
|
||||
int "Clock granularity for RTO in milliseconds"
|
||||
default 10
|
||||
help
|
||||
Clock granularity for retransmission timeout (RTO) for TCP in
|
||||
microseconds. Default value is 10000 microseconds (10 milliseconds).
|
||||
milliseconds. Default value is 10 milliseconds.
|
||||
Refer to RFC 6298 for more information.
|
||||
|
||||
config GNRC_TCP_RTO_A_DIV
|
||||
@ -104,13 +104,21 @@ config GNRC_TCP_RTO_K
|
||||
int "K value for RTO calculation"
|
||||
default 4
|
||||
|
||||
config GNRC_TCP_PROBE_LOWER_BOUND
|
||||
int "Lower bound for the duration between probes in microseconds"
|
||||
default 1000000
|
||||
config GNRC_TCP_PROBE_LOWER_BOUND_MS
|
||||
int "Lower bound for the duration between probes in milliseconds"
|
||||
default 1000
|
||||
help
|
||||
Lower bound value for window probes in milliseconds.
|
||||
Default value is 1000 milliseconds (1 second).
|
||||
Refer to RFC 6298 for more information.
|
||||
|
||||
config GNRC_TCP_PROBE_UPPER_BOUND
|
||||
int "Lower bound for the duration between probes in microseconds"
|
||||
default 60000000
|
||||
config GNRC_TCP_PROBE_UPPER_BOUND_MS
|
||||
int "Lower bound for the duration between probes in milliseconds"
|
||||
default 60000
|
||||
help
|
||||
Upper bound value for window probes in milliseconds.
|
||||
Default value is 60000 milliseconds (60 seconds). Refer to RFC 6298
|
||||
for more information.
|
||||
|
||||
config GNRC_TCP_MSG_QUEUE_SIZE_SIZE_EXP
|
||||
int "Message queue size for TCP API internal messaging (as exponent of 2^n)"
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include <string.h>
|
||||
#include <utlist.h>
|
||||
|
||||
#include "evtimer.h"
|
||||
#include "evtimer_mbox.h"
|
||||
#include "mbox.h"
|
||||
#include "net/af.h"
|
||||
#include "net/gnrc.h"
|
||||
@ -41,19 +43,11 @@
|
||||
|
||||
#define TCP_MSG_QUEUE_SIZE (1 << CONFIG_GNRC_TCP_MSG_QUEUE_SIZE_EXP)
|
||||
|
||||
/**
|
||||
* @brief Allocate memory for GNRC TCP thread stack.
|
||||
*/
|
||||
#if ENABLE_DEBUG
|
||||
static char _stack[TCP_EVENTLOOP_STACK_SIZE + THREAD_EXTRA_STACKSIZE_PRINTF];
|
||||
#else
|
||||
static char _stack[TCP_EVENTLOOP_STACK_SIZE];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief TCPs eventloop pid, declared externally.
|
||||
* @brief Central MBOX evtimer used by gnrc_tcp
|
||||
*/
|
||||
kernel_pid_t gnrc_tcp_pid = KERNEL_PID_UNDEF;
|
||||
static evtimer_t _tcp_mbox_timer;
|
||||
|
||||
/**
|
||||
* @brief Head of liked TCB list.
|
||||
@ -65,40 +59,23 @@ gnrc_tcp_tcb_t *_list_tcb_head;
|
||||
*/
|
||||
mutex_t _list_tcb_lock;
|
||||
|
||||
/**
|
||||
* @brief Helper struct, holding all argument data for_cb_mbox_put_msg.
|
||||
*/
|
||||
typedef struct _cb_arg {
|
||||
uint32_t msg_type; /**< Message Type to Put into mbox behind mbox_ptr */
|
||||
mbox_t *mbox_ptr; /**< Pointer to mbox */
|
||||
} cb_arg_t;
|
||||
|
||||
/**
|
||||
* @brief Callback for xtimer, puts a message in a mbox.
|
||||
*
|
||||
* @param[in] arg Ptr to cb_arg_t. Must not be NULL or anything else.
|
||||
*/
|
||||
static void _cb_mbox_put_msg(void *arg)
|
||||
static void _sched_mbox(evtimer_mbox_event_t *event, uint32_t offset,
|
||||
uint16_t type, mbox_t *mbox)
|
||||
{
|
||||
msg_t msg;
|
||||
msg.type = ((cb_arg_t *) arg)->msg_type;
|
||||
mbox_try_put(((cb_arg_t *) arg)->mbox_ptr, &msg);
|
||||
event->event.offset = offset;
|
||||
event->msg.type = type;
|
||||
evtimer_add_mbox(&_tcp_mbox_timer, event, mbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup timer with a callback function.
|
||||
*
|
||||
* @param[in/out] timer Ptr to timer, which should be set.
|
||||
* @param[in] duration Duration after @p timer expires.
|
||||
* @param[in] cb Function to be called after @p duration.
|
||||
* @param[in] arg Arguments for @p cb.
|
||||
*/
|
||||
static void _setup_timeout(xtimer_t *timer, const uint32_t duration, const xtimer_callback_t cb,
|
||||
cb_arg_t *arg)
|
||||
static void _sched_connection_timeout(evtimer_mbox_event_t *event, mbox_t *mbox)
|
||||
{
|
||||
timer->callback = cb;
|
||||
timer->arg = arg;
|
||||
xtimer_set(timer, duration);
|
||||
_sched_mbox(event, CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION_MS,
|
||||
MSG_TYPE_CONNECTION_TIMEOUT, mbox);
|
||||
}
|
||||
|
||||
static void _unsched_mbox(evtimer_mbox_event_t *event)
|
||||
{
|
||||
evtimer_del(&_tcp_mbox_timer, (evtimer_event_t *)event);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,7 +101,6 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
|
||||
msg_t msg;
|
||||
msg_t msg_queue[TCP_MSG_QUEUE_SIZE];
|
||||
mbox_t mbox = MBOX_INIT(msg_queue, TCP_MSG_QUEUE_SIZE);
|
||||
cb_arg_t connection_timeout_arg = {MSG_TYPE_CONNECTION_TIMEOUT, &mbox};
|
||||
int ret = 0;
|
||||
|
||||
/* Lock the TCB for this function call */
|
||||
@ -185,9 +161,8 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
|
||||
tcb->local_port = local_port;
|
||||
tcb->peer_port = remote->port;
|
||||
|
||||
/* Setup connection timeout: Put timeout message in TCBs mbox on expiration */
|
||||
_setup_timeout(&(tcb->timer_misc), CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION,
|
||||
_cb_mbox_put_msg, &connection_timeout_arg);
|
||||
/* Setup connection timeout */
|
||||
_sched_connection_timeout(&tcb->event_misc, &mbox);
|
||||
}
|
||||
|
||||
/* Call FSM with event: CALL_OPEN */
|
||||
@ -211,9 +186,8 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
|
||||
* send SYN+ACK we received upon entering SYN_RCVD is never acknowledged
|
||||
* by the peer. */
|
||||
if ((tcb->state == FSM_STATE_SYN_RCVD) && (tcb->status & STATUS_PASSIVE)) {
|
||||
_setup_timeout(&(tcb->timer_misc),
|
||||
CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION, _cb_mbox_put_msg,
|
||||
&connection_timeout_arg);
|
||||
_unsched_mbox(&tcb->event_misc);
|
||||
_sched_connection_timeout(&tcb->event_misc, &mbox);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -241,7 +215,7 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
|
||||
|
||||
/* Cleanup */
|
||||
_fsm_set_mbox(tcb, NULL);
|
||||
xtimer_remove(&(tcb->timer_misc));
|
||||
_unsched_mbox(&tcb->event_misc);
|
||||
if (tcb->state == FSM_STATE_CLOSED && ret == 0) {
|
||||
ret = -ECONNREFUSED;
|
||||
}
|
||||
@ -378,11 +352,6 @@ int gnrc_tcp_ep_from_str(gnrc_tcp_ep_t *ep, const char *str)
|
||||
|
||||
int gnrc_tcp_init(void)
|
||||
{
|
||||
/* Guard: Check if thread is already running */
|
||||
if (gnrc_tcp_pid != KERNEL_PID_UNDEF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Initialize mutex for TCB list synchronization */
|
||||
mutex_init(&(_list_tcb_lock));
|
||||
|
||||
@ -390,10 +359,11 @@ int gnrc_tcp_init(void)
|
||||
_list_tcb_head = NULL;
|
||||
_rcvbuf_init();
|
||||
|
||||
/* Initialize timers */
|
||||
evtimer_init_mbox(&_tcp_mbox_timer);
|
||||
|
||||
/* Start TCP processing thread */
|
||||
return thread_create(_stack, sizeof(_stack), TCP_EVENTLOOP_PRIO,
|
||||
THREAD_CREATE_STACKTEST, _event_loop, NULL,
|
||||
"gnrc_tcp");
|
||||
return _gnrc_tcp_event_loop_init();
|
||||
}
|
||||
|
||||
void gnrc_tcp_tcb_init(gnrc_tcp_tcb_t *tcb)
|
||||
@ -460,7 +430,7 @@ int gnrc_tcp_open_passive(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *local)
|
||||
}
|
||||
|
||||
ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
|
||||
const uint32_t timeout_duration_us)
|
||||
const uint32_t timeout_duration_ms)
|
||||
{
|
||||
assert(tcb != NULL);
|
||||
assert(data != NULL);
|
||||
@ -468,12 +438,9 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
|
||||
msg_t msg;
|
||||
msg_t msg_queue[TCP_MSG_QUEUE_SIZE];
|
||||
mbox_t mbox = MBOX_INIT(msg_queue, TCP_MSG_QUEUE_SIZE);
|
||||
cb_arg_t connection_timeout_arg = {MSG_TYPE_CONNECTION_TIMEOUT, &mbox};
|
||||
xtimer_t user_timeout;
|
||||
cb_arg_t user_timeout_arg = {MSG_TYPE_USER_SPEC_TIMEOUT, &mbox};
|
||||
xtimer_t probe_timeout;
|
||||
cb_arg_t probe_timeout_arg = {MSG_TYPE_PROBE_TIMEOUT, &mbox};
|
||||
uint32_t probe_timeout_duration_us = 0;
|
||||
evtimer_mbox_event_t event_user_timeout;
|
||||
evtimer_mbox_event_t event_probe_timeout;
|
||||
uint32_t probe_timeout_duration_ms = 0;
|
||||
ssize_t ret = 0;
|
||||
bool probing_mode = false;
|
||||
|
||||
@ -489,12 +456,12 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
|
||||
/* Setup messaging */
|
||||
_fsm_set_mbox(tcb, &mbox);
|
||||
|
||||
/* Setup connection timeout: Put timeout message in tcb's mbox on expiration */
|
||||
_setup_timeout(&(tcb->timer_misc), CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION,
|
||||
_cb_mbox_put_msg, &connection_timeout_arg);
|
||||
/* Setup connection timeout */
|
||||
_sched_connection_timeout(&tcb->event_misc, &mbox);
|
||||
|
||||
if (timeout_duration_us > 0) {
|
||||
_setup_timeout(&user_timeout, timeout_duration_us, _cb_mbox_put_msg, &user_timeout_arg);
|
||||
if (timeout_duration_ms > 0) {
|
||||
_sched_mbox(&event_user_timeout, timeout_duration_ms,
|
||||
MSG_TYPE_USER_SPEC_TIMEOUT, &mbox);
|
||||
}
|
||||
|
||||
/* Loop until something was sent and acked */
|
||||
@ -510,11 +477,12 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
|
||||
/* If this is the first probe: Setup probing duration */
|
||||
if (!probing_mode) {
|
||||
probing_mode = true;
|
||||
probe_timeout_duration_us = tcb->rto;
|
||||
probe_timeout_duration_ms = tcb->rto;
|
||||
}
|
||||
/* Setup probe timeout */
|
||||
_setup_timeout(&probe_timeout, probe_timeout_duration_us, _cb_mbox_put_msg,
|
||||
&probe_timeout_arg);
|
||||
_unsched_mbox(&event_probe_timeout);
|
||||
_sched_mbox(&event_probe_timeout, probe_timeout_duration_ms,
|
||||
MSG_TYPE_PROBE_TIMEOUT, &mbox);
|
||||
}
|
||||
|
||||
/* Try to send data in case there nothing has been sent and we are not probing */
|
||||
@ -541,14 +509,14 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
|
||||
DEBUG("gnrc_tcp.c : gnrc_tcp_send() : PROBE_TIMEOUT\n");
|
||||
/* Send probe */
|
||||
_fsm(tcb, FSM_EVENT_SEND_PROBE, NULL, NULL, 0);
|
||||
probe_timeout_duration_us += probe_timeout_duration_us;
|
||||
probe_timeout_duration_ms += probe_timeout_duration_ms;
|
||||
|
||||
/* Boundary check for time interval between probes */
|
||||
if (probe_timeout_duration_us < CONFIG_GNRC_TCP_PROBE_LOWER_BOUND) {
|
||||
probe_timeout_duration_us = CONFIG_GNRC_TCP_PROBE_LOWER_BOUND;
|
||||
if (probe_timeout_duration_ms < CONFIG_GNRC_TCP_PROBE_LOWER_BOUND_MS) {
|
||||
probe_timeout_duration_ms = CONFIG_GNRC_TCP_PROBE_LOWER_BOUND_MS;
|
||||
}
|
||||
else if (probe_timeout_duration_us > CONFIG_GNRC_TCP_PROBE_UPPER_BOUND) {
|
||||
probe_timeout_duration_us = CONFIG_GNRC_TCP_PROBE_UPPER_BOUND;
|
||||
else if (probe_timeout_duration_ms > CONFIG_GNRC_TCP_PROBE_UPPER_BOUND_MS) {
|
||||
probe_timeout_duration_ms = CONFIG_GNRC_TCP_PROBE_UPPER_BOUND_MS;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -556,13 +524,13 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
|
||||
DEBUG("gnrc_tcp.c : gnrc_tcp_send() : NOTIFY_USER\n");
|
||||
|
||||
/* Connection is alive: Reset Connection Timeout */
|
||||
_setup_timeout(&(tcb->timer_misc), CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION,
|
||||
_cb_mbox_put_msg, &connection_timeout_arg);
|
||||
_unsched_mbox(&tcb->event_misc);
|
||||
_sched_connection_timeout(&tcb->event_misc, &mbox);
|
||||
|
||||
/* If the window re-opened and we are probing: Stop it */
|
||||
if (tcb->snd_wnd > 0 && probing_mode) {
|
||||
probing_mode = false;
|
||||
xtimer_remove(&probe_timeout);
|
||||
_unsched_mbox(&event_probe_timeout);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -573,15 +541,15 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
|
||||
|
||||
/* Cleanup */
|
||||
_fsm_set_mbox(tcb, NULL);
|
||||
xtimer_remove(&(tcb->timer_misc));
|
||||
xtimer_remove(&probe_timeout);
|
||||
xtimer_remove(&user_timeout);
|
||||
_unsched_mbox(&tcb->event_misc);
|
||||
_unsched_mbox(&event_probe_timeout);
|
||||
_unsched_mbox(&event_user_timeout);
|
||||
mutex_unlock(&(tcb->function_lock));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
|
||||
const uint32_t timeout_duration_us)
|
||||
const uint32_t timeout_duration_ms)
|
||||
{
|
||||
assert(tcb != NULL);
|
||||
assert(data != NULL);
|
||||
@ -589,9 +557,7 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
|
||||
msg_t msg;
|
||||
msg_t msg_queue[TCP_MSG_QUEUE_SIZE];
|
||||
mbox_t mbox = MBOX_INIT(msg_queue, TCP_MSG_QUEUE_SIZE);
|
||||
cb_arg_t connection_timeout_arg = {MSG_TYPE_CONNECTION_TIMEOUT, &mbox};
|
||||
xtimer_t user_timeout;
|
||||
cb_arg_t user_timeout_arg = {MSG_TYPE_USER_SPEC_TIMEOUT, &mbox};
|
||||
evtimer_mbox_event_t event_user_timeout;
|
||||
ssize_t ret = 0;
|
||||
|
||||
/* Lock the TCB for this function call */
|
||||
@ -612,8 +578,8 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If this call is non-blocking (timeout_duration_us == 0): Try to read data and return */
|
||||
if (timeout_duration_us == 0) {
|
||||
/* If this call is non-blocking (timeout_duration_ms == 0): Try to read data and return */
|
||||
if (timeout_duration_ms == 0) {
|
||||
ret = _fsm(tcb, FSM_EVENT_CALL_RECV, NULL, data, max_len);
|
||||
if (ret == 0) {
|
||||
ret = -EAGAIN;
|
||||
@ -625,10 +591,13 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
|
||||
/* Setup messaging */
|
||||
_fsm_set_mbox(tcb, &mbox);
|
||||
|
||||
/* Setup connection timeout: Put timeout message in tcb's mbox on expiration */
|
||||
_setup_timeout(&(tcb->timer_misc), CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION,
|
||||
_cb_mbox_put_msg, &connection_timeout_arg);
|
||||
_setup_timeout(&user_timeout, timeout_duration_us, _cb_mbox_put_msg, &user_timeout_arg);
|
||||
/* Setup connection timeout */
|
||||
_sched_connection_timeout(&tcb->event_misc, &mbox);
|
||||
|
||||
if (timeout_duration_ms > 0) {
|
||||
_sched_mbox(&event_user_timeout, timeout_duration_ms,
|
||||
MSG_TYPE_USER_SPEC_TIMEOUT, &mbox);
|
||||
}
|
||||
|
||||
/* Processing loop */
|
||||
while (ret == 0) {
|
||||
@ -674,8 +643,8 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
|
||||
|
||||
/* Cleanup */
|
||||
_fsm_set_mbox(tcb, NULL);
|
||||
xtimer_remove(&(tcb->timer_misc));
|
||||
xtimer_remove(&user_timeout);
|
||||
_unsched_mbox(&tcb->event_misc);
|
||||
_unsched_mbox(&event_user_timeout);
|
||||
mutex_unlock(&(tcb->function_lock));
|
||||
return ret;
|
||||
}
|
||||
@ -687,7 +656,6 @@ void gnrc_tcp_close(gnrc_tcp_tcb_t *tcb)
|
||||
msg_t msg;
|
||||
msg_t msg_queue[TCP_MSG_QUEUE_SIZE];
|
||||
mbox_t mbox = MBOX_INIT(msg_queue, TCP_MSG_QUEUE_SIZE);
|
||||
cb_arg_t connection_timeout_arg = {MSG_TYPE_CONNECTION_TIMEOUT, &mbox};
|
||||
|
||||
/* Lock the TCB for this function call */
|
||||
mutex_lock(&(tcb->function_lock));
|
||||
@ -701,9 +669,8 @@ void gnrc_tcp_close(gnrc_tcp_tcb_t *tcb)
|
||||
/* Setup messaging */
|
||||
_fsm_set_mbox(tcb, &mbox);
|
||||
|
||||
/* Setup connection timeout: Put timeout message in tcb's mbox on expiration */
|
||||
_setup_timeout(&(tcb->timer_misc), CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION,
|
||||
_cb_mbox_put_msg, &connection_timeout_arg);
|
||||
/* Setup connection timeout */
|
||||
_sched_connection_timeout(&tcb->event_misc, &mbox);
|
||||
|
||||
/* Start connection teardown sequence */
|
||||
_fsm(tcb, FSM_EVENT_CALL_CLOSE, NULL, NULL, 0);
|
||||
@ -728,7 +695,7 @@ void gnrc_tcp_close(gnrc_tcp_tcb_t *tcb)
|
||||
|
||||
/* Cleanup */
|
||||
_fsm_set_mbox(tcb, NULL);
|
||||
xtimer_remove(&(tcb->timer_misc));
|
||||
_unsched_mbox(&tcb->event_misc);
|
||||
mutex_unlock(&(tcb->function_lock));
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,39 @@
|
||||
|
||||
static msg_t _eventloop_msg_queue[TCP_EVENTLOOP_MSG_QUEUE_SIZE];
|
||||
|
||||
/**
|
||||
* @brief Allocate memory for GNRC TCP thread stack.
|
||||
*/
|
||||
#if ENABLE_DEBUG
|
||||
static char _stack[TCP_EVENTLOOP_STACK_SIZE + THREAD_EXTRA_STACKSIZE_PRINTF];
|
||||
#else
|
||||
static char _stack[TCP_EVENTLOOP_STACK_SIZE];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Central evtimer for gnrc_tcp event loop
|
||||
*/
|
||||
static evtimer_t _tcp_msg_timer;
|
||||
|
||||
/**
|
||||
* @brief TCPs eventloop pid
|
||||
*/
|
||||
static kernel_pid_t _tcp_eventloop_pid = KERNEL_PID_UNDEF;
|
||||
|
||||
void _gnrc_tcp_event_loop_sched(evtimer_msg_event_t *event, uint32_t offset,
|
||||
uint16_t type, void *context)
|
||||
{
|
||||
event->event.offset = offset;
|
||||
event->msg.type = type;
|
||||
event->msg.content.ptr = context;
|
||||
evtimer_add_msg(&_tcp_msg_timer, event, _tcp_eventloop_pid);
|
||||
}
|
||||
|
||||
void _gnrc_tcp_event_loop_unsched(evtimer_msg_event_t *event)
|
||||
{
|
||||
evtimer_del(&_tcp_msg_timer, (evtimer_event_t *)event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send function, pass packet down the network stack.
|
||||
*
|
||||
@ -220,6 +253,9 @@ static int _receive(gnrc_pktsnip_t *pkt)
|
||||
mutex_unlock(&_list_tcb_lock);
|
||||
|
||||
/* Call FSM with event RCVD_PKT if a fitting TCB was found */
|
||||
/* cppcheck-suppress knownConditionTrueFalse
|
||||
* (reason: tcb can be NULL at runtime)
|
||||
*/
|
||||
if (tcb != NULL) {
|
||||
_fsm(tcb, FSM_EVENT_RCVD_PKT, pkt, NULL, 0);
|
||||
}
|
||||
@ -228,7 +264,7 @@ static int _receive(gnrc_pktsnip_t *pkt)
|
||||
DEBUG("gnrc_tcp_eventloop.c : _receive() : Can't find fitting tcb\n");
|
||||
if ((ctl & MSK_RST) != MSK_RST) {
|
||||
_pkt_build_reset_from_pkt(&reset, pkt);
|
||||
if (gnrc_netapi_send(gnrc_tcp_pid, reset) < 1) {
|
||||
if (gnrc_netapi_send(_tcp_eventloop_pid, reset) < 1) {
|
||||
DEBUG("gnrc_tcp_eventloop.c : _receive() : unable to send reset packet\n");
|
||||
gnrc_pktbuf_release(reset);
|
||||
}
|
||||
@ -240,13 +276,13 @@ static int _receive(gnrc_pktsnip_t *pkt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *_event_loop(__attribute__((unused)) void *arg)
|
||||
static void *_event_loop(__attribute__((unused)) void *arg)
|
||||
{
|
||||
msg_t msg;
|
||||
msg_t reply;
|
||||
|
||||
/* Store pid */
|
||||
gnrc_tcp_pid = thread_getpid();
|
||||
_tcp_eventloop_pid = thread_getpid();
|
||||
|
||||
/* Setup reply message */
|
||||
reply.type = GNRC_NETAPI_MSG_TYPE_ACK;
|
||||
@ -257,7 +293,7 @@ void *_event_loop(__attribute__((unused)) void *arg)
|
||||
|
||||
/* Register GNRC TCPs handling thread in netreg */
|
||||
gnrc_netreg_entry_t entry;
|
||||
gnrc_netreg_entry_init_pid(&entry, GNRC_NETREG_DEMUX_CTX_ALL, gnrc_tcp_pid);
|
||||
gnrc_netreg_entry_init_pid(&entry, GNRC_NETREG_DEMUX_CTX_ALL, _tcp_eventloop_pid);
|
||||
gnrc_netreg_register(GNRC_NETTYPE_TCP, &entry);
|
||||
|
||||
/* dispatch NETAPI messages */
|
||||
@ -303,3 +339,18 @@ void *_event_loop(__attribute__((unused)) void *arg)
|
||||
/* Never reached */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int _gnrc_tcp_event_loop_init(void)
|
||||
{
|
||||
/* Guard: Check if thread is already running */
|
||||
if (_tcp_eventloop_pid != KERNEL_PID_UNDEF) {
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
/* Initialize timers */
|
||||
evtimer_init_msg(&_tcp_msg_timer);
|
||||
|
||||
return thread_create(_stack, sizeof(_stack), TCP_EVENTLOOP_PRIO,
|
||||
THREAD_CREATE_STACKTEST, _event_loop, NULL,
|
||||
"gnrc_tcp");
|
||||
}
|
||||
|
@ -22,7 +22,10 @@
|
||||
#include "random.h"
|
||||
#include "net/af.h"
|
||||
#include "net/gnrc.h"
|
||||
#include "evtimer.h"
|
||||
#include "evtimer_msg.h"
|
||||
#include "internal/common.h"
|
||||
#include "internal/eventloop.h"
|
||||
#include "internal/pkt.h"
|
||||
#include "internal/option.h"
|
||||
#include "internal/rcvbuf.h"
|
||||
@ -84,8 +87,8 @@ static uint16_t _get_random_local_port(void)
|
||||
static int _clear_retransmit(gnrc_tcp_tcb_t *tcb)
|
||||
{
|
||||
if (tcb->pkt_retransmit != NULL) {
|
||||
_gnrc_tcp_event_loop_unsched(&tcb->event_retransmit);
|
||||
gnrc_pktbuf_release(tcb->pkt_retransmit);
|
||||
xtimer_remove(&(tcb->timer_retransmit));
|
||||
tcb->pkt_retransmit = NULL;
|
||||
}
|
||||
return 0;
|
||||
@ -100,11 +103,9 @@ static int _clear_retransmit(gnrc_tcp_tcb_t *tcb)
|
||||
*/
|
||||
static int _restart_timewait_timer(gnrc_tcp_tcb_t *tcb)
|
||||
{
|
||||
xtimer_remove(&tcb->timer_retransmit);
|
||||
tcb->msg_retransmit.type = MSG_TYPE_TIMEWAIT;
|
||||
tcb->msg_retransmit.content.ptr = (void *)tcb;
|
||||
xtimer_set_msg(&(tcb->timer_retransmit), 2 * CONFIG_GNRC_TCP_MSL, &(tcb->msg_retransmit),
|
||||
gnrc_tcp_pid);
|
||||
_gnrc_tcp_event_loop_unsched(&tcb->event_retransmit);
|
||||
_gnrc_tcp_event_loop_sched(&tcb->event_retransmit, 2 * CONFIG_GNRC_TCP_MSL_MS,
|
||||
MSG_TYPE_TIMEWAIT, tcb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -20,9 +20,12 @@
|
||||
#include <utlist.h>
|
||||
#include <errno.h>
|
||||
#include "byteorder.h"
|
||||
#include "evtimer.h"
|
||||
#include "evtimer_msg.h"
|
||||
#include "net/inet_csum.h"
|
||||
#include "net/gnrc.h"
|
||||
#include "internal/common.h"
|
||||
#include "internal/eventloop.h"
|
||||
#include "internal/option.h"
|
||||
#include "internal/pkt.h"
|
||||
|
||||
@ -271,14 +274,15 @@ int _pkt_send(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *out_pkt, const uint16_t seq_c
|
||||
if (!retransmit) {
|
||||
tcb->retries = 0;
|
||||
tcb->snd_nxt += seq_con;
|
||||
tcb->rtt_start = xtimer_now().ticks32;
|
||||
tcb->rtt_start = evtimer_now_msec();
|
||||
}
|
||||
else {
|
||||
tcb->retries += 1;
|
||||
}
|
||||
|
||||
/* Pass packet down the network stack */
|
||||
if (gnrc_netapi_send(gnrc_tcp_pid, out_pkt) < 1) {
|
||||
if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_TCP, GNRC_NETREG_DEMUX_CTX_ALL,
|
||||
out_pkt)) {
|
||||
DEBUG("gnrc_tcp_pkt.c : _pkt_send() : unable to send packet\n");
|
||||
gnrc_pktbuf_release(out_pkt);
|
||||
}
|
||||
@ -385,10 +389,11 @@ int _pkt_setup_retransmit(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *pkt, const bool r
|
||||
if (!retransmit) {
|
||||
/* If this is the first transmission: rto is 1 sec (Lower Bound) */
|
||||
if (tcb->srtt == RTO_UNINITIALIZED || tcb->rtt_var == RTO_UNINITIALIZED) {
|
||||
tcb->rto = CONFIG_GNRC_TCP_RTO_LOWER_BOUND;
|
||||
tcb->rto = CONFIG_GNRC_TCP_RTO_LOWER_BOUND_MS;
|
||||
}
|
||||
else {
|
||||
tcb->rto = tcb->srtt + _max(CONFIG_GNRC_TCP_RTO_GRANULARITY, CONFIG_GNRC_TCP_RTO_K * tcb->rtt_var);
|
||||
tcb->rto = tcb->srtt + _max(CONFIG_GNRC_TCP_RTO_GRANULARITY_MS,
|
||||
CONFIG_GNRC_TCP_RTO_K * tcb->rtt_var);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -404,17 +409,16 @@ int _pkt_setup_retransmit(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *pkt, const bool r
|
||||
}
|
||||
|
||||
/* Perform boundary checks on current RTO before usage */
|
||||
if (tcb->rto < (int32_t) CONFIG_GNRC_TCP_RTO_LOWER_BOUND) {
|
||||
tcb->rto = CONFIG_GNRC_TCP_RTO_LOWER_BOUND;
|
||||
if (tcb->rto < (int32_t) CONFIG_GNRC_TCP_RTO_LOWER_BOUND_MS) {
|
||||
tcb->rto = CONFIG_GNRC_TCP_RTO_LOWER_BOUND_MS;
|
||||
}
|
||||
else if (tcb->rto > (int32_t) CONFIG_GNRC_TCP_RTO_UPPER_BOUND) {
|
||||
tcb->rto = CONFIG_GNRC_TCP_RTO_UPPER_BOUND;
|
||||
else if (tcb->rto > (int32_t) CONFIG_GNRC_TCP_RTO_UPPER_BOUND_MS) {
|
||||
tcb->rto = CONFIG_GNRC_TCP_RTO_UPPER_BOUND_MS;
|
||||
}
|
||||
|
||||
/* Setup retransmission timer, msg to TCP thread with ptr to TCB */
|
||||
tcb->msg_retransmit.type = MSG_TYPE_RETRANSMISSION;
|
||||
tcb->msg_retransmit.content.ptr = (void *) tcb;
|
||||
xtimer_set_msg(&tcb->timer_retransmit, tcb->rto, &tcb->msg_retransmit, gnrc_tcp_pid);
|
||||
_gnrc_tcp_event_loop_sched(&tcb->event_retransmit, tcb->rto,
|
||||
MSG_TYPE_RETRANSMISSION, tcb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -438,12 +442,12 @@ int _pkt_acknowledge(gnrc_tcp_tcb_t *tcb, const uint32_t ack)
|
||||
|
||||
/* If segment can be acknowledged -> stop timer, release packet from pktbuf and update rto. */
|
||||
if (LSS_32_BIT(seg, ack)) {
|
||||
xtimer_remove(&(tcb->timer_retransmit));
|
||||
_gnrc_tcp_event_loop_unsched(&tcb->event_retransmit);
|
||||
gnrc_pktbuf_release(tcb->pkt_retransmit);
|
||||
tcb->pkt_retransmit = NULL;
|
||||
|
||||
/* Measure round trip time */
|
||||
int32_t rtt = xtimer_now().ticks32 - tcb->rtt_start;
|
||||
int32_t rtt = evtimer_now_msec() - tcb->rtt_start;
|
||||
|
||||
/* Use time only if there was no timer overflow and no retransmission (Karns Algorithm) */
|
||||
if (tcb->retries == 0 && rtt > 0) {
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "kernel_types.h"
|
||||
#include "thread.h"
|
||||
#include "mutex.h"
|
||||
#include "evtimer.h"
|
||||
#include "net/gnrc/netapi.h"
|
||||
#include "net/gnrc/tcp/tcb.h"
|
||||
|
||||
@ -113,11 +114,6 @@ extern "C" {
|
||||
*/
|
||||
#define GET_OFFSET( x ) (((x) & MSK_OFFSET) >> 12)
|
||||
|
||||
/**
|
||||
* @brief PID of GNRC TCP event handling thread
|
||||
*/
|
||||
extern kernel_pid_t gnrc_tcp_pid;
|
||||
|
||||
/**
|
||||
* @brief Head of linked TCB list.
|
||||
*/
|
||||
|
@ -20,18 +20,43 @@
|
||||
#ifndef EVENTLOOP_H
|
||||
#define EVENTLOOP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "evtimer_msg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GNRC TCPs main processing thread.
|
||||
* @brief Starts GNRC TCP's main processing thread.
|
||||
*
|
||||
* @param[in] arg Thread arguments (unused).
|
||||
*
|
||||
* @returns Never, its an endless loop
|
||||
* @retval PID of processing thread on success
|
||||
* @retval -EEXIST if processing thread was already started
|
||||
* @retval see @ref thread_create() for more error cases.
|
||||
*/
|
||||
void *_event_loop(__attribute__((unused)) void *arg);
|
||||
int _gnrc_tcp_event_loop_init(void);
|
||||
|
||||
/**
|
||||
* @brief Schedule event to event loop
|
||||
*
|
||||
* @param[in] event The event to schedule
|
||||
* @param[in] offset Offset in milliseconds when the event should be handled
|
||||
* in the event loop
|
||||
* @param[in] type Type of the message for the event
|
||||
* @param[in] context Context of the event.
|
||||
*/
|
||||
void _gnrc_tcp_event_loop_sched(evtimer_msg_event_t *event, uint32_t offset,
|
||||
uint16_t type, void *context);
|
||||
|
||||
/**
|
||||
* @brief Unschedule event to event loop
|
||||
*
|
||||
* Does nothing if @p event was not scheduled.
|
||||
*
|
||||
* @param[in] event The event to unschedule
|
||||
*/
|
||||
void _gnrc_tcp_event_loop_unsched(evtimer_msg_event_t *event);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ BOARD ?= native
|
||||
TAP ?= tap0
|
||||
|
||||
# Shorten default TCP timeouts to speedup testing
|
||||
MSL_US ?= 1000000
|
||||
TIMEOUT_US ?= 3000000
|
||||
MSL_MS ?= 1000
|
||||
TIMEOUT_MS ?= 3000
|
||||
|
||||
# This test depends on tap device setup (only allowed by root)
|
||||
# Suppress test execution to avoid CI errors
|
||||
@ -45,12 +45,12 @@ ethos:
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
|
||||
# Set CONFIG_GNRC_TCP_MSL via CFLAGS if not being set via Kconfig
|
||||
ifndef CONFIG_GNRC_TCP_MSL
|
||||
CFLAGS += -DCONFIG_GNRC_TCP_MSL=$(MSL_US)
|
||||
ifndef CONFIG_GNRC_TCP_MSL_MS
|
||||
CFLAGS += -DCONFIG_GNRC_TCP_MSL_MS=$(MSL_MS)
|
||||
endif
|
||||
|
||||
# Set CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION via CFLAGS if not being set
|
||||
# via Kconfig
|
||||
ifndef CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION
|
||||
CFLAGS += -DCONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION=$(TIMEOUT_US)
|
||||
ifndef CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION_MS
|
||||
CFLAGS += -DCONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION_MS=$(TIMEOUT_MS)
|
||||
endif
|
||||
|
Loading…
Reference in New Issue
Block a user