/*
Transfer.c: Transfer

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

Transfer user's program from Xserver 3.x.xx to MFW.
  
Hordware: uPAC-7186EX

[Jan 13, 2005] by Kevin
[Dec 19, 2008] by Liam  
*/

#include<conio.h>
#include<stdio.h>
#include "..\lib\7186e.h"
#include "..\lib\Tcpip32.h"
#include "..\lib\MFW.h"
  
//=== Begin Function declaration for Xserver library version 3.x.xx ====
void Port502Start(int SocketNumber);   //Port 502, connected event.
int  VcomCmdModbus(TCPREADDATA *p);    //Port 502

void Port9999Start(int SocketNumber);  //Port 9999, connected event.
int  VcomCmd7000(TCPREADDATA *p);      //Port 9999

void PortUserStart(int SocketNumber);  //Port 10000, connected event.

int  UserCmd(unsigned char *Cmd,unsigned char *Response); //Port 10000, user cmd "19"
int  VcomUserBinaryCmd(TCPREADDATA *p); //Port 10000, user cmd "23"
//=== End Function declaration for Xserver library version 3.x.xx ======


void Port502  (int SocketNumber, int Connected);
void Port9999 (int SocketNumber, int Connected);
void Port10000(int SocketNumber, int Connected);

#define BUFSIZE 1460       /* read/write buffer size */
/*
typedef struct {
    unsigned port;
    int socket;
    int state;
    int     connect;
    void (*CallBackFun)(int skt,int mode);
} TCP_SERVER;
*/
void do_GetResponse(int skt); //TCP client's callback function

TCP_CLIENT TcpClient=  //Initialize a TCP Client with default IP 10.0.8.157 and port 10001
{
    "10.0.8.165",   //  char *ip;
    10001,      //  unsigned port;
    0,      //  int socket;
    0,      //  int tmpState;
    -2,     //  int     bConnected;
    1,      //  int iConnectTryCount;   //連線不成功時重試次數
    4000,       //  long    lConnetTimeout;     //等連線成功的 timeout 時間。(0 就用預設值 400ms)
    0,      //  long    ltmpT;
    do_GetResponse, //void  (*CallBackFun)(int skt);
    NULL
};

TCP_SERVER TcpServer[]={
    {
        502,        /* port */
        -1,         /* socket */
        0,          /* state */
        0,          /* connect */
        Port502     /* CallBackFun */
    },
    {
        9999,       /* port */
        -1,         /* socket */
        0,          /* state */
        0,          /* connect */
        Port9999    /* CallBackFun */
    },    
    {
        10000,      /* port */
        -1,         /* socket */
        0,          /* state */
        0,          /* connect */
        Port10000   /* CallBackFun */
    }
};

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

void XS_UserInit(int argc, char *argv[])
{
    extern int bAcceptBroadcast;
    extern unsigned long ACKDELAY;  /* vaariable in tcp.c */
    
    void UserLoop(void);
    
    int iRet;
    unsigned char IP_Address[4];
    char version[20];

    InitLib();
    
    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, Library Date is %s\r\n",GetTcpipLibVer(),version);
    
    GetIp(IP_Address);
    Print("IP=%d.%d.%d.%d\r\n",IP_Address[0],IP_Address[1],IP_Address[2],IP_Address[3]);

    XS_AddSystemLoopFun(UserLoop);  //Add a function to Xserver light's system loop.
    XS_AddServer(&TcpServer[0]);    //Add 1st server port (502)
    XS_AddServer(&TcpServer[1]);    //Add 2nd server port (9999)
    XS_AddServer(&TcpServer[2]);    //Add 3rd server port (10000)
    
    XS_AddClient(&TcpClient); //Add a client
    
    XS_StartSocket();
    /*****************************************************/
    /*  Move your code from UserInit of user.c to here.  */
    /*****************************************************/
}


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

char buf[BUFSIZE],SendBack[BUFSIZE+2];
void do_GetResponse( int skt)
{ 
    int i, cc, err, Sendlen;

    err = cc = readsocket( skt, buf, sizeof(buf)-1);
    if (err <= 0) {              /* error or disconnected by remote side */
        XS_CloseSocket(skt);
    }
    else {
        for( i=0; i < cc; i++ ) {
            Putch(buf[i]);
            if(buf[i]=='\r') Putch('\n');
        }
    }
}

void UserLoop(void)
{
    /*****************************************************/
    /*  Move your code from UserLoop of user.c to here.  */
    /*****************************************************/
}

char far sInputBuffer_P502[32767];
void Port502(int SocketNumber, int Connected)
{
    /* 
    Function Port502 is used to transfer following 2 functions
        1. Port502Start
        2. VcomCmdModbus 
    of Xserver library version 3.x.xx to X-server light version.
    */
    
    int iByte;
    
    TCPREADDATA pTCP_Data_Pointer;
    
    if(Connected==0) //First time connected from remote clients.
    {
        Port502Start(SocketNumber);
    }  
    else
    {
        iByte=readsocket(SocketNumber, sInputBuffer_P502, sizeof(sInputBuffer_P502)-1);
        if(iByte>0)
        {
            pTCP_Data_Pointer.Socket=SocketNumber;
            pTCP_Data_Pointer.ReadUartChar=sInputBuffer_P502;
            pTCP_Data_Pointer.Length=iByte;
            
            VcomCmdModbus(&pTCP_Data_Pointer);
        }
        else    //Disconnect from remote client.
            XS_CloseSocket(SocketNumber);
    }
}

char far sInputBuffer_P9999[1460];
void Port9999(int SocketNumber, int Connected)
{
    /* 
    Function Port9999 is used to transfer transfer following 2 functions
        1. Port9999Start
        2. VcomCmd7000 
    of Xserver library version 3.x.xx to X-server light version.
    */
    
    int iByte;
    
    TCPREADDATA pTCP_Data_Pointer;
    
    if(Connected==0) //First time connected from remote clients.
    {
        Port9999Start(SocketNumber);
    }  
    else
    {
        iByte=readsocket(SocketNumber, sInputBuffer_P9999, sizeof(sInputBuffer_P9999)-1);
        if(iByte>0)
        {
            pTCP_Data_Pointer.Socket=SocketNumber;
            pTCP_Data_Pointer.ReadUartChar=sInputBuffer_P9999;
            pTCP_Data_Pointer.Length=iByte;
            
            VcomCmd7000(&pTCP_Data_Pointer);
        }
        else    //Disconnect from remote client.
            XS_CloseSocket(SocketNumber);
    }
}

char far sInputBuffer_P10000[32767], sOutputBuffer_P10000[32767];
void Port10000(int SocketNumber, int Connected)
{
    /* 
    Function Port10000 is used to transfer following 3 functions 
        1. PortUserStart
        2. UserCmd
        3. VcomUserBinaryCmd 
    of Xserver library version 3.x.xx to X-server light version.
    */
    
    int iByte;
    
    TCPREADDATA pTCP_Data_Pointer;
    
    if(Connected==0) //First time connected from remote clients.
    {
        PortUserStart(SocketNumber);
    }  
    else
    {
        iByte=readsocket(SocketNumber, sInputBuffer_P10000, sizeof(sInputBuffer_P10000)-1);
        if(iByte>0)
        {
            //For user's command "19"
            if(sInputBuffer_P10000[0]=='1' && sInputBuffer_P10000[1]=='9')
            {   sInputBuffer_P10000[iByte]=0; //Add zero end to the string.
                UserCmd(sInputBuffer_P10000+2,sOutputBuffer_P10000);
                XS_WriteSocket(SocketNumber,sOutputBuffer_P10000,strlen(sOutputBuffer_P10000)); 
            }
            
            //For user's command "23"
            else if (sInputBuffer_P10000[0]=='2' && sInputBuffer_P10000[1]=='3')
            {
                pTCP_Data_Pointer.Socket=SocketNumber;
                pTCP_Data_Pointer.ReadUartChar=sInputBuffer_P10000;
                pTCP_Data_Pointer.Length=iByte;
                VcomUserBinaryCmd(&pTCP_Data_Pointer);
            }
            else
                XS_WriteSocket(SocketNumber,"Unknown command!",16); //return 16 bytes.
        }
        else    //Disconnect from remote clients.
            XS_CloseSocket(SocketNumber);
    }
}

/**************************************************************/
/*  Functions used in Xserver version 3.x.xx                  */
/*                                                            */
/*  Please move your code from user.c, v7000.c and vModbus.c  */
/*  to following functions.                                   */
/**************************************************************/
void Port502Start(int SocketNumber) //Port 502, connected event.
{
    Print("Port 502 is connected.");
    Print("Socket number is %d\n\r\n\r",SocketNumber);  
}

int VcomCmdModbus(TCPREADDATA* p)   //Port 502
{
    int i;
    Print("COMPort=%d\n\r",p->Comport);
    Print("Socket=%d\n\r",p->Socket);
    Print("Length=%d\n\r",p->Length);
    Print("Data:\n\r");
    for(i=0;i<p->Length;i++)
        Print("%c[%02X] ",p->ReadUartChar[i],p->ReadUartChar[i]);
    
    //Echos data to the client.
    //VcomSendSocket(p->Socket,p->ReadUartChar,p->Length);  //For Xserver 3.x.xx
    XS_WriteSocket(p->Socket,p->ReadUartChar,p->Length);    //For Xserver light
    return 0;
}  


void Port9999Start(int SocketNumber)    //Port 9999, connected event.
{
    Print("Port 9999 is connected.");
    Print("Socket number is %d\n\r\n\r",SocketNumber);  
}  

int VcomCmd7000(TCPREADDATA *p) //Port 9999
{
    //Echos data to the client.
    //VcomSendSocket(p->Socket,p->ReadUartChar,p->Length);  //For Xserver 3.x.xx
    XS_WriteSocket(p->Socket,p->ReadUartChar,p->Length);    //For Xserver light
    return 0;   /* any value will be accepable */
}      

void PortUserStart(int SocketNumber)    //Port 10000, connected event.
{
    Print("Port 10000 is connected.\n\r");
    Print("Socket number is %d\n\r\n\r",SocketNumber);
}   


int UserCmd(unsigned char *Cmd,unsigned char *Response) //Port 10000, user cmd "19" 
{
    sprintf(Response,"Command 19=%s",Cmd);
    return 0;   /* any value will be accepable */
}    
    
    
int VcomUserBinaryCmd(TCPREADDATA *p) //Port 10000, user cmd "23"
{    
    // return 24 bytes.
    //VcomSendSocket(p->Socket,"User-defined command(23)",24);  //For Xserver 3.x.xx    
    XS_WriteSocket(p->Socket,"User-defined command(23)",24);    //For Xserver light
    return 0;   /* any value will be accepable */
}      
