📄 mac-802_11.cc
字号:
inline int Mac802_11::hdr_src(char* hdr, int src ){ struct hdr_mac802_11 *dh = (struct hdr_mac802_11*) hdr; // change wrt Mike's code /*if(src > -2) STORE4BYTE(&src, (dh->dh_sa)); return ETHER_ADDR(dh->dh_sa);*/ if(src > -2) STORE4BYTE(&src, (dh->dh_ta)); return ETHER_ADDR(dh->dh_ta); // change ends}inline int Mac802_11::hdr_type(char* hdr, u_int16_t type){ struct hdr_mac802_11 *dh = (struct hdr_mac802_11*) hdr; if(type) STORE2BYTE(&type,(dh->dh_body)); return GET2BYTE(dh->dh_body);}/* ====================================================================== Misc Routines ====================================================================== */// change wrt Mike's code#undef INTERLEAVING// change endsinline intMac802_11::is_idle(){ // change wrt Mike's code #ifdef INTERLEAVING #define INTERLEAVING_TIME 0.030 Scheduler &s = Scheduler::instance(); double st = s.clock(); double nextCycle = floor(st / (INTERLEAVING_TIME*2) + 1) * INTERLEAVING_TIME*2; double nextSwitch = nextCycle - INTERLEAVING_TIME - phymib_.getDIFS() - phymib_.getSIFS() + txtime(phymib_.getCTSlen(), basicRate_) - txtime(phymib_.getCTSlen(), basicRate_) * 2 - (Random::random() % cw_) * phymib_.getSlotTime(); if ((st >= nextSwitch) && (st < nextCycle)) { if (nextCycle > nav_) { nav_ = nextCycle; if (mhNav_.busy()) { mhNav_.stop(); } mhNav_.start(nextCycle - st); } return(0); } #endif // change ends if(rx_state_ != MAC_IDLE) return 0; if(tx_state_ != MAC_IDLE) return 0; if(nav_ > Scheduler::instance().clock()) return 0; return 1;}voidMac802_11::discard(Packet *p, const char* why){ hdr_mac802_11* mh = HDR_MAC802_11(p); hdr_cmn *ch = HDR_CMN(p);#if 0 /* old logic 8/8/98 -dam */ /* * If received below the RXThreshold, then just free. */ if(p->txinfo_.Pr < p->txinfo_.ant.RXThresh) { Packet::free(p); //p = 0; return; }#endif // 0 /* if the rcvd pkt contains errors, a real MAC layer couldn't necessarily read any data from it, so we just toss it now */ if(ch->error() != 0) { Packet::free(p); //p = 0; return; } switch(mh->dh_fc.fc_type) { case MAC_Type_Management: drop(p, why); return; case MAC_Type_Control: switch(mh->dh_fc.fc_subtype) { case MAC_Subtype_RTS: // change wrt Mike's code //if((u_int32_t)ETHER_ADDR(mh->dh_sa) == if((u_int32_t)ETHER_ADDR(mh->dh_ta) == (u_int32_t)index_) { drop(p, why); return; } //change ends /* fall through - if necessary */ case MAC_Subtype_CTS: case MAC_Subtype_ACK: // change wrt Mike's code //if((u_int32_t)ETHER_ADDR(mh->dh_da) == 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: // change wrt Mike's code /*if((u_int32_t)ETHER_ADDR(mh->dh_da) == \ (u_int32_t)index_ || (u_int32_t)ETHER_ADDR(mh->dh_sa) == \ (u_int32_t)index_ || (u_int32_t)ETHER_ADDR(mh->dh_da) == MAC_BROADCAST) { drop(p,why); return; */ 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. */ // change wrt Mike's code //set_nav(usec(eifs_ + txtime(p))); set_nav(usec(phymib_.getEIFS() + txtime(p))); Packet::free(p);}voidMac802_11::collision(Packet *p){ switch(rx_state_) { case MAC_RECV: // change wrt Mike's code //SET_RX_STATE(MAC_COLL); 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. */ // change wrt Mike's code //mhDefer_.start(sifs_); mhDefer_.start(phymib_.getSIFS()); } else if(pktRTS_) { if(mhBackoff_.busy() == 0) { // change wrt Mike's code /* rTime = (Random::random() % cw_) * phymib_->SlotTime; mhDefer_.start(difs_ + rTime); */ 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_); // change wrt Mike's code /* if ((u_int32_t) ch->size() < macmib_->RTSThreshold || (u_int32_t) ETHER_ADDR(mh->dh_da) == MAC_BROADCAST) { rTime = (Random::random() % cw_) * phymib_->SlotTime; mhDefer_.start(difs_ + rTime); } else { mhDefer_.start(sifs_); } */ 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); } // change wrt Mike's code //SET_TX_STATE(MAC_IDLE); setTxState(MAC_IDLE);}voidMac802_11::rx_resume(){ assert(pktRx_ == 0); assert(mhRecv_.busy() == 0); // change wrt Mike's code //SET_RX_STATE(MAC_IDLE); setRxState(MAC_IDLE);}/* ====================================================================== Timer Handler Routines ====================================================================== */voidMac802_11::backoffHandler(){///-ak-------// printf("backoff andler \n"); if(pktCTRL_) { assert(mhSend_.busy() || mhDefer_.busy()); return; } if(check_pktRTS() == 0) return; if(check_pktTx() == 0) return;}// change wrt Mike's code void Mac802_11::beaconHandler() { /* schedule timer for the next beacon! */ // mhBeacon_.start(cfp_period_); }voidMac802_11::deferHandler(){ assert(pktCTRL_ || pktRTS_ || pktTx_); if(check_pktCTRL() == 0) return; assert(mhBackoff_.busy() == 0); //if (mhBackoff_.busy() != 0) //{ // printf("deferHandler:mhBackoff_ busy!\n"); // return; //} if(check_pktRTS() == 0) return; if(check_pktTx() == 0) return;}voidMac802_11::navHandler(){ if(is_idle() && mhBackoff_.paused()) // change wrt Mike's code //mhBackoff_.resume(difs_); mhBackoff_.resume(phymib_.getDIFS());}voidMac802_11::recvHandler(){ recv_timer();}voidMac802_11::sendHandler(){ send_timer();}voidMac802_11::txHandler(){ // change wrtt Mike's code 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; } // change wrt Mike's code //SET_TX_STATE(MAC_CTS); 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) */ // change wrt Mike's code /*timeout = txtime(ETHER_CTS_LEN, basicRate_) + DSSS_MaxPropagationDelay // XXX + sec(mh->dh_duration) + DSSS_MaxPropagationDelay // XXX - sifs_ - txtime(ETHER_ACK_LEN, basicRate_);*/ 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: // change wrt Mike's code /*SET_TX_STATE(MAC_ACK); timeout = txtime(ETHER_ACK_LEN, basicRate_);*/ setTxState(MAC_ACK); timeout = txtime(phymib_.getACKlen(), basicRate_); break; default: fprintf(stderr, "check_pktCTRL:Invalid MAC Control subtype\n"); exit(1); } // change wrt Mike's code // TRANSMIT(pktCTRL_, timeout); 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; //struct hdr_cmn *ch = HDR_CMN(pktRTS_); 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; } // change wrt Mike's code /*SET_TX_STATE(MAC_RTS); timeout = txtime(ETHER_RTS_LEN, basicRate_) + DSSS_MaxPropagationDelay // XXX + sifs_ + txtime(ETHER_CTS_LEN, basicRate_) + DSSS_MaxPropagationDelay; // XXX */ 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); } // change wrt Mike's code // TRANSMIT(pktRTS_, timeout);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -