📄 mac-802_11e.cc
字号:
Mac802_11e::txHandler(){ tx_active_ = 0; if(cfb_ && !cfb_broadcast) cfb_active = 0; if(cfb_broadcast) cfb_broadcast = 0;}voidMac802_11e::defer_stop(int pri){ mhBackoff_.start(pri, getCW(pri), is_idle());}/* sends the throughput every INTERVAL to Akaroa * via AkObservation. This works only if you have * installed Akaroa and the ns-2/Akaroa interface. */voidMac802_11e::calc_throughput(){#if AKAROA > 0 if(AKAROA){ if(index_ > 0){ //int pri = 2; // jitter is for cases in which the simulation is // already in a steady state at the very beginning if (jitter >0) {if(jitter >= 10 ) jitter -= 10; jitter = (-1) * jitter;} for(int pri = 0; pri < 3; pri++){ if(jitter > 0){ throughput = jitter + ((numbytes_[pri] * 8.) / interval_); }else { throughput = (8. * numbytes_[pri]) / interval_; } if(throughput <= 0) throughput = 0.0001; AkObservation((3 * (index_ - 1)) + (pri + 1), throughput); //AkObservation((pri + 1), throughput); //AkObservation(1, throughput); //if(index_ == 1 && pri == 0) { cout.precision(16); // cout<<"Mac "<<index_<<", now: "<<Scheduler::instance().clock()<<", priority "<<pri<<", throughput: "<<throughput<<", interval_: "<<interval_<<" numbytes " << numbytes_[pri] << "\n"; //} numbytes_[pri] = 0; throughput = 0; } AK.start(); } }#endif}/* ====================================================================== The "real" Timer Handler Routines ====================================================================== */voidMac802_11e::send_timer(){ Scheduler &s = Scheduler::instance(); for(int pri = 0; pri < MAX_PRI; pri ++){ switch(tx_state_[pri]) { /* * Sent a RTS, but did not receive a CTS. */ case MAC_RTS: RetransmitRTS(pri); break; /* * Sent a CTS, but did not receive a DATA packet. */ case MAC_CTS: assert(pktCTRL_[pri]); Packet::free(pktCTRL_[pri]); pktCTRL_[pri] = 0; break; /* * Sent DATA, but did not receive an ACK packet. */ case MAC_SEND: RetransmitDATA(pri); break; /* * Sent an ACK, and now ready to resume transmission. */ case MAC_ACK: assert(pktCTRL_[pri]); Packet::free(pktCTRL_[pri]); pktCTRL_[pri] = 0; break; case MAC_IDLE: break; default: assert(0); } } // if(mhDefer_.busy()) mhDefer_.stop(); if(!cfb_active) tx_resume(); }/* ====================================================================== Outgoing Packet Routines ====================================================================== */intMac802_11e::check_pktCTRL(int pri) { struct hdr_mac802_11 *mh; double timeout; if(pktCTRL_[pri] == 0) return -1; if(tx_state_[pri] == MAC_CTS || tx_state_[pri] == MAC_ACK) return -1; mh = HDR_MAC802_11(pktCTRL_[pri]); 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_[pri], DROP_MAC_BUSY); pktCTRL_[pri] = 0; return 0; } SET_TX_STATE(pri, 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_EDCF_MaxPropagationDelay // XXX + sec(mh->dh_duration) + DSSS_EDCF_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_ACK: SET_TX_STATE(pri, MAC_ACK); timeout = txtime(ETHER_ACK_LEN, basicRate_); break; default: fprintf(stderr, "check_pktCTRL:Invalid MAC Control subtype\n"); exit(1); } transmit(pktCTRL_[pri], timeout); return 0;}intMac802_11e::check_pktRTS(int pri) { struct hdr_mac802_11 *mh; double timeout; assert(mhBackoff_.backoff(pri) == 0); if(pktRTS_[pri] == 0) return -1; //struct hdr_cmn *ch = HDR_CMN(pktRTS_); mh = HDR_MAC802_11(pktRTS_[pri]); switch(mh->dh_fc.fc_subtype) { case MAC_Subtype_RTS: if(! is_idle()) { inc_cw(pri); mhBackoff_.start(pri, getCW(pri), is_idle()); return 0; } SET_TX_STATE(pri, MAC_RTS); timeout = txtime(ETHER_RTS_LEN, basicRate_) + DSSS_EDCF_MaxPropagationDelay // XXX + sifs_ + txtime(ETHER_CTS_LEN, basicRate_) + DSSS_EDCF_MaxPropagationDelay; // XXX break; default: fprintf(stderr, "check_pktRTS:Invalid MAC Control subtype\n"); exit(1); } transmit(pktRTS_[pri], timeout); return 0;}int Mac802_11e::check_pktTx(int pri){ struct hdr_mac802_11 *mh; double timeout; assert(mhBackoff_.backoff(pri) == 0); if(pktTx_[pri] == 0) { return -1; } mh = HDR_MAC802_11(pktTx_[pri]); //int len = HDR_CMN(pktTx_)->size(); switch(mh->dh_fc.fc_subtype) { case MAC_Subtype_Data: /*if(!is_idle()){ sendRTS(pri, ETHER_ADDR(mh->dh_da)); inc_cw(LEVEL(pktTx_[pri])); mhBackoff_.start(LEVEL(pktTx_[pri]), getCW(LEVEL(pktTx_[pri])), is_idle()); return 0; }*/ SET_TX_STATE(pri, MAC_SEND); if((u_int32_t)ETHER_ADDR(mh->dh_da) != MAC_BROADCAST) timeout = txtime(pktTx_[pri]) + DSSS_EDCF_MaxPropagationDelay // XXX + sifs_ + txtime(ETHER_ACK_LEN, basicRate_) + DSSS_EDCF_MaxPropagationDelay; // XXX else timeout = txtime(pktTx_[pri]); break; default: fprintf(stderr, "check_pktTx:Invalid MAC Control subtype\n"); //printf("pktRTS:%x, pktCTS/ACK:%x, pktTx:%x\n",pktRTS_, pktCTRL_,pktTx_); exit(1); } transmit(pktTx_[pri], timeout); return 0;}/* * Low-level transmit functions that actually place the packet onto * the channel. */voidMac802_11e::sendRTS(int pri, int dst){ Packet *p = Packet::alloc(); hdr_cmn* ch = HDR_CMN(p); struct rts_frame *rf = (struct rts_frame*)p->access(hdr_mac::offset_); assert(pktTx_[pri]); assert(pktRTS_[pri] == 0); /* * If the size of the packet is larger than the * RTSThreshold, then perform the RTS/CTS exchange. * * XXX: also skip if destination is a broadcast */ if( (u_int32_t) HDR_CMN(pktTx_[pri])->size() < macmib_->RTSThreshold || (u_int32_t) dst == MAC_BROADCAST) { Packet::free(p); //p = 0; return; } ch->uid() = 0; ch->ptype() = PT_MAC; ch->size() = ETHER_RTS_LEN; ch->iface() = -2; ch->error() = 0; bzero(rf, MAC_HDR_LEN); rf->rf_fc.fc_protocol_version = MAC_ProtocolVersion; rf->rf_fc.fc_type = MAC_Type_Control; rf->rf_fc.fc_subtype = MAC_Subtype_RTS; rf->rf_fc.fc_to_ds = 0; rf->rf_fc.fc_from_ds = 0; rf->rf_fc.fc_more_frag = 0; rf->rf_fc.fc_retry = 0; rf->rf_fc.fc_pwr_mgt = 0; rf->rf_fc.fc_more_data = 0; rf->rf_fc.fc_wep = 0; rf->rf_fc.fc_order = 0; //rf->rf_duration = RTS_DURATION(pktTx_); STORE4BYTE(&dst, (rf->rf_ra)); /* store rts tx time */ ch->txtime() = txtime(ch->size(), basicRate_); STORE4BYTE(&index_, (rf->rf_ta)); /* calculate rts duration field */ rf->rf_duration = usec(sifs_ + txtime(ETHER_CTS_LEN, basicRate_) + sifs_ + txtime(pktTx_[pri]) + sifs_ + txtime(ETHER_ACK_LEN, basicRate_)); pktRTS_[pri] = p;}voidMac802_11e::sendCTS(int pri, int dst, double rts_duration){ Packet *p = Packet::alloc(); 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() = ETHER_CTS_LEN; 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(ETHER_CTS_LEN, 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() = ETHER_ACK_LEN; 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_11* dh = HDR_MAC802_11(p); assert(pktTx_[pri] == 0); /* * Update the MAC header */ ch->size() += ETHER_HDR_LEN11; 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(ETHER_ACK_LEN, 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() -= ETHER_HDR_LEN11; 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_11 *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_11(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(ETHER_ACK_LEN, 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() - ETHER_HDR_LEN11; 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() -= ETHER_HDR_LEN11; 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_11 *dh; dh = HDR_MAC802_11(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); double rTime; 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_[pri] = h; sendDATA(pri, p); // framing und Berechnung der Tx-Duration sendRTS(pri, ETHER_ADDR(dh->dh_da)); //check, ob packet groesser als RTSthreshold /* * Assign the data packet a sequence number. */ dh->dh_scontrol = sta_seqno_++; /* * If the medium is IDLE, we must wait for a DIFS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -