Main Page | Modules | Directories | File List | Globals | Related Pages

cgi.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2002-2005 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  */
00033 
00034 #include <string.h>
00035 #include <stdio.h>
00036 #include <io.h>
00037 
00038 #include <dev/spidigio.h>
00039 #include <pro/httpd.h>
00040 
00041 #include "db_shift.h"
00042 #include "webport.h"
00043 
00044 /*!
00045  * \file cgi.c
00046  * \brief CGI Callbacks.
00047  */
00048 
00049 /*!
00050  * \addtogroup xgCGI
00051  */
00052 /*@{*/
00053 
00054 static u_char spi_ni = 255;     /*!< \brief Number of detected opto inputs. */
00055 static u_char spi_no = 255;     /*!< \brief Number of detected relays. */
00056 static u_long relay_status;     /*!< \brief Relays status. */
00057 static u_char relay_known;      /*!< \brief Equals zero as long as the relay status is unknown. */
00058 
00059 /*!
00060  * \brief Print HTML code for a row of LEDs.
00061  *
00062  * The resulting HTML code will present a row of LEDs. The color and
00063  * the lit state of each LED is determined by three bit values. The
00064  * required images are expected in the URL root of the urom flash
00065  * filesystem:
00066  *
00067  * - r0.gif Red LED not lit. Will be displayed if the corresponding
00068  *          bit in the direction mask is set and the input and output
00069  *          bits are both not set.
00070  * - r1.gif Red LED lit. Will be displayed if the corresponding
00071  *          bit in the direction mask is set and the input and output
00072  *          bits are both set.
00073  * - g0.gif Green LED not lit. Will be displayed if the corresponding
00074  *          bit in the direction mask and the input value are both not set.
00075  * - g1.gif Green LED lit. Will be displayed if the corresponding
00076  *          bit in the direction mask is not set and the input bit is set.
00077  * - y0.gif Yellow LED not lit. Will be displayed if the corresponding
00078  *          bit in the direction mask is set, the output bit is set
00079  *          but the input bit is not set.
00080  * - y1.gif Yellow LED lit. Will be displayed if the corresponding
00081  *          bit in the direction mask is set, the output bit is not set
00082  *          but the input bit is set.
00083  *
00084  * All LED images must be of the same size, 28 x 28 pixels.
00085  *
00086  * \param stream HTML code is printed to this stream device.
00087  * \param num    The number of LEDs to print.
00088  * \param desc   If not equal zero, bits are processed in descending order.
00089  * \param ival   Input bit values.
00090  * \param oval   Output bit values.
00091  * \param dir    Data direction mask. Any bit set to one represents an output.
00092  */
00093 static void HtmlLedRow(FILE * stream, u_char num, u_char desc, u_long ival, u_long oval, u_long dir)
00094 {
00095     u_char i;
00096     u_long mask;
00097 
00098     for (i = 0; i < num; i++) {
00099         if (desc)
00100             mask = 1UL << (num - i - 1);
00101         else
00102             mask = 1UL << i;
00103         fputs("<td><img src=\"/", stream);
00104         if (dir & mask) {
00105             if (oval & mask) {
00106                 if (ival & mask)
00107                     fputs("r1", stream);
00108                 else
00109                     fputs("y0", stream);
00110             } else {
00111                 if (ival & mask)
00112                     fputs("y1", stream);
00113                 else
00114                     fputs("r0", stream);
00115             }
00116         } else {
00117             if (ival & mask) {
00118                 fputs("g1", stream);
00119             } else {
00120                 fputs("g0", stream);
00121             }
00122         }
00123         fputs(".gif\" width=\"28\" heigth=\"28\"></td>\r\n", stream);
00124     }
00125 }
00126 
00127 /*!
00128  * \brief Print HTML code for a row of checkboxes.
00129  *
00130  * The resulting HTML code will present a row of checkboxes. 
00131  *
00132  * \param stream HTML code is printed to this stream device.
00133  * \param num    The number of checkboxes to print.
00134  * \param desc   If not equal zero, bits are processed in descending order.
00135  * \param name   Identifier of the checkboxes.
00136  * \param check  The checkbox will be checked if the corresponding bit is set.
00137  * \param enable The checkbox will be created only, ff the corresponding bit 
00138  *               in this bitmask is set.
00139  */
00140 static void HtmlCheckboxRow(FILE * stream, u_char num, u_char desc, u_char * name, u_long check, u_long enable)
00141 {
00142     u_char i;
00143     u_long mask;
00144     for (i = 0; i < num; i++) {
00145         if (desc)
00146             mask = 1UL << (num - i - 1);
00147         else
00148             mask = 1UL << i;
00149         if (enable & mask) {
00150             fputs("<td><input type=\"checkbox\" name=\"", stream);
00151             fprintf(stream, "%s\" value=\"%u\" ", name, num - i - 1);
00152             if (check & mask)
00153                 fputs(" checked=\"checked\"", stream);
00154             fputs("></td>\r\n", stream);
00155         } else
00156             fputs("<td></td>\r\n", stream);
00157     }
00158 }
00159 
00160 
00161 /*!
00162  * \brief Print HTML code for a separator row.
00163  *
00164  * The resulting HTML code will present a black row. 
00165  *
00166  * \param stream HTML code is printed to this stream device.
00167  * \param width  Separator width in columns.
00168  * \param height Separator width in pixels.
00169  */
00170 static void HtmlSeparatorRow(FILE * stream, u_char width, u_char height)
00171 {
00172     fprintf(stream, "<tr bgcolor=\"#000000\"><td colspan=\"%u\" "       /* */
00173             "height=\"%u\"></td></tr>", width, height);
00174 }
00175 
00176 /*!
00177  * \brief Print HTML code to display a single I/O port.
00178  *
00179  * The resulting HTML code will present a row of LEDs and two rows of
00180  * checkboxes. While the LEDs show the current port status, the checkboxes
00181  * may be used to modify the port output and the data direction register.
00182  *
00183  * See HtmlLedRow() for further details about how LEDs are displayed.
00184  * The checkboxes are created by calling HtmlCheckboxRow().
00185  *
00186  * \param stream HTML code is printed to this stream device.
00187  * \param name   Port identifier, typically 'A' for Port A, 'B' for port B etc.
00188  * \param pin    Contents of the PIN register.
00189  * \param port   Contents of the PORT register.
00190  * \param ddr    Contents of the data direction register.
00191  * \param enable If a bit is not set in this bit mask, then the corresponding
00192  *               checkboxes are not created and the port bits and data direction
00193  *               can't be modified.
00194  */
00195 static void HtmlInOutPortRow(FILE * stream, char name, u_char pin, u_char port, u_char ddr, u_char enable)
00196 {
00197     char ditem[3] = { 'D', 'X', 0 };
00198     char pitem[3] = { 'P', 'X', 0 };
00199 
00200     ditem[1] = name;
00201     pitem[1] = name;
00202     fputs("<tr><th rowspan=\"4\">", stream);
00203     fprintf(stream, "%c", name);
00204     fputs("</th><td>Status</td>", stream);
00205     HtmlLedRow(stream, 8, 1, pin, port, ddr);
00206     fputs("</tr>\r\n<tr><td>Output</td>", stream);
00207     HtmlCheckboxRow(stream, 8, 1, ditem, ddr, enable);
00208     fputs("</tr>\r\n<tr><td>Pull up</td>", stream);
00209     HtmlCheckboxRow(stream, 8, 1, pitem, port, enable);
00210     fputs("</tr>\r\n", stream);
00211 }
00212 
00213 /*!
00214  * \brief Process request parameters for CPU port control.
00215  *
00216  * Parse the CGI query and perform the corresponding action:
00217  *
00218  * - Dx=y will set bit y in the data direction register of port x.
00219  * - Px=y will set bit y in the port output register of port x.
00220  *
00221  * All other bits are switched off.
00222  *
00223  * \param query CGI query string.
00224  */
00225 static void ProcessCgiPortRequest(REQUEST * req)
00226 {
00227     u_char ddrb = 0;
00228     u_char portb = 0;
00229     u_char ddrd = 0;
00230     u_char portd = 0;
00231     u_char ddre = 0;
00232     u_char porte = 0;
00233     int mods = 0;
00234     int i;
00235     int pcount = NutHttpGetParameterCount(req);
00236     char *name;
00237     char *value;
00238 
00239     for (i = 0; i < pcount; i++) {
00240         name = NutHttpGetParameterName(req, i);
00241         value = NutHttpGetParameterValue(req, i);
00242         if (strcmp(name, "DB") == 0) {
00243             ddrb |= BV(*value - '0');
00244             mods++;
00245         } else if (strcmp(name, "PB") == 0) {
00246             portb |= BV(*value - '0');
00247             mods++;
00248         } else if (strcmp(name, "DD") == 0) {
00249             ddrd |= BV(*value - '0');
00250             mods++;
00251         } else if (strcmp(name, "PD") == 0) {
00252             portd |= BV(*value - '0');
00253             mods++;
00254         } else if (strcmp(name, "DE") == 0) {
00255             ddre |= BV(*value - '0');
00256             ddre &= ~_BV(5);
00257             mods++;
00258         } else if (strcmp(name, "PE") == 0) {
00259             porte |= BV(*value - '0');
00260             porte &= ~_BV(5);
00261             mods++;
00262         }
00263     }
00264     if (mods) {
00265         outb(DDRB, ddrb);
00266         outb(PORTB, portb);
00267         outb(DDRD, ddrd);
00268         outb(PORTD, portd);
00269         outb(DDRE, ddre);
00270         outb(PORTE, porte);
00271     }
00272 }
00273 
00274 /*!
00275  * \brief Process request parameters for relay output control.
00276  *
00277  * Parse the CGI query and switch the corresponding relays.
00278  * 'S=y' will switch on relay y. All other relays are switched off.
00279  *
00280  * Note, that before calling this function is called for the first time,
00281  * the status of the relays is unknown.
00282  *
00283  * \param query CGI query string.
00284  */
00285 static void ProcessCgiRelayRequest(char *query)
00286 {
00287     u_char *item = query;
00288     u_char *val;
00289 
00290     relay_status = 0;
00291     for (;;) {
00292         if ((val = strchr(item, '=')) == 0)
00293             break;
00294         *val++ = 0;
00295         if (item[0] == 'S')
00296             relay_status |= 1UL << (7 - (*val - '0'));
00297         if ((item = strchr(val, '&')) == 0)
00298             break;
00299         item++;
00300     }
00301     SpiDigitalSet(spi_no, relay_status);
00302     relay_known = 1;
00303 }
00304 
00305 /*!
00306  * \brief CGI callback function to control the CPU ports.
00307  *
00308  * Creates HTML code to show the status of CPU ports B, D, E and F
00309  * plus a HTML form to modify the port and data direction registers 
00310  * of ports B, D and E by checkboxes. 
00311  *
00312  * The resulting HTML code is send back to the browser. If the submit
00313  * button is clicked on this page, this function will be called again
00314  * to process the checkboxes.
00315  *
00316  * \image html cport.gif
00317  *
00318  *
00319  *
00320  * This function is called by the HTTP module when a browser requests
00321  * a CGI function, for which this routine has been registered via
00322  * NutRegisterCgi().
00323  *
00324  * \param stream Stream of the HTTP connection.
00325  * \param req    Pointer to the CGI REQUEST structure. Detailed information
00326  *               is available in the Nut/OS API documentation.
00327  *
00328  * \return 0 on success or -1 in case of any failure.
00329  */
00330 int CpuPortControl(FILE * stream, REQUEST * req)
00331 {
00332     static prog_char head[] = "<html>"  /* */
00333         "<head>"                /* */
00334         "<meta http-equiv=\"expires\" content=\"0\">"   /* */
00335         "<title>Ethernut CPU Port Control</title>"      /* */
00336         "</head>"               /* */
00337         "<body bgcolor=\"#C7D0D9\"><a href=\"/\">"      /* */
00338         "<img src=\"/enmini.gif\" border=\"0\" width=\"70\" height=\"17\">"     /* */
00339         "</a><div align=\"center\">";
00340     static prog_char thdr[] = "<form action=\"" PORT_CONTROL_CGI        /* */
00341         "\" enctype=\"text/plain\">"    /* */
00342         "<table border=\"1\" cellspacing=\"0\">\r\n"    /* */
00343         "<thead><tr><th rowspan=\"2\"> PORT </th>"      /* */
00344         "<th rowspan=\"2\"> Type </th>" /* */
00345         "<th colspan=\"8\">Bit</th></tr>"       /* */
00346         "<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th>"        /* */
00347         "<th>2</th><th>1</th><th>0</th></tr>"   /* */
00348         "</thead><tfoot>\r\n";
00349     static prog_char foot[] = "</tfoot></table><br>"    /* */
00350         " <input type=\"submit\" value=\" Set \"> "     /* */
00351         " <input type=\"reset\" value=\" Cancel \"> "   /* */
00352         "</form>\r\n</div></body>\r\n</html>";
00353 
00354     NutHttpSendHeaderTop(stream, req, 200, "Ok");
00355     NutHttpSendHeaderBot(stream, "text/html", -1);
00356 
00357     fputs_P(head, stream);
00358     if (req->req_url)
00359         ProcessCgiPortRequest(req);
00360 
00361     fputs_P(thdr, stream);
00362 
00363     HtmlInOutPortRow(stream, 'B', inb(PINB), inb(PORTB), inb(DDRB), 0xFF);
00364     HtmlSeparatorRow(stream, 10, 5);
00365     HtmlInOutPortRow(stream, 'D', inb(PIND), inb(PORTD), inb(DDRD), 0xFF);
00366     HtmlSeparatorRow(stream, 10, 5);
00367     HtmlInOutPortRow(stream, 'E', inb(PINE), inb(PORTE), inb(DDRE), 0xDC);
00368     HtmlSeparatorRow(stream, 10, 5);
00369 
00370     fputs("<tr><th>F</th><td>Status</td>", stream);
00371     HtmlLedRow(stream, 8, 1, inb(PINF), inb(PINF), 0);
00372     fputs("</tr>\r\n", stream);
00373 
00374     fputs_P(foot, stream);
00375     fflush(stream);
00376     return 0;
00377 }
00378 
00379 
00380 /*!
00381  * \brief CGI callback function to display the status of the CPU ports.
00382  *
00383  * Creates HTML code to show the status of CPU ports B, D, E and F.
00384  * The page will be automatically refreshed every 5 seconds.
00385  *
00386  * \image html sport.gif
00387  *
00388  *
00389  *
00390  * This function is called by the HTTP module when a browser requests
00391  * a CGI function, for which this routine has been registered via
00392  * NutRegisterCgi().
00393  *
00394  * \param stream Stream device of the HTTP connection.
00395  * \param req    Pointer to the CGI REQUEST structure. Detailed information
00396  *               is available in the Nut/OS API documentation.
00397  *
00398  * \return 0 on success or -1 in case of any failure.
00399  */
00400 int CpuPortStatus(FILE * stream, REQUEST * req)
00401 {
00402     static prog_char head[] =   /* */
00403         "<html>"                /* */
00404         "<head>"                /* */
00405         "<meta http-equiv=\"refresh\" content=\"5; URL=" PORT_STATUS_CGI "\">"  /* */
00406         "<title>Ethernut CPU Port Status</title>"       /* */
00407         "</head>"               /* */
00408         "<body bgcolor=\"#C7D0D9\"><a href=\"/\">"      /* */
00409         "<img src=\"/enmini.gif\" border=\"0\" width=\"70\" height=\"17\">"     /* */
00410         "</a><div align=\"center\">"    /* */
00411         "<table border=\"1\" cellspacing=\"0\">\r\n"    /* */
00412         "<thead><tr><th rowspan=\"2\"> PORT </th>"      /* */
00413         "<th colspan=\"8\">Bit</th></tr>"       /* */
00414         "<tr><th>7</th><th>6</th><th>5</th><th>4</th><th>3</th>"        /* */
00415         "<th>2</th><th>1</th><th>0</th></tr>"   /* */
00416         "</thead><tfoot>\r\n";
00417 
00418     NutHttpSendHeaderTop(stream, req, 200, "Ok");
00419     NutHttpSendHeaderBot(stream, "text/html", -1);
00420 
00421     fputs_P(head, stream);
00422 
00423     fputs("<tr><th>B</th>", stream);
00424     HtmlLedRow(stream, 8, 1, inb(PINB), inb(PORTB), inb(DDRB));
00425     fputs("</tr>\r\n", stream);
00426 
00427     fputs("<tr><th>D</th>", stream);
00428     HtmlLedRow(stream, 8, 1, inb(PIND), inb(PORTD), inb(DDRD));
00429     fputs("</tr>\r\n", stream);
00430 
00431     fputs("<tr><th>E</th>", stream);
00432     HtmlLedRow(stream, 8, 1, inb(PINE), inb(PORTE), inb(DDRE));
00433     fputs("</tr>\r\n", stream);
00434 
00435     fputs("<tr><th>F</th>", stream);
00436     HtmlLedRow(stream, 8, 1, inb(PINF), inb(PINF), 0);
00437     fputs("</tr>\r\n", stream);
00438 
00439     fputs("</tfoot></table><br></div></body>\r\n</html>", stream);
00440     fflush(stream);
00441     return 0;
00442 }
00443 
00444 
00445 /*!
00446  * \brief CGI callback function to control a shift register output board.
00447  *
00448  * Creates HTML code to show the status of any attached shift register
00449  * output board plus a HTML form to modify the current relay status
00450  * via checkboxes.
00451  *
00452  * The resulting HTML code is send back to the browser. If the submit
00453  * button is clicked on this page, this function will be called again
00454  * to process the checkboxes and display the updated status.
00455  *
00456  * \image html relay.gif
00457  *
00458  *
00459  *
00460  * This function is called by the HTTP module when a browser requests
00461  * a CGI function, for which this routine has been registered via
00462  * NutRegisterCgi().
00463  *
00464  * \param stream Stream device of the HTTP connection.
00465  * \param req    Pointer to the CGI REQUEST structure. Detailed information
00466  *               is available in the Nut/OS API documentation.
00467  *
00468  * \return 0 on success or -1 in case of any failure.
00469  */
00470 int SpiRelayControl(FILE * stream, REQUEST * req)
00471 {
00472     u_char i;
00473     static prog_char head[] = "<html>"  /* */
00474         "<head>"                /* */
00475         "<meta http-equiv=\"expires\" content=\"0\">"   /* */
00476         "<title>Ethernut Shift Register Output</title>" /* */
00477         "</head>"               /* */
00478         "<body bgcolor=\"#C7D0D9\"><a href=\"/\">"      /* */
00479         "<img src=\"/enmini.gif\" border=\"0\" width=\"70\" height=\"17\">"     /* */
00480         "</a><div align=\"center\">";
00481     static prog_char foot[] = "</tfoot></table><br>"    /* */
00482         " <input type=\"submit\" value=\" Set \"> "     /* */
00483         " <input type=\"reset\" value=\" Cancel \"> "   /* */
00484         "</form>\r\n";
00485 
00486     if (spi_no == 255)
00487         SpiDigitalInit(&spi_ni, &spi_no);
00488 
00489     NutHttpSendHeaderTop(stream, req, 200, "Ok");
00490     NutHttpSendHeaderBot(stream, "text/html", -1);
00491 
00492     fputs_P(head, stream);
00493 
00494     if (spi_no) {
00495         if (req->req_query)
00496             ProcessCgiRelayRequest(req->req_query);
00497 
00498         fputs("<form action=\"" RELAY_CONTROL_CGI "\" enctype=\"text/plain\">"  /* */
00499               "<table border=\"1\" cellspacing=\"0\">\r\n"      /* */
00500               "<thead><tr><th> </th><th colspan=\"", stream);
00501         fprintf(stream, "%u", spi_no);
00502         fputs("\">Relay</th></tr><tr><td> </td>", stream);
00503         for (i = 1; i <= spi_no; i++)
00504             fprintf(stream, "<th>%u</th>", i);
00505         fputs("</tr></thead><tfoot>\r\n", stream);
00506 
00507         fputs("<tr><td> </td>", stream);
00508         if (relay_known)
00509             HtmlLedRow(stream, spi_no, 0, relay_status, relay_status, 0xFFFFFFFF);
00510         else
00511             HtmlLedRow(stream, spi_no, 0, relay_status, ~relay_status, 0xFFFFFFFF);
00512         fputs("</tr>\r\n", stream);
00513 
00514         fputs("<tr><td>On</td>", stream);
00515         HtmlCheckboxRow(stream, spi_no, 0, "S", relay_status, 0xFFFFFFFF);
00516         fputs("</tr>\r\n", stream);
00517 
00518         fputs_P(foot, stream);
00519     } else
00520         fputs("No Outputs", stream);
00521     fputs("</div></body>\r\n</html>", stream);
00522     fflush(stream);
00523     return 0;
00524 }
00525 
00526 /*!
00527  * \brief CGI callback function to query a shift register input board.
00528  *
00529  * This function is called by the HTTP helper routines when a browser requests
00530  * a CGI function, for which this routine has been registered via
00531  * NutRegisterCgi().
00532  *
00533  * \image html opto.gif
00534  *
00535  *
00536  *
00537  * Creates HTML code to show the status of the optically isolated inputs
00538  * of an attached input shift register board. The page will be automatically 
00539  * refreshed every 5 seconds.
00540  *
00541  * \param stream Stream device of the HTTP connection.
00542  * \param req    Pointer to the CGI REQUEST structure. Detailed information
00543  *               is available in the Nut/OS API documentation.
00544  *
00545  * \return 0 on success or -1 in case of any failure.
00546  */
00547 int SpiOptoStatus(FILE * stream, REQUEST * req)
00548 {
00549     u_long status;
00550     u_char i;
00551     static prog_char title[] = "<title>Ethernut Shift Register Input</title>"   /* */
00552         "</head><body bgcolor=\"#C7D0D9\"><a href=\"/\">"       /* */
00553         "<img src=\"/enmini.gif\" border=\"0\" width=\"70\" height=\"17\">"     /* */
00554         "</a><div align=\"center\">";
00555 
00556     if (spi_ni == 255)
00557         SpiDigitalInit(&spi_ni, &spi_no);
00558 
00559     NutHttpSendHeaderTop(stream, req, 200, "Ok");
00560     NutHttpSendHeaderBot(stream, "text/html", -1);
00561 
00562     fputs("<html><head>", stream);
00563     if (spi_ni)
00564         fputs("<meta http-equiv=\"refresh\" content=\"5; URL=" OPTO_STATUS_CGI "\">", stream);
00565     fputs_P(title, stream);
00566     if (spi_ni) {
00567         fputs("<table border=\"1\" cellspacing=\"0\">\r\n"      /* */
00568               "<thead><tr><th colspan=\"", stream);
00569         fprintf(stream, "%u", spi_ni);
00570         fputs("\">Input</th></tr><tr>", stream);
00571         for (i = 1; i <= spi_ni; i++)
00572             fprintf(stream, "<th>%u</th>", i);
00573         fputs("</tr></thead><tfoot><tr>\r\n", stream);
00574         status = SpiDigitalGet(spi_ni);
00575         HtmlLedRow(stream, spi_ni, 0, status, status, 0);
00576         fputs("</tfoot></table><br>", stream);
00577     } else
00578         fputs("No Inputs", stream);
00579     fputs("</div></body>\r\n</html>", stream);
00580     fflush(stream);
00581     return 0;
00582 }
00583 
00584 
00585 /*!
00586  * \brief CGI callback function to control the Charon II LEDs.
00587  *
00588  * Creates HTML code to show the status of any attached shift register
00589  * output board plus a HTML form to modify the current relay status
00590  * via checkboxes.
00591  *
00592  * The resulting HTML code is send back to the browser. If the submit
00593  * button is clicked on this page, this function will be called again
00594  * to process the checkboxes and display the updated status.
00595  *
00596  * \image html relay.gif
00597  *
00598  *
00599  *
00600  * This function is called by the HTTP module when a browser requests
00601  * a CGI function, for which this routine has been registered via
00602  * NutRegisterCgi().
00603  *
00604  * \param stream Stream device of the HTTP connection.
00605  * \param req    Pointer to the CGI REQUEST structure. Detailed information
00606  *               is available in the Nut/OS API documentation.
00607  *
00608  * \return 0 on success or -1 in case of any failure.
00609  */
00610 int CharonLedControl(FILE * stream, REQUEST * req)
00611 {
00612     static u_char led_status;
00613     u_char i;
00614     char *name;
00615     char *value;
00616     int pcount = NutHttpGetParameterCount(req);
00617     static prog_char head[] = "<html>"  /* */
00618         "<head>"                /* */
00619         "<meta http-equiv=\"expires\" content=\"0\">"   /* */
00620         "<title>Charon II LEDs</title>" /* */
00621         "</head>"               /* */
00622         "<body bgcolor=\"#C7D0D9\"><a href=\"/\">"      /* */
00623         "<img src=\"/enmini.gif\" border=\"0\" width=\"70\" height=\"17\">"     /* */
00624         "</a><div align=\"center\">";
00625     static prog_char foot[] = "</tfoot></table><br>"    /* */
00626         " <input type=\"submit\" value=\" Set \"> "     /* */
00627         " <input type=\"reset\" value=\" Cancel \"> "   /* */
00628         "</form>\r\n";
00629 
00630     NutHttpSendHeaderTop(stream, req, 200, "Ok");
00631     NutHttpSendHeaderBot(stream, "text/html", -1);
00632 
00633     fputs_P(head, stream);
00634 
00635     led_status = 0;
00636     for (i = 0; i < pcount; i++) {
00637         name = NutHttpGetParameterName(req, i);
00638         value = NutHttpGetParameterValue(req, i);
00639         if (*name == 'S') {
00640             led_status |= 1 << (7 - (*value - '0'));
00641         }
00642     }
00643     if (pcount > 0)
00644         DevBoardShiftLedOut(~led_status);
00645     fputs("<form action=\"" CHARON_CONTROL_CGI "\" enctype=\"text/plain\">"     /* */
00646           "<table border=\"1\" cellspacing=\"0\">\r\n"  /* */
00647           "<thead><tr><th> </th><th colspan=\"8\">"     /* */
00648           "LED</th></tr><tr><td> </td>", stream);
00649     for (i = 1; i <= 8; i++) {
00650         fprintf(stream, "<th>%u</th>", i);
00651     }
00652     fputs("</tr></thead><tfoot>\r\n", stream);
00653 
00654     fputs("<tr><td> </td>", stream);
00655     HtmlLedRow(stream, 8, 0, led_status, led_status, 0xFFFFFFFF);
00656     fputs("</tr>\r\n", stream);
00657 
00658     fputs("<tr><td>On</td>", stream);
00659     HtmlCheckboxRow(stream, 8, 0, "S", led_status, 0xFFFFFFFF);
00660     fputs("</tr>\r\n", stream);
00661 
00662     fputs_P(foot, stream);
00663     fputs("</div></body>\r\n</html>", stream);
00664     fflush(stream);
00665     return 0;
00666 }
00667 
00668 /*!
00669  * \brief CGI callback function to query the Charon II switches.
00670  *
00671  * This function is called by the HTTP helper routines when a browser requests
00672  * a CGI function, for which this routine has been registered via
00673  * NutRegisterCgi().
00674  *
00675  * \image html opto.gif
00676  *
00677  *
00678  *
00679  * Creates HTML code to show the status of the optically isolated inputs
00680  * of an attached SPI input board. The page will be automatically refreshed 
00681  * every 5 seconds.
00682  *
00683  * \param stream Stream device of the HTTP connection.
00684  * \param req    Pointer to the CGI REQUEST structure. Detailed information
00685  *               is available in the Nut/OS API documentation.
00686  *
00687  * \return 0 on success or -1 in case of any failure.
00688  */
00689 int CharonSwitchStatus(FILE * stream, REQUEST * req)
00690 {
00691     u_char status;
00692     u_char i;
00693     static prog_char title[] = "<title>Charon II Switches</title>"      /* */
00694         "</head><body bgcolor=\"#C7D0D9\"><a href=\"/\">"       /* */
00695         "<img src=\"/enmini.gif\" border=\"0\" width=\"70\" height=\"17\">"     /* */
00696         "</a><div align=\"center\">";
00697 
00698     NutHttpSendHeaderTop(stream, req, 200, "Ok");
00699     NutHttpSendHeaderBot(stream, "text/html", -1);
00700 
00701     fputs("<html><head>", stream);
00702     fputs("<meta http-equiv=\"refresh\" content=\"5; URL=" CHARON_STATUS_CGI "\">", stream);
00703     fputs_P(title, stream);
00704     fputs("<table border=\"1\" cellspacing=\"0\">\r\n"  /* */
00705           "<thead><tr><th colspan=\"8\">"       /* */
00706           "Switches</th></tr><tr>", stream);
00707     for (i = 1; i <= 8; i++) {
00708         fprintf(stream, "<th>%u</th>", i);
00709     }
00710     fputs("</tr></thead><tfoot><tr>\r\n", stream);
00711     status = ~DevBoardShiftByteIn();
00712     HtmlLedRow(stream, 8, 0, status, status, 0);
00713     fputs("</tfoot></table><br>", stream);
00714     fputs("</div></body>\r\n</html>", stream);
00715     fflush(stream);
00716     return 0;
00717 }
00718 
00719 
00720 /*@}*/

© 2002-2004 by egnite Software GmbH - visit http://www.ethernut.de/