Moved ETX management from neighbor-info to rpl-of-etx. Avoids conversions between different fixed point representations, and simplifies neighbor management. Makes more clear how default-ETX and noack-ETX actually affect the rank. Removed neighbor-info and neighbor-attr.
This commit is contained in:
parent
c50d10aa53
commit
c3f62b24c8
15 changed files with 86 additions and 757 deletions
|
@ -1,8 +1,6 @@
|
||||||
NET = \
|
NET = \
|
||||||
dhcpc.c \
|
dhcpc.c \
|
||||||
hc.c \
|
hc.c \
|
||||||
neighbor-attr.c \
|
|
||||||
neighbor-info.c \
|
|
||||||
neighbor-table.c \
|
neighbor-table.c \
|
||||||
netstack.c \
|
netstack.c \
|
||||||
packetbuf.c \
|
packetbuf.c \
|
||||||
|
|
|
@ -1,250 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2010, Vrije Universiteit Brussel
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of the Institute nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Author: Joris Borms <joris.borms@vub.ac.be>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "contiki.h"
|
|
||||||
|
|
||||||
#include "lib/memb.h"
|
|
||||||
#include "lib/list.h"
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "net/neighbor-attr.h"
|
|
||||||
|
|
||||||
#define DEBUG 0
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
#define PRINTF(...) printf(__VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define PRINTF(...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static uint16_t timeout = 0;
|
|
||||||
|
|
||||||
MEMB(neighbor_addr_mem, struct neighbor_addr, NEIGHBOR_ATTR_MAX_NEIGHBORS);
|
|
||||||
|
|
||||||
LIST(neighbor_addrs);
|
|
||||||
LIST(neighbor_attrs);
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
static struct neighbor_addr *
|
|
||||||
neighbor_addr_get(const rimeaddr_t *addr)
|
|
||||||
{
|
|
||||||
struct neighbor_addr *item;
|
|
||||||
|
|
||||||
/* check if addr is derived from table, inside memb */
|
|
||||||
if(memb_inmemb(&neighbor_addr_mem, (char *)addr)) {
|
|
||||||
return (struct neighbor_addr *)
|
|
||||||
(((char *)addr) - offsetof(struct neighbor_addr, addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
item = list_head(neighbor_addrs);
|
|
||||||
while(item != NULL) {
|
|
||||||
if(rimeaddr_cmp(addr, &item->addr)) {
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
item = item->next;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
struct neighbor_addr *
|
|
||||||
neighbor_attr_list_neighbors(void)
|
|
||||||
{
|
|
||||||
return list_head(neighbor_addrs);
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
static void
|
|
||||||
set_attr(struct neighbor_attr *attr, uint16_t index)
|
|
||||||
{
|
|
||||||
if(attr->default_value != NULL) {
|
|
||||||
memcpy((char *)attr->data + index * attr->size,
|
|
||||||
attr->default_value, attr->size);
|
|
||||||
} else {
|
|
||||||
/* fill with zeroes */
|
|
||||||
memset((char *)attr->data + index * attr->size, 0, attr->size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
int
|
|
||||||
neighbor_attr_register(struct neighbor_attr *def)
|
|
||||||
{
|
|
||||||
struct neighbor_addr *addr;
|
|
||||||
|
|
||||||
list_push(neighbor_attrs, def);
|
|
||||||
|
|
||||||
/* set default values for already existing neighbors */
|
|
||||||
for(addr = list_head(neighbor_addrs); addr != NULL; addr = addr->next) {
|
|
||||||
set_attr(def, addr->index);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
int
|
|
||||||
neighbor_attr_has_neighbor(const rimeaddr_t *addr)
|
|
||||||
{
|
|
||||||
return neighbor_addr_get(addr) != NULL;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
int
|
|
||||||
neighbor_attr_add_neighbor(const rimeaddr_t *addr)
|
|
||||||
{
|
|
||||||
struct neighbor_attr *def;
|
|
||||||
struct neighbor_addr *item;
|
|
||||||
struct neighbor_addr *ptr;
|
|
||||||
uint16_t i;
|
|
||||||
|
|
||||||
if(neighbor_attr_has_neighbor(addr)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
item = memb_alloc(&neighbor_addr_mem);
|
|
||||||
if(item == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_push(neighbor_addrs, item);
|
|
||||||
|
|
||||||
item->time = 0;
|
|
||||||
rimeaddr_copy(&item->addr, addr);
|
|
||||||
|
|
||||||
/* look up index and set default values */
|
|
||||||
ptr = neighbor_addr_mem.mem;
|
|
||||||
for(i = 0; i < neighbor_addr_mem.num; ++i) {
|
|
||||||
if(&ptr[i] == item) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
item->index = i;
|
|
||||||
|
|
||||||
for(def = list_head(neighbor_attrs); def != NULL; def = def->next) {
|
|
||||||
set_attr(def, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
int
|
|
||||||
neighbor_attr_remove_neighbor(const rimeaddr_t *addr)
|
|
||||||
{
|
|
||||||
struct neighbor_addr *item = neighbor_addr_get(addr);
|
|
||||||
|
|
||||||
if(item != NULL) {
|
|
||||||
list_remove(neighbor_addrs, item);
|
|
||||||
memb_free(&neighbor_addr_mem, item);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void *
|
|
||||||
neighbor_attr_get_data(struct neighbor_attr *def, const rimeaddr_t *addr)
|
|
||||||
{
|
|
||||||
struct neighbor_addr *attr = neighbor_addr_get(addr);
|
|
||||||
|
|
||||||
if(attr != NULL) {
|
|
||||||
return (char *)def->data + attr->index * def->size;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
int
|
|
||||||
neighbor_attr_set_data(struct neighbor_attr *def, const rimeaddr_t *addr,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
struct neighbor_addr *attr = neighbor_addr_get(addr);
|
|
||||||
|
|
||||||
if(attr == NULL) {
|
|
||||||
if(neighbor_attr_add_neighbor(addr)) {
|
|
||||||
attr = neighbor_addr_get(addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(attr != NULL) {
|
|
||||||
attr->time = 0;
|
|
||||||
memcpy((char *)def->data + attr->index * def->size, data, def->size);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
neighbor_attr_tick(const rimeaddr_t * addr)
|
|
||||||
{
|
|
||||||
struct neighbor_addr *attr = neighbor_addr_get(addr);
|
|
||||||
|
|
||||||
if(attr != NULL) {
|
|
||||||
attr->time = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
uint16_t
|
|
||||||
neighbor_attr_get_timeout(void)
|
|
||||||
{
|
|
||||||
return timeout;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
static struct ctimer ct;
|
|
||||||
|
|
||||||
#define TIMEOUT_SECONDS 5
|
|
||||||
static void
|
|
||||||
timeout_check(void *ptr)
|
|
||||||
{
|
|
||||||
if(timeout > 0) {
|
|
||||||
struct neighbor_addr *item = neighbor_attr_list_neighbors();
|
|
||||||
|
|
||||||
while(item != NULL) {
|
|
||||||
item->time += TIMEOUT_SECONDS;
|
|
||||||
if(item->time >= timeout) {
|
|
||||||
struct neighbor_addr *next_item = item->next;
|
|
||||||
|
|
||||||
list_remove(neighbor_addrs, item);
|
|
||||||
memb_free(&neighbor_addr_mem, item);
|
|
||||||
item = next_item;
|
|
||||||
} else {
|
|
||||||
item = item->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctimer_set(&ct, TIMEOUT_SECONDS * CLOCK_SECOND, timeout_check, ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
neighbor_attr_set_timeout(uint16_t time)
|
|
||||||
{
|
|
||||||
if(timeout == 0 && time > 0) {
|
|
||||||
ctimer_set(&ct, TIMEOUT_SECONDS * CLOCK_SECOND, timeout_check, NULL);
|
|
||||||
} else if(timeout > 0 && time == 0) {
|
|
||||||
ctimer_stop(&ct);
|
|
||||||
}
|
|
||||||
timeout = time;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
|
@ -1,163 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2010, Vrije Universiteit Brussel
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of the Institute nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Author: Joris Borms <joris.borms@vub.ac.be>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifndef NEIGHBORATTR_H_
|
|
||||||
#define NEIGHBORATTR_H_
|
|
||||||
|
|
||||||
#include "net/rime.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* define how many neighbors you can store
|
|
||||||
*/
|
|
||||||
#ifdef NEIGHBOR_CONF_MAX_NEIGHBORS
|
|
||||||
#define NEIGHBOR_ATTR_MAX_NEIGHBORS NEIGHBOR_CONF_MAX_NEIGHBORS
|
|
||||||
#else /* NEIGHBOR_CONF_MAX_NEIGHBORS */
|
|
||||||
#define NEIGHBOR_ATTR_MAX_NEIGHBORS 12
|
|
||||||
#endif /* NEIGHBOR_CONF_MAX_NEIGHBORS */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief properties of a single neighbor
|
|
||||||
*/
|
|
||||||
struct neighbor_addr {
|
|
||||||
struct neighbor_addr *next;
|
|
||||||
rimeaddr_t addr;
|
|
||||||
uint16_t time;
|
|
||||||
uint16_t index;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief properties that define a neighbor attribute
|
|
||||||
*/
|
|
||||||
struct neighbor_attr {
|
|
||||||
struct neighbor_attr *next;
|
|
||||||
uint16_t size;
|
|
||||||
void *default_value;
|
|
||||||
void *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Define space for additional parameters in neighbor table entries.
|
|
||||||
* \param type The type of the attribute.
|
|
||||||
* \param name The name of the attribute.
|
|
||||||
* \param def A ptr to the default value for this attribute. If NULL, attribute will
|
|
||||||
* be filled with zeroes by default.
|
|
||||||
*
|
|
||||||
* The attribute 'name' should be registered with 'neighbor_attr_register'
|
|
||||||
* during initialization.
|
|
||||||
*/
|
|
||||||
#define NEIGHBOR_ATTRIBUTE(type, name, default_value_ptr) \
|
|
||||||
static type _##name##_mem[NEIGHBOR_ATTR_MAX_NEIGHBORS]; \
|
|
||||||
static struct neighbor_attr name = \
|
|
||||||
{NULL, sizeof(type), default_value_ptr, (void *)_##name##_mem}
|
|
||||||
|
|
||||||
/** Same as NEIGHBOR_ATTRIBUTE, only the attr is not declared static
|
|
||||||
* this way you can say <tt>extern struct neighbor_attr name</tt> in header to declare
|
|
||||||
* a global neighbor attribute
|
|
||||||
*/
|
|
||||||
#define NEIGHBOR_ATTRIBUTE_GLOBAL(type, name, default_value_ptr) \
|
|
||||||
static type _##name##_mem[NEIGHBOR_ATTR_MAX_NEIGHBORS]; \
|
|
||||||
struct neighbor_attr name = \
|
|
||||||
{NULL, sizeof(type), default_value_ptr, (void *)_##name##_mem}
|
|
||||||
|
|
||||||
#define NEIGHBOR_ATTRIBUTE_DECLARE(name) extern struct neighbor_attr name
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief register a neighbor attribute
|
|
||||||
* \retval non-zero if successful, zero if not
|
|
||||||
*/
|
|
||||||
int neighbor_attr_register(struct neighbor_attr *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \retval head of neighbor list, useful for iterating over all neighbors
|
|
||||||
*/
|
|
||||||
struct neighbor_addr *neighbor_attr_list_neighbors(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Check if a neighbor is already added to the neighbor table
|
|
||||||
* \retval non-zero if present, zero if not
|
|
||||||
*/
|
|
||||||
int neighbor_attr_has_neighbor(const rimeaddr_t *addr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Add a neighbor entry to neighbor table
|
|
||||||
* \retval -1 if unsuccessful, 0 if the neighbor was already
|
|
||||||
* in the table, and 1 if successful
|
|
||||||
*/
|
|
||||||
int neighbor_attr_add_neighbor(const rimeaddr_t *addr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Remove a neighbor entry to neighbor table
|
|
||||||
* \retval -1 if unsuccessful, 0 if the neighbor was removed
|
|
||||||
*/
|
|
||||||
int neighbor_attr_remove_neighbor(const rimeaddr_t *addr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Get pointer to neighbor table data specified by id
|
|
||||||
* \param requested attribute
|
|
||||||
* \param addr requested neighbor
|
|
||||||
* \retval pointer to data, NULL if neighbor was not found
|
|
||||||
*
|
|
||||||
* Searches neighbor table for addr and returns pointer to data section
|
|
||||||
* specified by attribute type and addr.
|
|
||||||
* This pointer should not be saved, as it may point to data from another
|
|
||||||
* neighbor in the future if neighbors get removed/added over time.
|
|
||||||
*/
|
|
||||||
void *neighbor_attr_get_data(struct neighbor_attr *, const rimeaddr_t *addr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Copy data to neighbor table
|
|
||||||
* \retval non-zero if successful, zero if not
|
|
||||||
*
|
|
||||||
* Copies data to specific part of the neighbor table, specified by
|
|
||||||
* neighbor and attribute type, and resets timeout for that neighbor.
|
|
||||||
* If neighbor was not found, this will add a new neighbor to the table.
|
|
||||||
*/
|
|
||||||
int neighbor_attr_set_data(struct neighbor_attr *, const rimeaddr_t *addr,
|
|
||||||
void *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Set global lifetime of neighbor entries.
|
|
||||||
* \param Lifetime in seconds. If 0, entries will not time out
|
|
||||||
*/
|
|
||||||
void neighbor_attr_set_timeout(uint16_t);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief get global lifetime of neighbor entries. If 0, entries will not time out
|
|
||||||
*/
|
|
||||||
uint16_t neighbor_attr_get_timeout(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief reset timeout of a neighbor to prevent it from being removed
|
|
||||||
*/
|
|
||||||
void neighbor_attr_tick(const rimeaddr_t *);
|
|
||||||
|
|
||||||
#endif /* NEIGHBORATTR_H_ */
|
|
|
@ -1,193 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2010, Swedish Institute of Computer Science.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of the Institute nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This file is part of the Contiki operating system.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* A generic module for management of neighbor information.
|
|
||||||
*
|
|
||||||
* \author Nicolas Tsiftes <nvt@sics.se>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "net/neighbor-info.h"
|
|
||||||
#include "net/neighbor-attr.h"
|
|
||||||
#include "net/uip-ds6.h"
|
|
||||||
#include "net/uip-nd6.h"
|
|
||||||
|
|
||||||
#define DEBUG DEBUG_NONE
|
|
||||||
#include "net/uip-debug.h"
|
|
||||||
|
|
||||||
#define ETX_LIMIT 15
|
|
||||||
#define ETX_SCALE 100
|
|
||||||
#define ETX_ALPHA 90
|
|
||||||
#define ETX_NOACK_PENALTY ETX_LIMIT
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
NEIGHBOR_ATTRIBUTE_GLOBAL(link_metric_t, attr_etx, NULL);
|
|
||||||
NEIGHBOR_ATTRIBUTE_GLOBAL(unsigned long, attr_timestamp, NULL);
|
|
||||||
|
|
||||||
static neighbor_info_subscriber_t subscriber_callback;
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
static void
|
|
||||||
update_metric(const rimeaddr_t *dest, int packet_metric)
|
|
||||||
{
|
|
||||||
link_metric_t *metricp;
|
|
||||||
link_metric_t recorded_metric, new_metric;
|
|
||||||
unsigned long time;
|
|
||||||
int first_update = 0;
|
|
||||||
|
|
||||||
metricp = (link_metric_t *)neighbor_attr_get_data(&attr_etx, dest);
|
|
||||||
packet_metric = NEIGHBOR_INFO_ETX2FIX(packet_metric);
|
|
||||||
if(metricp == NULL || *metricp == 0) {
|
|
||||||
recorded_metric = NEIGHBOR_INFO_ETX2FIX(ETX_LIMIT);
|
|
||||||
new_metric = packet_metric;
|
|
||||||
first_update = 1;
|
|
||||||
} else {
|
|
||||||
recorded_metric = *metricp;
|
|
||||||
/* Update the EWMA of the ETX for the neighbor. */
|
|
||||||
new_metric = ((uint16_t)recorded_metric * ETX_ALPHA +
|
|
||||||
(uint16_t)packet_metric * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRINTF("neighbor-info: ETX changed from %d to %d (packet ETX = %d) %d\n",
|
|
||||||
NEIGHBOR_INFO_FIX2ETX(recorded_metric),
|
|
||||||
NEIGHBOR_INFO_FIX2ETX(new_metric),
|
|
||||||
NEIGHBOR_INFO_FIX2ETX(packet_metric),
|
|
||||||
dest->u8[7]);
|
|
||||||
|
|
||||||
if(neighbor_attr_has_neighbor(dest)) {
|
|
||||||
time = clock_seconds();
|
|
||||||
neighbor_attr_set_data(&attr_etx, dest, &new_metric);
|
|
||||||
neighbor_attr_set_data(&attr_timestamp, dest, &time);
|
|
||||||
if((first_update || new_metric != recorded_metric) && subscriber_callback != NULL) {
|
|
||||||
subscriber_callback(dest, 1, new_metric);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
static void
|
|
||||||
add_neighbor(const rimeaddr_t *addr)
|
|
||||||
{
|
|
||||||
switch(neighbor_attr_add_neighbor(addr)) {
|
|
||||||
case -1:
|
|
||||||
PRINTF("neighbor-info: failed to add a node.\n");
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
PRINTF("neighbor-info: The neighbor is already known\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
neighbor_info_packet_sent(int status, int numtx)
|
|
||||||
{
|
|
||||||
const rimeaddr_t *dest;
|
|
||||||
link_metric_t packet_metric;
|
|
||||||
#if UIP_DS6_LL_NUD
|
|
||||||
uip_ds6_nbr_t *nbr;
|
|
||||||
#endif /* UIP_DS6_LL_NUD */
|
|
||||||
|
|
||||||
dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
|
|
||||||
if(rimeaddr_cmp(dest, &rimeaddr_null)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
packet_metric = numtx;
|
|
||||||
|
|
||||||
PRINTF("neighbor-info: packet sent to %d.%d, status=%d, metric=%u\n",
|
|
||||||
dest->u8[sizeof(*dest) - 2], dest->u8[sizeof(*dest) - 1],
|
|
||||||
status, (unsigned)packet_metric);
|
|
||||||
|
|
||||||
switch(status) {
|
|
||||||
case MAC_TX_OK:
|
|
||||||
add_neighbor(dest);
|
|
||||||
#if UIP_DS6_LL_NUD
|
|
||||||
nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest);
|
|
||||||
if(nbr != NULL &&
|
|
||||||
(nbr->state == STALE || nbr->state == DELAY || nbr->state == PROBE)) {
|
|
||||||
nbr->state = REACHABLE;
|
|
||||||
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
|
|
||||||
PRINTF("neighbor-info : received a link layer ACK : ");
|
|
||||||
PRINTLLADDR((uip_lladdr_t *)dest);
|
|
||||||
PRINTF(" is reachable.\n");
|
|
||||||
}
|
|
||||||
#endif /* UIP_DS6_LL_NUD */
|
|
||||||
break;
|
|
||||||
case MAC_TX_NOACK:
|
|
||||||
packet_metric = ETX_NOACK_PENALTY;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Do not penalize the ETX when collisions or transmission
|
|
||||||
errors occur. */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
update_metric(dest, packet_metric);
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
neighbor_info_packet_received(void)
|
|
||||||
{
|
|
||||||
const rimeaddr_t *src;
|
|
||||||
|
|
||||||
src = packetbuf_addr(PACKETBUF_ADDR_SENDER);
|
|
||||||
if(rimeaddr_cmp(src, &rimeaddr_null)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRINTF("neighbor-info: packet received from %d.%d\n",
|
|
||||||
src->u8[sizeof(*src) - 2], src->u8[sizeof(*src) - 1]);
|
|
||||||
|
|
||||||
add_neighbor(src);
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
int
|
|
||||||
neighbor_info_subscribe(neighbor_info_subscriber_t s)
|
|
||||||
{
|
|
||||||
if(subscriber_callback == NULL) {
|
|
||||||
neighbor_attr_register(&attr_etx);
|
|
||||||
neighbor_attr_register(&attr_timestamp);
|
|
||||||
subscriber_callback = s;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
link_metric_t
|
|
||||||
neighbor_info_get_metric(const rimeaddr_t *addr)
|
|
||||||
{
|
|
||||||
link_metric_t *metricp;
|
|
||||||
|
|
||||||
metricp = (link_metric_t *)neighbor_attr_get_data(&attr_etx, addr);
|
|
||||||
return metricp == NULL ? ETX_LIMIT : *metricp;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
|
@ -1,94 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2010, Swedish Institute of Computer Science.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of the Institute nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This file is part of the Contiki operating system.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Declarations for the neighbor information module.
|
|
||||||
*
|
|
||||||
* \author Nicolas Tsiftes <nvt@sics.se>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NEIGHBOR_INFO_H
|
|
||||||
#define NEIGHBOR_INFO_H
|
|
||||||
|
|
||||||
#include "net/neighbor-attr.h"
|
|
||||||
#include "net/rime.h"
|
|
||||||
|
|
||||||
/* ETX_DIVISOR is the value that a fix-point representation of the ETX
|
|
||||||
should be divided by in order to obtain the integer representation. */
|
|
||||||
#define NEIGHBOR_INFO_ETX_DIVISOR 16
|
|
||||||
|
|
||||||
/* Macros for converting between a fix-point representation of the ETX
|
|
||||||
and a integer representation. */
|
|
||||||
#define NEIGHBOR_INFO_ETX2FIX(etx) ((etx) * NEIGHBOR_INFO_ETX_DIVISOR)
|
|
||||||
#define NEIGHBOR_INFO_FIX2ETX(fix) ((fix) / NEIGHBOR_INFO_ETX_DIVISOR)
|
|
||||||
|
|
||||||
typedef void (*neighbor_info_subscriber_t)(const rimeaddr_t *, int known, int etx);
|
|
||||||
typedef uint8_t link_metric_t;
|
|
||||||
|
|
||||||
NEIGHBOR_ATTRIBUTE_DECLARE(attr_etx);
|
|
||||||
NEIGHBOR_ATTRIBUTE_DECLARE(attr_timestamp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify the neighbor information module about the status of
|
|
||||||
* a packet transmission.
|
|
||||||
*
|
|
||||||
* \param status The MAC status code for this packet.
|
|
||||||
*
|
|
||||||
* \param numtx The amount of transmissions made for this packet.
|
|
||||||
*/
|
|
||||||
void neighbor_info_packet_sent(int status, int numtx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify the neighbor information module that a packet was received.
|
|
||||||
*
|
|
||||||
* \param status The MAC status code for this packet.
|
|
||||||
*
|
|
||||||
* \param numtx The amount of transmissions made for this packet.
|
|
||||||
*/
|
|
||||||
void neighbor_info_packet_received(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscribe to notifications of changed neighbor information.
|
|
||||||
*
|
|
||||||
* \return Returns 1 if the subscription was successful, and 0 if not.
|
|
||||||
*/
|
|
||||||
int neighbor_info_subscribe(neighbor_info_subscriber_t);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get link metric value for a specific neighbor.
|
|
||||||
*
|
|
||||||
* \return Returns link metric if the neighbor exists, and 0 if not.
|
|
||||||
*/
|
|
||||||
link_metric_t neighbor_info_get_metric(const rimeaddr_t *addr);
|
|
||||||
|
|
||||||
#endif /* NEIGHBOR_INFO_H */
|
|
|
@ -162,9 +162,9 @@
|
||||||
* Initial metric attributed to a link when the ETX is unknown
|
* Initial metric attributed to a link when the ETX is unknown
|
||||||
*/
|
*/
|
||||||
#ifndef RPL_CONF_INIT_LINK_METRIC
|
#ifndef RPL_CONF_INIT_LINK_METRIC
|
||||||
#define RPL_INIT_LINK_METRIC NEIGHBOR_INFO_ETX2FIX(5)
|
#define RPL_INIT_LINK_METRIC 5 * RPL_MIN_HOPRANKINC
|
||||||
#else
|
#else
|
||||||
#define RPL_INIT_LINK_METRIC NEIGHBOR_INFO_ETX2FIX(RPL_CONF_INIT_LINK_METRIC)
|
#define RPL_INIT_LINK_METRIC RPL_CONF_INIT_LINK_METRIC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -56,8 +56,6 @@
|
||||||
#define DEBUG DEBUG_NONE
|
#define DEBUG DEBUG_NONE
|
||||||
#include "net/uip-debug.h"
|
#include "net/uip-debug.h"
|
||||||
|
|
||||||
#include "net/neighbor-info.h"
|
|
||||||
|
|
||||||
#if UIP_CONF_IPV6
|
#if UIP_CONF_IPV6
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
extern rpl_of_t RPL_OF;
|
extern rpl_of_t RPL_OF;
|
||||||
|
|
|
@ -45,13 +45,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "net/rpl/rpl-private.h"
|
#include "net/rpl/rpl-private.h"
|
||||||
#include "net/neighbor-info.h"
|
#include "net/neighbor-table.h"
|
||||||
|
|
||||||
#define DEBUG DEBUG_NONE
|
#define DEBUG DEBUG_NONE
|
||||||
#include "net/uip-debug.h"
|
#include "net/uip-debug.h"
|
||||||
|
|
||||||
static void reset(rpl_dag_t *);
|
static void reset(rpl_dag_t *);
|
||||||
static void parent_state_callback(rpl_parent_t *, int, int);
|
static void neighbor_link_callback(rpl_parent_t *, int, int);
|
||||||
static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *);
|
static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *);
|
||||||
static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *);
|
static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *);
|
||||||
static rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t);
|
static rpl_rank_t calculate_rank(rpl_parent_t *, rpl_rank_t);
|
||||||
|
@ -59,7 +59,7 @@ static void update_metric_container(rpl_instance_t *);
|
||||||
|
|
||||||
rpl_of_t rpl_mrhof = {
|
rpl_of_t rpl_mrhof = {
|
||||||
reset,
|
reset,
|
||||||
parent_state_callback,
|
neighbor_link_callback,
|
||||||
best_parent,
|
best_parent,
|
||||||
best_dag,
|
best_dag,
|
||||||
calculate_rank,
|
calculate_rank,
|
||||||
|
@ -67,6 +67,10 @@ rpl_of_t rpl_mrhof = {
|
||||||
1
|
1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Constants for the ETX moving average */
|
||||||
|
#define ETX_SCALE 100
|
||||||
|
#define ETX_ALPHA 90
|
||||||
|
|
||||||
/* Reject parents that have a higher link metric than the following. */
|
/* Reject parents that have a higher link metric than the following. */
|
||||||
#define MAX_LINK_METRIC 10
|
#define MAX_LINK_METRIC 10
|
||||||
|
|
||||||
|
@ -88,7 +92,6 @@ calculate_path_metric(rpl_parent_t *p)
|
||||||
return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR;
|
return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR;
|
||||||
} else {
|
} else {
|
||||||
long link_metric = p->link_metric;
|
long link_metric = p->link_metric;
|
||||||
link_metric = (link_metric * RPL_DAG_MC_ETX_DIVISOR) / NEIGHBOR_INFO_ETX_DIVISOR;
|
|
||||||
#if RPL_DAG_MC == RPL_DAG_MC_NONE
|
#if RPL_DAG_MC == RPL_DAG_MC_NONE
|
||||||
return p->rank + (uint16_t)link_metric;
|
return p->rank + (uint16_t)link_metric;
|
||||||
#elif RPL_DAG_MC == RPL_DAG_MC_ETX
|
#elif RPL_DAG_MC == RPL_DAG_MC_ETX
|
||||||
|
@ -105,8 +108,29 @@ reset(rpl_dag_t *sag)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parent_state_callback(rpl_parent_t *parent, int known, int etx)
|
neighbor_link_callback(rpl_parent_t *p, int status, int numtx)
|
||||||
{
|
{
|
||||||
|
/* Do not penalize the ETX when collisions or transmission errors occur. */
|
||||||
|
if(status == MAC_TX_OK || status == MAC_TX_NOACK) {
|
||||||
|
int recorded_etx = p->link_metric;
|
||||||
|
int packet_etx = numtx;
|
||||||
|
int new_etx;
|
||||||
|
|
||||||
|
if(status == MAC_TX_NOACK) {
|
||||||
|
packet_etx = MAX_LINK_METRIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_etx = ((uint16_t)recorded_etx * ETX_ALPHA +
|
||||||
|
(uint16_t)packet_etx * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE;
|
||||||
|
|
||||||
|
PRINTF("RPL: ETX changed from %d to %d (packet ETX = %d) %d\n",
|
||||||
|
recorded_etx / p->dag->instance->min_hoprankinc,
|
||||||
|
new_etx / p->dag->instance->min_hoprankinc,
|
||||||
|
packet_etx / p->dag->instance->min_hoprankinc,
|
||||||
|
dest->u8[7]);
|
||||||
|
p->link_metric = new_etx;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static rpl_rank_t
|
static rpl_rank_t
|
||||||
|
@ -119,10 +143,10 @@ calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank)
|
||||||
if(base_rank == 0) {
|
if(base_rank == 0) {
|
||||||
return INFINITE_RANK;
|
return INFINITE_RANK;
|
||||||
}
|
}
|
||||||
rank_increase = NEIGHBOR_INFO_FIX2ETX(RPL_INIT_LINK_METRIC) * RPL_MIN_HOPRANKINC;
|
rank_increase = RPL_INIT_LINK_METRIC;
|
||||||
} else {
|
} else {
|
||||||
/* multiply first, then scale down to avoid truncation effects */
|
/* multiply first, then scale down to avoid truncation effects */
|
||||||
rank_increase = NEIGHBOR_INFO_FIX2ETX(p->link_metric * p->dag->instance->min_hoprankinc);
|
rank_increase = p->link_metric;
|
||||||
if(base_rank == 0) {
|
if(base_rank == 0) {
|
||||||
base_rank = p->rank;
|
base_rank = p->rank;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,6 @@
|
||||||
#define DEBUG DEBUG_NONE
|
#define DEBUG DEBUG_NONE
|
||||||
#include "net/uip-debug.h"
|
#include "net/uip-debug.h"
|
||||||
|
|
||||||
#include "net/neighbor-info.h"
|
|
||||||
|
|
||||||
static void reset(rpl_dag_t *);
|
static void reset(rpl_dag_t *);
|
||||||
static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *);
|
static rpl_parent_t *best_parent(rpl_parent_t *, rpl_parent_t *);
|
||||||
static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *);
|
static rpl_dag_t *best_dag(rpl_dag_t *, rpl_dag_t *);
|
||||||
|
@ -64,7 +62,7 @@ rpl_of_t rpl_of0 = {
|
||||||
|
|
||||||
#define DEFAULT_RANK_INCREMENT RPL_MIN_HOPRANKINC
|
#define DEFAULT_RANK_INCREMENT RPL_MIN_HOPRANKINC
|
||||||
|
|
||||||
#define MIN_DIFFERENCE (NEIGHBOR_INFO_ETX_DIVISOR + NEIGHBOR_INFO_ETX_DIVISOR / 2)
|
#define MIN_DIFFERENCE (RPL_MIN_HOPRANKINC + RPL_MIN_HOPRANKINC / 2)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reset(rpl_dag_t *dag)
|
reset(rpl_dag_t *dag)
|
||||||
|
@ -137,9 +135,9 @@ best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
|
||||||
p2->link_metric, p2->rank);
|
p2->link_metric, p2->rank);
|
||||||
|
|
||||||
|
|
||||||
r1 = DAG_RANK(p1->rank, p1->dag->instance) * NEIGHBOR_INFO_ETX_DIVISOR +
|
r1 = DAG_RANK(p1->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC +
|
||||||
p1->link_metric;
|
p1->link_metric;
|
||||||
r2 = DAG_RANK(p2->rank, p1->dag->instance) * NEIGHBOR_INFO_ETX_DIVISOR +
|
r2 = DAG_RANK(p2->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC +
|
||||||
p2->link_metric;
|
p2->link_metric;
|
||||||
/* Compare two parents by looking both and their rank and at the ETX
|
/* Compare two parents by looking both and their rank and at the ETX
|
||||||
for that parent. We choose the parent that has the most
|
for that parent. We choose the parent that has the most
|
||||||
|
|
|
@ -44,7 +44,6 @@
|
||||||
#include "net/tcpip.h"
|
#include "net/tcpip.h"
|
||||||
#include "net/uip-ds6.h"
|
#include "net/uip-ds6.h"
|
||||||
#include "net/rpl/rpl-private.h"
|
#include "net/rpl/rpl-private.h"
|
||||||
#include "net/neighbor-info.h"
|
|
||||||
|
|
||||||
#define DEBUG DEBUG_NONE
|
#define DEBUG DEBUG_NONE
|
||||||
#include "net/uip-debug.h"
|
#include "net/uip-debug.h"
|
||||||
|
@ -168,8 +167,8 @@ rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len,
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
void
|
||||||
rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
|
rpl_link_neighbor_callback(const rimeaddr_t *addr, int status, int numtx)
|
||||||
{
|
{
|
||||||
uip_ipaddr_t ipaddr;
|
uip_ipaddr_t ipaddr;
|
||||||
rpl_parent_t *parent;
|
rpl_parent_t *parent;
|
||||||
|
@ -178,9 +177,6 @@ rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
|
||||||
|
|
||||||
uip_ip6addr(&ipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0);
|
uip_ip6addr(&ipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0);
|
||||||
uip_ds6_set_addr_iid(&ipaddr, (uip_lladdr_t *)addr);
|
uip_ds6_set_addr_iid(&ipaddr, (uip_lladdr_t *)addr);
|
||||||
PRINTF("RPL: Neighbor ");
|
|
||||||
PRINT6ADDR(&ipaddr);
|
|
||||||
PRINTF(" is %sknown. ETX = %u\n", known ? "" : "no longer ", NEIGHBOR_INFO_FIX2ETX(etx));
|
|
||||||
|
|
||||||
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
|
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
|
||||||
if(instance->used == 1 ) {
|
if(instance->used == 1 ) {
|
||||||
|
@ -188,27 +184,12 @@ rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
|
||||||
if(parent != NULL) {
|
if(parent != NULL) {
|
||||||
/* Trigger DAG rank recalculation. */
|
/* Trigger DAG rank recalculation. */
|
||||||
parent->updated = 1;
|
parent->updated = 1;
|
||||||
parent->link_metric = etx;
|
if(instance->of->neighbor_link_callback != NULL) {
|
||||||
|
instance->of->neighbor_link_callback(parent, status, numtx);
|
||||||
if(instance->of->parent_state_callback != NULL) {
|
|
||||||
instance->of->parent_state_callback(parent, known, etx);
|
|
||||||
}
|
|
||||||
if(!known) {
|
|
||||||
PRINTF("RPL: Removing parent ");
|
|
||||||
PRINT6ADDR(&parent->addr);
|
|
||||||
PRINTF(" in instance %u because of bad connectivity (ETX %d)\n", instance->instance_id, etx);
|
|
||||||
parent->rank = INFINITE_RANK;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!known) {
|
|
||||||
PRINTF("RPL: Deleting routes installed by DAOs received from ");
|
|
||||||
PRINT6ADDR(&ipaddr);
|
|
||||||
PRINTF("\n");
|
|
||||||
uip_ds6_route_rm_by_nexthop(&ipaddr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -242,7 +223,6 @@ rpl_init(void)
|
||||||
|
|
||||||
rpl_dag_init();
|
rpl_dag_init();
|
||||||
rpl_reset_periodic_timer();
|
rpl_reset_periodic_timer();
|
||||||
neighbor_info_subscribe(rpl_link_neighbor_callback);
|
|
||||||
|
|
||||||
/* add rpl multicast address */
|
/* add rpl multicast address */
|
||||||
uip_create_linklocal_rplnodes_mcast(&rplmaddr);
|
uip_create_linklocal_rplnodes_mcast(&rplmaddr);
|
||||||
|
|
|
@ -156,7 +156,7 @@ typedef struct rpl_instance rpl_instance_t;
|
||||||
* Resets the objective function state for a specific DAG. This function is
|
* Resets the objective function state for a specific DAG. This function is
|
||||||
* called when doing a global repair on the DAG.
|
* called when doing a global repair on the DAG.
|
||||||
*
|
*
|
||||||
* parent_state_callback(parent, known, etx)
|
* neighbor_link_callback(parent, known, etx)
|
||||||
*
|
*
|
||||||
* Receives link-layer neighbor information. The parameter "known" is set
|
* Receives link-layer neighbor information. The parameter "known" is set
|
||||||
* either to 0 or 1. The "etx" parameter specifies the current
|
* either to 0 or 1. The "etx" parameter specifies the current
|
||||||
|
@ -185,7 +185,7 @@ typedef struct rpl_instance rpl_instance_t;
|
||||||
*/
|
*/
|
||||||
struct rpl_of {
|
struct rpl_of {
|
||||||
void (*reset)(struct rpl_dag *);
|
void (*reset)(struct rpl_dag *);
|
||||||
void (*parent_state_callback)(rpl_parent_t *, int, int);
|
void (*neighbor_link_callback)(rpl_parent_t *, int, int);
|
||||||
rpl_parent_t *(*best_parent)(rpl_parent_t *, rpl_parent_t *);
|
rpl_parent_t *(*best_parent)(rpl_parent_t *, rpl_parent_t *);
|
||||||
rpl_dag_t *(*best_dag)(rpl_dag_t *, rpl_dag_t *);
|
rpl_dag_t *(*best_dag)(rpl_dag_t *, rpl_dag_t *);
|
||||||
rpl_rank_t (*calculate_rank)(rpl_parent_t *, rpl_rank_t);
|
rpl_rank_t (*calculate_rank)(rpl_parent_t *, rpl_rank_t);
|
||||||
|
|
|
@ -65,7 +65,6 @@
|
||||||
#include "net/uip-ds6.h"
|
#include "net/uip-ds6.h"
|
||||||
#include "net/rime.h"
|
#include "net/rime.h"
|
||||||
#include "net/sicslowpan.h"
|
#include "net/sicslowpan.h"
|
||||||
#include "net/neighbor-info.h"
|
|
||||||
#include "net/netstack.h"
|
#include "net/netstack.h"
|
||||||
|
|
||||||
#if UIP_CONF_IPV6
|
#if UIP_CONF_IPV6
|
||||||
|
@ -113,11 +112,6 @@ void uip_log(char *msg);
|
||||||
#endif /* SICSLOWPAN_CONF_COMPRESSION */
|
#endif /* SICSLOWPAN_CONF_COMPRESSION */
|
||||||
#endif /* SICSLOWPAN_COMPRESSION */
|
#endif /* SICSLOWPAN_COMPRESSION */
|
||||||
|
|
||||||
#ifndef SICSLOWPAN_CONF_NEIGHBOR_INFO
|
|
||||||
/* Default is to use neighbor info updates if using RPL */
|
|
||||||
#define SICSLOWPAN_CONF_NEIGHBOR_INFO UIP_CONF_IPV6_RPL
|
|
||||||
#endif /* SICSLOWPAN_CONF_NEIGHBOR_INFO */
|
|
||||||
|
|
||||||
#define GET16(ptr,index) (((uint16_t)((ptr)[index] << 8)) | ((ptr)[(index) + 1]))
|
#define GET16(ptr,index) (((uint16_t)((ptr)[index] << 8)) | ((ptr)[(index) + 1]))
|
||||||
#define SET16(ptr,index,value) do { \
|
#define SET16(ptr,index,value) do { \
|
||||||
(ptr)[index] = ((value) >> 8) & 0xff; \
|
(ptr)[index] = ((value) >> 8) & 0xff; \
|
||||||
|
@ -1309,9 +1303,8 @@ compress_hdr_ipv6(rimeaddr_t *rime_destaddr)
|
||||||
static void
|
static void
|
||||||
packet_sent(void *ptr, int status, int transmissions)
|
packet_sent(void *ptr, int status, int transmissions)
|
||||||
{
|
{
|
||||||
#if SICSLOWPAN_CONF_NEIGHBOR_INFO
|
uip_ds6_link_neighbor_callback(status, transmissions);
|
||||||
neighbor_info_packet_sent(status, transmissions);
|
|
||||||
#endif /* SICSLOWPAN_CONF_NEIGHBOR_INFO */
|
|
||||||
if(callback != NULL) {
|
if(callback != NULL) {
|
||||||
callback->output_callback(status);
|
callback->output_callback(status);
|
||||||
}
|
}
|
||||||
|
@ -1834,10 +1827,6 @@ input(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SICSLOWPAN_CONF_NEIGHBOR_INFO
|
|
||||||
neighbor_info_packet_received();
|
|
||||||
#endif /* SICSLOWPAN_CONF_NEIGHBOR_INFO */
|
|
||||||
|
|
||||||
/* if callback is set then set attributes and call */
|
/* if callback is set then set attributes and call */
|
||||||
if(callback) {
|
if(callback) {
|
||||||
set_packet_attrs();
|
set_packet_attrs();
|
||||||
|
|
|
@ -61,6 +61,13 @@ void NEIGHBOR_STATE_CHANGED(uip_ds6_nbr_t *n);
|
||||||
#define NEIGHBOR_STATE_CHANGED(n)
|
#define NEIGHBOR_STATE_CHANGED(n)
|
||||||
#endif /* UIP_DS6_CONF_NEIGHBOR_STATE_CHANGED */
|
#endif /* UIP_DS6_CONF_NEIGHBOR_STATE_CHANGED */
|
||||||
|
|
||||||
|
#ifdef UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK
|
||||||
|
#define LINK_NEIGHBOR_CALLBACK(addr, status, numtx) UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK(addr, status, numtx)
|
||||||
|
void LINK_NEIGHBOR_CALLBACK(const rimeaddr_t *addr, int status, int numtx);
|
||||||
|
#else
|
||||||
|
#define LINK_NEIGHBOR_CALLBACK(addr, status, numtx)
|
||||||
|
#endif /* UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK */
|
||||||
|
|
||||||
NEIGHBOR_TABLE_GLOBAL(uip_ds6_nbr_t, ds6_neighbors);
|
NEIGHBOR_TABLE_GLOBAL(uip_ds6_nbr_t, ds6_neighbors);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -166,6 +173,33 @@ uip_ds6_nbr_lladdr_from_ipaddr(uip_ipaddr_t *ipaddr)
|
||||||
uip_ds6_nbr_t *nbr = uip_ds6_nbr_lookup(ipaddr);
|
uip_ds6_nbr_t *nbr = uip_ds6_nbr_lookup(ipaddr);
|
||||||
return nbr ? uip_ds6_nbr_get_ll(nbr) : NULL;
|
return nbr ? uip_ds6_nbr_get_ll(nbr) : NULL;
|
||||||
}
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_ds6_link_neighbor_callback(int status, int numtx)
|
||||||
|
{
|
||||||
|
const rimeaddr_t *dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
|
||||||
|
if(rimeaddr_cmp(dest, &rimeaddr_null)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LINK_NEIGHBOR_CALLBACK(dest, status, numtx);
|
||||||
|
|
||||||
|
#if UIP_DS6_LL_NUD
|
||||||
|
if(status == MAC_TX_OK) {
|
||||||
|
uip_ds6_nbr_t *nbr;
|
||||||
|
nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest);
|
||||||
|
if(nbr != NULL &&
|
||||||
|
(nbr->state == STALE || nbr->state == DELAY || nbr->state == PROBE)) {
|
||||||
|
nbr->state = REACHABLE;
|
||||||
|
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
|
||||||
|
PRINTF("uip-ds6-neighbor : received a link layer ACK : ");
|
||||||
|
PRINTLLADDR((uip_lladdr_t *)dest);
|
||||||
|
PRINTF(" is reachable.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* UIP_DS6_LL_NUD */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
|
|
@ -81,6 +81,7 @@ uip_ds6_nbr_t *uip_ds6_nbr_lookup(uip_ipaddr_t *ipaddr);
|
||||||
uip_ds6_nbr_t *uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr);
|
uip_ds6_nbr_t *uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr);
|
||||||
uip_ipaddr_t *uip_ds6_nbr_ipaddr_from_lladdr(uip_lladdr_t *lladdr);
|
uip_ipaddr_t *uip_ds6_nbr_ipaddr_from_lladdr(uip_lladdr_t *lladdr);
|
||||||
uip_lladdr_t *uip_ds6_nbr_lladdr_from_ipaddr(uip_ipaddr_t *ipaddr);
|
uip_lladdr_t *uip_ds6_nbr_lladdr_from_ipaddr(uip_ipaddr_t *ipaddr);
|
||||||
|
void uip_ds6_link_neighbor_callback(int status, int numtx);
|
||||||
void uip_ds6_neighbor_periodic();
|
void uip_ds6_neighbor_periodic();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -203,6 +203,13 @@ typedef struct uip_ds6_maddr {
|
||||||
#endif /* UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED */
|
#endif /* UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED */
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
#endif /* UIP_CONF_IPV6_RPL */
|
||||||
|
|
||||||
|
#if UIP_CONF_IPV6_RPL
|
||||||
|
#ifndef UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK
|
||||||
|
#define UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK rpl_link_neighbor_callback
|
||||||
|
#endif /* UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED */
|
||||||
|
#endif /* UIP_CONF_IPV6_RPL */
|
||||||
|
|
||||||
|
|
||||||
/** \brief Interface structure (contains all the interface variables) */
|
/** \brief Interface structure (contains all the interface variables) */
|
||||||
typedef struct uip_ds6_netif {
|
typedef struct uip_ds6_netif {
|
||||||
uint32_t link_mtu;
|
uint32_t link_mtu;
|
||||||
|
|
Loading…
Reference in a new issue