📄 mac-802_11.cc
字号:
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_->RTSThreshold || (u_int32_t) ETHER_ADDR(mh->dh_da) == MAC_BROADCAST) { mhDefer_.start(difs_); } else {//JUNGMIN //this is because there has been RTS/CTS exchange//end of JUNGMIN mhDefer_.start(sifs_); } }//JUNGMIN //because of this callback, send function can just return if it is during //backoff. Here callback is Interface Queue.//end of JUNGMIN } else if(callback_) { Handler *h = callback_; callback_ = 0; if(pktPending_ != 0 && mhWait_.busy() == 0) { Packet *p = pktPending_; pktPending_ = 0; send(p, h); } else { h->handle((Event*) 0); } } SET_TX_STATE(MAC_IDLE);}voidMac802_11::rx_resume(){ assert(pktRx_ == 0); assert(mhRecv_.busy() == 0); SET_RX_STATE(MAC_IDLE);}voidMac802_11::dx_resume(){ assert(pktDx_ == 0); assert(mhRecvDATA_.busy() == 0); SET_DX_STATE(MAC_IDLE);}/* ====================================================================== Timer Handler Routines ====================================================================== */voidMac802_11::backoffHandler(){ if(pktCTRL_) { assert(mhSend_.busy() || mhDefer_.busy()); return; } if(check_pktPCF() == 0) return; if(pktATIMRSH_) { return; } if(pktATIMACK_) { return; }//JUNGMIN if(check_pktATIM() == 0) return;//end of JUNGMIN if(pktTx_) { if(atim_window_ == 1 || NearBeacon(pktTx_, 1)) { ll_->ifq()->ReturnPacket(pktTx_); if(pktRTS_ != 0) Packet::free(pktRTS_); pktRTS_ = 0; pktTx_ = 0; } } if(check_pktRTS() == 0) return; if(check_pktTx() == 0) return;}voidMac802_11::deferHandler(){//JUNGMIN assert(pktCTRL_ || pktRTS_ || pktTx_ || pktPCF_ || pktATIM_ || pktATIMACK_ || pktATIMRSH_);//end of JUNGMIN if(check_pktCTRL() == 0) return; if(check_pktPCF() == 0) return;//JUNGMIN if(check_pktATIMRSH() == 0) return; if(check_pktATIMACK() == 0) return; if(check_pktATIM() == 0) return;//end of JUNGMIN assert(mhBackoff_.busy() == 0); if(check_pktRTS() == 0) return; if(check_pktTx() == 0) return;}voidMac802_11::navHandler(){ if(is_idle() && mhBackoff_.paused()) mhBackoff_.resume(difs_);}voidMac802_11::channelusageHandler(int ch){ if(ch < NUMBER_OF_CHANNELS) { dca_cul_[ch] = 0; } else { printf("ERROR: Trying to access non-existing channel\n"); }}voidMac802_11::waitHandler(){}//JUNGMINvoidMac802_11::atimHandler(){ atim_window_ = 0; ready_for_atim_ = 0; if(selected_channel_ == -1) active_channel_ = 0; //Default channel else active_channel_ = selected_channel_; if(index_ < 18 && index_ >= 0) { } if(btbs_) { btbs_ = 0; } if(callback_ == 0) { ll_->ifq()->ResetATIMWindow(1); } else { ll_->ifq()->ResetATIMWindow(0); } //status parameter 0: not idle 1: idle // if idle, this function should callback the queue // explicitly to send packets. }//end of JUNGMINvoidMac802_11::recvHandler(){ recv_timer();}voidMac802_11::recvDATAHandler(){ recvDATA_timer();}voidMac802_11::sendHandler(){ send_timer();}voidMac802_11::txHandler(){ tx_active_ = 0;}//JUNGMINvoidMac802_11::beaconHandler(){ //Schedule the next beacon mhBeacon_.start(macmib_->dot11BeaconPeriod*0.001000); next_beacon_time_ = NOW + (macmib_->dot11BeaconPeriod * 0.001000); ResetAtBeacon(); SetATIMWindow(); if(mhATIMWindow_.busy()) mhATIMWindow_.stop(); mhATIMWindow_.start(macmib_->dot11ATIMWindowSize*0.001000); //Distribute Beacon //Instead of sending beacon right away, wait for a certain amount of time. prepare_beacon(); }voidMac802_11::beaconBackoffHandler(){ //printf("[%d] %lf: beaconBackoffHandler Called.\n", index_, NOW); send_beacon();}//end of JUNGMIN/* ====================================================================== The "real" Timer Handler Routines ====================================================================== */voidMac802_11::send_timer(){ switch(tx_state_) { case MAC_ATIM: RetransmitATIM(); break; case MAC_ATIMACK: assert(pktATIMACK_); Packet::free(pktATIMACK_); pktATIMACK_ = 0; break; case MAC_ATIMRSH: assert(pktATIMRSH_); Packet::free(pktATIMRSH_); pktATIMRSH_ = 0; break; /* * 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: if(pktRSH_) { Packet::free(pktRSH_); pktRSH_ = 0; //only for now RetransmitDATA(); } else { RetransmitDATA(); } break; /* * Sent an ACK, and now ready to resume transmission. */ case MAC_ACK: assert(pktCTRL_); Packet::free(pktCTRL_); pktCTRL_ = 0; break;//JUNGMIN case MAC_BEACONING: if(pktPCF_) { Packet::free(pktPCF_); pktPCF_ = 0; } break;//end of JUNGMIN 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_); struct dca_cts_frame *dcts; 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; } SET_TX_STATE(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(ETHER_CTS_LEN, basicRate_) + DSSS_MaxPropagationDelay // XXX + sec(mh->dh_duration) + DSSS_MaxPropagationDelay // XXX - sifs_ - txtime(ETHER_ACK_LEN, 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_DCTS: if(!is_idle()) { discard(pktCTRL_, DROP_MAC_BUSY); pktCTRL_ = 0; return 0; } SET_TX_STATE(MAC_CTS); dcts = (struct dca_cts_frame*)pktCTRL_->access(hdr_mac::offset_); timeout = txtime(ETHER_DCTS_LEN, basicRate_) + DSSS_MaxPropagationDelay + dcts->dcts_usage_time + sifs_ + DSSS_MaxPropagationDelay + DSSS_MaxPropagationDelay; if(dcts->dcts_selected_channel == -1) { timeout = txtime(ETHER_DCTS_LEN, basicRate_); } break; case MAC_Subtype_ACK: SET_TX_STATE(MAC_ACK); timeout = txtime(ETHER_ACK_LEN, basicRate_); break; default: fprintf(stderr, "check_pktCTRL:Invalid MAC Control subtype\n"); exit(1); }//JUNGMIN if(mh->dh_fc.fc_subtype == MAC_Subtype_CTS) { } else if(mh->dh_fc.fc_subtype == MAC_Subtype_DCTS) { } else if(mh->dh_fc.fc_subtype == MAC_Subtype_ACK) { }//end of JUNGMIN TRANSMIT(pktCTRL_, timeout); return 0;}//JUNGMINintMac802_11::check_pktATIMACK(){ struct hdr_mac802_11 *mh; double timeout; if(pktATIMACK_ == 0) return -1; if(tx_state_ == MAC_ATIMACK) return -1; mh = HDR_MAC802_11(pktATIMACK_); switch(mh->dh_fc.fc_subtype) { case MAC_Subtype_ATIMACK: SET_TX_STATE(MAC_ATIMACK); timeout = txtime(ETHER_ATIMACK_LEN, basicRate_) ; break; default: fprintf(stderr, "check_pktATIMACK: Invalid MAC Management subtype\n"); exit(1); } TRANSMIT(pktATIMACK_, timeout); return 0;}intMac802_11::check_pktATIMRSH(){ struct hdr_mac802_11 *mh; double timeout; if(pktATIMRSH_ == 0) return -1; if(tx_state_ == MAC_ATIMRSH) return -1; mh = HDR_MAC802_11(pktATIMRSH_); switch(mh->dh_fc.fc_subtype) { case MAC_Subtype_ATIMRSH: SET_TX_STATE(MAC_ATIMRSH); timeout = txtime(ETHER_ATIMRSH_LEN, basicRate_) ; break; default: fprintf(stderr, "check_pktATIMRSH: Invalid MAC Management subtype\n"); exit(1); } TRANSMIT(pktATIMRSH_, timeout); return 0;}//end of JUNGMINintMac802_11::check_pktRTS(){ struct hdr_mac802_11 *mh; double timeout; assert(mhBackoff_.busy() == 0); if(pktRTS_ == 0) return -1; mh = HDR_MAC802_11(pktRTS_); struct dca_rts_frame *drts; switch(mh->dh_fc.fc_subtype) { case MAC_Subtype_RTS: if(! is_idle()) { inc_cw(); mhBackoff_.start(cw_, is_idle()); return 0; } SET_TX_STATE(MAC_RTS); timeout = txtime(ETHER_RTS_LEN, basicRate_) + DSSS_MaxPropagationDelay // XXX + sifs_ + txtime(ETHER_CTS_LEN, basicRate_) + DSSS_MaxPropagationDelay; // XXX break; case MAC_Subtype_DRTS: if(! is_idle()) { inc_cw(); mhBackoff_.start(cw_, is_idle()); return 0; } SET_TX_STATE(MAC_RTS); timeout = txtime(ETHER_DRTS_LEN, basicRate_) + DSSS_MaxPropagationDelay // XXX + sifs_ + txtime(ETHER_DCTS_LEN, basicRate_) + DSSS_MaxPropagationDelay; // XXX drts = (struct dca_rts_frame*)pktRTS_->access(hdr_mac::offset_); DCABuildFreeChannelList(drts->drts_channel_list); break; default: fprintf(stderr, "check_pktRTS:Invalid MAC Control subtype\n"); exit(1); } TRANSMIT(pktRTS_, timeout); return 0;}intMac802_11::check_pktATIM(){ struct hdr_mac802_11 *mh; double timeout; assert(mhBackoff_.busy() == 0); if(pktATIM_ == 0) return -1; mh = HDR_MAC802_11(pktATIM_); struct atim_frame *atf = (struct atim_frame*)pktATIM_->access(hdr_mac::offset_); switch(mh->dh_fc.fc_subtype) { case MAC_Subtype_ATIM: if(!is_idle()) { inc_cw(); mhBackoff_.start(cw_, is_idle()); return 0; } SET_TX_STATE(MAC_ATIM); timeout = txtime(ETHER_ATIM_LEN, basicRate_) + DSSS_MaxPropagationDelay + sifs_ + txtime(ETHER_ATIMACK_LEN, basicRate_) + DSSS_MaxPropagationDelay; break; default: fprintf(stderr, "check_pktATIM: Invalid MAC Management subtype\n"); exit(1); } //copying my fcl_ onto the packet (SHOULD BE AS CLOSEST AS POSSIBLE TO ACTUAL SEND) for(int j=0; j<NUMBER_OF_CHANNELS; j++) { atf->atf_channel_list[j] = fcl_[j]; } TRANSMIT(pktATIM_, timeout); return 0;}intMac802_11::check_pktTx(){ struct hdr_mac802_11 *mh; double timeout; assert(mhBackoff_.busy() == 0); if(pktTx_ == 0) return -1; //if DCA mode, send DRSH also at the same time in different channel mh = HDR_MAC802_11(pktTx_); int len = HDR_CMN(pktTx_)->size(); struct hdr_cmn *ch = HDR_CMN(pktTx_); switch(mh->dh_fc.fc_subtype) { case MAC_Subtype_Data: if(! is_idle()) { if(dca_) { sendDRTS(ETHER_ADDR(mh->dh_da)); } else { sendRTS(ETHER_ADDR(mh->dh_da)); } inc_cw(); mhBackoff_.start(cw_, is_idle()); return 0; } SET_TX_STATE(MAC_SEND);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -