NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
Trickle.c
1/************************************************************************************
2* Copyright (C) 2023 *
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_enum.h"
17
18static void set_trickle_t_time(PRPL_NODE r)
19{
20 r->trickle.t = ((UINT)NETSIM_RAND() % ((UINT)(r->trickle.I / 2))) + r->trickle.I / 2;
21}
22
23void rpl_trickle_reset(NETSIM_ID ndevId)
24{
25 NetSim_EVENTDETAILS pevent;
26 PRPL_NODE r = GET_RPL_NODE(ndevId);
27
28#ifdef DEBUG_RPL_TRICKLE
29 print_rpl_log("node '%d',Time '%0.3lf ms': resetting trickle timer", ndevId,pstruEventDetails->dEventTime/1000);
30#endif
31
32 if (rpl_node_is_root(r))
33 {
34 r->trickle.Imin = pow(2, r->root_info->dio_interval_min)*MILLISECOND;
35 r->trickle.Imax = r->root_info->dio_interval_doublings;
36 r->trickle.k = r->root_info->dio_redundancy_constant;
37 }
38 else if (rpl_node_is_joined(r) || rpl_node_is_poisoning(r))
39 {
40 r->trickle.Imin = pow(2, r->joined_dodag->dio_interval_min)*MILLISECOND;
41 r->trickle.Imax = r->joined_dodag->dio_interval_doublings;
42 r->trickle.k = r->joined_dodag->dio_redundancy_constant;
43 }
44 else
45 {
46 return; /* no trickle timer in isolated state */
47 }
48
49 r->trickle.I = r->trickle.Imin;
50
51 set_trickle_t_time(r);
52
53 //Delete the old trickle event
54 fnDeleteEvent(r->trickle.trickle_i_eventid);
55 fnDeleteEvent(r->trickle.trickle_t_eventid);
56
57 memset(&pevent, 0, sizeof pevent);
58
59 //Schedule the Trickle_t time out event
60 r->trickle.last_trickle_t_schedule_time = ldEventTime + r->trickle.t;
61 pevent.dEventTime = r->trickle.last_trickle_t_schedule_time;
62 pevent.nDeviceId = ndevId;
63 pevent.nDeviceType = DEVICE_TYPE(ndevId);
64 pevent.nEventType = TIMER_EVENT;
65 pevent.nProtocolId = NW_PROTOCOL_RPL;
66 pevent.nSubEventType = RPL_TRICKLE_T_TIMEOUT;
67 r->trickle.trickle_t_eventid = fnpAddEvent(&pevent);
68
69 //Schedule the Trickle_i time out event
70 r->trickle.last_trickle_i_schedule_time = ldEventTime + r->trickle.I;
71 pevent.dEventTime = r->trickle.last_trickle_i_schedule_time;
72 pevent.nSubEventType = RPL_TRICKLE_I_TIMEOUT;
73 r->trickle.trickle_i_eventid = fnpAddEvent(&pevent);
74}
75
76void rpl_trickle_handle_t_timeout()
77{
78 PRPL_NODE r = GET_RPL_NODE(pstruEventDetails->nDeviceId);
79
80 NetSim_PACKET *dio_pdu = create_current_dio_message(pstruEventDetails->nDeviceId, pstruEventDetails->dEventTime, TRUE);
81
82 if (dio_pdu != NULL)
83 rpl_node_send_msg(pstruEventDetails->nDeviceId, dio_pdu);
84}
85
86void rpl_trickle_handle_i_timeout()
87{
88 PRPL_NODE rpl = GET_RPL_NODE(pstruEventDetails->nDeviceId);
89
90 if (rpl_node_is_root(rpl))
91 {
92 if (rpl->trickle.C < rpl->trickle.Imax)
93 {
94 rpl->trickle.C++;
95 rpl->trickle.I *= 2;
96 }
97 }
98 else if (rpl_node_is_joined(rpl))
99 {
100 if (rpl->trickle.C < rpl->trickle.Imax)
101 {
102 rpl->trickle.C++;
103 rpl->trickle.I *= 2;
104 }
105 }
106 else if (rpl_node_is_poisoning(rpl))
107 {
108 if (rpl->poison_count_so_far < RPL_DEFAULT_POISON_COUNT)
109 {
110 rpl->poison_count_so_far++;
111 }
112 else
113 { /* enough with poisoning */
114 bool same;
115 PRPL_CTRL_MSG preferred_dodag_pdu = get_preferred_dodag_dio_pdu(pstruEventDetails->nDeviceId,
116 &same,
117 pstruEventDetails->dEventTime);
118
119 if (preferred_dodag_pdu != NULL)
120 {
121 join_dodag_iteration(pstruEventDetails->nDeviceId, preferred_dodag_pdu);
122 choose_parents_and_siblings(pstruEventDetails->nDeviceId);
123 }
124 else
125 {
126 start_as_root(pstruEventDetails->nDeviceId);
127 }
128
129 return;
130 }
131 }
132 else
133 {
134 fnNetSimError("Unknown node status for node %s in rpl\n", pstruEventDetails->nDeviceId);
135 return; /* this should never happen */
136 }
137
138 set_trickle_t_time(rpl);
139
140#ifdef DEBUG_RPL_TRICKLE
141 print_rpl_log("node '%d': trickle time is generated at t=%0.3lf, i=%0.2lf",
142 pstruEventDetails->nDeviceId,
143 (ldEventTime + rpl->trickle.t) / 1000,
144 (ldEventTime + rpl->trickle.I) / 1000);
145#endif
146
147 NetSim_EVENTDETAILS pevent;
148
149 memset(&pevent, 0, sizeof pevent);
150
151 //Schedule the Trickle_t time out event
152 rpl->trickle.last_trickle_t_schedule_time = ldEventTime + rpl->trickle.t;
153 pevent.dEventTime = rpl->trickle.last_trickle_t_schedule_time;
154 pevent.nDeviceId = pstruEventDetails->nDeviceId;
155 pevent.nDeviceType = pstruEventDetails->nDeviceType;
156 pevent.nEventType = TIMER_EVENT;
157 pevent.nProtocolId = NW_PROTOCOL_RPL;
158 pevent.nSubEventType = RPL_TRICKLE_T_TIMEOUT;
159 rpl->trickle.trickle_t_eventid = fnpAddEvent(&pevent);
160
161 //Schedule the Trickle_i time out event
162 rpl->trickle.last_trickle_i_schedule_time = ldEventTime + rpl->trickle.I;
163 pevent.dEventTime = rpl->trickle.last_trickle_i_schedule_time;
164 pevent.nSubEventType = RPL_TRICKLE_I_TIMEOUT;
165 rpl->trickle.trickle_i_eventid = fnpAddEvent(&pevent);
166}