📄 mac-802_11_brdcst.cc
字号:
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) - phymib_.getSIFS() - txtime(phymib_.getCTSlen(), basicRate_)); pktCTRL_ = p; }voidMac802_11::sendACK(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_ == 0); p->txinfo_.CPThresh = CPTHRESH_BASIC; // VIVEK_NEW ctrl pkts sent at basic rate ch->uid() = 0; ch->ptype() = PT_MAC; // CHANGE WRT Mike's code ch->size() = phymib_.getACKlen(); ch->iface() = -2; ch->error() = 0; 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_ = p;}voidMac802_11::sendDATA(Packet *p){ double Rate;// int i, found; int arf_index; u_int8_t type; u_int8_t subtype; u_int32_t rcvr_nodeID; hdr_cmn* ch = HDR_CMN(p); struct hdr_mac802_11* dh = HDR_MAC802_11(p); type = dh->dh_fc.fc_type; subtype = dh->dh_fc.fc_subtype; assert(pktTx_ == 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; 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;// VIVEK MULTI-RATE, MULTI-SINR MODULE// Depending on who the rcvr is, // 1. Use a different dataRate_// 2. Set p->txinfo_.CPThresh correspondingly rcvr_nodeID = (u_int32_t)ETHER_ADDR(dh->dh_ra); if((u_int32_t)ETHER_ADDR(dh->dh_ra) != MAC_BROADCAST){// printf("sendDATA(): Node[%d]\n", addr()); //VIVEK_ARF Transmitting pkt, check if ARF timer has expired // and if so, update the rate. arf_index = ARF_find_index(dh->dh_ra); if(arf_index != -1){// Specified rate or Auto rate if(ARF_Entry[arf_index].algorithm != AUTO_RATE_NONE){// Do this only if Auto rate is used if(ARF_Entry[arf_index].timer <= 0) ARF_timer_expired(arf_index); ARF_Entry[arf_index].timer--; //Timer decremented since we are sending a pkt }// printf(TIME_FORMAT " ARF_DEBUG Node[%d]->%d: sending: Rate %d", Scheduler::instance().clock(), addr(), ARF_Entry[arf_index].MAC_ID, ARF_Entry[arf_index].rate_index);// printf("Node[%d]->%d: Decr timer to tx %d\n", addr(), ARF_Entry[arf_index].MAC_ID, ARF_Entry[arf_index].timer); Rate = link_bitrate[ARF_Entry[arf_index].rate_index]; p->txinfo_.CPThresh = link_SINR[ARF_Entry[arf_index].rate_index];// printf("Pkt info: rate=%f, CPThresh=%f\n", Rate, mWtodB(p->txinfo_.CPThresh)); } else{ // Default rate Rate = link_bitrate[0]; p->txinfo_.CPThresh = link_SINR[0]; } /* store data tx time for unicast packets */ ch->txtime() = txtime(ch->size(), Rate); dh->dh_duration = usec(txtime(phymib_.getACKlen(), basicRate_) + phymib_.getSIFS()); //ETT_ETX_HACK if (ch->size()==127) printf(TIME_FORMAT " %d %d %d %f %f %f -%d\n", Scheduler::instance().clock(), ETHER_ADDR(dh->dh_ra), addr(), ETHER_ADDR(dh->dh_ra), 0.0, 0.0, mWtodB(p->txinfo_.CPThresh), ch->size()); } else { /* store data tx time for broadcast packets (see 9.6) */ p->txinfo_.CPThresh = CPTHRESH_BASIC; ch->txtime() = txtime(ch->size(), basicRate_); dh->dh_duration = 0; }// VIVEK MULTI-RATE, MULTI-SINR MODULE 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_.getShortRetryLimit()) { 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() -= phymib_.getHdrLen11(); ch->xmit_reason_ = XMIT_REASON_RTS; ch->xmit_failure_(pktTx_->copy(), ch->xmit_failure_data_); } discard(pktTx_, DROP_MAC_RETRY_COUNT_EXCEEDED); pktTx_ = 0; ssrc_ = 0; rst_cw(); } else { 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; int arf_index; u_int32_t *rcount, thresh; u_int8_t type; u_int8_t subtype; assert(mhBackoff_.busy() == 0); assert(pktTx_); assert(pktRTS_ == 0); ch = HDR_CMN(pktTx_); mh = HDR_MAC802_11(pktTx_); type = mh->dh_fc.fc_type; subtype = mh->dh_fc.fc_subtype; /* * Broadcast packets don't get ACKed and therefore * are never retransmitted. */ if((u_int32_t)ETHER_ADDR(mh->dh_ra) == MAC_BROADCAST) { Packet::free(pktTx_); pktTx_ = 0; /* * Backoff at end of TX. */ rst_cw(); mhBackoff_.start(cw_, is_idle()); // ETT_ETX_HACK if (ch->size()==127) printf(TIME_FORMAT " %d %d %d %f %f %f -%d\n", Scheduler::instance().clock(), ETHER_ADDR(mh->dh_ra), addr(), ETHER_ADDR(mh->dh_ra), 0.0, 0.0, mWtodB(pktTx_->txinfo_.CPThresh), ch->size()); return; } macmib_.ACKFailureCount++; if((u_int32_t) ch->size() <= macmib_.getRTSThreshold()) { rcount = &ssrc_; thresh = macmib_.getShortRetryLimit(); } else { rcount = &slrc_; thresh = macmib_.getLongRetryLimit(); } (*rcount)++; // VIVEK_ARF Data packet lost. Lower tx rate, also update txtime // and CPThresh of this packet// printf(TIME_FORMAT " RetransmitDATA(): Node[%d]\n", Scheduler::instance().clock(), addr()); arf_index = ARF_find_index(mh->dh_ra); if((arf_index != -1) && (ARF_Entry[arf_index].algorithm != AUTO_RATE_NONE)){// Do this only if Auto rate is used ARF_decr_rate(arf_index); ARF_update_txtime(pktTx_, arf_index); ARF_Entry[arf_index].timer--; //Timer decremented since we are sending a pkt }// printf("Node[%d]->%d: Decr timer due to rtx %d\n", addr(), ARF_Entry[arf_index].MAC_ID, ARF_Entry[arf_index].timer); if(*rcount >= thresh) { /* IEEE Spec section 9.2.3.5 says this should be greater than or equal */ 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() -= phymib_.getHdrLen11(); ch->xmit_reason_ = XMIT_REASON_ACK; ch->xmit_failure_(pktTx_->copy(), ch->xmit_failure_data_); } discard(pktTx_, DROP_MAC_RETRY_COUNT_EXCEEDED); pktTx_ = 0; *rcount = 0; rst_cw(); // ETT_ETX_HACK if (ch->size()==127) printf(TIME_FORMAT " %d %d %d %f %f %f -%d\n", Scheduler::instance().clock(), ETHER_ADDR(mh->dh_ra), addr(), ETHER_ADDR(mh->dh_ra), 0.0, 0.0, mWtodB(pktTx_->txinfo_.CPThresh), ch->size()); } else { struct hdr_mac802_11 *dh; dh = HDR_MAC802_11(pktTx_); dh->dh_fc.fc_retry = 1; // ETT_ETX_HACK if (ch->size()==127) printf(TIME_FORMAT " %d %d %d %f %f %f -%d\n", Scheduler::instance().clock(), ETHER_ADDR(mh->dh_ra), addr(), ETHER_ADDR(mh->dh_ra), 0.0, 0.0, mWtodB(pktTx_->txinfo_.CPThresh), ch->size()); sendRTS(ETHER_ADDR(mh->dh_ra)); inc_cw(); mhBackoff_.start(cw_, is_idle()); }}/* ====================================================================== Incoming Packet Routines ====================================================================== */voidMac802_11::send(Packet *p, Handler *h){ double rTime; struct hdr_mac802_11* dh = HDR_MAC802_11(p); 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_ra)); /* * 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 (mhDefer_.busy() == 0) { /* * If we are already deferring, there is no * need to reset the Defer timer. */ if (bugFix_timer_) { mhBackoff_.start(cw_, is_idle(), phymib_.getDIFS()); } else { rTime = (Random::random() % cw_) * (phymib_.getSlotTime()); mhDefer_.start(phymib_.getDIFS() + rTime); } } } else { /* * If the medium is NOT IDLE, then we start * the backoff timer. */ mhBackoff_.start(cw_, is_idle()); } }}voidMac802_11::recv(Packet *p, Handler *h){ struct hdr_cmn *hdr = HDR_CMN(p); struct hdr_mac802_11 *mh = HDR_MAC802_11(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; } // VIVEK CUMULATIVE INTERFERENCE MODULE// if(p->txinfo_.CPThresh <= 0.0){// Some bug TODO: ARP packets don't go through MAC?// p->txinfo_.CPThresh = CPTHRESH_BASIC; // Assume lowest modulation coding scheme.// printf("This should not happen\n");// } if(rx_state_ == MAC_IDLE) { p->init_interference(noise_); // Set to noise power /* * Schedule the reception of this packet, in * txtime seconds. */ setRxState(MAC_RECV); pktRx_ = p; if(pktRx_->txinfo_.RxPr / pktRx_->get_interference() < pktRx_->txinfo_.CPThresh) hdr->error() = 1; // VIVEK_NEW Ensures that if the SNR is not high enough, the pkt is dropped mhRecv_.start(txtime(p));// }// else{// Rcvd pwr is too weak as compared to noise, drop pkt// if(addr() == 2)// printf(TIME_FORMAT "Noise D[%d]: %d->%d Pr=%f, interf=%f, CPTh=%f, RTSTh=%d, 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), macmib_.getRTSThreshold(), hdr->size());// collision(p);// Reuse collision function. // Think of the event as collision of pkt with itself// } } else { // Currently receiving packet pktRx_, and simultaneously started receiving p pktRx_->incr_interference(p->txinfo_.RxPr); // Cumulative interference of pktRx_ if(pktRx_->txinfo_.RxPr / pktRx_->get_interference() >= pktRx_->txinfo_.CPThresh) { capture(p); return; // Interference is not enough to corrupt pktRx_ } else {// printf(TIME_FORMAT "D[%d]: %d->%d Pr=%f, interf=%f, CPTh=%f, RTSTh=%d, 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), macmib_.getRTSThreshold(), hdr->size()); collision(p); } } // VIVEK CUMULATIVE INTERFERENCE MODULE}voidMac802_11::recv_timer(){ u_int32_t src; hdr_cmn *ch = HDR_CMN(pktRx_); hdr_mac802_11 *mh = HDR_MAC802_11(pktRx_); u_int32_t dst = ETHER_ADDR(mh->dh_ra); 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(phymib_.getEIFS())); goto done; } /* VIVEK_JENGFARN_LEE * a frame resulting in channel busy, but * the physical layer cannot receive it */ if (ch->busy()){ Packet::free(pktRx_); 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -