Contiki-NG
rpl-dag-root.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2014, Thingsquare, http://www.thingsquare.com/.
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 copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28  * OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  */
31 
32 /**
33 * \addtogroup rpl-lite
34 * @{
35 *
36 * \file
37 * DAG root utility functions for RPL.
38 */
39 
40 #include "contiki.h"
41 #include "contiki-net.h"
42 
43 #include "net/routing/rpl-lite/rpl.h"
44 #include "net/ipv6/uip-ds6-route.h"
45 #include "net/ipv6/uip-sr.h"
46 
47 /* Log configuration */
48 #include "sys/log.h"
49 #define LOG_MODULE "RPL"
50 #define LOG_LEVEL LOG_LEVEL_RPL
51 
52 /*---------------------------------------------------------------------------*/
53 void
54 rpl_dag_root_print_links(const char *str)
55 {
56  if(rpl_dag_root_is_root()) {
57  if(uip_sr_num_nodes() > 0) {
58  uip_sr_node_t *link;
59  /* Our routing links */
60  LOG_INFO("links: %u routing links in total (%s)\n", uip_sr_num_nodes(), str);
61  link = uip_sr_node_head();
62  while(link != NULL) {
63  char buf[100];
64  uip_sr_link_snprint(buf, sizeof(buf), link);
65  LOG_INFO("links: %s\n", buf);
66  link = uip_sr_node_next(link);
67  }
68  LOG_INFO("links: end of list\n");
69  } else {
70  LOG_INFO("No routing links\n");
71  }
72  }
73 }
74 /*---------------------------------------------------------------------------*/
75 static void
76 set_global_address(uip_ipaddr_t *prefix, uip_ipaddr_t *iid)
77 {
78  static uip_ipaddr_t root_ipaddr;
79  int i;
80  uint8_t state;
81 
82  /* Assign a unique local address (RFC4193,
83  http://tools.ietf.org/html/rfc4193). */
84  if(prefix == NULL) {
85  uip_ip6addr(&root_ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0);
86  } else {
87  memcpy(&root_ipaddr, prefix, 8);
88  }
89  if(iid == NULL) {
90  uip_ds6_set_addr_iid(&root_ipaddr, &uip_lladdr);
91  } else {
92  memcpy(((uint8_t*)&root_ipaddr) + 8, ((uint8_t*)iid) + 8, 8);
93  }
94 
95  uip_ds6_addr_add(&root_ipaddr, 0, ADDR_AUTOCONF);
96 
97  LOG_INFO("IPv6 addresses:\n");
98  for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
99  state = uip_ds6_if.addr_list[i].state;
100  if(uip_ds6_if.addr_list[i].isused &&
101  (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
102  LOG_INFO("-- ");
103  LOG_INFO_6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
104  LOG_INFO_("\n");
105  }
106  }
107 }
108 /*---------------------------------------------------------------------------*/
109 void
110 rpl_dag_root_set_prefix(uip_ipaddr_t *prefix, uip_ipaddr_t *iid)
111 {
112  static uint8_t initialized = 0;
113 
114  if(!initialized) {
115  set_global_address(prefix, iid);
116  initialized = 1;
117  }
118 }
119 /*---------------------------------------------------------------------------*/
120 int
122 {
123  struct uip_ds6_addr *root_if;
124  int i;
125  uint8_t state;
126  uip_ipaddr_t *ipaddr = NULL;
127 
128  rpl_dag_root_set_prefix(NULL, NULL);
129 
130  for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
131  state = uip_ds6_if.addr_list[i].state;
132  if(uip_ds6_if.addr_list[i].isused &&
133  state == ADDR_PREFERRED &&
134  !uip_is_addr_linklocal(&uip_ds6_if.addr_list[i].ipaddr)) {
135  ipaddr = &uip_ds6_if.addr_list[i].ipaddr;
136  }
137  }
138 
139  root_if = uip_ds6_addr_lookup(ipaddr);
140  if(ipaddr != NULL || root_if != NULL) {
141 
142  rpl_dag_init_root(RPL_DEFAULT_INSTANCE, ipaddr,
143  (uip_ipaddr_t *)rpl_get_global_address(), 64, UIP_ND6_RA_FLAG_AUTONOMOUS);
145 
146  LOG_INFO("created a new RPL DAG\n");
147  return 0;
148  } else {
149  LOG_ERR("failed to create a new RPL DAG\n");
150  return -1;
151  }
152 }
153 /*---------------------------------------------------------------------------*/
154 int
156 {
157  return curr_instance.used && curr_instance.dag.rank == ROOT_RANK;
158 }
159 /*---------------------------------------------------------------------------*/
160 /** @} */
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Definition: uip-nd6.c:125
#define uip_ip6addr(addr, addr0, addr1, addr2, addr3, addr4, addr5, addr6, addr7)
Construct an IPv6 address from eight 16-bit words.
Definition: uip.h:961
uip_lladdr_t uip_lladdr
Host L2 address.
Definition: uip6.c:107
int rpl_dag_root_start(void)
Set the node as root and start a DAG.
Definition: rpl-dag-root.c:121
int uip_sr_num_nodes(void)
Tells how many nodes are currently stored in the graph.
Definition: uip-sr.c:63
#define ROOT_RANK
Rank of a root node.
Definition: rpl-types.h:78
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr)
set the last 64 bits of an IP address based on the MAC address
Definition: uip-ds6.c:557
void rpl_dag_init_root(uint8_t instance_id, uip_ipaddr_t *dag_id, uip_ipaddr_t *prefix, unsigned prefix_len, uint8_t prefix_flags)
Initializes DAG internal structure for a root node.
Definition: rpl-dag.c:705
void rpl_dag_root_print_links(const char *str)
Prints a summary of all routing links.
Definition: rpl-dag-root.c:54
int rpl_dag_root_is_root(void)
Tells whether we are DAG root or not.
Definition: rpl-dag-root.c:155
Source routing support.
uip_sr_node_t * uip_sr_node_next(uip_sr_node_t *item)
Returns the next element of the non-storing node list.
Definition: uip-sr.c:200
void rpl_dag_root_set_prefix(uip_ipaddr_t *prefix, uip_ipaddr_t *iid)
Set a prefix in case the node is later set as dag root.
Definition: rpl-dag-root.c:110
uip_sr_node_t * uip_sr_node_head(void)
Returns the head of the non-storing node list.
Definition: uip-sr.c:194
Unicast address structure.
Definition: uip-ds6.h:204
#define ADDR_TENTATIVE
Possible states for the an address (RFC 4862)
Definition: uip-ds6.h:155
uip_ds6_addr_t * uip_ds6_addr_add(uip_ipaddr_t *ipaddr, unsigned long vlifetime, uint8_t type)
Add a unicast address to the interface.
Definition: uip-ds6.c:341
int uip_sr_link_snprint(char *buf, int buflen, uip_sr_node_t *link)
Print a textual description of a source routing link.
Definition: uip-sr.c:252
const uip_ipaddr_t * rpl_get_global_address(void)
Get one of the node&#39;s global addresses.
Definition: rpl.c:71
uip_ds6_netif_t uip_ds6_if
The single interface.
Definition: uip-ds6.c:75
void rpl_dag_update_state(void)
Updates RPL internal state: selects preferred parent, updates rank & metreic container, triggers control traffic accordingly and updates uIP6 internal state.
Definition: rpl-dag.c:264
Header file for routing table manipulation.
#define uip_is_addr_linklocal(a)
is addr (a) a link local unicast address, see RFC 4291 i.e.
Definition: uip.h:2023
Header file for the logging system
A node in a source routing graph, stored at the root and representing all child-parent relationship...
Definition: uip-sr.h:92