📄 patch.mac
字号:
+ case MAC_Subtype_RTS:+ if(! is_idle()) {+ inc_cw();+ mhBackoff_.start(cw_, is_idle());+ return 0;+ }+ SET_TX_STATE(MAC_RTS);+ timeout = txtime(ETHER_RTS_LEN, basicRate_)+ + DSSS_MaxPropagationDelay // XXX+ + sifs_+ + txtime(ETHER_CTS_LEN, basicRate_)+ + DSSS_MaxPropagationDelay; // XXX+ break;+ default:+ fprintf(stderr, "check_pktRTS:Invalid MAC Control subtype\n");+ exit(1);+ }+ TRANSMIT(pktRTS_, timeout);+ return 0;+}++int+Mac802_11_if::check_pktTx()+{+ struct hdr_mac802_11 *mh;+ double timeout;+ + assert(mhBackoff_.busy() == 0);++ if(pktTx_ == 0)+ return -1;++ mh = HDR_MAC802_11(pktTx_);+ //int len = HDR_CMN(pktTx_)->size();++ switch(mh->dh_fc.fc_subtype) {+ case MAC_Subtype_Data:+ if(! is_idle()) {+ sendRTS(ETHER_ADDR(mh->dh_da));+ inc_cw();+ mhBackoff_.start(cw_, is_idle());+ return 0;+ }+ SET_TX_STATE(MAC_SEND);+ if((u_int32_t)ETHER_ADDR(mh->dh_da) != MAC_BROADCAST)+ timeout = txtime(pktTx_)+ + DSSS_MaxPropagationDelay // XXX+ + sifs_+ + txtime(ETHER_ACK_LEN, basicRate_)+ + DSSS_MaxPropagationDelay; // XXX+ else+ timeout = txtime(pktTx_);+ 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_, timeout);+ return 0;+}++/*+ * Low-level transmit functions that actually place the packet onto+ * the channel.+ */+void+Mac802_11_if::sendRTS(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_);+ assert(pktRTS_ == 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_)->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_)+ + sifs_+ + txtime(ETHER_ACK_LEN, basicRate_));+ + + pktRTS_ = p;+}++void+Mac802_11_if::sendCTS(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_ == 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_ = p;+ +}++void+Mac802_11_if::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);++ ch->uid() = 0;+ ch->ptype() = PT_MAC;+ ch->size() = ETHER_ACK_LEN;+ 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;+}++void+Mac802_11_if::sendDATA(Packet *p)+{+ hdr_cmn* ch = HDR_CMN(p);+ struct hdr_mac802_11* dh = HDR_MAC802_11(p);++ assert(pktTx_ == 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 */+ ch->txtime() = txtime(ch->size(), dataRate_);++ 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_ = p;+}++/* ======================================================================+ Retransmission Routines+ ====================================================================== */+void+Mac802_11_if::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_LEN11;+ 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());+ }+}++void+Mac802_11_if::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_LEN11;+ 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+ ====================================================================== */+void+Mac802_11_if::send(Packet *p, Handler *h)+{+ 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_ = 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) {+ rTime = (Random::random() % cw_) * (phymib_->SlotTime);+ mhDefer_.start(difs_ + rTime);+ }+ + }+ /*+ * If the medium is NOT IDLE, then we start+ * the backoff timer.+ */+ else {+ mhBackoff_.start(cw_, is_idle());+ }+ }+}++void+Mac802_11_if::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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -