1 / 54

Implementing RTS/CTS in ns-2 for Efficient Data Transmission

Learn how RTS/CTS, NAV, and back-off timers are implemented in ns-2 for better wireless communication. Understand the packet sending process and frame structure in MAC layer.

belk
Download Presentation

Implementing RTS/CTS in ns-2 for Efficient Data Transmission

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. NS2 HW3 2006/9/20 雷喻翔

  2. Today’s Outline • How is the RTS/CTS implemented? • Is the default setting for RTS/CTS on or off in ns-2? • How is the NAV implemented? • How is the back-off timer implemented?

  3. Today’s Outline • How is the RTS/CTS implemented? • Is the default setting for RTS/CTS on or off in ns-2? • How is the NAV implemented? • How is the back-off timer implemented?

  4. DCF Four-way Two-way sender receiver sender receiver DIFS DIFS RTS data SIFS SIFS CTS ACK SIFS data SIFS ACK

  5. DCF with four-way handshaking (cont.)

  6. How is the RTS/CTS implemented? • Sending a packet (no errors) recv() -> send() -> sendDATA() and sendRTS() -> start defer timer -> deferHandler() -> check_pktRTS() -> transmit() -> recv() -> receive timer started -> recv_timer() -> recvCTS() -> tx_resume() -> start defer timer -> rx_resume() -> deferHandler() -> check_pktTx() -> transmit() -> recv() -> receive timer started -> recv_timer() -> recvACK() -> tx_resume() -> callback_ -> rx_resume() -> done! receiver

  7. recv() void Mac802_11::recv(Packet *p, Handler *h) { struct hdr_cmn *hdr = HDR_CMN(p); assert(initialized()); if( hdr->direction() == hdr_cmn::DOWN ) { send(p, h); return; } if(tx_active_ && hdr->error() == 0) { hdr->error() = 1; } if(rx_state_ == MAC_IDLE) { setRxState(MAC_RECV); pktRx_ = p; mhRecv_.start(txtime(p)); } else { ……………………………………………………………………………………… } } receiver

  8. send() void Mac802_11::send(Packet *p, Handler *h) { double rTime; struct hdr_mac802_11* dh = HDR_MAC802_11(p); EnergyModel *em = netif_->node()->energy_model(); if (em && em->sleep()) { em->set_node_sleep(0); em->set_node_state(EnergyModel::INROUTE); } callback_ = h; sendDATA(p); sendRTS(ETHER_ADDR(dh->dh_ra)); dh->dh_scontrol = sta_seqno_++; if(mhBackoff_.busy() == 0) { if(is_idle()) { if (mhDefer_.busy() == 0) { rTime = (Random::random() % cw_) * (phymib_.getSlotTime()); mhDefer_.start(phymib_.getDIFS() + rTime); } } else { mhBackoff_.start(cw_, is_idle()); } } } main

  9. Mac802_11::sendDATA(Packet *p) { hdr_cmn* ch = HDR_CMN(p); struct hdr_mac802_11* dh = HDR_MAC802_11(p); assert(pktTx_ == 0); ch->size() += phymib_.getHdrLen11(); dh->dh_fc.fc_protocol_version = MAC_ProtocolVersion; dh->dh_fc.fc_type = MAC_Type_Data; dh->dh_fc.fc_subtype = MAC_Subtype_Data; dh->dh_fc.fc_to_ds = 0; dh->dh_fc.fc_from_ds = 0; dh->dh_fc.fc_more_frag = 0; dh->dh_fc.fc_retry = 0; dh->dh_fc.fc_pwr_mgt = 0; dh->dh_fc.fc_more_data = 0; dh->dh_fc.fc_wep = 0; dh->dh_fc.fc_order = 0; /* store data tx time */ ch->txtime() = txtime(ch->size(), dataRate_); if((u_int32_t)ETHER_ADDR(dh->dh_ra) != MAC_BROADCAST) { /* store data tx time for unicast packets */ ch->txtime() = txtime(ch->size(), dataRate_); dh->dh_duration = usec(txtime(phymib_.getACKlen(), basicRate_) + phymib_.getSIFS()); } else { /* store data tx time for broadcast packets */ ch->txtime() = txtime(ch->size(), basicRate_ ); dh->dh_duration = 0; } pktTx_ = p; } sendDATA()

  10. getHdrLen11() inline u_int32_t getHdrLen11(){ return (getPLCPhdrLen() + sizeof(struct hdr_mac802_11) + ETHER_FCS_LEN); }

  11. MAC frame structure

  12. void Mac802_11::sendRTS(int dst) { Packet *p = Packet::alloc(); hdr_cmn* ch = HDR_CMN(p); struct rts_frame *rf = (struct rts_frame*)p ->access(hdr_mac::offset_); assert(pktTx_); assert(pktRTS_ == 0); if( (u_int32_t) HDR_CMN(pktTx_) ->size() < macmib_.getRTSThreshold() || (u_int32_t) dst == MAC_BROADCAST) { Packet::free(p); return; } ch->uid() = 0; ch->ptype() = PT_MAC; ch->size() = phymib_.getRTSlen(); ch->iface() = -2; ch->error() = 0; bzero(rf, MAC_HDR_LEN); rf->rf_fc.fc_protocol_version = MAC_ProtocolVersion; rf->rf_fc.fc_type = MAC_Type_Control; rf->rf_fc.fc_subtype = MAC_Subtype_RTS; rf->rf_fc.fc_to_ds = 0; rf->rf_fc.fc_from_ds = 0; rf->rf_fc.fc_more_frag = 0; rf->rf_fc.fc_retry = 0; rf->rf_fc.fc_pwr_mgt = 0; rf->rf_fc.fc_more_data= 0; rf->rf_fc.fc_wep = 0; rf->rf_fc.fc_order = 0; STORE4BYTE(&dst, (rf->rf_ra)); ch->txtime() = txtime(ch->size(), basicRate_ ); STORE4BYTE(&index_, (rf->rf_ta)); rf->rf_duration = usec(phymib_.getSIFS() + txtime(phymib_.getCTSlen(), basicRate_) + phymib_.getSIFS()+ txtime(pktTx_) + phymib_.getSIFS() + txtime(phymib_.getACKlen(), basicRate_)); pktRTS_ = p; } sendRTS() send RTSheader

  13. deferHandler() void Mac802_11::deferHandler() { … if( check_pktCTRL() == 0) return; if( check_pktRTS() == 0) return; if( check_pktTx() == 0) return; }

  14. check_pktRTS() int Mac802_11::check_pktRTS() { struct hdr_mac802_11 *mh; double timeout; if(pktRTS_ == 0) return -1; mh = HDR_MAC802_11(pktRTS_); switch(mh->dh_fc.fc_subtype) { case MAC_Subtype_RTS: if(! is_idle()) { inc_cw(); mhBackoff_.start(cw_, is_idle()); return 0; } setTxState(MAC_RTS); timeout = txtime(phymib_.getRTSlen(), basicRate_) + DSSS_MaxPropagationDelay + phymib_.getSIFS()+ txtime(phymib_.getCTSlen(), basicRate_)+ DSSS_MaxPropagationDelay; break; default: fprintf(stderr, "check_pktRTS:Invalid MAC Control subtype\n"); exit(1); } transmit(pktRTS_, timeout); return 0; }

  15. transmit() inline voidMac802_11::transmit(Packet *p, double timeout){ tx_active_ = 1; … if(rx_state_ != MAC_IDLE) { assert(pktRx_); struct hdr_cmn *ch = HDR_CMN(pktRx_); ch->error() = 1; /* force packet discard */ } downtarget_->recv(p->copy(), this); mhSend_.start(timeout); mhIF_.start(txtime(p)); }

  16. When mhIF_ timer expires void Mac802_11::txHandler() { if (EOTtarget_) { assert(eotPacket_); EOTtarget_->recv(eotPacket_, (Handler *) 0); eotPacket_ = NULL; } tx_active_ = 0; } main receiver

  17. Void Mac802_11::recv_timer() { …………………. switch(type) { case MAC_Type_Management: ……………………………………… goto done; case MAC_Type_Control: switch(subtype) { case MAC_Subtype_RTS: recvRTS(pktRx_); break; case MAC_Subtype_CTS: recvCTS(pktRx_); break; case MAC_Subtype_ACK: recvACK(pktRx_); break; default: …………………………… } break; case MAC_Type_Data: switch(subtype) { case MAC_Subtype_Data: recvDATA(pktRx_); break; default: fprintf(stderr, "recv_timer2:Invalid MAC Data Subtype %x\n", subtype); exit(1); } break; default: fprintf(stderr, "recv_timer3:Invalid MAC Type %x\n", subtype); exit(1); } done: pktRx_ = 0; rx_resume(); } recv_timer() receiver NAV

  18. recvCTS() Void Mac802_11::recvCTS(Packet *p) { if(tx_state_ != MAC_RTS) { discard(p, DROP_MAC_INVALID_STATE); return; } assert(pktRTS_); Packet::free(pktRTS_); pktRTS_ = 0; assert(pktTx_); mhSend_.stop(); /* * The successful reception of this CTS packet implies * that our RTS was successful. * According to the IEEE spec 9.2.5.3, you must * reset the ssrc_, but not the congestion window. */ ssrc_ = 0; tx_resume(); mac_log(p); }

  19. void Mac802_11::tx_resume() { double rTime; assert(mhSend_.busy() == 0); assert(mhDefer_.busy() == 0); if(pktCTRL_) { mhDefer_.start(phymib_. getSIFS()); } else if(pktRTS_) { if (mhBackoff_.busy() == 0) { rTime = (Random::random() % cw_) * phymib_.getSlotTime(); mhDefer_.start( phymib_.getDIFS() + rTime); } } else if(pktTx_) { if (mhBackoff_.busy() == 0) { hdr_cmn *ch = HDR_CMN(pktTx_); struct hdr_mac802_11 *mh = HDR_MAC802_11(pktTx_); if ((u_int32_t) ch->size() < macmib_.getRTSThreshold() || (u_int32_t) ETHER_ADDR(mh->dh_ra) == MAC_BROADCAST) { rTime = (Random::random() % cw_) * phymib_.getSlotTime(); mhDefer_.start(phymib_.getDIFS() + rTime); } else { mhDefer_.start(phymib_.getSIFS()); } } } else if(callback_) { Handler *h = callback_; callback_ = 0; h->handle((Event*) 0); } setTxState(MAC_IDLE); } tx_resume() recv_timer recvRTS recvDATA

  20. rx_resume() void Mac802_11::rx_resume() { … setRxState(MAC_IDLE); } main receiver

  21. check_pktTx() int Mac802_11::check_pktTx() { struct hdr_mac802_11 *mh; double timeout; assert(mhBackoff_.busy() == 0); if(pktTx_ == 0) return -1; mh = HDR_MAC802_11(pktTx_); switch(mh->dh_fc.fc_subtype) { case MAC_Subtype_Data: if(! is_idle()) { sendRTS(ETHER_ADDR(mh->dh_ra)); inc_cw(); mhBackoff_.start(cw_, is_idle()); return 0; } setTxState(MAC_SEND); if((u_int32_t)ETHER_ADDR(mh->dh_ra) != MAC_BROADCAST) timeout = txtime(pktTx_) + DSSS_MaxPropagationDelay + phymib_.getSIFS() + txtime(phymib_.getACKlen(), basicRate_) + DSSS_MaxPropagationDelay; else timeout = txtime(pktTx_); break; default: fprintf(stderr, "check_pktTx:Invalid MAC Control subtype\n"); exit(1); } transmit(pktTx_, timeout); return 0; }

  22. recvACK() void Mac802_11::recvACK(Packet *p) { struct hdr_cmn *ch = HDR_CMN(p); if(tx_state_ != MAC_SEND) { discard(p, DROP_MAC_INVALID_STATE); return; } assert(pktTx_); mhSend_.stop(); if((u_int32_t) HDR_CMN(pktTx_)->size() <= macmib_.getRTSThreshold()) ssrc_ = 0; else slrc_ = 0; rst_cw(); Packet::free(pktTx_); pktTx_ = 0; assert(mhBackoff_.busy() == 0); mhBackoff_.start(cw_, is_idle()); tx_resume(); mac_log(p); }

  23. txtime(double, double) doubleMac802_11::txtime(double psz, double drt){ double dsz = psz - phymib_.getPLCPhdrLen(); int plcp_hdr = phymib_.getPLCPhdrLen() << 3; int datalen = (int)dsz << 3; double t = (((double)plcp_hdr)/phymib_.getPLCPDataRate()) + (((double)datalen)/drt); return(t); } sendDATA

  24. txtime(Packet*) doubleMac802_11::txtime(Packet *p) { struct hdr_cmn *ch = HDR_CMN(p); double t = ch->txtime(); if (t < 0.0) { drop(p, "XXX"); exit(1); } return t; } transmit

  25. How is the RTS/CTS implemented? • Receiving a packet destined for itself recv() -> receive timer started -> recv_timer() -> recvRTS() -> sendCTS() -> tx_resume() -> start defer timer -> rx_resume() -> deferHandler() -> check_pktCTRL() -> transmit() -> recv() -> receive timer started -> recv_timer() -> recvDATA() -> sendACK() -> tx_resume() -> start defer timer -> uptarget_->recv() -> rx_resume() -> deferHandler() -> check_pktCTRL() -> transmit() -> start send timer -> send_timer() -> tx_resume() <- nothing happens, we're done!

  26. recvRTS() void Mac802_11::recvRTS(Packet *p) { struct rts_frame *rf = (struct rts_frame*)p->access(hdr_mac::offset_); if(tx_state_ != MAC_IDLE) { discard(p, DROP_MAC_BUSY); return; } if(pktCTRL_) { discard(p, DROP_MAC_BUSY); return; } sendCTS(ETHER_ADDR(rf->rf_ta), rf->rf_duration); if(mhDefer_.busy()) mhDefer_.stop(); tx_resume(); mac_log(p); }

  27. void Mac802_11::sendCTS(int dst, double rts_duration) { Packet *p = Packet::alloc(); hdr_cmn* ch = HDR_CMN(p); struct cts_frame *cf = (struct cts_frame*)p ->access(hdr_mac::offset_); assert(pktCTRL_ == 0); ch->uid() = 0; ch->ptype() = PT_MAC; ch->size() = phymib_.getCTSlen(); ch->iface() = -2; ch->error() = 0; bzero(cf, MAC_HDR_LEN); cf->cf_fc.fc_protocol_version = MAC_ProtocolVersion; cf->cf_fc.fc_type = MAC_Type_Control; cf->cf_fc.fc_subtype = MAC_Subtype_CTS; cf->cf_fc.fc_to_ds = 0; cf->cf_fc.fc_from_ds = 0; cf->cf_fc.fc_more_frag = 0; cf->cf_fc.fc_retry = 0; cf->cf_fc.fc_pwr_mgt = 0; cf->cf_fc.fc_more_data = 0; cf->cf_fc.fc_wep = 0; cf->cf_fc.fc_order = 0; /* store cts tx time */ ch->txtime() = txtime(ch->size(), basicRate_); /* calculate cts duration */ cf->cf_duration = usec(sec(rts_duration) - phymib_.getSIFS() - txtime(phymib_.getCTSlen(), basicRate_)); pktCTRL_ = p; } sendCTS() CTSheader

  28. int Mac802_11::check_pktCTRL() { struct hdr_mac802_11 *mh; double timeout; if(pktCTRL_ == 0) return -1; if(tx_state_ == MAC_CTS || tx_state_ == MAC_ACK) return -1; mh = HDR_MAC802_11(pktCTRL_); switch(mh->dh_fc.fc_subtype) { case MAC_Subtype_CTS: if(!is_idle()) { discard(pktCTRL_, DROP_MAC_BUSY); pktCTRL_ = 0; return 0; } setTxState(MAC_CTS); timeout = txtime(phymib_.getCTSlen(), basicRate_) + DSSS_MaxPropagationDelay + sec(mh->dh_duration) + DSSS_MaxPropagationDelay - phymib_.getSIFS() - txtime(phymib_.getACKlen(), basicRate_); break; case MAC_Subtype_ACK: setTxState(MAC_ACK); timeout = txtime(phymib_.getACKlen(), basicRate_); break; default: fprintf(stderr, "check_pktCTRL:Invalid MAC Control subtype\n"); exit(1); } transmit(pktCTRL_, timeout); return 0; } check_pktCTRL

  29. void Mac802_11::recvDATA(Packet *p) { struct hdr_mac802_11 *dh = HDR_MAC802_11(p); u_int32_t dst, src, size; struct hdr_cmn *ch = HDR_CMN(p); dst = ETHER_ADDR(dh->dh_ra); src = ETHER_ADDR(dh->dh_ta); size = ch->size(); ch->size() -= phymib_.getHdrLen11(); ch->num_forwards() += 1; if(dst != MAC_BROADCAST) { if(size >= macmib_.getRTSThreshold()) { if (tx_state_ == MAC_CTS) { assert(pktCTRL_); Packet::free(pktCTRL_); pktCTRL_ = 0; mhSend_.stop(); } else { discard(p, DROP_MAC_BUSY); return; } sendACK(src); tx_resume(); } else { if(pktCTRL_) { discard(p, DROP_MAC_BUSY); return; } sendACK(src); if(mhSend_.busy() == 0) tx_resume(); } } …………………………………………………………………………………………. uptarget_->recv(p, (Handler*) 0); } recvDATA() recv_timer

  30. void Mac802_11::sendACK(int dst) { Packet *p = Packet::alloc(); hdr_cmn* ch = HDR_CMN(p); struct ack_frame *af = (struct ack_frame*)p->access(hdr_mac::offset_); assert(pktCTRL_ == 0); ch->uid() = 0; ch->ptype() = PT_MAC; ch->size() = phymib_.getACKlen(); ch->iface() = -2; ch->error() = 0; bzero(af, MAC_HDR_LEN); af->af_fc.fc_protocol_version = MAC_ProtocolVersion; af->af_fc.fc_type = MAC_Type_Control; af->af_fc.fc_subtype = MAC_Subtype_ACK; af->af_fc.fc_to_ds = 0; af->af_fc.fc_from_ds = 0; af->af_fc.fc_more_frag = 0; af->af_fc.fc_retry = 0; af->af_fc.fc_pwr_mgt = 0; af->af_fc.fc_more_data = 0; af->af_fc.fc_wep = 0; af->af_fc.fc_order = 0; STORE4BYTE(&dst, (af->af_ra)); /* store ack tx time */ ch->txtime() = txtime(ch->size(), basicRate_); /* calculate ack duration */ af->af_duration = 0; pktCTRL_ = p; } sendACK()

  31. DCF with four-way handshaking (cont.) • Errors • Sender sends a RTS but never receives the CTS • Sender sends the data but never receives the ACK • Number of retransmissions • shortRetryLimit : for short frame (frame_length < RTSThreshold) • longRetryLimit : for long frame (frame_length >= RTSThreshold)

  32. When the first RTS fails • Transmitting a packet (RTS loss) recv() -> send() -> sendDATA() and sendRTS() -> start defer timer -> deferHandler() -> check_pktRTS() -> transmit() -> start send timer -> send_timer() -> RetransmitRTS() -> tx_resume() -> backoff timer started -> backoffHandler() -> check_pktRTS() -> transmit The rest is the same as above

  33. When mhSend_ timer expires void Mac802_11::send_timer() { switch(tx_state_) { case MAC_RTS: RetransmitRTS(); break; case MAC_CTS: assert(pktCTRL_); Packet::free(pktCTRL_); pktCTRL_ = 0; break; case MAC_SEND: RetransmitDATA(); break; case MAC_ACK: assert(pktCTRL_); Packet::free(pktCTRL_); pktCTRL_ = 0; break; case MAC_IDLE: break; default: assert(0); } tx_resume(); }

  34. RetransmitRTS() Mac802_11::RetransmitRTS(){ … ssrc_ += 1; if(ssrc_ >= macmib_.getShortRetryLimit()) { discard(pktRTS_, DROP_MAC_RETRY_COUNT_EXCEEDED); pktRTS_ = 0; … discard(pktTx_,DROP_MAC_RETRY_COUNT_EXCEEDED); pktTx_ = 0; ssrc_ = 0; rst_cw(); } else { struct rts_frame *rf; rf = (struct rts_frame*)pktRTS_->access(hdr_mac::offset_); rf->rf_fc.fc_retry = 1; inc_cw(); mhBackoff_.start(cw_, is_idle()); } }

  35. backoffHandler() Void Mac802_11::backoffHandler(){ if(pktCTRL_) { assert(mhSend_.busy() || mhDefer_.busy()); return; } if(check_pktRTS() == 0) return; if(check_pktTx() == 0) return; }

  36. When data lost • Sending a packet (data lost) recv() -> send() -> sendDATA() and sendRTS() -> start defer timer -> deferHandler() -> check_pktRTS() -> transmit() -> recv() -> receive timer started -> recv_timer() -> recvCTS() -> tx_resume() -> start defer timer -> rx_resume() -> deferHandler() -> check_pktTx() -> transmit() -> start send timer -> send_timer() -> RetransmitDATA() -> tx_resume() -> backoff timer started -> backoffHandler() -> check_pktTx() -> transmit The rest is the same as previous

  37. Today’s Outline • How is the RTS/CTS implemented? • Is the default setting for RTS/CTS on or off in ns-2? • How is the NAV implemented? • How is the back-off timer implemented?

  38. DCF • DCF has two access mechanisms for packet transmission : two-way handshaking and four-way handshaking • Using two-way or four-way depends on the RTSThreshold value • If the size of transmitted packet is larger than this value, then four-way is applied

  39. DCF Four-way Two-way sender receiver sender receiver DIFS DIFS RTS data SIFS SIFS CTS ACK SIFS data SIFS ACK

  40. Is the default setting for RTS/CTS on or off in ns-2? • This condition will be checked in sendRTS() (in mac-802_11.cc)

  41. Is the default setting for RTS/CTS on or off in ns-2? (cont.) voidMac802_11::sendRTS(int dst){ … /* If the size of the packet is larger than the RTSThreshold, then perform the RTS/CTS exchange. Also skip if destination is a broadcast */ if( (u_int32_t) HDR_CMN(pktTx_)->size() < macmib_.getRTSThreshold() || (u_int32_t) dst == MAC_BROADCAST) { Packet::free(p); //p = 0; return; }

  42. Is the default setting for RTS/CTS on or off in ns-2? (cont.) • So all we concerned is the value of RTSThreshold • The default value of RTSThreshold is 0 in ns-default.tcl file • Mac/802_11 set RTSThreshold_ 0 • So the “if statement” of previous page is always false, it means that the default setting for RTS/CTS is on in ns-2

  43. Today’s Outline • Is the default setting for RTS/CTS on or off in ns-2? • How is the RTS/CTS implemented? • How is the NAV implemented? • How is the back-off timer implemented?

  44. How is the NAV implemented? • NAV (network allocation vector) indicates the period which the channel is busy. • Each node will update this value when receives RTS or CTS. • This value is according to the duration field of the frames.

  45. How is the NAV implemented? • If a node is not the sender or destination, once it receives the RTS or CTS, it will update its NAV. • This is done in recv_timer() (see next page)

  46. How is the NAV implemented? sendRTS sendCTS

  47. How is the NAV implemented? • Nodes also update the NAV if they detect any error or collision. • In these cases, nodes will defer for EIFS (extension interframe space)

  48. How is the NAV implemented? void Mac802_11::recv_timer() { … /* Handle collisions */ if(rx_state_ == MAC_COLL) { discard(pktRx_, DROP_MAC_COLLISION); set_nav(usec(phymib_.getEIFS())); goto done; } recv_timer

  49. How is the NAV implemented? /* Check to see if this packet was received with errors that the current level of FEC still could not fix all of the problems */ if( ch->error() ) { Packet::free(pktRx_); set_nav(usec(phymib_.getEIFS())); goto done; }

  50. How is the NAV implemented? /* IEEE 802.11 specs, update the NAV */ if(dst != (u_int32_t)index_) { set_nav(mh->dh_duration); }

More Related