📄 patch.mac
字号:
+ cache_node_count_ = atoi(argv[2]);+ cache_ = new Host[cache_node_count_ + 1];+ assert(cache_);+ bzero(cache_, sizeof(Host) * (cache_node_count_+1 ));+ return TCL_OK;+ } else if (strcmp(argv[1], "netif") == 0) {+ // JCW+ netif_ = (InterferencePhy*) TclObject::lookup(argv[2]);+ return TCL_OK;+ }+ }+ return Mac::command(argc, argv);+}++/* ======================================================================+ Debugging Routines+ ====================================================================== */+void+Mac802_11_if::trace_pkt(Packet *p) {+ struct hdr_cmn *ch = HDR_CMN(p);+ struct hdr_mac802_11* dh = HDR_MAC802_11(p);+ u_int16_t *t = (u_int16_t*) &dh->dh_fc;++ fprintf(stderr, "\t[ %2x %2x %2x %2x ] %x %s %d\n",+ *t, dh->dh_duration,+ ETHER_ADDR(dh->dh_da), ETHER_ADDR(dh->dh_sa),+ index_, packet_info.name(ch->ptype()), ch->size());+}++void+Mac802_11_if::dump(char *fname)+{+ fprintf(stderr,+ "\n%s --- (INDEX: %d, time: %2.9f)\n",+ fname, index_, Scheduler::instance().clock());++ fprintf(stderr,+ "\ttx_state_: %x, rx_state_: %x, nav: %2.9f, idle: %d\n",+ tx_state_, rx_state_, nav_, is_idle());++ fprintf(stderr,+ "\tpktTx_: %x, pktRx_: %x, pktRTS_: %x, pktCTRL_: %x, callback: %x\n",+ (int) pktTx_, (int) pktRx_, (int) pktRTS_,+ (int) pktCTRL_, (int) callback_);++ fprintf(stderr,+ "\tDefer: %d, Backoff: %d (%d), Recv: %d, Timer: %d Nav: %d\n",+ mhDefer_.busy(), mhBackoff_.busy(), mhBackoff_.paused(),+ mhRecv_.busy(), mhSend_.busy(), mhNav_.busy());+ fprintf(stderr,+ "\tBackoff Expire: %f\n",+ mhBackoff_.expire());+}+++/* ======================================================================+ Packet Headers Routines+ ====================================================================== */+inline int+Mac802_11_if::hdr_dst(char* hdr, int dst )+{+ struct hdr_mac802_11 *dh = (struct hdr_mac802_11*) hdr;+ //dst = (u_int32_t)(dst);++ if(dst > -2)+ STORE4BYTE(&dst, (dh->dh_da));++ return ETHER_ADDR(dh->dh_da);+}++inline int +Mac802_11_if::hdr_src(char* hdr, int src )+{+ struct hdr_mac802_11 *dh = (struct hdr_mac802_11*) hdr;+ if(src > -2)+ STORE4BYTE(&src, (dh->dh_sa));+ return ETHER_ADDR(dh->dh_sa);+}++inline int +Mac802_11_if::hdr_type(char* hdr, u_int16_t type)+{+ struct hdr_mac802_11 *dh = (struct hdr_mac802_11*) hdr;+ if(type)+ STORE2BYTE(&type,(dh->dh_body));+ return GET2BYTE(dh->dh_body);+}+++/* ======================================================================+ Misc Routines+ ====================================================================== */+inline int+Mac802_11_if::is_idle()+{+ if(rx_state_ != MAC_IDLE)+ return 0;+ if(tx_state_ != MAC_IDLE)+ return 0;+ if(nav_ > Scheduler::instance().clock())+ return 0;+ // JCW+ if(netif_->is_idle() == 0)+ return 0;++ return 1;+}++void+Mac802_11_if::discard(Packet *p, const char* why)+{+ hdr_mac802_11* mh = HDR_MAC802_11(p);+ hdr_cmn *ch = HDR_CMN(p);++#if 0+ /* old logic 8/8/98 -dam */+ /*+ * If received below the RXThreshold, then just free.+ */+ if(p->txinfo_.Pr < p->txinfo_.ant.RXThresh) {+ Packet::free(p);+ //p = 0;+ return;+ }+#endif // 0++ /* if the rcvd pkt contains errors, a real MAC layer couldn't+ necessarily read any data from it, so we just toss it now */+ if(ch->error() != 0) {+ Packet::free(p);+ //p = 0;+ return;+ }++ switch(mh->dh_fc.fc_type) {+ case MAC_Type_Management:+ drop(p, why);+ return;+ case MAC_Type_Control:+ switch(mh->dh_fc.fc_subtype) {+ case MAC_Subtype_RTS:+ if((u_int32_t)ETHER_ADDR(mh->dh_sa) == \+ (u_int32_t)index_) {+ drop(p, why);+ return;+ }+ /* fall through - if necessary */+ case MAC_Subtype_CTS:+ case MAC_Subtype_ACK:+ if((u_int32_t)ETHER_ADDR(mh->dh_da) == \+ (u_int32_t)index_) {+ drop(p, why);+ return;+ }+ break;+ default:+ fprintf(stderr, "invalid MAC Control subtype\n");+ exit(1);+ }+ break;+ case MAC_Type_Data:+ switch(mh->dh_fc.fc_subtype) {+ case MAC_Subtype_Data:+ if((u_int32_t)ETHER_ADDR(mh->dh_da) == \+ (u_int32_t)index_ ||+ (u_int32_t)ETHER_ADDR(mh->dh_sa) == \+ (u_int32_t)index_ ||+ (u_int32_t)ETHER_ADDR(mh->dh_da) == MAC_BROADCAST) {+ drop(p);+ return;+ }+ break;+ default:+ fprintf(stderr, "invalid MAC Data subtype\n");+ exit(1);+ }+ break;+ default:+ fprintf(stderr, "invalid MAC type (%x)\n", mh->dh_fc.fc_type);+ trace_pkt(p);+ exit(1);+ }+ Packet::free(p);+}++void+Mac802_11_if::capture(Packet *p)+{+ /*+ * Update the NAV so that this does not screw+ * up carrier sense.+ */+ set_nav(usec(eifs_ + txtime(p)));+ Packet::free(p);+}++void+Mac802_11_if::collision(Packet *p)+{+ switch(rx_state_) {+ case MAC_RECV:+ SET_RX_STATE(MAC_COLL);+ /* fall through */+ case MAC_COLL:+ assert(pktRx_);+ assert(mhRecv_.busy());+ /*+ * Since a collision has occurred, figure out+ * which packet that caused the collision will+ * "last" the longest. Make this packet,+ * pktRx_ and reset the Recv Timer if necessary.+ */+ if(txtime(p) > mhRecv_.expire()) {+ mhRecv_.stop();+ discard(pktRx_, DROP_MAC_COLLISION);+ pktRx_ = p;+ mhRecv_.start(txtime(pktRx_));+ }+ else {+ discard(p, DROP_MAC_COLLISION);+ }+ break;+ default:+ assert(0);+ }+}++void+Mac802_11_if::tx_resume()+{+ double rTime;+ assert(mhSend_.busy() == 0);+ assert(mhDefer_.busy() == 0);++ if(pktCTRL_) {+ /*+ * Need to send a CTS or ACK.+ */+ mhDefer_.start(sifs_);+ } else if(pktRTS_) {+ if(mhBackoff_.busy() == 0) {+ rTime = (Random::random() % cw_) * phymib_->SlotTime;+ mhDefer_.start(difs_ + rTime);+ }+ } else if(pktTx_) {+ if(mhBackoff_.busy() == 0) {+ hdr_cmn *ch = HDR_CMN(pktTx_);+ struct hdr_mac802_11 *mh = HDR_MAC802_11(pktTx_);+ + if ((u_int32_t) ch->size() < macmib_->RTSThreshold ||+ (u_int32_t) ETHER_ADDR(mh->dh_da) == MAC_BROADCAST) {+ rTime = (Random::random() % cw_) * phymib_->SlotTime;+ mhDefer_.start(difs_ + rTime);+ } else {+ mhDefer_.start(sifs_);+ }+ }+ } else if(callback_) {+ Handler *h = callback_;+ callback_ = 0;+ h->handle((Event*) 0);+ }+ SET_TX_STATE(MAC_IDLE);+}++void+Mac802_11_if::rx_resume()+{+ assert(pktRx_ == 0);+ assert(mhRecv_.busy() == 0);+ SET_RX_STATE(MAC_IDLE);+}+++/* ======================================================================+ Timer Handler Routines+ ====================================================================== */+void+Mac802_11_if::backoffHandler()+{+ if(pktCTRL_) {+ assert(mhSend_.busy() || mhDefer_.busy());+ return;+ }++ if(check_pktRTS() == 0)+ return;++ if(check_pktTx() == 0)+ return;+}++void+Mac802_11_if::deferHandler()+{+ assert(pktCTRL_ || pktRTS_ || pktTx_);++ if(check_pktCTRL() == 0)+ return;++ assert(mhBackoff_.busy() == 0);+ //if (mhBackoff_.busy() != 0)+ //{+ // printf("deferHandler:mhBackoff_ busy!\n");+ // return;+ //}+ if(check_pktRTS() == 0)+ return;++ if(check_pktTx() == 0)+ return;+}++void+Mac802_11_if::navHandler()+{+ if(is_idle() && mhBackoff_.paused())+ mhBackoff_.resume(difs_);+}++void+Mac802_11_if::recvHandler()+{+ recv_timer();+}++void+Mac802_11_if::sendHandler()+{+ send_timer();+}+++void+Mac802_11_if::txHandler()+{+ tx_active_ = 0;+}+++/* ======================================================================+ The "real" Timer Handler Routines+ ====================================================================== */+void+Mac802_11_if::send_timer()+{+ switch(tx_state_) {+ /*+ * Sent a RTS, but did not receive a CTS.+ */+ case MAC_RTS:+ RetransmitRTS();+ break;+ /*+ * Sent a CTS, but did not receive a DATA packet.+ */+ case MAC_CTS:+ assert(pktCTRL_);+ Packet::free(pktCTRL_); pktCTRL_ = 0;+ break;+ /*+ * Sent DATA, but did not receive an ACK packet.+ */+ case MAC_SEND:+ RetransmitDATA();+ break;+ /*+ * Sent an ACK, and now ready to resume transmission.+ */+ case MAC_ACK:+ assert(pktCTRL_);+ Packet::free(pktCTRL_); pktCTRL_ = 0;+ break;+ case MAC_IDLE:+ break;+ default:+ assert(0);+ }+ tx_resume();+}+++/* ======================================================================+ Outgoing Packet Routines+ ====================================================================== */+int+Mac802_11_if::check_pktCTRL()+{+ struct hdr_mac802_11 *mh;+ double timeout;++ if(pktCTRL_ == 0)+ return -1;+ if(tx_state_ == MAC_CTS || tx_state_ == MAC_ACK)+ return -1;++ mh = HDR_MAC802_11(pktCTRL_);+ + 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_, DROP_MAC_BUSY); pktCTRL_ = 0;+ return 0;+ }+ SET_TX_STATE(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_MaxPropagationDelay // XXX+ + sec(mh->dh_duration)+ + DSSS_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(MAC_ACK);++ timeout = txtime(ETHER_ACK_LEN, basicRate_);+ + break;+ default:+ fprintf(stderr, "check_pktCTRL:Invalid MAC Control subtype\n");+ exit(1);+ }+ TRANSMIT(pktCTRL_, timeout);+ return 0;+}++int+Mac802_11_if::check_pktRTS()+{+ struct hdr_mac802_11 *mh;+ double timeout;++ assert(mhBackoff_.busy() == 0);++ if(pktRTS_ == 0)+ return -1;+ //struct hdr_cmn *ch = HDR_CMN(pktRTS_);+ mh = HDR_MAC802_11(pktRTS_);++ switch(mh->dh_fc.fc_subtype) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -