polite-announcement.c

Go to the documentation of this file.
00001 /**
00002  * \addtogroup rimeexamples
00003  * @{
00004  */
00005 
00006 /*
00007  * Copyright (c) 2006, Swedish Institute of Computer Science.
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. Neither the name of the Institute nor the names of its contributors
00019  *    may be used to endorse or promote products derived from this software
00020  *    without specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  *
00034  * This file is part of the Contiki operating system.
00035  *
00036  * $Id: polite-announcement.c,v 1.16 2010/06/16 10:10:10 nifi Exp $
00037  */
00038 
00039 /**
00040  * \file
00041  *         An example announcement back-end, based on the polite primitive
00042  * \author
00043  *         Adam Dunkels <adam@sics.se>
00044  */
00045 
00046 #include "contiki.h"
00047 
00048 #include "lib/list.h"
00049 #include "net/rime.h"
00050 #include "net/rime/announcement.h"
00051 #include "net/rime/ipolite.h"
00052 
00053 #if NETSIM
00054 #include "ether.h"
00055 #endif
00056 
00057 #include <string.h>
00058 #include <stdio.h>
00059 #include <stddef.h>
00060 
00061 struct announcement_data {
00062   uint16_t id;
00063   uint16_t value;
00064 };
00065 
00066 #ifdef POLITE_ANNOUNCEMENT_CONF_MAX_DUPS
00067 #define NUM_DUPS POLITE_ANNOUNCEMENT_CONF_MAX_DUPS
00068 #else /* POLITE_ANNOUNCEMENT_CONF_MAX_DUPS */
00069 #define NUM_DUPS 5
00070 #endif /* POLITE_ANNOUNCEMENT_CONF_MAX_DUPS */
00071 
00072 #define ANNOUNCEMENT_MSG_HEADERLEN 2
00073 struct announcement_msg {
00074   uint16_t num;
00075   struct announcement_data data[];
00076 };
00077 
00078 
00079 static struct polite_announcement_state {
00080   struct ipolite_conn c;
00081   struct ctimer t;
00082   clock_time_t interval;
00083   clock_time_t min_interval, max_interval;
00084 } c;
00085 
00086 #define DEBUG 0
00087 #if DEBUG
00088 #include <stdio.h>
00089 #define PRINTF(...) printf(__VA_ARGS__)
00090 #else
00091 #define PRINTF(...)
00092 #endif
00093 
00094 #define MIN(a, b) ((a)<(b)?(a):(b))
00095 
00096 /*---------------------------------------------------------------------------*/
00097 static void
00098 send_adv(clock_time_t interval)
00099 {
00100   struct announcement_msg *adata;
00101   struct announcement *a;
00102 
00103   packetbuf_clear();
00104   adata = packetbuf_dataptr();
00105   adata->num = 0;
00106   for(a = announcement_list(); a != NULL; a = list_item_next(a)) {
00107     adata->data[adata->num].id = a->id;
00108     adata->data[adata->num].value = a->value;
00109     adata->num++;
00110   }
00111 
00112   packetbuf_set_datalen(ANNOUNCEMENT_MSG_HEADERLEN +
00113                       sizeof(struct announcement_data) * adata->num);
00114 
00115   PRINTF("%d.%d: sending neighbor advertisement with %d announcements\n",
00116          rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], adata->num);
00117 
00118   if(adata->num > 0) {
00119     /* Send the packet only if it contains more than zero announcements. */
00120     ipolite_send(&c.c, interval, packetbuf_datalen());
00121   }
00122 }
00123 /*---------------------------------------------------------------------------*/
00124 static void
00125 adv_packet_received(struct ipolite_conn *ipolite, const rimeaddr_t *from)
00126 {
00127   struct announcement_msg adata;
00128   int i;
00129 
00130   /* Copy number of announcements */
00131   memcpy(&adata, packetbuf_dataptr(), sizeof(struct announcement_msg));
00132   PRINTF("%d.%d: adv_packet_received from %d.%d with %d announcements\n",
00133          rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00134          from->u8[0], from->u8[1], adata.num);
00135 
00136   for(i = 0; i < adata.num; ++i) {
00137     struct announcement_data data;
00138 
00139     /* Copy announcements */
00140     memcpy(&data.id, &((struct announcement_msg *)packetbuf_dataptr())->data[i].id,
00141           sizeof(uint16_t));
00142     memcpy(&data.value, &((struct announcement_msg *)packetbuf_dataptr())->data[i].value,
00143           sizeof(uint16_t));
00144     announcement_heard(from,
00145                        data.id,
00146                        data.value);
00147   }
00148 }
00149 /*---------------------------------------------------------------------------*/
00150 static void
00151 send_timer(void *ptr)
00152 {
00153   send_adv(c.interval);
00154   ctimer_set(&c.t,
00155              c.interval,
00156              send_timer, &c);
00157 
00158   c.interval = MIN(c.interval * 2, c.max_interval);
00159 }
00160 /*---------------------------------------------------------------------------*/
00161 static void
00162 new_announcement(uint16_t id, uint8_t has_value, uint16_t newval,
00163     uint16_t oldval, uint8_t bump)
00164 {
00165   if(newval != oldval) {
00166     c.interval = c.min_interval;
00167     send_timer(&c);
00168   }
00169 }
00170 /*---------------------------------------------------------------------------*/
00171 static const struct ipolite_callbacks ipolite_callbacks =
00172   {adv_packet_received, NULL, NULL};
00173 /*---------------------------------------------------------------------------*/
00174 void
00175 polite_announcement_init(uint16_t channel,
00176                         clock_time_t min,
00177                         clock_time_t max)
00178 {
00179   ipolite_open(&c.c, channel, NUM_DUPS, &ipolite_callbacks);
00180 
00181   c.min_interval = min;
00182   c.max_interval = max;
00183 
00184   announcement_register_observer_callback(new_announcement);
00185 }
00186 /*---------------------------------------------------------------------------*/
00187 void
00188 polite_announcement_stop(void)
00189 {
00190   ctimer_stop(&c.t);
00191   ipolite_close(&c.c);
00192 }
00193 /*---------------------------------------------------------------------------*/
00194 /** @} */

Generated on Mon Apr 11 14:23:30 2011 for Contiki 2.5 by  doxygen 1.6.1