-
Notifications
You must be signed in to change notification settings - Fork 0
/
a00012.html
281 lines (258 loc) · 20.4 KB
/
a00012.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>Contiki 2.5: example-multihop.c</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<!-- Generated by Doxygen 1.6.1 -->
<div class="navigation" id="top">
<div class="tabs">
<ul>
<li><a href="main.html"><span>Main Page</span></a></li>
<li><a href="pages.html"><span>Related Pages</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li><a href="annotated.html"><span>Data Structures</span></a></li>
<li><a href="files.html"><span>Files</span></a></li>
<li><a href="dirs.html"><span>Directories</span></a></li>
<li><a href="examples.html"><span>Examples</span></a></li>
</ul>
</div>
</div>
<div class="contents">
<h1>example-multihop.c</h1><div class="fragment"><pre class="fragment"><span class="comment">/*</span>
<span class="comment"> * Copyright (c) 2007, Swedish Institute of Computer Science.</span>
<span class="comment"> * All rights reserved.</span>
<span class="comment"> *</span>
<span class="comment"> * Redistribution and use in source and binary forms, with or without</span>
<span class="comment"> * modification, are permitted provided that the following conditions</span>
<span class="comment"> * are met:</span>
<span class="comment"> * 1. Redistributions of source code must retain the above copyright</span>
<span class="comment"> * notice, this list of conditions and the following disclaimer.</span>
<span class="comment"> * 2. Redistributions in binary form must reproduce the above copyright</span>
<span class="comment"> * notice, this list of conditions and the following disclaimer in the</span>
<span class="comment"> * documentation and/or other materials provided with the distribution.</span>
<span class="comment"> * 3. Neither the name of the Institute nor the names of its contributors</span>
<span class="comment"> * may be used to endorse or promote products derived from this software</span>
<span class="comment"> * without specific prior written permission.</span>
<span class="comment"> *</span>
<span class="comment"> * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND</span>
<span class="comment"> * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE</span>
<span class="comment"> * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE</span>
<span class="comment"> * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE</span>
<span class="comment"> * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL</span>
<span class="comment"> * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS</span>
<span class="comment"> * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)</span>
<span class="comment"> * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT</span>
<span class="comment"> * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY</span>
<span class="comment"> * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF</span>
<span class="comment"> * SUCH DAMAGE.</span>
<span class="comment"> *</span>
<span class="comment"> * This file is part of the Contiki operating system.</span>
<span class="comment"> *</span>
<span class="comment"> * $Id: example-multihop.c,v 1.7 2010/01/15 10:24:36 nifi Exp $</span>
<span class="comment"> */</span>
<span class="comment"></span>
<span class="comment">/**</span>
<span class="comment"> * \file</span>
<span class="comment"> * Testing the multihop forwarding layer (multihop) in Rime</span>
<span class="comment"> * \author</span>
<span class="comment"> * Adam Dunkels <adam@sics.se></span>
<span class="comment"> *</span>
<span class="comment"> *</span>
<span class="comment"> * This example shows how to use the multihop Rime module, how</span>
<span class="comment"> * to use the announcement mechanism, how to manage a list</span>
<span class="comment"> * with the list module, and how to allocate memory with the</span>
<span class="comment"> * memb module.</span>
<span class="comment"> *</span>
<span class="comment"> * The multihop module provides hooks for forwarding packets</span>
<span class="comment"> * in a multi-hop fashion, but does not implement any routing</span>
<span class="comment"> * protocol. A routing mechanism must be provided by the</span>
<span class="comment"> * application or protocol running on top of the multihop</span>
<span class="comment"> * module. In this case, this example program provides the</span>
<span class="comment"> * routing mechanism.</span>
<span class="comment"> *</span>
<span class="comment"> * The routing mechanism implemented by this example program</span>
<span class="comment"> * is very simple: it forwards every incoming packet to a</span>
<span class="comment"> * random neighbor. The program maintains a list of neighbors,</span>
<span class="comment"> * which it populated through the use of the announcement</span>
<span class="comment"> * mechanism.</span>
<span class="comment"> *</span>
<span class="comment"> * The neighbor list is populated by incoming announcements</span>
<span class="comment"> * from neighbors. The program maintains a list of neighbors,</span>
<span class="comment"> * where each entry is allocated from a MEMB() (memory block</span>
<span class="comment"> * pool). Each neighbor has a timeout so that they do not</span>
<span class="comment"> * occupy their list entry for too long.</span>
<span class="comment"> *</span>
<span class="comment"> * When a packet arrives to the node, the function forward()</span>
<span class="comment"> * is called by the multihop layer. This function picks a</span>
<span class="comment"> * random neighbor to send the packet to. The packet is</span>
<span class="comment"> * forwarded by every node in the network until it reaches its</span>
<span class="comment"> * final destination (or is discarded in transit due to a</span>
<span class="comment"> * transmission error or a collision).</span>
<span class="comment"> *</span>
<span class="comment"> */</span>
<span class="preprocessor">#include "contiki.h"</span>
<span class="preprocessor">#include "<a class="code" href="a00310.html" title="Header file for the Rime stack.">net/rime.h</a>"</span>
<span class="preprocessor">#include "<a class="code" href="a00202.html" title="Linked list manipulation routines.">lib/list.h</a>"</span>
<span class="preprocessor">#include "<a class="code" href="a00208.html" title="Memory block allocation routines.">lib/memb.h</a>"</span>
<span class="preprocessor">#include "lib/random.h"</span>
<span class="preprocessor">#include "dev/button-sensor.h"</span>
<span class="preprocessor">#include "dev/leds.h"</span>
<span class="preprocessor">#include <stdio.h></span>
<span class="preprocessor">#define CHANNEL 135</span>
<span class="preprocessor"></span>
<span class="keyword">struct </span>example_neighbor {
<span class="keyword">struct </span>example_neighbor *next;
rimeaddr_t addr;
<span class="keyword">struct </span>ctimer ctimer;
};
<span class="preprocessor">#define NEIGHBOR_TIMEOUT 60 * CLOCK_SECOND</span>
<span class="preprocessor"></span><span class="preprocessor">#define MAX_NEIGHBORS 16</span>
<span class="preprocessor"></span><a name="a0"></a><a class="code" href="a01556.html#ga1e61a00c396ab8bd4141f54772e310ce" title="Declare a linked list.">LIST</a>(neighbor_table);
<a name="a1"></a><a class="code" href="a01558.html#gaf31774d02a69fd3f1c2b282454438cba" title="Declare a memory block.">MEMB</a>(neighbor_mem, <span class="keyword">struct</span> example_neighbor, MAX_NEIGHBORS);
<span class="comment">/*---------------------------------------------------------------------------*/</span>
<a name="a2"></a><a class="code" href="a01627.html#ga27e9b6fc13f0438e37a198f69b38b4cf" title="Declare a process.">PROCESS</a>(example_multihop_process, <span class="stringliteral">"multihop example"</span>);
AUTOSTART_PROCESSES(&example_multihop_process);
<span class="comment">/*---------------------------------------------------------------------------*/</span>
<span class="comment">/*</span>
<span class="comment"> * This function is called by the ctimer present in each neighbor</span>
<span class="comment"> * table entry. The function removes the neighbor from the table</span>
<span class="comment"> * because it has become too old.</span>
<span class="comment"> */</span>
<span class="keyword">static</span> <span class="keywordtype">void</span>
remove_neighbor(<span class="keywordtype">void</span> *n)
{
<span class="keyword">struct </span>example_neighbor *e = n;
<a name="a3"></a><a class="code" href="a01556.html#ga3eb717d9997a980e937e2ea8b0c07677" title="Remove a specific element from a list.">list_remove</a>(neighbor_table, e);
<a name="a4"></a><a class="code" href="a01558.html#ga513698da82ec79ec7115ffa0d80df77d" title="Deallocate a memory block from a memory block previously declared with MEMB().">memb_free</a>(&neighbor_mem, e);
}
<span class="comment">/*---------------------------------------------------------------------------*/</span>
<span class="comment">/*</span>
<span class="comment"> * This function is called when an incoming announcement arrives. The</span>
<span class="comment"> * function checks the neighbor table to see if the neighbor is</span>
<span class="comment"> * already present in the list. If the neighbor is not present in the</span>
<span class="comment"> * list, a new neighbor table entry is allocated and is added to the</span>
<span class="comment"> * neighbor table.</span>
<span class="comment"> */</span>
<span class="keyword">static</span> <span class="keywordtype">void</span>
received_announcement(<span class="keyword">struct</span> <a name="_a5"></a><a class="code" href="a00026.html" title="Representation of an announcement.">announcement</a> *a, rimeaddr_t *from,
uint16_t <span class="keywordtype">id</span>, uint16_t value)
{
<span class="keyword">struct </span>example_neighbor *e;
<span class="comment">/* printf("Got announcement from %d.%d, id %d, value %d\n",</span>
<span class="comment"> from->u8[0], from->u8[1], id, value);*/</span>
<span class="comment">/* We received an announcement from a neighbor so we need to update</span>
<span class="comment"> the neighbor list, or add a new entry to the table. */</span>
<span class="keywordflow">for</span>(e = <a name="a6"></a><a class="code" href="a01556.html#gacc0723982dcfcc54cfa6ba932ee63051" title="Get a pointer to the first element of a list.">list_head</a>(neighbor_table); e != NULL; e = e->next) {
<span class="keywordflow">if</span>(<a name="a7"></a><a class="code" href="a01606.html#gaed118d3d8fe7e7ac9d6d00988268357e" title="Compare two Rime addresses.">rimeaddr_cmp</a>(from, &e->addr)) {
<span class="comment">/* Our neighbor was found, so we update the timeout. */</span>
<a name="a8"></a><a class="code" href="a01622.html#ga27fd17da97a91042bfb1adf1991cc545" title="Set a callback timer.">ctimer_set</a>(&e->ctimer, NEIGHBOR_TIMEOUT, remove_neighbor, e);
<span class="keywordflow">return</span>;
}
}
<span class="comment">/* The neighbor was not found in the list, so we add a new entry by</span>
<span class="comment"> allocating memory from the neighbor_mem pool, fill in the</span>
<span class="comment"> necessary fields, and add it to the list. */</span>
e = <a name="a9"></a><a class="code" href="a01558.html#ga9eb12536c921ee25d3886ed9640fe6fe" title="Allocate a memory block from a block of memory declared with MEMB().">memb_alloc</a>(&neighbor_mem);
<span class="keywordflow">if</span>(e != NULL) {
<a name="a10"></a><a class="code" href="a01606.html#gacd6a22e93c7a4eb02d901743c958c2b2" title="Copy a Rime address.">rimeaddr_copy</a>(&e->addr, from);
<a name="a11"></a><a class="code" href="a01556.html#ga775c0dfc08dca991297df7b419b7be43" title="Add an item at the end of a list.">list_add</a>(neighbor_table, e);
<a class="code" href="a01622.html#ga27fd17da97a91042bfb1adf1991cc545" title="Set a callback timer.">ctimer_set</a>(&e->ctimer, NEIGHBOR_TIMEOUT, remove_neighbor, e);
}
}
<span class="keyword">static</span> <span class="keyword">struct </span><a class="code" href="a00026.html" title="Representation of an announcement.">announcement</a> example_announcement;
<span class="comment">/*---------------------------------------------------------------------------*/</span>
<span class="comment">/*</span>
<span class="comment"> * This function is called at the final recepient of the message.</span>
<span class="comment"> */</span>
<span class="keyword">static</span> <span class="keywordtype">void</span>
recv(<span class="keyword">struct</span> multihop_conn *c, <span class="keyword">const</span> rimeaddr_t *sender,
<span class="keyword">const</span> rimeaddr_t *prevhop,
uint8_t hops)
{
printf(<span class="stringliteral">"multihop message received '%s'\n"</span>, (<span class="keywordtype">char</span> *)<a name="a12"></a><a class="code" href="a01563.html#ga29a6f3f230b55e6bc2f017879c27113a" title="Get a pointer to the data in the packetbuf.">packetbuf_dataptr</a>());
}
<span class="comment">/*</span>
<span class="comment"> * This function is called to forward a packet. The function picks a</span>
<span class="comment"> * random neighbor from the neighbor list and returns its address. The</span>
<span class="comment"> * multihop layer sends the packet to this address. If no neighbor is</span>
<span class="comment"> * found, the function returns NULL to signal to the multihop layer</span>
<span class="comment"> * that the packet should be dropped.</span>
<span class="comment"> */</span>
<span class="keyword">static</span> rimeaddr_t *
forward(<span class="keyword">struct</span> multihop_conn *c,
<span class="keyword">const</span> rimeaddr_t *originator, <span class="keyword">const</span> rimeaddr_t *dest,
<span class="keyword">const</span> rimeaddr_t *prevhop, uint8_t hops)
{
<span class="comment">/* Find a random neighbor to send to. */</span>
<span class="keywordtype">int</span> num, i;
<span class="keyword">struct </span>example_neighbor *n;
<span class="keywordflow">if</span>(<a name="a13"></a><a class="code" href="a01556.html#ga96f2c18e2a603b297e3c1cae6198dcca" title="Get the length of a list.">list_length</a>(neighbor_table) > 0) {
num = random_rand() % <a class="code" href="a01556.html#ga96f2c18e2a603b297e3c1cae6198dcca" title="Get the length of a list.">list_length</a>(neighbor_table);
i = 0;
<span class="keywordflow">for</span>(n = <a class="code" href="a01556.html#gacc0723982dcfcc54cfa6ba932ee63051" title="Get a pointer to the first element of a list.">list_head</a>(neighbor_table); n != NULL && i != num; n = n->next) {
++i;
}
<span class="keywordflow">if</span>(n != NULL) {
printf(<span class="stringliteral">"%d.%d: Forwarding packet to %d.%d (%d in list), hops %d\n"</span>,
<a name="a14"></a><a class="code" href="a01606.html#gaade5a80096fb3b4296cf89eeaca3087d" title="The Rime address of the node.">rimeaddr_node_addr</a>.u8[0], <a class="code" href="a01606.html#gaade5a80096fb3b4296cf89eeaca3087d" title="The Rime address of the node.">rimeaddr_node_addr</a>.u8[1],
n->addr.u8[0], n->addr.u8[1], num,
packetbuf_attr(PACKETBUF_ATTR_HOPS));
<span class="keywordflow">return</span> &n->addr;
}
}
printf(<span class="stringliteral">"%d.%d: did not find a neighbor to foward to\n"</span>,
<a class="code" href="a01606.html#gaade5a80096fb3b4296cf89eeaca3087d" title="The Rime address of the node.">rimeaddr_node_addr</a>.u8[0], <a class="code" href="a01606.html#gaade5a80096fb3b4296cf89eeaca3087d" title="The Rime address of the node.">rimeaddr_node_addr</a>.u8[1]);
<span class="keywordflow">return</span> NULL;
}
<span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">struct </span>multihop_callbacks multihop_call = {recv, forward};
<span class="keyword">static</span> <span class="keyword">struct </span>multihop_conn multihop;
<span class="comment">/*---------------------------------------------------------------------------*/</span>
<a name="a15"></a><a class="code" href="a01627.html#gaa4cff8e4f3abc50c74619a90ae347200" title="Define the body of a process.">PROCESS_THREAD</a>(example_multihop_process, ev, data)
{
<a name="a16"></a><a class="code" href="a01627.html#ga3dee46e19ad8848b86d9d06321b75c0e" title="Specify an action when a process exits.">PROCESS_EXITHANDLER</a>(multihop_close(&multihop);)
<a name="a17"></a><a class="code" href="a01627.html#ga8efc62947f2ca2c870f52896e0dc1a81" title="Define the beginning of a process.">PROCESS_BEGIN</a>();
<span class="comment">/* Initialize the memory for the neighbor table entries. */</span>
<a name="a18"></a><a class="code" href="a01558.html#gab8f8dad927b501d8b4ed4340d1bcf4fb" title="Initialize a memory block that was declared with MEMB().">memb_init</a>(&neighbor_mem);
<span class="comment">/* Initialize the list used for the neighbor table. */</span>
<a name="a19"></a><a class="code" href="a01556.html#ga10fe9694aceedc8308cc543b9b95d9c9" title="Initialize a list.">list_init</a>(neighbor_table);
<span class="comment">/* Open a multihop connection on Rime channel CHANNEL. */</span>
multihop_open(&multihop, CHANNEL, &multihop_call);
<span class="comment">/* Register an announcement with the same announcement ID as the</span>
<span class="comment"> Rime channel we use to open the multihop connection above. */</span>
<a name="a20"></a><a class="code" href="a01593.html#ga7c4524fbd47cc0eb7bd18d411f3938fb" title="Register an announcement.">announcement_register</a>(&example_announcement,
CHANNEL,
0,
received_announcement);
<span class="comment">/* Activate the button sensor. We use the button to drive traffic -</span>
<span class="comment"> when the button is pressed, a packet is sent. */</span>
SENSORS_ACTIVATE(button_sensor);
<span class="comment">/* Loop forever, send a packet when the button is pressed. */</span>
<span class="keywordflow">while</span>(1) {
rimeaddr_t to;
<span class="comment">/* Wait until we get a sensor event with the button sensor as data. */</span>
<a name="a21"></a><a class="code" href="a01627.html#ga996168a0f904c0e28e3f6ed18dddd129" title="Wait for an event to be posted to the process, with an extra condition.">PROCESS_WAIT_EVENT_UNTIL</a>(ev == sensors_event &&
data == &button_sensor);
<span class="comment">/* Copy the "Hello" to the packet buffer. */</span>
<a name="a22"></a><a class="code" href="a01563.html#ga5fd9cb98f800733b6d9381bce81cd224" title="Copy from external data into the packetbuf.">packetbuf_copyfrom</a>(<span class="stringliteral">"Hello"</span>, 6);
<span class="comment">/* Set the Rime address of the final receiver of the packet to</span>
<span class="comment"> 1.1. This is just a dummy value that happens to work nicely in a</span>
<span class="comment"> netsim simulation (because the default simulation setup creates</span>
<span class="comment"> one node with address 1.1). */</span>
to.u8[0] = 1;
to.u8[1] = 1;
<span class="comment">/* Send the packet. */</span>
multihop_send(&multihop, &to);
}
<a name="a23"></a><a class="code" href="a01627.html#ga9c2681a0070eba8a7c9fdf4dbb6db05e" title="Define the end of a process.">PROCESS_END</a>();
}
<span class="comment">/*---------------------------------------------------------------------------*/</span>
</pre></div> </div>
<hr size="1"/><address style="text-align: right;"><small>Generated on Mon Apr 11 14:23:26 2011 for Contiki 2.5 by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.6.1 </small></address>
</body>
</html>