Browse Source

net: added ng_nomac module

dev/timer
Hauke Petersen 8 years ago
parent
commit
549867b57e
  1. 3
      sys/Makefile
  2. 63
      sys/include/net/ng_nomac.h
  3. 1
      sys/net/link_layer/ng_nomac/Makefile
  4. 157
      sys/net/link_layer/ng_nomac/ng_nomac.c

3
sys/Makefile

@ -86,6 +86,9 @@ endif
ifneq (,$(filter nhdp,$(USEMODULE)))
DIRS += net/routing/nhdp
endif
ifneq (,$(filter ng_nomac,$(USEMODULE)))
DIRS += net/link_layer/ng_nomac
endif
DIRS += $(dir $(wildcard $(addsuffix /Makefile, ${USEMODULE})))

63
sys/include/net/ng_nomac.h

@ -0,0 +1,63 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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 net_nomac Simplest possible MAC layer
* @ingroup net
* @brief Simplest possible MAC protocol that sends without considering
* the state of the medium
* @{
*
* @file
* @brief Interface definition for the NOMAC MAC layer
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef NG_NOMAC_H_
#define NG_NOMAC_H_
#include "kernel.h"
#include "net/ng_netdev.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Set the default message queue size for NOMAC layers
*/
#ifndef NG_NOMAC_MSG_QUEUE_SIZE
#define NG_NOMAC_MSG_QUEUE_SIZE (8U)
#endif
/**
* @brief Initialize an instance of the NOMAC layer
*
* The initialization starts a new thread that connects to the given netdev
* device and starts a link layer event loop.
*
* @param[in] stack stack for the control thread
* @param[in] stacksize size of *stack*
* @param[in] priority priority for the thread housing the NOMAC instance
* @param[in] name name of the thread housing the NOMAC instance
* @param[in] dev netdev device, needs to be already initialized
*
* @return PID of NOMAC thread on success
* @return -EINVAL if creation of thread fails
* @return -ENODEV if *dev* is invalid
*/
kernel_pid_t ng_nomac_init(char *stack, int stacksize, char priority,
const char *name, ng_netdev_t *dev);
#ifdef __cplusplus
}
#endif
#endif /* __NOMAC_H_ */
/** @} */

1
sys/net/link_layer/ng_nomac/Makefile

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

157
sys/net/link_layer/ng_nomac/ng_nomac.c

@ -0,0 +1,157 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
*
* 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_nomac
* @file
* @brief Implementation of the NOMAC MAC protocol
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @}
*/
#include <errno.h>
#include "kernel.h"
#include "msg.h"
#include "thread.h"
#include "net/ng_nomac.h"
#include "net/ng_netreg.h"
#include "net/ng_pkt.h"
#include "net/ng_nettype.h"
#include "net/ng_netdev.h"
#include "net/ng_netapi.h"
#include "net/ng_netif.h"
#include "net/ng_pktbuf.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
/**
* @brief Function called by the device driver on device events
*
* @param[in] event type of event
* @param[in] data optional parameter
*/
static void _event_cb(ng_netdev_event_t event, void *data)
{
DEBUG("nomac: event triggered -> %i\n", event);
/* NOMAC only understands the RX_COMPLETE event... */
if (event == NETDEV_EVENT_RX_COMPLETE) {
ng_pktsnip_t *pkt;
ng_netreg_entry_t *sendto;
/* get pointer to the received packet */
pkt = (ng_pktsnip_t *)data;
/* find out, who to send the packet to */
sendto = ng_netreg_lookup(pkt->type, NG_NETREG_DEMUX_CTX_ALL);
/* throw away packet if no one is interested */
if (sendto == NULL) {
DEBUG("nomac: unable to forward packet of type %i\n", pkt->type);
ng_pktbuf_release(pkt);
}
/* send the packet to everyone interested in it's type */
ng_pktbuf_hold(pkt, ng_netreg_num(pkt->type, NG_NETREG_DEMUX_CTX_ALL) - 1);
while (sendto != NULL) {
DEBUG("nomac: sending pkt %p to PID %u\n", pkt, sendto->pid);
ng_netapi_send(sendto->pid, pkt);
sendto = ng_netreg_getnext(sendto);
}
}
}
/**
* @brief Startup code and event loop of the NOMAC layer
*
* @param[in] args expects a pointer to the underlying netdev device
*
* @return never returns
*/
static void *_nomac_thread(void *args)
{
ng_netdev_t *dev = (ng_netdev_t *)args;
ng_netapi_opt_t *opt;
int res;
msg_t msg, reply, msg_queue[NG_NOMAC_MSG_QUEUE_SIZE];
/* setup the MAC layers message queue */
msg_init_queue(msg_queue, NG_NOMAC_MSG_QUEUE_SIZE);
/* save the PID to the device descriptor and register the device */
dev->mac_pid = thread_getpid();
ng_netif_add(dev->mac_pid);
/* register the event callback with the device driver */
dev->driver->add_event_callback(dev, _event_cb);
/* start the event loop */
while (1) {
DEBUG("nomac: waiting for incoming messages\n");
msg_receive(&msg);
/* dispatch NETDEV and NETAPI messages */
switch (msg.type) {
case NG_NETDEV_MSG_TYPE_EVENT:
DEBUG("nomac: NG_NETDEV_MSG_TYPE_EVENT received\n");
dev->driver->isr_event(dev, msg.content.value);
break;
case NG_NETAPI_MSG_TYPE_SND:
DEBUG("nomac: NG_NETAPI_MSG_TYPE_SND received\n");
dev->driver->send_data(dev, (ng_pktsnip_t *)msg.content.ptr);
break;
case NG_NETAPI_MSG_TYPE_SET:
/* TODO: filter out MAC layer options -> for now forward
everything to the device driver */
DEBUG("nomac: NG_NETAPI_MSG_TYPE_SET received\n");
/* read incoming options */
opt = (ng_netapi_opt_t *)msg.content.ptr;
/* set option for device driver */
res = dev->driver->set(dev, opt->opt, opt->data, opt->data_len);
/* send reply to calling thread */
reply.type = NG_NETAPI_MSG_TYPE_ACK;
reply.content.value = (uint32_t)res;
msg_reply(&msg, &reply);
break;
case NG_NETAPI_MSG_TYPE_GET:
/* TODO: filter out MAC layer options -> for now forward
everything to the device driver */
DEBUG("nomac: NG_NETAPI_MSG_TYPE_GET received\n");
/* read incoming options */
opt = (ng_netapi_opt_t *)msg.content.ptr;
/* get option from device driver */
res = dev->driver->get(dev, opt->opt, opt->data,
(size_t*)(&(opt->data_len)));
/* send reply to calling thread */
reply.type = NG_NETAPI_MSG_TYPE_ACK;
reply.content.value = (uint32_t)res;
msg_reply(&msg, &reply);
break;
default:
DEBUG("nomac: Unknown command %" PRIu16 "\n", msg.type);
break;
}
}
/* never reached */
return NULL;
}
kernel_pid_t ng_nomac_init(char *stack, int stacksize, char priority,
const char *name, ng_netdev_t *dev)
{
kernel_pid_t res;
/* check if given netdev device is defined and the driver is set */
if (dev == NULL || dev->driver == NULL) {
return -ENODEV;
}
/* create new NOMAC thread */
res = thread_create(stack, stacksize, priority, CREATE_STACKTEST,
_nomac_thread, (void *)dev, name);
if (res <= 0) {
return -EINVAL;
}
return res;
}
Loading…
Cancel
Save