Exemplo n.º 1
0
void startServer() {
	/* Initialze lighting service */

	/* Create  a service for us */
	if (gethostname(hostname, INSTANCE_MAX) != 0) {
		fprintf(stderr, "Unable to retrieve the hostname");
		exit(1);
	}
	telldusService = xPL_createService("telldus", "core", hostname);
	xPL_setServiceVersion(telldusService, TELLDUS_VERSION);

	/* Add a responder */
	xPL_addServiceListener(telldusService, lightingRequestHandler, xPL_MESSAGE_COMMAND, "lighting", "request", NULL);
	xPL_addServiceListener(telldusService, lightingCommandHandler, xPL_MESSAGE_COMMAND, "lighting", "basic", NULL);

	/* Install signal traps for proper shutdown */
	signal(SIGTERM, shutdownHandler);
	signal(SIGINT, shutdownHandler);

	/* Enable the service */
	xPL_setServiceEnabled(telldusService, TRUE);
	sendGatewayReadyMessage();

	for (;;) {
		/* Let XPL run */
		xPL_processMessages(-1);
	}
}
Exemplo n.º 2
0
int main(int argc, char **argv) {
  cf = &cfg;
  config_init(cf);
  
  if (!config_read_file(cf, "./pmaxd.conf")) {
            fprintf(stderr, "%s:%d - %s\n",
                config_error_file(cf),
                config_error_line(cf),
                config_error_text(cf));
            config_destroy(cf);
            return(EXIT_FAILURE);
        }

        

         
  /* Our process ID and Session ID */
  pid_t pid = 0, sid = 0;        
  
  int helpOption = 0;
   
  int j=0;
  int k=0;
  struct PlinkBuffer testbuffer;
 
  parseCommandLineArgs(argc, argv); 
        
  /* Fork off the parent process */
  if  (foregroundOption==0) pid = fork();
  if (pid < 0) {
    exit(EXIT_FAILURE);
  }
  /* If we got a good PID, then
  we can exit the parent process. */
  if (pid > 0) {
    exit(EXIT_SUCCESS);
  }
  /* Change the file mode mask */
  umask(0);
        

  initLog(verboseLevel);
       
  DEBUG (LOG_NOTICE, "Program started by User %d", getuid ());
        
  DEBUG (LOG_INFO, "Setting SID"); 
                                     
  /* Create a new SID for the child process */
  if  (foregroundOption==0) sid = setsid();
  if (sid < 0) {
    /* Log the failure */
    DEBUG (LOG_INFO, "Cannot set SID");
    exit(EXIT_FAILURE);
  }

  /* Change the current working directory */
  if ((chdir("/")) < 0) {
    /* Log the failure */
    exit(EXIT_FAILURE);
  }
  
  /* Close out the standard file descriptors */
  if  (foregroundOption==0) {
    DEBUG (LOG_INFO, "Closing std file descriptor");
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);
  }
   
  /* Daemon-specific initialization goes here */
          
        
	struct timeval  tvLastSerialCharTime,tvCurrentTime;
	double          lastSerialCharTime,currentTime;
 	struct PlinkBuffer commandBuffer;
 	commandBuffer.size=0;
 	
 	int eop=0;
	int loop=0;
	unsigned char *bufptr;  /* Current char in buffer */
 	
	DEBUG(LOG_NOTICE,"Starting......");

	gettimeofday(&tvLastSerialCharTime, NULL);
	lastSerialCharTime = tvLastSerialCharTime.tv_sec*1000000 + (tvLastSerialCharTime.tv_usec);  
  
 	initXpl();
	initSocket();
//  initSerialPort();  
	PmaxInit(); 

	DEBUG(LOG_DEBUG,"Starting main loop....");
	

/* read characters into our string buffer until timeout */  
  while (!loop) {
	int maxMsgLength = MAX_BUFFER_SIZE;
   
    if (foregroundOption==1)  //manage keypress if interactive mode
      KeyPressHandling();
       
  	while ((read(fd, commandBuffer.size+commandBuffer.buffer, 1) == 1) && commandBuffer.size < maxMsgLength) {
		DEBUG(LOG_DEBUG, "Received char 0x%02x buf position %d", (int) (commandBuffer.size+commandBuffer.buffer)[0], commandBuffer.size);
		commandBuffer.size++;
		
		/* for "known" messages, limit read to corresponding size */
		if (commandBuffer.size == 2) switch (commandBuffer.buffer[1]) {
			case 0x02:
			case 0x08:
				maxMsgLength = 5;
				break;
			case 0xA5:
			case 0xA7:
			case 0xAA:
				maxMsgLength = 15;
				break;
		}

		gettimeofday(&tvLastSerialCharTime, NULL);
		lastSerialCharTime = tvLastSerialCharTime.tv_sec*1000000 + (tvLastSerialCharTime.tv_usec);
		eop=1;
	}
	
	gettimeofday(&tvCurrentTime, NULL);
	currentTime = tvCurrentTime.tv_sec*1000000 + (tvCurrentTime.tv_usec);
	
	if (eop==1) {
      
		// if timeout, assume packet is finished, and manage it (check format/ deformat/......) 
		if ((currentTime-lastSerialCharTime)> PACKET_TIMEOUT || commandBuffer.size == maxMsgLength) {
			DEBUG(LOG_DEBUG, "Interpreting packet");
			packetManager(&commandBuffer);
			maxMsgLength = MAX_BUFFER_SIZE;
			eop=0;
		}
    }   

	/* check if activity in the last MAX_IDLE_TIME (at the very least should be heartbeat message) */
	if ((currentTime-lastSerialCharTime) > MAX_IDLE_TIME) {
		
		/* try to re-start the TCP connection */
		DEBUG(LOG_INFO, "Reseting TCP connection");
		initSocket();
		lastSerialCharTime = currentTime;
	}

    usleep(IDLE_TIME);
    xPL_processMessages(0);
  }
  
  closelog ();
  exit(EXIT_SUCCESS);
}
Exemplo n.º 3
0
int main(void)
{
  pmaxSystem.status[0]=0;
  pmaxSystem.pmaxstatus[0]=0;
  pmaxSystem.readytoarm[0]=0;
  pmaxSystem.PmaxStatus[0]=0;
  
  int k;
  for (k=0;k<31;k++)
  {
    pmaxSystem.sensor[k].type[0]=0;
    pmaxSystem.sensor[k].alert[0]=0;
    pmaxSystem.sensor[k].PmaxAlarmType[0]=0;
    pmaxSystem.sensor[k].armed[0]=0;                  
    pmaxSystem.sensor[k].alarmed[0]=0;
    pmaxSystem.sensor[k].lowbattery[0]=0;  
    pmaxSystem.sensor[k].enrolled[0]=0;
    pmaxSystem.sensor[k].tampered[0]=0;
    pmaxSystem.sensor[k].id[0]=0;
  } 
  
//	char *data;
	long m,n;
	printf("%s%c%c\n" ,
	"Content-Type:text/html;charset=iso-8859-1",13,10);

	
  xPL_initialize(xPL_getParsedConnectionType());
  webgateway = xPL_createService("viknet", "webgateway", "default");  
  xPL_setServiceVersion(webgateway, "1.0");

  /* Add a responder for time setting */
  xPL_addServiceListener(webgateway, webgatewayMessageHandler, xPL_MESSAGE_ANY, "security", NULL, NULL);
  xPL_setServiceEnabled(webgateway, TRUE);
//  int j;
  
//  for (j=0;j<10;j++)
//  {
  /* Create a message to send */
  xplMessage = xPL_createBroadcastMessage(webgateway, xPL_MESSAGE_COMMAND);
  xPL_setSchema(xplMessage, "security", "request");
  xPL_setMessageNamedValue(xplMessage, "request", "zonelist");	
  xPL_sendMessage(xplMessage);
//  printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
  int i;
  
  
  xplMessage = xPL_createBroadcastMessage(webgateway, xPL_MESSAGE_COMMAND);
  xPL_setSchema(xplMessage, "security", "request");
  xPL_setMessageNamedValue(xplMessage, "request", "gatestat");	
  xPL_sendMessage(xplMessage);
  
  
  for (i=1;i<1000;i++)
  {
    usleep(1000);
    if (nbzone!=0) break;
    xPL_processMessages(0);
  }
  
  
  strcpy(tpzonelist,zonelist);
  char * element;
//  printf("yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\n");
//  printf("zone: %d, %s\n",nbzone,zonelist);
//  for (i=0;i<nbzone;i++)  {
//  char * pch;
  element = strtok (tpzonelist,",");
   while (element != NULL)
  {
//    printf ("%s\n",element);
   
   // xplListAt(element,zonelist,i);
  //  sprintf(element,"%d",i);
  //  printf("element: %s\n",element);
    xplMessage = xPL_createBroadcastMessage(webgateway, xPL_MESSAGE_COMMAND);
    xPL_setSchema(xplMessage, "security", "request");
    xPL_setMessageNamedValue(xplMessage, "request", "zoneinfo");	
    xPL_setMessageNamedValue(xplMessage, "zone", element);	
    xPL_sendMessage(xplMessage);
    
    
    xplMessage = xPL_createBroadcastMessage(webgateway, xPL_MESSAGE_COMMAND);
    xPL_setSchema(xplMessage, "security", "request");
    xPL_setMessageNamedValue(xplMessage, "request", "zonestat");	
    xPL_setMessageNamedValue(xplMessage, "zone", element);	
    xPL_sendMessage(xplMessage);
    
    
    usleep(40000);
    xPL_processMessages(0);
    element = strtok (NULL, ",");  
  }
//  printf("zonelist: %s\n",zonelist);
  for (i=0;i<10;i++)
  { 
  usleep(15000);
  xPL_processMessages(0);
  }      
  printf("{ \"status\":\"%s\",\"pmaxstatus\":\"%s\",\"readytoarm\":\"%s\",\"sensor\":[",pmaxSystem.status,pmaxSystem.pmaxstatus,pmaxSystem.readytoarm);
 
// strcpy(tpzonelist,zonelist);
//  element = strtok (tpzonelist,",");
  i=0;
//  while (element != NULL)
  char tmpbuff[200];
  char buff[6000];
  buff[0]=0;
  for (i=0;i<31;i++)
  {
//    printf ("%s\n",element);
    if ( strcmp(pmaxSystem.sensor[i].id,"")!=0 ) { 
    sprintf(tmpbuff,"{\"zone\":\"%s\",\"type\":\"%s\",\"alert\":\"%s\",\"armed\":\"%s\",\"tamper\":\"%s\",\"low-battery\":\"%s\",\"alarm\":\"%s\"},",
    pmaxSystem.sensor[i].id,
    pmaxSystem.sensor[i].type,
    pmaxSystem.sensor[i].alert,
    pmaxSystem.sensor[i].armed,
    pmaxSystem.sensor[i].tampered,
    pmaxSystem.sensor[i].lowbattery,
    pmaxSystem.sensor[i].alarmed);
    strcat(buff,tmpbuff);
    //element = strtok (NULL, ",");
    //if (element!=NULL)
    
    //i++;
    }
  }
  buff[strlen(buff)-1]=0;
  printf("%s",buff);
  printf("]}"); 
  nbzone=0;
  zonelist[0]=0;

//}  
  
	return 0;  
}       
Exemplo n.º 4
0
int main(void)
{
	char *data;
	long m,n;
	printf("%s%c%c\n",
	"Content-Type:text/html;charset=iso-8859-1",13,10);

//	printf("<h3>Multiplication results</h3>\n");

	data = getenv("QUERY_STRING");

  

	stripSpace(data);
	char schemaclass[500];
	char schematype[500];
	char namedvaluearray[500];
	char name[500];
	char value[500];
	char command[500];
	char varcontent[500];
  char jsoncontent[500];
  char NVelement[500];
//  printf("URL %s<BR>\n",data);
  strcpy(command,data);
  unencode(command);
  findVarInURL(varcontent,data,"xplpacket");
  unencode(varcontent); 
  stripSpace(varcontent);
	
  xPL_initialize(xPL_getParsedConnectionType());
  webgateway = xPL_createService("viknet", "webgateway", "default");  
  xPL_setServiceVersion(webgateway, "1.0");

  
  /* Add a responder for time setting */
  xPL_addServiceListener(webgateway, webgatewayMessageHandler, xPL_MESSAGE_ANY, "security", NULL, NULL);
  xPL_setServiceEnabled(webgateway, TRUE);
  /* Create a message to send */
  xplMessage = xPL_createBroadcastMessage(webgateway, xPL_MESSAGE_COMMAND);

  if (JSONfindObject(schemaclass,varcontent,"msgschemaclass")!=NULL && JSONfindObject(schematype,varcontent,"msgschematype")!=NULL)
    xPL_setSchema(xplMessage, JSONtoString(schemaclass), JSONtoString(schematype));
	else
    xPL_setSchema(xplMessage, "schemaclass", "schematype");	
	
	JSONfindObject(namedvaluearray,varcontent,"namevaluelist");
  int i;
   for (i=0;i<JSONArrayLength(namedvaluearray);i++)
   {
     JSONArrayAt(NVelement,namedvaluearray,i);
	   if ( JSONfindObject(name,NVelement,"name") && JSONfindObject(value,NVelement,"value"))
	   xPL_addMessageNamedValue(xplMessage, JSONtoString(name), JSONtoString(value));	   
   }
   xPL_sendMessage(xplMessage);

 
  usleep(50000);
  xPL_processMessages(0);
	return 0;  
}       
Exemplo n.º 5
0
int c_engine( int argc, char *argv[] )
{
    off_t f_offset;
    int check4poll();
    struct stat stat_buf;
    char spoolfile[100];
    time_t time_now, time_prev;
    long   tmin_now, tmin_prev, thour_now, thour_prev;
    mode_t oldumask;
    extern FILE *fdsout;
    extern FILE *fdserr;
#ifdef HAVE_LIBXPL
    long xpl_poll = configp->engine_poll / 1000;
    Bool xpl_ready = FALSE;
#endif
    
    sprintf( spoolfile, "%s/%s%s", SPOOLDIR, SPOOLFILE, configp->suffix);

    (void) signal(SIGINT, engine_quit /*iquit*/);
    (void) signal(SIGTERM, engine_quit);

    if (setjmp(mjb))
	return(0);

    i_am_state = 1;
    i_am_monitor = 1;
    heyu_parent = D_CMDLINE;

    openlog( "heyu_engine", 0, LOG_DAEMON);
    syslog(LOG_ERR, "engine setting up-\n");

    if ( read_x10state_file() != 0 )
       x10state_init_all();

    time_now = time_prev = time(NULL);
    tmin_now = tmin_prev = (long)time_now / 60L;
    thour_now = thour_prev = (long)time_now / 3600;

    engine_local_setup(E_START);
    fix_tznames();

    f_offset = lseek(sptty, 0, SEEK_CUR);  /* find current position */

    oldumask = umask(configp->log_umask);
    fdsout = freopen(configp->logfile, "a", stdout);
    fdserr = freopen(configp->logfile, "a", stderr);
    umask(oldumask);

#ifdef HAVE_LIBXPL
    /* xPLLib bug? */
    if (xpl_poll == 1000)
        xpl_poll = 999;

    xpl_ready = xpl_init();
#endif

    fprintf(fdsout, "%s Engine started\n", datstrf());
    fflush(fdsout);

    while (1) {
	if ( f_offset == lseek(sptty, 0, SEEK_END) )  {  /* find end of file */
	    if( stat( spoolfile, &stat_buf ) < 0)
	       engine_quit(SIGTERM) /* return(0) */; 

#ifdef HAVE_LIBXPL
            if (xpl_ready)
		xPL_processMessages(xpl_poll);
            else
#endif
	    /* this imposes a delay between the start of new output*/
	    /* It keeps the disk from being thrashed. */
	    microsleep(configp->engine_poll);
	}
	else {
	    if ( fstat( sptty, &stat_buf ) < 0)
	         return(0);
	    lseek(sptty, f_offset, SEEK_SET);
	    check4poll(1,1);
	    f_offset = lseek(sptty, 0, SEEK_CUR);  /* find current position */
	}

        if ( (time_now = time(NULL)) != time_prev ) {
           if ( is_tomorrow(time_now) ) {
              /* Local Midnight. STD Time */
              midnight_tick(time_now);
              set_global_tomorrow(time_now);
           }
           if ( (thour_now = (long)time_now / 3600L) != thour_prev ) {
              /* Once every hour */
              hour_tick(time_now);
              thour_prev = thour_now;
           } 
           if ( (tmin_now = (long)time_now / 60L) != tmin_prev ) {
              /* Once every minute */
              minute_tick(time_now);
              tmin_prev = tmin_now;
           }
           /* Once every second */
           /* Activate countdown timers */
           second_tick(time_now, (long)(time_now - time_prev));
           time_prev = time_now;       
        }
    }
    /* return(0); */
}
Exemplo n.º 6
0
int c_monitor( int argc, char *argv[] )
{
    off_t f_offset;
    int check4poll();
    struct stat stat_buf;
    char spoolfile[100];
    time_t time_now, time_prev;
#ifdef HAVE_LIBXPL
    long xpl_poll = configp->engine_poll / 1000;
    Bool xpl_ready = FALSE;
#endif

    sprintf( spoolfile, "%s/%s%s", SPOOLDIR, SPOOLFILE, configp->suffix);
    (void) signal(SIGCHLD, iquit);
    (void) signal(SIGINT, iquit);
    if (setjmp(mjb))
	return(0);

    i_am_monitor = 1;

    if ( read_x10state_file() != 0 )
       x10state_init_all();

    if ( argc == 3 && strcmp(argv[2], "rfxmeter") == 0 ) {
       /* Disable display except for RFXMeter setup file pointers */
       i_am_monitor = 0;
       i_am_rfxmeter = 1;
       fdsout = fopen("/dev/null", "w");
       fdserr = fopen("/dev/null", "w");
       fprfxo = stdout;
       fprfxe = stderr;
    }
    else {
#ifdef HAVE_LIBXPL
       /* xPLLib bug? */
       if (xpl_poll == 1000)
           xpl_poll = 999;

       xpl_ready = xpl_init();
#endif
       fprintf(stdout, "%s Monitor started\n", datstrf());
       fflush(stdout);
    }
     
    f_offset = lseek(sptty, 0, SEEK_CUR);  /* find current position */

    time_now = time_prev = time(NULL);


    while (1)  {
	if( f_offset == lseek(sptty, 0, SEEK_END) )  {  /* find end of file */
	    if( stat( spoolfile, &stat_buf ) < 0)
	        return(0); 

#ifdef HAVE_LIBXPL
            if (i_am_monitor && xpl_ready)
	        xPL_processMessages(xpl_poll);
            else
#endif
	    /* this imposes a delay between the start of new output*/
	    /* It keeps the disk from being thrashed. */
	    microsleep(configp->engine_poll);
	}
	else {
	    if ( fstat( sptty, &stat_buf ) < 0 )
	         return(0);
	    lseek(sptty, f_offset, SEEK_SET);
	    check4poll(1,1);
	    f_offset = lseek(sptty, 0, SEEK_CUR);  /* find current position */
	}

        /* Activate countdown timers */
        if ( (time_now = time(NULL)) != time_prev ) {
           second_tick(time_now, (long)(time_now - time_prev));
           time_prev = time_now;       
        }
    }
    /* return(0); */
}
Exemplo n.º 7
0
int main(int argc, char *argv[])
{
	int longindex;
	int optchar;
	String p;
	KeyEntryPtr_t e;
	zoneMapPtr_t zm;

	/* Set the program name */
	progName=argv[0];

	/* Parse the arguments. */
	while((optchar=getopt_long(argc, argv, SHORT_OPTIONS, longOptions, &longindex)) != EOF) {
		
		/* Handle each argument. */
		switch(optchar) {
			
			/* Was it a long option? */
			case 0:
				
				/* Hrmm, something we don't know about? */
				fatal("Unhandled long getopt option '%s'", longOptions[longindex].name);
			
			/* If it was an error, exit right here. */
			case '?':
				exit(1);

			/* Was it a config file path ? */
			case 'c':
				confreadStringCopy(configFile, optarg, WS_SIZE - 1);
				debug(DEBUG_ACTION,"New config file path is: %s", configFile);
				break;
		

		
			/* Was it a debug level set? */
			case 'd':

				/* Save the value. */
				debugLvl=atoi(optarg);
				if(debugLvl < 0 || debugLvl > DEBUG_MAX) {
					fatal("Invalid debug level");
				}

				break;

			/* Was it a pid file switch? */
			case 'f':
				confreadStringCopy(pidFile, optarg, WS_SIZE - 1);
				debug(DEBUG_ACTION,"New pid file path is: %s", pidFile);
				configOverride |= CO_PID_FILE;
				break;

			
			/* Was it a help request? */
			case 'h':
				showHelp();
				exit(0);

			/* Specify interface to broadcast on */
			case 'i': 
				confreadStringCopy(interface, optarg, WS_SIZE -1);
				xPL_setBroadcastInterface(interface);
				configOverride |= CO_INTERFACE;

				break;

			case 'u':
				/* Override debug path*/
				confreadStringCopy(debugFile, optarg, WS_SIZE - 1);
				debug(DEBUG_ACTION,"New debug path is: %s", debugFile);
				configOverride |= CO_DEBUG_FILE;
				break;

			/* Was it a no-backgrounding request? */
			case 'n':

				/* Mark that we shouldn't background. */
				noBackground = TRUE;

				break;
			case 'p':
				/* Override com port*/
				confreadStringCopy(comPort, optarg, WS_SIZE - 1);
				debug(DEBUG_ACTION,"New com port is: %s", comPort);
				configOverride |= CO_COM_PORT;
				break;

			/* Was it an instance ID ? */
			case 's':
				confreadStringCopy(instanceID, optarg, WS_SIZE);
				debug(DEBUG_ACTION,"New instance ID is: %s", instanceID);
				configOverride |= CO_INSTANCE_ID;
				break;


			/* Was it a version request? */
			case 'v':
				printf("Version: %s\n", VERSION);
				exit(0);
	

			
			/* It was something weird.. */
			default:
				fatal("Unhandled getopt return value %d", optchar);
		}
	}
	
	/* If there were any extra arguments, we should complain. */

	if(optind < argc) {
		fatal("Extra argument on commandline, '%s'", argv[optind]);
	}

	/* Load the config file */
	if(!(configEntry =confreadScan(configFile, NULL)))
		exit(1);

	/* Parse the general section */

	/* Com port */
	if(!(configOverride & CO_COM_PORT)){
		if((p = confreadValueBySectKey(configEntry, "general", "com-port"))){
			confreadStringCopy(comPort, p, WS_SIZE);
		}	
	}

	/* Debug file */
	if(!(configOverride & CO_DEBUG_FILE)){
		if((p = confreadValueBySectKey(configEntry, "general", "debug-file"))){
			confreadStringCopy(debugFile, p, WS_SIZE);
		}
	
	}

	/* PID file */
	if(!(configOverride & CO_PID_FILE)){
		if((p = confreadValueBySectKey(configEntry, "general", "pid-file"))){
			confreadStringCopy(pidFile, p, WS_SIZE);
		}
	
	}

	/* Instance ID */
	if(!(configOverride & CO_INSTANCE_ID)){
		if((p =  confreadValueBySectKey(configEntry, "general", "instance-id"))){
			confreadStringCopy(instanceID, p, WS_SIZE);
		}	
	}


	/* Interface */
	if(!(configOverride & CO_INTERFACE)){
		if((p = confreadValueBySectKey(configEntry, "general", "interface"))){
			confreadStringCopy(interface, p, WS_SIZE);
		}	
	}

	/* Build Zone Map */
	
	if(!(e = confreadGetFirstKeyBySection(configEntry, "zone-map")))
		fatal("A valid zone-map section and at least one entry must be defined in the config file");
	for(; e; e = confreadGetNextKey(e)){
		String plist[3];
		const String key = confreadGetKey(e);
		const String value = confreadGetValue(e);
		/* Allocate a zone struct */
		if(!(zm = mallocz(sizeof(zoneMap_t))))
			MALLOC_ERROR;
			
		/* Get the zone number */
		if(!str2uns(key, &zm->zone_num, 1, 99))
			syntax_error(e, configFile,"invalid zone number");
			
		/* Get the parameters */
		if(3 != splitString(value, plist, ',', 3))
			syntax_error(e, configFile, "3 parameters required");
		if(!(zm->zone_name = strdup(plist[0])))
			MALLOC_ERROR;
		if(!(zm->zone_type = strdup(plist[1])))
			MALLOC_ERROR;
		if(!(zm->alarm_type = strdup(plist[2])))
			MALLOC_ERROR;
			
		/* Hash the zone name */
		zm->zone_name_hash = confreadHash(zm->zone_name);
		
			
		/* Free the split string */
		free(plist[0]);
		
		/* Insert the entry into the zone list */
		if(!zoneMapHead)
			zoneMapHead = zoneMapTail = zm;
		else{
			zm->prev = zoneMapTail;
			zoneMapTail->next = zm;
			zoneMapTail = zm;
		}
		zoneCount++;
	}

	/* EXP zone mapping */

	for(e =  confreadGetFirstKeyBySection(configEntry, "exp-map"); e; e = confreadGetNextKey(e)){
		expMapPtr_t emp;
		const String keyString = confreadGetKey(e);
		const String zone = confreadGetValue(e);
		String plist[3];
		unsigned expaddr, expchannel;

		/* Check the key and zone strings */
		if(!(keyString) || (!zone))
			syntax_error(e, configFile, "key or zone missing");


		/* Split the address and channel */
		plist[0] = NULL;
		if(2 != splitString(keyString, plist, ',', 2))
			syntax_error(e, configFile, "left hand side needs 2 numbers separated by a comma");

		/* Convert and check address */
		if(!str2uns(plist[0], &expaddr, 1, 99))
			syntax_error(e, configFile,"address is limited from 1 - 99");


		/* Convert and check channel */
		if(!str2uns(plist[1], &expchannel, 1, 99))
			syntax_error(e, configFile,"channel is limited from 1 - 99");
			

		/* debug(DEBUG_ACTION, "Address: %u, channel: %u, zone: %s", expaddr, expchannel, zone); */
		
		/* Look up zone to ensure it is defined */
		
		if(!(zm = zoneLookup(zone)))
			syntax_error(e, configFile, "Zone must be defined in zone-map section");
		

		/* Get memory for entry */
		if(!(emp = mallocz(sizeof(expMap_t))))
			MALLOC_ERROR;

		/* Initialize entry */
		emp->zone_entry = zm;
		emp->addr = expaddr;
		emp->channel = expchannel;
		if(!(emp->zone = strdup(zone)))
			MALLOC_ERROR;

		/* Insert into list */
		if(!expMapHead){
			expMapHead = expMapTail = emp;
		}
		else{
			expMapTail->next = emp;
			emp->prev = expMapTail;
			expMapTail = emp;
		}

		/* Free parameter string */
		if(plist[0])
			free(plist[0]);
	}


	/* Turn on library debugging for level 5 */
	if(debugLvl >= 5)
		xPL_setDebugging(TRUE);

 	/* Make sure we are not already running (.pid file check). */
	if(pid_read(pidFile) != -1) {
		fatal("%s is already running", progName);
	}

	/* Check to see the serial device exists before we fork */
	if(!serio_check_node(comPort))
		fatal("Serial device %s does not exist or its permissions are not allowing it to be used.", comPort);

	/* Fork into the background. */

	if(!noBackground) {
		int retval;
		debug(DEBUG_STATUS, "Forking into background");

    		/* 
		* If debugging is enabled, and we are daemonized, redirect the debug output to a log file if
    		* the path to the logfile is defined
		*/

		if((debugLvl) && (debugFile[0]))                          
			notify_logpath(debugFile);

		/* Fork and exit the parent */

		if((retval = fork())){
      			if(retval > 0)
				exit(0);  /* Exit parent */
			else
				fatal_with_reason(errno, "parent fork");
    		}



		/*
		* The child creates a new session leader
		* This divorces us from the controlling TTY
		*/

		if(setsid() == -1)
			fatal_with_reason(errno, "creating session leader with setsid");


		/*
		* Fork and exit the session leader, this prohibits
		* reattachment of a controlling TTY.
		*/

		if((retval = fork())){
			if(retval > 0)
        			exit(0); /* exit session leader */
			else
				fatal_with_reason(errno, "session leader fork");
		}

		/* 
		* Change to the root of all file systems to
		* prevent mount/unmount problems.
		*/

		if(chdir("/"))
			fatal_with_reason(errno, "chdir to /");

		/* set the desired umask bits */

		umask(022);
		
		/* Close STDIN, STDOUT, and STDERR */

		close(0);
		close(1);
		close(2);
		} 

	/* Start xPL up */
	if (!xPL_initialize(xPL_getParsedConnectionType())) {
		fatal("Unable to start xPL lib");
	}

	/* Initialize xplrcs service */

	/* Create a service and set our application version */
	xplService = xPL_createService("hwstar", "xplademco", instanceID);
  	xPL_setServiceVersion(xplService, VERSION);

	/*
	* Create a status message object
	*/

  	xplStatusMessage = xPL_createBroadcastMessage(xplService, xPL_MESSAGE_STATUS);
  
	/*
	* Create trigger message objects
	*/

	/* security.gateway */
	if(!(xplEventTriggerMessage = xPL_createBroadcastMessage(xplService, xPL_MESSAGE_TRIGGER)))
		fatal("Could not initialize security.gateway trigger");
	xPL_setSchema(xplEventTriggerMessage, "security", "gateway");

	/* security.zone */
	if(!(xplZoneTriggerMessage = xPL_createBroadcastMessage(xplService, xPL_MESSAGE_TRIGGER)))
		fatal("Could not initialize security.zone trigger");
	xPL_setSchema(xplZoneTriggerMessage, "security", "zone");


  	/* Install signal traps for proper shutdown */
 	signal(SIGTERM, shutdownHandler);
 	signal(SIGINT, shutdownHandler);

	/* Initialize the COM port */
	
	if(!(serioStuff = serio_open(comPort, COM_BAUD_RATE)))
		fatal("Could not open com port: %s", comPort);


	/* Flush any partial commands */
	serio_printf(serioStuff, "\r");
	usleep(100000);
	serio_flush_input(serioStuff);

	/* Ask xPL to monitor our serial device */
	if(xPL_addIODevice(serioHandler, 1234, serio_fd(serioStuff), TRUE, FALSE, FALSE) == FALSE)
		fatal("Could not register serial I/O fd with xPL");

	/* Add 1 second tick service */
	xPL_addTimeoutHandler(tickHandler, 1, NULL);

  	/* And a listener for all xPL messages */
  	xPL_addMessageListener(xPLListener, NULL);


 	/* Enable the service */
  	xPL_setServiceEnabled(xplService, TRUE);

	/* Update pid file */
	if(pid_write(pidFile, getpid()) != 0) {
		debug(DEBUG_UNEXPECTED, "Could not write pid file '%s'.", pidFile);
	}




 	/** Main Loop **/

	for (;;) {
		/* Let XPL run forever */
		xPL_processMessages(-1);
  	}

	exit(1);
}