• Nenhum resultado encontrado

Reconfiguração e novas funcionalidades para um servidor REST ONVIF: serviço de IO e configuração de descoberta

N/A
N/A
Protected

Academic year: 2020

Share "Reconfiguração e novas funcionalidades para um servidor REST ONVIF: serviço de IO e configuração de descoberta"

Copied!
82
0
0

Texto

(1)

Escola de Engenharia

Adriana Alexandra Oliveira Passos

Reconfiguração e novas

funcionalidades para um servidor REST

ONVIF: serviço de IO e configuração

de descoberta

(2)

Escola de Engenharia

Adriana Alexandra Oliveira Passos

Reconfiguração e novas funcionalidades

para um servidor REST ONVIF: serviço de IO

e configuração de descoberta

Dissertação de Mestrado Ciclo de Estudos

Conducentes ao Grau de Mestre em Engenharia de Telecomunicações e Informática

Trabalho efectuado sob a orientação de:

Professor Doutor Sérgio Adriano Fernandes Lopes

(3)
(4)

iv

Agradecimentos

“Nenhum caminho é longo demais quando um amigo nos acompanha.” (RALPH WALDO EMERSON)

Neste momento tão importante na minha vida em que completo mais um desafio não posso deixar de dizer, que sem o apoio e o incentivo de algumas pessoas, não teria sido possivel atingir esta meta. Como tal serve o presente texto para prestar os meus sinceros agradecimentos.

Em primeiro lugar agradeço à minha irmã, aos meus pais (em especial ao meu pai) por todo o apoio, pela paciência, pelo incentivo, por nunca me terem deixado desistir tão perto do fim. Agradeço sobretudo pelo apoio incondicional que sempre me deram ao longo da minha e meu percurso académico.

Ao Professor Sérgio Adriano Lopes agradeço toda a dedicação, toda a paciência e a disponibilidade total que demonstrou ao longo deste trabalho.

Aos meus amigos, em especial a uma amiga, Andreia Silva, agradeço por terem estado sempre presentes, pelo apoio que sempre me deram.

Em último gostaria de dedicar este trabalho aos meus pais e à minha irmã, sem o apoio deles nada disto teria sido possível.

(5)

v

Resumo

O ONVIF surge como uma especificação que pretende normalizar a interação com dispositivos multimédia. Esta necessidade deveu-se a uma enorme diversidade de protocolos, formatos e especificidades que as câmaras IP utilizam, e que obrigam a que as aplicações desenvolvidas para este tipo de dispositivos variem de fabricante para fabricante.

Com o rápido desenvolvimento da Internet e uma elevada adopção por parte dos utilizadores das aplicações web, surgiu a ideia de implementar uma aplicação web que seja capaz de configurar câmaras ONVIF, bem como disponibilizar acesso aos respectivos streams multimédia. Num trabalho de dissertação anterior, foi desenvolvida uma aplicação web que permite a configuração e acesso a algumas funcionalidades de câmaras ONVIF e pode ser utilizada em todos os dispositivos que possuam um browser.

Com a constante evolução das técnicas de programação direccionadas para a web, este é um trabalho em constante desenvolvimento. Por isso, este trabalho tem como objectivos principais acrescentar novas funcionalidades e a melhoria das que já existem, permitindo assim tirar mais proveito dos serviços ONVIF e com um melhor desempenho.

A arquitectura da aplicação web consiste num servidor que oferece uma API REST para as operações ONVIF e um cliente AJAX sem plugins que fornece uma interface gráfica para essas operações. O servidor é baseado numa biblioteca C que abstrai a comunicação ONVIF. Nesta dissertação adicionam-se ao servidor as funcionalidades do serviço de IO disponíveis na biblioteca C, a configuração dos parâmetros que controlam a descoberta de câmaras e a filtragem dos recursos REST que são devolvidos em cada serviço. Além disso, a configuração do servidor é alterada sem afectar a API web e no sentido de uma maior eficiência computacional. A implementação das novas funcionalidades é realizada tanto ao nível da biblioteca C como ao nível do processamento dos pedidos REST.

O resultado é um servidor REST ONVIF funcionalmente mais completo e que além de servir o cliente web, pode servir outros clientes como, por exemplo, Android, ou outras plataformas nativas para dispositivos móveis

(6)

vi

Abstract

ONVIF (Open Network Video Interface Forum) arises as specification that ensures interoperability between products regardless of manufacturer.

This need was due to a huge diversity of protocols, formats and specificities that IP cameras use, and require that applications developed to operate and configure these types of devices vary from manufacturer to manufacturer.

With the rapid development of the Internet and high adoption by end-users of web applications, there is the idea of implementing a web application that was able to configure ONVIF cameras, as well as provide access to their media streams. In a previous dissertation, a web application that allows configuration and access to some features of ONVIF cameras and can be used in all devices that have a browser was developed. With the constant evolution of programming techniques directed to the web, this is a work in progress. Therefore, this work aims primarily to add new features and improving existing ones, thus getting more out of ONVIF services and better performance.

The architecture of the web application is a server that provides a REST API for ONVIF operations and AJAX client without plugins that provides a graphical interface for these operations. The server is based on a C library that abstracts the ONVIF communication. In this thesis add to the server IO functionality of the service available in the C library, the configuration of parameters that control the discovery of cameras and filtering the REST resources that are returned for each service. In addition, the server configuration has changed without affecting the API web and towards a higher computational efficiency. The implementation of the new features is performed both in the C library as the processing of applications REST level..

The result is a more functionally complete REST ONVIF server and that besides serving the web client, can serve other customers, for example, Android, or other native platforms for mobile devices

(7)

vii

Índice

Agradecimentos ... iv Resumo... v Abstract ... vi Índice de Figuras ... ix Índice de Tabelas ... x Acrónimos ... xi 1 Introdução ... 1 1.1 Enquadramento ... 1 1.2 Motivação ... 2 1.3 Objectivos ... 3 2 Fundamentos ... 5 2.1 Protocolo ONVIF ... 5 2.2 Arquitectura do Servidor... 6 2.3 Biblioteca UMOC ... 7

2.4 API web do servidor ... 8

2.4.1 Devicemgmt ... 8

2.4.2 Media... 9

2.4.3 PTZ ... 11

2.4.4 Imaging ... 11

2.4.5 Formato de dados dos pedidos e das respostas ... 12

2.5 Descrição do Apache ... 13

3 Servidor REST ONVIF ... 17

3.1 Configuração ... 17 3.1.1 Servidor HTTP Apache ... 17 3.1.2 Servidor REST ... 18 3.2 FastCGI ... 21 3.3 Estrutura e Funcionamento ... 23 3.4 API web ... 25 3.4.1 DeviceManagement ... 26

(8)

viii

3.4.2 DeviceIO ... 30

3.5 Desenvolvimento do serviço DeviceIO ... 31

3.5.1 Classe Rest_io ... 31

3.5.2 Exemplo de Resultado ... 32

3.5.3 Tratamento de um pedido ao Serviço IO ... 33

4 Configuração da descoberta de câmaras... 35

4.1 Biblioteca UMOC ... 35

4.1.1 DiscoveryMode e RemoteDiscoveryMode ... 38

4.1.2 Discovery Proxy Addresses ... 39

4.2 Servidor ... 40

4.2.1 Funções de consulta ... 40

4.2.2 Funções de alteração... 42

4.2.3 Funções de Gestão dos Discovery Proxys... 43

4.3 Desenvolvimento do Programa de Teste ... 45

5 Conclusão ... 49

5.1 Discussão dos Resultados ... 49

5.2 Conclusões ... 51

5.3 Trabalho Futuro ... 52

6 Referências ... 53

Anexo A – Actualização Apache 2.2 para 2.4, antigo / novo ficheiro de configuração ... 54

Anexo B - Parâmetros das operações - objectos JSON ... 58

Anexo C – Serviço IO – exemplo de objectos JSON devolvidos ... 60

Anexo D – Resultados JSON obtidos para a configuração da descoberta ... 63

Anexo E – Testes efectuados com a aplicação de teste criada para o debug às novas funcionalidades da biblioteca UMOC ... 67

(9)

ix

Índice de Figuras

Figura 1 - Arquitectura do Servidor ... 6

Figura 2 - Diagrama DeviceManagement ... 9

Figura 3 - Diagrama das funcionalidades Media ... 10

Figura 4 - Diagrama das funcionalidades PTZ ... 11

Figura 5 - Diagrama das funcionalidades Imaging ... 12

Figura 6 - Diagrama Geral de serviços e recursos do Servidor ... 25

Figura 7 - Diagrama DeviceManagement ... 26

Figura 8 - Funções de Descoberta ... 27

Figura 9 - Diagrama GetServices e GetServicesCapabilities ... 30

Figura 10 - Diagrama das funcionalidades DeviceIO... 30

Figura 11 - Mensagem JSON, resultado do Get ... 32

Figura 12 - Tratamento do Pedido ... 33

Figura 13 - Diagrama da função GetDiscoveryMode ... 41

Figura 14 - Diagrama da função SetDiscoveryMode... 43

Figura 15 - Fluxograma do Programa Main ... 46

Figura 16 - Fluxograma do Sub_menu1... 47

Figura 17 - Fluxograma do Sub_menu2... 48

(10)

x

Índice de Tabela

Tabela 1 - Diferenças Apache 2.2 / 2.4 ... 14

Tabela 2 - Comando instalar Apache ... 17

Tabela 3- Especificações do ficheiro antigo que foram eliminadas ... 19

Tabela 4 - Especificações do novo ficheiro de configuração ... 19

Tabela 5 - Formato pedidos/respostas para GET / PUT ... 27

Tabela 6 - Protótipo das funções ... 28

Tabela 7 - Classe Serviço do IO ... 31

Tabela 8- Stub ONVIF definido pelo gSOAP... 36

Tabela 9 - Criar e Configurar objecto SOAP... 36

Tabela 10 - Adicionar credenciais de autenticação no cabeçalho ... 37

Tabela 11 - Definir as variáveis de pedido e resposta para o objecto SOAP ... 37

Tabela 12 - Função soap_call para o GetDiscoveryMode ... 37

Tabela 13 - GetDiscoveryMode / GetRemoteDiscoveryMode ... 38

Tabela 14 - SetDiscoveryMode / SetRemoteDiscoveryMode ... 38

Tabela 15 - GetDPAddresses ... 39

(11)

xi

Acrónimos

API - Application Programming Interface

CGI - Common Gateway Interface

HTTP - Hypertext Transfer Protocol

HTTPS - Hyper Text Transfer Protocol Secure

HTML5 - Hypertext Markup Language, versão 5

JSON - JavaScript Object Notation

NVT - Network Video Transmitter

ONVIF - Open Network Video Interface Forum

PTZ - Pan, Titl and Zoom

IO - In / Out

REST - Representational State Transfer

SOAP - Simple Object Access Protocol

SSL - Secure Sockets Layer

SW - Serviço Web

W3C - World Wide Web Consortium

WWW - World Wide Web

XML - eXtensible Markup Language

IP- Internet Protocol

(12)

1

1 Introdução

1.1 Enquadramento

As câmaras de videovigilância que funcionam sobre IP, tem uma diversidade de protocolos, de formatos, e de especificações de configuração. O ONVIF (Open Network

Video Interface Forum) surge para responder a um desafio, permitir desenvolver

aplicações que manipulam vários tipos de equipamentos de quaisquer fabricantes [1], evitando assim a necessidade de se desenvolver uma aplicação diferente para cada um dos fabricantes/modelos de câmaras existentes no mercado.

O ONVIF (Open Network Video Interface Forum), é uma norma aberta e que garante a interoperabilidade independentemente do fabricante [1], e por isso é a norma mais utilizada no mercado de dispositivos multimédia IP. É baseado em serviços web e tem como foco as funcionalidades disponíveis nos dispositivos. O ONVIF utiliza um número significativo de normas web, como por exemplo o SOAP, WSDL, WS-Discovery, e para além disto possui várias especificações referentes aos serviços web que o constituem. Isto torna o processo de desenvolvimento de aplicações cliente sobre o mesmo algo complexo.

Com o objectivo de tornar mais simples o desenvolvimento de aplicações do lado do cliente para operar sobre câmaras ONVIF surgiu uma biblioteca C designada UMOC. Esta biblioteca fornece uma API de fácil utilização e elimina a necessidade de os integradores terem de lidar com a complexidade do processamento SOAP, permitindo um desenvolvimento mais fácil e rápido das aplicações. Esta é uma biblioteca desenvolvida em linguagem C, que por não ser uma linguagem interpretada garante uma boa gestão de recursos.

A biblioteca UMOC é implementada sobre um toolkit que suporta vários sistemas operativos, no entanto o desenvolvimento de uma aplicação cliente nativa e compatível ao nível do código fonte com as plataformas computacionais mais utilizadas (Linux,

Windows, MAC OS, Android) não é viável sobretudo devido à interface com o utilizador.

Temos assistido nos últimos tempos a um enorme crescimento das aplicações web (correm sobre browsers), sendo esta uma forma de tornar as aplicações “universais”, ou seja, independentes do sistema operativo. As aplicações web apresentam algumas

(13)

2 vantagens, estão sempre disponíveis e não obrigam à instalação de software, e oferecem uma maior protecção sobre o código do servidor pois este fica inacessível. O aparecimento do HTML5 foi o impulso para a expansão das aplicações web cliente, permitindo que estas se tornem compatíveis com um enorme número de dispositivos,

smartphones, PC’s, tablets, laptops, etc.

No mercado já se encontravam disponíveis aplicações web para câmaras IP, no entanto estas apenas permitem a configuração das câmaras e estão restritas ao modelo e ao fabricante. Com isto percebemos que não tiram partido da normalização oferecida pelo ONVIF. Num trabalho de dissertação foi desenvolvida uma aplicação web, capaz de configurar câmaras ONVIF, mas que não cobre todas as funcionalidades desse tipo de dispositivos. Esta aplicação consiste num serviço web que fornece uma API REST para as funcionalidades ONVIF da biblioteca UMOC e um cliente AJAX sem plugins.

1.2 Motivação

Apesar de já existir uma aplicação web capaz de configurar e aceder a dispositivos

ONVIF, o constante desenvolvimento da tecnologia torna possível introduzir melhorias e

até mesmo a implementação de novas funcionalidades. Partindo deste ponto existe a possibilidade de implementar novas funcionalidades ao nível da biblioteca UMOC e ao nível do Servidor, e até mesmo melhorar as que já existem. Aquilo que se pretende é dar continuidade ao trabalho desenvolvido, através de melhorias que possam ser feitas tanto do lado do cliente como do servidor e também o acréscimo de novas funcionalidades.

Noutra perspectiva a possibilidade de migrar a nosso servidor para uma nova versão do servidor Apache e preparar uma nova configuração que permita um melhor desempenho a nível da aplicação. Actualmente, utiliza-um modo de fazer o redireccionamento de pedidos do servidor HTTP para o serviço REST que é computacionalmente pesado.

Tendo em conta que a norma ONVIF sofreu algumas alterações, é importante que o trabalho já existente acompanhe essas alterações e evolua tal como a norma. Isso acontece neste trabalho em especial relativamente à funcionalidade de “Capabilities”, que sofreu alterações. Em cada serviço ONVIF existem funcionalidades opcionais, que as câmaras podem não implementar. Actualmente, o servidor REST fornece acesso às

(14)

3 URI de todos os recursos de cada serviço, independentemente de a câmara os suportar ou não.

Finalmente, o servidor ONVIF existente não suporta nem o serviço de IO nem a funcionalidade de configuração do modo de descoberta. Estas funcionalidades são obrigatórias para as câmaras ONVIF.

1.3 Objectivos

Num cenário em que já existe uma aplicação web capaz de configurar câmaras

ONVIF, bem como disponibilizar acesso aos respectivos dados multimédia, pretende-se

dar continuidade ao trabalho existente completando-o e melhorando-o em alguns aspectos.

Para tornar a aplicação existente mais completa pretende-se implementar as funcionalidades relativas ao serviço de IO ao nível do servidor REST, que já existem ao nível da biblioteca UMOC.

Com o objectivo de poder disponibilizar mais funcionalidades ao nível do Servidor, como por exemplo, a configuração do modo de descoberta de dispositivos ONVIF é necessário acrescentar em primeiro lugar essas novas funções à biblioteca UMOC e depois ao servidor.

Pretende-se filtrar essas URI fazendo uso da funcionalidade de GetCapabilities de cada serviço, de acordo com a versão 2.0 da norma. Essa funcionalidade tem que ser implementada desde o nível da biblioteca, que actualmente apenas suporta a operação GetCapabilities do serviço DeviceManagement.

Outro objectivo é optimizar o desempenho do lado do servidor, tentando encontrar uma nova configuração do servidor Apache, que seja mais simples da que já existe. Concretamente, procurar uma alternativa ao redireccionamento de pedidos para o serviço REST.

(15)
(16)

5

2 Fundamentos

2.1 Protocolo ONVIF

Fundado em 2008 pela Axis, Bosch e Sony [1], o ONVIF rapidamente ganhou força, apoiado pela maioria dos grandes fabricantes de equipamento de videovigilância, sendo no presente o mais adoptado.

Os dispositivos ONVIF são classificados por tipos: Network Video Transmitter (NVT),

Network Video Display (NVD), Network Video Storage (NVS) e Network Video Analytics (NVA). Neste trabalho os dispositivos abordados são os Network Video Transmitter

(NVT), que são câmaras que funcionam sobre IP.

O ONVIF adopta um número significativo de normas para serviços web (e.g., WSDL,

SOAP, WS-Discovery) para definir o protocolo de comunicação dos dispositivos e é

constituído por diversas especificações. A “Core Specification” [14], contextualiza o uso de WS-Discovery, WS-Security e WS-BaseNotification, e define os serviços Device

Management (DM) e Events, comuns a todos os dispositivos. Cada uma das outras

especificações define um serviço ONVIF [1] que para cada tipo de dispositivo é classificado como: obrigatório (M); obrigatório se o dispositivo tem uma característica relacionada (C); ou opcional (O). Um dispositivo NVT tem o seguinte conjunto de serviços: M = {Device Management, Events, Media, Streaming, Device IO}, C = {PTZ}, e O

= {Imaging, Video Analytics}.

Por exemplo no serviço DeviceManagement podemos saber se o dispositivo está configurado no modo de descoberta local ou descoberta remota, e esta configuração pode também ser alterada.

O serviço Media permite consultar e alterar as configurações media de um dispositivo: consultar e alterar perfis de media, obter a lista de video sources, consultar os URI para a captura de uma imagem, o URI de streaming de vídeo, etc.

O serviço PTZ permite, dado um perfil media do dispositivo, realizar movimentos PTZ. Esses movimentos podem ser absolutos, relativos ou contínuos. Permite também consultar e alterar os presets e consultar e alterar “home position” de um determinado perfil media.

(17)

6 O serviço Imaging, dado um video source de um dispositivo, permite consultar e alterar as suas configurações de imagem: brilho, contraste, sharpness, saturação, exposição, focagem, etc.

Um outro serviço é o DeviceIO, que tem como funcionalidades a possibilidade de consulta sobre as saídas físicas existentes, a alteração das configurações de uma saída física e também a alteração do seu estado entre o activo e o inactivo. Este serviço é uma nova funcionalidade implementada neste trabalho ao nível do servidor REST.

2.2 Arquitectura do Servidor

O Servidor implementado é um FastCGI, cujo serviço web se encontra alojado num servidor Apache. Este foi escolhido por dois motivos principais: é o servidor web de domínio livre mais utilizado e por ser desenvolvido em linguagem C, sendo que esta última característica é garantia de um bom desempenho. Para além disto o Apache proporciona um canal seguro e encriptado entre o cliente e o servidor, através da utilização do módulo SSL.

A utilização de uma arquitectura de FastCGI sobre um servidor HTTP permitir que cada programa execute como um processo isolado e na eventualidade de erros, afectar

(18)

7 apenas o cliente cujo pedido originou a falha. O FastCGI é implementado em C++, permitindo assim a linkagem com a biblioteca desenvolvidas em C (sendo o exemplo mais importante a UMOC. Pelo facto de utilizar linguagens não interpretadas o serviço web consegue um bom desempenho.

O serviço web segue a filosofia Rest [8] e as mensagens trocadas são do tipo JSON [6]. Para auxiliar o tratamento deste formato de dados foi utilizada a biblioteca

libjsoncpp [7] por ser uma biblioteca em C++, e ser uma das mais utilizadas e mais bem

documentadas.

2.3 Biblioteca UMOC

O protocolo ONVIF define que a comunicação entre os dispositivos de vídeo sobre IP (NVTs) é feita através de mensagens SOAP. Neste trabalho foi utilizada a biblioteca UMOC que implementa a troca de mensagens com as câmaras. Esta biblioteca foi desenvolvida utilizando o toolkit gSOAP.

O gSOAP é um toolkit que tem o código fonte disponível, é utilizado no desenvolvimento de web services SOAP/XML e aplicações XML, está disponível para várias plataformas, Linux, Windows e MacOS, e suporta as linguagens C/C++.

A partir dos ficheiros WSDL dos serviços ONVIF, o gSOAP gera stubs (código cliente) para enviar e receber as mensagens SOAP do ONVIF. A biblioteca UMOC acrescenta à camada de stubs, a abstracção de detalhes relativos ao gSOAP e uma definição mais amigável das estruturas de dados das mensagens.

De forma concreta e geral a camada da biblioteca UMOC acima dos stubs transforma uma API do tipo

int stub(contexto, endpoint, action, req, resp); em

int func(usr, pass, addr, req /resp);

Na qual já é integrada a autenticação. Outro aspecto a salientar é o facto de as operações ONVIF serem ou do tipo “get” ou do tipo “set” e de um modo geral ou têm dados para enviar ou para receber.

(19)

8

2.4 API web do servidor

Nesta secção é apresentada a API REST do servidor para cada um dos serviços. Na API herdada do trabalho anteriormente desenvolvido, o serviço IO não estava disponível.

2.4.1

Devicemgmt

Na API inicial o servidor permite o acesso aos endereços e capabilities dos vários serviços das câmaras utilizando uma operação ONVIF que foi descontinuada e se mantém apenas para compatibilidade com a versão 1.0 da norma. Essa operação chama-se GetCapabilities e pertence ao serviço DeviceManagement, como é visível no diagrama da figura 2. É esta função que obtém os endereços dos vários serviços do dispositivo e inclui as respectivas capabilities.

A URI de base deste serviço constitui a “home page” do servidor REST. Esta URI é tudo que o cliente precisa de saber sobre o servidor. Como se pode ver na figura 2, a partir daí o servidor devolve todas as URI’s subsequentes, concretizando o

Representational State-Transfer. Ao fazer o GET dessa URI o servidor devolve todas as URI’s do nível abaixo/seguinte, permitindo assim a navegação do cliente.

(20)

9 Figura 2 - Diagrama DeviceManagement

2.4.2 Media

O serviço Media permite consultar e alterar as configurações media de um dispositivo, como perfis de media, obter a lista de video sources, consultar as URI para a captura de uma imagem, a URI de streaming de vídeo, entre outros. A API está descrita na figura 3.

(21)

10 Figura 3 - Diagrama das funcionalidades Media

(22)

11

2.4.3 PTZ

O serviço PTZ permite, dado um perfil media do dispositivo, realizar movimentos PTZ. Esses movimentos podem ser absolutos, relativos ou contínuos. Permite também consultar e alterar os presets e consultar e alterar a “home position” de um determinado perfil media, na figura 4 pode ver-se as suas funcionalidades.

2.4.4 Imaging

O diagrama da figura 5 expõe o serviço Imaging. Este, dado um video source de um dispositivo, permite consultar e alterar as suas configurações de imagem: brilho, contraste, sharpness, saturação, exposição, focagem, etc.

(23)

12

2.4.5 Formato de dados dos pedidos e das respostas

JSON é o formato de mensagens utilizadas nos pedidos e resposta ao serviço web, por ser computacionalmente mais leve e permitir des-serialização nativa por parte dos

browsers.

Todos os pedidos PUT/POST que envolvam o envio de parâmetros no corpo, fazem-no fazem-no formato JSON. Isso é sinalizado pela inclusão fazem-no cabeçalho da mensagem HTTP do campo:

As respostas devolvidas pelo serviço são também no formato JSON. O formato do objecto JSON devolvido contém sempre os seguintes objectos:

Figura 5 - Diagrama das funcionalidades Imaging

(24)

13 • Associado a cada recurso, deve ser devolvida a lista de recursos dependentes do

mesmo, bem como a lista de operações sobre esses mesmos recursos.

• Um com o resultado (sucesso/insucesso) do pedido, e em caso de insucesso, o tipo de erro o detalhe do erro;

• Um com a informação do recurso solicitado;

Com o primeiro objecto assegura-se o princípio REST que defende que deve ser incluída num dado recurso toda a informação necessária para a navegação para os recursos/estados subsequentes, evitando a manutenção de estado do lado do servidor.

Na execução de um pedido GET, uma resposta bem-sucedida tem sempre um objecto relativo à informação do recurso a que o pedido se refere.

Em cada resposta (após um pedido GET, PUT, POST ou DELETE) vêm também as operações (recursos+verbos) que podem ser realizadas a partir do estado actual. Esta informação é uma lista de recursos (resources_uris) com os seguintes atributos [11]:

• method – verbo HTTP a ser utilizado (GET, POST, PUT, DELETE);

• rel – relação com o contexto atual (e.g: _self - para o próprio, next - próxima • operação/detalhe , new – novo, edit- edição);

• title – um título que represente a operação;

• uri – o URI a ser utilizado para acesso ao recurso/operação;

• params – array de parâmetros para a operação em causa. O array de parâmetros tem os seguintes atributos:

o name – nome do parâmetro;

o type – é opcional e indica o tipo de dados do parâmetro (boolean, int, o string, etc);

o value – valor do parâmetro, caso este não apresente uma lista de valores possíveis;

o options – é um array de “params” e representa a lista de todos os valores possíveis para o parâmetro em causa.

2.5 Descrição do Apache

Actualmente o servidor Apache é dos mais utilizados no mundo. É uma aplicação que pode ser configurada consoante o problema.

Inicialmente o desenvolvimento deste trabalho foi realizado sobre o Apache2.2, apesar de existir uma maior familiaridade com a sintaxe de configuração deste, optou-se por utilizar a versão mais recente optou-sendo esta a 2.4 [2]. Entre as duas versões existem

(25)

14 algumas diferenças importantes, que permitiram elaborar configurar serviço de uma forma mais simples e mais leve.

Uma das principais diferenças tem a ver com o modo como cada um das versões lida com processos. No Apache 2.2 cada ligação representava um processo em execução, logo a um aumento significativo de ligações teríamos um aumento igual de processos, afectando assim o desempenho do Apache. Nesta nova versão, isto já não acontece um processo é capaz de lidar com no máximo até 25 ligações. Esta alteração permite libertar memória e melhorar o desempenho [2].

No que diz respeito à construção do ficheiro de configuração para o VirtualHost, ele encontra-se na mesma pasta tanto numa versão como na outra, no entanto na versão 2.4 a extensão do ficheiro por padrão dever ser “.conf”.

Em relação às directivas utilizadas para a configuração de um VirtualHost existem algumas diferenças, expostas na tabela que se segue:

Tabela 1 - Diferenças Apache 2.2 / 2.4

Apache 2.2 Apache 2.4

Order allow, deny

Deny from all / Allow from all

Require all granted

Order deny, allow Deny from all

Require all denied

Relativamente ao modo de como activar e desactivar sites ou módulos, não houve alteração de uma versão para a outra. Para activar/desactivar sites utiliza-se respectivamente a2ensite/a2dissite, em relação a activar/desactivar módulos os comandos utilizados são a2enmod/a2dismod.

A migração da versão 2.2 para a versão 2.4, deve ser feita para se tirar partido da novas directrizes, aproveitar também os recursos adicionais e ainda o facto de esta ter

(26)

15 uma sintaxe mais simples [2] e mais fácil de entender. Por estes motivos foi feita o

(27)
(28)

17

3 Servidor REST ONVIF

Este capítulo está dividido na preparação do servidor HTTP que serve de base ao servidor REST, na configuração do serviço REST, e na configuração do programa FastCGI que implementa o servidor REST.

3.1 Configuração

3.1.1 Servidor HTTP Apache

Para alojarmos o SW Rest, optámos pelo servidor Apache [3], instalado num sistema operativo Xubuntu. Para instalar o Apache executa-se o seguinte comando:

Este comando instala o servidor apache na versão mais recente que existir. A versão instalada foi a 2.4,tem algumas diferenças quando comparada com a versão 2.2, que foi utilizada no início do desenvolvimento deste projecto.

Para alojar o serviço SW Rest, foi preciso criar um Virtual Host. Este Virtual Host tem que ser seguro, ou seja suportar HTTPS. Então para garantirmos que teremos todas as condições de configuração a nível de segurança disponíveis, instalou-se o módulo ssl, da seguinte forma:

• sudo apt-get install libssl – Através deste comando instala-se a livraria SSL;

• sudo a2enmod ssl – Com este comando activa-se o módulo SSl para o servidor Apache.

Para criar o ficheiro de configuração para o Virtual Host de raíz, é necessário fazer o seguinte:

• Criar o certificado SSL - sudo make‐ssl‐cert /usr/share/ssl‐ cert/ssleay.cnf /etc/ssl/private/restonvif.crt

sudo apt-get install apache2

(29)

18 • Copiar o ficheiro de configuração do Virtual Host default (pasta sites-available),

que é instalado por defeito com o Apache2;

• Renomear o ficheiro para o nome pretendido do novo Virtual Host - “nome_escolhido.pt”;

• Activar o Virtual Host executando o comando: sudo a2ensite nome_escolhido.pt;

• No ficheiro /etc/hosts do sistema adicionar o nome do Virtual Host – 127.0.0.1 nome_escolhido.pt;

• Activar o fastcgi para o Apache 2.4 – sudo a2enmod fastcgi

Reiniciar o Apache2 de modo a que as últimas configurações sejam carregadas para o servidor;

Uma vez que este trabalho dá continuidade a um trabalho anterior, este ficheiro de configuração para o Virtual Host já existia, no entanto foram realizadas alterações que são importantes de realçar.

O conteúdo do ficheiro nome_escolhido.pt foi colocado num novo ficheiro com o nome umoc.conf, logo aqui temos uma alteração a nível da extensão do ficheiro, esta alteração é imposta pela utilização de uma versão do Apache mais actual.

3.1.2 Servidor REST

O ficheiro de configuração do VirtualHost existente foi substituído por um novo ficheiro com uma nova configuração, mais simples e que teve como principal objectivo a eliminação do mod_rewrite [3].

Na tabela 3 pode visualizar-se as configurações que existiam no ficheiro de configuração antigo, e que no novo ficheiro já não existem.

Pela análise feita ao conteúdo dos ficheiros acima, é possível verificar que o ficheiro actual é muito mais simples para o sistema que o ficheiro antigo. Na actual configuração foi possível eliminar as regras das expressões regulares do Rewrite [3]. A definição dos pedidos GET, PUT, POST e DELETE, está feita de uma forma mais directa e mais simples também.

(30)

19

Tabela 3- Especificações do ficheiro antigo que foram eliminadas

RewriteEngine On RewriteCond %{REQUEST_METHOD} (PUT|DELETE) RewriteRule ^/onvif.*$ /testfcgi/rest_umoc_ll.fcgi?%{QUERY_STRING} [L] DocumentRoot /home/joana/public_html/ <Directory /> Options FollowSymLinks AllowOverride None

<Limit GET POST PUT DELETE HEAD OPTIONS> Order allow,deny

# You might want something a little more secure here, this is a dev setup

Allow from all

<LimitExcept GET POST PUT DELETE HEAD OPTIONS>

Order deny,allow Deny from all </LimitExcept>

</Limit>

ScriptAlias /cgi-bin "/home/joana/public_html/cgi-bin/"

<Directory "/home/joana/public_html/cgi-bin/"> AllowOverride None

Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch

Order allow,deny Allow from all </Directory>

ScriptAlias /ftestfcgi

/home/joana/public_html/testfcgi/

<Directory "/home/joana/public_html/testfcgi"> AllowOverride None

Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch

Order allow,deny Allow from all </Directory>

Na tabela 4 temos a nova configuração que substitui a configuração anterior.

Tabela 4 - Especificações do novo ficheiro de configuração DocumentRoot /home/adriana/public_html/

<Directory /home/adriana/public_html/> Options Indexes FollowSymLinks MultiViews AllowOverride ALL

Require all granted </Directory>

Action fastcgi-script /home/adriana/testfcgi/umoc_rest.fcgi ScriptAlias /onvif/home/adriana/testfcgi/umoc_rest.fcgi <Directory "/home/adriana/testfcgi">

AllowOverride ALL

Options +ExecCGI -MultiViews

+SymLinksIfOwnerMatch Require all granted Script GET umoc_rest.fcgi Script POST umoc_rest.fcgi Script PUT umoc_rest.fcgi Script DELETE umoc_rest.fcgi </Directory>

AccessFileName .htaccess <FilesMatch "^\.ht"> Require all granted

Existem alguns pontos que merecem mais atenção neste ficheiro, como por exemplo:

(31)

20 • ServerName contém o nome/endereço para o Virtual Host;

• SSLEngine e SSLCertificateFile permitem respetivamente ativar e indicar o ficheiro com o certificado SSL criado;

• ServerEncodedSlashes ativa a aceitação por parte do servidor apache da existência do caracter “/” codificado nos pedidos realizados Virtual Host

Este último parâmetro de configuração é importante uma vez que o endereço do serviço da câmara contém “/” e é codificado nas chamadas ao SW REST.

O redireccionamento dos pedidos é feito através das seguintes linhas, também elas colocadas no ficheiro de configuração do Virtual Host:

Os pedidos GET, POST, PUT e DELETE com o endereço iniciado por https://[nome_do_sítio]/onvif são redireccionados, juntamente com a sua querystring, para o rest_umoc.fcgi.

A directiva “Script” permite a execução da aplicação FastCGI para os métodos GET, POST, PUT e DELETE. Esta é uma alteração relativamente ao ficheiro de configuração anterior, uma vez que foi eliminada a necessidade de utilizar o seguinte:

<VirtualHost *:443> ServerAdmin webmaster@localhost ServerName umoc AllowEncodedSlashes On SSLProtocol all SSLEngine on SSLCertificateFile /etc/ssl/private/teste.crt <Directory "/home/adriana/testfcgi"> AllowOverride ALL

Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Require all granted

Script GET umoc_rest.fcgi Script POST umoc_rest.fcgi Script PUT umoc_rest.fcgi

Script DELETE umoc_rest.fcgi

(32)

21 Umas das principais alterações foi a troca do mod_rewrite pelo mod_alias. O mod_rewrite consiste num conjunto de regras com base em expressões regulares, que são criadas para ser possível reescrever as URI’s solicitadas em tempo real [4].

O mod_alias permite também a manipulação de URI’S mas de uma forma mais simples e sem a necessidade da utilização de expressões regulares. Para reescrever as

URI’s utiliza as directivas Alias e ScriptAlias. Esta última tem como acção adicional

marcar a directoria como contendo apenas scripts cgi.

Nesta nova configuração do VirtualHost foi utilizado o mod_alias devido à sua simplicidade e ter permitido eliminar as expressões regulares, e também uma vez que utilizamos scripts cgi.

3.2 FastCGI

Para a utilização do fastcgi [9] temos de realizar dois passos cruciais: • Instalar o mod_fastcgi – sudo apt-get install mod_fasctgi • Activar o fastcgi para o Apache 2.4 – sudo a2enmod fastcgi

Após a instalação do módulo FastCGI, o ficheiro de configuração por defeito fica disponível na directoria /etc/apache2/mods-available e pode/deve ser alterado de acordo com o que se pretende para o FastCGI do servidor REST ONVIF [3]. Além de identificar o programa FastCGI que serve os pedidos do serviço REST, este define os parâmetros que controlam a gestão dos respectivos processos por parte do servidor HTTP.

O ficheiro original tem a seguinte configuração <IfModule mod_fastcgi.c>

AddHandler fastcgi-script .fcgi

# Config used for dynamic applications

FastCgiConfig maxProcesses 50 maxClassProcesses 4 startDelay 1 killInterval 30 -idletimeout

90 </IfModule>

<Limit GET POST PUT DELETE HEAD OPTIONS Order allow,deny

# You might want something a little more secure here, this is a dev setup Allow from all

</Limit>

<LimitExcept GET POST PUT DELETE HEAD OPTIONS> Order deny,allow

Deny from all </LimitExcept>

(33)

22 e o ficheiro definido neste trabalho tem algumas alterações:

A directiva AddHandler, indica que qualquer ficheiro com a extensão .fcgi será tratado como sendo um FastCGI. Esta é a extensão da aplicação FastCGI desenvolvida.

Ao analisar os dois ficheiros verifica-se que a configuração para “Dynamic FastCGI

applications”, não é exactamente a mesma. No caso do serviço REST implementado a

configuração é:

A directiva FastCgiConfig, da forma que está definida, assegura que no caso de ser efetuado um pedido que não consiga ser respondido com o delay de 1 segundo (startDelay), o gestor de processos do Apache irá criar um novo processo, até ao limite de 20 processos por cada aplicação (maxClassProcesses) FastCGI, e 50 processos (maxProcesses) para todas as aplicações FastCGI, a executar no servidor no momento.

O parâmetro killInterval determina o número de segundos que um dado processo pode ficar no estado idle até ser terminado automaticamente pelo gestor de processos do Apache.

Os parâmetros aqui referidos são importantes para que seja possível obter o melhor desempenho possível da aplicação FastCGI [10]. Estes podem e devem ser alterados num ambiente produtivo, mediante a qualidade pretendida para os serviços disponibilizados e recursos do servidor.

Por último deve ter-se em atenção que deve ser feito o mapeamento da directoria onde está colocado o fastcgi [10] desenvolvido. Nesta nova configuração o

<IfModule mod_fastcgi.c>

AddHandler fastcgi-script .fcgi

#FastCgiWrapper /usr/lib/apache2/suexec FastCgiIpcDir /var/lib/apache2/fastcgi # Config used for dynamic applications

FastCgiConfig -maxProcesses 50 -maxClassProcesses 20 -startDelay 1 -killInterval 30 -idle-timeout 90

ScriptAlias /onvif /home/adriana/testfcgi/umoc_rest.fcgi </IfModule>

FastCgiConfig maxProcesses 50 maxClassProcesses 20 startDelay 1 killInterval 30 -idletimeout 90

(34)

23 mapeamento está feito nos ficheiros de configuração do Virtual Host e no fastcgi.conf respectivamente. O mapeamento foi realizado da seguinte forma:

No ficheiro de configuração umoc.conf (Virtual Host):

No ficheiro de configuração fastcgi.conf:

Os pedidos efectuados a https://umoc.conf/testfcgi/rest_umoc.fcgi devem executar o FastCGI “rest_umoc.fcgi” existente na pasta “/home/adriana/testfcgi”.Para que o servidor Apache redireccione todos os pedidos suportados pelo SW REST para a aplicação FastCGI (rest_umoc.fcgi), é necessário colocar estas duas linhas no ficheiro de configuração do Virtual Host:

3.3 Estrutura e Funcionamento

O servidor REST é um FastCGI desenvolvido em linguagem C++. O principal objectivo deste é fazer a ponte entre a aplicação web cliente e a biblioteca UMOC. O cliente faz um pedido REST/JSON ao servidor, este recebe e trata o pedido enviando-o de seguida para a biblioteca. A biblioteca é que é responsável pela comunicação SOAP/ONVIF com o dispositivo NVT. Este devolve a resposta ao servidor, que volta a tratar a informação e a enviar a resposta REST/JSON para o cliente.

A API web do servidor é constituída por URIs cujo formato genérico é: método /onvif/<servico>,{ESC}/<recurso(s)>

• método – são os verbos disponíveis para serviços HTTP: GET, PUT, POST e DELETE.

• <servico> - é uma denominação que identifica o serviço ONVIF do dispositivo ao qual pretendemos aceder, como por exemplo o devicemgmt, media, ptz, etc. Action fastcgi-script /home/adriana/testfcgi/umoc_rest.fcgi

ScriptAlias /onvif /home/adriana/testfcgi/umoc_rest.fcgi

Action fastcgi-script /home/adriana/testfcgi/umoc_rest.fcgi ScriptAlias /onvif /home/adriana/testfcgi/umoc_rest.fcgi

(35)

24 • ESC – é a abreviatura de Endereço de Serviço Codificado, e consiste na

codificação URLEncode da URI do serviço ONVIF na câmara (que varia de dispositivo para dispositivo).

• <recurso(s)> – representa uma sequência de recursos da API REST específicos do serviço, tendo uma correspondência com as entidades envolvidas nas operações ONVIF.

Aquando da recepção da URI o servidor começa por extrair a informação do campo <servico>, de seguida executa um switch-case (ilustrado na figura 3) que, mediante o <serviço> cria um objecto da classe responsável por servir os pedidos correspondentes.

Todas estas classes derivam de RestRequest, que contêm funções comuns como por exemplo, para codificar/descodificar URIs, extrair recursos da URI, etc. Todo o restante processamento é delegado do ciclo principal do servidor para as classes de cada serviço invocando a função virtual getRestResult sobre o objecto criado. Esta função é polimórfica, ou seja varia consoante a classe do objecto, que vai analisar os recursos da URI, permitindo assim um tratamento abstracto e igual para os pedidos dos vários serviços. A figura 6 ilustra os vários serviços NVT suportados.

A partir da interpretação dos recursos e do método HTTP utilizados pelo cliente, a função getRestResult de cada serviço encaminha o pedido para um conjunto de funções da mesma classe que têm uma correspondência 1:1 com as funções da biblioteca. Estas funções são as representadas à direita na figura 6 (apenas alguns exemplos), e invocam a função da biblioteca correspondente. São destacadas a fundo cinzento-escuro, algumas funções que foram adicionadas por este trabalho. Estas funções da fazem a des-serialização dos dados JSON do pedido para C (no caso de funções do tipo “get”) e serialização de C para JSON (no caso de funções do tipo “set”). Após a invocação da função da biblioteca a resposta é colocada no objecto JSON de resultado e termina a função getRestResult. Finalmente, o ciclo principal do servidor é retomado e envia a resposta JSON para o cliente.

(36)

25 Figura 6 - Diagrama Geral de serviços e recursos do Servidor

3.4 API web

Nesta secção são apresentadas todas as funcionalidades que foram adicionadas de raiz à API REST do servidor. Notas importantes sobre o diagrama a sigla {ESC} representa o Endereço do Serviço Codificado, as formas que se encontram preenchidas a cinzento e as palavras a negrito representam as novas funcionalidades adicionados. Como por

(37)

26 exemplo o novo GetServiceCapabilities que foi uma actualização feita à norma ONVIF na versão 2.0.

3.4.1 DeviceManagement

Na figura 7 estão expostas a cinzento-escuro todas funções adicionadas de raiz à API do servidor. O bloco com reticências representa todas as funções que já estavam disponíveis na API que serviu de base a este trabalho.

(38)

27 Uma das funcionalidades adicionadas foi a capacidade de configurar o modo de descoberta, dos dispositivos, quer local quer remoto, e neste último caso os Discovery

Proxys respectivos (ver secção 5.3). A figura 8 ilustra as novas funções destacadas a

cinzento-escuro. Os pedidos do tipo “set” ao recurso DiscoveryMode, levam no corpo o parâmetro que se pretende alterar (modo de descoberta "local” ou “remote") e o respectivo valor (“Discoverable” ou “NonDiscoverable”). Desta forma unifica-se o modo de descoberta local e remoto num único URI, pois estes configuram-se da mesma forma. Concretamente, o corpo do pedido PUT DiscoveryMode tem o formato indicado na tabela 4.

Tabela 5 - Formato pedidos/respostas para GET / PUT

Verbo Recurso Formato do corpo do pedido/resposta HTTP

PUT DiscoveryMode {"local/remote": "Discoverable/NonDiscoverable"} GET DiscoveryMode { "mode": "NonDiscoverable",

"status": { "msg": "Sucesso!", "value": 1 }} PUT / GETT DiscoveryProxys {"list": [ {"Type": "IPv4/IPv6/DNS", "Address/Name": "endereco/nome"} ]}

(39)

28 O mesmo acontece para o pedido PUT do recurso DiscoveryProxys, cujo corpo transporta uma lista parâmetros identificadores dos servidores Discovery Proxy a configurar, concretamente o tipo de endereço e o endereço. O pedido GET a este recurso obtém uma resposta que tem exactamente o mesmo formato.

A outra alteração feita no serviço Device Management foi acrescentar a utilização da operação GetServices. O servidor que estava desenvolvido permitia o acesso aos endereços e capabilities dos restantes serviços das câmaras utilizando a operação

GetCapabilities que foi descontinuada e que apenas se mantém para compatibilidade

com a versão 1.0 da norma. Facilmente é possível encontrá-la na norma, e no soapStub.h ela aparece como:

A norma 2.0 do ONVIF introduziu novas operações para descobrir os endereços e

capabilities de forma separada, concreta e respectivamente as operações GetServices e GetServiceCapabilities. A operação GetServices do Device Management permite

conhecer os endereços dos restantes serviços. Utilizando esse endereço, pode então descobrir-se as respectivas capabilities (IO, media, ptz, imaging, events) utilizando a operação GetServiceCapabilities de cada um dos serviços.

Essas novas operações foram adicionadas à biblioteca, concretamente:

Tabela 6 - Protótipo das funções

NOME DA FUNÇÃO PROTÓTIPO

getMediaCapabilities int getMediaCapabilities_LL (const char* xaddr, const char* user,

const char* pass, MediaCapabilities** cap);

getPtzCapabilities int getPtzCapabilities_LL (const char* xaddr, const char* user,

const char* pass, PtzCapabilities** cap);

getImagingCapabilities int getImagingCapabilities_LL (const char* xaddr, const char* user,

const char* pass, ImagingCapabilities** cap);

getEventsCapabilities int getEventsCapabilities_LL (const char* xaddr, const char* user,

const char* pass, EventsCapabilities** cap);

SOAP_FMAC5 int SOAP_FMAC6 soap_call___device__GetCapabilities(struct soap *soap, const char *soap_endpoint, const char *soap_action, struct _device__GetCapabilities *device__GetCapabilities, struct _device__GetCapabilitiesResponse

(40)

29 As estruturas capabilities são obtidas por cada serviço. Como cada serviço tem a sua operação Get<servico>Capabilities, a respectiva estrutura inclui apenas as respectivas informações.

Com base nestas novas funções da biblioteca, as funcionalidades do servidor REST sofreram também uma evolução. Esta evolução não é muito visível ao nível da API, mas tem um impacto fundamental na coerência e correcção do funcionamento do servidor.

Anteriormente, as URIs dos recursos seguintes (ou de nível inferior) ao actual são devolvidas nas respostas do servidor sem qualquer filtragem. Esta implementação assume que cada câmara suporta todas as funcionalidades de um determinado serviço, o que não é correcto. De facto, dentro de cada serviço dos dispositivos NVT existem funcionalidades que são opcionais e para isso existe a operação GetServiceCapabilities. Neste trabalho, os recursos devolvidos nas respostas do servidor são filtradas de acordo com as capacidades do dispositivo. Isso é implementado ao nível de topo (recurso “/”) de cada serviço, conforme representado na figura 8. Quando o servidor recebe um pedido de topo, invoca a função get<servico>Capabilities e só devolve URIs para recursos que de facto a câmara suporta. Desta forma, não se passa informação enganosa para o cliente REST, minimizando também o número de pedidos errados por parte do cliente.

Nesta nova abordagem, compatível com a norma 2.0 do ONVIF, o cliente REST deve obter os endereços dos restantes serviços utilizando o novo recurso “services”, em detrimento do recurso “capabilities”.

Com base nestas novas funções da biblioteca, as funcionalidades do servidor REST sofreram também uma evolução. Esta evolução não é muito visível ao nível da API, mas tem um impacto fundamental na coerência e correcção da informação obtida dos serviços que podem ver-se na figura 9.

O DiscoveryMode e o DiscoveryProxys são duas funções de descoberta local ou remota que foram introduzidas de raiz neste trabalho, tendo sido desenvolvidas a nível da biblioteca e do Servidor, serão explicadas mais detalhadamente no ponto “Configuração da descoberta de câmaras”.

(41)

30

3.4.2 DeviceIO

O DeviceIO permite consultar quais as saídas físicas de um dispositivo, e alterar o estado e as configurações das mesmas. A API está apresentada na figura 10.

Este serviço visa complementar o servidor ONVIF já existente, adicionando suporte para um serviço que é obrigatório para dispositivos NVT. A utilidade deste serviço está em permitir consultar a informação sobre as saídas entradas físicas de um dispositivo, assim como alterar o estado e a configuração destas.

Figura 9 - Diagrama GetServices e GetServicesCapabilities

(42)

31 No diagrama da figura 10 temos as URIs disponibilizadas pelo serviço DeviceIO, e as respectivas operações ONVIF. A função GetRelayOutputs devolve as saídas / entradas físicas do dispositivo, a função SetRelayOutputState permite alterar o estado de uma saída / entrada de activo para inactivo e vice-versa. Esta permite alterar as configurações de uma entrada / saída física de um dispositivo, as configurações que se podem alterar são o “mode”, “delayTime” e o “idleState”.

3.5 Desenvolvimento do serviço DeviceIO

3.5.1 Classe Rest_io

A função GetAudioOutputs devolve o número de saídas de áudio. E a função GetAudioSources devolve o número de entradas de áudio.

Para o desenvolvimento do serviço IO foi seguida a lógica já existente para os serviços, media, ptz, imaging, etc. Então a classe do serviço IO deriva da classe RestRequest e é constituída da pelas funções descritas no diagrama de classes da tabela 6.

Tabela 7 - Classe Serviço do IO

Rest_io getRestResult() rest_deviceio() inicializaRecursos() getRelayOutputsResult() getOutputs() updateState() updateConfig()

A classe de serviço define um enumerado cujo objectivo é permitir indexar os respectivos recursos. Tem ainda uma estrutura unordered_map que mapeia num valor do enumerado os <recursos> possíveis de um segmento do URI.

Este tipo de mapeamento é feito para os vários segmentos do URI e permite utilizar a instrução switch para encaminhar o pedido até à função respectiva da biblioteca UMOC. Este trabalho é feito pelos métodos privados da classe de serviço: getRelayOutputsResult(), getOutputs(), updateState(), updateConfig()

(43)

32 { "resources_uri": [ { "method": "GET", "rel": "_self", "title": "Device IO",

"uri": "/onvif/deviceio,remotedacrib.dynip.sapo.pt/Outputs/" }, { "method": "GET", "rel": "/onvif/deviceio,remotedacrib.dynip.sapo.pt/Outputs/", "title": "RelayOutput", "uri": "/onvif/deviceio,remotedacrib.dynip.sapo.pt/Outputs/relayoutput" }, { "method": "GET", "rel": "/onvif/deviceio,remotedacrib.dynip.sapo.pt/Outputs/", "title": "Digital Inputs",

"uri": "/onvif/deviceio,remotedacrib.dynip.sapo.pt/Outputs/DigitalInputs" }, { "method": "PUT", "params": [ { "name": "state", "options": [ { "name": "active", "value": 0 }, { "name": "Inactive", "value": 1 } ] } ], "rel": "/onvif/deviceio,remotedacrib.dynip.sapo.pt/Outputs/", "title": "State", "uri": "/onvif/deviceio,remotedacrib.dynip.sapo.pt/Outputs/RelayOutput/token" } ], "status": { "msg": "Sucesso!", "value": 1 }

3.5.2 Exemplo de Resultado

Na figura 11 apresenta-se o resultado de um pedido Get https://192.168.1.70/onvif/deviceio,remotedacrib.dynip.sapo .pt/Outputs utilizando a ferramenta Postman:

(44)

33 Pela mensagem obtida como resposta, percebe-se que quando fazemos um pedido GET, O JSON devolve todas as URI’s disponíveis e os métodos que podemos utilizar sobre elas. No caso dos métodos PUT e POST tem também a informação que vai no corpo do pedido.

Este é apenas um exemplo de uma mensagem JSON, as respostas obtidas para as outras funções são idênticas, apenas variam devido ao tipo de método (PUT, GET) e se tem corpo ou não.

3.5.3 Tratamento de um pedido ao Serviço IO

Quando o serviço IO recebe um pedido, ele é tratado da forma que está exposto na figura 12.

Assume-se que é realizado o seguinte pedido: GET /onvif/deviceio,{ESC}/outputs. A lógica de funcionamento está representada no diagrama de sequência da figura 10:

Figura 12 - Tratamento do Pedido

Em primeiro lugar obtemos o recurso do primeiro segmento <recursos>, é o que se situa logo a seguir ao {ESC}. Neste exemplo o recurso é <outputs>. Isso é feito pela função “getCurrentResourcesSegment” da classe RestRequest. Juntando a informação

(45)

34 do verbo HTTP do pedido (GET) e do recurso <outputs> é seleccionado e invocado o método getOutputs. Este executa o método getServiceURL para obter o segmento do URI que define o endereço do serviço na câmara, a partir do endereço de serviço codificado (ESC) do pedido. A seguir invoca a função da biblioteca UMOC correspondente, que se chama get_outputs_LL, passando como argumentos o login e

password de acesso à câmara.

Este é o funcionamento que as funções do Serviço IO seguem, e que varia apenas no que diz respeito à des-serialização e serialização de dados JSON respectivamente caso a operação seja do tipo “get” ou “set”. Se for realizado um pedido ao serviço REST em que existe informação no corpo do pedido (isto só acontece nos métodos PUT e POST), os métodos privados de encaminhamento obtém-na recorrendo às propriedades (protegidas) da classe RestRequest denominadas “jsoncontent”, “contentok” e ”contenterror”.

A primeira é um objecto JSON com o conteúdo do corpo, a segunda indica se o

parsing do conteúdo para JSON ocorreu com sucesso e a terceira contém o erro (caso

(46)

35

4 Configuração da descoberta de câmaras

O serviço de Device Management permite configurar os modos como um dispositivos pode ser descoberto, e no caso de descoberta remota quem são os respectivos Discovery Proxys, neste caso saber o tipo e o endereço da(s) proxy(s).

O Device Management baseia-se num conjunto de funções que permitem consultar e/ou alterar a configuração do modo de descoberta bem como os parâmetros da(s) proxy(s). Essas funções denominam-se:

• GetDiscoveryMode • SetDiscoveryMode • GetRemoteDiscoveryMode • SetRemoteDiscoveryMode • GetDPAddresses • SetDPAddresses

O DiscoveryMode e o DiscoveryProxys são duas funções de descoberta local ou remota que foram introduzidas de raíz neste trabalho, tendo sido desenvolvidas a nível da biblioteca e do Servidor.

4.1 Biblioteca UMOC

Cada função de descoberta da biblioteca corresponde a uma operação ONVIF. Na tabela 2 pode ver-se a função stub gerada para a operação GetDiscoveryMode. De notar que para além dos dois últimos argumentos, que contêm o pedido e a resposta SOAP, respectivamente, existem mais três parâmetros:

• Um apontador para o contexto exclusivo de execução de cada método

gSOAP, que inclui, por exemplo, campos de cabeçalho SOAP para o

argumento pedido (por exemplo, credenciais de autenticação e parâmetros de comunicação) e para o argumento reposta (por exemplo, mensagens de erro) [5].

(47)

36 • O endereço do dispositivo.

• A URI da operação ONVIF que é opcional; Se o valor dele for NULL então o parâmetro é preenchido com o valor definido por defeito.

Estes cinco parâmetros formam um padrão comum a todos os gSOAP stubs.

ONVIF depende de vários WSs padrão cuja definição não inclui ligações concretas de operação, nem de serviços e portas. Isto acontece para os seguintes casos,

WS-Addressing, WS-Discovery e WS-Security. Como consequência, o gSOAP não cria stubs

para eles, no entanto estes podem ser suportados através da utilização de plugins[5].

Para utilizar os stubs no desenvolvimento da biblioteca UMOC, existe um conjunto de passos que se executam da mesma forma para todas as funções.

Em primeiro lugar é necessário criar o contexto, inicializa-lo, e configurar os tempos para envio e recepção da mensagem. Na tabela 9 pode ver-se como é feito este procedimento.

int soap_call___device__GetDiscoveryMode (

struct soap *soap,

const char *soap_endpoint, const char *soap_action,

struct _device__GetDiscoveryMode *device__GetDiscoveryMode, struct_device__GetDiscoveryModeResponse *device__GetDiscoveryModeResponse ); struct soap s; soap_init(&s); s.send_timeout = SEND_TIMEOUT; s.recv_timeout = RECV_TIMEOUT; s.accept_timeout = ACCEPT_TIMEOUT; s.connect_timeout = CONN_TIMEOUT;

Tabela 8- Stub ONVIF definido pelo gSOAP

(48)

37 O próximo passo é adicionar as credenciais de autenticação ao contexto. Isto é feito da seguinte forma, exposto na tabela 10.

Para finalizar a preparação da operação faltam duas variáveis, uma que leva a mensagem de pedido e outra que tem a mensagem de resposta. Como mostra o exemplo a seguir, na tabela 11.

Depois de executados estes passos, o último é invocar o stub pretendido. O protótipo da função é mostrado na tabela 12.

Em todas as funções que se desenvolveu para a biblioteca foi utilizado este processo na realização das operações SOAP.

Foram desenvolvidas as funções para a configuração dos parâmetros de descoberta do DeviceManagement, sendo elas as seguintes: get_discoverymode_LL, set_discoverymode_LL,get_remotediscoverymode_LL,set_remotediscoverymode_LL,get_DPAddr esses_LL,set_DPAddresses_LL.

Os passos descritos definem a lógica geral que é comum a todas as funções da biblioteca. Esta pode ser mais detalhada considerando que as funções se dividem em

soap_register_plugin(&s, soap_wsse);

soap_wsse_add_UsernameTokenDigest(&s, 0, user, pass);

struct _device__GetDiscoveryMode req;

struct _device__GetDiscoveryModeResponse resp;

soap_call___device__GetDiscoveryMode(&s, address, NULL, &req, &resp);

Tabela 12 - Função soap_call para o GetDiscoveryMode Tabela 10 - Adicionar credenciais de autenticação no cabeçalho

(49)

38 dois tipos: “get” e “set”. Isso é feito nas subsecções seguintes, que mostram as diferenças entre os dois tipos.

4.1.1 DiscoveryMode e RemoteDiscoveryMode

No que diz respeito à descoberta, os dispositivos ONVIF podem estar em dois modos: descobríveis ou não-descobríveis.

A norma define dois modos de descoberta, um que permite a descoberta local e outra que permite a descoberta remota. Estas funções são denominadas GetDiscoveryMode e GetRemoteDiscoveryMode.

Ambas devolvem um booleano, caso o seu valor seja true então o dispositivo encontrasse no modo descobrível caso contrário devolve false e o dispositivo encontrasse no modo não-descobrível.

Tabela 13 - GetDiscoveryMode / GetRemoteDiscoveryMode

GetDiscoveryMode / GetRemoteDiscoveryMode

Access Class: READ_SYSTEM Nome Mensagem Descrição

Pedido Vazia

Resposta Opção de descoberta: descobrível ou não-descobrível.

As duas funções descritas acima para além da operação de consulta (Get) do modo em que o dispositivo se encontra, permitem através da operação Set alterar o seu estado de descobrível ou não-descobrível. As funções que permitem esta alteração de estado saõ: SetDiscoveryMode, SetRemoteDiscoveryMode, como se pode ver na seguinte tabela

Tabela 14 - SetDiscoveryMode / SetRemoteDiscoveryMode

SetDiscoveryMode / SetRemoteDiscoveryMode

Access Class: WRITE_SYSTEM

(50)

39

Pedido Opção de alteração da descoberta: descobrível ou não-descobrível. Resposta Vazia.

4.1.2 Discovery Proxy Addresses

A operação GetDPAddresses permite a descoberta do(s) endereço(s) da(s) proxy(s) de um dispositivo, neste caso saber o tipo e o endereço da(s) proxy(s). No caso do dispositivo estar configurado com o modo remoto de descoberta activo, deve ser possível recuperar o endereço remoto de descoberta da(s) proxy(s).

Tabela 15 - GetDPAddresses

GetDPAddresses Access Class: READ_SYSTEM

Nome Mensagem Descrição Pedido Vazia

Resposta Opção do endereço e o tipo de proxy. Caso não tenha nenhuma proxy configurada é retornada uma lista vazia.

A operação SetDPAddresses permite alterar a configuração de uma proxy existente num dispositivo. Se o dispositivo suportar o modo de descoberta remoto então deve permitir a alteração do endereço e do tipo remoto da proxy(s).

Tabela 16 - SetDPAddresses

SetDPAddresses Access Class: WRITE_SYSTEM

Nome Mensagem Descrição

Pedido Opção de alteração do endereço e do tipo da proxy.

(51)

40

4.2 Servidor

4.2.1 Funções de consulta

As funções do tipo “get” permitem consultar informação sobre um dispositivo. Considerando, por exemplo, o caso concreto da função que implementa a operação ONVIF GetDiscoveryMode cujo protótipo é:

(52)

41 int get_discoverymode_LL (const char* address, const char* user, const char* pass, enum DiscoveryMode* mode );

Em primeiro lugar trata da validação dos argumentos. Depois, segue a parte comum aos dois tipos de preparação do contexto e da criação das estruturas de pedido e a de resposta.

(53)

42 No caso das funções “get” acima referidas, a variável do pedido é vazia e a variável de resposta contém os dados da respectiva operação.

No diagrama da figura 13 pode ver-se que após a realização da operação, as funções do tipo “get” verificam se esta teve sucesso. Nesse caso, processam os dados resultantes colocando-os no argumento de saída.

4.2.2 Funções de alteração

O método SET permite alterar parâmetros de configuração do dispositivo. Seguindo o exemplo acima, vou pegar exactamente na mesma função mas neste caso executando sobre ela o método SET, SetDiscoveryMode o protótipo dela é o seguinte:

int set_discoverymode_LL ( const char* address, const char* user, const char* pass, enum DiscoveryMode mode );

Tal como na função GetDiscoveryMode, a lógica seguida na função SetDiscoveryMode é a mesma, em primeiro lugar tratamos da criação e configuração do objecto SOAP, e de definir as estruturas das duas variáveis de saída, a variável de pedido e a de resposta.

No SET a variável de pedido tem a informação relativa ao parâmetro de configuração do dispositivo que se pretende alterar, e a variável de resposta é vazia. De realçar que no GET ocorria exactamente o contrário, a variável de pedido era vazia, e a variável de resposta é que continha dados.

O diagrama da figura 14 seguinte expõe os passos realizados no desenvolvimento da função, volto a referir que para todos os SET’s a lógica seguida foi sempre a mesma.

(54)

43 Figura 14 - Diagrama da função SetDiscoveryMode

4.2.3 Funções de Gestão dos Discovery Proxys

Apesar de todas as funções referidas acima terem seguido a mesma lógica, existiram duas que lidam com dados com alguma complexidade e que por isso merecem destaque. As funções são:

(55)

44 GetDPAddresses:

int get_DPAddresses_LL ( const char* address, const char* user, const char* pass, int* numDP, Network_Info** discoveryProxies );

SetDPAddresses:

int set_DPAddresses_LL ( const char* address, const char* user, const char* pass, int numDP, Network_Info* dp );

Ao contrário das funções anteriores estas (SetDPAddresses e GetDPAddresses) têm dois parâmetros, de saída, no caso do ”get”, e de entrada, no caso do ”set”, que são um array de estruturas. Como tal, esses parâmetros são constituídos por um (endereço de) apontador para os elementos do array e por (o endereço de) uma variável que indica a dimensão do array. Devido a estes arrays terem um formato mais simples do que os dados das respectivas funções stub e a, no caso do “get”, ser necessário copiar os dados da resposta para os argumentos de saída antes da eliminação do contexto gSOAP, o processamento destas funções assume proporções bastante superiores. Além disso, este processamento foi desenvolvido com preocupações de desempenho e segurança na gestão de memória.

Envolve a alocação dinâmica dos campos apontador de cada elemento, nomeadamente do segundo campo: o endereço. O formato deste endereço é dado pelo primeiro campo, que pode ser IPv4, IPv6 ou DNS (um nome).

Como este processamento trabalha com memória dinâmica, todas as falhas têm que ser previstas, e caso aconteçam têm que ser geridas de forma a deixar a biblioteca num estado coerente. Por exemplo, se falhar a alocação de um elemento do array, a função regista o erro, mas adopta uma abordagem best-effort e devolve os elementos já copiados. Para isso, o tamanho do array que é devolvido corresponde cujo ao número dos elementos copiados com sucesso, permitindo assim uma correcta libertação dessa memória. Para fazer isso é também fornecida uma função de ajuda, que liberta arrays do mesmo tipo.

A função SetDPAddresses, envia para o dispositivo o número de proxys que se pretende alterar, e a estrutura com a informação sobre o tipo (IPv4, IPv6, DNS) e o

Imagem

Figura 1 - Arquitectura do Servidor
Figura 2 - Diagrama DeviceManagement
Figura 3 - Diagrama das funcionalidades Media
Figura 4 - Diagrama das funcionalidades PTZ
+7

Referências

Documentos relacionados

No primeiro, destacam-se as percepções que as cuidadoras possuem sobre o hospital psiquiátrico e os cuidados com seus familiares durante o internamento; no segundo, evidencia-se

A par disso, analisa-se o papel da tecnologia dentro da escola, o potencial dos recursos tecnológicos como instrumento de trabalho articulado ao desenvolvimento do currículo, e

c.4) Não ocorrerá o cancelamento do contrato de seguro cujo prêmio tenha sido pago a vista, mediante financiamento obtido junto a instituições financeiras, no

Contudo, não é possível imaginar que essas formas de pensar e agir, tanto a orientada à Sustentabilidade quanto a tradicional cartesiana, se fomentariam nos indivíduos

- Se o estagiário, ou alguém com contacto direto, tiver sintomas sugestivos de infeção respiratória (febre, tosse, expetoração e/ou falta de ar) NÃO DEVE frequentar

Esta realidade exige uma abordagem baseada mais numa engenharia de segu- rança do que na regulamentação prescritiva existente para estes CUA [7], pelo que as medidas de segurança

Se você vai para o mundo da fantasia e não está consciente de que está lá, você está se alienando da realidade (fugindo da realidade), você não está no aqui e

• Os municípios provavelmente não utilizam a análise dos dados para orientar o planejamento de suas ações;. • Há grande potencialidade na análise dos micro dados do Sisvan