server/server.c

00001 /*
00002  * Copyright Ian Burnett 2005, 2006.
00003  *
00004  * This file is part of Ian's Interactive LCD controller (IILC).
00005  * 
00006  * IILC is free software; you can redistribute it and/or modify it under
00007  * the terms of the GNU General Public License as published by the Free
00008  * Software Foundation; either version 2 of the License, or (at your
00009  * option) any later version.
00010  *
00011  * IILC is distributed in the hope that it will be useful, but WITHOUT
00012  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00014  * for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License along
00017  * with IILC; if not, write to the Free Software Foundation, Inc.,
00018  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
00019  */
00020 
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <time.h>
00024 #include <string.h>
00025 
00026 #if defined(_WIN32)
00027 #   include "pthread_w32.h"
00028 #else
00029 #   include <pthread.h>
00030 #   include <errno.h>
00031 #endif
00032 
00033 #include "lcd.h"
00034 #include "config.h"
00035 #include "trace.h"
00036 #include "vector.h"
00037 #include "screen.h"
00038 #include "module.h"
00039 #include "display.h"
00040 #include "parserImpl.h"
00041 
00042 
00043 #define IILC_MODULE MODULE_TYPE_APP
00044 
00045 #if defined(_WIN32)
00046 #   define DEFAULT_CONFIG_FILE      "iilc.conf"
00047 #else
00048 #   define DEFAULT_CONFIG_FILE      "/etc/iilc.conf"
00049 #endif
00050 
00051 
00052 static int processConfigFile(LPCONFIG_FILE pFile, 
00053                              LPVECTOR pVector);
00054 
00055 static int processConfigDisplay(LPCONFIG_DISPLAY pDisplay, 
00056                                 LPDISPLAY * ppDisplay);
00057 
00058 
00059 typedef struct _tag_module_map
00060 {
00061     const char * pszModuleName;
00062 
00063     LPMODULE pModule;
00064 }
00065 MODULE_MAP;
00066 
00067 int main(int argc, char ** argv)
00068 {
00069     /* One configuration file per application instance */
00070     LPCONFIG_FILE pFile = NULL;
00071 
00072     /* A vector which will contain all the displays we configure */
00073     LPVECTOR pDisplayVector = NULL;
00074     
00075     /* Handy loop variables */
00076     int i = 0, nCount = 0;
00077 
00078     /* Generic return code */
00079     int rc = 0;
00080 
00081     IILC_TRACE_ENTRY(IILC_MODULE, T_main);
00082 
00083     if (argc > 1) {
00084         printf("%s\n", argv[1]);
00085         g_bSev0Enabled = 1;
00086         g_bSev1Enabled = 1;
00087     }
00088 
00089     /* Create a vector to hold all the displays setup by the config file */
00090     vectorCreate(&pDisplayVector);
00091 
00092     /*
00093      * Processes the config file. This step performs most of the syntax checking and
00094      * very little of the contextual checking on the config file.
00095      */
00096     rc = parserParse(&pFile, "../conf/lcd.conf");
00097     if (rc > 0) { goto end_of_function; }
00098 
00099     /*
00100      * Verify the data structure is valid. This step does no syntax checking, but ensures
00101      * that things like cross-references within the file are valid and that mistakes such
00102      * as duplicated entries are caught. This second step is required if we want an LALR
00103      * parser, but wish to allow the user to define things in any order they desire.
00104      */
00105     rc = configFileValidate(pFile);
00106     if (rc > 0) { goto end_of_function; }
00107 
00108     /*
00109      * Performs the setup stage which takes the memory model and converts it into running
00110      * code. At this point, everything is assumed to be correct. There is the small issue
00111      * where things cannot be determined until we connect to the display (such as number of
00112      * temperature sensors connected), but that can be dealt with as and when necessary.
00113      */
00114     rc = processConfigFile(pFile, pDisplayVector);
00115     if (rc > 0) { goto end_of_function; }
00116 
00117 
00118     /* Start each of the display instances */
00119     vectorGetSize(pDisplayVector, &nCount);
00120     for (i = 0; (i < nCount) && (rc == 0); i++) {
00121         LPDISPLAY pDisplay = NULL;
00122         rc = vectorGetElementAt(pDisplayVector, i, (void **) &pDisplay);
00123         if (!rc) {
00124             rc = displayStart(pDisplay);
00125         }
00126     }
00127 
00128     if (rc) {
00129         goto end_of_function;
00130     }
00131 
00132     /* Wait around for a bit (just demo code at the minute) */
00133     SLEEP(10000);
00134 
00135     /* Stop each of the display instances */
00136     for (i = 0; (i < nCount) && (rc == 0); i++) {
00137 
00138         LPDISPLAY pDisplay = NULL;
00139 
00140         /* Get each display */
00141         rc = vectorGetElementAt(pDisplayVector, i, (void **) &pDisplay);
00142 
00143         /* Remove from the vector */
00144         vectorRemove(pDisplayVector, pDisplay);
00145 
00146         /* Stop it... */
00147         if (!rc) {
00148             rc = displayStop(pDisplay);
00149         }
00150 
00151         /* ... and dispose. */
00152         if (!rc) {
00153             rc = displayDispose(&pDisplay);
00154         }
00155     }
00156 
00157     if (rc) {
00158         goto end_of_function;
00159     }
00160 
00161     /* Dispose of the vector */
00162     vectorDestroy(&pDisplayVector);
00163 
00164 end_of_function:
00165 
00166     /* Delete the config file instance */
00167     if (pFile != NULL) {
00168         configFileDispose(&pFile);
00169     }
00170 
00171     IILC_TRACE_EXIT_RC(rc);
00172     return rc;
00173 }
00174 
00175 
00176 
00177 /****************************************************************************/
00178 /*                                                                          */
00179 /* Functions to convert the memory model into something useful              */
00180 /*                                                                          */
00181 /****************************************************************************/
00182 
00183 
00189 int processConfigFile(LPCONFIG_FILE pConfigFile, LPVECTOR pVector)
00190 {
00191     int rc = 0;
00192     int i = 0, nCount = 0;
00193 
00194     IILC_TRACE_ENTRY(IILC_MODULE, T_processConfigFile);
00195     traceDebug(IILC_TRACE_CONTEXT, "pFile %p, pVector %p", pConfigFile, pVector);
00196 
00197     /* Number of displays in config file */
00198     rc = configFileGetDisplayCount(pConfigFile, &nCount);
00199     if (rc) { goto end_of_function; }
00200 
00201     /* Check we have something configured */
00202     if (nCount == 0) {
00203         rc = ERR_INVALID_CONFIG;
00204         traceError(IILC_TRACE_CONTEXT, "No displays configured for application. Exiting");
00205         goto end_of_function;
00206     }
00207 
00208     /* Initialise each display */
00209     for (i = 0; (i < nCount) && (rc == 0); i++) {
00210 
00211         LPCONFIG_DISPLAY pConfigDisplay = NULL;
00212         LPDISPLAY        pDisplay       = NULL;
00213 
00214         /* Get the display configuration information out of the model */
00215         rc = configFileGetDisplay(pConfigFile, i, &pConfigDisplay);
00216         if (!rc) {
00217             rc = processConfigDisplay(pConfigDisplay, &pDisplay);
00218         }
00219 
00220         /* Add this display to the vector */
00221         vectorAdd(pVector, pDisplay);
00222     }
00223 
00224 end_of_function:
00225 
00226     IILC_TRACE_EXIT_RC(rc);
00227     return rc;
00228 }
00229 
00230 
00235 int processConfigDisplay(LPCONFIG_DISPLAY pConfigDisplay, LPDISPLAY * ppDisplay)
00236 {
00237     int rc     = 0;
00238     int i = 0, j = 0;
00239     int nCount = 0;
00240     int nModuleCount = 0;
00241 
00242     LPCONFIG_DEVICE pConfigDevice = NULL;
00243 
00244     LPDISPLAY pDisplay = NULL;
00245     MODULE_MAP * pModuleMap = NULL;
00246 
00247     /* Configuration information obtained from the device data */
00248     char * pszClass = NULL;
00249     char * pszPort  = NULL;
00250 
00251     IILC_TRACE_ENTRY(IILC_MODULE, T_processConfigDisplay);
00252     traceDebug(IILC_TRACE_CONTEXT, 
00253         "pConfigDisplay %p, ppDisplay %p", pConfigDisplay, ppDisplay);
00254 
00255     /* ----- Device configuration ----- */
00256 
00257     /* Get the configuration of the device to use */
00258     configDisplayGetDevice(pConfigDisplay, &pConfigDevice);
00259 
00260     /* Extract the necessary information */
00261     configDeviceGetClass(pConfigDevice, &pszClass);
00262     configDeviceGetPort(pConfigDevice, &pszPort);
00263 
00264     /* Create the display object */
00265     displayCreate(pszClass, pszPort, &pDisplay);
00266 
00267 
00268     /* ----- Module configuration ----- */
00269 
00270     /* How many modules are involved here? */
00271     configDisplayGetModuleCount(pConfigDisplay, &nModuleCount);
00272 
00273     /* Alloc some space for this */
00274     pModuleMap = (MODULE_MAP *) calloc(nCount, sizeof(MODULE_MAP));
00275 
00276     for (i = 0; (i < nModuleCount) && (rc == 0); i++) {
00277 
00278         LPCONFIG_MODULE pConfigModule = NULL;
00279         const char * pszModuleName = NULL;
00280         LPMODULE pModule = NULL;
00281         int nReports = 0;
00282 
00283         /* Get the specific module */
00284         configDisplayGetModule(pConfigDisplay, i, &pConfigModule);
00285 
00286         /* Get the module configuration information */
00287         configModuleGetLibrary(pConfigModule, &pszModuleName);
00288 
00289         /* Load the module */
00290         moduleInit(pszModuleName, &pModule);
00291 
00292         /* Store information away for later use */
00293         pModuleMap[i].pszModuleName = pszModuleName;
00294         pModuleMap[i].pModule       = pModule;
00295 
00296         /* --- Setup the entities this module receives reports for --- */
00297 
00298         /* Get the number of objects this module wishes to receive reports for */
00299         configModuleGetReportCount(pConfigModule, &nReports);
00300         for (j = 0; (j < nReports) && (rc == 0); j++) {
00301 
00302             LPCONFIG_OBJECT pConfigObject = NULL;
00303             enum displayObjectType type;
00304             unsigned int nId;
00305             char * pszReportName = NULL;
00306 
00307             /* Get the configuration of this object */
00308             configModuleGetReportObject(pConfigModule, j, &pConfigObject);
00309 
00310             /* Get the configuration information */
00311             configObjectGetId(pConfigObject, &nId);
00312             configObjectGetName(pConfigObject, &pszReportName);
00313 
00314             /* Decide what sort of action this should take */
00315             configObjectGetType(pConfigObject, &type);
00316             switch (type) {
00317 
00318             case OBJECT_TYPE_FAN:
00319                 displayAddFanReportListener(pDisplay, nId, pModule, pszReportName);
00320                 break;
00321 
00322             case OBJECT_TYPE_TEMP:
00323                 displayAddTempReportListener(pDisplay, nId, pModule, pszReportName);
00324                 break;
00325 
00326             case OBJECT_TYPE_LED: /* LEDs don't get reported */
00327             default:
00328                 break;
00329             }
00330 
00331         }
00332 
00333 
00334         /* --- Setup the virtual entities that this module provides --- */
00335 
00336 
00337         /* --- Setup the controlling links --- */
00338 
00339         //displaySetLEDController(pDisplay, nId, pModule);
00340 
00341     }
00342 
00343 
00344     /* ----- Screen configuration ----- */
00345 
00346 
00347     /* How many screens are involved here? */
00348     configDisplayGetScreenCount(pConfigDisplay, &nCount);
00349     for (i = 0; (i < nCount) && (rc == 0); i++) {
00350 
00351         LPCONFIG_SCREEN pConfigScreen = NULL;
00352         LPSCREEN        pScreen       = NULL;
00353         int nWindowCount;
00354 
00355         /* Create a new screen object to manipulate */
00356         screenCreate(&pScreen, 20, 4);
00357 
00358         /* Get the next screen information from the config object */
00359         configDisplayGetScreen(pConfigDisplay, i, &pConfigScreen);
00360 
00361         /* How many windows exist in this screen? */
00362         configScreenGetWindowCount(pConfigScreen, &nWindowCount);
00363         for (j = 0; (j < nWindowCount) && (rc == 0); j++) {
00364 
00365             LPCONFIG_WINDOW pConfigWindow = NULL;
00366             LPMODULE        pModule       = NULL;
00367             int x, y, width, height;
00368             const char * pszModuleName = NULL;
00369             int m = 0;
00370 
00371             /* Get the next window */
00372             configScreenGetWindow(pConfigScreen, j, &pConfigWindow);
00373 
00374             /* Get the various bits of information about it */
00375             configWindowGetLocation(pConfigWindow, &x, &y);
00376             configWindowGetSize(pConfigWindow, &width, &height);
00377             
00378             /* Get the module used to control this window */
00379             configWindowGetModuleName(pConfigWindow, &pszModuleName);
00380 
00381             /* Lookup the actual module we've mapped to this config object */
00382             for (m = 0; m < nModuleCount; m++) {
00383                 if (strcmp(pModuleMap[m].pszModuleName, pszModuleName) == 0) {
00384                     pModule = pModuleMap[m].pModule;
00385                     break;
00386                 }
00387             }
00388 
00389             /* Found a match? */
00390             if (pModule != NULL) {
00391 
00392                 /* Add to the main screen */
00393                 screenAddWindow(pScreen, x, y, width, height, pModule);
00394             }
00395             else {
00396                 printf("Module %s not found!\n", pszModuleName);
00397             }
00398         }
00399 
00400         /* Add the fully-configured screen to the display */
00401         displayScreenAdd(pDisplay, pScreen);
00402     }
00403 
00404 
00405     /* ----- Final tidy-up ----- */
00406 
00407     /* Return to the caller */
00408     *ppDisplay = pDisplay;
00409 
00410 
00411     IILC_TRACE_EXIT_RC(rc);
00412     return rc;
00413 }
00414 
00415 

Generated on Mon Jul 17 01:36:12 2006 for IILC by  doxygen 1.4.6