DESERT 3.5.1
Loading...
Searching...
No Matches
uwcbr-module.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
40#include "uwcbr-module.h"
41
42#include <iostream>
43#include <rng.h>
44#include <stdint.h>
45#include <fstream>
46#include <cstdlib>
47
48extern packet_t PT_UWCBR;
49
56static class UwCbrPktClass : public PacketHeaderClass
57{
58public:
60 : PacketHeaderClass("PacketHeader/UWCBR", sizeof(hdr_uwcbr))
61 {
62 this->bind();
63 bind_offset(&hdr_uwcbr::offset_);
64 }
66
70static class UwCbrModuleClass : public TclClass
71{
72public:
74 : TclClass("Module/UW/CBR")
75 {
76 }
77
78 TclObject *
79 create(int, const char *const *)
80 {
81 return (new UwCbrModule());
82 }
84
85void
87{
88 module->transmit();
89}
90
92
94 : dstPort_(0)
95 , dstAddr_(0)
96 , priority_(0)
97 , PoissonTraffic_(0)
98 , debug_(0)
99 , drop_out_of_order_(0)
100 , traffic_type_(0)
101 , sendTmr_(this)
102 , txsn(1)
103 , hrsn(0)
104 , pkts_recv(0)
105 , pkts_ooseq(0)
106 , pkts_lost(0)
107 , pkts_invalid(0)
108 , pkts_last_reset(0)
109 , rftt(-1)
110 , srtt(0)
111 , sftt(0)
112 , lrtime(0)
113 , sthr(0)
114 , period_(0)
115 , pktSize_(0)
116 , sumrtt(0)
117 , sumrtt2(0)
118 , rttsamples(0)
119 , log_suffix("")
120 , sumftt(0)
121 , sumftt2(0)
122 , fttsamples(0)
123 , sumbytes(0)
124 , sumdt(0)
125 , esn(0)
126 , tracefile_enabler_(0)
127 , cnt(0)
128{ // binding to TCL variables
129 bind("period_", &period_);
130 bind("destPort_", (int *) &dstPort_);
131 bind("destAddr_", (int *) &dstAddr_);
132 bind("packetSize_", &pktSize_);
133 bind("PoissonTraffic_", &PoissonTraffic_);
134 bind("debug_", &debug_);
135 bind("drop_out_of_order_", &drop_out_of_order_);
136 bind("traffic_type_", (uint *) &traffic_type_);
137 bind("tracefile_enabler_", (int *) &tracefile_enabler_);
138 sn_check = new bool[USHRT_MAX];
139 for (int i = 0; i < USHRT_MAX; i++) {
140 sn_check[i] = false;
141 }
142}
143
144
146{
147 cout << "sdpaosdisaopdisp" << endl;
148}
149
150int
151UwCbrModule::command(int argc, const char *const *argv)
152{
153 Tcl &tcl = Tcl::instance();
154 if (argc == 2) {
155 if (strcasecmp(argv[1], "start") == 0) {
156 start();
157 return TCL_OK;
158 } else if (strcasecmp(argv[1], "stop") == 0) {
159 stop();
160 return TCL_OK;
161 } else if (strcasecmp(argv[1], "getrtt") == 0) {
162 tcl.resultf("%f", GetRTT());
163 return TCL_OK;
164 } else if (strcasecmp(argv[1], "getftt") == 0) {
165 tcl.resultf("%f", GetFTT());
166 return TCL_OK;
167 } else if (strcasecmp(argv[1], "gettxtime") == 0) {
168 tcl.resultf("%f", GetTxTime());
169 return TCL_OK;
170 } else if (strcasecmp(argv[1], "getper") == 0) {
171 tcl.resultf("%f", GetPER());
172 return TCL_OK;
173 } else if (strcasecmp(argv[1], "getthr") == 0) {
174 tcl.resultf("%f", GetTHR());
175 return TCL_OK;
176 } else if (strcasecmp(argv[1], "getcbrheadersize") == 0) {
177 tcl.resultf("%d", this->getCbrHeaderSize());
178 return TCL_OK;
179 } else if (strcasecmp(argv[1], "getrttstd") == 0) {
180 tcl.resultf("%f", GetRTTstd());
181 return TCL_OK;
182 } else if (strcasecmp(argv[1], "getfttstd") == 0) {
183 tcl.resultf("%f", GetFTTstd());
184 return TCL_OK;
185 } else if (strcasecmp(argv[1], "getsentpkts") == 0) {
186 tcl.resultf("%d", txsn - 1);
187 return TCL_OK;
188 } else if (strcasecmp(argv[1], "getrecvpkts") == 0) {
189 tcl.resultf("%d", pkts_recv);
190 return TCL_OK;
191 } else if (strcasecmp(argv[1], "setprioritylow") == 0) {
192 priority_ = 0;
193 return TCL_OK;
194 } else if (strcasecmp(argv[1], "setpriorityhigh") == 0) {
195 priority_ = 1;
196 return TCL_OK;
197 } else if (strcasecmp(argv[1], "sendPkt") == 0) {
198 this->sendPkt();
199 return TCL_OK;
200 } else if (strcasecmp(argv[1], "sendPktLowPriority") == 0) {
201 this->sendPktLowPriority();
202 return TCL_OK;
203 } else if (strcasecmp(argv[1], "sendPktHighPriority") == 0) {
204 this->sendPktHighPriority();
205 return TCL_OK;
206 } else if (strcasecmp(argv[1], "resetStats") == 0) {
207 resetStats();
208 fprintf(stderr,
209 "CbrModule::command() resetStats %s, pkts_last_reset=%d, "
210 "hrsn=%d, txsn=%d\n",
211 tag_,
213 hrsn,
214 txsn);
215 return TCL_OK;
216 } else if (strcasecmp(argv[1], "printidspkts") == 0) {
217 this->printIdsPkts();
218 return TCL_OK;
219 }
220 } else if (argc == 3) {
221 if (strcasecmp(argv[1], "setLogSuffix") == 0){
222 string tmp_ = (char *) argv[2];
223 log_suffix = std::string(tmp_);
224 tracefilename = "tracefile" + log_suffix + ".txt";
225 if (tracefile_enabler_) {
226 tracefile.open(tracefilename.c_str() , std::ios_base::out | std::ios_base::app);
227 }
228 return TCL_OK;
229 }
230 } else if (argc == 4) {
231 if (strcasecmp(argv[1], "setLogSuffix") == 0){
232 string tmp_ = (char *) argv[2];
233 int precision = std::atoi(argv[3]);
234 log_suffix = std::string(tmp_);
235 tracefilename = "tracefile" + log_suffix + ".txt";
236 if (tracefile_enabler_) {
237 tracefile.open(tracefilename.c_str() , std::ios_base::out | std::ios_base::app);
238 tracefile.precision(precision);
239 }
240
241 return TCL_OK;
242 }
243 }
244
245 return Module::command(argc, argv);
246}
247
248int
250{
251 switch (m->type()) {
252 default:
253 return Module::crLayCommand(m);
254 }
255}
256
257void
259{
260 hdr_cmn *ch = hdr_cmn::access(p);
261 ch->uid() = uidcnt_++;
262 ch->ptype() = PT_UWCBR;
263 ch->size() = pktSize_;
264
265 hdr_uwip *uwiph = hdr_uwip::access(p);
266 uwiph->daddr() = dstAddr_;
267
268 hdr_uwudp *uwudp = hdr_uwudp::access(p);
269 uwudp->dport() = dstPort_;
270
271 hdr_uwcbr *uwcbrh = HDR_UWCBR(p);
272 uwcbrh->sn() = txsn++;
273 uwcbrh->priority() = priority_;
274 uwcbrh->traffic_type() = traffic_type_;
275 ch->timestamp() = Scheduler::instance().clock();
276
277 if (rftt >= 0) {
278 uwcbrh->rftt() = rftt;
279 uwcbrh->rftt_valid() = true;
280 } else {
281 uwcbrh->rftt_valid() = false;
282 }
283}
284
285void
290
291void
293{
294 double delay = 0;
295 Packet *p = Packet::alloc();
296 this->initPkt(p);
297 hdr_cmn *ch = hdr_cmn::access(p);
298 hdr_uwcbr *uwcbrh = HDR_UWCBR(p);
299 if (debug_ > 10)
300 printf("CbrModule(%d)::sendPkt, send a pkt (%d) with sn: %d\n",
301 getId(),
302 ch->uid(),
303 uwcbrh->sn());
304 sendDown(p, delay);
305}
306
307void
309{
310 double delay = 0;
311 Packet *p = Packet::alloc();
312 this->initPkt(p);
313 hdr_cmn *ch = hdr_cmn::access(p);
314 hdr_uwcbr *uwcbrh = HDR_UWCBR(p);
315 uwcbrh->priority() = 0;
316 if (debug_ > 10)
317 printf("CbrModule(%d)::sendPkt, send a pkt (%d) with sn: %d\n",
318 getId(),
319 ch->uid(),
320 uwcbrh->sn());
321 sendDown(p, delay);
322}
323
324void
326{
327 double delay = 0;
328 Packet *p = Packet::alloc();
329 this->initPkt(p);
330 hdr_cmn *ch = hdr_cmn::access(p);
331 hdr_uwcbr *uwcbrh = HDR_UWCBR(p);
332 uwcbrh->priority() = 1;
333 if (debug_ > 10)
334 printf("CbrModule(%d)::sendPkt, send a pkt (%d) with sn: %d\n",
335 getId(),
336 ch->uid(),
337 uwcbrh->sn());
338 sendDown(p, delay);
339}
340
341void
343{
344 sendPkt();
345 sendTmr_.resched(getTimeBeforeNextPkt()); // schedule next transmission
346}
347
348void
350{
351 sendTmr_.force_cancel();
352}
353
354void
355UwCbrModule::recv(Packet *p, Handler *h)
356{
357 // hdr_cmn* ch = hdr_cmn::access(p);
358 recv(p);
359}
360
361void
363{
364 hdr_cmn *ch = hdr_cmn::access(p);
365 hdr_uwip *uwiph = hdr_uwip::access(p);
366
367 if (debug_ > 10)
368 printf("CbrModule(%d)::recv(Packet*p,Handler*) pktId %d\n",
369 getId(),
370 ch->uid());
371
372 if (ch->ptype() != PT_UWCBR) {
375 return;
376 }
377
378 hdr_uwcbr *uwcbrh = HDR_UWCBR(p);
379 esn = hrsn + 1; // expected sn
380
381 if (!drop_out_of_order_) {
382 if (sn_check[uwcbrh->sn() &
383 0x00ffffff]) { // Packet already processed: drop it
386 return;
387 }
388 }
389
390 sn_check[uwcbrh->sn() & 0x00ffffff] = true;
391
392 if (drop_out_of_order_) {
393 if (uwcbrh->sn() <
394 esn) { // packet is out of sequence and is to be discarded
395 incrPktOoseq();
396 if (debug_ > 1) {
397 printf("CbrModule::recv() Pkt out of sequence! "
398 "cbrh->sn=%d\thrsn=%d\tesn=%d\n",
399 uwcbrh->sn(),
400 hrsn,
401 esn);
402 }
404 return;
405 }
406 }
407
408 rftt = Scheduler::instance().clock() - ch->timestamp();
409
410 if (uwcbrh->rftt_valid()) {
411 double rtt = rftt + uwcbrh->rftt();
412 updateRTT(rtt);
413 }
414
415 if (tracefile_enabler_) {
417 }
418
420
421 /* a new packet has been received */
422 incrPktRecv();
423
424 hrsn = uwcbrh->sn();
425 if (drop_out_of_order_) {
426 if (uwcbrh->sn() > esn) { // packet losses are observed
427 incrPktLost(uwcbrh->sn() - (esn));
428 }
429 }
430
431 double dt = Scheduler::instance().clock() - lrtime;
432 updateThroughput(ch->size(), dt);
433
434 lrtime = Scheduler::instance().clock();
435
436 Packet::free(p);
437
438 if (drop_out_of_order_) {
440 fprintf(stderr,
441 "ERROR CbrModule::recv() pkts_lost=%d pkts_recv=%d "
442 "hrsn=%d\n",
443 pkts_lost,
444 pkts_recv,
445 hrsn);
446 }
447 }
448}
449
450double
452{
453 return (rttsamples > 0) ? sumrtt / rttsamples : 0;
454}
455
456double
458{
459 return (fttsamples > 0) ? sumftt / fttsamples : 0;
460}
461
462double
464{
465 return (fttsamples > 0) ? sumtxtimes / fttsamples : 0;
466}
467
468double
470{
471 if (rttsamples > 1) {
472 double var =
473 (sumrtt2 - (sumrtt * sumrtt / rttsamples)) / (rttsamples - 1);
474 return (sqrt(var));
475 } else
476 return 0;
477}
478
479double
481{
482 if (fttsamples > 1) {
483 double var = 0;
484 var = (sumftt2 - (sumftt * sumftt / fttsamples)) / (fttsamples - 1);
485 if (var > 0)
486 return (sqrt(var));
487 else
488 return 0;
489 } else {
490 return 0;
491 }
492}
493
494double
496{
497 if ((pkts_recv + pkts_lost) > 0) {
498 return ((double) pkts_lost / (double) (pkts_recv + pkts_lost));
499 } else {
500 return 0;
501 }
502}
503
504double
506{
507 return ((sumdt != 0) ? sumbytes * 8 / sumdt : 0);
508}
509
510void
511UwCbrModule::updateRTT(const double &rtt)
512{
513 sumrtt += rtt;
514 sumrtt2 += rtt * rtt;
515 rttsamples++;
516}
517
518void
519UwCbrModule::updateFTT(const double &ftt)
520{
521 sumftt += ftt;
522 sumftt2 += ftt * ftt;
523 fttsamples++;
524}
525
526void
527UwCbrModule::updateThroughput(const int &bytes, const double &dt)
528{
529 sumbytes += bytes;
530 sumdt += dt;
531
532 if (debug_ > 1) {
533 cerr << "bytes=" << bytes << " dt=" << dt << endl;
534 }
535}
536
537void
539{
540 pkts_lost += npkts;
541}
542
543void
548
549void
554
555void
560
561void
563{
565 pkts_recv = 0;
566 pkts_ooseq = 0;
567 pkts_lost = 0;
568 srtt = 0;
569 sftt = 0;
570 sthr = 0;
571 rftt = -1;
572 sumrtt = 0;
573 sumrtt2 = 0;
574 rttsamples = 0;
575 sumftt = 0;
576 sumftt2 = 0;
577 fttsamples = 0;
578 sumbytes = 0;
579 sumdt = 0;
580}
581
582double
584{
585 if (period_ < 0) {
586 fprintf(stderr, "%s : Error : period <= 0", __PRETTY_FUNCTION__);
587 exit(1);
588 }
589 if (PoissonTraffic_) {
590 double u = RNG::defaultrng()->uniform_double();
591 double lambda = 1 / period_;
592 return (-log(u) / lambda);
593 } else {
594 // CBR
595 return period_;
596 }
597}
598
599void
601{
602 hdr_uwcbr *uwcbrh = HDR_UWCBR(p);
603 hdr_cmn *ch = hdr_cmn::access(p);
604 hdr_uwip *uwiph = hdr_uwip::access(p);
605 if (tracefile_enabler_) {
606 tracefile << NOW << " " << ch->timestamp() << " " << uwcbrh->sn() << " "
607 << (int) uwiph->saddr() << " " << (int) uwiph->daddr() << " " << ch->size() <<"\n";
608 tracefile.flush();
609 }
610}
Adds the module for UwCbrModuleClass in ns2.
TclObject * create(int, const char *const *)
UwCbrModule class is used to manage UWCBR packets and to collect statistics about them.
double sumdt
Sum of the delays.
UwCbrModule()
Constructor of UwCbrModule class.
virtual void incrPktRecv()
Increases by one the number of received packets.
virtual int crLayCommand(ClMessage *m)
virtual void initPkt(Packet *p)
Initializes a data packet passed as argument with the default values.
static int getCbrHeaderSize()
Returns the size in byte of a hdr_uwcbr packet header.
std::string tracefilename
static int uidcnt_
Unique id of the packet generated.
virtual void sendPktLowPriority()
Allocates, initialize and sends a packet with the default priority flag set from tcl.
virtual double getTimeBeforeNextPkt()
Returns the amount of time to wait before the next transmission.
double rftt
Forward Trip Time seen for last received packet.
double sumbytes
Sum of bytes received.
int txsn
Sequence number of the next packet to be transmitted.
int pkts_lost
Total number of lost packets, including packets received out of sequence.
virtual double GetRTTstd() const
Returns the Round Trip Time Standard Deviation.
virtual void stop()
Stop to send packets.
virtual void incrPktInvalid()
Increases by one the number of invalid packets.
uint32_t esn
Expected serial number.
double sumftt2
Sum of (FTT^2).
double sthr
Smoothed throughput calculation.
virtual void incrPktLost(const int &)
Increases the number of packets lost.
uint16_t dstPort_
Destination port.
int pkts_ooseq
Total number of packets received out of sequence.
virtual double GetTHR() const
Returns the mean Throughput.
std::string log_suffix
Possibility to insert a log suffix.
int debug_
Flag to enable several levels of debug.
bool * sn_check
Used to keep track of the packets already received.
double sumftt
Sum of FTT samples.
double srtt
Smoothed Round Trip Time, calculated as for TCP.
uint traffic_type_
Traffic type of the packets.
virtual void printReceivedPacket(Packet *p)
Print to tracefile details about a received packet.
void printIdsPkts() const
Prints the IDs of the packet's headers defined by UWCBR.
char priority_
Priority of the data packets.
virtual double GetTxTime() const
Returns the mean transmission time.
int drop_out_of_order_
Flag to enable or disable the check for out of order packets.
double sftt
Smoothed Forward Trip Time, calculated as srtt.
virtual double GetFTTstd() const
Returns the mean Forward Trip Time Standard Deviation.
virtual void incrPktOoseq()
Increases by one the number of out of sequence packets received.
virtual void updateThroughput(const int &, const double &)
Updates the Throughput.
virtual void updateRTT(const double &)
Updates the Round Trip Time.
int tracefile_enabler_
True if enable tracefile of received packets, default disabled.
nsaddr_t dstAddr_
IP of the destination.
int pkts_recv
Total number of received packets.
UwSendTimer sendTmr_
Timer which schedules packet transmissions.
virtual void start()
Start to send packets.
double lrtime
Time of last packet reception.
virtual void sendPktHighPriority()
Allocates, initialize and sends a packet with the default priority flag set from tcl.
double sumrtt
Sum of RTT samples.
virtual double GetFTT() const
Returns the mean Forward Trip Time.
virtual void recv(Packet *)
Performs the reception of packets from upper and lower layers.
virtual double GetPER() const
Returns the mean Packet Error Rate.
virtual void transmit()
Creates and transmits a packet and schedules a new transmission.
int pktSize_
UWCBR packets payload size.
int hrsn
Highest received sequence number.
int pkts_invalid
Total number of invalid packets received.
double sumtxtimes
Sum of transmission times
double sumrtt2
Sum of (RTT^2).
virtual ~UwCbrModule()
Destructor of UwCbrModule class.
int fttsamples
Number of FTT samples.
virtual int command(int argc, const char *const *argv)
TCL command interpreter.
std::ofstream tracefile
virtual double GetRTT() const
Returns the mean Round Trip Time.
virtual void updateFTT(const double &)
Updates the Forward Trip Time.
int pkts_last_reset
Used for error checking after stats are reset.
virtual void resetStats()
Resets all the statistics of the UWCBR module.
double period_
Period between two consecutive packet transmissions.
virtual void sendPkt()
Allocates, initialize and sends a packet with the default priority flag set from tcl.
int PoissonTraffic_
1 if the traffic is generated according to a poissonian distribution, 0 otherwise.
int rttsamples
Number of RTT samples.
Adds the header for hdr_uwcbr packets in ns2.
virtual void expire(Event *e)
hdr_uwcbr describes UWCBR packets.
float & rftt()
Reference to the rftt_ variable.
char & priority()
Reference to the priority_ variable.
uint16_t & traffic_type()
Reference to the rftt_ variable.
bool & rftt_valid()
Reference to the rftt_valid_ variable.
uint16_t & sn()
Reference to the sn_ variable.
static int offset_
Required by the PacketHeaderManager.
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
static hdr_uwip * access(const Packet *p)
Definition uwip-module.h:86
hdr_uwudp describes UWUDP packets.
static struct hdr_uwudp * access(const Packet *p)
uint8_t & dport()
Reference to the dport_ variable.
UwCbrModuleClass class_module_uwcbr
UwCbrPktClass class_uwcbr_pkt
Provides the UWCBR packets header description and the definition of the class UWCBR.
#define UWCBR_DROP_REASON_DUPLICATED_PACKET
Reason for a drop in a UWCBR module.
#define UWCBR_DROP_REASON_OUT_OF_SEQUENCE
Reason for a drop in a UWCBR module.
#define HDR_UWCBR(p)
#define UWCBR_DROP_REASON_UNKNOWN_TYPE
Reason for a drop in a UWCBR module.