
4 changed files with 224 additions and 0 deletions
@ -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_ */ |
||||
/** @} */ |
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base |
@ -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…
Reference in new issue