mac-802_11.cc
资源名称:NS2.rar [点击查看]
上传用户:sdhqmy
上传日期:2015-12-07
资源大小:63k
文件大小:72k
源码类别:
3G开发
开发平台:
C/C++
- /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*-
- *
- * Copyright (c) 1997 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Header: /nfs/jade/vint/CVSROOT/ns-2/mac/mac-802_11.cc,v 1.39 2002/03/14 01:12:53 haldar Exp $
- *
- * Ported from CMU/Monarch's code, nov'98 -Padma.
- */
- #include "delay.h"
- #include "connector.h"
- #include "packet.h"
- #include "random.h"
- #include "mobilenode.h"
- // #define DEBUG 99
- #include "arp.h"
- #include "ll.h"
- #include "mac.h"
- #include "mac-timers.h"
- #include "mac-802_11.h"
- #include "cmu-trace.h"
- // XXX Can't we make these macros inline methods? Otherwise why should we have
- // inline methods at all??
- #define BEACON_BACKOFF_WINDOW 32
- //#define ATIM_WINDOW 0.02
- #define DEFAULT_CHANNEL 0
- #define CHECK_BACKOFF_TIMER()
- {
- if(is_idle() && mhBackoff_.paused())
- mhBackoff_.resume(difs_);
- if(! is_idle() && mhBackoff_.busy() && ! mhBackoff_.paused())
- mhBackoff_.pause();
- }
- #define TRANSMIT(p, t)
- {
- tx_active_ = 1;
- /*
- * If I'm transmitting without doing CS, such as when
- * sending an ACK, any incoming packet will be "missed"
- * and hence, must be discarded.
- */
- if(rx_state_ != MAC_IDLE) {
- struct hdr_mac802_11 *dh = HDR_MAC802_11(p);
- assert(dh->dh_fc.fc_type == MAC_Type_Control);
- assert(dh->dh_fc.fc_subtype == MAC_Subtype_ACK);
- assert(pktRx_);
- struct hdr_cmn *ch = HDR_CMN(pktRx_);
- ch->error() = 1; /* force packet discard */
- }
- /*
- * pass the packet on the "interface" which will in turn
- * place the packet on the channel.
- *
- * NOTE: a handler is passed along so that the Network
- * Interface can distinguish between incoming and
- * outgoing packets.
- */
- downtarget_->recv(p->copy(), this);
- mhSend_.start(t);
- mhIF_.start(txtime(p));
- }
- //It was p->copy(), 8 lines above
- #define SET_RX_STATE(x)
- {
- rx_state_ = (x);
- CHECK_BACKOFF_TIMER();
- }
- #define SET_TX_STATE(x)
- {
- tx_state_ = (x);
- CHECK_BACKOFF_TIMER();
- }
- #define SET_DX_STATE(x)
- {
- dx_state_ = (x);
- CHECK_BACKOFF_TIMER();
- }
- /* ======================================================================
- Global Variables
- ====================================================================== */
- static PHY_MIB PMIB =
- {
- DSSS_CWMin, DSSS_CWMax, DSSS_SlotTime, DSSS_CCATime,
- DSSS_RxTxTurnaroundTime, DSSS_SIFSTime, DSSS_PreambleLength,
- DSSS_PLCPHeaderLength, DSSS_PLCPDataRate
- };
- static MAC_MIB MMIB =
- {
- MAC_RTSThreshold, MAC_ShortRetryLimit,
- MAC_LongRetryLimit, MAC_FragmentationThreshold,
- MAC_MaxTransmitMSDULifetime, MAC_MaxReceiveLifetime,
- //JUNGMIN
- 100 /* BeaconPeriod */, 20 /* ATIMWindowSize */,
- //end of JUNGMIN
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- /* ======================================================================
- TCL Hooks for the simulator
- ====================================================================== */
- static class Mac802_11Class : public TclClass {
- public:
- Mac802_11Class() : TclClass("Mac/802_11") {}
- TclObject* create(int, const char*const*) {
- return (new Mac802_11(&PMIB, &MMIB));
- }
- } class_mac802_11;
- /* ======================================================================
- Mac Class Functions
- ====================================================================== */
- Mac802_11::Mac802_11(PHY_MIB *p, MAC_MIB *m) : Mac(), mhIF_(this), mhNav_(this), mhRecv_(this), mhRecvDATA_(this), mhSend_(this), mhDefer_(this, p->SlotTime), mhBackoff_(this, p->SlotTime)
- //JUNGMIN
- ,mhBeacon_(this), mhBeaconBackoff_(this), mhATIMWindow_(this)
- ,mhWait_(this)
- //end of JUNGMIN
- {
- macmib_ = m;
- phymib_ = p;
- nav_ = 0.0;
- //JUNGMIN
- mhChannelUsage_ = new ChannelUsageTimer[NUMBER_OF_CHANNELS](this);
- //initialize Free Channel List and Channel NAV
- for(int i=0; i<NUMBER_OF_CHANNELS; i++) {
- fcl_[i] = 0;
- dca_cul_[i] = 0.0;
- mhChannelUsage_[i].AssignChannel(i);
- }
- selected_channel_ = -1;
- active_channel_ = 0;
- ready_for_atim_ = 0;
- next_beacon_time_ = 0;
- recved_bytes_ = 0;
- ResetDestInfo();
- //end of JUNGMIN
- tx_state_ = rx_state_ = dx_state_ = MAC_IDLE;
- tx_active_ = 0;
- pktRTS_ = 0;
- pktCTRL_ = 0;
- pktRSH_ = 0;
- //JUNGMIN
- pktATIM_ = 0;
- pktATIMACK_ = 0;
- pktATIMRSH_ = 0;
- pktDx_ = 0;
- pktPending_ = 0;
- //end of JUNGMIN
- cw_ = phymib_->CWMin;
- ssrc_ = slrc_ = 0;
- //JUNGMIN
- sarc_ = 0;
- //end of JUNGMIN
- packet_count_ = 0;
- total_delay_ = 0.0;
- sifs_ = phymib_->SIFSTime;
- pifs_ = sifs_ + phymib_->SlotTime;
- difs_ = sifs_ + 2*phymib_->SlotTime;
- // see (802.11-1999, 9.2.10)
- eifs_ = sifs_ + (8 * ETHER_ACK_LEN / phymib_->PLCPDataRate) + difs_;
- tx_sifs_ = sifs_ - phymib_->RxTxTurnaroundTime;
- tx_pifs_ = tx_sifs_ + phymib_->SlotTime;
- tx_difs_ = tx_sifs_ + 2 * phymib_->SlotTime;
- sta_seqno_ = 1;
- cache_ = 0;
- cache_node_count_ = 0;
- //JUNGMIN
- pc_ = 0;
- btbs_ = 0;
- atim_window_ = 0;
- dca_ = 0;
- //end of JUNGMIN
- // chk if basic/data rates are set
- // otherwise use bandwidth_ as default;
- Tcl& tcl = Tcl::instance();
- tcl.evalf("Mac/802_11 set basicRate_");
- if (strcmp(tcl.result(), "0") != 0)
- bind_bw("basicRate_", &basicRate_);
- else
- basicRate_ = bandwidth_;
- tcl.evalf("Mac/802_11 set dataRate_");
- if (strcmp(tcl.result(), "0") != 0)
- bind_bw("dataRate_", &dataRate_);
- else
- dataRate_ = bandwidth_;
- }
- int
- Mac802_11::command(int argc, const char*const* argv)
- {
- if (argc == 3) {
- if (strcmp(argv[1], "log-target") == 0) {
- logtarget_ = (NsObject*) TclObject::lookup(argv[2]);
- if(logtarget_ == 0)
- return TCL_ERROR;
- return TCL_OK;
- } else if(strcmp(argv[1], "nodes") == 0) {
- if(cache_) return TCL_ERROR;
- 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;
- }
- //JUNGMIN
- //Sets the beacon period
- else if(strcmp(argv[1], "beaconperiod") == 0) {
- macmib_->dot11BeaconPeriod = atoi(argv[2]);
- return TCL_OK;
- } else if(strcmp(argv[1], "atimwindowsize") == 0) {
- macmib_->dot11ATIMWindowSize = atoi(argv[2]);
- return TCL_OK;
- }
- }
- else if(argc == 2) {
- //Let this node be the Point Coordinator
- if(strcmp(argv[1], "make-pc") == 0) {
- pc_ = 1;
- mhBeacon_.start(macmib_->dot11BeaconPeriod*0.001000);
- next_beacon_time_ = NOW + (macmib_->dot11BeaconPeriod * 0.001000);
- return TCL_OK;
- } else if(strcmp(argv[1], "recved_bytes") == 0) {
- printf("%dn", recved_bytes_);
- fflush(stdout);
- return TCL_OK;
- } else if(strcmp(argv[1], "average_delay") == 0) {
- if(packet_count_ != 0) {
- printf("%lfn", (total_delay_ / (double)packet_count_));
- } else {
- printf("");
- }
- fflush(stdout);
- return TCL_OK;
- } else if(strcmp(argv[1], "dca") == 0) {
- dca_ = 1;
- return TCL_OK;
- }
- //end of JUNGMIN
- }
- return Mac::command(argc, argv);
- }
- /* ======================================================================
- Debugging Routines
- ====================================================================== */
- void
- Mac802_11::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 %dn",
- *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::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: %dn",
- tx_state_, rx_state_, nav_, is_idle());
- fprintf(stderr,
- "tpktTx_: %x, pktRx_: %x, pktRTS_: %x, pktCTRL_: %x, callback: %xn",
- (int) pktTx_, (int) pktRx_, (int) pktRTS_,
- (int) pktCTRL_, (int) callback_);
- fprintf(stderr,
- "tDefer: %d, Backoff: %d (%d), Recv: %d, Timer: %d Nav: %dn",
- mhDefer_.busy(), mhBackoff_.busy(), mhBackoff_.paused(),
- mhRecv_.busy(), mhSend_.busy(), mhNav_.busy());
- fprintf(stderr,
- "tBackoff Expire: %fn",
- mhBackoff_.expire());
- }
- /* ======================================================================
- Packet Headers Routines
- ====================================================================== */
- inline int
- Mac802_11::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::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::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::is_idle()
- {
- if(rx_state_ != MAC_IDLE)
- return 0;
- if(tx_state_ != MAC_IDLE)
- return 0;
- if(dx_state_ != MAC_IDLE)
- return 0;
- if(nav_ > Scheduler::instance().clock())
- return 0;
- return 1;
- }
- inline int
- Mac802_11::is_channel_idle(int ch)
- {
- if(rx_state_ != MAC_IDLE)
- return 0;
- if(tx_state_ != MAC_IDLE)
- return 0;
- return 1;
- }
- void
- Mac802_11::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);
- break;
- case MAC_Type_Control:
- switch(mh->dh_fc.fc_subtype) {
- case MAC_Subtype_DRTS:
- 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_DCTS:
- case MAC_Subtype_DRSH:
- 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 subtypen");
- 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 subtypen");
- 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::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::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);
- }
- }
- //JUNGMIN
- //When a node becomes available to transmit a packet, it checks whether
- //there is a packet that needs to be sent.
- //end of JUNGMIN
- void
- Mac802_11::tx_resume()
- {
- assert(mhSend_.busy() == 0);
- assert(mhDefer_.busy() == 0);
- //JUNGMIN
- if(btbs_) {
- btbs_ = 0;
- send_beacon();
- }
- //end of JUNGMIN
- //Shouldn't we use else if?
- if(pktCTRL_) {
- //printf("[%d] tx_resume(): Control Packet Ready.n", index_);
- /*
- * Need to send a CTS or ACK.
- */
- mhDefer_.start(sifs_);
- }
- //JUNGMIN
- else if(pktATIMRSH_) {
- mhDefer_.start(sifs_);
- }
- else if(pktATIMACK_) {
- mhDefer_.start(sifs_);
- }
- else if(pktPCF_) {
- if(mhBackoff_.busy()) {
- mhBackoff_.stop();
- }
- mhDefer_.start(sifs_);
- }
- else if(pktATIM_) {
- if(mhBackoff_.busy() == 0)
- mhDefer_.start(difs_);
- }
- //end of JUNGMIN
- else if(pktRTS_) {
- if(mhBackoff_.busy() == 0)
- mhDefer_.start(difs_);
- } 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) {
- mhDefer_.start(difs_);
- } else {
- //JUNGMIN
- //this is because there has been RTS/CTS exchange
- //end of JUNGMIN
- mhDefer_.start(sifs_);
- }
- }
- //JUNGMIN
- //because of this callback, send function can just return if it is during
- //backoff. Here callback is Interface Queue.
- //end of JUNGMIN
- } else if(callback_) {
- Handler *h = callback_;
- callback_ = 0;
- if(pktPending_ != 0 && mhWait_.busy() == 0) {
- Packet *p = pktPending_;
- pktPending_ = 0;
- send(p, h);
- } else {
- h->handle((Event*) 0);
- }
- }
- SET_TX_STATE(MAC_IDLE);
- }
- void
- Mac802_11::rx_resume()
- {
- assert(pktRx_ == 0);
- assert(mhRecv_.busy() == 0);
- SET_RX_STATE(MAC_IDLE);
- }
- void
- Mac802_11::dx_resume()
- {
- assert(pktDx_ == 0);
- assert(mhRecvDATA_.busy() == 0);
- SET_DX_STATE(MAC_IDLE);
- }
- /* ======================================================================
- Timer Handler Routines
- ====================================================================== */
- void
- Mac802_11::backoffHandler()
- {
- if(pktCTRL_) {
- assert(mhSend_.busy() || mhDefer_.busy());
- return;
- }
- if(check_pktPCF() == 0)
- return;
- if(pktATIMRSH_) {
- return;
- }
- if(pktATIMACK_) {
- return;
- }
- //JUNGMIN
- if(check_pktATIM() == 0)
- return;
- //end of JUNGMIN
- if(pktTx_) {
- if(atim_window_ == 1 || NearBeacon(pktTx_, 1)) {
- ll_->ifq()->ReturnPacket(pktTx_);
- if(pktRTS_ != 0)
- Packet::free(pktRTS_); pktRTS_ = 0;
- pktTx_ = 0;
- }
- }
- if(check_pktRTS() == 0)
- return;
- if(check_pktTx() == 0)
- return;
- }
- void
- Mac802_11::deferHandler()
- {
- //JUNGMIN
- assert(pktCTRL_ || pktRTS_ || pktTx_ || pktPCF_ || pktATIM_ || pktATIMACK_ || pktATIMRSH_);
- //end of JUNGMIN
- if(check_pktCTRL() == 0)
- return;
- if(check_pktPCF() == 0)
- return;
- //JUNGMIN
- if(check_pktATIMRSH() == 0)
- return;
- if(check_pktATIMACK() == 0)
- return;
- if(check_pktATIM() == 0)
- return;
- //end of JUNGMIN
- assert(mhBackoff_.busy() == 0);
- if(check_pktRTS() == 0)
- return;
- if(check_pktTx() == 0)
- return;
- }
- void
- Mac802_11::navHandler()
- {
- if(is_idle() && mhBackoff_.paused())
- mhBackoff_.resume(difs_);
- }
- void
- Mac802_11::channelusageHandler(int ch)
- {
- if(ch < NUMBER_OF_CHANNELS) {
- dca_cul_[ch] = 0;
- } else {
- printf("ERROR: Trying to access non-existing channeln");
- }
- }
- void
- Mac802_11::waitHandler()
- {
- }
- //JUNGMIN
- void
- Mac802_11::atimHandler()
- {
- atim_window_ = 0;
- ready_for_atim_ = 0;
- if(selected_channel_ == -1) active_channel_ = 0; //Default channel
- else active_channel_ = selected_channel_;
- if(index_ < 18 && index_ >= 0) {
- }
- if(btbs_) {
- btbs_ = 0;
- }
- if(callback_ == 0) {
- ll_->ifq()->ResetATIMWindow(1);
- }
- else {
- ll_->ifq()->ResetATIMWindow(0);
- }
- //status parameter 0: not idle 1: idle
- // if idle, this function should callback the queue
- // explicitly to send packets.
- }
- //end of JUNGMIN
- void
- Mac802_11::recvHandler()
- {
- recv_timer();
- }
- void
- Mac802_11::recvDATAHandler()
- {
- recvDATA_timer();
- }
- void
- Mac802_11::sendHandler()
- {
- send_timer();
- }
- void
- Mac802_11::txHandler()
- {
- tx_active_ = 0;
- }
- //JUNGMIN
- void
- Mac802_11::beaconHandler()
- {
- //Schedule the next beacon
- mhBeacon_.start(macmib_->dot11BeaconPeriod*0.001000);
- next_beacon_time_ = NOW + (macmib_->dot11BeaconPeriod * 0.001000);
- ResetAtBeacon();
- SetATIMWindow();
- if(mhATIMWindow_.busy())
- mhATIMWindow_.stop();
- mhATIMWindow_.start(macmib_->dot11ATIMWindowSize*0.001000);
- //Distribute Beacon
- //Instead of sending beacon right away, wait for a certain amount of time.
- prepare_beacon();
- }
- void
- Mac802_11::beaconBackoffHandler()
- {
- //printf("[%d] %lf: beaconBackoffHandler Called.n", index_, NOW);
- send_beacon();
- }
- //end of JUNGMIN
- /* ======================================================================
- The "real" Timer Handler Routines
- ====================================================================== */
- void
- Mac802_11::send_timer()
- {
- switch(tx_state_) {
- case MAC_ATIM:
- RetransmitATIM();
- break;
- case MAC_ATIMACK:
- assert(pktATIMACK_);
- Packet::free(pktATIMACK_); pktATIMACK_ = 0;
- break;
- case MAC_ATIMRSH:
- assert(pktATIMRSH_);
- Packet::free(pktATIMRSH_); pktATIMRSH_ = 0;
- break;
- /*
- * 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:
- if(pktRSH_) {
- Packet::free(pktRSH_); pktRSH_ = 0;
- //only for now
- RetransmitDATA();
- } else {
- RetransmitDATA();
- }
- break;
- /*
- * Sent an ACK, and now ready to resume transmission.
- */
- case MAC_ACK:
- assert(pktCTRL_);
- Packet::free(pktCTRL_); pktCTRL_ = 0;
- break;
- //JUNGMIN
- case MAC_BEACONING:
- if(pktPCF_) {
- Packet::free(pktPCF_); pktPCF_ = 0;
- }
- break;
- //end of JUNGMIN
- case MAC_IDLE:
- break;
- default:
- assert(0);
- }
- tx_resume();
- }
- /* ======================================================================
- Outgoing Packet Routines
- ====================================================================== */
- int
- Mac802_11::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_);
- struct dca_cts_frame *dcts;
- 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_DCTS:
- if(!is_idle()) {
- discard(pktCTRL_, DROP_MAC_BUSY); pktCTRL_ = 0;
- return 0;
- }
- SET_TX_STATE(MAC_CTS);
- dcts = (struct dca_cts_frame*)pktCTRL_->access(hdr_mac::offset_);
- timeout = txtime(ETHER_DCTS_LEN, basicRate_)
- + DSSS_MaxPropagationDelay
- + dcts->dcts_usage_time
- + sifs_
- + DSSS_MaxPropagationDelay
- + DSSS_MaxPropagationDelay;
- if(dcts->dcts_selected_channel == -1) {
- timeout = txtime(ETHER_DCTS_LEN, basicRate_);
- }
- break;
- case MAC_Subtype_ACK:
- SET_TX_STATE(MAC_ACK);
- timeout = txtime(ETHER_ACK_LEN, basicRate_);
- break;
- default:
- fprintf(stderr, "check_pktCTRL:Invalid MAC Control subtypen");
- exit(1);
- }
- //JUNGMIN
- if(mh->dh_fc.fc_subtype == MAC_Subtype_CTS) {
- }
- else if(mh->dh_fc.fc_subtype == MAC_Subtype_DCTS) {
- }
- else if(mh->dh_fc.fc_subtype == MAC_Subtype_ACK) {
- }
- //end of JUNGMIN
- TRANSMIT(pktCTRL_, timeout);
- return 0;
- }
- //JUNGMIN
- int
- Mac802_11::check_pktATIMACK()
- {
- struct hdr_mac802_11 *mh;
- double timeout;
- if(pktATIMACK_ == 0)
- return -1;
- if(tx_state_ == MAC_ATIMACK)
- return -1;
- mh = HDR_MAC802_11(pktATIMACK_);
- switch(mh->dh_fc.fc_subtype) {
- case MAC_Subtype_ATIMACK:
- SET_TX_STATE(MAC_ATIMACK);
- timeout = txtime(ETHER_ATIMACK_LEN, basicRate_) ;
- break;
- default:
- fprintf(stderr, "check_pktATIMACK: Invalid MAC Management subtypen");
- exit(1);
- }
- TRANSMIT(pktATIMACK_, timeout);
- return 0;
- }
- int
- Mac802_11::check_pktATIMRSH()
- {
- struct hdr_mac802_11 *mh;
- double timeout;
- if(pktATIMRSH_ == 0)
- return -1;
- if(tx_state_ == MAC_ATIMRSH)
- return -1;
- mh = HDR_MAC802_11(pktATIMRSH_);
- switch(mh->dh_fc.fc_subtype) {
- case MAC_Subtype_ATIMRSH:
- SET_TX_STATE(MAC_ATIMRSH);
- timeout = txtime(ETHER_ATIMRSH_LEN, basicRate_) ;
- break;
- default:
- fprintf(stderr, "check_pktATIMRSH: Invalid MAC Management subtypen");
- exit(1);
- }
- TRANSMIT(pktATIMRSH_, timeout);
- return 0;
- }
- //end of JUNGMIN
- int
- Mac802_11::check_pktRTS()
- {
- struct hdr_mac802_11 *mh;
- double timeout;
- assert(mhBackoff_.busy() == 0);
- if(pktRTS_ == 0)
- return -1;
- mh = HDR_MAC802_11(pktRTS_);
- struct dca_rts_frame *drts;
- switch(mh->dh_fc.fc_subtype) {
- 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;
- case MAC_Subtype_DRTS:
- if(! is_idle()) {
- inc_cw();
- mhBackoff_.start(cw_, is_idle());
- return 0;
- }
- SET_TX_STATE(MAC_RTS);
- timeout = txtime(ETHER_DRTS_LEN, basicRate_)
- + DSSS_MaxPropagationDelay // XXX
- + sifs_
- + txtime(ETHER_DCTS_LEN, basicRate_)
- + DSSS_MaxPropagationDelay; // XXX
- drts = (struct dca_rts_frame*)pktRTS_->access(hdr_mac::offset_);
- DCABuildFreeChannelList(drts->drts_channel_list);
- break;
- default:
- fprintf(stderr, "check_pktRTS:Invalid MAC Control subtypen");
- exit(1);
- }
- TRANSMIT(pktRTS_, timeout);
- return 0;
- }
- int
- Mac802_11::check_pktATIM()
- {
- struct hdr_mac802_11 *mh;
- double timeout;
- assert(mhBackoff_.busy() == 0);
- if(pktATIM_ == 0)
- return -1;
- mh = HDR_MAC802_11(pktATIM_);
- struct atim_frame *atf = (struct atim_frame*)pktATIM_->access(hdr_mac::offset_);
- switch(mh->dh_fc.fc_subtype) {
- case MAC_Subtype_ATIM:
- if(!is_idle()) {
- inc_cw();
- mhBackoff_.start(cw_, is_idle());
- return 0;
- }
- SET_TX_STATE(MAC_ATIM);
- timeout = txtime(ETHER_ATIM_LEN, basicRate_)
- + DSSS_MaxPropagationDelay
- + sifs_
- + txtime(ETHER_ATIMACK_LEN, basicRate_)
- + DSSS_MaxPropagationDelay;
- break;
- default:
- fprintf(stderr, "check_pktATIM: Invalid MAC Management subtypen");
- exit(1);
- }
- //copying my fcl_ onto the packet (SHOULD BE AS CLOSEST AS POSSIBLE TO ACTUAL SEND)
- for(int j=0; j<NUMBER_OF_CHANNELS; j++) {
- atf->atf_channel_list[j] = fcl_[j];
- }
- TRANSMIT(pktATIM_, timeout);
- return 0;
- }
- int
- Mac802_11::check_pktTx()
- {
- struct hdr_mac802_11 *mh;
- double timeout;
- assert(mhBackoff_.busy() == 0);
- if(pktTx_ == 0)
- return -1;
- //if DCA mode, send DRSH also at the same time in different channel
- mh = HDR_MAC802_11(pktTx_);
- int len = HDR_CMN(pktTx_)->size();
- struct hdr_cmn *ch = HDR_CMN(pktTx_);
- switch(mh->dh_fc.fc_subtype) {
- case MAC_Subtype_Data:
- if(! is_idle()) {
- if(dca_) {
- sendDRTS(ETHER_ADDR(mh->dh_da));
- } else {
- 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 subtypen");
- exit(1);
- }
- if(dca_) {
- if((u_int32_t)ETHER_ADDR(mh->dh_da) != MAC_BROADCAST) {
- if(active_channel_ == DEFAULT_CHANNEL || active_channel_ < 0) {
- printf("ERROR: Cannot send data on this channel!n");
- exit(1);
- } else {
- mh->dh_fc.fc_channel = active_channel_;
- }
- } else {
- mh->dh_fc.fc_channel = DEFAULT_CHANNEL;
- }
- } else {
- if(active_channel_ != -1)
- mh->dh_fc.fc_channel = active_channel_;
- else
- mh->dh_fc.fc_channel = DEFAULT_CHANNEL;
- }
- if(dca_) {
- if((u_int32_t)ETHER_ADDR(mh->dh_da) != MAC_BROADCAST) {
- //TRANSMIT(pktRSH_, 0.0);
- }
- }
- TRANSMIT(pktTx_, timeout);
- return 0;
- }
- //JUNGMIN
- int
- Mac802_11::check_pktPCF()
- {
- struct hdr_mac802_11 *mh;
- double timeout;
- //assert(mhBackoff_.busy() == 0);
- if(pktPCF_ == 0)
- return -1;
- mh = HDR_MAC802_11(pktPCF_);
- int len = HDR_CMN(pktPCF_)->size();
- switch(mh->dh_fc.fc_type) {
- case MAC_Type_Management:
- switch(mh->dh_fc.fc_subtype) {
- case MAC_Subtype_Beacon:
- if(!is_idle())
- return -1;
- struct beacon_frame *beacon = (struct beacon_frame *)pktPCF_->access(hdr_mac::offset_);
- timeout = txtime(pktPCF_);
- SET_TX_STATE(MAC_BEACONING);
- }
- break;
- default:
- fprintf(stderr, "check_pktPCF:Invalid MAC (sub)typen");
- exit(1);
- }
- TRANSMIT(pktPCF_, timeout);
- //set a flag saying I sent a beacon
- //It is also set when I receive the beacon
- //This is to start sending ATIMs
- if(ready_for_atim_ == 0) {
- ready_for_atim_ = 1;
- ll_->ifq()->StartSendingATIM();
- }
- return 0;
- }
- //end of JUNGMIN
- /*
- * Low-level transmit functions that actually place the packet onto
- * the channel.
- */
- void
- Mac802_11::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_);
- //just for checking
- struct hdr_mac802_11* dh = HDR_MAC802_11(p);
- // sendDATA should be called before sendRTS
- // this is to make sure that RTS be sent only when DATA is ready to be sent.
- 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;
- if(active_channel_ != -1) {
- rf->rf_fc.fc_channel = active_channel_;
- }
- else
- rf->rf_fc.fc_channel = DEFAULT_CHANNEL;
- //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::sendDRTS(int dst)
- {
- Packet *p = Packet::alloc();
- hdr_cmn* ch = HDR_CMN(p);
- struct dca_rts_frame *drts = (struct dca_rts_frame*)p->access(hdr_mac::offset_);
- assert(pktTx_);
- assert(pktRTS_);
- if( (u_int32_t) HDR_CMN(pktTx_)->size() < macmib_->RTSThreshold ||
- (u_int32_t) dst == MAC_BROADCAST) {
- Packet::free(p);
- return;
- }
- ch->uid() = 0;
- ch->ptype() = PT_MAC;
- ch->size() = ETHER_DRTS_LEN;
- ch->iface() = -2;
- ch->error() = 0;
- bzero(drts, MAC_HDR_LEN);
- drts->drts_fc.fc_protocol_version = MAC_ProtocolVersion;
- drts->drts_fc.fc_type = MAC_Type_Control;
- drts->drts_fc.fc_subtype = MAC_Subtype_DRTS;
- drts->drts_fc.fc_to_ds = 0;
- drts->drts_fc.fc_from_ds = 0;
- drts->drts_fc.fc_more_frag = 0;
- drts->drts_fc.fc_retry = 0;
- drts->drts_fc.fc_pwr_mgt = 0;
- drts->drts_fc.fc_more_data = 0;
- drts->drts_fc.fc_wep = 0;
- drts->drts_fc.fc_order = 0;
- drts->drts_fc.fc_channel = DEFAULT_CHANNEL;
- STORE4BYTE(&dst, (drts->drts_da));
- ch->txtime() = txtime(ch->size(), basicRate_);
- STORE4BYTE(&index_, (drts->drts_sa));
- drts->drts_duration = usec(sifs_
- + txtime(ETHER_DCTS_LEN, basicRate_)
- + sifs_
- + txtime(ETHER_DRSH_LEN, basicRate_));
- drts->drts_data_transfer_time = txtime(pktTx_);
- pktRTS_ = p;
- }
- //JUNGMIN
- void
- Mac802_11::InsertDestState(int dst)
- {
- if(dst < 0 || dst > MAX_NODES) return;
- dest_state_[dst] = 1;
- return;
- }
- void
- Mac802_11::InsertNeighborChannelState(int dst, int channel)
- {
- if(dst < 0 || dst > MAX_NODES) return;
- channel_state_[dst] = channel;
- return;
- }
- int
- Mac802_11::LookupDestState(int dst)
- {
- if(dst < 0) return 0;
- return dest_state_[dst];
- }
- int
- Mac802_11::NearBeacon(Packet* p, int afterbackoff)
- {
- //if it is near beacon, return 1
- if(pc_ == 0) return 0;
- //if afterbackoff is 1, then exclude the first difs
- hdr_cmn* ch = HDR_CMN(p);
- int size = ch->size() + ETHER_HDR_LEN11;
- double left_time = next_beacon_time_ - NOW;
- double estimated_time = txtime(ETHER_RTS_LEN, basicRate_)
- + sifs_
- + txtime(ETHER_CTS_LEN, basicRate_)
- + sifs_
- + txtime(size, basicRate_)
- + sifs_
- + txtime(ETHER_ACK_LEN, basicRate_);
- if(afterbackoff == 0) estimated_time += difs_;
- if(estimated_time > left_time) {
- return 1;
- }
- else return 0;
- }
- void
- Mac802_11::sendATIM(int dst, Handler* h)
- {
- //see if it has previously sent an ATIM to that particular destination
- int prev = LookupDestState(dst);
- if(prev == 1) return;
- Packet *p = Packet::alloc();
- hdr_cmn* ch = HDR_CMN(p);
- struct atim_frame *atf = (struct atim_frame*)p->access(hdr_mac::offset_);
- assert(pktATIM_ == 0);
- ch->uid() = 0;
- ch->ptype() = PT_MAC;
- ch->size() = ETHER_ATIM_LEN;
- ch->iface() = -2;
- ch->error() = 0;
- bzero(atf, MAC_HDR_LEN);
- atf->atf_fc.fc_protocol_version = MAC_ProtocolVersion;
- atf->atf_fc.fc_type = MAC_Type_Management;
- atf->atf_fc.fc_subtype = MAC_Subtype_ATIM;
- atf->atf_fc.fc_to_ds = 0;
- atf->atf_fc.fc_from_ds = 0;
- atf->atf_fc.fc_more_frag = 0;
- atf->atf_fc.fc_retry = 0;
- atf->atf_fc.fc_pwr_mgt = 0;
- atf->atf_fc.fc_more_data = 0;
- atf->atf_fc.fc_wep = 0;
- atf->atf_fc.fc_order = 0;
- atf->atf_fc.fc_channel = DEFAULT_CHANNEL;
- STORE4BYTE(&dst, (atf->atf_da));
- ch->txtime() = txtime(ch->size(), basicRate_);
- STORE4BYTE(&index_, (atf->atf_sa));
- atf->atf_duration = usec(sifs_
- + txtime(ETHER_ATIMACK_LEN, basicRate_)
- + sifs_
- + txtime(ETHER_ATIMRSH_LEN, basicRate_));
- //set callback to get back to the queue
- callback_ = h;
- pktATIM_ = p;
- EnergyModel *em = netif_->node()->energy_model();
- if(em && em->sleep()) {
- em->set_node_sleep(0);
- em->set_node_state(EnergyModel::INROUTE);
- }
- if(mhBackoff_.busy() == 0) {
- if(is_idle()) {
- if(mhDefer_.busy() == 0)
- mhDefer_.start(difs_);
- }
- else {
- mhBackoff_.start(cw_, is_idle());
- }
- }
- }
- //end of JUNGMIN
- void
- Mac802_11::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;
- if(active_channel_ != -1)
- cf->cf_fc.fc_channel = active_channel_;
- else
- cf->cf_fc.fc_channel = DEFAULT_CHANNEL;
- //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;
- }
- //JUNGMIN
- void
- Mac802_11::sendDRSH(int dst, double dcts_usage_time)
- {
- Packet *p = Packet::alloc();
- hdr_cmn* ch = HDR_CMN(p);
- struct dca_rsh_frame *drsh = (struct dca_rsh_frame*)p->access(hdr_mac::offset_);
- ch->uid() = 0;
- ch->ptype() = PT_MAC;
- ch->size() = ETHER_DRSH_LEN;
- ch->iface() = -2;
- ch->error() = 0;
- bzero(drsh, MAC_HDR_LEN);
- drsh->drsh_fc.fc_protocol_version = MAC_ProtocolVersion;
- drsh->drsh_fc.fc_type = MAC_Type_Management;
- drsh->drsh_fc.fc_subtype = MAC_Subtype_DRSH;
- drsh->drsh_fc.fc_to_ds = 0;
- drsh->drsh_fc.fc_from_ds = 0;
- drsh->drsh_fc.fc_more_frag = 0;
- drsh->drsh_fc.fc_retry = 0;
- drsh->drsh_fc.fc_pwr_mgt = 0;
- drsh->drsh_fc.fc_more_data = 0;
- drsh->drsh_fc.fc_wep = 0;
- drsh->drsh_fc.fc_order = 0;
- drsh->drsh_fc.fc_channel = DEFAULT_CHANNEL;
- STORE4BYTE(&dst, (drsh->drsh_ra));
- ch->txtime() = txtime(ch->size(), basicRate_);
- drsh->drsh_duration = 0;
- drsh->drsh_confirmed_channel = active_channel_;
- drsh->drsh_usage_time = dcts_usage_time
- - sifs_
- - txtime(ETHER_DRSH_LEN, basicRate_);
- //update dca_cul_
- DCAUpdateCUL(active_channel_, dcts_usage_time);
- pktRSH_ = p;
- }
- void
- Mac802_11::sendDCTS(int dst, double data_transfer_time)
- {
- Packet *p = Packet::alloc();
- hdr_cmn* ch = HDR_CMN(p);
- struct dca_cts_frame *dcts = (struct dca_cts_frame*)p->access(hdr_mac::offset_);
- assert(pktCTRL_ == 0);
- ch->uid() = 0;
- ch->ptype() = PT_MAC;
- ch->size() = ETHER_DCTS_LEN;
- ch->iface() = -2;
- ch->error() = 0;
- //ch->direction() = hdr_cmn::DOWN;
- bzero(dcts, MAC_HDR_LEN);
- dcts->dcts_fc.fc_protocol_version = MAC_ProtocolVersion;
- dcts->dcts_fc.fc_type = MAC_Type_Control;
- dcts->dcts_fc.fc_subtype = MAC_Subtype_DCTS;
- dcts->dcts_fc.fc_to_ds = 0;
- dcts->dcts_fc.fc_from_ds = 0;
- dcts->dcts_fc.fc_more_frag = 0;
- dcts->dcts_fc.fc_retry = 0;
- dcts->dcts_fc.fc_pwr_mgt = 0;
- dcts->dcts_fc.fc_more_data = 0;
- dcts->dcts_fc.fc_wep = 0;
- dcts->dcts_fc.fc_order = 0;
- dcts->dcts_fc.fc_channel = DEFAULT_CHANNEL;
- //cf->cf_duration = CTS_DURATION(rts_duration);
- STORE4BYTE(&dst, (dcts->dcts_ra));
- /* store cts tx time */
- ch->txtime() = txtime(ch->size(), basicRate_);
- /* calculate cts duration */
- dcts->dcts_duration = usec(sifs_
- + txtime(ETHER_DRSH_LEN, basicRate_));
- dcts->dcts_usage_time = sifs_
- + data_transfer_time
- + sifs_
- + txtime(ETHER_ACK_LEN, basicRate_);
- active_channel_ = DCASelectChannel(dca_recved_fcl_);
- dcts->dcts_selected_channel = active_channel_;
- if(dcts->dcts_selected_channel != -1) {
- dcts->dcts_wait_time = 0.0;
- //update dca_cul_
- DCAUpdateCUL(active_channel_, dcts->dcts_usage_time + txtime(ETHER_DCTS_LEN, basicRate_) + sifs_);
- } else {
- dcts->dcts_wait_time = FindNearestChannelFreeTime();
- }
- pktCTRL_ = p;
- }
- //end of JUNGMIN
- void
- Mac802_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);
- 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;
- if(dca_ == 0) {
- if(active_channel_ != -1)
- af->af_fc.fc_channel = active_channel_;
- else
- af->af_fc.fc_channel = DEFAULT_CHANNEL;
- } else {
- if(active_channel_ == -1 || active_channel_ == DEFAULT_CHANNEL) {
- printf("ERROR: cannot send packet on this channel!n");
- exit(1);
- }
- else {
- af->af_fc.fc_channel = active_channel_;
- }
- }
- //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;
- }
- //JUNGMIN
- void
- Mac802_11::sendATIMACK(int dst)
- {
- Packet *p = Packet::alloc();
- hdr_cmn* ch = HDR_CMN(p);
- struct atimack_frame *aaf = (struct atimack_frame*)p->access(hdr_mac::offset_);
- assert(pktATIMACK_ == 0);
- ch->uid() = 0;
- ch->ptype() = PT_MAC;
- ch->size() = ETHER_ATIMACK_LEN;
- ch->iface() = -2;
- ch->error() = 0;
- bzero(aaf, MAC_HDR_LEN);
- aaf->aaf_fc.fc_protocol_version = MAC_ProtocolVersion;
- aaf->aaf_fc.fc_type = MAC_Type_Management;
- aaf->aaf_fc.fc_subtype = MAC_Subtype_ATIMACK;
- aaf->aaf_fc.fc_to_ds = 0;
- aaf->aaf_fc.fc_from_ds = 0;
- aaf->aaf_fc.fc_more_frag = 0;
- aaf->aaf_fc.fc_retry = 0;
- aaf->aaf_fc.fc_pwr_mgt = 0;
- aaf->aaf_fc.fc_more_data = 0;
- aaf->aaf_fc.fc_wep = 0;
- aaf->aaf_fc.fc_order = 0;
- aaf->aaf_fc.fc_channel = DEFAULT_CHANNEL;
- STORE4BYTE(&dst, (aaf->aaf_ra));
- STORE4BYTE(&index_, (aaf->aaf_sa));
- ch->txtime() = txtime(ch->size(), basicRate_);
- aaf->aaf_duration = usec(sifs_
- + txtime(ETHER_ATIMRSH_LEN, basicRate_));
- aaf->aaf_selected_channel = selected_channel_;
- pktATIMACK_ = p;
- }
- void
- Mac802_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 JUNGMIN
- void
- Mac802_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-%dn",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
- ====================================================================== */
- void
- Mac802_11::RetransmitRTS()
- {
- //printf("[%d] %lf: Retransmitting RTSn", 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:%xn",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:%xn",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());
- }
- }
- //JUNGMIN
- void
- Mac802_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 JUNGMIN
- void
- Mac802_11::RetransmitDATA()
- {
- //printf("[%d] %lf: Retransmit DATAn", 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
- ====================================================================== */
- void
- Mac802_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());
- }
- }
- }
- void
- Mac802_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);
- }
- }
- }
- }
- }
- void
- Mac802_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 6n");
- 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(pktDx_, "---");
- goto done;
- }
- //printf("STEP FINALn");
- switch(type) {
- case MAC_Type_Control:
- switch(subtype) {
- case MAC_Subtype_ACK:
- recvACK(pktDx_);
- break;
- default:
- fprintf(stderr,"recvTimer1:Invalid MAC Control Subtype %xn",
- subtype);
- exit(1);
- }
- break;
- case MAC_Type_Data:
- //printf("DATA RECEIVEDn");
- switch(subtype) {
- case MAC_Subtype_Data:
- recvDATA(pktDx_);
- break;
- default:
- fprintf(stderr, "recv_timer2:Invalid MAC Data Subtype %xn",
- subtype);
- exit(1);
- }
- break;
- default:
- fprintf(stderr, "recv_timer3:Invalid MAC Type %xn", subtype);
- exit(1);
- }
- done:
- pktDx_ = 0;
- dx_resume();
- }
- void
- Mac802_11::recv_timer()
- {
- u_int32_t src;
- hdr_cmn *ch = HDR_CMN(pktRx_);
- hdr_mac802_11 *mh = HDR_MAC802_11(pktRx_);
- //JUNGMIN
- struct beacon_frame *beacon;
- //end of JUNGMIN
- 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(!(type == MAC_Type_Management && subtype == MAC_Subtype_Beacon)) {
- 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)
- */
- //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(pktRx_);
- }
- else if(subtype == MAC_Subtype_ATIMACK) {
- recvOtherATIMACK(pktRx_);
- }
- } else if(type == MAC_Type_Control) {
- if(subtype == MAC_Subtype_DCTS) {
- recvOtherDCTS(pktRx_);
- }
- else if(subtype == MAC_Subtype_DRSH) {
- recvOtherDRSH(pktRx_);
- }
- }
- }
- /* 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:
- //JUNGMIN
- switch(subtype) {
- case MAC_Subtype_Beacon:
- beacon = (struct beacon_frame *)pktRx_->access(hdr_mac::offset_);
- macmib_->dot11BeaconPeriod = beacon->bf_binterval;
- //if waiting to send beacon, stop it.
- beacon_received();
- mac_log(pktRx_);
- break;
- case MAC_Subtype_ATIM:
- recvATIM(pktRx_);
- break;
- case MAC_Subtype_ATIMACK:
- recvATIMACK(pktRx_);
- break;
- case MAC_Subtype_ATIMRSH:
- recvATIMRSH(pktRx_);
- break;
- default:
- discard(pktRx_, DROP_MAC_PACKET_ERROR);
- }
- //end of JUNGMIN
- 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_DRTS:
- recvDRTS(pktRx_);
- break;
- case MAC_Subtype_DCTS:
- recvDCTS(pktRx_);
- break;
- case MAC_Subtype_DRSH:
- recvDRSH(pktRx_);
- break;
- case MAC_Subtype_ACK:
- recvACK(pktRx_);
- break;
- default:
- fprintf(stderr,"recvTimer1:Invalid MAC Control Subtype %xn",
- subtype);
- exit(1);
- }
- break;
- //JUNGMIN
- case MAC_Type_Data:
- switch(subtype) {
- case MAC_Subtype_Data:
- recvDATA(pktRx_);
- break;
- //end of JUNGMIN
- default:
- fprintf(stderr, "recv_timer2:Invalid MAC Data Subtype %xn",
- subtype);
- exit(1);
- }
- break;
- default:
- fprintf(stderr, "recv_timer3:Invalid MAC Type %xn", subtype);
- exit(1);
- }
- done:
- pktRx_ = 0;
- rx_resume();
- }
- void
- Mac802_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);
- }
- void
- Mac802_11::recvDRTS(Packet *p)
- {
- struct dca_rts_frame *drts = (struct dca_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;
- }
- for(int i=0; i<NUMBER_OF_CHANNELS; i++) {
- dca_recved_fcl_[i] = drts->drts_channel_list[i];
- }
- sendDCTS(ETHER_ADDR(drts->drts_sa), drts->drts_data_transfer_time);
- /*
- * Stop deferring - will be reset in tx_resume().
- */
- if(mhDefer_.busy()) mhDefer_.stop();
- tx_resume();
- mac_log(p);
- }
- //JUNGMIN
- void
- Mac802_11::recvATIM(Packet *p)
- {
- struct atim_frame *atf = (struct atim_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 ATIM.
- if(pktATIMACK_) {
- discard(p, DROP_MAC_BUSY);
- return;
- }
- SelectChannel(atf);
- sendATIMACK(ETHER_ADDR(atf->atf_sa));
- if(mhDefer_.busy()) mhDefer_.stop();
- tx_resume();
- mac_log(p);
- }
- void
- Mac802_11::DCABuildFreeChannelList(int* fcl)
- {
- fcl[0] = 0;
- for(int i=1; i<NUMBER_OF_CHANNELS; i++) {
- if(dca_cul_[i] == 0)
- fcl[i] = 1;
- else
- fcl[i] = 0;
- }
- }
- void
- Mac802_11::ConfirmChannel(struct atimack_frame* aaf)
- {
- if(selected_channel_ == -1) {
- selected_channel_ = aaf->aaf_selected_channel;
- }
- }
- void
- Mac802_11::SelectChannel(struct atim_frame* atf)
- {
- //Channel Selection Algorithm
- int* cl = atf->atf_channel_list;
- int j, potentia, p_index, dye;
- //1. Receiver Selected
- if(selected_channel_ != -1)
- return;
- //2. Sender preferable
- for(j=0; j<NUMBER_OF_CHANNELS; j++) {
- if(cl[j] == -1) {
- fcl_[j] = -1;
- selected_channel_ = j; //update mine
- return;
- }
- }
- p_index = 0;
- potentia = fcl_[p_index];
- //3. Receiver Free
- for(j=0; j<NUMBER_OF_CHANNELS; j++) {
- if(fcl_[j] <= potentia) {
- if(fcl_[j] == potentia) {
- p_index = j;
- }
- else {
- potentia = fcl_[j];
- p_index = j;
- }
- }
- }
- //4. Sender Free
- for(j=0; j<NUMBER_OF_CHANNELS; j++) {
- if(cl[j] < potentia) {
- potentia = cl[j];
- p_index = j;
- }
- }
- fcl_[p_index] = -1;
- selected_channel_ = p_index;
- return;
- }
- int
- Mac802_11::DCASelectChannel(int* fcl)
- {
- for(int i=1; i<NUMBER_OF_CHANNELS; i++) {
- if(dca_cul_[i] == 0) return i;
- }
- return -1;
- }
- double
- Mac802_11::FindNearestChannelFreeTime()
- {
- double nearest = dca_cul_[1];
- int i;
- for(i=2; i<NUMBER_OF_CHANNELS; i++) {
- if(dca_cul_[i] < nearest) {
- nearest = dca_cul_[i];
- }
- }
- return nearest;
- }
- void
- Mac802_11::ResetChannelInfo()
- {
- for(int j=0; j<NUMBER_OF_CHANNELS; j++) {
- fcl_[j] = 0;
- }
- selected_channel_ = -1;
- active_channel_ = 0;
- }
- void
- Mac802_11::ResetNeighborChannelStateInfo()
- {
- for(int j=0; j<MAX_NODES; j++) {
- channel_state_[j] = -1;
- }
- }
- void
- Mac802_11::ResetDestInfo()
- {
- for(int i=0; i<MAX_NODES; i++) {
- dest_state_[i] = 0; //Did I send ATIM packet to dest i?
- }
- }
- void
- Mac802_11::ResetAtBeacon()
- {
- ResetChannelInfo();
- ResetDestInfo();
- ResetNeighborChannelStateInfo();
- }
- //end of JUNGMIN
- /*
- * txtime() - pluck the precomputed tx time from the packet header
- */
- double
- Mac802_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
- */
- double
- Mac802_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);
- }
- //JUNGMIN
- void
- Mac802_11::recvDCTS(Packet *p)
- {
- if(tx_state_ != MAC_RTS) {
- discard(p, DROP_MAC_INVALID_STATE);
- return;
- }
- assert(pktRTS_);
- Packet::free(pktRTS_); pktRTS_ = 0;
- assert(pktTx_);
- mhSend_.stop();
- ssrc_ = 0;
- rst_cw();
- struct dca_cts_frame *dcts = (struct dca_cts_frame*)p->access(hdr_mac::offset_);
- if(dcts->dcts_selected_channel != -1) {
- active_channel_ = dcts->dcts_selected_channel;
- sendDRSH(ETHER_ADDR(dcts->dcts_ra), dcts->dcts_usage_time);
- tx_resume();
- } else {
- //postpone the transmission and start waitTimer
- pktTx_ = 0;
- if(NOW - dcts->dcts_wait_time > 0) {
- if(mhWait_.busy())
- mhWait_.stop();
- mhWait_.start(difs_);
- } else {
- if(mhWait_.busy())
- mhWait_.stop();
- mhWait_.start(dcts->dcts_wait_time - NOW);
- }
- tx_resume();
- }
- mac_log(p);
- }
- //end of JUNGMIN
- void
- Mac802_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_);
- 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);
- }
- //JUNGMIN
- void
- Mac802_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);
- {
- 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(dca_ == 0) {
- if (tx_state_ == MAC_CTS) {
- assert(pktCTRL_);
- Packet::free(pktCTRL_); pktCTRL_ = 0;
- mhSend_.stop();
- /*
- * Our CTS got through.
- */
- ssrc_ = 0;
- rst_cw();
- }
- else {
- discard(p, DROP_MAC_BUSY);
- return;
- }
- } else {
- assert(pktCTRL_);
- Packet::free(pktCTRL_); pktCTRL_ = 0;
- mhSend_.stop();
- ssrc_ = 0;
- rst_cw();
- }
- 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.
- //record recved bytes
- if((ch->ptype() != PT_MESSAGE) && (ch->ptype() != PT_ARP)) {
- recved_bytes_ += size - ETHER_HDR_LEN11;
- }
- uptarget_->recv(p, (Handler*) 0);
- }
- //end of JUNGMIN
- void
- Mac802_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:%xn",index_,p);
- assert(pktTx_);
- //printf("[%d] Free DATA because it's ACKed.nn", index_);
- 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.
- */
- rst_cw();
- assert(mhBackoff_.busy() == 0);
- mhBackoff_.start(cw_, is_idle());
- tx_resume();
- mac_log(p);
- }
- //JUNGMIN
- void
- Mac802_11::recvATIMACK(Packet *p)
- {
- struct atimack_frame *aaf = (struct atimack_frame*)p->access(hdr_mac::offset_);
- struct hdr_cmn *ch = HDR_CMN(p);
- if(tx_state_ != MAC_ATIM) {
- discard(p, DROP_MAC_INVALID_STATE);
- return;
- }
- assert(pktATIM_);
- Packet::free(pktATIM_); pktATIM_ = 0;
- mhSend_.stop();
- ConfirmChannel(aaf);
- sendATIMRSH(ETHER_ADDR(aaf->aaf_sa));
- InsertDestState(ETHER_ADDR(aaf->aaf_sa));
- InsertNeighborChannelState(ETHER_ADDR(aaf->aaf_sa), aaf->aaf_selected_channel);
- sarc_ = 0;
- rst_cw();
- assert(mhBackoff_.busy() == 0);
- mhBackoff_.start(cw_, is_idle());
- tx_resume();
- mac_log(p);
- }
- void
- Mac802_11::recvDRSH(Packet *p)
- {
- mac_log(p);
- }
- void
- Mac802_11::recvATIMRSH(Packet *p)
- {
- struct hdr_cmn *ch = HDR_CMN(p);
- tx_resume();
- mac_log(p);
- }
- void
- Mac802_11::DCAUpdateCUL(int s_channel, double usage_time)
- {
- //update dca_cul_ and timer
- if(dca_cul_[s_channel] < NOW + usage_time) {
- //update
- dca_cul_[s_channel] = NOW + usage_time;
- if(mhChannelUsage_[s_channel].busy())
- mhChannelUsage_[s_channel].stop();
- mhChannelUsage_[s_channel].start(usage_time);
- }
- }
- void
- Mac802_11::recvOtherDRSH(Packet *p)
- {
- struct dca_rsh_frame *drsh = (struct dca_rsh_frame*)p->access(hdr_mac::offset_);
- int s_channel = drsh->drsh_confirmed_channel;
- if(s_channel > 0) {
- DCAUpdateCUL(s_channel, drsh->drsh_usage_time);
- }
- }
- void
- Mac802_11::recvOtherATIMRSH(Packet *p)
- {
- struct atimrsh_frame *ahf = (struct atimrsh_frame*)p->access(hdr_mac::offset_);
- int s_channel = ahf->ahf_confirmed_channel;
- if(fcl_[s_channel] != -1) fcl_[s_channel]++;
- return;
- }
- void
- Mac802_11::recvOtherDCTS(Packet *p)
- {
- struct dca_cts_frame *dcts = (struct dca_cts_frame*)p->access(hdr_mac::offset_);
- int s_channel = dcts->dcts_selected_channel;
- if(s_channel > 0) {
- DCAUpdateCUL(s_channel, dcts->dcts_usage_time);
- }
- }
- void
- Mac802_11::recvOtherATIMACK(Packet *p)
- {
- struct atimack_frame *aaf = (struct atimack_frame*)p->access(hdr_mac::offset_);
- int s_channel = aaf->aaf_selected_channel;
- if(fcl_[s_channel] != -1) fcl_[s_channel]++;
- return;
- }
- int
- Mac802_11::CheckDest(Packet *p)
- {
- hdr_mac802_11* dh = HDR_MAC802_11(p);
- return (u_int32_t)ETHER_ADDR(dh->dh_da);
- }
- void
- Mac802_11::prepare_beacon()
- {
- mhBeaconBackoff_.start(BEACON_BACKOFF_WINDOW);
- }
- void
- Mac802_11::beacon_received()
- {
- if(mhBeaconBackoff_.busy())
- mhBeaconBackoff_.stop();
- if(btbs_ == 1) {
- btbs_ = 0;
- }
- if(pktPCF_) {
- Packet::free(pktPCF_);
- pktPCF_ = 0;
- }
- if(ready_for_atim_ == 0) {
- SetATIMWindow(); //it automatically tells queue to set ATIM window
- if(mhATIMWindow_.busy())
- mhATIMWindow_.stop();
- mhATIMWindow_.start(macmib_->dot11ATIMWindowSize*0.001000);
- ready_for_atim_ = 1;
- ll_->ifq()->StartSendingATIM();
- }
- }
- void
- Mac802_11::SetATIMWindow()
- {
- atim_window_ = 1;
- ll_->ifq()->SetATIMWindow();
- }
- void
- Mac802_11::send_beacon()
- {
- if(tx_state_!=MAC_SEND&&tx_state_!=MAC_CTS && rx_state_==MAC_IDLE) {
- //We can send the beacon now
- pcfSend(MAC_Type_Management, MAC_Subtype_Beacon);
- } else {
- btbs_ = 1;
- }
- }
- void Mac802_11::pcfSend(int type, int subtype)
- {
- //Packet Generation
- Packet* p = Packet::alloc();
- struct hdr_mac802_11 *mh = (struct hdr_mac802_11 *)p->access(hdr_mac::offset_);
- hdr_cmn* ch = HDR_CMN(p);
- ch->ptype() = PT_MAC;
- int dst = MAC_BROADCAST;
- double defertime = pifs_;
- Scheduler &s = Scheduler::instance();
- bzero(&mh->dh_fc, sizeof(struct frame_control));
- mh->dh_fc.fc_protocol_version = MAC_ProtocolVersion;
- mh->dh_fc.fc_type = type;
- mh->dh_fc.fc_subtype = subtype;
- if(active_channel_ != -1) {
- mh->dh_fc.fc_channel = active_channel_;
- }
- else
- mh->dh_fc.fc_channel = DEFAULT_CHANNEL;
- mh->dh_scontrol = sta_seqno_++;
- ch->size() += ETHER_HDR_LEN11;
- switch(type) {
- case MAC_Type_Management:
- switch(subtype) {
- case MAC_Subtype_Beacon:
- struct beacon_frame *beacon = (struct beacon_frame *)p->access(hdr_mac::offset_);
- beacon->bf_timestamp = (unsigned long long)((Scheduler::instance()).clock()*1000);
- beacon->bf_binterval = macmib_->dot11BeaconPeriod;
- beacon->bf_duration = 0;
- break;
- }
- break;
- }
- pktPCF_ = p;
- STORE4BYTE(&dst, (mh->dh_da));
- STORE4BYTE(&index_, (mh->dh_sa));
- EnergyModel *em = netif_->node()->energy_model();
- if(em && em->sleep()) {
- em->set_node_sleep(0);
- em->set_node_state(EnergyModel::INROUTE);
- }
- if(mhBackoff_.busy() == 0) {
- if(is_idle()) {
- if(mhDefer_.busy() == 0)
- mhDefer_.start(defertime);
- }
- else {
- mhBackoff_.start(cw_, is_idle());
- }
- }
- }
- double
- Mac802_11::NextBeaconTime()
- {
- return next_beacon_time_;
- }
- //end of JUNGMIN