state.c

00001 /* Copyright 2008 Michael Marsh, University of Maryland.
00002  *
00003  * This file is part of pydtn.
00004  *
00005  * pydtn is free software: you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation, either version 3 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * pydtn is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with pydtn.  If not, see <http://www.gnu.org/licenses/>.
00017  *
00018  * The views and conclusions contained in the software and documentation
00019  * are those of the authors and should not be interpreted as representing
00020  * official policies, either expressed or implied, of the University
00021  * of Maryland.
00022  *
00023  * pydtn extends and embeds the Python interpreter, which is
00024  * Copyright 2001-2006 Python Software Foundation, All Rights Reserved,
00025  * and is released under the PSF License Agreement.
00026  *
00027  * RANLUX random number generation uses the Boost library,
00028  * Copyright 1994-2006 by various authors (details in individual files),
00029  * which is released under the Boost Software License, Version 1.0.
00030  */
00031 
00032 #include "aodv.h"
00033 
00034 /*
00035  * This routine allocates a new state structure and performs most of
00036  * the necessary initialization.  Once the parameters have been set
00037  * correctly (including a call to recompute_aodv_params if any have
00038  * been changed), configure_aodv_state should be called to complete
00039  * the initialization.
00040  */
00041 aodv_state_t*
00042 new_aodv_state( const aodv_addr_t* self, uint16_t prefix )
00043 {
00044    aodv_state_t* state = NULL;
00045    state = (aodv_state_t*) malloc( sizeof(aodv_state_t) );
00046    if ( NULL == state )
00047    {
00048       return NULL;
00049    }
00050    init_aodv_state( state, self, prefix );
00051 
00052    return state;
00053 }
00054 
00055 /*
00056  * This routine performs the necessary initialization of an allocate
00057  * state structure.  Once the parameters have been set correctly
00058  * (including a call to recompute_aodv_params if any have been
00059  * changed), configure_aodv_state should be called to complete the
00060  * initialization.
00061  */
00062 void
00063 init_aodv_state( aodv_state_t* state,
00064                  const aodv_addr_t* self,
00065                  uint16_t prefix )
00066 {
00067    if ( NULL == state )
00068    {
00069       return;
00070    }
00071    state->self.data = NULL;
00072    state->self.length = 0U;
00073    set_aodv_addr( &(state->self), self );
00074    state->subnet_size = prefix;
00075    state->sequence_number = 1;
00076    state->rreq_id = 0;
00077    state->rreq_buffer = NULL;
00078    state->rcvd_rreq_buffer = NULL;
00079    state->rreq_time_ring = NULL;
00080    state->rerr_time_ring = NULL;
00081    state->use_acks = 0;
00082    state->interfaces.interfaces = NULL;
00083    state->interfaces.nifaces = 0;
00084    state->interfaces.lifaces = 0;
00085    state->routing_table.head = NULL;
00086    set_aodv_param_defaults( state );
00087 }
00088 
00089 /*
00090  * Most of the initialization should have been done before this is
00091  * called.  All this routine does is to set up the circular buffers
00092  * that control the rate with which RREQ and RERR messages are
00093  * generated.
00094  */
00095 void
00096 configure_aodv_state( aodv_state_t* state )
00097 {
00098    if ( NULL != state->rreq_time_ring )
00099    {
00100       free_aodv_time_ring( state->rreq_time_ring );
00101    }
00102    state->rreq_time_ring =
00103       (aodv_time_ring_t*) malloc( sizeof(aodv_time_ring_t) );
00104    if ( NULL == state->rreq_time_ring ) return;
00105    aodv_initialize_time_ring( state->rreq_time_ring,
00106                               state->params.rreq_ratelimit );
00107 
00108    if ( NULL != state->rerr_time_ring )
00109    {
00110       free_aodv_time_ring( state->rerr_time_ring );
00111    }
00112    state->rerr_time_ring =
00113       (aodv_time_ring_t*) malloc( sizeof(aodv_time_ring_t) );
00114    if ( NULL == state->rerr_time_ring ) return;
00115    aodv_initialize_time_ring( state->rerr_time_ring,
00116                               state->params.rerr_ratelimit );
00117 }
00118 
00119 static void
00120 _free_rreq_buffer( aodv_rreq_t* buffer )
00121 {
00122    aodv_rreq_t* curr;
00123    aodv_rreq_t* next;
00124 
00125    if ( NULL == buffer ) return;
00126 
00127    curr = buffer;
00128    do
00129    {
00130       next = curr->next;
00131       free_aodv_rreq( curr );
00132       curr = next;
00133    } while ( curr != buffer );
00134 }
00135 
00136 void
00137 free_aodv_state( aodv_state_t* state )
00138 {
00139    if ( NULL == state ) return;
00140    clear_aodv_state( state );
00141    free(state);
00142 }
00143 
00144 void
00145 clear_aodv_state( aodv_state_t* state )
00146 {
00147    if ( NULL == state ) return;
00148    _free_rreq_buffer( state->rreq_buffer );
00149    _free_rreq_buffer( state->rcvd_rreq_buffer );
00150 
00151    free_aodv_time_ring( state->rreq_time_ring );
00152    free_aodv_time_ring( state->rerr_time_ring );
00153 
00154    if ( NULL != state->interfaces.interfaces )
00155    {
00156       free( state->interfaces.interfaces );
00157    }
00158 
00159    clear_aodv_routing_table( &(state->routing_table) );
00160 }

Generated on Mon Mar 24 11:15:45 2008 for Pydtn Simulator by  doxygen 1.5.4