📄 mac-802_11_brdcst.cc
字号:
* failed. */ if( ch->error() ) { Packet::free(pktRx_); set_nav(usec(phymib_.getEIFS())); goto done; } /* * IEEE 802.11 specs, section 9.2.5.6 * - update the NAV (Network Allocation Vector) */ if(dst != (u_int32_t)index_) { set_nav(mh->dh_duration); } // VIVEK Scenario dependent logging // ETT_ETX_HACK // For ETX Only log data pkts here, not ACK, RTS, CTS etc. if ((type == MAC_Type_Data) && (MAC_Subtype_Data == subtype) && (ch->size() == 127)) printf(TIME_FORMAT " %d %d %d %f %f %f %d\n", Scheduler::instance().clock(), addr(), ETHER_ADDR(mh->dh_ta), ETHER_ADDR(mh->dh_ra), mWtodB(pktRx_->txinfo_.RxPr*1000.0), mWtodB(pktRx_->get_interference()*1000.0), mWtodB(pktRx_->txinfo_.CPThresh), ch->size()); // For ETT Only log data pkts addressed to me// if ((type == MAC_Type_Data) && (MAC_Subtype_Data == subtype) && (addr() == ETHER_ADDR(mh->dh_ra)) && (ch->size() == 127)) // printf(TIME_FORMAT " %d %d %d %f %f %f %d\n", Scheduler::instance().clock(), addr(), ETHER_ADDR(mh->dh_ta), ETHER_ADDR(mh->dh_ra), mWtodB(pktRx_->txinfo_.RxPr*1000.0), mWtodB(pktRx_->get_interference()*1000.0), mWtodB(pktRx_->txinfo_.CPThresh), ch->size());// printf(TIME_FORMAT " [%d]: %d->%d Pr=%f, interf=%f, CPTh=%f, lth=%d\n", Scheduler::instance().clock(), addr(), ETHER_ADDR(mh->dh_ta), ETHER_ADDR(mh->dh_ra), mWtodB(pktRx_->txinfo_.RxPr*1000.0), mWtodB(pktRx_->get_interference()*1000.0), mWtodB(pktRx_->txinfo_.CPThresh), ch->size()); /* tap out - */ if (tap_ && type == MAC_Type_Data && MAC_Subtype_Data == subtype ) tap_->tap(pktRx_); /* * Adaptive Fidelity Algorithm Support - neighborhood infomation * collection * * Hacking: Before filter the packet, log the neighbor node * 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_ta); 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; 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_11::recvRTS(Packet *p){ struct rts_frame *rf = (struct rts_frame*)p->access(hdr_mac::offset_); if(tx_state_ != MAC_IDLE) { discard(p, DROP_MAC_BUSY); return; } /* * If I'm responding to someone else, discard this RTS. */ if(pktCTRL_) { discard(p, DROP_MAC_BUSY); return; } sendCTS(ETHER_ADDR(rf->rf_ta), rf->rf_duration); /* * Stop deferring - will be reset in tx_resume(). */ if(mhDefer_.busy()) mhDefer_.stop(); tx_resume(); mac_log(p);}/* * txtime() - pluck the precomputed tx time from the packet header */doubleMac802_11::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_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);}voidMac802_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);}voidMac802_11::recvDATA(Packet *p){ struct hdr_mac802_11 *dh = HDR_MAC802_11(p); u_int32_t dst, src, size; struct hdr_cmn *ch = HDR_CMN(p); dst = ETHER_ADDR(dh->dh_ra); src = ETHER_ADDR(dh->dh_ta); 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_.getRTSThreshold()) { if (tx_state_ == MAC_CTS) { assert(pktCTRL_); Packet::free(pktCTRL_); pktCTRL_ = 0; mhSend_.stop(); /* * Our CTS got through. */ } else { discard(p, DROP_MAC_BUSY); return; } sendACK(src); tx_resume(); } else { /* * We did not send a CTS and there's no * room to buffer an ACK. */ if(pktCTRL_) { discard(p, DROP_MAC_BUSY); return; } sendACK(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_11: 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. */ /* in BSS mode, if a station receives a packet via * the AP, and higher layers are interested in looking * at the src address, we might need to put it at * the right place - lest the higher layers end up * believing the AP address to be the src addr! a quick * grep didn't turn up any higher layers interested in * the src addr though! * anyway, here if I'm the AP and the destination * address (in dh_3a) isn't me, then we have to fwd * the packet; we pick the real destination and set * set it up for the LL; we save the real src into * the dh_3a field for the 'interested in the info' * receiver; we finally push the packet towards the * LL to be added back to my queue - accomplish this * by reversing the direction!*/ if ((bss_id() == addr()) && ((u_int32_t)ETHER_ADDR(dh->dh_ra)!= MAC_BROADCAST)&& ((u_int32_t)ETHER_ADDR(dh->dh_3a) != ((u_int32_t)addr()))) { struct hdr_cmn *ch = HDR_CMN(p); u_int32_t dst = ETHER_ADDR(dh->dh_3a); u_int32_t src = ETHER_ADDR(dh->dh_ta); /* if it is a broadcast pkt then send a copy up * my stack also */ if (dst == MAC_BROADCAST) { uptarget_->recv(p->copy(), (Handler*) 0); } ch->next_hop() = dst; STORE4BYTE(&src, (dh->dh_3a)); ch->addr_type() = NS_AF_ILINK; ch->direction() = hdr_cmn::DOWN; } uptarget_->recv(p, (Handler*) 0);}voidMac802_11::recvACK(Packet *p){ // VIVEK_ARF struct hdr_mac802_11* dh = HDR_MAC802_11(pktTx_); // Rcvr address is in pktTx_, not in p which is the ACK pkt int arf_index; if(tx_state_ != MAC_SEND) { discard(p, DROP_MAC_INVALID_STATE); return; } assert(pktTx_); mhSend_.stop(); // VIVEK_ARF Increase rate if possible arf_index = ARF_find_index(dh->dh_ra); if((arf_index != -1) && (ARF_Entry[arf_index].algorithm != AUTO_RATE_NONE)){// Do this only if Auto rate is used ARF_success(arf_index); } /* * 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. * * need to check the size of the packet we sent that's being * ACK'd, not the size of the ACK packet. */ if((u_int32_t) HDR_CMN(pktTx_)->size() <= macmib_.getRTSThreshold()) ssrc_ = 0; else slrc_ = 0; rst_cw(); Packet::free(pktTx_); pktTx_ = 0; /* * Backoff before sending again. */ assert(mhBackoff_.busy() == 0); mhBackoff_.start(cw_, is_idle()); tx_resume(); mac_log(p);}// VIVEK_ARF// ARF Algorithm details obtained from//// ftp://ftp.inria.fr/INRIA/publication/publi-pdf/RR/RR-5208.pdf//// IEEE 802.11 Rate Adaptation: A Practical Approach// Mathieu Lacage, Hossein Manshaei, Thierry Turletti// See mac-802_11.h for details//void Mac802_11::ARF_success(int index){ ARF_Entry[index].num_failed = 0;// Reset failure counter if(ARF_Entry[index].probing_tx){// This was a probing tx, and it succeeded ARF_Entry[index].probing_tx = 0;// Next tx is normal } ARF_Entry[index].num_success++; if(ARF_Entry[index].num_success == ARF_Entry[index].success_thresh){ if(ARF_Entry[index].rate_index<NUM_DISCRETE_RATES-1){ ARF_Entry[index].rate_index++; // Increase rate ARF_Entry[index].num_success = 0; // Reset success counter ARF_Entry[index].timer = ARF_TIMEOUT;// Reset timer ARF_Entry[index].probing_tx = 1; // Next tx is a probe// printf(TIME_FORMAT " ARF_DEBUG Node[%d]->%d: Thresh: Rate increased to %d\n", Scheduler::instance().clock(), addr(), ARF_Entry[index].MAC_ID, ARF_Entry[index].rate_index); } } return;}void Mac802_11::ARF_timer_expired(int index){ ARF_Entry[index].timer = ARF_TIMEOUT;// Reset timer if(ARF_Entry[index].rate_index<NUM_DISCRETE_RATES-1){ ARF_Entry[index].rate_index++; // Increase rate ARF_Entry[index].probing_tx = 1; // Next tx is a probe // printf(TIME_FORMAT " ARF_DEBUG Node[%d]->%d: Probe: Rate increased to %d\n", Scheduler::instance().clock(), addr(), ARF_Entry[index].MAC_ID, ARF_Entry[index].rate_index); } return;}void Mac802_11::ARF_decr_rate(int index){ ARF_Entry[index].num_failed++; ARF_Entry[index].num_success = 0; // Reset success counter if((ARF_Entry[index].probing_tx) || (ARF_Entry[index].num_failed == ARF_FAILURE_THRESHOLD)){ // This was a probing tx, and it failed, lower rate // Or, you have ARF_FAILURE_THRESHOLD successive failures if(ARF_Entry[index].rate_index>0){ ARF_Entry[index].rate_index--; // Decrease rate if possible// if(ARF_Entry[index].probing_tx)// printf(TIME_FORMAT " ARF_DEBUG Node[%d]->%d: Probe loss: Rate decreased to %d\n", Scheduler::instance().clock(), addr(), ARF_Entry[index].MAC_ID, ARF_Entry[index].rate_index);// else// printf(TIME_FORMAT " ARF_DEBUG Node[%d]->%d: 2-pkt loss: Rate decreased to %d\n", Scheduler::instance().clock(), addr(), ARF_Entry[index].MAC_ID, ARF_Entry[index].rate_index); } // AARF // This is the only place where ARF and AARF differ if((ARF_Entry[index].probing_tx) && (ARF_Entry[index].algorithm==AUTO_RATE_AARF) && (2*ARF_Entry[index].success_thresh < MAX_AARF_SUCCESS_THRESHOLD)){ // Probing pkt lost // Algo is AARF // threshold can be doubled ARF_Entry[index].success_thresh *= 2; // Binary Exponential Backoff// printf("ARF_DEBUG Node[%d]->%d: BEB AARF thresh %d to %d\n", addr(), ARF_Entry[index].MAC_ID, ARF_Entry[index].success_thresh/2, ARF_Entry[index].success_thresh); } if((ARF_Entry[index].num_failed == ARF_FAILURE_THRESHOLD) && (ARF_Entry[index].algorithm==AUTO_RATE_AARF)){ // 2 consecutive lost pkts // Algorithm is AARF // printf("ARF_DEBUG Node[%d]->%d: Reset AARF thresh %d to %d\n", addr(), ARF_Entry[index].MAC_ID, ARF_Entry[index].success_thresh, ARF_SUCCESS_THRESHOLD); ARF_Entry[index].success_thresh = ARF_SUCCESS_THRESHOLD; // reset to minimum } // AARF ARF_Entry[index].timer = ARF_TIMEOUT; // reset timer if(ARF_Entry[index].num_failed == ARF_FAILURE_THRESHOLD) ARF_Entry[index].num_failed = 0; //Reset this counter// printf("Node[%d]->%d: Reset timer\n", addr(), ARF_Entry[index].MAC_ID); ARF_Entry[index].probing_tx = 0; // Next tx is normal, not probe; } return;}int Mac802_11::ARF_find_index(u_char* macaddr){ int i, MAC_ID; MAC_ID = (u_int32_t)ETHER_ADDR(macaddr); if(counter_==0) // No auto rate. Defualt return -1; for(i=0;i<counter_;i++){// printf("Node[%d]: ARF_Entry[%d].MAC_ID=%d\n", addr(), i, ARF_Entry[i].MAC_ID); if(MAC_ID == ARF_Entry[i].MAC_ID) return i; }// printf("ARF_find_index(): Something WRONG, MAC_ID=%d!\n", MAC_ID); return -1;}void Mac802_11::ARF_update_txtime(Packet *p, int index){ hdr_cmn* ch = HDR_CMN(p);// printf("Node[%d]->%d; Index:CPTHRESH:TXTIME from %f:%f to ", addr(), p->txinfo_.CPThresh, ch->txtime()); p->txinfo_.CPThresh = link_SINR[ARF_Entry[index].rate_index]; ch->txtime() = txtime(ch->size(), link_bitrate[ARF_Entry[index].rate_index]);// printf("%f:%f\n", p->txinfo_.CPThresh, ch->txtime()); return;}// VIVEK_ARF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -