UNIVERSIDAD DE CASTILLA-LA MANCHA ESCUELA SUPERIOR DE INFORMÁTICA

GRADO EN INGENIERÍA INFORMÁTICA

TRABAJO FIN DE GRADO

Infraestructura de eventos para la Internet de las cosas.

Roberto Requena Camacho

Septiembre, 2014

INFRAESTRUCTURADEEVENTOSPARALA INTERNETDELASCOSAS.

UNIVERSIDAD DE CASTILLA-LA MANCHA ESCUELA SUPERIOR DE INFORMÁTICA Tecnologías y Sistemas de Información

TECNOLOGÍA ESPECÍFICA DE INGENIERÍA DE COMPUTADORES

TRABAJO FIN DE GRADO

Infraestructura de eventos para la Internet de las cosas.

Autor: Roberto Requena Camacho Director: Dr. Félix Jesús Villanueva Molina

Septiembre, 2014

Roberto Requena Camacho Alcázar de San Juan – España E-mail: [email protected] Teléfono: 653 683 383 c 2014 Roberto Requena Camacho 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

TRIBUNAL:

Presidente:

Vocal:

Secretario:

FECHA DE DEFENSA:

CALIFICACIÓN:

PRESIDENTE VOCAL SECRETARIO

Fdo.: Fdo.: Fdo.:

iii

Resumen

El Internet de las Cosas, como paradigma para la conexión de los objetos cotidianos a Internet, está suponiendo una revolución en cuanto a la forma en que se interactúa con el en- torno. Su uso permite aprovechar con mayor eficiencia las posibilidades que este nos ofrece. Este hecho, está dando lugar a un auge en el esfuerzo que se realiza para desarrollar tecno- logías y estándares que soporten las características que requieren este tipo de escenarios. Gracias al Internet de las Cosas, está apareciendo la tecnología necesaria para recopilar, transmitir y gestionar información relevante dentro de los distintos procesos que ocurren en ciudad. Hecho que permite el desarrollo del paradigma de las Ciudades Inteligentes o Smart Cities. A partir del cual, se pretende que una ciudad mejore en la toma de decisiones referentes a los planos: económico, operativo, social y ambiental. Estos a menudo, se activan a partir de la aparición de una serie de eventos, ante los que la tiene que reaccionar. La recopilación y transmisión de la información que se genera en la ciudad, necesita de la cooperación de numerosas tecnologías, estándares, dispositivos, etc. siendo la Smart City la encargada de proporcionar la abstracción necesaria sobre estos elementos, con el fin de proporcionar servicios de valor a ciudadanos e instituciones. En este Trabajo Fin de Grado se presenta una infraestructura para el Internet de las Co- sas, que utiliza un modelo de comunicación basado en la publicación/suscripción de eventos, como medio para transmitir la información recopilada por los dispositivos de una red de sen- sores, hacia una red externa. De forma que, queda accesible a cualquier consumidor que se encuentre conectado a ella. En concreto, los resultados obtenidos con este proyecto, preten- den formar parte de uno de los métodos para recopilar información del entorno, que tendría una Smart City. A partir de la puesta en escena de la infraestructura, en un escenario real, se ha podido comprobar que realiza correctamente sus funciones. Proporciona los servicios de middlewa- re muy básico, a través del cual las aplicaciones pueden consultar la información que los sensores han recopilado del entorno, sin necesidad de que estas tengan que lidiar con las tecnologías subyacentes.

V

Abstract

Nowadays a revolution in the way people interact with the environment due to develop- ment of is taking place; this could be seen like a paradigm in where everyday objects are connected to Internet. This process allows people to take advantage of environment possibilities in a more efficient way. In this sense, technologies and standards need to be created in order to support this characteristics scenario. In a similar way, the Smart City paradigm, which will enable cities to take economic, operative, social and environment decisions in a best way, is growing up. This is possible through Internet of Things, which establishes the basis for the appearance of technologies to collect, transmit and manage massive information that appears in cities. In the city, in- formation is organized in processes and events that activate it. Therefore, the city must be able to respond and manage these events. To collect and transmit information produced by cities, cooperation between technologies, standards and devices is needed. So the City will be responsible of making the abstraction over these elements in order to provide services to citizens and organizations. In this sense, this Final Degree Project presents an event-based infrastructure for Internet of Things. Which uses a publish/subscribe model similar to the way of transmission of sen- sory information towards a higher transport level network. This system enables any consumer to obtain this information. Specifically, this project aims to be part of one of the methods the Smart City will have in order to collect and transmit information. Once the infrastructure has been tested in a real scenario, it’s correct operation will have been checked. This infrastructure provides services of a very basic middleware, through applications that can obtain environmental information collected by sensors, without the need of taking care about underlying technologies.

VII

Agradecimientos

Ya han pasado cinco años desde que comencé la carrera universitaria y durante su tras- curso, mi vida y mi forma de pensar han cambiado de manera significativa, debido en gran parte a las amistades realizadas en este periodo de tiempo y, por supuesto, a las personas que ya estaban en mi vida. Así que, tras la realización de este proyecto, que representa el último obstáculo en el camino, es bueno disponer de una parte del mismo en la que escribir unas lineas completamente personales. En primer lugar, quiero mostrar mi más sincero agradecimiento a toda mi familia. En especial a mis padres, Lorenzo y Ana, ya que a partir de su educación y su forma de ver la vida, han logrado inculcarme un gusto por el estudio, la cultura y el trabajo bien hecho, que sin duda me ayudarán a lo largo de mi vida. Y por supuesto, gracias a su soporte económico, que tanto esfuerzo les ha costado y sin el cual, no hubiese sido posible siquiera empezar la carrera. En menor grado pero también destacable, ha sido el apoyo, tanto moral como logístico, recibido por mis tíos Luismi y Minerva. Por otra parte, quiero mencionar a María, Alba, José Puche, José Duro, Carlos y Antonio, personas que comenzaron siendo compañeros de clase, y que después de cinco años y tras muchas experiencias vividas, son amigos de los que no me voy a olvidar a pesar de que se separen nuestros caminos. A todos ellos, gracias. Gracias por hacer más ameno el día a día y más llevadera la rutina. Y como no, gracias por lo buenos momentos de esparcimiento que hemos tenido. Por último, agradecer a mi tutor, Felix, el tiempo que me ha dedicado a pesar de tener una agenda bien completa. Debido a sus logros personales y a su forma de dar clase, pensé que sería una buena experiencia realizar el proyecto con él, y así ha sido.

Roberto Requena Camacho

IX

A mis padres, por soportar el día a día sin rendirse y sacarlo todo adelante.

xi

Índice general

Resumen V

Abstract VII

Agradecimientos IX

Índice general XIII

Índice de cuadros XVII

Índice de figuras XIX

Índice de listados XXI

Listado de acrónimos XXIII

1. Introducción 1 1.1. IoT y las ciudades inteligentes ...... 2 1.1.1. Aspectos tecnológicos ...... 2 1.1.2. Civitas, un middleware para las Smart Cities ...... 4 1.2. Paradigma de programación basado en eventos ...... 5

1.2.1. MQTT y MQTT-SN, protocolos para el IOT ...... 5

2. Objetivos 9 2.1. Objetivo general ...... 9 2.2. Objetivos específicos ...... 9 2.2.1. Diseño e implementación de una librería MQTT-SN ...... 10 2.2.2. Diseño e implementación de una pasarela software ...... 10 2.2.3. Diseño e implementación de una librería MQTT ...... 10 2.2.4. Diseño de un suscriptor en una red externa ...... 11 2.2.5. Diseño y validación de escenarios de test ...... 11

XIII 3. Antecedentes 13 3.1. Internet de las Cosas ...... 13 3.1.1. Tecnologías de identificación, captura y comunicación ...... 16 3.1.2. Importancia del middleware ...... 18 3.1.3. Internet de las Cosas, un paradigma libre ...... 19 3.2. Smart Cities ...... 23 3.2.1. Tecnologías de la Smart City ...... 24 3.2.2. Middlewares ...... 29 3.2.3. Civitas: Plataforma de soporte a las ciudades inteligentes ...... 29 3.2.4. Smart City en España ...... 32 3.2.5. Proyectos Europeos en el marco de la Smart City ...... 34 3.2.6. Plataformas y aplicaciones Open Source para la Smart City . . . . . 35 3.3. Programación orientada a eventos ...... 38 3.3.1. Topologías ...... 40 3.3.2. MQTT ...... 40 3.3.3. Otras tecnologías ...... 46 3.4. Conclusiones ...... 49

4. Metodología de trabajo 51 4.1. Metodología de trabajo ...... 51 4.1.1. eXtreme Programming (XP)...... 52 4.1.2. Test Driven Development (TDD)...... 53 4.2. Planificación del proyecto ...... 55 4.3. Herramientas ...... 55 4.3.1. Hardware ...... 56 4.3.2. Software ...... 57 4.3.3. Lenguajes de programación ...... 59

5. Arquitectura y desarrollo 61 5.1. Etapa 1: Despliegue mínimo de la plataforma ...... 62 5.1.1. Establecimiento de una red 802.15.4 ...... 64 5.1.2. Intercambio de paquetes ...... 69 5.2. Etapa 2: Instalación y configuración de Mosquitto ...... 74 5.2.1. Instalación ...... 75 5.2.2. Configuración ...... 77 5.3. Etapa 3: Librería MQTT ...... 78

xiv 5.3.1. Estudio de la especificación ...... 78 5.3.2. Creación del archivo de cabecera ...... 85 5.3.3. Implementación del protocolo ...... 87 5.4. Etapa 4: Pasarela transparente ...... 101 5.4.1. Estructura del código ...... 102 5.4.2. Archivo principal tGatewayServer.cpp (transparent Gateway Server) 113 5.5. Etapa 5: Librería MQTT-SN y el software de traducción ...... 119 5.5.1. Estudio de la especificación ...... 120 5.5.2. Creación de los archivos de cabecera ...... 125 5.5.3. Implementación ...... 128 5.6. Etapa 6: Suscriptores externos ...... 154

6. Resultados 157 6.1. Infraestructura de comunicación ...... 157 6.2. Repositorio ...... 159 6.3. Coste del proyecto ...... 159 6.3.1. Coste hardware ...... 160 6.3.2. Coste software ...... 160 6.3.3. Coste de la mano de obra ...... 160 6.4. Publicación ...... 161

7. Conclusiones y propuestas 163 7.1. Conclusiones ...... 163 7.2. Propuestas ...... 166 7.3. Conclusiones personales ...... 168

A. Manual de usuario de la librería MQTT v3.1.0 171 A.1. Conexión TCP ...... 171 A.2. Conexión MQTT ...... 172 A.3. Publicación MQTT ...... 172 A.4. Suscripción MQTT ...... 174 A.5. Valores de retorno ...... 175 A.6. Clientes ...... 175

B. Manual de usuario de la librería MQTT-SN v1.2 177 B.1. Instalación ...... 177 B.2. Configuración inicial ...... 177

xv B.3. Registro de topics MQTT-SN ...... 178 B.4. Publicación MQTT-SN ...... 179

B.4.1. Publicación con QOS -1...... 180 B.5. Valores de retorno ...... 181 B.6. Clientes ...... 181

C. Manual sobre cómo programar Waspmote 183 C.1. IDE de Waspmote: Descarga e instalación ...... 183 C.2. Cargar un nuevo programa en Waspmote ...... 184

D. Instalación y configuración de CUnit 189 D.0.1. Instalación ...... 189 D.0.2. Ejemplo de uso ...... 190

Referencias 193

xvi Índice de cuadros

3.1. Características de redes inalámbricas. Fuente: [tel11] ...... 26 3.2. Middlewares. Fuente: [VSV+13] ...... 30 3.3. Distintas tecnologías de comunicación ofrecidas por Libelium...... 37 3.4. Comparativa entre brokers MQTT. Fuente: [MQT]...... 46 3.5. Comparativa entre XMPP y MQTT...... 50

5.1. Formato de la cabecera fija. Fuente: [Loc10]...... 79 5.2. Tipos de mensajes y su numeración. Fuente: [Loc10]...... 80

5.3. Codificación de las distintas QOS. Fuente: [Loc10]...... 80 5.4. Flags de conexión del mensaje CONNECT. Fuente: [Loc10]...... 81 5.5. Códigos de retorno al mensaje CONNECT y su significado. Fuente: [Loc10]. 82 5.6. Codificación de una cadena de caracteres en MQTT. Fuente: [Loc10]. . . . 82 5.7. Descripción de los mensajes MQTT. Fuente: [Loc10]...... 88 5.8. Formato de la cabecera MQTT-SN. Fuente: [SCT13]...... 121 5.9. Valores de los códigos que representan los tipos de mensajes MQTT-SN. Fuente: [SCT13]...... 121 5.10. Campo flags de la cabecera variable. Fuente: [SCT13]...... 122 5.11. Formato de los mensajes que envían los sensores de la infraestructura. . . . 133

6.1. Lineas de código implementadas por componentes de la infraestructura. . . 160 6.2. Costes Hardware...... 160 6.3. Costes de la mano de obra...... 161 6.4. Coste total del proyecto ...... 161

XVII

Índice de figuras

1.1. Cadena de valor tecnológica de la Smart City ...... 4 1.2. Modelo de distribución de eventos para uno y varios subscriptores...... 6 1.3. Figura esquemática del proyecto ...... 7

3.1. Paradigma del IOT como el resultado de las convergencia de diferentes pun- tos de vista. Fuente: [AIM10a] ...... 14 3.2. Esquema de un Sistema RFID...... 17 3.3. Arquitectura de alto nivel de tecnologías M2M en el marco de las Smart Ci- ties. Fuente: [tel11] ...... 27 3.4. Esquema del framework Civitas. Fuente: [RAB+14] ...... 31 3.5. A la izquierda la Smart Parking Sensor Board junto con Waspmote, instalada en una plaza de aparcamiento. A la derecha uno de los paneles informativos. Fuente: [Bie13] ...... 34 3.6. Mapa interactivo que muestra la disponibilidad de plazas de aparcamiento. Fuente: [Bie13] ...... 34 3.7. Distintas topologías de los sistemas basados en eventos. Fuente: [LP+03] . 41 3.8. Arquitectura MQTT-SN. Fuente: [SCT13] ...... 44 3.9. Tipos de pasarelas. Fuente: [SCT13] ...... 45

4.1. Etapas del proyecto...... 55 4.2. Diagrama de Gantt del proyecto...... 56

5.1. Arquitectura y componentes de la infraestructura. Fuente: elaboración propia. 62 5.2. Escenario bajo el que se trabaja utilizando el firmware Meshlium ZigBee AP. Fuente: [Lib13a]...... 63 5.3. Acceso a configuración de parámetros de Meshlium...... 65 5.4. Chequeo de parámetros de Meshlium...... 66 5.5. Captura de paquetes en Meshlium, acceso via Manager System...... 71 5.6. Comprobación del correcto funcionamiento de Mosquitto...... 77

5.7. Flujo de datos para una publicación con QOS nivel 2. Fuente: elaboración propia...... 84

XIX 5.8. Ejemplo de flujo de datos ordenado. Fuente: elaboración propia...... 85 5.9. Máquina de estados para detectar la secuencia de inicio de mensaje. Fuente: Elaboración propia...... 109 5.10. Escenario de actuación del mensaje CONNECT. Fuente: elaboración propia. 130 5.11. Escenario de actuación del mensaje CONNECT con las características last will and testament. Fuente: elaboración propia...... 130 5.12. Escenario de actuación del mensaje REGISTER. Fuente: elaboración propia. 131

5.13. Escenario de actuación del mensaje PUBLISH con QOS 0 y 1. Fuente: ela- boración propia...... 132

5.14. Escenario de actuación del mensaje PUBLISH con QOS 2. Fuente: elabora- ción propia...... 133

5.15. Escenario de actuación del mensaje PUBLISH con QOS -1. Fuente: elabora- ción propia...... 134 5.16. Mecanismo creado para la realización de los suscriptores externos...... 155 5.17. Visualización de las coordenadas publicadas por los sensores...... 156

6.1. Arquitectura y componentes de la infraestructura. Fuente: elaboración propia. 158

C.1. Como encender Waspmote. Fuente: [Lib13d]...... 184 C.2. Seleccionar placa adecuada. Fuente: [Lib13d]...... 185 C.3. Seleccionar puerto adecuado. Fuente: [Lib13d]...... 185 C.4. Guardar un Sketch. Fuente: [Lib13d]...... 186 C.5. Cargar un Sketch 1. Fuente: [Lib13d]...... 186 C.6. Cargar un Sketch 2. Fuente: [Lib13d]...... 187

D.1. Estructura del framework CUnit...... 190

xx Índice de listados

5.1. Código de Libelium ejemplo 802_01 - configure XBee basic parameters. . . 65 5.2. Código de Libelium ejemplo 802_02 - send packets...... 69 5.3. Código de Libelium ejemplo 802_11b - complete example receive...... 72 5.4. Archivo de cabecera tras codificar el formato de lo mensajes de MQTT. . . 86 5.5. Suite para los test MQTT...... 90 5.6. Test para el escenario CONNECT/DISCONNECT...... 91 5.7. Manejador de conexión con el broker...... 92 5.8. Prototipos de las funciones necesarias para el escenario CONNECT/DIS- CONNECT ...... 92 5.9. Función de inicialización del manejador de conexión ...... 94 5.10. Implementación del mensaje CONNACK...... 95 5.11. Implementación del mensaje DISCONNECT...... 96 5.12. Implementación del mensaje CONNECT...... 98 5.13. Código de la función xbee_init() ...... 106 5.14. Código principal de xbee_getPacket() ...... 108 5.15. Código ejemplo de xbee_parsePacket() ...... 111 5.16. Código de la primera versión del archivo WaspMqttSN.h ...... 126 5.17. Código de la función obtain_sensorMac() ...... 135 5.18. Test del escenario CONNECT/DISCONNECT ...... 135 5.19. Código de las funciones del escenario CONNECT/DISCONNECT . . . . . 137 5.20. Código de las funciones de conversión del escenario CONNECT/DISCON- NECT...... 138 5.21. Test del escenario REGISTER ...... 139 5.22. Código de las funciones de la librería del escenario REGISTER ...... 141 5.23. Código de las funciones de la pasarela del escenario REGISTER ...... 143 5.24. Test del escenario PUBLISH ...... 144 5.25. Código de las funciones del escenario PUBLISH ...... 146 5.26. Código de las partes de traducción del escenario PUBLISH ...... 148 5.27. Test del escenario PING ...... 151

XXI 5.28. Código de las funciones del escenario PING ...... 152 5.29. Código de las partes de traducción del escenario PING ...... 153

A.1. Cliente MQTT que publica utilizando distintos niveles de QOS ...... 173 A.2. Cliente MQTT que se suscribe a un topic y después cancela esta suscripción. 174 B.1. Ejemplo de configuración de cliente...... 178 B.2. Ejemplo de registro de topic name de un cliente...... 179

B.3. Ejemplo de publish con QOS 1...... 180

B.4. Ejemplo de publish con QOS -1...... 180 D.1. Código de ejemplo de uso de CUnit ...... 191

xxii Listado de acrónimos

AMQP Advanced Message Queuing Protocol

API Application Programming Interface

C/S Cliente/Servidor

EPC Electronic Product Code

E/S Entrada/Salida

GNU GNU is Not Unix

GPL General Public License

GPRS General Packet Radio Service

HTML HyperText Markup Language

HTTP Hypertext Transfer Protocol

ICT Information and Communications Technologies

IDE Entorno de Desarrollo Integrado

IDL Interface Description Language

IoT Internet of Things

IP Internet Protocol

IPSO IP for Smart Objects Alliance

JVM Java Virtual Machine

LSB Least Significant Byte

MAC Media Access Control

MSB Most Significant Byte

M2M Machine-to-Machine

NFC Near Field Communications

OTA Over The Air Programming

POE Power Over Ethernet

P2P Peer-to-Peer

QoS Quality of Service

XXIII RFID Radio-Frequency IDentification

SASL Simple Authentication and Security Layer

SCADA Supervisory Control and Data Acquisition

TCP Transmision Control Protocol

TDD Test Driven Development

TIC Tecnologías de la Información y la Comunicación

TFG Trabajo Fin de Grado uID Unique/Universal/Ubiquitous IDentifier

UTF Unicode Transformation Format

VoIP Voice over IP

WISP Wireless Identification and Sensing Platforms

XML eXtensible Markup Language

XMPP eXtensible Messaging and Presence Protocol

XP eXtreme Programming

xxiv Capítulo 1 Introducción

A evolución en eficiencia, comunicaciones, coste, etc. de las tecnologías de la informa- L ción está permitiendo que sean abordables nuevos paradigmas hasta hace unos años impensables. Uno de estos paradigmas es el Internet de las Cosas (en adelante IOT, del inglés Internet of Things), el cual se entiende como la conexión de los objetos más cotidianos a Internet y se ha convertido en un concepto de actualidad con una gran proyección de futuro.

Uno de los hechos más recientes que nos hacen ver la importancia que el IOT está adquiriendo es que Google está apostando fuerte en este sector, la empresa Estadounidense ha adquirido recientemente por 3.200 millones de dólares a Nest Labs, una empresa que está detrás de los termostatos y detectores de humo inteligentes, en lo que no es sino uno de los muchos ejemplos de que habrá grandes inversiones en este campo en los próximos años.

También es importante mencionar la relevancia que el IOT está tomando en España, donde en los últimos años se han creado startups como Carriots1 o Bitcarrier2, además de proyectos de investigación como Smart Malaga, Barcelona o SmartSantander, este último ha sido reco- nocido a nivel Europeo por sus buenos resultados y su realización ha convertido a Santander en la primera ciudad inteligente integral de Europa. Por último, es muy importante mencio- nar a la empresa Libelium3, que también es española y que tiene un reconocido prestigio internacional en la industria de los sensores. A lo largo del documento se hablará de esta empresa y de sus productos, ya que algunos de ellos han sido utilizados en este Trabajo Fin de Grado (TFG).

Pero, ¿en qué consiste el IOT? Puede verse como un paradigma en el que los objetos cotidianos tienen la capacidad de conectarse a la red, enviar datos a través de ella y/o reci- bir algunos de estos datos, interpretarlos y actuar consecuentemente para nuestro beneficio. Un ejemplo sencillo podemos verlo en el campo de la domótica, donde por ejemplo, desde nuestro smartphone podemos encender el horno, controlar el termostato de la calefacción o cualquier tarea del hogar que pueda automatizarse. Si ampliamos este concepto y hacemos que estos u otros objetos usen esta tecnología para conectarse a Internet, las posibilidades de uso de este paradigma se multiplican. Todo esto hace pensar que el IOT transformará nuestro

1https://www.carriots.com 2http://www.bitcarrier.com 3http://www.libelium.com/es/

1 2 CAPÍTULO 1. INTRODUCCIÓN entorno y los objetos cotidianos para hacerlos mucho más inteligentes, con el objetivo de hacernos la vida más cómoda e, incluso, contribuirá a que seamos más eficientes a la hora de gestionar nuestro tiempo o nuestros recursos [AIM10b].

De esta forma, se prevé una especial importancia en el desarrollo de sistemas informáticos que usen o que estén basados en el IOT.

1.1 IoT y las ciudades inteligentes

Uno de los principales campos de aplicación del IOT son las Smart Cities o ciudades inteli- gentes. En la Smart City cualquier proceso que se lleve a cabo a diario en una ciudad, puede verse beneficiado dado que está apareciendo la tecnología necesaria para recopilar, trans- mitir y gestionar la información que se considere importante para ese proceso, y después interpretar esta información y actuar en consecuencia para lograr un beneficio común.

Si se piensa en la Smart City desde un punto de vista social, esta puede verse como un tipo de desarrollo urbano basado en la sostenibilidad, que es capaz de responder adecuadamente a las necesidades básicas de instituciones, empresas, y de los propios habitantes, tanto en el plano económico, como en los aspectos operativos, sociales y ambientales [SKP+11]. Una Smart City cuyos servicios se aprovechasen de forma correcta, impulsaría el crecimiento económico sostenible y «teóricamente» la prosperidad para sus ciudadanos, ya que sus diri- gentes dispondrían de las herramientas necesarias para analizar los datos que les permitirían tomar mejores decisiones, anticiparse a los problemas para resolverlos de forma proactiva y coordinar los recursos para actuar de forma eficiente.

Es importante entender el factor social que llevan asociado las Smart Cities, así como sus posibles beneficios para la población, organizaciones e instituciones, pero para comprender la importancia de este TFG es necesario centrarse en los aspectos tecnológicos de las Smart Cities: qué tecnologías se usan, qué problemas surgen, posibles soluciones, etc.

1.1.1 Aspectos tecnológicos

Desde un punto de vista tecnológico, el concepto de IOT aplicado al campo de las ciudades inteligentes, presenta una serie de retos que deben ser abordados desde diferentes puntos de vista, como lo son el hardware, el software, la metodología en el desarrollo de servicios, la seguridad, etc.

Para tener una visión amplia de las tecnologías que forman parte de una Smart City, se define de forma resumida, lo que se puede denominar como «cadena de valor tecnológica» de la Smart City [tel11]:

En primer lugar se encuentra la etapa de recolección de datos de la ciudad. Esta tarea se realiza utilizando redes de sensores, actuadores y diferentes dispositivos de captu- ra de datos que permitan la recolección de información. Entre estos dispositivos hay 1.1. IOT Y LAS CIUDADES INTELIGENTES 3

que incluir los móviles de las personas, diferentes aparatos del entorno del hogar, los vehículos, así como los dispositivos de medida situados en infraestructuras fijas, como mobiliario urbano, edificios, sistemas de canalización y tuberías, estaciones meteoro- lógicas y así un largo etc.

La forma que utilizan estos dispositivos para comunicarse con otros que estén fuera de su red, es haciendo uso de la infraestructura desplegada para Internet. Este escenario

es, por definición, un entorno de IOT.

En segundo lugar se realiza la transmisión de los datos recopilados de la ciudad a través de las redes de comunicación. Esto se lleva a cabo mediante una combinación de infraestructura inalámbrica, móvil y fija dependiendo de las necesidades de movilidad, ancho de banda y latencia de la aplicación en concreto. En algunos casos las redes inalámbricas y móviles serán las únicas de las que se disponga y sus arquitecturas pueden ser muy variadas. Por regla general, los sensores transmitirán la información a través de protocolos ligeros a coordinadores o gateways que a su vez enrutarán los da- tos a través de líneas móviles o fijas y lo harán llegar a las bases de datos y plataformas que faciliten la provisión de los servicios.

En este punto toman especial importancia las comunicaciones entre dispositivos, en lo que se ha denominado M2M (del inglés, Machine-to-Machine). Este tipo de comuni- caciones son muy comunes en el entorno de las Smart Cities y están teniendo también un gran impacto gracias al desarrollo de las nuevas redes inalámbricas.

Una tercera fase comprende el almacenamiento y el análisis de los datos. Se trata de almacenar en una plataforma central los datos recopilados en el entorno de la ciudad al mismo tiempo que se facilita su procesamiento posterior mediante diferentes sistemas analíticos.

En cuarto lugar, los datos alimentan una plataforma de provisión de servicios que facilita la prestación de los servicios en el ámbito de la Smart City. Se trata de una plataforma horizontal y escalable, que permite ofrecer servicios de una manera segura y con garantías de privacidad.

La plataforma en el seno de la cual se desarrolla este TFG, es el middleware Civitas (véase Sección 1.1.2).

Finalmente se encuentran los servicios de la Smart City, que podrán ser desarrollados por los mismos agentes involucrados en el resto de la cadena, o por otros agentes. Estos servicios se apoyan en todas las tecnologías, infraestructuras y plataformas anterior- mente comentadas para ofrecer su valor final al cliente. Hay numerosos ejemplos de servicios finales posibles, tantos como servicios públicos que ha de prestar un Ayunta- miento, aunque no únicamente. 4 CAPÍTULO 1. INTRODUCCIÓN

En la Figura 1.1 puede verse de forma esquemática el proceso que forma esta «cadena de valor tecnológica».

Figura 1.1: Cadena de valor tecnológica de la Smart City

1.1.2 Civitas, un middleware para las Smart Cities En el seno del grupo de investigación Arco de la Escuela Superior de Informática de la Universidad de Castilla-La Mancha se está desarrollando una plataforma para ciudades inteligentes que pretende abordar todas las etapas anteriormente descritas y que se denomina Civitas [VSV+13].

Civitas nace ante la necesidad de una plataforma que gestione la heterogeneidad en cuanto a estándares, protocolos y formatos de representación de datos, de los dispositivos y de las redes que forman parte de las etapas de recolección y transmisión de datos de una Smart City.

Como plataforma para las Smart Cities, Civitas necesita ser capaz de adaptarse a nuevas tecnologías, con el fin de adoptar fácilmente nuevas formas de recolectar datos del entorno. La infraestructura que se desarrolla con este TFG pretende formar parte de uno de los mé- todos de los que dispone Civitas para recopilar información de la ciudad, este modelo de recolección de datos está basado en eventos, que como se verá en la siguiente sección, es ideal para el marco de la Smart City. 1.2. PARADIGMA DE PROGRAMACIÓN BASADO EN EVENTOS 5

1.2 Paradigma de programación basado en eventos

El software es uno de los aspectos que más importancia tiene en este TFG, en la ciudad se generan datos que deben ser transferidos a través de los diferentes dispositivos que forman parte de las infraestructuras subyacentes a la Smart City, con el objetivo de que esta pueda utilizarlos para proporcionar sus servicios. Esta parte de generación y transmisión de datos es crucial en el proceso de prestación de servicios de una Smart City, y se corresponde con las dos primeras etapas explicadas en la Sección 1.1.1.

A la hora de generar y de recibir información, uno de los paradigmas de programación que mejor se adapta al IOT es la programación orientada a eventos. Este tipo de programación se basa en un modelo de comunicación en el que interactúan dos o más elementos, donde unos son productores de eventos, y otros consumidores de los mismos. Los productores generan información (con un formato preestablecido) y la distribuyen a través de un broker o canal de eventos a uno o varios consumidores. En este contexto, se entiende por broker a un servidor que implementa un protocolo basado en este tipo de paradigma, y que, a grandes rasgos, se encarga de gestionar la misma y distribuir los eventos. Como en todo proceso de comunicación, entre productor y consumidor debe de establecerse un canal para que el mensaje pueda ser enviado/recibido, en este caso se usa un canal de eventos, que no es sino un canal lógico al cual se subscriben los productores/consumidores para enviar o recibir eventos. Los diversos canales de eventos son gestionados por el broker.

Las ventajas de este paradigma en cuanto a bajo acoplamiento, escalabilidad, sencillez de gestión, etc. hacen que esté destinado a jugar un rol importante en el IOT. En la Figura 1.2 puede verse un esquema de un modelo basado en eventos, notesé que la complejidad del modelo no varía haya uno o varios elementos de comunicación.

El broker recibe las subscripciones por parte de los consumidores, los cuales indican el tipo de eventos en los que están interesados mediante un identificador de canal de eventos (topic), a partir de este momento, todo evento generado por un productor de eventos, es enviado a todos los consumidores subscritos.

1.2.1 MQTT y MQTT-SN, protocolos para el IOT En el marco de los paradigmas que siguen un modelo basado en la distribución de eventos, una de las plataformas más prometedoras es la definida por IBM en la decada de los 90, asociada al protocolo MQTT [Loc10]. Este protocolo ha sido seleccionado recientemente 4 por OASIS , como uno de los protocolos destinados a soportar el paradigma del IOT y por ende, las Smart Cities. Además de esto, desde que IBM liberara la especificación de este protocolo, su uso ha crecido paulatinamente, llegando a estar en auge en la actualidad. En este aspecto cabe destacar la contribución del Eclipse Paho Project, un proyecto que está en

4OASIS es un consorcio de empresas cuyo cometido es guiar el desarrollo, la convergencia y la adopción de estándares abiertos con el objetivo de globalizar la sociedad de la información. 6 CAPÍTULO 1. INTRODUCCIÓN

Figura 1.2: Modelo de distribución de eventos para uno y varios subscriptores. continuo desarrollo por la fundación Eclipse, cuyo objetivo es implementar clientes MQTT en varios lenguajes de programación, como Java, C o JavaScript, y que publicó su primera versión de las librerías MQTT en Junio de 2014.

En esencia, MQTT es un protocolo muy ligero, asíncrono y basado en la publicación/sus- cripción de mensajes. Sus principios de diseño lo hacen ideal para paradigmas emergentes como M2M, el IOT, las aplicaciones móviles y las redes de sensores. MQTT opera sobre re- des TCP/IP. Consecuentemente, este protocolo no puede ser ejecutado directamente sobre una red de sensores ya que estas no tienen porque estar adaptadas a las redes TCP/IP y gene- ralemente tienen su propia pila de protocolos. Para solventar este problema, IBM desarrolló MQTT-SN [SCT13] como una extensión de MQTT adaptada a las peculiaridades de una red de sensores.

El objetivo principal de este TFG es la creación de una infraestructura basada en eventos

MQTT/MQTT-SN para el IOT, con el fin de proporcionar a Civitas (véase Sección 1.1.2) los datos necesarios acerca de qué está pasando en la ciudad. Para ello se implementará el protocolo MQTT/MQTT-SN en una red de sensores/pasarelas de la empresa Libelium.

En la Figura 1.3 puede verse un esquema de la citada infraestructura, en el cual existen tres elementos bien diferenciados:

En la parte inferior se encuentra una red de sensores formada por dos tipos de ele- mentos: sensores y pasarelas o gateways. Los sensores se comunican con las pasarelas 1.2. PARADIGMA DE PROGRAMACIÓN BASADO EN EVENTOS 7

Figura 1.3: Figura esquemática del proyecto

mediante el protocolo MQTT-SN y su fin último es publicar información del entorno. Las pasarelas por regla general sirven para interconectar dos redes con tecnologías di- ferentes, en este caso interconectan una red de sensores en la que se usa MQTT-SN sobre 802.15.4 con una red TCP/IP en la que se encuentra el broker MQTT. Con lo cual, la pasarela debe de realizar una conversión entre ambos protocolos. Además de esto, en ocasiones deberá actuar como servidor para los sensores, debido a requisitos del protocolo MQTT-SN. Como puede observarse, esta parte del esquema se corresponde con las dos primeras etapas de la «cadena de valor tecnológica de las Smart City» que se han introducido en la Sección 1.1.1 y que se describen detalladamente en la Sección 3.2.1. En la parte central se encuentra una «nube» representando todo el proceso que se lleva a cabo para gestionar y distribuir los eventos que generan los sensores y que llegan hasta aquí a través de las pasarelas. Por último, en la parte de arriba se encuentran los receptores de la información gene- rada por la red subyacente: usuarios, gobierno, empresas, instituciones y asociaciones, entre otros.

Capítulo 2 Objetivos

N el siguiente capítulo se presentan los objetivos que se marcaron para el desarrollo E de este TFG, a partir de la propuesta de Anteproyecto. Tras finalizar este capítulo, el lector tendrá consciencia de lo que pretende conseguirse con el desarrollo de los mismos, y del ámbito y el alcance de los resultados obtenidos tras su realización.

2.1 Objetivo general

En términos generales, se pretende crear una infraestructura que use un modelo de co- municación basado en la publicación/suscripción de eventos, para el IOT. El objetivo es que los dispositivos de una plataforma sensora puedan publicar información acerca de que está ocurriendo en su entorno, y esta llegue, a través de la infraestructura, a cualquier suscriptor que se encuentre en una red externa. Actuando de esta forma, como un middleware que pro- porciona la información que genera el IOT en un entorno concreto, ocultando los detalles de las tecnologías que hay por debajo de él.

Como base al desarrollo de la infraestructura, se despliega una plataforma sensora de la empresa Libelium, sobre la que se implementará una lógica de comunicación utilizando los protocolos MQTT, MQTT-SN y un software para la pasarela.

A su vez, la infraestructura pretende formar parte del framework Civitas, como uno de los métodos que tiene la Smart City para recopilar información de su entorno.

2.2 Objetivos específicos

El desarrollo de esta infraestructura conlleva la creación de una serie de elementos soft- ware y de su interoperabilidad, a partir de la cual el flujo de información se irá desplazando desde los sensores hasta servidores en redes externas, y en última instancia a los receptores de información.

Lograr obtener buenos resultados en la implementación de las distintas partes que hacen funcionar la infraestructura, desembocará inequívocamente en un funcionamiento correcto de la misma. El desarrollo de estas partes se consigue a partir del planteamiento de los obje- tivos específicos que se exponen en apartados sucesivos.

9 10 CAPÍTULO 2. OBJETIVOS

2.2.1 Diseño e implementación de una librería MQTT-SN El flujo de eventos que recorrerá la infraestructura se llevará a cabo utilizando los pro- tocolos MQTT-SN y MQTT. MQTT-SN es un protocolo pensado para actuar en redes de sensores, y tendrá la función de realizar la interacción entre la pasarela y los sensores que estén conectados en red a ella. En este caso los sensores son dispositivos Waspmote de la empresa Libelium, se ha elegido esta empresa debido a su prestigio tanto nacional como in- ternacional, a que es una empresa líder en el campo de los sensores y a que tanto el hardware como el software que distribuyen, es libre. Con lo cual, para que pueda escribirse código que haga que estos dispositivos utilicen MQTT-SN, deberá implementarse una librería del protocolo que pueda ejecutarse sobre ellos.

Aunque la implementación se va a realizar sobre redes y dispositivos de esta empresa, también forma parte de este objetivo, el realizar todo el software de forma que adaptarlo a distintas tecnologías, se realizase con un esfuerzo y coste mínimos. De forma que, por ejem- plo, si las distintas librerías están bien modularizadas, un cambio en la tecnología de acceso al medio tan solo conllevaría modificar la parte del código encargada de la funcionalidad de enviar/recibir datos por la red subyacente, y no el envío o la recepción de cada mensaje.

2.2.2 Diseño e implementación de una pasarela software Para que los datos que se generan en la red de sensores lleguen a una red de nivel superior, como TCP/IP, es necesaria la participación de unos dispositivos conocidos como pasarelas. En este caso se utiliza la pasarela Meshlium de la empresa Libelium, cuya función será la de mantener comunicación tanto con los sensores como con un broker MQTT, realizando una traducción entre MQTT-SN y MQTT, y viceversa.

En concreto deberá implementarse un tipo de pasarela llamado pasarela transparente. Este tipo de pasarelas mantienen una conexión con el «broker» (véase Sección 3.3.2) por cada cliente MQTT-SN conectado.

2.2.3 Diseño e implementación de una librería MQTT Una de las partes más importantes del software de traducción es la comunicación que se debe de establecer con el broker MQTT, una vez que se hayan traducido los mensajes MQTT-SN. Para establecer esta comunicación y para que la tarea de traducción resulte más sencilla, se implementará una librería para el protocolo MQTT.

Con el desarrollo de este objetivo se dotará a la infraestructura de la capacidad de trasladar por completo la información que han recopilado y publicado los sensores, hacía una red TCP/IP en la que se encontrará un broker MQTT, el cual se encargará de distribuir estas publicaciones de eventos, a cualquier suscriptor que se suscriba al canal de eventos en el que han publicado los sensores. 2.2. OBJETIVOS ESPECÍFICOS 11

2.2.4 Diseño de un suscriptor en una red externa Desarrollada la infraestructura, surge la necesidad de situarla bajo un escenario de actua- ción real para comprobar que funciona de forma correcta. Para llevar a cabo esta tarea, se va a implementar un mecanismo mediante el cual cualquier dispositivo situado en una red exter- na, pueda acceder a través de Internet y de un navegador web a la información que publican los sensores, en tiempo real. Esta implementación se realizará con tecnologías web para que sea multiplataforma y se trabajará sobre un escenario en el que los sensores publican su geolocalización, y esta se muestra en un mapa situado en el navegador del suscriptor externo. Notesé, que para cumplir con lo especificado en este objetivo, hace falta disponer de la infraestructura completamente desarrollada, y sus resultados indicarán sin lugar a dudas, no solo un completo conocimiento del ámbito del proyecto y sus posibles aplicaciones, sino también que la infraestructura está preparada para actuar en un entorno real.

2.2.5 Diseño y validación de escenarios de test Se pretende desarrollar la infraestructura de tal forma, que una vez concluidos los es- fuerzos de implementación, se disponga de una serie de escenarios de test que permitan la validación de todas las funcionalidades implementadas.

Capítulo 3 Antecedentes

L ámbito de aplicación de este proyecto comprende algunos de los paradigmas más E prometedores de cara al futuro de las nuevas tecnologías y a su aplicación para nuestro beneficio. Estos paradigmas son el Internet de las Cosas y las ciudades inteligentes o Smart Cities. Como señala la Fundación Telefónica en su último informe sobre Smart Cities [tel11], en un contexto tecnológico, el concepto de Smart City y el de IOT son dos términos que van de la mano ya que ambos tienen en las comunicaciones M2M su fundamento y adelantan el Internet del futuro que permitirá la conexión no sólo de las personas, sino también de los objetos, configurando de esta forma un mundo digital. Por otra parte, una de las aproximaciones más prometedoras en este ámbito es la progra- mación orientada a eventos, con lo cual una Smart City necesita incorporar tecnologías de publicación/suscripción de eventos, que le permitan adecuarse a esta situación. En este capítulo se pretende situar al lector en el contexto del proyecto, en primer lugar se tratan los dos grandes ámbitos de aplicación de este TFG, Internet de las Cosas y las Smart Cities, en ambos casos se mostrará su estado actual y cuales son las principales tecnologías involucradas y que rol jugaría la implementación de este proyecto en dichos ámbitos. En tercer lugar se estudia el estado del arte de la programación orientada a eventos y la descripción de los protocolos MQTT y MQTT-SN, de cara a introducir al lector en este paradigma y en los protocolos seleccionados. De igual forma se mostrarán las características de la plataforma seleccionada para la implementación de referencia de dichos protocolos.

3.1 Internet de las Cosas

Hoy en día se pueden encontrar múltiples definiciones de IOT dentro de la comunidad de investigación, buscando en la literatura existente sobre este tema a un lector interesado podría resultarle difícil entender lo que este paradigma realmente significa, que ideas básicas están detrás de este concepto y que implicaciones sociales, económicas y técnicas supondría un despliegue completo del IOT. La razón por la que el significado de este concepto sigue estando borroso no es otra que su propio nombre, «Internet de las Cosas», el cual está compuesto sintácticamente por dos términos. El primero de ellos te sitúa en el contexto de la red global Internet, mientras que

13 14 CAPÍTULO 3. ANTECEDENTES el segundo te lleva a imaginar un conjunto de «objetos» integrados en un framework co- mún. La diferencia principal entre estos dos puntos de vista se debe al hecho de que los stakeholders, el mundo empresarial, la comunidad de investigación y los organismos de es- tandarización, comienzan a abordar el tema desde diferentes perspectivas, bién desde una perspectiva «orientada a Internet», o bién desde otra «orientada a cosas», dependiendo en cualquier caso de unos intereses, finalidad y trasfondo específicos. Además, la necesidad de un direccionamiento único por «objeto» y la representación y almacenamiento de la información intercambiada, se han convertido en uno de los retos más desafiantes de este paradigma, surgiendo de esta forma una tercera perspectiva, la llamada «orientada a la semántica». En la Figura 3.1 pueden verse los conceptos principales, las tecnologías y estándares des- tacados, clasificados según la perspectiva/s en la que se encuentran. Viendo la figura queda claro que el IOT es el resultado de la convergencia entre 3 puntos de vista distintos.

Figura 3.1: Paradigma del IOT como el resultado de las convergencia de diferentes puntos de vista. Fuente: [AIM10a]

La definición original de IOT derivaba de la perspectiva «orientada a cosas»; el término «cosas» es sencillo, se consideraba como «cosas» a todo aquello que lleve una etiqueta RFID (Radio-Frequency IDentification). De hecho, el termino completo «Internet de las Cosas», se atribuye a The Auto-ID Labs1, una red global de laboratorios de investigación en el campo de

1http://autoidlabs.org/ 3.1. INTERNET DE LAS COSAS 15 las redes RFID y las tecnologías sensoras emergentes. Estas instituciones, desde su creación, + se han encargado de estructurar el IOT, junto con EPCglobal [JHU 05]. Su objetivo principal ha sido el desarrollo del EPC (Electronic Product Code) [Bro01], con el propósito de dar soporte al uso de RFID en las redes de área global modernas. Estos estándares se diseñaron con la intención de mejorar la visibilidad de los objetos dentro de un framework común.

En un sentido más amplio, el IOT no puede ser simplemente un sistema global de EPCs, donde los únicos objetos son RFIDs; estos serán parte de un todo mucho mayor. Y lo mismo se puede aplicar a la arquitectura alternativa Unique/Universal/Ubiquitous IDentifier (UID), que se propone en [Sak06], cuya idea principal sigue siendo el desarrollo de soluciones

(basadas en middleware en este caso) que logren dotar al IOT de una visibilidad global de los objetos. No obstante, esta alternativa es de alguna manera más completa que la anterior, ya que este paradigma implica tener una visión más amplia que simplemente un identificador de cada objeto.

De acuerdo a los autores de [PG09], RFID se mantendrá algún tiempo en la vanguardia de las tecnologías de este campo, debido a su madurez, su bajo coste y a un fuerte apoyo desde el mundo de los negocios. Sin embargo, afirman que con el tiempo el IOT estará formado por una amplia gama de dispositivos, redes y tecnologías (hecho que está teniendo lugar hoy en día). Por otra parte, la tecnología NFC (Near Field Communications) y las redes de sensore- s/actuadores (WSAN) junto con RFID, están reconocidas como «los componentes atómicos que enlazarán el mundo real con el mundo digital». También vale la pena destacar que la ma- yoría de los proyectos están siendo llevados a cabo con el objetivo de desarrollar plataformas que permitan el uso de estas tecnologías, como el proyecto WISP (Wireless Identification and Sensing Platforms) [Rad12].

Otras instituciones han insistido en que el concepto de IOT tiene que estar principalmente centrado en las «cosas» y que el camino hacia un despliegue total de este paradigma, de- be empezar por un aumento de la inteligencia de dichas «cosas». Surgen, de esta forma, lo que se conoce como Smart Items, que son conjuntos de sensores equipados no solo con capacidad comunicativa inalámbrica y con memoria, sino que también poseen potencial pa- ra ser autónomos y tener un comportamiento proactivo, conocimiento del contexto de sus acciones y comunicaciones colaborativas. Un dispositivo de este tipo sería algo similar a los Smartphones y un ejemplo de aplicación, los ambientes inteligentes (del inglés, Smart Environments).

Uno de los puntos de vista que va más allá del enfoque RFID, es el propuesto por el consorcio CASAGRAS [DV08]. Sus miembros se centran en “un mundo donde las cosas puedan comunicarse de forma automática entre ellas y con computadores, proporcionando servicios para el beneficio de la humanidad”. CASAGRAS busca dos objetivos:

Proponer una visión del IOT como una infraestructura global donde están conectados 16 CAPÍTULO 3. ANTECEDENTES

tanto objetos virtuales como físicos. Resaltar la importancia de incluir la infraestructura desplegada para Internet.

Esta definición juega un rol importante ya que une de alguna forma dos de las tres perspec- tivas en las que se divide el IOT. La «orientada a cosas» y la «orientada a Internet». Dentro de esta última perspectiva encaja la visión de la IPSO (IP for Smart Objects Alliance) [DV08]. Según la cual, la pila IP (Internet Protocol) está formada por protocolos ligeros que ya co- nectan una gran cantidad de dispositivos y que pueden correr en sistemas empotrados con recursos limitados. Esto garantiza que IP tiene todas las características necesarias para hacer el IOT una realidad. La IPSO, además, expresa que todo pasa por realizar una buena adap- tación de IP y por incorporar el estándar IEEE 802.15.4 a la arquitectura IP, como se ve en 6LoWPAN [HCC09] el despliegue de este paradigma sería automático. [GKC04] sigue un enfoque similar, propone reducir la complejidad de la pila IP para conseguir un protocolo que este diseñado para enrrutar «IP sobre cualquier objeto».

De acuerdo tanto a los enfoques de IPSO como de Internet 0, el despliegue del IOT pasa por realizar una simplificación del actual IP, para adaptarlo a cualquier objeto y hacer que estos objetos sean direccionables y alcanzables desde cualquier localización.

Como se ha dicho anteriormente, existe otra perspectiva dentro del IOT, la «orientada a la semántica». La idea que hay detrás de ella se basa en que el número de objetos involucrados en el Internet del futuro, será extremadamente grande, y en este contexto, las tecnologías semánticas pueden jugar un rol importante. Como por ejemplo, el razonamiento sobre los datos generados o la ejecución semántica de entornos y arquitecturas que adapten los requi- sitos del paradigma y proporcionen almacenamiento y comunicación escalables dentro de la infraestructura [TSH09].

3.1.1 Tecnologías de identificación, captura y comunicación «En cualquier momento, en cualquier lugar, cualquier contenido multimedia» ha sido du- rante muchos tiempo la visión bajo la que se han producido los mayores avances en las tecnologías de comunicación. En este contexto, las tecnologías inalámbricas han jugado un rol fundamental y hoy en día la relación entre radiotransmisores y seres humanos, está cerca del uno por uno [Sri06]. Sin embargo, la reducción en términos de tamaño, peso, energía consumida y coste del radiotransmisor, puede llevarnos a una nueva era donde la relación anterior se vea incrementada en varios ordenes de magnitud. Esto permitirá integrar radio- transmisores en la mayoría de los objetos, y con ello, añadir «cualquier cosa» a la visión comentada anteriormente, la cual conduce inequívocamente al concepto de IOT.

En este marco, el componente clave serán los sistemas RFID [Fin10], los cuales están com- puestos de uno o más lectores y varias etiquetas RFID. La etiqueta consiste en un microchip que va adjunto a una antena de radio y que sirve para identificar unívocamente al elemento portador de la etiqueta, con esto se puede llegar a almacenar hasta 2KB de datos. El lector 3.1. INTERNET DE LAS COSAS 17 debe de ser capaz de leer los datos almacenados en la etiqueta, lo más normal será contar con un dispositivo que tenga una o más antenas que emitan ondas de radio y que reciban las se- ñales devueltas por la etiqueta RFID. Una vez hecho esto se puede trabajar con un ordenador sobre los datos que se han leído (veasé Figura 3.2).

Figura 3.2: Esquema de un Sistema RFID.

.

Los sistemas RFID pueden ser usados en un rango de escenarios de aplicación muy amplio, desde aspectos puramente logísticos hasta usos sanitarios o de seguridad.

Las redes de sensores también juegan un rol crucial en el IOT. De hecho, pueden cooperar con los sistemas RFID para mejorar el seguimiento de las «cosas», p.e. su localización, tem- peratura, movimientos, etc. consiguiendo con ello un aumento del conocimiento que se tenga sobre un cierto entorno y así, actuar como un enlace más entre el mundo físico y el digital. El uso de redes de sensores ha sido propuesto en muchos escenarios de aplicación, como en monitorización de entornos medioambientales, sanidad, sistemas inteligentes de transporte, militar y en monitorización de plantas industriales. Este tipo de redes están formadas por un determinado número de nodos sensores (normal- mente un número alto), que se comunican de forma inalámbrica con el resto de dispositivos de la red, que pueden ser o nodos «sumideros» (del inglés sinks) o pasarelas. Estas últimas se encargan de enlazar la red de sensores con una red de transporte de nivel superior, como 18 CAPÍTULO 3. ANTECEDENTES puede ser TCP/IP. La mayor parte de la literatura científica que se ha escrito sobre las redes de sensores, dirige sus esfuerzos a problemas relacionados con su pila de protocolos, como en [ASSC02]. Hoy en día, la mayoría de las soluciones comerciales para las redes de sensores inalámbri- cas, están basadas en el estándar IEEE 802.15.4, que define las capas física y MAC (Media Access Control). Este estándar no incluye especificaciones de las capas superiores de la pila de protocolos, y estas son necesarias para una integración sin fisuras de los nodos sensores dentro de Internet. El hecho de integrar los sensores en la infraestructura global de Internet supone una dificultad añadida para el despliegue de estas redes, por varias razones:

Las redes de sensores están formadas por un gran número de nodos, y esto puede conllevar problemas obvios ya que hoy en día hay escasa disponibilidad de direcciones IP.

El paquete más grande en IEEE 802.15.4 tiene una longitud de 127 bytes; lo que conlleva que los frames de la capa de acceso al medio tengan un tamaño de 102 octetos, que incluso puede verse disminuido dependiendo del tipo de seguridad que se use. Estos tamaños son demasiado pequeños si los comparamos con el tamaño típico de un paquete IP.

En muchos escenarios los sensores pasan la mayor parte del tiempo en estado «dur- miente» con el fin de ahorrar energía y no se pueden comunicar durante este periodo. Esto es absolutamente anómalo para las redes IP.

La integración de tecnologías sensoras con las etiquetas RFID, permitirá el despliegue de un gran número de nuevas aplicaciones en el campo del IOT, especialmente en el área de la sanidad [MOA10]. Esta integración de tecnologías da como resultado lo que se conoce como sistemas sensores RFID y permitirán formar redes de sensores RFID (RSN) [BGS+08], que consisten en pequeños dispositivos con capacidad de cómputo y basados en RFID, y lectores de RFID, que actúan como los sumideros de la información generada por las etiquetas RFID y proporcionan la potencia necesaria para que funcione la red.

3.1.2 Importancia del middleware El middleware es una capa de software o un conjunto de subcapas, interpuestas entre los niveles tecnológico y de aplicación. Tiene la característica de ocultar los detalles de las diferentes tecnologías que están por debajo de él, y esto es fundamental para eximir al programador de problemas que no están directamente relacionados con su propósito, que no es otro que el desarrollo de una aplicación especifica que hace uso de las infraestructuras del

IOT

En los últimos años se está incrementando la importancia del middleware debido a que juega un rol fundamental a la hora de simplificar el desarrollo de nuevos servicios y en la 3.1. INTERNET DE LAS COSAS 19 integración de nuevas tecnologías junto con la ya existentes. En este contexto, es importante mencionar el proyecto OpenIoT [LTQS+12], este proyecto propone una arquitectura que permite el desarrollo de aplicaciones basadas en el cloud-computing2 usando los servicios del IOT. La mayor parte del framework OpenIoT reside en el uso de una infraestructura de virtualización para integrar las diferentes tecnologías de las redes de sensores, dentro de la nube. OpenIoT define una serie de extensiones a estándares bien conocidos como la ontología SSN-XG para las definiciones de las redes de sensores y utiliza servicios RESTful para el acceso a los mismos. El trabajo de Fazio et al. [FPPV12] también hace uso de especificaciones de estándares y protocolos, como Sensor Web Enablement, para hacer frente a los problemas de hete- rogeneidad en las plataformas sensoras. Según estos autores, se identifican tres niveles de incompatibilidad en las infraestructuras complejas de sensores/actuadores:

Nivel de la tecnología del dispositivo.

Nivel de comunicación.

Nivel de datos.

En última instancia, los sensores son accedidos a través de la API REST, la cual se basa en lo que se denomina como Sensor Observation Service Agent que resume, de alguna forma, las distintas observaciones y el sistema sensor. Sin embargo, el uso de protocolos basados en la web (como HTML o XML) para la integración de sensores tiene 3 grandes inconvenien- tes:

Limita la clase y el tipo de dispositivos a usar, ya que la comunicación basada en texto demanda una cantidad considerable de ciclos de CPU para parsear los mensajes del protocolo.

La vida útil de la batería de los dispositivos se reduce en gran medida.

No es muy recomendable para las comunicaciones con una baja velocidad de transfe- rencia (como 802.15.4) ni en sus formas comprimidas (RESTFul, CoAP, etc).

La infraestructura que presenta este TFG, proporciona los servicios de un middleware bá- sico, utilizando los protocolos MQTT y MQTT-SN para construir una capa de abstracción sobre una de las tecnologías del IOT, en concreto para un tipo de redes de sensores.

3.1.3 Internet de las Cosas, un paradigma libre La importancia y el papel que juegan tanto el software, como los estándares libres en el

IOT es doble [Pul13]:

2Cloud-computing o computación en la nube. Se conoce con este nombre al paradigma que permite ofrecer servicios de computación, de almacenamiento y/o de software como servicios de pago por uso librando al usuario de los problemas de escalabilidad y mantenimiento. 20 CAPÍTULO 3. ANTECEDENTES

Por un lado, la gran variedad de dispositivos conectados a Internet, hará imposible o muy difícil para cualquier empresa o incluso un grupo de empresas, generar el código

necesario para los millones de sistemas diferentes que se unen al IOT. La única forma de que esto funcione será utilizando software libre, por lo que los fabricantes sólo tendrán que adaptarse a su dispositivo favorito. Un ejemplo de esta forma de proceder puede verse en lo que ha ocurrido con algunos de los códigos más exitosos en el campo de los teléfonos móviles. La otra razón que da una ventaja al software libre, es una revolución silenciosa que ha tenido lugar durante los últimos años, y que ha consistido en que las grandes empresas de electrónica han adoptado Linux empotrado para sus dispositivos, por razones obvias como:

• Menor coste. • Fiabilidad. • Capacidad de personalización. • Disponibilidad de herramientas, etc.

Esto significa que el software libre para el IOT va a integrarse mucho más fácilmente con estos dispositivos, ya que ambas partes son libres (asumiendo licencias compati- bles).

Debido a estos motivos, la infraestructura que se desarrolla con este TFG se basa en tec- nologías y estándares libres, para proporcionar sus servicios. En la práctica se encuentran múltiples tecnologías libres que ejemplifican todo esto [Pul13].

Arduino Arduino3 es una plataforma electrónica para la creación de prototipos, basada en software y hardware libres, flexibles y fáciles de usar. puede tomar información del entorno utilizando toda una gama de sensores, a través de sus pines de entrada y puede afectar aquello que le rodea controlando una serie de actuadores. El microcontrolador de la placa se programa mediante el lenguaje de programación Ar- duino (basado en Wiring) y el entorno de desarrollo Arduino (basado en Processing). Ar- duino está sirviendo como base a numerosas aplicaciones del IOT: sistemas de automatiza- ción del hogar, sistema para detectar terremotos, sistemas que avisan por Twitter cuando se produce algún evento, etc. Uno de los grandes hitos de Arduino ha sido la conexión de los teléfonos móviles con placas de esta marca, de forma que mediante el ADK (Android Open Accesory Development Kit) de Google, se permite la comunicación del sistema operativo Android con dispositivos hardware Arduino.

3http://arduino.cc/ 3.1. INTERNET DE LAS COSAS 21

Rasberry Pi The Raspberry Pi4 es un ordenador del tamaño de una tarjeta de crédito que se puede conectar a una televisión o a un teclado. Es un PC en miniatura con procesador ARM que se puede utilizar para muchas de las cosas que un PC convencional puede hacer. Ha sido desarrollado por la Fundación de Reino Unido con la intención de estimular la enseñanza de la informática básica en las escuelas.

OpenPicus 5 Open Picus es una compañía italiana que fabrica hardware para el IOT Los módulos están enriquecidos con un sistema operativo de software libre potente, pero ligero, y tiene embebi- do una pila de software TCP/IP, así como un servidor Web embebido. La compañía produce principalmente dos productos: Flyport, un sistema modular programable con conectividad a Internet y un IDE libre para crear, compilar y descargar aplicaciones para los módulos.

Accada Accada [GDFSB09] es un prototipo de plataforma Open Source RFID desarrollada por el Auto-ID Lab de la ETH Zurich/University St. Gallen, de Suiza. Ha sido diseñada para permitir a los usuarios finales, a integradores de sistemas y a los investigadores experimentar con protocolos de red EPCglobal para el desarrollo de nuevas aplicaciones. La plataforma incluye un módulo de lectura que puede ejecutarse en un dispositivo EPC o separado. Accada implementa el Protocolo EPCglobal (ERP).

Contiki + [D 06] es un sistema operativo de código abierto para el IOT que permite a sis- temas pequeños, que funcionan con baterías de baja potencia, comunicarse con Internet. Contiki se utiliza en una amplia variedad de sistemas tales como la monitorización de los niveles de ruido de la ciudad, el alumbrado de la calle, los medidores de energía eléctrica conectados en red, el control industrial, el control de la radiación, el monitoreo del sitio de construcción, sistemas de alarma, y control remoto de las viviendas. Contiki cuenta con una amplia comunidad de desarrolladores a nivel internacional, con contribuciones desde Atmel, Cisco, ETH, Redwire LLC, SAP, SICS, Thingsquare, y muchos otros.

ThingSpeak ThingSpeak6 es una plataforma abierta de aplicaciones diseñada para permitir conexiones entre las personas y los objetos. Esta compuesto por una aplicación Open Source para el IOT y

4http://www.raspberrypi.org/ 5http://www.openpicus.com/ 6https://thingspeak.com/ 22 CAPÍTULO 3. ANTECEDENTES una API para almacenar y recuperar datos de los objetos usando HTTP sobre Internet o vía una red de área local. Con ThingSpeak, se pueden crear aplicaciones de sensores, aplicaciones de seguimiento o de localización, y una red social de las «cosas» con las actualizaciones de su estado.

El API de ThingSpeak está disponible en GitHub para su descarga e instalación en un servidor propio, así mismo también se puede tomar el código fuente para modificarlo y con- tribuir con nuevas características. La licencia de ThingSpeak es la GPLv3 para el uso como Open Source, aunque también se puede obtener una licencia de ioBridge para aplicaciones de código cerrado.

OpenBeacon

El proyecto OpenBeacon7 es una plataforma abierta para aplicaciones RFID, que operan a frecuencia 2,4 GHz, banda ISM. OpenBeacon se basa en software libre y en un módulo muy flexible y de bajo costo reprogramable, Rfmodule Open Source. El código del firmware y los esquemas del hardware están disponibles bajo licencias GPL.

Grupo IoT eclipse.org iot.eclipse.org es el grupo de Eclipse encargado del desarrollo de tecnologías relacciona- das con el IOT (servicios, frameworks, protocolos, etc). Estas tecnologías tienen como obje- tivo establecer una pila de protocolos libre, con el fin de hacer que el desarrollo del IOT sea más sencillo. Incluyen un marco de desarrollo M2M, con el lenguaje de programación Lua, protocolos de comunicación como MQTT y OMA-DM y herramientas de desarrollo como Lua Development Tools. También tienen disponible toda una comunidad de desarrolladores en la que se puede participar de forma activa, y un entorno para testear las implementaciones de los distintos usuarios, denominado Sandbox.

Proyecto Eclipse Paho

Paho es otro de los proyectos desarrollados por la Fundación Eclipse en el ámbito del IOT Su objetivo es proporcionar implementaciones escalables y en varios lenguajes de progra- mación, de los protocolos MQTT y MQTT-SN. Con el objetivo de apoyar las aplicaciones existentes y emergentes en este paradigma, en concreto con MQTT ya que está en proceso de estandarización por el OASIS consortium [CCB14].

La versión 1.0 de sus implementaciones fue publicada en Junio de 2014, y ya forma parte de la nueva versión del IDE de Eclipse. Esta versión cuenta con:

Implementaciones MQTT para:

• C (Posix/Windows)

7http://www.openbeacon.org/ 3.2. SMART CITIES 23

• C (Embebido) • C++ • Java (J2SE) • Java (Android Service) • JavaScript • Python • Go Implementaciones MQTT-SN para: • C (Embebido)

3.2 Smart Cities El Proyecto Epic de la UE8 en relación a la definición de este paradigma, señala que la actual crisis económica, junto con las crecientes expectativas de los ciudadanos, está aumen- tando la presión sobre las ciudades para que estas proporcionen mejores infraestructuras y servicios más eficientes. Esta tendencia ha contribuido a la creciente popularidad y el uso del concepto Smart City cuyas definiciones varían ampliamente y van desde el uso discreto 9 de nuevas tecnologías como RFID, el IOT o el Big Data ; a una concepción más holística de inteligencia, como un desarrollo urbano que se basa en realizar una gestión sostenible de los recursos y así poder responder a las necesidades básicas de los ciudadanos, institu- ciones y empresas en los planos: económico, operativo, social y ambiental. Mientras que la primera definición es ampliamente utilizada por las empresas TIC de todo tipo, la segunda aproximación es la que ha adoptado la Comisión Europea, la cual desde principios de 1995 trata de mejorar los servicios públicos, las transacciones e interacciones con los ciudadanos y las empresas, a través de la financiación y el despliegue de una amplia gama de iniciativas [Pul13]. Desde otro punto de vista, una Smart City es un ecosistema complejo en el que intervienen numerosas tecnologías y múltiples agentes que las implementan, operan y usan, con el fin de proporcionar una serie de servicios. Por ello, para entender bien el valor de estos servicios, es necesario entender que puede ofrecer la tecnología. Desplegar una Smart City lleva asociada la creación de una serie de infraestructuras y es necesario disponer de mecanismos de gestión de la información generada y de diferentes plataformas, todo integrado bajo una perspectiva global. Para ampliar la definición dada en la Sección 1.1, en el siguiente apartado se expone la «cadena de valor tecnológica» de la Smart City. En el resto de apartados de esta sección se

8European Union Platform for Inteligent Cities. http://www.epic-cities.eu/ 9Conjunto de datos de gran volumen, de gran velocidad y procedente de gran variedad de fuentes de infor- mación que demandan formas innovadoras y efectivas de procesar la información. 24 CAPÍTULO 3. ANTECEDENTES profundiza en áreas de las ciudades inteligentes que tienen relevancia para el desarrollo de este TFG, como son los proyectos europeos, los middlewares, las plataformas de software libre existentes, el framework Civitas y la situación de las Smart Cities en España.

3.2.1 Tecnologías de la Smart City La «cadena de valor tecnológica» de la Smart City puede definirse en cinco pasos [tel11]:

En primer lugar se encuentra la etapa de recolección de datos de la ciudad. En segundo lugar se realiza la transmisión de los datos recopilados a través de las redes de comunicación. Una tercera fase comprende el almacenamiento y el análisis de los datos. En cuarto lugar, los datos alimentan una plataforma de provisión de servicios. Finalmente se encuentran los servicios de la Smart City.

Etapa de recolección de datos El primer paso para formar una Smart City es llevar a cabo un despliegue masivo de ins- trumentación que permita conocer que está pasando en la ciudad. Este despliegue incluye sensores y otros dispositivos de captura de datos con los que se pueda recolectar informa- ción. Los sensores son dispositivos capaces de convertir magnitudes físicas como la tempera- tura, la luminosidad, la presión atmosférica, etc. en valores que puedan ser tratados según convenga. Los hay de diferentes tipos: de recursos (luz, agua, gas), de seguridad (detecto- res de humo, sensores de gases), de iluminación, de presencia (infrarrojos, por vibración, fotoeléctricos, etc), de condiciones climatológicas (humedad, presión atmosférica), de in- fraestructuras de transportes, de movimiento (acelerómetro) y de posición (GPS). Aunque estos son los más importantes, la gama es más amplia y abarca la mayoría de las magnitudes físicas. En la actualidad los dispositivos de captación de datos han evolucionado, permitiendo la digitalización y la conexión a Internet de los mismos. Gracias a esto es posible poner a dispo- sición del público una gran cantidad de información en tiempo real y así plantear novedosos servicios en el marco de la Smart City. En la mayoría de los casos, estos dispositivos han adoptado el adjetivo de «smart» ya que utilizan tanto la información del entorno que les ro- dea como la información de su propio funcionamiento. Una estructura de red que use estos dispositivos para formar redes de sensores, se le denomina «ambiente inteligente» y tiene varias características clave:

La capacidad de realizar procesamientos gracias al microprocesador que tienen. La capacidad de almacenar información en la memoria que incorporan. 3.2. SMART CITIES 25

La facilidad de enviar datos gracias a un módulo de transmisión inalámbrica.

Hoy en día, existen multitud de redes de sensores cuyos datos pueden ser consultados a través de Internet, pero el problema radica en que cada red utiliza sus propios estándares, protocolos y formatos de representación de datos. Por este motivo es importante disponer de una plataforma que ayude a gestionar esta heterogeneidad. Hay que destacar que en un proyecto de Smart City es especialmente importante que los sensores tengan las siguientes características:

Sean de fácil instalación. Se auto-identifiquen. Se auto-diagnostiquen. Sean fiables. Se coordinen con otros nodos. Incorporen software que les permita tratar digitalmente la señal. Utilicen protocolos de control y de red estándares. Tengan un bajo consumo que les permita estar activos mucho tiempo. Tengan un fácil mantenimiento.

También es importante que los nodos sensores pueden re-programarse de forma inalám- brica. En este sentido, la metodología Over The Air Programming (OTA) es la que suele usarse. Otro grupo de tecnologías que pertenecen a este punto de la cadena, son las tecnologías de identificación, entre las que se encuentran: RFID, códigos BiDi y QR y los smartphones. Sobre RFID se habló en la Sección 3.1. Los códigos BiDi y QR son elementos que contie- nen información codificada y que permiten consultar información ampliada sobre múltiples objetos y elementos, a través del teléfono móvil. Por su parte, los smartphones actúan como dispositivos de captura de datos en el ámbito urbano. En definitiva, estas tecnologías permiten «sentir» la ciudad, sus infraestructuras, vehículos, habitantes, ambiente, etc.

Etapa de transmisión de datos En la comunicación que se debe llevar a cabo en una Smart City , no solo tienen que poder comunicarse los dispositivos entre sí, si no que también debe existir una comunicación entre personas y entre personas y dispositivos. De forma que, en la etapa de transmisión de datos juegan un papel fundamental las redes de comunicación. Estas redes por carácter general son muy heterogéneas, por lo que la interoperabilidad y la transparencia son aspectos muy importantes en ellas. 26 CAPÍTULO 3. ANTECEDENTES

En este ámbito las redes inalámbricas son las que ayudan de forma más significativa a transmitir los datos obtenidos del entorno. Hoy en día hay multitud de tecnologías inalám- bricas que buscan satisfacer los requisitos de este tipo de comunicación, pero no existe una tecnología que sea la que mejor funciona en todos los ámbitos, sino que cada una tiene una serie de características que hacen de ella una solución adecuada para un determinado entorno (en el Cuadro 3.1 puede verse una comparativa de algunas de estas redes). En cualquier ca- so, las comunicaciones en la Smart City suelen plantearse a diferentes niveles. En el nivel inferior se van recogiendo datos de los sensores en unos elementos que suelen llamarse re- petidores. En un segundo nivel, los repetidores se comunican con pasarelas, cuyo cometido es transferir los datos a una red de transporte de nivel superior. En estos niveles se pueden utilizar, por ejemplo, redes mesh (con tecnología inalámbrica Zigbee, por ejemplo) y luego, para conectar con la red de transporte superior se suelen usar tecnologías celulares, como GPRS o 3G, y si las pasarelas están conectadas a redes fijas, tecnologías como ADSL o fibra óptica.

Nivel físico y MAC Radio de acción Bit-rate Consumo Normas 250Kbps (2.4GHz) 10-100m interior Pico de Estándar ZigBee 802.15.4 200Kbps (868MHz) 1Km exterior 50mW (2.4GH) de facto 40Kbps (915MHz) 200m interior - Desde 10Kb/s 18mA RX Wavenis Propietario Propietario 1Km LOS Hasta 100Kb/s 45mA TX 50-70m interior WiFi low power 802.11b/g 40-100Kbps 20mA Estándar <300m exterior Se basa en IEEE WiMAX Hasta 75Km Hasta 75 Mbps 230mW-49mW Estándar 802.16 Modo reposo GSM/GPRS Hasta 85,6Kbps 2,6mA, GPRS cl. Estándar 10(max): 370

Cuadro 3.1: Características de redes inalámbricas. Fuente: [tel11]

Las comunicaciones M2M, al tratarse de comunicaciones entre dispositivos, son muy co- munes en el entorno de las Smart Cities y constituyen un factor importante de cara al desa- rrollo de las nuevas redes inalámbricas. Por este motivo, la mayoría de los organismos de estandarización están teniendo en cuentan este hecho a la hora de desarrollar nuevas versio- nes de las tecnologías. Las altas previsiones apuntan a que en 2020 habrá más de 50.000 millones de conexiones M2M [Ins10], con lo cual no solo es necesario cambiar de estándares, sino también crear nuevas arquitecturas y plataformas M2M, que sean aptas para manejar estos datos, y sobre todo, la heterogeneidad de las tecnologías que usan los dispositivos conectados a Internet. En este esquema habrá, por un lado, dispositivos conectados directamente a las platafor- mas y, por otro lado, dispositivos que tienen una relación entre si y que se conectan a la red a través de una pasarela que actúa como punto de acceso y agregación. Estas pasarelas o ga- teways son dispositivos que actúan entre dos tipos de redes, y juegan un papel fundamental 3.2. SMART CITIES 27 a la hora de recopilar los datos de los sensores y presentarlos a las capas superiores de la infraestructura. En ocasiones incluso, funcionarán como verdaderas plataformas y ofrecerán servicios de valor añadido (como servicios en la nube). Este esquema puede verse de forma gráfica en la Figura 3.3.

Figura 3.3: Arquitectura de alto nivel de tecnologías M2M en el marco de las Smart Cities. Fuente: [tel11]

Es en esta etapa donde este TFG contribuye con una implementación del protocolo MQTT- S/MQTT que permite la recolección y distribución de eventos software desde las redes de sensores inalámbricas hacia los servicios finales.

Etapa de almacenamiento y análisis de datos Con esta etapa se busca crear una capa lógica dentro de la Smart City con el objetivo de que ofrezca dos funcionalidades esenciales: (i) permitir disponer de toda la información necesaria para proveer los servicios, y (ii) permitir analizar los datos de la ciudad para poder mejorar los procesos de toma de decisiones. Se trata, además, de construir un modelo unificado de «ciudad» que pueda ser utilizado por diferentes aplicaciones y servicios de la Smart City. Además, toda la información necesaria para este propósito necesita de ciertos niveles de protección y seguridad, con lo cual en esta etapa deberán proporcionarse.

Los datos son la materia prima fundamental de todo servicio en el marco de la Smart City y, por su naturaleza (se consumen en tiempo real, muy variados, con diferentes formatos, etc) la gestión de estos es una tarea compleja. Surge, de este modo, la necesidad de contar 28 CAPÍTULO 3. ANTECEDENTES con herramientas que faciliten su homogeneización y estructuración. En este sentido, los almacenes de datos (del inglés data warehouses) son herramientas ampliamente conocidas como solución para almacenar y procesar grandes cantidades de información. En dichos almacenes se escriben datos que son necesarios o útiles para una organización como paso intermedio para posteriormente transformarlos en información útil para el usuario. Una vez estructurados los datos, también es necesario proporcionarles análisis y control, con el fin de sacarles el mayor partido posible e incluso realizar actividades de previsión de comportamientos, para ayudar a la toma de decisiones. En este sentido las técnicas de data mining se hacen imprescindibles.

Plataforma de provisión de servicios La plataforma de provisión de servicios de la Smart City (véase Figura 3.3) ofrece un conjunto de módulos que son comunes a los múltiples servicios que se ofrecen en el marco de la ciudad inteligente. Se trata pues, de una plataforma horizontal y escalable, que permite ofrecer servicios de una manera segura y con garantías de privacidad. Varias son las tareas principales de esta plataforma:

Autentificar a los usuarios. Obtener sus permisos para acceder a los datos privados. Establecer precios en tiempo real. Tener capacidad para realizar transacciones de pago de servicios. Almacenar los datos de forma segura. Facilitar el análisis de uso de los servicios, etc.

Este tipo de plataformas se denominan Service Delivery Platform y en un entorno urbano se han definido como Sistemas Operativos Urbanos (en inglés, Urban OS). Resultan esen- ciales para la construcción de una Smart City pues son las que resuelven los problemas con las tecnologías subyacentes, facilitando tareas comunes al resto de servicios, que son los que deben aportar valor a la ciudad inteligente. En apartados posteriores de esta sección se detallan aspectos de algunas de estas platafor- mas.

Servicios finales de la Smart City Los servicios finales de la Smart City se apoyan en todas las tecnologías, infraestructuras y plataformas anteriormente comentadas para ofrecer su valor final al cliente. Hay numerosos ejemplos de servicios finales posibles, tantos como servicios públicos que ha de prestar un Ayuntamiento, aunque no únicamente. También hay otros servicios que pueden prestarse en el marco de la plataforma Smart City por otros agentes que no necesariamente tienen que ser 3.2. SMART CITIES 29 servicios públicos pero que se van a volver indispensables para asegurar tanto la calidad de vida como la sostenibilidad en el ámbito de las ciudades. En este sentido se abren muchas oportunidades de negocio.

3.2.2 Middlewares A las tecnologías que intervienen en las etapas de recolección y transmisión de datos, pueden aplicársele un primer nivel de abstracción y considerar a todas ellas como el IOT. Desde este punto de vista, el paradigma de la Smart City puede verse como un sistema distribuido que utiliza el IOT para proporcionar datos a un conjunto de aplicaciones, que los usarán para elaborar servicios a niveles estratégico y táctico.

Como ya se ha mencionado, el IOT es posible gracias a la integración de diversas tec- nologías, lo que genera una gran heterogeneidad en cuanto al tipo de dispositivos, redes, estándares y protocolos. Por ejemplo, no se necesita la misma tecnología para que una per- sona proporcione datos que recogen los sensores de su Smartphone, que para conocer el estado de polución del aire de una zona rural. Estas diferencias, a priori, son un problema si queremos que ambos casos formen parte de un todo, como puede ser una Smart City. El middleware es la única solución a este inconveniente, y gracias a él se consigue pro- porcionar la suficiente abstracción para que desarrolladores e investigadores puedan trabajar con los datos que genera el IOT, sin necesidad de lidiar con los problemas que las tecnologías subyacentes puedan generar. Uno de los problemas principales de la Smart City es el conocido como «isla de servicios» o «isla de información», problema que aparece si se desarrollan servicios como aplicaciones independientes que luego son incapaces de interaccionar. Ejemplos de este tipo de servi- cios se encuentran en la gestión del tráfico [KS13], human dynamics [VAG13], rutas para bicicletas [CLI13], etc. El uso de un middleware como una de las partes de la Smart City soluciona este problema, ya que, entre otras ventajas, evita que se tengan que crear todos los servicios desde cero. Con el uso de middlewares se incorporan de forma automática algunos servicios tan importantes como la seguridad. Los que tengan relación directa con las Smart Cities, tendrían que ser añadidos como nuevas capas. En el Cuadro 3.2 se pueden ver algunos de los middlewares que son candidatos a soportar las Smart Cities. Unos son específicos, creados para resolver un tipo concreto de problema, y otros son genéricos. Como ya se ha mencionado, la infraestructura que se desarrolla con este proyecto, pretende ser un middleware básico basado en MQTT, para el IOT.

3.2.3 Civitas: Plataforma de soporte a las ciudades inteligentes Civitas es un plataforma software distribuida que pretende ser el sistema nervioso de la ciudad del futuro, recopilando y distribuyendo la información que se genera y consume por 30 CAPÍTULO 3. ANTECEDENTES

Middleware Modelo Lenguaje Protocolo Aplicación Java RMI RMI Java Binario General ZeroC ICE RMI Multiple Binario General JXTA P2P Multiple Basado en XML General MQTT Eventos Multiple Binario Internet de las Cosas SOFIA Eventos/SOA Multiple Multiple Smart Cities U-City Servicios Web Multiple Basado en XML Smart Cities OpenIoT REST Multiple Basado en HTTP Internet de las Cosas

Cuadro 3.2: Middlewares. Fuente: [VSV+13] parte de los ciudadanos, empresas y gobiernos. Junto con esa labor de distribución, se ofre- cerán una serie de servicios comunes a desarrolladores, para la elaboración de servicios inteligentes de diversa índole. Esta plataforma de investigación se está desarrollando en el grupo ARCO de la Universi- dad de Castilla-La Mancha. Este TFG es parte de esta plataforma de investigación y muchos de los requisitos impuestos vienen heredados de la necesidad de integración con el resto de la plataforma como se verá más adelante. Una de las claves para que una plataforma de este tipo tenga éxito, es que debe centrarse en facilitar la vida a los desarrolladores mediante las siguientes características principales [VSV+13]:

Proporcionar al desarrollador libertad para desarrollar con aquellas tecnologías más apropiadas al servicio que está desarrollando, por lo que debe ser libre de escoger el lenguaje de programación y el sistema operativo que desee. Tener clara la nomenclatura e interfaces que se utilizan en la plataforma. Tener libertad para implementar el modelo de seguridad que mejor se adapte al servicio a desarrollar y tener los mecanismos adecuados para ello en la plataforma. Tener acceso a servicios avanzados que le permitan centrarse en la funcionalidad de su servicio. Al igual que los middlewares genéricos proporcionan servicios relacionados con varios dominios de aplicación (gestión de eventos, despliegue, etc.), un middlewa- re orientado a ciudades inteligentes debe proporcionar servicios avanzados, relaciona- dos con este dominio de aplicación (anonimización, estructura de la ciudad, actividad de las redes sociales relacionadas con la ciudad). A partir de estos servicios se pueden generar nuevos servicios más avanzados, con un coste de desarrollo acotado.

Para que Civitas pueda tener estas funcionalidades se necesita que toda una pila de tec- nologías, estándares, procesos, etc. trabajen de forma conjunta. La Figura 3.4 muestra un esquema del framework que pretende ser Civitas [RAB+14]. En la ciudad tienen que ser monitorizados y controlados un grán número de procesos, esta 3.2. SMART CITIES 31

Figura 3.4: Esquema del framework Civitas. Fuente: [RAB+14] función la proporcionan los sensores y actuadores, luego la capa más baja de Civitas estara´ formada por este tipo de dispositivos. De acuerdo a los tipos de servicios que se quieran pro- porcionar, un conjunto de específico de sensores y actuadores tendrá que ser desplegado en la ciudad. La información que estos generen, junto con información de otros tipos (por ejemplo la que generan los ciudadanos), es recopilada usando una infraestructura ICT (Information and Communications Technologies).

Los servicios de naturaleza similar son proporcionados usando infraestructuras comunes (red de distribución agua/eléctrica, redes de transporte, etc.), una Smart City debería con- tar con una capa ICT para al despliegue de estos servicios y dispositivos. A nivel lógico, la capa Civitas backbone tiene un propósito similar al de la capa ICT a nivel físico. Civitas backbone se encarga de recopilar, agrupar y distribuir la información, acorde a cada cam- po de aplicación (seguridad del hogar, gestión de residuos, social media). Es en esta capa donde la implementación de MQTT-S/MQTT proporciona un protocolo estándar abierto de recopilación y distribución de eventos software.

Estos campos de aplicación, a su vez, están divididos en servicios específicos (control 32 CAPÍTULO 3. ANTECEDENTES de semáforos, monitorización de polución, monitorización de tráfico, gestión de plazas de aparcamiento, etc.).

Sobre estos campos de aplicación, Civitas ofrece una capa de razonamiento y análisis con el fin de hacer frente a la extracción de información a partir de datos en bruto. De nuevo, esta capa está especializada según los diferentes campos de aplicación y la información es proporcionada a distintas entidades (gobiernos, instituciones y ciudadanos), que también proporcionarán información.

Finalmente, una capa avanzada de visualización y control permite la interacción avan- zada con los humanos, con el fin de monitorizar y controlar los diferentes procesos de la ciudad.

Cada capa y cada servicio en Civitas ofrece una o varias interfaces orientadas a objetos, que permiten interactuar con su funcionalidad. Estas interfaces están descritas usando un Interface Definition Language IDL (Interface Description Language), el cual proporciona una herramienta excelente para establecer un «contrato» entre el desarrollador que proporciona el servicio y el desarrollador que lo usa.

De forma adicional, con el fin de integrar sensores de diversos grupos, en la capa de sensores y actuadores, Civitas soporta varios protocolos. Esto se lleva a cabo a través del despliegue de un conjunto de «nodos de servicios», con cuatro interfaces cada uno:

802.15.4 a 868.6 MHz, para la información recopilada por sensores. Esta tecnología es usada para redes de sensores/actuadores.

802.11 a 2.4 GHz, para los servicios públicos a los ciudadanos, permitiendo a estos conectarse a la infraestructura de la Smart City en puntos específicos, para acceder directamente a sus servicios.

802.11 a 5.8GHz, para conectar los «nodos de servicios» entre ellos y formar redes mesh, en el caso en que no sea posible una conexión Ethernet.

Interfaz Ethernet para conectar los «nodos de servicios» al resto de la infraestructura cableada.

3.2.4 Smart City en España España está mostrando un gran interés a la hora de invertir en el campo de las Smart Cities10, tanto con fondos del estado, como en proyectos conjuntos con la Unión Europea. Actualmente existe una red de ciudades inteligentes españolas llamada Red Española de Ciudades Inteligentes (RECI)11, cuyo objetivo es fomentar la gestión automática y eficiente de las infraestructuras y de los servicios urbanos, con el fin de que las ciudades progresen.

10Para realizar esta sección se ha consultado [Sel14] 11http://www.redciudadesinteligentes.es/ 3.2. SMART CITIES 33

RECI agrupa las ciudades miembro en diferentes ámbitos de trabajo, según corresponda a una u otra temática. Los grupos son los siguientes:

Grupo 1: Innovación Social.

Grupo 2: Energía.

Grupo 3: Medio Ambiente, Infraestructuras y Habitabilidad.

Grupo 4: Movilidad Urbana.

Grupo 5: Gobierno, Economía y Negocios.

La red está formada por más de 48 ciudades de toda España, entre las que se establece un ranking que se encuentra encabezado por Málaga, Barcelona y Santander.

La Smart City de Málaga, o MalagaValley tiene como principal objetivo el ahorro ener- gético y para ello ha invertido en infraestructuras y servicios, que permitan gestionar de forma eficiente recursos en los campos del transporte, agua, movilidad y alumbrado público. Barcelona, por su parte, está teniendo gran repercusión a nivel internacional, no sólo por albergar grandes congresos o liderar el campo de investigación en el área de las Smart Cities, sino también por tomar el liderazgo en ciertos proyectos como la estandarización de City Protocol Society12.

En cuanto a Santander, la Smart City se desarrolla en torno al proyecto SmartSantander que fue iniciado en 2009 con el objetivo de realizar una gestión coordinada e integral de la ciudad bajo la idea del IOT y las nuevas tecnologías. Se pretende que una vez finalizado, haya más de 20.000 dispositivos de diversos tipos (cámaras, sensores, etc.), que se encargarán de recopilar datos de la ciudad de distinto índole. Estos serán controlados por Cloud City Center, un centro de operaciones que se encarga de integrar la gestión de los servicios de la ciudad inteligente y desarrollar el proyecto.

Entre algunos de los servicios que ya están implantados en SmartSantander, cabe destacar el denominado calm traffic, que se encarga de informar a los ciudadanos acerca de plazas de aparcamiento libres en tiempo real, influyendo positivamente en la reducción de CO2, el ahorro de combustible y el tiempo empleado por el ciudadano en estacionar su vehículo. Para la realización de esta aplicación se ha usado la plataforma Waspmote Plug & Sense de la empresa Libelium, en concreto se han desplegado numerosos sensores Waspmote que in- corporan la Smart Parking Sensor Board, haciendo uso de esta placa, los sensores detectan la variación en el campo magnético que produce un vehículo cuando está aparcado sobre ellos. La información que proporcionan los sensores es enviada a repetidores, y estos a pasarelas, que actualizan la información disponible para los ciudadanos. En la ciudad hay una serie de paneles que indican el número de plazas libres y que se recargan cada 5 minutos (véase 3.5).

12http://www.cityprotocol.org/ 34 CAPÍTULO 3. ANTECEDENTES

Las pasarelas también actualizan un mapa dinámico que los ciudadanos pueden consultar (véase Figura 3.6) [Bie13].

Figura 3.5: A la izquierda la Smart Parking Sensor Board junto con Waspmote, instalada en una plaza de aparcamiento. A la derecha uno de los paneles informativos. Fuente: [Bie13]

Figura 3.6: Mapa interactivo que muestra la disponibilidad de plazas de aparcamiento. Fuen- te: [Bie13]

3.2.5 Proyectos Europeos en el marco de la Smart City La Unión Europea está destinando miles de millones de euros al desarrollo de proyectos innovadores y de I+D+i en el marco del IOT y la Smart City. Algunos de los más importantes, tienen como objetivo el desarrollo de plataformas y servicios comunes a nivel europeo, que permitan el desarrollo y despliegue de las ciudades inteligentes y la provisión de servicios basados en el IOT. La mayoría de estos proyectos, publican sus resultados con licencias de software libre, lo que permite que las soluciones desarrolladas puedan ser compartidas a nivel europeo. A continuación se muestran algunos de estos proyectos: 3.2. SMART CITIES 35

SOFIA (Smart Objects for Intelligent Applications) SOFIA [WLZZ12] ha sido un proyecto de I+D+i desarrollado entre 2009 y 2011, en el marco de la iniciativa Tecnológica Conjunta ARTEMIS13. Con este proyecto, se ha desa- rrollado una plataforma basada en tecnología web semántica, interoperabilidad y redes de sensores inteligentes (Smart Items, veasé Sección 3.1) que permite la automatización de las ciudades, edificios y automóviles, así como la provisión de servicios inteligentes y perso- nalizados, por ejemplo, geolocalización o detección de movimiento a través de dispositivos móviles. En el proyecto han participado dieciocho países socios de la UE, tanto entidades públicas, como privadas. Todas las soluciones técnicas desarrolladas en el marco del proyecto son Open Source y se ha creado una comunidad entorno al mismo. Esto ha posibilitado, por ejemplo, que uno de los socios del proyecto, en concreto la empresa Indra, haya lanzado su propia Plataforma Urbana de Interoperabilidad (UOIP), denominada Atenea.

PEOPLE: Smart Cities for Smart Innovation PEOPLE es otro proyecto de colaboración público/privada financiado por el programa Marco de Competitividad e Innovación en el área de las Smart Cities. PEOPLE se centra en el ámbito de los servicios y aplicaciones de las ciudades inteligentes, en concreto, el proyecto ha puesto en marcha dieciséis servicios inteligentes Open Source, en cuatro ciudades euro- peas: Bilbao (España), Bremen (Alemania), Thermi (Grecia) y Vitry sur Seine (Francia).

ICOS En el marco del proyecto PEOPLE, se ha desarrollado una interesante iniciativa denomi- nada ICOS-Intelligent/Smart Cities Open Source Community y que consiste precisamente en una comununidad de desarrolladores en el campo de las Smart Cities. La comunidad está orientada a cualquier persona que esté interesada en el desarrollo de las ciudades inteligentes y busque aplicaciones y soluciones Open Source que se hayan aplicado con éxito en otras ciudades.

3.2.6 Plataformas y aplicaciones Open Source para la Smart City La cooperación y el intercambio de información son ideas fundamentales en la Smart City [Pul12]. Estas ideas son compartidas con el movimiento del software libre. El software de código abierto o Open Source es una valiosa fuente de tecnologías, aplicaciones y soluciones para las ciudades inteligentes y para la informática en general. Puede encontrarse tecnología Open Source en toda la cadena de valor tecnológica de la Smart City [tel11]. Desde las tecno- logías para la captura de datos, pasando por la transmisión de los mismos, su almacenamiento

13La empresa común Artemis es un organismo comunitario dotado de personalidad jurídica. Se crea por un periodo que finaliza el 31 de diciembre de 2017, para ejecutar una iniciativa tecnológica conjunta sobre sistemas de computación empotrados. 36 CAPÍTULO 3. ANTECEDENTES y análisis, plataformas y las propias aplicaciones de la Smart City.

A continuación se muestran algunas de las múltiples soluciones Open Source disponibles a la hora de implementar software para la Smart City [Pul12]. Tiene especial interés la plata- forma Waspmote Plug&Sense de Libelium, ya que es sobre la que se desarrolla este TFG.

Libelium Waspmote Plug & Sense Waspmote Plug & Sense, Plataforma de Redes Inalámbricas de Sensores de la empresa aragonesa Libelium, es un ejemplo de plataforma Open Source capaz de tratar con diferentes tecnologías, protocolos de comunicación y bases de datos, que permite a los desarrolladores diseñar y desplegar aplicaciones de sensores para diversos entornos del IOT como:

Smart Cities

Smart Environment

Smart Water

Smart Metering

Security and Emergencies

Smart Agriculture

Smart Animal Farming

Domotic and Home Automation

eHealth

Waspmote es una plataforma horizontal y modular, especialmente orientada a los desarro- lladores, que trabaja con diferentes protocolos, frecuencias, rangos, etc. (véase Cuadro 3.3). Los sensores cuentan con modos de bajo consumo sleep e hibernate que les permiten ahorrar batería cuando no están transmitiendo, y con placas específicas para aplicaciones particulares (Radiation Board, Prototyping Board, Events Board, etc.). En la actualidad cuentan con más de 50 tipos de sensores disponibles (humedad, temperatura, radiación, etc) y un entorno de desarrollo integrado de código abierto, que cuenta con APIs y compiladores para programar los diferentes dispositivos.

Waspmote cuenta con más de 2000 desarrolladores entre las empresas más importantes del mundo (Telefónica, Iberdrola, Sony , Intel, Siemens, IBM, etc.) así como desa- rrolladores en más de 75 paises. Algunos ejemplos de despliegue de servicios para la Smart City a partir de la utilización de esta plataforma son:

Proyecto Smart Parking en Santander [Bie13], para monitorear las plazas de aparca- miento disponibles. 3.2. SMART CITIES 37

Modelo Protocolo Frecuencia TX power Sensibilidad Rango XBee-802.15.4 802.15.4 2.4 GHz 1mW -92 dB 500 m XBee-802.15.4-Pro 802.15.4 2.4 GHz 63 mW -100 dBm 7000 m XBee-ZigBee Zigbee-Pro 2.4 GHz 2 mW -96 dBm 500 m XBee-ZigBee-Pro Zigbee-Pro 2.4 GHz 50 mW -102 dBm 7000 m XBee-868 RF 868 MHz 315 mW -112 dBm 12 km XBee-900 RF 900 MHz 50 mW -100 dBm 9 km XBee-XSC RF 900 MHz 100 mW -106 mW 9 km

Cuadro 3.3: Distintas tecnologías de comunicación ofrecidas por Libelium.

Proyecto PRETESIC en Valencia [Bie12], para monitorear la red de alcantarillado sanitario en tiempo real, con el fin de determinar la calidad del agua y definir si los elementos que se encuentran dentro de la red funcionan correctamente.

Proyecto RESCATAME en Salamanca14, para medir la calidad del aire.

Proyecto SISVIA «Vigilancia y Seguimiento Ambiental» en Asturias, para la detec- ción de incendios forestales.

Además de esto, en las versiones más recientes de sus productos, permiten interactuar con plataformas en la nube, como Axeda, Esri, ThingWorx, MQTT o Sentilo. Esta última, es la primera plataforma para la Smart City desarrollada para un municipio completo, Barcelona. El ayuntamiento de Barcelona está inmerso en un proyecto cuyo fin es monitorizar el ruido y la polución del aire en las zonas públicas de la ciudad, para ello está utilizando los productos de Libelium y la plataforma de software Sentilo.

En este TFG se utiliza la plataforma Waspmote para desplegar por encima de ella la infra- estructura de comunicación que pretende desarrollarse.

Code for America Commons En Estados Unidos se desarrolla el proyecto Code for America Commons15. Se trata de un proyecto creado por Code for America en colaboración con Open Plans, lanzado en 2011 como un experimiento de colaboración en materia de innovación ciudadana y que ha evo- lucionado hasta convertirse en la actualidad en una oferta independiente. El proyecto parte de la premisa de que los gobiernos pueden hacer un mejor uso del dinero que invierten en tecnología, trabajando juntos para resolver problemas comunes. El objetivo del proyecto es ayudar a las autoridades a que compartan sus soluciones, conocimientos y mejores prácticas. El proyecto está compuesto por:

Un directorio de aplicaciones comunes o Civic Commons Marketplace.

14http://www.rescatame.eu/DisplayPage.aspx?pid=24 15http://commons.codeforamerica.org/apps 38 CAPÍTULO 3. ANTECEDENTES

La base de conocimientos Wiki Commons.

En el Civic Commons Market se encuentran aplicaciones organizadas por el tipo de soft- ware, por funcionalidad, o por licencia. En la actualidad hay un total de 72 aplicaciones con licencias de software libre (GPL, Apache, MIT y BSD). A continuación se muestran dos a modo de ejemplo:

FixMyStreet: permite a cualquier ciudadano reportar al Ayuntamiento cualquier pro- blema que detecte en la ciudad. Open Legislation: es un servicio que permite a los ciudadanos navegar, buscar y com- partir información legislativa, así como un servicio que permite que otras aplicaciones accedan a sus datos básicos a través de una robusta API.

Open City También en Estados Unidos pero a nivel local, en concreto en la ciudad de Chicago, se desarrolla la iniciativa ciudadana Open City, el cual es un proyecto de un grupo de volun- tarios que crean aplicaciones para la Smart City utilizando Open Data de la ciudad, con el objetivo de mejorar la transparencia y el conocimiento del gobierno por parte de la ciudada- nía. Algunas de estas aplicaciones son:

2nd City Zoning: mapa interactivo que permite saber cómo un edificio está dividido en zonas. Permite ubicar los negocios y explorar patrones de zonificación de la ciudad. Edifece: es una serie de mapas que exploran el medio ambiente de Chicago, desde el impacto ecológico de las áreas edificadas, a las violaciones de demoliciones y nuevas construcciones. How’s Business: ofrece un panel de la economía de Chicago. Utiliza el Open Data de la ciudad, la Oficina de Estadísticas Laborales y el Instituto Woodstock, para mostrar la tendencia de varios indicadores económicos desde 2005.

3.3 Programación orientada a eventos En esta sección se introduce al lector dentro del último ámbito de este proyecto que queda por tratar, el paradigma de la programación orientada a eventos y el modelo de comuni- cación que lleva asociado. Se estudiarán sus aspectos teóricos, como los tipos de sistemas que pueden formarse, o las distintas topologías existentes. Después se introduce el protocolo MQTT, sobre el que se estructura la infraestructura que pretende desarrollarse. Y por último se realiza una comparación entre tecnologías. De un tiempo a esta parte, se ha ido incrementando el uso del paradigma de la publi- cación/suscripción de eventos, debido a que propone un tipo de comunicación que posee un acoplamiento más flexible entre las partes involucradas y una mayor escalabilidad. En 3.3. PROGRAMACIÓN ORIENTADA A EVENTOS 39 general, los suscriptores registran sus intereses mediante un topic o un patrón de eventos y después, de forma asíncrona reciben la información que se ha publicado sobre esos intereses. La fuerza de este estilo de comunicación reside en el desacoplamiento en cuanto a espacio y tiempo, entre suscriptores y publicadores de información.

Existen varios tipos de sistemas basados en la publicación/suscripción. La clasificación más popular los divide en subject-based systems y content-based systems o sistemas basados en el contenido [LP+03].

Por una parte, en los subject-based systems, un mensaje pertenece a uno, o a un conjunto de grupos, canales o topics. Las suscripciones van dirigidas a estos grupos, canales o topics, y los clientes reciben todos los eventos que estén asociados a dichos conjuntos. En este contexto, se denomina brokering entre publicadores y suscriptores, al acto de conectar un canal proveedor con un canal consumidor de eventos, y por ende, se denomina broker al dispositivo que realiza esta función.

Por otra parte, los sistemas basados en el contenido no están limitados a la noción de que un mensaje debe pertenecer a un grupo particular. En su lugar, la decisión de a quién se dirige se toma sobre una base de mensajes, basándose en consultas o predicados emitidos por los suscriptores. La ventaja frente a los sistemas anteriores reside en la flexibilidad, se proporciona al suscriptor simplemente la información que necesita, no es necesario que conozca un conjunto de topics y su contenido antes de suscribirse. Una desventaja de este tipo de sistemas es la carga que depositan en el sistema subyacente encargado de asociar mensajes a suscripciones. El número de suscripciones únicas puede ser varios ordenes de magnitud superior al número de grupos que deben ser gestionados por el sistema. Por lo tanto, la asociación mensaje-suscripción debe ser altamente eficiente.

La arquitectura también es una característica que diferencia estos sistemas, se distinguen dos tipos de sistemas atendiendo a su arquitectura:

Basados en un modelo push, en estos sistemas los mensajes se distribuyen automá- ticamente a los suscriptores utilizando broadcast. Este modelo proporciona ajustada consistencia y almacena un mínimo de información.

Basados en un modelo pull, cuya principal característica es una mejor adaptabilidad a las necesidades de usuario.

Los sistemas basados en la publicación-suscripción deben proporcionar escalabilidad, (i) en términos de la gestión de suscripciones, (ii) en términos de una asociación cliente-evento eficiente cuando existe un gran número de suscriptores y (iii) en términos de una distribución eficiente de eventos. 40 CAPÍTULO 3. ANTECEDENTES

3.3.1 Topologías Un sistema basado en eventos es un paradigma de comunicación distribuida, que consta de varios tipos de componentes software. Estos pueden ser servidores de eventos, clientes de eventos, o ambos. La arquitectura de estos sistemas puede ser clasificada en las categorías de Cliente/Servidor (C/S) y Peer-to-Peer (P2P).

En el modelo C/S, hay dos tipos de componentes: servidores y clientes de eventos. Los servidores de eventos, reciben eventos, de forma opcional pueden almacenarlos y después, los reenvían. Estos servidores pueden comunicarse con otros del mismo tipo para lograr una mejor escalabilidad. Los clientes actúan como suscriptores, publicadores, o como ambos. Dependiendo de como actúen los servidores, surgen varios tipos de topologías:

Topología en estrella (servidor centralizado). Donde un servidor actúa de broker entre todos los publicadores y suscriptores. Topología jerárquica. Se basa en una relación jerárquica entre los servidores de even- tos. Se utiliza el mismo protocolo tanto para las comunicaciones servidor-servidor, como para las cliente-servidor. Un servidor recibirá publicaciones y suscripciones de todos sus clientes pero solo reenviará los eventos que vayan destinados a su subárbol. El propósito de esta topología es la escalabilidad.

Topología en anillo. En este caso, los servidores tienen una relación P2P entre ellos y el grafo de conexión forma un anillo. La comunicación entre servidores se implementa con un protocolo de comunicación bidireccional que permite intercambiarse suscrip- ciones y notificaciones, distinto al utilizado para la comunicación cliente-servidor. Topología en polígono irregular. Es una generalización de la topología en anillo, sin la restricción de que los servidores tengan que estar conectados en anillo, pueden adoptar cualquier forma geométrica. El protocolo entre servidores también es distinto al usado entre cliente-servidor.

La Figura 3.7 es una representación esquemática de cada una de ellas, donde pueden verse los servidores («server»), los suscriptores («s»), los publicadores («p») y las distintas cone- xiones entre estos elementos, linea fina para las conexiones cliente-servidor y linea gruesa para la conexión entre servidores.

En el modelo P2P todos los nodos son iguales, es decir, cada nodo puede actuar como pu- blicador, suscriptor, como raíz de su árbol, nodo interno de un árbol, o cualquier combinación lógica. Por lo que no hay servidores ni clientes en este modelo, una parte de la funcionalidad de servidor está incorporada como parte local de cada nodo.

3.3.2 MQTT MQTT es un protocolo ligero basado en la publicación/suscripctión de mensajes a un broker, sigue el modelo de los subject-based systems. Está diseñado para ser: abierto, simple, 3.3. PROGRAMACIÓN ORIENTADA A EVENTOS 41

Figura 3.7: Distintas topologías de los sistemas basados en eventos. Fuente: [LP+03] ligero y fácil de implementar. Sus características lo hacen ideal para:

Redes de poco ancho de banda y poco fiables. Dispositivos empotrados con recursos de memoria y procesamiento limitados.

Historia MQTT fue originado en la década de 1990 dentro del sector industrial. Las compañías buscaban monitorizar los sistemas industriales y mecánicos que tenían en sus fábricas, para ello se requería una tecnología que fuese muy ligera y con un alto grado de adaptabilidad a la hora de ejecutarse sobre sistemas y dispositivos con recursos limitados.

Hasta ese momento, el protocolo que actuaba en estos entornos era SCADA (Supervisory Control and Data Acquisition), y las primeras versiones de este protocolo eran monolíticas, propietarias y sistemas cerrados. Para mejorar esta situación IBM trabajaba junto con algunos colaboradores, uno de ellos era la compañía Arcom, para desarrollar un protocolo ligero basado en mensajes como alternativa a SCADA, que permitiese mejor escalabilidad y mayor facilidad de integración. De forma que, MQTT nació en una era y en un entorno en el que premiaba aprovechar al máximo los recursos de computación y de ancho de banda disponibles. Fue diseñado para sistemas con limitaciones de memoria y ciclos de CPU, y también para redes con un ancho 42 CAPÍTULO 3. ANTECEDENTES de banda mínimo y alta latencia. En todos estos escenarios había que ser especialmente cuidadoso con cada byte transmitido y MQTT se diseñó pensando en ello. Como resultado, hoy en día, en la era de las conexiones de banda ancha y de smartpho- nes con mucha más capacidad que los ordenadores de los 90, MQTT puede ejecutarse de forma muy eficiente sobre pequeños dispositivos o en zonas donde la cobertura de red es irregular.

Características Sus principales características son:

Sigue un modelo de comunicación basado en la publicación/suscripción de mensa- jes, lo que le permite una distribución de uno a uno, uno a muchos, muchos a uno y desacoplada de las aplicaciones. Se basa en la publicación/suscripción a topics. Los topics se organizan de forma jerár- quica, como un sistema de archivos (por ejemplo, a/b/c). Transporta los mensajes con un desconocimiento total de la carga útil.

Uso de TCP/IP para proporcionar conectividad básica de red.

Tres tipos de QOS:

• At most once, donde los mensajes son entregados de acuerdo al servicio best effort de TCP/IP. Pueden ocurrir la perdida y la duplicación de mensajes. Esta

QOS es útil, por ejemplo, cuando en una red de sensores puede permitirse perder mensajes porque va a ser reenviado pronto. • At least once, donde se asegura que los mensajes llegan, pero pueden ocurrir duplicados. • Exactly once, donde los mensajes solo llegan una vez y además se asegura que no haya duplicación.

Introduce una sobrecarga de transporte muy pequeña (la cabecera corta de los mensajes tiene tan solo 2 bytes) e intercambios de mensajes reducidos, para minimizar el tráfico de red. Posee un mecanismo conocido como last will and testament, para notificar a las partes interesadas de una desconexión anormal. El cliente informa al broker de que mensajes debe distribuir a determinados topics, cuando se produzca una desconexión descontro- lada. Soporta que el broker almacene mensajes de forma persistente. Cuando se publican mensajes, los clientes pueden requerir persistencia para ellos, de forma que cuando un cliente se suscribe a un topic, todos los mensajes persistentes le serán enviados. 3.3. PROGRAMACIÓN ORIENTADA A EVENTOS 43

En la versión 3.1 se añade el uso de usuario y contraseña para que el broker propor- cione servicios de autenticación. Estos se especificarán en el establecimiento de la conexión MQTT. Para asegurar privacidad, la conexión TCP puede ser cifrada usando SSL/TLS.

MQTT-SN MQTT es un protocolo que opera sobre redes TCP/IP, para que se establezca una conexión MQTT, previamente debe haberse establecido una conexión TCP entre las dos partes de la comunicación. Consecuentemente, este protocolo no puede ser ejecutado directamente sobre una red de sensores ya que estas tienen su propia pila de protocolos (por ejemplo, Zigbee sobre 802.15.4). Para solventar este problema y poder beneficiarse de las características de MQTT en una red de sensores, IBM desarrolló MQTT-SN. MQTT-SN fue diseñado para ser lo más cercano posible a MQTT, pero está adaptado a las peculiaridades de las redes de sensores inalámbricas, como pueden ser: alta probabilidad de fallo, mensajes cortos, red de bajo ancho de banda, etc. Algunas de sus diferencias con MQTT son:

El mecanismo last will and testament se desacopla del establecimiento de la conexión, para hacerla más ligera. Esta característica se configura en dos mensajes adicionales, dividiéndose el establecimiento de la conexión en tres partes: (i) conectarse, (ii) confi- gurar will topic y (iii) configurar will message; las dos últimas opcionales. Para acortar la longitud de los mensajes, con el fin de cumplir con los requisitos de una red de sensores, se han acortado los nombres de los topics a los que se publica. Estos han sido reemplazados por un identificador de topic (Topic Id) y se ha definido un procedimiento para permitir a los clientes registrar sus topics completos en el broker, y obtener su correspondiente identificador de topic. Se introducen lo que se denomina como pre-defined Topic Ids y Short Topic Names, para los que no es necesario registro previo. Un procedimiento de descubrimiento ayuda a los clientes sin un broker configurado, a descubrir su actual dirección de red. Se extiende la funcionalidad de las sesiones limpias de MQTT (en las que no se alma- cena información alguna en el broker una vez desconectado el cliente), para que los campos will topic y will message puedan tener persistencia. Además, un cliente podrá modificarlos durante su sesión. Se ha definido un procedimiento para que los brokers soporten cliente «dormidos», mediante el uso de una máquina de estados.

Se ha definido un nuevo nivel de QOS, el nivel -1. En el que un cliente MQTT-SN no necesita enviar mensajes de establecimiento de conexión a la pasarela, sino que 44 CAPÍTULO 3. ANTECEDENTES

directamente publica y es la pasarela la que se encarga de mantener una sesión MQTT con el broker, que finaliza cuando se realiza la publicación.

La arquitectura de MQTT-SN puede verse en la Figura 3.8. Hay tres tipos de componentes: clientes MQTT-SN, pasarelas MQTT-SN y forwarders MQTT-SN. Los clientes se conectan a un broker MQTT a través de una pasarela, usando el protocolo MQTT-SN. La pasarela puede estar o no, integrada con el broker. En caso de no estarlo, se usa el protocolo MQTT entre el broker y la pasarela, cuya función principal será la traducción entre ambos protocolos.

Figura 3.8: Arquitectura MQTT-SN. Fuente: [SCT13]

En el caso de que la pasarela no esté directamente conectada a la red de los clientes, estos también pueden acceder a la pasarela a través de un forwarder. La función de este dispositivo es simple, encapsula los frames MQTT-SN que le llegan desde la parte inalámbrica de la red y los envía sin modificar hacia la pasarela; en la dirección opuesta, desencapsula los frames que recibe desde la pasarela y los envía a los clientes, también sin modificar. En función de como realicen el proceso de traducción entre MQTT y MQTT-SN, se dis- tinguen dos tipos tipos de pasarelas: transparentes y de agregación (véase Figura 3.9). Cabe destacar que en este TFG se implementa una pasarela transparente. Una pasarela transparente mantiene una conexión MQTT con el broker para cada cliente MQTT-SN conectado a ella. Esta conexión MQTT es exclusiva para cada cliente y propor- ciona un intercambio de mensajes de extremo a extremo entre el cliente y el broker MQTT. Las ventajas de este tipo de pasarela son: su facilidad de implementación con respecto a la de agregación y que como consecuencia de la conexión extremo a extremo que se establece, 3.3. PROGRAMACIÓN ORIENTADA A EVENTOS 45

Figura 3.9: Tipos de pasarelas. Fuente: [SCT13] todas las características del broker están disponibles para el cliente. Su principal desventaja es la escalabilidad, ya que al tener que mantener una conexión dedicada para cada cliente, el rendimiento del broker puede verse disminuido en redes de sensores con un gran número de dispositivos. Por otra parte, una pasarela de agregación tan solo mantiene una conexión con el bro- ker MQTT. Todos los mensajes intercambiados entre un cliente MQTT-SN y la pasarela, finalizan en la pasarela. Es esta, la que decide que información será transmitida al broker y cual no. Implementar este tipo de pasarelas es una tarea más compleja, pero su rendimiento es mucho más eficiente en redes grandes, ya que se reducen las conexiones MQTT que el broker tiene que mantener concurrentemente. Otra de característica importante de este protocolo es que está diseñado de tal manera que es independiente de los servicios de las redes subyacentes. Es decir, que cualquier red que proporcione un servicio de transferencia de datos bidireccional entre un nodo y una pasarela, debe ser capaz de soportar MQTT-SN.

Brokers MQTT Como puede verse a lo largo de esta sección, el broker es la pieza clave de los sistemas basados en la publicación/suscripción de eventos y por ende, en los sistemas que utilizan MQTT y MQTT-SN. En el Cuadro 3.4 puede verse una comparativa entre los brokers MQTT más utilizados actualmente. Clave: soportado, no soportado, ? desconocido, % ver limitaciones. 46 CAPÍTULO 3. ANTECEDENTES

Broker QoS 0 QoS 1 QoS 2 Auth Puente SSL Topics dinámicos Websockets mosquitto         RSMB         WebSphere MQ        ? HiveMQ         Apache Apollo         Apache ActiveMQ    ? ? ? ?  RabbitMQ        ? MQTT.js    %    ? moquette    ????  mosca     ? ? ? 

Cuadro 3.4: Comparativa entre brokers MQTT. Fuente: [MQT].

Limitaciones: MQTT.js acepta conexiones con usuario y contraseña, pero actualmente no realiza el procedimiento de autentificar la conexión.

3.3.3 Otras tecnologías Como paradigma emergente y uno de los llamados a confeccionar el Internet del futuro, el

IOT debe hacer frente a numerosos problemas, interrogantes y retos que están aún por resol- ver. Una de las consecuencias directas del crecimiento de este paradigma es la proliferación de protocolos que pueden dar soporte al IOT.

En el marco de la tecnologías orientadas a eventos, algunos protocolos como XMPP, AMQP, MQTT, etc. están cambiando la forma en que se construye y se utiliza la web, quedan- do esta cada vez más distanciada de su visión clásica, basada en HTTP, HTML y en protocolos de petición/respuesta. En el resto de apartados de esta sección, se realiza una comparativa entre alguno de estos protocolos y MQTT, que es el protocolo elegido para implementar la infraestructura que se presenta en este TFG.

AMQP AMQP (Advanced Message Queuing Protocol) es un protocolo binario de la capa de apli- cación, diseñado para soportar eficientemente una amplia variedad de aplicaciones de men- sajería y patrones de comunicación. Proporciona control de flujo, comunicación orientada a mensaje con tres tipos de QOS (at-most-once, at-least-once y exactly-once) y autentica- ción y/o cifrado basado en SASL16 y TLS. AMQP asume una capa de transporte subyacente confiable, como la que proporciona TCP.

Tanto MQTT como AMQP [Coh] cubren las necesidades básicas de la mensajería, con la diferencia de que AMQP proporciona un conjunto más completo de escenarios de comunica- ción. Ambos protocolos están siendo promovidos para un uso amplio en Internet:

16Simple Authentication and Security Layer (SASL), es un framework para la autentificación y la seguridad de los datos en los protocolos de Internet. 3.3. PROGRAMACIÓN ORIENTADA A EVENTOS 47

MQTT como una forma sencilla y con poca sobrecarga, de implementar el envío de datos, especialmente entre dispositivos empotrados.

AMQP como complemento asíncrono a HTTP.

Como tales, ambos están siendo promovidos en los campos de la computación en la nube y del IOT.

Origenes AMQP tiene sus orígenes en la comunidad financiera, y está enfocado al con- sumidor. MQTT está dirigido desde una visión del vendedor, lo crearon IBM y sus socios, como una reacción al alto coste de implementación que las MQSeries infligían en los consu- midores de dispositivos pequeños. Estas dos aproximaciones tienen una fuerte influencia en el diseño y las características de los protocolos.

Uso pretendido El uso pretendido para un protocolo influye en su diseño. Ambos protoco- los giran entorno a TCP/IP, y pretenden ser usados para permitir que los programas envíen y reciban mensajes de forma asíncrona, independientemente de su hardware, sistema operativo o lenguaje de programación. Sin embargo, a partir de esta base, surgen ciertas diferencias. MQTT está diseñado para ser usado por dispositivos pequeños, generalmente dispositivos empotrados que envían pequeños mensajes a través de redes de bajo ancho de banda. AMQP, por otra parte, está diseñado para proveer todos los tipos de escenarios de mensajería que han tenido lugar en los últimos 25 años. Los principios de diseño de MQTT son un subconjunto de sus usos previstos.

Optimización del frame de datos Ambos protocolos proporcionan un alto nivel de op- timización de los frames de datos. MQTT usa una aproximación mas orientada al stream, facilitando la generación de frames a los dispositivos de pocos recursos. AMQP usa una aproximación orientada a buffer, permitiendo disponer de servidores de alto rendimiento. MQTT no permite la fragmentación de mensajes, lo que supone una dificultad extra a la hora de transmitir mensajes largos en dispositivos pequeños. AMQP si lo permite.

Escenarios de mensajería MQTT soporta la publicación/suscripción de mensajes a topics. El tipo de mensajería que proporciona MQTT es efectiva, pero solo en algunos casos, esta optimizada para ser usada en el caso de tener simultáneamente publicadores y suscriptores conectados. Consecuentemente, es difícil que pueda ser usada para la mensajería clásica que requiere mantener durante un periodo largo de tiempo, colas de mensajes. AMQP soporta este caso, y muchos más, dispone de cinco tipos diferentes de tiempos de vida para publicadores y suscriptores, desde «tanto tiempo como este conectado» a «nadie está usando esta cola». AMQP también permite varios tipos de colas de mensajes, como las clásicas, round-robin, store-and-forward y combinaciones entre ellas. 48 CAPÍTULO 3. ANTECEDENTES

Transacciones MQTT no soporta transacciones, soporta acuses de recibo básicos. AMQP soporta distintos tipos de acuses de recibo y de transacciones a través de las colas de men- sajes. Esto no discrimina a MQTT, simplemente lo hace tener un uso para escenarios más específicos.

Seguridad En cuanto a la seguridad de la conexión, MQTT permite usar los servicios de SSL para establecer una comunicación segura entre máquinas. AMQP, por su parte, está integrado con TLS y SASL. En cuanto a la seguridad del usuario, MQTT en su versión 3.1 permite el uso de usuarios y contraseñas para la autenticación del cliente, esto no proporciona mucha seguridad en el mundo actual. Además, las contraseñas viajan como texto plano si no usa TLS. AMQP permite el uso de los mecanismos SASL, dejando a las organizaciones la elección de que medidas de seguridad tomar (por ejemplo, Kerberos V5).

Confiabilidad de los mensajes Ambos protocolos proporcionan confiabilidad a los men- sajes, esencialmente usando acuses de recibo para asegurarse que el mensaje ha llegado exactamente una vez. Además de esto, AMQP proporciona «recuperación del enlace», lo que permite un control más fino de la comunicación y asegura eventualmente la distribución de información bajo condiciones «hostiles».

Espacio de nombres El espacio de nombres de MQTT es una jerarquía de topics, a la que todos los mensajes van dirigidos y después se distribuyen de forman adecuada en función del topic. AMQP implementa varios espacios de nombres (como «nodos» o «colas»), cada uno puede tener varias formas de identificar mensajes.

Implementación MQTT es más sencillo de implementar, es un protocolo más sencillo que AMQP. En cuanto a eficiencia, ambos protocolos han sido implementados en dispositivos con menos de 64Kb de RAM, pero MQTT, por sus principios de diseño, se ejecuta de forma más eficiente sobre este tipo de dispositivos.

Extensibilidad AMQP tiene definidos ciertos puntos donde es posible la incorporación de extensiones. MQTT no, requiere una nueva versión del protocolo para incorporar una nueva funcionalidad.

XMPP

eXtensible Messaging and Presence Protocol (XMPP), es un protocolo de la capa de apli- cación diseñado originalmente por Jermie Miller en 1998 para la mensajería instantánea (originalmente llamado Jabber). El protocolo consiste, a grandes rasgos, en un sistema de 3.4. CONCLUSIONES 49 mensajería presencial que usa datagramas en XML para implementar las funcionalidades ne- cesarias en este tipo de mensajería.

Es un protocolo libre y abierto (según el estándar de software libre). XMPP fue creado con la intención de unificar los servicios de mensajería, dado que para su época no existía un pro- tocolo que pudiese satisfacer dicha necesidad, lo que llevaba a situaciones incómodas como el uso de múltiples clientes (uno por cada servidor/servicio), lo cual era altamente ineficien- te. Esta situación motiva a su creador a desarrollar un protocolo que pudiese convertirse en estándar de facto.

XMPP fue diseñado para ser extensible y también puede ser usado para: sistemas de publi- cación/suscripción de eventos, VOIP, vídeo, transferencia de archivos, juegos y aplicaciones del IOT.

En el Cuadro 3.5 se muestra una comparativa entre MQTT y XMPP.

3.4 Conclusiones En este capítulo se ha descrito el contexto en el cual se origina la motivación de este proyecto, Civitas, y sus dos principales campos de aplicación (IOT y Smart Cities). Era im- portante hacer una descripción completa de estos campos de aplicación de cara a entender cómo encaja este TFG en la pila compleja de herramientas, tecnologías y protocolos que necesitan ser orquestadas para el éxito tanto del IOT como de las Smart Cities.

Este TFG proporciona una herramienta para la recolección/distribución de eventos soft- ware en redes de sensores inalámbricas de bajo coste. En la última parte de este capítulo se describe tanto la programación orientada a eventos, como la especificación MQTT, así como otras tecnologías relacionadas que pueden dar al lector una visión más amplia de este campo. 50 CAPÍTULO 3. ANTECEDENTES

XMPP MQTT Estándar Estandarizado por la IETF en los RFCs En proceso de estandarización por el 6120 y 6121. Libre de derechos de au- OASIS (MQTT) Technical Committee. tor. Libre de derechos de autor desde que IBM liberó su especificación. Modelo Petición/respuesta. Publicación/sus- Publicación/suscripción. cripción. Seguridad Fuerte. Incorpora SASL y TLS. Media. Autentificación de cliente y co- nexión seguro con SSL. Flexibilidad Flexibe. Admite extensiones para aña- No flexible. Se requiere una nueva ver- dir nuevas funcionalidades o para sión del protocolo para añadir una fun- adaptar al protocolo a nuevas tecnolo- cionalidad. gías. Las desarrolla XSF (XMPP Stan- dards Foundation), o cualquier organi- zación o proyecto individual de soft- ware, p.e. Google+. QOS No soportada. Soportada. 3 tipos (veasé 3.3.2). Sobrecarga Alta. XMPP está basado en procesa- Muy baja. La cabecera corta de los miento de texto y esto produce una so- mensajes tan solo ocupa 2 bytes. En brecarga en la red y un gasto alto en general es un protocolo muy ligero que recursos de cómputo. introduce una sobrecarga mínima en la red. Websockets Si. Si. Soporta IOT Si. En principio sería un protocolo de- Si. Debido sus características, MQTT masiado pesado debido a que está ba- es un protocolo ideal para los requisi- sado en XML y no se adaptaría bién tos que impone el IOT. a los dispositivos empotrados. Pero la capacidad de permitir extensiones ha- cen que pueda adaptarse a esta situa- ción. Escalabilidad Alta. P.e. la aplicación Whatsapp Alta. Por lo general, depende de la ca- lidad de los nodos servidores y de la topología que usen. p.e. el chat de Fa- cebook.

Cuadro 3.5: Comparativa entre XMPP y MQTT. Capítulo 4 Metodología de trabajo

N este capítulo se pretende informar al lector de todos los aspectos relacionados con la E metodología de desarrollo empleada para la realización de este TFG. Se muestra ade- más, la planificación inicial del proyecto, con sus diferentes fases, etapas y la temporización estimada para cada una de ellas, y también las herramientas, tanto hardware como software, que han sido utilizadas.

4.1 Metodología de trabajo Para la realización de este proyecto se ha elegido una metodología de desarrollo ágil, en concreto eXtreme Programming (XP) [Bec00]. Este hecho puede ser contradictorio si se parte de la base de que los requisitos del proyecto estaban bastante bien acotados desde un principio y se tenían claros los objetivos a lograr. Sin embargo, debido a la poca experiencia por parte del desarrollador en este tipo de proyectos, resultaba imposible realizar un calculo, siquiera aproximado, de aspectos como la duración de cada una de las etapas del proyecto o de la totalidad del trabajo necesitado para terminarlo. Además, no se fijó un número concreto de funcionalidades con las que se dotaría a la infraestructura, si no que conforme avanzase el proceso de desarrollo y fuesen necesarias, se añadirían a la lista de características implementadas. Produciéndose de esta forma saltos entre las diferentes etapas, haciendo imposible el uso de metodologías convencionales, como el modelo en cascada. Este modelo está basado en el ciclo convencional de una ingeniería y su visión es muy simple: el desarrollo de software se debe realizar siguiendo una secuencia de fases, cada una de ellas formada por un conjunto de metas bien definidas. El arquetipo del ciclo de vida abarca las siguientes actividades [Rog02]:

Ingeniería y análisis del sistema. Análisis de los requisitos del software. Diseño. Codificación. Pruebas. Verificación.

51 52 CAPÍTULO 4. METODOLOGÍA DE TRABAJO

Mantenimiento.

En este modelo se aprecia una ventaja evidente y no es otra que la sencillez a la hora de seguir unos pasos intuitivos para desarrollar software. Pero el modelo se aplica en un contexto, así que debe atenderse también a él y saber que [JPPM10]:

Los proyectos reales raramente siguen el flujo secuencial que propone este modelo.

No siempre es fácil establecer todos los requisitos al principio. El ciclo de vida clásico lo requiere y resulta dificultoso acomodar posibles incertidumbres que pueden existir al comienzo de un proyecto.

Hasta llegar a las etapas finales del proyecto, no se obtendrán los primeros resultados. Lo que conlleva a que un error importante puede que no sea detectado hasta que el código este funcionando.

El desarrollo ágil intenta solucionar estos y otros problemas de los modelos convenciona- les, en el caso de este proyecto tiene especial importancia la problemática al intentar aplicar prácticas de estimación y planificación, ya que no se tienen claros estos datos, y puede ter- minar en un esfuerzo vano la realización de estas técnicas.

El abanico de metodologías ágiles es amplio [CLP03], desde métodos para organizar equi- pos, hasta técnicas para escribir y mantener el software. Como ya se ha dicho, en este pro- yecto se ha usado XP como metodología, en concreto una de sus técnicas, Test Driven De- velopment (TDD). En los siguientes apartados de esta sección se proporcionan más detalles sobre estos métodos.

4.1.1 eXtreme Programming (XP)

XP es una metodología ágil creada por Kent Beck, cuyo objetivo principal es entregar al cliente el software que necesita en el momento que lo necesita, respondiendo a los requeri- mientos cambiantes de los clientes incluso en la fases finales del ciclo de vida del desarro- llo.

XP se basa en una serie de valores que deben ser maximizados en todo proyecto para alcanzar el éxito [BMA02]:

Simplicidad: Únicamente hay que hacer lo que se nos pide, de la forma más sencilla posible. Los objetivos marcados se conseguirán dando pequeños pasos, corrigiendo fallos que vayan apareciendo sobre la marcha.

Comunicación: Para evitar errores de desarrollo es necesaria la comunicación de todas las partes del proceso de desarrollo.

Retroalimentación: Se realizan iteraciones cortas en las que se presenta un software funcional al cliente. 4.1. METODOLOGÍA DE TRABAJO 53

Honestidad: Hay que ser honestos sobre las estimaciones y afrontar los problemas que se presenten.

Con el fin de maximizar estos valores, XP establece una serie de reglas y prácticas que deben ser realizadas. Estas reglas se agrupan en cinco tipos [NMF+02]:

Planificación: El primer paso es describir la funcionalidad del software, mediante la recopilación de «historias de usuario». A cada una de estas historias se le asigna una prioridad y el equipo de desarrollo evalúa el tiempo que será necesario para realizar cada una de ellas. El proyecto se divide en iteraciones y se planifica el comienzo de cada una de ellas.

Gestión: Se realiza una reunión entre los miembros al inicio de cada día para medir la velocidad a la que avanza el proyecto.

Diseño: Se realizan esfuerzos para conseguir facilitar la comprensión rápida del códi- go, por ello se utilizan nombres claros y descriptivos que no requieran documentación extra. Se crean soluciones «spike1.» y se utiliza la recodificación siempre que sea po- sible, para reducir riesgos.

Codificación: El cliente, en cierta forma, pasa a formar parte del grupo de trabajo, ya que se le requiere disponibilidad durante todo el proyecto. Se hace uso de estándares y se realiza una programación dirigida por pruebas (véase Sección 4.1.2). También se establece una programación por parejas, con el fin de evitar errores.

Pruebas: Son uno de los conceptos más importantes en XP. Para cada módulo deben existir sus correspondientes pruebas unitarias, que deberán ser pasadas en su totalidad antes de la publicación de dicho módulo. Para la corrección de errores se deberán escribir pruebas que permitan verificar que el error ha sido resuelto.

4.1.2 Test Driven Development (TDD)

TDD es una técnica de diseño e implementación de software incluida dentro de la metodo- logía XP. Se centra en tres pilares fundamentales [JPPM10]:

La implementación de las funciones justas que el cliente necesita y no más. Con lo que se evita desarrollar funcionalidades que nuca serán usadas.

La minimización del número de defectos que llegan al software en fase de producción.

La producción de software modular, altamente reutilizable y preparado para el cambio.

A priori, TDD parece que se trata de una buena técnica para que el código tenga una cobertura de test muy alta, algo que siempre es deseable, pero en realidad es una herramienta

» 1Un spike es un pequeño programa que se escribe para indagar en la herramienta, explorando su funciona- lidad 54 CAPÍTULO 4. METODOLOGÍA DE TRABAJO de diseño que convierte al programador en un desarrollador. Esta metodología da repuesta a las grandes preguntas de:

¿Cómo lo hago?, ¿Por dónde empiezo?, ¿Cómo sé qué es lo que hay que im- plementar y lo que no?, ¿Cómo escribir un código que se pueda modificar sin romper funcionalidad existente?

Con el fin de no realizar esfuerzo en vano a la hora de determinar aspectos importantes de nuestro proyecto, como el tipo de arquitectura, patrones de diseño, modelo de comunicación, etc. En TDD se deja que la propia implementación de pequeños ejemplos, en constantes iteraciones, hagan surgir dichos aspectos, además de una forma más certera y seguro, pues ya se está escribiendo código que funciona.

En el libro de Kent Beck [Bec03], se dan unos argumentos muy claros y directos sobre por qué merece la pena, o por qué es beneficioso usar TDD. Estas son algunas de las razones:

Aumenta la calidad del software.

Se consigue código altamente reutilizable.

El trabajo en equipo se hace más fácil.

Multiplica la comunicación entre los miembros del equipo.

Las personas encargadas de la garantía de calidad adquieren un rol más inteligente e interesante.

Escribir el test antes que el código, obliga a escribir el mínimo de funcionalidad nece- saria, evitando sobrediseñar.

Los test se convierten en la mejor documentación técnica que se puede consulta.

El algoritmo TDD

La utilización correcta de TDD como técnica de diseño, conlleva la aplicación del algorit- mo TDD, que consta de tres etapas [JPPM10]:

Escribir la especificación del requisito (el test).

Implementar el código según dicho test.

Refactorizar para eliminar duplicidad y hacer mejorar.

Con el primero de estos pasos, se consigue expresar en forma de código el requisito. Este código será un test, que inicialmente puede ser visto como un ejemplo o especificación. Para escribir este test es necesario pensar primero en un comportamiento del SUT (del inglés, Subject Under Test) bien definido y en como se podría comprobar que, efectivamente, hace lo que se le pide. 4.2. PLANIFICACIÓN DEL PROYECTO 55

Una vez realizado el test, debe escribirse únicamente el código necesario para que este sea superado con éxito. No importa que el código se vea «feo», eso se enmendará en la siguiente etapa y en las siguientes iteraciones. Durante este proceso surgirán dudas sobre distintos comportamientos del SUT ante distintas entradas, pero debe evitarse el impulso de codificarlas sobre la marcha, y limitarse a anotar esas dudas para futuras especificaciones. Refactorizar2 no significa reescribir el código, refactorizar significa modificar el diseño sin alterar su comportamiento. Con lo cual en la tercera etapa, se revisa el código, test inclusive, en busca de líneas duplicadas, posibles mejoras y prestando atención a que se cumplan los principios de diseño establecidos. La clave de una buena refactorización es hacerla en pasos pequeños. Se hace un cambio, se ejecutan todos los test y, si todo sigue funcionando, se hace otro pequeño cambio.

4.2 Planificación del proyecto En las Figuras 4.1 y 4.2 puede verse la planificación inicial del proyecto, la cual se ha organizado por etapas y de forma jerárquica. También se ha estimado la duración que tendrá cada etapa, pudiendo variar estos tiempos según requiera el desarrollo del proyecto. Como puede verse la fecha de inicio del proyecto es el 10 de Enero de 2014, y la de finalización el 19 de Junio de 2014. Así que, en principio, la parte de implementación del proyecto tiene una duración de 5 meses y 9 días, más el tiempo que se emplee en completar la documenta- ción.

Figura 4.1: Etapas del proyecto.

4.3 Herramientas En esta sección se muestran todas las herramientas hardware y software, que han sido utilizadas en este TFG, tanto las empleadas para desarrollar las distintas partes del código,

2El verbo refactorizar no existe como tal en la Real Academia Española pero, como indican en [JPPM10], es la mejor traducción del término inglés refactoring. 56 CAPÍTULO 4. METODOLOGÍA DE TRABAJO

Figura 4.2: Diagrama de Gantt del proyecto. como las empleadas para elaborar toda la documentación. También se exponen los distintos lenguajes de programación que han sido utilizados. Obsérvese que todas las herramientas software son libres, accesibles a cualquier usuario que quiera utilizarlas.

4.3.1 Hardware Como medios hardware se han utilizado: un ordenador portátil, un ordenador de sobreme- sa, una placa sensora y una pasarela, estos dos últimos de la empresa Libelium.

El ordenador portátil es un HP ProBook 4510s y ha sido utilizado para realizar todas las tareas de programación, tanto de la placa sensora, como de la pasarela, como los distintos test. También es el equipo en el que se ha realizado toda la fase de búsqueda de información previa al comienzo del proyecto, y con el que se ha escrito la documentación.

El ordenador de sobremesa es un HP Envy y su cometido ha sido el de actuar como servi- dor MQTT, HTTP y NodeJS, durante el desarrollo del proyecto.

Tanto la placa sensora como la pasarela, son productos de la empresa Libelium y han sido utilizadas para realizar un despliegue mínimo de una de las redes de sensores sobre las que pretende usarse la infraestructura de comunicación que se desarrolla en este TFG (véase Sección 5.1). La placa es una Waspmote PRO v1.2 con un módulo XBee S1/S2, incorporado para lograr conectividad inalámbrica. Ambos dispositivos forman parte del Evaluation Kit que distribuye Libelium para desarrolladores. Por su parte, la pasarela es una Meshlium Xtreme ZigBee Sensor Gateway.

Características de Waspmote PRO v1.2 Las placas Waspmote son sistemas empotrados que tienen las siguientes características [Lib14b]:

Microcontrolador ATmega1281.

Frecuencia de 14.7456 MHz.

Memorias: SRAM de 8 KB, EEPROM de 4 KB y FLASH de 128 KB. 4.3. HERRAMIENTAS 57

Tarjeta SD de 2 GB.

Peso de 20 gr.

Clock RTC a 32 KHz. El módulo XBee incorporado transmite utilizando el estándar 802.15.4, sus características pueden verse en la Sección 3.2.6 y de forma más amplia en [Lib14a].

Características de Meshlium Meshlium es un computador con arquitectura x86, algunas de sus características son [Lib13a]: Procesador a 500 MHz.

256 MB de memoria RAM.

8 GB de disco duro.

Power Over Ethernet (POE) como fuente de alimentación.

Wi-Fi (802.11 a/b/g).

ZigBee (802.15.4).

Bluetooth 2.1.

3G/GPRS (3G, WCDMA, HSPA, UMTS, GPRS, GSM).

Sistema Debian Linux.

4.3.2 Software Los medio software utilizados han sido muchos y muy variados, de forma que se organizan por categorías:

Sistema operativo Tanto en el ordenador de sobremesa como en el portátil, se ha utilizado el sistema ope- rativo Debian GNU/Linux jessie/sid de 64 bits. En la pasarela también se ha utilizado la distribución Debian, en este caso la versión 6 de este sistema, en su rama estable. Los dispo- sitivos Waspmote se utilizan sin necesidad de sistema operativo, directamente a través de la API que proporciona Libelium.

Software de desarrollo GNU Emacs Editor de texto extensible perteneciente al proyecto GNU. Este editor ha sido usado como IDE para programar en C/C++, JavaScript y HTML5. La documentación del proyecto también ha sido realizada utilizando este editor. La versión utilizada ha sido GNU Emacs 23.4.1. 58 CAPÍTULO 4. METODOLOGÍA DE TRABAJO

CUnit CUnit es un sistema ligero para escribir, gestionar y ejecutar test unitarios en C. Proporciona funcionalidades de testing básicas a los programadores de C, ofreciendo 4 ti- pos de interfaces de usuario: automática (genera un archivo XML), básica (proporciona una interfaz flexible), consola (interfaz interactiva basada en terminal) y curses (interfaz gráfica para sistemas Unix). Este framework ha sido utilizado para testear la librería MQTT.

Plugin de MQTT para Wireshark Wireshark es un analizador de protocolos utilizado para realizar análisis y solucionar problemas en redes de computadores, para desarrollo de software de redes y de protocolos, y también como una herramienta didáctica. Con esta he- rramienta, puede verse de forma estructurada, la información contenida en los paquetes de los distintos protocolos que se utilizan para la comunicación en red. En este caso solo in- teresaba interceptar y analizar los paquetes MQTT, como Wireshark no proporciona soporte para ello, ha sido necesario instalar el plugin MQTT dissector for Wireshark para conseguir esta funcionalidad.

Mosquitto Mosquitto es un broker MQTT Open Source, que implementa la versión 3.1 del protocolo y que ha sido utilizado como broker MQTT para este proyecto. En el caso de Debian, mosquitto se encuentra disponible en los repositorios oficiales de la distribución, con lo cual solo tendremos que buscar los paquetes adecuados e instalarlos con el gestor de paquetes que se prefiera.

IDE y API de Libelium Libelium proporciona un IDE y una API a todos los desarrolla- dores, para programar los dispositivos Waspmote. El IDE está basado en el IDE de Arduino. Libelium recomienda usar siempre las últimas versiones, que están disponibles en su página web oficial. En este caso se han usado las versiones 4 (IDE) y 9 (API).

Secure SHell (SSH) SSH es el nombre de un protocolo y del programa que lo implemen- ta. Sirve para acceder a máquinas remotas en red y manejarlas por completo mediante un interprete de comandos. SSH también permite copias datos de forma segura, gestionar cla- ves RSA y pasar los datos de cualquier otra aplicación a través de un canal seguro. Este software ha sido utilizado para acceder a la pasarela Meshlium y así poder controlarla y programarla.

Software para documentar LATEX LATEX es un sistema de composición de textos, escrito por Leslie Lamport en 1984, con la intención de facilitar el uso del lenguaje de composición tipográfica TEX , creado por Donald Knuth. Es software libre bajo licencia GPL. Se ha utilizado para realizar esta memoria. 4.3. HERRAMIENTAS 59

BibTeX Herramienta que se usa para dar formato a las listas de referencias de los docu- mentos escritos en LATEX . Ha sido utilizado para crear las referencias de este documento.

LibreOffice Draw Draw es uno de los programas que forman parte de la suite ofimática LibreOffice, sirve para crear imágenes en varios formatos (pdf, png, jpeg, svg, etc.) y ade- más, por sus características, también es bastante útil para crear diagramas y esquemas. Se ha utilizado la versión 4.2.5.2 de este software para crear las imágenes de esta documenta- ción.

Gimp e Inkscape Ambos son programas de manipulación de imágenes. Se han utilizado para retocar o editar algunas de la imágenes de esta documentación.

GanttProject GanttProject es una aplicación de escritorio multiplataforma para la progra- mación y gestión de proyectos, muy similar a Microsoft Project. Es libre y Open Source, tiene licencia GPL y es un proyecto de software que surgió en la Universidad de Marne-la- Vallée, en Francia.

Control de versiones Para el control de versiones se ha utilizado Git, un software diseñado por Linus Torvalds que permite una gestión eficiente y distribuida de proyectos. Con Git se ha gestionado un repositorio alojado en Bitbucket 3

4.3.3 Lenguajes de programación Para el desarrollo de este proyecto se han utilizado los siguientes lenguajes:

C/C++, utilizados para crear todo el software de la infraestructura de comunicación (librerías y traductor entre protocolos). Se han elegido estos lenguajes debido a la eficiencia que posee el código que generan. JavaScript y HTML5, utilizados para crear la lógica necesaria para tener suscriptores externos multi-plataforma. Se han elegido estos lenguajes con el fin de que cualquier máquina con conexión a Internet, pueda acceder a la información que se publica a través de la infraestructura, utilizando cualquier navegador web.

3https://bitbucket.org

Capítulo 5 Arquitectura y desarrollo

OMO se ha visto en el capítulo anterior, la planificación del proyecto implica una serie C de etapas o fases, a través de las cuales se irá dotando a la infraestructura de funciona- lidad y se irán logrando los objetivos establecidos. Antes de dar una descripción completa de como se ha desarrollado el proyecto, es nece- sario tener una visión general de lo que pretende conseguirse. En la Figura 5.1 puede verse la arquitectura que sigue esta infraestructura. En la que se distinguen los siguientes elemen- tos:

Clientes MQTT-SN: son sensores cuyo objetivo es recopilar y publicar información de su entorno, a un broker MQTT, utilizando diferentes topics para clasificar la infor- mación. Pasarela MQTT-SN/MQTT: este dispositivo realiza la función más compleja de la infraestructura. Por un lado tiene que establecer y gestionar la red sensores. Y por otro, es el encargado de llevar las publicaciones de los clientes hasta el broker MQTT, realizando la traducción entre protocolos y actuando como servidor. Broker MQTT: cuyo objetivo es gestionar las publicaciones/suscripciones de los clien- tes, tanto de la red de sensores subyacente, como de redes externas. Suscriptores externos: se suscriben a determinados topics en los que publican los sensores y el broker se encarga de enviarles las publicaciones.

Como puede observarse, una vez implementada la infraestructura, los sensores podrán publicar información de su entorno a un broker MQTT, a través de la pasarela. Y los suscrip- tores externos podrán recibir esta información y actuar en consecuencia. El desarrollo del proyecto se organiza en 6 etapas, en cada una de las cuales se expone: el estado de desarrollo del proyecto hasta dicha etapa, qué se pretende conseguir con su realización y cómo va a realizarse el trabajo requerido. Las etapas de que consta el proyecto son:

1. Despliegue mínimo de la plataforma. 2. Instalación y configuración de Mosquitto.

61 62 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

Figura 5.1: Arquitectura y componentes de la infraestructura. Fuente: elaboración propia.

3. Librería MQTT. 4. Pasarela transparente. 5. Librería MQTT-SN y el software de traducción. 6. Suscriptores externos.

En lo que resta de capítulo se expone como se ha llevado a cabo cada una de ellas y que resultados se han obtenido. En las etapas de implementación se explicará como se ha llevado a cabo la metodología de desarrollo elegida.

5.1 Etapa 1: Despliegue mínimo de la plataforma Para poder desarrollar la infraestructura de comunicación pretendida y cumplir así con los diversos objetivos del proyecto, es necesario realizar un despliegue mínimo de la plata- forma sensora sobre la que se ejecutará el software que pretende implementarse. Es decir, para poder testear las diferentes funcionalidades del protocolo MQTT-SN, es necesario tener desplegada una red que tenga como mínimo una pasarela y un sensor. Para que esto se entienda mejor, véase un ejemplo. Si un determinado sensor está progra- mado para que publique información referente al nivel de polución de su entorno cada 20 minutos, cuando el sensor despierte y recopile la información a transmitir, este deberá ini- ciar el procedimiento de conexión MQTT-SN, mediante el cual podrá conectarse a un broker 5.1. ETAPA 1: DESPLIEGUE MÍNIMO DE LA PLATAFORMA 63

MQTT/MQTT-SN y publicar eventos en él para que este los distribuya entre los suscriptores. En este procedimiento de conexión y posterior publicación de eventos, es necesario que el sensor y la pasarela se intercambien mensajes.

El protocolo MQTT-SN va a implementarse para que se ejecute sobre las capas MAC y física que proporciona el estándar 802.15.4, luego es necesario establecer una red entre sensor y pasarela, que siga este estándar.

La plataforma sensora estaría formada por dispositivos de la empresa Libelium, en concre- to por sensores Waspmote Plug&Sense y pasarelas Meshlium. Sin embargo, para desplegar esta «red mínima» mencionada anteriormente, se usarán sensores del Evaluation Kit de Li- belium, en concreto una placa Waspmote Pro v1.2 con XBee S1, y una pasarela Meshlium configurada para actuar con el firmware Meshlium ZigBee AP (véase Figura 5.2), que per- mite a la pasarela recoger datos provenientes de una red de sensores Waspmote, establecida usando ZigBee/802.15.4, y enviarlos a Internet haciendo uso de la interfaz Ethernet (en este caso concreto, enviarlos a un broker MQTT). También permite que los desarrolladores se conecten directamente a Meshlium usando la interfaz Wi-Fi, para programar/configurar la pasarela y acceder a los datos de los sensores.

Figura 5.2: Escenario bajo el que se trabaja utilizando el firmware Meshlium ZigBee AP. Fuente: [Lib13a]. 64 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

En los siguientes apartados se muestra como configurar un dispositivo Waspmote Pro v1.2 con un módulo XBee S1 y una pasarela Meshlium, con el fin de que puedan realizar un intercambio de mensajes y poder así implementar un protocolo de comunicación entre ambos.

5.1.1 Establecimiento de una red 802.15.4 Para establecer una red 802.15.4 todos los módulos XBee participantes deben estar confi- gurados con los mismos parámetros de red. Básicamente hay tres parámetros que identifican de forma unívoca una red: PAN ID1, canal y modo de encriptado. Estos parámetros los de- termina la pasarela y deberán utilizarse en los dispositivos Waspmote para que la red pueda ser establecida. Tanto Meshlium como Waspmote ya tienen configurados unos parámetros por defecto para sus módulos XBee, pero para asegurarse el establecimiento de una red entre ellos, hay que acceder a la configuración de Meshlium y ver que parámetros de red tiene, después usarlos para configurar el módulo XBee de Waspmote.

Consultar los parámetros del módulo XBee-802.15.4 que hay dentro de Meshlium Para consultar los parámetros de red de Meshlium, debemos acceder al Manager System que trae instalado [Lib13b], a través de cualquier navegador web. Después de conectarse, basta con acceder a la pestaña Sensor Networks, apartado 802.15.4 y presionar sobre el botón Load MAC. Esta operación realiza una petición al módulo XBee 802.15.4 que hay dentro de Meshlium preguntándole por su dirección MAC, cuando termine, estarán visibles todos los parámetros de red de Meshlium. Estos pueden simplemente consultarse, o cambiarse. Después se deberá pulsar sobre el botón Check status para comprobar que los parámetros son válidos y por último, en Save para guardar esos valores. Véanse Figuras 5.3 y 5.4.

Cambiar los parámetros de configuración de Wasmote Antes de poder enviar paquetes a Meshlium hay que configurar Waspmote con los paráme- tros de red que se han consultado anteriormente. Para realizar esta acción se puede proceder de dos formas diferentes:

Utilizando el software XCTU, proporcionado por la empresa Digi International2. Mediante código específico para Waspmote proporcionado por Libelium.

XCTU es una solución bastante buena, ya que posee una interfaz gráfica que permite explorar los diferentes tipos de parámetros y de configuraciones, además de permitir la po- sibilidad de testear la conexión con un gateway XBee in situ, cambiar de firmware, etc. El problema de este software es que solo está disponible para sistemas operativos Microsoft

1Identificador de Red de Área Personal. 2http://www.digi.com/support/kbase/kbaseresultdetl?id=2125 5.1. ETAPA 1: DESPLIEGUE MÍNIMO DE LA PLATAFORMA 65

Figura 5.3: Acceso a configuración de parámetros de Meshlium.

Windows y el propósito de esta sección es que cualquier persona que la lea pueda realizar todos sus pasos sin problemas, sin importar el sistema operativo que utilice. Con lo cual, a continuación se explica como configurar los parámetros de red del módulo XBee de Wasp- mote, utilizando código específico para esta plataforma y proporcionado por Libelium para este fin.

Primero es necesario descargarse el IDE de Waspmote y la última versión de su API, con el fin de poder programar el dispositivo. Para ello debe seleccionarse la versión adecuada dentro del área para desarrolladores de la web de Libelium3. Para programar estos dispositivos hay que seguir una serie de instrucciones, así que es conveniente documentarse sobre ello consultando en la documentación oficial de Libelium, en concreto [Lib13d], o bien el Anexo C. Una vez obtenidos los conocimientos sobre como programar Waspmote, para configurar los parámetros de red debe usarse el ejemplo de código 802_01 - configure XBee basic pa- rameters (véase Listado 5.1) obtenido de la API de Waspmote, en el que deberán cambiarse los parámetros de red, por los consultados en Meshlium anteriormente.

1 #include

3 //PAN(Personal Area Network) Identifier

4 uint8_t PANID[2]={0x33,0x32};

5 // 16−byte Encryption Key

6 char∗ KEY="WaspmoteLinkKey!";

3http://www.libelium.com/development/waspmote/sdk applications/ 66 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

Figura 5.4: Chequeo de parámetros de Meshlium.

8 void setup ()

9 {

10 // openUSB port

11 USB.ON();

12 USB.println(F("802_01 example"));

14 // init XBee

15 xbee802.ON();

16 // wait fora second

17 delay(1000);

19 /////////////////////////////////////

20 // 1. set channel

21 /////////////////////////////////////

22 xbee802.setChannel(0x0C);

23 // check at commmand execution flag

24 if( xbee802.error_AT == 0 ) {

25 USB.println(F("Channel set OK"));

26 }

27 else {

28 USB.println(F("Error setting channel"));

29 }

31 ///////////////////////////////////// 5.1. ETAPA 1: DESPLIEGUE MÍNIMO DE LA PLATAFORMA 67

32 // 2. setPANID

33 /////////////////////////////////////

34 xbee802.setPAN(PANID);

35 // check theAT commmand execution flag

36 if( xbee802.error_AT == 0 ) {

37 USB.println(F("PANID set OK"));

38 }

39 else {

40 USB.println(F("Error setting PANID"));

41 }

43 /////////////////////////////////////

44 // 3. set encryption mode (1:enable; 0:disable)

45 /////////////////////////////////////

46 xbee802.setEncryptionMode(0);

47 // check theAT commmand execution flag

48 if( xbee802.error_AT == 0 ) {

49 USB.println(F("encryption set OK"));

50 }

51 else {

52 USB.println(F("Error setting security"));

53 }

55 /////////////////////////////////////

56 // 4. set encryption key

57 /////////////////////////////////////

58 xbee802.setLinkKey(KEY);

59 // check theAT commmand execution flag

60 if( xbee802.error_AT == 0 ) {

61 USB.println(F("encryption key set OK"));

62 }

63 else {

64 USB.println(F("Error setting encryption key"));

65 }

67 /////////////////////////////////////

68 // 5. write values to XBee module memory

69 /////////////////////////////////////

70 xbee802.writeValues();

71 // check theAT commmand execution flag

72 if( xbee802.error_AT == 0 ) {

73 USB.println(F("write values OK"));

74 }

75 else {

76 USB.println(F("Error writing values"));

77 } 68 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

79 USB.println(F("−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−"));

80 }

82 void loop ()

83 {

84 /////////////////////////////////////

85 // 1. get channel

86 /////////////////////////////////////

87 xbee802.getChannel();

88 USB.print(F("channel: "));

89 USB.printHex(xbee802.channel);

90 USB.println();

92 /////////////////////////////////////

93 // 2. getPANID

94 /////////////////////////////////////

95 xbee802.getPAN();

96 USB.print(F("panid: "));

97 USB.printHex(xbee802.PAN_ID[0]);

98 USB.printHex(xbee802.PAN_ID[1]);

99 USB.println();

101 /////////////////////////////////////

102 // 3. get encryption mode (1:enable; 0:disable)

103 /////////////////////////////////////

104 xbee802.getEncryptionMode();

105 USB.print(F("encryption mode: "));

106 USB.printHex(xbee802.encryptMode);

107 USB.println();

109 USB.println(F("−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−"));

111 delay(3000);

112 }

Listado 5.1: Código de Libelium ejemplo 802_01 - configure XBee basic parameters.

Es importante mencionar:

El módulo XBee debe ser configurado con los valores por defecto para los parámetros baud rate (BD=7) y AP (AP=2).

Para que la configuración de los parámetros sea persistente cuando se apague el dispo- sitivo, es necesario ejecutar la función writeValues(). De no ser así, cuando se corte la alimentación no se almacenarán estos valores en la memoria.

Tras cargar y ejecutar el código, este deberá proporcionar una salida similar a esta: 5.1. ETAPA 1: DESPLIEGUE MÍNIMO DE LA PLATAFORMA 69

B# 802_01 example Channel set OK PANID set OK encryption set OK encryption key set OK write values OK ------channel : 0C panid : 3332 encryption mode: 00 ------

Donde podrá verse que los parámetros han sido cambiados con éxito, lo que indicará que Waspmote y Meshlium ya están bien configurados para proceder al envío y recepción de paquetes entre ellos.

5.1.2 Intercambio de paquetes Desde Waspmote a Meshlium Una vez realizados los pasos anteriores, para enviar paquetes desde Waspmote a Meshlium tan solo hay que cargar en el dispositivo otro de los ejemplos de la API de Libelium, en este caso el código 802_02 - send packets (véase Listado 5.2).

1 #include

2 #include

4 //Pointer to an XBee packet structure

5 packetXBee ∗ packet ;

6 // DestinationMAC address

7 char∗ MAC_ADDRESS="0013A2004052414C";

9 void setup ()

10 {

11 // initUSB port

12 USB.ON();

13 USB.println(F("802_2 example"));

14 // init XBee

15 xbee802.ON();

16 }

18 void loop ()

19 {

20 ///////////////////////////////////////////

21 // 1. CreateASCII frame

22 ///////////////////////////////////////////

23 // create new frame

24 frame.createFrame(ASCII, "WASPMOTE_XBEE");

26 // add frame fields 70 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

27 frame.addSensor(SENSOR_STR, "XBee frame");

28 frame.addSensor(SENSOR_BAT, PWR.getBatteryLevel());

30 ///////////////////////////////////////////

31 // 2. Send packet

32 ///////////////////////////////////////////

33 // set parameters to packet:

34 packet=(packetXBee ∗) calloc (1,sizeof(packetXBee));

35 packet −>mode=UNICAST;// Choose transmission mode

37 // set destination XBee parameters to packet

38 xbee802.setDestinationParams( packet, MAC_ADDRESS, frame.buffer,

39 frame.length, MAC_TYPE);

41 // send XBee packet

42 xbee802.sendXBee(packet);

44 // checkTX flag

45 if( xbee802.error_TX == 0 ) {

46 USB.println(F("ok"));

47 }

48 else {

49 USB.println(F("error"));

50 }

52 // free variables

53 free(packet);

54 packet=NULL;

56 // wait for five seconds

57 delay(5000);

58 }

Listado 5.2: Código de Libelium ejemplo 802_02 - send packets.

Lo único que debe cambiarse es la dirección MAC destino de los paquetes a enviar, el resto de opciones no es necesario tratarlas en este ejemplo, aunque la API de Libelium es flexible y ofrece varias posibilidades a la hora de enviar paquetes 802.15.4 (como crear frames propios o directamente introducir en el paquete datos de aplicación).

Tras cargar y ejecutar este código, si todo ha ido bien el dispositivo mostrará por el puerto serie impresiones con la palabra «ok», mientras que si el mensaje no se ha enviado, mostrará la palabra «error».

A pesar de que el puerto serie nos muestre que el paquete se ha enviado, no necesariamente significa que la pasarela lo haya recibido. Para comprobar de forma segura si Meshlium ha 5.1. ETAPA 1: DESPLIEGUE MÍNIMO DE LA PLATAFORMA 71 recibido el paquete, se puede obrar de dos formas:

Accediendo a él mediante el Manager System, dirigiéndose a la pestaña Sensor Net- works, apartado Capturer, comprobando que el botón Sensor Parser Available esté en verde y viendo si existen datos en la base de datos (véase Figura 5.5). Accediendo a Mehslium a través de SSH [Lib13c], deteniendo el daemon sensorParser, que se encarga de almacenar los paquetes entrantes en la base de datos local:

sensorParser.sh stop

Y ejecutando el siguiente comando:

capturer S0 38400

Los datos recibidos desde Waspmote serán mostrados por consola.

meshlium:~# sensorParser.sh stop meshlium:~# capturer S0 38400 setting speed 38400 ttyS0 chosen ... Press Ctrl+c to close the program [Aqui ira apareciendo el contenido de los paquetes entrantes]

Figura 5.5: Captura de paquetes en Meshlium, acceso via Manager System.

Desde Meshlium a Waspmote Una vez que se haya comprobado que Meshlium recibe de forma correcta los paquete de Waspmote, hay que realizar la comunicación inversa, desde Meshlium a Waspmote. En este 72 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO caso es necesario utilizar dos programas, uno para que Waspmote se mantenga a la espera de recibir paquetes y otro para que Meshlium los envíe.

Recepción en Waspmote: De nuevo, el código necesario para que Waspmote se mantenga a la espera de recibir mensajes puede encontrarse en la API que nos proporciona Libelium para programar los dispositivos. En esta ocasión el código necesario es el contenido en el ejemplo 802_11b - complete example receive (véase Listado 5.3)

1 #include

2 #include

4 // pointer to the packet to send

5 packetXBee ∗ packet ;

6 unsigned long previous=0;

7 uint8_t destination[8];

9 void setup ()

10 {

11 // initUSB port

12 USB.ON();

13 USB.println(F("802_11b example"));

14 // init XBee

15 xbee802.ON();

16 }

18 void loop ()

19 {

20 // Wait message for 20 seconds

21 previous=millis();

22 while( ( millis()−previous) < 20000 )

23 {

24 // check available data inRX buffer

25 if( xbee802.available() > 0 ) {

26 // parse information

27 xbee802.treatData();

29 // checkRX flag after’treatData’

30 if( !xbee802.error_RX ) {

31 // check available packets

32 while( xbee802.pos>0 ) {

33 /∗ Available info in’xbee802.packet_finished’

34 structure ∗/

36 //Treat this data in your own

38 // 2.6. Free variable 5.1. ETAPA 1: DESPLIEGUE MÍNIMO DE LA PLATAFORMA 73

39 free(xbee802.packet_finished[xbee802.pos −1]);

40 xbee802.packet_finished[xbee802.pos −1]=NULL ;

42 // 2.7. Decrement packet counter

43 xbee802.pos−−;

44 }

45 }

46 }

47 // Condition to avoid an overflow(DONOTREMOVE)

48 if (millis() < previous) {

49 previous = millis();

50 }

51 }/ ∗ end while ∗/

53 delay(5000);

54 }

Listado 5.3: Código de Libelium ejemplo 802_11b - complete example receive.

Si se modifica la condición del bucle «while», se estará modificando la cantidad de tiempo que el dispositivo se mantiene a la espera de mensajes, antes de proceder a se- guir con la ejecución del resto del código. Cuando se recibe información en Waspmote, esta se almacena en determinadas estructuras de la API, en este caso se almacenan en la estructura «xbee802.packet_finished», cuyos campos más importantes son:

• xbee802.packet_finished->lenght: longitud total del paquete recibido. • xbee802.packet_finished->data: todos los datos recibidos accesibles byte a byte. • xbee802.packet_finished->macSH: contiene los bytes mas significativos de la MAC origen del paquete. • xbee802.packet_finished->macSL: contiene los bytes menos significativos de la MAC origen del paquete.

En lugar del comentario de la linea 35 del listado anterior, deberá escribirse el código especifico que se necesite para tratar la información recibida. Envío desde Meshlium: Para conseguir un intercambio completo entre ambos dispositivos, solo queda explicar como realizar el envío de paquetes desde Meshlium a Waspmote. Para conseguir este propósito hay que usar el archivo ZigBeeSend.c contenido en la ruta /var/ManagerSystem/plugin/b_SensorData/b0_capturer/bin/ de la pasarela. Para usar este archivo son necesarias dos acciones:

• Detener el daemon sensorParser.sh

sensorParse.sh stop 74 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

• Compilar el archivo fuente ZigBeeSend.c

gcc -o ZigBeeSend ZigBeeSend.c -lpthread

Hecho esto, hay tres formas para enviar paquetes usando el ejecutable generado:

• Usando la dirección MAC 802.15.4 destino.

./ZigBeeSend -mac 00XXXXxxXXXXXXxx <>

• Usando la dirección de red (MY).

./ZigBeeSend -net 1234 <>

• Realizando una transmisión broadcast.

./ZigBeeSend -b <>

Tras ejecutar el archivo con alguna de estas opciones, se mostrará la siguiente infor- mación por pantalla:

Preparing the module... Sending message... Restoring original values...

Esto es así debido a que el módulo XBee residente en Meshlium está configurado como Router AT y sus parámetros de red están accesibles vía comandos AT, en la primera fase de este envío, se prepara el módulo (usando estos comandos) para enviar con las opciones que hayamos elegido, después se envía el mensaje y por último, se restaura el estado del módulo XBee a sus valores originales. Para comprobar que la recepción en Waspmote ha sido satisfactoria, basta con im- primir información relevante de la estructura packet_finished por el puerto serie del dispositivo. O, por ejemplo, encender los LEDs cada vez que se reciba un mensaje. Esta parte queda a elección del desarrollador. La información de este apartado ha sido sacada de la Sección 15.8 de [Lib13c].

5.2 Etapa 2: Instalación y configuración de Mosquitto Mosquitto ha sido el broker elegido para cargar con el peso de la gestión y distribución de eventos de la infraestructura, entre los distintos suscriptores. Esta elección se debe en su mayor parte, a la eficiencia en cuanto al número de clientes conectados y los recursos consumidos que proporciona este broker. Esta etapa es necesaria antes de comenzar la im- plementación. Mosquitto es un servidor o broker de los protocolos MQTT y MQTT-SN, escrito en C y creado por la fundación Eclipse junto con IBM. La razón para estar escrito en C es, según sus 5.2. ETAPA 2: INSTALACIÓN Y CONFIGURACIÓN DE MOSQUITTO 75 creadores, permitir que el servidor se ejecute en máquinas que no tengan capacidad suficiente para ejecutar una Java Virtual Machine (JVM). Además, al hacerlo de esta forma, Mosquitto también puede ejecutarse en dispositivos empotrados. La implementación actual de este software tiene un ejecutable con un tamaño de unos 120kB y consume alrededor de 3MB de RAM con 1.000 clientes conectados. Además, hay informes que contienen test satisfactorios con 100.000 clientes conectados y un envío de mensajes moderado [mos14]. Datos que representan un magnífico rendimiento. Mosquitto implementa todas las características descritas en las especificaciones de los protocolos, junto con tres más:

Puede actuar como puente entre otros servidores MQTT, incluyendo otras instancias de Mosquitto. Esto permite construir redes de servidores MQTT, pudiendo dotar a estas redes de diferentes topologías (véase Sección 3.3.1), dependiendo de que requi- sitos nos pida el sistema que estemos construyendo. Esta característica proporciona escalabilidad a cualquier solución que utilice Mosquitto. Puede ser configurado para usar MQTT sobre SSL/TLS. Proporcionando de esta for- ma, conexiones seguras entre máquinas. Esto es importante debido a que MQTT no tiene seguridad por si mismo, es el broker debidamente configurado el que proporcio- nará servicios de seguridad como cifrado, autenticación y control de acceso. De un primer estudio de MQTT, puede verse que a partir de la versión 3.1 provee autenticación de cliente mediante usuario y contraseña, sin embargo, sin el broker bien configurado este mecanismo no proporciona seguridad alguna, ya que este debe tener indicado en su archivo de configuración, una ruta hacia un archivo donde se encuentre la relación usuario-contraseña. Además, si no se utiliza encriptado de red, los datos viajarán sin cifrar y serán vulnerables. Para hacer más seguro el intercambio de mensajes, Mosquitto permite el uso de certi- ficados SSL/TLS. Si la opción require_certificate está activada en el archivo de confi- guración, el cliente deberá proveer un certificado válido para conectarse a Mosquitto, si no está activada, la autenticación del cliente queda en manos del mecanismo de seguridad basado en usuario y contraseña que proporciona MQTT. Añade la posibilidad de restringir el acceso a determinados topics, a ciertos usuarios. Es decir, control de acceso.

5.2.1 Instalación La instalación de Mosquitto depende del sistema operativo sobre el que quiera utilizarse, en este caso se necesita instalar Mosquitto sobre una máquina con Debian GNU/Linux. Para ello, tan solo hay que instalar ciertos paquetes de los repositorios oficiales de la distribución, ya que Mosquitto viene incluido en ellos. Esto mismo ocurre en la mayoría de distribuciones 76 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

GNU/Linux, como Fedora, openSUSE o Ubuntu. Con el gestor de paquetes que se prefiera, basta con realizar una búsqueda del patrón «mosquitto» y ver los elementos que se listan, para poder utilizar el servidor con todas sus funcionalidades tan solo es necesario el paquete mosquitto, si además se quiere disponer de clientes MQTT, deben instalarse los paquetes mosquitto-clients y libmosquitto1. El resto de paquetes no son necesarios para este caso en concreto. Listado de paquetes con aptitude:

# aptitude search mosquitto p libmosquitto-dev - MQTT version 3.1 client library, development files i A libmosquitto1 - MQTT version 3.1 client library p libmosquittopp-dev - MQTT version 3.1 client C++ library, development files p libmosquittopp1 - MQTT version 3.1 client C++ library i mosquitto - MQTT version 3.1 compatible message broker i mosquitto-clients - Mosquitto command line MQTT clients p mosquitto-dbg - debugging symbols for mosquitto binaries p python-mosquitto - MQTT version 3.1 Python client library p python3-mosquitto - MQTT version 3.1 Python 3 client library

Una vez que se instale Mosquitto, este pasará a ejecutarse como un daemon del sistema, utilizando una configuración por defecto (p.e. esperando conexiones MQTT en el puerto 1883, sin persistencia y sin seguridad), para comprobar si Mosquitto funciona de forma co- rrecta pueden usarse los clientes que se han instalado previamente:

Primero se comprueba si Mosquitto se está ejecutando en el sistema:

# /etc/init.d/mosquitto status [ ok ] mosquitto is running.

En caso de que no estuviera en ejecución, Mosquitto puede iniciarse de dos formas: ejecutando el comando anterior pero con la orden start, o a través del comando «mos- quitto», del cual puede obtenerse información consultando la página de manual que se habrá instalado con los paquetes anteriores. Después en una terminal se ejecuta un suscriptor:

$ mosquitto_sub -t hello/world

Con esto se consigue que el suscriptor se mantenga a la espera de publicaciones en el topic «hello/world» (opción -t). Por último se ejecuta un publicador en otra terminal:

$ mosquitto_pub -t hello/world -m ‘‘Hello World!’’

Si todo ha ido bien, la publicación habrá llegado a Mosquitto y este la habrá distri- buido a los suscriptores del topic en cuestión, apareciendo el mensaje «Hello World!» 5.2. ETAPA 2: INSTALACIÓN Y CONFIGURACIÓN DE MOSQUITTO 77

(opción -m) en la terminal anterior (véase Figura 5.6).

Figura 5.6: Comprobación del correcto funcionamiento de Mosquitto.

5.2.2 Configuración El archivo de configuración de Mosquitto se denomina mosquitto.conf y puede residir en cualquier sitio, siempre que Mosquitto tenga permisos de lectura sobre él. Por defecto, Mos- quitto no necesita un archivo de configuración y usará valores predeterminados, en el caso de necesitar usar un archivo de configuración, se tendrá que ejecutar el comando «mosquitto» utilizando la opción -c seguida de la ruta hacia el archivo. Un archivo de ejemplo, con explicaciones detalladas de todas las opciones de configura- ción y de como utilizarlas, se encuentra disponible en: /etc/mosquitto/mosquitto.conf. Para este proyecto se ha usado Mosquitto indicándole un archivo de configuración concreto, la mayor parte de las opciones se han dejado por defecto, sólo se han modificado dos aspec- tos:

Persistencia: activando la opción persistence se consigue que Mosquitto almacene en un archivo, la información referente a conexiones, suscripciones, publicaciones, etc. Para que cuando Mosquitto se reinicie recupere de este archivo los datos y vuelva a su estado anterior. Esta información se almacena en el archivo cada cierto intervalo de tiempo, especificado en la opción autosave_interval (en segundos). La ruta y el nombre del archivo de persistencia se indican en las opciones persistencia_file [file name] y persistence_location [path]. Logs: con la opción log_dest file [path] se especifica la ruta y el archivo de log en el que queremos guardar esta información. Con la opción log_type [debug | error | war- ning | notice | information] se indica a Mosquitto que tipo de información debe mandar al archivo de log. Deberá añadirse una nueva linea por cada tipo de información.

Es importante mencionar, que Mosquitto abre el puerto 1883 para aceptar conexiones MQTT no seguras, y el 8883 para las conexiones de MQTT sobre SSL/TLS. Por defecto Mosquitto estará disponible en todas las interfaces de red, salvo que se le indique lo con- 78 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO trario mediante la opción bind_address y acepta conexiones desde cualquier dirección IP y puerto.

5.3 Etapa 3: Librería MQTT

Una vez realizadas las etapas anteriores, el proceso de desarrollo del proyecto se centra en la implementación de la librería MQTT, esta librería está destinada a ser ejecutada en la pasarela, como parte del software de traducción entre los protocolos MQTT-SN y MQTT.

Esta etapa se divide, a su vez, en tres fases o tareas, que son:

Estudio de la especificación del protocolo, fase importante en la que se estudia la sintaxis, semántica y temporización de MQTT.

Creación de un archivo de cabecera para la librería, que recopile y organice todos los datos útiles, sacados de la especificación, de cara a la implementación.

Implementación del protocolo, en la que se implementan los distintos tipos de men- sajes y características de MQTT, siguiendo la metodología de desarrollo TDD.

En los siguientes apartados se explican en profundidad estas fases.

5.3.1 Estudio de la especificación Los elementos clave de un protocolo son: sintaxis, semántica y temporización. La sintaxis se refiere a la estructura del formato de los datos, es decir, el orden en el cual se presentan. La semántica se refiere al significado de cada campo de bits. Y la temporización define cuando se deberían enviar los datos y con que rapidez deberían ser enviados.

Todos estos aspectos se comprenden tras realizar un estudio de la especificación de MQTT [Loc10]. Convirtiéndose esta fase, en una de las más importantes antes de comenzar con la implementación de los mensajes.

La especificación está dividida en 3 partes:

1. Formato de los mensajes, donde se detallan las distintas partes que puede tener un paquete MQTT.

2. Detalles específicos de cada mensaje, donde de trata en profundidad cada uno de ellos.

3. Flujo de mensajes, donde se explica como deben ser los intercambios de paquetes entre cliente y servidor.

En esta sección interesan las partes 1 y 3, la parte 2, al contener información específica sobre como debe formarse cada mensaje, deberá ser consultada durante la fase de implemen- tación de los mensajes. 5.3. ETAPA 3: LIBRERÍA MQTT 79

Formato de los mensajes Los mensajes MQTT pueden estar formados por 3 partes: cabecera fija, cabecera variable y payload. La cabecera fija es obligatoria en todos los mensajes, de hecho en ocasiones será lo único que contengan, mientras que otros necesitarán la cabecera variable y el payload. Todos los valores de los campos de los mensajes deben ir codificados siguiendo un orden big-endian, es decir, los bytes de mayor orden preceden a los de menor. Una palabra de 16-bit se representa con el Most Significant Byte (MSB), seguido del Least Significant Byte (LSB).

bit 7 6 5 4 3 2 1 0 byte 1 Message Type DUP flag QoS level RETAIN byte 2 Remaining Length Cuadro 5.1: Formato de la cabecera fija. Fuente: [Loc10].

El formato de la cabecera fija puede verse en el Cuadro 5.1. Message Type es un valor sin signo de 4-bit, el valor que deberá adoptar este campo depende del tipo de mensaje que se esté codificando (véase Cuadro 5.2). El resto de bits del byte 1 contienen los campos DUP,

QOS y RETAIN, que representan los flags del mensaje:

DUP: Este flag se activa cuando el cliente o el servidor intentan redistribuir un mensaje PUBLISH, PUBREL, SUBSCRIBE o UNSUBSCRIBE. Se aplica a los mensajes con

una QOS mayor que cero. Cuando el flag DUP está activo, la cabecera variable debe incluir un identificador de mensaje.

QoS: Este flag indica el nivel de garantía para la distribución de un mensaje PUBLISH. Ocupa dos bits y se codifica como puede verse en el Cuadro 5.3.

RETAIN: Este flag solo se usa en los mensajes PUBLISH. Cuando un cliente envía una publicación a un servidor, si este flag está activo, el servidor debe mantener el mensaje incluso después de que haya sido repartido a todos los suscriptores. Cuando se establezca una nueva suscripción a un topic, el último mensaje retenido en ese topic, deberá ser enviado al suscriptor con el flag RETAIN activo.

El campo remaining length indica el número de bytes que le quedan al mensaje, inclu- yendo los datos de la cabecera variable y del payload. Este campo comienza en el byte 2 de la cabecera fija y puede llegar a ocupar hasta cuatro bytes, dependiendo del tamaño restante del mensaje. La cabecera fija queda fuera de la cuenta de bytes que debe indicar remaining length, y aunque este campo ocupe más de dos bytes, siempre es parte de la cabecera fija. Como ya se ha dicho anteriormente, algunos mensajes MQTT contienen una cabecera variable, que se encuentra entre la cabecera fija y el payload. A continuación se describen los campos de esta cabecera, en el orden en que deben aparecer en los mensajes: 80 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

Mnemonico Numeración Reserved 0 CONNECT 1 CONNACK 2 PUBLISH 3 PUBACK 4 PUBREC 5 PUBREL 6 PUBCOMP 7 SUBSCRIBE 8 SUBACK 9 UNSUBSCRIBE 10 UNSUBACK 11 PINGREQ 12 PINGRESP 13 DISCONNECT 14 Reserved 15 Cuadro 5.2: Tipos de mensajes y su numeración. Fuente: [Loc10].

QoS bit 2 bit 1 Descripción 0 0 0 At most once 1 0 1 At least once 2 1 0 Exactly once 3 1 1 Reserved

Cuadro 5.3: Codificación de las distintas QOS. Fuente: [Loc10].

Nombre del protocolo: Debe estar presente en la cabecera variable de los mensajes CONNECT. Este campo es una cadena de caracteres codificada en formato UTF (Uni- code Transformation Format), que representa el nombre del protocolo, capitalizado así: «MQIsdp».

Versión del protocolo: También debe estar presente en la cabecera variable de los mensajes CONNECT. Es un carácter de 8-bit sin signo que representa el nivel de revi- sión del protocolo, en este caso será 3 (0x03).

Flags de conexión: Este campo representa en un byte los flags de conexión del men- saje CONNECT. El significado de cada bit de este campo puede verse en el Cuadro 5.4.

• Clean Session: Si no está activado (con valor 0), el servidor deberá almacenar

las suscripciones del cliente después de que este se desconecte. Válido para QOS 1 y 2. Si está activado (con valor 1), el servidor descarta cualquier información acerca del cliente cuando este se desconecta. 5.3. ETAPA 3: LIBRERÍA MQTT 81

• Will Flag: Este bit indica si se va a utilizar o no, la funcionalidad last will and testament de MQTT. Si está activado, los bits Will QoS y Will Retain también deberán estarlo, y los campos Will Topic y Will Message del payload deberán estar presentes. • Will QoS: En caso de estar activado el bit Will Flag, indica el nivel garantía para el futuro Will Message. Se codifica conforme al Cuadro 5.3. • Will Retain: Si el Will Flag está activado, indica si el Will Message debe perma- necer o no, en el servidor, una vez desconectado el cliente. • Usuario y contraseña: Indican si el cliente va a usar esta característica del pro- tocolo. En caso de estar activados, deberán incluirse los campos correspondientes en el payload del mensaje. No es posible que esté activado el bit de la contraseña, si no lo está el de usuario. «Tiempo de vida» o Keep Alive: Debe estar presente en la cabecera variable del men- saje CONNECT. Mide el máximo intervalo de tiempo (en segundos), entre los mensa- jes recibidos por el cliente. Se usa para que el servidor detecte si la conexión de red ha caido, sin tener que esperar el largo timeout que tiene TCP/IP. El cliente tiene la responsabilidad de enviar un mensaje cada periodo de «tiempo de vida». En ausencia de mensajes en este periodo, el cliente envía un PINGERQ, que será contestado por un PINGRESP desde el servidor. Si el cliente no recibe un PINGRESP antes de que acabe el «tiempo de vida», este cerrará la conexión TCP. Este campo es un valor de 16-bit y debe ir codificado en orden big-endian. Código de retorno para el CONNECT: Este campo debe estar presente en la cabe- cera variable del mensaje CONNACK. Utiliza un byte y puede contener 5 tipos de código de retorno (véase Cuadro 5.5). Topic Name: Debe estar presente en la cabecera variable de los mensajes PUBLISH. El Topic Name representa la clave que identifica el canal de información al que debe ser enviada la información publicada. Es una cadena codificada en UTF-8 y como máximo puede tener una longitud de 32.767 caracteres.

bit 7 6 5 4 3 2 1 0 User Name Password Will Will Will Clean Reserved Flag Flag Retain QoS Flag Session Cuadro 5.4: Flags de conexión del mensaje CONNECT. Fuente: [Loc10].

La última parte de los mensajes MQTT es el payload, que solo está presente en los mensa- jes: CONNECT, SUBSCRIBE, SUBACK y PUBLISH. En los mensajes de establecimiento de conexión, el payload contendrá una o varias cadenas de caracteres codificadas en UTF-8. 82 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

Numeración Hex Significado 0 0x00 Conexión aceptada 1 0x01 Conexión rechazada: versión de protocolo no aceptada 2 0x02 Conexión rechazada: identificador rechazado 3 0x03 Conexión rechazada: servidor no disponible 4 0x04 Conexión rechazada: usuario o contraseña incorrectos 5 0x05 Conexión rechazada: no autorizado 6-255 Reservado para uso futuro Cuadro 5.5: Códigos de retorno al mensaje CONNECT y su significado. Fuente: [Loc10].

Estas especificarán: un único identificador de cliente, el Will Topic y el Will Message y el usuario y la contraseña, en caso de estar activados sus respectivos flags de la cabecera varia- ble. El payload de los mensajes SUBSCRIBE contendrá una lista de Topic Names a los que el cliente se quiere suscribir, y la QOS que requiere para ellos. Todo codificado en UTF-8. El payload del mensaje SUBACK estará formado por una lista de QOSs garantizadas a los To- pic Names indicados en la correspondiente suscripción. Por último, el payload del mensaje PUBLISH contendrá los datos de aplicación que deben ser publicados. Una vez estudiadas las distintas partes que puede contener un mensaje MQTT, es impor- tante destacar dos aspectos más, que influyen en la sintaxis de un mensaje:

Identificadores de mensaje: Los mensajes PUBLISH, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE Y UNSUBACK, necesitan un identificador de mensaje, para poder realizar la asociación con sus correspondientes acuses de recibo. Este cam- po está representado por un entero sin signo de 16-bit, codificado en orden big-endian. MQTT y UTF-8:

UTF-8 es una forma eficiente de codificación de caracteres y cadenas Unicode, que optimiza la codificación de caracteres ASCII como apoyo a las codificaciones basadas en texto. En MQTT, todas las cadenas de caracteres van precedidas de dos bytes que indican su longitud. Es decir, antes de introducir en el mensaje una cadena determi- nada, se introduce su longitud (véase Cuadro 5.6). De esta forma, la longitud de una cadena no será su número de caracteres, sino el número de bytes que ocupa la cadena codificada (número de caracteres + 2).

bit 7 6 5 4 3 2 1 0 byte 1 Longitud de Cadena MSB byte 2 Longitud de Cadena LSB bytes 3... Caracteres codificados Cuadro 5.6: Codificación de una cadena de caracteres en MQTT. Fuente: [Loc10]. 5.3. ETAPA 3: LIBRERÍA MQTT 83

Flujo de datos

En MQTT la distribución de los mensajes está relacionada con la QOS usada. Como se mencionó en la Sección 3.3.2, existen tres niveles de QOS, cada una de las cuales lleva aso- ciado un determinado flujo de mensajes. A continuación se describen en detalle cada uno de estos niveles:

QoS 0, At most once delivery: La garantía de los mensajes distribuidos se deja al ser- vicio best effort de la red TCP/IP subyacente. No se espera respuesta ni están definidas políticas para el reenvío.

Cuando se publica información utilizando QOS nivel 0, no se tiene certeza de que esta haya llegado al servidor. Cuando el servidor la reciba, la distribuirá a los suscriptores. QoS 1, At least once delivery: En este nivel si se tienen garantías de los mensajes distribuidos. Cuando se publica información, el emisor queda a la espera del corres- pondiente acuse de recibo, que deberá contener un identificador de mensaje idéntico al del mensaje que contenía la publicación. Si este identificador fuese erróneo, o el acuse de recibo no se recibiese después del «tiempo de vida» establecido, el emisor de la publicación deberá reenviar el mensaje con el flag DUP activado.

Los mensajes SUBSCRIBE y UNSUBSCRIBE siempre utilizan QOS nivel 1. Cuando

el servidor reciba un PUBLISH con este nivel de QOS, deberá: (i) almacenar el men- saje, (ii) distribuir el mensaje a los suscriptores, (iii) borrar el mensaje y (iv) enviar un acuse de recibo (mensaje PUBACK en este caso) al emisor de la publicación. Si el servidor recibe publicaciones con el flag DUP activo, deberá redistribuir esta información y enviar otro acuse de recibo. QoS 2, Exactly once delivery: Este nivel añade una garantía más al nivel 1, asegu- rándose de que los suscriptores no reciban mensajes duplicados. Este es el nivel más alto de garantías que puede proporcionar MQTT y está pensado para usarlo cuando el suscriptor no deba recibir publicaciones duplicadas bajo ningún concepto. Dependiendo de cuando de distribuya la información a los suscriptores, un receptor de

un mensaje PUBLISH con QOS 2 puede actuar de dos formas:

1. Almacenando el mensaje y enviando un mensaje PUBREC, que contendrá el identificador de mensaje del PUBLISH recibido. Cuando el emisor reciba este mensaje, deberá enviar un PUBREL, con el mismo identificador. Entonces, el servidor distribuirá la publicación hacía los suscriptores, borrará el mensaje y enviará un PUBCOMP, con el mismo identificador usado en todo el proceso. 2. Almacenando el identificador de mensaje y publicando la información a los sus- criptores. Después enviará un PUBREC que contendrá el identificador almacena- do. Cuando lo reciba el emisor, enviará un PUBREL, con el mismo identificador, 84 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

Figura 5.7: Flujo de datos para una publicación con QOS nivel 2. Fuente: elaboración propia.

y cuando el servidor lo reciba, borrará el identificador de mensaje almacenado previamente y enviará un PUBCOMP en última instancia.

Si se detecta un fallo en el proceso, el flujo de datos se reanuda a partir del último acuse de recibo que haya llegado correcto. Tanto si es del mensaje PUBLISH, como del PUBREC. En cualquiera de los casos, el flujo de datos es conforme aparece en la Figura 5.7

Por otra parte, en MQTT el orden en que se envían/reciben los mensajes puede verse afectado por ciertos factores, como el número de flujos de publicaciones que permita un cliente a la vez, o si el cliente es multihilo o no. Para que una implementación proporcione garantías de cara a la conservación del orden de los mensajes, esta debe asegurarse de que cada flujo de distribución de mensajes, sea completado en el mismo orden en que comenzó.

Por ejemplo, en una serie de flujos de QOS 2, los mensajes PUBREL deben ser enviados en el mismo orden en que se enviaron los PUBLISH originales (véase Figura 5.8). El número de mensajes «en el aire» permitidos, también afecta al tipo de garantías que pueden ser proporcionadas: Si se permite un solo mensaje «en el aire», cada flujo de distribución se completa antes de que empiece el siguiente. Si se permite más de un mensaje «en el aire», el orden de los mensajes solo puede ser 5.3. ETAPA 3: LIBRERÍA MQTT 85

Figura 5.8: Ejemplo de flujo de datos ordenado. Fuente: elaboración propia.

garantizado por el nivel de QOS utilizado.

5.3.2 Creación del archivo de cabecera Cada uno de los mensajes del protocolo está formado por una serie de campos de bits, que dependiendo del tipo de mensaje y de las necesidades del usuario/cliente, tomarán diferentes valores. Hacer que las distintas partes de un mensaje tengan un valor u otro, es más sencillo si estos se encuentran identificados. Surge de esta forma, la necesidad de disponer de un lugar donde se almacenen estos identificadores, junto con su valor asociado. Ese lugar es el archivo de cabecera, en este caso mqtt.h. En esta fase se trata de realizar una primera versión de este archivo, que posteriormente será modificado ya que también debe contener los prototipos de las funciones que vaya a ser necesario implementar y cualquier otro aspecto común a todas las partes del protocolo. Las inclusiones del resto de archivos de cabecera que se necesiten durante el proceso de implementación de los mensajes, también debe de ir en este archivo. Los aspectos vistos hasta ahora y que pueden ser codificados en mqtt.h son:

Códigos de los mensajes. Flags de la cabecera fija. Flags de conexión. 86 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

Códigos de retorno a un mensaje de petición de conexión.

Nombre y versión del protocolo.

Por ejemplo, los códigos vistos en el Cuadro 5.2 deben ser codificados en hexadecimal y desplazados 4 bits hacía la izquierda, ya que el código de mensaje representa los 4 primeros bits del primer byte de la cabecera fija, p.e. el código número 1, en hexadecimal es 0x01, y desplazado 4 bits a la izquierda es 0x10.

Si todos estos elementos se codifican correctamente y se les asigna un identificador, la tarea de formar los mensajes será estrictamente eso, dar forma a los mensajes utilizando los diferentes campos de bits previamente codificados e identificados. Además, las distintas funciones que contendrá la implementación final, poseerán un código más legible.

El código de la primera versión de mqtt.h puede verse en el Listado 5.4.

1 #ifndef MQTT_H

2 #define MQTT_H

4 /∗ protocol version ∗/

5 #define MQTT_PROTOCOL_VERSION (0x03)

7 /∗ messages types ∗/

8 #define MQTT_TYPE_CONNECT (0x10)

9 #define MQTT_TYPE_CONNACK (0x20)

10 #define MQTT_TYPE_PUBLISH (0x30)

11 #define MQTT_TYPE_PUBACK (0x40)

12 #define MQTT_TYPE_PUBREC (0x50)

13 #define MQTT_TYPE_PUBREL (0x60)

14 #define MQTT_TYPE_PUBCOMP (0x70)

15 #define MQTT_TYPE_SUBSCRIBE (0x80)

16 #define MQTT_TYPE_SUBACK (0x90)

17 #define MQTT_TYPE_UNSUBSCRIBE (0xA0)

18 #define MQTT_TYPE_UNSUBACK (0xB0)

19 #define MQTT_TYPE_PINGREQ (0xC0)

20 #define MQTT_TYPE_PINGRESP (0xD0)

21 #define MQTT_TYPE_DISCONNECT (0xE0)

23 /∗ connect flags ∗/

24 #define MQTT_CONNECT_CLEAN_SESSION (0x02)

25 #define MQTT_CONNECT_WILL (0x04)

26 #define MQTT_CONNECT_WILL_QoS1 (0x08)

27 #define MQTT_CONNECT_WILL_QoS2 (0x10)

28 #define MQTT_CONNECT_WILL_RETAIN (0x20)

29 #define MQTT_CONNECT_PASSWORD (0x40)

30 #define MQTT_CONNECT_USERNAME (0x80)

32 /∗ fixed−header flags ∗/ 5.3. ETAPA 3: LIBRERÍA MQTT 87

33 #define MQTT_NO_FLAGS (0x00)

34 #define MQTT_FLAG_DUP (0x08)

35 #define MQTT_FLAG_QoS0 (0x00)

36 #define MQTT_FLAG_QoS1 (0x02)

37 #define MQTT_FLAG_QoS2 (0x04)

38 #define MQTT_FLAG_RETAIN (0x01)

40 /∗ connect message constants ∗/

41 #define MQTT_CONNECT_M’M’

42 #define MQTT_CONNECT_Q’Q’

43 #define MQTT_CONNECT_I’I’

44 #define MQTT_CONNECT_s ’s’

45 #define MQTT_CONNECT_d ’d’

46 #define MQTT_CONNECT_p ’p’

48 /∗ connack return codes ∗/

49 enum connack_return_code{

50 CONNECTION_ACCEPTED = (0x00),

51 UNPROTOCOL_VERSION = (0x01),

52 IDENTIFIER_REJECTED = (0x02),

53 SERVER_UNAVAILABLE = (0x03),

54 BAD_USER_OR_PASS= (0x04),

55 NOT_AUTHORIZED= (0x05)

56 };

58 #endif

Listado 5.4: Archivo de cabecera tras codificar el formato de lo mensajes de MQTT.

La mayor parte de estos datos, son usados para codificar las cabeceras de los mensajes, sobre todo la fija. Otros simplemente conviene identificarlos para dotar al código de más legibilidad, como los retornos de la petición de conexión.

5.3.3 Implementación del protocolo A partir del estudio de la parte 2 de la especificación de MQTT y utilizando el archivo de cabecera mqtt.h, a lo largo de esta fase se irán implementando todos los mensajes del protocolo (véase Cuadro 5.7), dotando poco a poco al código de todas las características de MQTT. Para lograr este cometido será necesario la creación de varios archivos nuevos, y la modificación de mqtt.h, para ir haciéndolo más completo. Cuando terminen los esfuerzos de implementación, se dispondrá de una librería que dará soporte completo a MQTT, para que posteriormente sea usada en la pasarela como parte del proceso de traducción entre MQTT- SN y MQTT. El código de la toda librería tiene la siguiente estructura: Archivo mqtt.h, que contiene toda la estructura del protocolo. Aquí están declaradas 88 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

todas las variables, constantes, estructuras y prototipos de funciones necesarias. Tam- bién todos los archivos de cabecera necesarios. Archivo mqtt.c, en el que se hará uso de todas las declaraciones del archivo mqtt.h para implementar las distintas funcionalidades del protocolo. Archivo mqtt-test.c, que contendrá los tests que se hayan ido creando durante la im- plementación del protocolo. Archivo Makefile, que se encarga de compilar los archivos anteriores y de generar el ejecutable para que puedan pasarse los test.

Mnemónico Descripción CONNECT El cliente realiza una petición de conexión al servidor CONNACK Acuse de recibo de la petición de conexión PUBLISH Publicación de un mensaje PUBACK Acuse de recibo de la publicación PUBREC Indicador de publicación recibida PUBREL Indicador de publicación realizada PUBCOMP Indicador de publicación completada SUBSCRIBE El cliente realiza una petición de suscripción SUBACK Acuse de recibo para la peticón de suscripción UNSUBSCRIBE El cliente realiza una petición de unsuscripción UNSUBACK Acuse de recibo para la petición de unsuscripción PINGREQ Petición de PING PINGRESP Respuesta de PING DISCONNECT El cliente indica que se desconecta Cuadro 5.7: Descripción de los mensajes MQTT. Fuente: [Loc10].

Todo el código generado en esta etapa ha sido creado utilizando la metodología de desa- rrollo TDD. Para ello se han identificado varios escenarios de actuación del protocolo, cada uno de los cuales se implementa en una iteración, de forma que con cada escenario se prueba todo el código generado hasta el momento, asegurando que las nuevas funcionalidades no dañan las ya existentes. Los escenarios identificados son:

Escenario CONNECT/DISCONNECT: en el que un cliente se conecta y desconecta de Mosquitto. Escenario SUBSCRIBE/UNSUBSCRIBE: en el que un cliente se suscribe a un topic, y después elimina esta suscripción. Escenario PUBLISH: en el que un cliente publica información a un topic, utilizando

cada uno de los niveles de QOS de MQTT. Escenario PING: en el que un cliente envía y recibe un ping, para probar las funciones de mantenimiento de la conexión. 5.3. ETAPA 3: LIBRERÍA MQTT 89

En general, el empleo práctico de TDD sigue los siguientes pasos [KBE06]:

1. Escoger la funcionalidad del sistema que se va a desarrollar. 2. Desarrollar un test que verifique la funcionalidad escogida. 3. Enlazar el código funcional al test para hacer que este compile. 4. Compilar y comprobar que al ejecutar el test falla. 5. Desarrollar el código funcional. 6. Compilar y ejecutar el test. 7. Refactorizar el código funcional. 8. Repetir los pasos 6 y 7 hasta que el código funcional se convierte en una implementa- ción limpia. 9. Repetir los pasos 1-8 hasta que todas las funcionalidades sean implementadas.

Estos pasos representan la secuencia detallada de como seguir el algoritmo de TDD, visto en la Sección 4.1.2. En este caso, las funcionalidades del sistema, son los distintos escenarios de actuación del protocolo y los test se desarrollan utilizando el framework CUnit. Con la consecución de las distintas iteraciones se consigue implementar todos los mensajes del protocolo, con una buena cobertura de pruebas. Esta implementación es un trabajo mecánico, una vez que se haya conseguido implementar el primer escenario, se dispondrá del código necesario para que el resto de implementaciones sean más ligeras, ya que se habrán creado diversas funciones comunes a todos los escenarios y se habrán solventado numerosos problemas que pueden surgir al formar los mensajes. Con el fin de mostrar este proceso de implementación, en este documento se detallarán los procedimientos realizados durante la primera iteración de la metodología, en la que se desa- rrolla el escenario CONNECT/DISCONNECT. Este escenario tiene especial importancia, ya que sin su implementación no pueden llevarse a cabo el resto de escenarios y al tener que formarse los primeros mensajes del protocolo, tiene que escribirse el código de funciones importantes que serán usadas durante el resto del proceso.

Escenario CONNECT/DISCONNECT

Siguiendo los pasos de TDD, para la implementación de este, y de todos los escenarios, se han realizado los siguientes procedimientos:

1. Escoger la funcionalidad del sistema que se va a desarrollar: La funcionalidad elegida es el escenario de actuación del protocolo en el que un clien- te se conecta al broker Mosquitto y después se desconecta. Este escenario engloba 90 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

todos los tipos posibles de conexión: clean-session, unclean session y con usuario y contraseña.

Antes de pasar al siguiente paso, es necesario un estudio de la parte 2 de la especifi- cación de MQTT, para detectar que mensajes deben implementarse y sus principales requisitos. Esto dará como resultado que los test sean de mayor calidad, ya que tendrán una mayor adecuación a las necesidades de un futuro cliente MQTT.

2. Desarrollar un test que verifique la funcionalidad escogida:

Todos los test que se realizan durante el proceso de implementación forman parte de una única suite, que consta de dos funciones: inicialización y destrucción. En la inicialización de la suite se crea todo lo necesario para que un cliente pueda conectarse al broker y proceder al intercambio de mensajes. En la destrucción de la suite se limpia lo creado anteriormente.

Esta suite puede verse en el Listado 5.5. La mayor parte del código no tiene sentido porque aún no están creadas las estructuras, variables, funciones, etc. que lo harían compilar. Esto llegará en pasos posteriores.

1 /∗ SUITE ∗/

2 int init_suite(void)

3 {

4 /∗ initilization of conexion structure

5 ∗ andTCP conexion with the broker ∗/

6 broker = (broker_handle_t ∗) malloc (sizeof(broker_handle_t));

7 if( (broker != NULL) &&

8 (mqtt_init(broker, "localhost", "1883")) >= 0 ) {

9 return 0;

10 }

11 else {

12 return −1;

13 }

14 }

16 int clean_suite(void)

17 {

18 /∗ closeTCP socket and free variables ∗/

19 close(broker −>sockfd );

20 free(broker);

21 broker=NULL;

22 return 0;

23 }

Listado 5.5: Suite para los test MQTT.

Para llevar a cabo la funcionalidad elegida, es necesaria la implementación de los men- 5.3. ETAPA 3: LIBRERÍA MQTT 91

sajes: CONNECT, DISCONNECT y CONNACK. Con lo cual se han realizado test que envían y reciben estos mensajes, para cada tipo de conexión. En el Listado 5.6 pue- den verse los distintos test para este escenario, los cuales han sido añadidos a la suite anterior, y esta suite al registro de test, para posteriormente ser ejecutados. Todo este código se omite en el listado ya que sigue las directrices que se detallan en el Anexo D.

1 /∗ Clean−session conexion Test ∗/

2 void testCONNECT_clean(void)

3 {

4 mqtt_set_client_id(broker, "mqtt_clean");

5 CU_ASSERT_TRUE( mqtt_send_connect(broker) );

6 CU_ASSERT_TRUE( mqtt_recv_connack(broker) );

7 CU_ASSERT_TRUE( mqtt_send_disconnect(broker) );

8 }

10 /∗ Unclean−session conexion Test ∗/

11 void testCONNECT_unClean(void)

12 {

13 mqtt_init(broker, "localhost", "1883");

14 mqtt_set_client_id(broker, "mqtt_unclean");

15 broker −>clean_session = 0;

16 CU_ASSERT_TRUE( mqtt_send_connect(broker) );

17 CU_ASSERT_TRUE( mqtt_recv_connack(broker) );

18 CU_ASSERT_TRUE( mqtt_send_disconnect(broker) );

19 }

21 /∗ Username and password conexion Test ∗/

22 void testCONNECT_userpass(void)

23 {

24 mqtt_init(broker, "localhost", "1883");

25 mqtt_set_client_id(broker, "mqtt_userpass");

26 mqtt_set_userpass(broker, "botto", "botto");

27 CU_ASSERT_TRUE( mqtt_send_connect(broker) );

28 CU_ASSERT_TRUE( mqtt_recv_connack(broker) );

29 CU_ASSERT_TRUE( mqtt_send_disconnect(broker) );

30 }

Listado 5.6: Test para el escenario CONNECT/DISCONNECT.

Como puede observarse, para cada conexión MQTT será necesario inicializar un ma- nejador de conexión, una conexión TCP con Mosquitto y después configurar el mane- jador según las opciones de conexión que se busquen.

3. Enlazar el código funcional al test, para hacer que este compile:

Para que los test anteriores compilen es necesario el siguiente código funcional: 92 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

• Manejador de conexión con el broker Mosquitto. Este elemento es una estructura que contiene todas las variables necesarias para el establecimiento de una co- nexión MQTT, forma parte del archivo mqtt.h. Esta estructura debe inicializarse antes de enviar el primer mensaje CONNECT de cada cliente, todos los mensajes necesitarán obtener información de ella (véase Listado 5.7).

1 /∗ broker handler ∗/

2 typedef struct{

3 int sockfd ;

4 char client_id[23];

5 char username[13];

6 char password[13];

7 uint8_t will_retain;

8 uint8_t will_qos;

9 uint8_t clean_session;

10 uint16_t keep_alive;

11 uint8_t debug_session;

12 }broker_handle_t;

Listado 5.7: Manejador de conexión con el broker.

• Funciones para modificar algunos de los campos del manejador de conexión. • Funciones de inicialización de las conexiones TCP y MQTT. • Funciones para enviar los mensajes CONNECT y DISCONNECT. • Función para recibir el mensaje CONNACK y comprobar el código de retorno. • Funciones para realizar el envío y recepción de datos por el socket TCP previa- mente creado. • Funciones para la comprobación del tipo de mensaje MQTT. Estas funciones deberán tener su prototipo en el archivo mqtt.h (véase Listado 5.8) y su implementación en mqtt.c (en un principio vacía). Todas reciben, al menos, el manejador de conexión como parámetro.

1 /∗ initialize the broker handler connection ∗/

2 int mqtt_init(broker_handle_t ∗ broker , const char∗ host ,

3 const char∗ port );

5 /∗ initialize tcp connection ∗/

6 int mqtt_create_socket(const char∗ host , const char∗ port );

8 /∗ send−receive mqtt packets throught tcp socket ∗/

9 int mqtt_send_packet(broker_handle_t ∗ broker ,

10 size_t send_buffer_size, uint8_t type_id);

11 int mqtt_recv_packet(broker_handle_t ∗ broker ,

12 size_t recv_buffer_size, uint8_t type_id); 5.3. ETAPA 3: LIBRERÍA MQTT 93

14 /∗ check and get message by type ∗/

15 int mqtt_check_msgtype(uint8_t type_id);

16 const char∗ mqtt_get_msgtype(uint8_t type_id);

18 /∗ set client−id, user and password fields functions ∗/

19 void mqtt_set_client_id(broker_handle_t ∗ broker , const char ∗ id );

20 void mqtt_set_userpass(broker_handle_t ∗ broker ,

21 const char ∗ username , const char ∗ pass );

23 /∗ send−receive functions ∗/

24 int mqtt_send_connect(broker_handle_t ∗ broker );

25 int mqtt_recv_connack(broker_handle_t ∗ broker );

26 int mqtt_send_disconnect(broker_handle_t ∗ broker );

Listado 5.8: Prototipos de las funciones necesarias para el escenario CONNECT/DISCON- NECT

Por otra parte, en el archivo de test mqtt-test.c deberá incluirse el archivo de cabecera mqtt.h, para tener disponibles este código funcional creado.

4. Compilar y comprobar que al ejecutar el test falla:

En este instante, una vez que se logre que el archivo de test compile con el código funcional, los test fallarán. Ya que no hay implementada ninguna funcionalidad de las funciones anteriores.

5. Desarrollar el código funcional:

Con el fin de lograr que se pasen todos los test, en este paso se desarrolla el código de cada una de las funciones anteriores.

• Creación de la conexión TCP (mqtt_create_socket): Esta función recibe como parámetros el host y el puerto donde reside el broker Mosquitto, y abre una conexión TCP con él. Devuelve el descriptor de socket que se haya asignado a la conexión TCP. El código de esta función se ha obtenido del Manual de Linux para Programado- res, en concreto de la entrada getaddrinfo. • Inicialización de la conexión MQTT (mqtt_init): Esta función inicializa todos los campos del manejador de conexión con el broker o broker handler. Le llega por parámetro la dirección de memoria del manejador, el host y el puerto requeridos para la conexión TCP. Para obtener el descriptor del socket con Mosquitto, se utiliza la función anterior. El resto de variables se inicializan con valores por defecto, determinados por las buenas prácticas de MQTT, en su especificación. Los valores que no siempre es necesario usarlos, se 94 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

inicializan a cero, quedando en manos del cliente su modificación (véase Listado 5.9).

1 int mqtt_init(broker_handle_t ∗ broker , const char ∗ host ,

2 const char ∗ port ) {

3 mqtt_id ++;

4 broker −>sockfd = mqtt_create_socket(host,port);

5 broker −>will_retain = 0;

6 broker −>will_qos = 0;

7 broker −>clean_session = 1;

8 broker −>keep_alive = 60;

9 broker −>debug_session = 0;

11 memset(broker −>username, 0, sizeof( broker −>username));

12 memset(broker −>password, 0, sizeof( broker −>password));

13 memset(broker −>client_id, 0, sizeof( broker −>client_id));

14 sprintf(broker −>client_id, "mqtt:%d", mqtt_id);

16 return broker −>sockfd ;

17 }

Listado 5.9: Función de inicialización del manejador de conexión

Puede observarse como, en primera instancia, se incrementa la variable mqtt_id y que posteriormente se usa para formar el identificador de cliente. Esta variable se ha añadido como global a todo el código y representa un identificador de cliente MQTT, para que cada cliente conectado disponga por defecto, de una identidad única de cara al broker. • Modificación de las variables del manejador: Estas funciones simplemente modifican los valores de las variables del maneja- dor. Deberán ser ejecutadas después de crear la conexión TCP y antes de enviar el mensaje de petición de conexión MQTT. • Funciones de envío/recepción de datos por el socket TCP (mqtt_send_packet, mqtt_recv_packet): Estas funciones sirven para enviar/recibir datos por el socket que indique el ma- nejador de conexión, de esta forma se desacopla el envío y la recepción de datos, de las funciones que implementan los mensajes MQTT. Una vez enviados/reci- bidos datos, se realizan comprobaciones (tanto en el socket, como en el tipo de mensaje MQTT), generándose un mensaje de alerta en caso de detectar error. Para realizar sus cálculos, estas funciones se ayudan de mqtt_check_msgtype() (comprueba si el código de mensaje que le llega por parámetro es igual al del mensaje que se está comprobando) y de mqtt_get_msgtype() (devuelve una cade- na de caracteres que indica el nombre del mensaje correspondiente al código que 5.3. ETAPA 3: LIBRERÍA MQTT 95

le llega por parámetro). • Función para el envío del mensaje CONNECT (mqtt_send_connect): Esta función es una de las más importantes de todo el código de la librería. Tras el establecimiento de una conexión TCP con el broker, el cliente debe crear una sesión MQTT usando un mensaje de petición de conexión MQTT al broker. Si el mensaje está bien formado y los parámetros de conexión son válidos, el broker responderá a esta petición con un acuse de recibo (mensaje CONNACK en este caso), si no se indica error, la conexión quedará establecida. Para obtener toda la información necesaria sobre como debe formarse este men- saje, es necesario consultar la especificación de MQTT, parte 2. Aquí puede verse que el mensaje CONNECT está formado por tres partes (cabecera fija, cabecera variable y payload), la estructura de cada parte ya se mencionó en la Sección 5.3.1. Los flags de mensaje de la cabecera fija no se utilizan en este caso, la cabecera variable contiene: nombre del protocolo, versión del protocolo, flags de conexión y periodo de «tiempo de vida» o Keep Alive Timer. Un total de 12 bytes. El payload contiene obligatoriamente el identificador de cliente, y de forma opcional el resto de campos (Will Topic, Username, etc.), que estarán presentes o no, en función de los flags que se activen. • Función para la recepción del mensaje CONNACK (mqtt_recv_connack): Este mensaje lo envía el broker para indicar el estado en que se encuentra la petición de conexión del cliente (aceptada o rechazada). En caso de ser rechazada, se indica el problema mediante un código (véase Cuadro 5.5). Esta función (al igual que todas las funciones de recepción de mensajes MQTT) debe llamar en primera instancia a la función de recepción desde el socket TCP, que almacenará los datos recibidos en el array mqtt_recv_buffer y comprobará ciertos errores. Si el mensaje es correcto solo queda comprobar el código de retorno para ver si se ha establecido o no, y porque motivo. La primera versión del código de esta función puede verse en el Listado 5.10.

1 /∗ function to handler the connack message ∗/

2 int mqtt_recv_connack(broker_handle_t ∗ broker ) {

3 int ret ;

4 /∗ receive from the socket ∗/

5 ret = mqtt_recv_packet(broker, CONNACK, MQTT_TYPE_CONNACK);

6 if( ret > 0) {

7 /∗ if connection accepted ∗/

8 if(mqtt_recv_buffer[3] == CONNECTION_ACCEPTED) {

9 if( broker −>debug_session)

10 printf("Conexion accepted\n");

11 return SUCCESS; 96 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

12 }

13 /∗ if not, check the return code and display the error ∗/

14 else {

15 switch(mqtt_recv_buffer[3]) {

16 case UNPROTOCOL_VERSION:

17 fprintf(stderr,"Unnaceptable protocol version\n");

18 break;

19 case IDENTIFIER_REJECTED:

20 fprintf(stderr,"Identifier rejected\n");

21 break;

22 case SERVER_UNAVAILABLE:

23 fprintf(stderr,"Server unavailable\n");

24 break;

25 case BAD_USER_OR_PASS:

26 fprintf(stderr,"Bad user name or password\n");

27 break;

28 case NOT_AUTHORIZED:

29 fprintf(stderr,"Not authorized\n");

30 break;

31 }

32 return −1;

33 }

34 }

35 else return −1;

36 }

Listado 5.10: Implementación del mensaje CONNACK.

Como puede observarse, para consultar el código de retorno, debe examinarse el contenido del cuarto byte del mensaje CONNACK que envía el broker. Esta información se obtiene de la parte 2 de la especificación de MQTT. • Función de envío del mensaje DISCONNECT (mqtt_send_disconnect): Esta función es sencilla de implementar, el mensaje DISCONNECT tan solo ocu- pa 2 bytes (la cabecera fija). El primer byte contiene el tipo de mensaje y los flags inactivos, el segundo byte es remaining length y contiene un cero, ya que el men- saje no tiene ningún campo más. Este mensaje no necesita acuse de recibo por parte del servidor. El código elaborado para esta función puede verse en el Listado 5.11.

1 /∗ function to senda disconnect message ∗/

2 int mqtt_send_disconnect(broker_handle_t ∗ broker ) {

3 uint8_t packet[] = {MQTT_TYPE_DISCONNECT, (0x00)};

4 memset(mqtt_send_buffer, 0, MAX_PACKET_LENGTH);

5 memcpy(mqtt_send_buffer, packet, sizeof( packet ));

7 return mqtt_send_packet(broker, sizeof( packet ), 5.3. ETAPA 3: LIBRERÍA MQTT 97

8 MQTT_TYPE_DISCONNECT);

9 }

Listado 5.11: Implementación del mensaje DISCONNECT.

Como puede observarse se utiliza el array mqtt_send_buffer, para almacenar los datos que forman el mensaje. Este buffer posteriormente es utilizado por la fun- ción mqtt_send_packet() para enviar el paquete MQTT por el socket. Tiene un tamaño máximo de 255 bytes.

6. Compilar y ejecutar el test: Cuando se tenga todo el código funcional implementado, deben ejecutarse los tests, para comprobar que, efectivamente, pasan.

$ make test ./exec/mqtt-test

CUnit - A unit testing framework for C - Version 2.1-2 http://cunit.sourceforge.net/

Suite: General Suite Test: connect & disconnect()_clean ...passed Test: connect & disconnect()_unclean ...passed Test: connect & disconnect()_userpass ...passed

Run Summary: Type Total Ran Passed Failed Inactive suites 1 1 n/a 0 0 tests 3 3 3 0 0 asserts 9 9 9 0 n/a

Elapsed time = 0.001 seconds

7. Refactorizar el código funcional: Una vez que se tiene el código funcional para un determinado escenario, en esta fase debe refactorizarse, es decir, revisarse en busca de mejoras. Como eliminar redundan- cias, dotarlo de mayor legibilidad, elegir buenos nombres para las variables, etc. 8. Repetir los pasos 6 y 7 hasta obtener una implementación limpia: Después de cada fase de refactorización, deben ejecutarse de nuevo las pruebas, para asegurarse de que los cambios no modifican el comportamiento del código. Cuando se disponga de una implementación limpia, habrá terminado esta fase y la primera iteración del proceso. La función que ha sufrido cambios más significativos es la encargada de enviar el men- saje CONNECT. Como ya se ha mencionado, es una de las funciones más importantes de la librería, y es fundamental que esté implementada de forma correcta. La última versión de su código, debidamente comentada para mayor claridad, puede verse en el Listado 5.12. 98 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

1 /∗ FUNCTIONTOSENDCONNECTMESSAGE ∗/

3 int mqtt_send_connect(broker_handle_t ∗ broker )

4 {

5 /∗ VARIABLES ∗/

6 //lengths

7 uint16_t clientidlen = strlen(broker −>client_id);

8 uint16_t usernamelen = strlen(broker −>username);

9 uint16_t passwordlen = strlen(broker −>password);

10 uint16_t payloadlen = clientidlen+2;

11 //others

12 uint8_t flags = (0x00), offset = 0;

13 uint8_t ∗ payload, var_header[12];

14 uint16_t packetlen;

16 //set clean −session flag

17 if( broker −>clean_session) flags |= MQTT_CONNECT_CLEAN_SESSION;

19 /∗ GENERATEPAYLOADANDUPDATEVARIABLE −HEADERFLAGS ∗/

20 //allocate memory and set to0

21 payload = (uint8_t ∗)malloc(payloadlen ∗sizeof(uint8_t));

22 memset(payload,0, payloadlen);

24 //set client id

25 payload[offset++] = clientidlen >> 8;//string lengthMSB

26 payload[offset++] = clientidlen & (0xFF);//string lengthLSB

27 memcpy(payload+offset, broker −>client_id, clientidlen);//data

29 //put username in payload if it’s neccesary

30 if(usernamelen)

31 {

32 payloadlen += usernamelen+2;//update payload length

33 offset += clientidlen;//update offset inside payload

34 flags |= MQTT_CONNECT_USERNAME;//update flags

35 //reallocate mem and add username to payload

36 payload = (uint8_t ∗)realloc(payload, payloadlen);

37 memset(payload+offset,0,payloadlen−offset );

38 payload[offset++] = usernamelen >> 8;

39 payload[offset++] = usernamelen & (0xFF);

40 memcpy(payload+offset, broker −>username, usernamelen);

41 }

43 //put password in payload if it’s neccesary

44 if(passwordlen)

45 {

46 payloadlen += passwordlen+2;//update payload length 5.3. ETAPA 3: LIBRERÍA MQTT 99

47 offset += usernamelen;//update offset inside payload

48 flags |= MQTT_CONNECT_PASSWORD;//update flags

49 //reallocate mem and add password to payload

50 payload = (uint8_t ∗)realloc(payload, payloadlen);

51 memset(payload+offset,0,payloadlen−offset );

52 payload[offset++] = passwordlen >> 8;

53 payload[offset++] = passwordlen & (0xFF);

54 memcpy(payload+offset, broker −>password, passwordlen);

55 }

57 /∗ VARIABLE−HEADER ∗/

58 //protocol name

59 var_header[0] = (0x00);//string lengthMSB

60 var_header[1] = (0x06);//string lengthLSB

61 var_header[2] = MQTT_CONNECT_M;//data

62 var_header[3] = MQTT_CONNECT_Q;

63 var_header[4] = MQTT_CONNECT_I;

64 var_header[5] = MQTT_CONNECT_s;

65 var_header[6] = MQTT_CONNECT_d;

66 var_header[7] = MQTT_CONNECT_p;

67 //protocol version

68 var_header[8] = MQTT_PROTOCOL_VERSION;

69 //flags

70 var_header[9] = flags;

71 //keep −alive

72 var_header[10] = broker −>keep_alive >> 8;

73 var_header[11] = broker −>keep_alive & (0xFF);

75 /∗ FIXED−HEADER ∗/

76 //now we know remaining length

77 uint8_t fix_header[] = {

78 MQTT_TYPE_CONNECT|MQTT_NO_FLAGS,

79 ( uint8_t )(sizeof(var_header)+payloadlen)

80 };

82 /∗ PACKET ∗/

83 //set packet length

84 packetlen = sizeof(fix_header)+sizeof(var_header)+payloadlen;

85 //reset send buffer

86 memset(mqtt_send_buffer, 0, MAX_PACKET_LENGTH);

87 //add fix −header, var −header and payload

88 memcpy(mqtt_send_buffer, fix_header, sizeof(fix_header));

89 memcpy(mqtt_send_buffer+sizeof(fix_header), var_header,

90 sizeof(var_header));

91 memcpy(mqtt_send_buffer+sizeof(fix_header)+sizeof(var_header),

92 payload, payloadlen); 100 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

94 //free memory

95 free(payload);

96 payload = NULL;

98 // send packet and return

99 return mqtt_send_packet(broker, (size_t)packetlen,

100 MQTT_TYPE_CONNECT);

101 }

Listado 5.12: Implementación del mensaje CONNECT.

El último paso de las directrices que marca TDD es el de repetir los pasos 1-8 hasta que todas las funcionalidades sean implementadas. En este caso, se deberá elegir un escenario distinto en cada iteración, y su implementación se irá realizando de igual manera a como se ha descrito en este escenario, pero con mucho menos esfuerzo, ya que tras esta primera iteración se han escrito partes de la librería que son usadas por todos los mensajes, y que como se ha podido comprobar, funcionan correctamente. Tras realizar todas las iteraciones, quedan implementados todos los mensajes de MQTT, con una alta cobertura de pruebas. Una vez finalizado la última iteración, la salida de test que se obtiene es la siguiente:

$ make test ./exec/mqtt-test

CUnit - A unit testing framework for C - Version 2.1-2 http://cunit.sourceforge.net/

Suite: General Suite Test: connect & disconnect()_clean ...passed Test: connect & disconnect()_unclean ...passed Test: connect & disconnect()_userpass ...passed Test: subscribe & unsubscribe()_topicQoS0 ...passed Test: subscribe & unsubscribe()_topicQoS1 ...passed Test: publish()_QoS0 ...passed Test: publish()_QoS1 ...passed Test: publish()_QoS2 ...passed Test: publish()_dup ...passed Test: publish()_retain ...passed Test: ping() ...passed

Run Summary: Type Total Ran Passed Failed Inactive suites 1 1 n/a 0 0 tests 11 11 11 0 0 asserts 52 52 52 0 n/a

Elapsed time = 0.002 seconds

Donde puede verse como se han pasado con éxito todos los test unitarios que se han ido creando en las distintas iteraciones. A partir de este momento, se obtiene uno de los primeros resultados de este proyecto, una librería para el protocolo MQTT. 5.4. ETAPA 4: PASARELA TRANSPARENTE 101

5.4 Etapa 4: Pasarela transparente Gracias a los resultados obtenidos en etapas anteriores, ya se dispone de un despliegue mí- nimo de la plataforma sensora y de una librería MQTT, destinada a ejecutarse en Meshlium como parte del proceso de traducción entre protocolos. El siguiente paso es preparar la pa- sarela para que sea capaz de actuar como pasarela transparente entre los clientes MQTT-SN y el broker MQTT (véase Figura 3.9). Debe elaborarse un programa que haga que la pasarela se mantenga a la espera tanto de paquetes MQTT-SN como MQTT, y cuando los reciba, realice la traducción que corresponda en cada caso y los envíe a uno de los extremos de la comunicación (cliente o broker). Este software es una pieza clave dentro de la infraestructura que se está desarrollando, ya que sin él no es posible que la información recopilada por los sensores llegue hasta Mosqui- tto, y por ende, a los suscriptores externos. Debe poseer las siguientes características:

Capacidad para: 1. Recibir frames 802.15.4. 2. «Parsear» estos frames para obtener el paquete MQTT-SN que contienen, y el resto de información útil que envíen los sensores. Capacidad para que un cliente MQTT-SN pueda realizar las siguientes acciones: • Conectarse y desconectarse a un broker MQTT. • Publicar información a un topic determinado de un broker MQTT, utilizando

cualquiera de las QOS que ofrece tanto MQTT-SN como MQTT. • Realizar el procedimiento de registro de un Topic Name. • Mantener la conexión con el broker utilizando pings. Capacidad para que un broker pueda enviar mensajes a los clientes conectados. Capacidad para mantener varios de estos clientes conectados al mismo tiempo. Proporcionar seguridad a la información de cada cliente, para que esta no se mezcle con la del resto. Controlar casos especiales, como los reintentos de conexión.

La pasarela transparente establece una conexión con Mosquitto por cada cliente MQTT- SN conectado, con el fin de establecer un flujo de datos entre ambas partes. Para mantener este flujo, debe atender las peticiones que le lleguen desde estas conexiones, es decir, tiene que actuar como un servidor que es capaz de mantener un conjunto de descriptores de archivo (cada uno maneja una conexión) y ejecutar un conjunto de acciones según se activen unos u otros. Entre estos descriptores pueden diferenciarse dos tipos4: el que se usa para manejar

4En los sistemas Unix, los descriptores de archivo se pueden referir a archivos, directorios, dispositivos de bloques o dispositivos de caracteres (también llamados “archivos especiales”), sockets, FIFOs (también llamados “tuberías con nombre”) o tuberías sin nombre. 102 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO la interfaz 802.15.4 y los usados para manejar los distintos sockets abiertos (descriptores de socket) con Mosquitto. Si se activa el descriptor de 802.15.4: Significa que existen datos disponibles en él, procedentes de algún sensor. La pasarela deberá recibir estos datos y procesarlos.

Tras este procesamiento se dispondrá de la dirección MAC origen de los datos (el sensor que ha emitido el mensaje) y del paquete MQTT-SN que ha sido enviado. Una vez hecho esto, la pasarela deberá actuar en consecuencia, dependiendo del tipo de mensaje recibido. Es decir, como servidor o como traductor, además de las acciones asociadas que conlleve cada tipo de mensaje. Por último, volverá a mantenerse a la espera de que se active algún descriptor. Si por el contrario, se activa un descriptor de socket: Significa que Mosquitto ha enviado un mensaje MQTT a la pasarela. Estos datos deben recibirse y procesarse. En este caso la pasarela siempre debe actuar como traductor. Es decir, detectar que tipo de mensaje MQTT se ha recibido, traducirlo y enviarlo al sensor correspondiente. Todo este proceso es complejo y requiere bastante esfuerzo de implementación. Por ello, en lo que resta de sección, primero se exponen los diferentes archivos que forman esta pasa- rela software, describiendo cada una de sus partes. Después se muestran distintos pseudocó- digos del archivo principal, con el objetivo de esclarecer el funcionamiento del programa y se explica en detalle el funcionamiento de este código.

5.4.1 Estructura del código El código de la pasarela tiene la siguiente estructura:

Librería MQTT: • mqtt.h • mqtt.c Librería utils: • utils.h • utils.c Librería mqttsnServerForwarder: • mqttsnSF.cpp • mqttsnSF.h Archivo principal tGatewayServer.cpp 5.4. ETAPA 4: PASARELA TRANSPARENTE 103

La librería MQTT ya es una parte del software completamente operativa y funcional. Se ha desarrollado durante las etapas anteriores y proporciona a la pasarela toda la funcionalidad necesaria para que esta establezca sesiones MQTT con Mosquitto. La librería mqttsnServerForwarder realiza dos funciones. Por un lado maneja todo el proceso relativo a la traducción entre MQTT-SN y MQTT, y por otro, realiza funciones de servidor MQTT-SN cuando los clientes conectados lo requieren. Para realizar la traducción entre protocolos, se utiliza una librería reducida de MQTT-SN, contenida en el archivo mqttsnSF.h, este archivo de cabecera, al igual que mqtt.h, ofrece identificadores de los distintos valores que pueden tomar los campos de bits, que se utilizan para formar los mensajes MQTT-SN (códigos de los mensajes, flags, código de retorno, etc.), todo ello sacado de la librería de MQTT-SN que también se ha desarrollado en este proyecto y que será explicada en secciones posteriores. A partir de la aplicación de operaciones a nivel de bit, utilizando la información de la librería y los mensajes MQTT-SN entrantes, se obtiene la información necesaria para formar un mensaje MQTT, haciendo uso la librería MQTT desarrollada. La traducción propiamente dicha, se realiza en dos funciones de esta librería:

Función mqttsn2mqtt(): Esta función se encarga de traducir un mensaje MQTT-SN a MQTT. Su estructura es sencilla, dispone de un switch que ejecuta un conjunto de sentencias u otro, en función del tipo de mensaje (CONNECT, PUBLISH, etc). En el Pseudocódigo 5.1 puede verse un esquema orientativo de esta función: Función mqtt2mqttsn(): Esta función realiza la traducción inversa a la función anterior, de MQTT a MQTT-SN. Su estructura es la misma, un switch que ejecutará unas sentencias u otras, en función del tipo de mensaje que se esté procesando. En este caso, los mensajes serán acuses de recibo que el broker envía a la pasarela, como respuesta a los mensajes previos. Con lo cual, deberán ser traducidos y enviados a los clientes MQTT-SN. Completando, de esta forma, el proceso de traducción para cada escenario del protocolo. En el Pseudocódigo 5.2 puede verse un esquema orientativo de esta función:

El código de ambas funciones se completará durante la etapa de implementación del pro- tocolo MQTT-SN, ya que durante esta etapa se adquieren unos conocimientos sólidos del protocolo y es el mejor momento para realizar la traducción. Por otra parte, hay ciertos mensajes MQTT-SN que no deben ser traducidos y enviados a Mosquitto, sino que requieren la ejecución de acciones concretas en la pasarela y que esta les envíe una respuesta. Es decir, necesitan que la pasarela actúe como servidor. En este caso, cuando se detecte uno de estos mensajes, deberá ejecutarse un manejador determinado, que 104 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

Pseudocódigo 5.1 Pseudocódigo de la función mqttsn2mqtt(). function MQTTSN2MQTT(mqtt-sn message) Switch Message type Case CONNECT –Code to translate message res ← MQTT_SEND_CONNECT(broker) EndCase Case DISCONNECT –Code to translate message res ← MQTT_SEND_DISCONNECT(broker) CLOSE(socket) EndCase Case PUBLISH –Code to translate message res ← MQTT_SEND_PUBLISH(broker, topicName, msg, qos, dup, retain) EndCase Case PUBREL –Code to translate message res ← MQTT_SEND_PUBREL(broker) EndCase Case PINGREQ –Code to translate message res ← MQTT_SEND_PING(broker) EndCase Default wrong message type EndSwitch return res end function procese la petición y actúe según marque la especificación del protocolo. Puede verse un esquema de este tipo de escenario en el Pseudocódigo 5.3.

El resto de funciones de esta librería, son utilidades concretas para alguno de los mensajes. De ser importantes, serán explicadas durante el proceso de implementación de MQTT-SN y posterior traducción.

Por su parte, la librería utils contiene todo el código necesario para operar con el módulo XBee de la pasarela. Como se verá en la siguiente etapa, cuando un sensor quiere enviar un mensaje MQTT-SN, lo encapsula en un paquete 802.15.4 junto con su dirección MAC y después lo manda por la red. Cuando este paquete llega a la pasarela, se activa el corres- pondiente descriptor de archivo y el servidor que está en ejecución (la pasarela transparente) debe leer de este descriptor para obtener la información contenida en dicho paquete.

Para realizar las funciones de inicialización del descriptor, lectura y «parseo» de la infor- mación recibida, y envío de datos desde la pasarela a los sensores, el programa principal utiliza las funcionalidades que ofrece esta librería. El código necesario para realizar estas 5.4. ETAPA 4: PASARELA TRANSPARENTE 105

Pseudocódigo 5.2 Pseudocódigo de la función mqtt2mqttsn(). function MQTT2MQTTSN(mqttMessage, originMac) Switch Message type Case CONNACK –Code to translate message buf ← message bufAllocated ← true EndCase Case PUBACK –Code to translate message buf ← message bufAllocated ← true EndCase Case PUBREC –Code to translate message buf ← message bufAllocated ← true EndCase Case PUBCOMP –Code to translate message buf ← message bufAllocated ← true EndCase Case PINGRESP –Code to translate message buf ← message bufAllocated ← true EndCase Default wrong message type EndSwitch if bufAllocated == true then –Prepare buf to send by XBee module SEND_BYMAC(originMac, buf) . Función para enviar datos a los sensores end if end function 106 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

Pseudocódigo 5.3 Pseudocódigo para un manejador de petición. function MESSAGEX_HANDLER(message, originMac) –Code to process the request linked to this message SEND_MESSAGEX(param1, param2, ..., originMac) end function function SEND_MESSAGEX(param1, param2, ..., originMac) –Code to generate the message to send using parameters received buf ← message SEND_BYMAC(originMac, buf) end function

tareas, es quizás el de más bajo nivel de esta etapa, con lo cual, en los siguientes apartados se explicará con detalle cada una de las funciones implementadas. Una vez se concluyan estos apartados, tan solo quedará explicar todo lo relacionado con el archivo principal de la pasarela (tGatewayServer.cpp). Dada su importancia, se le dedica la Sección 5.4.2.

Inicialización y configuración del módulo XBee, función xbee_init() El puerto serie del modulo XBee se encuentra en el archivo /dev/ttyS0 de la pasarela. Esta función devuelve un entero que representa al descriptor de archivo de /dev/ttyS0, una vez abierto y configurado. Un descriptor de archivo, es una referencia a una de la entradas de la tabla de archivos abiertos que mantiene el sistema. En esta entrada se almacena el desplazamiento dentro del archivo y sus flags de estado. Para obtener este descriptor se utiliza la función open(), que dada una ruta de archivo, devuelve un entero no negativo que representa su descriptor. Como segundo parámetro de esta función, deben indicarse los flags de creación del archivo. Una vez obtenido correctamente el descriptor de archivo, se configuran diversos aspectos de la comunicación, como la velocidad de E/S, control de flujo, paridad, etc. para ello se utiliza una estructura del tipo termios y funciones asociadas a ella. En el Listado 5.13 puede verse el código de esta función, con aclaraciones paso a paso de todo lo que implica.

1 int xbee_init() {

3 struct termios options;

5 /∗ opening port:

6 ∗ O_RDWR − read and write access mode

7 ∗ O_ASYNC − generatea signal when in input or

8 output becomes possible on this file descriptor

9 ∗ O_NOCTTY − for pathnames which refers toa terminal device

10 ∗ O_NDELAY − open the file in nonblocking mode 5.4. ETAPA 4: PASARELA TRANSPARENTE 107

11 ∗ serialPort="/dev/ttyS0"

12 ∗/

13 thefd = open(serialPort, O_RDWR | O_NOCTTY | O_NDELAY | O_ASYNC);

14 if ( thefd == −1) {

15 // could not open port

16 fprintf(stderr, "open_port: Unable to open %s\n", serialPort);

17 }

18 else {

19 fcntl(thefd, F_SETFL, O_NDELAY);

20 tcgetattr(thefd, &options);

21 // setBAUDRATE= B38400

22 cfsetispeed(&options, BAUD_RATE);

23 cfsetospeed(&options, BAUD_RATE);

24 // enable the receiver and set local mode...

25 options.c_cflag |= (CLOCAL | CREAD);

26 // no parity (8 in 1)

27 options.c_cflag &= ~PARENB;

28 options.c_cflag &= ~CSTOPB;

29 options.c_cflag &= ~CSIZE;

30 options.c_cflag |= CS8;

31 // set input mode(non −canonical, no echo,...)

32 options.c_lflag = 0;

33 // inter−character timer unused

34 options.c_cc[VTIME] = 0;

35 // blocking read until1 char received

36 options.c_cc[VMIN] = 1;

38 tcflush(thefd, TCIFLUSH);

40 // apply all changes immediately

41 tcsetattr(thefd, TCSANOW, &options);

42 }

44 return thefd ;

45 }

Listado 5.13: Código de la función xbee_init()

Lectura de un paquete, función xbee_getPacket() Una vez se obtenga el descriptor de archivo, se necesita disponer de un procedimiento para leer datos cuando estos estén disponibles en él. Esta función realiza esa tarea.

Durante el desarrollo de este código, se han tenido grandes inconvenientes, derivados de un comportamiento inesperado del puerto serie que maneja al módulo XBee, ya que este proporcionaba una vez tras otra los datos que tenía disponibles, a pesar de que se leyesen, 108 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

haciendo imposible leer un mensaje completo utilizando el procedimiento habitual (cuando se activa el descriptor, leer todos los datos disponibles).

Para solucionar este problema, se ha realizado una máquina de estados que reconoce una secuencia concreta de la información que debe recibirse, cuando la máquina de estados reco- noce esta secuencia, deja que se lea el resto de información hasta fin de linea. Consiguiendo de esta forma, detectar un mensaje completo. Este procedimiento es clave en esta función y en el funcionamiento general de la pasarela transparente, ya que sin disponer de los mensa- jes MQTT-SN que envían los sensores, no es posible realizar ninguna acción más. Lo que resta de apartado, está dedicado a explicar con detalle el funcionamiento de la máquina de estados.

En la Figura 5.9 puede verse la máquina de estados utilizada. Esta máquina se encuentra dentro de un bucle infinito, en estado IDLE, a la espera del comienzo de la secuencia de caracteres: 0x23 → 0x2d → 0x4d → 0x41. Cuando detecta el primer carácter, pasa a estado START1 y si va recibiendo la secuencia correcta avanza hasta el estado DATA, en el que permanece procesando caracteres hasta que detecta un 0x0a (carácter de nueva linea), y pasa a estado END. Cualquier carácter que rompa la secuencia durante los estados START1, START2 y START3, hace que la máquina vuelva a IDLE.

Cuando se llega al estado END, significa que se ha recibido un fragmento del flujo total de caracteres, que representa un mensaje enviado por un sensor. Es el momento de almacenar la información leída en una estructura de la librería utils, para que este disponible al resto del programa. Una vez hecho esto, se activa un variable para salir del bucle en la siguiente iteración.

Por su extensión no se incluye todo el código de esta función. En su lugar se exponen sus partes más importantes en el Listado 5.14, en el que puede verse como se implementa la máquina de estados y como está incluida dentro del bucle que itera leyendo caracteres.

1 /∗ In utils.h there are some define’s

2 ∗ and one struct that this function needs ∗/

3 #define IDLE 0

4 #define START1 1

5 #define START2 2

6 #define START3 3

7 #define DATA 4

8 #define END 5

10 typedef struct {

11 char ∗ buf ;

12 int size ;

13 }packet_received_t;

15 /∗ Some code of xbee_getpacket() function in utils.c ∗/ 5.4. ETAPA 4: PASARELA TRANSPARENTE 109

Figura 5.9: Máquina de estados para detectar la secuencia de inicio de mensaje. Fuente: Elaboración propia.

17 void xbee_getPacket(packet_received_t ∗ p802 ) {

18 char inbuff[MAX_FRAME];// Buffer to read incoming data into

19 char ∗ offset ;

20 int sizepacket = 0, finish = 0;

21 unsigned int state = IDLE;

23 offset = &inbuff[0];

25 while(1) {

26 //thefd is the file descriptor of/dev/ttyS0

27 sizepacket = read(thefd, offset, 1);

28 if (sizepacket <= 0) { 110 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

29 close(thefd);

30 break;

31 }

32 else {

33 switch( state ) {

34 case IDLE:

35 if (∗ offset==(0x23)){//start state machine

36 state=START1;

37 offset ++;

38 } else state = IDLE;

39 break;

41 case START1 :

42 if (∗ offset==(0x2d)){

43 state=START2;

44 offset ++;

45 } else state = IDLE;

46 break;

48 case START2 :

49 if (∗ offset==(0x4d)){

50 state=START3;

51 offset ++;

52 } else state = IDLE;

53 break;

55 case START3 :

56 if (∗ offset==(0x41)){

57 state=DATA;

58 offset ++;

59 } else state = IDLE;

60 break;

62 case DATA:

63 if (∗ offset==(0x0a)){

64 state = END ;

65 //fragment received;

66 }else {

67 offset ++;

68 break;

69 }

71 case END:

72 // store the bytes reads into p802 structure

73 p802−>size = (offset −&inbuff[0])+1;

74 p802−>buf = (char∗)malloc(p802−>size ∗sizeof(char));

75 memcpy(p802−>buf, inbuff, p802−>size ); 5.4. ETAPA 4: PASARELA TRANSPARENTE 111

77 finish = 1;//set finish variable to1

78 offset = &inbuff[0];//reset offset

80 default:

81 state = IDLE;

82 }

83 }

84 if( finish ) break;//exit of while if finish

85 }

86 }

Listado 5.14: Código principal de xbee_getPacket()

«Parseo» de un paquete para estructurar su información, función xbee_parsePacket() Después de ejecutar la función xbee_getPacket() se tendrá almacenado el paquete recibido en una estructura del tipo packet_received_t, junto con su tamaño. Como se verá en la eta- pa de implementación de MQTT-SN, cuando un sensor envía un mensaje, no solo envía el contenido del paquete MQTT-SN, sino que también añade su dirección MAC para que la pa- sarela pueda enviarle mensajes de respuesta. Para poder identificar la información se añaden etiquetas antes del comienzo de cada parte. Esta función se encarga de separar esta información y de almacenar en una estructura del tipo packet_splited_t la dirección MAC y el mensaje MQTT-SN, en variables distintas, para que el programa principal de la pasarela pueda usarlos de forma independiente. Para conse- guir esto, hay que realizar un tratamiento del buffer de caracteres recibido anteriormente, en concreto se han utilizado las funciones strpbrk() y strchr() de la librería estándar de C, para localizar las etiquetas y posteriormente almacenar convenientemente la información que les sigue. La función strpbrk() recibe como parámetros dos punteros a cadenas de caracteres (s y p, respectivamente) y localiza en s, la ocurrencia de cualquiera de los caracteres de p. Devuelve un puntero al byte en s que coincide con uno de los caracteres de p, o el valor NULL si no encuentra coincidencias. La función strchr() recibe como parámetros un puntero a una cadena de caracteres (s) y un carácter (c), y localiza la primera ocurrencia de c en s. Devuelve un puntero al byte en s que coincida con c, o NULL si c no está contenido en s.

Por ejemplo, la forma en que se ha obtenido la dirección MAC puede verse en el Listado 5.15. Del mismo modo, se ha obtenido el paquete MQTT-SN, y se ha almacenado en otro campo de la estructura del tipo packet_splited_t.

1 /∗ How to obtain mac value.

2 ∗ −− p802 isa packet_received_t structure that contains 112 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

3 ∗ the message received from the sensor

4 ∗ −− pSplited isa empty packet_splited_t structure ∗/

6 char ∗ _macStart , ∗ aux ;

7 char mac [22];

8 int index, error = 0;

9 char pAux [p802−>size −1];

11 aux = strpbrk(pAux, "−MAC");

12 if(aux == NULL)

13 error = 1;

15 //Get mac value

16 memset(mac, 0, sizeof( mac ));

17 if(! error ) {

18 _macStart=strchr(aux,’:’);

19 if (_macStart != NULL) {

20 index=_macStart−aux ;

21 memcpy(mac,aux+index+1,22);

22 mac[22] = ’\0’;

23 }else

24 error = 1;

25 }

27 if( error ) {

28 fprintf(stderr, "ERROR − Unable to parse received frame: %s\n",

29 pAux );

30 exit(−1);

31 } else {

32 pSplited −>mac = (char∗) malloc ((sizeof( mac ))∗sizeof(char));

33 memset(pSplited −>mac , 0, sizeof( mac ));

34 memcpy(pSplited −>mac , mac , sizeof( mac ));

35 }

Listado 5.15: Código ejemplo de xbee_parsePacket()

Con esta función, se han terminado de desarrollar todas las utilidades necesarias para que la pasarela pueda recibir y procesar los mensajes provenientes de los sensores, aislando los distintos tipos de información disponibles en el mensaje (dirección MAC y paquete MQTT- SN), pudiendo proceder así, a realizar sus funciones como servidor y traductor.

Envio de datos al sensor, función send_byMac() Cuando el broker Mosquitto envíe mensajes hacia los clientes MQTT-SN, estos pasarán previamente por la pasarela, en concreto deberán pasar por la función mqtt2mqttsn() explica- da anteriormente. Una vez que el mensaje haya sido traducido, la pasarela deberá enviarlo al 5.4. ETAPA 4: PASARELA TRANSPARENTE 113 sensor correspondiente, utilizando la dirección MAC del sensor, que la pasarela habrá alma- cenado previamente (generalmente durante la conexión del cliente MQTT-SN). La función send_byMac() se encarga de realizar este envío. Su código ha sido obtenido por completo del archivo ZigBeeSend.c contenido en la ru- ta /var/ManagerSystem/plugin/b_SensorData/b0_capturer/bin/ de la pasarela. Este archivo contiene funciones para enviar datos a los sensores que estén conectados en red con la pa- sarela Meshlium (véase Sección 5.1.2). Lo único que se ha hecho es adaptar la función que realiza el envío de mensajes utilizando la dirección MAC del sensor. En lugar de esperar el mensaje a enviar y la dirección MAC por linea de ordenes, le llegan como parámetros. También se ha eliminado una parte del código que ponía a la pasarela a la espera de recibir respuesta en un hilo de ejecución nuevo, esto no es necesario en este caso.

5.4.2 Archivo principal tGatewayServer.cpp (transparent Gateway Server) Como se dijo al comienzo de esta sección, la pasarela transparente tiene que actuar como un programa servidor al que se le pueden conectar varios clientes, en este caso los clientes son las distintas conexiones que tiene que manejar, tanto con los sensores como con el broker MQTT. De forma que, el archivo tGatewayServer.cpp es un servidor. A la hora de escribir el código de este archivo se contemplaron dos opciones posibles:

Crear un nuevo proceso o hilo por cada conexión que llegase desde los sensores, más el proceso o hilo principal, que se mantendría a la espera de aceptar nuevas conexiones. Manejar todas las conexiones en el mismo proceso, manteniendo el servidor «dormi- do», a la espera de que hubiese datos disponibles en alguna de las conexiones.

Tras estudiar ambas posibilidades, se llegó a la conclusión de que la primera opción, sería adecuada cuando las peticiones de conexión por parte de los sensores fuesen muy numerosas, y el servidor emplease más tiempo en procesar una petición, que el periodo de tiempo que pasa entre peticiones de conexión. De forma que el servidor no fuese capaz de atender las conexiones de forma consecutiva, y tuviese que delegar este trabajo a nuevos procesos o hilos, y el dedicarse a crearlos y gestionarlos. Este caso no se adapta a estas características, ya que el tiempo en atender una petición es muy pequeño, en comparación con el tiempo en que se suceden. La segunda opción es la adecuada, ya que está pensada para cuando las peticiones de los clientes se pueden procesar rápidamente, de forma que es posible atender a una conexión antes de que se active otra. Si cada conexión que debe gestionar el servidor, es manejada por un descriptor de archivo, el código que se escriba para implementar el servidor tiene que ser capaz de gestionar un conjunto de estos descriptores (descriptor de socket, descriptor de dispositivo de terminal, etc.). Esta acción es posible llevarla a cabo con la función select() de la librería estándar de 114 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

C.

La función select() permite que un programa monitorice múltiples descriptores de archivo, manteniéndose a la espera de que uno o varios de estos descriptores pasen a estado «prepa- rado», para alguna operación de E/S. Un descriptor de archivo se considera «preparado» si es posible realizar una operación de E/S sin bloqueo.

Los parámetros de esta función son los siguientes:

int nfds: debe contener el valor del descriptor de archivo más alto, más uno.

fd_set *readfds: puntero al conjunto de descriptores de los que interesa saber si hay algún data disponible para leer. También se avisará cuando haya un nuevo cliente o un cliente cierre la conexión.

fd_set *writefds: puntero al conjunto de descriptores de los que interesa saber si se puede escribir en ellos. Para este caso en concreto no se usa.

fd_set *exceptfds: puntero al conjunto de descriptores de los que interesa saber si ha ocurrido alguna excepción. En este caso tampoco interesa.ç

struct timeval *timeout: especifica el intervalo de tiempo que select() va a estar es- perando para que algún descriptor este «preparado».

Una llamada a select() mantendrá el programa bloqueado hasta que un descriptor esté «preparado», se reciba una señal de interrupción o expire el timeout. Cuando la función retorna, cambia los contenidos de los conjuntos de descriptores, para indicar cuales de estos descriptores están «preparados», por este motivo es importante inicializar todos los conjuntos antes de volver a llamar a select(). Para operar con los conjuntos se dispone de una serie de macros:

FD_ZERO(fd_set*): vacía el conjunto al que apunta el puntero.

FD_SET(int, fd_set*): introduce el descriptor que se le pasa como parámetro uno, en el conjunto que se le pasa como parámetro dos.

FD_ISSET(int, fd_set*): indica si el descriptor que se le pasa como parámetro uno, esta «preparado». Con esta macro se debe de ir preguntando a select() por cada uno de los descriptores que contiene.

FD_CLEAR(int, fd_set*): elimina el descriptor que se le pasa como parámetro uno, del conjunto que se le pasa como parámetro dos.

La función select() es fundamental en la realización del archivo tGatewayServer.cpp, ya que permite alternar entre el tratamiento de mensajes MQTT-SN y MQTT, mediante el uso de un conjunto de lectura de descriptores de archivo (readfds), donde, como ya se ha dicho, se introducen tanto los descriptores de socket, como el descriptor del módulo XBee. 5.4. ETAPA 4: PASARELA TRANSPARENTE 115

Lo que resta de apartado está dedicado a explicar en profundidad el código de la función principal o main, de este archivo. Para ello se han realizado una serie de pseudocódigos que esquematizan el código y permiten aclarar su propósito.

Pseudocódigos En el Pseudocódigo 5.4, puede verse la estructura del código de esta función, la cual está formada por un bucle infinito, en cuyo interior se realiza una llamada a la función select().

Pseudocódigo 5.4 Esquema de todo el código de la función principal. function MAIN . p802: puntero a estructura packet_received_t maxfd ← −1 . pSplited: puntero a estructura packet_splited_t numCon ← 0 . rfds: conjunto de descriptores xbeefd ← XBEE_INIT maxfd ← MAX(xbeefd, maxfd) while 1 do –Code to prepare select() function SELECT(maxfd + 1, rfds, 0, 0, NULL) . Llamada a select() if FD_ISSET(xbeefd, rfds) then . Si se activa XBee... XBEE_GETPACKET(p802) XBEE_PARSEPACKET(pSplited, p802) –Obtain message type from the packet if msgtype == connect then –Code for treat this situation else –Code for treat this situation end if –After that, we know if client requires a server or a translation if messagerequiresserver then –Code to serve the request else –Code to translate messages end if end if for i

En cada vuelta del bucle se comprueban tanto el descriptor del modulo XBee, como los descriptores de los sockets, si hay alguno activo, se realizan acciones pertinentes en cada caso.

Si se activa el descriptor del modulo XBee: 116 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

1. Se recibe el paquete. 2. Se «parsea» el paquete. 3. Se analiza el mensaje MQTT-SN que ha llegado. Si es un CONNECT, antes de realizar la traducción a MQTT, es necesario (véase Pseudocódigo 5.5): • Comprobar si es un CONNECT que requiere will features. • Inicializar el manejador de conexión con el broker de este cliente. A partir de esta acción se obtiene un descriptor de socket que representa la conexión TCP abierta con Mosquitto. • Almacenar este descriptor y añadirlo al conjunto de descriptores de la función select(). • Actualizar la variable que representa el número de descriptor más alto. • Actualizar los mapas: Durante la ejecución del programa, la pasarela mantiene tres mapas (utilizando la librería map de C++), que le permiten relacionar cada cliente conectado con su descriptor de socket correspondiente, y viceversa, con el fin de poder realizar el envío de los mensajes sin equivocarse de destinatario. Además, el empleo de estos mapas también hace posible que la pasarela mantenga más de un cliente conectado al mismo tiempo. Los mapas son:

◦ macsMap: almacena parejas clave-valor, del tipo: MAC → socket. Esta aso- ciación, permite mantener una lista de direcciones MAC de los clientes co- nectados, además de proporcionar en cualquier momento su descriptor de socket correspondiente. ◦ socksMap: almacena parejas clave-valor, del tipo: socket → MAC. Esta asociación, permite a la pasarela poder consultar la dirección MAC de un cliente MQTT-SN, cuando se reciben mensajes desde Mosquitto. ◦ brokersMap: almacena parejas clave-valor, del tipo: MAC → broker. Esta asociación, permite que la pasarela pueda consultar en cualquier momen- to, cuál es el manejador de conexión MQTT correspondiente a un cliente MQTT-SN en concreto. • Inicializar los topics por defecto del cliente (esta funcionalidad está relacionada con el procedimiento de registro de topics y se explicará en la etapa de imple- mentación de MQTT-SN.). • Incrementar en uno el número de conexiones con Mosquitto.

Si por el contrario, no se trata de un mensaje CONNECT, hay que comprobar si la MAC del sensor que ha enviado el mensaje, existe en macsMap. Si existe, es un mensaje válido y se pasa a comprobar si pertenece a uno de los tipos «especiales» que harían que la pasarela tuviese que actuar como servidor. Si la MAC no existe en el mapa, 5.4. ETAPA 4: PASARELA TRANSPARENTE 117

Pseudocódigo 5.5 Procedimiento cuando llega un CONNECT. if msgtype == connect then –Check if will features are active sockets[numCon] ← MQTT_INIT(broker, host, port) FD_SET(sockets[numCon], rfds) maxfd ← MAX(sockfd, maxfd) macsMap[mac] ← sockets[numCon] . Actualizar mapas socksMap[sockets[numCon] ← mac brokersMap[mac] ← broker INITTOPICS(mac) . Iniciar topics por defecto numCon ← numCon + 1 end if

el único motivo que indicaría que no se trata de un error, es que el mensaje sea un

PUBLISH con QOS nivel -1 (véase Sección 3.3.2). Este procedimiento puede verse esquematizado en el Pseudocódigo 5.6.

Pseudocódigo 5.6 Procedimiento cuando no llega un CONNECT. if EXIST_MAC(macsMap, mac) then if msgtype == register then msg_register ← true else if msgtype == disconnect then if ISSPECIALDISCONNECT then special_disconnect ← true end if else if msgtype == pingreq then if ISSPECIALPING then special_ping ← true end if end if else if msgtype == publish then if qos == -1 then publishM1 ← true end if else error ← true end if end if

Una vez realizados estos pasos, ya pueden activarse bien los manejadores de petición (pasarela como servidor), bien las funciones de conversión (pasarela como traductor).

4. Si el mensaje corresponde a uno de los tipos para los que es necesario actuar como servidor, se llama a su función manejador. Sino, la pasarela debe actuar como traductor, se distinguen tres casos distintos (véase Pseudocódigo 5.7): 118 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

• Que el mensaje sea un PUBLISH con QOS -1. En cuyo caso la pasarela debe establecer una sesión MQTT con el broker, llamar a la función de conversión, que se encarga de enviar el mensaje al broker, y cerrar la sesión MQTT. • Que el mensaje sea un DISCONNECT. En cuyo caso, después de llamar a la función de conversión, la pasarela deberá eliminar toda información del cliente contenida en los mapas, cerrar su socket con Mosquitto y decrementar el número de conexiones. • Que el mensaje no corresponda a los casos anteriores, y solo sea necesario obte- ner manejador de conexión con Mosquitto y llamar a la función de conversión.

Pseudocódigo 5.7 Procedimiento cuando debe actuar como servidor. if register then REGISTER_HANDLER(mqttsnMsg, mac) else if special_disconnect then DISCONNECT_HANDLER(mqttsnMsg, mac) else if special_connect then CONNECT_HANDLER(mqttsnMsg, mac) else if special_ping then PING_HANDLER(mqttsnMsg, mac) else if publishM1 == true then MQTT_INIT(broker, host, port) . La pasarela gestiona la sesión MQTT INITTOPICS(mac) MQTTSN2MQTT(mqttsnMsg, broker, msgtype, mac) . Función de conversión else broker ← GETBROKER_BYMAC(brokersMap, mac) MQTTSN2MQTT(mqttsnMsg, broker, msgtype, mac) end if if msgtype == disconnect then CLOSE(sockfd) . Limpiar información del cliente CLEAN_CLIENTINFO(macsMap, socksMap, brokersMap, mac) numCon ← numCon − 1 end if end if

Si por el contrario, se activa alguno de los descriptores de socket, se comprueba si el socket existe en socksMap. Si existe:

Se obtiene su dirección MAC.

Se obtiene el manejador de conexión MQTT que corresponde a esa MAC. Se recibe la información del socket y se llama a la función de conversión mqtt2mqttsn(), que se encarga de convertir y enviar el mensaje. Si no existe, significa que el cliente ya ha cerrado la conexión enviando un mensaje DIS- CONNECT, y la información que ha enviado Mosquitto se corresponde con alguno de los 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 119 intercambios de TCP para cerrar la conexión. Hay que leer del socket y descartar los datos (véase Pseudocódigo 5.8).

Pseudocódigo 5.8 Procedimiento a seguir cuando se activa un socket. if FD_ISSET(sockets[i], rfds) then . Si se activa el socket i... if EXISTS_SOCK(socksMap, sockets[i]) then macAux ← GETMAC_BYSOCKET(socksMap, sockets[i]) broker ← GETBROKER_BYMAC(brokersMap, mac) MQTT_RECV_PACKET(broker, 255, 0x1e) MQTT2MQTTSN(mac) else RECV(sockets[i], tempBuf) . Descartar datos recibidos end if end if

5.5 Etapa 5: Librería MQTT-SN y el software de traducción Hasta el momento, se ha escrito código para dos de las tres partes que tiene la infraes- tructura de comunicación. Una de ellas se ha terminado por completo, la librería MQTT, y en la otra, la pasarela transparente, se han dado grandes pasos implementando su estructura principal, pero está aún por terminar ya que falta por añadirle las partes de código referentes al tratamiento de mensajes MQTT-SN y a la traducción entre protocolos. En esta etapa se realiza un estudio en profundidad del protocolo MQTT-SN, lo que per- mitirá terminar con la implementación de todo el código de la infraestructura, puesto que se conocerán todos los aspectos relativos a la sintaxis, semántica y temporización del protocolo, y se podrá:

Implementar la librería MQTT-SN para los dispositivos Waspmote de la empresa Li- belium. Completar el código del archivo principal de la pasarela, para que examine los mensa- jes y quede definido el flujo del programa. Realizar las funciones de traducción entre protocolos necesarias para la librería mqt- tsnServerForwarder de la pasarela (tanto mqttsnSF.h como mqttsnSF.cpp).

Al igual que la etapa de implementación de la librería MQTT (Sección 5.3), esta etapa se divide en tres fases o tareas: Estudio de la especificación del protocolo, en la que se expondrán todos los aspectos referentes a la especificación de MQTT-SN que sean importantes de cara al desarrollo de esta parte. Creación de los archivos de cabecera, en este caso dos: el archivo de cabecera de la li- brería de los sensores y el archivo mqttsnSF.h de la mqttsnServerForwarder, explicado en la etapa anterior. 120 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

Implementación del protocolo MQTT-SN y del software de traducción, en la que se implementan los distintos tipos de mensajes y características de MQTT-SN, junto con el código de las funciones de traducción vistas en la etapa anterior. Siguiendo la metodología de desarrollo TDD.

La implementación de las funciones de traducción podría dejarse para una etapa poste- rior, y en esta tan solo escribir el código de la librería MQTT-SN. Sin embargo, es en esta etapa donde se adquieren conocimientos sólidos del protocolo, que junto con los ya adqui- ridos sobre MQTT, permiten realizar el software de traducción sin mucho esfuerzo añadido. Además, los distintos escenarios de prueba realizados (que necesitan la traducción de proto- colos), permiten que una vez terminada esta etapa, las funcionalidades de la infraestructura estén completamente testeadas.

Cuando se finalicen estas fases, la infraestructura estará completamente desarrollada y lista para ser probada con algún ejemplo real que utilice suscriptores externos, tema que será tratado en la siguiente etapa (véase Sección 5.6).

5.5.1 Estudio de la especificación La especificación de MQTT-SN [SCT13] está dividida en 7 secciones, entre las que se distingue 4 partes distintas:

1. Teoría sobre el protocolo, que engloba las secciones 2, 3 y 4. En las que se introduce la necesidad de desarrollar MQTT-SN como alternativa a MQTT para las redes de sensores, las diferencias entre ambos protocolos y algunos aspectos de su arquitectura.

2. Formato de los mensajes, donde se detallan tanto el formato general de los mensajes MQTT-SN, como detalles específicos de cada mensaje. Sección 5 de la especificación.

3. Descripción funcional del protocolo, donde se explican los distintos procedimientos que lleva asociado MQTT-SN. Sección 6 de la especificación.

4. Notas de implementación, contiene consejos y buenas prácticas a tener en cuenta a la hora de implementar el protocolo. Sección 7 de las especificación.

En esta sección del documento interesan las partes 2, 3 y 4. Y en la parte 2, tan solo el formato general de los mensajes del protocolo, ya que el formato de cada mensaje en concreto se tratará en la etapa de implementación cuando tenga que escribirse su código. Los aspectos tratados en la parte 1 de la especificación, fueron útiles durante la etapa de documentación, pueden verse en la Sección 3.3.2.

Formato de los mensajes Un mensaje MQTT-SN tiene dos partes: una cabecera de 2 o 4 bytes de longitud y una parte variable opcional. Mientras que la cabecera siempre está presente en los mensajes y 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 121 contiene los mismos campos, la presencia y el contenido de la parte variable depende del tipo de mensaje.

Length MsgType (1 o 3 bytes) (1 byte) Cuadro 5.8: Formato de la cabecera MQTT-SN. Fuente: [SCT13].

El formato de la cabecera puede verse en el Cuadro 5.8. El campo length especifica el número total de bytes que contiene el mensaje (incluyéndose a si misma). Si su primer byte tiene el valor 0x01, entonces su longitud es de 3 bytes. Los dos siguientes bytes especifican el número total de bytes del mensaje (en formato big-endian), el mensaje puede tener más de 256 bytes de longitud. Si length solo tiene un byte, este indica la longitud del mensaje, que será como máximo de 256 bytes. MQTT-SN no admite fragmentación así que la longitud máxima del paquete viene deter- minada por la capacidad de la red subyacente. El número de bytes que pueden encapsularse en un paquete 802.15.4 es inferior a 256, con lo cual este campo siempre tendrá un byte de longitud en esta implementación. El campo MsgType ocupa 1 byte y especifica el código del mensaje (véase Cuadro 5.9).

Código Mensaje Código Mensaje 0x00 ADVERTISE 0x01 SEARCHGW 0x02 GWINFO 0x03 reserved 0x04 CONNECT 0x05 CONNACK 0x06 WILLTOPICREQ 0x07 WILLTOPIC 0x08 WILLMSGREQ 0x09 WILLMSG 0x0A REGISTER 0x0B REGACK 0x0C PUBLISH 0x0D PUBACK 0x0E PUBCOMP 0x0F PUBREC 0x10 PUBREL 0x11 reserved 0x12 SUBSCRIBE 0x13 SUBACK 0x14 UNSUBSCRIBE 0x15 UNSUBACK 0x16 PINGREQ 0x17 PINGRESP 0x18 DISCONNECT 0x19 reserved 0x1A WILLTOPICUPD 0x1B WILLTOPICRESP 0x1C WILLMSGUPD 0x1D WILLMSGRESP 0x1E-0xFD reserved 0xFE Mensaje encapsulado 0xFF reserved Cuadro 5.9: Valores de los códigos que representan los tipos de mensajes MQTT-SN. Fuente: [SCT13].

Por su parte, el contenido de la cabecera variable depende el tipo de mensaje. Un mensaje puede contener los siguientes campos en su cabecera variable: 122 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

ClientID: Al igual que en MQTT, este campo sirve para identificar a un cliente de forma unívoca y tiene entre 1 y 23 carácteres. Data: Al igual que en MQTT, este campo contiene la información a publicar y tiene una longitud variable. Duration: Este campo tiene 2 bytes de longitud y sirve para codificar un periodo de tiempo en segundos. El valor máximo que puede indicar es de aproximadamente 18 horas. Flags: Este campo tiene una longitud de 1 byte y contiene los siguientes flags (véase Cuadro 5.10): • DUP y Retain: Mismo significado que en MQTT. Solo relevante para mensajes PUBLISH.

• QOS: Mismo significado que en MQTT, pero se añade el valor 0x11 para el nuevo

nivel -1 de QOS. • Will: Si está activo indica que el cliente está pidiendo que se le pregunte por Will Topic y Will Message. Solo relevante durante el proceso de conexión. • CleanSession: Mismo significado que en MQTT, pero extendido para el proce- dimiento last will and testament. • TopicIdType: Indica si los campos TopicId o TopicName están incluidos en el mensaje, puede valer: 0x00 si contiene un normal topic, 0x01 si contiene un pre- defined topic o 0x10 si contiene un Short Topic Name.

DUP QoS Retain Will CleanSession TopicIdType (bit 7) (6,5) (4) (3) (2) (1,0) Cuadro 5.10: Campo flags de la cabecera variable. Fuente: [SCT13].

GwAdd: Contiene la dirección de la pasarela. Tiene longitud variable, depende del tipo de red sobre la que opere MQTT-SN. GwId: Campo de un byte de longitud que identifica unívocamente a un gateway. MsgID: Este campo tiene dos bytes de longitud y se corresponde con el parámetro Message ID de MQTT. Sirve para que el emisor identifique un mensaje con su corres- pondiente acuse de recibo. ProtocolId: Contiene el valor 0x01 e indica el nombre de protocolo y la versión. Solo está presente en el mensaje CONNECT. Ocupa 1 byte. Radius: Indica el valor del radio de broadcast. El valor 0x00 significa «broadcast a todos los nodos de la red». Ocupa 1 byte. ReturnCode: Puede tomar los siguientes valores: • 0x00: Aceptado. 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 123

• 0x01: Rechazado: congestión. • 0x02: Rechazado: topic ID invalido. • 0x03: Rechazado: no soportado. • 0x04 − 0xF F : reserved.

TopicId: Contiene el valor del Topic Id correspondiente. Ocupa 2 bytes.

TopicName: Campo de longitud variable que contiene una cadena de caracteres codi- ficada en UTF-8, que especifica el nombre del topic.

WillMsg: Campo de longitud variable que indica el Will message.

WillTopic: Campo de longitud variable que indica el Will topic name.

Para la implementación que requiere esta infraestructura, no va a ser necesario utilizar los siguientes campos:

GwAdd y GwId, ya que en este caso MQTT-SN opera sobre una red 802.15.4 que ya ha sido establecida, los sensores llevan configurado el firmware con los parámetros de red de la pasarela y no es necesario que MQTT-SN tenga procedimiento de descubrimiento de nodos. Si se añade un nuevo sensor a la red, este deberá ser configurado conforme se indica en la Sección 5.1.

Radius.

WillMsg y WillTopic, ya que la característica last will and testament no van a ser im- plementadas.

Descripción funcional A pesar de que MQTT-SN fue diseñado para ser los más cercano posible a MQTT: mismos flujos de datos, semántica similar, mismos mensajes, etc. Existen procedimientos y caracte- rísticas que difieren con lo que MQTT establece. En este apartado se tratan los principios de diseño de MQTT-SN que varían con los es- tablecidos en MQTT y que tienen relación directa con su uso en la infraestructura que se desarrolla. Aquellos procedimientos de MQTT-SN que no vayan a ser usados, debido a que la infraestructura no contempla esas situaciones, no se incluyen. Se distinguen los siguientes mecanismos:

Procedimiento para el registro de Topic Name:

Debido al ancho de banda limitado y al tamaño reducido del payload en los mensajes de las redes de sensores, en MQTT-SN los datos no se publican junto con el Topic Name como en MQTT. Sino que se introduce un procedimiento que permite tanto a la pasarela como al cliente, mantener una relación Topic Name-Topic Id. Antes de pu- 124 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

blicar, es necesario realizar el registro de un Topic Name y obtener su correspondiente Topic Id, que posteriormente será incluido en el mensaje PUBLISH. Para realizar este registro, un cliente envía un mensaje REGISTER a la pasarela, indi- cando un Topic Name. Si el registro es aceptado, la pasarela asigna un Topic Id a ese Topic Name y se lo envía al cliente en un mensaje REGACK. Si el registro no puede ser realizado, también es necesario enviar un mensaje REGACK indicando en el campo ReturnCode el motivo. Después de que el cliente haya recibido un REGACK satisfactorio, deberá usar ese Topic Id para publicar información, la pasarela realizará la conversión al Topic Name. Si en el mensaje REGACK se indica que se ha rechazado el registro por motivos de congestión, el cliente deberá esperar un tiempo antes de intentar el registro de nuevo. Esta operación es bloqueante en el aspecto de que un cliente no puede enviar dos REGISTER sin haber recibido el correspondiente REGACK del primero. Procedimiento para que un cliente publique: Después de haber registrado satisfactoriamente un Topic Name con la pasarela, el clien- te puede empezar a publicar datos en ese topic, indicando en el mensaje PUBLISH el Topic Id que le haya proporcionado la pasarela. MQTT-SN soporta los tres niveles de

QOS de MQTT y sus correspondientes flujos de mensajes. Si durante alguno de estos flujos, el cliente recibe un PUBACK con un código que indique que el Topic Id es invalido, el cliente deberá registrarlo de nuevo. En un mismo instante de tiempo, un cliente solo puede tener un flujo de PUBLISH con

QOS 1 o 2. Hasta que uno de estos flujos no termine, no puede empezar el siguiente. Pre-defined topic ids y short topic names: Un pre-defined topic id es un Topic Id cuyo mapeo con su Topic Name correspondiente, se conoce de antemano, tanto por el cliente como por la pasarela. Cuando se utiliza este tipo de topic, debe de indicarse en el correspondiente flag del mensaje. Para usar estos topics no hace falta registro previo. Si se recibe un PUBLISH con un pre-defined topic id desconocido, debe contestarse con un PUBACK que indique esta situación. Esta situación de error no puede ser subsanada realizando el proceso de registro. Un Short Topic Name es un Topic Name que tiene una longitud de 2 bytes y puede ser llevado junto al payload sin necesidad de registro previo.

PUBLISH con nivel de QOS -1: Esta característica esta definida para aquellos clientes cuya implementación sea tan simple que no soporte ninguna otra característica. En este caso, no hay establecimiento de conexión, ni registro, ni suscripciones. El cliente tan solo necesita enviar un mensaje PUBLISH a la pasarela (cuya dirección se conoce a priori) y descartarlo después. No 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 125

importa si la dirección de la pasarela es correcta, si esta está disponible o si el mensaje ha llegado o no.

Notas de implementación En las implementaciones en las que se use una pasarela transparente, como una publi-

cación con nivel de QOS -1 no requiere de establecimiento de conexión previo, será la pasarela la que se encargue de mantener una sesión MQTT con el broker, y de cerrarla cuando el proceso termine.

Este dato tiene especial relevancia ya que es justo el escenario que se desarrolla en la infraestructura. Deberá realizar lo que aquí se indica.

Para reducir el riesgo de asignar a un Topic Name un Topic Id erróneo, la pasarela debe mantener una estructura de datos que guarde la relación Topic Id-Topic Name distinta para cada cliente.

Debido al tamaño pequeño de payload que poseen las redes ZigBee, si se opta por usar este tipo de red, el tamaño máximo de mensaje MQTT-SN será de 60 bytes.

5.5.2 Creación de los archivos de cabecera Al igual que el archivo de cabecera que se creó durante la implementación de MQTT, una vez que se han obtenido los conocimientos necesarios sobre como formar los mensajes MQTT-SN, es el momento ideal para crear una primera versión de los dos archivos de cabe- cera que se desarrollan durante esta etapa, que contendrán los distintos valores que pueden tomar los diferentes campos de bits de un mensaje MQTT-SN, permitiendo una implementa- ción más sencilla tanto de los mensajes y características de MQTT-SN, como de las funciones de traducción de la pasarela.

Se van a crear dos archivos:

El archivo de cabecera de la librería MQTT-SN para dispositivos Waspmote, denomi- nado WaspMqttSN.h.

El archivo de cabecera de la librería mqttsnServerForwarder (véase Sección 5.4.1), denominado mqttsnSF.h.

WaspMqttSN.h Como Libelium indica en su foro para desarrolladores5, es recomendable escribir las li- brerías para los dispositivos Waspmote en lenguaje C++. De forma que, la librería contenga una clase que permita instanciar objetos, a través de los cuales se accede a las distintas fun- cionalidades de la librería.

5http://www.libelium.com/forum/viewtopic.php?f=28&t=12143 126 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

En esta fase tan solo se codificarán las distintas declaraciones de variables, constantes, estructuras, etc. Junto con la definición de la estructura de la clase, que se irá completando en la siguiente etapa conforme avance el desarrollo de la librería.

Tras el estudio realizado en la Sección 5.5.1, se ha creado la primera versión de este archi- vo (véase Listado 5.16). En el que puede verse como en primera instancia se han declarado los identificadores de los distintos campos de bits, después la clase y después el objeto de esta clase, que se usará desde el código cliente para utilizar la librería. Cabe destacar la inclu- sión del archivo de cabecera WaspXBee802.h de la API de Libelium, usado para tratar todo lo relacionado con el envío/recepción de paquetes a través de la red.

Otro aspecto importante, es el uso de las características public y private de C++, utiliza- das para controlar el acceso del cliente a las distintas partes de la librería. En este caso se declarará como publico todas las funciones que el usuario necesite utilizar de forma directa, el constructor y el destructor de la clase. Y como privado, todas las variables utilizadas y las funciones que no necesiten ser llamadas desde el código del cliente, sino que sean utilizadas por otras funciones de la librería.

1 #ifndef MQTTSN_H

2 #define MQTTSN_H

4 /∗ includes ∗/

5 #include

7 /∗ definitions& declarations ∗/

8 #define SUCCESS 1

9 #define MAX_PACKET_LENGTH 66

11 // message types

12 #define MQTTSN_PROTOCOL_VERSION (0x01)

13 #define MQTTSN_TYPE_CONNECT (0x04)

14 #define MQTTSN_TYPE_CONNACK (0x05)

15 #define MQTTSN_TYPE_REGISTER (0x2E)

16 #define MQTTSN_TYPE_REGACK (0x0B)

17 #define MQTTSN_TYPE_PUBLISH (0x0C)

18 #define MQTTSN_TYPE_PUBACK (0x0D)

19 #define MQTTSN_TYPE_PUBCOMP (0x0E)

20 #define MQTTSN_TYPE_PUBREC (0x0F)

21 #define MQTTSN_TYPE_PUBREL (0x10)

22 #define MQTTSN_TYPE_SUBSCRIBE (0x12)

23 #define MQTTSN_TYPE_SUBACK (0x13)

24 #define MQTTSN_TYPE_UNSUBSCRIBE (0x14)

25 #define MQTTSN_TYPE_UNSUBACK (0x15)

26 #define MQTTSN_TYPE_PINGREQ (0x16)

27 #define MQTTSN_TYPE_PINGRESP (0x17)

28 #define MQTTSN_TYPE_DISCONNECT (0x18) 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 127

30 // flags

31 #define MQTTSN_FLAG_DUP (0x80)

32 #define MQTTSN_FLAG_QoS0 (0x00)

33 #define MQTTSN_FLAG_QoS1 (0x20)

34 #define MQTTSN_FLAG_QoS2 (0x40)

35 #define MQTTSN_FLAG_QoSm1 (0x60)

36 #define MQTTSN_FLAG_RETAIN (0x10)

37 #define MQTTSN_FLAG_WILL (0x08)

38 #define MQTTSN_FLAG_CLEAN_SESSION (0x04)

40 // topics types

41 #define MQTTSN_TOPIC_TYPE_NORMAL (0x00)

42 #define MQTTSN_TOPIC_TYPE_PREDEFINED (0x01)

43 #define MQTTSN_TOPIC_TYPE_SHORT (0x02)

45 // number of topics per client

46 #define MAX_TOPICS 10

48 /∗ Recommended values for timers and counters.

49 ∗ All timers are in seconds. ∗/

50 #define T_ADV 960

51 #define N_ADV 3

52 #define T_SEARCH_GW 5

53 #define T_GW_INFO 5

54 #define T_WAIT 360

55 #define T_RETRY 15

56 #define N_RETRY 5

58 /∗ Return codes ∗/

59 enum return_codes {

60 ACCEPTED = (0x00),

61 REJECTED_CONGESTION = (0x01),

62 REJECTED_INVALID_TOPIC_ID = (0x02),

63 REJECTED_NOT_SUPPORTED = (0x03)

64 };

66 /∗ struct to store the relationship beetwen topic name and topic id ∗/

67 struct topic {

68 const char ∗ name ;

69 uint16_t id;

70 };

72 /∗ class ∗/

73 class WaspMqttSN

74 {

75 /∗ All private variables here 128 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

76 ∗ (variables are private by default) ∗/

78 private :

79 /∗ Prototype of private functions here ∗/

81 public :

82 WaspMqttSN();

83 ~WaspMqttSN(){};

85 /∗ Prototipe of public functions here ∗/

87 };

89 /∗ Class object ∗/

90 extern WaspMqttSN mqttSN;

92 #endif

Listado 5.16: Código de la primera versión del archivo WaspMqttSN.h

mqttsnSF.h Como se mencionó en la Sección 5.4.1, este archivo contiene una librería reducida de MQTT-SN, para que la pasarela pueda disponer de la información referente al formato de los mensajes de este protocolo, y utilizarla para realizar la conversión de MQTT-SN/MQTT y viceversa. La creación de este archivo se fundamenta en que no es posible incluir el archivo de ca- becera WaspMqttSN.h, como parte del código de la pasarela transparente y utilizarlo para la traducción de protocolos, debido a que utiliza la API de Libelium para dispositivos Wasp- mote, que no está disponible para la pasarela Meshlium. Con lo cual, este archivo contendrá todas las declaraciones de constantes, variables y es- tructuras de WaspMqttSN.h, más los prototipos de las funciones necesarias para la imple- mentación del software de la pasarela transparente, explicado en la Sección 5.4.1.

5.5.3 Implementación En esta última fase de la etapa, se pretende desarrollar por completo la librería MQTT-SN, a partir de la implementación de todos los mensajes, características y procedimientos del protocolo. A su vez, también se trata de implementar las funciones de traducción del software de la pasarela transparente. Todo esto se consigue llevando a cabo la implementación de una serie de escenarios de actuación, pero esta vez no del protocolo MQTT-SN, sino de toda la infraestructura. De forma que en cada escenario:

Se desarrolla código para una serie de mensajes MQTT-SN. 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 129

Se escribe el código que necesita la pasarela para tratar estos mensajes. Cabe recordar que el código de la pasarela está prácticamente implementado, solo queda por codi- ficar ciertos aspectos referentes al tratamiento de los mensajes MQTT-SN (una vez «parseado» el mensaje completo enviado por el sensor) y realizar las funciones de traducción. Se desarrolla código para traducir los mensajes que conlleva el escenario, a MQTT. Se desarrolla código para traducir las respuestas que proporciona Mosquitto y enviarlas a los sensores. Es decir, se implementa la traducción de MQTT a MQTT-SN.

Para la implementación de cada mensaje MQTT-SN, se ha consultado la parte 2 de su especificación, en concreto los apartados que tratan cada mensaje de forma individual. Du- rante los esfuerzos de traducción, se han consultado las especificaciones de ambos protocolos (también la parte 2) y la librería MQTT previamente implementada (véase Sección 5.3.3). Los escenarios planteados son los siguientes:

1. CONNECT/DISCONNECT: Este escenario trata la situación en la que un cliente MQTT-SN se conecta a un broker MQTT, a través de una pasarela transparente. Los mensajes que intervienen en este ca- so son: CONNECT, DISCONNECT (envío) y CONNACK (recepción) (véase Figura 5.10). La implementación de este escenario es clave, ya que sin su implementación no es posible realizar el resto. MQTT-SN soporta otro tipo de conexión, llevada a cabo cuando un cliente quiere utilizar la característica last will and testament (véase Figura 5.11). Esta característica no la soporta la infraestructura que se desarrolla, y no será implementada. Sin embargo, es interesante para visualizar como aumenta considerablemente el número de mensajes si se utiliza esta característica. Si se han elegido estos protocolos para llevar a cabo la implementación de la infraestructura que se desarrolla en este TFG, es precisamente porque sobrecargan poco la red sobre la que actúan, luego esta característica no tiene sentido utilizarla. 2. REGISTER: Este escenario trata la situación en la que un cliente MQTT-SN se conecta a Mosquitto, registra un Topic Name en la pasarela y después se desconecta (véase Figura 5.12). Los mensajes que intervienen en este caso son: CONNECT, DISCONNECT (escenario 1), REGISTER (envío) y REGACK (recepción). Este es uno de los casos en que la pasarela no tiene que actuar como traductor, sino como servidor, activando la función manejador correspondiente (véase pseudocódigo 5.3). 3. PUBLISH: 130 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

Figura 5.10: Escenario de actuación del mensaje CONNECT. Fuente: elaboración propia.

Figura 5.11: Escenario de actuación del mensaje CONNECT con las características last will and testament. Fuente: elaboración propia. 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 131

Figura 5.12: Escenario de actuación del mensaje REGISTER. Fuente: elaboración propia.

Este escenario trata la situación en la que un cliente MQTT-SN se conecta a Mosquitto, publica información a un topic, y después se desconecta. Los mensajes que intervie- nen en este caso son: CONNECT, DISCONNECT (escenario 1), PUBLISH, PUBREL (envío), PUBREC y PUBCOMP (recepción).

La publicación puede realizarse con cualquiera de los niveles de QOS que soporta

MQTT-SN (0, 1, 2 y -1). Dependiendo del nivel de QOS, el flujo de mensajes que viajan a través de la infraestructura varía. La Figura 5.13 representa los distintos flujos de datos necesarios para las publicaciones nivel 0, 1. La Figura 5.14 representa el flujo de datos de una publicación de nivel 2, como puede verse conlleva un intercambio complejo, pero en este caso, al tratarse de la publicación de mensajes, se ha considerado conveniente implementarlo. La Figura 5.15 muestra el flujo de datos para una publicación de nivel -1. En la que el cliente se desentiendo por completo de la entrega de la publicación, quedando esta tarea para la pasarela. Para la ejecución de este escenario, es necesario que previamente se haya registrado el Topic Id en el que se publica (escenario 2). 4. PING: En este escenario se comprueba el funcionamiento del procedimiento de ping. Un 132 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

Figura 5.13: Escenario de actuación del mensaje PUBLISH con QOS 0 y 1. Fuente: elabora- ción propia.

cliente se conecta a Mosquitto, envía un ping para mantener la conexión, recibe con- testación y se desconecta. Los mensajes que intervienen son: CONNECT, DISCON- NECT (escenario 1), PINGREQ (envío) y PINGRESP (recepción).

Estos escenarios se implementan utilizando la metodología de desarrollo TDD, cada itera- ción representa la implementación de un escenario, al que se le aplicará el algoritmo de TDD6. Una vez se haya terminado este proceso, habrá concluido el desarrollo de la infraestructura de comunicación sobre la que trata este TFG, y se dispondrá, además, de una cobertura de pruebas completa para ella, que permitirá comprobar el correcto funcionamiento de cada una de sus partes.

En los siguientes apartados se explican funciones que son comunes a todos los escenarios, y sin las cuales no es posible empezar a desarrollarlos. En los apartados sucesivos a estos, se explica el proceso de desarrollo seguido para cada uno de los escenarios descritos.

6Para mayor simplicidad no se aplican todos los pasos de TDD como se explicó en el desarrollo de la librería MQTT (véase Sección 5.3.3), sino que se exponen los procedimientos realizados en cada una de las fases del algoritmo. 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 133

Figura 5.14: Escenario de actuación del mensaje PUBLISH con QOS 2. Fuente: elaboración propia.

Funciones de envío/recepción de paquetes Como ya se ha mencionado, cada uno de los paquetes MQTT-SN que envía un dispo- sitivo Waspmote, va encapsulado en un paquete 802.15.4, junto con la dirección MAC del dispositivo, para que la pasarela pueda identificarlo. Para realizar el envío/recepción de paquetes, en esta librería se han implementado dos funciones: send_packet() y recv_packet(). Su código es una adaptación de los ejemplos que proporciona la API de Libelium, y que se estudiaron en la Sección 5.1.2. Para que la máquina de estados de la función xbee_getPacket() (véase Sección 5.4.1) pueda reconocer la secuencia de inicio de mensaje, y también para distinguir ambas partes a la hora de realizar el «parseo» del mensaje (función xbee_parsePacket()), el mensaje que envía cada sensor contiene dos etiquetas antes del comienzo de cada parte (véase Cuadro 5.11).

Etiqueta Etiqueta (#-MAC:) (#-MQTT:) Cuadro 5.11: Formato de los mensajes que envían los sensores de la infraestructura.

Cada vez que un cliente MQTT-SN quiere enviar un mensaje, ejecutará su función de en- vío correspondiente (por ejemplo connect()), y esta, una vez genere el mensaje en cuestión, llamará a send_packet() para que le añada la dirección MAC (previamente obtenida por el 134 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

Figura 5.15: Escenario de actuación del mensaje PUBLISH con QOS -1. Fuente: elaboración propia. dispositivo) y las etiquetas. Una vez formado el paquete completo, se introduce como pay- load del paquete 802.15.4 y se envía por la red. Para recibir un mensaje, el cliente llamará a recv_packet(), que se mantendrá a la espera de datos durante un tiempo determinado y cuando estos lleguen:

Analizará las estructuras de la API en las que se ha guardado la información recibida (véase Sección 5.1.2).

Procesará el mensaje en busca de errores (longitud errónea, que no se trate de un mensaje MQTT-SN, etc.).

En ausencia de errores, pondrá el mensaje disponible a la función de la librería corres- pondiente.

Obtención de la dirección MAC del dispositivo

Para obtener la dirección MAC del dispositivo Waspmote, se ha añadido una función a la librería (obtain_sensorMac()), que se encarga de almacenar en dos arrays de carácteres, la parte alta de la dirección y la parte baja. Para realizar su código se ha adaptado el ejemplo wasp_pro_start_program_full_802_v1 de la API de Libelium.

El código de está función puede verse en el Listado 5.17. 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 135

1 /∗ macHigh and macLow are array variables in WaspMqttSN.h ∗/

3 void WaspMqttSN::obtain_sensorMac() {

4 xbee802.ON();

5 delay(1000);

6 xbee802.flush();

8 // Get the XBeeMAC address

9 int counter = 0;

10 while((xbee802.getOwnMac()!=0) && (counter<12)) {

11 xbee802.getOwnMac();

12 counter ++;

13 }

15 // convert mac address from array to string

16 Utils.hex2str(xbee802.sourceMacHigh, macHigh, 4);

17 Utils.hex2str(xbee802.sourceMacLow, macLow, 4);

19 delay(1000);

20 xbee802.OFF();

21 }

Listado 5.17: Código de la función obtain_sensorMac()

Escenario CONNECT/DISCONNECT Este escenario representa la primera iteración del proceso de desarrollo, se le aplica el algoritmo de TDD:

1. Escribir la especificación del requisito (el test): En este escenario se pretende desarrollar código para hacer que la librería posea la funcionalidad expresada en el test contenido en el Listado 5.18.

1 /∗ Test Connect/Disconnect Scenary ∗/

2 void test_connect() {

3 int ret = −1, resCon, resCack, resDis;

5 // connect to mosquitto

6 resCon = mqttSN.connect();

7 if (resCon == 1)

8 USB.println("−−−− connect send");

9 // wait fot ack

10 resCack = mqttSN.recv_connack();

11 if (resCack == 1)

12 USB.println("−−−− connack received"); 136 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

14 // small delay

15 delay(1000);

17 // disconnect

18 resDis = mqttSN.disconnect();

19 if (resDis == 1)

20 USB.println("−−−− disconnect send");

22 // check results

23 if (resCon && resCack && resDis)

24 ret = 1;

26 if( ret == 1)

27 USB.println("All Test Passed!!");

28 else

29 USB.println("Test Fail!!");

31 delay(1000);

32 }

Listado 5.18: Test del escenario CONNECT/DISCONNECT

2. Implementar el código según dicho test:

Para superar este test debe escribirse el siguiente código:

• Función de la librería MQTT-SN para enviar los mensajes CONNECT y DIS- CONNECT. Y para recibir el CONNACK. • Parte correspondiente a la traducción MQTT-SN → MQTT de la función mqt- tsn2mqtt() de la pasarela transparente. • Parte correspondiente a la traducción MQTT → MQTT-SN de la pasarela trans- parente (función mqtt2mqttsn()), para traducir el mensaje de respuesta de Mos- quitto. • Código adicional (variables, prototipos de funciones, etc.) que necesite la clase WaspMqttSN de la librería MQTT-SN, para que compilen las funciones realiza- das.

Siguiendo la metodología, primero debe escribirse un código básico, que pase los test, apuntando las dudas que surjan y las posibles mejoras, para mejorar el código en la etapa de refactorización.

3. Refactorizar:

Tras las sucesivas etapas de refactorización (en las que se mejora una parte del código escrito y se ejecutan los test), se obtiene todo el código de este escenario. 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 137

En el Listado 5.19 pueden verse las funciones de envío/recepción de mensajes imple- mentadas en esta iteración. Como puede observarse, para formar los buffer de envío y recepción, se utilizan dos arrays de caracteres. Estos se encuentran declarados en la clase WaspMqttSN, que contiene dos punteros a cadenas de caracteres. En este caso se han utilizado punteros para realizar una reserva de memoria eficiente, ya que los sistemas empotrados que se están programando disponen de pocos recursos. Antes de formar un mensaje MQTT-SN se reserva memoria para él, cuando se envía por la red, se libera esta memoria. De forma análoga se trata el buffer de recepción.

1 /∗ FUNCTIONTOSENDMESSAGECONNECT ∗/

2 int WaspMqttSN::connect() {

3 // variables

4 uint16_t clientidlen = strlen(client_id), offset=0, flags=0x00;

5 uint16_t packetlen = clientidlen+6;

7 // set flags

8 if(clean_session)

9 flags |= MQTTSN_FLAG_CLEAN_SESSION;

11 // allocate packet memory

12 mqttsn_send_buffer =

13 ( uint8_t ∗)malloc(packetlen ∗sizeof(uint8_t));

14 memset(mqttsn_send_buffer, 0, packetlen);

16 // set header

17 mqttsn_send_buffer[0] = packetlen;

18 mqttsn_send_buffer[1] = MQTTSN_TYPE_CONNECT;

19 // set variable−part

20 mqttsn_send_buffer[2] = flags;

21 mqttsn_send_buffer[3] = MQTTSN_PROTOCOL_VERSION;

22 mqttsn_send_buffer[4] = (keep_alive)>>8;

23 mqttsn_send_buffer[5] = (keep_alive)&(0xFF);

24 memcpy(mqttsn_send_buffer+6, client_id, clientidlen);

26 // send msg

27 return WaspMqttSN::send_packet(packetlen, MQTTSN_TYPE_CONNECT);

28 }

30 /∗ FUNCTIONTOSENDDISCCONECTMESSAGE ∗/

31 int WaspMqttSN::disconnect() {

32 // allocate packet memory

33 mqttsn_send_buffer = (uint8_t ∗) malloc (2∗sizeof(uint8_t));

34 memset(mqttsn_send_buffer, 0, 2);

36 // set header

37 mqttsn_send_buffer[0] = (0x02); 138 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

38 mqttsn_send_buffer[1] = MQTTSN_TYPE_DISCONNECT;

40 // send message

41 return WaspMqttSN::send_packet(2, MQTTSN_TYPE_DISCONNECT);

42 }

44 /∗ FUNCTIONTORECEIVECONNACKMESSAGE ∗/

45 int WaspMqttSN::recv_connack() {

46 // receive message

47 int ret =

48 WaspMqttSN::recv_packet(CONNACK_SIZE, MQTTSN_TYPE_CONNACK);

49 if( ret > 0) {

50 //check return code

51 if(mqttsn_recv_buffer[2] == ACCEPTED)

52 ret = 1;

53 else

54 ret = −1;

55 }

56 // free recv buffer

57 free(mqttsn_recv_buffer);

58 mqttsn_recv_buffer = NULL;

60 return ret ;

61 }

Listado 5.19: Código de las funciones del escenario CONNECT/DISCONNECT

En el Listado 5.20 pueden verse las distintas partes de las funciones de traducción, tanto de mqttsn2mqtt() como de mqtt2mqttsn(). En cada caso de traducción se saca la información relevante del mensaje origen, para formar el mensaje destino, ya sea utilizando la librería MQTT implementada, o formando el mensaje in situ.

1 /∗ Code inside mqttsn2mqtt() function

2 ∗ −− res variable is an integer ∗/

3 case MQTTSN_TYPE_CONNECT:

4 {

5 uint16_t durationB1 = (uint16_t)mqttsn[4];

6 uint16_t durationB2 = (uint16_t)mqttsn[5];

7 broker −>clean_session =

8 (mqttsn[2] & MQTTSN_FLAG_CLEAN_SESSION)>>2;

9 broker −>keep_alive = (durationB1<<8)|(durationB2);

10 res = mqtt_send_connect(broker);

11 break;

12 }

14 case MQTTSN_TYPE_DISCONNECT:

15 { 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 139

16 res = mqtt_send_disconnect(broker);

17 close(broker −>sockfd );

18 break;

19 }

21 /∗ Code inside mqtt2mqttsn() function

22 ∗ −− buf isa character array ∗/

23 case MQTT_TYPE_CONNACK:

24 {

25 buf = (char∗)malloc(CONNACK_SIZE ∗sizeof(char));

26 buf[0] = 0x33;

27 buf[1] = MQTTSN_TYPE_CONNACK;

28 if(mqtt_recv_buffer[3] == 0x00)

29 buf[2] = ACCEPTED;

30 else

31 buf[2] = REJECTED_CONGESTION;

33 len = CONNACK_SIZE;

34 bufAllocated = 1;

35 break;

36 }

Listado 5.20: Código de las funciones de conversión del escenario CONNECT/DISCON- NECT

Escenario REGISTER Este escenario representa la segunda iteración del proceso de desarrollo, se le aplica el algoritmo de TDD:

1. Escribir la especificación del requisito (el test): El requisito que debe cumplirse en este escenario viene especificado por el test del Listado 5.21.

1 /∗ Test Register Scenary ∗/

2 void test_register() {

3 int resCon, resCack, resReg, resRack;

5 // connect to mosquitto

6 resCon = mqttSN.connect();

7 if (resCon == 1)

8 USB.println("−−−− connect send");

9 // wait for ack

10 resCack = mqttSN.recv_connack();

11 if (resCack > 0)

12 USB.println("−−−− connack received"); 140 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

14 //small delay

15 delay(1000);

17 // register the topic namea/b

18 resReg = mqttSN.register_topicName("a/b");

19 if(resReg == 1)

20 USB.println("−−−− register send");

21 //wait for ack

22 resRack = mqttSN.recv_regack();

23 if(resRack > 0)

24 USB.println("−−−− regack received");

26 if(resCon && resCack && resReg && resRack)

27 USB.println("All Test Passed!!");

28 else

29 USB.println("Test Fail!!");

31 delay(1000);

32 }

Listado 5.21: Test del escenario REGISTER

2. Implementar el código según dicho test: Para superar este test debe escribirse el siguiente código: • Función de la librería MQTT-SN para enviar el mensaje REGISTER a la pasarela. Y para recibir el REGACK. • Función que devuelva el Topic Id asignado a un Topic Name determinado. • Función manejador del mensaje REGISTER en la pasarela, que se ejecutará cuando el software de la pasarela detecte que el mensaje que ha llegado desde uno de los sensores, es un REGISTER. • Función para enviar el mensaje REGACK desde la pasarela al sensor correspon- diente. Siguiendo la metodología, primero debe escribirse un código básico, que pase los test, apuntando las dudas que surjan y las posibles mejoras, para mejorar el código en la etapa de refactorización. 3. Refactorización: Tras las sucesivas etapas de refactorización (en las que se mejora una parte del código escrito y se ejecutan los test), se obtiene todo el código de este escenario. En el Listado 5.22 pueden verse tanto la función para enviar un mensaje de este tipo, como la encargada de recibir su acuse de recibo. La librería mantiene en todo momento un vector en el que almacena estructuras que guardan la relación Topic Id-Topic Name, 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 141

el número máximo de topics almacenados también lo determina la librería. Antes de enviar un mensaje REGISTER, se comprueba que el número actual de topics almace- nados, no sea superior al número máximo. De ser así, se crea la entrada en el vector de topics con el nuevo Topic Name, y se forma y envía el mensaje. Si el número de topics supera al máximo, se muestra error. Por otra parte, cuando se recibe un mensaje REGACK, se actúa igual que con todos los acuses de recibo, pero además si el código de retorno indica que se ha aceptado el registro, se actualiza la entrada correspondiente del vector de topics, añadiendo el Topic Id devuelto.

1 /∗ FUNCTIONTOSENDREGISTERMESSAGE ∗/

2 int WaspMqttSN::register_topicName(const char ∗ topicName) {

3 int ret = 0;

4 if(topic_count < (MAX_TOPICS −1))

5 {

6 //variables

7 uint16_t topicnamelen = strlen(topicName);

8 uint16_t packetlen = topicnamelen+6;

10 //allocate packet memory and increase msg id count

11 mqttsn_send_buffer =

12 ( uint8_t ∗)malloc(packetlen ∗sizeof(uint8_t));

13 memset(mqttsn_send_buffer, 0, packetlen);

14 msg_id ++;

16 //store topic name

17 topic_table[topic_count].name = topicName;

18 topic_table[topic_count].id = 0;

20 //header

21 mqttsn_send_buffer[0] = packetlen;

22 mqttsn_send_buffer[1] = MQTTSN_TYPE_REGISTER;

23 //variable −part

24 mqttsn_send_buffer[2] = 0x00;

25 mqttsn_send_buffer[3] = 0x00;

26 mqttsn_send_buffer[4] = (msg_id)>>8;

27 mqttsn_send_buffer[5] = (msg_id)&(0xFF);

28 memcpy(mqttsn_send_buffer+6, topicName, topicnamelen);

30 // send message

31 ret =

32 WaspMqttSN::send_packet(packetlen, MQTTSN_TYPE_REGISTER);

33 }

34 else {

35 fprintf(stderr,

36 "Error, no free space to store more topics.\n"); 142 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

37 ret = −2;

38 }

39 return ret ;

40 }

42 /∗ FUNCTIONTORECEIVEREGACKMESSAGE ∗/

43 int WaspMqttSN::recv_regack() {

44 // receive message

45 int ret = WaspMqttSN::recv_packet(REGACK_SIZE,

46 MQTTSN_TYPE_REGACK);

47 if( ret > 0) {

48 // check msg_id

49 if( (msg_id>>8 != mqttsn_recv_buffer[4]) ||

50 ((msg_id&(0xFF)) != mqttsn_recv_buffer[5]) ) {

51 if( debug )

52 USB.println("recv_regack(): Wrong message id.");

53 ret = −1;

54 }

55 // check return code

56 else if(mqttsn_recv_buffer[6] == REJECTED_INVALID_TOPIC_ID) {

57 USB.println("Error, rejected invalid topic id.\n");

58 ret = −2;

59 }

60 // update topic_table

61 else if(mqttsn_recv_buffer[6] == ACCEPTED) {

62 uint16_t idMSB = (uint16_t)mqttsn_recv_buffer[2];

63 uint16_t idLSB = (uint16_t)mqttsn_recv_buffer[3];

64 topic_table[topic_count].id = (idMSB<<8)|(idLSB);

65 topic_count++;

66 }

67 }

69 // free allocated mem

70 free(mqttsn_recv_buffer);

71 mqttsn_recv_buffer=NULL;

73 return ret ;

74 }

Listado 5.22: Código de las funciones de la librería del escenario REGISTER

En el Listado 5.23 pueden verse las dos funciones que se encargan de manejar la llegada de un mensaje register a la pasarela. En cuanto al manejador, su función es obtener el Topic Name que quiere registrarse, darle un identificador, almacenar esta relación en el espacio del cliente, y llamar a la función que envía el mensaje REGACK, la cual formará el mensaje correctamente y lo enviará utilizando la MAC del cliente. 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 143

Es importante mencionar la forma en que la pasarela almacena los registros de topics. Siguiendo las pautas que vienen en las «Notas de implementación» de la especifica- ción de MQTT-SN (véase Sección 5.5.1), se ha implementado un mecanismo para que la pasarela mantenga la lista de topics de cada cliente, aislada de la del resto. Para ello se mantienen dos mapas, uno de ellos almacena una lista de los topics (id-name) regis- trados por cada cliente (localmap), y otro almacena una lista con todos los clientes y su mapa local (globalmap). De forma que cuando se quiere registrar un nuevo topic, se consulta el mapa del cliente que este pidiendo el registro, y si hay espacio disponible, se añade una entrada más.

1 /∗ FUNCTIONTOHANDLEREGISTERMESSAGE ∗/

2 void register_handler(char ∗ mqttsn , char ∗ mac ) {

3 // variables

4 char ∗ offset = mqttsn;

5 uint8_t retCode = REJECTED_INVALID_TOPIC_ID;

6 uint8_t topic_id;

8 // obtain topic name

9 int topicnamelen = mqttsn[0] − 6;

10 char ∗ topicName = (char∗)malloc((topicnamelen+1)∗sizeof(char));

11 memset(topicName, 0, topicnamelen);

12 memcpy(topicName, offset+6, topicnamelen);

13 topicName[topicnamelen] = ’\0’;

15 // store topic in map

16 topic_id = store_topicId(topicName, mac);

18 if(topic_id != −1) {

19 retCode = ACCEPTED;

20 topic_id_count++;

21 }

23 // free allocated mem

24 free(topicName);

25 topicName = NULL;

27 // send regack

28 send_regack(topic_id, mqttsn[4], mqttsn[5], retCode, mac);

29 }

31 /∗ FUNCTIONTOSENDREGACKMESSAGE ∗/

32 void send_regack(uint16_t topic_id, uint8_t msg_idMSB,

33 uint8_t msg_idLSB, uint8_t return_code,

34 const char ∗ mac ) {

35 // set character buffer to make regack msg

36 char buf [7]; 144 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

37 buf[0] = 0x37;

38 buf[1] = MQTTSN_TYPE_REGACK;

39 buf[2] = topic_id>>8;

40 buf[3] = topic_id&(0xFF);

41 buf[4] = msg_idMSB;

42 buf[5] = msg_idLSB;

43 buf[6] = return_code;

45 // send regack using mac

46 send_byMac(mac, buf);

47 }

Listado 5.23: Código de las funciones de la pasarela del escenario REGISTER

Escenario PUBLISH Este escenario representa la tercera iteración del proceso de desarrollo, se le aplica el algoritmo de TDD:

1. Escribir la especificación del requisito (el test): El requisito que debe cumplirse en este escenario viene especificado por el test del Lis- tado 5.24. En la descripción del escenario proporcionada en esta sección, se introdujo

que se implementarían las publicaciones para cualquier nivel de QOS, y así ha sido, pero por brevedad tan solo se van a exponer dos, para los niveles 1 y -1. Ya que se consideran los más representativos, el nivel 0 es igual que el 1, pero sin esperar acuse de recibo y el nivel 2 es igual que el 1, pero con un intercambio más de confirmaciones

1 /∗ Test Publish Scenary ∗/

2 uint8_t dup = 0;

3 uint8_t retain = 0;

4 int topicId = 1;//pre −defined topic id

6 void test_publish() {

7 int ret = −1, resCon, resCack, resPub, resPack;

8 uint8_t qos = 1;

10 // connect to mosquitto

11 resCon = mqttSN.connect();

12 if (resCon == 1)

13 USB.println("−−−− connect send");

14 //wait for ack

15 resCack = mqttSN.recv_connack();

16 if (resCack == 1)

17 USB.println("−−−− connack received");

19 // small delay 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 145

20 delay(1000);

22 // publish toa pre −defined topic

23 resPub = mqttSN.publish(topicId, MQTTSN_TOPIC_TYPE_PREDEFINED,

24 "Hello World from Waspmote",

25 qos, dup, retain);

26 if(resPub == 1)

27 USB.println("−−−− publish send");

28 // wait for ack

29 if( qos == 1) {

30 resPack = mqttSN.recv_puback();

31 if(resPack == 1)

32 USB.println("−−−− puback received");

33 }

35 // check results

36 if (resCon && resCack && resPub)

37 ret = 1;

39 if( ret == 1)

40 USB.println("All Test Passed!!");

41 else

42 USB.println("Test Fail!!");

44 delay(1000);

45 }

47 void test_publish_m1() {

48 int ret = −1, resPub ;

49 uint8_t qos = −1;

51 // publish toa pre −defined topic

52 resPub = mqttSN.publish(topicId, MQTTSN_TOPIC_TYPE_PREDEFINED,

53 "Hello World from Waspmote, QoS−1",

54 qos, dup, retain);

55 if(resPub == 1)

56 USB.println("−−−− publish send");

58 // small delay

59 delay(1000);

61 // check results

62 if ( resPub )

63 ret = 1;

65 if( ret == 1)

66 USB.println("All Test Passed!!"); 146 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

67 else

68 USB.println("Test Failed!!");

70 delay(1000);

71 }

Listado 5.24: Test del escenario PUBLISH

2. Implementar el código según dicho test: Para superar este test debe escribirse el siguiente código: • Función de la librería MQTT-SN para enviar el mensaje PUBLISH y PUBREL. Y las funciones para recibir los mensajes PUBACK, PUBREC Y PUBCOMP. • Parte correspondiente a la traducción MQTT-SN → MQTT de la función mqt- tsn2mqtt() de la pasarela transparente. • Parte correspondiente a la traducción MQTT → MQTT-SN de la pasarela trans- parente (función mqtt2mqttsn()), para traducir los mensajes de respuesta que en- víe Mosquitto. Siguiendo la metodología, primero debe escribirse un código básico, que pase los test, apuntando las dudas que surjan y las posibles mejoras, para mejorar el código en la etapa de refactorización. 3. Refactorización: Tras las sucesivas etapas de refactorización (en las que se mejora una parte del código escrito y se ejecutan los test), se obtiene todo el código de este escenario. En el Listado 5.25 pueden verse la función de envío del mensaje PUBLISH y de re- cepción del mensaje PUBACK. De nuevo se omiten los códigos de las funciones PU- BREL, PUBREC y PUBCOMP, por ser muy similares a las expuestas en este listado. Como puede observarse, la función implementada sirve para enviar cualquier tipo de publicación que soporta el protocolo.

1 /∗ FUNCTIONTOSENDPUBLISHMESSAGE ∗/

2 int WaspMqttSN::publish(uint16_t topicId, uint8_t topicType,

3 const char ∗msg, uint8_t qos,

4 uint8_t dup, uint8_t retain) {

5 // variables

6 uint16_t msglen = strlen(msg);

7 uint16_t packetlen = 7+msglen;

9 // allocate packet mem

10 mqttsn_send_buffer =

11 ( uint8_t ∗)malloc(packetlen ∗sizeof(uint8_t));

12 memset(mqttsn_send_buffer, 0, packetlen);

13 msg_id ++; 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 147

15 //set flags

16 uint8_t flags = topicType;

17 if( dup )

18 flags |= MQTTSN_FLAG_DUP;

19 if( retain )

20 flags |= MQTTSN_FLAG_RETAIN;

21 if(! qos )

22 flags |= MQTTSN_FLAG_QoS0;

23 else if( qos ==1)

24 flags |= MQTTSN_FLAG_QoS1;

25 else if( qos ==2)

26 flags |= MQTTSN_FLAG_QoS2;

27 else

28 flags |= MQTTSN_FLAG_QoSm1;

30 // set header

31 mqttsn_send_buffer[0] = packetlen;

32 mqttsn_send_buffer[1] = MQTTSN_TYPE_PUBLISH;

33 //set variable −part

34 mqttsn_send_buffer[2] = flags;

35 mqttsn_send_buffer[3] = (topicId)>>8;

36 mqttsn_send_buffer[4] = (topicId)&(0xFF);

37 mqttsn_send_buffer[5] = (msg_id)>>8;

38 mqttsn_send_buffer[6] = (msg_id)&(0xFF);

39 memcpy(mqttsn_send_buffer+7, msg, msglen);

41 // send message

42 return WaspMqttSN::send_packet(packetlen,

43 MQTTSN_TYPE_PUBLISH);

44 }

46 /∗ FUNCTIONTORECEIVEPUBACKMESSAGE ∗/

47 int WaspMqttSN::recv_puback() {

48 // receive packet

49 int ret = WaspMqttSN::recv_packet(PUBACK_SIZE,

50 MQTTSN_TYPE_PUBACK);

51 if( ret > 0) {

52 // check msg id

53 if( (msg_id>>8 != mqttsn_recv_buffer[4]) ||

54 ((msg_id&(0xFF)) != mqttsn_recv_buffer[5]) ) {

55 if( debug )

56 USB.println("recv_puback(): Wrong message id");

57 ret = −1;

58 }

59 else {

60 // check return code 148 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

61 if(mqttsn_recv_buffer[6] == ACCEPTED)

62 if( debug )

63 USB.printf("Puback received");

64 ret = 1;

65 }

66 }

68 // free allocated mem

69 free(mqttsn_recv_buffer);

70 mqttsn_recv_buffer=NULL;

72 return ret ;

73 }

Listado 5.25: Código de las funciones del escenario PUBLISH

En el Listado 5.26 pueden verse las dos partes en la que se realiza la traducción entre

protocolos. En este código toma especial interés la implementación del nivel de QOS -1, realizado en la función mqttsn2mqtt(). En este caso el cliente MQTT-SN se des- preocupa por completo de la calidad de la publicación y la pasarela debe gestionar por completo la conexión con Mosquitto.

La primera parte de la traducción se encarga de: (i) obtener el valor de los campos qos, dup y retain, (ii) de obtener el contenido del mensaje a publicar y (iii) obtener el topic name en el que se publicará. La segunda parte de la traducción consiste en evaluar la

QOS requerida y actuar consecuentemente.

Otro de los procedimientos importantes de esta traducción, es la llamada a la función process_topicIDType(), que se encarga de devolver una cadena de caracteres que re- presenta el topic name al que hay que enviar la publicación. El proceso interno de esta función se encarga de obtener el Topic Id contenido en el mensaje MQTT-SN, y tras analizarlo, consultar el mapa de topics del cliente, para así obtener el correspondiente Topic Name.

Por su parte, las funciones de traducción MQTT → MQTT-SN, se encargan de formar los correspondientes acuses de recibo y enviarlos al cliente utilizando su MAC.

1 /∗ Code inside mqttsn2mqtt() function

2 ∗ −− res variable is an integer ∗/

3 case MQTTSN_TYPE_PUBLISH:

4 {

5 // variables

6 offset = mqttsn;

7 uint8_t qos = mqttsn[2]&(0x60);

8 uint8_t dup = (mqttsn[2]&(MQTTSN_FLAG_DUP))>>8;

9 uint8_t retain = (mqttsn[2]&(MQTTSN_FLAG_RETAIN))>>4; 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 149

10 char ∗ topicName ;

12 //obtain the msg data

13 int msglen = mqttsn[0] − 7;

14 char ∗ msg = (char∗)malloc((msglen+1)∗sizeof(char));

15 memset(msg, 0, msglen);

16 memcpy(msg, offset+7, msglen);

17 msg[msglen] = ’\0’;

19 // obtain topic name

20 topicName = process_topicIdType(mqttsn, mac, msgtype);

22 if(qos == MQTTSN_FLAG_QoSm1) {

23 qos = 0;

24 // init mqtt connection

25 res = mqtt_send_connect(broker);

26 res = mqtt_recv_connack(broker);

27 // send publish

28 res = mqtt_send_publish(broker, topicName, msg, qos,

29 dup, retain);

30 // disconnect and close

31 res = mqtt_send_disconnect(broker);

32 close(broker −>sockfd );

33 }

34 else {

35 if(qos == MQTTSN_FLAG_QoS0) qos = 0;

36 else if(qos == MQTTSN_FLAG_QoS1) qos = 1;

37 else if(qos == MQTTSN_FLAG_QoS2) qos = 2;

38 // only send publish

39 res = mqtt_send_publish(broker, topicName, msg, qos,

40 dup, retain);

41 }

43 // free allocated mem

44 free ( msg );

45 msg = NULL ;

46 break;

47 }

49 case MQTTSN_TYPE_PUBREL:

50 {

51 // send pubrel

52 res = mqtt_send_pubrel(broker);

53 break;

54 }

56 /∗ Code inside mqtt2mqttsn() function 150 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

57 ∗ −− buf isa character array ∗/

58 case MQTT_TYPE_PUBACK:

59 {

60 // set character buffer to make puback msg

61 buf = (char∗)malloc(PUBACK_SIZE ∗sizeof(char));

62 buf[0] = 0x37;

63 buf[1] = MQTTSN_TYPE_PUBACK;

64 buf[2] = 0x1e;

65 buf[3] = 0x1e;

66 buf[4] = mqtt_recv_buffer[2];

67 buf[5] = mqtt_recv_buffer[3];

68 buf[6] = ACCEPTED;

70 len = PUBACK_SIZE;

71 bufAllocated = 1;

72 break;

73 }

75 case MQTT_TYPE_PUBREC:

76 {

77 // set character buffer to make pubrec msg

78 buf = (char∗)malloc(PUBREC_SIZE ∗sizeof(char));

79 buf[0] = 0x34;

80 buf[1] = MQTTSN_TYPE_PUBREC;

81 buf[2] = mqtt_recv_buffer[2];

82 buf[3] = mqtt_recv_buffer[3];

84 len = PUBREC_SIZE;

85 bufAllocated = 1;

86 break;

87 }

89 case MQTT_TYPE_PUBCOMP:

90 {

91 // set character buffer to make pubcomp msg

92 buf = (char∗)malloc(PUBCOMP_SIZE ∗sizeof(char));

93 buf[0] = 0x34;

94 buf[1] = MQTTSN_TYPE_PUBCOMP;

95 buf[2] = mqtt_recv_buffer[2];

96 buf[3] = mqtt_recv_buffer[3];

98 len = PUBCOMP_SIZE;

99 bufAllocated = 1;

100 break;

101 }

Listado 5.26: Código de las partes de traducción del escenario PUBLISH 5.5. ETAPA 5: LIBRERÍA MQTT-SN Y EL SOFTWARE DE TRADUCCIÓN 151

Escenario PING Este escenario representa la cuarta iteración del proceso de desarrollo, se le aplica el algo- ritmo de TDD:

1. Escribir la especificación del requisito (el test):

El requisito que debe cumplirse en este escenario viene especificado por el test del Listado 5.27.

1 void test_ping() {

2 int ret = −1, resCon, resCack, resPing, resPingAck;

4 // connect to mosquitto

5 resCon = mqttSN.connect();

6 if (resCon == 1)

7 USB.println("−−−− connect send");

8 // wait for ack

9 resCack = mqttSN.recv_connack();

10 if (resCack == 1)

11 USB.println("−−−− connack received");

12 // send ping

13 resPing = mqttSN.pinreq();

14 if (resPing == 1)

15 USB.println("−−− ping send");

16 // wait for pingresp

17 resPingAck = mqttSN.recv_ping();

18 if (resPingAck == 1)

19 USB.println("−−− ping received")

21 // small delay

22 delay(1000);

24 // check results

25 if(resCon && resCack && resPing && resPingAck)

26 ret = 1;

28 if( ret == 1)

29 USB.println("All Test Passed!!");

30 else

31 USB.println("Test Fail!!");

33 delay(5000);

34 }

Listado 5.27: Test del escenario PING

2. Implementar el código según dicho test: 152 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

Para superar este test debe escribirse el siguiente código: • Función de la librería MQTT-SN para enviar el mensaje PINGREQ. Y la función para recibir el mensaje PINGRESP. • Parte correspondiente a la traducción MQTT-SN → MQTT de la función mqt- tsn2mqtt() de la pasarela transparente. • Parte correspondiente a la traducción MQTT → MQTT-SN de la pasarela trans- parente (función mqtt2mqttsn()), para traducir el ping de respuesta que envíe Mosquitto. Siguiendo la metodología, primero debe escribirse un código básico, que pase los test, apuntando las dudas que surjan y las posibles mejoras, para mejorar el código en la etapa de refactorización. 3. Refactorización: Tras las sucesivas etapas de refactorización (en las que se mejora una parte del código escrito y se ejecutan los test), se obtiene todo el código de este escenario. En el Listado 5.28 pueden verse las funciones de envío del mensaje PINGREQ y de recepción de PINGRESP.

1 /∗ FUNCTIONTOSENDPINGMESSAGE ∗/

2 int WaspMqttSN::pingreq() {

3 // variables

4 uint8_t packetlen = 2;

5 // allocate packet memory

6 mqttsn_send_buffer =

7 ( uint8_t ∗)malloc(packetlen ∗sizeof(uint8_t));

8 memset(mqttsn_send_buffer, 0, packetlen);

10 //header

11 mqttsn_send_buffer[0] = packetlen;

12 mqttsn_send_buffer[1] = MQTTSN_TYPE_PINGREQ;

14 // send packet

15 return WaspMqttSN::send_packet(packetlen,

16 MQTTSN_TYPE_PINGREQ);

17 }

19 /∗ FUNCTIONTORECEIVEPINGRESPMESSAGE ∗/

20 int WaspMqttSN::recv_ping() {

21 // receive packet

22 int ret = WaspMqttSN::recv_packet(PING_SIZE, MQTTSN_TYPE_PINGRESP);

23 if( ret > 0) {

24 ret = 1;

25 } 5.6. ETAPA 6: SUSCRIPTORES EXTERNOS 153

27 // free allocated mem

28 free(mqttsn_recv_buffer);

29 mqttsn_recv_buffer=NULL;

31 return ret ;

32 }

Listado 5.28: Código de las funciones del escenario PING

En el Listado 5.29 pueden verse las dos partes en las que se realiza la traducción entre protocolos.

1 /∗ Code inside mqttsn2mqtt() function

2 ∗ −− res variable is an integer ∗/

3 case MQTTSN_TYPE_PINGREQ:

4 {

5 res = mqtt_send_ping(broker);

6 break;

7 }

9 /∗ Code inside mqtt2mqttsn() function

10 ∗ −− buf isa character array ∗/

11 case MQTT_TYPE_PINGRESP:

12 {

13 buf = (char∗)malloc(PING_SIZE ∗sizeof(char));

14 buf[0] = 0x32;

15 buf[1] = MQTTSN_TYPE_PINGRESP;

17 len = PING_SIZE;

18 bufAllocated = 1;

19 break;

20 }

Listado 5.29: Código de las partes de traducción del escenario PING

Una vez concluidas todas las iteraciones, quedan implementadas y testeadas, todas las funcionalidades de la librería MQTT-SN y del software de traducción. Además, a pesar de que la librería MQTT se desarrolló por separado y ya estaba completamente testeada, los es- cenarios planteados para esta etapa del desarrollo del proyecto, han demostrado su completa adhesión a la infraestructura. Comprobando el correcto funcionamiento de la misma.

Con esta etapa se concluye el desarrollo de la librería MQTT-SN y de la pasarela transpa- rente. 154 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

5.6 Etapa 6: Suscriptores externos Una vez finalizadas las etapas 1 a 5, se dispone de una infraestructura de comunicación que permite a los dispositivos de una red de sensores de la empresa Libelium, publicar informa- ción de su entorno a un broker MQTT, situado en una red externa (a la red de sensores).

El objetivo de esta etapa, es desarrollar un mecanismo que muestre un procedimiento me- diante el cual, cualquier dispositivo situado en una red externa a la infraestructura, pueda suscribirse a los canales de comunicación en los que publican los sensores, y recibir la in- formación cuando el broker la distribuya. Con lo que se conseguirá comprobar el correcto funcionamiento de la infraestructura desarrollada, en un escenario real.

El escenario que se plantea, es la visualización de la posición geográfica de sensores co- locados cerca de la Escuela Superior de Informática de Ciudad Real. Estos publicaran sus coordenadas siguiendo el procedimiento de publicación de eventos MQTT-SN, los cuales llegarán hasta el broker Mosquitto, a través de la infraestructura, y este los distribuirá a los suscriptores. En este caso tan solo se tiene un suscriptor, situado en un navegador web, que actualiza un mapa cuando recibe una publicación.

Para que la solución sea multiplataforma se han utilizado tecnologías web, en concreto JavaScript, NodeJS y HTML. Se pretende conseguir que cualquier dispositivo, tanto fijo como móvil, pueda acceder a la información que publican los sensores, a través de un navegador web. Para ello se ha creado:

Un archivo HTML (Civitas.html).

La función de este archivo es hacer que el navegador cliente que ha realizado la peti- ción, se suscriba a determinados topics MQTT, en los que los sensores publicarán in- formación. Esta información serán coordenadas, que representarán la posición actual del sensor en cuestión. Cuando el navegador reciba publicaciones con esta informa- ción, colocará una etiqueta en un mapa, indicando la localización del sensor.

Un servidor NodeJS que realiza tres acciones:

1. Se mantiene a la espera de peticiones HTTP (en cualquier dirección de red, en el puerto 3000), sirviendo en cada caso el archivo que requiera la petición (por defecto el archivo Civitas.html) o mostrando error si el archivo no se encuentra en el servidor. 2. Crea un cliente MQTT que se conecta a Mosquitto. Su función es suscribirse al topic que le indique el suscriptor externo (desde el navegador web). 3. Abre un socket y se mantiene a la espera de conexiones por parte del navegador cliente (en cualquier dirección y en el puerto 5000). Cuando recibe una conexión, se mantiene a la espera de una suscripción por parte del cliente, que enviará después a Mosquitto. 5.6. ETAPA 6: SUSCRIPTORES EXTERNOS 155

Figura 5.16: Mecanismo creado para la realización de los suscriptores externos.

De esta forma, es el propio servidor NodeJS el que está suscrito a determinados topics de Mosquitto, y es él, el que distribuye las publicaciones cuando Mosquitto se las envía (véase Figura 5.16).

Con este mecanismo se consigue demostrar que la infraestructura que se ha desarrollado realiza sus funciones de forma correcta, en un escenario real. Ya que representa un uso com- pleto de todas sus partes: MQTT-SN, MQTT, pasarela transparente y Mosquitto. En la Figura 5.17 puede verse el resultado final obtenido tras la ejecución, para ello han sido necesarias las siguientes acciones:

Establecimiento de la red de sensores Waspmote-Meshlium. Conexión de Meshlium a la red TCP/IP en la que se encuentra el ordenador de Civitas con Mosquitto configurado y en ejecución. Puesta en marcha del servidor NodeJS. Realizar la petición del archivo Civitas.html desde un navegador en una red externa. Elaborar un código para los sensores, utilizando la librería MQTT-SN implementada, para que publiquen sus coordenadas a un topic o canal de eventos. Poner en ejecución este código, lo que genera un intercambio de mensajes entre sensor- pasarela-Mosquitto que demuestra: 156 CAPÍTULO 5. ARQUITECTURA Y DESARROLLO

• El correcto funcionamiento de la librería MQTT-SN implementada. • El correcto funcionamiento del código de la pasarela transparente, tanto su pro- cedimiento de servidor (a la hora de registrar topics, aunque es opcional en este caso) como de traductor. • El correcto funcionamiento de la librería MQTT implementada. Distribución de publicaciones desde Mosquitto a los suscriptores. Visualización de los resultados en el mapa del navegador.

Figura 5.17: Visualización de las coordenadas publicadas por los sensores.

Para realizar el código necesario para manejar el protocolo MQTT tanto en el archivo HTML como en el servidor NodeJS, se ha utilizado la librería MQTT.js7. Para el uso de mapas se ha utilizado la API de JavaScript de Google Maps8.

7https://github.com/adamvr/MQTT.js 8https://developers.google.com/maps/documentation/javascript/?hl=es Capítulo 6 Resultados

N este capítulo se van a exponer los resultados obtenidos tras finalizar el proceso de E desarrollo de este TFG. Primero se resume de forma breve la infraestructura de co- municación que se ha desarrollado, pues es el resultado principal. Después se exponen cada una de sus partes, ya que todas ellas pueden ser usadas de forma independiente, con otros fines. Acto seguido, se realiza una breve descripción del repositorio de software en el que se haya todo el código desarrollado y la documentación generada. Se sigue con una estimación de los costes del proyecto y por último, se introduce otro de los resultados del proyecto, la publicación de un artículo en el marco de las Smart Cities.

6.1 Infraestructura de comunicación El proceso de desarrollo llevado a cabo, y expuesto a lo largo del Capítulo 5, ha dado como resultado el cumplimiento de todos los objetivos que inicialmente se establecieron para este proyecto.

Tras la finalización de todas las implementaciones, se dispone de una infraestructura de co- municación basada en la publicación/suscripción de eventos, para el IOT. Que permite poner a disponibilidad de los distintos consumidores, la información que publican los dispositivos de una red de sensores (véase Figura 6.1).

Además, como se ha podido comprobar en la Sección 5.6, la infraestructura ha sido tes- teada bajo un escenario real, obteniendo resultados satisfactorios. Este hecho, junto con la cobertura de pruebas que se obtiene como parte del proceso del desarrollo de TDD, hace que se haya generado una infraestructura completamente funcional.

Por otro lado, algunas de las partes que componen esta infraestructura pueden ser usadas de forma independiente fuera de ella, pudiéndose considerar de esta forma, como resultados adicionales del proyecto. Estas partes son:

Librería MQTT:

Esta librería se considera como otro de los resultados del proyecto, ya que puede ser utilizada de forma independiente a la infraestructura. Con ella puede crearse cualquier tipo de cliente MQTT, exceptuando el uso de la característica last will and testament.

157 158 CAPÍTULO 6. RESULTADOS

Figura 6.1: Arquitectura y componentes de la infraestructura. Fuente: elaboración propia.

Puede verse su manual de usuario en el Anexo A. Librería MQTT-SN: Esta librería también se considera como otro resultado del proyecto, ya que también puede utilizarse de forma independiente a la infraestructura, aunque en este caso con más limitaciones, ya que tan solo está preparada para ejecutarse sobre dispositivos Waspmote de la empresa Libelium. Puede verse su manual de usuario en el Anexo B. Pasarela transparente: El software que forma la pasarela transparente también puede considerarse como una entidad independiente. En este caso, encargada de traducir paquetes MQTT-SN en MQTT, y viceversa. Este software puede ser portado a cualquier sistema de este tipo, sin la necesidad de realizar grandes cambios en él, tan solo habría que modificar el uso de una u otra librería para el envío/recepción de paquetes, en función de la que elija usarse. Clientes MQTT: Como se explica en el Anexo A, una de las partes de la librería MQTT, son dos clien- tes: publicador y suscriptor. Los cuales pueden ser usados de forma completamente independiente a la infraestructura desarrollada, para cualquier finalidad que implique la publicación/suscripción de eventos MQTT. 6.2. REPOSITORIO 159

El código de la infraestructura completa, así como de todas sus partes, esta disponible en: https://rober [email protected]/rober botto/tfg.git

Bajo la licencia de uso GNUGPL.

6.2 Repositorio Todo el código realizado durante el desarrollo del proyecto (infraestructura, librerías, test, clientes, etc.), junto con los archivos para generar toda la documentación asociada, están disponibles en un repositorio público de bitbucket.org1.

Para descargar el repositorio completo, puede ejecutarse el comando:

$ git clone https://[email protected]/rober_botto/tfg.git

La organización de este repositorio es la siguiente:

anteproyecto: contiene los archivos para generar el documento que representa el Ante- proyecto previamente aprobado al desarrollo de este TFG.

proyecto: contiene los archivos para generar la memoria del proyecto.

code: contiene todo el código fuente de la infraestructura desarrollada. Se organiza como sigue:

• gateway: contiene el código fuente de la pasarela transparente (dentro de src/) y un archivo Makefile para compilarlo. • mqtt: contiene el código fuente de la librería MQTT, independiente de la pasa- rela transparente. En src/ se encuentra la librería y los test unitarios, y en client/ los clientes MQTT implementados. También dispone de archivo Makefile para compilar. • mqtt-sn: contiene el código fuente de la librería MQTT-SN y de los test creados para sus pruebas. • server: contiene el código fuente del servidor NodeJS utilizado para soportar suscriptores externos multiplataforma.

En el Cuadro 6.1 puede verse una comparación de las lineas de código implementadas para construir la infraestructura, organizadas según la parte a la que pertenecen.

6.3 Coste del proyecto

En esta sección se exponen los costes que lleva asociados este TFG, para ello se presentan agrupados según su procedencia, ya sea hardware, software o mano de obra.

1https://bitbucket.org/ 160 CAPÍTULO 6. RESULTADOS

Componente Lenguaje Lineas Librería MQTT-SN C/C++ 874 Pararela transparente C/C++ 1188 Librería MQTT C/C++ 935 Suscriptores externos JavaScript/HTML 130

Cuadro 6.1: Lineas de código implementadas por componentes de la infraestructura.

6.3.1 Coste hardware Como se especificó en la Sección 4.3.1, las herramientas hardware utilizadas para este proyecto han sido: un ordenador de sobremesa, un ordenador portátil, una placa sensora (contenida en el Kit de Evaluación de Libelium) y una pasarela, ambos de la empresa Libe- lium. En el Cuadro 6.2 puede verse el desglose de los gastos que ha supuesto la adquisición de estos elementos. Elemento Coste HP Envy 1400e HP ProBook 4510s 600e Kit de Evaluación de Libelium (University Lab Kit) 2500e Pasarela Meshlium 895e Total 5395e Cuadro 6.2: Costes Hardware.

6.3.2 Coste software Como puede observarse en la Sección 4.3.2, todo el software que se ha utilizado para desarrollar este proyecto, es software libre. Con lo cual, supone un coste cero en cuanto a cuestiones de licencias o adquisición de software privativo específico.

6.3.3 Coste de la mano de obra Para calcular el coste que ha supuesto la mano de obra, se han dividido los esfuerzos realizados en dos partes. Por un lado, los esfuerzos de implementación, y por otro, los de documentación. Como se indica en la Sección 4.2, la implementación del proyecto comienza la segunda semana de Enero de 2014, y se alarga hasta la última semana de Junio. Lo que arroja un total de 22 semanas aproximadamente, durante las cuales se dedicó una media de 4 horas al día, debido al solapamiento en el tiempo del desarrollo del proyecto con las últimas asignaturas de la carrera. La documentación del proyecto ha tenido lugar desde la última semana de Junio de 2014 (fecha de fin de implementación), hasta el día 26 de Agosto de 2014 (tercera semana del mes). Arrojando un total de 9 semanas aproximadamente, durante las cuales se ha dedicado una media de 8 horas al día. 6.4. PUBLICACIÓN 161

En el Cuadro 6.3 se muestran los costes asociados a la mano de obra necesaria para la realización del proyecto, teniendo en cuenta que cada hora de trabajo se cobrase a 50e. En el Cuadro 6.4 se muestran todos los costes del proyecto.

Jornada Semanas Horas/semana Coste Media 22 20 22.000 e Completa 9 40 18.000 e Total 40.000e Cuadro 6.3: Costes de la mano de obra.

Procedencia Coste Hardware 5395e Software 0e Mano de obra 40.000e Total 45.395e Cuadro 6.4: Coste total del proyecto

6.4 Publicación Uno de los ámbitos de este proyecto son las Smart Cities, en concreto las etapas de reco- lección y transmisión de información. Como muestra de ello, uno de los resultados obtenidos es la publicación del artículo Implementing a Holistic Approach for the Smart City en The 2014 IEEE/WIC/ACM International Conference on Intelligent Agent Technology, celebrado en Varsovia del 11 al 14 de Agosto de 2014. Este artículo propone soluciones concretas para poder llevar a cabo una fácil implementa- ción e integración de nuevos dispositivos y servicios en la Smart City, en concreto propone abordar esta tarea mediante la realización de abstracciones entre los distintos estándares y protocolos que forman parte de una Smart City, a través del empleo de un middleware, para hacer posible el uso de estos servicios de forma independiente a las tecnologías subyacen- tes. La realización de este proyecto ha servido como base a la redacción de la sección 3.2 del mencionado artículo, en la que se trata la integración de esta infraestructura como parte de la capa ICT Infraestructure de Civitas.

Capítulo 7 Conclusiones y propuestas

L objetivo general del proyecto, implementar una infraestructura basada en la publica- E ción/suscripción de eventos para el IOT, ha sido llevado a cabo a partir del desarrollo de los distintos objetivos específicos identificados en el Capítulo 2. Cada uno de ellos, ha supuesto avanzar en el proceso de desarrollo, aportando resultados e implementaciones que después se han utilizado conjuntamente para formar la infraestructura.

Este capítulo se divide en tres partes, la primera de ellas muestra las conclusiones ob- tenidas tras los esfuerzos de implementación realizados durante el trascurso del proyecto, organizadas según las distintas partes que se han desarrollado para cumplir con los objetivos específicos. La segunda parte expone posibles propuestas que pueden llevarse a cabo para mejorar y ampliar la infraestructura, enfocadas en su mayoría a añadir nuevas caracterís- ticas a la infraestructura para hacerla más completa. Y por último, la tercera, muestra las conclusiones personales del autor, obtenidas tras la realización de esta memoria.

7.1 Conclusiones

Como primera tarea en el proceso de desarrollo de este TFG, se realizó un despliegue mínimo de la plataforma sensora sobre la que posteriormente se implementaría la mayor parte del software. En este ámbito, la documentación que Libelium tiene disponible para sus productos, fue clave. A partir de una lectura detallada de [Lib13a], [Lib13b], [Lib14a], [Lib13d] y de algunas secciones de [Lib14c] se obtuvieron los conocimientos necesarios para desplegar dicha plataforma (véase Sección 5.1).

Esta etapa fue complicada, debido a que el comportamiento que requiere la infraestruc- tura, difiere del comportamiento que Libelium plantea para las redes desplegadas con sus productos, con lo cual no todo estaba documentado y se tomaron ciertas decisiones cuyos resultados no estaban, a priori, garantizados. Por otra parte, Libelium no realiza una actua- lización inmediata de sus documentos cuando salen nuevas versiones del software de sus productos, como nuevas versiones del software de Meshlium, y en ocasiones fue necesario consultar y añadir hilos en su foro de ayuda, con el fin de obtener esta información, hecho que retrasó el tiempo de realización de esta etapa.

El siguiente paso en el proceso de desarrollo, trató la implementación de la librería

163 164 CAPÍTULO 7. CONCLUSIONES Y PROPUESTAS

MQTT, que posteriormente sería usada como parte del proceso de traducción de protocolos, y que además como ya se ha mencionado, constituye una librería independiente que puede ser usada para crear clientes MQTT (véase Anexo A). Tras finalizar esta fase de implementación, puede concluirse que:

Mosquitto es un broker MQTT muy eficiente, capaz de soportar un gran número de clientes conectados sin apenas consumir recursos de la máquina. Además, su configu- ración es sencilla, permitiendo en pocos pasos: dotar a MQTT de comunicación segura entre máquinas, establecer una red de brokers para mayor escalabilidad, control de ac- ceso a topics por cliente, etc. MQTT, por sus características y principios de diseño, cumple con los requisitos que

requiere una infraestructura para el IOT.

Tras la implementación de esta librería, se dispuso a crear la estructura principal del soft- ware de la pasarela transparente, realizando toda la lógica de servidor y preparándola para interpretar mensajes MQTT-SN de los sensores. Esta fase tuvo una duración larga en compa- ración con el resto de implementaciones, debido a los problemas surgidos durante el proceso de lectura de un paquete 802.15.4 entrante, que se solucionaron con la máquina de estados vista en la Sección 5.4.1. De este proceso se obtienen las siguientes conclusiones:

Por el tipo de acciones que tiene que realizar, la pasarela debe implementar un servidor monoproceso, manteniéndose a la espera de peticiones y procesándolas en un periodo de tiempo corto. Dentro de la infraestructura, el código de la pasarela es la pieza más importante, ya que actúa de puente entre los dos tipos de redes. Este código debe de estar ejecutándose durante periodos largos de tiempo y tiene que ser capaz de gestionar las conexiones de los clientes sin colapsarse. Esto significa:

• Cuando un cliente se conecta, debe de crear e inicializar las estructuras de datos necesarias para almacenar su información, sin que entre en conflicto con la del resto de clientes. • Cuando un cliente se desconecta, debe de limpiar toda su información, para que la pasarela no almacene basura que con el tiempo colapsaría el sistema.

Debido al desarrollo y la continua actividad en la que se haya inmerso el paradigma

del IOT, las características requeridas para una infraestructura de este tipo pueden va- riar con relativa rapidez. De forma que, es importante que el código de la pasarela transparente este debidamente modularizado, permitiendo la incorporación de nuevas características de forma sencilla, sin que sea necesaria una gran reestructuración. Con el modelo de comunicación propuesto por esta infraestructura, no es necesario que la pasarela almacene la información que recopilan los sensores (en bases de datos, 7.1. CONCLUSIONES 165

o archivos), aunque puede hacerlo si así se requiere. Esto es debido a que el centro de operaciones se encuentra en un servidor externo, en Mosquitto. Con este esquema, la carga de trabajo de la pasarela se disminuye, al no tener que mantener ni gestionar, bases de datos o archivos. Si se desea que la información que publiquen los sensores se almacene de forma per- sistente, además de distribuirse a los suscriptores, estos deberán programarse para que utilicen convenientemente MQTT-SN, y le indiquen a Mosquitto que dichas publica- ciones deben de tener persistencia. Este modelo, es distinto al que proporciona Libelium, basado en el protocolo ZigBee y en el almacenamiento de la información en bases de datos. La información se presenta a los consumidores en forma de eventos, y la tendrán disponible instantes después de que sea generada. La única tarea que deben de llevar a cabo los consumidores de infor- mación, es suscribirse a los canales de comunicación en los que los eventos publican, la infraestructura se encargará de hacer llegar estas publicaciones a Mosquitto, y este de distribuirlas a los suscriptores. Mosquitto puede residir en cualquier máquina que tenga conexión con la pasarela, ya sea a través de la interfaz Ethernet, Wi-Fi o 3G/GPRS. Proporcionando de esta forma, flexibilidad a la infraestructura.

Una vez satisfechos los objetivos anteriores, solo quedaba implementar la librería MQTT- SN y completar el software de traducción de la pasarela. Que permitirían disponer de la in- fraestructura completamente operativa. En esta etapa es en la que se programó el dispositivo Waspmote (véase Anexo C), para hacer que la librería pasase todos los test establecidos. En cuanto a la creación de la librería MQTT-SN y el software de traducción, se conclu- ye:

MQTT-SN es un protocolo adecuado para las redes de sensores, en relación al tamaño de los paquetes que envía por la red. Minimiza al máximo cada paquete, el mensaje mínimo es de 2 bytes de longitud. Y permite disponer de la mayor parte del paquete para la carga útil del mismo, acortando los Topic Names con el proceso de registro, mantiene identificadores de mensaje de tan solo 2 bytes, etc. Por regla general, realiza las mismas funciones que MQTT pero con mensajes menos pesados Sin embargo, en algunos escenarios de actuación del protocolo, el intercambio de men- sajes requerido entre pasarela y sensor, es excesivo:

• El proceso de conexión utilizando la característica last will and testament se ha dividido en un intercambio de 6 mensajes. • Para que la pasarela mantenga clientes en diferentes estados (dormido, despierto, activo, perdido, etc) se requiere un flujo de mensajes demasiado grande. 166 CAPÍTULO 7. CONCLUSIONES Y PROPUESTAS

Estas dos situaciones, en una red con varios clientes conectados, pueden llevar a una sobrecarga excesiva y a un mal funcionamiento, ya que pueden generar efectos no deseados, como alta latencia. Además, este hecho se agrava debido a la naturaleza de las redes de sensores, que por lo general, son de bajo ancho de banda y alta latencia.

La publicación con nivel de QOS -1, es la más adecuada de cara a la eficiencia de la red, pero no proporciona ninguna garantía de entrega.

La librería se ha implementado para actuar sobre dispositivos Waspmote de Libelium, y sitúa MQTT-SN sobre 802.15.4, pero se ha programado de forma que adaptarlo a una tecnología distinta solo dependa de dos funciones, las que envían y reciben datos a través de la red. Modificando estas funciones, se adaptará la librería a cualquier escenario de red.

Una vez desarrollada la infraestructura, el último de los objetivos consistía en implementar un mecanismo para soportar suscriptores externos y comprobar su funcionamiento. Tras su realización, se concluye:

Se ha comprobado que la infraestructura proporciona la información que publiquen los sensores, en tiempo real.

Puede afirmarse que la infraestructura actúa como un middleware básico, que abstrae al suscriptor externo o aplicación, de las tecnologías involucradas en el proceso de transmisión de la información desde los sensores de la red.

Esta infraestructura puede ser utilizada como subsistema dentro de un sistema mayor, que utilice los eventos una vez llegan a Mosquitto, con alguna finalidad en concreto.

7.2 Propuestas

El ámbito de este proyecto es amplio, el IOT es un paradigma emergente con multitud de lineas de evolución y un gran número de tecnologías involucradas en él. Las Smart Cities están teniendo gran acogida, tanto en España como en Europa, la Unión Europea y los dis- tintos gobiernos de las ciudades, están destinando fondos a su desarrollo y en algunas lugares como Santander, Malaga o Barcelona ya se han obtenido buenos resultados. Y por su parte, MQTT y MQTT-SN son dos protocolos cuyo auge es latente, actualmente se está trabajando continuamente en nuevas versiones, tanto de brokers como de librerías y clientes, habien- do implementaciones disponibles para una gran variedad de lenguajes de programación (C, JavaScript, Java, C++, Go, etc.) y plataformas, como Android. De esta forma, a pesar de que se han cumplido con los objetivos establecidos inicialmente, surgen una serie de posibles mejoras susceptibles de ser aplicadas a la infraestructura im- plementada, para hacerla más completa o adaptarla a nuevos requisitos. A continuación se expone una lista con ellas: 7.2. PROPUESTAS 167

1. Hay algunas características de los protocolos que no eran necesarias para los requisitos con que se pretendía dotar a la infraestructura. Sin embargo, pueden resultar útiles en futuros usos, estas son: • Características last will and testament, tanto de MQTT como de MQTT-SN. • Gestión por parte de la pasarela de los diferentes estados del cliente MQTT-SN. 2. Debido a la inexistencia de actuadores en la plataforma sobre la que se ha desplegado la infraestructura, esta carece de la funcionalidad que haría posible que la pasarela pudiese enviar publicaciones a uno de los sensores, es decir, de tener el flujo inverso de información, que las publicaciones llegasen desde publicadores externos, hacia los dispositivos de la plataforma y que se provocasen acciones en los mismos. Una posible mejora sería dotar a la infraestructura de esta funcionalidad, realizando: • Las funciones de envío y recepción de los mensajes SUBSCRIBE y UNSUBS- CRIBE del protocolo MQTT-SN. • La traducción de estos mensajes a MQTT y su envío utilizando la librería MQTT implementada. • La traducción de los mensajes PUBLISH que llegasen desde Mosquitto. • La recepción de mensajes PUBLISH en la librería MQTT-SN. 3. Integrar la infraestructura en Civitas, como uno de los mecanismos que tiene a su disposición el framework, para recopilar información que se produce en la ciudad. 4. Añadir seguridad al tráfico de la infraestructura. Para ello es posible: • Utilizar las funciones de seguridad del estándar 802.15.4, para que se cifrasen todos los paquetes enviados por la red de sensores. • Configurar Mosquitto para que la interacción con la pasarela, se realice utilizando criptografía de clave asimétrica. • Ambos procedimientos. 5. En caso de necesitar una solución muy escalable, pueden configurarse varios servido- res Mosquitto en red, estableciendo una jerarquía entre ellos y consiguiendo que se repartan las suscripciones, disminuyendo así la carga de distribución de eventos que cada nodo Mosquitto de la red tendría que soportar. 6. Añadir opciones de persistencia a la pasarela. Con el funcionamiento actual, si los clientes lo desean, pueden almacenar sus publicaciones de forma permanente en el broker Mosquitto. Sin embargo, la pasarela no almacena información alguna. Esta mejora serviría para el caso concreto en que se requiriese que la pasarela almacenase la información que recopilan los sensores, para proporcionársela a otras aplicaciones. Para llevarla a cabo tan solo habría que añadir al código de la pasarela, las funciones necesarias para, tras recibir y procesar un mensaje, almacenar su información en un archivo o base de datos. Este trabajo sería sencillo de realizar ya que Libelium propor- ciona el código hace estas tareas, y tan solo habría que adaptarlo.

7.3 Conclusiones personales

En lo que a opinión personal del autor se refiere, la realización de este TFG ha servido para afianzar y ampliar los conocimientos adquiridos a lo largo de la carrera de Ingeniería Informática, en especial aquellos relacionados con la especificación cursada, Ingeniería de Computadores. Desde un primer momento el autor se decantó por la elección de dicha rama, debido en su mayor parte a los conocimientos asociados a ella y a los profesores encargados de difundirlos. La realización de este TFG, que está directamente relacionado con dicha rama, no ha hecho sino fortalecer la elección y el camino tomados. Por otra parte, el autor considera que este proyecto ha sido muy útil para ampliar los conocimientos de que disponía en áreas importantes de la informática, como son los sistemas empotrados, los sistemas de comunicaciones, la programación de estos sistemas, las redes de computadores, las comunicaciones inalámbricas, etc.

En cuanto a aspectos que tienen relación directa con la temática de este TFG, el autor con- sidera igualmente fructífero el descubrimiento de paradigmas y tecnologías de actualidad y en pleno auge, como son el Internet de las Cosas y las Ciudades Inteligentes. Durante la fase de documentación y posterior desarrollo, se han leído y estudiado numerosos documentos científicos, proyectos de investigación, trabajos innovadores, etc. que han reforzado en gran medida los conocimientos asimilados sobre estos temas, llegando al punto de comprender perfectamente sobre que cimientos están construidos y que puede aportar su uso a la socie- dad. Por último, el autor considera que uno de los pilares fundamentales de esta ciencia, son los protocolos de comunicación. Con lo cual, el haber desarrollado un proyecto basado en el estudio, comprensión y posterior programación y aplicación de algunos de ellos, ha sido una tarea muy provechosa de cara a su formación como ingeniero informático. Como añadido, el lenguaje de programación C, ha sido el que más ha gustado al autor a lo largo de la carrera. Su aportación a la informática es innegable, estando los mejores sistemas construidos sobre él y siendo la base de la mayoría de los lenguajes de programación utilizados en la actualidad. El hecho de utilizarlo en este proyecto, ha permitido aumentar el conocimiento y el dominio sobre este lenguaje, y esto es algo que de alguna forma gratifica al autor.

168 ANEXOS

169

Anexo A Manual de usuario de la librería MQTT v3.1.0

Este anexo presenta un manual de usuario en el que se describe como utilizar la librería MQTT que ha sido implementada durante el desarrollo del proyecto.

Esta librería proporciona las funcionalidades necesarias para permitir que un usuario desa- rrolle un cliente MQTT. Se explicará como debe de proceder y se pondrán ejemplos prácticos que ilustren las distintas situaciones posibles.

A.1 Conexión TCP Antes de establecer una sesión MQTT, el cliente debe establecer una conexión TCP con un broker MQTT. Este procedimiento se realiza a través de la función mqtt_init(), la cual recibe tres parámetros:

Estructura del tipo broker_handle_t: utilizada para manejar la conexión con el broker, siempre debe mantenerse una estructura de este tipo a lo largo de la ejecución del programa cliente, el programador deberá declararla, asignarle memoria y pasarla como parámetro a esta función. El manejador gestiona las siguientes opciones de conexión:

• Descriptor del socket: utilizado para almacenar el descriptor de archivo corres- pondiente a la conexión TCP abierta con el broker MQTT. • Identificador del cliente MQTT. • Nombre de usuario. • Contraseña. • Característica Will1. • Sesión limpia. • Tiempo de espera. • Indicativo de sesión de depuración.

La función mqtt_init() inicializa todas estas opciones con sus valores por defecto, pu- diendo modificarse cualquiera de ellas antes de realizar la conexión MQTT. Bien uti-

1Aunque esta característica no ha sido implementada, se mantiene esta opción para futuras mejoras de la librería.

171 lizando las funciones mqtt_set_client_id() y mqtt_set_userpass(), o accediendo a cada uno de los campos de la estructura. Host: indica la dirección de red de la máquina en la que reside el broker MQTT, y con la que se quiere establecer la conexión TCP subyacente. Port: indica el puerto de la máquina destino en el que está escuchando el broker MQTT, a la espera de conexiones entrantes.

La función mqtt_init() retorna el valor asignado al descriptor de socket, para que el cliente pueda realizar comprobación de errores si así lo desea. Cuando la sesión MQTT haya finalizado y no sea necesario utilizar de nuevo el manejador de conexión del cliente, deberá utilizarse la función mqtt_destroy() para liberar la memoria previamente asignada al manejador. La función mqtt_destroy() recibe como único parámetro el manejador de conexión.

A.2 Conexión MQTT Una vez establecida la conexión TCP con el broker, el cliente deberá utilizarla para es- tablecer sobre ella una sesión MQTT. Para gestionar el establecimiento y la finalización de esta sesión, el usuario tiene disponibles las siguientes funciones:

mqtt_send_connect(): esta función utilizará las opciones de conexión que se hayan definido en el manejador, para formar un mensaje CONNECT y enviarlo al broker. mqtt_recv_connack(): como respuesta a la petición de conexión, el broker enviará al cliente un mensaje CONNACK, en el que indicará si se ha establecido la sesión MQTT de forma correcta. Esta función sirve para mantenerse a la espera de este mensaje y procesarlo. mqtt_send_disconnect(): esta función envía un mensaje DISCONNECT al broker MQTT para que este finalice la sesión. Una vez enviado se supone concluida la sesión, ya que el broker no envía mensaje de respuesta. Deberá destruirse el manejador de conexión del cliente.

A.3 Publicación MQTT

La librería soporta los distintos niveles de QOS de MQTT, para cada tipo de publicación se dispone de una función que envía/recibe los distintos tipos de mensajes involucrados. La función más importante es mqtt_send_publish() que envía el mensaje PUBLISH. Re- cibe los siguiente parámetros:

broker: manejador de conexión. topic_name: canal de eventos en el que se va a publicar.

172 msg: mensaje que se va a publicar.

qos: nivel de QOS que se va a utilizar. dup: indica si el mensaje es un duplicado de un mensaje anterior, deberá utilizarse cuando se reenvíen mensajes. retain: sirve para indicar al broker si debe tratar la publicación con esta característica de MQTT.

En el listado A.1 puede verse un ejemplo sencillo de como publicar con lo distintos niveles

de QOS que soporta MQTT, a un broker situado en la dirección de red localhost y a la espera en el puerto 1883.

1 #include " mqtt .h"

3 const char ∗ host = "localhost";

4 const char ∗ port = "1883";

6 int main (int argc , char∗ argv []){

8 // allocate memory to broker handler

9 broker_handle_t ∗ broker = malloc(sizeof(broker_handle_t));

10 // init tcp connection with broker

11 mqtt_init(broker, host, port);

12 // connect to broker

13 mqtt_send_connect(broker);

14 mqtt_recv_connack(broker);

15 // publish toa topic, with QoS0

16 mqtt_send_publish(broker, "a/b", "Hello World!", 0, 0, 0);

17 // publish toa topic, with QoS1

18 mqtt_send_publish(broker, "a/b", "Hello World!", 1, 0, 0);

19 mqtt_recv_puback(broker);

20 // publish toa topic, with QoS2

21 mqtt_send_publish(broker, "a/b", "Hello World!", 2, 0, 0);

22 mqtt_recv_pubrec(broker);

23 mqtt_send_pubrel(broker);

24 mqtt_recv_pubcomp(broker);

25 // disconnect

26 mqtt_send_disconnect(broker);

27 // destroy broker handler

28 mqtt_destroy(broker);

30 return 0;

32 }

Listado A.1: Cliente MQTT que publica utilizando distintos niveles de QOS

173 A.4 Suscripción MQTT Si el cliente quiere añadir o quitar suscripciones a determinados topics, deberá utilizar las funciones mqtt_send_subscribe() y mqtt_send_unsubscribe(). Tienen los siguientes paráme- tros:

broker: manejador de conexión. topic_name: canal de eventos al que se quiere añadir/quitar la suscripción.

La función mqtt_send_suscribe() tiene además, el parámetro qos para indicar el nivel mí-

nimo de QOS para ese canal de eventos. En el listado A.2 puede verse un ejemplo sencillo de como suscribirse y posteriormente quitar la suscripción a un topic.

1 #include " mqtt .h"

3 const char ∗ host = "localhost";

4 const char ∗ port = "1883";

6 int main (int argc , char∗ argv []){

8 // allocate memory to broker handler

9 broker_handle_t ∗ broker = malloc(sizeof(broker_handle_t));

10 // init tcp connection with broker

11 mqtt_init(broker, host, port);

12 // connect to broker

13 mqtt_send_connect(broker);

14 mqtt_recv_connack(broker);

15 // subscribe toa topic

16 mqtt_send_subscribe(broker,"a/b", 1);

17 mqtt_recv_suback(broker);

18 // unsubscribe toa topic

19 mqtt_send_unsubscribe(broker, "a/b");

20 mqtt_recv_unsuback(broker);

21 // disconnect

22 mqtt_send_disconnect(broker);

23 // destroy broker handler

24 mqtt_destroy(broker);

26 return 0;

28 }

Listado A.2: Cliente MQTT que se suscribe a un topic y después cancela esta suscripción.

Para hacer que un cliente suscriptor se mantenga a la espera de publicaciones, habrá que utilizar la función mqtt_loop(), que mantiene la conexión utilizando pings y cuando recibe

174 una publicación, aísla el mensaje recibido. El código de cliente deberá elegir que acción realizar con dicho mensaje.

A.5 Valores de retorno Todas las funciones de envío/recepción de mensajes de la librería, retornan el valor 1 si el mensaje se ha enviado/recibido sin que hayan ocurrido errores. Si por el contrario, ha ocurrido algún error, retornan el valor -1 y muestran por la salida estándar de error un mensaje indicando el tipo de error.

A.6 Clientes Esta librería también contiene dos clientes MQTT, exec/mqtt_sub y exec/mqtt_pub, que pueden ser ejecutados para probar la librería. El uso de ambos programas viene determinado por los comandos:

$ mqtt_sub [options] -t $ mqtt_pub [options] -t -m

Donde las opciones pueden ser: -c: desactiva la opción clean-session, que viene activada por defecto. -d: activa el modo de depuración. -h : host en el que reside el broker MQTT al que hay que conectarse. Por defecto localhost. -p : puerto de red del host anterior, en el que está escuchando el broker. Por defecto 1883. -i : identidad que se asignará al cliente. -k : periodo de tiempo de vida para el cliente, en segundos. Por defecto 180.

-q : QOS requerida para las publicaciones del topic al que se suscribe el cliente. -u : nombre de usuario del cliente, en caso de que el broker tenga confi- gurado control de acceso para conectarse. -P : contraseña para el anterior nombre de usuario.

175

Anexo B Manual de usuario de la librería MQTT-SN v1.2

Este anexo presenta un manual de usuario en el que se describe como utilizar la librería MQTT-SN que ha sido implementada durante el desarrollo del proyecto. Esta librería proporciona las funcionalidades necesarias para permitir que un usuario desa- rrolle un cliente MQTT-SN. Se explicará como debe de proceder y se pondrán ejemplos prácticos que ilustren las distintas situaciones posibles.

B.1 Instalación Para poder usar una librería de usuario en Waspmote, deben de introducirse sus archivos fuente en un directorio situado dentro del directorio libraries del IDE de Waspmote. Por ejemplo, si el IDE está situado en el home del usuario bajo el directorio waspmote, la ruta en la que habría que introducir los archivos de la librería MQTT-SN sería: /waspmote/librarie- s/MQTTSN. Una vez que se han situado los archivos fuente en su directorio correspondiente, si quieren usarse para programar el dispositivo, se deberá incluir el archivo de cabecera correspondiente en el código. Esta acción puede hacerse manualmente o a través de la interfaz de usuario, pestaña Sketch → Import libraries, y seleccionarla. Realizado esto, ya pueden usarse todas las funcionalidades que ofrezca la librería.

B.2 Configuración inicial Antes de comenzar con el proceso de conexión MQTT-SN, el cliente debe de configurar algunos aspectos de la futura conexión. Para ello tiene disponibles las siguientes funciones, que deberán ser usadas dentro de la función setup() del Sketch:

set_debug_on(): sirve para activar el modo depuración, que imprimirá información de todo el proceso posterior, por el puerto serie.

set_gw_mac(): recibe por parámetro una dirección MAC, que deberá ser la de la pasa- rela a la que se quieren enviar los mensajes. Siempre es necesario llamar a esta función al menos una vez durante la ejecución del código del cliente. set_client_id(): recibe por parámetro la identidad que se quiere asignar al cliente. En

177 caso de no utilizarse esta función, se inicializará automáticamente a un valor por de- fecto.

set_keep_alive(): recibe como parámetro un entero de 16 bits, que indicará el periodo de tiempo de vida del cliente.

obtain_sensorMac(): consulta la dirección MAC 802.15.4 del dispositivo, y la almace- na en dos vectores de caracteres, por un lado la parte alta y por otro la parte baja. Esta función también es necesario utilizarla al menos una vez en cada ejecución.

En el listado B.1 puede verse un ejemplo de configuración, en la que se establece la direc- ción MAC, se modifica el identificador de cliente y se deja el modo de depuración apagado (por defecto).

1 const char ∗ gw_mac = "0013A200xxxxxxxx";

2 const char ∗ client_id = "mqttsn −0001";

4 void setup () {

5 mqttSN.set_gw_mac(gw_mac);

6 mqttSn.set_client_id(client_id);

7 mqttSN.obtain_sensorMac();

9 xbee802.ON();

10 }

Listado B.1: Ejemplo de configuración de cliente.

Como puede observarse se utiliza el objeto mqttSN para acceder a las funcionalidades de la librería.

B.3 Registro de topics MQTT-SN Para publicar información a un topic determinado, antes es necesario registrarlo en la pasarela, y obtener su identificador de topic correspondiente.

El primer paso es conectarse ya sea a un broker MQTT-SN, o MQTT a través de una pasarela. Cuando se reciba el acuse de recibo indicando que la conexión se ha realizado con éxito, el cliente deberá comenzar el proceso de registro, utilizando la función register_- topicName() e indicando el topic name que quiere registrar. Después se mantendrá a la espera de recibir la confirmación de que todo ha ido bien, de no ser así, deberá intentar de nuevo registrar el topic name cuando pase un periodo de tiempo Twait (constante T_WAIT de la librería).

En el listado B.21 puede verse un ejemplo en el que un cliente registra el topic name

1El resto de listados del Anexo, corresponden a código que iría situado en el interior de la funcón loop() del Sketch.

178 «a/b». Tras recibir el REGACK, el topic id quedara´ almacenado en la tabla de topics del dispositivo.

1 //CONNECT

2 int resCon = mqttSN.connect();

3 if (resCon == 1)

4 USB.println("−−−− connect send");

6 int resCack = mqttSN.recv_connack();

7 if (resCack > 0)

8 USB.println("−−−− connack received");

10 //REGISTER

11 int resReg = mqttSN.register_topicName("a/b");

12 if(resReg == 1)

13 USB.println("−−−− register send");

15 int resRack = mqttSN.recv_regack();

16 if(resRack > 0)

17 USB.println("−−−− regack received");

Listado B.2: Ejemplo de registro de topic name de un cliente.

B.4 Publicación MQTT-SN En MQTT-SN hay varias formas de publicar, una es realizando el registro de un topic name como en la sección anterior, y después publicar utilizando el topic id recibido. Otra es utilizando bien un pre-defined topic id, o bien un short topic name. Los cuales no necesitan de registro previo, en el caso de pre-defined topic id porque la pasarela ya almacena una estructura de datos con varios topic id a los que publicar, en el caso de short topic name, porque son topic names de tan solo 2 bytes, y pueden enviarse en el mensaje PUBLISH. En este caso la pasarela almacena 3 pre-defined topic id por defecto, que son: 0→«a/b», 1→«a/c» y 2→«a/d». En cualquier caso, la función utiliza se denomina publish() y recibe los siguientes pará- metros:

topicId: identificador de topic al que publicar. topicType: tipo de topic. msg: mensaje para publicar.

qos: nivel de QOS de la publicación. dup: indica si el mensaje es un duplicado. retain: indica si el mensaje debe tener persistencia en el broker.

179 El cliente puede publicar con cualquiera de las QOS de MQTT-SN, el flujo de mensajes es

idéntico al de MQTT, en el listado A.1 puede verse un ejemplo de publicación con QOS nivel 1.

1 int qos = 1;

2 int dup = 0;

3 int retain = 0;

5 //CONNECT

6 int resCon = mqttSN.connect();

7 if (resCon == 1)

8 USB.println("−−−− connect send");

10 int resCack = mqttSN.recv_connack();

11 if (resCack == 1)

12 USB.println("−−−− connack received");

14 //PUBLISH

15 int resPub = mqttSN.publish(1, MQTTSN_TOPIC_TYPE_PREDEFINED,

16 "Hello World from Waspmote",

17 qos, dup, retain);

18 if(resPub == 1)

19 USB.println("−−−− publish send");

21 if( qos == 1) {

22 resPack = mqttSN.recv_puback();

23 if(resPack == 1)

24 USB.println("−−−− puback received");

25 }

Listado B.3: Ejemplo de publish con QOS 1.

B.4.1 Publicación con QOS -1 Este tipo de publicación es la única forma de publicar en la que MQTT-SN difiere de MQTT, en este caso no es necesario conexión previa con el broker, es la pasarela la que maneja todo el proceso.

Puede verse un ejemplo en el listado B.4.

1 int qos = −1;

2 int dup = 0;

3 int reatin = 0;

5 //PUBLISH

6 int resPub = mqttSN.publish(1, MQTTSN_TOPIC_TYPE_PREDEFINED,

7 "Hello World from Waspmote, QoS−1",

8 qos, dup, retain);

180 9 if(resPub == 1)

10 USB.println("−−−− publish send");

Listado B.4: Ejemplo de publish con QOS -1.

B.5 Valores de retorno Todas las funciones de envío/recepción de esta librería, retornan en valor 1 si el paquete se ha enviado/recibido correctamente por la red, y el valor -1, si ha ocurrido algún error en el envío/recepción, o si no se han recibido los datos esperados.

B.6 Clientes Como parte del desarrollo y testeo de la librería, se han realizado varios clientes, cada uno para probar un escenario determinado. Pueden consultarse en el repositorio del proyecto:

https://bitbucket.org/rober botto/tfg

181

Anexo C Manual sobre cómo programar Waspmote

Este anexo pretende ser una guía sobre los pasos que hay que realizar para programar de forma correcta los dispositivos Waspmote de Libelium. Desde la instalación del IDE a cargar y ejecutar código en la placa.

C.1 IDE de Waspmote: Descarga e instalación

El IDE de Waspmote está disponible para su descarga en la página web de Libelium, en concreto aquí:

http://www.libelium.com/development/waspmote/sdk applications

Desde donde se deberá descargar la versión correspondiente al sistema operativo del usua- rio, en este caso y siguiendo la linea de todo el documento, se opta por tratar la instalación del IDE para sistemas operativos GNU/Linux.

Para este tipo de sistemas existen dos versiones distintas del software, la de 32 bits y la de 64 bits, ambas portables en el aspecto de que no necesitan instalación de paquetes para ejecutarse. Sin embargo, para poder compilar y ejecutar código sobre los dispositivos de forma correcta, es necesaria la instalación de algunos paquetes extra:

1. La versión necesaria del entorno Java. En concreto la versión 6 del JRE de Java. Para ello debe utilizarse cualquier gestor de paquetes e instalar sun-java6-jre.

2. La versión necesaria del compilador avr-gcc, para ser capaz de programar el micro- controlador ATMEGA 1281 de Waspmote. El paquete a instalar es gcc-avr.

3. La versión necesaria de la librería lib-avc. Contenida en el paquete avr-libc.

Realizadas estas acciones ya se dispone del entorno adecuado para ejecutar el IDE y poder utilizar todas sus funcionalidades. Para ello, deberá ejecutarse el archivo ejecutable llamado waspmote, contenido dentro del directorio raíz del conjunto de archivos y directorios descar- gados.

183 C.2 Cargar un nuevo programa en Waspmote Para cargar y ejecutar código en el dispositivo, hay una serie de pasos, tanto para la propia placa como para el IDE, que hay que realizar siempre:

1. Encender Waspmote, en la Figura C.1 mover el botón hacia la izquierda.

Figura C.1: Como encender Waspmote. Fuente: [Lib13d].

2. Conectar Waspmote al ordenador personal utilizando el cable USB. Abrir el IDE y seleccionar la placa y el puerto apropiados, en el menú Tools (véanse Figuras C.2 y C.3). 3. Preparar el código para subir a Waspmote, en este caso la plantilla hello_world. 4. Guardar el Sketch (con el botón correspondiente). Comprobar el estado que indica el IDE para ver si se ha guardado (véase Figura C.4). 5. Compilar el código (con el botón correspondiente) para ver si contiene errores o avisos. Si todo está correcto, el IDE mostrará el estado Done Compiling. 6. Cargar el código en el dispositivo, para ello utilizar el botón Upload y esperar unos se- gundos hasta que el proceso termine. Si se muestra el estado Done uploading significa que no han ocurrido errores en el proceso (véanse Figuras C.5 y C.6).

184 Figura C.2: Seleccionar placa adecuada. Fuente: [Lib13d].

Figura C.3: Seleccionar puerto adecuado. Fuente: [Lib13d].

185 Figura C.4: Guardar un Sketch. Fuente: [Lib13d].

Figura C.5: Cargar un Sketch 1. Fuente: [Lib13d].

186 Figura C.6: Cargar un Sketch 2. Fuente: [Lib13d].

187

Anexo D Instalación y configuración de CUnit

En este anexo se tratan aspectos relativos al proceso de instalación y configuración del framework de testing CUnit, utilizado para realizar los distintos escenarios de test para el protocolo MQTT. CUnit es un framework para escribir, gestionar y ejecutar test unitarios en C. Está cons- truido como una librería estática que se vincula al código del usuario mediante el uso de directivas del preprocesador. Además de proporcionar una plataforma para escribir test, tam- bién incorpora un conjunto de interfaces de usuario, las cuales facilitan la interacción con el framework y permiten visualizar los resultados de distintas formas. La estructura que sigue este framework puede verse en la Figura D.1. Los test unitarios son empaquetados en suites, y estas suites se registran en el registro de test activo. Las suites pueden tener funciones de inicialización y destrucción, que serán llamadas automáticamente antes y después de ejecutar los test que contengan. Solo puede haber un registro activo a la vez. Un esquema de uso de CUnit puede ser el siguiente:

1. Escribir funciones para testear y la inicialización/destrucción de las suites, si es nece- sario. 2. Inicializar el registro de test’s: CU_initialize_registry(). 3. Añadir las suites al registro: CU_add_suite(). 4. Añadir test’s a las suites: CU_add_test(). 5. Ejecutar los test’s usando la interfaz apropiada: p.e. CU_console_run_tests(). 6. Limpiar el registro de test: CU_cleanup_registry()

D.0.1 Instalación CUnit no está disponible en los repositorios de ninguna distribución, para instalar este software es necesario compilarlo desde los fuentes. Esta tarea no tiene un procedimiento unificado para llevarse a cabo, y depende de la máquina en la que se quiera instalar. Sin embargo, si que hay un procedimiento habitual que, por regla general, suele funcionar sin problemas. Consta de los siguientes pasos:

189 Figura D.1: Estructura del framework CUnit.

1. Descargarse todos los archivos necesarios desde la página web del proyecto [KS].

2. Extraer los archivos y situarse en el interior del directorio que los contiene. 3. Ejecutar:

# ./configure # make # make install

4. Opcionalmente se pueden borrar los archivos generados durante este proceso, ejecu- tando:

# make clean

Entre los comandos make y make install, se puede ejecutar make check, para pasar una serie de test que vienen incorporados con el software. Para situaciones especiales en las que no logre instalarse CUnit con este procedimiento, será necesario consultar el archivo INSTALL que viene incluido en la descarga.

D.0.2 Ejemplo de uso Una vez instalado el framework, para utilizarlo tan solo es necesario incluir en nuestro código los archivos de cabecera que se necesiten. CUnit dispone de varios de estos archivos, incluyendo cada uno, una parte del framework. De esta forma no es necesario incluir toda la funcionalidad de CUnit si no se necesita.

190 En el Listado D.1 puede verse un ejemplo de uso de CUnit, el escenario de test está formado por un test que comprueba la existencia del carácter H en un array de caracteres. En el código puede verse el proceso mediante el cual se declara la suite, se inicializa el registro, se añade la suite al registro y se añade el test a la suite. Una vez hecho esto, CUnit ya puede ejecutar el test, en este caso se ha usado la interfaz básica.

1 #include "CUnit/Basic.h"

2 #include "CUnit/CUnit.h"

3 #include

5 char ∗ array ;

7 /∗ Init function of the Suite

8 ∗− Get memory for array

9 ∗− Store"Hello" in array ∗/

10 int init_suite_containsH(void){

11 array = (char∗) malloc (5∗sizeof(char));

12 memcpy(array, "Hello", 5);

13 return 0;

14 }

16 /∗ Clean function of the Suite

17 ∗− Free mem

18 ∗− Free pointer ∗/

19 int clean_suite_containsH(void){

20 free(array);

21 array = NULL;

22 return 0;

23 }

25 /∗ Test that search into array the existence

26 ∗ of the character’H’ ∗/

27 void test_ARRAY_contains_H(void){

28 /∗ strchr function returnsNULL if the characterH is not

29 ∗ found on ∗ array and returna pointer to the matched

30 ∗ character ifH is found ∗/

31 CU_ASSERT_TRUE( strchr(array, ’H’) != NULL );

32 }

34 /∗ main function ∗/

35 int main () {

36 CU_pSuite pSuite_containsH = NULL;

38 /∗ initialize the CUnit test registry ∗/

39 if (CU_initialize_registry() != CUE_SUCCESS)

40 return CU_get_error();

191 42 /∗ add the suites to the registry ∗/

43 pSuite_containsH = CU_add_suite("ContainsH_Suite",

44 init_suite_containsH,

45 clean_suite_containsH);

47 if (pSuite_containsH == NULL) {

48 CU_cleanup_registry();

49 return CU_get_error();

50 }

52 /∗ add the tests to the suites ∗/

53 if((CU_add_test(pSuite_containsH, "contains H",

54 test_ARRAY_contains_H) == NULL)) {

55 CU_cleanup_registry();

56 return CU_get_error();

57 }

59 /∗ Run all tests using the CUnit Basic interface ∗/

60 CU_basic_set_mode(CU_BRM_VERBOSE);

61 CU_basic_run_tests();

63 CU_cleanup_registry();

64 return CU_get_error();

65 }

Listado D.1: Código de ejemplo de uso de CUnit

Para compilar este código debe usarse la librería lcunit, por ejemplo, si el archivo fuente tuviese el nombre test.c, valdría el comando:

$ gcc -Wall test.c -o test -lcunit

La salida tras ejecutar el test sería la siguiente:

$ ./ test

CUnit - A unit testing framework for C - Version 2.1-2 http://cunit.sourceforge.net/

Suite: ContainsH_Suite Test: contains H ...passed

Run Summary: Type Total Ran Passed Failed Inactive suites 1 1 n/a 0 0 tests 1 1 1 0 0 asserts 1 1 1 0 n/a

Elapsed time = 0.000 seconds

Donde puede verse que el test contains H, de la suite ContainsH_Suite, ha sido pasado con éxito.

192 Referencias

[AIM10a] Luigi Atzori, Antonio Iera, y Giacomo Morabito. The internet of things: A survey. Computer networks, 54(15):2787–2805, 2010.

[AIM10b] Luigi Atzori, Antonio Iera, y Giacomo Morabito. The Internet of Things: A Survey. Comput. Netw., 54(15):2787–2805, Octubre 2010. url: http://dx. doi.org/10.1016/j.comnet.2010.05.010.

[ASSC02] Ian F Akyildiz, Weilian Su, Yogesh Sankarasubramaniam, y Erdal Cayirci. Wi- reless sensor networks: a survey. Computer networks, 38(4):393–422, 2002.

[Bec00] Kent Beck. Extreme programming explained: embrace change. Addison- Wesley Professional, 2000.

[Bec03] Kent Beck. Test-driven development: by example. Addison-Wesley Professio- nal, 2003.

[BGS+08] Michael Buettner, Ben Greenstein, Alanson P Sample, Joshua R Smith, Da- vid Wetherall, et al. Revisiting Smart Dust with RFID Sensor Networks. En HotNets, páginas 37–42, 2008.

[Bie12] Alberto Bielsa. Smart Water project in Valencia to moni- tor Water Cycle Management. http://www.libelium.com/ smart water cycle monitoring sensor network/, 2012.

[Bie13] Alberto Bielsa. Smart Parking and environmental monitoring in one of the world’s largest WSN. http://www.libelium.com/ smart santander parking smart city/, 2013.

[BMA02] Kent Beck, Jesús García Molina, y Luis Joyanes Aguilar. Una explicación de la programación extrema: aceptar el cambio. Addison Wesley, 2002.

[Bro01] David L Brock. The electronic product code (epc). Auto-ID Center White Paper MIT-AUTOID-WH-002, 2001.

[CCB14] Raphael Cohn, Richard Coppen, y Geoff Brown. OASIS Message Queuing Telemetry Transport (MQTT) TC. https://www.oasis-open.org/ committees/tc home.php?wg abbrev=mqtt, 2014.

193 [CLI13] Oscar Cosido, Carlos Loucera, y Andres Iglesias. Automatic calculation of bicycle routes by combining meta-heuristics and GIS techniques within the framework of smart cities. En New Concepts in Smart Cities: Fostering Pu- blic and Private Alliances (SmartMILE), 2013 International Conference on, páginas 1–6. IEEE, 2013.

[CLP03] José H Canós, Patricio Letelier, y Ma Carmen Penadés. Metodologías Ágiles en el desarrollo de Software. VIII Jornadas de Ingeniería de Software y Bases de Datos, JISBD, 2003.

[Coh] Raphael Cohn. StormMQ: A Comparison of AMQP and MQTT. url: http:// stormmq.com.

[D+06] Adam Dunkels et al. The contiki operating system. Web page. Visited Oct, 24, 2006.

[DV08] Adam Dunkels y JP Vasseur. IP for smart objects. Ipso alliance white paper, 1, 2008.

[Fin10] Klaus Finkenzeller. RFID Handbook, ed, 2010.

[FPPV12] Maria Fazio, Maurizio Paone, Antonio Puliafito, y Massimo Villari. Hetero- geneous sensors become homogeneous things in smart cities. En Innovative Mobile and Internet Services in (IMIS), 2012 Sixth In- ternational Conference on, páginas 775–780. IEEE, 2012.

[GDFSB09] Ning Gui, Vincenzo De Florio, Hong Sun, y Chris Blondia. ACCADA: A Framework for Continuous Context-Aware Deployment and Adaptation. En Rachid Guerraoui y Franck Petit, editors, Stabilization, Safety, and Security of Distributed Systems, volume 5873 of Lecture Notes in Computer Science, páginas 325–340. Springer Berlin Heidelberg, 2009. url: http://dx.doi.org/ 10.1007/978-3-642-05118-0 23.

[GKC04] Neil Gershenfelo, Raffi Krikorian, y Danny Cohen. The Internet of Things- The principles that run the Internet are now creating a new kind of network of everyday devices, anÏnternet-O.". Scientific American, 291(4):46–51, 2004.

[HCC09] Jonathan Hui, David Culler, y Samita Chakrabarti. 6LoWPAN: Incorporating IEEE 802.15. 4 into the IP architecture. IPSO Alliance White Paper, 3, 2009.

[Ins10] Berg Insight. Fleet Management and Wireless M2M, 2010.

[JHU+05] Felice Armenio Johnson Johnson, Mark Harrison, Bernie Hogan GS US, Jin Mitsugi, Josef Preishuber, Oleg Ryaboy CVS, y KK Suen. The EPCglobal Architecture Framework. 2005.

194 [JPPM10] Carlos Blé Jurado, Juan Gutierrez Plaza, Fran Reyes Perdomo, y Gregorio Me- na. Diseño Ágil con TDD. Enero 2010.

[KBE06] Michael J Karlesky, William I Bereza, y Carl B Erickson. Effective test driven development for embedded software. En Electro/information Technology, 2006 IEEE International Conference on, páginas 382–387. IEEE, 2006.

[KS] Anil Kumar y Jerry St.Clair. CUnit Testing Framework. http://cunit. sourceforge.net/index.html.

[KS13] Ganesh S Khekare y Apeksha V Sakhare. A smart city framework for inte- lligent traffic system using VANET. En Automation, Computing, Communi- cation, Control and Compressed Sensing (iMac4s), 2013 International Multi- Conference on, páginas 302–305. IEEE, 2013.

[Lib13a] Libelium Comunicaciones Distribuidas S.L. Meshlium Datasheet, Agosto 2013.

[Lib13b] Libelium Comunicaciones Distribuidas S.L. Meshlium Quickstart Guide, No- viembre 2013.

[Lib13c] Libelium Comunicaciones Distribuidas S.L. Meshlium Technical Guide, No- viembre 2013.

[Lib13d] Libelium Comunicaciones Distribuidas S.L. Waspmote Quickstart Guide, Agosto 2013.

[Lib14a] Libelium Comunicaciones Distribuidas S.L. Waspmote 802.15.4 Networking Guide, Febrero 2014.

[Lib14b] Libelium Comunicaciones Distribuidas S.L. Waspmote Datasheet, Febrero 2014.

[Lib14c] Libelium Comunicaciones Distribuidas S.L. Waspmote Technical Guide, Fe- brero 2014.

[Loc10] D Locke. MQ Telemetry Transport (MQTT) V3. 1 Protocol Specification. Technical report, 2010.

[LP+03] Ying Liu, Beth Plale, et al. Survey of publish subscribe event systems. Com- puter Science Dept, Indian University, 16, 2003.

[LTQS+12] Anh Le Tu’n, Hoan Nguyen Mau Quoc, Martin Serrano, Manfred Hauswirth, John Soldatos, Thanasis Papaioannou, y Karl Aberer. Global Sensor Mode- ling and Constrained Application Methods Enabling Cloud-Based Open Space

195 Smart Services. En Ubiquitous Intelligence & Computing and 9th Interna- tional Conference on Autonomic & Trusted Computing (UIC/ATC), 2012 9th International Conference on, páginas 196–203. IEEE, 2012.

[MOA10] Gaetano Marrocco, Cecilia Occhiuzzi, y Francesco Amato. Sensor-oriented passive RFID. En The Internet of Things, páginas 273–282. Springer, 2010.

[mos14] Mosquitto Eclipse Technology Project. http://projects.eclipse.org/ projects/technology.mosquitto, 2014.

[MQT] MQTT.org. url: http://mqtt.org.

[NMF+02] James Newkirk, Robert C Martin, Martin Fowler, Francisco Javier Zapata Mar- tínez, y Jesús García Molina. La programación extrema en la práctica. Addison Wesley, 2002.

[PG09] Mirko Presser y Alexander Gluhak. The Internet of Things: Connecting the Real World with the Digital World. 2, 2009. url: http://eurescom.eu/ message.

[Pul12] Ana Trejo Pulido. Open Smart Cities III: Plataformas, servicios y aplicaciones de código abierto para las Smart Cities. http://goo.gl/TXJgzV, 2012.

[Pul13] Ana Trejo Pulido. Open Smart Cities I: La Internet de las Cosas de Código Abierto. http://observatorio.cenatic. es/index.php?option=com content&view=article&id=803: open-smart-cities-i-la-internet-de-las-cosas-abierto&catid= 94:tecnologia&Itemid=137, 2013.

[RAB+14] Roberto Requena, Antonio Agudo, Alba Baron, Maria Campos, Carlos Guija- rro, Jose Puche, David Villa, Felix Villanueva, y Juan Carlos Lopez. Imple- menting a Holistic Approach for the Smart City. En Active Media Technology, páginas 537–548. Springer, 2014.

[Rad12] Loki Radoslav. Wireless Identification and Sensing Platform. 2012.

[Rog02] S PRESSMAN Roger. Ingeniería de software: un enfoque practico. McGraw Hill, 2002.

[Sak06] Ken Sakamura. Challenges in the age of ubiquitous computing: a case study of T-Engine, an open development platform for embedded systems. En Procee- dings of the 28th international conference on Software engineering, páginas 713–720. ACM, 2006.

196 [SCT13] AS Stanford-Clark y Hong Linh Truong. MQTT for Sensor Networks (MQTT- S) Protocol Specification. Technical report, IBM developerWorks Technical Library, available at http://mqtt.org/documentation, 2013.

[Sel14] María Campos Selfa. Razonamiento espacio-temporal basado en sentido co- mún para la Smart City. Master’s thesis, 2014.

[SKP+11] Hans Schaffers, Nicos Komninos, Marc Pallot, Brigitte Trousse, Michael Nils- son, y Alvaro Oliveira. Smart Cities and the Future Internet: Towards Coope- ration Frameworks for Open Innovation. En John Domingue, Alex Galis, y Gavras et al., editors, The Future Internet, volume 6656 of Lecture Notes in Computer Science, páginas 431–446. Springer Berlin Heidelberg, 2011. url: http://dx.doi.org/10.1007/978-3-642-20898-0 31.

[Sri06] Lara Srivastava. Pervasive, ambient, ubiquitous: the magic of radio. En Euro- pean Commission Conference “From RFID to the Internet of Things”, Bruxe- lles, Belgium, 2006.

[tel11] Fundación telefónica. Smart Cities: un primer paso hacia la internet de las cosas. Gran Via, 28, Madrid, 2011.

[TSH09] Ioan Toma, Elena Simperl, y Graham Hench. A joint roadmap for semantic technologies and the internet of things. En Proceedings of the Third STI Road- mapping Workshop, Crete, Greece, volume 1, 2009.

[VAG13] Athena Vakali, Lefteris Angelis, y Maria Giatsoglou. Sensors talk and hu- mans sense towards a reciprocal collective awareness smart city framework. En Communications Workshops (ICC), 2013 IEEE International Conference on, páginas 189–193. IEEE, 2013.

[VSV+13] F.J. Villanueva, M.J. Santofimia, D. Villa, J. Barba, y J.C. Lopez. Innovative Mobile and Internet Services in Ubiquitous Computing (IMIS), 2013 Seventh International Conference on. páginas 445–450, July 2013.

[WLZZ12] Jiafu Wan, Di Li, Caifeng Zou, y Keliang Zhou. M2m communications for smart city: An event-based architecture. En Computer and Information Tech- nology (CIT), 2012 IEEE 12th International Conference on, páginas 895–900. IEEE, 2012.

197

Este documento fue editado y tipografiado con LATEX empleando la clase esi-tfg que se puede encontrar en: https://bitbucket.org/arco group/esi-tfg

[Respeta esta atribución al autor]

199