NS-2.27 and Leach

Wednesday, April 28, 2004

proc add-interface changed its signature

Problem:
The tcl code complains that the wrong number of arguments was inserted:

0 _o12 _o13 RCALinkLayer Mac/Sensor Queue/DropTail 100 Phy/WirelessPhy Antenna/OmniAntenna # _o5 {} {} {}
wrong # args: should be "_o17 self class proc channel pmodel lltype mactype qtype qlen iftype anttype topo inerrproc outerrproc fecproc"
(Object next line 1)
invoked from within
"_o17 next _o12 _o13 RCALinkLayer Mac/Sensor Queue/DropTail 100 Phy/WirelessPhy Antenna/OmniAntenna # _o5 {} {} {}"
("eval" body line 1)
invoked from within
"eval $self next $args"
(procedure "_o17" line 15)
(MobileNode/ResourceAwareNode add-interface line 15)
invoked from within
"$node add-interface $chan $prop $opt(ll) $opt(mac) $opt(ifq) $opt(ifqlen) $opt(netif) $opt(ant) # $ns_ "" "" """
(procedure "leach-create-mobile-node" line 54)
invoked from within
"leach-create-mobile-node $i"
invoked from within
"if { [string compare $opt(rp) "dsr"] == 0} {
for {set i 0} {$i < $opt(nn) } {incr i} {
dsr-create-mobile-node $i
}
} elseif { [string compare $op..."
(file "./wireless-leach.tcl" line 246)


This is because the Node/MobileNode procedure add-interface in file tcl/lib/ns-mobilenode.tcl is different since 2.1b5. The documentation hasn't been keeping up either. The old signature is:

Node/MobileNode instproc add-interface { channel pmodel lltype mactype qtype qlen iftype anttype}

The new signature is:

Node/MobileNode instproc add-interface { channel pmodel lltype mactype qtype qlen iftype anttype topo inerrproc outerrproc fecproc}

As you can see, there are four extra arguments tacked on the end, but I have no idea what those argument are, much less their type. I'm guessing it's a topology object, some incoming error procedure, an outgoing error procedure, and a forward error correction procedure.

Fix:
I grepped for 'proc channel':

gen/ns_tcl.cc:Simulator instproc channel {val} {$self set channel_ $val}\ngen/ns_tcl.cc:Simulator instproc channelType {val} {$self set channelType_ $val}\nBinary file gen/ns_tcl.o matches
Binary file ns.exe matches
tcl/lib/ns-lib.tcl:Simulator instproc channel {val} {$self set channel_ $val}
tcl/lib/ns-lib.tcl:Simulator instproc channelType {val} {$self set channelType_ $val}


Which makes me guess that since the only object that has a channel procedure is simulator, I assume $topo takes a Simulator object. There is a Topography object in ns2. It makes more sense that this is what you pass in. I'll have to check if it has a channel procedure though.

Looking at the code within proc add-interface, I noticed the following lines were added:

if {$inerrproc != ""} {
set inerr_($t) [$inerrproc]
}
set outerr_($t) ""
if {$outerrproc != ""} {
set outerr_($t) [$outerrproc]
}
set fec_($t) ""
if {$fecproc != ""} {
set fec_($t) [$fecproc]
}


So I assume that I can pass in nothing and leach will still work, since it didn't need it before. Therefore, in mit/uAMPS/sims/uamps.tcl, I changed

$node add-interface $chan $prop $opt(ll) $opt(mac) $opt(ifq) $opt(ifqlen) $opt(netif) $opt(ant)

into:

$node add-interface $chan $prop $opt(ll) $opt(mac) $opt(ifq) $opt(ifqlen) $opt(netif) $opt(ant) $ns_$topo "" "" ""

Tuesday, April 27, 2004

Looking for TDMAschedule.*.txt

Problem:
The rest of the tcl scripts that she wrote for leach has some directory pointing problems. Those are easily fixable. However, the script, uamps.tcl, asks for "TDMAschedule.*.txt", which I have no idea where to find them.

Fix:
They were being deleted if they existed, not being created. Error in the syntax of the catch statement.

catch "eval exec rm [glob $opt(dirname)/TDMAschedule.*.txt]"

changes to:

catch {eval exec rm [glob $opt(dirname)/TDMAschedule.*.txt]}

This way, the eval statement is treated as an argument into catch, so that it doesn't error out.

Tuesday, April 20, 2004

sample-wireless-script failed

Problem:
The execution of the tcl script (wireless-leach.tcl--formerly wireless.tcl) to validate LEACH is failing. Somehow, nodes aren't being defined.

Fix:
"sample_leach_script" was originally written as a sh file. Need to convert to bash file.

set alg = leach

changes to:

alg = "leach"

etc, for the variable instanciations.

Monday, April 19, 2004

Some validation tests failed

Problem:
The following validation files filed after compilation:

./test-all-full ./test-all-wireless-shadowing ./test-all-wireless-lan-aodv ./test-all-wireless-tdma ./test-all-wireless-gridkeeper ./test-all-wireless-diffusion ./test-all-wireless-lan-newnode ./test-all-WLtutorial ./test-all-energy ./test-all-diffusion3 ./test-all-tagged-trace ./test-all-smac

Explaination:
The validation failed because the tcl script could not recognize the new MIT-uAMPS variables added into wireless-phy.cc. Therefore, no output was generated for the test, and thus the test failed. I don't think that it's THAT important to get these validations tests up and running, since the tests weren't designed for MIT-uAMPS in the first place.

Friday, April 16, 2004

IT COMPILES!

Yay. It compiles. :) Now I'll have to run the validation tests on it.

Missing Macros in packet.h

Problem:
mac/mac-sensor.cc: In member function `void MacSensor::send(Packet*, Handler*)
':
mac/mac-sensor.cc:106: error: `HDR_MACSensor' undeclared (first use this
function)
mac/mac-sensor.cc:106: error: (Each undeclared identifier is reported only once
for each function it appears in.)
make: *** [mac/mac-sensor.o] Error 1


Fix:
Put the following missing macros in packet.h next to the other HDR macros:

#ifdef MIT_uAMPS
#define HDR_RCA(p) ((struct hdr_rca*)(p)->access(hdr_rca::offset_))
#define HDR_MACSensor(p) ((struct hdr_macSensor*)(p)->access(hdr_mac::offset_))
#endif

log_target->buffer() changed

Problem:
In the file rcagent.cc and bsagent.cc, log_target->buffer() is no longer being used

Fix:
Guessing from common/mobilenode.cc, it probably changed to log_target_->pt_->buffer(); After looking at trace/trace.h and trace/basetrace.h, I'm pretty sure that it is. Same applies for the log_target_->pt_->dump(); call.

Changed

sprintf(log_target->buffer(),
"C %.5f %s",
s.clock(),
msg);
log_target->dump();


to

sprintf(log_target_->pt_->buffer(),
"C %.5f %s",
s.clock(),
msg);
log_target_->pt_->dump();


Note: Remember to change rcagent.h's (and bsagent.h)class attribute definition of log_target to log_target_, and all other references to the old attribute name in rcagent.cc(and bsagent.cc)

Traces and what wrk_ attribute?

Problem:
Don't know which wrk_ attribute it's referring to.

trace/cmu-trace.cc: In member function `void CMUTrace::format_rca(Packet*, int)
':
trace/cmu-trace.cc:1200: error: `wrk_' undeclared (first use this function)
trace/cmu-trace.cc:1200: error: (Each undeclared identifier is reported only
once for each function it appears in.)
make: *** [trace/cmu-trace.o] Error 1


Fix:
the offending line is apparently:

sprintf(wrk_ + offset, "------- [%c %d %d %d] ",
op,
rca_hdr->rca_src(),
rca_hdr->rca_link_dst(),
rca_hdr->rca_mac_dst()
);


Since ns2.1b5, wrk_ has been replaced by another pointer.

sprintf(pt_->buffer() + offset, "------- [%c %d %d %d] ",
op,
rca_hdr->rca_src(),
rca_hdr->rca_link_dst(),
rca_hdr->rca_mac_dst()
);


However, I'm not sure if the trace format is correct. It should be...though there are other types of traces, such as pt_->tagged() and newtrace_, from looking at the other format functions.

A GOTO statement in wireless-phy.cc!?

Problem:
Wow. I haven't seen these since GWBASIC. A goto statement jumps over declarations in the MIT code.

mac/wireless-phy.cc: In member function `virtual int
WirelessPhy::sendUp(Packet*)':
mac/wireless-phy.cc:483: error: jump to label `DONE'
mac/wireless-phy.cc:387: error: from here
mac/wireless-phy.cc:397: error: crosses initialization of `int code'
mac/wireless-phy.cc:393: error: crosses initialization of `hdr_rca*rca_hdr'
mac/wireless-phy.cc:392: error: crosses initialization of `hdr_cmn*ch'


Fix:
I just moved the declarations up to the top of the function before any goto statements.

int
WirelessPhy::sendUp(Packet *p)
{
/*
* Sanity Check
*/
assert(initialized());

PacketStamp s;
double Pr;
int pkt_recvd = 0;

#ifdef MIT_uAMPS
hdr_cmn *ch = HDR_CMN(p);
hdr_rca *rca_hdr = HDR_RCA(p);
int code = rca_hdr->get_code();
#endif

// if the node is in sleeping mode, drop the packet simply
if (em())
...

Change in wireless-phy.cc

Problem:
mac/wireless-phy.cc: In member function `virtual int
WirelessPhy::sendUp(Packet*)':
mac/wireless-phy.cc:456: error: `getLoc' undeclared (first use this function)
mac/wireless-phy.cc:456: error: (Each undeclared identifier is reported only
once for each function it appears in.)


Fix:
The uAMPs assumes that the node_ attribute is a MobileNode*, but when it's really of a base type, Node*.

As a quick fix, I just cast it down to a MobileNode* like the following:

dynamic_cast<MobileNode*>(node_)->getLoc(&tX, &tY, &tZ);

generally bad practice, I know, but I'm only trying to patch it, and I'm pretty sure that the uAMPs code only deals with mobile nodes, so having it call getLoc() assuming a MobileNode isn't too bad...

Change in channel.cc

channel.cc should use removechnl() instead of deletechnl(&[arg])

Where to put #define MIT_uAMPS?

Problem:
Where do you put the #define MIT_uAMPS? Without it, the additional files, such as mit/rca/rcagent.cc cannot compile, since it needs the additional definition of PT_RCA in common/packet.h

mit/uAMPS -o mit/rca/rcagent.o mit/rca/rcagent.cc
mit/rca/rcagent.cc: In constructor `RCAgent::RCAgent()':
mit/rca/rcagent.cc:33: error: `PT_RCA' undeclared (first use this function)
mit/rca/rcagent.cc:33: error: (Each undeclared identifier is reported only once
for each function it appears in.)


Added #define MIT_uAMPS in:
  • common/packet.h
  • common/tclAppInit.cc
  • removed all #defines and put in makefile


Fix:
Figured out that defines can be put in Makefiles. I simply added

DEFINE_MIT = -DMIT_uAMPS

and added $(DEFINE_MIT) to the end of:

DEFINE = -DTCP_DELAY_BIND_ALL -DNO_TK @V_DEFINE@ @V_DEFINES@ @DEFS@ -DNS_DIFFUSION -DSMAC_NO_SYNC -DCPP_NAMESPACE=@CPP_NAMESPACE@ -DUSE_SINGLE_ADDRESS_SPACE -Drng_test

Thursday, April 15, 2004

Make is seg faulting

Problem:
Make seg faults on

g++ -c -DTCP_DELAY_BIND_ALL -DNO_TK -DTCLCL_CLASSINSTVAR -DNDEBUG -DUSE_SHM -DHAVE_LIBTCLCL -DHAVE_TCLCL_H -DHAVE_LIBOTCL1_8 -DHAVE_OTCL_H -DHAVE_LIBTK8_4 -DHAVE_TK_H -DHAVE_LIBTCL8_4 -DHAVE_TCL_H -DHAVE_CONFIG_H -DNS_DIFFUSION -DSMAC_NO_SYNC -DCPP_NAMESPACE=std -DUSE_SINGLE_ADDRESS_SPACE -Drng_test -I. -I/usr/X11R6/include -I/home/chungw1/ns-allinone-2.27/tclcl-1.15 -I/home/chungw1/ns-allinone-2.27/otcl-1.8 -I/home/chungw1/ns-allinone-2.27/include -I/home/chungw1/ns-allinone-2.27/include -I/usr/include/pcap -I./tcp -I./sctp -I./common -I./link -I./queue -I./adc -I./apps -I./mac -I./mobile -I./trace -I./routing -I./tools -I./classifier -I./mcast -I./diffusion3/lib/main -I./diffusion3/lib -I./diffusion3/lib/nr -I./diffusion3/ns -I./diffusion3/filter_core -I./asim/ -I./qs -I./mit/rcs -I./mit/uAMPS -o common/ptypes2tcl.o common/ptypes2tcl.cc
g++ -o common/ptypes2tcl common/ptypes2tcl.o
./common/ptypes2tcl > gen/ptypes.cc
Signal 11
make: *** [gen/ptypes.cc] Error 139


ptypes.cc is a generated piece of code during compile. Because it somehow segs out, it never finishes writing the file. On subsequent makes, I get Error 1, due to the incomplete file not being able to generate the *.o file.

  • first search for #ifndef instead of #ifdef...no problems.
  • replacing changed files with original 2.27 files and recompile...success.
  • put back changed files without defining MIT_uAMPS and added $(OBJ_MIT) to the end of $(OBJ) in Makefile.in and recompile...success
  • ./validate wireless-test...success
  • complete recompile...success
  • #define MIT_uAMPS and recompile...failed

Semi-Fix:
The problem was because I uncommented #ifdef MIT_uAMPS in packet.h to bypass a compile error, and it ended up seg faulting. Man. A day wasted. See next post for real problem

Incorporating Leach

I thought about using the older version of ns2, but figured that it should be too hard to compile leach with the new version. Besides, there are probably bug fixes that I would want to keep up with. ns2 should have an easier way to incorporate new protocol, instead of modifying existing code.

ns-2.1b5 is the last build LEACH was written for. The directory structure of ns-2.1b5 is different from ns-2.27, and thus, some of the files go into different directories now. Assuming a directory of ns2.27, The following files from the ns-2.27 will change with the LEACH protocol:

/apps/app.cc
/apps/app.h
/mac/channel.cc
/trace/cmu-trace.cc
/trace/cmu-trace.h
/common/packet.cc
/common/packet.h
/mac/phy.cc
/mac/phy.h
/mac/wireless-phy.cc
/mac/wireless-phy.h
/mac/ll.h


These files are unchanged, even though they're included in the MIT_uAMPs distribution. I found that it was unnecessary to incorporate these changes, because those changes had been accepted in ns2.27:

/mac/mac.cc
/mac/mobilenode.cc


The are new files that you will need to add. I put them in the /mac subdirectory

/mac/mac-sensor-timers.cc
/mac/mac-sensor-timers.h
/mac/mac-sensor.cc
/mac/mac-sensor.h


Instead of just copying the old files, I searched for

#ifndef MIT_uAMPS

to see where it is the leach made changes, and made the corresponding changes in the existing ns2.27 code. I will post the new ns2.27 modified LEACH code later.

The Makefile.in also changes. I have added the following definitions:

# MIT uAMP LEACH includes
INCLUDES_MIT = -I./mit/rcs -I./mit/uAMPS

# MIT additions
#
OBJ_MIT = mit/rca/rcagent.o mit/rca/rca-ll.o mit/rca/resource.o mit/rca/energy.o mac/mac-sensor-timers.o mac/mac-sensor.o mit/uAMPS/bsagent.o


I added $(INCLUDES_MIT) to the end of the definition of $(INCLUDES)

I also added $(OBJ_MIT:.o=.c) to the end of the following:

SRC =
$(OBJ_C:.o=.c) $(OBJ_CC:.o=.cc)
$(OBJ_EMULATE_C:.o=.c) $(OBJ_EMULATE_CC:.o=.cc)
common/tclAppInit.cc common/tkAppInit.cc


And added $(OBJ_MIT) to the end of the following:

OBJ = $(OBJ_C) $(OBJ_CC) $(OBJ_GEN) $(OBJ_COMPAT)

Makefile of ns-allinone-2.27 flawed

Problem:
When I go to remake ns-2.27 without any changes, it stops and complains about namespace errors.

Fix:
I found this post in the ns2 user mailing list addressing the problem, but I didn't want to change just the makefiles if I had to reconfigure.

I found out how autoconf and automake works. Basically, autoconf reads configure.in (or configure.ac) files to configure the Makefiles for platform specific compiles. Makefile.in is the template to generate Makefiles, and there's one in every subdirectory. The Makefile.in is wrong in the directories:

ns-allinone-2.27/ns-2.27/indep-utils/cmu-scen-gen
ns-allinone-2.27/ns-2.27/indep-utils/webtrace-conv/dec
ns-allinone-2.27/ns-2.27/indep-utils/webtrace-conv/nlanr


The line:
CFLAGS = @V_CCOPT@ -DSTL_NAMESPACE=@STL_NAMESPACE@

should be changed to:
CFLAGS = @V_CCOPT@ -DSTL_NAMESPACE=@STL_NAMESPACE@ -DCPP_NAMESPACE=@CPP_NAMESPACE@

in all Makefile.in in the aforementioned directories.

Cannot simply use ./configure

Problem:
I don' t know if this is Cygwin specific or not, but I found that while the install file installs correctly, ./configure does not run correctly in the ns-2.27 directory.

Fix:
I looked at the ./install file in the top-level directory, ns-allinone-2.27, and looked at the ./install file. I found that there are options that needed to be passed into ./configure in the ns-2.27 subdirectory to make it work.

./configure --x-libraries=/usr/X11R6/lib --x-includes=/usr/X11R6/include

Where to get ns2

You can get the software and installation tutorials at the following places:

ns-2
uAMPs/Leach

I'm currently using Cygwin. It's not necessary for the operation of ns-2

Cygwin
Cygwin/ns2 installation tutorial

Purpose of Blog

This is so that I can keep track of the knowledge I've acquired in using the ns2 software. And also if anyone else that needs to know this information. If you mess up your life from the info you gleamed off of here, I'm not responsible. Use at your own risk.