21
How to send a unicast packet?

How to send a unicast packet?

  • Upload
    silas

  • View
    37

  • Download
    0

Embed Size (px)

DESCRIPTION

How to send a unicast packet?. Procedure. Roughly takes the following path (when no errors or congestion): recv() -> send() -> sendDATA() and sendRTS() -> start defer timer -> deferHandler() -> check_pktRTS() -> transmit() -> recv() -> receive timer started - PowerPoint PPT Presentation

Citation preview

Page 1: How to send a unicast packet?

How to send a unicast packet?

Page 2: How to send a unicast packet?

ProcedureRoughly takes the following path (when no errors or congestion):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!

Page 3: How to send a unicast packet?

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 {

………………………………………………………………………………………}

}

back to procedure

Page 4: How to send a unicast packet?

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());}

}}

back to procedure

Page 5: How to send a unicast packet?

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 (see 9.6) */

ch->txtime() = txtime(ch->size(), basicRate_ );

dh->dh_duration = 0;}pktTx_ = p;

}

sendDATA( )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_);

Back to send ( )

Back to procedure

Page 6: How to send a unicast packet?

sendRTS( )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;

}Back to send ( )

Back to procedure

Page 7: How to send a unicast packet?

deferHandler( )void Mac802_11::deferHandler(){

assert(pktCTRL_ || pktRTS_ || pktTx_);

if( check_pktCTRL() == 0)return;

assert(mhBackoff_.busy() == 0);if( check_pktRTS() == 0)

return;if( check_pktTx() == 0)

return;}

Back to procedure

Page 8: How to send a unicast packet?

Check_pktCTRL()int Mac802_11::check_pktCTRL(){

struct hdr_mac802_11 *mh;double timeout;

if(pktCTRL_ == 0)return -1;

…………………….}

Back to deferHandler()

Back to procedure

Page 9: How to send a unicast packet?

check_pktRTS()int Mac802_11::check_pktRTS(){

struct hdr_mac802_11 *mh;double timeout;assert(mhBackoff_.busy() == 0);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;}

Back to deferHandler()

Back to procedure

Page 10: How to send a unicast packet?

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;

}Back to deferHandler()

Back to procedure

Page 11: How to send a unicast packet?

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;

elsetimeout = txtime(pktTx_);break;default:fprintf(stderr, "check_pktTx:Invalid MAC Control subtype\n");exit(1);}transmit(pktTx_, timeout);return 0;

}

Back to procedure

Back to recv_timer()

Page 12: How to send a unicast packet?

recv_timer()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_ti

mer2:Invalid MAC Data Subtype %x\n",subtype);

exit(1);}break;

default:fprintf(stderr, "recv_timer3:Invali

d MAC Type %x\n", subtype);exit(1);

} done:

pktRx_ = 0;rx_resume();

}

Back to procedure

Page 13: How to send a unicast packet?

} 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()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);

}

Back to procedure

Back to recvCTS

Back to recvACK

Page 14: How to send a unicast packet?

rx_resume( )

Void Mac802_11::rx_resume(){

assert(pktRx_ == 0);assert(mhRecv_.busy() == 0);setRxState(MAC_IDLE);

}

Back to procedure

Back to recv_timer

Page 15: How to send a unicast packet?

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);}

Back to procedure

Back to recv_timer()

Page 16: How to send a unicast packet?

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;elseslrc_ = 0;rst_cw();Packet::free(pktTx_); pktTx_ = 0;

assert(mhBackoff_.busy() == 0);mhBackoff_.start(cw_, is_idle());

tx_resume();

mac_log(p);}

Back to procedure

Back to recv_timer()

Page 17: How to send a unicast packet?

inline void Mac802_11::transmit(Packet *p, double timeout){

tx_active_ = 1;

if (EOTtarget_) {assert (eotPacket_ == NULL);eotPacket_ = p->copy();

}

/* * If I'm transmitting without doing CS, such as when sending an ACK, any incoming packet will be

* "missed“ and hence, must be discarded. */if(rx_state_ != MAC_IDLE) {

struct hdr_mac802_11 *dh = HDR_MAC802_11(p);assert(dh->dh_fc.fc_type == MAC_Type_Control);assert(dh->dh_fc.fc_subtype == MAC_Subtype_ACK);assert(pktRx_);struct hdr_cmn *ch = HDR_CMN(pktRx_);ch->error() = 1; /* force packet discard */

}

/* * pass the packet on the "interface" which will in turn* place the packet on the channel. * NOTE: a handler is passed along so that the Network Interface can distinguish between incoming

* and outgoing packets.

*/downtarget_->recv(p->copy(), this);mhSend_.start(timeout);mhIF_.start(txtime(p));

}Back to procedure

Back to check_pktRTS()

Page 18: How to send a unicast packet?

txtime( )/* * txtime() - calculate tx time for packet of size "psz" bytes * at rate "drt" bps */double Mac802_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);

}

Back to procedure

Back to sendDATA()

Page 19: How to send a unicast packet?

When mhSend_ timer expiresvoid 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();

}

Back to procedure

Back to transmit()

Page 20: How to send a unicast packet?

When mhIF_ timer expires voidMac802_11::txHandler(){

if (EOTtarget_) {assert(eotPacket_);EOTtarget_->recv(eotPacket_, (Handler *) 0);eotPacket_ = NULL;}tx_active_ = 0;

}

Back to procedure

Back to transmit()

Page 21: How to send a unicast packet?

References

• mac-802_11.cc, mac-802_11.h• mac-timers.cc, mac-timers.h• http://www.ece.rice.edu/~jpr/ns/docs/802_

11.html#DeferTimer