Contiki 2.5
netflood.c
Go to the documentation of this file.
1 /**
2  * \addtogroup rimenetflood
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: netflood.c,v 1.6 2010/01/25 13:54:06 adamdunkels Exp $
37  */
38 
39 /**
40  * \file
41  * Best-effort network flooding (netflood)
42  * \author
43  * Adam Dunkels <adam@sics.se>
44  */
45 
46 #include "net/rime/netflood.h"
47 
48 #include <string.h>
49 
50 #define HOPS_MAX 16
51 
52 struct netflood_hdr {
53  uint16_t originator_seqno;
54  rimeaddr_t originator;
55  uint16_t hops;
56 };
57 
58 #define DEBUG 0
59 #if DEBUG
60 #include <stdio.h>
61 #define PRINTF(...) printf(__VA_ARGS__)
62 #else
63 #define PRINTF(...)
64 #endif
65 
66 /*---------------------------------------------------------------------------*/
67 static int
68 send(struct netflood_conn *c)
69 {
70  PRINTF("%d.%d: netflood send to ipolite\n",
72  return ipolite_send(&c->c, c->queue_time, 4);
73 }
74 /*---------------------------------------------------------------------------*/
75 static void
76 recv_from_ipolite(struct ipolite_conn *ipolite, const rimeaddr_t *from)
77 {
78  struct netflood_conn *c = (struct netflood_conn *)ipolite;
79  struct netflood_hdr hdr;
80  uint8_t hops;
81  struct queuebuf *queuebuf;
82 
83  memcpy(&hdr, packetbuf_dataptr(), sizeof(struct netflood_hdr));
84  hops = hdr.hops;
85 
86  /* Remember packet if we need to forward it. */
87  queuebuf = queuebuf_new_from_packetbuf();
88 
89  packetbuf_hdrreduce(sizeof(struct netflood_hdr));
90  if(c->u->recv != NULL) {
91  if(!(rimeaddr_cmp(&hdr.originator, &c->last_originator) &&
92  hdr.originator_seqno <= c->last_originator_seqno)) {
93 
94  if(c->u->recv(c, from, &hdr.originator, hdr.originator_seqno,
95  hops)) {
96 
97  if(queuebuf != NULL) {
98  queuebuf_to_packetbuf(queuebuf);
99  queuebuf_free(queuebuf);
100  queuebuf = NULL;
101  memcpy(&hdr, packetbuf_dataptr(), sizeof(struct netflood_hdr));
102 
103  /* Rebroadcast received packet. */
104  if(hops < HOPS_MAX) {
105  PRINTF("%d.%d: netflood rebroadcasting %d.%d/%d (%d.%d/%d) hops %d\n",
107  hdr.originator.u8[0], hdr.originator.u8[1],
108  hdr.originator_seqno,
109  c->last_originator.u8[0], c->last_originator.u8[1],
110  c->last_originator_seqno,
111  hops);
112  hdr.hops++;
113  memcpy(packetbuf_dataptr(), &hdr, sizeof(struct netflood_hdr));
114  send(c);
115  rimeaddr_copy(&c->last_originator, &hdr.originator);
116  c->last_originator_seqno = hdr.originator_seqno;
117  }
118  }
119  }
120  }
121  }
122  if(queuebuf != NULL) {
123  queuebuf_free(queuebuf);
124  }
125 }
126 /*---------------------------------------------------------------------------*/
127 static void
128 sent(struct ipolite_conn *ipolite)
129 {
130  struct netflood_conn *c = (struct netflood_conn *)ipolite;
131  if(c->u->sent != NULL) {
132  c->u->sent(c);
133  }
134 }
135 /*---------------------------------------------------------------------------*/
136 static void
137 dropped(struct ipolite_conn *ipolite)
138 {
139  struct netflood_conn *c = (struct netflood_conn *)ipolite;
140  if(c->u->dropped != NULL) {
141  c->u->dropped(c);
142  }
143 }
144 /*---------------------------------------------------------------------------*/
145 static const struct ipolite_callbacks netflood = {recv_from_ipolite, sent, dropped};
146 /*---------------------------------------------------------------------------*/
147 void
148 netflood_open(struct netflood_conn *c, clock_time_t queue_time,
149  uint16_t channel, const struct netflood_callbacks *u)
150 {
151  ipolite_open(&c->c, channel, 1, &netflood);
152  c->u = u;
153  c->queue_time = queue_time;
154 }
155 /*---------------------------------------------------------------------------*/
156 void
157 netflood_close(struct netflood_conn *c)
158 {
159  ipolite_close(&c->c);
160 }
161 /*---------------------------------------------------------------------------*/
162 int
163 netflood_send(struct netflood_conn *c, uint8_t seqno)
164 {
165  if(packetbuf_hdralloc(sizeof(struct netflood_hdr))) {
166  struct netflood_hdr *hdr = packetbuf_hdrptr();
167  rimeaddr_copy(&hdr->originator, &rimeaddr_node_addr);
168  rimeaddr_copy(&c->last_originator, &hdr->originator);
169  c->last_originator_seqno = hdr->originator_seqno = seqno;
170  hdr->hops = 0;
171  PRINTF("%d.%d: netflood sending '%s'\n",
173  (char *)packetbuf_dataptr());
174  return ipolite_send(&c->c, 0, 4);
175  }
176  return 0;
177 }
178 /*---------------------------------------------------------------------------*/
179 void
180 netflood_cancel(struct netflood_conn *c)
181 {
182  ipolite_cancel(&c->c);
183 }
184 /*---------------------------------------------------------------------------*/
185 /** @} */