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