AODVForwardingPolicy.cc

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 #include "config.h"
00032 
00033 #include "dtnaodv.h"
00034 #include "AODVForwardingPolicy.h"
00035 #include "AODVLink.h"
00036 #include "AODVApp.h"
00037 #include "dtn/Exception.h"
00038 #include "dtn/Bundle.h"
00039 #include "dtn/Node.h"
00040 #include "dtn/RoutingTable.h" // for DTN::NoRoute exception
00041 
00042 #include <iostream>
00043 
00044 AODVForwardingPolicy::AODVForwardingPolicy( DTN::Node* owner,
00045                                             uint16_t prefix ) :
00046    DTN::ForwardingPolicy( owner ),
00047    m_link(0)
00048 {
00049    if ( 0 == owner ) throw DTN::Exception( __FILE__ , __LINE__ );
00050 
00051    aodv_addr_t self;
00052    fill_addr( self, owner->addr() );
00053 
00054    init_aodv_state( &m_state, &self, prefix );
00055    configure_aodv_state( &m_state );
00056    aodv_add_interface( &m_state, 0 );
00057 }
00058 
00059 AODVForwardingPolicy::~AODVForwardingPolicy()
00060 {
00061    clear_aodv_state( &m_state );
00062 }
00063 
00064 void
00065 AODVForwardingPolicy::cache( DTN::BundlePointer& p )
00066 {
00067 }
00068 
00069 bool
00070 AODVForwardingPolicy::forward( DTN::Bundle* b )
00071 {
00072    if ( 0 == m_owner ) return false;
00073    if ( 0 == m_link ) return false;
00074    if ( 0 == b ) return false;
00075 
00076    // handle broadcasts first
00077    if ( DTN::Bundle::kBcast & b->type() )
00078    {
00079       if ( m_link->available() )
00080       {
00081          m_owner->send( b, *m_link );
00082          return true;
00083       }
00084       return false;
00085    }
00086 
00087    // lookup aodv route (might trigger RREQ)
00088    int e;
00089    aodv_addr_t src;
00090    fill_addr( src, b->source() );
00091    aodv_addr_t dest;
00092    fill_addr( dest, b->destination() );
00093    aodv_table_entry_t* r = aodv_get_route( &m_state,
00094                                            &src,
00095                                            &dest,
00096                                            &e );
00097    if ( 0 == r )
00098    {
00099       if ( AODV_GR_NOROUTE == e )
00100       {
00101          throw DTN::NoRoute( __FILE__ , __LINE__ );
00102       }
00103       return false;
00104    }
00105    // check link availability
00106    if ( m_link->available() )
00107    {
00108       // try to send (using a dummy link)
00109       AODVLink dl( r, m_link );
00110       m_owner->send( b, dl );
00111       return true;
00112    }
00113 
00114    return false;
00115 }
00116 
00117 DTN::Bundle*
00118 AODVForwardingPolicy::forwardOn( const DTN::Link& l )
00119 {
00120    if ( 0 == m_owner )
00121    {
00122       throw DTN::Exception( __FILE__ , __LINE__ );
00123    }
00124 
00125    DTN::BundlePointer p = m_owner->cachedVolatile();
00126    while ( ! p.isNull() )
00127    {
00128       DTN::Bundle* b = p.repr()->bundle();
00129       int e;
00130       aodv_addr_t src;
00131       fill_addr( src, b->source() );
00132       aodv_addr_t dest;
00133       fill_addr( dest, b->destination() );
00134       aodv_table_entry_t* r = aodv_get_route( &m_state,
00135                                               &src,
00136                                               &dest,
00137                                               &e );
00138       if ( 0 != r )
00139       {
00140          m_owner->remove(b,false);
00141          return b;
00142       }
00143       p = p.next();
00144    }
00145    return 0;
00146 }
00147 
00148 void
00149 AODVForwardingPolicy::handleMessage( const DTN::Bundle& b )
00150 {
00151    if ( 0 == m_owner ) return;
00152 
00153    aodv_msghdr_t headers;
00154    fill_addr( headers.addr, b.source() );
00155    headers.ttl = 2; // we're not really using this
00156    headers.interface = 0; // we're not really using this
00157 
00158    aodv_chunk_t message;
00159    const DTN::ByteString& data = b.payload();
00160    message.length = data.length();
00161    message.data = (unsigned char*)malloc(message.length*sizeof(unsigned char));
00162    message.next = 0;
00163    data.copy( message.data, message.length, 0 );
00164 
00165    aodv_handle_message(&m_state,&headers,&message);
00166 
00167    free(headers.addr.data);
00168    free(message.data);
00169 }
00170 
00171 unsigned int
00172 AODVForwardingPolicy::traversalTime() const
00173 {
00174    return m_state.params.net_traversal_time;
00175 }
00176 
00177 void
00178 AODVForwardingPolicy::addLink( DTN::Link* l )
00179 {
00180    if ( 0 != l )
00181    {
00182       m_link = l;
00183    }
00184 }
00185 
00186 void
00187 AODVForwardingPolicy::notify()
00188 {
00189    if ( 0 == m_owner ) return;
00190    if ( 0 == m_link ) return;
00191    if ( m_link->available() )
00192    {
00193       m_owner->forwardOn( *m_link );
00194    }
00195 }

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