---
# System prepended metadata

title: Análisis de rendimiento paquetes LoRaWAN
tags: [academic, technical doc]

---

# Análisis de rendimiento paquetes LoRaWAN

* **Estudiante**: Bibiana Mollinedo Rivadeneira
* **Cátedra**: Redes de Información
* **Año**: 2019

## Resumen

Se simulan paquetes provenientes de una red LoRaWAN, se implementan servidores de red y de aplicación de la misma y se realiza un **análisis comparativo** de los diferentes **protocolos** de transmisión de datos entre servidor de red y servidor de aplicación:

* **MQTT**
* **HTTP** (API)

Describiendo cada uno de ellos así como mediante capturas y análisis de paquetes, haciendo hincapié en características de **latencia** y **overhead**.

Se concluye respecto a ventajas  desventajas según contextos y aplicaciones en el campo de IoT.

## Sobre este documento

**“Desarrollo de Prototipo de solución IoT basado en tecnología LoRaWAN”** se produce en el contexto de una práctica profesional supervisada para culminar la carrera de Ing. en Telecomunicaciones, en la Universidad Nacional de Río Cuarto por Bibiana Rivadeneira, bajo la tutoría de Jonathan Sanchez y convenio entre UNRC y Fonexa S.A.

Este documento es de libre acceso, permite modificación y redistribución, apostando al cumplimiento de la [Ley 26899: Repositorios digitales institucionales de acceso abierto.](https://www.argentina.gob.ar/normativa/nacional/ley-26899-223459)

<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Licencia Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br />Esta obra está bajo una <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Licencia Creative Commons Atribución-CompartirIgual 4.0 Internacional</a>.

Este es un resumen legible por humanos (y no un sustituto) de la licencia. Advertencia. 

Usted es libre de: 
* **Compartir** — copiar y redistribuir el material en cualquier medio o formato 
* **Adaptar** — remezclar, transformar y construir a partir del material para cualquier propósito, incluso comercialmente. 
 
* La licenciante no puede revocar estas libertades en tanto usted siga los términos de la licencia 

Bajo los siguientes términos:

* **Atribución** — Usted debe dar crédito de manera adecuada, brindar un enlace a la licencia, e indicar si se han realizado cambios. Puede hacerlo en cualquier forma razonable, pero no de forma tal que sugiera que usted o su uso tienen el apoyo de la licenciante. 
* No hay restricciones adicionales — No puede aplicar términos legales ni medidas tecnológicas que restrinjan legalmente a otras a hacer cualquier uso permitido por la licencia. 
***

## Índice de contenidos

[TOC]

## Objetivos

### Generales

* Resforzar conceptos de redes de datos.
* Implementar y analizar herramientas de redes de datos LoRaWAN.
* Capturar y analizar paquetes de protocolos de datos.

### Específicos

* Realizar una breve introducción a la tecnología LoRaWAN.
* Implementar de servidores de red y de aplicación de red LoRaWAN.
* Simular de paquetes para los diferentes protocolos de comunicación, captura y análisis de los mismos.
* Confeccionar conclusiones sobre ventajas y desventajas según diferentes contextos y aplicaciones.

## Metodología

Se realiza la búsqueda bibliográfica haciendo hincapié en protocolos de comunicación de tecnologías LoRaWAN, formato de frame LoRa, payload, y protocolos de comunicación entre servidores de red y de aplicación.

Se implementan los servidores de red y de aplicación, simulando los paquetes provenientes de gateways LoRa, según diferentes protocolos de comunicación, se capturan paquetes y se realizan análisis respecto a **latencia y overhead**.

Se confeccionan conclusiones.

## Marco teórico

### Sobre LoRaWAN

*Tecnología LPWAN (Low Power Wide Area Network - Redes de baja potencia y área amplia)* es un protocolo de comunicación y arquitectura de sistema, orientado a **[IoT](#IoT-gIoT)** *(Internet of Things - Internet de las cosas)* que implementa **[LoRa](#LoRa-dLoRa)**.

Dichas especificaciones adquirieron gran *"popularidad"* en el campo de **[IoT](#IoT-gIoT)**, algunos de los factores de lo anterior son:

* **Largo alcance**, un [gateway](#Gateway-dGateway) puede dar cobertura a dispositivos de toda una ciudad, esto es, alcance a distancias en kilómetros.

> El 13 de Julio de 2019, se logró un nuevo récord mundial de alcance con [LoRaWAN](#LoRaWAN-dLoRaWAN, con **766 km** de distancia y `25mW` de potencia de transmisión. 
> [Más información.](https://www.thethingsnetwork.org/article/lorawan-distance-world-record)

* **Bajo consumo**, el protocolo de comunicación de datos permite bajos requerimientos de energía (potencia) para la transmisión de datos.
* **Alta capacidad de la red**, la técnica de modulación empleada permite la comunicación entre un [gateway](#Gateway-dGateway) y múltiples nodos a diferentes distancias y tasas de transferencia.
* **Adaptabilidad**, la red soporta diferentes clases de nodos según los requerimientos, permitiendo adaptar la red a diferentes aplicaciones.
* **Bajo costo**, una red funcional puede ser implementada con dispositivos de bajo costo.
* **Seguridad**, implementa algoritmos robustos de encriptación.
* **Gran comunidad activa alrededor del mundo**.
* **Compatible con componentes open source**.

#### Arquitectura

La arquitectura general de una red [LoRaWAN](#LoRaWAN-dLoRaWAN) es como sigue:

[![](https://upload.wikimedia.org/wikipedia/commons/c/cc/ArquitecturaLoRa.png)](https://commons.wikimedia.org/wiki/File:ArquitecturaLoRa.png)

*Arquitectura general de una red [LoRaWAN](#LoRaWAN-dLoRaWAN)* de brivadeneira / [CC BY SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.en)

* **End-points**: Se comunican con uno o más gateways según el protocolo LoRa.
    * **Sensor**: *(→)* Registra medición de una magnitud física y la transmite a los gateways. *Ej: sensor de temperatura, de presión, de nivel.*
    * **Actuador**: *(↔)* Según dato recibido desde la red *modifica* uno o más parámetros del entorno. *Ej: LED, relé.*
* **Gateways**: *(↔)* Se comunican con end-points según protocolo LoRa, así como con *-uno o más-* servidores de red por *Ethernet, WiFi o 3G/4G*.
* **Servidor de red**: *(↔)* Se comunica con gateways y servidor de aplicación a través de red de datos.
* **Servidor de aplicación**: *(↔)* Se comunica con dispositivos del usuario, así como servidor de red. Provee servicios al usuario, autentica dispositivos, etc.

#### Especificaciones técnicas

A continuación se exponen las especificaciones técnicas de interés de [LoRaWAN](#LoRaWAN-dLoRaWAN).

#### Cifrado

[LoRaWAN](#LoRaWAN-dLoRaWAN) implementa **[AES](#AES-gAES)-CTR** en el payload del tráfico de la red, así como **[AES](#AES-gAES)-CMAC** en el campo de *MIC, Código de Integridad del Mensaje*

#### Frecuencia de trabajo

En Argentina, la banda de frecuencias de trabajo para una red LoRaWAN es **`902 - 928 MHz`**, (915-928 MHz usable). 

*Ver pag. 8, "Table 1: Channel Plan per Country" en Anexo 1: LoRaWAN Regional Parameters (v1.1)*.

##### Normativa Argentina

El rango de frecuencias de trabajo corresponde a la lista de [Bandas no licenciadas](https://www.enacom.gob.ar/bandas-no-licenciadas_p680):

> Conviene destacar que el Reglamento de Radiocomunicaciones de UIT ha destinado a nivel mundial (y en algún caso, regional) bandas para uso primario para las aplicaciones Industriales, Científicas y Médicas (ICM). La Nota de Pie 5.150 dice:
> "Las bandas *(...)* **`902-928MHz` en la Región 2 (frecuencia central 915MHz)**, *(...)*, están designadas para aplicaciones industriales, científicas y médicas (ICM). Los servicios de radiocomunicación que funcionan en estas bandas deben aceptar la interferencia perjudicial resultante de estas aplicaciones."

Según la [Cuadro de atribución de bandas de frecuencias de la República Argentina](https://www.enacom.gob.ar/multimedia/noticias/archivos/201904/archivo_20190416044315_5617.pdf), la banda comprendida entre los **`915 MHz y 928 MHz`** *(ver pag 188, nótese que no comienza en `902 MHz`)*, corresponde a 
* **"Servicio TIC para banda de frecuencia de uso compartido"**.
* Tipo de servicio FIJO/MOVIL de *Uso Privado – Prestador*.
* Bajo **[resolución 581MM18](https://www.enacom.gob.ar/multimedia/normativas/2018/res581MM.pdf)**, la que establece los siguientes niveles de trabajo:
    * Potencia Máxima del Transmisor (Conducida) `30dBm`.
    * Potencia Máxima del Transmisor (P.I.R.E.) `36dBm`.

#### Ocupación espectral

La distribución espectral es según la norma **AU915-928 US902-928**, como sigue:

[![](https://upload.wikimedia.org/wikipedia/commons/thumb/2/27/EspectroAU915-928LoRa.png/800px-EspectroAU915-928LoRa.png)](https://commons.wikimedia.org/wiki/File:EspectroAU915-928LoRa.png)

*"AU915-928 LoRa v1.1"* de brivadeneira / [CC-BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/) 

* **Upstream**
    * 64 canales numerados de 0 a 63 de **`125kHz`** de ancho de banda, y **`200kHz`** entre ellos. El primero en **`915.2MHz`** y el último en **`927.1MHz`**. *(Verde)*.
    * 8 canales numerados de 64 a 71 de **`500kHz`** de ancho de banda, y **`1.6MHz`** entre ellos. El primero en **`915.9MHz`** y el último en **`927.1MHz`**. *(Azul)*.
*  **Downstream**
    * 8 canales numerados de 0 a 7 de **`500kHz`** de ancho de banda, y **`600kHz`** entre ellos. El primero en **`923.3MHz`** y el último en **`927.5MHz`**. *(Amarillo)*.

> NOTA: En Argentina existe un consenso de usar los canales 8 a 15 de la especificación AU915 p **AU915 sub-band 2**, Para implementación de la red de código abierto TTN.

#### Formato de las tramas

Las tramas *(frames)* del protocolo LoRa posee una estructura formada por las capas **física**, **MAC** y superiores *(aplicación)*:

[![](https://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/LoRaFrameFormat.png/800px-LoRaFrameFormat.png)](https://commons.wikimedia.org/wiki/File:LoRaFrameFormat.png)

*"LoRa Frame Format"* de brivadeneira / [CC-BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/) 

* **Capa física** *-azul-* (*Physical Layer Frame*): La trama LoRa comienza con un 
    * **Preámbulo**: Además de cumplir la función de *sincronismo*, define el *esquema de modulación de paquetes*. Duración típica del preámbulo: `12.25 Ts.`
    * **Encabezado + CRC** *(Header)*: Contiene información sobre el *tamaño* del [payload](#Payload-gPayload), si el *[CRC](#CRC-gCRC)* del [payload](#Payload-gPayload) de `16-bit` está o no presente en la trama. *Sólo los frames del enlace de subida contienen el campo [CRC](#CRC-gCRC)*. Tamaño de `20 bits`.
    * **Payload**:  *-anaranjado-* *(PHY Payload)* - `0-96 bits`
        * **Capa MAC**.
            * **MAC Header**: Define la versión del protocolo así como el tipo de mensaje.
            * **MAC Payload**: *-verde-*  Contiene *join-request* o *join-access*, empleados en el proceso de activación de un end-point. El MAC Payload es gestionado por la *capa de aplicación*, está conformado por:
                * **Frame Header**:  *-violeta-* 
                    * **Dirección de dispositivo**: los primeros`8 bits` identifican la red, los demás se asignan deforma dinámica durante el inicio de sesión e identifican al dispositivo en la red.
                    * **Frame Control**: `1 byte`, contiene información de control de la red como ser implementar o no velocidad de *subida* especificada por el [gateway](#Gateway-dGateway), [ACK](#ACK-gACK) del mensaje anterior, si el [gateway](#Gateway-dGateway) tiene más datos para transmitir.
                    * **Frame counter** para el número de secuencia.
                    * **Frame options**: datos para cambiar configuración como velocidad de transmisión, potencia de transmisión y validación de conexión.
                * **Frame Port**: Valor determinado según el tipo de aplicación.
                * **Frame Payload**: Datos a enviar a la red. Se cifra con la AppSKey mediante el algoritmo [AES](#AES-gAES) 128.

            * **MIC** *(Message Integrity Code)*: Resultado de computar el header y payload MAC con una NwkSKey.

#### Formato de Payload 

(*Frame Payload*)

A continuación se describen los formatos de [payload](#Payload-gPayload) bien conocidos:

##### CBOR

*Concise Binary Object* ([RFC 7049](https://cbor.io))

Formato diseñado para un tamaño de código extremadamente pequeño, por ende un tamaño de mensaje pequeño y extensibilidad sin la necesidad de negociar la versión.

* **Estructura de datos [JSON](#JSON-gJSON)**: Soporta objetos de tipo `number`, `string`, `array`, `map`, `bool`. No requiere un esquema en particular. Pero requiere codificar objetos como claves, gráficos o valores sensados, usualmente se realiza en `base64`, también es posible la codificación binaria *(procesamiento más veloz, impelmentación simple)*.

* **"tags"**: Definidos como mecanismo de identificación de **información adicional** al modelo básico. Tanto futuras versiones del estándar como *terceros* pueden definir tags.

Se puede implementar con numerosos lenguajes de programación incluyendo *Python*, *C* y hasta *Scratch*.

Ejemplo simple:

```jsonld
{"Fun": true, "Amt": -2}  
```

##### Cayenne LPP

*[Cayenne Low Power Payload](https://github.com/myDevicesIoT/CayenneLPP)*

El formato de payload para redes [LoRaWAN](#LoRaWAN-dLoRaWAN). Es compatible con reglas de **restricción de tamaño** por debajo de `11bytes`, lo que permite a un dispositivo enviar múltiples datos a la vez.

Además, permite enviar diferentes datos sensados en *diferentes frames*. Para ello, cada dato debe acompañarse de un prefijo de `2bytes`:
* **Data Channel:** Identifica unívocamente a un sensor en los frames. Por ejemplo: *“indoor sensor”*
-   **Data Type:** Identifica el *tipo de dato* en el frame, por ejemplo *“temperature”.*

* **Estructura del payload**:

| 1 Byte | 1 Byte | N Bytes | 1 Byte | 1 Byte | M Bytes | ... |
|-----------|------------|---------|-----------|------------|---------|-----|
| Data1 Ch. | Data1 Type | Data1 | Data2 Ch. | Data2 Type | Data2 | ... |

* **Tipos de datos** *(Data type)* Corresponde a los lineamientos de la *IPSO Alliance Smart Objects*, identificando los tipos con un ID de objeto. 
    * **LPP Data Type**: Identificador de `1byte` que se corresponde con el identivicador IPSO y puede convertirse de manera sencilla. Por ejemplo:

```python
LPP_DATA_TYPE = IPSO_OBJECT_ID - 3200
```

Donde `3200` es el ID IPSO, mientras que el ID LPP es `0` y se corresponde con una entrada digital.

Ejemplo de payload enviando *dos datos sensados a la vez* :

| Payload (Hex) | 03 67 01 10 05 67 00 FF |  |
|---------------|-------------------------|---------------------|
| Data Channel | Type | Value |
| 03 ⇒ 3 | 67 ⇒ Temperature | 0110 = 272 ⇒ 27.2°C |
| 05 ⇒ 5 | 67 ⇒ Temperature | 00FF = 255 ⇒ 25.5°C |

Compatible con `Arduino`.

##### Endpoints 

El módulo de adquisición de datos tiene como funcionalidad el sensado de magnitudes físicas de interés, *(según aplicación, temperatura, presión, humedad, nivel, etc)*. Se conecta directamente con el de transmisión según tecnología [LoRaWAN](#LoRaWAN-dLoRaWAN).

En el diagrama general de la arquitectura de la red [LoRa](#LoRa-dLoRa) se denominan *[end-point](#Endpoints-Endpoints)s*.

##### Factor de ensanchado vs tasa de bits

El factor de ensanchado de las señales enviadas en una red [LoRa](#LoRa-dLoRa), defindo como: $SF = \frac{chip\_rate}{symbol\_rate}$, el cociente entre la cantidad de pulsos por segundo y la cantidad de símbolos por segundo, varía entre 7 y 12 según normativa regional e impacta directamente en la tasa de bits como sigue: 

$bit rate = SF·\frac{Bw}{2^{SF}}$

A continuación se muestran las tasas de bits, según configuración física correspondiente a normativa `AU915-928`

| DataRate | Configuration | Bit rate [bit/sec] |
|----------|----------------------|--------------------|
| 0 | LoRa: SF12 / 125 kHz | 250 |
| 1 | LoRa: SF11 / 125 kHz | 440 |
| 2 | LoRa: SF10 / 125 kHz | 980 |
| 3 | LoRa: SF9 / 125 kHz | 1760 |
| 4 | LoRa: SF8 / 125 kHz | 3125 |
| 5 | LoRa: SF7 / 125 kHz | 5470 |
| 6 | LoRa: SF8 / 500 kHz | 12500 |
| 7 | RFU |  |
| 8 | LoRa: SF12 / 500 kHz | 980 |
| 9 | LoRa: SF11 / 500 kHz | 1760 |
| 10 | LoRa: SF10 / 500 kHz | 3900 |
| 11 | LoRa: SF9 / 500 kHz | 7000 |
| 12 | LoRa: SF8 / 500 kHz | 12500 |
| 13 | LoRa: SF7 / 500 kHz | 21900 |
| 14 | RFU |  |
| 15 | Defined in LoRaWAN |  |

*Ver tabla 35, pag. 38 de Anexo 1: LoRaWAN Regional Parameters (v1.1)*

### MQTT

*(**M**essage **Q**ueuing **T**elemetry **T**ransport)* Transporte de mensajes de telemetría por colas.

#### Breve introducción al protocolo

MQTT se diseña para intercambiar grandes cantidades de datos entre dispositivos de una red IoT -*(M2M, embebidos o aplicaciones móviles)*- bajo la pila de protocolos TCP/IP, de manera agnóstica a sus tecnologías y rendimientos, pensado para generar mensajes **ligeros**, en redes **inestables**, de **ancho de banda limitado** y con nodos de **baja potencia**, con rendimiento que roza el **tiempo real**.

El mecanismo de intercambio *bidireccional* de mensajes de tipo suscripción-publicación se basa en un **broker** *(intermediario o negociador)*, bajo un paradigma de orientado a **eventos** y de **baja latencia.** Provee seguridad y escalabilidad.

#### Fundamentos

Todos los clientes se comunican con el **broker** o *servidor*, éste se encarga de la autenticación y autorización de los mismos. Un cliente puede **publicar** un mensaje, enviandolo al servidor, o puede *"estar interesado en recibir cierto tipo de mensajes"*, por lo que se **suscribe** para hacerlo. El broker recibe los mensajes publicados y los distribuye a los clientes suscriptos a ese tipo de mensajes.

##### Autenticación

El cliente envía un paquete **CONNECT**.

[![](https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/MQTT_autenticacion.png/800px-MQTT_autenticacion.png)](https://commons.wikimedia.org/wiki/File:MQTT_autenticacion.png) 
"MQTT autentication" de brivadeneira / [CC BY SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.en)

* **ClientID**: `string` único que identifica a los clientes, si el campo está vacío, el servidor genera uno.
* **CleanSession**: `bool`, indica cómo proceder cuando in cliente se desconecta, si está seteado en `1` o `True`, se descarta toda información relacionada con la sesión. Si se setea en `0` o `False`, el servidor almacena los datos de la sesión y cuando el cliente se reconecta, gozade una sesión persistente.
* **UserName**: `bool`, indica si el cliente desea especificar un nombre de usuario o no con `True`/`1` o `False`/`0` correspondientemente y especificarlo en el campo `Userfield`.
* **password**: `bool`, indica si el cliente desea especificar una contraseña de usuario o no con `True`/`1` o `False`/`0` correspondientemente y especificarlo en el campo `password`.

* **ProtocolLevel**: Indica la versión de MQTT que debe usar el broker.
* **KeepAlive**: Tiempo en segundos al cabo del cual el cliente debe enviar mensajes de control al servidor. Si el parámetro es `0`, el cliente debe enviar un `PINGREQ` o ping request para indicar al servidor que continúa conectado, al que responde el servidor con un `PINGRESP`. Si nada de lo anterior sucede, la conexión se cierra.
* **Will, WillQoS, WillRetain, WillTopic y WillMessage**: Indican al servidor almacenar o no el último mensaje de la sesión, la calidad de servicio del último mensaje, si se debe mantener el último mensaje o no, correspondientemente. Si `Will` es `1` o `True`, se deben especificar `WillMessage` y `WillTopic`, si el cliente se desconecta, el servidor publica el mensaje en el tópico correspondiente, con la calidad de servicio especificada.

El servidor responde con un paquete **CONNACK** con los siguientes campos:

* **SessionPresent**: (Según *CleanSession*, `1`/`True` → `0`/`False` (no requiere almacenar sesión), `0`/`False` → `1`/`True` (sesión persistente))
* **ReturnCode**: Indica resultado de la autenticación según:

| ReturnCode | Descripción |
|------------|----------------------------------------------------------------------|
| 0 | Conexión aceptada. |
| 1 | Conexión rechazada por no soportar versión de MQTT solicitado. |
| 2 | Conexión rechazada por haber sido denegado el `ClientId` solicitado. |
| 3 | Conexión rechazada, si bien la red está disponible, no lo está MQTT. |
| 4 | Conexión rechazada por usuario o contraseña incorrectos. |
| 5 | Conexión rechazada por haber fallado la autenticación. |

##### Suscripción

El cliente envía un paquete **SUSCRIBE** para *suscribirse* a uno o más tópicos con un `PacketId` en el header y uno o más pares `Topic`, `QoS` → `"topic/1"`, `0`.

[![](https://upload.wikimedia.org/wikipedia/commons/thumb/8/8f/MQTT_suscribe.png/800px-MQTT_suscribe.png)](https://commons.wikimedia.org/wiki/File:MQTT_autenticacion.png)

"MQTT suscribe" de brivadeneira / [CC BY SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.en)

El broker responde con un paquete **SUBACK** con el mismo `PacketId` y un `ReturnCode` según:

| ReturnCode | Descripción |
|------------|--------------------------------------------|
| 0 | Suscripción exitosa con un máximo QoS de 0 |
| 1 | Suscripción exitosa con un máximo QoS de 1 |
| 2 | Suscripción exitosa con un máximo QoS de 2 |
| 128 | Falló suscripción |

##### Publicación

Una vez que el cliente se conectó exitosamente con el broker, puede comenzar a **publicar** mensajes, enviando paquetes **PUBLISH**.

[![](https://upload.wikimedia.org/wikipedia/commons/thumb/3/3f/MQTT_publish.png/800px-MQTT_publish.png)](https://commons.wikimedia.org/wiki/File:MQTT_publish.png)

"MQTT publish" de brivadeneira / [CC BY SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.en)

* **PacketId**: Según `QoS`, `0` → `0`/`null`, `1/2` → `!=0`
* **Dup**: Según `QoS`, `0` → `0`/`null`, `1/2` → `!=0`, en este último caso el servidor reenvía el mensaje publicado si no se recibió ACK de los clientes suscriptos.
* **QoS**: Nivel de QoS para el mensaje. De ser `0`, ante un mensaje de publicación, el broker no responde, lo envía a los clientes suscriptos. Para valores distintos de `0`, se realiza interacción extra entre cliente que publica y broker.
    * **0**: Máximo una entrega, ofrece la misma garantía que TCP, el servidor envía el paquete una vez, el cliente no devuelve ACK, el servidor no almacena el paquete para reenvío ni planifica ninguna otra comunicación luego de la entrega. *Baja sobrecarga*, *no hay garantía*.
    * **1**: Mínimo de una entrega, el servidor envía el paquete, pero lo almacena a la espera un `ACK` del cliente, hasta entonces, reenvía el paquete. *Garantiza entrega*, *paquetes duplicados*.
    * **2**: Exactamente una entrega, el servidor envía un paquete, recibe un paquete `PUBREC`, al que responde con un `PUBREL` y espera un `PUBCOMP` considerado como ACK, y garantía de exactamente una entrega del paquete. *Garantía de entrega*, *no hay sobrecarga*, *datos críticos*.
* **Retain**: `1/True`, `0/False`, retiene o no el mensaje, si se retiene, es enviado a los clientes que se suscriban al tópico en el futuro.
* **TopicName**: `string` que indica el nombre del tópico, responden a una jerarquía y usan "/" como delimitador, por ejemplo: `"sensors/drone01/altitude"`.

> Los datos del payload son agnósticos al formato, es decir que puede contener un `JSON`, un `XML` o un `binario`.

El cliente puede enviar un paquete **UNSUSCRIBE** para *desuscribirse* a uno o más tópicos con un `PacketId` en el header y uno o más pares `Topic`, `QoS` → `"topic/1"`, `0`.

> Recomendaciones para nombres de tópicos:
> Crear directorios jerárquicos separados por "/", por ejemplo: `sensors/drone01/altitude`.
> NO usar: "+", "#" ni "$".

#### Seguridad

Se pueden implementar técnicas de seguridad para la comunicación bajo MQTT en tres diferentes capas:

* **Red (3)**: VPN (Virtual Private Network).
* **Transporte (4)**: TLS (Transport Layer Security), las comunicaciones MQTT viajan por TCP, por defecto no están cifradas, se puede usar TLS para asegurar cifrado e integridad, se denomina **MQTTS**.
* **Aplicación (5)**: Se pueden implementar funcionalidad de autenticación y autorización empleando el `ClientId`.

##### Mosquitto

Borker o Server Open source compatible con MQTT.

### HTTP REST API

#### REST

**RE**presentational **S**tate **T**ransfer *(transferencia de estado representacional)* es un estilo de arquitectura  de software para sistemas distribuidos como la Web. 

El término se originó en el año 2000, en una tesis doctoral sobre la web escrita por Roy Fielding, uno de los principales autores de la especificación del protocolo HTTP, ante la crisis de escalabilidad.

#### REST API

Los servicios web *"sirven"* a un sitio u aplicación. Los clientes usan **I**nterfaces de **P**rogramación de **A**plicaciones para comunicarse con servicios web. Una API ofrece un conjunto de datos y de funciones para facilitar la interacción entre programas y les permite intercambiar infrormación. Una API web puede ser descripta como *la cara* de un servicio web, escuchando y respondiendo directamente a los pedidos de los clientes.

Una API en la que se aplica el estilo de arquitectura REST, es una REST API.

[![](https://upload.wikimedia.org/wikipedia/commons/3/36/Web_API.png)](https://commons.wikimedia.org/wiki/File:Web_API.png)

"Web API" de brivadeneira / [CC BY SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.en)

Una REST API usa URIs (Uniform Resource Identifiers) como dirección del recurso que deben respetar el siguiente formato:

URI = scheme "://" authority "/" path [ "?" query ] [ "#" fragment ]

> * `/` debe separar jerarquías y no debe estar al final de una URI.
> * `-` se debe usar para facilitar la lectura de la URI y no se debe usar `_`
> * Se deben usar minúsculas.
> * Las URIs no deben incluir la extensión de los archivos.

REST API implementa el protocolo HTTP (v1.1), incluyendo los métodos, códigos de respuesta y cabeceras de mensajes.

#### Métodos HTTP

**GET**
El método GET  solicita una representación de un recurso específico. Las peticiones que usan el método GET sólo deben recuperar datos.

**HEAD**
El método HEAD pide una respuesta idéntica a la de una petición GET, pero sin el cuerpo de la respuesta.

**POST**
El método POST se utiliza para enviar una entidad a un recurso en específico, causando a menudo un cambio en el estado o efectos secundarios en el servidor.

**PUT**
El modo PUT reemplaza todas las representaciones actuales del recurso de destino con la carga útil de la petición.

**DELETE**
El método DELETE borra un recurso en específico.

**CONNECT**
El método CONNECT establece un túnel hacia el servidor identificado por el recurso.

**OPTIONS**
El método OPTIONS es utilizado para describir las opciones de comunicación para el recurso de destino.

**TRACE**
El método TRACE  realiza una prueba de bucle de retorno de mensaje a lo largo de la ruta al recurso de destino.

**PATCH**
El método PATCH  es utilizado para aplicar modificaciones parciales a un recurso.

## Procedimiento

> Se implementa el servidor en una distribución GNU/Linux Debian 4.19.

### Servidor de red/aplicación

**1.** Se requiere registro en [thethingsnetwork](https://www.thethingsnetwork.org/)
**2.** Click en avatar de usuario y luego en `consola`. A continuación seleccionar `Aplicaciones`:

![](https://i.imgur.com/ptdWS4E.png)

**3.** Click en `add aplication`:

![](https://i.imgur.com/ZiiYfbV.png)

**4.**  Una vez creada la aplicación, click en `devices` y `register device`

![](https://i.imgur.com/XR09sao.png)

**4.1.** Elegir un ID para el dispositivo, y click en `generate` para el campo `Device EUI`:

![](https://i.imgur.com/YJI3zuN.png)

**4.2.** En el *overview* del dispositivo, visualizar las claves en sistema hexadecimal *(presionando los símbolos `<>`)*.

![](https://i.imgur.com/aTrRETH.png)

### Simulación paquetes LoRa

Se emplea el simulador online [Mbed OS Simulator](https://labs.mbed.com/simulator), escrito en js y con ejemplos LoRa disponibles.

**5.** Elegir el ejemplo **LoRaWAN**:

![](https://i.imgur.com/XzoKLyr.png)

**5.1** Copiar y pegar las claves desde la aplicación *(paso 4.2)* y reemplazar en el código:

```javascript
// Device credentials, register device as OTAA in The Things Network and copy credentials here
static uint8_t DEV_EUI[] = { 0x00, 0x37, 0xD5, 0x78, 0x63, 0x16, 0xE6, 0x64 };
static uint8_t APP_EUI[] = { 0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x02, 0x38, 0x0C };
static uint8_t APP_KEY[] = { 0xB3, 0x9B, 0x30, 0x5F, 0xF1, 0xDF, 0xB4, 0x5B, 0xFA, 0xB5, 0x61, 0x3E, 0x4B, 0x30, 0xF7, 0x75 };

```

**5.2** Modificar el puerto a 1

```javascript
// The port we're sending and receiving on
#define MBED_CONF_LORA_APP_PORT     1
```

**6.** Click en `run`

**6.1** En `devices` -> `sim-1` -> `data` se pueden observar los paquetes generados:

![](https://i.imgur.com/z7A5vIJ.png)

**7.** Repetir los pasos 4 a 6 tantas veces como dispositivos se deseen simular.

Se simulan 5 dispositivos:

![](https://i.imgur.com/XbbyhQb.png)

En la pestaña `data`se pueden observar los paquetes simulados:

![](https://i.imgur.com/qzQKCZ8.png)

### Integración

#### MQTT

**Instalar Mosquitto**

```shell=sh
wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key
sudo apt-key add mosquitto-repo.gpg.key
cd /etc/apt/sources.list.d/
sudo wget http://repo.mosquitto.org/debian/mosquitto-stretch.list
sudo apt update
sudo apt install mosquitto
sudo apt install mosquitto-clients
```

**Iniciar el broker**

```shell=sh
mosquitto_sub -h <Region>.thethings.network -t "+/devices/+/events/activations" -u "<AppID>" -P "<AppKey>" -v
```

```shell=sh
mosquitto_sub -h eu.thethings.network -t '+/devices/+/events/activations' -u 'simulacion-lora' -P 'ttn-account-v2.Ry5fpvakBfsaUGz7FRjFh1YFJl3s18D9W4jW7ynlWz8' -v
```

*Enviar un mensaje desde el gateway simulado*.

Se puede observar en la consola de `mosquitto`:

```shell=sh
simulacion-lora/devices/sim-1/events/activations 
{"app_eui":"70B3D57ED002380C",
"dev_eui":"0037D5786316E664",
"dev_addr":"2601210B",
"metadata":{"time":"2019-10-09T23:30:59.946537221Z",
"frequency":868.3,
"modulation":"LORA",
"data_rate":"SF8BW125",
"airtime":53760000,"coding_rate":"4/6",
"gateways":[{"gtw_id":"eui-0242ee000084ee70",
"timestamp":1322089000,"time":"2019-10-09T23:30:59.939Z","channel":2,
"rssi":-35,
"snr":5,
"rf_chain":0}]}}
```

##### Análisis MQTT

**Instalar e iniciar wireshark**

```shell=sh
sudo apt install wireshark
sudo wireshark
```

**Escribir MQTT en filtros**

![](https://i.imgur.com/pbeLN0O.png)
*Captura MQTT*

###### Jerarquía de protocolos

`Statistics` -> `Protocol hierarchy`

![](https://i.imgur.com/uCa5ovi.png)
*Protocol Hierarchy Statistics, Wireshark*

###### Conversación entre Broker y cliente

`Statistics` -> `Conversation`

```YAML
---
-
 - Address A
 - Port A
 - Address B
 - Port B
 - Packets
 - Bytes
 - Packets A → B
 - Bytes A → B
 - Packets B → A
 - Bytes B → A
 - Rel Start
 - Duration
 - Bits/s A → B
 - Bits/s B → A
-
 - 192.168.0.20
 - 55794
 - 52.169.76.255
 - 1883
 - 5
 - 918
 - 2
 - 283
 - 3
 - 635
 - 1.800446844
 - 11.158864002
 - 202.8880358784034
 - 455.2434727306931
```

`Statistics` -> `Flow Diagram`

![](https://i.imgur.com/V2ZrBbL.png)
*Flow Diagram, Wireshark*

###### Latencia

Desde un paquete MQTT, sobre la capa de transporte TCP, se despliegan los datos de la pestaña `Timestamps`, click derecho y `Apply as a column`, lo que habilita en la captura los *delta* de tiempo:

![](https://i.imgur.com/vP3DHNi.png)

El mayor tiempo entre frames es de `60` segundos, pero se trata de un tiempo entre `ping request y response`, se toma como **delta de tiempo máximo** el más grande que corresponda a otro tipo de mensaje MQTT, es decir el paquete **11196** con delta de tiempo de ~`0.0014` segundos.

###### Sobrecarga (overhead)

Para analizar el **overhead** se aplican como columnas `Frame length` *(primer capa, física)* y `Msg length`, *(MQTT)*

![](https://i.imgur.com/WrXYp5A.png)

Se puede observar una sobre carga *(dada por la diferencia entre la longitud del mensaje y la longirud de frame)* que varía entre `66` y `69` bytes.

###### Seguridad

Para un paquete MQTT con un mensaje lora, es posible mirar el contenido del mensaje:

![](https://i.imgur.com/Fpp4L7m.png)

```JSON
{"app_eui":"70B3D57ED002380C",
"dev_eui":"0037D5786316E664",
"dev_addr":"26012979",
"metadata":{"time":"2019-10-10T01:22:38.970294643Z",
"frequency":868.5,
"modulation":"LORA",
"data_rate":"SF7BW125",
"airtime":26880000,
"coding_rate":"4/6",
"gateways":[{"gtw_id":"eui-0242ee000084ee70","timestamp":1623747000,
"time":"2019-10-10T01:22:38.962Z",
"channel":2,"rssi":-35,
"snr":5,"rf_chain":0}]}}
```

Dado que MQTT, por defecto, no implementa cifrado.

#### HTTP

En la aplicación creada en *thethingsnetwork*, click en `Integrations` -> `Add integrations`, seleccionar `HTTP Integration`:

![](https://i.imgur.com/3CwRjFR.png)
*HTTP integration*

Crear URL de API, ingresar en [requestbin](https://requestbin.com), `Create a Request bin`.

*Editar la URL del endpoint en configuración de aplicación*.

##### Análisis HTTP

**Escribir HTTP en filtros**

![](https://i.imgur.com/235eqCx.png)
*Captura HTTP*

Con vista en un *POST* lora *(columna Info)*, en la pestaña HTTP, y método POST seleccionar el post lora como filtro:

![](https://i.imgur.com/B5sFfR7.png)
*Captura POST lora api*

###### Jerarquía de protocolos

`Statistics` -> `Protocol hierarchy`

![](https://i.imgur.com/o6IgB4z.png)
*Protocol Hierarchy Statistics, Wireshark*

###### Conversación entre Broker y cliente

`Statistics` -> `Conversation`

```YAML
---
-
 - Address A
 - Address B
 - Packets
 - Bytes
 - Packets A → B
 - Bytes A → B
 - Packets B → A
 - Bytes B → A
 - Rel Start
 - Duration
 - Bits/s A → B
 - Bits/s B → A
-
 - 52.211.146.247
 - 192.168.0.20
 - 9
 - 7000
 - 0
 - 0
 - 9
 - 7000
 - 49.331159418
 - 44.471642003
 - 0
 - 1259.2294207671107

```

`Statistics` -> `Flow Diagram`

![](https://i.imgur.com/dwcbEcr.png)
*Flow Diagram, Wireshark*

###### Latencia

Desde un paquete HTTP correspondiente a un POST de lor api, sobre la capa de transporte TCP, se despliegan los datos de la pestaña `Timestamps`, click derecho y `Apply as a column`, lo que habilita en la captura los *delta* de tiempo:

![](https://i.imgur.com/hKEcwjP.png)

El mayor tiempo entre frames es de `9.87` segundos.

###### Sobrecarga (overhead)

Para analizar el **overhead** se aplican como columnas `Frame length` *(primer capa, física)* y `Content length`, *(HTTP)*.

![](https://i.imgur.com/0wvNKiU.png)

Se puede observar una sobre carga *(dada por la diferencia entre la longitud del mensaje y la longirud de frame)* promedio es de`635` bytes.

###### Seguridad

Para el caso de un POST de mensaje lora por HTTP (API), el contenido del mensaje **no es visible**, dado que está cifrado.

![](https://i.imgur.com/KdLRXOc.png)

## Resultados

| Parámetro | MQTT | HTTP (API) |
|-----------|------------|------------|
| latencia | 0.0014 [s] | 9.87 [s] |
| overhead | 69 bytes | 635 bytes |
| credenciales visibles | si | no |

## Análisis de los resultados

Ambos protocolos de aplicación, pero en particular de *integración* en el contexto de una red LoRaWAN, cumplen con el objetivo de servir los datos de dispositivos LoRa.

Para el relevamiento de los dos parámetros de interés, se observa una diferencia muy significativa que favorece a MQTT, sin embargo para este último protocolo las credenciales de autorización son transparentes.

> Se puede implementar una capa de seguridad con MQTTS.

## Conclusiones

MQTT resulta un protocolo de aplicación/integración versátil, de muy baja latencia y sobrecarga para aplicaciones de internet de las cosas, donde se requieren enviar pequeños mensajes y en algún contexto, puedan requerir ser entregados con urgencia.

HTTP sin embargo muestra robustez respecto a la seguridad del mensaje, implementando por defecto un cifrado del mismo.

## Proyección

Se proyecta un entorno de simulación con incremento de dispositivos y de mensajes enviados, para evaluar además las colisiones y retransmisiones, parámetros que impactan directamente en la latencia y en la confiabilidad de los datos.

Se considera valioso para la simulación la variación de los parámetros con modelos aleatorios, acercandose a un escenario real.

Posteriormente, se proyecta la implementación de dispositivos reales para una red LoRaWAN, pudiendo variar distancias, potencias, anchos de banda y tasas de datos.

## Bibliografía

Technical Marketing Workgroup 1.0, [**"LoRaWAN. What is it?"**](https://lora-alliance.org/resource-hub/what-lorawanr), [*LoRa Alliance*](https://lora-alliance.org/), Noviembre 2015.

[*LoRa Alliance*](https://lora-alliance.org/), [**"LoRaWAN Regional Parameters v1.0.3revA"**](https://lora-alliance.org/resource-hub/lorawanr-regional-parameters-v11rb), [LoRa Alliance](https://lora-alliance.org/resource-hub/lorawanr-regional-parameters-v103reva), Inc., 2017

[Cuadro de Atribución de Bandas de Frecuencias de la República Argentina](https://www.enacom.gob.ar/cuadro-de-atribucion-de-bandas-de-frecuencias-de-la-republica-argentina-cabfra-_p1588), CABFRA, Julio 2019.

[Resolución 581MM18](https://www.enacom.gob.ar/multimedia/normativas/2018/res581MM.pdf), Poder Ejecutivo Nacional, Septiembre 2018.

Admin (10 de Octubre de 2018). ["LoRa- (Long Range) Network and Protocol Architecture with Its Frame Structure"](http://www.techplayon.com/lora-long-range-network-architecture-protocol-architecture-and-frame-formats) [*Entrada en un blog*]. Recuperado de [Techplayon](http://www.techplayon.com).

[Carsten Bormann](mailto:cabo@tzi.org?subject=cbor.io), [RFC 7049 - Concise Binary Object Representation (CBOR)](https://cbor.io/), Octubre de 2013.

["LoRaWAN - OTA or ABP?"](https://static1.squarespace.com/static/560cc2c2e4b01e842d9fac18/t/5a938d38ec212d9451fbecf8/1519619387035/OTAA_or_ABPv3.pdf), Newie Ventures.

[Documentación oficial Semtech UDP](https://github.com/LoRa-net/packet_forwarder/blob/master/PROTOCOL.TXT), Semtech-Cycleo.

[Documentación oficial Basic Station Forwarder](https://doc.sm.tc/station/), Semtech Corp.

G. C. Hillar, [*MQTT Essentials - ALightweight IoT Protocol*](http://ebooks.blt4spd.com/ebooks/titles/2596/file/MQTT%20Essentials%20-%20a%20Lightweight%20-%20Gaston%20C.%20Hillar.pdf), Birmingham, UK: Packt Publishing Ltd, 2017.

