Contiki-NG
Loading...
Searching...
No Matches
tsch-roots.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018, Amber Agriculture
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the Institute nor the names of its contributors
13 * may be used to endorse or promote products derived from this software
14 * without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 */
29
30/**
31 * \file
32 * Keeps track of which neighbors advertise themselves as roots.
33 * This information is used by the Orchestra root rule.
34 *
35 * \author
36 * Atis Elsts <atis.elsts@gmail.com>
37 */
38
39#include "contiki.h"
40#include "lib/list.h"
41#include "lib/memb.h"
42#include "net/mac/tsch/tsch.h"
43
44/* Log configuration */
45#include "sys/log.h"
46#define LOG_MODULE "TSCH"
47#define LOG_LEVEL LOG_LEVEL_MAC
48
49/*---------------------------------------------------------------------------*/
50#if BUILD_WITH_ORCHESTRA
51/*---------------------------------------------------------------------------*/
52#define TSCH_MAX_ROOT_NODES 5
53#define ROOT_ALIVE_TIME_SECONDS (2 * 60 * 60) /* 2h timeout */
54#define PERIODIC_PROCESSING_TICKS (60 * CLOCK_SECOND)
55
56/*---------------------------------------------------------------------------*/
57/* TSCH roots data structure */
58struct tsch_root_info {
59 struct tsch_root_info *next;
60 linkaddr_t address;
61 clock_time_t last_seen_seconds; /* the time when this was last seen */
62};
63/*---------------------------------------------------------------------------*/
64MEMB(tsch_root_memb, struct tsch_root_info, TSCH_MAX_ROOT_NODES);
65LIST(tsch_roots);
66static struct ctimer periodic_timer;
67/*---------------------------------------------------------------------------*/
68void
69tsch_roots_add_address(const linkaddr_t *new_root_address)
70{
71 struct tsch_root_info *root;
72
73 LOG_INFO("add root address ");
74 LOG_INFO_LLADDR(new_root_address);
75 LOG_INFO_("\n");
76
77 /* search for an existing entry */
78 root = list_head(tsch_roots);
79 while(root != NULL) {
80 if(linkaddr_cmp(new_root_address, &root->address)) {
81 break;
82 }
83 root = root->next;
84 }
85
86 if(root == NULL) {
87 /* add a new entry */
88 if((root = memb_alloc(&tsch_root_memb)) == NULL) {
89 LOG_ERR("failed to add root ");
90 LOG_ERR_LLADDR(new_root_address);
91 LOG_ERR_("\n");
92 return;
93 }
94 linkaddr_copy(&root->address, new_root_address);
95 list_add(tsch_roots, root);
96
97 /* make sure there is a link in the schedule */
98 TSCH_CALLBACK_ROOT_NODE_UPDATED(&root->address, 1);
99 }
100
101 /* update the entry */
102 root->last_seen_seconds = clock_seconds();
103}
104/*---------------------------------------------------------------------------*/
105void
106tsch_roots_set_self_to_root(uint8_t is_root)
107{
108 TSCH_CALLBACK_ROOT_NODE_UPDATED(&linkaddr_node_addr, is_root);
109}
110/*---------------------------------------------------------------------------*/
111int
112tsch_roots_is_root(const linkaddr_t *address)
113{
114 struct tsch_root_info *root;
115 if(address == NULL) {
116 return 0;
117 }
118
119 root = list_head(tsch_roots);
120 while(root != NULL) {
121 if(linkaddr_cmp(address, &root->address)) {
122 return 1;
123 }
124 root = root->next;
125 }
126 return 0;
127}
128/*---------------------------------------------------------------------------*/
129static void
130periodic(void *ptr)
131{
132 struct tsch_root_info *root;
133 struct tsch_root_info *next;
134 clock_time_t now;
135
136 now = clock_seconds();
137 root = list_head(tsch_roots);
138 while(root != NULL) {
139 next = root->next;
140 if((int32_t)(root->last_seen_seconds + ROOT_ALIVE_TIME_SECONDS - now) < 0) {
141 /* the root info has become obsolete; remove its scheduled link */
142 LOG_INFO("remove root address ");
143 LOG_INFO_LLADDR(&root->address);
144 LOG_INFO_("\n");
145 TSCH_CALLBACK_ROOT_NODE_UPDATED(&root->address, 0);
146 /* remove itself from the table */
147 list_remove(tsch_roots, root);
148 memb_free(&tsch_root_memb, root);
149 }
150 root = next;
151 }
152
153 /* schedule the next time */
154 ctimer_set(&periodic_timer, PERIODIC_PROCESSING_TICKS, periodic, NULL);
155}
156/*---------------------------------------------------------------------------*/
157void
158tsch_roots_init(void)
159{
160 list_init(tsch_roots);
161 memb_init(&tsch_root_memb);
162 ctimer_set(&periodic_timer, PERIODIC_PROCESSING_TICKS, periodic, NULL);
163}
164/*---------------------------------------------------------------------------*/
165#else /* BUILD_WITH_ORCHESTRA */
166/*---------------------------------------------------------------------------*/
167void
168tsch_roots_add_address(const linkaddr_t *root_address)
169{
170}
171void
173{
174}
175int
176tsch_roots_is_root(const linkaddr_t *address)
177{
178 return 0;
179}
180void
182{
183}
184/*---------------------------------------------------------------------------*/
185#endif /* BUILD_WITH_ORCHESTRA */
186/*---------------------------------------------------------------------------*/
unsigned long clock_seconds(void)
Get the current value of the platform seconds.
Definition clock.c:130
static void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
Definition ctimer.h:137
linkaddr_t linkaddr_node_addr
The link-layer address of the node.
Definition linkaddr.c:48
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a link-layer address.
Definition linkaddr.c:63
bool linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two link-layer addresses.
Definition linkaddr.c:69
static void list_init(list_t list)
Initialize a list.
Definition list.h:152
#define LIST(name)
Declare a linked list.
Definition list.h:90
void list_add(list_t list, void *item)
Add an item at the end of a list.
Definition list.c:71
void list_remove(list_t list, const void *item)
Remove a specific element from a list.
Definition list.c:134
static void * list_head(const_list_t list)
Get a pointer to the first element of a list.
Definition list.h:169
int memb_free(struct memb *m, void *ptr)
Deallocate a memory block from a memory block previously declared with MEMB().
Definition memb.c:78
void * memb_alloc(struct memb *m)
Allocate a memory block from a block of memory declared with MEMB().
Definition memb.c:59
void memb_init(struct memb *m)
Initialize a memory block that was declared with MEMB().
Definition memb.c:52
#define MEMB(name, structure, num)
Declare a memory block.
Definition memb.h:91
Linked list manipulation routines.
Header file for the logging system.
Memory block allocation routines.
int tsch_roots_is_root(const linkaddr_t *address)
Tests whether a given address belongs to a single-hop reachable root node in this network.
Definition tsch-roots.c:176
void tsch_roots_set_self_to_root(uint8_t is_root)
Set the root status of the local node.
Definition tsch-roots.c:172
void tsch_roots_add_address(const linkaddr_t *root_address)
Add address as a potential RPL root that is a single-hop neighbor in the TSCH network.
Definition tsch-roots.c:168
void tsch_roots_init(void)
Initialize the list of RPL network roots.
Definition tsch-roots.c:181
Main API declarations for TSCH.