/********************************************************************
	tcp_respond.c
	Z-World, 2001
 	(Adapted from Intellicom's tcp_respond.c)

 	This sample program is used with controller boards
 	equipped with ethernet, LCD and keypad.  A 122x32 pixel
 	display and 1x7 keypad module with LED's are assumed.
 	
	This program and tcp_send.c are to be executed on two different
	controller boards so that the two boards communicate with each
	other.  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\lcd_keypad\windows directory.

	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.
	
********************************************************************/

fontInfo fi6x8;
windowFrame wholewindow;

/***********************************
 * 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.112"
#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 0x20

/*
 * Receive a message.  The connected socket and is sent back, and the need
 * for a response is indicated.
 */
void RecvMessage(tcp_Socket* tcpSock, int* respond)
{
	char buffer[2048];
	int status;
	int numBytes;

	tcp_listen(tcpSock, PORT, 0, 0, NULL, 0);
	sock_wait_established(tcpSock, 0, NULL, &status);
	sock_wait_input(tcpSock, 0, NULL, &status);
	numBytes = sock_fastread(tcpSock, buffer, 2048);
	glBlankScreen();
	if (numBytes != -1) {
		buffer[numBytes] = '\0';
		TextGotoXY(&wholewindow, 0, 0 );
		TextPrintf(&wholewindow, "%s", buffer);
		*respond = 1;	// Indicate the need for a response
	} else {
		TextGotoXY(&wholewindow, 0, 0);
		TextPrintf(&wholewindow, "Error");
	}

sock_err:
	switch(status) {
	case 1: /* foreign host closed */
		glBlankScreen();
		TextGotoXY(&wholewindow, 0, 0 );
		TextPrintf(&wholewindow, "Error");
		break;

	case -1: /* timeout */
		glBlankScreen();
		TextGotoXY(&wholewindow, 0, 0 );
		TextPrintf(&wholewindow, "Error");
		break;
	}
}

/*
 * Send the response to the remote machine
 */
void SendMessage(tcp_Socket *tcpSock, unsigned key, char* messages[]) {
	sock_write(tcpSock, messages[key], strlen(messages[key])+1);
	sock_close(tcpSock);
	while (tcp_tick(tcpSock) != 0);
	glBlankScreen();
	TextGotoXY(&wholewindow, 0, 0 );
	TextPrintf(&wholewindow, "Response sent");
	return;
}
	
void msdelay (long sd)
{
	auto unsigned long t1;

	t1=MS_TIMER;
	for (t1=MS_TIMER; MS_TIMER<(sd+t1); );
}

void flashled(int led)
{
	switch (led)
	{
		case 0: 
			led = 0;
			break;
		case 1:
			led = 1;
			break;
		case 2:
			led = 2;
			break;
		case 3:
			led = 3;
			break;
		default:
		   led = 6;
	}
	ledOut(led,1);
	msdelay(400);
	ledOut(led,0);
}

void initsystem()
{
	auto int status;
	
	brdInit();
	keyInit();
	keypadDef();	
	glInit();
	glXFontInit(&fi6x8, 6, 8, 32, 127, Font6x8);
	status = TextWindowFrame(&wholewindow, &fi6x8, 0, 0, LCD_XS, LCD_YS);
	glBackLight(1);
}


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";

	initsystem();
	sock_init();

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

	while (1) {
		costate {								//	Process Keypad Press/Hold/Release
			keyProcess ();
			waitfor ( DelayMs(10) );
		}

		costate {
			glBlankScreen();
			TextGotoXY(&wholewindow, 0, 0 );
			TextPrintf(&wholewindow, "Press the key that\nis setup to send a\nresponse...");						
			waitfor ( key = keyGet() );	//	Wait for Keypress
			if (key != 0)
				flashled(key-0x30);
			// 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-0x30, messages);
				respond = 0;
			}
		}

		// Receive a message
	
		if (respond == 0) {
			glBlankScreen();
			TextGotoXY(&wholewindow, 0, 0 );
			TextPrintf(&wholewindow, "Waiting for message to be sent...");
			RecvMessage(&tcpSock, &respond);
		}
	}
}