Contiki-Inga 3.x
multihop.c
Go to the documentation of this file.
1 /**
2  * \addtogroup rime
3  * @{
4  */
5 
6 /*
7  * Copyright (c) 2007, 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  */
37 
38 /**
39  * \file
40  * Multihop forwarding
41  * \author
42  * Adam Dunkels <adam@sics.se>
43  */
44 
45 #include "contiki.h"
46 #include "net/rime/rime.h"
47 #include "net/rime/multihop.h"
48 #include "net/rime/route.h"
49 
50 #include <string.h>
51 
52 static const struct packetbuf_attrlist attributes[] =
53  {
54  MULTIHOP_ATTRIBUTES
55  PACKETBUF_ATTR_LAST
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 void
68 data_packet_received(struct unicast_conn *uc, const linkaddr_t *from)
69 {
70  struct multihop_conn *c = (struct multihop_conn *)uc;
71  linkaddr_t *nexthop;
72  linkaddr_t sender, receiver;
73 
74  /* Copy the packet attributes to avoid them being overwritten or
75  cleared by an application program that uses the packet buffer for
76  its own needs. */
77  linkaddr_copy(&sender, packetbuf_addr(PACKETBUF_ADDR_ESENDER));
78  linkaddr_copy(&receiver, packetbuf_addr(PACKETBUF_ADDR_ERECEIVER));
79 
80  PRINTF("data_packet_received from %d.%d towards %d.%d len %d\n",
81  from->u8[0], from->u8[1],
82  packetbuf_addr(PACKETBUF_ADDR_ERECEIVER)->u8[0],
83  packetbuf_addr(PACKETBUF_ADDR_ERECEIVER)->u8[1],
85 
86  if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_ERECEIVER),
88  PRINTF("for us!\n");
89  if(c->cb->recv) {
90  c->cb->recv(c, &sender, from,
91  packetbuf_attr(PACKETBUF_ATTR_HOPS));
92  }
93  } else {
94  nexthop = NULL;
95  if(c->cb->forward) {
96  packetbuf_set_attr(PACKETBUF_ATTR_HOPS,
97  packetbuf_attr(PACKETBUF_ATTR_HOPS) + 1);
98  nexthop = c->cb->forward(c, &sender, &receiver,
99  from, packetbuf_attr(PACKETBUF_ATTR_HOPS) - 1);
100  }
101  if(nexthop) {
102  PRINTF("forwarding to %d.%d\n", nexthop->u8[0], nexthop->u8[1]);
103  unicast_send(&c->c, nexthop);
104  }
105  }
106 }
107 /*---------------------------------------------------------------------------*/
108 static const struct unicast_callbacks data_callbacks = { data_packet_received };
109 /*---------------------------------------------------------------------------*/
110 void
111 multihop_open(struct multihop_conn *c, uint16_t channel,
112  const struct multihop_callbacks *callbacks)
113 {
114  unicast_open(&c->c, channel, &data_callbacks);
115  channel_set_attributes(channel, attributes);
116  c->cb = callbacks;
117 }
118 /*---------------------------------------------------------------------------*/
119 void
120 multihop_close(struct multihop_conn *c)
121 {
122  unicast_close(&c->c);
123 }
124 /*---------------------------------------------------------------------------*/
125 int
126 multihop_send(struct multihop_conn *c, const linkaddr_t *to)
127 {
128  linkaddr_t *nexthop;
129 
130  if(c->cb->forward == NULL) {
131  return 0;
132  }
134  packetbuf_set_addr(PACKETBUF_ADDR_ERECEIVER, to);
135  packetbuf_set_addr(PACKETBUF_ADDR_ESENDER, &linkaddr_node_addr);
136  packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 1);
137  nexthop = c->cb->forward(c, &linkaddr_node_addr, to, NULL, 0);
138 
139  if(nexthop == NULL) {
140  PRINTF("multihop_send: no route\n");
141  return 0;
142  } else {
143  PRINTF("multihop_send: sending data towards %d.%d\n",
144  nexthop->u8[0], nexthop->u8[1]);
145  unicast_send(&c->c, nexthop);
146  return 1;
147  }
148 }
149 /*---------------------------------------------------------------------------*/
150 void
151 multihop_resend(struct multihop_conn *c, const linkaddr_t *nexthop)
152 {
153  unicast_send(&c->c, nexthop);
154 }
155 /*---------------------------------------------------------------------------*/
156 /** @} */