/********************************************************************
	tcp_respond.c
	Z-World, 2000
	
 	This sample program is used with Intellicom Series.
 	
	This program and tcp_send.c are to be executed on two different
	Intellicom boards so that the two boards communicate with each
	other.  A TCP socket is used to send a very reliable datagram.

	In the absence of a second board, pcsend.exe can be used on
	the PC console side at the command prompt.  This executable and
	source code is located in \samples\icom\windows directory.

	If you use telnet to connect (ie "telnet 10.10.6.100 4040"),
	this code will disconnect after sending each response.  Simply
	re-connect (run telnet again) to get the next response.

	This program waits for a message from another machine.  The message
	received is displayed on the LCD, and the user is allowed to respond
	by pressing a key on the keypad.  The response is then sent to the
	remote machine.
	
********************************************************************/

/***********************************
 * Configuration                   *
 * -------------                   *
 * All fields in this section must *
 * be altered to match your local  *
 * network settings.               *
 ***********************************/

/*
 * You must change the following values to whatever
 * your local IP address and netmask are. Contact your
 * network administrator for these numbers.
 */
#define MY_IP_ADDRESS	"10.10.6.100"
#define MY_NETMASK		"255.255.255.0"
#define MY_GATEWAY		"10.10.6.1"

// Port to listen on
#define PORT				4040

/********************************
 * End of configuration section *
 ********************************/

#memmap xmem
#use "dcrtcp.lib"

#define IGNORE 99

/*
 * Receive a message.  The socket is re-opened and message read.  The need
 * for a response is indicated.  tcp_tick() fails if peer closed socket.
 */
void RecvMessage(tcp_Socket* tcpSock, int* respond)
{
	auto char buffer[500];
	auto int numBytes;

	tcp_listen(tcpSock, PORT, 0, 0, NULL, 0);
	dispClear();

	/* Wait for connection. */
	while( ! tcp_established( tcpSock ) ) {
		if( ! tcp_tick( (sock_type *) tcpSock ) ) {
			dispPrintf( "ERROR: listening: %s\n", tcpSock->err_msg );
			exit( 99 );
		}
	}

	/*  Wait for some data to appear, or an error... */
	while( 0 == (numBytes = sock_fastread(tcpSock, buffer, sizeof(buffer))) ) {
		if( ! tcp_tick( tcpSock ) ) {
	bad_read:
			dispPrintf( "ERROR: read: %s\n", tcpSock->err_msg );
			exit( 99 );
		}
	}
	if (numBytes == -1) {
		goto bad_read;
	}

	buffer[numBytes] = '\0';
	dispPrintf("%s", buffer);
	*respond = 1;	// Indicate the need for a response

}   /* end RecvMessage() */

/*
 * Send the response to the remote machine.  Close the socket.
 */
void SendMessage(tcp_Socket *tcpSock, unsigned key, char* messages[])
{
	auto char * p;
	auto int 	len;

	/* Use sock_fastwrite() here to encourage good programming practices. */

	sock_write(tcpSock, messages[key-1], strlen(messages[key-1])+1);
	sock_close(tcpSock);
	while (tcp_tick(tcpSock) != 0);
	dispClear();
	dispPrintf("Response sent");
	return;
}
	
void main(void)
{
	char* messages[12];
	int i;
	unsigned key;    // User keypress
	tcp_Socket tcpSock;
	int respond;

	respond = 0;
	
	// Initialize the message array
	for (i = 0; i < 12; i++) {
		messages[i] = "";
	}

	// Define messages here--note that you only need define the messages
	// you will actually use.
	messages[0] = "I hear ya";
	messages[1] = "Hello, there";
	messages[2] = "I'm here";
	messages[3] = "This Rabbit is fast!";

	brdInit();
	sock_init();

	// Configure the upper row of keys on the keypad, in order from left
	// to right
	for (i = 0; i < 6; i++) {
		// Only enable a key if there is a corresponding message
		if (strcmp(messages[i], "") != 0) {
			keyConfig ( 5-i, i+1, 0, 0, 0, 0, 0 );
		} else {
			keyConfig ( 5-i, IGNORE, 0, 0, 0, 0, 0 );
		}
	}
	// Configure the lower row of keys on the keypad, in order from left
	// to right
	for (i = 6; i < 12; i++) {
		// Only enable a key if there is a corresponding message
		if (strcmp(messages[i], "") != 0) {
			keyConfig ( 19-i, i+1, 0, 0, 0, 0, 0 );
		} else {
			keyConfig ( 19-i, IGNORE, 0, 0, 0, 0, 0 );
		}
	}

	while (1) {
		costate {								//	Process Keypad Press/Hold/Release
			keyProcess ();
			waitfor ( DelayMs(10) );
		}
			
		costate {								//	Process Keypad Press/Hold/Release
			waitfor ( key = keyGet() );	//	Wait for Keypress
			// Only handle the keypress if it corresponds to a message and if
			// a response is currently needed
			if ((key != IGNORE) && (respond == 1)) {
				SendMessage(&tcpSock, key, messages);
				respond = 0;
			}
		}

		// Receive a message.  RecvMessage() will block until something comes in.
		if (respond == 0) {
			RecvMessage(&tcpSock, &respond);
		}
	}
}
