GNU Info

Info Node: (gawkinet.info)REMCONF

(gawkinet.info)REMCONF


Next: URLCHK Prev: GETURL Up: Some Applications and Techniques
Enter node , (file) or (file)node

REMCONF: Remote Configuration of Embedded Systems
=================================================

   Today, you often find powerful processors in embedded systems.
Dedicated network routers and controllers for all kinds of machinery
are examples of embedded systems. Processors like the Intel 80x86 or
the AMD Elan are able to run multitasking operating systems, such as
XINU or GNU/Linux in embedded PCs.  These systems are small and usually
do not have a keyboard or a display.  Therefore it is difficult to set
up their configuration. There are several widespread ways to set them
up:

   * DIP switches

   * Read Only Memories such as EPROMs

   * Serial lines or some kind of keyboard

   * Network connections via `telnet' or SNMP

   * HTTP connections with HTML GUIs

   In this node, we look at a solution that uses HTTP connections to
control variables of an embedded system that are stored in a file.
Since embedded systems have tight limits on resources like memory, it
is difficult to employ advanced techniques such as SNMP and HTTP
servers. `gawk' fits in quite nicely with its single executable which
needs just a short script to start working.  The following program
stores the variables in a file, and a concurrent process in the
embedded system may read the file. The program uses the
site-independent part of the simple web server that we developed in
Note: A Web Service with Interaction.  As
mentioned there, all we have to do is to write two new procedures
`SetUpServer' and `HandleGET':

     function SetUpServer() {
       TopHeader = "<HTML><title>Remote Configuration</title>"
       TopDoc = "<BODY>\
         <h2>Please choose one of the following actions:</h2>\
         <UL>\
           <LI><A HREF=" MyPrefix "/AboutServer>About this server</A></LI>\
           <LI><A HREF=" MyPrefix "/ReadConfig>Read Configuration</A></LI>\
           <LI><A HREF=" MyPrefix "/CheckConfig>Check Configuration</A></LI>\
           <LI><A HREF=" MyPrefix "/ChangeConfig>Change Configuration</A></LI>\
           <LI><A HREF=" MyPrefix "/SaveConfig>Save Configuration</A></LI>\
         </UL>"
       TopFooter  = "</BODY></HTML>"
       if (ConfigFile == "") ConfigFile = "config.asc"
     }

   The function `SetUpServer' initializes the top level HTML texts as
usual. It also initializes the name of the file that contains the
configuration parameters and their values. In case the user supplies a
name from the command line, that name is used. The file is expected to
contain one parameter per line, with the name of the parameter in
column one and the value in column two.

   The function `HandleGET' reflects the structure of the menu tree as
usual. The first menu choice tells the user what this is all about. The
second choice reads the configuration file line by line and stores the
parameters and their values. Notice that the record separator for this
file is `"\n"', in contrast to the record separator for HTTP. The third
menu choice builds an HTML table to show the contents of the
configuration file just read. The fourth choice does the real work of
changing parameters, and the last one just saves the configuration into
a file:

     function HandleGET() {
       if(MENU[2] == "AboutServer") {
         Document  = "This is a GUI for remote configuration of an\
           embedded system. It is is implemented as one GAWK script."
       } else if (MENU[2] == "ReadConfig") {
         RS = "\n"
         while ((getline < ConfigFile) > 0)
            config[$1] = $2;
         close(ConfigFile)
         RS = "\r\n"
         Document = "Configuration has been read."
       } else if (MENU[2] == "CheckConfig") {
         Document = "<TABLE BORDER=1 CELLPADDING=5>"
         for (i in config)
           Document = Document "<TR><TD>" i "</TD>" \
             "<TD>" config[i] "</TD></TR>"
         Document = Document "</TABLE>"
       } else if (MENU[2] == "ChangeConfig") {
         if ("Param" in GETARG) {            # any parameter to set?
           if (GETARG["Param"] in config) {  # is  parameter valid?
             config[GETARG["Param"]] = GETARG["Value"]
             Document = (GETARG["Param"] " = " GETARG["Value"] ".")
           } else {
             Document = "Parameter <b>" GETARG["Param"] "</b> is invalid."
           }
         } else {
           Document = "<FORM method=GET><h4>Change one parameter</h4>\
             <TABLE BORDER CELLPADDING=5>\
             <TR><TD>Parameter</TD><TD>Value</TD></TR>\
             <TR><TD><input type=text name=Param value=\"\" size=20></TD>\
                 <TD><input type=text name=Value value=\"\" size=40></TD>\
             </TR></TABLE><input type=submit value=\"Set\"></FORM>"
         }
       } else if (MENU[2] == "SaveConfig") {
         for (i in config)
           printf("%s %s\n", i, config[i]) > ConfigFile
         close(ConfigFile)
         Document = "Configuration has been saved."
       }
     }

   We could also view the configuration file as a database. From this
point of view, the previous program acts like a primitive database
server.  Real SQL database systems also make a service available by
providing a TCP port that clients can connect to. But the application
level protocols they use are usually proprietary and also change from
time to time.  This is also true for the protocol that MiniSQL uses.


automatically generated by info2www version 1.2.2.9