
11 changed files with 1280 additions and 1 deletions
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base |
@ -0,0 +1,509 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Martin Lenders <mlenders@inf.fu-berlin.de> |
||||
* |
||||
* 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 pktbuf.c |
||||
* |
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de> |
||||
*/ |
||||
|
||||
#include <errno.h> |
||||
#include <inttypes.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#include "mutex.h" |
||||
#include "pktbuf.h" |
||||
|
||||
typedef struct __attribute__((packed)) _packet_t { |
||||
volatile struct _packet_t *next; |
||||
uint8_t processing; |
||||
size_t size; |
||||
} _packet_t; |
||||
|
||||
static uint8_t _pktbuf[PKTBUF_SIZE]; |
||||
static mutex_t _pktbuf_mutex = MUTEX_INIT; |
||||
|
||||
/**
|
||||
* @brief Get first element in packet buffer. |
||||
*/ |
||||
static inline _packet_t *_pktbuf_head(void) |
||||
{ |
||||
return (_packet_t *)(&(_pktbuf[0])); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Get data part (memory behind `_packet_t` descriptive header) of a packet |
||||
* |
||||
* @param[in] pkt A packet |
||||
* |
||||
* @return Data part of the packet. |
||||
*/ |
||||
static inline void *_pkt_data(_packet_t *pkt) |
||||
{ |
||||
return (void *)(((_packet_t *)pkt) + 1); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Calculates total size (*size* + size of `_packet_t` descriptive header) of a |
||||
* packet in memory |
||||
* |
||||
* @param[in] size A given packet size |
||||
* |
||||
* @return Total size of a packet in memory. |
||||
*/ |
||||
static inline size_t _pkt_total_sz(size_t size) |
||||
{ |
||||
return sizeof(_packet_t) + size; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Get pointer to the byte after the last byte of a packet. |
||||
* |
||||
* @param[in] pkt A packet |
||||
* |
||||
* @return Pointer to the last byte of a packet |
||||
*/ |
||||
static inline void *_pkt_end(_packet_t *pkt) |
||||
{ |
||||
return (void *)((uint8_t *)pkt + _pkt_total_sz(pkt->size)); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Get index in packet buffer of the first byte of a packet's data part |
||||
* |
||||
* @param[in] pkt A packet |
||||
* |
||||
* @return Index in packet buffer of the first byte of *pkt*'s data part. |
||||
*/ |
||||
static inline size_t _pktbuf_start_idx(_packet_t *pkt) |
||||
{ |
||||
return (size_t)(((uint8_t *)pkt) - (&(_pktbuf[0]))); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Get index in packet buffer of the last byte of a packet's data part |
||||
* |
||||
* @param[in] pkt A packet |
||||
* |
||||
* @return Index in packet buffer of the last byte of *pkt*'s data part. |
||||
*/ |
||||
static inline size_t _pktbuf_end_idx(_packet_t *pkt) |
||||
{ |
||||
return _pktbuf_start_idx(pkt) + _pkt_total_sz(pkt->size) - 1; |
||||
} |
||||
|
||||
static _packet_t *_pktbuf_find_with_prev(_packet_t **prev_ptr, |
||||
_packet_t **packet_ptr, const void *pkt) |
||||
{ |
||||
_packet_t *packet = _pktbuf_head(), *prev = NULL; |
||||
|
||||
while (packet != NULL) { |
||||
|
||||
if (_pkt_data(packet) == pkt) { |
||||
*prev_ptr = prev; |
||||
*packet_ptr = packet; |
||||
return packet; |
||||
} |
||||
|
||||
prev = packet; |
||||
packet = (_packet_t *)packet->next; |
||||
} |
||||
|
||||
*prev_ptr = NULL; |
||||
*packet_ptr = NULL; |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
static _packet_t *_pktbuf_find(const void *pkt) |
||||
{ |
||||
_packet_t *packet = _pktbuf_head(); |
||||
|
||||
#ifdef DEVELHELP |
||||
|
||||
if (pkt == NULL) { |
||||
return NULL; |
||||
} |
||||
|
||||
#endif /* DEVELHELP */ |
||||
|
||||
while (packet != NULL) { |
||||
if ((_pkt_data(packet) <= pkt) && (pkt < _pkt_end(packet))) { |
||||
mutex_unlock(&_pktbuf_mutex); |
||||
return packet; |
||||
} |
||||
|
||||
packet = (_packet_t *)packet->next; |
||||
} |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
static _packet_t *_pktbuf_alloc(size_t size) |
||||
{ |
||||
_packet_t *packet = _pktbuf_head(), *old_next; |
||||
|
||||
if ((size == 0) || (size > PKTBUF_SIZE)) { |
||||
return NULL; |
||||
} |
||||
|
||||
if ((packet->size == 0) /* if first packet is currently not initialized
|
||||
* but next packet and no space between first |
||||
* and next in its slot */ |
||||
&& (packet->processing == 0) |
||||
&& (packet->next != NULL) |
||||
&& ((_pktbuf_start_idx((_packet_t *)(packet->next)) - _pkt_total_sz(packet->size)) < size)) { |
||||
packet = (_packet_t *)packet->next; |
||||
} |
||||
|
||||
/* while packet is not initialized */ |
||||
while ((packet->processing > 0) || (packet->size > size)) { |
||||
old_next = (_packet_t *)packet->next; |
||||
|
||||
/* if current packet is the last in buffer, but buffer space is exceeded */ |
||||
if ((old_next == NULL) |
||||
&& ((_pktbuf_end_idx(packet) + _pkt_total_sz(size)) > PKTBUF_SIZE)) { |
||||
return NULL; |
||||
} |
||||
|
||||
/* if current packet is the last in the buffer or if space between
|
||||
* current packet and next packet is big enough */ |
||||
if ((old_next == NULL) |
||||
|| ((_pktbuf_start_idx((_packet_t *)(packet->next)) - _pktbuf_end_idx(packet)) >= _pkt_total_sz( |
||||
size))) { |
||||
|
||||
_packet_t *new_next = (_packet_t *)(((uint8_t *)packet) + _pkt_total_sz(packet->size)); |
||||
/* jump ahead size of current packet. */ |
||||
packet->next = new_next; |
||||
packet->next->next = old_next; |
||||
|
||||
packet = new_next; |
||||
|
||||
break; |
||||
} |
||||
|
||||
packet = old_next; |
||||
} |
||||
|
||||
packet->size = size; |
||||
packet->processing = 1; |
||||
|
||||
return packet; |
||||
} |
||||
|
||||
static void _pktbuf_free(_packet_t *prev, _packet_t *packet) |
||||
{ |
||||
if ((packet->processing)-- > 1) { /* `> 1` because packet->processing may already
|
||||
* be 0 in which case --(packet->processing) |
||||
* would wrap to 255. */ |
||||
return; |
||||
} |
||||
|
||||
if (prev == NULL) { /* packet is _pktbuf_head() */ |
||||
packet->size = 0; |
||||
} |
||||
else { |
||||
prev->next = packet->next; |
||||
} |
||||
} |
||||
|
||||
int pktbuf_contains(const void *pkt) |
||||
{ |
||||
return ((&(_pktbuf[0]) < ((uint8_t *)pkt)) && (((uint8_t *)pkt) <= &(_pktbuf[PKTBUF_SIZE - 1]))); |
||||
} |
||||
|
||||
void *pktbuf_alloc(size_t size) |
||||
{ |
||||
_packet_t *packet; |
||||
|
||||
mutex_lock(&_pktbuf_mutex); |
||||
|
||||
packet = _pktbuf_alloc(size); |
||||
|
||||
if (packet == NULL) { |
||||
mutex_unlock(&_pktbuf_mutex); |
||||
return NULL; |
||||
} |
||||
|
||||
mutex_unlock(&_pktbuf_mutex); |
||||
|
||||
return _pkt_data(packet); |
||||
} |
||||
|
||||
void *pktbuf_realloc(const void *pkt, size_t size) |
||||
{ |
||||
_packet_t *new, *prev, *orig; |
||||
|
||||
mutex_lock(&_pktbuf_mutex); |
||||
|
||||
if ((size == 0) || (size > PKTBUF_SIZE)) { |
||||
mutex_unlock(&_pktbuf_mutex); |
||||
return NULL; |
||||
} |
||||
|
||||
_pktbuf_find_with_prev(&prev, &orig, pkt); |
||||
|
||||
if ((orig != NULL) && |
||||
((orig->size >= size) /* and *orig* is last packet, and space in
|
||||
* _pktbuf is sufficient */ |
||||
|| ((orig->next == NULL) |
||||
&& ((_pktbuf_start_idx(orig) + _pkt_total_sz(size)) < PKTBUF_SIZE)) |
||||
|| ((orig->next != NULL) /* or space between pointer and the next is big enough: */ |
||||
&& ((_pktbuf_start_idx((_packet_t *)(orig->next)) - _pktbuf_start_idx(orig)) |
||||
>= _pkt_total_sz(size))))) { |
||||
orig->size = size; |
||||
|
||||
mutex_unlock(&_pktbuf_mutex); |
||||
return (void *)pkt; |
||||
} |
||||
|
||||
new = _pktbuf_alloc(size); |
||||
|
||||
if (new == NULL) { |
||||
mutex_unlock(&_pktbuf_mutex); |
||||
return NULL; |
||||
} |
||||
|
||||
if (orig != NULL) { |
||||
memcpy(_pkt_data(new), _pkt_data(orig), orig->size); |
||||
|
||||
_pktbuf_free(prev, orig); |
||||
} |
||||
else { |
||||
memcpy(_pkt_data(new), pkt, size); |
||||
} |
||||
|
||||
|
||||
mutex_unlock(&_pktbuf_mutex); |
||||
|
||||
return _pkt_data(new); |
||||
} |
||||
|
||||
void *pktbuf_insert(const void *data, size_t size) |
||||
{ |
||||
_packet_t *packet; |
||||
|
||||
if ((data == NULL) || (size == 0)) { |
||||
return NULL; |
||||
} |
||||
|
||||
mutex_lock(&_pktbuf_mutex); |
||||
packet = _pktbuf_alloc(size); |
||||
|
||||
if (packet == NULL) { |
||||
mutex_unlock(&_pktbuf_mutex); |
||||
return NULL; |
||||
} |
||||
|
||||
memcpy(_pkt_data(packet), data, size); |
||||
|
||||
mutex_unlock(&_pktbuf_mutex); |
||||
return _pkt_data(packet); |
||||
} |
||||
|
||||
int pktbuf_copy(void *pkt, const void *data, size_t data_len) |
||||
{ |
||||
_packet_t *packet; |
||||
|
||||
mutex_lock(&_pktbuf_mutex); |
||||
|
||||
#ifdef DEVELHELP |
||||
|
||||
if (data == NULL) { |
||||
mutex_unlock(&_pktbuf_mutex); |
||||
return -EFAULT; |
||||
} |
||||
|
||||
if (pkt == NULL) { |
||||
mutex_unlock(&_pktbuf_mutex); |
||||
return -EINVAL; |
||||
} |
||||
|
||||
#endif /* DEVELHELP */ |
||||
|
||||
packet = _pktbuf_find(pkt); |
||||
|
||||
|
||||
if ((packet != NULL) && (packet->size > 0) && (packet->processing > 0)) { |
||||
/* packet space not engough? */ |
||||
if (data_len > (size_t)(((uint8_t *)_pkt_end(packet)) - ((uint8_t *)pkt))) { |
||||
mutex_unlock(&_pktbuf_mutex); |
||||
return -ENOMEM; |
||||
} |
||||
} |
||||
|
||||
|
||||
memcpy(pkt, data, data_len); |
||||
|
||||
mutex_unlock(&_pktbuf_mutex); |
||||
return data_len; |
||||
} |
||||
|
||||
void pktbuf_hold(const void *pkt) |
||||
{ |
||||
_packet_t *packet; |
||||
|
||||
mutex_lock(&_pktbuf_mutex); |
||||
|
||||
packet = _pktbuf_find(pkt); |
||||
|
||||
if (packet != NULL) { |
||||
packet->processing++; |
||||
} |
||||
|
||||
mutex_unlock(&_pktbuf_mutex); |
||||
} |
||||
|
||||
void pktbuf_release(const void *pkt) |
||||
{ |
||||
_packet_t *packet = _pktbuf_head(), *prev = NULL; |
||||
|
||||
mutex_lock(&_pktbuf_mutex); |
||||
|
||||
while (packet != NULL) { |
||||
|
||||
if ((_pkt_data(packet) <= pkt) && (pkt < _pkt_end(packet))) { |
||||
_pktbuf_free(prev, packet); |
||||
|
||||
mutex_unlock(&_pktbuf_mutex); |
||||
return; |
||||
} |
||||
|
||||
prev = packet; |
||||
packet = (_packet_t *)packet->next; |
||||
} |
||||
|
||||
mutex_unlock(&_pktbuf_mutex); |
||||
} |
||||
|
||||
#ifdef DEVELHELP |
||||
#include <stdio.h> |
||||
|
||||
void pktbuf_print(void) |
||||
{ |
||||
_packet_t *packet = _pktbuf_head(); |
||||
int i = 0; |
||||
|
||||
mutex_lock(&_pktbuf_mutex); |
||||
|
||||
printf("current pktbuf allocations:\n"); |
||||
printf("===================================================\n"); |
||||
|
||||
if (packet->next == NULL && packet->size == 0) { |
||||
printf("empty\n"); |
||||
printf("===================================================\n"); |
||||
printf("\n"); |
||||
mutex_unlock(&_pktbuf_mutex); |
||||
|
||||
return; |
||||
} |
||||
else if (packet->next != NULL && packet->size == 0) { |
||||
packet = (_packet_t *)packet->next; |
||||
} |
||||
|
||||
while (packet != NULL) { |
||||
uint8_t *data = (uint8_t *)_pkt_data(packet); |
||||
|
||||
printf("packet %d (%p):\n", i, (void *)packet); |
||||
printf(" next: %p\n", (void *)(packet->next)); |
||||
printf(" size: %" PRIu32 "\n", (uint32_t)packet->size); |
||||
printf(" processing: %" PRIu8 "\n", packet->processing); |
||||
|
||||
if (packet->next != NULL) { |
||||
printf(" free data after: %" PRIu32 "\n", |
||||
(uint32_t)(_pktbuf_start_idx((_packet_t *)(packet->next)) - _pktbuf_end_idx(packet) - 1)); |
||||
} |
||||
else { |
||||
printf(" free data after: %" PRIu32 "\n", (uint32_t)(PKTBUF_SIZE - _pktbuf_end_idx(packet) - 1)); |
||||
|
||||
} |
||||
|
||||
printf(" data: (start address: %p)\n ", data); |
||||
|
||||
if (packet->size > PKTBUF_SIZE) { |
||||
printf(" We have a problem: packet->size (%" PRIu32 ") > PKTBUF_SIZE (%" PRIu32 ")\n", |
||||
(uint32_t)(packet->size), (uint32_t)PKTBUF_SIZE); |
||||
} |
||||
else { |
||||
for (size_t j = 0; j < packet->size; j++) { |
||||
printf(" %02x", data[j]); |
||||
|
||||
if (((j + 1) % 16) == 0) { |
||||
printf("\n "); |
||||
} |
||||
} |
||||
|
||||
printf("\n\n"); |
||||
} |
||||
|
||||
packet = (_packet_t *)packet->next; |
||||
i++; |
||||
} |
||||
|
||||
printf("===================================================\n"); |
||||
printf("\n"); |
||||
|
||||
mutex_unlock(&_pktbuf_mutex); |
||||
|
||||
} |
||||
#endif |
||||
|
||||
#ifdef TEST_SUITES |
||||
size_t pktbuf_bytes_allocated(void) |
||||
{ |
||||
_packet_t *packet = _pktbuf_head(); |
||||
size_t bytes = 0; |
||||
|
||||
mutex_lock(&_pktbuf_mutex); |
||||
|
||||
while (packet != NULL) { |
||||
bytes += packet->size; |
||||
packet = (_packet_t *)(packet->next); |
||||
} |
||||
|
||||
mutex_unlock(&_pktbuf_mutex); |
||||
|
||||
return bytes; |
||||
} |
||||
|
||||
unsigned int pktbuf_packets_allocated(void) |
||||
{ |
||||
_packet_t *packet = _pktbuf_head(); |
||||
unsigned int packets = 0; |
||||
|
||||
mutex_lock(&_pktbuf_mutex); |
||||
|
||||
while (packet != NULL) { |
||||
if ((packet != _pktbuf_head()) || (packet->size > 0)) { /* ignore head if head->size == 0 */ |
||||
packets++; |
||||
} |
||||
|
||||
packet = (_packet_t *)(packet->next); |
||||
} |
||||
|
||||
mutex_unlock(&_pktbuf_mutex); |
||||
|
||||
return packets; |
||||
} |
||||
|
||||
int pktbuf_is_empty(void) |
||||
{ |
||||
return ((_pktbuf_head()->next == NULL) && (_pktbuf_head()->size == 0)); |
||||
} |
||||
|
||||
void pktbuf_reset(void) |
||||
{ |
||||
memset(_pktbuf, 0, PKTBUF_SIZE); |
||||
mutex_init(&_pktbuf_mutex); |
||||
} |
||||
#endif |
||||
|
||||
/** @} */ |
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Martin Lenders <mlenders@inf.fu-berlin.de> |
||||
* |
||||
* 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 pktbuf Packet buffer |
||||
* @ingroup net |
||||
* @brief A global network packet buffer. |
||||
* @{ |
||||
* |
||||
* @file pktbuf.h |
||||
* @brief Interface definition for the global network buffer. Network devices |
||||
* and layers can allocate space for packets here. |
||||
* |
||||
* @note **WARNING!!** Do not store data structures that are not packed |
||||
* (defined with `__attribute__((packed))`) or enforce alignment in |
||||
* in any way in here. On some RISC architectures this *will* lead to |
||||
* alignment problems and can potentially result in segmentation/hard |
||||
* faults and other unexpected behaviour. |
||||
* |
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de> |
||||
*/ |
||||
#ifndef __PKTBUF_H_ |
||||
#define __PKTBUF_H_ |
||||
|
||||
#include <stdlib.h> |
||||
|
||||
#include "cpu-conf.h" |
||||
|
||||
#ifndef PKTBUF_SIZE |
||||
/**
|
||||
* @brief Maximum size of the packet buffer. |
||||
* |
||||
* @detail The rational here is to have at least space for 4 full-MTU IPv6 |
||||
* packages (2 incoming, 2 outgoing; 2 * 2 * 1280 B = 5 KiB) + |
||||
* Meta-Data (roughly estimated to 1 KiB; might be smaller) |
||||
*/ |
||||
#define PKTBUF_SIZE (6144) |
||||
#endif /* PKTBUF_SIZE */ |
||||
|
||||
/**
|
||||
* @brief Allocates new packet data in the packet buffer. This also marks the |
||||
* allocated data as processed. |
||||
* |
||||
* @see @ref pktbuf_hold() |
||||
* |
||||
* @param[in] size The length of the packet you want to allocate |
||||
* |
||||
* @return Pointer to the start of the data in the packet buffer, on success. |
||||
* @return NULL, if no space is left in the packet buffer or size was 0. |
||||
*/ |
||||
void *pktbuf_alloc(size_t size); |
||||
|
||||
/**
|
||||
* @brief Reallocates new space in the packet buffer, without changing the |
||||
* content. |
||||
* |
||||
* @datail If enough memory is available behind it or *size* is smaller than |
||||
* the original size the packet will not be moved. Otherwise, it will |
||||
* be moved. If no space is available nothing happens. |
||||
* |
||||
* @param[in] pkt Old position of the packet in the packet buffer |
||||
* @param[in] size New amount of data you want to allocate |
||||
* |
||||
* @return Pointer to the (maybe new) position of the packet in the packet buffer, |
||||
* on success. |
||||
* @return NULL, if no space is left in the packet buffer or size was 0. |
||||
* The packet will remain at *ptr*. |
||||
*/ |
||||
void *pktbuf_realloc(const void *pkt, size_t size); |
||||
|
||||
/**
|
||||
* @brief Allocates and copies new packet data into the packet buffer. |
||||
* This also marks the allocated data as processed for the current |
||||
* thread. |
||||
* |
||||
* @see @ref pktbuf_hold() |
||||
* |
||||
* @param[in] data Data you want to copy into the new packet. |
||||
* @param[in] size The length of the packet you want to allocate |
||||
* |
||||
* @return Pointer to the start of the data in the packet buffer, on success. |
||||
* @return NULL, if no space is left in the packet buffer. |
||||
*/ |
||||
void *pktbuf_insert(const void *data, size_t size); |
||||
|
||||
/**
|
||||
* @brief Copies packet data into the packet buffer, safely. |
||||
* |
||||
* @detail Use this instead of memcpy, since it is thread-safe and checks if |
||||
* *pkt* is |
||||
* |
||||
* -# in the buffer at all |
||||
* -# its *size* is smaller or equal to the data allocated at *pkt* |
||||
* |
||||
* If the *pkt* is not in the buffer the data is just copied as |
||||
* memcpy would do. |
||||
* |
||||
* @param[in,out] pkt The packet you want to set the data for. |
||||
* @param[in] data The data you want to copy into the packet. |
||||
* @param[in] data_len The length of the data you want to copy. |
||||
* |
||||
* @return *data_len*, on success. |
||||
* @return -EFAULT, if *data* is NULL and DEVELHELP is defined. |
||||
* @return -EINVAL, if *pkt* is NULL and DEVELHELP is defined. |
||||
* @return -ENOBUFS, if *data_len* was greater than the packet size of *pkt*. |
||||
*/ |
||||
int pktbuf_copy(void *pkt, const void *data, size_t data_len); |
||||
|
||||
/**
|
||||
* @brief Marks the data as being processed. |
||||
* |
||||
* @detail Internally this increments just a counter on the data. |
||||
* @ref pktbuf_release() decrements it. If the counter is <=0 the |
||||
* reserved data block in the buffer will be made available again. |
||||
* |
||||
* @param[in] pkt The packet you want mark as being processed. |
||||
*/ |
||||
void pktbuf_hold(const void *pkt); |
||||
|
||||
/**
|
||||
* @brief Marks the data as not being processed. |
||||
* |
||||
* @param[in] pkt The packet you want mark as not being processed anymore. |
||||
* |
||||
* @detail Internally this decrements just a counter on the data. |
||||
* @ref pktbuf_hold() increments and any allocation |
||||
* operation initializes it. If the counter is <=0 the reserved data |
||||
* block in the buffer will be made available again. |
||||
*/ |
||||
void pktbuf_release(const void *pkt); |
||||
|
||||
/**
|
||||
* @brief Prints current packet buffer to stdout if DEVELHELP is defined. |
||||
*/ |
||||
#ifdef DEVELHELP |
||||
void pktbuf_print(void); |
||||
#else |
||||
#define pktbuf_print() ; |
||||
#endif |
||||
|
||||
/* for testing */ |
||||
#ifdef TEST_SUITES |
||||
/**
|
||||
* @brief Counts the number of allocated bytes |
||||
* |
||||
* @return Number of allocated bytes |
||||
*/ |
||||
size_t pktbuf_bytes_allocated(void); |
||||
|
||||
/**
|
||||
* @brief Counts the number of allocated packets |
||||
* |
||||
* @return Number of allocated packets |
||||
*/ |
||||
size_t pktbuf_packets_allocated(void); |
||||
|
||||
/**
|
||||
* @brief Checks if packet buffer is empty |
||||
* |
||||
* @return 1, if packet buffer is empty |
||||
* @return 0, if packet buffer is not empty |
||||
*/ |
||||
int pktbuf_is_empty(void); |
||||
|
||||
/**
|
||||
* @brief Checks if a given pointer is stored in the packet buffer |
||||
* |
||||
* @param[in] pkt Pointer to be checked |
||||
* |
||||
* @return 1, if *pkt* is in packet buffer |
||||
* @return 0, otherwise |
||||
*/ |
||||
int pktbuf_contains(const void *pkt); |
||||
|
||||
/**
|
||||
* @brief Sets the whole packet buffer to 0 |
||||
*/ |
||||
void pktbuf_reset(void); |
||||
#endif |
||||
|
||||
#endif /* __PKTBUF_H_ */ |
||||
/** @} */ |
@ -0,0 +1,3 @@
|
||||
MODULE = tests-pktbuf
|
||||
|
||||
include $(RIOTBASE)/Makefile.base |
@ -0,0 +1,538 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Martine Lenders <mail@martine-lenders.eu> |
||||
* |
||||
* 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 tests-pktbuf.c |
||||
*/ |
||||
#include <errno.h> |
||||
#include <stdint.h> |
||||
|
||||
#include "embUnit/embUnit.h" |
||||
|
||||
#include "pktbuf.h" |
||||
|
||||
#include "tests-pktbuf.h" |
||||
|
||||
typedef struct __attribute__((packed)) { |
||||
uint8_t u8; |
||||
uint16_t u16; |
||||
uint32_t u32; |
||||
uint64_t u64; |
||||
int8_t s8; |
||||
int16_t s16; |
||||
int32_t s32; |
||||
int64_t s64; |
||||
} test_pktbuf_struct_t; |
||||
|
||||
static void tear_down(void) |
||||
{ |
||||
pktbuf_reset(); |
||||
} |
||||
|
||||
static void test_pktbuf_alloc_0(void) |
||||
{ |
||||
TEST_ASSERT_NULL(pktbuf_alloc(0)); |
||||
} |
||||
|
||||
static void test_pktbuf_alloc_memfull(void) |
||||
{ |
||||
for (int i = 0; i < 9; i++) { |
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc((PKTBUF_SIZE / 10) + 4)); |
||||
/* Why 4? Because: http://xkcd.com/221/, thats why ;-) */ |
||||
} |
||||
|
||||
TEST_ASSERT_NULL(pktbuf_alloc((PKTBUF_SIZE / 10) + 4)); |
||||
} |
||||
|
||||
static void test_pktbuf_alloc_success(void) |
||||
{ |
||||
void *data, *data_prev = NULL; |
||||
|
||||
for (int i = 0; i < 9; i++) { |
||||
data = pktbuf_alloc((PKTBUF_SIZE / 10) + 4); |
||||
|
||||
TEST_ASSERT(data_prev < data); |
||||
|
||||
data_prev = data; |
||||
} |
||||
} |
||||
|
||||
static void test_pktbuf_realloc_0(void) |
||||
{ |
||||
void *data = pktbuf_alloc(512); |
||||
|
||||
TEST_ASSERT_NULL(pktbuf_realloc(data, 0)); |
||||
} |
||||
|
||||
static void test_pktbuf_realloc_memfull(void) |
||||
{ |
||||
void *data = pktbuf_alloc(512); |
||||
|
||||
TEST_ASSERT_NULL(pktbuf_realloc(data, PKTBUF_SIZE + 1)); |
||||
} |
||||
|
||||
static void test_pktbuf_realloc_memfull2(void) |
||||
{ |
||||
void *data = pktbuf_alloc(512); |
||||
|
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(512)); |
||||
TEST_ASSERT_NULL(pktbuf_realloc(data, PKTBUF_SIZE - 512)); |
||||
} |
||||
|
||||
static void test_pktbuf_realloc_memfull3(void) |
||||
{ |
||||
void *data; |
||||
|
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(25)); |
||||
|
||||
data = pktbuf_alloc(512); |
||||
|
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(73)); |
||||
|
||||
TEST_ASSERT_NULL(pktbuf_realloc(data, PKTBUF_SIZE - 512)); |
||||
} |
||||
|
||||
static void test_pktbuf_realloc_smaller(void) |
||||
{ |
||||
void *data; |
||||
|
||||
data = pktbuf_alloc(512); |
||||
|
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(25)); |
||||
|
||||
TEST_ASSERT(data == pktbuf_realloc(data, 128)); |
||||
} |
||||
|
||||
static void test_pktbuf_realloc_memenough(void) |
||||
{ |
||||
void *data; |
||||
|
||||
data = pktbuf_alloc(128); |
||||
|
||||
TEST_ASSERT_NOT_NULL(data); |
||||
|
||||
TEST_ASSERT(data == pktbuf_realloc(data, 200)); |
||||
} |
||||
|
||||
static void test_pktbuf_realloc_memenough2(void) |
||||
{ |
||||
void *data, *data2; |
||||
|
||||
data = pktbuf_alloc(128); |
||||
|
||||
TEST_ASSERT_NOT_NULL(data); |
||||
|
||||
data2 = pktbuf_alloc(128); |
||||
|
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(25)); |
||||
|
||||
pktbuf_release(data2); |
||||
|
||||
TEST_ASSERT(data == pktbuf_realloc(data, 200)); |
||||
} |
||||
|
||||
static void test_pktbuf_realloc_nomemenough(void) |
||||
{ |
||||
void *data, *data2; |
||||
|
||||
data = pktbuf_alloc(128); |
||||
|
||||
TEST_ASSERT_NOT_NULL(data); |
||||
|
||||
data2 = pktbuf_alloc(128); |
||||
|
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(25)); |
||||
|
||||
pktbuf_release(data2); |
||||
|
||||
TEST_ASSERT(data != pktbuf_realloc(data, 512)); |
||||
} |
||||
|
||||
static void test_pktbuf_realloc_unknown_ptr(void) |
||||
{ |
||||
char *data = "abcd", *new_data = pktbuf_realloc(data, 5); |
||||
|
||||
TEST_ASSERT_NOT_NULL(new_data); |
||||
TEST_ASSERT(data != new_data); |
||||
TEST_ASSERT_EQUAL_STRING(data, new_data); |
||||
} |
||||
|
||||
static void test_pktbuf_insert_size_0(void) |
||||
{ |
||||
TEST_ASSERT_NULL(pktbuf_insert("", 0)); |
||||
} |
||||
|
||||
static void test_pktbuf_insert_data_NULL(void) |
||||
{ |
||||
TEST_ASSERT_NULL(pktbuf_insert(NULL, 4)); |
||||
} |
||||
|
||||
static void test_pktbuf_insert_memfull(void) |
||||
{ |
||||
while (pktbuf_insert("abc", 4)); |
||||
|
||||
TEST_ASSERT_NULL(pktbuf_insert("abc", 4)); |
||||
} |
||||
|
||||
static void test_pktbuf_insert_success(void) |
||||
{ |
||||
char *data, *data_prev = NULL; |
||||
|
||||
for (int i = 0; i < 10; i++) { |
||||
data = (char *)pktbuf_insert("abc", 4); |
||||
|
||||
TEST_ASSERT(data_prev < data); |
||||
TEST_ASSERT_EQUAL_STRING("abc", data); |
||||
|
||||
data_prev = data; |
||||
} |
||||
} |
||||
|
||||
#ifdef DEVELHELP |
||||
static void test_pktbuf_copy_efault(void) |
||||
{ |
||||
char *data = (char *)pktbuf_insert("abcd", 5); |
||||
|
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_EQUAL_INT(-EFAULT, pktbuf_copy(data, NULL, 3)); |
||||
TEST_ASSERT_EQUAL_STRING("abcd", data); |
||||
} |
||||
#endif |
||||
|
||||
static void test_pktbuf_copy_data_len_too_long(void) |
||||
{ |
||||
char *data = (char *)pktbuf_insert("ab", 3); |
||||
|
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_EQUAL_INT(-ENOMEM, pktbuf_copy(data, "cdef", 5)); |
||||
TEST_ASSERT_EQUAL_STRING("ab", data); |
||||
} |
||||
|
||||
static void test_pktbuf_copy_data_len_too_long2(void) |
||||
{ |
||||
char *data = (char *)pktbuf_insert("abcd", 5); |
||||
|
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_EQUAL_INT(-ENOMEM, pktbuf_copy(data + 2, "efgh", 5)); |
||||
TEST_ASSERT_EQUAL_STRING("abcd", data); |
||||
} |
||||
|
||||
static void test_pktbuf_copy_data_len_0(void) |
||||
{ |
||||
char *data = (char *)pktbuf_insert("abcd", 5); |
||||
|
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_EQUAL_INT(0, pktbuf_copy(data, "ef", 0)); |
||||
TEST_ASSERT_EQUAL_STRING("abcd", data); |
||||
} |
||||
|
||||
static void test_pktbuf_copy_success(void) |
||||
{ |
||||
char *data = (char *)pktbuf_insert("abcd", 5); |
||||
|
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_EQUAL_INT(3, pktbuf_copy(data, "ef", 3)); |
||||
TEST_ASSERT_EQUAL_STRING("ef", data); |
||||
} |
||||
|
||||
static void test_pktbuf_copy_success2(void) |
||||
{ |
||||
char *data = (char *)pktbuf_insert("abcdef", 7); |
||||
|
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_EQUAL_INT(2, pktbuf_copy(data + 3, "gh", 2)); |
||||
TEST_ASSERT_EQUAL_STRING("abcghf", data); |
||||
} |
||||
|
||||
static void test_pktbuf_hold_ptr_null(void) |
||||
{ |
||||
char *data; |
||||
|
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(25)); |
||||
data = (char *)pktbuf_insert("abcd", 5); |
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(16)); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, pktbuf_packets_allocated()); |
||||
|
||||
pktbuf_hold(NULL); |
||||
pktbuf_release(data); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(2, pktbuf_packets_allocated()); |
||||
TEST_ASSERT_EQUAL_STRING("abcd", data); |
||||
} |
||||
|
||||
static void test_pktbuf_hold_wrong_ptr(void) |
||||
{ |
||||
char *data, wrong; |
||||
|
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(25)); |
||||
data = (char *)pktbuf_insert("abcd", 5); |
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(16)); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, pktbuf_packets_allocated()); |
||||
|
||||
pktbuf_hold(&wrong); |
||||
pktbuf_release(data); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(2, pktbuf_packets_allocated()); |
||||
TEST_ASSERT_EQUAL_STRING("abcd", data); |
||||
} |
||||
|
||||
static void test_pktbuf_hold_success(void) |
||||
{ |
||||
char *data; |
||||
|
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(25)); |
||||
data = (char *)pktbuf_insert("abcd", 5); |
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(16)); |
||||
|
||||
pktbuf_hold(data); |
||||
pktbuf_release(data); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, pktbuf_copy(data, "ef", 3)); |
||||
TEST_ASSERT_EQUAL_STRING("ef", data); |
||||
} |
||||
|
||||
static void test_pktbuf_hold_success2(void) |
||||
{ |
||||
char *data; |
||||
|
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(25)); |
||||
data = (char *)pktbuf_insert("abcd", 5); |
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(16)); |
||||
|
||||
pktbuf_hold(data + 4); |
||||
pktbuf_release(data + 4); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, pktbuf_copy(data, "ef", 3)); |
||||
TEST_ASSERT_EQUAL_STRING("ef", data); |
||||
} |
||||
|
||||
static void test_pktbuf_release_ptr_null(void) |
||||
{ |
||||
char *data; |
||||
|
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(25)); |
||||
data = (char *)pktbuf_insert("abcd", 5); |
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(16)); |
||||
|
||||
pktbuf_release(NULL); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, pktbuf_copy(data, "ef", 3)); |
||||
TEST_ASSERT_EQUAL_STRING("ef", data); |
||||
} |
||||
|
||||
static void test_pktbuf_release_wrong_ptr(void) |
||||
{ |
||||
char *data, wrong; |
||||
|
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(25)); |
||||
data = (char *)pktbuf_insert("abcd", 5); |
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(16)); |
||||
|
||||
pktbuf_release(&wrong); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, pktbuf_copy(data, "ef", 3)); |
||||
TEST_ASSERT_EQUAL_STRING("ef", data); |
||||
} |
||||
|
||||
static void test_pktbuf_release_success(void) |
||||
{ |
||||
char *data; |
||||
|
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(25)); |
||||
data = (char *)pktbuf_insert("abcd", 5); |
||||
TEST_ASSERT_NOT_NULL(data); |
||||
TEST_ASSERT_NOT_NULL(pktbuf_alloc(16)); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, pktbuf_packets_allocated()); |
||||
|
||||
pktbuf_hold(data); |
||||
pktbuf_hold(data); |
||||
pktbuf_release(data + 3); |
||||
pktbuf_release(data + 4); |
||||
pktbuf_release(data + 2); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(2, pktbuf_packets_allocated()); |
||||
} |
||||
|
||||
static void test_pktbuf_release_success2(void) |
||||
{ |
||||
char *data1, *data2, *data3; |
||||
|
||||
data1 = (char *)pktbuf_insert("abcd", 5); |
||||
TEST_ASSERT_NOT_NULL(data1); |
||||
data2 = (char *)pktbuf_insert("ef", 3); |
||||
TEST_ASSERT_NOT_NULL(data2); |
||||
data3 = (char *)pktbuf_insert("ghijkl", 7); |
||||
TEST_ASSERT_NOT_NULL(data3); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, pktbuf_packets_allocated()); |
||||
|
||||
pktbuf_release(data2); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(2, pktbuf_packets_allocated()); |
||||
TEST_ASSERT_EQUAL_INT(2, pktbuf_copy(data1, "m", 2)); |
||||
TEST_ASSERT_EQUAL_STRING("m", data1); |
||||
TEST_ASSERT_EQUAL_INT(4, pktbuf_copy(data3, "nop", 4)); |
||||
TEST_ASSERT_EQUAL_STRING("nop", data3); |
||||
} |
||||
|
||||
static void test_pktbuf_release_success3(void) |
||||
{ |
||||
char *data1, *data2, *data3; |
||||
|
||||
data1 = (char *)pktbuf_insert("abcd", 5); |
||||
TEST_ASSERT_NOT_NULL(data1); |
||||
data2 = (char *)pktbuf_insert("ef", 3); |
||||
TEST_ASSERT_NOT_NULL(data2); |
||||
data3 = (char *)pktbuf_insert("ghijkl", 7); |
||||
TEST_ASSERT_NOT_NULL(data3); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, pktbuf_packets_allocated()); |
||||
|
||||
pktbuf_release(data1); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(2, pktbuf_packets_allocated()); |
||||
TEST_ASSERT_EQUAL_INT(2, pktbuf_copy(data2, "m", 2)); |
||||
TEST_ASSERT_EQUAL_STRING("m", data2); |
||||
TEST_ASSERT_EQUAL_INT(4, pktbuf_copy(data3, "nop", 4)); |
||||
TEST_ASSERT_EQUAL_STRING("nop", data3); |
||||
} |
||||
|
||||
static void test_pktbuf_release_success4(void) |
||||
{ |
||||
char *data1, *data2, *data3; |
||||
|
||||
data1 = (char *)pktbuf_insert("abcd", 5); |
||||
TEST_ASSERT_NOT_NULL(data1); |
||||
data2 = (char *)pktbuf_insert("ef", 3); |
||||
TEST_ASSERT_NOT_NULL(data2); |
||||
data3 = (char *)pktbuf_insert("ghijkl", 7); |
||||
TEST_ASSERT_NOT_NULL(data3); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, pktbuf_packets_allocated()); |
||||
|
||||
pktbuf_release(data3); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(2, pktbuf_packets_allocated()); |
||||
TEST_ASSERT_EQUAL_INT(2, pktbuf_copy(data1, "m", 2)); |
||||
TEST_ASSERT_EQUAL_STRING("m", data1); |
||||
TEST_ASSERT_EQUAL_INT(1, pktbuf_copy(data2, "", 1)); |
||||
TEST_ASSERT_EQUAL_STRING("", data2); |
||||
} |
||||
|
||||
static void test_pktbuf_insert_packed_struct(void) |
||||
{ |
||||
test_pktbuf_struct_t data = { 0x4d, 0xef43, 0xacdef574, 0x43644305695afde5, |
||||
34, -4469, 149699748, -46590430597 |
||||
}; |
||||
test_pktbuf_struct_t *data_cpy; |
||||
|
||||
data_cpy = (test_pktbuf_struct_t *)pktbuf_insert(&data, sizeof(test_pktbuf_struct_t)); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(data.u8, data_cpy->u8); |
||||
TEST_ASSERT_EQUAL_INT(data.u16, data_cpy->u16); |
||||
TEST_ASSERT_EQUAL_INT(data.u32, data_cpy->u32); |
||||
TEST_ASSERT_EQUAL_INT(data.u64, data_cpy->u64); |
||||
TEST_ASSERT_EQUAL_INT(data.s8, data_cpy->s8); |
||||
TEST_ASSERT_EQUAL_INT(data.s16, data_cpy->s16); |
||||
TEST_ASSERT_EQUAL_INT(data.s32, data_cpy->s32); |
||||
TEST_ASSERT_EQUAL_INT(data.s64, data_cpy->s64); |
||||
} |
||||
|
||||
static void test_pktbuf_alloc_off_by_one1(void) |
||||
{ |
||||
char *data1, *data2, *data3, *data4; |
||||
|
||||
data1 = (char *)pktbuf_insert("1234567890a", 12); |
||||
TEST_ASSERT_NOT_NULL(data1); |
||||
data2 = (char *)pktbuf_alloc(44); |
||||
TEST_ASSERT_NOT_NULL(data2); |
||||
data4 = (char *)pktbuf_alloc(4); |
||||
TEST_ASSERT_NOT_NULL(data4); |
||||
TEST_ASSERT_EQUAL_INT(3, pktbuf_packets_allocated()); |
||||
TEST_ASSERT_EQUAL_INT(12 + 44 + 4, pktbuf_bytes_allocated()); |
||||
|
||||
pktbuf_release(data1); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(2, pktbuf_packets_allocated()); |
||||
TEST_ASSERT_EQUAL_INT(44 + 4, pktbuf_bytes_allocated()); |
||||
|
||||
data3 = (char *)pktbuf_insert("bcdefghijklm", 13); |
||||
TEST_ASSERT_NOT_NULL(data3); |
||||
TEST_ASSERT(data1 != data3); |
||||
|
||||
TEST_ASSERT_EQUAL_INT(3, pktbuf_packets_allocated()); |
||||
TEST_ASSERT_EQUAL_INT(44 + 4 + 13, pktbuf_bytes_allocated()); |
||||
} |
||||
|
||||
Test *tests_pktbuf_tests(void) |
||||
{ |
||||
EMB_UNIT_TESTFIXTURES(fixtures) { |
||||
new_TestFixture(test_pktbuf_alloc_0), |
||||
new_TestFixture(test_pktbuf_alloc_memfull), |
||||
new_TestFixture(test_pktbuf_alloc_success), |
||||
new_TestFixture(test_pktbuf_realloc_0), |
||||
new_TestFixture(test_pktbuf_realloc_memfull), |
||||
new_TestFixture(test_pktbuf_realloc_memfull2), |
||||
new_TestFixture(test_pktbuf_realloc_memfull3), |
||||
new_TestFixture(test_pktbuf_realloc_smaller), |
||||
new_TestFixture(test_pktbuf_realloc_memenough), |
||||
new_TestFixture(test_pktbuf_realloc_memenough2), |
||||
new_TestFixture(test_pktbuf_realloc_nomemenough), |
||||
new_TestFixture(test_pktbuf_realloc_unknown_ptr), |
||||
new_TestFixture(test_pktbuf_insert_size_0), |
||||
new_TestFixture(test_pktbuf_insert_data_NULL), |
||||
new_TestFixture(test_pktbuf_insert_memfull), |
||||
new_TestFixture(test_pktbuf_insert_success), |
||||
#ifdef DEVELHELP |
||||
new_TestFixture(test_pktbuf_copy_efault), |
||||
#endif |
||||
new_TestFixture(test_pktbuf_copy_data_len_too_long), |
||||
new_TestFixture(test_pktbuf_copy_data_len_too_long2), |
||||
new_TestFixture(test_pktbuf_copy_data_len_0), |
||||
new_TestFixture(test_pktbuf_copy_success), |
||||
new_TestFixture(test_pktbuf_copy_success2), |
||||
new_TestFixture(test_pktbuf_hold_ptr_null), |
||||
new_TestFixture(test_pktbuf_hold_wrong_ptr), |
||||
new_TestFixture(test_pktbuf_hold_success), |
||||
new_TestFixture(test_pktbuf_hold_success2), |
||||
new_TestFixture(test_pktbuf_release_ptr_null), |
||||
new_TestFixture(test_pktbuf_release_wrong_ptr), |
||||
new_TestFixture(test_pktbuf_release_success), |
||||
new_TestFixture(test_pktbuf_release_success2), |
||||
new_TestFixture(test_pktbuf_release_success3), |
||||
new_TestFixture(test_pktbuf_release_success4), |
||||
new_TestFixture(test_pktbuf_insert_packed_struct), |
||||
new_TestFixture(test_pktbuf_alloc_off_by_one1), |
||||
}; |
||||
|
||||
EMB_UNIT_TESTCALLER(pktbuf_tests, NULL, tear_down, fixtures); |
||||
|
||||
return (Test *)&pktbuf_tests; |
||||
} |
||||
|
||||
void tests_pktbuf(void) |
||||
{ |
||||
TESTS_RUN(tests_pktbuf_tests()); |
||||
} |
||||
/** @} */ |
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Martin Lenders |
||||
* |
||||
* 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. |
||||
*/ |
||||
|
||||
/**
|
||||
* @addtogroup unittests |
||||
* @{ |
||||
* |
||||
* @file tests-pktbuf.h |
||||
* @brief Unittests for the ``pktbuf`` module |
||||
* |
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de> |
||||
*/ |
||||
#ifndef __TESTS_PKTBUF_H_ |
||||
#define __TESTS_PKTBUF_H_ |
||||
|
||||
#include "../unittests.h" |
||||
|
||||
/**
|
||||
* @brief The entry point of this test suite. |
||||
*/ |
||||
void tests_pktbuf(void); |
||||
|
||||
#endif /* __TESTS_PKTBUF_H_ */ |
||||
/** @} */ |
Loading…
Reference in new issue