1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

gnrc_tcp: cleanup: removed internal fsm structs from public headers

This commit is contained in:
Simon Brummer 2017-02-01 15:43:16 +01:00
parent 67ed2a0ad8
commit bc0bf3bc4f
6 changed files with 145 additions and 181 deletions

View File

@ -1,68 +0,0 @@
/*
* Copyright (C) 2015 Simon Brummer
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_gnrc_tcp TCP
* @ingroup net_gnrc
* @brief RIOT's tcp implementation for the gnrc stack
*
* @{
*
* @file
* @brief Definies states and events for TCP finite state maschine
*
* @author Simon Brummer <brummer.simon@googlemail.com>
*/
#ifndef GNRC_TCP_FSM_H_
#define GNRC_TCP_FSM_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief The TCP FSM States.
*/
typedef enum {
GNRC_TCP_FSM_STATE_CLOSED,
GNRC_TCP_FSM_STATE_LISTEN,
GNRC_TCP_FSM_STATE_SYN_SENT,
GNRC_TCP_FSM_STATE_SYN_RCVD,
GNRC_TCP_FSM_STATE_ESTABLISHED,
GNRC_TCP_FSM_STATE_CLOSE_WAIT,
GNRC_TCP_FSM_STATE_LAST_ACK,
GNRC_TCP_FSM_STATE_FIN_WAIT_1,
GNRC_TCP_FSM_STATE_FIN_WAIT_2,
GNRC_TCP_FSM_STATE_CLOSING,
GNRC_TCP_FSM_STATE_TIME_WAIT
} gnrc_tcp_fsm_state_t;
/**
* @brief Events that trigger translations in TCP FSM.
*/
typedef enum {
GNRC_TCP_FSM_EVENT_CALL_OPEN, /* User function call: open */
GNRC_TCP_FSM_EVENT_CALL_SEND, /* User function call: send */
GNRC_TCP_FSM_EVENT_CALL_RECV, /* User function call: recv */
GNRC_TCP_FSM_EVENT_CALL_CLOSE, /* User function call: close */
GNRC_TCP_FSM_EVENT_CALL_ABORT, /* User function call: abort */
GNRC_TCP_FSM_EVENT_RCVD_PKT, /* Paket received from peer */
GNRC_TCP_FSM_EVENT_TIMEOUT_TIMEWAIT, /* Timeout: Timewait */
GNRC_TCP_FSM_EVENT_TIMEOUT_RETRANSMIT, /* Timeout: Retransmit */
GNRC_TCP_FSM_EVENT_TIMEOUT_CONNECTION, /* Timeout: Connection */
GNRC_TCP_FSM_EVENT_SEND_PROBE, /* Send a Zero Window Probe */
GNRC_TCP_FSM_EVENT_CLEAR_RETRANSMIT /* Clear Retransmission Mechanism */
} gnrc_tcp_fsm_event_t;
#ifdef __cplusplus
}
#endif
#endif /* GNRC_TCP_FSM_H_ */
/** @} */

View File

@ -28,7 +28,6 @@
#include <mutex.h>
#include <msg.h>
#include "net/gnrc.h"
#include "fsm.h"
#include "config.h"
#ifdef MODULE_GNRC_IPV6
@ -55,7 +54,7 @@ typedef struct _transmission_control_block {
#endif
uint16_t local_port; /**< local connections port number */
uint16_t peer_port; /**< port connections port number */
gnrc_tcp_fsm_state_t state; /**< Connections state */
uint8_t state; /**< Connections state */
uint8_t status; /**< A connections status flags */
uint32_t snd_una; /**< Send Unacknowledged */
uint32_t snd_nxt; /**< Send Next */

View File

@ -103,7 +103,7 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const uint8_t *target_addr, uint1
mutex_lock(&(tcb->function_lock));
/* Connection is already connected: Return -EISCONN */
if (tcb->state != GNRC_TCP_FSM_STATE_CLOSED) {
if (tcb->state != FSM_STATE_CLOSED) {
mutex_unlock(&(tcb->function_lock));
return -EISCONN;
}
@ -156,7 +156,7 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const uint8_t *target_addr, uint1
}
/* Call FSM with Event: CALL_OPEN */
ret = _fsm(tcb, GNRC_TCP_FSM_EVENT_CALL_OPEN, NULL, NULL, 0);
ret = _fsm(tcb, FSM_EVENT_CALL_OPEN, NULL, NULL, 0);
if (ret == -ENOMEM) {
DEBUG("gnrc_tcp.c : gnrc_tcp_connect() : Out of receive buffers.\n");
} else if(ret == -EADDRINUSE) {
@ -164,15 +164,15 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const uint8_t *target_addr, uint1
}
/* Wait until a connection was established or closed */
while (ret >= 0 && tcb->state != GNRC_TCP_FSM_STATE_CLOSED
&& tcb->state != GNRC_TCP_FSM_STATE_ESTABLISHED
&& tcb->state != GNRC_TCP_FSM_STATE_CLOSE_WAIT
while (ret >= 0 && tcb->state != FSM_STATE_CLOSED
&& tcb->state != FSM_STATE_ESTABLISHED
&& tcb->state != FSM_STATE_CLOSE_WAIT
) {
msg_receive(&msg);
switch (msg.type) {
case MSG_TYPE_CONNECTION_TIMEOUT:
DEBUG("gnrc_tcp.c : _gnrc_tcp_open() : CONNECTION_TIMEOUT\n");
_fsm(tcb, GNRC_TCP_FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0);
_fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0);
ret = -ETIMEDOUT;
break;
@ -187,7 +187,7 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const uint8_t *target_addr, uint1
/* Cleanup */
xtimer_remove(&connection_timeout_timer);
if (tcb->state == GNRC_TCP_FSM_STATE_CLOSED && ret == 0) {
if (tcb->state == FSM_STATE_CLOSED && ret == 0) {
ret = -ECONNREFUSED;
}
tcb->owner = KERNEL_PID_UNDEF;
@ -229,7 +229,7 @@ void gnrc_tcp_tcb_init(gnrc_tcp_tcb_t* tcb)
#endif
tcb->local_port = PORT_UNSPEC;
tcb->peer_port = PORT_UNSPEC;
tcb->state = GNRC_TCP_FSM_STATE_CLOSED;
tcb->state = FSM_STATE_CLOSED;
tcb->status = 0;
tcb->snd_una = 0;
tcb->snd_nxt = 0;
@ -323,8 +323,8 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
mutex_lock(&(tcb->function_lock));
/* Check if connection is in a valid state */
if (tcb->state != GNRC_TCP_FSM_STATE_ESTABLISHED
&& tcb->state != GNRC_TCP_FSM_STATE_CLOSE_WAIT
if (tcb->state != FSM_STATE_ESTABLISHED
&& tcb->state != FSM_STATE_CLOSE_WAIT
) {
mutex_unlock(&(tcb->function_lock));
return -ENOTCONN;
@ -348,7 +348,7 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
/* Loop until something was sent and acked */
while (ret == 0 || tcb->pkt_retransmit != NULL) {
/* Check if the connections state is closed. If so, a reset was received */
if (tcb->state == GNRC_TCP_FSM_STATE_CLOSED) {
if (tcb->state == FSM_STATE_CLOSED) {
ret = -ECONNRESET;
break;
}
@ -368,7 +368,7 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
/* Try to send data in case there nothing has been sent and we are not probing */
if (ret == 0 && !probing) {
ret = _fsm(tcb, GNRC_TCP_FSM_EVENT_CALL_SEND, NULL, (void *) data, len);
ret = _fsm(tcb, FSM_EVENT_CALL_SEND, NULL, (void *) data, len);
}
/* Wait for responses */
@ -376,20 +376,20 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
switch (msg.type) {
case MSG_TYPE_CONNECTION_TIMEOUT:
DEBUG("gnrc_tcp.c : gnrc_tcp_send() : CONNECTION_TIMEOUT\n");
_fsm(tcb, GNRC_TCP_FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0);
_fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0);
ret = -ECONNABORTED;
break;
case MSG_TYPE_USER_SPEC_TIMEOUT:
DEBUG("gnrc_tcp.c : gnrc_tcp_send() : USER_SPEC_TIMEOUT\n");
_fsm(tcb, GNRC_TCP_FSM_EVENT_CLEAR_RETRANSMIT, NULL, NULL, 0);
_fsm(tcb, FSM_EVENT_CLEAR_RETRANSMIT, NULL, NULL, 0);
ret = -ETIMEDOUT;
break;
case MSG_TYPE_PROBE_TIMEOUT:
DEBUG("gnrc_tcp.c : gnrc_tcp_send() : PROBE_TIMEOUT\n");
/* Send Probe */
_fsm(tcb, GNRC_TCP_FSM_EVENT_SEND_PROBE, NULL, NULL, 0);
_fsm(tcb, FSM_EVENT_SEND_PROBE, NULL, NULL, 0);
probe_timeout_duration_us += probe_timeout_duration_us;
/* Boundry check for time interval between probes */
@ -445,10 +445,10 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
mutex_lock(&(tcb->function_lock));
/* Check if connection is in a valid state */
if (tcb->state != GNRC_TCP_FSM_STATE_ESTABLISHED
&& tcb->state != GNRC_TCP_FSM_STATE_FIN_WAIT_1
&& tcb->state != GNRC_TCP_FSM_STATE_FIN_WAIT_2
&& tcb->state != GNRC_TCP_FSM_STATE_CLOSE_WAIT
if (tcb->state != FSM_STATE_ESTABLISHED
&& tcb->state != FSM_STATE_FIN_WAIT_1
&& tcb->state != FSM_STATE_FIN_WAIT_2
&& tcb->state != FSM_STATE_CLOSE_WAIT
) {
mutex_unlock(&(tcb->function_lock));
return -ENOTCONN;
@ -456,7 +456,7 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
/* If this call is non-blocking (timeout_duration_us == 0): Try to read data and return */
if (timeout_duration_us == 0) {
ret = _fsm(tcb, GNRC_TCP_FSM_EVENT_CALL_RECV, NULL, data, max_len);
ret = _fsm(tcb, FSM_EVENT_CALL_RECV, NULL, data, max_len);
if(ret == 0) {
ret = -EAGAIN;
}
@ -480,13 +480,13 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
/* Processing Loop */
while (ret == 0) {
/* Check if the connections state is closed. If so, a reset was received */
if (tcb->state == GNRC_TCP_FSM_STATE_CLOSED) {
if (tcb->state == FSM_STATE_CLOSED) {
ret = -ECONNRESET;
break;
}
/* Try to read available data */
ret = _fsm(tcb, GNRC_TCP_FSM_EVENT_CALL_RECV, NULL, data, max_len);
ret = _fsm(tcb, FSM_EVENT_CALL_RECV, NULL, data, max_len);
/* If there was no data: Wait for next packet or until the timeout fires */
if (ret <= 0) {
@ -494,13 +494,13 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
switch (msg.type) {
case MSG_TYPE_CONNECTION_TIMEOUT:
DEBUG("gnrc_tcp.c : gnrc_tcp_recv() : CONNECTION_TIMEOUT\n");
_fsm(tcb, GNRC_TCP_FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0);
_fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0);
ret = -ECONNABORTED;
break;
case MSG_TYPE_USER_SPEC_TIMEOUT:
DEBUG("gnrc_tcp.c : gnrc_tcp_send() : USER_SPEC_TIMEOUT\n");
_fsm(tcb, GNRC_TCP_FSM_EVENT_CLEAR_RETRANSMIT, NULL, NULL, 0);
_fsm(tcb, FSM_EVENT_CLEAR_RETRANSMIT, NULL, NULL, 0);
ret = -ETIMEDOUT;
break;
@ -534,7 +534,7 @@ int gnrc_tcp_close(gnrc_tcp_tcb_t *tcb)
mutex_lock(&(tcb->function_lock));
/* Start connection teardown if the connection was not closed before */
if (tcb->state != GNRC_TCP_FSM_STATE_CLOSED) {
if (tcb->state != FSM_STATE_CLOSED) {
/* Take ownership */
msg_init_queue(tcb->msg_queue, GNRC_TCP_TCB_MSG_QUEUE_SIZE);
tcb->owner = thread_getpid();
@ -545,15 +545,15 @@ int gnrc_tcp_close(gnrc_tcp_tcb_t *tcb)
&connection_timeout_msg, tcb->owner);
/* Start connection teardown sequence */
_fsm(tcb, GNRC_TCP_FSM_EVENT_CALL_CLOSE, NULL, NULL, 0);
_fsm(tcb, FSM_EVENT_CALL_CLOSE, NULL, NULL, 0);
/* Loop until the connection has been closed */
while (tcb->state != GNRC_TCP_FSM_STATE_CLOSED) {
while (tcb->state != FSM_STATE_CLOSED) {
msg_receive(&msg);
switch (msg.type) {
case MSG_TYPE_CONNECTION_TIMEOUT:
DEBUG("gnrc_tcp.c : gnrc_tcp_close() : CONNECTION_TIMEOUT\n");
_fsm(tcb, GNRC_TCP_FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0);
_fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0);
break;
case MSG_TYPE_NOTIFY_USER:

View File

@ -163,7 +163,7 @@ static int _receive(gnrc_pktsnip_t *pkt)
if (ip->type == GNRC_NETTYPE_IPV6 && tcb->address_family == AF_INET6) {
/* If SYN is set, a connection is listening on that port ... */
ipv6_addr_t * tmp_addr = NULL;
if (syn && tcb->local_port == dst && tcb->state == GNRC_TCP_FSM_STATE_LISTEN) {
if (syn && tcb->local_port == dst && tcb->state == FSM_STATE_LISTEN) {
/* ... and local addr is unspec or preconfigured */
tmp_addr = &((ipv6_hdr_t * )ip->data)->dst;
if (ipv6_addr_equal((ipv6_addr_t *) tcb->local_addr, (ipv6_addr_t *) tmp_addr)
@ -194,7 +194,7 @@ static int _receive(gnrc_pktsnip_t *pkt)
/* Call FSM with event RCVD_PKT if a fitting connection was found */
if (tcb != NULL) {
_fsm(tcb, GNRC_TCP_FSM_EVENT_RCVD_PKT, pkt, NULL, 0);
_fsm(tcb, FSM_EVENT_RCVD_PKT, pkt, NULL, 0);
}
/* No fitting connection has been found. Respond with reset */
else {
@ -255,14 +255,14 @@ void *_event_loop(__attribute__((unused)) void *arg)
/* Retransmission Timer expired -> Call FSM with retransmission event */
case MSG_TYPE_RETRANSMISSION:
DEBUG("gnrc_tcp_eventloop.c : _event_loop() : MSG_TYPE_RETRANSMISSION\n");
_fsm((gnrc_tcp_tcb_t *)msg.content.ptr, GNRC_TCP_FSM_EVENT_TIMEOUT_RETRANSMIT,
_fsm((gnrc_tcp_tcb_t *)msg.content.ptr, FSM_EVENT_TIMEOUT_RETRANSMIT,
NULL, NULL, 0);
break;
/* Time Wait Timer expired -> Call FSM with timewait event */
case MSG_TYPE_TIMEWAIT:
DEBUG("gnrc_tcp_eventloop.c : _event_loop() : MSG_TYPE_TIMEWAIT\n");
_fsm((gnrc_tcp_tcb_t *)msg.content.ptr, GNRC_TCP_FSM_EVENT_TIMEOUT_TIMEWAIT,
_fsm((gnrc_tcp_tcb_t *)msg.content.ptr, FSM_EVENT_TIMEOUT_TIMEWAIT,
NULL, NULL, 0);
break;

View File

@ -115,13 +115,13 @@ static int _restart_timewait_timer(gnrc_tcp_tcb_t* tcb)
*
* @return zero on success
*/
static int _transition_to(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_state_t state, bool *notify_owner)
static int _transition_to(gnrc_tcp_tcb_t* tcb, fsm_state_t state, bool *notify_owner)
{
gnrc_tcp_tcb_t *iter = NULL;
uint8_t found = 0;
switch (state) {
case GNRC_TCP_FSM_STATE_CLOSED:
case FSM_STATE_CLOSED:
/* Free Packets in Retransmit queue */
_clear_retransmit(tcb);
@ -142,7 +142,7 @@ static int _transition_to(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_state_t state, bool
*notify_owner = true;
break;
case GNRC_TCP_FSM_STATE_LISTEN:
case FSM_STATE_LISTEN:
/* Clear Adress Info */
switch (tcb->address_family) {
#ifdef MODULE_GNRC_IPV6
@ -177,7 +177,7 @@ static int _transition_to(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_state_t state, bool
mutex_unlock(&_list_tcb_lock);
break;
case GNRC_TCP_FSM_STATE_SYN_SENT:
case FSM_STATE_SYN_SENT:
/* Allocate rcv Buffer */
if (_rcvbuf_get_buffer(tcb) == -ENOMEM) {
return -ENOMEM;
@ -211,15 +211,15 @@ static int _transition_to(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_state_t state, bool
mutex_unlock(&_list_tcb_lock);
break;
case GNRC_TCP_FSM_STATE_ESTABLISHED:
case FSM_STATE_ESTABLISHED:
*notify_owner = true;
break;
case GNRC_TCP_FSM_STATE_CLOSE_WAIT:
case FSM_STATE_CLOSE_WAIT:
*notify_owner = true;
break;
case GNRC_TCP_FSM_STATE_TIME_WAIT:
case FSM_STATE_TIME_WAIT:
_restart_timewait_timer(tcb);
break;
@ -251,8 +251,8 @@ static int _fsm_call_open(gnrc_tcp_tcb_t* tcb, bool *notify_owner)
if (tcb->status & STATUS_PASSIVE) {
/* Passive Open, T: CLOSED -> LISTEN */
if (_transition_to(tcb, GNRC_TCP_FSM_STATE_LISTEN, notify_owner) == -ENOMEM){
_transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner);
if (_transition_to(tcb, FSM_STATE_LISTEN, notify_owner) == -ENOMEM){
_transition_to(tcb, FSM_STATE_CLOSED, notify_owner);
return -ENOMEM;
}
}
@ -263,9 +263,9 @@ static int _fsm_call_open(gnrc_tcp_tcb_t* tcb, bool *notify_owner)
tcb->snd_una = tcb->iss;
/* Translate to SYN_SENT */
ret = _transition_to(tcb, GNRC_TCP_FSM_STATE_SYN_SENT, notify_owner);
ret = _transition_to(tcb, FSM_STATE_SYN_SENT, notify_owner);
if ( ret < 0) {
_transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner);
_transition_to(tcb, FSM_STATE_CLOSED, notify_owner);
return ret;
}
@ -357,9 +357,9 @@ static int _fsm_call_close(gnrc_tcp_tcb_t* tcb, bool *notify_owner)
uint16_t seq_con = 0; /* Sequence number consumption (out_pkt) */
DEBUG("gnrc_tcp_fsm.c : _fsm_call_close()\n");
if (tcb->state == GNRC_TCP_FSM_STATE_SYN_RCVD
|| tcb->state == GNRC_TCP_FSM_STATE_ESTABLISHED
|| tcb->state == GNRC_TCP_FSM_STATE_CLOSE_WAIT
if (tcb->state == FSM_STATE_SYN_RCVD
|| tcb->state == FSM_STATE_ESTABLISHED
|| tcb->state == FSM_STATE_CLOSE_WAIT
) {
/* Send FIN packet */
_pkt_build(tcb, &out_pkt, &seq_con, MSK_FIN_ACK, tcb->snd_nxt, tcb->rcv_nxt, NULL, 0);
@ -367,17 +367,17 @@ static int _fsm_call_close(gnrc_tcp_tcb_t* tcb, bool *notify_owner)
_pkt_send(tcb, out_pkt, seq_con, false);
}
switch (tcb->state) {
case GNRC_TCP_FSM_STATE_LISTEN:
_transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner);
case FSM_STATE_LISTEN:
_transition_to(tcb, FSM_STATE_CLOSED, notify_owner);
break;
case GNRC_TCP_FSM_STATE_SYN_RCVD:
case GNRC_TCP_FSM_STATE_ESTABLISHED:
_transition_to(tcb, GNRC_TCP_FSM_STATE_FIN_WAIT_1, notify_owner);
case FSM_STATE_SYN_RCVD:
case FSM_STATE_ESTABLISHED:
_transition_to(tcb, FSM_STATE_FIN_WAIT_1, notify_owner);
break;
case GNRC_TCP_FSM_STATE_CLOSE_WAIT:
_transition_to(tcb, GNRC_TCP_FSM_STATE_LAST_ACK, notify_owner);
case FSM_STATE_CLOSE_WAIT:
_transition_to(tcb, FSM_STATE_LAST_ACK, notify_owner);
break;
default:
@ -448,7 +448,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti
#endif
/* Handle state LISTEN */
if (tcb->state == GNRC_TCP_FSM_STATE_LISTEN) {
if (tcb->state == FSM_STATE_LISTEN) {
/* 1) Check RST: if set, return */
if (ctl & MSK_RST) {
return 0;
@ -516,12 +516,12 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti
_pkt_build(tcb, &out_pkt, &seq_con, MSK_SYN_ACK, tcb->iss, tcb->rcv_nxt, NULL, 0);
_pkt_setup_retransmit(tcb, out_pkt, false);
_pkt_send(tcb, out_pkt, seq_con, false);
_transition_to(tcb, GNRC_TCP_FSM_STATE_SYN_RCVD, notify_owner);
_transition_to(tcb, FSM_STATE_SYN_RCVD, notify_owner);
}
return 0;
}
/* Handle state SYN_SENT */
else if (tcb->state == GNRC_TCP_FSM_STATE_SYN_SENT) {
else if (tcb->state == FSM_STATE_SYN_SENT) {
/* 1) Check ACK */
if (ctl & MSK_ACK) {
/* If ACK is not acceptable ...*/
@ -538,7 +538,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti
if (ctl & MSK_RST) {
/* ... and ACK: Translate to CLOSED, if not return */
if (ctl & MSK_ACK) {
_transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner);
_transition_to(tcb, FSM_STATE_CLOSED, notify_owner);
}
return 0;
}
@ -566,7 +566,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti
_pkt_build(tcb, &out_pkt, &seq_con, MSK_ACK, tcb->snd_nxt, tcb->rcv_nxt,
NULL, 0);
_pkt_send(tcb, out_pkt, seq_con, false);
_transition_to(tcb, GNRC_TCP_FSM_STATE_ESTABLISHED, notify_owner);
_transition_to(tcb, FSM_STATE_ESTABLISHED, notify_owner);
}
/* Simultaneous SYN received send SYN+ACK, T: SYN_SENT -> SYN_RCVD */
else {
@ -574,7 +574,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti
NULL, 0);
_pkt_setup_retransmit(tcb, out_pkt, false);
_pkt_send(tcb, out_pkt, seq_con, false);
_transition_to(tcb, GNRC_TCP_FSM_STATE_SYN_RCVD, notify_owner);
_transition_to(tcb, FSM_STATE_SYN_RCVD, notify_owner);
}
tcb->snd_wnd = seg_wnd;
tcb->snd_wl1 = seg_seq;
@ -599,16 +599,16 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti
/* 2) Check RST: If RST is set ... */
if (ctl & MSK_RST) {
/* .. and State is SYN_RCVD and passive Open: SYN_RCVD -> LISTEN */
if (tcb->state == GNRC_TCP_FSM_STATE_SYN_RCVD
if (tcb->state == FSM_STATE_SYN_RCVD
&& (tcb->status & STATUS_PASSIVE)
) {
if (_transition_to(tcb, GNRC_TCP_FSM_STATE_LISTEN, notify_owner) == -ENOMEM) {
_transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner);
if (_transition_to(tcb, FSM_STATE_LISTEN, notify_owner) == -ENOMEM) {
_transition_to(tcb, FSM_STATE_CLOSED, notify_owner);
return -ENOMEM;
}
}
else {
_transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner);
_transition_to(tcb, FSM_STATE_CLOSED, notify_owner);
}
return 0;
}
@ -617,7 +617,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti
/* ... send RST, seq_no = snd_nxt, ack_no = rcv_nxt */
_pkt_build(tcb, &out_pkt, &seq_con, MSK_RST, tcb->snd_nxt, tcb->rcv_nxt, NULL, 0);
_pkt_send(tcb, out_pkt, seq_con, false);
_transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner);
_transition_to(tcb, FSM_STATE_CLOSED, notify_owner);
return 0;
}
/* 4) Check ACK */
@ -625,12 +625,12 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti
return 0;
}
else {
if (tcb->state == GNRC_TCP_FSM_STATE_SYN_RCVD) {
if (tcb->state == FSM_STATE_SYN_RCVD) {
if (LSS_32_BIT(tcb->snd_una, seg_ack) && LEQ_32_BIT(seg_ack, tcb->snd_nxt)) {
tcb->snd_wnd = seg_wnd;
tcb->snd_wl1 = seg_seq;
tcb->snd_wl2 = seg_ack;
_transition_to(tcb, GNRC_TCP_FSM_STATE_ESTABLISHED, notify_owner);
_transition_to(tcb, FSM_STATE_ESTABLISHED, notify_owner);
}
else {
_pkt_build(tcb, &out_pkt, &seq_con, MSK_RST, seg_ack, 0, NULL, 0);
@ -638,12 +638,12 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti
}
}
/* Acknowledgment processing */
if (tcb->state == GNRC_TCP_FSM_STATE_ESTABLISHED
|| tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_1
|| tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_2
|| tcb->state == GNRC_TCP_FSM_STATE_CLOSE_WAIT
|| tcb->state == GNRC_TCP_FSM_STATE_CLOSING
|| tcb->state == GNRC_TCP_FSM_STATE_LAST_ACK
if (tcb->state == FSM_STATE_ESTABLISHED
|| tcb->state == FSM_STATE_FIN_WAIT_1
|| tcb->state == FSM_STATE_FIN_WAIT_2
|| tcb->state == FSM_STATE_CLOSE_WAIT
|| tcb->state == FSM_STATE_CLOSING
|| tcb->state == FSM_STATE_LAST_ACK
) {
/* Sent data has been acknowledged */
if (LSS_32_BIT(tcb->snd_una, seg_ack) && LEQ_32_BIT(seg_ack, tcb->snd_nxt)) {
@ -672,27 +672,27 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti
}
/* Additional processing */
/* Check additionaly if previous our sent FIN has been acknowledged */
if (tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_1) {
if (tcb->state == FSM_STATE_FIN_WAIT_1) {
if (tcb->pkt_retransmit == NULL) {
_transition_to(tcb, GNRC_TCP_FSM_STATE_FIN_WAIT_2, notify_owner);
_transition_to(tcb, FSM_STATE_FIN_WAIT_2, notify_owner);
}
}
/* If retransmission queue is empty, acknowledge close operation */
if (tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_2) {
if (tcb->state == FSM_STATE_FIN_WAIT_2) {
if (tcb->pkt_retransmit == NULL) {
/* Optional: Unblock user close operation */
}
}
/* If our FIN has been acknowledged: Translate to TIME_WAIT */
if (tcb->state == GNRC_TCP_FSM_STATE_CLOSING) {
if (tcb->state == FSM_STATE_CLOSING) {
if (tcb->pkt_retransmit == NULL) {
_transition_to(tcb, GNRC_TCP_FSM_STATE_TIME_WAIT, notify_owner);
_transition_to(tcb, FSM_STATE_TIME_WAIT, notify_owner);
}
}
/* If our FIN has been acknowledged: last ACK received, close connection */
if (tcb->state == GNRC_TCP_FSM_STATE_LAST_ACK) {
if (tcb->state == FSM_STATE_LAST_ACK) {
if (tcb->pkt_retransmit == NULL) {
_transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner);
_transition_to(tcb, FSM_STATE_CLOSED, notify_owner);
return 0;
}
}
@ -703,9 +703,9 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti
/* 6) Process Payload, if existing */
if (pay_len > 0) {
/* Check if State is valid */
if (tcb->state == GNRC_TCP_FSM_STATE_ESTABLISHED
|| tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_1
|| tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_2
if (tcb->state == FSM_STATE_ESTABLISHED
|| tcb->state == FSM_STATE_FIN_WAIT_1
|| tcb->state == FSM_STATE_FIN_WAIT_2
) {
/* Search for begin of payload "chain" */
LL_SEARCH_SCALAR(in_pkt, snp, type, GNRC_NETTYPE_UNDEF);
@ -733,9 +733,9 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti
}
/* 7) Check FIN */
if (ctl & MSK_FIN) {
if (tcb->state == GNRC_TCP_FSM_STATE_CLOSED
|| tcb->state == GNRC_TCP_FSM_STATE_LISTEN
|| tcb->state == GNRC_TCP_FSM_STATE_SYN_SENT
if (tcb->state == FSM_STATE_CLOSED
|| tcb->state == FSM_STATE_LISTEN
|| tcb->state == FSM_STATE_SYN_SENT
) {
return 0;
}
@ -744,23 +744,23 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti
_pkt_build(tcb, &out_pkt, &seq_con, MSK_ACK, tcb->snd_nxt, tcb->rcv_nxt, NULL, 0);
_pkt_send(tcb, out_pkt, seq_con, false);
if (tcb->state == GNRC_TCP_FSM_STATE_SYN_RCVD
|| tcb->state == GNRC_TCP_FSM_STATE_ESTABLISHED
if (tcb->state == FSM_STATE_SYN_RCVD
|| tcb->state == FSM_STATE_ESTABLISHED
) {
_transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSE_WAIT, notify_owner);
_transition_to(tcb, FSM_STATE_CLOSE_WAIT, notify_owner);
}
else if (tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_1) {
else if (tcb->state == FSM_STATE_FIN_WAIT_1) {
if (tcb->pkt_retransmit == NULL) {
_transition_to(tcb, GNRC_TCP_FSM_STATE_TIME_WAIT, notify_owner);
_transition_to(tcb, FSM_STATE_TIME_WAIT, notify_owner);
}
else {
_transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSING, notify_owner);
_transition_to(tcb, FSM_STATE_CLOSING, notify_owner);
}
}
else if (tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_2) {
_transition_to(tcb, GNRC_TCP_FSM_STATE_TIME_WAIT, notify_owner);
else if (tcb->state == FSM_STATE_FIN_WAIT_2) {
_transition_to(tcb, FSM_STATE_TIME_WAIT, notify_owner);
}
else if (tcb->state == GNRC_TCP_FSM_STATE_TIME_WAIT) {
else if (tcb->state == FSM_STATE_TIME_WAIT) {
_restart_timewait_timer(tcb);
}
}
@ -779,7 +779,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti
static int _fsm_timeout_timewait(gnrc_tcp_tcb_t* tcb, bool *notify_owner)
{
DEBUG("gnrc_tcp_fsm.c : _fsm_timeout_timewait()\n");
_transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner);
_transition_to(tcb, FSM_STATE_CLOSED, notify_owner);
return 0;
}
@ -814,7 +814,7 @@ static int _fsm_timeout_retransmit(gnrc_tcp_tcb_t* tcb)
static int _fsm_timeout_connection(gnrc_tcp_tcb_t* tcb, bool *notify_owner)
{
DEBUG("gnrc_tcp_fsm.c : _fsm_timeout_connection()\n");
_transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner);
_transition_to(tcb, FSM_STATE_CLOSED, notify_owner);
return 0;
}
@ -867,51 +867,51 @@ static int _fsm_clear_retransmit(gnrc_tcp_tcb_t* tcb)
* @return -EADDRINUSE Given local port is already in use
* @return -EOPNOTSUPP If event is not implemented
*/
static int _fsm_unprotected(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_event_t event,
static int _fsm_unprotected(gnrc_tcp_tcb_t* tcb, fsm_event_t event,
gnrc_pktsnip_t *in_pkt, void *buf, size_t nByte, bool *notify_owner)
{
int ret = 0; /* Return Value */
DEBUG("gnrc_tcp_fsm.c : _fsm_unprotected()\n");
switch (event) {
case GNRC_TCP_FSM_EVENT_CALL_OPEN :
case FSM_EVENT_CALL_OPEN :
ret = _fsm_call_open(tcb, notify_owner);
break;
case GNRC_TCP_FSM_EVENT_CALL_SEND :
case FSM_EVENT_CALL_SEND :
ret = _fsm_call_send(tcb, buf, nByte);
break;
case GNRC_TCP_FSM_EVENT_CALL_RECV :
case FSM_EVENT_CALL_RECV :
ret = _fsm_call_recv(tcb, buf, nByte);
break;
case GNRC_TCP_FSM_EVENT_CALL_CLOSE :
case FSM_EVENT_CALL_CLOSE :
ret = _fsm_call_close(tcb, notify_owner);
break;
case GNRC_TCP_FSM_EVENT_CALL_ABORT :
case FSM_EVENT_CALL_ABORT :
ret = _fsm_call_abort();
break;
case GNRC_TCP_FSM_EVENT_RCVD_PKT :
case FSM_EVENT_RCVD_PKT :
ret = _fsm_rcvd_pkt(tcb, in_pkt, notify_owner);
break;
case GNRC_TCP_FSM_EVENT_TIMEOUT_TIMEWAIT :
case FSM_EVENT_TIMEOUT_TIMEWAIT :
ret = _fsm_timeout_timewait(tcb, notify_owner);
break;
case GNRC_TCP_FSM_EVENT_TIMEOUT_RETRANSMIT :
case FSM_EVENT_TIMEOUT_RETRANSMIT :
ret = _fsm_timeout_retransmit(tcb);
break;
case GNRC_TCP_FSM_EVENT_TIMEOUT_CONNECTION :
case FSM_EVENT_TIMEOUT_CONNECTION :
ret = _fsm_timeout_connection(tcb, notify_owner);
break;
case GNRC_TCP_FSM_EVENT_SEND_PROBE :
case FSM_EVENT_SEND_PROBE :
ret = _fsm_send_probe(tcb);
break;
case GNRC_TCP_FSM_EVENT_CLEAR_RETRANSMIT :
case FSM_EVENT_CLEAR_RETRANSMIT :
ret = _fsm_clear_retransmit(tcb);
break;
}
return ret;
}
int _fsm(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_event_t event, gnrc_pktsnip_t *in_pkt, void *buf,
int _fsm(gnrc_tcp_tcb_t* tcb, fsm_event_t event, gnrc_pktsnip_t *in_pkt, void *buf,
size_t nByte)
{
msg_t msg;

View File

@ -25,13 +25,46 @@
#include <errno.h>
#include "net/gnrc/pktbuf.h"
#include "net/gnrc/pkt.h"
#include "net/gnrc/tcp/fsm.h"
#include "net/gnrc/tcp.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief The TCP FSM States.
*/
typedef enum {
FSM_STATE_CLOSED,
FSM_STATE_LISTEN,
FSM_STATE_SYN_SENT,
FSM_STATE_SYN_RCVD,
FSM_STATE_ESTABLISHED,
FSM_STATE_CLOSE_WAIT,
FSM_STATE_LAST_ACK,
FSM_STATE_FIN_WAIT_1,
FSM_STATE_FIN_WAIT_2,
FSM_STATE_CLOSING,
FSM_STATE_TIME_WAIT
} fsm_state_t;
/**
* @brief Events that trigger translations in TCP FSM.
*/
typedef enum {
FSM_EVENT_CALL_OPEN, /* User function call: open */
FSM_EVENT_CALL_SEND, /* User function call: send */
FSM_EVENT_CALL_RECV, /* User function call: recv */
FSM_EVENT_CALL_CLOSE, /* User function call: close */
FSM_EVENT_CALL_ABORT, /* User function call: abort */
FSM_EVENT_RCVD_PKT, /* Paket received from peer */
FSM_EVENT_TIMEOUT_TIMEWAIT, /* Timeout: Timewait */
FSM_EVENT_TIMEOUT_RETRANSMIT, /* Timeout: Retransmit */
FSM_EVENT_TIMEOUT_CONNECTION, /* Timeout: Connection */
FSM_EVENT_SEND_PROBE, /* Send a Zero Window Probe */
FSM_EVENT_CLEAR_RETRANSMIT /* Clear Retransmission Mechanism */
} fsm_event_t;
/**
* @brief TCP finite state maschine
*
@ -45,7 +78,7 @@ extern "C" {
* @return Positive Number, number of bytes sent from or copied into buf.
* @return -ENOSYS if event is not implemented
*/
int _fsm(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_event_t event, gnrc_pktsnip_t *in_pkt, void *buf,
int _fsm(gnrc_tcp_tcb_t* tcb, fsm_event_t event, gnrc_pktsnip_t *in_pkt, void *buf,
size_t nByte);
#ifdef __cplusplus