DESERT 3.5.1
Loading...
Searching...
No Matches
uwsr.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
38#include "uwsr.h"
39#include <mac.h>
40#include <cmath>
41#include <climits>
42#include <iomanip>
43#include <rng.h>
44#include <algorithm>
45#include <vector>
46#include <ctime>
47#include <cstdlib>
48
52static class UWSRModuleClass : public TclClass
53{
54public:
59 : TclClass("Module/UW/USR")
60 {
61 }
62 TclObject *
63 create(int, const char *const *)
64 {
65 return (new MMacUWSR());
66 }
68
69void
71{
73 module->incrPktsLostCount();
74
75 if (module->curr_state == UWSR_STATE_WAIT_ACK ||
76 module->curr_state == UWSR_STATE_PRE_TX_DATA) {
77
78 if (module->uwsr_debug)
79 cout << NOW << " MMacUWSR(" << module->addr
80 << ") timer expire() current state = "
81 << module->status_info[module->curr_state]
82 << "; ACK not received, next state = "
83 << module->status_info[UWSR_STATE_BACKOFF] << endl;
84
85 module->refreshReason(UWSR_REASON_ACK_TIMEOUT);
86 module->eraseExpiredItemsFrommapAckandCalc();
87 module->stateBackoff();
88 } else {
89 if (module->uwsr_debug)
90 cout << NOW << " MMacUWSR(" << module->addr
91 << ")::AckTimer::expired() in state "
92 << module->status_info[module->curr_state] << endl;
93 }
94}
95
96void
97MMacUWSR::BackOffTimer::expire(Event *e)
98{
99 timer_status = UWSR_EXPIRED;
100 if (module->curr_state == UWSR_STATE_BACKOFF) {
101
102 if (module->uwsr_debug)
103 cout << NOW << " MMacUWSR(" << module->addr
104 << ") timer expire() current state = "
105 << module->status_info[module->curr_state]
106 << "; backoff expired, next state = "
107 << module->status_info[UWSR_STATE_IDLE] << endl;
108
110 module->exitBackoff();
111 module->stateIdle();
112 } else {
113 if (module->uwsr_debug)
114 cout << NOW << " MMacUWSR(" << module->addr
115 << ")::BackoffTimer::expired() " << endl;
116 }
117}
118
119void
121{
123
124 if (module->curr_state == UWSR_STATE_LISTEN) {
125
126 if (module->uwsr_debug)
127 cout << NOW << " MMacUWSR(" << module->addr
128 << ")::timer expire() current state = "
129 << module->status_info[module->curr_state]
130 << "; listening period expired, next state = "
131 << module->status_info[UWSR_STATE_PRE_TX_DATA] << endl;
132
133 module->refreshReason(UWSR_REASON_LISTEN_TIMEOUT);
134 module->statePreTxData();
135 } else {
136 if (module->uwsr_debug)
137 cout << NOW << " MMacUWSR(" << module->addr
138 << ")::ListenTimer::expired() " << endl;
139 }
140}
141
142void
143MMacUWSR::WaitTxTimer::expire(Event *e)
144{
145 timer_status = UWSR_EXPIRED;
146
147 if (module->curr_state == UWSR_STATE_PRE_TX_DATA ||
148 module->curr_state == UWSR_STATE_RX_IN_PRE_TX_DATA) {
149
150 if (module->uwsr_debug)
151 cout << NOW << " MMacUWSR(" << module->addr
152 << ")::timer expire() current state = "
153 << module->status_info[module->curr_state]
154 << "; wait tx period expired, next state = "
155 << module->status_info[UWSR_STATE_TX_DATA] << endl;
156
157 module->refreshReason(UWSR_REASON_WAIT_TX_TIMEOUT);
158 module->stateTxData();
159 } else {
160 if (module->uwsr_debug)
161 cout << NOW << " MMacUWSR(" << module->addr
162 << ")::wait tx timer expired() " << endl;
163 }
164}
165
166const double MMacUWSR::prop_speed = 1500.0;
167bool MMacUWSR::initialized = false;
168
169map<MMacUWSR::UWSR_STATUS, string> MMacUWSR::status_info;
170map<MMacUWSR::UWSR_REASON_STATUS, string> MMacUWSR::reason_info;
171map<MMacUWSR::UWSR_PKT_TYPE, string> MMacUWSR::pkt_type_info;
172
173MMacUWSR::MMacUWSR()
174 : wait_tx_timer(this)
175 , ack_timer(this)
176 , listen_timer(this)
177 , backoff_timer(this)
178 , txsn(1)
179 , last_sent_data_id(-1)
180 , curr_data_pkt(0)
181 , last_data_id_rx(-1)
182 , print_transitions(false)
183 , has_buffer_queue(true)
184 , curr_state(UWSR_STATE_IDLE)
185 , prev_state(UWSR_STATE_IDLE)
186 , prev_prev_state(UWSR_STATE_IDLE)
187 , last_reason(UWSR_REASON_NOT_SET)
188 , start_tx_time(0)
189 , srtt(0)
190 , sumrtt(0)
191 , sumrtt2(0)
192 , rttsamples(0)
193 , round_trip_time(0)
194 , wait_tx_time(0)
195 , sumwtt(0)
196 , wttsamples(0)
197 , recv_data_id(-1)
198 , backoff_count(0)
199 , pkt_tx_count(0)
200 , curr_tx_rounds(0)
201 , pkts_sent_1RTT(0)
202 , acks_rcv_1RTT(0)
203 , pkts_lost_counter(0)
204 , prv_mac_addr(-1)
205 , window_size(0)
206 , hit_count(0)
207 , total_pkts_tx(0)
208 , latest_ack_timeout(0)
209
210{
211 mac2phy_delay_ = 1e-19;
212 curr_tx_rounds = 0;
213
214 bind("HDR_size_", (int *) &HDR_size);
215 bind("ACK_size_", (int *) &ACK_size);
216 bind("max_tx_tries_", (int *) &max_tx_tries);
217 bind("wait_costant_", (double *) &wait_constant);
218 bind("uwsr_debug", (double *) &uwsr_debug); // degug mode
219 bind("max_payload_", (int *) &max_payload);
220 bind("ACK_timeout_", (double *) &ACK_timeout);
221 bind("alpha_", (double *) &alpha_);
222 bind("backoff_tuner_", (double *) &backoff_tuner);
223 bind("buffer_pkts_", (int *) &buffer_pkts);
224 bind("max_backoff_counter_", (int *) &max_backoff_counter);
225 bind("listen_time_", &listen_time);
226 bind("guard_time_", (double *) &guard_time);
227 bind("node_speed_", (double *) &node_speed);
228 bind("var_k_", (double *) &var_k);
229 bind("uwsr_debug_", (int *) &uwsr_debug);
230
231 if (max_tx_tries <= 0)
232 max_tx_tries = INT_MAX;
233 if (buffer_pkts > 0)
234 has_buffer_queue = true;
235 if (listen_time <= 0.0)
236 listen_time = 1e-19;
237}
238
239MMacUWSR::~MMacUWSR()
240{
241}
242
243// TCL command interpreter
244int
245MMacUWSR::command(int argc, const char *const *argv)
246{
247 Tcl &tcl = Tcl::instance();
248 if (argc == 2) {
249 if (strcasecmp(argv[1], "initialize") == 0) {
250 if (initialized == false)
251 initInfo();
252 if (print_transitions)
253 fout.open("/tmp/UWSRstateTransitions.txt", ios_base::app);
254 return TCL_OK;
255 } else if (strcasecmp(argv[1], "printTransitions") == 0) {
256 print_transitions = true;
257 return TCL_OK;
258 }
259 // stats functions
260 else if (strcasecmp(argv[1], "getQueueSize") == 0) {
261 tcl.resultf("%d", mapPacket.size());
262 return TCL_OK;
263 } else if (strcasecmp(argv[1], "getBackoffCount") == 0) {
264 tcl.resultf("%d", getBackoffCount());
265 return TCL_OK;
266 } else if (strcasecmp(argv[1], "getAvgPktsTxIn1RTT") == 0) {
267 tcl.resultf("%f", getAvgPktsTxIn1RTT());
268 return TCL_OK;
269 }
270 } else if (argc == 3) {
271 if (strcasecmp(argv[1], "setMacAddr") == 0) {
272 addr = atoi(argv[2]);
273 if (debug_)
274 cout << "UwSR MAC address of current node is " << addr << endl;
275 return TCL_OK;
276 }
277 }
278 return MMac::command(argc, argv);
279}
280
281void
282MMacUWSR::initInfo()
283{
284
285 initialized = true;
286
287 if ((print_transitions) && (system(NULL))) {
288 system("rm -f /tmp/UWSRstateTransitions.txt");
289 system("touch /tmp/UWSRstateTransitions.txt");
290 }
291
292 status_info[UWSR_STATE_IDLE] = "Idle state";
293 status_info[UWSR_STATE_BACKOFF] = "Backoff state";
294 status_info[UWSR_STATE_TX_DATA] = "Transmit DATA state";
295 status_info[UWSR_STATE_TX_ACK] = "Transmit ACK state";
296 status_info[UWSR_STATE_WAIT_ACK] = "Wait for ACK state";
297 status_info[UWSR_STATE_DATA_RX] = "DATA received state";
298 status_info[UWSR_STATE_ACK_RX] = "ACK received state";
299 status_info[UWSR_STATE_LISTEN] = "Listening channel state";
300 status_info[UWSR_STATE_RX_IDLE] = "Start rx Idle state";
301 status_info[UWSR_STATE_RX_BACKOFF] = "Start rx Backoff state";
302 status_info[UWSR_STATE_RX_LISTEN] = "Start rx Listen state";
303 status_info[UWSR_STATE_RX_WAIT_ACK] = "Start rx Wait ACK state";
304 status_info[UWSR_STATE_CHK_LISTEN_TIMEOUT] = "Check Listen timeout state";
305 status_info[UWSR_STATE_CHK_BACKOFF_TIMEOUT] = "Check Backoff timeout state";
306 status_info[UWSR_STATE_CHK_ACK_TIMEOUT] = "Check Wait ACK timeout state";
307 status_info[UWSR_STATE_WRONG_PKT_RX] = "Wrong Pkt Rx state";
308 status_info[UWSR_STATE_WAIT_TX] = "Waiting for transmitting another packet";
309 status_info[UWSR_STATE_CHK_WAIT_TX_TIMEOUT] = "Check wait tx timeout state";
310 status_info[UWSR_STATE_WAIT_ACK_WAIT_TX] =
311 "Moving from wait tx state to rx wait ack state";
312 status_info[UWSR_STATE_RX_DATA_TX_DATA] =
313 "Data receive in txData state and moving to new state";
314
315 reason_info[UWSR_REASON_DATA_PENDING] = "DATA pending from upper layers";
316 reason_info[UWSR_REASON_DATA_RX] = "DATA received";
317 reason_info[UWSR_REASON_DATA_TX] = "DATA transmitted";
318 reason_info[UWSR_REASON_ACK_TX] = "ACK tranmsitted";
319 reason_info[UWSR_REASON_ACK_RX] = "ACK received";
320 reason_info[UWSR_REASON_BACKOFF_TIMEOUT] = "Backoff expired";
321 reason_info[UWSR_REASON_ACK_TIMEOUT] = "ACK timeout";
322 reason_info[UWSR_REASON_DATA_EMPTY] = "DATA queue empty";
323 reason_info[UWSR_REASON_MAX_TX_TRIES] = "DATA dropped due to max tx rounds";
324 reason_info[UWSR_REASON_LISTEN] = "DATA pending, listening to channel";
325 reason_info[UWSR_REASON_LISTEN_TIMEOUT] =
326 "DATA pending, end of listening period";
327 reason_info[UWSR_REASON_START_RX] = "Start rx pkt";
328 reason_info[UWSR_REASON_PKT_NOT_FOR_ME] = "Received an erroneous pkt";
329 reason_info[UWSR_REASON_BACKOFF_PENDING] = "Backoff timer pending";
330 reason_info[UWSR_REASON_WAIT_ACK_PENDING] = "Wait for ACK timer pending";
331 reason_info[UWSR_REASON_LISTEN_PENDING] = "Listen to channel pending";
332 reason_info[UWSR_REASON_PKT_ERROR] = "Erroneous pkt";
333 reason_info[UWSR_REASON_WAIT_TX] =
334 "Waiting for transmitting another packet";
335 reason_info[UWSR_REASON_WAIT_TX_PENDING] = "Transmission pending";
336 reason_info[UWSR_REASON_WAIT_TX_TIMEOUT] = "Waiting for tx timeout";
337
338 pkt_type_info[UWSR_ACK_PKT] = "ACK pkt";
339 pkt_type_info[UWSR_DATA_PKT] = "DATA pkt";
340 pkt_type_info[UWSR_DATAMAX_PKT] = "MAX payload DATA pkt";
341}
342
343void
344MMacUWSR::updateTxStatus(macAddress mac_addr, int rcv_acks)
345{
346 map<macAddress, txStatusPair>::iterator it_tx;
347 it_tx = mapTxStatus.find(mac_addr);
348
349 if (it_tx == mapTxStatus.end()) {
350 mapTxStatus.insert(
351 make_pair(mac_addr, make_pair(getPktsSentIn1RTT(), rcv_acks)));
352 } else {
353 if ((it_tx->second).first != getPktsSentIn1RTT())
354 (it_tx->second).first = getPktsSentIn1RTT();
355 if ((it_tx->second).second != rcv_acks)
356 (it_tx->second).second = rcv_acks;
357 }
358}
359
360int
361MMacUWSR::calWindowSize(macAddress mac_addr)
362{
363 map<macAddress, txStatusPair>::iterator it_tx;
364 it_tx = mapTxStatus.find(mac_addr);
365
366 if (it_tx == mapTxStatus.end()) {
367 window_size = 1;
368 } else {
369 if ((it_tx->second).first == (it_tx->second).second)
370 window_size = max(window_size, ((it_tx->second).first + 1));
371 else
372 window_size = (floor((it_tx->second).first * var_k));
373 }
374 if (uwsr_debug)
375 cout << NOW << " MMacUWSR(" << addr << ")::window size "
376 << max(1, window_size) << endl;
377 return max(1, window_size);
378}
379
380void
381MMacUWSR::putRTTInMap(int mac_addr, double rtt)
382{
383
384 double time = NOW;
385
386 if (uwsr_debug)
387 cout << NOW << " MMacUWSR(" << addr << ")::putRTTInMap() mac add "
388 << mac_addr << "rtt " << rtt << "time " << time << endl;
389
390 map<macAddress, rttPair>::iterator it_d;
391 it_d = mapRTT.find(mac_addr);
392
393 if (it_d == mapRTT.end()) {
394 mapRTT.insert(make_pair(mac_addr, make_pair(rtt, time)));
395 } else {
396 if (rtt != (it_d->second).first || time != (it_d->second).second) {
397 (it_d->second).first = rtt;
398 (it_d->second).second = time;
399 } else {
400 // do nothing. keep the RTT saved in the map
401 }
402 }
403}
404
405int
406MMacUWSR::getPktsCanSendIn1RTT(int mac_addr)
407{
408
409 if (uwsr_debug)
410 cout << NOW << " MMacUWSR(" << addr
411 << ")::getPktsCanSendIn1RTT() rcv mac addr " << mac_addr << endl;
412
413 int pkts_can_send_1RTT = 1;
414
415 map<macAddress, rttPair>::iterator it_d = mapRTT.find(mac_addr);
416
417 if (it_d != mapRTT.end()) {
418
419 double tx_time = (computeTxTime(UWSR_DATA_PKT) +
420 computeTxTime(UWSR_ACK_PKT) + guard_time);
421
422 double apprx_travel_dis =
423 2 * node_speed * (NOW - (it_d->second).second);
424 double apprx_curr_rtt =
425 (it_d->second).first - (apprx_travel_dis / prop_speed);
426
427 pkts_can_send_1RTT = max(1, (int) (floor(apprx_curr_rtt / tx_time)));
428 }
429
430 if (uwsr_debug)
431 cout << NOW << " MMacUWSR(" << addr
432 << ")::No pkts can send in 1 RTT is " << pkts_can_send_1RTT
433 << endl;
434 if (uwsr_debug)
435 cout << NOW << " MMacUWSR(" << addr << ")::Window size: " << window_size
436 << endl;
437 if (uwsr_debug)
438 cout << NOW << " MMacUWSR(" << addr
439 << ")::Pkts can transmit in 1 RTT is "
440 << min(window_size, pkts_can_send_1RTT) << endl;
441 return min(calWindowSize(mac_addr), pkts_can_send_1RTT);
442}
443
444bool
445MMacUWSR::chkItemInmapTxRounds(int mac_addr, int seq_num)
446{
447 map<usrPair, txRounds>::iterator it_t;
448 it_t = mapTxRounds.find(make_pair(mac_addr, seq_num));
449 if (uwsr_debug)
450 cout << NOW << " MMacUWSR(" << addr << ")::chkItemInmapTxRounds()"
451 << endl;
452 if (it_t != mapTxRounds.end())
453 return true;
454 else
455 return false;
456}
457
458double
459MMacUWSR::calcWaitTxTime(int mac_addr)
460{
461
462 if (uwsr_debug)
463 cout << NOW << " MMacUWSR(" << addr
464 << ")::calcWaitTxTime() rcv mac addr " << mac_addr << endl;
465
466 double wait_time;
467 double rtt_time;
468 double pkts_can_tx;
469
470 map<macAddress, rttPair>::iterator it_d;
471 it_d = mapRTT.find(mac_addr);
472
473 if (it_d == mapRTT.end()) {
474 cerr << NOW << " MMacUWSR(" << addr
475 << ")::calcWaitTxTime() is accessed in inappropriate time" << endl;
476 exit(1);
477 } else
478 rtt_time = (it_d->second).first;
479 pkts_can_tx = getPktsCanSendIn1RTT(mac_addr);
480
481 wait_time = ((computeTxTime(UWSR_ACK_PKT) / 2 + rtt_time -
482 (pkts_can_tx - 1) * computeTxTime(UWSR_DATA_PKT)) /
483 (pkts_can_tx - 0.5));
484
485 if (uwsr_debug)
486 cout << NOW << " MMacUWSR(" << addr << ")::round trip time " << rtt_time
487 << endl;
488 if (uwsr_debug)
489 cout << NOW << " MMacUWSR(" << addr << ")::calcWaitTxTime() wait time "
490 << wait_time << endl;
491 return wait_time;
492}
493
494bool
495MMacUWSR::checkMultipleTx(int rcv_mac_addr)
496{
497
498 if (uwsr_debug)
499 cout << NOW << " MMacUWSR(" << addr
500 << ")::checkMultipleTx() rcv mac addr " << rcv_mac_addr << endl;
501
502 Packet *nxt_data_pkt;
503
504 map<usrPair, Packet *>::iterator it_p;
505 map<usrPair, AckTimer>::iterator it_a;
506
507 int nxt_mac_addr;
508
509 if (mapPacket.size() == 0)
510 return false;
511 else if (mapPacket.size() <= mapAckTimer.size())
512 return false;
513 else if (getPktsCanSendIn1RTT(rcv_mac_addr) < 2)
514 return false;
515 else {
516 for (it_p = mapPacket.begin(); it_p != mapPacket.end(); it_p++) {
517 it_a = mapAckTimer.find((*it_p).first);
518 if ((*it_a).first != (*it_p).first) {
519 nxt_data_pkt = (*it_p).second;
520 if (uwsr_debug)
521 cout << NOW << " MMacUWSR(" << addr
522 << ")::Next Packet transmitting: " << nxt_data_pkt
523 << endl;
524 hdr_mac *mach = HDR_MAC(nxt_data_pkt);
525 nxt_mac_addr = mach->macDA();
526 if (rcv_mac_addr == nxt_mac_addr)
527 break;
528 } else
529 nxt_mac_addr = -1;
530 }
531
532 if (rcv_mac_addr == nxt_mac_addr &&
533 getPktsCanSendIn1RTT(rcv_mac_addr) > getPktsSentIn1RTT())
534 return true;
535 else
536 return false;
537 }
538}
539
540int
541MMacUWSR::checkAckTimer(CHECK_ACK_TIMER type)
542{
543
544 int iteration_count = 0;
545 int active_count = 0;
546 int idle_count = 0;
547 int expired_count = 0;
548 int value = 0;
549
550 map<usrPair, AckTimer>::iterator it_a;
551
552 for (it_a = mapAckTimer.begin(); it_a != mapAckTimer.end(); it_a++) {
553 if (((*it_a).second).isActive()) {
554 active_count += 1;
555 } else if (((*it_a).second).isExpired()) {
556 expired_count += 1;
557 } else if (((*it_a).second).isIdle()) {
558 idle_count += 1;
559 } else {
560 cerr << "Ack Timer is in wrong state" << endl;
561 exit(1);
562 }
563 iteration_count += 1;
564 }
565
566 if (uwsr_debug)
567 cout << NOW << " MMacUWSR(" << addr
568 << ")::No of item in ack map: " << mapAckTimer.size() << endl;
569 if (uwsr_debug)
570 cout << NOW << " MMacUWSR(" << addr
571 << ")::No of iteration count: " << iteration_count << endl;
572 if (uwsr_debug)
573 cout << NOW << " MMacUWSR(" << addr
574 << ")::No of active count: " << active_count << endl;
575 if (uwsr_debug)
576 cout << NOW << " MMacUWSR(" << addr
577 << ")::No of expired count: " << expired_count << endl;
578 if (uwsr_debug)
579 cout << NOW << " MMacUWSR(" << addr
580 << ")::No of idle count: " << idle_count << endl;
581
582 if (type == CHECK_ACTIVE) {
583 if (mapAckTimer.size() == 0) {
584 value = 1;
585 } else {
586 value = floor(active_count / mapAckTimer.size());
587 }
588 } else if (type == CHECK_EXPIRED) {
589 value = expired_count;
590 } else if (type == CHECK_IDLE) {
591 value = idle_count;
592 } else {
593 if (uwsr_debug)
594 cout << NOW << " MMacUWSR(" << addr
595 << ")::Ack Timer is in wrong state" << endl;
596 exit(1);
597 }
598
599 if (uwsr_debug)
600 cout << NOW << " MMacUWSR(" << addr << ")::returning value: " << value
601 << endl;
602 return value;
603}
604
605void
606MMacUWSR::eraseExpiredItemsFrommapAckandCalc()
607{
608
609 if (uwsr_debug)
610 cout << NOW << " MMacUWSR(" << addr
611 << ")::Erasing expired items from map ack and calc" << endl;
612
613 map<usrPair, AckTimer>::iterator it_a1, it_a2;
614
615 it_a1 = mapAckTimer.begin();
616
617 while (it_a1 != mapAckTimer.end()) {
618
619 it_a2 = it_a1;
620 it_a1++;
621
622 if (((*it_a2).second).isExpired()) {
623 int mac_addr = (it_a2->first).first;
624 int seq_num = (it_a2->first).second;
625 eraseItemFrommapAckTimer(mac_addr, seq_num);
626 eraseItemFrommapCalcAck(mac_addr, seq_num);
627 } else {
628 // do nothing
629 }
630 }
631}
632
633double
634MMacUWSR::computeTxTime(UWSR_PKT_TYPE type)
635{
636 map<usrPair, Packet *>::iterator it_p;
637
638 double duration;
639 Packet *temp_data_pkt;
640
641 if (type == UWSR_DATA_PKT) {
642 if (!mapPacket.empty()) {
643 it_p = mapPacket.begin();
644 temp_data_pkt = ((*it_p).second)->copy();
645 hdr_cmn *ch = HDR_CMN(temp_data_pkt);
646 ch->size() = HDR_size + ch->size();
647 } else {
648 temp_data_pkt = Packet::alloc();
649 hdr_cmn *ch = HDR_CMN(temp_data_pkt);
650 ch->size() = HDR_size + max_payload;
651 }
652 } else if (type == UWSR_ACK_PKT) {
653 temp_data_pkt = Packet::alloc();
654 hdr_cmn *ch = HDR_CMN(temp_data_pkt);
655 ch->size() = ACK_size;
656 }
657 duration = Mac2PhyTxDuration(temp_data_pkt);
658 Packet::free(temp_data_pkt);
659 return (duration);
660}
661
662void
663MMacUWSR::exitBackoff()
664{
665 backoff_timer.stop();
666}
667
668double
669MMacUWSR::getBackoffTime()
670{
671 incrTotalBackoffTimes();
672 double random = RNG::defaultrng()->uniform_double();
673
674 backoff_timer.incrCounter();
675 double counter = backoff_timer.getCounter();
676 if (counter > max_backoff_counter)
677 counter = max_backoff_counter;
678
679 double backoff_duration =
680 backoff_tuner * random * 2.0 * ACK_timeout * pow(2.0, counter);
681 backoffSumDuration(backoff_duration);
682
683 if (uwsr_debug) {
684 cout << NOW << " MMacUWSR(" << addr
685 << ")::getBackoffTime() backoff time = " << backoff_duration
686 << " latest ack timeout = " << (latest_ack_timeout - NOW) << endl;
687 }
688
689 return max((latest_ack_timeout - NOW) + wait_constant, backoff_duration);
690}
691
692void
693MMacUWSR::recvFromUpperLayers(Packet *p)
694{
695 if (((has_buffer_queue == true) && (mapPacket.size() < buffer_pkts)) ||
696 (has_buffer_queue == false)) {
697 initPkt(p, UWSR_DATA_PKT);
698 putPktInQueue(p);
699 incrUpperDataRx();
700 waitStartTime();
701
702 if (curr_state == UWSR_STATE_IDLE) {
703 refreshReason(UWSR_REASON_DATA_PENDING);
704 stateListen();
705 }
706 } else {
707 incrDiscardedPktsTx();
708 drop(p, 1, UWSR_DROP_REASON_BUFFER_FULL);
709 }
710}
711
712void
713MMacUWSR::initPkt(Packet *p, UWSR_PKT_TYPE type, int dest_addr)
714{
715 hdr_cmn *ch = hdr_cmn::access(p);
716 hdr_mac *mach = HDR_MAC(p);
717
718 int curr_size = ch->size();
719
720 switch (type) {
721
722 case (UWSR_DATA_PKT): {
723 ch->size() = curr_size + HDR_size;
724 } break;
725
726 case (UWSR_ACK_PKT): {
727 ch->ptype() = PT_MMAC_ACK;
728 ch->size() = ACK_size;
729 ch->uid() = recv_data_id;
730 mach->set(MF_CONTROL, addr, dest_addr);
731 mach->macSA() = addr;
732 mach->macDA() = dest_addr;
733 } break;
734 }
735}
736
737void
738MMacUWSR::Mac2PhyStartTx(Packet *p)
739{
740
741 if (uwsr_debug)
742 cout << NOW << " MMacUWSR(" << addr
743 << ")::Mac2PhyStartTx() start tx packet" << endl;
744
745 MMac::Mac2PhyStartTx(p);
746}
747
748void
749MMacUWSR::Phy2MacEndTx(const Packet *p)
750{
751
752 hdr_cmn *ch = hdr_cmn::access(p);
753 int seq_num = ch->uid();
754
755 hdr_mac *mach = HDR_MAC(p);
756 int dst_mac_addr = mach->macDA();
757 prv_mac_addr = dst_mac_addr;
758
759 if (uwsr_debug)
760 cout << NOW << " MMacUWSR(" << addr << ")::Phy2MacEndTx() end tx packet"
761 << endl;
762 if (uwsr_debug)
763 cout << NOW << " MMacUWSR(" << addr << ")::Phy2MacEndTx() dst mac addr "
764 << dst_mac_addr << endl;
765
766 switch (curr_state) {
767
768 case (UWSR_STATE_TX_DATA): {
769 refreshReason(UWSR_REASON_DATA_TX);
770
771 incrPktsSentIn1RTT();
772 double wait_time, ack_time;
773 double ack_timeout_time;
774
775 map<int, rttPair>::iterator it_d;
776 it_d = mapRTT.find(dst_mac_addr);
777
778 if (it_d == mapRTT.end())
779 ack_timeout_time = ACK_timeout + 2 * wait_constant;
780 else
781 ack_timeout_time =
782 getRTTInMap(dst_mac_addr) + 2 * wait_constant;
783
784 ack_time = NOW + ack_timeout_time;
785
786 putAckTimerInMap(dst_mac_addr, seq_num);
787 map<usrPair, AckTimer>::iterator it_a;
788 it_a = mapAckTimer.find(make_pair(dst_mac_addr, seq_num));
789 ((*it_a).second).stop();
790 ((*it_a).second).schedule(ack_timeout_time);
791
792 if (uwsr_debug)
793 cout << NOW << " MMacUWSR(" << addr
794 << ")::Phy2MacEndTx(), ack_timeout_time: " << ack_time
795 << " latest_ack_timeout " << latest_ack_timeout << endl;
796 if (ack_time > latest_ack_timeout)
797 latest_ack_timeout = ack_time;
798 if (uwsr_debug)
799 cout << NOW << " MMacUWSR(" << addr
800 << ")::Phy2MacEndTx(), ack_timeout_time: " << ack_time
801 << " latest_ack_timeout " << latest_ack_timeout << endl;
802
803 if (checkMultipleTx(dst_mac_addr)) {
804 if (uwsr_debug)
805 cout << NOW << " MMacUWSR(" << addr
806 << ")::Phy2MacEndTx() DATA sent,from "
807 << status_info[curr_state] << " to "
808 << status_info[UWSR_STATE_PRE_TX_DATA] << endl;
809
810 wait_time = calcWaitTxTime(dst_mac_addr);
811 wait_tx_timer.stop();
812 wait_tx_timer.incrCounter();
813 wait_tx_timer.schedule(wait_time);
814
815 statePreTxData();
816 }
817
818 else {
819
820 if (uwsr_debug)
821 cout << NOW << " MMacUWSR(" << addr
822 << ")::Phy2MacEndTx() DATA sent,from "
823 << status_info[curr_state] << " to "
824 << status_info[UWSR_STATE_WAIT_ACK] << endl;
825
826 updateTxStatus(dst_mac_addr, 0);
827 calTotalPktsTx();
828 stateWaitAck();
829 }
830
831 } break;
832
833 case (UWSR_STATE_TX_ACK): {
834 refreshReason(UWSR_REASON_ACK_TX);
835
836 if (prev_prev_state == UWSR_STATE_RX_BACKOFF) {
837 if (uwsr_debug)
838 cout << NOW << " MMacUWSR(" << addr
839 << ")::Phy2MacEndTx() ack sent, from "
840 << status_info[curr_state] << " to "
841 << status_info[UWSR_STATE_CHK_BACKOFF_TIMEOUT] << endl;
842
843 stateCheckBackoffExpired();
844 } else if (prev_prev_state == UWSR_STATE_RX_WAIT_ACK) {
845 if (uwsr_debug)
846 cout << NOW << " MMacUWSR(" << addr
847 << ")::Phy2MacEndTx() ack sent, from "
848 << status_info[curr_state] << " to "
849 << status_info[UWSR_STATE_CHK_BACKOFF_TIMEOUT] << endl;
850
851 stateCheckAckExpired();
852 } else if (prev_prev_state == UWSR_STATE_RX_IN_PRE_TX_DATA) {
853 if (uwsr_debug)
854 cout << NOW << " MMacUWSR(" << addr
855 << ")::Phy2MacEndTx() ack sent, from "
856 << status_info[curr_state] << " to "
857 << status_info[UWSR_STATE_CHK_BACKOFF_TIMEOUT] << endl;
858
859 stateCheckWaitTxExpired();
860 } else if (prev_prev_state == UWSR_STATE_RX_LISTEN) {
861 if (uwsr_debug)
862 cout << NOW << " MMacUWSR(" << addr
863 << ")::Phy2MacEndTx() ack sent, from "
864 << status_info[curr_state] << " to "
865 << status_info[UWSR_STATE_CHK_LISTEN_TIMEOUT] << endl;
866
867 stateCheckListenExpired();
868 } else if (prev_prev_state == UWSR_STATE_RX_IDLE) {
869 if (uwsr_debug)
870 cout << NOW << " MMacUWSR(" << addr
871 << ")::Phy2MacEndTx() ack sent, from "
872 << status_info[curr_state] << " to "
873 << status_info[UWSR_STATE_IDLE] << endl;
874
875 stateIdle();
876 } else {
877 cerr << NOW << " MMacUWSR(" << addr
878 << ")::Phy2MacEndTx() logical error in timers, current "
879 "state = "
880 << status_info[curr_state] << endl;
881 exit(1);
882 }
883
884 } break;
885
886 default: {
887 cerr << NOW << " MMacUWSR(" << addr
888 << ")::Phy2MacEndTx() logical error, current state = "
889 << status_info[curr_state] << endl;
890 exit(1);
891 } break;
892 }
893}
894
895void
896MMacUWSR::Phy2MacStartRx(const Packet *p)
897{
898 if (uwsr_debug)
899 cout << NOW << " MMacUWSR(" << addr << ")::Phy2MacStartRx() rx Packet "
900 << endl;
901
902 refreshReason(UWSR_REASON_START_RX);
903
904 switch (curr_state) {
905
906 case (UWSR_STATE_IDLE):
907 stateRxIdle();
908 break;
909
910 case (UWSR_STATE_LISTEN):
911 stateRxListen();
912 break;
913
914 case (UWSR_STATE_BACKOFF):
915 stateRxBackoff();
916 break;
917
918 case (UWSR_STATE_PRE_TX_DATA):
919 stateRxinPreTxData();
920 break;
921
922 case (UWSR_STATE_WAIT_ACK):
923 stateRxWaitAck();
924 break;
925
926 default: {
927 cerr << NOW << " MMacUWSR(" << addr
928 << ")::Phy2MacStartRx() logical warning, current state = "
929 << status_info[curr_state] << endl;
930 }
931 }
932}
933
934void
935MMacUWSR::Phy2MacEndRx(Packet *p)
936{
937
938 hdr_cmn *ch = HDR_CMN(p);
939 packet_t rx_pkt_type = ch->ptype();
940 hdr_mac *mach = HDR_MAC(p);
941 hdr_MPhy *ph = HDR_MPHY(p);
942
943 int source_mac = mach->macSA();
944 int dest_mac = mach->macDA();
945
946 double gen_time = ph->txtime;
947 double received_time = ph->rxtime;
948 double diff_time = received_time - gen_time;
949 putRTTInMap(source_mac, 2 * diff_time);
950
951 double distance = diff_time * prop_speed;
952 int seq_num = getPktSeqNum(p);
953 map<usrPair, AckTimer>::iterator it_a;
954
955 if (uwsr_debug)
956 cout << NOW << " MMacUWSR(" << addr << ")::Phy2MacEndRx() "
957 << status_info[curr_state]
958 << ", received a pkt type = " << ch->ptype()
959 << ", src addr = " << mach->macSA()
960 << " dest addr = " << mach->macDA() << " RTT = " << 2 * diff_time
961 << ", estimated distance between nodes = " << distance << " m "
962 << endl;
963
964 if (ch->error()) {
965
966 if (uwsr_debug)
967 cout << NOW << " MMacUWSR(" << addr
968 << ")::Phy2MacEndRx() dropping corrupted pkt " << endl;
969 incrErrorPktsRx();
970
971 refreshReason(UWSR_REASON_PKT_ERROR);
972 drop(p, 1, UWSR_DROP_REASON_ERROR);
973 stateRxPacketNotForMe(NULL);
974 } else {
975 if (dest_mac == addr || dest_mac == MAC_BROADCAST) {
976 if (rx_pkt_type == PT_MMAC_ACK) {
977 it_a = mapAckTimer.find(make_pair(source_mac, seq_num));
978 if (it_a != mapAckTimer.end()) {
979 refreshReason(UWSR_REASON_ACK_RX);
980 stateRxAck(p);
981 } else {
982 drop(p, 1, UWSR_DROP_REASON_ERROR);
983 stateRxPacketNotForMe(NULL);
984 }
985 } else {
986 refreshReason(UWSR_REASON_DATA_RX);
987 stateRxData(p);
988 }
989 } else {
990 refreshReason(UWSR_REASON_PKT_NOT_FOR_ME);
991 stateRxPacketNotForMe(p);
992 }
993 }
994}
995
996void
997MMacUWSR::stateTxData()
998{
999 refreshState(UWSR_STATE_TX_DATA);
1000
1001 if (uwsr_debug)
1002 cout << NOW << " MMacUWSR(" << addr << ")::stateTxData" << endl;
1003
1004 Packet *data_pkt = curr_data_pkt->copy(); // copio pkt
1005 int seq_num = getPktSeqNum(data_pkt);
1006 int mac_addr = getMacAddress(data_pkt);
1007
1008 start_tx_time = NOW;
1009 map<usrPair, txStartTime>::iterator it_ca;
1010 it_ca = mapCalcAck.find(make_pair(mac_addr, seq_num));
1011 if (it_ca == mapCalcAck.end())
1012 putStartTxTimeInMap(mac_addr, seq_num, start_tx_time);
1013
1014 incrDataPktsTx();
1015
1016 Mac2PhyStartTx(data_pkt);
1017}
1018
1019void
1020MMacUWSR::txAck(int dest_addr)
1021{
1022 Packet *ack_pkt = Packet::alloc();
1023 initPkt(ack_pkt, UWSR_ACK_PKT, dest_addr);
1024
1025 incrAckPktsTx();
1026 Mac2PhyStartTx(ack_pkt);
1027}
1028
1029void
1030MMacUWSR::stateRxPacketNotForMe(Packet *p)
1031{
1032 if (uwsr_debug)
1033 cout << NOW << " MMacUWSR(" << addr
1034 << ")::stateRxPacketNotForMe() pkt for another address. Dropping "
1035 "pkt"
1036 << endl;
1037 if (p != NULL)
1038 Packet::free(p);
1039
1040 refreshState(UWSR_STATE_WRONG_PKT_RX);
1041
1042 switch (prev_state) {
1043
1044 case UWSR_STATE_RX_IDLE:
1045 stateIdle();
1046 break;
1047
1048 case UWSR_STATE_RX_LISTEN:
1049 stateCheckListenExpired();
1050 break;
1051
1052 case UWSR_STATE_RX_BACKOFF:
1053 stateCheckBackoffExpired();
1054 break;
1055
1056 case UWSR_STATE_RX_IN_PRE_TX_DATA:
1057 stateCheckWaitTxExpired();
1058 break;
1059
1060 case UWSR_STATE_RX_WAIT_ACK:
1061 stateCheckAckExpired();
1062 break;
1063
1064 default:
1065 cerr << NOW << " MMacUWSR(" << addr
1066 << ")::stateRxPacketNotForMe() logical error, current state = "
1067 << status_info[curr_state] << endl;
1068 curr_state = prev_state;
1069 prev_state = prev_prev_state;
1070 break;
1071 }
1072}
1073
1074void
1075MMacUWSR::stateCheckListenExpired()
1076{
1077 refreshState(UWSR_STATE_CHK_LISTEN_TIMEOUT);
1078
1079 if (uwsr_debug)
1080 cout << NOW << " MMacUWSR(" << addr << ")::stateCheckListenExpired()"
1081 << endl;
1082 if (print_transitions)
1083 printStateInfo();
1084 if (listen_timer.isActive()) {
1085 refreshReason(UWSR_REASON_LISTEN_PENDING);
1086 refreshState(UWSR_STATE_LISTEN);
1087 } else if (listen_timer.isExpired()) {
1088 refreshReason(UWSR_REASON_LISTEN_TIMEOUT);
1089 if (!(prev_state == UWSR_STATE_TX_ACK ||
1090 prev_state == UWSR_STATE_WRONG_PKT_RX ||
1091 prev_state == UWSR_STATE_ACK_RX ||
1092 prev_state == UWSR_STATE_DATA_RX))
1093 stateTxData();
1094 else
1095 stateListen();
1096 } else {
1097 cerr << NOW << " MMacUWSR(" << addr
1098 << ")::stateCheckListenExpired() listen_timer logical error, "
1099 "current timer state = "
1100 << status_info[curr_state] << endl;
1101 exit(1);
1102 }
1103}
1104
1105void
1106MMacUWSR::stateCheckAckExpired()
1107{
1108 refreshState(UWSR_STATE_CHK_ACK_TIMEOUT);
1109
1110 if (uwsr_debug)
1111 cout << NOW << " MMacUWSR(" << addr << ")::stateCheckAckExpired()"
1112 << endl;
1113 if (print_transitions)
1114 printStateInfo();
1115
1116 if (mapAckTimer.size() == 0)
1117 stateIdle();
1118 else if (checkAckTimer(CHECK_ACTIVE)) {
1119 refreshReason(UWSR_REASON_WAIT_ACK_PENDING);
1120 refreshState(UWSR_STATE_WAIT_ACK);
1121 } else if (checkAckTimer(CHECK_EXPIRED) > 0) {
1122 refreshReason(UWSR_REASON_ACK_TIMEOUT);
1123 eraseExpiredItemsFrommapAckandCalc();
1124 stateBackoff();
1125 } else {
1126 cerr << NOW << " MMacUWSR(" << addr
1127 << ")::stateCheckAckExpired() ack_timer logical error, current "
1128 "timer state = "
1129 << status_info[curr_state] << endl;
1130 exit(1);
1131 }
1132}
1133
1134void
1135MMacUWSR::stateCheckBackoffExpired()
1136{
1137 refreshState(UWSR_STATE_CHK_BACKOFF_TIMEOUT);
1138
1139 if (uwsr_debug)
1140 cout << NOW << " MMacUWSR(" << addr << ")::stateCheckBackoffExpired()"
1141 << endl;
1142 if (print_transitions)
1143 printStateInfo();
1144 if (backoff_timer.isActive()) {
1145 refreshReason(UWSR_REASON_BACKOFF_PENDING);
1146 stateBackoff();
1147 } else if (backoff_timer.isExpired()) {
1148 refreshReason(UWSR_REASON_BACKOFF_TIMEOUT);
1149 exitBackoff();
1150 stateIdle();
1151 } else {
1152 cerr << NOW << " MMacUWSR(" << addr
1153 << ")::stateCheckBackoffExpired() backoff_timer logical error, "
1154 "current timer state = "
1155 << status_info[curr_state] << endl;
1156 exit(1);
1157 }
1158}
1159
1160void
1161MMacUWSR::stateCheckWaitTxExpired()
1162{
1163
1164 refreshState(UWSR_STATE_CHK_WAIT_TX_TIMEOUT);
1165
1166 if (uwsr_debug)
1167 cout << NOW << " MMacUWSR(" << addr << ")::stateCheckWaitTxExpired()"
1168 << endl;
1169
1170 if (print_transitions)
1171 printStateInfo();
1172
1173 if (checkAckTimer(CHECK_EXPIRED) > 0) {
1174 refreshReason(UWSR_REASON_ACK_TIMEOUT);
1175 eraseExpiredItemsFrommapAckandCalc();
1176 stateBackoff();
1177 }
1178
1179 else if (checkAckTimer(CHECK_ACTIVE)) {
1180 if (uwsr_debug)
1181 cout << NOW << " MMacUWSR(" << addr
1182 << ")::wait tx is active:" << wait_tx_timer.isActive() << endl;
1183 if (uwsr_debug)
1184 cout << NOW << " MMacUWSR(" << addr
1185 << ")::wait tx is expired:" << wait_tx_timer.isExpired()
1186 << endl;
1187 if (uwsr_debug)
1188 cout << NOW << " MMacUWSR(" << addr
1189 << ")::wait tx is idle:" << wait_tx_timer.isIdle() << endl;
1190
1191 if (wait_tx_timer.isActive()) {
1192 refreshReason(UWSR_REASON_WAIT_TX_PENDING);
1193 refreshState(UWSR_STATE_PRE_TX_DATA);
1194 }
1195
1196 else if (wait_tx_timer.isExpired()) {
1197 refreshReason(UWSR_REASON_WAIT_TX_TIMEOUT);
1198 refreshState(UWSR_STATE_PRE_TX_DATA);
1199 stateTxData();
1200 }
1201
1202 else {
1203 cerr << NOW << " MMacUWSR(" << addr
1204 << ")::stateCheckWaitTxExpired() wait_tx_timer logical error, "
1205 "current timer state = "
1206 << status_info[curr_state] << endl;
1207 exit(1);
1208 }
1209 }
1210
1211 else {
1212
1213 cerr << NOW << " MMacUWSR(" << addr
1214 << ")::stateCheckAckExpired() ack_timer logical error, current "
1215 "timer state = "
1216 << status_info[curr_state] << endl;
1217 exit(1);
1218 }
1219}
1220
1221void
1222MMacUWSR::stateIdle()
1223{
1224
1225 rstPktsLostCount();
1226 if (uwsr_debug)
1227 cout << NOW << " MMacUWSR(" << addr
1228 << ")::stateIdle(), Pkts sent in one RTT: " << getPktsSentIn1RTT()
1229 << endl;
1230 rstPktsSentIn1RTT();
1231 rstAcksRcvIn1RTT();
1232 backoff_timer.stop();
1233 listen_timer.stop();
1234 wait_tx_timer.stop();
1235
1236 refreshState(UWSR_STATE_IDLE);
1237
1238 if (print_transitions)
1239 printStateInfo();
1240
1241 if (!mapPacket.empty()) {
1242 refreshReason(UWSR_REASON_LISTEN);
1243 stateListen();
1244 }
1245}
1246
1247void
1248MMacUWSR::stateRxIdle()
1249{
1250 refreshState(UWSR_STATE_RX_IDLE);
1251
1252 if (print_transitions)
1253 printStateInfo();
1254}
1255
1256void
1257MMacUWSR::stateListen()
1258{
1259 listen_timer.stop();
1260 refreshState(UWSR_STATE_LISTEN);
1261
1262 listen_timer.incrCounter();
1263
1264 double time =
1265 listen_time * RNG::defaultrng()->uniform_double() + wait_constant;
1266
1267 if (uwsr_debug)
1268 cout << NOW << " MMacUWSR(" << addr
1269 << ")::stateListen() listen time = " << time << endl;
1270
1271 if (print_transitions)
1272 printStateInfo();
1273
1274 listen_timer.schedule(time);
1275}
1276
1277void
1278MMacUWSR::stateRxListen()
1279{
1280 refreshState(UWSR_STATE_RX_LISTEN);
1281
1282 if (print_transitions)
1283 printStateInfo();
1284}
1285
1286void
1287MMacUWSR::stateBackoff()
1288{
1289
1290 rstPktsLostCount();
1291 wait_tx_timer.stop();
1292
1293 refreshState(UWSR_STATE_BACKOFF);
1294
1295 setBackoffCount();
1296
1297 if (backoff_timer.isFrozen())
1298 backoff_timer.unFreeze();
1299 else
1300 backoff_timer.schedule(getBackoffTime());
1301 if (uwsr_debug)
1302 cout << NOW << " MMacUWSR(" << addr
1303 << ")::stateBackoff() get backoff time " << getBackoffTime()
1304 << endl;
1305
1306 if (uwsr_debug)
1307 cout << NOW << " MMacUWSR(" << addr << ")::stateBackoff() " << endl;
1308 if (print_transitions)
1309 printStateInfo(backoff_timer.getDuration());
1310}
1311
1312void
1313MMacUWSR::stateRxBackoff()
1314{
1315 backoff_timer.freeze();
1316 refreshState(UWSR_STATE_RX_BACKOFF);
1317
1318 if (print_transitions)
1319 printStateInfo();
1320}
1321
1322bool
1323MMacUWSR::prepBeforeTx(int mac_addr, int seq_num)
1324{
1325
1326 if (uwsr_debug)
1327 cout << NOW << " MMacUWSR(" << addr
1328 << ")::prepBeforeTx(), is item in tx rounds map "
1329 << chkItemInmapTxRounds(mac_addr, seq_num) << endl;
1330
1331 if (chkItemInmapTxRounds(mac_addr, seq_num)) {
1332 if (getCurrTxRounds(mac_addr, seq_num) < max_tx_tries + 1) {
1333
1334 last_sent_data_id = seq_num;
1335 incrCurrTxRounds(mac_addr, seq_num);
1336 return true;
1337 } else {
1338 eraseItemFromPktQueue(mac_addr, seq_num);
1339 eraseItemFromTxRounds(mac_addr, seq_num);
1340 eraseItemFrommapAckTimer(mac_addr, seq_num);
1341 incrDroppedPktsTx();
1342
1343 refreshReason(UWSR_REASON_MAX_TX_TRIES);
1344
1345 if (uwsr_debug)
1346 cout << NOW << " MMacUWSR(" << addr
1347 << ")::stateTxData() curr_tx_rounds " << curr_tx_rounds
1348 << " > max_tx_tries = " << max_tx_tries << endl;
1349 return false;
1350 }
1351 } else {
1352 listen_timer.resetCounter();
1353 backoff_timer.resetCounter();
1354
1355 setCurrTxRounds(mac_addr, seq_num);
1356 return true;
1357 }
1358}
1359
1360void
1361MMacUWSR::statePreTxData()
1362{
1363
1364 refreshState(UWSR_STATE_PRE_TX_DATA);
1365
1366 if (uwsr_debug)
1367 cout << NOW << " MMacUWSR(" << addr
1368 << ")::Time require to transmit a data packet: "
1369 << computeTxTime(UWSR_DATA_PKT) << endl;
1370 if (uwsr_debug)
1371 cout << NOW << " MMacUWSR(" << addr
1372 << ")::Time require to transmit an ack packet: "
1373 << computeTxTime(UWSR_ACK_PKT) << endl;
1374
1375 if (uwsr_debug)
1376 cout << NOW << " MMacUWSR(" << addr << ")::statePreTxData() " << endl;
1377 if (print_transitions)
1378 printStateInfo();
1379
1380 map<usrPair, Packet *>::iterator it_p;
1381 map<usrPair, AckTimer>::iterator it_a;
1382
1383 int curr_mac_addr;
1384 int seq_num;
1385
1386 it_p = mapPacket.begin();
1387 if (mapPacket.size() == 0) {
1388 stateIdle();
1389 } else if (mapAckTimer.size() == 0) {
1390 curr_data_pkt = (*it_p).second;
1391 if (uwsr_debug)
1392 cout << NOW << " MMacUWSR(" << addr
1393 << ")::Packet transmitting: " << curr_data_pkt << endl;
1394 seq_num = getPktSeqNum(curr_data_pkt);
1395 if (uwsr_debug)
1396 cout << NOW << " MMacUWSR(" << addr << ")::seq_num: " << seq_num
1397 << endl;
1398
1399 hdr_mac *mach = HDR_MAC(curr_data_pkt);
1400 curr_mac_addr = mach->macDA();
1401
1402 if (prepBeforeTx(curr_mac_addr, seq_num)) {
1403 if (prev_state == UWSR_STATE_LISTEN) {
1404 stateTxData();
1405 } else {
1406 stateCheckWaitTxExpired();
1407 }
1408 } else
1409 stateIdle();
1410 } else if (mapPacket.size() > mapAckTimer.size()) {
1411 // int seq_num;
1412 for (it_p = mapPacket.begin(); it_p != mapPacket.end(); it_p++) {
1413 it_a = mapAckTimer.find((*it_p).first);
1414 if ((*it_a).first != (*it_p).first) {
1415 // it_p = mapPacket.begin();
1416 curr_data_pkt = (*it_p).second;
1417 if (uwsr_debug)
1418 cout << NOW << " MMacUWSR(" << addr
1419 << ")::Packet transmitting: " << curr_data_pkt << endl;
1420 seq_num = getPktSeqNum(curr_data_pkt);
1421 if (uwsr_debug)
1422 cout << NOW << " MMacUWSR(" << addr
1423 << ")::seq_num: " << seq_num << endl;
1424 hdr_mac *mach = HDR_MAC(curr_data_pkt);
1425 curr_mac_addr = mach->macDA();
1426 if (prev_state == UWSR_STATE_TX_DATA) {
1427 if (curr_mac_addr == prv_mac_addr)
1428 break;
1429 // else continue;
1430 } else
1431 break;
1432 }
1433 }
1434 if (prepBeforeTx(curr_mac_addr, seq_num)) {
1435 if (prev_state == UWSR_STATE_LISTEN) {
1436 stateTxData();
1437 } else {
1438 stateCheckWaitTxExpired();
1439 }
1440 } else
1441 stateIdle();
1442 } else {
1443 stateCheckAckExpired();
1444 }
1445}
1446
1447void
1448MMacUWSR::stateWaitAck()
1449{
1450
1451 refreshState(UWSR_STATE_WAIT_ACK);
1452
1453 if (uwsr_debug)
1454 cout << NOW << " MMacUWSR(" << addr << ")::stateWaitAck() " << endl;
1455 if (print_transitions)
1456 printStateInfo();
1457}
1458
1459void
1460MMacUWSR::stateRxWaitAck()
1461{
1462 refreshState(UWSR_STATE_RX_WAIT_ACK);
1463
1464 if (print_transitions)
1465 printStateInfo();
1466}
1467
1468void
1469MMacUWSR::stateRxinPreTxData()
1470{
1471 refreshState(UWSR_STATE_RX_IN_PRE_TX_DATA);
1472
1473 if (print_transitions)
1474 printStateInfo();
1475}
1476
1477void
1478MMacUWSR::stateTxAck(int dest_addr)
1479{
1480
1481 refreshState(UWSR_STATE_TX_ACK);
1482
1483 if (uwsr_debug)
1484 cout << NOW << " MMacUWSR(" << addr << ")::stateTxAck() dest addr "
1485 << dest_addr << endl;
1486 if (print_transitions)
1487 printStateInfo();
1488
1489 txAck(dest_addr);
1490}
1491
1492void
1493MMacUWSR::stateRxData(Packet *data_pkt)
1494{
1495
1496 refreshState(UWSR_STATE_DATA_RX);
1497
1498 if (uwsr_debug)
1499 cout << NOW << " MMacUWSR(" << addr << ")::stateRxData() " << endl;
1500 refreshReason(UWSR_REASON_DATA_RX);
1501
1502 hdr_mac *mach = HDR_MAC(data_pkt);
1503 int dst_addr = mach->macSA();
1504 hdr_cmn *ch = hdr_cmn::access(data_pkt);
1505 ch->size() = ch->size() - HDR_size;
1506 recv_data_id = ch->uid();
1507 incrDataPktsRx();
1508 sendUp(data_pkt); // mando agli strati superiori il pkt
1509 stateTxAck(dst_addr);
1510}
1511
1512void
1513MMacUWSR::stateRxAck(Packet *p)
1514{
1515
1516 refreshState(UWSR_STATE_ACK_RX);
1517 if (uwsr_debug)
1518 cout << NOW << " MMacUWSR(" << addr << ")::stateRxAck() " << endl;
1519
1520 hdr_mac *mach = HDR_MAC(p);
1521 int curr_mac_addr = mach->macSA();
1522 int seq_num = getPktSeqNum(p);
1523
1524 map<usrPair, AckTimer>::iterator it_a;
1525 map<usrPair, txStartTime>::iterator it_ca;
1526
1527 it_a = mapAckTimer.find(make_pair(curr_mac_addr, seq_num));
1528 ((*it_a).second).stop();
1529
1530 it_ca = mapCalcAck.find(make_pair(curr_mac_addr, seq_num));
1531 double start_tx_time = ((*it_ca).second);
1532
1533 eraseItemFromPktQueue(curr_mac_addr, seq_num);
1534 eraseItemFromTxRounds(curr_mac_addr, seq_num);
1535 eraseItemFrommapAckTimer(curr_mac_addr, seq_num);
1536 eraseItemFrommapCalcAck(curr_mac_addr, seq_num);
1537 incrAckPktsRx();
1538
1539 incrAcksRcvIn1RTT();
1540 updateTxStatus(curr_mac_addr, getAcksRcvIn1RTT());
1541
1542 Packet::free(p);
1543
1544 refreshReason(UWSR_REASON_ACK_RX);
1545
1546 switch (prev_state) {
1547
1548 case UWSR_STATE_RX_IDLE:
1549 stateIdle();
1550 break;
1551
1552 case UWSR_STATE_RX_LISTEN:
1553 stateCheckListenExpired();
1554 break;
1555
1556 case UWSR_STATE_RX_BACKOFF:
1557 stateCheckBackoffExpired();
1558 break;
1559
1560 case UWSR_STATE_RX_WAIT_ACK:
1561 if (mapAckTimer.size() > 0)
1562 stateCheckAckExpired();
1563 else
1564 stateIdle();
1565 break;
1566
1567 case UWSR_STATE_RX_IN_PRE_TX_DATA: {
1568 if (mapPacket.size() == 0)
1569 stateIdle();
1570 else
1571 stateCheckWaitTxExpired();
1572 } break;
1573
1574 default:
1575
1576 cerr << NOW << " MMacUWSR(" << addr
1577 << ")::stateRxAck() logical error, prev state = "
1578 << status_info[prev_state] << endl;
1579 exit(1);
1580 }
1581}
1582
1583void
1584MMacUWSR::printStateInfo(double delay)
1585{
1586 if (uwsr_debug)
1587 cout << NOW << " MMacUWSR(" << addr << ")::printStateInfo() "
1588 << "from " << status_info[prev_state] << " to "
1589 << status_info[curr_state]
1590 << ". Reason: " << reason_info[last_reason] << endl;
1591
1592 if (curr_state == UWSR_STATE_BACKOFF) {
1593 fout << left << setw(10) << NOW << " MMacUWSR(" << addr
1594 << ")::printStateInfo() "
1595 << "from " << status_info[prev_state] << " to "
1596 << status_info[curr_state]
1597 << ". Reason: " << reason_info[last_reason]
1598 << ". Backoff duration = " << delay << endl;
1599 } else {
1600 fout << left << setw(10) << NOW << " MMacUWSR(" << addr
1601 << ")::printStateInfo() "
1602 << "from " << status_info[prev_state] << " to "
1603 << status_info[curr_state]
1604 << ". Reason: " << reason_info[last_reason] << endl;
1605 }
1606}
1607
1608void
1609MMacUWSR::waitForUser()
1610{
1611 std::string response;
1612 std::cout << "Press Enter to continue";
1613 std::getline(std::cin, response);
1614}
virtual void expire(Event *e)
What a node is going to do when a timer expire.
Definition uwsr.cpp:70
virtual void expire(Event *e)
What a node is going to do when a timer expire.
Definition uwsr.cpp:120
MMacUWSR *UWSR_TIMER_STATUS timer_status
< Pointer of MMacUWSR module.
Definition uwsr.h:381
This is the base class of MMacUWSR protocol, which is a derived class of MMac.
Definition uwsr.h:85
virtual void printStateInfo(double delay=0)
This methods print the state information of the nodes.
Definition uwsr.cpp:1584
virtual void stateCheckWaitTxExpired()
It checks whether the wait transmit timer is already expired while it was busy with other activities.
Definition uwsr.cpp:1161
AckTimer ack_timer
An object of the AckTimer class.
Definition uwsr.h:1225
@ UWSR_EXPIRED
Definition uwsr.h:180
int getBackoffCount()
It returns the number of time backoff counter is run in the whole communication period.
Definition uwsr.h:577
virtual bool checkMultipleTx(int rcv_mac_addr)
This method checks whether the node is capable of sending multiple packets in a single RTT.
Definition uwsr.cpp:495
virtual void stateTxData()
If a node has packet to transmits.
Definition uwsr.cpp:997
virtual void stateListen()
A short time which is used to sense the channel condision.
Definition uwsr.cpp:1257
UWSR_STATUS curr_state
Enum variable.
Definition uwsr.h:1233
ListenTimer listen_timer
An object of the ListenTimer class.
Definition uwsr.h:1227
WaitTxTimer wait_tx_timer
An object of the WaitTxTimer class.
Definition uwsr.h:1228
virtual double calcWaitTxTime(int mac_addr)
Calcultes the time a node has to wait before transmitting another packet in a single RTT.
Definition uwsr.cpp:459
MMacUWSR()
Constructor of MMacUWSR Class.
Definition uwsr.cpp:173
int uwsr_debug
Debuging flag.
Definition uwsr.h:1167
virtual void Mac2PhyStartTx(Packet *p)
It informs that a packet transmission started.
Definition uwsr.cpp:738
bool chkItemInmapTxRounds(int mac_addr, int seq_num)
handling transmission round
Definition uwsr.cpp:445
virtual void stateRxPacketNotForMe(Packet *p)
The receive packet is not intended for this node.
Definition uwsr.cpp:1030
virtual int getPktsCanSendIn1RTT(int mac_addr)
Number of packets a node can transmits to a receiving node in a single RTT.
Definition uwsr.cpp:406
virtual void stateTxAck(int dest_addr)
After receiving a Data packet the node sends an ACK packet.
Definition uwsr.cpp:1478
virtual bool prepBeforeTx(int mac_addr, int seq_num)
It checks how many times a packet is transmitted.
Definition uwsr.cpp:1323
virtual void stateIdle()
Node is in Idle state.
Definition uwsr.cpp:1222
double latest_ack_timeout
Latest timeout of an acknowledgement packet.
Definition uwsr.h:1216
double getAvgPktsTxIn1RTT()
Average number of packets transmitted in a single RTT.
Definition uwsr.h:1142
int curr_tx_rounds
How many times the same packet is (re)transmitted.
Definition uwsr.h:1188
virtual void stateCheckAckExpired()
It checks whether the ack timer is already expired while it was busy with other activities.
Definition uwsr.cpp:1106
virtual void Phy2MacStartRx(const Packet *p)
PHY layer informs the MAC layer that it is receiving a packet.
Definition uwsr.cpp:896
@ UWSR_REASON_BACKOFF_TIMEOUT
Definition uwsr.h:148
int max_tx_tries
Maximum number of retransmissions attempt.
Definition uwsr.h:1149
@ UWSR_STATE_IDLE
Definition uwsr.h:113
@ UWSR_STATE_PRE_TX_DATA
Definition uwsr.h:134
@ UWSR_STATE_LISTEN
Definition uwsr.h:121
@ UWSR_STATE_WAIT_ACK
Definition uwsr.h:117
virtual void stateBackoff()
If ACK packet is not received within the acknowledgement expire time.
Definition uwsr.cpp:1287
virtual void stateRxData(Packet *p)
It process the packet which is received.
Definition uwsr.cpp:1493
static map< UWSR_STATUS, string > status_info
Container which stores all the status information.
Definition uwsr.h:1242
virtual double getBackoffTime()
This function calculates the backoff duration and return the backoff time.It employs the exponential ...
Definition uwsr.cpp:669
virtual void Phy2MacEndTx(const Packet *p)
It infroms that a packet transmission end.
Definition uwsr.cpp:749
virtual void statePreTxData()
This method finds out whether there is any packet to be transmitted to the destination.
Definition uwsr.cpp:1361
double alpha_
This variable is used to tune the RTT.
Definition uwsr.h:1158
virtual void Phy2MacEndRx(Packet *p)
PHY layer informs the MAC layer that the reception of the packet is over.
Definition uwsr.cpp:935
virtual void exitBackoff()
It stops the backoff timer.
Definition uwsr.cpp:663
BackOffTimer backoff_timer
An object of the BackOffTimer class.
Definition uwsr.h:1226
virtual void stateCheckListenExpired()
It checks whether the listen timer is already expired while it was busy with other activities.
Definition uwsr.cpp:1075
virtual void stateCheckBackoffExpired()
It checks whether the backoff timer is already expired while it was busy with other activities.
Definition uwsr.cpp:1135
virtual void stateRxAck(Packet *p)
The node comes to this state if it receives an ACK packet.
Definition uwsr.cpp:1513
virtual void putRTTInMap(int mac_addr, double rtt)
Put RTT of all the nodes which are whithin the transmission range of a node.
Definition uwsr.cpp:381
virtual void stateWaitAck()
After transmitting a Data packet, a node waits for the ACK packet.
Definition uwsr.cpp:1448
virtual void refreshReason(UWSR_REASON_STATUS reason)
To know the reason why a node in this current state.
Definition uwsr.h:734
Class that handles the timers in T-LOHI nodes.
Class that represents the binding with tcl scripting language.
Definition uwsr.cpp:53
TclObject * create(int, const char *const *)
Definition uwsr.cpp:63
UWSRModuleClass()
Constructor of the class.
Definition uwsr.cpp:58
@ DATA
UWSRModuleClass class_module_uwsr
UnderWater Selective Repeat (UWSR) this is basically a selective repeat ARQ protocol that coordinates...