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: <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 ü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;
}