DESERT 3.5.1
Loading...
Searching...
No Matches
uwmulti-traffic-range-crt.cc
Go to the documentation of this file.
1//
2// Copyright (c) 2014 Regents of the SIGNET lab, University of Padova.
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 University of Padova (SIGNET lab) nor the
14// names of its contributors may be used to endorse or promote products
15// derived 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 LIMITED
19// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
39#include "uwip-clmsg.h"
40#include <uwcbr-module.h>
41#include <iostream>
42
50
54static class UwMultiTrafficRangeCtrClass : public TclClass
55{
56public:
60 UwMultiTrafficRangeCtrClass() : TclClass("Module/UW/MULTI_TRAFFIC_RANGE_CTR") {}
65 TclObject* create(int, const char*const*)
66 {
67 return (new UwMultiTrafficRangeCtr);
68 }
70
72:
74 status(),
77 timers()
78{
79 bind("check_to_period_", &check_to_period);
80 bind("signaling_pktSize_", &signaling_pktSize);
81}
82
83int UwMultiTrafficRangeCtr::command(int argc, const char*const* argv)
84{
85 Tcl &tcl = Tcl::instance();
86 if (argc == 3)
87 {
88 if(strcasecmp(argv[1], "getProbeSent") == 0)
89 {
90 tcl.resultf("%d", getSignalingCounter(atoi(argv[2]), tx_probe_cnt));
91 return TCL_OK;
92 }
93 else if((strcasecmp(argv[1], "getProbeRecv") == 0))
94 {
95 tcl.resultf("%d", getSignalingCounter(atoi(argv[2]), rx_probe_cnt));
96 return TCL_OK;
97 }
98 else if((strcasecmp(argv[1], "getProbeAckSent") == 0))
99 {
100 tcl.resultf("%d", getSignalingCounter(atoi(argv[2]), tx_probe_ack_cnt));
101 return TCL_OK;
102 }
103 else if((strcasecmp(argv[1], "getProbeAckRecv") == 0))
104 {
105 tcl.resultf("%d", getSignalingCounter(atoi(argv[2]), rx_probe_ack_cnt));
106 return TCL_OK;
107 }
108 }
109 else if (argc == 4)
110 {
111 if(strcasecmp(argv[1], "addRobustLowLayer") == 0)
112 {
113 addLowLayerFromTag(atoi(argv[2]),argv[3],ROBUST);
114 return TCL_OK;
115 }
116 else if(strcasecmp(argv[1], "addFastLowLayer") == 0)
117 {
118 addLowLayerFromTag(atoi(argv[2]),argv[3],CHECK_RANGE);
119 return TCL_OK;
120 }
121 }
122 return UwMultiTrafficControl::command(argc, argv);
123} /* UwMultiTrafficRangeCtr::command */
124
125void UwMultiTrafficRangeCtr::recv(Packet* p, int idSrc)
126{
127 hdr_cmn *ch = HDR_CMN(p);
128 if (ch->direction() == hdr_cmn::UP) {
129 if (ch->ptype() == PT_MULTI_TR_PROBE_ACK) {
130 hdr_uwip* iph = HDR_UWIP(p);
131 if (debug_)
132 std::cout << NOW << " UwMultiTrafficRangeCtr::recv PT_MULTI_TR_PROBE_ACK from:"
133 << (int)(iph->saddr()) << " in layer " << idSrc << std::endl;
135 manageCheckedLayer(HDR_UWMTR(p)->traffic() , iph->saddr(), true, idSrc);
136 Packet::free(p);
137 }
138 else if (ch->ptype() == PT_MULTI_TR_PROBE) {
140 sendSyncClMsgUp(&msg);
141 hdr_uwip* iph = HDR_UWIP(p);
143 if (iph->daddr() == msg.getAddr() || iph->daddr() == UWIP_BROADCAST) {
144 ch->ptype() = PT_MULTI_TR_PROBE_ACK;
145 ch->size() = signaling_pktSize;
146 if (debug_)
147 std::cout << NOW << " UwMultiTrafficRangeCtr::recv PT_MULTI_TR_PROBE from:"
148 << (int)iph->saddr() << " in layer " << idSrc << std::endl;
149 iph->daddr() = iph->saddr();
150 iph->saddr() = msg.getAddr();
152 /*ch->next_hop() = ch->prev_hop_;*/
153 sendDown(idSrc, p);
154 }
155 else {
156
157 if (debug_)
158 std::cout << NOW << " UwMultiTrafficRangeCtr::recv PT_MULTI_TR_PROBE from :" << (int)iph->saddr()
159 << " for:" << (int)iph->daddr() << "and not " << msg.getAddr() << " in layer "
160 << idSrc << " discarded" << std::endl;
161 Packet::free(p);
162 }
163 }
164 else {
166 if(debug_)
167 std::cout << "UwMultiTrafficRangeCtr::recv(DIR=UP, no signaling)" << std::endl;
168 }
169 }
170 else {
172 if(debug_)
173 std::cout << NOW << " UwMultiTrafficRangeCtr::recv(DIR=DOWN)" << std::endl;
174 }
175}
176
177void UwMultiTrafficRangeCtr::manageCheckedLayer(int traffic, uint8_t destAdd, bool in_range, int idSrc)
178{
179 BufferTrafficFeature::iterator it_feat = buffer_feature_map.find(traffic);
180 if (it_feat == buffer_feature_map.end()) {
181 std::cout << "UwMultiTrafficControl::manageCheckedLayer. ERROR. Buffer not "
182 << "configured. Traffic " << traffic << std::endl;
183 return;
184 }
185 std::map<int, UwCheckRangeTimer*>::iterator it_t = timers.find(traffic);
186 if (it_t == timers.end())
187 return;
188 UwCheckRangeTimer *to = it_t->second;
189 if(to->status() == TIMER_IDLE) {
190 return; // nothing to check is pending
191 }
192 else {
193 StatusMap::iterator it_s = status.find(traffic);
194 if (it_s == status.end())
195 return;
196 if(status[traffic].status == RANGE_CNF_WAIT){
197 if(in_range || status[traffic].robust_id) {
198 Packet *p = NULL;
199 while(true){
200 p = getFromBuffer(traffic);
201 if(p != NULL && (HDR_UWIP(p)->daddr() == destAdd || HDR_CMN(p)->next_hop() == destAdd ||
202 HDR_CMN(p)->next_hop() == UWIP_BROADCAST)) {
203 to->force_cancel();
204 to->num_expires = 0;
205 status[traffic].status = IDLE;
206 //do {
207 if(debug_)
208 std::cout << NOW << " UwMultiTrafficRangeCtr::manageCheckedLayer sending packet" << std::endl;
209 if(in_range) {
210 /*sendDown(status[traffic].module_id,p);*/
211 sendDown(idSrc,p, it_feat->second.getUpdatedDelay(NOW));
212 }
213 else {
214 sendDown(status[traffic].robust_id,p,
215 it_feat->second.getUpdatedDelay(NOW));
216 }
217 removeFromBuffer(traffic);
218 //p = removeFromBuffer(traffic);
219 //} while (p != NULL && HDR_UWIP(p)->daddr() == destAdd);
220 }
221 else if(p == NULL) {
222 if(debug_)
223 std::cout << NOW << " UwMultiTrafficRangeCtr::manageCheckedLayer nothing to send to no one"
224 << std::endl;
225 break;
226 }
227 else{ //NEVER APPENS IF THERE ARE ONLY 2 NODES
228 Packet *p0 = p;
229 do {
230 removeFromBuffer(traffic);
231 insertInBuffer(p,traffic);
232 p = getFromBuffer(traffic);
233 } while (p != NULL && p != p0 && (HDR_UWIP(p)->daddr() != destAdd ||
234 HDR_CMN(p)->next_hop() == destAdd || HDR_CMN(p)->next_hop() == UWIP_BROADCAST));
235 if(!(HDR_UWIP(p)->daddr() == destAdd || HDR_CMN(p)->next_hop() == destAdd ||
236 HDR_CMN(p)->next_hop() == UWIP_BROADCAST)) {
237 if(debug_)
238 std::cout << NOW << " UwMultiTrafficRangeCtr::manageCheckedLayer wrong daddr "
239 << (int)HDR_UWIP(p)->daddr() << ", " << (int)destAdd << std::endl;
240 break;
241 }
242 else {
243 if(in_range) {
244 /*sendDown(status[traffic].module_id,p);*/
245 sendDown(idSrc,p,it_feat->second.getUpdatedDelay(NOW));
246 }
247 else {
248 sendDown(status[traffic].robust_id,p,
249 it_feat->second.getUpdatedDelay(NOW));
250 }
251 removeFromBuffer(traffic);
252 }
253 }
254 }
255 }
256 else {
257 to->force_cancel();
258 ++to->num_expires;
259 /*checkRange(traffic, status[traffic].module_id);*/
260 checkRange(traffic, idSrc);
261 }
262 }
263 }
264}
265
266
268{
269 BufferTrafficFeature::iterator it_feat = buffer_feature_map.find(traffic);
270 if (it_feat == buffer_feature_map.end()) {
271 std::cout << "UwMultiTrafficControl::manageBuffer. ERROR. Buffer not "
272 << "configured. Traffic " << traffic << std::endl;
273 return;
274 }
275 Packet *p = getFromBuffer(traffic);
276 if (p != NULL) {
277 int l_id = getBestLowerLayer(traffic,p);
278 StatusMap::iterator it_s = status.find(traffic);
279 if (it_s == status.end() || status[traffic].status == IDLE) {
280 double delay = it_feat->second.getUpdatedDelay(NOW);
281 return l_id ? sendDown(l_id,removeFromBuffer(traffic),delay)
282 : sendDown(removeFromBuffer(traffic),delay);
283 }
284 }
285}
286
288{
289 if (debug_)
290 std::cout << NOW << " UwMultiTrafficRangeCtr::getBestLowerLayer(" << traffic << ")" << std::endl;
291 DownTrafficMap::iterator it = down_map.find(traffic);
292 if (it != down_map.end()) {
293 StatusMap::iterator it_s = status.find(traffic);
294 if (it_s == status.end()) {
295 initStatus(traffic);
296 }
297 if (status[traffic].status == RANGE_CNF_WAIT) {// I'm checking the range
298 if (debug_)
299 std::cout << NOW << " UwMultiTrafficRangeCtr::getBestLowerLayer(" << traffic
300 << ") status == RANGE_CNF_WAIT" << std::endl;
301 return 0;
302 }
303 BehaviorMap temp = it->second;
304 BehaviorMap::iterator it_b = temp.begin();
305 for (; it_b!=temp.end(); ++it_b)
306 {
307 int module_id_tmp = it_b->second.first;
308 switch (it_b->second.second)
309 {
310 case(CHECK_RANGE):
311 {
312 if (debug_)
313 std::cout << NOW << " UwMultiTrafficRangeCtr::getBestLowerLayer(" << traffic << "): CHECK_RANGE"
314 << "PROBING" << it_b->second.first << std::endl;
315 if(status[traffic].module_ids.find(module_id_tmp)==status[traffic].module_ids.end())
316 status[traffic].module_ids.insert(module_id_tmp);
317 checkRange(traffic, it_b->second.first, HDR_CMN(p)->next_hop());
318 break;
319 }
320 case(ROBUST):
321 {
322 if (debug_)
323 std::cout << NOW << " UwMultiTrafficRangeCtr::getBestLowerLayer(" << traffic << "): ROBUST"
324 << std::endl;
325 status[traffic].robust_id = module_id_tmp;
326 break;
327 }
328 default:
329 {
330 std::cout << NOW << " UwMultiTrafficRangeCtr:: DEFAULT NOT ALLOWED" << std::endl;
331 break;
332 }
333 }
334 }
335 if (status[traffic].status == IDLE && status[traffic].robust_id)
336 return status[traffic].robust_id;
337 }
338 return 0;
339}
340
341void UwMultiTrafficRangeCtr::checkRange(int traffic, int module_id, uint8_t destAdd)
342{
343 StatusMap::iterator it_s = status.find(traffic);
344 if (it_s == status.end()) {
345 initStatus(traffic);
346 }
347 if(status[traffic].status == RANGE_CNF_WAIT){//already checking
348 if (debug_)
349 std::cout << NOW << " UwMultiTrafficRangeCtr::checkRange ALREADY CHECKING" << endl;
350 }
351 else {
352 status[traffic].status = RANGE_CNF_WAIT;
353 std::map<int, UwCheckRangeTimer*>::iterator it_t = timers.find(traffic);
354 if (it_t == timers.end()) {
355 UwCheckRangeTimer *t_o = new UwCheckRangeTimer(this,traffic);
356 t_o->resched(check_to_period * (t_o->num_expires + 1));
357 timers.insert(std::pair<int,UwCheckRangeTimer*>(traffic, t_o));
358 }
359 else{
360 it_t->second->resched(check_to_period * (it_t->second->num_expires + 1));
361 }
362 }
363 Packet* p = Packet::alloc();
364 hdr_cmn* ch = hdr_cmn::access(p);
365 ch->ptype() = PT_MULTI_TR_PROBE;
366 ch->size() = signaling_pktSize;
367 hdr_uwm_tr* tr = HDR_UWMTR(p);
368 tr->traffic() = traffic;
369 hdr_uwip* iph = HDR_UWIP(p);
371 sendSyncClMsgUp(&msg);
372 iph->saddr() = msg.getAddr();
373 iph->daddr() = destAdd;
374 hdr_uwcbr *ah = HDR_UWCBR(p);
375 ah->priority() = 1;
377 sendDown(module_id, p);
378 if (debug_)
379 std::cout << NOW << " UwMultiTrafficRangeCtr(" << (int)iph->saddr() << ")::checkRange "
380 << "sending PT_MULTI_TR_PROBE to " << (int) iph->saddr() << std::endl;
381}
382
384{
385 if(debug_)
386 std::cout << NOW << " UwMultiTrafficRangeCtr::timerExpired(" << traffic << ")" << std::endl;
387 StatusMap::iterator it_s = status.find(traffic);
388 if (it_s == status.end())
389 return;
390 if (status[traffic].status != RANGE_CNF_WAIT)
391 return;
392 if (status[traffic].robust_id)
393 {
394 std::map<int, UwCheckRangeTimer*>::iterator it_t = timers.find(traffic);
395 if (it_t != timers.end()) {
396 it_t->second->num_expires = 0;
397 }
398 Packet *p = getFromBuffer(traffic);
399 if(p!=NULL)
400 manageCheckedLayer(traffic, HDR_UWIP(p)->daddr(), false);
401 status[traffic].status = IDLE;
402 }
403 else
404 {
405 status[traffic].status = IDLE;
406 for (std::set<int>::iterator it = status[traffic].module_ids.begin();
407 it!= status[traffic].module_ids.end(); ++it){
408 if(*it > 0) {
409 checkRange(traffic, *it, UWIP_BROADCAST);
410 }
411 }
412 }
413}
414
416{
417 check_status default_st;
418 default_st.status = IDLE;
419 default_st.module_ids = set<int>();
420 default_st.robust_id = 0;
421 status[traffic] = default_st;
422}
423
425 CounterMap& map_cnt)
426{
427 CounterMap::iterator it = map_cnt.find(traffic);
428 if (it != map_cnt.end()) {
429 it->second++;
430 } else {
431 map_cnt[traffic] = 1;
432 }
433}
434
436 const CounterMap& map_cnt) const
437{
438 CounterMap::const_iterator it = map_cnt.find(traffic);
439 if (it == map_cnt.end()) {
440 return 0;
441 } else {
442 return it->second;
443 }
444}
Class used to answer to UWIPClMsgReqAddr cross layer messages.
Definition uwip-clmsg.h:68
nsaddr_t getAddr()
Class used to represents the UwMultiTrafficControl layer of a node.
BufferTrafficFeature buffer_feature_map
Map with features of each buffer.
virtual int command(int, const char *const *)
TCL command interpreter.
int debug_
Flag to activate debug verbosity.
virtual void addLowLayerFromTag(int traffic_id, std::string tag, int behavior)
add a lower layer from the tag name in the map
DownTrafficMap down_map
Map of lower layers.
virtual Packet * getFromBuffer(int traffic)
get a packet of a certain type from the buffer and return it
virtual Packet * removeFromBuffer(int traffic)
remove a packet of a certain type from the buffer and return it
virtual void recv(Packet *p)
recv method.
virtual void insertInBuffer(Packet *p, int traffic)
insert a packet of a certain type in the buffer
Class that represents the binding with the tcl configuration script.
UwMultiTrafficRangeCtrClass()
Constructor of the class.
TclObject * create(int, const char *const *)
Creates the TCL object needed for the tcl language interpretation.
int const max_increment
max increment of the timeout
virtual void expire(Event *e)
Timer expire procedure: handles the PROBE timeout.
Class used to represents the UwMultiTrafficRangeCtr layer of a node.
virtual void manageCheckedLayer(int module_id, uint8_t destAdd, bool in_range, int idSrc=0)
procedure when a CHECKED stack is checked
virtual void manageBuffer(int traffic)
manage to tx a packet of traffic type
CounterMap rx_probe_ack_cnt
Number of probe ACK pkts recv for each traffic.
StatusMap status
Map of status per traffic types.
virtual void recv(Packet *p, int idSrc)
Handle a packet coming from upper layers.
CounterMap tx_probe_cnt
Number of probe pkts sent for each traffic.
void incrSignalingCounter(int traffic, CounterMap &map_cnt)
Incement number of signaling pkts sent for the given traffic.
virtual int command(int, const char *const *)
TCL command interpreter.
virtual void initStatus(int traffic)
default status initialization
CounterMap tx_probe_ack_cnt
Number of probe ACK pkts sent for each traffic.
int signaling_pktSize
Signaling packet size.
double check_to_period
Time-Out period.
uint getSignalingCounter(int traffic, const CounterMap &map_cnt) const
Return the number of signaling pkts sent for the given traffic.
UwMultiTrafficRangeCtr()
Constructor of UwMultiPhy class.
std::map< int, UwCheckRangeTimer * > timers
Map of timer per traffic types.
virtual void checkRange(int traffic, int module_id, uint8_t destAdd=UWIP_BROADCAST)
procedure to check if a
virtual void sendDown(Packet *p, double delay=0)
Send a packet to the module(s) of the bottom layers.
virtual void timerExpired(int traffic)
handle when a a timer expires
CounterMap rx_probe_cnt
Number of probe pkts recv for each traffic.
virtual int getBestLowerLayer(int traffic, Packet *p=NULL)
return the Best Lower Layer id where to forward the packet of traffic type
std::set< int > module_ids
hdr_uwcbr describes UWCBR packets.
char & priority()
Reference to the priority_ variable.
hdr_uwip describes UWIP packets.
Definition uwip-module.h:70
uint8_t & daddr()
Reference to the daddr_ variable.
uint8_t & saddr()
Reference to the saddr_ variable.
Definition uwip-module.h:95
traffic, counter
int & traffic()
Reference to the traffic ID.
Provides the UWCBR packets header description and the definition of the class UWCBR.
#define HDR_UWCBR(p)
Cross layer messages definition for the UWIP Module.
static const uint8_t UWIP_BROADCAST
Variable used to represent a broadcast UWIP.
Definition uwip-module.h:62
#define HDR_UWIP(P)
Definition uwip-module.h:58
std::map< int, BehaviorItem > BehaviorMap
stack_id, behavior>
UwMultiTrafficRangeCtrClass class_tr_range_control
#define HDR_UWMTR(P)
std::map< int, uint > CounterMap
traffic, status