mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
ng_sixlowpan: initial import
This commit is contained in:
parent
07e2dbaf7e
commit
5412e0e68b
@ -48,6 +48,11 @@ ifneq (,$(filter sixlowpan,$(USEMODULE)))
|
||||
USEMODULE += vtimer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter ng_sixlowpan,$(USEMODULE)))
|
||||
USEMODULE += ng_sixlowpan_netif
|
||||
USEMODULE += ng_netbase
|
||||
endif
|
||||
|
||||
ifneq (,$(filter ng_sixlowpan_ctx,$(USEMODULE)))
|
||||
USEMODULE += ng_ipv6_addr
|
||||
USEMODULE += vtimer
|
||||
|
@ -95,6 +95,9 @@ endif
|
||||
ifneq (,$(filter ng_pktbuf,$(USEMODULE)))
|
||||
DIRS += net/crosslayer/ng_pktbuf
|
||||
endif
|
||||
ifneq (,$(filter ng_sixlowpan,$(USEMODULE)))
|
||||
DIRS += net/network_layer/ng_sixlowpan
|
||||
endif
|
||||
ifneq (,$(filter ng_sixlowpan_ctx,$(USEMODULE)))
|
||||
DIRS += net/network_layer/ng_sixlowpan/ctx
|
||||
endif
|
||||
|
@ -82,6 +82,10 @@
|
||||
#include "periph/cpuid.h"
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_NG_SIXLOWPAN
|
||||
#include "net/ng_sixlowpan.h"
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_NG_IPV6
|
||||
#include "net/ng_ipv6.h"
|
||||
#endif
|
||||
@ -284,6 +288,10 @@ void auto_init(void)
|
||||
DEBUG("Auto init ng_pktdump module.\n");
|
||||
ng_pktdump_init();
|
||||
#endif
|
||||
#ifdef MODULE_NG_SIXLOWPAN
|
||||
DEBUG("Auto init ng_sixlowpan module.\n");
|
||||
ng_sixlowpan_init();
|
||||
#endif
|
||||
#ifdef MODULE_NG_IPV6
|
||||
DEBUG("Auto init ng_ipv6 module.\n");
|
||||
ng_ipv6_init();
|
||||
|
@ -49,7 +49,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Default name for the IPv6 thread
|
||||
* @brief Default priority for the IPv6 thread
|
||||
*/
|
||||
#ifndef NG_IPV6_PRIO
|
||||
#define NG_IPV6_PRIO (PRIORITY_MAIN - 3)
|
||||
|
@ -83,6 +83,15 @@ extern "C" {
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @name Flags for the interfaces
|
||||
*/
|
||||
#define NG_IPV6_NETIF_FLAGS_SIXLOWPAN (0x01) /**< interface is 6LoWPAN interface */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Type to represent an IPv6 address registered to an interface.
|
||||
*/
|
||||
|
83
sys/include/net/ng_sixlowpan.h
Normal file
83
sys/include/net/ng_sixlowpan.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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 net_ng_sixlowpan 6LoWPAN
|
||||
* @ingroup net
|
||||
* @brief 6LoWPAN implementation
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Definitions for 6LoWPAN
|
||||
*
|
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
*/
|
||||
#ifndef NG_SIXLOWPAN_H_
|
||||
#define NG_SIXLOWPAN_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "kernel_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Default stack size to use for the 6LoWPAN thread
|
||||
*/
|
||||
#ifndef NG_SIXLOWPAN_STACK_SIZE
|
||||
#define NG_SIXLOWPAN_STACK_SIZE (KERNEL_CONF_STACKSIZE_DEFAULT)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Default priority for the 6LoWPAN thread
|
||||
*/
|
||||
#ifndef NG_SIXLOWPAN_PRIO
|
||||
#define NG_SIXLOWPAN_PRIO (PRIORITY_MAIN - 4)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Default message queue size to use for the 6LoWPAN thread.
|
||||
*/
|
||||
#ifndef NG_SIXLOWPAN_MSG_QUEUE_SIZE
|
||||
#define NG_SIXLOWPAN_MSG_QUEUE_SIZE (8U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Dispatch for uncompressed 6LoWPAN frame.
|
||||
*/
|
||||
#define NG_SIXLOWPAN_UNCOMPRESSED (0x41)
|
||||
|
||||
/**
|
||||
* @brief Checks if dispatch indicats that fram is not a 6LoWPAN (NALP) frame.
|
||||
*
|
||||
* @param[in] disp The first byte of a frame.
|
||||
*
|
||||
* @return true, if frame is a NALP.
|
||||
* @return false, if frame is not a NALP.
|
||||
*/
|
||||
static inline bool ng_sixlowpan_nalp(uint8_t disp)
|
||||
{
|
||||
return (disp & 0x3f);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialization of the 6LoWPAN thread.
|
||||
*
|
||||
* @return The PID to the 6LoWPAN thread, on success.
|
||||
* @return -EOVERFLOW, if there are too many threads running already
|
||||
*/
|
||||
kernel_pid_t ng_sixlowpan_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NG_SIXLOWPAN_H_ */
|
||||
/** @} */
|
@ -135,6 +135,43 @@ static void *_event_loop(void *args)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef MODULE_NG_SIXLOWPAN
|
||||
static void _send_to_iface(kernel_pid_t iface, ng_pktsnip_t *pkt)
|
||||
{
|
||||
ng_ipv6_netif_t *if_entry = ng_ipv6_netif_get(iface);
|
||||
|
||||
((ng_netif_hdr_t *)pkt->data)->if_pid = iface;
|
||||
|
||||
if ((if_entry != NULL) && (if_entry->flags & NG_IPV6_NETIF_FLAGS_SIXLOWPAN)) {
|
||||
DEBUG("ipv6: send to 6LoWPAN instead\n");
|
||||
ng_netreg_entry_t *reg = ng_netreg_lookup(NG_NETTYPE_SIXLOWPAN,
|
||||
NG_NETREG_DEMUX_CTX_ALL);
|
||||
|
||||
if (reg != NULL) {
|
||||
ng_pktbuf_hold(pkt, ng_netreg_num(NG_NETTYPE_SIXLOWPAN,
|
||||
NG_NETREG_DEMUX_CTX_ALL) - 1);
|
||||
}
|
||||
else {
|
||||
DEBUG("ipv6: no 6LoWPAN thread found");
|
||||
}
|
||||
|
||||
while (reg) {
|
||||
ng_netapi_send(reg->pid, pkt);
|
||||
reg = ng_netreg_getnext(reg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ng_netapi_send(iface, pkt);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static inline void _send_to_iface(kernel_pid_t iface, ng_pktsnip_t *pkt)
|
||||
{
|
||||
((ng_netif_hdr_t *)pkt->data)->if_pid = iface;
|
||||
ng_netapi_send(iface, pkt);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* functions for sending */
|
||||
static void _send_unicast(kernel_pid_t iface, uint8_t *dst_l2addr,
|
||||
uint16_t dst_l2addr_len, ng_pktsnip_t *pkt)
|
||||
@ -165,7 +202,7 @@ static void _send_unicast(kernel_pid_t iface, uint8_t *dst_l2addr,
|
||||
|
||||
DEBUG("ipv6: send unicast over interface %" PRIkernel_pid "\n", iface);
|
||||
/* and send to interface */
|
||||
ng_netapi_send(iface, pkt);
|
||||
_send_to_iface(iface, pkt);
|
||||
}
|
||||
|
||||
static int _fill_ipv6_hdr(kernel_pid_t iface, ng_pktsnip_t *ipv6,
|
||||
@ -243,7 +280,7 @@ static inline void _send_multicast_over_iface(kernel_pid_t iface, ng_pktsnip_t *
|
||||
/* mark as multicast */
|
||||
((ng_netif_hdr_t *)netif->data)->flags |= NG_NETIF_HDR_FLAGS_MULTICAST;
|
||||
/* and send to interface */
|
||||
ng_netapi_send(iface, pkt);
|
||||
_send_to_iface(iface, pkt);
|
||||
}
|
||||
|
||||
static void _send_multicast(kernel_pid_t iface, ng_pktsnip_t *pkt,
|
||||
|
1
sys/net/network_layer/ng_sixlowpan/Makefile
Normal file
1
sys/net/network_layer/ng_sixlowpan/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
253
sys/net/network_layer/ng_sixlowpan/ng_sixlowpan.c
Normal file
253
sys/net/network_layer/ng_sixlowpan/ng_sixlowpan.c
Normal file
@ -0,0 +1,253 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "kernel_types.h"
|
||||
#include "net/ng_netbase.h"
|
||||
#include "thread.h"
|
||||
#include "utlist.h"
|
||||
|
||||
#include "net/ng_sixlowpan.h"
|
||||
#include "net/ng_sixlowpan/netif.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
static kernel_pid_t _pid = KERNEL_PID_UNDEF;
|
||||
static char _stack[NG_SIXLOWPAN_STACK_SIZE];
|
||||
|
||||
/* handles NG_NETAPI_MSG_TYPE_RCV commands */
|
||||
void _receive(ng_pktsnip_t *pkt);
|
||||
/* handles NG_NETAPI_MSG_TYPE_SND commands */
|
||||
void _send(ng_pktsnip_t *pkt);
|
||||
/* Main event loop for 6LoWPAN */
|
||||
static void *_event_loop(void *args);
|
||||
|
||||
kernel_pid_t ng_sixlowpan_init(void)
|
||||
{
|
||||
if (_pid > KERNEL_PID_UNDEF) {
|
||||
return _pid;
|
||||
}
|
||||
|
||||
_pid = thread_create(_stack, NG_SIXLOWPAN_STACK_SIZE, NG_SIXLOWPAN_PRIO,
|
||||
CREATE_STACKTEST, _event_loop, NULL, "6lo");
|
||||
|
||||
return _pid;
|
||||
}
|
||||
|
||||
void _receive(ng_pktsnip_t *pkt)
|
||||
{
|
||||
ng_pktsnip_t *payload;
|
||||
uint8_t *dispatch;
|
||||
ng_netreg_entry_t *entry;
|
||||
|
||||
LL_SEARCH_SCALAR(pkt, payload, type, NG_NETTYPE_SIXLOWPAN);
|
||||
|
||||
if ((payload == NULL) || (payload->size < 1)) {
|
||||
DEBUG("6lo: Received packet has no 6LoWPAN payload\n");
|
||||
ng_pktbuf_release(pkt);
|
||||
}
|
||||
|
||||
dispatch = payload->data;
|
||||
|
||||
if (dispatch[0] == NG_SIXLOWPAN_UNCOMPRESSED) {
|
||||
ng_pktsnip_t *sixlowpan;
|
||||
DEBUG("6lo: received uncompressed IPv6 packet\n");
|
||||
payload = ng_pktbuf_start_write(payload);
|
||||
|
||||
if (payload == NULL) {
|
||||
DEBUG("6lo: can not get write access on received packet\n");
|
||||
#if defined(DEVELHELP) && defined(ENABLE_DEBUG)
|
||||
ng_pktbuf_stats();
|
||||
#endif
|
||||
ng_pktbuf_release(pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
/* packet is uncompressed: just mark and remove the dispatch */
|
||||
sixlowpan = ng_pktbuf_add(payload, payload->data, sizeof(uint8_t),
|
||||
NG_NETTYPE_SIXLOWPAN);
|
||||
LL_DELETE(pkt, sixlowpan);
|
||||
ng_pktbuf_release(sixlowpan);
|
||||
}
|
||||
else {
|
||||
DEBUG("6lo: dispatch %02x ... is not supported\n",
|
||||
dispatch[0]);
|
||||
ng_pktbuf_release(pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
payload->type = NG_NETTYPE_IPV6;
|
||||
|
||||
entry = ng_netreg_lookup(NG_NETTYPE_IPV6, NG_NETREG_DEMUX_CTX_ALL);
|
||||
|
||||
if (entry == NULL) {
|
||||
DEBUG("ipv6: No receivers for this packet found\n");
|
||||
ng_pktbuf_release(pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
ng_pktbuf_hold(pkt, ng_netreg_num(NG_NETTYPE_IPV6, NG_NETREG_DEMUX_CTX_ALL) - 1);
|
||||
|
||||
while (entry) {
|
||||
DEBUG("6lo: Send receive command for %p to %" PRIu16 "\n",
|
||||
(void *)pkt, entry->pid);
|
||||
ng_netapi_receive(entry->pid, pkt);
|
||||
entry = ng_netreg_getnext(entry);
|
||||
}
|
||||
}
|
||||
|
||||
void _send(ng_pktsnip_t *pkt)
|
||||
{
|
||||
ng_netif_hdr_t *hdr;
|
||||
ng_pktsnip_t *ipv6, *sixlowpan;
|
||||
ng_sixlowpan_netif_t *iface;
|
||||
/* cppcheck: datagram_size will be read by frag */
|
||||
/* cppcheck-suppress unreadVariable */
|
||||
size_t payload_len, datagram_size;
|
||||
uint16_t max_frag_size;
|
||||
uint8_t *disp;
|
||||
|
||||
if ((pkt == NULL) || (pkt->size < sizeof(ng_netif_hdr_t))) {
|
||||
DEBUG("6lo: Sending packet has no netif header\n");
|
||||
ng_pktbuf_release(pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
hdr = pkt->data;
|
||||
ipv6 = pkt->next;
|
||||
|
||||
if ((ipv6 == NULL) || (ipv6->type != NG_NETTYPE_IPV6)) {
|
||||
DEBUG("6lo: Sending packet has no IPv6 header\n");
|
||||
ng_pktbuf_release(pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
/* payload length and datagram size are different in that the payload
|
||||
* length is the length of the IPv6 datagram + 6LoWPAN dispatches,
|
||||
* while the datagram size is the size of only the IPv6 datagram */
|
||||
payload_len = ng_pkt_len(ipv6);
|
||||
/* cppcheck: datagram_size will be read by ng_sixlowpan_frag implementation */
|
||||
/* cppcheck-suppress unreadVariable */
|
||||
datagram_size = (uint16_t)payload_len;
|
||||
|
||||
/* use sixlowpan packet snip as temporary one */
|
||||
sixlowpan = ng_pktbuf_start_write(pkt);
|
||||
|
||||
if (sixlowpan == NULL) {
|
||||
DEBUG("6lo: no space left in packet buffer\n");
|
||||
ng_pktbuf_release(pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
pkt = sixlowpan;
|
||||
|
||||
DEBUG("6lo: Send uncompressed\n");
|
||||
|
||||
sixlowpan = ng_pktbuf_add(NULL, NULL, sizeof(uint8_t), NG_NETTYPE_SIXLOWPAN);
|
||||
|
||||
if (sixlowpan == NULL) {
|
||||
DEBUG("6lo: no space left in packet buffer\n");
|
||||
ng_pktbuf_release(pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
sixlowpan->next = ipv6;
|
||||
pkt->next = sixlowpan;
|
||||
disp = sixlowpan->data;
|
||||
disp[0] = NG_SIXLOWPAN_UNCOMPRESSED;
|
||||
payload_len++;
|
||||
|
||||
iface = ng_sixlowpan_netif_get(hdr->if_pid);
|
||||
|
||||
if (iface == NULL) {
|
||||
if (ng_netapi_get(hdr->if_pid, NETCONF_OPT_MAX_PACKET_SIZE,
|
||||
0, &max_frag_size, sizeof(max_frag_size)) < 0) {
|
||||
/* if error we assume it works */
|
||||
DEBUG("6lo: can not get max packet size from interface %"
|
||||
PRIkernel_pid "\n", hdr->if_pid);
|
||||
max_frag_size = UINT16_MAX;
|
||||
}
|
||||
|
||||
ng_sixlowpan_netif_add(hdr->if_pid, max_frag_size);
|
||||
}
|
||||
else {
|
||||
max_frag_size = iface->max_frag_size;
|
||||
}
|
||||
|
||||
DEBUG("6lo: max_frag_size = %" PRIu16 " for interface %"
|
||||
PRIkernel_pid "\n", max_frag_size, hdr->if_pid);
|
||||
|
||||
/* IP should not send anything here if it is not a 6LoWPAN interface,
|
||||
* so we don't need to check for NULL pointers */
|
||||
if (payload_len <= max_frag_size) {
|
||||
DEBUG("6lo: Send SND command for %p to %" PRIu16 "\n",
|
||||
(void *)pkt, hdr->if_pid);
|
||||
ng_netapi_send(hdr->if_pid, pkt);
|
||||
|
||||
return;
|
||||
}
|
||||
DEBUG("6lo: packet too big (%u> %" PRIu16 ")\n",
|
||||
(unsigned int)payload_len, max_frag_size);
|
||||
}
|
||||
|
||||
static void *_event_loop(void *args)
|
||||
{
|
||||
msg_t msg, reply, msg_q[NG_SIXLOWPAN_MSG_QUEUE_SIZE];
|
||||
ng_netreg_entry_t me_reg;
|
||||
|
||||
(void)args;
|
||||
msg_init_queue(msg_q, NG_SIXLOWPAN_MSG_QUEUE_SIZE);
|
||||
|
||||
me_reg.demux_ctx = NG_NETREG_DEMUX_CTX_ALL;
|
||||
me_reg.pid = thread_getpid();
|
||||
|
||||
/* register interest in all 6LoWPAN packets */
|
||||
ng_netreg_register(NG_NETTYPE_SIXLOWPAN, &me_reg);
|
||||
|
||||
/* preinitialize ACK */
|
||||
reply.type = NG_NETAPI_MSG_TYPE_ACK;
|
||||
|
||||
/* start event loop */
|
||||
while (1) {
|
||||
DEBUG("6lo: waiting for incoming message.\n");
|
||||
msg_receive(&msg);
|
||||
|
||||
switch (msg.type) {
|
||||
case NG_NETAPI_MSG_TYPE_RCV:
|
||||
DEBUG("6lo: NG_NETDEV_MSG_TYPE_RCV received\n");
|
||||
_receive((ng_pktsnip_t *)msg.content.ptr);
|
||||
break;
|
||||
|
||||
case NG_NETAPI_MSG_TYPE_SND:
|
||||
DEBUG("6lo: NG_NETDEV_MSG_TYPE_SND received\n");
|
||||
_send((ng_pktsnip_t *)msg.content.ptr);
|
||||
break;
|
||||
|
||||
case NG_NETAPI_MSG_TYPE_GET:
|
||||
case NG_NETAPI_MSG_TYPE_SET:
|
||||
DEBUG("6lo: reply to unsupported get/set\n");
|
||||
reply.content.value = -ENOTSUP;
|
||||
msg_reply(&msg, &reply);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG("6lo: operation not supported\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** @} */
|
Loading…
Reference in New Issue
Block a user