DESERT 3.5.1
Loading...
Searching...
No Matches
uwinterferenceofdm.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 "uwinterferenceofdm.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_FOverlap_Class : public TclClass
49{
50public:
52 : TclClass("Module/UW/INTERFERENCEOFDM")
53 {
54 }
55
56 TclObject *
57 create(int, const char *const *)
58 {
59 return (new uwinterferenceofdm);
60 }
62
64{
65
68 delete ee;
69}
70
72 : uwinterference(), end_timerOFDM(this)
73{
74 bind("use_maxinterval_", &use_maxinterval_);
75 bind("inodeID_", (int *)&inodeID);
76}
77
81
82int uwinterferenceofdm::command(int argc, const char *const *argv)
83{
84 Tcl &tcl = Tcl::instance();
85 if (argc == 2)
86 {
87 if (strcasecmp(argv[1], "getInterfCarriers") == 0)
88 {
89 tcl.resultf("%d", getInterfCarriers());
90 return TCL_OK;
91 }
92 }
93 if (argc == 3)
94 {
95 if (strcasecmp(argv[1], "setInterfCarriers") == 0)
96 {
97 setInterfCarriers(atoi(argv[2]));
98 return TCL_OK;
99 }
100 }
101 return uwinterferenceofdm::command(argc, argv);
102}
103
105{
106 hdr_MPhy *ph = HDR_MPHY(p);
107 hdr_mac *mach = HDR_MAC(p);
108 hdr_OFDM *ofdmph = HDR_OFDM(p);
109 std::vector<double> car_power;
110 int used_carriers = 0;
111
112 // Check how many carriers are effectively used
113 for (int i = 0; i < ofdmph->carrierNum; i++)
114 {
115 used_carriers += ofdmph->carriers[i];
116 }
117
118 // For each used carrier fill with associated power
119 for (int i = 0; i < ofdmph->carrierNum; i++)
120 {
121 car_power.push_back(ph->Pr / used_carriers * ofdmph->carriers[i]);
122 }
123 bool ctrl_pkt = (mach->ftype() == MF_CTS || mach->ftype() == MF_RTS || mach->ftype() == MF_ACK );
124
125 if (ctrl_pkt) {
126
127 if (debug_)
128 std::cout << NOW << " uwinterference::addToInterference() CTRL packet" << std::endl;
129 addToInterference(ph->Pr, CTRL, ofdmph->carriers, ofdmph->carrierNum);
130 EndInterfEvent *ee = new EndInterfEvent(ph->Pr, CTRL, car_power);
131 // EPSILON_TIME needed to avoid the scheduling of simultaneous events
132 Scheduler::instance().schedule(
133 &end_timerOFDM, ee, ph->duration - EPSILON_TIME);
134
135 } else {
136
137 if (debug_)
138 std::cout << NOW << " uwinterference::addToInterference() DATA packet" << std::endl;
139 addToInterference(ph->Pr, DATA, ofdmph->carriers, ofdmph->carrierNum);
140 EndInterfEvent *ee = new EndInterfEvent(ph->Pr, DATA, car_power);
141 // EPSILON_TIME needed to avoid the scheduling of simultaneous events
142 Scheduler::instance().schedule(
143 &end_timerOFDM, ee, ph->duration - EPSILON_TIME);
144 }
145}
146
147void uwinterferenceofdm::addToInterference(double pw, PKT_TYPE tp, int *carriers, int carNum)
148{
149 std::vector<double> car_power;
150 int used_carriers = 0;
151
152 // Check how many carriers are effectively used
153 for (int i = 0; i < carNum; i++)
154 {
155 used_carriers += carriers[i];
156 }
157
158 // For each used carrier fill with associated power
159 for (int i = 0; i < carNum; i++)
160 {
161 car_power.push_back(pw / used_carriers * carriers[i]);
162 }
163
164 if (use_maxinterval_) {
165
166 std::list<ListNodeOFDM>::iterator it;
167 for (it = power_list.begin(); it != power_list.end();)
168 {
169 if (it->time < NOW - maxinterval_) {
170 it = power_list.erase(it); // Side effect: it++
171 } else
172 break;
173 }
174 }
175
176 if (power_list.empty()) {
177
178 if (tp == CTRL) {
179 ListNodeOFDM pn(NOW, pw, 1, 0, car_power);
180 power_list.push_back(pn);
181 } else {
182 ListNodeOFDM pn(NOW, pw, 0, 1, car_power);
183 power_list.push_back(pn);
184 }
185 } else {
186
187 double power_temp = power_list.back().sum_power;
188 int ctrl_temp = power_list.back().ctrl_cnt;
189 int data_temp = power_list.back().data_cnt;
190 std::vector<double> car_pwr_old = power_list.back().carrier_power;
191
192 string carPwr = "CarrierPower_Vector = [";
193
194 for (int i = 0; i < car_pwr_old.size(); i++)
195 {
196 car_power.at(i) += car_pwr_old.at(i);
197 carPwr += (std::to_string(car_power.at(i)) + ", ");
198 }
199 carPwr += "]";
200
201 if (debug_)
202 std::cout << NOW << " uwinterference::addToInterference() " << carPwr << std::endl;
203
204 if (tp == CTRL)
205 {
206 ListNodeOFDM pn(NOW, pw + power_temp, ctrl_temp + 1, data_temp, car_power);
207 power_list.push_back(pn);
208 } else {
209 ListNodeOFDM pn(NOW, pw + power_temp, ctrl_temp, data_temp + 1, car_power);
210 power_list.push_back(pn);
211 }
212 }
213
214 if (debug_)
215 {
216 std::cout << NOW << " uwinterference::addToInterference, power: " << pw
217 << " ,total power: " << power_list.back().sum_power
218 << " ,ctrl_packet: " << power_list.back().ctrl_cnt
219 << " ,data packets: " << power_list.back().data_cnt
220 << std::endl;
221 }
222}
223
224void uwinterferenceofdm::removeFromInterference(double pw, PKT_TYPE tp, const std::vector<double> &carPwr)
225{
226 if (use_maxinterval_) {
227 std::list<ListNodeOFDM>::iterator it;
228
229 for (it = power_list.begin(); it != power_list.end();)
230 {
231 if (it->time < NOW - maxinterval_) {
232 it = power_list.erase(it); // Side effect: it++
233 }
234 else
235 break;
236 }
237 }
238
239 if (power_list.empty()) {
240
241 std::cerr << "uwinterference::removeFromInterference, "
242 << "some interference removed wrongly" << std::endl;
243 return;
244 } else {
245 double power_temp = power_list.back().sum_power;
246 int ctrl_temp = power_list.back().ctrl_cnt;
247 int data_temp = power_list.back().data_cnt;
248 std::vector<double> car_pwr_old = power_list.back().carrier_power;
249 std::vector<double> car_pwr_new;
250 for (std::size_t i = 0; i < car_pwr_old.size(); ++i)
251 {
252 double tempPwr = car_pwr_old[i] - carPwr[i];
253 if (tempPwr < 0)
254 {
255 if (tempPwr < -0.001)
256 cerr << NOW << " NODE " << inodeID << " REMOVE FROM INTERFERENCE !!! result < 0 ("
257 << tempPwr << ") car " << i << std::endl;
258 tempPwr = 0;
259 }
260 car_pwr_new.push_back(tempPwr);
261 }
262
263 if (tp == CTRL) {
264 // NOW+EPSILON_TIME to compensate the early scheduling in
265 // addToInterference(Packet* p)
266 ListNodeOFDM pn(NOW + EPSILON_TIME,
267 power_temp - pw,
268 ctrl_temp - 1,
269 data_temp, car_pwr_new);
270 power_list.push_back(pn);
271 } else {
272
273 // NOW+EPSILON_TIME to compensate the early scheduling in
274 // addToInterference(Packet* p)
275 ListNodeOFDM pn(NOW + EPSILON_TIME,
276 power_temp - pw,
277 ctrl_temp,
278 data_temp - 1, car_pwr_new);
279 power_list.push_back(pn);
280 }
281 }
282 if (debug_) {
283 std::cout << NOW << " uwinterference::removeFromInterference, "
284 << "power: " << pw
285 << " ,total power: " << power_list.back().sum_power
286 << " ,ctrl_packet: " << power_list.back().ctrl_cnt
287 << " ,data packets: " << power_list.back().data_cnt
288 << std::endl;
289 }
290
291 double power_temp = power_list.back().sum_power;
292
293 if (power_temp < -0.001) {
294 if (debug_)
295 std::cout << NOW << " NODE " << inodeID << " Precision error, negative power: " << power_temp
296 << std::endl;
297 if (power_temp < -1)
298 cerr << NOW << " NODE " << inodeID << " Precision ERROR, negative power: " << power_temp
299 << std::endl;
300
301 power_list.back().sum_power = 0;
302 }
303}
304
305double
307{
308
309 hdr_MPhy *ph = HDR_MPHY(p);
310 hdr_OFDM *ofdmph = HDR_OFDM(p);
311
312 return (getInterferencePower(ph->Pr, ph->rxtime, ph->duration, ofdmph->carriers, ofdmph->carrierNum));
313}
314
315double
317 double power, double starttime, double duration, int *carriers, int ncarriers)
318{
319 std::list<ListNodeOFDM>::reverse_iterator rit;
320
321 std::vector<double> car_pwr;
322
323 double integral = 0;
324 double car_integral = 0;
325 double car_power = 0;
326 double lasttime = NOW;
327 assert(starttime <= NOW);
328 assert(duration > 0);
329
330 for (rit = power_list.rbegin(); rit != power_list.rend(); ++rit)
331 {
332 car_power = 0;
333 if (starttime < rit->time)
334 {
335 integral += rit->sum_power * (lasttime - rit->time);
336
337 // for each carrier add interf pwr if carrier is used
338 for (int i = 0; i < rit->carrier_power.size(); i++)
339 {
340 car_power += carriers[i] * rit->carrier_power.at(i);
341 }
342
343 car_integral += car_power * (lasttime - rit->time);
344 lasttime = rit->time;
345 } else {
346
347 integral += rit->sum_power * (lasttime - starttime);
348 for (int i = 0; i < rit->carrier_power.size(); i++)
349 {
350 car_power += carriers[i] * rit->carrier_power.at(i);
351 }
352 car_integral += car_power * (lasttime - starttime);
353 break;
354 }
355 }
356 double interference = (integral / duration) - power;
357 double ofdminterference = (car_integral / duration) - power;
358 if(interference < (ofdminterference - 1))
359 std::cerr << "PROBLEM interference VS OFDM interference " << interference << " - " << ofdminterference << std::endl;
360
361 if (abs(interference) < POWER_PRECISION_THRESHOLD)
362 {
363 if (debug_)
364 std::cout << "getInterferencePower() WARNING:"
365 << " interference=" << interference
366 << " POWER_PRECISION_THRESHOLD="
368 << ". Precision error, interference set to 0"
369 << endl;
370 }
371 // Check for cancellation errors
372 // which can arise when interference is subtracted
373 if (interference < 0) {
374 if (debug_)
375 std::cout << "getInterferencePower() WARNING:"
376 << " cancellation errors, interference set to 0"
377 << " previous value " << interference << endl;
378 interference = 0;
379 }
380
381 if (debug_) {
382 std::cout << "transmission from " << starttime << " to "
383 << starttime + duration << " power " << power
384 << " gets interference " << interference << std::endl;
385 }
386 if (ofdminterference < 0) {
387 if (debug_)
388 std::cout << "getInterferencePower() WARNING:"
389 << " cancellation errors, ofdminterference set to 0 "
390 << "previous value " << ofdminterference << endl;
391
392 ofdminterference = 0;
393 }
394 return ofdminterference;
395}
396
397double
399{
400 if (power_list.empty())
401 return 0.0;
402 else
403 return (power_list.back().sum_power);
404}
405
406double
408{
409 if (power_list.empty())
410 return 0.0;
411 else
412 return (power_list.back().carrier_power.at(carrier));
413}
414
415double
417{
418
419 hdr_MPhy *ph = HDR_MPHY(p);
420 return (getTimeOverlap(ph->rxtime, ph->duration));
421}
422
423double
424uwinterferenceofdm::getTimeOverlap(double starttime, double duration)
425{
426 std::list<ListNodeOFDM>::reverse_iterator rit;
427
428 double overlap = 0;
429 double lasttime = NOW;
430 assert(starttime <= NOW);
431 assert(duration > 0);
432
433 for (rit = power_list.rbegin(); rit != power_list.rend(); ++rit)
434 {
435 if (starttime < rit->time) {
436
437 if (rit->ctrl_cnt > 1 || rit->data_cnt > 1) {
438 overlap += (lasttime - rit->time);
439 }
440 lasttime = rit->time;
441 } else {
442 if (rit->ctrl_cnt > 1 || rit->data_cnt > 1) {
443 overlap += (lasttime - starttime);
444 }
445 break;
446 }
447 }
448 return overlap / duration;
449}
450
453{
454 hdr_MPhy *ph = HDR_MPHY(p);
455 hdr_mac *mach = HDR_MAC(p);
456 counter cnt;
457 if (mach->ftype() == MF_CONTROL) {
458 cnt = getCounters(ph->rxtime, ph->duration, CTRL);
459 } else {
460 cnt = getCounters(ph->rxtime, ph->duration, DATA);
461 }
462 return cnt;
463}
464
466uwinterferenceofdm::getCounters(double starttime, double duration, PKT_TYPE tp)
467{
468 std::list<ListNodeOFDM>::reverse_iterator rit;
469
470 int ctrl_pkts = 0;
471 int data_pkts = 0;
472
473 assert(starttime <= NOW);
474 assert(duration > 0);
475
476 rit = power_list.rbegin();
477 int last_ctrl_cnt = rit->ctrl_cnt;
478 int last_data_cnt = rit->data_cnt;
479 rit++;
480 for (; rit != power_list.rend(); ++rit)
481 {
482 if (starttime < rit->time) {
483 if (last_ctrl_cnt - rit->ctrl_cnt >= 0) {
484 ctrl_pkts += last_ctrl_cnt - rit->ctrl_cnt;
485 }
486 if (last_data_cnt - rit->data_cnt >= 0) {
487 data_pkts += last_data_cnt - rit->data_cnt;
488 }
489 last_ctrl_cnt = rit->ctrl_cnt;
490 last_data_cnt = rit->data_cnt;
491 } else {
492 ctrl_pkts += rit->ctrl_cnt;
493 data_pkts += rit->data_cnt;
494 break;
495 }
496 }
497
498 if (tp == CTRL) {
499 ctrl_pkts--;
500 } else {
501 data_pkts--;
502 }
503
504 if (debug_) {
505 std::cout << NOW << " uwinterference::getCounters(), collisions"
506 << " with ctrl pkts: " << ctrl_pkts
507 << ", collisions with data pkts: " << data_pkts << std::endl;
508 }
509
510 return counter(ctrl_pkts, data_pkts);
511}
std::vector< double > carrier_power
uwinterferenceofdm * interference
virtual void handle(Event *e)
TclObject * create(int, const char *const *)
double use_maxinterval_
set to 1 to use maxinterval_.
virtual int command(int, const char *const *)
TCL command interpreter.
std::list< ListNodeOFDM > power_list
List with power and counters.
void setInterfCarriers(int sc)
Sets number of carriers used by the node.
virtual void removeFromInterference(double pw, PKT_TYPE tp, const std::vector< double > &carPwr)
Remove a packet to the interference calculation.
uwinterferenceofdm()
Constructor of the class uwinterference.
virtual ~uwinterferenceofdm()
Destructor of the class uwinterference.
virtual double getCurrentTotalPowerOnCarrier(int carrier)
Compute the total power on a carrier.
virtual counter getCounters(Packet *p)
Returns the counters of collisions.
EndInterfTimerOFDM end_timerOFDM
Timer for schedules end of interference for a transmission.
virtual void addToInterference(Packet *p)
Add a packet to the interference calculation.
virtual double getInterferencePower(Packet *p)
Compute the average interference power for the given packet.
virtual double getTimeOverlap(Packet *p)
Returns the percentage of overlap between current packet and interference packets.
virtual double getCurrentTotalPower()
Header of the OFDM message with fields to implement a multi carrier system.
int carriers[MAX_CARRIERS]
#define POWER_PRECISION_THRESHOLD
#define EPSILON_TIME
std::pair< int, int > counter
counter of collisions
PKT_TYPE
@ CTRL
@ DATA
Interf_FOverlap_Class class_interf_foverlap
Implementation of uwinterference class. Your can find the brief description of this module in the pap...
std::pair< int, int > counter
counter of collisions
#define HDR_OFDM(p)
alias defined to access the PROBE HEADER