polite-announcement.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
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
00069 #define NUM_DUPS 5
00070 #endif
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
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
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
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