16#include "RPL_Message.h"
20static double compute_dao_delay(NETSIM_ID d)
22 PRPL_NODE rpl = GET_RPL_NODE(d);
24 if (rpl_node_is_joined(rpl))
26 double min_time = rpl->DAODelayTime / 100;
27 double max_time = rpl->DAODelayTime;
29 UINT16 min_rank = RPL_RANK_ROOT;
30 UINT16 max_rank = INFINITE_RANK;
32 UINT16 rank = rpl->joined_dodag->rank;
33 double delay = max_time + min_time - ((rank - min_rank) * (max_time - min_time) / (max_rank - min_rank) + min_time);
39 return rpl->DAODelayTime;
45 NETSIM_ID d = pstruEventDetails->nDeviceId;
46 PRPL_NODE rpl = GET_RPL_NODE(d);
48 if (!rpl_node_is_joined(rpl) || !rpl->joined_dodag->dao_supported)
50 print_rpl_log(
"node '%d': canceled DAO mechanism", d);
53 NetSim_PACKET* dao_pdu = create_dao_message(d,
54 pstruEventDetails->dEventTime,
55 rpl->joined_dodag->pref_parent->nodeId);
59 ptrIP_ROUTINGTABLE* route_list = iptable_get_table_by_type(IP_TABLE_GET(d),
"RPL_DAO", &route_count);
61 for (i = 0; i < route_count; i++)
63 ptrIP_ROUTINGTABLE route = route_list[i];
64 create_and_add_rpl_target_option(dao_pdu,
66 route->networkDestination);
69 if (route_list != NULL)
73 create_and_add_rpl_target_option(dao_pdu,
75 DEVICE_NWADDRESS(d,1));
76 rpl_node_send_msg(d, dao_pdu);
79 NetSim_EVENTDETAILS pevent;
80 memset(&pevent, 0,
sizeof pevent);
81 pevent.dEventTime = pstruEventDetails->dEventTime + compute_dao_delay(d);
83 pevent.nDeviceType = DEVICE_TYPE(d);
84 pevent.nEventType = TIMER_EVENT;
85 pevent.nProtocolId = NW_PROTOCOL_RPL;
86 pevent.nSubEventType = RPL_SEND_DAO;
90static ptrIP_ROUTINGTABLE check_is_route_is_present(PRPL_TARGET_OPTION target,
91 ptrIP_ROUTINGTABLE* route_list,
95 for (i = 0; i < route_count; i++)
97 if (!IP_COMPARE(target->Traget_Prefix, route_list[i]->networkDestination)
98 && target->Prefix_Length == route_list[i]->prefix_len)
104void rpl_process_dao_msg()
106 NETSIM_ID d = pstruEventDetails->nDeviceId;
107 PRPL_CTRL_MSG daoPdu = GET_PRPL_CTRL_MSG(pstruEventDetails->pPacket);
108 PRPL_NODE drpl = GET_RPL_NODE(d);
109 PRPL_DIO_BASE daobase = daoPdu->Base;
110 NETSIM_IPAddress gateway = IP_COPY(pstruEventDetails->pPacket->pstruNetworkData->szSourceIP);
112 PRPL_TARGET_OPTION* target = (PRPL_TARGET_OPTION*)get_all_option_from_msg(daoPdu,RPLOPTION_RPLTARGET,&target_count);
115 ispresent = (
bool*)calloc(target_count,
sizeof* ispresent);
119 ptrIP_ROUTINGTABLE* route_list = iptable_get_table_by_type(IP_TABLE_GET(d),
"RPL_DAO", &route_count);
121 for (i = 0; i < target_count; i++)
124 ptrIP_ROUTINGTABLE route;
125 route = check_is_route_is_present(target[i], route_list, route_count);
129 route->update_time = pstruEventDetails->dEventTime;
130#ifdef DEBUG_RPL_PRINT_DAO_ROUTE_INFOMATION
131 print_rpl_log(
"Node '%d',%0.3lfms: received dao msg with old route information. dest = %s, gateway=%s.",
133 pstruEventDetails->dEventTime/1000,
134 RPL_IP_TO_STR(target[i]->Traget_Prefix),
135 RPL_IP_TO_STR(route->gateway));
140 if (route_list != NULL)
143 for (i = 0; i < target_count; i++)
147#ifdef DEBUG_RPL_PRINT_DAO_ROUTE_INFOMATION
148 print_rpl_log(
"Node '%d',%0.3lfms: received dao msg with new route information. dest = %s, gateway= %s.",
150 pstruEventDetails->dEventTime/1000,
151 RPL_IP_TO_STR(target[i]->Traget_Prefix),
152 RPL_IP_TO_STR(gateway));
154 NETSIM_ID inetrfaceId = 1;
155 ptrIP_ROUTINGTABLE route = iptable_add(IP_WRAPPER_GET(d),
156 target[i]->Traget_Prefix,
158 target[i]->Prefix_Length,
161 &DEVICE_NWADDRESS(d, 1),
165 route->update_time = pstruEventDetails->dEventTime;
168 NetSim_EVENTDETAILS pevent;
169 memset(&pevent, 0,
sizeof pevent);
170 pevent.dEventTime = pstruEventDetails->dEventTime + RPL_DEFAULT_DAO_REMOVE_TIMEOUT;
171 pevent.nDeviceId = d;
172 pevent.nDeviceType = DEVICE_TYPE(d);
173 pevent.nEventType = TIMER_EVENT;
174 pevent.nProtocolId = NW_PROTOCOL_RPL;
175 pevent.nSubEventType = RPL_DAO_ROUTE_TIMEOUT;
176 fnpAddEvent(&pevent);
183void rpl_dao_route_timeout()
185 double time = pstruEventDetails->dEventTime;
186 NETSIM_ID d = pstruEventDetails->nDeviceId;
188 double minupdatetime = 0xFFFFFFFFFFFF;
189 ptrIP_ROUTINGTABLE* route_list = iptable_get_table_by_type(IP_TABLE_GET(d),
"RPL_DAO", &route_count);
190 for (i = 0; i < route_count; i++)
192 ptrIP_ROUTINGTABLE route = route_list[i];
193 if (route->update_time + RPL_DEFAULT_DAO_REMOVE_TIMEOUT <= time)
195#ifdef DEBUG_RPL_PRINT_DAO_ROUTE_INFOMATION
196 print_rpl_log(
"Node '%d',%0.3lfms: Route %s, prefix %d is expired.",
199 RPL_IP_TO_STR(route->networkDestination),
203 iptable_delete_by_route(IP_WRAPPER_GET(d), route);
207 minupdatetime = min(minupdatetime, route->update_time);
211 pstruEventDetails->dEventTime = minupdatetime + RPL_DEFAULT_DAO_REMOVE_TIMEOUT;
212 fnpAddEvent(pstruEventDetails);
218void rpl_dao_msg_destroy(NetSim_PACKET* packet)
220 PRPL_CTRL_MSG rpl = packet->pstruNetworkData->Packet_RoutingProtocol;
221 PRPL_DAO_BASE b = rpl->Base;
226 for (i = 0; i < rpl->option_count; i++)
227 rpl_option_destroy(rpl->options[i]);
232void rpl_dao_msg_copy(
const NetSim_PACKET* destPacket,
const NetSim_PACKET* srcPacket)
234 PRPL_CTRL_MSG srpl = srcPacket->pstruNetworkData->Packet_RoutingProtocol;
235 PRPL_CTRL_MSG drpl = (PRPL_CTRL_MSG)calloc(1,
sizeof* drpl);
236 memcpy(drpl, srpl,
sizeof* drpl);
237 destPacket->pstruNetworkData->Packet_RoutingProtocol = drpl;
239 PRPL_DAO_BASE b = srpl->Base;
240 PRPL_DAO_BASE db = (PRPL_DAO_BASE)calloc(1,
sizeof* db);
241 memcpy(db, b,
sizeof* db);
245 drpl->options = (PRPL_OPTION*)calloc(drpl->option_count,
sizeof* drpl->options);
246 for (i = 0; i < srpl->option_count; i++)
247 drpl->options[i] = rpl_option_copy(srpl->options[i]);