CoAP

De Wiki Cursos IFPR Foz
Ir para navegaçãoIr para pesquisar

CoAP

Referências: [1], [2], [3], [4]

Introdução ao CoAP

O CoAP (Constrained Application Protocol) (RFC7252) é uma alternativa mais leve ao HTTP, com alvo nos dispositivos limitados em termos de energia e interface de comunicação. O CoAP usa UDP, ao invés do TCP usado pelo HTTP, reduzindo o overhead de mensagens ocasionado pela abertura e encerramento de uma conexão TCP, assim como reconhecimentos e retransmissões.

O CoAP provê interação usando um modelo pedido/resposta (request/response) entre aplicações, com comunicação assíncrona por meio de mensagens UDP. Este modelo é semelhante ao modelo cliente/servidor usado no HTTP, porém, ambas as máquinas podem atuar nas duas funções, diferente do HTTP. O CoAP apresenta baixo overhead de cabeçalho e processamento e suporta URI (Uniform Resource Identifier) e Content-type.

Pode-se visualizar o CoAP em duas camadas, uma camada de mensagens interagindo de forma assíncrona com o UDP e uma camada de interações pedido/resposta usando métodos e códigos de resposta.

+----------------------+
|      Application     |
+----------------------+  \
|  Requests/Responses  |  |
|----------------------|  | CoAP
|       Messages       |  |
+----------------------+  /
|          UDP         |
+----------------------+

CoAP roda por padrão na porta UDP 5683.

REST (Representational State Transfer)

As mensagens CoAP, assim como o HTTP, seguem a arquitetura REST (Representational State Transfer) para criar, ler, atualizar ou apagar de dados de aplicação em servidores remotos.

Na arquitetura REST um servidor REST simplesmente provê acesso a recursos e um cliente REST acessa e apresenta os recursos. Cada recurso é identificado por uma URI (Uniform Resource Identifier), que é sua identidade global.

Um sistema com capacidade de aplicar os princípios de REST é chamado de RESTful.

Métodos RESTful
  1. GET - ler informação
  2. PUT - atualizar informação
  3. POST - criar uma nova informação
  4. DELETE - apagar informação

A arquitetura REST é fortemente influenciada pelas tecnologias Web, sendo o HTTP uma de suas instâncias mais relevantes.

Muitas aplicações de IoT que utilizam protocolos IP fazem uso publicadores MQTT (sensores) e subscritores MQTT (atuadores), mas podem também utilizar REST Web Services.

O CoAP é um protocolo de transferência RESTful para nós e redes com recursos restritos em termos de processamento, memória e consumo de energia.

URI (Uniform Resource Identifier)

Estrutura de uma URI:

coap://   host     [:port] path [? query] [#fragment]
parâmetros query :
?key1=value1&key2=value2 
lista de chave/valor separados por &.
#fragment 
é um marcador para um fragmento do próprio recurso.

Exemplo[5]:

          userinfo       host      port
          ┌──┴───┐ ┌──────┴──────┐ ┌┴┐
  https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top
  └─┬─┘   └───────────┬──────────────┘└───────┬───────┘ └───────────┬─────────────┘ └┬┘
  scheme          authority                  path                 query           fragment


Interação entre CoAP e HTTP

Por sua arquitetura REST, o CoAP pode ser integrado ao HTTP por meio de um proxy/cache, permitindo, por exemplo, que um usuário utilizando a Web e HTTP interaja com um dispositivo restrito que suporta o CoAP.

HTTP Client           Proxy           CoAP Server
     | HTTP GET /temp   |                  |
     +----------------->|  CON GET /temp   |
     |                  +----------------->|
     |                  |   ACK "22.5"     |
     |  200 OK "22.5"   |<-----------------+
     |<-----------------+                  |
     |             cache "22.5"            |
     |                  |                  |
     | HTTP GET /temp   |                  |
     +----------------->|                  |
     |  200 OK "22.5"   |                  |
     |<-----------------+                  |

Modelo de mensagens

O CoAP usa mensagens curtas com cabeçalho de tamanho fixo (4 bytes) que podem ser seguidas por opções e dados (payload). Cada mensagem contém um identificador (Message ID) usado para implementar o serviço de entrega garantida de mensagens.

Para a entrega garantida uma mensagem é marcada como confirmável (CON). Uma mensagem confirmável é retransmitida, usando um temporizador, até receber uma reconhecimento (ACK). Se o receptor não estiver habilitado a fornecer uma resposta adequada ele responde com a mensagem de reset (RST).

Client              Server
   |                  |
   |   CON [0x7d34]   |
   +----------------->|
   |                  |
   |   ACK [0x7d34]   |
   |<-----------------+
   |                  |

Uma mensagem que não requer confirmação é marcada como não confirmável (NON).

Client              Server
   |                  |
   |   NON [0x01a0]   |
   +----------------->|
   |                  |

Modelo pedido/resposta

Os pedidos e respostas são carregados por mensagens CoAP, as quais incluem o código do método e da resposta.

Os métodos utilizados pelo CoAP são GET, PUT, POST, e DELETE de modo similar ao HTTP.

Os métodos podem usar mensagens confirmáveis (CON) ou não confirmáveis (NON). A resposta, se tiver disponível, pode ser enviada imediatamente, confirmável ou não confirmável.

Client              Server       Client              Server
   |                  |             |                  |
   |   CON [0xbc90]   |             |   CON [0xbc91]   |
   | GET /temperature |             | GET /temperature |
   |   (Token 0x71)   |             |   (Token 0x72)   |
   +----------------->|             +----------------->|
   |                  |             |                  |
   |   ACK [0xbc90]   |             |   ACK [0xbc91]   |
   |   2.05 Content   |             |  4.04 Not Found  |
   |   (Token 0x71)   |             |   (Token 0x72)   |
   |     "22.5 C"     |             |   "Not found"    |
   |<-----------------+             |<-----------------+
   |                  |             |                  |
Client              Server
   |                  |
   |   NON [0x7a11]   |
   | GET /temperature |
   |   (Token 0x73)   |
   +----------------->|
   |                  |
   |   NON [0x23bc]   |
   |   2.05 Content   |
   |   (Token 0x73)   |
   |     "22.5 C"     |
   |<-----------------+
   |                  |

Se a resposta não estiver disponível imediatamente, pode ser enviada posteriormente em mensagem separada.

Client              Server
   |                  |
   |   CON [0x7a10]   |
   | GET /temperature |
   |   (Token 0x74)   |
   +----------------->|
   |                  |
   |   ACK [0x7a10]   |
   |<-----------------+
   |                  |
   ... Time Passes  ...
   |                  |
   |   CON [0x23bb]   |
   |   2.05 Content   |
   |   (Token 0x74)   |
   |     "22.5 C"     |
   |<-----------------+
   |                  |
   |   ACK [0x23bb]   |
   +----------------->|
   |                  |

Formato das mensagens

As mensagens CoAP são codificadas em binário, iniciando com um cabeçalho fixo de 4 bytes.

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |Ver| T |  TKL  |      Code     |          Message ID           |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |   Token (if any, TKL bytes) ...
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |   Options (if any) ...
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |1 1 1 1 1 1 1 1|    Payload (if any) ...
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Campos:

  • Ver: 1
  • T (Type): CON (0), NON (1), ACK (2) ou RST (3)
  • TKL: Comprimento variável do Token (0 a 8 bytes).
  • Code: Código da mensagem:
    • Class (3 bits): request (0), success response (2), client error response (4), server error response (5) ou signaling codes (7)
    • Detail (5 bits): Em caso de pedido, indica o método. Em caso de resposta indica o código da resposta.
Method:0.XX Success:2.XX Client Error:4.XX Server Error: 5.XX       Signaling Codes: 7.XX
0 EMPTY     1 Created    0 Bad Request     0 Internal Server Error  0 Unassigned
1 GET       2 Deleted    1 Unauthorized    1 Not Implemented        1 CSM
2 POST      3 Valid      2 Bad Option      2 Bad Gateway            2 Ping
3 PUT       4 Changed    3 Forbidden       3 Service Unavailable    3 Pong
4 DELETE    5 Content    4 Not Found       4 Gateway Timeout        4 Release
5 FETCH                  ...               5 Proxying Not Supported 5 Abort
6 PATCH
7 iPATCH
  • Message ID: Identificador da mensagem, usado para detectar duplicatas ou correspondências entre uma mensagem CON com a mensagem ACK/RST ou entre uma mensagem NON com uma mensagem RST (caso o nó não possa processar a mensagem).

Campos opcionais:

  • Token: Usado para correlacionar pedidos e respostas
  • Options: A especificação CoAP define um conjunto de opções, identificadas por números, para serem utilizadas nas mensagens.
  • Payload: Dados

Observação de Recursos CoAP

Uma característica importante do CoAP para aplicações de IoT é a possibilidade de observar recursos, recebendo atualizações, por exemplo, quando os dados de um sensor são atualizados.

Para observar recursos usa-se um GET com a opção observar:

Client                                      Server
   |                                          |
   |   CON GET /temp Observe: 0 Token: 0x3f   |
   +----------------------------------------->|
   |   ACK Observe: 20 Token: 0x3f "22,5"     |
   |<-----------------------------------------+
   |                                          |
   |                                          | temp change
   |   ACK Observe: 21 Token: 0x3f "22,8"     |
   |<-----------------------------------------+
   |            ACK Token: 0x3f               |
   +----------------------------------------->|
   |                                          |

Descoberta de Recursos CoAP

Outra característica do CoAP para aplicações de IoT é a possibilidade de descoberta de serviços ou recursos. Esta característica é importante para aplicações de comunicação máquina máquina.

Um servidor é descoberto por um cliente aprendendo a URI que referencia um recurso no servidor. Ou, pode utilizar mensagens CoAP multicast para descobrir servidores.

Clientes e Servidores CoAP

Algumas referências:

  • Artigo: (Porciúncula etal, 2018) [6]
  • Video: [7]

Agente Usuário CoAP para Chrome

Agente usuário CoAP desenvolvido por Kovatsch Matthias como extensão para o o navegador Chrome [8].

Cliente e Servidor CoAP para Ubuntu

coap-client e coap-server baseado na biblioteca libcoap.

Instalação Ubuntu 20.04:
sudo apt-get update
sudo apt-get install libcoap2

Biblioteca CoAP para Arduíno

Biblioteca CoAP-simple-library: [9], [10]

CoAP para Raspberry Pi

coap-client e coap-server baseado na biblioteca libcoap.

Instalação: Ver [11]

CoAP: Análise do protocolo com Arduíno e Wireshark

Para a análise do protocolo CoAP foram utilizadas as seguintes ferramentas
  • Arduíno e programas exemplo da biblioteca CoAP-simple-library (IP 192.168.0.30) ;
  • coap-server e coap-client: rodando em Ubuntu 18.04 (IP 192.168.0.13);
  • wireshark para captura e análise dos pacotes.

Cenário 1: Arduíno request e coap-server response

Cenário com Arduíno Leonardo (IP 192.168.0.30) rodando programa exemplo coaptest da biblioteca CoAP-simple-library, interagindo através de request (GET) com servidor coap-server (IP 192.168.0.13) rodando em Ubuntu 18.04.

O programa coaptest no Arduíno envia a cada 5s uma mensagem GET para o coap-server solicitando a hora relógio (time) e imprime no monitor serial.

Saída do monitor serial do Arduino
My IP address: 192.168.0.30
Setup Response Callback
Send Request
Coap Response got:
May 21 10:04:14
Send Request
Coap Response got:
May 21 10:04:19
Mostra a sequência de mensagens enviadas (Send Request) e as respostas recebidas do servidor (Coap Response got:) seguida da hora relógio.
Captura de pacotes com Wireshark

Mostra duas trocas de mensagens, cada uma incluindo um pedido CON (GET com confirmação exigida) e a resposta ACK (incluindo o time solicitado).

6--px

Detalhes da captura de pacotes
  • Destaque para o protocolo de transporte UDP e as portas CoAP padrão 5683 utilizados pelas mensagens.
  • Na primeira mensagem CoAP pode-se observar o Code (GET) e a URI [Uri-Path: coap://192.168.0.13/time] da solicitação.
  • O detalhe da mensagem mostra o tamanho reduzido da mensagem CoAP, 4 bytes de cabeçalho, mais as opções com o Uri-Path: coap://192.168.0.13/time.

Cenário 2: Arduíno request e coap-server response e coap-client request e Arduíno response

Cenário com Arduíno Leonardo (IP 192.168.0.30) rodando programa exemplo coapserver da biblioteca CoAP-simple-library, interagindo com um servidor coap-server rodando em Ubuntu 18.04 (IP 192.168.0.13) e também respondendo a requisições de um coap-client rodando no mesmo Ubuntu 18.04 (IP 192.168.0.13).

O programa coapserver no Arduíno também envia a cada 5s uma requisição (GET) para o coap-server solicitando a hora relógio (time) e imprime no monitor serial. Além disto, aceita requisições de um coap-client (PUT) que permite comandar um led conectado a uma porta do Arduíno.

Comando executado no coap-client
coap-client -e "0" -m put coap://192.168.0.30/light
para desligar o led
coap-client -e "1" -m put coap://192.168.0.30/light
para ligar o led
Captura de pacotes com Wireshark

Análise dos pacotes capturados
  • Na marca de tempo 9,41... o Arduíno requisita (CON GET) a hora relógio ao coap-server e recebe a resposta (ACK);
  • Na marca de tempo 11,79... o coap-client requisita (CON PUT) ao Arduíno para apagar led.
  • Na marca de tempo 14,26... uma nova requisição (CON PUT) com mesmo identificador (MID) pois não houve resposta imediata.
  • Nas marcas de tempo 14,4172... e 14,4187... as respostas (ACK) foram enviadas.
  • Na marca de tempo 14,4188... uma mensagem ICMP (Destination unreachable) foi enviada pelo coap-client ao Arduíno pois mesmo encerrou após o recebimento da primeira resposta.
  • Na sequência tivemos mais duas requisições (CON GET) de hora relógio pelo Arduíno ao coap-server e mais uma última requisição (CON PUT) pelo coap-client ao Arduíno.

Agente usuário Copper (Cu)

Outra maneira de interagir com o Arduíno rodando o coapserver para acionamento de leds é através da extensão Copper (Cu) no Google Chrome:

Referências

Evandro.cantu (discussão) 15h22min de 14 de maio de 2020 (-03)