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
00032
00033 #include <assert.h>
00034
00035 #include <cmu-trace.h>
00036 #include <aodv/aodv_rqueue.h>
00037
00038 #define CURRENT_TIME Scheduler::instance().clock()
00039 #define QDEBUG
00040
00041
00042
00043
00044
00045 aodv_rqueue::aodv_rqueue() {
00046 head_ = tail_ = 0;
00047 len_ = 0;
00048 limit_ = AODV_RTQ_MAX_LEN;
00049 timeout_ = AODV_RTQ_TIMEOUT;
00050 }
00051
00052 void
00053 aodv_rqueue::enque(Packet *p) {
00054 struct hdr_cmn *ch = HDR_CMN(p);
00055
00056
00057
00058
00059 purge();
00060
00061 p->next_ = 0;
00062 ch->ts_ = CURRENT_TIME + timeout_;
00063
00064 if (len_ == limit_) {
00065 Packet *p0 = remove_head();
00066
00067 assert(p0);
00068 if(HDR_CMN(p0)->ts_ > CURRENT_TIME) {
00069 drop(p0, DROP_RTR_QFULL);
00070 }
00071 else {
00072 drop(p0, DROP_RTR_QTIMEOUT);
00073 }
00074 }
00075
00076 if(head_ == 0) {
00077 head_ = tail_ = p;
00078 }
00079 else {
00080 tail_->next_ = p;
00081 tail_ = p;
00082 }
00083 len_++;
00084 #ifdef QDEBUG
00085 verifyQueue();
00086 #endif // QDEBUG
00087 }
00088
00089
00090 Packet*
00091 aodv_rqueue::deque() {
00092 Packet *p;
00093
00094
00095
00096
00097 purge();
00098
00099 p = remove_head();
00100 #ifdef QDEBUG
00101 verifyQueue();
00102 #endif // QDEBUG
00103 return p;
00104
00105 }
00106
00107
00108 Packet*
00109 aodv_rqueue::deque(nsaddr_t dst) {
00110 Packet *p, *prev;
00111
00112
00113
00114
00115 purge();
00116
00117 findPacketWithDst(dst, p, prev);
00118 assert(p == 0 || (p == head_ && prev == 0) || (prev->next_ == p));
00119
00120 if(p == 0) return 0;
00121
00122 if (p == head_) {
00123 p = remove_head();
00124 }
00125 else if (p == tail_) {
00126 prev->next_ = 0;
00127 tail_ = prev;
00128 len_--;
00129 }
00130 else {
00131 prev->next_ = p->next_;
00132 len_--;
00133 }
00134
00135 #ifdef QDEBUG
00136 verifyQueue();
00137 #endif // QDEBUG
00138 return p;
00139
00140 }
00141
00142 char
00143 aodv_rqueue::find(nsaddr_t dst) {
00144 Packet *p, *prev;
00145
00146 findPacketWithDst(dst, p, prev);
00147 if (0 == p)
00148 return 0;
00149 else
00150 return 1;
00151
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161 Packet*
00162 aodv_rqueue::remove_head() {
00163 Packet *p = head_;
00164
00165 if(head_ == tail_) {
00166 head_ = tail_ = 0;
00167 }
00168 else {
00169 head_ = head_->next_;
00170 }
00171
00172 if(p) len_--;
00173
00174 return p;
00175
00176 }
00177
00178 void
00179 aodv_rqueue::findPacketWithDst(nsaddr_t dst, Packet*& p, Packet*& prev) {
00180
00181 p = prev = 0;
00182 for(p = head_; p; p = p->next_) {
00183
00184 if(HDR_IP(p)->daddr() == dst) {
00185 return;
00186 }
00187 prev = p;
00188 }
00189 }
00190
00191
00192 void
00193 aodv_rqueue::verifyQueue() {
00194 Packet *p, *prev = 0;
00195 int cnt = 0;
00196
00197 for(p = head_; p; p = p->next_) {
00198 cnt++;
00199 prev = p;
00200 }
00201 assert(cnt == len_);
00202 assert(prev == tail_);
00203
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 bool
00222 aodv_rqueue::findAgedPacket(Packet*& p, Packet*& prev) {
00223
00224 p = prev = 0;
00225 for(p = head_; p; p = p->next_) {
00226 if(HDR_CMN(p)->ts_ < CURRENT_TIME) {
00227 return true;
00228 }
00229 prev = p;
00230 }
00231 return false;
00232 }
00233
00234 void
00235 aodv_rqueue::purge() {
00236 Packet *p, *prev;
00237
00238 while ( findAgedPacket(p, prev) ) {
00239 assert(p == 0 || (p == head_ && prev == 0) || (prev->next_ == p));
00240
00241 if(p == 0) return;
00242
00243 if (p == head_) {
00244 p = remove_head();
00245 }
00246 else if (p == tail_) {
00247 prev->next_ = 0;
00248 tail_ = prev;
00249 len_--;
00250 }
00251 else {
00252 prev->next_ = p->next_;
00253 len_--;
00254 }
00255 #ifdef QDEBUG
00256 verifyQueue();
00257 #endif // QDEBUG
00258
00259 p = prev = 0;
00260 }
00261
00262 }
00263