/*
smtp_cli.c: 1. support echo server for TCP port 10000.
            2. support SMTP client(send E-mail)
  
Compiler: BC++ 3.1, 
          Turbo C++ 1.01(3.01) (free from http://cc.codegear.com/free/cpp)

Compile mode: Large

Project: Client.c
         ..\lib\7186el.Lib
         ..\lib\tcp_dm32.lib
         ..\lib\FW_nnnnn.LIB

Hordware: uPAC-7186EX

There are some data values should be set.
    SMTP_MyEmailAddr : source email address
    SMTP_DestEmailAddr[0] : destination email address 1
    SMTP_DestEmailAddr[1] : destination email address 2
    SMTP_DestEmailAddrNo : number of destination email address
                  **max destination address number is 5
    SMTP_Subject : email subject
    SMTP_MailData : email contents

[Dec 19, 2008] by Liam
*/

#include<conio.h>
#include<stdio.h>
#include "..\lib\7186e.h"
#include "..\lib\Tcpip32.h"
#include "..\lib\MFW.h"

void do_echo( int skt , int mode);

#define BUFSIZE 1460       /* read/write buffer size */

TCP_SERVER TcpServer[]={
    {
    10000, /* port */
    -1, /* socket */
    0,  /* state */
    0,  /* connect */
    do_echo/* CallBackFun */
    }
};
           
unsigned char MyIp[4];

void ShowIp(void)
{ 
    static int idx=0;
    int data;

#if 0
    data=MyIp[idx];
#endif
    data=netconf[nets[0].confix].Iaddr.c[idx];
    
#if 0
    if(!idx) Puts("\r\n");
    Print("%d.",data);
#endif  
    idx++;
    Show5DigitLedWithDot(1,idx);
    Show5DigitLed(5,data%10);
    data/=10;
    if(data){
        Show5DigitLed(4,data%10);
        data/=10;
        if(data) Show5DigitLed(3,data);
        else    Show5DigitLed(3,16);
    }
    else {
        Show5DigitLed(4,16);
        Show5DigitLed(3,16);
    }
    Show5DigitLed(2,16);
    if(idx>=4) idx=0;
}

#define ESTABLISHED   1     /* state machine states, see handbook */
#define FINWAIT_1     2
#define FINWAIT_2     3
#define CLOSED_WAIT   4
#define TIMEWAIT      5
#define LAST_ACK      6
#define CLOSED        7
#define SYN_SENT      8
#define SYN_RECEIVED  9
#define LISTEN       16

void ShowSocketStatus(void)
{ 
    int i;

    Puts("\r\n");
    for(i=0; i<MaxSocketNo; i++){
        Print("[%02d=%02d:", i, connblo[i].state);
        switch(connblo[i].state){
            case ESTABLISHED: Print("ESTABLISHED]"); break;
            case FINWAIT_1: Print("FINWAIT_1]"); break;
            case FINWAIT_2: Print("FINWAIT_2]"); break;
            case CLOSED_WAIT: Print("CLOSED_WAIT]"); break;
            case TIMEWAIT: Print("TIMEWAIT]"); break;
            case LAST_ACK: Print("LAST_ACK]"); break;
            case CLOSED: Print("CLOSED]"); break;
            case SYN_SENT: Print("SYN_SENT]"); break;
            case SYN_RECEIVED: Print("SYN_RECEIVED]"); break;
            case LISTEN: Print("LISTEN]"); break;
            case 0: Print("NOT_USED_YET]"); break;
            default: Print("!!!UnKnown STATE!!!]"); break;
        }
        
        Print(",stat=%x", connblo[i].blockstat);
        if(i & 1) Print("\r\n");
        else Print(" , ");
    }
}

void UserLoop(void);
//void UserInit(int argc,char *argv[])
void XS_UserInit(int argc,char *argv[])
{ 
    int i;
    extern int bAcceptBroadcast;
    extern unsigned long ACKDELAY;  /* variable in tcp.c */
    char version[20];

    InitLib();
    
    SmtpClient.port=25;
    for(i=1;i<argc;i++){
        if(argv[i][0]=='/'){
            switch(argv[i][1]){
                case 'i': case 'I':
                    // set the IP address of the remote SMTP server.
                    SmtpClient.ip=argv[i]+2;
                    Print("[SMTP server IP=%s]",SmtpClient.ip);
                    break;
/* set the service port.
                case 'p': case 'P':
                    // set the TCP port of the remote server.
                    if(1==sscanf(argv[i]+2,"%i",&port)){
                        SmtpClient.port=port;
                        Print("[remote port=%u(%x)]",SmtpClient.port,SmtpClient.port);
                    }
                    break;
*/
            }
        }
    }

    bAcceptBroadcast=0;
    ACKDELAY=200;
    XS_GetVersion(version);
    Print("[X-Server library]: version=%s ",version);
    XS_GetLibDate(version);
    Print("date=%s\r\n",version);
    GetTcpipLibDate(version);
    Print("[Tcpip library]: version=%X, Date=%s\r\n",GetTcpipLibVer(),version);
    
#if 0
    Print("<%d>",SmtpClient.bConnected);
#endif  

    XS_AddSystemLoopFun(UserLoop); /* need add this line for the library date after 2004/06/02 */

    /* to use TCP/IP function, add the following two lines after XS library 0.9.3.00*/  
    XS_AddSystemLoopFun(XS_SocketLoopFun);
    XS_StartSocket();    //Called on xs09300.lib[2006/09/26] or later 
    
    XS_AddServer(&TcpServer[0]);
    XS_AddClient(&SmtpClient);
    DT2_AddTimer(500,2,LedToggle);
}

void XS_UserEnd(void)
{
    XS_StopSocket();
    DisableWDT();
}

char Command[100];
int idx=0;

void UserLoop(void)
{ 
    long tmpt;
    int data;
    int err;
    int XS_SendMail(void);
  
  
    if(Kbhit()){
        switch(data=Getch()){
            case 27:
                QuitMain=1;
                break;
            default:
                Command[idx]=data;
                if(idx<99) idx++;
                Putch(data);
                if(data=='\r'){
                    Command[idx]=0;
                    Putch('\n');
                    if(Command[0]=='/'){
                        if(Command[1]=='S'){
                            SMTP_MyName="ICPDAS_7186E"; 
#if 0
                            SMTP_MyEmailAddr="service@icpdas.com";
                            SMTP_DestEmailAddr[0]="service@icpdas.com";
                            SMTP_DestEmailAddr[1]="service@icpdas.com";
#endif
                            SMTP_MyEmailAddr="jency_fang@icpdas.com";
                            SMTP_DestEmailAddr[0]="jency_fang@icpdas.com";
                            SMTP_DestEmailAddr[1]="jency_fang@icpdas.com";
                            SMTP_DestEmailAddrNo=2;
                            SMTP_Subject="Test Mail from uPAC-7186EX";
                            SMTP_MailData="This is a test mail send from uPAC-7186EX.";
                            
                            // 如果沒有郵件內容應該用:
                            // SMTP_MailData="";
                            // 而不是用:
                            // SMTP_MailData=0; // 內容將是"(null)"

                            err=XS_SendMail();
                        }
                        else if(Command[1]=='i'){
                            DT_AddTimer(4, 1000, 1, ShowIp);
                        }
                        else if(Command[1]=='0' && Command[2]=='0'){
                            ShowSocketStatus();
                        }
                        else {
                            Print("Unsupport command\r\n");
                        }
                    }
                    else {
                        Print("[do nothing]\r\n");
                    }
                    idx=0;
                }
                break;  
        }
    }
}

char buf[BUFSIZE],SendBack[BUFSIZE+2];
void DoCommand(char *cmd,int cmdlen,int skt)
{
    if(cmdlen>=3){
        if(cmd[1]=='0' && cmd[2]=='0'){
            
        }
    }
}

// when client is connected, do echo here
void do_echo( int skt, int mode)
{ 
    int i, cc, err, Sendlen;

    if(!mode){
        Sendlen=sprintf(SendBack, "Welcome connect to port %u\r\nThere are %d clients connect to this port\r\n",
                    TcpServer[Socket_Idx[skt]].port, TcpServer[Socket_Idx[skt]].connect);
        goto SendMessage;
    }
    else{
        err = cc = readsocket(skt, buf, sizeof(buf)-1);
        if(err <= 0){              /* error or disconnected by remote side */
            XS_CloseSocket(skt);
        }
        else{
            if(buf[0]=='/'){
                DoCommand(buf, cc, skt);
            }
            else{
                for(i=0; i < cc; i++){
                    SendBack[i]=buf[i];
                }
                Sendlen=cc;
SendMessage:
                err= writesocket(skt, SendBack, Sendlen);
                if (err < 0) {               /* write error */
                    Print( "echo write error %d\n\r", err );
                    XS_CloseSocket(skt);
                }
            }
        }
    }
}

void main(int argc,char *argv[])
{
    XS_main(argc,argv); /* call the XS library main function. */
}