1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/sys/net/destiny/tcp_timer.c

157 lines
4.6 KiB
C
Raw Normal View History

2013-06-22 17:58:19 +02:00
/**
* Destiny TCP timer implementation
*
2013-06-22 17:58:19 +02:00
* Copyright (C) 2013 INRIA.
*
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*
* @ingroup destiny
* @{
* @file tcp_timer.c
* @brief TCP timer
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @}
*/
2013-06-22 17:58:19 +02:00
#include <thread.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "tcp_timer.h"
#include "vtimer.h"
#include "thread.h"
#include "destiny.h"
#include "socket.h"
#include "net_help/msg_help.h"
2013-05-22 16:54:20 +02:00
#include "../sixlowpan/sixlowpan.h"
void handle_synchro_timeout(socket_internal_t *current_socket)
2013-06-22 17:58:19 +02:00
{
msg_t send;
if (thread_getstatus(current_socket->recv_pid) == STATUS_RECEIVE_BLOCKED) {
2013-06-22 17:58:19 +02:00
timex_t now;
vtimer_now(&now);
if ((current_socket->socket_values.tcp_control.no_of_retries == 0) &&
2013-06-22 17:58:19 +02:00
(timex_sub(now,
current_socket->socket_values.tcp_control.last_packet_time).microseconds >
TCP_SYN_INITIAL_TIMEOUT)) {
current_socket->socket_values.tcp_control.no_of_retries++;
net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY);
}
else if ((current_socket->socket_values.tcp_control.no_of_retries > 0) &&
2013-06-22 17:58:19 +02:00
(timex_sub(now,
current_socket->socket_values.tcp_control.last_packet_time).microseconds >
(current_socket->socket_values.tcp_control.no_of_retries *
TCP_SYN_TIMEOUT + TCP_SYN_INITIAL_TIMEOUT))) {
current_socket->socket_values.tcp_control.no_of_retries++;
if (current_socket->socket_values.tcp_control.no_of_retries >
2013-06-22 17:58:19 +02:00
TCP_MAX_SYN_RETRIES) {
net_msg_send(&send, current_socket->recv_pid, 0, TCP_TIMEOUT);
}
else {
net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY);
}
}
}
}
void handle_established(socket_internal_t *current_socket)
2013-06-22 17:58:19 +02:00
{
msg_t send;
double current_timeout = current_socket->socket_values.tcp_control.rto;
if (current_timeout < SECOND) {
2013-06-22 17:58:19 +02:00
current_timeout = SECOND;
}
uint8_t i;
if ((current_socket->socket_values.tcp_control.send_nxt >
2013-06-22 17:58:19 +02:00
current_socket->socket_values.tcp_control.send_una) &&
(thread_getstatus(current_socket->send_pid) == STATUS_RECEIVE_BLOCKED)) {
for (i = 0; i < current_socket->socket_values.tcp_control.no_of_retries;
2013-06-22 17:58:19 +02:00
i++) {
current_timeout *= 2;
}
timex_t now;
vtimer_now(&now);
if (current_timeout > TCP_ACK_MAX_TIMEOUT) {
2013-06-22 17:58:19 +02:00
net_msg_send(&send, current_socket->send_pid, 0, TCP_TIMEOUT);
}
else if (timex_sub(now, current_socket->socket_values.tcp_control.last_packet_time).microseconds >
2013-06-22 17:58:19 +02:00
current_timeout) {
current_socket->socket_values.tcp_control.no_of_retries++;
net_msg_send(&send, current_socket->send_pid, 0, TCP_RETRY);
}
}
}
void check_sockets(void)
2013-06-22 17:58:19 +02:00
{
socket_internal_t *current_socket;
uint8_t i = 1;
while (i < MAX_SOCKETS + 1) {
2013-06-22 17:58:19 +02:00
current_socket = getSocket(i);
if (isTCPSocket(i)) {
2013-06-22 17:58:19 +02:00
switch(current_socket->socket_values.tcp_control.state) {
case ESTABLISHED: {
handle_established(current_socket);
break;
}
case SYN_SENT: {
handle_synchro_timeout(current_socket);
break;
}
case SYN_RCVD: {
handle_synchro_timeout(current_socket);
break;
}
default: {
break;
}
}
}
i++;
}
}
void inc_global_variables(void)
2013-06-22 17:58:19 +02:00
{
mutex_lock(&global_sequence_clunter_mutex);
global_sequence_counter += rand();
mutex_unlock(&global_sequence_clunter_mutex);
#ifdef TCP_HC
2013-06-22 17:58:19 +02:00
mutex_lock(&global_context_counter_mutex);
global_context_counter += rand();
mutex_unlock(&global_context_counter_mutex);
#endif
2013-06-22 17:58:19 +02:00
}
void tcp_general_timer(void)
2013-06-22 17:58:19 +02:00
{
vtimer_t tcp_vtimer;
timex_t interval = timex_set(0, TCP_TIMER_RESOLUTION);
while (1) {
2013-06-22 17:58:19 +02:00
inc_global_variables();
check_sockets();
vtimer_set_wakeup(&tcp_vtimer, interval, thread_getpid());
thread_sleep();
}
}