📄 mac-802_11.c
字号:
pktTx_ = p;}/* ====================================================================== Retransmission Routines ====================================================================== */voidMac802_11::RetransmitRTS(){ assert(pktTx_); assert(pktRTS_); assert(mhBackoff_.busy() == 0); macmib_->RTSFailureCount++; ssrc_ += 1; // STA Short Retry Count if(ssrc_ >= macmib_->ShortRetryLimit) { discard(pktRTS_, DROP_MAC_RETRY_COUNT_EXCEEDED); pktRTS_ = 0; /* tell the callback the send operation failed before discarding the packet */ hdr_cmn *ch = HDR_CMN(pktTx_); if (ch->xmit_failure_) { /* * Need to remove the MAC header so that * re-cycled packets don't keep getting * bigger. */ ch->size() -= ETHER_HDR_LEN; ch->xmit_reason_ = XMIT_REASON_RTS; ch->xmit_failure_(pktTx_->copy(), ch->xmit_failure_data_); } //printf("(%d)....discarding RTS:%x\n",index_,pktRTS_); discard(pktTx_, DROP_MAC_RETRY_COUNT_EXCEEDED); pktTx_ = 0; ssrc_ = 0; rst_cw(); } else { //printf("(%d)...retxing RTS:%x\n",index_,pktRTS_); struct rts_frame *rf; rf = (struct rts_frame*)pktRTS_->access(hdr_mac::offset_); rf->rf_fc.fc_retry = 1; inc_cw(); mhBackoff_.start(cw_, is_idle()); }}voidMac802_11::RetransmitDATA(){ struct hdr_cmn *ch; struct hdr_mac802_11 *mh; u_int32_t *rcount, *thresh; assert(mhBackoff_.busy() == 0); assert(pktTx_); assert(pktRTS_ == 0); ch = HDR_CMN(pktTx_); mh = HDR_MAC802_11(pktTx_); /* * Broadcast packets don't get ACKed and therefore * are never retransmitted. */ if((u_int32_t)ETHER_ADDR(mh->dh_da) == MAC_BROADCAST) { Packet::free(pktTx_); pktTx_ = 0; /* * Backoff at end of TX. */ rst_cw(); mhBackoff_.start(cw_, is_idle()); return; } macmib_->ACKFailureCount++; if((u_int32_t) ch->size() <= macmib_->RTSThreshold) { rcount = &ssrc_; thresh = &macmib_->ShortRetryLimit; } else { rcount = &slrc_; thresh = &macmib_->LongRetryLimit; } (*rcount)++; if(*rcount > *thresh) { macmib_->FailedCount++; /* tell the callback the send operation failed before discarding the packet */ hdr_cmn *ch = HDR_CMN(pktTx_); if (ch->xmit_failure_) { ch->size() -= ETHER_HDR_LEN; ch->xmit_reason_ = XMIT_REASON_ACK; ch->xmit_failure_(pktTx_->copy(), ch->xmit_failure_data_); } discard(pktTx_, DROP_MAC_RETRY_COUNT_EXCEEDED); pktTx_ = 0; //printf("(%d)DATA discarded: count exceeded\n",index_); *rcount = 0; rst_cw(); } else { struct hdr_mac802_11 *dh; dh = HDR_MAC802_11(pktTx_); dh->dh_fc.fc_retry = 1; sendRTS(ETHER_ADDR(mh->dh_da)); //printf("(%d)retxing data:%x..sendRTS..\n",index_,pktTx_); inc_cw(); mhBackoff_.start(cw_, is_idle()); }}/* ====================================================================== Incoming Packet Routines ====================================================================== */voidMac802_11::send(Packet *p, Handler *h){ struct hdr_mac802_11* dh = HDR_MAC802_11(p); /* * drop the packet if the node is in sleep mode XXX sleep mode can't stop node from sending packets */ EnergyModel *em = netif_->node()->energy_model(); if (em && em->sleep()) { em->set_node_sleep(0); em->set_node_state(EnergyModel::INROUTE); } callback_ = h; sendDATA(p); sendRTS(ETHER_ADDR(dh->dh_da)); /* * Assign the data packet a sequence number. */ dh->dh_scontrol = sta_seqno_++; /* * If the medium is IDLE, we must wait for a DIFS * Space before transmitting. */ if(mhBackoff_.busy() == 0) { if(is_idle()) { /* * If we are already deferring, there is no * need to reset the Defer timer. */ if(mhDefer_.busy() == 0) mhDefer_.start(difs_); } /* * If the medium is NOT IDLE, then we start * the backoff timer. */ else { mhBackoff_.start(cw_, is_idle()); } }}voidMac802_11::recv(Packet *p, Handler *h){ struct hdr_cmn *hdr = HDR_CMN(p); /* * Sanity Check */ assert(initialized()); /* * Handle outgoing packets. */ if(hdr->direction() == hdr_cmn::DOWN) { send(p, h); return; } /* * Handle incoming packets. * * We just received the 1st bit of a packet on the network * interface. * */ /* * If the interface is currently in transmit mode, then * it probably won't even see this packet. However, the * "air" around me is BUSY so I need to let the packet * proceed. Just set the error flag in the common header * to that the packet gets thrown away. */ if(tx_active_ && hdr->error() == 0) { hdr->error() = 1; } // wqos - Fri 03 Nov 00, 17:45 - dugdale if(pc_&&tx_state_ == MAC_POLLING) { // Why is this done here?????????? Check! // Might not be so good // fprintf(stderr, "Nils@%f!!! %x %x\n",Scheduler::instance().clock(),mh->dh_fc.fc_type,mh->dh_fc.fc_subtype); if(mhSend_.busy()) mhSend_.stop(); } // wqos - changes by dugdale ends if(rx_state_ == MAC_IDLE) { SET_RX_STATE(MAC_RECV); pktRx_ = p; /* * Schedule the reception of this packet, in * txtime seconds. */ mhRecv_.start(TX_Time(p)); } else { /* * If the power of the incoming packet is smaller than the * power of the packet currently being received by at least * the capture threshold, then we ignore the new packet. */ if(pktRx_->txinfo_.RxPr / p->txinfo_.RxPr >= p->txinfo_.CPThresh) { capture(p); } else { collision(p); } }}voidMac802_11::recv_timer(){ u_int32_t src; hdr_cmn *ch = HDR_CMN(pktRx_); hdr_mac802_11 *mh = HDR_MAC802_11(pktRx_); // wqos - Thu 05 Oct 00, 14:03 - dugdale struct beacon_frame *beacon; // wqos - changes by dugdale ends u_int32_t dst = ETHER_ADDR(mh->dh_da); // XXX debug //struct cts_frame *cf = (struct cts_frame*)pktRx_->access(hdr_mac::offset_); //u_int32_t src = ETHER_ADDR(mh->dh_sa); u_int8_t type = mh->dh_fc.fc_type; u_int8_t subtype = mh->dh_fc.fc_subtype; assert(pktRx_); assert(rx_state_ == MAC_RECV || rx_state_ == MAC_COLL); /* * If the interface is in TRANSMIT mode when this packet * "arrives", then I would never have seen it and should * do a silent discard without adjusting the NAV. */ if(tx_active_) { Packet::free(pktRx_); goto done; } /* * Handle collisions. */ if(rx_state_ == MAC_COLL) { discard(pktRx_, DROP_MAC_COLLISION); set_nav(usec(eifs_)); goto done; } /* * Check to see if this packet was received with enough * bit errors that the current level of FEC still could not * fix all of the problems - ie; after FEC, the checksum still * failed. */ if( ch->error() ) { Packet::free(pktRx_); set_nav(usec(eifs_)); goto done; } /* * IEEE 802.11 specs, section 9.2.5.6 * - update the NAV (Network Allocation Vector) */ if(dst != (u_int32_t)index_) { // wqos - Wed 29 Nov 00, 13:07 - dugdale // Detect CFP even if the beacon was lost... if(mh->dh_duration==32768&&!cfp_) { cfp_=1; //set_nav(macmib_->dot11CFPMaxDuration); set_nav((u_int32_t)(macmib_->dot11CFPMaxDuration*0.001024*1000000)); } else if(!cfp_) { set_nav(mh->dh_duration); } // wqos - changes by dugdale ends } /* 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_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: // wqos - Tue 03 Oct 00, 16:42 - dugdale switch(subtype) { case MAC_Subtype_Beacon: beacon = (struct beacon_frame *)pktRx_->access(hdr_mac::offset_); // Set these values received from the PC in the MACMIB macmib_->dot11CFPPeriod = beacon->bf_cfparamset.CFPPeriod; macmib_->dot11CFPMaxDuration = beacon->bf_cfparamset.CFPMaxDuration; macmib_->dot11BeaconPeriod = beacon->bf_binterval; macmib_->dot11DTIMPeriod = beacon->bf_tim.DTIMperiod; if(beacon->bf_cfparamset.CFPCount==0) { // A CFP starts here cfp_=1; fprintf(stderr,"CFP started at time %f... Duration %f\n",(Scheduler::instance()).clock(), tutos(beacon->bf_cfparamset.CFPMaxDuration)); // Set the NAV to the maximum length of the CFP set_nav((u_int32_t)(beacon->bf_cfparamset.CFPMaxDuration*0.001024*1000000)); // Set the PCF Timer // Should we really stop these timers??? Maybe just pause them... // if(mhBackoff_.busy() && !mhBackoff_.paused()) if(mhBackoff_.busy()) //mhBackoff_.pause(); mhBackoff_.stop(); if(mhSend_.busy()) mhSend_.stop(); } // We should set a timer to expire the next TBTT to know when // the next CFP should start, but that is not implemented yet // Do something else here... mac_log(pktRx_); break; default: discard(pktRx_, DROP_MAC_PACKET_ERROR); } // wqos - changes by dugdale ends 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; // wqos - Fri 13 Oct 00, 15:48 - dugdale case MAC_Subtype_CFEnd: cfp_=0; // No longer a CFP if we receive a CFEnd frame // set_nav(0); nav_=0; fprintf(stderr,"CFEnd received!\n"); if(mhNav_.busy()) mhNav_.stop(); mac_log(pktRx_); pktRx_=0; tx_resume(); break; // wqos - changes by dugdale ends 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; // wqos - Mon 09 Oct 00, 17:37 - dugdale case MAC_Subtype_CFPoll: recvPoll(pktRx_); break; // wqos - changes by dugdale ends 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_);// wqos - Mon 20 Nov 00, 19:30 - dugdale // We shouldn't answer an RTS during a CFP if(tx_state_ != MAC_IDLE||cfp_) {// wqos - changes by dugdale ends 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);}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_); // 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(); 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_da); src = ETHER_ADDR(dh->dh_sa); size = ch->size(); /* * Adjust the MAC packet size - ie; strip * off the mac header */ ch->size() -= ETHER_HDR_LEN; ch->num_forwards() += 1; } /* * If we sent a CTS, clean up... */ if(dst != MAC_BROADCAST) { if(size >= macmib_->RTSThreshold) { if (tx_state_ == MAC_CTS) { assert(pktCTRL_); Packet::free(pktCTRL_); pktCTRL_ = 0; mhSend_.stop(); /* * Our CTS got through. */ //printf("(%d): RECVING DATA!\n",index_); ssrc_ = 0; rst_cw(); } // wqos - Tue 07 Nov 00, 15:38 - dugdale // If we were polling, we could receive data even without // having sent a CTS else if(tx_state_ == MAC_POLLING) { assert(pktPCF_); Packet::free(pktPCF_); pktPCF_ = 0; if(mhSend_.busy()) mhSend_.stop(); ssrc_ = 0; rst_cw(); } // wqos - changes by dugdale ends
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -