/* XDemo64: SMTP demo Compiler: BC++ 3.1 Compile mode: large Project: user.c v7000.c vModbus.c [after vcom3002.lib] Vsocket.c ..\Lib\7186EL.Lib ..\Lib\tcp_dm32.lib ..\Lib\VcomNNNN.Lib, with NNNN being the lib file's version. The Simple Mail Transfer Protocol(SMTP) is used as the common mechanism for transporting electronic mail among different hosts within the Department of Defense Internet protocol suite. A user's SMTP process opens a TCP connection to a server SMTP process on a remote host and send mail across the connection. The server SMTP listens for a TCP connection on a well-known port (25). [Model for SMTP Use] +----------+ +----------+ | | | | | | | | +------+ | Sender |Commands/Replies| Receiver | |Sender| | MTA |<-------------->| MTA | +------+ | |<---->| | TCP connection | |<---->| File | |System| | | | | |System| +------+ +----------+ +----------+ +------+ uPAC-7186EX Sender-SMTP Receiver-SMTP User MailBox *MAT (message transfer agent) The SMTP provides mechanisms for the transmission of mail; directly from the sending user's host to the receiving user's host. If you need the detail in SMTP,please refer to RFC821 Follow the executing steps below to send the e-mail without changing the source code. Step 1: 19smtp 210.241.239.69 or 19SMTP 210.241.239.69 -->Change the SMTP server 19from sean@icpdas.com or 19FROM test@test.com -->Change the MAIL FROM address 19to sean@icpdas.com or 19TO test@test.com -->Change the MAIL TO address 19s 1 -->Build a socket to connect to the SMTP server Step 2: Load a file to the uPAC-7186EX, such as 'Mail.ini', but must follow the rules: 1.Add the string 'Subject' in this file, because NO subject e-mail will reject by SMTP server 2.Add the character '.' in end of file, because the DATA process will end by detecting this character. Subject:Test SMTP Hello!! This is a test Mail . The client functions consist of the ReceiveSocketBinaryCmd(),KillSockets(),BuildSockets() and SendSocketBinaryCmd() in "Vsocket.C". Hardware: uPAC-7186EX * 1 uPAC-7186EX (IP:192.168.254.30) SMTP server:10.0.0.5 (ICPDAS SMTP server) Note: Run this demo, you can load one extra text file into uPAC-7186EX. (You can write the data in the Mail.ini you want to send for this demo). [Dec 18, 2008] by Liam */ #include #include #include "..\lib\7186e.h" #include "..\lib\tcpip32.h" #include "..\lib\vxcomm.h" #include "Vsocket.h" int iSocketflag; char InBuf[1023],OutBuf[1023]; //InBuf:the buffer of receing ,OutBuf:the buffer of sending int iOutskt; //the socket number of connecting unsigned int iPort; //the SMTP server port number unsigned char iIpStr[17]; //the SMTP server IP static FILE_DATA far *config; int SmtpMode; int Recesucceed=0; unsigned long stime; char HELO[]="HELO ICPDAS_Sean\r\n"; char MAIL[]=""; //Change the mail address to your char RCPT[]=""; //Change the mail address where you want to send unsigned long FSeek(FILE_DATA far *file_pointer,char cMark,unsigned long lStart,int iTh,char *sstring); void UserCount(void) { /* User's timer trigger function. Please refer to XDemo04 for detail description. Please refer to XDemo09 for example code. */ } void UserInit(void) { /* Initialize user's program. Please refer to XDemo04 for detail description. Please refer to XDemo09 for example code. */ /* All of the program user.c needn't function Installcom(). Becuase they have install When the Xserver initialize. If you want to change the baud rate.data format, please using the function SetBaudrate().SetDataFormat(). */ InitLib(); SetBaudrate1(115200L); iSocketflag=0; SmtpMode=0; sprintf(iIpStr, "10.0.0.5"); //SMTP server IP iPort=25; //SMTP server port 25 printCom1("IpStr=%10s, iPort=%5d\n\r", iIpStr, iPort); config=GetFileInfoByName("Mail.ini"); } void UserLoopFun(void) { /* VxComm.exe will call this function every scan time Please refer to XDemo11 for Real-time I/O control */ int iRet, i; int icheck; extern int errno; if(iSocketflag>0) { iRet=ReceiveSocketBinaryCmd(iOutskt, InBuf, sizeof(InBuf), 700); if (iRet==-1)// read error { if(errno==ETIMEDOUT) //Detect whether the error of recv is caused by timeout. { if(GetTimeTicks()-stime<8000) //8 sec { Recesucceed=1; printCom1("echo Receive timeout \r\n"); } else { printCom1("Receive timeout over 8 sec\r\n",iRet); KillSocket(iOutskt); Recesucceed=0; iSocketflag=0; SmtpMode=0; } } else { Recesucceed=0; printCom1("echo Receive error,code(%d)\r\n",iRet); KillSocket(iOutskt); iSocketflag=0; SmtpMode=0; } } else { printCom1("%d, %s\r\n", SmtpMode+1, InBuf); sscanf(InBuf, "%d", &icheck); if(icheck!=221) //221 means the SMTP server return sending mail successfully and quit this connection { Recesucceed=0; if(Recesucceed==0) { switch(SmtpMode) { case 0: strcpy(OutBuf,HELO); break; case 1: sprintf(OutBuf,"MAIL FROM:%s\r\n",MAIL); break; case 2: sprintf(OutBuf,"RCPT TO:%s\r\n",RCPT); break; case 3: strcpy(OutBuf,"DATA\r\n"); break; case 4: sprintf(OutBuf,"From:%s\r\nTo:%ls\r\n",MAIL,RCPT); if(config!=NULL) strcat(OutBuf,config->addr); else strcat(OutBuf,"Subject:Test Mail\r\nThis is a test mail\r\n.\r\n"); break; case 5: strcpy(OutBuf,"QUIT\r\n"); break; } iRet=SendSocketBinaryCmd(iOutskt, OutBuf, strlen(OutBuf)); if (iRet==-1)// write error { printCom1("echo Send error,code(%d)\r\n",iRet); return; } else { stime=GetTimeTicks(); printCom1("Send the command(%s) from client\r\n",OutBuf); } SmtpMode++; } } else { Recesucceed=0; printCom1("Send the mail successfully and close the connection!!\r\n"); KillSocket(iOutskt); iSocketflag=0; SmtpMode=0; } } } } int UserCmd(unsigned char *Cmd,unsigned char *Response) { /* Xserver executes this function when received a package form TCP port 10000 and the first two bytes are "19". Funtion of Xserver, Please refer to XDemo04 for detail description. */ int start; char sCommand[10], sParameter[50]; strlwr(Cmd); sscanf(Cmd,"%s %s", &sCommand, &sParameter); printCom1("%s, %s\r\n", sCommand, sParameter); if(!strcmp(sCommand, "smtp")) strcpy(iIpStr, sParameter); if(!strcmp(sCommand, "from")) strcpy(MAIL, sParameter); if(!strcmp(sCommand, "to")) strcpy(RCPT, sParameter); if(Cmd[0]=='s') //Build a socket to connect to the SMTP server { sscanf(Cmd+1,"%d", &start); if(start==1) { if(!iSocketflag) { iOutskt=BuildSocket(iIpStr, iPort, 2000); //buildsockets printCom1("Socket number:%d!!\r\n", iOutskt); if (iOutskt==-1){ printCom1("connect error!!\r\n"); iSocketflag=0; } else{ iSocketflag=1; start=0; } } } } return 1; /* return error */ } int VcomUserBinaryCmd(TCPREADDATA *p) { /* VXCOMM.EXE 2.6.12(04,Sep,2001) or later will support this function. Xserver executes this function when received a package form TCP port 10000 and the first two bytes are "23". Please refer to XDemo04 for detail description. Please refer to XDemo23 for example code. */ return 1; /* any value will be accept */ } int VcomCmdUser(TCPREADDATA *p) { /* VCOM3005 (Feb,22,2002) or later will call this function for PortUser. When packets received by TCP PORT PortUser(user defined) of 7188E/8000E, Xserver will call this function. Please refer to XDemo04 for detail description. */ VcomSendSocket(p->Socket, p->ReadUartChar, p->Length); return 1; /* any value will be accept */ } void PortUserStart(int skt) { /* XS8_3200.Lib Version 3.2.00 (20,Apr,2004) or later version supports this function. When a TCP/IP client connects to the 7188E/8000E via the user's defined port(PortUser), the Xserver calls the function once. Please refer to XDemo04 for detail description. */ skt=skt; //do nothing } void Port9999Start(int skt) { /* XS8_3200.Lib Version 3.2.00 (20,Apr,2004) or later version supports this function. When a TCP/IP client connects to the 7188E/8000E TCP port 9999, the Xserver calls the function once. Please refer to XDemo04 for detail description. */ skt=skt; //do nothing } void Port502Start(int skt) { /* XS8_3200.Lib Version 3.2.00 (20,Apr,2004) or later version supports this function. When a TCP/IP client connects to the 7188E/8000E TCP port 502, the Xserver calls the function once. Please refer to XDemo04 for detail description. */ skt=skt; //do nothing }