#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};
struct NETCONFIG NetConfig;
void server_open_task(void *par);
void client_open_task(void *par);
OS_STACK server_open_stk[1024];
OS_STACK client_open_stk[1024];
long cntc,cnts;

// Modify Here to Change Connection Properties
const long ServerIP[4]={61,247,173,251};
const int ServerPort = 20009;
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);
 gotoxy(0,3);printf("Server IP=      ");
 gotoxy(0,4);printf("%ld.%ld.%ld.%ld",ServerIP[0],ServerIP[1],ServerIP[2],ServerIP[3]);
 gotoxy(0,5);printf("ServerPort=%d",ServerPort);
 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,3);printf("I am Client OK!!");
 gotoxy(0,4);clr_eol();printf("Sending %ld",cntc);
 gotoxy(0,5);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_FATAL)) {
		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,5);clr_eol();printf("Recv OK %ld",cntc);
		     cntc++;
		     sprintf(send_bufc,"%06ld",cntc);
		     send_bufc[6] = ':';
             gotoxy(0,4);clr_eol();printf("Sending %ld",cntc);
		     send(sc,send_bufc,sizeof(send_bufc),0);
		     i = 0;
          }
	      else {
             gotoxy(0,5);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;

 //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:

 OS_ENTER_CRITICAL();
 wherexy(&x,&y);
 gotoxy(0,0);printf("MyIP=           ");
 gotoxy(0,1);printf("%d.%d.%d.%d", NetConfig.IpAddr[0],NetConfig.IpAddr[1],NetConfig.IpAddr[2],NetConfig.IpAddr[3]);
 gotoxy(0,2);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,0);printf("I am Server OK!!");
 gotoxy(0,1);clr_eol();printf("Sending %ld",cnts);
 gotoxy(0,2);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_FATAL)) {
		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,2);clr_eol();printf("Recv OK %ld",cnts);
		     cnts++;
		     sprintf(send_bufs,"%06ld",cnts);
		     send_bufs[6] = ':';
             gotoxy(0,1);clr_eol();printf("Sending %ld",cnts);
		     send(ss,send_bufs,sizeof(send_bufs),0);
		     i = 0;
          }
	      else {
             gotoxy(0,2);clr_eol();printf("Recv Fail !!!");
	      }
          gotoxy(x,y);
          OS_EXIT_CRITICAL();
     }
     OSTimeDly(10);
 }
}

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

    if (sys_msec - mon_ms > 100) {
        //GetNetStatus((void*)&Net);
        gotoxy(0,7);
        printf("Q:%04d", CheckNetStatus(WLAN_Signal));
        mon_ms = sys_msec;
    }
}
//***********************************************************************
void main(void)
{
	int i ;
    struct NETSTATUS S;


    cnts=cntc=0;

	NetInit(5L);
    clr_scr();
                      //1234567890123456  
    gotoxy(0,0);printf("   Echo  Test   ");
    gotoxy(0,1);printf("================");
    gotoxy(0,2);printf("      Wait      ");
    gotoxy(0,3);printf(" Connecting.... ");
    gotoxy(0,4);printf("================");
    while(1) {
        if(CheckNetStatus(NET_IPReady))  break;
        //GetNetStatus((void*)&S);
        //if (S.IPReady) break;
        OSTimeDly(4);
    }

    on_beeper (beep);

    //GetNetConfig((void*)&NetConfig);
    GetNetParameter((void*)NetConfig.IpAddr, P_LOCAL_IP);
    clr_scr();

	//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] = ':';

    OSTaskCreate(server_open_task, (void*)0,server_open_stk, 1024, 11);

    //create client connection
    OSTaskCreate(client_open_task, (void*)0,client_open_stk, 1024, 10);

    mon_ms = sys_msec;
    InitScanner1();

	while (1) {
        netstat();
        if (Decode()) {
            on_beeper(KEY_CLICK);
            gotoxy(0,7);
            CodeBuf[40] = 0;
            printf("%s",CodeBuf);
        }
        OSTimeDly(10);
    }
}

//*****************************************************************************
