DFPolicy.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 "DFPolicy.h"
00032 #include "DFApp.h"
00033 #include "dtn/Bundle.h"
00034 #include "dtn/Node.h"
00035 
00036 using namespace DifferentialForwarding;
00037 
00038 DFPolicy::DFPolicy( DTN::Node* owner, DTN::Link* link, DFApp* app ) :
00039    DTN::ForwardingPolicy( owner ),
00040    m_link( link ),
00041    m_app( app )
00042 {
00043 }
00044 
00045 DFPolicy::~DFPolicy()
00046 {
00047 }
00048 
00049 bool
00050 DFPolicy::forward( DTN::Bundle* b )
00051 {
00052    if ( 0 == m_owner ) return false;
00053    if ( 0 == m_link ) return false;
00054    if ( 0 == m_app ) return false;
00055    if ( 0 == b ) return false;
00056 
00057    // broadcasts and acknowledgments get sent as long as the link is
00058    // available
00059    if ( ( DTN::Bundle::kBcast & b->type() ) ||
00060         ( DTN::Bundle::kACK & b->type() ) )
00061    {
00062       if ( m_link->available() )
00063       {
00064          m_owner->send( b, *m_link );
00065          return true;
00066       }
00067       return false;
00068    }
00069 
00070    // everything else requires a downhill connection
00071    DTN::Link* dl = m_app->linked( b->destination() );
00072    if ( 0 == dl ) return false;
00073    if ( m_link->available() )
00074    {
00075       m_owner->send( b, *dl );
00076       return true;
00077    }
00078 
00079    return false;
00080 }
00081 
00082 DTN::Bundle*
00083 DFPolicy::forwardOn( const DTN::Link& l )
00084 {
00085    if ( 0 == m_owner ) return 0;
00086    if ( 0 == m_link ) return 0;
00087    if ( 0 == m_app ) return 0;
00088 
00089    DTN::BundlePointer firstFallback;
00090    DTN::BundlePointer p = m_owner->cachedVolatile();
00091 
00092    // Look for a sendable bundle.  Also, keep track of the first
00093    // broadcast or ACK we see, since that will be sent as a fallback
00094    // if nothing else could be.
00095    while ( ! p.isNull() )
00096    {
00097       DTN::Bundle* b = p.repr()->bundle();
00098       if ( 0 != m_app->linked( b->destination() ) )
00099       {
00100          m_owner->remove(b,false);
00101          return b;
00102       }
00103       if ( firstFallback.isNull() )
00104       {
00105          if ( ( DTN::Bundle::kBcast & b->type() ) ||
00106               ( DTN::Bundle::kACK & b->type() ) )
00107          {
00108             firstFallback = p;
00109          }
00110       }
00111       p = p.next();
00112    }
00113 
00114    // At this point, we weren't able to send anything, so check the
00115    // fallback.
00116    if ( ! firstFallback.isNull() )
00117    {
00118       DTN::Bundle* b = firstFallback.repr()->bundle();
00119       m_owner->remove(b,false);
00120       return b;
00121    }
00122 
00123    // We have nothing that we're able to send.
00124    return 0;
00125 }

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