miracle_mac-802_11.cc

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

Generated on Wed Nov 26 15:47:28 2008 for NS-MIRACLE library by  doxygen 1.5.2