Você está na página 1de 0

UNIVERSIDADE LUTERANA DO BRASIL

CURSO DE CINCIA DA COMPUTAO


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.