Forwarding.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 "Forwarding.h"
00032 #include "Protocol.h"
00033 
00034 #include "dtn/Bundle.h"
00035 #include "dtn/Node.h"
00036 
00037 using namespace MobileForwarding;
00038 
00039 Forwarding::Forwarding( DTN::Node* owner, DTN::Link* link, Protocol* prot ):
00040    DTN::ForwardingPolicy(owner),
00041    m_link(link),
00042    m_prot(prot)
00043 {
00044 }
00045 
00046 Forwarding::~Forwarding()
00047 {
00048 }
00049 
00050 bool
00051 Forwarding::forward( DTN::Bundle* b )
00052 {
00053    if ( 0 == b ) return false;
00054    if ( 0 == m_owner ) return false;
00055    if ( 0 == m_link ) return false;
00056    if ( 0 == m_prot ) return false;
00057 
00058    // Let the protocol modify the bundle, if it needs to.
00059    m_prot->tweak(b);
00060 
00061    if ( m_link->available() )
00062    {
00063       try
00064       {
00065          if ( DTN::Bundle::kBcast & b->type() )
00066          {
00067             m_owner->send( b , *m_link );
00068             return true;
00069          }
00070          if ( m_prot->visible( b->recv() ) )
00071          {
00072             DTN::Link* l = m_prot->getLink( b->recv() );
00073             if ( 0 != l )
00074             {
00075                m_owner->send( b , *l );
00076                return true;
00077             }
00078          }
00079       }
00080       catch ( ... )
00081       {
00082       }
00083    }
00084 
00085    return false;
00086 }
00087 
00088 DTN::Bundle*
00089 Forwarding::forwardOn( const DTN::Link& l )
00090 {
00091    if ( 0 == m_owner ) return 0;
00092 
00093    DTN::Bundle* retval = 0;
00094 
00095    // We want to run the loop for *all* bundles, because this also
00096    // serves as a cleanup of the volatile store for (currently)
00097    // unroutable bundles.
00098    DTN::BundlePointer p = m_owner->cachedVolatile();
00099    DTN::BundlePointer prev;
00100    while ( ! p.isNull() )
00101    {
00102       DTN::Bundle* b = p.repr()->bundle();
00103       if ( ( !(DTN::Bundle::kBcast & b->type()) ) &&
00104            ( ( ! m_prot->visible( b->recv() ) ) ||
00105              ( 0 == m_prot->getLink( b->recv() ) ) ) )
00106       {
00107          m_owner->remove(b,true,DTN::NoRouteDrop::inst);
00108          p = prev;
00109       }
00110       else if ( 0 == retval )
00111       {
00112          retval = b;
00113       }
00114       prev = p;
00115       if ( p.isNull() )
00116       {
00117          p = m_owner->cachedVolatile();
00118       }
00119       else
00120       {
00121          p = p.next();
00122       }
00123    }
00124 
00125    if ( 0 != retval )
00126    {
00127       m_owner->remove(retval,false);
00128    }
00129    return retval;
00130 }

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