Contiki 2.5
neighbor-discovery.c
Go to the documentation of this file.
1 /**
2  * \addtogroup rimeneighbordiscovery
3  * @{
4  */
5 
6 /*
7  * Copyright (c) 2006, Swedish Institute of Computer Science.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in the
17  * documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the Institute nor the names of its contributors
19  * may be used to endorse or promote products derived from this software
20  * without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * This file is part of the Contiki operating system.
35  *
36  * $Id: neighbor-discovery.c,v 1.19 2010/03/19 13:21:48 adamdunkels Exp $
37  */
38 
39 /**
40  * \file
41  * Neighbor discovery
42  * \author
43  * Adam Dunkels <adam@sics.se>
44  */
45 
46 #include "contiki.h"
47 
48 #include "net/rime.h"
50 
51 #include "dev/radio-sensor.h"
52 
53 #include "lib/random.h"
54 
55 #if CONTIKI_TARGET_NETSIM
56 #include "ether.h"
57 #endif
58 
59 #include <string.h>
60 #include <stdio.h>
61 #include <stddef.h>
62 
63 struct adv_msg {
64  uint16_t val;
65 };
66 
67 #define DEBUG 0
68 #if DEBUG
69 #include <stdio.h>
70 #define PRINTF(...) printf(__VA_ARGS__)
71 #else
72 #define PRINTF(...)
73 #endif
74 
75 /*---------------------------------------------------------------------------*/
76 static void
77 send_adv(void *ptr)
78 {
79  struct neighbor_discovery_conn *c = ptr;
80  struct adv_msg *hdr;
81 
83  packetbuf_set_datalen(sizeof(struct adv_msg));
84  hdr = packetbuf_dataptr();
85  hdr->val = c->val;
86  broadcast_send(&c->c);
87  if(c->u->sent) {
88  c->u->sent(c);
89  }
90  PRINTF("%d.%d: sending neighbor advertisement with val %d\n",
92  c->val);
93 }
94 /*---------------------------------------------------------------------------*/
95 static void
96 adv_packet_received(struct broadcast_conn *ibc, const rimeaddr_t *from)
97 {
98  struct neighbor_discovery_conn *c = (struct neighbor_discovery_conn *)ibc;
99  struct adv_msg *msg = packetbuf_dataptr();
100  uint16_t val;
101 
102  memcpy(&val, &msg->val, sizeof(val));
103 
104  PRINTF("%d.%d: adv_packet_received from %d.%d with val %d\n",
106  from->u8[0], from->u8[1], val);
107 
108  /* If we receive an announcement with a lower value than ours, we
109  cancel our own announcement. */
110  if(val < c->val) {
111  /* ctimer_stop(&c->send_timer);*/
112  }
113 
114  if(c->u->recv) {
115  c->u->recv(c, from, val);
116  }
117 }
118 /*---------------------------------------------------------------------------*/
119 static void
120 adv_packet_sent(struct broadcast_conn *bc, int status, int num_tx)
121 {
122 }
123 /*---------------------------------------------------------------------------*/
124 static void send_timer(void *ptr);
125 
126 static void
127 set_timers(struct neighbor_discovery_conn *c)
128 {
129  ctimer_set(&c->interval_timer, c->current_interval, send_timer, c);
130  ctimer_set(&c->send_timer, c->current_interval / 2 + random_rand() %
131  (c->current_interval / 2),
132  send_adv, c);
133 }
134 /*---------------------------------------------------------------------------*/
135 static void
136 send_timer(void *ptr)
137 {
138  struct neighbor_discovery_conn *c = ptr;
139  clock_time_t interval;
140 
141  interval = c->current_interval * 2;
142 
143  if(interval > c->max_interval) {
144  interval = c->max_interval;
145  }
146 
147  c->current_interval = interval;
148 
149  /* printf("current_interval %lu\n", (long unsigned int) interval);*/
150 
151  PRINTF("current_interval %lu\n", (long unsigned int) interval);
152 
153  set_timers(c);
154 }
155 /*---------------------------------------------------------------------------*/
157  {adv_packet_received, adv_packet_sent };
158 /*---------------------------------------------------------------------------*/
159 void
160 neighbor_discovery_open(struct neighbor_discovery_conn *c, uint16_t channel,
161  clock_time_t initial,
162  clock_time_t min,
163  clock_time_t max,
164  const struct neighbor_discovery_callbacks *cb)
165 {
166  PRINTF("%d.%d: neighbor discovery open channel %d\n",
168  channel);
169  broadcast_open(&c->c, channel, &broadcast_callbacks);
170  c->u = cb;
171  c->initial_interval = initial;
172  c->min_interval = min;
173  c->max_interval = max;
174 }
175 /*---------------------------------------------------------------------------*/
176 void
177 neighbor_discovery_close(struct neighbor_discovery_conn *c)
178 {
179  broadcast_close(&c->c);
180  ctimer_stop(&c->send_timer);
181  ctimer_stop(&c->interval_timer);
182 }
183 /*---------------------------------------------------------------------------*/
184 void
185 neighbor_discovery_set_val(struct neighbor_discovery_conn *c, uint16_t val)
186 {
187  c->val = val;
188 }
189 /*---------------------------------------------------------------------------*/
190 void
191 neighbor_discovery_start(struct neighbor_discovery_conn *c, uint16_t val)
192 {
193  c->current_interval = c->initial_interval;
194  c->val = val;
195  set_timers(c);
196 }
197 /*---------------------------------------------------------------------------*/
198 /** @} */