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 #include "aodv.h"
00033
00034 static void
00035 _buffer_rreq_base( aodv_rreq_t** buffer,
00036 aodv_rreq_t* rreq,
00037 unsigned int timeout )
00038 {
00039 aodv_rreq_t* head = NULL;
00040 aodv_rreq_t* tail = NULL;
00041 struct timeval* tv = NULL;
00042
00043 if ( NULL == buffer ) return;
00044 if ( NULL == rreq ) return;
00045
00046 if ( NULL == *buffer )
00047 {
00048 rreq->next = rreq;
00049 rreq->prev = rreq;
00050 *buffer = rreq;
00051 }
00052 else
00053 {
00054 head = *buffer;
00055 tail = head->prev;
00056 rreq->next = head;
00057 rreq->prev = tail;
00058 tail->next = rreq;
00059 head->prev = rreq;
00060 }
00061
00062 tv = &(rreq->buffer_time);
00063 aodv_gettime(tv);
00064 tv->tv_usec += 1000 * timeout;
00065 while ( tv->tv_usec >= 1000000 )
00066 {
00067 tv->tv_usec -= 1000000;
00068 tv->tv_sec += 1;
00069 }
00070 rreq->ntries = 1;
00071 }
00072
00073 void
00074 buffer_aodv_rreq( aodv_state_t* state, aodv_rreq_t* rreq )
00075 {
00076 _buffer_rreq_base( &(state->rreq_buffer),
00077 rreq,
00078 state->params.net_traversal_time );
00079 }
00080
00081 void
00082 buffer_rcvd_aodv_rreq( aodv_state_t* state, aodv_rreq_t* rreq )
00083 {
00084 _buffer_rreq_base( &(state->rcvd_rreq_buffer),
00085 rreq,
00086 state->params.path_discovery_time );
00087 }
00088
00089
00090 static aodv_rreq_t*
00091 _unbuffer_rreq_base( aodv_rreq_t** buffer, aodv_rreq_t* rreq )
00092 {
00093 aodv_rreq_t* head;
00094 aodv_rreq_t* tail;
00095 aodv_rreq_t* retval = NULL;
00096 char is_head = 0;
00097 char is_tail = 0;
00098
00099 if ( NULL == buffer ) return NULL;
00100 if ( NULL == *buffer ) return NULL;
00101 if ( NULL == rreq ) return NULL;
00102
00103 head = *buffer;
00104 tail = head->prev;
00105
00106 if ( rreq == head ) is_head = 1;
00107 if ( rreq == tail ) is_tail = 1;
00108
00109 if ( is_head && is_tail )
00110 {
00111 retval = NULL;
00112 *buffer = NULL;
00113 }
00114 else if ( is_head )
00115 {
00116 retval = rreq->next;
00117 *buffer = retval;
00118 retval->prev = tail;
00119 tail->next = retval;
00120 }
00121 else if ( is_tail )
00122 {
00123 retval = tail->prev;
00124 head->prev = tail->prev;
00125 tail->prev->next = head;
00126 }
00127 else
00128 {
00129 retval = rreq->next;
00130 rreq->prev->next = rreq->next;
00131 rreq->next->prev = rreq->prev;
00132 }
00133
00134 free_aodv_rreq( rreq );
00135
00136 return retval;
00137 }
00138
00139 aodv_rreq_t*
00140 unbuffer_aodv_rreq( aodv_state_t* state, aodv_rreq_t* rreq )
00141 {
00142 if ( NULL == state ) return NULL;
00143 if ( NULL == state->rreq_buffer ) return NULL;
00144 if ( NULL == rreq ) return NULL;
00145
00146 return _unbuffer_rreq_base( &(state->rreq_buffer), rreq );
00147 }
00148
00149 aodv_rreq_t*
00150 unbuffer_rcvd_aodv_rreq( aodv_state_t* state, aodv_rreq_t* rreq )
00151 {
00152 if ( NULL == state ) return NULL;
00153 if ( NULL == state->rcvd_rreq_buffer ) return NULL;
00154 if ( NULL == rreq ) return NULL;
00155
00156 return _unbuffer_rreq_base( &(state->rcvd_rreq_buffer), rreq );
00157 }
00158
00159
00160
00161
00162
00163
00164
00165 static int
00166 _is_buffered_rreq_base( aodv_rreq_t** buffer, const aodv_rreq_t* rreq )
00167 {
00168 aodv_rreq_t* head;
00169 aodv_rreq_t* curr;
00170 int retval = 0;
00171
00172 if ( NULL == buffer ) return 0;
00173 if ( NULL == *buffer ) return 0;
00174 if ( NULL == rreq ) return 0;
00175
00176 head = *buffer;
00177 curr = head;
00178 do
00179 {
00180 if ( aodv_pasttime( &(curr->buffer_time) ) )
00181 {
00182 curr = _unbuffer_rreq_base( buffer, curr );
00183 head = *buffer;
00184 }
00185
00186 if ( NULL != curr )
00187 {
00188 if ( ( 0 == retval ) &&
00189 ( 0 == aodv_cmp_addr( &(curr->originator),
00190 &(rreq->originator) ) ) &&
00191 ( curr->rreq_id == rreq->rreq_id ) )
00192 {
00193 retval = 1;
00194 }
00195 curr = curr->next;
00196 }
00197 } while ( curr != head );
00198
00199 return retval;
00200 }
00201
00202 int
00203 is_buffered_aodv_rreq( aodv_state_t* state, aodv_rreq_t* rreq )
00204 {
00205 if ( NULL == state ) return 0;
00206 if ( NULL == state->rreq_buffer ) return 0;
00207 if ( NULL == rreq ) return 0;
00208
00209 return _is_buffered_rreq_base( &(state->rreq_buffer), rreq );
00210 }
00211
00212 int
00213 is_buffered_rcvd_aodv_rreq( aodv_state_t* state, aodv_rreq_t* rreq )
00214 {
00215 if ( NULL == state ) return 0;
00216 if ( NULL == state->rcvd_rreq_buffer ) return 0;
00217 if ( NULL == rreq ) return 0;
00218
00219 return _is_buffered_rreq_base( &(state->rcvd_rreq_buffer), rreq );
00220 }
00221
00222 aodv_rreq_t*
00223 find_buffered_aodv_rreq( aodv_state_t* state, const aodv_addr_t* dest )
00224 {
00225 aodv_rreq_t* head;
00226 aodv_rreq_t* curr;
00227
00228 if ( NULL == state ) return NULL;
00229 if ( NULL == state->rreq_buffer ) return NULL;
00230
00231 head = state->rreq_buffer;
00232 curr = head;
00233 do
00234 {
00235 if ( 0 == aodv_cmp_addr( &(curr->destination), dest ) ) return curr;
00236 curr = curr->next;
00237 } while ( curr != head );
00238 return NULL;
00239 }