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 #include "simlpy/interpreter_defs.h"
00032 #include "simlpy/interpreter_hooks.h"
00033
00034 #include <iostream>
00035 #include <math.h>
00036
00037 #include "Globals.h"
00038 #include "SimLink.h"
00039 #include "WrapLink.h"
00040 #include "WrapNode.h"
00041 #include "BundleEvent.h"
00042 #include "LinkAvailEvent.h"
00043
00044 #include "simlpy/Clock.h"
00045 #include "simlpy/SimulationException.h"
00046
00047 SimLink::SimLink( WrapLink* owner, bool up ) :
00048 m_owner( owner ),
00049 m_latency( Globals::latency() ),
00050 m_bandwidth( Globals::bandwidth() ),
00051 m_busy( false ),
00052 m_up( up )
00053 {
00054 if ( m_up )
00055 {
00056 m_upSince = Clock::time();
00057 }
00058 }
00059
00060 SimLink::~SimLink()
00061 {
00062
00063 }
00064
00065 void
00066 SimLink::send( DTN::Bundle* b )
00067 {
00068 if ( 0 == b ) return;
00069 if ( ! m_up )
00070 {
00071
00072 return;
00073 }
00074
00075 if ( m_busy )
00076 {
00077
00078 std::cerr << "We shouldn't be here!" << std::endl;
00079 return;
00080 }
00081
00082
00083 Time arrival_time = Clock::time() + m_latency;
00084
00085
00086 if ( arrival_time < m_earliestDelivery )
00087 {
00088 arrival_time = m_earliestDelivery;
00089 }
00090
00091
00092 unsigned int length = b->size();
00093
00094
00095 unsigned long int injection_time =
00096 (unsigned long int)( ceil( 1.0 * 1000000 * 8 * length / m_bandwidth ) );
00097
00098
00099
00100 Time t = arrival_time + Time(0,injection_time);
00101
00102
00103 Time t0 = t - m_latency;
00104
00105
00106 m_earliestDelivery = t;
00107
00108 BundleEvent* evt = new BundleEvent( m_owner, m_owner, Clock::time(), t, b );
00109 if ( 0 == evt )
00110 {
00111 std::cerr << "Could not allocate a new BundleEvent" << std::endl;
00112 throw SimulationException( __FILE__ , __LINE__ );
00113 }
00114
00115 m_busy = true;
00116 m_busyUntil = t0;
00117 Clock::schedule( evt );
00118 Clock::schedule( new LinkAvailEvent( m_owner, m_owner, t0 ) );
00119 }
00120
00121 const DTN::ByteString&
00122 SimLink::remoteAddr() const
00123 {
00124 if ( 0 == m_owner )
00125 {
00126 throw SimulationException( __FILE__ , __LINE__ );
00127 }
00128 if ( 0 == m_owner->destination() )
00129 {
00130 throw SimulationException( __FILE__ , __LINE__ );
00131 }
00132 return m_owner->destination()->addr();
00133 }
00134
00135 void
00136 SimLink::setLatency( double lat )
00137 {
00138 unsigned long int s = ::floor(lat);
00139 unsigned long int us = Time::MILLION * ( lat - s );
00140 m_latency = Time(s,us);
00141 }
00142
00143 void
00144 SimLink::setUp()
00145 {
00146 if ( ! m_up )
00147 {
00148 m_upSince = Clock::time();
00149 }
00150 m_up = true;
00151 if ( 0 == m_owner ) return;
00152
00153 if ( ! m_busy )
00154 {
00155 m_owner->source()->forwardOn( *this );
00156 }
00157 }
00158
00159 void
00160 SimLink::setDown()
00161 {
00162 m_up = false;
00163 }