/*******************************************************************************
        pingled.c
        Z-World, 2000

        ICMP demonstration, by pinging a remote host.

        This sample program is an adaptation of samples/tcpip/ping.c.  It
        has been modified for the RCM2100 to flash LEDs on the prototyping
        board.  It flashes DS2 when it sends a ping and flashes DS3 when
        it receives a ping response.

        To use this program modify the MY_IP_ADDRESS, MY_NETMASK, MY_GATEWAY,
        and MY_NAMESERVER to the appropriate settings for the network.  Then
        change PING_WHO to the host you want to ping.  The MY_NAMESERVER
        define is only necessary when you are specifing PING_WHO by name
        instead of by IP address.

        You can modify the PING_DELAY define to change the amount of time
        in milliseconds between the outgoing pings.

        If you would like to see the incoming ping replies, uncomment the
        VERBOSE define.
*******************************************************************************/

#define MY_IP_ADDRESS 	"10.10.6.101"
#define MY_NETMASK		"255.255.255.0"
#define MY_GATEWAY		"10.10.6.1"
#define MY_NAMESERVER	"10.10.6.1"

//#define VERBOSE

#define PING_WHO			"10.10.6.1"
#define PING_DELAY		500

#memmap xmem
#use "dcrtcp.lib"

/*******************************************************************************
		Routines to change the LEDs.  The DS2, DS3, DS4, and DS5 LEDs are
		on the least significant bits of the A register.  The pingleds_setup
		routine turns off DS2-5.  The pingoutled routine turns DS3 on when what
		is nonzero and off when it is zero.  Similarly, the pinginled routine
		toggles DS4.
*******************************************************************************/

#define LEDON	1
#define LEDOFF	0

int ledstatus;

pingleds_setup()
{

	WrPortI(SPCR, NULL, 0x84);  // Set Port A to Output

	ledstatus=0x0f;
	WrPortI(PADR,NULL,ledstatus);

}

pingoutled(int what)
{
	if(what==LEDON)
		ledstatus&=0xfe;
	else
		ledstatus|=0x01;

	WrPortI(PADR,NULL,ledstatus);
}

pinginled(int what)
{
	if(what==LEDON)
		ledstatus&=0xfd;
	else
		ledstatus|=0x02;

	WrPortI(PADR,NULL,ledstatus);
}


main()
{
	longword seq,ping_who,tmp_seq,time_out;

	seq=0;

	pingleds_setup();
	
	sock_init();
	
	/*
	 *		Get the binary ip address for the target of our 
	 *		pinging.
	 */
	
	ping_who=resolve(PING_WHO);
	if(ping_who==0) {
		printf("unable to resolve %s",PING_WHO);
		return 1;
	}
	
	for(;;) {
		/*
		 *		It is important to call tcp_tick here because
		 *		ping packets will not get processed otherwise.
		 *
		 */

		tcp_tick(NULL);
		
		/*
		 *		Send one ping every PING_DELAY ms.
		 */
		
		costate {
			waitfor(DelayMs(PING_DELAY));
			_ping(ping_who,seq++);
			pingoutled(LEDON);					// flash the DS3 LED
			waitfor(DelayMs(50));
			pingoutled(LEDOFF);
		}
		
		/*
		 *		Has a ping come in?  time_out!=0xfffffff->yes.
		 */

		costate {
			time_out=_chk_ping(ping_who,&tmp_seq);
			if(time_out!=0xffffffff) {

#ifdef VERBOSE			
				printf("received ping:  %ld\n", tmp_seq);
#endif

				pinginled(LEDON);					// flash the DS4 LED
				waitfor(DelayMs(50));
				pinginled(LEDOFF);
			}
		}
	}
}