Contiki-Inga 3.x
rpl.h
1 /*
2  * Copyright (c) 2010, 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  * \file Public API declarations for ContikiRPL.
34  *
35  * \author Joakim Eriksson <joakime@sics.se>
36  * \author Nicolas Tsiftes <nvt@sics.se>
37  */
38 
39 /**
40  * @addtogroup uip6
41  * @{ */
42 
43 /**
44  * @defgroup rpl RPL implementation ContikiRPL (RFC 6550).
45  *
46  * @{ */
47 
48 #ifndef RPL_H
49 #define RPL_H
50 
51 #include "rpl-conf.h"
52 
53 #include "lib/list.h"
54 #include "net/ip/uip.h"
55 #include "net/ipv6/uip-ds6.h"
56 #include "sys/ctimer.h"
57 
58 /*---------------------------------------------------------------------------*/
59 typedef uint16_t rpl_rank_t;
60 typedef uint16_t rpl_ocp_t;
61 /*---------------------------------------------------------------------------*/
62 /** @name DAG Metric Container Object Types, to be confirmed by IANA.
63  * @{ */
64 #define RPL_DAG_MC_NONE 0 /* Local identifier for empty MC */
65 #define RPL_DAG_MC_NSA 1 /* Node State and Attributes */
66 #define RPL_DAG_MC_ENERGY 2 /* Node Energy */
67 #define RPL_DAG_MC_HOPCOUNT 3 /* Hop Count */
68 #define RPL_DAG_MC_THROUGHPUT 4 /* Throughput */
69 #define RPL_DAG_MC_LATENCY 5 /* Latency */
70 #define RPL_DAG_MC_LQL 6 /* Link Quality Level */
71 #define RPL_DAG_MC_ETX 7 /* Expected Transmission Count */
72 #define RPL_DAG_MC_LC 8 /* Link Color */
73 /** @} */
74 
75 /** @name DAG Metric Container flags.
76  * @{ */
77 #define RPL_DAG_MC_FLAG_P 0x8
78 #define RPL_DAG_MC_FLAG_C 0x4
79 #define RPL_DAG_MC_FLAG_O 0x2
80 #define RPL_DAG_MC_FLAG_R 0x1
81 /** @} */
82 
83 /** @name DAG Metric Container aggregation mode.
84  * @{ */
85 #define RPL_DAG_MC_AGGR_ADDITIVE 0
86 #define RPL_DAG_MC_AGGR_MAXIMUM 1
87 #define RPL_DAG_MC_AGGR_MINIMUM 2
88 #define RPL_DAG_MC_AGGR_MULTIPLICATIVE 3
89 /** @} */
90 
91 /** The bit index within the flags field of
92  the rpl_metric_object_energy structure. */
93 #define RPL_DAG_MC_ENERGY_INCLUDED 3
94 #define RPL_DAG_MC_ENERGY_TYPE 1
95 #define RPL_DAG_MC_ENERGY_ESTIMATION 0
96 
97 #define RPL_DAG_MC_ENERGY_TYPE_MAINS 0
98 #define RPL_DAG_MC_ENERGY_TYPE_BATTERY 1
99 #define RPL_DAG_MC_ENERGY_TYPE_SCAVENGING 2
100 
101 struct rpl_metric_object_energy {
102  uint8_t flags;
103  uint8_t energy_est;
104 };
105 
106 /** Logical representation of a DAG Metric Container. */
108  uint8_t type;
109  uint8_t flags;
110  uint8_t aggr;
111  uint8_t prec;
112  uint8_t length;
113  union metric_object {
114  struct rpl_metric_object_energy energy;
115  uint16_t etx;
116  } obj;
117 };
119 /*---------------------------------------------------------------------------*/
120 struct rpl_instance;
121 struct rpl_dag;
122 /*---------------------------------------------------------------------------*/
123 struct rpl_parent {
124  struct rpl_parent *next;
125  struct rpl_dag *dag;
126 #if RPL_DAG_MC != RPL_DAG_MC_NONE
128 #endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
129  rpl_rank_t rank;
130  uint16_t link_metric;
131  uint8_t dtsn;
132  uint8_t updated;
133 };
134 typedef struct rpl_parent rpl_parent_t;
135 /*---------------------------------------------------------------------------*/
136 /** RPL DIO prefix suboption */
137 struct rpl_prefix {
138  uip_ipaddr_t prefix;
139  uint32_t lifetime;
140  uint8_t length;
141  uint8_t flags;
142 };
143 typedef struct rpl_prefix rpl_prefix_t;
144 /*---------------------------------------------------------------------------*/
145 /** Directed Acyclic Graph */
146 struct rpl_dag {
147  uip_ipaddr_t dag_id;
148  rpl_rank_t min_rank; /* should be reset per DAG iteration! */
149  uint8_t version;
150  uint8_t grounded;
151  uint8_t preference;
152  uint8_t used;
153  /* live data for the DAG */
154  uint8_t joined;
155  rpl_parent_t *preferred_parent;
156  rpl_rank_t rank;
157  struct rpl_instance *instance;
158  rpl_prefix_t prefix_info;
159 };
160 typedef struct rpl_dag rpl_dag_t;
161 typedef struct rpl_instance rpl_instance_t;
162 /*---------------------------------------------------------------------------*/
163 /**
164  * API for RPL objective functions (OF)
165  */
166 struct rpl_of {
167  /**
168  * Resets the objective function state for a specific DAG.
169  * This function is called when doing a global repair on the DAG.
170  */
171  void (*reset)(struct rpl_dag *);
172  /**
173  * Receives link-layer neighbor information.
174  * The parameter "known" is set either to 0 or 1.
175  * The "etx" parameter specifies the current ETX(estimated transmissions) for the neighbor.
176  */
177  void (*neighbor_link_callback)(rpl_parent_t *, int, int);
178  /**
179  * Compares two parents and returns the best one, according to the OF.
180  */
181  rpl_parent_t *(*best_parent)(rpl_parent_t *, rpl_parent_t *);
182  /**
183  * Compares two DAGs and returns the best one, according to the OF.
184  */
185  rpl_dag_t *(*best_dag)(rpl_dag_t *, rpl_dag_t *);
186  /**
187  * Calculates a rank value using the parent rank and a base rank.
188  * If "parent" is NULL, the objective function selects a default increment
189  * that is adds to the "base_rank". Otherwise, the OF uses information known
190  * about "parent" to select an increment to the "base_rank".
191  */
192  rpl_rank_t (*calculate_rank)(rpl_parent_t *, rpl_rank_t);
193  /**
194  * Updates the metric container for outgoing DIOs in a certain DAG.
195  * If the objective function of the DAG does not use metric containers,
196  * the function should set the object type to RPL_DAG_MC_NONE.
197  */
199  rpl_ocp_t ocp;
200 };
201 typedef struct rpl_of rpl_of_t;
202 
203 /* Declare the selected objective function. */
204 extern rpl_of_t RPL_OF;
205 /*---------------------------------------------------------------------------*/
206 /** RPL Instance */
207 struct rpl_instance {
208  /* DAG configuration */
210  rpl_of_t *of;
211  rpl_dag_t *current_dag;
212  rpl_dag_t dag_table[RPL_MAX_DAG_PER_INSTANCE];
213  /* The current default router - used for routing "upwards" */
214  uip_ds6_defrt_t *def_route;
215  uint8_t instance_id;
216  uint8_t used;
217  uint8_t dtsn_out;
218  uint8_t mop;
219  uint8_t dio_intdoubl;
220  uint8_t dio_intmin;
221  uint8_t dio_redundancy;
222  uint8_t default_lifetime;
223  uint8_t dio_intcurrent;
224  uint8_t dio_send; /* for keeping track of which mode the timer is in */
225  uint8_t dio_counter;
226  rpl_rank_t max_rankinc;
227  rpl_rank_t min_hoprankinc;
228  uint16_t lifetime_unit; /* lifetime in seconds = l_u * d_l */
229 #if RPL_CONF_STATS
230  uint16_t dio_totint;
231  uint16_t dio_totsend;
232  uint16_t dio_totrecv;
233 #endif /* RPL_CONF_STATS */
234  clock_time_t dio_next_delay; /* delay for completion of dio interval */
235  struct ctimer dio_timer;
236  struct ctimer dao_timer;
237  struct ctimer dao_lifetime_timer;
238 };
239 
240 /*---------------------------------------------------------------------------*/
241 /**
242  * @name Public RPL functions.
243  * @{ */
244 /** */
245 void rpl_init(void);
246 /** */
247 void uip_rpl_input(void);
248 /** */
249 rpl_dag_t *rpl_set_root(uint8_t instance_id, uip_ipaddr_t * dag_id);
250 /** */
251 int rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len);
252 /** */
253 int rpl_repair_root(uint8_t instance_id);
254 /** */
255 int rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from);
256 /** */
257 rpl_dag_t *rpl_get_any_dag(void);
258 /** */
259 rpl_instance_t *rpl_get_instance(uint8_t instance_id);
260 /** */
261 void rpl_update_header_empty(void);
262 /** */
263 int rpl_update_header_final(uip_ipaddr_t *addr);
264 /** */
265 int rpl_verify_header(int);
266 /** */
267 void rpl_insert_header(void);
268 /** */
269 void rpl_remove_header(void);
270 /** */
271 uint8_t rpl_invert_header(void);
272 /** */
273 uip_ipaddr_t *rpl_get_parent_ipaddr(rpl_parent_t *nbr);
274 /** */
275 rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
276 /** */
277 uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr);
278 /** */
279 void rpl_dag_init(void);
280 /** @} */
281 
282 /**
283  * RPL modes
284  *
285  * The RPL module can be in either of three modes:
286  * - mesh mode (RPL_MODE_MESH):
287  * nodes forward data for other nodes, and are reachable by others
288  * - feater mode (RPL_MODE_FEATHER):
289  * nodes can forward data for other nodes, but are not reachable themselves
290  * - and leaf mode (RPL_MODE_LEAF):
291  * nodes do not forward data for others, but are reachable by others
292  */
293 enum rpl_mode {
294  RPL_MODE_MESH = 0,
295  RPL_MODE_FEATHER = 1,
296  RPL_MODE_LEAF = 2,
297 };
298 
299 /**
300  * Set the RPL mode
301  *
302  * \param mode The new RPL mode
303  * \retval The previous RPL mode
304  */
305 enum rpl_mode rpl_set_mode(enum rpl_mode mode);
306 
307 /**
308  * Get the RPL mode
309  *
310  * \retval The RPL mode
311  */
312 enum rpl_mode rpl_get_mode(void);
313 
314 /** @} */
315 /** @} */
316 /*---------------------------------------------------------------------------*/
317 #endif /* RPL_H */