Renamed the neighbor module to collect-neighbor, as it is only used by the collect module and is not a generic neighbor module

This commit is contained in:
adamdunkels 2010-03-19 13:17:00 +00:00
parent 137e02baac
commit 7b0606cd58
3 changed files with 490 additions and 34 deletions

View file

@ -0,0 +1,354 @@
/**
* \addtogroup rimecollect_neighbor
* @{
*/
/*
* Copyright (c) 2006, 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.
*
* $Id: collect-neighbor.c,v 1.1 2010/03/19 13:17:00 adamdunkels Exp $
*/
/**
* \file
* Radio neighborhood management
* \author
* Adam Dunkels <adam@sics.se>
*/
#include <limits.h>
#include <stdio.h>
#include "contiki.h"
#include "lib/memb.h"
#include "lib/list.h"
#include "net/rime/collect-neighbor.h"
#include "net/rime/ctimer.h"
#include "net/rime/collect.h"
#ifdef COLLECT_NEIGHBOR_CONF_MAX_COLLECT_NEIGHBORS
#define MAX_COLLECT_NEIGHBORS COLLECT_NEIGHBOR_CONF_MAX_COLLECT_NEIGHBORS
#else /* COLLECT_NEIGHBOR_CONF_MAX_COLLECT_NEIGHBORS */
#define MAX_COLLECT_NEIGHBORS 8
#endif /* COLLECT_NEIGHBOR_CONF_MAX_COLLECT_NEIGHBORS */
#define RTMETRIC_MAX COLLECT_MAX_DEPTH
MEMB(collect_neighbors_mem, struct collect_neighbor, MAX_COLLECT_NEIGHBORS);
LIST(collect_neighbors_list);
/*static struct collect_neighbor collect_neighbors[MAX_COLLECT_NEIGHBORS];*/
static struct ctimer t;
static int max_time = 2400;
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/*---------------------------------------------------------------------------*/
static void
periodic(void *ptr)
{
struct collect_neighbor *n, *next;
/* Go through all collect_neighbors and remove old ones. */
for(n = list_head(collect_neighbors_list); n != NULL; n = next) {
next = NULL;
/* for(i = 0; i < MAX_COLLECT_NEIGHBORS; ++i) {*/
if(!rimeaddr_cmp(&n->addr, &rimeaddr_null) &&
n->time < max_time) {
n->time++;
if(n->time == max_time) {
n->rtmetric = RTMETRIC_MAX;
PRINTF("%d.%d: removing old collect_neighbor %d.%d\n",
rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1],
n->addr.u8[0], n->addr.u8[1]);
rimeaddr_copy(&n->addr, &rimeaddr_null);
next = n->next;
list_remove(collect_neighbors_list, n);
memb_free(&collect_neighbors_mem, n);
}
}
if(next == NULL) {
next = n->next;
}
}
/* PRINTF("collect_neighbor periodic\n");*/
ctimer_set(&t, CLOCK_SECOND, periodic, NULL);
}
/*---------------------------------------------------------------------------*/
void
collect_neighbor_init(void)
{
static uint8_t initialized = 0;
if(initialized == 0) {
initialized = 1;
memb_init(&collect_neighbors_mem);
list_init(collect_neighbors_list);
ctimer_set(&t, CLOCK_SECOND, periodic, NULL);
}
}
/*---------------------------------------------------------------------------*/
struct collect_neighbor *
collect_neighbor_find(const rimeaddr_t *addr)
{
struct collect_neighbor *n;
for(n = list_head(collect_neighbors_list); n != NULL; n = n->next) {
if(rimeaddr_cmp(&n->addr, addr)) {
return n;
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
void
collect_neighbor_update(struct collect_neighbor *n, uint8_t rtmetric)
{
if(n != NULL) {
PRINTF("%d.%d: collect_neighbor_update %d.%d rtmetric %d\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
n->addr.u8[0], n->addr.u8[1], rtmetric);
n->rtmetric = rtmetric;
n->time = 0;
}
}
/*---------------------------------------------------------------------------*/
void
collect_neighbor_timedout_etx(struct collect_neighbor *n, uint8_t etx)
{
if(n != NULL) {
n->etxs[n->etxptr] += etx;
if(n->etxs[n->etxptr] > RTMETRIC_MAX / COLLECT_NEIGHBOR_ETX_SCALE) {
n->etxs[n->etxptr] = RTMETRIC_MAX / COLLECT_NEIGHBOR_ETX_SCALE;
}
n->etxptr = (n->etxptr + 1) % COLLECT_NEIGHBOR_NUM_ETXS;
}
}
/*---------------------------------------------------------------------------*/
void
collect_neighbor_update_etx(struct collect_neighbor *n, uint8_t etx)
{
if(n != NULL) {
n->etxs[n->etxptr] = etx;
n->etxptr = (n->etxptr + 1) % COLLECT_NEIGHBOR_NUM_ETXS;
n->time = 0;
}
}
/*---------------------------------------------------------------------------*/
uint8_t
collect_neighbor_etx(struct collect_neighbor *n)
{
int i, etx;
etx = 0;
for(i = 0; i < COLLECT_NEIGHBOR_NUM_ETXS; ++i) {
etx += n->etxs[i];
}
return COLLECT_NEIGHBOR_ETX_SCALE * etx / COLLECT_NEIGHBOR_NUM_ETXS;
}
/*---------------------------------------------------------------------------*/
void
collect_neighbor_add(const rimeaddr_t *addr, uint8_t nrtmetric, uint8_t netx)
{
uint16_t rtmetric;
uint16_t etx;
struct collect_neighbor *n, *max;
int i;
PRINTF("collect_neighbor_add: adding %d.%d\n", addr->u8[0], addr->u8[1]);
/* Check if the collect_neighbor is already on the list. */
for(n = list_head(collect_neighbors_list); n != NULL; n = n->next) {
if(rimeaddr_cmp(&n->addr, &rimeaddr_null) ||
rimeaddr_cmp(&n->addr, addr)) {
PRINTF("collect_neighbor_add: already on list %d.%d\n", addr->u8[0], addr->u8[1]);
break;
}
}
/* If the collect_neighbor was not on the list, we try to allocate memory
for it. */
if(n == NULL) {
PRINTF("collect_neighbor_add: not on list, allocating %d.%d\n", addr->u8[0], addr->u8[1]);
n = memb_alloc(&collect_neighbors_mem);
if(n != NULL) {
list_add(collect_neighbors_list, n);
}
}
/* If we could not allocate memory, we try to recycle an old
collect_neighbor */
if(n == NULL) {
PRINTF("collect_neighbor_add: not on list, not allocated, recycling %d.%d\n", addr->u8[0], addr->u8[1]);
/* Find the first unused entry or the used entry with the highest
rtmetric and highest etx. */
rtmetric = 0;
etx = 0;
max = NULL;
for(n = list_head(collect_neighbors_list); n != NULL; n = n->next) {
if(!rimeaddr_cmp(&n->addr, &rimeaddr_null)) {
if(n->rtmetric > rtmetric) {
rtmetric = n->rtmetric;
etx = collect_neighbor_etx(n);
max = n;
} else if(n->rtmetric == rtmetric) {
if(collect_neighbor_etx(n) > etx) {
rtmetric = n->rtmetric;
etx = collect_neighbor_etx(n);
max = n;
/* PRINTF("%d: found worst collect_neighbor %d with rtmetric %d, signal %d\n",
node_id, collect_neighbors[n].nodeid, rtmetric, signal);*/
}
}
}
}
n = max;
}
/* PRINTF("%d: adding collect_neighbor %d with rtmetric %d, signal %d at %d\n",
node_id, collect_neighbors[n].nodeid, rtmetric, signal, n);*/
if(n != NULL) {
n->time = 0;
rimeaddr_copy(&n->addr, addr);
n->rtmetric = nrtmetric;
for(i = 0; i < COLLECT_NEIGHBOR_NUM_ETXS; ++i) {
n->etxs[i] = netx;
}
n->etxptr = 0;
}
}
/*---------------------------------------------------------------------------*/
void
collect_neighbor_remove(const rimeaddr_t *addr)
{
struct collect_neighbor *n;
for(n = list_head(collect_neighbors_list); n != NULL; n = n->next) {
if(rimeaddr_cmp(&n->addr, addr)) {
PRINTF("%d.%d: removing %d.%d\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
addr->u8[0], addr->u8[1]);
rimeaddr_copy(&n->addr, &rimeaddr_null);
n->rtmetric = RTMETRIC_MAX;
list_remove(collect_neighbors_list, n);
memb_free(&collect_neighbors_mem, n);
return;
}
}
/* int i;
for(i = 0; i < MAX_COLLECT_NEIGHBORS; ++i) {
if(rimeaddr_cmp(&collect_neighbors[i].addr, addr)) {
PRINTF("%d: removing %d @ %d\n", rimeaddr_node_addr.u16[0], addr->u16[0], i);
rimeaddr_copy(&collect_neighbors[i].addr, &rimeaddr_null);
collect_neighbors[i].rtmetric = RTMETRIC_MAX;
return;
}
}*/
}
/*---------------------------------------------------------------------------*/
struct collect_neighbor *
collect_neighbor_best(void)
{
int found;
/* int lowest, best;*/
struct collect_neighbor *n, *best;
uint16_t rtmetric;
rtmetric = RTMETRIC_MAX;
best = NULL;
found = 0;
/* PRINTF("%d: ", node_id);*/
/* Find the lowest rtmetric. */
for(n = list_head(collect_neighbors_list); n != NULL; n = n->next) {
PRINTF("collect_neighbor_best: checking %d.%d with rtmetric %d + %d\n",
n->addr.u8[0], n->addr.u8[1],
n->rtmetric, collect_neighbor_etx(n));
if(!rimeaddr_cmp(&n->addr, &rimeaddr_null) &&
rtmetric > n->rtmetric + collect_neighbor_etx(n)) {
rtmetric = n->rtmetric + collect_neighbor_etx(n);
best = n;
}
}
return best;
}
/*---------------------------------------------------------------------------*/
void
collect_neighbor_set_lifetime(int seconds)
{
max_time = seconds;
}
/*---------------------------------------------------------------------------*/
int
collect_neighbor_num(void)
{
PRINTF("collect_neighbor_num %d\n", list_length(collect_neighbors_list));
return list_length(collect_neighbors_list);
}
/*---------------------------------------------------------------------------*/
struct collect_neighbor *
collect_neighbor_get(int num)
{
int i;
struct collect_neighbor *n;
PRINTF("collect_neighbor_get %d\n", num);
i = 0;
for(n = list_head(collect_neighbors_list); n != NULL; n = n->next) {
if(i == num) {
PRINTF("collect_neighbor_get found %d.%d\n", n->addr.u8[0], n->addr.u8[1]);
return n;
}
i++;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
void
collect_neighbor_purge(void)
{
memb_init(&collect_neighbors_mem);
list_init(collect_neighbors_list);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,89 @@
/**
* \addtogroup rime
* @{
*/
/**
* \defgroup rimeneighbor Rime neighbor management
* @{
*
* The neighbor module manages the neighbor table.
*/
/*
* Copyright (c) 2006, 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.
*
* $Id: collect-neighbor.h,v 1.1 2010/03/19 13:17:00 adamdunkels Exp $
*/
/**
* \file
* Header file for the Contiki radio neighborhood management
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __COLLECT_NEIGHBOR_H__
#define __COLLECT_NEIGHBOR_H__
#include "net/rime/rimeaddr.h"
#define COLLECT_NEIGHBOR_ETX_SCALE 16
#define COLLECT_NEIGHBOR_NUM_ETXS 4
struct collect_neighbor {
struct collect_neighbor *next;
uint16_t time;
rimeaddr_t addr;
uint16_t rtmetric;
uint8_t etxptr;
uint8_t etxs[COLLECT_NEIGHBOR_NUM_ETXS];
};
void collect_neighbor_init(void);
/*void collect_neighbor_periodic(int max_time);*/
void collect_neighbor_add(const rimeaddr_t *addr, uint8_t rtmetric, uint8_t etx);
void collect_neighbor_update(struct collect_neighbor *n, uint8_t rtmetric);
void collect_neighbor_update_etx(struct collect_neighbor *n, uint8_t etx);
void collect_neighbor_timedout_etx(struct collect_neighbor *n, uint8_t etx);
void collect_neighbor_remove(const rimeaddr_t *addr);
struct collect_neighbor *collect_neighbor_find(const rimeaddr_t *addr);
struct collect_neighbor *collect_neighbor_best(void);
void collect_neighbor_set_lifetime(int seconds);
uint8_t collect_neighbor_etx(struct collect_neighbor *n);
int collect_neighbor_num(void);
struct collect_neighbor *collect_neighbor_get(int num);
void collect_neighbor_purge(void);
#endif /* __COLLECT_NEIGHBOR_H__ */
/** @} */
/** @} */

View file

@ -33,7 +33,7 @@
* *
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
* $Id: collect.c,v 1.40 2010/03/16 18:12:34 adamdunkels Exp $ * $Id: collect.c,v 1.41 2010/03/19 13:17:00 adamdunkels Exp $
*/ */
/** /**
@ -46,7 +46,7 @@
#include "contiki.h" #include "contiki.h"
#include "net/rime.h" #include "net/rime.h"
#include "net/rime/neighbor.h" #include "net/rime/collect-neighbor.h"
#include "net/rime/collect.h" #include "net/rime/collect.h"
#include "net/rime/packetqueue.h" #include "net/rime/packetqueue.h"
@ -119,7 +119,7 @@ static void retransmit_callback(void *ptr);
static void static void
update_rtmetric(struct collect_conn *tc) update_rtmetric(struct collect_conn *tc)
{ {
struct neighbor *n; struct collect_neighbor *n;
PRINTF("update_rtmetric: tc->rtmetric %d\n", tc->rtmetric); PRINTF("update_rtmetric: tc->rtmetric %d\n", tc->rtmetric);
@ -127,7 +127,7 @@ update_rtmetric(struct collect_conn *tc)
if(tc->rtmetric != SINK) { if(tc->rtmetric != SINK) {
/* Find the neighbor with the lowest rtmetric. */ /* Find the neighbor with the lowest rtmetric. */
n = neighbor_best(); n = collect_neighbor_best();
/* If n is NULL, we have no best neighbor. */ /* If n is NULL, we have no best neighbor. */
if(n == NULL) { if(n == NULL) {
@ -148,23 +148,28 @@ update_rtmetric(struct collect_conn *tc)
} else { } else {
/* We set our rtmetric to the rtmetric of our best neighbor plus /* We set our rtmetric to the rtmetric of our best neighbor plus
the expected transmissions to reach that neighbor. */ the expected transmissions to reach that neighbor. */
if(n->rtmetric + neighbor_etx(n) != tc->rtmetric) { if(n->rtmetric + collect_neighbor_etx(n) != tc->rtmetric) {
uint16_t old_rtmetric = tc->rtmetric; uint16_t old_rtmetric = tc->rtmetric;
tc->rtmetric = n->rtmetric + neighbor_etx(n); tc->rtmetric = n->rtmetric + collect_neighbor_etx(n);
#if ! COLLECT_ANNOUNCEMENTS #if ! COLLECT_ANNOUNCEMENTS
/* If we get a significantly better rtmetric than we had /* If we get a significantly better rtmetric than we had
before, we call neighbor_discovery_start to start a new before, we call neighbor_discovery_start to start a new
period. */ period. */
if(old_rtmetric >= tc->rtmetric + NEIGHBOR_ETX_SCALE + NEIGHBOR_ETX_SCALE / 2) { if(old_rtmetric >= tc->rtmetric + COLLECT_NEIGHBOR_ETX_SCALE + COLLECT_NEIGHBOR_ETX_SCALE / 2 ||
old_rtmetric == SINK) {
neighbor_discovery_start(&tc->neighbor_discovery_conn, tc->rtmetric); neighbor_discovery_start(&tc->neighbor_discovery_conn, tc->rtmetric);
} else { } else {
neighbor_discovery_set_val(&tc->neighbor_discovery_conn, tc->rtmetric); neighbor_discovery_set_val(&tc->neighbor_discovery_conn, tc->rtmetric);
} }
#else /* ! COLLECT_ANNOUNCEMENTS */ #else /* ! COLLECT_ANNOUNCEMENTS */
announcement_set_value(&tc->announcement, tc->rtmetric); announcement_set_value(&tc->announcement, tc->rtmetric);
if(old_rtmetric >= tc->rtmetric + COLLECT_NEIGHBOR_ETX_SCALE + COLLECT_NEIGHBOR_ETX_SCALE / 2 ||
old_rtmetric == SINK) {
announcement_bump(&tc->announcement);
}
#endif /* ! COLLECT_ANNOUNCEMENTS */ #endif /* ! COLLECT_ANNOUNCEMENTS */
PRINTF("%d.%d: new rtmetric %d\n", PRINTF("%d.%d: new rtmetric %d\n",
@ -186,7 +191,7 @@ update_rtmetric(struct collect_conn *tc)
if(tc->rtmetric == RTMETRIC_MAX) { if(tc->rtmetric == RTMETRIC_MAX) {
strcpy(buf, " "); strcpy(buf, " ");
} else { } else {
sPRINTF(buf, "%.1f", (float)tc->rtmetric / NEIGHBOR_ETX_SCALE); PRINTF(buf, "%.1f", (float)tc->rtmetric / COLLECT_NEIGHBOR_ETX_SCALE);
} }
ether_set_text(buf); ether_set_text(buf);
} }
@ -197,7 +202,7 @@ static void
send_queued_packet(void) send_queued_packet(void)
{ {
struct queuebuf *q; struct queuebuf *q;
struct neighbor *n; struct collect_neighbor *n;
struct packetqueue_item *i; struct packetqueue_item *i;
struct collect_conn *c; struct collect_conn *c;
@ -234,15 +239,15 @@ send_queued_packet(void)
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]); rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
queuebuf_to_packetbuf(q); queuebuf_to_packetbuf(q);
n = neighbor_best(); n = collect_neighbor_best();
while(n != NULL && rimeaddr_cmp(&n->addr, packetbuf_addr(PACKETBUF_ADDR_SENDER))) { while(n != NULL && rimeaddr_cmp(&n->addr, packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
PRINTF("%d.%d: avoiding fowarding loop to %d.%d\n", PRINTF("%d.%d: avoiding fowarding loop to %d.%d\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
n->addr.u8[0], n->addr.u8[1]); n->addr.u8[0], n->addr.u8[1]);
neighbor_remove(&n->addr); collect_neighbor_remove(&n->addr);
update_rtmetric(c); update_rtmetric(c);
n = neighbor_best(); n = collect_neighbor_best();
} }
/* Don't send to the neighbor if it is the same neighbor that sent /* Don't send to the neighbor if it is the same neighbor that sent
@ -304,7 +309,7 @@ handle_ack(struct collect_conn *tc)
{ {
struct ack_msg *msg; struct ack_msg *msg;
uint16_t rtmetric; uint16_t rtmetric;
struct neighbor *n; struct collect_neighbor *n;
if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER), if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER),
&tc->current_receiver) && &tc->current_receiver) &&
@ -313,9 +318,9 @@ handle_ack(struct collect_conn *tc)
msg = packetbuf_dataptr(); msg = packetbuf_dataptr();
memcpy(&rtmetric, &msg->rtmetric, sizeof(uint16_t)); memcpy(&rtmetric, &msg->rtmetric, sizeof(uint16_t));
n = neighbor_find(packetbuf_addr(PACKETBUF_ADDR_SENDER)); n = collect_neighbor_find(packetbuf_addr(PACKETBUF_ADDR_SENDER));
if(n != NULL) { if(n != NULL) {
neighbor_update(n, rtmetric); collect_neighbor_update(n, rtmetric);
update_rtmetric(tc); update_rtmetric(tc);
} }
@ -387,7 +392,7 @@ node_packet_received(struct unicast_conn *c, const rimeaddr_t *from)
struct collect_conn *tc = (struct collect_conn *) struct collect_conn *tc = (struct collect_conn *)
((char *)c - offsetof(struct collect_conn, unicast_conn)); ((char *)c - offsetof(struct collect_conn, unicast_conn));
int i; int i;
struct neighbor *n; struct collect_neighbor *n;
/* To protect against sending duplicate packets, we keep a list /* To protect against sending duplicate packets, we keep a list
of recently forwarded packet seqnos. If the seqno of the current of recently forwarded packet seqnos. If the seqno of the current
@ -426,9 +431,9 @@ node_packet_received(struct unicast_conn *c, const rimeaddr_t *from)
packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID), packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0], packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],
packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1]); packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1]);
n = neighbor_find(&recent_packets[i].sent_to); n = collect_neighbor_find(&recent_packets[i].sent_to);
if(n != NULL) { if(n != NULL) {
neighbor_update_etx(n, neighbor_etx(n) / NEIGHBOR_ETX_SCALE + 4); collect_neighbor_update_etx(n, collect_neighbor_etx(n) / COLLECT_NEIGHBOR_ETX_SCALE + 4);
update_rtmetric(tc); update_rtmetric(tc);
} }
break; break;
@ -437,10 +442,10 @@ node_packet_received(struct unicast_conn *c, const rimeaddr_t *from)
recent_packets[recent_packet_ptr].seqno = packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID); recent_packets[recent_packet_ptr].seqno = packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID);
rimeaddr_copy(&recent_packets[recent_packet_ptr].originator, rimeaddr_copy(&recent_packets[recent_packet_ptr].originator,
packetbuf_addr(PACKETBUF_ADDR_ESENDER)); packetbuf_addr(PACKETBUF_ADDR_ESENDER));
/* n = neighbor_best();*/ /* n = collect_neighbor_best();*/
if(tc->rtmetric != SINK) { if(tc->rtmetric != SINK) {
n = neighbor_best(); n = collect_neighbor_best();
rimeaddr_copy(&recent_packets[recent_packet_ptr].sent_to, rimeaddr_copy(&recent_packets[recent_packet_ptr].sent_to,
&n->addr); &n->addr);
} else { } else {
@ -551,7 +556,7 @@ node_packet_sent(struct unicast_conn *c, int status, int transmissions)
/* Update ETX with the number of transmissions. */ /* Update ETX with the number of transmissions. */
PRINTF("Updating ETX with %d transmissions (punished %d)\n", tc->transmissions, PRINTF("Updating ETX with %d transmissions (punished %d)\n", tc->transmissions,
tx); tx);
neighbor_update_etx(neighbor_find(&tc->current_receiver), tx); collect_neighbor_update_etx(collect_neighbor_find(&tc->current_receiver), tx);
update_rtmetric(tc); update_rtmetric(tc);
} }
} }
@ -564,7 +569,7 @@ timedout(struct collect_conn *tc)
tc->max_rexmits); tc->max_rexmits);
tc->sending = 0; tc->sending = 0;
neighbor_timedout_etx(neighbor_find(&tc->current_receiver), tc->transmissions); collect_neighbor_timedout_etx(collect_neighbor_find(&tc->current_receiver), tc->transmissions);
update_rtmetric(tc); update_rtmetric(tc);
send_next_packet(tc); send_next_packet(tc);
@ -591,14 +596,14 @@ adv_received(struct neighbor_discovery_conn *c, const rimeaddr_t *from,
{ {
struct collect_conn *tc = (struct collect_conn *) struct collect_conn *tc = (struct collect_conn *)
((char *)c - offsetof(struct collect_conn, neighbor_discovery_conn)); ((char *)c - offsetof(struct collect_conn, neighbor_discovery_conn));
struct neighbor *n; struct collect_neighbor *n;
n = neighbor_find(from); n = collect_neighbor_find(from);
if(n == NULL) { if(n == NULL) {
neighbor_add(from, rtmetric, 1); collect_neighbor_add(from, rtmetric, 1);
} else { } else {
neighbor_update(n, rtmetric); collect_neighbor_update(n, rtmetric);
PRINTF("%d.%d: updating neighbor %d.%d, etx %d\n", PRINTF("%d.%d: updating neighbor %d.%d, etx %d\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
n->addr.u8[0], n->addr.u8[1], rtmetric); n->addr.u8[0], n->addr.u8[1], rtmetric);
@ -613,17 +618,17 @@ received_announcement(struct announcement *a, const rimeaddr_t *from,
{ {
struct collect_conn *tc = (struct collect_conn *) struct collect_conn *tc = (struct collect_conn *)
((char *)a - offsetof(struct collect_conn, announcement)); ((char *)a - offsetof(struct collect_conn, announcement));
struct neighbor *n; struct collect_neighbor *n;
n = neighbor_find(from); n = collect_neighbor_find(from);
if(n == NULL) { if(n == NULL) {
neighbor_add(from, value, 1); collect_neighbor_add(from, value, 1);
PRINTF("%d.%d: new neighbor %d.%d, etx %d\n", PRINTF("%d.%d: new neighbor %d.%d, etx %d\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
from->u8[0], from->u8[1], value); from->u8[0], from->u8[1], value);
} else { } else {
neighbor_update(n, value); collect_neighbor_update(n, value);
PRINTF("%d.%d: updating neighbor %d.%d, etx %d\n", PRINTF("%d.%d: updating neighbor %d.%d, etx %d\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
n->addr.u8[0], n->addr.u8[1], value); n->addr.u8[0], n->addr.u8[1], value);
@ -648,7 +653,7 @@ collect_open(struct collect_conn *tc, uint16_t channels,
channel_set_attributes(channels + 1, attributes); channel_set_attributes(channels + 1, attributes);
tc->rtmetric = RTMETRIC_MAX; tc->rtmetric = RTMETRIC_MAX;
tc->cb = cb; tc->cb = cb;
neighbor_init(); collect_neighbor_init();
packetqueue_init(&sending_queue); packetqueue_init(&sending_queue);
#if !COLLECT_ANNOUNCEMENTS #if !COLLECT_ANNOUNCEMENTS
@ -661,7 +666,6 @@ collect_open(struct collect_conn *tc, uint16_t channels,
#else /* !COLLECT_ANNOUNCEMENTS */ #else /* !COLLECT_ANNOUNCEMENTS */
announcement_register(&tc->announcement, channels, tc->rtmetric, announcement_register(&tc->announcement, channels, tc->rtmetric,
received_announcement); received_announcement);
/* announcement_listen(2);*/
#endif /* !COLLECT_ANNOUNCEMENTS */ #endif /* !COLLECT_ANNOUNCEMENTS */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -684,6 +688,8 @@ collect_set_sink(struct collect_conn *tc, int should_be_sink)
PRINTF("collect_set_sink: tc->rtmetric %d\n", tc->rtmetric); PRINTF("collect_set_sink: tc->rtmetric %d\n", tc->rtmetric);
#if !COLLECT_ANNOUNCEMENTS #if !COLLECT_ANNOUNCEMENTS
neighbor_discovery_start(&tc->neighbor_discovery_conn, tc->rtmetric); neighbor_discovery_start(&tc->neighbor_discovery_conn, tc->rtmetric);
#else
announcement_bump(&tc->announcement);
#endif /* !COLLECT_ANNOUNCEMENTS */ #endif /* !COLLECT_ANNOUNCEMENTS */
} else { } else {
tc->rtmetric = RTMETRIC_MAX; tc->rtmetric = RTMETRIC_MAX;
@ -697,7 +703,7 @@ collect_set_sink(struct collect_conn *tc, int should_be_sink)
int int
collect_send(struct collect_conn *tc, int rexmits) collect_send(struct collect_conn *tc, int rexmits)
{ {
struct neighbor *n; struct collect_neighbor *n;
packetbuf_set_attr(PACKETBUF_ATTR_EPACKET_ID, tc->eseqno++); packetbuf_set_attr(PACKETBUF_ATTR_EPACKET_ID, tc->eseqno++);
packetbuf_set_addr(PACKETBUF_ADDR_ESENDER, &rimeaddr_node_addr); packetbuf_set_addr(PACKETBUF_ADDR_ESENDER, &rimeaddr_node_addr);
@ -723,7 +729,7 @@ collect_send(struct collect_conn *tc, int rexmits)
return 1; return 1;
} else { } else {
update_rtmetric(tc); update_rtmetric(tc);
n = neighbor_best(); n = collect_neighbor_best();
if(n != NULL) { if(n != NULL) {
#if CONTIKI_TARGET_NETSIM #if CONTIKI_TARGET_NETSIM
ether_set_line(n->addr.u8[0], n->addr.u8[1]); ether_set_line(n->addr.u8[0], n->addr.u8[1]);
@ -763,4 +769,11 @@ collect_depth(struct collect_conn *tc)
return tc->rtmetric; return tc->rtmetric;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void
collect_purge(struct collect_conn *tc)
{
collect_neighbor_purge();
update_rtmetric(tc);
}
/*---------------------------------------------------------------------------*/
/** @} */ /** @} */