📄 mac-802_11.cc
字号:
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()); } }}voidMac802_11::recv(Packet *p, Handler *h){ struct hdr_cmn *hdr = HDR_CMN(p); //Yuan add struct hdr_ip *ih = HDR_IP(p); hdr_pdp* ph = hdr_pdp::access(p); /* * Sanity Check */ assert(initialized()); /* * Handle outgoing packets. */ if(hdr->direction() == hdr_cmn::DOWN) { //Yuan add if (hdr->ptype() == PT_CBR) { pkt_size = hdr->size(); pkt_dest = hdr->next_hop_; //pkt_enqeue_time = ph->enqueue_time_; double pkt_mac_time = Scheduler::instance().clock(); if (last_pkt_depart_time[pkt_dest] !=-1) { if (last_pkt_depart_time[pkt_dest] < pkt_mac_time) pkt_arrival_time = last_pkt_depart_time[pkt_dest]; else pkt_arrival_time = pkt_mac_time; if (ph->enqueue_time_ > pkt_arrival_time) pkt_arrival_time = ph->enqueue_time_; if (last_pkt_arr_time[pkt_dest] != -1) // last pkt is lost pkt_arrival_time = last_pkt_arr_time[pkt_dest]; last_pkt_arr_time[pkt_dest] = pkt_arrival_time; } else { pkt_arrival_time = pkt_mac_time; last_pkt_arr_time[pkt_dest] = pkt_arrival_time; } //printf("to %d, enqueue %f, last_depart %f, mac %f, arr %f\n", pkt_dest, ph->enqueue_time_, last_pkt_depart_time[pkt_dest], pkt_mac_time, pkt_arrival_time); } else { pkt_arrival_time = 0; } 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; } 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_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_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_)); 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_)); goto done; } /* * 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 * 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 */ 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. */ discard(pktRx_, "---"); goto done; } switch(type) { case MAC_Type_Management: discard(pktRx_, DROP_MAC_PACKET_ERROR); goto done; break; case MAC_Type_Control: switch(subtype) { case MAC_Subtype_RTS: recvRTS(pktRx_); break; case MAC_Subtype_CTS: recvCTS(pktRx_); break; case MAC_Subtype_ACK: recvACK(pktRx_); break; default: fprintf(stderr,"recvTimer1:Invalid MAC Control Subtype %x\n", subtype); exit(1); } break; case MAC_Type_Data: switch(subtype) { case MAC_Subtype_Data: recvDATA(pktRx_); break; default: fprintf(stderr, "recv_timer2:Invalid MAC Data Subtype %x\n", subtype); exit(1); } break; default: fprintf(stderr, "recv_timer3:Invalid MAC Type %x\n", subtype); exit(1); } done: pktRx_ = 0; rx_resume();}voidMac802_11::recvRTS(Packet *p){ struct rts_frame *rf = (struct rts_frame*)p->access(hdr_mac::offset_); if(tx_state_ != MAC_IDLE) { discard(p, DROP_MAC_BUSY); return; } /* * If I'm responding to someone else, discard this RTS. */ if(pktCTRL_) { discard(p, DROP_MAC_BUSY); return; } sendCTS(ETHER_ADDR(rf->rf_ta), rf->rf_duration); /* * Stop deferring - will be reset in tx_resume(). */ if(mhDefer_.busy()) mhDefer_.stop(); tx_resume(); mac_log(p);}/* * txtime() - pluck the precomputed tx time from the packet header */doubleMac802_11::txtime(Packet *p) { struct hdr_cmn *ch = HDR_CMN(p); double t = ch->txtime(); if (t < 0.0) { drop(p, "XXX"); exit(1); } return t; } /* * txtime() - calculate tx time for packet of size "psz" bytes * at rate "drt" bps */doubleMac802_11::txtime(double psz, double drt){ double dsz = psz - PLCP_HDR_LEN; int plcp_hdr = PLCP_HDR_LEN << 3; int datalen = (int)dsz << 3; double t = (((double)plcp_hdr)/phymib_->PLCPDataRate) + (((double)datalen)/drt); return(t);}voidMac802_11::recvCTS(Packet *p){ if(tx_state_ != MAC_RTS) { discard(p, DROP_MAC_INVALID_STATE); return; } assert(pktRTS_); Packet::free(pktRTS_); pktRTS_ = 0; assert(pktTx_); // debug //struct hdr_mac802_11 *mh = HDR_MAC802_11(pktTx_); //printf("(%d):recvCTS:pktTx_-%x,mac-subtype-%d & pktCTS_:%x\n",index_,pktTx_,mh->dh_fc.fc_subtype,p); mhSend_.stop(); /* * The successful reception of this CTS packet implies * that our RTS was successful. Hence, we can reset * the Short Retry Count and the CW. */ //ssrc_ = 0; //rst_cw(); tx_resume(); mac_log(p);}voidMac802_11::recvDATA(Packet *p){ struct hdr_mac802_11 *dh = HDR_MAC802_11(p); u_int32_t dst, src, size; struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); hdr_pdp* ph = hdr_pdp::access(p); { dst = ETHER_ADDR(dh->dh_da); src = ETHER_ADDR(dh->dh_sa); size = ch->size(); /* * Adjust the MAC packet size - ie; strip * off the mac header */ ch->size() -= ETHER_HDR_LEN11; ch->num_forwards() += 1; } /* * If we sent a CTS, clean up... */ if(dst != MAC_BROADCAST) { if(size >= macmib_->RTSThreshold) { if (tx_state_ == MAC_CTS) { assert(pktCTRL_); Packet::free(pktCTRL_); pktCTRL_ = 0; mhSend_.stop(); /* * Our CTS got through. */ //printf("(%d): RECVING DATA!\n",index_); //ssrc_ = 0; //rst_cw(); } else { discard(p, DROP_MAC_BUSY); //printf("(%d)..discard DATA\n",index_); return; } sendACK(src); tx_resume(); } /* * We did not send a CTS and there's no * room to buffer an ACK. */ else { if(pktCTRL_) { discard(p, DROP_MAC_BUSY); return; } sendACK(src); if(mhSend_.busy() == 0) tx_resume(); } } /* ============================================================ Make/update an entry in our sequence number cache. ============================================================ */ /* Changed by Debojyoti Dutta. This upper loop of if{}else was suggested by Joerg Diederich <dieder@ibr.cs.tu-bs.de>. Changed on 19th Oct'2000 */ if(dst != MAC_BROADCAST) { if (src < (u_int32_t) cache_node_count_) { Host *h = &cache_[src]; if(h->seqno && h->seqno == dh->dh_scontrol) { discard(p, DROP_MAC_DUPLICATE); return; } h->seqno = dh->dh_scontrol; } else { static int count = 0; if (++count <= 10) { printf ("MAC_802_11: accessing MAC cache_ array out of range (src %u, dst %u, size %d)!\n", src, dst, cache_node_count_); if (count == 10) printf ("[suppressing additional MAC cache_ warnings]\n"); }; }; } /* * Pass the packet up to the link-layer. * XXX - we could schedule an event to account * for this processing delay. */ //p->incoming = 1; // XXXXX NOTE: use of incoming flag has been depracated; In order to track direction of pkt flow, direction_ in hdr_cmn is used instead. see packet.h for details. uptarget_->recv(p, (Handler*) 0);//Yuan add// if (routing_agent!=NULL){ if ((ch->ptype() == PT_CBR)&&(ih->daddr() == routing_agent->index) && (ch->prev_hop_ !=LARGE_INT8)){// printf("MAC:view_update_on_rate (%d, %d) pkt %d\n", routing_agent->index,ch->prev_hop_, ch->uid_ ); routing_agent->view_update(ch->prev_hop_, ph->grad_); } }}voidMac802_11::recvACK(Packet *p){ struct hdr_cmn *ch = HDR_CMN(p); if(tx_state_ != MAC_SEND) { discard(p, DROP_MAC_INVALID_STATE); return; } //printf("(%d)...................recving ACK:%x\n",index_,p); assert(pktTx_); Packet::free(pktTx_); pktTx_ = 0; mhSend_.stop(); /* * The successful reception of this ACK packet implies * that our DATA transmission was successful. Hence, * we can reset the Short/Long Retry Count and the CW. */ if((u_int32_t) ch->size() <= macmib_->RTSThreshold) ssrc_ = 0; else slrc_ = 0; /* * Backoff before sending again. */ //Yuan add if (pkt_arrival_time !=0) { //this is a valid data pkt double pkt_depart_time = Scheduler::instance().clock(); double pkt_delay,pkt_bw; pkt_delay = pkt_depart_time - pkt_arrival_time; last_pkt_depart_time[pkt_dest] = pkt_depart_time; last_pkt_arr_time[pkt_dest] = -1; if (pkt_delay >0){ new_delay[pkt_dest] += pkt_delay; // printf("to dest %d MAC: pkt_arr %f, pkt_dept %f, pkt_delay %f, pkt_bw %f\n",pkt_dest,pkt_arrival_time, pkt_depart_time, pkt_delay, (double)(pkt_size << 3)/((double)1000* pkt_delay)); num_pkt[pkt_dest]++; } if (num_pkt[pkt_dest]>= NUM_MEASURE_PKT){ num_pkt[pkt_dest] = 0; bandwidth[pkt_dest] = (double )(NUM_MEASURE_PKT)*((pkt_size) <<3 )/(new_delay[pkt_dest]*1000*ADJUST_PARA); new_delay[pkt_dest] = 0; printf("MAC:bandwidth[%d] %f at %f\n",pkt_dest, bandwidth[pkt_dest],Scheduler::instance().clock()); } } rst_cw(); assert(mhBackoff_.busy() == 0); mhBackoff_.start(cw_, is_idle()); tx_resume(); mac_log(p);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -