/* * Copyright (C) 2015-2017 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. */ /** * @ingroup net_gnrc * @{ * * @file * @brief Implementation of internal/rcvbuf.h * * @author Simon Brummer */ #include #include "internal/rcvbuf.h" #define ENABLE_DEBUG (0) #include "debug.h" rcvbuf_t _static_buf; /**< Staticly allocated receive buffers */ void _rcvbuf_init(void) { DEBUG("gnrc_tcp_rcvbuf.c : _rcvbuf_init() : Entry\n"); mutex_init(&(_static_buf.lock)); for (size_t i = 0; i < GNRC_TCP_RCV_BUFFERS; ++i) { _static_buf.entries[i].used = 0; } } static void* _rcvbuf_alloc(void) { void *result = NULL; DEBUG("gnrc_tcp_rcvbuf.c : _rcvbuf_alloc() : Entry\n"); mutex_lock(&(_static_buf.lock)); for (size_t i = 0; i < GNRC_TCP_RCV_BUFFERS; ++i) { if (_static_buf.entries[i].used == 0) { _static_buf.entries[i].used = 1; result = (void *)(_static_buf.entries[i].buffer); break; } } mutex_unlock(&(_static_buf.lock)); return result; } static void _rcvbuf_free(void * const buf) { DEBUG("gnrc_tcp_rcvbuf.c : _rcvbuf_free() : Entry\n"); mutex_lock(&(_static_buf.lock)); for (size_t i = 0; i < GNRC_TCP_RCV_BUFFERS; ++i) { if (_static_buf.entries[i].used == 1 && buf == _static_buf.entries[i].buffer) { _static_buf.entries[i].used = 0; } } mutex_unlock(&(_static_buf.lock)); } int _rcvbuf_get_buffer(gnrc_tcp_tcb_t *tcb) { if (tcb->rcv_buf_raw == NULL) { tcb->rcv_buf_raw = _rcvbuf_alloc(); if (tcb->rcv_buf_raw == NULL) { DEBUG("gnrc_tcp_rcvbuf.c : _rcvbuf_get_buffer() : Can't allocate rcv_buf_raw\n"); return -ENOMEM; } else { ringbuffer_init(&tcb->rcv_buf, (char *) tcb->rcv_buf_raw, GNRC_TCP_RCV_BUF_SIZE); } } return 0; } void _rcvbuf_release_buffer(gnrc_tcp_tcb_t *tcb) { if (tcb->rcv_buf_raw != NULL) { _rcvbuf_free(tcb->rcv_buf_raw); tcb->rcv_buf_raw = NULL; } }