Translate

quinta-feira, 29 de setembro de 2011

Desenvolvendo Drivers XFS - Detalhes

Olá leitores. Tenho recebido vários e-mails com pedidos de mais informações de como construir um Service Provider. Há algum tempo, eu publiquei um overview sobre isso (Desenvolvendo Drivers XFS - Overview), mas realmente não passou de um breve resumo. De fato não é uma coisa trivial, e não há muito material disponível. Por isso, vou tentar colocar as informações essenciais (sem muitos detalhes) para guiar o desenvolvimento dos incautos que quiserem tentar construir um Service Provider.

Por motivos econômicos, vou referir-me a Service Provider apenas como SP.

Pré-requisitos para essa peleja
Para conseguir desenvolver satisfatoriamente um SP, é necessário um conhecimento intermediário-avançado sobre threads e desenvolvimento Win32. Além disso, será necessário ter um bom conhecimento sobre o desenvolvimento de DLLs em alguma plataforma de desenvolvimento, como por exemplo: Microsoft Visual C++, Borland C++ Builder ou outra qualquer.

Além disso é necessário ler o documento 1 da especificação CEN/XFS (na versão que se pretende para o SP), e o documento relativo a classe de dispositivo que se pretende desenvolver. Por exemplo, caso se esteja usando a especificação versão 2 de Dezembro de 1998, e o objetivo seja o desenvolvimento para uma impressora, os documentos necessários seriam: CWA13449-1.pdfCWA13449-3.pdf.

Requisitos do SP
Tudo o que é preciso ter em um SP está descrito nos dois documentos da especificação indicados acima. No entanto, a seguir eu relacionou os requisitos chave de qualquer SP:

  1. Exportar as 11 funções WFPXXXXX descritas na especificação: são através dessas funções que se garante a aderência à especificação, por isso elas precisam existir no SP, e precisam também ter um comportamento aderente à especificação;
  2. Funcionamento assíncrono: O SP é assíncrono. Isso é muito importante, mas às vezes passa desapercebido. O ponto é que o protocolo de comunicação entre o SP e o XFS Manager é baseando em regras assíncronas. O XFS Manager é quem permite, artificialmente, que uma aplicação faça chamadas síncronas. Basicamente o que ele faz é aguardar o retorno do atendimento da request por parte do SP antes de retornar a chamada para a aplicação;
  3. Suportar multi-sessões: O SP precisa ser projetado para atender mais de uma aplicação ao mesmo tempo. Isso é muito importante, pois praticamente todos os sistemas de autoatendimento possuem agentes de monitoração que funcionam de modo não integrado à aplicação, e com isso um SP multi-sessão é indispensável;
Arquitetura do SP
Um SP tem, basicamente, duas grandes partes com responsabilidades bem definidas nas quais se concentram os componentes constituintes de qualquer SP:
  1. Estrutura compartilhada: Essa parte do SP é onde se concentra a maior complexidade desse desenvolvimento. Ela é comum a qualquer SP, sem mudanças (se for projetado corretamente).  Em geral, se constrói um ambiente de desenvolvimento de SPs, onde essa parte é compartilhada entre todos os SPs da solução. Mas, essa parte tem tantos componentes críticos que são tão complexos que é muito comum que as empresas e pessoas comprem essa parte pronta de alguma outra empresa que já a tenha construída e debugada (que é o mais importante). Essa parte do desenvolvimento se concentra quase que inteiramente no documento 1 da especificação. Os componentes mais básicos dessa parte são:
    • Gestor de Trace: responsável pela geração de logs do SP. Esse componente pode ser bem simples, onde apenas se escreve o que se quer em um arquivo de log, ou então pode ser bem complexo definindo níveis dos logs que serão gravados, estratégia de rotate, limite de tamanho e etc. Para essa parte, utilizar um framework de mercado como o log4cxx é uma alternativa bem interessante;
    • Gestor de eventos: o SP é basicamente orientado à eventos, ou seja, ele envia e recebe eventos o tempo todo para poder informar que uma operação foi concluída ou que um marco foi alcançado no processamento ou ainda que um limite foi atingido;
    • Agendador de requisições: o SP tem que ser assíncrono conforme os requisitos chaves. Isso quer dizer que qualquer comando que o SP receber deverá ser agendado para execução posterior. Isso é muito importante, pois é preciso prever que um mesmo comando será chamado várias vezes (várias aplicações acessando o SP). Com isso, o agendador precisa implementar uma estratégia de agendamento baseada em fila;
  2. Estrutura específica: Essa parte do SP muda de acordo com a classe de dispositivo e também de acordo com a interface do device driver. Essa é a parte do SP que precisa se comunicar efetivamente com o device driver, que é o controlador do dispositivo. Essa parte pode ser projetada de modo que o comportamento especifico da classe XFS seja resolvido junto com a interface do device driver. No entanto, a solução que mais me agrada é separar as duas coisas; Essa parte do desenvolvimento se concentra inteiramente no documento relativo a classe de dispositivo no qual o SP será construído. Os componentes mais básicos dessa parte são:
    • Interface do Device Driver: este é o ponto de acesso ao dispositivo. Então aqui, em geral, existe uma classe com métodos que dão acesso a funções exportadas em uma dll ou lib do device driver que controla o dispositivo;
    • Implementação da classe de dispositivo XFS: aqui deve ser implementado o comportamento específico da classe de dispositivo XFS de qual trata o SP. Por exemplo, se o SP for para impressora, então a classe de dispositivo é a PTR e deve-se então consultar a especificação dessa classe no conjunto de documentos XFS. No caso da impressora o documento é CWA13449-3.pdf;

Codificação
Aqui a dica é criar um projeto de DLL. Essa DLL precisa exportar as 11 funções previstas na especificação, e toda vez que essas funções forem executadas, uma sequencia de acontecimento deve ocorrer no interior do SP. Basicamente a sequencia é a seguinte:
  1. Verificar informações básicas a cerca dos parâmetros recebidos e também o estado em que se encontra a sessão. Por exemplo, um WFSExecute só pode ser executado após um WFSOpen. Ainda, se for executado um WFSLock, somente a aplicação que possui o "lock" poderá executar WFSExecute. As demais aplicações que não possuírem o "lock" poderão apenas consultar informações, executando, por exemplo WFSGetInfo;
  2. Agendar o processamento dessa "solicitação", armazenando todos os parâmetros da chamada em uma fila;
  3. Retornar WFS_SUCCESS para a chamada da função. Obviamente esse retorno significa apenas: "Ok, tudo certo até aqui, eu posso processar sua requisição...". Caso não seja esse o caso, precisa então ser retornado um código de erro que melhor indique o motivo pelo qual a solicitação não pôde ser atendida;
  4. Assim que possível, retirar solicitações da fila, analisar seus parâmetros e processa-los de acordo com a especificação para aquela classe de dispositivo. O resultado do processamento é SEMPRE um evento. Ou seja, mesmo que o resultado do processamento seja um erro, um evento deve ser gerado para o XFS Manager, informando-o desse resultado. Esse evento nada mais é do que uma mensagem windows, direcionada para o handle indicado nos parâmetros da chamada. Claro que isso aqui é uma aproximação simplista. De fato, existem mais questões envolvidas aqui como: verificar se não foi atingido o timeout para execução da solicitação, lançar eventos intermediários, notificar aplicações ouvintes que se registram para receber certo tipos de eventos e etc;

Testes
Bom, para testar o SP é necessário uma aplicação XFS para a classe de dispositivo em questão. Essa parte é bem mais fácil, e é possível construir rapidamente essa aplicação de testes. A aplicação pode ser inclusive construída para operar com uma interface de linha de comando. Para fazer essa construção basta utilizar o documento 1 da especificação, buscando informações sobre as funções WFSXXXX contidas no capitulo 4 (Application Programming Interface (API) Functions). A sequência básica de comandos para uma aplicação XFS é a seguinte:
  1. WFSStartUp;
  2. WFSOpen;
A partir daí, é possível executar os comandos específicos da classe utilizando os comandos WFSExecute e WFSGetInfo.


É isso. Té mais!!!



3 comentários:

Anderson Cunha disse...

kro Fagner,

Estou com alguns problemas em fazer esse SP ... aqui estou com a seguinte mensagem no meu teste!! "APIRETURN: WFSOpen Error: WFS_ERR_SERVICE_NOT_FOUND - unable to locate open entry point"... pior que jah implementei as 11 funções ... e o StartUP retorna OK ... não imagino oq possa ser !!

Anderson Cunha disse...
Este comentário foi removido pelo autor.
Unknown disse...

To which path we need to copy the built dll?. Can you please share the sample code for this?