Final document - Grupo ARCO - Universidad de Castilla

Anuncio
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
I NFRAESTRUCTURA PARA LA I NTEGRACIÓN
DE R EDES DE S ENSORES Y ACTUADORES
EN E NTORNOS I NTELIGENTES
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
D EPARTAMENTO DE T ECNOLOGÍAS Y S ISTEMAS DE I NFORMACIÓN
E SCUELA S UPERIOR DE I NFORMÁTICA
U NIVERSIDAD DE C ASTILLA -L A M ANCHA
TESIS DOCTORAL
I NFRAESTRUCTURA PARA LA I NTEGRACIÓN
DE R EDES DE S ENSORES Y ACTUADORES
EN E NTORNOS I NTELIGENTES
Autor:
David Villa Alises
Ingeniero Informático
Universidad de Castilla-La Mancha
Directores:
Francisco Moya Fernández
Dr. Ingeniero de Telecomunicación
Universidad de Castilla-La Mancha
Juan Carlos López López
Dr. Ingeniero de Telecomunicación
Catedrático de Universidad
Universidad de Castilla-La Mancha
Ciudad Real, 2009
i
i
i
i
i
i
i
i
David Villa Alises
Ciudad Real
Spain
E-mail:
Telefono:
Web site:
c 2009
[email protected]
(+34) 926 295300 (ext: 3707)
http://arco.esi.uclm.es/~david.villa/
David Villa Alises
Permission is granted to copy, distribute and/or modify this document under the terms
of the GNU Free Documentation License, Version 1.3 or any later version published by
the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and
no Back-Cover Texts. A copy of the license is included in the section entitled "GNU
Free Documentation License".
Se permite la copia, distribución y/o modificación de este documento bajo los términos
de la Licencia de Documentación Libre GNU, versión 1.3 o cualquier versión posterior
publicada por la Free Software Foundation; sin secciones invariantes. Una copia de esta
licencia esta incluida en el apéndice titulado «GNU Free Documentation License».
Muchos de los nombres usados por las compañías para diferenciar sus productos y
servicios son reclamados como marcas registradas. Allí donde estos nombres aparezcan
en este documento, y cuando el autor haya sido informado de esas marcas registradas,
los nombres estarán escritos en mayúsculas o como nombres propios.
i
i
i
i
i
i
i
i
Resumen
L
AS redes de sensores —especialmente las inalámbricas— son desde hace unos
años un importante tema de investigación para muchas disciplinas debido quizá
al impresionante potencial que se prevé en su aplicación a campos tan dispares como
la medicina o la defensa. Y todo ello a pesar de los graves problemas que suponen sus
peculiares características: energía limitada, reducido tamaño, movilidad, comunicaciones
intermitentes y un largo etcétera.
Uno de los aspectos más importantes para una utilización provechosa de las redes de
sensores es la creación de servicios de valor sobre ellas. Para lograrlo hay que resolver
primero un problema clave: se deben establecer los medios para comunicar los sistemas
de información tradicionales con los nodos sensores, pero también éstos entre sí, aun
perteneciendo a redes con distinta tecnología.
Tradicionalmente la solución a estos problemas es un middleware de comunicaciones,
y aunque existe gran cantidad de propuestas para diseño de middlewares para redes de
sensores, en nuestra opinión, se ocupan solo de los problemas específicos y olvidan la
importancia de una solución global aplicable a todo el sistema.
Esta tesis propone una infraestructura que permite adaptar middlewares de comunicaciones orientados a objetos de propósito general para uso dentro y fuera de la red de
sensores. Esta infraestructura proporciona un entorno homogéneo y eficaz para la creación de servicios de alto nivel, evitando la necesidad de contemplar casos especiales
cuando tratamos con redes de sensores o actuadores.
Las contribuciones más importantes son: un método para crear objetos distribuidos
empotrados, un modelo de información adaptado a la naturaleza de las redes de sensores,
un protocolo de descubrimiento de servicios y un mecanismo para la interconexión de
redes heterogéneas por medio de encaminamiento de mensajes sobre el middleware. A
diferencia de muchos trabajos previos, éstas no son soluciones particulares; todas ellas
pueden ser aplicadas al sistema completo —incluya o no redes de sensores— sin un
sacrificio significativo de eficiencia o prestaciones.
Palabras clave – red de sensores, middleware de comunicaciones, computación
distribuida orientada a objetos.
VII
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
Abstract
S
ENSOR networks —specially wireless sensor networks— have been the focus of
very active research in many fields, probably due to their impressive potential in
broadly different fields such as medicine or defense. This is happening in spite of their
severe problems regarding their distinctive characteristics: limited energy, reduced size,
mobility, intermittent communication, and so on.
One of the main aspects that may lead to a fruitful exploitation of sensor networks
is the development of valuable services on top of them. To achieve this goal another
key problem must be solved first: there must be well defined means to communicate
traditional information systems with sensor nodes, and also among themselves, even
when they use different underlying technologies.
The traditional solution to this kind of problems is a communication middleware and
there is a large offering of proposals of middlewares for sensor networks. Unfortunately we
believe that they are all limited to some specific problems, forgetting about the importance
of a global solution which may be applied to the whole system.
This thesis proposes an infrastructure to enable the adaptation of any general purpose
object oriented communication middleware to be used inside and outside of the sensor
network. This infrastructure provides an homogeneous and effective environment to
develop high level services and avoids the need to consider special cases when dealing
with sensor and actuator networks.
The main contributions are: a method to define highly efficient embedded distributed
objects, an information model specially suited to the needs of sensor networks, a service
discovery protocol, and a mechanism for heterogeneous network interconnection by
means of message routing on top of the underlying middleware. By contrast to many
former works these are not isolated solutions; they may all be applied to the whole
system whether it includes sensor networks or not without any noticeable overhead
regarding efficiency or performance.
Keywords – sensor network, communication middleware, object oriented distributed
computing.
IX
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
Índice general
Índice general
XI
Índice de cuadros
XXI
Índice de figuras
XXIII
Índice de listados
XXVII
Listado de acrónimos
XXXI
1. Introducción
1
1.1.
Redes de sensores . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
1.2.
Objetivos de la investigación . . . . . . . . . . . . . . . . . . . . . . . .
5
1.3.
Estructura del documento . . . . . . . . . . . . . . . . . . . . . . . . .
7
1.4.
Middleware de referencia . . . . . . . . . . . . . . . . . . . . . . . . .
9
1.5.
Convenciones tipográficas . . . . . . . . . . . . . . . . . . . . . . . . .
9
2. Antecedentes
11
2.1.
Entornos inteligentes . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
2.2.
Aplicaciones distribuidas . . . . . . . . . . . . . . . . . . . . . . . . .
13
2.3.
2.2.1.
Primeras aproximaciones . . . . . . . . . . . . . . . . . . . . . .
13
2.2.2.
Llamada a procedimiento remoto . . . . . . . . . . . . . . . . . .
14
2.2.3.
Invocación a método remoto . . . . . . . . . . . . . . . . . . . . .
17
Sistemas Distribuidos Heterogéneos . . . . . . . . . . . . . . . . . . . .
17
2.3.1.
Nomenclatura . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
2.3.2.
Servicios comunes . . . . . . . . . . . . . . . . . . . . . . . . . .
19
2.3.3.
CORBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
XI
i
i
i
i
i
i
i
i
ÍNDICE GENERAL
XII
2.3.4.
2.4.
2.5.
2.6.
ZeroC Ice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
Miniaturización de middlewares generalistas . . . . . . . . . . . . . . .
37
2.4.1.
Minimum CORBA . . . . . . . . . . . . . . . . . . . . . . . . . .
38
2.4.2.
e*ORB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
42
2.4.3.
Gibraltar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
42
2.4.4.
nORB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
42
2.4.5.
dynamicTAO . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43
2.4.6.
UIC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
44
2.4.7.
LegORB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
45
2.4.8.
MicroQoSCORBA . . . . . . . . . . . . . . . . . . . . . . . . . .
46
2.4.9.
Smart Transducer Interface . . . . . . . . . . . . . . . . . . . . .
47
2.4.10. UORB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
49
2.4.11. I CE -E . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
50
Middlewares para redes de sensores . . . . . . . . . . . . . . . . . . . .
50
2.5.1.
SINA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
51
2.5.2.
DSWare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
52
2.5.3.
TinyDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54
2.5.4.
Cougar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54
2.5.5.
Maté . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54
2.5.6.
Magnet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
2.5.7.
SensorWare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
57
2.5.8.
MiLAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
58
2.5.9.
TinyCubus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
59
2.5.10. Impala . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
2.5.11. TinyLime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
63
2.5.12. EnviroTrack . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
64
2.5.13. Kairos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
65
2.5.14. WSP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
66
2.5.15. C OPRA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
68
Encaminamiento en redes heterogéneas . . . . . . . . . . . . . . . . . .
69
2.6.1.
Protocolo de red universal . . . . . . . . . . . . . . . . . . . . . .
69
2.6.2.
Pasarelas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
73
i
i
i
i
i
i
i
i
ÍNDICE GENERAL
2.7.
XIII
2.6.3.
Protocolos híbridos . . . . . . . . . . . . . . . . . . . . . . . . . .
76
2.6.4.
Redes «inmersivas» . . . . . . . . . . . . . . . . . . . . . . . . .
78
Descubrimiento de servicios y recursos . . . . . . . . . . . . . . . . . .
78
2.7.1.
Terminología . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79
2.7.2.
Prestaciones habituales . . . . . . . . . . . . . . . . . . . . . . . .
79
2.7.3.
Descubrimiento de Servicios en redes ad hoc y SAN . . . . . . . .
81
3. Objetos Distribuidos Universales
83
3.1.
Nomenclatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
84
3.2.
Interfaces escalares . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
84
3.2.1.
Actuación relativa . . . . . . . . . . . . . . . . . . . . . . . . . .
87
3.3.
Contenedores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
88
3.4.
Actores activos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
89
3.4.1.
Reactivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
91
3.4.2.
Proactivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
92
3.4.3.
Activación condicional . . . . . . . . . . . . . . . . . . . . . . . .
92
3.5.
Componentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
3.6.
Actores compuestos . . . . . . . . . . . . . . . . . . . . . . . . . . . .
94
3.7.
3.6.1.
Actor compuesto activo . . . . . . . . . . . . . . . . . . . . . . .
96
3.6.2.
Distribución . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
96
Composición básica de servicios . . . . . . . . . . . . . . . . . . . . .
97
3.7.1.
Cableado virtual . . . . . . . . . . . . . . . . . . . . . . . . . . .
97
3.7.2.
Servicios reactivos . . . . . . . . . . . . . . . . . . . . . . . . . .
98
3.7.3.
Relaciones n-arias . . . . . . . . . . . . . . . . . . . . . . . . . .
98
3.8.
Consulta múltiple . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
99
3.9.
Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
4. picoObjetos
103
4.1.
Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
4.2.
Una estrategia diferente . . . . . . . . . . . . . . . . . . . . . . . . . . 107
4.2.1.
4.3.
El objeto mínimo . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Interoperabilidad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
4.3.1.
picoCORBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
i
i
i
i
i
i
i
i
ÍNDICE GENERAL
XIV
4.3.2.
4.4.
Funcionamiento del picoObjeto . . . . . . . . . . . . . . . . . . . . . . 115
4.4.1.
4.5.
4.6.
4.7.
picoIce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Máquina de estados . . . . . . . . . . . . . . . . . . . . . . . . . 115
Especificación de picoObjetos . . . . . . . . . . . . . . . . . . . . . . . 116
4.5.1.
Gestión de los datos . . . . . . . . . . . . . . . . . . . . . . . . . 117
4.5.2.
Utilidades auxiliares . . . . . . . . . . . . . . . . . . . . . . . . . 120
4.5.3.
Repertorio de instrucciones FSM . . . . . . . . . . . . . . . . . . 120
4.5.4.
Bloques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
4.5.5.
Subrutinas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
4.5.6.
Eventos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
4.5.7.
Sirvientes, código de usuario . . . . . . . . . . . . . . . . . . . . 124
4.5.8.
Bytecode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
4.5.9.
Limitaciones y saltos . . . . . . . . . . . . . . . . . . . . . . . . . 126
Transformación de FSM a bytecode . . . . . . . . . . . . . . . . . . . . 127
4.6.1.
Optimizaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
4.6.2.
Generación del bytecode . . . . . . . . . . . . . . . . . . . . . . . 129
Máquina virtual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
4.7.1.
Comunicación con el sirviente . . . . . . . . . . . . . . . . . . . . 130
4.8.
Generación de código nativo . . . . . . . . . . . . . . . . . . . . . . . . 130
4.9.
Despliegue de aplicaciones en la SAN . . . . . . . . . . . . . . . . . . . 130
4.10. Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
5. Descubrimiento del entorno
133
5.1.
Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
5.2.
Elementos básicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
5.2.1.
Canales de eventos . . . . . . . . . . . . . . . . . . . . . . . . . . 135
5.2.2.
Propiedades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
5.2.3.
Taxonomía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
5.3.
Prestaciones de ASDF . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
5.4.
Anunciamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
5.5.
Descripción de servicios . . . . . . . . . . . . . . . . . . . . . . . . . . 140
5.5.1.
Servicios proporcionados . . . . . . . . . . . . . . . . . . . . . . 141
5.5.2.
Persistencia de las propiedades . . . . . . . . . . . . . . . . . . . 142
i
i
i
i
i
i
i
i
ÍNDICE GENERAL
5.5.3.
5.6.
XV
Servidor de propiedades . . . . . . . . . . . . . . . . . . . . . . . 143
Búsqueda de servicios . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
5.6.1.
Directorio distribuido puro . . . . . . . . . . . . . . . . . . . . . . 144
5.6.2.
Directorio híbrido . . . . . . . . . . . . . . . . . . . . . . . . . . 144
5.6.3.
Directorio centralizado . . . . . . . . . . . . . . . . . . . . . . . . 145
5.6.4.
Directorio jerárquico . . . . . . . . . . . . . . . . . . . . . . . . . 146
5.6.5.
Anunciamiento reactivo . . . . . . . . . . . . . . . . . . . . . . . 147
5.7.
Servicio de metamodelo . . . . . . . . . . . . . . . . . . . . . . . . . . 148
5.8.
Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
6. Flujo de diseño
6.1.
6.2.
6.3.
151
Lenguaje IcePick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
6.1.1.
Especificación de interfaces . . . . . . . . . . . . . . . . . . . . . 153
6.1.2.
Objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
6.1.3.
Adaptadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
6.1.4.
Eventos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
6.1.5.
Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
6.1.6.
Atributos por defecto en objetos . . . . . . . . . . . . . . . . . . . 157
6.1.7.
Métodos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Lenguaje SIS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
6.2.1.
Métodos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
6.2.2.
Eventos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
El compilador ipkc . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
6.3.1.
Estructura general . . . . . . . . . . . . . . . . . . . . . . . . . . 161
6.3.2.
Frontal para IcePick . . . . . . . . . . . . . . . . . . . . . . . . . 162
6.3.3.
Frontal para SIS . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
6.3.4.
Frontal para S LICE . . . . . . . . . . . . . . . . . . . . . . . . . . 162
6.3.5.
Compilador extensible . . . . . . . . . . . . . . . . . . . . . . . . 166
6.3.6.
Soporte para macro-programación . . . . . . . . . . . . . . . . . . 166
6.3.7.
Generación de FSM . . . . . . . . . . . . . . . . . . . . . . . . . 168
6.4.
Drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
6.5.
Plataforma para desarrollo de picoObjetos . . . . . . . . . . . . . . . . 171
i
i
i
i
i
i
i
i
ÍNDICE GENERAL
XVI
7. Integración de redes heterogéneas
7.1.
175
Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
7.1.1.
Inter-redes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
7.1.2.
Encaminamiento homogéneo . . . . . . . . . . . . . . . . . . . . 178
7.1.3.
Acerca de los prototipos . . . . . . . . . . . . . . . . . . . . . . . 179
7.2.
Direccionamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
7.2.1.
Identidad del objeto . . . . . . . . . . . . . . . . . . . . . . . . . 180
7.2.2.
Un posible esquema de direccionamiento . . . . . . . . . . . . . . 180
7.3.
Endpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
7.4.
Gestión de calidad de servicio . . . . . . . . . . . . . . . . . . . . . . . 184
7.5.
Entrega de mensajes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
7.5.1.
Entrega directa . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
7.5.2.
Entrega indirecta . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
7.6.
Encaminamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
7.6.1.
Encaminamiento dinámico . . . . . . . . . . . . . . . . . . . . . . 189
7.6.2.
Gestión de la red . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
7.7.
Integración con el middleware . . . . . . . . . . . . . . . . . . . . . . . 190
7.7.1.
7.8.
Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
8. Prototipos
8.1.
API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
197
Dispositivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
8.1.1.
Motas Crossbow . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
8.1.2.
TINI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
8.1.3.
NXT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
8.1.4.
XPort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
8.1.5.
WIZnet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
8.1.6.
Cámaras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
8.2.
Máquina virtual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
8.3.
TwinPanel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
8.4.
Servicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
8.4.1.
PropertyServer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
8.4.2.
ContextServer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
i
i
i
i
i
i
i
i
ÍNDICE GENERAL
8.5.
XVII
8.4.3.
CacheService . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
8.4.4.
CameraServer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
8.4.5.
ChannelMonitor . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
Activos experimentales . . . . . . . . . . . . . . . . . . . . . . . . . . 209
8.5.1.
Actor mínimo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
8.5.2.
Otros actores sencillos . . . . . . . . . . . . . . . . . . . . . . . . 210
8.5.3.
Cerradura inteligente . . . . . . . . . . . . . . . . . . . . . . . . . 211
8.5.4.
Control de consumo . . . . . . . . . . . . . . . . . . . . . . . . . 212
8.5.5.
Placas de prototipado . . . . . . . . . . . . . . . . . . . . . . . . 213
8.5.6.
Cableado virtual . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
8.5.7.
Termostato . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
8.5.8.
Sensor día/noche . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
8.5.9.
Detección de presencia polivalente . . . . . . . . . . . . . . . . . 216
8.5.10. Requisitos de memoria . . . . . . . . . . . . . . . . . . . . . . . . 218
8.6.
8.7.
8.8.
Análisis de protocolos . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
8.6.1.
DUO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
8.6.2.
ASDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
Prototipos IDM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
8.7.1.
Latencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
8.7.2.
Rendimiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
9. Conclusiones y trabajo futuro
9.1.
225
Infraestructura de integración . . . . . . . . . . . . . . . . . . . . . . . 225
9.1.1.
Middleware orientado a objetos . . . . . . . . . . . . . . . . . . . 226
9.1.2.
picoObjetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
9.1.3.
Modelo de información . . . . . . . . . . . . . . . . . . . . . . . 228
9.1.4.
Descubrimiento de servicios . . . . . . . . . . . . . . . . . . . . . 229
9.1.5.
Redes heterogéneas . . . . . . . . . . . . . . . . . . . . . . . . . 229
9.2.
Un middleware para WSN . . . . . . . . . . . . . . . . . . . . . . . . . 230
9.3.
Resumen de contribuciones . . . . . . . . . . . . . . . . . . . . . . . . 232
9.4.
Publicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
9.5.
Nuevas líneas de trabajo . . . . . . . . . . . . . . . . . . . . . . . . . . 233
i
i
i
i
i
i
i
i
ÍNDICE GENERAL
XVIII
9.5.1.
Encaminamiento ad hoc con IDM . . . . . . . . . . . . . . . . . . 234
9.5.2.
Plataforma de gestión para redes heterogéneas . . . . . . . . . . . 234
9.5.3.
Plataforma de despliegue heterogéneo . . . . . . . . . . . . . . . . 235
9.5.4.
Modelado semántico de servicios . . . . . . . . . . . . . . . . . . 235
A. Repertorio de instrucciones FSM
239
B. Servicios Web empotrados
245
B.1.
Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
B.2.
Servicios Web en la SAN . . . . . . . . . . . . . . . . . . . . . . . . . 246
B.3.
Un enfoque ascendente . . . . . . . . . . . . . . . . . . . . . . . . . . 247
B.3.1. Compilación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
B.4.
Arquitectura de red . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
B.5.
Prototipos EWS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
B.6.
Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
C. El protocolo Ice
C.1.
257
Codificación de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
C.1.1. Tamaños . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
C.1.2. Encapsulaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
C.1.3. Slices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
C.1.4. Tipos básicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
C.1.5. Cadenas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
C.1.6. Tipos agregados . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
C.1.7. Identidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
C.2.
Proxies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
C.2.1. Endpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
C.3.
Mensajes del protocolo . . . . . . . . . . . . . . . . . . . . . . . . . . 262
C.3.1. Cabecera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
C.3.2. Cuerpo del mensaje de petición . . . . . . . . . . . . . . . . . . . 263
C.3.3. Cuerpo del mensaje de petición por lotes . . . . . . . . . . . . . . 264
C.3.4. Cuerpo del mensaje de respuesta . . . . . . . . . . . . . . . . . . 265
C.3.5. Mensaje de validación de conexión . . . . . . . . . . . . . . . . . 265
i
i
i
i
i
i
i
i
ÍNDICE GENERAL
XIX
C.3.6. Mensaje de cierre de conexión . . . . . . . . . . . . . . . . . . . . 265
D. General Inter-ORB Protocol
267
D.1. Visión general de GIOP . . . . . . . . . . . . . . . . . . . . . . . . . . 267
D.1.1. Representación común de datos (CDR) . . . . . . . . . . . . . . . 269
D.1.2. Mensajes GIOP . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
D.1.3. Transferencia de mensajes GIOP
. . . . . . . . . . . . . . . . . . 270
D.2. Sintaxis de transferencia de CDR . . . . . . . . . . . . . . . . . . . . . 270
D.2.1. Tipos primitivos . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
D.2.2. Tipos compuestos . . . . . . . . . . . . . . . . . . . . . . . . . . 274
D.2.3. Encapsulación . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
D.3. Formato de los mensajes GIOP . . . . . . . . . . . . . . . . . . . . . . 276
D.3.1. Cabecera GIOP . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
D.3.2. Mensaje de petición (Request) . . . . . . . . . . . . . . . . . . . . 278
D.3.3. Mensaje de respuesta (Reply) . . . . . . . . . . . . . . . . . . . . 279
D.3.4. Mensaje de cancelación de petición (CancelRequest) . . . . . . . . 281
D.3.5. Mensaje de petición de localización (LocateRequest) . . . . . . . . 282
D.3.6. Mensaje de respuesta de localización (LocateReply) . . . . . . . . 282
D.3.7. Mensaje de finalización de conexión (CloseConnection) . . . . . . 283
D.3.8. Mensaje de error (MessageError) . . . . . . . . . . . . . . . . . . 283
D.4. Transporte de mensajes GIOP . . . . . . . . . . . . . . . . . . . . . . . 284
E. Interfaces Slice
285
E.1.
DUO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
E.2.
ASDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
E.3.
Property Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
F. GNU Free Documentation License
291
F.0.
PREAMBLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
F.1.
APPLICABILITY AND DEFINITIONS . . . . . . . . . . . . . . . . . 291
F.2.
VERBATIM COPYING . . . . . . . . . . . . . . . . . . . . . . . . . . 292
F.3.
COPYING IN QUANTITY . . . . . . . . . . . . . . . . . . . . . . . . 292
F.4.
MODIFICATIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
i
i
i
i
i
i
i
i
ÍNDICE GENERAL
XX
F.5.
COLLECTIONS OF DOCUMENTS . . . . . . . . . . . . . . . . . . . 294
F.6.
AGGREGATION WITH INDEPENDENT WORKS . . . . . . . . . . . 294
F.7.
TRANSLATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
F.8.
TERMINATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
F.9.
FUTURE REVISIONS OF THIS LICENSE . . . . . . . . . . . . . . . 294
F.10. RELICENSING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
Glosario
297
Bibliografía
299
Índice alfabético
311
i
i
i
i
i
i
i
i
Índice de cuadros
2.1. Semánticas de RPC en presencia de distintos fallos . . . . . . . . . . . .
16
2.2. nORB: Tamaños de programa para una aplicación de referencia . . . . . .
43
2.3. Memoria necesaria para algunas configuraciones de UIC . . . . . . . . .
45
2.4. MQC: Comparativa de memoria necesaria . . . . . . . . . . . . . . . . .
47
2.5. Maté: Requerimientos de memoria . . . . . . . . . . . . . . . . . . . . .
56
2.6. SensorWare: Requerimientos de memoria . . . . . . . . . . . . . . . . .
57
2.7. Impala: Requerimientos de memoria . . . . . . . . . . . . . . . . . . . .
63
2.8. WSP: Requerimientos de memoria . . . . . . . . . . . . . . . . . . . . .
68
5.1. ASDF: Resumen de las prestaciones del protocolo . . . . . . . . . . . . . 149
6.1. Tokens del lenguaje IcePick . . . . . . . . . . . . . . . . . . . . . . . . 163
6.2. Tokens del lenguaje SIS . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
8.1. Memoria requerida por la máquina virtual de picoObjetos . . . . . . . . . 204
8.2. Memoria requerida para varios prototipos . . . . . . . . . . . . . . . . . 220
8.3. I CE y DUO: Tamaño de los mensajes . . . . . . . . . . . . . . . . . . . . 221
8.4. ASDF: Tamaño de los mensajes . . . . . . . . . . . . . . . . . . . . . . 222
8.5. IDM: Pruebas de latencia . . . . . . . . . . . . . . . . . . . . . . . . . . 224
8.6. IDM: Pruebas de rendimiento . . . . . . . . . . . . . . . . . . . . . . . . 224
A.1. FSM: Resumen del juego de instrucciones . . . . . . . . . . . . . . . . . 244
B.1. Comparativa de tamaños de un WS para un servicio get/set básico . . . . 254
C.1. Tamaño de los tipos básicos de Slice . . . . . . . . . . . . . . . . . . . . 259
XXI
i
i
i
i
i
i
i
i
XXII
ÍNDICE DE CUADROS
D.1. Alineación requerida para los tipos primitivos de IDL . . . . . . . . . . . 271
D.2. Tamaño y ordenamiento de los tipos IDL enteros . . . . . . . . . . . . . 272
D.3. Tamaño y ordenamiento de los tipos IDL de punto flotante . . . . . . . . 273
D.4. GIOP: Tipos de mensajes . . . . . . . . . . . . . . . . . . . . . . . . . . 276
i
i
i
i
i
i
i
i
Índice de figuras
2.1. Arquitectura CORBA . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
2.2. Métodos de entrega de eventos en un modelo híbrido . . . . . . . . . . .
29
2.3. Representación de las características omitidas en Minimum CORBA
respecto a CORBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
39
2.4. Representación de un sistema STI . . . . . . . . . . . . . . . . . . . . .
48
2.5. Relación de MiLAN con las capas de red inferiores . . . . . . . . . . . .
59
2.6. Arquitectura de capas de Impala . . . . . . . . . . . . . . . . . . . . . .
62
2.7. Nodo ZebraNet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
63
2.8. Combinación de Stargate y mota MICA2 usada en un prototipo de Kairos
66
2.9. Estructura de un nodo WSP . . . . . . . . . . . . . . . . . . . . . . . . .
67
2.10. Encaminamiento de mensajes CORBA . . . . . . . . . . . . . . . . . . .
71
2.11. Red SAN con una pasarela explícita . . . . . . . . . . . . . . . . . . . .
74
3.1. Diagramas de secuencia del actor reactivo y el proactivo . . . . . . . . .
91
3.2. Actor DUO::IByte::R compuesto según patrón de diseño . . . . . . . . .
95
3.3. Actor DUO::IByte::R compuesto con interfaces DUO . . . . . . . . . . .
96
3.4. Ejemplo de cableado virtual . . . . . . . . . . . . . . . . . . . . . . . . 100
3.5. Diagrama de secuencia de una consulta múltiple . . . . . . . . . . . . . . 101
4.1. Comparación de una invocación convencional con una a picoObjeto . . . 105
4.2. Representación gráfica de CORBA, Minimum CORBA y picoCORBA . . . 108
4.3. Ejemplo de una máquina de estados para dos objetos I CE sencillos . . . . 117
5.1. Clases de servicios definidos en la taxonomía . . . . . . . . . . . . . . . 137
5.2. Diagrama de secuencia de un anunciamiento . . . . . . . . . . . . . . . . 139
5.3. Ejemplo de herencia múltiple de interfaces para servicios . . . . . . . . . 142
XXIII
i
i
i
i
i
i
i
i
XXIV
ÍNDICE DE FIGURAS
5.4. Búsqueda de servicios con directorio distribuido puro . . . . . . . . . . . 145
5.5. Delegación de la búsqueda de servicios al dominio superior . . . . . . . . 147
6.1. Diagrama simplificado del proceso de compilación . . . . . . . . . . . . 152
6.2. Diagrama de bloques del compilador ipkc . . . . . . . . . . . . . . . . . 161
6.3. Ejemplo de macro-programación . . . . . . . . . . . . . . . . . . . . . . 168
6.4. Plataforma completa para desarrollo y prueba de picoObjetos . . . . . . . 172
6.5. Distintos roles en la creación del entorno inteligente . . . . . . . . . . . . 173
7.1. IDM: Ejemplo de encaminamiento funcional . . . . . . . . . . . . . . . . 181
7.2. Un posible esquema de direccionamiento para IDM . . . . . . . . . . . . 181
7.3. Relación de IDM con el modelo de capas de red tradicional . . . . . . . . 182
7.4. Una inter-red IDM formada por 4 redes IDM . . . . . . . . . . . . . . . . 186
7.5. Diagrama de bloques de IDM . . . . . . . . . . . . . . . . . . . . . . . . 188
7.6. Comparación entre un encaminador IP y uno IDM . . . . . . . . . . . . . 189
7.7. IDM: Invocación de un objeto IDM remoto . . . . . . . . . . . . . . . . 191
8.1. Motas Crossbow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
8.2. Módulo DSTINI1 en el socket E10 . . . . . . . . . . . . . . . . . . . . . 199
8.3. Aspecto del NXT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
8.4. XPort y WIZnet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
8.5. Cámaras de vídeo utilizadas en los prototipos . . . . . . . . . . . . . . . 201
8.6. TwinPanel, aspecto general . . . . . . . . . . . . . . . . . . . . . . . . . 205
8.7. TwinPanel inspeccionando un contexto alojado en un ContextServer . . . 207
8.8. TwinPanel inspeccionando el CacheService . . . . . . . . . . . . . . . . 207
8.9. TwinPanel inspeccionando una cámara servida por CameraServer . . . . 209
8.10. Cerradura electrónica controlada por un picoObjeto . . . . . . . . . . . . 212
8.11. Prototipo para control de consumo eléctrico . . . . . . . . . . . . . . . . 212
8.12. Placa de prototipado para picoObjetos (ALSO1) . . . . . . . . . . . . . . 213
8.13. Interruptor inalámbrico para cableado virtual . . . . . . . . . . . . . . . 214
8.14. Topología de red utilizada para las pruebas de rendimiento . . . . . . . . 223
9.1. Esquema general de la infraestructura de integración de redes SAN . . . . 226
i
i
i
i
i
i
i
i
ÍNDICE DE FIGURAS
XXV
B.1. Máquina de estados simplificada para los mensajes SOAP get y set . . . 250
B.2. Topología de red para la gestión de luces de emergencia . . . . . . . . . . 252
B.3. Proceso de encapsulación de la pasarela . . . . . . . . . . . . . . . . . . 253
D.1. Diagrama de capas de CORBA . . . . . . . . . . . . . . . . . . . . . . . 268
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
Índice de listados
2.1. Interfaz CORBA::Object . . . . . . . . . . . . . . . . . . . . . . . . . .
28
2.2. Proxies directos e indirectos en I CE . . . . . . . . . . . . . . . . . . . . .
33
2.3. Interfaz Ice::Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35
2.4. Programa de ejemplo de Maté . . . . . . . . . . . . . . . . . . . . . . .
55
3.1. Interfaces DUO escalares . . . . . . . . . . . . . . . . . . . . . . . . . .
86
3.2. Creación de una interfaz para composición de interfaces básicas . . . . .
87
3.3. Interfaz DUO::Func::Relative . . . . . . . . . . . . . . . . . . . . . . .
87
3.4. Módulo DUO::Container para colecciones de objetos . . . . . . . . . . .
88
3.5. Módulo DUO::Active en lenguaje Slice . . . . . . . . . . . . . . . . . .
90
3.6. Interfaz DUO::Component . . . . . . . . . . . . . . . . . . . . . . . . .
93
3.7. Módulo para construcción de actores DUO compuestos . . . . . . . . . .
95
3.8. Actor DUO::IByte::R compuesto . . . . . . . . . . . . . . . . . . . . . .
95
4.1. Ejemplo de uso de las funciones del banco de registros . . . . . . . . . . 119
4.2. Ejemplos de variables FSM . . . . . . . . . . . . . . . . . . . . . . . . . 119
4.3. Ejemplos de constantes FSM (zona DATA) . . . . . . . . . . . . . . . . . 119
4.4. Algunos bloques de ejemplo de un programa FSM . . . . . . . . . . . . . 121
4.5. Parte del bytecode resultante de la compilación de un programa FSM . . . 126
5.1. ASD::Listener: Interfaz para recepción de anunciamientos . . . . . . . . 138
5.2. Services.ice: Definición de interfaces para servicios . . . . . . . . . . 140
5.3. Herencia (incorrecta) de múltiples servicios . . . . . . . . . . . . . . . . 141
5.4. ASD::PropHldr: Delegación de propiedades a un objeto externo . . . . . 143
5.5. ASD::Search: Interfaz para búsqueda de servicios . . . . . . . . . . . . . 144
5.6. Interfaz IceGrid::Query . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
5.7. Interfaz Slice de MIS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
6.1. IcePick: Definición de objetos . . . . . . . . . . . . . . . . . . . . . . . 153
XXVII
i
i
i
i
i
i
i
i
XXVIII
ÍNDICE DE LISTADOS
6.2. IcePick: Definición de una faceta . . . . . . . . . . . . . . . . . . . . . . 154
6.3. IcePick: Declaración de adaptadores . . . . . . . . . . . . . . . . . . . . 155
6.4. IcePick: Cláusulas para definición de triggers . . . . . . . . . . . . . . . 156
6.5. IcePick: Instrucciones para gestión de eventos . . . . . . . . . . . . . . . 157
6.6. IcePick: Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
6.7. SIS: Ejemplo de declaración de la interfaz de un sirviente . . . . . . . . . 159
6.8. SIS: Soporte a parámetros de tipos variables . . . . . . . . . . . . . . . . 160
6.9. Gramática del lenguaje IcePick . . . . . . . . . . . . . . . . . . . . . . . 164
6.10. Gramática del lenguaje SIS . . . . . . . . . . . . . . . . . . . . . . . . . 165
6.11. IcePick: Ejemplo de macro-programación . . . . . . . . . . . . . . . . . 167
7.1. Formato de los mensajes IDM . . . . . . . . . . . . . . . . . . . . . . . 183
7.2. Interfaz para administración de perfiles de Q O S en encaminadores IDM . 185
7.3. Interfaz ALP para registro de objetos y localización de adaptadores . . . . 186
7.4. Tabla de rutas IDM simplificada . . . . . . . . . . . . . . . . . . . . . . 188
7.5. Interfaz Slice para el protocolo de encaminamiento RIP . . . . . . . . . . 190
7.6. Implementación de un servidor IDM mínimo . . . . . . . . . . . . . . . 193
7.7. Implementación de un cliente IDM mínimo . . . . . . . . . . . . . . . . 194
8.1. Declaración de un actor que sirve una cámara de vídeo PTZ . . . . . . . . 208
8.2. Objeto mínimo: DUO::Pulse::W con transporte oneway . . . . . . . . . 210
8.3. Un sensor DUO::IBool::R y un actuador DUO::IBool::RW
. . . . . . . 210
8.4. Declaración de una interfaz Slice para un sensor activo . . . . . . . . . . 211
8.5. Definición de un sensor booleano proactivo . . . . . . . . . . . . . . . . 211
8.6. Especificación del nodo de control del termostato con alarma . . . . . . . 215
8.7. Sensor día/noche con activación condicional . . . . . . . . . . . . . . . . 217
8.8. Detección de presencia polivalente (iluminación e intrusión) . . . . . . . 219
8.9. Disección de un mensaje ASD::Listener::adv() . . . . . . . . . . . . 222
B.1. Ejemplo de petición SOAP . . . . . . . . . . . . . . . . . . . . . . . . . 247
B.2. Especificación WSDL para el ejemplo descrito . . . . . . . . . . . . . . . 248
B.3. Respuesta SOAP sintetizada . . . . . . . . . . . . . . . . . . . . . . . . 248
B.4. Ejemplo de IcePick para un WS . . . . . . . . . . . . . . . . . . . . . . 251
B.5. Fragmento WSDL para la localización de un nodo . . . . . . . . . . . . . 253
C.1. Formato de codificación de una encapsulación Slice . . . . . . . . . . . . 258
i
i
i
i
i
i
i
i
ÍNDICE DE LISTADOS
XXIX
C.2. Estructura de una identidad de objeto I CE . . . . . . . . . . . . . . . . . 260
C.3. Estructura común de un proxy I CE . . . . . . . . . . . . . . . . . . . . . 260
C.4. Estructura de un endpoint TCP . . . . . . . . . . . . . . . . . . . . . . . 261
C.5. Estructura de un endpoint UDP . . . . . . . . . . . . . . . . . . . . . . . 262
C.6. Estructura de un endpoint SSL . . . . . . . . . . . . . . . . . . . . . . . 262
C.7. Protocolo I CE: Formato de la cabecera . . . . . . . . . . . . . . . . . . . 263
C.8. Protocolo I CE: Formato del mensaje de petición . . . . . . . . . . . . . . 264
C.9. Protocolo I CE: Formato del mensaje de petición por lotes . . . . . . . . . 264
C.10. Protocolo I CE: Formato del mensaje de respuesta . . . . . . . . . . . . . 265
D.1. Formato de la cabecera GIOP . . . . . . . . . . . . . . . . . . . . . . . . 277
E.1. DUO.ice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
E.2. ASDF.ice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
E.3. PropertyService.ice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
E.4. PropertyType.ice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
Listado de acrónimos
ACE
ADAPTIVE Communication Environment
ACM
Active Connection Management
ALP
Adapter Location Protocol
AmI
Ambient Intelligence
AMI
Asynchronous Method Invocation
AMD
Asynchronous Method Dispatching
ANSI
American National Standards Institute
AODV
Ad hoc On-Demand Distance Vector
API
Application Program Interface
ARCO
Arquitectura y Redes de Computadores
ARPANET
Advanced Research Projects Agency NETwork
ASCII
American Standard Code for Information Interchange
ASDA
ASDF Announce
ASDF
Abstract Service Discovery Framework
ASDS
ASDF Search
ASN
Abstract Syntax Notation
BOA
Basic Object Adapter
BSD
Berkeley Software Distribution
CAN
Control Area Network
CASE
Computer-Aided Software Engineering
CBA
Content-Based Addresses
CCD
Charge Coupled Device
CCITT
Comité Consultatif International Téléphonique et Télégraphique
CCM
CORBA Component Model
CDR
Common Data Representation
CIDL
Component Implementation Definition Language
CIOP
IOP sobre DCE
CMR
CORBA Message Routing
CORBA
Common Object Request Broker Architecture
CPD
Centro de Proceso de Datos
XXXI
i
i
i
i
i
i
i
i
LISTADO DE ACRÓNIMOS
XXXII
CPU
Central Processing Unit
CRC
Cyclic Redundancy Check
DAIS
Declarative Applications in Immersive Sensor networks
DARPA
Defense Advanced Research Projects Agency
DBA
Distributed Breakout Algorithm
DCE
Distributed Computing Environment
DCOM
Distributed Component Object Model
DHCP
Dynamic Host Configuration Protocol
DII
Dynamic Invocation Interface
DNS
Domain Name System
DOBS
Distributed Object Based Services
DPS
Distributed Programming System
DSI
Dynamic Skeleton Interface
DSL
Domain-Specific Language
DSP
Digital Signal Processor
DSWare
Data Service middleWare
DTN
Delay Tolerant Network
DUO
Distributed Universal Objects
EBNF
Extended Backus-Naur Form
EEPROM
Electrically Erasable Programmable Read-Only Memory
EJB
Enterprise JavaBeans
ESIOP
Environment Specific IOP
EWS
Embedded Web Services
FPGA
Field-Programmable Gate Array
FSM
Finite State Machine
FTP
File Transfer Protocol
GCC
GNU Compiler Collection
GIOP
General IOP
GNU
GNU is Not Unix
GPIO
General Purpose Input/Output
GPS
Global Positioning System
GTK
The GIMP Toolkit
GUI
Graphical User Interface
GUID
Globally Unique IDentifiers
HTIOP
IOP sobre HTTP
HTTP
Hypertext Transfer Protocol
HTML
HyperText Markup Language
I2C
Inter-Integrated Circuit
Ice
Internet Communications Engine
i
i
i
i
i
i
i
i
LISTADO DE ACRÓNIMOS
Ice-E
Embedded I CE
IceP
I CE Protocol
IDL
Interface Definition Language
IDM
Inter-Domain Messaging
IEC
International Electrotechnical Commission
IEEE
Institute of Electrical and Electronics Engineers
IETF
Internet Engineering Task Force
IFS
Interface File System
IIOP
Internet IOP
IOP
Inter-ORB Protocol
IOR
Interoperable Object Reference
IP
Internet Protocol
IPC
Inter-Process Communication
IPv6
IP versión 6
IR
Interface Repository
ISA
Instruction Set Architecture
ISO
International Organization for Standardization
ISTAG
Information Society Technologies Advisory Group
JVM
Java Virtual Machine
LAN
Local Area Network
LCD
Liquid Crystal Display
LDR
Light Dependent Resistor
LED
Light Emitting Diode
LIME
Linda in Mobile Environments
M-JPEG
Motion JPEG
MAC
Media Access Control
MANET
Mobile Ad-hoc Network
MDOO
Middleware Distribuido Orientado a Objetos
MiLAN
Middleware Linking Applications and Networks
MIS
Model Information Service
MQC
MicroQoSCORBA
MTU
Maximum Transmission Unit
MVC
Model-View-Controller
NAT
Network Address Translation
NEST
Networked Embedded System Technology
NDR
Network Data Representation
NFS
Network File System
OASIS
Organization for the Advancement of Structured Information Standards
OID
Object Identity
XXXIII
i
i
i
i
i
i
i
i
LISTADO DE ACRÓNIMOS
XXXIV
OMA
Object Management Architecture
OMG
Object Management Group
ONC
Open Network Computing
OO
Orientación a Objetos
ORB
Object Request Broker
OSGi
Open Systems Gateway Initiative
OSI
Open Systems Interconnection
OSF
Open Software Foundation
OWL
Ontology Web Language
P2P
Peer to Peer
PAL
Phase Alternating Line
PARC
Palo Alto Research Center
PC
Personal Computer
PCP
Procedure Call Protocol
PDA
Personal Digital Assistant
PDP
Pervasive Discovery Protocol
PIR
Passive Infra Red
PLC
Power Line Carrier
POA
Portable Object Adapter
POO
Programación Orientada a Objetos
PPE
Protocol Processing Stages
PPS
Protocol Precessing Engines
PTZ
Pan-Tilt-Zoom
QoS
Quality of Service
RAM
Random Access Memory
RFC
Request For Comments
RIP
Routing Information Protocol
RMI
Remote Method Invocation
ROM
Read Only Memory
RPC
Remote Procedure Call
RSI
Rutina de Servicio de Interrupción
RTE
Run-Time Environment
RTSP
Real Time Streaming Protocol
SA
Sistema Autónomo
SAN
Sensor Actuator Network
SAX
Simple API for XML
SDP
Service Discovery Protocol
SENDA
Services and Networks for Domotic Applications
SIMM
Single In-line Memory Module
i
i
i
i
i
i
i
i
LISTADO DE ACRÓNIMOS
SI
Sistema de Información
SINA
Sensor Information Networking Architecture
SIS
Servant Interface Specification
Slice
Specification Language for Ice
SLIP
Serial Line Internet Protocol
SLOC
Source Lines of Code
SLP
Service Location Protocol
SMS
Short Message Service
SO
Sistema Operativo
SOA
Service Oriented Architecture
SOAP
Simple Object Access Protocol
SPI
Serial Peripheral Interface
SQL
Structured Query Language
SQTL
Sensor Query and Tasking Language
SRAM
Static Random Access Memory
SSDP
Simple Service Discovery Protocol
SSL
Secure Socket Layer
SSLIOP
IOP over SSL
ST
Smart Transducer
STI
Smart Transducer Interface
SVG
Scalable Vector Graphics
TAO
The ACE ORB
Tcl
Tool Command Language
TCP
Transmission Control Protocol
TCP/IP
Arquitectura de protocolos de Internet
TDMA
Time Division Multiple Access
TINI
Tiny InterNet Interface
TMN
Telecommunications Management Network
ToS
Type of Service
TTL
Time To Live
UART
Universal Asynchronous Receiver/Transmitter
UIC
Universally Interoperable Core
UDDI
Universal Description Discovery and Integration
UDP
User Datagram Protocol
UPnP
Universal Plug and Play
UORB
Ubiquitous ORB
USART
Universal Synchronous Receiver/Transmitter
USB
Universal Serial Bus
UTF
Unicode Transformation Format
XXXV
i
i
i
i
i
i
i
i
LISTADO DE ACRÓNIMOS
XXXVI
V-ISA
Virtual ISA
VLC
Video LAN Client
VM
Virtual Machine
VPN
Virtual Private Network
WASP
Wirelessly Accessible Sensor Populations
WS
Web Services
WSN
Wireless Sensor Network
WSAN
Wireless Sensor-Actuator Network
WSDL
Web Services Definition Language
XBow
Crossbow
XDR
eXternal Data Representation
XML
Extensible Markup Language
XML-RPC
RPC sobre XML
i
i
i
i
i
i
i
i
Agradecimientos
Como es lógico y normal ésta será, probablemente, la única hoja que leerá la mayor parte
de la gente que llegue a abrir este libro. No lo digo tanto por la falta de interés que puedan
tener sino por el probable desconocimiento del tema. Entre esas personas está mi familia. A
pesar de que todo este mundo les pueda resultar ajeno y extraño, sé que están tan orgullos
de mí como yo de ellos. Les agradezco su apoyo, paciencia y comprensión al dejarme elegir
esta profesión. Al menos lograré formar parte de ese nada exclusivo club de los M C D1 .
Desgraciadamente el país en el que vivimos otorga poco valor a una tesis doctoral.
Normalmente los que nos metemos en esta aventura buscamos algo distinto al
reconocimiento o estatus social. En mi caso, confieso que la universidad me ha dado
la oportunidad de dedicarme a cosas en las que tengo claro que es casi imposible trabajar
en la empresa, en la española al menos. He de admitir que he disfrutado con ello, no sólo
con el trabajo técnico o científico. Las discusiones, propuestas e incluso peleas en torno al
desarrollo de las ideas y los prototipos han sido para mí el mejor aliciente y el motivo no es
otro que la gente tan agradable y capaz con la que tengo la suerte de trabajar cada día.
Quiero expresar mi agradecimiento y admiración a mis directores: Francisco Moya
y Juan Carlos López. A Paco por su infinita paciencia, por estar siempre dispuesto a
escuchar cualquier problema (o «solución»), por compartir con nosotros su impresionante
capacidad técnica y aplicar sus particulares dotes diplomáticas en los escasos momentos
en los que las aguas salieron de su cauce. A Juan Carlos por su constante preocupación
por el trabajo bien hecho, por darme su confianza y demostrarme que no siempre el
camino fácil es el mejor.
Por supuesto quiero agradecer el buen ambiente que hay tanto arriba como en el
laboratorio. Gracias a Fernando, Jesús, Paco Sánchez, David de la Fuente, María José
y especialmente a Félix que, como compañero de despacho, sufre más que nadie mis
desvaríos, tanto en cuestiones de docencia como de investigación.
Y lo mismo puedo decir de los tecnólogos, becarios y colaboradores del grupo ARCO.
Gracias a Cleto, sobre todo en el último año a cargo del compilador de IcePick, que
ha experimentado como nadie el concepto de requisitos dinámicos. A Javieralso por
las incontables e interminables horas de pelea constante con los picos, sufriendo la
desesperación que conlleva trabajar con hardware, algo difícil de entender para los que no
se han visto en la tesitura. A Oscarah por su estupendo trabajo a cargo de los prototipos
de TwinPanel, IDM y EWS entre otros; su profesionalidad resulta inspiradora. Tampoco
se han librado Tobías, Lucas, Miguel Ángel, Peris y Nacho; ni Top, Magmax y Víctor,
1 Mileuristas
con Doctorado
i
i
i
i
i
i
i
i
aunque estos últimos ya no estén con nosotros, tuvieron el buen juicio de irse a tiempo.
También a Carlos González por sus consejos sobre la cubierta.
Debo agradecer al Ministerio de Industria, Comercio y Telecomunicaciones, a la Junta
de Comunidades de Castilla-La Mancha y al Fondo Europeo de Desarrollo Regional la
financiación parcial de este trabajo por medio de los proyectos SODA (TIN2005-08719),
Hesperia (CENIT 2005), MARISA (PBC-05-0009) y RGRID (PAI08-0234-8083).
De manera especial quiero agradecer a Gloria su tremenda paciencia, su constante
apoyo y comprensión. No es sencillo entender que durante estos años haya antepuesto
muchas veces (demasiadas) mi trabajo a mi vida personal, robándole horas que eran suyas.
También le agradezco su gran labor revisando incansablemente este documento, con un
nivel de detalle y precisión que costaría creer a quien no la conozca personalmente. Ella
siempre está ahí para mí. Sé que no es fácil, y no puedo por menos que ofrecerle mi
más profunda gratitud y todo mi cariño.
Mi más sincero agradecimiento a todos los compañeros de ARCO, por ser amigos, y
no sólo colegas. Me siento afortunado de poder contar con gente de tanta calidad humana
y profesional. No lo habría logrado sin vosotros.
David
i
i
i
i
i
i
i
i
11
Introducción
1.1.
1.2.
1.3.
1.4.
1.5.
Redes de sensores
Objetivos de la investigación
Estructura del documento
Middleware de referencia
Convenciones tipográficas
C
UALQUIER sistema de información que realice algún tipo de interacción con el
entorno obtiene la mayor parte de sus datos a través de sensores y responde por
medio de actuadores. La utilización de estos dispositivos en el ámbito industrial, doméstico,
académico, etc., está creciendo y dando lugar a nuevas aplicaciones en diversos campos:
domótica, inmótica, e-health y computación ubicua, pervasive computing, A M I, etc. Todas
estas tecnologías, que se pueden encuadrar en lo que habitualmente se conocen como
entornos inteligentes, constituyen un nuevo paradigma en la forma en la que los sistemas
de cómputo se relacionan con las personas y el entorno. La tendencia actual parece
indicar que su uso aumentará a medio y largo plazo.
La computación ubicua y su aplicación para la creación de entornos inteligentes se
basa en las posibilidades de comunicación con estos sensores y actuadores, desplegados
masivamente en el entorno. Para varios autores [RMKC00, RKM02], el éxito de
estos sistemas depende en gran parte de la disponibilidad de medios que logren la
interoperabilidad entre todos estos dispositivos, tecnologías y redes heterogéneas. Ello
implica interfaces y protocolos bien definidos que les proporcionen un medio sencillo
y eficiente para exportar los servicios que pueden proporcionar. Esas son precisamente
algunas de las prestaciones típicas de un middleware de comunicaciones.
Sin embargo, se da una circunstancia interesante que puede estar condicionando el
desarrollo de una industria alrededor de los entornos inteligentes. Una parte considerable
de esos sensores o actuadores son dispositivos muy simples en la forma en la que el
sistema interactúa con ellos; su función principal es ofrecer un único valor escalar como
puede ser temperatura, intensidad luminosa, presión, presencia, etc. En contraposición,
gran parte de las propuestas y plataformas que se vienen utilizando (muchas materia de
investigación) imponen una importante sobrecarga en muchos aspectos y ello repercute
dramáticamente en el coste final del conjunto. Consideramos que ése es uno de los motivos
1
i
i
i
i
i
i
i
i
2
1. I NTRODUCCIÓN
—probablemente el más grave— por el que sigue siendo inviable la adopción masiva
de estas aplicaciones en el mercado de consumo.
En este tipo de plataformas, la cantidad de memoria externa de los dispositivos
empleados va desde los 32 KiB en plataformas WesC hasta 64 MiB en la plataforma
Rockwell WINS 3.0 [KHH05, PH05, WIN]. Del mismo modo, el microcontrolador
incluido en la plataforma Crossbow MICA1 , es un ATmega128L, varios órdenes de
magnitud más caro que el microcontrolador más sencillo que existe en el mercado. Estas
plataformas consumen una cantidad de recursos considerable, aunque los nodos sensores
implementen una funcionalidad mínima.
Por ejemplo, Open Systems Gateway Initiative (OSG I) [All06], una de las tecnologías
con mayor aceptación en el mundo de la domótica, necesita dispositivos que requieren
una máquina Java con soporte RMI, lo cual implica un precio mínimo de alrededor de
30e por unidad. Pensar que este tipo de dispositivo es necesario para cada punto de
luz, interruptor, detector de paso, presencia, etc., es algo completamente inadmisible en
muchos aspectos, no sólo el económico.
Eso implica una importante contradicción: dispositivos muy sencillos y potencialmente
muy baratos, tienen precios desorbitados debido a las necesidades de cómputo que requiere
el software que permite conectarlos al sistema. Como resultado, el coste del dispositivo
que ofrece la funcionalidad real (sensor o actuador) es marginal en relación al coste
total del nodo al que está conectado.
A primera vista puede parecer que el coste de un despliegue con cualquiera de estas
tecnologías no es tan alto. Pero si se toma en consideración que cualquier aplicación de
ambient intelligence o instalación domótica con una funcionalidad digna de mención puede
involucrar decenas o centenares de dispositivos tales como sensores de movimiento, de
proximidad, micrófonos, detectores de paso, cerraduras electrónicas y un largo etcétera,
implica que el precio total de la instalación resulte totalmente prohibitivo.
Además muchas de esas plataformas resultan insuficientes o ineficientes cuando, en la
misma infraestructura de comunicaciones, se pretende integrar aplicaciones que requieren
un ancho de banda elevado, como puede ser la transmisión de flujos multimedia.
Otro aspecto importante es la interoperabilidad entre aplicaciones, servicios y
dispositivos. Lo habitual es que cada fabricante utilice sus propios dispositivos, protocolos
e infraestructura física de comunicaciones. Por ejemplo, un sensor de presencia del
sistema de seguridad no puede ser utilizado por las aplicaciones de mejora del confort,
de modo que es necesario instalar otro dispositivo que tiene prácticamente la misma
funcionalidad, pero que se comunica utilizando interfaces y protocolos de un fabricante
distinto. Intentar atar al cliente a una tecnología o fabricante concreto es una estrategia
de mercado habitual pero, en este caso, los gastos del equipo, instalación y despliegue
sobrepasan las ventajas que se obtienen.
Sin embargo, con el enfoque, medios y herramientas adecuadas es posible diseñar,
implementar y fabricar nodos sensores y actuadores de complejidad no trivial, dotarlos
de inteligencia local y reduciendo su coste a una décima parte, como mínimo. A pesar
del interés que tiene esa posibilidad, es importante señalar de nuevo que el auténtico
1 La
más utilizada en redes de sensores inalámbricas.
i
i
i
i
i
i
i
i
1. I NTRODUCCIÓN
3
objetivo no es el bajo coste. Ese es sólo un requisito que permitirá afrontar el auténtico
reto: la posibilidad de diseñar e implementar sistemas de sensores y actuadores lo
suficientemente ricos, por cantidad y calidad de la información que manejan, como para
plantear aplicaciones realmente innovadoras en entornos inteligentes. Solo con un precio
de unos pocos euros por unidad es razonable pensar en aplicaciones que impliquen
alguna de las siguientes circunstancias:
Despliegue o instalación de gran número de dispositivos en la oficina o el hogar:
cientos o miles.
Condicionantes que supongan la destrucción de los dispositivos, tales como
observación y/o control de fenómenos naturales como volcanes o incendios.
Aplicaciones que, por la ubicación de los dispositivos, impliquen costes de
mantenimiento implanteables: glaciares, exploración submarina o extraterreste, etc.
1.1.
Redes de sensores
Las redes formadas por los dispositivos mencionados reciben varias denominaciones
dependiendo de las capacidades, tecnología de comunicaciones, protocolos de encaminamiento de mensajes, etc. Una de las variantes más relevantes en los últimos años son
las llamadas WSN (Wireless Sensor Network). Según [RKM02]:
Una red de sensores inalámbricos (WSN) consiste en un gran número de pequeños
nodos, con capacidad de cómputo limitada, que cooperan en tareas de detección y se
comunican con tecnologías de comunicaciones inalámbricas.
Para las aplicaciones y servicios del sistema no debería haber ninguna diferencia en
el tipo de comunicaciones (cableadas, inalámbricas o mixtas) que se requieren para
acceder a los nodos.
Sin embargo, las comunicaciones tienen una gran influencia en el desempeño y
autonomía de la red, los procesos de despliegue, encaminamiento y actualización de
software entre otros. La capa de enlace necesita protocolos robustos que soporten
bien las frecuentes pérdidas o fallos en la transmisión física de los mensajes. En la
capa de red, la naturaleza dinámica y propensa a errores de la red inalámbrica puede
producir fragmentación de la red por lo que deben existir mecanismos para solventar
las consecuencias, sobre todo, en el caso de redes ad hoc.
Aunque no es obligatorio, los nodos de las WSN suelen ser pequeños y utilizar
alimentación por medio de baterías, paneles solares o algún otro tipo sistema con
poca autonomía o potencia. Por ello, tanto el software empotrado en el nodo como
los protocolos implicados deben considerar esta cuestión a fin de conseguir un uso
eficiente de la energía disponible.
Otro concepto más general, que no implica necesariamente comunicaciones inalámbricas,
es la Red de Sensores. La siguiente definición está tomada de [Hae06]:
i
i
i
i
i
i
i
i
4
1. I NTRODUCCIÓN
Una Red de Sensores es un conjunto de pequeños sistemas autónomos, llamados
nodos sensores, que cooperan para resolver al menos una aplicación común. Sus tareas
incluyen algún tipo de percepción de parámetros físicos.
Ampliando aún más el concepto, se puede abordar también el problema de la gestión
de nodos actuadores o mixtos sensor/actuador. A estas redes se las denomina SANet o
SAN (Sensor Actuator Network) . Cuando la SAN utiliza únicamente comunicaciones
inalámbricas se la denomina WSAN (Wireless Sensor-Actuator Network).
Incidiendo en la nomenclatura del área, es necesario puntualizar que el concepto de
sensor normalmente debe entenderse en un sentido amplio hasta el punto de englobar
también a los dispositivos de actuación. Para evitar la confusión que ello pudiera implicar,
se utiliza en este texto el término transductor2 para hacer referencia tanto a sensores
como actuadores. Por supuesto, se utilizan los términos específicos cuando se pretende
distinguirlos. En el caso de redes de dispositivos se utiliza preferentemente el término
SAN aunque ocasionalmente y, por respeto a la bibliografía, se emplean otros como WSN
y red de sensores que, en algunos casos, pueden englobar actuadores.
A pesar de ser una tecnología joven, en la que aún quedan muchos aspectos importantes
por resolver, existe ya un gran número de aplicaciones que explotan las características
únicas que ofrecen las SAN y, en especial, las WSN.
Según [Mar05], los siguientes son algunos de los usos más importantes que se han dado
a las redes de sensores y se prevé aumentarán en un futuro próximo.
Aplicaciones de monitorización de hábitats naturales.
Observación de entorno y sistemas de previsión.
Aplicaciones relacionadas con la salud.
Aplicaciones militares.
Monitorización de edificios inteligentes.
Sistemas inteligentes para control del tráfico.
Sistemas domóticos y entornos inteligentes.
Este trabajo pretende aportar facilidades técnicas para el desarrollo de servicios y
aplicaciones que involucren el uso de transductores accesibles de algún modo por medio
de redes de comunicaciones. Al mismo tiempo, se persigue una reducción de costes
que haga económicamente posible la implantación de las aplicaciones mencionadas. Se
utiliza un enfoque integrador de modo que no sea necesario renunciar a dispositivos
o tecnologías existentes o futuras.
La intención es conseguir un middleware con el que sea posible desarrollar y utilizar
aplicaciones dentro y fuera de las redes SAN de forma transparente, evitando la necesidad
de utilizar herramientas, tecnologías o paradigmas distintos para una misma aplicación.
En muchos aspectos, las redes SAN pueden verse como una particularización de la
computación distribuida heterogénea tradicional. No obstante, en este tipo de sistema
2 La
definición a la que se refiere es más cercana a la palabra inglesa transducer que al término español.
i
i
i
i
i
i
i
i
1. I NTRODUCCIÓN
5
distribuido lo más importante no es la productividad en términos de capacidad de cómputo,
como suele ocurrir en sistemas grid, clusters, redes malladas mesh networks, etc. En el
caso de las SAN son mucho más relevantes otros aspectos como el dimensionamiento
adecuado de los recursos o los servicios específicos. Otros escenarios especiales, como
las WSN, requieren soluciones a problemas inherentes como movilidad, pérdida temporal
de conectividad, autonomía de las baterías, etc.
Extendiendo los argumentos de [HMCP04], podemos considerar que en las redes SAN
se presentan una serie de particularidades que hacen que el desarrollo de aplicaciones
sea diferente al de las redes convencionales:
Las redes SAN están conceptual y físicamente distribuidas. Los nodos están dispersos
por el espacio físico y, en ocasiones, pueden ser completamente autónomos. Nuestro
enfoque trata precisamente de potenciar esta cualidad.
Disponibilidad dinámica de nodos. Pueden aparecer o desaparecer nodos en cualquier
momento ya sea porque los ha instalado/desplegado un operador o bien porque
queden momentáneamente inaccesibles al utilizar comunicaciones inalámbricas.
Las aplicaciones demandan ciertas restricciones: disponibilidad de ciertos nodos,
servicios y niveles de Q O S, lo que puede implicar la necesidad de replicación u otras
técnicas para lograr diferentes niveles de tolerancia ante fallos.
Recursos limitados. El ancho de banda de la red, la energía disponible, la memoria y
la capacidad de cómputo de los nodos pueden estar gravemente acotados.
Aplicaciones cooperativas. Es frecuente y deseable que las aplicaciones puedan
compartir el acceso a los nodos y datos que proporcionan, aunque eso puede requerir
de cierto control para evitar colapsar las comunicaciones o malgastar energía.
Esta tesis propone utilizar middlewares de comunicaciones orientados a objetos para la
integración de dispositivos simples en la red. A pesar de que históricamente se ha considerado que arquitecturas como CORBA (Common Object Request Broker Architecture) son
pesadas y requieren una importante cantidad de recursos de cómputo [RBW01, Yu004],
el presente trabajo aporta argumentos en contra de esa teoría, demostrando que es perfectamente factible implementar objetos distribuidos plenamente operativos en algunos
de los dispositivos de cómputo más pequeños y baratos que se fabrican3 y que, a pesar
de ello, cumplen los protocolos y estándares aplicables.
1.2.
Objetivos de la investigación
Tal como se comentaba anteriormente, el objetivo principal de esta tesis es el diseño
de una infraestructura para el desarrollo de aplicaciones en entornos inteligentes
sobre plataformas de redes de transductores, así como la definición de métodos y
servicios para la integración de esta infraestructura con los flujos de diseño de sistemas
distribuidos heterogéneos tradicionales. Los resultados incluyen un conjunto de protocolos
y herramientas altamente cohesivas y con bajo acoplamiento que facilitan la creación de
3 Tales
como microcontroladores de 8 bits con 1024 palabras de memoria de programa y 128 bytes de RAM.
i
i
i
i
i
i
i
i
6
1. I NTRODUCCIÓN
redes SAN de bajo coste y que permiten la integración con otras tecnologías habituales
en el campo de aplicación.
Además se describe un conjunto de servicios comunes construidos sobre objetos
distribuidos estándar, pero diseñados teniendo en cuenta las características de las redes
SAN. Eso incluye un protocolo para descubrimiento de servicios y dispositivos, utilidades
para distribución de eventos y soporte para monitorización del entorno.
Los objetivos específicos se detallan a continuación:
Middleware polivalente
Se pretende aportar métodos específicos para la implementación de objetos
distribuidos completamente autónomos e interoperables sobre plataformas de
cómputo empotradas. El principal criterio de diseño consiste en minimizar los
requerimientos de memoria y potencia de cálculo.
El aspecto más importante es que no se intenta desarrollar un nuevo middleware
para redes SAN. Se propone desarrollar métodos que permitan la utilización de un
middleware de propósito general en todo el sistema, dentro y fuera de la red o las
redes de sensores, pudiendo haber varias y de varios tipos; sin casos especiales. Este
planteamiento contrasta fuertemente con todas las propuestas previas.
Un nuevo paradigma
La integración del middleware de comunicaciones en cualquier elemento del sistema
es un logro que conlleva una ventaja decisiva. Para cualquiera de los profesionales
que intervienen en el desarrollo de aplicaciones en entornos inteligentes (analistas,
diseñadores, programadores, etc.) supone un importante cambio conceptual bajo el
cual, esta vez sí, todo es un objeto y en el que cualquier elemento físico o lógico
puede verse como una entidad que ofrece servicios al sistema, hasta tal punto que
pueden resultar indistinguibles, si se desea.
Desde el punto de vista del desarrollador de aplicaciones, un transductor presente en
el sistema se comporta exactamente igual que un objeto distribuido convencional, si
bien la implementación interna puede ser considerablemente diferente.
Descubrimiento del entorno
Se pretende aportar un SDP (Service Discovery Protocol) perfectamente compatible
con la filosofía de los middlewares para sistemas distribuidos, y que contemple
expresamente el enfoque orientado a objetos y las limitaciones propias de los
dispositivos de cómputo utilizados para la implementación de picoObjetos. El
uso de este protocolo no se limita a la red SAN. Se pretende que sea un SDP de
propósito general que pueda ser utilizado para cualquier servicio del sistema.
Encaminamiento heterogéneo
El objetivo de integración de los nodos de la red de sensores va más allá del mero
acceso a la información que pueden ofrecer. La intención es que los propios nodos
tengan la posibilidad de acceder por sí mismos a cualquier host o servicio del sistema
o, incluso, a nodos de otras redes SAN. El problema aquí es que estas redes suelen
utilizar protocolos de red incompatibles entre sí y también con la red troncal, lo cual
—en la actualidad— obliga a utilizar pasarelas a nivel de aplicación.
i
i
i
i
i
i
i
i
1. I NTRODUCCIÓN
7
Se propone el desarrollo de un nuevo protocolo de red que utilice identificadores
de objeto como direcciones lógicas y que permita, por medio de encaminadores
especiales, transportar mensajes extremo a extremo sin importar los protocolos de
red, tecnologías o topología de las redes implicadas.
Validación experimental
Se pretende validar las propuestas anteriores mediante el desarrollo de un conjunto
de prototipos funcionales que demuestren la viabilidad de su implementación sobre
aplicaciones reales.
1.3.
Estructura del documento
El presente documento trata de exponer con detalle todos los aspectos de la problemática
presentada anteriormente. A lo largo del texto se ofrecen las soluciones que propone el
autor a cada uno de esos problemas, con un enfoque constructivo, abordando primero
los problemas técnicos elementales para después ir incorporando servicios con un
mayor nivel de abstracción.
Para una comprensión más sencilla, el autor aconseja una lectura secuencial del resto
del texto. A continuación, se describe brevemente el contenido de cada capítulo.
Capítulo 2: «Antecedentes»
Se introducen las tecnologías y plataformas relacionadas con el ámbito del problema.
También se comentan aproximaciones anteriores, algunas aún en desarrollo, que
persiguen objetivos similares a los planteados aquí.
Capítulo 3: «Objetos Distribuidos Universales»
Es un modelo de información básico que facilita y simplifica sensiblemente la
interacción remota de los traductores entre sí y con las aplicaciones. La intención
es aprovechar al máximo las posibilidades de los dispositivos empotrados más
simples, pero manteniendo la generalidad, es decir, sin que ello suponga plantear
casos especiales al acceder a estos dispositivos.
Capítulo 4: «picoObjetos»
Los picoObjetos son nuestra propuesta para solventar el problema de la miniaturización de middlewares. Este capítulo describe en detalle sus fundamentos, funcionamiento y las estrategias de implementación de los mismos en sistemas empotrados.
Se hace una descripción de los requisitos funcionales mínimos necesarios para que
un nodo de una red SAN pueda interoperar con una implementación tradicional de
un Middleware Distribuido Orientado a Objetos (MDOO).
Capítulo 5: «Descubrimiento del entorno»
Contiene una descripción de ASDF (Abstract Service Discovery Framework), un
protocolo para Descubrimiento de Servicios diseñado para cubrir las necesidades
especiales de nodos de redes SAN implementados como picoObjetos, pero planteado
como una solución global aplicable al sistema completo.
i
i
i
i
i
i
i
i
8
1. I NTRODUCCIÓN
Capítulo 6: «Flujo de diseño»
Este capítulo describe el soporte que se ofrece a diseñadores, integradores y
desarrolladores de software empotrado para obtener un máximo aprovechamiento
de las aportaciones de esta tesis en la creación de aplicaciones para entornos
inteligentes y sistemas de sensorización y control. Se ha desarrollado un compilador
y herramientas auxiliares para facilitar y agilizar sensiblemente el proceso de
desarrollo.
Capítulo 7: «Integración de redes heterogéneas»
Disponer de un protocolo de red y soporte de encaminamiento a un nivel de
abstracción similar al del middleware ofrece grandes ventajas operativas que pueden
influir decisivamente en la factibilidad de ciertas aplicaciones que, de otro modo,
sería complejo conseguir. En este capítulo se analizan dichos casos de uso y se
describe el protocolo de red que se ha diseñado al efecto.
Capítulo 8: «Prototipos»
Se argumentará la viabilidad del enfoque y la metodología con un conjunto de
prototipos que ofrecen distintos grados de interoperabilidad con CORBA y ZeroC
I CE, así como con sus servicios más importantes.
Se describen las características, limitaciones y funcionalidad de dichos prototipos y
se justifica en qué medida demuestran la consecución de las propuestas desarrolladas
a lo largo de todo el documento.
Capítulo 9:«Conclusiones y trabajo futuro»
Por último, se exponen las conclusiones a las que hemos llegado tras evaluar los
resultados obtenidos en aplicación de los prototipos. Como consecuencia de las
contribuciones, se han abierto nuevas líneas de trabajo e investigación que el autor
considera podrían resultar interesantes en el futuro.
Anexo A: «Repertorio de instrucciones FSM»
Define el repertorio de instrucciones para especificación del comportamiento de
picoObjetos. Incluye el formato, modos de direccionamiento, sintaxis y ejemplos de
cada una de las instrucciones.
Anexo B: «Servicios Web empotrados»
Presenta una propuesta para la implementación de Servicios Web autónomos en
plataformas empotradas. Se utiliza una filosofía similar a la de los picoObjetos,
pero teniendo en cuenta las características y limitaciones propias de los protocolos
empleados en este tipo de sistemas. Se incluyen prototipos específicos.
Anexos C: «El protocolo Ice» y D: «GIOP»
Debido a la relevancia que tienen los protocolos GIOP e I CE P en la exposición
de algunos problemas y soluciones que se tratan a lo largo del documento, se ha
considerado oportuno incluir una traducción resumida de la documentación oficial
de dichos protocolos.
Anexo E: «Interfaces Slice»
Es una recopilación de todas las interfaces que se definen a lo largo del documento.
i
i
i
i
i
i
i
i
1. I NTRODUCCIÓN
1.4.
9
Middleware de referencia
Parte de las aportaciones de esta tesis se encuentran en los mecanismos que hacen
posible la implementación y utilización de un middleware empotrado. Por ello, el autor
considera que la inclusión de la especificación de algunas de las interfaces propuestas,
así como ejemplos y fragmentos de código, contribuye a facilitar significativamente la
comprensión de los conceptos y procedimientos descritos.
Aunque en términos generales los resultados son aplicables a la miniaturización de
cualquier MDOO, la mayoría de las especificaciones y ejemplos se refieren al middleware
ZeroC I CE. Con ello se pretende definir una línea de referencia a lo largo de todo el
documento como medio para evitar complejidad innecesaria a la hora explicar cada
una de las aportaciones y sus interrelaciones.
1.5.
Convenciones tipográficas
Este documento ha sido escrito adoptando las normas básicas de la tradición tipográfica
y ortográfica del castellano, siendo [Mar08] una excelente referencia a este respecto.
Para evitar posibles ambigüedades en la terminología técnica, a menudo se incluyen —en
cursiva y entre paréntesis— los vocablos equivalentes en inglés. Allí dónde no sea posible
la traducción del término, o el autor la considere confusa, se utiliza el vocablo original.
A fin de facilitar la lectura del texto, se han utilizado algunos convenios adicionales:
Los nombres de clases, tipos y otras entidades propias de los lenguajes de
programación se escriben con letra palo seco.
Las interfaces se escriben en cursiva.
Los identificadores de variables, nombres de ficheros, funciones y fragmentos de
código aparecen con letra monoespaciada.
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
Antecedentes
2.1.
2.2.
2.3.
2.4.
2.5.
2.6.
2.7.
Entornos inteligentes
Aplicaciones distribuidas
Sistemas Distribuidos Heterogéneos
Miniaturización de middlewares generalistas
Middlewares para redes de sensores
Encaminamiento en redes heterogéneas
Descubrimiento de servicios y recursos
22
E
N este capítulo se describen tecnologías, tanto industriales como experimentales,
relacionadas con los objetivos planteados en la introducción. Se ofrece una
descripción de los sistemas, iniciativas, proyectos, trabajos de investigación, etc., que se
aplican, o se podrían aplicar, a la resolución total o parcial de los problemas propuestos.
Las primeras secciones introducen los conceptos y paradigmas clásicos involucrados
históricamente en el desarrollo de sistemas distribuidos. Después se tratan las plataformas
que han tenido o tienen mayor apoyo por parte de la industria y, por último, se
hace un repaso a los sistemas más innovadores, siendo muchos de ellos materia de
investigación actualmente.
2.1.
Entornos inteligentes
Los entornos inteligentes (o A M I) son, por su enfoque y características, una de las
tecnologías emergentes más influenciada por los sistemas de interacción con el entorno
físico y concretamente en su relación con las personas. Según Z ELKHA [ZE98], el
entorno inteligente se caracteriza por:
Disponer de una gran cantidad de información procedente de dispositivos integrados
en el entorno, con capacidad para comunicarse por medio de una red de datos.
Poder utilizar esa información para detectar situaciones concretas que afectan a las
personas, es decir, son sensibles al contexto.
Pueden reconocer necesidades concretas de cada persona de modo que la respuesta
del sistema cambia dependiendo de la cada situación o los individuos a los que
afecta.
11
i
i
i
i
i
i
i
i
12
2. A NTECEDENTES
Tienen en cuenta la interacción del usuario con el sistema, especialmente de forma
implícita, de modo que se adaptan a situaciones y requisitos cambiantes.
Pueden anticipar las necesidades de las personas a partir de experiencia o directrices
previas.
Desde el punto de vista de la infraestructura tecnológica puede no haber una diferencia
significativa con un sistema domótico . Sin embargo, A M I proporciona servicios mucho más
complejos basados en la percepción de situaciones y necesidades, y en la capacidad para
adaptarse y adelantarse a nuevos requisitos impuestos implícitamente por los usuarios.
En estos términos, A M I tiene evidentes relaciones con la computación ubicua o los
sistemas pervasivos. Todos estos paradigmas de computación requieren mucha más
información del entorno y de medios para filtrarla y clasificarla de modo que resulte
útil a sus propósitos. En este contexto nace el concepto de la Internet de cosas (Internet of
Things) que hace referencia a la necesidad de obtener información a partir de cualquier
elemento del entorno, por insignificante que parezca, incluyendo el mobiliario o la ropa.
Esto supone una gran diferencia con los sistemas domóticos, en los que generalmente
el usuario interacciona con el sistema de forma explícita.
Según el conocido informe del Information Society Technologies Advisory Group
(ISTAG) «Scenarios for ambient intelligence in 2010» [DBS+ 01], los requisitos
tecnológicos para lograr los objetivos marcados incluyen la disponibilidad de:
Hardware especializado integrado en el entorno. Independientemente de su
complejidad o sofisticación, este tipo de dispositivos responde claramente a las
características de las redes SAN.
Una infraestructura de comunicaciones que integre dispositivos móviles y fijos.
Es decir, protocolos que permitan acceso e interacción con cualquier elemento
independientemente de la red o tecnología que utilice. El informe lo describe con un
requisito bastante esclarecedor: «Probablemente todas las redes podrían operar con
algo equivalente a la tecnología IP. Es probable que las redes troncales y de acceso
converjan».
Redes de dispositivos masivamente distribuidas y dinámicas. De nuevo se refiere a
redes de sensores, pero además implica middlewares capaces de escalar para trabajar
con cantidades enormes de dispositivos y datos, en múltiples dominios y pudiendo
adaptarse a entornos cambiantes.
La disponibilidad de tanta y tan variada información procedente del entorno no es un
requisito baladí. Ya era un grave problema en la domótica [Moy03] debido principalmente
a la complejidad de integrar protocolos, dispositivos y herramientas de distintos fabricantes.
Los nuevos requisitos que impone A M I agravan aún más esos problemas, además de
exigir nuevas y complejas prestaciones.
Si bien las redes de sensores tienen aplicación en infinidad de campos, y muchos de
los problemas que se presentan aparecen recurrentemente, en los entornos inteligentes
tienen un papel protagonista [PST07, BFG06] hasta el punto de que pueden determinar
el éxito o fracaso de este paradigma de computación. Por este motivo hemos elegido los
entornos inteligentes como hilo conductor sobre el que apoyar nuestras propuestas, aunque
sin detrimento de otros posibles usos fuera de este campo.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
2.2.
13
Aplicaciones distribuidas
En una aplicación distribuida el usuario no necesita tener (a veces, no puede tener)
conciencia de qué nodo de la red realiza el cómputo o en cuál están almacenados
físicamente los datos, y eso es cierto incluso en las aplicaciones cliente-servidor más
básicas. La principal diferencia es que en un sistema distribuido el usuario demanda un
servicio sin especificar explícitamente dónde se encuentra.
En esta sección se hace una breve retrospectiva de las principales aportaciones
conceptuales y técnicas que han contribuido a definir las bases de los sistemas distribuidos
actuales.
2.2.1.
Primeras aproximaciones
Debido al gran éxito de los sistemas Unix y su vinculación en el comienzo de Internet, el
socket BSD pronto se estableció como el estándar de facto para el desarrollo de aplicaciones
de red. Sin embargo, el socket es una API de muy bajo nivel que habitualmente implica
graves problemas de escalabilidad y mantenimiento en aplicaciones grandes ya que los
desarrolladores deben lidiar con demasiados detalles relativos a las comunicaciones.
Además, el socket no impone formato a los datos por lo que cada nuevo servicio debe ir
acompañado de un nuevo protocolo específico (protocolos del nivel de aplicación).
Las bases de los sistemas distribuidos son casi tan antiguas como las redes de
computadores. Ya a finales de la década de los 70, IETF publicó la RFC 707 [Whi75]
titulada «High-level framework for network-based resource sharing». En ella se aborda
la problemática del acceso a recursos remotos por medio de Protocolos Orientados a
la Función (Function-Oriented Protocols). En esa categoría encuadra los protocolos
de red desarrollados hasta ese momento para ARPANET, como FTP o Telnet. La RFC
plantea un enfoque innovador en aquel momento: desarrollar un protocolo genérico de
petición/respuesta que se puede utilizar como mecanismo de comunicación entre procesos
(IPC). Según el autor, este enfoque aporta interesantes ventajas:
Los recursos son accesibles a otros programas, no solo a operadores humanos.
Es posible crear un único protocolo independiente del recurso para ofrecer acceso a
un nivel funcional.
Los recursos remotos están accesibles al programador desde el punto de vista
funcional y con independencia de la aplicación.
Evita tener que diseñar, implementar y documentar nuevos protocolos específicos
para cada nueva aplicación.
Estimula la creación de recursos específicamente pensados para ser accedidos
remotamente.
Cada instrucción lleva asociado un nombre, un identificador y un conjunto de parámetros.
La respuesta incluye ese mismo identificador para realizar la correspondencia y los
resultados de la petición. La consecuencia evidente es que ese enfoque se puede denominar
protocolo de llamada a procedimiento1 . El documento concluye (texto literal):
1 Procedure
Call Protocol.
i
i
i
i
i
i
i
i
14
2. A NTECEDENTES
El modelo de llamada a procedimiento elevaría la tarea de creación de protocolos de
aplicación a la definición de procedimientos y la secuencia de llamadas. Proporcionaría
los fundamentos para un verdadero sistema de programación distribuida (DPS) que
agiliza y facilita el trabajo del programador extendiendo el entorno de programación
local para abarcar módulos en otras máquinas a través del RTE.
Esta integración de los entornos de programación local y de red se puede llevar
más lejos modificando los compiladores para que puedan proporcionar variantes de las
llamadas a procedimientos para permitir realizar llamadas remotas.
J. E. W HITE, RFC 707
El autor opina que este enfoque debería tener una gran influencia en el desarrollo
de la mayoría de los sistemas distribuidos que estaban por llegar. También advierte
sobre dos cuestiones a tener en cuenta:
La invocación de un procedimiento local tiene un coste computacional prácticamente
despreciable mientras que una invocación remota puede ser potencialmente muy
cara. Esto implica que el diseño de las aplicaciones debe hacer un uso responsable
de las llamadas a procedimientos remotos.
Las aplicaciones convencionales normalmente tienen un único punto de control,
mientras que en las aplicaciones distribuidas no suele ser así.
2.2.2.
Llamada a procedimiento remoto
El enfoque que planteaba [Whi75] fue objeto de debate en la comunidad científica
durante algunos años. Una de las consecuencias más importantes fue el trabajo de Xerox
PARC en torno al proyecto Cedar [DT80] cuya cara más visible fue la tesis de Bruce
N ELSON [Nel81] y un artículo titulado «Implementing Remote Procedure Calls» [BN84].
Como resultado desarrollaron Courier [Cou81], la primera implementación de un protocolo
para ejecución de procedimientos remotos y que dio nombre a las RPC (Remote Procedure
Call). Sus objetivos principales fueron:
Simplificar la programación de aplicaciones distribuidas, para que personal con
conocimientos básicos de redes pudiera acometer el desarrollo de aplicaciones
complejas centrándose en los problemas específicos como sincronización o
tolerancia a fallos.
Conseguir una alta eficiencia. Lo suficiente como para que el programador pudiera
optar por una llamada remota sin tener que plantearse una reducción sensible del
desempeño de la aplicación. Los experimentos de los autores incluyen la posibilidad
de eliminar los protocolos de red cuando la máquina remota pertenece a la misma
red.
Como principio de diseño, mantener la semántica de invocación lo más cercana
posible a la de las llamadas a procedimientos convencionales.
Seguridad en las comunicaciones.
Los pasos para realizar una llamada remota incluyen:
El programa del usuario realiza una llamada a un procedimiento local.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
15
Los cabos de usuario realizan el enlace (binding) y empaquetan la llamada y los
argumentos.
El núcleo de comunicaciones (RPCRuntime) transfiere los paquetes de forma
confiable.
Los cabos del servidor desempaquetan el mensaje y realizan una llamada al
procedimiento en el servidor como si fuese una llamada local con los parámetros
procedentes del cliente.
Los cabos del servidor empaquetan el resultado y lo envían al cliente.
Los cabos de usuario desempaquetan el resultado y devuelven el control al programa
del usuario cuyo proceso ha estado bloqueado desde el inicio del proceso.
Los cabos eran generados por un programa llamado Lupine a partir de una especificación
de la interfaz exportada. Incluía características muy interesantes como excepciones
remotas, mecanismos de indirección, enlace dinámico (dynamic binding) por medio
de una base de datos, etc.
Como el lector podrá comprobar, las similitudes con los sistemas venideros son
evidentes y no es arriesgado decir que este trabajo sentó las bases técnicas de los sistemas
distribuidos tal como son hoy en día.
A pesar de ello, la primera implementación de RPC que se popularizó significativamente
fue la que Sun Microsystems realizó para el sistema de ficheros NFS en Unix, quizá debido
al éxito de este entorno en relación al de Xerox. Esta implementación se conoce como
ONC RPC (o Sun RPC) y está recogida en la RFC 1831 [Sri95a]. ONC RPC utiliza las
convenciones de invocación del lenguaje C por homogeneidad con el sistema operativo
Unix. Emplea un sistema de serialización de datos llamado XDR [Sri95b, Eis06]. La
implementación de Sun incluye un compilador llamado rpcgen que genera ficheros C
para el cliente y el servidor a partir de la especificación XDR.
DCE/RPC es una implementación de RPC que forma parte de DCE (Distributed
Computing Environment) de OSF (Open Software Foundation). Entre sus características
más destacables está la autenticación opcional mediante Kerberos, la posibilidad de utilizar
parámetros de entrada/salida y el uso de hilos en el servidor para atender múltiples procesos
de forma concurrente. Dispone de un lenguaje de especificación de interfaces llamado
Interface Definition Language (IDL) y de un sistema de representación de datos llamado
Network Data Representation (NDR).
También es digno de mención el estándar ISO/IEC 11578:1996 dentro de OSI, más
conocido como ISO RPC. Define un modelo de interacción, un modelo de comunicación,
un lenguaje de notación y un protocolo. Utiliza ASN-1 como sistema de representación
externa de datos.
Características comunes
Prácticamente todas las implementaciones de RPC definen:
Un lenguaje de especificación de la interfaz, que incluye los tipos de datos y las
signaturas de los procedimientos.
i
i
i
i
i
i
i
i
16
2. A NTECEDENTES
Un compilador para el lenguaje anterior.
Un formato de intercambio de datos, que permite salvar las diferencias entre
arquitecturas y sistemas operativos.
Un protocolo específico para codificación de los mensajes.
El uso de uno o varios protocolos de transporte.
Semántica de llamada
Un aspecto a considerar es el soporte que se da a las distintas semánticas de llamada
posibles. La definición de esta semántica es importante cuando ocurren errores en el
transporte de los mensajes o en los servidores. Dependiendo de la semántica requerida,
puede ser preciso saber si la petición de ejecución de un procedimiento por parte de
un cliente ya se satisfizo.
Idealmente una RPC debería implementar la semántica exactly-once, es decir, debe
garantizar que incluso en presencia de fallo cada llamada a procedimiento remoto se ejecuta
una y sólo una vez. Sin embargo, en sistemas asíncronos, como es el caso de las redes más
extendidas en el espacio de interés de esta tesis, no es posible implementar tales garantías. El
cuadro 2.1 resume las características de las semánticas más usuales en relación al ideal.
Tipo de fallo
Sin fallos
Mensaje perdido
Servidor caído
Maybe
Ejecuta: 1
Resultado: 1
Ejecuta: 1
Resultado: 1
Ejecuta: 1
Resultado: 1
Ejecuta: 1
Resultado: 1
Ejecuta: 0/1
Resultado: 0
Ejecuta: ≥ 1
Resultado: ≥ 1
Ejecuta: 1
Resultado: 1
Ejecuta: 1
Resultado: 1
Ejecuta: 0/1
Resultado: 0
Ejecuta: ≥ 0
Resultado: ≥ 0
Ejecuta: 0/1
Resultado: 0
Ejecuta: 1
Resultado: 1
Al-least-once
At-most-once
Exactly-once
C UADRO 2.1: Semánticas de RPC en presencia de distintos fallos (P UDER [PRP05])
A efectos prácticos predominan dos semánticas intermedias entre exactly-once y
maybe:
Al menos una vez (at-least-once)
Se refiere a procedimientos que garantizan la ejecución en el servidor en caso de
pérdida de mensajes. Sin embargo, puede darse el caso de que una sola invocación dé
lugar a ejecuciones repetidas. Este tipo de semántica es adecuada con procedimientos
idempotentes, es decir, aquellos en los que la ejecución múltiple provoca exactamente
el mismo efecto y resultados que si se ejecutaran una sola vez. Un procedimiento que
calcula un valor a partir de sus parámetros es un ejemplo de llamada idempotente.
A lo sumo una vez (at-most-once)
Se refiere a procedimientos que garantizan una única ejecución, salvo en caso de
fallo del servidor. En general, este tipo de semántica requiere una infraestructura
i
i
i
i
i
i
i
i
2. A NTECEDENTES
17
software considerablemente más compleja, incluyendo secuenciamiento de mensajes
y filtrado de duplicados.
Es prácticamente imposible que el compilador de RPC pueda averiguar la semántica
de invocación requerida por sí mismo. Por eso el programador debería indicarlo
convenientemente, ya que la mejora en la eficiencia de la aplicación puede ser
significativa.
Otra característica que mejora el desempeño del protocolo consiste en no enviar los
resultados de una operación al usuario a menos que sea necesario. Cuando se utiliza un
procedimiento remoto que no tiene valor de retorno ni parámetros de salida es posible
realizar algunas optimizaciones para el transporte de los mensajes. Por ello, se distingue
entre llamadas twoway si se requiere devolver datos al usuario o oneway en caso contrario.
También puede ser relevante para el runtime considerar el envío de mensajes multi-destino,
como un caso particular de las llamadas oneway.
2.2.3.
Invocación a método remoto
La posterior revolución que supuso la Orientación a Objetos (OO) a finales de los 80
propició la aparición de un concepto obviamente relacionado: RMI (Remote Method
Invocation) . Disponer de objetos da la oportunidad no solo de aprovechar los recursos de
una máquina remota; permite además modelar el problema en los mismos términos que
si se tratara de una aplicación local, retrasando las decisiones de qué elemento debe ser
local y cuál remoto. Además simplifica enormemente la gestión de los datos relacionados
(el estado de los objetos), abriendo todo un mundo de posibilidades como el envío de
referencias a objetos propios o de terceros, paso por valor (envío de instancias), indirección,
transparencia de localización, replicación, migración y otras muchas características que
se desarrollaron a lo largo de los años 90, principalmente a cargo de la investigación
en torno a los sistemas distribuidos.
2.3.
Sistemas Distribuidos Heterogéneos
Desde comienzos de la década de los 80 la industria ha realizado numerosos esfuerzos
para intentar reducir la complejidad intrínseca del desarrollo de aplicaciones distribuidas.
Los esfuerzos más destacables son CORBA de OMG, DCE de OSF y Java RMI por
parte de Sun.
La mayoría de los sistemas distribuidos actuales tienen una infraestructura basada en
una capa de software intermedio, comúnmente llamado middleware de comunicaciones. El
middleware define protocolos, servicios básicos y un API para el desarrollo de aplicaciones.
Uno de los modelos de programación más exitosos hoy en día es el paradigma de objetos
distribuidos, que tiene como objetivo aplicar la misma semántica de la orientación a objetos
tradicional para llevar a cabo invocación a métodos de objetos remotos.
La mayoría proporcionan bibliotecas de programación en varios lenguajes, junto a un
convenio de uso que se conoce habitualmente por su denominación en inglés, mappings.
Ofrecen soporte para varios sistemas operativos, plataformas y arquitecturas hardware y,
por eso, se las reconoce como viables para el desarrollo de aplicaciones distribuidas sobre
i
i
i
i
i
i
i
i
18
2. A NTECEDENTES
sistemas heterogéneos. Las plataformas de objetos distribuidos suelen incorporar un rico
conjunto de herramientas y servicios a los desarrolladores proporcionando medios comunes,
probados y eficientes para aprovechar al máximo las posibilidades del middleware.
2.3.1.
Nomenclatura
La mayor parte de los conceptos relacionados con objetos distribuidos fueron
desarrollados antes de que se extendiera el concepto de patrón de diseño en la ingeniería de
software. Por ello existe una amplia variedad de términos relacionados que se corresponden
total o parcialmente con patrones de diseño bien establecidos. En este documento
utilizaremos una terminología relativamente actualizada, similar a la empleada en los
middlewares más modernos, que se resumen en esta sección.
Servidor
Designa un programa (un ejecutable) que se mantiene inactivo, esperando recibir
una petición de otro programa a través de una conexión de red. También se aplica
servidor para identificar el rol pasivo que puede tener un programa durante el proceso
de comunicación, aunque es habitual que un servidor pueda actuar también como
cliente. Se suele utilizar para identificar un programa que aloja objetos accesibles
remotamente, siendo esa su función principal.
Cliente
Se refiere a un programa que solicita un servicio a un servidor. Como el caso anterior,
también se utiliza para designar el rol activo de cualquier programa en el proceso
de comunicación aunque eso no impide que en otros momentos pueda actuar como
servidor.
Interfaz
Una interfaz es un conjunto de métodos que pueden ser invocados remotamente. La
interfaz es únicamente declarativa, debe existir una entidad que la implemente para
poder ser utilizada.
Objeto (distribuido)
Es una entidad abstracta que puede ser identificada unívocamente por medio de una
identidad u OID (Object Identity). Es equivalente al concepto del mismo nombre
en la Programación Orientada a Objetos (POO) con la peculiaridad de que puede
recibir invocaciones desde clientes en otras máquinas. Cada objeto implementa una
o más interfaces.
Sirviente
Es una entidad concreta (una porción de código, la instancia de una clase, etc.) que
en último término realiza la funcionalidad requerida por la invocación de un método
sobre un objeto remoto. Un único objeto puede hacer uso de uno o varios sirvientes
del mismo modo que un único sirviente puede respaldar más de un objeto.
Adaptador (de objetos)
Es un elemento que permite al servidor registrar objetos para que sean accesibles
remotamente. El adaptador debe conocer qué sirviente o sirvientes respaldan cada
i
i
i
i
i
i
i
i
2. A NTECEDENTES
19
objeto o la forma de conseguirlos. Cada adaptador tiene asociado uno o varios
endpoints a los que está vinculado.
El endpoint especifica un punto lógico de conexión. En el caso de TCP/IP, el endpoint
indica una dirección IP y un puerto, puede incluir otras características de la conexión
como, por ejemplo, el timeout.
Proxy
Es un delegado del objeto distribuido remoto en el espacio de direcciones del cliente.
A veces se le denomina referencia remota dado que su diseño sigue las directrices
básicas del patrón remote proxy [GHJV96]. Implementa la misma interfaz que el
objeto remoto, pero su función es únicamente la de redirigir las peticiones que recibe
al objeto remoto correspondiente. Del mismo modo, devuelve a la invocación local
los resultados obtenidos por la ejecución del método remoto. El proxy permite al
programador utilizar un objeto remoto como si fuera local. A veces se distingue
entre proxies directos: aquellos para los que se conoce un endpoint específico, y
proxies indirectos: que se designan con un identificador que debe ser resuelto a
través de un segundo objeto conocido.
Bus de comunicaciones
Se trata de un bus lógico situado conceptualmente justo encima de la infraestructura
de red. Este bus es el encargado de codificar, transmitir y decodificar los mensajes
que portan las invocaciones remotas. Se suele identificar por las siglas ORB (Object
Request Broker), término acuñado por OMG, pero que se aplica frecuentemente para
cualquier middleware orientado a objetos.
2.3.2.
Servicios comunes
En esta sección se describen brevemente algunos de los servicios que suelen incorporar
los middlewares. Se explica únicamente la utilidad general puesto que los detalles y casos
de uso pueden variar sensiblemente de un middleware a otro.
Servicio de eventos
Los objetos habitualmente tienen estado o propiedades que cambian y, a menudo, es
necesario notificar esos cambios de forma asíncrona a otros objetos que pudieran estar
interesados. El servicio de eventos proporciona un mecanismo de envío de mensajes
asíncronos a través del bus lógico, desacoplando productores y consumidores de datos.
Por medio de un objeto intermedio (el canal), los consumidores obtienen datos que los
productores envían al canal, previa suscripción. Normalmente, el servicio de eventos
es un mecanismo de propagación centralizado, aunque puede estar respaldado por
varios objetos.
Cuando el middleware y el protocolo de red subyacente lo permitan puede no ser
necesario un servicio como tal. Creando un proxy asociado a un endpoint multicast es
posible enviar un mensaje a todos los objetos vinculados a dicho endpoint, de modo que
no hay realmente ningún objeto intermedio y solo una copia del mensaje. Evidentemente
eso obliga a todos los participantes del canal a utilizar un mismo protocolo que, en la
mayoría de los casos, no ofrecerá garantía de entrega.
i
i
i
i
i
i
i
i
20
2. A NTECEDENTES
Cuando sea posible, el objeto interesado en los mensajes del canal puede escuchar
a la vez en un endpoint multicast y también en uno unicast de modo que se pueden
aprovechar las ventajas del servicio de eventos estándar y del direccionamiento multicast,
según convenga.
Servicio de nombres
Ofrece la posibilidad de asociar un identificador arbitrario (normalmente una cadena de
texto) a un proxy. El servicio de nombres como tal también es un objeto cuya referencia
debe ser conocida por todas las aplicaciones que necesiten resolver objetos de manera
similar a lo que ocurre con el servicio de DNS en Internet.
Servicio de persistencia
La persistencia proporciona un medio para almacenar el estado de los objetos incluso
aunque el nodo que los aloja sea reiniciado o sean migrados a otro lugar. Normalmente
la gestión de la persistencia se delega a algún agente externo tal como una base de datos
u otro mecanismo proporcionado por el usuario.
Servicio de propiedades
Permite definir un conjunto de variables que se pueden asociar a los objetos en tiempo
de ejecución para obtener un modelo de datos más rico y dinámico. Resulta muy adecuado
cuando no se puede prever en tiempo de diseño qué atributos requerirá cada clase.
Servicio de transacciones
Ofrece soporte para la gestión de transacciones y de los problemas derivados: escrituras
prematuras, equivalencia secuencial, ejecución estricta, gestión de bloqueos, esquemas
optimistas de control de concurrencia, ordenación por marcas de tiempo, etc.
Servicio de seguridad
La seguridad es un aspecto básico de cualquier sistema distribuido, involucra tanto
la confidencialidad de los datos como su integridad.
Proporciona mecanismos para garantizar la identidad de los extremos (autenticación).
También puede proporcionar transporte con cifrado para garantizar la privacidad de
las comunicaciones.
2.3.3.
CORBA
OMG (Object Management Group) [OMG] es un consorcio que agrupa a más de 800
empresas de todo el mundo. Su misión es impulsar el uso y desarrollo de la orientación
a objetos con el fin de reducir la complejidad, el coste de los sistemas de información
y permitir la introducción de nuevas aplicaciones.
Para lograrlo, desde 1989 OMG desarrolla OMA (Object Management Architecture)
, una arquitectura basada en componentes que proporciona un bus software conceptual,
independiente de:
i
i
i
i
i
i
i
i
2. A NTECEDENTES
21
El fabricante.
La plataforma de desarrollo y explotación.
El lenguaje de programación.
El lugar donde se ejecutan.
El núcleo de OMA es CORBA (Common Object Request Broker Architecture) [COR02]
y el componente intermedio que garantiza la interoperabilidad es el ORB (Object Request
Broker), que consigue que componentes escritos por diferentes fabricantes puedan
interoperar por medio de redes de comunicaciones independientemente del sistema
operativo, lenguaje o compilador empleado. Este estándar permite que un objeto invoque
a cualquier otro sin conocimiento del lugar donde reside.
La norma CORBA cubre cinco grandes ámbitos constitutivos de los sistemas de
objetos distribuidos:
Un lenguaje de descripción de objetos, denominado IDL, y una infraestructura de
distribución de objetos llamada ORB, que ha dado su nombre a la propia norma.
CORBA describe completamente las capas de servicios y de transporte características
de los sistemas de objetos distribuidos.
Una descripción de servicios comunes necesarios sistemáticamente para los objetos
de aplicación (CorbaServices). Estas especificaciones cubren los servicios de
nombres, persistencia, anuario, ciclo de vida de los objetos, concurrencia, etc. Estos
servicios, descritos mediante IDL, son necesarios en los sistemas distribuidos y
permiten aislar a clientes y servidores de los detalles de implementación debidos a
su localización o a su estado de activación.
Una descripción de servicios comunes a las aplicaciones, y no ya solamente a los
objetos (CorbaFacilities). Estas especificaciones cubren servicios de más alto nivel
como la interfaz de usuario, los documentos compuestos (para los que OMG ha
adoptado la norma OpenDoc), la administración de sistemas y redes, etc. Se trata de
un gran proyecto puesto que CorbaFacilities pretende definir colecciones de objetos
prefabricados para aplicaciones recurrentes en la empresa: creación de documentos,
administración de sistemas informáticos, etc.
Una colección de descripciones de servicios especializados por rama industrial
(DomainServices). Estas especificaciones pretenden ofrecer una descripción estándar
de objetos y servicios comunes a una industria determinada. Existen grupos de
trabajo para los sectores de las telecomunicaciones, la salud, las finanzas, etc. Éste es
el proyecto más ambicioso de OMG; DomainServices pretende crear una fundación
orientada a objetos para una informática específica de cada sector, poniendo en
común la experiencia de las empresas líderes en estos ámbitos.
Una especificación normativa de compatibilidad entre ORB S, llamada CORBA 2.0 y
posterior en algunos años a la norma CORBA 1, a la cual engloba. Esta especificación
cubre el ámbito de las comunicaciones entre diferentes ORB S, necesaria debido
a la proliferación de las implementaciones, a menudo incompatibles entre sí,
consecuencia de la adopción de la norma CORBA 1.1.
i
i
i
i
i
i
i
i
22
2. A NTECEDENTES
F IGURA 2.1: Arquitectura CORBA
Los objetos CORBA difieren de los objetos implementados en un lenguaje de
programación típico en tres aspectos. Los objetos CORBA pueden:
Residir en cualquier parte de la red y además pueden moverse dentro de ella.
Interoperar con objetos escritos en otras plataformas.
Escribirse en cualquier lenguaje de programación para el que se haya definido un
mapping a IDL.
En la mayoría de las situaciones, un cliente CORBA tiene una referencia a un objeto
remoto en forma de cabo (stub). Éste se encarga de la comunicación con el objeto remoto,
de modo que se puede acceder localmente a la interfaz del objeto como si fuese local.
Hay muchas formas de que una aplicación cliente consiga una referencia a objeto a través
del ORB, pero todas ellas deben utilizar uno de estos métodos:
Conseguir una referencia inicial directamente desde el ORB.
Conseguir una referencia a objeto a través de la invocación de un método de otro
objeto remoto.
Usar una referencia serializada conseguida por otro medio y convertirla a una
referencia real a objeto.
En la figura 2.1, la aplicación cliente hace peticiones y la aplicación servidora las
recibe y ejecuta. El flujo de peticiones surge del cliente, atraviesa el ORB y llega hasta
el servidor del siguiente modo:
El cliente puede utilizar un cabo estático compilado a partir de la definición de la
interfaz del objeto o usando Dynamic Invocation Interface (DII)2 . En cualquier caso,
el cliente dirige las peticiones al núcleo del ORB enlazado con sus procesos.
El ORB del cliente transmite las peticiones al ORB enlazado con el servidor.
2 Interfaz
de Invocación Dinámica.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
23
El ORB del servidor redirige la petición al adaptador de objetos que ha creado el
objeto destino.
El adaptador de objetos dirige la petición al sirviente que implementa el objeto
destino. Como en el cliente, el servidor puede elegir entre mecanismos de recepción
estáticos o dinámicos para sus sirvientes. Puede confiar en esqueletos estáticos
compilados a partir de la interfaz del objeto o en que sus sirvientes usen Dynamic
Skeleton Interface (DSI)3 .
El servidor devuelve su respuesta a la aplicación cliente después de ejecutar la
operación.
IDL
La parte más importante de la especificación de OMG es el IDL que permite hacer
una especificación exacta de la interfaz pública del objeto. Por tanto, en el interior de
todo objeto CORBA está su interfaz IDL, la parte más importante de su implementación.
Permite a cada objeto interactuar con el resto de objetos indicando a través del ORB
qué métodos y parámetros tiene.
A partir de la especificación IDL, CORBA define una correspondencia (mapping) entre
IDL y los lenguajes de implementación. Este mapping está perfectamente normalizado
de modo que garantiza la compatibilidad. En la actualidad, el mapping de IDL está
definido para C, C++, Java, Ada, COBOL, Lisp, Python, CORBA Scripting Language,
Smalltalk, etc.
Los fabricantes de ORB S, siguiendo estas especificaciones, han construido compiladores
que, a partir de un fichero IDL que define una interfaz, generan código en un lenguaje
de programación convencional determinado.
A partir del fichero IDL el compilador genera diferentes archivos:
El cabo del cliente, mediante el cual se puede acceder a los objetos remotos.
El skeleton (esqueleto) del objeto, a partir del cual el servidor gestionará las peticiones
de los clientes e interaccionará con ellos a través del Portable Object Adapter (POA)
.
Entre las principales características del lenguaje IDL podemos citar:
Es un lenguaje neutro y de sólo especificación (no implementación).
No existe polimorfismo.
Permite la herencia de interfaces.
Contempla la definición de:
•
•
•
•
•
3 Interfaz
Módulos.
Interfaces.
Operaciones.
Atributos.
Excepciones.
de Esqueleto Dinámico.
i
i
i
i
i
i
i
i
24
2. A NTECEDENTES
• Constantes.
Tiene un fuerte control de tipos.
Contiene calificadores de parámetros de las operaciones para determinar si son de
entrada (in), salida (out) o ambas (inout).
ORB
El ORB es el núcleo de CORBA. Es lo que se conoce como el bus lógico de objetos. El
ORB se encarga de poner en contacto a los clientes y a los objetos de forma transparente
con respecto a su localización.
Sus responsabilidades principales son:
Proporcionar mecanismos para que el cliente localice la implementación de la
interfaz.
Preparar la implementación de la interfaz para que pueda recibir invocaciones
remotas.
Proveer la comunicación que hace posible la invocación de métodos (argumentos de
la función y parámetros de retorno).
Hacer transparente al cliente los detalles de localización, acceso, serialización y
activación de un objeto remoto.
Encontrar la implementación del objeto que se solicita.
Para cubrir estas responsabilidades, el ORB proporciona cinco elementos básicos:
Una DII, para que la aplicación cliente construya dinámicamente los mensajes.
Una DSI, para que la aplicación servidor responda a mensajes construidos
dinámicamente.
Un repositorio de interfaces o Interface Repository (IR).
Una interfaz de programación para el propio ORB.
Una implementación del POA.
POA
El POA es el componente del ORB encargado de hacer accesibles remotamente los
objetos que el programador crea en un servidor. Entre sus funciones más importantes,
el POA proporciona:
Un medio para crear implementaciones de objetos portables (entre ORB S).
Soporte básico para el ciclo de vida de los objetos, incluyendo la persistencia.
Activación transparente de objetos y sirvientes.
Desacoplamiento entre objeto y sirviente, de modo que sea posible implementar
estrategias como default servant.
Creación y gestión de objetos temporales (minimizando la sobrecarga).
i
i
i
i
i
i
i
i
2. A NTECEDENTES
25
Soporte para construir implementaciones de objetos a partir de los esqueletos
generados por el compilador de IDL y también por medio de la interfaz DSI.
Se trata de un objeto que el programador debe instanciar para poner sus objetos a
disposición del ORB y, por tanto, de los clientes. Por medio de un conjunto de políticas
(policies) el programador determina aspectos concretos del comportamiento del POA que
se aplican a todos los objetos vinculados a él. El ORB incluye por defecto el RootPOA,
pero si se precisan comportamientos diferentes es posible crear varios POA S y asignarles
otras políticas. Las políticas y sus valores posibles son:
Thread – El ORB creará un hilo para atender cada nueva invocación (ORB_CTRL_MODEL)
o se atenderán en el mismo hilo (SINGLE_THREAD_MODEL).
Lifespan – Los sirvientes serán eliminados al destruirse el POA (TRANSIENT) o serán
persistentes (PERSISTENT).
Object Id Uniqueness – Los sirvientes tienen identidades únicas (UNIQUE_ID) o
múltiples (MULTIPLE_ID).
Id Assignment – Las identidades de objetos son generadas por el ORB (SYSTEM_ID) o
por el usuario (USER_ID).
Servant Retention – Los sirvientes se mantienen en el mapa de objetos RETAIN / NON_RETAIN.
Request Processing – Política de procesamiento de invocaciones: USE_ACTIVE_OBJECT_MAP_ONLY, USE_DEFAULT_SERVANT o USE_SERVANT_MANAGER.
Implicit Activation – Los sirvientes se activan automáticamente IMPLICIT_ACTIVATION
/ NO_IMPLICIT_ACTIVATION.
Referencias a objetos
Las referencias a objetos son análogas a los punteros a instancias de una clase de
C++, pero pueden denotar objetos implementados en procesos distintos (incluso en otra
máquina), así como objetos implementados en el mismo espacio de memoria del cliente.
Excepto por esta capacidad de direccionamiento distribuido, las referencias a objetos
tienen una semántica muy similar a los punteros a instancias C++:
Cada referencia a objeto identifica exactamente a una instancia de una clase.
Varias referencias distintas pueden identificar al mismo objeto.
Las referencias pueden ser nulas (no se refieren a ningún objeto).
Pueden quedar invalidadas (si el objeto referido desaparece).
Son opacas.
Usan tipado fuerte.
Permiten enlace tardío o dinámico.
Pueden ser persistentes.
i
i
i
i
i
i
i
i
26
2. A NTECEDENTES
Pueden ser interoperables.
Para que un cliente pueda utilizar un objeto remoto necesita una referencia que puede
conseguir por alguno de estos métodos:
Como valor de retorno o de salida de un método de otro objeto.
Por medio del Naming Service o el Trading Service.
Convertir una referencia a objeto en un string y escribiéndolo en un fichero que
puede transmitirse o publicarse por algún medio.
Este último tipo de referencia es textual y está pensada como alternativa a las referencias
binarias cuando se quiere almacenar o transmitir por medios más cercanos al usuario.
Las referencias textuales pueden ser de tres tipos:
IOR (Interoperable Object Reference) 4 : Identifica uno o más protocolos de apoyo y
contiene información específica para cada uno. Es lo suficientemente flexible como
para almacenar la información de casi cualquier mecanismo inter-ORB imaginable.
Permite que se puedan añadir nuevos protocolos a CORBA sin tener que rehacer
las aplicaciones existentes. Un IOR de IIOP contiene un nombre de host, un puerto
TCP/IP y una clave de objeto que permite identificar unívocamente al objeto destino.
La IOR es una secuencia de bytes de longitud variable que comienza siempre por
IOR:.
CORBAloc : Para disponer de referencias a objetos se definieron dos tipos más:
el corbaloc y el corbaname. El corbaloc está pensado para referirse a objetos que
implementan servicios estándar o a objetos registrados en el POA con un nombre
concreto (object key). Un corbaloc tiene una apariencia del tipo:
corbaloc :: arco . uclm . es :5000/ NameService
que se refiere al objeto con identidad NameService en el puerto 5 000 de la máquina
llamada arco.uclm.es.
CORBAname : Permite especificar una referencia registrada en un servicio de
nombres. Por ejemplo:
corbaname :: arco . uclm . es :5000/ NameService # casa1 / cerradura
que hace referencia al objeto registrado con el nombre cerradura en el contexto
casa1 del Name Service que reside en la máquina arco.
Transporte de mensajes
Todos los mensajes que se transmiten entre cliente y servidor utilizan un protocolo
llamado GIOP (General IOP). El anexo D es una descripción detallada de todas las
características de GIOP que pueden resultar de interés para el ámbito de este documento.
Incluye también las especificaciones relativas a la serialización de datos conforme al
formato CDR (Common Data Representation).
4 Referencia
Interoperable de Objeto.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
27
Existen varias especificaciones relacionadas con GIOP que es interesante nombrar
aquí:
IIOP [Obj04]
Se trata del transporte de GIOP sobre una arquitectura de red que utiliza una pila de
protocolo TCP/IP.
ESIOP
Se trata de protocolos no compatibles con GIOP, pero que pueden ser utilizados para
comunicación entre ORB S. La comunicación entre GIOP y distintos ESIOP puede
lograrse por medio de puentes (Inter-ORB Bridges).
DCE CIOP [Obj04]
Es un ESIOP para DCE.
HTIOP
Es una implementación de IIOP sobre HTTP pensada para facilitar el paso de
cortafuegos.
SSLIOP
Es una implementación de IIOP sobre SSL.
CORBA::Object
Cuando se procesa la especificación de interfaces, el compilador genera esqueletos
para los sirvientes en forma de clases. El programador debe heredar de esas clases y
proporcionar una implementación para los métodos que definió en el fichero IDL. Son
métodos completamente dependientes del dominio del problema y, por tanto, sólo él puede
especificar la funcionalidad requerida. Sin embargo, esas clases-esqueleto incluyen un
conjunto de métodos que corresponden a la interfaz CORBA::Object. De ese modo, el
ORB asegura que todos los objetos CORBA tienen una funcionalidad mínima que garantiza
interoperabilidad y proporciona soporte de introspección.
El listado 2.1 muestra la descripción de la mencionada interfaz en pseudo-IDL. La
mayoría de estos métodos son atendidos por el ORB o el proxy local. Solo algunos de
ellos, como non_existent() o is_a(), implican realmente acceso al objeto remoto. Se
colocan juntos por conveniencia desde el punto de vista de la abstracción de objeto.
CORBAServices
Los CorbaServices son interfaces IDL cuya especificación provee los servicios básicos
necesarios en toda arquitectura distribuida. Las distribuciones de ORB suelen traer
implementados desde los servicios más básicos (como MICO), hasta los más avanzados,
como TAO (The ACE ORB). Se describen brevemente algunos de los servicios más
importantes especificados hasta la fecha.
Servicio de Nombres El Naming Service [Obj01b] de OMG proporciona una
organización para las referencias a objetos muy parecida a la estructura empleada en
i
i
i
i
i
i
i
i
28
2. A NTECEDENTES
interface Object {
InterfaceDef get_interface () ;
boolean is_nil () ;
boolean is_a (in RepositoryId lo gi ca l_ t yp e_ id ) ;
boolean non_existent () ;
boolean is_equivalent (in Object other_object ) ;
unsigned long hash (in unsigned long maximum ) ;
string respo sitory_i d () ;
// [...]
};
L ISTADO 2.1: Interfaz CORBA::Object
un sistema de ficheros, es decir, con forma de árbol o grafo. Desde el punto de vista
práctico, su utilidad es la asociar una cadena de texto a un objeto, de modo que pueda
obtenerse una referencia real al objeto dado su nombre simbólico. Es parecido a los DNS
utilizados en Internet para resolución de nombres de dominio. Como en aquellos, el cliente
necesita una referencia inicial a el/los servicios de nombres que desee utilizar.
Una referencia a objeto es una estructura opaca que contiene la información necesaria
para la localización del objeto por parte del ORB, en el caso de TCP/IP, la información
contenida en esta referencia se compone del puerto, máquina e identificador dentro
del proceso del objeto referenciado.
Las referencias a objetos se almacenan mediante un nombre y una extensión (kind); el
binomio nombre-referencia se denomina vínculo (binding). Para crear un vínculo se utiliza
el método CosNaming::NamingService::bind(), para lo cual el cliente requiere una
referencia al contexto raíz5 . Dentro de un contexto se pueden vincular a su vez otros
contextos consiguiendo así la estructura de árbol. Además, tanto los objetos como los
contextos pueden vincularse varias veces con diferentes nombres.
El contexto raíz lo implementa normalmente una aplicación específica proporcionada
por el fabricante del ORB. El cliente requiere conocer la referencia al servidor de
nombres para poder utilizarlo. Consulte la sección 2.3.3 para más información sobre
referencias a objetos.
Servicio de eventos Event Service [Obj01a] establece canales a los cuales se suscriben
dos tipos de objetos: los productores y los consumidores. Cuando un objeto se suscribe a
un canal como productor lanza eventos al canal codificando la información necesaria, en
el otro lado todos los consumidores suscritos al canal reciben el evento (y la información
contenida en él) y actúan en consecuencia.
Además, existen dos tipos de interfaces, tanto para productores como consumidores:
la interfaz de inyección (push) y la de extracción (pull). Lo que da lugar a cuatro
tipos de elementos:
Productor por inyección (PushSupplier). Ejecuta un método remoto implementado
por el consumidor para transmitir el evento.
5 Los
contextos implementan la interfaz CosNaming::NamingContext.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
29
Productor por extracción (PullSupplier). Provee una interfaz pública para que el
administrador del canal o los clientes pregunten por los nuevos eventos.
Consumidor por inyección (PushConsumer). Provee una interfaz pública de modo
que el administrador del canal puede ejecutar su método PushConsumer::push()
cuando tenga un evento para él.
Consumidor de extracción (PullConsumer). El consumidor debe invocar el método
try_pull() o pull() de su proveedor continuamente para comprobar si hay
eventos nuevos. El método pull() bloquea al consumidor.
Las comunicaciones se establecen por medio del SupplierAdmin y el ConsumerAdmin
respectivamente. Los modelos de inyección y extracción pueden darse a la vez en el
mismo canal de eventos (ver figura 2.2).
F IGURA 2.2: Métodos de entrega de eventos en un modelo híbrido
Esta forma de comunicación asíncrona permite la realización de operaciones comunes
a determinados sucesos dentro del sistema. Existen varias evoluciones del servicio de
eventos, como el denominado Notification Service [Rod] (Servicio de Notificación),
que además permite:
Definir las notificaciones como estructuras de datos, pudiendo de ese modo enviar
una información más completa.
Los consumidores pueden especificar filtros para determinar los eventos de interés,
con lo que evitan tener que procesar eventos que no van dirigidos a ellos.
Los suministradores pueden descubrir los eventos que interesan a sus consumidores
y generar sólo esos eventos.
Se pueden configurar las propiedades del canal de eventos, de manera que se
establezcan políticas de descarte, prioridades en los eventos, etc.
Servicio de propiedades Property Service [Obj00] establece un conjunto de interfaces
estándar para asociar propiedades a los objetos. Una propiedad es un valor tipado
(property_value) identificado por un nombre (property_name). Las propiedades no
forman parte del conjunto de tipos del sistema, es decir, no están especificadas en un
fichero IDL (tampoco como atributos). De ese modo, el usuario de la aplicación puede
enriquecer el modelo de información para un cometido o durante un período concretos.
i
i
i
i
i
i
i
i
30
2. A NTECEDENTES
No interfiere con la visión que otros usuarios o aplicaciones tienen del mismo sistema
y se evita la necesidad de recompilar o reiniciar ningún componente.
La especificación incluye interfaces para la definición de metadatos básicos como
tipo de acceso (lectura/escritura), propiedades obligatorias, conjuntos de propiedades
(PropertySet), iteradores y comprobación de restricciones.
Seguridad y autenticación de objetos El Security Service (Servicio de Seguridad) de
CORBA define dos niveles de seguridad [Bak97]:
El nivel uno soporta clientes y servidores que no conocen el servicio de seguridad.
Este nivel se aplica a todos los elementos que se ejecutan sobre un ORB seguro.
Incluye seguridad entre las invocaciones y respuestas de los clientes y servidores,
protección de mensajes, control y registro de accesos.
El nivel dos soporta clientes y servidores que tienen conocimiento del servicio de
seguridad. Este servicio pone a su disposición una serie de interfaces y opciones que
delega a estas aplicaciones.
El servicio de seguridad contempla credenciales y atributos que determinan lo que
se puede hacer y lo que no. Actualmente hay dos tipos de atributos: de identidad y de
privilegios. Todos los métodos invocados deben ir acompañados con estos atributos, el
servicio de seguridad establece sus privilegios en base a ellos.
Mediante las interfaces que se ponen a disposición de las aplicaciones (en el nivel dos),
éstas pueden registrarse obteniendo credenciales para sus objetos. En lo concerniente a
las llamadas, el servicio de seguridad añade una serie de operaciones a las referencias a
objetos que permiten, por ejemplo, asociar credenciales a referencias de manera que
se apliquen cada vez que se usan.
Resumiendo, el servicio de seguridad contempla:
Autenticación de usuarios (ya sean personas físicas o sistemas).
Control de acceso a las llamadas.
Registro de acciones que ayudan al administrador del sistema a trazar los principales
eventos que han sucedido.
Delegación de seguridad entre objetos.
Encriptación de los mensajes que viajan a través de la red.
Es necesario resaltar que en la seguridad del sistema deben intervenir todas las partes
involucradas: ORB, aplicaciones etc.
Otros servicios importantes son:
Trading Service (Anuario de objetos). Permite que un cliente localice un objeto
servidor en base a determinadas propiedades de éste. Si comparamos el Naming
Service con la guía telefónica, el Trading Service es como las páginas amarillas.
Lifecycle Service (Servicio de ciclo de vida) se ocupa de los detalles de creación,
destrucción, copia y movimiento de objetos. Al contrario que otros servicios de
i
i
i
i
i
i
i
i
2. A NTECEDENTES
31
OMG, éste no puede ser construido por un fabricante, es sólo un conjunto de
recomendaciones. El servicio describe varias interfaces y patrones de diseño para
gestionar el ciclo de vida de los objetos.
Persistent Object Service (Servicio de persistencia).
Transaction Service (Transacciones entre objetos).
Concurrency Service (Paralelismo entre objetos).
Security Service y Licensing Service (Seguridad y autenticación de objetos).
Componentes
CORBA Component Model (CCM) [CCM06] describe el modelo de componentes de
CORBA, que incluye la especificación de interfaces, implementación, empaquetado y
despliegue de componentes. Un componente es básicamente un meta-tipo que se especifica
en lenguaje IDL. El componente se representa por medio de una referencia a objeto.
Cada tipo de componente puede verse como una entidad que proporciona un conjunto de
prestaciones encapsulando su implementación y representación interna.
Se definen varias formas diferentes de interactuar con un componente, ya sea con
los clientes o cualquier otro elemento del sistema. Se las denomina puertos (ports)
y son las siguientes:
Facets – Una faceta representa un modo de interacción entre el componente y el cliente.
Normalmente cada faceta implementa una interfaz IDL diferente. La interfaz del
componente incluye métodos para listar y resolver las facetas disponibles.
Receptacles – Se trata de puntos de conexión predefinidos, que pueden alojar una
referencia a un objeto proporcionado por otra entidad del sistema. Se trata de un
medio portable para establecer relaciones entre objetos.
Fuentes y sumideros de eventos – Son entidades que, respectivamente, pueden producir y aceptar eventos de un tipo concreto. Una fuente de eventos puede estar asociada
a uno o varios consumidores o a un canal de eventos.
Atributos – Son similares a los atributos de los objetos CORBA convencionales
(disponibles a través de accesores y mutadores) con la diferencia de que éstos pueden
producir excepciones. Se utilizan principalmente para configurar el componente.
Los componentes básicos no pueden ofrecer ninguna de las prestaciones anteriores,
solo pueden tener atributos.
CCM introduce un nuevo lenguaje declarativo llamado Component Implementation
Definition Language (CIDL), que extiende la sintaxis de IDL para especificación de
implementación de componentes. Esta especificación indica los detalles de conexión del
componente con el sistema, servicios estándar y otros componentes.
El componente se diseña de modo que pueda desempeñar un conjunto de tareas para un
servidor de aplicaciones manteniendo cierta generalidad. El servidor debe proporcionar
un contenedor compatible. El contenedor es el medio para lograr la interacción entre
i
i
i
i
i
i
i
i
32
2. A NTECEDENTES
el sistema y el componente puesto que actúa de intermediario en cualquier operación
que implique al componente.
Se definen cuatro categorías de componentes:
Service component – Son aquellos cuya vida está ligada a una operación. No tienen
identidad, estado ni persistencia.
Session component – Están asociados a un cliente concreto. Aunque pueden tener
estado no tienen persistencia si se reinicia el servidor.
Process component – Su identidad y estado es persistente, aunque este último no es
visible para el cliente. Lo gestiona la implementación o su contenedor. Puede
interactuar con múltiples clientes.
Entity component – Su estado es persistente y accesible por el cliente. También puede
ser compartido por múltiples clientes. Se puede obtener por medio de una primary_key de modo que su utilidad semántica es similar —salvando las distancias— a las
entidades de una base de datos.
El componente también incluye metadatos e información para su empaquetado y
despliegue utilizando un fichero XML.
2.3.4.
ZeroC Ice
I CE (Internet Communications Engine) [Hen04, HS08] es un middleware de
comunicaciones orientado a objetos de propósito general desarrollado por ZeroC [Zera].
Se trata de una empresa relativamente joven formada por prestigiosos profesionales de la
industria de los sistemas distribuidos, tales como Michi Henning, vinculado durante años
a algunos de los comités técnicos de OMG en el desarrollo de CORBA.
I CE respeta la mayor parte de los conceptos que sustentan CORBA. Sin embargo, su
diseño está dirigido únicamente por objetivos prácticos, directamente plasmados en una
implementación para su puesta en producción. Eso contrasta con el diseño por comité
característico de una organización como OMG. También evita el lastre que implica la
compatibilidad con protocolos, especialmente cuando éstos llevan asociados errores de
diseño conocidos y reconocidos.
El resultado hace de I CE uno de los middlewares con más servicios funcionales y de
más calidad del mercado, en contraste con los muchos servicios de OMG que nunca
fueron implementados por ningún fabricante.
Aunque existen diferencias destacables, es posible hacer una correspondencia directa
entre muchas de las características de I CE con respecto a las de CORBA.
Proxies
El proxy encapsula toda la lógica necesaria para contactar con el objeto remoto, enviar
el mensaje de petición, serializar los parámetros y recoger los resultados. Tiene algunas
particularidades respecto al concepto general (véase § 2.3.1) ya que el proxy I CE debe
incorporar la identidad del objeto y el identificador de la faceta.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
33
Los proxies directos incluyen información para localizar el servidor en el que se aloja
el objeto destino (el endpoint). Los protocolos soportados por defecto son TCP, UDP
y SSL; de modo que el endpoint especifica un protocolo, una dirección IP y un puerto.
Se proporcionan mecanismos para la creación de nuevos tipos de endpoints que pueden
utilizar otros protocolos que nada tengan que ver con Internet, aunque en la versión
actual no existe un API pública para ello.
I CE permite la posibilidad de utilizar proxies indirectos. En ese caso, el proxy utiliza
los mecanismos de indirección del núcleo de comunicaciones para resolver el endpoint
adecuado y poder contactar con el objeto.
Representación de proxies Cualquier proxy tiene una representación textual legible
asociada denominada en inglés stringified-proxies (el equivalente al IOR de CORBA). Para
los proxies directos esa representación está formada por la identidad del objeto, un modo
y una lista de endpoints. Es posible construir un proxy a partir de datos proporcionados
por el usuario dado que no existen partes ocultas u opacas.
En los proxies indirectos no se especifica ningún endpoint. Si el objeto está registrado
como bien conocido solo es necesario indicar su nombre. Si pertenece a un adaptador
bien conocido se especifica la identidad del objeto y el nombre del adaptador. El
listado 2.2 muestra las representaciones de los tres tipos de proxies. El apéndice D
(Proxies and Endpoints) del manual oficial de I CE [HS08] muestra en detalle el formato
y opciones aplicables.
# proxy directo
SystemControl −t : −h 10.0.0.21 −p 10000
# proxy indirecto de un objeto bien conocido
SystemControl
# proxy indirecto de un objeto en un adaptador bien conocido
SystemControl @ SystemAdapter
L ISTADO 2.2: Proxies directos e indirectos en I CE
Slice
I CE define un completo lenguaje de especificación de interfaces llamado Slice. Como
es habitual, es un lenguaje diseñado para especificar la interfaz de los objetos y los
tipos de datos que manejan de forma abstracta e independiente de la implementación
tanto del servidor como del cliente.
El programador escribe la especificación Slice en un fichero que posteriormente será
compilado por medio de uno de los I CE translators, compiladores específicos para cada
lenguaje soportado por el middleware. En la versión actual, I CE soporta la implementación
de servidores y clientes en C++, Java, C#, Python y Objective-C; y de clientes en Ruby y
PHP. Sin embargo, algunos de los servicios y extensiones solo tienen API S para C++
y Java. Contempla la declaración de:
Módulos.
i
i
i
i
i
i
i
i
34
2. A NTECEDENTES
Interfaces (con herencia).
Clases (con herencia).
Atributos.
Excepciones.
Tipos:
•
•
•
•
•
•
bool, byte, short, int, long, float, double, string,
enumerados,
estructuras,
secuencias,
diccionarios y
constantes y literales.
Algunas de sus características:
Admite directivas de preprocesamiento para incluir otros ficheros (#include) y su
control por medio de guardas (#ifndef).
Ofrece soporte para Freeze —el servicio de persistencia de I CE— directamente en la
definición de los tipos.
Permite influir sobre la generación de los cabos por medio de metadatos.
Transporte de mensajes
Para la codificación y transporte de invocaciones, respuestas, etc., I CE utiliza su propio
protocolo, llamado I CE P (I CE Protocol). En el anexo C se incluye una descripción detallada
de todas las características de I CE P que el autor considera pueden resultar de interés
para el lector a lo largo del presente documento.
Un aspecto muy interesante de I CE P es que los parámetros se encapsulan en slices
(rodajas) que son estructuras especificadas por un tamaño y una codificación. Si la
aplicación conoce el formato de la slice puede entender su contenido, en caso contrario
todavía puede almacenarla o reenviarla de modo completamente transparente.
I CE dispone de una biblioteca denominada Dynamic I CE que permite leer y escribir
mensajes I CE P de modo programático. La biblioteca se encarga de la (de)serialización de
datos de acuerdo al formato correspondiente. Esto, junto a las slices, es de gran utilidad ya
que un servidor puede redirigir invocaciones sin tener que comprender la estructura interna
de los datos que incluye. En eso se basa el funcionamiento del servicio de eventos.
Ice::Object
Todo objeto I CE implementa la interfaz Ice::Object. Como en el caso de CORBA::Object,
esta interfaz proporciona capacidades mínimas de introspección mediante los métodos
ice_isA(), ice_id() y ice_ids(), y comprobación de alcanzabilidad por medio del
método ice_ping(). Estos mecanismos de introspección no están disponibles si se accede
al objeto a través de un transporte oneway. El listado 2.3 muestra una especificación
parcial de la citada interfaz.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
interface Object {
idempotent void
idempotent bool
idempotent string
idempotent StrSeq
// [...]
};
35
ice_ping () ;
ice_isA (string typeID ) ;
ice_id () ;
ice_ids () ;
L ISTADO 2.3: Interfaz Ice::Object
Soporte para programación asíncrona
El modelo de invocación de I CE sigue el comportamiento tradicional de RMI. Como
en las invocaciones locales, implica el bloqueo del hilo que realiza la petición hasta
el momento en que reciben los resultados.
Sin embargo, I CE también ofrece AMI (Asynchronous Method Invocation). En ese
caso, el cliente debe utilizar un método distinto, acabado en _async. A parte de los
parámetros del método original, éste requiere un objeto proporcionado por el usuario,
que debe implementar una interfaz específica. Cuando se completa la invocación, el
ORB ejecuta un método de ese objeto para proporcionar los resultados o informar
de una posible excepción.
Si se especifica en la declaración del método (como metadato), el compilador de
interfaces genera los métodos AMI, es decir, este mecanismo afecta únicamente al cliente.
Para el servidor la interfaz es la misma y los métodos son atendidos y ejecutados de la
forma habitual puesto que no hay nada distinto en el mensaje de petición.
Por parte del servidor también es posible realizar despachado asíncrono mediante
AMD (Asynchronous Method Dispatching). En el modo de funcionamiento habitual
(síncrono) el servidor se ve forzado a atender inmediatamente las invocaciones de los
clientes. El hilo que gestiona los mensajes de petición en los cabos del servidor permanece
bloqueado hasta que recibe los resultados. Con AMD el servidor puede atender la petición
más adelante. Cuando el servidor realiza el trabajo informa al ORB de que la invocación
ha sido satisfecha y se pueden enviar los resultados al cliente.
Los mecanismos AMI y AMD son independientes y no afectan en absoluto al
funcionamiento de la otra parte. Puede plantearse AMI sólo para algunos clientes, o
sólo para algunas invocaciones o circunstancias especiales, y lo mismo puede aplicarse
a AMD por parte del servidor. Es factible emplear cualquier combinación de los tres
mecanismos posibles: síncrono-síncrono, AMI-síncrono, síncrono-AMD o AMI-AMD.
También es posible construir servidores que delegan parte de su trabajo a otros servidores,
en cuyo caso puede ser muy útil despachar a sus clientes con AMD e invocar con AMI.
Servicio de eventos: IceStorm
IceStorm es una implementación directa del patrón de diseño observer (también
llamado publish-subscribe). Es decir, a diferencia de los servicios de eventos habituales
en otros middlewares, IceStorm es un servicio de propagación de invocaciones, en
lugar de datos.
i
i
i
i
i
i
i
i
36
2. A NTECEDENTES
Eso tiene importantes ventajas, por ejemplo, para un cliente no hay diferencia entre
enviar un evento o hacer una invocación convencional a un servidor, lo único distinto es el
proxy que utiliza. La única particularidad es que los métodos que se invocan sobre un canal
de eventos no pueden tener valor de retorno ni parámetros de salida por razones obvias.
Por motivos de escalabilidad no es conveniente conectar demasiados nodos a un mismo
canal de eventos. Por ello, se utilizan diferentes topics6 que tienen un coste mínimo
de recursos, pero que pueden ser interconectados mediante links para propagar eventos
entre ellos. Es posible definir costes asociados a estas acciones y, de ese modo, definir
umbrales como medio para priorizar ciertos mensajes.
Por medio de la federación, se pueden agrupar los nodos asociados a una funcionalidad,
localización, tipo o servicio concreto en un mismo canal, pero manteniendo la posibilidad
de propagar ciertos eventos a otros canales.
Permite utilizar diferentes protocolos de transporte (al menos TCP, SSL y UDP) de forma
transparente para los implicados y sobre el mismo canal. Cada publicador o suscriptor
puede incluso elegir el transporte que desea de forma individual.
Servicio de persistencia: Freeze
Para utilizar el servicio de persistencia, el usuario debe aportar una especificación del
estado de sus objetos utilizando el lenguaje Slice. Un compilador especial genera código
específico para almacenar y recuperar ese tipo en una base de datos.
El servicio también contempla una solución de escalabilidad basada en los Freeze
Evictors. Éstos permiten que no todos los sirvientes que respaldan los objetos accesibles
tengan que estar en memoria en un momento dado. La base de datos de Freeze puede
almacenar una gran cantidad de objetos aunque realmente solo unos pocos estén activos.
Cuando se realiza una petición a uno de los objetos desactivados, el servicio se encarga
de recuperarlo de la base de datos automáticamente. La penalización es prácticamente
irrelevante para la mayoría de las aplicaciones.
IceGrid
IceGrid proporciona un conjunto muy rico de prestaciones:
Indirección de objetos, por medio del Locator. El Locator es el encargado de resolver
la localización real de un objeto a partir de un proxy indirecto.
Activación de servidores bajo demanda. De forma implícita la invocación de un
cliente es utilizada para desencadenar la activación del servidor que aloja el objeto
invocado.
Soporte para replicación y balanceo de carga automático.
Despliegue de aplicaciones y actualizaciones.
IceGrid se integra directamente con IceBox, un servidor de aplicaciones genérico.
IceBox se utiliza para arrancar y gestionar un conjunto de servidores aportando grandes
6 Un
topic es un canal de eventos lógico.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
37
ventajas como la posibilidad de compartir la misma instancia del ORB o la misma
máquina virtual en el caso de Java.
IcePatch2
Es un servicio para despliegue de aplicaciones y todo tipo de ficheros que éstas puedan
necesitar. Funciona bajo demanda, es decir, los nodos deben actuar como clientes para
solicitar al servidor IcePatch la versión más actual disponible de la aplicación concreta.
El servidor puede autenticar al cliente y desplegar los ficheros necesarios, incluso en
redes formadas por computadores heterogéneos.
Glacier2
Es un servicio para facilitar la integración de redes que utilizan NAT o detrás de
cortafuegos muy restrictivos. Glacier2 plantea el uso de sesiones seguras por medio de
tráfico SSL y certificados, por lo que la seguridad de la red no se verá comprometida.
2.4.
Miniaturización de middlewares generalistas
Varias iniciativas han ideado estrategias para integrar middlewares ad hoc en dispositivos
empotrados. Sin embargo, han existido relativamente pocos esfuerzos por garantizar
interoperabilidad con las plataformas y herramientas estándar como las que se utilizan
en los sistemas de cómputo habituales. En esta sección se describen algunas de las
propuestas más destacables.
El problema principal que aparece cuando se intenta empotrar un MDOO de propósito
general para su instalación en dispositivos de cómputo con características limitadas es
principalmente la cantidad de memoria que requieren los núcleos de comunicaciones
habituales.
Tal como apunta RODRIGUES [RFC03], existen principalmente tres alternativas
principales para lograr la miniaturización de objetos distribuidos:
Eliminar las prestaciones más costosas
Consiste en determinar qué prestaciones de un middleware existente (en la mayoría
de los casos CORBA) tendrán poca o ninguna utilidad en un dominio específico.
Eliminando estas prestaciones es posible reducir drásticamente las necesidades de
recursos en la plataforma objetivo.
A esta estrategia corresponden la especificación Minimum CORBA (véase § 2.4.1) y
los núcleos de comunicaciones nORB (véase § 2.4.4), dynamicTAO (véase § 2.4.5)
y sus descendientes: LegORB (véase § 2.4.7), UIC (véase § 2.4.6) y I CE -E (véase
§ 2.4.11).
Adaptar el middleware a dispositivos específicos
Este tipo de sistemas buscan aprovechar todas las características propias de
una plataforma concreta con el fin de conseguir una implementación pequeña y
eficiente que satisfaga los requisitos de la aplicación. Normalmente ello supone un
sacrificio de portabilidad, es decir, prácticamente implica por diseño la imposibilidad
i
i
i
i
i
i
i
i
38
2. A NTECEDENTES
de adaptar el sistema a otros dispositivos. En este grupo se podrían incluir
TINIORB [MML02] y PalmORB [RSC+ 99].
Usar pasarelas de protocolo
La tercera posibilidad consiste en utilizar un protocolo específico, mucho más simple
que el que impone el middleware, para comunicar un nodo maestro con los nodos de
la red. Ese maestro o pasarela se encarga bien de realizar la conversión de protocolos,
bien de recopilar información de la red interna y presentarla al exterior. En cualquier
caso, implica el uso de una pasarela que aloja entidades software (proxies) que
materialicen la ilusión de que los nodos de la red interna son objetos distribuidos.
Este es el enfoque usado en Smart Transducer Interface (STI) (véase § 2.4.9), UORB
y en una de las alternativas de integración que propone SENDA (Services and
Networks for Domotic Applications) [ML02].
Todos estos trabajos siguen las mismas reglas básicas:
Eliminar los métodos de invocación e instanciación dinámica.
Simplificar el lenguaje de definición de interfaces (OMG IDL en el caso de CORBA).
Eliminar los tipos de datos complejos o grandes.
Eliminar algunos campos del formato de trama definida por el protocolo de
comunicaciones.
Eliminar o simplificar los tipos de mensajes usados en el protocolo.
Eliminar el soporte a referencias indirectas y a servicios comunes.
Modularizar el núcleo de comunicaciones e instanciar sólo aquellos componentes
que realmente se necesiten en cada caso.
Es importante señalar que todos los núcleos de comunicación que se citan requieren
muchas utilidades de soporte adicionales: serialización de tipos de datos, primitivas de
comunicaciones, sistema operativo, etc. Es decir, los requerimientos de memoria reales
pueden llegar a ser órdenes de magnitud mayores que los citados, lo que además impide
que puedan ser comparados con precisión.
2.4.1.
Minimum CORBA
El propio OMG publicó la especificación Minimum CORBA [Obj02] , una versión ligera
de su popular arquitectura CORBA. Se trata de un subconjunto de CORBA diseñado
específicamente para sistemas con recursos limitados. Elimina las prestaciones más
costosas del núcleo de comunicaciones manteniendo un buen grado de interoperabilidad
con objetos CORBA estándar.
En los ORB S de CORBA convencionales hay muchas características que se incluyen
tanto si se utilizan como si no. Es decir, el hecho de utilizarlas no repercute en la cantidad
de recursos requeridos. En la mayoría de las aplicaciones esto no es importante, pero en
una aplicación en la que los recursos son limitados la inclusión de estas características
puede hacer impracticable la utilización del ORB. Minimum CORBA elimina algunas de
ellas de manera que se puedan implementar sólo en la aplicación que las requiera, pero
i
i
i
i
i
i
i
i
2. A NTECEDENTES
39
omitiéndolas cuando no se necesitan. Estas características dejan de formar parte del ORB
para delegar en la propia aplicación (figura 2.3).
F IGURA 2.3: Representación de las características omitidas en Minimum CORBA (b)
respecto a CORBA (a)
La omisión de una característica de CORBA supone una elección entre usabilidad y
recursos utilizados. CORBA es un entorno más amigable para el programador, mientras
que Minimum CORBA permite un mayor aprovechamiento de los recursos.
La especificación establece unos objetivos principales:
Elegir cuidadosamente qué características de CORBA se deben mantener, adquiriendo un perfil que aún tenga aplicación en el mundo de los sistemas de recursos
limitados.
Minimum CORBA debe poder interactuar con CORBA, de manera que las aplicaciones que operen sobre el ORB de Minimum CORBA puedan ser parte de sistemas que
incluyan componentes sobre ORB S de CORBA.
El soporte de IDL debe ser completo, de manera que, con los suficientes recursos,
cualquier aplicación CORBA pueda utilizarse tanto sobre CORBA como sobre
Minimum CORBA e, incluso, sobre una combinación de las dos. La posibilidad
de utilizar el mismo lenguaje IDL de OMG permite que la compatibilidad de
aplicaciones respecto a CORBA sea completa (véase § 2.4.1).
Las características que proveen a CORBA de aspectos dinámicos se omiten, de
manera que deberán ser los propios sistemas los encargados de proporcionarlos en
tiempo de diseño.
Como siempre existe la posibilidad de encontrar entornos más reducidos o acotados,
los objetivos prioritarios como portabilidad, interoperabilidad y el soporte completo del
IDL son necesarios y trata de restringir las capacidades de CORBA, pero respetando
estos objetivos.
De cualquier modo, Minimum CORBA considera ciertas características de CORBA que
influyen en el coste en términos de los recursos utilizados por el ORB o el tamaño de
los cabos, aunque estas características no se utilicen:
TypeCodes – Se mantiene la seguridad en todos los TypeCodes salvo para el tipo Any
(que está excluido), serializando las referencias a Objetos.
Excepciones – El soporte, tanto de las excepciones de usuario como las de sistema, se
puede omitir cuando no se utilizan en la aplicación. Este modelo de programación
i
i
i
i
i
i
i
i
40
2. A NTECEDENTES
aún puede ser útil (por ejemplo, en máquinas de estados finitos cooperativas donde
los objetos puedan terminar de forma segura y su recuperación depende de la propia
aplicación).
Herencia – Se pueden omitir las tablas necesarias para mantener herencia múltiple si
la aplicación no la utiliza.
Las implementaciones de Minimum CORBA pueden decidir omitir estas características
si se aseguran de que las aplicaciones no van a utilizarlas. El estándar contempla todas
las características de CORBA explicando cuáles soporta y cuáles ha decidido omitir.
A continuación, se exponen algunas de ellas:
Repositorio de Interfaces
Es un componente del ORB que permite el almacenamiento persistente de las
definiciones de interfaces, su distribución y el manejo de colecciones de definiciones
de interfaz relativas a los objetos. Se ha omitido todo excepto:
RepositoryId: es una cadena que establece la identidad de la información en el
repositorio. Permite a los programas operar con estos identificadores.
TypeCode: son valores que representan los tipos de datos, tanto primitivos como
derivados. Son necesarios para manejar el tipo CORBA Any, por lo que se ha
mantenido en Minimum CORBA.
El adaptador de objetos: POA
Minimum CORBA admite un subconjunto de las interfaces y políticas del POA:
Interfaces:
POA – Se omite el soporte del modo dinámico de operación del POA.
POAManager – El objeto POAManager se mantiene puesto que se utiliza en
la operación create_POA. Las únicas declaraciones que no se han omitido
son la operación activate y la excepción AdapterInactive, debido a que esta
operación proporciona portabilidad de las aplicaciones en entornos CORBA.
ServantManager – Se omiten los ServantManager debido a que ofrecen un
modo de operación que no resulta imprescindible en un ORB básico. Como
consecuencia, las interfaces derivadas también se omiten, igual que las
excepciones inherentes a este modo de operación.
Políticas:
ThreadPolicy – Sólo se mantiene la política ORB_CTRL_MODEL, que es la que se
aplica por defecto. Esta política delega en el ORB la responsabilidad de asignar
hilos para peticiones al POA que controla dicho ORB.
LifespanPolicy – Minimum CORBA la soporta completamente, con los valores
TRANSIENT y PERSISTENT. Los objetos asociados a un POA con política
TRANSIENT no pueden sobrevivir a la instancia del POA en la que fueron
creados. Se mantiene la política PERSISTENT debido a que es la única manera
i
i
i
i
i
i
i
i
2. A NTECEDENTES
41
de crear objetos con una referencia conocida. Esta característica puede ser
necesaria para que un servicio sea capaz de localizar a un objeto tras haber
sido reinicializado. También es útil cuando se requiere un entorno prefijado,
como puede ocurrir en aplicaciones que ofrezcan el código de acceso a las
referencias de los servidores.
ObjectIdUniquenessPolicy – También se encuentra totalmente soportada. Sus
valores UNIQUE_ID y MULTIPLE_ID permiten que los sirvientes se activen
ante un único ObjectId o que puedan soportar varios ObjectId. El coste
de implementación de ambos es muy pequeño y permite a un único sirviente
manejar varios objetos mediante multiplexación, lo que puede redundar en un
mayor aprovechamiento de recursos.
IdAssignmentPolicy – Los valores SYSTEM_ID y USER_ID se mantienen debido a
que su coste es pequeño. Si se utiliza la política SYSTEM_ID será el propio POA
quien asigne los ObjectId a los objetos, mientras que con la política USER_ID
debe ser la aplicación la encargada de ello.
ServantRetentionPolicy – Especifica si el POA debe mantener sus sirvientes
activos en la Tabla de Objetos Activos (Active Object Map). En este caso, la
política NON_RETAIN contiene elementos dinámicos no deseables, por lo que
sólo se mantiene la política RETAIN.
RequestProcessingPolicy – Especifica la forma de acceder a los sirvientes, pero
como se explicó anteriormente, el modo de acceso siempre será a través de
la Tabla de Objetos Activos que se encuentre en el POA. Esto implica que el
único valor posible para esta política es USE_ACTIVE_OBJECT_MAP_ONLY.
ImplicitActivationPoicy – Nuevamente se toma la decisión en base a qué
valores permite una implementación de un ORB sencillo y sin valores
dinámicos, puesto que el valor IMPLICIT_ACTIVATION tiene un coste nada
despreciable. De este modo, Minimum CORBA sólo soporta el modo NO_IMPLICIT_ACTIVATION, por lo que el POA no permite la activación implícita
de sirvientes.
Interoperabilidad
Para lograr la interoperabilidad hay que tener en cuenta dos situaciones: la comunicación
entre la aplicación y el ORB, y la comunicación entre distintos ORB S. Si se desea que
la interoperabilidad sea completa es necesario que estas dos situaciones se resuelvan
de manera satisfactoria.
El API del ORB ofrece un conjunto de servicios que la aplicación puede utilizar (dichos
servicios se describen en «ORB Interoperability Architecture») [COR02, Cap.13]. Si el
ORB es interoperable en este punto, cualquier aplicación CORBA podrá utilizarlo.
Por otra parte, la interoperabilidad entre ORB S permite la comunicación entre sistemas
con distintos conjuntos de prestaciones; por ejemplo, puede asegurar la comunicación
entre el ORB de Minimum CORBA y CORBA, de manera que las aplicaciones que los
utilicen puedan interactuar.
i
i
i
i
i
i
i
i
42
2. A NTECEDENTES
Correspondencias de lenguajes
CORBA especifica correspondencias con gran número de lenguajes: Ada, C, C++,
COBOL, Java, Lisp, Python, etc.; las especificaciones de estas correspondencias pueden
encontrarse en [Gro].
Minimum CORBA no especifica ninguna de ellas como obligatoria; sólo indica que
debe existir, al menos, correspondencia con un lenguaje.
2.4.2.
e*ORB
OpenFusion e*ORB [eOR] es una implementación de Minimum CORBA con extensiones
para tolerancia a fallos y tiempo real para obtener distintos niveles de servicios de
disponibilidad y predictibilidad.
Proporciona bindings para los lenguajes C, C++, Java y Ada. Las características de cada
uno de ellos son diferentes, pero podemos resumirlas en las siguientes:
Conformes a la especificación de Minimum CORBA 1.0.
Portables entre distintas plataformas.
GIOP 1.2.
IIOP.
Compilador de IDL a los diferentes lenguajes.
Alrededor de un 10 % de sobrecarga frente a sockets.
e*ORB se puede ejecutar en una HP iPAQ o en un DSP Texas Instruments TMS320C64X.
El fabricante lo describe como «el ORB CORBA más pequeño y rápido», aunque no
proporciona código fuente ni comparativas con otras alternativas.
2.4.3.
Gibraltar
Esta implementación trata de ser fiel a la especificación de Minimum CORBA. El
proyecto está dividido en módulos con objetivos concretos. Así, Gibraltar [Gib04]
necesita los módulos: tibet, que contiene toda la documentación, y france, que es el
compilador de IDL. Esta división hace posible la utilización de herramientas de otros
fabricantes para tareas específicas.
2.4.4.
nORB
nORB [SXGC03, GSP+ 03, SXG+ 04] es un middleware de propósito específico basado
en CORBA para redes de sensores, concretamente se trata del mismo dominio que describe
el programa NEST (Networked Embedded System Technology) [NESb] de DARPA. Los
objetivos que se marcaron sus diseñadores fueron:
Reutilizar infraestructuras existentes – Para evitar el desarrollo de un middleware
desde cero.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
43
Proporcionar garantía de tiempo real – Debe proporcionar tiempos deterministas a
las aplicaciones.
Proporcionar un MDOO robusto – El enfoque de comunicación de objetos distribuidos ofrece un modelo de programación más mantenible y ofrece comunicación
directa con los nodos de la red.
Recursos de cómputo limitados – La plataforma objetivo son los nodos transductores,
que tienen fuertes restricciones de memoria.
nORB sigue una estrategia de diseño bottom-up utilizando ACE (ADAPTIVE
Communication Environment) como base, pero muy dirigida por los conceptos de diseño
de Kokyu, e*ORB, UIC-Core y, especialmente, de TAO.
nORB soporta los tipos básicos de CORBA, estructuras y secuencias, pero no los
tipos Any ni TypeCode ya que se considera que las aplicaciones sobre la SAN no
harán un uso relevante de estos tipos. Utiliza CDR para la serialización de datos, cuyo
soporte proporciona ACE.
nORB ofrece únicamente los mensajes Request, Reply, Locate Request y Locate
Reply, pero elimina algunos campos del protocolo GIOP, como service context, ya que
considera que eliminar generalidad innecesaria ayuda a reducir los recursos requeridos
por la implementación.
El entorno experimental que describe S UBRAMONIAN [SXGC03] consta de cuatro
computadores con procesador Pentium 4 a 2,53 GHz, cuentan con 512 MiB de RAM
y sistema operativo KURT con núcleo Linux 2.4.18. La aplicación de pruebas aplica
Distributed Breakout Algorithm (DBA) al problema del coloreado de grafos distribuido.
La tabla 2.2 muestra el tamaño del programa ejecutable en varias alternativas. Note
que los valores mostrados incluyen el código específico de la aplicación (unos 164 kB),
pero no el de las bibliotecas del sistema o el SO.
middleware
ACE
TAO
nORB
TAO optimizado
nORB optimizado
tamaño (kB)
376
1 800
567
1 738
509
C UADRO 2.2: nORB: Tamaños de programa para una aplicación de referencia
nORB implementa un conjunto de protocolos de transporte como plugins, que incluyen
protocolos ESIOP S.
2.4.5.
dynamicTAO
dynamicTAO [KCBC02] es una extensión para dotar a TAO de capacidades de reflexión.
Un middleware reflexivo es aquel que tiene la capacidad de acceder a sus parámetros
de funcionamiento interno (introspección) y modificarlos en tiempo de ejecución para
adaptar su desempeño a las necesidades de un entorno cambiante.
i
i
i
i
i
i
i
i
44
2. A NTECEDENTES
TAO utiliza el concepto de estrategia para encapsular un conjunto de parámetros de
configuración que permiten definir aspectos de concurrencia, planificación, gestión de
conexión, etc. La estrategia está expresada en un fichero de configuración y es evaluada
y establecida en el arranque del ORB. dynamicTAO aporta mecanismos para que el
middleware pueda cambiar de estrategia en tiempo de ejecución, clientes conectados o
pueda afectar a instancias remotas del mismo ORB.
Su arquitectura se basa en un conjunto de entidades llamadas configuradores de
componentes (component configurators). Son los encargados de gestionar las dependencias
entre los componentes del sistema. Los más importantes son:
DomainConfigurator – Se encarga de mantener referencias a otras instancias del ORB
y a los sirvientes vinculados a un proceso. Debe existir una instancia de este
componente en cada proceso que ejecuta el ORB.
TAOConfigurator – Contiene referencias a las estrategias activadas. Estos componentes
están implementados como plugins, de modo que se pueden cargar o descargar en
tiempo de ejecución.
Network Broker – Recibe y gestiona las peticiones de reconfiguración del ORB.
Dynamic Service Configurator – Proporciona primitivas para la reconfiguración dinámica de los componentes.
2.4.6.
UIC
Universally Interoperable Core (UIC) [RKC01] es un middleware reflexivo diseñado
para cubrir las necesidades propias de las aplicaciones de computación ubicua, es decir:
Integración de una gran variedad de dispositivos, protocolos y servicios.
Entornos altamente dinámicos.
Posibilidad de adaptación de la propia arquitectura del middleware a la funcionalidad
requerida.
Proporciona un esqueleto para un entorno de comunicaciones completo basado en
componentes abstractos y sus instancias concretas como componentes que pueden ser
cargados dinámicamente. De ese modo, es capaz de ofrecer soporte a distintas plataformas,
dispositivos y protocolos.
Su diseño sigue dos principios básicos:
Simplicidad – Se consigue con un diseño muy modular, de modo que la descomposición funcional sea clara y fácil de comprender.
Adaptabilidad – Sólo los componentes necesarios para cubrir la funcionalidad
requerida serán incluidos en cada instancia concreta de UIC.
Esto supone una gran diferencia respecto a los núcleos de comunicaciones convencionales, en los que se incluye siempre toda la funcionalidad disponible aunque no se
utilice para un cliente u objeto concreto.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
45
La instanciación dinámica de componentes puede no ser conveniente o posible en
dispositivos con recursos limitados. Por ello, existe también la posibilidad de generar un
núcleo UIC de forma estática. Los componentes, sus interfaces exportadas y la propia
estructura del esqueleto pueden ser adaptadas estática o dinámicamente dependiendo
del escenario o dispositivo concreto.
Proporciona componentes especializados para tres importantes núcleos de comunicaciones orientados a objetos: CORBA, Java RMI y DCOM (Distributed Component
Object Model), aunque ello no implica la imposibilidad de adaptación a otras plataformas que no estén basadas en objetos distribuidos. Los componentes relacionados con
un middleware específico se denominan personalidad distinguiendo entre cliente y servidor; es posible que un mismo núcleo tenga varias personalidades al tiempo, por ejemplo, ClientCORBA, ServerCORBA y ClientJavaRMI. Todos los aspectos del núcleo de
comunicaciones pueden ser adaptados por medio de componentes: protocolos de transporte, estrategias de serialización, despachado de invocaciones, interfaz de los objetos,
gestión de la memoria, de la concurrencia, etc.
La flexibilidad de UIC permite crear núcleos de comunicaciones para un amplio rango
de necesidades; desde sistemas sin limitaciones de recursos (en cuyo caso todas las
prestaciones habituales del ORB están disponibles) hasta PDA S, cubriendo únicamente la
funcionalidad requerida. La tabla 2.3 muestra los tamaños para algunos núcleos concretos
en dispositivos de recursos limitados.
Personalidad
HybridMultipersonality
CORBA Dynamic Server
Simple TCP Dynamic Server
CORBA Static Client
CORBA Static Server
CORBA Static Full (client + server)
WindowsCE (SH3)
PalmOS
39
28
30
29
35
44,5
16
-
C UADRO 2.3: Memoria necesaria (en kB) para algunas configuraciones de UIC.
(ROMAN [RKC01])
2.4.7.
LegORB
LegORB [RMKC00] es un ORB modularizado con capacidades de configuración
dinámica por medio de una arquitectura basada en componentes. Sigue los mismos
principios de diseño que UIC, pero con dos diferencias principales: está mucho más
orientado a dispositivos con pocos recursos y sólo utiliza CORBA.
LegORB incluye únicamente los componentes esenciales para garantizar interoperabilidad CORBA. El programador puede implementar componentes a medida o utilizar
los que ya incorpora el ORB. El núcleo de LegORB tiene tres component configurators
(véase § 2.4.5): LegORB configurator, Client-side configurator y Server-side configurator. Con ellos se pueden combinar los elementos necesarios para crear un núcleo de
comunicaciones funcional. Estos elementos se clasifican en diferentes categorías: red,
serialización, etc. Así se determina la funcionalidad, comportamiento y tamaño del ORB
resultante. No obstante, estos componentes se pueden cargar y eliminar en tiempo de
i
i
i
i
i
i
i
i
46
2. A NTECEDENTES
ejecución, de modo que la aplicación puede decidir si se requiere la funcionalidad necesaria como cliente, como servidor o ambos.
La interfaz de invocación dinámica no es conforme a la especificación CORBA pero,
según sus autores, resulta suficiente para dispositivos empotrados. LegORB ha sido
instalado con una PDA PalmPilot con SO PalmOS 3.0 y con un terminal HP Jornada
680 con WindowsCE 2.11. Se ha probado la interoperabilidad de un cliente conectando a
un objeto alojado en un PC que utiliza TAO. En la versión PalmPilot el tamaño de LegORB
es de 6 kB y en la WindowsCE de 20 kB (solo cliente en ambos casos).
2.4.8.
MicroQoSCORBA
MicroQoSCORBA (MQC) [Hau01] es un conjunto de herramientas CASE para la
creación de núcleos CORBA personalizables. Su objetivo es facilitar la creación de
middlewares especializados a desarrolladores de aplicaciones distribuidas sobre sistemas
empotrados que no tengan experiencia en este área.
Utilizando un compilador de IDL propio y herramientas gráficas proporciona al
desarrollador la posibilidad de especificar diferentes aspectos tales como protocolo de
comunicaciones, seguridad, consumo de potencia, rendimiento y otras restricciones de
Q O S, para obtener un ORB a la medida de las necesidades de la aplicación y plataforma
objetivo. Algunos de los aspectos que puede especificar el programador son:
Roles del ORB
Sólo se incluyen las utilidades para el lado del servidor, del cliente o ambos, si son
necesarias.
Soporte para servicios
Por ejemplo, para utilizar el servicio de nombres.
Protocolos de comunicación
Aparte de los protocolos de transporte soportados: TCP/IP, UDP, serie y 1-Wire;
también permite distintos protocolos para codificación de mensajes: GIOP, GIOPLite y MQC-IOP. MQC-IOP es un protocolo basado en GIOP 1.1, pero que elimina
campos innecesarios para simplificar las rutinas de construcción y reconocimiento
de mensajes. También utiliza otras técnicas que no comprometen la interoperabilidad,
como la restricción de utilizar identidades de objeto de tamaño fijo.
Tipos de datos
El programador puede especificar individualmente si desea que se incluyan las rutinas
para serialización de muchos de los tipos CDR y excepciones. No se permiten tipos
complejos como Any o TypeCode.
Compresión
Opcionalmente es posible comprimir los nombres de métodos e interfaces para
reducir el tamaño de los mensajes.
La implementación realizada está escrita en lenguaje Java y se ejecuta sobre el dispositivo
Tiny InterNet Interface (TINI) y también sobre PC S convencionales. La implementación
i
i
i
i
i
i
i
i
2. A NTECEDENTES
47
proporcionaba interoperabilidad con ORB genéricos como JacORB, TAO, Visibroker y
ZEN. Las opciones utilizadas fueron GIOP, TCP/IP, serialización en línea y compresión
de nombres. La tabla 2.4 muestra el tamaño de los ficheros .class de la aplicación y las
bibliotecas para distintas alternativas. En la comparación, MQC no proporciona soporte
para ningún servicio estándar mientras que JacORB sí lo hace (suponen unos 3.7 MB
del tamaño indicado). El tamaño de la JVM es de 1 MB para JacORB y 200 kB para
ZEN. La memoria RAM requerida por MQC en el dispositivo TINI es de unos 31 kB
para un cliente y unos 35 KB para un servidor.
GNU/Linux
TINI
middleware
cliente
servidor
cliente
servidor
Java RMI
MQC
Zen
JacORB
4,38
35,18
356,08
6 596,19
4,59
43,41
351,70
6 592,64
14,59
-
22,11
-
C UADRO 2.4: MQC: Comparativa de memoria necesaria (en kB). (Olav H AU GAN [Hau01])
2.4.9.
Smart Transducer Interface
Las redes de dispositivos (no solo las SAN) tienen habitualmente un conjunto de
necesidades comunes. En ese contexto, aparece el concepto de ST (Smart Transducer)7 ,
que puede definirse como sigue:
Un smart transducer es un dispositivo formado por uno o varios transductores (sensores
y/o actuadores), un elemento de cómputo simple (microcontrolador), una o varias
interfaces de comunicaciones y el software necesario para la comunicación, calibración
y diagnosis de los transductores que incorpora.
Existen varias propuestas que pretenden definir una interfaz estándar para ST S: el
estándar IEC 61158 (muy influenciado por sistemas anteriores como PROFIBUS y
FieldBus), IEEE 1451.2, etc. Sin embargo, en el contexto de este documento, resulta
mucho más interesante la especificación STI [Obj03] de OMG debido a que implica
la utilización de un MDOO.
STI pretende definir y estandarizar una interfaz universal para la comunicación e
integración de ST S pasados y futuros, incorporando al diseño los requisitos que aparecen
reiteradamente en las aplicaciones relacionadas con estos dispositivos. La especificación
comprende un servicio de transporte de datos dirigido por tiempo (time-triggered) y la
definición de interfaces para un sistema CORBA.
Para STI un sistema ST es un conjunto de racimos (cluster) de transductores accesibles
a través de un único bus de comunicaciones. Cada racimo depende de un nodo maestro
que lo conecta a una pasarela que es la encargada de que los transductores sean vistos
como objetos CORBA. El maestro se comunica con los ST S utilizando un protocolo
de comunicaciones de tiempo real (ver figura 2.4).
7 Transductor
inteligente.
i
i
i
i
i
i
i
i
48
2. A NTECEDENTES
F IGURA 2.4: Representación de un sistema STI [Obj03]
Todos los datos que puede ofrecer el transductor se acceden a través de registros de un
sistema llamado Interface File System (IFS). Por medio del bus interno del racimo (fieldbus)
se copian datos desde y hacia el IFS de cada ST. La planificación de estas operaciones de
bus está predefinida. Cada ST puede contener un máximo de 64 ficheros en su IFS; cada
fichero es un vector de 256 registros (32 bits por registro). Estos registros son accesibles
como unidades individuales mediante un sistema de direccionamiento jerárquico.
Se definen tres interfaces especializadas para acceder a los datos de cada ST individual
por medio de registros IFS:
DM (diagnosis and management) – Permite leer y modificar registros IFS relacionados con los parámetros y la calibración inicial del transductor, también se utiliza para
acceder a datos de diagnóstico que sirven para verificar el correcto funcionamiento
del nodo y sus transductores.
CP (configuration and planning) – Se utiliza para configurar e integrar nodos nuevos
en la red.
RS (real-time service) – Se establece una comunicación periódica para recoger datos
relacionados con el valor de los transductores del nodo. En el caso de un sensor,
el ST realiza lecturas del sensor periódicamente, las preprocesa, acondiciona y las
envía al maestro del racimo.
El transporte definido en la citada especificación ha sido implementado en el protocolo
TTP/A. Utiliza un sistema de arbitraje de bus de tipo TDMA, y es lo suficientemente
simple para ser implementado en microcontroladores de 2 KiB de memoria Flash y 64
bytes de memoria RAM. Es importante señalar que este protocolo se utiliza sólo en
el racimo para comunicar los ST S con el maestro, es decir, los clientes de la aplicación
CORBA acceden a datos alojados en la pasarela y en ningún momento tienen comunicación
directa con los dispositivos detrás de la misma.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
49
NAGEL[NA02] propone un enfoque con características similares. Describe cómo
una colección de pequeños microcontroladores de 8 bits pueden aparecer como un
conjunto de objetos CORBA. El host ejecuta un proxy para cada dispositivo conectado y
las comunicaciones entre los dispositivos y el proxy utilizan un protocolo específico
no estándar.
2.4.10.
UORB
Ubiquitous ORB [RFC03] propone un sistema que permite a dispositivos con
limitaciones de capacidad de cómputo y memoria, participar en un entorno CORBA,
pero sin que estos implementen ninguna función del ORB. Sigue un modelo similar al
que planteaba Jini Surrogate Architecture [Sun06] de Sun Microsystems.
No implementa ninguna interfaz CORBA en los dispositivos, de forma similar a
STI, de modo que éstos utilizan la infraestructura CORBA únicamente a través de los
objetos intermediarios8 alojados en un computador sin restricciones de recursos. Estos
intermediarios son objetos CORBA convencionales que pueden desarrollarse con cualquier
ORB disponible; es la referencia de estos objetos la que se publica y la que utilizan
los clientes para acceder desde la red CORBA.
El sistema proporciona integración automática de nuevos dispositivos basada en un
mecanismo de descubrimiento entre el dispositivo y el computador intermediario. Por
medio del objeto intermediario, el dispositivo averigua la identidad del servidor pero
no necesita conocer la información de direccionamiento. También es posible utilizar
diversos mecanismos de comunicación entre los dispositivos y el host intermediario,
tales como memoria compartida o sockets Unix.
Como UORB no es una implementación conforme a Minimum CORBA, todos las
estrategias de escalabilidad como servant activators o servant locators están disponibles,
así como cualquier servicio de la plataforma. Por ejemplo, se requiere el servicio de
nombres (CosNaming) e IR para su correcto funcionamiento.
El sistema se sustenta en dos módulos principales:
El servicio intermediario (Surrogate Host). Se preocupa de la carga, activación y
ejecución de los objetos intermediarios.
El adaptador de interconexión (Interconnect Adapter). Se encarga de las comunicaciones entre el módulo anterior y los dispositivos, que se efectúa por medio del
protocolo de interconexión.
Dicho protocolo (basado en IP) define los mecanismos de descubrimiento (basado en
multicast), registro y recuperación de objetos intermediarios y comprobación periódica
de los dispositivos (liveness).
Se realizó y simuló un prototipo implementado en lenguaje Java con JDK 1.3 sobre
ORBacus 4.1. El tamaño del bytecode generado es de 45 kB tanto en el caso de un
cliente como en un servidor. En cuanto a la plataforma requerida, RODRIGUES[RFC03]
indica que las necesidades de procesamiento y memoria son menores que las de Orbix/E
8 Llamados
surrogate objects en la terminología de Jini.
i
i
i
i
i
i
i
i
50
2. A NTECEDENTES
2000 (un ORB conforme a Minimum CORBA). No se indican detalles concretos sobre
la posible plataforma objetivo.
2.4.11.
I CE -E
Embedded I CE (I CE -E) es una versión de I CE para sistemas empotrados, especialmente
orientada a smart phones y otros dispositivos personales con energía y memoria
relativamente limitada. Como en los casos anteriores, la estrategia utilizada consiste en
eliminar prestaciones, concretamente se ha eliminado la gestión de conexiones ACM,
el soporte para UDP y SSL, el Servant Locator, las optimizaciones de co-ubicación,
el despachado asíncrono (AMD), las utilidades de dynamic I CE y la compresión de
paquetes entre otras.
Sin embargo, se han añadido otras prestaciones útiles para las aplicaciones y plataformas
objetivo: sirvientes por defecto, priorización de hilos, soporte para Windows Mobile y
dispositivos Embedded Linux, compilación estática y lo más importante, la posibilidad
de elegir las prestaciones del ORB al compilar gracias a su sistema de construcción
modular. Pudiendo además utilizar una versión completa de la biblioteca o una que solo
incluye funcionalidad para clientes. Según su documentación [Ice], un cliente enlazado
estáticamente ocupa menos de 216 kB mientras que un servidor ronda los 272 kB.
2.5.
Middlewares para redes de sensores
En esta sección se hace una descripción de algunos de los middlewares para redes
SAN más relevantes. La mayoría de ellos se centran específicamente en WSN dado
que se considera un área con condicionantes particulares [HM06, RKM02, HR06,
WCLD08, Yu004, VHM+ 07, R0̈4]. Concretamente, las comunicaciones inalámbricas
y la alimentación por medio de baterías tienen una gran influencia en el diseño y
prestaciones de estos sistemas.
Las propuestas analizadas se han clasificado en 5 tipos, aunque no son excluyentes. Para
cada tipo se presentan en detalle las que consideramos más representativas.
Máquina virtual
Se basa en la utilización de un intérprete de bytecode que se aloja en el nodo. Los
motivos para seguir este enfoque son variados:
Conseguir portabilidad de los programas entre distintas arquitecturas. Se consigue
independencia del dispositivo, simplifica los procesos de depuración y prueba.
Crear un juego de instrucciones con un mayor nivel de abstracción, más cercano
al dominio del problema de modo que el programador de la aplicación no necesita
conocer los detalles del dispositivo.
Disponer de programas más pequeños. Eso implica actualización y despliegue más
eficiente de las aplicaciones que se ejecutan en los nodos al tener que transmitir
menos bytes.
Se describen Maté (§ 2.5.5), Magnet (§ 2.5.6), SensorWare (§ 2.5.7) y WSP (§ 2.5.14).
i
i
i
i
i
i
i
i
2. A NTECEDENTES
51
Base de datos virtual
Modelan la red de sensores como una base de datos distribuida. Ofrecen un lenguaje
de consulta similar a SQL. Este lenguaje permite escribir consultas para seleccionar un
conjunto de sensores por su tipo, localización u otros atributos. A los sensores seleccionados
se les puede solicitar su valor y en algunos casos proporcionan operadores de agregación
como la suma o la media de sus valores.
En general estos sistemas consideran que todos los nodos son similares y ofrecen
información homogénea asumiendo que todos ellos tienen un conjunto concreto de sensores
que se representan como columnas de una tabla. Esto es una grave limitación en entornos
en los que pueden aparecer nuevos tipos de nodos o sensores.
Este modelo es adecuado para sensores que ofrecen valores simples, pero es insuficiente
para tratar datos generados por sensores complejos como micrófonos, arrays de sensores
infrarrojos o cámaras de vídeo [HR06].
Se describen SINA (§ 2.5.1), DSWare (§ 2.5.2), TinyDB (§ 2.5.3) y Cougar (§ 2.5.4).
Macro-programación
Es un enfoque holístico de la funcionalidad de la SAN. El programador escribe un
programa en el que especifica el funcionamiento de la red completa como un solo ente.
Después, un compilador genera un conjunto de instrucciones o programa individual para
cada nodo, y así una vez en ejecución, el comportamiento de la red corresponda con
el requerido en la especificación original.
Se describen Maté (§ 2.5.5), Magnet (§ 2.5.6), SensorWare (§ 2.5.7) y WSP (§ 2.5.14).
Clusters
Son middlewares cuyo funcionamiento está determinado por la formación de clusters
o grupos de nodos. Uno de los nodos del cluster asume un rol especial actuando como
cabeza. Ese nodo se encarga de tareas de agregación de datos, filtrado o encaminamiento.
El procedimiento para la formación del grupo o la elección de la cabeza varía mucho
de un sistema a otro.
SINA (§ 2.5.1), DSWare (§ 2.5.2) o EnviroTrack (§ 2.5.12) utilizan clusters.
Otros
Se describen también otros middlewares con diseños menos convencionales; orientados
a la movilidad de los nodos: Impala (§ 2.5.10), con especial énfasis en la adaptabilidad
de la red y las aplicaciones: MiLAN (§ 2.5.8) y TinyCubus (§ 2.5.9) o que modelan la
SAN como un espacio de memoria compartida: TinyLime (§ 2.5.11).
2.5.1.
SINA
Sensor Information Networking Architecture (SINA) [SJS01] es un middleware que
ofrece soporte para la organización adaptativa de la información disponible en los sensores
mediante un conjunto de primitivas. Modela la SAN como una colección de objetos
i
i
i
i
i
i
i
i
52
2. A NTECEDENTES
masivamente distribuidos y permite la organización e interacción con los nodos de la red
bajo criterios de escalabilidad, fiabilidad y uso eficiente de la energía.
Las bases de su diseño son:
Organización como clustering jerárquico basado en los niveles de energía y
proximidad de los nodos. Con ello se logra un acceso energéticamente eficiente
desde el punto de vista de las comunicaciones. Hace uso de protocolos que reducen
las retransmisiones cuando la información solicitada involucra a nodos cercanos. El
proceso de clustering se reinicia cuando la cabeza del cluster falla o su batería baja
de cierto umbral.
SINA asume que el usuario nunca requerirá información proporcionada por un sensor
concreto. Las aplicaciones únicamente requieren datos generales sobre una zona o
colección de sensores relacionados.
Identificación de los nodos basada en atributos. Los nodos no se acceden por
medio de un identificador o dirección explícita. En lugar de eso se utiliza
un enfoque basado en atributos y valores [EGHK99] ya que se considera
que encaja mejor en la naturaleza data-centric de las redes de sensores.
Por ejemplo, se puede seleccionar un nodo como [type=temperature, id=101,
timestamp=1/10/2000:09:05:29, location=N-E, temperature=103] y responderá
o no dependiendo de la consulta que se haga a la red.
La información de los sensores se almacena y presenta como hojas de cálculo
asociativas [KSSZ97]. De ese modo, la información se accede y organiza de acuerdo
a las necesidades de cada aplicación específica.
Las aplicaciones obtienen la información recogida por los sensores haciendo
consultas a esas hojas de cálculo (una por sensor) por medio de SQTL (Sensor
Query and Tasking Language).
SQTL es un lenguaje de script basado en la sintaxis de SQL. Aparte del acceso a
los datos de los dispositivos, proporciona primitivas para la gestión de eventos y las
comunicaciones.
Las aplicaciones consideradas por SINA requieren la localización espacial de los nodos.
Como resulta económicamente prohibitivo instalar un receptor GPS en cada sensor, se
establecen mecanismos para que los nodos que no lo tienen puedan calcular su posición
a partir de información periódica que reciben de los nodos que sí tienen GPS.
La asunción de que las aplicaciones no estarán interesadas en datos de nodos individuales
impide a la aplicación elegir la granularidad que más le conviene en cada caso. También
limita las posibilidades del middleware para realizar tareas sencillas, pero muy habituales
en aplicaciones típicas en muchos ámbitos como la domótica, la seguridad y, en general,
cualquier entorno inteligente.
2.5.2.
DSWare
Data Service middleWare (DSWARE) [LLS+ 03] es un middleware centrado en los
datos que proporciona una abstracción de base de datos. Está basado en la definición
de grupos como medio para la toma de decisiones, correlación de datos y ahorro de
i
i
i
i
i
i
i
i
2. A NTECEDENTES
53
energía. Asume que las operaciones sobre la WSN implican restricciones temporales
y requieren una respuesta en tiempo real.
La arquitectura de DSWare se basa en los siguientes componentes funcionales:
Almacenamiento de datos
Los datos que describen diferentes ocurrencias del mismo tipo de actividad se
pueden mapear en ciertas localizaciones para que futuras consultas no impliquen
nuevos mensajes en la red, optimizando de ese modo el uso de la red y, por tanto, la
autonomía.
Caché de datos
Se mantienen varias copias de los datos más solicitados. Los datos se distribuyen a
lo largo de las rutas para reducir las comunicaciones. Es posible determinar el uso
de cada copia. Éstas se pueden migrar a otros nodos para maximizar su uso.
Gestión de grupos
Asume que los sensores del mismo área producen valores similares. Eso permite que,
en zonas con suficiente densidad de sensores, se puedan detectar nodos que ofrecen
lecturas erróneas. También es posible desactivar sensores cuando se detecta que
ofrecen información redundante y así ahorrar energía. Este componente se encarga
también de aquellas tareas que requieren la cooperación de un conjunto concreto de
sensores.
Los grupos se crean cuando se debe satisfacer una necesidad y desaparecen cuando
termina la tarea asignada. El sistema hace una consulta a la red y son los sensores
los que deciden si formarán parte del grupo evaluando el criterio indicado en la
consulta.
Detección de eventos
Los eventos se registran de acuerdo a cada aplicación.
Suscripción de datos
Es un servicio avanzado de suscripción a eventos por medio de consultas que
implican una duración y un ratio.
Planificación
Proporciona gestión de plazos para tiempo real y ahorro de energía. Las aplicaciones
pueden especificar el esquema de planificación teniendo en cuenta sus propios
condicionantes.
Los eventos tienen una gran importancia en esta propuesta. Se clasifican en atómicos
(detectados por un sensor) o compuestos (inferidos a partir de coincidencia temporal o
espacial de otros eventos). Por ejemplo, un evento compuesto explosión ocurre cuando
se detectan eventos atómicos acústicos, luminosos y de subida de la temperatura al
mismo tiempo.
Cuando ocurren eventos físicos lo habitual es que el sistema detecte sus consecuencias
por medio de diferentes sensores (sub-eventos). La función de confianza ayuda a determinar
si el conjunto de sub-eventos encajan en la definición de un evento complejo teniendo
i
i
i
i
i
i
i
i
54
2. A NTECEDENTES
en cuenta factores de contexto, históricos, importancia relativa de cada sub-evento,
distancia al lugar, etc.
Para la declaración, registro y cancelación de eventos utiliza una interfaz que procesa
un lenguaje similar a SQL.
Plataforma
Ofrece resultados en la gestión de eventos en un despliegue simulado, pero no incluye
información sobre una implementación en dispositivos físicos o de los requisitos de
cómputo que implicaría.
2.5.3.
TinyDB
TinyDB [MFHH05] utiliza un lenguaje llamado ACQL similar al utilizado por SINA.
El procesador de consultas está diseñado para reducir las comunicaciones y el consumo
de energía. La red de sensores completa está modelada como una única tabla (SENSORS)
de una base de datos en la que cada fila es un sensor y cada columna un atributo:
identificador, autonomía, etc. El lenguaje de consulta tiene capacidades para procesamiento
de eventos y especificación del tiempo de validez. Dispone de características para
agregación flexible y extensible de los datos.
Sin embargo, el middleware ofrece poco soporte a las aplicaciones. Éstas no tienen
la posibilidad de influir en los parámetros a optimizar y deben implementar la mayor
parte de la funcionalidad necesaria por los servicios. Presenta problemas de escalabilidad
dado que las consultas se envían a todos los nodos y debe mantener un árbol de
expansión de toda la red.
Está implementado como un componente para TinyOS.
2.5.4.
Cougar
Cougar [YG02] es otro middleware de base de datos virtual. Como en los anteriores,
utiliza un lenguaje de consulta inspirado en SQL. Sus características son muy similares
a las de TinyDB incluyendo los operadores para selección de sensores y agregación
de datos por técnicas de clustering, gestión de eventos y procesamiento de consultas
optimizado para ahorro de batería.
No se aporta información sobre la plataforma de implementación o los recursos
requeridos.
2.5.5.
Maté
Maté [LC02, LGC05] es un intérprete de bytecode (máquina virtual) que se ejecuta en
motas con TinyOS. Está inspirado en Active Messages y J-Machine, pero simplificado
debido a las restricciones de la plataforma objetivo. Define un juego de instrucciones que
permite especificar el comportamiento del nodo ante una serie de eventos predefinidos.
Dichos eventos están ligados a los sensores disponibles en la plataforma.
La máquina virtual se utiliza para conseguir instrucciones de mayor nivel de abstracción.
De ese modo, es posible describir comportamientos no triviales en programas muy cortos.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
55
Los programas se dividen en cápsulas de 24 instrucciones para que sea más sencillo
transmitirlos sobre los protocolos típicos en esta plataforma. Disponer de programas tan
cortos hace que el coste de las actualizaciones en términos de energía sea muy bajo.
Maté está diseñado bajo la presunción de que, dentro de un mismo dominio, las
aplicaciones están compuestas a partir de un conjunto cerrado de bloques funcionales,
de modo que únicamente la forma en la que se combinan determina la finalidad del
servicio o sub-sistema. El juego de instrucciones permite al programador definir hasta 8
instrucciones propias. Cada instrucción virtual se ejecuta como una tarea independiente
de TinyOS, por lo que los servicios propios del sistema operativo pueden funcionar de
forma concurrente a la ejecución de las instrucciones. El listado 2.4 muestra un programa
de ejemplo: en cada ciclo de reloj incrementa un contador y representa en los LED S
de la mota sus tres bits menos significativos.
pushc 1
add
copy
pushc 7
and
putled
halt
# Push one onto operand stack
# Add the one to the stored counter
# Copy the new counter value
# Take bottom three bits of copy
# Set the LEDs to these three bits
L ISTADO 2.4: Programa de ejemplo de Maté. (P. L EVIS [LC02])
Con esta filosofía es posible construir aplicaciones complejas como encaminamiento
ad hoc que pueden estar compuestas por varias cápsulas ocupando en total menos de 100
bytes. Aparte del bytecode, cada cápsula contiene un tipo y un número de versión. Existen
cuatro tipos: envío de mensaje, recepción de mensaje, de tiempo y de subrutina.
La máquina virtual emplea una pila para operandos, que es utilizada por la mayor
parte de las instrucciones. Una segunda pila almacena direcciones de retorno y la
utilizan las instrucciones de control de flujo. Además, algunas de las instrucciones
tienen operandos implícitos codificados con algunos de los bits del propio código de
instrucción. La máquina dispone de tres contextos de ejecución concurrentes para timeouts,
recepción y envío de mensajes.
Para el despliegue de código dispone de una instrucción para enviar la propia cápsula a
otra mota. Dicha instrucción se ocupa de los detalles necesarios para que sea encaminada
automáticamente.
El diseño de la ISA (Instruction Set Architecture) y la máquina virtual permiten
desplegar y ejecutar código con bajo consumo y alta seguridad. El sistema oculta la
asincronía de TinyOS de modo que el programador sólo tiene que ocuparse de la
coherencia secuencial de su programa.
Sin embargo, el diseño de Maté dificulta la posibilidad de incluir nuevas características
en los nodos y más aún si se trata de nuevas plataformas o arquitecturas. La asunción
de que todos los programas de un dominio emplean los mismos bloques funcionales
implica una baja flexibilidad en las posibilidades de adaptar Maté a entornos especializados
o dinámicos.
i
i
i
i
i
i
i
i
56
2. A NTECEDENTES
Tiene un gran acoplamiento con TinyOS y la plataforma, hasta el punto de que
realiza un direccionamiento predefinido de los sensores disponibles en el dispositivo
(por ejemplo, la lectura del sensor de luz es pushc 1; sense). No ofrece una abstracción
real sobre los dispositivos que propicie la elaboración de servicios de alto nivel ni
ofrece mecanismos para la integración de la red SAN en aplicaciones complejas o
que abarquen otras redes de sensores.
Además, la máquina virtual no permite modelar el protocolo de comunicaciones; los
programas escritos con bytecode especifican la funcionalidad del sirviente, es decir, cómo
se manejan los datos procedentes de los sensores, pero no se utiliza para describir los
sensores disponibles o sus tipos.
Según sus autores, Maté es sólo una arquitectura y un bytecode. El siguiente paso es
crear lenguajes de alto nivel y modelos de programación para el desarrollo de aplicaciones,
proporcionando un entorno de programación distintivo de TinyOS.
Agilla [FRL05] propone algunas mejoras sobre Maté, estableciendo procedimientos
más eficaces para despliegue de actualizaciones de código. Utiliza agentes que pueden
moverse de un nodo a otro evaluando el estado de la red.
Plataforma
Puede instalarse sobre las motas modelo MICA y Rene2. La tabla 2.5 muestra los
requerimientos de memoria para una aplicación patrón.
componente
Máquina virtual (Maté)
Network
Logger
Hardware
Boot/Scheduler
Total
código (bytes)
datos (bytes)
7 286
6 410
844
1 232
272
16 044
603
206
18
8
14
849
C UADRO 2.5: Maté: Requerimientos de memoria
2.5.6.
Magnet
Magnet [BBD+ 02] es un sistema adaptativo para redes ad hoc y redes de sensores.
Proporciona una máquina virtual Java que representa toda la red. Ofrece gran flexibilidad
al programador permitiéndole migrar objetos y decidir su localización.
Sus aplicaciones pueden verse como macro-programas, dado que se escribe un único
programa Java que se ejecuta sobre toda la red. El sistema se encarga de dividir y
distribuir el código y colocar los objetos en el lugar más adecuado. Es decir, lo más
cerca de los datos que consumen y con ello consigue reducir los recursos y energía
necesarios para las comunicaciones.
El hecho de utilizar Java simplifica su uso aunque también implica limitaciones en
cuanto a soporte de plataformas heterogéneas. En ese sentido, la JVM requiere demasiados
i
i
i
i
i
i
i
i
2. A NTECEDENTES
57
recursos de cómputo como para que se pueda ejecutar siquiera en la plataforma WSN
por excelencia: las motas.
2.5.7.
SensorWare
SensorWare [BHS03, BHSS07] es un framework muy enfocado al despliegue de
actualizaciones de software en redes WSN. Mediante un conjunto de servicios abstractos
y la ejecución de scripts de control que pueden ser instalados en los nodos puede definir
nuevos servicios de forma dinámica.
Su enfoque permite la agregación de los datos consultados como una base de datos
distribuida, pero no utiliza un lenguaje derivado de SQL. En su lugar utiliza scripts
T CL. Aplica la idea de sensores activos, es decir, que pueden reaccionar a distintos
tipos de eventos, no sólo a consultas recibidas de los clientes. Por tanto, se trata de
un sistema dirigido por eventos.
Su diseño considera que un algoritmo distribuido debe ser entendido como un conjunto
de programas que se ejecutan en nodos independientes y colaboran para realizar una tarea.
Todos los recursos del nodo (sensores, interfaz de comunicaciones, etc.) están disponibles
para estos scripts. Los clientes realizan consultas inyectando scripts de control en la
red, que se propagan a los nodos que lo requieran.
SensorWare está formado por dos componentes principales: un lenguaje y un entorno de
ejecución. Cada una de las instrucciones que forman el lenguaje abstrae una tarea concreta
en el nodo sensor, tal como la comunicación con otros nodos, la lectura de información de
los sensores, etc., aparte de instrucciones de control de flujo y sentencias condicionales
habituales en un lenguaje procedural. Éste está constituido por funciones T CL.
Para dar soporte a plataformas heterogéneas, se representan los dispositivos por medio
de una capa de abstracción de hardware que permite utilizarlos como dispositivos virtuales
(concepto extraído del kernel Linux). Existe una serie de primitivas que se implementan en
el driver de dispositivo y permiten añadir nuevos elementos al run-time de SensorWare.
Existen varios prototipos de implementación en torno a varios modelos de PDA S HP
iPAQ. El último de ellos [BHSS07] utiliza una iPAQ 3950 con procesador Intel XScale de
32 bits, 16 MiB de RAM y 64 MiB de Flash. El sistema operativo utilizado es Familiar
con Linux 2.4.18. También se ha portado a nodos Rockwell WINS, que disponen de
un procesador StrongARM y 1 MiB de Flash. Utiliza SO eCos y microC/OS-II. La
tabla 2.6 muestra los requisitos de memoria de un nodo SensorWare sobre HP iPAQ;
no incluye el código de drivers de dispositivo, timers, etc.
componente
Librerías
tinyTcl
SensorWare Core
Aplicación
Total
tamaño (KiB)
97
64
35
40
237
C UADRO 2.6: SensorWare: Requerimientos de memoria
i
i
i
i
i
i
i
i
58
2. A NTECEDENTES
2.5.8.
MiLAN
M I LAN (Middleware Linking Applications and Networks) [HMCP04] apuesta por un
modelo en el que las aplicaciones tienen un papel proactivo que influye directamente
en el comportamiento de la red y los nodos.
Asume que las aplicaciones para SAN están dirigidas a datos (data-driven). Las
aplicaciones recogen datos y estiman su calidad en función de las características de
los sensores utilizados, ruido, condiciones externas momentáneas, de contexto, etc.
Las aplicaciones tienen estado. Las necesidades de la aplicación cambian con el tiempo
o al recibir determinados datos de los sensores.
MiLAN permite a las aplicaciones especificar los necesidades de Q O S y ajustar
los parámetros de la red para conseguir su objetivo. Esos parámetros se obtienen
de tres fuentes:
Las necesidades que las aplicaciones demandan en términos de Q O S y la
especificación de alternativas para conseguirla a partir de distintos conjuntos de
sensores. Para ello, las aplicaciones disponen de unos grafos especiales en los que
describen cambios entre estados y los requerimientos necesarios en cada uno de
ellos.
La prioridad que cada aplicación tiene para el sistema en relación a las demás.
La disponibilidad de recursos (sensores), la autonomía con que cuentan, su ancho de
banda, etc.
A partir de estos datos, MiLAN adapta continuamente los parámetros de la red para
conseguir el mejor resultado global: qué sensores envían datos, cuáles tienen roles
especiales o pueden encaminar su tráfico de cierta manera, etc.
Su objetivo principal es maximizar la vida útil de la red SAN y de sus nodos cuando
éstos están alimentados con baterías. El sistema debe saber qué sensores están activos,
en qué tarea están implicados y cómo se relacionan con los demás desde el punto de
vista funcional y topológico.
Los diseñadores creen que el diseño de los middlewares suele considerar el uso
eficiente de la red, pero no las características y propiedades de la propia red. Arguyen
que actuar sobre los parámetros de la red puede mejorar la gestión de la energía de los
nodos y el desempeño de las aplicaciones. También creen importante dotar al sistema
de la flexibilidad suficiente como para dar soporte a requisitos de Q O S, arquitecturas
y protocolos de red diferentes.
Para lograr un control mucho más fino de los parámetros de la red, MiLAN actúa sobre
toda la pila de protocolos de red y no solo sobre la capa de transporte (ver figura 2.5). Para
ofrecer soporte para distintas tecnologías de red, incorpora una capa de abstracción. Por
medio de plugins convierte las primitivas de comunicaciones propias a las de cada uno de
los protocolos soportados. Dependiendo de la tecnología de red subyacente, puede actuar
sobre determinadas variables específicas a fin de lograr objetivos equivalentes.
Hace uso de un protocolo de descubrimiento de servicios que depende de la red
subyacente, puede usar SLP (Service Location Protocol) [VGPK97, GPVD99] de IETF
i
i
i
i
i
i
i
i
2. A NTECEDENTES
F IGURA 2.5: Relación de MiLAN
(H EINZELMAN [HMCP04])
59
con
las
capas
de
red
inferiores.
o SDP de BlueTooth. El SDP se utiliza para saber cuándo aparecen y desaparecen
nodos. Cuando un nodo deja de estar disponible se asume que su batería se ha agotado.
El SDP también es responsable de ofrecer información del nodo como la potencia a
la que puede transmitir, la autonomía que le queda o el tipo de información que sus
sensores pueden ofrecer.
Plataforma
Menciona su relación con las pilas de protocolos en redes BlueTooth e IEEE 802.11,
pero no se especifica con qué dispositivos o plataformas se ha probado.
2.5.9.
TinyCubus
TinyCubus [MLM+ 05] es otro middleware diseñado sobre TinyOS. Consiste en
tres partes principales:
Tiny Data management Framework
Proporciona un conjunto de componentes para manipulación de datos que cubren las
necesidades de acceso, replicación, agregación, etc. Este componente es responsable
de seleccionar la implementación adecuada en función de los requisitos del sistema.
Cubus hace referencia a un modelo de tres ejes ortogonales que representan
los parámetros de optimización, aplicación y sistema. Los algoritmos de cada
componente están clasificados en función de su peso en estos tres ejes de modo que
su importancia relativa determina su idoneidad para un objetivo o situación concreta.
Tiny Cross-layer Framework
Proporciona acceso a parámetros de los niveles de red inferiores para poder realizar
las optimizaciones necesarias en términos de rendimiento y ahorro de energía.
i
i
i
i
i
i
i
i
60
2. A NTECEDENTES
Dispone de un lenguaje de especificación para describir la información que puede
generar y consumir cada componente.
Para proporcionar información cross-layer, dispone de:
El repositorio de estado. Para evitar que cualquier componente acceda sin
control a cualquier otro componente o capa, la información se obtiene a través
de un elemento intermedio (el repositorio) que permite mantener desacoplados
los componentes.
Enlaces o retro-llamadas. Se encargan de la asociación entre los datos y los
componentes, de modo que pueden cambiar dinámicamente.
Tiny Configuration Engine
Es el componente encargado de instalar y distribuir código nuevo en la red de
sensores, normalmente para dar soporte a nuevos tipos de sensores, funciones de
agregación o requisitos de aplicación.
El gestor de topología se encarga de la configuración de la red y la asignación
de roles a los nodos en función de sus recursos de cómputo, situación
física y relación con los nodos próximos. Algunos roles son: SOURCE,
AGGREGATOR, SINK, GATEWAY, CLUSTERHEAD, VIBRATION, LIGHT,
etc.
La especificación de roles y el algoritmo de asignación de roles determina el
rol de cada nodo individual consultando una serie de reglas descritas con el
lenguaje de especificación. El algoritmo se ejecuta localmente en cada nodo.
La asignación de rol determina el código que será enviado e instalado en cada nodo.
Aunque la plataforma de prototipado y simulación es TinyOS/TOSSIM, los autores han
tenido en cuenta en su diseño la posibilidad de integrar dispositivos con cierto grado de
heterogeneidad, sobre todo, en lo referente al despliegue de código específico.
2.5.10.
Impala
Impala [LM03] se diseñó para cubrir las necesidades del proyecto ZebraNet [JOW+ 02,
LSZM04]. El objetivo de este proyecto es buscar soluciones para la instalación de sensores
en animales salvajes a fin de llevar a cabo tareas de control y observación. Los animales
pueden moverse libremente por amplias zonas geográficas sin ningún tipo de infraestructura
de comunicaciones. Por tanto, se caracteriza por una alta movilidad, toma continua de datos
y mayor potencia de transmisión que en otros escenarios. Los objetivos del middleware se
centran en la modularidad, facilidad en las actualizaciones, eficiencia en el consumo
de energía y fiabilidad del software.
Una de sus funciones más destacables y en la que más esfuerzo hicieron sus autores
es el despliegue de código a los nodos por medio de pequeñas actualizaciones. De ese
modo, se requiere poca potencia para la transmisión ayudando a mejorar la autonomía
de los dispositivos y la vida útil del sistema. Las aplicaciones son muy modulares y las
actualizaciones utilizan versionado y almacenamiento intermedio para que el sistema sea
robusto ante actualizaciones parciales o incompatibles. La aplicación sigue funcionado
mientras se recibe el nuevo código. Esto responde a un enfoque particular de su diseño
i
i
i
i
i
i
i
i
2. A NTECEDENTES
61
por el que se asume que un sistema de este tipo, incluso en explotación, sufrirá frecuentes
actualizaciones para afinar su funcionamiento.
Solo es posible ejecutar una aplicación en cada momento. El sistema dispone de un
algoritmo y una estructura de datos (Application Device Table) que determina cuál es la
siguiente aplicación a ejecutar en función de la disponibilidad de los datos requeridos o de
los sensores asociados. Los nodos pueden almacenar información de forma independiente
y la transmitirán hacia la estación base cuando la comunicación sea factible. En la capa
inferior (ver figura 2.6) existen tres componentes importantes:
Filtro de eventos
Se encarga de recibir y procesar eventos procedentes de los dispositivos y enviarlos
a otros módulos del sistema y a las aplicaciones. Existen cinco tipos de eventos:
de tiempo – Indican que expiró un temporizador. Hay tres tipos de eventos:
para la aplicación activa, el adaptador de aplicaciones y el actualizador de
aplicaciones.
de paquete – Indica que ha llegado un mensaje. Hay dos tipos: de aplicación a
aplicación y de actualizador a actualizador.
de datos – Indica a la aplicación activa que existe un sensor listo para ser leído.
de dispositivo – Indica al adaptador de aplicaciones que se ha detectado un fallo
en un dispositivo.
envío completado – Indica que se ha completado el envío de un mensaje.
El adaptador de aplicaciones
Los nodos pueden utilizar distintas aplicaciones para encaminar datos a la estación
base, dependiendo de condicionantes como el rendimiento, el ahorro de energía
u otros factores. La adaptación está soportada por el modelo de programación de
eventos de Impala. La adaptación ocurre como respuesta a los distintos tipos de
eventos.
El actualizador de aplicaciones
Las actualizaciones en Impala tienen algunas peculiaridades: alta movilidad de los
nodos, bajo ancho de banda que se debe compartir con la transmisión de datos de
los sensores y actualizaciones de distinta consideración, desde parches a cambios
completos en las aplicaciones.
Debido a ello, las actualizaciones deben afrontar varios problemas: actualizaciones
parciales debido a cortes en las comunicaciones, procesos de ejecución y
actualización simultánea, actualizaciones procedentes de varios orígenes y gestión
de la memoria, cada nodo puede contener código de cuatro aplicaciones a la vez.
Los módulos tienen un número de versión asignado. Solo se transmite un módulo
cuando el receptor confirma que la versión instalada es más antigua. Aunque se
despliegan como binarios, el actualizador es el encargado de enlazar los módulos a
la aplicación. No se permiten las dependencias entre éstos. Cuando se dispone de
todos los módulos, el nodo procede a su enlace en la aplicación.
i
i
i
i
i
i
i
i
62
2. A NTECEDENTES
F IGURA 2.6: Arquitectura de capas de Impala. (Ting L IU [LSZM04])
Plataforma
Los módulos Application Adapter y Application Updater se ejecutan en una PDA
HP iPAQ con CPU a 266 MHz, 32 MB de RAM y 16 MB de Flash para el sistema de
ficheros. Utilizan el sistema operativo Linux Familiar 5.2.
Los módulos Operation Scheduler, Event Filter y Network support se ejecutan en
nodos ZebraNet (ver figura 2.7). Este dispositivo dispone de un microcontrolador TI
MSP430F149 RISC de 16 bits con 2 KiB de RAM y 60 KiB de ROM, con un reloj
dual de 8 MHz/32 KHz.
Para las comunicaciones utiliza un módulo de radio MaxStream 9Xstream a 902928MHz que permite una tasa 19,2Kbps en campo abierto con un alcance de entre
media y una milla.
Para el almacenamiento de datos en modo desconectado utiliza una memoria Flash
ATMEL AT45DB041B de 4 MiB, que le permite almacenar datos durante 78 días. Para
la localización utiliza un GPS µblox GPS-MS1E.
Los cuatro módulos se comunican mediante un bus SPI a 667 Kbps y USART
a 38,4 Kbps.
Los requisitos de memoria para la aplicación prototipada se muestran en la tabla 2.7.
Como prototipo se hizo un despliegue montando nodos zebranet en collares que se
colocaron a 7 cebras que vivían en libertad en una reserva natural de Kenia durante
enero de 2004.
Se trata de un middleware confiable y con un sistema de actualizaciones eficiente
desde el punto de vista energético. Sin embargo, es una solución muy especializada que
no contempla aspectos generales de la problemática de las WSN como, por ejemplo, la
i
i
i
i
i
i
i
i
2. A NTECEDENTES
63
componente
tamaño
firmware
Impala
Aplicación
RAM
10 KiB
7 KiB
1 KiB
650 B
C UADRO 2.7: Impala: Requerimientos de memoria
(a)
(b)
F IGURA 2.7: Diagrama de bloques (a) y aspecto físico (b) del nodo ZebraNet. (Ting
L IU [LSZM04])
limitación de ejecutar una única aplicación. Difícilmente es aplicable o portable a otros
entornos, plataformas o aplicaciones fuera del ámbito de estudio.
2.5.11.
TinyLime
TinyLime [CGG+ 05] al igual que los sistemas de base de datos virtual, dispone de
un lenguaje de consulta, pero su modelo de datos es un espacio de tuplas [Gel85] que
funciona como una especie de memoria compartida. Una tupla es una lista de valores
que puede ser creada o accedida por las aplicaciones.
TinyLime es un trabajo derivado de LIME (Linda in Mobile Environments). Las
tuplas las almacena temporalmente cada nodo de la red y pueden ser consultadas por
sus vecinos. Por tanto, la información es generada y consultada de forma asíncrona
puesto que no se requiere que dichas operaciones ocurran en el mismo momento y lugar.
El mecanismo de suscripción de las aplicaciones depende de plantillas que especifican
cuáles son los datos de interés. Estas plantillas deben tener el mismo formato que utilizan
las tuplas de los sensores y pueden incluir condicionantes de dicha suscripción, tales
como la frecuencia de actualización.
i
i
i
i
i
i
i
i
64
2. A NTECEDENTES
Para que la información esté disponible para las aplicaciones del exterior, se representa
cada sensor de la red por medio de un agente LIME alojado en la pasarela. Ese
agente se encarga de recoger información procedente del sensor y representarla en
el espacio de tuplas.
Funciona sobre TinyOS en la plataforma de sensores Crossbow Mote. La implementación aporta por defecto la especificación del formato de tuplas para los sensores habituales en dicha plataforma.
2.5.12.
EnviroTrack
EnviroTrack [Abd04] es un middleware distribuido basado en objetos que persigue
dos objetivos principales: la gestión eficiente de grupos por medio de objetos lógicos,
y el seguimiento (tracking) de entidades del entorno físico.
El tracked object es una abstracción que se puede instanciar dinámicamente y que
permite obtener datos relativos a un fenómeno u objeto físico, tal como un vehículo o un
incendio. El middleware se encarga de recoger toda la información relativa al fenómeno
físico y presentarla al programador de la aplicación por medio de una interfaz única,
aunque provenga de varios sensores o se mueva a través de la red. Eso significa que,
dinámicamente, se crean grupos de sensores en torno a los fenómenos observados.
EnviroTrack se basa en un concepto llamada estado agregado aproximado (approximate
aggregate state). Se trata de una función que permite obtener un dato como resultado de la
agregación del estado de los sensores que forman un grupo (por ejemplo, la media).
La peculiaridad es que el grupo se define automáticamente por aquellos nodos que
satisfacen un predicado dado (p.ej. umbral de temperatura) en un instante t. Como
esta información no puede ser calculada y transmitida de forma instantánea, se define
una ventana de tiempo para realizar la agregación. Por último, se precisa un número
mínimo de sensores (masa crítica) para que el fenómeno sea tomado en consideración. Por
ejemplo, se considera que existe fuego si al menos 5 sensores detectan alta temperatura
en un plazo de 3 segundos en la misma zona. Estos condicionantes son considerados
restricciones de Q O S en la detección de fuego.
Por último, una abstracción denominada etiqueta de contexto (context label) realiza el
seguimiento sobre la entidad del entorno y mantiene el valor agregado. La etiqueta de
contexto es un sistema de direccionamiento de nodos basado en atributos similar al de otros
desarrollos; sin embargo, en este caso es posible asociar objetos (tracking objects) que
pueden realizar trabajos sobre el contexto (los nodos relacionados con el fenómeno).
Plataforma
El entorno de programación de EnviroTrack está formado por cuatro elementos:
Un preprocesador que transforma declaraciones EnviroTrack en código nesC que
se encarga de materializar la gestión de grupos, la agregación de datos y las
comunicaciones.
Un protocolo de gestión de grupos que utiliza las etiquetas de contexto para tomar
las decisiones de membresía.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
65
Servicios de directorio y direccionamiento de objetos, que mantiene una lista de
objetos activos y su posición.
El servicio de transporte y comunicación por medio de RMI.
El sistema se ha probado con motas MICA2 utilizando TinyOS. No se facilitan
datos precisos sobre los recursos de cómputo necesarios, cuáles de los componentes
citados se alojan en las motas y cuáles fuera, dónde se ejecutan las aplicaciones o
cómo se comunican con la WSN.
2.5.13.
Kairos
Kairos [GGG05] es un ejemplo claro de macro-programación. Su objetivo es dar al
programador la capacidad de expresar el comportamiento global de toda una red de sensores
proporcionando un único programa con instrucciones de alto nivel.
Ese programa se compila, generando código específico que se distribuye después
a cada nodo. Todo ese proceso es transparente al programador. Para ello ofrece un
lenguaje con las siguientes abstracciones:
El nodo permite al programador hacer referencia a un nodo o conjunto de ellos. Los
nodos se direccionan utilizando números enteros como identificadores.
El vecino es un nodo directamente alcanzable desde otro dado. Como en otros
middlewares, es posible obtener la lista de vecinos e iterar sobre ellos para realizar
operaciones relacionadas con el encaminamiento y la topología.
El acceso remoto a datos permite acceder remotamente al valor de cualquier variable
del nodo, siempre que tenga sentido fuera de él.
Los nodos mantienen copias en caché de las variables remotas por lo que se hace
necesario un mecanismo de sincronización. No es posible modificar variables remotas,
por lo que no se plantean problemas de acceso concurrente.
Kairos asume que las aplicaciones pueden funcionar adecuadamente empleando un
sistema de sincronización débil (loose). Significa que la lectura de una variable remota
se bloquea únicamente cuando se obtiene la referencia y no en cada lectura de la
variable. Así se consigue menor sobrecarga de comunicaciones aunque puedan aparecer
inconsistencias entre los valores reales de las variables y sus cachés. En los casos en que
este tipo de inconsistencia sea intolerable, Kairos proporciona una sincronización más
estricta (loop-level) entre las variables en cada iteración del bucle en lugar de utilizar
sólo el valor almacenado localmente.
Aunque no se aportan datos sobre los requerimientos de cómputo de Kairos, a la
vista de los prototipos utilizados, parece claro que no es viable su instalación en los
dispositivos de la SAN propiamente dichos.
Plataforma
Los autores describen una plataforma de evaluación consistente en una red híbrida
formada por 16 Stargate’s que ejecutan Kairos.
i
i
i
i
i
i
i
i
66
2. A NTECEDENTES
Stargate [Sta] es un dispositivo de la empresa Crossbow. Cuenta con un procesador Intel
PXA255 (XScale) y 64 MiB de RAM. Ejecuta una versión empotrada de Linux y se puede
conectar a varios modelos de motas como IRIS, MICAz, etc., y otros periféricos.
Kairos utiliza Emstar [GES+ 04] para implementar el encaminamiento y la gestión de la
topología. Emstar usa una mota MICA2 conectada al Stargate como interfaz de red. Las
motas ejecutan TinyOS. Es decir, cada nodo es una combinación de una mota MICA2
conectada a un Stargate (ver figura 2.8), que ejecuta Linux con Emstar y Kairos.
F IGURA 2.8: Combinación de Stargate y mota MICA2 usada en un prototipo de Kairos
Otro despliegue utiliza 8 MICA2DOT conectadas por un puerto serie a un PC estándar
que ejecuta un proceso Emstar y un proceso Kairos para cada una.
2.5.14.
WSP
Otra propuesta bastante reciente [BLV09], relacionada con el proyecto WASP (Wirelessly
Accessible Sensor Populations) [WAS], pretende desarrollar un modelo de programación
para WSN heterogéneas utilizando un enfoque basado en eventos. Se trata de mensajes
auto-contenidos, que incluyen una función global y una lista de argumentos. Se trata de
una propuesta similar a SensorScheme [EHK+ 07] o Active Messages [VECGS92].
Cada tipo de mensaje tiene un manejador asociado y su procesamiento no requiere
de nuevas comunicaciones. Los mensajes incluyen campos con información de Q O S
tales como prioridad, plazo, fiabilidad requerida, etc. Todos los mensajes incluyen
además un identificador de aplicación para agrupar manejadores y gestionar la versión
del protocolo.
El objetivo de estos mensajes es doble: aplicar optimizaciones cross-layer, y adaptar
la complejidad y tamaño del mensaje a las necesidades concretas. Los mensajes se
pueden encapsular en cualquier capa que permita transporte de mensajes aunque la
preferencia es utilizar la capa más baja posible. En las implementaciones se encapsula
sobre IEEE802.15.4.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
67
Cada nodo de la red expone una serie de servicios. Cada uno de ellos contiene
un conjunto de generadores de eventos, manejadores y suscripciones. La figura 2.9
muestra el diagrama de bloques de un nodo, en el que se representan las relaciones
entre los elementos citados.
F IGURA 2.9: Estructura de un nodo WSP. (Remi B OSMAN [BLV09])
La aplicación determina los servicios y las suscripciones. Desde la perspectiva de
un nodo, una suscripción es una conexión lógica entre un evento local y un manejador
remoto. Los generadores de eventos son tuplas condición-acción de modo que se envía
un mensaje cuando se produce una condición dada.
Las funciones de un servicio se ejecutan en un contexto dado. Se definen cuatro
contextos:
Gcontext – Es una lista de todas las variables y contantes disponibles globalmente.
Incluye primitivas del SO como, por ejemplo, la lectura de sensores.
Ncontext – Variables locales al servicio.
Mcontext – Manejadores del servicio.
Scontext – La información proporcionada por un suscriptor para los generadores de
eventos. Por ejemplo, umbrales para el disparo de eventos.
Utiliza Content-Based Addresses (CBA) con dos propósitos: establecer servicios en
los nodos y para la suscripción de manejadores a generadores de eventos. Una CBA
es una expresión que puede ser evaluada por el nodo remoto. Cuando se solicita una
suscripción se especifica una de estas expresiones y un conjunto de características de
Q O S. El establecimiento de servicios se realiza por medio de un mensaje especial cuyos
argumentos son instrucciones de una pequeña máquina virtual (de 6 instrucciones). Este
lenguaje se usa para definir CBA S, declarar variables en el Gcontext y definir manejadores
y generadores de eventos en el nodo.
Se trata de un sistema de macro-programación que genera bytecode para una máquina
virtual (basada en pila) que se ejecuta en cada nodo. El lenguaje de macro-programación
i
i
i
i
i
i
i
i
68
2. A NTECEDENTES
(llamado Network Programming Language) intenta reducir el salto de abstracción que hay
entre la descripción del escenario y el código que se ejecuta realmente en los nodos.
El conjunto de standard handlers es la definición de la interfaz remota del nodo, de modo
que los servicios del nodo quedan determinados por diseño. Tiene manejadores específicos
para el establecer rutas, encaminar mensajes, pedir suscripciones, fijar la potencia de
transmisión, encender/apagar LED S, etc., hasta un total de 27 funciones; todo ello sin
una diferenciación conceptual o definición de roles.
Define abstracciones que tienen claros equivalentes en la OO y que podrían ser
empleados o adaptados para representar los mismos conceptos y restricciones, con la
consiguiente simplificación en la especificación y nomenclatura.
Plataforma
No se aporta información sobre un despliegue en dispositivos físicos, aunque sí
aparece una tabla con los requisitos de memoria de la implementación de la máquina
virtual (ver 2.8).
componente
SO
VM
Llamadas al sistema
Total
ROM (bytes)
RAM (bytes)
24 084
1 664
1 530
27 278
1 191
20
146
1 357
C UADRO 2.8: WSP: Requerimientos de memoria
2.5.15.
C OPRA
C OPRA [KN06] (parte del proyecto C OCOS) no es un middleware como los anteriores. Se
trata de una arquitectura para el diseño e implementación de protocolos de comunicaciones
para dispositivos de escasos recursos.
Plantea como principio de diseño que utilizar un protocolo o middleware genérico
para una red SAN siempre resulta ineficiente, dado que al no estar optimizados para
hardware específico, supone un gasto de recursos innecesario. Otro problema añadido
es que al utilizar transductores de radio muy simples, la CPU debe encargarse de tareas
como el control de acceso al medio o el direccionamiento, que normalmente haría la
interfaz de red [KKKP99].
C OPRA define una biblioteca de PPS (Protocol Precessing Engines), que son
componentes simples que pueden ser ensamblados para crear protocolos de comunicaciones
dependientes de aplicación llamados Protocol Processing Stagess (PPE S), curiosamente se
trata de una solución prácticamente opuesta al principio de W HITE [Whi75]. El PPE es
una cadena de PPS u otros PPE en el que cada uno de ellos tiene un puntero al siguiente,
de modo que los datos procedentes del dispositivo de radio o la aplicación atraviesan toda
la cadena. Utilizar una cadena de invocaciones explícitas a través de la cadena implica
copiar el mensaje con el consiguiente gasto en tiempo y memoria.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
69
Por ejemplo, I MPACT [BKN07] es un protocolo muy interesante construido sobre
C OPRA. I MPACT aprovecha los enlaces inalámbricos característicos de las WSN para
evitar enviar reconocimientos. Cuando un nodo reenvía un mensaje hacia su destino, el
nodo anterior también lo recibe, de ese modo puede comprobar que el mensaje le llegó
correctamente haciendo innecesario un mensaje de reconocimiento explícito y ahorrando
así una importante cantidad de energía. Prevé casos especiales en los que sí hay que enviar
ese reconocimiento, por ejemplo en los enlaces asimétricos (unidireccionales) o en el
caso del nodo destino, que no reenvía el mensaje a nadie.
2.6.
Encaminamiento en redes heterogéneas
La interconexión de redes heterogéneas (de diferente tecnología) es la esencia misma
de cualquier protocolo de red, pero existen otras soluciones, parciales quizá, al mismo
problema. El objetivo de una inter-red es poder intercambiar datos —en los niveles
superiores— entre hosts que disponen de interfaces de comunicaciones incompatibles
o que requieren la utilización de una o varias redes intermedias debido a la distancia
física que las separa.
Aunque es posible tratar el problema de la interconexión desde un punto de vista
generalista, en esta sección se trata dentro del contexto que nos ocupa, es decir,
conectar redes de sensores entre sí y a la infraestructura de comunicaciones del SI,
y potencialmente a Internet.
En la línea de lo que apunta S ENNER [SKLN08], la interconexión de redes heterogéneas
se puede lograr de cuatro maneras diferentes, que se detallan a continuación.
2.6.1.
Protocolo de red universal
Se trata de un único protocolo que deben adoptar obligatoriamente todos los nodos
de todas las redes que se pretende comunicar entre sí. Esta solución implica también la
definición de un sistema de direccionamiento universal que garantice que cada nodo de la
red tiene una dirección única. Se trata, por supuesto, de la solución adoptada en Internet
gracias a IP. Entre las muchas ventajas de esta solución, existe la de poder establecer islas
que pueden tener incluso sus propios protocolos de encaminamiento dinámico (llamadas
Sistema Autónomo (SA) en la terminología de TCP/IP).
Dado que es muy probable que en algún momento se necesite conectar cualquier
red imaginable a Internet, la solución obvia parece que es utilizar IP en absolutamente
cualquier dispositivo. Propuestas como uIP [DAV04] van en esta línea.
Emplear un protocolo de red idéntico en todos los nodos simplifica significativamente
el proceso de encaminamiento y reenvío de paquetes. Los encaminadores realizan la
misma tarea y con los mismos condicionantes en cualquier parte de la inter-red. No tienen
estado y no necesitan modificar los paquetes transmitidos, a excepción de campos de
control sencillos como el caso del TTL. Otra cuestión es el protocolo de encaminamiento
dinámico que puede ser muy distinto dependiendo del ámbito, como ocurre por ejemplo
en las Mobile Ad-hoc Network (MANET).
i
i
i
i
i
i
i
i
70
2. A NTECEDENTES
Sin embargo, IP no se adapta bien a muchas particularidades específicas de ciertas
redes o dispositivos (como es el caso de las WSN), no solo por los requisitos de cómputo
necesarios, también por la necesidad de protocolos de transporte que por diseño resultan
inadecuados. Por ejemplo, en un enlace inalámbrico, lo habitual es introducir información
redundante que permita recuperar los datos que se pierden debido a los frecuentes errores.
Por el contrario, TCP reacciona reduciendo la tasa de salida asumiendo que es un problema
de congestión [HV99]. Otros problemas están relacionados con las grandes diferencias en
la MTU, uno de los problemas que trata de resolver 6L OWPAN [MKHC07, KMS07].
Para lograr un desempeño aceptable de TCP/IP en nodos limitados habitualmente
son necesarias adaptaciones como compresión de cabeceras [Dun03], modificaciones en
la encapsulación de los paquetes, direccionamiento, etc. Este tipo de «optimizaciones»
implican cambios en el formato de las cabeceras que es precisamente una de las
consecuencias que se pretendía evitar utilizando un protocolo de red homogéneo.
Respetar el protocolo que el fabricante utiliza en sus nodos puede tener ventajas que no
resultan compensadas al intentar aplicar TCP/IP sobre ellos, además de simplificar su uso
puesto que podemos contar con las herramientas que proporciona el fabricante.
Además, existe una gran cantidad de trabajo [AY05, CSAT06] en relación al
encaminamiento para redes WSN con propuestas que tratan de mejorar el consumo
energético, utilizando información geográfica, creando un árbol basado en clusters o
presuponiendo la existencia de enlaces unidireccionales. Algunos de esos protocolos
utilizan atajos (cross-layer) o tienen un diseño tan peculiar como SPIN [HKB99] o
Directed Diffusion [IGE00] que utiliza un encaminamiento orientado a datos, es decir,
los sensores no tienen direcciones únicas. Estos modelos plantean serias dificultades si
se pretende adaptarlos a los parámetros clásicos de los protocolos de encaminamiento
que se emplean en IP.
Encaminamiento de mensajes en CORBA
Los mismos problemas que se pretende resolver con un direccionamiento y un protocolo
de red común pueden ser atacados a otro nivel. CORBA y, en general cualquier middleware
orientado a objetos, dispone de alguna entidad lógica para direccionar unívocamente
cualquier objeto dentro del sistema distribuido, ya sea de forma directa o indirecta.
Como vimos en la sección 2.3.3, la referencia al objeto (IOR) incluye la información
necesaria para contactar con el adaptador que sirve el objeto destino. La referencia está
compuesta de perfiles etiquetados; toda IOR tiene al menos uno.
Existe un gran número de perfiles de IOR predefinidos. Entre ellos, el más
común es TAG_INTERNET_IOP que corresponde con referencias que se resuelven por
medio de IIOP. Uno de ellos resulta especialmente interesante para el tema que
nos ocupa. Se trata de TAG_MESSAGE_ROUTERS, lo que nos lleva al capítulo «CORBA
Messaging» [Obj08b] de la especificación y concretamente a la sección titulada «Message
Routing Interoperability».
Tanto AMI como la entrega de invocaciones no dependientes del tiempo, es decir,
aquellas que pueden llegar a entregarse aunque el destino no estuviera disponible en el
momento de producirse la invocación, no pueden ser efectuadas con una comunicación
GIOP síncrona.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
71
Este tipo de invocaciones (y sus respuestas) son reenviadas a través de una serie de
agentes (o encaminadores) hasta alcanzar su destino. El último encaminador (el más
cercano al servidor, en términos de coste) efectúa la invocación como si fuera el cliente,
recoge la respuesta y la envía de vuelta al cliente como una nueva invocación empleando la
referencia de un objeto callback. Dicho objeto debe implementar la interfaz ReplyHandler
y lo puede aportar el cliente o, en su defecto, el primer encaminador (el situado más cerca
del cliente). El proceso de una invocación completa se ilustra en la figura 2.10.
F IGURA 2.10: Encaminamiento de mensajes CORBA [Obj08b]
La principal utilidad de este sistema de encaminamiento es permitir que los servidores
puedan especificar otros destinos alternativos cuando el nodo final pueda no estar disponible
durante largos períodos de tiempo. Esos destinos alternativos son encaminadores. El
objeto especifica la lista de referencias a esos encaminadores como un componente
de su propia IOR. El identificador de ese perfil es TAG_MESSAGE_ROUTERS, al que nos
referíamos anteriormente.
La tarea del encaminador consiste en reenviar la invocación al siguiente que aparece en
la lista o, si le es posible, efectuar la invocación sobre el servidor. El mensaje que se reenvía
a través de los encaminadores contiene una invocación estándar para el objeto destino
además de la información necesaria para el proceso de encaminamiento, que incluye:
La lista de encaminadores visitados.
La lista de encaminadores por visitar (los que aparecen en la IOR del objeto destino).
La referencia al objeto destino.
La referencia al objeto que ha de recibir la respuesta.
Una secuencia de descriptores de Q O S.
El propio encaminador es también un objeto CORBA; estos mensajes se codifican
usando GIOP y se envían como parámetros de las operaciones de la interfaz implementada
por el encaminador (MessageRouting::Router). Cada encaminador reenvía el mensaje al
siguiente utilizando esa misma interfaz, o bien al objeto destino si está accesible.
i
i
i
i
i
i
i
i
72
2. A NTECEDENTES
Aunque se han indicado varios roles para los encaminadores (primero, último e
intermedios), realmente un mismo proceso puede implementar varios de ellos, y es posible
incluso que el cliente o el objeto destino dispongan de encaminadores co-localizados.
Cuando el cliente no puede invocar directamente al objeto destino, por no estar accesible
mediante un protocolo síncrono, el ORB cliente intenta contactar con el primer encaminador.
Si la IOR del objeto destino tiene un componente TAG_MESSAGE_ROUTERS, el ORB utiliza
las referencias de la lista que contiene, empezando por la última, que debe ser la más
cercana al objeto destino. Si no puede contactar con ninguno de los encaminadores de la
lista, o la IOR destino no tiene dicho componente, el ORB cliente utiliza el encaminador
por defecto más cercano al destino.
El cliente puede decidir entre dos alternativas para realizar la invocación sobre el
primer encaminador:
Modelo de objeto callback – El cliente crea y sirve un objeto que implementa la
interfaz ReplyHandler y le pasa la referencia al primer encaminador. Esta referencia
será utilizada por el último encaminador para enviar la respuesta de la invocación
como otra invocación a ese objeto.
Modelo polling – En este caso no es el cliente, es el primer encaminador el que crea
el objeto para recepción de la respuesta. Lo hace a petición del cliente a través de
su interfaz PersistentRequestRouter mediante la operación create_persistent_request que le devuelve una referencia al objeto alojado en el primer encaminador.
Posteriormente, el cliente puede invocar las operaciones get_reply() o get_reply_with_context() para averiguar si la respuesta está disponible y obtener el
resultado cuando suceda.
La especificación incluye una interfaz para interacción entre encaminadores (RouterAdmin) para evitar tráfico de red innecesario. Cuando un encaminador es contactado por
otro que no conoce, se registra en él y le da instrucciones que debe usar si en el futuro no
puede contactarle. Esta información dice durante cuánto tiempo puede seguir intentando
contactar antes de declararlo inactivo, el intervalo de tiempo entre reintentos, la progresión
con la que crece ese intervalo, su valor máximo, etc.
Cada encaminador dispone de una lista en la que aparecen otros encaminadores
registrados de este modo y si están activos o no. Si un encaminador recibe mensajes
que solo pueden ser entregados a través de otro inactivo, puede almacenarlos y esperar
a que vuelva a estar activo. Así se consigue un sistema de transporte de mensajes con
características típicas de una Delay Tolerant Network (DTN).
Aunque se trata de un sistema de encaminamiento de invocaciones muy potente, su
uso está orientado a un problema bastante particular: la imposibilidad de realizar una
comunicación síncrona entre cliente y objeto destino. La selección de rutas se basa
en información contenida en las referencias almacenadas en los propios mensajes, no
hay tablas de encaminamiento. No proporciona mecanismos para descubrimiento de
rutas o vecinos ni ningún otro equivalente funcional a un protocolo de encaminamiento
dinámico. La lista de encaminadores que aparece en la referencia del objeto es una
forma de aumentar las posibilidades de recibir mensajes, nombrando otros objetos (los
i
i
i
i
i
i
i
i
2. A NTECEDENTES
73
encaminadores) que pueden redirigírselos. Tampoco prevé transporte de invocaciones
multi-destino ni esquemas de direccionamiento adecuados para ello.
2.6.2.
Pasarelas
La principal ventaja de usar pasarelas9 es que permite que cada red tenga su propio
esquema de direccionamiento, delegando en ellas la traducción de protocolos. Ésta puede
ser una solución aceptable cuando hay muy pocos sistemas distintos y para una aplicación
acotada. Aun así la ausencia de un esquema de direcciones global implica importantes
problemas que se comentan a continuación.
Direccionar nodos de una red desde otra diferente implica conocer los esquemas de
direccionamiento ajenos.
Como lo anterior resulta prácticamente inviable, en la mayoría de los casos se
opta por instalar delegados (representantes) de cada nodo en las pasarelas para la
conversión de direcciones.
Esto es lo habitual en las redes SAN por medio de las llamadas estaciones base.
El problema es que estos delegados suelen funcionar sólo en un sentido. Se puede
acceder a los nodos de la SAN desde la red troncal pero no a la inversa.
Los clientes realizan peticiones sobre la pasarela utilizando un protocolo como
TCP/IP. El software presente en la pasarela se ocupa de hacer llegar la petición hasta
el nodo y recoger la respuesta utilizando el protocolo específico de la red en cuestión
(ver figura 2.11).
La conversión de direcciones requiere disponer de un sistema de equivalencia uno a
uno entre ambos esquemas de direccionamiento o bien que la pasarela conozca, bien
de antemano bien dinámicamente, las direcciones de los nodos de la SAN.
Resulta difícil comunicar dos redes distantes iguales a través de una diferente debido
a que todas las redes que utilizan el mismo esquema de direccionamiento deben estar
coordinadas para evitar conflictos; se hace necesario un sistema de encaminamiento
que permita saber a qué red se debe enviar cada mensaje normalmente utilizando
técnicas de tunneling.
Resulta especialmente complicado instalar varias pasarelas en una misma red dado
que todas deberían tener una copia de todos los delegados con el consiguiente
problema de coordinación que plantea. Pueden surgir problemas de ambigüedad en
la semántica de acceso o bucles en la entrega de mensajes.
Utilizar sólo una pasarela supone admitir un único punto de fallo, y
Cuando se emplean protocolos ad hoc en redes inalámbricas ocurre que los nodos
cercanos a la pasarela consumirán mucha más energía que los demás dado que deben
encaminar los mensajes de toda la red. La consecuencia es que una vez agotada
la energía de estos nodos, la red queda incomunicada y potencialmente inservible.
Existen algunos trabajos que tratan de evitar estos problemas [PH08].
Las pasarelas son elementos explícitos del sistema. Con frecuencia el programador
debe ser consciente de la existencia de la pasarela. Para solicitar un servicio a un
9 Denominadas
habitualmente sink en la bibliografía sobre SAN.
i
i
i
i
i
i
i
i
74
2. A NTECEDENTES
nodo de la SAN debe indicar la dirección de la pasarela en lugar de la dirección o
identificador del sensor que realmente le interesa. Esto contrasta fuertemente con los
encaminadores de la alternativa anterior, que normalmente son transparentes para
las aplicaciones.
Pérdida de autonomía. Los nodos de la red SAN no pueden interactuar directamente
con elementos externos y por eso resulta complicado que puedan ofrecer y, sobre
todo, demandar servicios a dispositivos que están en una red SAN diferente.
F IGURA 2.11: Red SAN con una pasarela explícita
A pesar de todos esos problemas, estas pasarelas inteligentes (smart gateways) son la
principal solución de conectividad para la aplastante mayoría de middlewares y protocolos
de comunicaciones para redes de dispositivos de todo tipo, incluyendo sistemas domóticos,
entornos inteligentes, de control de procesos, etc.
Las razones para adoptar esta solución a pesar de los inconvenientes tienen mucho
que ver con la reducción de complejidad que supone para los nodos sensores. En los
middlewares de redes de sensores orientados a base de datos [SJS01, LLS+ 03, MFHH05,
YG02, BHSS07], el procesamiento de las consultas suele hacerse en la pasarela mientras
que la recolección de información suele tener poco que ver con la forma en la que se
presentan los datos al cliente. A veces, la consulta no se produce de forma síncrona; se
ofrecen datos recopilados durante instantes previos que se encuentran almacenados en
la pasarela. En ocasiones, servicios o módulos importantes del middleware residen en
la pasarela como Impala [LM03] o Kairos [GGG05].
También es el caso de STI [Obj03], en el que la pasarela se encarga de que un conjunto
de dispositivos simples sean vistos desde la red como si fuesen objetos distribuidos,
aunque las comunicaciones entre la pasarela y dichos dispositivos utilizan un protocolo
mucho más simple.
Arquitectura de interoperabilidad de CORBA
El problema de la integración de redes también se da a nivel del middleware. En
esta situación, se suele hablar de dominios, un concepto más general que además de las
incompatibilidades debidas a protocolos o tecnologías de red pueden deberse a aspectos
de más alto nivel como seguridad, cifrado, políticas administrativas, etc.
La «ORB Interoperability Architecture» [Obj08a] de la especificación CORBA trata
en detalle todos los aspectos relacionados con el transporte de mensajes entre dominios.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
75
La correspondencia (mapping) se basa en el uso de puentes (bridges) en un sentido
amplio10 . Se exponen dos posibles enfoques:
Mediated bridging – La transformación entre elementos de ambos dominios se realiza
a una tercera forma común. Esa forma no tiene porqué ser universal, puede depender
del sistema para así conseguir una solución óptima.
Immediate bridging – La transformación se realiza desde el dominio origen directamente al formato del dominio destino. Es una solución más eficiente que la anterior,
pero menos general y flexible.
Uno de los aspectos más interesantes es el direccionamiento, que en el caso de
CORBA se aplica a los objetos (mediante las referencias). Cada perfil de una referencia
a objeto (la IOR) identifica uno o más protocolos y los detalles para conectar con un
adaptador remoto, eso incluye la dirección de red del host, puertos, etc. Es posible que
el direccionamiento utilizado en un dominio no sea aplicable en otros, por lo que es
necesario realizar algún tipo de transformación.
Nótese que las referencias a objetos no solo se utilizan para dirigir un mensaje hacia
su destino. Se pueden obtener en los parámetros de retorno de una operación, como
ocurre con el servicio de nombres. También se utilizan habitualmente para enviar object
callbacks de modo que el destinatario disponga de una referencia al objeto responsable
del mensaje original o un tercero. Es decir, la transformación de referencias afecta al
contenido de la invocación además de a su cabecera.
La sección «Object addressing» explica diferentes esquemas posibles para traducir
referencias a objetos en los puentes.
Object Reference Translation Reference Embedding – El puente almacena la referencia recibida y genera otra completamente nueva que identifica el objeto en el otro
dominio. El puente se encarga de gestionar las referencias almacenadas de modo
que para cada referencia «puenteada» se pueda referenciar el objeto en el dominio
original.
Reference Encapsulation – El puente no almacena estado. Lo que hace es concatenar
un identificador del nuevo dominio en el nombre del objeto. En una invocación, se
asume que la referencia ya dispone de un identificador encapsulado en el dominio
destino y, en ese caso, el puente elimina el identificador del dominio origen.
Domain Reference Translation – El estado almacenado en el puente (un identificador
de la ruta basado en el dominio) puede ser compartido por varias referencias. En
cada una de ellas se incluye únicamente ese identificador.
Reference Canonicalization – Es similar al anterior, pero utiliza identificadores de
dominio globales en lugar de codificar una ruta.
Cada alternativa presenta ventajas e inconvenientes. Un problema importante que
afecta a la escalabilidad es la necesidad de almacenar estado en los puentes, ya sean
10 Se
respeta aquí el término «puente» sobre «pasarela» utilizado en el resto del texto.
i
i
i
i
i
i
i
i
76
2. A NTECEDENTES
referencias a los objetos en el dominio origen o identificadores con la ruta al dominio de
partida. Cuando se encapsulan referencias o se añade información extra al atravesar
un puente puede ocurrir que los mensajes crezcan dado que las referencias pueden
tener tamaños realmente considerables.
Este tipo de interconexión de dominios no está basado en la decisión o cálculo de
rutas ni media ningún tipo de algoritmo de encaminamiento. Es un mecanismo para
interconectar ad hoc dominios distintos dependientes de una entidad administrativa común.
Es decir, no está diseñado como un método flexible y escalable para interconexión
ocasional de dominios sino como una solución permanente para un conjunto concreto
y estudiado de subsistemas.
Agimone
Un caso un tanto especial es Agimone [HFRL06], un middleware que proporciona
movilidad para agentes entre distintas WSN usando redes IP (principalmente Internet)
como mecanismo intermedio. Los agentes de la WSN están implementados sobre el
middleware Agilla [FRL05]. Para poder ser transportados a través de Internet requieren
una adaptación como agentes para el middleware Limone [FRH04]. Es decir, Agimone
es una capa adicional para proporcionar interacción entre dos middlewares de agentes
existentes: Agilla (específico de la WSN) y Limone (específico de la red IP). Se asume
que cada WSN está conectada a Internet a través un PC o Stargate [Sta] que actúa como
pasarela, aloja una instancia de Limone y se encarga del proceso de adaptación.
2.6.3.
Protocolos híbridos
Se trata de un intento por resolver parte de los problemas que causan las pasarelas.
Consiste en diseñar un protocolo que puede funcionar en modo dual de manera que
se pueda utilizar para acceder a nodos de al menos dos redes diferentes. La necesidad
de eliminar la pasarela se debe a que ambas redes deben poder interconectarse sin
absolutamente ninguna infraestructura.
S ENNER [SKLN08] propone una solución para el clásico escenario de los bomberos.
Utiliza un esquema de direccionamiento en el que se reserva 1 bit para indicar a qué
tipo de red se refiere el resto de la dirección. Nótese que no se trata de un prefijo de
subred sino un código que identifica la tecnología de la red.
Se supone la existencia de una red de sensores (desplegados por los propios bomberos)
y otra formada por las PDA S que llevan consigo. La red de PDA S es obviamente móvil y
utiliza encaminamiento ad hoc (una MANET), mientras que la red SAN se considera fija.
Ambas redes deben interconectarse por medio de cualquier par PDA-sensor dado que las
PDA S van equipadas con una interfaz W I F I y una de radio del mismo tipo que utiliza la SAN.
La consecuencia es que cualquier PDA puede actuar como puente entre ambas redes.
Debido a las limitaciones de energía, la SAN solo transporta mensajes producidos por
los nodos sensores, pero en circunstancias excepcionales es posible encaminar mensajes
procedentes de una PDA y dirigidos a otra, por ejemplo si se produce la orden de abandonar
un edificio cuyo colapso es inminente. Este trabajo propone eliminar IP también en la red
de PDA y encapsular los datos directamente sobre el protocolo de enlace. El nuevo esquema
de direccionamiento está dividido entre identidades para los sensores y para las PDA S de la
i
i
i
i
i
i
i
i
2. A NTECEDENTES
77
MANET. Utiliza 1 bit para indicar si el mensaje debe propagarse a ambas redes o solo a una,
otro para indicar la red a la que corresponde y 6 bits más para direccionar el nodo. Es decir,
puede haber un máximo de 63 nodos sensores y 63 PDA S en total. Los nodos utilizados en
los experimentos son TMote Sky, que cuentan con 10 KiB de RAM y 48 KiB de ROM.
Se trata, por tanto, de una solución diseñada ex profeso para un despliegue particular.
Las limitaciones a 2 redes con 63 nodos por red son inaceptables para plantear una solución
general y es fácil comprobar que el mismo planteamiento no escala bien a cualquier
número de redes o nodos. El protocolo concreto es específico de la aplicación y se ha
creado a partir de la arquitectura C OPRA (véase § 2.5.15). No se dan detalles sobre
sus características o prestaciones aunque sí se ofrecen datos sobre su desempeño en
simulaciones utilizando una versión modificada de AODV (Ad hoc On-Demand Distance
Vector) para el encaminamiento de paquetes.
Además de los problemas de escalabilidad, hay algunos detalles importantes que el
artículo deja pendientes o no aclara:
¿Cuál es el formato de la cabecera? – No solo se requiere un esquema de direccionamiento común, también en necesario un formato que permita a los encaminadores
obtener esas direcciones de la cabecera de cada datagrama.
¿Cuál es la representación de datos externa? – Cómo se serializan y representan los
datos de la aplicación «en el cable». El propio artículo indica que se debería
determinar el tamaño de los tipos de datos y su ordenamiento.
¿Cómo se gestiona la diferencia de MTU? – No cualquier mensaje de la MANET
puede atravesar la WSN dado que éstas suelen tener una trama mucho menor que
W I F I.
¿Cómo se comunica la red MANET con otras? – ¿Es posible acceder a la MANET
desde Internet o una red troncal de otro tipo?
La conclusión a todas estas cuestiones es que no basta con un esquema de direcciones
unificado, es necesario también un protocolo de red único.
G ADALLAH [GEK08] plantea un escenario muy similar al anterior. En este caso, se
supone una red de sensores que se despliega inmediatamente después de una catástrofe,
como un terremoto o un gran incendio. La otra red está formada por los vehículos de
los equipos de emergencia, que forman una MANET, pero que además tienen interfaces
de radio compatibles con la WSN y posiblemente acceso a Internet. Cualquiera de estos
vehículos puede funcionar como pasarela entre la MANET y la WSN. Lo interesante de este
trabajo es que propone un protocolo de encaminamiento que proporciona dos modos:
Modo orientado a dirección, se utiliza para comunicar los vehículos entre sí
utilizando AODV. Si un nodo sensor recibe un mensaje de petición de ruta en
este modo lo descarta inmediatamente.
Modo orientado a datos, se utiliza para obtener información de la red de sensores.
Cuando un mensaje de consulta (que no incluye dirección destino) llega a un sensor,
si la consulta que contiene le atañe, puede responder encaminando el mensaje a
través de la ruta almacenada en el propio mensaje de petición.
i
i
i
i
i
i
i
i
78
2. A NTECEDENTES
La ventaja de este tipo de protocolos orientados a datos es que no se requiere un protocolo
de transporte adicional, el propio protocolo de encaminamiento lo es también de transporte.
Sin embargo, presenta el inconveniente de que los tipos de datos, sus tamaños y los criterios
de selección están definidos intrínsecamente en el propio protocolo de encaminamiento de
modo que un nuevo tipo de sensor o consulta implica tener que modificar el protocolo.
2.6.4.
Redes «inmersivas»
Se trata de redes inalámbricas en las que pueden aparecer dispositivos de otra naturaleza
pero con capacidad para comunicarse con los nodos de la red. El ejemplo clásico es un
sistema ubicuo en el que una persona con una PDA o smart phone puede comunicarse
directamente con los dispositivos que hay instalados en el entorno, para lo cual debe
disponer lógicamente de una interfaz de radio compatible. En realidad es un escenario
muy similar al de los bomberos que veíamos en la sección anterior.
En esta situación, cualquier nodo puede actuar como pasarela para dispositivos externos.
Aunque desde el punto de vista de los sistemas ubicuos, ésta es una situación con un
gran potencial para las WSN, raramente se considera en la bibliografía debido quizá
al alto grado de autonomía que implica para los nodos, a la necesidad de plantear un
protocolo de comunicaciones suficientemente robusto y a la potencial heterogeneidad
y dinamismo que implica.
Por ejemplo, K ABADAYI [Kab06] propone un modelo para el desarrollo de un
middleware en el que una persona puede entrar en una zona en la que hay una red de
sensores (inmersión) y configurar un escenario con unos condicionantes muy precisos
para acceder a los nodos próximos hasta una cierta «profundidad» (no a cualquiera). Este
middleware, denominado Declarative Applications in Immersive Sensor networks (DAIS)
está basado en la composición de estas escenas y en la utilización de sensores virtuales para
agregación de datos procedentes de los sensores. El trabajo citado es bastante preliminar
y no ha sido posible encontrar detalles sobre cómo se produce la entrega de mensajes,
su formato o el protocolo de encaminamiento utilizado. DAIS contempla la aparición de
dispositivos individuales que interaccionan con la WSN, mientras que [SKLN08] considera
dos redes formadas por dispositivos distintos pero situadas en la misma zona, a pesar de
ello. Aunque el título de esta sección se ha tomado de este artículo, una vez analizado
su diseño, quizá sería más preciso hablar de «clientes inmersos».
2.7.
Descubrimiento de servicios y recursos
Es frecuente que en muchos sistemas distribuidos los servicios disponibles puedan
aparecer y desaparecer dinámicamente. También puede ocurrir que varias entidades
puedan proporcionar el mismo servicio, quizá con distintos condicionantes de Q O S. Los
SDP S son una solución bastante efectiva para proporcionar mecanismos a los servicios
para darse a conocer, y a los clientes y aplicaciones para localizar el servicio más
adecuado a sus necesidades.
En esta sección veremos primero unos conceptos generales, después las prestaciones
habituales de los SDP S analizando las distintas alternativas para su diseño y funcionamiento.
i
i
i
i
i
i
i
i
2. A NTECEDENTES
79
Por último, se introducen algunas iniciativas destacables en su aplicación a las SAN
y en entornos inteligentes.
2.7.1.
Terminología
Para la descripción de SDP utilizaremos la terminología y criterios de clasificación
habituales en este campo, siendo M ARIN -P ERIANU [MPHS05] un buen referente a este
respecto. Se definen a continuación algunos de los conceptos más importantes en este
campo a fin de evitar posibles ambigüedades:
Servicio
Cualquier funcionalidad que una entidad hardware o software ofrece a la red y que
pudiera ser de interés para otros elementos del sistema, ya sean usuarios u otros
servicios.
Descubrimiento de Servicios
Protocolos y herramientas destinados a la búsqueda, registro y detección automática
de dispositivos y sus servicios en una red de comunicaciones.
De acuerdo con la terminología habitual, se pueden identificar tres tipos de entidades
básicas en cualquier SDP:
Cliente12
La entidad interesada en encontrar y utilizar servicios presentes en la red. Eso implica
aplicaciones finales para el usuario del sistema, aplicaciones de gestión y depuración,
servicios derivados, etc.
Servidor
La entidad que ofrece el servicio. Un nodo puede alojar varios objetos del mismo
o diferentes tipos. Podemos concluir pues que el rol de servidor recae en el nodo
tanto como entidad física como lógica. Cuando los servicios se implementan con las
herramientas estándar del middleware (sobre un PC, por ejemplo) el concepto de
servidor es muy similar desde ambos puntos de vista: el SDP y el middleware.
Directorio14
Se trata de un servicio especial que permite a cualquier elemento del sistema acceder
a la información que describe los demás servicios, de modo que se pueda determinar
qué nodo o nodos ofrecen determinado servicio y en qué condiciones.
2.7.2.
Prestaciones habituales
A continuación se enumeran y describen los casos de uso habituales que soportan
los SDP S. Aunque no todos ellos incorporan todas las prestaciones, y algunos integran
otros aspectos adicionales (como encaminamiento) que no son contemplados aquí, puede
servir como referente a efectos de comparación.
12 También
14 También
user.
servidor, broker, central, resolver.
i
i
i
i
i
i
i
i
80
2. A NTECEDENTES
A pesar de que algunos SDP S (como el de Jini [Sun01]) definen el uso del servicio como
parte del protocolo de descubrimiento, nosotros hemos excluido ese aspecto puesto que
consideramos que realmente queda fuera de la funcionalidad del SDP como tal.
Descripción de servicios
El SDP debe definir algún lenguaje, nomenclatura o modelo de información para
describir qué función realiza el servicio, cómo se usa y los requisitos que debe
cumplir el cliente para utilizarlo, incluyendo posiblemente directrices de autenticación
o seguridad.
Así por ejemplo, SLP [VGPK97] define sus servicios mediante plantillas [GPK99].
Éstas incluyen conjuntos de atributos y sus valores. Bluetooth SDP [BT04] también define
sus servicios por medio de una lista de atributos.
Persistencia de las descripciones
Existen varias alternativas para el almacenamiento de las descripciones de los servicios.
En los protocolos basados en directorio, éstas residen en el mismo (modelo centralizado),
mientras que en el modelo distribuido pueden estar en los nodos que implementan los
servicios. Son posibles modelos híbridos y directorios jerarquizados. UP N P SSDP [UPn00]
utiliza un modelo de persistencia distribuido, mientras que SLP y Jini utilizan modelos
centralizados basados en directorio.
En cuanto al formato de los datos, Universal Plug and Play (UP N P) y otros utilizan
descripciones en XML lo que los hace poco adecuados como candidatos para SAN
ya que los requisitos para el procesamiento de XML pueden resultar prohibitivos en
dispositivos con recursos limitados.
Referencia del servicio
Todo servicio debe tener asociada una referencia o descriptor que haga posible su uso o
localización. Tanto el proceso de búsqueda como el de anunciamiento utilizan descriptores
de servicios para lograr su función. El formato del descriptor, que por comodidad suele tener
un formato textual, puede incluir un protocolo, una dirección de host y otra información
para localización unívoca del servicio.
Anunciamiento/Registro
El procedimiento por el cual un servicio nuevo se da a conocer al sistema se denomina
anunciamiento (advertisement). Para ello se utiliza algún mecanismo de multi-envío
que puede estar basado en direccionamiento broadcast o multicast, requiriendo en este
último caso una dirección conocida públicamente. Este hecho normalmente limita la
operación del mecanismo de anunciamiento a una LAN o medio de difusión equivalente,
puesto que propagarlos a una red de tamaño considerable tiene importantes efectos
sobre su escalabilidad.
El anunciamiento puede ser un proceso proactivo (descubrimiento pasivo) si lo realiza
el servicio por iniciativa propia o bien puede ser reactivo (descubrimiento activo), si
lo desencadena una acción del cliente, aunque en ese caso puede ser visto como una
i
i
i
i
i
i
i
i
2. A NTECEDENTES
81
modalidad de búsqueda. El anunciamiento proactivo suele ser periódico lo que, en principio,
lo convierte en una mala solución para SAN si los dispositivos se alimentan con baterías.
También es posible encontrar SDP S que contemplan la despedida de servicios como una
forma de cortesía para evitar interacciones innecesarias cuando un servicio desaparece.
En los SDP S basados en directorio el mecanismo de anunciamiento puede ser substituido
por una operación de registro explícito. El directorio mejora la escalabilidad de la solución
puesto que no requiere tráfico adicional en la red. También son posibles modelos híbridos
en los que los servicios pueden elegir entre registro, anunciamiento reactivo o proactivo.
SLP registra sus agentes de servicio en los agentes de directorio enviando mensajes
SrvReg. También dispone de anunciamiento explícito para servicios y directorios por
medio de los mensajes SAAdvert y DAAdvert.
Los servicios Jini se registran enviando al directorio (el Jini Lookup Service) un objeto
que contiene la descripción y atributos del servicio.
Búsqueda
El proceso de búsqueda de servicios es siempre un mecanismo proactivo, normalmente
iniciado por el cliente, aunque es interesante la posibilidad de búsquedas realizadas a
expensas de agentes de mantenimiento, gestión o, incluso, de composición automática
de servicios.
La búsqueda implica algún tipo de consulta o criterio de aceptación. El resultado suele
ser una lista de posibles candidatos aunque si lo que se pretende es un procedimiento
complemente automático, lo ideal es que el sistema decida por sí mismo cuál es la
elección ideal sin intervención del usuario.
En SLP la búsqueda incluye una lista de atributos que el servicio ha de cumplir. Otros
como INS [BBK02] permiten especificar comodines.
Jini utiliza una plantilla para realizar el filtrado de servicios disponibles. Si la consulta
se satisface, el cliente obtiene un objeto procedente del directorio que le sirve como
proxy para contactar con el servicio.
2.7.3.
Descubrimiento de Servicios en redes ad hoc y SAN
El descubrimiento de servicios resulta especialmente importante en redes ad hoc, SAN y
WSN debido a su naturaleza dinámica, no ya por la movilidad (que puede no existir) sino
por el hecho de que las comunicaciones inalámbricas, la aparición de nuevos nodos y el
agotamiento de las baterías pueden provocar cambios en la disponibilidad de servicios.
Los SDP S para SAN suelen prestar especial atención a cualquier característica del
protocolo que pueda tener repercusión sobre los recursos de cómputo y energía a la vez que
se cuidan los aspectos dinámicos. Por ello, suelen evitarse los protocolos basados en XML,
el descubrimiento pasivo, el directorio centralizado, etc., muy habituales en SDP S para redes
convencionales. Veamos algunos de los protocolos más representativos en este área.
R. M ARIN -P ERIANU [MPSH06, MPSHH08] utiliza un enfoque basado en grupos
(clusters) para diseñar un SDP para WSN heterogéneas. A fin de reducir el tráfico necesario
para realizar registros y búsquedas se divide la red en grupos como es habitual en muchos
i
i
i
i
i
i
i
i
82
2. A NTECEDENTES
middlewares para SAN y para cada uno de ellos se nombra una cabeza que alojará un
directorio local. Ese nodo será el más potente o con más energía del vecindario (nodos
alcanzables en un salto). El resultado es un modelo de directorio jerárquico en el que los
nodos solo informan de sus servicios a la cabeza de su grupo.
C. F RANK [FHK04] propone un SDP integrado con el protocolo de encaminamiento
asumiendo que se trata de un protocolo ad hoc bajo demanda como puede ser AODV, que
es lo habitual en redes MANET y en WSN aunque la movilidad no sea un factor aplicable.
El motivo más importante para hacerlo de este modo es el considerable ahorro de mensajes
que supone, algo especialmente importante en WSN. Propone dos posibles soluciones; la
primera consiste en extender el protocolo de encaminamiento para transportar información
sobre la descripción de los servicios tal como propone C. P ERKINS [PK02]. La segunda es
utilizar una arquitectura de direccionamiento semántico [HKFK03] empleando algunos
de sus mensajes para implementar anunciamientos y búsquedas con muy poca sobrecarga
adicional. Otros protocolos similares son GSD [CJYF02] y HSID [OKK04].
Pervasive Discovery Protocol (PDP) [Cam02, CMnP+ 05, CGMA06] es un SDP
diseñado para cubrir dos problemas de los protocolos anteriores:
La necesidad de un elemento o servidor central (directorio) es incompatible con los
entornos pervasivos o ubicuos dado que no hay garantías de que ningún dispositivo
esté conectado y accesible para todos por tiempo indefinido.
Las soluciones sin directorio hacen un uso constante e ineficiente de comunicaciones
multicast o broadcast que suponen un grave inconveniente para dispositivos
alimentados por baterías.
Para evitar los problemas que suponen estos dos enfoques, PDP propone un modelo
completamente distribuido con una mezcla de descubrimiento pasivo y anuncios reactivos.
Es decir, los nodos anuncian sus servicios sólo cuando un cliente realiza una petición de
servicio. Las respuestas a esas consultas son anunciamientos de servicios (que podemos
considerar reactivos) pero que se transmiten broadcast a todos los dispositivos y clientes de
la red de modo que todos conocen el nuevo servicio, pero sólo si ha habido una solicitud.
Con ello se minimiza la cantidad de mensajes necesarios aunque no se puedan descubrir
los nuevos servicios inmediatamente de estar disponibles.
i
i
i
i
i
i
i
i
Objetos Distribuidos Universales
3.1.
3.2.
3.3.
3.4.
3.5.
3.6.
3.7.
3.8.
3.9.
Nomenclatura
Interfaces escalares
Contenedores
Actores activos
Componentes
Actores compuestos
Composición básica de servicios
Consulta múltiple
Conclusiones
33
U
NA parte considerable de los dispositivos que aparecen en las redes SAN suele
ofrecer información escalar tal como un valor de temperatura, presión, intensidad
luminosa; e incluso más simple, como un contacto libre: presencia mediante una barrera
de infrarrojos, cierre de una puerta, una pisadera y un largo etcétera.
En los dispositivos utilizados actualmente, sobre todo en las WSN, es muy habitual
que un mismo nodo integre varios sensores distintos: LDR, acelerómetro, inclinómetro,
etc. (ver figura 8.1a). Desde el primer momento, nuestra visión de la red SAN desacopla
funcionalmente el transductor y el nodo al que está físicamente conectado. Cada transductor
situado en la placa de un nodo es un objeto distribuido autónomo e independiente, y
el nodo al que está conectado desempeña únicamente el papel de punto de conexión.
Aunque obviamente todos comparten el mismo dispositivo de cómputo e interfaz de
red, eso resulta irrelevante para los clientes, los servicios implicados y la aplicación
distribuida de la que forma parte.
Teniendo muy presente la idea del transductor como objeto independiente y tomando
como base las interfaces que ya proponía el proyecto SENDA [ML02, Moy03], definimos
un modelo de información basado en un conjunto de interfaces que homogeneiza el
acceso y simplifica la interacción remota con los transductores para, de ese modo,
aprovechar al máximo las posibilidades de los dispositivos empotrados más simples.
Ese modelo de información, que denominamos DUO (Distributed Universal Objects),
es el tema del presente capítulo.
Es importante señalar que DUO no está en modo alguno limitado a la interacción con
los transductores de una red SAN. Se puede aplicar a servicios o dispositivos complejos
—como una cámara de vídeo— sin detrimento de su funcionalidad o eficiencia, tal como
se mostrará en la descripción de los prototipos (véase capítulo 8).
83
i
i
i
i
i
i
i
i
84
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
3.1.
Nomenclatura
Con la intención de evitar posibles ambigüedades, aparecen a continuación definiciones
informales para algunos conceptos que se utilizarán habitualmente en éste y subsiguientes
capítulos.
Faceta
Un mismo objeto puede desempeñar distintos roles dependiendo del subsistema
o cliente que desea interaccionar con él. Cada uno de estos roles o facetas
representa una forma diferente de interactuar con un mismo objeto. Cada faceta suele
implementar interfaces diferentes y normalmente tiene asociado un conjunto distinto
de casos de uso. Cada faceta se identifica por medio de una clave o cadena y existe
una faceta por defecto, que debería corresponder con la funcionalidad principal del
objeto.
Servicio
Aunque se han dado definiciones de servicio tan vagas como «la implementación
de un algoritmo o el acceso a un dispositivo en un host de modo que un cliente
puede contactar con él para utilizarlo» [OVB05], el concepto de servicio en DUO
es más cercano al que OASIS define para su modelo SOA (Service Oriented
Architecture) [Org06], que viene a decir:
Un servicio es un mecanismo que permite acceder a una o más capacidades. El
acceso se proporciona usando una interfaz prescrita y se ejerce ajustándose a las
restricciones y políticas especificadas en la descripción del servicio.
Precisamente este capítulo contiene la interfaz, la descripción y las restricciones
de cada servicio. Es decir, las siguientes secciones definen los servicios DUO que
pueden ser implementados por objetos distribuidos. Nótese que un solo objeto puede
proporcionar varios servicios implementando varias interfaces y/o facetas.
Actor
Llamamos actores a los objetos que desempeñan una tarea dentro del sistema y
no son meros consumidores de los servicios que éste presta. Así, un actor DUO es
todo objeto distribuido que implemente alguna de las interfaces especificadas en el
modelo.
3.2.
Interfaces escalares
Se define un módulo para cada tipo de dato susceptible de ser utilizado para representar
el estado de un transductor, es decir, el valor de la magnitud que mide el sensor, o aplica
el actuador. En el caso general, cada módulo tiene dos interfaces: R (readable) y W
(writable) que definen respectivamente los métodos get() y set(). Es un modelo de datos
basado en consulta (query-based), una versión orientada a objetos del enfoque data-centric
utilizado en muchos middlewares de SAN como TinyDB [MFHH05], Cougar [YG02]
o SensorWare [BHS03].
Se trata de interfaces minimalistas que reflejan cómo se utiliza el actor, pero no qué
es. Son deliberadamente pobres desde el punto de vista semántico. La interacción entre
i
i
i
i
i
i
i
i
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
85
actores y la configuración de servicios se han diseñado como mecanismos ortogonales y
desacoplados. Dicha diferenciación posibilita la delegación parcial de responsabilidades
a otros dispositivos o servicios aprovechando mejor el enfoque distribuido y resulta
en un sistema más tolerante a fallos.
Una vez fijadas las relaciones entre actores (configuración), la única funcionalidad
esencial es la que permite interactuar con el estado de los mismos, es decir, averiguar
o modificar el valor de los transductores. Despojar a la interfaz de gran parte de su
semántica simplifica sensiblemente su implementación, aumenta la generalidad y no
perjudica el modelo de información.
Partiendo de esta premisa, es posible modelar tres situaciones muy frecuentes:
Un sensor (interfaz R).
Un actuador, cuyo estado no es accesible de modo síncrono (W). Esta situación
ocurre cuando no se dispone de conectividad bidireccional, aunque eso no implica
que ese valor no pueda ser obtenido indirectamente, como se verá más adelante.
Un actuador, cuyo estado puede ser consultado de modo síncrono. Implementa tanto
R como W.
El listado 3.1 muestra la declaración de las interfaces básicas por medio del lenguaje
Slice. El método get() es idempotente en todos los módulos, es decir, puede ser invocado
varias veces consiguiendo el mismo efecto (sobre el actor) que si se invocara sólo una vez.
Obviamente el método puede devolver un valor distinto en cada ocasión si el dispositivo
efectúa una lectura instantánea de su sensor.
El método set() tiene dos parámetros: el primero es el valor que se pretende asignar al
actuador, el segundo (oid) es una identidad de objeto y lo utiliza el emisor del mensaje para
que el receptor pueda identificarlo. Si no hay ningún actor ligado al emisor del mensaje
(se trata de un cliente puro) puede especificar una identidad vacía. Lo habitual es que
los clientes y aplicaciones envíen una identidad nula como segundo argumento, mientras
que los actores activos (véase § 3.4) indican su propia identidad.
La interfaz Pulse::W se utiliza para actores que deben ser informados de la ocurrencia
de un suceso, pero éste no tiene asociado valor alguno. Un disparador remoto para una
cámara fotográfica es un buen ejemplo para ilustrar el uso de esta interfaz.
También merece especial atención el módulo Object. El tipo de dato en este caso es
una referencia a objeto. De ese modo, se proporciona la posibilidad de que un actor
ofrezca/acepte un proxy (que puede cambiar). Este mecanismo se puede utilizar para
proteger objetos, pudiendo conseguir la referencia al verdadero objeto únicamente cuando
se cumplen determinadas condiciones. También se puede utilizar para proporcionar un
mecanismo de delegación similar al concepto de receptacle en la nomenclatura CCM.
La utilización de nombres tan cortos para las interfaces y los módulos no es casual.
Los métodos para introspección (como ice_id() o ice_isA()) transmiten esos tipos
como cadenas. Nombres más largos implican mensajes más largos, más cantidad de
memoria, energía, etc. Por ese motivo, los programadores deberían aplicar este principio
también a los nombres de sus interfaces.
i
i
i
i
i
i
i
i
86
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
module DUO {
module Pulse {
interface W { void set ( Ice :: Identity oid ) ; };
};
module IBool {
interface R { idempotent bool get () ; };
interface W { void set (bool v , Ice :: Identity oid ) ; };
};
module IByte {
interface R { idempotent byte get () ; };
interface W { void set (byte v , Ice :: Identity oid ) ; };
};
module IInt {
interface R { idempotent int get () ; };
interface W { void set (int v , Ice :: Identity oid ) ; };
};
module IFloat {
interface R { idempotent float get () ; };
interface W { void set (float v , Ice :: Identity oid ) ; };
};
module IString {
interface R { idempotent string get () ; };
interface W { void set (string v , Ice :: Identity oid ) ; };
};
module IByteSeq {
interface R { idempotent Ice :: ByteSeq get () ; };
interface W { void set ( Ice :: ByteSeq v , Ice :: Identity oid ) ; };
};
module IObject {
interface R { idempotent Object∗ get () ; };
interface W { void set (Object∗ v , Ice :: Identity oid ) ; };
};
};
L ISTADO 3.1: Interfaces DUO escalares (especificación Slice)
i
i
i
i
i
i
i
i
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
87
Si se requiere un actor que implemente al tiempo la interfaz R y W de un módulo,
el programador deberá definir una interfaz adicional que herede de ambas. Nótese que
ni la aplicación cliente ni ninguna otra entidad que haga uso del actor necesita conocer
esa tercera interfaz; se trata de un mecanismo de composición para la funcionalidad del
servidor. Es decir, no importa el nombre que se le dé a esa interfaz o que cambie de un
actor a otro; la única directiva es utilizar también nombres cortos por las razones explicadas
en el párrafo anterior. Un ejemplo de esto aparece en el listado 3.2.
module MySystem {
interface MyBoolRW extends DUO :: IBool :: R , DUO :: IBool :: W {};
};
L ISTADO 3.2: Creación de una interfaz para composición de interfaces básicas. El resto
del sistema puede ignorarla sin consecuencias
3.2.1.
Actuación relativa
Pueden aparecer situaciones en las que es conveniente manipular un actuador sin conocer
su valor actual. Estas situaciones se dan cuando:
La tecnología de la red de datos no permite averiguar su valor (p.ej. X10 [X10]).
El transporte de datos no permite leer un valor (por ser oneway) de modo que no se
puede utilizar (get()) para obtenerlo.
Realmente no se requiere conocer el valor del actuador, solo modificarlo, evitando
así el mensaje adicional de lectura.
Se trata de añadir al actuador soporte (opcional) para manipulación relativa de su estado.
Para ello se define una nueva interfaz que aparece en el listado 3.3.
module DUO {
module Func {
interface Relative {
void inc (short nsteps ) ;
};
};
};
L ISTADO 3.3: Interfaz DUO::Func::Relative
Esta interfaz es aplicable a casos como el desplazamiento de un motor (izquierda/derecha), zoom (acercar/alejar), enfoque y muchas otras actuaciones similares que
pueden definirse indicando un valor relativo respecto al actual, a diferencia de set()
que indica un valor absoluto.
El único método de la interfaz DUO::Func::Relative es inc(), y su parámetro (nsteps)
indica un número de pasos. Como este parámetro tiene signo, puede indicar tanto
incremento como decremento. El valor del paso lo establece el propio actor y puede
no ser conocido por el cliente.
i
i
i
i
i
i
i
i
88
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
3.3.
Contenedores
La creación de colecciones de objetos o transductores, ya sea por medio de grupos o
clusters [VR05], es una característica habitual en los middlewares convencionales como,
por ejemplo, el servicio CosNaming [Obj01b] de CORBA.
También es común en middlewares especializados en redes WSN. La formación
de grupos responde a diversos motivos: puede estar ligada a un suceso o necesidad
puntual (EnviroTrack [Abd04], DSWare [LLS+ 03]), utilizar criterios como la proximidad
o el nivel de energía a efectos de optimización de las comunicaciones (SINA [SJS01],
MiLAN [HMCP04]) o formar grupos a partir de los elementos que satisfacen un criterio
dado [Abd04] o los sensor spaces de COCOS [KKN07].
El módulo DUO::Container proporciona un mecanismo básico para crear colecciones
y jerarquías de actores similar al servicio CosNaming. La interfaz DUO::Container::R
ofrece un diccionario de objetos cuyas claves son cadenas de texto arbitrarias elegidas por
el programador. Las referencias que contiene ese diccionario pueden ser de objetos situados
en cualquier parte, no tienen porqué tener relación alguna con el actor contenedor.
La interfaz DUO::Container::W (listado 3.4) ofrece métodos para manipular la lista de
objetos que mantiene el contenedor. El método link() registra un objeto asociado a una
clave, ambos proporcionados por el cliente. El método unlink() elimina un registro.
module DUO {
dictionary <string , Object∗ > ObjectPrxDict ;
module Container {
exception A l r e a d y E x i s t s E x c e p t i o n { string key ; };
exception N o S u c h K e y E x c e p t i o n { string key ; };
interface RW ;
interface R { idempotent ObjectPrxDict list () ; };
interface W {
void link (string key , Object∗ value )
throws A l r e a d y E x i s t s E x c e p t i o n ;
void unlink (string key )
throws N o S u c h K e y E x c e p t i o n ;
Container :: RW ∗ create (string key )
throws A l r e a d y E x i s t s E x c e p t i o n ;
void destroy () ;
};
interface RW extends R , W {};
};
};
L ISTADO 3.4: Módulo DUO::Container para colecciones de objetos
Por otra parte, el método create() se puede utilizar para crear un contenedor y
vincularlo (con el nombre dado) dentro del contenedor que proporciona el método.
Nótese que esos contenedores hijos los crea y mantiene el servidor en el que se
i
i
i
i
i
i
i
i
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
89
encuentre el contenedor padre. El método destroy() elimina tanto la asociación como
el propio contenedor.
Existe una tercera interfaz RW debido a que los contenedores que devuelve el método
create() deben implementar R y W.
3.4.
Actores activos
Con frecuencia, las aplicaciones que utilizan redes SAN necesitan mecanismos para
conocer el valor actualizado de un transductor o varios (un grupo). Sin embargo, cuando
hay gran cantidad de nodos conectados, la consulta síncrona por parte de los clientes
presenta varios problemas:
Se requiere un transporte twoway, pues el valor se obtiene como respuesta.
Como alternativa, y empleando transporte unidireccional, existe la posibilidad de
utilizar algún mecanismo de retrollamada, en el cual el cliente indica en la invocación
la referencia de un segundo objeto bajo su control. A continuación, el nodo envía un
mensaje a dicho objeto con el valor solicitado.
En ambos casos, se requieren dos mensajes para obtener el dato deseado.
Si se utiliza un transporte twoway, se debe consultar a cada objeto de forma
independiente ya que no existe la posibilidad de utilizar multicast.
Una gran parte de los objetos consultados no habrán sufrido cambios y retornarán el
mismo valor que en la consulta anterior resultando por tanto innecesaria, pero no
hay forma de saberlo de antemano.
Todas estas circunstancias incrementan la cantidad de mensajes, lo cual repercute en el
dimensionamiento del ancho de banda necesario en la red SAN y, por ende, en su coste.
Además, implica también un incremento significativo del consumo, que en el caso de nodos
alimentados por baterías lleva consigo una reducción de su autonomía.
Para evitar estos problemas utilizamos actores activos. Se trata de actores que pueden
actuar también como clientes, es decir, que pueden realizar invocaciones a otros objetos,
aunque de un modo muy concreto. Los actores activos utilizan esas invocaciones con
el propósito exclusivo de notificar a otros su propio estado y su identidad (utilizando
las interfaces W).
Al igual que DSWare [LLS+ 03], TinyDB [MFHH05], Impala [LM03] o Mires [SGaV+ 04], DUO proporciona soporte para estrategias de comunicación basadas
solo en eventos, útiles también para aquellos casos en los que no se puede o no se desea
utilizar un medio twoway por los motivos antes mencionados.
Los actores activos materializan el soporte de DUO para redes de sensores
activas [BHS03], es decir, redes en las que los nodos no sólo responden a paquetes de
datos procedentes de la red; también lo hacen a eventos del entorno físico, timeouts, etc.
No se debe confundir con otro concepto del mismo nombre que presenta [LGC05], y que
se refiere a la capacidad de los nodos sensores para realizar procesamiento de datos.
i
i
i
i
i
i
i
i
90
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
Todo actor activo puede tener asociado un objeto observador1 , es decir, otro objeto
distribuido que observa el estado del actor. Para permitir esta asociación el actor dispone
de una referencia a su observador que puede ser modificada si se requiere. Cuando sea
preciso, el actor invocará el método set() de su observador para comunicar el nuevo
estado del transductor. Se requiere, por tanto, que el observador implemente una interfaz
DUO compatible (ver figura 3.1).
La interfaz en lenguaje Slice para la implementación de objetos activos se muestra en
el listado 3.5. En el caso de la implementación para I CE, la interfaz DUO::Active tiene
un soporte específico para su servicio de eventos. Eso conlleva grandes ventajas porque
así puede utilizarse con un número arbitrario de observadores, se desacopla al productor
de los consumidores (el actor sólo tiene que conocer la referencia del canal) y facilita la
integración con otros servicios proporcionados por el middleware. Sin embargo, el hecho
de utilizar canales de eventos como observadores no excluye la posibilidad de utilizar
objetos convencionales no ligados al servicio de eventos del fabricante.
module DUO {
module Active {
interface R {
Object∗ getCb () ;
IceStorm :: Topic ∗ getTopic () ;
};
interface W {
void setCbTopic (Object∗ publisher , IceStorm :: Topic ∗ topic ) ;
};
};
};
L ISTADO 3.5: Módulo DUO::Active en lenguaje Slice
La interfaz DUO::Active::R proporciona información acerca del canal asociado al
objeto. El método getCb() se utiliza para conseguir una referencia al observador del
objeto. Cuando el actor activo se conecta a un canal de eventos este método retorna
el publicador de dicho canal, un objeto remoto al que se deben enviar los mensajes
que deben llegar a los consumidores.
El método getTopic() retorna una referencia al canal de eventos asociado. Este
dato es necesario para suscribir consumidores adicionales o cualquier otra operación
de mantenimiento del canal. Este proxy no es utilizado por el objeto, simplemente lo
sirve a terceros por conveniencia, dado que de otro modo la relación actor/cliente sería
dependiente de un tercero. Cuando el observador es un objeto sin relación con el servicio
de distribución de eventos el método getTopic() retorna un proxy nulo.
Por su parte, la interfaz DUO::Active::W ofrece la oportunidad de cambiar remotamente
el observador del objeto. Esto resulta especialmente interesante cuando el objeto es tan
reducido que no tiene capacidad suficiente para crear su propio canal de eventos. En ese
caso, un servicio externo puede intermediar creando y asignando los canales de eventos
automáticamente a los objetos que lo requieran (véase § 8.4.5).
1 Por
cercanía semántica, se aplica aquí la terminología del patrón de diseño observer [GHJV96].
i
i
i
i
i
i
i
i
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
91
La interfaz DUO::Active::W sólo define el método setCbTopic(), cuya función es
informar al actor de las referencias necesarias para utilizar un nuevo observador/canal.
De nuevo, si el observador no es un canal proporcionado por el middleware, el segundo
parámetro (topic) ha de ser un proxy nulo. Para eliminar el observador, el cliente debe
invocar este método pasando dos proxies nulos.
A efectos terminológicos, los objetos que no ofrecen este comportamiento se denominan
pasivos. Su estado sólo se puede averiguar mediante una consulta directa por medio de su
método get(). Eso implica la necesidad de un soporte de comunicaciones bidireccional,
mientras que los activos pueden implementarse utilizando únicamente primitivas de
comunicación unidireccional.
3.4.1.
Reactivos
Un actor reactivo informa de su estado invocando el método set() de su observador
cada vez que recibe un mensaje ice_ping(), tal como muestra la figura 3.1a.
(a)
(b)
F IGURA 3.1: Diagramas de secuencia de un actor reactivo (a) y uno proactivo (b)
Es importante señalar que se trata de un mecanismo idempotente y completamente
asíncrono ya que el tiempo de que dispone el actor para reaccionar no está acotado, aunque
podría estarlo. Otro punto importante es que la aplicación interesada en obtener el valor
del transductor no tiene porqué ser la misma que envía los mensajes ping.
i
i
i
i
i
i
i
i
92
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
En aquellos middlewares en los que los objetos no disponen de serie de un método equivalente a Ice::Object::ice_ping() o CORBA::Object::non_existent() será necesario definir una interfaz DUO::Object para proporcionar este tipo de funcionalidad.
3.4.2.
Proactivos
Un actor proactivo puede enviar mensajes set() de forma espontánea. Resulta
especialmente adecuado en las siguientes situaciones:
Sensores que pueden detectar cambios en la magnitud asociada. De este modo sólo
se envían nuevos mensajes cuando hay algún cambio en el valor.
Actuadores que informan de su estado como consecuencia de un cambio provocado
por un tercero.
Sensores o actuadores que por definición deben comunicar su estado cada cierto
tiempo con independencia de los cambios que se produzcan en él. Esto es útil para
implementar wathdogs, señales de sincronización, etc.
Nótese que, al contrario de lo que ocurre con los actores reactivos, ninguno de estos
casos requiere un mensaje de petición de estado implícito ni explícito (ver figura 3.1b).
3.4.3.
Activación condicional
Como hemos visto, los sensores proactivos envían su estado cada vez que cambia. Sin
embargo, este comportamiento puede ser contraproducente en muchos casos. Por ejemplo,
si tenemos un sensor que lee un termómetro quizá no necesitemos que el actor envíe un
evento cada vez que la temperatura cambie, incluso aunque lo pudiéramos discretizar a
grados o décimas de grado. Evitar el envío de esos mensajes es importante, se ahorra
energía y ancho de banda, muy escasos en una red tipo WSN.
Existen dos vías sencillas para reducir considerablemente el número de mensajes que
envía un actor activo. Lo ideal es que sólo se transmita información nueva cuando es
realmente útil para sus potenciales consumidores.
Activación por rango
Se trata de fijar un rango para que el actor sólo envíe nuevos eventos si su valor está
dentro (o fuera) de un rango determinado.
Para ello se asocian facetas especiales al actor, llamadas range_min y range_max.
Así por ejemplo, un sensor con interfaz DUO::IFloat::R puede tener una o ambas
facetas, que deben implementar el mismo tipo. Opcionalmente, estas facetas pueden
implementar la interfaz de escritura para permitir la modificación remota del umbral.
Un actor proactivo que disponga de estas facetas no se comportará como tal a menos
que su valor se encuentre dentro del rango definido por las mismas. Si el valor de
range_max es menor que el de range_min, entonces sólo enviará eventos si el valor
queda fuera del rango. Es posible también asociar al actor una de las facetas (en
lugar de las dos), caso en el que se utilizará como umbral que debe superar el valor.
Por razones obvias, esta funcionalidad solamente tiene sentido para actores escalares
no booleanos.
i
i
i
i
i
i
i
i
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
93
Activación por magnitud del cambio
Otro caso muy frecuente es la necesidad de evitar la transmisión de valores
demasiado similares. Para solventar este problema se utiliza también una faceta
(delta). Esta vez la faceta indica cuál es la diferencia mínima entre el valor actual y
el del último evento enviado para considerar que debe producirse un nuevo evento.
De este modo, se evita una gran cantidad de mensajes sin perder información, dado
que la aplicación puede modificar el valor delta remotamente adaptándolo a sus
necesidades en relación a la precisión del sensor.
3.5.
Componentes
En algunas situaciones puede ser conveniente que un solo objeto ofrezca varios
roles. Por ejemplo, un punto de luz regulable podría modelarse con la interfaz
DUO::IByte::W para ajustar la intensidad, pero también con la interfaz DUO::IBool::W
para encender/apagar.
El problema aquí es que en muchos middlewares, un objeto no puede tener dos métodos
con el mismo nombre; en este caso, tendría un set() heredado de cada interfaz. La
solución consiste en crear una faceta para cada uno de los roles que puede ofrecer el
objeto. El cliente puede listar sus facetas y después decidir cuál le interesa. Para ello,
se utiliza la interfaz DUO::Component, que se muestra en el listado 3.6. Se trata de
una interfaz muy sencilla cuando se utiliza I CE como middleware. Se debe a que los
objetos I CE ya disponen del método ice_getFacet() que devuelve un proxy a la faceta
solicitada a partir de cualquier otra. En otros middlewares que no dispongan de esa
funcionalidad habría que añadirla en esta misma interfaz.
module DUO {
interface Component {
Ice :: StringSeq getAllFacets () ;
};
};
L ISTADO 3.6: Interfaz DUO::Component
No se considera conveniente emplear el soporte de componentes que pudiera estar
disponible en cada middleware (como es el caso de CCM) porque la implementación
de objetos y clientes puede llegar a ser bastante compleja, mientras que la interfaz
DUO::Component —a pesar de ser tan simple— proporciona la funcionalidad básica
necesaria y puede ser implementada en dispositivos empotrados. El resto de las
características propias de un componente, como fuentes y sumideros de eventos, receptacles
o atributos se pueden conseguir por medio de otras interfaces DUO. En cualquier caso,
nótese que la finalidad de DUO::Component no es la de conseguir un componente con
todas las prestaciones propias de CCM o EJB (Enterprise JavaBeans), sino únicamente
la de proporcionar navegabilidad de facetas.
i
i
i
i
i
i
i
i
94
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
3.6.
Actores compuestos
La abstracción de la agregación aparece de forma recurrente en muchas de las propuestas
que se comentan en la sección 2.5. Por razones obvias, la agregación involucra colecciones
de objetos (véase § 3.3).
Muchos middlewares, sobre todo aquellos con interfaz de base de datos, ofrecen
operadores o servicios explícitos de agregación de datos como, por ejemplo, SINA [SJS01],
DSWare [LLS+ 03], TinyDB [MFHH05], Cougar [YG02] o Mires [SGaV+ 04]. En muchos
casos, son similares a los del lenguaje SQL; por medio de una sentencia de selección y un
operador que se aplica al resultado (p.ej. AVG). En otros, la agregación se consigue de
forma transparente mediante un objeto lógico o virtual [CMP06, RMDS02, Kab06].
DUO ofrece soporte para agregación transparente de actores a través de actores
compuestos, es decir, aquellos que implementan la interfaz DUO::Composite. Los objetos
compuestos (o simplemente composite) se utilizan para implementar transductores virtuales,
es decir, su estado no corresponde con el valor medido por un transductor físico, sino
que se obtiene luego de aplicar una función de agregación a partir de los valores de
un conjunto de actores.
Esta posibilidad permite, por ejemplo, obtener la temperatura media de una habitación
en la que hay desplegados una docena de sensores, pero realizando sólo una lectura, y con
la ventaja de que resulta completamente transparente para el cliente, que puede percibirlo
a todos los efectos como la lectura de un sensor real único.
La interfaz Composite toma su nombre del conocido patrón de diseño [GHJV96]. Lo
cual implica que desde el punto de vista de diseño, el composite desempeña las relaciones
tiene-un y es-un respecto a una interfaz DUO escalar. Para lograrlo, Composite hereda
de la interfaz DUO::Container para proporcionar agrupación de referencias a los actores
implicados (relación tiene-un). El resultado de la función de agregación lo proporciona
implementando la misma interfaz que los actores que agrega (es-un). La figura 3.2 lo
ilustra para el caso de un composite de DUO::IByte::R. Sin embargo, no se utiliza
este diseño porque presenta varios problemas:
1. No exporta un medio para que el usuario pueda listar o añadir nuevos actores al
composite.
2. No explicita la función de agregación que se está utilizando. No hay ninguna pista
para el cliente de cuál es la implementación del método get() del composite.
3. No permite proporcionar más de una función de agregación para el mismo conjunto
de actores.
El primer problema se resuelve utilizando la interfaz DUO::Container, que dota al
composite de métodos remotos para listar, añadir o eliminar referencias a los actores.
Los otros dos problemas se resuelven haciendo que el composite implemente también la
interfaz DUO::Component. Para obtener el resultado de una función de agregación concreta
se debe acceder a la faceta correspondiente: sum, max, avg, any, all, etc. El composite y
todas las facetas deben implementar la misma interfaz DUO escalar. Para averiguar de qué
i
i
i
i
i
i
i
i
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
95
F IGURA 3.2: Diagrama de herencia de interfaces para un actor DUO::IByte::R
compuesto, según el patrón de diseño
funciones de agregación dispone el composite basta utilizar su método getAllFacets().
La implementación de múltiples facetas no tiene porqué implicar un gran consumo de
recursos puesto que se pueden utilizar estrategias default servant, consiguiendo que un
único sirviente pueda calcular todas las funciones de agregación soportadas. La faceta,
por tanto, puede ser vista como un mecanismo de multiplexación.
La especificación aparece en el listado 3.7. El módulo Composite proporciona interfaces
R y W dependiendo de si el conjunto de actores agregados está predefinido (R) o el
cliente tiene la posibilidad de editar el conjunto (W).
module DUO {}
module Composite {
interface R extends DUO :: Component , DUO :: Container :: R {};
interface W extends DUO :: Component , DUO :: Container :: RW {};
};
};
L ISTADO 3.7: Módulo para construcción de actores DUO compuestos (especificación
Slice)
Estas interfaces permiten acceder a la funcionalidad de navegación de facetas y
agrupación de actores, pero aún falta especificar el tipo concreto del compuesto. Para
ello, el programador debe escribir una interfaz adicional que herede de DUO::Composite
y del tipo que corresponda a los actores que desea agregar. Como ejemplo, el listado 3.8
y la figura 3.3 muestran el caso de un actor DUO::IByte::R compuesto.
interface M y B y t e R C o m p o si t e extends DUO :: IByte :: R , DUO :: Composite :: W
{};
L ISTADO 3.8: Actor DUO::IByte::R compuesto (especificación Slice)
El método DUO::Container::W::link() debe encargarse de verificar que los objetos
añadidos al compuesto por los clientes implementan todos los tipos DUO escalares
que implemente el propio composite.
i
i
i
i
i
i
i
i
96
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
F IGURA 3.3: Diagrama de herencia de interfaces para un actor DUO::IByte::R
compuesto, utilizando interfaces DUO
Como el composite solo contiene referencias, un mismo actor puede estar agregado
en varios de ellos al mismo tiempo siendo totalmente transparente para él mismo y para
los actores agregados. Para participar en un composite, el actor no tiene que implementar
ninguna funcionalidad o interfaz especial.
3.6.1.
Actor compuesto activo
El composite también puede comportarse como un actor activo (ya sea reactivo o
proactivo) para cada una de sus funciones de agregación (facetas). Cada faceta en uso
puede tener su propio observador o canal de eventos asociado. Nótese que cada faceta se
comporta a todos los efectos como un actor DUO escalar y se puede utilizar en cualquier
lugar o servicio en el que cabe esperar un actor convencional. Esto es una gran ventaja a
efectos de coherencia semántica, bajo acoplamiento y facilidad en el despliegue respecto
a las propuestas citadas anteriormente. Entre otras cosas, eso permite que se puedan
agrupar (Container) o federar en otros actores compuestos.
3.6.2.
Distribución
La contrapartida de la agregación de datos es la distribución de acciones. En este caso,
un actor compuesto que implementa una interfaz escalar escribible (W) aplicará el valor
que recibe en su invocación set() a todos los actores que contiene.
El mismo comportamiento se podría conseguir utilizando el mecanismo estándar de
distribución de eventos si todos los actores agregados se suscriben a un canal creado
al efecto y se envía la invocación al publicador del canal. Sin embargo, la utilización
del composite presenta varias ventajas:
i
i
i
i
i
i
i
i
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
97
Se abstrae el mecanismo de distribución. Realmente la implementación puede
realizarse por medio de un canal de eventos tal como se ha explicado, pero resulta
transparente al cliente. El mecanismo puede cambiar en aquellos entornos en los que
el servicio de eventos no resulte conveniente o no esté disponible, sin que afecte la
forma en que los clientes utilizan la aplicación.
Existe una forma sencilla de listar los suscriptores a través de la interfaz
DUO::Container.
Proporciona un servicio de distribución basado en invocaciones para aquellos
middlewares en los que el servicio de eventos está orientado a datos, como ocurre
en el EventService de CORBA.
Proporciona un mecanismo elegante de comprobación de tipo para aquellos
middlewares que no lo tienen por defecto en su servicio de eventos, como ocurre en
IceStorm.
Cuando se usa un composite para distribución solo existe un método set() (el del
propio actor compuesto). Este método debe ser el encargado de hacer llegar el dato
a cada actor agregado por el medio más conveniente en el dominio de la aplicación
concreta, aunque tal como se ha indicado, el más sencillo y eficiente suele ser el servicio
de eventos que incorpora el middleware.
Por supuesto, también es posible y útil implementar un composite para actores que
sean al tiempo R y W. Como ejemplo, suponga un edificio en el que se dispone de
cerraduras automatizadas para bloquear el acceso a partir de una hora o a una zona. Si
esta cerradura está controlada con un actor booleano que implementa R y W, se puede leer
y modificar su estado (bloqueado/desbloqueado). Si todos estos actores se añaden a un
composite del mismo tipo, podríamos manipular todas las puertas con un solo mensaje.
Pero además podrían estar disponibles funciones de agregación como any o all que
informarían respectivamente si hay alguna puerta bloqueada o todas lo están.
3.7.
Composición básica de servicios
El diseño de las interfaces DUO hace posible un modelo de despliegue de servicios
básicos extremadamente simple y robusto. Dado que la definición de las interfaces fuerza
una comprobación estricta de tipos, el propio middleware puede garantizar la consistencia
del modelo de información de toda la aplicación.
3.7.1.
Cableado virtual
Utilizando actores activos es posible realizar conexiones lógicas dinámicas entre
servicios. Sobre un sistema en explotación y utilizando específicamente la interfaz
DUO::Active::W, un operador del sistema puede reconfigurar dinámicamente el observador
de cualquier actor, o bien crear y destruir canales de eventos relacionados. De ese
modo, los consumidores de los datos producidos por los dispositivos del sistema pueden
ser reasignados en cualquier momento por decisión del operador o de un servicio
específico de alto nivel.
i
i
i
i
i
i
i
i
98
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
Denominamos a este mecanismo cableado dinámico virtual (dynamic virtual wiring)
debido a que permite crear y gestionar un conjunto de relaciones unidireccionales entre
actores (cableado) que pueden cambiar sin afectar al resto del sistema (dinámico) y que
están completamente desacopladas de la topología de red o tecnología de comunicaciones
subyacente (virtual).
Este cableado tiene la ventaja adicional de que la información necesaria para establecer
las relaciones se encuentra en los mismos nodos en los que están alojados los actores. Eso
significa que, una vez configurado, el sistema es autosuficiente. La única infraestructura
requerida es la red de comunicaciones.
Si se utiliza el servicio de eventos, obviamente también se requiere un computador
que aloje el servicio. Sin embargo, es viable crear una versión empotrada de dicho
servicio que puede ser implementada en plataformas similares a las marcadas como
objetivo para nuestros transductores.
3.7.2.
Servicios reactivos
Mediante el cableado virtual es posible desplegar servicios reactivos básicos, pero
capaces de solventar un alto porcentaje de las necesidades de automatización de un
entorno inteligente. El caso más simple (y más común) implica la conexión lógica
de un sensor y un actuador.
En este escenario, cuando el sensor detecta un cambio en su entrada, dispara la ejecución
de una acción por parte del actuador. Esto sólo tiene sentido cuando el tipo del sensor y
el actuador son compatibles, por ejemplo, un sensor de presencia todo/nada que activa la
apertura de una puerta motorizada. Si bien se trata de un servicio funcionalmente trivial,
resuelto anteriormente por infinidad de tecnologías, en nuestro caso presenta grandes
ventajas que raramente se encuentran en otras propuestas:
No existe ningún intermediario y, sin embargo, no es un sistema aislado.
Tanto el sensor como el actuador pueden ser operados por terceros sin romper la
relación existente.
La relación es persistente, pero remotamente reconfigurable. Un operador del sistema
puede modificar la configuración del sensor por medio de invocaciones remotas para
designar otro actuador (observador).
3.7.3.
Relaciones n-arias
El mismo esquema se puede utilizar para desplegar servicios reactivos que implican a
varios actores. Para algunas situaciones ni siquiera se requieren canales de eventos, como
el caso en el que varios sensores operan sobre un actuador.
Supongamos un escenario algo más complejo. La apertura de cualquier puerta de
emergencia de un edificio activa una señal acústica para alertar al personal de seguridad.
En ese caso, los elementos involucrados implican los siguientes requisitos:
Las puertas están equipadas con un sensor proactivo que implementa la interfaz
DUO::IBool::R.
i
i
i
i
i
i
i
i
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
99
Cuando la puerta se abre, el estado del sensor cambia a True.
La señal acústica está controlada por un actuador que implementa la interfaz
DUO::IBool::W. Se activará al recibir un mensaje set(True) y se desactivará
al recibir un mensaje set(False).
La interconexión de estos actores puede realizarse de tres modos:
Se crea un canal de eventos (T) y se asigna el publicador de ese canal (TP) a todos
los sensores de las puertas mediante su método setCbTopic(). Requiere que los
sensores sean DUO::Active::W. El actuador se suscribe al canal T. Ver figura 3.4a.
Se crea un canal de eventos (T) y se federan (enlazan) los canales de todos los
sensores (T1-Tn). Requiere que los sensores implementen DUO::Active::R y que
dispongan de un canal propio, es decir, que su método getTopic() devuelva un
proxy no nulo. El actuador se suscribe al canal T. Ver figura 3.4b.
Se asigna el proxy del actuador alarma (A) como observador a todos los
sensores mediante el método setCbTopic(). Necesita que los sensores sean
DUO::Active::W, pero no es obligatorio un servicio de eventos. Sin embargo, esta
solución es menos flexible en cuanto a posibilidades de gestión, ya que no hay
un modo sencillo de averiguar qué sensores están lógicamente conectados. Ver
figura 3.4c.
La elección del tipo de interconexión a realizar dependerá de las necesidades específicas
de la aplicación concreta. Por ejemplo, el tercer método no permite añadir nuevos
consumidores para esos mensajes a menos que los actuadores cuenten con direcciones
multicast.
En todos los casos, se cumple el principio de autonomía que se indicaba en la sección
anterior. Cualquier cliente puede consultar el estado de los sensores, y puede leer y escribir
sobre el actuador sin que ello afecte a las relaciones establecidas.
3.8.
Consulta múltiple
En las redes de sensores es habitual que un agente o servicio externo necesite consultar
el valor de un conjunto de sensores en el mismo instante, por ejemplo, para realizar un
mapa que represente el nivel de humedad de una explotación agraria o un campo de fútbol,
instalando una cantidad considerable de sensores. El objetivo es evitar la necesidad de
enviar un mensaje de consulta dirigido específicamente a cada uno de los sensores. La
solución propuesta pasa por usar actores reactivos (véase § 3.4.1).
Para recibir los eventos con el estado de cada sensor, el cliente crea un nuevo canal
recolector. Se enlazan a éste los canales de todos los sensores involucrados. Dicho canal
puede ser reutilizado para sucesivas consultas, siempre que involucre a los mismos actores.
Si los nodos tienen algún tipo de relación funcional o estructural es factible crear estos
canales automáticamente. Todos los clientes interesados en recibir el valor de los sensores
se suscriben al canal recolector (o son suscritos por un tercero). El diagrama de secuencia
de la figura 3.5 muestra todo el proceso.
i
i
i
i
i
i
i
i
100
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
F IGURA 3.4: Ejemplo de cableado virtual. Tres alternativas: a) Fijando el canal de los
actores activos, b) Enlazando sus canales y c) Sin utilizar el servicio de eventos
El mensaje que dispara el proceso —el método ice_ping()— debe llegar a todos los
sensores reactivos involucrados utilizando un canal de consulta. La forma más conveniente
de implementar este canal sería que los sensores tuvieran un endpoint multicast adicional,
pero eso no siempre es posible pues depende de la tecnología de red subyacente. En
esos casos se puede utilizar un canal de eventos adicional.
A dicho canal se suscriben todos los sensores. Nótese que esta operación de suscripción
la realiza la aplicación cliente (o, en su defecto, un servicio especializado), pero nunca
el propio sensor.
Una vez interconectados los objetos como se ha explicado, una invocación ice_ping() sobre el canal de consulta provoca que cada sensor reaccione enviando el
valor de su estado actual a su canal. Al estar éstos enlazados al canal recolector, la
aplicación recibirá un mensaje set() por cada sensor. Dado que el segundo parámetro
de ese mensaje es la identidad del emisor, la aplicación tiene constancia de a qué sensor
i
i
i
i
i
i
i
i
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
101
F IGURA 3.5: Diagrama de secuencia de una consulta múltiple
corresponde cada valor, información que puede utilizar a efectos de contabilidad, estadística
o representación gráfica del entorno.
Nótese que aunque el proceso se ha explicado refiriéndose a sensores exclusivamente (por
continuidad con el ejemplo inicial), el mecanismo de consulta múltiple es perfectamente
aplicable sin ninguna diferencia para un conjunto de actuadores o también a una mezcla
de ambos, a condición de que todos ellos sean reactivos y del mismo tipo.
La diferencia evidente respecto a los actores compuestos es que la consulta múltiple
se utiliza cuando se necesita el valor de todos los sensores y no el resultado de una
función de agregación. Sin embargo, ambos mecanismos se pueden combinar haciendo
que el composite reenvíe también la invocación de su método ice_ping() a los actores
agregados y proporcionando automáticamente el canal de eventos recolector.
3.9.
Conclusiones
DUO es un modelo de información completo para el desarrollo de sistemas en los
que intervienen transductores y redes de transductores de todo tipo. Se sustenta en
el principio de que todo sensor o actuador es un objeto, en todas sus acepciones y
durante todo el ciclo de vida del sistema o aplicación, desde la captura de requisitos
hasta el mantenimiento y explotación.
i
i
i
i
i
i
i
i
102
3. O BJETOS D ISTRIBUIDOS U NIVERSALES
DUO proporciona interfaces simples y escalables para cualquier tipo de transductor, pero
también para realizar descomposición funcional de dispositivos más complejos, en los que
se requiere acceso individual a los elementos que lo conforman. Dispone de interfaces para
agrupación y agregación, objetos virtuales, navegación de facetas, interconexión dinámica
de objetos, actualización asíncrona, distribución de eventos, etc.
Su diseño no promueve ni asume la existencia de una sola forma correcta de solucionar
el problema. Al contrario, proporciona herramientas genéricas que trabajan bien juntas,
con bajo acoplamiento y alta cohesión. Facilita el diseño de sistemas adaptándose a
las restricciones o necesidades del entorno: lenguaje, middleware, disponibilidad de
sus servicios, etc.
La utilización de estas interfaces facilita sensiblemente la integración en cualquier
sistema automatizado o de información, puesto que el acceso al transductor se hace
utilizando un API local proporcionada por el middleware a través del proxy correspondiente,
todo ello de un modo predecible y estandarizado.
Se integra perfectamente con el dominio del problema que se trata de modelar, dado que
aporta conceptos de alto nivel respetando el paradigma de la OO y aplicando conceptos
y patrones de diseño clásicos. Los transductores pasan a ser entidades básicas en el
modelado del sistema, simplificando los procesos de captura de requisitos, análisis,
diseño y, particularmente, la implementación. El personal involucrado en el desarrollo
no requiere formación específica, sea cual sea la tecnología empleada por el fabricante
de los dispositivos o la red de datos utilizada. Cualquier programador o diseñador,
acostumbrado a trabajar con objetos distribuidos de cualquier tecnología, inmediatamente
puede comprender y aplicar DUO al desarrollo de soluciones que integran redes de
transductores de manera natural.
A pesar de otorgar interfaces de alto nivel a simples transductores, la sobrecarga de
implementación puede ser realmente baja. Los mensajes que se intercambian, incluso
siendo conformes al protocolo inter-ORB, son pequeños y regulares. Por ello, DUO es un
modelo de información especialmente adecuado para plataformas con pocos recursos de
cómputo, memoria, energía y ancho de banda. En resumen, DUO es un buen candidato
para construir una «Internet de cosas».
i
i
i
i
i
i
i
i
picoObjetos
4.1.
4.2.
4.3.
4.4.
4.5.
4.6.
4.7.
4.8.
4.9.
4.10.
Introducción
Una estrategia diferente
Interoperabilidad
Funcionamiento del picoObjeto
Especificación de picoObjetos
Transformación de FSM a bytecode
Máquina virtual
Generación de código nativo
Despliegue de aplicaciones en la SAN
Conclusiones
44
E
L modelo de información e interacción propuesto en el capítulo anterior proporciona
una imagen minimalista y homogénea de las redes de sensores en entornos
heterogéneos. No se ha sacrificado ningún aspecto de la riqueza de modelos de interacción
disponibles, pero además debe ser complementado con un modelo de ejecución y
despliegue de objetos distribuidos que pueda ser implementado en las tecnologías de
redes de sensores actuales.
El presente capítulo es una descripción detallada de la propuesta que realiza esta tesis
para obtener implementaciones mínimas funcionales de objetos distribuidos, llamados
picoObjetos, en middlewares de comunicaciones de propósito general.
Después de comentar las pautas iniciales, se introducen las restricciones de interoperabilidad y criterios de diseño para dos casos concretos: picoCORBA y picoIce. A continuación,
se establecen las bases de la solución y del modelo de ejecución de código propuesto.
4.1.
Introducción
Nuestra motivación principal es proporcionar una infraestructura para el desarrollo
de aplicaciones distribuidas sobre dispositivos como los que se utilizan habitualmente
en las redes SAN, pero también cualquier otro elemento de cómputo conectado a una
red —independientemente de su complejidad y capacidades— que sea susceptible de
ser integrado en un entorno inteligente o automatizado.
Un aspecto clave de este enfoque es la posibilidad de utilizar exactamente la misma
metodología de desarrollo empleada tradicionalmente en los MDOO para diseñar y
desarrollar aplicaciones y servicios que involucran redes de sensores.
103
i
i
i
i
i
i
i
i
104
4. picoObjetos
Empecemos analizando cómo se produce una invocación sobre un método remoto. En
un MDOO, una invocación remota implica la cooperación de una cantidad considerable de
entidades: uno o más adaptadores de objetos, un conjunto de sirvientes que implementan
el comportamiento de los objetos, y un mapa de objetos activos que supervisa las
relaciones entre objetos y sirvientes.
Cada invocación a método remoto se traduce, al menos, en una petición (un mensaje)
que incluye tres importantes componentes:
La identidad del objeto, que identifica unívocamente al objeto destino en toda la red
o, al menos, de modo que no sea posible un conflicto dentro del mismo dominio.
La operación, que determina qué método del sirviente se ha de ejecutar.
Un conjunto de argumentos necesarios para llevar a cabo la operación.
Cualquier interacción entre un cliente y un objeto se consigue exclusivamente por el
paso de mensajes usando el protocolo estandarizado (GIOP en CORBA o I CE P en ZeroC
I CE). Por tanto, cualquier implementación de un objeto sigue siendo compatible siempre
que cumpla el protocolo inter-ORB correspondiente.
Como se vio en el capítulo 2, todos estos sistemas tienen un flujo de desarrollo
muy similar. El proceso de desarrollo tradicional de aplicaciones distribuidas basado
en modelos de programación de objetos empieza con la descripción de las interfaces
remotas que ofrecen los objetos (el contrato). Después, se utiliza un compilador para
generar automáticamente tanto los cabos del cliente como el esqueleto del servidor
para cada interfaz.
La figura 4.1 muestra dos implementaciones compatibles y, sin embargo, muy diferentes.
La figura 4.1a es una simplificación de un diagrama de secuencia que muestra una
invocación tal como la realiza cualquier middleware tradicional. La figura 4.1b muestra
el comportamiento de la propuesta de este trabajo.
La idea básica es conseguir máquinas de estados capaces de reconocer los mensajes
procedentes de los clientes a través de una interfaz de red y generar respuestas válidas. De
ese modo, su comportamiento será indistinguible de un objeto distribuido convencional.
Con este enfoque es posible obtener programas con tamaños, dependencias y restricciones
adecuados para su implementación en plataformas empotradas con recursos de cómputo
gravemente limitados.
Sin embargo, no es sólo una cuestión de tamaño. Hemos fijado una serie de requisitos
que deben cumplir los picoObjetos y, a pesar de que ello implica cierta complejidad
adicional, consideramos que son lo suficientemente importantes como para asumir el
impacto que supone sobre el consumo de recursos:
Autonomía
La principal característica de los picoObjetos es que son autónomos. Eso garantiza
que una red compuesta por picoObjetos puede funcionar de forma independiente.
Los nodos y los servicios básicos seguirán trabajando incluso aunque todas las
pasarelas de servicio fallen. Esta característica es crucial para conseguir un sistema
lo suficientemente robusto, confiable y tolerante a fallos.
i
i
i
i
i
i
i
i
4. picoObjetos
105
(a)
(b)
F IGURA 4.1: Comparación de la invocación de un método remoto a un objeto
implementado en un middleware convencional (a) y a un picoObjeto (b)
Los elementos intermedios tales como las pasarelas que propone OMG STI [Obj03] u
OSG I [All06] suponen además puntos únicos de fallo, encarecimiento y dependencia
funcional. Debería ser posible implementar servicios autónomos garantizados, sin
que ello dependa de la disponibilidad o estado de cualquier pasarela o servicio
externo. Obviamente, en muchos casos sigue siendo necesaria la conectividad con el
exterior, pero utilizando pasarelas sencillas, sin estado, que únicamente transportan
mensajes entre dos o más redes, pero no intervienen en absoluto en el funcionamiento
de la aplicación.
Objetos distribuidos
Se trata de obtener dispositivos empotrados que ofrezcan sus capacidades como si
fuesen objetos distribuidos convencionales, indistinguibles de los implementados
con las herramientas y bibliotecas suministradas por el fabricante.
i
i
i
i
i
i
i
i
106
4. picoObjetos
Sistema heterogéneo
Los picoObjetos deben ser capaces de ocultar sus características internas: la
plataforma hardware sobre la que se hallan, las tecnologías de comunicaciones
subyacentes, los protocolos de transporte y red empleados, etc.
Para dotar de un núcleo de comunicaciones a dispositivos con muy escasos recursos
de cómputo y memoria, la técnica habitual, que sigue manteniendo compatibilidad, es
recortar o eliminar sus capacidades más complejas (véase § 2.4). El principal servicio que
el núcleo de comunicaciones presta a los objetos es el soporte para el envío y recepción de
mensajes conforme a las reglas del protocolo concreto, ocupándose de la codificación y
serialización de datos y consiguiendo, de ese modo, una comunicación transparente con
los clientes. Al mismo tiempo, el programador de la aplicación distribuida no tiene que
preocuparse de todos esos detalles, evitando muchos errores recurrentes.
La disponibilidad de un protocolo de alto nivel para la comunicación entre pares dentro
del middleware permite que desde el exterior el objeto se pueda ver con dos enfoques:
A nivel de programa
Cualquier objeto remoto es como un objeto local. El núcleo de comunicaciones
se encarga de crear en el espacio de memoria local del cliente un delegado del
objeto remoto, llamado proxy en la terminología específica. Ese nombre se debe
a que realmente se trata de una implementación automática del patrón de diseño
remote proxy [GHJV96]. Desde este enfoque, la aplicación no conoce —no necesita
conocer— la ubicación física y lógica del objeto al que se está invocando.
A nivel del bus
Con un segundo enfoque de más bajo nivel, el objeto puede verse desde la red como
un servidor que implementa un pequeño protocolo inter-ORB.
Si la intención es buscar objetos mínimos, ese segundo enfoque puede resultar muy
conveniente. En el caso extremo, permite eliminar todo el núcleo de comunicaciones y
substituirlo por el código necesario para dar soporte al protocolo concreto que le afecta.
Tras nuestra experiencia en este asunto, esa parece ser la única estrategia que hace viable
alojar un objeto distribuido en un dispositivo que está lejos de poder dar cabida a cualquier
ORB convencional, incluso ateniéndose a las limitaciones de Minimum CORBA.
Concretando, la propuesta consiste en implementar un pequeño núcleo de comunicaciones generado completamente a la medida de los mensajes que debe responder
e invocar el nodo. Dicho núcleo está constituido por una máquina de estados jerárquica y las utilidades mínimas necesarias para ejecutar el código de los métodos del
sirviente asociado a cada objeto.
El código generado no se puede considerar una biblioteca dado que puede variar
sustancialmente de una implementación a otra. Esta estrategia es útil porque no se
genera un conjunto de servicios comunes para los objetos. Al contrario, cada servidor
implementa ad hoc la funcionalidad mínima imprescindible para cubrir las necesidades
del conjunto de objetos que reside en el nodo. Es decir, el código generado para cada
servidor es esencialmente distinto al de cualquier otro dado que el conjunto de objetos
y sus tipos determinan la mayor parte.
i
i
i
i
i
i
i
i
4. picoObjetos
107
El código generado no se puede considerar un ORB puesto que no están disponibles
servicios habituales —pero exclusivos— que no tienen relación directa con los objetos.
Tales servicios incluyen, por ejemplo, la indirección y localización de objetos. Sólo se
responde a mensajes dirigidos específicamente a algún objeto alojado en el servidor.
Como su nombre indica, la principal finalidad de los picoObjetos es la implementación
de objetos, entendiendo el objeto como el ente pasivo que presta servicios bajo demanda
(véase § 2.3.1). Sin embargo, resulta también muy conveniente dotar a los dispositivos
de capacidades como clientes, es decir, la posibilidad de realizar invocaciones a otros
objetos. Eso permite prestar servicios muy interesantes, como actualización asíncrona
de observadores del transductor (véase § 3.4), anunciamiento de servicios (véase § 5.4),
etc. Éstas y otras características se discutirán a lo largo del texto.
Estas invocaciones deben ser oneway, es decir, no se espera ni se procesa respuesta
alguna. Esa asunción simplifica la implementación pues no se requieren otros autómatas
para reconocer cada una de las respuestas posibles. Aunque esta restricción resta algo de
potencia y flexibilidad, el ahorro en complejidad resulta conveniente. Estas invocaciones
se utilizan para informar a terceros y no para solicitar información.
Teniendo en cuenta estos condicionantes, podríamos dar una definición informal
de picoObjeto como:
Una entidad autónoma capaz de procesar, responder y enviar invocaciones a métodos
remotos conforme a un protocolo definido por un MDOO. Implementa una máquina
de estados generada ad hoc para un dispositivo con acceso a una red de datos, que
integra uno o más transductores y los ofrece al sistema como objetos distribuidos
convencionales.
4.2.
Una estrategia diferente
Minimum CORBA (véase § 2.4.1) propone un modelo simplificado de ORB manteniendo
interoperabilidad con la arquitectura CORBA.
Aunque el alcance de los picoObjetos no está limitado a la norma CORBA y, como hemos
visto, Minimum CORBA no es la única iniciativa de miniaturización, sí es un buen referente
para comparar las prestaciones y limitaciones de la implementación de picoObjetos para
CORBA (picoCORBA) y, por extensión, las de otros middlewares.
Los objetos CORBA convencionales están conectados a un ORB que le proporciona los
servicios básicos de comunicación. Los objetos Minimum CORBA se programan y utilizan
del mismo modo. En contraste, los picoObjetos deben integrar ellos mismos todos los
servicios proporcionados. Los sirvientes no se registran para ser accesibles; no existe un
adaptador de objetos explícito, aunque sí un mapa de objetos rudimentario. Todo ello
implica un gran ahorro de complejidad y memoria también respecto a Minimum CORBA.
La figura 4.2 muestra de forma visual las diferencias de picoCORBA en relación a
CORBA y Minimum CORBA.
Veamos en qué medida cumplen los picoObjetos los objetivos de Minimum CORBA
y las diferencias entre ambos:
i
i
i
i
i
i
i
i
108
4. picoObjetos
F IGURA 4.2: Representación gráfica de CORBA (a), Minimum CORBA (b) y picoCORBA (c)
Portabilidad – Un servidor escrito para Minimum CORBA se puede compilar y ejecutar
en otro ORB sin ningún cambio. Por contra, un picoObjeto no tiene ningún soporte
de portabilidad puesto que es monolítico y autocontenido. Las únicas bibliotecas con
las que se enlaza serán las del runtime estándar y las del soporte de comunicaciones
disponible en la plataforma objetivo.
Interoperabilidad – Puesto que los servidores de picoObjetos implementan directamente el protocolo inter-ORB e interactúan directamente con el núcleo de comunicaciones del cliente, la interoperabilidad está garantizada.
Soporte del lenguaje de especificación de interfaces – El compilador de picoObjetos incluye soporte para los tipos de datos básicos y para los mecanismos de composición como estructuras o secuencias. También proporciona soporte a tipos complejos
concretos como identidades o proxies, dada su relevancia.
Por supuesto, nuestro objetivo en la reducción de recursos va más allá que
Minimum CORBA u otras iniciativas. Nos planteamos dos requisitos adicionales:
Funcionalidad mínima – Definiendo el objeto mínimo que sigue teniendo un
comportamiento compatible y respetando los requisitos imprescindibles de
interoperabilidad, aunque en ocasiones puedan quedar acotados a una aplicación o
entorno concreto.
Dimensionamiento – Diseñando e implementando mecanismos que permitan adaptar
y adoptar funcionalidades deseables aunque no esenciales según las capacidades de
cómputo y memoria de la plataforma concreta.
i
i
i
i
i
i
i
i
4. picoObjetos
109
En relación a Minimum CORBA, los objetos picoCORBA hacen mucho más que reducir
prestaciones. Éstos ofrecen un grado de portabilidad mucho menor dado que pueden
implementarse en un lenguaje ensamblador específico. Incluso los que están implementados
en C o Java no respetan en absoluto el mapping que define OMG.
Algunos de estos lenguajes, incluso de propósito específico, ni siquiera han sido
considerados por el estándar; por supuesto no existe ninguna implementación del
middleware que ofrezca una biblioteca de soporte para esos lenguajes.
4.2.1.
El objeto mínimo
En lugar de buscar características prescindibles como medio para lograr la reducción
de requerimientos hardware, decidimos plantear el problema desde el otro extremo,
con una filosofía bottom-up. Definimos las características funcionales mínimas de la
entidad lógica que podemos seguir considerando como objeto distribuido. A partir de ahí
podremos evaluar la sobrecarga que supone añadir otras prestaciones que impliquen un
mayor nivel de interoperabilidad y cumplimiento de la norma aplicable, o que supongan
características funcionales adicionales.
Aunque la plataforma objetivo son dispositivos muy pequeños y baratos, además de los
dispositivos habituales en el mundo de las redes SAN, el modelo propuesto permite —en
principio— implementar cada detalle de un núcleo de comunicaciones convencional de
modo que la solución se podría aplicar a cualquier tamaño y complejidad.
Sin embargo, utilizar el modelo de picoObjetos para una implementación completa de
un núcleo de comunicaciones que cuente con adaptadores de objetos, serialización de tipos
complejos, mecanismos de indirección, etc., podría llegar a ser complejo e ineficaz por la
dificultad intrínseca para manejar un entorno dinámico, resultando una mala alternativa a la
implementación de un ORB convencional. El único caso en el que se podría justificar dicho
uso sería en entornos muy específicos en los que fueran cruciales las consideraciones de
tiempo real o de confiabilidad, precisamente por la naturaleza estática y determinista
del modelo de ejecución de los picoObjetos.
A continuación se definen algunas consideraciones adicionales al conjunto mínimo
de prestaciones generales anteriores:
1. Siempre se cumple el formato de mensajes del protocolo inter-ORB de cada
middleware. Aunque puede haber mensajes no soportados, los que se soportan
no sufren modificaciones. Consideramos que usar protocolos modificados (como
el protocolo GIOPLite de MicroQoSCORBA [Hau01] o nORB [SXGC03])
conlleva necesariamente la utilización de pasarelas, responsables de la traducción de
protocolos para lograr la interoperabilidad con los ORB S estándar. Ello supondría
una contradicción a nuestra intención de hacer dispositivos directamente accesibles
desde una red de comunicaciones común.
2. Únicamente se ofrece soporte a la versión más simple del protocolo, siempre que
ello no repercuta negativamente en la interoperabilidad, por ejemplo, protocolos
obsoletos.
i
i
i
i
i
i
i
i
110
4. picoObjetos
3. Los objetos que residen en un nodo están siempre activos (always on). No hay
ningún modo de activar objetos adicionales o desactivar los que ya existen.
4.3.
Interoperabilidad
Existen gran cantidad de detalles que deben considerarse cuando se desea realizar
una implementación empotrada de un middleware comercial convencional. Esta sección
muestra cómo se han tomado en cuenta las restricciones específicas de dos middlewares
distribuidos concretos para obtener implementaciones empotrables eficientes: CORBA
e I CE.
4.3.1.
picoCORBA
En esta sección se explican las decisiones de diseño que se han tomado en picoCORBA
respecto al formato de los mensajes y otras características del protocolo GIOP. Se analiza
el soporte ofrecido para cada tipo de mensajes y sus implicaciones en la compatibilidad con
el middleware. Todas las alusiones a GIOP se refieren al capítulo 15 de la especificación
CORBA [COR02]; el anexo D es un resumen de dicho documento.
Una primera medida para simplificar el proceso consiste en utilizar identidades de objeto
(el campo object_key) de tamaño fijo, tal como hacen otras propuestas, por ejemplo,
MicroQoSCORBA (véase § 2.4.8). La identidad aparece en la referencia pública del objeto
(la IOR) y la norma especifica que los clientes deben utilizarla sin modificaciones. Es
decir, no plantea ningún problema de interoperabilidad.
Versión de GIOP
Se ofrece soporte únicamente para GIOP versión 1.0. Aunque los clientes dispongan
de soporte para versiones posteriores del protocolo, la especificación obliga al cliente
a utilizar una versión igual o inferior a la que el servidor indique en la referencia del
objeto. Por tanto, si el servidor (el objeto) opta por utilizar la versión 1.0, eso asegura
compatibilidad total con cualquier cliente actual o futuro.
Por la misma razón, cuando un objeto picoCORBA actúa como cliente, genera mensajes
de petición con GIOP 1.0, lo que asegura que cualquier servidor podrá procesarlos
adecuadamente.
Las revisiones posteriores del estándar GIOP han añadido funcionalidades relacionadas
con:
Direccionamiento indirecto de objetos a otros ORB S.
Fragmentación de mensajes.
GIOP bi-direccional.
Estas prestaciones quedan fuera de los objetivos marcados para picoObjetos. Resulta
muy conveniente tener la posibilidad de obviarlas pues su implementación supondría
un grave impacto sobre los requerimientos de memoria necesarios, puesto que la norma
obliga además a cumplir todas las versiones inferiores.
i
i
i
i
i
i
i
i
4. picoObjetos
111
Ordenamiento
La especificación GIOP indica que el extremo que inicia la comunicación determina cuál
será el ordenamiento de bytes (big endian, little endian) mientras dure la conexión. En el
caso de GIOP 1.0, el iniciador de la conexión es siempre el cliente. El servidor debe realizar
la conversión cuando sea necesario y responder con el ordenamiento que use el cliente.
Debido al enfoque minimalista del diseño de los picoObjetos, implementar ambos
ordenamientos obliga a prácticamente duplicar el código necesario para el reconocimiento
de los mensajes. Aunque puede incrementar sensiblemente la cantidad de código, si la
aplicación lo requiere, tal posibilidad es perfectamente factible.
Sin embargo, en la mayor parte de los casos, los picoObjetos se utilizarán para
implementar nodos de una red instalada en un entorno acotado en los que este aspecto
se puede controlar, pudiendo soportar sólo el ordenamiento necesario. Por tanto, incluso
soportando únicamente uno de los ordenamientos, no habría problemas de interoperabilidad
con los clientes, que pueden ser desarrollados de la forma habitual.
CORBA::Object
Todo objeto CORBA está obligado a implementar un conjunto de métodos comunes
que corresponden a la interfaz heredada CORBA::Object (véase § 2.3.3).
A pesar de que, desde el punto de vista del cliente, estos métodos se utilizan del
mismo modo que los definidos en la especificación IDL, lo cierto es que el código
asociado no tiene relación directa con el sirviente. En su lugar, el ORB o el esqueleto
del servidor captura y responde estas invocaciones sin que lleguen al sirviente que
implementa el programador.
Aunque esta interfaz incluye bastantes métodos, algunos de ellos son atendidos
de forma local por el ORB del cliente (duplicate(), release() o is_nil()). De
entre los que requieren acceder al ORB remoto, el picoObjeto mínimo solo requiere
implementar dos de ellos:
non_existent()
Permite a un cliente comprobar si el objeto sigue vivo.
is_a()
Ofrece prestaciones mínimas de introspección, necesarias para poder averiguar qué
interfaces implementa un objeto una vez obtenido un proxy genérico.
A diferencia de lo que ocurre en un ORB convencional, estos métodos son
procesados y respondidos por el picoObjeto ya que no dispone de un ORB. Se genera
una implementación automática que se incorpora implícitamente a cualquier objeto
picoCORBA sin que el programador necesite indicar nada al respecto.
Mensajes GIOP
GIOP 1.0 define tres tipos de mensajes que el cliente puede enviar al servidor: Request,
LocateRequest y CancelRequest, y tres más que el servidor puede enviar al cliente:
i
i
i
i
i
i
i
i
112
4. picoObjetos
Reply, LocateReply y CloseConnection, más un mensaje MessageError que pueden
enviar ambos ante una situación de error.
Cabecera GIOP Los objetos picoCORBA reconocen y generan cabeceras GIOP
estándar. La única peculiaridad es que el campo GIOP_version es siempre 1.0 y en
la implementación mínima solo se soporta uno de los ordenamientos, por tanto, el
campo byte_order es constante.
Petición Los mensajes de petición (Request) son invocaciones de métodos del objeto
remoto. Se toman las siguientes consideraciones:
El campo service_context se ignora.
El valor del campo response_expected se ignora. Los picoObjetos siempre generan
respuestas aunque no se soliciten. Se trata de un comportamiento correcto porque
los clientes ignoran a su vez respuestas no solicitadas.
El campo requesting_principal está obsoleto y se ignora.
Respuesta El objeto envía mensajes de respuesta (Reply) al recibir un mensaje de
invocación y ejecutar con éxito el código asociado. Si el mensaje de petición es incorrecto,
está mal formado o simplemente no coincide con lo que la máquina de estados espera,
el objeto no responderá a esa petición y quedará a la espera del siguiente mensaje. En
la versión mínima, picoCORBA no ofrece soporte para ningún tipo de excepción. La
máquina aprovecha partes del mensaje de petición para construir el mensaje de respuesta,
además de los valores de los parámetros de salida y valor de retorno que resultan de la
ejecución del procedimiento de usuario correspondiente.
Sobre los campos del mensaje:
service_context – Se genera un contexto vacío. Opcionalmente se puede considerar
un objeto que copia byte a byte el valor que tuviese este campo desde el mensaje de
petición.
request_id – Se copia el valor que llega en la petición.
reply_status – Dado que no se soportan excepciones, el valor de este campo es siempre
NO_EXCEPTION.
Nótese que lo explicado se refiere al objeto mínimo. Es posible añadir soporte básico
de excepciones para informar sobre objetos o métodos desconocidos.
Cancelación de petición Los objetos picoCORBA ignoran completamente los mensajes
de cancelación de petición (CancelRequest). El nodo procesa y ejecuta la operación
solicitada a pesar de que el cliente envíe un mensaje de cancelación. La norma permite
explícitamente este comportamiento.
i
i
i
i
i
i
i
i
4. picoObjetos
113
Localización Los mensajes de localización (LocateRequest/LocateReply) se utilizan para dar soporte a los mecanismos de transparencia de localización del middleware. Los picoObjetos no tienen por sí mismos capacidad para localizar otros objetos dado que esta característica correspondería a un hipotético ORB. Por tanto, ni se
atienden ni se generan estos mensajes.
Cierre de conexión El mensaje de cierre de conexión (CloseConnection) lo utiliza el
servidor para indicar al cliente que dejará de estar disponible en breve. Esta situación
no se contempla en picoCORBA puesto que se asume que los nodos en los que se
ejecuta el picoObjeto están siempre conectados.
Error Los mensajes de notificación de error (MessageError) sirven para indicar al
emisor que la invocación que ha enviado es un mensaje incorrecto, mal formado o que
corresponde a una versión de GIOP incorrecta. Dado que picoCORBA ignora los mensajes
incorrectos o no soportados, tampoco genera este tipo de mensaje.
Tampoco es capaz de procesarlos si provienen de un cliente. Tal circunstancia implicaría
un fallo en la implementación del picoObjeto, y al ser ésta completamente estática no
hay mucho que el nodo pueda hacer al respecto.
Resumen
Se muestra a continuación un breve resumen de las decisiones de diseño que se han
expuesto en esta sección. Un servidor picoCORBA mínimo:
Ignora todos los mensajes que no vayan dirigidos a uno de los objetos alojados en el
nodo. Es decir, si la identidad del objeto que aparece en el mensaje no es una de las
que se indicaron al generar la implementación, el mensaje de invocación se descarta
silenciosamente.
Solo soporta uno de los ordenamientos e ignora los mensajes que pueda recibir con
un ordenamiento distinto.
Únicamente implementa los métodos heredados is_a() y non_existent().
Ignora los mensajes CancelRequest, LocateRequest y MessageError y nunca
genera CloseConnection ni MessageError.
4.3.2.
picoIce
En esta sección se explican las decisiones de diseño que se han tomado en picoIce
respecto al formato de los mensajes y otras características del protocolo I CE P. Se analiza
el soporte ofrecido para cada tipo de mensaje y sus implicaciones en la compatibilidad
con el middleware. Todas las alusiones a I CE P se refieren al capítulo 38 del manual de
referencia de I CE [HS08]; el anexo C es un resumen de dicho capítulo.
A pesar de que actualmente tiene poco soporte para plataformas empotradas, I CE ofrece
varias ventajas respecto a CORBA en la reducción del uso de recursos. El protocolo I CE
es más simple que GIOP debido a varios motivos:
i
i
i
i
i
i
i
i
114
4. picoObjetos
Los mensajes son siempre little endian.
Soporta protocolos de transporte no confiables como UDP, mucho más sencillos de
implementar en dispositivos empotrados de bajo coste.
Existen menos tipos de mensajes y algunos de ellos pueden ser obviados sin
comprometer la interoperabilidad.
Los campos no procesados se pueden saltar fácilmente porque van precedidos por
un campo que indica su longitud.
No se realiza alineamiento de palabras al serializar los mensajes.
ICE::Object
Del mismo modo que con CORBA, todos los objetos I CE implementan por defecto
la interfaz ICE::Object (véase § 2.3.4).
Los objetos picoIce implementan todos los métodos remotos definidos en la interfaz
por lo que está garantizado un comportamiento estándar también a ese nivel.
Mensajes I CE P
Los objetos picoIce soportan todos los mensajes I CE P exceptuando BatchRequest.
Eso no supone ningún problema de interoperabilidad dado que el envío por lotes es
únicamente una característica opcional para optimización del ancho de banda. Se utilizan
cabeceras I CE P convencionales aunque el campo compressionStatus debe ser siempre
0 (no permitido). De nuevo, la compresión es una prestación opcional que de hecho
no suele aplicarse a mensajes pequeños (menores de 100 bytes), que corresponden
precisamente con los que nos interesan.
Mensajes de petición Son muy similares a sus equivalentes CORBA. Existe un
identificador de petición (requestId) que se utiliza para establecer la correspondencia entre
peticiones y respuestas y que, por tanto, debe ser copiado al generar estas últimas. También
existe un campo que indica la identidad del objeto cuyo tamaño se asume constante.
Mensajes de respuesta Contienen los resultados en el caso de invocaciones twoway.
Estos mensajes incluyen un campo replyStatus que tiene un valor 0 cuando la invocación
es correcta. El objeto picoIce también es capaz de informar sobre un mensaje dirigido a un
objeto inexistente (excepción 2) y de la invocación de un método no definido (excepción
4). Ver el cuadro 38.16 de [HS08] para obtener información más detallada.
Mensajes de validación Cuando un servidor acepta una nueva conexión —lógicamente,
con un protocolo orientado a conexión— lo primero que debe hacer es enviar un mensaje
especial de reconocimiento ValidateConnection. Sólo cuando el cliente ha recibido dicho
mensaje empieza a enviar mensajes de petición. Se trata de un mensaje pequeño formado
únicamente por una cabecera (14 bytes) y todo su contenido es completamente estático
por lo que no representa ningún problema para ser implementado en picoObjetos. De
i
i
i
i
i
i
i
i
4. picoObjetos
115
este modo se evitan situaciones que pueden llevar a dead-locks consumiendo recursos
en el cliente cuando se utilizan distintos hilos para cada petición.
Mensajes de cierre de conexión Del mismo modo, cuando un cliente deja de hacer
peticiones al servidor, debe enviar un mensaje CloseConnection. El servidor también
puede hacerlo para indicar al cliente que no aceptará nuevas peticiones. Los objetos picoIce
responden a este mensaje, pero nunca lo envían. Estos dos mensajes no se utilizan cuando
se emplea un protocolo de transporte no orientado a conexión.
Funcionamiento del picoObjeto
4.4.
El primer paso que debe realizar el programador para crear un picoObjeto es escribir
un fichero en lenguaje FSM. A partir de éste, el compilador fsm2data genera un fichero
que contiene el bytecode correspondiente, además de la especificación de la memoria
necesaria, datos constantes, etc.
Posteriormente, ese bytecode es susceptible de ser ejecutado por una máquina virtual
de la que se han creado implementaciones para varias plataformas, tal como se verá
en el Capítulo 8.
Esta sección describe los detalles de dicho procedimiento y todos los elementos
involucrados.
4.4.1.
Máquina de estados
El programa FSM citado anteriormente es la especificación de un autómata de estados
finitos que se ha de crear a la medida de los objetos que alojará el nodo objetivo. La
gramática y elementos léxicos concretos quedan determinados por:
El formato de los mensajes del protocolo de comunicación inter-ORB definido por
el middleware.
Las identidades de los objetos alojados. Nótese que lo habitual será que varios
objetos estén respaldados por el mismo sirviente. Esta técnica se denomina sirviente
por defecto (default servant) cuando se aplica en middlewares convencionales.
Las interfaces que implementa cada uno de los objetos. Eso implica conocer los
nombres y tipos de los argumentos de entrada y salida de cada método.
Los procedimientos de serialización definidos por el middleware (CDR en el caso de
CORBA).
Interfaces estándar heredadas por todos los objetos (CORBA::Object, Ice::Object,
etc.).
Para minimizar la cantidad de memoria necesaria, los mensajes de entrada se procesan
en línea, es decir, en ningún momento se almacenan en la memoria del dispositivo.
Pero no todas las transiciones entre los estados del autómata están determinadas por
un único byte. En lugar de procesar el mensaje byte a byte, se precalculan sumas de
comprobación (checksums) para secuencias de bytes que solo pueden tener unos valores
i
i
i
i
i
i
i
i
116
4. picoObjetos
concretos y predecibles; tal es el caso de las identidades de objeto, las facetas y los
nombres de los métodos.
Por ejemplo, en el mensaje de petición, los nombres de los métodos y, en general,
cualquier cadena de caracteres, va precedida por su tamaño. Una función puede leer y
calcular un checksum para la cantidad de bytes indicada por ese tamaño. Como se conocen
los valores de checksum que corresponden a cada uno de los métodos posibles, basta
con comparar el resultado obtenido para determinar cuál es el método que está siendo
invocado. El coste en memoria de esta operación solo requiere de 2 ó 3 bytes de memoria
RAM dependiendo del tipo de checksum que se implemente.
Obviamente esta técnica no resuelve todos los problemas. Hay partes del mensaje
que deben ser almacenadas para su utilización posterior en la generación del mensaje
de respuesta (p.ej. el identificador de petición), o deben estar disponibles durante la
ejecución del método (p.ej. parámetros de la invocación). Otros campos simplemente
pueden ignorarse porque no tienen efecto en la ejecución sea cual sea su valor (p.ej.
campos obsoletos).
Como ejemplo, la figura 4.3 ilustra una máquina de estados para dos objetos
(sensor01 y actuator02) que implementan respectivamente las interfaces DUO::IByte::R
y DUO::IBool::RW.
Queda patente que el autómata debe realizar acciones muy concretas dependiendo del
objeto y mensaje que está siendo recibido o enviado. Puesto que escribir a mano un
programa FSM teniendo en cuenta todos esos detalles puede llegar a ser una tarea compleja
y repetitiva, se ha diseñado un lenguaje de alto nivel (IcePick) y un compilador que ayudan
a automatizar y simplificar sensiblemente el proceso. El capítulo 6 aborda la descripción
de alto nivel para objetos empotrados utilizando dicho lenguaje.
4.5.
Especificación de picoObjetos
Las máquinas de estados para descripción de picoObjetos se definen por medio de
un fichero FSM. Se trata de un lenguaje de programación diseñado al efecto. Es un
DSL (Domain-Specific Language) basado en el lenguaje Python [Pyt], aunque sólo soporta
un subconjunto muy reducido de la funcionalidad del mismo. Permite la creación de
variables de los tipos básicos: entero, cadena, lista y tupla, y el uso de todos sus métodos.
Un programa FSM está formado por los siguientes elementos, que se describen en
las siguientes secciones:
Banco de registros
Variables
Constantes
Persistencia
Un conjunto de bloques
i
i
i
i
i
i
i
i
4. picoObjetos
117
F IGURA 4.3: Ejemplo de una máquina de estados para dos objetos I CE sencillos
4.5.1.
Gestión de los datos
Como todo sistema de cómputo, un picoObjeto ejecuta un conjunto de instrucciones
que operan sobre una colección de datos (constantes y variables) almacenadas en memoria.
En esta sección veremos cómo se organizan y manipulan esos datos.
Banco de registros
El banco de registros es un array de bytes indexable por medio del juego de instrucciones
FSM (véase § 4.5.3). Aunque todos los registros son accesibles para lectura y escritura
en cualquier momento, hay algunos que tienen un uso predefinido:
i
i
i
i
i
i
i
i
118
4. picoObjetos
0. Registro de trabajo – Algunas instrucciones utilizan este registro como parámetro
adicional y/o como ubicación para el resultado.
1. Longitud de la petición – Tamaño total del mensaje de invocación. Se determina a
partir del campo correspondiente en la cabecera del mensaje y se utiliza para detectar
errores en el formato del mensaje o resincronizar con el siguiente mensaje en caso
de error.
2. Identificador de petición – Es un entero de 4 bytes que utiliza el cliente para
comprobar la correspondencia entre el mensaje de petición que envía y el mensaje
de respuesta que recibe.
3. Identidad – Se utiliza para almacenar la identidad del objeto sobre el que se realiza
la invocación actual.
El resto de los registros son de propósito general y se utilizan principalmente para el
almacenamiento temporal de los parámetros y su uso concreto lo determina el compilador
en cada caso. El banco de registros se ubica normalmente en la RAM del dispositivo y,
por tanto, su contenido se perderá al ocurrir un corte en la alimentación.
Es posible definir variables en el banco de registros asignando identificadores a los
índices del array. Estas variables pueden tener tamaño arbitrario.
Para que las funciones del sirviente puedan localizar la situación de los parámetros
se construye un mapa de parámetros. Es un vector que indica en qué registro comienza
cada uno de los parámetros de entrada/salida que toman los métodos de los objetos. El
mapa de parámetros se ubica al comienzo de la zona DATA, dado que las cantidades y
tamaños de los parámetros son datos que se pueden obtener en tiempo de compilación
y, por ello, pueden ser almacenados estáticamente.
En un programa FSM, el banco de registros se utiliza como un objeto (bank) con
la siguiente interfaz1 :
byte alloc(byte n)
Reserva espacio para una variable en el banco de registros. El parámetro n indica el
tamaño en bytes que debe tener la variable. El método retorna el índice del primer
registro asignado a la variable (su dirección). Este valor se puede asignar a un
identificador para después utilizar esa variable en el programa.
byte alloc(str val)
Si se invoca el método alloc() pasando una cadena de caracteres, se obtiene una
variable de tamaño igual al de dicha cadena y se copia la cadena en él.
byte alloc(list val)
Si el parámetro de alloc() es una lista, los elementos de dicha lista se convierten a
una secuencia de bytes y se procede como en el caso anterior.
init(var, [values])
Asigna valores iniciales a los registros. El parámetro var es el identificador de la
variable (o el número de registro), el parámetro values es una lista con los valores
que se deben asignar a cada byte de la variable.
1 Los tipos indicados son meramente descriptivos puesto que Python no permite forzarlos en la signatura de
las funciones.
i
i
i
i
i
i
i
i
4. picoObjetos
119
El listado 4.1 muestra cómo reservar espacio en el banco de registros desde un
programa FSM:
request_len
request_id
identity
param_map
param0_len
param0
socket_1
=
=
=
=
=
=
=
bank . alloc (1)
bank . alloc (4)
bank . alloc (5)
bank . alloc (2)
bank . alloc (1)
bank . alloc (2)
bank . alloc ([ ’T ’ , ’ 127.0.0.1 ’. ljust (15) , [208 , 7]])
L ISTADO 4.1: Ejemplo de uso de las funciones del banco de registros
Variables auxiliares
Se utilizan para fabricar trozos de los mensajes que se emplearán posteriormente.
También para calcular tamaños o definir valores simbólicos. Las variables únicamente
se utilizan como almacenamiento auxiliar en tiempo de compilación, pero no forman
parte del autómata a menos que sea copiado en las zonas DATA o Flash. Para crear
una de estas variables basta asignar un valor a un identificador. El listado 4.2 muestra
ejemplos de variables FSM.
TIMER_EVENT = 4
var_I ce_Objec t = lit ( ’:: Ice :: Object ’)
L ISTADO 4.2: Ejemplos de variables FSM
Constantes, zona DATA
Son fragmentos de mensajes, normalmente para la generación de respuestas e
invocaciones, aunque también se pueden utilizar para reconocimiento de mensajes entrantes.
Cuando se programa el dispositivo, los valores definidos en la zona DATA deberían
colocarse en memoria de sólo lectura puesto que son constantes a todos los efectos.
Para introducir valores en la zona DATA se utiliza el objeto data, que funciona de
modo muy similar a bank (ver listado 4.3).
Cuando se introduce un valor en la zona DATA automáticamente se antepone un
byte adicional que contiene el tamaño de la secuencia. Por ejemplo, en el listado 4.3,
la asignación para la sentencia id_ob1 almacena en realidad los valores 3, 8, 12 y 10
en la posición correspondiente. Los valores se ubican en memoria en el mismo orden
en el que se escriben estas asignaciones en el fichero fuente, precedidos de su tamaño.
Debido a que se direcciona por medio de un registro de 1 byte, la cantidad total de la
zona DATA no puede exceder los 256 bytes, y es obvio que tampoco puede hacerlo
ningún elemento almacenado en ella.
IceHeader = data . alloc ( ’ IceP ’ , 1 , 0 , 1 , 0)
id_ob1
= data . alloc (8 , 12 , 10)
L ISTADO 4.3: Ejemplos de constantes FSM (zona DATA)
i
i
i
i
i
i
i
i
120
4. picoObjetos
Persistencia, zona Flash
En la zona Flash se almacenan valores que pueden cambiar, pero que lo harán con poca
frecuencia y que además es conveniente conservar ante reinicios del dispositivo o eventuales
fallos de alimentación. Tal es el caso de las direcciones (endpoints) de objetos remotos que
deben ser invocados por el picoObjeto. Otro caso interesante ocurre cuando el nodo debe
conseguir su propia dirección después del arranque y necesita almacenarla para comunicarla
a otros servicios. La sintaxis y estructura de almacenamiento es análoga a la de DATA.
4.5.2.
Utilidades auxiliares
Al escribir un programa FSM, el programador dispone de algunas funciones que
facilitan tareas comunes. Son:
byte digest(byteseq)
Retorna el valor de la suma de comprobación. Como parámetro se le puede pasar
un número arbitrario de valores de tipos entero, cadena, o tuplas y listas de estos.
Internamente la función convierte todos esos parámetros en una lista de bytes a la
que aplica el algoritmo para obtener la suma de comprobación.
Literal lit(byteseq)
Es una función factoría que crea un objeto Literal a partir de los parámetros.
El Literal es un tipo que almacena una secuencia de bytes constante y que, bajo
demanda, puede ser precedida automáticamente por su tamaño.
4.5.3.
Repertorio de instrucciones FSM
FSM es una arquitectura de repertorio de instrucciones virtual (V-ISA). Se trata de
instrucciones muy especializadas para el reconocimiento y generación de elementos
léxicos. Y aunque se puede conseguir cierta versatilidad, las tareas principales para
las que ha sido diseñado son:
Lectura/escritura de un byte en la interfaz de red.
Lectura/escritura de una secuencia de bytes precedida por el tamaño de ésta.
Lectura de una secuencia de bytes de la que se conoce de antemano el valor de una
suma de comprobación y el tamaño.
Movimiento de datos entre registros y operaciones aritméticas básicas.
Definición de etiquetas e instrucciones de salto para control del flujo de ejecución.
Gestión de eventos síncronos/asíncronos.
Ejecución de rutinas aportadas por el programador del dispositivo (sirvientes).
Gestión de conexiones activas/pasivas.
La especificación del repertorio de instrucciones, sus formatos y modos de direccionamiento se explican detalladamente en el anexo A.
i
i
i
i
i
i
i
i
4. picoObjetos
4.5.4.
121
Bloques
Las instrucciones FSM han de incluirse siempre en algún bloque. La utilidad real del
bloque es definir un punto de entrada (una etiqueta) que sirve como destino para las
instrucciones de salto, ejecución de funciones, subrutinas o manejadores para eventos. En
todos esos casos se utiliza el nombre de un bloque como parámetro de la instrucción, tal
como hemos visto en el juego de instrucciones. El proceso de compilación traduce cada
etiqueta por la dirección que ocupa la primera instrucción de cada bloque.
Nótese que las instrucciones se ejecutan siempre de forma secuencial y, a menos que
exista un salto, la ejecución continuará en el bloque subsiguiente. El listado 4.4 muestra
tres de estos bloques e ilustra este hecho. La ejecución del bloque replyIds implica
siempre la ejecución posterior del bloque replyId.
Existe un bloque especial —llamado init por convenio— que es siempre el primero
que aparece en el programa y el que obtiene el control cuando arranca el dispositivo. En
este bloque recae la responsabilidad de la inicialización de los periféricos o cualquier otra
tarea como, por ejemplo, la obtención de la dirección de red si es dinámica. Dado que estas
tareas normalmente son específicas de cada plataforma, este proceso implica la ejecución
de procedimientos de usuario proporcionados por el programador del dispositivo.
def init () :
user_proc ( PROC_INIT )
set_event ( ’ validate ’ , IN COMING_E VENT )
set_event ( ’ main ’ , RESET_EVENT )
reset ()
def replyIds () :
put_data ( Ice_Object )
put_data ( DUO_IBool_R )
put_data ( DUO_IBool_W )
def replyId () :
put_data ( DUO_IBool_RW )
goto ( ’ ice_close ’)
L ISTADO 4.4: Algunos bloques de ejemplo de un programa FSM
4.5.5.
Subrutinas
Las subrutinas permiten ejecutar un bloque volviendo al punto de llamada una vez
terminada la ejecución del mismo. Para ello se utiliza la instrucción call() indicando
el nombre de un bloque.
El bloque invocado debe tener una instrucción ret() (normalmente al final); sin
embargo, ésta será ignorada si el flujo de ejecución llega a ella de otro modo (mediante
goto). Así pues, un mismo bloque se puede utilizar como subrutina o como etiqueta de
salto dependiendo de la instrucción que se utilice para llegar a él. No existe pila, sólo hay
un puntero de retorno, por lo que no es posible ejecutar subrutinas de forma anidada.
i
i
i
i
i
i
i
i
122
4. picoObjetos
4.5.6.
Eventos
El funcionamiento del picoObjeto está dirigido por eventos , ya sean síncronos
(lanzados explícitamente) o asíncronos (provocados por una señal externa). Los eventos
se representan con un valor entero único, aunque en el código fuente FSM se asocian
a un identificador para facilitar su lectura. Gracias al uso de eventos se consiguen
varias prestaciones interesantes:
Mínimo acoplamiento
No hay ninguna dependencia entre la generación del evento y su tratamiento. Ambos
procesos ocurren en partes distintas del programa. La instrucción set_event()
asocia un evento con su manejador (un bloque). Esta instrucción se puede invocar
desde cualquier parte del programa, de modo que el manejador de un mismo evento
se puede modificar cuando se requiera.
Fácilmente extensible
Resulta trivial añadir eventos y manejadores nuevos y no requiere ningún soporte ni
modificaciones adicionales. De hecho, no se trata de algo excepcional, es bastante
habitual que cada objeto necesite añadir sus propios eventos.
Ejecución lineal
El manejador no es ejecutado inmediatamente después de producirse el evento. En
su lugar, se marca una bandera y cuando han terminado las tareas pendientes, se
atienden los eventos en orden de prioridad. Por ese motivo, la ejecución de los
manejadores es lineal y no puede ser interrumpida. Esto simplifica sensiblemente la
implementación de la máquina virtual y facilita su depuración.
Hay varios eventos que se utilizan prácticamente en cualquier programa y por ello
tienen nombre, valor y finalidad predeterminada:
RESET_EVENT
El manejador asociado a este evento es utilizado internamente como dirección de
salto al terminar la ejecución de la instrucción reset(). Es decir, asocia un bloque
(por convenio llamado main) como punto de salto después de reiniciar la máquina
de estados.
Normalmente ese bloque es el que hace el reconocimiento de la cabecera de los
mensajes entrantes. En la mayor parte de los programas FSM aparece una sentencia
set_event(‘main’, RESET_EVENT) en el bloque init.
INCOMING_EVENT
Este evento lo produce la máquina virtual cuando detecta una conexión entrante.
Como respuesta ejecutará el bloque asociado como manejador. Esta funcionalidad
se requiere para contemplar casos como el mensaje de validación de conexión de
I CE (véase § C.3.5).
ERROR_EVENT
Cuando se detecta un error de reconocimiento, la máquina de estados ejecuta
el manejador programado para este evento. Su misión debe ser sincronizar el
autómata con el siguiente mensaje de entrada, cerrar las conexiones abiertas, etc.
Este manejador termina ejecutando la instrucción reset().
i
i
i
i
i
i
i
i
4. picoObjetos
123
Los timers están también relacionados con los eventos. Cada timer está representado
por un evento que se lanza cuando el tiempo asociado llega a 0. El manejador del timer
es un bloque al igual que cualquier otro evento.
El programador también puede definir y utilizar sus propios eventos, que puede
disparar desde el código del sirviente. Resultan especialmente adecuados para modelar
el comportamiento de sensores que pueden detectar cambios en el entorno físico. El
dispositivo puede instalar una RSI para la interrupción correspondiente y utilizar esa
rutina para disparar el evento FSM.
El picoObjeto como reactor
Tomando en cuenta estas consideraciones, podemos ver el picoObjeto como una
implementación del patrón de diseño reactor [GHJV96]. Es una máquina dirigida por
eventos dado que materializa la especificación de un autómata de estados finitos. A partir
del estado de reposo pueden ocurrir las siguientes situaciones:
Una conexión pasiva. Se considera como una activación del evento INCOMING_EVENT
y desencadena la ejecución del manejador registrado.
Llegada de un byte por la interfaz de red. Este hecho sólo se considera como evento
si es el primero del mensaje. El bloque que está en ejecución en espera de ese primer
byte corresponde al manejador registrado para el evento RESET_EVENT.
Expiración de un timer. Se dispara la ejecución del manejador asociado.
La activación de un periférico del dispositivo (un sensor) genera una interrupción.
El identificador de dicho evento debe estar especificado en el fichero FSM y como
con cualquier otro evento, se debería haber registrado un manejador.
Tratamiento de eventos
Los eventos pueden producirse en cualquier momento: asíncronos si se trata de un evento
asociado a un sensor o la invocación de un mensaje, o síncronos si el propio código incluye
la instrucción raise_event(). Sin embargo, los eventos no se atienden en el mismo
instante en que se producen, sufren un pequeño retardo debido a que sólo se comprueban
cuando se ejecuta una instrucción de lectura o durante un reset().
Aunque la forma de implementar el registro de eventos pendientes dependerá de cada
máquina virtual concreta, el modo más sencillo es un vector de banderas booleanas. El
identificador de cada evento determina la posición de la bandera en este vector. Si se
produce el evento se marca activando la bandera correspondiente, y cuando se atiende
un evento se desactiva su bandera.
La prioridad queda determinada también por la posición de su bandera en el vector. El
evento (RESET) es el más prioritario (evento 0). No se atienden eventos menos prioritarios
aunque se produjeran antes. Implementarlo de este modo tiene algunas consecuencias
deseables, en aras de la simplicidad:
Los manejadores de eventos no pueden anidarse, de modo que la ejecución de sus
manejadores es secuencial y por prioridad.
i
i
i
i
i
i
i
i
124
4. picoObjetos
Si se produce un mismo evento antes de que pueda ser atendido, el manejador sólo
se ejecutará una vez. Esto debe ser tenido en cuenta por el programador de tener
implicaciones indeseadas para ciertas aplicaciones concretas.
En las plataformas con menos recursos, el vector de banderas para los eventos se puede
implementar utilizando los bits individuales de una palabra, con lo que un solo byte sirve
para representar ocho eventos, más que suficiente para muchos transductores sencillos.
4.5.7.
Sirvientes, código de usuario
Como en cualquier middleware de comunicaciones, la invocación de un procedimiento
o método remoto desencadena la ejecución de código vinculado a la aplicación específica
que se está desarrollando y que, por tanto, debe ser proporcionado por el programador; de
ahí la denominación de código de usuario. El conjunto de procedimientos relacionados
como métodos de un mismo objeto (en el caso de los MDOO) se denomina sirviente
(véase § 2.3.1).
Como el objetivo es poder implementar picoObjetos en una amplia variedad de
dispositivos y plataformas, tanto la máquina virtual que ejecuta el bytecode como
el propio código de usuario deben estar escritos en un lenguaje soportado por la
plataforma específica.
Para desacoplar al máximo máquina virtual y sirviente, se asigna un simple identificador
entero a cada procedimiento de usuario y por medio de la instrucción user_proc se
determina cuál ejecutar. La implementación de esa instrucción la debe proporcionar el
programador. Esta instrucción es responsable de las siguientes tareas:
Recuperar el identificador del procedimiento a ejecutar.
Acceder a los parámetros de la invocación desde el banco de registros.
Dejar el valor de retorno y parámetros de salida en esos mismos registros.
Paso de parámetros
La máquina de estados lee y almacena los parámetros de tamaño fijo (bool, byte, int,
float, etc.) en el banco de registros. Cada parámetro requiere un byte que indica el
tamaño del parámetro y a continuación el valor del mismo. El sirviente puede determinar
dónde empieza cada parámetro utilizando el mapa de parámetros ubicado en la zona
DATA (véase § 4.5.1).
Los parámetros de tamaño variable, como string, identidades de objeto, proxies y
otros tipos permitidos reciben un tratamiento muy especial. Dado que no se puede
determinar su tamaño hasta el momento de su llegada, no es posible decidir cuántos
bytes deberían reservarse en el banco de registros. Por otro lado, se pretende que el
banco sea lo más pequeño posible. Por limitaciones de direccionamiento nunca puede ser
mayor de 256 bytes; en muchas plataformas concretas está limitado a 128 bytes, dado
que esa es la RAM disponible. La mayoría de las implementaciones de los prototipos
realizados requieren menos de 64 bytes.
Para el tratamiento de parámetros de tamaño variable el programador debe proporcionar
rutinas específicas que serán invocadas por la máquina de estados en el momento
i
i
i
i
i
i
i
i
4. picoObjetos
125
oportuno. Estas rutinas se encargan de leer/escribir los parámetros directamente desde
el dispositivo de red y almacenarlos en memoria gestionada por su cuenta, fuera del
banco de registros de la máquina virtual.
4.5.8.
Bytecode
A partir de un fichero fuente FSM individual, el compilador fsm2data genera un fichero
de bytecode (ver listado 4.5) compuesto básicamente por cuatro secuencias de bytes:
fsmCode
Contiene los equivalentes numéricos de las instrucciones FSM del fichero fuente y
los valores de sus parámetros (ver § 4.5.3 y § 4.5.4). Es simplemente un array, una
secuencia unidimensional que, durante la programación del dispositivo, se copia
directamente a memoria de sólo lectura. El código se genera en el mismo orden en
el que las instrucciones están escritas en el fichero fuente sin necesidad de marcas
entre bloques.
fsmData
Contiene los datos almacenados en la zona DATA (véase § 4.5.1). El proceso de
instalación en el dispositivo es responsable de ubicar estos datos bajo la premisa de
que nunca necesitarán ser modificados por el programa en ejecución (ROM).
fsmFlash
Los datos de la zona Flash, como su nombre indica, deben ir a una memoria Flash u
otro dispositivo de almacenamiento persistente.
fsmBank
Contiene los valores iniciales para los registros (véase § 4.5.1). Además, su tamaño
indica cuántos registros serán necesarios.
El formato del fichero que contiene el bytecode depende del lenguaje de programación
en el que esté implementada la máquina virtual. Es posible generar el mismo bytecode
en Java, Python, C y ensamblador de la familia MicroChip PIC.
Dependiendo también de la plataforma y lenguaje objetivo, el fichero del bytecode
puede contener otros datos:
Etiquetas de inclusión
Se trata de una lista con los nombres de las instrucciones que realmente se
utilizan en el programa FSM. Cuando se genera C, se utilizan cláusulas #define
del preprocesador, lo que permite generar una implementación completamente
especializada en la que ni siquiera se incluye el código de las instrucciones
innecesarias, con el consiguiente ahorro en tamaño de memoria de programa.
Cadenas de depuración
Si la plataforma objetivo soporta log para depuración —instrucción debug()— el
fichero de bytecode puede incluir el texto correspondiente como una secuencia de
cadenas. Sólo las implementaciones de la máquina virtual que se ejecutan sobre un
PC disponen de esta posibilidad.
i
i
i
i
i
i
i
i
126
4. picoObjetos
fsmCode = [
26 ,
0,
6,
1,
[...]
103 ,
4,
211 ,
4,
182 ,
4,
26 ,
17 ,
1,
3,
6,
6,
1,
8,
1 , 229 ,
1 , 61 , 38 ,
0 , 191 , 228 ,
0 , 252 ,
2,
4,
4,
1,
2,
1,
0 , 183 ,
0 , 199 ,
1]
fsmData = [
6,
4,
4 , 84 ,
4 , 76 ,
[...]
118 , 101 ,
85 , 79 ,
108 , 58 ,
76 ,
80 ,
79 ,
79 ,
67 ,
67 ,
67 ,
49 ,
50 ,
49 ,
0,
0,
82 ,
58 ,
58 ,
17 ,
58 ,
82 ,
16 ,
73 ,
87]
58 , 58 , 68 ,
66 , 111 , 111 ,
fsmBank = [
0,
0,
0,
0,
0,
0,
50 , 55 ,
32 , 32 ,
0,
0,
0,
46 ,
32 ,
0,
0,
0,
48 ,
32 ,
0,
0,
0,
46 ,
32 ,
0,
0,
15 , 18 ,
18 , 84 ,
48 , 46 ,
32 , 208 ,
0,
0,
7,
7,
6,
0,
0,
0,
49 ,
49 ,
7]
L ISTADO 4.5: Parte del bytecode resultante de la compilación de un programa FSM
4.5.9.
Limitaciones y saltos
Al estar diseñado para dispositivos de cómputo muy simples, todas las direcciones y
registros corresponden a una máquina de 8 bits. Y por ello, los tamaños de memoria y
código quedan limitados. Las tres zonas de memoria (banco de registros, DATA y Flash)
pueden tener un máximo de 256 bytes cada una. También las variables y los mensajes
que puede recibir el objeto están limitados a ese tamaño.
Estos tamaños máximos son asumibles puesto que en muchos casos los microcontroladores que consideramos como objetivo tienen aun menos recursos.
Sin embargo, 256 palabras de bytecode es insuficiente. Para paliar este problema se
permite que las instrucciones de salto tengan direcciones de 2 bytes. Se utiliza un espacio
de memoria de programa segmentado. El primer byte de una dirección indica una página
y el segundo un desplazamiento dentro de la misma. Cada página tiene 256 palabras y
puede haber tantas como permita el almacenamiento del dispositivo hasta un máximo
de 256 × 256 = 64KiB que supera con creces la cantidad de memoria de programa
necesaria para el tipo de aplicaciones que nos planteamos.
El mismo sistema podría aplicarse a las zonas de memoria de datos, aunque aumentaría
el tamaño de todas las instrucciones al requerir direcciones de 16 bits. La implementación
de transductores simples es perfectamente compatible con las limitaciones que plantea
la máquina de 8 bits, con el ahorro que implica.
En cualquier caso, éstas son limitaciones del bytecode, no del repertorio FSM. Un
bytecode y una máquina de 16 bits resultarían adecuados para servicios más complejos
como encaminadores (capítulo 7), bridges, propagación de eventos, etc. Los requerimientos
i
i
i
i
i
i
i
i
4. picoObjetos
127
funcionales de tales servicios pueden sobrepasar fácilmente las prestaciones de cualquier
microcontrolador de 8 bits.
4.6.
Transformación de FSM a bytecode
En las secciones anteriores se ha descrito tanto el lenguaje FSM como el bytecode
equivalente. Esta transformación la realiza el compilador/traductor fsm2data. Es necesario
puntualizar ciertos detalles no triviales de este proceso.
El lenguaje FSM es un programa Python muy restringido. El proceso de compilación
comienza ejecutando ese programa con un intérprete de Python estándar, pero dentro de un
entorno modificado, que contiene los objetos y funciones Python especiales comentados
anteriormente (bank, data, flash, lit, etc.).
Dicho entorno también contiene las instrucciones del repertorio implementadas como
métodos de un objeto. Éstos realizan la transformación de cada instrucción y sus
parámetros a su equivalente en bytecode, que se almacena programáticamente utilizando
una representación abstracta. Su representación definitiva depende del lenguaje que
requiera la plataforma objetivo.
4.6.1.
Optimizaciones
Al analizar el bytecode resultante vemos que, de media, ocupa menos de 4 páginas (unas
450 palabras). Es fácil comprobar que muchos de los saltos tienen como destino bloques
de la misma página. Es decir, solo los saltos que se refieren a bloques de otras páginas
necesitarían realmente indicar la página. Es por ello que se definen dos tipos de saltos:
Salto corto
Cuando el destino es un bloque de la misma página en la que está la instrucción
de salto. El único byte de la dirección indica el desplazamiento dentro de la página
actual.
Salto largo
Cuando el destino es un bloque de otra página. La dirección tiene el formato que se ha
indicado más arriba: el primer byte indica la página y el segundo es el desplazamiento
respecto a aquella.
Las instrucciones de salto necesitan distinguir qué tipo de salto deben efectuar. La
solución es sencilla: leen el primer byte de la dirección, si su valor es menor o igual
al número de páginas (p) se entiende que indica una página y, por tanto, es un salto
largo; a continuación, lee el siguiente byte para determinar el desplazamiento. Si el valor
es mayor a p, se interpreta como un salto corto y ese valor indica el desplazamiento
dentro de la página actual. La consecuencia es que no se puede indicar un salto corto a
un bloque cuyo comienzo esté en los primeros pbytes de una página; en esos casos es
necesario utilizar un salto largo. Estadísticamente eso ocurre con muy poca frecuencia
de modo que la sobrecarga adicional es muy baja.
i
i
i
i
i
i
i
i
128
4. picoObjetos
Fragmentación de instrucciones
Con el fin de simplificar aún más la implementación de la máquina virtual, se asume
que la lógica que gestiona el cambio de página al leer el bytecode solo está disponible al
cargar una nueva instrucción, y no durante la carga de los operandos. Para que eso sea
posible, toda la instrucción incluyendo sus operandos debe estar en la misma página.
Es responsabilidad del compilador de FSM reubicar el código para evitar esa situación.
De ahí la existencia de una instrucción nop. Se utiliza como relleno al final de una
página de modo que la siguiente instrucción quede alineada a la siguiente página.
Dado que la instrucción más larga tiene 4 bytes, en el caso peor se introducirían solo
3 instrucciones nop.
Conversión de direcciones
El compilador construye un mapa de memoria a partir de las instrucciones asignando
direcciones a cada instrucción en función de su tamaño y número de parámetros. Cuando
todas las instrucciones están ubicadas traduce la etiqueta de cada bloque por la dirección
asignada a su primera instrucción.
Inicialmente todos los saltos son largos (véase § 4.5.9). En una segunda pasada, el
compilador substituye los saltos largos por cortos cuando la dirección destino está en la
misma página. Al eliminar datos del bytecode, las direcciones de los bloques subsiguientes
cambian (a un valor menor), por lo que requiere modificar también dichas direcciones
en las instrucciones de salto y llamada a subrutinas.
Al modificar las direcciones puede ocurrir que un bloque al comienzo de una página
pase al final de la página anterior. Eso tiene importantes consecuencias, puesto que los
saltos cortos a ese bloque de su página original deben convertirse de nuevo en largos,
y los cortos en la página destino pueden ahora convertirse en largos, de modo que todo
el proceso debe comenzar de nuevo. Se trata de un problema de equilibrio típico que
se resuelve con programación dinámica.
Reordenación de bloques
Exceptuando el bloque init (que debe ser el primero), los bloques FSM pueden
estar en cualquier parte del código. Pero, en el proceso de traducción, el bytecode se
genera respetando el orden del fichero original. Por ello ese orden, aunque funcionalmente
irrelevante, conlleva la generación de bytecodes distintos, dependiendo de las posibilidades
de optimización de los saltos.
El compilador fsm2data puede reordenar los bloques buscando la situación que
haga posible una solución óptima, es decir, minimizando el número de saltos largos
necesarios.
Otra pequeña optimización a tener en cuenta es la aparición de un salto al bloque
siguiente. Por diseño, al alcanzarse el final de un bloque, el flujo de ejecución continúa
en el siguiente bloque a menos que haya una instrucción de salto (véase § 4.5.4). El
compilador debe favorecer esta situación a fin de poder eliminar saltos incondicionales
cuando se producen al final de un bloque.
i
i
i
i
i
i
i
i
4. picoObjetos
4.6.2.
129
Generación del bytecode
La generación del bytecode concreto para un lenguaje destino se realiza por medio de
una implementación del patrón de diseño builder [GHJV96].
4.7.
Máquina virtual
El bytecode generado está diseñado para ser independiente de la plataforma. Obviamente,
se necesita una implementación de la máquina virtual para el dispositivo concreto. Ésta
se encarga de ejecutar las instrucciones codificadas y acceder a los datos necesarios. El
modelo de máquina virtual ofrece varias ventajas:
Facilita la incorporación de nuevos dispositivos y plataformas. Únicamente se
requiere implementar la máquina virtual sobre la nueva plataforma. No tiene ningún
impacto sobre el proceso de compilación de FSM ni sobre las herramientas de alto
nivel.
Simplifica la depuración. Al disponer de una implementación de la máquina virtual
para PC se pueden reconstruir situaciones que puedan aparecer en cualquier aspecto
o eventualidad de la comunicación de un dispositivo con el exterior.
Hace posible la re-programación remota. Al utilizar una máquina virtual, es posible
distribuir nuevas versiones del bytecode incluso con el sistema en producción (véase
§ 4.9).
La implementación de la máquina virtual para una nueva plataforma no requiere un
esfuerzo considerable precisamente porque se ha hecho incapié en conseguir un diseño tan
simple como ha sido posible. Las prestaciones que debe ofrecer una implementación
de la máquina virtual son:
Gestión y alojamiento del banco de registros y las zonas de datos DATA y Flash.
La implementación decide si es posible y/o conveniente aprovechar las necesidades
de cada zona. Por ejemplo, si el dispositivo no cuenta con memoria Flash u otro
tipo de persistencia puede utilizar memoria RAM, aunque debe avisar para evitar las
consecuencias que ello pudiera acarrear.
Funciones para la ejecución de las instrucciones del repertorio. La mayoría son
realmente simples. La implementación de repertorio completo no supera las 200
SLOC de código en lenguaje C.
Vector de banderas para gestión de eventos. Una posible implementación se esboza
en la sección 4.5.6.
Gestión de tiempo para los timers.
Lectura/escritura desde la interfaz de red.
Ejecución de métodos del sirviente.
i
i
i
i
i
i
i
i
130
4. picoObjetos
4.7.1.
Comunicación con el sirviente
La especificación del autómata se encarga de colocar los parámetros de entrada
en el banco de registros e invocar la instrucción user_proc(). Desde ese código, el
programador puede acceder a cualquier componente lógico del dispositivo: banco de
registros, ROM, etc. También dispone de soporte para leer y escribir en la interfaz
de red, pero no para acceso a periféricos. Esa es precisamente la responsabilidad
principal del sirviente.
4.8.
Generación de código nativo
La alternativa al binomio máquina virtual + bytecode es generar un programa completo
ad hoc. Es posible plantear esta opción con un compilador que genere código nativo
directamente a partir del código FSM. Las ventajas principales de este enfoque son la
reducción de tamaño del programa y la sobrecarga que implica el código que carga
e interpreta el bytecode. También implica un sensible aumento en la complejidad de
adaptar la solución a nuevas plataformas y la pérdida de todas las ventajas que aparecen
en la sección anterior.
La depuración del intérprete de una máquina virtual es muy sencilla; se pueden realizar
baterías de pruebas para cada instrucción ante escenarios diferentes. Sin embargo, la
depuración y prueba de un generador de código para un lenguaje y arquitectura concreta
resulta mucho más complicada y no es fácil extrapolar su funcionamiento a una arquitectura
PC, que es significativamente más amigable para el proceso de desarrollo y depuración.
4.9.
Despliegue de aplicaciones en la SAN
picoGrid es nuestra propuesta para despliegue de aplicaciones en la SAN. Es posible
reprogramar el funcionamiento de un picoObjeto sin más que enviar una nueva versión
del bytecode. Éste incluye la definición de los objetos alojados en el nodo y sus tipos,
pero también tratamiento de eventos y relaciones entre objetos que permiten especificar
servicios sencillos, como se verá en el capítulo 6.
Los requisitos para permitir despliegue remoto con picoGrid son:
FSM en memoria reescribible. Se debe almacenar el código FSM en memoria Flash
o EEPROM en lugar de ROM.
Utilizar únicamente drivers como sirvientes. El código de los sirvientes no se
despliega en la red dado que es dependiente de la plataforma. El nodo debe disponer
de los drivers necesarios para manipular todos sus sensores y actuadores, aunque en
un primer momento no los necesite.
Máquina virtual completa. Aunque está prevista la posibilidad de no incluir en el
dispositivo la implementación de instrucciones no utilizadas, esta optimización no
es posible si se desea reprogramación remota.
Para que un nodo pueda ser reprogramado necesita además un objeto especial (el
picoNode) que atenderá las solicitudes para envío de código nuevo. Es un objeto
i
i
i
i
i
i
i
i
4. picoObjetos
131
especificado del mismo modo que cualquier otro usando código FSM. Eso significa que una
nueva versión del bytecode podría eliminar el picoNode impidiendo futuros despliegues.
Si se desea evitar esta posibilidad es necesario almacenar el bytecode de ese objeto en
memoria ROM y garantizar que podrá seguir accesible.
4.10.
Conclusiones
Como vimos en el capítulo 2, existen varias propuestas que utilizan máquinas virtuales
para la implementación de lógica de control y comunicaciones en dispositivos asociados
a transductores de una red SAN.
El repertorio de instrucciones FSM, a diferencia de Maté [LC02], no está orientado
a la especificación del sirviente, sino al protocolo de comunicaciones y las relaciones
con otros servicios. Maté está limitado a plataformas MICA con sistema TinyOS. Sus
instrucciones se refieren específicamente a los sensores de estas plataformas y su diseño
es difícilmente generalizable.
Sin embargo, la máquina FSM se puede implementar sobre prácticamente cualquier
dispositivo de cómputo con capacidad de red. No está ligado a ningún protocolo o
middleware concreto dado que las instrucciones son de más bajo nivel y, por tanto,
mucho más flexible. Ciertamente, el diseño del repertorio está especializado en protocolos
binarios similares a GIOP, pero su diseño permite extensiones del repertorio para dotarlo
de instrucciones especializadas en protocolos tipo XML sin pérdida de generalidad, con
la ventaja añadida de que es posible eliminar de la máquina virtual las instrucciones
no utilizadas.
WSP [BLV09] también está ligado a la plataforma y algunas de las instrucciones
virtuales de su repertorio son de un nivel de abstracción mucho mayor que las que se
propone para los picoObjetos. Por ejemplo, incluye instrucciones para: establecimiento
de rutas, encaminamiento de mensajes, encender/apagar un LED. Por contra, el repertorio
FSM no presupone la existencia de ningún periférico concreto en el nodo, de la utilización
de protocolo concreto, etc. Tanto WSP como el picoObjeto proponen un modelo de control
por eventos, pero mientras el primero determina por diseño la existencia de servicios
concretos e inmutables en el nodo, el picoObjeto es un sistema que permite definirlos
y construirlos específicamente para un nodo concreto. Otra gran diferencia es que WSP
propone un modelo de macro-programación, mientras que en nuestro caso ésta es una
decisión de alto nivel, sin relación con el funcionamiento de la máquina virtual.
Nuestra propuesta guarda ciertas similitudes con SensorWare [BHSS07]. El modelo
en capas que propone, definiendo interfaces para drivers y servicios del SO, hace posible
implementar el sistema sobre múltiples plataformas. La utilización de T CL como lenguaje
de programación le proporciona flexibilidad a efectos de control de los algoritmos, sin
embargo, las instrucciones son de muy alto nivel (p. ej. return_reply_to) de modo
que no es posible modificar un protocolo de comunicaciones distinto con un programa
nuevo; algo que es perfectamente posible con los picoObjetos.
Por otra parte, la necesidad de un intérprete de T CL, soporte multi-hilo y los considerables
requisitos de memoria que impone, hacen que SensorWare sea un middleware inviable para
nuestros objetivos en lo referente a plataformas hardware a utilizar como nodos SAN.
i
i
i
i
i
i
i
i
132
4. picoObjetos
La principal diferencia entre los picoObjetos y otras iniciativas es que, en nuestro caso,
el repertorio de instrucciones está formado por ladrillos pequeños aunque orientados
específicamente a la generación y reconocimiento de mensajes. Esto permite desacoplar
la definición de los servicios y prestaciones del middleware del mecanismo que permite
transportar información entre los elementos del sistema. Es decir, es posible proporcionar
muchas de las prestaciones de alto nivel que proponen cualquiera de los middlewares
que se han presentado; pero en lugar de proporcionar esa funcionalidad desde la máquina
virtual, pueden obtenerse como servicios sobre el middleware. Es decir, los servicios
no los ofrece el nodo, sino los objetos alojados en él.
El problema de utilizar una ISA de tan bajo nivel es la dificultad de especificar servicios
incluso muy simples. Por esta razón, se ha creado un lenguaje de alto nivel que simplifica
sensiblemente esta tarea y a partir del cual es posible generar un programa FSM completo,
este tema se trata en profundidad en el capítulo 6.
i
i
i
i
i
i
i
i
Descubrimiento del entorno
5.1.
5.2.
5.3.
5.4.
5.5.
5.6.
5.7.
5.8.
Objetivos
Elementos básicos
Prestaciones de ASDF
Anunciamiento
Descripción de servicios
Búsqueda de servicios
Servicio de metamodelo
Conclusiones
55
E
N los últimos años el grupo ARCO (Arquitectura y Redes de Computadores)
ha desarrollado un nuevo SDP denominado ASDF (Abstract Service Discovery
Framework). Se ha aplicado con éxito en varios proyectos sufriendo algunas modificaciones
y mejoras para adaptarlo a nuevos requisitos. Si bien se trata de un protocolo de propósito
general, su diseño está influenciado por las particularidades propias de dispositivos con
recursos limitados como los que se utilizan para la implementación de picoObjetos. En
este capítulo se describen sus características y usos, con especial énfasis en su aplicación a
las redes SAN y otras redes heterogéneas susceptibles de incorporar picoObjetos.
5.1.
Objetivos
Aparte de las prestaciones típicas de cualquier SDP (véase § 2.7.2), ASDF se ha diseñado
para cumplir los siguientes objetivos específicos:
Orientado a objetos
Dada la naturaleza del sistema de invocación remota que se emplea en la plataforma,
se considera que lo más adecuado es modelar los servicios como clases e interfaces.
Así, el proceso de enumeración y composición de servicios es un mecanismo
homogéneo que se integra de forma natural con el resto del sistema.
Extensible y escalable
El diseño basado en interfaces permite versionado y especialización de una forma
sencilla, haciendo uso de las prestaciones del middleware cuando estén disponibles.
Auto-configuración
Uno de los principales objetivos que cumple ASDF es ofrecer la posibilidad de
integrar nuevos dispositivos y sus servicios en el sistema de forma automática. Como
133
i
i
i
i
i
i
i
i
134
5. D ESCUBRIMIENTO DEL ENTORNO
se verá, este objetivo está supeditado en algunos casos a las características de la
tecnología de comunicaciones o los protocolos subyacentes como, por ejemplo, la
disponibilidad de direccionamiento multicast o broadcast.
Soporte para recursos limitados
Otro requisito clave en el diseño del protocolo ASDF ha sido el soporte de
dispositivos con reducidas capacidades de cómputo. Se han tomado en especial
consideración las cuestiones referentes a tamaño de los mensajes, volumen de
tráfico, consumo energético e interoperabilidad. También, aunque en menor medida,
se han evaluado las limitaciones que pudiera implicar el uso de tecnologías de
comunicaciones con poco ancho de banda, enlaces de datos de bajo coste o que por
sus características pudieran no tener grandes prestaciones.
A pesar de haber tenido muy en cuenta estas particularidades, su uso no está
restringido a redes de transductores. Dado que los picoObjetos se comportan
como objetos distribuidos convencionales, una consecuencia muy positiva es que
ASDF es un protocolo de propósito general que se puede utilizar en todo el sistema
simplificando la integración de cualquier tipo de servicio o dispositivo de forma
natural.
Interoperabilidad
Se pretende alcanzar un nivel importante de interoperabilidad con otros SDP S ajenos,
pero de amplio uso como pueden ser UP N P, Bluetooth SDP o Zeroconf. La intención
es ofrecer los servicios ASDF en dominios distintos y, en principio, incompatibles.
También poder representar dentro de nuestro dominio servicios ofrecidos por otros
y, no menos relevante, conseguir que dos protocolos ajenos e incompatibles puedan
interoperar entre sí gracias a nuestros mecanismos de integración.
Félix J.V ILLANUEVA, co-diseñador del protocolo, aborda en su tesis doctoral [Vil09,
Cap.7] los aspectos específicos de interoperabilidad de ASDF, proponiendo
mecanismos concretos en diferentes escenarios. Estos aspectos quedan fuera de
las aportaciones de esta tesis y, por ello, se recomienda al lector el citado documento
si esas cuestiones resultasen de su interés.
Todos estos objetivos están encaminados a facilitar al máximo el despliegue de
redes SAN de todo tipo. Pretendemos que cualquier nuevo dispositivo que se active
en el ámbito de la red sea capaz de auto-configurarse con mínima o nula intervención
explícita por parte de los componentes del sistema. En particular, los nuevos dispositivos
deberían ser perfectamente funcionales sin intervención alguna por parte del instalador u
operador del sistema, aunque quizá no con todas sus prestaciones potenciales, como
por ejemplo, su ubicación física.
5.2.
Elementos básicos
A continuación, se describen los elementos estructurales sobre los que se realiza la
implementación del protocolo ASDF. Generalmente debería proporcionarlos el middleware
pero, de no existir equivalencia, la propia aplicación podría proporcionar un sustituto dado
que no implican una complejidad de implementación prohibitiva.
i
i
i
i
i
i
i
i
5. D ESCUBRIMIENTO DEL ENTORNO
5.2.1.
135
Canales de eventos
ASDF hace un uso extensivo del servicio estándar de notificación de eventos provisto
por el middleware. Con ello se consigue bajo acoplamiento entre todos los elementos
involucrados de una manera sencilla y eficiente, principalmente porque los servicios
comunes del middleware suelen estar más optimizados que cualquier desarrollo realizado
por terceros.
ASDF define y utiliza dos actores (normalmente canales de eventos) considerados
como bien conocidos. Eso significa que el middleware puede obtener sus referencias
automáticamente mediante los servicios de indirección o bien el nodo las tiene previamente
almacenadas. Son estos:
ASDA
Se utiliza para enviar mensajes de anunciamiento (adv) y despedida (bye) de actores.
Todos los objetos suscritos deben implementar la interfaz ASD::Listener. Cualquier
elemento del sistema puede enviar ese tipo de mensajes a este canal (véase § 5.4).
ASDS
Se utiliza para enviar los mensajes de búsqueda de servicios (lookup). Los
objetos suscritos —susceptibles de ser buscados— deben implementar la interfaz
ASD::Search (véase § 5.6).
Aunque se han descrito como canales de eventos, ASDA y ASDS pueden ser objetos
distribuidos convencionales, dependiendo si se desea un planteamiento distribuido o
centralizado, respectivamente. La alternativa que se elija no afecta en absoluto al resto
del sistema. A efectos funcionales resulta transparente para los demás elementos. Se
incidirá sobre esto más adelante en este capítulo.
Los mecanismos de búsqueda pueden requerir la creación de otros canales auxiliares
para propósitos concretos o puntuales.
5.2.2.
Propiedades
Una propiedad es una tupla clave-valor que representa una característica de un servicio.
La clave es siempre una cadena de caracteres y el valor es normalmente un tipo básico
(entero, cadena, float, etc.) o lista de ellos, aunque puede ser de tipos más complejos.
El diseño de las interfaces para acceso remoto a las propiedades, definiciones y conjuntos
de estas está basado en la descripción del Servicio de Propiedades [Obj00] definido
por OMG. Para la implementación de los prototipos I CE se han realizado únicamente
modificaciones relacionadas con las diferencias existentes entre los distintos lenguajes
de especificación de interfaces. Con ello se pretende conseguir el mayor grado de
interoperabilidad con pasadas o futuras implementaciones del servicio, independientemente
del middleware que se utilice.
Las propiedades pueden ofrecer información muy variada sobre un servicio; pueden
almacenar desde el fabricante del dispositivo, el modelo, la precisión, el instalador, la
fecha de la última operación de mantenimiento y un largo etcétera. Hay propiedades
que se establecen por fabricación y ofrecen información estática, mientras que otras son
modificables por el instalador, el usuario o, incluso, los servicios o aplicaciones.
i
i
i
i
i
i
i
i
136
5. D ESCUBRIMIENTO DEL ENTORNO
La finalidad de las propiedades es doble:
Permiten clasificar y discriminar servicios. Facilita al cliente la tarea de encontrar
aquel que más se acerca a sus necesidades concretas. Como se verá, a cada servicio
le corresponde un conjunto posible de propiedades que se puede comparar con los
requisitos del usuario para evaluar en qué medida satisface una necesidad concreta.
La otra utilidad de las propiedades está relacionada con las operaciones de gestión,
mantenimiento y administración del sistema. Aportan meta-información muy útil
para las aplicaciones finales en las que es necesario representar gráficamente el
entorno. Los servicios pueden proporcionar propiedades que almacenan iconos,
mapas, áreas de cobertura. Por ejemplo, una GUI para manipulación de una cámara
tipo PTZ es mucho más útil y amigable si fuerza el valor de los ángulos límite
(mínimo y máximo) que puede tomar físicamente el motor correspondiente.
Se proporciona también soporte para meta-propiedades, es decir, datos referentes a
una propiedad. Por ejemplo, si un servicio tiene una propiedad position puede ser
necesario saber respecto a qué referencia está tomada. Para ello se construyen nombres de
propiedades jerárquicos (separados con el carácter ‘.’); esa meta-propiedad se representaría
como position.origin.
Debe tenerse muy presente que la disponibilidad de los servicios prestados por los actores
no está supeditada a la disponibilidad de las propiedades. Si se configura un servicio que
relaciona ciertos objetos, ese servicio seguirá funcionando del mismo modo aunque las
propiedades de los servicios involucrados dejen de estar accesibles. El sistema ofrece
un modo degradado, pero completamente funcional, en el que no se podrá (o será más
complejo) buscar o configurar servicios nuevos, pero que no afectará a ninguno de los que
ya estuvieran en producción. Lo consideramos un principio de diseño del protocolo:
Ninguna relación entre objetos o servicio ya establecido se verá afectada si
posteriormente aparecen problemas temporales o permanentes en el acceso al
sistema de propiedades.
5.2.3.
Taxonomía
Para que los servicios proporcionados por los actores se puedan buscar es necesario
que tanto éstos como los clientes utilicen un vocabulario común para describirlos. Este
vocabulario está definido en una taxonomía, que incluye:
Una jerarquía de clases de servicios
Cada clase identifica unívocamente un servicio estándar que puede ser ofrecido por
un actor o demandado por un cliente. Cada clase se traduce en una interfaz de objeto
remoto. Cada actor puede ofrecer varios de estos servicios sin más que implementar
las interfaces correspondientes.
Una jerarquía de eventos
Los eventos son útiles para identificar situaciones especiales y realizar cambios de
estado que pueden afectar al funcionamiento de varios servicios.
i
i
i
i
i
i
i
i
5. D ESCUBRIMIENTO DEL ENTORNO
137
Un diccionario de propiedades
Define el conjunto de propiedades posibles que puede tener asociadas cada clase
de servicios: el nombre, el tipo de dato del valor, de sólo lectura o modificable,
obligatoria u opcional, etc.
Esta taxonomía se define por medio de una ontología que se almacena en un fichero
OWL. A partir de éste se obtiene toda la información necesaria, tanto para la definición de
servicios por parte de los actores, como de los clientes para solicitar servicios a la red.
La figura 5.1 muestra parte de la jerarquía de servicios. En todo caso, es previsible
que cada aplicación tenga su propia taxonomía, puesto que la orientación del problema
determina características y servicios relevantes que para otras aplicaciones podrían
ser completamente inútiles; aspirar a un taxonomía universal absoluta no es práctico
aparte de resultar muy complejo.
F IGURA 5.1: Clases de servicios definidos en la taxonomía. (V ILLANUEVA [Vil09])
5.3.
Prestaciones de ASDF
Por su enfoque integrador y flexible, el diseño del protocolo trata de recoger la mayoría
de los casos de uso que se pueden encontrar en los SDP más utilizados. Por el mismo
motivo se proporcionan alternativas centralizadas, distribuidas e híbridas para casi todos
ellos. Estas son las prestaciones más importantes:
i
i
i
i
i
i
i
i
138
5. D ESCUBRIMIENTO DEL ENTORNO
Registro
Siempre que sea posible se utilizan los mecanismos propios del middleware para
localización de objetos. En el caso de I CE, todo servicio que utilice el servidor de
aplicaciones puede quedar automáticamente registrado en el Registry.
Anunciamiento/despedida
Para aquellos actores más limitados (como el caso de picoObjetos) el acceso al
servicio de registro del middleware resulta demasiado complejo. En su caso envían
mensajes a través del actor ASDA. Se proporciona soporte para anunciamiento
proactivo y reactivo. También es posible su uso por cualquier servicio si no existe o
no se desea utilizar un registro.
Localización del directorio
En nuestro protocolo la funcionalidad del directorio está dividida. Los mecanismos
de búsqueda de servicios y descripción de los mismos son independientes.
La única referencia necesaria para realizar búsquedas es ASDS y asumimos que es
un objeto bien conocido tanto si es un canal de eventos como si es un actor al uso,
es decir, no es necesario buscarlo.
Búsqueda
La localización de un servicio concreto se logra mediante consultas explícitas a la
referencia ASDS por parte de las aplicaciones. El proceso de búsqueda en sí mismo
también puede ser centralizado, distribuido o híbrido.
En las siguientes secciones se describen las características y funcionamiento de cada
uno de estos casos. A menos que se indique lo contrario, se debe asumir que se trata
de las modalidades distribuidas de los mismos.
5.4.
Anunciamiento
Cuando un actor se conecta o vuelve de un estado de sleep su nodo envía un mensaje de
anunciamiento adv() a ASDA. Estos anuncios también pueden efectuarse (opcionalmente)
cada cierto tiempo, no necesariamente periódico. Éste es un mecanismo de anunciamiento
proactivo puesto que se realiza por iniciativa del servidor/ actor.
El método adv() corresponde a la interfaz ASD::Listener (ver listado 5.1). El argumento
prx es un proxy para contactar con el actor.
module ASD {
interface Listener {
idempotent void adv (Object∗ prx ) ;
idempotent void bye ( Ice :: Identity oid ) ;
};
};
L ISTADO 5.1: ASD::Listener: Interfaz para recepción de anunciamientos
i
i
i
i
i
i
i
i
5. D ESCUBRIMIENTO DEL ENTORNO
139
Los argumentos de este mensaje pueden ser completamente estáticos. El tamaño del
mensaje completo no supera los 100 bytes, aunque depende mucho del tipo de endpoint
que utilice el proxy: el tamaño de las direcciones lógicas y las identidades de objeto (véase
§ C.2). Gracias a ello es factible almacenarlo en memoria ROM en el propio dispositivo.
En el caso extremo, en que el nodo no fuese capaz de enviar el mensaje adv(), un agente
externo puede enviarlo por él si conoce su proxy. Sin embargo, esa es una situación a
evitar por la grave pérdida de autonomía que conlleva.
Los clientes y servicios interesados en recibir anuncios de los actores deben implementar
la interfaz ASD::Listener y estar suscritos al canal ASDA (ver figura 5.2). Cuando un
suscriptor recibe un evento adv() obtiene el proxy al actor anunciado y, desde ese momento,
puede utilizar los mecanismos de introspección estándar del middleware para averiguar
qué interfaces implementa, invocar sus métodos, etc.
F IGURA 5.2: Diagrama de secuencia de un anunciamiento
Se puede emplear también un servicio de anunciamiento centralizado (registro) sin
más que substituir el canal ASDA por un objeto. Éste almacenaría las referencias a los
objetos anunciados, es decir, sería parte de la funcionalidad de un directorio (véase § 5.6.3).
Un modelo híbrido también es posible mediante un Servicio de Caché (CacheService),
que se suscribe al canal ASDA, almacena y clasifica las referencias de todos los actores
que se anuncian, y las elimina cuando se despiden. Este modelo híbrido es similar a la
funcionalidad del Service Directory de UP N P en el sentido de que los anuncios/registros
pueden ser distribuidos (con o sin caché) o centralizados. Sin embargo, en el caso de ASDF
la ventaja es que el modelo elegido es transparente para los servicios.
Del mismo modo que ocurre en el anunciamiento, un actor también puede despedirse
(mensaje Listener::bye()) cuando va a dejar de estar disponible por un tiempo. Se
puede considerar información de cortesía, pues evitará que otros actores —que mantuviesen
una referencia— intenten contactar cuando el servicio ya no esté accesible. No es que eso
suponga un problema grave, pero ayuda a mantener la coherencia de la información
que unos servicios mantienen sobre otros y la convergencia de los protocolos que
impliquen búsquedas activas.
Si un servicio desaparece sin despedirse ocurrirá un error cuando un cliente que conocía
la referencia trate de utilizarlo. En ese caso, el cliente puede informar al resto de la
red enviando el mensaje bye() para dicho servicio, dado que conoce su identidad. Lo
mismo puede aplicarse si se está utilizando un registro o el servicio de caché. Si por
i
i
i
i
i
i
i
i
140
5. D ESCUBRIMIENTO DEL ENTORNO
error —o de forma maliciosa— un cliente envía mensajes bye() de servicios activos,
no supondrá ningún problema ya que quedarán obsoletos al recibir nuevos anuncios,
independientemente de que sean activos o proactivos. Además, resulta sencillo implementar
servicios de monitorización (como suscriptores de ASDA) que detecten mensajes adv() y
bye() para un mismo servicio, e informen convenientemente como causa probable de que
está ocurriendo un mal funcionamiento en el sistema. En el caso de picoObjetos nunca se
envían mensajes de despedida ya que se considera que son servicios siempre conectados,
lo cual favorece además la simplicidad de su implementación.
Es un mecanismo de anunciamiento de alto nivel puesto que se está distribuyendo
una referencia a objeto directamente invocable por el receptor. Sin embargo, puede
ser implementado en dispositivos muy simples con un comportamiento idéntico al de
un objeto convencional.
5.5.
Descripción de servicios
La descripción de un servicio individual requiere de dos elementos:
Una interfaz
La clase de servicio, en términos de la taxonomía, queda definida en el lenguaje de
especificación de interfaces del middleware. Son interfaces puramente declarativas,
es decir, no tienen métodos ni definen comportamiento alguno. Sirven únicamente
como etiquetado de los actores. Cualquier actor puede heredar de una o varias de
estas interfaces para indicar que es capaz de proporcionar los servicios asociados.
Un conjunto de propiedades
Las propiedades habitualmente representan restricciones o valores para condiciones
de entorno. Por ejemplo, un sensor de temperatura puede tener varias propiedades:
valores máximo y mínimo, precisión de la medida, situación, etc. Cada clase
de servicio tiene asociado un conjunto específico de propiedades. Si un actor
implementa varias interfaces de servicio, tendrá varios conjuntos de propiedades,
aunque se accedan a través de una misma referencia.
El listado 5.2 muestra parte del fichero Services.ice que contiene las interfaces (en
lenguaje Slice) que corresponden a las distintas clases de servicios. Se ha desarrollado
una herramienta llamada ows2slice que genera automáticamente este fichero a partir
de la descripción OWL de la taxonomía.
module Services {
interface Prese nceSenso r {};
interface T e m p e r a t u r e S e n s o r {};
interface MotionSensor {};
[...]
};
L ISTADO 5.2: Services.ice: Definición de interfaces para servicios
i
i
i
i
i
i
i
i
5. D ESCUBRIMIENTO DEL ENTORNO
141
En las próximas secciones veremos cómo y dónde se almacena la información de
descripción del servicio.
5.5.1.
Servicios proporcionados
La clase de servicio la mantiene la propia implementación del actor, heredando de
la interfaz correspondiente. En el caso de un objeto convencional, el compilador de
interfaces genera un esqueleto de implementación que incorpora la definición de esas
interfaces como corresponda al lenguaje de implementación elegido para el servidor. En el
caso de un picoObjeto, la propia implementación del autómata almacena estáticamente
la información necesaria.
Es muy simple determinar qué servicios implementa un actor a partir de una referencia;
basta utilizar los mecanismos de introspección incorporados. En CORBA la única
posibilidad es el método is_a() (véase § 2.3.3), mientras que en I CE existen los métodos
ice_id(), ice_ids() y ice_isA() (véase § 2.3.4).
Múltiples servicios por actor
Las interfaces que definen servicios siguen una jerarquía de especialización. Por
ejemplo, el servicio VideoCamera es una subclase del servicio ImageSource. Un actor que
implementa el servicio Camera hereda todos los servicios definidos como supertipos en la
jerarquía hasta la clase raíz (Service) y con ellos también sus propiedades asociadas.
Los objetos también pueden utilizar herencia múltiple para implementar varios servicios
a la vez, lo que significa que pueden ser utilizados con distintos roles. Siguiendo el ejemplo
anterior, el objeto podría implementar además el servicio PhotoCamera, que también
es una especialización del ImageSource tal como muestra la figura 5.3. El código de
especificación para la nueva interfaz podría ser el que aparece en el listado 5.3.
interface MyCam extends Services :: VideoCamera , Services :: PhotoCamera
{};
L ISTADO 5.3: Herencia (incorrecta) de múltiples servicios
Sin embargo, esto plantea un problema: como el servicio ImageSource tiene asociada
la propiedad resolution, un objeto de clase MyCam heredaría dicha propiedad a través
de dos caminos de herencia diferentes. Evidentemente la propiedad sólo puede tener un
valor, pero rara vez una cámara de vídeo que puede ser usada como cámara de fotos
tiene la misma resolución en ambos modos.
La solución pasa por asumir cada servicio como una faceta diferente utilizando la
interfaz DUO::Component (véase § 3.5). Aunque esta es la solución general, realmente
no ocurre en todos los casos. La mayoría de las combinaciones de interfaces no producen
este tipo de conflictos en las propiedades heredadas.
i
i
i
i
i
i
i
i
142
5. D ESCUBRIMIENTO DEL ENTORNO
F IGURA 5.3: Ejemplo de herencia múltiple de interfaces para servicios
5.5.2.
Persistencia de las propiedades
Las propiedades asociadas a un objeto se acceden por medio de la interfaz
PropertyService::PropertySetDef, que corresponde a la especificación del servicio Property
Service [Obj00] de OMG.
Se consideran tres posibilidades (excluyentes) que pueden darse a la hora de acceder
a las propiedades de un servicio y que determinan dónde pueden estar realmente
almacenadas:
En el actor
Si el actor implementa la interfaz PropertyService::PropertySetDef, él mismo sirve
sus propiedades. Este caso es el habitual cuando se trata de objetos implementados
con las herramientas estándar del ORB.
Se ha creado una biblioteca denominada libPropertyServer que capacita a un
objeto para servir sus propiedades y le confiere persistencia automática por medio
de Freeze (véase § 2.3.4).
En un Servidor de Propiedades
Cuando un objeto no tiene suficiente capacidad (principalmente memoria) para
gestionar sus propiedades y/o posibilidad de almacenar sus valores de forma
persistente puede delegar esta responsabilidad en un servidor de propiedades que
llamamos PropertyServer (véase § 5.5.3).
Para ello, el objeto implementa la interfaz ASD::PropHldr (ver listado 5.4). Mediante
el método getp(), el cliente solicita al objeto el proxy del objeto que mantiene sus
propiedades, el cual implementa la interfaz PropertyService::PropertySetDef, de
modo que al tratarse de una indirección no supone apenas complejidad adicional
para los clientes.
i
i
i
i
i
i
i
i
5. D ESCUBRIMIENTO DEL ENTORNO
143
El objeto no tiene propiedades
Si el actor no implementa la interfaz PropertyService::PropertySetDef ni tampoco ASD::PropHldr significa que no hay propiedades disponibles a pesar de que
implemente alguna interfaz de servicio. Esto puede ocurrir en objetos extremadamente simples o que forman parte de un actor más complejo como ocurre en los
contenedores (véase § 3.3) o los componentes (véase § 3.5).
module ASD {
interface PropHldr {
idempotent P ro pe rt y Se rv ic e :: Prop ertySetD ef ∗ getp () ;
};
};
L ISTADO 5.4: ASD::PropHldr: Delegación de propiedades a un objeto externo
5.5.3.
Servidor de propiedades
El almacenamiento de propiedades por delegación, es decir, cuando el actor utiliza la
interfaz ASD::PropHldr implica la necesidad de un servicio especializado encargado
de la persistencia de gran cantidad de objetos.
Para cubrir esta necesidad se ha diseñado e implementado PropertyServer. Es un
servicio IceBox que implementa únicamente la interfaz PropertyService::PropertySetDef.
Para poder servir las propiedades de varios servicios (potencialmente cientos) utiliza
un localizador de sirvientes modificado. Realmente sólo hay un sirviente encargado
de localizar en una base de datos las propiedades que corresponden al objeto cuya
identidad se ha utilizado para la invocación, aunque ese objeto no existe realmente
en el adaptador. Para el cliente no hay diferencia, pero supone una gran ventaja en
la escalabilidad de la solución.
También por razones de escalabilidad, los actores no deberían delegar sus propiedades
a instancias del PropertyServer fuera de su dominio.
5.6.
Búsqueda de servicios
El mecanismo básico de búsqueda de servicios implica al canal ASDS y a los actores
suscritos al mismo.
Cuando un cliente necesita buscar un servicio, crea un canal de eventos como callback
para las respuestas y se suscribe a sí mismo a dicho canal (ver figura 5.4). Después, envía
un mensaje lookup() (ver listado 5.5) al canal ASDS indicando:
La interfaz del servicio que desea (la clase de la taxonomía).
Un conjunto de propiedades que deben satisfacer los servicios.
El proxy del canal que ha creado. La aplicación también es responsable de su
eliminación cuando no sea necesario.
i
i
i
i
i
i
i
i
144
5. D ESCUBRIMIENTO DEL ENTORNO
module ASD {
interface Search {
idempotent void lookup ( ASD :: Listener ∗ cb , string tid ,
P ro pe rt y Se rv ic e :: Properties query ) ;
idempotent void discover ( ASD :: Listener ∗ cb ) ;
};
};
L ISTADO 5.5: ASD::Search: Interfaz para búsqueda de servicios
Quién y cómo se manejan estos mensajes de búsqueda por parte de los suscriptores
del canal ASDS es lo que determina qué tipo de directorio se está usando. El resto de
esta sección evalúa las diferentes posibilidades.
5.6.1.
Directorio distribuido puro
Cuando un actor (suscrito al canal ASDS) decide que cumple el criterio de búsqueda
recibido a través de un mensaje lookup(), envía un mensaje adv() convencional al canal
que aparece en el mensaje de búsqueda. Este procedimiento se muestra como diagrama de
secuencia en la figura 5.4. Si hay otras aplicaciones o clientes interesados en las posibles
respuestas simplemente pueden suscribirse también al canal creado por la aplicación
interrogadora. Esto es útil si se quiere implementar un servicio de cacheado de búsquedas
o simplemente a efectos de registro de actividades.
Para asegurar que las respuestas de los actores no llegan antes que la suscripción
de terceros, los actores esperan un tiempo fijo antes de enviar su anunciamiento. Es
interesante la posibilidad de que esperen un tiempo adicional aleatorio antes de contestar
para mejorar la escalabilidad de la solución, aunque la propia latencia de la red puede
ser suficiente en muchos casos1 para evitar el pico de tráfico de red que pueden suponer
las respuestas de los nodos en redes muy grandes.
En este escenario no hay ningún elemento central que procese las búsquedas. La única
referencia común es el canal ASDS, pero este mecanismo de distribución puede ser
substituido de forma transparente por un endpoint multicast si la tecnología de red lo
soporta. Se trata por ello de un directorio distribuido o P2P.
5.6.2.
Directorio híbrido
Teniendo en cuenta la información de que dispone el PropertyServer, es posible
enriquecer su funcionalidad para darle un papel activo en el descubrimiento de
servicios y convertirlo así en un servicio de directorio concreto, que llamamos
ServiceDirectory.
Este directorio se suscribe al canal ASDS. Recibe peticiones lookup(), evalúa las
consultas sobre los actores que conoce y responde enviando anuncios para los servicios que
correspondan. Se trata de una funcionalidad muy interesante pues permite buscar servicios
alojados en picoObjetos sin que esos nodos tengan que soportar dicha funcionalidad, y
todo de forma transparente para la aplicación cliente (véase § 5.5.2).
1 Debido
el pequeño tamaño de los mensajes.
i
i
i
i
i
i
i
i
5. D ESCUBRIMIENTO DEL ENTORNO
145
F IGURA 5.4: Búsqueda de servicios con directorio distribuido puro
Dado que no hay ningún motivo que impida la coexistencia de varios PropertyServer
o ServiceDirectory en un mismo dominio —a condición de que las propiedades de un
objeto dado estén en el mismo servidor— el mecanismo expuesto hace posible también
un modelo de directorio distribuido estructurado.
Este directorio no substituye al mecanismo de búsqueda abordado en la sección
anterior, lo complementa, de ahí que se denomine híbrido. La única precaución que
debe tomar el Servicio de Directorio es esperar un tiempo adecuado por si los servicios
involucrados respondiesen por sí mismos. En el caso peor, tanto el actor como el directorio
enviarían mensajes idénticos al canal de la aplicación interrogadora. Al ser información
idempotente, no tendría ninguna consecuencia negativa importante, salvo el pequeño
desperdicio de ancho de banda que implica.
Nótese que los clientes del SDP no requieren de un mecanismo específico para
encontrar los directorios puesto que estos están suscritos al canal ASDS y reciben las
peticiones de forma indirecta. La asociación ServiceDirectory/PropertyServer
responde únicamente a razones prácticas puesto que utilizan básicamente la misma
información. Ni los clientes ni ningún otro componente del sistema necesitan saberlo.
No debería asumirse que siempre ocurre de ese modo ya que es posible implementar
directorios que recopilan información de otra forma como se verá en la sección 5.6.4.
5.6.3.
Directorio centralizado
Para lograr un modelo de directorio centralizado se substituye el canal ASDS por un
ServiceDirectory. En este caso ningún actor sirve sus propiedades ni se suscribe a
ningún canal. En esta situación, el directorio debería ser un suscriptor de ASDA para
mantener la coherencia de la información que mantiene o, incluso, la referencia ASDA
podría apuntar al propio ServiceDirectory, tal como se apunta en la sección 5.4.
Aunque la situación es sensiblemente diferente para los actores, no implica ningún
cambio para los clientes, que seguirán usando la referencia ASDS de la forma habitual. La
i
i
i
i
i
i
i
i
146
5. D ESCUBRIMIENTO DEL ENTORNO
única diferencia es que ahora apunta a un objeto y no a un canal, pero esa circunstancia no
afecta absolutamente en nada al funcionamiento o implementación de los clientes.
Aunque esta modalidad de directorio tiene evidentes desventajas, puede ser una
alternativa valiosa en determinadas circunstancias. Es responsabilidad del diseñador
decidir cuál es la solución oportuna.
5.6.4.
Directorio jerárquico
Ningún mecanismo de búsqueda de servicios puede escalar indefinidamente; al igual
que la mayor parte del protocolo ASDF, éste está diseñado para funcionar en entornos
con un número de dispositivos predecible. Sin embargo, puede ser necesario acceder a
servicios prestados por un dominio de nivel superior. Si el middleware que se está usando
es I CE se puede utilizar para ello uno de sus servicios estándar: IceGrid.
IceGrid ofrece muchas prestaciones orientadas al desarrollo de aplicaciones en grid,
tales como balanceo de carga, migración, activación implícita, etc. En nuestro caso nos
interesan especialmente dos de ellas:
IceGrid/Locator
Permite contactar con objetos concretos a partir de un proxy indirecto. Deben estar
registrados previamente en otro componente llamado IceGrid/Registry.
IceGrid/Query
Es una interfaz para consultar la base de datos de objetos conocidos por el Registry.
El listado 5.6 muestra algunos de los métodos de la citada interfaz.
interface Query {
Object∗ findO bjectByI d ( Ice :: Identity id ) ;
Object∗ f i n d O b j e c t By T y p e (string type ) ;
Ice :: O bjectPro xySeq f i n d A l l O b j e c t s B y T y p e (string type ) ;
Ice :: O bjectPro xySeq f in d Al lR ep l ic as (Object∗ proxy ) ;
};
L ISTADO 5.6: Interfaz IceGrid::Query
Así pues, el componente IceGrid/Query sirve como sistema de directorio de servicios ya
que permite obtener uno o todos los actores que implementan un servicio dado. Sin
embargo, eso solo resuelve parte del problema. Es necesario implementar un objeto
Locator con capacidad para redirigir peticiones al dominio superior cuando se requiera.
Además, es necesario comprobar que esos objetos cumplen el criterio expresado por
el conjunto de propiedades.
Desde el punto de vista de clientes y actores, este nuevo componente, llamado
ExternalLocator, actúa de forma transparente y para el cliente tiene un comportamiento
indistinguible al descrito para el directorio centralizado (véase § 5.6.3).
Desde el punto de vista estructural la diferencia es que el ExternalLocator funciona
como un directorio jerárquico de dos niveles (ver figura 5.5).
i
i
i
i
i
i
i
i
5. D ESCUBRIMIENTO DEL ENTORNO
147
F IGURA 5.5: Delegación de la búsqueda de servicios al dominio superior
5.6.5.
Anunciamiento reactivo
ASDF también ofrece soporte para anuncios reactivos como una particularización
del mecanismo de búsqueda.
Los anuncios proactivos (véase § 5.4) pueden plantear problemas de escalabilidad si la
red de comunicaciones tiene poco ancho de banda y, sobre todo, de consumo de energía
si el servicio se aloja en un dispositivo alimentado por baterías.
Una vez dado a conocer un servicio, los anunciamientos proactivos (periódicos o no)
tienen poca utilidad. Únicamente pueden servir como heartbeat para que un hipotético
servicio de monitorización de la red asuma que dicho servicio anunciado sigue estando
activo sin necesidad de tener que invocarlo.
Para estas situaciones se proporciona una interfaz para soporte de anunciamiento
pasivo. El mecanismo es sencillo, cuando el objeto recibe una invocación a su método
discover() (para lo cual debe implementar la interfaz ASD::Search) envía un mensaje
adv() al proxy que aparece en la invocación. Ese proxy puede ser el canal ASDA
si el cliente así lo decide.
El método de anunciamiento reactivo se puede utilizar en los dos escenarios de
canales de eventos:
Cuando el actor dispone de un endpoint multicast estáticamente vinculado el canal
ASDS (sin servicio de eventos).
Cuando se utiliza el servicio de eventos y se dispone del proxy del canal ASDS en
tiempo de compilación. En este caso, los picoObjetos se suscriben al canal en el
arranque del nodo.
Si no se da ninguna de estas condiciones no es posible utilizar anunciamientos reactivos
ya que para enviar un mensaje al actor se requeriría su proxy, y precisamente ésa es
la finalidad del anunciamiento.
i
i
i
i
i
i
i
i
148
5. D ESCUBRIMIENTO DEL ENTORNO
5.7.
Servicio de metamodelo
Nuestro SDP también proporciona acceso remoto al modelo de servicios a través
de un servicio llamado MIS (Model Information Service), que implementa la interfaz
MIS::Metamodel.
Éste permite a cualquier componente del sistema acceder a la taxonomía de servicios
y propiedades. Es posible averiguar de un modo sencillo cuál es el conjunto válido de
propiedades para una clase dada, las relaciones entre clases, etc. El listado 5.7 muestra
la interfaz MIS::Metamodel en lenguaje Slice. MIS::MetaClass es un tipo que se utiliza
para describir clases de la ontología (una metaclase). Incluye métodos para obtener la
especificación de las propiedades posibles para el servicio que representa y averiguar
cuáles son las subclases disponibles.
module MIS {
interface MetaClass ;
dictionary <string , MetaClass ∗ > MetaClassDict ;
exception N o S u c h C l a s s E x c e p t i o n { string typeID ; };
interface MetaClass {
P ro pe rt y Se rv ic e :: Pro pertySetD ef ∗ g e t P r o p e r t i e s S p e c () ;
MetaClassDict getSubClasses () ;
};
interface MetaModel extends Service :: MetaModel {
MetaClass ∗ getClass (string typeId ) throws N o S u c h C l a s s E x c e p t i o n ;
MetaClassDict getClasses () ;
};
};
L ISTADO 5.7: Interfaz Slice de MIS
El servicio de metamodelo resulta muy útil para construir herramientas de administración.
Es posible editar las propiedades de los servicios validando las reglas que impone la
taxonomía por medio de acceso remoto al propio modelo. MIS::Metamodel es una
herramienta de introspección que ofrece acceso inmediato al conjunto de servicios posibles
y a sus definiciones de forma programática.
5.8.
Conclusiones
ASDF es un SDP potente, con un diseño altamente flexible, capaz de cubrir necesidades
muy diversas y adaptándose a las peculiaridades del middleware sobre el que se implemente,
pudiendo suplir, si es necesario, la ausencia de transporte multicast o servicios como
el de notificación de eventos.
El protocolo completo solo define 5 mensajes diferentes para cubrir todos los escenarios.
Es lo suficientemente sencillo como para ser implementado en dispositivos muy limitados,
bajo el enfoque de diseño de picoObjeto ya que el almacenamiento de propiedades —la
característica más costosa— se puede delegar a dispositivos más capaces. Los nodos
i
i
i
i
i
ASDS es el ServiceDirectory.
PropertyServer.
Anunciamiento / despedida
Directorio (búsquedas)
Persistencia de las propiedades
ASDS es un canal de eventos (no hay directorio). Los
actores responden a las búsquedas.
Los actores sirven las propiedades.
tos.
Ambos.
ServiceDirectory subscrito
a ASDA.
ServiceDirectory subscrito
a ASDS. Ambos responden.
CacheService.
Basado en anunciamientos.
ASDA es un canal de even-
híbrido
distribuido
C UADRO 5.1: ASDF: Resumen de las prestaciones del protocolo
Basado en los servicios del middleware.
ASDA es el ServiceDirectory.
Registro
centralizado
i
i
i
i
5. D ESCUBRIMIENTO DEL ENTORNO
149
i
i
i
i
i
i
i
150
5. D ESCUBRIMIENTO DEL ENTORNO
de la SAN se integran en la infraestructura sin necesidad de ninguna configuración
previa ni de la intervención de ningún operador humano. El anunciamiento ofrece en
un solo mensaje toda la información que el entorno inteligente requiere para localizar
el nuevo actor y empezar a utilizarlo.
El cuadro 5.1 resume las distintas alternativas que proporciona ASDF para soportar las
prestaciones típicas de los SDP. Nótese que las columnas de dicho cuadro no representan
escenarios excluyentes, es decir, es posible un escenario en el que exista búsqueda
centralizada y anunciamiento distribuido al mismo tiempo.
Por último, el servicio MIS ofrece un medio sencillo y potente para realizar introspección
del modelo de servicios de un modo programático.
i
i
i
i
i
i
i
i
Flujo de diseño
6.1.
6.2.
6.3.
6.4.
6.5.
Lenguaje IcePick
Lenguaje SIS
El compilador ipkc
Drivers
Plataforma para desarrollo de picoObjetos
66
L
LEGADOS a este punto, disponemos de los mecanismos y herramientas necesarios
para construir una red SAN formada por nodos cuyos transductores son accesibles
como objetos remotos por medio de picoObjetos. Sin embargo, el programador debe
realizar una ardua tarea para conseguirlo: para cada nodo debe escribir un fichero
FSM especificando cada detalle de cada mensaje del protocolo que el picoObjeto debe
reconocer o generar. Además de resultar una tarea tediosa y propensa a errores, requiere
del programador un profundo conocimiento del formato y detalles de bajo nivel del
protocolo inter-ORB correspondiente.
Se hace necesario disponer de un lenguaje de alto nivel que permita abstraer al
programador de todos esos detalles: IcePick. Con este lenguaje se puede escribir un
fichero que incluye la especificación de un nodo en el que residen uno o varios objetos.
Después, un compilador (ipkc) se encarga de generar código FSM que, posteriormente,
podrá ser a su vez compilado a bytecode. La figura 6.1 muestra un diagrama simplificado
del proceso completo de compilación. A lo largo de este capítulo se refinará este
diagrama incluyendo más detalles.
Disponer de un lenguaje de más alto nivel no invalida FSM. Hay varios motivos
para mantenerlo:
A partir del lenguaje FSM es posible plantear la generación de bytecode o bien de
código nativo (véase § 4.8). Esto pueden hacerlo dos herramientas independientes.
Si no existiera el lenguaje FSM, el compilador ipkc debería dar soporte a
ambas alternativas por sí mismo, aumentando la complejidad de su diseño e
implementación.
FSM permite depurar de un modo mucho más sencillo y rápido la salida del
compilador ipkc. Es posible escribir baterías de pruebas que comprueben la validez
151
i
i
i
i
i
i
i
i
152
6. F LUJO DE DISEÑO
F IGURA 6.1: Diagrama simplificado del proceso de compilación
del resultado comparando con ficheros FSM correctos. Hacerlo con bytecode
implicaría disponer de la misma versión en todos los lenguajes de implementación
soportados.
FSM permite al diseñador escribir código a mano para poder experimentar con las
posibilidades de la Virtual ISA (V-ISA) y plantear mejoras o detectar errores sin
tener que modificar ipkc. Sólo cuando se ha comprobado que esos cambios son
ventajosos se plantea la modificación del backend de ipkc.
FSM impone una interfaz que aisla al lenguaje de alto nivel (IcePick) de los detalles
relacionados con la máquina virtual o de la generación de código nativo, si fuera el
caso.
6.1.
Lenguaje IcePick
El objetivo del lenguaje IcePick es definir el conjunto de objetos distribuidos que ha
de alojar un nodo abstrayendo todos los detalles de bajo nivel. Concretamente, un fichero
en lenguaje IcePick incluye los siguientes datos:
Inclusión de interfaces (los tipos de los objetos).
Declaraciones de objetos.
Declaraciones de adaptadores remotos.
Declaraciones de adaptadores locales, normalmente sólo uno, pero puede haber más.
Definición de triggers.
i
i
i
i
i
i
i
i
6. F LUJO DE DISEÑO
6.1.1.
153
Especificación de interfaces
Cualquier MDOO incluye algún lenguaje para especificar el contrato (interfaz) entre
el objeto y sus clientes. Las cláusulas uses de IcePick se utilizan para hacer referencia
a ficheros que contienen las declaraciones de estas interfaces.
Tanto el lenguaje como el compilador están diseñados de modo que sean independientes
del middleware utilizado. El compilador admite la posibilidad de incluir nuevos lenguajes
de especificación de interfaces por medio de bibliotecas. Hasta el momento sólo hay
disponibles frontends de S LICE (Specification Language for Ice) e IDL, pero se puede
considerar la posibilidad de construir otros para sistemas como WSDL, Remoting o
Java RMI.
Como resultado del procesamiento de dichos ficheros, el compilador construye una
tabla de símbolos que incluye todas las interfaces declaradas, con sus relaciones de
herencia, métodos en cada interfaz, etc.
Los nombres de estas interfaces y métodos están disponibles para el resto del fichero
IcePick. Independientemente del formato que tuvieran en el lenguaje original, los nombres
de las interfaces se indican como una ruta de herencia utilizando el carácter ‘.’ como
separador (puede ver un ejemplo en el listado 6.1). IcePick no permite declarar interfaces
adicionales. Únicamente se pueden utilizar las contenidas en los ficheros incluidos por
medio de la cláusula uses.
6.1.2.
Objetos
La declaración de un objeto identifica una entidad lógica sobre la que se pueden
realizar invocaciones. Todo objeto lleva asociado un tipo declarado en un fichero
incluido con uses.
La declaración de un objeto consta de:
La palabra reservada object.
Un tipo (interfaz remota).
Un identificador dentro del fichero IcePick.
Un bloque con argumentos (que puede ser vacío).
El listado 6.1 muestra la declaración de varios objetos.
1
uses " DOBS / DUO . ice ";
3
4
5
6
7
8
object
mode
};
object
object
object
DUO . IBool . RW lock {
= oneway ;
DUO . IFloat . R ldr ;
ASD . Listener asda ;
DUO . IBool . W signal ;
L ISTADO 6.1: IcePick: Definición de objetos
i
i
i
i
i
i
i
i
154
6. F LUJO DE DISEÑO
Argumentos
El bloque de argumentos que se puede incluir en la declaración de un objeto funciona
como un diccionario genérico clave/valor. Existen algunas claves predefinidas, pero es
posible incorporar otras, como se verá a continuación. Los argumentos permiten añadir
información adicional necesaria en casos especiales.
El argumento mode indica si el objeto tiene capacidad para devolver valores de respuesta.
Si su valor es oneway significa que no la tiene y, por tanto, el compilador puede realizar
optimizaciones avisando si alguno de los métodos de las interfaces que implementa requiere
devolver parámetros. Se utiliza para evitar la generación de los métodos de soporte de
introspección que se incluyen por defecto, que en ese caso, serían inútiles.
También es posible definir facetas utilizando argumentos. Una faceta es similar a un
objeto convencional. La diferencia es que debe incluir dos argumentos especiales:
facet – Es la cadena que identifica la faceta.
default – Es el identificador de objeto de la faceta por defecto a la que está asociado.
El listado 6.2 muestra un ejemplo de definición de un objeto con una faceta.
uses " DOBS / DUO . ice ";
object DUO . IByte . RW light ;
object DUO . IBool . RW bool_light {
default = light ;
facet =
" bool ";
};
L ISTADO 6.2: IcePick: Definición de una faceta
6.1.3.
Adaptadores
El adaptador de IcePick es prácticamente equivalente al mismo concepto tal como se ha
utilizado a lo largo del texto (ver glosario). Cada adaptador IcePick se declara con:
Un tipo (local o remote).
La palabra reservada adapter.
Un identificador.
La representación textual de uno o varios endpoints.
Un mapa de objetos.
El formato de la representación textual del endpoint depende completamente del
middleware que se esté empleando. Así, en CORBA será un perfil de IOR (véase § 2.3.3),
mientras que en I CE será un stringfied proxy (véase § 2.3.4).
La declaración de un adaptador incluye obligatoriamente un conjunto de identificadores
de objetos y las identidades a las que estarán asociados en ese adaptador. Eso significa
i
i
i
i
i
i
i
i
6. F LUJO DE DISEÑO
155
que estarán accesibles a través de los endpoints de ese adaptador. Es posible asociar un
mismo objeto a más de un adaptador, con la misma identidad o distintas; o simplemente
no asociarlo a ningún adaptador, caso en el que no será accesible remotamente.
El listado 6.3 muestra un ejemplo que define dos adaptadores (uno de cada tipo)
y varios objetos.
uses " DOBS / DUO . ice ";
uses " DOBS / ASDF . ice ";
object DUO . IBool . W signal ;
object DUO . IByte . RW obj1 ;
object ASD . Listener asda ;
local adapter node {
endpoint = " tcp −h 20.0.0.2 −p 2030" ;
objects = {" UUID1 ": signal , " UUID2 ": obj1 };
};
remote adapter gateway {
endpoint = [" xbow −h 20740" , " tcp −p 2000"];
objects = {" IceStorm / ASDA . publisher ": asda };
};
L ISTADO 6.3: IcePick: Declaración de adaptadores
6.1.4.
Eventos
En la sección 4.5.6 se explicaba cómo el picoObjeto funciona como una máquina
dirigida por eventos. Por esa razón, el lenguaje IcePick ofrece soporte para especificar
eventos concretos y la forma en que deben ser atendidos (un manejador). Las cláusulas
para especificación de eventos (triggers) implican un hecho y un conjunto de acciones
que se llevarán a cabo como consecuencia. Existen cuatro cláusulas:
boot
Es un evento que se lanza en el arranque del dispositivo o cuando se reinicia, y
una vez ha terminado de inicializarse. Sólo puede haber una cláusula boot en cada
programa IcePick. En el manejador de este evento se inicializan los manejadores
del resto de eventos y se realizan tareas de inicialización específicas del dispositivo
invocando métodos del sirviente.
timer
Define un evento que se lanza periódicamente con el intervalo especificado. Se
pueden definir varias cláusulas timer en un mismo programa.
when
Define un evento que se lanza al producirse una invocación sobre un método de un
objeto local concreto. Puede haber varias cláusulas when.
event
Define un manejador para un evento aportado por el programador del transductor (en
el sirviente). Esto es necesario para poder indicar al picoObjeto que cierta situación
i
i
i
i
i
i
i
i
156
6. F LUJO DE DISEÑO
ha ocurrido en el dispositivo. Típicamente se tratará de una lectura asíncrona
procedente de un sensor, aunque pueden darse otras situaciones. La cláusula event
permite definir el comportamiento asociado a un evento cuya aparición queda fuera
de la responsabilidad del código generado, es decir, el programador debe informar
explícitamente de que ese evento se ha producido por medio de la instrucción
raise_event() (véase § 4.5.3). Esta característica es la que hace posible definir
comportamientos proactivos (véase § 3.4.2).
El manejador de un evento es un conjunto de acciones que deben ejecutarse cuando se
activa. Se especifica con un bloque que contiene una o más invocaciones a métodos. Éstos
pueden corresponder tanto a objetos locales como remotos y deben estar declarados. El
listado 6.4 muestra un ejemplo que incluye una cláusula de cada tipo de evento.
1
2
3
boot {
signal . subscribe ( lock , lock . qos () ) ;
}
5
6
7
8
timer (30) {
asda . adv ( lock ) ;
asda . adv ( ldr ) ;
}
10
11
12
when ldr . get () do {
lock . test () ;
}
14
15
16
event AUTOL OCK_EVEN T do {
lock . set ( True , lock . oid ) ;
}
L ISTADO 6.4: IcePick: Cláusulas para definición de triggers
Gestión de triggers
Todos los triggers definidos en un fichero IcePick están activos por defecto y se lanzarán
según sus reglas (véase § 6.1.4) una vez que el picoObjeto ha arrancado.
Para permitir mayor flexibilidad y dar soporte a comportamientos más complejos, IcePick
permite especificar la activación/desactivación de los triggers, a excepción de boot.
Para lograrlo primero es necesario nombrar el trigger; por defecto son anónimos. El
nombrado se consigue escribiendo una etiqueta que se sitúa antes de la cláusula que
define el trigger y seguida del carácter ‘:’. Después, se utiliza el método enable()
con un parámetro booleano.
Esta característica es de gran utilidad para definir distintos comportamientos en el mismo
nodo dependiendo de condicionantes externos. Por ejemplo, un sensor de movimiento
que envía eventos sólo cuando se ha establecido un modo de alerta. Con ello se
logra ahorrar mensajes, evitando el consumo de energía para ese nodo y aquellos que
deberían encaminar ese mensaje.
i
i
i
i
i
i
i
i
6. F LUJO DE DISEÑO
157
Como ejemplo, el listado 6.5 muestra un fragmento de un fichero IcePick en el
que se utilizan estas instrucciones. El evento auto_off (línea 5) se encarga de apagar
automáticamente la luz controlada por el objeto light una vez pasados 15 ticks. El evento
auto_off no se repite puesto que su propio manejador lo desactiva (línea 7).
1
2
3
boot {
auto_off .enable( false ) ;
}
5
6
7
8
auto_off : timer (15) {
light . set ( false , "") ;
auto_off .enable( false ) ;
}
10
11
12
when light . set () do {
auto_off .enable( true ) ;
}
L ISTADO 6.5: IcePick: Instrucciones para gestión de eventos
6.1.5.
Funciones
Para evitar repetir código IcePick es posible definir funciones. Una función es una
secuencia de instrucciones con un nombre asociado. Para invocarla se utiliza un método
llamado run(). Vea un ejemplo en el listado 6.6.
propagate : function {
obj2 . set ( obj1 . get () , obj1 . oid ) ;
obj3 . set ( obj1 . get () , obj1 . oid ) ;
}
when obj1 . set do {
propagate . run () ;
}
L ISTADO 6.6: IcePick: Funciones
6.1.6.
Atributos por defecto en objetos
Todos los objetos asociados a un adaptador local tienen dos atributos especiales. Intentar
acceder a ellos en otro caso provocará un error de compilación. Son los siguientes:
Identidad del objeto
Se obtiene escribiendo el identificador del objeto seguido de un punto y el
identificador oid, tal como puede verse en el segundo argumento del método set()
en la línea 15 del listado 6.4.
Proxy
El compilador generará un proxy completo para el objeto, simplemente escribiendo
su identificador, tal como se ve en las líneas 6 y 7 del listado 6.4.
i
i
i
i
i
i
i
i
158
6. F LUJO DE DISEÑO
6.1.7.
Métodos
Dentro del bloque asociado al manejador de un evento se pueden realizar invocaciones
a dos tipos de métodos:
Métodos remotos
Corresponden con los métodos accesibles remotamente, es decir, especificados en la
interfaz que implementa el objeto. Es posible invocar métodos remotos de cualquier
objeto, independientemente si el objeto es remoto o local, aunque solo se obtiene un
posible valor de retorno cuando el objeto es local.
Métodos locales
El sirviente suministrado por el programador del dispositivo (escrito en el lenguaje
específico de la plataforma) debe contener implementaciones para todos los métodos
remotos declarados en la interfaz que implementa. Pero también puede contener
métodos adicionales que pueden ser invocados únicamente desde el propio nodo. A
esos métodos son los que denominamos locales.
IcePick no dispone de un operador de asignación, de modo que no es posible recoger el
valor de retorno de un método. El único caso en el que se puede utilizar el resultado de
una invocación es usándolo como parámetro de otra; tal es el caso de la invocación
lock.qos() en el listado 6.4 (línea 2).
6.2.
Lenguaje SIS
Los middlewares convencionales proporcionan bindings para unos cuantos lenguajes
de uso común. Eso ofrece la posibilidad de implementar el sirviente en el lenguaje que
el programador considere más adecuado para la aplicación. Estos lenguajes suelen ser de
alto nivel puesto que el esqueleto del servidor y el código del sirviente se compilan
juntos para obtener un binario.
En el caso de los picoObjetos, la situación es sensiblemente distinta. Para aprovechar
al máximo las posibilidades y capacidad del dispositivo se crea una implementación de
la máquina virtual en el lenguaje propio de la plataforma, típicamente C, Java o algún
ensamblador. Debido a la forma en que la máquina virtual ejecuta el código del sirviente
(véase § 4.7.1) éste debe estar implementado en el mismo lenguaje que la máquina virtual.
Lo mismo es aplicable incluso aunque el autómata fuese compilado a código nativo
en lugar de a bytecode (véase § 4.8).
Se podría utilizar una estrategia diferente decidiendo por diseño un lenguaje común
para cualquier sirviente y también para la máquina virtual, tal es el caso de Maté [LC02]
o WSP [BLV09]. Sin embargo, consideramos que esa alternativa no es conveniente para
nuestros objetivos. En muchos casos, incluso usando un lenguaje tan adaptable y ligero
como C, no siempre es posible aprovechar plenamente las posibilidades de los dispositivos
más simples por la sobrecarga que supone. Utilizar un único lenguaje de implementación
complica o limita el uso de algunos microcontroladores y otros dispositivos de cómputo
para sistemas empotrados que existen actualmente, sobre todo, los menos potentes, que
son precisamente los que más nos pueden interesar.
i
i
i
i
i
i
i
i
6. F LUJO DE DISEÑO
159
Sin embargo, ofrecer la posibilidad de implementar el sirviente en cualquier lenguaje también presenta algunos problemas, que consideramos hemos resuelto satisfactoriamente:
Debe existir una implementación de la máquina virtual en el lenguaje de la
plataforma, o bien la posibilidad de generar código para el autómata, directamente
en ese lenguaje. Debido a su sencillo diseño, la implementación de la máquina
virtual en una plataforma nueva no es un esfuerzo significativo. Además, eso permite
optimizar al máximo los recursos requeridos en la plataforma destino.
Se requiere un medio para que el programador del sirviente y el desarrollador que
escribe el fichero IcePick puedan determinar una correspondencia entre ambos,
principalmente en lo referente a métodos y eventos, es decir, una interfaz. El resto
de la sección muestra la forma en la que se ha resuelto este problema.
Con el lenguaje SIS (Servant Interface Specification) proporcionamos un modo genérico
para especificar la interfaz del sirviente independientemente del lenguaje en el que esté
escrito. SIS es un lenguaje sencillo y puramente declarativo. El listado 6.7 muestra un
ejemplo. Dispone sólo de dos elementos: métodos y eventos.
event AUTOL OCK_EVEN T (5) ;
local DUO . IBool . RW test (6) ;
local DUO . IBool . RW qos (7) ;
local DUO . IFloat . R threshold (8) {
input = byte;
}
local DUO . IBool . RW get (3) {
input = byte;
}
L ISTADO 6.7: SIS: Ejemplo de declaración de la interfaz de un sirviente
6.2.1.
Métodos
La declaración de métodos sirve para asignar un identificador entero a cada
procedimiento de usuario (métodos del sirviente). La ejecución de los métodos es
responsabilidad de la máquina virtual al encontrar una instrucción user_proc().
La declaración de un método consta de:
Un tipo (remote o local).
Una interfaz.
Puede incluir una lista de tipos de entrada (input) y salida (output). En el caso de
métodos locales, esta especificación de parámetros es obligatoria; es el único modo que
tendrá el compilador para verificar que las invocaciones son correctas.
i
i
i
i
i
i
i
i
160
6. F LUJO DE DISEÑO
En el caso de métodos remotos, el compilador puede extraer la signatura de las
declaraciones de interfaces en el fichero S LICE o IDL correspondiente de modo que,
en principio, no es necesario que aparezcan especificados aquí.
Sin embargo, por limitaciones de memoria obvias, la máquina virtual no puede almacenar
parámetros de tipos arbitrariamente complejos o largos como cadenas, secuencias, etc. Para
resolver este problema, el sirviente debe proporcionar manejadores (métodos especiales)
que se encargarán de leer y escribir este tipo de parámetros en el cable. Es decir,
serían el equivalente a los procedimientos de (de)serialización en los middlewares
convencionales.
Estos manejadores se especifican en la lista de parámetros indicando el nombre de los
métodos tal como se muestra en el listado 6.8. Por este motivo, cuando un método remoto de
un objeto local utiliza parámetros de tipos variables es necesario incluir la especificación de
parámetros en el fichero SIS. En éste, los métodos get() y set() corresponden al módulo
DUO::IString, es decir, manejan una cadena de caracteres. En la línea 7 se indican dos
procedimientos, separados por comas, que son los encargados de leer sendos parámetros del
método set() (valor e identidad). La línea 11 indica cómo enviar el resultado del método
get(). Requiere dos métodos: el primero (put_size) se utiliza para obtener el tamaño del
valor de retorno, necesario para calcular el tamaño total del mensaje que ha de escribirse en
la cabecera; el segundo (put_data) escribe la secuencia de bytes en la interfaz de red.
1
2
3
4
local
local
local
local
DUO . IString . RW
DUO . IString . RW
DUO . IString . RW
DUO . IString . RW
get_data (20) ;
get_id (21) ;
put_size (22) ;
put_data (23) ;
6
7
8
remote DUO . IString . W set (11) {
input = get_data , get_id ;
};
10
11
12
remote DUO . IString . R get (12) {
output = put_size : put_data ;
};
L ISTADO 6.8: SIS: Soporte a parámetros de tipos variables
6.2.2.
Eventos
Los eventos declarados en el fichero SIS corresponden con los utilizados en las
cláusulas event de IcePick. Declaran eventos que serán activados exclusivamente bajo
la responsabilidad del sirviente. Se especifica un identificador y un valor entero único.
El identificador se escribe utilizando sólo mayúsculas por convenio. Como ejemplo, el
listado 6.7 incluye una declaración de evento en la primera línea.
6.3.
El compilador ipkc
El compilador ipkc es la principal herramienta para la generación de picoObjetos. Se
encarga de procesar los ficheros de entrada y construir un modelo que aglutina todos los
i
i
i
i
i
i
i
i
6. F LUJO DE DISEÑO
161
detalles que conciernen a la definición de un nodo. La entrada principal es un fichero
en lenguaje IcePick. Ese fichero incluye referencias a ficheros externos que aportan las
declaraciones de interfaces para el middleware que corresponda.
6.3.1.
Estructura general
La estructura del compilador sigue un diseño clásico de frontends/backends. Incluye
de forma obligatoria frontends para los lenguajes IcePick y SIS. Para el reconocimiento
de los ficheros de interfaz se requiere un frontend específico dependiendo del lenguaje
concreto. Actualmente se dispone de un frontend para S LICE basado en la biblioteca
libSlice de ZeroC y existe una versión preliminar para IDL.
La figura 6.2 muestra la estructura general del compilador ipkc. Ilustra el caso en
que se usa Slice para generación de objetos compatibles con I CE, que es la situación
más habitual en el desarrollo de nuestros prototipos.
La información de los ficheros fuente es reconocida por un analizador léxico y otro
sintáctico, creados con las herramientas flex y bison de GNU. El resultado es un
objeto SymbolTable que sirve como fachada al resto del modelo de datos. Sobre este
objeto se aplican un conjunto de restricciones semánticas y posteriormente se utiliza
por los backends para generación de código. Los backends son específicos para cada
middleware puesto que es su responsabilidad aplicar el formato y restricciones del
protocolo inter-ORB concreto.
F IGURA 6.2: Diagrama de bloques del compilador ipkc
Todo el diseño del compilador está orientado a objetos, lo cual facilita la modularización
y la incorporación de nuevos elementos: frontales para otros lenguajes de especificación
de interfaces y backends para generación de código. La versión actual del compilador está
implementada en lenguaje C++ y permite backends escritos tanto en C++ como Python.
i
i
i
i
i
i
i
i
162
6. F LUJO DE DISEÑO
El diseño de todos los frontends está basado en el uso del patrón visitor, de modo que su
estructura es muy regular y puede ser replicada con facilidad para crear otros nuevos. Todos
son reconocedores de una única pasada puesto que construyen un modelo programático
completo del fichero de entrada, que más tarde es verificado. Por esta razón no es necesario
hacer declaraciones adelantadas cuando un identificador se usa antes de ser definido.
Las siguientes secciones incluyen la especificación formal de los lenguajes introducidos
anteriormente.
6.3.2.
Frontal para IcePick
Tabla de tokens
El cuadro 6.1 muestra los tokens del lenguaje IcePick. Incluye el nombre del token,
la expresión para el reconocedor léxico y el lexema o ejemplos cuando la expresión
describe un conjunto de valores posibles.
Gramática
El listado 6.9 muestra la gramática de IcePick en notación EBNF. Nótese que,
por generalidad, es posible especificar construcciones que la implementación real
del picoObjeto no permite. Concretamente, la gramática permite invocaciones como
parámetros de otras de forma indefinida, sin imponer restricciones al tipo de las mismas.
Sin embargo, en la implementación actual de la máquina virtual existen dos limitaciones
que no refleja esta gramática:
No es posible utilizar más de un nivel de anidamiento. Es decir, la expresión
obj1.method1(obj2.method2()) es correcta, pero no lo sería una en la que
method2 tuviera a su vez otra invocación por parámetro.
Únicamente se pueden utilizar invocaciones a objetos locales como parámetro de
otras, nunca a objetos remotos.
En todo caso, estas limitaciones se refieren a la versión actual, pueden no afectar a
implementaciones alternativas o ser subsanadas en futuras versiones. Ese es el motivo
por el que estas limitaciones no se han reflejado en la gramática.
6.3.3.
Frontal para SIS
SIS es un lenguaje puramente declarativo muy sencillo. Se limita a la definición de
eventos y signaturas de métodos. Describe los tipos de los parámetros de entrada y
salida, y en el caso de tipos variables, permite la especificación de manejadores concretos
para cada parámetro. El cuadro 6.2 muestra los tokens y el listado 6.9 la gramática
del lenguaje en forma EBNF.
6.3.4.
Frontal para S LICE
En el caso de S LICE no ha sido necesario desarrollar un reconocedor completo ya
que la distribución estándar de I CE incorpora la biblioteca libSlice para soporte a la
i
i
i
i
i
i
i
i
6. F LUJO DE DISEÑO
163
token
expresión
lexemas
colon
semicolon
dot
comma
equal
start_block
end_block
start_p
end_p
eq
neq
lt
gt
lteq
gteq
if
boot
do
event
local
object
remote
timer
adapter
uses
when
int
bool
literal
id
:
;
.
,
=
{
}
(
)
==
!=
<
>
<=
>=
if
boot
do
event
local
object
remote
timer
adapter
uses
when
[0-9]+
true | false
“[ˆ\n"]∗ ”
[A-Za-z_][A-Za-z0-9_]∗
‘:’
‘;’
‘.’
‘,’
‘=’
‘{’
‘}’
‘(’
‘)’
‘==’
‘!=’
‘<’
‘>’
‘<=’
‘>=’
‘if’
‘boot’
‘do’
‘event’
‘local’
‘object
‘remote’
‘timer’
‘adapter’
‘uses’
‘when’
06, 1024
‘true’, ‘false’
“LIT3R4L.”, “123f”
‘var_23a’, ‘_3f’
C UADRO 6.1: Tokens del lenguaje IcePick
i
i
i
i
i
i
i
i
164
6. F LUJO DE DISEÑO
PROG
::= USES DECLS BLOCKS
| USES DECLS
USES
::= uses lit ; { uses lit ;}
DECLS
DECL
::= DECL ; { DECL ;}
::= OBJECT_DECL
| ADAP_DECL
OBJECT_DECL ::= object INTER id
| object INTER id ’{ ’ ATTRS ’} ’
ADAP_DECL
::= local | remote adapter id ’{ ’ ATTRS ’} ’
INTER
ATTRS
ATTR
::= id .
::= ATTR
::= id =
| id
| id
DICT
KV
::= ’{ ’ { KV } ’} ’
::= lit | id : lit | id | int
BLOCKS
LABEL
::= [ LABEL ] BLOCK {[ LABEL ] BLOCK }
::= id :
BLOCK
::= WHEN | BOOT | EVENT | TIMER | FUNCTION
WHEN
BOOT
EVENT
TIMER
FUNCTION
::=
::=
::=
::=
::=
id {. id }
; { ATTR ;}
id
= lit
= DICT
when INVOCATION do ’{ ’ INVOCATIONS ’} ’
boot ’{ ’ INVOCATIONS ’} ’
event id do ’{ ’ INVOCATIONS ’} ’
timer ’( ’ int ’) ’ ’{ ’ INVOCATIONS ’} ’
function ’{ ’ INVOCATIONS ’} ’
INVOCATIONS ::= INVOCATION ; { INVOCATION ;}
INVOCATION ::= id . id ’( ’ [ PARAMS ] ’) ’ [ if ’( ’ COND ’) ’]
COND
COMP
::= PARAM COMP PARAM
::= == | != | < | > | <= | >=
PARAMS
PARAM
::= PARAM { , PARAM }
::= true | false
| id | id . id
| lit | int | INVOCATION
| DICT
L ISTADO 6.9: Gramática del lenguaje IcePick en notación EBNF. Los caracteres
entrecomillados corresponden a tokens definidos en el cuadro 6.1. Se
representan así por legibilidad
i
i
i
i
i
i
i
i
6. F LUJO DE DISEÑO
165
token
expresión
lexemas
colon
semicolon
dot
comma
equal
start_block
end_block
start_p
end_p
local
remote
byte
bool
int
float
double
long
id
:
;
.
,
=
{
}
(
)
local
remote
byte
bool
int
float
double
long
[A-Za-z_][A-Za-z0-9_]∗
‘:’
‘;’
‘.’
‘,’
‘=’
‘{’
‘}’
‘(’
‘)’
‘local’
‘remote’
‘byte’
‘bool’
‘int’
‘float’
‘double’
‘long’
‘var_23a’, ‘_3f’
C UADRO 6.2: Tokens del lenguaje SIS
SIS
DECL
EVENT
METHOD
TYPE
DEF
ATTR
LIST
VAL
::= DECL { DECL }
::= EVENT ;
| METHOD ;
::= event ’( ’ integer ’) ’
::= ( remote | local ) TYPE id ’( ’ int ’) ’
| ( remote | local ) TYPE id ’( ’ int ’) ’ ’{ ’ DEF ’} ’
::= id . id { id . id }
::= ATTR ; { ATTR ;}
::= ( input | output ) = LIST
::= VAL { , VAL }
::= TYPEVAL
| id
| id : id
TYPEVAL ::= byte | double | long | float | int | bool
L ISTADO 6.10: Gramática del lenguaje SIS en notación EBNF. Los caracteres
entrecomillados corresponden a tokens definidos en el cuadro 6.2. Se
representan así por legibilidad
i
i
i
i
i
i
i
i
166
6. F LUJO DE DISEÑO
construcción de compiladores de S LICE. Para utilizarla, el programador debe aportar una
clase visitante (en la jerga del patrón de diseño).
6.3.5.
Compilador extensible
La posibilidad de incorporar nuevos argumentos a la definición de los objetos y
adaptadores permite especificar semántica adicional al lenguaje por medio de plugins.
Éstos son útiles para simplificar el trabajo del programador aportando comprobaciones
semánticas adicionales y generación de código específica para entornos y situaciones
concretas. Se muestran dos casos para módulos DUO.
Objetos activos
Un caso evidente de esta situación es el módulo DUO::Active (véase § 3.4). Los
requisitos para la implementación de objetos DUO activos son demasiado particulares
como para tener cabida en una especificación genérica de objetos distribuidos como
la que pretende IcePick.
Por otra parte, la funcionalidad que requieren los objetos activos es idéntica en todos
los casos (almacenar y recuperar proxies) y resulta muy conveniente poder generar el
código correspondiente cuando un objeto lo requiera.
La solución ha sido crear un plugin que se incorpora al compilador ipkc, realizar
las comprobaciones semánticas necesarias (interfaces implementadas por el objeto) y
generar el código que le otorga a los objetos del nodo la capacidad de actuar como
activos. Para hacer uso del plugin, el programador simplemente debe utilizar interfaces
que hereden de DUO::Active::R o DUO::Active::W y añadir los atributos necesarios
(topic y publisher).
Contenedores
Un caso similar es la interfaz DUO::Container. Este plugin se encarga de generar el
código necesario para la implementación de los métodos que corresponden a dicha interfaz,
de modo que el programador no tiene que preocuparse por ello, simplemente tiene que
heredar de la interfaz DUO::Container::R o W. El atributo children se puede utilizar
opcionalmente para indicar qué objetos están incluidos en el contenedor en el momento de
su creación; ésta es la única opción si se trata de un contenedor de sólo lectura (R).
6.3.6.
Soporte para macro-programación
El objetivo inicial para el lenguaje FSM es la definición del comportamiento de un
nodo en el que pueden residir varios objetos. IcePick, por contra, está orientado a la
descripción de escenarios en los que se relacionan e interactúan varios objetos, del
mismo o de diferentes nodos.
En los ejemplos que se han mostrado hasta ahora aparecía sólo un adaptador local, que
representa el punto de conexión del nodo en la red. En un sistema distribuido tradicional,
un nodo puede disponer de varios adaptadores de objetos, ya sea en distintos puertos o en
diferentes interfaces de red. Si hay relación entre los servicios que ofrecen (p.ej. un servicio
de bridging) pueden ser considerados conceptualmente como un mismo nodo de la red. Por
i
i
i
i
i
i
i
i
6. F LUJO DE DISEÑO
167
contra, si los adaptadores alojan servicios independientes puede ser considerados nodos
lógicos diferentes aunque se ejecuten en la misma máquina. Ambos escenarios son posibles
en IcePick simplemente definiendo más de un adaptador local en el fichero fuente.
Pero es posible ir un paso más allá. Podemos especificar una aplicación que involucra a
varios nodos físicamente diferentes tal como hacer los lenguajes de macro-programación
(véase § 2.5). Es necesario definir al menos un adaptador para cada nodo y modelar las
interacciones por medio de triggers. Después el compilador genera un fichero FSM para
cada nodo. Para soportar esta funcionalidad es necesario añadir una nueva estructura
sintáctica al lenguaje (node), que agrupa uno o más adaptadores. Como ejemplo, la
figura 6.3 muestra interacciones entre 4 objetos situados en 3 nodos diferentes, el
listado 6.11 es el fichero IcePick equivalente. Al compilar ese fichero se obtienen 3
ficheros FSM independientes, que pueden instalarse sobre plataformas diferentes.
uses " DOBS / DUO . ice ";
object
object
object
object
DUO . IBool . W
DUO . IBool . W
DUO . IBool . W
DUO . IBool . W
obj0 ;
obj1 ;
obj2 ;
obj3 ;
local adapter ad1 {
endpoint = " tcp −h 10.0.0.1 −p 1000";
objects = {" UUID00 ": obj0 , " UUID01 ": obj1 };
};
local adapter ad2 {
endpoint = " tcp −h 10.0.0.2 −p 1000";
objects = {" UUID02 ": obj2 };
};
local adapter ad3 {
endpoint = " tcp −h 10.0.0.3 −p 1000";
objects = {" UUID03 ": obj3 };
};
node node1 { adapters = [ ad1 ]; }
node node2 { adapters = [ ad2 ]; }
node node3 { adapters = [ ad3 ]; }
when obj1 . set () do {
obj2 . set ( obj1 . status () , obj1 . oid ) ;
obj3 . set ( obj1 . status () , obj1 . oid ) ;
}
when obj2 . set () do {
obj0 . set ( obj2 . status () , obj2 . oid ) ;
}
when obj0 . set () do {
obj3 . ice_ping () ;
}
L ISTADO 6.11: IcePick: Ejemplo de macro-programación
i
i
i
i
i
i
i
i
168
6. F LUJO DE DISEÑO
F IGURA 6.3: Ejemplo de macro-programación
El soporte para características de macro-programación en el compilador ipkc es muy
preliminar. Por el momento su principal objetivo es demostrar que es posible aplicar este
enfoque y que no es en absoluto incompatible con un modelo centrado en el nodo.
6.3.7.
Generación de FSM
El backend slice2fsm es en el que se ha centrado la mayor parte del esfuerzo
de desarrollo hasta el momento puesto que se ha empleado en prácticamente todos
los prototipos actuales.
En su diseño se ha aplicado el patrón Builder empleando un modelo lógico del código
FSM que se pretende generar. Eso facilita la inclusión de código en cualquier momento
y bloque, y también su posterior reordenamiento y optimización. Gran parte del código
generado se basa en plantillas FSM que se pueden instanciar y parametrizar. Una vez
terminada la generación se renderiza ese modelo sobre un fichero de texto.
Gestión de memoria
El módulo slice2fsm es el encargado de planificar el uso de la memoria del picoObjeto
determinando qué valores pueden ir a ROM (zona DATA), a RAM (banco de registros)
o a la zona de persistencia. Como vimos, algunos registros tienen un uso y ubicación
prefijada, debido a que pueden ser accedidos también desde el sirviente.
Otros registros, como las variables necesarias para los parámetros de las invocaciones
deben ser decididos aquí. Estas variables son compartidas por todas las invocaciones
para parámetros de entrada y salida, de modo que el ahorro de memoria sea máximo. El
backend reserva tantas variables como parámetros tenga el método con más parámetros
de cualquiera de las interfaces de los objetos que aloja el nodo. Del mismo modo, el
tamaño de cada variable depende del mayor tamaño para el parámetro en esa posición
en todas las interfaces.
i
i
i
i
i
i
i
i
6. F LUJO DE DISEÑO
169
Los fragmentos utilizados para la composición de mensajes se sitúan en ROM. Muchos
de ellos tienen partes comunes. Algo especialmente común en las cadenas que se
utilizan para identificación de los tipos (Type IDs en la terminología de I CE) puesto
que tienen las mismas raíces . Muchos de esos fragmentos pueden ser almacenados sólo
una vez para conseguir un significativo ahorro de memoria. Sin embargo, esa es una
optimización que debe realizarse después, cuando se haya determinado el contenido
completo de la memoria.
Invocaciones
Realizar una invocación a un objeto remoto implica generar código para:
Abrir una conexión activa, lo cual requiere disponer de la dirección del adaptador
remoto almacenada en memoria ROM o Flash.
Una cabecera de invocación, que incluye el tamaño total del mensaje.
La identidad del objeto remoto.
El nombre del método.
Una cabecera de encapsulación, con su tamaño.
El valor de los parámetros. Puede implicar la invocación de métodos locales del
sirviente si estos parámetros son variables.
Un mensaje de cierre de conexión.
Cerrar la conexión activa.
Como se apuntaba anteriormente, el mensaje de respuesta se descarta si lo hubiese.
En la mayor parte de los casos su uso está pensado para notificación de eventos sobre
trasporte oneway o no confiable. Por la misma razón, no es posible utilizar un valor
de retorno para otra acción.
El tratamiento de las invocaciones a objetos locales es muy diferente. Cuando el objeto es
local no se realiza una conexión ni se construye un mensaje de invocación, la operación se
reduce a colocar el valor de los parámetros en los registros adecuados y ejecutar el método
del sirviente con la instrucción user_proc(). Las invocaciones a objetos locales sí pueden
devolver un valor de retorno, que se puede utilizar en otra invocación local o remota, tal
como muestra el listado 6.4 (línea 2). Ese es el límite de anidamiento, no es posible realizar
invocaciones anidadas de más de dos niveles con la versión actual de este backend.
Optimizaciones
Muchas tareas en el funcionamiento del picoObjeto requieren de datos estáticos o
parametrizables. Los más importantes son:
Datos de conexión a dispositivos remotos: direcciones IP, MAC o de otro tipo,
puertos, etc.
Identidades de objeto, ya sean remotos para realizar invocaciones, o locales para
construir y retornar proxies.
i
i
i
i
i
i
i
i
170
6. F LUJO DE DISEÑO
Identificadores de tipo (Type IDs), como resultado de las operaciones ice_id() e
ice_ids(), por ejemplo.
Cabeceras de mensajes.
Cabeceras de encapsulación.
Todos estas secuencias de bytes se deben colocar en la memoria ROM para que estén
disponibles durante la ejecución. El backend slice2fsm recopila estas cadenas a partir
del fichero fuente IcePick y de las especificaciones propias del protocolo.
Una vez terminado este proceso es sencillo comprobar que muchas de esas cadenas,
o partes de ellas, se repiten incluso varias veces. Por ejemplo, un actuador que utilice el
módulo DUO::IFloat debe devolver las cadenas DUO::IFloat::R y DUO::IFloat::W
cuando se invoque su método ice_ids(). En ese caso, lo ideal sería almacenar la
raíz común una sola vez.
Para conseguir una solución óptima se debe favorecer la reutilización de los fragmentos,
evitando al mismo tiempo que sean demasiado pequeños. Cada fragmento tiene un coste
de 1 byte (tamaño) además de la propia cadena; y enviarlo con la instrucción put_data
requiere 2 bytes de bytecode. Se requiere un algoritmo que optimice el consumo total de
memoria ROM para las cadenas y de instrucciones necesarias para utilizarlas.
Para la fragmentación óptima del conjunto de cadenas se utiliza un algoritmo de texto
predictivo, similar al que se emplea en los teléfonos móviles para edición de mensajes SMS.
Se obtiene un grafo acíclico dirigido que indica la secuencia de fragmentos para conseguir
cada cadena completa y el mapa de memoria tal como debe quedar en la zona DATA.
6.4.
Drivers
Intentado respetar lo máximo posible el planteamiento típico de los MDOO, hemos
dado por hecho que el código de los sirvientes debe ser aportado por el programador,
avalada esta teoría por el hecho de que puede haber una cantidad importante de plataformas
diferentes, que utilizan distintos lenguajes de programación, métodos y protocolos para
acceder a los periféricos (transductores).
A pesar de ello, hemos hecho un esfuerzo por evitar al programador la necesidad de
realizar tareas repetitivas. Gracias al uso de plugins, el compilador puede aportar parte de
la funcionalidad del sirviente implementándola en la lógica de la máquina de estados.
Siguiendo la misma idea y basándonos en la experiencia adquirida, vemos que el
camino a seguir pasa por reducir la implementación del sirviente a su mínima expresión.
Es más conveniente expresar toda la funcionalidad posible en IcePick y delegar en el
sirviente únicamente el acceso al dispositivo y la responsabilidad de mantener el estado
del transductor, cuando sea necesario. De esta manera, la funcionalidad del nodo está
disponible en cualquier plataforma ya que se encuentra en el bytecode.
En estos términos, las tareas que debe desempeñar el sirviente son:
Acceso a los buses de dispositivo, como I2C, RS232, one-wire, etc.
i
i
i
i
i
i
i
i
6. F LUJO DE DISEÑO
171
Filtrado o conformación de señales, eliminación de ruidos, corrección de datos
espurios, etc.
Generación de eventos asíncronos, por medio de una Rutina de Servicio de
Interrupción (RSI) o polling, dependiendo de las posibilidades del dispositivo.
Almacenamiento del estado del dispositivo, si no es posible su lectura (X10) o el
programador no lo considera eficiente.
Lectura y escritura de parámetros de tipos variables desde/hacia las invocaciones, si
los hubiere.
La interfaz del sirviente se describe como siempre en un fichero SIS, convirtiéndose
entonces en una entidad opaca, similar en algunos aspectos a un componente (interfaz
+ eventos), y que podríamos denominar driver.
Otros middlewares basados en máquina virtual como Maté [LC02] o WSP [BLV09]
han hecho un esfuerzo por especificar toda la funcionalidad del sirviente utilizando el
repertorio de instrucciones virtual. El problema de ese enfoque es que acopla el sistema a
un dispositivo concreto o familia de ellos. En imposible prever en la V-ISA todos los tipos
posibles de transductores y dotar al run-time de código específico para manejarlos todos.
Nuestro enfoque es más parecido al de SensorWare [BHSS07], aunque en nuestro caso
no es imprescindible la existencia del driver. Es necesario recordar además que SensorWare
tiene requerimientos de memoria y plataforma varios órdenes de magnitud mayores.
Se puede desarrollar una biblioteca de drivers por cada plataforma soportada,
implementada con un enfoque generalista. En una misma aplicación es poco probable
que se requieran muchos tipos de drivers, pero si se requiere un driver no disponible, o
cuya funcionalidad equivalente no pueda ser especificada en IcePick, siempre existirá la
posibilidad de implementar el sirviente concreto a mano. Se trata de una solución más
flexible que propuestas anteriores pues puede aplicarse a situaciones en las que muchas de
ellas no lo serían (nueva plataforma o transductor), aun a costa de un esfuerzo adicional.
6.5.
Plataforma para desarrollo de picoObjetos
Los compiladores ipkc y fsm2data, y la implementación de la máquina virtual
FSM para PC constituyen un conjunto de herramientas completo para el desarrollo
de picoObjetos. Hacen posible la especificación, diseño, implementación, integración
y prueba de objetos distribuidos en dispositivos empotrados. La máquina virtual dota
al conjunto de gran flexibilidad. El código FSM puede ejecutarse sobre un PC, en un
entorno distribuido real, incluso sobre la misma aplicación objetivo, sin necesidad de
programarla en el nodo. Una vez probado y cuando se tienen ciertas garantías, se genera
el bytecode equivalente para el dispositivo final. Con ello se recortan sensiblemente los
tiempos de prueba y verificación sobre la plataforma concreta.
La figura 6.4 describe todas las fases del proceso de compilación, desde los ficheros
de especificación de interfaces, descripción del nodo (IcePick) y del sirviente (SIS), hasta
la obtención del fichero binario para programar en el dispositivo.
i
i
i
i
i
i
i
i
172
6. F LUJO DE DISEÑO
F IGURA 6.4: Plataforma completa para desarrollo y prueba de picoObjetos
La característica más interesante del planteamiento es que permite utilizar un middleware
convencional de propósito general sin ninguna modificación ni adaptación, dentro y
fuera de la red de transductores.
No afecta a ninguno de los procesos paralelos relacionados con el desarrollo de
aplicaciones y servicios, involucren o no a las redes de dispositivos.
El contrato que impone el middleware desacopla el trabajo entre los proveedores y
los usuarios de los servicios.
Por la misma razón, estos grupos pueden trabajar de forma independiente. Es sencillo
desarrollar aplicaciones mínimas que substituyan uno de los lados (servidor o
usuario).
Los diseñadores y desarrolladores de aplicaciones y servicios para el entorno
inteligente no necesitan formación especial. Cualquier programador habituado al
trabajo con CORBA, EJB, .Net o Web Services puede ser productivo de inmediato.
i
i
i
i
i
i
i
i
6. F LUJO DE DISEÑO
173
Se utilizan los mismos conceptos y, salvando las distancias, existen abstracciones
prácticamente equivalentes en todos ellos.
Esa misma independencia se consigue también a nivel de dispositivo gracias a la
máquina virtual.
El diseñador/programador de servicios sobre el picoObjeto no necesita conocer los
detalles de cada plataforma.
La implementación de la máquina virtual para un dispositivo concreto no afecta ni
se ve afectada por el funcionamiento de otros dispositivos.
Por último, la creación de drivers puede ser también una tarea independiente, dado que
sólo atañe a la gestión de los transductores y no tiene relación directa con la funcionalidad
del nodo ni con la aplicación distribuida. La figura 6.5 muestra los distintos roles del
personal involucrado y sus áreas de interés.
F IGURA 6.5: Diferencias entre las tareas del diseñador de aplicaciones para el sistema
y el programador de los nodos
En la medida en que un middleware establecido cuente con el soporte adecuado en
determinada tecnología o fabricante de dispositivos para redes SAN, no hay nada especial
en el flujo de diseño utilizado en el desarrollo de aplicaciones para dichas redes. La mayoría
de los servicios y aplicaciones finales están desarrolladas usando un flujo convencional
y cualquiera de las herramientas disponibles comercialmente.
i
i
i
i
i
i
i
i
174
6. F LUJO DE DISEÑO
El desarrollo de nodos SAN se integra perfectamente con el del middleware. Los
cabos del cliente se generan como siempre, utilizando el compilador de interfaces que
incorpora el ORB. Cuando el servidor es un picoObjeto, se utiliza ipkc partiendo de
los mismos ficheros de interfaz.
Respetar este modelo de desarrollo, habitual en los MDOO, aporta importantes beneficios
a la construcción de aplicaciones con redes SAN desde el punto de vista metodológico.
El analista/diseñador de la aplicación puede ver los nodos de la red SAN como
entidades autónomas y opacas que poseen un rol claro ya desde fases tempranas del
diseño del sistema. Es decir, el diseño de una aplicación que emplea redes SAN es
completamente equivalente a cualquier otra aplicación basada en objetos.
El desarrollador de la aplicación utiliza interfaces de programación genéricas y
de alto nivel que permiten desacoplar el diseño de las cuestiones específicas de
la tecnología del nodo. Los nodos transductores se pueden usar como cualquier
otro objeto del sistema. El mismo middleware se utiliza en todas las fases y en
todos los niveles. Los nodos se especifican por medio de un lenguaje de alto nivel
(IcePick) indicando únicamente los tipos e identidades de los objetos involucrados y
sus relaciones básicas.
El desarrollador del código empotrado dispone de un conjunto de herramientas para
automatizar la generación de la infraestructura de comunicaciones, conseguir la
interacción entre los nodos de la red SAN y casi cualquier sistema externo.
Programar y configurar una red de sensores es una tarea difícil y propensa a
errores [CGG+ 05]. Empleando picoObjetos, el compilador genera todo el código
relacionado con las comunicaciones, permitiendo al desarrollador concentrarse
únicamente en los detalles relativos al acceso a los transductores y al tratamiento de
los datos procedentes de éstos.
i
i
i
i
i
i
i
i
Integración de redes heterogéneas
7.1.
7.2.
7.3.
7.4.
7.5.
7.6.
7.7.
7.8.
Introducción
Direccionamiento
Endpoints
Gestión de calidad de servicio
Entrega de mensajes
Encaminamiento
Integración con el middleware
Conclusiones
77
L
A gran diversidad en protocolos y tecnologías existentes dificulta en muchas ocasiones
el desarrollo de mecanismos para lograr interoperabilidad entre aplicaciones que se
ejecutan en nodos cualesquiera, sea cual sea el tipo de red en la que se encuentren. No
siempre es posible ni deseable utilizar el mismo protocolo de red.
Un buen ejemplo de este problema es el acceso a los nodos de una red de sensores. Tales
dispositivos utilizan tecnologías de red como Zigbee o Bluetooth, que si bien pueden operar
con la pila TCP/IP, su adopción suele requerir un esfuerzo considerable y no siempre se
obtienen soluciones óptimas. Otras tecnologías pueden implicar protocolos especializados
o hardware propietario, lo cual en algunos casos, puede hacer inviable esa posibilidad.
Desde el punto de vista de las SAN, éste es un asunto pendiente —al menos no totalmente
resuelto— en lo concerniente al transporte transparente de mensajes entre una red troncal y
las redes de sensores a las que está conectada. En particular buscamos una solución para los
siguientes dos casos, pero lo suficientemente flexible como para cubrir muchos otros.
Acceso desde el SI convencional de cualquier organización a las redes de sensores
que se desplieguen como soporte a servicios cualesquiera.
Interacción entre nodos de dos o más redes SAN con diferente tecnología, incluso si
fuera necesario atravesar otras intermedias, de cualquier tipo.
A fin de cuentas, el objetivo es poder enviar mensajes desde una red a cualquier otra
sin importar que utilicen tecnologías o protocolos de red incompatibles.
175
i
i
i
i
i
i
i
i
176
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
7.1.
Introducción
Tal como vimos en la sección 2.6, existen varias alternativas para lograr la interconexión
de redes heterogéneas. En la inmensa mayoría de los protocolos, middlewares y sistemas
diseñados para la conectividad de redes SAN se considera, casi por descontado, que el
sistema cuenta con una única pasarela de servicio que es utilizada por las redes externas
para acceder a los nodos de la SAN. La pasarela aloja normalmente componentes software
cruciales para el acceso a los nodos, lo que conlleva una gran cantidad de problemas
que ya se comentaban en la sección 2.6.2.
Comparando las diferentes alternativas que se plantean en la citada sección, parece
que la solución más flexible y eficiente es la utilización de un protocolo de red común,
incluyendo la definición de un esquema de direccionamiento global. Dado que obviamente
no se pretende substituir IP, pero sí resolver los problemas que el uso de la pila TCP/IP
puede suponer en ciertos ámbitos, el camino adecuado parece ser un protocolo no
solo independiente de la red, también del transporte. Construir un nuevo protocolo
sobre la capa de enlace implicaría reinventar la rueda enfrentándonos a problemas ya
resueltos por otros ya probados y admitidos. La alternativa más adecuada es usar el
protocolo o pila que resulte más natural en cada entorno y construir nuestro protocolo
homogeneizador en una capa superior.
La especificación «CORBA Message Routing» [Obj08b, cap. 17] (en adelante CMR)
apunta en el camino correcto. El middleware proporciona una capa de abstracción lo
suficientemente consistente como para ocultar los detalles de las tecnologías software
y hardware subyacentes, se puede implementar sobre una gran diversidad de sistemas
siempre que se cumplan ciertas condiciones (en función del middleware concreto),
proporciona un sistema de direccionamiento abstracto mediante referencias interoperables
a objetos, etc.
Sin embargo, las motivaciones y decisiones de diseño de CMR no corresponden a un
protocolo general de encaminamiento de mensajes. Al menos los siguientes aspectos
resultan inadecuados o contrarios en relación a los objetivos que perseguimos:
Los encaminadores no disponen de tablas de encaminamiento que permitan construir
rutas extremo a extremo en colaboración con los encaminadores vecinos. La ruta
queda determinada por las referencias indicadas en la propia referencia de objeto
destino y/o de decisiones administrativas locales del ORB en el que ejecuta el
encaminador intermedio. La ruta que sigue la invocación es una forma de lograr
tolerancia a fallos ante la imposibilidad de entregar el mensaje directamente al
destino, o a circunstancias que impliquen la desactivación temporal (o definitiva) de
parte de los encaminadores involucrados.
No prevé la posibilidad de implementar encaminamiento dinámico que permita
establecer rutas alternativas ante cambios en la carga, disponibilidad o desempeño
de los recursos de la red.
Las referencias a objetos, que son el equivalente funcional a direcciones universales,
pueden tener tamaños arbitrarios. Dado que contienen una cantidad no acotada de
perfiles y componentes, que incluyen a su vez la lista de encaminadores posibles, el
tamaño de estas referencias puede alcanzar con facilidad miles de bytes.
i
i
i
i
i
i
i
i
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
177
No se puede considerar que éstos sean fallos de diseño en la especificación de CMR.
Simplemente ocurre que su finalidad es diferente, lo cual dificulta su aplicación al problema
de la interconexión genérica de redes.
Este capítulo propone la especificación e implementación de un nuevo protocolo llamado
Inter-Domain Messaging (IDM) , y de los mecanismos asociados para emplear un MDOO
de propósito general para encapsular y transportar mensajes como invocaciones a objetos,
aprovechando algunos aspectos del diseño de CMR, IP y otros protocolos existentes, pero
cuidando otros aspectos que consideramos esenciales para nuestro propósito:
Mantener una sobrecarga lo suficientemente baja como para permitir su aplicación a
cualquier tipo de red, en especial las que tienen un MTU pequeño, como es habitual
en las SAN. Menor sobrecarga de cabeceras implica también transmitir menos bytes
y por tanto consumir menos energía.
Incorporación de información tanto a la red como a los propios mensajes, que haga
posible encaminamiento dirigido por requisitos de Q O S, tanto DiffServ (basado en
clase) como IntServ (basado en flujo).
El protocolo ha de ser lo suficientemente genérico como para implementar algoritmos
de encaminamiento dinámico sobre él.
Debe tener capacidades de cross-layer, que permitan eliminar capas o prestaciones
innecesarias en función de los requisitos demandados por el cliente.
Debe definir un esquema de direccionamiento universal, jerárquico, con direcciones
de tamaño máximo acotado pero lo más pequeñas posible. El direccionamiento
universal, que potencialmente puede incluir nodos de miles de redes, puede implicar
direcciones de tamaño considerable. Por ello, es necesario llegar a un compromiso
que satisfaga ambos requisitos contrapuestos.
Tanto los elementos finales como los encaminadores de la red se modelarán e
implementarán como objetos distribuidos convencionales. Además, el programador
dispondrá de dos posibles puntos de vista a la hora de diseñar su aplicación:
Un mecanismo transparente para la aplicación cliente, por medio de un API similar
al de los sockets BSD.
Una referencia a un objeto remoto (mediante un proxy) sobre la que puede invocar
métodos conforme a su tipo.
7.1.1.
Inter-redes
Consideremos el problema como analogía a la red más conocida por todos. Internet,
como en la mayoría de las redes, se fundamenta en el uso de un protocolo de red único, en
este caso IP. Un esquema global de direcciones lógicas permite la interconexión de redes
con distintas tecnologías en la capa de enlace y física. Por tanto, para que una red pueda
formar parte de una inter-red requiere que se cumplan ciertas condiciones básicas:
Los hosts deben entender el esquema de direccionamiento lógico.
Los hosts deben poder fabricar y entramar paquetes sobre la tecnología de red
subyacente.
i
i
i
i
i
i
i
i
178
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
En el caso de que se trate de un medio de difusión, debe existir un mecanismo que
permita mapear direcciones lógicas a físicas.
Debe existir una pasarela o encaminador capaz de reenviar (forward) paquetes
entre redes diferentes, realizando los procesos de desentramado y entramado que
correspondan a los protocolos de enlace de cada red.
En Internet, cuando se precisa atravesar una red que utiliza un protocolo de red
incompatible, la solución suele ser alguna técnica de tunneling, aunque eso impide
normalmente implantar un esquema de encaminamiento homogéneo. El otro problema
evidente es enviar datos entre dispositivos de esas redes, que tienen protocolos de red
y direcciones lógicas incompatibles.
7.1.2.
Encaminamiento homogéneo
Nuestro objetivo es proporcionar un servicio de transporte de mensajes extremo
a extremo, independiente de las tecnologías de las redes intermedias, aprovechando
los protocolos y tecnologías disponibles en cada dominio a fin de no reimplementar
funcionalidades ya disponibles. En muchos sentidos se trata de cumplir uno de los requisitos
que planteaba el ISTAG [DBS+ 01] para los entornos inteligentes en cuanto a la necesidad
de una infraestructura de comunicaciones integradora. También es una de las necesidades
identificadas a menudo en los middlewares para redes de sensores [R0̈4].
IDM no delega el direccionamiento a las capas inferiores aunque sí puede delegar
el encaminamiento. En ese aspecto cada red puede considerarse un SA. Por ejemplo,
en una red TCP/IP se pueden encapsular los mensajes sobre paquetes IP y delegar el
encaminamiento en los protocolos habituales, mientras que en una red MANET sin IP
se puede implementar un protocolo de encaminamiento tipo AODV cuyos mensajes van
encapsulados en mensajes de nuestro protocolo. La combinación de un middleware con
la posibilidad de encaminamiento multicapa (cross-layer) extremo a extremo aporta
muchas y valiosas ventajas:
Direccionamiento
Realmente global e independiente de la tecnología y el protocolo.
Red virtual
Posibilita el despliegue de redes virtuales sobre cualquier tipo de red existente o
futura.
Calidad de servicio
Proporciona soporte para aplicar políticas de calidad de servicio de alto nivel, puesto
que se puede manejar información mucho más rica en las capas superiores.
Flexible
Y adaptable a las necesidades de la aplicación. Utilizar un middleware de
comunicaciones no implica necesariamente una sobrecarga de protocolos ni un
aumento significativo de la complejidad. Por ejemplo, es perfectamente viable
encapsular mensajes sobre tramas Ethernet, si los requerimientos de calidad de
servicio solicitados lo permiten.
i
i
i
i
i
i
i
i
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
179
Servicios de la plataforma
Por el hecho de utilizar un middleware de comunicaciones de propósito general, se
puede contar con muchos de los servicios comunes que incorpora. En el caso de
nuestro prototipo actual (basado en I CE) podemos destacar: cifrado y autenticación
transparentes, soporte multi-lenguaje, persistencia automática, despliegue, activación
implícita, balanceo de carga, replicación transparente, etc.
Transparencia de localización
Nuestros encaminadores son entidades lógicas y, por tanto, pueden ser migrados o
replicados a otros nodos de la red de forma transparente.
Encaminamiento funcional
Esta cualidad permite plantear esquemas y algoritmos de rutado basados en
agrupaciones funcionales de nodos y no solo en su localización geográfica.
Eficiencia
Nuestros encaminadores también se pueden implementar sobre sistemas empotrados.
Es posible utilizar plataformas que van desde microcontroladores, como los
que incluyen los nodos de una SAN hasta sistemas sintetizables sobre lógica
reconfigurable, como FPGA (Field-Programmable Gate Array). Esto es posible
utilizando picoObjetos.
Orientado a Objetos
Si el programador lo desea, es posible ver al servidor como un objeto remoto por
medio de la declaración de su interfaz. Si se trata de un servicio orientado a flujo o
que no requiere semántica en la invocación, es posible utilizar un API alternativo
con primitivas read/write.
7.1.3.
Acerca de los prototipos
En la sección 8.7 se describe en detalle el diseño de algunos de los prototipos iniciales.
Para su implementación se ha utilizado I CE. Sin embargo, las propuestas que se plantean
aquí no son específicas de éste. Se puede utilizar cualquier middleware heterogéneo
basado en objetos distribuidos.
A lo largo del texto se harán referencias a algunas de las características y particularidades
de este middleware pues consideramos que puede ayudar a una mejor comprensión
de los conceptos que se exponen.
7.2.
Direccionamiento
Los esquemas de direccionamiento de red tradicionales utilizan una dirección lógica
que identifica al host, delegando la identificación de la aplicación destino (el servidor)
a los protocolos de la capa de transporte, llamados puertos en el caso de TCP y UDP.
IDM utiliza un esquema de direcciones jerárquico, en el que se reserva un sufijo para
identificar la aplicación. Estas direcciones son realmente identidades de objetos. Si se
desea direccionamiento global, se puede usar cualquier esquema de identificadores que
garantice la unicidad, llamados GUID (Globally Unique IDentifiers), y que permita obtener
i
i
i
i
i
i
i
i
180
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
identificadores jerárquicos. Aunque es posible, no es estrictamente necesario que la
dirección identifique el host en el que reside el objeto.
El cliente solo necesita conocer la identidad de objeto, que puede entenderse a todos los
efectos como una dirección lógica. Para llevar a cabo la transmisión de los datos se precisa
de un endpoint. Éste encapsula la implementación del transporte sobre una tecnología o
protocolo concreto: TCP, UDP, IP, Ethernet, Crossbow (XB OW), Bluetooth, etc. La elección
del endpoint la realiza el encaminador en base a las restricciones de calidad de servicio
especificadas por el cliente y de la disponibilidad de las interfaces físicas en el nodo en el
que reside. La transmisión puede no ser posible si no se satisfacen estas condiciones.
IDM proporciona mecanismos para localizar la dirección del endpoint de un objeto a
partir de su identificador sin que sea necesario conocer su ubicación. Más concretamente,
sirve para averiguar el endpoint del adaptador en el que está registrado el objeto destino.
7.2.1.
Identidad del objeto
Desde el punto de vista funcional, el identificador de objeto es una secuencia de bytes
globalmente única con dos campos relevantes:
Aplicación
Identifica el propósito del servicio, es decir, el objetivo común de todos los objetos
que la comparten. Ejemplos válidos podrían ser una red P2P, un conjunto de
suscriptores a un servicio de streaming, etc. Debe entenderse como un filtro y, por
ello, su uso no es obligatorio. Este campo puede ser utilizado por los encaminadores
para dar un tratamiento especial a todos los mensajes que corresponden a una
aplicación determinada, aplicando técnicas de traffic shaping o priorización por
contenido.
Nombre
Identifica el objeto independientemente de la aplicación. Un objeto dado tiene
el mismo nombre en todas las aplicaciones en la que esté involucrado, aunque
también es posible que un mismo objeto tenga más de un nombre y, por tanto, varias
identidades incluso dentro del contexto de la misma aplicación.
El campo nombre debe utilizar necesariamente un esquema jerárquico, pues esa es la
base del funcionamiento de las tablas de rutas que se emplean. Una de las características
diferenciadoras es que este tipo de jerarquía puede ser funcional además de geográfica
(ver figura 7.1). Esto aporta una gran flexibilidad y permite la migración transparente de
nodos y encaminadores. Aunque pueden desplegarse encaminadores en cualquier punto
de la red, es imprescindible que existan al menos en las fronteras entre redes distintas
pues el objetivo de IDM es precisamente la interconexión de redes.
7.2.2.
Un posible esquema de direccionamiento
Para ilustrar el sistema de direccionamiento se propone un esquema concreto basado
en IP V 6. Nótese que se trata únicamente de un ejemplo para ilustrar lo explicado en la
sección anterior. El uso de este tipo de direcciones no implica utilizar ninguna de las
restricciones documentadas en la RFC 2460 [DH98]. Se propone como un esquema de
i
i
i
i
i
i
i
i
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
181
F IGURA 7.1: IDM: Ejemplo de encaminamiento funcional
direccionamiento general. En principio IDM está diseñado como un protocolo genérico
para el transporte de mensajes en aplicaciones distribuidas, no como un substituto de
IP. Normalmente no serán necesarias direcciones tan grandes. En redes virtuales, de
propósito específico o con un número reducido y acotado de nodos, es posible utilizar
direcciones mucho más sencillas, de sólo unos pocos bytes.
A partir del espacio de direccionamiento de 2128 definido en IP V 6, proponemos un
esquema jerárquico multinivel similar al que se define en la RFC2073 [RLH+ 97]. La
figura 7.2 representa ese formato.
F IGURA 7.2: Un posible esquema de direccionamiento para IDM
El espacio de direcciones queda dividido en los siguientes campos:
Aplicación (32 bits). Tal como se indicaba se utiliza para identificar una aplicación
o red lógica concreta.
Organización (32 bits). Identifica la institución responsable o propietaria del objeto.
Sección (8 bits). Niveles organizativos intermedios.
Unidad (8 bits).
Subred (16 bits).
Nodo (16 bits). Identifica un nodo lógico dentro de la red. Un mismo dispositivo
puede contener varios.
Objeto (16 bits). Identifica un objeto dentro del nodo.
Nótese que en ningún momento la utilización de este tipo de direcciones implica la
necesidad de utilizar nada de IP V 6 en la capa de red, ni tan siquiera una pila de protocolos
tipo TCP/IP. Es decir, no existe ninguna posibilidad de ambigüedad o colisión entre estos
identificadores y la dirección lógica de la interfaz de red del dispositivo en que reside,
incluso en el caso en que utilice una implementación real de IP V 6 en la capa de red.
i
i
i
i
i
i
i
i
182
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
7.3.
Endpoints
Un endpoint es una estructura lógica independiente que encapsula todos los detalles
del transporte de datos para una tecnología o protocolo subyacente. Bajo la perspectiva
de IDM, no hay diferencias funcionales entre un endpoint que permite abrir y mantener
una conexión TCP sobre una VPN, de otro que envía tramas SLIP sobre un cable RS-232.
Las diferencias están en las prestaciones del endpoint, pero no en su uso.
El endpoint es responsable de las siguientes tareas:
Construye las tramas IDM, serializa y encapsula la invocación del usuario, calcula
sumas de verificación, información redundante, autenticación, etc. Todo esto se
realiza apoyándose lo máximo posible en los servicios proporcionados por el
middleware. No tiene porqué suponer un trabajo excesivamente complejo.
Oculta todos los detalles relacionados con el uso de un protocolo o interfaz de
comunicaciones.
Enumera y comprueba las prestaciones de Q O S que ofrece cada transporte y
tecnología concreta.
I CE incluye de serie únicamente tres tipos de endpoints: TCP, UDP y SSL. Nosotros
hemos desarrollado algunos más: Socket UNIX, colas de mensajes y Crossbow. La
figura 7.3 ilustra la relación que tiene IDM con el modelo tradicional de capas por medio
de los distintos endpoints. Dicha figura refleja que la elección no está condicionada por
el protocolo de bajo nivel o la capa a la que pertenezca sino por la funcionalidad que
proporcione, es decir, sus prestaciones de Q O S.
F IGURA 7.3: Relación de IDM con el modelo de capas de red tradicional
Cada endpoint tiene una representación textual que especifica el protocolo de nivel
inferior utilizado, la dirección lógica o física, el puerto o cualquier otra información
necesaria para establecer la conexión o el envío, y otros datos como timeouts, certificados
para cifrado, etc.
En IDM existe un tipo de endpoint muy especial que se encarga de anteponer la cabecera
IDM a los mensajes del protocolo inter-ORB convencionales. En el caso de I CE, eso
simplifica el uso de IDM sobre la distribución software; no hay necesidad de modificar
nada en el código que proporciona el fabricante.
i
i
i
i
i
i
i
i
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
183
IDM podría utilizar el protocolo inter-ORB para codificar sus mensajes (como hace
CMR) pero ello implica una sobrecarga muy importante que resulta prohibitiva para
MTU S pequeñas. Por ese motivo se ha definido un formato de cabecera específico (ver
listado 7.1). Los mensajes de reenvío (forward) —cuyo equivalente en CMR sería send_-
request()— incluyen los siguientes campos:
magic sequence – (3 bytes) Caracteres ‘I’,‘D’,‘M’.
messageType – (1 byte) Tipo de mensaje.
messageSize – (4 bytes) Tamaño total del mensaje incluyendo la carga útil.
requestId – (4 bytes) Identificador de la petición para realizar la correspondencia con
el mensaje de respuesta si lo hubiere.
routerId – (2 bytes) Identidad del encaminador que debe reenviar este mensaje.
dst – (16 bytes) La identidad del objeto destino.
src – (16 bytes) La identidad del objeto que recibirá la respuesta.
hopLimit – (1 byte) Un contador que el encaminador descuenta en cada salto. Evita
bucles de encaminamiento de manera similar al campo del mismo nombre en IPv6.
tos – (1 byte) Un código que identifica el T O S. El encaminador aplica un conjunto de
restricciones de Q O S a cada tipo de servicio. Su función es similar al campo del
mismo nombre en IP.
flow – (4 bytes) Identifica una secuencia de mensajes que comparten un perfil de Q O S.
mode – (1 byte) Características de entrega de la invocación: idempotente, one-
way/twoway, respuesta requerida, etc.
module IDM {
struct HeaderData {
byte magic_I , magic_D , magic_M ;
byte messageType ;
int messageSize ;
int requestId ;
byte routerId ;
IDM :: Identity dst ;
IDM :: Identity src ;
byte hopLimit ;
ToS tos ;
int flow ;
byte mode ;
};
struct ForwardData {
string operation ;
Encapsulation params ;
};
struct Forwa rdUserMs g {
i
i
i
i
i
i
i
i
184
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
struct HeaderData ;
struct ForwardData ;
};
struct ForwardRawMsg {
struct HeaderData ;
Ice :: ByteSeq payload ;
};
};
L ISTADO 7.1: Formato de los mensajes IDM (notación pseudo-Slice)
Nótese que el campo router no es una identidad IDM completa. Solo se requiere el
sufijo —la identidad del objeto dentro del nodo— dado que el adaptador que lo aloja
debe ser localizado por otro medio. Por ejemplo, IP no requiere identificar al encargado
de procesar los paquetes puesto que únicamente hay un proceso de encaminamiento por
host. Sin embargo, hay muchos motivos por los que puede resultar ventajoso que varios
encaminadores IDM (objetos) convivan al tiempo en un nodo.
A pesar de la mencionada sobrecarga, puede ser interesante definir este mensaje como
un método del encaminador, empleando Slice y utilizando I CE P como formato. El caso
más claro para decantarse por esta opción lo tenemos a la hora de prototipar algoritmos de
encaminamiento dinámico o depurar protocolos de aplicación encapsulados sobre IDM.
El motivo es que implementar y probar métodos convencionales del objeto es mucho más
sencillo desde el punto de vista del desarrollo ya que los procesos de (de)serialización
son realizados automáticamente por el middleware.
En cuanto a la carga útil, IDM permite transportar mensajes de dos tipos:
Raw – Ofrece al usuario un API similar a los sockets BSD para darle la posibilidad de
transportar bloques de datos sin ningún tipo de semántica ni formato.
User – Si se dispone de la especificación de la interfaz del objeto remoto, es posible
realizar invocaciones a métodos. De ese modo se logra serialización/deserialización
de parámetros, verificación de tipos, gestión de excepciones, etc.
7.4.
Gestión de calidad de servicio
Los requisitos de Q O S necesarios son especificados en el momento en que se solicita
el acceso al objeto remoto. Algunos de ellos, como el cifrado o la autenticación pueden
establecerse extremo a extremo, pero otros como el ancho de banda requerido deben
satisfacerse a lo largo de toda la ruta. A continuación se listan algunos de los parámetros
que hemos considerado, aunque varios no están disponibles en los prototipos actuales.
Invocación oneway/twoway.
Confirmación/Garantía de entrega.
Ordenamiento de mensajes.
Autenticación.
i
i
i
i
i
i
i
i
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
185
Autorización.
Latencia máxima.
Ancho de banda mínimo.
Encaminamiento fuente.
El cliente también debe especificar qué ocurre cuando no es posible satisfacer alguno
de los requisitos. Solicitar una política estricta puede implicar la imposibilidad de
llevar a cabo el transporte.
Se considera que los encaminadores pueden contar con un conjunto de T O S definidos
junto con sus requisitos de Q O S. Adicionalmente, los encaminadores pueden implementar
la interfaz IDM::QoS::Admin, que se utiliza para definir nuevos perfiles de Q O S. Esta
interfaz (listado 7.2) tiene un método que permite registrar un perfil Q O S en base a un
código de T O S o bien a un identificador de flujo.
module IDM {
module QoS {
enum feature { maxLatency ,
minBandwidth ,
reliability };
dictionary < feature ,string > profile ;
interface Admin {
void setQoSbyToS ( profile qos , ToS tos ) ;
profile getQoSbyToS ( ToS tos ) ;
void setQoSbyFlow ( profile qos , int flow ) ;
profile getQoSbyFlow (int flow ) ;
};
};
};
L ISTADO 7.2: Interfaz para administración de perfiles de Q O S en encaminadores IDM
7.5.
Entrega de mensajes
IDM se ha concebido como un protocolo de red, de modo que se plantean los mismos
problemas, con la salvedad de que deben resolverse en una capa de abstracción diferente:
sobre el middleware en lugar de sobre la capa de enlace. Un problema básico en un
protocolo de red es la descripción de los mecanismos de entrega de mensajes, tanto a
vecinos de su red como a hosts fuera de ella.
7.5.1.
Entrega directa
El método más simple de entrega de mensajes involucra únicamente al cliente y al objeto
o servidor; a esto se denomina normalmente entrega directa. Para lograrlo es necesario
averiguar los endpoints de que dispone el adaptador al que pertenece el objeto destino y
después comprobar si el host cliente cuenta con algún endpoint compatible.
i
i
i
i
i
i
i
i
186
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
F IGURA 7.4: Una inter-red IDM formada por 4 redes IDM
Una red IDM es un conjunto de objetos directamente alcanzables por medio de un
tipo de endpoint. No tiene porqué existir ninguna relación entre una red IDM y las redes
físicas a las que está conectado el host. Puede ocurrir incluso que un adaptador de objetos
cuente con varios tipos de endpoints a pesar de estar conectado a una sola red física. En el
escenario más simple los encaminadores IDM se encuentran sólo en los nodos frontera
entre redes con distintas tecnologías o protocolos de red incompatibles (ver figura 7.4).
Eso proporciona conectividad entre todos los objetos y clientes IDM, pero hay otros
usos posibles en los que pueden existir muchos más encaminadores, por ejemplo, en una
MANET todos los nodos son encaminadores IDM.
Para conocer los endpoints del adaptador al que pertenece un objeto se ha diseñado el
protocolo Adapter Location Protocol (ALP). Es un protocolo general de descubrimiento
de vecinos, pero asume que los actores son objetos accesibles mediante IDM. El
listado 7.3 muestra la especificación de la interfaz que deben implementar los objetos
que soportar este protocolo.
module IDM {
module ALP {
exception O b j e c t N o t F o u n d E x c e p t i o n {};
interface Locator {
void add (Object∗ prx ) ;
void remove ( IDM :: Identity oid ) ;
Object∗ resolve ( IDM :: Identity oid )
throws O b j e c t N o t F o u n d E x c e p t i o n ;
};
interface Lookup {
idempotent void request ( IDM :: Identity oid ,
Lookup ∗ callback ) ;
idempotent void reply (Object∗ prx ) ;
};
};
};
L ISTADO 7.3: Interfaz ALP para registro de objetos y localización de adaptadores
(especificación Slice)
i
i
i
i
i
i
i
i
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
187
Cada nodo de la red IDM debe disponer de un demonio local, llamado Servicio
ALP, que implementa la interfaz ALP::Locator. Mediante la invocación del método
lookup y conocida la identidad destino, el nodo cliente obtiene un proxy, que permite
realizar invocaciones directamente sobre el objeto remoto. Nótese que sólo es posible
localizar endpoints de adaptadores vecinos, es decir, que se correspondan a nodos de
la misma red IDM.
Existen diversas formas de implementar el servicio ALP. Para nuestros prototipos
iniciales hemos considerado dos. La elección se hace por configuración y es transparente
tanto para los clientes como para los objetos.
Un servicio distribuido que permite a cualquier host interrogar a su segmento de red
sobre la existencia de un objeto concreto. Este servicio utiliza los mecanismos
multicast o broadcast específicos de los endpoints disponibles. El servicio en
cada nodo debe atender los mensajes request() y los debe contestar mediante
mensajes reply(). Estos mensajes pertenecen a la interfaz IDM::ALP::Lookup y
en la práctica dicha interfaz se implementa como una faceta del Servicio ALP (ver
figura 7.5).
Utilizar las características de indirección que incorpore el middleware. En I CE la
indirección de objetos se consigue por medio de un servicio llamado Ice Locator, que
aunque centralizado puede estar replicado. IDM dispone de un adaptador para utilizar
IceGrid::Locator con una sobrecarga mínima. Eso resulta muy útil en segmentos
grandes de la red virtual y cuando los hosts dispongan de suficientes recursos de
cómputo como para ejecutar un nodo IceGrid (véase § 2.3.4). Obviamente ofrece
alguna desventaja respecto al anterior: todos los hosts deben conocer desde su
arranque la referencia remota de al menos una de las réplicas del Locator y contar
con un endpoint compatible con ella.
En ambos casos, los hosts que deseen exportar objetos deben registrarlos en el servicio
ALP para que puedan ser encontrados por otros nodos, independientemente si están
implementados mediante IceGrid Locator o por el propio host. Ambos mecanismos
pueden coexistir en la misma red.
El servicio ALP cuenta con una caché que almacena temporalmente los endpoints
resueltos, sin importar el modo en que se resolvieron. El propósito de la caché es reducir
el impacto en el desempeño que implican los mecanismos de resolución. Cuando se
utiliza un servicio ALP centralizado, el runtime IDM incorpora una caché local para
evitar tener que repetir consultas al servicio remoto.
7.5.2.
Entrega indirecta
Se utiliza entrega indirecta para aquellos objetos que no son alcanzables a través de
ninguno de los endpoints del cliente. En esos casos es necesaria la mediación de al menos
un encaminador. Nótese que puede ocurrir un caso especial. Aún existiendo accesibilidad
directa por medio de un endpoint, es posible que las restricciones de Q O S impidan su uso
y obliguen a utilizar uno o varios encaminadores para llegar al destino.
i
i
i
i
i
i
i
i
188
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
F IGURA 7.5: Diagrama de bloques de IDM
7.6.
Encaminamiento
Todos los nodos que forman parte de una inter-red IDM requieren de una tabla de
rutas que determina si la entrega de mensajes puede realizarse de forma directa o se
necesita un encaminador. Éste también es un objeto distribuido convencional, similar a
los nodos servidores; la principal diferencia es que puede aceptar y redirigir mensajes
que no van dirigidos explícitamente a él.
El listado 7.4 muestra la tabla de rutas de un encaminador. Se han utilizado
identificadores textuales simplificados para mejorar la legibilidad. Esta tabla de rutas
muestra lo siguiente:
Los objetos con prefijo NetA.Subnet1 o NetA.Subnet2 son alcanzables directamente
(entrega directa).
Los objetos con prefijo NetB son alcanzables a través del encaminador
NetA.Subnet1.R2.
Para el resto de objetos se debe utilizar el encaminador NetA.Subnet2.R3 (ruta por
defecto).
Router . Row . NetA . Subnet1 .∗
Router . Row . NetA . Subnet2 .∗
Router . Row . NetB . ∗
Router . Row .∗
=
=
=
=
tcp , ∗
tcp , ∗
udp tcp , NetA . Subnet1 . R2
tcp , NetA . Subnet2 . R1
L ISTADO 7.4: Tabla de rutas IDM simplificada
i
i
i
i
i
i
i
i
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
189
Cada fila de la tabla de rutas incluye una lista de tipos de endpoints que se pueden
utilizar para contactar con objetos de esa red. Eso se debe a que cada red IDM está
constituida por una o más redes físicas compatibles que utilizan un mismo protocolo
(o conjunto de ellos). Para utilizar los mecanismos ALP de una red IDM es necesario
conocer al menos un tipo de endpoint compatible con esa red.
La figura 7.6 muestra las similitudes funcionales (salvando las distancias) entre los
procesos de encapsulación en un encaminador IP y uno IDM.
F IGURA 7.6: Comparación entre un encaminador IP y uno IDM
7.6.1.
Encaminamiento dinámico
Como los encaminadores son objetos distribuidos, resulta relativamente sencillo
implementar algoritmos de encaminamiento dinámico de cualquier tipo. Cada mensaje
del protocolo de encaminamiento elegido se define como un método del objeto en la
interfaz específica. Para soportar un nuevo protocolo de encaminamiento es suficiente
que implemente la interfaz correspondiente como una nueva faceta.
Como ejemplo, el listado 7.5 muestra la interfaz para el protocolo RIP2 [Mal98].
En ambos métodos, el parámetro oids es una lista de identificadores de objetos, que
puede estar vacía en el mensaje request(). El parámetro src es la identidad del
encaminador que realiza la invocación.
Este planteamiento permite implementar varios protocolos de encaminamiento dinámico
en el mismo nodo, aunque de operar a la vez, debe definirse un criterio de prioridad para
evitar conflictos en la actualización de la tabla de rutas.
7.6.2.
Gestión de la red
Dado que los encaminadores y los servidores son objetos distribuidos convencionales,
es posible utilizar los servicios estándar para despliegue que proporciona el middleware
(IceGrid en I CE). Con ello se consiguen muchas funcionalidades, algunas típicas de una
i
i
i
i
i
i
i
i
190
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
module Routing {
sequence < Ice :: Identity > IdentitySeq ;
interface RIP {
void request ( IdentitySeq oids , Ice :: Identity src ) ;
void response ( IdentitySeq oids , Ice :: Identity src ) ;
};
};
L ISTADO 7.5: Interfaz Slice para el protocolo de encaminamiento RIP
plataforma de gestión de red, pero con sobrecarga mínima y totalmente integradas en
el funcionamiento de la propia red:
Planificación
Es posible diseñar la topología, analizar las necesidades y requerimientos de red y
los usuarios, cuantificar los costes de mantenimiento y operación incluso antes de
disponer físicamente de los hosts y el equipamiento de comunicaciones.
Despliegue
Permite realizar distribución de ficheros de configuración, bibliotecas y binarios a
cada encaminador y, todo ello, a la medida de las prestaciones y tipo de arquitectura
de cada nodo.
Monitorización/contabilidad
Se puede evaluar el rendimiento del sistema, consecución de las prestaciones, ancho
de banda disponible/consumido, latencia y muchas otras variables de un modo
sencillo en cada encaminador y servidor de la red.
Gestión de la configuración
Cuando se disponga de nuevas versiones del software, éste puede ser desplegado
a los encaminadores, incluyendo implementación o mejoras de los protocolos de
encaminamiento. También es sencillo añadir interfaces para administración de los
equipos, definición de prioridades, políticas de seguridad, etc.
7.7.
Integración con el middleware
Una de nuestras prioridades es la integración del mecanismo de encaminamiento
con el middleware. Para el programador, las diferencias entre usar un objeto IDM y
un objeto distribuido convencional deberían ser mínimas. Por ese motivo, el reenvío
de mensajes se utiliza únicamente entre encaminadores y no afecta a la interacción
de estos con los clientes y los objetos.
Cuando un cliente desea hacer un invocación a un objeto IDM remoto utiliza una
clase especial para conseguir un proxy a su encaminador local (situado en el mismo
nodo que el cliente). El cliente realiza la invocación utilizando este proxy como si se
tratase realmente del objeto remoto.
A continuación se explica en detalle el proceso completo para realizar una invocación
a un objeto IDM remoto afectando al menos a un encaminador intermedio, es decir,
i
i
i
i
i
i
i
i
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
191
potencialmente cliente y objeto destino podrían encontrarse en redes tecnológicamente
distintas. La figura 7.7 ilustra todo ese proceso.
F IGURA 7.7: IDM: Invocación de un objeto IDM remoto
El encaminador local puede recibir invocaciones destinadas a cualquier objeto. Si la
identidad destino es la suya propia, él procesa el mensaje; en caso contrario, encamina el
mensaje hacia su destino. Cuando un encaminador recibe una invocación de un cliente
local realiza los siguientes pasos:
1. Si el mensaje requiere respuesta, crea un objeto callback alojado en su espacio
de memoria para poder recibir la respuesta. La referencia a este objeto es la que
aparecerá como campo src de la estructura HeaderData.
2. Construye un mensaje según el formato de la estructura ForwardRawMsg o
ForwardUserMsg (en adelante forward, por simplicidad) según el tipo de invocación
elegida por el cliente.
3. Comprueba su tabla de encaminamiento y determina la identidad del siguiente
encaminador y los endpoints de que dispone.
4. Filtra dichos endpoints según la información de Q O S de cada uno de ellos en relación
al T O S al que corresponde la invocación procedente del cliente. Si no encuentra
ninguno compatible retorna una excepción al cliente y aborta.
5. Utiliza el servicio ALP para determinar la información de direccionamiento del
protocolo inferior que corresponda.
6. Utiliza dicho endpoint para enviar el mensaje forward al siguiente encaminador.
Encaminador intermedio es aquel que recibe mensajes forward procedentes de cualquier
otro encaminador. En este caso el procedimiento de trabajo incluye únicamente los
puntos 3 a 6 de la lista anterior.
El encaminador final debe encargarse de entregar invocaciones directamente a los
objetos destino. Procede del siguiente modo:
1. Recibe un mensaje forward y comprueba su tabla de rutas para determinar si el
destino es un objeto de la forma habitual.
i
i
i
i
i
i
i
i
192
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
2. Mediante ALP obtiene los endpoints del objeto destino. Si ninguno de ellos fuera
compatible con los requisitos de Q O S, en este momento generaría una excepción
dirigida al objeto src.
3. A partir del contenido del mensaje forward crea un mensaje de invocación
convencional (en el caso de I CE será un HeaderData y un RequestData del protocolo
I CE P).
4. Ejecuta dicha invocación directamente sobre el cliente. Puede ser síncrono o no
dependiendo del tipo de mensaje y el endpoint utilizado.
5. Si la invocación es síncrona y hay respuesta, el encaminador procede con los mismos
pasos que se han descrito para el encaminador local, pero utilizando la referencia
src contenida en el mensaje forward.
Cuando la respuesta llega al objeto temporal que creó el encaminador local, éste
crea una respuesta según el formato del protocolo inter-ORB y lo entrega al cliente
por la misma conexión que se estableció para realizar la invocación. El cliente ha
estado bloqueado durante todo el proceso a menos que utilice los mecanismos AMI
proporcionados por el middleware.
Los calificativos local, final e intermedio no determinan tipos de encaminadores
sino roles. Todos los encaminadores pueden funcionar con cualquiera de esos roles.
La distinción presentada aquí se debe a motivos de legibilidad y simplificación de
las fases del procedimiento.
Nótese que a diferencia de CMR, se asume que todo nodo que aloja clientes tiene un
encaminador local, que es el único que recibe invocaciones directamente de los clientes. Es
decir, un cliente no puede efectuar invocaciones convencionales (no-IDM) a encaminadores
fuera de su nodo. Aunque esto implica un salto más, mejora la escalabilidad del sistema
dado que los encaminadores tienen que almacenar objetos callback para sus clientes. De
ese modo, es mucho más sencillo dimensionar las necesidades de memoria y procesamiento
del nodo, y los encaminadores sin clientes ni objetos pueden ser mucho más sencillos
pues están por diseño exentos de esa tarea.
7.7.1.
API
La intención es que IDM esté disponible como una biblioteca para servicios avanzados
de comunicaciones extremo a extremo de forma transparente. Por ese motivo, se ha
diseñado e implementado como un conjunto de clases que permite desarrollar objetos
y clientes de una manera muy sencilla.
Desde el punto de vista del programador de aplicaciones, para la implementación
de servidores sólo es necesario tener en cuenta una pequeña diferencia respecto a la
implementación de un servidor I CE convencional. Se debe utilizar un Adapter especial,
llamado IDM::Adapter. Es un decorador1 que extiende la funcionalidad del Adapter I CE.
Al crearse este adaptador, se registra automáticamente en el Servicio ALP disponible (tal
como se haya especificado por configuración). El listado 7.6 muestra la implementación
en lenguaje C++ de un objeto mínimo accesible mediante IDM.
1 en
referencia al patrón de diseño decorator [GHJV96]
i
i
i
i
i
i
i
i
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
193
class HelloI : virtual public Demo :: Hello {
public:
void sayHello (const string & name ,
const Ice :: Current & current ) {
cout << " Hello from ’" << name << " ’" << endl ;
}
};
class SimpleServer : public Ice :: Application {
public:
int run (int argc , char∗ argv []) {
Ice :: ObjectPtr serv = new HelloI ;
IDM :: AdapterPtr adapter =
new IDM :: Adapter ( communicator () , " testAdapter " ) ;
adapter −>add ( serv ,
communicator ()−>s t r i n g T o I d e n t i t y ( argv [1]) ) ;
adapter −>activate () ;
communicator ()−>w ai tF or S hu td ow n () ;
return EXIT_SUCCESS ;
}
};
int main (int argc , char∗ argv []) {
SimpleServer app ;
return app . main ( argc , argv ) ;
}
L ISTADO 7.6: Implementación de un servidor IDM mínimo
El cliente IDM también requiere algunas modificaciones respecto a la implementación
de un cliente I CE convencional. Es necesario crear una instancia de la clase IDM::Socket.
Éste dispone de un método plug() que acepta un identificador de objeto y devuelve un
proxy que permite enviar mensajes a ese objeto. Internamente, esa clase consulta la tabla
de encaminamiento del nodo y utiliza el servicio ALP para conseguir la referencia ya sea
para entrega directa o indirecta (primer salto). El listado 7.7 muestra la implementación
de un cliente para acceder al servidor del listado 7.6.
7.8.
Conclusiones
Aunque a primera vista, el diseño e implementación de un protocolo de red por encima
incluso de la capa de transporte pueda parecer un concepto contradictorio y un esfuerzo
baldío, queda demostrado que las prestaciones que ofrece IDM pueden resultar muy
valiosas en muchos escenarios diferentes. Algunas de las más importantes son:
Direccionamiento lógico universal independiente de la tecnología.
Transporte transparente extremo a extremo.
Mejoras en la eficiencia al poder seleccionar transportes específicos con menor
granularidad, que decide el diseñador de la aplicación.
i
i
i
i
i
i
i
i
194
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
class SimpleClient : public Ice :: Application {
public:
int run (int argc , char∗ argv []) {
IDM :: SocketPtr sock = new IDM :: Socket ( communicator () ) ;
Ice :: ObjectPrx obj = sock −>plug ( argv [1] , IDM :: QoS () ) ;
Demo :: HelloPrx prx = Demo :: HelloPrx :: uncheckedCast ( obj ) ;
prx −>sayHello ( " John " ) ;
return EXIT_SUCCESS ;
}
};
int main (int argc , char∗ argv []) {
SimpleClient app ;
return app . main ( argc , argv ) ;
}
L ISTADO 7.7: Implementación de un cliente IDM mínimo
Prestaciones adicionales transparentes y desacopladas del transporte como cifrado,
contabilidad, autenticación, autorización, etc.
Encaminamiento funcional.
Migración de nodos y encaminadores.
Aprovechando las posibilidades que ofrece IDM, estamos evaluando su aplicación
a diversos campos:
Redes MANET (Mobile Ad-hoc Network). Cada nodo de la red ad hoc puede incluir
un encaminador IDM, homogeneizando el acceso desde la red troncal. Este enfoque
permite incluso plantear redes ad hoc híbridas como, por ejemplo, una red IP y una
red de sensores.
Implementación del encaminador IDM en sistemas empotrados basados en
microcontrolador y/o en FPGA para el desarrollo de encaminadores eficientes para
redes SAN y grids heterogéneos [RDB+ 09].
Métricas del desempeño de la red y del servicio prestado.
Red virtual para provisión de Q O S [UVV+ 09].
En lo referente al desarrollo de nuevos endpoints, cabe destacar que se encuentran
en fase de desarrollo los que corresponden a protocolos tan variados como Zigbee,
BlueTooth y Ethernet.
Un concepto que creemos merece la pena abordar es lo que llamamos decoradores 2 de
endpoints. Pueden añadir características opcionales a cualquier endpoint, como cifrado,
garantía de entrega, contabilidad, etc. Estos decoradores facilitan la composición funcional
de endpoints dando lugar a combinaciones muy interesantes. Por ejemplo, si se requiere
transmitir audio en una red LAN Ethernet salvaguardando la privacidad, pero sin necesidad
de garantizar la entrega, se podría utilizar un endpoint que realiza transporte directamente
2 También
en referencia al patrón de diseño.
i
i
i
i
i
i
i
i
7. I NTEGRACIÓN DE REDES HETEROGÉNEAS
195
sobre tramas Ethernet y que está decorado con un endpoint que cifra los mensajes. De
ese modo, se puede conseguir el transporte deseado sin la sobrecarga que implicarían
las cabeceras IP y UDP.
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
88
Prototipos
8.1.
8.2.
8.3.
8.4.
8.5.
8.6.
8.7.
8.8.
Dispositivos
Máquina virtual
TwinPanel
Servicios
Activos experimentales
Análisis de protocolos
Prototipos IDM
Conclusiones
A
lo largo de este capítulo se describen algunos prototipos que sirven para validar
las propuestas realizadas en torno al modelo de información DUO, el protocolo
ASDF y su uso en picoObjetos. Se presentan varios escenarios concretos y algunos
servicios de uso general que utilizan y se integran en la infraestructura. Se evalúan
también prototipos preliminares de IDM.
8.1.
Dispositivos
En esta sección se describen brevemente algunos de los dispositivos utilizados para
la implementación de los prototipos. Se han incluido fotografías y esquemas para dar
una idea más exacta de su tamaño físico y complejidad.
8.1.1.
Motas Crossbow
Las motas de la empresa Crossbow son con toda seguridad los dispositivos más usados
en la investigación, prototipado y desarrollo de aplicaciones con WSN. Ésta es razón
suficiente para considerar la implementación de nuestros prototipos sobre dicha plataforma,
a pesar de que sus capacidades y recursos de cómputo superan con creces las necesidades
para la implementación de nuestra máquina virtual. Hemos realizado prototipos con
los siguientes dispositivos concretos:
Mota Crossbow IRIS (XM2210CA)
Integra un microcontrolador Atmel ATmega1280 con 8 KiB de SRAM, 4 KiB de
EEPROM y 128 KiB de Flash. Dispone de una interfaz de comunicaciones Zigbee
2.4GHz IEEE 802.15.4. La figura 8.1a muestra una fotografía de esta mota, indicando
la situación los sensores que integra. Se alimenta con dos pilas AA convencionales.
197
i
i
i
i
i
i
i
i
198
8. P ROTOTIPOS
Mota Crossbow MICA2 (MPR400CB)
Emplea un microcontrolador Atmel ATmega128 con 4 KiB de SRAM, 4 KiB de
EEPROM y 128 KiB de Flash. Como interfaz de red utiliza un transductor de
radio multicanal en la banda de 868/916 MHz. Se alimenta con dos pilas AA
convencionales.
Mota MICA2DOT (MPR500)
Tiene prácticamente las mismas características que el modelo anterior pero con
un formato más reducido. Integra un microcontrolador Atmel ATmega128L y se
alimenta con una pila botón de 3V (ver figura 8.1b).
Tarjeta de sensores Crossbow MTS310
Tiene un LDR, micrófono, magnetómetro, acelerómetro y zumbador.
Tarjeta de sensores Crossbow MTS420
Dispone de barómetro, sensor de temperatura, LDR, acelerómetro y receptor GPS.
Tarjeta de sensores Crossbow MDA300CA
Dispone de 6 canales digitales, 6 canales analógicos, 2 entradas optoacopladas,
sensor de humedad y sensor de temperatura.
Otros sensores
Utilizando tarjetas de expansión hemos integrado otros sensores como PIR (Passive
Infra Red), sensores de inclinación, relé reed y pulsadores convencionales.
(a)
(b)
F IGURA 8.1: Motas Crossbow IRIS (a) y MICA2DOT (b)
8.1.2.
TINI
El TINI (Tiny InterNet Interface) [TIN] es un dispositivo fabricado por Dallas
Semiconductor. Está diseñado para aplicaciones empotradas orientadas a usos relacionados
con Internet. Incorpora una implementación completa de la pila TCP/IP, ejecución
nativa de bytecode Java y varias interfaces para control de dispositivos: 1-wire, RS232
y Ethernet 10 Base-T.
i
i
i
i
i
i
i
i
8. P ROTOTIPOS
199
El modelo concreto que utilizamos es el DSTINI1-512; está basado en el procesador
DS80C390 que tiene 64 KiB de ROM, 512KB de SRAM y 1MB de Flash. Está montado
en un módulo SIMM de 72 contactos que se conecta en una placa de expansión (el
E10) que incluye las interfaces indicadas. La figura 8.2 muestra el módulo DSTINI1
montado en el socket E10.
F IGURA 8.2: Módulo DSTINI1 en el socket E10
8.1.3.
NXT
El NXT [NXT] es parte de Lego Mindstorm, un kit de robótica con fines docentes y
lúdicos. El brick es un dispositivo que incluye todo el hardware de control, el resto son
periféricos y accesorios mecánicos. El microprocesador principal es un ARM7DMI de
32 bits a 48 MHz. Dispone de 64 KiB de RAM y 256 KiB de Flash.
Además dispone de un microcontrolador ATmega48 de 8 bits a 4 KHz, 512 B de
RAM y 4 KiB de Flash. Cuenta también con un controlador Bluetooth, LCD de 100x64
píxels, USB 2.0, 4 puertos de entrada y 3 de salida. Aunque existen varios sistemas
para su programación, nuestros prototipos utilizan leJOS NXJ, un lenguaje basado
en Java. La figura 8.3 muestra el aspecto del NXT y los sensores y actuadores con
los que se distribuye.
8.1.4.
XPort
El XPort [XPo] (modelo XP1001001-03R) ofrece una interfaz RS232 con posibilidad de
utilizar instrucciones Hayes. Dispone de una implementación completa de la pila TCP/IP
pudiendo usar tanto UDP como TCP ya sea para conexiones pasivas o activas. Tiene un
cliente DHCP integrado y posibilidad de configurar el tipo de control de flujo, paridad
y otras opciones típicas de un puerto serie. También admite opciones básicas sobre la
conectividad TCP/IP. La figura 8.4a muestra un ejemplar de XPort.
i
i
i
i
i
i
i
i
200
8. P ROTOTIPOS
(a)
(b)
F IGURA 8.3: Brick NXT (a) y sus periféricos (b)
8.1.5.
WIZnet
WIZnet [WIZ] (modelo NM7010B) es una interfaz de red Ethernet similar a XPort
aunque ofrece algunas ventajas sobre éste. Incorpora una implementación completa de
la pila TCP/IP incluyendo IP multicast y medios 10/100 Base-T con auto-detección.
Se muestra en la figura 8.4b.
(a)
(b)
F IGURA 8.4: Interfaces Ethernet XPort(a) y WIZnet (b)
8.1.6.
Cámaras
En nuestros prototipos utilizamos cámaras de vídeo con distintas capacidades:
AXIS 214 [AXIb] – Es una cámara Pan-Tilt-Zoom (PTZ) de gama media con servidor
web incorporado y múltiples posibilidades de transporte, codecs de vídeo y otras
posibilidades avanzadas, como detección de movimiento.
AXIS 212 [AXIa] – Es un modelo algo más modesto que el anterior. Tiene la
peculiaridad de ofrecer PTZ instantáneo ya que no tiene partes móviles, utiliza
parte del CCD como si fuera la imagen completa.
i
i
i
i
i
i
i
i
8. P ROTOTIPOS
201
Canon VCC4 [VCC] – Es una cámara PTZ con gran calidad óptica. El control del
pedestal se efectúa con un protocolo específico mediante una interfaz RS232. La
imagen se obtiene de forma analógica por medio de una salida PAL convencional,
de modo que es necesario una tarjeta de captura de vídeo.
Logitech Sphere [Sph] – Es una webcam para uso doméstico, pero que permite giro e
inclinación. Utiliza una interfaz USB tanto para acceder al framegrabber como para
las instrucciones de control del pedestal.
(a)
(c)
(b)
(d)
F IGURA 8.5: Algunas cámaras de vídeo utilizadas en los prototipos. AXIS 214 (a),
AXIS 212 (b), Canon VCC4 (c) y Logitech Sphere (d)
8.2.
Máquina virtual
Se han realizado implementaciones de la máquina virtual FSM para distintas plataformas
y lenguajes de programación, pero siguiendo la misma especificación funcional. A
continuación se describen sus características concretas y su propósito:
i
i
i
i
i
i
i
i
202
8. P ROTOTIPOS
Máquina Python
La VM Python se ejecuta sobre un PC convencional. Se utiliza principalmente para la
ejecución de baterías de pruebas para los compiladores ipkc y fsm2data; también
para propósitos de depuración de las otras implementaciones de la máquina. Emplea
un diseño orientado a objetos en el que el propio intérprete es una clase. Permite
utilizar varios dispositivos como interfaz de red por medio de subclases:
Socket TCP.
Socket UDP.
Interfaz serie RS-232 para conexión a través de XPort.
Entrada/salida estándar para conectar a través de un programa externo como
netcat.
Utiliza el bucle de eventos de GNU Glib que permite registrar manejadores para
las entradas y eventos de manera sencilla. La implementación completa supone 831
SLOC de las cuales 265 corresponden a la implementación de la ISA.
El programa genera un registro detallado del funcionamiento incluyendo el contenido
de los mensajes recibidos y transmitidos, contenido de los registros, activación de
timers, etc.
Máquina Java
En este caso se ha realizado una única implementación del intérprete que no requiere
ninguna biblioteca externa. El intérprete lo constituyen 514 SLOC.
PC – Es una versión para ejecución de pruebas y ayuda para la depuración de las
otras implementaciones Java. El módulo específico para PC tiene 259 SLOC.
TINI – Aunque el TINI es un dispositivo potente que ejecuta nativamente
bytecode Java, no soporta un ORB CORBA completo. Sin embargo, es posible
ejecutar la VM de FSM sin ningún problema.
TINI permite acceder a una red CAN y tiene puertos USB y RS-232. Puede
utilizarse como bridge para acceder a transductores que utilicen estas interfaces.
NXT – La versión para el NXT es muy similar a la anterior salvo porque utiliza
leJOS FW v0.7 y comunicaciones Bluetooth. Requiere 270 SLOC adicionales.
Su finalidad, a pesar de ser completamente funcional, está más orientada a
ilustrar la versatilidad de la propuesta que a conseguir una plataforma de
sensorización realmente útil, al menos con objetivos industriales.
Máquina C
Esta versión es la más versátil. El módulo que implementa la ISA está escrito en
ANSI C, sin ninguna biblioteca o dependencia; ocupa unas 683 SLOC incluyendo
abundante código de preprocesador que permite incluir sólo las instrucciones que se
utilizan si así se desea.
Existe una única implementación del intérprete que se compila junto a otros módulos
para tareas dependientes de la plataforma (interfaz de red, timers, bucle de eventos,
etc.) para así obtener una VM completa en cada una de las plataformas soportadas.
i
i
i
i
i
i
i
i
8. P ROTOTIPOS
203
PC – Emplea IO Channels de GNU Glib para la implementación del bucle de
eventos y timers. Utiliza la E/S estándar como dispositivo de red. El fichero
ejecutable resultante se utiliza conjuntamente con la utilidad netcat, socat o
socket, disponibles en la mayoría de sistemas GNU.
TinyOS – Esta versión está escrita en nesC [Nesa], el lenguaje típicamente usado
en la plataforma TinyOS. El bucle de eventos y gestión de timers está construido
sobre el sistema de tareas de este SO, así como el acceso a la interfaz de red.
Se utiliza en varios tipos de mota (véase § 8.1.1).
Atmel – En este caso se utiliza un sencillo ejecutivo cíclico como implementación del bucle de eventos. Para las comunicaciones se utiliza una biblioteca
Zigbee que acompaña al kit de desarrollo que se ha utilizado para la implementación.
Máquina en Ensamblador
Esta es la implementación más simple que hemos realizado. Está destinada a
microcontroladores Microchip de 8 bits. Tenemos prototipos para dos modelos:
P16F876A – Reloj de 10/20 KHz, 368 B de RAM, 8 Kpalabras de memoria de
programa, 256 B de EEPROM y 32 pines GPIO. Dispone de 2 timers de 8 bits
y uno de 16 bits.
P16F690 – Reloj de 20 KHz, 256 B de RAM, 256 B de EEPROM y 18 pines de
GPIO. Tiene los mismos timers que el modelo anterior.
No supondría un problema portarlo a otros modelos. Las únicas dependencias están
en la comunicación con la UART/USART, la programación de timers y la gestión
de la GPIO. De modo que el planteamiento en ese aspecto resulta muy similar a la
versión C. La diferencia más importante en los prototipos realizados es el dispositivo
utilizado como interfaz de red:
Ethernet – Se han implementado versiones para dos dispositivos: el XPort y el
WIZnet.
WiFi – En este caso la única diferencia consiste en utilizar el dispositivo WiPort
en lugar de XPort.
RS-485 – El objetivo aquí es utilizar una red de datos de muy bajo coste para
sistemas estáticos en los que sea factible realizar cableado físico. Se utiliza un
transductor RS232 a RS485 (modelo SN75HVD08DR). Se pueden conectar
hasta 256 nodos a un único bus. Requiere un árbitro implementado con un
ATmega128.
La tabla 8.1 muestra los requisitos mínimos necesarios para cada una de las
implementaciones de la VM. Nótese que las versiones C y ensamblador pueden optimizarse
para incorporar únicamente las instrucciones que realmente se usan en el FSM específico.
En el caso de la mencionada tabla, se trata de una implementación completa sin este
tipo de optimización, ya que se considera que de ese modo es más sencillo comparar
en términos absolutos. En la versión ensamblador, el tamaño de programa está indicado
en palabras (no bytes); en la versión C se indica el tamaño de los ficheros objeto y
en la versión Java el de los .class.
i
i
i
i
i
i
i
i
204
8. P ROTOTIPOS
La cantidad total de recursos necesarios para un nodo concreto se puede obtener sumando
a los datos de esta tabla los requisitos concretos del bytecode y sirviente concretos. Las
diferencias por sobrecarga u optimizaciones particulares deberían ser mínimas. Por este
motivo, consideramos que el tamaño de la VM es en sí mismo un dato representativo.
plataforma
PIC + XPort (asm)
PIC + RS485 (asm)
Atmel + Zigbee (C)
MICA (TinyOS, NesC)
TINI (Java)
NXT (leJOS)
PC (C)
PC (Python)
PC (Java)
VM
bibliotecas
SO
RAM
1 824
1 824
4 667
5 199
30 230
23 000
9 360
35 699
32 074
819
360
4 261
687
lejOS
GNU glib
std lib
JVM
N/A
N/A
N/A
14 873
-
65
55
85
3 176
645
-
C UADRO 8.1: Memoria requerida por la máquina virtual en cada plataforma (en bytes)
8.3. TwinPanel
TwinPanel es una completa aplicación gráfica para inspección, depuración y diagnóstico
del entorno inteligente con soporte específico para los protocolos e interfaces definidos
en los capítulos anteriores.
Utiliza un diseño extremadamente modular —basado en el patrón Model-ViewController (MVC)— que permite decidir automáticamente cuales son las posibilidades
de visualización y actuación para un actor concreto. El usuario puede decidir cuál de las
vistas posibles desea utilizar para interactuar con un actor o servicio.
El soporte para cada interfaz o protocolo (los modelos) está encapsulado en un inspector
y las alternativas de visualización (las vistas) en lo que llamamos skins. Todos ellos están
disponibles como plugins que se cargan dinámicamente cuando se requieren. Toda la
aplicación está escrita en lenguaje Python y hace uso extensivo de la biblioteca GTK,
algo más de 10 600 SLOC incluyendo todos los plugins.
Los inspectores específicos que cubren las funcionalidades relacionadas con las
aportaciones de este trabajo son:
I CE
• Objetos genéricos
• Canales de eventos
• IceGrid
DUO
•
•
•
•
Interfaces escalares
Objetos activos
Contenedores
Componentes
i
i
i
i
i
i
i
i
8. P ROTOTIPOS
205
• Objetos compuestos
ASDF
• Anunciamientos
• Propiedades de un objeto
• Búsqueda de servicios
Otros
• Cámaras de vídeo
Existen además otros inspectores de uso general que pueden ser útiles para el sistema:
Bluetooth
Zeroconf
UP N P
La figura 8.6 muestra la apariencia de TwinPanel haciendo uso de ambos paneles.
F IGURA 8.6: TwinPanel, aspecto general
8.4.
Servicios
En esta sección se describen algunos servicios de uso general implementados como
servicios IceBox, y que aprovechan muchas de las pautas de diseño de DUO y ASDF.
8.4.1.
PropertyServer
Este servicio es una implementación directa de la interfaz PropertySetDef. Utiliza una
base de datos Freeze accedida automáticamente desde un único sirviente. Para poder servir
propiedades de muchos actores, utiliza un ServantLocator especial que emplea la identidad
de objeto del proxy para indexar la base de datos. Esto significa que es una solución
i
i
i
i
i
i
i
i
206
8. P ROTOTIPOS
muy escalable. La memoria requerida por el servidor no crece de manera significativa
puesto que no es necesario crear nuevos objetos dinámicamente a pesar de que la base de
datos incluya información sobre miles o millones de actores. El servicio se anuncia con
ASDF aunque también puede estar registrado como un objeto bien conocido. Está escrito
íntegramente en C++ y hace uso de las bibliotecas Freeze y IceStorm.
Este servidor utiliza una biblioteca llamada libPropertyService. El objetivo de
ésta es dotar de propiedades a cualquier actor sin más que enlazar la biblioteca y crear
la instancia de la clase que proporciona.
8.4.2.
ContextServer
Se trata de una generalización del concepto de contenedor (véase § 3.3). Es una
implementación directa de la interfaz DUO::Container::RW, pero además permite asignar
propiedades a cualquier contenedor de la jerarquía. El método create() crea nuevos
objetos iguales al raíz que se alojan en la memoria del propio servidor. También permite
enlazar contenedores que residen en otras instancias de forma transparente. Podemos
considerar que los contenedores definen contextos que agrupan objetos cualesquiera
con la ayuda de propiedades.
Por ejemplo, uno de los casos más representativos es la construcción de mapas
conceptuales, es decir, representaciones visuales de un grupo de objetos. El contexto
tiene una propiedad map que permite acceder a un fichero gráfico (SVG generalmente) y
propiedades que indican la posición de cada objeto respecto a ese mapa. Por su parte, cada
objeto tiene una propiedad icon para representar visualmente el objeto. Por supuesto, si se
trata de dispositivos simples puede ser una cadena de texto que indica un icono de stock,
y si son picoObjetos la propiedad estará en un servidor de propiedades y no en el propio
objeto. La figura 8.7 muestra uno de estos contextos que incluye representación gráfica.
8.4.3.
CacheService
Es un servicio de registro automático para anunciamientos. Se puede utilizar como
servicio de registro centralizado o híbrido en ASDF, tal como se explica en la sección 5.6.2.
El servicio se encarga de clasificar automáticamente cada nuevo actor anunciado y lo
elimina al despedirse. Por cada interfaz de servicio que implemente se registra en un
contexto, que se crea automáticamente si no existe. Esta información no es persistente
dado que puede cambiar con cierta frecuencia.
Se anuncia y si encuentra el ContextServer se registra automáticamente. Implementa
las interfaces DUO::Container::R y ASD::Listener. La figura 8.8 muestra una captura de
TwinPanel inspeccionando el CacheService. El código específico supone alrededor
de 200 SLOC de C++.
8.4.4.
CameraServer
Se trata de un servicio genérico para integrar fuentes multimedia (principalmente
cámaras de vídeo) en el entorno inteligente. Una cámara se modela por medio de varias
interfaces predefinidas. La declaración de la interfaz se muestra en el listado 8.1. La
utilidad de cada una de esas interfaces heredadas se explica a continuación:
i
i
i
i
i
i
i
i
8. P ROTOTIPOS
207
F IGURA 8.7: TwinPanel inspeccionando un contexto alojado en un ContextServer
F IGURA 8.8: TwinPanel inspeccionando el CacheService
Service::Camera
Es la interfaz que identifica el tipo de servicio proporcionado por el actor según la
taxonomía (véase § 5.2.3).
i
i
i
i
i
i
i
i
208
8. P ROTOTIPOS
DUO::Container::R
La cámara es un contenedor que almacena referencias a otros actores. En este caso
tiene una función muy concreta. Representa una relación de agregación en la que
cada uno de los actores contenidos tiene una responsabilidad funcional específica
pero opcional.
En las cámaras PTZ, cada elemento con el que se puede interactuar se modela como
otro objeto DUO que se incluye en el contenedor. Es posible añadir actores para pan,
tilt, zoom, focus, preset, iris y muchos otros.
AVStreams::MMDevice
La transmisión de flujos multimedia está desacoplada del transporte utilizado por
el middleware. Para ello se utiliza la especificación A/V Streams [Obj98] de OMG.
La cámara se comporta como un Multimedia Device que puede negociar el tipo de
transporte a utilizar con el otro extremo.
Se han implementado transportes con RTSP y M-JPEG. TwinPanel dispone de un
inspector de cámaras capaz de representar el flujo de vídeo utilizando libVLC.
PropertyService::PropertySetDef
El servicio proporciona almacenamiento y acceso a las propiedades de la cámara
por medio de libPropertyService.
interface Camera extends
Service :: Camera ,
DUO :: Container :: R ,
AVStreams :: MMDevice ,
P ro pe rt y Se rv ic e :: Pro pertySetD ef {};
L ISTADO 8.1: Declaración de un actor que sirve una cámara de vídeo PTZ
Tanto para el acceso al flujo multimedia como para el control del movimiento, el
programa emplea plugins que se cargan en función de la configuración del servicio,
mediante propiedades I CE. Puede gestionar cámaras que tienen su propio transporte de
vídeo, como es el caso de las cámaras IP. Si el framebuffer es accesible localmente,
utiliza VLC como servidor. Se han creado drivers para las cámaras AXIS 214, AXIS
212, Cannon VCC4 y Logitech Quickcam Orbit.
Este servicio también se anuncia a través de ASDF y es un suscriptor del canal ASDS
para poder responder a búsquedas. La implementación, incluyendo todos los drivers
mencionados supone alrededor de 5 882 SLOC.
La figura 8.9 muestra el aspecto de TwinPanel inspeccionando una cámara. En el panel
derecho aparece el flujo de vídeo y los controles del pan-tilt y en el izquierdo aparece
la misma cámara pero utilizando la vista de contenedor.
8.4.5.
ChannelMonitor
Es un servicio auxiliar para dotar de canales de eventos a los picoObjetos activos.
Un actor convencional es capaz de interactuar con el servicio de eventos para crear su
i
i
i
i
i
i
i
i
8. P ROTOTIPOS
209
F IGURA 8.9: TwinPanel inspeccionando una cámara servida por CameraServer
propio canal al que enviar sus actualizaciones de estado. Sin embargo, los picoObjetos
por diseño, no pueden obtener el proxy a su canal aunque pudieran crearlo. Es necesario
que un tercero se encargue de crear el canal y asignarlo al actor activo por medio de
la interfaz DUO::Active::W. Cuando un picoObjeto activo arranca por primera vez,
el proxy de su canal es nulo. CacheMonitor se encarga de la tarea de crear y asignar
canales en esta situación.
Existen dos posibilidades para su diseño:
El servicio puede escuchar los anunciamientos de los actores, comprobar si son
activos y tienen su canal asociado. Este mecanismo es transparente pero requiere
que el servicio consulte a todos los actores que se anuncian, con el gasto que ello
implica.
La aplicación cliente que desea suscribirse a un objeto activo, y detecta que no tiene
un canal válido, solicita al ChannelMonitor que le asigne uno. Esta opción es menos
transparente porque los clientes deben contactar explícitamente con el servicio, pero
escala mejor y no genera tráfico innecesario.
Como siempre, la elección de uno u otro diseño depende de las necesidades concretas
del entorno. En nuestros prototipos utilizamos la primera opción.
8.5.
Activos experimentales
Esta sección describe escenarios concretos de complejidad creciente. Para cada uno
de ellos, se explica su utilidad y se incluye la definición correspondiente usando IcePick.
En la sección 8.5.10 se ofrece un resumen de los requerimientos de memoria de los
siguientes ejemplos.
i
i
i
i
i
i
i
i
210
8. P ROTOTIPOS
8.5.1.
Actor mínimo
El actor más simple que podemos crear es un actuador que implementa la interfaz
DUO::Pulse::W y utiliza transporte oneway. Eso implica que no puede responder a ningún
método y, por tanto, los mecanismos de introspección (métodos de la interfaz Ice::Object)
son inútiles y puede ser excluidos. La definición de un nodo que aloja uno de estos objetos
en una red TCP/IP podría ser la que muestra el listado 8.2.
uses " DOBS / DUO . ice ";
object DUO . Pulse . W minimo {
mode = oneway ;
};
local adapter node {
endpoint = " tcp −p 12345";
objects = {" OBJ01 ": minimo };
};
L ISTADO 8.2: Objeto mínimo: DUO::Pulse::W con transporte oneway
8.5.2.
Otros actores sencillos
Cuando se cuenta con un transporte que permite responder a los mensajes (twoway) se
pueden incorporar los mecanismos de introspección y el soporte básico de excepciones,
asumiendo el coste correspondiente. El listado 8.3 muestra la especificación de un nodo
con un sensor DUO::IBool::R y un actuador DUO::IBool::RW 1 .
uses " DOBS / DUO . ice ";
uses " picos . ice ";
object DUO . IBool . R sensor ;
object DUO . IBool . RW actuador ;
local adapter node {
endpoint = " tcp −p 12345";
objects = {" OBJ01 ": sensor , " OBJ02 ": actuador };
};
L ISTADO 8.3: Un sensor DUO::IBool::R y un actuador DUO::IBool::RW
Para crear un sensor proactivo es necesario escribir una interfaz Slice que herede
de alguna interfaz DUO escalar además de DUO::Active::R. El listado 8.4 muestra
la declaración Slice de dicha interfaz para un sensor booleano activo (fichero boolactive-sensor.ice) y el listado 8.5 muestra la definición de un sensor proactivo
que utiliza esa interfaz y además envía anuncios proactivos usando el método
ASD::Listener::adv().
1 Esta
interfaz requiere heredar de DUO::IBool::R y DUO::IBool::W tal como se explicaba en 3.2
i
i
i
i
i
i
i
i
8. P ROTOTIPOS
211
#include " DOBS / DUO . ice "
module MySystem {
interface BoolRactive extends DUO :: IBool :: R , DUO :: Active :: R {};
};
L ISTADO 8.4: Declaración de una interfaz Slice para un sensor activo
uses " DOBS / DUO . ice ";
uses " bool−active−sensor . ice ";
uses " DOBS / ASDF . ice ";
object MySystem . BoolRactive sensor ;
local adapter node {
endpoint = " tcp −p 12345";
objects = {" OBJ01 ": sensor };
};
object DUO . IBool . W sink ;
object ASD . Listener ASDA ;
remote adapter external {
endpoint = " tcp −h 10.0.0.2 −p 9000";
objects = {" SINK04 ": sink ,
" IceStorm / ASDA . publish ": ASDA };
};
timer (30) {
ASDA . adv ( sensor ) ;
}
event PRESE NCE_EVEN T do {
sink . set ( sensor . get () , sensor . oid ) ;
}
L ISTADO 8.5: Definición de un sensor booleano proactivo
Existen cientos de combinaciones útiles de las interfaces de DUO y ASDF. La tabla 8.2
recoge el tamaño de éstos y otros prototipos con el fin de ilustrar las necesidades en
memoria que implica utilizar distintas características.
8.5.3.
Cerradura inteligente
Se trata de un prototipo muy sencillo, pero que se ha construido físicamente para su
uso real. Implementa un actuador DUO::IBool::RW twoway con anunciamientos, que
utiliza un PIC 16F690 y un módulo XPort. Permite accionar remotamente la cerradura y
conocer su estado. Se puede integrar de forma muy sencilla con un servicio de seguridad
y de autenticación de personas para acceso a una habitación. En la figura 8.10 se puede
observar un montaje preliminar del prototipo.
i
i
i
i
i
i
i
i
212
8. P ROTOTIPOS
F IGURA 8.10: Cerradura electrónica controlada por un picoObjeto
8.5.4.
Control de consumo
En este caso se exporta la funcionalidad de un interruptor electrónico de media potencia
como un actuador. El objetivo es cortar la corriente de un aula de computadores durante
los periodos de inactividad. Un PC convencional puede tener un consumo de hasta 40 W
cuando está apagado porque realmente se mantiene en un estado de stand-by. Este prototipo
se puede integrar en el cuadro eléctrico del aula y permite establecer un servicio que conoce
los horarios de uso y puede apagar completamente todos los equipos del aula.
(a)
(b)
F IGURA 8.11: Prototipo para control de consumo eléctrico
Sería muy conveniente un servicio de este tipo para una escuela o todo un campus,
puesto que algunas de las aulas se utilizan en periodos no lectivos para realizar rendering y
otras actividades de cómputo intensivo. Realizar una conexión/desconexión manual sería
administrativamente complejo, ineficaz y propenso a errores.
Funcionalmente el nodo es un actuador booleano, pero estamos trabajando en un modelo
que permite conocer además el consumo realizado por cada aula y así medir con precisión
i
i
i
i
i
i
i
i
8. P ROTOTIPOS
213
cuál es la previsión y el ahorro que realmente se consigue. Utiliza un PIC 16LF876A y un
módulo XPort como interfaz de red. La figura 8.11 muestra una fotografía del prototipo.
8.5.5.
Placas de prototipado
Para la realización de prototipos sencillos basados en PIC utilizamos principalmente
dos montajes:
El primero está basado en el PICkit2, un kit extremadamente simple fabricado por
Microchip, pero que con pequeñas modificaciones sirve perfectamente a nuestros
propósitos. Esta es la placa que se muestra en la imagen de la figura 8.10.
El segundo es un diseño propio, también muy sencillo, que integra dos displays de 7
segmentos y dos pulsadores. Puede verse en la figura 8.12. Utiliza un PIC 16LF876
y puede conectarse con XPort, WIZnet o línea serie.
F IGURA 8.12: Placa de prototipado para picoObjetos (ALSO1)
8.5.6.
Cableado virtual
El escenario puede ser un salón de ferias y muestras en el que la colocación y tamaño de
los stands de los anunciantes puede ser totalmente diferente en eventos distintos. Aunque la
sala dispone de alumbrado permanente, raramente se acomoda a las necesidades concretas
de cada stand, ya que el patrón de encendido es estático; se conectan puntos de luz por
filas o columnas. Cuando una sala tiene decenas o centenares de ellos, es demasiado
caro y aparatoso instalar interruptores para cada uno.
Debe llevarse una línea de corriente a cada punto de luz como se hace habitualmente,
pero en lugar de conectar un interruptor en un registro, proponemos instalar un actuador
booleano que funcione como interruptor, de forma similar al prototipo de la sección 8.5.4,
pero para una carga menor. Para evitar el cableado de una red de datos se puede utilizar
una interfaz inalámbrica o bien PLC.
i
i
i
i
i
i
i
i
214
8. P ROTOTIPOS
El control de todos estos puntos de luz puede hacerse desde cualquier dispositivo que
puede enviar invocaciones a los actores; puede ser una interfaz gráfica en un PC, un panel
de control centralizado, interruptores fijos instalados en el edificio o bien interruptores
inalámbricos, como el que se muestra en la figura 8.13. Tal como vimos en la sección 3.7.1,
cada interruptor individual puede actuar sobre un conjunto arbitrario de puntos de luz
y es posible recablear las interconexiones lógicas en cualquier momento. Se pueden
añadir interruptores y puntos de luz para cubrir las necesidades de cada evento de una
forma muy sencilla, rápida y barata.
F IGURA 8.13: Interruptor inalámbrico para cableado virtual
8.5.7.
Termostato
Planteamos un escenario en el que se debe controlar la temperatura de una habitación
(por ejemplo, un CPD). El termostato debe poder fijar una temperatura máxima mediante
interacción directa o remota sobre el control. Si la refrigeración falla y el umbral fijado
se ve superado, el sistema dispara una señal que se puede utilizar para activar una alarma,
avisar a un operario o apagar las máquinas susceptibles de sufrir daños por la temperatura
excesiva. Hay tres nodos involucrados:
Un sensor de temperatura. Es un sensor proactivo instalado en una mota IRIS.
Un actuador que recibirá la señal de alerta cuando se supere el umbral establecido.
Se implementa como un canal de eventos convencional ejecutándose en un PC.
El panel de control. Representa la temperatura actual en un display y permite editar
la temperatura máxima con dos pulsadores. Se instala en la placa ALSO1 (ver
figura 8.12).
El umbral, que también es un objeto, únicamente almacena el valor y puede ser
consultado y modificado remotamente como un actuador. El listado 8.6 muestra la
especificación IcePick para el panel de control. ByteRWSeq es una interfaz Slice que
hereda de DUO::IByte::R, DUO::IByte::W y DUO::Func::Relative.
i
i
i
i
i
i
i
i
8. P ROTOTIPOS
1
2
3
uses " DOBS / DUO . ice ";
uses " IceStorm / IceStorm . ice ";
uses " MyApp . ice ";
5
6
object DUO . IByte . W display ;
object MyApp . ByteRWSeq threshold ;
8
9
10
11
local adapter thermostat {
endpoint = "";
objects = {" UUID1 ": display , " UUID2 ": threshold };
};
13
14
object IceStorm . Topic t h e r m o m e t e r _ t o p i c ;
object DUO . Pulse . W alarm ;
16
17
18
19
20
remote adapter events_server {
endpoint = "";
objects = {" IceStorm / therm01 . topic ": thermometer_topic ,
" IceStorm / alarm01 . publish ": alarm };
};
22
object DUO . IByte . R thermometer ;
24
25
26
27
remote adapter therm {
endpoint = "";
objects = {" therm01 ": thermometer };
};
29
30
31
boot {
t h e r m o m e t e r _ t o p i c . subscribe ( display ) ;
}
33
34
35
36
display_delay : timer (2) {
thermometer . ice_ping () ;
display_delay .enable( false ) ;
}
38
39
40
41
show_ threshol d : function {
display . set ( threshold . get () , "") ;
display_delay .enable( true ) ;
}
43
44
45
46
event UP_PUSH do {
threshold . inc (1) ;
show_ threshol d . run () ;
}
48
49
50
51
event DOWN_PUSH do {
threshold . inc (−1);
show_ threshol d . run () ;
}
53
54
55
when display . set ( v ) do {
alarm . set ("") if ( v > threshold . get () ) ;
}
215
L ISTADO 8.6: Especificación del nodo de control del termostato con alarma
i
i
i
i
i
i
i
i
216
8. P ROTOTIPOS
En el arranque (boot) el display se subscribe al canal de eventos del termómetro,
de modo que a partir de ese momento representará su valor de temperatura cada
vez que cambie. Durante su funcionamiento, este nodo responde ante dos situaciones
asíncronas:
Cuando se pulse cualquiera de los dos pulsadores UP y DOWN se ejecutarán
los triggers event respectivos; esos eventos son lanzados por el sirviente de los
pulsadores. Esto provoca un cambio en el valor del objeto threshold por medio
del método inc(). A continuación se ejecuta la función show_threshold.
Esa función presenta el valor de threshold en el display y activa el temporizador
display_timer. Transcurridos dos ticks se dispara la ejecución del código asociado
que invoca el método ice_ping() sobre el termómetro. Como es un actor reactivo,
enviará su valor de inmediato a su canal, provocando que el display deje de
mostrar el valor del umbral —que se estaba editando— y presente el valor de la
temperatura actual. A continuación display_delay se desactiva a sí mismo para
evitar sucesivos disparos automáticos.
Cuando llega un nuevo valor de temperatura procedente del termómetro (trigger
when) evalúa si es mayor que el valor del objeto threshold. Si es así envía un
mensaje set() al publicador del canal alarm, que recibirán todos los subscriptores,
lo que les informa de que la temperatura ha superado el umbral.
8.5.8.
Sensor día/noche
Veamos una forma de implementar un sensor día/noche por medio de un sensor
tipo LDR y la definición de rangos con el soporte que define DUO para activación
condicional (véase § 3.4.3).
El listado 8.7 muestra la especificación IcePick para este ejemplo. Un sensor proactivo
con activación condicional por rango, como éste, envía eventos set() con su estado sólo
cuando se produce un cambio en el valor que mide y éste se encuentra dentro del rango.
Sin embargo, el sensor día/noche debe enviar un valor booleano indicando si es de día o de
noche. Para lograrlo se crea un objeto intermedio (dummy), que no es accesible remotamente.
Se configura ese objeto como publisher del verdadero sensor. El trigger when se encarga de
«convertir» la condición de superación de ambos umbrales en un valor booleano. Nótese
que el sensor sólo genera eventos cuando el valor está dentro de rango, es decir, no puede
ocurrir que el when envíe dos eventos booleanos seguidos del mismo valor.
8.5.9.
Detección de presencia polivalente
Una de las aplicaciones más frecuentes hoy día de los detectores de presencia
volumétricos y sensores PIR en oficinas y hogares es la activación de iluminación interior.
Este prototipo desempeña esa función, encendiendo las luces sólo si es de noche, pero
además se utilizan esos sensores para detección de intrusos si el sistema está en modo
de seguridad. Con ello se pretende demostrar la versatilidad de nuestra solución evitando
la necesidad de instalar sensores específicos para cada servicio (algo habitual en las
soluciones domóticas tradicionales).
Contamos con los siguientes elementos:
i
i
i
i
i
i
i
i
8. P ROTOTIPOS
1
2
uses " DOBS / DUO . ice ";
uses " MyApp . ice ";
4
object DUO . IFloat . W dummy ;
6
7
8
object DUO . ActiveFloatR light_sensor {
publisher = dummy ;
};
10
11
12
13
object DUO . IFloat . RW day_value {
default = light_sensor ;
facet
= " range_max ";
};
15
16
17
18
object DUO . IFloat . RW night_value {
default = light_sensor ;
facet
= " range_min ";
};
20
21
22
23
24
25
local adapter node {
endpoint = "";
objects = {" LDR001 ": light_sensor ,
" LDR001 . day ": day_value ,
" LDR001 . night ": night_value };
};
27
object DUO . IBool . W day_topic ;
29
30
31
32
remote adapter server {
endpoint = "";
objects = {" IceStorm / day . publish ": day_topic };
};
34
35
36
37
when dummy . set ( value ) do {
day_topic . set ( False , "") if ( value > day_value . get () ) ;
day_topic . set ( True , "") if ( value < night_value . get () ) ;
}
217
L ISTADO 8.7: Sensor día/noche con activación condicional. La interfaz ActiveFloatR
hereda de DUO.IFloat.R y DUO.Active.R
i
i
i
i
i
i
i
i
218
8. P ROTOTIPOS
Un sensor noche/día. Podría haber varios para evitar fallos y utilizar un objeto
compuesto (véase § 3.6) para agregar la información deseada. En cualquier caso,
se considera un actor que envía mensajes DUO::IBool::set() siendo True el
anochecer y False el amanecer.
Sensores de presencia. Aunque implementados como picoObjetos, son sólo clientes,
no objetos. Envían mensajes DUO::Pulse::W::set().
Control de iluminación. La iluminación de cada sala es independiente. Los sensores
de presencia activan la iluminación de su sala. De cualquier modo, esto puede
cambiar aplicando el cableado virtual.
Alarma. Será una referencia a un canal de eventos al que pueden suscribirse todos
aquellos que quieran ser alertados de una situación de intrusión, es decir, detección
de presencia en modo emergencia.
En el listado 8.8 especificamos el servicio que se instala en los nodos que integran
el sensor de presencia. Al detectar presencia, el servicio conecta la iluminación local
durante 15 ticks, después la apaga. Nótese que, con esta especificación, las luces no se
encienden si es de día y tampoco en modo de seguridad.
Cuando el nodo se conecta, se suscribe automáticamente al canal del sensor día/noche,
de modo que estará operativo automáticamente. Si se desea, es posible que el modo de
seguridad se propague por medio de un canal de eventos, caso en el que el nodo podría
suscribirse del mismo modo. También es posible integrar el control de la iluminación
de la zona en el mismo nodo con cambios mínimos.
Si se quiere disponer globalmente de la información de presencia, sin que ello esté
ligado a la señal de alarma e independientemente de que esté activado el modo de
seguridad, basta con convertir el sensor de presencia en proactivo. Los canales de todos
los sensores se pueden enlazar para que los suscriptores pueden saber qué sensor se ha
activado en cada momento. Si los sensores tienen información de posición es sencillo
realizar una representación gráfica.
8.5.10.
Requisitos de memoria
La tabla 8.2 muestra los recursos necesarios para la implementación de cada uno
de los prototipos descritos en las secciones anteriores. Se incluyen algunos otros de
diferente complejidad pero que, por su similitud, no se han descrito expresamente. Cada
fila de la tabla describe un nodo con uno o varios objetos. Para cada uno, muestra
la cantidad de memoria de programa (fsmCode), ROM (fsmData), Flash (fsmFlash) y
RAM (tamaño del banco de registros).
Para obtener los recursos necesarios para un nodo completo, hay que sumar a estas
cantidades lo requerido por la máquina virtual sobre la que se ejecute (ver tabla 8.1)
y el sirviente o drivers que se utilicen.
i
i
i
i
i
i
i
i
8. P ROTOTIPOS
1
2
3
uses " DOBS / DUO . ice ";
uses " DOBS / ASD . ice ";
uses " IceStorm / IceStorm . ice ";
5
6
object DUO . IBool . W ni ght_obse rver ;
object DUO . IBool . RW service ;
8
9
10
11
12
local adapter presence_node {
endpoint = "";
objects = {" UUID1 ": night_observer ,
" UUID2 ": service };
};
14
15
16
object DUO . Pulse . W alarm ;
object IceStorm . Topic night_topic ;
object ASD . Listener ASDA ;
18
19
20
21
22
23
remote adapter event_server {
endpoint = "";
objects = {" IceStorm / alarm . publish ": alarm ,
" IceStorm / night . topic ": night_topic ,
" IceStorm / ASDA . publich ": ASDA };
};
25
object DUO . IBool . W light ;
27
28
29
30
remote adapter local_light {
endpoint = "";
objects = {" UUID3 ": light };
};
32
33
34
35
boot {
auto_off .enable( False ) ;
night_topic . subscribe ({} , nigh t_observ er ) ;
}
37
38
39
timer (10) {
ASDA . adv ( service ) ;
}
41
42
43
44
auto_off : timer (15) {
light . set ( False , service . oid ) ;
auto_off .enable( False ) ;
}
46
47
48
49
night : event PRES ENCE_EVE NT do {
light . set ( True , service . oid ) ;
auto_off . reset () ;
}
51
52
53
security : event PRESE NCE_EVEN T do {
alarm . set ( service . oid ) ;
}
55
56
57
when nigh t_observ er . set ( v ) do {
night .enable( v ) ;
}
59
60
61
when service . set ( v ) do {
security .enable( v ) ;
}
219
L ISTADO 8.8: Detección de presencia polivalente (iluminación e intrusión)
i
i
i
i
i
i
i
i
220
8. P ROTOTIPOS
prototipo
endpoint
adv
#trig
data
code
flash
total
RAM
actor mínimo
(Pulse.W)
IBool.R + Bool.RW
cerradura (Bool.RW)
IBool.R + Active.R
IString.RW
IBool.RW + IByte.RW
3 × IBool.RW
3 × (IBool.RW
+ Active.R)
3 × IInt.RW,
3 × IInt.R,
1 × IBool.R
termostato
presencia polivalente
oneway
no
0
14
89
-
103
18
twoway
twoway
twoway
twoway
twoway
twoway
twoway
no
sí
sí
no
sí
no
no
0
1
2
0
3
1
3
68
177
212
71
186
138
159
374
322
431
292
500
381
488
100
16
95
442
449
743
363
702
519
742
19
19
19
19
19
19
19
twoway
sí
1
209
846
-
1 055
22
twoway
twoway
no
no
5
7
250
248
626
657
-
876
905
20
19
C UADRO 8.2: Memoria requerida para varios prototipos (en bytes)
8.6.
Análisis de protocolos
En esta sección se analizan el formato y tamaño de los mensajes utilizados por DUO y
ASDF con el fin de demostrar su idoneidad para su implementación en picoObjetos.
8.6.1.
DUO
Los mensajes para las interfaces escalares son extremadamente regulares. Un mensaje
get() para cualquier módulo requiere únicamente 32 bytes más la identidad del objeto.
En una red SAN, con identidades de 4 bytes, supone mensajes de 38 bytes (identidad +
tamaño + categoría). Las respuestas a estos mensajes son siempre de 25 bytes más el
tamaño del valor de retorno: 26 para bool y byte, 27 para short, etc.
La interfaz DUO::Container maneja nombres de contenedores y proxies, por lo que el
tamaño de los mensajes puede ser muy variable. Por ejemplo, la operación link() para
enlazar un contenedor con un nombre de 4 letras y un proxy TCP requiere 92 bytes si se
utilizan identidades de 4 bytes. El mensaje más costoso es la respuesta al método list()
dado que devuelve una secuencia de proxies. Si éstos son TCP y tienen identidades de 4
bytes supone 48 bytes por cada uno. Es poco probable que un picoObjeto que actúe como
contenedor tenga muchos hijos, y debe tenerse en cuenta que prácticamente todo el proxy
es idéntico (solo cambia la identidad), de modo que para el picoObjeto el coste en memoria
es mucho menor, solo tiene que guardar las identidades y una plantilla de proxy.
La tabla 8.3 muestra el tamaño de los mensajes más importantes de DUO y también de
los mensajes de I CE requeridos para la operación de los servicios típicos. Se suponen
identidades de 4 bytes y proxies TCP.
i
i
i
i
i
i
i
i
8. P ROTOTIPOS
221
mensaje
tamaño (bytes)
Ice::Object::ice_ping
Ice::Object::ice_isA (request)
Ice::Object::ice_isA (reply)
IceStorm::TopicManager::create
IceStorm::Topic::subscribe
IceStorm::Topic::link
DUO::IByte::W::get (request)
DUO::IByte::W::get (reply)
DUO::IByte::W::set (request)
DUO::IByte::W::set (reply)
DUO::Container::list (request)
DUO::Container::list (reply)
DUO::Container::link
DUO::Container::create
DUO::Container::destroy
DUO::Active::getCb (request)
DUO::Active::getCb (reply)
DUO::Active::getTopic (request)
DUO::Active::getTopic (reply)
DUO::Active::setCbTopic
43
42 + Type ID
26
41 + nombre
91
91
38
26
39
25
39
25 + (n.o proxies × 48)
87 + nombre
41 + nombre
42
40
88
43
88
141 (ambos no nulos)
C UADRO 8.3: I CE y DUO: Tamaño de los mensajes
8.6.2.
ASDF
El listado 8.9 muestra el desglose del método adv() transportando un proxy con un
endpoint TCP convencional. El mensaje completo ocupa 95 bytes. El tamaño del mensaje
depende principalmente de dos cosas: la identidad del objeto anunciado («R309» en el
ejemplo) y el tipo de endpoint que utiliza el proxy (24 bytes en este caso). De modo que
el tamaño fijo mínimo del mensaje es de 49 bytes (usando IceStorm/ASDA.publish como
destino), a los que hay que sumar lo requerido por esos dos elementos.
Si se utilizan endpoints más simples, el tamaño puede verse sensiblemente reducido.
Por ejemplo, el endpoint XBow sólo ocupa 3 bytes frente a los 24 del endpoint TCP. En
una red SAN con identidades de 4 bytes, este mensaje ocuparía en torno a 55 bytes, lo
suficientemente pequeño para enviarse en un solo mensaje (128 bytes por defecto en el
protocolo XBow). Todo el contenido del mensaje es estático, a menos que se utilicen
direcciones lógicas dinámicas. Eso significa que puede ser almacenado en memoria ROM
del dispositivo, con la ventaja añadida de que varios fragmentos de este mensaje se pueden
utilizar también en otras invocaciones o en las respuestas.
Los dos únicos mensajes que deben implementar los picoObjetos son adv() de la
interfaz ASD::Listener (como cliente) y getp() de la interfaz ASD::PropHldr (como
servidor). Para éste último, el picoObjeto debe enviar respuestas, pero su formato y tamaño
son muy similares a los del adv() puesto que también implican el envío de un proxy.
i
i
i
i
i
i
i
i
222
8. P ROTOTIPOS
Internet Commu nication s Engine Protocol
Magic Number : ’I ’ , ’c ’ , ’e ’ , ’P ’
Protocol : 1 ,0 − Encoding : 1 ,0
Message Type : Request (0)
Compression Status : Uncompressed (0)
Message Size : 95
Request Message Body
Request Identifier : 1
Object Identity : IceStorm / ASDA . publish
Facet Name : ( empty )
Operation Name : adv − Ice :: OperationMode : idempotent (2)
Invocation Context : ( empty )
Input Parameters Size : 48 − Encoding : 1 ,0
Encapsulated parameters (42 bytes )
Object Identity : / R309
Facet Name : ( empty )
Mode : twoway (0)
Secure : False (0)
Endpoints (1)
Type : TCP (1 ,0)
Input Parameters Size : 30 − Encoding : 1 ,0
Encapsulation (24 bytes )
Host : 193.6 3.148. 188 (14 bytes )
Port : 37752 (4 bytes )
Timeout : Max (4 bytes )
Compress : False (0)
L ISTADO 8.9: Disección de un mensaje ASD::Listener::adv()
La tabla 8.4 muestra el tamaño del resto de los mensajes de ASDF para identidades de
4 bytes y endpoints TCP con direcciones de host de 15 bytes. El mensaje más caro
es lookup() ya que incorpora un conjunto de propiedades. Sin embargo, gracias a
la indirección que proporciona la interfaz ASD::PropHldr, estos mensajes nunca son
gestionados por los nodos de la SAN.
mensaje
ASD::Listener::adv
ASD::Listener::bye
ASD::Search::lookup
ASD::Search::discover
ASD::PropHldr::getp (request)
ASD::PropHldr::getp (reply)
tamaño (bytes)
80
43
83 + consulta
85
32
73
C UADRO 8.4: ASDF: Tamaño de los mensajes
8.7.
Prototipos IDM
Hemos realizado algunos prototipos iniciales para ilustrar las posibilidades y para evaluar
la sobrecarga al utilizar IDM. Se compara IDM con invocaciones I CE convencionales
y con sockets TCP y UDP tradicionales. Los prototipos utilizan el middleware ZeroC
i
i
i
i
i
i
i
i
8. P ROTOTIPOS
223
I CE (versión 3.3). Los siguientes datos se han obtenido en un computador compatible
IBM PC con procesador Intel Core2 Duo 2.33GHz, interfaz de red Ethernet 100 Mbps
con un sistema operativo Debian GNU/Linux. Los ejemplos están implementados en
C++ y compilados con GNU GCC 4.3.
Estas pruebas de latencia y transferencia están inspiradas en las que ZeroC facilita en
su página web [Zerb] así como en el código fuente utilizado para ellas.
F IGURA 8.14: Topología de red utilizada para las pruebas de rendimiento
La intención de estas pruebas es demostrar que la sobrecarga debida al uso de IDM
no implica una degradación significativa de las prestaciones. Además, debe tenerse muy
presente que se han empleado endpoints TCP y UDP para todas las conexiones. Cuando
estén disponibles endpoints más adecuados será posible mejorar en muchos casos las
prestaciones de I CE e, incluso, de la pila TCP/IP. Por ejemplo, si las restricciones de
la aplicación lo permiten se podrá enviar un flujo multimedia multicast dentro de una
LAN encapsulado directamente sobre tramas Ethernet, con el consiguiente ahorro de
cabeceras y sobrecarga debida al cálculo de CRC, etc.
El código fuente empleado para la realización de estas pruebas, la implementación
de referencia de nuestro prototipo actual y otra información relevante está disponible
para consulta en la página web de IDM [IDM].
8.7.1.
Latencia
Las pruebas de latencia miden el tiempo necesario para realizar una invocación a
un objeto remoto enviando una carga útil nula o muy pequeña. La tabla 8.5 muestra
los tiempos medios por invocación de una serie de 100 000 invocaciones del método
ice_ping(). Se trata del mensaje más simple que se puede implementar en I CE, no
tiene parámetros ni valor de retorno. Para la comparación con los sockets BSD, se
envían mensajes y respuestas de un byte. Se fuerza el envío de cada mensaje mediante
flush() para evitar que el socket pueda optimizar el envío de varios mensajes en un
solo segmento. Las invocaciones twoway requieren la recepción del mensaje de respuesta
antes de enviar la siguiente petición, mientras que las invocaciones oneway permiten
enviar el siguiente mensaje inmediatamente.
i
i
i
i
i
i
i
i
224
8. P ROTOTIPOS
invocación
(Twoway)
Local
Remoto (directo)
Remoto (1 salto IP)
Remoto (1 salto IDM)
(Oneway)
Local (oneway)
Remoto (directo)
Remoto (1 salto IDM)
socket
I CE
IDM
23
268
312
N/A
31
274
360
N/A
32
278
384
2 537
8
76
N/A
13
98
N/A
15
112
1 049
C UADRO 8.5: Pruebas de latencia de IDM (en µs)
8.7.2.
Rendimiento
Las pruebas de rendimiento (tasa de transferencia) tratan de medir la eficiencia del
protocolo enviando datos en crudo. La tabla 8.6 muestra los tiempos medios por invocación
de un conjunto de 1 000 mensajes twoway que transportan secuencias de 500 kB. Todas
las invocaciones son twoway.
invocación
Local
Remoto (direct)
Remoto (1 salto IDM)
Remoto (2 saltos IDM)
socket
I CE
IDM
292
42 394
N/A
N/A
365
43 051
N/A
N/A
485
43 276
98 291
101 265
C UADRO 8.6: Pruebas de rendimiento de IDM (en µs)
8.8.
Conclusiones
Los prototipos que se han descrito a lo largo de este capítulo demuestran la viabilidad
de nuestros planteamientos. Hemos implementado con éxito picoObjetos tanto en
plataformas comerciales como en dispositivos de diseño propio, utilizando varios lenguajes
de implementación, y con niveles de complejidad y prestaciones muy diferentes. Los
prototipos demuestran también la gran flexibilidad del modelo DUO, la interconexión
de actores por medio del cableado virtual y el protocolo ASDF, incluso con servicios
de una complejidad importante.
i
i
i
i
i
i
i
i
Conclusiones y trabajo futuro
9.1.
9.2.
9.3.
9.4.
9.5.
Infraestructura de integración
Un middleware para WSN
Resumen de contribuciones
Publicaciones
Nuevas líneas de trabajo
99
U
NA vez abordados todos los componentes de la infraestructura de integración
que nos planteábamos como objetivo, llega el momento de recapitular y analizar
las ventajas que se obtienen al fusionar las soluciones a los problemas parciales que
implica el uso de las redes de sensores bajo nuestro enfoque: el entorno inteligente
como un sistema distribuido heterogéneo.
Este capítulo comienza con la descripción de esa infraestructura, incluyendo un resumen
de los elementos que la forman, y para cada uno de ellos se destacan las contribuciones
concretas que aporta este trabajo. Por último, se plantean algunas líneas de trabajo que
se abren como consecuencia de dichas aportaciones, y se describen algunas aplicaciones
que pueden ser objeto de investigación en el futuro.
9.1.
Infraestructura de integración
El objetivo era la definición de una infraestructura completa, flexible y eficaz para
resolver la mayoría de los problemas que aparecen de forma recurrente en la integración de
redes SAN con una red troncal y/o entre redes SAN de distinta tecnología. Los principios
de diseño para la construcción de esa infraestructura han sido los siguientes:
Integración
Adaptar otros middlewares, dispositivos o sistemas, incluso cerrados, a nuestra
infraestructura.
Especialización sin pérdida de generalidad
Mediante la definición de interfaces adecuadas, abstrayendo las diferencias pero
exponiendo la funcionalidad al sistema.
225
i
i
i
i
i
i
i
i
226
9. C ONCLUSIONES Y TRABAJO FUTURO
Reutilización
Aprovechando cualquier trabajo previo disponible, ya sean dispositivos, protocolos,
drivers, etc.
Interoperabilidad a nivel de protocolo
Consiguiendo de ese modo un buen nivel de compatibilidad e interacción
transparente entre sistemas diferentes.
Nodos autónomos
La autonomía de los dispositivos es un aspecto clave para lograr tolerancia ante
fallos. Propiciar que la inteligencia del sistema esté distribuida en lugar de residir en
unos pocos componentes.
Orientación a objetos
El objeto es la unidad funcional básica para realizar cualquier tarea: todo es un objeto.
Ese principio permite encapsular la funcionalidad, delimitar las responsabilidades
sobre datos y procesos, y ocultar los detalles específicos.
La figura 9.1 muestra los elementos que forman la infraestructura resultante. Los
componentes relacionados con esta tesis (con fondo blanco) y su papel dentro de ella
se resumen en el resto de la sección. Otros componentes de la arquitectura tratan
aspectos como la gestión global de la Q O S o la composición automática de servicios,
y no han sido abordados. La arquitectura completa se denomina DOBS (Distributed
Object Based Services) [VVSL09] y su objetivo es proporcionar servicios avanzados
en entornos inteligentes.
F IGURA 9.1: Esquema general de la infraestructura de integración de redes SAN
9.1.1.
Middleware orientado a objetos
No proponemos un nuevo middleware; estamos convencidos que la cantidad y variedad
de MDOO de propósito general es suficiente para encontrar alguno que se adapte
razonablemente a la gran mayoría de las situaciones. Prácticamente todos los middlewares
que se han considerado en la sección 2.5 proponen planteamientos muy especializados
i
i
i
i
i
i
i
i
9. C ONCLUSIONES Y TRABAJO FUTURO
227
que implican el diseño de sistemas completamente nuevos. Sin embargo, en muchos casos
llegan a diseños con abstracciones muy similares a los MDOO clásicos. Nuestra estrategia
en este aspecto es más parecida a la de nORB [SXGC03].
Si bien es cierto que las redes SAN tienen características y necesidades especiales,
creemos que es mucho más conveniente emplear un MDOO convencional y añadir los
servicios y componentes necesarios para cubrir los casos de uso no considerados en éste
que realizar un nuevo diseño desde cero. Ello supone varias ventajas importantes:
Orientación a objetos
Un paradigma de programación ampliamente aceptado y que encaja perfectamente
en el diseño e implementación de sistemas distribuidos dotando de abstracciones
muy convenientes que permiten reducir el acoplamiento y aumentar la reutilización
por medio de interfaces bien definidas a nivel del sistema.
Heterogeneidad
Muchos de estos middlewares proporcionan bibliotecas o bindings para ser utilizados
desde varios lenguajes de programación y están diseñados de modo que es
relativamente sencillo adaptarlos a nuevas plataformas y sistemas operativos.
Independencia del transporte
Aunque no es una característica presente en todos los MDOO, la posibilidad de
abstraer la infraestructura de comunicaciones utilizada para el transporte de mensajes
inter-ORB resulta especialmente útil.
En cualquier caso, la necesidad de ese protocolo inter-ORB y una representación
de datos independiente ofrece una interfaz de bajo nivel para interaccionar con
el middleware, y esa es precisamente la característica que hace posible nuestros
picoObjetos.
Servicios comunes
Prácticamente todos los middlewares veteranos disponen de un rico conjunto
de servicios perfectamente integrados y probados. El desarrollo de cualquier
aplicación final se ve a menudo favorecido por el ahorro de esfuerzo que suponen
los mecanismos ya previstos por el fabricante del middleware.
Experiencia
Los principios de diseño en los que se basan los MDOO se vienen utilizando desde
hace tiempo para crear grandes aplicaciones. Han demostrado ser una buena solución
y adaptarse bien a los problemas que han ido apareciendo a lo largo de los años.
Consideramos de vital importancia aprovechar los diseños, desarrollos y experiencia
en torno a los sistemas previos. La inmensa cantidad de aplicaciones exitosas que
se han venido desarrollando durante más de una década avalan los middlewares de
propósito general, especialmente los MDOO.
Por ejemplo, CORBA cuenta con el consenso de cientos de las más importantes
empresas de la industria del software de todo el mundo.
En nuestra propuesta, el middleware es la piedra angular de la infraestructura, pero ésta es
lo suficientemente flexible como para adaptarse a middlewares considerablemente distintos
i
i
i
i
i
i
i
i
228
9. C ONCLUSIONES Y TRABAJO FUTURO
siempre que respeten en mayor o menor medida el concepto de objeto o servicio distribuido
y estén basados en el intercambio de mensajes o invocación de métodos remotos.
9.1.2. picoObjetos
Se han descrito y analizado las ventajas prácticas y metodológicas que implica la
construcción de objetos distribuidos empotrados con picoObjetos. Su utilización en las
redes SAN ofrece la oportunidad de que cualquier transductor pueda ser integrado en una
aplicación distribuida de forma completamente transparente, ocultando todos los detalles de
fabricación del dispositivo, su funcionamiento interno o, incluso, paliando sus limitaciones
funcionales cuando se requiera. Cada transductor es visto desde la red como un objeto
autónomo al que se le pueden solicitar servicios sin intermediarios.
Se han analizado en detalle las limitaciones y requisitos de interoperabilidad para dos
casos concretos: CORBA e I CE, y se incluye una descripción del juego de instrucciones
que permite describir máquinas de estados para reconocimiento y generación de mensajes
conforme a sus respectivos formatos de protocolo.
Se ha diseñado un lenguaje de alto nivel (IcePick) con el que es posible modelar
servicios como interacciones simples, pero no triviales, entre objetos de un nodo o
entre nodos diferentes, independientemente de si los objetos involucrados están o no
implementados como picoObjetos. La descripción de interacción entre objetos de diferentes
nodos permite, pero no limita, la definición de comportamiento global similar al que
ofrecen los sistemas de macro-programación.
El modelo de ejecución que se propone está basado en la utilización de una máquina
virtual y la generación de bytecode (aunque no se descarta la posibilidad de generar código
nativo). Se ha diseñado e implementado un compilador capaz de generar bytecode a
partir de una descripción en IcePick. Proporcionamos implementaciones de referencia
de la máquina virtual para un conjunto de plataformas lo suficientemente rico como para
demostrar su viabilidad sobre prácticamente cualquier dispositivo de cómputo empotrado
conectado a una red de datos. Se proporciona soporte al flujo de desarrollo completo
de aplicaciones distribuidas en las que haya involucrados transductores implementados
como picoObjetos. Este flujo abarca desde la especificación de las interfaces hasta
las fases de prueba e implantación.
El uso de bytecode hace posible plantear una solución general para despliegue y
actualización de aplicaciones en los picoObjetos por medio de picoGrid (véase § 4.9).
9.1.3.
Modelo de información
DUO define un conjunto de servicios rico y flexible, orientado a satisfacer las necesidades
funcionales de la mayoría de las aplicaciones que involucran redes SAN en entornos
inteligentes. Es lo suficientemente sencillo como para ser implementado sin problema en
dispositivos con capacidades muy reducidas, a la vez que es suficientemente potente como
para construir servicios complejos como es el caso de cámaras de vídeo motorizadas.
Proporciona utilidades para la creación y gestión dinámica de colecciones de objetos,
mecanismos de notificación asíncrona mediante objetos activos, agregación transparente,
activación condicional, etc.
i
i
i
i
i
i
i
i
9. C ONCLUSIONES Y TRABAJO FUTURO
229
Obviamente, su diseño está muy influenciado por las restricciones para las que están
diseñados los picoObjetos, pero sin que eso suponga sacrificar sus posibilidades en sistemas
o aplicaciones que no los requieren. Resulta muy útil para disponer de colecciones de
objetos con interfaces muy ortogonales y genéricas, que dan lugar a características tan
interesantes como el cableado virtual, que no serían posibles con interfaces especializadas.
Hace posible la instanciación de servicios reactivos sin más infraestructura que los propios
nodos y la necesaria red de comunicaciones.
9.1.4.
Descubrimiento de servicios
ASDF complementa el modelo de información de DUO aunque no depende de él.
Dota al sistema de mecanismos para la búsqueda y descubrimiento de servicios. De
nuevo, aunque se trata de un protocolo diseñado teniendo en cuenta las restricciones
de los picoObjetos, no supone una desventaja para su adopción en el sistema completo.
ASDF no es un SDP para la SAN sino para toda la red, para todos los servicios de la
aplicación, involucren o no a redes de sensores.
Su funcionamiento se fundamenta en una taxonomía de servicios y en la definición
de conjuntos de propiedades. La distribución de información se realiza por medio
de los canales de eventos proporcionados por el middleware, aunque dispone de una
gran diversidad de alternativas para disposiciones distribuidas, centralizadas o mixtas
en los mecanismos de anuncio, búsqueda y almacenamiento de las propiedades. Esto
lo dota de una gran flexibilidad que le permite adaptarse a las necesidades de casi
cualquier sistema.
También dispone de un servicio de metamodelo que permite a las aplicaciones explorar
programáticamente la descripción de los servicios de forma que, por ejemplo, un cliente
puede listar los tipos de servicio disponibles o las propiedades válidas en cada uno de
ellos —algo muy útil para la búsquedas— sin necesidad de conocimiento previo del
entorno o la aplicación concreta.
9.1.5.
Redes heterogéneas
La interconexión de la red SAN con la red troncal se realiza normalmente por
medio de estaciones base que operan como pasarelas de servicio. IDM propone una
solución alternativa para lograr encaminamiento independiente de la capa de red, su
tecnología o protocolos.
Esto es posible gracias a que los nodos de la red SAN (los picoObjetos) son autónomos
y no requieren entidades ajenas que los representen o que traduzcan su protocolo, como
suele ocurrir en la gran mayoría de las propuestas previas. Simplifica o soluciona muchos
de los problemas que implicaba el uso de pasarelas (véase § 2.6.2). Por ejemplo, hace
posible la creación de redes de sensores multisink.
IDM es un mecanismo universal de encaminamiento de mensajes. Aunque ha sido
diseñado para solventar los problemas de acceso a las SAN, se ha hecho un esfuerzo
considerable para que pueda aplicarse en cualquier circunstancia en la que se desee
comunicar entre sí nodos de redes incompatibles.
i
i
i
i
i
i
i
i
230
9. C ONCLUSIONES Y TRABAJO FUTURO
Incluye la definición del formato de los mensajes para el reenvío de invocaciones, la
descripción del procedimiento completo para la entrega al objeto remoto y la devolución
de la respuesta al cliente de forma transparente.
9.2.
Un middleware para WSN
Veamos a continuación en qué medida resuelve nuestra propuesta los problemas de los
middlewares para SAN identificados en la bibliografía. ROMER [RKM02] sugiere una
serie de requisitos que, en su experiencia, debería tener un middleware en el contexto
concreto de las WSN. Consideramos que es una buena referencia para medir algunos de
los logros conseguidos en esta tesis. Estas son las consideraciones más importantes:
«El pequeño tamaño de los nodos implica también recursos reducidos (capacidad de
cómputo, memoria, alcance y ancho de banda, etc.)».
Una implementación completa de un racimo de picoObjetos, incluyendo la
máquina virtual, ocupa una pequeña parte de la memoria disponible en la
mayor parte de los dispositivos utilizados en redes WSN, al menos un orden de
magnitud menos que cualquier sistema previo. Al ser una máquina dirigida por
eventos (event-driven), el consumo de CPU se produce únicamente cuando es
necesario. Los mensajes utilizados por las interfaces propuestas son pequeños
y se soportan protocolos asíncronos, y envío multicast cuando la tecnología
de red lo permite (habitual en redes wireless).
«La red WSN puede estar formada por una gran cantidad de nodos diferentes, en
términos de transductores utilizados, potencia de cómputo y memoria».
En relación a la ejecución de código, el uso de una máquina virtual abstrae las
peculiaridades de la arquitectura concreta de cada nodo.
En las comunicaciones, el protocolo de transporte inter-ORB homogeneiza la
invocación de cualquier servicio en cualquier nodo.
«Comunicación centrada en los datos (data-centric). Los nodos de la red son, por lo
general, meros productores o consumidores de datos. Eso mejora la robustez porque
desacopla el dato del sensor que lo produce».
Las interfaces DUO encajan perfectamente en este enfoque, pero además
permiten ver los transductores como objetos y proporcionan mecanismos para
crear colecciones, componentes e integración de servicios reactivos por medio
de cableado virtual.
Las interfaces DUO desacoplan el dato del transductor que lo produce, pero el
consumidor puede obtener la identidad del objeto responsable si lo necesita.
Eso permite implementar servicios de consulta masiva con una eficiencia
razonable.
«El middleware debe dar soporte al desarrollo, mantenimiento, despliegue de
aplicaciones».
i
i
i
i
i
i
i
i
9. C ONCLUSIONES Y TRABAJO FUTURO
231
Se proporciona un entorno de desarrollo completo (capítulo 6) que permite
el desarrollo de picoObjetos de un modo sencillo y que pueden ser probados
antes de su implantación, separando claramente los roles del personal
implicado en el desarrollo.
Servicios proporcionados por I CE, como IceGrid o IcePatch2 pueden resultar
muy útiles para tareas de mantenimiento y despliegue de aplicaciones. El
despliegue de aplicaciones en la SAN se aborda con picoGrid, con un
modelo de ejecución que encaja perfectamente con el funcionamiento de
los picoObjetos.
«debe proporcionar [...] mecanismos para especificar tareas de detección complejas,
coordinación de sensores para dividir la tarea y distribuirla a los nodos sensores
individuales, fusión y mezcla de los datos a partir de las lecturas individuales para
conseguir datos de más alto nivel...».
El lenguaje IcePick proporciona mecanismos básicos para especificar
relaciones no triviales entre objetos del mismo o distintos nodos, de forma
transparente.
Por medio de canales de eventos y utilizando los servicios que proporciona
ASDF es sencillo construir aplicaciones complejas: consultas selectivas,
búsquedas por servicio, gestión de propiedades, etc. Con todo ello se pueden
obtener datos de más alto nivel calculados a partir de las lecturas y teniendo
en cuenta el contexto en que se realiza.
Estos datos derivados se pueden ofrecer de nuevo a la red por medio de
sensores virtuales [RMDS02]. Por ejemplo, un objeto compuesto (véase § 3.6)
puede ofrecer la temperatura media de una habitación utilizando la misma
interfaz que los sensores reales que hay en la sala.
«El ámbito del middleware de la WSN no está restringido solo a la red, también debe
cubrir dispositivos y redes conectados a la WSN. El middleware para la red de sensores
debería proporcionar una visión holística de la WSN y las redes tradicionales, lo que
supone un desafío para el diseño arquitectural y la implementación».
Como se utiliza un middleware de propósito general, para la aplicación no hay
ninguna diferencia en el acceso a un objeto dentro de una WSN o de cualquier
otro dispositivo en cualquier red accesible.
Con IDM se intenta llevar esta transparencia un paso más allá, de modo
que se puedan encaminar eventos y peticiones a través de cualquier
red independientemente de su protocolo o tecnología de red. Bajo este
enfoque, todos los elementos son objetos distribuidos: nodos, transductores,
encaminadores, consumidores, etc.
Aunque ciertamente es un desafío, ya está parcialmente resuelto por los
middlewares de comunicaciones para sistemas distribuidos heterogéneos. La
necesidad aquí es adaptarlos a las características de las redes SAN, pero no es
necesario plantear un diseño arquitectural o la implementación de middlewares
completamente nuevos.
i
i
i
i
i
i
i
i
232
9. C ONCLUSIONES Y TRABAJO FUTURO
Éste es un aspecto muy importante que plantean también otros autores.
En [VHM+ 07, HMM+ ] se clasifican los middlewares dependiendo si se
aplican a la SAN, la pasarela o la red troncal (backend) concluyendo que lo
ideal sería un middleware para todo (end-to-end). Ese es precisamente nuestro
planteamiento inicial y creemos que se ha logrado en buena medida.
9.3.
Resumen de contribuciones
Según se desprende de las secciones anteriores esta tesis aporta las siguientes
contribuciones específicas:
Una infraestructura de integración que resuelve los problemas de las redes SAN en
un contexto heterogéneo de dispositivos, redes y servicios.
Un middleware construido sobre cualquier MDOO de propósito general que
aprovecha las ventajas de las soluciones estándar para computación distribuida
heterogénea.
Un conjunto de métodos, lenguajes, y herramientas de soporte para el desarrollo de
objetos distribuidos diminutos, como mínimo un orden de magnitud más pequeños
que las aproximaciones anteriores.
Un modelo de información rico y flexible orientado al diseño de aplicaciones
que involucran redes SAN. El modelo soporta una amplia variedad de modos de
interacción, jerarquía, agregación, activación condicional e introspección avanzada.
Un mecanismo de anunciamiento y descubrimiento de servicios que permite
integrar muy fácilmente redes heterogéneas e incluso islas gestionadas con SDP
incompatibles entre sí. El mecanismo se sustenta en una taxonomía que define
el conjunto de propiedades y un metamodelo que proporciona mecanismos de
introspección.
Un mecanismo de encaminamiento heterogéneo de mensajes, que resuelve problemas
de acceso a las SAN, pero que también puede ser usado para proporcionar calidad de
servicio, incrementar la tolerancia a fallos, proporcionar transparencia de migración,
etc.
Todas estas contribuciones responden al diseño de una plataforma unificada para la
construcción de aplicaciones, servicios e instalaciones que involucren a redes SAN, incluso
las que integran dispositivos de muy bajo coste. De esta forma se proporciona una solución
a la mayoría de los problemas identificados con anterioridad.
9.4.
Publicaciones
Derivados de los trabajos de esta tesis se han publicado algunos trabajos relevantes;
bien como consecuencia directa de las aportaciones, bien como trabajo conjunto con
otros miembros del grupo ARCO:
i
i
i
i
i
i
i
i
9. C ONCLUSIONES Y TRABAJO FUTURO
233
En [VML04] se plantea la posibilidad de generar autómatas reconocedores para mensajes
GIOP y de ese modo conseguir interoperabilidad básica con clientes CORBA. Se analiza en
detalle cómo salvar los problemas de interoperabilidad con el formato de los mensajes.
En [VVM+ 05a] se generaliza el planteamiento para dar cabida a cualquier protocolo
inter-ORB binario, dando detalles específicos tanto de CORBA como I CE. Por último,
en [VVM+ 06a] se aportan prototipos funcionales de picoCORBA para PC (en C y Java),
TINI y PIC12C509 (asm) y se comparan con prototipos de otros middlewares empotrados.
En [VVM+ 07b] se describen las ventajas que el flujo de diseño con picoObjetos aporta al
desarrollo de aplicaciones ubicuas y sus posibilidades de implementación mediante lógica
reconfigurable. En [MVV+ 09] planteamos una solución completa para el uso de MDOO
en redes de sensores incluyendo la posibilidad de implementar objetos distribuidos tanto
en microcontroladores de gama baja como en dispositivos FPGA.
También es destacable la solicitud de patente titulada «Método y dispositivo para
interconexión de equipos heterogéneos con recursos limitados por medio de middlewares
orientados a objeto» (Ref:200803715) que en estos momentos se encuentra pendiente
de aprobación.
En [VVM+ 05b, VVM+ 06b] se aborda el problema de la gestión de calidad de
servicio en redes móviles ad hoc (MANET) en el contexto de los entornos inteligentes.
En [VOV+ 06] se tratan los problemas de transmisión de flujos multimedia en este
tipo de redes.
El protocolo ASDF y sus características como SDP adecuado para redes de sensores
se discuten en [VVM+ 07a, VVM+ 08a]. Se analizan los casos de uso soportados y
los diferentes escenarios posibles que cubren la funcionalidad típica de los SDP S
más utilizados.
IDM y su aplicación para obtener acceso transparente a las redes de sensores se aborda
en [VVM+ 08b] explicando los problemas de interoperabilidad y robustez que implican las
pasarelas de servicios y cómo este enfoque ayuda a evitarlas. En [UVV+ 09] se aplican
estos principios a la comunicación con redes de vehículos submarinos.
Los métodos y herramientas desarrollados para la generación de picoObjetos tienen
también aplicación a middlewares no orientados a objeto, como es el caso de los Web
Services. En [VVM+ 09] se explora esta posibilidad de forma análoga a como se describe
en el anexo B. Se incide en los procesos necesarios para dotar de autonomía a los
nodos de una red de sensores que implementan por sí mismos todo lo necesario para
proporcionar un servicio extremo a extremo.
9.5.
Nuevas líneas de trabajo
El trabajo realizado proporciona nuevos enfoques para la resolución de problemas,
o bien para mejorar o simplificar otros ya resueltos. Algunos de ellos se describen
a continuación.
i
i
i
i
i
i
i
i
234
9. C ONCLUSIONES Y TRABAJO FUTURO
9.5.1.
Encaminamiento ad hoc con IDM
Si bien IDM se ha concebido como una solución de interconexión de redes heterogéneas,
se puede utilizar para conseguir encaminamiento en una red ad hoc (muy habitual en
redes SAN). En este caso, cada nodo de la red debe incluir un encaminador IDM y un
servicio que proporcione descubrimiento de vecinos mediante ALP. Este planteamiento
tiene varias ventajas:
El encaminamiento de invocaciones dentro y fuera de la red ad hoc es transparente.
Para los objetos del nodo no hay diferencia entre invocar un objeto en otro nodo de
la red ad hoc, la red troncal o una tercera red. Lo mismo puede aplicarse a un cliente
en la red troncal.
Es relativamente sencillo plantear soluciones de encaminamiento para redes híbridas.
En estos momentos ya estamos trabajando en un escenario en el que una red de PDA S
que forman una red ad hoc se comunica con redes de sensores y con una red troncal
estática en la que puede haber computadores portátiles. Las invocaciones desde
cualquier nodo, sea computador, PDA o nodo de la SAN pueden llegar a cualquier
otro dispositivo encaminándose a través de cualquiera de las tres redes de forma
transparente, gracias a IDM. El protocolo de encaminamiento (basado en AODV) se
implementa sobre IDM.
Es posible acceder fácil y remotamente a la información de encaminamiento dado
que los encaminadores IDM son objetos distribuidos. No se necesitan mecanismos
adicionales, el mismo middleware utilizado para acceder a los servicios se emplea
para transportar los mensajes del protocolo de encaminamiento y acceder a los
propios encaminadores.
Los encaminadores IDM se pueden implementar como picoObjetos. En ese caso,
las capacidades de los nodos deberían ser mayores que las consideradas para servir
transductores. El encaminador puede requerir una cantidad relativamente importante
de memoria RAM (en relación a los nodos sensores) para el mantenimiento de la
tabla de rutas y el estado del algoritmo de encaminamiento. Los 128 bytes de RAM
que eran suficientes para un picoObjeto resultan insuficientes en este caso. Incluso
requiriendo una plataforma de 16 bits, el tamaño de estos encaminadores podría ser
ostensiblemente menor que el de otras propuestas actuales y con la gran ventaja de
permitir encaminamiento transparente fuera de la red.
9.5.2.
Plataforma de gestión para redes heterogéneas
Siguiendo nuestro planteamiento habitual de que todo es un objeto, proponemos
el modelado de cualquier nodo de la red como un conjunto de objetos. No sólo sus
transductores; cada componente funcional del host puede ser representado como un objeto,
siguiendo un modelo de información similar a DUO. Por ejemplo, la memoria disponible,
la energía restante o el número de mensajes recibidos podrían obtenerse remotamente por
medio de invocaciones a métodos. No es una propuesta nueva. El modelo de información
de TMN (Telecommunications Management Network) [TMN01] no dista mucho de esta
idea. La ventaja aquí es que nuestra plataforma de gestión podría estar implementada
como picoObjetos (cuando las limitaciones lo requieran), aunque eso no debería impedir
su adaptación a cualquier otro nodo, incluso a PC S.
i
i
i
i
i
i
i
i
9. C ONCLUSIONES Y TRABAJO FUTURO
235
Una plataforma de este tipo sería muy útil para analizar y depurar algoritmos de
encaminamiento o protocolos de comunicaciones experimentales en redes de dispositivos
empotrados. Únicamente las variables a controlar serían realmente instaladas en el
dispositivo, y con la posibilidad de utilizar picoGrid para desplegar versiones nuevas
para cambiar el conjunto de variables accesibles.
9.5.3.
Plataforma de despliegue heterogéneo
En redes formadas por muy diversos dispositivos resultaría muy útil un servicio de
despliegue único que permita enviar actualizaciones de configuración y programas de forma
completamente independiente de la tecnología del nodo y de la red a la que esté conectado.
La solución pasaría por integrar un servicio de despliegue para nodos convencionales
(como IceGrid) junto con picoGrid, empleando IDM como medio de comunicación para
homogeneizar el acceso a cualquier dispositivo.
9.5.4.
Modelado semántico de servicios
Nuestra experiencia en el uso del protocolo de búsqueda de servicios que proporciona
ASDF ha puesto en evidencia algunos problemas principalmente en cuanto a flexibilidad. El
más grave es que al emplear una taxonomía como diccionario de servicios, las posibilidades
de incluir nuevos tipos de servicios en un sistema en operación son muy limitadas. Esto
normalmente no es un problema si todos los servicios están definidos en la fase de
diseño, pero sí puede serlo en otro caso.
Se propone la definición de un modelo semántico, expresado mediante una ontología y
descrito mediante un lenguaje formal, que permite a servicios y dispositivos definir nuevas
instancias en contextos específicos. De este modo, cuando un cliente necesita un servicio
envía una consulta que especifica un conjunto de enunciados que se deben cumplir, por
ejemplo «captar imagen» y se puede acompañar de propiedades como la ubicación o la
disponibilidad. El diccionario de verbos (captar) y objetos (imagen) puede estar disponible
a través de un servicio específico. Las descripciones de los servicios y el vocabulario
pueden cambiar incluso en un sistema en funcionamiento.
Realmente no implica grandes cambios respecto a las propuestas realizadas en esta
tesis. Seguimos teniendo propiedades tal como se han implementado en ASDF, un servicio
de metamodelo para servir los vocabularios y las relaciones (MIS) y una descripción
del servicio alojada en cada actor. Solo el método ASD::Search::lookup() necesita
ser modificado para incluir una descripción de servicio más compleja, en lugar de
simplemente una interfaz y un conjunto de propiedades. El resto del protocolo ASDF
funcionaría tal como se ha explicado, pero la flexibilidad, riqueza y precisión de las
búsquedas aumentaría sensiblemente.
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
ANEXOS
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
Repertorio de instrucciones FSM
A
A
A continuación se detalla la finalidad y forma de uso de todas las instrucciones
disponibles en el lenguaje FSM:
nop()
No ejecuta nada, sirve únicamente como relleno para el alineamiento de las páginas
de bytecode (véase § 4.6.1).
ejemplo:
bytecode:
nop()
NOP
reset()
Inicializa el contexto de ejecución según los valores por defecto y salta al manejador
del evento RESET que normalmente es una función principal indicada en el bloque
de inicialización de la máquina.
ejemplo:
bytecode:
reset()
RESET
goto(block)
Salta a la dirección de comienzo del bloque block.
ejemplo:
bytecode:
goto(‘reply’)
GOTO ADDR
goto_nz(block)
Salta a la dirección de comienzo del bloque block si el registro de trabajo contiene
un valor distinto de cero.
ejemplo:
bytecode:
goto_nz(‘put_iface’)
GOTO_NZ ADDR
239
i
i
i
i
i
i
i
i
240
A. R EPERTORIO DE INSTRUCCIONES FSM
goto_eq(block, reg)
Salta a la dirección de comienzo del bloque block si el registro de trabajo y el registro
reg contienen el mismo valor.
ejemplo:
bytecode:
goto_eq(‘put_iface’, 8)
GOTO_EQ ADDR REG
goto_neq(block, reg)
Salta a la dirección de comienzo del bloque block si el registro de trabajo y el registro
reg contienen valores diferentes.
ejemplo:
bytecode:
goto_neq(‘put_iface’, 8)
GOTO_NEQ ADDR REG
call(block)
Almacena la dirección de la siguiente instrucción en el puntero de retorno y después
salta a la dirección de comienzo del bloque block.
ejemplo:
bytecode:
call(‘reply_header’)
CALL ADDR
ret()
Salta a la dirección almacenada en el puntero de retorno y después pone su contenido
a cero (dirección nula). Si al ejecutarse la instrucción ret() el puntero de retorno
ya contiene la dirección nula, la instrucción termina sin realizar ninguna acción. Esto
permite que un mismo bloque se pueda utilizar como subrutina y también como
destino de salto convencional.
ejemplo:
bytecode:
ret()
RET
set_event(block, event)
Instala el bloque block como manejador para el evento event. La próxima vez que se
ejecute la instrucción reset() saltará a la dirección de comienzo del bloque block
si se ha producido el evento event durante ese lapso.
Si se requiere desactivar un evento pendiente se debe invocar set_event(0,
event). Indica que dicho evento tiene asignado el manejador nulo y, por tanto,
no se ejecutará ninguna acción cuando el evento se produzca.
ejemplo:
bytecode:
set_event(‘main’, INCOMING_EVENT)
SET_EVENT ADDR EVENT
skip()
Lee y descarta un byte de la entrada.
ejemplo:
bytecode:
skip()
SKIP
skip_mod_4()
Lee y descarta de 1 a 4 bytes para conservar el alineamiento de 4 bytes para el
siguiente dato.
ejemplo:
bytecode:
skip_mod_4()
SKIP_MOD_4
i
i
i
i
i
i
i
i
A. R EPERTORIO DE INSTRUCCIONES FSM
241
get_w()
Lee un byte de la entrada y lo almacena en el registro de trabajo.
ejemplo:
bytecode:
get_w()
GET_W
get_reg(reg, offset)
Lee un byte de la entrada, le suma offset y lo almacena en el registro reg.
ejemplo:
bytecode:
get_reg(8, -10)
GET_REG REG OFFSET
get_str(reg, max)
Copia el valor del registro de trabajo en el registro reg. A continuación lee tantos
bytes como indique dicho valor y los almacena a partir del registro reg+1.
Para evitar desbordamiento del espacio reservado, la instrucción get_str()
comprueba que el tamaño indicado en el registro de trabajo es menor o igual al
parámetro max. En caso contrario, salta a la dirección de comienzo del bloque
definido como manejador del evento ERROR.
ejemplo:
bytecode:
get_str(8)
GET_STR REG
get_flash(reg, max)
Igual que la anterior salvo que escribe el resultado en la zona Flash en lugar de en el
banco de registros.
assure(byte seq)
En tiempo de compilación, la instrucción assure() obtiene el tamaño (t) y la
suma de comprobación (c) de la secuencia de bytes indicada como parámetro. Esos
valores son los que se generan como argumentos en el bytecode. Cuando se ejecuta
la instrucción, la máquina consume de la entrada t bytes y al terminar comprueba
que el valor del checksum de los bytes leídos corresponde con c.
Si el checksum no corresponde, salta al manejador asociado al evento ERROR.
ejemplo:
bytecode:
assure(‘IceP’,1,0,1,0)
ASSURE SIZE DIGEST
test_digest()
Consume tantos bytes como indique el registro de trabajo, calcula un checksum
sobre ellos y deja el resultado en el registro de trabajo.
ejemplo:
bytecode:
test_digest()
TEST_DIGEST
put_val(value)
Escribe a la salida el dato inmediato value.
ejemplo:
bytecode:
put_val(2)
PUT_VAL VALUE
put_reg(reg)
Escribe a la salida el contenido del registro reg.
i
i
i
i
i
i
i
i
242
A. R EPERTORIO DE INSTRUCCIONES FSM
ejemplo:
bytecode:
put_reg(8)
PUT_REG REG
put_str(reg)
El registro reg indica cuántos registros a partir de él deben escribirse en la salida. La
cantidad propiamente dicha no se escribe.
ejemplo:
bytecode:
put_str(12)
PUT_STR REG
put_data(addr)
Escribe en la salida datos desde la zona DATA. La dirección addr indica cuántos
bytes a partir de la dirección addr deben escribirse. La cantidad propiamente dicha
no se escribe.
ejemplo:
bytecode:
put_data(IceHeader)
PUT_DATA ADDR
put_flash(addr)
Igual que la anterior salvo que lee los datos de la zona Flash.
template(addr, offset)
Igual que la instrucción put_data(), pero suma al byte que ocupa la posición offset
el valor almacenado en el registro de trabajo.
ejemplo:
bytecode:
template(IceHeader, 3)
TEMPLATE ADDR OFFSET
set_w(value)
Almacena el valor value en el registro de trabajo.
ejemplo:
bytecode:
set_w(4)
SET_W VALUE
move(dst, src)
Copia el contenido del registo src al registro dst.
ejemplo:
bytecode:
move(4, 0)
MOVE REG REG
set_val(reg, value)
Almacena el dato inmediato value en el registro reg.
ejemplo:
bytecode:
set_reg(8, 0)
SET_REG REG VALUE
add(reg, value)
Suma el dato inmediato value al valor que contiene el registro reg. El resultado
queda en reg.
ejemplo:
bytecode:
add(8, 2)
ADD REG VALUE
i
i
i
i
i
i
i
i
A. R EPERTORIO DE INSTRUCCIONES FSM
243
set_timer(interval)
Inicializa el timer para que genere el evento TIMEOUT con un intervalo de repetición
determinado por interval.
El timer puede ser desactivado con la instrucción set_timer(0).
ejemplo:
bytecode:
set_timer(5)
SET_TIMER VALUE
cmp(reg)
Si el contenido del registro de trabajo es mayor que el de reg el resultado es 1, si
es menor el resultado es 2 y si son iguales el resultado es 0. El valor del resultado
queda almacenado en el registro de trabajo.
ejemplo:
bytecode:
cmp(5)
CMP VALUE
connect_data(addr)
Inicia una conexión activa. A partir de ese momento y hasta que se ejecute la
instrucción close(), la salida generada se enviará a través de esa conexión. La
información necesaria para realizar la conexión se encuentra en la zona DATA a partir
de la dirección addr. Utiliza la misma configuración que la instrucción put_data().
La información almacenada tiene distinto formato dependiendo del tipo de conector
que se utilice. En el caso de TCP o UDP se trata de una dirección IP y un puerto.
ejemplo:
bytecode:
connect(socket)
CONNECT ADDR
connect_flash(addr)
Igual que la anterior salvo que lee los datos de conexión a partir de la zona Flash.
close()
Cierra la conexión actual, sea activa o pasiva.
ejemplo:
bytecode:
close()
CLOSE
raise_event(event)
Marca el evento event para su ejecución.
ejemplo:
bytecode:
raise_event(PRESENCE_EVENT)
RAISE_EVENT VALUE
user_proc(n)
Ejecuta el procedimiento de usuario que corresponde al código n.
ejemplo:
bytecode:
user_proc(PROC_SET)
USER_PROC VALUE
debug(msg)
Permite almacenar un mensaje de texto a efectos de depuración. El texto se imprimirá
en la salida de error en el momento de su ejecución. Depende de la implementación
concreta de la máquina virtual proporcionar o no soporte a esta instrucción.
ejemplo:
bytecode:
debug(‘Evento Enviado’)
DEBUG ADDR
i
i
i
i
i
i
i
i
244
A. R EPERTORIO DE INSTRUCCIONES FSM
mnemotécnico
tamaño (bytes)
nop
reset
goto
goto_nz
goto_eq
goto_neq
call
ret
set_event
skip
skip_mod_4
get_w
get_reg
get_str
get_flash
assure
test_digest
put_val
1
1
2/3
2/3
3/4
3/4
2/3
1
3/4
1
1
1
3
3
3
3
1
2
mnemotécnico
put_reg
put_str
put_data
put_flash
template
set_w
move
set_val
add
set_timer
cmp
connect_data
connect_flash
close
raise_event
user_proc
debug
tamaño (bytes)
2
2
2
2
3
2
3
3
3
2
2
2
2
1
2
2
2
C UADRO A.1: FSM: Resumen del juego de instrucciones. En el tamaño, la barra indica
salto corto/largo
i
i
i
i
i
i
i
i
Servicios Web empotrados
B.1.
B.2.
B.3.
B.4.
B.5.
B.6.
Introducción
Servicios Web en la SAN
Un enfoque ascendente
Arquitectura de red
Prototipos EWS
Conclusiones
B
B
Los denominados Servicios Web (en adelante WS) han tenido un gran auge en los
últimos años gracias en buena parte al apoyo de la industria. Aunque siguen sufriendo
grandes carencias y desventajas respecto a los MDOO tradicionales [dJ02, GKS02, Hen09],
su relevancia en la comunidad investigadora y en el desarrollo profesional de sistemas
distribuidos no puede ser ignorada.
Los protocolos binarios como GIOP o I CE P, habituales en los MDOO, permiten
aprovechar al máximo las posibilidades de los picoObjetos puesto que los mensajes
requeridos son mucho más pequeños y regulares que sus equivalentes funcionales
en protocolos como XML-RPC o SOAP (Simple Object Access Protocol), basados
en XML.
A pesar de que consideramos que los protocolos basados en XML son mucho más
ineficientes que sus equivalentes binarios en términos de memoria, energía y ancho de
banda, en este capítulo se introduce un mecanismo para conseguir implementaciones
de WS aptas para dispositivos empotrados, con niveles de autonomía equiparables a los
que exigimos a los picoObjetos, aunque obviamente con requerimientos de memoria
mayores que aquellos.
Nuestra intención con esta propuesta es proporcionar una alternativa viable para la
construcción de WS autónomos empotrados, cuando las necesidades concretas de la
aplicación lo impongan ya sea como medio para la integración con un sistema existente
o como requisito del cliente. En otro caso, aconsejamos utilizar un middleware basado
en un protocolo binario, especialmente en el caso de nodos de una red SAN, ya que ello
permite la utilización de picoObjetos, más eficientes, con menos consumo y adecuados
para dispositivos más sencillos. A los servicios web implementados con las directrices que
se explican a continuación los denominamos EWS (Embedded Web Services).
245
i
i
i
i
i
i
i
i
246
B. S ERVICIOS W EB EMPOTRADOS
Como en el caso de los picoObjetos, los EWS consiguen un alto grado de
interoperabilidad con sistemas basados en XML-RPC o SOAP con el único requisito
de pasarelas sencillas, sin necesidad de delegados como entidades software residentes
en ellas.
B.1.
Introducción
Aunque es posible conseguir interoperabilidad a nivel de red mediante implementaciones reducidas de TCP/IP, en la capa de aplicación todavía puede ser un grave problema [PKGZ08]. Los WS aparecen como una solución interoperable, independiente del
lenguaje y la plataforma para acceder a los servicios de una red SAN a través de Internet.
Ello puede implicar una serie de interesantes ventajas que veremos a continuación.
El uso de un protocolo como SOAP [GHM+ 03] dentro de una red SAN introduce una
sobrecarga importante comparado con los protocolos binarios. Sin embargo, en algunos
escenarios en los que el consumo de energía o el ancho de banda no son aspectos críticos
puede ser admisible. En este caso, supondremos una instalación de control y diagnóstico
para luces de emergencia en grandes edificios. En este escenario:
Los nodos no tienen problemas de energía porque están conectados a la red eléctrica.
Los nodos no se mueven.
Utilizan comunicaciones inalámbricas para no depender de infraestructuras de
comunicaciones ajenas al sistema. Esta red tiene poco tráfico, se utiliza únicamente
para proporcionar acceso al diagnóstico de los nodos. Como ésta es una tarea
planificada no es previsible que se produzca congestión ni grandes requerimientos
de ancho de banda.
El procedimiento de configuración debería ser lo más simple posible para reducir el
coste de la instalación. En principio será posible una configuración remota como un
servicio para todo el sistema.
En este caso, o cualquier otro con características similares, los WS pueden ser una
buena alternativa como solución al problema para proporcionar interoperabilidad en la
capa de aplicación con sistemas externos preexistentes.
B.2.
Servicios Web en la SAN
La mayoría de las propuestas previas toman datos directamente de la WSN usando
protocolos propietarios y los exportan a través de WS residentes en la pasarela [KBL07,
arc07]. El WS reside realmente en la pasarela y no en los nodos sensores. Cada nueva
aplicación suele requerir nuevos desarrollos, y cada WS se convierte en un adaptador
o envoltorio para un protocolo binario usado en la SAN.
Nuestro enfoque pretende utilizar pasarelas genéricas (independientes de los dispositivos
concretos que forman la red de sensores) reduciendo todo lo posible los procedimientos
de configuración para conseguir que la información de los nodos esté accesible como WS.
i
i
i
i
i
i
i
i
B. S ERVICIOS W EB EMPOTRADOS
247
La intención (como en ocasiones anteriores) es eliminar la necesidad de intermediarios a
nivel de aplicación tal como el Sensor Collection Service descrito en [KBL07].
En [AYS07] se presenta un entorno para dar soporte al uso de SOAP en las WSN
con especial énfasis en la reducción de la sobrecarga (p.ej. reduciendo el número
de mensajes) utilizando técnicas de agregación de datos. Su implementación se ha
probado en el simulador NS2, pero no se aporta información sobre una implementación
en dispositivos reales.
Otras propuestas [HX05] intentan empotrar la arquitectura de WS en dispositivos de
bajo coste reduciendo el tamaño de la pila de protocolos (TCP/IP, XML, SOAP, etc.).
Esos dispositivos de bajo coste exceden, sin embargo, la capacidad media de la mayoría
de las plataformas para redes de sensores inalámbricas.
EWS propone una forma diferente de empotrar servicios web mínimos en dispositivos
WSN siguiendo un enfoque muy similar a los picoObjetos. En lugar de reducir el tamaño
de implementaciones existentes de la pila de protocolos empleada en WS, definiremos
el conjunto mínimo de prestaciones que necesita proporcionar un WS para que pueda
seguir considerándose como tal, y partiremos de ese punto para añadir funcionalidad
adicional cuando se requiera y sea posible.
B.3.
Un enfoque ascendente
Aunque es importante que cada dispositivo se comporte como un WS, no es
imprescindible la existencia de una implementación completa de TCP/IP, un servidor
web o un reconocedor de XML. Si al recibir peticiones predefinidas, los dispositivos
son capaces de generar respuestas coherentes el sistema puede funcionar tal como se
espera. Para una especificación Web Services Definition Language (WSDL) [Win01]
dada, los mensajes de petición y respuesta están perfectamente definidos por el protocolo
de transporte elegido (SOAP o XML-RPC).
Veamos una petición SOAP encapsulada en un mensaje HTTP (listado B.1) y su
correspondiente respuesta para un protocolo de interacción muy simple similar a DUO:
leer el estado de una luz de emergencia. Se muestran mensajes SOAP completos, a fin de
que el comportamiento descrito en la figura B.1 resulte más fácil de comprender.
POST / HTTP /1.0
Host: loc alhost:8 080
User−agent: SOAPpy 0.12.0
Content−type: text / xml ; charset = " UTF −8"
Content−length: 336
SOAPAction: " get "
<?xml version= " 1.0 " encoding = " UTF−8" ? >
< SOAP−ENV:Envelope
SOAP−E N V : e n c o d i n g S t y l e = " http: // schemas . xmlsoap . org / soap / encoding / "
xmlns:SOAP−ENC = " http: // schemas . xmlsoap . org / soap / encoding / "
xmlns:SOAP−ENV = " http: // schemas . xmlsoap . org / soap / envelope / " >
< SOAP−ENV:Body >
< get SOAP−ENC:root = " 1 " >
</ get >
i
i
i
i
i
i
i
i
248
B. S ERVICIOS W EB EMPOTRADOS
</ SOAP−ENV:Body >
</ SOAP−ENV:Envelope >
L ISTADO B.1: Ejemplo de petición SOAP
Es fácil comprobar que SOAP resulta un protocolo bastante verboso en el que la mayoría
de la información útil se encuentra en el elemento Body. Este mensaje se puede obtener
a partir de la especificación WSDL del listado B.2.
[...]
< message name = " getRequest " >
</ message >
< message name = " getResponse " >
< part name = " retval " type = " xs:boolean " / >
</ message >
[...]
< operation name = " get " >
< input message = " getRequest " / >
< output message = " getResponse " / >
</ operation >
[...]
L ISTADO B.2: Especificación WSDL para el ejemplo descrito
Podemos implementar un reconocedor ad hoc tomando la especificación WSDL como
punto de partida. Este reconocedor puede construir la respuesta adecuada a partir de
plantillas (listado B.3). Puede verse fácilmente la equivalencia con las propuestas realizadas
para los picoObjetos en el capítulo 4 si bien es necesario puntualizar algunas diferencias
que se verán a continuación.
HTTP /1.0 200 OK
Content−type: text / xml ; charset = " UTF −8"
Content−length: 501
<?xml version= " 1.0 " encoding = " UTF−8" ? >
< SOAP−ENV:Envelope
SOAP−E N V : e n c o d i n g S t y l e = " http: // schemas . xmlsoap . org / soap / encoding / "
xmlns:SOAP−ENC = " http: // schemas . xmlsoap . org / soap / encoding / "
xmlns:xsi = " http: // www . w3 . org /1999/ XMLSchema−instance "
xmlns:SOAP−ENV = " http: // schemas . xmlsoap . org / soap / envelope / "
xmlns:xsd = " http: // www . w3 . org /1999/ XMLSchema " >
< SOAP−ENV:Body >
< getResponse SOAP−ENC:root = " 1 " >
< Result xsi:type = " xsd:boolean " > False </ Result >
</ getResponse >
</ SOAP−ENV:Body >
</ SOAP−ENV:Envelope >
L ISTADO B.3: Respuesta SOAP sintetizada
Como en los capítulos precedentes, nuestro objetivo sigue siendo cubrir la funcionalidad
de los transductores más habituales en las redes SAN y por esa razón planteamos un
i
i
i
i
i
i
i
i
B. S ERVICIOS W EB EMPOTRADOS
249
conjunto de interfaces WSDL similar a DUO siguiendo el mismo diseño data-centric.
Por supuesto, ésta es una estrategia para maximizar las posibilidades de implementación
en dispositivos con graves limitaciones de memoria, pero como en aquel caso, no se
trata de una restricción y es posible utilizar interfaces más complejas, asumiendo el
coste correspondiente.
El objetivo es minimizar la cantidad de memoria requerida para reconocer el conjunto
de los posibles mensajes de entrada. Para conseguirlo, se emplean varias técnicas:
Se genera una máquina de estados para reconocer una petición y construir una
respuesta. El reconocedor ignora varios elementos sintácticos irrelevantes, como los
espacios en blanco, saltos de línea, comentarios XML, etc.
Nunca se almacenan ni comparan las etiquetas XML. En lugar de eso, se calculan
checksums según el algoritmo CCITT-CRC 16 bits. El reconocedor únicamente
compara resultados del CRC obtenidos a partir del mensaje con los almacenados en
el dispositivo. Éstos fueron precalculados en tiempo de generación del autómata.
Nunca se almacenan mensajes completos. Cada mensaje es analizado de forma
incremental tal como se recibe, de manera similar a como haría un reconocedor
SAX (Simple API for XML).
Como ejemplo, para el mensaje de petición del listado B.1, se genera una máquina
de estados similar a la de la figura B.1. Se calcula un CRC para cada etiqueta XML
(delimitadas por ‘<>’). Desde el estado init se reconoce la entrada ignorando la cabecera
HTML. Esa cabecera no incluye información relevante desde el punto de vista de
los nodos de la SAN.
El reconocedor ignora todos los datos de entrada hasta la llegada de la etiqueta <?xml
... ?>. Cuando ha llegado completamente se comprueba el checksum almacenado y se
produce la transición al estado Start que decidirá entre los posibles mensajes de entrada.
La entrada incluye algunas etiquetas de codificación seguidas de la operación que se desea
invocar (get o set en el ejemplo). Dependiendo del CRC obtenido en las posiciones
esperadas del flujo de entrada la transición lleva al estado en el que se leen los argumentos
de la operación. Esas posiciones quedan definidas por el punto del flujo en el que aparece
alguno de los caracteres ‘<>’. Las operaciones sin argumentos de entrada implican una
transición directa al estado Tail. En este estado se valida el resto del mensaje de petición
y se invoca el procedimiento de usuario correspondiente (el sirviente).
Las operaciones con parámetros de entrada pasan por estados intermedios. Para el
ejemplo, el estado Req Set reconoce y almacena temporalmente los parámetros asociados
a la operación set antes de disparar la transición al estado Tail. Por último, después de
comprobar la validez del resto del mensaje, se genera el mensaje de respuesta. Nótese que
no es necesario almacenar nada del método invocado puesto que la cola de cada petición
es diferente y se puede utilizar para discriminar entre los generadores de respuestas.
En cada estado de generación de respuestas (Resp Set y Resp Get en el ejemplo), el
usuario debe proporcionar una rutina que se ejecuta como consecuencia del mensaje
reconocido y genera la respuesta apropiada.
Aunque por legibilidad no se indica explícitamente en la figura B.1, cuando alguna
etiqueta de entrada no corresponde con el checksum previsto, la máquina de estados
i
i
i
i
i
i
i
i
250
B. S ERVICIOS W EB EMPOTRADOS
F IGURA B.1: Máquina de estados simplificada para los mensajes SOAP get y set
retorna al estado inicial y cierra la conexión. Eso proporciona una protección sencilla
pero razonable contra clientes defectuosos.
B.3.1.
Compilación
Por los mismos motivos que se explicaban en el capítulo 6, se hace necesaria una forma
sencilla de especificar las interfaces que implementa cada servicio, para que un compilador
pueda generar el código del autómata. Para ello creamos un frontend de WSDL para el
compilador ipkc, tal como estaba previsto en su diseño (véase § 6.3).
La máquina de estados es un programa completo generado ad hoc. No se utiliza
FSM puesto que los requisitos de memoria en este caso superan las posibilidades de
direccionamiento de la ISA. En cualquier caso, la posibilidad de utilizar el mismo modelo
de ejecución basado en máquina virtual que se propone para los picoObjetos resulta
interesante también aquí. Para lograrlo se propone la utilización de una versión de FSM de
16 bits y algunas instrucciones adicionales para manejar secuencias de bytes delimitadas por
banderas en lugar de por tamaños (que es lo habitual en los protocolos inter-ORB binarios).
Por lo demás, no habría grandes diferencias en el funcionamiento de un reconocedor de
mensajes SOAP respecto al que se propone para I CE P o GIOP.
En este caso, las entradas para el compilador son:
La especificación de la interfaz del servicio en formato WSDL. Los servicios
proporcionados por el nodo deben estar descritos en este fichero.
La implementación del sirviente, es decir, las porciones de código que realmente
realizan operaciones sobre el hardware del nodo. Idealmente pueden ser drivers
(véase § 6.4).
La definición del servicio. El programador debe indicar qué servicios están
disponibles en el nodo y las interfaces (portType) que expondrá cada transductor.
i
i
i
i
i
i
i
i
B. S ERVICIOS W EB EMPOTRADOS
251
Este fichero utiliza el lenguaje IcePick (véase § 6.1). El listado B.4 muestra un
ejemplo sencillo en el que se definen dos WS: uno local y otro remoto. Indica
también la ejecución de una invocación periódica en la que se envía el estado y el
endpoint del servicio.
La especificación de la interfaz del sirviente proporcionado por el programador. Se
utiliza para ello el mismo lenguaje SIS que se introdujo en la sección 6.2.
uses " DUORW . wsdl ";
object D U O I B o o l R W _ S e r v i c e svc1 ;
local adapter myLocalEP {
endpoint = " 1 2 0 . 3 0 . 4 0 . 1 0 : 8 0 6 0 " ;
objects = { svc1 };
};
object D U O I B o o l R W _ S e r v i c e svc2 ;
remote myRemoteEP {
endpoint = " 1 2 0 . 3 0 . 4 0 . 1 0 : 8 0 7 0 " ;
objects = { svc2 };
};
timer (5) {
svc2 . set ( svc1 . status () , svc1 .endpoint) ;
}
L ISTADO B.4: Ejemplo de IcePick para un WS
El compilador puede generar implementaciones de la máquina de estados para varias
plataformas por medio de backends. Se ofrece soporte para motas MICA2 e IRIS con
TinyOS, y para microcontroladores ATmega128 y 8051 sin sistema operativo.
B.4.
Arquitectura de red
En nuestro caso de ejemplo, un centro de control externo gestiona y monitoriza edificios
distribuidos en una gran extensión geográfica (varias ciudades). Son frecuentes edificios
con cientos o incluso miles de luces de emergencia (aeropuertos, museos, estaciones,
etc.). Cada instalación está conectada a una red externa común (p.ej. Internet) por medio
de una o varias pasarelas (figura B.2).
Cada pasarela realiza las siguientes tareas:
Extrae mensajes SOAP desde el protocolo de transporte de la red externa (TCP en
el ejemplo) y los encapsula en mensajes del protocolo de la red SAN, que no tiene
porqué estar basado en TCP/IP. Y realiza el proceso inverso para los mensajes SOAP
salientes. Esta tarea se ilustra en la figura B.3.
Debe implementar un mecanismo de correspondencia unívoca bidireccional entre
direcciones de transporte (puerto TCP) y el identificador de cada nodo. Éste es un
aspecto crucial porque evita la necesidad de un procedimiento de configuración
i
i
i
i
i
i
i
i
252
B. S ERVICIOS W EB EMPOTRADOS
F IGURA B.2: Topología de red para la gestión de luces de emergencia
manual. Cuando se instala un nodo nuevo, la pasarela asigna un puerto TCP para
cada identificador de nodo.
Una consecuencia destacable es que este tipo de pasarelas no tiene ningún conocimiento
previo de la red, no están ligadas a una aplicación concreta y, lo más importante, no
realiza traducción de protocolos sino encapsulación. Esto implica además que puede
haber varias pasarelas dando acceso a la misma red SAN puesto que no tienen estado. Lo
único a tener en cuenta en ese caso es que la dirección del nodo será con toda seguridad
diferente dependiendo de la pasarela que se utilice para contactar con el nodo. Eso puede
solventarse con un algoritmo que garantice que dado un identificador de nodo se asocia
siempre a la misma dirección externa. Por ejemplo, si utilizamos las direcciones de nodo
de una red con protocolo XB OW, es posible hacer un mapping directo entre identificadores
de nodo y puertos TCP puesto que ambos son números de 16 bits, y raramente una
única SAN necesitará más de 216 nodos.
La asociación establecida entre el puerto TCP y el identificador del nodo debe estar
representada en el fichero WSDL. El fichero representa la interfaz del servicio para
los usuarios y también sus propiedades, por ejemplo la localización (el endpoint). Los
dos datos quedan plasmados en la etiqueta soap:address del fichero WSDL, tal como
se muestra en el listado B.5. La pasarela necesita conocer los identificadores de nodo
i
i
i
i
i
i
i
i
B. S ERVICIOS W EB EMPOTRADOS
253
F IGURA B.3: Proceso de encapsulación de la pasarela
para generar el fichero WSDL correspondiente. Eso puede realizarse previamente si se
conocen todos los identificadores posibles o bien utilizar un SDP. Concretamente es
posible usar ASDF, aunque dentro de la red SAN.
Cuando se conecta un nodo a la red, éste envía un anunciamiento. Las pasarelas
interesadas en servir ese nodo hacia el exterior preguntan al nodo cuál es su identificador y
las interfaces que implementa. Para ello se puede utilizar un MDOO binario puesto que es
un proceso independiente y desacoplado del transporte de mensajes. La pasarela construye
el fichero WSDL a partir de una plantilla que contiene la interfaz del servicio. En la sección
sobre implementación de servicio incluimos información común sobre el entorno tal como
la localización del nodo en formato legible, el identificador del nodo, etc.
[...]
<!−− Service to export −−>
< service name = " E xi t D o o r _ S e r v i c e " >
< port name = " IBoolRW_Port " binding = " IB oo lR W _B in di n g " >
< soap:address location = " http: // example . com:7890 " / >
</ port >
</ service >
[...]
L ISTADO B.5: Fragmento WSDL para la localización de un nodo
Los servicios pueden ser localizados también por medio del protocolo Universal
Description Discovery and Integration (UDDI). El proceso de publicación de un WS
asociado a un nodo en un registro UDDI es similar al de cualquier otro WS, es decir,
la interfaz WS como estructura t-model y la implementación como servicio UDDI
business.
Además, es posible instalar otros servicios en la pasarela para proporcionar otras
prestaciones como registro, autorización, etc. La pasarela puede generar los ficheros
WSDL a partir de un conjunto de plantillas de cada una de las interfaces implementadas
por los nodos de la red. Pero hay tres alternativas posibles:
Las plantillas pueden estar almacenadas en las pasarelas. Cuando se instala un nodo
con una interfaz nueva es necesario añadir una nueva plantilla a cada pasarela. Esta
situación introduce acoplamiento entre las pasarelas y las aplicaciones desplegadas
en la SAN pero no afecta a los nodos.
i
i
i
i
i
i
i
i
254
B. S ERVICIOS W EB EMPOTRADOS
Cuando un nuevo nodo se anuncia, la pasarela puede solicitar la plantilla de las
interfaces implementadas por el nodo, si es que las desconoce. Esto requiere
almacenar la plantilla WSDL en los nodos e implementar una operación para
obtenerla, lo que implica más memoria ROM o Flash en los nodos, aunque permite
pasarelas más sencillas y completamente independientes.
Una tercera alternativa es colocar las plantillas en un servidor remoto de modo que
las pasarelas las puedan solicitar bajo demanda. No implica mayores necesidades de
memoria en los nodos ni acoplamiento para las pasarelas, pero requiere de un host
remoto conocido por todas las pasarelas.
B.5.
Prototipos EWS
Utilizando las propuestas descritas, hemos desarrollado un conjunto de prototipos sobre
las plataformas típicas en WSN: el Atmel ATmega128 con el sistema operativo TinyOS.
También hemos realizado algunos prototipos sobre dispositivos sin sistema operativo.
Comparamos el tamaño de distintas implementaciones de WS. En un primer paso,
implementamos un servicio básico get/set (véase § B.3), usando dos bibliotecas ligeras de
propósito general: csoap [cso] y libxml-rpc [lib]. Después implementamos el mismo
servicio utilizando nuestra estrategia en tres plataformas diferentes: PC, MICA2 con
TinyOS y un microcontrolador AVR sin sistema operativo. El tamaño de los binarios
resultantes se muestra en la tabla B.1. Nótese que:
Todos los prototipos x86 están enlazados estáticamente y se ejecutan en un PC
convencional con SO Debian GNU/Linux. El tamaño del SO y sus dependencias no
se han considerado.
Los prototipos x86 de EWS son programas C puros con el soporte estándar de
sockets.
Los prototipos con MICA2 y AVR incluyen todos los componentes requeridos. Los
datos que aparecen en la tabla se refieren al fichero que instalamos en el dispositivo.
El prototipo AVR no utiliza SO, sólo un sencillo ejecutivo cíclico, mucho más
pequeño que TinyOS, aunque obviamente a costa de sus prestaciones.
software
platform
middleware
C-SOAP
libXML-RPC
x86
EWS
x86
SOAP
XML-RPC
SOAP
XML-RPC
SOAP
XML-RPC
SOAP
XML-RPC
TinyOS
AVR
binario (bytes)
otros
1 731 508
768 536
507 676
504 772
35 150
11 216
1 068
1 182
OS
OS
OS
OS
ZigBee (4 261)
ZigBee (4 261)
C UADRO B.1: Comparativa de tamaños (en bytes) de un WS para un servicio get/set
básico
i
i
i
i
i
i
i
i
B. S ERVICIOS W EB EMPOTRADOS
255
El código fuente de todos los prototipos, la implementación de referencia y otros ficheros
necesarios están disponibles en la página web de EWS [EWS].
B.6.
Conclusiones
EWS es una propuesta para implementar WS directamente en los nodos de una SAN o
WSN. Hasta donde sabemos, no existe una estrategia previa que permita algo semejante
en dispositivos con capacidad de cómputo tan limitada ya que lo habitual es exponer
los WS únicamente desde la pasarela.
Empotrar un WS directamente en el nodo SAN permite construir pasarelas genéricas
independientes de la aplicación. De ese modo, se proporciona un despliegue físico de
dispositivos con procedimientos de configuración mínimos.
Se han implementado algunos prototipos con transporte SOAP y XML-RPC para
demostrar la viabilidad de la solución propuesta (véase § B.5). En estos momentos, nuestro
objetivo es mejorar el soporte para la generación y prueba de máquinas de estados mediante
el compilador que permite la construcción de nodos listos para usar. También nos parece
muy interesante diseñar una nueva FSM que permita unificar el desarrollo y despliegue
de picoObjetos y WS en una misma red e, incluso, sobre los mismos nodos.
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
C
C
El protocolo Ice
C.1. Codificación de datos
C.2. Proxies
C.3. Mensajes del protocolo
Este anexo es un resumen del capítulo The Ice Protocol de la referencia oficial
de ZeroC I CE titulada «Distributed Programming with Ice» [HS08]. Se trata de una
traducción parcial del citado capítulo, incluyendo las aclaraciones e incisos que se han
considerado oportunos, pero excluyendo aquellas partes que quedan fuera de los objetivos
del presente trabajo. Con ello se pretende facilitar al lector una visión detallada de los
aspectos más relevantes del protocolo.
La especificación del protocolo I CE consta de tres partes principales:
Un conjunto de reglas de codificación para varios tipos de datos.
El formato y función de los mensajes que intercambian cliente y servidor.
Un conjunto de reglas que determinan cómo cliente y servidor negocian una versión
del protocolo y de la codificación.
C.1.
Codificación de datos
Los objetivos principales de la codificación de datos de I CE son la simplicidad y la
eficiencia. Por ello, se tomaron las siguientes decisiones de diseño.
No se fuerza el alineamiento de tipos básicos con los bordes de palabra. Eso
simplifica la serialización, evita pérdida de datos y cantidad de tráfico en la red.
Siempre se utiliza ordenamiento little endian para los datos numéricos. Con ello se
mejora notablemente la eficiencia de servicios de distribución de datos que requieren
varios saltos. En el caso en el que servidor o cliente se ejecuten en una máquina
big endian se requiere la transformación, pero ello no supone un gran coste dentro
257
i
i
i
i
i
i
i
i
258
C. E L PROTOCOLO I CE
del proceso de deserialización y en la actualidad la mayoría de las arquitecturas de
cómputo son little endian.
C.1.1.
Tamaños
Muchos de los tipos de datos y algunas partes del propio protocolo tienen un tamaño
asociado. Los tamaños se codifican con la siguiente regla:
1. Si el número de elementos es menor que 255, la cifra se codifica en un solo byte.
2. En otro caso, la cifra se codifica con un byte con valor 255, seguido de un entero
indicando la cifra propiamente dicha.
Con ello se consigue que para secuencias cortas se ahorren 3 bytes por cada tamaño,
mientras que para secuencias largas el byte adicional puede ser irrelevante.
C.1.2.
Encapsulaciones
Una encapsulación se utiliza para almacenar un tipo de dato de tamaño variable, pudiendo
ser ese tipo desconocido para elementos intermedios sin que eso impida que pueda seguir
su camino hasta el receptor. Las encapsulaciones se codifican del siguiente modo:
struct Encapsulation {
int size ;
byte major ;
byte minor ;
// [... size − 6 bytes ...]
};
L ISTADO C.1: Formato de codificación de una encapsulación Slice
El campo size indica el tamaño de la encapsulación completa (en bytes). Los campos
major y minor especifican la versión de la codificación utilizada para los datos. Al número
de versión le sigue el tamaño de los datos menos los 6 bytes que ocupa la cabecera de
la encapsulación, dado que dicho tamaño ocupa 4 bytes.
La encapsulación es un bloque de datos autónomo que puede ser reenviado sin necesidad
de conocer el formato de los datos que contiene. Permite anidamiento y es posible enviar
encapsulaciones vacías que tendrán, por tanto, un tamaño de 6 bytes.
C.1.3.
Slices
Una slice (rebanada) es un bloque de bytes precedido por un tamaño codificado como
un entero de 4 bytes. Por lo que un slice vacío ocupa 4 bytes. Tanto las excepciones como
las clases están formadas por slices. El objetivo es que al enviar una clase o excepción con
determinada jerarquía de herencia, el receptor pueda pasar por alto las clases especializadas
que no conoce y acceder a los datos de los tipos que sí conoce.
i
i
i
i
i
i
i
i
C. E L PROTOCOLO I CE
C.1.4.
259
Tipos básicos
Los tipos básicos se codifican según se muestra en el Cuadro C.1. Los tipos en punto
flotante usan formatos estándar de IEEE[IEE85]. Todos los tipos usan ordenamiento
little endian.
tipo
tamaño
notas
bool
byte
short
int
long
float
double
1 byte
1 byte
2 bytes
4 bytes
8 bytes
4 bytes
8 bytes
0:falso, 1:verdadero
23 bits de mantisa, 8 de exponente, 1 de signo
52 bits de mantisa, 11 de exponente, 1 de signo
C UADRO C.1: Tamaño de los tipos básicos de Slice
C.1.5.
Cadenas
Las cadenas de texto se codifican con un tamaño (véase § C.1.3) y, a continuación, el
contenido de la cadena codificado en formato UTF-8 [Uni00]. Las cadenas no contienen
un valor nulo al final. Una cadena vacía es un tamaño con valor cero.
C.1.6.
Tipos agregados
Secuencias
Las secuencias se codifican como un tamaño (véase § C.1.3) que indica la cantidad de
elementos en la secuencia seguido por los elementos codificados conforme a su tipo.
Diccionarios
Los diccionarios se codifican con un tamaño (véase § C.1.3) que indica la cantidad
de pares clave-valor seguido por dichos pares. Cada par se codifica como una estructura
con dos miembros: clave y valor, en ese orden.
Enumeraciones
La codificación de los enumerados depende de la cantidad de valores declarados. Hasta
127 valores se codifican como un byte. Más de 127 y hasta 32767 se codifican como un
short. Si son más, se codifican como int. El valor de cada enumerado es el ordinal
que le corresponda comenzando en cero.
Estructuras
Los miembros de una estructura se codifican en el mismo orden en el que aparecen en
su declaración y siguiendo las reglas definidas para sus respectivos tipos.
i
i
i
i
i
i
i
i
260
C. E L PROTOCOLO I CE
C.1.7.
Identidades
Todo objeto I CE tiene una identidad de objeto definida del siguiente modo:
module Ice {
struct Identity {
string name ;
string category ;
};
};
L ISTADO C.2: Estructura de una identidad de objeto I CE
La identidad consiste en dos cadenas: name y category. Para que dos identidades sean
consideradas iguales ambos campos deben coincidir. La category normalmente es vacía
salvo cuando se utilizan Servant locators (véase § 28.7 de [HS08])
C.2.
Proxies
El primer campo que se codifica es una identidad (tipo Ice::Identity). El protocolo
permite especificar proxies nulos, en cuyo caso se incluye únicamente una identidad
con sendas cadenas vacías para category y name (véase § C.1.7). Si el proxy no es
nulo se incluyen un conjunto de parámetros generales y después pueden aparecer
uno o varios endpoints.
La parte común del proxy se codifica como una estructura con los siguientes campos:
struct ProxyData {
Ice :: Identity id ;
Ice :: StringSeq facet ;
byte mode ;
bool secure ;
};
L ISTADO C.3: Estructura común de un proxy I CE
El significado de los miembros de esta estructura es el siguiente:
id – La identidad de objeto.
facet – El nombre de la faceta (una secuencia de cero o un elemento). La secuencia
vacía corresponde con la faceta por defecto.
mode – El modo del proxy:
0.
1.
2.
3.
4.
twoway.
oneway.
batch oneway.
datagram.
batch datagram.
i
i
i
i
i
i
i
i
C. E L PROTOCOLO I CE
261
secure – Es true si se requiere un endpoint seguro.
El proxy puede indicar además una lista de endpoints (si es un proxy directo) o un
identificador de adaptador (si es un proxy indirecto), en este segundo caso se codifica
un byte con valor 0 y el identificador como una cadena.
C.2.1.
Endpoints
Los endpoints se codifican inmediatamente después de la estructura indicada en la
sección anterior. Primero, un tamaño indica el número de endpoints que aparecen después.
Cada endpoint se codifica como un short que indica el tipo:
1. TCP
2. SSL
3. UDP
y, a continuación, una encapsulación con los parámetros específicos de cada endpoint.
Esto es así para que receptores que no conocen la estructura de ciertos tipos de endpoints
puedan manejar el proxy completo a pesar de ello.
Endpoints TCP
Se codifican por medio de la siguiente estructura:
struct T CP En dp o in tD at a {
string host ;
int port ;
int timeout ;
bool compress ;
};
L ISTADO C.4: Estructura de un endpoint TCP
cuyo significado es:
host – El nombre del host que aloja el servidor o su dirección IP.
port – El puerto al que está vinculado el servidor.
timeout – El timeout especificado para los sockets (en ms).
compress – Si debe utilizarse compresión.
Endpoints UDP
Se codifican según la siguiente estructura:
i
i
i
i
i
i
i
i
262
C. E L PROTOCOLO I CE
struct U DP En dp o in tD at a {
string host ;
int port ;
byte protocolMajor ;
byte protocolMinor ;
byte encodingMajor ;
byte encodingMinor ;
bool compress ;
};
L ISTADO C.5: Estructura de un endpoint UDP
cuyo significado es:
host – El nombre del host que aloja el servidor o su dirección IP.
port – El puerto al que está vinculado el servidor.
protocolMajor/protocolMinor – Versión del protocolo soportado por el endpoint.
encodingMajor/encodingMinor – Versión de la codificación soportada por el endpoint.
compress – Si debe utilizarse compresión.
Endpoints SSL
Se codifican según la siguiente estructura:
struct S SL En dp o in tD at a {
string host ;
int port ;
int timeout ;
bool compress ;
};
L ISTADO C.6: Estructura de un endpoint SSL
cuyo significado es idéntico al del endpoint TCP (véase § C.2.1).
C.3.
Mensajes del protocolo
El protocolo I CE define 5 tipos de mensajes:
1. Petición (del cliente al servidor).
2. Petición por lotes (del cliente al servidor).
3. Respuesta (del servidor al cliente).
Y en transportes orientados a conexión:
i
i
i
i
i
i
i
i
C. E L PROTOCOLO I CE
263
4. Validación de conexión (del servidor al cliente).
5. Cierre de conexión (ambos sentidos).
Los mensajes no requieren ningún tipo de alineamiento y constan de una cabecera
y un cuerpo.
C.3.1.
Cabecera
Todos los mensajes del protocolo I CE comienzan con una cabecera de 14 bytes
según la siguiente estructura:
struct HeaderData {
int magic ;
byte protocolMajor ;
byte protocolMinor ;
byte encodingMajor ;
byte encodingMinor ;
byte messageType ;
byte c o m p r e s s i o n S t a t u s ;
int messageSize ;
};
L ISTADO C.7: Protocolo I CE: Formato de la cabecera
El significado de cada miembro es el siguiente:
magic – Una secuencia de 4 bytes con los códigos ASCII de los caracteres ‘I’,‘c’,‘e’,‘P’.
protocolMajor/protocolMinor – Versión del protocolo.
encodingMajor/encodingMinor – Versión de la codificación.
messageType – Tipo de mensaje:
0.
1.
2.
3.
4.
Petición.
Petición por lotes.
Respuesta.
Validación de conexión.
Cierre de conexión.
compressionStatus – Indica si el mensaje está comprimido.
messageSize – El tamaño total del mensaje incluyendo la cabecera.
C.3.2.
Cuerpo del mensaje de petición
El cuerpo contiene toda la información necesaria para realizar la invocación a un método
de un objeto remoto, lo cual incluye la identidad del objeto, el nombre de la operación y
los parámetros de entrada. Se codifican conforme a la siguiente estructura:
i
i
i
i
i
i
i
i
264
C. E L PROTOCOLO I CE
struct RequestData {
int requestId ;
Ice :: Identity id ;
Ice :: StringSeq facet ;
string operation ;
byte mode ;
Ice :: Context context ;
Encapsulation params ;
};
L ISTADO C.8: Protocolo I CE: Formato del mensaje de petición
siendo:
requestId – Identificador de la petición. En las invocaciones oneway tiene valor 0 e
indica que no se debe responder al cliente.
id – Identidad del objeto invocado.
facet – Nombre de la faceta (cero o un elemento).
operation – El nombre de la operación invocada.
modo – Modo de operación: normal (0) o idempotente (2).
context – Contexto de la invocación.
params – Parámetros de entrada, en el orden en el que aparecen en la declaración de la
operación.
C.3.3.
Cuerpo del mensaje de petición por lotes
Un mensaje de petición por lotes contiene una o varias invocaciones oneway agrupadas.
Se codifica como un entero que indica el número de invocaciones seguido de los cuerpos
de los mensajes de petición codificados del siguiente modo:
struct B a t c h R e q u e st D a t a {
Ice :: Identity id ;
Ice :: StringSeq facet ;
string operation ;
byte mode ;
Ice :: Context context ;
Encapsulation params ;
};
L ISTADO C.9: Protocolo I CE: Formato del mensaje de petición por lotes
El significado de los miembros es equivalente al del mensaje de petición (véase
§ C.3.2).
i
i
i
i
i
i
i
i
C. E L PROTOCOLO I CE
C.3.4.
265
Cuerpo del mensaje de respuesta
El mensaje de respuesta contiene los resultados de una invocación twoway incluyendo
el valor de retorno, los parámetros de salida o el contenido de una posible excepción.
Se codifica según la siguiente estructura.
struct ReplyData {
int requestId ;
byte replyStatus ;
Encapsulation body ; // messageSize − 19 bytes
};
L ISTADO C.10: Protocolo I CE: Formato del mensaje de respuesta
El valor requestId debe corresponder con el campo del mismo nombre según se
indicó en el mensaje de petición. El campo replyStatus indica un tipo de respuesta
según la siguiente lista:
0. Invocación satisfactoria.
1. Excepción de usuario.
2. El objeto no existe.
3. La faceta no existe.
4. La operación no existe.
5. Excepción I CE local desconocida.
6. Excepción I CE de usuario desconocida.
7. Excepción desconocida.
C.3.5.
Mensaje de validación de conexión
Cuando un servidor sobre un protocolo orientado a conexión recibe un intento de
conexión siempre responde con un mensaje de validación de conexión sin que el cliente
tenga que enviar nada. El cliente debe esperar este mensaje antes de poder enviar mensajes
de petición. Este mensaje resuelve dos problemas:
Informa al cliente de la versión del protocolo y codificación soportados por el
servidor.
Evita que el cliente escriba el mensaje en sus buffers locales antes de que el servidor
haya comprobado que puede atender sus peticiones. Eso evita que el servidor acepte
nuevas peticiones cuando se está apagando.
C.3.6.
Mensaje de cierre de conexión
Este mensaje lo puede enviar tanto cliente como servidor para indicar que va a realizar
el cierre de la conexión. Solo puede ocurrir cuando no quedan invocaciones por responder
y únicamente cuando se utilizan transportes twoway.
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
General Inter-ORB Protocol
D.1.
D.2.
D.3.
D.4.
Visión general de GIOP
Sintaxis de transferencia de CDR
Formato de los mensajes GIOP
Transporte de mensajes GIOP
D
D
Este anexo es un resumen del capítulo General Inter-ORB Protocol del documento
central de la especificación CORBA [COR02]. Una parte importante de este capítulo
es una traducción más o menos libre del original, aplicando como criterio la claridad
y la relación con el objetivo que nos ocupa. Se han omitido las secciones que tratan
características no soportadas por picoCORBA, tales como serialización de tipos complejos,
localización de objetos o GIOP bidireccional.
D.1.
Visión general de GIOP
Después de las primeras versiones del estándar de CORBA se observó la necesidad
de definir un protocolo común para comunicar varios ORB S.
A partir de CORBA 2.0 se definió la arquitectura de interoperabilidad entre ORB S de
distintos fabricantes sobre el protocolo GIOP. Sin embargo, se mantuvo la idea de poder
utilizar, además de GIOP, cualquier otro protocolo propio del fabricante (ESIOP). Estas
dos ideas se han respetado hasta el momento y son la base que permite la interoperabilidad
entre ORB S de diferentes fabricantes.
GIOP puede mapearse sobre cualquier protocolo de transporte orientado a conexión
que cumpla unos mínimos requisitos. CORBA define un mapping de GIOP específico
para conexiones TCP/IP llamado IIOP (Internet IOP) cuyo diagrama de capas aparece
en la figura D.1.
Los objetivos más importantes que se tuvieron en cuenta en el diseño de GIOP fueron:
267
i
i
i
i
i
i
i
i
268
D. G ENERAL I NTER -ORB P ROTOCOL
Objetos de la aplicación
ORB
IIOP
TCP
IP
Ethernet
Medio físico
F IGURA D.1: Diagrama de capas de CORBA
Disponibilidad
GIOP está basado en el mecanismo de transporte más flexible y usado que existe
(TCP/IP), y define un protocolo mínimo adicional para transmitir peticiones CORBA
entre ORB S.
Simplicidad
GIOP está pensado para ser lo más simple posible siempre que cumpla los demás
objetivos. La simplicidad asegura variedad de implementaciones independientes y
compatibles.
Escalabilidad
GIOP/IIOP debería soportar ORB S y puentes (bridges) de ORB S dado el tamaño
actual y futuro de Internet.
Bajo coste
Añadir soporte para GIOP a un ORB nuevo o existente debería requerir poco
esfuerzo en desarrollo. Además, el coste requerido para soportar IIOP en un ORB en
exploración debería ser mínimo.
Generalidad
El formato de los mensajes GIOP está diseñado para ser usado con cualquier
protocolo de transporte orientado a conexión.
Neutralidad arquitectural
La especificación de GIOP hace suposiciones mínimas sobre la arquitectura de
agentes que soporta. GIOP trata a los ORB S como entidades opacas con arquitecturas
desconocidas.
La especificación de GIOP consta de los siguientes elementos:
Definición de CDR (Common Data Representation). CDR es un mapping de los tipos
de datos de IDL a una representación bicanónica de bajo nivel para transferencias
entre ORB S o entre puentes Inter-ORB (agentes).
Formatos de mensajes GIOP. Los agentes intercambian mensajes GIOP para
conseguir peticiones a objetos, localización de implementaciones y gestión de canales
de comunicación.
i
i
i
i
i
i
i
i
D. G ENERAL I NTER -ORB P ROTOCOL
269
Consideraciones sobre el transporte GIOP. La especificación GIOP describe ciertas
condiciones generales que conciernen a cualquier protocolo de transporte que puede
ser usado para transferir mensajes GIOP. También describe cómo gestionar las
conexiones y las restricciones en la ordenación de mensajes.
D.1.1.
Representación común de datos (CDR)
CDR tiene las siguientes características:
Ordenación de bytes variable
Las máquinas con una ordenación de bytes (byte order) común pueden intercambiar
datos sin tener que realizar modificaciones en el ordenamiento. Cuando la
comunicación se realiza entre máquinas con ordenación diferente, el emisor
determina la ordenación de bytes en el mensaje, y el receptor es responsable de
realizar el intercambio para que corresponda con su ordenamiento. Cada mensaje
GIOP (y encapsulación CDR) contiene un flag que indica el ordenamiento.
Tipos primitivos alineados
Los tipos de datos primitivos de IDL se alinean a sus límites naturales dentro de los
mensajes, permitiendo que los datos se puedan manejar de forma más eficiente por
las arquitecturas que fuerzan el alineamiento de datos en memoria.
Mapping completo de IDL
CDR describe la representación de todos los tipos de datos de IDL, incluyendo
pseudo-objetos como TypeCodes.
D.1.2.
Mensajes GIOP
GIOP especifica el formato de los mensajes que se intercambian los ORB S. El formato
de los mensajes GIOP tiene las siguientes características:
Mensajes simples
Con pocos mensajes, GIOP soporta la funcionalidad completa de CORBA entre
ORB S, con capacidades extendidas que permiten servicio de localización de objetos,
migración dinámica, gestión eficiente de comunicación de recursos. La semántica
de GIOP no requiere negociación. En muchos casos, los clientes pueden invocar
operaciones inmediatamente después de establecerse la conexión.
Localización dinámica de objetos
Muchas arquitecturas de ORB permiten que la implementación de un objeto sea
activada desde un lugar diferente durante su ciclo de vida, y permite a los objetos
migrar dinámicamente. Los mensajes GIOP dan soporte para la localización y
migración de objetos. No se requiere que los ORB S implementen dichos mecanismos
cuando sea innecesario o inapropiado.
Soporte completo para CORBA
Los mensajes GIOP posibilitan directamente todas las funciones y comportamientos
requeridos por CORBA, incluyendo manipulación de excepciones, contextos de
operación e invocaciones sobre referencias a objetos remotos.
i
i
i
i
i
i
i
i
270
D. G ENERAL I NTER -ORB P ROTOCOL
GIOP también permite el paso de contextos propios de los servicios, tales como
el contexto del servicio estándar de transacción. Este mecanismo está diseñado para
soportar cualquier servicio que requiera información de contexto que tenga que ser
enviada implícitamente en las peticiones.
D.1.3.
Transferencia de mensajes GIOP
La especificación GIOP está diseñada para operar sobre cualquier protocolo de
transporte que cumpla unas mínimas condiciones (véase § D.4). GIOP utiliza conexión
de varias maneras:
Uso asimétrico de conexión
GIOP define dos roles diferentes con respecto a las conexiones: cliente y servidor.
El cliente origina la conexión y envía petición a los objetos a través de esa conexión.
El servidor recibe las peticiones y envía respuestas.
Multiplexación de peticiones
Si es necesario, varios clientes de un ORB pueden compartir una conexión para
enviar peticiones a un ORB o servidor concreto. Cada petición únicamente identifica
al objeto destino. Varias peticiones independientes para uno o varios objetos se
pueden enviar sobre la misma conexión.
Peticiones solapadas
En general, la ordenación de mensajes GIOP es mínima. GIOP está diseñado
para permitir el solapamiento de peticiones asíncronas. Los identificadores
únicos permiten una adecuada correlación entre peticiones y respuestas. Las
implementaciones son libres de imponer mecanismos de ordenación internos si
las arquitecturas de sus ORB S lo requieren.
Gestión de conexiones
GIOP define mensajes para cancelación y finalización controlada de las conexiones.
Estas características permiten a los ORB S reutilizar los recursos no ocupados.
D.2.
Sintaxis de transferencia de CDR
La sintaxis de transferencia CDR es el formato en que GIOP representa los tipos
de datos IDL en un flujo de octetos.
Un flujo de octetos es una notación abstracta que corresponde con un buffer de memoria
que debe ser transmitida a otro proceso con un mecanismo de comunicación entre
procesos (IPC) o transporte de red. Un flujo de octetos es arbitrariamente largo (pero
finito), formado por valores de 8 bits (octetos) y con un comienzo bien definido. Cada
flujo puede ser indexado en una posición de 0 a n-1, siendo n el número de octetos
del flujo. La posición que ocupa un octeto se llama índice; estos índices se usan para
alinear los datos IDL dentro del flujo.
GIOP define dos tipos de flujos de octetos, mensajes y encapsulaciones. Los mensajes
son unidades básicas de información GIOP, que se describe en el sección D.3. Las
encapsulaciones son tramas en las que las estructuras de datos IDL se pueden serializar
i
i
i
i
i
i
i
i
D. G ENERAL I NTER -ORB P ROTOCOL
271
(marshall) independientemente de cualquier contexto del mensaje. Una vez que una
estructura de datos está encapsulada, el flujo de octetos puede representarse como un tipo
IDL sequence<octet> opaco, que se puede serializar en otro mensaje o encapsulación.
La encapsulación permite constantes complejas (como los TypeCode); esto también
permite que ciertos componentes del mensaje puedan usarse sin tener que realizar
una deserialización completa.
D.2.1.
Tipos primitivos
Los tipos primitivos están definidos en orden big-endian y en little-endian; tanto
los mensajes como las encapsulaciones disponen de un flag en su cabecera que indica
el tipo de ordenamiento que usan. Las encapsulaciones en el interior de los mensajes
pueden tener un ordenamiento distinto al propio mensaje. Los tipos de datos primitivos
se codifican en múltiplos de octeto.
Alineamiento
Para trasladar los tipos primitivos a las tramas de octetos se definen funciones específicas
para cada uno de los tipos; CDR requiere que todos los tipos primitivos estén alineados
a sus límites naturales. El alineamiento de los tipos primitivos es igual al tamaño del
tipo en bytes. Un tipo primitivo de tamaño n debe comenzar en una posición de la trama
múltiplo de n; en CDR, n puede ser 1, 2, 4 u 8.
Cuando sea necesario, pueden aparecer huecos (alignment gap) antes de la representación
de los datos. El valor de los octetos que conforman los huecos no está definido. En la
tabla D.1 se muestra la alineación en octetos que deben tener los tipos primitivos.
tipo
char
octet
short
unsigned short
long
unsigned long
long long
unsigned long long
float
double
long double
boolean
enum
alineamiento
1
1
1
2
4
4
8
8
4
8
8
1
4
C UADRO D.1: Alineación requerida para los tipos primitivos de IDL
El alineamiento se define respecto al comienzo de la trama de octetos. El primer octeto
de la trama tiene índice cero; todos los tipos de datos se almacenan comenzando por este
i
i
i
i
i
i
i
i
272
D. G ENERAL I NTER -ORB P ROTOCOL
índice. La trama de octetos empieza con una cabecera de mensaje GIOP (véase § D.3.1)
o con una encapsulación, incluso si está anidada en otra encapsulación.
Tipos enteros
En la tabla D.2 se muestra la ordenación de bytes, tanto en big-endian como en littleendian, para los enteros definidos en IDL, entre los que se encuentran los siguientes:
short
unsigned short
long
unsigned long
long long
unsigned long long
short
MSB
LSB
0
1
LSB
0
1
2
3
LSB
0
1
LSB
0
1
2
3
MSB
long
MSB
long long
(a) Big-Endian
MSB
LSB
MSB
(b) Little-Endian
0
1
2
3
4
5
6
7
LSB
MSB
0
1
2
3
4
5
6
7
C UADRO D.2: Tamaño y ordenamiento en codificaciones big endian y little endian de
los tipos de datos enteros IDL, con y sin signo
Tipos en punto flotante
Un número en punto flotante está compuesto del bit de signo, el exponente y la parte
fraccionaria de la mantisa, tal y como se define en el estándar IEEE para los números
en punto flotante [IEE85]. La tabla D.3 representa los diferentes componentes para
números en punto flotante: el bit de signo (s), el exponente (e) y la parte fraccionaria
de la mantisa (f ). El bit de signo puede tomar valores 0 ó 1, representando positivo
y negativo respectivamente.
i
i
i
i
i
i
i
i
D. G ENERAL I NTER -ORB P ROTOCOL
273
float
s
e2
e1
f1
f2
f3
0
1
2
3
e1
f1
f2
f3
f4
f5
f6
f7
0
1
2
3
4
5
6
7
e1
e2
f1
f2
f3
f4
f5
f6
f7
f8
f9
f10
f11
f12
f13
f14
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
e2
s
f3
f2
f1
e1
0
1
2
3
e2
s
f7
f6
f5
f4
f3
f2
f1
e1
7
6
5
4
3
2
1
0
s
f14
f13
f12
f11
f10
f9
f8
f7
f6
f5
f4
f3
f2
f1
e2
e1
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
double
s
e2
long double
s
C UADRO D.3: Tamaño y ordenamiento en codificaciones big endian y little endian de
los tipos de datos de punto flotante de IDL, con y sin signo
i
i
i
i
i
i
i
i
274
D. G ENERAL I NTER -ORB P ROTOCOL
Octetos
El octeto es un valor de 8 bits no interpretado para el cual está garantizado que su
contenido no se convertirá ni modificará durante la transmisión. A efectos de especificación
se puede considerar a los octetos como enteros sin signo de 8 bits.
Booleanos
Están codificados como octetos simples, donde TRUE (cierto) es el valor 1, y FALSE
(falso) es el valor 0.
Caracteres
Un carácter IDL se representa como un octeto simple, la tabla de códigos (code set)
que se usa en la transmisión de caracteres entre los ORB S de un servidor y un cliente se
determina en el propio proceso de transmisión. En caso de codificación multi-byte1 , una
instancia del tipo carácter (char) sólo puede contener uno de los valores del multi-byte.
La sintaxis de transferencia para caracteres anchos (wide char) depende de la versión
de GIOP (véase §13.7, Code Set Conversion de [COR02]).
D.2.2.
Tipos compuestos
Los tipos de datos compuestos se construyen a partir de los tipos primitivos usando
medios definidos en el lenguaje IDL.
Alineamiento
Los tipos compuestos no tienen restricciones de alineamiento aparte de las de sus
componentes primitivos. GIOP asume que los agentes construyen los tipos de datos
estructurados copiando datos primitivos entre el buffer serializado y la estructura de datos
en memoria para la implementación del mapping del lenguaje concreto.
Estructuras (struct)
Los elementos de una estructura se codifican en el orden de su declaración IDL. Cada
componente se codifica según su propio tipo.
Union
Se codifican como una etiqueta discriminante (del tipo especificado en la declaración),
seguido por la representación de miembros correspondientes a la etiqueta, codificados
según su propio tipo.
Array
Se codifican como un vector de elementos en secuencia. Como la longitud del array
es fija, no se incluyen valores de longitud. Cada elemento se codifica según su tipo.
1 Se
utilizan varios bytes para codificar cada carácter.
i
i
i
i
i
i
i
i
D. G ENERAL I NTER -ORB P ROTOCOL
275
En arrays multidimensionales, los elementos se ordenan de modo que el índice de la
primera dimensión varía más despacio.
Secuencias (Sequence)
Se codifican como un valor unsigned long que indica el tamaño seguido por los
elementos de la secuencia. Dichos elementos se codifican según su tipo.
Enumeraciones (enum)
Los valores de las enumeraciones se almacenan como unsigned long. El valor
numérico asociado a cada identificador se determina por el orden de éstos en la
definición del tipo comenzando con cero; el resto reciben valores en orden ascendente
de izquierda a derecha.
Cadenas
Una cadena (string) se codifica como unsigned long que indica la longitud en
octetos, seguido por el valor de los caracteres que forman la cadena ya sea en formato
de caracteres simples o multi-byte; la representación es equivalente a una secuencia de
octetos. La cadena incluye un carácter simple nulo que indica el fin; la longitud de la
cadena incluye dicho carácter, de modo que el tamaño de una cadena vacía es 1.
Tipos decimales en punto fijo
El tipo IDL fixed no tiene restricciones de alineación. Cada octeto contiene dos
dígitos decimales. Cada nibble2 codifica un dígito en hexadecimal. Si el tipo fijo
tiene un número par de dígitos decimales, la representación empieza por el dígito más
significativo; en otro caso, el primer nibble es un cero y el segundo es el dígito más
significativo del número. La representación del signo es el último nibble: 0xD si es
negativo y 0xC si es positivo o cero.
El número de dígitos debe ser igual al número de dígitos significativos especificado
en la definición IDL, con la excepción del nibble añadido en el caso de valores con
un número impar de dígitos significativos.
D.2.3.
Encapsulación
Los tipos de datos IDL se pueden serializar en encapsulaciones de tramas de octetos.
La trama de octetos se representa con el tipo IDL sequence<octet>, que puede ser
incluida en un mensaje GIOP o anidada en otra encapsulación.
GIOP e IIOP utilizan encapsulaciones explícitamente en tres sitios:
TypeCodes.
Perfiles IIOP en el interior de IOR.
Contextos específicos del servicio.
2 Semi-octeto.
i
i
i
i
i
i
i
i
276
D. G ENERAL I NTER -ORB P ROTOCOL
Cuando se encapsulan tipos IDL, el primer octeto de la trama (índice 0) contiene un
valor booleano que indica el ordenamiento de los datos encapsulados. Si el valor es
FALSE (0), los datos encapsulados están codificados en big-endian; si es TRUE (1),
se codifican en little-endian, es el mismo criterio que en las cabeceras GIOP (véase
§ D.3.1). Este valor no es parte de los datos encapsulados, pero es parte del flujo de
octetos incluidos en la encapsulación. A continuación del flag de ordenamiento, los
datos a encapsular se serializan en el buffer tal como indican las reglas de CDR. Los
datos serializados se alinean con relación al comienzo del flujo de octetos (el primer
octeto ocupado por el flag de ordenamiento).
Cuando la encapsulación se codifica con el tipo sequence<octet> para su serialización,
se coloca delante un unsigned long cuyo valor es el tamaño de la secuencia. El valor
de la longitud no es parte de la encapsulación y no afecta al alineamiento de los datos.
Esto garantiza un alineamiento de 4 bytes al comienzo de todos los datos en mensajes
GIOP y encapsulaciones anidadas.
D.3.
Formato de los mensajes GIOP
GIOP está restringido al modelo cliente/servidor en lo referente a inicialización y
recepción de mensajes. Para las versiones 1.0 y 1.1 de GIOP, un cliente es un agente que
abre una conexión y envía peticiones; un servidor es un agente que acepta conexiones y
recibe dichas peticiones. Sin embargo, cuando se utiliza GIOP bidireccional en el protocolo
GIOP versiones 1.2 y 1.3, cualquiera de los interlocutores puede originar mensajes tal
como se especifica en la sección Bi-Directional GIOP en [COR02].
El cuadro D.4 resume todos los mensajes GIOP, indicando su nombre, el emisor
(cliente, servidor o ambos) y el valor usado para identificar el mensaje en la cabecera
del mensaje GIOP.
mensaje
Request
Reply
CancelRequest
LocateRequest
LocateReply
CloseConnection
MessageError
Fragment
origen
valor
cliente
servidor
cliente
cliente
servidor
servidor
ambos
ambos
0
1
2
3
4
5
6
7
versión
1.0, 1.1, 1.2
1.0, 1.1, 1.2
1.0, 1.1, 1.2
1.0, 1.1, 1.2
1.0, 1.1, 1.2
1.0, 1.1, 1.2
1.0, 1.1, 1.2
1.1, 1.2
C UADRO D.4: GIOP: Tipos de mensajes
En esta sección se describe sólo el formato y funcionamiento de GIOP versión 1.0, por
ser la primera y más simple de las definidas hasta el momento por OMG. Las versiones
posteriores: 1.1, 1.2 y 1.3 han incorporado mejoras y nuevas características al protocolo.
Aún así, la esencia del mismo no ha cambiado y, por tanto, GIOP 1.0 es una referencia
más que suficiente para comprender perfectamente la finalidad del protocolo. Para una
i
i
i
i
i
i
i
i
D. G ENERAL I NTER -ORB P ROTOCOL
277
descripción detallada de versiones más recientes de GIOP, consultar [COR02]. El formato
de los mensajes se describe en IDL conforme a la especificación original.
D.3.1.
Cabecera GIOP
Todos los mensajes GIOP comienzan con una cabecera de tamaño fijo descrita en
el listado D.1.
module GIOP {
struct Version {
octet major ;
octet minor ;
};
enum MsgType_1_0 {
Request , Reply , CancelRequest ,
LocateRequest , LocateReply ,
CloseConnection , MessageError
};
struct M e s s a g e H e a d e r _ 1 _ 0 {
char
magic [4];
Version
GIOP_version ;
boolean
byte_order ;
octet
message_type ;
unsigned long
message_size ;
};
};
L ISTADO D.1: Formato de la cabecera GIOP
La cabecera identifica el mensaje GIOP y su ordenación de bytes (byte-order). La
cabecera es independiente de la ordenación excepto para los siguientes campos:
magic – Identifica a los mensajes GIOP. El valor de este miembro es constante y
corresponde con los caracteres «GIOP», en mayúsculas y codificados en ISO Latin-1
(8859.1).
GIOP_version – Es el número de versión del protocolo GIOP usado en el mensaje. Éste
se aplica a los elementos independientes del transporte, es decir, CDR y el formato de
los mensajes. Es diferente de la versión de IIOP aunque tenga la misma estructura.
Una implementación que soporte GIOP 1.n (con n > 0) debe también poder procesar
mensajes GIOP de versiones anteriores. Un servidor que recibe una petición de una
versión GIOP mayor de la que soporta debería responder con un mensaje de error
con el número de versión mayor que soporta y, después, cerrar la conexión.
Ningún cliente debería enviar un mensaje con una versión mayor que la publicada
por el servidor en el perfil IIOP de su IOR.
byte_order – Indica el ordenamiento del mensaje (incluyendo el campo message_size).
Un valor 0 indica big-endian y un valor 1 indica little-endian.
i
i
i
i
i
i
i
i
278
D. G ENERAL I NTER -ORB P ROTOCOL
message_type – Indica el tipo de mensaje de acuerdo con el cuadro D.4. Los valores
posibles corresponden con el tipo MsgType.
message_size – Contiene el número de octetos del mensaje (sin incluir la cabecera)
codificados con el ordenamiento indicado por el campo byte_order. Indica el tamaño
del cuerpo del mensaje, este valor incluye los octetos necesarios para los huecos de
alineamiento (alignment gap), los parámetros de la petición o respuesta y los octetos
de relleno al final del mensaje de modo que termine en un límite de 8 bytes.
D.3.2.
Mensaje de petición (Request)
Los mensajes de petición codifican las invocaciones a objetos CORBA, incluyendo
acceso a los atributos y operaciones de CORBA::Object como get_interface() y get_implementation(). Las peticiones fluyen del cliente hacia el servidor.
Los mensajes de petición tienen tres elementos, codificados en este orden:
Una cabecera de mensaje GIOP.
Una cabecera de petición.
El cuerpo de la petición.
Cabecera de petición
La cabecera de petición está definida como sigue:
module GIOP {
struct R e q u e s t H e a d e r _ 1 _ 0 {
IOP :: S e r v i c e C o n t e x t L i s t
unsigned long
boolean
sequence < otet >
string
CORBA :: OctetSeq
}
};
s er vi c e_ co nt e xt ;
request_id ;
response_expected ;
object_key ;
operation ;
requesting_principal ;
Los miembros tienen los siguientes significados:
service_context – Contiene datos del ORB que se pasan del cliente al servidor tal
como se explica en Object Service Context en [COR02].
request_id – Se usa para asociar los mensajes de respuesta con los de petición (inclu-
yendo los mensajes LocateRequest). El cliente peticionario es el responsable de
generar valores de forma que no haya ningún tipo de ambigüedad; específicamente,
un cliente no debería reutilizar los mismos valores durante una conexión si:
1. La última petición que contenía el identificador aún está pendiente de respuesta.
2. La última petición que contenía el identificador fue cancelada y no se recibió
respuesta.
i
i
i
i
i
i
i
i
D. G ENERAL I NTER -ORB P ROTOCOL
279
response_expected – Indica que el cliente espera recibir una respuesta para la petición
si su valor es TRUE.
object_key – Identifica al objeto al que va dirigida la petición. Corresponde con el
valor del campo object_key del perfil GIOP presente en la IOR para ese objeto. El
cliente no debe modificar ni interpretar nunca este valor.
operation – Es un identificador IDL en el contexto de la interfaz que implementa el
objeto y que identifica el método que el cliente desea invocar. En el caso de accesores,
los nombres de las operaciones son _get_<attribute> y _set_<attribute>.
El valor de la operación debe corresponder con un nombre o atributo usado en la
declaración de la interfaz IDL.
Las operaciones definidas para CORBA::Object son:
_interface.
_is_a.
_non_existent.
_domain_managers.
_component.
requesting_principal – Es un campo que se utilizaba en implementaciones del BOA,
predecesor del POA y que hoy está en desuso.
Cuerpo de la petición
En GIOP 1.0 y 1.1, el cuerpo de la petición se serializa en la encapsulación CDR
inmediatamente después de la cabecera de petición. Los datos en el cuerpo de la petición
incluyen los siguientes elementos en este orden:
Todos los parámetros de entrada (in) y entrada/salida (inout), en el orden en que se
especifiquen en la definición de la operación en IDL, de izquierda a derecha.
Un pseudo-objeto opcional Context. Este elemento está presente sólo si la definición
de la operación en IDL incluye una expresión de contexto y únicamente aparecen
los miembros definidos en la expresión IDL.
D.3.3.
Mensaje de respuesta (Reply)
Los mensajes de respuesta se devuelven al emisor del mensaje de petición sólo si el flag
de response_expected tiene un valor TRUE. El mensaje de respuesta incluye los parámetros
de salida, los de entrada/salida y el valor de retorno de la operación. En GIOP 1.0 y 1.1
los mensajes de respuesta fluyen sólo del servidor hacia el cliente.
Los mensajes de respuesta tienen tres elementos, codificados en este orden:
Una cabecera GIOP.
Una cabecera de respuesta.
El cuerpo de la respuesta.
i
i
i
i
i
i
i
i
280
D. G ENERAL I NTER -ORB P ROTOCOL
Cabecera de respuesta
La cabecera de respuesta está definida como sigue:
module GIOP {
enum R e p l y S t a t u s T y p e _ 1 _ 0 {
NO_EXCEPTION ,
USER_EXCEPTION ,
SYSTEM_EXCEPTION ,
L O C A T I O N _ F OR W A R D
};
struct R ep ly He a de r_ 1_ 0 {
IOP :: S e r v i c e C o n t e x t L i s t
unsigned long
ReplyStatusType_1_0
};
s er vi c e_ co nt e xt ;
request_id ;
reply_status ;
};
Siendo:
request_id – Se usa para asociar las respuestas a las peticiones. Contiene el valor del
campo del mismo nombre en la petición correspondiente.
reply_status – Indica el estado de la petición asociada, y también determina parte
del contenido del cuerpo del mensaje de respuesta. Si no ocurren excepciones y
la operación se completa satisfactoriamente, el valor es NO_EXCEPTION y el cuerpo
contiene los valores de retorno. En otro caso, el cuerpo puede:
Contener una excepción,
Indicar al cliente que redirija la petición a un objeto que se encuentra en otra
localización, o
Pedir al cliente que indique más información de direccionamiento.
service_context – Es equivalente al campo del mismo nombre presente en la cabecera
de petición.
No se incluyen octetos de relleno (padding) cuando el cuerpo del mensaje de
respuesta es vacío.
Cuerpo del mensaje de respuesta
En GIOP 1.0 y 1.1, el cuerpo del mensaje de respuesta está serializado en una
encapsulación CDR que aparece inmediatamente a continuación de la cabecera de
respuesta. El contenido del mensaje de respuesta está determinado por el valor del
campo reply_status. El cuerpo puede ser de los siguientes tipos dependiendo del
valor del campo reply_status:
Si es NO_EXCEPTION, en el cuerpo se codifica primero el valor de retorno de la
operación, si lo hubiere, después los parámetros entrada/salida y de salida en el
orden en el que aparecen en la declaración de la operación en IDL, de izquierda a
derecha.
i
i
i
i
i
i
i
i
D. G ENERAL I NTER -ORB P ROTOCOL
281
Si es USER_EXCEPTION o SYSTEM_EXCEPTION, el cuerpo contiene la excepción
levantada por la operación. Sólo se pueden levantar las excepciones de usuario
que aparezcan en la definición de operación del IDL.
Cuando el valor del campo reply_status es SYSTEM_EXCEPTION, el cuerpo de la
respuesta tiene la siguiente estructura:
module GIOP {
struct S y s t e m E x c e p t i o n R e p l y B o d y {
string
exception_id ;
unsigned long
m i n o r _ c o d e _ va l u e ;
unsigned long
completion_status ;
};
};
Si es LOCATION_FORWARD, el cuerpo contiene una referencia a objeto (IOR). El ORB
cliente es responsable de reenviar la petición original al objeto asociado a dicha
referencia. Este reenvío es transparente para el programa cliente que hace la petición.
D.3.4.
Mensaje de cancelación de petición (CancelRequest)
En GIOP 1.0 y 1.1 son mensajes enviados por el cliente al servidor para notificar que el
cliente no seguirá esperando la respuesta para un mensaje de petición pendiente.
El mensaje de cancelación de petición tiene dos elementos:
Una cabecera de mensaje GIOP.
Una cabecera de mensaje de cancelación de petición.
Cabecera de cancelación de petición
Está definida del siguiente modo:
module GIOP {
struct C a n c e l R e q u e s t H e a d e r {
unsigned long
request_id ;
};
};
request_id identifica el mensaje de petición, o petición de localización (LocateRequest),
al que se aplica la cancelación. Este valor es el mismo que el especificado en el campo
del mismo nombre en el mensaje de petición original.
Cuando un cliente emite un mensaje de cancelación de petición sólo supone un aviso.
El servidor puede hacer caso omiso y enviar el mensaje de respuesta de todos modos.
El cliente no debería hacer suposiciones sobre si llegará o no la respuesta una vez
enviado el mensaje de cancelación de petición.
i
i
i
i
i
i
i
i
282
D. G ENERAL I NTER -ORB P ROTOCOL
D.3.5.
Mensaje de petición de localización (LocateRequest)
Estos mensajes pueden ser enviados por un cliente a un servidor para determinar las
siguientes características sobre el objeto:
Si el servidor es capaz de dirigir peticiones hacia la referencia a objeto, o no.
Qué petición de dirección podría enviar para la referencia a objeto.
Esta información también se obtiene a través de un mensaje de petición convencional,
pero puede que algunos clientes no deseen retransmitir paquetes grandes cuando el
mensaje de respuesta retorna el estado LOCATION_FORWARD. El cliente puede utilizar
el mensaje de petición de localización para transmitir sus mensajes directamente a
la localización correcta.
El mensaje de petición de localización tiene dos elementos:
Una cabecera de mensaje GIOP.
Una cabecera de petición de localización.
Cabecera de petición de localización
Está definida como sigue:
module GIOP {
struct L o c a t e R e q u e s t H e a d e r _ 1 _ 0 {
unsigned long
request_id ;
sequence <octet >
object_key ;
};
};
Los miembros tienen el significado habitual.
D.3.6.
Mensaje de respuesta de localización (LocateReply)
Los mensajes de respuesta de localización los envían los servidores a los clientes como
consecuencia de la recepción de un mensaje de petición de localización.
Un mensaje de respuesta de localización tiene tres elementos, codificados en el
siguiente orden:
Una cabecera de mensaje GIOP.
Una cabecera de respuesta de localización.
El cuerpo de la respuesta de localización.
Cabecera del mensaje de respuesta de localización
Está definido tal como se indica a continuación:
module GIOP {
i
i
i
i
i
i
i
i
D. G ENERAL I NTER -ORB P ROTOCOL
283
enum L o c a t e S t a t u s T y p e _ 1 _ 0 {
UNKNOWN_OBJECT ,
OBJECT_HERE ,
OBJEC T_FORWAR D
};
struct L o c a t e R e p l y H e a d e r _ 1 _ 0 {
unsigned long
request_id ;
LocateStatusType_1_0
locate_status ;
};
};
Los miembros tienen la siguiente definición:
request_id – Se usa para asociar la respuesta con la petición correspondiente.
locate_status – Su valor determina el contenido del cuerpo del mensaje. Los valores
que puede tomar son:
UNKNOWN_OBJECT – El objeto especificado en el mensaje de petición de localiza-
ción es desconocido para el servidor. No se incluye cuerpo en el mensaje.
OBJECT_HERE – El servidor que emite el mensaje de respuesta de localización
puede recibir directamente peticiones para el objeto especificado. No existe
cuerpo en el mensaje.
OBJECT_FORWARD – El cuerpo del mensaje contiene información.
Cuerpo del mensaje de respuesta de localización
El cuerpo del mensaje está vacío, excepto si el valor del campo locate_status es
OBJECT_FORWARD. En ese caso, el cuerpo contiene una IOR que debe usarse para acceder
al objeto especificado en el mensaje de petición de localización.
El cuerpo del mensaje está serializado siguiendo inmediatamente a la cabecera.
D.3.7.
Mensaje de finalización de conexión (CloseConnection)
Son mensajes procedentes de los servidores en GIOP 1.0 y 1.1. Este mensaje informa
al cliente de que el servidor pretende cerrar la conexión y no debería esperar respuestas
para las peticiones futuras. Además, el cliente no recibirá respuestas para las peticiones
pendientes que ni siquiera serán procesadas.
El mensaje de finalización de conexión está formado únicamente por una cabecera
de mensaje GIOP que identifica el tipo de mensaje.
D.3.8.
Mensaje de error (MessageError)
El mensaje de error se envía en respuesta a cualquier mensaje GIOP cuyo número de
versión o tipo de mensaje sea desconocido para el receptor del mensaje. También se puede
utilizar como respuesta al recibir un mensaje con una cabecera mal formada.
El mensaje de error está compuesto únicamente por una cabecera GIOP que identifica
el tipo de mensaje.
i
i
i
i
i
i
i
i
284
D. G ENERAL I NTER -ORB P ROTOCOL
D.4.
Transporte de mensajes GIOP
GIOP está diseñado para ser implementable sobre una gran variedad de protocolos.
La definición de GIOP hace las siguientes suposiciones sobre el comportamiento del
transporte:
El transporte está orientado a conexión.
El transporte es fiable. Específicamente, el transporte garantiza que los bytes se
entregan en el mismo orden que son enviados, al menos una vez, y que existe algún
mecanismo que permite conocer la entrega exitosa.
El transporte puede verse como un flujo de bytes. No se fuerzan limitaciones
arbitrarias del tamaño de los mensajes, fragmentación o alineamiento.
El transporte ofrece notificación de conexiones perdidas.
El modelo de transporte para crear conexiones se puede mapear en el modelo general
de TCP/IP. Un agente publica una dirección de red conocida en una IOR que el
cliente usa cuando inicia la conexión.
El servidor no inicia conexiones, pero está preparado para aceptar peticiones de conexión
(accept en términos de TCP/IP). Otro agente que conoce la dirección (llamado cliente)
puede intentar iniciar conexiones enviando peticiones de conexión a la dirección. El
servidor puede aceptar la petición, creando una nueva y única conexión con el cliente, o
puede rechazar la petición. Una vez abierta la conexión, cualquiera de los dos puede
cerrar la conexión.
i
i
i
i
i
i
i
i
E
E
Interfaces Slice
E.1.
E.2.
E.3.
DUO
ASDF
Property Service
Aunque a lo largo del texto se han ido mostrando fragmentos de las especificaciones
Slice relacionadas con el contexto de cada sección, consideramos adecuado incluir aquí
las ficheros completos a efectos de completitud.
E.1.
DUO
L ISTADO E.1: DUO.ice
#include < Ice / B u i l t i n S e q u e n c e s . ice >
#include < Ice / Identity . ice >
#include < IceStorm / IceStorm . ice >
module DUO {
dictionary <string , Object∗> ObjectPrxDict ;
module Pulse {
interface W { void set ( Ice :: Identity oid ) ; };
};
module IBool {
interface R { idempotent bool get () ; };
interface W { set (bool v , Ice :: Identity oid ) ; };
};
module IByte {
interface R { idempotent byte get () ; };
interface W { void set (byte v , Ice :: Identity oid ) ; };
};
module IInt {
interface R { idempotent int get () ; };
interface W { void set (int v , Ice :: Identity oid ) ; };
};
module ILong {
interface R { idempotent long get () ; };
285
i
i
i
i
i
i
i
i
286
E. I NTERFACES S LICE
interface W { void set ( long v , Ice :: Identity oid ) ; };
};
module IFloat {
interface R { idempotent float get () ; };
interface W { void set (float v , Ice :: Identity oid ) ; };
};
module IString {
interface R { idempotent string get () ; };
interface W { void set (string v , Ice :: Identity oid ) ; };
};
module IByteSeq {
interface R { idempotent Ice :: ByteSeq get () ; };
interface W { void set ( Ice :: ByteSeq v , Ice :: Identity oid ) ; };
};
module IObject {
interface R { idempotent Object∗ get () ; };
interface W { void set (Object∗ v , Ice :: Identity oid ) ; };
};
module Func {
interface Relative {
void inc (short nsteps ) ;
};
};
module Container {
exception A l r e a d y E x i s t s E x c e p t i o n { string key ; };
exception N o S u c h K e y E x c e p t i o n { string key ; };
exception O pe ra ti o nF ai le d { string reason ; };
interface RW ;
interface R { [" freeze : read " , " ami "] idempotent ObjectPrxDict list () ; };
interface W {
// Add and remove external items
[" freeze : write " , " ami "]
void link (string key , Object∗ value ) throws A l r e a d y E x i s t s E x c e p t i o n ;
[" freeze : write " , " ami "]
void unlink (string key ) throws N o S u c h K e y E x c e p t i o n ;
// Create new Container ’ s in this object
[" freeze : write " , " ami "]
Container :: RW∗ create (string key ) throws A l r e a d y E x i s t s E x c e p t i o n ;
// Destroy ∗ this ∗ object
[" freeze : write " , " ami "]
void destroy () ;
};
interface RW extends R , W {};
};
interface Component {
Ice :: StringSeq getAllFacets () ;
};
module Composite {
// Valid operations for byte , int, float , long
const string MIN = " minimum "; // lowest value
const string MAX = " maximum "; // highest value
const string AVG = " average "; // sum (0.. n ) / n
const string MED = " median ";
// sort (0.. n ) [ n /2]
const string HEI = " height ";
// max−min
i
i
i
i
i
i
i
i
E. I NTERFACES S LICE
287
// Valid operations for bool
const string ANY = " any ";
const string ALL = " all ";
// true if any true
// true if all true
// Exceptions
exception I n v a l i d T y p e E x c e p t i o n { string tid ; };
exception N o S u c h O b j e c t E x c e p t i o n { string oid ; };
// Public Factory to create Composites
interface Factory {
Object∗ create (string scalarType ) throws I n v a l i d T y p e E x c e p t i o n ;
void destroy (Object∗ proxy ) throws N o S u c h O b j e c t E x c e p t i o n ;
Ice :: StringSeq g e tA ll ow e dT yp es () ;
};
interface R extends DUO :: Container :: R , DUO :: Component {};
interface W extends DUO :: Container :: RW , DUO :: Component {};
};
module Active {
interface R {
Object∗ getCb () ;
IceStorm :: Topic ∗ getTopic () ;
};
interface W {
void setCbTopic (Object∗ publisher , IceStorm :: Topic ∗ topic ) ;
};
};
};
E.2.
ASDF
L ISTADO E.2: ASDF.ice
#include < Ice / B u i l t i n S e q u e n c e s . ice >
#include < Ice / Identity . ice >
#include " Pr op e rt yS er vi c e . ice "
module ASD {
interface Listener {
idempotent void adv (Object∗ prx ) ;
idempotent void bye ( Ice :: Identity oid ) ;
};
interface Search {
idempotent void lookup ( Listener ∗ cb , string tid ,
P ro pe rt y Se rv ic e :: Properties query ) ;
idempotent void discover ( Listener ∗ cb ) ;
};
interface PropHldr {
idempotent P ro pe rt y Se rv ic e :: Pro pertySet Def ∗ getp () ;
};
};
E.3.
Property Service
L ISTADO E.3: PropertyService.ice
#include " PropertyType . ice "
module P ro pe rt y Se rv ic e {
i
i
i
i
i
i
i
i
288
E. I NTERFACES S LICE
struct Property {
string propertyName ;
P :: T propertyValue ;
};
enum P r o p e r t y M o d e T y p e {
NORMAL ,
READONLY ,
FIXEDNORMAL ,
FIXEDREADONLY ,
UNDEFINED
};
struct PropertyDef {
P :: T propertyValue ;
P r o p e r t y M o d e T y pe propertyMode ;
};
dictionary <string , P :: T > Properties ;
dictionary <string , PropertyDef > PropertyDefs ;
dictionary <string , PropertyModeType > PropertyModes ;
interface
interface
interface
interface
interface
PropertyNamesIterator ;
PropertiesIterator ;
PropertySetFactory ;
Prope rtySetDe f ;
PropertySet ;
exception
exception
exception
exception
exception
exception
exception
exception
exception
C o n s t r a i n t N o t S u p p o r t e d {};
I n v a l i d P r o p e r t y N a m e {};
C o n f l i c t i n g P r o p e r t y {};
P r o p e r t y N o t F o u nd {};
U n s u p p o r t e d T y p e C o d e {};
U n s u p p o r t e d P r o p e r t y {};
U ns up po r te dM od e {};
FixedProperty {};
R e a d O n l y P r o p e r ty {};
enum E xc ep ti o nR ea so n {
rInvalidPropertyName ,
rConflictingProperty ,
rPropertyNotFound ,
rUnsupportedTypeCode ,
rUnsupportedProperty ,
rUnsupportedMode ,
rFixedProperty ,
rReadOnlyProperty
};
struct P r o p e r t y E x c e p t i o n {
E xc ep ti o nR ea so n reason ;
string f a i l i n g P r o p e r t y N a m e ;
};
sequence < PropertyException > P r o p e r t y E x c e p t i o n s ;
exception M u l t i p l e E x c e p t i o n s {
P r o p e r t y E x c e p t i o n s exceptions ;
};
interface P r o p e r t y S e t F a c t o r y {
PropertySet ∗ c r e a t e P r o p e r t y S e t () ;
PropertySet ∗ c r e a t e C o n s t r a i n e d P r o p e r t y S e t ( Properties a l l o w e d P r o p e r t i e s )
throws C o n s t r a i n t N o t S u p p o r t e d ;
PropertySet ∗ c r e a t e I n i t i a l P r o p e r t y S e t ( Properties i n i t i a l P r o p e r t i e s )
throws M u l t i p l e E x c e p t i o n s ;
};
i
i
i
i
i
i
i
i
E. I NTERFACES S LICE
289
interface P r o p e r t y S e t D e f F a c t o r y {
Prop ertySetD ef ∗ c r e a t e P r o p e r t y S e t D e f () ;
Prop ertySetD ef ∗ c r e a t e C o n s t r a i n e d P r o p e r t y S e t D e f (\
PropertyDefs a l l o w e d P r o p e r t y D e f s )
throws C o n s t r a i n t N o t S u p p o r t e d ;
Prop ertySetD ef ∗ c r e a t e I n i t i a l P r o p e r t y S e t D e f (\
PropertyDefs i n i t i a l P r o p e r t y D e f s )
throws M u l t i p l e E x c e p t i o n s ;
};
interface PropertySet {
void defin ePropert y (string theName , P :: T theValue )
throws InvalidPropertyName , ConflictingProperty , UnsupportedTypeCode ,
UnsupportedProperty , R e ad O n l y P r o p e r t y ;
void d e f i n e P r o p e rt i e s ( Properties nproperties )
throws M u l t i p l e E x c e p t i o n s ;
long g e t N u m b e r O f P r o p e r t i e s () ;
void g e t A l l P r o p e r t y N a m e s ( long howMany , out Ice :: StringSeq theNames ,
out P r o p e r t y N a m e s I t e r a t o r ∗ rest ) ;
P :: T g e t P r o p er t y V a l u e (string theName )
throws PropertyNotFound , I n v a l i d P r o p e r t y N a m e ;
bool getProperties ( Ice :: StringSeq theNames , out Properties nproperties ) ;
void g e t A l l P r o p e rt i e s ( long howMany , out Properties nproperties ,
out P r o p e r t i e s I t e r a t o r ∗ rest ) ;
void delet ePropert y (string theName )
throws PropertyNotFound , InvalidPropertyName , FixedProperty ;
void d e l e t e P r o p e rt i e s ( Ice :: StringSeq theNames )
throws M u l t i p l e E x c e p t i o n s ;
bool d e l e t e A l l P r o p e r t i e s () ;
bool i s P r o p e r t y D e f i n e d (string theName ) throws I n v a l i d P r o p e r t y N a m e ;
};
interface Prop ertySetD ef extends PropertySet {
void g e t A l l o w e d P r o p e r t i e s (out PropertyDefs allowedDefs ) ;
void d e f i n e P r o p e r t y W i t h M o d e (string theName , P :: T theValue ,
P r o p e r t y M o d eT y p e theMode )
throws InvalidPropertyName , ConflictingProperty , UnsupportedTypeCode ,
UnsupportedProperty , UnsupportedMode , R e a d O n l y P r o p e r t y ;
void d e f i n e P r o p e r t i e s W i t h M o d e s ( PropertyDefs theDefs )
throws M u l t i p l e E x c e p t i o n s ;
P r o p e r t y M o d e T y pe ge tP ro p er ty Mo d e (string theName )
throws PropertyNotFound , I n v a l i d P r o p e r t y N a m e ;
bool g e t P r o p e r t y Mo d e s ( Ice :: StringSeq theNames , out PropertyModes theModes ) ;
void s et Pr op e rt yM od e (string theName , P r o pe r t y M o d e T y p e theMode )
throws InvalidPropertyName , PropertyNotFound , U ns u pp or te d Mo de ;
void s e t P r o p e r t y Mo d e s ( PropertyModes theModes )
throws M u l t i p l e E x c e p t i o n s ;
};
interface P r o p e r t y N a m e s I t e r a t o r {
void reset () ;
bool nextOne (out string theName ) ;
bool nextN ( long howMany , out Ice :: StringSeq theNames ) ;
void destroy () ;
i
i
i
i
i
i
i
i
290
E. I NTERFACES S LICE
};
interface P r o p e r t i e s I t e r a t o r {
void reset () ;
bool nextOne (out Property aProperty ) ;
bool nextN ( long howMany , out Properties nProperties ) ;
void destroy () ;
};
};
L ISTADO E.4: PropertyType.ice
#include < Ice / B u i l t i n S e q u e n c e s . ice >
module P {
class T {};
class BoolT extends T
{
class ByteT extends T
{
class ByteSeqT extends T
{
class IntT extends T
{
class FloatT extends T
{
class StringT extends T
{
class StringSeqT extends T {
class ObjectT extends T
{
};
bool value ; };
byte value ; };
Ice :: ByteSeq value ; };
int value ; };
float value ; };
string value ; };
Ice :: StringSeq value ; };
Object∗ value ; };
i
i
i
i
i
i
i
i
GNU Free Documentation License
Version 1.3, 3 November 2008
c 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. <http://fsf.org/>
Copyright F
F
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
0.
PREAMBLE
The purpose of this License is to make a manual, textbook, or other functional and useful document “free” in the sense of
freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially
or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while
not being considered responsible for modifications made by others.
This License is a kind of “copyleft”, which means that derivative works of the document must themselves be free in the same
sense. It complements the GNU General Public License, which is a copyleft license designed for free software.
We have designed this License in order to use it for manuals for free software, because free software needs free
documentation: a free program should come with manuals providing the same freedoms that the software does. But this License
is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as
a printed book. We recommend this License principally for works whose purpose is instruction or reference.
1.
APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder
saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited
in duration, to use that work under the conditions stated herein. The “Document”, below, refers to any such manual or work.
Any member of the public is a licensee, and is addressed as “you”. You accept the license if you copy, modify or distribute
the work in a way requiring permission under copyright law.
A “Modified Version” of the Document means any work containing the Document or a portion of it, either copied verbatim,
or with modifications and/or translated into another language.
A “Secondary Section” is a named appendix or a front-matter section of the Document that deals exclusively with the
relationship of the publishers or authors of the Document to the Document’s overall subject (or to related matters) and contains
nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a
Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the
subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.
The “Invariant Sections” are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in
the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary
then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document
does not identify any Invariant Sections then there are none.
The “Cover Texts” are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the
notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a
Back-Cover Text may be at most 25 words.
A “Transparent” copy of the Document means a machine-readable copy, represented in a format whose specification is
available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for
images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable
for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy
made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage
291
i
i
i
i
i
i
i
i
292
F. GNU F REE D OCUMENTATION L ICENSE
subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount
of text. A copy that is not “Transparent” is called “Opaque”.
Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX
input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF
designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats
include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the
DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced
by some word processors for output purposes only.
The “Title Page” means, for a printed book, the title page itself, plus such following pages as are needed to hold,
legibly, the material this License requires to appear in the title page. For works in formats which do not have any title
page as such, “Title Page” means the text near the most prominent appearance of the work’s title, preceding the beginning
of the body of the text.
The “publisher” means any person or entity that distributes copies of the Document to the public.
A section “Entitled XYZ” means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in
parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned
below, such as “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” of such a section
when you modify the Document means that it remains a section “Entitled XYZ” according to this definition.
The Document may include Warranty Disclaimers next to the notice which states that this License applies to the
Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards
disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the
meaning of this License.
2.
VERBATIM COPYING
You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this
License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies,
and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or
control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange
for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and you may publicly display copies.
3.
COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more
than 100, and the Document’s license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly
and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both
covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title
with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying
with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be
treated as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit
reasonably) on the actual cover, and continue the rest onto adjacent pages.
If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machinereadable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location
from which the general network-using public has access to download using public-standard network protocols a complete
Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps,
when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible
at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your
agents or retailers) of that edition to the public.
It is requested, but not required, that you contact the authors of the Document well before redistributing any large number
of copies, to give them a chance to provide you with an updated version of the Document.
4.
MODIFICATIONS
You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided
that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document,
thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you
must do these things in the Modified Version:
i
i
i
i
i
i
i
i
F. GNU F REE D OCUMENTATION L ICENSE
293
A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous
versions (which should, if there were any, be listed in the History section of the Document). You may use the same title
as a previous version if the original publisher of that version gives permission.
B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in
the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if
it has fewer than five), unless they release you from this requirement.
C. State on the Title page the name of the publisher of the Modified Version, as the publisher.
D. Preserve all the copyright notices of the Document.
E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified
Version under the terms of this License, in the form shown in the Addendum below.
G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’s
license notice.
H. Include an unaltered copy of this License.
I. Preserve the section Entitled “History”, Preserve its Title, and add to it an item stating at least the title, year, new
authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled “History” in
the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then
add an item describing the Modified Version as stated in the previous sentence.
J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document,
and likewise the network locations given in the Document for previous versions it was based on. These may be placed
in the “History” section. You may omit a network location for a work that was published at least four years before the
Document itself, or if the original publisher of the version it refers to gives permission.
K. For any section Entitled “Acknowledgements” or “Dedications”, Preserve the Title of the section, and preserve in
the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the
equivalent are not considered part of the section titles.
M. Delete any section Entitled “Endorsements”. Such a section may not be included in the Modified Version.
N. Do not retitle any existing section to be Entitled “Endorsements” or to conflict in title with any Invariant Section.
O. Preserve any Warranty Disclaimers.
If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain
no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do
this, add their titles to the list of Invariant Sections in the Modified Version’s license notice. These titles must be distinct
from any other section titles.
You may add a section Entitled “Endorsements”, provided it contains nothing but endorsements of your Modified Version
by various parties—for example, statements of peer review or that the text has been approved by an organization as the
authoritative definition of a standard.
You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text,
to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover
Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the
same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add
another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for
or to assert or imply endorsement of any Modified Version. 5. COMBINING DOCUMENTS
You may combine the Document with other documents released under this License, under the terms defined in section 4
above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original
documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you
preserve all their Warranty Disclaimers.
The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced
with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of
each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that
section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections
in the license notice of the combined work.
In the combination, you must combine any sections Entitled “History” in the various original documents, forming one section
Entitled “History”; likewise combine any sections Entitled “Acknowledgements”, and any sections Entitled “Dedications”.
You must delete all sections Entitled “Endorsements”.
i
i
i
i
i
i
i
i
294
F. GNU F REE D OCUMENTATION L ICENSE
5.
COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other documents released under this License, and replace the
individual copies of this License in the various documents with a single copy that is included in the collection, provided that
you follow the rules of this License for verbatim copying of each of the documents in all other respects.
You may extract a single document from such a collection, and distribute it individually under this License, provided
you insert a copy of this License into the extracted document, and follow this License in all other respects regarding
verbatim copying of that document.
6.
AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other separate and independent documents or works, in or on
a volume of a storage or distribution medium, is called an “aggregate” if the copyright resulting from the compilation is
not used to limit the legal rights of the compilation’s users beyond what the individual works permit. When the Document
is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves
derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less
than one half of the entire aggregate, the Document’s Cover Texts may be placed on covers that bracket the Document within
the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on
printed covers that bracket the whole aggregate.
7.
TRANSLATION
Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of
section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you
may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections.
You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers,
provided that you also include the original English version of this License and the original versions of those notices and
disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer,
the original version will prevail.
If a section in the Document is Entitled “Acknowledgements”, “Dedications”, or “History”, the requirement (section 4) to
Preserve its Title (section 1) will typically require changing the actual title.
8.
TERMINATION
You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License.
Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights
under this License.
However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the
copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of
the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work)
from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights
from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some
or all of the same material does not give you any rights to use it.
9.
FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time
to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems
or concerns. See http://www.gnu.org/copyleft/.
Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered
version of this License “or any later version” applies to it, you have the option of following the terms and conditions either of that
specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document
does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free
i
i
i
i
i
i
i
i
F. GNU F REE D OCUMENTATION L ICENSE
295
Software Foundation. If the Document specifies that a proxy can decide which future versions of this License can be used, that
proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Document.
10.
RELICENSING
“Massive Multiauthor Collaboration Site” (or “MMC Site”) means any World Wide Web server that publishes copyrightable
works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example
of such a server. A “Massive Multiauthor Collaboration” (or “MMC”) contained in the site means any set of copyrightable
works thus published on the MMC site.
“CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons
Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future
copyleft versions of that license published by that same organization.
“Incorporate” means to publish or republish a Document, in whole or in part, as part of another Document.
An MMC is “eligible for relicensing” if it is licensed under this License, and if all works that were first published under this
License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover
texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008.
The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time
before August 1, 2009, provided the MMC is eligible for relicensing.
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
Glosario
actuador
Dispositivo electrónico con capacidad para modificar el valor de una magnitud física.
adaptador
[de objetos] En un servidor, estructura ligada a uno o más puntos de conexión
(endpoints) que permite acceder remotamente a uno o varios objetos distribuidos.
co-localizado
(colocated) Se aplica a objetos o servidores para indicar que su implementación
comparte la misma máquina, proceso, espacio de memoria, etc., que un potencial
cliente; circunstancias que permiten realizar optimizaciones en recursos y tiempo.
domótica
Conjunto de tecnologías orientadas al aumento del confort, la seguridad y el
aprovechamiento de recursos en el hogar.
e-health
Aplicación de la tecnología para la asistencia de personas mediante cuidados
médicos, normalmente fuera de las instalaciones sanitarias.
endpoint
Especifica un punto lógico de conexión en el que puede escuchar un servidor en
espera de peticiones.
inmótica
Conjunto de tecnologías orientadas a la mejora del confort, la seguridad y la
optimización de recursos en grandes edificios, comúnmente llamados inteligentes.
observador
Entidad software (objeto o función) que es invocado por una segunda entidad
observable para notificar un cambio Ş Patrón de diseño [GHJV96] que especifica
este comportamiento.
retrollamada
Es una referencia a una función o método, normalmente escrita por el usuario. Esta
referencia se le pasa a una segunda entidad (como argumento de una función) para
que sea invocada al producirse cierto evento o condición.
297
i
i
i
i
i
i
i
i
298
F. GNU F REE D OCUMENTATION L ICENSE
sensor
Dispositivo electrónico capaz de detectar y/o medir una magnitud física para
ofrecerla como un dato a un sistema de cómputo.
serialización
Procedimiento por el cual una entidad software de cualquier tipo se puede representar
como una secuencia de bytes con objeto de ser almacenada o enviada a través de
una red de comunicaciones.
sirviente
Es la porción de código encargada de realizar una tarea concreta como respuesta a la
invocación de un método de un objeto remoto. En los MDOO el sirviente suele ser
la instancia de una clase proporcionada por el usuario y que especializa las clases
generadas por el compilador de interfaces (el esqueleto).
transductor
Un dispositivo que puede convertir una magnitud física o señal en, o a partir de, una
señal electrónica. Engloba por tanto a sensores y actuadores.
i
i
i
i
i
i
i
i
Bibliografía
[Abd04]
T. Abdelzaher, B. Blum, Q. Cao, Y. Chen, D. Evans, J. George, S. George, L. Gu, T. He,
S. Krishnamurthy, L. Luo, S. Son, J. Stankovic, R. Stoleru, y A. Wood. EnviroTrack:
towards an environmental computing paradigm for distributed sensor networks. En
Distributed Computing Systems, 2004. Actas de 24th International Conference on,
páginas 582–589, 2004.
[All06]
OSGi Alliance. OSGi Service Platform, Core Specification Release 4, Version 4.0.1.
Technical report, Open Service Gateway Initiative, 2006. url: http://www.osgi.
org/Release4/Download.
[arc07]
Arch Rock Primer Pack product gateway datasheet, 2007. Product Catalog.
[AXIa]
AXIS 212 Network Camera. url: http://www.axis.com/products/cam_212/.
[AXIb]
AXIS 214 Network Camera. url: http://www.axis.com/products/cam_214/.
[AY05]
K. Akkaya y M. Younis. A survey on routing protocols for wireless sensor networks.
Ad Hoc Networks, 3(3):325–349, May 2005.
[AYS07]
A. Al-Yasiri y A. Sunley. Data aggregation and middleware in wireless sensor
networks. En Sensor and theory applicatios XIV (SENSOR07), Journal of Physics:
Conference Series 76, 2007., 2007.
[Bak97]
S. Baker. CORBA Distributed Objects. Addison-Wesley, 1997.
+
[BBD 02]
R. Barr, J. C. Bicket, D. S. Dantas, B. Du, T. W. Danny, K. Bing, Z. Emin, y G. Sirer.
On the Need for System-Level Support for Ad Hoc and Sensor Networks. Operating
System Review, 36:1–5, 2002.
[BBK02]
M. Balazinska, H. Balakrishnan, y D. Karger. INS/Twine: A Scalable Peer-to-Peer
Architecture for Intentional Resource Discovery. En Actas de First International
Conference on Pervasive Computing, páginas 195–210, 2002.
[BFG06]
L. Benini, E. Farella, y C. Guiducci. Wireless sensor networks: Enabling technology
for ambient intelligence. Microelectronics Journal, 37(12):1639–1649, December
2006.
[BHS03]
A. Boulis, C. C. Han, y M. B. Srivastava. Design and implementation of a framework
for efficient and programmable sensor networks. En MobiSys ’03: Actas de 1st
international conference on Mobile systems, applications and services, páginas 187–
200, New York, NY, USA, 2003. ACM.
[BHSS07]
A. Boulis, C. C. Han, R. Shea, y M. B. Srivastava. SensorWare: Programming sensor
networks beyond code update and querying. Pervasive Mob. Comput., 3(4):386–412,
2007.
299
i
i
i
i
i
i
i
i
300
BIBLIOGRAFÍA
[BKN07]
M. Brzozowski, R. Karnapke, y J. Nolte. IMPACT - A Family of Cross-Layer
Transmission Protocols for Wireless Sensor Networks. En Performance, Computing,
and Communications Conference, 2007. IPCCC 2007. IEEE Internationa, páginas
619–625, 2007.
[BLV09]
R. Bosman, J. Lukkien, y R. Verhoeven. An integral approach to programming sensor
networks. En Actas de Consumer Communications and Networking Conference, IEEE,
Enero 2009. url: http://www.win.tue.nl/san/wsp.
[BN84]
A. D. Birrell y B. J. Nelson. Implementing remote procedure calls. ACM Trans.
Comput. Syst., 2(1):39–59, 1984.
[BT04]
Bluetooth SIG. Specification of the Bluetooth System v2.0, Noviembre 2004. url:
http://www.bluetooth.org.
[Cam02]
C. Campo. Service Discovery in Pervasive Multi-Agent Systems. En Workshop on
Ubiquitous Agents and embedded, wearable and mobile devices, 2002.
[CCM06]
Object Management Group. CORBA Component Model Specification, edición Versión
4.0, Abril 2006. url: http://www.omg.org/docs/formal/06-04-01.pdf.
[CGG+ 05]
C. Curino, M. Giani, M. Giorgetta, A. Giusti, A. L. Murphy, y G. P. Picco. TinyLIME:
bridging mobile and sensor networks through middleware. Pervasive Computing
and Communications, 2005. PerCom 2005. Third IEEE International Conference on,
páginas 61–72, 2005.
[CGMA06]
C. Campo, C. García, A. Marín, y F. Almenárez. PDP: a lightweight discovery
protocol for local-scope interactions in wireless ad hoc networks. Comput. Networks,
50(17):3264–3283, December 2006.
[CJYF02]
D. Chakraborty, A. Joshi, Y. Yesha, y T. Finin. GSD: A Novel Group-based Service
Discovery Protocol for MANETS. En In 4th IEEE Conference on Mobile and Wireless
Communications Networks (MWCN, páginas 140–144, 2002.
[CMnP+ 05] C. Campo, M. Muñoz, J. C. Perea, A. Marin, y C. Garcia. PDP and GSDL: a
new service discovery middleware to support spontaneous interactions in pervasive
systems. En Third IEEE International Conference on Pervasive Computing and
Communications Workshops, páginas 178–182, March 2005.
[CMP06]
P. Ciciriello, L. Mottola, y G. P. Picco. Building virtual sensors and actuators
over logical neighborhoods. En MidSens ’06: Actas de International Workshop on
Middleware for Sensor Networks, páginas 19–24, New York, NY, USA, 2006. ACM.
[COR02]
Object Management Group. The Common Object Request Broker: Architecture and
Specification, edición 3.0, Junio 2002. url: http://www.omg.org/docs/formal/
98-12-01.pdf.
[Cou81]
Xerox Corporation, Stamford, Connecticut. Courier: The remote procedure call
protocol, Diciembre 1981.
[CSAT06]
A. Chalak, V. Sivaraman, N. Aydin, y D. Turgut. A Comparative Study of Routing
Protocols in Wireless Sensor Networks. En Actas de IEEE Thirteenth International
Conference on Telecommunications (ICT), May 2006.
[cso]
csoap client/server SOAP library in pure C. url: http://csoap.sourceforge.
net/.
[DAV04]
A. Dunkels, J. Alonso, y T. Voigt. Making TCP/IP Viable for Wireless Sensor
Networks. En Actas de The First European Workshop on Wireless Sensor Networks
(EWSN), 2004.
i
i
i
i
i
i
i
i
BIBLIOGRAFÍA
301
[DBS+ 01]
K. Ducatel, M. Bogdanowicz, F. Scapolo, J. Leijten, y J. C. Burgelman. Scenarios for
ambiente intelligence in 2010. Technical report, Information Society Technologies
Advisory Group, Febrero 2001.
[DH98]
S. Deering y R. Hinden. Internet Protocol, Version 6 (IPv6) Specification. RFC
2460 (Draft Standard), Diciembre 1998. Updated by RFC 5095. url: http:
//www.ietf.org/rfc/rfc2460.txt.
[dJ02]
I. de Jong. Web Services/SOAP and CORBA. Technical report, Abril 2002. url:
http://www.xs4all.nl/~irmen/comp/CORBA_vs_SOAP.html.
[DT80]
L. P. Deutsch y E. A. Taft. Requirements for a exceptional programming environment.
Technical report, Xerox Palo Alto Research Center, 1980.
[Dun03]
A. Dunkels. Full TCP/IP for 8-Bit Architectures. En Actas de First International
Conference on Mobile Applications, Systems and Services, MOBISYS’03, Mayo 2003.
[EGHK99]
D. Estrin, R. Govindan, J. Heidemann, y S. Kumar. Next Century Challenges: Scalable
Coordination in Sensor Networks. En Actas de ACM/IEEE International Conference
on Mobile Computing and Networking, páginas 263–270, Seattle, Washington, USA,
Agosto 1999. ACM. url: http://www.isi.edu/~johnh/PAPERS/Estrin99e.
html.
[EHK+ 07]
L. Evers, P. J. M. Havinga, J. Kuper, M. E. M. Lijding, y N. Meratnia. SensorScheme:
Supply chain management automation using Wireless Sensor Networks. En Emerging
Technologies and Factory Automation, 2007. ETFA. IEEE Conference on, páginas
448–455, 2007.
[Eis06]
M. Eisler. XDR: External Data Representation Standard. RFC 4506 (Standard), Mayo
2006. url: http://www.ietf.org/rfc/rfc4506.txt.
[eOR]
OpenFusion e*ORB. url: http://www.prismtechnologies.com/.
[EWS]
EWS: Embedded Web Services, Grupo ARCO. url: http://arco.esi.uclm.es/
ews.
[FHK04]
C. Frank, V. Handziski, y H. Karl. Service Discovery in Wireless Sensor Networks.
Technical report, Technical University Berlin, March 2004.
[FRH04]
C. L. Fok, G. C. Roman, y G. Hackmann. A Lightweight Coordination Middleware
for Mobile Computing. páginas 135–151. 2004.
[FRL05]
C. L. Fok, G. C. Roman, y C. Lu. Mobile agent middleware for sensor networks: an
application case study. En Information Processing in Sensor Networks, 2005. IPSN
2005. Fourth International Symposium on, páginas 382–387, 2005.
[GEK08]
Y. Gadallah y H. El-Kassabi. A WSN/MANET Hybrid Protocol for Routing Data in
Heterogeneous Wireless Sensor Networks. En Wireless Communications and Mobile
Computing Conference, 2008. IWCMC ’08, páginas 523–528, 2008.
[Gel85]
D. Gelernter. Generative communication in Linda.
Programming Languages and Systems, 7:80–112, 1985.
[GES+ 04]
L. Girod, J. Elson, T. Stathopoulos, M. Lukac, y D. Estrin. Emstar: a software
environment for developing and deploying wireless sensor networks. En Actas de
2004 USENIX Technical Conference, páginas 283–296, 2004.
[GGG05]
Ramakrishna G., Omprakash G., y Ramesh G. Macro-programming Wireless Sensor
Networks using Kairos. En In DCOSS, páginas 126–140. Springer, 2005.
[GHJV96]
E. Gamma, R. Helm, R. Johnson, y J. Vlissides. Dessign Patterns. Addison-Wesley,
1996.
ACM Transactions on
i
i
i
i
i
i
i
i
302
BIBLIOGRAFÍA
[GHM+ 03]
M. Gudgin, M. Hadley, N. Mendelsohn, J. Moreau, y H. F. Nielsen. SOAP Version 1.2
Part 1: Messaging Framework. World Wide Web Consortium, 2003.
[Gib04]
Bionic Buffalo Corporation. TatankaT M CORBA Tools and Components, 2004. url:
http://www.tatanka.com/prod/info/gibraltar.html.
[GKS02]
A. Gokhale, B. Kumar, y A. Sahuguet. Reinventing the Wheel? CORBA vs. Web
Services. En Actas de la 11o International World Wide Web Conference, Mayo 2002.
url: http://www2002.org/CDROM/alternate/395/.
[GPK99]
E. Guttman, C. Perkins, y J. Kempf. Service Templates and Service: Schemes. RFC
2609 (Proposed Standard), Junio 1999. url: http://www.ietf.org/rfc/rfc2609.
txt.
[GPVD99]
E. Guttman, C. Perkins, J. Veizades, y M. Day. Service Location Protocol, Version
2. RFC 2608 (Proposed Standard), Junio 1999. Updated by RFC 3224. url:
http://www.ietf.org/rfc/rfc2608.txt.
[Gro]
Object Managemet Group. Catalog of OMG IDL / Language Mappings Specifications. url: http://www.omg.org/technology/documents/idl2x_spec_
catalog.htm.
[GSP+ 03]
C. Gill, V. Subramonian, J. Parsons, H. M. Huang, S. Torri, D. Niehaus, y D. Stuart.
ORB middleware evolution for networked embedded systems. En Actas de Eighth
International Workshop on Object-Oriented Real-Time Dependable Systems, 2003.
(WORDS 2003)., páginas 169–176, Enero 2003.
[Hae06]
T. Haenselmann. Sensornetworks. 2006.
[Hau01]
O. Haugan. Configuration and Code Generation Tools for Middleware Targeting
Small, Embedded Devices. Master’s thesis, Washington State University, Diciembre
2001.
[Hen04]
M. Henning. A New Approach to Object-Oriented Middleware. Internet Computing,
IEEE, 8(1):66–75, 2004.
[Hen09]
M. Henning. Choosing Middleware: Why Performance and Scalability do (and do not)
Matter, 2009. url: http://zeroc.com/articles/IcePerformanceWhitePaper.
pdf.
[HFRL06]
G. Hackmann, C. L. Fok, G. C. Roman, y C. Lu. Agimone: Middleware Support for
Seamless Integration of Sensor and IP Networks. 2006.
[HKB99]
W. R. Heinzelman, J. Kulik, y H. Balakrishnan. Adaptive protocols for information
dissemination in wireless sensor networks. En MobiCom ’99: Actas de 5th Annual
ACM/IEEE International Conference on Mobile Computing and Networking, páginas
174–185, New York, NY, USA, 1999. ACM.
[HKFK03]
V. Handziski, A. Kopke, C. Frank, y H. Karl. Semantic Addressing for Wireless Sensor
Networks. Technical report, November 2003.
[HM06]
S. Hadim y N. Mohamed. Middleware: middleware challenges and approaches for
wireless sensor networks. Distributed Systems Online, IEEE, 7(3):1–1, March 2006.
[HMCP04]
W. B. Heinzelman, A. L. Murphy, H. S. Carvalho, y M. A. Perillo. Middleware to
support sensor network applications. IEEE Network, 18(1):6–14, 2004.
[HMM+ ]
W. Horré, S. Michiels, N. Matthys, W. Joosen, y P. Verbaeten. On the Integration of
Sensor Networks and General Purpose IT Infrastructure.
[HR06]
K. Henricksen y R. Robinson. A survey of middleware for sensor networks: state-ofthe-art and future directions. En MidSens ’06: Actas de International Workshop on
Middleware for Sensor Networks, páginas 60–65, New York, NY, USA, 2006. ACM.
i
i
i
i
i
i
i
i
BIBLIOGRAFÍA
[HS08]
M. Henning y M. Spruiell. Distributed Programming with Ice. ZeroC Inc., Mayo
2008. Revision 3.3.0.
[HV99]
G. Holland y N. Vaidya. Analysis of TCP Performance over Mobile Ad Hoc Networks.
En Actas de MOBISYS’99, Agosto 1999.
[HX05]
J. Helander y Y. Xiong. Secure Web services for low-cost devices. En Eighth IEEE
International Symposium on Object-Oriented Real-Time Distributed Computing, 2005,
2005.
[Ice]
Embedded Ice. url: http://www.zeroc.com/icee/index.html.
[IDM]
IDM: Inter-Domain Messaging, Grupo ARCO. url: http://arco.esi.uclm.es/
IDM.
[IEE85]
Institute of Electrical y Electronic Engineers. IEEE 754-1985 Standard for Binary
Floating-Point Arithmetic, ANSI/IEEE Standard 754-1985, 1985.
[IGE00]
C. Intanagonwiwat, R. Govindan, y D. Estrin. Directed Diffusion: A Scalable and
Robust Communication Paradigm for Sensor Networks. En ACM International
Conference on Mobile Computing and Networking (MOBICOM’00, páginas 56–67,
2000.
[JOW+ 02]
P. Juang, H. Oki, Y. Wang, M. Martonosi, L. S. Peh, y D. Rubenstein. Energy-Efficient
Computing for Wildlife Tracking: Design Tradeoffs and Early Experiences with
ZebraNet. En ASPLOS-X 2002: Actas de la 10a 10th international conference on
Architectural support for programming languages and operating systems, volume 37,
páginas 96–107, New York, NY, USA, Octubre 2002. ACM Press.
[Kab06]
S. Kabadayi. Middleware for On-Demand Access to Sensor Networks. Technical
report, University of Texas, October 2006.
[KBL07]
T. Kobialka, R. Buyya, y C. Leckie. Open Sensor Web Architecture: Stateful Web
Services. En Actas del Third International Conference on Intelligent Sensors, Sensor
Networks and Information Processing (ISSNIP) 2007, 2007.
[KCBC02]
F. Kon, F. Costa, G. Blair, y R. Campbell. The Case for Reflective Middleware.
Adaptive middleware (special issue), 45:33–38, Junio 2002.
[KHH05]
M. Kuorilehto, M. Hännikäinen, y T. D. Hämäläinen. A survey of application
distribution in wireless sensor networks. EURASIP J. Wirel. Commun. Netw., 5(5):774–
788, 2005. url: http://portal.acm.org/citation.cfm?id=1115500.
[KKKP99]
J. M. Kahn, R. H. Katz, Katz, y K. S. J. Pister. Next Century Challenges: Mobile
Networking for Smart Dust, 1999.
[KKN07]
M. Kruger, R. Karnapke, y J. Nolte. In-network processing and collective operations
using the COCOS-framework. En Emerging Technologies and Factory Automation,
2007. ETFA. IEEE Conference on, páginas 1194–1201, 2007.
[KMS07]
N. Kushalnagar, G. Montenegro, y C. Schumacher. IPv6 over Low-Power Wireless
Personal Area Networks (6LoWPANs): Overview, Assumptions, Problem Statement,
and Goals. RFC 4919 (Informational), Agosto 2007. url: http://www.ietf.org/
rfc/rfc4919.txt.
[KN06]
R. Karnapke y J. Nolte. COPRA - A Communication Processing Architecture for
Wireless Sensor Networks. En Euro-Par 2006 Parallel Processing, páginas 951–960,
2006.
[KSSZ97]
P. Kalyanasundaram, A. S. Sethi, C. M. Sherwin, y D. Zhu. A spreadsheet-based
scripting environment for SNMP. En Integrated Network Management V, páginas
752–765. Chapman and Hall, 1997.
303
i
i
i
i
i
i
i
i
304
BIBLIOGRAFÍA
[LC02]
P. Levis y D. Culler. Mate: A tiny virtual machine for sensor networks. En International
Conference on Architectural Support for Programming Languages and Operating
Systems, San Jose, CA, USA, Octubre 2002.
[LGC05]
P. Levis, D. Gay, y D. Culler. Active sensor networks. En NSDI’05: Actas de 2nd
conference on Symposium on Networked Systems Design & Implementation, páginas
343–356, Berkeley, CA, USA, 2005. USENIX Association.
[lib]
XML-RPC for C and C++, A lightweight RPC library based on XML and HTTP. url:
http://xmlrpc-c.sourceforge.net/.
[LLS+ 03]
S. Li, Y. Lin, S. H. Son, J. A. Stankovic, y Y. Wei. Event detection services using
data service middleware in distributed sensor networks. En Information Processing in
Sensor Networks, página 557. Springer, Enero 2003.
[LM03]
T. Liu y M. Martonosi. Impala: A Middleware System for Managing Autonomic,
Parallel Sensor Systems. En In PPoPP ’03: Actas de la 9a ACM SIGPLAN symposium
on Principles and practice of parallel programming, páginas 107–118. ACM Press,
2003.
[LSZM04]
T. Liu, C. M. Sadler, P. Zhang, y M. Martonosi. Implementing Software on ResourceConstrained Mobile Sensors: Experiences with Impala and ZebraNet. Princeton
University, ACM, Junio 2004.
[Mal98]
G. Malkin. RIP Version 2. RFC 2453 (Standard), Noviembre 1998. Updated by RFC
4822. url: http://www.ietf.org/rfc/rfc2453.txt.
[Mar05]
P. J. Marrón. Middleware Approaches for Sensor Networks. Summer School on
WSNs and Smart Objects, Agosto 2005.
[Mar08]
J. Martínez de Sousa. Ortografía y ortotipografía del español actual. Trea, 2008.
[MFHH05]
S. R. Madden, M. J. Franklin, J. M. Hellerstein, y W. Hong. TinyDB: an acquisitional
query processing system for sensor networks. ACM Trans. Database Syst., 30(1):122–
173, 2005.
[MKHC07]
G. Montenegro, N. Kushalnagar, J. Hui, y D. Culler. Transmission of IPv6 Packets
over IEEE 802.15.4 Networks. RFC 4944 (Proposed Standard), Septiembre 2007. url:
http://www.ietf.org/rfc/rfc4944.txt.
[ML02]
F. Moya y J. C. López. SENDA: An Alternative to OSGi for Large Scale Domotics.
En Actas de Networks, páginas 165–176. World Scientific Publishing, Agosto 2002.
[MLM+ 05] P. J. Marrón, A. Lachenmann, D. Minder, J. Hähner, R. Sauter, y K. Rothermel.
TinyCubus: A Flexible and Adaptive Framework for Sensor Networks. En Actas
de Second European Workshop on Wireless Sensor Networks (EWSN 2005), páginas
278–289, January 2005.
[MML02]
J. Morena, F. Moya, y J. C. López. Implementación de un ORB para Dispositivos
Empotrados. En Actas de Symposium on Informatics and Telecommunications, 2002.
[Moy03]
F. Moya. Infraestructura de comunicaciones para la creación, modelado y gestión
de servicios y redes para el hogar. PhD thesis, Universidad Politécnica de Madrid,
Escuela Técnica Superior de Ingenieros de Telecomunicación, 2003.
[MPHS05]
R. Marin-Perianu, P. Hartel, y H. Scholten. A Classification of Service Discovery
Protocols. Technical report, University of Twente, The Netherlands, Junio 2005. url:
http://eprints.eemcs.utwente.nl/735/.
[MPSH06]
R. S. Marin-Perianu, J. Scholten, y P. J. M. Havinga. Distributed Service Discovery
for Heterogeneous Wireless Sensor Networks. Technical Report TR-CTIT-06-42,
Enschede, Junio 2006.
i
i
i
i
i
i
i
i
BIBLIOGRAFÍA
305
[MPSHH08] R. S. Marin-Perianu, J. Scholten, P. J. M. Havinga, y P. H. Hartel. Cluster-based
service discovery for heterogeneous wireless sensor networks. International Journal
of Parallel, Emergent and Distributed Systems, 23(4):325–346, Agosto 2008.
[MVV+ 09]
F. Moya, D. Villa, F. J. Villanueva, J. Barba, F. Rincón, y J. C. López. Embedding
standard distributed object-oriented middlewares in wireless sensor networks. Wireless
Communications and Mobile Computing, 9(3):335–345, 2009.
[NA02]
W. Nagel y N. Anderson. A Protocol for Representing Individual Hardware Devices
as Objects in a CORBA Networt. En Actas de Real-time and Embedded Distributed
Object Computing Workshop, 2002.
[Nel81]
B. J. Nelson. Remote Procedure Call. Technical report, Xerox Palo Alto Research
Center, 1981.
[Nesa]
nesC: A Programming Language for Deeply Networked Systems.
//nescc.sourceforge.net/.
[NESb]
NEST: Network Embedded Systems Technology. url: http://www.darpa.mil/
ipto/programs/nest/nest.asp.
[NXT]
Lego NXT technology.
default.aspx.
[Obj98]
Object Managemet Group. CORBAtelecoms: Telecommunications Domain Specifications, Junio 1998. url: http://www.omg.org/cgi-bin/doc?formal/98-07-12.
[Obj00]
Object Managemet Group. Property Service Specification, Abril 2000. url: http:
//www.omg.org/docs/formal/00-06-22.pdf.
[Obj01a]
Object Managemet Group. Event Service Specification, edición 1.1, Marzo 2001. url:
http://www.omg.org/docs/formal/01-03-01.pdf.
[Obj01b]
Object Managemet Group. Naming Service Specification, Febrero 2001.
http://www.omg.org/docs/formal/01-02-65.pdf.
[Obj02]
Object Management Group. Minimum CORBA Specification, edición 2.3, Agosto
2002. url: http://www.omg.org/docs/formal/02-08-01.pdf.
[Obj03]
Object Management Group. Smart Transducers Interface Specification, edición
Versión 1.0, Enero 2003. url: http://www.omg.org/docs/formal/03-01-01.
pdf.
[Obj04]
Object Management Group. Internet Inter-ORB Protocol, edición 3.0.3, Marzo 2004.
url: http://www.omg.org/cgi-bin/doc?formal/04-03-12.
[Obj08a]
Object Management Group. CORBA Interoperability Architecture, edición Versión 3.1,
Enero 2008. url: http://www.omg.org/spec/CORBA/3.1/Interoperability/
PDF.
[Obj08b]
Object Management Group. CORBA Messaging, edición Versión 3.1, Enero 2008. url:
http://www.omg.org/spec/CORBA/3.1/Interfaces/PDF.
[OKK04]
C. S. Oh, Y. B. Ko, y J. H. Kim. A Hybrid Service Discovery for Improving Robustness
in Mobile Ad Hoc Networks. En InternationalConference on Dependable Systems
and Networks, July 2004.
[OMG]
Object Management Group. url: http://www.omg.org/.
[Org06]
Organization for the Advancement of Structured Information Standards. OASIS
Reference Model for Service Oriented Architecture 1.0, Octubre 2006. url: http:
//docs.oasis-open.org/soa-rm/v1.0/soa-rm.pdf.
url: http:
url: http://mindstorms.lego.com/eng/Overview/
url:
i
i
i
i
i
i
i
i
306
BIBLIOGRAFÍA
[OVB05]
F. Outay, V. Vêque, y R. Bouallègue. Survey of Service Discovery Protocols and
Benefits of Combining Service and Route Discovery. International Journal of
Computer Science and Networking Security, 7(11):85–92, 2005.
[PH05]
D. Puccinelli y M. Haenggi. Wireless sensor networks: applications and challenges of
ubiquitous sensing. Circuits and Systems Magazine, IEEE, 5(3):19–31, 2005.
[PH08]
D. Puccinelli y M. Haenggi. Arbutus: Network-Layer Load Balancing for Wireless
Sensor Networks. En Wireless Communications and Networking Conference, 2008.
WCNC 2008. IEEE, páginas 2063–2068, 2008.
[PK02]
C. Perkins y R. Koodli. Service Discovery in On-Demand Ad Hoc Networks. Technical
report, IETF, Octubre 2002.
[PKGZ08]
B. Priyantha, A. Kansal, M. Goraczko, y F. Zhao. Tiny Web Services for Sensor Device
Interoperability. En IPSN ’08: Actas de 7th International Conference on Information
Processing in Sensor Networks, páginas 567–568, Washington, DC, USA, 2008. IEEE
Computer Society.
[PRP05]
A. Puder, K. Römer, y F. Pilhofer. Distributed Systems Architecture: A Middleware
Approach. Morgan Kaufman, 2005.
[PST07]
E. J. Pauwels, A. A. Salah, y R. Tavenard. Sensor Networks for Ambient Intelligence.
En Multimedia Signal Processing, 2007. MMSP 2007. IEEE 9th Workshop on, páginas
13–16, 2007.
[Pyt]
Python. url: http://www.python.org/.
[R0̈4]
K. Römer. Programming Paradigms and Middleware for Sensor Networks. En GI/ITG
Workshop on Sensor Networks, páginas 49–54, 2004.
[RBW01]
G. Rivera, R. Brega, y F. H. Wullschleger. Light-Weight Distributed Computing
for Embedded Systems. First-Hand Experiences with the Simple Object Access
Protocol for Mobile Robots. En Actas de EUROBOT’2001, 2001. url: http:
//xo2.org/Docs/eurobot01soap.pdf.
[RDB+ 09]
F. Rincón, J. Dondo, J. Barba, F. Moya, y J. C. López. Supporting Operating
Systems for Reconfigurable Computing: A Distributed Service Oriented Approach. En
International Conference on Engineering of Reconfigurable Systems and Algorithms,
July 2009.
[RFC03]
G. Rodrigues, C. Ferraz, y S. V. Cavalcante. A CORBA–Based Surrogate Model on
IP Networks. En Actas de 21st Brazilian Symposium on Computer Networks – Natal,
RN, Brazil. Sociedade Brasileira de Computacao – SBC, Mayo 2003.
[RKC01]
M. Roman, F. Kon, y R. H. Campbell. Reflective middleware: From your desk to your
hand. IEEE Distributed Systems Online, 2, 2001.
[RKM02]
K. Römer, O. Kasten, y F. Mattern. Middleware Challenges for Wireless Sensor
Networks. SIGMOBILE: Mobile Computing and Communications Review, 6(4):59–
61, Octubre 2002.
[RLH+ 97]
Y. Rekhter, P. Lothberg, R. Hinden, S. Deering, y J. Postel. An IPv6 Provider-Based
Unicast Address Format. RFC 2073 (Proposed Standard), Enero 1997. Obsoleted by
RFC 2374. url: http://www.ietf.org/rfc/rfc2073.txt.
[RMDS02]
K. Römer, F. Mattern, T. Dübendorfer, y J. Senn. Infrastructure for Virtual Counterparts
of Real World Objects. Technical report, 2002.
[RMKC00]
M. Roman, M. D. Mickunas, F. Kon, y R. Campbell. LegORB and ubiquitous CORBA.
En Proc. IFIP/ACM Middleware’2000 Workshop on Reflective Middleware (RM2000,
páginas 1–2, 2000.
i
i
i
i
i
i
i
i
BIBLIOGRAFÍA
307
[Rod]
P. Rodriguez. Sistemas Operativos Distribuidos y de Tiempo Real. E.T.S.E
de Telecomunicación. url: http://alen.ait.uvigo.es/~pedro/pub/sodtr/
index.html.
[RSC+ 99]
M. Román, A. Singhai, D. Carvalho, C. K. Hess, y R. H. Campbell. Integrating PDAs
into Distributed Systems: 2K and PalmORB. En HUC ’99: Actas de 1st international
symposium on Handheld and Ubiquitous Computing, páginas 137–149, London, UK,
1999. Springer-Verlag.
[SGaV+ 04] E. Souto, G. Guimarães, G. Vasconcelos, M. Vieira, N. Rosa, y C. Ferraz. A messageoriented middleware for sensor networks. En MPAC ’04: Actas de 2nd workshop on
Middleware for pervasive and ad-hoc computing, páginas 127–134, New York, NY,
USA, 2004. ACM.
[SJS01]
C. Srisathapornphat, C. Jaikaeo, y C. C. Shen. Sensor Information Networking
Architecture and Applications. IEEE Personal Communications, 8:52–59, 2001.
[SKLN08]
T. Senner, R. Karnapke, A. Lagemann, y J. Nolte. A Combined Routing Layer
for Wireless Sensor Networks and Mobile Ad-Hoc Networks. En SENSORCOMM
’08: Actas de 2008 Second International Conference on Sensor Technologies and
Applications, páginas 147–153, Washington, DC, USA, 2008. IEEE Computer Society.
[Sph]
Logitech QuickCam Sphere.
url: http://www.logitech.com/index.cfm/
webcam_communications/webcams/devices/3480&cl=roeu,en.
[Sri95a]
R. Srinivasan. RPC: Remote Procedure Call Protocol Specification Version 2.
RFC 1831 (Proposed Standard), Agosto 1995. url: http://www.ietf.org/rfc/
rfc1831.txt.
[Sri95b]
R. Srinivasan. XDR: External Data Representation Standard. RFC 1832 (Draft
Standard), Agosto 1995. Obsoleted by RFC 4506. url: http://www.ietf.org/
rfc/rfc1832.txt.
[Sta]
Crossbow Stargate.
url: http://www.xbow.com/products/Product_pdf_
files/Wireless_pdf/Stargate_Datasheet.pdf.
[Sun01]
Sun Microsystems. Jini Architecture Specification, edición 1.2, Diciembre 2001. url:
http://www.sun.com/.
[Sun06]
Sun Microsystems. Jini Technology Surrogate Architecture Specification, Junio 2006.
url: https://surrogate.dev.java.net/.
[SXG+ 04]
V. Subramonian, G. Xing, C. Gill, C. Lu, y R. Cytron. Middleware specialization for
memory-constrained networked embedded systems. En in 9th IEEE Real-Time and
Embedded Technology and Applications Symposium, 2004.
[SXGC03]
V. Subramonian, G. Xing, C. Gill, y R. Cytron. The design and performance of special
purpose middleware: A sensor networks case study. Enero 2003.
[TIN]
TINI: The InterNet Interface.
microcontrollers/tini/.
[TMN01]
International Telecommunication Union. Telecommunications management network.
ITU-T Recommendation M.3120. CORBA generic network and network element level
information model, 2001.
[Uni00]
The Unicode Standard, Version 3.0, 2000.
unicode/uni2book/u2.html.
url: http://www.maxim-ic.com/products/
url: http://www.unicode.org/
[UPn00]
UPnP Forum. Universal Plug and Play Device Architecture 1.0, Junio 2000.
[UVV+ 09]
G. Urzaiz, D. Villa, F. J. Villanueva, F. Moya, F. Rincon, J. C. Lopez, y L. A. Munoz. A
novel communication platform to enable the collaboration of Autonomous Underwater
Vehicles. En Actas de International Conference on Wireless Networks, Julio 2009.
i
i
i
i
i
i
i
i
308
BIBLIOGRAFÍA
[VCC]
Canon VCC4 Communication Camera.
url: http://www.usa.canon.com/
consumer/controller?act=ModelInfoAct&fcategoryid=158&modelid=
7402.
[VECGS92] T. Von Eicken, D. E. Culler, S. C. Goldstein, y K. E. Schauser. Active messages: a
mechanism for integrated communication and computation. En Actas de 19th Annual
International Symposium on Computer Architecture, páginas 256–266, 1992.
[VGPK97]
J. Veizades, E. Guttman, C. Perkins, y S. Kaplan. Service Location Protocol.
RFC 2165 (Proposed Standard), Junio 1997. Updated by RFCs 2608, 2609. url:
http://www.ietf.org/rfc/rfc2165.txt.
[VHM+ 07]
P. Verbaeten, W. Horré, N. Matthys, S. Michiels, y W. Joosen. A survey of middleware
for wireless sensor networks. Technical report, Katholieke Universiteit Leuven, Agosto
2007.
[Vil09]
F. J. Villanueva. Despliegue eficiente de entornos inteligentes basado en redes
inalámbricas. PhD thesis, Universidad de Castilla-La Mancha, 2009.
[VML04]
D. Villa, F. Moya, y J. C. López. Implementación mínima de objetos CORBA para
dispositivos empotrados. En Actas de XIV Jornadas TELECOM I+D, 2004.
[VOV+ 06]
F. J. Villanueva, J. A. Olivera, D. Villa, F. Moya, F. Rincón, J. Barba, y J. C. López.
Multimedia Data Transmission in MANETs for Intelligent Environments. En Actas
de 2nd International Workshop on Ubiquitous Computing and Ambient Intelligence,
páginas 35–44, Noviembre 2006.
[VR05]
M. S. Vieira y N. S. Rosa. A reconfigurable group management middleware service
for wireless sensor networks. En MPAC ’05: Actas de 3rd international workshop on
Middleware for pervasive and ad-hoc computing, páginas 1–8, New York, NY, USA,
2005. ACM.
[VVM+ 05a] D. Villa, F. J. Villanueva, F. Moya, F. Rincón, J. Barba, y J. C. López. Spreading
Pervasive Computing by Means of Small Distributed Objects. En Ubiquitous
Computing and Ambient Intelligence, Septiembre 2005.
[VVM+ 05b] F. J. Villanueva, D. Villa, F. Moya, F. Rincón, J. Barba, y J. C. López. A QoS
Framework for Adaptative Context-Aware Applications in Mobile Ad-hoc Network
-based Smart Buildings. En Actas del International Symposium on Ubiquitous
Computing and Ambient Intelligence 2005, páginas 19–26, Septiembre 2005.
[VVM+ 06a] D. Villa, F. J. Villanueva, F. Moya, F. Rincón, J. Barba, y J. C. López. Embedding a
Middleware for Networked Hardware and Software Objects. En Actas de International
Conference on Grid and Pervasive Computing. Springer, Mayo 2006.
[VVM+ 06b] F. J. Villanueva, D. Villa, F. Moya, F. Rincón, J. Barba, y J. C. López. Context-Aware
QoS Provision for Mobile Ad-hoc Network based Ambient Intelligent Environments.
Journal of Universal Computer Science (JUCS), 12(3):315–327, Abril 2006.
[VVM+ 07a] D. Villa, F. J. Villanueva, F. Moya, F. Rincón, J. Barba, y J. C. López. Minimalist
Object Oriented Service Discovery Protocol for Wireless Sensor Networks. En Actas
de International Conference on Grid and Pervasive Computing, páginas 472–483.
Springer, Mayo 2007.
[VVM+ 07b] F. J. Villanueva, D. Villa, F. Moya, F. Rincón, J. Barba, y J. C. López. Lightweight
Middleware for Seamless HW-SW Interoperability, with Application to Wireless
Sensor Networks. En Actas de Design, Automation and Test in Europe (DATE),
páginas 1042–1047, Abril 2007.
[VVM+ 08a] D. Villa, F. J. Villanueva, F. Moya, F. Rincón, J. Barba, y J. C. López. ASDF: an object
oriented service discovery framework for wireless sensor networks. International
i
i
i
i
i
i
i
i
BIBLIOGRAFÍA
309
Journal of Pervasive Computing and Communications (IJPCC), 4(4):371–389,
Diciembre 2008.
[VVM+ 08b] D. Villa, F. J. Villanueva, F. Moya, G. Urzaiz, F. Rincón, y J. C. López. Object
Oriented Multi-Layer Router with Application on Wireless Sensor-Actuator Networks.
En ICON 2008. 16th IEEE International Conference on Networks, 2008., páginas 1–7.
IEEE, Diciembre 2008.
[VVM+ 09]
D. Villa, F. J. Villanueva, F. Moya, F. Rincón, J. Barba, y J. C. López. Web Services
for deeply embedded extra low-cost devices. En Actas de International Conference
on Grid and Pervasive Computing, páginas 400–409. Springer, Mayo 2009.
[VVSL09]
F. J. Villanueva, D. Villa, M. J. Santofimia, y J. C. López. A Framework for Advanced
Home Service Design and Management. En Actas del International Conference on
Consumer Electronics, Enero 2009.
[WAS]
WASP: Wirelessly Accesible Sensor Populations. url: http://www.wasp-project.
org/.
[WCLD08]
M. M. Wang, J. N. Cao, J. Li, y S. K. Das. Middleware for Wireless Sensor Networks:
A Survey. Journal Of Computer Science and Technology, páginas 305–326, Mayo
2008.
[Whi75]
J. E. White. High-level framework for network-based resource sharing. RFC 707,
Diciembre 1975. url: http://www.ietf.org/rfc/rfc707.txt.
[WIN]
Rockwell WINS node. url: http://wins.rsc.rockwell.com/.
[Win01]
D. Winer. WSDL Specification. World Wide Web Consortium, 2001. url: http:
//www.w3.org/TR/wsdl.
[WIZ]
WIZnet module.
url: http://www.wiznet.co.kr/en/pro02.php?&ss[2]
=2&page=1&num=77.
[X10]
The
X10
PowerHouse
Powerline
Interface
Two-Way Powerline Interface Model TW523.
ftp://ftp.x10.com/pub/manuals/technicalnote.pdf.
[XPo]
Lantronix XPort.
url: http://www.lantronix.com/device-networking/
embedded-device-servers/xport.html.
[YG02]
Y. Yao y J. Gehrke. The Cougar approach to in-network query processing in sensor
networks. SIGMOD Record, 31:2002, 2002.
[Yu004]
Issues in designing middleware for wireless sensor networks.
18(1):15–21, Jan/Feb 2004.
[ZE98]
E. Zelkha y B. Epstein. From Devices to “Ambient Intelligence”. Digital Living Room
Conference, Junio 1998.
[Zera]
ZeroC, Inc. url: http://www.zeroc.com/.
[Zerb]
Inc. ZeroC. Ice Performance Tests. url: http://www.zeroc.com/performance/.
Model
PL513
and
Disponible en
Network, IEEE,
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
Índice alfabético
actor, 84
activo, 89
compuesto, 94
proactivo, 92
reactivo, 91
adaptador, 18, 180
banco (de registros), 117
bloque, 121
bus lógico, 19
bytecode, 125
cableado virtual, 97
cliente, 18
componente, 93
contenedor, 88
corbaloc, 26
corbaname, 26
CORBAServices, 27
DATA (FSM), 119
digest, 120
DL, 23
domótica, 12
endpoint, 182
EnviroTrack, 64
ERROR_EVENT, 122
Event Service, 28
eventos, 122
Flash (FSM), 120
FSM, 120
fsmCode, 125
fsmData, 125
fsmFlash, 125
GIOPLite, 46, 109
Ice (ZeroC), 32
IDM, 177
Impala, 60
INCOMING_EVENT, 122
interfaz, 18
IOR, 26
Kairos, 65
lit, 120
Literal, 120
máquina virtual, 129
Magnet, 56
MiLAN, 58
MinimumCORBA, 38
Naming Service, 27
objeto, 18
OMA, 20
OMG, 20
ORB, 24
picoObjeto, 107
POA, 23
propiedad, 135
proxy, 19, 106
reactor, 123
referencia (a objeto), 25
311
i
i
i
i
i
i
i
i
312
ÍNDICE ALFABÉTICO
RESET_EVENT, 122
RMI, 17
RPC, 14
SAN, 4
servicio
DUO, 84
reactivo, 98
SDP, 79
servidor, 18
sirviente, 18
subrutinas, 121
timer, 123
TinyCubus, 59
TinyLime, 63
variables FSM, 119
WIZnet, 200
XPort, 199
ZebraNet, 60
i
i
i
i
i
i
i
i
Este documento fue editado con GNU Emacs
y tipografiado con LATEX en un sistema GNU.
Las figuras fueron realizadas con Inkscape.
Ciudad Real, julio de 2009.
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
i
Descargar