#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "../mcu/types.h"
#include "../mcu/serial.h"
#include "../util/util.h"
#include "../util/myprintf.h"
#include "../util/sockutil.h"
#include "../iinchip/socket.h"
#include "../inet/dns.h"
#include "../inet/ping.h"

#include "ping_app.h"

char *strupr (a) char *a;
{
  char *ret = a;

  while (*a != '\0')
    {
      if (islower (*a))
	*a = toupper (*a);
      ++a;
    }

  return ret;
}

/*
********************************************************************************
* Description: ping request to peer
* Arguments  : None.
* Returns    : None.
* Note       : 
********************************************************************************
*/
void ping_request(void)
{
	PINGLOG PingLog;			// Variable for result of pinging
	char command[81];			// Variable for command from serial terminal
	char qname[MAX_QNAME_LEN];
	char* NextTok;				// Pointer to next token string
	char PeerIp[50];			// Peer IP Address String
	u_long peerip;				// 32bit Peer IP Address
	char PingArgsFlags=0;			// If ping arguments are correct then IsValidPingArgs = 0, else -1
	u_int pingcnt;				// Count of sending ping-request to a peer
	u_int pingsize;                           // Size of ping-request's data
	u_int pingtimeout;                        // wait time for ping-reply


	memset(qname,0,sizeof(qname));
	printf("\r\nPing Reqeust program started...\r\n\r\n");
	/* Wait for command, and call ping function. Then display the result of pinging */
	ping_usage();
	while(1)
	{
		/* Initialize local variables */
		pingcnt = pingsize = pingtimeout = 0;	
		PingArgsFlags = 0;
		printf("\r\nPING> ");				// Display prompt 'PING>'
		uart_gets(0, command,0,sizeof(command));                  		// Wait for command from serial Terminal
		if(*command=='\0') continue;			// Is command empty?
		NextTok = strtok(command,"\t\r\n ");    	// Get first token from command
		NextTok = strupr(NextTok);			// Converts first token to an uppercase string.
		if(!strcmp(NextTok,"EXIT"))	break;		// If first token is equal to "EXIT" then end program
		else if(strcmp(NextTok,"PING"))     		// If first token is not equal to "PING" then enter command again
		{
			printf("Unknown Command\r\n");
			printf("You can use 'ping' or 'exit' commands\r\n");
			printf("If you want to ping request then use 'ping'.\r\n");
			printf("If you want to terminate the program, use 'exit'.\r\n");
			continue;
		}
		while( (NextTok=strtok(NULL,"\t\r\n ")) )
		{
			if(!strcmp(NextTok,"-t"))
			{
				pingcnt = -1;
				PingArgsFlags |= 0x01;
			}
			else if(!strcmp(NextTok,"-a"))
			{
				PingArgsFlags |= 0x02;
			}
			else if(!strcmp(NextTok,"-n"))
			{
				NextTok = strtok(NULL,"\t\r\n ");	// get value of '-n' option
				if(!ValidATOI(NextTok,10,&pingcnt))	// If value of '-n' option is valid
				{
					printf("Bad value for option -n, valid range is from 1 to %d.\r\n",0x7FFF);
					PingArgsFlags |= 0x80;
					break;
				}
				if(PingArgsFlags & 0x01) pingcnt = -1;
				else PingArgsFlags |= 0x04;				
			}
			else if(!strcmp(NextTok,"-l"))
			{
				
				NextTok = strtok(NULL,"\t\r\n ");	// Get value of '-l' option
				if(!ValidATOI(NextTok,10,&pingsize))	// If value of '-l' option is valid
				{
					printf("Bad value for option -l, valid range is from 1 to %d.\r\n",PINGBUF_LEN);
					PingArgsFlags |= 0x80;
					break;
				}
				PingArgsFlags |= 0x08;
			}
			else if(!strcmp(NextTok,"-w"))
			{
				NextTok = strtok(NULL,"\t\r\n ");	// Get value of '-w' option
				if(!ValidATOI(NextTok,10,&pingtimeout))	// If value of '-w' option is valid
				{
					printf("Bad value for option -w, valid range is from 1 to %d.\r\n\r\n",0x7FFF);
					PingArgsFlags |= 0x80;
					break;
				}
				PingArgsFlags |= 0x10;
			}
			else if(!strcmp(NextTok,"-h")|| !strcmp(NextTok,"-?") || !strcmp(NextTok,"/?"))
			{
				ping_usage();
				PingArgsFlags |= 0x80;
				break;
			}
////---- MODIFY_2006_01_16 : When '-' character is included in domain name token, it is a fail to parse the domain name.
//			else if(strchr(NextTok,'-'))			
////---- END_MODIFY
			else if(strchr(NextTok,'-') && strlen(NextTok)==2)
			
			{
				PingArgsFlags |= 0x80;
				printf("Bad options.\r\n");
				break;
			}
			else if(strchr(NextTok,'.'))
			{
				if(PingArgsFlags & 0x20)
				{
					printf("You can use only one destination-list\r\n");
					PingArgsFlags |= 0x80;
					break;
				}
				strcpy(qname,NextTok);
				PingArgsFlags |= 0x20;
			}
			else
			{
				PingArgsFlags |= 0x80;
				printf("Unknown option\r\n");
			}
		}
		if( PingArgsFlags == 0)				// no arguments
		{
			printf("ping command must have one more auguments\r\n");
			continue;
		}		
		if(PingArgsFlags & 0x80) continue;		// fail to parse arguments

		if(!(PingArgsFlags & 0x20))
		{
			printf("ping command have a destination-list\r\n");
			continue;
		}
		if(VerifyIPAddress(qname))			// Get the peer IP address string
		{
			strcpy(PeerIp,qname);
			peerip = inet_addr(PeerIp);
			if(PingArgsFlags & 0x02)
			{
				if(!gethostbyaddr(htonl(peerip),qname))
				{
					printf("Unknown host.\r\n");
					continue;
				}				
			}
		}
		else
		{
			peerip = ntohl(gethostbyname(qname));
			if(!peerip)
			{
				printf("Unknown host name.\r\n");
				continue;
			}
			PingArgsFlags |= 0x40;
		}
		strcpy(PeerIp,inet_ntoa(peerip));
		printf("\r\nPing Request to %s",PeerIp);
		if((PingArgsFlags & 0x42))
			printf("[%s]",qname);
//		PRINTLN("");
		if(!ping(pingcnt,pingsize,pingtimeout,PeerIp,&PingLog))		// call ping function
			printf("Fail to ping()\r\n");
		else
			DisplayPingStatistics(PingLog);                    	// Display the result of pinging
	}
	printf("Ping Test Program ended.\r\n");
}	

/*
********************************************************************************
* Description: Display usage of ping
* Arguments  : None.
* Returns    : None.
* Note       : 
********************************************************************************
*/
void ping_usage(void)
{
	printf("\r\nUsage : ping [-t] [-a] [-n count] [-l size] [-w timeout] destination-list\r\n");
	printf("\r\nOption : \r\n");
	printf("    -t            Ping the specified host until stopped.\r\n");
	printf("                  To see statistics and continue - type Control-Break;\r\n");
	printf("                  To stop - type Control-C.\r\n");
	printf("    -a            Resolve addresses to hostnames\r\n");
	printf("    -n count      Number of echo requests to send.\r\n");
	printf("    -l size       Send buffer size.\r\n\r\n");
	printf("    -w timeout    Timeout in milliseconds to wait for each reply.\r\n\r\n");	
}
