📄 mac-802_11_brdcst.cc
字号:
case MAC_Subtype_RTS: if((u_int32_t)ETHER_ADDR(mh->dh_ta) == (u_int32_t)index_) { drop(p, why); return; } /* fall through - if necessary */ case MAC_Subtype_CTS: case MAC_Subtype_ACK: if((u_int32_t)ETHER_ADDR(mh->dh_ra) == (u_int32_t)index_) { drop(p, why); return; } break; default: fprintf(stderr, "invalid MAC Control subtype\n"); exit(1); } break; case MAC_Type_Data: switch(mh->dh_fc.fc_subtype) { case MAC_Subtype_Data: if((u_int32_t)ETHER_ADDR(mh->dh_ra) == \ (u_int32_t)index_ || (u_int32_t)ETHER_ADDR(mh->dh_ta) == \ (u_int32_t)index_ || (u_int32_t)ETHER_ADDR(mh->dh_ra) == MAC_BROADCAST) { drop(p,why); return; } break; default: fprintf(stderr, "invalid MAC Data subtype\n"); exit(1); } break; default: fprintf(stderr, "invalid MAC type (%x)\n", mh->dh_fc.fc_type); trace_pkt(p); exit(1); } Packet::free(p);}voidMac802_11::capture(Packet *p){ /* * Update the NAV so that this does not screw * up carrier sense. */ set_nav(usec(phymib_.getEIFS() + txtime(p))); Packet::free(p);}voidMac802_11::collision(Packet *p){ switch(rx_state_) { case MAC_RECV: setRxState(MAC_COLL); /* fall through */ case MAC_COLL: assert(pktRx_); assert(mhRecv_.busy()); /* * Since a collision has occurred, figure out * which packet that caused the collision will * "last" the longest. Make this packet, * pktRx_ and reset the Recv Timer if necessary. */ if(txtime(p) > mhRecv_.expire()) { mhRecv_.stop(); discard(pktRx_, DROP_MAC_COLLISION); pktRx_ = p; mhRecv_.start(txtime(pktRx_)); } else { discard(p, DROP_MAC_COLLISION); } break; default: assert(0); }}voidMac802_11::tx_resume(){ double rTime; assert(mhSend_.busy() == 0); assert(mhDefer_.busy() == 0); if(pktCTRL_) { /* * Need to send a CTS or ACK. */ mhDefer_.start(phymib_.getSIFS()); } else if(pktRTS_) { if (mhBackoff_.busy() == 0) { if (bugFix_timer_) { mhBackoff_.start(cw_, is_idle(), phymib_.getDIFS()); } else { 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) { if (bugFix_timer_) { mhBackoff_.start(cw_, is_idle(), phymib_.getDIFS()); } else { 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);}voidMac802_11::rx_resume(){ assert(pktRx_ == 0); assert(mhRecv_.busy() == 0); setRxState(MAC_IDLE);}/* ====================================================================== Timer Handler Routines ====================================================================== */voidMac802_11::backoffHandler(){ if(pktCTRL_) { assert(mhSend_.busy() || mhDefer_.busy()); return; } if(check_pktRTS() == 0) return; if(check_pktTx() == 0) return;}voidMac802_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;}voidMac802_11::navHandler(){ if(is_idle() && mhBackoff_.paused()) mhBackoff_.resume(phymib_.getDIFS());}voidMac802_11::recvHandler(){ recv_timer();}voidMac802_11::sendHandler(){ send_timer();}voidMac802_11::txHandler(){ if (EOTtarget_) { assert(eotPacket_); EOTtarget_->recv(eotPacket_, (Handler *) 0); eotPacket_ = NULL; } tx_active_ = 0;}/* ====================================================================== The "real" Timer Handler Routines ====================================================================== */voidMac802_11::send_timer(){ switch(tx_state_) { /* * Sent a RTS, but did not receive a CTS. */ case MAC_RTS: RetransmitRTS(); break; /* * Sent a CTS, but did not receive a DATA packet. */ case MAC_CTS: assert(pktCTRL_); Packet::free(pktCTRL_); pktCTRL_ = 0; break; /* * Sent DATA, but did not receive an ACK packet. */ case MAC_SEND: RetransmitDATA(); break; /* * Sent an ACK, and now ready to resume transmission. */ case MAC_ACK: assert(pktCTRL_); Packet::free(pktCTRL_); pktCTRL_ = 0; break; case MAC_IDLE: break; default: assert(0); } tx_resume();}/* ====================================================================== Outgoing Packet Routines ====================================================================== */intMac802_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) { /* * If the medium is not IDLE, don't send the CTS. */ case MAC_Subtype_CTS: if(!is_idle()) { discard(pktCTRL_, DROP_MAC_BUSY); pktCTRL_ = 0; return 0; } setTxState(MAC_CTS); /* * timeout: cts + data tx time calculated by * adding cts tx time to the cts duration * minus ack tx time -- this timeout is * a guess since it is unspecified * (note: mh->dh_duration == cf->cf_duration) */ timeout = txtime(phymib_.getCTSlen(), basicRate_) + DSSS_MaxPropagationDelay // XXX + sec(mh->dh_duration) + DSSS_MaxPropagationDelay // XXX - phymib_.getSIFS() - txtime(phymib_.getACKlen(), basicRate_); break; /* * IEEE 802.11 specs, section 9.2.8 * Acknowledments are sent after an SIFS, without regard to * the busy/idle state of the medium. */ 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;}intMac802_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 // XXX + 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;}intMac802_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 // XXX + phymib_.getSIFS() + txtime(phymib_.getACKlen(), basicRate_) + DSSS_MaxPropagationDelay; // XXX else timeout = txtime(pktTx_); break; default: fprintf(stderr, "check_pktTx:Invalid MAC Control subtype\n"); exit(1); } transmit(pktTx_, timeout); return 0;}/* * Low-level transmit functions that actually place the packet onto * the channel. */voidMac802_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 the size of the packet is larger than the * RTSThreshold, then perform the RTS/CTS exchange. */ if( (u_int32_t) HDR_CMN(pktTx_)->size() < macmib_.getRTSThreshold() || (u_int32_t) dst == MAC_BROADCAST) { Packet::free(p); return; } p->txinfo_.CPThresh = CPTHRESH_BASIC; // VIVEK_NEW ctrl pkts sent at basic rate 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; //rf->rf_duration = RTS_DURATION(pktTx_); STORE4BYTE(&dst, (rf->rf_ra)); /* store rts tx time */ ch->txtime() = txtime(ch->size(), basicRate_); STORE4BYTE(&index_, (rf->rf_ta)); /* calculate rts duration field */ rf->rf_duration = usec(phymib_.getSIFS() + txtime(phymib_.getCTSlen(), basicRate_) + phymib_.getSIFS() + txtime(pktTx_) + phymib_.getSIFS() + txtime(phymib_.getACKlen(), basicRate_)); pktRTS_ = p;}voidMac802_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); p->txinfo_.CPThresh = CPTHRESH_BASIC; // VIVEK_NEW ctrl pkts sent at basic rate ch->uid() = 0; ch->ptype() = PT_MAC; ch->size() = phymib_.getCTSlen(); ch->iface() = -2; ch->error() = 0; //ch->direction() = hdr_cmn::DOWN; 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -