Skip to content
Snippets Groups Projects
Commit c80c04d6 authored by Martine Lenders's avatar Martine Lenders
Browse files

netreg: Initial import

parent f3fccf20
Branches
No related tags found
No related merge requests found
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
......
/*
* Copyright (C) 2015 Martine 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 ng_netreg Network protocol registry
* @ingroup net
* @{
*
* @file
* @brief Definitions to register network protocol PIDs to use with
* @ref net_netapi.
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef NETREG_H_
#define NETREG_H_
#include <inttypes.h>
#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_ */
/** @} */
......@@ -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;
......
include $(RIOTBASE)/Makefile.base
/*
* Copyright (C) 2015 Martine 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 ng_netreg.c
*/
#include <errno.h>
#include <string.h>
#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;
}
/** @} */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment