python_init.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 "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          // convert from KB to B
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          // convert from KB to B
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          // convert from Mbps to bps
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; // 10ms default
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 ); // This lets us use operator==.
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} // sentinel
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 

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