From c80c04d6ed2b59a9cea13c574e08db5a5aba7d87 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Sat, 7 Feb 2015 13:14:37 +0100 Subject: [PATCH] netreg: Initial import --- sys/Makefile | 6 + sys/include/net/ng_netreg.h | 134 +++++++++++++++++++ sys/include/net/ng_nettype.h | 10 +- sys/net/crosslayer/ng_netreg/Makefile | 1 + sys/net/crosslayer/ng_netreg/ng_netreg.c | 161 +++++++++++++++++++++++ 5 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 sys/include/net/ng_netreg.h create mode 100644 sys/net/crosslayer/ng_netreg/Makefile create mode 100644 sys/net/crosslayer/ng_netreg/ng_netreg.c diff --git a/sys/Makefile b/sys/Makefile index a5470fcea..bb960d61f 100644 --- a/sys/Makefile +++ b/sys/Makefile @@ -1,3 +1,6 @@ +ifneq (,$(filter pkt,$(USEMODULE))) + DIRS += net/crosslayer/pkt +endif ifneq (,$(filter pktbuf,$(USEMODULE))) DIRS += net/crosslayer/pktbuf endif @@ -68,6 +71,9 @@ endif ifneq (,$(filter ng_netif,$(USEMODULE))) DIRS += net/crosslayer/ng_netif endif +ifneq (,$(filter ng_netreg,$(USEMODULE))) + DIRS += net/crosslayer/ng_netreg +endif ifneq (,$(filter netapi,$(USEMODULE))) DIRS += net/crosslayer/netapi endif diff --git a/sys/include/net/ng_netreg.h b/sys/include/net/ng_netreg.h new file mode 100644 index 000000000..631d8212a --- /dev/null +++ b/sys/include/net/ng_netreg.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2015 Martine 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. + */ + +/** + * @defgroup ng_netreg Network protocol registry + * @ingroup net + * @{ + * + * @file + * @brief Definitions to register network protocol PIDs to use with + * @ref net_netapi. + * + * @author Martine Lenders + */ +#ifndef NETREG_H_ +#define NETREG_H_ + +#include + +#include "kernel_types.h" +#include "net/ng_nettype.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Number of maximum entries to @ref ng_netreg + * @def NG_NETREG_SIZE + */ +#ifndef NG_NETREG_SIZE +#define NG_NETREG_SIZE (NG_NETTYPE_NUMOF) +#endif + +/** + * @brief Entry to the @ref ng_netreg + */ +typedef struct ng_netreg_entry { + struct ng_netreg_entry *next; /**< next element in list */ + + /** + * @brief The demultiplexing context for the registering thread. + * + * @details This can be defined by the network protocol themselves. + * E. g. protocol numbers / next header numbers in IPv4/IPv6, + * ports in UDP/TCP, or similar. + */ + uint16_t demux_ctx; + kernel_pid_t pid; /**< The PID of the registering thread */ +} ng_netreg_entry_t; + +/** + * @brief Initializes module. + */ +void ng_netreg_init(void); + +/** + * @brief Registers a thread to the registry. + * + * @details The semantics are: Thread @p pid is interested in packets of + * protocol @p type with context @p demux_ctx. + * + * @param[in] type Type of the protocol. Must not be NG_NETTYPE_UNDEF or + * >= NG_NETTYPE_NUMOF. + * @param[in] demux_ctx The demultiplexing context for the registering thread. + * See ng_netreg_entry_t::demux_ctx. + * @param[in] pid The PID of the registering thread. + * + * @return 0 on success + * @return -ENOMEM if no space is left in the registry. + * @return -EINVAL if @p type was NG_NETTYPE_UNDEF or >= NG_NETTYPE_NUMOF + */ +int ng_netreg_register(ng_nettype_t type, uint16_t demux_ctx, kernel_pid_t pid); + +/** + * @brief Removes a thread from the registry. + * + * @param[in] type Type of the protocol. + * @param[in] demux_ctx The demultiplexing context for the registered thread. + * See ng_netreg_entry_t::demux_ctx. + * @param[in] pid The PID of the registered thread. + */ +void ng_netreg_unregister(ng_nettype_t type, uint16_t demux_ctx, kernel_pid_t pid); + +/** + * @brief Searches for entries with given parameters in the registry and + * returns the first found. + * + * @param[in] type Type of the protocol. + * @param[in] demux_ctx The demultiplexing context for the registered thread. + * See ng_netreg_entry_t::demux_ctx. + * + * @return The first entry fitting the given parameters on success + * @return NULL if no entry can be found. + */ +ng_netreg_entry_t *ng_netreg_lookup(ng_nettype_t type, uint16_t demux_ctx); + +/** + * @brief Returns number of entries with the same ng_netreg_entry_t::type and + * ng_netreg_entry_t::demux_ctx. + * + * @param[in] type Type of the protocol. + * @param[in] demux_ctx The demultiplexing context for the registered thread. + * See ng_netreg_entry_t::demux_ctx. + * + * @return Number of entries with the same ng_netreg_entry_t::type and + * ng_netreg_entry_t::demux_ctx as the given parameters. + */ +int ng_netreg_num(ng_nettype_t type, uint16_t demux_ctx); + +/** + * @brief Returns the next entry after @p entry with the same + * ng_netreg_entry_t::type and ng_netreg_entry_t::demux_ctx as the + * given entry. + * + * @param[in] entry A registry entry retrieved by ng_netreg_lookup() or + * ng_netreg_getnext(). Must not be NULL. + * + * @return The next entry after @p entry fitting the given parameters on success + * @return NULL if no entry new entry can be found. + */ +ng_netreg_entry_t *ng_netreg_getnext(ng_netreg_entry_t *entry); + +#ifdef __cplusplus +} +#endif + +#endif /* NETREG_H_ */ +/** @} */ diff --git a/sys/include/net/ng_nettype.h b/sys/include/net/ng_nettype.h index 8c33ed298..4997c02a6 100644 --- a/sys/include/net/ng_nettype.h +++ b/sys/include/net/ng_nettype.h @@ -51,7 +51,6 @@ typedef enum { /** * @{ * @name Transport layer - * */ #ifdef MODULE_NG_TCP NG_NETTYPE_TCP, /**< Protocol is TCP */ @@ -63,6 +62,15 @@ typedef enum { * @} */ + + /** + * @{ + * @name Testing + */ +#ifdef TEST_SUITES + NG_NETTYPE_TEST, +#endif + NG_NETTYPE_NUMOF, /**< maximum number of available protocols */ } ng_nettype_t; diff --git a/sys/net/crosslayer/ng_netreg/Makefile b/sys/net/crosslayer/ng_netreg/Makefile new file mode 100644 index 000000000..48422e909 --- /dev/null +++ b/sys/net/crosslayer/ng_netreg/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/sys/net/crosslayer/ng_netreg/ng_netreg.c b/sys/net/crosslayer/ng_netreg/ng_netreg.c new file mode 100644 index 000000000..5082819c4 --- /dev/null +++ b/sys/net/crosslayer/ng_netreg/ng_netreg.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2015 Martine 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. + */ + +/** + * @{ + * + * @file ng_netreg.c + */ + +#include +#include + +#include "clist.h" +#include "net/ng_netreg.h" +#include "net/ng_nettype.h" +#include "utlist.h" + +#define _INVALID_TYPE(type) (((type) <= NG_NETTYPE_UNDEF) || ((type) >= NG_NETTYPE_NUMOF)) + +/* The registry as lookup table by ng_nettype_t */ +static ng_netreg_entry_t *netreg[NG_NETTYPE_NUMOF - 1]; /* leave out NG_NETTYPE_UNDEF */ + +/* unstructured pool of entries, marked as unclaimed by + * netreg_entries[i].pid == KERNEL_PID_UNDEF */ +static ng_netreg_entry_t netreg_entries[NG_NETREG_SIZE]; + +void ng_netreg_init(void) +{ + /* set all pointers in registry to NULL */ + memset(netreg, 0, NG_NETTYPE_NUMOF * sizeof(ng_netreg_entry_t *)); + + for (int i = 0; i < NG_NETREG_SIZE; i++) { + netreg_entries[i].pid = KERNEL_PID_UNDEF; /* mark entry pool unclaimed */ + } +} + +static inline int _netreg_entry_equal(ng_netreg_entry_t *a, ng_netreg_entry_t *b) +{ + /* to be pluggable with utlist, so result must be 0 when match */ + return ((a->pid != b->pid) || (a->demux_ctx != b->demux_ctx)); +} + +int ng_netreg_register(ng_nettype_t type, uint16_t demux_ctx, kernel_pid_t pid) +{ + ng_netreg_entry_t *entry = NULL; + + if (_INVALID_TYPE(type)) { + return -EINVAL; + } + + for (int i = 0; i < NG_NETREG_SIZE; i++) { /* Search unclaimed entry */ + if (netreg_entries[i].pid == KERNEL_PID_UNDEF) { + entry = &(netreg_entries[i]); + break; + } + } + + if (entry == NULL) { + return -ENOMEM; + } + + entry->demux_ctx = demux_ctx; + entry->pid = pid; + + if (netreg[type - 1] == NULL) { + netreg[type - 1] = entry; + } + else { + ng_netreg_entry_t *dup; + + /* search for duplicates to new entry */ + LL_SEARCH(netreg[type - 1], dup, entry, _netreg_entry_equal); + + if (dup == NULL) { /* new entry is not a duplicate, add to registry */ + LL_PREPEND(netreg[type - 1], entry); + } + else { /* new entry is a duplicate, mark as unclaimed again */ + entry->pid = KERNEL_PID_UNDEF; + } + } + + return 0; +} + +void ng_netreg_unregister(ng_nettype_t type, uint16_t demux_ctx, kernel_pid_t pid) +{ + ng_netreg_entry_t *entry = netreg[type - 1]; + + if (_INVALID_TYPE(type)) { + return; + } + + while (entry != NULL) { + /* Find entry with given parameters in registry */ + if ((entry->pid == pid) && (entry->demux_ctx == demux_ctx)) { + LL_DELETE(netreg[type - 1], entry); + entry->pid = KERNEL_PID_UNDEF; + + return; + } + + entry = entry->next; + } +} + +ng_netreg_entry_t *ng_netreg_lookup(ng_nettype_t type, uint16_t demux_ctx) +{ + ng_netreg_entry_t *res; + + if (_INVALID_TYPE(type)) { + return NULL; + } + + LL_SEARCH_SCALAR(netreg[type - 1], res, demux_ctx, demux_ctx); + + return res; +} + +int ng_netreg_num(ng_nettype_t type, uint16_t demux_ctx) +{ + int num = 0; + ng_netreg_entry_t *entry; + + if (_INVALID_TYPE(type)) { + return 0; + } + + entry = netreg[type - 1]; + + while (entry != NULL) { + if (entry->demux_ctx == demux_ctx) { + num++; + } + + entry = entry->next; + } + + return num; +} + +ng_netreg_entry_t *ng_netreg_getnext(ng_netreg_entry_t *entry) +{ + uint16_t demux_ctx; + + if (entry == NULL) { + return NULL; + } + + demux_ctx = entry->demux_ctx; + + LL_SEARCH_SCALAR(entry->next, entry, demux_ctx, demux_ctx); + + return entry; +} + +/** @} */