mac-802_11.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*-
00002  *
00003  * Copyright (c) 1997 Regents of the University of California.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. All advertising materials mentioning features or use of this software
00015  *    must display the following acknowledgement:
00016  *  This product includes software developed by the Computer Systems
00017  *  Engineering Group at Lawrence Berkeley Laboratory.
00018  * 4. Neither the name of the University nor of the Laboratory may be used
00019  *    to endorse or promote products derived from this software without
00020  *    specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  *
00034  * $Header: /nfs/jade/vint/CVSROOT/ns-2/mac/mac-802_11.cc,v 1.50 2005/09/18 23:33:33 tomh Exp $
00035  *
00036  * Ported from CMU/Monarch's code, nov'98 -Padma.
00037  * Contributions by:
00038  *   - Mike Holland
00039  *   - Sushmita
00040  */
00041 
00042 #include "delay.h"
00043 #include "connector.h"
00044 #include "packet.h"
00045 #include "random.h"
00046 #include "mobilenode.h"
00047 
00048 // #define DEBUG 99
00049 
00050 #include "arp.h"
00051 #include "ll.h"
00052 #include "mac.h"
00053 #include "mac-timers.h"
00054 #include "mac-802_11.h"
00055 #include "cmu-trace.h"
00056 
00057 // Added by Sushmita to support event tracing
00058 #include "agent.h"
00059 #include "basetrace.h"
00060 
00061 
00062 /* our backoff timer doesn't count down in idle times during a
00063  * frame-exchange sequence as the mac tx state isn't idle; genreally
00064  * these idle times are less than DIFS and won't contribute to
00065  * counting down the backoff period, but this could be a real
00066  * problem if the frame exchange ends up in a timeout! in that case,
00067  * i.e. if a timeout happens we've not been counting down for the
00068  * duration of the timeout, and in fact begin counting down only
00069  * DIFS after the timeout!! we lose the timeout interval - which
00070  * will is not the REAL case! also, the backoff timer could be NULL
00071  * and we could have a pending transmission which we could have
00072  * sent! one could argue this is an implementation artifact which
00073  * doesn't violate the spec.. and the timeout interval is expected
00074  * to be less than DIFS .. which means its not a lot of time we
00075  * lose.. anyway if everyone hears everyone the only reason a ack will
00076  * be delayed will be due to a collision => the medium won't really be
00077  * idle for a DIFS for this to really matter!!
00078  */
00079 
00080 inline void
00081 Mac802_11::checkBackoffTimer()
00082 {
00083     if(is_idle() && mhBackoff_.paused())
00084         mhBackoff_.resume(phymib_.getDIFS());
00085     if(! is_idle() && mhBackoff_.busy() && ! mhBackoff_.paused())
00086         mhBackoff_.pause();
00087 }
00088 
00089 inline void
00090 Mac802_11::transmit(Packet *p, double timeout)
00091 {
00092     tx_active_ = 1;
00093     
00094     if (EOTtarget_) {
00095         assert (eotPacket_ == NULL);
00096         eotPacket_ = p->copy();
00097     }
00098 
00099     /*
00100      * If I'm transmitting without doing CS, such as when
00101      * sending an ACK, any incoming packet will be "missed"
00102      * and hence, must be discarded.
00103      */
00104     if(rx_state_ != MAC_IDLE) {
00105         //assert(dh->dh_fc.fc_type == MAC_Type_Control);
00106         //assert(dh->dh_fc.fc_subtype == MAC_Subtype_ACK);
00107         assert(pktRx_);
00108         struct hdr_cmn *ch = HDR_CMN(pktRx_);
00109         ch->error() = 1;        /* force packet discard */
00110     }
00111 
00112     /*
00113      * pass the packet on the "interface" which will in turn
00114      * place the packet on the channel.
00115      *
00116      * NOTE: a handler is passed along so that the Network
00117      *       Interface can distinguish between incoming and
00118      *       outgoing packets.
00119      */
00120     downtarget_->recv(p->copy(), this); 
00121     mhSend_.start(timeout);
00122     mhIF_.start(txtime(p));
00123 }
00124 inline void
00125 Mac802_11::setRxState(MacState newState)
00126 {
00127     rx_state_ = newState;
00128     checkBackoffTimer();
00129 }
00130 
00131 inline void
00132 Mac802_11::setTxState(MacState newState)
00133 {
00134     tx_state_ = newState;
00135     checkBackoffTimer();
00136 }
00137 
00138 
00139 /* ======================================================================
00140    TCL Hooks for the simulator
00141    ====================================================================== */
00142 static class Mac802_11Class : public TclClass {
00143 public:
00144     Mac802_11Class() : TclClass("Mac/802_11") {}
00145     TclObject* create(int, const char*const*) {
00146     return (new Mac802_11());
00147 
00148 }
00149 } class_mac802_11;
00150 
00151 
00152 /* ======================================================================
00153    Mac  and Phy MIB Class Functions
00154    ====================================================================== */
00155 
00156 PHY_MIB::PHY_MIB(Mac802_11 *parent)
00157 {
00158     /*
00159      * Bind the phy mib objects.  Note that these will be bound
00160      * to Mac/802_11 variables
00161      */
00162 
00163     parent->bind("CWMin_", &CWMin);
00164     parent->bind("CWMax_", &CWMax);
00165     parent->bind("SlotTime_", &SlotTime);
00166     parent->bind("SIFS_", &SIFSTime);
00167     parent->bind("PreambleLength_", &PreambleLength);
00168     parent->bind("PLCPHeaderLength_", &PLCPHeaderLength);
00169     parent->bind_bw("PLCPDataRate_", &PLCPDataRate);
00170 }
00171 
00172 MAC_MIB::MAC_MIB(Mac802_11 *parent)
00173 {
00174     /*
00175      * Bind the phy mib objects.  Note that these will be bound
00176      * to Mac/802_11 variables
00177      */
00178     
00179     parent->bind("RTSThreshold_", &RTSThreshold);
00180     parent->bind("ShortRetryLimit_", &ShortRetryLimit);
00181     parent->bind("LongRetryLimit_", &LongRetryLimit);
00182 }
00183 
00184 /* ======================================================================
00185    Mac Class Functions
00186    ====================================================================== */
00187 Mac802_11::Mac802_11() : 
00188     Mac(), phymib_(this), macmib_(this), mhIF_(this), mhNav_(this), 
00189     mhRecv_(this), mhSend_(this), 
00190     mhDefer_(this), mhBackoff_(this)
00191 {
00192     
00193     nav_ = 0.0;
00194     tx_state_ = rx_state_ = MAC_IDLE;
00195     tx_active_ = 0;
00196     eotPacket_ = NULL;
00197     pktRTS_ = 0;
00198     pktCTRL_ = 0;       
00199     cw_ = phymib_.getCWMin();
00200     ssrc_ = slrc_ = 0;
00201     // Added by Sushmita
00202         et_ = new EventTrace();
00203     
00204     sta_seqno_ = 1;
00205     cache_ = 0;
00206     cache_node_count_ = 0;
00207     
00208     // chk if basic/data rates are set
00209     // otherwise use bandwidth_ as default;
00210     
00211     Tcl& tcl = Tcl::instance();
00212     tcl.evalf("Mac/802_11 set basicRate_");
00213     if (strcmp(tcl.result(), "0") != 0) 
00214         bind_bw("basicRate_", &basicRate_);
00215     else
00216         basicRate_ = bandwidth_;
00217 
00218     tcl.evalf("Mac/802_11 set dataRate_");
00219     if (strcmp(tcl.result(), "0") != 0) 
00220         bind_bw("dataRate_", &dataRate_);
00221     else
00222         dataRate_ = bandwidth_;
00223 
00224         EOTtarget_ = 0;
00225         bss_id_ = IBSS_ID;
00226     //printf("bssid in constructor %d\n",bss_id_);
00227 }
00228 
00229 
00230 int
00231 Mac802_11::command(int argc, const char*const* argv)
00232 {
00233     if (argc == 3) {
00234         if (strcmp(argv[1], "eot-target") == 0) {
00235             EOTtarget_ = (NsObject*) TclObject::lookup(argv[2]);
00236             if (EOTtarget_ == 0)
00237                 return TCL_ERROR;
00238             return TCL_OK;
00239         } else if (strcmp(argv[1], "bss_id") == 0) {
00240             bss_id_ = atoi(argv[2]);
00241             return TCL_OK;
00242         } else if (strcmp(argv[1], "log-target") == 0) { 
00243             logtarget_ = (NsObject*) TclObject::lookup(argv[2]);
00244             if(logtarget_ == 0)
00245                 return TCL_ERROR;
00246             return TCL_OK;
00247         } else if(strcmp(argv[1], "nodes") == 0) {
00248             if(cache_) return TCL_ERROR;
00249             cache_node_count_ = atoi(argv[2]);
00250             cache_ = new Host[cache_node_count_ + 1];
00251             assert(cache_);
00252             bzero(cache_, sizeof(Host) * (cache_node_count_+1 ));
00253             return TCL_OK;
00254         } else if(strcmp(argv[1], "eventtrace") == 0) {
00255             // command added to support event tracing by Sushmita
00256                         et_ = (EventTrace *)TclObject::lookup(argv[2]);
00257                         return (TCL_OK);
00258                 }
00259     }
00260     return Mac::command(argc, argv);
00261 }
00262 
00263 // Added by Sushmita to support event tracing
00264 void Mac802_11::trace_event(char *eventtype, Packet *p) 
00265 {
00266         if (et_ == NULL) return;
00267         char *wrk = et_->buffer();
00268         char *nwrk = et_->nbuffer();
00269     
00270         //char *src_nodeaddr =
00271     //       Address::instance().print_nodeaddr(iph->saddr());
00272         //char *dst_nodeaddr =
00273         //      Address::instance().print_nodeaddr(iph->daddr());
00274     
00275         struct hdr_mac802_11* dh = HDR_MAC802_11(p);
00276     
00277         //struct hdr_cmn *ch = HDR_CMN(p);
00278     
00279     if(wrk != 0) {
00280         sprintf(wrk, "E -t "TIME_FORMAT" %s %2x ",
00281             et_->round(Scheduler::instance().clock()),
00282                         eventtype,
00283                         //ETHER_ADDR(dh->dh_sa)
00284                         ETHER_ADDR(dh->dh_ta)
00285                         );
00286         }
00287         if(nwrk != 0) {
00288                 sprintf(nwrk, "E -t "TIME_FORMAT" %s %2x ",
00289                         et_->round(Scheduler::instance().clock()),
00290                         eventtype,
00291                         //ETHER_ADDR(dh->dh_sa)
00292                         ETHER_ADDR(dh->dh_ta)
00293                         );
00294         }
00295         et_->dump();
00296 }
00297 
00298 /* ======================================================================
00299    Debugging Routines
00300    ====================================================================== */
00301 void
00302 Mac802_11::trace_pkt(Packet *p) 
00303 {
00304     struct hdr_cmn *ch = HDR_CMN(p);
00305     struct hdr_mac802_11* dh = HDR_MAC802_11(p);
00306     u_int16_t *t = (u_int16_t*) &dh->dh_fc;
00307 
00308     fprintf(stderr, "\t[ %2x %2x %2x %2x ] %x %s %d\n",
00309         *t, dh->dh_duration,
00310          ETHER_ADDR(dh->dh_ra), ETHER_ADDR(dh->dh_ta),
00311         index_, packet_info.name(ch->ptype()), ch->size());
00312 }
00313 
00314 void
00315 Mac802_11::dump(char *fname)
00316 {
00317     fprintf(stderr,
00318         "\n%s --- (INDEX: %d, time: %2.9f)\n",
00319         fname, index_, Scheduler::instance().clock());
00320 
00321     fprintf(stderr,
00322         "\ttx_state_: %x, rx_state_: %x, nav: %2.9f, idle: %d\n",
00323         tx_state_, rx_state_, nav_, is_idle());
00324 
00325     fprintf(stderr,
00326         "\tpktTx_: %lx, pktRx_: %lx, pktRTS_: %lx, pktCTRL_: %lx, callback: %lx\n",
00327         (long) pktTx_, (long) pktRx_, (long) pktRTS_,
00328         (long) pktCTRL_, (long) callback_);
00329 
00330     fprintf(stderr,
00331         "\tDefer: %d, Backoff: %d (%d), Recv: %d, Timer: %d Nav: %d\n",
00332         mhDefer_.busy(), mhBackoff_.busy(), mhBackoff_.paused(),
00333         mhRecv_.busy(), mhSend_.busy(), mhNav_.busy());
00334     fprintf(stderr,
00335         "\tBackoff Expire: %f\n",
00336         mhBackoff_.expire());
00337 }
00338 
00339 
00340 /* ======================================================================
00341    Packet Headers Routines
00342    ====================================================================== */
00343 inline int
00344 Mac802_11::hdr_dst(char* hdr, int dst )
00345 {
00346     struct hdr_mac802_11 *dh = (struct hdr_mac802_11*) hdr;
00347     
00348        if (dst > -2) {
00349                if ((bss_id() == ((int)IBSS_ID)) || (addr() == bss_id())) {
00350                        /* if I'm AP (2nd condition above!), the dh_3a
00351                         * is already set by the MAC whilst fwding; if
00352                         * locally originated pkt, it might make sense
00353                         * to set the dh_3a to myself here! don't know
00354                         * how to distinguish between the two here - and
00355                         * the info is not critical to the dst station
00356                         * anyway!
00357                         */
00358                        STORE4BYTE(&dst, (dh->dh_ra));
00359                } else {
00360                        /* in BSS mode, the AP forwards everything;
00361                         * therefore, the real dest goes in the 3rd
00362                         * address, and the AP address goes in the
00363                         * destination address
00364                         */
00365                        STORE4BYTE(&bss_id_, (dh->dh_ra));
00366                        STORE4BYTE(&dst, (dh->dh_3a));
00367                }
00368        }
00369 
00370 
00371        return (u_int32_t)ETHER_ADDR(dh->dh_ra);
00372 }
00373 
00374 inline int 
00375 Mac802_11::hdr_src(char* hdr, int src )
00376 {
00377     struct hdr_mac802_11 *dh = (struct hdr_mac802_11*) hdr;
00378         if(src > -2)
00379                STORE4BYTE(&src, (dh->dh_ta));
00380         return ETHER_ADDR(dh->dh_ta);
00381 }
00382 
00383 inline int 
00384 Mac802_11::hdr_type(char* hdr, u_int16_t type)
00385 {
00386     struct hdr_mac802_11 *dh = (struct hdr_mac802_11*) hdr;
00387     if(type)
00388         STORE2BYTE(&type,(dh->dh_body));
00389     return GET2BYTE(dh->dh_body);
00390 }
00391 
00392 
00393 /* ======================================================================
00394    Misc Routines
00395    ====================================================================== */
00396 inline int
00397 Mac802_11::is_idle()
00398 {
00399     if(rx_state_ != MAC_IDLE)
00400         return 0;
00401     if(tx_state_ != MAC_IDLE)
00402         return 0;
00403     if(nav_ > Scheduler::instance().clock())
00404         return 0;
00405     
00406     return 1;
00407 }
00408 
00409 void
00410 Mac802_11::discard(Packet *p, const char* why)
00411 {
00412     hdr_mac802_11* mh = HDR_MAC802_11(p);
00413     hdr_cmn *ch = HDR_CMN(p);
00414 
00415     /* if the rcvd pkt contains errors, a real MAC layer couldn't
00416        necessarily read any data from it, so we just toss it now */
00417     if(ch->error() != 0) {
00418         Packet::free(p);
00419         return;
00420     }
00421 
00422     switch(mh->dh_fc.fc_type) {
00423     case MAC_Type_Management:
00424         drop(p, why);
00425         return;
00426     case MAC_Type_Control:
00427         switch(mh->dh_fc.fc_subtype) {
00428         case MAC_Subtype_RTS:
00429              if((u_int32_t)ETHER_ADDR(mh->dh_ta) ==  (u_int32_t)index_) {
00430                 drop(p, why);
00431                 return;
00432             }
00433             /* fall through - if necessary */
00434         case MAC_Subtype_CTS:
00435         case MAC_Subtype_ACK:
00436             if((u_int32_t)ETHER_ADDR(mh->dh_ra) == (u_int32_t)index_) {
00437                 drop(p, why);
00438                 return;
00439             }
00440             break;
00441         default:
00442             fprintf(stderr, "invalid MAC Control subtype\n");
00443             exit(1);
00444         }
00445         break;
00446     case MAC_Type_Data:
00447         switch(mh->dh_fc.fc_subtype) {
00448         case MAC_Subtype_Data:
00449             if((u_int32_t)ETHER_ADDR(mh->dh_ra) == \
00450                            (u_int32_t)index_ ||
00451                           (u_int32_t)ETHER_ADDR(mh->dh_ta) == \
00452                            (u_int32_t)index_ ||
00453                           (u_int32_t)ETHER_ADDR(mh->dh_ra) == MAC_BROADCAST) {
00454                                 drop(p,why);
00455                                 return;
00456             }
00457             break;
00458         default:
00459             fprintf(stderr, "invalid MAC Data subtype\n");
00460             exit(1);
00461         }
00462         break;
00463     default:
00464         fprintf(stderr, "invalid MAC type (%x)\n", mh->dh_fc.fc_type);
00465         trace_pkt(p);
00466         exit(1);
00467     }
00468     Packet::free(p);
00469 }
00470 
00471 void
00472 Mac802_11::capture(Packet *p)
00473 {
00474     /*
00475      * Update the NAV so that this does not screw
00476      * up carrier sense.
00477      */ 
00478     set_nav(usec(phymib_.getEIFS() + txtime(p)));
00479     Packet::free(p);
00480 }
00481 
00482 void
00483 Mac802_11::collision(Packet *p)
00484 {
00485     switch(rx_state_) {
00486     case MAC_RECV:
00487         setRxState(MAC_COLL);
00488         /* fall through */
00489     case MAC_COLL:
00490         assert(pktRx_);
00491         assert(mhRecv_.busy());
00492         /*
00493          *  Since a collision has occurred, figure out
00494          *  which packet that caused the collision will
00495          *  "last" the longest.  Make this packet,
00496          *  pktRx_ and reset the Recv Timer if necessary.
00497          */
00498         if(txtime(p) > mhRecv_.expire()) {
00499             mhRecv_.stop();
00500             discard(pktRx_, DROP_MAC_COLLISION);
00501             pktRx_ = p;
00502             mhRecv_.start(txtime(pktRx_));
00503         }
00504         else {
00505             discard(p, DROP_MAC_COLLISION);
00506         }
00507         break;
00508     default:
00509         assert(0);
00510     }
00511 }
00512 
00513 void
00514 Mac802_11::tx_resume()
00515 {
00516     double rTime;
00517     assert(mhSend_.busy() == 0);
00518     assert(mhDefer_.busy() == 0);
00519 
00520     if(pktCTRL_) {
00521         /*
00522          *  Need to send a CTS or ACK.
00523          */
00524         mhDefer_.start(phymib_.getSIFS());
00525     } else if(pktRTS_) {
00526         if (mhBackoff_.busy() == 0) {
00527             rTime = (Random::random() % cw_) * phymib_.getSlotTime();
00528             mhDefer_.start( phymib_.getDIFS() + rTime);
00529         }
00530     } else if(pktTx_) {
00531         if (mhBackoff_.busy() == 0) {
00532             hdr_cmn *ch = HDR_CMN(pktTx_);
00533             struct hdr_mac802_11 *mh = HDR_MAC802_11(pktTx_);
00534             
00535             if ((u_int32_t) ch->size() < macmib_.getRTSThreshold()
00536                 || (u_int32_t) ETHER_ADDR(mh->dh_ra) == MAC_BROADCAST) {
00537                 rTime = (Random::random() % cw_)
00538                     * phymib_.getSlotTime();
00539                 mhDefer_.start(phymib_.getDIFS() + rTime);
00540                         } else {
00541                 mhDefer_.start(phymib_.getSIFS());
00542                         }
00543         }
00544     } else if(callback_) {
00545         Handler *h = callback_;
00546         callback_ = 0;
00547         h->handle((Event*) 0);
00548     }
00549     setTxState(MAC_IDLE);
00550 }
00551 
00552 void
00553 Mac802_11::rx_resume()
00554 {
00555     assert(pktRx_ == 0);
00556     assert(mhRecv_.busy() == 0);
00557     setRxState(MAC_IDLE);
00558 }
00559 
00560 
00561 /* ======================================================================
00562    Timer Handler Routines
00563    ====================================================================== */
00564 void
00565 Mac802_11::backoffHandler()
00566 {
00567     if(pktCTRL_) {
00568         assert(mhSend_.busy() || mhDefer_.busy());
00569         return;
00570     }
00571 
00572     if(check_pktRTS() == 0)
00573         return;
00574 
00575     if(check_pktTx() == 0)
00576         return;
00577 }
00578 
00579 void
00580 Mac802_11::deferHandler()
00581 {
00582     assert(pktCTRL_ || pktRTS_ || pktTx_);
00583 
00584     if(check_pktCTRL() == 0)
00585         return;
00586     assert(mhBackoff_.busy() == 0);
00587     if(check_pktRTS() == 0)
00588         return;
00589     if(check_pktTx() == 0)
00590         return;
00591 }
00592 
00593 void
00594 Mac802_11::navHandler()
00595 {
00596     if(is_idle() && mhBackoff_.paused())
00597         mhBackoff_.resume(phymib_.getDIFS());
00598 }
00599 
00600 void
00601 Mac802_11::recvHandler()
00602 {
00603     recv_timer();
00604 }
00605 
00606 void
00607 Mac802_11::sendHandler()
00608 {
00609     send_timer();
00610 }
00611 
00612 
00613 void
00614 Mac802_11::txHandler()
00615 {
00616     if (EOTtarget_) {
00617         assert(eotPacket_);
00618         EOTtarget_->recv(eotPacket_, (Handler *) 0);
00619         eotPacket_ = NULL;
00620     }
00621     tx_active_ = 0;
00622 }
00623 
00624 
00625 /* ======================================================================
00626    The "real" Timer Handler Routines
00627    ====================================================================== */
00628 void
00629 Mac802_11::send_timer()
00630 {
00631     switch(tx_state_) {
00632     /*
00633      * Sent a RTS, but did not receive a CTS.
00634      */
00635     case MAC_RTS:
00636         RetransmitRTS();
00637         break;
00638     /*
00639      * Sent a CTS, but did not receive a DATA packet.
00640      */
00641     case MAC_CTS:
00642         assert(pktCTRL_);
00643         Packet::free(pktCTRL_); 
00644         pktCTRL_ = 0;
00645         break;
00646     /*
00647      * Sent DATA, but did not receive an ACK packet.
00648      */
00649     case MAC_SEND:
00650         RetransmitDATA();
00651         break;
00652     /*
00653      * Sent an ACK, and now ready to resume transmission.
00654      */
00655     case MAC_ACK:
00656         assert(pktCTRL_);
00657         Packet::free(pktCTRL_); 
00658         pktCTRL_ = 0;
00659         break;
00660     case MAC_IDLE:
00661         break;
00662     default:
00663         assert(0);
00664     }
00665     tx_resume();
00666 }
00667 
00668 
00669 /* ======================================================================
00670    Outgoing Packet Routines
00671    ====================================================================== */
00672 int
00673 Mac802_11::check_pktCTRL()
00674 {
00675     struct hdr_mac802_11 *mh;
00676     double timeout;
00677 
00678     if(pktCTRL_ == 0)
00679         return -1;
00680     if(tx_state_ == MAC_CTS || tx_state_ == MAC_ACK)
00681         return -1;
00682 
00683     mh = HDR_MAC802_11(pktCTRL_);
00684                               
00685     switch(mh->dh_fc.fc_subtype) {
00686     /*
00687      *  If the medium is not IDLE, don't send the CTS.
00688      */
00689     case MAC_Subtype_CTS:
00690         if(!is_idle()) {
00691             discard(pktCTRL_, DROP_MAC_BUSY); pktCTRL_ = 0;
00692             return 0;
00693         }
00694         setTxState(MAC_CTS);
00695         /*
00696          * timeout:  cts + data tx time calculated by
00697          *           adding cts tx time to the cts duration
00698          *           minus ack tx time -- this timeout is
00699          *           a guess since it is unspecified
00700          *           (note: mh->dh_duration == cf->cf_duration)
00701          */     
00702          timeout = txtime(phymib_.getCTSlen(), basicRate_)
00703                         + DSSS_MaxPropagationDelay                      // XXX
00704                         + sec(mh->dh_duration)
00705                         + DSSS_MaxPropagationDelay                      // XXX
00706                        - phymib_.getSIFS()
00707                        - txtime(phymib_.getACKlen(), basicRate_);
00708         break;
00709         /*
00710          * IEEE 802.11 specs, section 9.2.8
00711          * Acknowledments are sent after an SIFS, without regard to
00712          * the busy/idle state of the medium.
00713          */
00714     case MAC_Subtype_ACK:       
00715         setTxState(MAC_ACK);
00716         timeout = txtime(phymib_.getACKlen(), basicRate_);
00717         break;
00718     default:
00719         fprintf(stderr, "check_pktCTRL:Invalid MAC Control subtype\n");
00720         exit(1);
00721     }
00722     transmit(pktCTRL_, timeout);
00723     return 0;
00724 }
00725 
00726 int
00727 Mac802_11::check_pktRTS()
00728 {
00729     struct hdr_mac802_11 *mh;
00730     double timeout;
00731 
00732     assert(mhBackoff_.busy() == 0);
00733 
00734     if(pktRTS_ == 0)
00735         return -1;
00736     mh = HDR_MAC802_11(pktRTS_);
00737 
00738     switch(mh->dh_fc.fc_subtype) {
00739     case MAC_Subtype_RTS:
00740         if(! is_idle()) {
00741             inc_cw();
00742             mhBackoff_.start(cw_, is_idle());
00743             return 0;
00744         }
00745         setTxState(MAC_RTS);
00746         timeout = txtime(phymib_.getRTSlen(), basicRate_)
00747             + DSSS_MaxPropagationDelay                      // XXX
00748             + phymib_.getSIFS()
00749             + txtime(phymib_.getCTSlen(), basicRate_)
00750             + DSSS_MaxPropagationDelay;
00751         break;
00752     default:
00753         fprintf(stderr, "check_pktRTS:Invalid MAC Control subtype\n");
00754         exit(1);
00755     }
00756     transmit(pktRTS_, timeout);
00757   
00758 
00759     return 0;
00760 }
00761 
00762 int
00763 Mac802_11::check_pktTx()
00764 {
00765     struct hdr_mac802_11 *mh;
00766     double timeout;
00767     
00768     assert(mhBackoff_.busy() == 0);
00769 
00770     if(pktTx_ == 0)
00771         return -1;
00772 
00773     mh = HDR_MAC802_11(pktTx_);
00774 
00775     switch(mh->dh_fc.fc_subtype) {
00776     case MAC_Subtype_Data:
00777         if(! is_idle()) {
00778             sendRTS(ETHER_ADDR(mh->dh_ra));
00779             inc_cw();
00780             mhBackoff_.start(cw_, is_idle());
00781             return 0;
00782         }
00783         setTxState(MAC_SEND);
00784         if((u_int32_t)ETHER_ADDR(mh->dh_ra) != MAC_BROADCAST)
00785                         timeout = txtime(pktTx_)
00786                                 + DSSS_MaxPropagationDelay              // XXX
00787                                + phymib_.getSIFS()
00788                                + txtime(phymib_.getACKlen(), basicRate_)
00789                                + DSSS_MaxPropagationDelay;             // XXX
00790         else
00791             timeout = txtime(pktTx_);
00792         break;
00793     default:
00794         fprintf(stderr, "check_pktTx:Invalid MAC Control subtype\n");
00795         exit(1);
00796     }
00797     transmit(pktTx_, timeout);
00798     return 0;
00799 }
00800 /*
00801  * Low-level transmit functions that actually place the packet onto
00802  * the channel.
00803  */
00804 void
00805 Mac802_11::sendRTS(int dst)
00806 {
00807     Packet *p = Packet::alloc();
00808     hdr_cmn* ch = HDR_CMN(p);
00809     struct rts_frame *rf = (struct rts_frame*)p->access(hdr_mac::offset_);
00810     
00811     assert(pktTx_);
00812     assert(pktRTS_ == 0);
00813 
00814     /*
00815      *  If the size of the packet is larger than the
00816      *  RTSThreshold, then perform the RTS/CTS exchange.
00817      */
00818     if( (u_int32_t) HDR_CMN(pktTx_)->size() < macmib_.getRTSThreshold() ||
00819             (u_int32_t) dst == MAC_BROADCAST) {
00820         Packet::free(p);
00821         return;
00822     }
00823 
00824     ch->uid() = 0;
00825     ch->ptype() = PT_MAC;
00826     ch->size() = phymib_.getRTSlen();
00827     ch->iface() = -2;
00828     ch->error() = 0;
00829 
00830     bzero(rf, MAC_HDR_LEN);
00831 
00832     rf->rf_fc.fc_protocol_version = MAC_ProtocolVersion;
00833     rf->rf_fc.fc_type   = MAC_Type_Control;
00834     rf->rf_fc.fc_subtype    = MAC_Subtype_RTS;
00835     rf->rf_fc.fc_to_ds  = 0;
00836     rf->rf_fc.fc_from_ds    = 0;
00837     rf->rf_fc.fc_more_frag  = 0;
00838     rf->rf_fc.fc_retry  = 0;
00839     rf->rf_fc.fc_pwr_mgt    = 0;
00840     rf->rf_fc.fc_more_data  = 0;
00841     rf->rf_fc.fc_wep    = 0;
00842     rf->rf_fc.fc_order  = 0;
00843 
00844     //rf->rf_duration = RTS_DURATION(pktTx_);
00845     STORE4BYTE(&dst, (rf->rf_ra));
00846     
00847     /* store rts tx time */
00848     ch->txtime() = txtime(ch->size(), basicRate_);
00849     
00850     STORE4BYTE(&index_, (rf->rf_ta));
00851 
00852     /* calculate rts duration field */  
00853     rf->rf_duration = usec(phymib_.getSIFS()
00854                    + txtime(phymib_.getCTSlen(), basicRate_)
00855                    + phymib_.getSIFS()
00856                                + txtime(pktTx_)
00857                    + phymib_.getSIFS()
00858                    + txtime(phymib_.getACKlen(), basicRate_));
00859     pktRTS_ = p;
00860 }
00861 
00862 void
00863 Mac802_11::sendCTS(int dst, double rts_duration)
00864 {
00865     Packet *p = Packet::alloc();
00866     hdr_cmn* ch = HDR_CMN(p);
00867     struct cts_frame *cf = (struct cts_frame*)p->access(hdr_mac::offset_);
00868 
00869     assert(pktCTRL_ == 0);
00870 
00871     ch->uid() = 0;
00872     ch->ptype() = PT_MAC;
00873     ch->size() = phymib_.getCTSlen();
00874 
00875 
00876     ch->iface() = -2;
00877     ch->error() = 0;
00878     //ch->direction() = hdr_cmn::DOWN;
00879     bzero(cf, MAC_HDR_LEN);
00880 
00881     cf->cf_fc.fc_protocol_version = MAC_ProtocolVersion;
00882     cf->cf_fc.fc_type   = MAC_Type_Control;
00883     cf->cf_fc.fc_subtype    = MAC_Subtype_CTS;
00884     cf->cf_fc.fc_to_ds  = 0;
00885     cf->cf_fc.fc_from_ds    = 0;
00886     cf->cf_fc.fc_more_frag  = 0;
00887     cf->cf_fc.fc_retry  = 0;
00888     cf->cf_fc.fc_pwr_mgt    = 0;
00889     cf->cf_fc.fc_more_data  = 0;
00890     cf->cf_fc.fc_wep    = 0;
00891     cf->cf_fc.fc_order  = 0;
00892     
00893     //cf->cf_duration = CTS_DURATION(rts_duration);
00894     STORE4BYTE(&dst, (cf->cf_ra));
00895     
00896     /* store cts tx time */
00897     ch->txtime() = txtime(ch->size(), basicRate_);
00898     
00899     /* calculate cts duration */
00900     cf->cf_duration = usec(sec(rts_duration)
00901                               - phymib_.getSIFS()
00902                               - txtime(phymib_.getCTSlen(), basicRate_));
00903 
00904 
00905     
00906     pktCTRL_ = p;
00907     
00908 }
00909 
00910 void
00911 Mac802_11::sendACK(int dst)
00912 {
00913     Packet *p = Packet::alloc();
00914     hdr_cmn* ch = HDR_CMN(p);
00915     struct ack_frame *af = (struct ack_frame*)p->access(hdr_mac::offset_);
00916 
00917     assert(pktCTRL_ == 0);
00918 
00919     ch->uid() = 0;
00920     ch->ptype() = PT_MAC;
00921     // CHANGE WRT Mike's code
00922     ch->size() = phymib_.getACKlen();
00923     ch->iface() = -2;
00924     ch->error() = 0;
00925     
00926     bzero(af, MAC_HDR_LEN);
00927 
00928     af->af_fc.fc_protocol_version = MAC_ProtocolVersion;
00929     af->af_fc.fc_type   = MAC_Type_Control;
00930     af->af_fc.fc_subtype    = MAC_Subtype_ACK;
00931     af->af_fc.fc_to_ds  = 0;
00932     af->af_fc.fc_from_ds    = 0;
00933     af->af_fc.fc_more_frag  = 0;
00934     af->af_fc.fc_retry  = 0;
00935     af->af_fc.fc_pwr_mgt    = 0;
00936     af->af_fc.fc_more_data  = 0;
00937     af->af_fc.fc_wep    = 0;
00938     af->af_fc.fc_order  = 0;
00939 
00940     //af->af_duration = ACK_DURATION();
00941     STORE4BYTE(&dst, (af->af_ra));
00942 
00943     /* store ack tx time */
00944     ch->txtime() = txtime(ch->size(), basicRate_);
00945     
00946     /* calculate ack duration */
00947     af->af_duration = 0;    
00948     
00949     pktCTRL_ = p;
00950 }
00951 
00952 void
00953 Mac802_11::sendDATA(Packet *p)
00954 {
00955     hdr_cmn* ch = HDR_CMN(p);
00956     struct hdr_mac802_11* dh = HDR_MAC802_11(p);
00957 
00958     assert(pktTx_ == 0);
00959 
00960     /*
00961      * Update the MAC header
00962      */
00963     ch->size() += phymib_.getHdrLen11();
00964 
00965     dh->dh_fc.fc_protocol_version = MAC_ProtocolVersion;
00966     dh->dh_fc.fc_type       = MAC_Type_Data;
00967     dh->dh_fc.fc_subtype    = MAC_Subtype_Data;
00968     
00969     dh->dh_fc.fc_to_ds      = 0;
00970     dh->dh_fc.fc_from_ds    = 0;
00971     dh->dh_fc.fc_more_frag  = 0;
00972     dh->dh_fc.fc_retry      = 0;
00973     dh->dh_fc.fc_pwr_mgt    = 0;
00974     dh->dh_fc.fc_more_data  = 0;
00975     dh->dh_fc.fc_wep        = 0;
00976     dh->dh_fc.fc_order      = 0;
00977 
00978     /* store data tx time */
00979     ch->txtime() = txtime(ch->size(), dataRate_);
00980 
00981     if((u_int32_t)ETHER_ADDR(dh->dh_ra) != MAC_BROADCAST) {
00982         /* store data tx time for unicast packets */
00983         ch->txtime() = txtime(ch->size(), dataRate_);
00984         
00985         dh->dh_duration = usec(txtime(phymib_.getACKlen(), basicRate_)
00986                        + phymib_.getSIFS());
00987 
00988 
00989 
00990     } else {
00991         /* store data tx time for broadcast packets (see 9.6) */
00992         ch->txtime() = txtime(ch->size(), basicRate_);
00993         
00994         dh->dh_duration = 0;
00995     }
00996     pktTx_ = p;
00997 }
00998 
00999 /* ======================================================================
01000    Retransmission Routines
01001    ====================================================================== */
01002 void
01003 Mac802_11::RetransmitRTS()
01004 {
01005     assert(pktTx_);
01006     assert(pktRTS_);
01007     assert(mhBackoff_.busy() == 0);
01008     macmib_.RTSFailureCount++;
01009 
01010 
01011     ssrc_ += 1;         // STA Short Retry Count
01012         
01013     if(ssrc_ >= macmib_.getShortRetryLimit()) {
01014         discard(pktRTS_, DROP_MAC_RETRY_COUNT_EXCEEDED); pktRTS_ = 0;
01015         /* tell the callback the send operation failed 
01016            before discarding the packet */
01017         hdr_cmn *ch = HDR_CMN(pktTx_);
01018         if (ch->xmit_failure_) {
01019                         /*
01020                          *  Need to remove the MAC header so that 
01021                          *  re-cycled packets don't keep getting
01022                          *  bigger.
01023                          */
01024             ch->size() -= phymib_.getHdrLen11();
01025                         ch->xmit_reason_ = XMIT_REASON_RTS;
01026                         ch->xmit_failure_(pktTx_->copy(),
01027                                           ch->xmit_failure_data_);
01028                 }
01029         discard(pktTx_, DROP_MAC_RETRY_COUNT_EXCEEDED); 
01030         pktTx_ = 0;
01031         ssrc_ = 0;
01032         rst_cw();
01033     } else {
01034         struct rts_frame *rf;
01035         rf = (struct rts_frame*)pktRTS_->access(hdr_mac::offset_);
01036         rf->rf_fc.fc_retry = 1;
01037 
01038         inc_cw();
01039         mhBackoff_.start(cw_, is_idle());
01040     }
01041 }
01042 
01043 void
01044 Mac802_11::RetransmitDATA()
01045 {
01046     struct hdr_cmn *ch;
01047     struct hdr_mac802_11 *mh;
01048     u_int32_t *rcount, thresh;
01049     assert(mhBackoff_.busy() == 0);
01050 
01051     assert(pktTx_);
01052     assert(pktRTS_ == 0);
01053 
01054     ch = HDR_CMN(pktTx_);
01055     mh = HDR_MAC802_11(pktTx_);
01056 
01057     /*
01058      *  Broadcast packets don't get ACKed and therefore
01059      *  are never retransmitted.
01060      */
01061     if((u_int32_t)ETHER_ADDR(mh->dh_ra) == MAC_BROADCAST) {
01062         Packet::free(pktTx_); 
01063         pktTx_ = 0;
01064 
01065         /*
01066          * Backoff at end of TX.
01067          */
01068         rst_cw();
01069         mhBackoff_.start(cw_, is_idle());
01070 
01071         return;
01072     }
01073 
01074     macmib_.ACKFailureCount++;
01075 
01076     if((u_int32_t) ch->size() <= macmib_.getRTSThreshold()) {
01077                 rcount = &ssrc_;
01078                thresh = macmib_.getShortRetryLimit();
01079         } else {
01080                 rcount = &slrc_;
01081                thresh = macmib_.getLongRetryLimit();
01082         }
01083 
01084     (*rcount)++;
01085 
01086     if(*rcount >= thresh) {
01087         /* IEEE Spec section 9.2.3.5 says this should be greater than
01088            or equal */
01089         macmib_.FailedCount++;
01090         /* tell the callback the send operation failed 
01091            before discarding the packet */
01092         hdr_cmn *ch = HDR_CMN(pktTx_);
01093         if (ch->xmit_failure_) {
01094                         ch->size() -= phymib_.getHdrLen11();
01095             ch->xmit_reason_ = XMIT_REASON_ACK;
01096                         ch->xmit_failure_(pktTx_->copy(),
01097                                           ch->xmit_failure_data_);
01098                 }
01099 
01100         discard(pktTx_, DROP_MAC_RETRY_COUNT_EXCEEDED); 
01101         pktTx_ = 0;
01102         *rcount = 0;
01103         rst_cw();
01104     }
01105     else {
01106         struct hdr_mac802_11 *dh;
01107         dh = HDR_MAC802_11(pktTx_);
01108         dh->dh_fc.fc_retry = 1;
01109 
01110 
01111         sendRTS(ETHER_ADDR(mh->dh_ra));
01112         inc_cw();
01113         mhBackoff_.start(cw_, is_idle());
01114     }
01115 }
01116 
01117 /* ======================================================================
01118    Incoming Packet Routines
01119    ====================================================================== */
01120 void
01121 Mac802_11::send(Packet *p, Handler *h)
01122 {
01123     double rTime;
01124     struct hdr_mac802_11* dh = HDR_MAC802_11(p);
01125 
01126     EnergyModel *em = netif_->node()->energy_model();
01127     if (em && em->sleep()) {
01128         em->set_node_sleep(0);
01129         em->set_node_state(EnergyModel::INROUTE);
01130     }
01131     
01132     callback_ = h;
01133     sendDATA(p);
01134     sendRTS(ETHER_ADDR(dh->dh_ra));
01135 
01136     /*
01137      * Assign the data packet a sequence number.
01138      */
01139     dh->dh_scontrol = sta_seqno_++;
01140 
01141     /*
01142      *  If the medium is IDLE, we must wait for a DIFS
01143      *  Space before transmitting.
01144      */
01145     if(mhBackoff_.busy() == 0) {
01146         if(is_idle()) {
01147             if (mhDefer_.busy() == 0) {
01148                 /*
01149                  * If we are already deferring, there is no
01150                  * need to reset the Defer timer.
01151                  */
01152                 rTime = (Random::random() % cw_)
01153                     * (phymib_.getSlotTime());
01154                 mhDefer_.start(phymib_.getDIFS() + rTime);
01155             }
01156         } else {
01157             /*
01158              * If the medium is NOT IDLE, then we start
01159              * the backoff timer.
01160              */
01161             mhBackoff_.start(cw_, is_idle());
01162         }
01163     }
01164 }
01165 
01166 void
01167 Mac802_11::recv(Packet *p, Handler *h)
01168 {
01169     struct hdr_cmn *hdr = HDR_CMN(p);
01170     /*
01171      * Sanity Check
01172      */
01173     assert(initialized());
01174 
01175     /*
01176      *  Handle outgoing packets.
01177      */
01178     if(hdr->direction() == hdr_cmn::DOWN) {
01179                 send(p, h);
01180                 return;
01181         }
01182     /*
01183      *  Handle incoming packets.
01184      *
01185      *  We just received the 1st bit of a packet on the network
01186      *  interface.
01187      *
01188      */
01189 
01190     /*
01191      *  If the interface is currently in transmit mode, then
01192      *  it probably won't even see this packet.  However, the
01193      *  "air" around me is BUSY so I need to let the packet
01194      *  proceed.  Just set the error flag in the common header
01195      *  to that the packet gets thrown away.
01196      */
01197     if(tx_active_ && hdr->error() == 0) {
01198         hdr->error() = 1;
01199     }
01200 
01201     if(rx_state_ == MAC_IDLE) {
01202         setRxState(MAC_RECV);
01203         pktRx_ = p;
01204         /*
01205          * Schedule the reception of this packet, in
01206          * txtime seconds.
01207          */
01208         mhRecv_.start(txtime(p));
01209     } else {
01210         /*
01211          *  If the power of the incoming packet is smaller than the
01212          *  power of the packet currently being received by at least
01213                  *  the capture threshold, then we ignore the new packet.
01214          */
01215         if(pktRx_->txinfo_.RxPr / p->txinfo_.RxPr >= p->txinfo_.CPThresh) {
01216             capture(p);
01217         } else {
01218             collision(p);
01219         }
01220     }
01221 }
01222 
01223 void
01224 Mac802_11::recv_timer()
01225 {
01226     u_int32_t src; 
01227     hdr_cmn *ch = HDR_CMN(pktRx_);
01228     hdr_mac802_11 *mh = HDR_MAC802_11(pktRx_);
01229     u_int32_t dst = ETHER_ADDR(mh->dh_ra);
01230     
01231     u_int8_t  type = mh->dh_fc.fc_type;
01232     u_int8_t  subtype = mh->dh_fc.fc_subtype;
01233 
01234     assert(pktRx_);
01235     assert(rx_state_ == MAC_RECV || rx_state_ == MAC_COLL);
01236     
01237         /*
01238          *  If the interface is in TRANSMIT mode when this packet
01239          *  "arrives", then I would never have seen it and should
01240          *  do a silent discard without adjusting the NAV.
01241          */
01242         if(tx_active_) {
01243                 Packet::free(pktRx_);
01244                 goto done;
01245         }
01246 
01247     /*
01248      * Handle collisions.
01249      */
01250     if(rx_state_ == MAC_COLL) {
01251         discard(pktRx_, DROP_MAC_COLLISION);        
01252         set_nav(usec(phymib_.getEIFS()));
01253         goto done;
01254     }
01255 
01256     /*
01257      * Check to see if this packet was received with enough
01258      * bit errors that the current level of FEC still could not
01259      * fix all of the problems - ie; after FEC, the checksum still
01260      * failed.
01261      */
01262     if( ch->error() ) {
01263         Packet::free(pktRx_);
01264         set_nav(usec(phymib_.getEIFS()));
01265         goto done;
01266     }
01267 
01268     /*
01269      * IEEE 802.11 specs, section 9.2.5.6
01270      *  - update the NAV (Network Allocation Vector)
01271      */
01272     if(dst != (u_int32_t)index_) {
01273         set_nav(mh->dh_duration);
01274     }
01275 
01276         /* tap out - */
01277         if (tap_ && type == MAC_Type_Data &&
01278             MAC_Subtype_Data == subtype ) 
01279         tap_->tap(pktRx_);
01280     /*
01281      * Adaptive Fidelity Algorithm Support - neighborhood infomation 
01282      * collection
01283      *
01284      * Hacking: Before filter the packet, log the neighbor node
01285      * I can hear the packet, the src is my neighbor
01286      */
01287     if (netif_->node()->energy_model() && 
01288         netif_->node()->energy_model()->adaptivefidelity()) {
01289         src = ETHER_ADDR(mh->dh_ta);
01290         netif_->node()->energy_model()->add_neighbor(src);
01291     }
01292     /*
01293      * Address Filtering
01294      */
01295     if(dst != (u_int32_t)index_ && dst != MAC_BROADCAST) {
01296         /*
01297          *  We don't want to log this event, so we just free
01298          *  the packet instead of calling the drop routine.
01299          */
01300         discard(pktRx_, "---");
01301         goto done;
01302     }
01303 
01304     switch(type) {
01305 
01306     case MAC_Type_Management:
01307         discard(pktRx_, DROP_MAC_PACKET_ERROR);
01308         goto done;
01309     case MAC_Type_Control:
01310         switch(subtype) {
01311         case MAC_Subtype_RTS:
01312             recvRTS(pktRx_);
01313             break;
01314         case MAC_Subtype_CTS:
01315             recvCTS(pktRx_);
01316             break;
01317         case MAC_Subtype_ACK:
01318             recvACK(pktRx_);
01319             break;
01320         default:
01321             fprintf(stderr,"recvTimer1:Invalid MAC Control Subtype %x\n",
01322                 subtype);
01323             exit(1);
01324         }
01325         break;
01326     case MAC_Type_Data:
01327         switch(subtype) {
01328         case MAC_Subtype_Data:
01329             recvDATA(pktRx_);
01330             break;
01331         default:
01332             fprintf(stderr, "recv_timer2:Invalid MAC Data Subtype %x\n",
01333                 subtype);
01334             exit(1);
01335         }
01336         break;
01337     default:
01338         fprintf(stderr, "recv_timer3:Invalid MAC Type %x\n", subtype);
01339         exit(1);
01340     }
01341  done:
01342     pktRx_ = 0;
01343     rx_resume();
01344 }
01345 
01346 
01347 void
01348 Mac802_11::recvRTS(Packet *p)
01349 {
01350     struct rts_frame *rf = (struct rts_frame*)p->access(hdr_mac::offset_);
01351 
01352     if(tx_state_ != MAC_IDLE) {
01353         discard(p, DROP_MAC_BUSY);
01354         return;
01355     }
01356 
01357     /*
01358      *  If I'm responding to someone else, discard this RTS.
01359      */
01360     if(pktCTRL_) {
01361         discard(p, DROP_MAC_BUSY);
01362         return;
01363     }
01364 
01365     sendCTS(ETHER_ADDR(rf->rf_ta), rf->rf_duration);
01366 
01367     /*
01368      *  Stop deferring - will be reset in tx_resume().
01369      */
01370     if(mhDefer_.busy()) mhDefer_.stop();
01371 
01372     tx_resume();
01373 
01374     mac_log(p);
01375 }
01376 
01377 /*
01378  * txtime() - pluck the precomputed tx time from the packet header
01379  */
01380 double
01381 Mac802_11::txtime(Packet *p)
01382 {
01383     struct hdr_cmn *ch = HDR_CMN(p);
01384     double t = ch->txtime();
01385     if (t < 0.0) {
01386         drop(p, "XXX");
01387         exit(1);
01388     }
01389     return t;
01390 }
01391 
01392  
01393 /*
01394  * txtime() - calculate tx time for packet of size "psz" bytes 
01395  *        at rate "drt" bps
01396  */
01397 double
01398 Mac802_11::txtime(double psz, double drt)
01399 {
01400     double dsz = psz - phymib_.getPLCPhdrLen();
01401         int plcp_hdr = phymib_.getPLCPhdrLen() << 3;    
01402     int datalen = (int)dsz << 3;
01403     double t = (((double)plcp_hdr)/phymib_.getPLCPDataRate())
01404                                        + (((double)datalen)/drt);
01405     return(t);
01406 }
01407 
01408 
01409 
01410 void
01411 Mac802_11::recvCTS(Packet *p)
01412 {
01413     if(tx_state_ != MAC_RTS) {
01414         discard(p, DROP_MAC_INVALID_STATE);
01415         return;
01416     }
01417 
01418     assert(pktRTS_);
01419     Packet::free(pktRTS_); pktRTS_ = 0;
01420 
01421     assert(pktTx_); 
01422     mhSend_.stop();
01423 
01424     /*
01425      * The successful reception of this CTS packet implies
01426      * that our RTS was successful. 
01427      * According to the IEEE spec 9.2.5.3, you must 
01428      * reset the ssrc_, but not the congestion window.
01429      */
01430     ssrc_ = 0;
01431     tx_resume();
01432 
01433     mac_log(p);
01434 }
01435 
01436 void
01437 Mac802_11::recvDATA(Packet *p)
01438 {
01439     struct hdr_mac802_11 *dh = HDR_MAC802_11(p);
01440     u_int32_t dst, src, size;
01441     struct hdr_cmn *ch = HDR_CMN(p);
01442 
01443     dst = ETHER_ADDR(dh->dh_ra);
01444     src = ETHER_ADDR(dh->dh_ta);
01445     size = ch->size();
01446     /*
01447      * Adjust the MAC packet size - ie; strip
01448      * off the mac header
01449      */
01450     ch->size() -= phymib_.getHdrLen11();
01451     ch->num_forwards() += 1;
01452 
01453     /*
01454      *  If we sent a CTS, clean up...
01455      */
01456     if(dst != MAC_BROADCAST) {
01457         if(size >= macmib_.getRTSThreshold()) {
01458             if (tx_state_ == MAC_CTS) {
01459                 assert(pktCTRL_);
01460                 Packet::free(pktCTRL_); pktCTRL_ = 0;
01461                 mhSend_.stop();
01462                 /*
01463                  * Our CTS got through.
01464                  */
01465             } else {
01466                 discard(p, DROP_MAC_BUSY);
01467                 return;
01468             }
01469             sendACK(src);
01470             tx_resume();
01471         } else {
01472             /*
01473              *  We did not send a CTS and there's no
01474              *  room to buffer an ACK.
01475              */
01476             if(pktCTRL_) {
01477                 discard(p, DROP_MAC_BUSY);
01478                 return;
01479             }
01480             sendACK(src);
01481             if(mhSend_.busy() == 0)
01482                 tx_resume();
01483         }
01484     }
01485     
01486     /* ============================================================
01487        Make/update an entry in our sequence number cache.
01488        ============================================================ */
01489 
01490     /* Changed by Debojyoti Dutta. This upper loop of if{}else was 
01491        suggested by Joerg Diederich <dieder@ibr.cs.tu-bs.de>. 
01492        Changed on 19th Oct'2000 */
01493 
01494         if(dst != MAC_BROADCAST) {
01495                 if (src < (u_int32_t) cache_node_count_) {
01496                         Host *h = &cache_[src];
01497 
01498                         if(h->seqno && h->seqno == dh->dh_scontrol) {
01499                                 discard(p, DROP_MAC_DUPLICATE);
01500                                 return;
01501                         }
01502                         h->seqno = dh->dh_scontrol;
01503                 } else {
01504             static int count = 0;
01505             if (++count <= 10) {
01506                 printf ("MAC_802_11: accessing MAC cache_ array out of range (src %u, dst %u, size %d)!\n", src, dst, cache_node_count_);
01507                 if (count == 10)
01508                     printf ("[suppressing additional MAC cache_ warnings]\n");
01509             };
01510         };
01511     }
01512 
01513     /*
01514      *  Pass the packet up to the link-layer.
01515      *  XXX - we could schedule an event to account
01516      *  for this processing delay.
01517      */
01518     
01519     /* in BSS mode, if a station receives a packet via
01520      * the AP, and higher layers are interested in looking
01521      * at the src address, we might need to put it at
01522      * the right place - lest the higher layers end up
01523      * believing the AP address to be the src addr! a quick
01524      * grep didn't turn up any higher layers interested in
01525      * the src addr though!
01526      * anyway, here if I'm the AP and the destination
01527      * address (in dh_3a) isn't me, then we have to fwd
01528      * the packet; we pick the real destination and set
01529      * set it up for the LL; we save the real src into
01530      * the dh_3a field for the 'interested in the info'
01531      * receiver; we finally push the packet towards the
01532      * LL to be added back to my queue - accomplish this
01533      * by reversing the direction!*/
01534 
01535     if ((bss_id() == addr()) && ((u_int32_t)ETHER_ADDR(dh->dh_ra)!= MAC_BROADCAST)&& ((u_int32_t)ETHER_ADDR(dh->dh_3a) != ((u_int32_t)addr()))) {
01536         struct hdr_cmn *ch = HDR_CMN(p);
01537         u_int32_t dst = ETHER_ADDR(dh->dh_3a);
01538         u_int32_t src = ETHER_ADDR(dh->dh_ta);
01539         /* if it is a broadcast pkt then send a copy up
01540          * my stack also
01541          */
01542         if (dst == MAC_BROADCAST) {
01543             uptarget_->recv(p->copy(), (Handler*) 0);
01544         }
01545 
01546         ch->next_hop() = dst;
01547         STORE4BYTE(&src, (dh->dh_3a));
01548         ch->addr_type() = NS_AF_ILINK;
01549         ch->direction() = hdr_cmn::DOWN;
01550     }
01551 
01552     uptarget_->recv(p, (Handler*) 0);
01553 }
01554 
01555 
01556 void
01557 Mac802_11::recvACK(Packet *p)
01558 {   
01559     if(tx_state_ != MAC_SEND) {
01560         discard(p, DROP_MAC_INVALID_STATE);
01561         return;
01562     }
01563     assert(pktTx_);
01564 
01565     mhSend_.stop();
01566 
01567     /*
01568      * The successful reception of this ACK packet implies
01569      * that our DATA transmission was successful.  Hence,
01570      * we can reset the Short/Long Retry Count and the CW.
01571      *
01572      * need to check the size of the packet we sent that's being
01573      * ACK'd, not the size of the ACK packet.
01574      */
01575     if((u_int32_t) HDR_CMN(pktTx_)->size() <= macmib_.getRTSThreshold())
01576         ssrc_ = 0;
01577     else
01578         slrc_ = 0;
01579     rst_cw();
01580     Packet::free(pktTx_); 
01581     pktTx_ = 0;
01582     
01583     /*
01584      * Backoff before sending again.
01585      */
01586     assert(mhBackoff_.busy() == 0);
01587     mhBackoff_.start(cw_, is_idle());
01588 
01589     tx_resume();
01590 
01591     mac_log(p);
01592 }

Generated on Tue Mar 6 16:47:47 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6