In this section we'll explain how to create a library from your own source code. After doing these steps you'll be able to load your modules, tracers, ecc. into simulation files.
What we have to do is create an automatic process to compile your source code, load default values and link them to the rest of simulator. All these parts will be encapsulated in the make command.
Suppose that the name of new library will be foo.
We will organize the new directory as follows:
You can find nsallinone.m4 file here: http://www.dei.unipd.it/baldo/nsallinone.m4. Put it in m4 subfolder.
Create a file named autogen.sh, put it in the main directory and make it executable. The content of this file must be:
#!/bin/sh aclocal -I m4 --force && libtoolize --force && automake --foreign --add-missing && autoconfremember to add the option
-I m4
, which forces the file to search informations into *.m4
files.
Now create a file named configure.ac and fill as follows:
AC_INIT(foo,1.0) AM_INIT_AUTOMAKE AC_PROG_CXX AC_PROG_MAKE_SET AC_DISABLE_STATIC AC_LIBTOOL_WIN32_DLL AC_PROG_LIBTOOL AC_PATH_NS_ALLINONE AC_DEFINE(CPP_NAMESPACE,std) AC_CONFIG_FILES([ Makefile src/Makefile m4/Makefile ]) AC_OUTPUT
Then create Makefile.am file as here:
SUBDIRS = src m4 EXTRA_DIST = autogen.sh nsallinone.m4 ACLOCAL_AMFLAGS = -I m4 DISTCHECK_CONFIGURE_FLAGS = @NS_ALLINONE_DISTCHECK_CONFIGURE_FLAGS@ lib_LTLIBRARIES = libfoo.la libfoo_la_SOURCES = foo.cc foo.h initlib.cc libfoo_la_CPPFLAGS = @NS_CPPFLAGS@ libfoo_la_LDFLAGS = @NS_LDFLAGS@ libfoo_la_LIBADD = @NS_LIBADD@ nodist_libfoo_la_SOURCES = initTcl.cc BUILT_SOURCES = initTcl.cc CLEANFILES = initTcl.cc TCL_FILES = foo-init.tcl initTcl.cc: Makefile $(TCL_FILES) cat $(TCL_FILES) | @TCL2CPP@ FooTclCode > initTcl.cc EXTRA_DIST = $(TCL_FILES)This file is very important, it has a lot of informations. In the first part, we instruct compiler about files and directories which are necessary to complete linkage between your library and the rest of simulator. In the second part you define the name of the library (libfoo.la) and you provide the list of source code files which constitute the library itself (foo.cc foo.h and initlib.cc). initlib.cc file is the file the simulator refers to when library is loaded. It provides the list of opearations to be executed when library is loaded as packet header creation, Tracers setup and ClMessages setup. FooTclCode is recalled in initlib.cc as we'll see afterwards.
There are also two more files: initTcl.cc and foo-init.tcl. The latter contains the default values of binded variables and eventually some Tcl procedures. The former is the transposition of the foo-init.tcl file into C strings and is automatically generated.
The last thing to define is the initlib.cc file structure. As we have just previously anticipated, this file has the structure presented in the following (remember that this is the minimum required to make library working, please refer to specific sections for code to insert to add a packet type or a tracer).
#include<tclcl.h> extern EmbeddedTcl FooTclCode; extern "C" int Foo_Init() { FooTclCode.load(); return 0; }Remember that the name of the C function has always the name of the library followed by
_Init()
. Then there must be a call to load()
function and to return
.
We reassume the corrispondence that MUST be respected when creating files descripted above:
what name | what file | where |
foo, lib. name | configure.ac | in AC_INIT |
Makefile.am | liblibname called 6 times | |
initTcl.cc | libname_Init() | |
FooTclCode | Makefile.am and initlib.cc | name corrispondence in both files |
initTcl.cc | Makefile.am | repeated 4 times |
autogen.sh | Makefile.am | called in EXTRA_DIST |
Notice that the times a name is repeated (referring to the table above) is just indicative for a tipical set of configuration files. So you can find variations from previous table even in full working files.
And finally there is list of commands to create your loadable library and put all pieces together:
user@pcsignet08:~/foo$ ./autogen.sh user@pcsignet08:~/foo$ ./configure --with-ns-allinone=/locale/ns/ns-allinone-2.33 --with-nsmiracle=<ns_folder_path>/ user@pcsignet08:~/foo$ make && make install
Refer to http://www.dei.unipd.it/baldo/ns_dl_patch/Developer_s_manual.html for more detailed informations.
As we mentioned afore, default values for variables and settings are stored in the file we called foo-init.tcl. This contains default values for your variables. It is an important aspect, so take care. Starting a simulation with variables which have no value often means that they assume ``random'' values (i.e. the value of the variable(s) previously stored in that portion of memory). At simulation start you will be noticed of suc an event by a warning message. It has the form:
warning: no class variable Routing/MrclRoutingStatic::overheadLength_ see tcl-object.tcl in tclcl for info about this warning.
In the same file initialization of file headers are stored as we discussed regarding the tab_
variable. Being this a Tcl file it follows the rules of Tcl language so you'll set variable values by using the set command.
We now explain the content of one of these files, referring to the cbr-defaults.tcl
file, in cbr/
directory.
When you refer to a module in Tcl, you'll use the Tcl name for the calss. This name is defined in the *.cc file, in a part often described as ``TCL Hooks for the simulator''. In this case the file is cbr-module.cc
and the name is Module/CBR
. For example, let's set the value of packetSize_
variable when library is loaded:
Module/CBR set packetSize_ 180
Notice that this is a Tcl portion of code, so if you do the same on your simulation files, you'll obtain the same result: every module you'll create will use the value you defined in the line. It is important to emphasize that you are working on Tcl, so you can manage only those variables you share with Tcl code. To do so you have to use the bind
command. Default values of other variables are only in , and their default values can be setted up in constructor as you see for txsn(1), hrsn(0), pkts_recv(0)
variables in cbr-module.cc
file.