NetSim Source Code Help
Loading...
Searching...
No Matches
Neighbor.c
Go to the documentation of this file.
1/************************************************************************************
2* Copyright (C) 2020 *
3* TETCOS, Bangalore. India *
4* *
5* Tetcos owns the intellectual property rights in the Product and its content. *
6* The copying, redistribution, reselling or publication of any or all of the *
7* Product or its content without express prior written consent of Tetcos is *
8* prohibited. Ownership and / or any other right relating to the software and all *
9* intellectual property rights therein shall remain at all times with Tetcos. *
10* *
11* Author: Shashi Kant Suman *
12* *
13* ---------------------------------------------------------------------------------*/
14#include "main.h"
15#include "RPL.h"
16#include "RPL_Message.h"
17#include "RPL_enum.h"
18
20{
21 PRPL_NODE rpl = GET_RPL_NODE(d);
22 UINT i;
23 for (i = 0; i < rpl->neighbor_count; i++)
24 {
25 if (rpl->neighbor_list[i]->nodeId == r)
26 return rpl->neighbor_list[i];
27 }
28 return NULL;
29}
30
32{
33 PRPL_NODE rpl = GET_RPL_NODE(d);
34 if (rpl->neighbor_count)
35 rpl->neighbor_list = (PRPL_NEIGHBOR*)realloc(rpl->neighbor_list,(rpl->neighbor_count + 1)* (sizeof* rpl->neighbor_list));
36 else
37 rpl->neighbor_list = (PRPL_NEIGHBOR*)calloc(1, sizeof* rpl->neighbor_list);
38 PRPL_NEIGHBOR neighbor = (PRPL_NEIGHBOR)calloc(1, sizeof* neighbor);
39 neighbor->nodeId = r;
40 rpl->neighbor_list[rpl->neighbor_count] = neighbor;
41 rpl->neighbor_count++;
42}
43
45{
48
50 {
51 PRPL_NODE rpl = GET_RPL_NODE(d);
52 PRPL_NEIGHBOR neighbor = rpl_find_neighbor(d, r);
53 if (!neighbor)
54 add_neighbor(d, r);
55 }
56}
57
59{
61 neighbor->lastDIOMSG = rpl_dio_pdu_duplicate(dio_pdu);
62}
63
65{
66 PRPL_NODE rpl = GET_RPL_NODE(d);
67 if (!rpl->joined_dodag)
68 fnNetSimError("joined_dodag is null for %d device in %s\n", d, __FUNCTION__);
69
70 PRPL_DODAG dodag = rpl->joined_dodag;
71
72 dodag->parent_list = (PRPL_NEIGHBOR*)realloc(dodag->parent_list, (dodag->parent_count + 1) * sizeof(PRPL_NEIGHBOR));
73 dodag->parent_list[dodag->parent_count++] = parent;
74}
75
77{
78 PRPL_NODE drpl = GET_RPL_NODE(d);
79 if (drpl->joined_dodag == NULL)
80 return NULL;
81
82 PRPL_DODAG dodag = drpl->joined_dodag;
83
84 int i;
85 for (i = 0; i < dodag->parent_count; i++)
86 {
87 if (dodag->parent_list[i]->nodeId == parent)
88 return dodag->parent_list[i];
89 }
90
91 return NULL;
92}
93
95{
96 PRPL_NODE rpl = GET_RPL_NODE(d);
97 UINT16 i;
98 for (i = 0; i < rpl->joined_dodag->parent_count; i++)
99 {
100 //Don't free because same pointer is present in neighbor list and siblings also.
101 rpl->joined_dodag->parent_list[i] = NULL;
102 }
103 rpl->joined_dodag->parent_list = NULL;
104 rpl->joined_dodag->parent_count = 0;
105}
106
108{
109 UINT16 i;
110 for (i = 0; i < rpl->neighbor_count; i++)
111 {
112 PRPL_NEIGHBOR neighbor = rpl->neighbor_list[i];
113
114 if (neighbor->lastDIOMSG != NULL)
115 {
116 rpl_dio_pdu_free(neighbor->lastDIOMSG);
117 neighbor->lastDIOMSG = NULL;
118 }
119 }
120}
121
123{
124 PRPL_NODE rpl = GET_RPL_NODE(d);
125
126 if (!rpl->joined_dodag)
127 fnNetSimError("joined_dodag is null for %d in %s\n", d, __FUNCTION__);
128
129 PRPL_DODAG dodag = rpl->joined_dodag;
130
131 dodag->sibling_list = (PRPL_NEIGHBOR*)realloc(dodag->sibling_list, (dodag->sibling_count + 1) * sizeof(PRPL_NEIGHBOR));
132 dodag->sibling_list[dodag->sibling_count++] = sibling;
133}
134
136{
137 PRPL_NODE drpl = GET_RPL_NODE(d);
138 if (drpl->joined_dodag == NULL)
139 return NULL;
140
141 PRPL_DODAG dodag = drpl->joined_dodag;
142
143 int i;
144 for (i = 0; i < dodag->sibling_count; i++)
145 {
146 if (dodag->sibling_list[i]->nodeId == sibling)
147 return dodag->sibling_list[i];
148 }
149
150 return NULL;
151}
152
154{
155 PRPL_NODE rpl = GET_RPL_NODE(d);
156 if (!rpl->joined_dodag)
157 fnNetSimError("joined_dodag is null for %d device in %s\n", d, __FUNCTION__);
158
159 PRPL_DODAG dodag = rpl->joined_dodag;
160
161 if (dodag->sibling_list != NULL)
162 {
163 free(dodag->sibling_list);
164 dodag->sibling_list = NULL;
165 }
166
167 dodag->sibling_count = 0;
168}
169
171{
172 if (neighbor->nodeId == 0)
173 return INFINITE_RANK;
174
175 double send_link_quality = fn_NetSim_stack_get_link_quality(d, 1, neighbor->nodeId, 1);
176 double receive_link_quality = fn_NetSim_stack_get_link_quality(neighbor->nodeId, 1, d, 1);
177 double link_quality = (send_link_quality + receive_link_quality) / 2;
178
179 // Objective function. Rank calculation done by default using link quality.
180 // Users can change suitable
182
183 PRPL_DIO_BASE Base = neighbor->lastDIOMSG->Base;
184 rank += Base->Rank;
185
186 return rank > INFINITE_RANK ? INFINITE_RANK : rank;
187}
188
190{
191 PRPL_NODE rpl = GET_RPL_NODE(d);
192
193 if (!rpl->joined_dodag)
194 fnNetSimError("joined_dodag is null for %d device in %s\n", d, __FUNCTION__);
195
196 PRPL_DODAG dodag = rpl->joined_dodag;
197
198 /* forget about previous DIO routes */
200
203
204 INT16 best_rank_index = -1;
205
206 UINT16* matching_ranks = (UINT16*)calloc(rpl->neighbor_count,sizeof* matching_ranks);
207
208 UINT16 i;
209 for (i = 0; i < rpl->neighbor_count; i++)
210 {
211 PRPL_NEIGHBOR neighbor = rpl->neighbor_list[i];
212
213 matching_ranks[i] = INFINITE_RANK;
214
215 if (neighbor->lastDIOMSG == NULL)
216 { /* ignore neighbors who haven't sent any DIO */
217 continue;
218 }
219
220 PRPL_DIO_BASE nBase = neighbor->lastDIOMSG->Base;
221
222 if (IP_COMPARE(nBase->DODAGID, dodag->dodag_id) != 0)
223 { /* ignore neighbors from different DODAGs */
224 continue;
225 }
226
227 if (nBase->DTSN != dodag->seq_num)
228 { /* ignore neighbors from different DODAG iterations */
229 continue;
230 }
231
232 if (nBase->Rank >= INFINITE_RANK)
233 { /* ignore neighbors that started poisoning */
234 continue;
235 }
236
237 if (nBase->Rank > dodag->rank)
238 { /* ignore and forget neighbors that aren't our parents or siblings */
239 rpl_dio_pdu_free(neighbor->lastDIOMSG);
240 neighbor->lastDIOMSG = NULL;
241 continue;
242 }
243
244 matching_ranks[i] = compute_candidate_rank(d, neighbor);
245
246 if (best_rank_index == -1)
247 {
248 best_rank_index = i;
249 continue;
250 }
251
252 if (matching_ranks[i] < matching_ranks[best_rank_index])
253 {
254 best_rank_index = i;
255 }
256 }
257
258 if (best_rank_index == -1)
259 { /* no valid neighbors found for this current DODAG iteration */
260 print_rpl_log("node '%d': no valid neighbors left in dodag_id = '%s'", d, RPL_IP_TO_STR(dodag->dodag_id));
261 bool same;
263
264 if (preferred_dodag_pdu != NULL && !same)
265 { /* found something interesting around */
266 join_dodag_iteration(d, preferred_dodag_pdu);
268 }
269 else
270 { /* didn't find anything interesting, we're the best, start floating or poisoning */
272 }
273
274 return;
275 }
276
277 UINT16 best_rank = matching_ranks[best_rank_index];
278 if (best_rank - dodag->lowest_rank > dodag->max_rank_inc || best_rank >= INFINITE_RANK)
279 { /* rank would increase too much */
280 print_rpl_log("node '%d': in dodag_id = '%s', new rank (%d) would exceed the limit (%d + %d)",
281 d, RPL_IP_TO_STR(dodag->dodag_id), best_rank, dodag->lowest_rank, dodag->max_rank_inc);
282
283 if (rpl->joined_dodag->pref_parent != NULL &&
284 rpl->joined_dodag->pref_parent->lastDIOMSG != NULL &&
286 {
287
288 print_rpl_log("node '%d': following parent on dodag_id = '%s'",
289 d, ((PRPL_DIO_BASE)rpl->joined_dodag->pref_parent->lastDIOMSG)->DODAGID);
290
293 }
294 else
295 {
296 print_rpl_log("node '%d': couldn't follow preferred parent, need to poison", d);
298 }
299 return;
300 }
301
302 dodag->rank = best_rank;
303 if (best_rank < dodag->lowest_rank)
304 dodag->lowest_rank = best_rank;
305
306
307 NETSIM_ID old_pref_parent = ((dodag->pref_parent == NULL) ? (0) : (dodag->pref_parent->nodeId));
308 dodag->pref_parent = rpl->neighbor_list[best_rank_index];
309 if (dodag->pref_parent->nodeId != old_pref_parent)
310 {
311 NetSim_EVENTDETAILS pevent;
312 memset(&pevent, 0, sizeof pevent);
314 pevent.nDeviceId = d;
315 pevent.nDeviceType = DEVICE_TYPE(d);
316 pevent.nEventType = TIMER_EVENT;
318 pevent.nSubEventType = RPL_NEW_PREF_PARENT;
319 fnpAddEvent(&pevent);
320 }
322
323 for (i = 0; i < rpl->neighbor_count; i++)
324 {
325 PRPL_NEIGHBOR neighbor = rpl->neighbor_list[i];
326
327 if (matching_ranks[i] >= INFINITE_RANK)
328 {
329 if (neighbor->lastDIOMSG != NULL)
330 { /* forget messages from other DODAG iterations */
331 rpl_dio_pdu_free(neighbor->lastDIOMSG);
332 neighbor->lastDIOMSG = NULL;
333 }
334 continue;
335 }
336
337 PRPL_DIO_BASE dbase = neighbor->lastDIOMSG->Base;
338
339 if (dbase->Rank < best_rank)
340 { /* a parent */
341 rpl_node_add_parent(d, neighbor);
342 }
343 else if (dbase->Rank == best_rank)
344 { /* a sibling */
345 rpl_node_add_sibling(d, neighbor);
346 }
347 else
348 { /* forget messages from higher ranked nodes */
349 if (neighbor->lastDIOMSG != NULL)
350 {
351 rpl_dio_pdu_free(neighbor->lastDIOMSG);
352 neighbor->lastDIOMSG = NULL;
353 }
354 }
355 }
356
357#ifdef DEBUG_RPL
358
359 char parent_list_str[256];
360 char sibling_list_str[256];
361
362 dodag = rpl->joined_dodag;
363
364 parent_list_str[0] = '\0';
365 for (i = 0; i < dodag->parent_count; i++)
366 {
367 PRPL_NEIGHBOR neighbor = dodag->parent_list[i];
368
369 if (neighbor == dodag->pref_parent)
370 {
371 char sz[10];
372 sprintf(sz, "(%d)", neighbor->nodeId);
373 strcat(parent_list_str, sz);
374 }
375 else
376 {
377 char sz[10];
378 sprintf(sz, "%d", neighbor->nodeId);
379 strcat(parent_list_str, sz);
380 }
381
382 if (i < dodag->parent_count - 1)
383 {
384 strcat(parent_list_str, ", ");
385 }
386 }
387
388 sibling_list_str[0] = '\0';
389 for (i = 0; i < dodag->sibling_count; i++)
390 {
391 PRPL_NEIGHBOR neighbor = dodag->sibling_list[i];
392
393 char sz[10];
394 sprintf(sz, "%d", neighbor->nodeId);
395 strcat(sibling_list_str, sz);
396 if (i < dodag->sibling_count - 1)
397 {
398 strcat(sibling_list_str, ", ");
399 }
400 }
401 print_rpl_log("node '%d': chosen parents and siblings in dodag_id = '%s': new rank = %d, parents = [%s], siblings = [%s]",
402 d, RPL_IP_TO_STR(dodag->dodag_id), dodag->rank, parent_list_str, sibling_list_str);
403
404#endif /* DEBUG_RPL */
405}
406
408{
409 UINT16 i;
410 for (i = 0; i < rpl->neighbor_count; i++)
411 {
412 PRPL_NEIGHBOR n = rpl->neighbor_list[i];
413 free(n);
414 }
415 rpl->neighbor_count = 0;
416}
unsigned int NETSIM_ID
Definition: Animation.h:45
PRPL_CTRL_MSG get_preferred_dodag_dio_pdu(NETSIM_ID d, bool *same, double time)
Definition: DIO.c:78
void start_dio_poisoning(NETSIM_ID d)
Definition: DIO.c:60
void join_dodag_iteration(NETSIM_ID d, PRPL_CTRL_MSG dio_pdu)
Definition: DODAG.c:73
#define IP_COMPARE(ip1, ip2)
Definition: IP_Addressing.h:67
#define UINT
Definition: Linux.h:38
#define fnNetSimError(x,...)
Definition: Linux.h:56
#define UINT16
Definition: Linux.h:33
#define INT16
Definition: Linux.h:32
#define realloc(p, s)
Definition: Memory.h:32
#define free(p)
Definition: Memory.h:31
#define calloc(c, s)
Definition: Memory.h:29
static void add_neighbor(NETSIM_ID d, NETSIM_ID r)
Definition: Neighbor.c:31
void rpl_node_add_sibling(NETSIM_ID d, PRPL_NEIGHBOR sibling)
Definition: Neighbor.c:122
PRPL_NEIGHBOR rpl_node_find_sibling(NETSIM_ID d, NETSIM_ID sibling)
Definition: Neighbor.c:135
PRPL_NEIGHBOR rpl_node_find_parent(NETSIM_ID d, NETSIM_ID parent)
Definition: Neighbor.c:76
void forget_neighbor_messages(PRPL_NODE rpl)
Definition: Neighbor.c:107
void rpl_node_remove_all_siblings(NETSIM_ID d)
Definition: Neighbor.c:153
void choose_parents_and_siblings(NETSIM_ID d)
Definition: Neighbor.c:189
PRPL_NEIGHBOR rpl_find_neighbor(NETSIM_ID d, NETSIM_ID r)
Definition: Neighbor.c:19
void update_neighbor_dio_message(PRPL_NEIGHBOR neighbor, PRPL_CTRL_MSG dio_pdu)
Definition: Neighbor.c:58
void rpl_node_add_parent(NETSIM_ID d, PRPL_NEIGHBOR parent)
Definition: Neighbor.c:64
void rpl_add_to_neighbor_list()
Definition: Neighbor.c:44
static UINT16 compute_candidate_rank(NETSIM_ID d, PRPL_NEIGHBOR neighbor)
Definition: Neighbor.c:170
void free_all_neighbor(PRPL_NODE rpl)
Definition: Neighbor.c:407
void rpl_node_remove_all_parents(NETSIM_ID d)
Definition: Neighbor.c:94
void rpl_delete_all_route(NETSIM_ID d)
#define GET_RPL_NODE(d)
Definition: RPL.h:212
void rpl_dio_pdu_free(PRPL_CTRL_MSG dio)
Definition: RPL_Message.c:343
void rpl_add_route_to_parent(NETSIM_ID d, NETSIM_ID parent)
void print_rpl_log(char *format,...)
#define INFINITE_RANK
Definition: RPL.h:81
#define RPL_MAXIMUM_RANK_INCREMENT
Definition: RPL.h:84
#define RPL_IP_TO_STR(ip)
Definition: RPL.h:316
struct stru_rpl_neighbor * PRPL_NEIGHBOR
#define RPL_MINIMUM_RANK_INCREMENT
Definition: RPL.h:83
#define is_rpl_configured(d)
Definition: RPL.h:95
PRPL_CTRL_MSG rpl_dio_pdu_duplicate(PRPL_CTRL_MSG dio)
Definition: RPL_Message.c:314
#define DEVICE_TYPE(DeviceId)
Definition: Stack.h:773
@ NW_PROTOCOL_RPL
Definition: Stack.h:200
double fn_NetSim_stack_get_link_quality(NETSIM_ID trx, NETSIM_ID tri, NETSIM_ID rx, NETSIM_ID ri)
@ TIMER_EVENT
Definition: Stack.h:114
EXPORTED struct stru_NetSim_EventDetails * pstruEventDetails
Definition: Stack.h:837
#define fnpAddEvent(pstruEvent)
Definition: main.h:191
EVENT_TYPE nEventType
Definition: Stack.h:747
NETSIM_ID nProtocolId
Definition: Stack.h:748
struct stru_NetSim_Packet * pPacket
Definition: Stack.h:754
NETSIM_ID nSubEventType
Definition: Stack.h:757
NETSIM_ID nDeviceId
Definition: Stack.h:750
netsimDEVICE_TYPE nDeviceType
Definition: Stack.h:749
NETSIM_ID nTransmitterId
Definition: Packet.h:265
NETSIM_IPAddress DODAGID
Definition: RPL_Message.h:143
UINT16 rank
Definition: RPL.h:158
UINT16 lowest_rank
Definition: RPL.h:157
PRPL_NEIGHBOR pref_parent
Definition: RPL.h:164
PRPL_NEIGHBOR * sibling_list
Definition: RPL.h:162
DODAGID dodag_id
Definition: RPL.h:143
UINT16 parent_count
Definition: RPL.h:161
PRPL_NEIGHBOR * parent_list
Definition: RPL.h:160
UINT8 seq_num
Definition: RPL.h:156
UINT16 max_rank_inc
Definition: RPL.h:153
UINT16 sibling_count
Definition: RPL.h:163
NETSIM_ID nodeId
Definition: RPL.h:116
PRPL_CTRL_MSG lastDIOMSG
Definition: RPL.h:119
PRPL_DODAG joined_dodag
Definition: RPL.h:178
UINT16 neighbor_count
Definition: RPL.h:200
PRPL_NEIGHBOR * neighbor_list
Definition: RPL.h:199