59 : TclClass(
"Module/UW/USR")
73 module->incrPktsLostCount();
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;
85 module->refreshReason(UWSR_REASON_ACK_TIMEOUT);
86 module->eraseExpiredItemsFrommapAckandCalc();
87 module->stateBackoff();
89 if (module->uwsr_debug)
90 cout << NOW << " MMacUWSR(
" << module->addr
91 << ")::AckTimer::expired() in state
"
92 << module->status_info[module->curr_state] << endl;
97MMacUWSR::BackOffTimer::expire(Event *e)
99 timer_status = UWSR_EXPIRED;
100 if (module->curr_state == UWSR_STATE_BACKOFF) {
102 if (module->uwsr_debug)
103 cout << NOW << " MMacUWSR(
" << module->addr
104 << ") timer
expire() current state = "
106 << "; backoff expired, next state = "
113 if (module->uwsr_debug)
114 cout << NOW <<
" MMacUWSR(" <<
module->addr
115 << ")::BackoffTimer::expired() " << endl;
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;
133 module->refreshReason(UWSR_REASON_LISTEN_TIMEOUT);
134 module->statePreTxData();
136 if (module->uwsr_debug)
137 cout << NOW << " MMacUWSR(
" << module->addr
138 << ")::ListenTimer::expired()
" << endl;
143MMacUWSR::WaitTxTimer::expire(Event *e)
145 timer_status = UWSR_EXPIRED;
147 if (module->curr_state == UWSR_STATE_PRE_TX_DATA ||
148 module->curr_state == UWSR_STATE_RX_IN_PRE_TX_DATA) {
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;
157 module->refreshReason(UWSR_REASON_WAIT_TX_TIMEOUT);
158 module->stateTxData();
160 if (module->uwsr_debug)
161 cout << NOW << " MMacUWSR(
" << module->addr
162 << ")::wait tx timer expired()
" << endl;
166const double MMacUWSR::prop_speed = 1500.0;
167bool MMacUWSR::initialized = false;
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;
174 : wait_tx_timer(this)
177 , backoff_timer(this)
179 , last_sent_data_id(-1)
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)
203 , pkts_lost_counter(0)
208 , latest_ack_timeout(0)
211 mac2phy_delay_ = 1e-19;
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);
231 if (max_tx_tries <= 0)
232 max_tx_tries = INT_MAX;
234 has_buffer_queue = true;
235 if (listen_time <= 0.0)
243// TCL command interpreter
245MMacUWSR::command(int argc, const char *const *argv)
247 Tcl &tcl = Tcl::instance();
249 if (strcasecmp(argv[1], "initialize
") == 0) {
250 if (initialized == false)
252 if (print_transitions)
253 fout.open("/tmp/UWSRstateTransitions.txt
", ios_base::app);
255 } else if (strcasecmp(argv[1], "printTransitions
") == 0) {
256 print_transitions = true;
260 else if (strcasecmp(argv[1], "getQueueSize
") == 0) {
261 tcl.resultf("%d
", mapPacket.size());
264 tcl.resultf("%d
", getBackoffCount());
267 tcl.resultf("%f
", getAvgPktsTxIn1RTT());
270 } else if (argc == 3) {
271 if (strcasecmp(argv[1], "setMacAddr
") == 0) {
272 addr = atoi(argv[2]);
274 cout << "UwSR MAC address of current node is
" << addr << endl;
278 return MMac::command(argc, argv);
287 if ((print_transitions) && (system(NULL))) {
288 system("rm -f /tmp/UWSRstateTransitions.txt
");
289 system("touch /tmp/UWSRstateTransitions.txt
");
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
";
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
";
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
";
344MMacUWSR::updateTxStatus(macAddress mac_addr, int rcv_acks)
346 map<macAddress, txStatusPair>::iterator it_tx;
347 it_tx = mapTxStatus.find(mac_addr);
349 if (it_tx == mapTxStatus.end()) {
351 make_pair(mac_addr, make_pair(getPktsSentIn1RTT(), rcv_acks)));
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;
361MMacUWSR::calWindowSize(macAddress mac_addr)
363 map<macAddress, txStatusPair>::iterator it_tx;
364 it_tx = mapTxStatus.find(mac_addr);
366 if (it_tx == mapTxStatus.end()) {
369 if ((it_tx->second).first == (it_tx->second).second)
370 window_size = max(window_size, ((it_tx->second).first + 1));
372 window_size = (floor((it_tx->second).first * var_k));
375 cout << NOW << " MMacUWSR(
" << addr << ")::window size
"
376 << max(1, window_size) << endl;
377 return max(1, window_size);
381MMacUWSR::putRTTInMap(int mac_addr, double rtt)
388 << mac_addr << "rtt
" << rtt << "time
" << time << endl;
390 map<macAddress, rttPair>::iterator it_d;
391 it_d = mapRTT.find(mac_addr);
393 if (it_d == mapRTT.end()) {
394 mapRTT.insert(make_pair(mac_addr, make_pair(rtt, time)));
396 if (rtt != (it_d->second).first || time != (it_d->second).second) {
397 (it_d->second).first = rtt;
398 (it_d->second).second = time;
400 // do nothing. keep the RTT saved in the map
406MMacUWSR::getPktsCanSendIn1RTT(int mac_addr)
413 int pkts_can_send_1RTT = 1;
415 map<macAddress, rttPair>::iterator it_d = mapRTT.find(mac_addr);
417 if (it_d != mapRTT.end()) {
419 double tx_time = (computeTxTime(UWSR_DATA_PKT) +
420 computeTxTime(UWSR_ACK_PKT) + guard_time);
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);
427 pkts_can_send_1RTT = max(1, (int) (floor(apprx_curr_rtt / tx_time)));
432 << ")::No pkts can send in 1 RTT is
" << pkts_can_send_1RTT
435 cout << NOW << " MMacUWSR(
" << addr << ")::Window size:
" << window_size
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);
445MMacUWSR::chkItemInmapTxRounds(int mac_addr, int seq_num)
447 map<usrPair, txRounds>::iterator it_t;
448 it_t = mapTxRounds.find(make_pair(mac_addr, seq_num));
452 if (it_t != mapTxRounds.end())
459MMacUWSR::calcWaitTxTime(int mac_addr)
470 map<macAddress, rttPair>::iterator it_d;
471 it_d = mapRTT.find(mac_addr);
473 if (it_d == mapRTT.end()) {
475 << ")::
calcWaitTxTime() is accessed in inappropriate time
" << endl;
478 rtt_time = (it_d->second).first;
479 pkts_can_tx = getPktsCanSendIn1RTT(mac_addr);
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));
486 cout << NOW << " MMacUWSR(
" << addr << ")::round trip time
" << rtt_time
490 << wait_time << endl;
495MMacUWSR::checkMultipleTx(int rcv_mac_addr)
502 Packet *nxt_data_pkt;
504 map<usrPair, Packet *>::iterator it_p;
505 map<usrPair, AckTimer>::iterator it_a;
509 if (mapPacket.size() == 0)
511 else if (mapPacket.size() <= mapAckTimer.size())
513 else if (getPktsCanSendIn1RTT(rcv_mac_addr) < 2)
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;
522 << ")::Next Packet transmitting:
" << nxt_data_pkt
524 hdr_mac *mach = HDR_MAC(nxt_data_pkt);
525 nxt_mac_addr = mach->macDA();
526 if (rcv_mac_addr == nxt_mac_addr)
532 if (rcv_mac_addr == nxt_mac_addr &&
533 getPktsCanSendIn1RTT(rcv_mac_addr) > getPktsSentIn1RTT())
541MMacUWSR::checkAckTimer(CHECK_ACK_TIMER type)
544 int iteration_count = 0;
545 int active_count = 0;
547 int expired_count = 0;
550 map<usrPair, AckTimer>::iterator it_a;
552 for (it_a = mapAckTimer.begin(); it_a != mapAckTimer.end(); it_a++) {
553 if (((*it_a).second).isActive()) {
555 } else if (((*it_a).second).isExpired()) {
557 } else if (((*it_a).second).isIdle()) {
560 cerr << "Ack
Timer is in wrong state
" << endl;
563 iteration_count += 1;
568 << ")::No of item in ack map:
" << mapAckTimer.size() << endl;
571 << ")::No of iteration count:
" << iteration_count << endl;
574 << ")::No of active count:
" << active_count << endl;
577 << ")::No of expired count:
" << expired_count << endl;
580 << ")::No of idle count:
" << idle_count << endl;
582 if (type == CHECK_ACTIVE) {
583 if (mapAckTimer.size() == 0) {
586 value = floor(active_count / mapAckTimer.size());
588 } else if (type == CHECK_EXPIRED) {
589 value = expired_count;
590 } else if (type == CHECK_IDLE) {
595 << ")::Ack
Timer is in wrong state
" << endl;
600 cout << NOW << " MMacUWSR(
" << addr << ")::returning value:
" << value
606MMacUWSR::eraseExpiredItemsFrommapAckandCalc()
611 << ")::Erasing expired items from map ack and calc
" << endl;
613 map<usrPair, AckTimer>::iterator it_a1, it_a2;
615 it_a1 = mapAckTimer.begin();
617 while (it_a1 != mapAckTimer.end()) {
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);
634MMacUWSR::computeTxTime(UWSR_PKT_TYPE type)
636 map<usrPair, Packet *>::iterator it_p;
639 Packet *temp_data_pkt;
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();
648 temp_data_pkt = Packet::alloc();
649 hdr_cmn *ch = HDR_CMN(temp_data_pkt);
650 ch->size() = HDR_size + max_payload;
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;
657 duration = Mac2PhyTxDuration(temp_data_pkt);
658 Packet::free(temp_data_pkt);
663MMacUWSR::exitBackoff()
665 backoff_timer.stop();
669MMacUWSR::getBackoffTime()
671 incrTotalBackoffTimes();
672 double random = RNG::defaultrng()->uniform_double();
674 backoff_timer.incrCounter();
675 double counter = backoff_timer.getCounter();
676 if (counter > max_backoff_counter)
677 counter = max_backoff_counter;
679 double backoff_duration =
680 backoff_tuner * random * 2.0 * ACK_timeout * pow(2.0, counter);
681 backoffSumDuration(backoff_duration);
686 << " latest ack timeout =
" << (latest_ack_timeout - NOW) << endl;
689 return max((latest_ack_timeout - NOW) + wait_constant, backoff_duration);
693MMacUWSR::recvFromUpperLayers(Packet *p)
695 if (((has_buffer_queue == true) && (mapPacket.size() < buffer_pkts)) ||
696 (has_buffer_queue == false)) {
697 initPkt(p, UWSR_DATA_PKT);
702 if (curr_state == UWSR_STATE_IDLE) {
703 refreshReason(UWSR_REASON_DATA_PENDING);
707 incrDiscardedPktsTx();
708 drop(p, 1, UWSR_DROP_REASON_BUFFER_FULL);
713MMacUWSR::initPkt(Packet *p, UWSR_PKT_TYPE type, int dest_addr)
715 hdr_cmn *ch = hdr_cmn::access(p);
716 hdr_mac *mach = HDR_MAC(p);
718 int curr_size = ch->size();
722 case (UWSR_DATA_PKT): {
723 ch->size() = curr_size + HDR_size;
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;
738MMacUWSR::Mac2PhyStartTx(Packet *p)
745 MMac::Mac2PhyStartTx(p);
749MMacUWSR::Phy2MacEndTx(const Packet *p)
752 hdr_cmn *ch = hdr_cmn::access(p);
753 int seq_num = ch->uid();
755 hdr_mac *mach = HDR_MAC(p);
756 int dst_mac_addr = mach->macDA();
757 prv_mac_addr = dst_mac_addr;
764 << dst_mac_addr << endl;
766 switch (curr_state) {
768 case (UWSR_STATE_TX_DATA): {
769 refreshReason(UWSR_REASON_DATA_TX);
771 incrPktsSentIn1RTT();
772 double wait_time, ack_time;
773 double ack_timeout_time;
775 map<int, rttPair>::iterator it_d;
776 it_d = mapRTT.find(dst_mac_addr);
778 if (it_d == mapRTT.end())
779 ack_timeout_time = ACK_timeout + 2 * wait_constant;
782 getRTTInMap(dst_mac_addr) + 2 * wait_constant;
784 ack_time = NOW + ack_timeout_time;
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);
796 if (ack_time > latest_ack_timeout)
797 latest_ack_timeout = ack_time;
803 if (checkMultipleTx(dst_mac_addr)) {
807 << status_info[curr_state] << " to
"
808 << status_info[UWSR_STATE_PRE_TX_DATA] << endl;
810 wait_time = calcWaitTxTime(dst_mac_addr);
811 wait_tx_timer.stop();
812 wait_tx_timer.incrCounter();
813 wait_tx_timer.schedule(wait_time);
823 << status_info[curr_state] << " to
"
824 << status_info[UWSR_STATE_WAIT_ACK] << endl;
826 updateTxStatus(dst_mac_addr, 0);
833 case (UWSR_STATE_TX_ACK): {
834 refreshReason(UWSR_REASON_ACK_TX);
836 if (prev_prev_state == UWSR_STATE_RX_BACKOFF) {
840 << status_info[curr_state] << " to
"
841 << status_info[UWSR_STATE_CHK_BACKOFF_TIMEOUT] << endl;
843 stateCheckBackoffExpired();
844 } else if (prev_prev_state == UWSR_STATE_RX_WAIT_ACK) {
848 << status_info[curr_state] << " to
"
849 << status_info[UWSR_STATE_CHK_BACKOFF_TIMEOUT] << endl;
851 stateCheckAckExpired();
852 } else if (prev_prev_state == UWSR_STATE_RX_IN_PRE_TX_DATA) {
856 << status_info[curr_state] << " to
"
857 << status_info[UWSR_STATE_CHK_BACKOFF_TIMEOUT] << endl;
859 stateCheckWaitTxExpired();
860 } else if (prev_prev_state == UWSR_STATE_RX_LISTEN) {
864 << status_info[curr_state] << " to
"
865 << status_info[UWSR_STATE_CHK_LISTEN_TIMEOUT] << endl;
867 stateCheckListenExpired();
868 } else if (prev_prev_state == UWSR_STATE_RX_IDLE) {
872 << status_info[curr_state] << " to
"
873 << status_info[UWSR_STATE_IDLE] << endl;
878 << ")::
Phy2MacEndTx() logical error in timers, current
"
880 << status_info[curr_state] << endl;
889 << status_info[curr_state] << endl;
896MMacUWSR::Phy2MacStartRx(const Packet *p)
902 refreshReason(UWSR_REASON_START_RX);
904 switch (curr_state) {
906 case (UWSR_STATE_IDLE):
910 case (UWSR_STATE_LISTEN):
914 case (UWSR_STATE_BACKOFF):
918 case (UWSR_STATE_PRE_TX_DATA):
919 stateRxinPreTxData();
922 case (UWSR_STATE_WAIT_ACK):
929 << status_info[curr_state] << endl;
935MMacUWSR::Phy2MacEndRx(Packet *p)
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);
943 int source_mac = mach->macSA();
944 int dest_mac = mach->macDA();
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);
951 double distance = diff_time * prop_speed;
952 int seq_num = getPktSeqNum(p);
953 map<usrPair, AckTimer>::iterator it_a;
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
"
971 refreshReason(UWSR_REASON_PKT_ERROR);
972 drop(p, 1, UWSR_DROP_REASON_ERROR);
973 stateRxPacketNotForMe(NULL);
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);
982 drop(p, 1, UWSR_DROP_REASON_ERROR);
983 stateRxPacketNotForMe(NULL);
986 refreshReason(UWSR_REASON_DATA_RX);
990 refreshReason(UWSR_REASON_PKT_NOT_FOR_ME);
991 stateRxPacketNotForMe(p);
997MMacUWSR::stateTxData()
999 refreshState(UWSR_STATE_TX_DATA);
1004 Packet *data_pkt = curr_data_pkt->copy(); // copio pkt
1005 int seq_num = getPktSeqNum(data_pkt);
1006 int mac_addr = getMacAddress(data_pkt);
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);
1016 Mac2PhyStartTx(data_pkt);
1020MMacUWSR::txAck(int dest_addr)
1022 Packet *ack_pkt = Packet::alloc();
1023 initPkt(ack_pkt, UWSR_ACK_PKT, dest_addr);
1026 Mac2PhyStartTx(ack_pkt);
1030MMacUWSR::stateRxPacketNotForMe(Packet *p)
1033 cout << NOW << " MMacUWSR(
" << addr
1040 refreshState(UWSR_STATE_WRONG_PKT_RX);
1042 switch (prev_state) {
1044 case UWSR_STATE_RX_IDLE:
1048 case UWSR_STATE_RX_LISTEN:
1049 stateCheckListenExpired();
1052 case UWSR_STATE_RX_BACKOFF:
1053 stateCheckBackoffExpired();
1056 case UWSR_STATE_RX_IN_PRE_TX_DATA:
1057 stateCheckWaitTxExpired();
1060 case UWSR_STATE_RX_WAIT_ACK:
1061 stateCheckAckExpired();
1065 cerr << NOW << " MMacUWSR(
" << addr
1067 << status_info[curr_state] << endl;
1068 curr_state = prev_state;
1069 prev_state = prev_prev_state;
1075MMacUWSR::stateCheckListenExpired()
1077 refreshState(UWSR_STATE_CHK_LISTEN_TIMEOUT);
1082 if (print_transitions)
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))
1097 cerr << NOW << " MMacUWSR(
" << addr
1099 "current timer state =
"
1100 << status_info[curr_state] << endl;
1106MMacUWSR::stateCheckAckExpired()
1108 refreshState(UWSR_STATE_CHK_ACK_TIMEOUT);
1113 if (print_transitions)
1116 if (mapAckTimer.size() == 0)
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();
1126 cerr << NOW << " MMacUWSR(
" << addr
1129 << status_info[curr_state] << endl;
1135MMacUWSR::stateCheckBackoffExpired()
1137 refreshState(UWSR_STATE_CHK_BACKOFF_TIMEOUT);
1142 if (print_transitions)
1144 if (backoff_timer.isActive()) {
1145 refreshReason(UWSR_REASON_BACKOFF_PENDING);
1147 } else if (backoff_timer.isExpired()) {
1148 refreshReason(UWSR_REASON_BACKOFF_TIMEOUT);
1152 cerr << NOW << " MMacUWSR(
" << addr
1154 "current timer state =
"
1155 << status_info[curr_state] << endl;
1161MMacUWSR::stateCheckWaitTxExpired()
1164 refreshState(UWSR_STATE_CHK_WAIT_TX_TIMEOUT);
1170 if (print_transitions)
1173 if (checkAckTimer(CHECK_EXPIRED) > 0) {
1174 refreshReason(UWSR_REASON_ACK_TIMEOUT);
1175 eraseExpiredItemsFrommapAckandCalc();
1179 else if (checkAckTimer(CHECK_ACTIVE)) {
1181 cout << NOW << " MMacUWSR(
" << addr
1182 << ")::wait tx is active:
" << wait_tx_timer.isActive() << endl;
1184 cout << NOW << " MMacUWSR(
" << addr
1185 << ")::wait tx is expired:
" << wait_tx_timer.isExpired()
1188 cout << NOW << " MMacUWSR(
" << addr
1189 << ")::wait tx is idle:
" << wait_tx_timer.isIdle() << endl;
1191 if (wait_tx_timer.isActive()) {
1192 refreshReason(UWSR_REASON_WAIT_TX_PENDING);
1193 refreshState(UWSR_STATE_PRE_TX_DATA);
1196 else if (wait_tx_timer.isExpired()) {
1197 refreshReason(UWSR_REASON_WAIT_TX_TIMEOUT);
1198 refreshState(UWSR_STATE_PRE_TX_DATA);
1203 cerr << NOW << " MMacUWSR(
" << addr
1205 "current timer state =
"
1206 << status_info[curr_state] << endl;
1213 cerr << NOW << " MMacUWSR(
" << addr
1216 << status_info[curr_state] << endl;
1222MMacUWSR::stateIdle()
1227 cout << NOW << " MMacUWSR(
" << addr
1228 << ")::
stateIdle(), Pkts sent in one RTT:
" << getPktsSentIn1RTT()
1230 rstPktsSentIn1RTT();
1232 backoff_timer.stop();
1233 listen_timer.stop();
1234 wait_tx_timer.stop();
1236 refreshState(UWSR_STATE_IDLE);
1238 if (print_transitions)
1241 if (!mapPacket.empty()) {
1242 refreshReason(UWSR_REASON_LISTEN);
1248MMacUWSR::stateRxIdle()
1250 refreshState(UWSR_STATE_RX_IDLE);
1252 if (print_transitions)
1257MMacUWSR::stateListen()
1259 listen_timer.stop();
1260 refreshState(UWSR_STATE_LISTEN);
1262 listen_timer.incrCounter();
1265 listen_time * RNG::defaultrng()->uniform_double() + wait_constant;
1268 cout << NOW << " MMacUWSR(
" << addr
1269 << ")::
stateListen() listen time =
" << time << endl;
1271 if (print_transitions)
1274 listen_timer.schedule(time);
1278MMacUWSR::stateRxListen()
1280 refreshState(UWSR_STATE_RX_LISTEN);
1282 if (print_transitions)
1287MMacUWSR::stateBackoff()
1291 wait_tx_timer.stop();
1293 refreshState(UWSR_STATE_BACKOFF);
1297 if (backoff_timer.isFrozen())
1298 backoff_timer.unFreeze();
1300 backoff_timer.schedule(getBackoffTime());
1302 cout << NOW << " MMacUWSR(
" << addr
1303 << ")::
stateBackoff() get backoff time
" << getBackoffTime()
1308 if (print_transitions)
1309 printStateInfo(backoff_timer.getDuration());
1313MMacUWSR::stateRxBackoff()
1315 backoff_timer.freeze();
1316 refreshState(UWSR_STATE_RX_BACKOFF);
1318 if (print_transitions)
1323MMacUWSR::prepBeforeTx(int mac_addr, int seq_num)
1327 cout << NOW << " MMacUWSR(
" << addr
1329 << chkItemInmapTxRounds(mac_addr, seq_num) << endl;
1331 if (chkItemInmapTxRounds(mac_addr, seq_num)) {
1332 if (getCurrTxRounds(mac_addr, seq_num) < max_tx_tries + 1) {
1334 last_sent_data_id = seq_num;
1335 incrCurrTxRounds(mac_addr, seq_num);
1338 eraseItemFromPktQueue(mac_addr, seq_num);
1339 eraseItemFromTxRounds(mac_addr, seq_num);
1340 eraseItemFrommapAckTimer(mac_addr, seq_num);
1341 incrDroppedPktsTx();
1343 refreshReason(UWSR_REASON_MAX_TX_TRIES);
1346 cout << NOW << " MMacUWSR(
" << addr
1352 listen_timer.resetCounter();
1353 backoff_timer.resetCounter();
1355 setCurrTxRounds(mac_addr, seq_num);
1361MMacUWSR::statePreTxData()
1364 refreshState(UWSR_STATE_PRE_TX_DATA);
1367 cout << NOW << " MMacUWSR(
" << addr
1368 << ")::Time require to transmit a data packet:
"
1369 << computeTxTime(UWSR_DATA_PKT) << endl;
1371 cout << NOW << " MMacUWSR(
" << addr
1372 << ")::Time require to transmit an ack packet:
"
1373 << computeTxTime(UWSR_ACK_PKT) << endl;
1377 if (print_transitions)
1380 map<usrPair, Packet *>::iterator it_p;
1381 map<usrPair, AckTimer>::iterator it_a;
1386 it_p = mapPacket.begin();
1387 if (mapPacket.size() == 0) {
1389 } else if (mapAckTimer.size() == 0) {
1390 curr_data_pkt = (*it_p).second;
1392 cout << NOW << " MMacUWSR(
" << addr
1393 << ")::Packet transmitting:
" << curr_data_pkt << endl;
1394 seq_num = getPktSeqNum(curr_data_pkt);
1396 cout << NOW << " MMacUWSR(
" << addr << ")::seq_num:
" << seq_num
1399 hdr_mac *mach = HDR_MAC(curr_data_pkt);
1400 curr_mac_addr = mach->macDA();
1402 if (prepBeforeTx(curr_mac_addr, seq_num)) {
1403 if (prev_state == UWSR_STATE_LISTEN) {
1406 stateCheckWaitTxExpired();
1410 } else if (mapPacket.size() > mapAckTimer.size()) {
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;
1418 cout << NOW << " MMacUWSR(
" << addr
1419 << ")::Packet transmitting:
" << curr_data_pkt << endl;
1420 seq_num = getPktSeqNum(curr_data_pkt);
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)
1434 if (prepBeforeTx(curr_mac_addr, seq_num)) {
1435 if (prev_state == UWSR_STATE_LISTEN) {
1438 stateCheckWaitTxExpired();
1443 stateCheckAckExpired();
1448MMacUWSR::stateWaitAck()
1451 refreshState(UWSR_STATE_WAIT_ACK);
1455 if (print_transitions)
1460MMacUWSR::stateRxWaitAck()
1462 refreshState(UWSR_STATE_RX_WAIT_ACK);
1464 if (print_transitions)
1469MMacUWSR::stateRxinPreTxData()
1471 refreshState(UWSR_STATE_RX_IN_PRE_TX_DATA);
1473 if (print_transitions)
1478MMacUWSR::stateTxAck(int dest_addr)
1481 refreshState(UWSR_STATE_TX_ACK);
1485 << dest_addr << endl;
1486 if (print_transitions)
1493MMacUWSR::stateRxData(Packet *data_pkt)
1496 refreshState(UWSR_STATE_DATA_RX);
1500 refreshReason(UWSR_REASON_DATA_RX);
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();
1508 sendUp(data_pkt); // mando agli strati superiori il pkt
1509 stateTxAck(dst_addr);
1513MMacUWSR::stateRxAck(Packet *p)
1516 refreshState(UWSR_STATE_ACK_RX);
1520 hdr_mac *mach = HDR_MAC(p);
1521 int curr_mac_addr = mach->macSA();
1522 int seq_num = getPktSeqNum(p);
1524 map<usrPair, AckTimer>::iterator it_a;
1525 map<usrPair, txStartTime>::iterator it_ca;
1527 it_a = mapAckTimer.find(make_pair(curr_mac_addr, seq_num));
1528 ((*it_a).second).stop();
1530 it_ca = mapCalcAck.find(make_pair(curr_mac_addr, seq_num));
1531 double start_tx_time = ((*it_ca).second);
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);
1539 incrAcksRcvIn1RTT();
1540 updateTxStatus(curr_mac_addr, getAcksRcvIn1RTT());
1544 refreshReason(UWSR_REASON_ACK_RX);
1546 switch (prev_state) {
1548 case UWSR_STATE_RX_IDLE:
1552 case UWSR_STATE_RX_LISTEN:
1553 stateCheckListenExpired();
1556 case UWSR_STATE_RX_BACKOFF:
1557 stateCheckBackoffExpired();
1560 case UWSR_STATE_RX_WAIT_ACK:
1561 if (mapAckTimer.size() > 0)
1562 stateCheckAckExpired();
1567 case UWSR_STATE_RX_IN_PRE_TX_DATA: {
1568 if (mapPacket.size() == 0)
1571 stateCheckWaitTxExpired();
1576 cerr << NOW << " MMacUWSR(
" << addr
1577 << ")::
stateRxAck() logical error, prev state =
"
1578 << status_info[prev_state] << endl;
1584MMacUWSR::printStateInfo(double delay)
1588 << "from
" << status_info[prev_state] << " to
"
1589 << status_info[curr_state]
1590 << ". Reason:
" << reason_info[last_reason] << endl;
1592 if (curr_state == UWSR_STATE_BACKOFF) {
1593 fout << left << setw(10) << NOW << " MMacUWSR(
" << addr
1595 << "from
" << status_info[prev_state] << " to
"
1596 << status_info[curr_state]
1597 << ". Reason:
" << reason_info[last_reason]
1598 << ". Backoff duration =
" << delay << endl;
1600 fout << left << setw(10) << NOW << " MMacUWSR(
" << addr
1602 << "from
" << status_info[prev_state] << " to
"
1603 << status_info[curr_state]
1604 << ". Reason:
" << reason_info[last_reason] << endl;
1609MMacUWSR::waitForUser()
1611 std::string response;
1612 std::cout << "Press Enter to continue
";
1613 std::getline(std::cin, response);
virtual void expire(Event *e)
What a node is going to do when a timer expire.
virtual void expire(Event *e)
What a node is going to do when a timer expire.
MMacUWSR *UWSR_TIMER_STATUS timer_status
< Pointer of MMacUWSR module.
This is the base class of MMacUWSR protocol, which is a derived class of MMac.
virtual void printStateInfo(double delay=0)
This methods print the state information of the nodes.
virtual void stateCheckWaitTxExpired()
It checks whether the wait transmit timer is already expired while it was busy with other activities.
AckTimer ack_timer
An object of the AckTimer class.
int getBackoffCount()
It returns the number of time backoff counter is run in the whole communication period.
virtual bool checkMultipleTx(int rcv_mac_addr)
This method checks whether the node is capable of sending multiple packets in a single RTT.
virtual void stateTxData()
If a node has packet to transmits.
virtual void stateListen()
A short time which is used to sense the channel condision.
UWSR_STATUS curr_state
Enum variable.
ListenTimer listen_timer
An object of the ListenTimer class.
WaitTxTimer wait_tx_timer
An object of the WaitTxTimer class.
virtual double calcWaitTxTime(int mac_addr)
Calcultes the time a node has to wait before transmitting another packet in a single RTT.
MMacUWSR()
Constructor of MMacUWSR Class.
int uwsr_debug
Debuging flag.
virtual void Mac2PhyStartTx(Packet *p)
It informs that a packet transmission started.
bool chkItemInmapTxRounds(int mac_addr, int seq_num)
handling transmission round
virtual void stateRxPacketNotForMe(Packet *p)
The receive packet is not intended for this node.
virtual int getPktsCanSendIn1RTT(int mac_addr)
Number of packets a node can transmits to a receiving node in a single RTT.
virtual void stateTxAck(int dest_addr)
After receiving a Data packet the node sends an ACK packet.
virtual bool prepBeforeTx(int mac_addr, int seq_num)
It checks how many times a packet is transmitted.
virtual void stateIdle()
Node is in Idle state.
double latest_ack_timeout
Latest timeout of an acknowledgement packet.
double getAvgPktsTxIn1RTT()
Average number of packets transmitted in a single RTT.
int curr_tx_rounds
How many times the same packet is (re)transmitted.
virtual void stateCheckAckExpired()
It checks whether the ack timer is already expired while it was busy with other activities.
virtual void Phy2MacStartRx(const Packet *p)
PHY layer informs the MAC layer that it is receiving a packet.
@ UWSR_REASON_BACKOFF_TIMEOUT
int max_tx_tries
Maximum number of retransmissions attempt.
virtual void stateBackoff()
If ACK packet is not received within the acknowledgement expire time.
virtual void stateRxData(Packet *p)
It process the packet which is received.
static map< UWSR_STATUS, string > status_info
Container which stores all the status information.
virtual double getBackoffTime()
This function calculates the backoff duration and return the backoff time.It employs the exponential ...
virtual void Phy2MacEndTx(const Packet *p)
It infroms that a packet transmission end.
virtual void statePreTxData()
This method finds out whether there is any packet to be transmitted to the destination.
double alpha_
This variable is used to tune the RTT.
virtual void Phy2MacEndRx(Packet *p)
PHY layer informs the MAC layer that the reception of the packet is over.
virtual void exitBackoff()
It stops the backoff timer.
BackOffTimer backoff_timer
An object of the BackOffTimer class.
virtual void stateCheckListenExpired()
It checks whether the listen timer is already expired while it was busy with other activities.
virtual void stateCheckBackoffExpired()
It checks whether the backoff timer is already expired while it was busy with other activities.
virtual void stateRxAck(Packet *p)
The node comes to this state if it receives an ACK packet.
virtual void putRTTInMap(int mac_addr, double rtt)
Put RTT of all the nodes which are whithin the transmission range of a node.
virtual void stateWaitAck()
After transmitting a Data packet, a node waits for the ACK packet.
virtual void refreshReason(UWSR_REASON_STATUS reason)
To know the reason why a node in this current state.
Class that handles the timers in T-LOHI nodes.
Class that represents the binding with tcl scripting language.
TclObject * create(int, const char *const *)
UWSRModuleClass()
Constructor of the class.
UWSRModuleClass class_module_uwsr
UnderWater Selective Repeat (UWSR) this is basically a selective repeat ARQ protocol that coordinates...