/* ------------------------------------------------------------------------------------------------ */
/* FILE :		CGI_SSI.c																			*/
/*																									*/
/* CONTENTS :																						*/
/*				Code for the lwIP webserver															*/
/*				This file contains the CGI, POST and SSI functions and variables					*/
/*																									*/
/*																									*/
/* Copyright (c) 2013-2014, Code-Time Technologies Inc. All rights reserved.						*/
/*																									*/
/* Code-Time Technologies retains all right, title, and interest in and to this work				*/
/*																									*/
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS							*/
/* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF										*/
/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL							*/
/* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR								*/
/* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,							*/
/* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR							*/
/* OTHER DEALINGS IN THE SOFTWARE.																	*/
/*																									*/
/*																									*/
/*	$Revision: 1.2 $																				*/
/*	$Date: 2014/04/28 16:05:23 $																	*/
/*																									*/
/* ------------------------------------------------------------------------------------------------ */

#include "WebServer.h"

/* ------------------------------------------------------------------------------------------------ */

#define HOST_NAME	"STM3220G"						/* Name of the WebServer platform				*/

#define RTC_USE_XTAL	0							/* Set to != 0 when 32.768 kHz is available		*/
													/* Was not tested with xtal						*/
/* ------------------------------------------------------------------------------------------------ */

static const char g_DayOfWeek[7][4]   = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
static const char g_MonthNames[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", 
                                         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
static const char g_SwitchState[2][4] = {"OFF", "ON"};

#ifdef osCMSIS
  extern int G_TaskLed3off;
#endif

/* ------------------------------------------------------------------------------------------------ */
/* Send text to the LCD display																		*/
/* POST: already split in parameters and values														*/
/* Is attached to the POST dispatcher with POSTnewHandler()											*/

const char *LCD_POST_Handler(int NumParam, char *Params[], char *Values[])
{
int   ii;											/* Loop counter									*/
int   jj;											/* Line index									*/
char *Lines[10];
char  Names[] = "line0";

	memset(&Lines[0], 0, sizeof(Lines));

	for (ii=0 ; ii<NumParam ; ii++) {				/* Analyze all parameters						*/
		for (jj=0 ; jj<10 ; jj++) {					/* We have to compare with "line0" -> "line9"	*/
			Names[4] = '0' + jj;					/* Do char substitution to keep code compact	*/
			if (0 == strcmp(Params[ii] , Names)){	/* Matching line #, memo the string				*/
				Lines[jj] = Values[ii];
			}
		}
	}
	for (ii=0 ; ii<10 ; ii++) {						/* Time to print all lines						*/
		if (Lines[ii] == (char *)NULL) {
			LCD_ClearLine(LINE(ii));
		}
		else {
			LCD_ClearLine(LINE(ii));
			LCD_DisplayStringLine(LINE(ii), (uint8_t*)Lines[ii]);
		}
	}

	return("/LCD.shtml");							/* Web page to send back to the client			*/
}

/* ------------------------------------------------------------------------------------------------ */
/* Control the on-board LEDs																		*/
/* CGI: already split in parameters and values														*/

const char *LEDS_CGI_Handler(int NumParam, char *Params[], char *Values[])
{
int ii;												/* Loop counter and index						*/

	STM_EVAL_LEDOff(MY_LED_0);						/* Turn off all the LEDS first					*/
	STM_EVAL_LEDOff(MY_LED_1);
	STM_EVAL_LEDOff(MY_LED_2);
   #ifdef osCMSIS
	G_TaskLed3off = 1;
   #else
	TSKsuspend(TSKgetID("LED 3"));					/* LED 3 is controlled by the LED 3 task		*/
   #endif
	STM_EVAL_LEDOff(MY_LED_3);						/* So suspend the task and then turn LED 3 off	*/

	for (ii=0 ; ii<NumParam ; ii++) {				/* Get param: "GET /leds.cgi?led=1&led=2..."	*/
		if (0 == strcmp(Params[ii] , "led")){
			if (0 == strcmp(Values[ii], "1")) { 
				STM_EVAL_LEDOn(MY_LED_0);
			}
			if (0 == strcmp(Values[ii], "2")) { 
				STM_EVAL_LEDOn(MY_LED_1);
			}
			if (0 == strcmp(Values[ii], "3")) { 
				STM_EVAL_LEDOn(MY_LED_2);
			}
			if (0 == strcmp(Values[ii], "4")) { 
				STM_EVAL_LEDOn(MY_LED_3);
			  #ifdef osCMSIS
				G_TaskLed3off = 0;
			  #else
				TSKresume(TSKgetID("LED 3"));
			  #endif
			}
		}
	}

	return("/LED.shtml");							/* Web page to send back to the client			*/
}

/* ------------------------------------------------------------------------------------------------ */
/* Set the RTC																						*/
/* POST: already split in parameters and values														*/
/* Is attached to the POST dispatcher with POSTnewHandler()											*/

const char *RTC_POST_Handler(int NumParam, char *Params[], char *Values[])
{
RTC_DateTypeDef Date;
RTC_TimeTypeDef Time;
int  ii;											/* Loop counter									*/
int  d;												/* Day for computing day of the week			*/
int  m;												/* Month for computing day of the week			*/
int  y;												/* Year for computing day of the week			*/

	memset(&Date, 0, sizeof(Date));
	memset(&Time, 0, sizeof(Time));
	for (ii=0 ; ii<NumParam ; ii++) {
		if ((0 == strcmp(Params[ii] , "sec"))
		&&  (Values[ii][0] != '\0')) {
			Time.RTC_Seconds = strtol(Values[ii], NULL, 10);
		}
		if ((0 == strcmp(Params[ii] , "min"))
		&&  (Values[ii][0] != '\0')) {
			Time.RTC_Minutes = strtol(Values[ii], NULL, 10);
		}
		if ((0 == strcmp(Params[ii] , "hrs"))
		&&  (Values[ii][0] != '\0')) {
			Time.RTC_Hours = strtol(Values[ii], NULL, 10);
		}
		if ((0 == strcmp(Params[ii] , "day"))
		&&  (Values[ii][0] != '\0')) {
			Date.RTC_Date = strtol(Values[ii], NULL, 10);
		}
		if ((0 == strcmp(Params[ii] , "mth"))
		&&  (Values[ii][0] != '\0')) {
			Date.RTC_Month = strtol(Values[ii], NULL, 10);
		}
		if ((0 == strcmp(Params[ii] , "yr"))
		&&  (Values[ii][0] != '\0')) {
			y = strtol(Values[ii], NULL, 10);
			Date.RTC_Year = y - 2000;
		}
	}

	y  = Date.RTC_Year;								/* Compute what day of the week this is			*/
	m  = Date.RTC_Month;
	d  = Date.RTC_Date;
	d += (m < 3)
	   ? y--
	   : y-2;
	Date.RTC_WeekDay  = ((23*m/9+d+4+y/4-y/100+y/400)%7);
	Date.RTC_WeekDay += 1;

	RTC_SetTime(RTC_Format_BIN, &Time);
	RTC_SetDate(RTC_Format_BIN, &Date);

	return("/RTC.shtml");							/* Web page to send back to the client			*/
}

/* ------------------------------------------------------------------------------------------------ */
/* Read the RTC and insert the text in the DATE_LOCAL variable										*/
/* This function is attached to SSIupdate() with SSInewUpdate()										*/

void RTCupdate(void)
{
RTC_DateTypeDef Date;
char           *RTCptr;
RTC_TimeTypeDef Time;

	RTCptr = SSIgetVar("DATE_LOCAL");

	if (RTCptr != NULL) {							/* We use the I2C start/stop to take snapshot	*/
		RTC_GetTime(RTC_Format_BIN, &Time);
		RTC_GetDate(RTC_Format_BIN, &Date);

		sprintf(RTCptr, "%s, %02d-%s-%04d  %02d:%02d:%02d", &g_DayOfWeek[Date.RTC_WeekDay-1][0],
		                Date.RTC_Date, &g_MonthNames[Date.RTC_Month-1][0], 2000+(int)Date.RTC_Year,
			            Time.RTC_Hours, Time.RTC_Minutes, Time.RTC_Seconds);
	}

	return;	
}

/* ------------------------------------------------------------------------------------------------ */
/* Switches value read of zero is ON, non-zero is OFF												*/
/* Update the variables SW0 to "ON" or "OFF"														*/
/* This function is attached to SSIupdate() with SSInewUpdate()										*/

void SwitchUpdate(void)
{
char *SwPtr;

	SwPtr = SSIgetVar("SW0");
	if (SwPtr != NULL) {
		strcpy(SwPtr, &g_SwitchState[0 != STM_EVAL_PBGetState(MY_BUTTON_0)][0]);
	}
	SwPtr = SSIgetVar("SW1");
	if (SwPtr != NULL) {
		strcpy(SwPtr, &g_SwitchState[0 == STM_EVAL_PBGetState(MY_BUTTON_1)][0]);
	}
	SwPtr = SSIgetVar("SW2");
	if (SwPtr != NULL) {
		strcpy(SwPtr, &g_SwitchState[0 == STM_EVAL_PBGetState(MY_BUTTON_2)][0]);
	}
	SwPtr = SSIgetVar("SW3");
	if (SwPtr != NULL) {
		strcpy(SwPtr, &g_SwitchState[1 == IOE_JoyStickGetState()][0]);
	}
	SwPtr = SSIgetVar("SW4");
	if (SwPtr != NULL) {
		strcpy(SwPtr, &g_SwitchState[2 == IOE_JoyStickGetState()][0]);
	}
	SwPtr = SSIgetVar("SW5");
	if (SwPtr != NULL) {
		strcpy(SwPtr, &g_SwitchState[3 == IOE_JoyStickGetState()][0]);
	}
	SwPtr = SSIgetVar("SW6");
	if (SwPtr != NULL) {
		strcpy(SwPtr, &g_SwitchState[4 == IOE_JoyStickGetState()][0]);
	}
	SwPtr = SSIgetVar("SW7");
	if (SwPtr != NULL) {
		strcpy(SwPtr, &g_SwitchState[5 == IOE_JoyStickGetState()][0]);
	}

	return;
}

/* ------------------------------------------------------------------------------------------------ */
/* Set-up all CGI handlers																			*/

void CGIinit(void)
{ 

	CGInewHandler("/leds.cgi", LEDS_CGI_Handler);

	return;
}

/* ------------------------------------------------------------------------------------------------ */
/* Set-up all the POST handlers																		*/

void POSTinit(void)
{ 

	POSTnewHandler("/lcd.cgi",  LCD_POST_Handler);
	POSTnewHandler("/rtc.cgi",  RTC_POST_Handler);

	return;
}

/* ------------------------------------------------------------------------------------------------ */
/* Set-up all server variables and variables update handlers										*/

void SSIinit(void)
{
char DemoVal[4];								/* Temp to convert from number to string			*/
RTC_InitTypeDef RTCsetup;
												/* ------------------------------------------------ */
	SSInewVar("REMOTE_HOST", HOST_NAME, NULL);	/* Host name variable								*/

  #ifdef __ABASSI_H__
	SSInewVar("RTOS_ID", "Abassi", NULL);
  #endif
  #ifdef __MABASSI_H__
	SSInewVar("RTOS_ID", "mAbassi", NULL);
  #endif
  #ifdef __UABASSI_H__
	SSInewVar("RTOS_ID", "&micro;Abassi", NULL);
  #endif
												/* ------------------------------------------------ */
	sprintf(&DemoVal[0], "%d", OS_DEMO);		/* Demo # variable									*/
	SSInewVar("OS_DEMO", &DemoVal[0], NULL);
												/* ------------------------------------------------ */
	SSInewVar("SHOW_LCD_PAGE", "YES", NULL);	/* Don't have optional LCD board, so none			*/
	SSInewVar("SHOW_LED_PAGE", "YES", NULL);	/* The STM3220G board has a 4 LEDs					*/
	SSInewVar("SHOW_RTC_PAGE", "YES", NULL);	/* The STM32F207 chip has a Real Time Clock			*/
	SSInewVar("SHOW_SW_PAGE",  "YES", NULL);	/* The STM3220G board has switchs & joystick		*/

												/* ------------------------------------------------ */
	SSInewVar("LCD_HAS_LINE_0", "YES",  NULL);	/* The STM323220G hads a 10 line LCD				*/
	SSInewVar("LCD_HAS_LINE_1", "YES",  NULL);
	SSInewVar("LCD_HAS_LINE_2", "YES",  NULL);
	SSInewVar("LCD_HAS_LINE_3", "YES",  NULL);
	SSInewVar("LCD_HAS_LINE_4", "YES",  NULL);
	SSInewVar("LCD_HAS_LINE_5", "YES",  NULL);
	SSInewVar("LCD_HAS_LINE_6", "YES",  NULL);
	SSInewVar("LCD_HAS_LINE_7", "YES",  NULL);
	SSInewVar("LCD_HAS_LINE_8", "YES",  NULL);
	SSInewVar("LCD_HAS_LINE_9", "YES",  NULL);

												/* ------------------------------------------------ */
	SSInewVar("LED0_PRESENT", "NO",  NULL);		/* LED variables									*/
	SSInewVar("LED1_PRESENT", "YES", NULL);		/* The board has 4 leds								*/
	SSInewVar("LED2_PRESENT", "YES", NULL);		/* Use same numbers as on th silk screen			*/
	SSInewVar("LED3_PRESENT", "YES", NULL);
	SSInewVar("LED4_PRESENT", "YES", NULL);
	SSInewVar("LED5_PRESENT", "NO",  NULL);
	SSInewVar("LED6_PRESENT", "NO",  NULL);
	SSInewVar("LED7_PRESENT", "NO",  NULL);
	SSInewVar("LED8_PRESENT", "NO",  NULL);
	SSInewVar("LED9_PRESENT", "NO",  NULL);

												/* ------------------------------------------------ */
	SSInewVar("SW0",  "YES", NULL);				/* Switch variables									*/
	SSInewVar("SW1",  "YES", NULL);				/* 2 switches on the STM3220G & 5 for joystick		*/
	SSInewVar("SW2",  "YES", NULL);
	SSInewVar("SW3",  "YES", NULL);
	SSInewVar("SW4",  "YES", NULL);
	SSInewVar("SW5",  "YES", NULL);
	SSInewVar("SW6",  "YES", NULL);
	SSInewVar("SW7",  "YES", NULL);
	SSInewVar("SW8",  "--",  NULL);
	SSInewVar("SW9",  "--",  NULL);

	SSInewVar("DATE_LOCAL", " ", NULL);
												/* ------------------------------------------------ */
												/* RTC set-up										*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
	PWR_BackupAccessCmd(ENABLE);
  #if ((RTC_USE_XTAL) == 0)
	RCC_LSICmd(ENABLE);
	while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
	RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
	RCC_RTCCLKCmd(ENABLE);
	RTC_WaitForSynchro();
	RTCsetup.RTC_AsynchPrediv = 127;
	RTCsetup.RTC_SynchPrediv  = 249;
  #elif defined (RTC_CLOCK_SOURCE_LSE)
	RCC_LSEConfig(RCC_LSE_ON);
	while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
	RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
	RCC_RTCCLKCmd(ENABLE);
	RTC_WaitForSynchro();
	RTCsetup.RTC_AsynchPrediv = 127;
	RTCsetup.RTC_SynchPrediv  = 255;
  #endif
	RTCsetup.RTC_HourFormat   = RTC_HourFormat_24;
	RTC_Init(&RTCsetup);
	RTC_AlarmCmd(RTC_Alarm_A, DISABLE);
												/* ------------------------------------------------ */
	SSInewUpdate(&SwitchUpdate);				/* Add the switch refresh handler to the system		*/
	SSInewUpdate(&RTCupdate);					/* Add the real time clock update handler			*/

	return;
}

/* EOF */
