Anda di halaman 1dari 118

SUNSET framework version 2.

0: Guidelines to use the system and to develop


novel solutions.

Contents
1 SUNSET v2.0
1.1 SUNSET structure . . .
1.2 Download SUNSET . .
1.2.1 Update SUNSET
1.3 Install SUNSET . . . .
1.4 Changelog . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

9
9
13
14
14
15

2 Main Modules Description


2.1 Core Components . . . . . . . . . . . .
2.1.1 Debug Module . . . . . . . . .
2.1.2 Trace Module . . . . . . . . . .
2.1.3 Information Dispatcher Module
2.1.4 Utilities Module . . . . . . . .
2.1.5 Statistics Module . . . . . . . .
2.1.6 Timing Module . . . . . . . . .
2.1.7 Packet Converter . . . . . . . .
2.1.8 Energy Module . . . . . . . . .
2.1.9 Packet Error Model . . . . . .
2.2 Emulation Components . . . . . . . .
2.2.1 Generic Modem Module . . . .
2.2.2 Connections . . . . . . . . . . .
2.2.3 Channel Emulator . . . . . . .
2.3 Network Protocols . . . . . . . . . . .
2.3.1 Phy Module . . . . . . . . . . .
2.3.2 Blacklist . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

17
17
17
17
17
18
18
19
19
24
24
24
24
25
25
26
26
26

.
.
.
.
.
.

27
27
27
28
29
29
33

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

3 Instructions and examples of usage


3.1 Suggestions when developing using SUNSET . . . . . . .
3.2 Debug Module . . . . . . . . . . . . . . . . . . . . . . . .
3.3 Trace Module . . . . . . . . . . . . . . . . . . . . . . . . .
3.4 Information Dispatcher Module . . . . . . . . . . . . . . .
3.4.1 Using the Information Dispatcher in your modules
3.4.2 Set the Information Dispatcher in Tcl script . . . .
3

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

Contents
3.5
3.6
3.7

3.8
3.9
3.10
3.11
3.12
3.13
3.14
3.15
3.16

Timing Module . . . . . . . . . . . . . . . . .
Packet Converter . . . . . . . . . . . . . . . .
Utilities Modules . . . . . . . . . . . . . . . .
3.7.1 Simulation/Emulation running mode .
3.7.2 Scheduling new events . . . . . . . . .
3.7.3 Erasing data packets . . . . . . . . . .
Statistics Module . . . . . . . . . . . . . . . .
Energy Model . . . . . . . . . . . . . . . . . .
3.9.1 Energy Model - Print Statistics . . . .
Generic Modem . . . . . . . . . . . . . . . . .
Power Control . . . . . . . . . . . . . . . . . .
3.11.1 Power Control - Energy consumption Packet Error Model . . . . . . . . . . . . . .
Blacklist . . . . . . . . . . . . . . . . . . . . .
Channel Emulator - Position . . . . . . . . .
Implementing a new protocol . . . . . . . . .
3.15.1 Define a new packet . . . . . . . . . .
Connections . . . . . . . . . . . . . . . . . . .
3.16.1 TCP Connections . . . . . . . . . . .
3.16.2 UDP Connections . . . . . . . . . . .
3.16.3 Serial Connections . . . . . . . . . . .

4 Virtual Machine
4.1 SUNSET x86 . . . . . . . . . . . . . . . .
4.2 Update Ns . . . . . . . . . . . . . . . . . .
4.2.1 Patching ns-Miracle: older version
4.2.2 Patching Ns-Miracle: newer version
4.3 Update Ns-Miracle . . . . . . . . . . . . .
4.4 Update SUNSET . . . . . . . . . . . . . .
4.5 Update WOSS . . . . . . . . . . . . . . .

.
.
.
.
.
.
.

.
.
.
.
.
.
.

. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
Statistics
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

33
36
51
51
51
53
53
64
65
67
68
69
70
70
71
73
74
92
92
94
95

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

97
99
99
99
100
100
100
100

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

5 User group
6 Example scripts
6.1 Simulation . . . . . . . . . . . . . . . .
6.1.1 runUrick.tcl . . . . . . . . . . .
6.1.2 runBellhop.tcl . . . . . . . . . .
6.1.3 runSUNSETUrick.tcl . . . . . .
6.1.4 runSUNSETBellhop.tcl . . . .
6.1.5 runSUNSETUrick_agt.tcl . . .
6.1.6 runSUNSETBellhop_agt.tcl . .
6.1.7 runSUNSETUrick_agt_per.tcl
6.2 Emulation . . . . . . . . . . . . . . . .
6.2.1 channelEmulator.tcl . . . . . .

101

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

103
105
105
106
107
108
109
109
110
111
111

Contents
6.2.2
6.2.3
6.2.4
6.2.5

5
channelEmulator_black.tcl
runEvologics.tcl . . . . . . .
runEvologics_agt.tcl . . . .
runMicromodem.tcl . . . .

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

113
114
116
117

Contents

SUNSET is a new solution, developed by the UWSN Group, to seamlessly simulate, emulate and test in real-life novel
communication protocols. It is based on the open source and well known network simulator ns-2 and its extension
ns2-Miracle.
The development of new solutions for SUNSET follows the same basic rules that for ns-2 and more similarly for ns2Miracle.
To seamlessly move from simulation to emulation and real-life testing, however, new modules have been implemented in
SUNSET providing a set of utilities which can be easily used by the developers. These utilities allow the user/developer
to run the same exact implemented code in simulation and emulation mode in a transparent way. To proper use the
additional SUNSET modules few differences have to be considered when implementing novel solutions with respect to
the standard ns2 and ns2-Miracle.
It is useful to point out that when running in simulation mode these new modules just make use of basic ns-2 and
ns2-Miracle functions. This means that if the developer directly calls the basic ns-2 and ns2-Miracle functions there is
no difference. However, when then running in emulation mode the basic ns-2 and ns2-Miracle functions are not enough
to properly handle the use of real hardware and SUNSET functions have to be adopted. This means that making use of
the SUNSET modules and functions for both simulation and emulation allows the developer to re-use the same exact
code without any change in a transparent way.
The main components provided by SUNSET when running in emulation mode are: Real-time scheduler, Packet Converter.
Additional other modules are provided by SUNSET as a toolkit to make easier the development, debugging and evaluation of novel protocol solutions: Debug module, Statistic module, Information Dispatcher and Utilities module, Timing
module, Channel emulator.
The current version of SUNSET implements different MAC and routing protocols and it supports the use of different
acoustic modems, as listed below. For all the provided protocol solutions, SUNSET allows to run simulation, emulation
and real-life tests in a transparent way to the user. SUNSET implements all the utilities and conversion functions when
moving from running in simulation mode to running in emulation mode. No extra effort is required by the user.
Routing Protocols:
Static Routing
Flooding (simple and probabilistic versions are provided)
MAC Protocols:
Aloha
CSMA Aloha
Slotted CSMA
TDMA

Contents

Acoustic Modem Drivers:


WHOI FSK Micro-Modem (it should work with PSK as well)
Evologics Modem, firmware version 1.4
Evologics Modem, firmware version 1.6
In what follows we describe how to use and extend each of these modules, providing examples and pieces of code to
more easily understand the operations to perform.

Chapter 1

SUNSET v2.0
1.1

SUNSET structure

The overall SUNSET modules structure has been changed. There is no more division between Core and Add-on modules. Instead the following modular division has been preferred, which allows the user to avoid the use of any emulation
components when running in simulation mode. All the modules have been grouped in Core modules (used for both
simulations and emulation tests), Network modules (implementing all the different protocol stack solutions and additional components to evaluate the protocol solutions by means of both simulation and emulation), Emulation modules
(providing the additional support to seamlessly run the network solutions in emulation mode with no additional effort
by the user):
Core_Components
Emulation_Components
Network_Protocols
Improved and enhanced modules to run SUNSET in emulation and field testing mode have been designed
and implemented by SUNSET developers in collaboration with industrial third parties. Unfortunately,
these solutions CANNOT be all released open to the community. To provide these enhanced and improved modules to the users, we have decided to release them as compiled libraries. This allows anyone
to use freely and easily use the improved version of SUNSET when running in simulation, emulation
and real-life mode.
The source code for all the modules needed when running simulations and the released network solutions is instead freely
available. The modules released as libraries are: Packet converter modules in Core components; the Emulation components, with the exception of the Evologics and Micro-Modem drivers and the Debug_Emulation module (see below).
The provided libraries have been compiled using as target machine the released Virtual machine (see Sections 1.2 and 4)
and have been also added to the SVN repository (see Section 1.2). Additional libraries to run SUNSET on different
architectures can be requested to SUNSET developers.

10

Capitolo 1. SUNSET v2.0

A brief description of each of the released modules follows:


Core_Components: This folder contains all the core modules needed which are needed to properly run the
SUNSET framework. All these modules can be easily extended according to the user needs, if needed. The list of
the provided modules is:
General/Sunset_Module: This module is the main module extended by all the underwater modules. Common
properties of underwater modules have to be defined here.
General/Sunset_Queue: This module implements a generic packet queue which can be used at all layer of
the protocol stack.
General/Sunset_Timing: This module is used to compute the correct timing delays when running in simulation and emulation mode. Delays related to the use of embedded device, acoustic modem or other devices can
be added to this module to compute timing and delays closer to the ones that would be obtained in real-life
testing. The timing information will be used by the different layers of the protocol stack when they have to
compute timeouts or other time related information.
General/Sunset_Energy_Model: This module defines an energy model which can be used by the SUNSET
modules to estimate the node energy consumption. It supports the use of different transmission power levels.
The energy consumption can be set according to the different power levels.
General/Sunset_Packet_Error_Model: This module implements a packet error model which can be used at
the physical layer. Different error model are define allowing the user to set a predefined PER to be used for
all the received packets or a packet error rate related to the used modulation. Two different modulations are
supported at the moment: BPSK and FSK.
General/Sunset_Common_Header: The SUNSET common packet header is intended to contain useful information which can be commonly used by the different modules when running gin both simulation and
emulation mode.
Utilities/Sunset_Information_Dispatcher: This module implements the Information Dispatcher module, which
is used to share information among the different layers of the protocol stack. It implements a publish/subscribe
pattern.
Utilities/Sunset_Debug: This module is used to print debug information. The user can define the requested
debug level using the Tcl script. Lower levels correspond to less information printed on the standard output,
higher levels to more information.
Utilities/Sunset_Trace: This module is used to print tracing information. Differently from the Debug module,
the message is printed despite the debug level.
Utilities/Sunset_Utilities: This module is used to define utility functions which are used when running in
both simulation and emulation mode. Several of these functions make transparent to the user the use of
simulation modules or real hardware.
Utilities/Sunset_Position: This module is used to collect and provide position information to the interested
modules. The Information Dispatcher is used for the modules interaction.
Statistics/Sunset_Statistics: The generic statistics module is used by the other modules to trace what happens
during the simulation/emulation. The information are written on a trace file for post-processing analysis.
The Sunset_Protocol_Statistics (Network Protocols) extends this module to trace all the network protocols
statistics for the provided networking solutions.

1.1. SUNSET structure

11

ClMessage/Sunset_Modem2Phy: This module defines a cross-layer message which is sent by the modem
(or modem driver) to the PHY layer informing that the transmission of a packet p has not been correctly
completed (Transmission Aborted).
ClMessage/Sunset_Phy2Mac: This module defines a cross-layer message from the PHY layer to the MAC
layer informing that the transmission of a packet p has not been correctly completed.
ClMessage/Sunset_Mac2Rtg: This module defines cross-layer messages sent by the MAC layer to the routing
layer informing about the correct or erroneous transmission for packets coming from the upper layers.
Packet_Converter/Sunset_Common_Pkt_Converter: This module extends the packet converter module and
it is responsible for the conversion of the SUNSET common packet header information into a stream of bytes
for the actual in water transmission and vice versa. This module is available has a compiled library.
Packet_Converter/Sunset_Ns_Pkt_Converter: This module extends the packet converter module and it is
responsible for the conversion of the ns-2 common packet header information into a stream of bytes for the
actual in water transmission and vice versa. This module is available has a compiled library.
Packet_Converter/Sunset_Pkt_Converter: The generic packet converter module handles all the information
about ns-2 packets when running in emulation mode. It is responsible for the conversion of the different
ns-2 packet headers into a stream of bytes for the actual in water transmission and vice versa. All the
different considered packet types, for the different protocol stack layers, extend this module and implement
their own functions to convert packets into streams of bytes and bytes into packet. Moreover, additional
methods to collect information about the different packet header fields are provided which can be then
used by the interested modules. This module, together with the Sunset_Common_Pkt_Converter and the
Sunset_Ns_Pkt_Converter, is used only when running in emulation mode. It has not be added to the
Emulation_Components folder to make easier and more transparent to the user the new structure of the
SUNSET framework. This module is available has a compiled library.
Emulation_Components: This folder contains all the emulation modules needed by SUNSET to run in emulation mode during in field experiments (all the modules and libraries provided in this folder are not needed when
running in simulation mode):
Scheduler/Sunset_RT_Scheduler: This module implements the SUNSET real-time scheduler, which is used
when running in emulation mode. It is an improved and optimized scheduler with respect to the basic one
provided by ns-2. This module is available has a compiled library.
Utilities/Sunset_Debug_Emulation: This module is used to print the required debug information. It works
as the basing Sunset_Debug module in the Core folder, but it also provide the epoch time (time form the
epoch) when printing the information on the standard output.
Utilities/Sunset_Utilities_Emulation: This module implements the utilities function used when running in
real-time (emulation) mode: Interacting with the packet converter to remove the memory allocated for the
packet headers and payload, if any; event scheduling; etc. This module is available has a compiled library.
Utilities/Sunset_Connections: This module implements basic connection functionalities for the interaction
with external devices: The TCP, UDP and Serial modules all extend this generic module and implement the
corresponding function to read and write data over TCP and USP streams or serial line connections. This
module is available has a compiled library.

12

Capitolo 1. SUNSET v2.0


Utilities/Sunset_Timing_Emulation: This module is used to compute the correct timing delays when running
in emulation mode. It extends the basic Timing module and calls the modem driver functions to obtain the
actual delays related to use of the specific modem. This module is available has a compiled library.
Acoustic_Modems/Sunset_Generic_Modem: This module implements the generic modem operations. It uses
the Sunset_Pkt_Converter module to convert ns-2 data packets into streams of bytes before the actual transmissions and vice versa. It also implements all the timing function defined in Sunset_Generic_ModemTimer.
All the different acoustic modem drivers extend this module. This module is available has a compiled library.
Acoustic_Modems/Sunset_Micro_Modem: This module implements the FSK/PSK Micro-Modem operations. It implements the timing Micro-Modem function defined in Sunset_Modem_Timing_Interface. It
extends the generic driver module.
Acoustic_Modems/Sunset_Evologics/Sunset_Evologics_v1_6 : This module implements the Evologics Modem (firmware version 1.6) driver. It extends the generic modem module.
Acoustic_Modems/Sunset_Evologics/Sunset_Evologics_v1_4 : This module implements the Evologics Modem (firmware version 1.4) driver. It extends the generic modem module.
Uw_Channels/Sunset_Channel_Emulator: This module implements the SUNSET Channel Emulator. It can
be used to test the protocol solutions and parameter settings while running in emulation mode without the
need of a real acoustic device for data transmissions. It allows to have multiple nodes running in emulation
mode on the same machine or in the same network. Propagation delays over the different links are emulated
according to the defined node positions. This module is available has a compiled library.
Uw_Channels/Addon/Sunset_Position_Channel: This module is used to provide to the Channel Emulator
the information about the node positions. Using this module the Channel Emulator is informed when the
position of a node changes, e.g., when emulating a mobile asset in the network. This module is available has
a compiled library.
Network_Protocols:
Application/Sunset_Agent: The generic Agent layer class. It supports also the creation of data packets with
given payloads when running in emulation mode.
Datalink/Sunset_Mac: The generic MAC layer class. It implements basic functionalities needed by the specific
MAC protocols. It cannot be used as a stand alone MAC protocol but the extended classes have to be used.
Datalink/Sunset_Aloha: This class implements the Aloha protocol. It extends the Sunset_Mac class.
Datalink/Sunset_Csma_Aloha: This class implements the CSMA Aloha protocol. It extends the Sunset_Mac
class.
Datalink/Sunset_SlottedCsma: This class implements the Slotted CSMA MAC protocol. It extends the Sunset_Mac class.
Datalink/Sunset_Tdma: This class implements the TDMA MAC protocol. It extends the Sunset_Mac class.
Transport/Sunset_Transport: The generic Transport layer class - it does not implement any methods to
update the transport table. Other transport solutions have to extend this class and implements these methods.
Network/Sunset_Routing: The generic Routing layer class - it does not implement any methods to update
the routing table. Other routing solutions have to extend this class and implements these methods. The basic
routing protocol cannot be used in the protocol stack but the extended classes have to be considered.

1.2. Download SUNSET

13

Network/Sunset_Static_Routing: This class implements the Static Routing protocol. It extends the Sunset_Routing class.
Network/Sunset_Flooding: This class implements a Probabilistic Flooding Routing protocol. It extends the
Sunset_Routing class.
Phy/Sunset_Phy: This class defines a dummy PHY layer to connect upper layers to the selected device when
running in emulation mode. This module is used only when running in emulation mode. It has not be added
to the Emulation_Components folder to make easier and more transparent to the user the new structure of
the SUNSET framework,
Phy/Sunset_Phy_Uw/Sunset_Phy_Bellhop: This class extends the WossMPhyBpsk ("Bellhop" racy tracing
model) class of WOSS enabling the usage of several transmission powers and of a more accurate energy
consumption model.
Phy/Sunset_Phy_Uw/Sunset_Phy_Urick: This class extends the UnderwaterMPhyBpsk ("Urick" model)
class of WOSS (or ns-miracle if available) enabling the usage of several transmission powers and of a more
accurate energy consumption model.
Addon/Packet_Converter/Application/Sunset_Agent_Pkt_Converter: This class is responsible for the conversion of the Agent header information into a stream of bytes and vice versa.
Addon/Packet_Converter/Application/Sunset_Cbr_Pkt_Converter: This class is responsible for the conversion of the CBR header information into a stream of bytes and vice versa.
Addon/Packet_Converter/Datalink/Sunset_Mac_Pkt_Converter: This class extends the packet converter
class and it is responsible for the conversion of the MAC headers information into a stream of bytes and vice
versa.
Addon/Packet_Converter/Network/Sunset_Routing_Pkt_Converter: This class is responsible for the conversion of the routing headers information into a stream of bytes and vice versa. This class is a place holder
at the moment, since no routing packet headess have been implemented yet when running in emulation mode.
Addon/Packet_Converter/Phy/Sunset_Phy_Pkt_Converter: This class is responsible for the conversion of
the PHY headers information into a stream of bytes and vice versa. This class is a place holder at the moment,
since no PHY packet headers have been implemented yet when running in emulation mode.
Addon/Statistics/Sunset_Protocols_Statistics: This class extends the basic Sunset_Statistics class and implements all the methods to collect and store the information related to the different protocol solutions
currently implemented in the SUNSET framework. These information are stored in a log file and are processed at the end of the simulation/emulation to compute important metrics needed to evaluate the protocol
performance: Throughput, Packet delivery ratio, End-to-end Latency, Route length, Energy consumption,
Protocol overhead, etc. The processed information are also saved in a separated file for later use.

1.2

Download SUNSET

To download, install and use SUNSET version 2.0 two different options are provided:
Virtual machine - A complete virtual machine which already includes SUNSET and all the required software.
It is based on a light and minimal Linux Debian distribution to reduce the overall size of the virtual environment
( 1.5GB). This solution is strongly recommended by SUNSET developers. Detailed instruction on how
to download and use the Virtual machine are provided in Sections 4.

14

Capitolo 1. SUNSET v2.0


SVN repository - It allows to download the SUNSET code, libraries, scripts and examples. All the additional
software (ns-2, ns2-Miracle, cross-compile environment, etc.) have to be manually installed by the user.

All the modules to run SUNSET in emulation mode are released as compiled libraries for the architecture and environment of the provided virtual machine. This means that when using the virtual machine
the user can freely use SUNSET for simulation, emulation and in field tests. If the SVN repository
solution is instead used to download SUNSET, the user can freely run simulation, since no emulation
libraries are needed. However, it may need to use different compiled libraries, according to its host machine architecture and environment (used compiler, libraries, etc.), to run emulation and in field tests.
These compiled libraries can be requested to SUNSET developers.

To use the SVN repository you may need to install in your system the subversion package, if it has not been installed
before. The needed package and repository is already provided on the Virtual machine. To install SVN on your host
machine (for Debian based distributions) you just need to type:
apt-get install subversion
Once subversion has been installed on your machine, you can download the latest SUNSET version typing:
svn checkout http://svnreti.di.uniroma1.it/SUNSET
All the modules, libraries and the example scripts will be downloaded. You will find them inside the downloaded
SUNSET folder.
1.2.1

Update SUNSET

To update the SUNSET framework (from the Virtual machine or the host machine), you only need to move inside the
SUNSET root directory (which is the downloaded SUNSET folder, unless you have changed the directory name) and
run the following command:
svn update
And the framework will be automatically updated to the latest available version.

1.3

Install SUNSET

SUNSET depends on ns-2 and ns-Miracle software therefore you need to first install them. Moreover, if you want to
use the SUNSET Bellhop model you have to also install the WOSS package. Latest version of ns-Miracle include also
the Urick model, which has been removed from the latest WOSS version. If you do not install the latest ns-Miracle and
WOSS versions, the Urick model is in WOSS instead of ns-Miracle.
Four scripts are provided with SUNSET to make easier the installation of the different components:
install_core_components.sh: It installs SUNSET Core components.

1.4. Changelog

15

install_emulation_components.sh: It installs SUNSET Emulation components.


install_network_protocols.sh: It installs SUNSET Network protocol solutions.
install_network_protocols_pkt_converter.sh: It installs SUNSET packet converter modules related to the
network protocols.
In each of these scripts some variables must be properly set to install SUNSET. For the different components also
compile scripts are provided to compile only the modified modules. When installing and compiling SUNSET, the
pre-compiled libraries for the modules used in emulation mode (available in each folder) are automatically copied in the
selected folder (SUNSET_LIB_FOLDER) containing all the SUNSET libraries.
Packet converter modules related to network solutions must be installed after the installation of the networking modules.
Additionally, four scripts are also provided to just compile each module. these modules can be used after the installation:
compile_core_components.sh: It compiles SUNSET Core components.
compile_emulation_components.sh: It compiles SUNSET Emulation components.
compile_network_protocols.sh: It compiles SUNSET Network protocol solutions.
compile_network_protocols_pkt_converter.sh: It compiles SUNSET packet converter modules related to
the network protocols.
A brief description follows:
SUNSET_LIB_FOLDER: The directory where the SUNSET libraries will be installed.
NS_FOLDER: The directory where ns has been installed.
NSMIRACLE_FOLDER: The directory containing the folders related to the ns-Miracle modules (it is usually
in path_to_ns-Miracle/ns-Miracle/trunk/main).
WOSS_FOLDER: The directory where WOSS has been installed.
Note: The scripts define in the bash environment the SUNSET_LIB_FOLDER variable (defining it into the .bashrc
file). Therefore once the installation is complete, you may need to update your current bash environment just typing
source /.bashrc. The update environment will be automatically loaded if a new terminal window is opened.
When using the Virtual machine, all these software have been already installed and configured. The only
additional modules that the user may decide to install are the databases required by WOSS when using
Bellhop with real environmental data. These information ( 1GB) have not been included to reduce the
overall size of the Virtual machine.

1.4

Changelog

The following changes have been introduced in SUNSET version 2.0:


Several bug fixes;

16

Capitolo 1. SUNSET v2.0


Overall framework structure reorganization;
An improved and more detailed documentation;
An improved real time scheduler has been implemented;
A novel channel emulator allowing to debug and to investigate the overall system performance when running in
emulation mode, without the need of any real communication device.
A more accurate energy consumption module;
Different packet error models: Static PER and PER related to BPSK and FSK modulations;
A new protocol MAC protocol (CSMA Aloha);
New functionalities added to the PHY layer providing the possibility of remove direct link from the network (node
blacklist);
A novel trace module;
A statistic module to collect key metrics for the evaluation of the performance of the protocol solutions currently
implemented in SUNSET.
New classes allowing to handle the sharing of position information among the different modules (including also
the channel emulator) have been implemented.
A new Transport module to interconnect the ns-Miracle CBR module has been provided.
A packet converter for the CBR packet header has been implemented.
New connection classes have been provided to implement the separation between client modules and server modules;

Additionally, a patch has been provided allowing to use ns-Miracle together with ns-2.35 (see 4.2).

Chapter 2

Main Modules Description


2.1
2.1.1

Core Components
Debug Module

When developing and testing a novel solution, it is always useful for both developers and users to log debug information
for on-line or later processing. We have therefore developed and implemented a debug module which allows to assign to
each information to log a debug level. When the user starts the experiment it can define different debug levels for the
different information it wants to log. If debug level k is selected, it means that only the information with an assigned
debug level lower or equal tok will be logged. This module allows also to change the debug level on demand, while
the simulation/emulation is running, thus increasing and reducing the logged information according to the user needs.
This mechanism is particularly useful since when starting to develop a new solution a higher debug level can be used
to control the operations of the protocols in details. After this initial testing phase, the required debug value can be
reduced to have less information printed on the standard output without any change in the implemented code.
Please take a look at Section 3.2 for further information and examples of usage.
2.1.2

Trace Module

This module is used to trace experiment information. Differently from the Debug module 2.1.1, the message is printed
despite the debug level.
Please take a look at Section 3.3 for further information and examples of usage.
2.1.3

Information Dispatcher Module

The Information Dispatcher module implements the publish-subscribe pattern. The information dispatcher allows to
share information among the different layers of the protocol stack while keeping the high degree of flexibility and modularity given by the layered architecture. Each layer which wants to provide to or request information from the other
layers, can register itself to the information dispatcher and inform the dispatcher about the data it can provide and the
data it wants to be informed of. The dispatcher collects the information from the different modules and notifies any
update to all the modules which are interested about them. All modules can also request information on demand or
ask for periodic updates. Each information is timestamped in order to check its freshness. In case multiple layers are
providing the same information or some layers request information which require some processing on the data provided
17

18

Capitolo 2. Main Modules Description

by the other layers, the information dispatcher can take care of that, everything is inside the same module and provides
a more easy and fast way to handle the different information.
Please take a look at Section 3.4 for further information and examples of usage.
2.1.4

Utilities Module

To make transparent to the users the use of the framework in simulation and emulation mode an utilities module has
been implemented. It provides functionalities to check if the framework is running in simulation or emulation mode, i.e.,
if the standard scheduler or the real time scheduler is used. When scheduling an event the utilities module is responsible
to call the specific scheduler (standard or real-time) which has to take care of event scheduling. It also takes care of
removing the memory allocated for a ns-2 packet in a proper way: When running in simulation mode no actual memory
is allocated for the packet payload. When running in emulation mode, instead, additional memory could have been
allocated for the packet and it has to be erased when the packet is no longer needed, these operation are completed
making use of the Packet Converter Module. The utilities module also provides function to update the timing of the
real-time scheduler according to the clock of the device running the framework.
Please take a look at Section 3.7 for further information and examples of usage.
2.1.5

Statistics Module

To allow the user to collect statistical information to evaluate the protocol performance, a statistics module has been
designed. This module allows the user to collect all the information about packet transmissions and receptions, energy
consumption, additional delays (backoff period, device delays, etc.) and others. The user can then easily compute all
the metrics (per node or in the network) it is interested in: Packet delivery ratio, network throughput, packet latency,
energy consumption, etc. Moreover, the developers can easily extend the provided statistics module to include additional
information of interest. When running in simulation mode, the statistics module collects the information from all the
nodes in the network and all the required metrics are available at the end of the simulation. When running in emulation
mode, however, each node is an independent unit, storing its own information. For this reason, these information have
to be merged together with a post processing analysis. Moreover, all the collected and processes information are stored
on log files for later use.
The Sunset_Statistics class is the generic class defining the mechanism to collect the statistical information from the
different modules. The Sunset_Protocol_Statistics (located in Network_Protocols/Addon/Statistics/) is instead the
actual class implementing the data collection according to the packet header and protocol solutions currently supported
by SUNSET. These classes are really easy to use. The Sunset_Protocol_Statistics is a static class, whenever the user
or developer wants to log statistical information it can call the logStatInfo function:

virtual void logStatInfo(sunset_statisticType sType, u_int16_t node,


Packet* p, double time, const char *fmt, ...);
Where the first parameter is the action type, the second one the id of the node logging the action, the third one is the
packet the action refers to, the fourth parameter is the time when the action occurred, plus other possible information
to store additional messages.

2.1. Core Components

19

Please take a look at Section 3.8 for further information and examples of usage.
2.1.6

Timing Module

A timing module has been implemented which is used to model external device delays and overhead. When running
simulation, the delays related to the use of real devices are usually ignored. These delays include: 1) Computational
delay; 2) Operational delay related to internal operations of the considered device (acoustic modems, Gumstix, other
external devices); 3) Delays related to the communication between different hardware components on the same node.
These aspects have to be kept into account when tuning the protocols parameters before real-life tests. Moreover, it
is not always true that the message sent by the external device exactly corresponds to the original size of the created
message, because of coding performed by the device or constraints on the final packet sizes to be transmitted. E.g. the
packet length for FSK Micro-Modem is fixed to 32 Bytes, if the length of the message to be transmitted, lets say k, is
shorter than thatk < 32 always 32 Bytes are transmitted in water with 32 -k Bytes filled with zero. The timing module
is used to consider these delays and overhead when running both in simulation and emulation mode. If these delays are
already accounted for when computing protocol stack timeouts for simulation purposes (which means a specific modem
model is used for simulation and corresponding parameters are set in the timing module), no changes in the code are
needed and the code is seamlessly ported to real devices and used for tests at sea or in a lab emulation environment.
The Sunset_Timing class provides several functions which can be used to proper compute protocol timeouts and delays.
When running in simulation mode it uses the settings provided by the user in the Tcl scripts to consider properly all
the modem and device delays. When running in emulation mode it collects the needed information from the considered
device.
Please take a look at Section 3.5 for further information and examples of usage.
2.1.7

Packet Converter

A new module to convert an ns-2 packet into a stream of bytes then provided to the external device for actual transmission, has been implemented. Usually when defining a new packet header in ns-2 or ns2-Miracle, several information can
be added to he packet header without any particular constraints, since the packet size used in simulation is not derived
from the actual sizes of the packet headers and of the payload but it is simulated considering the size value written in the
common packet header. For this reason, in order to make the simulation analysis easier, information meant for statistic
or debugging purposes could be added to the defined packet header. Moreover, no attention is usually given to the
specific sizes used to store the packet header parameters, 1 bytes, 2 bytes or more. In such a situation it is not practical
to take an entire packet header and convert it into a stream of bytes for transmission without removing the information
that are not needed and without taking care of the actual sizes required by each parameters. E.g., if a simulation packet
header takes few tens of bytes when it is defined but the useful information are just source ID and destination ID, with
a maximum number of node in the network less or equal to 15, 4 bits can be used for each ID reducing the converted
header size to 1 Byte. On the other hand, it would be really impracticable to have packet header containing only the
exact information to be transmitted and having all of them with the exact sizes when running both simulation and
emulation. It would make the initial protocol analysis and design, conducted mainly through simulations, much harder.
To solve this problem, we have designed a new module for ns-2 packet conversion. When defining a new packet header,
the methods to convert it into an stream of bytes and vice versa have to be provided. In this way who designs the

20

Capitolo 2. Main Modules Description

packet header is also responsible for its conversion, deciding also about the subset of information to be converted and
the specific sizes. The selection about field selection and sizes can be performed by the user statically or at run time
using the configuration. The generic packet header class is responsible for the operations on the ns-2 packet conversion.
Such class uses the different packet header converter modules, having each module taking care of its specific packet
header. When the user decides what protocol and packet header have to be used in emulation, it also registers the used
packet header converter to the generic packet converter. Then the generic packet converter will detect for each packet
the different packet headers it contains and will use the corresponding converter to encode the ns-2 packet into a stream
of bytes for the actual transmission and vice versa for the packet reception.
Each packet converter has to implement few important functions:
virtual
virtual
virtual
virtual
virtual
virtual

int checkPktLevel(Packet* p);


int getHeaderSizeBits(); // returning the amount of bits needed in the packet header
int getConvertedInfoLength(Packet* p);
int pkt2Buffer(int level, Packet* p, char* buffer, int offset);
int buffer2Pkt(int level, Packet* p, char* buffer, int offset, int bits);
void erasePkt(int level, Packet* p);

The checkPktLevel(Packet* p) function returns 1 if the current packet header converter has to be considered for the
given packet, 0 otherwise.
The getHeaderSizeBits() function returns the maximal amount of bits which are needed by the packet header. It is
used by the Packet Converter module to compute the total size of the header information added to the packet and the
maximal allowed payload size, according to the maximal length of the message supported by the specific transmission
device.
The generic Packet Converter module uses the getHeaderSizeBytes() function to compute the header size information
for all the considered packet headers and the getMaxPayloadSize() function to return the maximal allowed payload
length.
The getConvertedInfoLength(Packet* p) function returns the number of bits needed to convert the given packet according to the user settings in the Tcl scripts.
The erasePkt(int level, Packet* p) function is used to remove the memory allocated for the given packet by the different
packet headers, if any.
The pkt2Buffer(int level, Packet* p, char* buffer, int offset) function takes the packet in input and converts it in a
stream of bits according to the user settings in the Tcl scripts. The generic packet converter will sum the total amount
of needed bits and will provided the final message size on bytes.
The buffer2Pkt (int level, Packet* p, char* buffer, int offset) function takes the stream of bits in input and converts it
in a ns-2 packet according to the user settings in the Tcl scripts.
Additional utilities function can be implemented to provide packet header information to the other modules:

2.1. Core Components

21

virtual int getSrc(int level, Packet* p, sunset_header_type m, int& src);


virtual int getDst(int level, Packet* p, sunset_header_type m, int& dst);
The sunset_header_type defines the type of packet header considered: Agent, MAC, routing, etc.
The getSrc(int level, Packet* p, sunset_header_type m, int& src) function is used to obtain the source ID for the packet
header.
The getDst(int level, Packet* p, sunset_header_type m, int& src) function is used to obtain the destination ID for the
packet header.
These information are particularly useful for the MAC layer to allow modem drivers to read into the packet and adjust
their operations.
Only if the user creates a new MAC packet (with new related subtype packets) and the related packet converter, it
has to implement also the following functions:
virtual int getMacPktSubType(int level, Packet* p, int& subType);
virtual int createMiniPkt(int level, Packet* p, sunset_header_type m, int src, \
int dst, int pkt_sub_type);
The getMacPktSubType(int level, Packet* p, int& subType) function is used to obtain the packet subtype of the MAC
packet header. Different operations could be taken when handling a data or control packet.
The createMiniPkt(...) function creates a short packet containing only the information on packet source, destination
and subtype (Currently used only for WHOI Micro-Modem when using the Micro-Modem mini packet). One of the
parameter in input is the packet header type (MAC, ROUTING, AGENT) allowing to create different kind of mini
packets, if needed.
Please, take a look at the Section 3.6 to have further information on the Packet Converter and to the examples reported
in Sections 3.15.1 and 3.6 to create a new packet and the related Packet Converter class.
Available fields

The following fields are currently provided by the different provided packet converter modules. According to the different
protocol stack layer, the following parameter can encoded/decoded in the transmitted packet in emulation mode (from
samples/channelEmulator.tcl):
Generic Packet Converter:
//maximal packet size in bytes (after the conversion into a stream of bytes)
Sunset_PktConverter set MAX_DATA_SIZE
1024
// number of bits used to express the node ID
Sunset_PktConverter set ADDR_BITS
3
// number of bits to express the maximal payload length

22

Capitolo 2. Main Modules Description


// (in this case no longer than 255 Bytes)
Sunset_PktConverter set DATA_BITS
8
// number of bits used to express packet ID
Sunset_PktConverter set PKT_ID_BITS
14
// number of bits used to express timing information
Sunset_PktConverter set TIME_BITS
24
Ns Converter:
//if 1 the timestamp value of the ns common header is used
$pktConverter_ns useTimestamp 1
//if 1 the destination port value of the ns common header is used
$pktConverter_ns useIpDestPort 1
//if 1 the source port value of the ns common header is used
$pktConverter_ns useIpSourcePort 1
//if 1 the source ID value of the ns common header is used
$pktConverter_ns useIpSource 1
//if 1 the destination ID value of the ns common header is used
$pktConverter_ns useIpDest 1
//if 1 the number of hops value of the ns common header is used
$pktConverter_ns useNumHop 1
//if 1 the packet id value of the ns common header is used
$pktConverter_ns usePktId 1
//if 1 the TTL value of the ns common header is used
$pktConverter_ns useTTL 0
//if 1 the packet transmission time
$pktConverter_ns useTxTime 0

value of the ns common header is used

//if 1 the previous hop ID value of the ns common header is used


$pktConverter_ns usePrevHop 0
//if 1 the next hop ID value of the ns common header is used
$pktConverter_ns useNextHop 0

2.1. Core Components

23

//number of bits to express the port value


$pktConverter_ns setPortBits 3
//number of bits to express the Time To Live (in number of hops or others)
$pktConverter_ns setTTLBits 4
//number of bits to express the packet transmission time
$pktConverter_ns setTxTimeBits 24
Common Converter:

//if 1 the information on if the packet is a request or response in the SUNSET common header i
$pktConverter_common useResponseBit 1
//if 1 the processing delay value in the SUNSET common header is used
$pktConverter_common useProcessingDelay 1
//if 1 the information on the estimated distance to the dest node in the SUNSET common header
$pktConverter_common useDistance 1
//if 1 the propagation delay value in the SUNSET common header is used
$pktConverter_common usePropagationDelay 1
Agent Converter:
//if 1 the source ID value in the agent packet header is used
$pktConverter_agt useSource 1
//if 1 the destination ID value in the agent packet header is used
$pktConverter_agt useDest 1
//if 1 the packet ID value in the agent packet header is used
$pktConverter_agt usePktId 0
//if 1 the payload in the agent packet header is used
$pktConverter_agt useData 1
When no packet fragmentation is assumed, the agent packet ID corresponds to the ns common packet ID. Therefore
only one of these two IDs is needed. In case of packet fragmentation, the ns common packet ID will be different
for all the packet, while the agent packet ID will be the same of the different fragments belonging to the same
agent packet.
CBR Converter:

24

Capitolo 2. Main Modules Description


//if 1 the timestamp value of the CBR packet header is used
$pktConverter_cbr use_timestamp 0
Mac Converter:
//if 1 the source ID value of the MAC
$pktConverter_mac useSource 1

packet header is used

//if 1 the destination ID value of the MAC


$pktConverter_mac useDest 1
//if 1 the packet ID value of the MAC
$pktConverter_mac usePktId 1

packet header is used

packet header is used

The use of the source and destination IDs at the MAC layer is not always needed. In fact, some acoustic modems
encode these information in the modem header and it is not needed to duplicate them in the packet payload to
further reduce the packet overhead. Other modems do not use these fields (or both of them) in their headers and
these have to be added in the packet payload to be then collected at the receiver nodes.
2.1.8

Energy Module

The SUNSET energy module provides a more accurate model to compute the energy consumption at each node and it
supports also the possibility to use different power transmission levels corresponding to a different energy consumption
at the node. Please take a look at Section 3.9 for further information and examples of usage.
2.1.9

Packet Error Model

The Packet Error Model Module permits to select or implement the preferred packet error model to be used when
running an experiment. It is mainly meant for simulations but it could be also used when the system is running in
emulation mode. Three different error models have been developed: BPSK, FSK and static. If the static model is
chosen, the user can set a value for the Packet Error Rate (PER), which is then used each time a packet is received by
a node. A random value will be computed and compared to the selected one in order to decide if the packet has to be
dropped or not. For the other two modules instead, the SNR and SNIR values are considered and the Bit Error Rate
(BER) and PER corresponding to the BPSK and FSK modulations are computed. These packet error models can be
used by each of the PHY modules provided in SUNSET.
Please, take a look at Section 3.12 for examples of usage.

2.2
2.2.1

Emulation Components
Generic Modem Module

When running in emulation and testing mode communication happens through real devices, i.e., acoustic modems. A
generic modem module has been implemented to take care of the modem interactions with ns-2.
This module is a generic interface. Each driver for a specific device extends the generic modem and implements the
different operations related to the specific driver using a language known by the specific acoustic modem (Application

2.2. Emulation Components

25

Programming Interface).
The generic modem module implements the connection to the external device and the basic operations that have to be
performed when transmitting and receiving data. It uses the packet converter functionalities to convert ns-2 packets in
streams of bytes for the specific device and vice versa. The generic modem module computes also the timing information
specific for the used device which have to be provided to the timing module for correct timeout computation at the
upper layers. Using the generic modem module, together with the timing module and the packet conversion module,
the presence of a simulated channel or of a real device is transparent to the protocol stack and no changes are needed
when moving from simulation to emulation mode.
Please take a look at Section 3.10 for further information and examples of usage.
2.2.2

Connections

SUNSET provides a generic connection module to create and handle several connection types: TCP, UDP and Serial.
Particularly, the TCP one is divided into client and server connection.
The base connection module class defines some basic functions which is supported by all the different modules:
virtual
virtual
virtual
virtual

bool open_connection() = 0;
//open a connection
bool close_connection() = 0;
//close a connection
int read_data(char *, int max_len) = 0;
int read_data(int, char *, int) = 0;
//read data from from the \
//given file descriptor
virtual bool write_data(char *, int ) = 0;
virtual bool write_data(int, char *, int ) = 0; //write data to the line with
//the given file descriptor
inline int get_fd() { return fd; }
//return the file descriptor
They are extended by all the different provided modules (TCP, UDP and Serial).
In particular, the behavior of the open_connection() changes according to the different type of connection:
Serial: it obtains a file descriptor and connects to the specified serial port with the specified baudrate.
TCP:
TCP Client: it opens a socket and connects to the specified IP at the specified port.
TCP Server: it opens a socket and listens to the specified IP at the specified port. Then the accept_connection()
function has to be called to accept new incoming connections.
UDP: It opens a socket to read and write data to the specified IP and port
Please, take a look at Section 3.16 for further information and examples of usage.
2.2.3

Channel Emulator

The Channel Emulator is a powerful tool provided by SUNSET to locally run tests emulating a real experiment using
the real-time scheduler and the other emulation components. Using this module it can be possible to check if everything
(i.e. timeout, packets conversion, etc.) has been set and tuned properly before running in field experiments.

26

Capitolo 2. Main Modules Description

The channel emulator supports the usage of multiple nodes. It can be combined with the blacklist capabilities (2.3.2)
of the PHY layer (2.3.1) and the packet error model provided by the related module (2.1.9) permitting to emulate a
multi-hop network with several nodes and variable links.
Using the provided channel emulator it is also possible to emulate node mobility updating the node position over time
or when some changes occur. Everything is done in a transparent way to the user/developer.
Please, take a look at Section 3.14 for further information and examples of usage.
Channel Emulator - Position

The Position Addon (Emulation_Components/Uw_Channels/Addon/Sunset_Position_Channel) extends the Sunset_Posi


class to provide and update the positions at the Channel Emulator in real time. This allows to properly simulate the
propagation delays while the network, which can be include static and mobile assets, is operating in the selected area.
Please, take a look at Section 3.14 for further information and examples of usage.

2.3
2.3.1

Network Protocols
Phy Module

The SUNSET Phy module implements the PHY layer of the protocol stacks. It can be used in Emulation mode and it uses
the Packet error model module 2.1.9, if enabled, to compute the error related to each received packet (see 2.1.9 and 3.12).
The Phy module considers also the transmission/reception delays according to the bitrate and the packet size in order
to emulate what would happen with real communication devices.
2.3.2

Blacklist

The Phy Module can be configured to blacklist some nodes in the network allowing to force multi-hop communications
or the presence of asymmetric links both in emulation or during sea trials.
Please, take a look at Section 3.13 and 6.2.2 for further information and examples of usage.

Chapter 3

Instructions and examples of usage


3.1

Suggestions when developing using SUNSET

Some suggestions when developing modules for SUNSET follow:


Create always a Debug object. These are named differently if simulation or emulation mode is considered: in the
latter case, the module must be also started. See Section 3.2.
Create always a Trace object. See Section 3.3.
All the modules must be started and stopped from the Tcl scripts, if some operations have to be performed by the
module at the beginning or at the end of the experiment. Moreover each module implementing the start()(stop())
function should call the related function of the class they extend from. I.e., see the Sunset_Csma_Aloha::start()
and Sunset_Csma_Aloha::stop() functions. It is also highly recommended to include any operation related to the
interaction with other modules or the initialization of variables depending on other modules in the start function
instead in the class constructor. The start function will be called after all the modules have been created avoiding
any problem of interaction with or access to the other modules.

3.2

Debug Module

Sunset_Debug is a static class.


To create the Debug module and set the debug level in the Tcl script we have:
set debug [new Sunset_Debug]
$debug setDebug
1 ;# debug level is set to 1
If simulation mode is considered. Instead if emulation mode is considered we have:
set debug [new Sunset_Debug_Emulation]
$debug setDebug 1 ;# debug level is set to 1
Moreover the module must be started as follows:
27

28

Capitolo 3. Instructions and examples of usage

$debug start
To dump debug information the function
debugInfo(int debugLevel, int addr, const char *fmt, ...)
is used. First parameter represents the debug level assigned to the information, second parameter is the ID of the
node/module printing the information (if no ID is assigned to a given module -1 can be used), the last parameter is
the message to dump. To set the node ID the setModuleAddress command must to be used. To each message the
debugInfo function adds the current time of the test (and the epoch time when running in emulation mode) and a new
line at the end of the message.
For example, when calling:
Sunset_Debug::debugInfo(3, nodeID, "Received pkt from src %d to dst %d", src, dst);
3 _DEBUG_ (15.000000) Node:3 - Received pkt from src 5 to dst 4
is printed on the standard output if the overall debug level selected by user in the Tcl script is higher or equal than 3,
where 15.0 is the time (seconds) since the experiment started.
When running in emulation mode also the epoch time (number of seconds from the Unix epoch) is dumped to ha a
global timing reference, if nodes are synchronized. In this case the message in output would be:
3 _DEBUG_ (15.000000) (1371205359.311897) Node:3 - Received pkt from src 5 to dst 4
Where (1371205359.311897) represents the epoch time.

3.3

Trace Module

The Trace module must be always created as follows:


set traceModule [new Sunset_Trace]
To dump trace information the function
print_info(const char *fmt, ...)
is used. Differently from the debugInfo in the Sunset_Debug module, no additional information or newline is added.
Only the information provided by the user are printed on the standard output. The information are always printed
without any check on potential trace level.
An example of using this function is:
Sunset_Trace::print_info("mac - (%.3f) Node:%d NEW DATA PACKET received from node %d

to %d \n", Sunse

printing on the standard output


mac - (152.543) Node:1 NEW DATA PACKET received from node 2

to 3

where the local time of the action is 152.543, the ID of the node printing the information is 1 and the received data
packet as node 2 as source ID and node 3 as destination ID at the MAC layer.

3.4. Information Dispatcher Module

3.4
3.4.1

29

Information Dispatcher Module


Using the Information Dispatcher in your modules

The Sunset_Information_Dispatcher is a static class.


To get a reference to the class, lets name it sid, the following instruction can be used.

Sunset_Information_Dispatcher* sid = Sunset_Information_Dispatcher::instance();


When a module wants to register itself to the Information Dispatcher it can uses:
int sid_id = sid->register_module(nodeID, "MODULE_NAME", this);
where MODULE_NAME is the name of the module (i.e., MAC_SLOTTED_CSMA). This function returns an int
value (sid_id) which is an ID assigned to the registered module and it is then used for the subsequent interactions with
the Information Dispatcher (if needed).
All the information provided to and requested from the Information Dispatcher use string as identifier. For example,
if a node is interested in the propagation delay to another node in the network, the string to identify this information
is "NODE_PROPAGATION_DELAY". The developer can use whatever string it wants but the same string has to be
used by all the modules interested in that information.
After the module has been registered to the Information Dispatcher, it can define new identification string which will
be then handled by the module using:
sid->define(nodeID, sid_id, "NODE_PROPAGATION_DELAY");
if such string has been already defined nothing is done at the Information Dispatcher level.
If a node wants to provide such information to the other modules it can inform the Dispatcher about it calling the
function:
sid->provide(nodeID, sid_id, "NODE_PROPAGATION_DELAY");
If instead it wants to be informed about it by the other modules it can use:
sid->subscribe(nodeID, sid_id, "NODE_PROPAGATION_DELAY");
It is recommended to add these calls in the start function of the module, which is called after all the modules have been
created.
For example, the generic MAC class (Sunset_Mac) creates the reference to the Information Dispatcher in its start()
function which is called by the Tcl script ( $mac($params(id)) start as in Tcl samples) few seconds after the starting
of the test:

30

Capitolo 3. Instructions and examples of usage

sid = Sunset_Information_Dispatcher::instance();
Similarly, the Slotted CSMA class (Sunset_SlottedCsma) in its start() function fist calls the super class method to
create the reference to the Information Dispatcher and then it registers the module and defines/provides/subscribes the
information it is interested in:
sid_id = sid->register_module(getModuleAddress(), "MAC_SLOTTED_CSMA", this);
sid->define(getModuleAddress(), sid_id, "NODE_PROPAGATION_DELAY");
sid->subscribe(getModuleAddress(), sid_id, "NODE_PROPAGATION_DELAY");
or in the Evologics modem driver (sunset_evologics_v1_6.cc):
sid_id = sid->register_module(getModuleAddress(), "EVO_MODEM_1.6", this);
sid->define(getModuleAddress(), sid_id, "NODE_PROPAGATION_DELAY");
sid->define(getModuleAddress(), sid_id, "TX_POWER");
sid->provide(getModuleAddress(), sid_id, "NODE_PROPAGATION_DELAY");
sid->subscribe(getModuleAddress(), sid_id, "TX_POWER");
To share the information among different modules the notified_info structure is used, which contains: 1) The string
identifying the information; 2) the ID of the node the information refers to; 3) the value for that information (it is a
void* since different values will be associated to the different strings); 4) the size in bytes for the info_value type to
allocate memory and read and write the specific value in the proper way; 5) the timestamp related to that information
to check its freshness.
The notified_info structure follows:
typedef struct notified_info {
string info_name;
int node_id;

// information name
// the ID of the node addressed by the information

void* info_value;

// information value

size_t info_size;

// information size in bytes

double info_time;

// information timestamp

} notified_info;
When a module has subscribed for a specific value it is then informed by the Information Dispatcher when a new value
has been provided by another module, using the notified_info function. All the modules subscribing for a specific value
have to implement this function.
We can take a look at the Slotted CSMA class:

3.4. Information Dispatcher Module

31

int Sunset_SlottedCsma::notify_info(list<notified_info> linfo)


{
list<notified_info>::iterator it = linfo.begin();
notified_info ni;
string s;
char msg[300];
memset(msg, \0, 300);
double val = 0.0;
for (; it != linfo.end(); it++) {
ni = *it;
s = "NODE_PROPAGATION_DELAY";
if (strncmp((ni.info_name).c_str(), s.c_str(), strlen(s.c_str())) == 0 ) {
sid->get_value(&val, ni); // it is used to get the related value
roundTripTime[ni.node_id] = 2.0 * val;
distanceToNode[ni.node_id] = (val * macTiming->getSoundSpeedInWater());
Sunset_Debug::debugInfo(1, getModuleAddress(), "Sunset_SlottedCsma::notify_info \
NODE_PROPAGATION_DELAY to %d val %f", ni.node_id, val);
return 1;
}
}
Sunset_Debug::debugInfo(-1, getModuleAddress(), "Sunset_SlottedCsma::notify_info \
NOTHING TO DO");
return Sunset_Mac::notify_info(linfo);
}
In the example above the timestamp information is not considered, since the notified_info function is called as soon
as an update on the value is notified. In case the developer wants to verify the timestamp information and eventually
discard old data it could check the ni.info_time and compare it an arbitrary timestamp GIVEN_TIME:
if (ni.info_time < GIVEN_TIME ) {
return 0;
}

When instead a node provides a given information it fills the notified_info structure and sends it to the Information Dispatcher in order to inform the interested (registered) modules about it. An example is the "NODE_PROPAGATION_DELA
which is provided by the Evologics modem driver.
void Sunset_Evologics_v1_4::setDelayToNode(int node, double delay_usec)

32

Capitolo 3. Instructions and examples of usage

{
...
if (sid == NULL) {
Sunset_Debug::debugInfo(-1, getModuleAddress(), "Sunset_Evologics_v1_4::setDelayToNode \
DISPATCHER NOT DEFINED");
return;
}
notified_info ni1;
ni1.node_id = node;

// the ID of the node for which the current node


// has estimated the propagation delay
ni1.info_time = NOW;
// information timestamp
ni1.info_name = "NODE_PROPAGATION_DELAY";
// assigned_value is used to assign the related value in the data structure
if ( sid->assign_value(&delay, &ni1, sizeof(double)) == false) {
Sunset_Debug::debugInfo(-1, getModuleAddress(), "Sunset_Evologics_v1_4::setDelayToNode \
ERROR ASSIGINING INFO %s", (ni1.info_name).c_str());
return;

}
// the set function provides the notified_info structure to the Information Dispatcher
if ( sid->set(getModuleAddress(), sid_id, ni1) == 0 ) {
Sunset_Debug::debugInfo(-1, getModuleAddress(), "Sunset_Evologics_v1_4::setDelayToNode \
PROVIDING INFO %s NOT DEFINED", (ni1.info_name).c_str());
}
Sunset_Debug::debugInfo(2, getModuleAddress(), "Sunset_Evologics_v1_4::setDelayToNode \
node %d delay %f distance %f", node, delay, distanceToNode[node].first);
}
To request the value for a given information the module is subscribed to, without waiting for new incoming notification
from the Information Dispatcher, the module can use the get function. In this case the information freshness should be
checked.
int get(int nodeID, int sid_id, string parameter, int node, notified_info& ni);
For example, if node 3 wants to request the propagation delay estimation to node 5 it can directly use:
notified_info ni;
sid->get(getModuleAddress(), sid_id, "NODE_PROPAGATION_DELAY", 5, ni);

3.5. Timing Module

33

The notified_info structure will then be filled with the request information and it will return 1. If no information are
available, the get function will return 0.
3.4.2

Set the Information Dispatcher in Tcl script

The Information Dispatcher has to be properly configured and started in the Tcl script. From the samples/simulation/runSU
...
Module/Sunset_Information_Dispatcher set debug_ false
set info_dispatcher [new Module/Sunset_Information_Dispatcher]
##################################
# Configure information dispatcher
##################################
$info_dispatcher addParameter $params(id)
$info_dispatcher addParameter $params(id)
$info_dispatcher addParameter $params(id)
$info_dispatcher addParameter $params(id)
...

"MAC_RESET"
"MAC_TX_DONE"
"MAC_TX_ABORT"
"MAC_TX_COMPLETED"

The addParameter command adds a parameter to the Information Dispatcher that can be requested or provided by the
registered modules. Therefore, if the user want to use the Slotted Csma MAC protocol and it wants to notify/receive
the node propagation delay information, or any other information, it can add the related parameter to the Information
Dispatcher as follows:
$info_dispatcher addParameter $params(id) "NODE_PROPAGATION_DELAY"
The user must start the Information Dispatcher module from the Tcl script:
$info_dispatcher start

3.5

Timing Module

In the Timing Module the following functions have been implemented:


To compute the time needed to transmit a given number of bytes:
virtual double txtime(int size, sunset_rateType rate = TIMING_DATA_RATE);
double txtime(int size, double rate);

Where in the first case predefined rates (bitrates) are considered: TIMING_DATA_RATE or TIMING_CTRL_RATE
In the second case an arbitrary value is considered. It is defined in the Tcl script and it could be a simulative value
or a value corresponding to the characteristics of a real acoustic modem.

34

Capitolo 3. Instructions and examples of usage


To return the final packet size needed to transmit a given amount of Bytes, considering also additional bytes due
to the conversion operations, when running in emulation mode, and the eventual additional bytes added by the
communication device.
virtual int getPktSize (int dataSize);
virtual int getPktSize (Packet* p);

To return the delay needed to transfer the given amount of Bytes over the communication line to the device (Serial
line, Ethernet, etc.).
//size is assumed to be in Bytes
double transfertTime(int size);

To return the delay related to the operations of the device running the entire framework (PC, Gumstix, IGEP, or
other computational devices):
double getDeviceDelay();

It can be set by the user in the Tcl script as follows (from samples/emulation/runEmulationEvologics.tcl):
Sunset_Timing_Emulation set deviceDelayCtrl_ $params(device_ctrl_delay)
Sunset_Timing_Emulation set deviceDelayData_ $params(device_data_delay)
Sunset_Timing_Emulation set deviceDelay_
$params(device_delay)

Different delays related to data or control packet operations can be considered.


To return the bit rate of the given device, which can change according to the device settings that can be modified
at run time:
double getDataRate();

It can be set by the user in the Tcl script as follows (from samples/emulation/runEmulationEvologics.tcl):
Sunset_Timing_Emulation set dataRate_ $params(evo_data_bitrate)
Sunset_Timing_Emulation set ctrlRate_ $params(evo_ctrl_bitrate)

3.5. Timing Module

35

Different bitrates related to data or control packet transmissions can be considered.


To return the delay related to the operations of the considered acoustic modem:
double getModemDelay();

It can be set by the user in the Tcl script as follows (from samples/emulation/runEmulationEvologics.tcl):
Sunset_Timing_Emulation set modemDelay
Sunset_Timing_Emulation set modemDelayCtrl_
Sunset_Timing_Emulation set modemDelayData_

$params(evo_delay)
$params(evo_ctrl_delay)
$params(evo_data_delay)

Different delays related to data or control packet operations can be considered.


To return the maximum propagation delay assumed in the network:
double getMaxPropagationDelay() { return maxPropagationDelay; }

It can be set by the user in the Tcl script as follows (from samples/emulation/runEmulationEvologics.tcl):
Sunset_Timing_Emulation set pDelay_ $params(propagationDelay)

To return the considered Short InterFrame Space:


double getSIFS();

It can be set by the user in the Tcl script as follows (from samples/emulation/runEmulationEvologics.tcl):
Sunset_Timing_Emulation set sifs_ 0.0

To return the considered sound speed in water, it could be statically set or collected from on board sensors.
double getSoundSpeedInWater();

To return the overhead in terms of delay to transmit a given amount of bytes considering the running platform
and the communication device.
double overheadTime(int size);

36

3.6

Capitolo 3. Instructions and examples of usage

Packet Converter

To make more clear the use of the Packet Converter functions and show how to configure the parameters in the Tcl
scripts, in what follows we consider the HDR_SUNSET_AGT packet and how its packet header converter implements
the required functions.
The structure containing the information of the agent packet header is:
struct sunset_agt_control
{
u_char ac_type
u_char ac_subtype
u_char ac_protocol_version
};

: 3; // type of the Agent packet.


: 3; // subtype of the Agent packet.
: 2; // version of the Agent packet.

/*! @brief The Agent packet header */


typedef struct hdr_Sunset_Agent
{
struct sunset_agt_control ac;
int pkt_id;
int src_id;
int dst_id;
char* data; /* This is the packet payload */
int data_size;
/* Functions to access to the packet fields */
inline
inline
inline
inline
inline

int& pktId() {return (pkt_id);}


int& dataSize() {return (data_size);}
int& srcId() {return (src_id);}
int& dstId() {return (dst_id);}
char* getData() { return data; }

static int offset_;


inline static int& offset() { return offset_; }
inline static hdr_Sunset_Agent* access(const Packet* p) {
return (hdr_Sunset_Agent*) p->access(offset_);
}
} hdr_Sunset_Agent;
It includes source ID and destination ID, packet ID, the size in bytes of the payload, a char* field for the payload and

3.6. Packet Converter

37

control information (sunset_agt_control) for packet type and subtype and protocol version.
The header packet converter for this specific packet header is implemented in the class Sunset_AgtPktConverter.
To check if for a given packet the packet header converter has to perform any conversion operations the checkPktLevel(Packet* p) is considered. It first considers the packet type, if it is an AGENT packet (originated at the agent
layer) it has to be considered and the function return 1, otherwise it could be a packet coming from the upper layer
and it checks the packet type and subtype to verify if agent header information have been written in the packet. If this
is the case it returns 1, 0 otherwise. If for example, this is a packet generated at the MAC layer (or at any other lower
layer) all the fields in the agent packet will be zero and the function will return 0.
/!*
*
*
*
*
*/

@brief The checkPktLevel function checks if the agent header


converter has to convert its header information in the specified packet.
@param p The received packet.
@retval 1 The packet contains the agent header.
@retval 0 The packet does not contain the agent header.

int Sunset_AgtPktConverter::checkPktLevel(Packet* p)
{
struct hdr_Sunset_Agent *gh = hdr_Sunset_Agent::access(p);
u_int8_t type = gh->ac.ac_type;
u_int8_t subtype = gh->ac.ac_subtype;
// if the packet type is PT_SUNSET_AGT, the packet has
// been created by an agent module and data conversion is needed
if (HDR_CMN(p)->ptype() == PT_SUNSET_AGT) {
return 1;
}
// if the packet type is not PT_SUNSET_AGT but agent
// information have been set data conversion is needed
switch(type) {
case SUNSET_AGT_Type_Data:
switch(subtype) {
case SUNSET_AGT_Subtype_Data:
return 1;

38

Capitolo 3. Instructions and examples of usage

case SUNSET_AGT_Subtype_Request:
return 1;
case SUNSET_AGT_Subtype_Response:
return 1;
default:
Sunset_Debug::debugInfo(3, -1, "Sunset_Agent::getBufferInfoLength DATA type \
%d subtype %d", type, subtype);
return 0;
}
break;
default:
Sunset_Debug::debugInfo(3, -1, "Sunset_Agent::getBufferInfoLength default type %d", type);
return 0;
}
Sunset_Debug::debugInfo(5, -1, "Sunset_AgtPktConverter::checkPktLevel");
return 0;
}
To make the user free to convert only the information it is interested in, the Sunset_AgtPktConverter has different
fields: use_source; use_dest; use_pktId and use_data. According to the setting for these values, the related information are then considered. The user could decide not to use the pktId field or source and destination IDs if not
needed or if this information is already added by some other packet converter headers, to save bits when transmitting
a packet in water.
Moreover, the user can also specify the number of bits to use for any field of the packet header. If less than 8 nodes are
in the network 3 bits can be used to code the source and destination IDs, if more nodes are in the network a higher
number of bits has to be used (an example will follow below in the document). When running in emulation mode, the
ID 0 is usually a reserved ID which is used for the broadcast address. SUNSET allows also to change it, but since several
modems do not permit to use 0 as a valid ID for the nodes it makes sense to use it as the broadcast address used in the
protocol stack, which is then translated into the real modem broadcast address at the modem driver layer.
The selection on the packet fields to consider can be done when creating the class using the bind function:

3.6. Packet Converter


bind("use_source", &use_source);
bind("use_dest", &use_dest);
bind("use_pktId", &use_pktId);
bind("use_data", &use_data);
or using the command function:
int Sunset_AgtPktConverter::command( int argc, const char*const* argv)
{
Tcl& tcl = Tcl::instance();
if (argc == 3) {
/* The "useSource" command is set to 1 if the source ID has to be
considered during the
conversion of the ns-2 packet into a stream
of bytes for external devices transmissions. */
if (strcmp(argv[1], "useSource") == 0) {
use_source = atoi(argv[2]);
return TCL_OK;
}

/* The "useDest" command is set to 1 if the destination ID has to be


considered during the conversion of the ns-2 packet into a stream
of bytes for external devices transmissions. */
if (strcmp(argv[1], "useDest") == 0) {
use_dest = atoi(argv[2]);
return TCL_OK;
}
/* The "usePktId" command is set to 1 if the packet ID has to be
considered during the conversion of the ns-2 packet into a stream
of bytes for external devices transmissions. */
if (strcmp(argv[1], "usePktId") == 0) {
use_pktId = atoi(argv[2]);
return TCL_OK;
}

39

40

Capitolo 3. Instructions and examples of usage


/* The "useData" command is set to 1 if the data payload has to be
considered during the conversion of the ns-2 packet into a stream of
bytes for external devices transmissions. */
if (strcmp(argv[1], "useData") == 0) {
use_data = atoi(argv[2]);
return TCL_OK;
}
}
return Sunset_PktConverter::command(argc, argv);

}
The setting of these values is performed in the Tcl script. First we can assign the number of bits commonly used by the
different packet header conversion (as described also above):
Sunset_PktConverter
Sunset_PktConverter
Sunset_PktConverter
Sunset_PktConverter

set
set
set
set

ADDR_BITS
DATA_BITS
PKT_ID_BITS
TIME_BITS

3
8
14
24

We can then create the packet header converter and the packet converter related to the agent layer:
set pktConverter [new Sunset_PktConverter]
...
set pktConverter_agt [new Sunset_PktConverter/Agent]
...
We can therefore set the packet header fields to use:
$pktConverter_agt
$pktConverter_agt
$pktConverter_agt
$pktConverter_agt

useSource 1
useDest 1
usePktId 0 ;# here we are not using the pktId field
useData 1

We need to then register the agent packet header to the generic packet header where $agt_level is the level for this
packet header converter in the protocol stack:
$pktConverter addPktConverter $agt_level $pktConverter_agt
An example of complete stack could be (from samples/emulation/channelEmulator.tcl):
$pktConverter
$pktConverter
$pktConverter
$pktConverter

addPktConverter
addPktConverter
addPktConverter
addPktConverter

3
2
1
0

$pktConverter_agt
$pktConverter_rtg
$pktConverter_mac
$pktConverter_ns

3.6. Packet Converter

41

These information are then used in the different packet converter class functions as described below.
When computing the size in bits for the agent packet header, the getHeaderSizeBits() is used. The getAddrBits()
function returns the number of bits assigned to the node ID field (3 bits as in the setting presented above); the
getPktIdBits() returns the number of bits assigned to the packet ID field (14 bits as in the setting presented
above); the getDataBits() function returns the number of bits assigned to express the payload size (8 bits as in the
setting presented above, which means a maximal size for the payload of 255 Bytes). Moreover, when converting a
packet also few bits (getLevelIdBits()) are added to identify the specific module header ID which is needed for a
correct conversion from a stream of bits to an ns-2 packet.
/*! @brief The getHeaderSizeBits returns the bits size of
* the agent layer header for the converted packet. The data payload
* is not considered.
*/
int Sunset_AgtPktConverter::getHeaderSizeBits()
{
int len = 0;
//control information in the agent header
len += ((int)(sizeof(struct sunset_agt_control))) * 8;
// According to the used header values, the corresponding number
// of bits needed during the conversion process is computed
if (use_source) {
len += getAddrBits(); //source id
}
if (use_dest) {
len += getAddrBits(); //dest id
}
if (use_pktId) {
len += getPktIdBits(); // packet id
}
if (use_data) {
len += getDataBits(); //source id
}

42

Capitolo 3. Instructions and examples of usage

len += getLevelIdBits(); // information about the packet header converter


// ID has to be always added to allow for correct conversion
Sunset_Debug::debugInfo(3, -1,

"Sunset_AgtPktConverter::getHeaderSizeBits length %d", len);

return len;
}
When computing the size in bits needed to convert the agent packet header information for the packet in input,
the getConvertedInfoLength() is used. This time also the amount of bits needed by the payload is considered.
/*!
*
*
*
*
*/

@brief The getConvertedInfoLength function returns the total bits


size of the converted agent packet header including the payload of a
specific packet.
@param p The considered packet.
@retval len The total headers size.

int Sunset_AgtPktConverter::getConvertedInfoLength(Packet* p)
{
int len = 0;
//control information in the agent header
len += ((int)sizeof(struct sunset_agt_control)) * 8;
// packet header converter ID bits
len += getLevelIdBits();
// According to the used header values, the corresponding number of
// bits needed during the conversion process is computed
if (use_source) {
len += getAddrBits(); //source id
}
if (use_dest) {
len += getAddrBits(); //dest id
}
if (use_pktId) {

3.6. Packet Converter

43

len += getPktIdBits();
}
if (use_data) {
len += getDataBits(); /* bits to store the size of the payload */
Sunset_Debug::debugInfo(3, -1, "Sunset_AgtPktConverter::getConvertedInfoLength \
data %d dataSizeB %d", len, HDR_SUNSET_AGT(p)->dataSize() * 8);
len += HDR_SUNSET_AGT(p)->dataSize() * 8; /* data payload */
}
Sunset_Debug::debugInfo(3, -1, "Sunset_AgtPktConverter::getConvertedInfoLength \
lengthBit %d lenghtByte %d data %d", len, (int)ceil((double)len/8.0),
HDR_SUNSET_AGT(p)->dataSize());
return len;
}
When converting an ns-2 packet into a stream of bits the pkt2Buffer() function is used. For each considered field
the corresponding amount of bits are written in the buffer. This function returns the amount of bits written to
the buffer, -1 in case of errors:
/*!
*
*
*
*
*
*
*
*
*/

@brief The pkt2Buffer function copies all the necessary information


from a ns-packet to a buffer at a specified offset.
@param level The layer ID of the agent header converter.
@param p A packet from which getting the information.
@param buffer The destination buffer that contains the packet information
of all the stack layers.
@param offset The offset of buffer from which to start writing information.
@retval size The bit size of the information written.

int Sunset_AgtPktConverter::pkt2Buffer(int level, Packet* p, char* buffer, int offset)


{
int aux = 0;
int size = 0;
// get the number of bits that have to be written by this packet header converter
aux = getConvertedInfoLength(p);

44

Capitolo 3. Instructions and examples of usage


if (aux == 0) {
return 0;
}
size = getLevelIdBits();
// information about the packet header converter ID has to be always
// written to allow for correct conversion
setBits(buffer, (char *)(&(level)), size, offset);
setBits(buffer, (char *)(&(HDR_SUNSET_AGT(p)->ac)),
(int)((sizeof(sunset_agt_control)) * 8), offset + size);
size += (int)((sizeof(sunset_agt_control)) * 8);
// According to the used header values, the corresponding number of bits
// needed during the conversion process is written
if (use_source) {
setBits(buffer, (char *)(&(HDR_SUNSET_AGT(p)->srcId())), getAddrBits(), offset + size);
size += getAddrBits();
}
if (use_dest) {
setBits(buffer, (char *)(&(HDR_SUNSET_AGT(p)->dstId())), getAddrBits(), offset + size);
size += getAddrBits();
}
if (use_pktId) {
setBits(buffer, (char *)(&(HDR_SUNSET_AGT(p)->pktId())), getPktIdBits(), offset + size);
size += getPktIdBits();
}
if (use_data) {
setBits(buffer, (char *)(&(HDR_SUNSET_AGT(p)->dataSize())),
getDataBits(), offset + size);
size += getDataBits();
if ((HDR_SUNSET_AGT(p)->dataSize()) > 0) {

3.6. Packet Converter

45

setBits(buffer, (HDR_SUNSET_AGT(p)->getData()), (HDR_SUNSET_AGT(p)->dataSize() * 8),


offset + size);
size += (HDR_SUNSET_AGT(p)->dataSize() * 8);
Sunset_Debug::debugInfo(5, -1, "Sunset_AgtPktConverter::pkt2Buffer AGENT data \
len %d msg:%s", (HDR_SUNSET_AGT(p)->dataSize()),
HDR_SUNSET_AGT(p)->data);
}
else {
Sunset_Debug::debugInfo(5, -1, "Sunset_AgtPktConverter::pkt2Buffer AGENT
data NO DATA");
}
}
// if less bits are written w.r.t. the ones computed using the getConvertedInfoLength
// an error occurrs and 0 bits are added to the packet
if (aux != size) {
Sunset_Debug::debugInfo(-1, -1, "Sunset_AgtPktConverter::pkt2Buffer buffer \
filled ERROR aux %d size %d bits", aux, size);
exit(1);
}
Sunset_Debug::debugInfo(5, -1, "Sunset_AgtPktConverter::pkt2Buffer type %d subtype \
%d version %d src %d dst %d pktId %d dataSize %d",
HDR_SUNSET_AGT(p)->ac.ac_type, HDR_SUNSET_AGT(p)->ac.ac_subtype,
HDR_SUNSET_AGT(p)->ac.ac_protocol_version,
HDR_SUNSET_AGT(p)->srcId(), HDR_SUNSET_AGT(p)->dstId(),
HDR_SUNSET_AGT(p)->pktId(), HDR_SUNSET_AGT(p)->dataSize());
Sunset_Debug::debugInfo(5, -1, "AGENT data %s", HDR_SUNSET_AGT(p)->data);
Sunset_Debug::debugInfo(5, -1, "Sunset_AgtPktConverter::pkt2Buffer buffer \
filled size %d bits", size);
return size;
}
When converting a stream of bits into an ns-2 packet, the buffer2Pkt function is used. For each considered field
the corresponding amount of bits are read from the buffer. This function returns the amount of bits read form the
buffer, -1 in case of errors:

46

Capitolo 3. Instructions and examples of usage


/*!
*
*
*
*
*
*
*
*
*
*/

@brief The pkt2Buffer function copies all the necessary information


from a buffer at a specified offset to a ns-packet.
@param level The layer ID of the agent header converter.
@param p The packet that will contain the information taken from the buffer.
@param buffer The source buffer that contains the packet
information of all the stack layers.
@param offset The offset used when starting to read from the buffer.
@param bits The number of bits to be read.
@retval size The number of bits read from the buffer.

int Sunset_AgtPktConverter::buffer2Pkt(int level, Packet* p, char* buffer,


int offset, int bits)
{
int length = 0;
struct hdr_ip* iph = HDR_IP(p);
int size = getLevelIdBits();
int info_level = 0;
// check if there are enough bits to read the packet header converter ID
if (bits < size) {
Sunset_Debug::debugInfo(5, -1, "Sunset_AgtPktConverter::buffer2Pkt check bits1
bits %d size %d", bits, size);
return 0;
}
// read the packet header converter ID
getBits(buffer, (char *)(&(info_level)), size, offset);
// check if the packet header converter ID corresponds to my ID
if (info_level != level) {
return 0;
}
// check if there are enough bits to read the packet header converter info
if (bits < getHeaderSizeBits()) {

3.6. Packet Converter

47

Sunset_Debug::debugInfo(5, -1,
"Sunset_AgtPktConverter::buffer2Pkt check bits2 bits %d size %d",
bits, getHeaderSizeBits());
return -1;
}
HDR_SUNSET_AGT(p)->srcId() = 0;
HDR_SUNSET_AGT(p)->dstId() = 0;
HDR_SUNSET_AGT(p)->pktId() = 0;
HDR_SUNSET_AGT(p)->dataSize() = 0;
getBits(buffer, (char *)(&(HDR_SUNSET_AGT(p)->ac)), (int)((sizeof(sunset_agt_control)) * 8),
offset + size);
size += (int)((sizeof(sunset_agt_control)) * 8);
// According to the used header values, the corresponding number of bits
// needed during the conversion process is written
if (use_source) {
int srcId = 0;
getBits(buffer, (char *)(&(srcId)), getAddrBits(), offset + size);
size += getAddrBits();
HDR_SUNSET_AGT(p)->srcId() = srcId;
iph->saddr() = HDR_SUNSET_AGT(p)->srcId();
}
if (use_dest) {
int dstId = 0;
getBits(buffer, (char *)(&(dstId)), getAddrBits(), offset + size);
size += getAddrBits();
HDR_SUNSET_AGT(p)->dstId() = dstId;
iph->daddr() = HDR_SUNSET_AGT(p)->dstId();
}
if (use_pktId) {

48

Capitolo 3. Instructions and examples of usage


int pktId = 0;
getBits(buffer, (char *)(&(pktId)), getPktIdBits(), offset + size);
size += getPktIdBits();
HDR_SUNSET_AGT(p)->pktId() = pktId;
}
else {
HDR_SUNSET_AGT(p)->pktId() = HDR_CMN(p)->uid();
}
if (use_data) {
int dataSize = 0;
getBits(buffer, (char *)(&(dataSize)), getDataBits(), offset + size);
size += getDataBits();
HDR_SUNSET_AGT(p)->dataSize() = dataSize;
length += (HDR_SUNSET_AGT(p)->dataSize());
HDR_CMN(p)->size() += length;
if ((HDR_SUNSET_AGT(p)->dataSize()) > 0 ) {
HDR_SUNSET_AGT(p)->data = (char*)(malloc((int)(HDR_SUNSET_AGT(p)->dataSize()) + 1));
memset(HDR_SUNSET_AGT(p)->data, 0x0, (int)(HDR_SUNSET_AGT(p)->dataSize() + 1));
getBits(buffer, (HDR_SUNSET_AGT(p)->data), HDR_SUNSET_AGT(p)->dataSize() * 8,
offset + size);
size += HDR_SUNSET_AGT(p)->dataSize() * 8;
//HDR_SUNSET_AGT(p)->getData() = HDR_SUNSET_AGT(p)->data;
Sunset_Debug::debugInfo(5, -1, "Sunset_AgtPktConverter::buffer2Pkt AGENT \
data len %d msg:%s", (HDR_SUNSET_AGT(p)->dataSize()),
HDR_SUNSET_AGT(p)->data);
}
else {

3.6. Packet Converter

49

Sunset_Debug::debugInfo(5, -1, "Sunset_AgtPktConverter::buffer2Pkt AGENT


data NO DATA");
}
}
Sunset_Debug::debugInfo(5, -1, "Sunset_AgtPktConverter::buffer2Pkt type %d \
subtype %d version %d src %d dst %d pktId %d dataSize %d length %d",
HDR_SUNSET_AGT(p)->ac.ac_type, HDR_SUNSET_AGT(p)->ac.ac_subtype,
HDR_SUNSET_AGT(p)->ac.ac_protocol_version, HDR_SUNSET_AGT(p)->srcId(),
HDR_SUNSET_AGT(p)->dstId(), HDR_SUNSET_AGT(p)->pktId(),
HDR_SUNSET_AGT(p)->dataSize(), length);
Sunset_Debug::debugInfo(5, -1, "Sunset_AgtPktConverter::buffer2Pkt agent info \
for the packet have been set length %d", length);
return size;
}
When a packet has to be erased (using the Sunset_Utilities::erasePkt function), if running in emulation, the packet
converter is in charge to erase the memory allocated by each of the registered packet headers, if any. For the agent
packet header converter, it first checks if the packet in input has to be considered by this converter and it then
checks if the data payload field is used and it is different from NULL. If it is the case, the allocated memory is
erased.
/*!
*
*
*
*
*/

@brief
stored
@param
@param

The erasePkt erases the packet and the data payload


in the agent header.
level The layer ID of the agent header converter.
p The packet to be erased.

void Sunset_AgtPktConverter::erasePkt(int level, Packet* p)


{
if ( checkPktLevel(p) ) {
if (use_data && HDR_SUNSET_AGT(p)->getData() != NULL) {
//remove the memory allocated for the packet payload
free(HDR_SUNSET_AGT(p)->getData());
HDR_SUNSET_AGT(p)->data = NULL;
}

50

Capitolo 3. Instructions and examples of usage


}
}
To allow the other modules to collect packet header information without knowing the specific protocol solutions and
packet headers used at the different layers, support functions have been added to the Packet Converter module
which are then implemented by the different modules. The interested module just need to ask to the packet
converter the packet field it wants to collect, specifying also the protocol layer, which corresponds to the packet
header, it is interested in. For example the functions to collect source and destination IDs of a given packet for the
agent packet header converter are presented below, where the sunset_header_type has to be UW_PKT_AGENT
to collect application layer information.
/*!
@brief The getSrc function is used to obtain the source ID for the agent packet header.
*
@param level The layer ID of the agent header converter.
*
@param p The packet.
*
@param m The packet header selected for checking.
*
@param[out] src The Agent source ID is written by the packet header
* converter in the src variable.
*
@retval 1 if the packet header is the one has been selected
* according to m value, 0 otherwise.
*/
int Sunset_AgtPktConverter::getSrc(int level, Packet* p, sunset_header_type m, int& src)
{
if (m == UW_PKT_AGENT) {
src = HDR_SUNSET_AGT(p)->srcId();
return 1;
}
return 0;
}
/*!
@brief The getDst function is used to obtain the destination ID for the
* MAC packet header.
*
@param level The layer ID of the MAC packet header converter.
*
@param p The packet.
*
@param m The packet header selected for checking.
*
@param[out] dst The MAC destination ID is written by the packet header
* converter in the dst variable.
*
@retval 1 if the packet header is the one has been selected according
* to m value, 0 otherwise.
*/
int Sunset_MacPktConverter::getDst(int level, Packet* p, sunset_header_type m, int& dst)

3.7. Utilities Modules

51

{
// check if this is a MAC packet
if (m == UW_PKT_MAC) {
dst = HDR_SUNSET_MAC(p)->dst;
return 1;
}
return 0;
}

Please take a look at Sections 3.6and 3.15.1 for further information and examples of usage.

3.7
3.7.1

Utilities Modules
Simulation/Emulation running mode

Sunset_Utilities is a static class. To check if the system is running in simulation or emulation mode the functions
Sunset_Utilities::isSimulation() or Sunset_Utilities::isEmulation()
can be used. The isSimulation() function returns 1 if the system is running in simulation mode, 0 otherwise. Similarly,
the isEmulation() function returns 1 if the system is running in emulation mode, 0 otherwise.
3.7.2

Scheduling new events

When using SUNSET to schedule a new event, instead of calling the basic ns-2 schedule function, the Sunset_Utilities
schedule function should be used
static void schedule(Handler*, Event*, double delay);
just calling Sunset_Utilities::schedule(...).
It takes the same parameters such as the basic ns-2 function. When running in simulation mode it will then call the
basic ns-2 schedule function, when running in emulation mode, instead, it will use the SUNSET Real-time scheduler class.
A new timer can be defined as follows (from the MAC timer defined in Network_Protocols/Datalink/Sunset_Mac):
class Sunset_Mac_Timer : public Handler
{
public:
Sunset_Mac_Timer(Sunset_Mac* m) : mac(m)
{

52

Capitolo 3. Instructions and examples of usage


busy_ = paused_ = 0; stime = rtime = 0.0;
}
// the handle() is a pure function (the other extending timers)
// have to define it.
virtual void handle(Event *e) = 0;
virtual void start(double time);
virtual void stop(void);
....
inline double expire(void)
{
Scheduler& s = Scheduler::instance();
return ((stime + rtime) - s.clock());
}

protected:
Sunset_Mac
*mac;
int
busy_;
int
paused_;
Event
intr;
double
stime;
double
rtime;
};

// start time
// remaining time

The implementation of the start() and stop() functions are really simple and similar to what should be done for the basic
ns-2 timers. The only difference is the use of the Sunset_Utilities::schedule() function instead of the basic schedule() in
the start() function:
void Sunset_Mac_Timer::start(double time)
{
Scheduler& s = Scheduler::instance();
if (busy()) {
if (rtime - stime > time) {
return;
}
stop();
}

3.8. Statistics Module

53

busy_ = 1;
paused_ = 0;
s.sync();
stime = s.clock();
rtime = time;
assert(rtime >= 0.0);
// events are scheduled using the Sunset_Utilities schedule function,
// which will call the appropriate scheduler if running in simulation
// or emulation mode.
Sunset_Utilities::schedule(this, &intr, rtime);
}
void Sunset_Mac_Timer::stop(void)
{
Scheduler& s = Scheduler::instance();
if(paused_ == 0)
s.cancel(&intr);
busy_ =
paused_
stime =
rtime =

0;
= 0;
0.0;
0.0;

}
3.7.3

Erasing data packets

When an ns-2 packet, lets say p, is not needed and it has to be erased, instead of calling the basic Packet::free(p) function,
the Sunset_Utilities::erasePkt(p, nodeID) function should be used. This function will call the basic Packet::free method
when running in simulation mode. When running in emulation mode instead, it will use the Packet Converter 3.6 to
erase the memory allocated to store the packet payload and other fields, if any. In case the developer already knows
that no memory has been allocated for the intended packet the Sunset_Utilities::eraseOnlyPkt(p, nodeID) can be used.

3.8

Statistics Module

Different kind of actions have been defined in the Sunset_Statistics class:


typedef enum {
SUNSET_DEBUG = -1,
SUNSET_STAT_AGENT_TX = 1,
SUNSET_STAT_AGENT_RX = 2,
SUNSET_STAT_ENQUE = 3,

54

Capitolo 3. Instructions and examples of usage


SUNSET_STAT_QUEUE_DISCARD = 4,
SUNSET_STAT_DEQUE = 5,
SUNSET_STAT_MAC_BACKOFF = 6,
SUNSET_STAT_MAC_TX = 7,
SUNSET_STAT_MAC_DISCARD = 8,
SUNSET_STAT_MAC_RX = 9,
SUNSET_STAT_MODEM_GET_PKT = 10,
SUNSET_STAT_MODEM_TX_START = 11,
SUNSET_STAT_MODEM_TX_DONE = 12,
SUNSET_STAT_MODEM_RX_START = 13,
SUNSET_STAT_MODEM_RX_DONE = 14,
SUNSET_STAT_MODEM_RX_PKT = 15,
SUNSET_STAT_MODEM_INFO = 16,
SUNSET_STAT_MAC_NAV = 17,
SUNSET_STAT_MODEM_TX_ABORTED
= 18,
SUNSET_STAT_MODEM_TRANSFERT_START = 19,
SUNSET_STAT_MODEM_TRANSFERT_END = 20,
SUNSET_STAT_MODEM_RX_ABORTED
= 21,
SUNSET_STAT_MAC_CHANNEL_BUSY = 22,
SUNSET_STAT_MAC_NO_REPLY = 23,
SUNSET_STAT_MAC_RX_ERROR = 24,
SUNSET_STAT_MAC_TX_DONE = 25,
SUNSET_STAT_MAC_TX_ABORTED = 26,
SUNSET_STAT_MAC_NEW = 27,
SUNSET_STAT_ENERGY_TX = 28,
SUNSET_STAT_ENERGY_RX = 29,
SUNSET_STAT_ENERGY_IDLE = 30

} sunset_statisticType;
When for example the agent layer create a new message this can be notified to the statistics class using:
stat->printInfo(SUNSET_STAT_AGENT_TX, getModuleAddress(), p, HDR_CMN(p)->timestamp(), "");
the reception of a new message at the agent layer can be logged using:
stat->printInfo(SUNSET_STAT_AGENT_RX, getModuleAddress(), p, HDR_CMN(p)->timestamp(), "");
or at the MAC layer using:
stat->printInfo(SUNSET_STAT_MAC_RX, getModuleAddress(), p, HDR_CMN(p)->timestamp(), "");
Once the information are logged into the statistic class, this class extracts the required data from the packet (if it is
a control or data packet, packet size, etc.) and stores them in its own data structures. The user can then collect the
required metrics using some of the functions implemented by this class:

3.8. Statistics Module

55

Agent Layer

The experiment duration in seconds:


getExperimentTime

Information related to the Packet Delivery Network.


The Packet Delivery Network in the network:
double getPDR();

Packet Delivery Network in the network between src node and dst node.
double getPDR(int src, int dst);

Information related to data packets generated.


The number of data packets generated at the application layer in the network:
double getGeneratedPacket();
The number of data packets generated at the application layer by the src node.
double getGeneratedPacket(int src);
The number of bytes generated by the src node to the dst node:
int getGeneratedBytes(int src, int dst)
Information related to data packets delivered.
The number of data packets correctly delivered at the application layer with no repetitions:
double getDeliveredPacket();

The number of data packets correctly delivered at the application layer with no repetitions generated by the src
node.
double getDeliveredPacket(int src);

56

Capitolo 3. Instructions and examples of usage


The number of bytes delivered by the src node to the dst node:
int getDeliveredBytes(int src, int dst)

Information related to data packets duplicated:


QUESTA MANCA:
int getDeliveredDuplicatedPacket()

The number of duplicated packet delivered by the src node to the dst node
getDeliveredDuplicatedPacket(int src, int dst)

The number of duplicated bytes delivered by the src node to the dst node:
int getDeliveredDuplicatedBytes(int src, int dst)

Information related to the application layer throughput.


The throughput at the application layer in the network:
double getApplicationThroughput();

The throughput at the application layer between the src node to the dst node:
double getApplicationThroughput(int src, int dst);

Information related to the end-to-end latency.


The average end-to-end packet latency in the network:
double getPacketLatency();

The average end-to-end for packets delivered by the src node to the dst node:
double getPacketLatency(int src, int dst)

3.8. Statistics Module

57

The average end-to-end packet latency in the network for the reception of duplicated packets:
double getDuplicatedPacketLatency();

The average end-to-end for duplicated packets delivered by the src node to the dst node:
double getDuplicatedPacketLatency(int src, int dst)

Information related to the data packets routes.


The average route length for packets delivered in the network, with no repetitions.
double getRouteLength();

The average route length traversed by duplicated packets delivered by the src node to the dst node:
getDuplicatedRouteLength

The number of different routes used in the network when delivering data packets to the destination node:
double getNumRoutes();

The number of different routes used in the network when delivering duplicated data packets to the destination
node:
double getDuplicatedNumRoutes();

The maximal route length in the network:


double getMaxRouteLength();

The maximal route length traversed by packets delivered by the src node to the dst node:
int getMaxRouteLength(int src, int dst)

58

Capitolo 3. Instructions and examples of usage


The maximal duplicated route length traversed by packets delivered by the src node to the dst node.
int getMaxDuplicatedRouteLength(int src, int dst)

The average route length for duplicated packets delivered in the network:
double getDuplicatedRouteLength();

The maximal routes length in the network when delivering duplicated data packets to the destination node:
double getMaxDuplicatedRouteLength();

Information related to overhead.


The amount of overhead information transmitted to deliver one bit of information in the network:
double getOverheadPerBit();

The amount of overhead information transmitted to deliver one bit of information from the src node to the dst
node:
double getOverheadPerBit(int src, int dst);

MAC Layer

Information related to the MAC data packets.


The number of data packets received at the MAC layer, generated at the upper layer to be transmitted on the
link from the src node to the dst node:
int getCreatedMacDataPacket(int src, int dst)

The number of data packets transmitted at the MAC layer, from the src node to the dst node:
int getMacDataPacketTransmissions(int src, int dst)

The number of data packets received at the MAC layer, transmitted on the link from the src node to the dst node:

3.8. Statistics Module

59

int getMacDataPacketReceptions(int src, int dst)

The number of data bytes received at the MAC layer, generated at the upper layer to be transmitted on the link
from the src node to the dst node:
int getCreatedMacDataBytes(int src, int dst)

The number of data bytes transmitted at the MAC layer, from the src node to the dst node:
int getMacDataBytesTransmissions(int src, int dst)

The number of data bytes received at the MAC layer, transmitted on the link from the src node to the dst node:
int getMacDataBytesReceptions(int src, int dst)

The number of data packets discarded at the MAC layer, by the src node addressed to dst node:
int getMacDataPacketDiscarded(int src, int dst)

The number of data bytes discarded at the MAC layer, by the src node addressed to dst node:
int getMacDataBytesDiscarded(int src, int dst)

Information related to the MAC control packets.


The number of control packets transmitted at the MAC layer, by the src node to the dst node:
int getMacCtrlPacketTransmissions(int src, int dst)

The number of control packets received at the MAC layer, transmitted on the link from the src node to the dst
node:
int getMacCtrlPacketReceptions(int src, int dst)

60

Capitolo 3. Instructions and examples of usage


The number of control bytes transmitted at the MAC layer, by the src node to the dst node:
int getMacCtrlBytesTransmissions(int src, int dst)

The number of control byes received at the MAC layer, transmitted on the link from the src node to the dst node:
int getMacCtrlBytesReceptions(int src, int dst)

The number of control packets discarded at the MAC layer, by the src node addressed to dst node:
int getMacCtrlPacketDiscarded(int src, int dst)

The number of control bytes discarded at the MAC layer, by the src node addressed to dst node:
int getMacCtrlBytesDiscarded(int src, int dst)

Information related to the MAC throughput.


The throughput at the MAC layer in the network:
double getMacThroughput();

The throughput at the MAC layer on the link src to dst:


double getMacThroughput(int src, int dst);

Information related to the MAC load (both of data and control packets).
The number of MAC packets transmitted in the network:
double getMacLoad();

The number of MAC bytes transmitted in the network:


double getMacLoadBytes();

3.8. Statistics Module


The number of MAC data packets transmitted in the network:
double getMacDataLoad();

The number of MAC data bytes transmitted in the network:


double getMacDataLoadBytes();

The number of MAC control packets transmitted in the network:


double getMacCtrlLoad();

The number of MAC control bytes transmitted in the network:


double getMacCtrlLoadBytes();

The average number of data packets retransmissions in the network:


double getMacDataRetransmissions(int src, int dst);

The average number of data packets retransmissions on the link from the src node to the dst node:
double getMacDataRetransmissions();

Energy Module

Information related to the residual energy.


The residual energy in the network:
float getResidualEnergy();

The residual energy of a given node:


float getResidualEnergy(int id);

61

62

Capitolo 3. Instructions and examples of usage


Information related to the amount of time spent for each action (idling, receiving, transmitting).
The amount of time spent by the network in idle:
float getIdleTime();

The amount of time spent by the id node in idle:


float getIdleTime(int id);

The amount of time spent by the network while receiving:

float getRxTime();

The amount of time spent by the id node while receiving


float getRxTime(int id);

The amount of time spent by the network while transmitting using a given transmission power pow:
float getTxTime(double pow);

The amount of time spent by the id node while transmitting using a given transmission power pow:
float getTxTime(int id, double pow);

The amount of time spent by the network while transmitting:


float getTotTxTime();

The amount of time spent by the id node while transmitting:


float getTotTxTime(int id);

3.8. Statistics Module

63

Information related to the amount of energy consumed for each action (idling, receiving, transmitting).
The energy consumed by the network in idle mode:
float getIdleConsumption();

The energy consumed by the id node in idle mode:


float getIdleConsumption(int id);

The energy consumed by the network in receiving mode:


float getRxConsumption();

The energy consumed by the id node in receiving mode


float getRxConsumption(int );

The energy consumed by the network while transmitting using a given transmission power pow:
float getTxConsumption(double pow);

The energy consumed by the id node while transmitting using a given transmission power pow:
float getTxConsumption(int, double );

The total energy consumed by the node while transmitting:


float getTotTxConsumption();

The total energy consumed by the id node while transmitting:


float getTotTxConsumption(int );

New metrics can be implemented and new packet structure considered. The user can easily extend the Sunset_Protocol_Stat
class adding new packet type and data to collect.

64

3.9

Capitolo 3. Instructions and examples of usage

Energy Model

SUNSET provides a more accurate energy model to simply trace the energy consumption of each node in the network.
The energy consumption related to the transmission, reception and idle state can be set by the user as follows (from
samples/runSimulationSUNSETUrick.tcl by defining the following variables):
#Module/Sunset_Phy_Bellhop set MaxTxSPL_dB_ $params(txPower)
Module/Sunset_Phy_Urick set MaxTxSPL_dB_ $params(txPower)
#set phy($id) [new "Module/Sunset_Phy_Bellhop"]
set phy($id) [new "Module/Sunset_Phy_Urick"]
set energy($id) [new "Module/Sunset_Energy_Model"]
$energy($id) setInitialEnergy

4040000

//in Joule

$energy($id)
$energy($id)
$energy($id)
$energy($id)

180.0 3
0.85
0.085
$id

//dB re micro Pa and W

setTxPower
setRxPower
setIdlePower
setModuleAddress

$phy($id) addEnergyModule $energy($id)


In this Tcl script, we have assigned to each node an initial energy to 4040000J. We have also assigned a the transmission
power of 180 dB re P a saying that it corresponds to 3W, a reception power of 0.85W and a power consumption while
in idle of 0.085W. Then we have assigned the energy module to the SUNSET Phy module.
The reason to assign the transmission power in terms of dB reP a and Watt depends to the fact that on the data sheet
of several acoustic modems these two values are provided and they usually do not match the results coming from the
application of standard conversion formulas. They in fact consider transmission and reception efficiency losses. In this
way the user can select both these values and does need to handle any conversion when computing the final energy
consumption. In case the value related to the transmission power in Watt is unknown, it will be estimated by the Energy
Model itself. What the user should do it is to only set the power consumption in dB reP a as follows:
...
$energy($id) setTxPower

180.0

...
$phy($id) addEnergyModule $energy($id)
The SUNSET Energy module supports also the possibility to use different power transmission levels corresponding to
a different energy consumption at the node. All the different supported power levels can be added using the Tcl script
and, if used by the different protocol solutions, the corresponding energy consumption will be considered by the energy
model. An example of the setting of multiple transmission powers is provided below.

3.9. Energy Model


...
$energy($id) setTxPower
$energy($id) setTxPower
$energy($id) setTxPower

65

176.0 2.2
180.0 3
190.0 18

...
$phy($id) addEnergyModule $energy($id)
3.9.1

Energy Model - Print Statistics

The Energy Model maintains internal statistics about the energy consumption related to each node. Particularly, the
following statistics can be obtained:
The amount of residual energy:
float getResidualEnergy();

It can be invoked by the Tcl as follows (from samples/simulation/runSimulationSUNSETUrick.tcl):


$energy($id) getResidualEnergy

The amount of time spent in idle:


float getIdleTime();

It can be invoked by the Tcl as follows (from samples/simulation/runSimulationSUNSETUrick.tcl):


$energy($id) getIdleTime

The amount of time spent in reception:


float getRxTime();

It can be invoked by the Tcl as follows (from samples/simulation/runSimulationSUNSETUrick.tcl):


$energy($id) getRxTime

66

Capitolo 3. Instructions and examples of usage


The amount of time spent in transmission at a given power pow:
float getTxTime(double pow);

It can be invoked by the Tcl as follows (pow == 180.0):


$energy($id) getTxTime 180.0

The amount of total time spent in transmission:


float getTotTxTime();

It can be invoked by the Tcl as follows (from samples/simulation/runSimulationSUNSETUrick.tcl):


$energy($id) getTotTxTime

The amount of energy consumed in idle:


float getIdleConsumption();

It can be invoked by the Tcl as follows (from samples/simulation/runSimulationSUNSETUrick.tcl):


$energy($id) getIdleConsumption

The amount of energy consumed in reception:


float getRxConsumption();

It can be invoked by the Tcl as follows (from samples/simulation/runSimulationSUNSETUrick.tcl):


$energy($id) getRxConsumption

The amount of energy consumed in transmission at a given power pow:

3.10. Generic Modem

67

float getTxConsumption(double );

It can be invoked by the Tcl as follows (pow == 180.0):


$energy($id) getTxConsumption 180.0

The amount of total energy consumed in transmission:


float getTotTxConsumption();

It can be invoked by the Tcl as follows (from samples/simulation/runSimulationSUNSETUrick.tcl):


$energy($id) getTotTxConsumption

Please, take a look also to the subsection 3.11.1 for further example.

3.10

Generic Modem

The generic modem supports both serial and TCP connections.


In order to use the generic modem, you need to first create the generic modem as follows:
set modem [new Sunset_Generic_Modem]
Then you can choose which type of connection to use. If the serial line is needed the following instructions have to be
used:
$modem useSerial 1
$modem setSerial "/dev/ttyUSB0"
$modem setBaud 19200
In this example, the generic modem will try to connect to the "/dev/ttyUSB0" device using a baudrate of 19200.
If a TCP connection is used (i.e. when using the channel emulator), the corresponding settings are (from samples/emulation/channelEmulator.tcl):
$modem useTcp $params(genmodem_tcp)
$modem setIp $params(emulator_ip)
$modem setPort $params(emulator_port)
$modem setDataRate $params(bitrate)

68

Capitolo 3. Instructions and examples of usage

Then the physical layer has to be connected to the generic modem:


$node($id) setConnection $phy($id) $modem 1
Finally the module can be started, together with the other after the creation of all the modules:
$modem start

3.11

Power Control

SUNSET allows to easily run and test protocols that use power control mechanisms allowing to use different transmission
powers and change them at run time. From the Tcl point of view, the user needs only to configure the Phy module
(when simulation mode is considered) to use different transmission powers as follows:
...
set phy($id) [new "Module/Sunset_Phy_Bellhop"]
#set phy($id) [new "Module/Sunset_Phy_Urick"]
$phy($id) setModuleAddress $id
$phy($id) addPower 180.0
$phy($id) addPower 182.0
...
The operations that have to be performed by the SUNSET protocol module are very simple. It has to inform the
Information Dispatcher (for further details see 3.4) that it will provide transmission power information (lets define it
as TX_POWER string)
sid->define(getModuleAddress(), sid_id, "TX_POWER");
sid->provide(getModuleAddress(), sid_id, "TX_POWER");
and then it has just to notify to all the TX_POWER subscribing modules (such as Sunset_Phy_Urick and Sunset_Phy_Bellhop) when it changes from using one power level to another one using the notified_info structure as
follows:
void Sunset_Dummy_Protocol::setTxPower(float pow)
{
if ( simMode == 1 ) {
notified_info ni;
ni.node_id = getModuleAddress();
ni.info_time = NOW;
ni.info_name = "TX_POWER";

3.11. Power Control

69

if ( sid->assign_value(&pow, &ni, sizeof(float)) == false ) {


Sunset_Debug::debugInfo(-1, getModuleAddress(), "setTxPower NO MEMORY");
exit(1);
}
if (sid == 0) {
return;
}
if ( sid->set(getModuleAddress(), sid_id, ni) == 0 ) {
Sunset_Debug::debugInfo(-1, getModuleAddress(), "setTxPower PROVIDING \
INFO %s NOT DEFINED", (ni.info_name).c_str());
return;
}
}
return;
}
Every time the setTxPower() functions is invoked, the transmission power will be set to pow and every module
subscribing the TX_POWER information will receive it. It can be used both in simulation or emulation: you can
take a look at the Sunset_Phy_Bellhop (simulation) or at the Sunset_Evologics_v1_6 (emulation) modules to check
how these modules handle the TX_POWER information.

3.11.1

Power Control - Energy consumption - Statistics

The Energy Model statistics can be also used to check how many(much) times(energy) a node has spent (consumed)
transmitting at a given power (as also explained in Subsection 3.9.1). If two transmission powers have been used (i.e.,
180.0 and 182.0) the related statistics can be obtained as follows:

$energy($id) getTxTime
180.0
$energy($id) getTxConsumption 180.0
$energy($id) getTxTime
182.0
$energy($id) getTxConsumption 182.0

Please, take a look at the Subsection 3.9.1 for further examples on Energy module.

70

Capitolo 3. Instructions and examples of usage

3.12

Packet Error Model

When using the packet error model, the module has to be first created and then the type of error has to be chosen.
Finally, the packet error model can be assigned to the Phy module:
set errors($id) [new Module/Sunset_Packet_Error_Model]
$errors($id) errorModel "static" 0.1
...
set phy($id) [new Module/MPhy/Sunset_Phy]
$phy($id) usePktErrorModel 1 ;# using the packet error model
In this example, the static error model has been selected (with a fixed Packet Error Rate equal to 0.1) and the emulation PHY module has been considered. When running simulations whatever of the other SUNSET PHY modules, i.e,
Sunset_Phy_Bellhop and Sunset_Phy_Urick, can be used.
Other error models can be chosen:
FSK: you need to specify the SNR penalty (in DB) on the reception as third parameter:
$errors($params(sink)) errorModel "fsk" -10.0

Here the SNR penalty has been set to 10.0.


BPSK: you need to specify the SNR penalty (in DB) on the reception as third parameter:
$errors($params(sink)) errorModel "bpsk" -10.0

Here the SNR penalty has been set to 10.0.


The Packet Error Model module can be extended by the user/developer which can add novel or more sophisticated
error models.

3.13

Blacklist

Adding a node to the blacklist is really easy, as shown below:


$phy(1) addToBlacklist 2
$phy(1) addToBlacklist 3
$phy(3) addToBlacklist 1
In this case, the node 1 will drop every packet coming from node 2 and 3, while the node 3 will drop every packet from
node 1. This allows to model asymmetric links and to force avoiding some link in the network when running in both
simulation and emulation mode.

3.14. Channel Emulator - Position

3.14

71

Channel Emulator - Position

A first example on how to use the channel emulator can be found in the samples directory using the ./channelEmulator.tcl configuration file. To start the test it is sufficient to specify the node ID:
ns ./channelEmulator.tcl -id 1
Multiple instances of ns can be run specifying different node ID. The first node starts the test and it also starts the
channel emulator, all the other nodes will connect to the channel emulator instance which has been already created.
Looking at the Tcl script, the channel emulator is started by the startChannel function:
proc startChannel {} {
global params
set channel [new Module/Sunset_Channel_Emulator]
$channel setChannelPort $params(emulator_port)
$channel setPositionPort $params(emulator_port_pos)
$channel
$channel
$channel
$channel

positionEmulation $params(emulator_usePos)
setDefPropDelay $params(emulator_defProp)
setModuleAddress $params(id)
start

}
The "setChannelPort" and "setPositionPort" commands set the TCP port to be used to send the packets and the
nodes position updates, respectively. If positionEmulation is set than the propagation delays between the nodes will be
emulated according to the node positions. The setDefPropDelay sets the default propagation delay if a node position is
not found.
In order to use the Channel Emulator the Generic Modem module must be properly configured as shown below:
$modem useTcp $params(genmodem_tcp)
if { $params(genmodem_tcp) == 1 } {
$modem setIp $params(emulator_ip)
$modem setPort $params(emulator_port)
$modem setDataRate $params(bitrate)
} else {
puts "Serial Connection"
}
The setIp command sets the IP address of the channel emulator that has to be used for the connection; the setPort
command instead is used to specify the connection port which has to be the same where the channel emulator is listening
to.

72

Capitolo 3. Instructions and examples of usage

The following instruction is used to inform the PHY layer that the channel emulator is used. In this case the PHY
layer will handle the messages about the end of a transmission and of a reception according to the packet transmission/reception delays.
$phy($id) useChEmulator 1
When the Position Emulator module is used, the following configuration have to be adopted:
proc startPosition {} {
global params channel sunPos
set sunPos [new Module/Sunset_Position]
$sunPos
$sunPos
$sunPos
$sunPos

checkNSPos $params(position_useNS) $params(position_tick)


setModuleAddress
$params(id)
setIp
$params(emulator_ip)
setPort
$params(emulator_port_pos)

}
The checkNSPos command takes two parameters. If the first parameter ($params(position_useNS)) is set to 1, the
positions will be load from the Tcl script, otherwise the Information Dispatcher will be used to define and update the
node position, e.g., the position data are not stored in the Tcl script but collected, through the Information Dispatcher,
from the navigation system of an underwater robot when running in emulation mode. When loading the position
information from the Tcl file, the second parameter $params(position_tick) specifies the frequency rate at which the
node will check for any update in its position (if mobile nodes are used). If this parameter is set to 0, the node will not
check for any update while the experiment is running. When loading the position information from Dispatcher all the
updates will be provided by the external modules, if any, and no active checks are currently supported.
When loading the information from the Tcl file, the Position module will use the following function to collect the
corresponding information:
getSunsetLatitude
getSunsetLongitude
getSunsetDepth
The functions have to be therefore implemented in the Tcl file to provide the requested information:
proc getSunsetLatitude {id} {
global position params
set latitude [$position($params(id)) getLatitude_]
return $latitude
}

3.15. Implementing a new protocol

73

proc getSunsetLongitude {id} {


global position params
set longitude [$position($params(id)) getLongitude_]
return $longitude
}
proc getSunsetDepth {id} {
global position params
set altitude [$position($params(id)) getAltitude_]
return $altitude
}
When the node position information are updated by external SUNSET modules (e.g. the driver for the navigation
system of a vehicle) using the Information Dispatcher, these module have to define, subscribe (to be informed about
any update) and provide the NODE_POSITION info to the other modules:
sid->define(getModuleAddress(), sid_id, "NODE_POSITION");
sid->subscribe(getModuleAddress(), sid_id, "NODE_POSITION");
sid->provide(getModuleAddress(), sid_id, "NODE_POSITION");

3.15

Implementing a new protocol

In what follows we describe the few simple steps that have to be followed when developing a new protocol solution for
the SUNSET framework. It basically follows the same rules such as when developing a new protocol using the ns-Miracle
framework, but few changes are needed.
Placing the new protocol folder according to the overall framework structure (e.g., any MAC protocol inside the
Network_Protocols/Datalink/ folder) (optional - it is just to maintain the SUNSET structure).
Implementing the start() and stop() functions for the developed module. These function are used to perform
module initialization together with the creation and destruction of the needed references to the other modules.
When implementing these two functions, the first thing to do is invoking the parent functions, if any, to perform
the related initialization and referencing in the parent module (e.g., see the Sunset_Csma_Aloha::start() and
Sunset_Csma_Aloha::stop() functions) to be sure that all the parent actions are properly completed before
starting to use the novel module. The start() and stop() functions have to be then invoked at the beginning and
at the end of the experiment using the Tcl script (please refer to the example scripts in the sample folder).

74

Capitolo 3. Instructions and examples of usage


In the new protocol Makefile.am all the dependencies to additional libraries have to be properly linked (i.e, see
the Sunset_Csma_Aloha or Sunset_Flooding protocols Makefile.am). That is because some Operating System
needs the explicit definition of these libraries to properly load the libraries.
Add to the root configure.ac and Makefile.am the path for the new protocol (i.e., see the Network_Protocols
configure.ac and Makefile.am).

3.15.1

Define a new packet

The creation of a new packet header is very simple because the same procedure used in ns-Miracle can be followed. The
user can take advantage of structure already defined by SUNSET to define its own packet or it can just simply ignore
them and implements its own.
We will explain how to create a new packet taking advantage of the SUNSET packet structure.
Lets suppose that a new MAC packet has to be defined and created for a custom MAC protocol (i.e., Dummy Protocol): well call it Dummy Pkt. You can create a new Sunset_Dummy_Pkt inside the Sunset_Dummy_Protocol
folder (take a look at the Network_Protocols/Datalink/Sunset_Mac/ directory).
Then you have to define the .h and .cc files. The sunset_dummy_pkt.h follows:
#define HDR_SUNSET_MAC_DUMMY(p)
#define HDR_SUNSET_MAC_DUMMY_MYPKT(p)

((struct hdr_dummy *)hdr_dummy::access(p))


((struct hdr_dummy_mypkt *)hdr_dummy::access(p))

...
#define DUMMY_PKT_MYPKT 0
...
extern packet_t PT_SUNSET_MAC;
struct hdr_dummy {
struct sunset_mac_frame_control dh_fc; // using already defined structure
static int offset_;
inline static int& offset() { return offset_; }
inline static hdr_dummy* access(const Packet* p) {
return (hdr_dummy*) p->access(offset_);
}
};
struct hdr_dummy_mypkt {
struct sunset_mac_frame_control dh_fc;

3.15. Implementing a new protocol

75

int src;
int dst;
float lq;
};
union hdr_all_dummy {
struct hdr_dummy a;
struct hdr_dummy_mypkt b;
};
We have defined a dummy packet containing the lq (link quality), source and destination fields. As you can see, we have
include also the sunset_mac_frame_control structure: thats because it already contains useful information such as:
u_char fc_type; /*!< \brief The type of the MAC packet. */
u_char fc_subtype; /*!< \brief The subtype of the MAC packet. */
u_char f_protocol_version; /*!< \brief The version of the MAC packet. */
The sunset_dummy_pkt.cc follows:
extern packet_t PT_SUNSET_MAC;
int hdr_dummy::offset_;
static class Sunset_Mac_dummy_Class : public PacketHeaderClass {
public:
Sunset_Mac_dummy_Class() : PacketHeaderClass("PacketHeader/SUNSET_DUMMY",
sizeof(hdr_all_dummy)) {
bind_offset(&hdr_dummy::offset_);
this->bind();
}
} class_sunset_mac_dummy;
The sunset_dummy_pkt-init.tcl follows:
PacketHeaderManager set tab_(PacketHeader/SUNSET_DUMMY) 1
Now, in the main Sunset_Dummy_Protocol folder we have to add the packet definition inside the initlib.cc file
#include <tclcl.h>
#include <sunset_dummy_pkt.h>
packet_t PT_SUNSET_MAC; // Add this line
extern EmbeddedTcl Sunset_dummy_TclCode;

76

Capitolo 3. Instructions and examples of usage

extern "C" int Sunset_mac_dummy_Init()


{
PT_SUNSET_MAC = p_info::addPacket("SUNSET_MAC"); // Add this line
Sunset_dummy_TclCode.load();
return 0;
}
and change the Makefile.am file:
lib_LTLIBRARIES = libSunset_Networking_Dummy.la
libSunset_Networking_Dummy = Sunset_Dummy_Pkt/sunset_dummy_pkt.cc \ ## add this line
Sunset_Dummy_Pkt/sunset_dummy_pkt.h \ ## add this line
sunset_dummy.cc sunset_dummy.h initlib.cc
libSunset_Networking_Dummy_la_CPPFLAGS = @NS_CPPFLAGS@ @NSMIRACLE_CPPFLAGS@ -ggdb
libSunset_Networking_Dummy_la_LDFLAGS = @NS_LDFLAGS@ @NSMIRACLE_LDFLAGS@ \
-L${SUNSET_FOLDER}/../build/sunset_lib/lib/ \
-L../Sunset_Mac
## load core modules potential dependencies and the link to the
## parent MAC class including basic MAC packet definition
libSunset_Networking_Dummy_la_LIBADD =
@NS_LIBADD@ @NSMIRACLE_LIBADD@
-lSunset_Core_Mac_Routing \
-lSunset_Core_Phy_Mac -lSunset_Core_Queue \
-lSunset_Core_Utilities -lSunset_Core_Statistics \
-lSunset_Core_Timing -lSunset_Core_Information_Dispatcher \
-lSunset_Core_Debug -lSunset_Networking_Mac \
-lSunset_Core_Module
nodist_libSunset_Networking_Dummy_la_SOURCES = initTcl.cc
BUILT_SOURCES = initTcl.cc
CLEANFILES = initTcl.cc
TCL_FILES =

sunset_dummy-init.tcl Sunset_Dummy_Pkt/sunset_dummy_pkt-init.tcl

initTcl.cc: Makefile $(TCL_FILES)


cat $(TCL_FILES) | @Tcl2CPP@ Sunset_dummy_TclCode > initTcl.cc
EXTRA_DIST = $(TCL_FILES)
Finally, we have to add the packet header to the global path inside the configure.ac:
SUNSET_CPPFLAGS="$SUNSET_CPPFLAGS "-I$(top_srcdir)/Datalink/Sunset_Dummy/Sunset_Dummy_Pkt

3.15. Implementing a new protocol

77

And load it in the Tcl script:


add-packet-header SUNSET_DUMMY
Suppose that we want now to create a new dummy packet to be sent (lets assume that Sunset_Mac_dummy is
the name of the main class of the Sunset_Dummy_Protocol). We also assume that this dummy MAC just send in
broadcast whatever control packet it generates:
void Sunset_Mac_dummy::sendMyPkt()
{
Packet *p = Packet::alloc();
hdr_cmn* cmh = HDR_CMN(p);
struct hdr_dummy_mypkt *mypkt = HDR_SUNSET_MAC_DUMMY_MYPKT(p);
int src = 0, dest = 0;
src = routingAddress;
dest = getBroadcastAddress();
cmh->ptype() = PT_SUNSET_MAC;
cmh->direction() = hdr_cmn::DOWN;
cmh->next_hop_ = getBroadcastAddress();
cmh->error() = 0;
mypkt->dh_fc.fc_type = SUNSET_MAC_Type_Control;
mypkt->dh_fc.fc_subtype = DUMMY_PKT_MYPKT;
mypkt->src = getModuleAddress();
mypkt->dst = getBroadcastAddress();
mypkt->lq = getLinkQuality();
//defined somewhere
cmh->size() = MYPKT_SIZE;
//macTiming is a Sunset_Timing* assigned by command()
//bitrate is defined somewhere
cmh->txtime() = macTiming->txtime(cmh->size(), bitrate);
// now we can send it
....
return;
}
When we want to handle a received packet we can proceed as follows:

78

Capitolo 3. Instructions and examples of usage

void Sunset_Mac_dummy::rxDone(Packet *p)


{
unsigned pktType = HDR_SUNSET_MAC_DUMMY(p)->dh_fc.fc_type;
unsigned pktSubType = HDR_SUNSET_MAC_DUMMY(p)->dh_fc.fc_subtype;
if ( pktType == SUNSET_MAC_Type_Control )

switch(pktSubType) {
case DUMMY_PKT_MYPKT:
// do something
break;
...
default:
// do something
break;
}
...
}
...
}
Packet Converter

Please, take a look at Subsection 3.6 for further information and examples on the Packet Converter.
In what follows we will create the packet header converter class for the dummy packet defined above.
To keep the same file organization, we first create a new folder, named Sunset_Dummy_Pkt_Converter, inside the
Network_Protocols/Addon/Packet_Converter/Datalink/ folder.
According to what described in Subsection 2.1.7 we implement the following functions:
virtual
virtual
virtual
virtual
virtual
virtual
virtual
virtual

int checkPktLevel(Packet* p);


int getHeaderSizeBits();
int getConvertedInfoLength(Packet* p);
int pkt2Buffer(int level, Packet* p, char* buffer, int
int buffer2Pkt(int level, Packet* p, char* buffer, int
void erasePkt(int level, Packet* p);
int getSrc(int level, Packet* p, sunset_header_type m,
int getDst(int level, Packet* p, sunset_header_type m,

offset);
offset, int bits);
int& src);
int& dst);

The sunset_dummy_pkt_converter.h can be organized in the following way:


#include "sunset_dummy_pkt.h"
#include "sunset_mac_pkt_converter.h"

3.15. Implementing a new protocol


class Sunset_Dummy_MacPktConverter : public Sunset_MacPktConverter {
public:
Sunset_Dummy_MacPktConverter();
virtual int command( int argc, const char*const* argv );
virtual int getHeaderSizeBits();
virtual int getConvertedInfoLength(Packet* p);
virtual int checkPktLevel(Packet* p);
virtual int createMiniPkt(int level, Packet* p, sunset_header_type m, int src,
int dst, int pkt_sub_type);
virtual int pkt2Buffer(int level, Packet* p, char* buffer, int offset);
virtual int buffer2Pkt(int level, Packet* p, char* buffer, int offset, int bits);
virtual int buffer2Pkt(int level, int src, int dst, Packet* p, char* buffer,
int offset, int bits);
virtual void erasePkt(int level, Packet* p) { };
virtual void getName() { Sunset_Debug::debugInfo(-1, -1, "Sunset_Dummy_MacPktConverter"); }
virtual int getSrc(int level, Packet* p, sunset_header_type m, int& src);
virtual int getDst(int level, Packet* p, sunset_header_type m, int& dst);
virtual int getMacPktSubType(int level, Packet* p, int& subType) {
subType = HDR_SUNSET_MAC_DUMMY(p)->dh_fc.fc_subtype;
return 1;
}
protected:
int checkPktSubType(int pkt_sub_type);
int lqSize;
Similarly, the sunset_dummy_pkt_converter.cc can be organized as in what follows:
#include "sunset_dummy_pkt_converter.h"
#include "sunset_mac_pkt.h"
static class Sunset_Dummy_MacPktConverterClass : public TclClass {
public:
Sunset_Dummy_MacPktConverterClass() : TclClass("Sunset_PktConverter/DummyMac") {}
TclObject* create(int, const char*const*) {
return (new Sunset_Dummy_MacPktConverter());
}
} class_Sunset_Dummy_MacPktConverterClass;
Sunset_Dummy_MacPktConverter::Sunset_Dummy_MacPktConverter() : Sunset_MacPktConverter()
{

79

80

Capitolo 3. Instructions and examples of usage


lqSize = 0;
//define if the source ID in the dummy packet has to be
//considered during the packet conversion
bind("use_source", &use_source);
//define if the destination ID in the dummy packet has to be
//considered during the packet conversion
bind("use_dest", &use_dest);
//define the number of bits assigned to the link quality information
bind("LQSIZE", &lqSize);
Sunset_Debug::debugInfo(-1, -1, "Sunset_Dummy_MacPktConverter CREATO");

}
int Sunset_Dummy_MacPktConverter::command( int argc, const char*const* argv )
{
Tcl& tcl = Tcl::instance();
if (argc == 3) {
if (strcmp(argv[1], "useSource") == 0) {
use_source = atoi(argv[2]);
return TCL_OK;
}
if (strcmp(argv[1], "useDest") == 0) {
use_dest = atoi(argv[2]);
return TCL_OK;
}
if (strcmp(argv[1], "setLqSize") == 0) {
lqSize = atoi(argv[2]);
return TCL_OK;
}
}
return Sunset_MacPktConverter::command(argc, argv);
}
int Sunset_Dummy_MacPktConverter::checkPktLevel(Packet* p)
{
struct hdr_dummy *mh = HDR_SUNSET_MAC_DUMMY(p);

3.15. Implementing a new protocol


u_int8_t
u_int8_t

type = mh->dh_fc.fc_type;
subtype = mh->dh_fc.fc_subtype;

Sunset_Debug::debugInfo(5, -1, "Sunset_Dummy_MacPktConverter::checkPktLevel");


if (type == SUNSET_MAC_Type_Control || type == SUNSET_MAC_Type_Data) {
return 1;
}
return 0;
}
int Sunset_Dummy_MacPktConverter::getHeaderSizeBits()
{
int len = 0;

len += getLevelIdBits();
len += ((int)sizeof(sunset_mac_frame_control)) * 8;
if (use_source) {
len += getAddrBits(); //source id
}
if(use_dest) {
len += getAddrBits(); //destination id
}
// here we need to compute the maximal size of the packet header
// in the worse case (it is needed to compute the maximal payload
// length, the link quality information has to be always considered
len += lqSize;
Sunset_Debug::debugInfo(5, -1, "Sunset_Dummy_MacPktConverter::getHeaderSizeBits \
%d", len);
return len;
}
int Sunset_Dummy_MacPktConverter::getConvertedInfoLength(Packet* p)
{
struct hdr_dummy *mh = HDR_SUNSET_MAC_DUMMY(p);

81

82

Capitolo 3. Instructions and examples of usage

u_int8_t type = mh->dh_fc.fc_type;


u_int8_t subtype = mh->dh_fc.fc_subtype;
int len = 0;
len += getLevelIdBits();
len += ((int)sizeof(sunset_mac_frame_control)) * 8;
if (use_source) {
len += getAddrBits(); //source id
}
if(use_dest) {
len += getAddrBits(); //destination id
}
switch(subtype) {
case DUMMY_PKT_MYPKT:
//
//
//
//

differently from the getHeaderSizeBits() function


we can check here the packet type and add only
the needed information to define the length of the
stream of bytes after the conversion
len += lqSize;
break;
// other packet subtypes if any
}
return len;

}
int Sunset_Dummy_MacPktConverter::pkt2Buffer(int level, Packet* p, char* buffer, int offset)
{
struct hdr_dummy *mh = HDR_SUNSET_MAC_DUMMY(p);
u_int8_t type = mh->dh_fc.fc_type;
u_int8_t subtype = mh->dh_fc.fc_subtype;;
int aux = getConvertedInfoLength(p);

3.15. Implementing a new protocol

if (aux == 0) {
return 0;
}
int size = getLevelIdBits();
// writing the sunset_mac_frame_control information
setBits(buffer, (char *)(&(level)), size, offset);
setBits(buffer, (char *)(&(HDR_SUNSET_MAC_DUMMY(p)->dh_fc)),
(int)((sizeof(sunset_mac_frame_control)) * 8), offset + size);
size += (int)((sizeof(sunset_mac_frame_control)) * 8);
switch(subtype) {
case DUMMY_PKT_MYPKT:
if (use_source) {
setBits(buffer, (char *)(&(HDR_SUNSET_MAC_DUMMY_MYPKT(p)->src)),
getAddrBits(), offset + size);
size += getAddrBits();
}
if (use_dest) {
setBits(buffer, (char *)(&(HDR_SUNSET_MAC_DUMMY_MYPKT(p)->dst)),
getAddrBits(), offset + size);
size += getAddrBits();
}
// writing the link quality information
setBits(buffer, (char *)(&(HDR_SUNSET_MAC_DUMMY_MYPKT(p)->lq)),
lqSize, offset + size);
size += lqSize;
break;
// other packet subtypes if any
}
if (aux != size) {
Sunset_Debug::debugInfo(-1, -1, "Sunset_Dummy_MacPktConverter::pkt2Buffer \
buffer filled ERROR aux %d size %d bits", aux, size);

83

84

Capitolo 3. Instructions and examples of usage


return 0;
}
Sunset_Debug::debugInfo(-1, -1, "Sunset_Dummy_MacPktConverter::pkt2Buffer \
buffer filled size %d bits", size);
return size;

int Sunset_Dummy_MacPktConverter::buffer2Pkt(int level, Packet* p, char* buffer,


int offset, int bits)
{
int size = getLevelIdBits();
int info_level = 0;
if (bits < size) { // not enough bits left to read the packet header information
Sunset_Debug::debugInfo(5, -1, "Sunset_Dummy_MacPktConverter::buffer2Pkt \
check bits1 bits %d size %d", bits, size);
return 0;
}
getBits(buffer, (char *)(&(info_level)), size, offset);
if (info_level != level) { // check if this is the right packet header
return 0;
}
if (bits - size < (int)((sizeof(sunset_mac_frame_control)) * 8)) {
// not enough bits left to read the packet header information but this
// packet contains dummy header information --> ERROR
Sunset_Debug::debugInfo(5, -1, "Sunset_Dummy_MacPktConverter::buffer2Pkt \
check bits2 AUCH bits %d size %d", bits, size);
return -1;
}
// reading the sunset_mac_frame_control information
getBits(buffer, (char *)(&(HDR_SUNSET_MAC_DUMMY(p)->dh_fc)),
(int)((sizeof(sunset_mac_frame_control)) * 8), offset + size);
size += (int)((sizeof(sunset_mac_frame_control)) * 8);

3.15. Implementing a new protocol


// The mac control frame has been filled with the correct information, we can control
// the packet subtype and compute the correct amount of converted information
if (bits < getConvertedInfoLength(p)) {
// not enough bits left to read the packet header information but this
// packet contains dummy header information --> ERROR
Sunset_Debug::debugInfo(5, -1, "Sunset_Dummy_MacPktConverter::buffer2Pkt \
check bits2 bits %d size %d", bits, getHeaderSizeBits());
return -1;
}
switch ( HDR_SUNSET_MAC_DUMMY(p)->dh_fc.fc_subtype ) {
case DUMMY_PKT_MYPKT:
if (use_source) {
getBits(buffer, (char *)(&(HDR_SUNSET_MAC_DUMMY_MYPKT(p)->src)),
getAddrBits(), offset + size);
size += getAddrBits();
}
if (use_dest) {
getBits(buffer, (char *)(&(HDR_SUNSET_MAC_DUMMY_MYPKT(p)->dst)),
getAddrBits(), offset + size);
size += getAddrBits();
}
// reading the link quality information
getBits(buffer, (char *)(&(HDR_SUNSET_MAC_DUMMY_MYPKT(p)->lq)),
lqSize, offset + size);
size += lqSize;
break;
// other packet subtypes if any
}
Sunset_Debug::debugInfo(5, -1, "Sunset_Dummy_MacPktConverter::buffer2Pkt dummy \
info for the packet have been set %d Bits", size);

85

86

Capitolo 3. Instructions and examples of usage

return size;
}

int Sunset_Dummy_MacPktConverter::createMiniPkt(int level, Packet* p,


sunset_header_type m, int src, int dst, int pkt_sub_type)
{
hdr_cmn* ch = HDR_CMN(p);
struct hdr_dummy *mh = HDR_SUNSET_MAC_DUMMY(p);
if (m != UW_PKT_MAC) {

//if the it is not a MAC mini packet exit

return 1;
}
ch->uid() = 0;
ch->ptype() = PT_SUNSET_MAC;
// we assume a fixed size here, it can be assigned according to the
// packet subtype
ch->size() = 10;
ch->iface() = -2;
ch->error() = 0;
int maxId = pow(2.0, getAddrBits());
if (src > maxId || dst > maxId) { // check if an error on the input occurred
Sunset_Debug::debugInfo(-1, -1, "Sunset_Dummy_MacPktConverter::createMiniPkt \
ERROR src %d dst %d maxId %d", src, dst, maxId);
ch->error() = 1;
}
// check if the subtype in input is a correct one supported by this MAC
if (checkPktSubType(pkt_sub_type) != 1) {
Sunset_Debug::debugInfo(-1, -1, "Sunset_MacPktConverter::createMacPkt \
ERROR pkt_sub_type %d", pkt_sub_type);
ch->error() = 1;
}
bzero(dh, sizeof(hdr_all_dummy));

3.15. Implementing a new protocol

dh->dh_fc.fc_protocol_version = SUNSET_MAC_ProtocolVersion;
dh->dh_fc.fc_to_ds
= 0;
dh->dh_fc.fc_from_ds
= 0;
dh->dh_fc.fc_more_frag
= 0;
dh->dh_fc.fc_retry
= 0;
dh->dh_fc.fc_pwr_mgt
= 0;
dh->dh_fc.fc_more_data
= 0;
dh->dh_fc.fc_wep
= 0;
dh->dh_fc.fc_order
= 0;
dh->dh_fc.fc_subtype

= pkt_sub_type;

switch(pkt_sub_type) {
case DUMMY_PKT_MYPKT:
HDR_SUNSET_MAC_DUMMY_MYPKT(p)->src = src;
HDR_SUNSET_MAC_DUMMY_MYPKT(p)->dst = dst;
dh->dh_fc.fc_type = SUNSET_MAC_Type_Control;
break;
// other packet subtypes if any
default:
Sunset_Debug::debugInfo(-1, -1, "Sunset_Dummy_MacPktConverter::checkPktSubType \
invalid MAC Control Subtype %d ERROR", pkt_sub_type);
return 0;
}
ch->txtime() = 1.0;
HDR_CMN(p)->timestamp() = NOW;
Sunset_Debug::debugInfo(2, -1, "Sunset_Dummy_MacPktConverter::createMacPkt");
return 1;
}
int Sunset_Dummy_MacPktConverter::checkPktSubType(int pkt_sub_type)
{

87

88

Capitolo 3. Instructions and examples of usage


switch(pkt_sub_type) {
case DUMMY_PKT_MYPKT:
return 1;
// other packet subtypes if any
default:
Sunset_Debug::debugInfo(-1, -1, "Sunset_Dummy_MacPktConverter::checkPktSubType \
invalid MAC Control Subtype %d ERROR", pkt_sub_type);
return 0;
}
return 0;

}
int Sunset_Dummy_MacPktConverter::getSrc(int level, Packet* p,
sunset_header_type m, int& src)
{
if (m != UW_PKT_MAC)
return 0;
int pkt_sub_type = HDR_SUNSET_MAC_DUMMY(p)->dh_fc.fc_subtype;
switch(pkt_sub_type) {
case DUMMY_PKT_MYPKT:
src = HDR_SUNSET_MAC_DUMMY_MYPKT(p)->src;
return 1;
// other packet subtypes if any
default:
Sunset_Debug::debugInfo(-1, -1, "Sunset_Dummy_MacPktConverter::getMacSrc \
invalid MAC Control Subtype %d ERROR", pkt_sub_type);
return 0;
}
return 1;
}

int Sunset_Dummy_MacPktConverter::getDst(int level, Packet* p,


sunset_header_type m, int& dst)

3.15. Implementing a new protocol


{
if (m != UW_PKT_MAC)
return 0;
int pkt_sub_type = HDR_SUNSET_MAC_DUMMY(p)->dh_fc.fc_subtype;
switch(pkt_sub_type) {
case DUMMY_PKT_MYPKT:
dst = HDR_SUNSET_MAC_DUMMY_MYPKT(p)->dst;
return 1;
// other packet subtypes if any
default:
Sunset_Debug::debugInfo(-1, -1, "Sunset_Dummy_MacPktConverter::getMacDst \
invalid MAC Control Subtype %d ERROR", pkt_sub_type);
return 0;
}
return 1;
}
// This function is used when the source and destination IDs of the MAC packet are known
// (provided by the communication device) before converting the stream of bytes into an
// ns-2 packet. In this case use_source and use_dest can be set to 0 to reduce the
// protocol overhead.
int Sunset_Dummy_MacPktConverter::buffer2Pkt(int level, int src, int dst,
Packet* p, char* buffer, int offset, int bits)
{
int size = buffer2Pkt(level, p, buffer, offset, bits);
int pkt_sub_type = HDR_SUNSET_MAC_DUMMY(p)->dh_fc.fc_subtype;
switch(pkt_sub_type) {
case DUMMY_PKT_MYPKT:
HDR_SUNSET_MAC_DUMMY_MYPKT(p)->src = src;
HDR_SUNSET_MAC_DUMMY_MYPKT(p)->dst = dst;
break;
// other packet subtypes if any
default:

89

90

Capitolo 3. Instructions and examples of usage


Sunset_Debug::debugInfo(-1, -1, "Sunset_Dummy_MacPktConverter::buffer2Pkt \
invalid MAC Control Subtype %d ERROR", pkt_sub_type);
return 0;
}
Sunset_Debug::debugInfo(5, -1, "Sunset_MacPktConverter::buffer2PktMAC_2 dummy \
info for the packet have been set %d Bits", size);
return size;

}
To compile the implemented dummy packet header converter module, the Makefile.am has to be provided, together with
the initlib.c and the sunset_dummy_pkt_converter-init.tcl:
##Makefile.am#
lib_LTLIBRARIES = libSunset_Networking_Dummy_PktConverter.la
libSunset_Networking_Dummy_PktConverter_la_SOURCES = sunset_dummy_pkt_converter.cc \
sunset_dummy_pkt_converter.h initlib.cc
libSunset_Networking_Dummy_PktConverter_la_CPPFLAGS = @NS_CPPFLAGS@ \
@NSMIRACLE_CPPFLAGS@ -ggdb
libSunset_Networking_Dummy_PktConverter_la_LDFLAGS = @NS_LDFLAGS@ \
@NSMIRACLE_LDFLAGS@ -L${SUNSET_FOLDER}/../build/sunset_lib/lib/ \
-L../../../../Datalink/Sunset_Mac \
-L../../../../Datalink/Sunset_Dummy/
libSunset_Networking_Dummy_PktConverter_la_LIBADD =
@NS_LIBADD@ \
@NSMIRACLE_LIBADD@ -lSunset_Core_Debug -lSunset_Core_Utilities \
-lSunset_Core_PktConverter -lSunset_Networking_Mac \
-lSunset_Networking_Dummy
nodist_libSunset_Networking_Dummy_PktConverter_la_SOURCES = initTcl.cc
BUILT_SOURCES = initTcl.cc
CLEANFILES = initTcl.cc
TCL_FILES =

sunset_dummy_pkt_converter-init.tcl

initTcl.cc: Makefile $(TCL_FILES)


cat $(TCL_FILES) | @Tcl2CPP@ Sunset_Dummy_PktConverter_TclCode > initTcl.cc
EXTRA_DIST = $(TCL_FILES)
//initlib.c

3.15. Implementing a new protocol

91

extern EmbeddedTcl Sunset_Dummy_PktConverter_TclCode;


extern "C" int Sunset_networking_dummy_pktconverter_Init() {
Sunset_Dummy_PktConverter_TclCode.load();
return 0;
}
#sunset_dummy_pkt_converter-init.tcl#
# It contains the initialization for the Tcl variables
Sunset_PktConverter/DummyMac set use_source 0
Sunset_PktConverter/DummyMac set use_dest 0
Sunset_PktConverter/DummyMac set LQSIZE 4

// we will use the source of MAC


// we will use the destination of MAC
// link quality size in bits

Finally the instruction to compile the new module have to be added to the root configure.ac:
AC_CONFIG_FILES([
Makefile
...
Addon/Packet_Converter/Datalink/Sunset_Dummy_Pkt_Converter/Makefile
])
and to the root Makefile.am:
SUBDIRS = m4\
...
Addon/Packet_Converter/Datalink/Sunset_Dummy_Pkt_Converter/
In order to use it, we have to load the library and configure it in the Tcl script:
...
load $pathSUNSET/libSunset_Networking_Dummy_PktConverter.so.0.0.0
...
set pktConverter [new Sunset_PktConverter]
...
// initialization
Sunset_PktConverter/DummyMac set use_source 0
Sunset_PktConverter/DummyMac set use_dest 0
Sunset_PktConverter/DummyMac set LQSIZE 4
set pktConverter_mac [new Sunset_PktConverter/DummyMac]
$pktConverter_mac useSource 1
$pktConverter_mac useDest 1

// we want to use the source field


// we want to use the destination field

92

Capitolo 3. Instructions and examples of usage

...
$pktConverter addPktConverter 1 $pktConverter_mac //add it to the Pkt Converter
No additional instructions and modifications are needed.

3.16

Connections

A brief description of the Connections Module can be found in Section 2.2.2.


All the Connections Modules (TCP, UDP and Serial) extend from the base class Sunset_Connection: therefore each
of them can be declared as a Sunset_Connection object (or as the specific class name) and then the specific class
object can be created.
3.16.1

TCP Connections

For the TCP Connections module, a TCP client or server can be created.
TCP Connections - Client

The following examples are taken from the Sunset_Position_Channel class.


In order to establish a TCP client connection, a new TCP client connection object has to be created and configured.
The class constructor function takes in input the IP and port number to be used for the connection.
Sunset_Tcp_Client_Connection* connection;
//or Sunset_Connection* connection;
...
// IP = ip_addr, PORT_NUMBER=port
connection = new Sunset_Tcp_Client_Connection(ip_addr, port);
After the class object creation, the connection to the given IP and port can be opened:
res = connection->open_connection();
if ( res == false ) {
return false;
}
// the connection is open
Sunset_Debug::debugInfo(-1, getModuleAddress(), "Sunset_Position_Channel::connect \
connection done");
if ( res == true ) {

3.16. Connections

93

// getting the file descriptor id


sockFd = connection->get_fd();
}
Once all these actions have been completed, data can be read from and written to the created TCP socket.
if( connection->write_data(sockFd, buffer, size) != true) {
Sunset_Debug::debugInfo(-1, getModuleAddress(), "Sunset_Position_Channel::writeModem \
write failed! ERROR");
return 1;
}
TCP Connections - Server

The following examples are taken from the Sunset_Channel_Emulator class .


Similarly to the client case, the TCP server connection object has to be first created and configured. The class constructor
function takes in input the IP and port number to be used for the connection.
Sunset_Channel_Emulator_Conn *server;
//or Sunset_Connection* connection;
...
// IP = any, PORT_NUMBER=socketPort
server = new Sunset_Channel_Emulator_Conn("0.0.0.0", socketPort);
The Sunset_Channel_Emulator_Conn extends the Sunset_Tcp_Server_Connection because it re-implements the
read_data() function (to read and parse the incoming data in the proper way) therefore their usage is the same.
After the class object creation, the connection to the given IP and port can be opened:
res = server->open_connection();
...
socketId = server->get_fd();
Once the server object has been created and the connection has been configures, the TCP server can start listening for
any incoming connection on the given IP and port. The return value of the accept_connection() is the file descriptor
related to the client connection:
newsockfd = server->accept_connection();
if (newsockfd < 0) {

94

Capitolo 3. Instructions and examples of usage


Sunset_Debug::debugInfo(-1, getModuleAddress(), "Sunset_Channel_Emulator::waitForConnections
ERROR");
...

}
Once all these actions have been completed, data can be read from and written to the created TCP socket to the TCP
client.
if ( server->read_data(newsockfd, (char*)&id, sizeof(int)) < sizeof(int)) {
Sunset_Debug::debugInfo(-1, getModuleAddress(), "Sunset_Channel_Emulator::waitForConnections
ERROR while reading the id of the client");
...
}
3.16.2

UDP Connections

In order to establish a UDP connection, a new UDP connection object has to be created and configured. The UDP
connection class implements two constructors:
Sunset_Udp_Connection(const char *, int);
Sunset_Udp_Connection(const char *, int, int);
The first one takes as arguments the IP and the port that will be used for both transmission and reception. The second
constructor takes three arguments: the IP, the port used for transmission and the port used for reception.
Therefore a new UDP connection object can be created as follows:
Sunset_Udp_Connection *conn;
//or Sunset_Connection* connection;
...
// IP = "127.0.0.1", PORT_NUMBER_TX=4000, PORT_NUMBER_TX=4001
Sunset_Udp_Connection *conn = new Sunset_Udp_Connection("127.0.0.1", 4001, 4000);
// IP = "127.0.0.1", PORT_NUMBER_TX_RX=4000
//Sunset_Udp_Connection *conn = new Sunset_Udp_Connection("127.0.0.1", 4000);
After the class object creation, the connection to the given IP and port(s) can be opened:
res = conn->open_connection();
...
socketId = server->get_fd();
Once all these actions have been completed, data can be read from and written to the created UDP socket.

3.16. Connections

95

char buf[30];
...
if ( conn->read_data(buf, 30) < 30) {
Sunset_Debug::debugInfo(-1, getModuleAddress(), "ERROR...");
...
}
3.16.3

Serial Connections

The following examples are taken from the Sunset_Generic_Modem class.


In order to establish a serial connection, a new serial connection object has to be created and configured. The class
constructor takes in input the path to entry where the serial device is connected and the connection baud rate.
Sunset_Connection* connection;
//or Sunset_Serial_Connection* connection;
...
// DEVICE = devName, BAUDRATE = baudRate
connection = new Sunset_Serial_Connection(devName, baudRate);
After the class object creation, the connection to the specified serial device can be opened:
res = connection->open_connection();
if ( res == false ) {
//error
...
}
if ( res == true ) {
...
gPortFd = connection->get_fd();
}
Once all these actions have been completed, data can be read from and written to the serial device.
if( connection->write_data(fd, buffer, size) != true) {
Sunset_Debug::debugInfo(-1, getModuleAddress(), "Sunset_Generic_Modem::writeModem \
write failed! ERROR");
return 0;
}

Chapter 4

Virtual Machine
We provide a virtual machine (SUNSET.ova) which includes all the necessary tools, scripts, libraries and software to
compile and run SUNSET on X86 target architecture. Using the provided virtual machine and development toolchain,
it is very simple to compile and use SUNSET in simulation mode in a controlled environment to tune the network protocol parameters and to test and improve the protocol performance. Once this preparation and improvement phase is
completed, the same code can be run in emulation mode on the PC or it can be cross-compiled for the target embedded
device. The use of the provided virtual machine allows you to complete all these actions without any modification to
your machine.
You can download the SUNSET Virtual Machine from UWSN Group website at the following URL: http://reti.dsi.
uniroma1.it/UWSN_Group/framework/download/SUNSET.ova.
Different virtualization software are currently available which support the use of OVA extension, e.g., Virtualbox,
VMware Player, qemu, etc. However, some problems have been experienced using the VMware Player (depending on
the used version). We therefore recommend the use of the open source Virtualbox software which is fully compatible
with the provided SUNSET.ova file.
To use the provided virtual machine, your system must satisfy the following requirements:
Oracle VM Virtual Box installed (see https://www.virtualbox.org/) - or other compatible virtualization software.
CPU that supports PAE/NX functionality.
CPU that supports VT-x/AMD-V instructions.
In the provided configuration, a minimal Debian 7.0 distribution with Xfce 4 desktop environment has been installed
to reduce the amount of memory and resource needed by the virtual environment. Everything is configured to have an
internet access thus to download other packages if needed: actually very few packages have been installed to reduce
the size of the virtual machine. However, the most important software to start working with the virtual machine, such
as a graphical text editor (medit), an SSH server and client (openssh) and subversion, have been already provided.
To login into Debian use the following credentials:
97

98

Capitolo 4. Virtual Machine


User: sunset
Password: sunset

The sunset user has been already inserted in the sudoers file so every super user command can be executed also by
the sunset user through the sudo command.
The root password is sunset as well.

The structure of the prepared environment is the following, where everything is inside the sunset home folder (/home/sunset
ns_environment/: this folder contains all the tools, scripts and code needed to compile and run SUNSET on x86
environment. It contains several folders (Please, see Section 4.1 for further information):
build/: It contains all the compiled executable files and libraries for the target architecture which are organized
in the following sub-folders:
libNs/: It contains all the libraries, includes and executable files needed by ns to properly run.
ns-2/: It contains the ns-2 executable.
sunset_lib/: It contains all the needed libraries to properly run SUNSET: ns-miracle, WOSS and SUNSET.
stripped/: It contains all the stripped libraries.
tcl8.4.19/: The Tcl-8.4 package needed by ns.
tk8.4.19/: The Tk-8.4 package needed by ns.
tclcl-1.19/: The Tclcl-1.19 package needed by ns.
otcl-1.13/: The Otcl-1.13 package needed by ns.
dei80211mr-1.1.4/: The dei80211mr-1.1 package (optional).
ns-2.34/: The ns-2.34 package.
ns-miracle-1.0/: The ns-miracle-1.0 package. This folder is already under subversion control (SVN) to easily
update (see 4.3) the ns-miracle version if a new one is available.
WOSS/:
AcousticToolbox/: The Bellhop program.
NetCDF/: The NetCDF package to use the NetCDF database in WOSS.
woss-1.3.5/: The WOSS-1.3.5 package.
SUNSET: The latest version of the SUNSET framework. This folder is already under subversion control
(SVN) to easily update (see 4.4) the SUNSET version if a new one is available.
Note: The library and executable files destination folder is set to ns_environment*/build in each script: you will find
everything in this directory.

4.1. SUNSET x86

4.1

99

SUNSET x86

The /home/sunset/ns_environment/ folder contains all the tools, scripts and code that are needed to compile and
run SUNSET on x86 architecture. There are several .sh scripts that help you to compile each related package: if new
changes have to applied to the provided package, you only have to run the related script to re-compile it.
You can start immediately to play with SUNSET using one of the provided scripts in the SUNSET/samples/ directory.
To simulate an underwater network using the Bellhop ray tracer (through the WOSS interface) as
acoustic channel model with real environmental data, the different databases needed by WOSS have
to be downloaded. All the instruction to complete this action can be found on the WOSS web page at http:
//telecom.dei.unipd.it/ns/woss/.

4.2

Update Ns

In the provided virtual machine ns version 2.34 has been installed. In case a different (newer or older) ns-2 version is
needed by the user, it has to be downloaded from the ns-2 web page at http://www.isi.edu/nsnam/ns/.
When installing the new ns-2 version, if our installation script is used, please notice that you may have to change this
script (install_ns.sh) according to the new version.
IMPORTANT: Please notice that there is a problem when trying to use the ns-Miracle together with ns-2.35. Some
of the ns-Miracle libraries are not properly compiled and linked to support the use of the ns-2.35 software. To solve
this problem we have provided a patch for the older and newer version of ns-Miracle allowing to fix this issue and to
use ns-2.35. Once patched, ns-Miracle is still fully compatible with the other ns-2 versions. We gratefully acknowledge
Maksym Komar for his help in providing these patches.
In what follows we describe how to patch the older and the newer version of ns-Miracle.
4.2.1

Patching ns-Miracle: older version

In order to patch the older version of ns-Miracle and to have it properly running with ns-2.35, you need to download
ns-Miracle patches archive (nsmiracle_patches.tar.gz) from the Senses Lab UWSN Group website at the following url:
http://reti.dsi.uniroma1.it/UWSN_Group/framework/download/nsmiracle_patches.tar.gz.
After you have downloaded the archive copy it into the ns_environment folder. Using your terminal, go to the
ns_environment folder and untar the downloaded archive. After that you can apply the patches.
To untar the archive type from the ns_environment folder:
tar -zxvf nsmiracle_patches.tar.gz
patch -p0 < nsmiracle_patches/nsmiracle-trunk-fix-libs-dependence.patch
patch -p0 < nsmiracle_patches/nsmiracle-trunk-fix-warning.patch
To apply the patches, type:
patch -p0 < nsmiracle_patches/nsmiracle-trunk-fix-libs-dependence.patch
patch -p0 < nsmiracle_patches/nsmiracle-trunk-fix-warning.patch
If you notice path problems while patching, please take a look at the patch manual (type man patch in your terminal).

100
4.2.2

Capitolo 4. Virtual Machine


Patching Ns-Miracle: newer version

In the newer version of ns-Miracle, the folder containing the Urick acoustic channel model has been moved from the
WOSS folder to ns-Miracle. Therefore such a folder has to be patched as well.
In order to patch the newer version of ns-Miracle and to have it properly running with ns-2.35, you need to download
ns-Miracle patches archive (nsmiracle_patches.tar.gz) from the Senses Lab UWSN Group website at the following url:
http://reti.dsi.uniroma1.it/UWSN_Group/framework/download/nsmiracle_patches.tar.gz.
Once the archive has been downloaded, you can copy it into the ns_environment folder. Using your terminal, go to the
ns_environment folder and untar the downloaded archive, as described above. After that you can apply the patches.
patch -p0 < nsmiracle_patches/nsmiracle-trunk-fix-libs-dependence.patch
patch -p0 < nsmiracle_patches/nsmiracle-trunk-fix-warning.patch
patch -p0 < nsmiracle_patches/nsmiracle-trunk-fix-uwm-lib-dependence.patch
If you notice path problems while patching, please take a look at the patch manual (type man patch in your terminal).

4.3

Update Ns-Miracle

To update the version of ns-Miracle, in case a new version is available, the subversion tool can be used. You have
only to browse to the ns-miracle-1.0/trunk/main/ directory and type:
svn update
Note that you may have to change the installation script (install_nsmiracle.sh) according to the new version.

4.4

Update SUNSET

Similarly, to update the version of SUNSET, in case a new version is available, the subversion tool can be used.
What you need to do it to to browse to the SUNSET/ directory and type:
svn update

4.5

Update WOSS

In case a new version of WOSS is available and it has to be installed, the package has to be manually downloaded
and installed. When installing the new version of WOSS, if our installation script is used, please notice that you may
have to change this script (install_WOSSAlone.sh and install_WOSS.sh) according to the new version.

Chapter 5

User group
The SUNSET user-group has been created with the intention to create a community of researchers and developers
supporting SUNSET and an open environment to ask questions, solve problems and share ideas.
Although several solutions have already been implemented for SUNSET and some of them have been made available
to the researching community, our intention is not to implement all the solutions proposed for UWSNs but to help
researchers and developers to implement their own solutions using SUNSET so that such solutions can be tested by
means of both simulation and real-life testing. Especially when running solutions in real-life testing, small details in the
implementation can make the difference in the protocol performance: for this reason we would like to encourage protocol
authors to implement their own solution in order to avoid any possible uncorrected implementation which could result
in a not proper protocol performance evaluation.
The SUNSET user-group is available at https://groups.google.com/group/sunset-user-group. Anybody can view
group content but only members can post messages. People can request an invitation to join the SUNSET user-group
sending an e-mail to sunset.group@di.uniroma1.it.

101

Chapter 6

Example scripts
In what follows we provide a description of the different scripts that can be found in the samples folder. We provide
different examples to run the system in both simulation and emulation mode. When running in simulation mode, several
examples are provided making use of the Urick and Bellhop channel models and of different configurations: Protocol
stack, error models, etc. When running in emulation mode, several examples are provided as well where the channel
emulator, the Evologics modem and the WHOI FSK Micro-Modem are are used. We show also how to blacklist the
nodes in the network, making some direct link not sable in the network.
In each scripts all the experiment parameters are stored in the Tcl params array. These parameters can be initialized
in the Tcl scripts or can be set from the command line when running the test.
Two of the available parameters are:
params(id) ;# ID of the node when running in emulation mode
params(debug) ;# Debug level used for the Sunste_Debug module
To set these values within the Tcl script, you can type:
set params(id) 2; # node ID is set to 2
set params(debug) 3;# Debug level is set to 3
When running a script, e.g., the emulation script runEvologics.tcl, it can be run without any parameters, the settings
as in the Tcl script are considered:
ns ./runEvologics.tcl
while providing also a list of parameters, these will overwrite the setting in the Tcl script. To overwrite id and debug
setting you can type:
ns ./runEvologics.tcl -id 5 -debug 4 ...
Each parameter is addressed using - and the name of the parameter such as in the params array.
In what follows we provide additional details on the different examples which have been provided to run simulations
and emulation tests. Two different application layer modules are considered (Agent and CBR). At the Datalink layer
the Aloha protocol is considered and the Static Routing at the network layer. To use a different Datalink protocol:
Csma Aloha, Slotted Csma or Tdma, the following line in the Tcl script creating the Aloha MAC module
103

104
set mac_($id)

Capitolo 6. Example scripts


[new "Module/MMac/Sunset_Aloha"]

has to be replace with one of the following lines according to the selected protocol:
set mac_($id)

[new "Module/MMac/Sunset_Csma_Aloha"]

or
set mac_($id)

[new "Module/MMac/Sunset_Slotted_Csma"]

or
set mac_($id)

[new "Module/MMac/Sunset_Tdma"]

The proper library has to be loaded:


load $pathSUNSET/libSunset_Networking_Aloha.so.0.0.0
has to be replace with:
load $pathSUNSET/libSunset_Networking_Csma_Aloha.so.0.0.0
or
load $pathSUNSET/libSunset_Networking_Slotted_Csma.so.0.0.0
or
load $pathSUNSET/libSunset_Networking_Tdma.so.0.0.0

In order to see how to initialize the parameters and settings for each MAC protocol (packet header sizes, slot duration
etc.) please take a look to the command function implemented by each MAC protocol or to the init.tcl file located in
each protocol folder:

sunset_csma_aloha-init.tcl in the Sunset_Csma_Aloha folder


sunset_slotted_csma-init.tcl in the Sunset_Slotted_Csma folder
sunset_tdma-init.tcl in the Sunset_Tdma folder

Similarly to use the Flooding protocol instead of the Static Routing, the Flooding module has to be created.

6.1. Simulation

105

set routing_($id) [new "Module/Sunset_Flooding"]


The Flooding library has to be loaded
load $pathSUNSET/libSunset_Networking_Flooding
For the initialization of the Flooding module parameters, the file sunset_flooding-init.tcl in the Sunset_Flooding
folder can be taken as an example or the command function implemented by the Flooding module.

6.1

Simulation

All the simulation Tcl examples are located in the samples/simulation/ folder.
All the provided examples, making use of the WOSS interface, have been configured to run with a WOSS version newer
than woss-1.2.0. If woss-1.2.0 is used the following lines have to be removed/commented in the Tcl script(s):
set altimetry_creator
[new "WOSS/Definitions/Altimetry/Bretschneider"]
$def_handler setAltimetryCreator
$altimetry_creator
WOSS/Definitions/Altimetry/Flat set evolution_time_quantum
-1
WOSS/Definitions/Altimetry/Flat set range
-1
WOSS/Definitions/Altimetry/Flat set total_range_steps
-1
WOSS/Definitions/Altimetry/Flat set depth
0.0
set cust_altimetry [new "WOSS/Definitions/Altimetry/Flat"]
$woss_creator setAltimetryType 0 0 "L"
6.1.1

runUrick.tcl

This script is configured to use the Urick channel model. The protocol stack is as following:
CBR
Portmap
Transport
Static Routing
Mac Aloha
BPSK Phy Layer (Urick)
Channel (Urick Module)
The Urick configure file can be found at tcl_folder/UrickFile.tcl.
A network with five nodes, IDs: 1, 2, 3, 4, 5 is created. The node positions are set such as defined in the topology_sim.tcl file. Two possible traffic models are supported: CBR and Poisson. You can select to use the Constant Bit
Rate or the Poisson traffic model by setting the params(lambda) to 0 or 1, respectively. The traffic rate can be set using
the params(cbr_period) variable. When params(lambda) is set to 0 (CBR is used), one packet every params(cbr_period)

106

Capitolo 6. Example scripts

seconds is generated by each node in the network, with the exception of the sink, if any. When params(lambda) is set to
1 instead the Poisson traffic model is used, params(cbr_period) packets per second are generated by each node in the
network, with the exception of the sink, if any.
To start/stop the data packet generation the CBR modules have to be started/stopped. You can take a look to the Tcl
examples on how to start and stop the CBR flows:
"$cbr_($id) start"
"$cbr_($id) stop"
At the end of the run, if the params(useStat) is set to 0 only the CBR Module statistics are printed, otherwise all the
SUNSET statistics will be printed.
6.1.2

runBellhop.tcl

This script is configured to use the Bellhop ray tracer via the WOSS interface. The protocol stack is as following:
CBR
Portmap
Transport
Static Routing
Mac Aloha
BPSK Phy Layer (Bellhop)
Channel (Bellhop Module)
You can use Bellhop loading real environmental data from the GEBCO Database setting the use_db parameter to 1
and configuring the right path to the database in the tcl_folder/WossFileWithDb.tcl file. If the use_db parameter is
set to 0 then the tcl_folder/WossFileWithoutDb.tcl will be loaded.
A network with five nodes, IDs: 1, 2, 3, 4, 5 is created. The node positions are set such as defined in the topology_sim.tcl file.
Two possible traffic models are supported: CBR and Poisson. You can select to use the Constant Bit Rate or the
Poisson traffic model by setting the params(lambda) to 0 or 1, respectively. The traffic rate can be set using the
params(cbr_period) variable. When params(lambda) is set to 0 (CBR is used), one packet every params(cbr_period)
seconds is generated by each node in the network, with the exception of the sink, if any. When params(lambda) is set to
1 instead the Poisson traffic model is used, params(cbr_period) packets per second are generated by each node in the
network, with the exception of the sink, if any.
To start/stop the data packet generation the CBR modules have to be started/stopped. You can take a look to the Tcl
examples on how to start and stop the CBR flows:

6.1. Simulation

107

"$cbr_($id) start"
"$cbr_($id) stop"
At the end of the run, if the params(useStat) is set to 0 only the CBR Module statistics are printed, otherwise all the
SUNSET statistics will be printed.
6.1.3

runSUNSETUrick.tcl

This script is configured to use the SUNSET Urick channel model and the SUNSET Energy model, it also prints out
the related statistics. The SUNSET Urick channel model extends the basic Urick channel model, but it support to use
of the more accurate energy model provided by SUNSET.
The protocol stack follows:
CBR
Portmap
Transport
Static Routing
Mac Aloha
BPSK Phy Layer (SUNSET Urick)
Channel (Urick Module)
The SUNSET Urick configure file can be found at tcl_folder/SUNSETUrickFile.tcl.
The instruction on how to configure the the SUNSET Energy model can be found in 3.9.
A network with five nodes, IDs: 1, 2, 3, 4, 5 is created. The node positions are set such as defined in the topology_sim.tcl file.
Two possible traffic models are supported: CBR and Poisson. You can select to use the Constant Bit Rate or the
Poisson traffic model by setting the params(lambda) to 0 or 1, respectively. The traffic rate can be set using the
params(cbr_period) variable. When params(lambda) is set to 0 (CBR is used), one packet every params(cbr_period)
seconds is generated by each node in the network, with the exception of the sink, if any. When params(lambda) is set to
1 instead the Poisson traffic model is used, params(cbr_period) packets per second are generated by each node in the
network, with the exception of the sink, if any.
To start/stop the data packet generation the CBR modules have to be started/stopped. You can take a look to the Tcl
examples on how to start and stop the CBR flows:
"$cbr_($id) start"
"$cbr_($id) stop"
At the end of the run, if the params(useStat) is set to 0 then the CBR Module and SUNSET Energy Module statistics
are printed, otherwise the SUNSET statistics will be printed.

108
6.1.4

Capitolo 6. Example scripts


runSUNSETBellhop.tcl

This script is configured to use the SUNSET Bellhop channel model and the SUNSET Energy model , it also prints out
the related statistics. The protocol stack follows:
CBR
Portmap
Transport
Static Routing
Mac Aloha
BPSK Phy Layer (SUNSET Bellhop)
Channel (Bellhop Module)
You can use Bellhop loading real environmental data from the GEBCO Database setting the use_db parameter to 1 and
configuring the right path to the database in the tcl_folder/SUNSETBellhopFileDb.tcl file. If the use_db parameter
is set to 0 then the tcl_folder/SUNSETBellhopFileNoDb.tcl will be loaded.
The instruction on how to configure the the SUNSET Energy model can be found in 3.9.
A network with five nodes, IDs: 1, 2, 3, 4, 5 is created. The node positions are set such as defined in the topology_sim.tcl file.
Two possible traffic models are supported: CBR and Poisson. You can select to use the Constant Bit Rate or the
Poisson traffic model by setting the params(lambda) to 0 or 1, respectively. The traffic rate can be set using the
params(cbr_period) variable. When params(lambda) is set to 0 (CBR is used), one packet every params(cbr_period)
seconds is generated by each node in the network, with the exception of the sink, if any. When params(lambda) is set to
1 instead the Poisson traffic model is used, params(cbr_period) packets per second are generated by each node in the
network, with the exception of the sink, if any.
To start/stop the data packet generation the CBR modules have to be started/stopped. You can take a look to the Tcl
examples on how to start and stop the CBR flows:
"$cbr_($id) start"
"$cbr_($id) stop"
At the end of the run, if the param useStat is set to 0 then the CBR Module and SUNSET Energy Module statistics
are printed, otherwise the SUNSET statistics will be printed.

6.1. Simulation
6.1.5

109

runSUNSETUrick_agt.tcl

This script is configured to use the SUNSET Urick channel model. The Sunset_Agent class is used at the application
layer. The protocol stack follows:
Agent
Static Routing
Mac Aloha
BPSK Phy Layer (SUNSET Urick)
Channel (Urick Module)
The SUNSET Urick configure file can be found at tcl_folder/SUNSETUrickFile.tcl.
The instruction on how to configure the the SUNSET Energy model can be found in 3.9.
A network with five nodes, IDs: 1, 2, 3, 4, 5 is created. The node positions are set such as defined in the topology_sim.tcl file.
Two possible traffic models are supported: CBR and Poisson. The packet are created directly by the Agent layer (instead of by the CBR module). You can select to use the Constant Bit Rate or the Poisson traffic model by setting
the params(lambda) to 0 or 1, respectively. The traffic rate can be set using the params(cbr_period) variable. When
params(lambda) is set to 0 (CBR is used), one packet every params(cbr_period) seconds is generated in the network
and a node, with the exception of the sink (if any) is randomly selected as data source. When params(lambda) is set to
1 instead the Poisson traffic model is used, params(cbr_period) packets per second are generated in the network and
a node, with the exception of the sink (if any) is randomly selected as data source. When params(usePktTime) is set
to 1 lambda does not represent the number of packets per second generated in the network but instead the number
of packets per packet time generated in the network. The destination ID of each created packet is always the sink
(params(sink)) unless params(randomDest) is set to 1. In this case a random destination is selected for each packet.
The params(traffic_barrier) defines the time before the end of the experiment, at which the data generation has to be
stopped in order to permit to deliver the latest packets generated in the network. If the params(genTraffic) is set to 0
no packet will be generated in the network.
At the end of the run, if the param useStat is set to 0 then the CBR Module and SUNSET Energy Module statistics
are printed, otherwise the SUNSET statistics will be printed.
6.1.6

runSUNSETBellhop_agt.tcl

This script is configured to use the SUNSET Bellhop channel model, the SUNSET Agent layer (to generate data packets),
the SUNSET Energy model and to print the related statistics. The protocol stack follows:
Agent
Static Routing

110

Capitolo 6. Example scripts

Mac Aloha
BPSK Phy Layer (SUNSET Bellhop)
Channel (Bellhop Module)
You can use Bellhop loading real environmental data from the GEBCO Database setting the use_db parameter to 1 and
configuring the right path to the database in the tcl_folder/SUNSETBellhopFileDb.tcl file. If the use_db parameter
is set to 0 then the tcl_folder/SUNSETBellhopFileNoDb.tcl will be loaded.
The instruction on how to configure the the SUNSET Energy model can be found in 3.9.
A network with five nodes, IDs: 1, 2, 3, 4, 5 is created. The node positions are set such as defined in the topology_sim.tcl file.
Two possible traffic models are supported: CBR and Poisson. The packet are created directly by the Agent layer (instead of by the CBR module). You can select to use the Constant Bit Rate or the Poisson traffic model by setting
the params(lambda) to 0 or 1, respectively. The traffic rate can be set using the params(cbr_period) variable. When
params(lambda) is set to 0 (CBR is used), one packet every params(cbr_period) seconds is generated in the network
and a node, with the exception of the sink (if any) is randomly selected as data source. When params(lambda) is set to
1 instead the Poisson traffic model is used, params(cbr_period) packets per second are generated in the network and
a node, with the exception of the sink (if any) is randomly selected as data source. When params(usePktTime) is set
to 1 lambda does not represent the number of packets per second generated in the network but instead the number
of packets per packet time generated in the network. The destination ID of each created packet is always the sink
(params(sink)) unless params(randomDest) is set to 1. In this case a random destination is selected for each packet.
The params(traffic_barrier) defines the time before the end of the experiment, at which the data generation has to be
stopped in order to permit to deliver the latest packets generated in the network. If the params(genTraffic) is set to 0
no packet will be generated in the network.
At the end of the run, if the param useStat is set to 0 then the CBR Module and SUNSET Energy Module statistics
are printed, otherwise the SUNSET statistics will be printed.
6.1.7

runSUNSETUrick_agt_per.tcl

This script is configured to use the SUNSET Urick channel model with the Packet Error Model. The protocol stack
follows:
Agent
Static Routing
Mac Aloha
BPSK Phy Layer (SUNSET Urick)
Channel (Urick Module)

6.2. Emulation

111

The SUNSET Urick configure file can be found at tcl_folder/SUNSETUrickFile.tcl.


The instruction on how to configure the the SUNSET Energy model can be found in 3.9.
A network with five nodes, IDs: 1, 2, 3, 4, 5 is created. The node positions are set such as defined in the topology_sim.tcl file.
Two possible traffic models are supported: CBR and Poisson. The packet are created directly by the Agent layer (instead of by the CBR module). You can select to use the Constant Bit Rate or the Poisson traffic model by setting
the params(lambda) to 0 or 1, respectively. The traffic rate can be set using the params(cbr_period) variable. When
params(lambda) is set to 0 (CBR is used), one packet every params(cbr_period) seconds is generated in the network
and a node, with the exception of the sink (if any) is randomly selected as data source. When params(lambda) is set to
1 instead the Poisson traffic model is used, params(cbr_period) packets per second are generated in the network and
a node, with the exception of the sink (if any) is randomly selected as data source. When params(usePktTime) is set
to 1 lambda does not represent the number of packets per second generated in the network but instead the number
of packets per packet time generated in the network. The destination ID of each created packet is always the sink
(params(sink)) unless params(randomDest) is set to 1. In this case a random destination is selected for each packet.
The params(traffic_barrier) defines the time before the end of the experiment, at which the data generation has to be
stopped in order to permit to deliver the latest packets generated in the network. If the params(genTraffic) is set to 0
no packet will be generated in the network.
The error model select for this test is the FSK with a SNR penalty (in DB) on the receiver set to 10.0.
At the end of the run, if the param useStat is set to 0 then the CBR Module and SUNSET Energy Module statistics
are printed, otherwise the SUNSET statistics will be printed.

6.2

Emulation

All the emulation Tcl examples are located in the samples/emulation/ folder.
Note: You can run multiple instances of SUNSET on your machine to emulate multiple nodes in the network simply
invoking the same script changing some parameters, such as the node ID (-id), Evologics TCP IP and port, etc.
6.2.1

channelEmulator.tcl

This script is configured to use the SUNSET Channel Emulator, SUNSET Channel Emulator Position module, SUNSET
Agent layer (to generate data packets), the SUNSET Phy Layer, the Packet Error Model and to print the related
statistics. The protocol stack follows:
Agent
Static Routing
Mac Aloha

112

Capitolo 6. Example scripts

SUNSET Phy Layer


Channel (Channel Emulator Module)
The Packet Error Model is set to static with a Packet Error Rate equal to 0.1. You can change the TCP IP and port
of the channel emulator by changing the following parameter:
set params(emulator_ip)
"127.0.0.1"
set params(emulator_port) 8000
The Channel Emulator is created by calling the startChannel function.
proc startChannel {} {
global params channel
set channel [new Module/Sunset_Channel_Emulator]
$channel setChannelPort $params(emulator_port)
$channel setPositionPort $params(emulator_port_pos)
$channel
$channel
$channel
$channel

positionEmulation $params(emulator_usePos)
setDefPropDelay
$params(emulator_defProp)
setModuleAddress $params(id)
start

}
As you can see, the Channel Emulator is configured to use the Channel Emulator Position module. You can change the
related TCP IP and port by changing the following parameters:
set params(emulator_port_pos)
set params(emulator_defProp)
set params(emulator_useNSPos)

8001
1.0
1

The nodes positions are set by the Tcl itself (emulator_useNSPos is set to 1) and the Position module is started by
invoking the startPosition function:
proc startPosition {} {
global params channel sunPos
set sunPos [new Module/Sunset_Position_Channel]
#position_tick --> how often read the node position

6.2. Emulation
$sunPos
$sunPos
$sunPos
$sunPos

113

checkNSPos $params(position_useNS) $params(position_tick)


setModuleAddress $params(id)
setIp
$params(emulator_ip)
setPort
$params(emulator_port_pos)

}
The nodes positions are loaded from the topology_channel_emu.tcl file.
If you dont want to use the Position Module, the default propagation delay (emulator_defProp) will be used.
You can try this module by invoking the following commands in separated terminal tabs:
ns ./channelEmulator -id 1 -sink 1 -genTraffic 0
ns ./channelEmulator -id 2 -sink 1 -genTraffic 1 -cbr_period 10
The node 2 will send every 10 seconds a packet to the node 1 (the sink).
Two possible traffic models are supported: CBR and Poisson. The packet are created directly by the Agent layer (instead of by the CBR module). You can select to use the Constant Bit Rate or the Poisson traffic model by setting
the params(lambda) to 0 or 1, respectively. The traffic rate can be set using the params(cbr_period) variable. When
params(lambda) is set to 0 (CBR is used), one packet every params(cbr_period) seconds is generated in the network by
the emulated node, with the exception of the sink (if any). When params(lambda) is set to 1 instead the Poisson traffic
model is used, params(cbr_period) packets per second are generated in the network by the emulated node, with the
exception of the sink (if any). When params(usePktTime) is set to 1 lambda does not represent the number of packets
per second generated in the network but instead the number of packets per packet time generated in the network.
The destination ID of each created packet is always the sink (params(sink)) unless params(randomDest) is set to 1.
In this case a random destination is selected for each packet. The params(traffic_barrier) defines the time before the
end of the experiment, at which the data generation has to be stopped in order to permit to deliver the latest packets
generated in the network. If the params(genTraffic) is set to 0 no packet will be generated in the network.
At the end of the run, the SUNSET Agent Module statistics are printed.
The Phy layer Blacklist feature has not bee used: to know how to add it please take a look at the Section 6.2.2.
When running in emulation mode, multiple SUNSET instances have to be run (one per node) on the same machine or
on different machine, each of them collecting its own statistic data. These data are stored in different files. When the
test is finished, all the statistics data files can be retrieved and post processed to collect network statistics instead of
node statistics.
6.2.2

channelEmulator_black.tcl

This script adds the Phy Blacklist feature to that described in Section 6.2.1. For further information on the Blackist
feature please refer to the Sections 2.3.2 and 3.13.
The function called to blacklist the nodes is createBlacklist:

114

Capitolo 6. Example scripts

proc createBlacklist {} {
global params phy
if { $params(id) == 1 } {
$phy($params(id)) addToBlacklist 4
$phy($params(id)) addToBlacklist 5
$phy($params(id)) addToBlacklist 6
}
...
if { $params(id) == 3 } {
$phy($params(id)) addToBlacklist 1
}
if { $params(id) == 4 } {
$phy($params(id)) addToBlacklist 1
$phy($params(id)) addToBlacklist 2
}
...
}
As you can see, there is no link between node 1 and node 4 and the is only a direct link from node 1 to node 3, but no
link from 3 to 1.
When running in emulation mode, multiple SUNSET instances have to be run (one per node) on the same machine or
on different machine, each of them collecting its own statistic data. These data are stored in different files. When the
test is finished, all the statistics data files can be retrieved and post processed to collect network statistics instead of
node statistics.
6.2.3

runEvologics.tcl

This script is configured to use the Evologics v1.6 acoustic modems (through the SUNSET Evologics driver) for data
transmissions and receptions. The protocol stack follows:
CBR
Portmap
Transport
Static Routing
Mac Aloha

6.2. Emulation

115

SUNSET Phy Layer


Evologics Modem (SUNSET Evologics driver)
The SUNSET Evologics driver tries to connect to the socketEvoId IP at the evoPort port. All the modem settings follow
(EVOLOGICS section):
#EVOLOGICS
set params(evo)
set params(evoPort)
set params(socketEvoId)
set params(evoPower)
set params(evo_bitrate)
set params(evo_data_bitrate)
set params(evo_ctrl_bitrate)
set params(evo_max_pkt_size)
set params(evo_version)

1
9200
;# it defines the modem port
"127.0.0.1"
;# it defines the modem IP
3
;# it defines the modem transmission power
500
500
500
$params(max_pktDataSize)
"1.6"

The modem delays can be also set in the MODEM DELAY section:
#MODEM DELAY
set params(evo_delay)
set params(evo_data_delay)
set params(evo_ctrl_delay)

0.3
0.3
0.3

The Timing Emulation module will be configured according to these values.


The Packet Error Model has not bee used at PHY layer: to know how to add it please take a look at the Section 6.2.1.
The Phy layer Blacklist feature has not bee used: to know how to add it please take a look at the Section 6.2.2.
The packet error model and black list feature are mainly meant when running in simulation but they can be also used
in emulation mode to design a desired network or channel conditions.
Two possible traffic models are supported: CBR and Poisson. You can select to use the Constant Bit Rate or the
Poisson traffic model by setting the params(lambda) to 0 or 1, respectively. The traffic rate can be set using the
params(cbr_period) variable. When params(lambda) is set to 0 (CBR is used), one packet every params(cbr_period)
seconds is generated by the emulated node, with the exception of the sink, if any. When params(lambda) is set to 1
instead the Poisson traffic model is used, params(cbr_period) packets per second are generated by the emulated node,
with the exception of the sink, if any.
To start/stop the data packet generation the CBR modules have to be started/stopped. You can take a look to the Tcl
examples on how to start and stop the CBR flows:
"$cbr_($id) start"
"$cbr_($id) stop"

116

Capitolo 6. Example scripts

When running in emulation mode, multiple SUNSET instances have to be run (one per node) on the same machine or
on different machine, each of them collecting its own statistic data. These data are stored in different files. When the
test is finished, all the statistics data files can be retrieved and post processed to collect network statistics instead of
node statistics.
6.2.4

runEvologics_agt.tcl

This script is configured to use the Evologics v1.6 acoustic modems (through the SUNSET Evologics driver) for data
transmissions and receptions and the SUNSET Agent layer (to generate data packets). The protocol stack follows:
Agent
Static Routing
Mac Aloha
SUNSET Phy Layer
Evologics Modem (SUNSET Evologics driver)
The SUNSET Evologics driver tries to connect to the socketEvoId IP at the evoPort port. All the modem settings follow
(EVOLOGICS section):
#EVOLOGICS
set params(evo)
set params(evoPort)
set params(socketEvoId)
set params(evoPower)
set params(evo_bitrate)
set params(evo_data_bitrate)
set params(evo_ctrl_bitrate)
set params(evo_max_pkt_size)
set params(evo_version)

1
9200
;# it defines the modem port
"127.0.0.1"
;# it defines the modem IP
3
;# it defines the modem transmission power
500
500
500
$params(max_pktDataSize)
"1.6"

The modem delays can be also set in the MODEM DELAY section:
#MODEM DELAY
set params(evo_delay)
set params(evo_data_delay)
set params(evo_ctrl_delay)

0.3
0.3
0.3

The Timing Emulation module will be configured according to these values.


The Packet Error Model has not bee used at PHY layer: to know how to add it please take a look at the Section 6.2.1.
The Phy layer Blacklist feature has not bee used: to know how to add it please take a look at the Section 6.2.2.

6.2. Emulation

117

Two possible traffic models are supported: CBR and Poisson. The packet are created directly by the Agent layer (instead of by the CBR module). You can select to use the Constant Bit Rate or the Poisson traffic model by setting
the params(lambda) to 0 or 1, respectively. The traffic rate can be set using the params(cbr_period) variable. When
params(lambda) is set to 0 (CBR is used), one packet every params(cbr_period) seconds is generated in the network by
the emulated node, with the exception of the sink (if any). When params(lambda) is set to 1 instead the Poisson traffic
model is used, params(cbr_period) packets per second are generated in the network by the emulated node, with the
exception of the sink (if any). When params(usePktTime) is set to 1 lambda does not represent the number of packets
per second generated in the network but instead the number of packets per packet time generated in the network.
The destination ID of each created packet is always the sink (params(sink)) unless params(randomDest) is set to 1.
In this case a random destination is selected for each packet. The params(traffic_barrier) defines the time before the
end of the experiment, at which the data generation has to be stopped in order to permit to deliver the latest packets
generated in the network. If the params(genTraffic) is set to 0 no packet will be generated in the network.
At the end of the run, the SUNSET Agent Module statistics are printed.
When running in emulation mode, multiple SUNSET instances have to be run (one per node) on the same machine or
on different machine, each of them collecting its own statistic data. These data are stored in different files. When the
test is finished, all the statistics data files can be retrieved and post processed to collect network statistics instead of
node statistics.
6.2.5

runMicromodem.tcl

This script is configured to use the FSK WHOI Micro-Modem acoustic modems (through the SUNSET Micro-Modem
driver) for data transmissions and receptions. The protocol stack follows:
CBR
Portmap
Transport
Static Routing
Mac Aloha
SUNSET Phy Layer
FSK WHOI Micro-Modem (SUNSET Micromodem driver)
The SUNSET Micro-Modem driver tries to connect to the mm_serial serial device at the mm_baudRate baudrate. All
the modem settings follow (MICRO-MODEM section):
#MICRO-MODEM
set params(mm)
set params(mm_ascii)
set params(mm_hex)
set params(mm_serial)

1
0
1
"/dev/ttyS1" ;# serial line the Micro-Modem is connected to

118
set
set
set
set
set
set
set
set
set
set
set

Capitolo 6. Example scripts


params(mm_baudRate)
params(mm_gps)
params(mm_rate)
params(mm_miniPkt)
params(mm_modemAck)
params(mm_agn)
params(mm_cto)
params(mm_bitrate)
params(mm_data_bitrate)
params(mm_ctrl_bitrate)
params(mm_max_pkt_size)

19200
0
0
1
0
250
30
80
80
80
32

The modem delays can be also set in the MODEM DELAY section:
#MODEM DELAY
set params(mm_delay)
set params(mm_data_delay)
set params(mm_ctrl_delay)

2.8
2.8
1

The Timing Emulation module will be configured according to these values.


The Packet Error Model has not bee used at PHY layer: to know how to add it please take a look at the Section 6.2.1.
The Phy layer Blacklist feature has not bee used: to know how to add it please take a look at the Section 6.2.2.
Two possible traffic models are supported: CBR and Poisson. You can select to use the Constant Bit Rate or the
Poisson traffic model by setting the params(lambda) to 0 or 1, respectively. The traffic rate can be set using the
params(cbr_period) variable. When params(lambda) is set to 0 (CBR is used), one packet every params(cbr_period)
seconds is generated by the emulated node, with the exception of the sink, if any. When params(lambda) is set to 1
instead the Poisson traffic model is used, params(cbr_period) packets per second are generated by the emulated node,
with the exception of the sink, if any.
To start/stop the data packet generation the CBR modules have to be started/stopped. You can take a look to the Tcl
examples on how to start and stop the CBR flows:
"$cbr_($id) start"
"$cbr_($id) stop"
When running in emulation mode, multiple SUNSET instances have to be run (one per node) on the same machine or
on different machine, each of them collecting its own statistic data. These data are stored in different files. When the
test is finished, all the statistics data files can be retrieved and post processed to collect network statistics instead of
node statistics.

Anda mungkin juga menyukai