how to send a unicast packet n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
How to send a unicast packet? PowerPoint Presentation
Download Presentation
How to send a unicast packet?

Loading in 2 Seconds...

play fullscreen
1 / 21

How to send a unicast packet? - PowerPoint PPT Presentation


  • 83 Views
  • Uploaded on

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

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'How to send a unicast packet?' - silas


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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
procedure
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

-> 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!

slide3
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

slide4
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

senddata
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;

}

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

sendDATA( )

Back to procedure

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;

}

sendRTS( )

Back to send ( )

Back to procedure

deferhandler
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

check pktctrl
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

check pktrts
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

check pkttx
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

check pkttx1
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 recv_timer()

Back to procedure

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

Back to procedure

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

}

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

}

tx_resume()

Back to recvCTS

Back to recvACK

Back to procedure

rx resume
rx_resume( )

Void Mac802_11::rx_resume()

{

assert(pktRx_ == 0);

assert(mhRecv_.busy() == 0);

setRxState(MAC_IDLE);

}

Back to recv_timer

Back to procedure

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

Back to procedure

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

}

Back to recv_timer()

Back to procedure

slide17

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 check_pktRTS()

Back to procedure

txtime
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 sendDATA()

Back to procedure

when mhsend timer expires
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();

}

Back to transmit()

Back to procedure

when mhif timer expires
When mhIF_ timer expires

void

Mac802_11::txHandler()

{

if (EOTtarget_) {

assert(eotPacket_);

EOTtarget_->recv(eotPacket_, (Handler *) 0);

eotPacket_ = NULL;

}

tx_active_ = 0;

}

Back to transmit()

Back to procedure

references
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