/****************************************************************************
*
* (C) 1999 by BECK IPC GmbH
*
*  BECK IPC GmbH
*  Garbenheimerstr. 38
*  D-35578 Wetzlar
*
*  Phone : (49)-6441-905-240
*  Fax   : (49)-6441-905-245
*
* ---------------------------------------------------------------------------
* Module      : Submit.c
*
* Function    :
        This program demonstrates the usage of the implemented
				CGI-Interface of IPC@CHIP in a dos program, especially
        the building of formulars.
				The programmer should use this program as an example
				for building own cgi functions.


				Compiler     : Borland C 3.0
				Projectfile  : submit.prj
				Memorymodel  : Large


				We install a cgi function, which
				produces a dynamic htmlpage in the memory.
				This page has the name "submitexample". The name of the
				installed cgi function is "Submit_Func".
				The expected http method is "get".

				If a browserrequest e.g. http://192.168.205.4/submit
				comes in, the web server calls this function.
				This function produces a html pages, which contains
				a formular tag with a submit button:

        <FORM ACTION=/processform METHOD=POST>
        Enter something in the box
        <INPUT TYPE=TEXT NAME=\"Testtext\" SIZE=15 MAXSIZE=15>
        <BR><BR>and <INPUT TYPE=SUBMIT NAME=\"Button\" VALUE=\"Submit\">
        </FORM>


        Entering some text and pressing the submit button
        at the browser, another installed cgi function
        of this program will be called:
        Htmlname: processform
        look the Form tag above: ACTION =/processform
        The webserver executes the function Process_func.
        This function generates a Html page, which contains
        the name of the formularfield ("Testtext") and the
        entered value.


				At the mainloop of our program, we increment a counter
				once per second. The program runs five minutes


				During runtime of the program, the page "submitexample"
				can be loaded from a browser.


				After five minutes the program ends.
				A browserrequest after the end of the program
				returns "Object not found, ......"


        Important for the usage of Microsoft C-Compiler:

				1. Use as struct member byte aligment: 1Byte !!!!!
				or #pragma pack(1)

				2. Cgi functions must be declared as the following:
				void far _saveregs _loadds Example1_Func(rpCgiPtr CgiRequest);


				3. Microsoft C compiler will not accept the follwing statements
				   from  the main function:

				   inregs.x.dx   = FP_SEG(&example);
				   inregs.x.si   = FP_OFF(&example);

				   because example is a structure, we changed it:

				   //declare a pointer of type CGI_ENTRY
				   CGI_Entry  * cgiptr;



				   cgiptr =  &example;
				   inregs.h.ah   = CGI_INSTALL;
				   inregs.x.dx   = FP_SEG(cgiptr);
				   inregs.x.si   = FP_OFF(cgiptr);



				Important:
				At the end of the program we must remove the installed
				cgi functions from webservers CGI table.



* Author        : Bartat
* Date          : 12.01.00
* Version       : V1.00
* ---------------------------------------------------------------------------
* History       :
*
*  Vx.yy        Author  Changes
*
*  V1.00          mb    Create
*  V1.01          mb    Change cgi func declaration to pascal style
*  V1.02          mb    Replaced "" with \" at html strings
*****************************************************************************/

/****************************************************************************/
/* Compiler dependent defines, Microsoft C V152 */
/****************************************************************************/
#ifdef _MSC_VER

  //set structure member assignment to 1Byte !!!!
  #pragma pack(1)

  #ifndef _M_I86LM
    #error Must use LARGE memory model
  #endif

#endif /* _MSC_VER */

/****************************************************************************/
//includes
/****************************************************************************/
#include <DOS.H>
#include <STDIO.H>
#include <STRING.H>
#include <STDLIB.H>
//needed for sleep call
#include "TCPIPAPI.H"
//cgi types, constants, ...
#include "CGI.H"
/*************************************************************************/
//constants
/*************************************************************************/
//needed interrupt vectors
#define TCPIPVECT     0xAC
#define CGIVECT       0xAB


#define MAIN_LOOPS    300L   /* our program run MAIN_LOOPS seconds*/


/* LCD definitions */
#define LCD_COM			  0x102
#define LCD_DAT       0x103

void lcd_wait(void);
void lcd_init(void);
void lcd_write  (unsigned char x, unsigned char y, char * text);


/****************************************************************************/
//needed registerstructs for CGI interrupt calls
/****************************************************************************/
static union  REGS  inregs;
static union  REGS  outregs;

/***************************************************************************
  the name of the page for the browserrequest
  e.g. http://192.168.200.5/example1
****************************************************************************/
static char * HtmlPageName     = "submitexample";
static char * ProcessName      = "processform";
/***************************************************************************
//our cgi entry webserver
 ***************************************************************************/
static CGI_Entry   submitexample;
static CGI_Entry   processexample;
static CGI_Entry  * cgiptr;

static unsigned long MainLoopCounter = 0L;

/***************************************************************************/
static char ProcessPageBuffer[1024];
/***************************************************************************/

/******************************/
//static Htmltext for submitexample
/******************************/

static char HtmlSubmitPage[] =

		"<HTML><HEAD><TITLE>ELEKTOR WEBIO LCDTEST</TITLE></HEAD>"
		"<BODY BGCOLOR=\"#A0A0A0\">"
		"<IMG SRC=\"beck.gif\" ALIGN=\"RIGHT\" ALT=\"BECK\">"
		"<BR><BR>"
		"<CENTER>"
		"<H1>ELEKTUUR WEBIO LCD TEST</H1>"
		"<HR size=0>"
		"</CENTER>"
		"<P>"
		"<FORM ACTION=/processform METHOD=POST>"
    "Enter something in the box "
    "<INPUT TYPE=TEXT NAME=\"Testtext\" SIZE=15 MAXSIZE=15>"
    "<BR><BR>and <INPUT TYPE=SUBMIT NAME=\"Button\" VALUE=\"Submit\">"
    "</FORM>"
    "<HR size=0>"
		"<p align=center><SMALL><EM>&copy BECK IPC GmbH, 2000</EM>"
		"</BODY>"
		"</HTML>";




/****************************************************/
//static head and tail for processform
/*****************************************************/

static char  HtmlPageHead[] =

    "<HTML><HEAD><TITLE>IPC@Chip Form Page</TITLE></HEAD>"
    "<BODY BGCOLOR=\"#A0A0A0\">"
		"<IMG SRC=\"beck.gif\" ALIGN=\"RIGHT\" ALT=\"BECK\">"
		"<BR><BR>"
		"<CENTER>"
		"<H1>IPC@Chip Form Page</H1>"
		"<HR size=0>"
		"</CENTER>";

static char  HtmlPageTail[] =
    "<P>"
    "<P><A HREF=\"submitexample\">Back to submit page</A></P>"
    "<HR size=0>"
		"<p align=center><SMALL><EM>&copy BECK IPC GmbH, 2000</EM>"
		"</BODY>"
		"</HTML>";

/****************************************************************************
	CGI function, the webserver executes this function, if a
	browser request e.g. http://192.168.200.8/submitexample comes in,
	We return at this function a html page in memory, which
  contains the foolowing Form tag

  "<FORM ACTION=/processform METHOD=POST>"
  "Enter something in the box "
  "<INPUT TYPE=TEXT NAME=\"Testtext\" SIZE=15 MAXSIZE=15>"
	"<BR><BR>and <INPUT TYPE=SUBMIT NAME=\"Button\" VALUE=\"Submit\">"
  "</FORM>"

****************************************************************************/

//Microsoft Visual C
#ifdef _MSC_VER
void far _saveregs _loadds _pascal Submit_Func(rpCgiPtr CgiRequest)
#else
void huge _pascal Submit_Func(rpCgiPtr CgiRequest)
#endif
{


   //set response fields
	 CgiRequest->fHttpResponse         = CgiHttpOk;       //HTTP 200 OK
   CgiRequest->fDataType             = CGIDataTypeHtml; //text/html

   CgiRequest->fResponseBufferPtr    = HtmlSubmitPage;  //page address

   CgiRequest->fResponseBufferLength = strlen(HtmlSubmitPage); //length of the page



}



/****************************************************************************
	CGI function, the webserver executes this function, if a
  the submit button was pressed at the page "submitexample"
  This function builds a page, which contains
****************************************************************************/


//Microsoft Visual C
#ifdef _MSC_VER
void far _saveregs _loadds  _pascal Process_Func(rpCgiPtr CgiRequest)
#else
void huge _pascal Process_Func(rpCgiPtr CgiRequest)
#endif
{

   //needed for calling func CGI_GETFORMITEM
   union  REGS  inregs;
	 union  REGS  outregs;
   struct SREGS segregs;
   char far     * FormNamePtr  = NULL;
	 char far     * FormValuePtr = NULL;
	 int    cursor;
   FormItem far * formitem     = NULL;



   //Insert the head of the dynamic html page
   strcpy(ProcessPageBuffer,HtmlPageHead);

   if(strlen(CgiRequest->fArgumentBufferPtr))
   {
	  //alloc memory
	  FormNamePtr=(char far *)malloc(sizeof(char )*25);
	  FormValuePtr=(char far *)malloc(sizeof(char )*25);
	  formitem=(FormItem far *)malloc(sizeof(FormItem));

	  if((FormNamePtr!=NULL) && (FormValuePtr!=NULL) && (formitem!=NULL))
	  {
		formitem->NamePtr  = FormNamePtr;
		formitem->ValuePtr = FormValuePtr;

		inregs.h.ah = CGI_GETFORMITEM;
		inregs.x.bx = FP_SEG(CgiRequest->fArgumentBufferPtr);
		inregs.x.si = FP_OFF(CgiRequest->fArgumentBufferPtr);
        segregs.es    = FP_SEG(formitem);
        inregs.x.di = FP_OFF(formitem);

				int86x(CGIVECT,&inregs,&outregs,&segregs);

				strcat(ProcessPageBuffer,"<P><P>Formularname : ");
				strcat(ProcessPageBuffer,formitem->NamePtr);

				strcat(ProcessPageBuffer,"<P><P>Entered value: ");
				strcat(ProcessPageBuffer,formitem->ValuePtr);

				lcd_write (0,0,"                ");

				lcd_write (0,0,formitem->ValuePtr);
				lcd_write (0,1,"WEB IO ELEKTUUR");

        //free memory
        free(FormNamePtr);
        free(FormValuePtr);
        free(formitem);
      }//
      else
      {
        strcat(ProcessPageBuffer,"<P>Webserver, memory allocation failed<P>");
			}
	 }//if(strlen(CgiRequest->fArgumentBufferPtr))

   //Append the tail of the dynamic html page
   strcat(ProcessPageBuffer,HtmlPageTail);


   //set response fields
   CgiRequest->fHttpResponse         = CgiHttpOk;       //HTTP 200 OK
   CgiRequest->fDataType             = CGIDataTypeHtml; //text/html

   CgiRequest->fResponseBufferPtr    = ProcessPageBuffer; //page address
   CgiRequest->fResponseBufferLength = strlen(ProcessPageBuffer); //length



}


/****************************************************************************/


void lcd_write  (unsigned char x, unsigned char y, char * text)
{

	unsigned char o;
	o = 128 + ((y%2)*64) + (x%32);
	outportb (LCD_COM, o ); lcd_wait();
	while (*text!='\0')
	{
		outportb (LCD_DAT,*text++); lcd_wait();
	}
}

void lcd_wait()
{
	do
	{	}
	while ( (volatile unsigned char) (inportb(LCD_COM)) >127 );
}


void lcd_init()
{
	outportb (LCD_COM , 0x38); lcd_wait();
	outportb (LCD_COM , 0x0C); lcd_wait();
	outportb (LCD_COM , 0x06); lcd_wait();
	outportb (LCD_COM , 0x01); lcd_wait();

}



int main(void)
{

	 lcd_init();
   lcd_write (1,1,"WEB IO2");

	 printf ("\nLCD initialized\n");

	 printf("\r\nInstalling CGI submit example\r\n");
	 #ifdef _MSC_VER
	 printf("Microsoft C\r\n");
	 #endif

	 /***********************************/
	 //install submitexample cgi function
	 /***********************************/

	 //init CGI_entry example;
	 submitexample.PathPtr    = HtmlPageName;    //name of the page
	 submitexample.method     = CgiHttpGet;      //method
	 submitexample.CgiFuncPtr = Submit_Func;   //function

	 cgiptr =  &submitexample;

	 // We need this helpptr because the Microsoft compiler
	 // will not accept the following:
	 // inregs.x.dx   = FP_SEG(&example);
	 // inregs.x.si   = FP_OFF(&example);

	 inregs.h.ah   = CGI_INSTALL;
	 inregs.x.dx   = FP_SEG(cgiptr);
	 inregs.x.si   = FP_OFF(cgiptr);

	 int86(CGIVECT,&inregs,&outregs);

	 if(outregs.x.dx == (unsigned int)CGI_ERROR)
	 {

		printf("\r\nInstalling CGI function %s failed --> exit program\r\n",submitexample.PathPtr);
		return 0;
	 }



	 /***********************************/
	 //install process_form cgi function
	 /***********************************/

	 //init CGI_entry process;
	 processexample.PathPtr     = ProcessName;    //name of the page
	 processexample.method      = CgiHttpPost;      //method
	 processexample.CgiFuncPtr  = Process_Func;   //function

	 cgiptr =  &processexample;

	 inregs.h.ah   = CGI_INSTALL;
	 inregs.x.dx   = FP_SEG(cgiptr);
	 inregs.x.si   = FP_OFF(cgiptr);

	 int86(CGIVECT,&inregs,&outregs);

	 if(outregs.x.dx == (unsigned int)CGI_ERROR)
	 {

		printf("\r\nInstalling CGI function %s failed --> exit program\r\n",submitexample.PathPtr);
		return 0;
	 }




	 /*******************************************************************/
	 //Main loop: Increment a counter
	 //
	 /*******************************************************************/
	 while(MainLoopCounter < MAIN_LOOPS)
	 {

			 //increcment the counter for our dynamic html page
			 MainLoopCounter++;

			 //sleep a second
			 inregs.h.ah = API_SLEEP;
			 inregs.x.bx = 1000; //milliseconds
			 int86(TCPIPVECT,&inregs,&outregs);
	 }

	 /****************************************/
	 //Important: remove example cgi function
	 /****************************************/


	 inregs.h.ah   = CGI_REMOVE;
	 inregs.x.dx   = FP_SEG(submitexample.PathPtr);
	 inregs.x.si   = FP_OFF(submitexample.PathPtr);
	 int86(CGIVECT,&inregs,&outregs);

   if(outregs.x.dx == (unsigned int)CGI_ERROR)
   {

	  printf("\r\nRemoving %s failed\r\n",submitexample.PathPtr);
	  return 0;
   }

   printf("\r\n%s removed\r\n",submitexample.PathPtr);


   inregs.h.ah   = CGI_REMOVE;
   inregs.x.dx   = FP_SEG(processexample.PathPtr);
   inregs.x.si   = FP_OFF(processexample.PathPtr);
   int86(CGIVECT,&inregs,&outregs);

   if(outregs.x.dx == (unsigned int)CGI_ERROR)
   {

	  printf("\r\nRemoving %s failed\r\n",processexample.PathPtr);
	  return 0;
   }

   printf("\r\n%s removed\r\n",processexample.PathPtr);



   printf("\r\nExit program\r\n");

   return 0;
}
/*************************************************************************/
//end submit.c
/*************************************************************************/
