📄 mac-802_11e.cc
字号:
* I can hear the packet, the src is my neighbor */ if (netif_->node()->energy_model() && netif_->node()->energy_model()->adaptivefidelity()) { src = ETHER_ADDR(mh->dh_sa); netif_->node()->energy_model()->add_neighbor(src); } /* * Address Filtering */ if(dst != (u_int32_t)index_ && dst != MAC_BROADCAST) { /* * We don't want to log this event, so we just free * the packet instead of calling the drop routine. */ discard(pktRx_, "---"); goto done; } switch(type) { case MAC_Type_Management: discard(pktRx_, DROP_MAC_PACKET_ERROR); goto done; break; 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: fprintf(stderr,"recvTimer1:Invalid MAC Control Subtype %x\n", subtype); exit(1); } 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();}voidMac802_11e::recvRTS(Packet *p){ int pri = LEVEL(p); struct rts_frame *rf = (struct rts_frame*)p->access(hdr_mac::offset_); if(tx_state_[pri] != MAC_IDLE) { discard(p, DROP_MAC_BUSY); return; } /* * If I'm responding to someone else, discard this RTS. */ if(pktCTRL_[pri]) { discard(p, DROP_MAC_BUSY); return; } sendCTS(pri, ETHER_ADDR(rf->rf_ta), rf->rf_duration); tx_resume(); mac_log(p);}/* * txtime() - pluck the precomputed tx time from the packet header */doubleMac802_11e::txtime(Packet *p) { struct hdr_cmn *ch = HDR_CMN(p); double t = ch->txtime(); if (t < 0.0) { drop(p, "XXX"); exit(1); } return t; } /* * txtime() - calculate tx time for packet of size "psz" bytes * at rate "drt" bps */doubleMac802_11e::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);}voidMac802_11e::recvCTS(Packet *p){ int pri = LEVEL(p); if(tx_state_[pri] != MAC_RTS) { discard(p, DROP_MAC_INVALID_STATE); return; } assert(pktRTS_[pri]); Packet::free(pktRTS_[pri]); pktRTS_[pri] = 0; assert(pktTx_[pri]); // debug //struct hdr_mac802_11 *mh = HDR_MAC802_11(pktTx_); //printf("(%d):recvCTS:pktTx_-%x,mac-subtype-%d & pktCTS_:%x\n",index_,pktTx_,mh->dh_fc.fc_subtype,p); mhSend_.stop(); /* * The successful reception of this CTS packet implies * that our RTS was successful. Hence, we can reset * the Short Retry Count and the CW. */ //ssrc_ = 0; //rst_cw(); // if(mhDefer_.busy()) mhDefer_.stop(); tx_resume(); mac_log(p);}voidMac802_11e::recvDATA(Packet *p){ int pri = LEVEL(p); struct hdr_mac802_11e *dh = HDR_MAC802_11E(p); u_int32_t dst, src, size; { struct hdr_cmn *ch = HDR_CMN(p); dst = ETHER_ADDR(dh->dh_da); src = ETHER_ADDR(dh->dh_sa); size = ch->size(); /* * Adjust the MAC packet size - ie; strip * off the mac header */ ch->size() -= phymib_.getHdrLen11(); ch->num_forwards() += 1; } /* * If we sent a CTS, clean up... */ if(dst != MAC_BROADCAST) { if(size >= macmib_.RTSThreshold) { if (tx_state_[pri] == MAC_CTS) { assert(pktCTRL_[pri]); Packet::free(pktCTRL_[pri]); pktCTRL_[pri] = 0; mhSend_.stop(); /* * Our CTS got through. */ printf("(%d): RECVING DATA!\n",index_); //ssrc_ = 0; //rst_cw(); } else { discard(p, DROP_MAC_BUSY); printf("(%d)..discard DATA\n",index_); return; } sendACK(pri, src); tx_resume(); } /* * We did not send a CTS and there's no * room to buffer an ACK. */ else { if(pktCTRL_[pri]) { discard(p, DROP_MAC_BUSY); return; } sendACK(pri, src); if(mhSend_.busy() == 0){ tx_resume(); } } } /* ============================================================ Make/update an entry in our sequence number cache. ============================================================ */ /* Changed by Debojyoti Dutta. This upper loop of if{}else was suggested by Joerg Diederich <dieder@ibr.cs.tu-bs.de>. Changed on 19th Oct'2000 */ if(dst != MAC_BROADCAST) { if (src < (u_int32_t) cache_node_count_) { Host *h = &cache_[src]; if(h->seqno && h->seqno == dh->dh_scontrol) { discard(p, DROP_MAC_DUPLICATE); return; } h->seqno = dh->dh_scontrol; } else { static int count = 0; if (++count <= 10) { printf ("MAC_802_11e: accessing MAC cache_ array out of range (src %u, dst %u, size %d)!\n", src, dst, cache_node_count_); if (count == 10) printf ("[suppressing additional MAC cache_ warnings]\n"); }; }; } /* * Pass the packet up to the link-layer. * XXX - we could schedule an event to account * for this processing delay. */ //p->incoming = 1; // XXXXX NOTE: use of incoming flag has been depracated; In order to track direction of pkt flow, direction_ in hdr_cmn is used instead. see packet.h for details. uptarget_->recv(p, (Handler*) 0);}voidMac802_11e::recvACK(Packet *p){ int pri = LEVEL(p); struct hdr_cmn *ch = HDR_CMN(p); if(tx_state_[pri] != MAC_SEND) { discard(p, DROP_MAC_INVALID_STATE); return; } //printf("(%d)...................recving ACK:%x\n",index_,p); mhSend_.stop(); /* * The successful reception of this ACK packet implies * that our DATA transmission was successful. Hence, * we can reset the Short/Long Retry Count and the CW. */ if((u_int32_t) ch->size() <= macmib_.RTSThreshold) ssrc_[pri] = 0; else slrc_[pri] = 0; /* succesful transmission => give delay * to Akaroa */ if(rtx_[pri]) rtx_[pri] = 0; double delay=Scheduler::instance().clock() - start_handle_[pri]; #if AKAROA > 0 if(AKAROA index_ > 0) { AkObservation((6 * (index_ - 1)) + (pri + 4), delay); start_handle_[pri]=0; } #endif sending = 0; check_backoff_timer(); /* * Backoff before sending again. */ if(!cfb_ || ch->size() > macmib_.RTSThreshold) { assert(mhBackoff_.backoff(pri) == 0); rst_cw(pri); mhBackoff_.start(pri, getCW(pri), is_idle()); assert(pktTx_[pri]); Packet::free(pktTx_[pri]); pktTx_[pri] = 0; tx_resume(); } else{ // if this is the first packet in cfb, we must take its // duration into account, too. if(cfb_dur == 0) { cfb_dur = txtime(pktTx_[pri]) + sifs_ + txtime(phymib_.getACKlen(), basicRate_); } pktRx_ = 0; rx_resume(); assert(pktTx_[pri]); Packet::free(pktTx_[pri]); pktTx_[pri] = 0; cfb(pri); } mac_log(p);}void Mac802_11e::cfb(int pri){ double timeout; struct hdr_mac802_11e *mh; // next packet out of queue //cout<<"packets in queue:"<<queue_->pri_[pri].getLen()<<"\n"; if(queue_->pri_[pri].getLen() > 0) { Packet* p = queue_->pri_[pri].deque(); // framing sendDATA(pri, p); hdr_cmn *ch = HDR_CMN(pktTx_[pri]); mh = HDR_MAC802_11E(pktTx_[pri]); //cout<<"Mac "<<index_<<" in cfb(), pri "<<pri<<", cfb_bytes "<<cfb_bytes<<" + "<<ch->size()<<", cfb_maxbytes "<<cfb_maxbytes_<<"\n"; if((u_int32_t)ETHER_ADDR(mh->dh_da) != MAC_BROADCAST) { cfb_dur += sifs_ + txtime(pktTx_[pri]) + sifs_ + txtime(phymib_.getACKlen(), basicRate_); cfb_broadcast = 0; } else { cfb_dur += sifs_ + txtime(pktTx_[pri]); cfb_broadcast = 1; } } else cfb_dur = txop_limit_[pri] + 1; if(cfb_dur <= txop_limit_[pri]) { // send if((u_int32_t)ETHER_ADDR(mh->dh_da) != MAC_BROADCAST) timeout = txtime(pktTx_[pri]) + DSSS_EDCA_MaxPropagationDelay + sifs_ + txtime(phymib_.getACKlen(), basicRate_) + DSSS_EDCA_MaxPropagationDelay; else timeout = txtime(pktTx_[pri]); cfb_active = 1; mhSifs_.start(pri, sifs_); } else { cfb_dur = 0; cfb_broadcast = 0; assert(mhBackoff_.backoff(pri) == 0); rst_cw(pri); mhBackoff_.start(pri, getCW(pri), is_idle()); //assert(pktTx_[pri]); //Packet::free(pktTx_[pri]); pktTx_[pri] = 0; tx_resume(); }}// request parameters for each priority from the corresponding queuesdouble Mac802_11e::getAIFS(int pri){ if(!AIFSset){ levels = queue_->getLevels(); for(int i = 0; i < levels; i++ ){ slotnum = queue_->pri_[i].getAIFS(); aifs_[i] = sifs_ + (slotnum * phymib_.getSlotTime()); txop_limit_[i] = queue_->pri_[i].getTXOPLimit(); // cout<<"Mac "<<index_<<", pri: "<<i<<", txop_limit:"<<txop_limit_[i]<<"\n"; } AIFSset = 1; } return aifs_[pri];}int Mac802_11e::getCW(int level){ if(!CWset){ levels = queue_->getLevels(); for(int i = 0; i < levels; i++ ){ cw_[i] = queue_->pri_[i].getCW_MIN(); cwmin_[i] = queue_->pri_[i].getCW_MIN(); cwmax_[i] = queue_->pri_[i].getCW_MAX(); } CWset = 1; } return cw_[level];}voidMac802_11e::setQ(PriQ* priqueue){ queue_ = priqueue;}inline void Mac802_11e::reset_eifs_nav() { if (eifs_nav_ > 0) { double now = Scheduler::instance().clock(); assert(nav_ > now); assert(mhNav_.busy()); mhNav_.stop(); nav_ -= eifs_nav_; eifs_nav_ = 0.0; if (nav_ > now) { mhNav_.start(nav_ - now); } else { nav_ = now; check_backoff_timer(); } }}bool Mac802_11e::inc_retryCounter(int pri) { u_int32_t *rcount, *thresh; struct hdr_cmn *ch = HDR_CMN(pktTx_[pri]); if((u_int32_t) ch->size() <= macmib_.RTSThreshold) { ssrc_[pri]++; rcount = &ssrc_[pri]; thresh = &macmib_.ShortRetryLimit; } else { slrc_[pri]++; rcount = &slrc_[pri]; thresh = &macmib_.LongRetryLimit; } if(*rcount > *thresh) { rtx_[pri] = 0; macmib_.FailedCount++; rst_cw(pri); discard(pktTx_[pri], DROP_MAC_RETRY_COUNT_EXCEEDED); pktTx_[pri] = 0; *rcount = 0; return 1; } else return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -