/*
XS_MB.c: Test COM PORT structure

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

Hardware: uPAC-7186EX
          COM1 (TXD1 must be connected to RXD1 during the program running)
    
[Jan 24, 2008] by Jency
*/

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

void UPort10000( int skt , int mode);
void CallBackCom1(pCOMPORT com, int mode);
#define BUFSIZE 1460        /* read/write buffer size */

#define NO_RESPONSE     -10
#define READ_TIMEOUT    -20
#define OVER_TRIGGER    -30
#define OVER_BUFFER     -50
#define READ_ERROR      -99
#define OUTPUT_SUCC       0

//============================//
//          TCP Server        //    
//============================//
TCP_SERVER TcpServer={
    10000,      // port
    -1,         // socket
    0,          // state
    0,          // connect
    UPort10000  // CallBackFun
};

//============================//
//          COM port          //    
//============================//
#define BUF1_SIZE 70
char Buf1[BUF1_SIZE]; 
COMPORT MyCom1={
    2,              //int Port; // 0:COM0, 1:COM1,...
    Buf1,           //char *Buf;
    BUF1_SIZE,      //unsigned Bufsize;
    0,              //char EndChar; 
    40,             //unsigned TriggerLevel;
    20,             //long Timeout;
    0,              //long StartTimeTicks;
    0,              //long LastTimeTicks;
    0,              //long MasterTimeout;
    0,              //long MasterStartTimeTicks; 
    0,              //unsigned Size; 
    ReadComn_1,     //int (*ReadComn)(unsigned char *buf,int n);         //defined in 7188E.H
    CallBackCom1,   //void (*CallbackFun)(pCOMPORT, int mode);
    0,              //pCOMPORT next;
};

char *GetModuleName(void)   /* User's program must support this function for UDP search */ 
{
    return "uPAC-7186E-XS" ;
}

char *GetAliasName(void)    /* User's program must support this function for UDP search */ 
{
    return "COMPORT" ;
}

//============================//
//        Init & End          //    
//============================//

void PrintTitle(int skt)
{
/*  printCom(iCom,"Test COM PORT\r\n\r\n");
  printCom(iCom,"1)Received by End character (%c)\r\n",MyCom1.EndChar);
  printCom(iCom,"2)Received by Trigger level (%u)\r\n",MyCom1.TriggerLevel);
  printCom(iCom,"3)'timeout' happened (%ld)\r\n",MyCom1.Timeout);
  printCom(iCom,"4)'Master Timeout' happened (%ld)\r\n",MyCom1.MasterTimeout);
  printCom(iCom,"5)'Buffer full' happened (%u)\r\n\r\n",MyCom1.Bufsize);
  printCom(iCom,"Q)Press Escape key to quit the Demo\r\n\r\n");*/
    TcpPrint(skt,0,"Test COM PORT\r\n\r\n");
    TcpPrint(skt,0,"1)Received by End character\r\n");
    TcpPrint(skt,0,"2)Received by Trigger level (%u)\r\n", MyCom1.TriggerLevel);
    TcpPrint(skt,0,"3)Test 'timeout' happened (%ld)\r\n", MyCom1.Timeout);
    TcpPrint(skt,0,"4)Test 'Master Timeout' happened (%ld)\r\n", MyCom1.MasterTimeout);
    TcpPrint(skt,0,"5)Test 'Buffer full' happened (%u)\r\n\r\n", MyCom1.Bufsize);
    TcpPrint(skt,1,"Q)Press 'q' or 'Q' key to quit the Demo\r\n\r\n");  
}

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

    InitLib();
    InstallCom_1(115200, 8, 0, 1);
    InstallCom_2(115200, 8, 0, 1);   
    
    bAcceptBroadcast=0;
    ACKDELAY=200;
    XS_GetVersion(version);
    printCom1("[X-Server library]: version=%s ",version);
    XS_GetLibDate(version);
    printCom1("date=%s\r\n",version);
    GetTcpipLibDate(version);
    printCom1("Tcpip library version:%X, Library Date is %s\r\n",GetTcpipLibVer(),version);
    GetIp(MyIp);
    printCom1("IP=%d.%d.%d.%d\r\n", MyIp[0], MyIp[1], MyIp[2], MyIp[3]);

    XS_AddComPort(&MyCom1); 

    XS_AddSystemLoopFun(UserLoop);

    XS_AddServer(&TcpServer);

    XS_AddUdpSocket(&XS_UdpSearch);
    bAcceptBroadcast=1;     // allow to receive the UDP broadcast

    EnableWDT();
    MAXTXTOUT=6000UL; 

    XS_AddSystemLoopFun(XS_SocketLoopFun);
    XS_StartSocket();   
}

void XS_UserEnd(void)
{
    XS_StopSocket();
    DisableWDT();
    XS_RemoveComPort(&MyCom1);
    RestoreCom_2();
    RestoreCom_1();
}

//============================//
//          User Loop         //    
//============================//

int Socket0=-1; 
extern int errno;

void UserLoop(void)
{   
    long tmpt;
    int i, err;    

    RefreshWDT();   

/*  if(IsCom(2))
    {
        key=ReadCom(2);
        switch(key)
        {
            case 27:
                QuitMain=1;
                break;
        }
    }*/

#if 1
    Show5DigitLedSeg(1,103);//--->'P'
    Show5DigitLedSeg(2,119);//--->'R'
    Show5DigitLedSeg(3,126);//--->'O'
    Show5DigitLedSeg(4,95);//--->'G'
    Show5DigitLedSeg(5,119);//--->'R'
#endif
}//void UserLoop(void)


//============================//
//       TCP call back  fun   //    
//============================//
char buf[BUFSIZE], SendBack[BUFSIZE+2];

void UPort10000(int skt, int mode)
{ 
    int i, cc, err, Sendlen;
    
    if(!mode)
    {
            Socket0=skt;
            Sendlen=sprintf(SendBack,"Welcome connect to port %u\r\nThere are %d clients connect to this port\r\n",
                    TcpServer.port,TcpServer.connect);
            err= XS_WriteSocket(skt,SendBack,Sendlen);
            PrintTitle(skt);            
    }//if(!mode)
    else 
    {
        err = readsocket( skt, buf, sizeof(buf)-1);
        if (err <= 0) 
        {              /* error or disconnected by remote side */
            XS_CloseSocket(skt);
        }//if (err <= 0) 
        else 
        {
          if(buf[0]=='q' || buf[0]=='Q')
            QuitMain=1;
      else
      {
        cc=ascii_to_hex(buf[0]);    
            switch(cc)
            {
              case 1:
                MyCom1.TriggerLevel=0;
                MyCom1.EndChar='\r';
                printCom(1,"Test1\n\r");
              break;
              case 2:
                MyCom1.TriggerLevel=40;
                MyCom1.EndChar=0;
                ToComBufn_1("1234567890123456789012345678901234567890",40);
              break;
              case 3:
                MyCom1.EndChar='\r';
                ToCom(1,'a');
              break;
              case 4:
                MyCom1.MasterTimeout=100;
                MyCom1.MasterStartTimeTicks=GetTimeTicks();
              break;
              case 5:
                MyCom1.TriggerLevel=0;
                MyCom1.EndChar=0;
                for(i=0;i<(BUF1_SIZE+2);i++)
                  ToCom(1,(i+0x41)%26); 
              break;
        }
      }
        }//else(err <= 0)
    }//else(!mode)          
}

//============================//
//     Callback function      //    
//============================//
void CallBackCom1(pCOMPORT com, int mode)   
{ 
    int i, key;
    unsigned long ReBack_value;
   
    switch(mode)
    {
        case 0: // 超過 Timeout 時間沒再收到字元 
            TcpPrint(Socket0, 1, "'Timeout' happened !!\r\n");          
            break;
        case 1: // 收到 EndChar     
            TcpPrint(Socket0, 1, "Receives EndChar, %s\r\n", com->Buf);
            break; 
        case 2: // 收到字元個數到達 TriggerLevel 
            TcpPrint(Socket0, 1, "Receives the data, %s (data count is same with TriggerLevel, %u)\r\n", com->Buf,com->TriggerLevel);
            break; 
        case 3: // buffer 已經滿了 
            TcpPrint(Socket0, 1, "Buffer is full %u\r\n", com->Bufsize);
            break; 
        case 4: // 超過Mastertimeout沒有回應
            TcpPrint(Socket0, 1, "Mastertimeout!!\r\n");
            break;
        default:
//          printCom1("[Error mode %d]\n\r",mode);
            break;  
    }//switch(mode)

    com->Size=0;
}

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