-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
602384e
commit 134180c
Showing
12 changed files
with
1,128 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
MODULE = gnrc_sock_tcp | ||
|
||
include $(RIOTBASE)/Makefile.base |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
/* | ||
* Copyright (C) 2021 Simon Brummer <[email protected]> | ||
* | ||
* 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. | ||
*/ | ||
|
||
/** | ||
* @{ | ||
* | ||
* @file | ||
* @brief GNRC implementation of @ref net_sock_tcp | ||
* | ||
* @author Simon Brummer <[email protected]> | ||
*/ | ||
|
||
#include <assert.h> | ||
|
||
#include "net/gnrc/tcp.h" | ||
#include "net/sock/tcp.h" | ||
#include "sock_types.h" | ||
|
||
int sock_tcp_connect(sock_tcp_t *sock, const sock_tcp_ep_t *remote, | ||
uint16_t local_port, uint16_t flags) | ||
{ | ||
/* Asserts defined by API. */ | ||
assert(sock != NULL); | ||
assert(remote != NULL); | ||
assert(remote->port != 0); | ||
|
||
/* Asserts to protect GNRC_TCP. Flags are not supported. */ | ||
assert(flags == 0); | ||
assert(sizeof(sock_tcp_t) == sizeof(gnrc_tcp_tcb_t)); | ||
assert(sizeof(sock_tcp_ep_t) == sizeof(gnrc_tcp_ep_t)); | ||
|
||
/* NOTE: GNRC_TCP and GNRC_SOCK_TCP types must have the same memory representation. */ | ||
gnrc_tcp_tcb_t *tcb = (gnrc_tcp_tcb_t *) sock; | ||
gnrc_tcp_ep_t *ep = (gnrc_tcp_ep_t *) remote; | ||
|
||
/* Initialize given TCB and try to open a connection */ | ||
gnrc_tcp_tcb_init(tcb); | ||
|
||
/* Forward call to gnrc_tcp_open. Return codes are identical except those that are | ||
* not generated by gnrc_tcp_open: -ENETUNREACH and -EPERM */ | ||
return gnrc_tcp_open(tcb, ep, local_port); | ||
} | ||
|
||
int sock_tcp_listen(sock_tcp_queue_t *queue, const sock_tcp_ep_t *local, | ||
sock_tcp_t *queue_array, unsigned queue_len, uint16_t flags) | ||
{ | ||
/* Asserts defined by API. */ | ||
assert(queue != NULL); | ||
assert(local != NULL); | ||
assert(local->port != 0); | ||
assert(queue_array != NULL); | ||
assert(queue_len != 0); | ||
|
||
/* Asserts to protect GNRC_TCP. Flags are not supported. */ | ||
assert(flags == 0); | ||
assert(sizeof(sock_tcp_queue_t) == sizeof(gnrc_tcp_tcb_queue_t)); | ||
assert(sizeof(sock_tcp_t) == sizeof(gnrc_tcp_tcb_t)); | ||
assert(sizeof(sock_tcp_ep_t) == sizeof(gnrc_tcp_ep_t)); | ||
|
||
/* NOTE: GNRC_TCP and GNRC_SOCK_TCP types must have the same memory representation. */ | ||
gnrc_tcp_tcb_queue_t *tcb_queue = (gnrc_tcp_tcb_queue_t *) queue; | ||
gnrc_tcp_tcb_t *tcbs = (gnrc_tcp_tcb_t *) queue_array; | ||
gnrc_tcp_ep_t *ep = (gnrc_tcp_ep_t *) local; | ||
|
||
/* Initialize given TCB queue, all given tcbs and forward call */ | ||
gnrc_tcp_tcb_queue_init(tcb_queue); | ||
for (unsigned i = 0; i < queue_len; ++i) { | ||
gnrc_tcp_tcb_init(&tcbs[i]); | ||
} | ||
return gnrc_tcp_listen(tcb_queue, tcbs, queue_len, ep); | ||
} | ||
|
||
void sock_tcp_disconnect(sock_tcp_t *sock) | ||
{ | ||
/* Asserts defined by API. */ | ||
assert(sock != NULL); | ||
|
||
/* Asserts to protect GNRC_TCP. */ | ||
assert(sizeof(sock_tcp_t) == sizeof(gnrc_tcp_tcb_t)); | ||
|
||
/* NOTE: GNRC_TCP and GNRC_SOCK_TCP types must have the same memory representation. */ | ||
gnrc_tcp_tcb_t *tcb = (gnrc_tcp_tcb_t *) sock; | ||
gnrc_tcp_close(tcb); | ||
} | ||
|
||
void sock_tcp_stop_listen(sock_tcp_queue_t *queue) | ||
{ | ||
/* Asserts defined by API. */ | ||
assert(queue != NULL); | ||
|
||
/* Asserts to protect GNRC_TCP. */ | ||
assert(sizeof(sock_tcp_queue_t) == sizeof(gnrc_tcp_tcb_queue_t)); | ||
|
||
/* NOTE: GNRC_TCP and GNRC_SOCK_TCP types must have the same memory representation. */ | ||
gnrc_tcp_tcb_queue_t *tcb_queue = (gnrc_tcp_tcb_queue_t *) queue; | ||
gnrc_tcp_stop_listen(tcb_queue); | ||
} | ||
|
||
int sock_tcp_get_local(sock_tcp_t *sock, sock_tcp_ep_t *ep) | ||
{ | ||
/* Asserts defined by API. */ | ||
assert(sock != NULL); | ||
assert(ep != NULL); | ||
|
||
/* Asserts to protect GNRC_TCP. */ | ||
assert(sizeof(sock_tcp_t) == sizeof(gnrc_tcp_tcb_t)); | ||
assert(sizeof(sock_tcp_ep_t) == sizeof(gnrc_tcp_ep_t)); | ||
|
||
/* NOTE: GNRC_TCP and GNRC_SOCK_TCP types must have the same memory representation. */ | ||
gnrc_tcp_tcb_t *tcb = (gnrc_tcp_tcb_t *) sock; | ||
gnrc_tcp_ep_t *local = (gnrc_tcp_ep_t *) ep; | ||
return gnrc_tcp_get_local(tcb, local); | ||
} | ||
|
||
int sock_tcp_get_remote(sock_tcp_t *sock, sock_tcp_ep_t *ep) | ||
{ | ||
/* Asserts defined by API. */ | ||
assert(sock != NULL); | ||
assert(ep != NULL); | ||
|
||
/* Asserts to protect GNRC_TCP. */ | ||
assert(sizeof(sock_tcp_t) == sizeof(gnrc_tcp_tcb_t)); | ||
assert(sizeof(sock_tcp_ep_t) == sizeof(gnrc_tcp_ep_t)); | ||
|
||
/* NOTE: GNRC_TCP and GNRC_SOCK_TCP types must have the same memory representation. */ | ||
gnrc_tcp_tcb_t *tcb = (gnrc_tcp_tcb_t *) sock; | ||
gnrc_tcp_ep_t *remote = (gnrc_tcp_ep_t *) ep; | ||
return gnrc_tcp_get_remote(tcb, remote); | ||
} | ||
|
||
int sock_tcp_queue_get_local(sock_tcp_queue_t *queue, sock_tcp_ep_t *ep) | ||
{ | ||
/* Asserts defined by API. */ | ||
assert(queue != NULL); | ||
assert(ep != NULL); | ||
|
||
/* Asserts to protect GNRC_TCP. */ | ||
assert(sizeof(sock_tcp_queue_t) == sizeof(gnrc_tcp_tcb_queue_t)); | ||
assert(sizeof(sock_tcp_ep_t) == sizeof(gnrc_tcp_ep_t)); | ||
|
||
/* NOTE: GNRC_TCP and GNRC_SOCK_TCP types must have the same memory representation. */ | ||
gnrc_tcp_tcb_queue_t *tcb_queue = (gnrc_tcp_tcb_queue_t *) queue; | ||
gnrc_tcp_ep_t *local = (gnrc_tcp_ep_t *) ep; | ||
return gnrc_tcp_queue_get_local(tcb_queue, local); | ||
} | ||
|
||
int sock_tcp_accept(sock_tcp_queue_t *queue, sock_tcp_t **sock, uint32_t timeout) | ||
{ | ||
/* Asserts defined by API. */ | ||
assert(queue != NULL); | ||
assert(sock != NULL); | ||
|
||
/* Asserts to protect GNRC_TCP. */ | ||
assert(sizeof(sock_tcp_queue_t) == sizeof(gnrc_tcp_tcb_queue_t)); | ||
assert(sizeof(sock_tcp_t) == sizeof(gnrc_tcp_tcb_t)); | ||
|
||
/* NOTE: GNRC_TCP and GNRC_SOCK_TCP types must have the same memory representation. */ | ||
gnrc_tcp_tcb_queue_t *tcb_queue = (gnrc_tcp_tcb_queue_t *) queue; | ||
gnrc_tcp_tcb_t **tcb = (gnrc_tcp_tcb_t **) sock; | ||
|
||
/* Map SOCK_NO_TIMEOUT to 0. 0 is used in GNRC_TCP for no timeout */ | ||
if (timeout == SOCK_NO_TIMEOUT) { | ||
timeout = 0; | ||
} | ||
|
||
/* Forward call to gnrc_tcp_accept. | ||
* NOTE: Errorcodes -ECONNABORTED, -EPERM are not returned by | ||
* gnrc_tcp_accept. All other error codes share the same semantics. */ | ||
return gnrc_tcp_accept(tcb_queue, tcb, timeout); | ||
} | ||
|
||
ssize_t sock_tcp_read(sock_tcp_t *sock, void *data, size_t max_len, uint32_t timeout) | ||
{ | ||
/* Asserts defined by API. */ | ||
assert(sock != NULL); | ||
assert(data != NULL); | ||
assert(max_len > 0); | ||
|
||
/* Asserts to protect GNRC_TCP. */ | ||
assert(sizeof(sock_tcp_t) == sizeof(gnrc_tcp_tcb_t)); | ||
|
||
/* NOTE: GNRC_TCP and GNRC_SOCK_TCP types must have the same memory representation. */ | ||
gnrc_tcp_tcb_t *tcb = (gnrc_tcp_tcb_t *) sock; | ||
|
||
/* Map SOCK_NO_TIMEOUT to 0. 0 is used in GNRC_TCP for no timeout */ | ||
if (timeout == SOCK_NO_TIMEOUT) { | ||
timeout = 0; | ||
} | ||
|
||
/* Forward call to gnrc_tcp_recv: All error codes share the same semantics */ | ||
return gnrc_tcp_recv(tcb, data, max_len, timeout); | ||
} | ||
|
||
ssize_t sock_tcp_write(sock_tcp_t *sock, const void *data, size_t len) | ||
{ | ||
/* Asserts defined by API. */ | ||
assert(sock != NULL); | ||
assert(data != NULL); | ||
assert(len > 0); | ||
|
||
/* Asserts to protect GNRC_TCP. */ | ||
assert(sizeof(sock_tcp_t) == sizeof(gnrc_tcp_tcb_t)); | ||
|
||
/* NOTE: GNRC_TCP and GNRC_SOCK_TCP types must have the same memory representation. */ | ||
gnrc_tcp_tcb_t *tcb = (gnrc_tcp_tcb_t *) sock; | ||
|
||
/* Forward call to gnrc_tcp_send. | ||
* NOTE: gnrc_tcp_send offers a timeout. By setting it to 0, the call blocks | ||
* until at least some data was transmitted. */ | ||
return gnrc_tcp_send(tcb, data, len, 0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
include ../Makefile.tests_common | ||
|
||
# Basic Configuration | ||
BOARD ?= native | ||
TAP ?= tap0 | ||
|
||
# Shorten default TCP timeouts to speedup testing | ||
MSL_MS ?= 1000 | ||
TIMEOUT_MS ?= 3000 | ||
|
||
# This test depends on tap device setup (only allowed by root) | ||
# Suppress test execution to avoid CI errors | ||
TEST_ON_CI_BLACKLIST += all | ||
|
||
ifeq (native,$(BOARD)) | ||
TERMFLAGS ?= $(TAP) | ||
else | ||
ETHOS_BAUDRATE ?= 115200 | ||
CFLAGS += -DETHOS_BAUDRATE=$(ETHOS_BAUDRATE) | ||
TERMDEPS += ethos | ||
TERMPROG ?= sudo $(RIOTTOOLS)/ethos/ethos | ||
TERMFLAGS ?= $(TAP) $(PORT) $(ETHOS_BAUDRATE) | ||
endif | ||
|
||
USEMODULE += auto_init_gnrc_netif | ||
USEMODULE += gnrc_ipv6_default | ||
USEMODULE += gnrc_sock_tcp | ||
USEMODULE += gnrc_pktbuf_cmd | ||
USEMODULE += gnrc_netif_single # Only one interface used and it makes | ||
# shell commands easier | ||
USEMODULE += shell | ||
USEMODULE += shell_commands | ||
USEMODULE += od | ||
|
||
# Export used tap device to environment | ||
export TAPDEV = $(TAP) | ||
|
||
.PHONY: ethos | ||
|
||
ethos: | ||
$(Q)env -u CC -u CFLAGS $(MAKE) -C $(RIOTTOOLS)/ethos | ||
|
||
include $(RIOTBASE)/Makefile.include | ||
|
||
# Set CONFIG_GNRC_TCP_MSL via CFLAGS if not being set via Kconfig | ||
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_MS | ||
CFLAGS += -DCONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION_MS=$(TIMEOUT_MS) | ||
endif | ||
|
||
# Set the shell echo configuration via CFLAGS if not being controlled via Kconfig | ||
ifndef CONFIG_KCONFIG_USEMODULE_SHELL | ||
CFLAGS += -DCONFIG_SHELL_NO_ECHO | ||
endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Put board specific dependencies here | ||
ifeq (native,$(BOARD)) | ||
USEMODULE += netdev_tap | ||
else | ||
USEMODULE += stdio_ethos | ||
endif |
Oops, something went wrong.