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 "Globals.h"
00035 #include "WrapNode.h"
00036 #include "WrapLink.h"
00037 #include "ExplicitRoutingEntity.h"
00038 #include "PrefixRoutingEntity.h"
00039 #include "SpaceAvailEntity.h"
00040 #include "TrafficGenerator.h"
00041 #include "Tracer.h"
00042 #include "GlobalStatistics.h"
00043 #include "GStatDump.h"
00044 #include "GStatTrigger.h"
00045 #include "PydtnBundle.h"
00046 #include "PydtnApplication.h"
00047 #include "simlpy/Clock.h"
00048
00049 #include <iostream>
00050 #include <fstream>
00051
00057 #ifndef PyMODINIT_FUNC
00060 #define PyMODINIT_FUNC extern "C" void
00061 #endif
00062
00064 static GStatDump* gsd = 0;
00065
00069 static char dtn_config_doc[] = "Global DTN parameter configuration.\n\
00070 \n\
00071 Valid configurations are:\n\
00072 \n\
00073 pydtn.config('capacity',<size>)\n\
00074 Set the default volatile storage capacity to <size>.\n\
00075 (real-valued, in kibibytes)\n\
00076 \n\
00077 pydtn.config('stable_store',<size>)\n\
00078 Set the default persistent storage capacity to <size>.\n\
00079 (real-valued, in kibibytes)\n\
00080 \n\
00081 pydtn.config('bandwidth',<bw>)\n\
00082 Set the default link bandwidth to <bw>.\n\
00083 (real-valued, in Mbps).\n\
00084 \n\
00085 pydtn.config('latency',<t>)\n\
00086 Set the default link latency to <t>, given as [s,us]\n\
00087 (seconds, microseconds).\n\
00088 \n\
00089 pydtn.config('bundle_lifetime',<t>)\n\
00090 Set the default bundle lifetime to <t>, given as [s,us]\n\
00091 (seconds, microseconds).\n\
00092 \n\
00093 pydtn.config('resend_period',<t>)\n\
00094 Set the default bundle resending period to <t>, given as [s,us]\n\
00095 (seconds, microseconds).\n";
00096
00105 static PyObject*
00106 dtn_config( PyObject* self, PyObject* args )
00107 {
00108 Entity::ArgList argList;
00109 if ( ! PyTuple_Check( args ) )
00110 {
00111 PyErr_SetString(PyExc_TypeError,"config expects a list of arguments");
00112 return 0;
00113 }
00114 build_arglist( argList, args );
00115 unsigned int nargs = argList.size();
00116
00117 if ( nargs < 2 )
00118 {
00119 std::cerr << "config() takes at least 2 arguments ("
00120 << nargs << " given)"
00121 << std::endl;
00122 return 0;
00123 }
00124
00125 try
00126 {
00127 std::string command = parse_string(argList[0]);
00128 if ( "capacity" == command )
00129 {
00130 double dcap = parse_double( argList[1] );
00131
00132 size_t cap = (size_t)(1024 * dcap);
00133 Globals::setVolatileCap(cap);
00134 }
00135 else if ( "stable_store" == command )
00136 {
00137 double dcap = parse_double( argList[1] );
00138
00139 size_t cap = (size_t)(1024 * dcap);
00140 Globals::setPersistentCap(cap);
00141 }
00142 else if ( "bandwidth" == command )
00143 {
00144 double dbw = parse_double( argList[1] );
00145
00146 unsigned long int bw = (unsigned long int)(1000000 * dbw);
00147 Globals::setBandwidth( bw );
00148 }
00149 else if ( "latency" == command )
00150 {
00151 Globals::setLatency( parse_time(argList[1]) );
00152 }
00153 else if ( "bundle_lifetime" == command )
00154 {
00155 Globals::setBundleLifetime( parse_time(argList[1]) );
00156 }
00157 else if ( "resend_period" == command )
00158 {
00159 Globals::setResendPeriod( parse_time(argList[1]) );
00160 }
00161 else
00162 {
00163 std::cerr << "Unrecognized configuration option: " << command
00164 << std::endl;
00165 clean_arglist( argList );
00166 return 0;
00167 }
00168 }
00169 catch ( ... )
00170 {
00171 clean_arglist( argList );
00172 return 0;
00173 }
00174
00175 clean_arglist( argList );
00176 Py_INCREF(Py_None);
00177 return Py_None;
00178 }
00179
00183 static char dtn_trace_doc[] = "Enable global tracing.\n\
00184 \n\
00185 This function takes no arguments.\n\
00186 \n\
00187 In general, this shouldn't be needed, as an individual tracing\n\
00188 module should be able to initialize global tracing.\n";
00189
00200 static PyObject*
00201 dtn_trace( PyObject* self, PyObject* args )
00202 {
00203 GlobalTracer::enable();
00204 Py_INCREF(Py_None);
00205 return Py_None;
00206 }
00207
00211 static char dtn_stats_doc[] = "Enable global statistics aggregation.\n\
00212 \n\
00213 Statistics aggregation is done as bundles move through the system.\n\
00214 Information is periodically displayed summarizing data collected\n\
00215 since the last dump and data collected since the beginning of the\n\
00216 simulation.\n\
00217 \n\
00218 In addition, at the end of the simulation a final summary will be\n\
00219 displayed.\n\
00220 \n\
00221 Syntax:\n\
00222 \n\
00223 pydtn.stats(<fname>,<period>)\n\
00224 The parameter <fname> is the name of the file into which the\n\
00225 data should be dumped, or 'stdout' or 'stderr'.\n\
00226 \n\
00227 The parameter <period> is the delay (in microseconds) between\n\
00228 collections, and is optional. The default value is 10000 (10ms).\n\
00229 Alternately, a period of 0 will inhibit periodic statistical\n\
00230 dumps, and only the end-of-simulation display will occur.\n";
00231
00240 static PyObject*
00241 dtn_stats( PyObject* self, PyObject* args )
00242 {
00243 const char* fname;
00244 long int t = 10000;
00245 if ( ! PyArg_ParseTuple(args, "s|l", &fname, &t) )
00246 {
00247 std::cerr << "Incorrect argument list" << std::endl;
00248 return 0;
00249 }
00250 std::string fnstr( fname );
00251 GlobalStatistics* gs = GlobalStatistics::instance();
00252 if ( 0 == gs )
00253 {
00254 GlobalStatistics::enable();
00255 if ( 0 != gsd ) delete gsd;
00256 gsd = 0;
00257 if ( "stdout" == fnstr )
00258 {
00259 gsd = new GStatDump( std::cout, t );
00260 }
00261 else if ( "stderr" == fnstr )
00262 {
00263 gsd = new GStatDump( std::cerr, t );
00264 }
00265 else
00266 {
00267 gsd = new GStatDump( *(new std::ofstream(fname)), t );
00268 }
00269 if ( 0 != gsd )
00270 {
00271 if ( 0 != t )
00272 {
00273 Clock::schedule( new GStatTrigger( gsd, gsd, Clock::time() ) );
00274 }
00275 }
00276 }
00277
00278 Py_INCREF(Py_None);
00279 return Py_None;
00280 }
00281
00283 void
00284 pydtn_statdump()
00285 {
00286 if ( 0 == gsd ) return;
00287 GlobalStatistics* gs = GlobalStatistics::instance();
00288 if ( 0 == gs ) return;
00289 gsd->dump();
00290 }
00291
00294 static PyMethodDef ExampleMethods[] =
00295 {
00296 {"config",dtn_config,METH_VARARGS,dtn_config_doc},
00297 {"trace",dtn_trace,METH_VARARGS,dtn_trace_doc},
00298 {"stats",dtn_stats,METH_VARARGS,dtn_stats_doc},
00299 {0,0,0,0}
00300 };
00301
00305 PyMODINIT_FUNC
00306 init_pydtn(void)
00307 {
00308 add_entity( new WrapNode );
00309 add_entity( new WrapLink );
00310 add_entity( new ExplicitRoutingEntity );
00311 add_entity( new PrefixRoutingEntity );
00312 add_entity( new SpaceAvailEntity );
00313 add_entity( new TrafficGenerator );
00314 Py_AtExit(pydtn_statdump);
00315 PyObject* m = Py_InitModule("_pydtn",ExampleMethods);
00316 addType_PydtnBundle(m);
00317 addType_PydtnAppObject(m);
00318 }
00319