DESERT 3.5.1
Loading...
Searching...
No Matches
uwmulti-traffic-control.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 <clmsg-discovery.h>
40#include <uwcbr-module.h>
41#include <iostream>
42
46static class UwMultiTrafficControlClass : public TclClass
47{
48public:
52 UwMultiTrafficControlClass() : TclClass("Module/UW/MULTI_TRAFFIC_CONTROL") {}
57 TclObject* create(int, const char*const*)
58 {
59 return (new UwMultiTrafficControl);
60 }
62
64:
65 Module(),
66 debug_(0),
67 up_map(),
68 down_map(),
69 down_buffer(),
70 buffer_feature_map()
71{
72 bind("debug_", &debug_);
73}
74
75int UwMultiTrafficControl::command(int argc, const char*const* argv)
76{
77 Tcl &tcl = Tcl::instance();
78 if (argc == 3)
79 {
80 if(strcasecmp(argv[1], "getDiscardedPacket") == 0)
81 {
82 tcl.resultf("%d", getDiscardedPacket(atoi(argv[2])));
83 return TCL_OK;
84 }
85 }
86 else if (argc == 4)
87 {
88 if(strcasecmp(argv[1], "addUpLayer") == 0)
89 {
90 addUpLayerFromTag(atoi(argv[2]),argv[3]);
91 return TCL_OK;
92 }
93 else if(strcasecmp(argv[1], "addLowLayer") == 0)
94 {
95 addLowLayerFromTag(atoi(argv[2]),argv[3],DEFAULT);
96 return TCL_OK;
97 }
98 }
99 else if (argc == 5)
100 {
101 if(strcasecmp(argv[1], "addLowLayer") == 0)
102 {
103 addLowLayerFromTag(atoi(argv[2]),argv[3],atoi(argv[4]));
104 return TCL_OK;
105 }
106 else if (strcasecmp(argv[1], "setBufferFeatures") == 0)
107 {
108 setBufferFeature(atoi(argv[2]),atoi(argv[3]),atoi(argv[4]));
109 return TCL_OK;
110 }
111 }
112 else if (argc == 6)
113 {
114 if (strcasecmp(argv[1], "setBufferFeatures") == 0)
115 {
116 setBufferFeature(atoi(argv[2]),atoi(argv[3]),atoi(argv[4]),atof(argv[5]));
117 return TCL_OK;
118 }
119 }
120
121 return Module::command(argc, argv);
122} /* UwMultiTrafficControl::command */
123
124void UwMultiTrafficControl::addUpLayerFromTag(int traffic_id, std::string tag) {
125 ClMsgDiscovery m;
126 m.addSenderData((const PlugIn*) this, getLayer(), getId(), getStackId(), name() , getTag());
127 sendSyncClMsgUp(&m);
128 DiscoveryStorage up_layer_storage = m.findTag(tag.c_str());
129 if (debug_)
130 std::cout << "UwMultiTrafficControl::addUpLayerFromTag(" << traffic_id << "," << tag << ")"
131 << up_layer_storage.getSize() << std::endl;
132 if (up_layer_storage.getSize() == 1)
133 {
134 if (debug_)
135 std::cout << "UwMultiTrafficControl::addUpLayerFromTag(" << traffic_id << "," << tag << ")" <<
136 (*up_layer_storage.begin()).first << std::endl;
137 insertTraffic2UpLayer(traffic_id,(*up_layer_storage.begin()).first);
138 }
139}
140
141void UwMultiTrafficControl::addLowLayerFromTag(int traffic_id, std::string tag, int behavior) {
142 ClMsgDiscovery m;
143 m.addSenderData((const PlugIn*) this, getLayer(), getId(), getStackId(), name() , getTag());
144 sendSyncClMsgDown(&m);
145 DiscoveryStorage low_layer_storage = m.findTag(tag.c_str());
146 DiscoveryData low_layer = (*low_layer_storage.begin()).second;
147 if (debug_)
148 std::cout << NOW << "UwMultiTrafficControl::addLowLayerFromTag(" << traffic_id << ","
149 << tag << ") disc size " << low_layer_storage.getSize() << endl;
150 if (low_layer_storage.getSize() == 1)
151 {
152 if (debug_)
153 std::cout << NOW << "UwMultiTrafficControl::addLowLayerFromTag(" << traffic_id << ","
154 << tag << ") disc data tr = "<< traffic_id << " m_id = " << low_layer.getId()
155 << " st_id = " << low_layer.getStackId() << " " << behavior << std::endl;
156 insertTraffic2LowerLayer(traffic_id,low_layer.getStackId(),low_layer.getId(),behavior);
157 }
158}
159
161{
162 hdr_cmn *ch = HDR_CMN(p);
163 if(ch->direction() == hdr_cmn::UP)
164 {
165 hdr_uwcbr *ah = HDR_UWCBR(p);
166 int traf_type = ah->traffic_type();
167 if(debug_)
168 std::cout << NOW << " UwMultiTrafficControl::recv type = " << traf_type <<std::endl;
169 sendUp(getUpperLayer(traf_type), p);
170 }
171 else //direction DOWN: packet is coming from upper layers
172 {
174 }
175}
176
178{
179 hdr_cmn *ch = HDR_CMN(p);
180 assert(ch->direction() == hdr_cmn::DOWN);
181
182 hdr_uwcbr *ah = HDR_UWCBR(p);
183 int traf_type = ah->traffic_type();
184 if(debug_)
185 std::cout << NOW << " UwMultiTrafficControl::recvFromUpperLayers" << std::endl;
186 insertInBuffer(p,traf_type);
187 manageBuffer(traf_type);
188}
189
190void UwMultiTrafficControl::insertInBuffer(Packet *p, int traffic)
191{
192 BufferTrafficFeature::iterator it_feat = buffer_feature_map.find(traffic);
193 if (it_feat == buffer_feature_map.end()) {
194 std::cout << "UwMultiTrafficControl::insertInBuffer. ERROR. Buffer not "
195 << "configured. Traffic " << traffic << std::endl;
196 Packet::free(p);
197 return;
198 }
199
200 DownTrafficBuffer::iterator it = down_buffer.find(traffic);
201 if (it != down_buffer.end()) {
202 uint n_elem = it->second->size();
203 if (n_elem < it_feat->second.max_size) {
204 it->second->push(p);
205 if(debug_)
206 std::cout << NOW <<" UwMultiTrafficControl::insertInBuffer, traffic = "
207 << traffic << ", buffer size =" << it->second->size()
208 << std::endl;
209 } else {
210 incrPktLoss(traffic);
211 if (it_feat->second.behavior_buff == BufferType::CIRCULAR) { //circular buffer
212 if (debug_)
213 std::cout << NOW << "UwMultiTrafficControl::insertInBuffer, traffic = "
214 << traffic << ", circular buffer full. Discard first element"
215 << std::endl;
216 it->second->pop();
217 it->second->push(p);
218 } else {
219 if (debug_)
220 std::cout << NOW << "UwMultiTrafficControl::insertInBuffer, traffic = "
221 << traffic << ", buffer full. Discard incoming packet "
222 << std::endl;
223 Packet::free(p);
224 }
225 }
226 }
227 else {
228 std::queue<Packet*> *q = new std::queue<Packet*>;
229 q->push(p);
230 down_buffer[traffic] = q;
231 if(debug_)
232 std::cout << NOW <<" UwMultiTrafficControl::insertInBuffer, traffic = "
233 << traffic << ", buffer size =" << 1 << std::endl;
234 }
235}
236
238{
239 BufferTrafficFeature::iterator it_feat = buffer_feature_map.find(traffic);
240 if (it_feat == buffer_feature_map.end()) {
241 std::cout << "UwMultiTrafficControl::insertInBuffer. ERROR. Buffer not "
242 << "configured. Traffic " << traffic << std::endl;
243 return;
244 }
245 DownTrafficBuffer::iterator it = down_buffer.find(traffic);
246 if (it != down_buffer.end()) {
247 sendDown(getBestLowerLayer(traffic),removeFromBuffer(traffic),
248 it_feat->second.getUpdatedDelay(NOW));
249 if(debug_)
250 std::cout << NOW << "UwMultiTrafficControl::manageBuffer(" << traffic << ")" << std::endl;
251 }
252}
253
255{
256 Packet * p = NULL;
257 DownTrafficBuffer::iterator it = down_buffer.find(traffic);
258 if (it != down_buffer.end() && ! it->second->empty()) {
259 p = it->second->front();
260 it->second->pop();
261 if (debug_)
262 std::cout << NOW << " UwMultiTrafficControl::removeFromBuffer(" << traffic
263 << "), packet in buffer = " << it->second->size() << std::endl;
264 }
265 return p;
266}
267
269{
270 Packet * p = NULL;
271 DownTrafficBuffer::iterator it = down_buffer.find(traffic);
272 if (it != down_buffer.end() && ! it->second->empty()) {
273 if (debug_)
274 std::cout << NOW << " UwMultiTrafficControl::getFromBuffer(" << traffic
275 << "), packet in buffer = " << it->second->size() << std::endl;
276 p = it->second->front();
277 }
278 return p;
279}
280
282{
283 DownTrafficMap::iterator it = down_map.find(traffic);
284 if (it != down_map.end()) {
285 BehaviorMap temp = it->second;
286 BehaviorMap::iterator it_b = temp.begin();
287 for (; it_b!=temp.end(); ++it_b)
288 {
289 if (it_b->second.second == DEFAULT)
290 {
291 if (debug_)
292 std::cout << NOW << " UwMultiTrafficControl::getBestLowerLayer("
293 << traffic << "), id = "
294 << it_b->second.first << std::endl;
295 return it_b->second.first;
296 }
297 }
298 }
299 return 0;
300}
301
303{
304 UpTrafficMap::iterator it = up_map.find(traffic);
305 if (it != up_map.end()) {
306 if(debug_)
307 std::cout << NOW << " UwMultiTrafficControl::getUpperLayer(" <<traffic<<") = "
308 << it->second << std::endl;
309 return it->second;
310 }
311 return 0;
312}
313
314void UwMultiTrafficControl::eraseTraffic2LowerLayer(int traffic, int lower_layer_stack)
315{
316 DownTrafficMap::iterator it = down_map.find(traffic);
317 if (it != down_map.end()) {
318 BehaviorMap behav = it->second;
319 BehaviorMap::iterator it_layer = behav.find(lower_layer_stack);
320 if(it_layer != behav.end())
321 behav.erase(lower_layer_stack);
322 if(behav.size() == 0)
323 down_map.erase(traffic);
324 }
325}
326
328{
329 UpTrafficMap::iterator it = up_map.find(traffic);
330 if (it != up_map.end()) {
331 up_map.erase(traffic);
332 }
333}
334
336{
337 UpTrafficMap::iterator it = up_map.find(traffic);
338 if (it != up_map.end()) {
339 up_map.erase(traffic);
340 }
341}
342
343void UwMultiTrafficControl::setBufferFeature(int traffic_id, int max_size,
344 bool is_circular, double send_down_delay)
345{
348 BufferType buff_type = BufferType(max_size, behav, send_down_delay);
349 buffer_feature_map.insert(std::make_pair(traffic_id, buff_type));
350
351 if (debug_)
352 std::cout << "Inserted buffer features for traffic " << traffic_id
353 << " with max size " << max_size << " Is circular "
354 << is_circular << std::endl;
355}
356
358{
359 BufferTrafficFeature::iterator it = buffer_feature_map.find(traffic_id);
360 if (it != buffer_feature_map.end()) {
361 it->second.pkts_lost++;
362 } else {
363 std::cout << "UwMultiTrafficControl::incrPktLoss. ERROR. Buffer not "
364 << "configured. Traffic " << traffic_id << std::endl;
365 return;
366 }
367}
368
370{
371 BufferTrafficFeature::const_iterator it = buffer_feature_map.find(traffic_id);
372 if (it == buffer_feature_map.end()) {
373 std::cout << "UwMultiTrafficControl::incrPktLoss. ERROR. Buffer not "
374 << "configured. Traffic " << traffic_id << std::endl;
375 return 0;
376 } else {
377 return it->second.pkts_lost;
378 }
379}
Class that represents the binding with the tcl configuration script.
TclObject * create(int, const char *const *)
Creates the TCL object needed for the tcl language interpretation.
UwMultiTrafficControlClass()
Constructor of the class.
Class used to represents the UwMultiTrafficControl layer of a node.
BufferTrafficFeature buffer_feature_map
Map with features of each buffer.
DownTrafficBuffer down_buffer
Map of buffer per traffic types.
virtual void recvFromUpperLayers(Packet *p)
Handle a packet coming from upper layers.
void setBufferFeature(int traffic_id, int max_size, bool is_circular, double send_down_delay=0)
set buffer features for the given traffic type
virtual int command(int, const char *const *)
TCL command interpreter.
UwMultiTrafficControl()
Constructor of UwMultiPhy class.
virtual int getUpperLayer(int traffic)
return the Upper Layer id where to forward the received packet of traffic type
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
virtual void manageBuffer(int traffic)
manage to tx a packet of traffic type
DownTrafficMap down_map
Map of lower layers.
virtual int getBestLowerLayer(int traffic, Packet *p=NULL)
return the Best Lower Layer id where to forward the packet of traffic type
UpTrafficMap up_map
Map of upper 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 eraseTraffic2Low(int traffic)
remove the traffic from the lower layers matrix
virtual void recv(Packet *p)
recv method.
virtual void addUpLayerFromTag(int traffic_id, std::string tag)
add an upper layer from the tag name in the map
virtual void eraseTraffic2LowerLayer(int traffic, int lower_layer_stack)
remove the behavior from the traffic lower layers matrix
virtual void incrPktLoss(int traffic_id)
Increment by 1 the number of lost packets for the given traffic.
virtual uint getDiscardedPacket(int traffic_id) const
get discarded packets
virtual void eraseTraffic2Up(int traffic)
remove the traffic from the upper layers matrix
void insertTraffic2UpLayer(int traffic, int upper_layer_id)
Set to which upper layer forward a specific kind of traffic received from the lower layers.
void insertTraffic2LowerLayer(int traffic, int lower_layer_stack, int lower_layer_id, int behavior)
Set to which upper layer forward a specific kind of traffic received from the lower layers.
virtual void insertInBuffer(Packet *p, int traffic)
insert a packet of a certain type in the buffer
hdr_uwcbr describes UWCBR packets.
uint16_t & traffic_type()
Reference to the rftt_ variable.
Provides the UWCBR packets header description and the definition of the class UWCBR.
#define HDR_UWCBR(p)
UwMultiTrafficControlClass class_traffic_control
#define DEFAULT
std::map< int, BehaviorItem > BehaviorMap
stack_id, behavior>
const double q