From 17db783fb0ff021111506d22738aa592eb32c7d4 Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Fri, 19 Mar 2010 13:15:19 +0000 Subject: [PATCH] Broadcast announcement back-end that sends announcement data as broadcasts, with increasing transmission intervals --- core/net/rime/broadcast-announcement.c | 225 +++++++++++++++++++++++++ core/net/rime/broadcast-announcement.h | 70 ++++++++ 2 files changed, 295 insertions(+) create mode 100644 core/net/rime/broadcast-announcement.c create mode 100644 core/net/rime/broadcast-announcement.h diff --git a/core/net/rime/broadcast-announcement.c b/core/net/rime/broadcast-announcement.c new file mode 100644 index 000000000..8d7896fb2 --- /dev/null +++ b/core/net/rime/broadcast-announcement.c @@ -0,0 +1,225 @@ +/** + * \addtogroup rimeexamples + * @{ + */ + +/* + * 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: broadcast-announcement.c,v 1.1 2010/03/19 13:15:19 adamdunkels Exp $ + */ + +/** + * \file + * An example announcement back-end, based on the broadcast primitive + * \author + * Adam Dunkels + */ + +#include "contiki.h" + +#include "net/rime.h" +#include "net/rime/announcement.h" +#include "net/rime/broadcast.h" +#include "lib/random.h" + +#if NETSIM +#include "ether.h" +#endif + +#include +#include +#include + +struct announcement_data { + uint16_t id; + uint16_t value; +}; + +#ifdef BROADCAST_ANNOUNCEMENT_CONF_MAX_DUPS +#define NUM_DUPS BROADCAST_ANNOUNCEMENT_CONF_MAX_DUPS +#else /* BROADCAST_ANNOUNCEMENT_CONF_MAX_DUPS */ +#define NUM_DUPS 5 +#endif /* BROADCAST_ANNOUNCEMENT_CONF_MAX_DUPS */ + +#define ANNOUNCEMENT_MSG_HEADERLEN 2 +struct announcement_msg { + uint16_t num; + struct announcement_data data[]; +}; + + +struct broadcast_announcement_state { + struct broadcast_conn c; + struct ctimer send_timer, interval_timer; + clock_time_t initial_interval, min_interval, max_interval; + clock_time_t current_interval; + uint16_t val; +} c; + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#define MIN(a, b) ((a)<(b)?(a):(b)) + +/*---------------------------------------------------------------------------*/ +static void +send_adv(void *ptr) +{ + struct announcement_msg *adata; + struct announcement *a; + + packetbuf_clear(); + adata = packetbuf_dataptr(); + adata->num = 0; + for(a = announcement_list(); a != NULL; a = a->next) { + adata->data[adata->num].id = a->id; + adata->data[adata->num].value = a->value; + adata->num++; + } + + packetbuf_set_datalen(ANNOUNCEMENT_MSG_HEADERLEN + + sizeof(struct announcement_data) * adata->num); + + PRINTF("%d.%d: sending neighbor advertisement with %d announcements\n", + rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], adata->num); + + if(adata->num > 0) { + /* Send the packet only if it contains more than zero announcements. */ + broadcast_send(&c.c); + } + PRINTF("%d.%d: sending neighbor advertisement with val %d\n", + rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], + c.val); +} +/*---------------------------------------------------------------------------*/ +static void +adv_packet_received(struct broadcast_conn *ibc, const rimeaddr_t *from) +{ + struct announcement_msg adata; + int i; + + /* Copy number of announcements */ + memcpy(&adata, packetbuf_dataptr(), sizeof(struct announcement_msg)); + PRINTF("%d.%d: adv_packet_received from %d.%d with %d announcements\n", + rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], + from->u8[0], from->u8[1], adata.num); + + for(i = 0; i < adata.num; ++i) { + struct announcement_data data; + + /* Copy announcements */ + memcpy(&data.id, &((struct announcement_msg *)packetbuf_dataptr())->data[i].id, + sizeof(uint16_t)); + memcpy(&data.value, &((struct announcement_msg *)packetbuf_dataptr())->data[i].value, + sizeof(uint16_t)); + announcement_heard(from, + data.id, + data.value); + } +} +/*---------------------------------------------------------------------------*/ +static void +adv_packet_sent(struct broadcast_conn *bc, int status, int num_tx) +{ +} +/*---------------------------------------------------------------------------*/ +static void send_timer(void *ptr); + +static void +set_timers(void) +{ + ctimer_set(&c.interval_timer, c.current_interval, send_timer, NULL); + ctimer_set(&c.send_timer, c.current_interval / 2 + random_rand() % + (c.current_interval / 2), + send_adv, NULL); +} +/*---------------------------------------------------------------------------*/ +static void +send_timer(void *ptr) +{ + clock_time_t interval; + + interval = c.current_interval * 2; + + if(interval > c.max_interval) { + interval = c.max_interval; + } + + c.current_interval = interval; + + /* printf("current_interval %lu\n", (long unsigned int) interval);*/ + + set_timers(); +} +/*---------------------------------------------------------------------------*/ +static void +new_announcement(uint16_t id, uint16_t newval, uint16_t oldval, uint8_t bump) +{ + if(bump == ANNOUNCEMENT_BUMP) { + c.current_interval = c.initial_interval; + set_timers(); + } else if(newval != oldval) { + c.current_interval = c.min_interval; + set_timers(); + } +} +/*---------------------------------------------------------------------------*/ +static CC_CONST_FUNCTION struct broadcast_callbacks broadcast_callbacks = + {adv_packet_received, adv_packet_sent }; +/*---------------------------------------------------------------------------*/ +void +broadcast_announcement_init(uint16_t channel, + clock_time_t initial, + clock_time_t min, + clock_time_t max) +{ + broadcast_open(&c.c, channel, &broadcast_callbacks); + c.initial_interval = initial; + c.min_interval = min; + c.max_interval = max; + + announcement_register_observer_callback(new_announcement); +} +/*---------------------------------------------------------------------------*/ +void +broadcast_announcement_stop(void) +{ + ctimer_stop(&c.interval_timer); + ctimer_stop(&c.send_timer); + broadcast_close(&c.c); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/core/net/rime/broadcast-announcement.h b/core/net/rime/broadcast-announcement.h new file mode 100644 index 000000000..29a4e64f6 --- /dev/null +++ b/core/net/rime/broadcast-announcement.h @@ -0,0 +1,70 @@ +/** + * \addtogroup rime + * @{ + */ + +/** + * \defgroup rimebroadcastannouncement + * @{ + * + * The broadcast announcement module implements a periodic explicit + * announcement. THe module announces the announcements that have been + * registered with the \ref rimeannouncement "announcement module". + * + * \section channels Channels + * + * The broadcast announcement module uses 1 channel. + * + */ + +/* + * 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: broadcast-announcement.h,v 1.1 2010/03/19 13:15:19 adamdunkels Exp $ + */ + +/** + * \file + * Neighbor discovery header file + * \author + * Adam Dunkels + */ + +#ifndef __BROADCAST_ANNOUNCEMENT_H__ +#define __BROADCAST_ANNOUNCEMENT_H__ + +void broadcast_announcement_init(uint16_t channel, + clock_time_t bump_time, + clock_time_t min_time, + clock_time_t max_time); + +#endif /* __BROADCAST_ANNOUNCEMENT_H__ */ +/** @} */ +/** @} */