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 "EpidemicApp.h" 00035 00036 #include "mobility/MobileNode.h" 00037 #include "mobility/WirelessLink.h" 00038 #include "dtn/SpaceAvailCustody.h" 00039 #include "pydtn/parsers.h" 00040 #include "mobility/parsers.h" 00041 #include "simlpy/Clock.h" 00042 00049 #ifndef PyMODINIT_FUNC 00052 #define PyMODINIT_FUNC extern "C" void 00053 #endif 00054 00055 00056 //====================================================================== 00057 // Methods callable from python 00058 // ---------------------------- 00059 // 00060 // There's only one method to call from python, attach(). We define 00061 // two things here related to this method. First, we define a 00062 // documentation string, called epidemic_attach_doc. This is what 00063 // will be displayed when we type "help(attach)" at the interactive 00064 // prompt. 00065 // 00066 // The second thing we define is the actual C++ function that will be 00067 // called when we invoke attach() in python. The function's name is 00068 // epidemic_attach. 00069 // 00070 // Using these two definitions, we then create the structure that will 00071 // bind the C++ function and docstring to the python function name. 00072 //====================================================================== 00073 00074 00078 static char epidemic_attach_doc[] = "Add an application instance to a node.\n\ 00079 \n\ 00080 Calling syntax:\n\ 00081 \n\ 00082 pydtn.mobility.basicepidemic.attach(<n>,<l>)\n\ 00083 \n\ 00084 <n> is a mobile node to which we want to add an instance.\n\ 00085 <l> is the wireless link for the node.\n\ 00086 \n\ 00087 In general, this will be called automatically at node creation by\n\ 00088 pydtn.mobility.node()\n"; 00089 00100 static PyObject* 00101 epidemic_attach( PyObject* self, PyObject* args ) 00102 { 00103 // Check the arguments. The first check is guaranteed to succeed 00104 // if we've registered the method correctly with METH_VARARGS. 00105 if ( ! PyTuple_Check( args ) ) 00106 { 00107 PyErr_SetString(PyExc_TypeError,"attach expects a list of arguments"); 00108 return 0; 00109 } 00110 if ( PyTuple_Size( args ) < 2 ) 00111 { 00112 PyErr_SetString(PyExc_TypeError, 00113 "attach expects two arguments"); 00114 return 0; 00115 } 00116 00117 // The arguments should be a tuple of the form (node,link). We 00118 // could have used build_arglist() and clean_arglist() from 00119 // simlpy/interpreter_hooks.h here. This lower-level interface 00120 // requires no management of reference counts. 00121 Mobility::MobileNode* mn = Mobility::parse_mn( PyTuple_GetItem(args,0) ); 00122 if ( 0 == mn ) return 0; 00123 00124 Mobility::WirelessLink* wl = Mobility::parse_wl( PyTuple_GetItem(args,1) ); 00125 if ( 0 == wl ) return 0; 00126 00127 // Construct the protocol instance, which is initialized with the 00128 // wireless link and the default bundle lifetime. 00129 BasicEpidemic::EpidemicApp* ma = 00130 new BasicEpidemic::EpidemicApp( mn, 00131 &(wl->link()), 00132 mn->bundleLifetime().tv ); 00133 00134 // Attach the protocol to the mobile node. This will also set the 00135 // forwarding policy, when the node reciprocally sets itself as the 00136 // protocol's owner. 00137 mn->addMobileApp(ma); 00138 00139 // Make sure there's a custody policy registered with the node. 00140 if ( ! mn->node().hasCustodyPolicy() ) 00141 { 00142 // Use SpaceAvailCustody as a default, if nothing has been configured. 00143 mn->node().setCustodyPolicy( new DTN::SpaceAvailCustody(&(mn->node())) ); 00144 } 00145 00146 // We're not returning anything meaningful, but we have to return 00147 // something, so we use the python None object. It's a 00148 // pre-existing object, so we don't have to create it, but we do 00149 // need to tell python that there's another reference to it now. 00150 Py_INCREF(Py_None); 00151 return Py_None; 00152 } 00153 00156 static PyMethodDef ExampleMethods[] = 00157 { 00158 {"attach",epidemic_attach,METH_VARARGS,epidemic_attach_doc}, 00159 {0,0,0,0} // sentinel 00160 }; 00161 00163 PyMODINIT_FUNC 00164 init_basicepidemic(void) 00165 { 00166 (void) Py_InitModule("_basicepidemic",ExampleMethods); 00167 } 00168
1.5.4