📄 mac-802_11e.cc
字号:
hdr_cmn* ch = HDR_CMN(p); struct cts_frame *cf = (struct cts_frame*)p->access(hdr_mac::offset_); assert(pktCTRL_[pri] == 0); ch->uid() = 0; ch->ptype() = PT_MAC; ch->size() = phymib_.getCTSlen(); ch->iface() = -2; ch->error() = 0; //ch->direction() = hdr_cmn::DOWN; bzero(cf, MAC_HDR_LEN); cf->cf_fc.fc_protocol_version = MAC_ProtocolVersion; cf->cf_fc.fc_type = MAC_Type_Control; cf->cf_fc.fc_subtype = MAC_Subtype_CTS; cf->cf_fc.fc_to_ds = 0; cf->cf_fc.fc_from_ds = 0; cf->cf_fc.fc_more_frag = 0; cf->cf_fc.fc_retry = 0; cf->cf_fc.fc_pwr_mgt = 0; cf->cf_fc.fc_more_data = 0; cf->cf_fc.fc_wep = 0; cf->cf_fc.fc_order = 0; //cf->cf_duration = CTS_DURATION(rts_duration); STORE4BYTE(&dst, (cf->cf_ra)); /* store cts tx time */ ch->txtime() = txtime(ch->size(), basicRate_); /* calculate cts duration */ cf->cf_duration = usec(sec(rts_duration) - sifs_ - txtime(phymib_.getCTSlen(), basicRate_)); pktCTRL_[pri] = p; }voidMac802_11e::sendACK(int pri, int dst){ Packet *p = Packet::alloc(); hdr_cmn* ch = HDR_CMN(p); struct ack_frame *af = (struct ack_frame*)p->access(hdr_mac::offset_); assert(pktCTRL_[pri] == 0); ch->uid() = 0; // ACK-UID ch->ptype() = PT_MAC; ch->size() = phymib_.getACKlen(); ch->iface() = -2; ch->error() = 0; HDR_IP(p)->prio() = pri; //same priority as data packet bzero(af, MAC_HDR_LEN); af->af_fc.fc_protocol_version = MAC_ProtocolVersion; af->af_fc.fc_type = MAC_Type_Control; af->af_fc.fc_subtype = MAC_Subtype_ACK; af->af_fc.fc_to_ds = 0; af->af_fc.fc_from_ds = 0; af->af_fc.fc_more_frag = 0; af->af_fc.fc_retry = 0; af->af_fc.fc_pwr_mgt = 0; af->af_fc.fc_more_data = 0; af->af_fc.fc_wep = 0; af->af_fc.fc_order = 0; //af->af_duration = ACK_DURATION(); STORE4BYTE(&dst, (af->af_ra)); /* store ack tx time */ ch->txtime() = txtime(ch->size(), basicRate_); /* calculate ack duration */ af->af_duration = 0; pktCTRL_[pri] = p;}voidMac802_11e::sendDATA(int pri, Packet *p){ hdr_cmn* ch = HDR_CMN(p); struct hdr_mac802_11e* dh = HDR_MAC802_11E(p); assert(pktTx_[pri] == 0); /* * Update the MAC header */ ch->size() += phymib_.getHdrLen11(); dh->dh_fc.fc_protocol_version = MAC_ProtocolVersion; dh->dh_fc.fc_type = MAC_Type_Data; dh->dh_fc.fc_subtype = MAC_Subtype_Data; //printf(".....p = %x, mac-subtype-%d\n",p,dh->dh_fc.fc_subtype); dh->dh_fc.fc_to_ds = 0; dh->dh_fc.fc_from_ds = 0; dh->dh_fc.fc_more_frag = 0; dh->dh_fc.fc_retry = 0; dh->dh_fc.fc_pwr_mgt = 0; dh->dh_fc.fc_more_data = 0; dh->dh_fc.fc_wep = 0; dh->dh_fc.fc_order = 0; /* store data tx time */ if((u_int32_t)ETHER_ADDR(dh->dh_da) != MAC_BROADCAST) { /* store data tx time for unicast packets */ ch->txtime() = txtime(ch->size(), dataRate_); //dh->dh_duration = DATA_DURATION(); dh->dh_duration = usec(txtime(phymib_.getACKlen(), basicRate_) + sifs_); } else { /* store data tx time for broadcast packets (see 9.6) */ ch->txtime() = txtime(ch->size(), basicRate_); dh->dh_duration = 0; } pktTx_[pri] = p;}/* ====================================================================== Retransmission Routines ====================================================================== */voidMac802_11e::RetransmitRTS(int pri){ assert(pktTx_[pri]); assert(pktRTS_[pri]); assert(mhBackoff_.backoff(pri) == 0); macmib_.RTSFailureCount++; ssrc_[pri] += 1; // STA Short Retry Count if(ssrc_[pri] >= macmib_.ShortRetryLimit) { discard(pktRTS_[pri], DROP_MAC_RETRY_COUNT_EXCEEDED); pktRTS_[pri] = 0; /* tell the callback the send operation failed before discarding the packet */ hdr_cmn *ch = HDR_CMN(pktTx_[pri]); if (ch->xmit_failure_) { /* * Need to remove the MAC header so that * re-cycled packets don't keep getting * bigger. */ ch->size() -= phymib_.getHdrLen11(); ch->xmit_reason_ = XMIT_REASON_RTS; ch->xmit_failure_(pktTx_[pri]->copy(), ch->xmit_failure_data_); } //printf("(%d)....discarding RTS:%x\n",index_,pktRTS_); rst_cw(pri); discard(pktTx_[pri], DROP_MAC_RETRY_COUNT_EXCEEDED); pktTx_[pri] = 0; ssrc_[pri] = 0; } else { //printf("(%d)...retxing RTS:%x\n",index_,pktRTS_); struct rts_frame *rf; rf = (struct rts_frame*)pktRTS_[pri]->access(hdr_mac::offset_); rf->rf_fc.fc_retry = 1; inc_cw(LEVEL(pktTx_[pri])); mhBackoff_.start(LEVEL(pktTx_[pri]), getCW(pri), is_idle()); }}voidMac802_11e::RetransmitDATA(int pri){ struct hdr_cmn *ch; struct hdr_mac802_11e *mh; u_int32_t *rcount, *thresh; assert(mhBackoff_.backoff(pri) == 0); assert(pktTx_[pri]); assert(pktRTS_[pri] == 0); ch = HDR_CMN(pktTx_[pri]); mh = HDR_MAC802_11E(pktTx_[pri]); /* * Broadcast packets don't get ACKed and therefore * are never retransmitted. */ if((u_int32_t)ETHER_ADDR(mh->dh_da) == MAC_BROADCAST) { /* * Backoff at end of TX. */ if(!cfb_ || rx_state_ != MAC_IDLE){ rst_cw(pri); mhBackoff_.start(pri, getCW(pri), is_idle()); Packet::free(pktTx_[pri]); pktTx_[pri] = 0; return; } else{ // if this is the first packet in cfb, we must take its // duration into account, too. if(cfb_dur == 0) { //cout<<"Mac "<<index<<", setting cfb_dur after Broadcast\n"; cfb_dur = txtime(pktTx_[pri]) + sifs_; //+ txtime(phymib_.getACKlen(), basicRate_); } assert(pktTx_[pri]); Packet::free(pktTx_[pri]); pktTx_[pri] = 0; cfb(pri); return; } } else if(cfb_) cfb_dur = 0; macmib_.ACKFailureCount++; rtx_[pri] = 1; if((u_int32_t) ch->size() <= macmib_.RTSThreshold) { rcount = &ssrc_[pri]; thresh = &macmib_.ShortRetryLimit; } else { rcount = &slrc_[pri]; thresh = &macmib_.LongRetryLimit; } (*rcount)++; if(*rcount > *thresh) { numbytes_[pri] -= ch->size() - phymib_.getHdrLen11(); rtx_[pri] = 0; macmib_.FailedCount++; /* tell the callback the send operation failed before discarding the packet */ hdr_cmn *ch = HDR_CMN(pktTx_[pri]); if (ch->xmit_failure_) { ch->size() -= phymib_.getHdrLen11(); ch->xmit_reason_ = XMIT_REASON_ACK; ch->xmit_failure_(pktTx_[pri]->copy(), ch->xmit_failure_data_); } rst_cw(pri); discard(pktTx_[pri], DROP_MAC_RETRY_COUNT_EXCEEDED); pktTx_[pri] = 0; //printf("(%d)DATA discarded: count exceeded\n",index_); *rcount = 0; } else { struct hdr_mac802_11e *dh; dh = HDR_MAC802_11E(pktTx_[pri]); dh->dh_fc.fc_retry = 1; sendRTS(pri, ETHER_ADDR(mh->dh_da)); //printf("(%d)retxing data:%x..sendRTS..\n",index_,pktTx_); inc_cw(LEVEL(pktTx_[pri])); mhBackoff_.start(pri, getCW(pri), is_idle()); }}/* ====================================================================== Incoming Packet Routines ====================================================================== */voidMac802_11e::send(Packet *p, Handler *h){ int pri = LEVEL(p); start_handle_[pri]=Scheduler::instance().clock(); double rTime; struct hdr_mac802_11e* dh = HDR_MAC802_11E(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_[pri] = h; sendDATA(pri, p); // framing and calculation of tx Duration sendRTS(pri, ETHER_ADDR(dh->dh_da)); //check whether size exceeds RTSthreshold /* * 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. */ assert(mhDefer_.defer(pri) == 0); if(mhBackoff_.backoff(pri) == 0) { //Mac can be still in post-backoff if(is_idle()) { /* * If we are already deferring, there is no * need to reset the Defer timer. */ if(mhDefer_.defer(pri) == 0) { rTime = ((Random::random() % getCW(LEVEL(p))) * phymib_.getSlotTime()); mhDefer_.start(LEVEL(p), getAIFS(LEVEL(p))); // + rTime);// - phymib_.getSlotTime()); } } /* * If the medium is NOT IDLE, then we start * the backoff timer. */ else { mhBackoff_.start(LEVEL(p),getCW(LEVEL(p)), is_idle()); } } }voidMac802_11e::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) { Scheduler &s = Scheduler::instance(); 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. */ Scheduler &s = Scheduler::instance(); if(tx_active_ && hdr->error() == 0 ) { hdr->error() = 1; } if(rx_state_ == MAC_IDLE) { set_rx_state(MAC_RECV); pktRx_ = p; /* * Schedule the reception of this packet, in * txtime seconds. */ mhRecv_.start(txtime(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_11e::recv_timer(){ Scheduler &s = Scheduler::instance(); u_int32_t src; hdr_cmn *ch = HDR_CMN(pktRx_); hdr_mac802_11e *mh = HDR_MAC802_11E(pktRx_); 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_)); eifs_nav_ = 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_)); eifs_nav_ = eifs_; goto done; } /* * avoid Nav-reset bug: * if received packet has no errors and had no collision, but nav * was set due to an earlier collision, nav has to be reset! */ if(mhNav_.busy()) reset_eifs_nav(); /* * 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); } /* 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -