aodv_rqueue.cc

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 1997, 1998 Carnegie Mellon University.  All Rights
00003 Reserved. 
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007 
00008 1. Redistributions of source code must retain the above copyright notice,
00009 this list of conditions and the following disclaimer.
00010 2. Redistributions in binary form must reproduce the above copyright notice,
00011 this list of conditions and the following disclaimer in the documentation
00012 and/or other materials provided with the distribution.
00013 3. The name of the author may not be used to endorse or promote products
00014 derived from this software without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00017 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00018 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00019 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00020 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00021 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00022 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00023 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00024 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00025 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 
00027 The AODV code developed by the CMU/MONARCH group was optimized and tuned by Samir Das and Mahesh Marina, University of Cincinnati. The work was partially done in Sun Microsystems.
00028 */
00029 
00030 
00031 #include <assert.h>
00032 
00033 #include <cmu-trace.h>
00034 #include <aodv/aodv_rqueue.h>
00035 
00036 #define CURRENT_TIME    Scheduler::instance().clock()
00037 #define QDEBUG
00038 
00039 /*
00040   Packet Queue used by AODV.
00041 */
00042 
00043 aodv_rqueue::aodv_rqueue() {
00044   head_ = tail_ = 0;
00045   len_ = 0;
00046   limit_ = AODV_RTQ_MAX_LEN;
00047   timeout_ = AODV_RTQ_TIMEOUT;
00048 }
00049 
00050 void
00051 aodv_rqueue::enque(Packet *p) {
00052 struct hdr_cmn *ch = HDR_CMN(p);
00053 
00054  /*
00055   * Purge any packets that have timed out.
00056   */
00057  purge();
00058  
00059  p->next_ = 0;
00060  ch->ts_ = CURRENT_TIME + timeout_;
00061 
00062  if (len_ == limit_) {
00063  Packet *p0 = remove_head();    // decrements len_
00064 
00065    assert(p0);
00066    if(HDR_CMN(p0)->ts_ > CURRENT_TIME) {
00067      drop(p0, DROP_RTR_QFULL);
00068    }
00069    else {
00070      drop(p0, DROP_RTR_QTIMEOUT);
00071    }
00072  }
00073  
00074  if(head_ == 0) {
00075    head_ = tail_ = p;
00076  }
00077  else {
00078    tail_->next_ = p;
00079    tail_ = p;
00080  }
00081  len_++;
00082 #ifdef QDEBUG
00083    verifyQueue();
00084 #endif // QDEBUG
00085 }
00086                 
00087 
00088 Packet*
00089 aodv_rqueue::deque() {
00090 Packet *p;
00091 
00092  /*
00093   * Purge any packets that have timed out.
00094   */
00095  purge();
00096 
00097  p = remove_head();
00098 #ifdef QDEBUG
00099  verifyQueue();
00100 #endif // QDEBUG
00101  return p;
00102 
00103 }
00104 
00105 
00106 Packet*
00107 aodv_rqueue::deque(nsaddr_t dst) {
00108 Packet *p, *prev;
00109 
00110  /*
00111   * Purge any packets that have timed out.
00112   */
00113  purge();
00114 
00115  findPacketWithDst(dst, p, prev);
00116  assert(p == 0 || (p == head_ && prev == 0) || (prev->next_ == p));
00117 
00118  if(p == 0) return 0;
00119 
00120  if (p == head_) {
00121    p = remove_head();
00122  }
00123  else if (p == tail_) {
00124    prev->next_ = 0;
00125    tail_ = prev;
00126    len_--;
00127  }
00128  else {
00129    prev->next_ = p->next_;
00130    len_--;
00131  }
00132 
00133 #ifdef QDEBUG
00134  verifyQueue();
00135 #endif // QDEBUG
00136  return p;
00137 
00138 }
00139 
00140 char 
00141 aodv_rqueue::find(nsaddr_t dst) {
00142 Packet *p, *prev;  
00143     
00144  findPacketWithDst(dst, p, prev);
00145  if (0 == p)
00146    return 0;
00147  else
00148    return 1;
00149 
00150 }
00151 
00152     
00153     
00154 
00155 /*
00156   Private Routines
00157 */
00158 
00159 Packet*
00160 aodv_rqueue::remove_head() {
00161 Packet *p = head_;
00162         
00163  if(head_ == tail_) {
00164    head_ = tail_ = 0;
00165  }
00166  else {
00167    head_ = head_->next_;
00168  }
00169 
00170  if(p) len_--;
00171 
00172  return p;
00173 
00174 }
00175 
00176 void
00177 aodv_rqueue::findPacketWithDst(nsaddr_t dst, Packet*& p, Packet*& prev) {
00178   
00179   p = prev = 0;
00180   for(p = head_; p; p = p->next_) {
00181       //        if(HDR_IP(p)->dst() == dst) {
00182            if(HDR_IP(p)->daddr() == dst) {
00183       return;
00184     }
00185     prev = p;
00186   }
00187 }
00188 
00189 
00190 void
00191 aodv_rqueue::verifyQueue() {
00192 Packet *p, *prev = 0;
00193 int cnt = 0;
00194 
00195  for(p = head_; p; p = p->next_) {
00196    cnt++;
00197    prev = p;
00198  }
00199  assert(cnt == len_);
00200  assert(prev == tail_);
00201 
00202 }
00203 
00204 
00205 /*
00206 void
00207 aodv_rqueue::purge() {
00208 Packet *p;
00209 
00210  while((p = head_) && HDR_CMN(p)->ts_ < CURRENT_TIME) {
00211    // assert(p == remove_head());     
00212    p = remove_head();     
00213    drop(p, DROP_RTR_QTIMEOUT);
00214  }
00215 
00216 }
00217 */
00218 
00219 bool
00220 aodv_rqueue::findAgedPacket(Packet*& p, Packet*& prev) {
00221   
00222   p = prev = 0;
00223   for(p = head_; p; p = p->next_) {
00224     if(HDR_CMN(p)->ts_ < CURRENT_TIME) {
00225       return true;
00226     }
00227     prev = p;
00228   }
00229   return false;
00230 }
00231 
00232 void
00233 aodv_rqueue::purge() {
00234 Packet *p, *prev;
00235 
00236  while ( findAgedPacket(p, prev) ) {
00237     assert(p == 0 || (p == head_ && prev == 0) || (prev->next_ == p));
00238 
00239     if(p == 0) return;
00240 
00241     if (p == head_) {
00242         p = remove_head();
00243     }
00244     else if (p == tail_) {
00245         prev->next_ = 0;
00246         tail_ = prev;
00247         len_--;
00248     }
00249     else {
00250         prev->next_ = p->next_;
00251         len_--;
00252     }
00253 #ifdef QDEBUG
00254     verifyQueue();
00255 #endif // QDEBUG
00256 
00257     p = prev = 0;
00258  }
00259 
00260 }
00261 

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