0 évaluation0% ont trouvé ce document utile (0 vote)
52 vues0 page
Este documento descreve um projeto de monitoramento ambiental remoto baseado em microcontroladores. O projeto permite medir a temperatura ambiental e enviar os dados por email caso este ultrapasse um valor configurado. O sistema foi desenvolvido utilizando um microcontrolador PIC18F87J60 conectado à internet através de rede Ethernet e implementa protocolos como HTTP e SMTP para comunicação e envio de dados.
Este documento descreve um projeto de monitoramento ambiental remoto baseado em microcontroladores. O projeto permite medir a temperatura ambiental e enviar os dados por email caso este ultrapasse um valor configurado. O sistema foi desenvolvido utilizando um microcontrolador PIC18F87J60 conectado à internet através de rede Ethernet e implementa protocolos como HTTP e SMTP para comunicação e envio de dados.
Droits d'auteur :
Attribution Non-Commercial (BY-NC)
Formats disponibles
Téléchargez comme PDF, TXT ou lisez en ligne sur Scribd
Este documento descreve um projeto de monitoramento ambiental remoto baseado em microcontroladores. O projeto permite medir a temperatura ambiental e enviar os dados por email caso este ultrapasse um valor configurado. O sistema foi desenvolvido utilizando um microcontrolador PIC18F87J60 conectado à internet através de rede Ethernet e implementa protocolos como HTTP e SMTP para comunicação e envio de dados.
Droits d'auteur :
Attribution Non-Commercial (BY-NC)
Formats disponibles
Téléchargez comme PDF, TXT ou lisez en ligne sur Scribd
CMPUS GRAVATA MONITORAO AMBIENTAL REMOTA BASEADA EM MICROCONTROLADORES Renato Silveira Zorzin Monografia desenvolvida durante a disciplina de Trabalho de Concluso de Curso em Cincia da Computao II e apresentada ao Curso de Cincia da Computao da Universidade Luterana do Brasil, cmpus Gravata, como pr-requisito para a obteno do ttulo de Bacharel em Cincia da Computao. Orientador: Prof. Julio Carlos Balzano de Mattos Gravata, julho de 2008. 2 Universidade Luterana do Brasil ULBRA Curso de Cincia da Computao Cmpus Gravata Reitor: Pastor Ruben Eugen Becker Vice-Reitor: Eng. Leandro Eugnio Becker Diretor do Cmpus Gravata: Prof. Felcio Korb Coordenadora do Curso de Cincia da Computao (Cmpus Gravata): Prof. Patrcia Nogueira Hbler Coordenador das Disciplinas de Trabalho de Concluso de Curso (Cmpus Gravata): Prof. Roland Teodorowitsch Banca Avaliadora composta por: Data da defesa: 12/07/2008. Prof. Julio Carlos Balzano de Mattos Prof. Roland Teodorowitsch Prof. Elgio Schlemer CIP Catalogao na Publicao Zorzin, Renato Silveira Monitorao Ambiental Remota Baseada em Microcontroladores / Renato Silveira Zorzin; [orientado por] Julio Carlos Balzano de Mattos. Gravata: 2008. 74 p.: il. Trabalho de Concluso de Curso (Graduao em Cincia da Computao). Universidade Luterana do Brasil, 2008. 1. Mini Web Server. 2. Monitorao Ambiental. 3. Microcontroladores. I. Mattos, Julio Carlos Balzano de. II. Ttulo. Endereo: Universidade Luterana do Brasil Cmpus Gravata Av. Itacolomi, 3.600 Bairro So Vicente CEP 94170-240 Gravata-RS Brasil melhor tentar e falhar, que preocupar-se e ver a vida passar, melhor tentar, ainda que em vo, que sentar-se fazendo nada at o final. Eu prefiro na chuva caminhar, que em dias tristes em casa me esconder. Prefiro ser feliz, embora louco, que em conformidade viver ... Martin Luther King AGRADECIMENTOS Agradeo minha famlia pelo apoio nesta longa jornada, especialmente minha me e meu av por me proporcionarem a concluso desta etapa, tambm ao meu amor pela compreenso nos momentos de ausncia, e todos meus amigos que contriburam para que esta fase fosse concluda. A todos os professores e funcionrios da universidade, em especial, ao meu orientador Jlio Carlos Balzano de Mattos por sempre estar presente durante o perodo deste trabalho, me auxiliando de diversas maneiras. SUMRIO LISTA DE FIGURAS ............................................................................................................ 7 LISTA DE ABREVIATURAS E SIGLAS............................................................................ 8 RESUMO................................................................................................................................ 9 ABSTRACT.......................................................................................................................... 10 1 INTRODUO............................................................................................................... 11 2 MICROCONTROLADORES ........................................................................................ 13 2.1 FAMLIA PIC............................................................................................................. 13 2.1.1 Microcontrolador PIC18F87J60 ........................................................................ 14 3 PROTOCOLO TCP/IP ................................................................................................... 17 3.1 CAMADAS DA PILHA TCP/IP...................................................................................... 18 3.2 ESTABELECIMENTO DE CONEXES............................................................................. 19 3.3 ESPECIFICAES TCP................................................................................................ 20 3.4 PROTOCOLO IP.......................................................................................................... 21 3.5 ESPECIFICAES IP ................................................................................................... 22 3.6 HTTP........................................................................................................................ 23 3.7 SMTP....................................................................................................................... 24 4 IMPLEMENTAO DO PROJETO PROPOSTO...................................................... 26 4.1 ESPECIFICAO DO KIT.............................................................................................. 27 4.1.1 Interfaces disponveis ........................................................................................ 29 4.2 AMBIENTE DE DESENVOLVIMENTO ............................................................................ 30 4.3 PROJETO DE SOFTWARE ............................................................................................. 30 4.3.1 Implementao do projeto ................................................................................. 31 4.3.2 Estudo dos protocolos HTTP e SMTP............................................................... 31 4.3.2.1 Implementao do protocolo HTTP ......................................................... 32 4.3.2.2 Implementao do protocolo SMTP......................................................... 34 4.3.3 Implementao das pginas de controle............................................................. 36 4.3.4 Implementao do controle de temperatura e envio de e-mail ........................... 38 4.3.4.1 Aquisio da Temperatura........................................................................ 38 4.3.4.2 Gravar configuraes ............................................................................... 39 4.3.4.3 Envio de e-mail ........................................................................................ 40 4.4 PORTANDO O CDIGO PARA O DESTINO...................................................................... 41 4.5 TESTES REALIZADOS.................................................................................................. 42 4.5.1 Ambiente de testes............................................................................................. 42 4.5.2 Verificao de funcionamento........................................................................... 43 6 4.5.3 Tipos de testes ................................................................................................... 44 5 CONCLUSO.................................................................................................................. 45 ANEXO A PROGRAMAS DESENVOLVIDOS PARA O PROTTIPO. ................... 46 REFERNCIAS................................................................................................................... 73 LISTA DE FIGURAS Figura 1 Arquitetura do Microcontrolador PIC18F87J60 (MICROCHIP, 2008)................. 15 Figura 2 Pipeline no microcontrolador PIC (SILVA, 2006) ................................................ 16 Figura 3 Datagramas que trafegam na rede TCP/IP............................................................. 17 Figura 4 Arquitetura do TCP/IP........................................................................................... 18 Figura 5 Estabelecendo Conexo Inicial de um handshake de trs vias (COMER, 2004) ... 19 Figura 6 Formato de um segmento TCP com o cabealho TCP seguido de dados............... 20 Figura 7 Formato de um datagrama IP com o cabealho IP seguido de dados..................... 22 Figura 8 Principais mtodos do HTTP................................................................................. 24 Figura 9 Arquitetura simplificada do projeto....................................................................... 26 Figura 10 Mdulo PME10A................................................................................................ 28 Figura 11 Programador PicKit2........................................................................................... 29 Figura 12 Regulador LM1117 (3V3)................................................................................... 29 Figura 13 Modelo de ciclo de vida incremental................................................................... 30 Figura 14 Gerenciamento das conexes HTTP.................................................................... 32 Figura 15 Inicio da conexo com o servidor HTTP............................................................. 33 Figura 16 Tratamento de arquivos suportados pelo servidor HTTP..................................... 33 Figura 17 Definio da estrutura da mensagem SMTP........................................................ 34 Figura 18 Habilitando o envio de e-mail ............................................................................. 35 Figura 19 Estados do transporte do envio da mensagem ..................................................... 35 Figura 20 Pgina de monitorao da temperatura................................................................ 36 Figura 21 Modelo do XML implementado.......................................................................... 37 Figura 22 Pgina de configurao do e-mail........................................................................ 37 Figura 23 Pgina de configurao da placa de rede ............................................................. 38 Figura 24 Rotina de ordenao dos valores de temperatura................................................. 39 Figura 25 Rotina que transforma para valor de temperatura................................................ 39 Figura 26 Rotina de gravao dos dados da configurao do e-mail ................................... 40 Figura 27 Rotina que habilita o envio de e-mail .................................................................. 40 Figura 28 Funes responsveis pelo envio do e-mail......................................................... 41 Figura 29 Comunicao PC x Microcontrolador x PicKit2 ................................................. 42 Figura 30 Ambiente de teste utilizado ................................................................................. 43 Figura 31 Evidncia do e-mail enviado pelo microcontrolador ........................................... 44 LISTA DE ABREVIATURAS E SIGLAS A/D Analogic/Digital ASCII American Standard Code for Information Interchange CAN Controller Area Network CCP Compare Capture PWM CGI Common Gateway Interface CI Integrated Circuit CPU Central Procesing Unity DNS Domain Name System EEPROM Eletrically Erasable Programmable Read Only Memory FTP File Transfer Protocol GPRS General Packet Radio Service HTML HyperText Markup Language HTTP HyperText Transfer Protocol LCD Liquid Crystal Display LIN Local Interconnect Network I/O Input/Output ICMP Internet Control Message Protocol ICSP In-Circuit Serial Programming IRDA Infrared Data Association IP Internet Protocol MIME Multipupose Internet Mail Extensions MIPS Millions of Instructions Per Second OTP One Time Programable PWM Pulse Width Modulation RAM Random Access Memory ROM Read Only Memory RISC Reduce Instruction Set SMTP Simple Mail Transfer Protocol SPI Serial Peripheral Interface TCP Transmission Control Protocol UDP User Datagram Protocol USB Universal Serial Bus XML Extensible Markup Language RESUMO Atualmente existe uma grande necessidade de monitorar dados ambientais de forma remota atravs do uso da Internet. Os microcontroladores so muito utilizados para monitorao e controle de equipamentos. O uso de microcontroladores para implementao de servidores Web embarcados permitir fazer a monitorao ambiental de qualquer parte do mundo aliado ao baixo custo e consumo dos microcontroladores. Este trabalho possui como objetivo desenvolver um Mini Servidor Web e um cliente SMTP embarcado em um microcontrolador de baixo custo para a monitorao ambiental remota. Esta implementao exigiu um estudo criterioso dos protocolos HTTP e SMTP, bem como o estudo dos equipamentos que foram utilizados no prottipo, propiciando assim que arquiteturas mais simples possam utilizar-se da Internet para as mais diversas finalidades. Palavras-chaves: Mini Web Server; Monitorao Ambiental; Microcontroladores. ABSTRACT Title: Environmental Monitoring based on Microcontrollers Nowadays it is necessary to collect environment data remotely, using the Internet. The microcontrollers area used to monitor and control several equipments. With the use of microcontrollers to implement embedded Web servers it will be possible to monitor the environmental around the world allied the microcontrollers low cost and energy. This work aims to design an embedded Mini Web server and a SMTP client based on low cost microcontroller for the remote environmental monitoring. This implementation required a thorough study of the protocols HTTP and SMTP, and the study of equipment that were used in the prototype, thus providing simpler architectures that can use the Internet for many different purposes. Key-words: Mini Web Server; Environmental Monitoring; Microcontrollers. 1 INTRODUO Atualmente existe um grande interesse da populao mundial sobre a proteo do meio ambiente. Relacionado a isto, diversas organizaes governamentais e no governamentais cada vez mais necessitam de equipamentos que realizem a monitorao dos mais diversos dados como, por exemplo, temperatura, presso, ndice de gs carbnico, entre outros. Estes equipamentos de monitorao podem ser disponibilizados em cidades como tambm em reas isoladas (reservas ambientais, etc.). O monitoramento ambiental pode ser definido como um processo de coleta de dados, estudo e acompanhamento contnuo e sistemtico das variveis ambientais, visando identificar e avaliar qualitativa e quantitativamente as condies dos recursos naturais em um determinado momento, assim como as tendncias ao longo do tempo (variaes temporais) (PORRCA, 2000). As variveis sociais, econmicas e institucionais tambm so includas, por exercerem influncias sobre o meio ambiente. O monitoramento ambiental fornece informaes sobre os fatores que influenciam no estado de conservao, preservao, degradao e recuperao ambiental. O monitoramento ambiental um instrumento de controle e avaliao. Desta forma, subsidia medidas de planejamento, controle, recuperao, preservao e conservao do ambiente em estudo, bem como auxilia na definio das polticas ambientais. Dessa forma, as informaes geradas devem transmitir clareza aos tcnicos, aos tomadores de decises, comunidade cientifica e a toda sociedade que se quer analisar. Se a informao no bem entendida, no h clareza para avaliar os resultados, podendo haver distores, decises inadequadas ou at mesmo erradas. Os microcontroladores so encontrados nos mais diversos segmentos e um dos principais recursos para fazer aquisio de dados e controle de equipamentos principalmente devido ao seu baixo custo. Os microcontroladores podem ser instalados em locais onde no seja necessria a comunicao com o ambiente externo ou podem ter uma conexo remota, onde desta maneira, de qualquer lugar onde haja uma conexo disponvel pode-se conectar com este microcontrolador. Para disponibilizar uma conexo remota existem alguns requisitos como: o tipo de conexo que ser disponibilizada, pois o dispositivo dever ser acessado de qualquer local, o fornecimento de energia e a manuteno que poder sofrer, pois o microcontrolador poder estar em qualquer tipo de ambiente (inclusive em um local longnquo e de difcil acesso). A automatizao na obteno de dados com uma conexo remota ao microcontrolador permite o acesso aos dados em tempo real. Neste caso tem-se a necessidade de que os dados adquiridos pelo microcontrolador estejam disponveis de alguma forma. Para isto, ser utilizada uma arquitetura de baixo custo (microcontrolador) com um Mini Servidor Web 12 embarcado no microcontrolador. O microcontrolador utilizar para conexo o protocolo TCP/IP (TANENBAUM, 2003), que assim disponibilizar via Internet os dados adquiridos. Como estes dados estaro disponveis via Internet, o microcontrolador ir executar a funo de um mini servidor de Internet, mostrando os dados que foram armazenados no formato de uma pgina da Internet. Exemplos de servidores Web para aplicaes embarcadas podem ser encontrados no trabalho de Bentham (2001; 2002). Devido forma de comunicao com o microcontrolador ser feita atravs da Internet, o microcontrolador deve consumir o mnimo possvel de energia, quando o microcontrolador no estiver sendo acessado ele dever apenas fazer a aquisio e armazenamento dos dados na memria de tempos em tempos. Assim, o microcontrolador dever ficar em stand-by (consumindo um nvel muito baixo de energia). Porm, quando o microcontrolador sofrer uma interrupo de conexo ele voltar ao seu estado normal. Este trabalho pretende implementar os protocolos necessrios para que um sistema microprocessado possa disponibilizar atravs da Internet as informaes colhidas, alm desta forma sero disponibilizadas tambm as informaes colhidas atravs de e-mail. Para isto ser descrito o funcionamento dos protocolos usados para disponibilizar pginas de Internet e para envio de e-mails. Como os recursos disponveis neste tipo de equipamento so escassos, a otimizao, juntamente com a compatibilidade das funcionalidades implementadas, foi uma das principais metas. Inicialmente, no Capitulo 2 ser apresentado o microcontrolador, explicando o que um microcontrolador, bem como um resumo de seu funcionamento, ser apresentado tambm o microcontrolador que ser utilizado neste trabalho. No Capitulo 3 ser apresentado o protocolo que base para este trabalho, pois sem o protocolo TCP/IP no seria possvel a implementao dos outros protocolos. Incluindo tambm os protocolos HTTP (HyperText Transfer Protocol) e SMTP (Simple Mail Transfer Protocol) que fazem parte da pilha TCP/IP e sero os protocolos estudados para desenvolvimento deste trabalho. No Capitulo 4 discutido a implementao do projeto proposto. Sero vistas as opes de ferramentas de desenvolvimento que foram utilizadas para implementao, qual o ambiente de teste necessrio, os recursos de hardware do prottipo escolhido e suas interfaces, a implementao do projeto abordando como ele foi realizado, os problemas enfrentados e as solues encontradas, os testes que foram realizados, utilizado-se do hardware escolhido como prottipo. Por fim, no Capitulo 5, ser apresentada a concluso do trabalho. 2 MICROCONTROLADORES Microcontroladores tm como principal caracterstica de a semelhana com um microprocessador de propsito geral, contudo a principal diferena que os microcontroladores so produzidos em um nico circuito integrado (chip) (WIKIPDIA, [s.d.]a). Os microcontroladores possuem as memrias e interfaces digitais e analgicas integradas. Um microcontrolador um sistema computacional completo, no qual esto includos uma CPU (Central Processur Unit), memria de dados e programa, um sistema de clock, portas de I/O (Input/Output), alm de outros possveis perifricos, tais como, mdulos de temporizao e conversores A/D entre outros, integrados em um mesmo componente (DENARDIN, [s.d.]). Os microcontroladores so muito utilizados atualmente nas mais diversas aplicaes como mquinas de lavar, forno de microondas, telefones, etc. Os microcontroladores so suficientes em desempenho para uma grande quantidade de aplicaes, principalmente as embarcadas. O termo microcontrolador usado para designar o dispositivo que controla um processo ou algum parmetro do ambiente. Pode-se definir que um microcontrolador um CI (Circuito Integrado) com alta densidade de integrao que inclui, dentro do chip, a maioria dos componentes necessrios para o controlador. Atualmente existe uma grande quantidade de famlias de microcontroladores disponveis de diversos fabricantes. Os microcontroladores se diferenciam na arquitetura interna, quantidade de memria interna, velocidade de processamento, quantidade de entradas/sadas e perifricos. Nas Sees 2.1 e 2.1.1 ser apresentado o microcontrolador que ser utilizado no trabalho. 2.1 FAMLIA PIC Os microcontroladores PIC so fabricados pela Microchip Technolog,que processam dados de 8, 16 e 32 bits, com extensa variedade de modelos e perifricos internos, com arquitetura Harvard e conjunto de instrues Risc (Reduce Instruction Set Computer) (conjunto de 35 instrues e de 76 instrues), com recursos de programao por memria flash, EEPROM (Eletrically Erasable Programmable Read Only Memory) e OTP (One Time Programable). Os microcontroladores PIC possuem famlias com ncleos de processamento de 12, 14 e 16 bits e trabalham com velocidade de 0KHz (ou DC) a 48MHz, usando ciclo de instruo mnimo de quatro perodos de clock, o que permite uma velocidade de no mximo 10 MIPS (Milhes de Instrues Por Segundo). H o reconhecimento de interrupes tanto 14 externas como de perifricos internos. Funcionam com tenses de alimentao de 2 a 6V e os modelos possuem encapsulamento de 6 a 100 pinos em diversos formatos (WIKIPDIA, [s.d.]c). Os perifricos abaixo so caractersticos dos microcontroladores PIC: conversores Analgicos digitais de 8 a 12 bits; contadores e timer de 8 e 16 bits; comparadores Analgicos; USARTs; controladores de comunicao I2C, SPI, USB; controladores PWM; controladores LCD; controladores de motores; gerador de energia de alta potncia; perifricos para LIN, CAN; controladores Ethernet; perifricos IRDA; watchdog timer; detectores de falha na alimentao; portas digitais com capacidade de 25mA (fornecer ou drenar) para acionar circuitos externos; osciladores internos. 2.1.1 Microcontrolador PIC18F87J60 O microcontrolador PIC18F87J60 possui uma CPU de 8 bits, a sua arquitetura baseada no modelo Harvard e com um conjunto de instrues RISC. A sua interface de conexo feita atravs de uma placa ethernet de 10 Mbps. Este modelo possui como principais vantagens: alto desempenho computacional; instrues e dados so transferidos separadamente; possui duas fases de pipeline, enquanto uma instruo executa a outra obtida; preo competitivo; nica palavra ampla de instrues: - aumenta eficincia; - reduz cdigo do programa; todas as instrues com palavras simples; maioria das instrues em apenas um ciclo. A Figura 1 apresenta a arquitetura interna do microcontrolador PIC18F87J60, onde nela pode-se visualizar todos os componentes que compem o microcontrolador. 15 Figura 1 Arquitetura do Microcontrolador PIC18F87J60 (MICROCHIP, 2008) Este microcontrolador possui sua arquitetura baseada no modelo Harvard, que apresenta barramentos de dados e endereos distintos, assim enquanto uma instruo executada, outra buscada da memria de programa. Este sistema de busca/execuo tambm conhecido como Pipeline. Os modelos dos microcontroladores PIC18F87J60 possuem oito novas instrues com um modo de endereamento indexado. Esta configurao foi concebida e ampliada neste dispositivo para otimizar as aplicaes desenvolvidas em linguagem de alto nvel C. So algumas caractersticas especiais deste microcontrolador: Comunicao: Este microcontrolador possui uma interface serial de comunicao para realizar a programao, e uma interface ethernet de comunicao do aplicativo desenvolvido. Mdulo CCP (Compare Capture PWM): O mdulo CCP feito para maximizar a flexibilidade no controle de aplicaes. Cada uma das trs CCP oferece mdulos de at quatro sadas PWM. 16 Conversor A/D de 10bits: Este modulo possui uma aquisio programvel de uma base de tempo e um canal que pode ser selecionado para iniciar a converso, sem esperar pelo programa, reduzindo um overhead do cdigo. Timer Watchdog: Esta verso possui um timer de 16 bits, permitindo um range maior de time-out. Existem dois tipos de memria flash neste microcontrolador: Memria de Progama; Memria RAM de dados. Este microcontrolador mesmo com suas restries, devido baixa quantidade de memria disponvel, se comparado a um computador pessoal, possui um desempenho muito bom devido a sua arquitetura em pipeline, na Figura 2 pode-se visualizar como executada uma instruo e a busca a instruo seguinte. Figura 2 Pipeline no microcontrolador PIC (SILVA, 2006) 3 PROTOCOLO TCP/IP Com a popularidade da Internet e o aumento exponencial do nmero de usurios, o protocolo TCP/IP tornou-se um padro de protocolo. Este protocolo no utilizado somente na Internet, mas tambm utilizado em pequenas redes residenciais bem como em grandes redes empresariais, pois estas redes internas alm da necessidade de visualizar as maquinas da rede, necessitavam de uma conexo com a Internet, por isso a crescente utilizao do protocolo TCP/IP. Na Internet possvel localizar os documentos que informam os padres do protocolo TCP/IP. Estes documentos so chamados de RFCs (Request for Comments). Estes documentos possuem uma abordagem detalhada sobre a implementao do protocolo. Neste capitulo alm de descrever o protocolo TCP/IP sero descritos tambm os protocolos HTTP e SMTP que fazem parte da camada de aplicao e estes dois sero implementados no projeto. O protocolo TCP/IP um conjunto de protocolos, seu nome, por exemplo, j fez referncia a dois protocolos que so os mais importantes dentro dos protocolos de comunicao: o TCP Transmission Control Protocol (protocolo de controle de transmisso) e o IP Internet Protocol (protocolo de Internet). Esses dois protocolos foram os primeiros a serem definidos (WIKIPDIA, [s.d.]b). Existem muitos outros protocolos que compe a pilha TCP/IP, como o FTP, o HTTP, o SMTP e o UDP entre outros. Em uma rede existem vrios nveis de protocolos que trafegam em forma de pacote. O termo pacote utilizado para indicar uma poro de dados que trafegam entre as estaes, o formato destes pacotes depende do protocolo. Abaixo a Figura 3 mostra um exemplo de pacote TCP contido em um datagrama IP. Figura 3 Datagramas que trafegam na rede TCP/IP 18 3.1 CAMADAS DA PILHA TCP/IP O protocolo TCP/IP possui uma pilha de estrutura de dados de quatro camadas, na Figura 4 pode-se observar os servios e protocolos que executam em cada camada da pilha. Figura 4 Arquitetura do TCP/IP Analisando a pilha pode-se observar que a camada mais prxima ao topo a camada mais prxima do usurio, enquanto as mais abaixo esto mais perto da transmisso fsica do dado. A camada de transporte tem a responsabilidade de informar o nvel de confiabilidade, pois o protocolo IP que est em uma camada mais abaixo foi projetado para no ser confivel. A seguir tem-se uma breve descrio de cada camada na pilha da sute IP (COMER, 2004): Camada de Aplicao: no nvel mais alto onde os usurios rodam programas aplicativos que acessam servios disponveis atravs de uma interligao em redes TCP/IP. Um aplicativo interage com um dos protocolos do nvel de transporte para enviar ou receber dados. Cada programa aplicativo escolhe o estilo de transporte necessrio, que tanto pode ser uma seqncia de mensagens individuais ou um stream de bytes. O programa aplicativo passa, para o nvel de transporte, os dados na forma adequada, para que possam, ento, serem transmitidos. O pacote relacionado camada de aplicao chamado Mensagem; Camada de Transporte: a primeira funo da camada de transporte prover a comunicao de um programa aplicativo para outro. Tal comunicao sempre chamada fim-a-fim. A camada de transporte pode regular o fluxo de informaes, assegurando que os dados cheguem sem erros e em seqncia. Para isso, o protocolo de transporte faz com que o lado receptor envie confirmaes e o lado transmissor retransmita pacotes perdidos. O software da camada de transporte divide o fluxo de dados transmitidos em pequenas partes e passe cada pacote, juntamente com o endereo de destino, camada seguinte para ser transmitido. O pacote da camada de transporte chamado Segmento; Camada de Internet: a camada da Internet trata do envio das informaes de uma mquina para outra. Aceita um pedido para enviar um pacote originrio da camada de transporte juntamente com uma identificao da mquina para a qual o pacote deve ser enviado. Encapsula o pacote em um datagrama IP, preenche o cabealho do datagrama, usa o algoritmo de roteamento para decidir se entrega o datagrama diretamente ou envia para o roteador e passa o datagrama para a interface de rede apropriada para transmisso. A camada Internet tambm lida com datagramas de entrada, verificando sua validade, e usa o algoritmo de roteamento para decidir se o datagrama deve ser processado no local ou se deve ser enviado. Para os datagramas endereados mquina local, o software da camada de interligao em redes apaga o cabealho do datagrama e, entre vrios protocolos de transporte, escolhe aquele que vai cuidar do pacote. Para finalizar, a 19 camada de Internet envia as mensagens de controle de erro ICMP como necessrio, e controla todas as mensagens ICMP que chegam. O pacote da camada de rede geralmente conhecido como Datagrama; Camada de Interface com a Rede: o nvel mais baixo do software TCP/IP compreende uma camada de interface de rede responsvel pela aceitao de datagramas IP e por sua transmisso atravs de uma rede especfica. Uma interface de rede pode consistir em um driver de dispositivo ou em um subsistema complexo que usa seu prprio protocolo de enlace de dados. O pacote da camada de interface de rede conhecido como Quadro. 3.2 ESTABELECIMENTO DE CONEXES Uma caracterstica do protocolo TCP a possibilidade de ele ser executado em um ambiente multitarefa, isto quer dizer que, mesmo que j tenha sido feita uma conexo, muitas outras podem estar em andamento simultaneamente. Para executar uma conexo foi criado o conceito de porta de conexo, as portas de conexo, so utilizadas para que um computador possa conectar a um servio de forma que as conexes fiquem isoladas em uma estao, assim podendo acessar determinados tipos de servio. Assim os processos que utilizam o TCP associam suas conexes s portas. Exemplos de portas atribudas servios so (SALAMON, 2002): 7: ECHO. Utilizada normalmente para verificar se um determinado servidor encontra-se ativo; 20 e 21: FTP ( File Transfer Protocol ); 23: Telnet; 80: HTTP ( Hipertext Transfer Protocol ). Para estabelecer uma conexo, o TCP utiliza um handshake de trs vias. Na hiptese mais simples, o handshake ocorre conforme a Figura 5. Figura 5 Estabelecendo Conexo Inicial de um handshake de trs vias (COMER, 2004) O primeiro segmento de um handshake pode ser identificado porque ele possui um conjunto de bits SYN no campo de cdigo. A segunda mensagem possui ambos os conjuntos de bits SYN e ACK, indicando que confirma o primeiro segmento SYN e continua o handshake. A mensagem final de handshake apenas uma confirmao e utilizada 20 simplesmente para informar ao destino que ambos os lados concordam em que uma conexo foi estabelecida. Normalmente, o software TCP de uma mquina espera passivamente pelo handshake e o software TCP de outra mquina o inicia. Entretanto, o handshake projetado para funcionar mesmo se ambas as mquinas tentarem iniciar uma conexo simultaneamente. Assim, uma conexo pode ser estabelecida de qualquer extremidade ou de ambas simultaneamente. Quando a conexo tiver sido estabelecida, os dados podem fluir igualmente bem nas duas direes. O handshake de trs vias necessrio e suficiente para a sincronizao correta entre as duas extremidades da conexo. O TCP cria pacotes como base no servio de transmisso no- confivel de pacotes, podendo as mensagens ser perdidas, retardadas, duplicadas, ou entregue fora de ordem. Assim, os protocolos precisam usar um mecanismo de timeout e retransmitir as solicitaes perdidas. Surgem problemas se as solicitaes originais e as retransmitidas chegarem quando a conexo estiver sendo estabelecida, ou se as solicitaes retransmitidas forem retardadas at depois que uma conexo tiver sido estabelecida, utilizada e concluda. 3.3 ESPECIFICAES TCP A unidade de transferncia entre o software TCP de duas mquinas denominada de segmento (COMER, 2004). Os segmentos so trocados para estabelecer conexes, transferir dados, enviar confirmaes, informar tamanhos de janelas e encerrar conexes. J que o TCP utiliza piggyback, uma confirmao que trafega da mquina A para a mquina B pode trafegar no mesmo segmento que os dados que trafegam da mquina A para a mquina B, embora a confirmao refira-se aos dados enviados de B para A. O protocolo TCP responsvel por deixar a comunicao robusta, estabelecendo uma conexo entre cliente e servidor que garante o recebimento dos dados enviados .Na Figura 6 pode-se visualizar o formato do segmento TCP. Figura 6 Formato de um segmento TCP com o cabealho TCP seguido de dados A seguir pode-se verificar a definio dos campos de um segmento TCP: 21 Porta de Origem (16 bits): nmero da porta origem, que identifica o processo que enviou os dados; Porta de Destino (16 bits): nmero da porta destino, que identifica o processo remoto que deve tratar os dados enviados; Nmero de Seqncia (32 bits): o nmero do primeiro octeto (byte) dentro do segmento (exceto se o flag SYN estiver presente). Se o flag SYN estiver presente, este representa o primeiro nmero de seqncia (ISN); Nmero de Reconhecimento (32 bits): se o flag ACK estiver definido, este campo ter o valor do prximo nmero de seqncia esperado; HLEN: contm um nmero inteiro que especifica o comprimento do cabealho do segmento, medido em mltiplos de 32 bits. Reservado: este campo reservado para utilizao futura; Bits de Cdigo (6 bits): utilizado para determinar a finalidade e contedo do segmento. - URG: Campo de ponteiro urgente valido; - ACK: Campo de reconhecimento valido; - PSH: Este segmento requer push; - RST: Derruba a conexo; - SYN: Sincronizar os nmeros de seqncia; - FIN: O emissor atingiu o final do fluxo de bytes. Janela (16 bits): tamanho da janela de dados que o protocolo TCP espera receber; Soma de Verificao (16 bits): soma de verificao dos dados; Ponteiro Urgente (16 bits): ponteiro para os dados urgentes, usado somente quando o flag URG estiver definido, indica o final da rea dos dados urgentes; Opes (24 bits): este campo no requerido para a maioria dos datagramas, utilizado para testes e depurao; Enchimento (8bits): este campo varivel, utilizado para preenchimento, de forma que a barreira limite de trmino do cabealho acabe em mltiplos de 16 bits. 3.4 PROTOCOLO IP Conforme Comer (2004), o objetivo do protocolo IP fornecer uma rede virtual com vrias redes fsicas que oferea um servio de entrega de datagramas sem conexo. Este nvel no se preocupa com a integridade dos dados. O protocolo IP implementa o conceito da entrega de pacotes sem conexo. Esta denominao especifica que cada pacote independente dos demais. Um certo nmero de pacotes enviados podem trafegar por vrios percursos diferentes, serem perdidos, danificados, ou mesmo chegar ao destino fora de ordem. Os aspectos mais relevantes que o protocolo implementa so: fragmentao de pacotes, adequando o tamanho dos fragmentos capacidade da rede. roteamento, ou seja, a escolha de um caminho por onde os pacotes sero enviados. Alm disso o protocolo especifica as regras de como os dados devem ser tratados por roteadores e estaes durante sua permanncia na rede. Os servios que o protocolo IP fornece so atendidos por quatro caractersticas implementadas em seu cabealho, so eles: tipo de servio, tempo de vida de um pacote, campo de opes e dado de soma de verificao de integridade de cabealho. 22 A qualidade do servio de entrega desejado especificada no campo tipo de servio. Este campo pode especificar o uso de servios desejados para o pacote e usados por entidades da rede para tomada de decises de roteamento. O tempo de vida de um pacote especifica o quanto um pacote deve permanecer na rede at que ele seja descartado, antes de chegar ao destino. Sua utilidade pode ser percebida pelo fato de que pacotes no entregues poderiam ficar trafegando na rede indefinidamente, causando trafego desnecessrio. O campo de opes prov meios de controle para situaes no muito comuns e que normalmente no so utilizadas para a maioria das comunicaes. H tratamento para segurana, roteamento e relgios. A integridade do cabealho assegurada pelo campo soma de verificao, que pode ser conferido para validao. Os dados enviados junto ao cabealho podem conter erros, mas no h qualquer indicao para sua verificao. Em caso de um cabealho estar corrompido, o pacote automaticamente descartado. Este modelo de operao pressupe que os integrantes da rede tenham mdulos IP idnticos residentes em cada unidade que faz parte desta rede. Desta forma podem compartilhar das caractersticas que o protocolo implementa. 3.5 ESPECIFICAES IP Alm de guiar os datagramas, o IP pode fragment-los. Isso feito no caso de redes que suportam apenas pacotes pequenos. Neste caso existe sempre o consentimento de quem originou o pacote. O cabealho IP tambm possui um checksum (Verificao da soma do cabealho) para garantir a integridade do cabealho (MOKARZEL e CARNEIRO, 2004). O datagrama IP encontra-se especificado na RFC 791 (COMER, 2004). O cabealho apresentado na Figura 7. Figura 7 Formato de um datagrama IP com o cabealho IP seguido de dados As definies dos campos do datagrama IP so: VERS (4 bits):contm a verso do protocolo IP utilizada para criar o datagrama. HLEN (4 bits):fornece o comprimento do cabealho do datagrama medido em palavras de 32 bits. Tipo de Servio (8 bits):determina como o datagrama deve ser tratado e est subdividido em cinco subcampos: 23 - precedence (bits 0-2): especificam a precedncia do datagrama com valores variando de zero (precedncia normal) at sete (controle de rede). - D (bit 3): especifica o tipo de transporte que o datagrama deseja, quando definido solicita um intervalo baixo. - T (bit 4): especifica o tipo de transporte que o datagrama deseja, quando definido solicita um throughput alto. - R (bit 5): especifica o tipo de transporte que o datagrama deseja, quando definido solicita alta confiabilidade. - bit 6 e 7: reservado para uso futuro. Comprimento Total (16 bits): fornece o comprimento do datagrama IP medido em octetos, incluindo octetos no cabealho e nos dados. Identificao (16 bits): utilizado para identificao do datagrama, fornecendo um nmero inteiro e nico (utilizado para controle de fragmentao). Flags(3 bits): bits de controle de fragmentao: - bit 0: reservado, deve ser zero. - bit 1: no fragmentar o datagrama. - bit 2: ltimo fragmento. Deslocamento do Fragmento (13 bits): especifica o deslocamento do datagrama quando fragmentado. Tempo de Vida (8 bits): especifica em segundos o tempo que o datagrama pode permanecer no sistema de interligao em rede antes de ser descartado. Protocolo (8 bits): informa qual o protocolo de alto nvel foi utilizado para criar a mensagem. Verificao da soma do cabealho (16 bits):soma de verificao dos dados do cabealho somente. Endereo IP de origem (32 bits): endereo IP do transmissor. Endereo IP de destino (32 bits): endereo IP do destino do datagrama (receptor). Opes IP (24 bits): campo utilizado para testes ou depurao da rede. No necessrio em todo o datagrama. Padding (8 bits): utilizado para preenchimento com bits visando garantir que o cabealho seja mltiplo de palavras de 32 bits. 3.6 HTTP O Hypertext Transfer Protocol (HTTP) o protocolo de pedido e resposta que oferece suporte para a World Wide Web. Ele um protocolo em nvel de aplicao, assim como o File Transfer Protocol (FTP) e o Telnet. No entanto, ao contrrio desses protocolos, HTTP no tem estado. O HTTP foi concebido em 1990 e tem sido o protocolo que transporta uma parte significativa do trfego na Internet desde 1995. O HTTP usado para transmitir informaes em vrios formatos, idiomas e conjunto de caracteres. O contedo do corpo de uma mensagem HTTP tratado cegamente pelo protocolo no feita qualquer interpretao (REXFORD e KRISHNAMURTHY, 2001). Em princpio, o HTTP simples: permite a um navegador solicitar um item especfico, que o servidor ento retorna. Para assegurar que navegadores e servidores possam interoperar de forma no-ambgua, o HTTP define o formato exato das requisies enviadas de um navegador a um servidor como tambm o formato das respostas que o servidor retorna. 24 Por meio dele os navegadores como o Internet Explorer, Firefox, entre outros, buscam nos servidores as pginas Web. O http utiliza um relacionamento do tipo cliente/servidor, em que o cliente envia um comando, conhecido como mtodo, e o servidor responde enviando uma ou mais mensagens (MOKARZEL e CARNEIRO, 2004). Existem trs mtodos principais, que sero apresentados na Figura 8. Figura 8 Principais mtodos do HTTP O protocolo HTTP pode ser utilizado para realizar a transferncia de arquivos em qualquer formato, alm do HTML tradicional. A combinao do uso de servidores de HTTP, HTML e browsers forma o que chamamos de Web. Por causa deste nome, os servidores que utilizam este protocolo so conhecidos como servidores Web. Um fato interessante sobre o funcionamento dos browsers, que so os principais clientes deste tipo de servidor, que eles abrem diversas conexes simultneas com o servidor. Isto feito para que eles possam receber ao mesmo tempo os diversos elementos de uma pgina HTML que so armazenados como arquivos independentes. Outro fato importante que podem ser executados comandos no servidor, para que possam ser geradas pginas com algum tipo de contedo especial, como, por exemplo, dados contidos em uma base de dados (ZEILMAN, 2002). 3.7 SMTP Quando um programa de transferncia de correio contata um servidor em uma mquina remota, ele forma uma conexo de TCP atravs da qual se comunica. Uma vez que a comunicao foi estabelecida, os dois programas seguem o Simple Mail Transfer Protocol (SMTP), que permite ao remetente se identificar apropriadamente, especificar um receptor e transferir uma mensagem de e-mail. A utilizao em massa deste protocolo iniciou na dcada de 80. Embora a transferncia de correio possa parecer simples, o protocolo SMTP trata de muitos detalhes. Por exemplo, o SMTP exige entrega confivel o remetente deve manter uma cpia da mensagem at que o receptor tenha armazenado uma cpia em memria no- voltil (por exemplo, em disco). Alm disso, o SMTP permite ao remetente perguntar se existe uma determinada caixa de correio no computador remoto (COMER, 2004). Cada parte de uma correspondncia eletrnica enviada aps uma negociao inicial a respeito de quem o emissor original, e de quem o receptor original. Quando um processo servidor SMTP concorda em aceitar uma correspondncia para um recebedor em particular, ele assume tambm a responsabilidade de enviar a correspondncia para o usurio, se ele for local, ou pass-la a diante, se o usurio for remoto. No caminho percorrido por uma mensagem que trafega na rede, um caminho reverso tambm executado, tornando possvel que se notifique ao emissor original a respeito de possveis falhas. 25 Para enviar uma correspondncia eletrnica, o cliente SMTP certifica-se primeiramente do endereo IP do computador destinatrio atravs do servio de diretrios DNS (Domain Name System), e em seguida utiliza este endereo, juntamente com a porta SMTP (porta 25), para poder iniciar o estabelecimento da conexo de transporte com o servidor SMTP no computador destinatrio. Depois de estabelecida a conexo, o cliente inicia a transferncia da correspondncia para o servidor Uma mensagem de correio eletrnico tem um formato bem simples. A mensagem consiste em texto ASCII que separado em duas partes por um linha em branco. Chamada de cabealho (header), a primeira parte contm informaes sobre a mensagem: o remetente, os receptores, a data que a mensagem foi enviada e o contedo. A segunda parte conhecida como corpo; contm o texto da mensagem. Embora o corpo de uma mensagem possa conter texto arbitrrio, o cabealho segue uma forma padro que o software de e-mail usa ao enviar uma mensagem. O SMTP usado na comunicao direta entre servidores de correio e para o envio de mensagens a partir do seu software cliente de e-mail. O SMTP um protocolo que as suas mensagens podem ser enviadas ou recebidas pelo servidor de correio, mas no possvel recolher as mensagens em qualquer outro servidor de correio com o uso deste protocolo, isso quer dizer que quando uma mensagem enviada para um servidor, somente ele capaz de receber essa mensagem. Existe alguns outros protocolos de envio de mensagens, porm o mais utilizado o protocolo SMTP, onde a sua definio pode ser encontrada na RFC 2821 (KLENSIN, 2001) que define comandos e seqncias de comandos, bem como todas as informaes vlidas que podem ser colocadas nas mensagens. 4 IMPLEMENTAO DO PROJETO PROPOSTO O objetivo final deste projeto permitir que um sistema microprocessado possa de conectar-se a Internet e disponibilizar pginas da Web e envio de e-mails, utilizando-se um servidor HTTP e um cliente SMTP, que foram especialmente implementados para este fim. O servidor HTTP foi implementado por ser o protocolo padro para disponibilizar pginas na Internet. Para realizar a implementao deste protocolo teve-se a necessidade de utilizar uma pilha TCP/IP, neste caso no foi necessrio implement-la, pois foi utilizada a pilha disponibilizada no microcontrolador, que foi desenvolvida pela Microchip. O protocolo TCP/IP fundamental nessa aplicao, pois o protocolo TCP fornece um dos principais servios: a comunicao segura entre duas estaes, e o protocolo IP o meio pelo qual os pacotes so enviados ao nvel fsico, ao destino da conexo. O cliente SMTP foi implementado para que houvesse uma forma de que o microcontrolador pudesse enviar mensagens da temperatura capturada, onde esta foi a finalidade para este projeto, mas para que tambm houvesse um meio em que o usurio pudesse ser notificado de algum evento. A Figura 9 mostra a arquitetura que foi desenvolvida e utilizada neste trabalho. Figura 9 Arquitetura simplificada do projeto Para que uma aplicao possa utilizar os recursos implementados em forma de uma biblioteca, foi necessrio criar uma interface para disponibilizar estes recursos de comunicao, de forma a manter um isolamento e tornar o seu uso mais simples e seguro. O projeto final inclui, alm do desenvolvimento da biblioteca do servidor HTTP e cliente SMTP, o desenvolvimento de um prottipo para que se possa realizar os testes e avaliaes. Para que os objetivos fossem atingidos alguns desafios foram enfrentados. Alguns deste desafios so: 27 Microcontrolador: Decidiu-se pelo uso de determinado microcontrolador, o qual foi estudado. Para isto foi necessrio obter o conhecimento de como so controlado os recursos de memria, quais instrues esto disponveis, quais recursos especiais ele apresenta e como utiliz-los. Quantas entradas e sadas digitais e analgicas ele possua, bem como quais estavam sendo utilizadas e quais estavam disponveis. Kit de Desenvolvimento: por se tratar de um projeto com implementao prtica ser utilizado um kit de desenvolvimento, onde neste caso, foi realizado um estudo comparativo de vrios kits disponveis no mercado, afim de buscar um que se adaptasse melhor ao problema proposto. A aquisio de conhecimento do kit de desenvolvimento utilizado foi determinante para que a implementao pudesse tirar proveito destes. de acordo com a especificao do hardware que deve-se configurar corretamente a ferramenta de gerao de cdigo. Mplab18: O compilador escolhido para a montagem dos cdigos tambm foi estudado. Somente com o pleno conhecimento de suas funcionalidades foi possvel usufruir de todos os recursos disponibilizados pelo compilador. O principal desafio foi conhecer como a ferramenta deve ser utilizada, saber como a ferramenta deve ser configurada para as necessidades deste trabalho. Pilha TCP/IP: Foi necessrio realizar um estudo da pilha TCP/IP que j est desenvolvida no microcontrolador, pois esta biblioteca, que foi desenvolvida atravs de Socket,ser fundamental para o desenvolvimento do trabalho. Servidor HTTP e Cliente SMTP: Foi necessrio conhecer os detalhes do funcionamento que fazem com que cada protocolo tenha suas caractersticas prprias, como cada um interage com os demais, de que forma uma aplicao usar os recursos, quais pontos crticos de cada protocolo devem ter um tratamento especial e qual a melhor forma de resolv-los. Aqui o conhecimento dos detalhes de funcionamento da pilha TCP/IP e do hardware utilizado extramente importante. Estes so alguns dos desafios que este estudo proporcionou nesta rea. Ambiente de testes: O prottipo desenvolvido para testes, tem como objetivo mostrar o que foi implementado, sendo assim atravs de um navegador Web e um software capaz de receber e-mail, pode-se verificar o funcionamento do que foi implementado no projeto. Foi necessrio tambm um estudo no equipamento que faz a medio de temperatura, pois este sensor tambm faz parte do ambiente de teste do trabalho. Este ambiente envolveu um microcomputador sendo utilizado como cliente, conectado via cabo Ethernet ao sistema de desenvolvimento. Este proporcionou os meios para visualizao da pgina desenvolvida e o recebimento de mensagens enviadas pelo prottipo. O desenvolvimento de cada atividade no ocorreu de forma isolada. Todas tem relao e devem ser priorizadas medida que o andamento de uma implique a realizao da outra. Para que o projeto ocorresse dentro do prazo proposto, cada tarefa e suas implicaes foram avaliadas com antecedncia, quando possvel. 4.1 ESPECIFICAO DO KIT Para a implementao deste projeto, foi necessrio uma plataforma com caractersticas especificas, empregadas em um sistema de controle e monitorao. Este equipamento deve ser 28 composto de microcontrolador, entradas e sadas digitais/analgicas para interagir com o sistema, memria para guardar os dados adquiridos e o cdigo desenvolvido. Pesquisou-se por um hardware que tivesse ferramentas de desenvolvimento, compilador, depurador, foi considerado tambm que o hardware deveria ter um baixo custo e fcil manuteno, prevendo-se que em caso de danos ao hardware, poderia haver um comprometimento nos prazos para concluso do projeto. A escolha deste hardware foi definida por haver a interface Ethernet que indispensvel para a realizao do projeto. Outros itens tambm foram muito importantes na escolha, como memria, quantidade de entradas e sadas analgicas/digitais que o hardware comporta e as suas ferramentas de desenvolvimento. Entre algumas opes de hardware que foram localizadas para servir a base para implementao, foi selecionado o modelo PME10A (2EI, [s.d.]). Este modelo fornecido pela empresa 2EI (http://www.2ei.com.br), localizada em So Paulo. A unidade central desta placa um microcontrolador de 8 bits da Microchip modelo PIC18F87J60. As caractersticas desta placa so: Processador PIC18F87J60; 128 Kbytes de ROM Flash; 32 Kbytes de RAM; 55 portas I/O; EEPROM 25LC160; Interface Ethernet 10Mbps; Interface RS232; Conector ICSP; 8 x 8 ciclo nico de hardware multiplicador; 2 registradores de 8 bits; 3 registradores de 16 bits; Oscilador RC interno para baixo consumo de energia; A disponibilidade de recursos de memria e a variedade de interfaces definiu a escolha deste mdulo, que propicia facilidade de carga de verses, pois utiliza memria flash incorporada junto a prpria UCP. Este recurso tornou o desenvolvimento e depurao mais eficiente. Na Figura 10 mostrado o modulo PME10A. Figura 10 Mdulo PME10A Este chip de microcontrolador desenvolvido pela Microchip. Por ele ser sensvel a descargas eletrostticas, foi necessrio o uso de uma fonte reguladora, com isso se evitou problemas com sobrecargas. 29 Como o microcontrolador possui uma memria interna e esta utilizada na gravao dos dados, a performance de acesso aos dados mais otimizada, pois, evita a utilizao da memria de programa externa (EEPROM), onde o seu processo de desenvolvimento mais lento, pois, h a necessidade de apagamento e regravao da memria a ser utilizada. 4.1.1 Interfaces disponveis Para interao com o dispositivo de hardware alm dos recursos que ele j oferece, foi necessrio a aquisio de outros componentes. Os componentes adquiridos e os j disponveis so: Sensor de temperatura MCP9700; Programador Pickit2; Regulador LM1117(3V3); Interface USART RS232; Interface ICSP (Esta utilizada para cargas de programas); Interface Ethernet (Esta utilizada como interface de comunicao para a rede). Atravs destas interfaces foi possvel interagir com o sistema, permitindo que informaes de sua operao fossem visualizadas continuamente. Na Figura 11 pode-se visualizar o programador PicKit2 e na Figura 12 pode-se visualizar o regulador LM1117. Figura 11 Programador PicKit2 Figura 12 Regulador LM1117 (3V3) 30 4.2 AMBIENTE DE DESENVOLVIMENTO Para o desenvolvimento da lgica de operao dos protocolos, optou-se por um ambiente em 32 bits, que possibilitou o uso da ferramenta Mplab18 e com isso tornou-se o desenvolvimento mais fcil de ser administrado. A maior preocupao no desenvolvimento foi com a linguagem escolhida, que deveria ser obrigatoriamente implementada em C ANSI (American National Standards Institue). Essa obrigao foi devido ao compilador que transfere o cdigo para o microcontrolador que aceita somente este tipo de codificao, caso contrrio haveriam restries quanto ao cdigo. Outra vantagem de ter escolhido um ambiente para a plataforma Windows, foi quanto comunicao do compilador com o microcontrolador, pois a interface de transferncia do cdigo para o programador era USB (Universal Serial Bus), onde este responsvel em transferir o cdigo para a memria do microcontrolador e com isso fazendo o seu reconhecimento pelo computador no momento em que a sua interface de comunicao conectada (Plug and Play). 4.3 PROJETO DE SOFTWARE A implementao das bibliotecas HTTP e SMTP para ambiente de microcontroladores foi realizada baseando-se em tcnicas j existentes e realizada pela Microchip, o livro TCP/IP Lean (BENTHAM, 2002) e o livro Internet Embedded TCP/IP para Microcontroladores (MOKARZEL e CARNEIRO, 2004). Utilizando-se destas tcnicas foi possvel realizar a implementao destes dois protocolos, entendendo o seu funcionamento e suas particularidades. A seguir iniciada a implementao e na seqncia os testes para verificao de conformidade. medida que as especificaes vo sendo atendidas, novas so introduzidas, fazendo com que isto se torne um ciclo de programao e testes. A tcnica de desenvolvimento de software denominada de Ciclo de Vida Incremental. O modelo de desenvolvimento de software Ciclo de Vida Incremental pode ser visto na Figura 13. Esta tcnica foi utilizada pois devido ao curto espao de tempo para programao do projeto proposto, via-se uma grande necessidade de que cada etapa concluda, tivesse que ser testada, sendo assim em cada etapa concluda era possvel iniciar outra. Seguindo este fluxo, pode-se evitar nmero maior de erros o que tornaria mais difcil a depurao e localizao destes erros. Figura 13 Modelo de ciclo de vida incremental 31 O modelo de ciclo de vida incremental teve incio na fase de levantamento de requisitos, onde a cada protocolo estudado era feito o levantamento do que deveria ser implementado. Nesta fase pde-se obter o que seria necessrio ser testado, seus relacionamentos e a definio de sua arquitetura. O projeto avaliou as prioridades, definiu as funes e mdulos que podem ser compartilhados e a interao entre mdulos. Para que a codificao ficasse clara e de fcil entendimento foram introduzidos comentrios em todas as funes que foram desenvolvidas, pois este procedimento facilita o incremento de novos requisitos. A fase de testes serviu para que pudesse ser feita uma avaliao do que foi implementado e verificar o que ainda deveria ser implementado. 4.3.1 Implementao do projeto Para o desenvolvimento deste projeto foi necessrio adquirir o conhecimento sobre duas reas: os protocolos que seriam implementados e o hardware que foi escolhido para ser o prottipo da implementao. Para realizar o desenvolvimento era preciso que cada um dos itens fosse testados aps a sua implementao um a um, em funo disso resolveu-se separar a etapa de implementao lgica do projeto, da etapa de testes de hardware, com isso o erros que fossem encontrados seriam mais facilmente solucionados, pois no seria influenciado pelo desconhecimento de funcionamento do prottipo. Aps a primeira fase de aquisio de conhecimento dos protocolos que tinham que ser implementados, partiu-se para o estudo de funcionamento do hardware escolhido, pois, como o hardware seria o ambiente de teste, fundamental que o conhecimento em cima da plataforma seja a melhor possvel. Foi necessrio tambm alm do conhecimento em cima do hardware, adquirir tambm o conhecimento da ferramenta que realiza a compilao do projeto e a transferncia do cdigo para o microcontrolador. Obtendo-se o conhecimento em todos os itens falados anteriormente, j era possvel ter uma base para incio da codificao do projeto. Para o desenvolvimento do projeto foi utilizada uma plataforma de 32 bits, utilizando- se de um compilador. Este compilador era composto de: compilador, editor e transferncia de dados para o microcontrolador. Com este software era possvel verificar passo a passo o que foi implementado e o que est sendo executado, o nome do software utilizado para desenvolvimento era Mplab18, que tinha a capacidade de realizar uma depurao no cdigo. 4.3.2 Estudo dos protocolos HTTP e SMTP Tendo em mente que os recursos disponibilizados so limitados, os protocolos HTTP e SMTP foram criados de maneira otimizada. Como a UCP no pode estar alocada somente para executar o que ser implementado, foi necessrio desenvolver funes de gerenciamento das aes que devero ser tomadas. Com isso a implementao teve que ser feita utilizando funes. Estas mesmas funes so responsveis tambm em estabelecer uma comunicao com o protocolo TCP/IP, portanto, como a pilha TCP/IP foi desenvolvida utilizando SOCKET, necessrio que tanto o SMTP quanto o HTTP utilizem os recursos que foram disponibilizados atravs de SOCKET pelo TCP/IP. Alguns detalhes de cada protocolo foram otimizados para atingir um uso mais racional dos recursos, sem com isto descuidar da compatibilidade. 32 Para a implementao do protocolo HTTP foi necessrio um estudo de seu funcionamento, onde foi fundamental o estudo da RFC 2616 (FIELDING et al., 1999) para saber qual o comportamento esperado deste protocolo e suas funcionalidades bsicas. O mesmo ocorreu para o protocolo SMTP, tendo tambm que realizar um estudo da RFC 2821 (KLENSIN, 2001) para tambm saber como funciona este protocolo, como, por exemplo, foi necessrio saber como montar a mensagem que ser enviada. Na implementao do protocolo SMTP teve que se disponibilizar o desenvolvimento do protocolo com autenticao, pois hoje alguns servidores SMTP exigem que o cliente SMTP seja autenticado, portanto este cuidado teve que ser tomado, devido a essa particularidade. 4.3.2.1 Implementao do protocolo HTTP Para o desenvolvimento do protocolo HTTP foi necessrio um estudo da especificao que padroniza a codificao do tipo de protocolo que est sendo implementado, onde neste caso a RFC 2616 (FIELDING et al., 1999). A implementao respeitou alguns passos que tiveram que ser tomados para que o protocolo funcionasse corretamente. O primeiro foi o desenvolvimento da base do servidor HTTP, nesta implementao foram desenvovidas as seguintes situaes: Conexo do HTTP com o TCP, caso no obtenha sucesso ele no consegue se conectar ao protocolo TCP e com isso no consegue realizar a sua funo; Verifica o tipo de pedido que foi realizado (GET/HEAD/POST); Realiza o parse da URL (Uniform Resource Locator) informada; Verifica se o arquivo que est sendo solicitado existe (pgina da web); Verifica se o tipo de arquivo que est sendo solicitado um arquivo vlido; Envia o arquivo para o display e encerra a conexo TCP; Estas operaes citadas anteriormente so um funcionamento otimizado do protocolo HTTP. Um servidor Web tem que estar disponvel para receber mais de uma conexo, portanto, para que isso fosse disponvel foi necessrio a implementao de uma rotina que pudesse ser executada sempre que uma requisio fosse enviada, assim nesta funo ela responsvel pelo gerenciamento da execuo dos processos do servidor Web. Na Figura 14 abaixo pode-se visualizar o trecho que executa esse gerenciamento. Figura 14 Gerenciamento das conexes HTTP 33 Verificando a Figura 14, pode se destacar que apesar da aplicao suportar mais de uma conexo, ela tem um limite de conexes que ela gerencia, pois em um ambiente microprocessado tem-se algumas limitaes e estas limitaes tem que ser tratadas, seno, a aplicao tende a ficar com um baixo processamento com isso gerando um desempenho no favorvel para a finalidade que o prottipo est sendo implementado. Na Figura 15 demonstrado o inicio de uma nova conexo com o servidor HTTP, neste caso verificada a conexo com a porta padro do HTTP, e depois passado o estado inicial da requisio. Figura 15 Inicio da conexo com o servidor HTTP Devido arquitetura ser limitada, como a memria que disposta para a implementao, foi necessrio fazer um tratamento para que somente alguns tipos de arquivos fossem validos, portanto, neste caso desta implementao so aceitos arquivos HTML, CGI, Java Script, XML caso seja algum outro tipo de arquivo que no seja do tipo suportado pela aplicao necessrio gerar um erro. Na Figura 16 pode-se verificar o tratamento realizado para esta situao. Os tipos de arquivos aceitos pela aplicao citados anteriormente, necessitam da utilizao de um programa a parte que torne estes tipos de arquivos interpretveis pelo microcontrolador. O programa utilizado se chama MPFS (Microchip File System), este programa fornecido pela Microchip e necessrio a sua utilizao para tornar os arquivos citados anteriormente interpretvel pelo sistema de arquivo do microcontrolador. Figura 16 Tratamento de arquivos suportados pelo servidor HTTP 34 Na biblioteca implementada para o servidor HTTP, que foi adaptada do modelo do servidor HTTP que a Microchip desenvolveu porm adaptado para este projeto, possui as chamadas das funes que so responsveis pela execuo continua do servidor, portanto, esta biblioteca teve que ser adicionada tambm na pilha TCP/IP, onde a chamada das funes que gerenciam o servidor http, conforme as Figuras 15 e 16, vistas anteriormente, estejam disponveis a cada nova conexo que seja estabelecida. A implementao do servidor HTTP contemplou os princpios bsicos do que o protocolo oferece, com isso a aplicao teve que ser bastante otimizada, se adequando ao ambiente microprocessado. 4.3.2.2 Implementao do protocolo SMTP Para o desenvolvimento do protocolo SMTP foi necessrio um estudo da especificao que padroniza a codificao do tipo de protocolo que est sendo implementado, onde neste caso a RFC 2821 (KLENSIN, 2001). Uma mensagem s pode ser enviada se ela possuir o formato que o protocolo SMTP exige, portanto, o primeiro procedimento implementado na biblioteca criada para o protocolo, foi a definio da estrutura que uma mensagem deve possuir. Na Figura 17 pode-se visualizar um trecho com a definio da estrutura e dos ponteiros de cada campo do cabealho SMTP. Figura 17 Definio da estrutura da mensagem SMTP Aps ter definido a estrutura da mensagem SMTP, que foi adaptada do modelo do servidor SMTP que a Microchip desenvolveu, porm adaptado para este projeto, foi necessrio realizar a implementao lgica da estrutura que ir enviar as mensagens. Esta implementao segue uma seqncia de funes, onde, nessas funes tambm tem que ser verificado se a execuo de envio de uma mensagem no est ativa, neste caso a mensagem no pode ser enviada, pois, tem que aguardar o trmino da execuo anterior. 35 Para realizar esta implementao, que verifica a situao que se encontra o cliente SMTP, foi implementado em uma funo que chamada no inicio do envio da mensagem, e se caso o cliente SMTP no esteja enviando nenhuma mensagem, carregado as variveis com todos os seus valores inicias que indicam que o cliente SMTP est pronto para enviar uma mensagem. Na Figura 18 pode-se visualizar a funo que realiza este procedimento. Figura 18 Habilitando o envio de e-mail Aps habilitar o envio de um e-mail outras funes implementadas so chamadas para que a mensagem possa ser enviada com sucesso, dentre essas funes teve-se a preocupao de realizar a separao de cada procedimento, assim, facilitando a localizao de um erro.Esta estrutura de programao foi baseada em um modelo da Microchip, porm adaptado para este projeto. A implementao possui uma funo que responsvel de executar as principais tarefas de conexo e envio do e-mail. Esta funo realiza as operaes de acordo com o estado do transporte da mensagem se encontra e conforme o estado do envio da mensagem. A Figura 19 mostra como os estados possveis do transporte da mensagem so tratados. Figura 19 Estados do transporte do envio da mensagem 36 A implementao teve como um princpio realizar as principais funcionalidades do protocolo SMTP, tendo em vista que essa implementao para um sistema microprocessado. As funes citadas acima e as outras que no foram demonstradas mas foram implementadas tiveram que ser otimizadas, para que se respeitasse os princpios bsicos do protocolo SMTP. 4.3.3 Implementao das pginas de controle A implementao das pginas de controle envolve principalmente a pgina de controle de temperatura e a pgina de configurao do e-mail. Para o desenvolvimento das pginas foi necessrio um estudo e conhecimento da linguagem padro da Internet, HTML. Esta implementao correspondente camada visual em que o usurio ir poder interagir com o prottipo. Na Figura 20 possvel visualizar como ficou a pgina que mostra os valores das quarenta e oito ltimas aquisies de temperatura do sensor. Figura 20 Pgina de monitorao da temperatura As temperaturas medida que vo sendo capturadas pelo sensor de temperatura, onde essa captura feita de trinta em trinta minutos, que com isso tem-se os quarenta e oito registros que so apresentados na tela, e que representam a aquisio de um dia inteiro, so apresentadas na tela de monitorao. Para que a pgina possa apresentar os valores adquiridos e gravados na memria, foi criado um arquivo XML que faz o papel intermedirio entre o programa que possui a rotina para pegar na memria os dados e a pgina que exibe estas informaes. Na Figura 21 pode- se verificar o modelo do XML implementado. 37 Figura 21 Modelo do XML implementado Os campos que aparecem dentro das tags do XML, so correspondentes aos campos que a funo em ajax carrega quando ela executada. Esta funo em ajax fornecida pela Microchip e nela somente informado como montar o XML e como deve ser a varivel no arquivo XML que ir receber o valor. Para o envio dos e-mails foi necessrio desenvolver a pgina de configurao do e- mail que ser enviado. Na Figura 22 pode-se verificar como ficou esta pgina. Figura 22 Pgina de configurao do e-mail Nesta pgina possvel fazer a configurao dos e-mails dos destinatrios, assim como possvel tambm realizar a configurao da placa de rede do prottipo. A configurao da placa de rede que aparece a configurao padro que vem na placa, portanto, para ter acesso ao prottipo necessrio somente configurar a sua rede de acordo com a configurao do prottipo. 38 Alm da configurao do e-mail possvel tambm realizar a configurao da placa de rede e na Figura 23 pode-se visualizar esta tela. Figura 23 Pgina de configurao da placa de rede 4.3.4 Implementao do controle de temperatura e envio de e-mail Para que as informaes que a pgina de controle necessita para informar para o usurio estejam disponveis, foi necessrio o desenvolvimento de um programa que tem a funo de: Buscar a temperatura recebida pelo sensor de temperatura que est gravada na memria. Gravar as configuraes para envio do e-mail. Enviar o e-mail com a ultima temperatura capturada pelo sensor. Realizando as trs funcionalidades citadas acima o software estar pronto para interagir com as pginas de controle. 4.3.4.1 Aquisio da Temperatura Como na pgina de controle sero mostrados sempre as quarenta e oito ultimas temperaturas capturadas pelo sensor, foram criados dois vetores que tm a funo guardar a temperatura. O primeiro vetor guarda a temperatura que o sensor est enviando e o segundo vetor guarda os valores que devero ser demonstrados na pgina de controle. Para a realizao deste controle foi feito uma fila de valores, que pode ser visualizada na Figura 24, que demonstra exatamente como foi feito no software de gerenciamento para realizar essa operao. Neste caso tem-se trs laos, onde o primeiro lao tem a funo de atualizar a temperatura atual na pgina, esta temperatura a temperatura que o sensor est enviando no 39 momento. O segundo lao guarda a temperatura no vetor de temperatura na pgina, e o terceiro lao faz a rotina de enfileirar todos os outros valores que j tinham sidos guardados. Figura 24 Rotina de ordenao dos valores de temperatura Aps os dados serem adquiridos necessrio que seja feita a converso do valor que est sendo enviado pelo sensor de temperatura para um valor decimal, onde este o valor real que dever ser apresentado nas pginas de controle de temperatura. Na Figura 25 apresentada a rotina para transformar o valor enviado pelo sensor em valor de temperatura. Figura 25 Rotina que transforma para valor de temperatura 4.3.4.2 Gravar configuraes A pgina de controle de temperatura possui tambm a possibilidade de realizar algumas configuraes. Essas configuraes so pertinentes s configuraes dos e-mails que iro receber as mensagens e tambm configurar o usurio e senha de autenticao do servidor de e-mail, que este exige que o cliente SMTP realize esta autenticao, portanto, estas configuraes teriam que estar disponveis para o usurio fazer o cadastro. Alm da necessidade de se tornar as configuraes mais flexveis, onde estas ficaram de mais fcil acesso estando na pgina de controle, esta implementao serviu tambm para testar o mtodo GET que foi implementado no servidor HTTP. Portanto, alm de testar a 40 gravao dos dados na memria, testou-se tambm os dados que a pgina estava enviando quando era executado o mtodo GET. Na Figura 26 pode-se visualizar um trecho do cdigo implementado que grava o destinatrio do e-mail. Figura 26 Rotina de gravao dos dados da configurao do e-mail Pode-se visualizar nesta rotina que h algumas chamadas de funes que executam a escrita na memria. As funes chamadas para a gravao dos dados so: XEEBeginWrite: esta funo passa por parmetro o endereo em que devera ser gravado o dado; XEEWrite: escreve o dado que passado por parmetro na memria; XEEEndWrite: Funo que verifica se o dado realmente foi gravado na memria. Executando essas funes tem-se a garantia de que o dado foi gravado realmente na memria EEPROM. 4.3.4.3 Envio de e-mail Para que o e-mail seja enviado, foi necessria a implementao de uma rotina que, atravs de um evento executa a rotina de envio de e-mail. Esta rotina busca as informaes que foram gravadas nas configuraes do e-mail, conforme foi escrito na seo 4.3.4.2. Neste caso foi criada uma rotina que envia e-mail uma vez por dia. enviado somente uma vez por dia em virtude de que quando o e-mail enviado o registro de temperatura do dia inteiro j foi realizado. Na Figura 27 pode-se visualizar um trecho do cdigo que verifica o tempo transcorrido para enviar o e-mail. Figura 27 Rotina que habilita o envio de e-mail 41 A rotina de envio de e-mail est configurada para enviar o e-mail sempre uma vez por dia, portanto, para que possa ser modificado este tempo de envio, necessrio que o programa seja modificado. Depois da verificao que habilita o envio de e-mail chamada a funo SMTPSendMail(). Esta funo responsvel por indicar que pode ser enviado o e-mail para o destinatrio. Aps isto chamada a funo SMTPTask que realiza os comandos de envio do e-mail. Este programa um programa extremamente importante para o projeto, pois o funcionamento desta lgica ir viabilizar o funcionamento do envio de e-mails pelo prottipo. A Figura 28 mostra a funo SMTPSendMail e os principais comandos da SMTPTask que so responsveis pelo envio do e-mail. Figura 28 Funes responsveis pelo envio do e-mail A importncia de uma lgica simples de envio de e-mail foi fundamental, pois neste caso os erros que pudessem ser ocasionados pela implementao do cliente SMTP seriam facilmente identificados, pois a parte mais crtica desta parte do projeto est no envio do e- mail. 4.4 PORTANDO O CDIGO PARA O DESTINO Aps a implementao da lgica de funcionamento dos protocolos, pgina de monitorao e controle dos dados, todos estes implementados no ambiente Windows de 32 bits, o cdigo foi portado para o ambiente final para o qual foi desenvolvido, ou seja, um microcontrolador de 8 bits. Aps a compilao do projeto no programa Mplab18, a sua transferncia e escrita na memria do microcontrolador realizada pela placa PicKit2, onde esta se comunica com o computador pela interface USB (Universal Serial Bus) e com o microcontrolador pela interface ICSP (In-Circuit Serial Programming). A Figura 29 mostra a arquitetura responsvel pela transferncia e comunicao do microcontrolador com a placa PicKit2 e com o computador. 42 Figura 29 Comunicao PC x Microcontrolador x PicKit2 Aps o cdigo ser portado para o ambiente de teste, foi possvel iniciar os testes de funcionamento das implementaes realizadas. Para realizar esta transferncia de cdigo para o ambiente microprocessado, foi necessrio realizar um estudo do funcionamento da placa PicKit2 e do programa Mplab18, onde seu funcionamento foi essencial para o projeto, tendo em vista que sem o correto funcionamento dessa etapa, no seria possvel transferir o cdigo para o ambiente microprocessado. 4.5 TESTES REALIZADOS Nas sees 4.5.1 e 4.5.2 sero descritos como foi disponibilizado o ambiente de teste, e tambm como foram realizados os testes do prottipo desenvolvido. 4.5.1 Ambiente de testes O ambiente de teste foi fundamental para que o projeto fosse concludo com sucesso. O planejamento antecipado de sua estrutura foi estipulado para que estivesse pronto quando iniciasse o teste de comunicao. Para a realizao dos testes foram necessrios alguns recursos para a montagem do ambiente planejado: Um microcomputador com uma porta Ethernet RJ-45; Software de desenvolvimento e software de acesso a pginas na Internet; Cabos de comunicao para interligao dos equipamentos; Kit PME10A (Kit composto do microcontrolador). Alm destes recursos foi necessrio utilizar um software fornecido pela Microchip, onde este software responsvel pela compilao do projeto, codificao do software desenvolvido e depurao do cdigo. O desenvolvimento no ambiente Windows permitiu conjugar as ferramentas desenvolvimento com as ferramentas que sero utilizadas para testar o que foi implementado. Como o objetivo deste projeto criar um servidor Web e um cliente de e-mails, foi necessrio a utilizao de um software de acesso a Internet, que neste caso o utilizado foi o Firefox e um software que receba os e-mails enviado pelo prottipo, que neste caso o utilizado foi o Outlook Express. Para testar a implementao do servidor Web ainda foi necessrio implementar uma homepage que ficou tambm hospedada no microcontrolador. Os software de acesso a Internet e recebimento de e-mail possuem exatamente as funcionalidades que so necessrias para verificar o funcionamento da aplicao, porm eles no possuem os recursos, caso haja um erro, de saber o que ocorreu. Portanto tambm foi 43 necessria a utilizao do editor nos testes realizados, j que este tem o recurso de depurar o que est ocorrendo na aplicao. A arquitetura utilizada para os testes composta de um servidor Web dois computadores e um switch. Todos perifricos esto conectados ao switch, em uma das portas do Switch est a conexo com a Internet, que teve que ser disponibilizada na rede, pois, para que o microcontrolador enviasse e-mails, era necessrio que ele tivesse uma conexo com a Internet disponvel. Na Figura 30 demonstra o ambiente que foi utilizado nos testes. Figura 30 Ambiente de teste utilizado Este ambiente simula exatamente a situao proposta, sendo assim, os problemas que pudessem aparecer, tiveram que ser tratados, solucionados e testados novamente no prprio prottipo, no havendo uma situao onde os testes no fossem fidedignos, pois os testes desde o inicio j tiveram que ser feitos em cima do prottipo elaborado. Com este ambiente de teste pode-se interagir diretamente com a aplicao desenvolvida. 4.5.2 Verificao de funcionamento Os testes das funcionalidades implementadas, foram realizados em todas as etapas do desenvolvimento do prottipo. Para um projeto ser de boa qualidade, necessrio que haja meios para comprovar a sua operao em conformidade com o que foi planejado. Para que isso seja possvel, foi desenvolvida uma interface de comunicao para que testes prticos pudessem ser realizados. Este recurso foi utilizado de forma a permitir que quem estiver testando pudesse interagir com a aplicao desenvolvida. Os recursos implementados no projeto permitem atender as seguintes caractersticas: Atendimento aos mtodos GET \ HEAD \ POST e a disponibilizar pginas de Internet (RFC 2616); Envio de mensagens SMTP (RFC 2821). Os protocolos descritos acima foram implementados de uma maneira otimizada, objetivando manter-se a compatibilidade com suas especificaes, eliminando alguns recursos que no trariam contribuio para seu uso em um ambiente microprocessado. 44 4.5.3 Tipos de testes Para a realizao da verificao das funcionalidades implementadas, foi utilizado um microcomputador interligado ao prottipo via porta de comunicao ethernet. O prottipo implementado deve se comportar como um servidor Web e um cliente SMTP. Os seguintes testes foram realizados: Em um navegador Web, foi colocado no endereo o IP do microcontrolador (10.0.0.101), e foi verificado se a pgina Web seria carregada no navegador. Na pgina que foi carregada, foi verificado se o sensor de temperatura estava fazendo a aquisio da temperatura e se os dados estavam sendo tratados corretamente pelo programa que faz o gerenciamento do dados. Na pgina de configurao foi adicionado os destinatrios dos e-mails que devem ser enviados, para isso foi testado tambm se a gravao dos dados estava sendo feita corretamente. Utilizando um software de e-mail foi verificado se os e-mails estavam sendo enviados pelo prottipo. Na Figura 31 pode-se visualizar a evidncia do e-mail recebido que foi enviado pelo microcontrolador. Figura 31 Evidncia do e-mail enviado pelo microcontrolador Na Figura 31 mostrado o e-mail que enviado com as temperaturas que o sensor de temperatura realizou a aquisio. Os valores enviados no e-mail so separados por vrgula para que os valores possam ser transportados para uma planilha. 5 CONCLUSO Este trabalho implementou os protocolos que so responsveis em disponibilizar pginas na Internet e para o envio de e-mail em um prottipo microprocessado de 8 bits. Foram implementados os protocolos HTTP e SMTP, tornado o prottipo utilizado plenamente funcional e apto para disponibilizar pginas da Internet, neste caso um servidor HTTP, e tambm apto para enviar e-mails, neste caso um cliente SMTP. Os protocolos implementados tiveram que ser muito estudados para que os requisitos que cada protocolo exige, fossem contemplados neste projeto. Com isso a aplicao se tornou vivel e compatvel com um sistema de capacidade computacional reduzida. A implementao deste projeto foi divida em trs fases. A primeira fase foi da construo lgica do servidor HTTP e cliente SMTP. A segunda fase foi da construo da interface que seria utilizada nos testes do projeto, onde esta etapa foi composta do desenvolvimento das pginas Web e do mdulo de gerenciamento e controle dos dados. A terceira fase foi realizada quando os protocolos e as pginas de teste j estavam prontos para serem testados por completo. Nesta fase foi portado o cdigo que foi construdo no ambiente de desenvolvimento para o compilador que responsvel por compilar e transferir o projeto para o ambiente microprocessado. Nas fases de construo dos protocolos e do mdulo de gerenciamento e controle dos dados, foi tomado o cuidado do desenvolvimento ser na linguagem C ANSI, pois assim, o cdigo em desenvolvimento seria portvel para o ambiente final. Nos testes realizados no prottipo ficou comprovado o funcionamento pleno do projeto. Demonstrou-se a capacidade deste desenvolvimento em ambientes microprocessado, sendo assim, possvel efetuar algumas funes de servidor Web e cliente SMTP. Permitindo a sua utilizao para ambientes especficos. Novas perspectivas se abrem e possibilidades de aprimoramento do projeto realizado. Ampliar as formas de conexes como o acesso via GPRS (General Packet Radio Service) seria um recurso possvel de implementao. Desta forma o acesso seria possvel de qualquer local do mundo, pois, seria somente necessrio um aparelho porttil com essa forma de conexo. Assim como seria possvel com esta arquitetura tornar o projeto vivel para qualquer outro tipo de aplicao embarcada, apenas adicionando os perifricos especficos para o foco ao qual est sendo utilizado. O desenvolvimento de um programa que verifique o e-mail que foi enviado pelo cliente SMTP e realize uma planilha com um grfico dos valores que foram capturados, tambm um trabalho futuro que dever ser realizado. ANEXO A PROGRAMAS DESENVOLVIDOS PARA O PROTTIPO. #define __NOBREAK_C #include "TCPIP Stack/TCPIP.h" /******************* * Variveis Globais *********************/ extern unsigned char USARTString_rec[15]; //----------------------------------- TEMPERATURA // array do vetor de temperatura unsigned char rec_temperatura_analogica[12][6]; // array do vetor de temperatura que ser mostrado no navegador unsigned char rec_tem_ana_nav[12][6]; // indice do vetor de temperatura unsigned char p_tem; unsigned char V_EVENTO_TEMPERATURA; unsigned char uchar_tem_atu[18]; //----------------------------------- REDE extern unsigned char grava_rede_parametros; // Endereo IP extern unsigned char Ip1; extern unsigned char Ip2; extern unsigned char Ip3; extern unsigned char Ip4; // Mscara de rede extern unsigned char M1; extern unsigned char M2; extern unsigned char M3; extern unsigned char M4; // Gateway extern unsigned char G1; extern unsigned char G2; extern unsigned char G3; extern unsigned char G4; // -------------------------------- EMAIL TICK EMAIL_Time_Out; // Timeout para recebimento de dados serial #pragma udata SMTP_Ass // buffer de recepo do email unsigned char SMTP_Ass[35]; // servidor de email unsigned char SMTP_Server[40]; // nome da conta do usuario unsigned char SMTP_Usuario[30]; // Senha da conta do usuario unsigned char SMTP_Senha[9]; #pragma udata SMTP_Dst1 // Identificao dos destinatrios unsigned char SMTP_Dst1[35]; unsigned char SMTP_Dst2[35]; // Habilitao ou no dos destinatrios unsigned char id_dst1_enable; unsigned char id_dst2_enable; // identifica qual destinatrio a ser enviado no correio eletronico unsigned char uchar_id_des; //identificao do remetente unsigned char SMTP_Rem[25]; // Quantidade de e-mail que devem ser enviados na ocorncia de um evento unsigned char quantidade_email; // Tempo para habilitar novamente evento a enviar email (em minutos) unsigned char tempo_email; // Usado para intervalo de e-mail TICK T_SMTP_Evento_subtensao_saida; // contador de e-mail enviado evento subtenso na sada unsigned char C_SMTP1_Evento_subtensao_saida; // contador de e-mail enviado evento subtenso na sada unsigned char C_SMTP2_Evento_subtensao_saida; // Status de envio do correio eletronico #pragma udata SMTP_enviando unsigned char SMTP_enviando; unsigned char SMTP1_Evento_subtensao_saida; unsigned char SMTP1_Evento_sobretensao_saida; unsigned char SMTP1_Evento_sobrecorrente_saida; unsigned char SMTP2_Evento_subtensao_saida; unsigned char SMTP2_Evento_sobretensao_saida; unsigned char SMTP2_Evento_sobrecorrente_saida; // ---------------------------------- USART 47 // Timeout para recebimento de dados serial extern TICK USART_Time_Out; // buffer de mensagem recebida serial - interrupo unsigned char rec[15]; // buffer de mensagem recebida serial para mostrar no navegador extern unsigned char USARTString_rec[15]; // ponteiro para mensagem extern unsigned char *p; // mudana de dados para Pgina Web unsigned char var_muda; // contador de bytes da serial (substitui 0x0D do HyperTerminal) unsigned char var_con_byt; /************************************************************** * Funo: void SMTP_Set(void) * Pr-Condio: * Entrada: * Sada: * Outros Efeitos: Nenhum * Funo: Processa informaes provenientes da serial USART * Notas: ***************************************************************/ void SMTP_Set(void) { TICK tr; //EVENTOS ON-LINE V_EVENTO_TEMPERATURA=1;
// S pode alterar eventos se no estiver enviando email // Evento subtenso na saida (o time-out s vai aceitar outro evento aps x minutos) if ( V_EVENTO_TEMPERATURA == 0x1 ) { // se a diferena entre tempos abaixo for maior que zero indica aptido para enviar e-mail tr = TickGet(); if ( tr > T_SMTP_Evento_subtensao_saida ){ // Eventos ocasionado SMTP1_Evento_subtensao_saida = 0x01; // Quantidade de e-mail a serem enviados na ocorrencia de evento C_SMTP1_Evento_subtensao_saida = quantidade_email; // S habilita enviar e-mail sobre este evento aps X minutos T_SMTP_Evento_subtensao_saida = TickGet() + 60*tempo_email*TICK_SECOND; SMTP2_Evento_subtensao_saida = 0x01; C_SMTP2_Evento_subtensao_saida = quantidade_email; } } } /************************************************************** * Funo: void SMTP_Verificar(void) * Pr-Condio: * Entrada: * Sada: * Outros Efeitos: Nenhum * Funo: Esta funo fica verificando o envio de emails * Notas: ****************************************************************/ void SMTP_Verificar(void){ // Ideia: enquanto no estiver transmitindo o time-out do correio sempre resetado // Enquanto estiver transmitindo o time-out do correio no resetado // Se o correio no chegar a desconectar estoura o time-out e volta a transmitir // Se estourar o time-out, desconecta, indica voltar a conectar e reseta o time-out if ((id_dst1_enable == 1) && (SMTP_enviando==0)) { // para enviar correio sobre este evento if ((SMTP1_Evento_subtensao_saida==1)&&(C_SMTP1_Evento_subtensao_saida>0)){ ram2ram( (char*)SMTP_Ass, (char*)uchar_tem_atu); uchar_id_des='1'; SMTP_enviando = 1; C_SMTP1_Evento_subtensao_saida--; if (C_SMTP1_Evento_subtensao_saida == 0) SMTP1_Evento_subtensao_saida=0; } } if ((id_dst2_enable == 1)&&(SMTP_enviando==0)) { if ((SMTP2_Evento_subtensao_saida==1)&&(C_SMTP2_Evento_subtensao_saida>0)){ ram2ram( (char*)SMTP_Ass, (char*)uchar_tem_atu); uchar_id_des='2'; SMTP_enviando = 1; C_SMTP2_Evento_subtensao_saida--; if (C_SMTP2_Evento_subtensao_saida==0) SMTP2_Evento_subtensao_saida=0; } } if (SMTP_enviando == 1) SMTPDemo(); } void SMTP_Init(void){ SMTP_enviando = 0; // indica que no deve enviar email SMTP1_Evento_subtensao_saida = 0; SMTP2_Evento_subtensao_saida = 0; EMAIL_Time_Out = TickGet(); // Variveis relacionas a quantidade de e-mails a serem enviados aps evento SMTP T_SMTP_Evento_subtensao_saida = TickGet(); } /********************************************************************* * Funo: void str2ram(static char *dest, static char rom *src) * PreCondition: * Input: * Output: * Side Effects: * Overview: Esta funo ler uma mensagem da memria FLASH interna e escreve 48 * em uma string na RAM * Note: ********************************************************************/ void str2ram(static char *dest, static char rom *src){ while ((*dest++ = *src++) != '\0'); } /********************************************************************* * Funo: void ram2ram(static char *dest, static char *src) * PreCondition: * Input: * Output: * Side Effects: * Overview: Esta funo ler uma mensagem da memria RAM e escreve * em uma string na RAM * Note: ********************************************************************/ void ram2ram(static char *dest, static char *src){ while ((*dest++ = *src++) != '\0'); } /********************************************************************* * Funo: void SMTPDemo(void) * PreCondition: * Input: * Output: * Side Effects: * Overview: Esta funo envia correio eletronico * Note: ********************************************************************/ static void SMTPDemo(void) { // Envia um nicp email static enum { MAIL_HOME = 0, MAIL_BEGIN, MAIL_SMTP_FINISHING, MAIL_DONE } MailState = MAIL_HOME; static TICK WaitTime; switch(MailState) { case MAIL_HOME: MailState++; break; case MAIL_BEGIN: if(SMTPBeginUsage()) { // Todas as string esto em RAM SMTPClient.Server.szRAM=SMTP_Server; // Nome da conta do usurio SMTPClient.Username.szRAM = SMTP_Usuario; // Senha da conta do usuario SMTPClient.Password.szRAM = SMTP_Senha; // Destinatrio do email if (uchar_id_des=='1') { SMTPClient.To.szRAM = SMTP_Dst1; } else{ SMTPClient.To.szRAM = SMTP_Dst2; } // Abaixo o que aparece no cabealho do destinatrio e nas as propriedades (ou seja, nome do remetente) SMTPClient.From.szRAM = SMTP_Rem; // Assunto e mensagem vo se confudir neste caso especfico (definido na hora do evento) SMTPClient.Subject.szRAM = SMTP_Ass; SMTPClient.Body.szRAM = SMTP_Ass; SMTPSendMail(); MailState++; } break; case MAIL_SMTP_FINISHING: if(!SMTPIsBusy()) { // Finished sending mail SMTPEndUsage();// == SMTP_SUCCESS; MailState++; WaitTime = TickGet(); } break; case MAIL_DONE: // Espera 15 segundos para habilitar envio de e-mail novamente if((TickGet() - WaitTime) > 15*TICK_SECOND){ MailState = MAIL_HOME; // volta a habilitar envio de email ou indica que acabou de enviar e-mail SMTP_enviando = 0; } break; } } void SMTP_Read_Configuracao(void){ BYTE c; unsigned char *p; // nome do servidor de correio eletronico p = (unsigned char*)&SMTP_Server; XEEBeginRead(0x00D0); for ( c = 0; c < sizeof(SMTP_Server); c++ ) { *p++ = XEERead(); } XEEEndRead(); // nome da conta no servidor de correio eletronico p = (unsigned char*)&SMTP_Usuario; XEEBeginRead(0x0100); for ( c = 0; c < sizeof(SMTP_Usuario); c++ ) { *p++ = XEERead(); } XEEEndRead(); // senha da conta no servidor de correio eletronico p = (unsigned char*)&SMTP_Senha; XEEBeginRead(0x0120); for ( c = 0; c < sizeof(SMTP_Senha); c++ ) { *p++ = XEERead(); 49 } XEEEndRead(); // Identificao do Remetente p = (unsigned char*)&SMTP_Rem; XEEBeginRead(0x0040); for ( c = 0; c < sizeof(SMTP_Rem); c++ ) { *p++ = XEERead(); } XEEEndRead(); // Identificao do Destinatrio 1 p = (unsigned char*)&SMTP_Dst1; XEEBeginRead(0x0060); for ( c = 0; c < sizeof(SMTP_Dst1); c++ ) { *p++ = XEERead(); } XEEEndRead(); // Identificao do Destinatrio 2 p = (unsigned char*)&SMTP_Dst2; XEEBeginRead(0x0090); for ( c = 0; c < sizeof(SMTP_Dst2); c++ ) { *p++ = XEERead(); } XEEEndRead(); // Habilitao ou no do destinatrio 1 para receber e-mail XEEBeginRead(0x00C0); id_dst1_enable = XEERead(); XEEEndRead(); // Habilitao ou no do destinatrio 2 para receber e-mail XEEBeginRead(0x00C1); id_dst2_enable = XEERead(); XEEEndRead(); // quantidade de e-mail repetidos a serem enviados na ocorrncia de evento XEEBeginRead(0x00C2); quantidade_email = XEERead(); XEEEndRead(); //tempo para e-mail ser enviado novamente na ocorrencia de evento em minutos XEEBeginRead(0x00C3); tempo_email = XEERead(); XEEEndRead(); } void SMTP_Write_Configuracao(void){ BYTE *ptr; WORD len; // nome do servidor de correio eletronico ptr = (BYTE*)SMTP_Server; XEEBeginWrite(0x00D0); for (len = 0; len < sizeof(AppConfig); len++ ) XEEWrite(*ptr++); XEEWrite(0x0); XEEEndWrite(); while(XEEIsBusy()); // nome da conta no servidor de correio eletronico ptr = (BYTE*)SMTP_Usuario; XEEBeginWrite(0x0100); for (len = 0; len < sizeof(AppConfig); len++ ) XEEWrite(*ptr++); XEEWrite(0x0); XEEEndWrite(); while(XEEIsBusy()); // senha da conta no servidor de correio eletronico ptr = (BYTE*)SMTP_Senha; XEEBeginWrite(0x0120); for (len = 0; len < sizeof(AppConfig); len++ ) XEEWrite(*ptr++); XEEWrite(0x0); XEEEndWrite(); while(XEEIsBusy()); // Identificao do Remetente ptr = (BYTE*)SMTP_Rem; XEEBeginWrite(0x0040); for (len = 0; len < sizeof(AppConfig); len++ ) XEEWrite(*ptr++); XEEWrite(0x0); XEEEndWrite(); while(XEEIsBusy()); // Identificao do Destinatrio 1 ptr = (BYTE*)SMTP_Dst1; XEEBeginWrite(0x0060); for (len = 0; len < sizeof(AppConfig); len++ ) XEEWrite(*ptr++); XEEWrite(0x0); XEEEndWrite(); while(XEEIsBusy()); // Identificao do Destinatrio 2 ptr = (BYTE*)SMTP_Dst2; XEEBeginWrite(0x0090); for (len = 0; len < sizeof(AppConfig); len++ ) XEEWrite(*ptr++); XEEWrite(0x0); XEEEndWrite(); while(XEEIsBusy()); // Habilitao ou no do destinatrio 1 para receber e-mail XEEBeginWrite(0x00C0); XEEWrite(id_dst1_enable); // Habilitao ou no do destinatrio 2 para receber e-mail XEEWrite(id_dst2_enable); // quantidade de e-mail repetidos a serem enviados na ocorrncia de evento XEEWrite(quantidade_email); //tempo para e-mail ser enviado novamente na ocorrencia de evento em minutos XEEWrite(tempo_email); XEEEndWrite(); while(XEEIsBusy()); } /************************************************************************* * Funo: void Temperatura_Init(void) * Pr-Condio: * Entrada: Nenhuma * Sada: Nenhuma * Outros Efeitos: Nenhum * Funo: Inicializao das variveis como luzes, ar ... * Notas: **************************************************************************/ void Temperatura_Init(void){ rec_temperatura_analogica[0][0] = 0; rec_temperatura_analogica[1][0] = 0; rec_temperatura_analogica[2][0] = 0; rec_temperatura_analogica[3][0] = 0; rec_temperatura_analogica[4][0] = 0; rec_temperatura_analogica[5][0] = 0; rec_temperatura_analogica[6][0] = 0; rec_temperatura_analogica[7][0] = 0; rec_temperatura_analogica[8][0] = 0; rec_temperatura_analogica[9][0] = 0; rec_temperatura_analogica[10][0] = 0; rec_temperatura_analogica[11][0] = 0; 50 rec_tem_ana_nav[0][0] = 0; rec_tem_ana_nav[1][0] = 0; rec_tem_ana_nav[2][0] = 0; rec_tem_ana_nav[3][0] = 0; rec_tem_ana_nav[4][0] = 0; rec_tem_ana_nav[5][0] = 0; rec_tem_ana_nav[6][0] = 0; rec_tem_ana_nav[7][0] = 0; rec_tem_ana_nav[8][0] = 0; rec_tem_ana_nav[9][0] = 0; rec_tem_ana_nav[10][0] = 0; rec_tem_ana_nav[11][0] = 0; uchar_tem_atu[0]='T';uchar_tem_atu[1]='e';uchar_tem_atu[2]='m' ;uchar_tem_atu[3]='p'; uchar_tem_atu[4]='e';uchar_tem_atu[5]='r';uchar_tem_atu[6]='a' ;uchar_tem_atu[7]='t'; uchar_tem_atu[8]='u';uchar_tem_atu[9]='r';uchar_tem_atu[10]='a';uchar_tem_atu[11]='='; p_tem = 0; } void Temperatura_Conversao(void) { unsigned char i,j,t; long int k; unsigned char uchar_can_4[8]; // bits 3 a 0 - somente AN0 a NA4 como entradas analgica ADCON1 = 0b00001010; // Seleciona canal AN4 (mdulo conversor A/D est desabilitado) ADCON0 = 0b00010000; // Right justify, 20TAD ACQ time, Fosc/64 (~21.0kHz) ADCON2 = 0xBE; // Habilita mdulo do conversor AD ADCON0bits.ADON = 1; // estabilizao do canal A4 t = 200; while( t-- ); // inicia converso ADCON0bits.GO = 1; // Espera converso terminar while( ADCON0bits.GO ); // transforma para valor de temperatura (ex. 18.4 est no formato 184) k =((( ((long int)256*(long int)ADRESH + (long int)ADRESL)*(long int)3300 ))/(long int)1024) - (long int)500; // somente para teste // k = 50*(long int)p_tem; // Converte valor da temperatura para String ASCII. itoa(k, uchar_can_4); if ( strlen(uchar_can_4) == 3) { rec_temperatura_analogica[p_tem][0]=uchar_can_4[0]; rec_temperatura_analogica[p_tem][1]=uchar_can_4[1]; rec_temperatura_analogica[p_tem][2]='.'; rec_temperatura_analogica[p_tem][3]=uchar_can_4[2]; rec_temperatura_analogica[p_tem][4]='C'; rec_temperatura_analogica[p_tem][5]=0x0; } if ( strlen(uchar_can_4) == 2) { rec_temperatura_analogica[p_tem][0]=uchar_can_4[0]; rec_temperatura_analogica[p_tem][1]='.'; rec_temperatura_analogica[p_tem][2]=uchar_can_4[1]; rec_temperatura_analogica[p_tem][3]='C'; rec_temperatura_analogica[p_tem][4]=0x0; } if ( strlen(uchar_can_4) == 1) { rec_temperatura_analogica[p_tem][0]='0'; rec_temperatura_analogica[p_tem][1]='.'; rec_temperatura_analogica[p_tem][2]=uchar_can_4[0]; rec_temperatura_analogica[p_tem][3]='C'; rec_temperatura_analogica[p_tem][4]=0x0; } for (i=0; i < 6; i++) { // atualiza temperatura atual uchar_tem_atu[i+12] = rec_temperatura_analogica[p_tem][i]; } j = 0; // transfere do apontador de temperatura atual at posio ndice 0 for (t=(p_tem+1); t>0; t--) { for (i=0; i <6; i++) { rec_tem_ana_nav[j][i] = rec_temperatura_analogica[t-1][i]; } j++; } // transfere do apontador ndice 11 at temperatura atual + 1 for (t=11; t > p_tem; t--) { for (i=0; i <6; i++) { rec_tem_ana_nav[j][i] = rec_temperatura_analogica[t][i]; } j++; } p_tem++; // ndice do vetor de temperatura // Ataualiza buffer que mostra no navegador pois a temperatura deve ser mostrada // primeiramente pela essa ltima converso feita at o final if (p_tem==12){ p_tem=0; // ndice do vetor de temperatura } } /*********************************************************************/ /* Programa: HTTP.c - Programa responsvel pelo servidor http */ /* Nome: Renato Silveira Zorzin */ /* Referencia: RFC 2616 */ /*********************************************************************/ #define __HTTP_C #include "TCPIP Stack/TCPIP.h" #include "ctype.h" #if defined(STACK_USE_HTTP_SERVER) // As variveis dinmicas que estaro dentro do CGI tem que ser precedidas pelo simbolo abaixo #define HTTP_VAR_ESC_CHAR '%' #define HTTP_DYNAMIC_FILE_TYPE (HTTP_CGI) // Tipos de arquivos HTTP possveis #define HTTP_TXT (0u) #define HTTP_HTML (1u) #define HTTP_CGI (2u) #define HTTP_XML (3u) #define HTTP_GIF (4u) #define HTTP_PNG (5u) #define HTTP_JPG (6u) #define HTTP_JAVA (7u) #define HTTP_WAV (8u) #define HTTP_UNKNOWN (9u) #define FILE_EXT_LEN (3u) typedef struct _FILE_TYPES 51 { BYTE fileExt[FILE_EXT_LEN+1]; } FILE_TYPES; // Cada entrada nesta estrutura deve ser em letra maiuscula // A ordem nessas entradas devem ser iguais as que foram definidas acima static ROM FILE_TYPES httpFiles[] = { { "TXT" }, // HTTP_TXT { "HTM" }, // HTTP_HTML { "CGI" }, // HTTP_CGI { "XML" }, // HTTP_XML { "GIF" }, // HTTP_GIF { "PNG" }, // HTTP_PNG { "JPG" }, // HTTP_JPG { "CLA" }, // HTTP_JAVA { "WAV" }, // HTTP_WAV { "" } // HTTP_UNKNOWN }; #define TOTAL_FILE_TYPES ( sizeof(httpFiles)/sizeof(httpFiles[0]) ) typedef struct _HTTP_CONTENT { ROM BYTE typeString[20]; } HTTP_CONTENT; // O Contedo dessas entradas devem estar aonde especificado abaixo static ROM HTTP_CONTENT httpContents[] = { { "text/plain" }, // HTTP_TXT { "text/html" }, // HTTP_HTML { "text/html" }, // HTTP_CGI { "text/xml" }, // HTTP_XML { "image/gif" }, // HTTP_GIF { "image/png" }, // HTTP_PNG { "image/jpeg" }, // HTTP_JPG { "application/java-vm" }, // HTTP_JAVA { "audio/x-wave" }, // HTTP_WAV { "" } // HTTP_UNKNOWN }; #define TOTAL_HTTP_CONTENTS ( sizeof(httpContents)/sizeof(httpConetents[0]) ) // Estado das conexes HTTP. typedef enum _SM_HTTP { SM_HTTP_IDLE = 0u, SM_HTTP_GET, SM_HTTP_NOT_FOUND, SM_HTTP_GET_READ, SM_HTTP_GET_PASS, SM_HTTP_GET_DLE, SM_HTTP_GET_HANDLE, SM_HTTP_GET_HANDLE_NEXT, SM_HTTP_GET_VAR, SM_HTTP_HEADER, SM_HTTP_DISCARD } SM_HTTP; // Comandos HTTP suportados typedef enum _HTTP_COMMAND { HTTP_GET = 0u, HTTP_POST, HTTP_NOT_SUPPORTED, HTTP_INVALID_COMMAND } HTTP_COMMAND; // Informao da conexo HTTP. Uma para cada conexo. typedef struct _HTTP_INFO { TCP_SOCKET socket; MPFS file; SM_HTTP smHTTP; BYTE smHTTPGet; WORD VarRef; BYTE bProcess; BYTE Variable; BYTE fileType; } HTTP_INFO; typedef BYTE HTTP_HANDLE; typedef enum { HTTP_NOT_FOUND = 0u, HTTP_NOT_AVAILABLE } HTTP_MESSAGES; // Aps a mensagem deve corresponder a fim de que HTTP_MESSAGE enum. static ROM BYTE *HTTPMessages[] = { (ROM BYTE*)"HTTP/1.1 404 Not found\r\n\r\nNot found.\r\n", (ROM BYTE*)"HTTP/1.1 503 \r\n\r\nService Unavailable\r\n" }; // Mensagens padres do HTTP. static ROM BYTE HTTP_OK_STRING[] = "HTTP/1.1 200 OK\r\nContent-type: "; static ROM BYTE HTTP_OK_NO_CACHE_STRING[] = "HTTP/1.1 200 OK\r\nDate: Wed, 05 Apr 2006 02:53:05 GMT\r\nExpires: Wed, 05 Apr 2006 02:52:05 GMT\r\nCache- control: private\r\nContent-type: "; #define HTTP_OK_STRING_LEN (sizeof(HTTP_OK_STRING)-1) #define HTTP_OK_NO_CACHE_STRING_LEN (sizeof(HTTP_OK_NO_CACHE_STRING)-1) static ROM BYTE HTTP_HEADER_END_STRING[] = "\r\n\r\n"; #define HTTP_HEADER_END_STRING_LEN (sizeof(HTTP_HEADER_END_STRING)-1) // Comandos String HTTP static ROM BYTE HTTP_GET_STRING[] = "GET"; #define HTTP_GET_STRING_LEN (sizeof(HTTP_GET_STRING)-1) // Definio da pgina padro HTML. static ROM BYTE HTTP_DEFAULT_FILE_STRING[] = "INDEX.HTM"; #define HTTP_DEFAULT_FILE_STRING_LEN (sizeof(HTTP_DEFAULT_FILE_STRING)-1) // Nmero maximo de argumentos suportado pelo servidor HTTP. #define MAX_HTTP_ARGS (11u) // Tamanho mximo de um comando HTML. #define MAX_HTML_CMD_LEN (100u) 52 static HTTP_INFO HCB[MAX_HTTP_CONNECTIONS]; static void HTTPProcess(HTTP_HANDLE h); static HTTP_COMMAND HTTPParse(BYTE *string, BYTE** arg, BYTE* argc, BYTE* type); static BOOL SendFile(HTTP_INFO* ph); /********************************************************************* Funo void HTTPInit(void) Esta funo chamada somente durante um perodo de vida do pedido. ********************************************************************/ void HTTPInit(void) { BYTE i; for ( i = 0; i < MAX_HTTP_CONNECTIONS; i++ ) { HCB[i].socket = TCPListen(HTTP_PORT); HCB[i].smHTTP = SM_HTTP_IDLE; } } /********************************************************************* Funo void HTTPServer(void) Esta funo atua como uma tarefa. Esta funo desempenha sua misso em forma de cooperao. Os pedidos devem executar est funo repetidamente para garantir que todas as novas conexo sejam atendidas. ********************************************************************/ void HTTPServer(void) { BYTE conn; for ( conn = 0; conn < MAX_HTTP_CONNECTIONS; conn++ ) HTTPProcess(conn); } /********************************************************************* funo HTTPProcess(HTTP_HANDLE h) ********************************************************************/ static void HTTPProcess(HTTP_HANDLE h) { BYTE httpData[MAX_HTML_CMD_LEN+1]; HTTP_COMMAND httpCommand; BOOL lbContinue; BYTE *arg[MAX_HTTP_ARGS]; BYTE argc; BYTE i; HTTP_INFO* ph; WORD w; ph = &HCB[h]; do { lbContinue = FALSE; // Se durante a tentativa de conexo do HTTP com o TCP ele no estiver conectado ele volta para o estado de repouso. if(!TCPIsConnected(ph->socket)) { ph->smHTTP = SM_HTTP_IDLE; break; } switch(ph->smHTTP) { case SM_HTTP_IDLE: // Procura o tipo de pedido que foi feito GET/HEAD/POST w = TCPFindROMArray(ph->socket, (ROM BYTE*)"\r\n", 2, 0, FALSE); if(w == 0xFFFFu) { if(TCPGetRxFIFOFree(ph->socket) == 0) { // Se a requisio for muito grande o TCP ir desconectar. TCPDisconnect(ph->socket); } break; } lbContinue = TRUE; if(w > sizeof(httpData)-1) w = sizeof(httpData)-1; TCPGetArray(ph->socket, httpData, w); httpData[w] = '\0'; TCPDiscard(ph->socket); ph->smHTTP = SM_HTTP_NOT_FOUND; argc = MAX_HTTP_ARGS; httpCommand = HTTPParse(httpData, arg, &argc, &ph->fileType); if ( httpCommand == HTTP_GET ) { // Se h qualquer argumento, este deve ser um comando remoto // Executa e envia o arquivo // O nome do arquivo pode ser modificado. if ( argc > 1u ) { // A aplicao principal responsavel por lidar com este comando remoto. HTTPExecCmd(&arg[0], argc); // As pginas web devero usar HMTL ou CGI ph->fileType = HTTP_CGI; } ph->file = MPFSOpen(arg[0]); if ( ph->file == MPFS_INVALID ) { ph->Variable = HTTP_NOT_FOUND; ph->smHTTP = SM_HTTP_NOT_FOUND; 53 } else if ( ph->file == MPFS_NOT_AVAILABLE ) { ph->Variable = HTTP_NOT_AVAILABLE; ph->smHTTP = SM_HTTP_NOT_FOUND; } else { ph->smHTTP = SM_HTTP_HEADER; } } break; case SM_HTTP_NOT_FOUND: if(TCPIsPutReady(ph->socket) >= strlenpgm((ROM char*)HTTPMessages[ph->Variable])) { TCPPutROMString(ph->socket, HTTPMessages[ph->Variable]); TCPFlush(ph->socket); TCPDisconnect(ph->socket); ph->smHTTP = SM_HTTP_IDLE; } break; case SM_HTTP_HEADER: if ( TCPIsPutReady(ph->socket) ) { lbContinue = TRUE; if ( ph->fileType == HTTP_DYNAMIC_FILE_TYPE ) { ph->bProcess = TRUE; TCPPutROMArray(ph->socket, (ROM BYTE*)HTTP_OK_NO_CACHE_STRING, HTTP_OK_NO_CACHE_STRING_LEN); } else { ph->bProcess = FALSE; TCPPutROMArray(ph->socket, (ROM BYTE*)HTTP_OK_STRING, HTTP_OK_STRING_LEN); } TCPPutROMString(ph->socket, httpContents[ph->fileType].typeString); TCPPutROMArray(ph->socket, (ROM BYTE*)HTTP_HEADER_END_STRING, HTTP_HEADER_END_STRING_LEN); ph->smHTTPGet = SM_HTTP_GET_READ; ph->smHTTP = SM_HTTP_GET; } break; case SM_HTTP_GET: // Dicarta os dados recebidos a mais TCPDiscard(ph->socket); if(SendFile(ph)) { // Encerra a conexo com a pgina da Internet e desconecta do TCP MPFSClose(); TCPDisconnect(ph->socket); ph->smHTTP = SM_HTTP_IDLE; } break; } } while( lbContinue ); } /********************************************************************* Funo SendFile(HTTP_INFO* ph) ********************************************************************/ static BOOL SendFile(HTTP_INFO* ph) { BOOL lbTransmit; BYTE c; BYTE buffer[8]; WORD w; WORD_VAL HexNumber; MPFSGetBegin(ph->file); // Verifica se o arquivo dinmico (.cgi) if(ph->bProcess) { w = TCPIsPutReady(ph->socket); while(w) { lbTransmit = FALSE; if(ph->smHTTPGet != SM_HTTP_GET_VAR) { c = MPFSGet(); if(MPFSIsEOF()) { MPFSGetEnd(); TCPFlush(ph->socket); return TRUE; } } switch(ph->smHTTPGet) { case SM_HTTP_GET_READ: if ( c == HTTP_VAR_ESC_CHAR ) ph->smHTTPGet = SM_HTTP_GET_DLE; else lbTransmit = TRUE; break; case SM_HTTP_GET_DLE: if ( c == HTTP_VAR_ESC_CHAR ) { lbTransmit = TRUE; ph->smHTTPGet = SM_HTTP_GET_READ; } else { HexNumber.v[1] = c; ph->smHTTPGet = SM_HTTP_GET_HANDLE; } break; case SM_HTTP_GET_HANDLE: HexNumber.v[0] = c; 54 ph->Variable = hexatob(HexNumber); ph->smHTTPGet = SM_HTTP_GET_VAR; ph->VarRef = HTTP_START_OF_VAR; break; case SM_HTTP_GET_VAR: ph->VarRef = HTTPGetVar(ph->Variable, ph->VarRef, &c); lbTransmit = TRUE; if ( ph->VarRef == HTTP_END_OF_VAR ) ph->smHTTPGet = SM_HTTP_GET_READ; break; } if(lbTransmit) { TCPPut(ph->socket, c); w--; } } } else // Pagina esttica { w = TCPIsPutReady(ph->socket); while(w >= sizeof(buffer)) { for(c = 0; c < sizeof(buffer); c++) { buffer[c] = MPFSGet(); if(MPFSIsEOF()) { MPFSGetEnd(); TCPPutArray(ph->socket, buffer, c); TCPFlush(ph->socket); return TRUE; } } TCPPutArray(ph->socket, buffer, sizeof(buffer)); w -= sizeof(buffer); lbTransmit = TRUE; } if(lbTransmit) TCPFlush(ph->socket); } ph->file = MPFSGetEnd(); // No estar enviando o arquivo ainda return FALSE; } /********************************************************************* * Funo HTTP_COMMAND HTTPParse Esta funo responsvel em fazer o tratamento do Parser da URL. ********************************************************************/ static HTTP_COMMAND HTTPParse(BYTE *string, BYTE** arg, BYTE* argc, BYTE* type) { BYTE i; BYTE smParse; HTTP_COMMAND cmd; BYTE *ext; BYTE c; ROM BYTE *fileType; enum { SM_PARSE_IDLE, SM_PARSE_ARG, SM_PARSE_ARG_FORMAT }; smParse = SM_PARSE_IDLE; ext = NULL; i = 0; // Apenas tipo "GET" est sendo verificada if ( !memcmppgm2ram(string, (ROM void*) HTTP_GET_STRING, HTTP_GET_STRING_LEN) ) { string += (HTTP_GET_STRING_LEN + 1); cmd = HTTP_GET; } else { return HTTP_NOT_SUPPORTED; } // Pula espaos em branco while( *string == ' ' ) string++; c = *string; while ( c != ' ' && c != '\0' && c != '\r' && c != '\n' ) { // No aceita mais argumentos do que recebido na passagem do parametro. if ( i >= *argc ) break; switch(smParse) { case SM_PARSE_IDLE: arg[i] = string; c = *string; if ( c == '/' || c == '\\' ) smParse = SM_PARSE_ARG; break; case SM_PARSE_ARG: arg[i++] = string; smParse = SM_PARSE_ARG_FORMAT; /* No para mesmo que os parmetros estejam vazios */ case SM_PARSE_ARG_FORMAT: c = *string; if ( c == '?' || c == '&' ) 55 { *string = '\0'; smParse = SM_PARSE_ARG; } else { // Modifica alguns caracteres if ( c == '+' ) *string = ' '; // Verifica quando uma extenso do arquivo. else if ( c == '.' && i == 1u ) { ext = ++string; } else if ( c == '=' ) { *string = '\0'; smParse = SM_PARSE_ARG; } // Somente interessa aqui o nome da pasta e no o nome do arquivo. else if ( c == '/' || c == '\\' ) arg[i-1] = string+1; } break; } string++; c = *string; } *string = '\0'; *type = HTTP_UNKNOWN; if ( ext != NULL ) { ext = (BYTE*)strupr((char*)ext); fileType = httpFiles[0].fileExt; for ( c = 0; c < TOTAL_FILE_TYPES; c++ ) { if ( !memcmppgm2ram((void*)ext, (ROM void*)fileType, FILE_EXT_LEN) ) { *type = c; break; } fileType += sizeof(FILE_TYPES); } } if ( i == 0u ) { memcpypgm2ram(arg[0], (ROM void*)HTTP_DEFAULT_FILE_STRING, HTTP_DEFAULT_FILE_STRING_LEN); arg[0][HTTP_DEFAULT_FILE_STRING_LEN] = '\0'; *type = HTTP_HTML; i++; } *argc = i; return cmd; } #endif #define __CUSTOMHTTPAPP_C #include "TCPIP Stack/TCPIP.h" #if defined(STACK_USE_HTTP2_SERVER) #if defined(HTTP_USE_POST) #if defined(USE_LCD) static HTTP_IO_RESULT HTTPPostLCD(void); #endif #if defined(STACK_USE_MD5) static HTTP_IO_RESULT HTTPPostMD5(void); #endif #if defined(STACK_USE_APP_RECONFIG) static HTTP_IO_RESULT HTTPPostConfig(void); #endif #endif extern unsigned char rec_temperatura_analogica[48][6]; // array do vetor de temperatura extern unsigned char rec_tem_ana_nav[48][6]; // array do vetor de temperatura que ser mostrado no navegador extern HTTP_CONN curHTTP; extern HTTP_STUB httpStubs[MAX_HTTP_CONNECTIONS]; extern BYTE curHTTPID; extern unsigned char V_EVENTO_SUBTENSAO_SAIDA; extern unsigned char V_EVENTO_SOBRETENSAO_SAIDA; extern unsigned char V_EVENTO_SOBRECORRENTE_SAIDA; // servidor de email extern unsigned char SMTP_Server[40]; // nome da conta do usuario extern unsigned char SMTP_Usuario[30]; // Senha da conta do usuario extern unsigned char SMTP_Senha[9]; // Identificao dos destinatrios extern unsigned char SMTP_Dst1[35]; extern unsigned char SMTP_Dst2[35]; // Habilitao ou no dos destinatrios extern unsigned char id_dst1_enable; extern unsigned char id_dst2_enable; /********************************************************************* * Funo que realiza a autenticao na pagina ********************************************************************/ #if defined(HTTP_USE_AUTHENTICATION) BYTE HTTPAuthenticate(BYTE *user, BYTE *pass, BYTE *filename) { 56 if(filename) { // A pagina informada abaixo requer autenticao if(memcmppgm2ram(filename, (ROM void*)"protect", 7) == 0) return 0x00; #if defined(HTTP_MPFS_UPLOAD_REQUIRES_AUTH) if(memcmppgm2ram(filename, (ROM void*)"mpfsupload", 10) == 0) return 0x00; #endif // Pgina de monitorao requer autenticao (index.htm) if(strcmppgm2ram(filename, (ROM void*)"index.htm") == 0) return 0x00; // Indica que a pagina necessita de autenticao return 0x80; // No necessrio autenticao } else {// This is a user/pass combination if(strcmppgm2ram((char *)user,(ROM char *)"admin") == 0 && strcmppgm2ram((char *)pass, (ROM char *)"microchip") == 0) return 0x80; // Se aceitou o usrio e senha return 0x00; // Se no aceitou usurio e senha } } #endif #if defined(HTTP_USE_POST) /********************************************************************* * Funo que chamada na hora que executado um post na tela ********************************************************************/ HTTP_IO_RESULT HTTPExecutePost(void) { // varivel que recebe o nome do arquivo que executou o post BYTE filename[20]; // Carrega na variavel o nome do arquivo que executou o post MPFSGetFilename(curHTTP.file, filename, 20); #if defined(STACK_USE_APP_RECONFIG) if(!memcmppgm2ram(filename, "protect/config.htm", 18)) // Salva nova configurao da placa return HTTPPostConfig(); #endif return HTTP_IO_DONE; } /********************************************************************* * Funo que chamada quando o post realizado na tela config.htm ********************************************************************/ #if defined(STACK_USE_APP_RECONFIG) extern APP_CONFIG AppConfig; #define HTTP_POST_CONFIG_MAX_LEN (HTTP_MAX_DATA_LEN - sizeof(AppConfig) - 3) static HTTP_IO_RESULT HTTPPostConfig(void) { APP_CONFIG *app; BYTE *ptr; WORD len; // Set app config pointer to use data array app = (APP_CONFIG*)&curHTTP.data[HTTP_POST_CONFIG_MAX_LEN]; // Use data[0] as a state machine. 0x01 is initialized, 0x02 is error, else uninit if(curHTTP.data[0] != 0x01 && curHTTP.data[0] != 0x02) { // First run, so use current config as defaults memcpy((void*)app, (void*)&AppConfig, sizeof(AppConfig)); app->Flags.bIsDHCPEnabled = 0; curHTTP.data[0] = 0x01; } // Loop over all parameters while(curHTTP.byteCount) { // Find end of next parameter string len = TCPFind(sktHTTP, '&', 0, FALSE); if(len == 0xffff && TCPIsGetReady(sktHTTP) == curHTTP.byteCount) len = TCPIsGetReady(sktHTTP); // If there's no end in sight, then ask for more data if(len == 0xffff) return HTTP_IO_NEED_DATA; // Read in as much data as we can if(len > HTTP_MAX_DATA_LEN-sizeof(AppConfig)) {// If there's too much, read as much as possible curHTTP.byteCount -= TCPGetArray(sktHTTP, curHTTP.data+1, HTTP_POST_CONFIG_MAX_LEN); curHTTP.byteCount -= TCPGetArray(sktHTTP, NULL, len - HTTP_POST_CONFIG_MAX_LEN); curHTTP.data[HTTP_POST_CONFIG_MAX_LEN-1] = '\0'; } else {// Otherwise, read as much as we wanted to curHTTP.byteCount -= TCPGetArray(sktHTTP, curHTTP.data+1, len); curHTTP.data[len+1] = '\0'; } // Decode the string HTTPURLDecode(curHTTP.data+1); // Compare the string to those we're looking for if(!memcmppgm2ram(curHTTP.data+1, "ip\0", 3)) { if(StringToIPAddress(&curHTTP.data[3+1], &(app->MyIPAddr))) memcpy((void*)&(app->DefaultIPAddr), (void*)&(app->MyIPAddr), sizeof(IP_ADDR)); else curHTTP.data[0] = 0x02; } else if(!memcmppgm2ram(curHTTP.data+1, "gw\0", 3)) { if(!StringToIPAddress(&curHTTP.data[3+1], &(app->MyGateway))) curHTTP.data[0] = 0x02; } else if(!memcmppgm2ram(curHTTP.data+1, "subnet\0", 7)) { if(StringToIPAddress(&curHTTP.data[7+1], &(app->MyMask))) memcpy((void*)&(app->DefaultMask), (void*)&(app->MyMask), sizeof(IP_ADDR)); else 57 curHTTP.data[0] = 0x02; } else if(!memcmppgm2ram(curHTTP.data+1, "dns1\0", 5)) { if(!StringToIPAddress(&curHTTP.data[5+1], &(app->PrimaryDNSServer))) curHTTP.data[0] = 0x02; } else if(!memcmppgm2ram(curHTTP.data+1, "dns2\0", 5)) { if(!StringToIPAddress(&curHTTP.data[5+1], &(app->SecondaryDNSServer))) curHTTP.data[0] = 0x02; } else if(!memcmppgm2ram(curHTTP.data+1, "mac\0", 4)) { WORD_VAL w; BYTE i, mac[12]; ptr = &curHTTP.data[4+1]; for(i = 0; i < 12; i++) {// Read the MAC address // Skip non-hex bytes while( *ptr != 0x00 && !(*ptr >= '0' && *ptr < '9') && !(*ptr >= 'A' && *ptr <= 'F') && !(*ptr >= 'a' && *ptr <= 'f') ) ptr++; // MAC string is over, so zeroize the rest if(*ptr == 0x00) { for(; i < 12; i++) mac[i] = '0'; break; } // Save the MAC byte mac[i] = *ptr++; } // Read MAC Address, one byte at a time for(i = 0; i < 6; i++) { w.v[1] = mac[i*2]; w.v[0] = mac[i*2+1]; app->MyMACAddr.v[i] = hexatob(w); } } else if(!memcmppgm2ram(curHTTP.data+1, "host\0", 5)) { memset(app->NetBIOSName, ' ', 15); app->NetBIOSName[15] = 0x00; memcpy((void*)app->NetBIOSName, (void*)&curHTTP.data[5+1], strlen((char*)&curHTTP.data[5+1])); strupr((char*)app->NetBIOSName); } // Configurao do correio eletronico // Servidor de email else if(!memcmppgm2ram(curHTTP.data+1, "serv\0", 5)) { memset(SMTP_Server, ' ', 39); SMTP_Server[strlen((char*)&curHTTP.data[5+1])] = 0x00; memcpy((void*)SMTP_Server, (void*)&curHTTP.data[5+1], strlen((char*)&curHTTP.data[5+1])); } // Conta do Usurio else if(!memcmppgm2ram(curHTTP.data+1, "user\0", 5)) { memset(SMTP_Usuario, ' ', 29); SMTP_Usuario[strlen((char*)&curHTTP.data[5+1])] = 0x00; memcpy((void*)SMTP_Usuario, (void*)&curHTTP.data[5+1], strlen((char*)&curHTTP.data[5+1])); } // Senha do Usurio else if(!memcmppgm2ram(curHTTP.data+1, "senh\0", 5)) { memset(SMTP_Senha, ' ', 8); SMTP_Senha[strlen((char*)&curHTTP.data[5+1])] = 0x00; memcpy((void*)SMTP_Senha, (void*)&curHTTP.data[5+1], strlen((char*)&curHTTP.data[5+1])); } // Destinatrio 1 else if(!memcmppgm2ram(curHTTP.data+1, "dst1\0", 5)) { memset(SMTP_Dst1, ' ', 34); SMTP_Dst1[strlen((char*)&curHTTP.data[5+1])] = 0x00; memcpy((void*)SMTP_Dst1, (void*)&curHTTP.data[5+1], strlen((char*)&curHTTP.data[5+1])); } // Destinatrio 2 else if(!memcmppgm2ram(curHTTP.data+1, "dst2\0", 5)) { memset(SMTP_Dst2, ' ', 34); SMTP_Dst2[strlen((char*)&curHTTP.data[5+1])] = 0x00; memcpy((void*)SMTP_Dst2, (void*)&curHTTP.data[5+1], strlen((char*)&curHTTP.data[5+1])); } else if(!memcmppgm2ram(curHTTP.data+1, "dst1enabled\0", 12)) { if(curHTTP.data[12+1] == '1') id_dst1_enable = 1; else id_dst1_enable = 0; } else if(!memcmppgm2ram(curHTTP.data+1, "dst2enabled\0", 12)) { if(curHTTP.data[12+1] == '1') id_dst2_enable = 1; else id_dst2_enable = 0; } // Trash the separator character while( TCPFind(sktHTTP, '&', 0, FALSE) == 0 || TCPFind(sktHTTP, '\r', 0, FALSE) == 0 || TCPFind(sktHTTP, '\n', 0, FALSE) == 0 ) { curHTTP.byteCount -= TCPGet(sktHTTP, NULL); } } 58 // Check if all settings were successful if(curHTTP.data[0] == 0x01) {// Salva as novas configuraes // Grava a configurao de rede ptr = (BYTE*)app; XEEBeginWrite(0x0000); XEEWrite(0x60); for (len = 0; len < (sizeof(AppConfig)-6); len++ ) XEEWrite(*ptr++); XEEEndWrite(); while(XEEIsBusy()); // Grava a configurao de correio eletronico SMTP_Write_Configuracao(); // Reinicia para mostrar os novos valores Reset(); strcpypgm2ram((char*)curHTTP.data, (ROM void*)"/protect/reboot.htm?"); memcpy((void*)(curHTTP.data+20), (void*)app->NetBIOSName, 16); ptr = curHTTP.data; while(*ptr != ' ' && *ptr != '\0') ptr++; *ptr = '\0'; } else {// Error parsing IP, so don't save to avoid errors strcpypgm2ram((char*)curHTTP.data, (ROM void*)"/protect/config_error.htm"); } curHTTP.httpStatus = HTTP_REDIRECT; return HTTP_IO_DONE; } #endif // ENVIAM AS VARIVEIS PARA O CLIENTE HTTP void HTTPPrint_builddate(void) { TCPPutROMArray(sktHTTP,(ROM void*)__DATE__" "__TIME__, strlenpgm((ROM char*)__DATE__" "__TIME__)); } void HTTPPrint_cookiename(void) { BYTE *ptr; ptr = HTTPGetROMArg(curHTTP.data, (ROM BYTE*)"name"); if(ptr) TCPPutArray(sktHTTP, ptr, strlen((char*)ptr)); else TCPPutROMArray(sktHTTP, (ROM BYTE*)"not set", 7); return; } void HTTPPrint_uploadedmd5(void) { BYTE i; // Seta a flag indicando que no finalizou curHTTP.callbackPos = 1; // Certifica que no h espao suficiente if(TCPIsPutReady(sktHTTP) < 32 + 37 + 5) return; // Verifica a flag do md5 if(curHTTP.data[0] != 0x05) { TCPPutROMArray(sktHTTP, (ROM BYTE*)"<b>Upload a File</b>", 20); curHTTP.callbackPos = 0; return; } TCPPutROMArray(sktHTTP, (ROM BYTE*)"<b>Uploaded File's MD5 was:</b><br />", 37); // Escreve um byte da soma md5 de uma s vez for(i = 1; i <= 16; i++) { TCPPut(sktHTTP, btohexa_high(curHTTP.data[i])); TCPPut(sktHTTP, btohexa_low(curHTTP.data[i])); if((i & 0x03) == 0) TCPPut(sktHTTP, ' '); } curHTTP.callbackPos = 0x00; return; } extern APP_CONFIG AppConfig; void HTTPPrintIP(IP_ADDR ip) { BYTE digits[4]; BYTE i; for(i = 0; i < 4; i++) { if(i != 0) TCPPut(sktHTTP, '.'); uitoa(ip.v[i], digits); TCPPutArray(sktHTTP, digits, strlen((char*)digits)); } } void HTTPPrint_config_hostname(void) { TCPPutArray(sktHTTP, AppConfig.NetBIOSName, strlen((char*)AppConfig.NetBIOSName)); return; } void HTTPPrint_config_ip(void) { HTTPPrintIP(AppConfig.MyIPAddr); return; } void HTTPPrint_config_gw(void) 59 { HTTPPrintIP(AppConfig.MyGateway); return; } void HTTPPrint_config_subnet(void) { HTTPPrintIP(AppConfig.MyMask); return; } void HTTPPrint_config_dns1(void) { HTTPPrintIP(AppConfig.PrimaryDNSServer); return; } void HTTPPrint_config_dns2(void) { HTTPPrintIP(AppConfig.SecondaryDNSServer); return; } void HTTPPrint_config_mac(void) { BYTE i; if(TCPIsPutReady(sktHTTP) < 18) { curHTTP.callbackPos = 0x01; return; } for(i = 0; i < 6; i++) { if(i != 0) TCPPut(sktHTTP, ':'); TCPPut(sktHTTP, btohexa_high(AppConfig.MyMACAddr.v[i])); TCPPut(sktHTTP, btohexa_low(AppConfig.MyMACAddr.v[i])); } curHTTP.callbackPos = 0x00; return; } void HTTPPrint_reboot(void) { // This is not so much a print function, but causes the board to reboot // when the configuration is changed. If called via an AJAX call, this // will gracefully reset the board and bring it back online immediately Reset(); } void HTTPPrint_rebootaddr(void) { TCPPutArray(sktHTTP, curHTTP.data, strlen((char*)curHTTP.data)); } // configurao do correio eletronico void HTTPPrint_config_user(void) { TCPPutArray(sktHTTP, SMTP_Usuario, strlen((char*)SMTP_Usuario)); return; } void HTTPPrint_config_serv(void) { TCPPutArray(sktHTTP, SMTP_Server, strlen((char*)SMTP_Server)); return; } void HTTPPrint_config_senh(void) { TCPPutArray(sktHTTP, SMTP_Senha, strlen((char*)SMTP_Senha)); return; } void HTTPPrint_config_dst1(void) { TCPPutArray(sktHTTP, SMTP_Dst1, strlen((char*)SMTP_Dst1)); return; } void HTTPPrint_config_dst2(void) { TCPPutArray(sktHTTP, SMTP_Dst2, strlen((char*)SMTP_Dst2)); return; } void HTTPPrint_config_dst1checked(void) { if(id_dst1_enable) TCPPutROMArray(sktHTTP, (ROM BYTE*)"checked", 7); return; } void HTTPPrint_config_dst2checked(void) { if(id_dst2_enable) TCPPutROMArray(sktHTTP, (ROM BYTE*)"checked", 7); return; } // ------------------------- TEMPERATURAS---------------------------- void HTTPPrint_stftem1(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[0], strlen((char*)rec_tem_ana_nav[0])); return; } void HTTPPrint_stftem2(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[1], strlen((char*)rec_tem_ana_nav[1])); return; } void HTTPPrint_stftem3(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[2], strlen((char*)rec_tem_ana_nav[2])); return; } 60 void HTTPPrint_stftem4(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[3], strlen((char*)rec_tem_ana_nav[3])); return; } void HTTPPrint_stftem5(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[4], strlen((char*)rec_tem_ana_nav[4])); return; } void HTTPPrint_stftem6(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[5], strlen((char*)rec_tem_ana_nav[5])); return; } void HTTPPrint_stftem7(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[6], strlen((char*)rec_tem_ana_nav[6])); return; } void HTTPPrint_stftem8(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[7], strlen((char*)rec_tem_ana_nav[7])); return; } void HTTPPrint_stftem9(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[8], strlen((char*)rec_tem_ana_nav[8])); return; } void HTTPPrint_stftem10(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[9], strlen((char*)rec_tem_ana_nav[9])); return; } void HTTPPrint_stftem11(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[10], strlen((char*)rec_tem_ana_nav[10])); return; } void HTTPPrint_stftem12(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[11], strlen((char*)rec_tem_ana_nav[11])); return; } void HTTPPrint_stftem13(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[12], strlen((char*)rec_tem_ana_nav[12])); return; } void HTTPPrint_stftem14(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[13], strlen((char*)rec_tem_ana_nav[13])); return; } void HTTPPrint_stftem15(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[14], strlen((char*)rec_tem_ana_nav[14])); return; } void HTTPPrint_stftem16(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[15], strlen((char*)rec_tem_ana_nav[15])); return; } void HTTPPrint_stftem17(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[16], strlen((char*)rec_tem_ana_nav[16])); return; } void HTTPPrint_stftem18(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[17], strlen((char*)rec_tem_ana_nav[17])); return; } void HTTPPrint_stftem19(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[18], strlen((char*)rec_tem_ana_nav[18])); return; } void HTTPPrint_stftem20(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[19], strlen((char*)rec_tem_ana_nav[19])); return; } void HTTPPrint_stftem21(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[20], strlen((char*)rec_tem_ana_nav[20])); return; } void HTTPPrint_stftem22(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[21], strlen((char*)rec_tem_ana_nav[21])); return; } void HTTPPrint_stftem23(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[22], strlen((char*)rec_tem_ana_nav[22])); return; } void HTTPPrint_stftem24(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[23], strlen((char*)rec_tem_ana_nav[23])); return; } void HTTPPrint_stftem25(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[24], strlen((char*)rec_tem_ana_nav[24])); return; } void HTTPPrint_stftem26(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[25], strlen((char*)rec_tem_ana_nav[25])); return; } void HTTPPrint_stftem27(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[26], strlen((char*)rec_tem_ana_nav[26])); return; } 61 void HTTPPrint_stftem28(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[27], strlen((char*)rec_tem_ana_nav[27])); return; } void HTTPPrint_stftem29(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[28], strlen((char*)rec_tem_ana_nav[28])); return; } void HTTPPrint_stftem30(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[29], strlen((char*)rec_tem_ana_nav[29])); return; } void HTTPPrint_stftem31(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[30], strlen((char*)rec_tem_ana_nav[30])); return; } void HTTPPrint_stftem32(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[31], strlen((char*)rec_tem_ana_nav[31])); return; } void HTTPPrint_stftem33(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[32], strlen((char*)rec_tem_ana_nav[32])); return; } void HTTPPrint_stftem34(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[33], strlen((char*)rec_tem_ana_nav[33])); return; } void HTTPPrint_stftem35(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[34], strlen((char*)rec_tem_ana_nav[34])); return; } void HTTPPrint_stftem36(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[35], strlen((char*)rec_tem_ana_nav[35])); return; } void HTTPPrint_stftem37(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[36], strlen((char*)rec_tem_ana_nav[36])); return; } void HTTPPrint_stftem38(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[37], strlen((char*)rec_tem_ana_nav[37])); return; } void HTTPPrint_stftem39(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[38], strlen((char*)rec_tem_ana_nav[38])); return; } void HTTPPrint_stftem40(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[39], strlen((char*)rec_tem_ana_nav[39])); return; } void HTTPPrint_stftem41(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[40], strlen((char*)rec_tem_ana_nav[40])); return; } void HTTPPrint_stftem42(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[41], strlen((char*)rec_tem_ana_nav[41])); return; } void HTTPPrint_stftem43(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[42], strlen((char*)rec_tem_ana_nav[42])); return; } void HTTPPrint_stftem44(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[43], strlen((char*)rec_tem_ana_nav[43])); return; } void HTTPPrint_stftem45(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[44], strlen((char*)rec_tem_ana_nav[44])); return; } void HTTPPrint_stftem46(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[45], strlen((char*)rec_tem_ana_nav[45])); return; } void HTTPPrint_stftem47(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[46], strlen((char*)rec_tem_ana_nav[46])); return; } void HTTPPrint_stftem48(void) { TCPPutArray(sktHTTP, rec_tem_ana_nav[47], strlen((char*)rec_tem_ana_nav[47])); return; } #endif /*********************************************************************/ /* Programa: SMTP.c - Programa responsvel pelo servidor http */ /* Nome: Renato Silveira Zorzin */ /* Referencia: RFC 2821 */ /*********************************************************************/ #define __SMTP_C #include "TCPIP Stack/TCPIP.h" #if defined(STACK_USE_SMTP_CLIENT) #define SMTP_PORT 25 62 #define SMTP_SERVER_REPLY_TIMEOUT (TICK_SECOND*8) // Variveis Publicas SMTP_POINTERS SMTPClient; // Variaveis Internas static IP_ADDR SMTPServer; static TCP_SOCKET MySocket = INVALID_SOCKET; static union { BYTE *Pos; enum { CR_PERIOD_SEEK_CR = 0, CR_PERIOD_SEEK_LF, CR_PERIOD_SEEK_PERIOD, CR_PERIOD_NEED_INSERTION } State; } CRPeriod; static enum _TransportState { TRANSPORT_HOME = 0, TRANSPORT_BEGIN, TRANSPORT_NAME_RESOLVE, TRANSPORT_OBTAIN_SOCKET, TRANSPORT_SOCKET_OBTAINED, TRANSPORT_CLOSE } TransportState = TRANSPORT_HOME; static enum _SMTPState { SMTP_HOME = 0, SMTP_HELO, SMTP_HELO_ACK, SMTP_AUTH_LOGIN, SMTP_AUTH_LOGIN_ACK, SMTP_AUTH_USERNAME, SMTP_AUTH_USERNAME_ACK, SMTP_AUTH_PASSWORD, SMTP_AUTH_PASSWORD_ACK, SMTP_MAILFROM, SMTP_MAILFROM_ACK, SMTP_RCPTTO_INIT, SMTP_RCPTTO, SMTP_RCPTTO_ACK, SMTP_RCPTTO_ISDONE, SMTP_RCPTTOCC_INIT, SMTP_RCPTTOCC, SMTP_RCPTTOCC_ACK, SMTP_RCPTTOCC_ISDONE, SMTP_RCPTTOBCC_INIT, SMTP_RCPTTOBCC, SMTP_RCPTTOBCC_ACK, SMTP_RCPTTOBCC_ISDONE, SMTP_DATA, SMTP_DATA_ACK, SMTP_DATA_HEADER, SMTP_DATA_BODY_INIT, SMTP_DATA_BODY, SMTP_DATA_BODY_ACK, SMTP_QUIT_INIT, SMTP_QUIT } SMTPState; static enum _PutHeadersState { PUTHEADERS_FROM_INIT = 0, PUTHEADERS_FROM, PUTHEADERS_TO_INIT, PUTHEADERS_TO, PUTHEADERS_CC_INIT, PUTHEADERS_CC, PUTHEADERS_SUBJECT_INIT, PUTHEADERS_SUBJECT, PUTHEADERS_OTHER_INIT, PUTHEADERS_OTHER, PUTHEADERS_DONE } PutHeadersState; static enum _RXParserState { RX_BYTE_0 = 0, RX_BYTE_1, RX_BYTE_2, RX_BYTE_3, RX_SEEK_CR, RX_SEEK_LF } RXParserState; static union _SMTPFlags { BYTE Val; struct { unsigned char RXSkipResponse:1; unsigned char SMTPInUse:1; unsigned char SentSuccessfully:1; unsigned char ReadyToStart:1; unsigned char ReadyToFinish:1; unsigned char ConnectedOnce:1; unsigned char filler:2; } bits; } SMTPFlags = {0x00}; static WORD ResponseCode; // Funes Internas static BYTE *FindEmailAddress(BYTE *str, WORD *wLen); static ROM BYTE *FindROMEmailAddress(ROM BYTE *str, WORD *wLen); /********************************************************************* * Funo responsvel pelo inicio do uso do protocolo ********************************************************************/ BOOL SMTPBeginUsage(void) { if(SMTPFlags.bits.SMTPInUse) return FALSE; SMTPFlags.Val = 0x00; SMTPFlags.bits.SMTPInUse = TRUE; TransportState = TRANSPORT_BEGIN; RXParserState = RX_BYTE_0; SMTPState = SMTP_HOME; memset((void*)&SMTPClient, 0x00, sizeof(SMTPClient)); 63 SMTPClient.ServerPort = SMTP_PORT; return TRUE; } /********************************************************************* * Funo que finaliza o uso do protocolo ********************************************************************/ WORD SMTPEndUsage(void) { if(!SMTPFlags.bits.SMTPInUse) return 0xFFFF; // Se estiver em uso o DNS finaliza tambm if(TransportState == TRANSPORT_NAME_RESOLVE) DNSEndUsage(); // Disconecta do TCP if(MySocket != INVALID_SOCKET) { TCPDisconnect(MySocket); MySocket = INVALID_SOCKET; } // Finaliza envio de mensagem e coloca para estado inicial SMTPFlags.bits.SMTPInUse = FALSE; TransportState = TRANSPORT_HOME; if(SMTPFlags.bits.SentSuccessfully) { return 0; } else { return ResponseCode; } } /********************************************************************* * Funo responsvel pela tarefas para envio da mensagem ********************************************************************/ void SMTPTask(void) { BYTE i; WORD w; BYTE vBase64Buffer[4]; static TICK Timer; static BYTE RXBuffer[4]; static ROM BYTE *ROMStrPtr, *ROMStrPtr2; static BYTE *RAMStrPtr; static WORD wAddressLength; switch(TransportState) { case TRANSPORT_HOME: // Essa tipo de estado colocado somente na funo SMTPBeginUsage break; case TRANSPORT_BEGIN: // Espera que todos os ponteiros estejam prontos e chama a funo SMTPSendMail if(!SMTPFlags.bits.ReadyToStart) break; // Obtm o DNS if(!DNSBeginUsage()) break; // Obtem o endereo ip do servidor de e-mail if(SMTPClient.Server.szRAM || SMTPClient.Server.szROM) { if(SMTPClient.ROMPointers.Server) DNSResolveROM(SMTPClient.Server.szROM, DNS_TYPE_A); else DNSResolve(SMTPClient.Server.szRAM, DNS_TYPE_A); } else { // Se no tiver um servidor de e-mail tenta enviar com o do destino if(SMTPClient.To.szRAM && !SMTPClient.ROMPointers.To) { SMTPClient.Server.szRAM = (BYTE*)strchr((char*)SMTPClient.To.szRAM, '@'); SMTPClient.ROMPointers.Server = 0; } else if(SMTPClient.To.szROM && SMTPClient.ROMPointers.To) { SMTPClient.Server.szROM = (ROM BYTE*)strchrpgm((ROM char*)SMTPClient.To.szROM, '@'); SMTPClient.ROMPointers.Server = 1; } if(!(SMTPClient.Server.szRAM || SMTPClient.Server.szROM)) { if(SMTPClient.CC.szRAM && !SMTPClient.ROMPointers.CC) { SMTPClient.Server.szRAM = (BYTE*)strchr((char*)SMTPClient.CC.szRAM, '@'); SMTPClient.ROMPointers.Server = 0; } else if(SMTPClient.CC.szROM && SMTPClient.ROMPointers.CC) { SMTPClient.Server.szROM = (ROM BYTE*)strchrpgm((ROM char*)SMTPClient.CC.szROM, '@'); SMTPClient.ROMPointers.Server = 1; } } if(!(SMTPClient.Server.szRAM || SMTPClient.Server.szROM)) { if(SMTPClient.BCC.szRAM && !SMTPClient.ROMPointers.BCC) { SMTPClient.Server.szRAM = (BYTE*)strchr((char*)SMTPClient.BCC.szRAM, '@'); SMTPClient.ROMPointers.Server = 0; } else if(SMTPClient.BCC.szROM && SMTPClient.ROMPointers.BCC) { SMTPClient.Server.szROM = (ROM BYTE*)strchrpgm((ROM char*)SMTPClient.BCC.szROM, '@'); SMTPClient.ROMPointers.Server = 1; } } // Se no achou o nome do servidor finaliza envio 64 if(!(SMTPClient.Server.szRAM || SMTPClient.Server.szROM)) { DNSEndUsage(); TransportState = TRANSPORT_HOME; break; } // Retira o que tem antes do @ e resolve o resto do e-mail destinatario if(SMTPClient.ROMPointers.Server) { SMTPClient.Server.szROM++; DNSResolveROM(SMTPClient.Server.szROM, DNS_TYPE_MX); } else { SMTPClient.Server.szRAM++; DNSResolve(SMTPClient.Server.szRAM, DNS_TYPE_MX); } } Timer = TickGet(); TransportState++; break; case TRANSPORT_NAME_RESOLVE: // Verifica se o DNS resolveu o endereo IP do Servidor if(!DNSIsResolved(&SMTPServer)) { // Time out do DNS if(TickGet() - Timer > 6*TICK_SECOND) { ResponseCode = SMTP_RESOLVE_ERROR; TransportState = TRANSPORT_HOME; DNSEndUsage(); } break; } // Se finalizou o uso do DNS nesta etapa porque deu erro no envio da mensagem if(!DNSEndUsage()) { ResponseCode = SMTP_RESOLVE_ERROR; TransportState = TRANSPORT_HOME; break; } TransportState++; case TRANSPORT_OBTAIN_SOCKET: // Conecta ao socket TCP MySocket = TCPOpen(SMTPServer.Val, TCP_OPEN_IP_ADDRESS, SMTPClient.ServerPort, TCP_PURPOSE_DEFAULT); // Aborta execuo se no tiver mais conexes disponiveis aos sockets TCP if(MySocket == INVALID_SOCKET) break; TransportState++; Timer = TickGet(); case TRANSPORT_SOCKET_OBTAINED: if(!TCPIsConnected(MySocket)) { // Se demorou demais para responder na conexo da erro if(SMTPFlags.bits.ConnectedOnce || ((LONG)(TickGet()-Timer) > (LONG)(SMTP_SERVER_REPLY_TIMEOUT))) { ResponseCode = SMTP_CONNECT_ERROR; TransportState = TRANSPORT_CLOSE; } break; } SMTPFlags.bits.ConnectedOnce = TRUE; // Se est pronto para iniciar a execuo do envio da mensagem while(TCPIsGetReady(MySocket)) { TCPGet(MySocket, &i); switch(RXParserState) { case RX_BYTE_0: case RX_BYTE_1: case RX_BYTE_2: RXBuffer[RXParserState] = i; RXParserState++; break; case RX_BYTE_3: switch(i) { case ' ': SMTPFlags.bits.RXSkipResponse = FALSE; RXParserState++; break; case '-': SMTPFlags.bits.RXSkipResponse = TRUE; RXParserState++; break; case '\r': RXParserState = RX_SEEK_LF; break; } break; case RX_SEEK_CR: if(i == '\r') RXParserState++; break; case RX_SEEK_LF: // Se recebeu comando final if(i == '\n') { RXParserState = RX_BYTE_0; if(!SMTPFlags.bits.RXSkipResponse) { RXBuffer[3] = 0; ResponseCode = atoi((char*)RXBuffer); // Respostas conforme estado do envio da mensagem switch(SMTPState) 65 { case SMTP_HELO_ACK: if(ResponseCode >= 200u && ResponseCode <= 299u) { if(SMTPClient.Username.szRAM || SMTPClient.Username.szROM) SMTPState = SMTP_AUTH_LOGIN; else SMTPState = SMTP_MAILFROM; } else SMTPState = SMTP_QUIT_INIT; break; case SMTP_AUTH_LOGIN_ACK: case SMTP_AUTH_USERNAME_ACK: if(ResponseCode == 334u) SMTPState++; else SMTPState = SMTP_QUIT_INIT; break; case SMTP_AUTH_PASSWORD_ACK: if(ResponseCode == 235u) SMTPState++; else SMTPState = SMTP_QUIT_INIT; break; case SMTP_HOME: case SMTP_MAILFROM_ACK: case SMTP_RCPTTO_ACK: case SMTP_RCPTTOCC_ACK: case SMTP_RCPTTOBCC_ACK: if(ResponseCode >= 200u && ResponseCode <= 299u) SMTPState++; else SMTPState = SMTP_QUIT_INIT; break; case SMTP_DATA_ACK: if(ResponseCode == 354u) SMTPState++; else SMTPState = SMTP_QUIT_INIT; break; case SMTP_DATA_BODY_ACK: if(ResponseCode >= 200u && ResponseCode <= 299u) SMTPFlags.bits.SentSuccessfully = TRUE; SMTPState = SMTP_QUIT_INIT; break; } } } else if(i != '\r') RXParserState--; break; } } // Gera novo dado no buffer if(TCPIsPutReady(MySocket) < 64u) break; // Comea a enviar os comandos para envio da mensagem switch(SMTPState) { case SMTP_HELO: TCPPutROMString(MySocket, (ROM BYTE*)"HELO MCHPBOARD\r\n"); TCPFlush(MySocket); SMTPState++; break; case SMTP_AUTH_LOGIN: // Envia comando de login TCPPutROMString(MySocket, (ROM BYTE*)"AUTH LOGIN\r\n"); TCPFlush(MySocket); SMTPState++; break; case SMTP_AUTH_USERNAME: // Envia o usurio if(SMTPClient.ROMPointers.Username) { ROMStrPtr = SMTPClient.Username.szROM; w = strlenpgm((ROM char*)ROMStrPtr); } else { RAMStrPtr = SMTPClient.Username.szRAM; w = strlen((char*)RAMStrPtr); } while(w) { i = 0; while((i < w) && (i < sizeof(vBase64Buffer)*3/4)) { if(SMTPClient.ROMPointers.Username) vBase64Buffer[i] = *ROMStrPtr++; else vBase64Buffer[i] = *RAMStrPtr++; i++; } w -= i; Base64Encode(vBase64Buffer, i, vBase64Buffer, sizeof(vBase64Buffer)); TCPPutArray(MySocket, vBase64Buffer, sizeof(vBase64Buffer)); 66 } TCPPutROMString(MySocket, (ROM BYTE*)"\r\n"); TCPFlush(MySocket); SMTPState++; break; case SMTP_AUTH_PASSWORD: // envia senha if(SMTPClient.ROMPointers.Password) { ROMStrPtr = SMTPClient.Password.szROM; w = strlenpgm((ROM char*)ROMStrPtr); } else { RAMStrPtr = SMTPClient.Password.szRAM; w = strlen((char*)RAMStrPtr); } while(w) { i = 0; while((i < w) && (i < sizeof(vBase64Buffer)*3/4)) { if(SMTPClient.ROMPointers.Password) vBase64Buffer[i] = *ROMStrPtr++; else vBase64Buffer[i] = *RAMStrPtr++; i++; } w -= i; Base64Encode(vBase64Buffer, i, vBase64Buffer, sizeof(vBase64Buffer)); TCPPutArray(MySocket, vBase64Buffer, sizeof(vBase64Buffer)); } TCPPutROMString(MySocket, (ROM BYTE*)"\r\n"); TCPFlush(MySocket); SMTPState++; break; case SMTP_MAILFROM: // Send MAIL FROM header. Note that this is for the SMTP server validation, // not what actually will be displayed in the recipients mail client as a // return address. TCPPutROMString(MySocket, (ROM BYTE*)"MAIL FROM:<"); if(SMTPClient.ROMPointers.From) { ROMStrPtr = FindROMEmailAddress(SMTPClient.From.szROM, &wAddressLength); TCPPutROMArray(MySocket, ROMStrPtr, wAddressLength); } else { RAMStrPtr = FindEmailAddress(SMTPClient.From.szRAM, &wAddressLength); TCPPutArray(MySocket, RAMStrPtr, wAddressLength); } TCPPutROMString(MySocket, (ROM BYTE*)">\r\n"); TCPFlush(MySocket); SMTPState++; break; case SMTP_RCPTTO_INIT: if(SMTPClient.To.szRAM && !SMTPClient.ROMPointers.To) { RAMStrPtr = FindEmailAddress(SMTPClient.To.szRAM, &wAddressLength); if(wAddressLength) { SMTPState = SMTP_RCPTTO; break; } } if(SMTPClient.To.szROM && SMTPClient.ROMPointers.To) { ROMStrPtr = FindROMEmailAddress(SMTPClient.To.szROM, &wAddressLength); if(wAddressLength) { SMTPState = SMTP_RCPTTO; break; } } SMTPState = SMTP_RCPTTOCC_INIT; break; case SMTP_RCPTTO: case SMTP_RCPTTOCC: case SMTP_RCPTTOBCC: TCPPutROMString(MySocket, (ROM BYTE*)"RCPT TO:<"); if( (SMTPClient.ROMPointers.To && (SMTPState == SMTP_RCPTTO)) || (SMTPClient.ROMPointers.CC && (SMTPState == SMTP_RCPTTOCC)) || (SMTPClient.ROMPointers.BCC && (SMTPState == SMTP_RCPTTOBCC)) ) TCPPutROMArray(MySocket, ROMStrPtr, wAddressLength); else TCPPutArray(MySocket, RAMStrPtr, wAddressLength); TCPPutROMString(MySocket, (ROM BYTE*)">\r\n"); TCPFlush(MySocket); SMTPState++; break; case SMTP_RCPTTO_ISDONE: if(SMTPClient.ROMPointers.To) ROMStrPtr = FindROMEmailAddress(ROMStrPtr+wAddressLength, &wAddressLength); else RAMStrPtr = FindEmailAddress(RAMStrPtr+wAddressLength, &wAddressLength); if(wAddressLength) { SMTPState = SMTP_RCPTTO; break; } SMTPState++; case SMTP_RCPTTOCC_INIT: if(SMTPClient.CC.szRAM && !SMTPClient.ROMPointers.CC) { RAMStrPtr = FindEmailAddress(SMTPClient.CC.szRAM, &wAddressLength); if(wAddressLength) { SMTPState = SMTP_RCPTTOCC; 67 break; } } if(SMTPClient.CC.szROM && SMTPClient.ROMPointers.CC) { ROMStrPtr = FindROMEmailAddress(SMTPClient.CC.szROM, &wAddressLength); if(wAddressLength) { SMTPState = SMTP_RCPTTOCC; break; } } SMTPState = SMTP_RCPTTOBCC_INIT; break; case SMTP_RCPTTOCC_ISDONE: if(SMTPClient.ROMPointers.CC) ROMStrPtr = FindROMEmailAddress(ROMStrPtr+wAddressLength, &wAddressLength); else RAMStrPtr = FindEmailAddress(RAMStrPtr+wAddressLength, &wAddressLength); if(wAddressLength) { SMTPState = SMTP_RCPTTOCC; break; } SMTPState++; case SMTP_RCPTTOBCC_INIT: if(SMTPClient.BCC.szRAM && !SMTPClient.ROMPointers.BCC) { RAMStrPtr = FindEmailAddress(SMTPClient.BCC.szRAM, &wAddressLength); if(wAddressLength) { SMTPState = SMTP_RCPTTOBCC; break; } } if(SMTPClient.BCC.szROM && SMTPClient.ROMPointers.BCC) { ROMStrPtr = FindROMEmailAddress(SMTPClient.BCC.szROM, &wAddressLength); if(wAddressLength) { SMTPState = SMTP_RCPTTOBCC; break; } } SMTPState = SMTP_DATA; break; case SMTP_RCPTTOBCC_ISDONE: if(SMTPClient.ROMPointers.BCC) ROMStrPtr = FindROMEmailAddress(ROMStrPtr+wAddressLength, &wAddressLength); else RAMStrPtr = FindEmailAddress(RAMStrPtr+wAddressLength, &wAddressLength); if(wAddressLength) { SMTPState = SMTP_RCPTTOBCC; break; } SMTPState++; case SMTP_DATA: TCPPutROMString(MySocket, (ROM BYTE*)"DATA\r\n"); SMTPState++; PutHeadersState = PUTHEADERS_FROM_INIT; TCPFlush(MySocket); break; case SMTP_DATA_HEADER: while((PutHeadersState != PUTHEADERS_DONE) && (TCPIsPutReady(MySocket) > 64u)) { switch(PutHeadersState) { case PUTHEADERS_FROM_INIT: if(SMTPClient.From.szRAM || SMTPClient.From.szROM) { PutHeadersState = PUTHEADERS_FROM; TCPPutROMString(MySocket, (ROM BYTE*)"From: "); } else { PutHeadersState = PUTHEADERS_TO_INIT; } break; case PUTHEADERS_FROM: if(SMTPClient.ROMPointers.From) { SMTPClient.From.szROM = TCPPutROMString(MySocket, SMTPClient.From.szROM); if(*SMTPClient.From.szROM == 0) PutHeadersState = PUTHEADERS_TO_INIT; } else { SMTPClient.From.szRAM = TCPPutString(MySocket, SMTPClient.From.szRAM); if(*SMTPClient.From.szRAM == 0) PutHeadersState = PUTHEADERS_TO_INIT; } break; case PUTHEADERS_TO_INIT: if(SMTPClient.To.szRAM || SMTPClient.To.szROM) { PutHeadersState = PUTHEADERS_TO; 68 TCPPutROMString(MySocket, (ROM BYTE*)"\r\nTo: "); } else { PutHeadersState = PUTHEADERS_CC_INIT; } break; case PUTHEADERS_TO: if(SMTPClient.ROMPointers.To) { SMTPClient.To.szROM = TCPPutROMString(MySocket, SMTPClient.To.szROM); if(*SMTPClient.To.szROM == 0) PutHeadersState = PUTHEADERS_CC_INIT; } else { SMTPClient.To.szRAM = TCPPutString(MySocket, SMTPClient.To.szRAM); if(*SMTPClient.To.szRAM == 0) PutHeadersState = PUTHEADERS_CC_INIT; } break; case PUTHEADERS_CC_INIT: if(SMTPClient.CC.szRAM || SMTPClient.CC.szROM) { PutHeadersState = PUTHEADERS_CC; TCPPutROMString(MySocket, (ROM BYTE*)"\r\nCC: "); } else { PutHeadersState = PUTHEADERS_SUBJECT_INIT; } break; case PUTHEADERS_CC: if(SMTPClient.ROMPointers.CC) { SMTPClient.CC.szROM = TCPPutROMString(MySocket, SMTPClient.CC.szROM); if(*SMTPClient.CC.szROM == 0) PutHeadersState = PUTHEADERS_SUBJECT_INIT; } else { SMTPClient.CC.szRAM = TCPPutString(MySocket, SMTPClient.CC.szRAM); if(*SMTPClient.CC.szRAM == 0) PutHeadersState = PUTHEADERS_SUBJECT_INIT; } break; case PUTHEADERS_SUBJECT_INIT: if(SMTPClient.Subject.szRAM || SMTPClient.Subject.szROM) { PutHeadersState = PUTHEADERS_SUBJECT; TCPPutROMString(MySocket, (ROM BYTE*)"\r\nSubject: "); } else { PutHeadersState = PUTHEADERS_OTHER_INIT; } break; case PUTHEADERS_SUBJECT: if(SMTPClient.ROMPointers.Subject) { SMTPClient.Subject.szROM = TCPPutROMString(MySocket, SMTPClient.Subject.szROM); if(*SMTPClient.Subject.szROM == 0) PutHeadersState = PUTHEADERS_OTHER_INIT; } else { SMTPClient.Subject.szRAM = TCPPutString(MySocket, SMTPClient.Subject.szRAM); if(*SMTPClient.Subject.szRAM == 0) PutHeadersState = PUTHEADERS_OTHER_INIT; } break; case PUTHEADERS_OTHER_INIT: TCPPutROMArray(MySocket, (ROM BYTE*)"\r\n", 2); if(SMTPClient.OtherHeaders.szRAM || SMTPClient.OtherHeaders.szROM) { PutHeadersState = PUTHEADERS_OTHER; } else { TCPPutROMArray(MySocket, (ROM BYTE*)"\r\n", 2); PutHeadersState = PUTHEADERS_DONE; SMTPState++; } break; case PUTHEADERS_OTHER: if(SMTPClient.ROMPointers.OtherHeaders) { SMTPClient.OtherHeaders.szROM = TCPPutROMString(MySocket, SMTPClient.OtherHeaders.szROM); if(*SMTPClient.OtherHeaders.szROM == 0) { TCPPutROMArray(MySocket, (ROM BYTE*)"\r\n", 2); PutHeadersState = PUTHEADERS_DONE; SMTPState++; } 69 } else { SMTPClient.OtherHeaders.szRAM = TCPPutString(MySocket, SMTPClient.OtherHeaders.szRAM); if(*SMTPClient.OtherHeaders.szRAM == 0) { TCPPutROMArray(MySocket, (ROM BYTE*)"\r\n", 2); PutHeadersState = PUTHEADERS_DONE; SMTPState++; } } break; } } TCPFlush(MySocket); break; case SMTP_DATA_BODY_INIT: SMTPState++; RAMStrPtr = SMTPClient.Body.szRAM; ROMStrPtr2 = (ROM BYTE*)"\r\n.\r\n"; CRPeriod.Pos = NULL; if(RAMStrPtr) CRPeriod.Pos = (BYTE*)strstrrampgm((char*)RAMStrPtr, (ROM char*)"\r\n."); case SMTP_DATA_BODY: if(SMTPClient.Body.szRAM || SMTPClient.Body.szROM) { if(*ROMStrPtr2) { // Put the application data, doing the transparancy replacement of "\r\n." with "\r\n.." while(CRPeriod.Pos) { CRPeriod.Pos += 3; RAMStrPtr += TCPPutArray(MySocket, RAMStrPtr, CRPeriod.Pos-RAMStrPtr); if(RAMStrPtr == CRPeriod.Pos) { if(!TCPPut(MySocket, '.')) { CRPeriod.Pos -= 3; break; } } else { CRPeriod.Pos -= 3; break; } CRPeriod.Pos = (BYTE*)strstrrampgm((char*)RAMStrPtr, (ROM char*)"\r\n."); } RAMStrPtr = TCPPutString(MySocket, RAMStrPtr); ROMStrPtr2 = TCPPutROMString(MySocket, ROMStrPtr2); TCPFlush(MySocket); } } else { if(SMTPFlags.bits.ReadyToFinish) { if(*ROMStrPtr2) { ROMStrPtr2 = TCPPutROMString(MySocket, ROMStrPtr2); TCPFlush(MySocket); } } } if(*ROMStrPtr2 == 0u) { SMTPState++; } break; case SMTP_QUIT_INIT: SMTPState++; ROMStrPtr = (ROM BYTE*)"QUIT\r\n"; case SMTP_QUIT: if(*ROMStrPtr) { ROMStrPtr = TCPPutROMString(MySocket, ROMStrPtr); TCPFlush(MySocket); } if(*ROMStrPtr == 0u) { TransportState = TRANSPORT_CLOSE; } break; } break; case TRANSPORT_CLOSE: TCPDisconnect(MySocket); MySocket = INVALID_SOCKET; // Go back to doing nothing TransportState = TRANSPORT_HOME; break; } } void SMTPSendMail(void) { SMTPFlags.bits.ReadyToStart = TRUE; } BOOL SMTPIsBusy(void) { return TransportState != TRANSPORT_HOME; } 70 WORD SMTPIsPutReady(void) { if(SMTPState != SMTP_DATA_BODY) return 0; return TCPIsPutReady(MySocket); } BOOL SMTPPut(BYTE c) { if(CRPeriod.State == CR_PERIOD_NEED_INSERTION) { if(TCPPut(MySocket, '.')) CRPeriod.State = CR_PERIOD_SEEK_CR; else return FALSE; } switch(CRPeriod.State) { case CR_PERIOD_SEEK_CR: if(c == '\r') CRPeriod.State++; break; case CR_PERIOD_SEEK_LF: if(c == '\n') CRPeriod.State++; else if(c != '\r') CRPeriod.State--; break; case CR_PERIOD_SEEK_PERIOD: if(c == '.') CRPeriod.State++; else if(c == '\r') CRPeriod.State--; else CRPeriod.State = CR_PERIOD_SEEK_CR; break; } if(!TCPPut(MySocket, c)) return FALSE; return TRUE; } WORD SMTPPutArray(BYTE* Data, WORD Len) { WORD result = 0; // Comando SMP que chama o TCPPutArray while(Len--) { if(SMTPPut(*Data++)) { result++; } else { Data--; break; } } return result; } #if defined(__18CXX) WORD SMTPPutROMArray(ROM BYTE* Data, WORD Len) { WORD result = 0; // Comando SMTP que chama o TCPPutROMArray while(Len--) { if(SMTPPut(*Data++)) { result++; } else { Data--; break; } } return result; } #endif WORD SMTPPutString(BYTE* Data) { WORD result = 0; while(*Data) { if(SMTPPut(*Data++)) { result++; } else { Data--; break; } } return result; } #if defined(__18CXX) WORD SMTPPutROMString(ROM BYTE* Data) { WORD result = 0; while(*Data) { if(SMTPPut(*Data++)) 71 { result++; } else { Data--; break; } } return result; } #endif void SMTPFlush(void) { TCPFlush(MySocket); } void SMTPPutDone(void) { SMTPFlags.bits.ReadyToFinish = TRUE; } static BYTE *FindEmailAddress(BYTE *str, WORD *wLen) { BYTE *lpStart; BYTE c; union { BYTE Val; struct { BYTE FoundOpenBracket : 1; BYTE FoundAt : 1; } bits; } ParseStates; lpStart = str; *wLen = 0x0000; ParseStates.Val = 0x00; while((c = *str++)) { if(c == '<') { ParseStates.bits.FoundOpenBracket = 1; lpStart = str; *wLen = -1; } else if(c == '@') ParseStates.bits.FoundAt = 1; if( !ParseStates.bits.FoundOpenBracket && !ParseStates.bits.FoundAt && (c == ' ' || c == ',')) { lpStart = str; continue; } else if(c == ',') break; if(ParseStates.bits.FoundOpenBracket && ParseStates.bits.FoundAt) { if(c == '>') break; } *wLen += 1; } if(!ParseStates.bits.FoundAt) *wLen = 0; return lpStart; } static ROM BYTE *FindROMEmailAddress(ROM BYTE *str, WORD *wLen) { ROM BYTE *lpStart; BYTE c; union { BYTE Val; struct { BYTE FoundOpenBracket : 1; BYTE FoundAt : 1; } bits; } ParseStates; lpStart = str; *wLen = 0x0000; ParseStates.Val = 0x00; while((c = *str++)) { if(c == '<') { ParseStates.bits.FoundOpenBracket = 1; lpStart = str; *wLen = -1; } else if(c == '@') ParseStates.bits.FoundAt = 1; if( !ParseStates.bits.FoundOpenBracket && !ParseStates.bits.FoundAt && (c == ' ' || c == ',')) { lpStart = str; continue; } else if(c == ',') break; if(ParseStates.bits.FoundOpenBracket && ParseStates.bits.FoundAt) 72 { if(c == '>') break; } *wLen += 1; } if(!ParseStates.bits.FoundAt) *wLen = 0; return lpStart; } #endif //#if defined(STACK_USE_SMTP_CLIENT) REFERNCIAS 2EI ENGENHARIA. PME10A. [s.d.]. Disponvel em: <http://www.2ei.com.br/loja/>. Acesso em: 1 maio 2008. BENTHAM, Jeremy. Miniature Web Server. [S.l.]: Embedded.com, 2001. Disponvel em: <http://www.embedded.com/story/OEG20010312S0103>. Acesso em: 17 Set. 2007. BENTHAM, Jeremy. TCP/IP LEAN: Web Server for Embedded System. Lawrence, Kansas: CMP Books, 2002. 559 p. COMER, Douglas. Interligao em Rede com TCP/IP. Rio de Janeiro: Campus, 2004. DENARDIN, Gustavo Weber. Microcontroladores. [S.l.]: [s.n.], [s.d.]. Disponvel em: <http://pessoal.pb.cefetpr.br/gustavo/apostila_micro.pdf>. Acesso em 13 jun. 2008. FIELDING, R; et al. RFC 2616: Hypertext Transfer Protocol - HTTP/1.1. [S.l.]: The Internet Society, 1999. Disponvel em: <http://tools.ietf.org/html/rfc2616>. Acesso em: 30 abr. 2008. KLENSIN, J. (ed.). RFC 2821: Simple Mail Transfer Protocol. [S.l.]: The Internet Society, 2001. Disponvel em: <http://tools.ietf.org/html/rfc2821>. Acesso em: 30 abr. 2008. MICROCHIP Technology Inc. PIC18F97J60 Family Data Sheet: 64/80/100-Pin High- Performance, 1-Mbit Flash Microcontrollers with Ethernet. [S.l.]: Microchip Technology Inc., 2008. Disponvel em: <http://ww1.microchip.com/downloads/en/DeviceDoc/39762d.pdf >. Acesso em: 1 maio 2008. MOKARZEL, Marcos Perez; CARNEIRO, Karina Perez Mokarzel. Internet Embedded TCP/IP para Microcontroladores. So Paulo: rica, 2004. 342 p. PORRCA, Lcia Maria. Monitoramento Ambiental. [S.l.]: IBAMA, 2000. Disponvel em: <http://www.ibama.gov.br/siucweb/guiadechefe/guia/t-1corpo.htm>. Acesso em: 10 nov. 2007. REXFORD, Jennifer; KRISHNAMURTHY, Balachander. Redes para a Web. Rio de Janeiro: Campus, 2001. 651 p. SALAMON, Luiz Guiode. Biblioteca TCP/IP para Ambientes Microprocessados. Dez. 2002. 68 p. Orientador: Elgio Schlemer. Monografia (Bacharelado) - Curso de Cincia da Computao, Universidade Luterana do Brasil, Gravata. 2002. SILVA, Rafael. Introduo a famlia de microcontroladores PIC. The Bug! Magazine, [S.l.], n. 1, edio 1, artigo 8, 5 mar. 2006. Disponvel em: <http://www.thebugmagazine.org/magazine/bug01/0x08_introducao-PIC.pdf> Acesso em: 21 jun. 2008. 74 TANENBAUM, Andrew. Redes de Computadores. Rio de Janeiro: Campus, 2003. WIKIPDIA. Microcontrolador PIC. [S.l.]: Wikipdia, [s.d.]. Disponvel em: <http://pt.wikipedia.org/wiki/Microcontrolador_PIC>. Acesso em: 30 abr. 2008. WIKIPDIA. Microcontrolador. [S.l.]: Wikipdia, [s.d.]. Disponvel em: <http://pt.wikipedia.org/wiki/Microcontrolador>. Acesso em: 17 set. 2007. WIKIPDIA.TCP/IP. [S.l.]: Wikipdia, [s.d.]. Disponvel em: <http://pt.wikipedia.org/wiki/TCP/IP>. Acesso em: 17 nov. 2007. ZEILMAN, Rafael Pereira. Trabalho de concluso ps-graduao lato senso. 2002. 139 p. Monografia (Ps-Graduao Lato Senso) Unimversidade Federal do Rio Grande do Sul, Porto Alegre. 2002.
Modelagem Numérica e Computacional com Similitude e Elementos Finitos: Desenvolvimento de Equação Preditiva para o Cálculo da Força de Retenção em Freios de Estampagem