#include <string.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <8400lib.h>
#include <8xTcpip.h>
#include <ucos.h>

char bufc[2000], send_bufc[128],bufs[2000], send_bufs[128];

static const int beep[] = {15, 5, 0, 0};

void server_open_task(void *par);
void client_open_task(void *par);
OS_STACK net_open_stk[1024];
long cntc,cnts;

// Modify Here to Change Connection Properties
const long ServerIP[4]={192,168,6,5};
const int ServerPort = 1024;
const int MyPort=3000;


void client_open_task(void *par)
{
 int i, len,x,y;
 SOCKET sc;
 struct sockaddr_in sockC;

 client_re_connect_loop:
 OS_ENTER_CRITICAL();
 wherexy(&x,&y);
 clr_scr();
 gotoxy(0,1);printf("Server IP=      ");
 gotoxy(0,3);printf("%ld.%ld.%ld.%ld",ServerIP[0],ServerIP[1],ServerIP[2],ServerIP[3]);
 gotoxy(0,5);printf("ServerPort=%d",ServerPort);
 gotoxy(0,9);printf("Press Any Key");
 while(!getchar());
 gotoxy(x,y);
 OS_EXIT_CRITICAL();

 while (1) {

    while(1) {
        sc = socket(PF_INET,SOCK_STREAM,0);
        if (sc>=0) break;
        OSTimeDly(4);
    }

    memset(&sockC,0,sizeof(sockC));
    sockC.sin_family = AF_INET;
    //try to link to 192.168.2.178//
    sockC.sin_addr.s_addr = (ServerIP[0]) | (ServerIP[1]<<8) | (ServerIP[2]<<16) | (ServerIP[3]<<24);
    //port number =5000//
    sockC.sin_port = htons(ServerPort);
    if (connect(sc,(struct sockaddr *)&sockC,sizeof(sockC)) >= 0) break;
    socket_noblock(sc);
    shutdown(sc,2);
    closesocket(sc);
    OSTimeDly(200);
 }
 socket_block(sc);
 socket_keepalive(sc, 20000UL);

 OS_ENTER_CRITICAL();
 wherexy(&x,&y);
 gotoxy(0,7);clr_eol();printf("Sending %ld",cntc);
 gotoxy(0,9);clr_eol();printf("Recv OK %ld",cntc);
 gotoxy(x,y);
 OS_EXIT_CRITICAL();

 send(sc,send_bufc,sizeof(send_bufc),0);
 i=0;
 while(1) {

	    if (socket_testfin(sc) || !socket_isopen(sc) || (socket_rxstat(sc) & S_RST)) {
		socket_noblock(sc);
        shutdown(sc,2);
        closesocket(sc);
        goto client_re_connect_loop; 
     }

	 if(socket_hasdata(sc)) {
           len = recv(sc,bufc+i,sizeof(bufc)-i,0);
	       i += len;
	       if (i > sizeof(send_bufc)) {
		     i = 0;
		     continue;
	       }
	      if (bufc[i-1] != 0x0d) continue;
          OS_ENTER_CRITICAL();
          wherexy(&x,&y);
	      if (i == sizeof(send_bufc) && (!strncmp(bufc,send_bufc,sizeof(send_bufc)))) {
             gotoxy(0,9);clr_eol();printf("Recv OK %ld",cntc);
		     cntc++;
		     sprintf(send_bufc,"%06ld",cntc);
		     send_bufc[6] = ':';
             gotoxy(0,7);clr_eol();printf("Sending %ld",cntc);
		     send(sc,send_bufc,sizeof(send_bufc),0);
		     i = 0;
          }
	      else {
             gotoxy(0,11);clr_eol();printf("Recv Fail !!!");
	      }
          gotoxy(x,y);
          OS_EXIT_CRITICAL();
     }
     OSTimeDly(10);
 }
}

void server_open_task(void *par)
{
 int i, len,x,y;
 SOCKET s1,ss;
 struct sockaddr_in sockS;
 unsigned char IP[4];

 //create server connection
 s1 = socket(PF_INET,SOCK_STREAM,0);
 memset(&sockS,0,sizeof(sockS));
 sockS.sin_family = AF_INET;
 sockS.sin_port = htons(MyPort);
 bind(s1,(struct sockaddr *)&sockS,sizeof(sockS));
 listen(s1,2);

 server_re_connect_loop:
 GetNetParameter((void*)IP,P_LOCAL_IP);

 OS_ENTER_CRITICAL();
 wherexy(&x,&y);
 clr_scr();
 gotoxy(0,1);printf("MyIP=           ");
 gotoxy(0,3);printf("%d.%d.%d.%d",IP[0],IP[1],IP[2],IP[3]);
 gotoxy(0,5);printf("MyPort=%d",MyPort);
 gotoxy(x,y);
 OS_EXIT_CRITICAL();

 len=sizeof(sockS);
 socket_noblock(s1);
 while((ss=accept(s1,(struct sockaddr *)&sockS,&len))<0) OSTimeDly(4);
 socket_block(s1);
 socket_keepalive(ss, 20000UL);

 OS_ENTER_CRITICAL();
 wherexy(&x,&y);
 gotoxy(0,7);clr_eol();printf("Sending %ld",cnts);
 gotoxy(0,9);clr_eol();printf("Recv OK %ld",cnts);
 gotoxy(x,y);
 OS_EXIT_CRITICAL();

 send(ss,send_bufs,sizeof(send_bufs),0);

 i=0;
 while(1) {

	    if (socket_testfin(ss) || !socket_isopen(ss) || (socket_rxstat(ss) & S_RST)) {
		socket_noblock(ss);
        shutdown(ss,2);
        closesocket(ss);
        goto server_re_connect_loop; 
     }

	 if(socket_hasdata(ss)) {
           len = recv(ss,bufs+i,sizeof(bufs)-i,0);
	       i += len;
	       if (i > sizeof(send_bufs)) {
		     i = 0;
		     continue;
	      }
	      if (bufs[i-1] != 0x0d) continue;
          OS_ENTER_CRITICAL();
          wherexy(&x,&y);
	      if (i == sizeof(send_bufs) && (!strncmp(bufs,send_bufs,sizeof(send_bufs)))) {
             gotoxy(0,9);clr_eol();printf("Recv OK %ld",cnts);
		     cnts++;
		     sprintf(send_bufs,"%06ld",cnts);
		     send_bufs[6] = ':';
             gotoxy(0,7);clr_eol();printf("Sending %ld",cnts);
		     send(ss,send_bufs,sizeof(send_bufs),0);
		     i = 0;
          }
	      else {
             gotoxy(0,11);clr_eol();printf("Recv Fail !!!");
	      }
          gotoxy(x,y);
          OS_EXIT_CRITICAL();
     }
     OSTimeDly(10);
 }
}

//***********************************************************************
long mon_ms;
void netstat(void)
{
    int i,ii[3];

    if (sys_msec - mon_ms > 100) {
        gotoxy(0, 13);
        printf("Q:%04d", CheckNetStatus(WLAN_Quality));

        mon_ms = sys_msec;
    }
}
//***********************************************************************
void main(void)
{
	int i ;
    unsigned char local_ip[4];
    char c;

    OSTaskDel(10);
    //SetCommType(1, COMM_DIRECT);
    //open_com(1,BAUD_115200|DATA_BIT8|PARITY_NONE|HANDSHAKE_NONE);
    SetFont(FONT_8X16);
    cnts=cntc=0;

RE_INIT:	
    clr_scr();
                      //12345678901234567890  
    gotoxy(0,1);printf("   WLAN Echo Test   ");
    gotoxy(0,3);printf("====================");
    gotoxy(0,5);printf("        Wait        ");
    gotoxy(0,7);printf("    Connecting....  ");
    gotoxy(0,9);printf("====================");
	
	if(NetInit(0L)<0)
    {
        clr_scr();
        printf("Network initialization Fail.");
        while(!getchar())  OSTimeDly(10);
        goto RE_INIT;
    }

    while(1) 
    {
        if (CheckNetStatus(NET_IPReady)) break;
        OSTimeDly(4);
    }
    
	//create data buffer
	for (i=7;i<sizeof(send_bufc)-1;i++) send_bufs[i]=send_bufc[i] = (i | 0x20) & 0x7f;
	send_bufc[i]=send_bufs[i] = 0x0d;
	memset(send_bufc,'0',6);
	memset(send_bufs,'0',6);
	send_bufs[6] = send_bufc[6] = ':';

    //
    GetNetParameter((void*)local_ip, P_LOCAL_IP);
    on_beeper(beep);
    while(beeper_status());
    clr_scr();
                         //12345678901234567890  
    //gotoxy(0, 1);  printf("My IP=");
    //gotoxy(0, 3);  printf("%d.%d.%d.%d", local_ip[0], local_ip[1], local_ip[2], local_ip[3]);
    //gotoxy(0, 5);  printf("My Port= %d", ECHO_PORT);
    gotoxy(0, 1);  printf("Select Test Mode:");
    gotoxy(0, 5);  printf("[1]Client Mode");
    gotoxy(0, 7);  printf("[2]Server Mode");
    
    while(1)
    {
        c=getchar();
        switch(c)
        {
            case '1':
                     OSTaskCreate(client_open_task, (void*)0,net_open_stk, 1024, 10);
                     goto OPENED;
            case '2':
                     OSTaskCreate(server_open_task, (void*)0,net_open_stk, 1024, 10);
                     goto OPENED;
            case KEY_ESC:
                     NetClose();
                     goto RE_INIT;
            default:
                     break;
        }
    }
    
OPENED:
    clr_scr();
    mon_ms = sys_msec;
    InitScanner1();
	while (1) 
	{
        netstat();
        if(Decode()) 
        {
            on_beeper(KEY_CLICK);
            gotoxy(0,3);
            CodeBuf[40] = 0;
            printf("%s",CodeBuf);
        }
        if((c=getchar())==KEY_ESC)
        {
            OSTaskDel(10);
            NetClose();
            goto RE_INIT;
        } 
        OSTimeDly(10);
    }
}
