/* ------------------------------------------------------------------------------------------------ */
/* FILE :		WebServer.h																			*/
/*																									*/
/* CONTENTS :																						*/
/*				Code for the lwIP webserver with netconn / BSD sockets.								*/
/*				This file contains all the webservices management.									*/
/*																									*/
/*																									*/
/* 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.8 $																				*/
/*	$Date: 2013/10/03 15:55:16 $																	*/
/*																									*/
/* ------------------------------------------------------------------------------------------------ */

#ifndef __WEBSERVER_H__
#define __WEBSERVER_H__


#include <stdio.h>
#include <string.h>
#ifdef STM32_P407
  #include "stm32_p407.h"
  #include "drv_glcd_cnfg.h"
  #include "drv_glcd.h"
  #include "glcd_ll_st.h"
#else
  #include "stm32f4xx.h"
  #include "stm32f4_discovery.h"
  #include "stm32f4x7_eth_bsp.h"
#endif
#include "stm32f4xx_rtc.h"
#include "NetAddr.h"
#ifndef OS_CMSIS_RTOS
  #include "Abassi.h"
#else
  #include "cmsis_os.h"
#endif
#if (((OS_DEMO) == 10) || ((OS_DEMO) == 11) || ((OS_DEMO) == 110) || ((OS_DEMO) == 111))
  #include "fs.h"									/* Only needed with in-memory file system		*/
#endif

#ifdef __cplusplus
 extern "C" {
#endif

#ifndef WEBS_PRIO
 #ifndef osCMSIS
  #define WEBS_PRIO					(OX_PRIO_MIN-1)	/* Priority of the HTTP webserver task			*/
 #else
  #define WEBS_PRIO					osPriorityLow
 #endif
#endif
#ifndef WEBS_STACKSIZE
  #define WEBS_STACKSIZE			2048			/* Stack size of the HTTP webserver task		*/
#endif
#ifndef WEBS_MAX_CGI
  #define WEBS_MAX_CGI				8				/* Maximum number of different CGIs handlers	*/
#endif
#ifndef WEBS_MAX_POST
  #define WEBS_MAX_POST				8				/* Maximum number of different POSTs handlers	*/
#endif
#ifndef WEBS_CGI_POST_PARAM
  #define WEBS_MAX_CGI_POST_PARAM	10				/* Maximum number of Param=Value in a request	*/
#endif
#ifndef WEBS_MAX_VARIABLE
  #define WEBS_MAX_VARIABLE			48				/* Maximum number of server variables for SSI	*/
#endif
#ifndef WEBS_MAX_SSI
  #define WEBS_MAX_SSI				16				/* Maximum number of SSI update functions		*/
#endif

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

typedef u16_t       (*SSIhandler_t)(int Index, char *Insert, int InsertLen);
typedef const char *(*CGIhandler_t)(int NumParams, char *Param[], char *Value[]);

typedef struct {
    const char  *Name;
    CGIhandler_t Handler;
} CGI_t;

enum VerbTypes {V_GET,   V_HEAD,    V_POST,    V_PUT,   V_DELETE,
                V_TRACE, V_OPTIONS, V_CONNECT, V_PATCH, V_UNKNOWN_};

struct Methods {									/* Association of text to verbs					*/
	char          *Text;
	enum VerbTypes Verb;
};

struct LocalVar {									/* Local variable information holding			*/
	char VarName[32];								/* Name of the variable							*/
	char Value[32];									/* Value of the variable: always text			*/
	char *(*Command)(char *);    					/* Command associated when is an exec variable	*/
};

#if (((OS_DEMO) == 10) || ((OS_DEMO) == 11) || ((OS_DEMO) == 110) || ((OS_DEMO) == 111))
  typedef struct fs_file	*FILE_DSC_t;
  #define F_INIT_FDSC(x)	((x)=NULL)
  #define F_MNT()                               0
  #define F_OPEN(F_Dsc, F_Name, F_Access)		(NULL != ((F_Dsc)=fs_open(F_Name)))
  #define F_CLOSE(F_Dsc)						fs_close(F_Dsc)
  #define F_READ(F_Dsc, Buf, BufSize, Nread)												\
						if (-1 == (*(Nread)=fs_read((F_Dsc), (char *)Buf, (BufSize)))) {	\
							*(Nread) = 0;													\
						}
  #define FA_READ								0
  #define F_PATCH_OPEN(F_Dsc)					do {(F_Dsc)->index = 0;} while(0)
#endif
#if (((OS_DEMO) == 12) || ((OS_DEMO) == 13) || ((OS_DEMO) == 112) || ((OS_DEMO) == 113))
  #include "ff.h"
  typedef FIL				FILE_DSC_t;
  #define F_INIT_FDSC(x)
  #define F_MNT()                             f_mount(&g_FileSys, "0", 1)
  #define F_OPEN(F_Dsc, F_Name, F_Access)	  (FR_OK == (f_open(&(F_Dsc),(F_Name), (F_Access))))
  #define F_CLOSE(F_Dsc)					  f_close(&(F_Dsc))
  #define F_READ(F_Dsc, Buf, BufSize, Nread)  f_read(&(F_Dsc),(void *)(Buf),(BufSize),(UINT *)(Nread))
  #define F_PATCH_OPEN(F_Dsc)                 do{int _=0;_=_;}while(0)
#endif


#ifndef osCMSIS										/* stdio mutex operations						*/
  #define MTXLOCK_STDIO()		MTXlock(G_OSmutex, -1)
  #define MTXUNLOCK_STDIO()		MTXunlock(G_OSmutex)
#else
  #define MTXLOCK_STDIO()		osMutexWait(G_OSmutex, 0)
  #define MTXUNLOCK_STDIO()		osMutexRelease(G_OSmutex)
#endif

#ifdef STM32_P407

  #define MY_LED_0		LED1
  #define MY_LED_1		LED2
  #define MY_LED_2		LED3
  #define MY_LED_3		LED4

  #define MY_BUTTON_0	BUTTON_TAMPER
  #define MY_BUTTON_1	BUTTON_WAKEUP
  #define MY_BUTTON_2	BUTTON_RIGHT
  #define MY_BUTTON_3	BUTTON_LEFT
  #define MY_BUTTON_4	BUTTON_UP
  #define MY_BUTTON_5	BUTTON_DOWN
  #define MY_BUTTON_6	BUTTON_SEL

  #define Line0	0
  #define Line1	1
  #define Line2	2
  #define Line3	3
  #define Line4	4
  #define Line5	5
  #define Line6	6
  #define Line7	7
  #define Line8	8
  #define Line9	9

  #define BG_COLOR	0x00000FFF
  #define FG_COLOR	0x00000000

  #define LCD_LINE(x, txt)	do {											\
							GLCD_SetWindow(0, ((x)*12)+3, GLCD_HORIZONTAL_SIZE-1, (((x)+1)*12)+3);	\
							GLCD_TextSetPos(0,0);													\
							GLCD_print("\f %s\r", txt);												\
							} while(0)
  #define DISPLAY(Line, Txt) 	do {																\
									LCD_LINE(Line, Txt);											\
								    puts(Txt);														\
								} while(0)

  #define LCD_ClearLine(Line) LCD_LINE(Line,"                  ")
#else
  #define MY_LED_0		LED4
  #define MY_LED_1		LED5
  #define MY_LED_2		LED6
  #define MY_LED_3		LED3

  #define MY_BUTTON_0	BUTTON_USER

  #define LCD_LINE(x, txt)
  #define DISPLAY(Line, Txt) 	do { puts(Txt); } while(0)
  #define LCD_ClearLine(Line)
#endif

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

void  CGIinit(void);
char *CGIprocess(char *buf);
int   CGInewHandler(const char *Fname, const CGIhandler_t Handler);
void  http_server_init(void);
void  LCDputs(char *Line_1, char *Line_2);
void  POSTinit(void);
int   POSTnewHandler(const char *Fname, const CGIhandler_t Handler);
char *POSTprocess(char *uri, char *Data);
int   SSIexpand(char *buf, const char *uri);
char *SSIgetVar(const char *Name);
void  SSIinit(void);
int   SSInewUpdate(void (*FctPtr)(void));
int   SSInewVar(const char *Name, char *Value, char *(*Command)(char *));
int   SSIvarUpdate(void);
void  WebServerInit(void);

#ifdef STM32_P407
  void ETH_BSP_Config(void);
#endif

#ifdef __cplusplus
}
#endif

#endif

/* EOF */

