📄 mac-802_11.cc
字号:
aaf->aaf_duration = usec(sifs_ + txtime(ETHER_ATIMRSH_LEN, basicRate_)); aaf->aaf_selected_channel = selected_channel_; pktATIMACK_ = p;}voidMac802_11::sendATIMRSH(int dst){ Packet *p = Packet::alloc(); hdr_cmn* ch = HDR_CMN(p); struct atimrsh_frame *ahf = (struct atimrsh_frame*)p->access(hdr_mac::offset_); assert(pktATIMRSH_ == 0); ch->uid() = 0; ch->ptype() = PT_MAC; ch->size() = ETHER_ATIMRSH_LEN; ch->iface() = -2; ch->error() = 0; bzero(ahf, MAC_HDR_LEN); ahf->ahf_fc.fc_protocol_version = MAC_ProtocolVersion; ahf->ahf_fc.fc_type = MAC_Type_Management; ahf->ahf_fc.fc_subtype = MAC_Subtype_ATIMRSH; ahf->ahf_fc.fc_to_ds = 0; ahf->ahf_fc.fc_from_ds = 0; ahf->ahf_fc.fc_more_frag = 0; ahf->ahf_fc.fc_retry = 0; ahf->ahf_fc.fc_pwr_mgt = 0; ahf->ahf_fc.fc_more_data = 0; ahf->ahf_fc.fc_wep = 0; ahf->ahf_fc.fc_order = 0; ahf->ahf_fc.fc_channel = DEFAULT_CHANNEL; STORE4BYTE(&dst, (ahf->ahf_ra)); ch->txtime() = txtime(ch->size(), basicRate_); ahf->ahf_duration = 0; ahf->ahf_confirmed_channel = selected_channel_; pktATIMRSH_ = p;}//end of JUNGMINvoidMac802_11::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; if(active_channel_ != -1) dh->dh_fc.fc_channel = active_channel_; else dh->dh_fc.fc_channel = DEFAULT_CHANNEL; /* 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 ====================================================================== */voidMac802_11::RetransmitRTS(){ //printf("[%d] %lf: Retransmitting RTS\n", index_, NOW); 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 if (atim_window_ == 1) { discard(pktRTS_, DROP_END_OF_BEACON_INTERVAL); pktRTS_ = 0; hdr_cmn *ch = HDR_CMN(pktTx_); if(ch->xmit_failure_) { ch->size() -= ETHER_HDR_LEN11; ch->xmit_reason_ = XMIT_REASON_RTS; ch->xmit_failure_(pktTx_->copy(), ch->xmit_failure_data_); } discard(pktTx_, DROP_END_OF_BEACON_INTERVAL); pktTx_ = 0; ssrc_ = 0; rst_cw(); } else { //printf("(%d)...retxing RTS:%x\n",index_,pktRTS_); struct rts_frame *rf; struct dca_rts_frame* drts; if(dca_ == 0) { rf = (struct rts_frame*)pktRTS_->access(hdr_mac::offset_); rf->rf_fc.fc_retry = 1; if(active_channel_ != -1) rf->rf_fc.fc_channel = active_channel_; else rf->rf_fc.fc_channel = DEFAULT_CHANNEL; } else { drts = (struct dca_rts_frame*)pktRTS_->access(hdr_mac::offset_); drts->drts_fc.fc_retry = 1; drts->drts_fc.fc_channel = DEFAULT_CHANNEL; } inc_cw(); mhBackoff_.start(cw_, is_idle()); }}//JUNGMINvoidMac802_11::RetransmitATIM(){ assert(pktATIM_); assert(mhBackoff_.busy() == 0); sarc_ += 1; //Hardcoding Retry Limit to 3 if(sarc_ >= 3) { discard(pktATIM_, DROP_MAC_RETRY_COUNT_EXCEEDED); pktATIM_ = 0; sarc_ = 0; rst_cw(); } else if(atim_window_ == 0) { discard(pktATIM_, DROP_END_OF_ATIM_WINDOW); pktATIM_ = 0; sarc_ = 0; rst_cw(); } else { struct atim_frame *atf; atf = (struct atim_frame*)pktATIM_->access(hdr_mac::offset_); atf->atf_fc.fc_retry = 1; if(active_channel_ != -1) atf->atf_fc.fc_channel = active_channel_; else atf->atf_fc.fc_channel = DEFAULT_CHANNEL; inc_cw(); mhBackoff_.start(cw_, is_idle()); }}//end of JUNGMINvoidMac802_11::RetransmitDATA(){ //printf("[%d] %lf: Retransmit DATA\n", index_, NOW); 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; *rcount = 0; rst_cw(); } else if( atim_window_ == 1 ) { macmib_->FailedCount++; 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_END_OF_BEACON_INTERVAL); pktTx_ = 0; *rcount = 0; rst_cw(); } else { struct hdr_mac802_11 *dh; dh = HDR_MAC802_11(pktTx_); dh->dh_fc.fc_retry = 1; if(active_channel_ != -1) dh->dh_fc.fc_channel = active_channel_; else dh->dh_fc.fc_channel = DEFAULT_CHANNEL; if(dca_) { sendDRTS(ETHER_ADDR(mh->dh_da)); } else { 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_cmn *ch = HDR_CMN(p); \ 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); if(dca_ == 0) { sendRTS(ETHER_ADDR(dh->dh_da)); } else { sendDRTS(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; }//JUNGMIN //silently discard packets sent on another channel struct hdr_mac802_11* dh = HDR_MAC802_11(p); int ch = dh->dh_fc.fc_channel; int dest = ETHER_ADDR(dh->dh_da); int i=0; if(dca_) { if((dh->dh_fc.fc_type == MAC_Type_Data || dh->dh_fc.fc_subtype == MAC_Subtype_ACK) && (u_int32_t)ETHER_ADDR(dh->dh_da) != MAC_BROADCAST) { if(active_channel_ == -1 && ch == 0) { i=1; } else if(ch == active_channel_) { i=2; } else { //if the channel is different, this packet has never received that packet Packet::free(p); return; } if((u_int32_t)ETHER_ADDR(dh->dh_da) != index_) { Packet::free(p); return; } } } else { if(active_channel_ == -1 && ch == 0) { i=1; } else if(ch == active_channel_) { i=2; } else { //if the channel is different, this packet has never received that packet Packet::free(p); return; } } //end of JUNGMIN if(dca_ == 0) { 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); } } } else { if((dh->dh_fc.fc_type == MAC_Type_Data || dh->dh_fc.fc_subtype == MAC_Subtype_ACK) && (u_int32_t)ETHER_ADDR(dh->dh_da) != MAC_BROADCAST) { if(dx_state_ == MAC_IDLE) { SET_DX_STATE(MAC_RECV); pktDx_ = p; mhRecvDATA_.start(txtime(p)); } else { Packet::free(p); } } else { if(rx_state_ == MAC_IDLE) { SET_RX_STATE(MAC_RECV); pktRx_ = p; mhRecv_.start(txtime(p)); } else { if(pktRx_->txinfo_.RxPr / p->txinfo_.RxPr >= p->txinfo_.CPThresh) { capture(p); } else { collision(p); } } } } }voidMac802_11::recvDATA_timer(){ u_int32_t src; hdr_cmn *ch = HDR_CMN(pktDx_); hdr_mac802_11 *mh = HDR_MAC802_11(pktDx_); 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(pktDx_); assert(dx_state_ == MAC_RECV || dx_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(pktDx_); goto done; } /* * Handle collisions. */ if(!(type == MAC_Type_Management && subtype == MAC_Subtype_Beacon)) { if(rx_state_ == MAC_COLL) { discard(pktDx_, 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(pktDx_); set_nav(usec(eifs_)); goto done; } /* * IEEE 802.11 specs, section 9.2.5.6 * - update the NAV (Network Allocation Vector) */ //Must modify this to make intelligent channel selection if(dst != (u_int32_t)index_) { set_nav(mh->dh_duration); if(type == MAC_Type_Management) { if(subtype == MAC_Subtype_ATIMRSH) { recvOtherATIMRSH(pktDx_); } else if(subtype == MAC_Subtype_ATIMACK) { recvOtherATIMACK(pktDx_); } } else if(type == MAC_Type_Control) { if(subtype == MAC_Subtype_DCTS) { recvOtherDCTS(pktDx_); } else if(subtype == MAC_Subtype_DRSH) { recvOtherDRSH(pktDx_); } } } /* tap out - */ if (tap_ && type == MAC_Type_Data && MAC_Subtype_Data == subtype ) tap_->tap(pktDx_); /* * 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 */ //printf("STEP 6\n"); 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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -