DESERT 3.5.1
Loading...
Searching...
No Matches
uwinterference.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2017 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//
29
39#include "uwinterference.h"
40
41#include <mphy.h>
42#include <mac.h>
43#include <iostream>
44
45#define POWER_PRECISION_THRESHOLD (1e-14)
46#define EPSILON_TIME 0.000000000001
47
48static class Interf_Overlap_Class : public TclClass
49{
50public:
52 : TclClass("Module/UW/INTERFERENCE")
53 {
54 }
55
56 TclObject *
57 create(int, const char *const *)
58 {
59 return (new uwinterference);
60 }
62
63void
65{
66
69 delete ee;
70}
71
73 : power_list()
74 , end_timer(this)
75 , use_maxinterval_(1)
76 , initial_interference_time(0)
77 , start_rx_time(0)
78 , end_rx_time(0)
79{
80 bind("use_maxinterval_", &use_maxinterval_);
81}
82
86
87void
89{
90 hdr_MPhy *ph = HDR_MPHY(p);
91 hdr_mac *mach = HDR_MAC(p);
92 if (mach->ftype() == MF_CONTROL) {
93 addToInterference(ph->Pr, CTRL);
94 EndInterfEvent *ee = new EndInterfEvent(ph->Pr, CTRL);
95 // EPSILON_TIME needed to avoid the scheduling of simultaneous events
96 Scheduler::instance().schedule(
97 &end_timer, ee, ph->duration - EPSILON_TIME);
98 } else {
99 addToInterference(ph->Pr, DATA);
100 EndInterfEvent *ee = new EndInterfEvent(ph->Pr, DATA);
101 // EPSILON_TIME needed to avoid the scheduling of simultaneous events
102 Scheduler::instance().schedule(
103 &end_timer, ee, ph->duration - EPSILON_TIME);
104 }
105}
106
107void
109{
110 if (use_maxinterval_) {
111 std::list<ListNode>::iterator it;
112 for (it = power_list.begin(); it != power_list.end();) {
113 if (it->time < NOW - maxinterval_) {
114 it = power_list.erase(it); // Side effect: it++
115 } else
116 break;
117 }
118 }
119
120 if (power_list.empty()) {
121 if (tp == CTRL) {
122 ListNode pn(NOW, pw, 1, 0);
123 power_list.push_back(pn);
124 } else {
125 ListNode pn(NOW, pw, 0, 1);
126 power_list.push_back(pn);
127 }
128 } else {
129 double power_temp = power_list.back().sum_power;
130 int ctrl_temp = power_list.back().ctrl_cnt;
131 int data_temp = power_list.back().data_cnt;
132 if (tp == CTRL) {
133 ListNode pn(NOW, pw + power_temp, ctrl_temp + 1, data_temp);
134 power_list.push_back(pn);
135 } else {
136 ListNode pn(NOW, pw + power_temp, ctrl_temp, data_temp + 1);
137 power_list.push_back(pn);
138 }
139 }
140
141 if (debug_) {
142 std::cout << NOW << " uwinterference::addToInterference, power: " << pw
143 << " ,total power: " << power_list.back().sum_power
144 << " ,ctrl_packet: " << power_list.back().ctrl_cnt
145 << " ,data packets: " << power_list.back().data_cnt
146 << std::endl;
147 }
148}
149
150void
152{
153 if (use_maxinterval_) {
154 std::list<ListNode>::iterator it;
155
156 for (it = power_list.begin(); it != power_list.end();) {
157 if (it->time < NOW - maxinterval_) {
158 it = power_list.erase(it); // Side effect: it++
159 } else
160 break;
161 }
162 }
163
164 if (power_list.empty()) {
165 std::cerr << "uwinterference::removeFromInterference, "
166 << "some interference removed wrongly" << std::endl;
167 return;
168 } else {
169 double power_temp = power_list.back().sum_power;
170 int ctrl_temp = power_list.back().ctrl_cnt;
171 int data_temp = power_list.back().data_cnt;
172
173 if (tp == CTRL) {
174 // NOW+EPSILON_TIME to compensate the early scheduling in
175 // addToInterference(Packet* p)
176 ListNode pn(NOW + EPSILON_TIME,
177 power_temp - pw,
178 ctrl_temp - 1,
179 data_temp);
180 power_list.push_back(pn);
181 } else {
182 // NOW+EPSILON_TIME to compensate the early scheduling in
183 // addToInterference(Packet* p)
184 ListNode pn(NOW + EPSILON_TIME,
185 power_temp - pw,
186 ctrl_temp,
187 data_temp - 1);
188 power_list.push_back(pn);
189 }
190 }
191 if (debug_) {
192 std::cout << NOW << " uwinterference::removeFromInterference, "
193 << "power: " << pw
194 << " ,total power: " << power_list.back().sum_power
195 << " ,ctrl_packet: " << power_list.back().ctrl_cnt
196 << " ,data packets: " << power_list.back().data_cnt
197 << std::endl;
198 }
199
200 double power_temp = power_list.back().sum_power;
201 if (power_temp < 0) {
202 if (debug_) {
203 std::cout << NOW
204 << " Precision error, negative power: " << power_temp
205 << std::endl;
206 }
207 power_list.back().sum_power = 0;
208 }
209}
210
211double
213{
214
215 hdr_MPhy *ph = HDR_MPHY(p);
216 double a = getTimeOverlap(p);
217 if (debug_) {
218 std::cout << NOW << " uwinterference::getInterferencePower, "
219 << "percentage of overlap: " << a << std::endl;
220 }
221 return (getInterferencePower(ph->Pr, ph->rxtime, ph->duration));
222}
223
224double
226 double power, double starttime, double duration)
227{
228 std::list<ListNode>::reverse_iterator rit;
229
230 double integral = 0;
231 double lasttime = NOW;
232 assert(starttime <= NOW);
233 assert(duration > 0);
234
235 for (rit = power_list.rbegin(); rit != power_list.rend(); ++rit) {
236 if (starttime < rit->time) {
237 integral += rit->sum_power * (lasttime - rit->time);
238 lasttime = rit->time;
239
240 } else {
241 integral += rit->sum_power * (lasttime - starttime);
242
243 break;
244 }
245 }
246 double interference = (integral / duration) - power;
247
248 if (abs(interference) < POWER_PRECISION_THRESHOLD) {
249 if (debug_)
250 std::cout << "getInterferencePower() WARNING:"
251 << " interference=" << interference
252 << " POWER_PRECISION_THRESHOLD="
254 << ". Precision error, interference set to 0"
255 << endl;
256 }
257 // Check for cancellation errors
258 // which can arise when interference is subtracted
259 if (interference < 0) {
260 interference = 0;
261 if (debug_)
262 std::cout << "getInterferencePower() WARNING:"
263 << " cancellation errors, interference set to 0"
264 << endl;
265 }
266
267 if (debug_) {
268 std::cout << "transmission from " << starttime << " to "
269 << starttime + duration << " power " << power
270 << " gets interference " << interference << std::endl;
271 }
272 return interference;
273}
274
275double
277{
278 if (power_list.empty())
279 return 0.0;
280 else
281 return (power_list.back().sum_power);
282}
283
284double
286{
287
288 hdr_MPhy *ph = HDR_MPHY(p);
289 return (getTimeOverlap(ph->rxtime, ph->duration));
290}
291
292double
293uwinterference::getTimeOverlap(double starttime, double duration)
294{
295 std::list<ListNode>::reverse_iterator rit;
296
297 double overlap = 0;
298 double lasttime = NOW;
299 assert(starttime <= NOW);
300 assert(duration > 0);
301
302 for (rit = power_list.rbegin(); rit != power_list.rend(); ++rit) {
303 if (starttime < rit->time) {
304
305 if (rit->ctrl_cnt > 1 || rit->data_cnt > 1) {
306 overlap += (lasttime - rit->time);
307 }
308 lasttime = rit->time;
309
310 } else {
311 if (rit->ctrl_cnt > 1 || rit->data_cnt > 1) {
312 overlap += (lasttime - starttime);
313 }
314 break;
315 }
316 }
317
318 return overlap / duration;
319}
320
323{
324 hdr_MPhy *ph = HDR_MPHY(p);
325 hdr_mac *mach = HDR_MAC(p);
326 counter cnt;
327 if (mach->ftype() == MF_CONTROL) {
328 cnt = getCounters(ph->rxtime, ph->duration, CTRL);
329 } else {
330 cnt = getCounters(ph->rxtime, ph->duration, DATA);
331 }
332 return cnt;
333}
334
336uwinterference::getCounters(double starttime, double duration, PKT_TYPE tp)
337{
338 std::list<ListNode>::reverse_iterator rit;
339
340 int ctrl_pkts = 0;
341 int data_pkts = 0;
342
343 assert(starttime <= NOW);
344 assert(duration > 0);
345
346 rit = power_list.rbegin();
347 int last_ctrl_cnt = rit->ctrl_cnt;
348 int last_data_cnt = rit->data_cnt;
349 rit++;
350 for (; rit != power_list.rend(); ++rit) {
351 if (starttime < rit->time) {
352 if (last_ctrl_cnt - rit->ctrl_cnt >= 0) {
353 ctrl_pkts += last_ctrl_cnt - rit->ctrl_cnt;
354 }
355 if (last_data_cnt - rit->data_cnt >= 0) {
356 data_pkts += last_data_cnt - rit->data_cnt;
357 }
358 last_ctrl_cnt = rit->ctrl_cnt;
359 last_data_cnt = rit->data_cnt;
360 } else {
361 ctrl_pkts += rit->ctrl_cnt;
362 data_pkts += rit->data_cnt;
363 break;
364 }
365 }
366
367 if (tp == CTRL) {
368 ctrl_pkts--;
369 } else {
370 data_pkts--;
371 }
372
373 if (debug_) {
374 std::cout << NOW << " uwinterference::getCounters(), collisions"
375 << " with ctrl pkts: " << ctrl_pkts
376 << ", collisions with data pkts: " << data_pkts << std::endl;
377 }
378
379 return counter(ctrl_pkts, data_pkts);
380}
virtual void handle(Event *e)
uwinterference * interference
TclObject * create(int, const char *const *)
virtual counter getCounters(Packet *p)
Returns the counters of collisions.
virtual void addToInterference(Packet *p)
Add a packet to the interference calculation.
EndInterfTimer end_timer
Timer for schedules end of interference for a transmission.
virtual double getTimeOverlap(Packet *p)
Returns the percentage of overlap between current packet and interference packets.
virtual double getCurrentTotalPower()
double use_maxinterval_
set to 1 to use maxinterval_.
virtual double getInterferencePower(Packet *p)
Compute the average interference power for the given packet.
virtual void removeFromInterference(double pw, PKT_TYPE tp)
Remove a packet to the interference calculation.
std::list< ListNode > power_list
List with power and counters.
virtual ~uwinterference()
Destructor of the class uwinterference.
uwinterference()
Constructor of the class uwinterference.
#define POWER_PRECISION_THRESHOLD
#define EPSILON_TIME
Interf_Overlap_Class class_interf_overlap
Implementation of uwinterference class.
std::pair< int, int > counter
counter of collisions
PKT_TYPE
@ CTRL
@ DATA