mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-24 22:13:52 +01:00
Merge pull request #133 from authmillenon/sixlowpan_refactor
Refactor 6LoWPAN module
This commit is contained in:
commit
9fdae28876
@ -39,4 +39,7 @@ ifneq (,$(findstring sixlowpan,$(USEMODULE)))
|
||||
ifeq (,$(findstring ieee802154,$(USEMODULE)))
|
||||
USEMODULE += ieee802154
|
||||
endif
|
||||
ifeq (,$(findstring net_help,$(USEMODULE)))
|
||||
USEMODULE += net_help
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
MODULE:=$(shell basename $(CURDIR))
|
||||
INCLUDES = -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/sys/net
|
||||
INCLUDES = -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/sys/net/destiny -I$(RIOTBASE)/sys/net/sixlowpan/include -I$(RIOTBASE)/sys/net/net_help/
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
||||
@ -40,7 +40,7 @@ void init_transport_layer(void)
|
||||
int udp_thread_pid = thread_create(udp_stack_buffer, UDP_STACK_SIZE,
|
||||
PRIORITY_MAIN, CREATE_STACKTEST,
|
||||
udp_packet_handler,"udp_packet_handler");
|
||||
set_udp_packet_handler_pid(udp_thread_pid);
|
||||
ipv6_register_next_header_handler(IPV6_PROTO_NUM_UDP, udp_thread_pid);
|
||||
|
||||
/* TCP */
|
||||
timex_t now;
|
||||
@ -55,7 +55,7 @@ void init_transport_layer(void)
|
||||
int tcp_thread_pid = thread_create(tcp_stack_buffer, TCP_STACK_SIZE,
|
||||
PRIORITY_MAIN, CREATE_STACKTEST,
|
||||
tcp_packet_handler, "tcp_packet_handler");
|
||||
set_tcp_packet_handler_pid(tcp_thread_pid);
|
||||
ipv6_register_next_header_handler(IPV6_PROTO_NUM_TCP, tcp_thread_pid);
|
||||
|
||||
thread_create(tcp_timer_stack, TCP_TIMER_STACKSIZE, PRIORITY_MAIN + 1,
|
||||
CREATE_STACKTEST, tcp_general_timer, "tcp_general_timer");
|
||||
|
||||
@ -13,7 +13,8 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Protocols (RFC 1700)
|
||||
* Protocols (RFC 1700) TODO: may be deleted due to some double definition
|
||||
* in sys/net/sixlowpan/include/sixlowpan/ip.h
|
||||
*/
|
||||
#define IPPROTO_IP (0) /* dummy for IP */
|
||||
#define IPPROTO_HOPOPTS (0) /* IP6 hop-by-hop options */
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include "ipv6.h"
|
||||
#include "udp.h"
|
||||
#include "tcp.h"
|
||||
#include "socket.h"
|
||||
@ -99,12 +100,13 @@ void print_tcp_cb(tcp_cb_t *cb)
|
||||
void print_tcp_status(int in_or_out, ipv6_hdr_t *ipv6_header,
|
||||
tcp_hdr_t *tcp_header, socket_t *tcp_socket)
|
||||
{
|
||||
char addr_str[IPV6_MAX_ADDR_STR_LEN];
|
||||
printf("--- %s TCP packet: ---\n",
|
||||
(in_or_out == INC_PACKET ? "Incoming" : "Outgoing"));
|
||||
printf("IPv6 Source:");
|
||||
ipv6_print_addr(&ipv6_header->srcaddr);
|
||||
printf("IPv6 Dest:");
|
||||
ipv6_print_addr(&ipv6_header->destaddr);
|
||||
printf("IPv6 Source: %s\n",
|
||||
ipv6_addr_to_str(addr_str, &ipv6_header->srcaddr));
|
||||
printf("IPv6 Dest: %s\n",
|
||||
ipv6_addr_to_str(addr_str, &ipv6_header->destaddr));
|
||||
printf("TCP Length: %x\n", ipv6_header->length - TCP_HDR_LEN);
|
||||
printf("Source Port: %x, Dest. Port: %x\n",
|
||||
NTOHS(tcp_header->src_port), NTOHS(tcp_header->dst_port));
|
||||
@ -123,12 +125,17 @@ void print_tcp_status(int in_or_out, ipv6_hdr_t *ipv6_header,
|
||||
|
||||
void print_socket(socket_t *current_socket)
|
||||
{
|
||||
char addr_str[IPV6_MAX_ADDR_STR_LEN];
|
||||
printf("Domain: %i, Type: %i, Protocol: %i \n",
|
||||
current_socket->domain,
|
||||
current_socket->type,
|
||||
current_socket->protocol);
|
||||
ipv6_print_addr(¤t_socket->local_address.sin6_addr);
|
||||
ipv6_print_addr(¤t_socket->foreign_address.sin6_addr);
|
||||
printf("Local address: %s\n",
|
||||
ipv6_addr_to_str(addr_str,
|
||||
¤t_socket->local_address.sin6_addr));
|
||||
printf("Foreign address: %s\n",
|
||||
ipv6_addr_to_str(addr_str,
|
||||
¤t_socket->foreign_address.sin6_addr));
|
||||
printf("Local Port: %u, Foreign Port: %u\n",
|
||||
NTOHS(current_socket->local_address.sin6_port),
|
||||
NTOHS(current_socket->foreign_address.sin6_port));
|
||||
@ -293,11 +300,11 @@ socket_internal_t *get_udp_socket(ipv6_hdr_t *ipv6_header, udp_hdr_t *udp_header
|
||||
bool is_four_touple(socket_internal_t *current_socket, ipv6_hdr_t *ipv6_header,
|
||||
tcp_hdr_t *tcp_header)
|
||||
{
|
||||
return ((ipv6_get_addr_match(¤t_socket->socket_values.local_address.sin6_addr,
|
||||
&ipv6_header->destaddr) == 128) &&
|
||||
return (ipv6_addr_is_equal(¤t_socket->socket_values.local_address.sin6_addr,
|
||||
&ipv6_header->destaddr) &&
|
||||
(current_socket->socket_values.local_address.sin6_port == tcp_header->dst_port) &&
|
||||
(ipv6_get_addr_match(¤t_socket->socket_values.foreign_address.sin6_addr,
|
||||
&ipv6_header->srcaddr) == 128) &&
|
||||
ipv6_addr_is_equal(¤t_socket->socket_values.foreign_address.sin6_addr,
|
||||
&ipv6_header->srcaddr) &&
|
||||
(current_socket->socket_values.foreign_address.sin6_port == tcp_header->src_port));
|
||||
}
|
||||
|
||||
@ -469,15 +476,15 @@ int send_tcp(socket_internal_t *current_socket, tcp_hdr_t *current_tcp_packet,
|
||||
return -1;
|
||||
}
|
||||
|
||||
sixlowpan_send(¤t_tcp_socket->foreign_address.sin6_addr,
|
||||
(uint8_t *)(current_tcp_packet), compressed_size,
|
||||
IPPROTO_TCP);
|
||||
ipv6_sendto(¤t_tcp_socket->foreign_address.sin6_addr,
|
||||
IPPROTO_TCP, (uint8_t *)(current_tcp_packet),
|
||||
compressed_size);
|
||||
return 1;
|
||||
#else
|
||||
switch_tcp_packet_byte_order(current_tcp_packet);
|
||||
sixlowpan_send(¤t_tcp_socket->foreign_address.sin6_addr,
|
||||
(uint8_t *)(current_tcp_packet),
|
||||
header_length * 4 + payload_length, IPPROTO_TCP);
|
||||
ipv6_sendto(¤t_tcp_socket->foreign_address.sin6_addr,
|
||||
IPPROTO_TCP, (uint8_t *)(current_tcp_packet),
|
||||
header_length * 4 + payload_length);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
@ -515,7 +522,7 @@ int connect(int socket, sockaddr6_t *addr, uint32_t addrlen)
|
||||
current_int_tcp_socket->recv_pid = thread_getpid();
|
||||
|
||||
/* Local address information */
|
||||
ipv6_get_saddr(&src_addr, &addr->sin6_addr);
|
||||
ipv6_iface_get_best_src_addr(&src_addr, &addr->sin6_addr);
|
||||
set_socket_address(¤t_tcp_socket->local_address, PF_INET6,
|
||||
HTONS(get_free_source_port(IPPROTO_TCP)), 0, &src_addr);
|
||||
|
||||
@ -978,7 +985,7 @@ int32_t sendto(int s, const void *msg, uint32_t len, int flags,
|
||||
uint8_t *payload = &send_buffer[IPV6_HDR_LEN + UDP_HDR_LEN];
|
||||
|
||||
memcpy(&(temp_ipv6_header->destaddr), &to->sin6_addr, 16);
|
||||
ipv6_get_saddr(&(temp_ipv6_header->srcaddr), &(temp_ipv6_header->destaddr));
|
||||
ipv6_iface_get_best_src_addr(&(temp_ipv6_header->srcaddr), &(temp_ipv6_header->destaddr));
|
||||
|
||||
current_udp_packet->src_port = get_free_source_port(IPPROTO_UDP);
|
||||
current_udp_packet->dst_port = to->sin6_port;
|
||||
@ -991,8 +998,9 @@ int32_t sendto(int s, const void *msg, uint32_t len, int flags,
|
||||
current_udp_packet->checksum = ~udp_csum(temp_ipv6_header,
|
||||
current_udp_packet);
|
||||
|
||||
sixlowpan_send(&to->sin6_addr, (uint8_t *)(current_udp_packet),
|
||||
current_udp_packet->length, IPPROTO_UDP);
|
||||
ipv6_sendto(&to->sin6_addr, IPPROTO_UDP,
|
||||
(uint8_t *)(current_udp_packet),
|
||||
current_udp_packet->length);
|
||||
return current_udp_packet->length;
|
||||
}
|
||||
else {
|
||||
|
||||
@ -20,10 +20,11 @@
|
||||
#define SOCKET_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ipv6.h"
|
||||
#include "tcp.h"
|
||||
#include "udp.h"
|
||||
#include "in.h"
|
||||
#include "../sixlowpan/sixlowip.h"
|
||||
#include "ipv6.h"
|
||||
|
||||
/*
|
||||
* POSIX compatibility
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
#include "socket.h"
|
||||
#include "../net_help/net_help.h"
|
||||
#include "../net_help/msg_help.h"
|
||||
#include "../sixlowpan/sixlowpan.h"
|
||||
#include "sixlowpan.h"
|
||||
|
||||
void printTCPHeader(tcp_hdr_t *tcp_header)
|
||||
{
|
||||
|
||||
@ -78,7 +78,7 @@ enum tcp_codes {
|
||||
|
||||
#define TCP_STACK_SIZE 1024
|
||||
|
||||
#include "../sixlowpan/sixlowip.h"
|
||||
#include "ipv6.h"
|
||||
|
||||
typedef struct __attribute__((packed)) tcp_mms_o_t {
|
||||
uint8_t kind;
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
#include "tcp_hc.h"
|
||||
#include "socket.h"
|
||||
#include "tcp.h"
|
||||
#include "../sixlowpan/sixlowip.h"
|
||||
#include "ipv6.h"
|
||||
#include "../net_help/net_help.h"
|
||||
|
||||
#ifdef TCP_HC
|
||||
@ -37,10 +37,10 @@ socket_internal_t *get_tcp_socket_by_context(ipv6_hdr_t *current_ipv6_header,
|
||||
temp_socket = getSocket(i);
|
||||
|
||||
if ((temp_socket != NULL) &&
|
||||
(ipv6_get_addr_match(&temp_socket->socket_values.foreign_address.sin6_addr,
|
||||
¤t_ipv6_header->srcaddr) == 128) &&
|
||||
(ipv6_get_addr_match(&temp_socket->socket_values.local_address.sin6_addr,
|
||||
¤t_ipv6_header->destaddr) == 128) &&
|
||||
ipv6_addr_is_equal(&temp_socket->socket_values.foreign_address.sin6_addr,
|
||||
¤t_ipv6_header->srcaddr) &&
|
||||
ipv6_addr_is_equal(&temp_socket->socket_values.local_address.sin6_addr,
|
||||
¤t_ipv6_header->destaddr) &&
|
||||
(temp_socket->socket_values.tcp_control.tcp_context.context_id ==
|
||||
current_context)) {
|
||||
return temp_socket;
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
#define TCP_HC_H_
|
||||
|
||||
#include "tcp.h"
|
||||
#include "../sixlowpan/sixlowip.h"
|
||||
#include "sixlowpan.h"
|
||||
#include "socket.h"
|
||||
|
||||
#ifdef TCP_HC
|
||||
|
||||
@ -26,8 +26,8 @@
|
||||
#include "thread.h"
|
||||
#include "destiny.h"
|
||||
#include "socket.h"
|
||||
#include "net_help/msg_help.h"
|
||||
#include "../sixlowpan/sixlowpan.h"
|
||||
#include "../net_help/msg_help.h"
|
||||
#include "sixlowpan.h"
|
||||
|
||||
void handle_synchro_timeout(socket_internal_t *current_socket)
|
||||
{
|
||||
|
||||
@ -22,8 +22,8 @@
|
||||
|
||||
#include "udp.h"
|
||||
#include "msg.h"
|
||||
#include "../sixlowpan/sixlowip.h"
|
||||
#include "../sixlowpan/sixlowpan.h"
|
||||
#include "ipv6.h"
|
||||
#include "sixlowpan.h"
|
||||
#include "socket.h"
|
||||
#include "in.h"
|
||||
#include "../net_help/net_help.h"
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
#define UDP_STACK_SIZE 512
|
||||
|
||||
#include "../sixlowpan/sixlowip.h"
|
||||
#include "ipv6.h"
|
||||
|
||||
typedef struct __attribute__((packed)) udp_h_t {
|
||||
uint16_t src_port;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
MODULE:=$(shell basename $(CURDIR))
|
||||
INCLUDES = -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include
|
||||
INCLUDES = -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/sys/net/sixlowpan/include
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
||||
@ -15,11 +15,11 @@
|
||||
#include <thread.h>
|
||||
#include <transceiver.h>
|
||||
|
||||
#include "sixlowpan/sixlowmac.h"
|
||||
#include "sixlowpan.h"
|
||||
#include "ieee802154/ieee802154_frame.h"
|
||||
|
||||
//prototytpes
|
||||
static uint8_t etx_count_packet_tx(etx_neighbor_t * candidate);
|
||||
static uint8_t etx_count_packet_tx(etx_neighbor_t *candidate);
|
||||
static void etx_set_packets_received(void);
|
||||
static bool etx_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2);
|
||||
|
||||
@ -89,37 +89,42 @@ transceiver_command_t tcmd;
|
||||
msg_t mesg;
|
||||
|
||||
//RPL-address
|
||||
static ipv6_addr_t * own_address;
|
||||
static ipv6_addr_t *own_address;
|
||||
|
||||
static etx_probe_t * etx_get_send_buf(void) {
|
||||
static etx_probe_t *etx_get_send_buf(void)
|
||||
{
|
||||
return ((etx_probe_t *) &(etx_send_buf[0]));
|
||||
}
|
||||
static etx_probe_t * etx_get_rec_buf(void) {
|
||||
static etx_probe_t *etx_get_rec_buf(void)
|
||||
{
|
||||
return ((etx_probe_t *) &(etx_rec_buf[0]));
|
||||
}
|
||||
|
||||
void show_candidates(void) {
|
||||
etx_neighbor_t * candidate;
|
||||
void show_candidates(void)
|
||||
{
|
||||
etx_neighbor_t *candidate;
|
||||
etx_neighbor_t *end;
|
||||
|
||||
for (candidate = &candidates[0], end = candidates
|
||||
+ ETX_MAX_CANDIDATE_NEIGHBORS; candidate < end;
|
||||
candidate++) {
|
||||
+ ETX_MAX_CANDIDATE_NEIGHBORS; candidate < end;
|
||||
candidate++) {
|
||||
if (candidate->used == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Candidates Addr:%d\n"
|
||||
"\t cur_etx:%f\n"
|
||||
"\t packets_rx:%d\n"
|
||||
"\t packets_tx:%d\n"
|
||||
"\t used:%d\n", candidate->addr.uint8[ETX_IPV6_LAST_BYTE],
|
||||
candidate->cur_etx, candidate->packets_rx,
|
||||
etx_count_packet_tx(candidate),
|
||||
candidate->used);
|
||||
"\t cur_etx:%f\n"
|
||||
"\t packets_rx:%d\n"
|
||||
"\t packets_tx:%d\n"
|
||||
"\t used:%d\n", candidate->addr.uint8[ETX_IPV6_LAST_BYTE],
|
||||
candidate->cur_etx, candidate->packets_rx,
|
||||
etx_count_packet_tx(candidate),
|
||||
candidate->used);
|
||||
}
|
||||
}
|
||||
|
||||
void etx_init_beaconing(ipv6_addr_t * address) {
|
||||
void etx_init_beaconing(ipv6_addr_t *address)
|
||||
{
|
||||
mutex_init(&etx_mutex);
|
||||
own_address = address;
|
||||
//set code
|
||||
@ -127,29 +132,30 @@ void etx_init_beaconing(ipv6_addr_t * address) {
|
||||
etx_send_buf[0] = ETX_PKT_OPTVAL;
|
||||
|
||||
etx_beacon_pid = thread_create(etx_beacon_buf, ETX_BEACON_STACKSIZE,
|
||||
PRIORITY_MAIN - 1, CREATE_STACKTEST,
|
||||
etx_beacon, "etx_beacon");
|
||||
PRIORITY_MAIN - 1, CREATE_STACKTEST,
|
||||
etx_beacon, "etx_beacon");
|
||||
|
||||
etx_radio_pid = thread_create(etx_radio_buf, ETX_RADIO_STACKSIZE,
|
||||
PRIORITY_MAIN - 1, CREATE_STACKTEST,
|
||||
etx_radio, "etx_radio");
|
||||
PRIORITY_MAIN - 1, CREATE_STACKTEST,
|
||||
etx_radio, "etx_radio");
|
||||
|
||||
etx_clock_pid = thread_create(etx_clock_buf, ETX_CLOCK_STACKSIZE,
|
||||
PRIORITY_MAIN - 1, CREATE_STACKTEST,
|
||||
etx_clock, "etx_clock");
|
||||
PRIORITY_MAIN - 1, CREATE_STACKTEST,
|
||||
etx_clock, "etx_clock");
|
||||
//register at transceiver
|
||||
transceiver_register(TRANSCEIVER_CC1100, etx_radio_pid);
|
||||
puts("...[DONE]");
|
||||
}
|
||||
|
||||
void etx_beacon(void) {
|
||||
void etx_beacon(void)
|
||||
{
|
||||
/*
|
||||
* Sends a message every ETX_INTERVAL +/- a jitter-value (default is 10%) .
|
||||
* A correcting variable is needed to stay at a base interval of
|
||||
* ETX_INTERVAL between the wakeups. It takes the old jittervalue in account
|
||||
* and modifies the time to wait accordingly.
|
||||
*/
|
||||
etx_probe_t * packet = etx_get_send_buf();
|
||||
etx_probe_t *packet = etx_get_send_buf();
|
||||
uint8_t p_length = 0;
|
||||
|
||||
/*
|
||||
@ -165,47 +171,55 @@ void etx_beacon(void) {
|
||||
mutex_lock(&etx_mutex);
|
||||
//Build etx packet
|
||||
p_length = 0;
|
||||
|
||||
for (uint8_t i = 0; i < ETX_BEST_CANDIDATES; i++) {
|
||||
if (candidates[i].used != 0) {
|
||||
packet->data[i * ETX_TUPLE_SIZE] =
|
||||
candidates[i].addr.uint8[ETX_IPV6_LAST_BYTE];
|
||||
candidates[i].addr.uint8[ETX_IPV6_LAST_BYTE];
|
||||
packet->data[i * ETX_TUPLE_SIZE + ETX_PKT_REC_OFFSET] =
|
||||
etx_count_packet_tx(&candidates[i]);
|
||||
etx_count_packet_tx(&candidates[i]);
|
||||
p_length = p_length + ETX_PKT_HDR_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
packet->length = p_length;
|
||||
send_ieee802154_frame(&empty_addr, &etx_send_buf[0],
|
||||
ETX_DATA_MAXLEN+ETX_PKT_HDR_LEN, 1);
|
||||
ETX_DATA_MAXLEN + ETX_PKT_HDR_LEN, 1);
|
||||
DEBUG("sent beacon!\n");
|
||||
etx_set_packets_received();
|
||||
cur_round++;
|
||||
|
||||
if (cur_round == ETX_WINDOW) {
|
||||
if (reached_window != 1) {
|
||||
//first round is through
|
||||
reached_window = 1;
|
||||
}
|
||||
|
||||
cur_round = 0;
|
||||
}
|
||||
|
||||
mutex_unlock(&etx_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
etx_neighbor_t * etx_find_candidate(ipv6_addr_t * address) {
|
||||
etx_neighbor_t *etx_find_candidate(ipv6_addr_t *address)
|
||||
{
|
||||
/*
|
||||
* find the candidate with address address and returns it, or returns NULL
|
||||
* if no candidate having this address was found.
|
||||
*/
|
||||
for (uint8_t i = 0; i < ETX_MAX_CANDIDATE_NEIGHBORS; i++) {
|
||||
if (candidates[i].used
|
||||
&& (etx_equal_id(&candidates[i].addr, address))) {
|
||||
&& (etx_equal_id(&candidates[i].addr, address))) {
|
||||
return &candidates[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
void etx_clock(void) {
|
||||
void etx_clock(void)
|
||||
{
|
||||
/*
|
||||
* Manages the etx_beacon thread to wake up every full second +- jitter
|
||||
*/
|
||||
@ -217,7 +231,7 @@ void etx_clock(void) {
|
||||
* That is why they are multiplied by 1000 when used for hwtimer_wait.
|
||||
*/
|
||||
uint8_t jittercorrection = ETX_DEF_JIT_CORRECT;
|
||||
uint8_t jitter = (uint8_t) (rand() % ETX_JITTER_MOD);
|
||||
uint8_t jitter = (uint8_t)(rand() % ETX_JITTER_MOD);
|
||||
|
||||
while (true) {
|
||||
thread_wakeup(etx_beacon_pid);
|
||||
@ -227,32 +241,37 @@ void etx_clock(void) {
|
||||
* for now.
|
||||
*/
|
||||
vtimer_usleep(
|
||||
((ETX_INTERVAL - ETX_MAX_JITTER)*MS)+ jittercorrection*MS + jitter*MS - ETX_CLOCK_ADJUST);
|
||||
((ETX_INTERVAL - ETX_MAX_JITTER)*MS) + jittercorrection * MS + jitter * MS - ETX_CLOCK_ADJUST);
|
||||
|
||||
//hwtimer_wait(
|
||||
// HWTIMER_TICKS(((ETX_INTERVAL - ETX_MAX_JITTER)*MS) + jittercorrection*MS + jitter*MS - ETX_CLOCK_ADJUST));
|
||||
|
||||
jittercorrection = (ETX_MAX_JITTER) - jitter;
|
||||
jitter = (uint8_t) (rand() % ETX_JITTER_MOD);
|
||||
jitter = (uint8_t)(rand() % ETX_JITTER_MOD);
|
||||
}
|
||||
}
|
||||
|
||||
double etx_get_metric(ipv6_addr_t * address) {
|
||||
etx_neighbor_t * candidate = etx_find_candidate(address);
|
||||
if (candidate != NULL ) {
|
||||
double etx_get_metric(ipv6_addr_t *address)
|
||||
{
|
||||
etx_neighbor_t *candidate = etx_find_candidate(address);
|
||||
|
||||
if (candidate != NULL) {
|
||||
if (etx_count_packet_tx(candidate) > 0) {
|
||||
//this means the current etx_value is not outdated
|
||||
return candidate->cur_etx;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
//The last time I received a packet is too long ago to give a
|
||||
//good estimate of the etx value
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
etx_neighbor_t * etx_add_candidate(ipv6_addr_t * address) {
|
||||
etx_neighbor_t *etx_add_candidate(ipv6_addr_t *address)
|
||||
{
|
||||
DEBUG("add candidate\n");
|
||||
/*
|
||||
* Pre-Condition: etx_add_candidate should only be called when the
|
||||
@ -275,16 +294,17 @@ etx_neighbor_t * etx_add_candidate(ipv6_addr_t * address) {
|
||||
* Returns the pointer to the candidate if it was added, or a NULL-pointer
|
||||
* otherwise.
|
||||
*/
|
||||
etx_neighbor_t * candidate;
|
||||
etx_neighbor_t * end;
|
||||
etx_neighbor_t *candidate;
|
||||
etx_neighbor_t *end;
|
||||
|
||||
for (candidate = &candidates[0], end = candidates
|
||||
+ ETX_MAX_CANDIDATE_NEIGHBORS; candidate < end;
|
||||
candidate++) {
|
||||
+ ETX_MAX_CANDIDATE_NEIGHBORS; candidate < end;
|
||||
candidate++) {
|
||||
if (candidate->used) {
|
||||
//skip
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
//We still have a free place add the new candidate
|
||||
memset(candidate, 0, sizeof(*candidate));
|
||||
candidate->addr = *address;
|
||||
@ -294,27 +314,31 @@ etx_neighbor_t * etx_add_candidate(ipv6_addr_t * address) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
void etx_handle_beacon(ipv6_addr_t * candidate_address) {
|
||||
void etx_handle_beacon(ipv6_addr_t *candidate_address)
|
||||
{
|
||||
/*
|
||||
* Handle the ETX probe that has been received and update all infos.
|
||||
* If the candidate address is unknown, try to add it to my struct.
|
||||
*/
|
||||
|
||||
DEBUG(
|
||||
"ETX beacon package received with following values:\n"
|
||||
"\tPackage Option:%x\n"
|
||||
"\t Data Length:%u\n"
|
||||
"\tSource Address:%d\n\n", etx_rec_buf[ETX_PKT_OPT], etx_rec_buf[ETX_PKT_LEN],
|
||||
candidate_address->uint8[ETX_IPV6_LAST_BYTE]);
|
||||
"ETX beacon package received with following values:\n"
|
||||
"\tPackage Option:%x\n"
|
||||
"\t Data Length:%u\n"
|
||||
"\tSource Address:%d\n\n", etx_rec_buf[ETX_PKT_OPT], etx_rec_buf[ETX_PKT_LEN],
|
||||
candidate_address->uint8[ETX_IPV6_LAST_BYTE]);
|
||||
|
||||
etx_neighbor_t* candidate = etx_find_candidate(candidate_address);
|
||||
if (candidate == NULL ) {
|
||||
etx_neighbor_t *candidate = etx_find_candidate(candidate_address);
|
||||
|
||||
if (candidate == NULL) {
|
||||
//Candidate was not found in my list, I should add it
|
||||
candidate = etx_add_candidate(candidate_address);
|
||||
if (candidate == NULL ) {
|
||||
|
||||
if (candidate == NULL) {
|
||||
puts("[ERROR] Candidate could not get added");
|
||||
puts("Increase the constant ETX_MAX_CANDIDATE_NEIHGBORS");
|
||||
return;
|
||||
@ -327,18 +351,18 @@ void etx_handle_beacon(ipv6_addr_t * candidate_address) {
|
||||
|
||||
// If i find my address in this probe, update the packet_rx value for
|
||||
// this candidate.
|
||||
etx_probe_t * rec_pkt = etx_get_rec_buf();
|
||||
etx_probe_t *rec_pkt = etx_get_rec_buf();
|
||||
|
||||
for (uint8_t i = 0; i < rec_pkt->length / ETX_TUPLE_SIZE; i++) {
|
||||
DEBUG("\tIPv6 short Addr:%u\n"
|
||||
"\tPackets f. Addr:%u\n\n", rec_pkt->data[i * ETX_TUPLE_SIZE],
|
||||
rec_pkt->data[i * ETX_TUPLE_SIZE + ETX_PKT_REC_OFFSET]);
|
||||
"\tPackets f. Addr:%u\n\n", rec_pkt->data[i * ETX_TUPLE_SIZE],
|
||||
rec_pkt->data[i * ETX_TUPLE_SIZE + ETX_PKT_REC_OFFSET]);
|
||||
|
||||
if (rec_pkt->data[i * ETX_TUPLE_SIZE]
|
||||
== own_address->uint8[ETX_IPV6_LAST_BYTE]) {
|
||||
== own_address->uint8[ETX_IPV6_LAST_BYTE]) {
|
||||
|
||||
candidate->packets_rx = rec_pkt->data[i * ETX_TUPLE_SIZE
|
||||
+ ETX_PKT_REC_OFFSET];
|
||||
+ ETX_PKT_REC_OFFSET];
|
||||
}
|
||||
}
|
||||
|
||||
@ -346,7 +370,8 @@ void etx_handle_beacon(ipv6_addr_t * candidate_address) {
|
||||
etx_update(candidate);
|
||||
}
|
||||
|
||||
void etx_radio(void) {
|
||||
void etx_radio(void)
|
||||
{
|
||||
msg_t m;
|
||||
radio_packet_t *p;
|
||||
|
||||
@ -357,13 +382,14 @@ void etx_radio(void) {
|
||||
ipv6_addr_t ll_address;
|
||||
ipv6_addr_t candidate_addr;
|
||||
|
||||
ipv6_set_ll_prefix(&ll_address);
|
||||
ipv6_get_saddr(&candidate_addr, &ll_address);
|
||||
ipv6_addr_set_link_local_prefix(&ll_address);
|
||||
ipv6_iface_get_best_src_addr(&candidate_addr, &ll_address);
|
||||
|
||||
while (1) {
|
||||
msg_receive(&m);
|
||||
|
||||
if (m.type == PKT_PENDING) {
|
||||
p = (radio_packet_t*) m.content.ptr;
|
||||
p = (radio_packet_t *) m.content.ptr;
|
||||
|
||||
read_802154_frame(p->data, &frame, p->length);
|
||||
|
||||
@ -392,7 +418,8 @@ void etx_radio(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void etx_update(etx_neighbor_t * candidate) {
|
||||
void etx_update(etx_neighbor_t *candidate)
|
||||
{
|
||||
DEBUG("update!\n");
|
||||
/*
|
||||
* Update the current ETX value of a candidate
|
||||
@ -400,7 +427,7 @@ void etx_update(etx_neighbor_t * candidate) {
|
||||
double d_f;
|
||||
double d_r;
|
||||
|
||||
if (reached_window != 1 || candidate == NULL ) {
|
||||
if (reached_window != 1 || candidate == NULL) {
|
||||
//We will wait at least ETX_WINDOW beacons until we decide to
|
||||
//calculate an ETX value, so that we have a good estimate
|
||||
return;
|
||||
@ -419,24 +446,26 @@ void etx_update(etx_neighbor_t * candidate) {
|
||||
/*
|
||||
* Calculate the current ETX value for my link to this candidate.
|
||||
*/
|
||||
if (d_f * d_r != 0) {
|
||||
if (d_f *d_r != 0) {
|
||||
candidate->cur_etx = 1 / (d_f * d_r);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
candidate->cur_etx = 0;
|
||||
}
|
||||
|
||||
DEBUG(
|
||||
"Estimated ETX Metric is %f for candidate w/ addr %d\n"
|
||||
"Estimated PDR_forward is %f\n"
|
||||
"Estimated PDR_backwrd is %f\n"
|
||||
"\n"
|
||||
"Received Packets: %d\n"
|
||||
"Sent Packets : %d\n\n",
|
||||
candidate->cur_etx, candidate->addr.uint8[ETX_IPV6_LAST_BYTE],
|
||||
d_f, d_r, candidate->packets_rx, etx_count_packet_tx(candidate));
|
||||
"Estimated ETX Metric is %f for candidate w/ addr %d\n"
|
||||
"Estimated PDR_forward is %f\n"
|
||||
"Estimated PDR_backwrd is %f\n"
|
||||
"\n"
|
||||
"Received Packets: %d\n"
|
||||
"Sent Packets : %d\n\n",
|
||||
candidate->cur_etx, candidate->addr.uint8[ETX_IPV6_LAST_BYTE],
|
||||
d_f, d_r, candidate->packets_rx, etx_count_packet_tx(candidate));
|
||||
}
|
||||
|
||||
static uint8_t etx_count_packet_tx(etx_neighbor_t * candidate) {
|
||||
static uint8_t etx_count_packet_tx(etx_neighbor_t *candidate)
|
||||
{
|
||||
/*
|
||||
* Counts the number of packets that were received for this candidate
|
||||
* in the last ETX_WINDOW intervals.
|
||||
@ -444,38 +473,46 @@ static uint8_t etx_count_packet_tx(etx_neighbor_t * candidate) {
|
||||
DEBUG("counting packets");
|
||||
uint8_t pkt_count = 0;
|
||||
DEBUG("[");
|
||||
|
||||
for (uint8_t i = 0; i < ETX_WINDOW; i++) {
|
||||
if (i != cur_round) {
|
||||
pkt_count = pkt_count + candidate->packets_tx[i];
|
||||
DEBUG("%d",candidate->packets_tx[i]);
|
||||
DEBUG("%d", candidate->packets_tx[i]);
|
||||
|
||||
if (i < ETX_WINDOW - 1) {
|
||||
DEBUG(",");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
//Check if I received something for the current round
|
||||
if (candidate->tx_cur_round == 0) {
|
||||
//Didn't receive a packet, zero the field and don't add
|
||||
candidate->packets_tx[i] = 0;
|
||||
DEBUG("%d!",candidate->packets_tx[i]);
|
||||
DEBUG("%d!", candidate->packets_tx[i]);
|
||||
|
||||
if (i < ETX_WINDOW - 1) {
|
||||
DEBUG(",");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
//Add 1 and set field
|
||||
pkt_count = pkt_count + 1;
|
||||
candidate->packets_tx[i] = 1;
|
||||
DEBUG("%d!",candidate->packets_tx[i]);
|
||||
DEBUG("%d!", candidate->packets_tx[i]);
|
||||
|
||||
if (i < ETX_WINDOW - 1) {
|
||||
DEBUG(",");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG("]\n");
|
||||
return pkt_count;
|
||||
}
|
||||
|
||||
static void etx_set_packets_received(void) {
|
||||
static void etx_set_packets_received(void)
|
||||
{
|
||||
/*
|
||||
* Set for all candidates if they received a packet this round or not
|
||||
*/
|
||||
@ -489,12 +526,14 @@ static void etx_set_packets_received(void) {
|
||||
}
|
||||
}
|
||||
|
||||
bool etx_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2){
|
||||
for(uint8_t i=0;i<4;i++){
|
||||
if(id1->uint32[i] != id2->uint32[i]){
|
||||
bool etx_equal_id(ipv6_addr_t *id1, ipv6_addr_t *id2)
|
||||
{
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
if (id1->uint32[i] != id2->uint32[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@ -9,20 +9,20 @@
|
||||
#ifndef ETX_BEACONING_H_
|
||||
#define ETX_BEACONING_H_
|
||||
|
||||
#include "sys/net/sixlowpan/sixlowip.h"
|
||||
#include "ipv6.h"
|
||||
|
||||
//For debugging purposes
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include <debug.h>
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
#define ETX_BEACON_STACKSIZE (4500)
|
||||
#define ETX_RADIO_STACKSIZE (4500)
|
||||
#define ETX_CLOCK_STACKSIZE (500)
|
||||
#define ETX_BEACON_STACKSIZE (4500)
|
||||
#define ETX_RADIO_STACKSIZE (4500)
|
||||
#define ETX_CLOCK_STACKSIZE (500)
|
||||
#else
|
||||
#define ETX_BEACON_STACKSIZE (2500) //TODO optimize, maybe 2000 is enough
|
||||
#define ETX_RADIO_STACKSIZE (2500) //TODO optimize, maybe 2000 is enough
|
||||
#define ETX_CLOCK_STACKSIZE (500) //TODO optimize, maybe 250 is enough
|
||||
#define ETX_BEACON_STACKSIZE (2500) //TODO optimize, maybe 2000 is enough
|
||||
#define ETX_RADIO_STACKSIZE (2500) //TODO optimize, maybe 2000 is enough
|
||||
#define ETX_CLOCK_STACKSIZE (500) //TODO optimize, maybe 250 is enough
|
||||
#endif
|
||||
|
||||
//[option|length|ipaddr.|packetcount] with up to 15 ipaddr|packetcount pairs
|
||||
@ -36,9 +36,9 @@
|
||||
* In my tests, the maximum count of neighbors was around 30-something
|
||||
*/
|
||||
#if ENABLE_DEBUG
|
||||
#define ETX_MAX_CANDIDATE_NEIGHBORS (15) //Stacksizes are huge in debug mode, so memory is rare
|
||||
#define ETX_MAX_CANDIDATE_NEIGHBORS (15) //Stacksizes are huge in debug mode, so memory is rare
|
||||
#else
|
||||
#define ETX_MAX_CANDIDATE_NEIGHBORS (40)
|
||||
#define ETX_MAX_CANDIDATE_NEIGHBORS (40)
|
||||
#endif
|
||||
//ETX Interval parameters
|
||||
#define MS (1000)
|
||||
@ -86,7 +86,7 @@
|
||||
* information.
|
||||
* The information processed shall not exceed the value set in Option Length.
|
||||
*/
|
||||
typedef struct __attribute__((packed)) etx_probe_t{
|
||||
typedef struct __attribute__((packed)) etx_probe_t {
|
||||
uint8_t code;
|
||||
uint8_t length;
|
||||
uint8_t data[30];
|
||||
@ -102,11 +102,11 @@ typedef struct etx_neighbor_t {
|
||||
} etx_neighbor_t;
|
||||
|
||||
//prototypes
|
||||
void etx_init_beaconing(ipv6_addr_t * address);
|
||||
void etx_init_beaconing(ipv6_addr_t *address);
|
||||
void etx_beacon(void);
|
||||
void etx_clock(void);
|
||||
double etx_get_metric(ipv6_addr_t * address);
|
||||
void etx_update(etx_neighbor_t * neighbor);
|
||||
double etx_get_metric(ipv6_addr_t *address);
|
||||
void etx_update(etx_neighbor_t *neighbor);
|
||||
void etx_radio(void);
|
||||
|
||||
#define ETX_PKT_OPT (0) //Position of Option-Type-Byte
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Objective function 0 for RPL implementation
|
||||
* Objective function 0 for RPL implementation
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
@ -7,10 +7,10 @@
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup rpl
|
||||
* @ingroup rpl
|
||||
* @{
|
||||
* @file of0.c
|
||||
* @brief RPL objective function 0
|
||||
* @file of0.c
|
||||
* @brief RPL objective function 0
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
@ -9,33 +9,37 @@ static uint16_t calc_rank(rpl_parent_t *, uint16_t);
|
||||
static rpl_parent_t *which_parent(rpl_parent_t *, rpl_parent_t *);
|
||||
static rpl_dodag_t *which_dodag(rpl_dodag_t *, rpl_dodag_t *);
|
||||
static void reset(rpl_dodag_t *);
|
||||
static uint16_t calc_path_cost(rpl_parent_t * parent);
|
||||
static uint16_t calc_path_cost(rpl_parent_t *parent);
|
||||
|
||||
uint16_t cur_min_path_cost = MAX_PATH_COST;
|
||||
rpl_parent_t * cur_preferred_parent = NULL;
|
||||
rpl_parent_t *cur_preferred_parent = NULL;
|
||||
|
||||
rpl_of_t rpl_of_mrhof = {
|
||||
0x1,
|
||||
calc_rank,
|
||||
which_parent,
|
||||
which_dodag,
|
||||
reset,
|
||||
NULL
|
||||
};
|
||||
0x1,
|
||||
calc_rank,
|
||||
which_parent,
|
||||
which_dodag,
|
||||
reset,
|
||||
NULL
|
||||
};
|
||||
|
||||
rpl_of_t * rpl_get_of_mrhof(void) {
|
||||
rpl_of_t *rpl_get_of_mrhof(void)
|
||||
{
|
||||
return &rpl_of_mrhof;
|
||||
}
|
||||
|
||||
void reset(rpl_dodag_t *dodag) {
|
||||
void reset(rpl_dodag_t *dodag)
|
||||
{
|
||||
}
|
||||
|
||||
static uint16_t calc_path_cost(rpl_parent_t * parent) {
|
||||
static uint16_t calc_path_cost(rpl_parent_t *parent)
|
||||
{
|
||||
puts("calc_pathcost");
|
||||
|
||||
/*
|
||||
* Calculates the path cost through the parent, for now, only for ETX
|
||||
*/
|
||||
if (parent == NULL ) {
|
||||
if (parent == NULL) {
|
||||
// Shouldn't ever happen since this function is supposed to be always
|
||||
// run with a parent. If it does happen, we can assume a root called it.
|
||||
puts("[WARNING] calc_path_cost called without parent!");
|
||||
@ -44,6 +48,7 @@ static uint16_t calc_path_cost(rpl_parent_t * parent) {
|
||||
|
||||
double etx_value = etx_get_metric(&(parent->addr));
|
||||
printf("Metric for parent returned: %f", etx_value);
|
||||
|
||||
if (etx_value != 0) {
|
||||
/*
|
||||
* (ETX_for_link_to_neighbor * 128) + Rank_of_that_neighbor
|
||||
@ -60,14 +65,16 @@ static uint16_t calc_path_cost(rpl_parent_t * parent) {
|
||||
}
|
||||
|
||||
if (etx_value * ETX_RANK_MULTIPLIER + parent->rank
|
||||
< parent->rank) {
|
||||
< parent->rank) {
|
||||
//Overflow
|
||||
return MAX_PATH_COST;
|
||||
}
|
||||
|
||||
//TODO runden
|
||||
return etx_value * ETX_RANK_MULTIPLIER
|
||||
+ parent->rank;
|
||||
} else {
|
||||
+ parent->rank;
|
||||
}
|
||||
else {
|
||||
// IMPLEMENT HANDLING OF OTHER METRICS HERE
|
||||
// if it is 0, it hasn't been computed, thus we cannot compute a path
|
||||
// cost
|
||||
@ -75,8 +82,10 @@ static uint16_t calc_path_cost(rpl_parent_t * parent) {
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t calc_rank(rpl_parent_t * parent, uint16_t base_rank) {
|
||||
static uint16_t calc_rank(rpl_parent_t *parent, uint16_t base_rank)
|
||||
{
|
||||
puts("calc_rank");
|
||||
|
||||
/*
|
||||
* Return the rank for this node.
|
||||
*
|
||||
@ -84,7 +93,7 @@ static uint16_t calc_rank(rpl_parent_t * parent, uint16_t base_rank) {
|
||||
* putation will always be assumed to be done for the ETX metric.
|
||||
* Baserank is pretty much only used to find out if a node is a root or not.
|
||||
*/
|
||||
if (parent == NULL ) {
|
||||
if (parent == NULL) {
|
||||
if (base_rank == 0) {
|
||||
//No parent, no rank, a root node would have a rank != 0
|
||||
return INFINITE_RANK;
|
||||
@ -97,7 +106,8 @@ static uint16_t calc_rank(rpl_parent_t * parent, uint16_t base_rank) {
|
||||
* (see rpl.c, function global_repair), we can assume this node is root.
|
||||
*/
|
||||
return DEFAULT_MIN_HOP_RANK_INCREASE;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* We have a parent and are a non-root node, calculate the path cost for
|
||||
* the parent and choose the maximum of that value and the advertised
|
||||
@ -107,19 +117,22 @@ static uint16_t calc_rank(rpl_parent_t * parent, uint16_t base_rank) {
|
||||
|
||||
if (calculated_pcost < MAX_PATH_COST) {
|
||||
if ((parent->rank + parent->dodag->minhoprankincrease)
|
||||
> calculated_pcost) {
|
||||
> calculated_pcost) {
|
||||
return parent->rank + parent->dodag->minhoprankincrease;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return calculated_pcost;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
//Path costs are greater than allowed
|
||||
return INFINITE_RANK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static rpl_parent_t * which_parent(rpl_parent_t * p1, rpl_parent_t * p2) {
|
||||
static rpl_parent_t *which_parent(rpl_parent_t *p1, rpl_parent_t *p2)
|
||||
{
|
||||
puts("which_parent");
|
||||
/*
|
||||
* Return the parent with the lowest path cost.
|
||||
@ -130,12 +143,12 @@ static rpl_parent_t * which_parent(rpl_parent_t * p1, rpl_parent_t * p2) {
|
||||
uint16_t path_p1 = calc_path_cost(p1);
|
||||
uint16_t path_p2 = calc_path_cost(p2);
|
||||
|
||||
if(cur_preferred_parent != NULL){
|
||||
if (cur_preferred_parent != NULL) {
|
||||
//test if the parent from which we got this path is still active
|
||||
if(cur_preferred_parent->used != 0){
|
||||
if (cur_preferred_parent->used != 0) {
|
||||
// Test, if the current best path is better than both parents given
|
||||
if(cur_min_path_cost < path_p1 + PARENT_SWITCH_THRESHOLD
|
||||
&& cur_min_path_cost < path_p2 + PARENT_SWITCH_THRESHOLD){
|
||||
if (cur_min_path_cost < path_p1 + PARENT_SWITCH_THRESHOLD
|
||||
&& cur_min_path_cost < path_p2 + PARENT_SWITCH_THRESHOLD) {
|
||||
return cur_preferred_parent;
|
||||
}
|
||||
}
|
||||
@ -149,12 +162,14 @@ static rpl_parent_t * which_parent(rpl_parent_t * p1, rpl_parent_t * p2) {
|
||||
cur_preferred_parent = p1;
|
||||
return p1;
|
||||
}
|
||||
|
||||
cur_min_path_cost = path_p2;
|
||||
cur_preferred_parent = p2;
|
||||
return p2;
|
||||
}
|
||||
|
||||
//Not used yet, as the implementation only makes use of one dodag for now.
|
||||
static rpl_dodag_t * which_dodag(rpl_dodag_t *d1, rpl_dodag_t *d2) {
|
||||
static rpl_dodag_t *which_dodag(rpl_dodag_t *d1, rpl_dodag_t *d2)
|
||||
{
|
||||
return d1;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* RPL implementation
|
||||
* RPL implementation
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
@ -7,10 +7,10 @@
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup rpl
|
||||
* @ingroup rpl
|
||||
* @{
|
||||
* @file rpl.c
|
||||
* @brief basic RPL functions
|
||||
* @file rpl.c
|
||||
* @brief basic RPL functions
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
@ -19,6 +19,7 @@
|
||||
#include <vtimer.h>
|
||||
#include <thread.h>
|
||||
#include <mutex.h>
|
||||
|
||||
#include "msg.h"
|
||||
#include "rpl.h"
|
||||
#include "etx_beaconing.h"
|
||||
@ -26,11 +27,8 @@
|
||||
#include "of_mrhof.h"
|
||||
#include "trickle.h"
|
||||
|
||||
#include "sys/net/sixlowpan/sixlowmac.h"
|
||||
#include "sys/net/sixlowpan/sixlowip.h"
|
||||
#include "sys/net/sixlowpan/sixlowpan.h"
|
||||
#include "sys/net/sixlowpan/sixlownd.h"
|
||||
#include "sys/net/sixlowpan/sixlowerror.h"
|
||||
#include "sixlowpan.h"
|
||||
#include "ipv6.h"
|
||||
|
||||
char rpl_process_buf[RPL_PROCESS_STACKSIZE];
|
||||
/* global variables */
|
||||
@ -74,7 +72,7 @@ static rpl_opt_transit_t *rpl_opt_transit_buf;
|
||||
/* SEND BUFFERS */
|
||||
static ipv6_hdr_t *get_rpl_send_ipv6_buf(void)
|
||||
{
|
||||
return ((ipv6_hdr_t *)&(rpl_send_buffer[0]));
|
||||
return ((ipv6_hdr_t *) &(rpl_send_buffer[0]));
|
||||
}
|
||||
|
||||
static uint8_t *get_rpl_send_payload_buf(uint8_t ext_len)
|
||||
@ -82,95 +80,86 @@ static uint8_t *get_rpl_send_payload_buf(uint8_t ext_len)
|
||||
return &(rpl_send_buffer[IPV6_HDR_LEN + ext_len]);
|
||||
}
|
||||
|
||||
static struct icmpv6_hdr_t *get_rpl_send_icmpv6_buf(uint8_t ext_len)
|
||||
{
|
||||
return ((struct icmpv6_hdr_t *)&(rpl_send_buffer[IPV6_HDR_LEN + ext_len]));
|
||||
static struct icmpv6_hdr_t *get_rpl_send_icmpv6_buf(uint8_t ext_len) {
|
||||
return ((struct icmpv6_hdr_t *) &(rpl_send_buffer[IPV6_HDR_LEN + ext_len]));
|
||||
}
|
||||
|
||||
static struct rpl_dio_t *get_rpl_send_dio_buf(void)
|
||||
{
|
||||
return ((struct rpl_dio_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN]));
|
||||
static struct rpl_dio_t *get_rpl_send_dio_buf(void) {
|
||||
return ((struct rpl_dio_t *) &(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN]));
|
||||
}
|
||||
|
||||
static struct rpl_dao_t *get_rpl_send_dao_buf(void)
|
||||
{
|
||||
return ((struct rpl_dao_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN]));
|
||||
static struct rpl_dao_t *get_rpl_send_dao_buf(void) {
|
||||
return ((struct rpl_dao_t *) &(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN]));
|
||||
}
|
||||
|
||||
static struct rpl_dao_ack_t *get_rpl_send_dao_ack_buf(void)
|
||||
{
|
||||
return ((struct rpl_dao_ack_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN]));
|
||||
static struct rpl_dao_ack_t *get_rpl_send_dao_ack_buf(void) {
|
||||
return ((struct rpl_dao_ack_t *) &(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN]));
|
||||
}
|
||||
|
||||
static struct rpl_dis_t *get_rpl_send_dis_buf(void)
|
||||
{
|
||||
return ((struct rpl_dis_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN]));
|
||||
static struct rpl_dis_t *get_rpl_send_dis_buf(void) {
|
||||
return ((struct rpl_dis_t *) &(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN]));
|
||||
}
|
||||
|
||||
static rpl_opt_dodag_conf_t *get_rpl_send_opt_dodag_conf_buf(uint8_t rpl_msg_len)
|
||||
{
|
||||
return ((rpl_opt_dodag_conf_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
return ((rpl_opt_dodag_conf_t *) &(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
}
|
||||
|
||||
static rpl_opt_target_t *get_rpl_send_opt_target_buf(uint8_t rpl_msg_len)
|
||||
{
|
||||
return ((rpl_opt_target_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
return ((rpl_opt_target_t *) &(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
}
|
||||
|
||||
static rpl_opt_transit_t *get_rpl_send_opt_transit_buf(uint8_t rpl_msg_len)
|
||||
{
|
||||
return ((rpl_opt_transit_t *)&(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
return ((rpl_opt_transit_t *) &(rpl_send_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
}
|
||||
|
||||
/* RECEIVE BUFFERS */
|
||||
static ipv6_hdr_t *get_rpl_ipv6_buf(void)
|
||||
{
|
||||
return ((ipv6_hdr_t *)&(rpl_buffer[0]));
|
||||
return ((ipv6_hdr_t *) &(rpl_buffer[0]));
|
||||
}
|
||||
|
||||
static struct rpl_dio_t *get_rpl_dio_buf(void)
|
||||
{
|
||||
return ((struct rpl_dio_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN]));
|
||||
static struct rpl_dio_t *get_rpl_dio_buf(void) {
|
||||
return ((struct rpl_dio_t *) &(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN]));
|
||||
}
|
||||
|
||||
static struct rpl_dao_t *get_rpl_dao_buf(void)
|
||||
{
|
||||
return ((struct rpl_dao_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN]));
|
||||
static struct rpl_dao_t *get_rpl_dao_buf(void) {
|
||||
return ((struct rpl_dao_t *) &(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN]));
|
||||
}
|
||||
|
||||
static struct rpl_dao_ack_t *get_rpl_dao_ack_buf(void)
|
||||
{
|
||||
return ((struct rpl_dao_ack_t *)&(buffer[LLHDR_ICMPV6HDR_LEN]));
|
||||
static struct rpl_dao_ack_t *get_rpl_dao_ack_buf(void) {
|
||||
return ((struct rpl_dao_ack_t *) &(buffer[LLHDR_ICMPV6HDR_LEN]));
|
||||
}
|
||||
|
||||
static struct rpl_dis_t *get_rpl_dis_buf(void)
|
||||
{
|
||||
return ((struct rpl_dis_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN]));
|
||||
static struct rpl_dis_t *get_rpl_dis_buf(void) {
|
||||
return ((struct rpl_dis_t *) & (rpl_buffer[IPV6HDR_ICMPV6HDR_LEN]));
|
||||
}
|
||||
|
||||
static rpl_opt_t *get_rpl_opt_buf(uint8_t rpl_msg_len)
|
||||
{
|
||||
return ((rpl_opt_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
return ((rpl_opt_t *) &(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
}
|
||||
|
||||
static rpl_opt_dodag_conf_t *get_rpl_opt_dodag_conf_buf(uint8_t rpl_msg_len)
|
||||
{
|
||||
return ((rpl_opt_dodag_conf_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
return ((rpl_opt_dodag_conf_t *) &(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
}
|
||||
|
||||
static rpl_opt_solicited_t *get_rpl_opt_solicited_buf(uint8_t rpl_msg_len)
|
||||
{
|
||||
return ((rpl_opt_solicited_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
return ((rpl_opt_solicited_t *) &(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
}
|
||||
|
||||
static rpl_opt_target_t *get_rpl_opt_target_buf(uint8_t rpl_msg_len)
|
||||
{
|
||||
return ((rpl_opt_target_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
return ((rpl_opt_target_t *) &(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
}
|
||||
|
||||
static rpl_opt_transit_t *get_rpl_opt_transit_buf(uint8_t rpl_msg_len)
|
||||
{
|
||||
return ((rpl_opt_transit_t *)&(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
return ((rpl_opt_transit_t *) &(rpl_buffer[IPV6HDR_ICMPV6HDR_LEN + rpl_msg_len]));
|
||||
}
|
||||
|
||||
/* find implemented OF via objective code point */
|
||||
@ -205,15 +194,15 @@ uint8_t rpl_init(transceiver_type_t trans, uint16_t rpl_address)
|
||||
objective_functions[0] = rpl_get_of0();
|
||||
/* objective_functions[1] = rpl_get_of_ETX() */
|
||||
|
||||
sixlowpan_init(trans, rpl_address, 0);
|
||||
sixlowpan_lowpan_init(trans, rpl_address, 0);
|
||||
/* need link local prefix to query _our_ corresponding address */
|
||||
ipv6_addr_t ll_address;
|
||||
ipv6_set_ll_prefix(&ll_address);
|
||||
ipv6_get_saddr(&my_address, &ll_address);
|
||||
set_rpl_process_pid(rpl_process_pid);
|
||||
ipv6_addr_set_link_local_prefix(&ll_address);
|
||||
ipv6_iface_get_best_src_addr(&my_address, &ll_address);
|
||||
ipv6_register_rpl_handler(rpl_process_pid);
|
||||
|
||||
/* initialize ETX-calculation if needed */
|
||||
if(RPL_DEFAULT_OCP == 1){
|
||||
if (RPL_DEFAULT_OCP == 1) {
|
||||
DEBUG("INIT ETX BEACONING\n");
|
||||
etx_init_beaconing(&my_address);
|
||||
}
|
||||
@ -239,7 +228,7 @@ void rpl_init_root(void)
|
||||
dodag = rpl_new_dodag(RPL_DEFAULT_INSTANCE, &my_address);
|
||||
|
||||
if (dodag != NULL) {
|
||||
dodag->of = (struct rpl_of_t*) rpl_get_of_for_ocp(RPL_DEFAULT_OCP);
|
||||
dodag->of = (struct rpl_of_t *) rpl_get_of_for_ocp(RPL_DEFAULT_OCP);
|
||||
dodag->instance = inst;
|
||||
dodag->mop = RPL_DEFAULT_MOP;
|
||||
dodag->dtsn = 1;
|
||||
@ -284,9 +273,9 @@ void send_DIO(ipv6_addr_t *destination)
|
||||
return;
|
||||
}
|
||||
|
||||
icmp_send_buf->type = ICMP_RPL_CONTROL;
|
||||
icmp_send_buf->type = ICMPV6_TYPE_RPL_CONTROL;
|
||||
icmp_send_buf->code = ICMP_CODE_DIO;
|
||||
icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6);
|
||||
icmp_send_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6);
|
||||
|
||||
rpl_send_dio_buf = get_rpl_send_dio_buf();
|
||||
memset(rpl_send_dio_buf, 0, sizeof(*rpl_send_dio_buf));
|
||||
@ -320,7 +309,7 @@ void send_DIO(ipv6_addr_t *destination)
|
||||
|
||||
|
||||
uint16_t plen = ICMPV6_HDR_LEN + DIO_BASE_LEN + opt_hdr_len;
|
||||
rpl_send(destination, (uint8_t *)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL);
|
||||
rpl_send(destination, (uint8_t *)icmp_send_buf, plen, IPV6_PROTO_NUM_ICMPV6, NULL);
|
||||
mutex_unlock(&rpl_send_mutex);
|
||||
}
|
||||
|
||||
@ -329,14 +318,14 @@ void send_DIS(ipv6_addr_t *destination)
|
||||
mutex_lock(&rpl_send_mutex);
|
||||
icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len);
|
||||
|
||||
icmp_send_buf->type = ICMP_RPL_CONTROL;
|
||||
icmp_send_buf->type = ICMPV6_TYPE_RPL_CONTROL;
|
||||
icmp_send_buf->code = ICMP_CODE_DIS;
|
||||
icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6);
|
||||
icmp_send_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6);
|
||||
|
||||
rpl_send_dis_buf = get_rpl_send_dis_buf();
|
||||
|
||||
uint16_t plen = ICMPV6_HDR_LEN + DIS_BASE_LEN;
|
||||
rpl_send(destination, (uint8_t *)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL);
|
||||
rpl_send(destination, (uint8_t *)icmp_send_buf, plen, IPV6_PROTO_NUM_ICMPV6, NULL);
|
||||
mutex_unlock(&rpl_send_mutex);
|
||||
}
|
||||
|
||||
@ -361,9 +350,9 @@ void send_DAO(ipv6_addr_t *destination, uint8_t lifetime, bool default_lifetime,
|
||||
|
||||
icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len);
|
||||
|
||||
icmp_send_buf->type = ICMP_RPL_CONTROL;
|
||||
icmp_send_buf->type = ICMPV6_TYPE_RPL_CONTROL;
|
||||
icmp_send_buf->code = ICMP_CODE_DAO;
|
||||
icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6);
|
||||
icmp_send_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6);
|
||||
|
||||
if (my_dodag == NULL) {
|
||||
mutex_unlock(&rpl_send_mutex);
|
||||
@ -427,7 +416,7 @@ void send_DAO(ipv6_addr_t *destination, uint8_t lifetime, bool default_lifetime,
|
||||
opt_len += RPL_OPT_TRANSIT_LEN + 2;
|
||||
|
||||
uint16_t plen = ICMPV6_HDR_LEN + DAO_BASE_LEN + opt_len;
|
||||
rpl_send(destination, (uint8_t *)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL);
|
||||
rpl_send(destination, (uint8_t *)icmp_send_buf, plen, IPV6_PROTO_NUM_ICMPV6, NULL);
|
||||
mutex_unlock(&rpl_send_mutex);
|
||||
|
||||
if (continue_index > 1) {
|
||||
@ -437,7 +426,8 @@ void send_DAO(ipv6_addr_t *destination, uint8_t lifetime, bool default_lifetime,
|
||||
|
||||
void send_DAO_ACK(ipv6_addr_t *destination)
|
||||
{
|
||||
ipv6_print_addr(destination);
|
||||
char addr_str[IPV6_MAX_ADDR_STR_LEN];
|
||||
printf("%s\n", ipv6_addr_to_str(addr_str, destination));
|
||||
rpl_dodag_t *my_dodag;
|
||||
my_dodag = rpl_get_my_dodag();
|
||||
|
||||
@ -448,9 +438,9 @@ void send_DAO_ACK(ipv6_addr_t *destination)
|
||||
mutex_lock(&rpl_send_mutex);
|
||||
icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len);
|
||||
|
||||
icmp_send_buf->type = ICMP_RPL_CONTROL;
|
||||
icmp_send_buf->type = ICMPV6_TYPE_RPL_CONTROL;
|
||||
icmp_send_buf->code = ICMP_CODE_DAO_ACK;
|
||||
icmp_send_buf->checksum = ~icmpv6_csum(PROTO_NUM_ICMPV6);
|
||||
icmp_send_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6);
|
||||
|
||||
rpl_send_dao_ack_buf = get_rpl_send_dao_ack_buf();
|
||||
rpl_send_dao_ack_buf->rpl_instanceid = my_dodag->instance->id;
|
||||
@ -459,7 +449,7 @@ void send_DAO_ACK(ipv6_addr_t *destination)
|
||||
rpl_send_dao_ack_buf->status = 0;
|
||||
|
||||
uint16_t plen = ICMPV6_HDR_LEN + DIS_BASE_LEN;
|
||||
rpl_send(destination, (uint8_t *)icmp_send_buf, plen, PROTO_NUM_ICMPV6, NULL);
|
||||
rpl_send(destination, (uint8_t *)icmp_send_buf, plen, IPV6_PROTO_NUM_ICMPV6, NULL);
|
||||
mutex_unlock(&rpl_send_mutex);
|
||||
}
|
||||
|
||||
@ -474,10 +464,10 @@ void rpl_process(void)
|
||||
uint8_t *code;
|
||||
code = ((uint8_t *)m_recv.content.ptr);
|
||||
/* differentiate packet types */
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
ipv6_buf = ipv6_get_buf();
|
||||
memcpy(&rpl_buffer, ipv6_buf, ipv6_buf->length + IPV6_HDR_LEN);
|
||||
|
||||
switch(*code) {
|
||||
switch (*code) {
|
||||
case (ICMP_CODE_DIS): {
|
||||
recv_rpl_dis();
|
||||
mutex_unlock(&rpl_recv_mutex);
|
||||
@ -533,11 +523,11 @@ void recv_rpl_dio(void)
|
||||
}
|
||||
}
|
||||
else if (my_inst->id != dio_inst->id) {
|
||||
/* TODO: Add support support for several instances. */
|
||||
/* TODO: Add support support for several instances. */
|
||||
|
||||
/* At the moment, nodes can only join one instance, this is
|
||||
* the instance they join first.
|
||||
* Instances cannot be switched later on. */
|
||||
/* At the moment, nodes can only join one instance, this is
|
||||
* the instance they join first.
|
||||
* Instances cannot be switched later on. */
|
||||
|
||||
DEBUG("Ignoring instance - we are %d and got %d\n", my_inst->id, dio_inst->id);
|
||||
return;
|
||||
@ -556,14 +546,14 @@ void recv_rpl_dio(void)
|
||||
|
||||
uint8_t has_dodag_conf_opt = 0;
|
||||
|
||||
/* Parse until all options are consumed.
|
||||
* ipv6_buf->length contains the packet length minus ipv6 and
|
||||
* icmpv6 header, so only ICMPV6_HDR_LEN remains to be
|
||||
* subtracted. */
|
||||
/* Parse until all options are consumed.
|
||||
* ipv6_buf->length contains the packet length minus ipv6 and
|
||||
* icmpv6 header, so only ICMPV6_HDR_LEN remains to be
|
||||
* subtracted. */
|
||||
while (len < (ipv6_buf->length - ICMPV6_HDR_LEN)) {
|
||||
rpl_opt_buf = get_rpl_opt_buf(len);
|
||||
|
||||
switch(rpl_opt_buf->type) {
|
||||
switch (rpl_opt_buf->type) {
|
||||
|
||||
case (RPL_OPT_PAD1): {
|
||||
len += 1;
|
||||
@ -601,7 +591,7 @@ void recv_rpl_dio(void)
|
||||
dio_dodag.minhoprankincrease = rpl_opt_dodag_conf_buf->MinHopRankIncrease;
|
||||
dio_dodag.default_lifetime = rpl_opt_dodag_conf_buf->default_lifetime;
|
||||
dio_dodag.lifetime_unit = rpl_opt_dodag_conf_buf->lifetime_unit;
|
||||
dio_dodag.of = (struct rpl_of_t*) rpl_get_of_for_ocp(rpl_opt_dodag_conf_buf->ocp);
|
||||
dio_dodag.of = (struct rpl_of_t *) rpl_get_of_for_ocp(rpl_opt_dodag_conf_buf->ocp);
|
||||
len += RPL_OPT_DODAG_CONF_LEN + 2;
|
||||
break;
|
||||
}
|
||||
@ -648,8 +638,9 @@ void recv_rpl_dio(void)
|
||||
}
|
||||
|
||||
if (rpl_dio_buf->rank != INFINITE_RANK) {
|
||||
char addr_str[IPV6_MAX_ADDR_STR_LEN];
|
||||
DEBUG("Will join DODAG\n");
|
||||
ipv6_print_addr(&dio_dodag.dodag_id);
|
||||
printf("%s", ipv6_addr_to_str(addr_str, &dio_dodag.dodag_id));
|
||||
rpl_join_dodag(&dio_dodag, &ipv6_buf->srcaddr, rpl_dio_buf->rank);
|
||||
}
|
||||
else {
|
||||
@ -685,7 +676,7 @@ void recv_rpl_dio(void)
|
||||
reset_trickletimer();
|
||||
}
|
||||
|
||||
/* We are root, all done! */
|
||||
/* We are root, all done! */
|
||||
if (my_dodag->my_rank == ROOT_RANK) {
|
||||
if (rpl_dio_buf->rank != INFINITE_RANK) {
|
||||
trickle_increment_counter();
|
||||
@ -739,7 +730,7 @@ void recv_rpl_dis(void)
|
||||
while (len < (ipv6_buf->length - ICMPV6_HDR_LEN)) {
|
||||
rpl_opt_buf = get_rpl_opt_buf(len);
|
||||
|
||||
switch(rpl_opt_buf->type) {
|
||||
switch (rpl_opt_buf->type) {
|
||||
case (RPL_OPT_PAD1): {
|
||||
len += 1;
|
||||
break;
|
||||
@ -808,7 +799,7 @@ void recv_rpl_dao(void)
|
||||
while (len < (ipv6_buf->length - ICMPV6_HDR_LEN)) {
|
||||
rpl_opt_buf = get_rpl_opt_buf(len);
|
||||
|
||||
switch(rpl_opt_buf->type) {
|
||||
switch (rpl_opt_buf->type) {
|
||||
|
||||
case (RPL_OPT_PAD1): {
|
||||
len += 1;
|
||||
@ -899,7 +890,7 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_
|
||||
uint8_t *p_ptr;
|
||||
ipv6_send_buf = get_rpl_send_ipv6_buf();
|
||||
p_ptr = get_rpl_send_payload_buf(ipv6_ext_hdr_len);
|
||||
packet_length = 0;
|
||||
uint16_t packet_length = 0;
|
||||
|
||||
ipv6_send_buf->version_trafficclass = IPV6_VER;
|
||||
ipv6_send_buf->trafficclass_flowlabel = 0;
|
||||
@ -909,7 +900,7 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_
|
||||
ipv6_send_buf->length = p_len;
|
||||
|
||||
memcpy(&(ipv6_send_buf->destaddr), destination, 16);
|
||||
ipv6_get_saddr(&(ipv6_send_buf->srcaddr), &(ipv6_send_buf->destaddr));
|
||||
ipv6_iface_get_best_src_addr(&(ipv6_send_buf->srcaddr), &(ipv6_send_buf->destaddr));
|
||||
|
||||
/* The packet was "assembled" in rpl.c. Therefore rpl_send_buf was used.
|
||||
* Therefore memcpy is not needed because the payload is at the
|
||||
@ -921,8 +912,10 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_
|
||||
|
||||
packet_length = IPV6_HDR_LEN + p_len;
|
||||
|
||||
if (ipv6_prefix_mcast_match(&ipv6_send_buf->destaddr)) {
|
||||
lowpan_init((ieee_802154_long_t *)&(ipv6_send_buf->destaddr.uint16[4]), (uint8_t *)ipv6_send_buf);
|
||||
if (ipv6_addr_is_multicast(&ipv6_send_buf->destaddr)) {
|
||||
sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(ipv6_send_buf->destaddr.uint16[4]),
|
||||
(uint8_t *)ipv6_send_buf,
|
||||
packet_length);
|
||||
}
|
||||
else {
|
||||
/* find appropriate next hop before sending */
|
||||
@ -943,7 +936,9 @@ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_
|
||||
}
|
||||
}
|
||||
|
||||
lowpan_init((ieee_802154_long_t *)&(next_hop->uint16[4]), (uint8_t *)ipv6_send_buf);
|
||||
sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(next_hop->uint16[4]),
|
||||
(uint8_t *)ipv6_send_buf,
|
||||
packet_length);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* RPL constants and prototypes
|
||||
* RPL constants and prototypes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
@ -7,7 +7,7 @@
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup rpl
|
||||
* @ingroup rpl
|
||||
* @{
|
||||
* @file rpl.h
|
||||
* @brief RPL header
|
||||
@ -20,7 +20,7 @@
|
||||
#include <vtimer.h>
|
||||
#include <mutex.h>
|
||||
#include <transceiver.h>
|
||||
#include "sixlowpan/sixlowip.h"
|
||||
#include "ipv6.h"
|
||||
#include "rpl_dodag.h"
|
||||
|
||||
#define CC1100_RADIO_MODE CC1100_MODE_WOR
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* RPL dodag implementation
|
||||
* RPL dodag implementation
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
@ -7,10 +7,10 @@
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup rpl
|
||||
* @ingroup rpl
|
||||
* @{
|
||||
* @file rpl_dodag.c
|
||||
* @brief RPL dodag functions
|
||||
* @brief RPL dodag functions
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
@ -179,7 +179,7 @@ void rpl_delete_parent(rpl_parent_t *parent)
|
||||
rpl_dodag_t *my_dodag = rpl_get_my_dodag();
|
||||
|
||||
if ((my_dodag != NULL) && rpl_equal_id(&my_dodag->my_preferred_parent->addr,
|
||||
&parent->addr)) {
|
||||
&parent->addr)) {
|
||||
my_dodag->my_preferred_parent = NULL;
|
||||
}
|
||||
|
||||
@ -275,7 +275,7 @@ void rpl_parent_update(rpl_parent_t *parent)
|
||||
}
|
||||
|
||||
if (rpl_calc_rank(old_rank, my_dodag->minhoprankincrease) !=
|
||||
rpl_calc_rank(my_dodag->my_rank, my_dodag->minhoprankincrease)) {
|
||||
rpl_calc_rank(my_dodag->my_rank, my_dodag->minhoprankincrease)) {
|
||||
if (my_dodag->my_rank < my_dodag->min_rank) {
|
||||
my_dodag->min_rank = my_dodag->my_rank;
|
||||
}
|
||||
@ -348,7 +348,7 @@ void rpl_global_repair(rpl_dodag_t *dodag, ipv6_addr_t *p_addr, uint16_t rank)
|
||||
else {
|
||||
/* Calc new Rank */
|
||||
my_dodag->my_rank = my_dodag->of->calc_rank(my_dodag->my_preferred_parent,
|
||||
my_dodag->my_rank);
|
||||
my_dodag->my_rank);
|
||||
my_dodag->min_rank = my_dodag->my_rank;
|
||||
reset_trickletimer();
|
||||
delay_dao();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* RPL dodag prototypes
|
||||
* RPL dodag prototypes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
@ -7,15 +7,16 @@
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup rpl
|
||||
* @ingroup rpl
|
||||
* @{
|
||||
* @file rpl_dodag.h
|
||||
* @brief RPL dodag header
|
||||
* @brief RPL dodag header
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "ipv6.h"
|
||||
#include "rpl_structs.h"
|
||||
|
||||
rpl_instance_t *rpl_new_instance(uint8_t instanceid);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* RPL data structs
|
||||
* RPL data structs
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
@ -7,7 +7,7 @@
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup rpl
|
||||
* @ingroup rpl
|
||||
* @{
|
||||
* @file rpl_structs.h
|
||||
* @brief RPL data structs
|
||||
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "sixlowpan/sixlowip.h"
|
||||
#include "ipv6.h"
|
||||
|
||||
#ifndef RPL_STRUCTS_H_INCLUDED
|
||||
#define RPL_STRUCTS_H_INCLUDED
|
||||
@ -219,12 +219,12 @@ struct rpl_dodag_t;
|
||||
typedef struct {
|
||||
ipv6_addr_t addr;
|
||||
uint16_t rank;
|
||||
uint8_t dtsn;
|
||||
uint8_t dtsn;
|
||||
struct rpl_dodag_t *dodag;
|
||||
uint16_t lifetime;
|
||||
double link_metric;
|
||||
uint8_t link_metric_type;
|
||||
uint8_t used;
|
||||
uint16_t lifetime;
|
||||
double link_metric;
|
||||
uint8_t link_metric_type;
|
||||
uint8_t used;
|
||||
} rpl_parent_t;
|
||||
|
||||
struct rpl_of_t;
|
||||
@ -264,13 +264,13 @@ typedef struct rpl_dodag_t {
|
||||
|
||||
typedef struct rpl_of_t {
|
||||
uint16_t ocp;
|
||||
uint16_t (*calc_rank)(rpl_parent_t * parent, uint16_t base_rank);
|
||||
uint16_t (*calc_rank)(rpl_parent_t *parent, uint16_t base_rank);
|
||||
rpl_parent_t *(*which_parent)(rpl_parent_t *, rpl_parent_t *);
|
||||
rpl_dodag_t *(*which_dodag)(rpl_dodag_t *, rpl_dodag_t *);
|
||||
void (*reset)(rpl_dodag_t *);
|
||||
void (*parent_state_callback)(rpl_parent_t *, int, int);
|
||||
void (*init) (void); //OF specific init function
|
||||
void (*process_dio) (void); //DIO processing callback (acc. to OF0 spec, chpt 5)
|
||||
void (*init)(void); //OF specific init function
|
||||
void (*process_dio)(); //DIO processing callback (acc. to OF0 spec, chpt 5)
|
||||
} rpl_of_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup rpl
|
||||
* @ingroup rpl
|
||||
* @{
|
||||
* @file trickle.c
|
||||
* @brief Trickle implementation
|
||||
@ -25,9 +25,9 @@
|
||||
#include "rpl/rpl.h"
|
||||
|
||||
//TODO in pointer umwandeln, speicher mit malloc holen
|
||||
char * timer_over_buf;
|
||||
char * interval_over_buf;
|
||||
char * dao_delay_over_buf;
|
||||
char *timer_over_buf;
|
||||
char *interval_over_buf;
|
||||
char *dao_delay_over_buf;
|
||||
char routing_table_buf[RT_STACKSIZE];
|
||||
int timer_over_pid;
|
||||
int interval_over_pid;
|
||||
@ -71,18 +71,23 @@ void reset_trickletimer(void)
|
||||
|
||||
void init_trickle(void)
|
||||
{
|
||||
timer_over_buf = calloc(TRICKLE_TIMER_STACKSIZE,sizeof(char));
|
||||
if(timer_over_buf == NULL){
|
||||
timer_over_buf = calloc(TRICKLE_TIMER_STACKSIZE, sizeof(char));
|
||||
|
||||
if (timer_over_buf == NULL) {
|
||||
puts("[ERROR] Could not allocate enough memory for timer_over_buf!");
|
||||
return;
|
||||
}
|
||||
interval_over_buf = calloc(TRICKLE_INTERVAL_STACKSIZE,sizeof(char));
|
||||
if(interval_over_buf == NULL){
|
||||
|
||||
interval_over_buf = calloc(TRICKLE_INTERVAL_STACKSIZE, sizeof(char));
|
||||
|
||||
if (interval_over_buf == NULL) {
|
||||
puts("[ERROR] Could not allocate enough memory for interval_over_buf!");
|
||||
return;
|
||||
}
|
||||
dao_delay_over_buf = calloc(DAO_DELAY_STACKSIZE,sizeof(char));
|
||||
if(dao_delay_over_buf == NULL){
|
||||
|
||||
dao_delay_over_buf = calloc(DAO_DELAY_STACKSIZE, sizeof(char));
|
||||
|
||||
if (dao_delay_over_buf == NULL) {
|
||||
puts("[ERROR] Could not allocate enough memory for interval_over_buf!");
|
||||
return;
|
||||
}
|
||||
@ -135,7 +140,7 @@ void trickle_increment_counter(void)
|
||||
void trickle_timer_over(void)
|
||||
{
|
||||
ipv6_addr_t mcast;
|
||||
ipv6_set_all_nds_mcast_addr(&mcast);
|
||||
ipv6_addr_set_all_nodes_addr(&mcast);
|
||||
|
||||
while (1) {
|
||||
thread_sleep();
|
||||
|
||||
@ -7,10 +7,10 @@
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup rpl
|
||||
* @ingroup rpl
|
||||
* @{
|
||||
* @file trickle.h
|
||||
* @brief Trickle
|
||||
* @brief Trickle
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
MODULE:=$(shell basename $(CURDIR))
|
||||
INCLUDES = -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/sys/net -I$(RIOTBASE)/cpu/arm_common/include/
|
||||
INCLUDES = -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/sixlowpan/include/
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* 6lowpan border router implementation
|
||||
* 6lowpan border router implementation
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
@ -10,7 +10,7 @@
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowborder.c
|
||||
* @brief constraint node implementation for a 6lowpan border router
|
||||
* @brief constraint node implementation for a 6lowpan border router
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
@ -19,24 +19,25 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <mutex.h>
|
||||
#include <thread.h>
|
||||
#include <msg.h>
|
||||
|
||||
#include <posix_io.h>
|
||||
#include <board_uart0.h>
|
||||
#include "mutex.h"
|
||||
#include "thread.h"
|
||||
#include "msg.h"
|
||||
#include "posix_io.h"
|
||||
#include "board_uart0.h"
|
||||
|
||||
#include "sixlowpan/error.h"
|
||||
#include "bordermultiplex.h"
|
||||
#include "ieee802154/ieee802154_frame.h"
|
||||
#include "flowcontrol.h"
|
||||
#include "sixlowborder.h"
|
||||
#include "sixlowip.h"
|
||||
#include "sixlownd.h"
|
||||
#include "border.h"
|
||||
#include "ip.h"
|
||||
#include "icmp.h"
|
||||
#include "serialnumber.h"
|
||||
#include "sixlowerror.h"
|
||||
|
||||
#include "sys/net/ieee802154/ieee802154_frame.h"
|
||||
#include "sys/net/net_help/net_help.h"
|
||||
|
||||
#define READER_STACK_SIZE 512
|
||||
#define READER_STACK_SIZE (KERNEL_CONF_STACKSIZE_DEFAULT)
|
||||
|
||||
ipv6_addr_t abr_addr;
|
||||
|
||||
@ -86,7 +87,7 @@ void serial_reader_f(void)
|
||||
bytes = readpacket(get_serial_in_buffer(0), BORDER_BUFFER_SIZE);
|
||||
|
||||
if (bytes < 0) {
|
||||
switch(bytes) {
|
||||
switch (bytes) {
|
||||
case (-SIXLOWERROR_ARRAYFULL): {
|
||||
printf("ERROR: Array was full\n");
|
||||
break;
|
||||
@ -119,7 +120,8 @@ void serial_reader_f(void)
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t border_initialize(transceiver_type_t trans, ipv6_addr_t *border_router_addr)
|
||||
uint8_t sixlowpan_lowpan_border_init(transceiver_type_t trans,
|
||||
const ipv6_addr_t *border_router_addr)
|
||||
{
|
||||
ipv6_addr_t addr;
|
||||
|
||||
@ -139,9 +141,9 @@ uint8_t border_initialize(transceiver_type_t trans, ipv6_addr_t *border_router_a
|
||||
* -- for now
|
||||
*/
|
||||
if (border_router_addr->uint16[4] != HTONS(IEEE_802154_PAN_ID ^ 0x0200) ||
|
||||
border_router_addr->uint16[5] != HTONS(0x00FF) ||
|
||||
border_router_addr->uint16[6] != HTONS(0xFE00)
|
||||
) {
|
||||
border_router_addr->uint16[5] != HTONS(0x00FF) ||
|
||||
border_router_addr->uint16[6] != HTONS(0xFE00)
|
||||
) {
|
||||
return SIXLOWERROR_ADDRESS;
|
||||
}
|
||||
|
||||
@ -152,26 +154,13 @@ uint8_t border_initialize(transceiver_type_t trans, ipv6_addr_t *border_router_a
|
||||
|
||||
memcpy(&(abr_addr.uint8[0]), &(border_router_addr->uint8[0]), 16);
|
||||
|
||||
sixlowpan_init(trans, border_router_addr->uint8[15], 1);
|
||||
sixlowpan_lowpan_init(trans, border_router_addr->uint8[15], 1);
|
||||
|
||||
ipv6_init_iface_as_router();
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void border_send_ipv6_over_lowpan(ipv6_hdr_t *packet, uint8_t aro_flag, uint8_t sixco_flag)
|
||||
{
|
||||
uint16_t offset = IPV6_HDR_LEN + HTONS(packet->length);
|
||||
|
||||
packet->flowlabel = HTONS(packet->flowlabel);
|
||||
packet->length = HTONS(packet->length);
|
||||
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
memcpy(buffer + LL_HDR_LEN, packet, offset);
|
||||
|
||||
lowpan_init((ieee_802154_long_t *)&(packet->destaddr.uint16[4]), (uint8_t *)packet);
|
||||
}
|
||||
|
||||
void border_process_lowpan(void)
|
||||
{
|
||||
msg_t m;
|
||||
@ -181,10 +170,10 @@ void border_process_lowpan(void)
|
||||
msg_receive(&m);
|
||||
ipv6_buf = (ipv6_hdr_t *)m.content.ptr;
|
||||
|
||||
if (ipv6_buf->nextheader == PROTO_NUM_ICMPV6) {
|
||||
struct icmpv6_hdr_t *icmp_buf = (struct icmpv6_hdr_t *)(((uint8_t *)ipv6_buf) + IPV6_HDR_LEN);
|
||||
if (ipv6_buf->nextheader == IPV6_PROTO_NUM_ICMPV6) {
|
||||
icmpv6_hdr_t *icmp_buf = (icmpv6_hdr_t *)(((uint8_t *)ipv6_buf) + IPV6_HDR_LEN);
|
||||
|
||||
if (icmp_buf->type == ICMP_REDIRECT) {
|
||||
if (icmp_buf->type == ICMPV6_TYPE_REDIRECT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowborder.h
|
||||
* @brief header for 6lowpan border router
|
||||
* @brief header for 6lowpan border router
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
@ -18,14 +18,15 @@
|
||||
|
||||
/* 6LoWPAN Border Router header file */
|
||||
|
||||
#ifndef SIXLOWBORDER_H
|
||||
#define SIXLOWBORDER_H
|
||||
#ifndef _SIXLOWPAN_BORDER_H
|
||||
#define _SIXLOWPAN_BORDER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <mutex.h>
|
||||
#include <transceiver.h>
|
||||
|
||||
#include "sixlowip.h"
|
||||
#include "mutex.h"
|
||||
#include "transceiver.h"
|
||||
|
||||
#include "ip.h"
|
||||
#include "semaphore.h"
|
||||
|
||||
extern ipv6_addr_t abr_addr;
|
||||
@ -35,8 +36,6 @@ uint16_t border_get_serial_reader(void);
|
||||
uint8_t *get_serial_out_buffer(int offset);
|
||||
uint8_t *get_serial_in_buffer(int offset);
|
||||
|
||||
uint8_t border_initialize(transceiver_type_t trans, ipv6_addr_t *border_router_addr);
|
||||
void border_send_ipv6_over_lowpan(ipv6_hdr_t *packet, uint8_t aro_flag, uint8_t sixco_flag);
|
||||
void border_process_lowpan(void);
|
||||
|
||||
#endif /* SIXLOWBORDER_H*/
|
||||
#endif /* _SIXLOWPAN_BORDER_H*/
|
||||
@ -19,24 +19,24 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <board_uart0.h>
|
||||
#include "board_uart0.h"
|
||||
#include "sixlowpan/error.h"
|
||||
|
||||
#include "flowcontrol.h"
|
||||
#include "sixlowpan.h"
|
||||
#include "sixlownd.h"
|
||||
#include "sixlowborder.h"
|
||||
#include "sixlowerror.h"
|
||||
#include "lowpan.h"
|
||||
#include "icmp.h"
|
||||
#include "border.h"
|
||||
|
||||
#include "bordermultiplex.h"
|
||||
|
||||
#define END 0xC0
|
||||
#define ESC 0xDB
|
||||
#define END_ESC 0xDC
|
||||
#define ESC_ESC 0xDD
|
||||
#define END (0xC0)
|
||||
#define ESC (0xDB)
|
||||
#define END_ESC (0xDC)
|
||||
#define ESC_ESC (0xDD)
|
||||
|
||||
void demultiplex(border_packet_t *packet, int len)
|
||||
{
|
||||
switch(packet->type) {
|
||||
switch (packet->type) {
|
||||
case (BORDER_PACKET_RAW_TYPE): {
|
||||
fputs(((char *)packet) + sizeof(border_packet_t), stdin);
|
||||
break;
|
||||
@ -45,10 +45,10 @@ void demultiplex(border_packet_t *packet, int len)
|
||||
case (BORDER_PACKET_L3_TYPE): {
|
||||
border_l3_header_t *l3_header_buf = (border_l3_header_t *)packet;
|
||||
|
||||
switch(l3_header_buf->ethertype) {
|
||||
switch (l3_header_buf->ethertype) {
|
||||
case (BORDER_ETHERTYPE_IPV6): {
|
||||
ipv6_hdr_t *ipv6_buf = (ipv6_hdr_t *)(((unsigned char *)packet) + sizeof(border_l3_header_t));
|
||||
border_send_ipv6_over_lowpan(ipv6_buf, 1, 1);
|
||||
ipv6_send_bytes(ipv6_buf);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -63,11 +63,11 @@ void demultiplex(border_packet_t *packet, int len)
|
||||
case (BORDER_PACKET_CONF_TYPE): {
|
||||
border_conf_header_t *conf_header_buf = (border_conf_header_t *)packet;
|
||||
|
||||
switch(conf_header_buf->conftype) {
|
||||
switch (conf_header_buf->conftype) {
|
||||
case (BORDER_CONF_CONTEXT): {
|
||||
border_context_packet_t *context = (border_context_packet_t *)packet;
|
||||
ipv6_addr_t target_addr;
|
||||
ipv6_set_all_nds_mcast_addr(&target_addr);
|
||||
ipv6_addr_set_all_nodes_addr(&target_addr);
|
||||
mutex_lock(&lowpan_context_mutex);
|
||||
lowpan_context_update(
|
||||
context->context.cid,
|
||||
@ -148,7 +148,7 @@ int readpacket(uint8_t *packet_buf, size_t size)
|
||||
if (esc) {
|
||||
esc = 0;
|
||||
|
||||
switch(byte) {
|
||||
switch (byte) {
|
||||
case (END_ESC): {
|
||||
*line_buf_ptr++ = END;
|
||||
continue;
|
||||
@ -184,7 +184,7 @@ int writepacket(uint8_t *packet_buf, size_t size)
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(*byte_ptr) {
|
||||
switch (*byte_ptr) {
|
||||
case (END): {
|
||||
*byte_ptr = END_ESC;
|
||||
uart0_putc(ESC);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* 6lowpan border router multiplexer
|
||||
* 6lowpan border router multiplexer
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
@ -9,32 +9,32 @@
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file bordermultiplex.h
|
||||
* @file bordermultiplex.h
|
||||
* @brief data structs for border router multiplexing
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef BORDERMULTIPLEX_H
|
||||
#define BORDERMULTIPLEX_H
|
||||
#ifndef _SIXLOWPAN_BORDERMULTIPLEX_H
|
||||
#define _SIXLOWPAN_BORDERMULTIPLEX_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "sixlowip.h"
|
||||
#include "ip.h"
|
||||
|
||||
/* packet types of uart-packets */
|
||||
#define BORDER_PACKET_RAW_TYPE 0
|
||||
#define BORDER_PACKET_CONF_TYPE 2
|
||||
#define BORDER_PACKET_L3_TYPE 3
|
||||
#define BORDER_PACKET_RAW_TYPE (0)
|
||||
#define BORDER_PACKET_CONF_TYPE (2)
|
||||
#define BORDER_PACKET_L3_TYPE (3)
|
||||
|
||||
/* configuration types */
|
||||
#define BORDER_CONF_CONTEXT 2
|
||||
#define BORDER_CONF_IPADDR 3
|
||||
#define BORDER_CONF_CONTEXT (2)
|
||||
#define BORDER_CONF_IPADDR (3)
|
||||
|
||||
/* ethertypes for L3 packets */
|
||||
#define BORDER_ETHERTYPE_IPV6 0x86DD
|
||||
#define BORDER_ETHERTYPE_IPV6 (0x86DD)
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t empty;
|
||||
@ -80,7 +80,7 @@ typedef struct __attribute__((packed)) {
|
||||
} context;
|
||||
} border_context_packet_t;
|
||||
|
||||
#define BORDER_BUFFER_SIZE (sizeof(border_l3_header_t) + MTU)
|
||||
#define BORDER_BUFFER_SIZE (sizeof(border_l3_header_t) + IPV6_MTU)
|
||||
|
||||
void demultiplex(border_packet_t *packet, int len);
|
||||
void multiplex_send_ipv6_over_uart(ipv6_hdr_t *packet);
|
||||
@ -89,4 +89,4 @@ void multiplex_send_addr_over_uart(ipv6_addr_t *addr);
|
||||
int readpacket(uint8_t *packet_buf, size_t size);
|
||||
int writepacket(uint8_t *packet_buf, size_t size);
|
||||
|
||||
#endif /* BORDERMULTIPLEX_H*/
|
||||
#endif /* _SIXLOWPAN_BORDERMULTIPLEX_H*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* 6lowpan border router flow control
|
||||
* 6lowpan border router flow control
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
@ -10,7 +10,7 @@
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file flowcontrol.c
|
||||
* @brief flowcontrol for constraint node border router implementation
|
||||
* @brief flowcontrol for constraint node border router implementation
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
@ -125,7 +125,7 @@ static int in_window(uint8_t seq_num, uint8_t min, uint8_t max)
|
||||
{
|
||||
uint8_t pos = seq_num - min;
|
||||
uint8_t maxpos = max - min + 1;
|
||||
return pos < maxpos;
|
||||
return (pos < maxpos);
|
||||
}
|
||||
|
||||
void flowcontrol_send_over_uart(border_packet_t *packet, int len)
|
||||
@ -181,8 +181,8 @@ void flowcontrol_deliver_from_uart(border_packet_t *packet, int len)
|
||||
slot = &(slwin_stat.recv_win[packet->seq_num % BORDER_RWS]);
|
||||
|
||||
if (!in_window(packet->seq_num,
|
||||
slwin_stat.next_exp,
|
||||
slwin_stat.next_exp + BORDER_RWS - 1)) {
|
||||
slwin_stat.next_exp,
|
||||
slwin_stat.next_exp + BORDER_RWS - 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* 6lowpan border router flow control
|
||||
* 6lowpan border router flow control
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
@ -16,29 +16,30 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef FLOWCONTROL_H
|
||||
#define FLOWCONTROL_H
|
||||
#ifndef _SIXLOWPAN_FLOWCONTROL_H
|
||||
#define _SIXLOWPAN_FLOWCONTROL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vtimer.h>
|
||||
|
||||
#include "vtimer.h"
|
||||
|
||||
#include "semaphore.h"
|
||||
#include "sixlowip.h"
|
||||
#include "sixlowborder.h"
|
||||
#include "ip.h"
|
||||
#include "border.h"
|
||||
#include "bordermultiplex.h"
|
||||
|
||||
/* packet types for flowcontrol */
|
||||
#define BORDER_PACKET_ACK_TYPE 1
|
||||
#define BORDER_PACKET_ACK_TYPE (1)
|
||||
|
||||
/* configuration types for flowcontrol */
|
||||
#define BORDER_CONF_SYN 0
|
||||
#define BORDER_CONF_SYNACK 1
|
||||
#define BORDER_CONF_SYN (0)
|
||||
#define BORDER_CONF_SYNACK (1)
|
||||
|
||||
#define BORDER_SWS 1
|
||||
#define BORDER_RWS 1
|
||||
#define BORDER_SL_TIMEOUT 500 // microseconds, maybe smaller
|
||||
#define BORDER_SWS (1)
|
||||
#define BORDER_RWS (1)
|
||||
#define BORDER_SL_TIMEOUT (500) // microseconds, maybe smaller
|
||||
|
||||
#define SENDING_SLOT_STACK_SIZE (256)
|
||||
#define SENDING_SLOT_STACK_SIZE (MINIMUM_STACK_SIZE + 256)
|
||||
|
||||
typedef struct {
|
||||
/* Sender state */
|
||||
@ -73,4 +74,4 @@ ipv6_addr_t flowcontrol_init(void);
|
||||
void flowcontrol_send_over_uart(border_packet_t *packet, int len);
|
||||
void flowcontrol_deliver_from_uart(border_packet_t *packet, int len);
|
||||
|
||||
#endif /* FLOWCONTROL_H*/
|
||||
#endif /* _SIXLOWPAN_FLOWCONTROL_H*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
64
sys/net/sixlowpan/icmp.h
Normal file
64
sys/net/sixlowpan/icmp.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 6lowpan neighbor discovery
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlownd.h
|
||||
* @brief 6lowpan neighbor discovery constants, data structs, and prototypes
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef _SIXLOWPAN_ICMP_H
|
||||
#define _SIXLOWPAN_ICMP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "vtimer.h"
|
||||
#include "sixlowpan/icmp.h"
|
||||
#include "sixlowpan/ndp.h"
|
||||
#include "sixlowpan/types.h"
|
||||
|
||||
#include "lowpan.h"
|
||||
#include "ip.h"
|
||||
|
||||
enum option_types_t {
|
||||
OPT_SLLAO = 1,
|
||||
OPT_TLLAO,
|
||||
OPT_PI,
|
||||
OPT_MTU,
|
||||
OPT_ARO,
|
||||
OPT_6CO,
|
||||
OPT_ABRO,
|
||||
OPT_DAR,
|
||||
OPT_DAC,
|
||||
};
|
||||
|
||||
extern unsigned int nd_nbr_cache_rem_pid;
|
||||
|
||||
|
||||
void recv_echo_req(void);
|
||||
void recv_echo_repl(void);
|
||||
void recv_rtr_sol(void);
|
||||
void recv_rtr_adv(void);
|
||||
void recv_nbr_adv(void);
|
||||
void recv_nbr_sol(void);
|
||||
|
||||
void nbr_cache_auto_rem(void);
|
||||
int8_t plist_add(ipv6_addr_t *addr, uint8_t size, uint32_t val_ltime,
|
||||
uint32_t pref_ltime, uint8_t adv_opt, uint8_t l_a_reserved1);
|
||||
|
||||
ndp_a6br_cache_t *abr_add_context(uint16_t version, ipv6_addr_t *abr_addr,
|
||||
uint8_t cid);
|
||||
void abr_remove_context(uint8_t cid);
|
||||
|
||||
uint16_t icmpv6_csum(uint8_t proto);
|
||||
#endif /* _SIXLOWPAN_ICMP_H*/
|
||||
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* ipv6.h - Wraps all API types, constants and functions of
|
||||
* 6LoWPAN in layer 3.
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file
|
||||
* @brief IPv6 and ICMP functions
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
*/
|
||||
#ifndef IPV6_H
|
||||
#define IPV6_H
|
||||
|
||||
#include "sixlowpan/error.h"
|
||||
#include "sixlowpan/types.h"
|
||||
#include "sixlowpan/ip.h"
|
||||
#include "sixlowpan/icmp.h"
|
||||
#include "sixlowpan/ndp.h"
|
||||
|
||||
#include "../icmp.h" /* TODO: remove if not needed anymore */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* IPV6_H */
|
||||
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* sixlowpan.h - Wraps all API types, constants and functions
|
||||
* of 6LoWPAN concerning layers under 3.
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup sixlowpan 6LoWPAN
|
||||
* @ingroup net
|
||||
* @brief 6LoWPAN module implements (parts of) the 6LoWPAN adaption layer
|
||||
* for IPv6 over Low Power Wireless Personal Area Networks
|
||||
* (6LoWPANs)
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4919">
|
||||
* RFC 4919 - IPv6 over Low-Power Wireless Personal Area
|
||||
* Networks (6LoWPANs): Overview, Assumptions, Problem
|
||||
* Statement, and Goals
|
||||
* </a>
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4944">
|
||||
* RFC 4944 - Transmission of IPv6 Packets over
|
||||
* IEEE 802.15.4 Networks
|
||||
* </a>
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6282">
|
||||
* RFC 6282 - Compression Format for IPv6 Datagrams over
|
||||
* IEEE 802.15.4-Based Networks
|
||||
* </a>
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6775">
|
||||
* RFC 6775 - Neighbor Discovery Optimization for IPv6
|
||||
* over Low-Power Wireless Personal Area Networks
|
||||
* (6LoWPANs)
|
||||
* </a>
|
||||
* @{
|
||||
* @file
|
||||
* @brief 6lowpan link layer and lowpan functions
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
*/
|
||||
#ifndef SIXLOWPAN_H
|
||||
#define SIXLOWPAN_H
|
||||
|
||||
#include "sixlowpan/error.h"
|
||||
#include "sixlowpan/types.h"
|
||||
#include "sixlowpan/lowpan.h"
|
||||
#include "sixlowpan/mac.h"
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* SIXLOWPAN_H */
|
||||
102
sys/net/sixlowpan/include/sixlowpan/error.h
Normal file
102
sys/net/sixlowpan/include/sixlowpan/error.h
Normal file
@ -0,0 +1,102 @@
|
||||
/**
|
||||
* sixlowpan/error.h - 6LoWPAN error codes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file
|
||||
* @brief 6LoWPAN error codes
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef SIXLOWPAN_ERROR_H
|
||||
#define SIXLOWPAN_ERROR_H
|
||||
|
||||
#ifndef SUCCESS
|
||||
/**
|
||||
* Functions return this if call was success. Only defined if not
|
||||
* already defined by other header.
|
||||
*/
|
||||
#define SUCCESS (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Error code that signals that array is full.
|
||||
*/
|
||||
#define SIXLOWERROR_ARRAYFULL (132)
|
||||
|
||||
/**
|
||||
* Error code that signals a NULL pointer error.
|
||||
*/
|
||||
#define SIXLOWERROR_NULLPTR (133)
|
||||
|
||||
/**
|
||||
* Error code that signals an illegal value.
|
||||
*/
|
||||
#define SIXLOWERROR_VALUE (134)
|
||||
|
||||
/**
|
||||
* Error code that signals an illegal address.
|
||||
*/
|
||||
#define SIXLOWERROR_ADDRESS (135)
|
||||
|
||||
/**
|
||||
* Error code that signals an unknown 6LoWPAN dispatch
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4944#section-5">
|
||||
* RFC 4944, Section 5: LoWPAN Adaptation Layer and Frame Format
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWERROR_DISPATCH (136)
|
||||
|
||||
/**
|
||||
* Error code that signals that the first 6LoWPAN fragment was
|
||||
* not received
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4944#section-5.3">
|
||||
* RFC 4944, Section 5.3: Fragmentation Type and Header
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWERROR_FSTFRAG (137)
|
||||
|
||||
/**
|
||||
* Error code that signals that an invalid 6LoWPAN fragment was
|
||||
* received.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4944#section-5.3">
|
||||
* RFC 4944, Section 5.3: Fragmentation Type and Header
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWERROR_INVFRAG (138)
|
||||
|
||||
/**
|
||||
* Error code that signals that the source context identifier was not
|
||||
* found.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1">
|
||||
* RFC 6282, Section 3.1: LOWPAN_IPHC Encoding format
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWERROR_SCI (139)
|
||||
|
||||
/**
|
||||
* Error code that signals that the destination context identifier was
|
||||
* not found.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1">
|
||||
* RFC 6282, Section 3.1: LOWPAN_IPHC Encoding format
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWERROR_DCI (140)
|
||||
|
||||
/**
|
||||
* Error code that signals that the destination context identifier was
|
||||
* not found.
|
||||
*/
|
||||
#define SIXLOWERROR_CSUM (141)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* SIXLOWPAN_ERROR_H */
|
||||
236
sys/net/sixlowpan/include/sixlowpan/icmp.h
Normal file
236
sys/net/sixlowpan/include/sixlowpan/icmp.h
Normal file
@ -0,0 +1,236 @@
|
||||
/**
|
||||
* sixlowpan/icmp.h - 6LoWPAN constants, data structs, and prototypes
|
||||
* related to ICMP
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file
|
||||
* @brief 6LoWPAN ICMP related header
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
*/
|
||||
|
||||
#ifndef SIXLOWPAN_ICMP_H
|
||||
#define SIXLOWPAN_ICMP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sixlowpan/types.h"
|
||||
|
||||
/**
|
||||
* @brief ICMPv6 packet type for parameter problem message.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4443#section-3.4">
|
||||
* RFC 4443, section 3.4
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_TYPE_PARAMETER_PROB (4)
|
||||
|
||||
/**
|
||||
* @brief ICMPv6 packet type for an echo request.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4443#section-4.1">
|
||||
* RFC 4443, section 4.1
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_TYPE_ECHO_REQUEST (128)
|
||||
|
||||
/**
|
||||
* @brief ICMPv6 packet type for an echo reply.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4443#section-4.2">
|
||||
* RFC 4443, section 4.2
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_TYPE_ECHO_REPLY (129)
|
||||
|
||||
/**
|
||||
* @brief ICMPv6 packet type for a router solicitation.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.1">
|
||||
* RFC 4861, section 4.1
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_TYPE_ROUTER_SOL (133)
|
||||
|
||||
/**
|
||||
* @brief ICMPv6 packet type for a router advertisement.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.2">
|
||||
* RFC 4861, section 4.2
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_TYPE_ROUTER_ADV (134)
|
||||
|
||||
/**
|
||||
* @brief ICMPv6 packet type for a neighbor solicitation.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.3">
|
||||
* RFC 4861, section 4.3
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_TYPE_NEIGHBOR_SOL (135)
|
||||
|
||||
/**
|
||||
* @brief ICMPv6 packet type for a neighbor advertisement.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.4">
|
||||
* RFC 4861, section 4.4
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_TYPE_NEIGHBOR_ADV (136)
|
||||
|
||||
/**
|
||||
* @brief ICMPv6 packet type for a redirect message.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.5">
|
||||
* RFC 4861, section 4.5
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_TYPE_REDIRECT (137)
|
||||
|
||||
/**
|
||||
* @brief ICMPv6 packet type for a rpl control message.
|
||||
* @note TODO: not RFC conform.
|
||||
*/
|
||||
#define ICMPV6_TYPE_RPL_CONTROL (155)
|
||||
|
||||
/**
|
||||
* @brief ICMPv6 parameter problem message code for
|
||||
* "Erroneous header field encountered".
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4443#section-3.4">
|
||||
* RFC 4443, section 3.4
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_PARAMETER_PROB_CODE_ERR (0)
|
||||
|
||||
/**
|
||||
* @brief ICMPv6 parameter problem message code for
|
||||
* "Unrecognized Next Header type encountered".
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4443#section-3.4">
|
||||
* RFC 4443, section 3.4
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_PARAMETER_PROB_CODE_NXT_HDR_UNREC (1)
|
||||
|
||||
/**
|
||||
* @brief ICMPv6 parameter problem message code for
|
||||
* "Unrecognized IPv6 option encountered".
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4443#section-3.4">
|
||||
* RFC 4443, section 3.4
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_PARAMETER_PROB_CODE_IPV6_OPT_UNREC (2)
|
||||
|
||||
/**
|
||||
* @brief Send ICMPv6 parameter problem message.
|
||||
*
|
||||
* @param[in] src Source address for IPv6 header.
|
||||
* @param[in] dest Destination address for IPv6 header.
|
||||
* @param[in] code Value for code field of parameter problem
|
||||
* message.
|
||||
* @param[in] pointer Value for pointer field of parameter problem
|
||||
* message.
|
||||
* @param[in] packet Data payload for echo request.
|
||||
* @param[in] packet_len Length of data payload.
|
||||
*/
|
||||
void icmpv6_send_parameter_prob(ipv6_addr_t *src, ipv6_addr_t *dest,
|
||||
uint8_t code, uint32_t pointer,
|
||||
uint8_t *packet, uint8_t packet_len);
|
||||
|
||||
/**
|
||||
* @brief Send ICMPv6 echo request.
|
||||
*
|
||||
* @param[in] destaddr Destination address for IPv6 header.
|
||||
* @param[in] id Value for identifier field of echo request.
|
||||
* @param[in] seq Value for sequence number field of echo request.
|
||||
* @param[in] data Data payload for echo request.
|
||||
* @param[in] data_len Length of data payload.
|
||||
*/
|
||||
void icmpv6_send_echo_request(ipv6_addr_t *destaddr, uint16_t id,
|
||||
uint16_t seq, char *data,
|
||||
size_t data_len);
|
||||
|
||||
/**
|
||||
* @brief Send ICMPv6 echo reply.
|
||||
*
|
||||
* @param[in] destaddr Destination address for IPv6 header.
|
||||
* @param[in] id Value for identifier field of echo reply.
|
||||
* @param[in] seq Value for sequence number field of echo reply.
|
||||
* @param[in] data Data payload for echo reply.
|
||||
* @param[in] data_len Length of data payload.
|
||||
*/
|
||||
void icmpv6_send_echo_reply(ipv6_addr_t *destaddr, uint16_t id,
|
||||
uint16_t seq, char *data, size_t data_len);
|
||||
|
||||
/**
|
||||
* @brief Send ICMPv6 router solicitation.
|
||||
*
|
||||
* @param[in] sllao Flag to include source link-layer address
|
||||
* option. If *sllao* == OPT_SLLAO add it, else
|
||||
* not.
|
||||
*/
|
||||
void icmpv6_send_router_sol(uint8_t sllao);
|
||||
|
||||
/**
|
||||
* @brief Send ICMPv6 router advertisement.
|
||||
*
|
||||
* @param[in] addr Address of node to advertise router to. If
|
||||
* NULL *addr* is set to the all nodes multicast
|
||||
* address.
|
||||
* @param[in] sllao Flag to include source link-layer address
|
||||
* option. If *sllao* == OPT_SLLAO add it, else
|
||||
* not.
|
||||
* @param[in] mtu Flag to include MTU option. If *mtu* == OPT_MTU
|
||||
* add it, else not.
|
||||
* @param[in] pi Flag to include prefix information option. If
|
||||
* *pi* == OPT_PI add it, else not.
|
||||
* @param[in] sixco Flag to include 6LoWPAN context option. If
|
||||
* *sixco* == OPT_6CO add it, else not.
|
||||
* @param[in] abro Flag to include 6LoWPAN authoritive border
|
||||
* router option. If *abro* == OPT_ABRO add it,
|
||||
* else not.
|
||||
*/
|
||||
void icmpv6_send_router_adv(ipv6_addr_t *addr, uint8_t sllao,
|
||||
uint8_t mtu, uint8_t pi, uint8_t sixco,
|
||||
uint8_t abro);
|
||||
|
||||
/**
|
||||
* @brief Send ICMPv6 neighbor solicitation.
|
||||
*
|
||||
* @param[in] src Source address for IPv6 header.
|
||||
* @param[in] dest Destination address for IPv6 header.
|
||||
* @param[in] targ Value for target address field of neighbor
|
||||
* solicitation.
|
||||
* @param[in] sllao Flag to include source link-layer address
|
||||
* option. If *sllao* == OPT_SLLAO add it, else
|
||||
* not.
|
||||
* @param[in] aro Flag to include address registration option. If
|
||||
* *aro* == OPT_ARO add it, else not.
|
||||
*/
|
||||
void icmpv6_send_neighbor_sol(ipv6_addr_t *src, ipv6_addr_t *dest,
|
||||
ipv6_addr_t *targ, uint8_t slloa,
|
||||
uint8_t aro);
|
||||
|
||||
/**
|
||||
* @brief Send ICMPv6 neighbor advertisement.
|
||||
*
|
||||
* @param[in] src Source address for IPv6 header.
|
||||
* @param[in] dest Destination address for IPv6 header.
|
||||
* @param[in] targ Value for target address field of neighbor
|
||||
* advertisement.
|
||||
* @param[in] rso Value for flags field of neighbor advertisement.
|
||||
* @param[in] sllao Flag to include source link-layer address
|
||||
* option. If *sllao* == OPT_SLLAO add it, else
|
||||
* not.
|
||||
* @param[in] aro Flag to include address registration option. If
|
||||
* *aro* == OPT_ARO add it, else not.
|
||||
*/
|
||||
void icmpv6_send_neighbor_adv(ipv6_addr_t *src, ipv6_addr_t *dst,
|
||||
ipv6_addr_t *tgt, uint8_t rso,
|
||||
uint8_t sllao, uint8_t aro);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* SIXLOWPAN_ICMP_H */
|
||||
355
sys/net/sixlowpan/include/sixlowpan/ip.h
Normal file
355
sys/net/sixlowpan/include/sixlowpan/ip.h
Normal file
@ -0,0 +1,355 @@
|
||||
/**
|
||||
* sixlowpan/ip.h - 6LoWPAN constants, data structs, and prototypes
|
||||
* for network layer
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file
|
||||
* @brief 6LoWPAN network layer header
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
*/
|
||||
|
||||
#ifndef SIXLOWPAN_IP_H
|
||||
#define SIXLOWPAN_IP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sixlowpan/types.h"
|
||||
|
||||
/**
|
||||
* @brief IPv6 maximum transmission unit.
|
||||
*/
|
||||
#define IPV6_MTU (256)
|
||||
|
||||
/**
|
||||
* @brief Maximum length of a IPv6 address represented as string.
|
||||
*/
|
||||
#define IPV6_MAX_ADDR_STR_LEN (40)
|
||||
|
||||
/**
|
||||
* @brief L4 protocol number for TCP.
|
||||
*/
|
||||
#define IPV6_PROTO_NUM_TCP (6)
|
||||
|
||||
/**
|
||||
* @brief L4 protocol number for UDP.
|
||||
*/
|
||||
#define IPV6_PROTO_NUM_UDP (17)
|
||||
|
||||
/**
|
||||
* @brief L4 protocol number for ICMPv6.
|
||||
*/
|
||||
#define IPV6_PROTO_NUM_ICMPV6 (58)
|
||||
|
||||
/**
|
||||
* @brief L4 protocol number for no L4 protocol in IPv6.
|
||||
*/
|
||||
#define IPV6_PROTO_NUM_NONE (59)
|
||||
|
||||
/**
|
||||
* @brief L4 protocol number for IPv6 destination options.
|
||||
*/
|
||||
#define IPV6_PROTO_NUM_IPV6_OPTS (60)
|
||||
|
||||
/**
|
||||
* @brief Get IPv6 send/receive buffer.
|
||||
*
|
||||
* @return Pointer to IPv6 header in send/receive bouffer.
|
||||
* @note To be deleted in later releases. Here only because it is
|
||||
* used by the rpl module.
|
||||
*/
|
||||
ipv6_hdr_t *ipv6_get_buf(void);
|
||||
|
||||
/**
|
||||
* @brief Send IPv6 packet to dest.
|
||||
*
|
||||
* @param[in] dest Destination of this packet.
|
||||
* @param[in] next_header Next header ID of payload.
|
||||
* @param[in] payload Payload of the packet.
|
||||
* @param[in] payload_length Length of payload.
|
||||
*/
|
||||
void ipv6_sendto(const ipv6_addr_t *dest, uint8_t next_header,
|
||||
const uint8_t *payload, uint16_t payload_length);
|
||||
|
||||
/**
|
||||
* @brief Determines if node is a router.
|
||||
*
|
||||
* @return 1 if node is router, 0 otherwise.
|
||||
*/
|
||||
uint8_t ipv6_is_router(void);
|
||||
|
||||
/**
|
||||
* @brief Registers a handler thread for incoming IP packets.
|
||||
*
|
||||
* @param[in] pid PID of handler thread.
|
||||
*
|
||||
* @return 0 on success, ENOMEN if maximum number of registrable
|
||||
* threads is exceeded.
|
||||
*/
|
||||
uint8_t ipv6_register_packet_handler(int pid);
|
||||
|
||||
/**
|
||||
* @brief Registers a handler thread for L4 protocol.
|
||||
*
|
||||
* @param[in] next_header Next header ID of the L4 protocol.
|
||||
* @param[in] pid PID of the handler thread
|
||||
*/
|
||||
void ipv6_register_next_header_handler(uint8_t next_header, int pid);
|
||||
|
||||
/**
|
||||
* @brief Registers a handler thread for RPL options
|
||||
*
|
||||
* @param[in] pid PID of the handler thread.
|
||||
*/
|
||||
void ipv6_register_rpl_handler(int pid);
|
||||
|
||||
/**
|
||||
* @brief Sets the first 64 bit of *ipv6_addr* to link local prefix.
|
||||
*
|
||||
* @param[in,out] ipv6_addr The address to set.
|
||||
*/
|
||||
void ipv6_addr_set_link_local_prefix(ipv6_addr_t *ipv6_addr);
|
||||
|
||||
/**
|
||||
* @brief Sets IPv6 address *out* according to the remaining
|
||||
* parameters.
|
||||
*
|
||||
* @param[out] out The resulting address.
|
||||
* @param[in] addr0 The first 16 bit of the new address.
|
||||
* @param[in] addr1 The second 16 bit of the new address.
|
||||
* @param[in] addr2 The third 16 bit of the new address.
|
||||
* @param[in] addr3 The fourth 16 bit of the new address.
|
||||
* @param[in] addr4 The fifth 16 bit of the new address.
|
||||
* @param[in] addr5 The sixth 16 bit of the new address.
|
||||
* @param[in] addr6 The seventh 16 bit of the new address.
|
||||
* @param[in] addr7 The eighth 16 bit of the new address.
|
||||
*/
|
||||
void ipv6_addr_init(ipv6_addr_t *out, uint16_t addr0, uint16_t addr1,
|
||||
uint16_t addr2, uint16_t addr3, uint16_t addr4,
|
||||
uint16_t addr5, uint16_t addr6, uint16_t addr7);
|
||||
|
||||
/**
|
||||
* @brief Sets IPv6 address *out* using the given *prefix* and this
|
||||
* nodes EUI-64 (i. e. interface must be initialized).
|
||||
*
|
||||
* @param[out] out Address to be set.
|
||||
* @param[in] prefix 64-bit network prefix to be used for *out*
|
||||
* (only the first 64 bit of the ipv6_addr_t type
|
||||
* are copied to *out*)
|
||||
*/
|
||||
void ipv6_addr_set_by_eui64(ipv6_addr_t *out,
|
||||
const ipv6_addr_t *prefix);
|
||||
|
||||
/**
|
||||
* @brief Sets IPv6 address *out* with the first *bits* bit taken
|
||||
* from *prefix* and the remaining bits to 0.
|
||||
*
|
||||
* @param[out] out Prefix to be set.
|
||||
* @param[in] prefix Address to take prefix from.
|
||||
* @param[in] bits Bits to be copied from *prefix* to *out*
|
||||
* (set to 128 when greater than 128).
|
||||
*/
|
||||
void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix,
|
||||
uint8_t bits);
|
||||
|
||||
/**
|
||||
* @brief Set *ipv6_addr* to the loopback address.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4291">
|
||||
* RFC 4291
|
||||
* </a>
|
||||
*
|
||||
* @param[out] ipv6_addr Is set to the loopback address.
|
||||
*/
|
||||
void ipv6_addr_set_loopback_addr(ipv6_addr_t *ipv6_addr);
|
||||
|
||||
/**
|
||||
* @brief Set *ipv6_addr* to a link-local all routers multicast
|
||||
* address (ff02::/16 prefix).
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4291">
|
||||
* RFC 4291
|
||||
* </a>
|
||||
*
|
||||
* @param[out] ipv6_addr Is set to a link-local all routers multicast
|
||||
* address.
|
||||
*/
|
||||
void ipv6_addr_set_all_routers_addr(ipv6_addr_t *ipv6_addr);
|
||||
|
||||
/**
|
||||
* @brief Set *ipv6_addr* to a link-local all nodes multicast address
|
||||
* (ff02::/16 prefix).
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4291">
|
||||
* RFC 4291
|
||||
* </a>
|
||||
*
|
||||
* @param[out] ipv6_addr Is set to a link-local all nodes multicast
|
||||
* address.
|
||||
*/
|
||||
void ipv6_addr_set_all_nodes_addr(ipv6_addr_t *ipv6_addr);
|
||||
|
||||
/**
|
||||
* @brief Set *ipv6_addr_out* to the solicited-node multicast address
|
||||
* computed from *ipv6_addr_in*.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4291">
|
||||
* RFC 4291
|
||||
* </a>
|
||||
*
|
||||
* @param[out] ipv6_addr_out Is set to solicited-node address of
|
||||
* this node.
|
||||
* @param[in] ipv6_addr_in The IPv6 address the solicited-node
|
||||
* address.
|
||||
*/
|
||||
void ipv6_addr_set_solicited_node_addr(ipv6_addr_t *ipv6_addr_out,
|
||||
const ipv6_addr_t *ipv6_addr_in);
|
||||
|
||||
/**
|
||||
* @brief Converts IPv6 address into string (unabbrivated notation).
|
||||
* Note that addr_str must allocate at least
|
||||
* IPV6_MAX_ADDR_STR_LEN byte (40 byte).
|
||||
*
|
||||
* @param[out] addr_str The IPv6 address as string. Must allocate
|
||||
* at least IPV6_MAX_ADDR_STR_LEN byte (40
|
||||
* byte).
|
||||
* @param[in] ipv6_addr IPv6 address to be converted.
|
||||
*
|
||||
* @return Pointer to addr_str.
|
||||
*/
|
||||
char *ipv6_addr_to_str(char *addr_str, const ipv6_addr_t *ipv6_addr);
|
||||
|
||||
/**
|
||||
* @brief Checks if two IPv6 addresses are equal.
|
||||
*
|
||||
* @param[in] a An IPv6 address.
|
||||
* @param[in] b Another IPv6 address.
|
||||
*
|
||||
* @return 1 if *a* and *b* are equal, 0 otherwise.
|
||||
*/
|
||||
int ipv6_addr_is_equal(const ipv6_addr_t *a, const ipv6_addr_t *b);
|
||||
|
||||
/**
|
||||
* @brief Checks if *ipv6_addr* is unspecified (all zero).
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4291">
|
||||
* RFC 4291
|
||||
* </a>
|
||||
*
|
||||
* @param[in] ipv6_addr An IPv6 address.
|
||||
*
|
||||
* @return 1 if *ipv6_addr* is unspecified address, 0 otherwise.
|
||||
*/
|
||||
int ipv6_addr_is_unspecified(const ipv6_addr_t *ipv6_addr);
|
||||
|
||||
/**
|
||||
* @brief Check if *ipv6_addr* is a link-local address.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4291">
|
||||
* RFC 4291
|
||||
* </a>
|
||||
*
|
||||
* @param[in] ipv6_addr An IPv6 address.
|
||||
*
|
||||
* @return 1 if *ipv6_addr* is link-local address, 0 otherwise.
|
||||
*/
|
||||
int ipv6_addr_is_link_local(const ipv6_addr_t *ipv6_addr);
|
||||
|
||||
/**
|
||||
* @brief Check if *ipv6_addr* is unique local unicast address.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4193">
|
||||
* RFC 4193
|
||||
* </a>
|
||||
*
|
||||
* @param[in] ipv6_addr An IPv6 address.
|
||||
*
|
||||
* @return 1 if *ipv6_addr* is unique local unicast address,
|
||||
* 0 otherwise.
|
||||
*/
|
||||
int ipv6_addr_is_unique_local_unicast(const ipv6_addr_t *addr);
|
||||
|
||||
/**
|
||||
* @brief Check if *ipv6_addr* is a multicast address.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4291">
|
||||
* RFC 4291
|
||||
* </a>
|
||||
*
|
||||
* @param[in] ipv6_addr An IPv6 address.
|
||||
*
|
||||
* @return 1 if *ipv6_addr* is multicast address, 0 otherwise.
|
||||
*/
|
||||
int ipv6_addr_is_multicast(const ipv6_addr_t *ipv6_addr);
|
||||
|
||||
/**
|
||||
* @brief Check if *ipv6_addr* is solicited-node multicast address.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4291">
|
||||
* RFC 4291
|
||||
* </a>
|
||||
*
|
||||
* @param[in] ipv6_addr An IPv6 address.
|
||||
*
|
||||
* @return 1 if *ipv6_addr* is solicited-node multicast address,
|
||||
* 0 otherwise.
|
||||
*/
|
||||
int ipv6_addr_is_solicited_node(const ipv6_addr_t *ipv6_addr);
|
||||
|
||||
/*
|
||||
* TODO to wrap sixlowpan initialisations
|
||||
* int ipv6_iface_init(transceiver_type_t trans, ..);
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Add an IPv6 address to this nodes interface.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4862">
|
||||
* RFC 4862
|
||||
* </a>
|
||||
*
|
||||
* @param[in] addr Address to be added to the interface.
|
||||
* @param[in] type Type of this address.
|
||||
* @param[in] state Initial state of the address.
|
||||
* @param[in] val_ltime Valid lifetime of this address in seconds.
|
||||
* @param[in] pref_ltime Preferred lifetime of this address in
|
||||
* seconds.
|
||||
*/
|
||||
void ipv6_iface_add_addr(const ipv6_addr_t *addr, ipv6_addr_type_t type,
|
||||
ndp_addr_state_t state, uint32_t val_ltime,
|
||||
uint32_t pref_ltime);
|
||||
|
||||
/**
|
||||
* @brief Tries to determine best suitable source address attached to
|
||||
* the interface of this node based on the given destination
|
||||
* address. The use-case for this function is to find a
|
||||
* suitable address for the source address field of an IPv6
|
||||
* address upon sending. *src* may be empty (all zero) if there
|
||||
* is no suitable address attached to the interface.
|
||||
*
|
||||
* @param[out] src The best source address for this node (may be
|
||||
* all zero if ther is none).
|
||||
* @param[in] dest The destination address for a packet we search
|
||||
* the source address for.
|
||||
*/
|
||||
void ipv6_iface_get_best_src_addr(ipv6_addr_t *src,
|
||||
const ipv6_addr_t *dest);
|
||||
|
||||
/**
|
||||
* @brief Print all addresses attached to the interface to stdout.
|
||||
*/
|
||||
void ipv6_iface_print_addrs(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* SIXLOWPAN_IP_H */
|
||||
273
sys/net/sixlowpan/include/sixlowpan/lowpan.h
Normal file
273
sys/net/sixlowpan/include/sixlowpan/lowpan.h
Normal file
@ -0,0 +1,273 @@
|
||||
/**
|
||||
* sixlowpan/lowpan.h - 6LoWPAN constants, data structs, and
|
||||
* prototypes for 6LoWPAN layer
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file
|
||||
* @brief 6LoWPAN LoWPAN layer header
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
*/
|
||||
|
||||
#ifndef SIXLOWPAN_LOWPAN_H
|
||||
#define SIXLOWPAN_LOWPAN_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "transceiver.h"
|
||||
#include "sixlowpan/types.h"
|
||||
|
||||
/**
|
||||
* @brief 6LoWPAN dispatch value for uncompressed IPv6 packets.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4944#section-5.1">
|
||||
* RFC 4944, section 5.1
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWPAN_IPV6_DISPATCH (0x41)
|
||||
|
||||
/**
|
||||
* @brief 6LoWPAN dispatch value for IPv6 header compression (part of
|
||||
* first byte of LOWPAN_IPHC).
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
|
||||
* RFC 4944, section 3.1.1
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWPAN_IPHC1_DISPATCH (0x60)
|
||||
|
||||
/**
|
||||
* @brief Flag for Flow Label elision (part of first byte of
|
||||
* LOWPAN_IPHC).
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
|
||||
* RFC 6282, section 3.1.1
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWPAN_IPHC1_FL_C (0x10)
|
||||
|
||||
/**
|
||||
* @brief Flag for Traffic Class elision (part of first byte of
|
||||
* LOWPAN_IPHC).
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
|
||||
* RFC 6282, section 3.1.1
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWPAN_IPHC1_TC_C (0x08)
|
||||
|
||||
/**
|
||||
* @brief Flag for Next Header Compression (part of first byte of
|
||||
* LOWPAN_IPHC).
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
|
||||
* RFC 6282, section 3.1.1
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWPAN_IPHC1_NH (0x04)
|
||||
|
||||
/**
|
||||
* @brief Flag for Context Identifier Extention (part of second byte
|
||||
* of LOWPAN_IPHC).
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
|
||||
* RFC 6282, section 3.1.1
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWPAN_IPHC2_CID (0x80)
|
||||
|
||||
/**
|
||||
* @brief Flag for Source Address Compression (part of second byte
|
||||
* of LOWPAN_IPHC).
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
|
||||
* RFC 6282, section 3.1.1
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWPAN_IPHC2_SAC (0x40)
|
||||
|
||||
/**
|
||||
* @brief Bits for Source Address Mode (part of second byte of
|
||||
* LOWPAN_IPHC).
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
|
||||
* RFC 6282, section 3.1.1
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWPAN_IPHC2_SAM (0x30)
|
||||
|
||||
/**
|
||||
* @brief Flag for Destination Address Compression (part of second
|
||||
* byte of LOWPAN_IPHC).
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
|
||||
* RFC 6282, section 3.1.1
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWPAN_IPHC2_DAC (0x04)
|
||||
|
||||
/**
|
||||
* @brief Bits for Destination Address Mode (part of second byte of
|
||||
* LOWPAN_IPHC).
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
|
||||
* RFC 6282, section 3.1.1
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWPAN_IPHC2_DAM (0x03)
|
||||
|
||||
/**
|
||||
* @brief Flag for Multicast Compression (part of second byte of
|
||||
* LOWPAN_IPHC).
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6282#section-3.1.1">
|
||||
* RFC 6282, section 3.1.1
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWPAN_IPHC2_M (0x08)
|
||||
|
||||
|
||||
/**
|
||||
* 6LoWPAN dispatch value for fragmentation header (first fragment)
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4944#section-5.1">
|
||||
* RFC 4944, section 5.1
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWPAN_FRAG1_DISPATCH (0xc0)
|
||||
|
||||
/**
|
||||
* 6LoWPAN dispatch value for fragmentation header (subsequent fragment)
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4944#section-5.1">
|
||||
* RFC 4944, section 5.1
|
||||
* </a>
|
||||
*/
|
||||
#define SIXLOWPAN_FRAGN_DISPATCH (0xe0)
|
||||
|
||||
|
||||
/**
|
||||
* 6LoWPAN fragmentation header length (first fragment)
|
||||
*/
|
||||
#define SIXLOWPAN_FRAG1_HDR_LEN (4)
|
||||
|
||||
/**
|
||||
* 6LoWPAN fragmentation header length (subsequent fragment)
|
||||
*/
|
||||
#define SIXLOWPAN_FRAGN_HDR_LEN (5)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Data type to configure 6LoWPAN IPv6 header compression.
|
||||
*/
|
||||
typedef enum __attribute__((packed))
|
||||
{
|
||||
LOWPAN_IPHC_DISABLE = 0, ///< header compression disabled
|
||||
LOWPAN_IPHC_ENABLE = 1 ///< header compression enabled
|
||||
}
|
||||
sixlowpan_lowpan_iphc_status_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent an 6LoWPAN frame as byte stream.
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t length; ///< length of the byte stream.
|
||||
uint8_t *data; ///< the byte stream representing the 6LoWPAN frame.
|
||||
} sixlowpan_lowpan_frame_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initializes 6LoWPAN.
|
||||
*
|
||||
* @param[in] trans Transceiver to use with 6LoWPAN.
|
||||
* @param[in] r_addr PHY layer address.
|
||||
* @param[in] as_border 1 if node should act as border router,
|
||||
* 0 otherwise.
|
||||
*/
|
||||
void sixlowpan_lowpan_init(transceiver_type_t trans, uint8_t r_addr,
|
||||
int as_border);
|
||||
|
||||
/**
|
||||
* @brief Initializes a 6LoWPAN router with address prefix
|
||||
*
|
||||
* @param[in] trans transceiver to use with 6LoWPAN.
|
||||
* @param[in] prefix the address prefix to advertise.
|
||||
* @param[in] r_addr PHY layer address.
|
||||
*/
|
||||
void sixlowpan_lowpan_adhoc_init(transceiver_type_t trans,
|
||||
const ipv6_addr_t *prefix,
|
||||
uint8_t r_addr);
|
||||
|
||||
/**
|
||||
* @brief Initializes a 6LoWPAN border router with an address
|
||||
*
|
||||
* @note Currently only working with addresses generated from
|
||||
* IEEE 802.15.4 16-bit short addresses.
|
||||
*
|
||||
* @param[in] trans transceiver to use with 6LoWPAN.
|
||||
* @param[in] border_router_addr Address of this border router.
|
||||
*
|
||||
* @return SUCCESS on success, otherwise SIXLOWERROR_ADDRESS if
|
||||
* address was not generated from IEEE 802.15.4 16-bit short
|
||||
* address.
|
||||
*/
|
||||
uint8_t sixlowpan_lowpan_border_init(transceiver_type_t trans,
|
||||
const ipv6_addr_t *border_router_addr);
|
||||
|
||||
/**
|
||||
* @brief Send data via 6LoWPAN to destination node dest.
|
||||
*
|
||||
* @param[in] dest EUI-64 of destination node.
|
||||
* @param[in] data Data to send to destination node (may be
|
||||
* manipulated).
|
||||
* @param[in] data_len Length of data.
|
||||
*/
|
||||
void sixlowpan_lowpan_sendto(const ieee_802154_long_t *dest,
|
||||
uint8_t *data, uint16_t data_len);
|
||||
|
||||
/**
|
||||
* @brief Set header compression status for 6LoWPAN.
|
||||
*
|
||||
* @param[in] status Header compression status to set to.
|
||||
*/
|
||||
void sixlowpan_lowpan_set_iphc_status(
|
||||
sixlowpan_lowpan_iphc_status_t status);
|
||||
|
||||
/**
|
||||
* @brief Initialize 6LoWPAN neighbor discovery (i.e. send
|
||||
* router advertisement with Source Link-Layer Address Option)
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861">
|
||||
* RFC 4861
|
||||
* </a>, <a href="http://tools.ietf.org/html/rfc6775">
|
||||
* RFC 6775
|
||||
* </a>
|
||||
*
|
||||
*/
|
||||
void sixlowpan_lowpan_bootstrapping(void);
|
||||
|
||||
/**
|
||||
* @brief Registers a thread to read received 6LoWPAN frames. The
|
||||
* 6LoWPAN frames are delivered as sixlowpan_lowpan_frame_t
|
||||
* structs.
|
||||
*
|
||||
* @param[in] pid The PID of the receiver thread.
|
||||
*
|
||||
* @return 1 on success, ENOMEM if maximum number of registrable
|
||||
* threads is exceeded.
|
||||
*/
|
||||
uint8_t sixlowpan_lowpan_register(int pid);
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
/**
|
||||
* @brief Print current buffer of assembled (i. e. not fragmented)
|
||||
* 6LoWPAN packages.
|
||||
*/
|
||||
void sixlowpan_lowpan_print_fifo_buffers(void);
|
||||
|
||||
/**
|
||||
* @brief Print current buffer for 6LoWPAN fragmentation reassembly.
|
||||
*/
|
||||
void sixlowpan_lowpan_print_reassembly_buffers(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* SIXLOWPAN_LOWPAN_H */
|
||||
@ -0,0 +1,92 @@
|
||||
/**
|
||||
* sixlowpan/mac.h - 6LoWPAN data structs, and prototypes for MAC layer
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file
|
||||
* @brief 6LoWPAN MAC layer header
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
*/
|
||||
|
||||
#ifndef SIXLOWPAN_MAC_H
|
||||
#define SIXLOWPAN_MAC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "transceiver.h"
|
||||
|
||||
#include "sixlowpan/types.h"
|
||||
|
||||
/**
|
||||
* @brief Gets current radio transmitter address.
|
||||
*
|
||||
* @return Current radio address as 8-bit value.
|
||||
*/
|
||||
uint8_t sixlowpan_mac_get_radio_address(void);
|
||||
|
||||
/**
|
||||
* @brief Sets radio transmitter address.
|
||||
*
|
||||
* @param[in] addr 8-bit radio address.
|
||||
*/
|
||||
void sixlowpan_mac_set_radio_address(uint8_t addr);
|
||||
|
||||
/**
|
||||
* @brief Generates EUI-64 from IEEE 802.15.4 PAN ID and
|
||||
* radio transceiver address.
|
||||
*
|
||||
* @param[out] laddr The EUI-64 address of this node.
|
||||
*/
|
||||
void sixlowpan_mac_init_802154_long_addr(ieee_802154_long_t *laddr);
|
||||
|
||||
/**
|
||||
* @brief Generates IEEE 802.15.4 16-bit short address from radio
|
||||
* transceiver address.
|
||||
*
|
||||
* @param[out] saddr The IEEE 802.15.4 16-bit short address of this
|
||||
* node.
|
||||
*/
|
||||
void sixlowpan_mac_init_802154_short_addr(ieee_802154_short_t *saddr);
|
||||
|
||||
/**
|
||||
* @brief Get pointer to potential EUI-64 bit of the IPv6 address.
|
||||
*
|
||||
* @param[in] ipaddr An IPv6 address of this node.
|
||||
*
|
||||
* @return The EUI-64 address of this node.
|
||||
*/
|
||||
ieee_802154_long_t *sixlowpan_mac_get_eui64(const ipv6_addr_t *ipaddr);
|
||||
|
||||
/**
|
||||
* @brief Send an IEEE 802.15.4 frame.
|
||||
*
|
||||
* @param[in] addr The destination address of the frame.
|
||||
* @param[in] payload The payload of the frame.
|
||||
* @param[in] length The length of the payload.
|
||||
* @param[in] mcast send frame as multicast frame (identical to
|
||||
* give a destination address of 0).
|
||||
*/
|
||||
void sixlowpan_mac_send_ieee802154_frame(const ieee_802154_long_t *addr,
|
||||
const uint8_t *payload,
|
||||
uint8_t length, uint8_t mcast);
|
||||
|
||||
/**
|
||||
* @brief Initialise 6LoWPAN MAC interface
|
||||
*
|
||||
* @param[in] type Type of transceiver.
|
||||
*/
|
||||
void sixlowpan_mac_init(transceiver_type_t type);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* SIXLOWPAN_MAC_H */
|
||||
129
sys/net/sixlowpan/include/sixlowpan/ndp.h
Normal file
129
sys/net/sixlowpan/include/sixlowpan/ndp.h
Normal file
@ -0,0 +1,129 @@
|
||||
/**
|
||||
* sixlowpan/ndp.h - 6LoWPAN constants, data structs, and prototypes
|
||||
* related to NDP
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file
|
||||
* @brief 6LoWPAN NDP related header
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
*/
|
||||
|
||||
#ifndef SIXLOWPAN_NDP_H
|
||||
#define SIXLOWPAN_NDP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "timex.h"
|
||||
#include "sixlowpan/types.h"
|
||||
|
||||
#define NDP_6LOWPAN_CONTEXT_MAX (16)
|
||||
|
||||
#define NDP_OPT_SLLAO_TYPE (1)
|
||||
#define NDP_OPT_TLLAO_TYPE (2)
|
||||
#define NDP_OPT_PI_VLIFETIME_INFINITE (0xffffffff)
|
||||
#define NDP_OPT_ARO_STATE_SUCCESS (0)
|
||||
#define NDP_OPT_ARO_STATE_DUP_ADDR (1)
|
||||
#define NDP_OPT_ARO_STATE_NBR_CACHE_FULL (2)
|
||||
|
||||
/**
|
||||
* @brief Neighbor cache entry state according to
|
||||
* <a href="http://tools.ietf.org/html/rfc4861#section-7.3.2">
|
||||
* RFC 4861, section 7.3.2
|
||||
* </a>.
|
||||
*/
|
||||
typedef enum __attribute__((packed)) {
|
||||
NDP_NCE_STATUS_INCOMPLETE,
|
||||
NDP_NCE_STATUS_REACHABLE,
|
||||
NDP_NCE_STATUS_STALE,
|
||||
NDP_NCE_STATUS_DELAY,
|
||||
NDP_NCE_STATUS_PROBE,
|
||||
} ndp_nce_state_t;
|
||||
|
||||
/**
|
||||
* @brief Neighbor cache entry type according to
|
||||
* <a href="http://tools.ietf.org/html/rfc6775#section-3.5">
|
||||
* RFC 6775, section 3.5
|
||||
* </a>.
|
||||
*/
|
||||
typedef enum __attribute__((packed)) {
|
||||
NDP_NCE_TYPE_GC = 1, ///< Garbage-collectible.
|
||||
NDP_NCE_TYPE_REGISTERED, ///< Registered.
|
||||
NDP_NCE_TYPE_TENTATIVE ///< Tentetive.
|
||||
} ndp_nce_type_t;
|
||||
|
||||
/**
|
||||
* @brief Prefix list type to store information spread by prefix
|
||||
* information option.
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t inuse; ///< Prefix is in in use.
|
||||
uint8_t adv;
|
||||
ipv6_addr_t addr; ///< The Prefix.
|
||||
uint8_t length; ///< Length of the prefix.
|
||||
uint8_t l_a_reserved1; ///< L and A flag of prefix information option
|
||||
uint32_t val_ltime; ///< valid lifetime
|
||||
uint32_t pref_ltime; ///< preferred lifetime
|
||||
uint8_t infinite; ///< flag to set to infinite lifetime
|
||||
} ndp_prefix_list_t;
|
||||
|
||||
/**
|
||||
* @brief Default router list to store information spread by
|
||||
* router advertisement.
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
ipv6_addr_t addr; ///< Address of router.
|
||||
timex_t inval_time; ///< remaining time until this entry is
|
||||
///< invalid.
|
||||
} ndp_default_router_list_t;
|
||||
|
||||
/**
|
||||
* @brief Neighbor cache as defined in
|
||||
* <a href="http://tools.ietf.org/html/rfc4861#section-3.5#section-5.1">
|
||||
* RFC 4861, section 5.1
|
||||
* </a>.
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
ndp_nce_type_t type; ///< Type of neighbor cache entry.
|
||||
ndp_nce_state_t state; ///< State of neighbor cache entry.
|
||||
uint8_t isrouter; ///< Flag to signify that this neighbor
|
||||
///< is a router.
|
||||
ipv6_addr_t addr; ///< IPv6 address of the neighbor.
|
||||
ieee_802154_long_t laddr; ///< EUI-64 of neighbor
|
||||
ieee_802154_short_t saddr; ///< IEEE 802.15.4 16-bit short address
|
||||
///< of neighbor.
|
||||
timex_t ltime; ///< lifetime of entry.
|
||||
} ndp_neighbor_cache_t;
|
||||
|
||||
/**
|
||||
* @brief Authoritive border router cache as defined in
|
||||
* <a href="http://tools.ietf.org/html/rfc6775">
|
||||
* RFC 6775
|
||||
* </a>.
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint16_t version; ///< version of entry.
|
||||
ipv6_addr_t abr_addr; ///< Addres of ABR.
|
||||
uint8_t cids[NDP_6LOWPAN_CONTEXT_MAX]; ///< context IDs.
|
||||
} ndp_a6br_cache_t;
|
||||
|
||||
ndp_default_router_list_t *ndp_default_router_list_search(ipv6_addr_t *ipaddr);
|
||||
ndp_neighbor_cache_t *ndp_neighbor_cache_search(ipv6_addr_t *ipaddr);
|
||||
/*TODO: to implement*/
|
||||
uint8_t ndp_prefix_list_search(ipv6_addr_t *addr);
|
||||
ndp_a6br_cache_t *ndp_a6br_cache_get_most_current(void);
|
||||
ndp_a6br_cache_t *ndp_a6br_cache_get_oldest(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* SIXLOWPAN_NDP_H */
|
||||
404
sys/net/sixlowpan/include/sixlowpan/types.h
Normal file
404
sys/net/sixlowpan/include/sixlowpan/types.h
Normal file
@ -0,0 +1,404 @@
|
||||
/**
|
||||
* 6LoWPAN data types
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowpan/types.h
|
||||
* @brief 6LoWPAN data types
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
*/
|
||||
|
||||
#ifndef SIXLOWPAN_TYPES_H
|
||||
#define SIXLOWPAN_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Data type to represent an EUI-64.
|
||||
*/
|
||||
typedef union __attribute__((packed)) {
|
||||
uint8_t uint8[8]; ///< devided by 8 8-bit words.
|
||||
uint16_t uint16[4]; ///< devided by 4 16-bit words.
|
||||
} ieee_802154_long_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent IEEE 802.15.4 short address.
|
||||
*/
|
||||
typedef union __attribute__((packed)) {
|
||||
uint8_t uint8[2]; ///< devided by 2 8-bit words.
|
||||
uint16_t uint16[1]; ///< as a 16-bit value.
|
||||
} ieee_802154_short_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent an IPv6 address.
|
||||
*/
|
||||
typedef union __attribute__((packed)) {
|
||||
uint8_t uint8[16]; ///< devided by 16 8-bit words.
|
||||
uint16_t uint16[8]; ///< devided by 8 16-bit words.
|
||||
uint32_t uint32[4]; ///< devided by 4 32-bit words.
|
||||
} ipv6_addr_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent IPv6 address types.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4291">
|
||||
* RFC 4291
|
||||
* </a>
|
||||
*/
|
||||
typedef enum __attribute__((packed))
|
||||
{
|
||||
IPV6_ADDR_TYPE_NONE, ///< address has no type/is invalid.
|
||||
IPV6_ADDR_TYPE_UNICAST, ///< address is an unicast address.
|
||||
IPV6_ADDR_TYPE_MULTICAST, ///< address is a multicast address.
|
||||
IPV6_ADDR_TYPE_ANYCAST, ///< address is an anycast address.
|
||||
IPV6_ADDR_TYPE_SOLICITED_NODE, ///< address is a solicitated node
|
||||
///< multicast address.
|
||||
IPV6_ADDR_TYPE_LOOPBACK, ///< address is a loopback address.
|
||||
IPV6_ADDR_TYPE_LINK_LOCAL, ///< address is a link-local address.
|
||||
IPV6_ADDR_TYPE_GLOBAL ///< address is a global address.
|
||||
}
|
||||
ipv6_addr_type_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent an IPv6 packet header
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc2460">
|
||||
* RFC 2460
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t version_trafficclass; ///< Version field + first 4 bit of Traffic Class.
|
||||
uint8_t trafficclass_flowlabel; ///< last 4 bit of Traffic Class
|
||||
///< and first 4 bit of Flow Label.
|
||||
uint16_t flowlabel; ///< last 16 bit of Flow Label.
|
||||
uint16_t length; ///< payload length of this packet.
|
||||
uint8_t nextheader; ///< type of next header in this packet.
|
||||
uint8_t hoplimit; ///< hop limit for this packet.
|
||||
ipv6_addr_t srcaddr; ///< source address of this packet.
|
||||
ipv6_addr_t destaddr; ///< destination address of this packet.
|
||||
} ipv6_hdr_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent an ICMPv6 packet header.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4443">
|
||||
* RFC 4443
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type; ///< type field.
|
||||
uint8_t code; ///< code field.
|
||||
uint16_t checksum; ///< checksum field.
|
||||
} icmpv6_hdr_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent the relevant sub-part of an
|
||||
* ICMPv6 Parameter Problem Message.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4443#section-3.4">
|
||||
* RFC 4443, section 3.4
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t pointer;
|
||||
} icmpv6_parameter_prob_hdr_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent the relevant sub-part of an
|
||||
* ICMPv6 Echo Request.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4443#section-4.1">
|
||||
* RFC 4443, section 4.1
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint16_t id; ///< identifier field.
|
||||
uint16_t seq; ///< sequence number field.
|
||||
} icmpv6_echo_request_hdr_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent the relevant sub-part of an
|
||||
* ICMPv6 Echo Reply.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4443#section-4.2">
|
||||
* RFC 4443, section 4.2
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint16_t id; ///< identifier field.
|
||||
uint16_t seq; ///< sequence number field.
|
||||
} icmpv6_echo_reply_hdr_t;
|
||||
|
||||
/*
|
||||
* ICMPv6 Router Solicitation has no fields but reserved fields
|
||||
* and is thus elided.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Data type to represent the relevant sub-part of an
|
||||
* ICMPv6 Router Advertisement.
|
||||
*
|
||||
* @see ICMPV6_ROUTER_ADV_FLAG_MANAGED
|
||||
* @see ICMPV6_ROUTER_ADV_FLAG_OTHER
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.2">
|
||||
* RFC 4861, section 4.2
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t hoplimit; ///< hop limit field.
|
||||
uint8_t autoconfig_flags; ///< (M)anaged and (Other) flag.
|
||||
uint16_t router_lifetime; ///< router lifetime field.
|
||||
uint32_t reachable_time; ///< reachable time field.
|
||||
uint32_t retrans_timer; ///< retrans timer field.
|
||||
} icmpv6_router_adv_hdr_t;
|
||||
|
||||
/**
|
||||
* @brief Bit for (M)anaged flag in Router Advertisement
|
||||
* @see icmpv6_router_adv_hdr_t
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.2">
|
||||
* RFC 4861, section 4.2
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_ROUTER_ADV_FLAG_MANAGED (0x80)
|
||||
|
||||
/**
|
||||
* @brief Bit for (O)ther flag in Router Advertisement
|
||||
* @see icmpv6_router_adv_hdr_t
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.2">
|
||||
* RFC 4861, section 4.2
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_ROUTER_ADV_FLAG_OTHER (0x40)
|
||||
|
||||
/**
|
||||
* @brief Data type to represent the relevant sub-part of an
|
||||
* ICMPv6 Neighbor Solicitation.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.3">
|
||||
* RFC 4861, section 4.3
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t reserved; ///< reserved field.
|
||||
ipv6_addr_t target_addr; ///< target address field.
|
||||
} icmpv6_neighbor_sol_hdr_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent the relevant sub-part of an
|
||||
* ICMPv6 Neighbor Solicitation.
|
||||
*
|
||||
* @see ICMPV6_NEIGHBOR_ADV_FLAG_ROUTER
|
||||
* @see ICMPV6_NEIGHBOR_ADV_FLAG_SOLICITED
|
||||
* @see ICMPV6_NEIGHBOR_ADV_FLAG_OVERRIDE
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.4">
|
||||
* RFC 4861, section 4.4
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t rso; ///< flags + first 5 bits of reserved field.
|
||||
uint8_t reserved[3]; ///< rest of reserved field.
|
||||
ipv6_addr_t target_addr; ///< target address field.
|
||||
} icmpv6_neighbor_adv_hdr_t;
|
||||
|
||||
/**
|
||||
* @brief Bit for (R)outer flag in Neighbor Advertisement
|
||||
* @see icmpv6_neighbor_adv_hdr_t
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.4">
|
||||
* RFC 4861, section 4.4
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_NEIGHBOR_ADV_FLAG_ROUTER (0x80)
|
||||
|
||||
/**
|
||||
* @brief Bit for (S)olicited flag in Neighbor Advertisement
|
||||
* @see icmpv6_neighbor_adv_hdr_t
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.4">
|
||||
* RFC 4861, section 4.4
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_NEIGHBOR_ADV_FLAG_SOLICITED (0x40)
|
||||
|
||||
/**
|
||||
* @brief Bit for (O)verride flag in Neighbor Advertisement
|
||||
* @see icmpv6_neighbor_adv_hdr_t
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.4">
|
||||
* RFC 4861, section 4.4
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_NEIGHBOR_ADV_FLAG_OVERRIDE (0x20)
|
||||
|
||||
/**
|
||||
* @brief Data type to represent an IPv6 Neighbor Discover Option
|
||||
* header.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.6">
|
||||
* RFC 4861, section 4.6
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type; ///< type field.
|
||||
uint8_t length; ///< length field.
|
||||
} icmpv6_ndp_opt_hdr_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent a Source/Target Link-layer Option
|
||||
* Address option. Link-layer address may be added in payload.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.6.1">
|
||||
* RFC 4861, section 4.6.1
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type; ///< type field.
|
||||
uint8_t length; ///< length field.
|
||||
} icmpv6_ndp_opt_stllao_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent a Prefix Information option.
|
||||
*
|
||||
* @see ICMPV6_NDP_OPT_PI_FLAG_ON_LINK
|
||||
* @see ICMPV6_NDP_OPT_PI_FLAG_AUTONOM
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.6.2">
|
||||
* RFC 4861, section 4.6.2
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type; ///< type field.
|
||||
uint8_t length; ///< length field.
|
||||
uint8_t prefix_length; ///< prefix length field.
|
||||
uint8_t l_a_reserved1; ///< flags + reserved1 field.
|
||||
uint32_t val_ltime; ///< valid lifetime field.
|
||||
uint32_t pref_ltime; ///< preferred lifetime field.
|
||||
uint32_t reserved2; ///< reserved2 field.
|
||||
ipv6_addr_t addr; ///< prefix field.
|
||||
} icmpv6_ndp_opt_pi_t;
|
||||
|
||||
/**
|
||||
* @brief Bit for on-(L)ink flag in Prefix Information option.
|
||||
* @see icmpv6_ndp_opt_pi_t
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.6.2">
|
||||
* RFC 4861, section 4.6.2
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_NDP_OPT_PI_FLAG_ON_LINK (0x80)
|
||||
|
||||
/**
|
||||
* @brief Bit for (A)utonoums address-configuration flag in Prefix
|
||||
* Information option.
|
||||
* @see icmpv6_ndp_opt_pi_t
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.6.2">
|
||||
* RFC 4861, section 4.6.2
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_NDP_OPT_PI_FLAG_AUTONOM (0x40)
|
||||
|
||||
/**
|
||||
* @brief Data type to represent a MTU option.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.6.4">
|
||||
* RFC 4861, section 4.6.4
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type; ///< type field.
|
||||
uint8_t length; ///< length field.
|
||||
uint16_t reserved; ///< reserved field.
|
||||
uint32_t mtu; ///< MTU field.
|
||||
} icmpv6_ndp_opt_mtu_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent an Address Registration Option.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6775#section-4.1">
|
||||
* RFC 6775, section 4.1
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type; ///< type field.
|
||||
uint8_t length; ///< length field.
|
||||
uint8_t status; ///< status field.
|
||||
uint8_t reserved1; ///< reserved1 field.
|
||||
uint16_t reserved2; ///< reserved2 field.
|
||||
uint16_t reg_ltime; ///< registration lifetem field.
|
||||
ieee_802154_long_t eui64; ///< EUI-64 field.
|
||||
} icmpv6_ndp_opt_aro_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent an 6LoWPAN Context Option.
|
||||
*
|
||||
* @see ICMPV6_NDP_OPT_6CO_FLAG_CCOMPR
|
||||
* @see ICMPV6_NDP_OPT_6CO_FLAG_CID
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6775#section-4.2">
|
||||
* RFC 6775, section 4.2
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type; ///< type field.
|
||||
uint8_t length; ///< length field.
|
||||
uint8_t c_length; ///< context length field.
|
||||
uint8_t c_flags; ///< Res(erved) field + C flag + CID field.
|
||||
uint16_t reserved; ///< reserved field.
|
||||
uint16_t val_ltime; ///< valid lifetime field.
|
||||
} icmpv6_ndp_opt_6co_hdr_t;
|
||||
|
||||
/**
|
||||
* @brief Bit for context (C)ompression flag in 6LoWPAN Context
|
||||
* Option.
|
||||
* @see icmpv6_ndp_opt_6co_hdr_t
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6775#section-4.2">
|
||||
* RFC 6775, section 4.2
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_NDP_OPT_6CO_FLAG_CCOMPR (0x10)
|
||||
|
||||
/**
|
||||
* @brief Bitmask for Context Identifier in 6LoWPAN Context Option.
|
||||
* @see icmpv6_ndp_opt_6co_hdr_t
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6775#section-4.2">
|
||||
* RFC 6775, section 4.2
|
||||
* </a>
|
||||
*/
|
||||
#define ICMPV6_NDP_OPT_6CO_FLAG_CID (0x0F)
|
||||
|
||||
/**
|
||||
* @brief Data type to represent an Authoritative Border Router Option.
|
||||
* @note TODO not according to RFC.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6775#section-4.3">
|
||||
* RFC 6775, section 4.3
|
||||
* </a>
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type; ///< type field.
|
||||
uint8_t length; ///< length field.
|
||||
uint16_t version; ///< version field.
|
||||
uint32_t reserved; ///< reseverd field.
|
||||
ipv6_addr_t addr; ///< 6LBR address field.
|
||||
} icmpv6_ndp_opt_abro_t;
|
||||
|
||||
/**
|
||||
* @brief Data type to represent address types according to
|
||||
* <a href="http://tools.ietf.org/hmtl/rfc4862">RFC 4862</a>.
|
||||
*/
|
||||
typedef enum __attribute__((packed))
|
||||
{
|
||||
NDP_ADDR_STATE_TENTATIVE, ///< tentative address, uniqueness to be verified.
|
||||
NDP_ADDR_STATE_PREFERRED, ///< preferred address, for unrestricted use.
|
||||
NDP_ADDR_STATE_DEPRECATED, ///< deprecated address, use discouraged.
|
||||
NDP_ADDR_STATE_ANY ///< addresses of this state are always permitted.
|
||||
}
|
||||
ndp_addr_state_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* SIXLOWPAN_TYPES_H */
|
||||
671
sys/net/sixlowpan/ip.c
Normal file
671
sys/net/sixlowpan/ip.c
Normal file
@ -0,0 +1,671 @@
|
||||
/**
|
||||
* IPv6 implementation
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowip.c
|
||||
* @brief 6lowpan IP layer functions
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "vtimer.h"
|
||||
#include "mutex.h"
|
||||
#include "msg.h"
|
||||
#include "sixlowpan/mac.h"
|
||||
|
||||
#include "ip.h"
|
||||
#include "icmp.h"
|
||||
#include "lowpan.h"
|
||||
|
||||
#include "sys/net/destiny/socket.h"
|
||||
#include "sys/net/net_help/net_help.h"
|
||||
#include "sys/net/net_help/msg_help.h"
|
||||
|
||||
#define IP_PKT_RECV_BUF_SIZE (64)
|
||||
#define LLHDR_IPV6HDR_LEN (LL_HDR_LEN + IPV6_HDR_LEN)
|
||||
|
||||
uint8_t ip_send_buffer[BUFFER_SIZE];
|
||||
uint8_t buffer[BUFFER_SIZE];
|
||||
msg_t msg_queue[IP_PKT_RECV_BUF_SIZE];
|
||||
ipv6_hdr_t *ipv6_buf;
|
||||
icmpv6_hdr_t *icmp_buf;
|
||||
uint8_t *nextheader;
|
||||
|
||||
uint8_t iface_addr_list_count = 0;
|
||||
int udp_packet_handler_pid = 0;
|
||||
int tcp_packet_handler_pid = 0;
|
||||
int rpl_process_pid = 0;
|
||||
|
||||
/* registered upper layer threads */
|
||||
int sixlowip_reg[SIXLOWIP_MAX_REGISTERED];
|
||||
|
||||
void ipv6_send_bytes(ipv6_hdr_t *bytes)
|
||||
{
|
||||
uint16_t offset = IPV6_HDR_LEN + HTONS(bytes->length);
|
||||
|
||||
bytes->flowlabel = HTONS(bytes->flowlabel);
|
||||
bytes->length = HTONS(bytes->length);
|
||||
|
||||
memset(bytes, 0, BUFFER_SIZE);
|
||||
memcpy(bytes + LL_HDR_LEN, bytes, offset);
|
||||
|
||||
sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(bytes->destaddr.uint16[4]),
|
||||
(uint8_t *)bytes,
|
||||
offset);
|
||||
}
|
||||
|
||||
ipv6_hdr_t *ipv6_get_buf_send(void)
|
||||
{
|
||||
return ((ipv6_hdr_t *) &(ip_send_buffer[LL_HDR_LEN]));
|
||||
}
|
||||
|
||||
uint8_t *get_payload_buf_send(uint8_t ext_len)
|
||||
{
|
||||
return &(ip_send_buffer[LLHDR_IPV6HDR_LEN + ext_len]);
|
||||
}
|
||||
|
||||
ipv6_hdr_t *ipv6_get_buf(void)
|
||||
{
|
||||
return ((ipv6_hdr_t *) &(buffer[LL_HDR_LEN]));
|
||||
}
|
||||
|
||||
icmpv6_hdr_t *get_icmpv6_buf(uint8_t ext_len)
|
||||
{
|
||||
return ((icmpv6_hdr_t *) &(buffer[LLHDR_IPV6HDR_LEN + ext_len]));
|
||||
}
|
||||
|
||||
uint8_t *get_payload_buf(uint8_t ext_len)
|
||||
{
|
||||
return &(buffer[LLHDR_IPV6HDR_LEN + ext_len]);
|
||||
}
|
||||
|
||||
void ipv6_sendto(const ipv6_addr_t *dest, uint8_t next_header,
|
||||
const uint8_t *payload, uint16_t payload_length)
|
||||
{
|
||||
uint8_t *p_ptr;
|
||||
uint16_t packet_length;
|
||||
|
||||
if (next_header == IPV6_PROTO_NUM_TCP) {
|
||||
p_ptr = get_payload_buf_send(ipv6_ext_hdr_len);
|
||||
ipv6_buf = ipv6_get_buf_send();
|
||||
}
|
||||
else {
|
||||
ipv6_buf = ipv6_get_buf();
|
||||
p_ptr = get_payload_buf(ipv6_ext_hdr_len);
|
||||
}
|
||||
|
||||
ipv6_buf->version_trafficclass = IPV6_VER;
|
||||
ipv6_buf->trafficclass_flowlabel = 0;
|
||||
ipv6_buf->flowlabel = 0;
|
||||
ipv6_buf->nextheader = next_header;
|
||||
ipv6_buf->hoplimit = MULTIHOP_HOPLIMIT;
|
||||
ipv6_buf->length = payload_length;
|
||||
|
||||
memcpy(&(ipv6_buf->destaddr), dest, 16);
|
||||
ipv6_iface_get_best_src_addr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr));
|
||||
|
||||
memcpy(p_ptr, payload, payload_length);
|
||||
|
||||
packet_length = IPV6_HDR_LEN + payload_length;
|
||||
|
||||
sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(ipv6_buf->destaddr.uint16[4]),
|
||||
(uint8_t *)ipv6_buf, packet_length);
|
||||
}
|
||||
|
||||
/* Register an upper layer thread */
|
||||
uint8_t ipv6_register_packet_handler(int pid)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; ((sixlowip_reg[i] != pid) && (i < SIXLOWIP_MAX_REGISTERED) &&
|
||||
(sixlowip_reg[i] != 0)); i++) {
|
||||
;
|
||||
}
|
||||
|
||||
if (i >= SIXLOWIP_MAX_REGISTERED) {
|
||||
return ENOMEM;
|
||||
}
|
||||
else {
|
||||
sixlowip_reg[i] = pid;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int icmpv6_demultiplex(const icmpv6_hdr_t *hdr)
|
||||
{
|
||||
switch (hdr->type) {
|
||||
case (ICMPV6_TYPE_ECHO_REQUEST): {
|
||||
puts("INFO: packet type: icmp echo request");
|
||||
/* processing echo request */
|
||||
recv_echo_req();
|
||||
break;
|
||||
}
|
||||
|
||||
case (ICMPV6_TYPE_ECHO_REPLY): {
|
||||
puts("INFO: packet type: icmp echo reply");
|
||||
/* processing echo reply */
|
||||
recv_echo_repl();
|
||||
break;
|
||||
}
|
||||
|
||||
case (ICMPV6_TYPE_ROUTER_SOL): {
|
||||
puts("INFO: packet type: icmp router solicitation");
|
||||
/* processing router solicitation */
|
||||
recv_rtr_sol();
|
||||
/* init solicited router advertisment*/
|
||||
break;
|
||||
}
|
||||
|
||||
case (ICMPV6_TYPE_ROUTER_ADV): {
|
||||
puts("INFO: packet type: icmp router advertisment");
|
||||
/* processing router advertisment */
|
||||
recv_rtr_adv();
|
||||
/* init neighbor solicitation */
|
||||
break;
|
||||
}
|
||||
|
||||
case (ICMPV6_TYPE_NEIGHBOR_SOL): {
|
||||
puts("INFO: packet type: icmp neighbor solicitation");
|
||||
recv_nbr_sol();
|
||||
break;
|
||||
}
|
||||
|
||||
case (ICMPV6_TYPE_NEIGHBOR_ADV): {
|
||||
puts("INFO: packet type: icmp neighbor advertisment");
|
||||
recv_nbr_adv();
|
||||
break;
|
||||
}
|
||||
|
||||
case (ICMPV6_TYPE_RPL_CONTROL): {
|
||||
puts("INFO: packet type: RPL message");
|
||||
|
||||
if (rpl_process_pid != 0) {
|
||||
msg_t m_send;
|
||||
m_send.content.ptr = (char *) &hdr->code;
|
||||
msg_send(&m_send, rpl_process_pid, 1);
|
||||
}
|
||||
else {
|
||||
puts("INFO: no RPL handler registered");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ipv6_get_addr_match(const ipv6_addr_t *src,
|
||||
const ipv6_addr_t *dst)
|
||||
{
|
||||
uint8_t val = 0, xor;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
/* if bytes are equal add 8 */
|
||||
if (src->uint8[i] == dst->uint8[i]) {
|
||||
val += 8;
|
||||
}
|
||||
else {
|
||||
xor = src->uint8[i] ^ dst->uint8[i];
|
||||
|
||||
/* while bits from byte equal add 1 */
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if ((xor & 0x80) == 0) {
|
||||
val++;
|
||||
xor = xor << 1;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void ipv6_process(void)
|
||||
{
|
||||
msg_t m_recv_lowpan, m_send_lowpan;
|
||||
msg_t m_recv, m_send;
|
||||
ipv6_addr_t myaddr;
|
||||
uint8_t i;
|
||||
uint16_t packet_length;
|
||||
|
||||
ipv6_addr_init(&myaddr, 0xabcd, 0x0, 0x0, 0x0, 0x3612, 0x00ff, 0xfe00,
|
||||
sixlowpan_mac_get_radio_address());
|
||||
|
||||
while (1) {
|
||||
msg_receive(&m_recv_lowpan);
|
||||
|
||||
ipv6_buf = (ipv6_hdr_t *)m_recv_lowpan.content.ptr;
|
||||
|
||||
/* identifiy packet */
|
||||
nextheader = &ipv6_buf->nextheader;
|
||||
|
||||
if ((ipv6_get_addr_match(&myaddr, &ipv6_buf->destaddr) >= 112) &&
|
||||
(ipv6_buf->destaddr.uint8[15] != myaddr.uint8[15])) {
|
||||
packet_length = IPV6_HDR_LEN + ipv6_buf->length;
|
||||
memcpy(ipv6_get_buf_send(), ipv6_get_buf(), packet_length);
|
||||
sixlowpan_lowpan_sendto((ieee_802154_long_t *) &(ipv6_buf->destaddr.uint16[4]),
|
||||
(uint8_t *)ipv6_get_buf_send(),
|
||||
packet_length);
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < SIXLOWIP_MAX_REGISTERED; i++) {
|
||||
if (sixlowip_reg[i]) {
|
||||
msg_t m_send;
|
||||
m_send.content.ptr = (char *) &ipv6_buf;
|
||||
msg_send(&m_send, sixlowip_reg[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
switch (*nextheader) {
|
||||
case (IPV6_PROTO_NUM_ICMPV6): {
|
||||
/* checksum test*/
|
||||
if (icmpv6_csum(IPV6_PROTO_NUM_ICMPV6) != 0xffff) {
|
||||
printf("ERROR: wrong checksum\n");
|
||||
}
|
||||
|
||||
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
|
||||
icmpv6_demultiplex(icmp_buf);
|
||||
break;
|
||||
}
|
||||
|
||||
case (IPV6_PROTO_NUM_TCP): {
|
||||
if (tcp_packet_handler_pid != 0) {
|
||||
m_send.content.ptr = (char *) ipv6_buf;
|
||||
msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid);
|
||||
}
|
||||
else {
|
||||
printf("INFO: No TCP handler registered.\n");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case (IPV6_PROTO_NUM_UDP): {
|
||||
if (udp_packet_handler_pid != 0) {
|
||||
m_send.content.ptr = (char *) ipv6_buf;
|
||||
msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid);
|
||||
}
|
||||
else {
|
||||
printf("INFO: No UDP handler registered.\n");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case (IPV6_PROTO_NUM_NONE): {
|
||||
printf("INFO: Packet with no Header following the IPv6 Header received.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
msg_reply(&m_recv_lowpan, &m_send_lowpan);
|
||||
}
|
||||
}
|
||||
|
||||
void ipv6_iface_add_addr(const ipv6_addr_t *addr, ipv6_addr_type_t type,
|
||||
ndp_addr_state_t state, uint32_t val_ltime,
|
||||
uint32_t pref_ltime)
|
||||
{
|
||||
if (ipv6_addr_is_unspecified(addr) == 128) {
|
||||
printf("ERROR: unspecified address (::) can't be assigned to interface.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ipv6_iface_addr_match(addr) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (iface_addr_list_count < IFACE_ADDR_LIST_LEN) {
|
||||
memcpy(&(iface.addr_list[iface_addr_list_count].addr.uint8[0]),
|
||||
&(addr->uint8[0]), 16);
|
||||
iface.addr_list[iface_addr_list_count].state = state;
|
||||
timex_t valtime = {val_ltime, 0};
|
||||
timex_t preftime = {pref_ltime, 0};
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
iface.addr_list[iface_addr_list_count].val_ltime = timex_add(now, valtime);
|
||||
iface.addr_list[iface_addr_list_count].pref_ltime = timex_add(now, preftime);
|
||||
iface.addr_list[iface_addr_list_count].type = type;
|
||||
iface_addr_list_count++;
|
||||
|
||||
/* Register to Solicited-Node multicast address according to RFC 4291 */
|
||||
if (type == IPV6_ADDR_TYPE_ANYCAST || type == IPV6_ADDR_TYPE_LINK_LOCAL ||
|
||||
type == IPV6_ADDR_TYPE_GLOBAL || type == IPV6_ADDR_TYPE_UNICAST) {
|
||||
ipv6_addr_t sol_node_mcast_addr;
|
||||
ipv6_addr_set_solicited_node_addr(&sol_node_mcast_addr, addr);
|
||||
|
||||
if (ipv6_iface_addr_match(&sol_node_mcast_addr) == NULL) {
|
||||
ipv6_iface_add_addr(&sol_node_mcast_addr,
|
||||
IPV6_ADDR_TYPE_SOLICITED_NODE,
|
||||
state, val_ltime, pref_ltime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addr_list_t *ipv6_iface_addr_match(const ipv6_addr_t *addr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < iface_addr_list_count; i++) {
|
||||
if (memcmp(&(iface.addr_list[i].addr.uint8[0]),
|
||||
&(addr->uint8[0]), 16) == 0) {
|
||||
return &(iface.addr_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
addr_list_t *ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < iface_addr_list_count; i++) {
|
||||
if (memcmp(&(iface.addr_list[i].addr.uint8[0]),
|
||||
&(addr->uint8[0]), 8) == 0) {
|
||||
return &(iface.addr_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ipv6_iface_print_addrs(void)
|
||||
{
|
||||
for (int i = 0; i < iface_addr_list_count; i++) {
|
||||
char addr_str[IPV6_MAX_ADDR_STR_LEN];
|
||||
printf("%s\n", ipv6_addr_to_str(addr_str,
|
||||
&(iface.addr_list[i].addr)));
|
||||
}
|
||||
}
|
||||
|
||||
void ipv6_addr_set_by_eui64(ipv6_addr_t *out, const ipv6_addr_t *prefix)
|
||||
{
|
||||
out->uint16[0] = prefix->uint16[0];
|
||||
out->uint16[1] = prefix->uint16[1];
|
||||
out->uint16[2] = prefix->uint16[2];
|
||||
out->uint16[3] = prefix->uint16[3];
|
||||
|
||||
memcpy(&(out->uint8[8]), &(iface.laddr.uint8[0]), 8);
|
||||
}
|
||||
|
||||
void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix,
|
||||
uint8_t bits)
|
||||
{
|
||||
if (bits > 128) {
|
||||
bits = 128;
|
||||
}
|
||||
|
||||
uint8_t bytes = bits / 8, mask;
|
||||
|
||||
if (bits % 8) {
|
||||
mask = 0xff << (bits - (bytes * 8));
|
||||
}
|
||||
else {
|
||||
mask = 0x00;
|
||||
}
|
||||
|
||||
bytes++;
|
||||
memset(out, 0, 16);
|
||||
memcpy(out, prefix, bytes);
|
||||
out->uint8[bytes] = prefix->uint8[bytes] & mask;
|
||||
}
|
||||
|
||||
void ipv6_addr_set_all_routers_addr(ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
ipv6_addr->uint16[0] = HTONS(0xff02);
|
||||
ipv6_addr->uint16[1] = 0;
|
||||
ipv6_addr->uint16[2] = 0;
|
||||
ipv6_addr->uint16[3] = 0;
|
||||
ipv6_addr->uint16[4] = 0;
|
||||
ipv6_addr->uint16[5] = 0;
|
||||
ipv6_addr->uint16[6] = 0;
|
||||
ipv6_addr->uint16[7] = HTONS(0x0002);
|
||||
}
|
||||
|
||||
void ipv6_addr_set_all_nodes_addr(ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
ipv6_addr->uint16[0] = HTONS(0xff02);
|
||||
ipv6_addr->uint16[1] = 0;
|
||||
ipv6_addr->uint16[2] = 0;
|
||||
ipv6_addr->uint16[3] = 0;
|
||||
ipv6_addr->uint16[4] = 0;
|
||||
ipv6_addr->uint16[5] = 0;
|
||||
ipv6_addr->uint16[6] = 0;
|
||||
ipv6_addr->uint16[7] = HTONS(0x0001);
|
||||
}
|
||||
|
||||
void ipv6_addr_set_loopback_addr(ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
ipv6_addr->uint16[0] = 0;
|
||||
ipv6_addr->uint16[1] = 0;
|
||||
ipv6_addr->uint16[2] = 0;
|
||||
ipv6_addr->uint16[3] = 0;
|
||||
ipv6_addr->uint16[4] = 0;
|
||||
ipv6_addr->uint16[5] = 0;
|
||||
ipv6_addr->uint16[6] = 0;
|
||||
ipv6_addr->uint16[7] = HTONS(0x0001);
|
||||
}
|
||||
|
||||
void ipv6_iface_get_best_src_addr(ipv6_addr_t *src, const ipv6_addr_t *dest)
|
||||
{
|
||||
/* try to find best match if dest is not mcast or link local */
|
||||
int8_t itmp = -1;
|
||||
uint8_t tmp = 0;
|
||||
uint8_t bmatch = 0;
|
||||
|
||||
if (!(ipv6_addr_is_link_local(dest)) && !(ipv6_addr_is_multicast(dest))) {
|
||||
for (int i = 0; i < IFACE_ADDR_LIST_LEN; i++) {
|
||||
if (iface.addr_list[i].state == NDP_ADDR_STATE_PREFERRED) {
|
||||
if (!ipv6_addr_is_link_local(&(iface.addr_list[i].addr)) &&
|
||||
!ipv6_addr_is_multicast(&(iface.addr_list[i].addr)) &&
|
||||
!ipv6_addr_is_unique_local_unicast(&(iface.addr_list[i].addr))) {
|
||||
tmp = ipv6_get_addr_match(dest, &(iface.addr_list[i].addr));
|
||||
|
||||
if (tmp >= bmatch) {
|
||||
bmatch = tmp;
|
||||
itmp = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int j = 0; j < IFACE_ADDR_LIST_LEN; j++) {
|
||||
if ((iface.addr_list[j].state == NDP_ADDR_STATE_PREFERRED) &&
|
||||
ipv6_addr_is_link_local(&(iface.addr_list[j].addr)) &&
|
||||
!ipv6_addr_is_multicast(&(iface.addr_list[j].addr))) {
|
||||
itmp = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (itmp == -1) {
|
||||
memset(src, 0, 16);
|
||||
}
|
||||
else {
|
||||
memcpy(src, &(iface.addr_list[itmp].addr), 16);
|
||||
}
|
||||
}
|
||||
|
||||
int ipv6_addr_is_equal(const ipv6_addr_t *a, const ipv6_addr_t *b)
|
||||
{
|
||||
return (ipv6_get_addr_match(a, b) == 128);
|
||||
}
|
||||
|
||||
void ipv6_addr_set_link_local_prefix(ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
ipv6_addr->uint16[0] = HTONS(0xfe80);
|
||||
ipv6_addr->uint16[1] = 0;
|
||||
ipv6_addr->uint16[2] = 0;
|
||||
ipv6_addr->uint16[3] = 0;
|
||||
}
|
||||
|
||||
void ipv6_addr_init(ipv6_addr_t *out, uint16_t addr0, uint16_t addr1,
|
||||
uint16_t addr2, uint16_t addr3, uint16_t addr4,
|
||||
uint16_t addr5, uint16_t addr6, uint16_t addr7)
|
||||
{
|
||||
out->uint16[0] = HTONS(addr0);
|
||||
out->uint16[1] = HTONS(addr1);
|
||||
out->uint16[2] = HTONS(addr2);
|
||||
out->uint16[3] = HTONS(addr3);
|
||||
out->uint16[4] = HTONS(addr4);
|
||||
out->uint16[5] = HTONS(addr5);
|
||||
out->uint16[6] = HTONS(addr6);
|
||||
out->uint16[7] = HTONS(addr7);
|
||||
}
|
||||
|
||||
int ipv6_addr_is_link_local(const ipv6_addr_t *addr)
|
||||
{
|
||||
return (addr->uint8[0] == 0xfe && addr->uint8[0] == 0x80);
|
||||
}
|
||||
|
||||
int ipv6_addr_is_unique_local_unicast(const ipv6_addr_t *addr)
|
||||
{
|
||||
return (addr->uint8[0] == 0xfc || addr->uint8[0] == 0xfd);
|
||||
}
|
||||
|
||||
int ipv6_addr_is_multicast(const ipv6_addr_t *addr)
|
||||
{
|
||||
return (addr->uint8[0] == 0xff);
|
||||
}
|
||||
|
||||
int ipv6_addr_is_unspecified(const ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
return (ipv6_addr->uint32[0] == 0) && (ipv6_addr->uint32[1] == 0) &&
|
||||
(ipv6_addr->uint32[2] == 0) && (ipv6_addr->uint32[3] == 0);
|
||||
}
|
||||
|
||||
int ipv6_addr_is_solicited_node(const ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
return (ipv6_addr->uint8[0] == 0xFF) &&
|
||||
(ipv6_addr->uint8[1] == 0x02) &&
|
||||
(ipv6_addr->uint16[1] == 0x00) &&
|
||||
(ipv6_addr->uint16[2] == 0x00) &&
|
||||
(ipv6_addr->uint16[3] == 0x00) &&
|
||||
(ipv6_addr->uint16[4] == 0x00) &&
|
||||
(ipv6_addr->uint8[10] == 0x00) &&
|
||||
(ipv6_addr->uint8[11] == 0x01) &&
|
||||
(ipv6_addr->uint8[12] == 0xFF);
|
||||
}
|
||||
|
||||
void ipv6_addr_set_solicited_node_addr(ipv6_addr_t *ipv6_addr_out,
|
||||
const ipv6_addr_t *ipv6_addr_in)
|
||||
{
|
||||
/* copy only the last 24-bit of the ip-address that is beeing resolved */
|
||||
ipv6_addr_out->uint16[0] = HTONS(0xff02);
|
||||
ipv6_addr_out->uint16[1] = 0;
|
||||
ipv6_addr_out->uint16[2] = 0;
|
||||
ipv6_addr_out->uint16[3] = 0;
|
||||
ipv6_addr_out->uint16[4] = 0;
|
||||
ipv6_addr_out->uint16[5] = HTONS(0x0001);
|
||||
ipv6_addr_out->uint8[12] = 0xff;
|
||||
ipv6_addr_out->uint8[13] = ipv6_addr_in->uint8[13];
|
||||
ipv6_addr_out->uint16[7] = ipv6_addr_in->uint16[7];
|
||||
}
|
||||
|
||||
char *ipv6_addr_to_str(char *addr_str, const ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
sprintf(addr_str,
|
||||
"%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
|
||||
ipv6_addr->uint16[0], ipv6_addr->uint16[1],
|
||||
ipv6_addr->uint16[2], ipv6_addr->uint16[3],
|
||||
ipv6_addr->uint16[4], ipv6_addr->uint16[5],
|
||||
ipv6_addr->uint16[6], ipv6_addr->uint16[7]);
|
||||
return addr_str;
|
||||
}
|
||||
|
||||
uint32_t get_remaining_time(timex_t *t)
|
||||
{
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
|
||||
return (timex_sub(*t, now).seconds);
|
||||
}
|
||||
|
||||
void set_remaining_time(timex_t *t, uint32_t time)
|
||||
{
|
||||
timex_t tmp = {time, 0};
|
||||
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
*t = timex_add(now, tmp);
|
||||
}
|
||||
|
||||
void ipv6_init_iface_as_router(void)
|
||||
{
|
||||
ipv6_addr_t addr;
|
||||
|
||||
ipv6_addr_set_all_routers_addr(&addr);
|
||||
ipv6_iface_add_addr(&addr, NDP_ADDR_STATE_PREFERRED, 0, 0, IPV6_ADDR_TYPE_MULTICAST);
|
||||
}
|
||||
|
||||
|
||||
uint8_t ipv6_is_router(void)
|
||||
{
|
||||
ipv6_addr_t addr;
|
||||
|
||||
ipv6_addr_set_all_routers_addr(&addr);
|
||||
|
||||
if (ipv6_iface_addr_match(&addr) != NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_tcp_packet_handler_pid(int pid)
|
||||
{
|
||||
tcp_packet_handler_pid = pid;
|
||||
}
|
||||
|
||||
void set_udp_packet_handler_pid(int pid)
|
||||
{
|
||||
udp_packet_handler_pid = pid;
|
||||
}
|
||||
|
||||
void ipv6_register_next_header_handler(uint8_t next_header, int pid)
|
||||
{
|
||||
switch (next_header) {
|
||||
case (IPV6_PROTO_NUM_TCP):
|
||||
set_tcp_packet_handler_pid(pid);
|
||||
break;
|
||||
case (IPV6_PROTO_NUM_UDP):
|
||||
set_udp_packet_handler_pid(pid);
|
||||
break;
|
||||
default:
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ipv6_register_rpl_handler(int pid)
|
||||
{
|
||||
rpl_process_pid = pid;
|
||||
}
|
||||
91
sys/net/sixlowpan/ip.h
Normal file
91
sys/net/sixlowpan/ip.h
Normal file
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* IPv6 constants, data structs, and prototypes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowip.h
|
||||
* @brief 6lowpan IP layer header
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* 6LoWPAN IP header file */
|
||||
|
||||
#ifndef _SIXLOWPAN_IP_H
|
||||
#define _SIXLOWPAN_IP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "timex.h"
|
||||
#include "mutex.h"
|
||||
|
||||
#include "sixlowpan/ip.h"
|
||||
#include "sixlowpan/types.h"
|
||||
|
||||
/* IPv6 field values */
|
||||
#define IPV6_VER (0x60)
|
||||
/* size of global buffer */
|
||||
#define BUFFER_SIZE (LL_HDR_LEN + IPV6_MTU)
|
||||
|
||||
#define MULTIHOP_HOPLIMIT (64)
|
||||
|
||||
#define SIXLOWIP_MAX_REGISTERED (4)
|
||||
|
||||
/* extern variables */
|
||||
extern uint8_t ipv6_ext_hdr_len;
|
||||
|
||||
/* base header lengths */
|
||||
#define LL_HDR_LEN (0x4)
|
||||
#define ICMPV6_HDR_LEN (0x4)
|
||||
#define IPV6_HDR_LEN (0x28)
|
||||
|
||||
#define IFACE_ADDR_LIST_LEN (10) // maybe to much
|
||||
|
||||
/* buffer */
|
||||
extern uint8_t buffer[BUFFER_SIZE];
|
||||
|
||||
extern int sixlowip_reg[SIXLOWIP_MAX_REGISTERED];
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
ipv6_addr_t addr;
|
||||
ipv6_addr_type_t type;
|
||||
ndp_addr_state_t state;
|
||||
timex_t val_ltime;
|
||||
timex_t pref_ltime;
|
||||
} addr_list_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
ieee_802154_short_t saddr;
|
||||
ieee_802154_long_t laddr;
|
||||
addr_list_t addr_list[IFACE_ADDR_LIST_LEN];
|
||||
uint8_t adv_cur_hop_limit;
|
||||
uint32_t adv_reachable_time;
|
||||
uint32_t adv_retrans_timer;
|
||||
} iface_t;
|
||||
|
||||
extern iface_t iface;
|
||||
|
||||
/* function prototypes */
|
||||
void ipv6_send_bytes(ipv6_hdr_t *bytes);
|
||||
icmpv6_hdr_t *get_icmpv6_buf(uint8_t ext_len);
|
||||
uint8_t *get_payload_buf(uint8_t ext_len);
|
||||
uint8_t *get_payload_buf_send(uint8_t ext_len);
|
||||
|
||||
int icmpv6_demultiplex(const icmpv6_hdr_t *hdr);
|
||||
void ipv6_init_iface_as_router(void);
|
||||
void ipv6_process(void);
|
||||
addr_list_t *ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr);
|
||||
addr_list_t *ipv6_iface_addr_match(const ipv6_addr_t *addr);
|
||||
uint32_t get_remaining_time(timex_t *t);
|
||||
void set_remaining_time(timex_t *t, uint32_t time);
|
||||
|
||||
#endif /* _SIXLOWPAN_IP_H*/
|
||||
@ -10,7 +10,7 @@
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowpan.c
|
||||
* @brief 6lowpan functions
|
||||
* @brief 6lowpan functions
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
@ -18,11 +18,11 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "sixlowip.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "vtimer.h"
|
||||
#include "timex.h"
|
||||
@ -31,18 +31,61 @@
|
||||
#include "mutex.h"
|
||||
#include "hwtimer.h"
|
||||
#include "msg.h"
|
||||
#include "sixlowmac.h"
|
||||
#include "sixlowpan.h"
|
||||
#include "sixlowborder.h"
|
||||
#include "sixlowip.h"
|
||||
#include "sixlownd.h"
|
||||
#include "transceiver.h"
|
||||
#include "ieee802154/ieee802154_frame.h"
|
||||
#include "sixlowpan/mac.h"
|
||||
#include "sixlowpan/ndp.h"
|
||||
|
||||
#include "lowpan.h"
|
||||
#include "border.h"
|
||||
#include "ip.h"
|
||||
#include "icmp.h"
|
||||
|
||||
#include "sys/net/ieee802154/ieee802154_frame.h"
|
||||
#include "sys/net/destiny/in.h"
|
||||
#include "sys/net/net_help/net_help.h"
|
||||
|
||||
uint16_t packet_length;
|
||||
uint8_t packet_dispatch;
|
||||
#define IP_PROCESS_STACKSIZE (KERNEL_CONF_STACKSIZE_DEFAULT * 6)
|
||||
#define NC_STACKSIZE (KERNEL_CONF_STACKSIZE_DEFAULT)
|
||||
#define CON_STACKSIZE (KERNEL_CONF_STACKSIZE_DEFAULT)
|
||||
#define LOWPAN_TRANSFER_BUF_STACKSIZE (KERNEL_CONF_STACKSIZE_DEFAULT)
|
||||
|
||||
#define SIXLOWPAN_MAX_REGISTERED (4)
|
||||
|
||||
#define LOWPAN_REAS_BUF_TIMEOUT (15 * 1000 * 1000)
|
||||
/* TODO: Set back to 3 * 1000 * (1000) */
|
||||
|
||||
#define IPV6_LL_ADDR_LEN (8)
|
||||
|
||||
#define SIXLOWPAN_FRAG_HDR_MASK (0xf8)
|
||||
|
||||
typedef struct lowpan_interval_list_t {
|
||||
uint8_t start;
|
||||
uint8_t end;
|
||||
struct lowpan_interval_list_t *next;
|
||||
} lowpan_interval_list_t;
|
||||
|
||||
typedef struct lowpan_reas_buf_t {
|
||||
/* Source Address */
|
||||
ieee_802154_long_t s_laddr;
|
||||
/* Destination Address */
|
||||
ieee_802154_long_t d_laddr;
|
||||
/* Identification Number */
|
||||
uint16_t ident_no;
|
||||
/* Timestamp of last packet fragment */
|
||||
long timestamp;
|
||||
/* Size of reassembled packet with possible IPHC header */
|
||||
uint16_t packet_size;
|
||||
/* Additive size of currently already received fragments */
|
||||
uint16_t current_packet_size;
|
||||
/* Pointer to allocated memory for reassembled packet + 6LoWPAN Dispatch Byte */
|
||||
uint8_t *packet;
|
||||
/* Pointer to list of intervals of received packet fragments (if any) */
|
||||
lowpan_interval_list_t *interval_list_head;
|
||||
/* Pointer to next reassembly buffer (if any) */
|
||||
struct lowpan_reas_buf_t *next;
|
||||
} lowpan_reas_buf_t;
|
||||
|
||||
extern mutex_t lowpan_context_mutex;
|
||||
uint16_t tag;
|
||||
uint8_t header_size = 0;
|
||||
uint8_t max_frame = 0;
|
||||
@ -50,7 +93,11 @@ uint8_t max_frag_initial = 0;
|
||||
uint8_t position;
|
||||
uint8_t max_frag;
|
||||
|
||||
static uint16_t packet_length;
|
||||
static sixlowpan_lowpan_iphc_status_t iphc_status = LOWPAN_IPHC_ENABLE;
|
||||
static ipv6_hdr_t *ipv6_buf;
|
||||
static lowpan_reas_buf_t *head = NULL;
|
||||
static lowpan_reas_buf_t *packet_fifo = NULL;
|
||||
|
||||
/* length of compressed packet */
|
||||
uint16_t comp_len;
|
||||
@ -59,8 +106,6 @@ uint8_t reas_buf[512];
|
||||
uint8_t comp_buf[512];
|
||||
uint8_t byte_offset;
|
||||
uint8_t first_frag = 0;
|
||||
lowpan_reas_buf_t *head = NULL;
|
||||
lowpan_reas_buf_t *packet_fifo = NULL;
|
||||
mutex_t fifo_mutex;
|
||||
|
||||
unsigned int ip_process_pid;
|
||||
@ -71,36 +116,59 @@ unsigned int transfer_pid = 0;
|
||||
iface_t iface;
|
||||
ipv6_addr_t lladdr;
|
||||
ieee_802154_long_t laddr;
|
||||
mutex_t buf_mutex;
|
||||
mutex_t lowpan_context_mutex;
|
||||
|
||||
/* registered upper layer threads */
|
||||
int sixlowpan_reg[SIXLOWPAN_MAX_REGISTERED];
|
||||
|
||||
char ip_process_buf[IP_PROCESS_STACKSIZE];
|
||||
char nc_buf[NC_STACKSIZE];
|
||||
char con_buf[CON_STACKSIZE];
|
||||
char lowpan_transfer_buf[LOWPAN_TRANSFER_BUF_STACKSIZE];
|
||||
lowpan_context_t contexts[LOWPAN_CONTEXT_MAX];
|
||||
lowpan_context_t contexts[NDP_6LOWPAN_CONTEXT_MAX];
|
||||
uint8_t context_len = 0;
|
||||
uint16_t local_address = 0;
|
||||
|
||||
void lowpan_context_auto_remove(void);
|
||||
void lowpan_iphc_encoding(ieee_802154_long_t *dest,
|
||||
ipv6_hdr_t *ipv6_buf_extra, uint8_t *ptr);
|
||||
void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
ieee_802154_long_t *s_laddr,
|
||||
ieee_802154_long_t *d_laddr);
|
||||
void add_fifo_packet(lowpan_reas_buf_t *current_packet);
|
||||
lowpan_reas_buf_t *collect_garbage_fifo(lowpan_reas_buf_t *current_buf);
|
||||
lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf);
|
||||
void init_reas_bufs(lowpan_reas_buf_t *buf);
|
||||
void check_timeout(void);
|
||||
|
||||
lowpan_context_t *lowpan_context_lookup(ipv6_addr_t *addr);
|
||||
|
||||
void lowpan_ipv6_set_dispatch(uint8_t *data);
|
||||
|
||||
/* deliver packet to mac*/
|
||||
void lowpan_init(ieee_802154_long_t *addr, uint8_t *data)
|
||||
void sixlowpan_lowpan_sendto(const ieee_802154_long_t *dest,
|
||||
uint8_t *data, uint16_t data_len)
|
||||
{
|
||||
uint8_t mcast = 0;
|
||||
|
||||
ipv6_buf = (ipv6_hdr_t *) data;
|
||||
packet_length = data_len;
|
||||
|
||||
memcpy(&laddr.uint8[0], &addr->uint8[0], 8);
|
||||
memcpy(&laddr.uint8[0], &dest->uint8[0], 8);
|
||||
|
||||
if (ipv6_prefix_mcast_match(&ipv6_buf->destaddr)) {
|
||||
if (ipv6_addr_is_multicast(&ipv6_buf->destaddr)) {
|
||||
/* send broadcast */
|
||||
mcast = 1;
|
||||
}
|
||||
|
||||
lowpan_iphc_encoding(&laddr, ipv6_buf, data);
|
||||
data = &comp_buf[0];
|
||||
packet_length = comp_len;
|
||||
if (iphc_status == LOWPAN_IPHC_ENABLE) {
|
||||
lowpan_iphc_encoding(&laddr, ipv6_buf, data);
|
||||
data = &comp_buf[0];
|
||||
packet_length = comp_len;
|
||||
}
|
||||
else {
|
||||
lowpan_ipv6_set_dispatch(data);
|
||||
}
|
||||
|
||||
/* check if packet needs to be fragmented */
|
||||
if (packet_length + header_size > PAYLOAD_SIZE - IEEE_802154_MAX_HDR_LEN) {
|
||||
@ -113,13 +181,15 @@ void lowpan_init(ieee_802154_long_t *addr, uint8_t *data)
|
||||
|
||||
memcpy(fragbuf + 4, data, max_frag_initial);
|
||||
|
||||
fragbuf[0] = (((0xc0 << 8) | packet_length) >> 8) & 0xff;
|
||||
fragbuf[1] = ((0xc0 << 8) | packet_length) & 0xff;
|
||||
fragbuf[2] = (tag >> 8) & 0xff;
|
||||
fragbuf[3] = tag & 0xff;
|
||||
fragbuf[0] = ((SIXLOWPAN_FRAG1_DISPATCH << 8) | packet_length) >> 8;
|
||||
fragbuf[1] = (SIXLOWPAN_FRAG1_DISPATCH << 8) | packet_length;
|
||||
fragbuf[2] = tag >> 8;
|
||||
fragbuf[3] = tag;
|
||||
|
||||
send_ieee802154_frame(&laddr, (uint8_t *)&fragbuf,
|
||||
max_frag_initial + header_size + 4, mcast);
|
||||
sixlowpan_mac_send_ieee802154_frame(&laddr,
|
||||
(uint8_t *)&fragbuf,
|
||||
max_frag_initial + header_size + 4,
|
||||
mcast);
|
||||
/* subsequent fragments */
|
||||
position = max_frag_initial;
|
||||
max_frag = ((max_frame - 5) / 8) * 8;
|
||||
@ -130,14 +200,15 @@ void lowpan_init(ieee_802154_long_t *addr, uint8_t *data)
|
||||
memset(&fragbuf, 0, packet_length + header_size);
|
||||
memcpy(fragbuf + 5, data, max_frag);
|
||||
|
||||
fragbuf[0] = (((0xe0 << 8) | packet_length) >> 8) & 0xff;
|
||||
fragbuf[1] = ((0xe0 << 8) | packet_length) & 0xff;
|
||||
fragbuf[2] = (tag >> 8) & 0xff;
|
||||
fragbuf[3] = tag & 0xff;
|
||||
fragbuf[0] = ((SIXLOWPAN_FRAGN_DISPATCH << 8) | packet_length) >> 8;
|
||||
fragbuf[1] = (SIXLOWPAN_FRAGN_DISPATCH << 8) | packet_length;
|
||||
fragbuf[2] = tag >> 8;
|
||||
fragbuf[3] = tag;
|
||||
fragbuf[4] = position / 8;
|
||||
|
||||
send_ieee802154_frame(&laddr, (uint8_t *)&fragbuf, max_frag + 5,
|
||||
mcast);
|
||||
sixlowpan_mac_send_ieee802154_frame(&laddr,
|
||||
(uint8_t *)&fragbuf,
|
||||
max_frag + 5, mcast);
|
||||
data += max_frag;
|
||||
position += max_frag;
|
||||
|
||||
@ -149,22 +220,32 @@ void lowpan_init(ieee_802154_long_t *addr, uint8_t *data)
|
||||
memset(&fragbuf, 0, packet_length + header_size);
|
||||
memcpy(fragbuf + 5, data, remaining);
|
||||
|
||||
fragbuf[0] = (((0xe0 << 8) | packet_length) >> 8) & 0xff;
|
||||
fragbuf[1] = ((0xe0 << 8) | packet_length) & 0xff;
|
||||
fragbuf[2] = (tag >> 8) & 0xff;
|
||||
fragbuf[3] = tag & 0xff;
|
||||
fragbuf[0] = ((SIXLOWPAN_FRAGN_DISPATCH << 8) | packet_length) >> 8;
|
||||
fragbuf[1] = (SIXLOWPAN_FRAGN_DISPATCH << 8) | packet_length;
|
||||
fragbuf[2] = tag >> 8;
|
||||
fragbuf[3] = tag;
|
||||
fragbuf[4] = position / 8;
|
||||
|
||||
send_ieee802154_frame(&laddr, (uint8_t *)&fragbuf, remaining + 5, mcast);
|
||||
sixlowpan_mac_send_ieee802154_frame(&laddr,
|
||||
(uint8_t *)&fragbuf,
|
||||
remaining + 5, mcast);
|
||||
}
|
||||
else {
|
||||
send_ieee802154_frame(&laddr, data, packet_length, mcast);
|
||||
sixlowpan_mac_send_ieee802154_frame(&laddr, data,
|
||||
packet_length, mcast);
|
||||
}
|
||||
|
||||
tag++;
|
||||
}
|
||||
|
||||
void printLongLocalAddr(ieee_802154_long_t *saddr)
|
||||
void sixlowpan_lowpan_set_iphc_status(
|
||||
sixlowpan_lowpan_iphc_status_t status)
|
||||
{
|
||||
iphc_status = status;
|
||||
}
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
void print_long_local_addr(ieee_802154_long_t *saddr)
|
||||
{
|
||||
printf("%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
|
||||
((uint8_t *)saddr)[0], ((uint8_t *)saddr)[1], ((uint8_t *)saddr)[2],
|
||||
@ -172,7 +253,7 @@ void printLongLocalAddr(ieee_802154_long_t *saddr)
|
||||
((uint8_t *)saddr)[6], ((uint8_t *)saddr)[7]);
|
||||
}
|
||||
|
||||
void printReasBuffers(void)
|
||||
void sixlowpan_lowpan_print_reassembly_buffers(void)
|
||||
{
|
||||
lowpan_reas_buf_t *temp_buffer;
|
||||
lowpan_interval_list_t *temp_interval;
|
||||
@ -181,7 +262,7 @@ void printReasBuffers(void)
|
||||
printf("\n\n--- Reassembly Buffers ---\n");
|
||||
|
||||
while (temp_buffer != NULL) {
|
||||
printLongLocalAddr(&temp_buffer->s_laddr);
|
||||
print_long_local_addr(&temp_buffer->s_laddr);
|
||||
printf("Ident.: %i, Packet Size: %i/%i, Timestamp: %li\n",
|
||||
temp_buffer->ident_no, temp_buffer->current_packet_size,
|
||||
temp_buffer->packet_size, temp_buffer->timestamp);
|
||||
@ -196,7 +277,7 @@ void printReasBuffers(void)
|
||||
}
|
||||
}
|
||||
|
||||
void printFIFOBuffers(void)
|
||||
void sixlowpan_lowpan_print_fifo_buffers(void)
|
||||
{
|
||||
lowpan_reas_buf_t *temp_buffer;
|
||||
lowpan_interval_list_t *temp_interval;
|
||||
@ -205,9 +286,9 @@ void printFIFOBuffers(void)
|
||||
printf("\n\n--- Reassembly Buffers ---\n");
|
||||
|
||||
while (temp_buffer != NULL) {
|
||||
printLongLocalAddr(&temp_buffer->s_laddr);
|
||||
print_long_local_addr(&temp_buffer->s_laddr);
|
||||
printf("Ident.: %i, Packet Size: %i/%i, Timestamp: %li\n",
|
||||
temp_buffer->ident_no, temp_buffer->current_packet_size,
|
||||
temp_buffer->ident_no, temp_buffer->current_packet_size,
|
||||
temp_buffer->packet_size, temp_buffer->timestamp);
|
||||
temp_interval = temp_buffer->interval_list_head;
|
||||
|
||||
@ -219,6 +300,7 @@ void printFIFOBuffers(void)
|
||||
temp_buffer = temp_buffer->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void lowpan_transfer(void)
|
||||
{
|
||||
@ -236,20 +318,20 @@ void lowpan_transfer(void)
|
||||
if (current_buf != NULL) {
|
||||
mutex_unlock(&fifo_mutex);
|
||||
|
||||
if ((current_buf->packet)[0] == LOWPAN_IPV6_DISPATCH) {
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
if ((current_buf->packet)[0] == SIXLOWPAN_IPV6_DISPATCH) {
|
||||
ipv6_buf = ipv6_get_buf();
|
||||
memcpy(ipv6_buf, (current_buf->packet) + 1, current_buf->packet_size - 1);
|
||||
m_send.content.ptr = (char *)ipv6_buf;
|
||||
packet_length = current_buf->packet_size - 1;
|
||||
msg_send_receive(&m_send, &m_recv, ip_process_pid);
|
||||
}
|
||||
else if (((current_buf->packet)[0] & 0xe0) == LOWPAN_IPHC_DISPATCH) {
|
||||
else if (((current_buf->packet)[0] & 0xe0) == SIXLOWPAN_IPHC1_DISPATCH) {
|
||||
lowpan_iphc_decoding(current_buf->packet,
|
||||
current_buf->packet_size,
|
||||
&(current_buf->s_laddr),
|
||||
&(current_buf->d_laddr));
|
||||
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
ipv6_buf = ipv6_get_buf();
|
||||
m_send.content.ptr = (char *) ipv6_buf;
|
||||
msg_send_receive(&m_send, &m_recv, ip_process_pid);
|
||||
}
|
||||
@ -315,8 +397,8 @@ lowpan_reas_buf_t *new_packet_buffer(uint16_t datagram_size,
|
||||
new_buf->packet = malloc(datagram_size);
|
||||
|
||||
if (new_buf->packet != NULL) {
|
||||
memcpy(&new_buf->s_laddr, s_laddr, SIXLOWPAN_IPV6_LL_ADDR_LEN);
|
||||
memcpy(&new_buf->d_laddr, d_laddr, SIXLOWPAN_IPV6_LL_ADDR_LEN);
|
||||
memcpy(&new_buf->s_laddr, s_laddr, IPV6_LL_ADDR_LEN);
|
||||
memcpy(&new_buf->d_laddr, d_laddr, IPV6_LL_ADDR_LEN);
|
||||
|
||||
new_buf->ident_no = datagram_tag;
|
||||
new_buf->packet_size = datagram_size;
|
||||
@ -353,10 +435,10 @@ lowpan_reas_buf_t *get_packet_frag_buf(uint16_t datagram_size,
|
||||
|
||||
while (current_buf != NULL) {
|
||||
if (((ll_get_addr_match(¤t_buf->s_laddr, s_laddr)) == 64) &&
|
||||
((ll_get_addr_match(¤t_buf->d_laddr, d_laddr)) == 64) &&
|
||||
(current_buf->packet_size == datagram_size) &&
|
||||
(current_buf->ident_no == datagram_tag) &&
|
||||
current_buf->interval_list_head != NULL) {
|
||||
((ll_get_addr_match(¤t_buf->d_laddr, d_laddr)) == 64) &&
|
||||
(current_buf->packet_size == datagram_size) &&
|
||||
(current_buf->ident_no == datagram_tag) &&
|
||||
current_buf->interval_list_head != NULL) {
|
||||
/* Found buffer for current packet fragment */
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
@ -372,14 +454,14 @@ lowpan_reas_buf_t *get_packet_frag_buf(uint16_t datagram_size,
|
||||
current_buf, temp_buf);
|
||||
}
|
||||
|
||||
uint8_t isInInterval(uint8_t start1, uint8_t end1, uint8_t start2, uint8_t end2)
|
||||
uint8_t is_in_interval(uint8_t start1, uint8_t end1, uint8_t start2, uint8_t end2)
|
||||
{
|
||||
/* 1: Interval 1 and 2 are the same or overlapping */
|
||||
/* 0: Interval 1 and 2 are not overlapping or the same */
|
||||
|
||||
if (((start1 < start2) && (start2 <= end1)) ||
|
||||
((start2 < start1) && (start1 <= end2)) ||
|
||||
((start1 == start2) && (end1 == end2))) {
|
||||
((start2 < start1) && (start1 <= end2)) ||
|
||||
((start1 == start2) && (end1 == end2))) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
@ -396,7 +478,7 @@ uint8_t handle_packet_frag_interval(lowpan_reas_buf_t *current_buf,
|
||||
current_interval = current_buf->interval_list_head;
|
||||
|
||||
while (current_interval != NULL) {
|
||||
if (isInInterval(current_interval->start, current_interval->end, datagram_offset, datagram_offset + frag_size) == 1) {
|
||||
if (is_in_interval(current_interval->start, current_interval->end, datagram_offset, datagram_offset + frag_size) == 1) {
|
||||
/* Interval is overlapping or the same as one of a previous fragment, discard fragment */
|
||||
return 0;
|
||||
}
|
||||
@ -505,7 +587,7 @@ lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf)
|
||||
return return_buf;
|
||||
}
|
||||
|
||||
void handle_packet_fragment(uint8_t *data, uint8_t datagram_offset,
|
||||
void handle_packet_fragment(uint8_t *data, uint8_t datagram_offset,
|
||||
uint16_t datagram_size, uint16_t datagram_tag,
|
||||
ieee_802154_long_t *s_laddr,
|
||||
ieee_802154_long_t *d_laddr, uint8_t hdr_length,
|
||||
@ -516,8 +598,8 @@ void handle_packet_fragment(uint8_t *data, uint8_t datagram_offset,
|
||||
current_buf = get_packet_frag_buf(datagram_size, datagram_tag, s_laddr, d_laddr);
|
||||
|
||||
if ((current_buf != NULL) && (handle_packet_frag_interval(current_buf,
|
||||
datagram_offset,
|
||||
frag_size) == 1)) {
|
||||
datagram_offset,
|
||||
frag_size) == 1)) {
|
||||
/* Copy fragment bytes into corresponding packet space area */
|
||||
memcpy(current_buf->packet + datagram_offset, data + hdr_length, frag_size);
|
||||
current_buf->current_packet_size += frag_size;
|
||||
@ -614,6 +696,25 @@ void add_fifo_packet(lowpan_reas_buf_t *current_packet)
|
||||
current_packet->next = NULL;
|
||||
}
|
||||
|
||||
/* Register an upper layer thread */
|
||||
uint8_t sixlowpan_lowpan_register(int pid)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; ((sixlowpan_reg[i] != pid) && (i < SIXLOWPAN_MAX_REGISTERED) &&
|
||||
(sixlowpan_reg[i] != 0)); i++) {
|
||||
;
|
||||
}
|
||||
|
||||
if (i >= SIXLOWPAN_MAX_REGISTERED) {
|
||||
return ENOMEM;
|
||||
}
|
||||
else {
|
||||
sixlowpan_reg[i] = pid;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
|
||||
ieee_802154_long_t *d_laddr)
|
||||
{
|
||||
@ -622,27 +723,40 @@ void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
|
||||
uint8_t datagram_offset = 0;
|
||||
uint16_t datagram_size = 0;
|
||||
uint16_t datagram_tag = 0;
|
||||
short i;
|
||||
sixlowpan_lowpan_frame_t current_frame;
|
||||
|
||||
check_timeout();
|
||||
|
||||
for (i = 0; i < SIXLOWPAN_MAX_REGISTERED; i++) {
|
||||
if (sixlowpan_reg[i]) {
|
||||
msg_t m_send;
|
||||
current_frame.length = length;
|
||||
current_frame.data = data;
|
||||
m_send.content.ptr = (char *) ¤t_frame;
|
||||
msg_send(&m_send, sixlowpan_reg[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fragmented Packet */
|
||||
if (((data[0] & 0xf8) == (0xc0)) || ((data[0] & 0xf8) == (0xe0))) {
|
||||
if (((data[0] & SIXLOWPAN_FRAG_HDR_MASK) == SIXLOWPAN_FRAG1_DISPATCH) ||
|
||||
((data[0] & SIXLOWPAN_FRAG_HDR_MASK) == SIXLOWPAN_FRAGN_DISPATCH)) {
|
||||
/* get 11-bit from first 2 byte*/
|
||||
datagram_size = (((uint16_t)(data[0] << 8)) | data[1]) & 0x07ff;
|
||||
|
||||
/* get 16-bit datagram tag */
|
||||
datagram_tag = (((uint16_t)(data[2] << 8)) | data[3]);
|
||||
|
||||
switch(data[0] & 0xf8) {
|
||||
switch (data[0] & SIXLOWPAN_FRAG_HDR_MASK) {
|
||||
/* First Fragment */
|
||||
case (0xc0): {
|
||||
case (SIXLOWPAN_FRAG1_DISPATCH): {
|
||||
datagram_offset = 0;
|
||||
hdr_length += 4;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Subsequent Fragment */
|
||||
case (0xe0): {
|
||||
case (SIXLOWPAN_FRAGN_DISPATCH): {
|
||||
datagram_offset = data[4];
|
||||
hdr_length += 5;
|
||||
break;
|
||||
@ -665,7 +779,7 @@ void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
|
||||
/* Regular Packet */
|
||||
else {
|
||||
lowpan_reas_buf_t *current_buf = get_packet_frag_buf(length, 0, s_laddr,
|
||||
d_laddr);
|
||||
d_laddr);
|
||||
/* Copy packet bytes into corresponding packet space area */
|
||||
memcpy(current_buf->packet, data, length);
|
||||
current_buf->current_packet_size += length;
|
||||
@ -681,7 +795,7 @@ void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
|
||||
void lowpan_ipv6_set_dispatch(uint8_t *data)
|
||||
{
|
||||
memmove(data + 1, data, packet_length);
|
||||
data[0] = LOWPAN_IPV6_DISPATCH;
|
||||
data[0] = SIXLOWPAN_IPV6_DISPATCH;
|
||||
packet_length++;
|
||||
}
|
||||
|
||||
@ -701,7 +815,7 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
|
||||
memset(&lowpan_iphc, 0, 2);
|
||||
|
||||
/* set iphc dispatch */
|
||||
lowpan_iphc[0] = LOWPAN_IPHC_DISPATCH;
|
||||
lowpan_iphc[0] = SIXLOWPAN_IPHC1_DISPATCH;
|
||||
|
||||
/* TF: Traffic Class, Flow Label:
|
||||
* first we need to change DSCP and ECN because in 6lowpan-nd-13 these
|
||||
@ -711,14 +825,14 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
|
||||
tc = (tc >> 2) | (tc << 6);
|
||||
|
||||
if ((ipv6_buf->flowlabel == 0) &&
|
||||
(ipv6_buf->trafficclass_flowlabel & 0x0f) == 0) {
|
||||
(ipv6_buf->trafficclass_flowlabel & 0x0f) == 0) {
|
||||
/* flowlabel is elided */
|
||||
lowpan_iphc[0] |= LOWPAN_IPHC_FL_C;
|
||||
lowpan_iphc[0] |= SIXLOWPAN_IPHC1_FL_C;
|
||||
|
||||
if (((ipv6_buf->version_trafficclass & 0x0f) == 0) &&
|
||||
((ipv6_buf->trafficclass_flowlabel & 0xf0) == 0)) {
|
||||
((ipv6_buf->trafficclass_flowlabel & 0xf0) == 0)) {
|
||||
/* traffic class is elided */
|
||||
lowpan_iphc[0] |= LOWPAN_IPHC_TC_C;
|
||||
lowpan_iphc[0] |= SIXLOWPAN_IPHC1_TC_C;
|
||||
}
|
||||
else {
|
||||
/* ECN + DSCP (1 byte), Flow Label is elided */
|
||||
@ -729,9 +843,9 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
|
||||
else {
|
||||
/* flowlabel not compressible */
|
||||
if (((ipv6_buf->version_trafficclass & 0x0f) == 0) &&
|
||||
((ipv6_buf->trafficclass_flowlabel & 0xf0) == 0)) {
|
||||
((ipv6_buf->trafficclass_flowlabel & 0xf0) == 0)) {
|
||||
/* traffic class is elided */
|
||||
lowpan_iphc[0] |= LOWPAN_IPHC_TC_C;
|
||||
lowpan_iphc[0] |= SIXLOWPAN_IPHC1_TC_C;
|
||||
/* ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided */
|
||||
ipv6_hdr_fields[hdr_pos] = ((tc & 0xc0) |
|
||||
(ipv6_buf->trafficclass_flowlabel & 0x0f));
|
||||
@ -752,7 +866,7 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
|
||||
hdr_pos++;
|
||||
|
||||
/* HLIM: Hop Limit: */
|
||||
switch(ipv6_buf->hoplimit) {
|
||||
switch (ipv6_buf->hoplimit) {
|
||||
case (1): {
|
||||
/* 01: The Hop Limit field is compressed and the hop limit is 1. */
|
||||
lowpan_iphc[0] |= 0x01;
|
||||
@ -782,21 +896,21 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
|
||||
|
||||
/* CID: Context Identifier Extension: */
|
||||
if ((lowpan_context_lookup(&ipv6_buf->srcaddr) != NULL) ||
|
||||
(lowpan_context_lookup(&ipv6_buf->destaddr) != NULL)) {
|
||||
lowpan_iphc[1] |= LOWPAN_IPHC_CID;
|
||||
(lowpan_context_lookup(&ipv6_buf->destaddr) != NULL)) {
|
||||
lowpan_iphc[1] |= SIXLOWPAN_IPHC2_CID;
|
||||
memmove(&ipv6_hdr_fields[1], &ipv6_hdr_fields[0], hdr_pos);
|
||||
hdr_pos++;
|
||||
}
|
||||
|
||||
/* SAC: Source Address Compression */
|
||||
if (ipv6_addr_unspec_match(&(ipv6_buf->srcaddr))) {
|
||||
if (ipv6_addr_is_unspecified(&(ipv6_buf->srcaddr))) {
|
||||
/* SAC = 1 and SAM = 00 */
|
||||
lowpan_iphc[1] |= LOWPAN_IPHC_SAC;
|
||||
lowpan_iphc[1] |= SIXLOWPAN_IPHC2_SAC;
|
||||
}
|
||||
else if ((con = lowpan_context_lookup(&ipv6_buf->srcaddr)) != NULL) {
|
||||
/* 1: Source address compression uses stateful, context-based
|
||||
* compression. */
|
||||
lowpan_iphc[1] |= LOWPAN_IPHC_SAC;
|
||||
lowpan_iphc[1] |= SIXLOWPAN_IPHC2_SAC;
|
||||
ipv6_hdr_fields[0] |= (con->num << 4);
|
||||
|
||||
if (memcmp(&(ipv6_buf->srcaddr.uint8[8]), &(iface.laddr.uint8[0]), 8) == 0) {
|
||||
@ -805,9 +919,9 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
|
||||
lowpan_iphc[1] |= 0x30;
|
||||
}
|
||||
else if ((ipv6_buf->srcaddr.uint16[4] == 0) &&
|
||||
(ipv6_buf->srcaddr.uint16[5] == 0) &&
|
||||
(ipv6_buf->srcaddr.uint16[6] == 0) &&
|
||||
((ipv6_buf->srcaddr.uint8[14]) & 0x80) == 0) {
|
||||
(ipv6_buf->srcaddr.uint16[5] == 0) &&
|
||||
(ipv6_buf->srcaddr.uint16[6] == 0) &&
|
||||
((ipv6_buf->srcaddr.uint8[14]) & 0x80) == 0) {
|
||||
/* 49-bit of interface identifier are 0, so we can compress
|
||||
* source address-iid to 16-bit */
|
||||
memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->srcaddr.uint16[7], 2);
|
||||
@ -824,7 +938,7 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
|
||||
lowpan_iphc[1] |= 0x10;
|
||||
}
|
||||
}
|
||||
else if (ipv6_prefix_ll_match(&ipv6_buf->srcaddr)) {
|
||||
else if (ipv6_addr_is_link_local(&ipv6_buf->srcaddr)) {
|
||||
/* 0: Source address compression uses stateless compression.*/
|
||||
if (memcmp(&(ipv6_buf->srcaddr.uint8[8]), &(iface.laddr.uint8[0]), 8) == 0) {
|
||||
/* 0 bits. The address is derived using context information
|
||||
@ -832,9 +946,9 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
|
||||
lowpan_iphc[1] |= 0x30;
|
||||
}
|
||||
else if ((ipv6_buf->srcaddr.uint16[4] == 0) &&
|
||||
(ipv6_buf->srcaddr.uint16[5] == 0) &&
|
||||
(ipv6_buf->srcaddr.uint16[6] == 0) &&
|
||||
((ipv6_buf->srcaddr.uint8[14]) & 0x80) == 0) {
|
||||
(ipv6_buf->srcaddr.uint16[5] == 0) &&
|
||||
(ipv6_buf->srcaddr.uint16[6] == 0) &&
|
||||
((ipv6_buf->srcaddr.uint8[14]) & 0x80) == 0) {
|
||||
/* 49-bit of interface identifier are 0, so we can compress
|
||||
* source address-iid to 16-bit */
|
||||
memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->srcaddr.uint16[7], 2);
|
||||
@ -858,30 +972,30 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
|
||||
}
|
||||
|
||||
/* M: Multicast Compression */
|
||||
if (ipv6_prefix_mcast_match(&ipv6_buf->destaddr)) {
|
||||
if (ipv6_addr_is_multicast(&ipv6_buf->destaddr)) {
|
||||
/* 1: Destination address is a multicast address. */
|
||||
lowpan_iphc[1] |= LOWPAN_IPHC_M;
|
||||
lowpan_iphc[1] |= SIXLOWPAN_IPHC2_M;
|
||||
|
||||
/* just another cool if condition */
|
||||
if ((ipv6_buf->destaddr.uint8[1] == 2) &&
|
||||
(ipv6_buf->destaddr.uint16[1] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[2] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[3] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[4] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[5] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[6] == 0) &&
|
||||
(ipv6_buf->destaddr.uint8[14] == 0)) {
|
||||
(ipv6_buf->destaddr.uint16[1] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[2] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[3] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[4] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[5] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[6] == 0) &&
|
||||
(ipv6_buf->destaddr.uint8[14] == 0)) {
|
||||
/* 11: 8 bits. The address takes the form FF02::00XX. */
|
||||
lowpan_iphc[1] |= 0x03;
|
||||
ipv6_hdr_fields[hdr_pos] = ipv6_buf->destaddr.uint8[15];
|
||||
hdr_pos++;
|
||||
}
|
||||
else if ((ipv6_buf->destaddr.uint16[1] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[2] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[3] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[4] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[5] == 0) &&
|
||||
(ipv6_buf->destaddr.uint8[12] == 0)) {
|
||||
(ipv6_buf->destaddr.uint16[2] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[3] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[4] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[5] == 0) &&
|
||||
(ipv6_buf->destaddr.uint8[12] == 0)) {
|
||||
/* 10: 32 bits. The address takes the form FFXX::00XX:XXXX. */
|
||||
lowpan_iphc[1] |= 0x02;
|
||||
/* copy second and last 3 byte */
|
||||
@ -891,10 +1005,10 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
|
||||
hdr_pos += 3;
|
||||
}
|
||||
else if ((ipv6_buf->destaddr.uint16[1] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[2] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[3] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[4] == 0) &&
|
||||
(ipv6_buf->destaddr.uint8[10] == 0)) {
|
||||
(ipv6_buf->destaddr.uint16[2] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[3] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[4] == 0) &&
|
||||
(ipv6_buf->destaddr.uint8[10] == 0)) {
|
||||
/* 01: 48 bits. The address takes the form FFXX::00XX:XXXX:XXXX */
|
||||
lowpan_iphc[1] |= 0x01;
|
||||
/* copy second and last 5 byte */
|
||||
@ -913,7 +1027,7 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
|
||||
if ((con = lowpan_context_lookup(&ipv6_buf->destaddr)) != NULL) {
|
||||
/* 1: Destination address compression uses stateful, context-based
|
||||
* compression. */
|
||||
lowpan_iphc[1] |= LOWPAN_IPHC_DAC;
|
||||
lowpan_iphc[1] |= SIXLOWPAN_IPHC2_DAC;
|
||||
ipv6_hdr_fields[0] = con->num;
|
||||
|
||||
if (memcmp(&(ipv6_buf->destaddr.uint8[8]), &(dest->uint8[0]), 8) == 0) {
|
||||
@ -922,9 +1036,9 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
|
||||
lowpan_iphc[1] |= 0x03;
|
||||
}
|
||||
else if ((ipv6_buf->destaddr.uint16[4] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[5] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[6] == 0) &&
|
||||
((ipv6_buf->destaddr.uint8[14]) & 0x80) == 0) {
|
||||
(ipv6_buf->destaddr.uint16[5] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[6] == 0) &&
|
||||
((ipv6_buf->destaddr.uint8[14]) & 0x80) == 0) {
|
||||
/* 49-bit of interface identifier are 0, so we can compress
|
||||
* source address-iid to 16-bit */
|
||||
memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->destaddr.uint16[7], 2);
|
||||
@ -941,16 +1055,16 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
|
||||
lowpan_iphc[1] |= 0x01;
|
||||
}
|
||||
}
|
||||
else if (ipv6_prefix_ll_match(&ipv6_buf->destaddr)) {
|
||||
else if (ipv6_addr_is_link_local(&ipv6_buf->destaddr)) {
|
||||
if (memcmp(&(ipv6_buf->destaddr.uint8[8]), &(dest->uint8[0]), 8) == 0) {
|
||||
/* 0 bits. The address is derived using context information
|
||||
* and possibly the link-layer addresses.*/
|
||||
lowpan_iphc[1] |= 0x03;
|
||||
}
|
||||
else if ((ipv6_buf->destaddr.uint16[4] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[5] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[6] == 0) &&
|
||||
((ipv6_buf->destaddr.uint8[14]) & 0x80) == 0) {
|
||||
(ipv6_buf->destaddr.uint16[5] == 0) &&
|
||||
(ipv6_buf->destaddr.uint16[6] == 0) &&
|
||||
((ipv6_buf->destaddr.uint8[14]) & 0x80) == 0) {
|
||||
/* 49-bit of interface identifier are 0, so we can compress
|
||||
* source address-iid to 16-bit */
|
||||
memcpy(&ipv6_hdr_fields[hdr_pos], &ipv6_buf->destaddr.uint16[7], 2);
|
||||
@ -979,7 +1093,7 @@ void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra,
|
||||
comp_buf[1] = lowpan_iphc[1];
|
||||
|
||||
/*uint8_t *ptr;
|
||||
if (ipv6_buf->nextheader == IPPROTO_TCP)
|
||||
if (ipv6_buf->nextheader == IPV6_PROTO_NUM_TCP)
|
||||
{
|
||||
ptr = get_payload_buf_send(ipv6_ext_hdr_len);
|
||||
}
|
||||
@ -1008,22 +1122,22 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
uint8_t m_prefix[2] = {0xff, 0x02};
|
||||
lowpan_context_t *con = NULL;
|
||||
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
ipv6_buf = ipv6_get_buf();
|
||||
|
||||
lowpan_iphc[0] = ipv6_hdr_fields[0];
|
||||
lowpan_iphc[1] = ipv6_hdr_fields[1];
|
||||
hdr_pos += 2;
|
||||
|
||||
/* first check if CID flag is set */
|
||||
if (lowpan_iphc[1] & LOWPAN_IPHC_CID) {
|
||||
if (lowpan_iphc[1] & SIXLOWPAN_IPHC2_CID) {
|
||||
hdr_pos++;
|
||||
cid = 1;
|
||||
}
|
||||
|
||||
/* TF: Traffic Class, Flow Label: */
|
||||
if (lowpan_iphc[0] & LOWPAN_IPHC_FL_C) {
|
||||
if (lowpan_iphc[0] & SIXLOWPAN_IPHC1_FL_C) {
|
||||
/* flowlabel is elided */
|
||||
if (lowpan_iphc[0] & LOWPAN_IPHC_TC_C) {
|
||||
if (lowpan_iphc[0] & SIXLOWPAN_IPHC1_TC_C) {
|
||||
/* traffic class is elided */
|
||||
ipv6_buf->version_trafficclass = 0x60;
|
||||
ipv6_buf->trafficclass_flowlabel = 0;
|
||||
@ -1041,7 +1155,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
}
|
||||
else {
|
||||
/* flowlabel carried inline */
|
||||
if (lowpan_iphc[0] & LOWPAN_IPHC_TC_C) {
|
||||
if (lowpan_iphc[0] & SIXLOWPAN_IPHC1_TC_C) {
|
||||
/* traffic class is elided */
|
||||
ipv6_buf->version_trafficclass = 0x60;
|
||||
/* ecn + 4 bit flowlabel*/
|
||||
@ -1066,7 +1180,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
}
|
||||
|
||||
/* NH: Next Header: */
|
||||
if (lowpan_iphc[0] & LOWPAN_IPHC_NH) {
|
||||
if (lowpan_iphc[0] & SIXLOWPAN_IPHC1_NH) {
|
||||
// TODO: next header decompression
|
||||
}
|
||||
else {
|
||||
@ -1076,7 +1190,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
|
||||
/* HLIM: Hop Limit: */
|
||||
if (lowpan_iphc[0] & 0x03) {
|
||||
switch(lowpan_iphc[0] & 0x03) {
|
||||
switch (lowpan_iphc[0] & 0x03) {
|
||||
case (0x01): {
|
||||
ipv6_buf->hoplimit = 1;
|
||||
break;
|
||||
@ -1102,7 +1216,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
}
|
||||
|
||||
/* CID: Context Identifier Extension: + SAC: Source Address Compression */
|
||||
if (lowpan_iphc[1] & LOWPAN_IPHC_SAC) {
|
||||
if (lowpan_iphc[1] & SIXLOWPAN_IPHC2_SAC) {
|
||||
/* 1: Source address compression uses stateful, context-based
|
||||
* compression.*/
|
||||
if (cid) {
|
||||
@ -1112,7 +1226,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
mutex_lock(&lowpan_context_mutex);
|
||||
|
||||
/* check context number */
|
||||
if (((lowpan_iphc[1] & LOWPAN_IPHC_SAM) >> 4) & 0x03) {
|
||||
if (((lowpan_iphc[1] & SIXLOWPAN_IPHC2_SAM) >> 4) & 0x03) {
|
||||
con = lowpan_context_num_lookup(sci);
|
||||
}
|
||||
|
||||
@ -1121,7 +1235,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
return;
|
||||
}
|
||||
|
||||
switch(((lowpan_iphc[1] & LOWPAN_IPHC_SAM) >> 4) & 0x03) {
|
||||
switch (((lowpan_iphc[1] & SIXLOWPAN_IPHC2_SAM) >> 4) & 0x03) {
|
||||
case (0x01): {
|
||||
/* 64-bits */
|
||||
memcpy(&(ipv6_buf->srcaddr.uint8[8]), &ipv6_hdr_fields[hdr_pos], 8);
|
||||
@ -1163,7 +1277,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
mutex_unlock(&lowpan_context_mutex);
|
||||
}
|
||||
else {
|
||||
switch(((lowpan_iphc[1] & LOWPAN_IPHC_SAM) >> 4) & 0x03) {
|
||||
switch (((lowpan_iphc[1] & SIXLOWPAN_IPHC2_SAM) >> 4) & 0x03) {
|
||||
case (0x01): {
|
||||
/* 64-bits */
|
||||
memcpy(&(ipv6_buf->srcaddr.uint8[0]), &ll_prefix[0], 2);
|
||||
@ -1201,9 +1315,9 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
}
|
||||
|
||||
/* M: Multicast Compression + DAC: Destination Address Compression */
|
||||
if (lowpan_iphc[1] & LOWPAN_IPHC_M) {
|
||||
if (lowpan_iphc[1] & SIXLOWPAN_IPHC2_M) {
|
||||
/* 1: Destination address is a multicast address. */
|
||||
if (lowpan_iphc[1] & LOWPAN_IPHC_DAC) {
|
||||
if (lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAC) {
|
||||
/* 1: Destination address compression uses stateful, context-based
|
||||
* compression.
|
||||
* If M=1 and DAC=1: */
|
||||
@ -1213,7 +1327,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
|
||||
mutex_lock(&lowpan_context_mutex);
|
||||
|
||||
if ((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) {
|
||||
if ((lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAM) & 0x03) {
|
||||
con = lowpan_context_num_lookup(dci);
|
||||
}
|
||||
|
||||
@ -1227,7 +1341,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
}
|
||||
else {
|
||||
/* If M=1 and DAC=0: */
|
||||
switch(lowpan_iphc[1] & 0x03) {
|
||||
switch (lowpan_iphc[1] & 0x03) {
|
||||
case (0x01): {
|
||||
m_prefix[1] = ipv6_hdr_fields[hdr_pos];
|
||||
hdr_pos++;
|
||||
@ -1244,7 +1358,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
break;
|
||||
}
|
||||
|
||||
switch(lowpan_iphc[1] & 0x03) {
|
||||
switch (lowpan_iphc[1] & 0x03) {
|
||||
case (0x01): {
|
||||
memcpy(&(ipv6_buf->destaddr.uint8[0]), &m_prefix[0], 2);
|
||||
memset(&(ipv6_buf->destaddr.uint8[2]), 0, 9);
|
||||
@ -1277,7 +1391,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (lowpan_iphc[1] & LOWPAN_IPHC_DAC) {
|
||||
if (lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAC) {
|
||||
/* 1: Destination address compression uses stateful, context-based
|
||||
* compression.
|
||||
* If M=1 and DAC=1: */
|
||||
@ -1287,7 +1401,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
|
||||
mutex_lock(&lowpan_context_mutex);
|
||||
|
||||
if ((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) {
|
||||
if ((lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAM) & 0x03) {
|
||||
con = lowpan_context_num_lookup(dci);
|
||||
}
|
||||
|
||||
@ -1296,7 +1410,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
return;
|
||||
}
|
||||
|
||||
switch((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) {
|
||||
switch ((lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAM) & 0x03) {
|
||||
case (0x01): {
|
||||
memcpy(&(ipv6_buf->destaddr.uint8[8]), &ipv6_hdr_fields[hdr_pos], 8);
|
||||
/* By draft-ietf-6lowpan-hc-15 3.1.1. Bits covered by context information are always used. */
|
||||
@ -1329,7 +1443,7 @@ void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
mutex_unlock(&lowpan_context_mutex);
|
||||
}
|
||||
else {
|
||||
switch((lowpan_iphc[1] & LOWPAN_IPHC_DAM) & 0x03) {
|
||||
switch ((lowpan_iphc[1] & SIXLOWPAN_IPHC2_DAM) & 0x03) {
|
||||
case (0x01): {
|
||||
memcpy(&(ipv6_buf->destaddr.uint8[0]), &ll_prefix[0], 2);
|
||||
memset(&(ipv6_buf->destaddr.uint8[2]), 0, 6);
|
||||
@ -1383,7 +1497,7 @@ void lowpan_context_remove(uint8_t num)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < LOWPAN_CONTEXT_MAX; i++) {
|
||||
for (i = 0; i < NDP_6LOWPAN_CONTEXT_MAX; i++) {
|
||||
if (contexts[i].num == num) {
|
||||
context_len--;
|
||||
break;
|
||||
@ -1392,7 +1506,7 @@ void lowpan_context_remove(uint8_t num)
|
||||
|
||||
abr_remove_context(num);
|
||||
|
||||
for (j = i; j < LOWPAN_CONTEXT_MAX; j++) {
|
||||
for (j = i; j < NDP_6LOWPAN_CONTEXT_MAX; j++) {
|
||||
contexts[j] = contexts[j + 1];
|
||||
}
|
||||
}
|
||||
@ -1408,7 +1522,7 @@ lowpan_context_t *lowpan_context_update(uint8_t num, const ipv6_addr_t *prefix,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (context_len == LOWPAN_CONTEXT_MAX) {
|
||||
if (context_len == NDP_6LOWPAN_CONTEXT_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1441,7 +1555,7 @@ lowpan_context_t *lowpan_context_lookup(ipv6_addr_t *addr)
|
||||
|
||||
for (i = 0; i < lowpan_context_len(); i++) {
|
||||
if (contexts[i].length > 0 && memcmp((void *)addr, &(contexts[i].prefix),
|
||||
contexts[i].length) == 0) {
|
||||
contexts[i].length) == 0) {
|
||||
/* longer prefixes are always prefered */
|
||||
if (context == NULL || context->length < contexts[i].length) {
|
||||
context = &contexts[i];
|
||||
@ -1469,7 +1583,7 @@ void lowpan_context_auto_remove(void)
|
||||
{
|
||||
timex_t minute = timex_set(60, 0);
|
||||
int i;
|
||||
int8_t to_remove[LOWPAN_CONTEXT_MAX];
|
||||
int8_t to_remove[NDP_6LOWPAN_CONTEXT_MAX];
|
||||
int8_t to_remove_size;
|
||||
|
||||
while (1) {
|
||||
@ -1493,8 +1607,8 @@ void lowpan_context_auto_remove(void)
|
||||
|
||||
void init_reas_bufs(lowpan_reas_buf_t *buf)
|
||||
{
|
||||
memset(&buf->s_laddr, 0, SIXLOWPAN_IPV6_LL_ADDR_LEN);
|
||||
memset(&buf->d_laddr, 0, SIXLOWPAN_IPV6_LL_ADDR_LEN);
|
||||
memset(&buf->s_laddr, 0, IPV6_LL_ADDR_LEN);
|
||||
memset(&buf->d_laddr, 0, IPV6_LL_ADDR_LEN);
|
||||
buf->ident_no = 0;
|
||||
buf->timestamp = 0;
|
||||
buf->packet_size = 0;
|
||||
@ -1504,19 +1618,20 @@ void init_reas_bufs(lowpan_reas_buf_t *buf)
|
||||
buf->next = NULL;
|
||||
}
|
||||
|
||||
void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border)
|
||||
void sixlowpan_lowpan_init(transceiver_type_t trans, uint8_t r_addr,
|
||||
int as_border)
|
||||
{
|
||||
ipv6_addr_t tmp;
|
||||
short i;
|
||||
|
||||
/* init mac-layer and radio transceiver */
|
||||
sixlowmac_init(trans);
|
||||
sixlowpan_mac_init(trans);
|
||||
|
||||
/* init interface addresses */
|
||||
memset(&iface, 0, sizeof(iface_t));
|
||||
set_radio_address(r_addr);
|
||||
init_802154_short_addr(&(iface.saddr));
|
||||
init_802154_long_addr(&(iface.laddr));
|
||||
/* init global buffer mutex */
|
||||
mutex_init(&buf_mutex);
|
||||
sixlowpan_mac_set_radio_address(r_addr);
|
||||
sixlowpan_mac_init_802154_short_addr(&(iface.saddr));
|
||||
sixlowpan_mac_init_802154_long_addr(&(iface.laddr));
|
||||
|
||||
/* init lowpan context mutex */
|
||||
mutex_init(&lowpan_context_mutex);
|
||||
@ -1527,20 +1642,20 @@ void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border)
|
||||
local_address = r_addr;
|
||||
|
||||
/* init link-local address */
|
||||
ipv6_set_ll_prefix(&lladdr);
|
||||
ipv6_addr_set_link_local_prefix(&lladdr);
|
||||
|
||||
memcpy(&(lladdr.uint8[8]), &(iface.laddr.uint8[0]), 8);
|
||||
ipv6_iface_add_addr(&lladdr, ADDR_STATE_PREFERRED, 0, 0,
|
||||
ADDR_TYPE_LINK_LOCAL);
|
||||
ipv6_set_loaddr(&tmp);
|
||||
ipv6_iface_add_addr(&tmp, ADDR_STATE_PREFERRED, 0, 0,
|
||||
ADDR_TYPE_LOOPBACK);
|
||||
ipv6_set_all_nds_mcast_addr(&tmp);
|
||||
ipv6_iface_add_addr(&tmp, ADDR_STATE_PREFERRED, 0, 0,
|
||||
ADDR_TYPE_LOOPBACK);
|
||||
ipv6_iface_add_addr(&lladdr, IPV6_ADDR_TYPE_LINK_LOCAL,
|
||||
NDP_ADDR_STATE_PREFERRED, 0, 0);
|
||||
ipv6_addr_set_loopback_addr(&tmp);
|
||||
ipv6_iface_add_addr(&tmp, IPV6_ADDR_TYPE_LOOPBACK,
|
||||
NDP_ADDR_STATE_PREFERRED, 0, 0);
|
||||
ipv6_addr_set_all_nodes_addr(&tmp);
|
||||
ipv6_iface_add_addr(&tmp, IPV6_ADDR_TYPE_LOOPBACK,
|
||||
NDP_ADDR_STATE_PREFERRED, 0, 0);
|
||||
|
||||
ipv6_iface_add_addr(&lladdr, ADDR_STATE_PREFERRED, 0, 0,
|
||||
ADDR_CONFIGURED_AUTO);
|
||||
ipv6_iface_add_addr(&lladdr, IPV6_ADDR_TYPE_LINK_LOCAL,
|
||||
NDP_ADDR_STATE_PREFERRED, 0, 0);
|
||||
|
||||
if (as_border) {
|
||||
ip_process_pid = thread_create(ip_process_buf, IP_PROCESS_STACKSIZE,
|
||||
@ -1563,14 +1678,29 @@ void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border)
|
||||
transfer_pid = thread_create(lowpan_transfer_buf, LOWPAN_TRANSFER_BUF_STACKSIZE,
|
||||
PRIORITY_MAIN - 1, CREATE_STACKTEST,
|
||||
lowpan_transfer, "lowpan_transfer");
|
||||
|
||||
for (i = 0; i < SIXLOWIP_MAX_REGISTERED; i++) {
|
||||
sixlowip_reg[i] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void sixlowpan_adhoc_init(transceiver_type_t trans, ipv6_addr_t *prefix,
|
||||
uint8_t r_addr)
|
||||
void sixlowpan_lowpan_adhoc_init(transceiver_type_t trans,
|
||||
const ipv6_addr_t *prefix,
|
||||
uint8_t r_addr)
|
||||
{
|
||||
/* init network prefix */
|
||||
ipv6_set_prefix(prefix, prefix);
|
||||
plist_add(prefix, 64, OPT_PI_VLIFETIME_INFINITE, 0, 1, OPT_PI_FLAG_A);
|
||||
ipv6_addr_t save_prefix;
|
||||
ipv6_addr_init_prefix(&save_prefix, prefix, 64);
|
||||
plist_add(&save_prefix, 64, NDP_OPT_PI_VLIFETIME_INFINITE, 0, 1,
|
||||
ICMPV6_NDP_OPT_PI_FLAG_AUTONOM);
|
||||
ipv6_init_iface_as_router();
|
||||
sixlowpan_init(trans, r_addr, 0);
|
||||
sixlowpan_lowpan_init(trans, r_addr, 0);
|
||||
}
|
||||
|
||||
void sixlowpan_lowpan_bootstrapping(void)
|
||||
{
|
||||
|
||||
icmpv6_send_router_sol(OPT_SLLAO);
|
||||
}
|
||||
|
||||
53
sys/net/sixlowpan/lowpan.h
Normal file
53
sys/net/sixlowpan/lowpan.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 6LoWPAN constants, data structs, and prototypes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowpan.h
|
||||
* @brief 6lowpan header
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef _SIXLOWPAN_LOWPAN_H
|
||||
#define _SIXLOWPAN_LOWPAN_H
|
||||
|
||||
#include "mutex.h"
|
||||
#include "vtimer.h"
|
||||
|
||||
#include "sixlowpan/lowpan.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t num;
|
||||
ipv6_addr_t prefix;
|
||||
uint8_t length;
|
||||
uint8_t comp;
|
||||
uint16_t lifetime;
|
||||
} lowpan_context_t;
|
||||
|
||||
extern uint16_t local_address;
|
||||
extern mutex_t lowpan_context_mutex;
|
||||
|
||||
void lowpan_read(uint8_t *data, uint8_t length,
|
||||
ieee_802154_long_t *s_laddr,
|
||||
ieee_802154_long_t *d_laddr);
|
||||
uint8_t lowpan_context_len(void);
|
||||
lowpan_context_t *lowpan_context_update(uint8_t num,
|
||||
const ipv6_addr_t *prefix,
|
||||
uint8_t length, uint8_t comp,
|
||||
uint16_t lifetime);
|
||||
lowpan_context_t *lowpan_context_get(void);
|
||||
lowpan_context_t *lowpan_context_num_lookup(uint8_t num);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* _SIXLOWPAN_LOWPAN_H */
|
||||
@ -9,8 +9,8 @@
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowmac.c
|
||||
* @brief 6lowpan link layer functions
|
||||
* @file sixlowmac.c
|
||||
* @brief 6lowpan link layer functions
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
@ -21,26 +21,31 @@
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "sixlowmac.h"
|
||||
#include "sixlowip.h"
|
||||
#include "sixlownd.h"
|
||||
#include "sixlowpan.h"
|
||||
#include <ltc4150.h>
|
||||
#include <hwtimer.h>
|
||||
#include "ltc4150.h"
|
||||
#include "hwtimer.h"
|
||||
#include "thread.h"
|
||||
#include "msg.h"
|
||||
#include "radio/radio.h"
|
||||
#include "transceiver.h"
|
||||
#include "vtimer.h"
|
||||
#include "ieee802154/ieee802154_frame.h"
|
||||
#include "net_help/net_help.h"
|
||||
#include "sixlowpan/mac.h"
|
||||
|
||||
#include "ip.h"
|
||||
#include "icmp.h"
|
||||
#include "lowpan.h"
|
||||
#include "sys/net/ieee802154/ieee802154_frame.h"
|
||||
#include "sys/net/net_help/net_help.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#define RADIO_STACK_SIZE (MINIMUM_STACK_SIZE + 256)
|
||||
#define RADIO_RCV_BUF_SIZE (64)
|
||||
#define RADIO_SENDING_DELAY (1000)
|
||||
|
||||
char radio_stack_buffer[RADIO_STACK_SIZE];
|
||||
msg_t msg_q[RADIO_RCV_BUF_SIZE];
|
||||
|
||||
@ -52,9 +57,8 @@ static radio_packet_t p;
|
||||
static msg_t mesg;
|
||||
int transceiver_type;
|
||||
static transceiver_command_t tcmd;
|
||||
uint16_t fragmentcounter = 0;
|
||||
|
||||
uint8_t get_radio_address(void)
|
||||
uint8_t sixlowpan_mac_get_radio_address(void)
|
||||
{
|
||||
int16_t address;
|
||||
|
||||
@ -67,7 +71,7 @@ uint8_t get_radio_address(void)
|
||||
return (uint8_t)address;
|
||||
}
|
||||
|
||||
void set_radio_address(uint8_t addr)
|
||||
void sixlowpan_mac_set_radio_address(uint8_t addr)
|
||||
{
|
||||
int16_t address = (int16_t)addr;
|
||||
|
||||
@ -97,18 +101,18 @@ void switch_to_rx(void)
|
||||
msg_send(&mesg, transceiver_pid, 1);
|
||||
}
|
||||
|
||||
void init_802154_short_addr(ieee_802154_short_t *saddr)
|
||||
void sixlowpan_mac_init_802154_short_addr(ieee_802154_short_t *saddr)
|
||||
{
|
||||
saddr->uint8[0] = 0;
|
||||
saddr->uint8[1] = get_radio_address();
|
||||
saddr->uint8[1] = sixlowpan_mac_get_radio_address();
|
||||
}
|
||||
|
||||
ieee_802154_long_t *mac_get_eui(ipv6_addr_t *ipaddr)
|
||||
ieee_802154_long_t *sixlowpan_mac_get_eui64(const ipv6_addr_t *ipaddr)
|
||||
{
|
||||
return ((ieee_802154_long_t *) & (ipaddr->uint8[8]));
|
||||
return ((ieee_802154_long_t *) &(ipaddr->uint8[8]));
|
||||
}
|
||||
|
||||
void init_802154_long_addr(ieee_802154_long_t *laddr)
|
||||
void sixlowpan_mac_init_802154_long_addr(ieee_802154_long_t *laddr)
|
||||
{
|
||||
// 16bit Pan-ID:16-zero-bits:16-bit-short-addr = 48bit
|
||||
laddr->uint16[0] = IEEE_802154_PAN_ID;
|
||||
@ -120,7 +124,7 @@ void init_802154_long_addr(ieee_802154_long_t *laddr)
|
||||
laddr->uint8[4] = 0xFE;
|
||||
laddr->uint8[5] = 0;
|
||||
laddr->uint8[6] = 0;
|
||||
laddr->uint8[7] = get_radio_address();
|
||||
laddr->uint8[7] = sixlowpan_mac_get_radio_address();
|
||||
}
|
||||
|
||||
void recv_ieee802154_frame(void)
|
||||
@ -142,7 +146,6 @@ void recv_ieee802154_frame(void)
|
||||
length = p->length - hdrlen;
|
||||
|
||||
/* deliver packet to network(6lowpan)-layer */
|
||||
fragmentcounter++;
|
||||
lowpan_read(frame.payload, length, (ieee_802154_long_t *)&frame.src_addr,
|
||||
(ieee_802154_long_t *)&frame.dest_addr);
|
||||
|
||||
@ -180,8 +183,9 @@ void set_ieee802154_frame_values(ieee802154_frame_t *frame)
|
||||
macdsn++;
|
||||
}
|
||||
|
||||
void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload,
|
||||
uint8_t length, uint8_t mcast)
|
||||
void sixlowpan_mac_send_ieee802154_frame(const ieee_802154_long_t *addr,
|
||||
const uint8_t *payload,
|
||||
uint8_t length, uint8_t mcast)
|
||||
{
|
||||
uint16_t daddr;
|
||||
/* TODO: check if dedicated response struct is necessary */
|
||||
@ -204,7 +208,7 @@ void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload,
|
||||
memcpy(&(frame.src_addr[0]), &(iface.laddr.uint8[0]), 8);
|
||||
|
||||
daddr = HTONS(addr->uint16[3]);
|
||||
frame.payload = payload;
|
||||
frame.payload = (uint8_t *)payload; // payload won't be changed so cast is legal.
|
||||
frame.payload_len = length;
|
||||
uint8_t hdrlen = get_802154_hdr_len(&frame);
|
||||
|
||||
@ -213,9 +217,6 @@ void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload,
|
||||
memcpy(&buf[hdrlen], frame.payload, frame.payload_len);
|
||||
DEBUG("IEEE802.15.4 frame - FCF: %02X %02X DPID: %02X SPID: %02X DSN: %02X\n", buf[0], buf[1], frame->dest_pan_id, frame->src_pan_id, frame->seq_nr);
|
||||
|
||||
/* mutex unlock */
|
||||
mutex_unlock(&buf_mutex);
|
||||
|
||||
p.length = hdrlen + frame.payload_len;
|
||||
|
||||
if (mcast == 0) {
|
||||
@ -231,7 +232,7 @@ void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload,
|
||||
hwtimer_wait(5000);
|
||||
}
|
||||
|
||||
void sixlowmac_init(transceiver_type_t type)
|
||||
void sixlowpan_mac_init(transceiver_type_t type)
|
||||
{
|
||||
int recv_pid = thread_create(radio_stack_buffer, RADIO_STACK_SIZE,
|
||||
PRIORITY_MAIN - 2, CREATE_STACKTEST, recv_ieee802154_frame , "radio");
|
||||
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Semaphore implemenation
|
||||
* Semaphore implemenation
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
@ -16,8 +16,6 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <mutex.h>
|
||||
|
||||
#include "semaphore.h"
|
||||
|
||||
void sem_init(sem_t *sem, int8_t value)
|
||||
|
||||
@ -16,11 +16,12 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef SEMAPHORE_H
|
||||
#define SEMAPHORE_H
|
||||
#ifndef _SIXLOWPAN_SEMAPHORE_H
|
||||
#define _SIXLOWPAN_SEMAPHORE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <mutex.h>
|
||||
|
||||
#include "mutex.h"
|
||||
|
||||
typedef struct sem_t {
|
||||
int8_t value;
|
||||
@ -32,4 +33,4 @@ void sem_init(sem_t *sem, int8_t value);
|
||||
int sem_wait(sem_t *sem);
|
||||
int sem_signal(sem_t *sem);
|
||||
|
||||
#endif /* SEMAPHORE_H*/
|
||||
#endif /* _SIXLOWPAN_SEMAPHORE_H*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* serial number arithmetics (corresponding RFC1982) for version field in ABRO
|
||||
* serial number arithmetics (corresponding RFC1982) for version field in ABRO
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
@ -10,7 +10,7 @@
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file serialnumber.c
|
||||
* @brief serial number arithmetics (corresponding RFC1982) for version field in ABRO
|
||||
* @brief serial number arithmetics (corresponding RFC1982) for version field in ABRO
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @}
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
* Header file for serial number arithmetics [RFC1982]
|
||||
*/
|
||||
|
||||
#ifndef SERIALNUMBER_H
|
||||
#define SERIALNUMBER_H
|
||||
#ifndef _SIXLOWPAN_SERIALNUMBER_H
|
||||
#define _SIXLOWPAN_SERIALNUMBER_H
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum serial_comp_res_t {
|
||||
@ -79,4 +79,4 @@ serial_comp_res_t serial_comp16(uint16_t s1, uint16_t s2);
|
||||
**/
|
||||
serial_comp_res_t serial_comp32(uint32_t s1, uint32_t s2);
|
||||
|
||||
#endif /* SERIALNUMBER_H*/
|
||||
#endif /* _SIXLOWPAN_SERIALNUMBER_H*/
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
#ifndef SIXLOWERROR_H
|
||||
#define SIXLOWERROR_H
|
||||
|
||||
#define SUCCESS 0
|
||||
#define SIXLOWERROR_ARRAYFULL 132 // array is full
|
||||
#define SIXLOWERROR_NULLPTR 133 // null pointer error
|
||||
#define SIXLOWERROR_VALUE 134 // illegal value
|
||||
#define SIXLOWERROR_ADDRESS 135 // illegal address
|
||||
#define SIXLOWERROR_DISPATCH 136 // lowpan dispatch unknown
|
||||
#define SIXLOWERROR_FSTFRAG 137 // first lowpan fragment not received
|
||||
#define SIXLOWERROR_INVFRAG 138 // invalid fragment received
|
||||
#define SIXLOWERROR_SCI 139 // source context not found
|
||||
#define SIXLOWERROR_DCI 140 // destination context not found
|
||||
#define SIXLOWERROR_CSUM 141 // wrong checksum
|
||||
|
||||
#endif /* SIXLOWERROR_H*/
|
||||
@ -1,586 +0,0 @@
|
||||
/**
|
||||
* IPv6 implementation
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowip.c
|
||||
* @brief 6lowpan IP layer functions
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <vtimer.h>
|
||||
#include <mutex.h>
|
||||
#include "msg.h"
|
||||
#include "sixlowip.h"
|
||||
#include "sixlowmac.h"
|
||||
#include "sixlownd.h"
|
||||
#include "sixlowpan.h"
|
||||
#include "sys/net/destiny/in.h"
|
||||
#include "sys/net/destiny/socket.h"
|
||||
#include "sys/net/net_help/net_help.h"
|
||||
#include "sys/net/net_help/msg_help.h"
|
||||
|
||||
uint8_t ip_send_buffer[BUFFER_SIZE];
|
||||
uint8_t buffer[BUFFER_SIZE];
|
||||
msg_t msg_queue[IP_PKT_RECV_BUF_SIZE];
|
||||
ipv6_hdr_t *ipv6_buf;
|
||||
struct icmpv6_hdr_t *icmp_buf;
|
||||
uint8_t *nextheader;
|
||||
uint8_t iface_addr_list_count = 0;
|
||||
int udp_packet_handler_pid = 0;
|
||||
int tcp_packet_handler_pid = 0;
|
||||
int rpl_process_pid = 0;
|
||||
|
||||
ipv6_hdr_t *get_ipv6_buf_send(void)
|
||||
{
|
||||
return ((ipv6_hdr_t *) & (ip_send_buffer[LL_HDR_LEN]));
|
||||
}
|
||||
|
||||
uint8_t *get_payload_buf_send(uint8_t ext_len)
|
||||
{
|
||||
return &(ip_send_buffer[LLHDR_IPV6HDR_LEN + ext_len]);
|
||||
}
|
||||
|
||||
ipv6_hdr_t *get_ipv6_buf(void)
|
||||
{
|
||||
return ((ipv6_hdr_t *)&(buffer[LL_HDR_LEN]));
|
||||
}
|
||||
|
||||
struct icmpv6_hdr_t *get_icmpv6_buf(uint8_t ext_len)
|
||||
{
|
||||
return ((struct icmpv6_hdr_t *) & (buffer[LLHDR_IPV6HDR_LEN + ext_len]));
|
||||
}
|
||||
|
||||
uint8_t *get_payload_buf(uint8_t ext_len)
|
||||
{
|
||||
return &(buffer[LLHDR_IPV6HDR_LEN + ext_len]);
|
||||
}
|
||||
|
||||
void sixlowpan_bootstrapping(void)
|
||||
{
|
||||
|
||||
init_rtr_sol(OPT_SLLAO);
|
||||
}
|
||||
|
||||
void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len,
|
||||
uint8_t next_header)
|
||||
{
|
||||
uint8_t *p_ptr;
|
||||
|
||||
if (next_header == IPPROTO_TCP) {
|
||||
p_ptr = get_payload_buf_send(ipv6_ext_hdr_len);
|
||||
ipv6_buf = get_ipv6_buf_send();
|
||||
}
|
||||
else {
|
||||
ipv6_buf = get_ipv6_buf();
|
||||
p_ptr = get_payload_buf(ipv6_ext_hdr_len);
|
||||
}
|
||||
|
||||
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
|
||||
packet_length = 0;
|
||||
|
||||
ipv6_buf->version_trafficclass = IPV6_VER;
|
||||
ipv6_buf->trafficclass_flowlabel = 0;
|
||||
ipv6_buf->flowlabel = 0;
|
||||
ipv6_buf->nextheader = next_header;
|
||||
ipv6_buf->hoplimit = MULTIHOP_HOPLIMIT;
|
||||
ipv6_buf->length = p_len;
|
||||
|
||||
memcpy(&(ipv6_buf->destaddr), addr, 16);
|
||||
ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr));
|
||||
|
||||
memcpy(p_ptr, payload, p_len);
|
||||
|
||||
packet_length = IPV6_HDR_LEN + p_len;
|
||||
|
||||
lowpan_init((ieee_802154_long_t *)&(ipv6_buf->destaddr.uint16[4]),
|
||||
(uint8_t *)ipv6_buf);
|
||||
}
|
||||
|
||||
int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr)
|
||||
{
|
||||
switch(hdr->type) {
|
||||
case (ICMP_RTR_SOL): {
|
||||
puts("INFO: packet type: icmp router solicitation");
|
||||
/* processing router solicitation */
|
||||
recv_rtr_sol();
|
||||
/* init solicited router advertisment*/
|
||||
break;
|
||||
}
|
||||
|
||||
case (ICMP_RTR_ADV): {
|
||||
puts("INFO: packet type: icmp router advertisment");
|
||||
/* processing router advertisment */
|
||||
recv_rtr_adv();
|
||||
/* init neighbor solicitation */
|
||||
break;
|
||||
}
|
||||
|
||||
case (ICMP_NBR_SOL): {
|
||||
puts("INFO: packet type: icmp neighbor solicitation");
|
||||
recv_nbr_sol();
|
||||
break;
|
||||
}
|
||||
|
||||
case (ICMP_NBR_ADV): {
|
||||
puts("INFO: packet type: icmp neighbor advertisment");
|
||||
recv_nbr_adv();
|
||||
break;
|
||||
}
|
||||
|
||||
case (ICMP_RPL_CONTROL): {
|
||||
puts("INFO: packet type: RPL message");
|
||||
|
||||
if (rpl_process_pid != 0) {
|
||||
msg_t m_send;
|
||||
m_send.content.ptr = (char *) &hdr->code;
|
||||
msg_send(&m_send, rpl_process_pid, 1);
|
||||
}
|
||||
else {
|
||||
puts("INFO: no RPL handler registered");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ipv6_process(void)
|
||||
{
|
||||
msg_t m_recv_lowpan, m_send_lowpan;
|
||||
msg_t m_recv, m_send;
|
||||
ipv6_addr_t myaddr;
|
||||
ipv6_init_address(&myaddr, 0xabcd, 0x0, 0x0, 0x0, 0x3612, 0x00ff, 0xfe00,
|
||||
get_radio_address());
|
||||
|
||||
while (1) {
|
||||
msg_receive(&m_recv_lowpan);
|
||||
|
||||
ipv6_buf = (ipv6_hdr_t *)m_recv_lowpan.content.ptr;
|
||||
|
||||
/* identifiy packet */
|
||||
nextheader = &ipv6_buf->nextheader;
|
||||
|
||||
if ((ipv6_get_addr_match(&myaddr, &ipv6_buf->destaddr) >= 112) &&
|
||||
(ipv6_buf->destaddr.uint8[15] != myaddr.uint8[15])) {
|
||||
memcpy(get_ipv6_buf_send(), get_ipv6_buf(),
|
||||
IPV6_HDR_LEN + ipv6_buf->length);
|
||||
lowpan_init((ieee_802154_long_t *)&(ipv6_buf->destaddr.uint16[4]),
|
||||
(uint8_t *)get_ipv6_buf_send());
|
||||
}
|
||||
else {
|
||||
switch(*nextheader) {
|
||||
case (PROTO_NUM_ICMPV6): {
|
||||
/* checksum test*/
|
||||
if (icmpv6_csum(PROTO_NUM_ICMPV6) != 0xffff) {
|
||||
printf("ERROR: wrong checksum\n");
|
||||
}
|
||||
|
||||
icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len);
|
||||
icmpv6_demultiplex(icmp_buf);
|
||||
break;
|
||||
}
|
||||
|
||||
case (IPPROTO_TCP): {
|
||||
if (tcp_packet_handler_pid != 0) {
|
||||
m_send.content.ptr = (char *) ipv6_buf;
|
||||
msg_send_receive(&m_send, &m_recv, tcp_packet_handler_pid);
|
||||
}
|
||||
else {
|
||||
printf("INFO: No TCP handler registered.\n");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case (IPPROTO_UDP): {
|
||||
if (udp_packet_handler_pid != 0) {
|
||||
m_send.content.ptr = (char *) ipv6_buf;
|
||||
msg_send_receive(&m_send, &m_recv, udp_packet_handler_pid);
|
||||
}
|
||||
else {
|
||||
printf("INFO: No UDP handler registered.\n");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case (PROTO_NUM_NONE): {
|
||||
printf("INFO: Packet with no Header following the IPv6 Header received.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
msg_reply(&m_recv_lowpan, &m_send_lowpan);
|
||||
}
|
||||
}
|
||||
|
||||
void ipv6_iface_add_addr(ipv6_addr_t *addr, uint8_t state, uint32_t val_ltime,
|
||||
uint32_t pref_ltime, uint8_t type)
|
||||
{
|
||||
if (ipv6_addr_unspec_match(addr) == 128) {
|
||||
printf("ERROR: unspecified address (::) can't be assigned to interface.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ipv6_iface_addr_match(addr) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (iface_addr_list_count < IFACE_ADDR_LIST_LEN) {
|
||||
memcpy(&(iface.addr_list[iface_addr_list_count].addr.uint8[0]),
|
||||
&(addr->uint8[0]), 16);
|
||||
iface.addr_list[iface_addr_list_count].state = state;
|
||||
timex_t valtime = {val_ltime, 0};
|
||||
timex_t preftime = {pref_ltime, 0};
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
iface.addr_list[iface_addr_list_count].val_ltime = timex_add(now, valtime);
|
||||
iface.addr_list[iface_addr_list_count].pref_ltime = timex_add(now, preftime);
|
||||
iface.addr_list[iface_addr_list_count].type = type;
|
||||
iface_addr_list_count++;
|
||||
|
||||
/* Register to Solicited-Node multicast address according to RFC 4291 */
|
||||
if (type == ADDR_TYPE_ANYCAST || type == ADDR_TYPE_LINK_LOCAL ||
|
||||
type == ADDR_TYPE_GLOBAL || type == ADDR_TYPE_UNICAST) {
|
||||
ipv6_addr_t sol_node_mcast_addr;
|
||||
ipv6_set_sol_node_mcast_addr(addr, &sol_node_mcast_addr);
|
||||
|
||||
if (ipv6_iface_addr_match(&sol_node_mcast_addr) == NULL) {
|
||||
ipv6_iface_add_addr(&sol_node_mcast_addr, state, val_ltime, pref_ltime, ADDR_TYPE_SOL_NODE_MCAST);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addr_list_t *ipv6_iface_addr_match(ipv6_addr_t *addr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < iface_addr_list_count; i++) {
|
||||
if (memcmp(&(iface.addr_list[i].addr.uint8[0]),
|
||||
&(addr->uint8[0]), 16) == 0) {
|
||||
return &(iface.addr_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
addr_list_t *ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < iface_addr_list_count; i++) {
|
||||
if (memcmp(&(iface.addr_list[i].addr.uint8[0]),
|
||||
&(addr->uint8[0]), 8) == 0) {
|
||||
return &(iface.addr_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ipv6_iface_print_addrs(void)
|
||||
{
|
||||
for (int i = 0; i < iface_addr_list_count; i++) {
|
||||
ipv6_print_addr(&(iface.addr_list[i].addr));
|
||||
}
|
||||
}
|
||||
|
||||
void ipv6_init_addr_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix)
|
||||
{
|
||||
inout->uint16[0] = prefix->uint16[0];
|
||||
inout->uint16[1] = prefix->uint16[1];
|
||||
inout->uint16[2] = prefix->uint16[2];
|
||||
inout->uint16[3] = prefix->uint16[3];
|
||||
|
||||
memcpy(&(inout->uint8[8]), &(iface.laddr.uint8[0]), 8);
|
||||
}
|
||||
|
||||
void ipv6_set_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix)
|
||||
{
|
||||
inout->uint16[0] = prefix->uint16[0];
|
||||
inout->uint16[1] = prefix->uint16[1];
|
||||
inout->uint16[2] = prefix->uint16[2];
|
||||
inout->uint16[3] = prefix->uint16[3];
|
||||
inout->uint16[4] = 0;
|
||||
inout->uint16[5] = 0;
|
||||
inout->uint16[6] = 0;
|
||||
inout->uint16[7] = 0;
|
||||
}
|
||||
|
||||
void ipv6_set_all_rtrs_mcast_addr(ipv6_addr_t *ipaddr)
|
||||
{
|
||||
ipaddr->uint16[0] = HTONS(0xff02);
|
||||
ipaddr->uint16[1] = 0;
|
||||
ipaddr->uint16[2] = 0;
|
||||
ipaddr->uint16[3] = 0;
|
||||
ipaddr->uint16[4] = 0;
|
||||
ipaddr->uint16[5] = 0;
|
||||
ipaddr->uint16[6] = 0;
|
||||
ipaddr->uint16[7] = HTONS(0x0002);
|
||||
}
|
||||
|
||||
void ipv6_set_all_nds_mcast_addr(ipv6_addr_t *ipaddr)
|
||||
{
|
||||
ipaddr->uint16[0] = HTONS(0xff02);
|
||||
ipaddr->uint16[1] = 0;
|
||||
ipaddr->uint16[2] = 0;
|
||||
ipaddr->uint16[3] = 0;
|
||||
ipaddr->uint16[4] = 0;
|
||||
ipaddr->uint16[5] = 0;
|
||||
ipaddr->uint16[6] = 0;
|
||||
ipaddr->uint16[7] = HTONS(0x0001);
|
||||
}
|
||||
|
||||
void ipv6_set_loaddr(ipv6_addr_t *ipaddr)
|
||||
{
|
||||
ipaddr->uint16[0] = 0;
|
||||
ipaddr->uint16[1] = 0;
|
||||
ipaddr->uint16[2] = 0;
|
||||
ipaddr->uint16[3] = 0;
|
||||
ipaddr->uint16[4] = 0;
|
||||
ipaddr->uint16[5] = 0;
|
||||
ipaddr->uint16[6] = 0;
|
||||
ipaddr->uint16[7] = HTONS(0x0001);
|
||||
}
|
||||
|
||||
void ipv6_get_saddr(ipv6_addr_t *src, ipv6_addr_t *dst)
|
||||
{
|
||||
/* try to find best match if dest is not mcast or link local */
|
||||
int8_t itmp = -1;
|
||||
uint8_t tmp = 0;
|
||||
uint8_t bmatch = 0;
|
||||
|
||||
if (!(ipv6_prefix_ll_match(dst)) && !(ipv6_prefix_mcast_match(dst))) {
|
||||
for (int i = 0; i < IFACE_ADDR_LIST_LEN; i++) {
|
||||
if (iface.addr_list[i].state == ADDR_STATE_PREFERRED) {
|
||||
if (!(ipv6_prefix_ll_match(&(iface.addr_list[i].addr)))) {
|
||||
tmp = ipv6_get_addr_match(dst, &(iface.addr_list[i].addr));
|
||||
|
||||
if (tmp >= bmatch) {
|
||||
bmatch = tmp;
|
||||
itmp = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int j = 0; j < IFACE_ADDR_LIST_LEN; j++) {
|
||||
if ((iface.addr_list[j].state == ADDR_STATE_PREFERRED) &&
|
||||
ipv6_prefix_ll_match(&(iface.addr_list[j].addr))) {
|
||||
itmp = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (itmp == -1) {
|
||||
memset(src, 0, 16);
|
||||
}
|
||||
else {
|
||||
memcpy(src, &(iface.addr_list[itmp].addr), 16);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ipv6_get_addr_match(ipv6_addr_t *src, ipv6_addr_t *dst)
|
||||
{
|
||||
uint8_t val = 0, xor;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
/* if bytes are equal add 8 */
|
||||
if (src->uint8[i] == dst->uint8[i]) {
|
||||
val += 8;
|
||||
}
|
||||
else {
|
||||
xor = src->uint8[i] ^ dst->uint8[i];
|
||||
|
||||
/* while bits from byte equal add 1 */
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if ((xor & 0x80) == 0) {
|
||||
val++;
|
||||
xor = xor << 1;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void ipv6_set_ll_prefix(ipv6_addr_t *ipaddr)
|
||||
{
|
||||
ipaddr->uint16[0] = HTONS(0xfe80);
|
||||
ipaddr->uint16[1] = 0;
|
||||
ipaddr->uint16[2] = 0;
|
||||
ipaddr->uint16[3] = 0;
|
||||
}
|
||||
|
||||
void ipv6_init_address(ipv6_addr_t *addr, uint16_t addr0, uint16_t addr1,
|
||||
uint16_t addr2, uint16_t addr3, uint16_t addr4,
|
||||
uint16_t addr5, uint16_t addr6, uint16_t addr7)
|
||||
{
|
||||
addr->uint16[0] = HTONS(addr0);
|
||||
addr->uint16[1] = HTONS(addr1);
|
||||
addr->uint16[2] = HTONS(addr2);
|
||||
addr->uint16[3] = HTONS(addr3);
|
||||
addr->uint16[4] = HTONS(addr4);
|
||||
addr->uint16[5] = HTONS(addr5);
|
||||
addr->uint16[6] = HTONS(addr6);
|
||||
addr->uint16[7] = HTONS(addr7);
|
||||
}
|
||||
|
||||
uint8_t ipv6_prefix_ll_match(ipv6_addr_t *addr)
|
||||
{
|
||||
if (addr->uint8[0] == 0xfe && addr->uint8[1] == 0x80) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ipv6_prefix_mcast_match(ipv6_addr_t *addr)
|
||||
{
|
||||
if (addr->uint8[0] == 0xff && addr->uint8[1] == 0x02) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ipv6_addr_unspec_match(ipv6_addr_t *addr)
|
||||
{
|
||||
if ((addr->uint16[0] == 0) && (addr->uint16[1] == 0) &&
|
||||
(addr->uint16[2] == 0) && (addr->uint16[3] == 0) &&
|
||||
(addr->uint16[4] == 0) && (addr->uint16[5] == 0) &&
|
||||
(addr->uint16[6] == 0) && (addr->uint16[7] == 0)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ipv6_addr_sol_node_mcast_match(ipv6_addr_t *addr)
|
||||
{
|
||||
/* note: cool if-condition*/
|
||||
if ((addr->uint8[0] == 0xFF) && (addr->uint8[1] == 0x02) &&
|
||||
(addr->uint16[1] == 0x00) && (addr->uint16[2] == 0x00) &&
|
||||
(addr->uint16[3] == 0x00) && (addr->uint16[4] == 0x00) &&
|
||||
(addr->uint8[10] == 0x00) && (addr->uint8[11] == 0x01) &&
|
||||
(addr->uint8[12] == 0xFF)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ipv6_set_sol_node_mcast_addr(ipv6_addr_t *addr_in, ipv6_addr_t *addr_out)
|
||||
{
|
||||
/* copy only the last 24-bit of the ip-address that is beeing resolved */
|
||||
addr_out->uint16[0] = HTONS(0xff02);
|
||||
addr_out->uint16[1] = 0;
|
||||
addr_out->uint16[2] = 0;
|
||||
addr_out->uint16[3] = 0;
|
||||
addr_out->uint16[4] = 0;
|
||||
addr_out->uint16[5] = HTONS(0x0001);
|
||||
addr_out->uint8[12] = 0xff;
|
||||
addr_out->uint8[13] = addr_in->uint8[13];
|
||||
addr_out->uint16[7] = addr_in->uint16[7];
|
||||
}
|
||||
|
||||
void ipv6_print_addr(ipv6_addr_t *ipaddr)
|
||||
{
|
||||
printf("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
|
||||
((uint8_t *)ipaddr)[0], ((uint8_t *)ipaddr)[1], ((uint8_t *)ipaddr)[2],
|
||||
((uint8_t *)ipaddr)[3], ((uint8_t *)ipaddr)[4], ((uint8_t *)ipaddr)[5],
|
||||
((uint8_t *)ipaddr)[6], ((uint8_t *)ipaddr)[7], ((uint8_t *)ipaddr)[8],
|
||||
((uint8_t *)ipaddr)[9], ((uint8_t *)ipaddr)[10], ((uint8_t *)ipaddr)[11],
|
||||
((uint8_t *)ipaddr)[12], ((uint8_t *)ipaddr)[13], ((uint8_t *)ipaddr)[14],
|
||||
((uint8_t *)ipaddr)[15]);
|
||||
}
|
||||
|
||||
uint8_t ipv6_next_hdr_unknown(uint8_t next_hdr)
|
||||
{
|
||||
return next_hdr == PROTO_NUM_ICMPV6 ||
|
||||
next_hdr == PROTO_NUM_NONE;
|
||||
}
|
||||
|
||||
|
||||
uint32_t get_remaining_time(timex_t *t)
|
||||
{
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
|
||||
return (timex_sub(*t, now).seconds);
|
||||
}
|
||||
|
||||
void set_remaining_time(timex_t *t, uint32_t time)
|
||||
{
|
||||
timex_t tmp = {time, 0};
|
||||
|
||||
timex_t now;
|
||||
vtimer_now(&now);
|
||||
*t = timex_add(now, tmp);
|
||||
}
|
||||
|
||||
void ipv6_init_iface_as_router(void)
|
||||
{
|
||||
ipv6_addr_t addr;
|
||||
|
||||
ipv6_set_all_rtrs_mcast_addr(&addr);
|
||||
ipv6_iface_add_addr(&addr, ADDR_STATE_PREFERRED, 0, 0, ADDR_TYPE_MULTICAST);
|
||||
}
|
||||
|
||||
|
||||
uint8_t ipv6_is_router(void)
|
||||
{
|
||||
ipv6_addr_t addr;
|
||||
|
||||
ipv6_set_all_rtrs_mcast_addr(&addr);
|
||||
|
||||
if (ipv6_iface_addr_match(&addr) != NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_tcp_packet_handler_pid(int pid)
|
||||
{
|
||||
tcp_packet_handler_pid = pid;
|
||||
}
|
||||
|
||||
void set_udp_packet_handler_pid(int pid)
|
||||
{
|
||||
udp_packet_handler_pid = pid;
|
||||
}
|
||||
|
||||
void set_rpl_process_pid(int pid)
|
||||
{
|
||||
rpl_process_pid = pid;
|
||||
}
|
||||
@ -1,188 +0,0 @@
|
||||
/**
|
||||
* IPv6 constants, data structs, and prototypes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowip.h
|
||||
* @brief 6lowpan IP layer header
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* 6LoWPAN IP header file */
|
||||
|
||||
#ifndef SIXLOWIP_H
|
||||
#define SIXLOWIP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <timex.h>
|
||||
#include <mutex.h>
|
||||
|
||||
/* set maximum transmission unit */
|
||||
#define MTU 256
|
||||
/* IPv6 field values */
|
||||
#define IPV6_VER 0x60
|
||||
#define PROTO_NUM_ICMPV6 58
|
||||
#define PROTO_NUM_NONE 59
|
||||
#define ND_HOPLIMIT 0xFF
|
||||
#define SIXLOWPAN_IPV6_LL_ADDR_LEN 8
|
||||
/* size of global buffer */
|
||||
#define BUFFER_SIZE (LL_HDR_LEN + MTU)
|
||||
|
||||
#define MULTIHOP_HOPLIMIT 64
|
||||
|
||||
#define IP_PKT_RECV_BUF_SIZE 64
|
||||
#define DEBUGLINE printf("%s:%d\n",__FILE__,__LINE__)
|
||||
|
||||
/* extern variables */
|
||||
extern uint8_t ipv6_ext_hdr_len;
|
||||
extern uint8_t opt_hdr_len;
|
||||
extern uint16_t packet_length;
|
||||
extern uint8_t packet_dispatch;
|
||||
extern uint8_t iface_addr_list_count;
|
||||
extern mutex_t buf_mutex;
|
||||
|
||||
extern double start;
|
||||
|
||||
/* base header lengths */
|
||||
#define LL_HDR_LEN 0x4
|
||||
#define ICMPV6_HDR_LEN 0x4
|
||||
#define IPV6_HDR_LEN 0x28
|
||||
#define LLHDR_IPV6HDR_LEN (LL_HDR_LEN + IPV6_HDR_LEN)
|
||||
#define LLHDR_ICMPV6HDR_LEN (LL_HDR_LEN + IPV6_HDR_LEN + ICMPV6_HDR_LEN)
|
||||
#define IPV6HDR_ICMPV6HDR_LEN (IPV6_HDR_LEN + ipv6_ext_hdr_len + ICMPV6_HDR_LEN)
|
||||
|
||||
#define IFACE_ADDR_LIST_LEN 10 // maybe to much
|
||||
/* rfc 4862 section 2. address states */
|
||||
#define ADDR_STATE_TENTATIVE 0
|
||||
#define ADDR_STATE_PREFERRED 1
|
||||
#define ADDR_STATE_DEPRECATED 2
|
||||
/* addresses with this state are always permitted */
|
||||
#define ADDR_STATE_ANY 4
|
||||
/* how the address is configured */
|
||||
#define ADDR_CONFIGURED_AUTO 1
|
||||
#define ADDR_CONFIGURED_MANUAL 2
|
||||
/* address types */
|
||||
#define ADDR_TYPE_NONE 0
|
||||
#define ADDR_TYPE_UNICAST 1
|
||||
#define ADDR_TYPE_MULTICAST 2
|
||||
#define ADDR_TYPE_ANYCAST 3
|
||||
#define ADDR_TYPE_SOL_NODE_MCAST 4
|
||||
#define ADDR_TYPE_LOOPBACK 5
|
||||
#define ADDR_TYPE_LINK_LOCAL 6
|
||||
#define ADDR_TYPE_GLOBAL 7
|
||||
/* dispatch types */
|
||||
#define DISPATCH_TYPE_IPV6 0x41
|
||||
#define DISPATCH_TYPE_LOWPAN_HC1 0x42
|
||||
/* compression types */
|
||||
#define COMPRESSION_TYPE_NONE
|
||||
|
||||
/* buffer */
|
||||
extern uint8_t buffer[BUFFER_SIZE];
|
||||
|
||||
|
||||
/* ipv6 extension header length */
|
||||
|
||||
typedef union __attribute__((packed)) {
|
||||
uint8_t uint8[16];
|
||||
uint16_t uint16[8];
|
||||
uint32_t uint32[4];
|
||||
} ipv6_addr_t;
|
||||
|
||||
struct __attribute__((packed)) icmpv6_hdr_t {
|
||||
uint8_t type;
|
||||
uint8_t code;
|
||||
uint16_t checksum;
|
||||
};
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t version_trafficclass;
|
||||
uint8_t trafficclass_flowlabel;
|
||||
uint16_t flowlabel;
|
||||
uint16_t length;
|
||||
uint8_t nextheader;
|
||||
uint8_t hoplimit;
|
||||
ipv6_addr_t srcaddr;
|
||||
ipv6_addr_t destaddr;
|
||||
} ipv6_hdr_t;
|
||||
|
||||
/* link layer addressing */
|
||||
typedef union __attribute__((packed)) {
|
||||
uint8_t uint8[8];
|
||||
uint16_t uint16[4];
|
||||
} ieee_802154_long_t;
|
||||
|
||||
typedef union __attribute__((packed)) {
|
||||
uint8_t uint8[2];
|
||||
uint16_t uint16[1];
|
||||
} ieee_802154_short_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t state;
|
||||
timex_t val_ltime;
|
||||
timex_t pref_ltime;
|
||||
uint8_t type;
|
||||
ipv6_addr_t addr;
|
||||
} addr_list_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
ieee_802154_short_t saddr;
|
||||
ieee_802154_long_t laddr;
|
||||
addr_list_t addr_list[IFACE_ADDR_LIST_LEN];
|
||||
uint8_t adv_cur_hop_limit;
|
||||
uint32_t adv_reachable_time;
|
||||
uint32_t adv_retrans_timer;
|
||||
} iface_t;
|
||||
|
||||
extern iface_t iface;
|
||||
|
||||
/* function prototypes */
|
||||
struct icmpv6_hdr_t *get_icmpv6_buf(uint8_t ext_len);
|
||||
ipv6_hdr_t *get_ipv6_buf(void);
|
||||
uint8_t *get_payload_buf(uint8_t ext_len);
|
||||
uint8_t *get_payload_buf_send(uint8_t ext_len);
|
||||
|
||||
int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr);
|
||||
void ipv6_init_iface_as_router(void);
|
||||
uint8_t ipv6_is_router(void);
|
||||
void ipv6_set_ll_prefix(ipv6_addr_t *ipaddr);
|
||||
void ipv6_set_all_rtrs_mcast_addr(ipv6_addr_t *ipaddr);
|
||||
void ipv6_set_all_nds_mcast_addr(ipv6_addr_t *ipaddr);
|
||||
void ipv6_set_loaddr(ipv6_addr_t *ipaddr);
|
||||
void ipv6_set_sol_node_mcast_addr(ipv6_addr_t *addr_in, ipv6_addr_t *addr_out);
|
||||
void sixlowpan_bootstrapping(void);
|
||||
void sixlowpan_send(ipv6_addr_t *addr, uint8_t *payload, uint16_t p_len, uint8_t next_header);
|
||||
void ipv6_print_addr(ipv6_addr_t *ipaddr);
|
||||
void ipv6_process(void);
|
||||
void ipv6_get_saddr(ipv6_addr_t *src, ipv6_addr_t *dst);
|
||||
uint8_t ipv6_get_addr_match(ipv6_addr_t *src, ipv6_addr_t *dst);
|
||||
uint8_t ipv6_prefix_mcast_match(ipv6_addr_t *addr);
|
||||
uint8_t ipv6_prefix_ll_match(ipv6_addr_t *addr);
|
||||
void ipv6_iface_add_addr(ipv6_addr_t *addr, uint8_t state, uint32_t val_ltime,
|
||||
uint32_t pref_ltime, uint8_t type);
|
||||
addr_list_t *ipv6_iface_addr_prefix_eq(ipv6_addr_t *addr);
|
||||
addr_list_t *ipv6_iface_addr_match(ipv6_addr_t *addr);
|
||||
void ipv6_iface_print_addrs(void);
|
||||
void ipv6_init_addr_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix);
|
||||
void ipv6_init_address(ipv6_addr_t *addr, uint16_t addr0, uint16_t addr1,
|
||||
uint16_t addr2, uint16_t addr3, uint16_t addr4,
|
||||
uint16_t addr5, uint16_t addr6, uint16_t addr7);
|
||||
uint32_t get_remaining_time(timex_t *t);
|
||||
void set_remaining_time(timex_t *t, uint32_t time);
|
||||
void ipv6_set_prefix(ipv6_addr_t *inout, ipv6_addr_t *prefix);
|
||||
uint8_t ipv6_addr_unspec_match(ipv6_addr_t *addr);
|
||||
uint8_t ipv6_addr_sol_node_mcast_match(ipv6_addr_t *addr);
|
||||
uint8_t ipv6_next_hdr_unrec(uint8_t next_hdr);
|
||||
void set_tcp_packet_handler_pid(int pid);
|
||||
void set_udp_packet_handler_pid(int pid);
|
||||
void set_rpl_process_pid(int pid);
|
||||
#endif /* SIXLOWIP_H*/
|
||||
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 6LoWPAN MAC - layer 2 prototypes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowmac.h
|
||||
* @brief 6lowpan link layer functions
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef SIXLOWMAC_H
|
||||
#define SIXLOWMAC_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "sixlowip.h"
|
||||
#include "radio/radio.h"
|
||||
#include <transceiver.h>
|
||||
|
||||
#define RADIO_STACK_SIZE (MINIMUM_STACK_SIZE + 256)
|
||||
#define RADIO_RCV_BUF_SIZE (64)
|
||||
#define RADIO_SENDING_DELAY (1000)
|
||||
|
||||
extern uint16_t fragmentcounter;
|
||||
|
||||
uint8_t get_radio_address(void);
|
||||
void set_radio_address(uint8_t addr);
|
||||
void send_ieee802154_frame(ieee_802154_long_t *addr, uint8_t *payload,
|
||||
uint8_t length, uint8_t mcast);
|
||||
void init_802154_long_addr(ieee_802154_long_t *laddr);
|
||||
void init_802154_short_addr(ieee_802154_short_t *saddr);
|
||||
void sixlowmac_init(transceiver_type_t type);
|
||||
ieee_802154_long_t *mac_get_eui(ipv6_addr_t *ipaddr);
|
||||
|
||||
#endif /* SIXLOWMAC_H*/
|
||||
@ -1,267 +0,0 @@
|
||||
/*
|
||||
* 6lowpan neighbor discovery
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlownd.h
|
||||
* @brief 6lowpan neighbor discovery constants, data structs, and prototypes
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef SIXLOWND_H
|
||||
#define SIXLOWND_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "vtimer.h"
|
||||
#include "sixlowpan.h"
|
||||
#include "sixlowip.h"
|
||||
|
||||
/* parameter problem [rfc4443] */
|
||||
#define PARA_PROB_LEN (8)
|
||||
#define PARA_PROB_CODE_ERR (0) /* Erroneous header field encountered */
|
||||
#define PARA_PROB_NXT_HDR_UNREC (1) /* Unrecognized Next Header type encountered */
|
||||
#define PARA_PROB_IPV6_OPT_UNREC (2) /* Unrecognized IPv6 option encountered */
|
||||
/* router solicitation */
|
||||
#define RTR_SOL_LEN (4)
|
||||
#define RTR_SOL_INTERVAL (4)
|
||||
#define RTR_SOL_MAX (3)
|
||||
/* router advertisment */
|
||||
#define RTR_ADV_M_FLAG (0)
|
||||
#define RTR_ADV_O_FLAG (0)
|
||||
#define RTR_ADV_MAX (3)
|
||||
#define RTR_ADV_MAX_INTERVAL (600)
|
||||
#define RTR_ADV_LEN (12)
|
||||
/* neighbour solicitation */
|
||||
#define NBR_SOL_LEN (20)
|
||||
/* neighbour advertisement */
|
||||
#define NBR_ADV_LEN (20)
|
||||
#define NBR_ADV_FLAG_R (0x80)
|
||||
#define NBR_ADV_FLAG_S (0x40)
|
||||
#define NBR_ADV_FLAG_O (0x20)
|
||||
/* stllao option rfc4861 4.6.1 */
|
||||
#define OPT_STLLAO_MIN_LEN (8)
|
||||
#define OPT_STLLAO_MAX_LEN (16)
|
||||
#define OPT_SLLAO_TYPE (1)
|
||||
#define OPT_TLLAO_TYPE (2)
|
||||
/* prefix info option rfc 4.6.2 */
|
||||
#define OPT_PI_LIST_LEN (5) //TODO: initalwert suchen
|
||||
#define OPT_PI_TYPE (3)
|
||||
#define OPT_PI_LEN (4)
|
||||
#define OPT_PI_HDR_LEN (32)
|
||||
#define OPT_PI_FLAG_A (0x40)
|
||||
#define OPT_PI_FLAG_L (0x80)
|
||||
#define OPT_PI_VLIFETIME_INFINITE (0xffffffff)
|
||||
/* mtu option rfc4861 4.6.4 */
|
||||
#define OPT_MTU_TYPE (5)
|
||||
#define OPT_MTU_LEN (1)
|
||||
#define OPT_MTU_HDR_LEN (8)
|
||||
/* aro - address registration option draft-ietf-6lowpan-nd-14 4.2 */
|
||||
#define OPT_ARO_TYPE (31) /* TBD1 */
|
||||
#define OPT_ARO_LEN (2)
|
||||
#define OPT_ARO_HDR_LEN (16)
|
||||
#define OPT_ARO_LTIME (300) /* geeigneten wert finden */
|
||||
#define OPT_ARO_STATE_SUCCESS (0)
|
||||
#define OPT_ARO_STATE_DUP_ADDR (1)
|
||||
#define OPT_ARO_STATE_NBR_CACHE_FULL (2)
|
||||
/* 6lowpan context option */
|
||||
#define OPT_6CO_TYPE (32)
|
||||
#define OPT_6CO_MIN_LEN (2)
|
||||
#define OPT_6CO_MAX_LEN (3)
|
||||
#define OPT_6CO_HDR_LEN (8)
|
||||
#define OPT_6CO_LTIME (5) /* geeigneten Wert finden */
|
||||
#define OPT_6CO_FLAG_C (0x10)
|
||||
#define OPT_6CO_FLAG_CID (0x0F)
|
||||
#define OPT_6CO_FLAG_C_VALUE_SET (1)
|
||||
#define OPT_6CO_FLAG_C_VALUE_UNSET (0)
|
||||
/* authoritative border router option */
|
||||
#define OPT_ABRO_TYPE (33)
|
||||
#define OPT_ABRO_LEN (3)
|
||||
#define OPT_ABRO_HDR_LEN (24)
|
||||
/* authoritive border router cache size */
|
||||
#define ABR_CACHE_SIZE (2)
|
||||
/* neighbor cache size */
|
||||
#define NBR_CACHE_SIZE (8)
|
||||
#define NBR_CACHE_TYPE_GC (1)
|
||||
#define NBR_CACHE_TYPE_REG (2)
|
||||
#define NBR_CACHE_TYPE_TEN (3)
|
||||
#define NBR_CACHE_LTIME_TEN (20)
|
||||
/* neighbor status values */
|
||||
#define NBR_STATUS_INCOMPLETE (0)
|
||||
#define NBR_STATUS_REACHABLE (1)
|
||||
#define NBR_STATUS_STALE (2)
|
||||
#define NBR_STATUS_DELAY (3)
|
||||
#define NBR_STATUS_PROBE (4)
|
||||
/* default router list size */
|
||||
#define DEF_RTR_LST_SIZE (3) /* geeigneten wert finden */
|
||||
|
||||
extern unsigned int nd_nbr_cache_rem_pid;
|
||||
|
||||
enum option_types_t {
|
||||
OPT_SLLAO = 1,
|
||||
OPT_TLLAO,
|
||||
OPT_PI,
|
||||
OPT_MTU,
|
||||
OPT_ARO,
|
||||
OPT_6CO,
|
||||
OPT_ABRO,
|
||||
OPT_DAR,
|
||||
OPT_DAC,
|
||||
};
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
} opt_buf_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
} opt_stllao_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint16_t reserved;
|
||||
uint32_t mtu;
|
||||
} opt_mtu_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t prefix_length;
|
||||
uint8_t l_a_reserved1;
|
||||
uint32_t val_ltime;
|
||||
uint32_t pref_ltime;
|
||||
uint32_t reserved2;
|
||||
ipv6_addr_t addr;
|
||||
} opt_pi_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t status;
|
||||
uint8_t reserved1;
|
||||
uint16_t reserved2;
|
||||
uint16_t reg_ltime;
|
||||
ieee_802154_long_t eui64;
|
||||
} opt_aro_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t c_length;
|
||||
uint8_t c_flags;
|
||||
uint16_t reserved;
|
||||
uint16_t val_ltime;
|
||||
} opt_6co_hdr_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint16_t version;
|
||||
uint32_t reserved;
|
||||
ipv6_addr_t addr;
|
||||
} opt_abro_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t inuse;
|
||||
uint8_t adv;
|
||||
ipv6_addr_t addr;
|
||||
uint8_t length;
|
||||
uint8_t l_a_reserved1;
|
||||
uint32_t val_ltime;
|
||||
uint32_t pref_ltime;
|
||||
uint8_t infinite;
|
||||
} plist_t;
|
||||
|
||||
struct __attribute__((packed)) rtr_adv_t {
|
||||
uint8_t hoplimit;
|
||||
uint8_t autoconfig_flags;
|
||||
uint16_t router_lifetime;
|
||||
uint32_t reachable_time;
|
||||
uint32_t retrans_timer;
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) nbr_sol_t {
|
||||
uint32_t reserved;
|
||||
ipv6_addr_t tgtaddr;
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) nbr_adv_t {
|
||||
uint8_t rso;
|
||||
uint8_t reserved[3];
|
||||
ipv6_addr_t tgtaddr;
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) para_prob_t {
|
||||
uint8_t pointer;
|
||||
};
|
||||
|
||||
/* authoritive border router cache - draft-draft-ietf-6lowpan-nd-17 */
|
||||
typedef struct __attribute__((packed)) abr_cache_t {
|
||||
uint16_t version;
|
||||
ipv6_addr_t abr_addr;
|
||||
uint8_t cids[LOWPAN_CONTEXT_MAX];
|
||||
} abr_cache_t;
|
||||
|
||||
/* neighbor cache - rfc4861 5.1. */
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t type;
|
||||
uint8_t state;
|
||||
uint8_t isrouter;
|
||||
ipv6_addr_t addr;
|
||||
ieee_802154_long_t laddr;
|
||||
ieee_802154_short_t saddr;
|
||||
timex_t ltime;
|
||||
} nbr_cache_t;
|
||||
|
||||
/* default router list - rfc4861 5.1. */
|
||||
typedef struct __attribute__((packed)) {
|
||||
ipv6_addr_t addr;
|
||||
timex_t inval_time;
|
||||
} def_rtr_lst_t;
|
||||
|
||||
void init_rtr_sol(uint8_t sllao);
|
||||
void recv_rtr_sol(void);
|
||||
void recv_rtr_adv(void);
|
||||
void init_rtr_adv(ipv6_addr_t *addr, uint8_t sllao, uint8_t mtu, uint8_t pi,
|
||||
uint8_t sixco, uint8_t abro);
|
||||
uint8_t plist_search(ipv6_addr_t *addr);
|
||||
uint8_t plist_cmp(ipv6_addr_t *addr1, ipv6_addr_t *addr2);
|
||||
int8_t plist_add(ipv6_addr_t *addr, uint8_t size, uint32_t val_ltime,
|
||||
uint32_t pref_ltime, uint8_t adv_opt, uint8_t l_a_reserved1);
|
||||
void set_llao(opt_stllao_t *sllao, uint8_t type, uint8_t length);
|
||||
|
||||
abr_cache_t *abr_get_version(uint16_t version, ipv6_addr_t *abr_addr);
|
||||
abr_cache_t *abr_add_context(uint16_t version, ipv6_addr_t *abr_addr,
|
||||
uint8_t cid);
|
||||
void abr_remove_context(uint8_t cid);
|
||||
|
||||
nbr_cache_t *nbr_cache_search(ipv6_addr_t *ipaddr);
|
||||
uint8_t nbr_cache_add(ipv6_addr_t *ipaddr, ieee_802154_long_t *laddr,
|
||||
uint8_t isrouter, uint8_t state, uint8_t type,
|
||||
uint16_t ltime, ieee_802154_short_t *saddr);
|
||||
void nbr_cache_auto_rem(void);
|
||||
void nbr_cache_rem(ipv6_addr_t *addr);
|
||||
uint16_t icmpv6_csum(uint8_t proto);
|
||||
def_rtr_lst_t *def_rtr_lst_search(ipv6_addr_t *ipaddr);
|
||||
void def_rtr_lst_add(ipv6_addr_t *ipaddr, uint32_t rtr_ltime);
|
||||
void def_rtr_lst_rem(def_rtr_lst_t *entry);
|
||||
void init_para_prob(ipv6_addr_t *src, ipv6_addr_t *dest, uint8_t code,
|
||||
uint32_t pointer, uint8_t *packet, uint8_t packet_len);
|
||||
void init_nbr_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t *targ,
|
||||
uint8_t slloa, uint8_t aro);
|
||||
void init_nbr_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt,
|
||||
uint8_t rso, uint8_t sllao, uint8_t aro, uint8_t aro_state);
|
||||
void recv_nbr_adv(void);
|
||||
void recv_nbr_sol(void);
|
||||
#endif /* SIXLOWND_H*/
|
||||
@ -1,144 +0,0 @@
|
||||
/*
|
||||
* 6lowpan constants, data structs, and prototypes
|
||||
*
|
||||
* Copyright (C) 2013 INRIA.
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup sixlowpan
|
||||
* @{
|
||||
* @file sixlowpan.h
|
||||
* @brief 6lowpan header
|
||||
* @author Stephan Zeisberg <zeisberg@mi.fu-berlin.de>
|
||||
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Oliver Gesch <oliver.gesch@googlemail.com>
|
||||
* @author Eric Engel <eric.engel@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef SIXLOWPAN_H
|
||||
#define SIXLOWPAN_H
|
||||
|
||||
#define IP_PROCESS_STACKSIZE (3072)
|
||||
#define NC_STACKSIZE (512)
|
||||
#define CON_STACKSIZE (512)
|
||||
#define LOWPAN_TRANSFER_BUF_STACKSIZE (512)
|
||||
|
||||
/* fragment size in bytes*/
|
||||
#define FRAG_PART_ONE_HDR_LEN (4)
|
||||
#define FRAG_PART_N_HDR_LEN (5)
|
||||
|
||||
#define LOWPAN_IPHC_DISPATCH (0x60)
|
||||
#define LOWPAN_IPHC_FL_C (0x10)
|
||||
#define LOWPAN_IPHC_TC_C (0x08)
|
||||
#define LOWPAN_IPHC_CID (0x80)
|
||||
#define LOWPAN_IPHC_SAC (0x40)
|
||||
#define LOWPAN_IPHC_SAM (0x30)
|
||||
#define LOWPAN_IPHC_DAC (0x04)
|
||||
#define LOWPAN_IPHC_DAM (0x03)
|
||||
#define LOWPAN_IPHC_M (0x08)
|
||||
#define LOWPAN_IPHC_NH (0x04)
|
||||
#define LOWPAN_IPV6_DISPATCH (0x41)
|
||||
#define LOWPAN_CONTEXT_MAX (16)
|
||||
|
||||
#define LOWPAN_REAS_BUF_TIMEOUT (15 * 1000 * 1000) /* TODO: Set back to 3 * 1000 * (1000) */
|
||||
|
||||
/* icmp message types rfc4443 */
|
||||
#define ICMP_PARA_PROB (4)
|
||||
/* icmp message types rfc4861 4.*/
|
||||
#define ICMP_RTR_ADV (134)
|
||||
#define ICMP_RTR_SOL (133)
|
||||
#define ICMP_NBR_ADV (136)
|
||||
#define ICMP_NBR_SOL (135)
|
||||
#define ICMP_REDIRECT (137) /* will be filtered out by the border router */
|
||||
#define ICMP_RPL_CONTROL (155)
|
||||
|
||||
#include "transceiver.h"
|
||||
#include "sixlowip.h"
|
||||
#include "vtimer.h"
|
||||
#include "mutex.h"
|
||||
|
||||
extern mutex_t lowpan_context_mutex;
|
||||
extern uint16_t local_address;
|
||||
|
||||
typedef struct {
|
||||
uint8_t num;
|
||||
ipv6_addr_t prefix;
|
||||
uint8_t length;
|
||||
uint8_t comp;
|
||||
uint16_t lifetime;
|
||||
} lowpan_context_t;
|
||||
|
||||
typedef struct lowpan_interval_list_t {
|
||||
uint8_t start;
|
||||
uint8_t end;
|
||||
struct lowpan_interval_list_t *next;
|
||||
} lowpan_interval_list_t;
|
||||
|
||||
typedef struct lowpan_reas_buf_t {
|
||||
/* Source Address */
|
||||
ieee_802154_long_t s_laddr;
|
||||
/* Destination Address */
|
||||
ieee_802154_long_t d_laddr;
|
||||
/* Identification Number */
|
||||
uint16_t ident_no;
|
||||
/* Timestamp of last packet fragment */
|
||||
long timestamp;
|
||||
/* Size of reassembled packet with possible IPHC header */
|
||||
uint16_t packet_size;
|
||||
/* Additive size of currently already received fragments */
|
||||
uint16_t current_packet_size;
|
||||
/* Pointer to allocated memory for reassembled packet + 6LoWPAN Dispatch Byte */
|
||||
uint8_t *packet;
|
||||
/* Pointer to list of intervals of received packet fragments (if any) */
|
||||
lowpan_interval_list_t *interval_list_head;
|
||||
/* Pointer to next reassembly buffer (if any) */
|
||||
struct lowpan_reas_buf_t *next;
|
||||
} lowpan_reas_buf_t;
|
||||
|
||||
extern lowpan_reas_buf_t *head;
|
||||
|
||||
/**
|
||||
* @brief Initializes 6lowpan
|
||||
*
|
||||
* @param[in] trans transceiver to use with 6lowpan
|
||||
* @param[in] r_addr phy layer address
|
||||
* @param[in] as_border 1 if node shoud act as border router, 0 otherwise
|
||||
*/
|
||||
void sixlowpan_init(transceiver_type_t trans, uint8_t r_addr, int as_border);
|
||||
|
||||
/**
|
||||
* @brief Initializes a 6lowpan router with address prefix
|
||||
*
|
||||
* @param[in] trans transceiver to use with 6lowpan
|
||||
* @param[in] prefix the address prefix to advertise
|
||||
* @param[in] r_addr phy layer address
|
||||
*/
|
||||
void sixlowpan_adhoc_init(transceiver_type_t trans, ipv6_addr_t *prefix,
|
||||
uint8_t r_addr);
|
||||
void lowpan_init(ieee_802154_long_t *addr, uint8_t *data);
|
||||
void lowpan_read(uint8_t *data, uint8_t length, ieee_802154_long_t *s_laddr,
|
||||
ieee_802154_long_t *d_laddr);
|
||||
void lowpan_iphc_encoding(ieee_802154_long_t *dest, ipv6_hdr_t *ipv6_buf_extra, uint8_t *ptr);
|
||||
void lowpan_iphc_decoding(uint8_t *data, uint8_t length,
|
||||
ieee_802154_long_t *s_laddr,
|
||||
ieee_802154_long_t *d_laddr);
|
||||
uint8_t lowpan_context_len(void);
|
||||
void add_fifo_packet(lowpan_reas_buf_t *current_packet);
|
||||
lowpan_context_t *lowpan_context_update(
|
||||
uint8_t num, const ipv6_addr_t *prefix,
|
||||
uint8_t length, uint8_t comp,
|
||||
uint16_t lifetime);
|
||||
lowpan_context_t *lowpan_context_get(void);
|
||||
lowpan_context_t *lowpan_context_lookup(ipv6_addr_t *addr);
|
||||
lowpan_context_t *lowpan_context_num_lookup(uint8_t num);
|
||||
lowpan_reas_buf_t *collect_garbage_fifo(lowpan_reas_buf_t *current_buf);
|
||||
lowpan_reas_buf_t *collect_garbage(lowpan_reas_buf_t *current_buf);
|
||||
void check_timeout(void);
|
||||
void lowpan_ipv6_set_dispatch(uint8_t *data);
|
||||
void init_reas_bufs(lowpan_reas_buf_t *buf);
|
||||
void printReasBuffers(void);
|
||||
void printFIFOBuffers(void);
|
||||
#endif
|
||||
Loading…
x
Reference in New Issue
Block a user