umts-queue.cc

00001 /*
00002  * Copyright (c) 2003 Ericsson Telecommunicatie B.V.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *     notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *     notice, this list of conditions and the following disclaimer in the
00012  *     documentation and/or other materials provided with the
00013  *     distribution.
00014  * 3. Neither the name of Ericsson Telecommunicatie B.V. may be used
00015  *     to endorse or promote products derived from this software without
00016  *     specific prior written permission.
00017  *
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY ERICSSON TELECOMMUNICATIE B.V. AND
00020  * CONTRIBUTORS "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES,
00021  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00022  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00023  * IN NO EVENT SHALL ERICSSON TELECOMMUNICATIE B.V., THE AUTHOR OR HIS
00024  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00026  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00028  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00030  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  *
00032  *
00033  * Contact for feedback on EURANE: eurane@ti-wmc.nl
00034  * EURANE = Enhanced UMTS Radio Access Network Extensions
00035  * website: http://www.ti-wmc.nl/eurane/
00036  */
00037 
00038 /*
00039  * $Id: umts-queue.cc,v 1.22 2004/02/20 11:31:09 simon Exp $
00040  */
00041 
00042 #include "umts-queue.h"
00043 #include <assert.h>
00044 #include<iostream>
00045 
00046 umtsQueue::umtsQueue():TclObject()
00047 {
00048    lastServedTime_ = 0.0;
00049    tx_seq_nr_ = 0;
00050    len_ = 0;
00051 }
00052 
00053 // Insert the packet in back of the queue
00054 void umtsQueue::enque(Packet * p)
00055 {
00056    if (q_.empty()) {
00057       lastServedTime_ = Scheduler::instance().clock();
00058    }
00059    q_.push_back(p);
00060    len_++;
00061 }
00062 
00063 // Insert the packet in front of the queue
00064 void umtsQueue::enqueUniqueFront(Packet * p)
00065 {
00066    int seqno = hdr_rlc::access(p)->seqno();
00067 
00068    //lastServedTime_ = Scheduler::instance().clock();
00069    for (unsigned int i = 0; i < q_.size(); i++) {
00070       int temp_seqno = hdr_rlc::access(q_.at(i))->seqno();
00071 
00072       if (temp_seqno == seqno) {
00073          return;
00074       }
00075    }
00076    q_.insert(q_.begin(), p);
00077    len_++;
00078 }
00079 
00080 // Insert the packet in front of the queue
00081 void umtsQueue::printQueue()
00082 {
00083    if (q_.size() > 0) {
00084       for (unsigned int i = 0; i < q_.size(); i++) {
00085          printf ("%d ", hdr_rlc::access(q_.at(i))->seqno() );
00086       }
00087       printf ("\n");
00088    }
00089 
00090 }
00091 
00092 // Insert the packet in sequence in the queue. If all the packets are inserted by
00093 // this method, the queue is ordered.
00094 void umtsQueue::orderedEnque(Packet * p)
00095 {
00096 
00097    if (q_.empty()) {
00098       lastServedTime_ = Scheduler::instance().clock();
00099 
00100    }
00101 
00102    int seqno = hdr_rlc::access(p)->seqno();
00103 
00104    for (unsigned int i = 0; i < q_.size(); i++) {
00105       if ((hdr_rlc::access(q_.at(i)))->seqno() > seqno) {
00106          q_.insert(q_.begin() + i, p);
00107          len_++;
00108          return;
00109       }
00110    }
00111    q_.push_back(p);
00112    len_++;
00113 }
00114 
00115 // Return the first packet from the queue, and remove the packet from the queue
00116 Packet     *umtsQueue::deque()
00117 {
00118    lastServedTime_ = Scheduler::instance().clock();
00119 
00120    if (q_.empty()) {
00121       return NULL;
00122    }
00123    Packet     *temp = q_.front();
00124 
00125    q_.erase(q_.begin());
00126    len_--;
00127    return temp;
00128 }
00129 
00130 // Return the last packet from the queue, and remove the packet from the queue
00131 Packet     *umtsQueue::dequeTail()
00132 {
00133    if (q_.size() == 1) {
00134       lastServedTime_ = Scheduler::instance().clock();
00135 
00136    }
00137    Packet     *temp = q_.back();
00138 
00139    q_.pop_back();
00140    len_--;
00141    return temp;
00142 }
00143 
00144 // Return a pointer to a copy of the first packet from the queue
00145 Packet     *umtsQueue::dequeCopy()
00146 {
00147    if (q_.empty()) {
00148       return NULL;
00149    }
00150    return q_.front()->copy();
00151 }
00152 
00153 // Return a pointer to a copy of the last packet from the queue
00154 Packet     *umtsQueue::dequeTailCopy()
00155 {
00156    if (q_.empty()) {
00157       return NULL;
00158    }
00159    return q_.back()->copy();
00160 }
00161 
00162 // Return the packet with a certain seqno from the queue, and remove the packet
00163 // from the queue
00164 Packet     *umtsQueue::deque(int seqno)
00165 {
00166    for (unsigned int i = 0; i < q_.size(); i++) {
00167       if ((hdr_rlc::access(q_.at(i)))->seqno() == seqno) {
00168          Packet     *temp = q_.at(i);
00169 
00170          q_.erase(q_.begin() + i);
00171          len_--;
00172          return temp;
00173       }
00174    }
00175    return NULL;
00176 }
00177 
00178 // Return a pointer to a copy of the packet with a certain seqno from the queue
00179 Packet     *umtsQueue::dequeCopy(int seqno)
00180 {
00181    for (unsigned int i = 0; i < q_.size(); i++) {
00182       if ((hdr_rlc::access(q_.at(i)))->seqno() == seqno) {
00183          return q_.at(i)->copy();
00184       }
00185    }
00186    return NULL;
00187 }
00188 
00189 // Returns the first packet with a seqno >= 0
00190 Packet     *umtsQueue::dequeFirstSendable()
00191 {
00192 
00193    unsigned int pos = 0;
00194 
00195    while (pos < q_.size() && ((hdr_rlc::access(q_.at(pos)))->seqno() < 0)) {
00196       pos++;
00197    }
00198    // pos is now the first packet with seqno >= 0, unless pos == q_.size
00199 
00200    Packet     *temp = NULL;
00201 
00202    if (pos < q_.size()) {
00203       temp = q_.at(pos);
00204       q_.erase(q_.begin() + pos);
00205       len_--;
00206    }
00207 
00208    return temp;
00209 }
00210 
00211 // Removes all packets with a seqno less to a certain seqno from the
00212 // queue and free the packets belonging to the queued pointers.
00213 void umtsQueue::dropTill(int seqno)
00214 {
00215    for (unsigned int i = 0; i < q_.size(); /* do nothing */ ) {
00216       // Do not drop sequence numbers lower than 0, because these have not been
00217       // set yet.
00218       if (((hdr_rlc::access(q_.at(i)))->seqno() < seqno)
00219           && ((hdr_rlc::access(q_.at(i)))->seqno() >= 0)) {
00220          assert(q_.at(i) != NULL);
00221          Packet::free(q_.at(i));
00222 
00223          q_.erase(q_.begin() + i);
00224          len_--;
00225       } else {
00226          i++;
00227       }
00228    }
00229 }
00230 
00231 void umtsQueue::updateLastServedTime()
00232 {
00233    lastServedTime_ = Scheduler::instance().clock();
00234 
00235 }
00236 
00237 // Returns the total size of all the packets in the queue, in bytes
00238 int umtsQueue::size()
00239 {
00240    int size = 0;
00241 
00242    for (unsigned int i = 0; i < q_.size(); i++) {
00243       size = size + hdr_cmn::access(q_.at(i))->size();
00244    }
00245    return size;
00246 }
00247 
00248 //returns packetsize of the first packet in the queue or at pos
00249 // returns -1 when nothing in the queue
00250 int umtsQueue::getPacketSize() {
00251    if (q_.empty()) {
00252       return -1;
00253    } else {
00254       return hdr_cmn::access(q_.front())->size();
00255    }
00256 }
00257 
00258 // Returns the size of the packet at a certain position in the queue, in bytes
00259 int umtsQueue::size(int position)
00260 {
00261    if (q_.size() < (unsigned) position) {
00262       return 0;
00263    }
00264    return hdr_cmn::access(q_.at(position - 1))->size();
00265 }
00266 
00267 // Returns the total size of all the packets in the queue, in bits
00268 int umtsQueue::sizeInBits()
00269 {
00270    return size() * 8;
00271 }
00272 
00273 // Returns the size of the packet at a certain position in the queue, in bits
00274 int umtsQueue::sizeInBits(int position)
00275 {
00276    return size(position) * 8;
00277 }
00278 
00279 // TODO: change code in am so this method can be deleted
00280 // Reduces the size of the first packet with a certain amount of bytes. This is
00281 // only done when the packet is large enough
00282 int umtsQueue::red_size(int bytes)
00283 {
00284    int size = (hdr_cmn::access(q_.at(0)))->size();
00285 
00286    if (q_.empty() || size <= bytes) {
00287       return -1;
00288    }
00289    (hdr_cmn::access(q_.at(0)))->size() = size - bytes;
00290    return size;
00291 }
00292 
00293 // Returns the number of packets in the queue
00294 int umtsQueue::length()
00295 {
00296    return q_.size();
00297 }
00298 
00299 
00300 // Dumps to stdout all sequence numbers in the queue:
00301 void umtsQueue::dump()
00302 {
00303   for (unsigned int i=0; i<q_.size(); i++)
00304     cout << " "<<  (hdr_rlc::access(q_.at(i)))->seqno() ;
00305   cout << endl;          
00306 }
00307 

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