00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
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
00056
00057 purge();
00058
00059 p->next_ = 0;
00060 ch->ts_ = CURRENT_TIME + timeout_;
00061
00062 if (len_ == limit_) {
00063 Packet *p0 = remove_head();
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
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
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
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
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
00207
00208
00209
00210
00211
00212
00213
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