Knowledge Base Nr: 00014 DK40_SET.CPP - http://www.swe-kaiser.de

Downloads:

CGI-Interface IPC@CHIP (Hutschienencomputer)

  
/*
This program demonstrates the usage of the implemented
CGI-Interface of IPC@CHIP in a dos executable.
This example returns a simple page with 14 links, which
allows per click to set or reset the DK40 IO pins 0-6
*/

/*
The name of the CGI page is "dk40_set" (warning: case sensitive !)

If a browserrequest e.g. http://192.168.205.4/dk40_set
comes in, the web server calls this function.

The arguments are made simple:
00 means reset DK40 Output 0 to 0
01 set DK40 Output 0 to 1
01s set DK40 Output 0 to 1 - return no page
...
61 means set DK40 Output 6 to 1

*/


#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <afx.h>

#include "tcpipapi.h"
#include "cgi.h"

extern "C" {
#include "tcpip.h"
}

#pragma pack(1)
#pragma check_stack( off )

//needed interrupt vectors
#define TCPIPVECT 0xAC
#define CGIVECT 0xAB

#define STARTTIMERBIT 2 //eingang: timer starten
#define SMSDELETEBIT 3 //eingang: sms-signalisierung rücksetzen
#define AUDIOPOWERBIT 4 //ausgang: audio-funkstrecke
#define SMSPOWERBIT 5 //ausgang: sms-signalisierung
#define TELESWTCHBIT 6 //eingang: teleswitch

#define WAITTIMERSEC (15*60) //timer in sekunden (sms-sig einschalten)

char * HtmlPageName = "dk40_set"; //the name of the page for the browserrequest

CGI_Entry example;

char * HtmlPageHead = "<HTML><HEAD><TITLE>IPC@CHIP CGI DK40 Switching</TITLE></HEAD>"
"<BODY BGCOLOR=\"#A0A0A0\">"
"<BR>"
"<CENTER>"
"<H1>IPC@CHIP: DK40 Switching</H1>"
"<HR size=0>"
;

char * HtmlPageBody = "<FONT FACE = \"Courier\" SIZE=+1><P>Pin 0: %s<BR>"
"Pin 1: %s<BR>"
"Pin 2: %s<BR>"
"Pin 3: %s<BR>"
"Pin 4: %s<BR>"
"Pin 5: %s<BR>"
"Pin 6: %s</P>"
"<BR><P>%s</P>"
"<IMG SRC=\"chip.gif\" ALIGN=LEFT ALT=\"ipc@chip\"><BR>"
"<P>%s</P>"
"<P>restliche Zeit des Timers: %d s.</P>"
"<form target=\"_self\" action=\"/kaiserreich/cgi-bin/k_kaiser.pl\" method=\"get\" align=\"center\">"
" <input type=\"hidden\" name=\"page\" value=\"Proxy\">"
" <input type=\"hidden\" name=\"href\" value=\"http://ipc_chip/dk40_set\">"
" Startwert in Sekunden:&nbsp;&nbsp;<input name=\"t\" size=\"6\" value=\"%d\">"
" <input type=\"submit\" name=\"Request\" value=\"Übernehmen\">"
"</form>"
"</FONT>"
;

char * HtmlPageFoot = "<HR size=0>"
"<H2>Beschaltete Eingänge sollten nicht &uuml;ber CGI gesetzt werden."
" Der IPC pollt diese Pins und reagiert entsprechend.</H2>"
"</CENTER>"
"</BODY>"
"</HTML>"
;

/****************************************************************************
CGI function, the webserver executes this function, if a
browser request e.g. http://192.168.200.8/dk40_set comes in,
****************************************************************************/

char* HtmlPage; //puffer für seitenaufbau

BOOL g_bSMStoggle = FALSE;

BOOL volatile g_bTimerLook = FALSE;
int volatile g_nTimer = 0;
int volatile g_nTimerStart = WAITTIMERSEC;

unsigned char old_outval=0;

void far _saveregs _loadds DK40_Func(rpCgiPtr CgiRequest)
{
//parse the arguments
if(CgiRequest->fArgumentBufferLength >= 2L)
{
int bit;

char tmp = CgiRequest->fArgumentBufferPtr[0];
if ((tmp=='t') || (tmp=='T'))
{
int nVal = 0;
for (int i=2; i<CgiRequest->fArgumentBufferLength; i++)
{
if (CgiRequest->fArgumentBufferPtr[i] == '&')
break;
nVal = nVal*10;
nVal += CgiRequest->fArgumentBufferPtr[i] - '0';
}

g_nTimer = 0;
g_nTimerStart = nVal;
}
else if ((tmp>='0') && (tmp<='7'))
{
//read the current value
old_outval = inp(0x600);
//printf("cgi(): read outval=%02x\n", old_outval);

//benutzte bits ausmaskieren um überschreiben zu vermeiden (nur für inputs!)
old_outval &= ~( (1<<TELESWTCHBIT) | (1<<SMSDELETEBIT) | (1<<STARTTIMERBIT));

//printf("cgi(): maskiert outval=%02x\n", old_outval);

bit = tmp - '0';
tmp = CgiRequest->fArgumentBufferPtr[1] - 48;

unsigned char mask = (1<<bit);

if (!g_bTimerLook) //nicht wenn timer gerade abläuft
{
switch(tmp)
{
case 0:
//printf("case 0 old_outval = %02X mask=%02X bit=%02X\r\n", old_outval, mask, bit);
old_outval &= ~mask;
outp(0x600,old_outval);
//printf("case 0 neu %02X bit=%02x\r\n", old_outval, bit);

if (bit == SMSPOWERBIT)
g_bSMStoggle = FALSE;

break;

case 1: old_outval |= 1<<bit;
outp(0x600,old_outval);
//printf("case 1 outp(0x600,0x%02X)\r\n", old_outval);

if (bit == SMSPOWERBIT)
g_bSMStoggle = TRUE;

break;

default: break;
}//switch(tmp)
}

if(CgiRequest->fArgumentBufferLength >= 3L) //silent: keine ausgabe
{
tmp = CgiRequest->fArgumentBufferPtr[2];
if((tmp=='s') || (tmp=='S'))
{
CgiRequest->fHttpResponse = CgiHttpOKNoDoc; //HTTP 204, no document
CgiRequest->fResponseBufferPtr = NULL;
CgiRequest->fResponseBufferLength = 0L;
return;
}
}
}//else if((tmp>=0) && (tmp<7))
}

unsigned char bits = inp(0x600);

CString strPage, strBody;

strBody.Format(HtmlPageBody
, (bits&0x01) ? "<A HREF=\"dk40_set?00\">Reset!</A>" : "<A HREF=\"dk40_set?01\">Set!</A>"
, (bits&0x02) ? "<A HREF=\"dk40_set?10\">Reset!</A>" : "<A HREF=\"dk40_set?11\">Set!</A>"
, (bits&0x04) ? "Start-Timer pressed (read-only)" : "Start-Timer NOT pressed (read-only)"
, (bits&0x08) ? "Reset-SMS pressed (read-only)" : "Reset-SMS NOT pressed (read-only)"
, (bits&0x10) ? "<A HREF=\"dk40_set?40\">220V Ausschalten!</A> (Laserdrucker Server)" : "<A HREF=\"dk40_set?41\">220V Anschalten!</A> (Laserdrucker Server)"
, (bits&0x20) ? "<A HREF=\"dk40_set?50\">220V Ausschalten!</A> (SMS-Signalisierung)" : "<A HREF=\"dk40_set?51\">220V Anschalten!</A> (SMS-Signalisierung)"
, (bits&0x40) ? "TeleSwitch ON (read-only)" : "TeleSwitch OFF (read-only/not used)"
, "<A HREF=\"dk40_set\">Refresh!</A>"
, g_bTimerLook ? "Der Timer läuft gerade ab - das Setzen ist gesperrt."
: "Die Ausgänge können einzeln gesetzt werden."
, g_nTimer
, g_nTimerStart
);

strPage.Format("%s\n%s\n%s\n", HtmlPageHead, (LPCSTR)strBody, HtmlPageFoot);

strcpy(HtmlPage, strPage);

//we send the page
CgiRequest->fHttpResponse = CgiHttpOk;
CgiRequest->fDataType = CGIDataTypeHtml; //text/html
CgiRequest->fResponseBufferPtr = HtmlPage;
CgiRequest->fResponseBufferLength = strlen(HtmlPage);

//printf("DK40_Func() called\n");
//printf(HtmlPage);
}

/****************************************************************************/

int httpGet(char *server, char *page, char *result, int maxlen)
{
int cnt = 0;
int error = 0;

printf("\r\nConnecting to %s\r\n", server);

int sd = tcp_connect(server, 0, 80, &error);
if (sd>0)
{
char request[2000];
int recvcnt = 0;
sprintf(request, "GET %s \r\n\r\n", page);

send(sd,request, strlen(request), 0, &error);
if (error==0)
{
do
{
memset(request, 0, sizeof(request));
recvcnt = recv(sd, request, sizeof(request), MSG_TIMEOUT, 10000L, &error); //sizeof(request) wird nicht berücksichtigt
//printf("\r\n***recv() recvcnt = %d error = %d maxlen = %d\r\n", recvcnt, error, maxlen);
if (error)
printf("Error %d in receiving\r\n", error);
else
{
strcat(result, request);
cnt += recvcnt;
if (cnt > maxlen)
{
printf("Error buffer too small\r\n");
break;
}

result[cnt]=0;
}

} while (recvcnt > 0);
}
else
{
printf("Error %d sending reuest\r\n", error);
}

closesocket(sd, &error);
}
else
{
printf("Error %d opening connection to http port\r\n", sd);
}

return cnt;
}

int main(int argc, char* argv[])
{
outp(0x600, 0);

static union REGS inregs;
static union REGS outregs;

const MAXPAGESIZE = 4096;
HtmlPage = new char[MAXPAGESIZE];

CGI_Entry* cgiptr;

printf("\r\nStarting MyDK40 CGI Example\r\n\r\n");

/********************************/
//install example cgi function
/********************************/
//init CGI_entry example;
example.PathPtr = HtmlPageName; //name of the page
example.method = CgiHttpGet; //http method
example.CgiFuncPtr = DK40_Func; //function

if (argc != 1) //parameter -> remove
{
inregs.h.ah = CGI_REMOVE;
inregs.x.dx = FP_SEG(HtmlPageName);
inregs.x.si = FP_OFF(HtmlPageName);
}
else
{
cgiptr = &example;
inregs.h.ah = CGI_INSTALL;
inregs.x.dx = FP_SEG(cgiptr);
inregs.x.si = FP_OFF(cgiptr);
}

int86(CGIVECT,&inregs,&outregs);
printf("\r\nCGI function (PathPtr:%s dx:%04X ax:%04X)\r\n", example.PathPtr, outregs.x.dx, outregs.x.ax);

if (outregs.x.dx == (unsigned int)CGI_ERROR)
return 1;

if (argc != 1) //parameter: exit
return 0;

/*******************************************************************/
//Main loop
/*******************************************************************/
while(1)
{
unsigned char outval = inp(0x600);
//printf("main(): read outval=%02x\n", outval);

if (outval & (1<<SMSDELETEBIT))
{
g_bSMStoggle = FALSE;
outval &= ~((1<<SMSDELETEBIT) | (1<<SMSPOWERBIT));
outp(0x600, outval);

int rslt = httpGet("192.168.32.70","/kaiserreich/k_SMS.php3?reset=1", HtmlPage, MAXPAGESIZE);
printf("\r\nhttpGet(192.168.32.70, /kaiserreich/k_SMS.php3) => %d\r\n%s\r\n", rslt, HtmlPage);
}

if (outval & (1<<STARTTIMERBIT))
{
//switch on ...
g_bTimerLook = TRUE;
g_nTimer = g_nTimerStart;
outval |= (1<<SMSPOWERBIT);
outp(0x600, outval);

//... for x seconds
while (--g_nTimer > 0)
{
inregs.h.ah = API_SLEEP;
inregs.x.bx = 1000; //milliseconds
int86(TCPIPVECT,&inregs,&outregs);
}

//.. and off again
outval &= ~((1<<STARTTIMERBIT) | (1<<SMSPOWERBIT));
outp(0x600, outval);
g_bTimerLook = FALSE;
}

if (g_bSMStoggle) //sms-sgnalisierung: wenn schon eingeschaltet dann ausschalten und umgekehrt
{
if (outval & (1<<SMSPOWERBIT))
outval &= ~(1<<SMSPOWERBIT);
else
outval |= (1<<SMSPOWERBIT);

outp(0x600, outval);
//printf("main(): write sms outval=%02x\n", outval);
}

//sleep
inregs.h.ah = API_SLEEP;
inregs.x.bx = 250; //milliseconds
int86(TCPIPVECT,&inregs,&outregs);
}

return 0;
}