📄 smtp.c
字号:
/******************************************************************
* smtp.c: Simple Mail transfer protocol
*
* Copyright (c) 2001 Atmel Corporation.
* All Rights Reserved.
*
* You are autorized to use, copy and distribute this software only at
* a single site (the term "site" meaning a single company location).
* This copyright notice must be included in any copy, modification
* or portion of this software merged into another program.
*
* This software is licenced solely for use with Atmel AVR micro
* controller family. The software may not be modified to execute on
* any other microcontroller architectures
*
* This software is provided "as is"; Without warranties either express
* or implied, including any warranty regarding merchantability,
* fitness for a particular purpose or noninfringement.
*
* In no event shall Atmel or its suppliers be liable for any special,
* indirect,incidential or concequential damages resulting from the
* use or inability to use this software.
*
* Revision history:
*
* January 17, 2001: Version 1.0 Created by JB
* July 13, 2001 Version 1.2 JB
* - Changed to IAR compiler V2.25
* - Renamed flash file functions to avoid conflict with
* standard file I/O names
* - Bug fixes in HTTP
* - Speed optimization in TCP
*
*
*******************************************************************/
#define ENABLE_BIT_DEFINITIONS
#include "comp_a90.h"
#include "tcp.h"
#include "main.h"
#include "ffile.h"
#include "smtp.h"
#include "config.h"
#include <iom103.h>
#include <string.h>
#include <stdio.h>
#include <pgmspace.h>
/*states*/
#define SMTP_STATE_CONNECT 0
#define SMTP_STATE_HELO 1
#define SMTP_STATE_MAIL 2
#define SMTP_STATE_RCPT 3
#define SMTP_STATE_DATA1 4
#define SMTP_STATE_DATA2 5
#define SMTP_STATE_QUIT 6
/*constant strings to placed in flash*/
flash char SMTP_CLRF[] ="\r\n";
flash char SMTP_CLRF_DOT_CLRF[] ="\r\n.\r\n";
flash char SMTP_HEADER_FROM[] ="From: ";
flash char SMTP_HEADER_TO[] ="To: ";
flash char SMTP_HEADER_SUBJECT[] ="Subject: ";
flash char SMTP_COMMAND_HELO[] ="HELO ";
flash char SMTP_COMMAND_MAIL[] ="MAIL FROM:";
flash char SMTP_COMMAND_RCPT[] ="RCPT TO:";
flash char SMTP_COMMAND_DATA[] ="DATA\r\n";
flash char SMTP_COMMAND_QUIT[] ="QUIT\r\n";
/*sends a mail to the adress specified in server.ini,
returns 1 if successful, 0 otherwise*/
unsigned char sendMail(char * subject, char * message)
{
unsigned char smtpState; //state of the state-machine
char buffer[SMTP_BUFFER]; //multipurpose buffer
char mailSender[SMTP_BUFFER_READ_MAIL]; //the sending mail address, read from server.ini
char mailReceiver[SMTP_BUFFER_READ_MAIL]; //the receiving mail address, read from server.ini
char mailHostName[SMTP_BUFFER_READ_HOST]; //the identification given to the mailserver, read from server.ini
unsigned int mailIp0,mailIp1; //the mailserver IP-address, read from server.ini
SOCKET *sock;
/*read setings from server.ini*/
if (!getOption("SMTP\0","sender\0",mailSender) || !getOption("SMTP\0","receiver\0",mailReceiver)
|| !getOption("SMTP\0","host\0",mailHostName))
{
return 0; //error reading from server.ini
}
if (!getOption("SMTP\0","mailIp0\0",buffer))
{
return 0; //error reading from server.ini
}
sscanf(buffer,"%x",&mailIp0);
if (!getOption("SMTP\0","mailIp1\0",buffer))
return 0; //error reading from server.ini
sscanf(buffer,"%x",&mailIp1);
smtpState=SMTP_STATE_CONNECT; //initial state
sock=TCPaopen(SMTP_SERVER_PORT,mailIp0,mailIp1,0);//connect to the mail server
/*state machine*/
for (;;)
{
switch (smtpState)
{
case SMTP_STATE_CONNECT:
if (SMTPwait(sock)) //if new data received
{
TCPreadln(sock,SMTP_BUFFER,buffer,1);
if (!strncmp(buffer,"220",3))
{
TCPbufferFlush(sock); //clear the receivebuffer
/*send HELO command*/
TCPsend_P(sock,strlen_P(SMTP_COMMAND_HELO),SMTP_COMMAND_HELO);
TCPsend(sock,strlen(mailHostName),mailHostName);
TCPsend_P(sock,strlen_P(SMTP_CLRF),SMTP_CLRF);
smtpState=SMTP_STATE_HELO;
}
else if (!strncmp(buffer,"421",3)) //Service not available
{
TCPsend_P(sock,strlen_P(SMTP_COMMAND_QUIT),SMTP_COMMAND_QUIT);
TCPclose(sock);
return 0;
}
}
else//timeout
{
TCPsend_P(sock,strlen_P(SMTP_COMMAND_QUIT),SMTP_COMMAND_QUIT);
TCPclose(sock);
return 0;
}
break;
case SMTP_STATE_HELO:
if (SMTPwait(sock)) //if new data received
{
TCPreadln(sock,SMTP_BUFFER,buffer,1);
if (!strncmp(buffer,"250",3))
{
TCPbufferFlush(sock); //clear the receivebuffer
/*send MAIL command*/
TCPsend_P(sock,strlen_P(SMTP_COMMAND_MAIL),SMTP_COMMAND_MAIL);
TCPsend(sock,strlen(mailSender),mailSender);
TCPsend_P(sock,strlen_P(SMTP_CLRF),SMTP_CLRF);
smtpState=SMTP_STATE_MAIL;
}
else if (!strncmp(buffer,"421",3) || !strncmp(buffer,"500",3) || !strncmp(buffer,"501",3)
|| !strncmp(buffer,"504",3))//error
{
TCPsend_P(sock,strlen_P(SMTP_COMMAND_QUIT),SMTP_COMMAND_QUIT);
TCPclose(sock);
return 0;
}
}
else//timeout
{
TCPsend_P(sock,strlen_P(SMTP_COMMAND_QUIT),SMTP_COMMAND_QUIT);
TCPclose(sock);
return 0;
}
break;
case SMTP_STATE_MAIL:
if (SMTPwait(sock)) //if new data received
{
TCPreadln(sock,SMTP_BUFFER,buffer,1);
if (!strncmp(buffer,"250",3))
{
TCPbufferFlush(sock); //clear the receivebuffer
/*send RCPT command*/
TCPsend_P(sock,strlen_P(SMTP_COMMAND_RCPT),SMTP_COMMAND_RCPT);
TCPsend(sock,strlen(mailReceiver),mailReceiver);
TCPsend_P(sock,strlen_P(SMTP_CLRF),SMTP_CLRF);
smtpState=SMTP_STATE_RCPT;
}
else if (!strncmp(buffer,"421",3) || !strncmp(buffer,"451",3) || !strncmp(buffer,"452",3)
|| !strncmp(buffer,"500",3) || !strncmp(buffer,"501",3) || !strncmp(buffer,"552",3))//error
{
TCPsend_P(sock,strlen_P(SMTP_COMMAND_QUIT),SMTP_COMMAND_QUIT);
TCPclose(sock);
return 0;
}
}
else//timeout
{
TCPsend_P(sock,strlen_P(SMTP_COMMAND_QUIT),SMTP_COMMAND_QUIT);
TCPclose(sock);
return 0;
}
break;
case SMTP_STATE_RCPT:
if (SMTPwait(sock)) //if new data received
{
TCPreadln(sock,SMTP_BUFFER,buffer,1);
if (!strncmp(buffer,"250",3) || !strncmp(buffer,"251",3))
{
TCPbufferFlush(sock); //clear the receivebuffer
/*send DATA command*/
TCPsend_P(sock,strlen_P(SMTP_COMMAND_DATA),SMTP_COMMAND_DATA);
smtpState=SMTP_STATE_DATA1;
}
else if (!strncmp(buffer,"421",3) || !strncmp(buffer,"450",3) || !strncmp(buffer,"451",3)
|| !strncmp(buffer,"452",3) || !strncmp(buffer,"500",3) || !strncmp(buffer,"501",3)
|| !strncmp(buffer,"503",3) || !strncmp(buffer,"550",3) || !strncmp(buffer,"551",3)
|| !strncmp(buffer,"552",3) || !strncmp(buffer,"553",3))//error
{
TCPsend_P(sock,strlen_P(SMTP_COMMAND_QUIT),SMTP_COMMAND_QUIT);
TCPclose(sock);
return 0;
}
}
else//timeout
{
TCPsend_P(sock,strlen_P(SMTP_COMMAND_QUIT),SMTP_COMMAND_QUIT);
TCPclose(sock);
return 0;
}
break;
case SMTP_STATE_DATA1:
if (SMTPwait(sock)) //if new data received
{
TCPreadln(sock,SMTP_BUFFER,buffer,1);
if (!strncmp(buffer,"354",3))
{
TCPbufferFlush(sock); //clear the receivebuffer
/*send the message*/
TCPsend_P(sock,strlen_P(SMTP_HEADER_FROM),SMTP_HEADER_FROM);
TCPsend(sock,strlen(mailSender),mailSender);
TCPsend_P(sock,strlen_P(SMTP_CLRF),SMTP_CLRF);
TCPsend_P(sock,strlen_P(SMTP_HEADER_TO),SMTP_HEADER_TO);
TCPsend(sock,strlen(mailReceiver),mailReceiver);
TCPsend_P(sock,strlen_P(SMTP_CLRF),SMTP_CLRF);
TCPsend_P(sock,strlen_P(SMTP_HEADER_SUBJECT),SMTP_HEADER_SUBJECT);
TCPsend(sock,strlen(subject),subject);
TCPsend_P(sock,strlen_P(SMTP_CLRF),SMTP_CLRF);
TCPsend_P(sock,strlen_P(SMTP_CLRF),SMTP_CLRF);
TCPsend(sock,strlen(message),message);
TCPsend_P(sock,strlen_P(SMTP_CLRF_DOT_CLRF),SMTP_CLRF_DOT_CLRF);
smtpState=SMTP_STATE_DATA2;
}
else if (!strncmp(buffer,"421",3) || !strncmp(buffer,"451",3) || !strncmp(buffer,"452",3)
|| !strncmp(buffer,"500",3) || !strncmp(buffer,"501",3) || !strncmp(buffer,"503",3)
|| !strncmp(buffer,"552",3) || !strncmp(buffer,"554",3))//error
{
TCPsend_P(sock,strlen_P(SMTP_COMMAND_QUIT),SMTP_COMMAND_QUIT);
TCPclose(sock);
return 0;
}
}
else //timeout
{
TCPsend_P(sock,strlen_P(SMTP_COMMAND_QUIT),SMTP_COMMAND_QUIT);
TCPclose(sock);
return 0;
}
break;
case SMTP_STATE_DATA2:
if (SMTPwait(sock)) //if new data received
{
TCPreadln(sock,SMTP_BUFFER,buffer,1);
if (!strncmp(buffer,"250",3))
{
TCPbufferFlush(sock); //clear the receivebuffer
/*send QUIT command*/
TCPsend_P(sock,strlen_P(SMTP_COMMAND_QUIT),SMTP_COMMAND_QUIT);
smtpState=SMTP_STATE_QUIT;
}
else if (!strncmp(buffer,"500",3)) //error
{
TCPsend_P(sock,strlen_P(SMTP_COMMAND_QUIT),SMTP_COMMAND_QUIT);
TCPclose(sock);
return 0;
}
}
else//timeout
{
TCPsend_P(sock,strlen_P(SMTP_COMMAND_QUIT),SMTP_COMMAND_QUIT);
TCPclose(sock);
return 0;
}
break;
case SMTP_STATE_QUIT:
if (SMTPwait(sock)) //if new data received
{
TCPreadln(sock,SMTP_BUFFER,buffer,1);
if (!strncmp(buffer,"221",3))
{
TCPbufferFlush(sock); //clear the receivebuffer
TCPclose(sock);
return 1;
}
else if (!strncmp(buffer,"500",3)) //error
{
TCPclose(sock);
/*return success, the message has succesfully been sent,
even if closing the conection failed */
return 1;
}
}
else//timeout
{
TCPclose(sock);
/*return success, the message has succesfully been sent,
even if closing the conection failed */
return 1;
}
break;
}
}
}
/* waits for timeout or TCP data, returns 1 if data, 0 if timeout */
unsigned char SMTPwait(SOCKET * sock)
{
TCCR1B|=(1<<CTC1 | 1<<CS12 | 1<<CS10); //clear counter on compare match, clock divided by 1024
OCR1A=SMTP_TIMEOUT;
TIFR|=(1<<OCF1A); //output compare flag 1A is cleared by writing a logic one
TCNT1=0; //clear the counter
for (;;)
{
if (TCPsize(sock)) //poll TCP buffer
{
return 1;
}
else if (TIFR&(1<<OCF1A)) //output compare flag 1A is set, timeout
{
return 0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -