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 = \
|
||||
dhcpc.c \
|
||||
hc.c \
|
||||
neighbor-attr.c \
|
||||
neighbor-info.c \
|
||||
neighbor-table.c \
|
||||
netstack.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
|
||||
*/
|
||||
#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
|
||||
#define RPL_INIT_LINK_METRIC NEIGHBOR_INFO_ETX2FIX(RPL_CONF_INIT_LINK_METRIC)
|
||||
#define RPL_INIT_LINK_METRIC RPL_CONF_INIT_LINK_METRIC
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -56,8 +56,6 @@
|
|||
#define DEBUG DEBUG_NONE
|
||||
#include "net/uip-debug.h"
|
||||
|
||||
#include "net/neighbor-info.h"
|
||||
|
||||
#if UIP_CONF_IPV6
|
||||
/*---------------------------------------------------------------------------*/
|
||||
extern rpl_of_t RPL_OF;
|
||||
|
|
|
@ -45,13 +45,13 @@
|
|||
*/
|
||||
|
||||
#include "net/rpl/rpl-private.h"
|
||||
#include "net/neighbor-info.h"
|
||||
#include "net/neighbor-table.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/uip-debug.h"
|
||||
|
||||
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_dag_t *best_dag(rpl_dag_t *, rpl_dag_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 = {
|
||||
reset,
|
||||
parent_state_callback,
|
||||
neighbor_link_callback,
|
||||
best_parent,
|
||||
best_dag,
|
||||
calculate_rank,
|
||||
|
@ -67,6 +67,10 @@ rpl_of_t rpl_mrhof = {
|
|||
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. */
|
||||
#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;
|
||||
} else {
|
||||
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
|
||||
return p->rank + (uint16_t)link_metric;
|
||||
#elif RPL_DAG_MC == RPL_DAG_MC_ETX
|
||||
|
@ -105,8 +108,29 @@ reset(rpl_dag_t *sag)
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -119,10 +143,10 @@ calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank)
|
|||
if(base_rank == 0) {
|
||||
return INFINITE_RANK;
|
||||
}
|
||||
rank_increase = NEIGHBOR_INFO_FIX2ETX(RPL_INIT_LINK_METRIC) * RPL_MIN_HOPRANKINC;
|
||||
rank_increase = RPL_INIT_LINK_METRIC;
|
||||
} else {
|
||||
/* 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) {
|
||||
base_rank = p->rank;
|
||||
}
|
||||
|
|
|
@ -44,8 +44,6 @@
|
|||
#define DEBUG DEBUG_NONE
|
||||
#include "net/uip-debug.h"
|
||||
|
||||
#include "net/neighbor-info.h"
|
||||
|
||||
static void reset(rpl_dag_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 *);
|
||||
|
@ -64,7 +62,7 @@ rpl_of_t rpl_of0 = {
|
|||
|
||||
#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
|
||||
reset(rpl_dag_t *dag)
|
||||
|
@ -137,9 +135,9 @@ best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
|
|||
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;
|
||||
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;
|
||||
/* Compare two parents by looking both and their rank and at the ETX
|
||||
for that parent. We choose the parent that has the most
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
#include "net/tcpip.h"
|
||||
#include "net/uip-ds6.h"
|
||||
#include "net/rpl/rpl-private.h"
|
||||
#include "net/neighbor-info.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#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;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
|
||||
void
|
||||
rpl_link_neighbor_callback(const rimeaddr_t *addr, int status, int numtx)
|
||||
{
|
||||
uip_ipaddr_t ipaddr;
|
||||
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_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) {
|
||||
if(instance->used == 1 ) {
|
||||
|
@ -188,27 +184,12 @@ rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
|
|||
if(parent != NULL) {
|
||||
/* Trigger DAG rank recalculation. */
|
||||
parent->updated = 1;
|
||||
parent->link_metric = etx;
|
||||
|
||||
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(instance->of->neighbor_link_callback != NULL) {
|
||||
instance->of->neighbor_link_callback(parent, status, numtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!known) {
|
||||
PRINTF("RPL: Deleting routes installed by DAOs received from ");
|
||||
PRINT6ADDR(&ipaddr);
|
||||
PRINTF("\n");
|
||||
uip_ds6_route_rm_by_nexthop(&ipaddr);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -242,7 +223,6 @@ rpl_init(void)
|
|||
|
||||
rpl_dag_init();
|
||||
rpl_reset_periodic_timer();
|
||||
neighbor_info_subscribe(rpl_link_neighbor_callback);
|
||||
|
||||
/* add rpl multicast address */
|
||||
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
|
||||
* 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
|
||||
* 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 {
|
||||
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_dag_t *(*best_dag)(rpl_dag_t *, rpl_dag_t *);
|
||||
rpl_rank_t (*calculate_rank)(rpl_parent_t *, rpl_rank_t);
|
||||
|
|
|
@ -65,7 +65,6 @@
|
|||
#include "net/uip-ds6.h"
|
||||
#include "net/rime.h"
|
||||
#include "net/sicslowpan.h"
|
||||
#include "net/neighbor-info.h"
|
||||
#include "net/netstack.h"
|
||||
|
||||
#if UIP_CONF_IPV6
|
||||
|
@ -113,11 +112,6 @@ void uip_log(char *msg);
|
|||
#endif /* SICSLOWPAN_CONF_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 SET16(ptr,index,value) do { \
|
||||
(ptr)[index] = ((value) >> 8) & 0xff; \
|
||||
|
@ -1309,9 +1303,8 @@ compress_hdr_ipv6(rimeaddr_t *rime_destaddr)
|
|||
static void
|
||||
packet_sent(void *ptr, int status, int transmissions)
|
||||
{
|
||||
#if SICSLOWPAN_CONF_NEIGHBOR_INFO
|
||||
neighbor_info_packet_sent(status, transmissions);
|
||||
#endif /* SICSLOWPAN_CONF_NEIGHBOR_INFO */
|
||||
uip_ds6_link_neighbor_callback(status, transmissions);
|
||||
|
||||
if(callback != NULL) {
|
||||
callback->output_callback(status);
|
||||
}
|
||||
|
@ -1834,10 +1827,6 @@ input(void)
|
|||
}
|
||||
#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) {
|
||||
set_packet_attrs();
|
||||
|
|
|
@ -61,6 +61,13 @@ void NEIGHBOR_STATE_CHANGED(uip_ds6_nbr_t *n);
|
|||
#define NEIGHBOR_STATE_CHANGED(n)
|
||||
#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);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -166,6 +173,33 @@ uip_ds6_nbr_lladdr_from_ipaddr(uip_ipaddr_t *ipaddr)
|
|||
uip_ds6_nbr_t *nbr = uip_ds6_nbr_lookup(ipaddr);
|
||||
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
|
||||
|
|
|
@ -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_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);
|
||||
void uip_ds6_link_neighbor_callback(int status, int numtx);
|
||||
void uip_ds6_neighbor_periodic();
|
||||
|
||||
/**
|
||||
|
|
|
@ -203,6 +203,13 @@ typedef struct uip_ds6_maddr {
|
|||
#endif /* UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED */
|
||||
#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) */
|
||||
typedef struct uip_ds6_netif {
|
||||
uint32_t link_mtu;
|
||||
|
|
Loading…
Reference in a new issue