/* * Copyright (C) 2021 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. */ /** * @{ * * @file * @brief GNRC implementation of @ref net_sock_tcp * * @author Simon Brummer */ #include #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); (void) flags; /* Initialize given TCB and try to open a connection */ gnrc_tcp_tcb_init(sock); /* 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(sock, remote, 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); (void) flags; /* Initialize given TCB queue, all given tcbs and forward call */ gnrc_tcp_tcb_queue_init(queue); for (unsigned i = 0; i < queue_len; ++i) { gnrc_tcp_tcb_init(&queue_array[i]); } return gnrc_tcp_listen(queue, queue_array, queue_len, local); } void sock_tcp_disconnect(sock_tcp_t *sock) { /* Asserts defined by API. */ assert(sock != NULL); gnrc_tcp_close(sock); } void sock_tcp_stop_listen(sock_tcp_queue_t *queue) { /* Asserts defined by API. */ assert(queue != NULL); gnrc_tcp_stop_listen(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); return gnrc_tcp_get_local(sock, ep); } int sock_tcp_get_remote(sock_tcp_t *sock, sock_tcp_ep_t *ep) { /* Asserts defined by API. */ assert(sock != NULL); assert(ep != NULL); return gnrc_tcp_get_remote(sock, ep); } 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); return gnrc_tcp_queue_get_local(queue, ep); } 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); /* Map SOCK_NO_TIMEOUT to GNRC_TCP_NO_TIMEOUT */ if (timeout == SOCK_NO_TIMEOUT) { timeout = GNRC_TCP_NO_TIMEOUT; } /* 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(queue, sock, 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); /* Map SOCK_NO_TIMEOUT to GNRC_TCP_NO_TIMEOUT */ if (timeout == SOCK_NO_TIMEOUT) { timeout = GNRC_TCP_NO_TIMEOUT; } /* Forward call to gnrc_tcp_recv: All error codes share the same semantics */ return gnrc_tcp_recv(sock, 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); /* 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(sock, data, len, 0); }