You are on page 1of 23

SOFTWARE PRACTICE AND EXPERIENCE

Softw. Pract. Exper. 2013; 43:501523


Published online 16 April 2012 in Wiley Online Library (wileyonlinelibrary.com). DOI: 10.1002/spe.2119

A wireless sensor network framework based on light databases


Eduardo Caete* , , Manuel Daz and Bartolom Rubio
University of Mlaga, Dpto. Lenguajes y ciencias de la Computacin. Calle de Bulevard Louis Pasteur,
s/n. 29071 Mlaga, Spain

SUMMARY
The development of wireless sensor and actor network applications is made difficult by the fact that developers have to face up to a set of resource-constrained devices which have to work wirelessly and distributely. In
this work, we propose a framework to create and integrate light databases within nodes that need to manage
and process data. The databases will be designed by means of simple entity-relationship models from which
the code needed to manage the database will be generated. Basically, this code will be composed of data
structures and the algorithms in charge of managing them. This architecture will help developers avoid data
redundancy to better manage the memory of the nodes and to save time in developing applications. Copyright
2012 John Wiley & Sons, Ltd.
Received 19 September 2011; Revised 5 March 2012; Accepted 17 March 2012
KEY WORDS:

wireless sensor network ; databases ; design ; high-level programming ; framework

1. INTRODUCTION
Wireless sensor and actor networks (WSANs) [1] are promising technology which allows users to
monitor and control any kind of scenario (indoor environment, whole cities, woods, . . . ) [2]. These
networks are composed of tiny devices which are quite resource-constrained because of their small
size. They are normally characterized by their short-range wireless communication capabilities,
short battery-life, small memory, and limited CPU processing capabilities.
One of the main issues during the development of a WSAN application is designing and implementing the data structures and algorithms necessary to manage the local information (clustering,
routing, sensed data, . . . ) collected by each node which forms a part of the whole sensor network.
For example, in most WSAN applications, each node manages the information of their neighbors
(battery level, identifiers, RSSI, LQI, etc.) [3]. If, in addition, the developed application is based on
clusters, nodes also have to manage information to know which cluster they belong to, and cluster
heads would store information on which nodes are members [4].
In short, nodes have to manage a substantial amount of information, which varies on the basis
of the goal of the application. We think it can be very useful to have a framework that, on the one
hand, allows developers to design all the data structures needed by the nodes graphically and, on
the other hand, automatically generates the necessary codes to manage all the data structures specified. This framework would facilitate the developers task as any required change in the application
can be performed in a graphical way, and the needed new code will be generated automatically.
Developers will save a lot of time because they do not have to analyze the code to see which part
must be changed. It could be even worse if the developer who has to change the code is not the
same person who developed the application. Often, this way of working can introduce difficult to
*Correspondence to: Eduardo Caete, University of Mlaga, E.T.S.I Informtica, Bulevar Louis Pasteur, 35. Campus
Teatinos. Lab 3.3.2, 29071 Mlaga, Spain..
E-mail: ecc@lcc.uma.es
Copyright 2012 John Wiley & Sons, Ltd.

502

E. CAETE, M. DAZ AND B. RUBIO

detect side effects in the application. However, the framework would also help designers and developers understand much better the behavior of the application, thanks to the graphical design of the
data structures.
In this paper, we present a framework to create light databases in charge of managing all the data
structure needed by the developers. Basically, the framework will allow developers to create a basis
entity-relationship model (ERM) from which all the codes needed to manage the data structure will
be generated. This code means that developers can interact with the database information by means
of a set of primitives which will be exposed to them through an API. From the generated code point
of view, we are aware that developers are also able to implement the same code as efficiently as
the framework, but it is also true that the code written by developers is error-prone. In contrast, the
framework will not only always generate the code in the same way but also future versions of the
framework will be improved to be more and more efficient. Finally, we would like to emphasize that
this framework is not thought to deal with the distributed nature of a sensor network in a direct way,
but it is thought to improve the performance of each individual node which, of course, will improve
the performance of the whole sensor network.
We would like to emphasize the fact that our work is a contribution to the WSAN research field
in the sense that it effectively provides the following innovations:
1. To the best of our knowledge, our approach is the first one that integrates light database management systems (DBMS) within sensor nodes in order to efficiently manage and structure
information. By using light DBMS within the nodes, several advantages are achieved
The ERM shows us not only the data structure used in the application, but it also shows us
the relationship between them.
Avoid data redundancy. It is important as the nodes used are devices with little storage
capacity.
Greater data integrity and independence from applications.
Improved data access to users through the use of primitives.
Reduced data entry, storage, and retrieval costs. It helps to reduce the energy consumption
of the nodes.
Facilitated development of new applications.
2. The proposed framework allows developers to graphically design the database model through
which they want to manage the data used by the nodes.
3. The model designed graphically shows in real time the memory space needed by the data structures and the algorithms used to interact with them. It facilitates users to choose the best design
in terms of memory constraint.
4. The code generated offers a friendly interface so that its integration with the whole application
is easy.
5. Finally, the framework is designed so that it can be easily adapted to any WSAN operating
system.
The rest of the paper is structured as follows. Section 2 summarizes related work. Section 3
describes the proposed architecture in creating and integrating light databases within the nodes that
compose WSANs. Section 4 describes a case study where a smart sensor application is designed by
using our approach. In Section 5, the environment set-up used to test the framework is described,
and a performance evaluation is presented. Finally, Section 6 concludes the paper.
2. RELATED WORK
Both researchers and companies are realizing that, with the passing of time, the industry and private
clients are increasingly depending on wireless sensor networks (WSN) to solve many problems that
would be really difficult to tackle with other kinds of technologies. For this and other reasons, an
important research issue is the development of middlewares and frameworks to be able to deal with
the challenges of WSANs [5, 6]. Most solutions fit into one of the following categories: tuple spaces
and channel approaches, agent-based approaches, macroprogramming approaches, service-oriented
Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

A WIRELESS SENSOR NETWORK FRAMEWORK

503

approaches, and database-inspired approaches. As the last category is the closest approach to our
proposal, the related work is divided into two different sections: the first includes all approaches that
are not based on databases, and the second includes those that are based on databases.

2.1. Approaches not based on databases


The coordination needed in WSNs and WSANs has attracted the attention of the coordination
paradigm community. More specifically, different coordination models and middleware based on
the Linda abstract model [7] have appeared in the area of sensor networks. Linda can be considered the most representative coordination language. It is based on a shared memory model
where data is represented by elementary data structures called tuples, and the memory is a multiset of tuples called a tuple space. Examples of this type of middleware are TinyLime [8] and
TeenyLime [9].
An alternative to tuple spaces is the proposal, based on the use of tuple channels, to carry out communication and synchronization between the nodes involved. Several advantages can be obtained
from the use of channels with respect to shared memory models (architectural expressiveness, data
streams in a natural and suitable way, definition of complex and dynamic interaction protocols, etc.).
A example of this category is tuple channel (TC)-WSANs [10]. An agent-based model makes migration decisions autonomously. The key to this approach is to make the application as modular as
possible to facilitate its injection and distribution throughout the network. One of the most important publications that follows this approach is Agilla [11]. The idea behind Agilla is to initially
deploy a network without the need for a previously installed application. Agents that implement the
application behavior can later be injected, effectively reprogramming the network. Because each
agent is executed autonomously and multiple agents can simultaneously run on a node, multiple
applications can coexist. Agilla presents a compromise between flexibility and power consumption
because of the transmission of agents by the network.
Traditional applications are composed of different programs, each of which is located in a node of
the network. Applications are therefore programmed by specifying the local behavior of all nodes in
our network. Proposals such as those by Kairos [12] and Regiment [13] have a different approach.
Applications can be created by specifying the global behavior of the network. This behavior will be
then be translated into different pieces of code which will be used in the nodes. The programming
tasks are therefore at a higher level of abstraction.
In the service-oriented paradigm category, functionality in the network is accessible as a service,
and it is in this way that communication is achieved between nodes. The programmer can specify the
execution flow by compacting these services together. The use of services provides a high level of
abstraction because programmers specify behavior by creating a program that makes use of different services, but the programmers do not have to worry about the communication or protocols tasks
used for this goal. These approaches can be classified in two big groups. There is a group where the
services act like real web services; one of the current approaches we can find is Tiny web services
[14] and TinyWS [15]. However, the rest of the service approaches deal with the service concept in
a different way. Some approaches are Oasis [16], TinySOA [17], Open Sensor-Rich Environments
[18], and USEME [4]

2.2. Approaches based on databases


To the best of our knowledge, there only exists one group of approaches that make use of database
concepts in the area of WSANs, but in a way different than our proposal. In such approaches
(TinyDB [19], SINA [20], COUGAR [21], MaD-WiSe [22], etc.), a WSAN is abstracted as a whole
database, which can be queried by the users to extract information.
TinyDB is a query-processing system that extracts information from the data collected by the
WSAN by using the underlying operating system, TinyOS, and a controlled flooding approach to
disseminate the queries throughout the network. SINA is a more complex database approach than
Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

504

E. CAETE, M. DAZ AND B. RUBIO

TinyDB, as it not only permits SQL-like language for expressing queries but also provides other
functions that are beyond the scope of traditional database systems. SINA incorporates two robust
mechanisms: hierarchical clustering, allowing scalability, and an attribute-based naming scheme
based on an associative broadcast to manage the spreadsheets. The COUGAR system is a platform
for testing query-processing techniques over ad hoc sensor networks. COUGAR has a three-tier
architecture: the QueryProxy, a small database component that runs on sensor nodes to interpret and
execute queries, a Frontend component, which is a more powerful QueryProxy that permits connections to the world outside of the sensor network, and a graphical user interface through which
users can pose ad hoc and long-running queries on the sensor network. In MaD-WiSe [22], authors
propose a query language based on SQL to extract data from the sensor network. Unlike traditional
databases, MaD-Wise is not designed to process a query as fast as possible but to maximize the
lifetime of the WSN, which implies minimization of the energy consumption of the queries. In
[23], a model in executing optimized and efficient queries is presented. In other words, the authors
have developed an optimized spanning tree able to transport a robust estimated value reported by
each sensor node, depending on the accuracy and confidence parameters provided by the user.
The main idea behind this approach is the combination of two models: an efficient Gaussianbased compression scheme that is geared towards minimizing erroneous reporting of value, and
a model used to know and select which are the most appropriate data on the basis of two parameters provided by the user to execute a concrete query. In [24], authors combine the concept of data
moving average with the increase of the data sampling rate when a possible alarm is detected.
Only in the case where the averaged value (after increasing the sampling rate) is still over the
alarm threshold, actions are carried out. It helps avoid taking unnecessary actions, which could
result in a huge waste of money. In [25], authors propose a model to mitigate the negative effect
of the enrichment process needed to express and execute complex queries on a sensor network
in terms of energy and response time. This is achieved by using a transformation from the standard XML extension, used to express queries on sensor data, to lower level primitives that execute
on raw sensor streams. This way, the interoperability between the system program and the sensor
network is maintained, and on the other hand, the packet size used to transport the query across
the sensor network is reduced. Finally, in [26], authors see the sensor network as a database. In
order to avoid that, all sensor data are directly sent to the sink; authors propose a model to optimize the transport of these stream data (database queries). To achieve this, they have developed
an efficient distributed implementation to join the multiple data stream generated by the sensor
nodes by using a perpendicular approach (PA) which is communication-efficient and load-balanced
and, in addition, incurs near-optimal communication for binary joins. According to the authors, this
is the first work to address distributed implementation of multitable join in sensor networks with
memory constraints.
The approaches mentioned are thought to help programmers in the development of WSAN applications in different ways, but as a trade-off, they can only interact with the deployed sensor networks
as the design of the approach used dictates. On the one hand, these kinds of approaches save the
developers time, but on the other hand, they have to adapt to the restrictions imposed. In contrast,
our approach does not abstract the sensor networks as a database, but it allows a programmer to
use light databases within the nodes that form the whole sensor network. So, developers are able
to structure the information efficiently, and in addition, they have total control over the application
they are developing.
3. WSAN-DATABASE FRAMEWORK ARCHITECTURE
Figure 1 depicts the proposed architecture for the WSAN-database framework. It is formed by four
main components:
1.
2.
3.
4.

WSAN application types


WSAN-ERM
primitive selector
code generator

Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

A WIRELESS SENSOR NETWORK FRAMEWORK

505

Figure 1. Wireless sensor and actor networks-database framework architecture.

Throughout the following subsections, each one of the four components will be explained in more
detail, together with a practical example based on the Contiki operating system [27].

3.1. WSAN application types


Because the goal of the framework will be to facilitate the management of data structures within a
WSAN application, it is essential that the framework knows all predefined types. Obviously, these
types will be different depending on the chosen operating system (Contiki, TinyOS, Squawk Java
Virtual Machine, etc.) to develop the WSAN application. To deal with this issue, the different types
are organized in XML files called Contiki-Types.xml, TinyOS-Types.xml, Squawk-Types.xml, and so
on. It helps us to achieve a platform-independent framework. Within an XML file, each type is
represented with the following structure:

The name field stores the name of the type to be modeled. The size field stores the number of
bytes needed to store the information assigned to a variable, declared with the type indicated in the
name field. Finally, the format field will be used to distinguish between two kinds of types: single
and structured types. This distinction is necessary as the code used to represent each type is different, depending on its format. In the following, it is shown how two different and predefined Contiki
types are represented:

Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

506

E. CAETE, M. DAZ AND B. RUBIO

The mentioned piece of XML code represents an integer type without a sign, whose size is 2 bytes.

On the other hand, this piece of code represents a data structure of 4 bytes which are used in Contiky
to store the addresses of the nodes.
Users can also define their own types by using the predefined types and/or the other user types
previously defined. These types will be stored in a file called OperatingSystem-UserTypes.xml, for
example, Contiki-UserTypes.xml.
3.2. The WSAN-ERM
This part of the system allows developers to graphically represent the data structures they have in
mind by using a reduced ERM. Basically, the model is represented through three concepts:
1. Entity. It represents a data structure. Developers can define as many entities as they want.
Each entity is composed of a name and a set of tuples which will represent the fields of the
data structure. Each tuple is composed of the following fields:
Type. Within this field, developers can chose one of the types defined in the XML file
commented in the previous section.
Name. In this field, developers write the desired name for the data field.
Pointer. Here, it is indicated if the data field is a pointer or not.
Unique key (UK). It indicates that there will not be two or more tuples with the same
value in the data field marked as unique key. It admits null values.
Primary key (PK). It is a special case of unique keys. The data fields (one or several)
marked as primary key will uniquely identify a tuple. It does not admit null values.
2. Mote. It represents the node in charge of managing the defined data structures. This concept
can only be defined once.
3. Relations. Through them, developers can specify what entities interact with other entities and
what entities interact with the mote. Thus, the kinds of relations are
Mote-entity. It represents data structures that directly depend on the nodes. For example, if
we want to model that a node manages the information of five neighbors as MAXIMUM,
we have to create the entity neighbor and create a relationship between the mote and this
entity with a cardinality of one to five.
Entityentity. This kind of relationship is useful when an entity depends on other entities
(nested structures).
In order to better understand the concepts explained previously, let us suppose that a WSAN
application based on groups/clusters has to be developed. So, all nodes are going to be organized in
groups where there will be nodes in charge of managing these groups. These nodes will be known
as leader nodes. Normally, these kinds of nodes are more powerful, and apart from managing the
groups, they are also in charge of receiving the data sensed by the sensor nodes that form part of
their groups. Therefore, this kind of application has two kinds of nodes: leader and sensor nodes.
Let us focus on the data structures the leader nodes would need in this application and how they are
modeled by using a WSAN-ERM. On the one hand, a leader node needs to store the information
of the groups where it leads. Concretely, it needs a data structure to store the ID of the group, the ID
of the place where the group is located, and information about the list of the member nodes. On the
other hand, it also needs to save and manage the information sent by the sensor nodes (members).
Let us suppose sensor nodes send temperature, humidity, and light data periodically at a set time
interval. This information has to be saved in another data structure which will facilitate its analysis
(data aggregation, higher values, lower values, etc.).
Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

A WIRELESS SENSOR NETWORK FRAMEWORK

507

Figure 2. The wireless sensor and actor networks (WSAN)-entity-relationship model (ERM).

Figure 2 shows how the data structures mentioned previously are modeled by using the WSANERM in the developed framework. From the application requirements, we can identify three different entities: groups, members, and sensed data. Once these entities have been added to the model, the
following step is to identify the data fields associated with each one of the entities. In our example,
for each entity, its data fields are
1. Group entity.
groupId. ID of the group where the node is the leader. Furthermore, this field will be the
primary key used to uniquely identify a group entity tuple because a node can not be the
leader of two or more equal groups.
locationId. ID of the physical place where the node is located.
2. Member entity.
memberId. It is a single value used as the primary key. The following data field (memberAddress) could be used as the primary key instead of this field, but it is not advisable because
the size of the memberAddress data field is bigger than the size of the memberId. In
addition, it is a data structure instead of a single value. Therefore, whenever possible, we
will use single values as the primary key because they might be used in auxiliary structures
to establish relationships between different entities. Furthermore, primary keys are mainly
used to find information within many tuples; so, the simpler they are, the less complex the
algorithms used to find information are.
memberAddress. Data field used to save the address of the member node.
batteryLevel. It stores the current battery level of the member node.
registerTime. Data field used to know how recent the data of a member entity tuple is.
3. Sensor data entity.
sourceNodeId. The address of the node that the information of a sensor data entity tuple
belongs to.
registerTime. The data field used to know how recent the data of the sensor data entity tuple
are. In this entity, the primary key is a combination between the above field and this field.
The sourceNodeId cannot bet used as a primary because there could be several tuples with
the same sourceNodeId but with different registerTime.
Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

508

E. CAETE, M. DAZ AND B. RUBIO

Temperature. The field used to store the temperature value sent by the node whose address
is the sourceNodeId.
Humidity. It stores the humidity value.
Light. It stores the light value.
4. Relationships between entities.
Relationship mote-group. It indicates that each leader mote will be able to manage 10
different groups.
Relationship group-member. It indicates that each group will have information on 20
different members, and each will be able to belong to the 10 different groups.
Relationship Mote-sensordata. Finally, this relation is used to indicate that a leader mote will
be able to store information (humidity, temperature, etc.) of 20 different nodes.
3.3. Primitives selector
Once developers have designed the desired data model to satisfy the application requirements, the
following step is to create the algorithms necessary to interact with the generated data structures.
Basically, the information stored in the data structures need to be created, updated or modified,
and consulted or deleted. In order to facilitate the generation of these algorithms, a visual system
is proposed. It takes developers through a simple and guided process with the purpose of helping
them design the API that will be used to interact with the designed data structures. Figure 3 shows
which steps are necessary to create the API primitives. In the following, each one of these steps is
explained in detail:
1. First, the developer has to indicate what kind of primitive he or she wants to create. There are
four kinds of primitives:
Primitives to store new data in the data structures.
Primitives to modify data already stored in the data structures.
Primitives to consult the data already stored.
Primitives to remove data.

Figure 3. Primitive-generating flow diagram.


Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

A WIRELESS SENSOR NETWORK FRAMEWORK

509

2. Second, a name must be assigned to the new primitive. It will be used to identify the primitive
within the API.
3. In the third step, developers have to select those entities related with the kind of primitive they
want to create. If two or more entities are selected, they have to be related to each other as it
does not make sense to create a primitive from two independent entities.
4. Once the previous step has been carried out, all data fields that belong to the selected entities
are revealed to the developer in order for them to select only those that are necessary to create
the primitive.
5. In the fifth step, developers can either ignore it and proceed onto the next step or can carry
out two different actions: either to define the grouping fields or to define the filtering fields.
This step can be repeated as many times as the user desires, thereby allowing developers to
define data filtering on data already grouped or vice versa. Let us describe what the goal of
each action is
Data grouping It is useful when developers need to group data registers that have common
values within the same data field. For example, let us imagine we have the following tuples
(1,33), (1,31), (1,29), (2,28), and (2,30), where the first value is the ID of a sensor node, and
the second one is the temperature registered by this node. A developer may wish to know
what the maximum temperature sensed by each node is ((1,31), (2,30)). To achieve this, he
or she has to indicate that the first field will be the grouping field and the second one must
group the data by choosing the highest value. Therefore, one of the data fields has to be
marked as the grouping field, and the rest of the fields have to be marked with one of the
following labels: MAX, MIN, SUM, . . . depending on the desired primitive.
Data filtering In this case, the developer has to select a set of constraints on the data fields
selected in the previous step. Through these constraints, the criteria in selecting the desired
data registers are established. They are modeled by associating one of the followings rules
with each one of the selected data fields:










Lower than (dat a < X ).


Greater than (dat a > X ).
Equal to (dat a D X ).
Lower than or equal to (dat a <D X ).
Greater than or equal to (dat a >D X ).
Greater and lower than (X < dat a < Y ).
Greater than and lower or equal than (X < dat a <D Y ).
Greater or equal than and lower than (X <D dat a < Y ).
Greater or equal than and lower or equal than (X <D dat a <D Y ).

6. Finally, the developers have to select the action data fields. Namely, they must indicate the
data fields they want to consult, remove, update, or add as the kind of primitive selected in the
first step. Because the generated primitive can only return a data structure, all selected data
fields must belong to the same entity. In the case when the chosen primitive is a consult, users
will have two options: the previously given option where the action data fields are indicated
or a new option to achieve data aggregation. To achieve this, users must indicate in the fields
selected the kind of aggregation (minimum, maximum, mode, sum, etc.) they desire. In the
following, these two possible options are explained.
Following our example (Figure 2), let us suppose we want to create the following four
primitives:
1. A primitive to consult those member nodes whose groupId is X and their battery level is
greater than or equal to Y .
2. A primitive to update the registerTime of the member node whose ID is X .
3. A primitive to remove member nodes whose battery level is lower than X .
4. A primitive to insert a new register with the data received from the node X .
Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

510

E. CAETE, M. DAZ AND B. RUBIO

Figure 4 shows the steps followed in creating the first primitive in a graphical way (Figure 5 also
shows how some of these steps are carried out using the application). As memberId was the action
data field selected, the primitive will return the number of members that satisfy the selection criterion defined in Step 4. In addition, in an external array called DATA_RESULT, a list of pointers
with the memory references to the corresponding member_t data structures (for member entities)
will be stored. We consider it is much more efficient to return a pointer list than to return a list with
the ID of the members because, through a pointer, the developer can consult any of its data fields
(not only the data stores in the memberId data field). In addition, independent of the number of
different consult primitives created and the kind of data they return, the system will only need to
allocate memory in managing a pointer list. Listing 1 shows the code generated by the framework
in creating the primitive defined in Figure 4 (data structures used are described in Section 3.4).
The signature of the primitives 2, 3, and 4 would be
 int UpdateRegisterTimeMembers(long newRegisterTime, uint16_t batteryLevel)
 int RemoveMember(uint16_t batteryLevel)

Figure 4. Steps followed to create a consult primitive.

(a)

Step 3

(b)

Step 4

(c)

Step 5

Figure 5. Consult primitive.


Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

A WIRELESS SENSOR NETWORK FRAMEWORK

511

 int InsertSensedData(rimeaddr_t sourceNodeId, long registerTime, uint16_t temperature,

uint16_t humidity, uint16_t light)


As mentioned before, in the case of the consult primitive, developers also have the possibility
of specifying aggregation data such as the maximum, minimum, average, sum, or mode value. Let
us imagine a developer needs to know the temperature average value from the data values sent by a
particular node. He or she would have to follow these steps:
1.
2.
3.
4.
5.
6.

Create a consult primitive.


Introduce the name of the primitive.
Select the sensor data entity.
Select the data fields: sourceNodeId and temperature.
Add to the sourceNodeId data field the value equal to.
Associate the aggregation value AVERAGE with the temperature data field.

These steps generate a primitive that return a single value (temperature average value) instead of
a set of registers. This value is not returned through the primitive but is stored in an auxiliary data
structure called DATA_RESULT, which has to be consulted by the user as long as the primitive is
executed successfully. It is indicated through an integer returned by the primitive (see Table IV).
Another option could be to obtain the node that sent the higher temperature value. To obtain a
primitive able to obtain this information, the developer would have to follow the same steps mentioned previously. But in this case, the sourceNodeId data field must be selected as the action data
field, and the aggregation value must be the maximum.
The update, remove, insert, and consult primitives will return an integer that will give developers
information about the execution of the primitive. Tables IIV show the meaning of the code returned
by the update, remove, and insert primitives, respectively.
Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

512

E. CAETE, M. DAZ AND B. RUBIO

Table I. Information code returned by an update primitive.


Update Primitive
Code
-1
0

Information
There was an error during the execution of
the primitive
Number of registers that have been updated
successfully

3.4. Code generator


Once it has been shown how to define the WSAN-ERM model and how to select the API primitives,
let us see how the model is translated in the source code so that it can be understood by a concrete
WSAN operating system. Listing 2 shows the code generated from the model defined in Figure 2.
Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

A WIRELESS SENSOR NETWORK FRAMEWORK

513

Table II. Information code returned by a remove primitive.


Remove Primitive
Code
-1
0

Information
There was an error during the execution of
the primitive
Number of registers that have been removed
successfully

Table III. Information code returned by an insert primitive.


Insert Primitive
Code
0
-1
-2
-3

Information
The data has been inserted successfully
It indicates that a data tuple already exists
with the same primary key
Unique key error
There is insufficient memory

Table IV. Information code returned by a consult primitive.


Consult primitive
Code
0
-1

Information
The data has been selected successfully
There was an error during the execution of
the primitive

On one hand, a code, where three data structures similar to the entities defined in the WSANERM has been generated, but an auxiliary data structure called group_members_t has also been
generated. These structures are needed when a WSAN-ERM contains many-to-many relations, and
thanks to them, not only the data redundancy is reduced but they also make the algorithms more
efficient. On the other hand, array structures have been also created. Through these, the cardinalities
specified in the relations established between the entities of the WSAN-ERM are represented.
In the generated code, we can appreciate that the size of the group_members_t data structure is
2 bytes; thus, the array structure called groupMembers will need to allocate 2  200 bytes. Let
us suppose that, in the member entity, we had selected the memberAddress data field as the primary key instead of the memberId data field. In this case, the size of the group_members_t data
structure would be 5 bytes, and the array structure would need to allocate 5  200 bytes, which is
2.5 times more memory. Thus, developers or designers need to pay close attention when they are
creating the WSAN-ERM of their application because a bad design can have a negative impact in
terms of memory.
As shown in Figure 2, the framework is able to indicate in real time the memory space needed
by the leader node to store the data structures generated from the WSAN-ERM. In our particular
example, the memory needed is calculated in the following way:









The size of group_t data structure is 2 bytes.


The size of member_t data structure is 13 bytes.
The size of group_members_t data structure is 2 bytes.
The size of sensorData_t data structure is 16 bytes.
groups array needs 10  2 bytes (20 bytes).
members array needs 20  10 bytes (200 bytes).
groupMembers array needs 200  2 bytes (400 bytes).
sensorData array needs 20  12 bytes (240 bytes).

Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

514

E. CAETE, M. DAZ AND B. RUBIO

 As four arrays have been generated, four variables are needed to control the last position where

the data was stored. These variables need 8 bytes because the size of each one of them is
2 bytes.
 From the mentioned information, we can conclude that 20 C 200 C 400 C 240 C 8 bytes
(868 bytes) need to be allocated.
4. CASE STUDY
In order to show how this approach is able to save time for the developers, a smart sensor network
application that detects mildew in a vineyard is going to be modeled. Mildew is one of the most
serious and costly diseases grape growers face, and the cost-per-day of protection is a significant
measure of fungicide performance and overall value. Mildew destroys large areas of crops in many
growing seasons, and poor control of this disease can result in the rejection of entire grape crops by
wineries. Furthermore, mildew also increases the susceptibility bunches of grapes to Botrytis and
other rots. During spring, the risk increases considerably when the temperature fall within the range
of 20 to 25 C, and the relative humidity is higher than 80%. The detection of these parameters can
be used to send an alarm to the vineyard owner in order for them to take the necessary measures.
Both parameters, temperature and humidity, will be controlled through a set of sensor nodes
which will send the sensed values to the sink node located in the farmhouse. The sink is the node
in charge of analyzing all the data sent by the sensor nodes. Its mission is to generate the necessary
alarms which are sent to the owner of the farmland via GPRS or e-mail. As the deployment will have
two different nodes (sensor and sink node), two different designs will be necessary. On one hand,
Figure 6(a) shows the database design of the sensor nodes. This design is thought to facilitate the
development of the routing protocol. Through the entity NEIGHBOR NODES, each sensor will
store information from the neighbor nodes in order to know which are located in the upper, same,
and lower level (number of hops need to reach the sink). This information allows us to send the
packets from the sink to the sensor nodes and vice versa through the shortest paths. Together with
this information, parameters such as Received Signal Strength Indication (RSSI), battery level, and
at what time a node registered their neighbors information will also be stored. The RSSI and battery
level are used in order to have two different routing protocols: (i) routing sensitive to the RSSI and
(ii) routing sensitive to the battery level. The goal of the former is to achieve a more reliable routing, and the goal of the latter is to achieve a uniform distribution of the energy consumption. The
entity CONTROL INFORMATION will store the kind of routing that it is going to be executed
and the level (distance to the sink) where the node is located. On the other hand, Figure 6(b) shows
the database design used for the sink node. Through this design, the sink will be able to store and
control the information of 20 sensor nodes. The sink will know the level (distance) where each node
is located, its address, and the timestamp when the information of the sensor node was updated for
the last time. The relation SENSOR NODES, SENSED DATA, allows the sink node to store up to
15 data tuples for each one of the 20 sensor nodes.

(a)

Software design of the sensor nodes

(b)

Software design of the sink node

Figure 6. Software design as a kind of node.


Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

A WIRELESS SENSOR NETWORK FRAMEWORK

515

These graphical designs not only allow us to understand what information is going to be managed
by the nodes at first sight, but also all the necessary codes to manage the information represented by
them will be automatically generated.
In the following, the code generated by the framework from the data structures previously commented on is shown in Listings 3 and 4. From another point of view, this is the code developers do
not have to worry about, as it will be automatically generated by the framework.
Let us see what the difference would be in terms of code if developers had to write the code for
the sink (see the code shown in Listing 5).
In this code, it can be clearly seen that in contrast to the code generated by the framework, the data
fields sensorNodeId and sensedDataId have not been used because both entities (data structures)
are related using a nested structure. Although it is possibly the most intuitive way to represent these
data structures, it is also the most inefficient way because the memory allocation for the data tuple
of a sensor node evolves into the memory allocation to manage 15 data tuples of the sensed data by
the node.
The code mentioned is not only clearer, but also the memory allocation problem is avoided. It
is achieved by relating the data structures through the primary keys. As we can see in the code,
the primary key of the sensorNode_t data structure has been migrated to the sensedData_t data
structure.
Of course, developers will also have to write the necessary algorithms to obtain, store, update,
or remove information from the data structures. Let us suppose that developers need the following
algorithms:
1. An algorithm for the sensor nodes to register a new neighbor node located in the upper level.
2. An algorithm for the sensor nodes to update the information of the neighbor nodes located in
an upper level.
3. An algorithm for the sensor nodes to know where the neighbor node with the higher battery
level located in the upper levels of a particular node is. This operation will be used by the
routing protocol.
Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

516

E. CAETE, M. DAZ AND B. RUBIO

Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

A WIRELESS SENSOR NETWORK FRAMEWORK

517

4. An algorithm for the sensor nodes to delete a specific neighbor node located in the upper level.
5. An algorithm for the sink node to register the sensor nodes of the wireless sensor network.
6. An algorithm for the sink node to register the sensed data received from a particular
sensor node.
7. An algorithm for the sink node to obtain the average temperature from all sensed data.
8. An algorithm for the sink node to obtain the average temperature from all sensed data by a
particular sensor node.
9. An algorithm for the sink node to know the average temperature sensed by the sensor nodes by
using the most up to date values. It will help the developers know if the average temperature
falls within the range of 2025C.
10. An algorithm for the sink node to obtain those network nodes with a battery level higher than
a given threshold.
Table V shows the signature of the primitive previously described.
In the following, the process to generate some of the primitives previously mentioned is described
step by step:
 For primitive 3,

1. Create a consult primitive;


2. Primitive name, upperLevelNodeWithHigherBattery;
3. Select NEIGHBOR NODES. As there are three different relationships between the mote
and the entity, it is necessary to select the correct one. In this case, the relation called
upperLevelNodes will be selected;
4. Select batteryLevel data field;
5. Do not select any selection criteria;
6. Select nodeAddress as the action data field;
7. Associate with the batteryLevel data field the aggregation value MAXIMUM.
8. Generated primitive: int GetUpperLevelNodeWithHigherBattery().
 For primitive 9,
1. Create a consult primitive;
2. Primitive name: AverageTemperatureAsTime;
3. Select SENSOR NODES and SENSED DATA entities;
4. Select sensorNodeId, temperature, and measureTime data fields;
5. Select as grouping data, the sensorNodeId data field, and to obtain the most up to date
value, the measureTime data field must be marked with the label MAX;
6. Associate with the temperture data field the aggregation value AVERAGE;
7. Generated primitive: int GetAverageTemperatureAsTime().
 And so on.
Listings 6 and 7 show the code generated by the framework used to add to the API the two
primitives mentioned previously.

Table V. Signature of the generated primitives.


ID

Primitive

1
2
3
4
5
6
7
8
9
10

int insertNodeUpperLevel(const rimeaddr_t *node, uint16_t rssi, uint16_t batteryLevel)


int updateNodeUpperLevel(const rimeaddr_t *node, uint16_t rssi, uint16_t batteryLevel)
int GetUpperLevelNodeWithHigherBattery()
int deleteNodeUpperLevel(const rimeaddr_t *node)
int insertNetworkNode(const rimeaddr_t *node, int dist, long lastUpdate, uint16_t batLevel)
int insertDataSensedByNetworkNode(const rimeaddr_t *n, uint16_t t, uint16_t h, long mTime)
int GetAverageTemperature()
int GetAverageTemperatureAsNode(const rimeaddr_t *node)
int GetAverageTemperatureAsTime()
int GetNetworkNodesWithBatteryLevelHigherThan(uint16_t batteryLevel)

Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

518

E. CAETE, M. DAZ AND B. RUBIO

Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

519

A WIRELESS SENSOR NETWORK FRAMEWORK

5. EVALUATION
In order to analyze and study the performance of the framework presented in this article, both data
structures obtained from the database model represented in Figure 6 and their respective primitives
generated in an automatic way (see Table V) are evaluated in terms of memory occupation, compiled
code footprint, energy consumption, and CPU activity time.
5.1. Environment set-up
The COOJA sensor network simulator [28] has been used to carry out all the experiments. COOJA
is a power profiling tool that enables accurate network-scale energy measurements in a simulated
environment. The COOJA simulator offers the possibility of carrying out the simulation in different
platforms. We selected the TelosB motes because they are one of the most used by the sensor net
community. In order to carry out the simulations, we used Contiki [27] which is an open source,
highly portable, multitasking operating system for memory-efficient networked embedded systems
and wireless sensor networks. In the following sections, each one of the experiments carried out are
explained in more detail.
We would like to lay stress on COOJA which allows us to carry out very realistic simulations
because of the fact that through COOJA, the sensor node software can be run in a sensor node
emulator that emulates an actual sensor node at the hardware level.
5.2. Evaluation of the generated data structures
Table VI shows the memory occupation and the compiled code footprint of the data structures used
as examples throughout of the paper. One of the advantages of this framework is that the users see
in real time the memory occupation of the generated data structures. If the data structures are analyzed, we observe that both memory occupation and compiled code footprint values are normal. In
other words, in spite of the fact that the code is automatically generated, the table shows the framework only generates the code when strictly necessary. This is well reflected in the last two rows of
the table where the penultimate and ultimate rows show the memory occupation and compiled code
footprint of the same data structure (see Figure 6(b)) generated in an automatic and customized way,
respectively. These data show three positive things:
1. The memory occupation of the data structure generated by the user in a customized way is
36 bytes higher than the structure generated by the framework. This shows that this value
depends on the cardinality defined between the entities specified in the data structure, so that
the bigger the cardinalities are, the bigger the difference between the memory occupation
needed by the data structure generated in a customized and automatic way.
2. The compiled code footprint is practically the same, and unlike the memory occupation, it is
independent of the cardinalities defined between the entities specified in the data structure.
3. The compiled code footprint of both structures also show that the framework does not generate
unnecessary code.
5.3. Primitives compiled code footprint
Figure 7 shows the compiled code footprint used by each one of the primitives described in Table V.
All footprints are within normal limits. In the case of primitives 4, 5, and 6, we think the code
Table VI. Data structure evaluation.

Data structure (Figure 2)


Data structure (Figure 6(a))
Data structure (Figure 6(b))
Data structure (Figure 6(b)) (custom)
Copyright 2012 John Wiley & Sons, Ltd.

Memory occupation
(bytes)

Compile code footprint


(bytes)

868
608
3890
3926

712
528
424
408
Softw. Pract. Exper. 2013; 43:501523
DOI: 10.1002/spe

520

E. CAETE, M. DAZ AND B. RUBIO

generated uses an instruction that depends on a Contiki external library, so that the final footprint is
the sum of the external library and the primitive footprint. In the case when creating these primitives
in a customized way, the instructions dependent on external libraries would also be necessary.
5.4. CPU activity time and energy consumption
Figures 8 and 9 show the CPU activity time and the energy consumption of the primitives shown in
Table V when they are executed. Obviously, the energy consumption is directly related to the time a

Figure 7. Compiled code footprint.

Figure 8. CPU activity time.

Figure 9. Energy consumption.


Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

A WIRELESS SENSOR NETWORK FRAMEWORK

521

primitive needs to be executed. Both figures present the evaluation of the primitives in the best and
worst case. In terms of code, best and worst case means the execution of a primitive where an array
of size N has to process one or N elements, respectively. Several conclusions can be drawn from
Figure 8:

Primitives generate for the sensor nodes


 For primitives 1 and 2 (insert and update), it is logical that they take the same time to be

executed because in both cases, they process the array in the same way. The only difference
between primitive 1 and 2 is that one inserts an element and the other updates it.
 In spite of the fact that primitive 3 has to process the same array as primitives 1 and 2, it needs
a little less time because it only has to find an element and return it instead of updating or
inserting all their attributes (RSSI, batteryLevel, lastUpdate, . . . ).
 For the worst case, primitive 4 takes more time than primitives 1, 2, and 3 because when an
element is removed, all the elements stored in the next positions of the array have to be moved
one position to the left.

Primitives generated for the sink


 Primitive 6 inserts a data tuple in the sensed data entity, which is related to the sensor nodes

entity. Thus, before inserting this tuple, the foreign key that relates the data tuple with the sensor that generated them must be found within the sensor nodes entity. In contrast, primitive
5 directly inserts the data tuples in the sensor nodes entity. For this reason, primitive 6 takes
more time than primitive 5 in both the best and worst cases.
 Primitives 7, 8, and 9 obtain the average temperature in three different ways. Primitive 7 calculates it by analyzing all the sensed data tuples generated by all the sensors nodes. This
calculation is quick as it is not necessary to apply any data filter. For this reason, the best
and worst cases of this primitive are better than the times of primitives 8 and 9. In the case
of primitive 8, the difference of these times is because the average temperature is calculated
depending on a particular node. It means that the system has to look for the primary key of the
desired node within the sensor nodes entity and then filter the data tuples of the sensed data
entity, depending on this primary key. Primitive 9 is quite special in terms of execution. In spite
of the fact that it only needs to look for information within a data structure, it takes more time
than the other primitives. This is because to obtain the average temperature from the most up
to date data, all data tuples have to be compared with each other.
 Although the primitives 10 and 3 are executed over different data structures, their executions
are similar. For this reason, their CPU activity times are equal.

6. CONCLUSIONS
In this article, we have proposed an architecture that allows developers to create and integrate light
databases within the nodes that form part of a WSAN. A framework based on this architecture can
help developers of WSAN applications in many ways. It will require less development time, applications will be more energy-efficient, and developers will be able to easily adapt to any requirement
changes of the data model. Furthermore, the architecture permits the creation of a framework independent of the platform; thus, a design could generate code for nodes based in different operating
systems. Also, a smart application that detects mildew disease in vineyards has been designed by
using this framework approach. It highlights the benefits of using this framework approach to design
smart sensor network applications. Finally, the performance evaluation of the framework shows that
the generated code in terms of memory occupation, compiled code footprint, CPU activity time, and
energy consumption is efficient.
Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

522

E. CAETE, M. DAZ AND B. RUBIO

7. ACKNOWLEDGEMENTS
This work was partially supported by European Project SEEDS FP7-285250 and Spanish Projects
P07-TIC-03184, TIN2008-03107, TIN2011-23795 and TIC-03085.

REFERENCES
1. Akyildiz IF, Kasimoglu IH. Wireless sensor and actor networks: research challenges. Ad Hoc Networks 2004;
2(4):351367.
2. Gehrke J, Liu L. Sensor-network applications. IEEE Internet Computing 2006; 10(2):1617.
3. Wenning BL, Pesch D, Timm-Giel A, Grg C. Environmental monitoring aware routing: making environmental
sensor networks more robust. Telecommunication Systems 2010; 43(1):311.
4. Caete E, Chen J, Daz M, Llopis L, Rubio B. A service-oriented approach to facilitate WSAN application
development. Ad Hoc Networks 2011; 9(3):430452.
5. Wang M, Cao J, Li J, Das SK. Middleware for wireless sensor networks: a survey. Journal of Computer Science and
Technology 2008; 23(3):305326.
6. Rubio B, Diaz M, Troya JM. Programming approaches and challenges for wireless sensor networks. In ICSNC 07:
Proceedings of the Second International Conference on Systems and Networks Communications. IEEE Computer
Society: Washington, DC, USA, 2007; 3643. DOI: 10.1109/ICSNC.2007.63.
7. Gelernter D. Generative communication in linda. ACM Transactions on Programming Languages and Systems 1985;
7(1):80112.
8. Curino C, Giani M, Giorgetta M, Giusti A, Murphy AL, Picco GP. TinyLime: bridging mobile and sensor networks through middleware. In Proceedings of the 3rd IEEE International Conference on Pervasive Computing and
Communications (PerCom 2005). IEEE Computer Society Press: Kauai Island (Hawaii, USA), 2005; 6172.
9. Costa P, Mottola L, Murphy AL, Picco GP. TeenyLIME: transiently shared tuple space middleware for wireless sensor networks. In Proceedings of the 1st International Workshop on Middleware for Wireless Sensor Networks (MidSens 2006), co-located with the 7th International Middleware Conference (Middleware06). ACM Press: Melbourne,
Australia, 2006; 4348.
10. Barbarn J, Daz M, Iaki E, Garrido D, Llopis L, Rubio B, Troya JM. Programming wireless sensor and actor
networks with TC-WSANS. In IEEE International Conference on Pervasive Services, ICPS07. IEEE Computer
Society: Istanbul, Turkey, 2007; 196203.
11. Herbert J, Ling G, Fei K. Mobile agent architecture integration for a wireless sensor medical application, 2006.
12. Gummadi R, Gnawali O, Govindan R. Macro-programming wireless sensor networks using kairos, 2005.
13. Newton R, Morrisett G, Welsh M. The regiment macroprogramming system. In IPSN 07: Proceedings of the
6th International Conference on Information Processing in Sensor Networks. ACM: New York, NY, USA, 2007;
489498. DOI: 10.1145/1236360.1236422.
14. Priyantha NB, Kansal A, Goraczko M, Zhao F. Tiny web services: design and implementation of interoperable and
evolvable sensor networks. In SenSys 08: Proceedings of the 6th ACM Conference on Embedded Network Sensor
Systems. ACM: New York, NY, USA, 2008; 253266. DOI: 10.1145/1460412.1460438.
15. Othman NY, Glitho RH, Khendek F. The design and implementation of a web service framework for individual
nodes in sinkless wireless sensor networks. In Proceedings of the IEEE International Conference on Computers and
Communications (ISCC07). IEEE Computer Society Press: Aveiro, Portugal, 2007; 941947.
16. Kushwaha M, Amundson I, Koutsoukos X, Neema E, Sztipanovits J. Oasis: A programming framework for serviceoriented sensor networks. In Proceedings of the 2nd International Conference on Communication Systems Software
and Middleware: Bangalore, India, 2007; 941947.
17. Rezgui A, Eltoweissy M. Service-oriented sensor-actuator networks: promises, challenges, and the road ahead.
Computer Communications 2007; 30:26272648.
18. Liu J, Zhao F. Composing semantic services in open sensor-rich environments. IEEE Network 2008; 22(4):4449.
19. Madden SR, Franklin MJ, Hellerstein JM, Hong W. Tinydb: an acquisitional query processing system for sensor
networks. ACM Transactions on Database Systems 2005; 30:122173. DOI: 10.1145/1061318.1061322.
20. Shen C-C, Srisathapornphat C, Jaikaeo C. Sensor information networking architecture and applications. IEEE
Personal Communications 2001; 8(4):5259. DOI: 10.1109/98.944004.
21. Yao Y, Gehrke J. The cougar approach to in-network query processing in sensor networks. SIGMOD Record 2002;
31:918. DOI: 10.1145/601858.601861.
22. Amato G, Chessa S, Vairo C. Mad-wise: a distributed stream management system for wireless sensor networks.
Software: Practice and Experience 2010; 40:431451.
23. Meliou A, Guestrin C, Hellerstein JM. Approximating sensor network queries with in-network summaries. Technical
Report UCB/EECS-2008-137, EECS Department, University of California, Berkeley, 2008.
24. Liu K, Chen L, Liu Y, Li M. Robust and efficient aggregate query processing in wireless sensor networks. Mobile
Networks and Applications 2008; 13:212227.
25. McCann D, Roantree M. A query service for raw sensor data. In Proceedings of the 4th European Conference on Smart Sensing and Context (EuroSSC09). Springer-Verlag: Berlin, Heidelberg, 2009; 3850. DOI:
1813042.1813048.
Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

A WIRELESS SENSOR NETWORK FRAMEWORK

523

26. Zhu X, Gupta H, Tang B. Join of multiple data streams in sensor networks. IEEE Transactions on Knowledge and
Data Engineering 2009; 21(12):17221736.
27. Dunkels A, Gronvall B, Voigt T. Contikia lightweight and flexible operating system for tiny networked sensors.
In Proceedings of the 29th Annual IEEE International Conference on Local Computer Networks (LCN 04). IEEE
Computer Society: Washington, DC, USA, 2004; 455462.
28. Eriksson J, sterlind F, Finne N, Dunkels A, Tsiftes N, Voigt T. Accurate network-scale power profiling for sensor
network simulators. In Wireless Sensor Networks, Vol. 5432, Roedig U, Sreenan C (eds), Lecture Notes in Computer
Science. Springer: Berlin / Heidelberg, 2009; 312326.

Copyright 2012 John Wiley & Sons, Ltd.

Softw. Pract. Exper. 2013; 43:501523


DOI: 10.1002/spe

You might also like