Server communication seems ok, can handle server shutdowns too.

Wed, 23 Apr 2014 17:19:00 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Wed, 23 Apr 2014 17:19:00 +0200
changeset 8
e584bc0177df
parent 7
d74b26b2f217
child 9
91218bc77abc

Server communication seems ok, can handle server shutdowns too.

lib/mbselib.h file | annotate | diff | comparison | revisions
lib/rdconfig.c file | annotate | diff | comparison | revisions
thermometers/Makefile file | annotate | diff | comparison | revisions
thermometers/main.c file | annotate | diff | comparison | revisions
--- a/lib/mbselib.h	Wed Apr 23 14:25:09 2014 +0200
+++ b/lib/mbselib.h	Wed Apr 23 17:19:00 2014 +0200
@@ -8,13 +8,21 @@
 #include <string.h>
 #include <ctype.h>
 #include <sys/types.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <getopt.h>
+
+#include <mosquitto.h>
+
 
 #define TRUE 1
 #define FALSE 0
 
+#define MBSE_SS(x) (x)?(x):"(null)"
+
 /* rdconfig.c */
-#define S(x) (x)?(x):"(null)"
-
 typedef struct _key_list {
     char	*key;
     int		(*prc)(char **);
@@ -24,14 +32,13 @@
 
 typedef struct _sys_config {
     char	*name;			/* Configuration name		*/
-    char	*mosq_server;		/* mosquitto server hostname	*/
+    char	*mosq_host;		/* mosquitto server hostname	*/
     int		mosq_port;		/* mosquitto server port	*/
 } sys_config;
 
 
 void killconfig(void);
-int  rdconfig(char *);
-int  wrconfig(char *);
+int  rdconfig(void);
 
 
 /* xutil.c */
--- a/lib/rdconfig.c	Wed Apr 23 14:25:09 2014 +0200
+++ b/lib/rdconfig.c	Wed Apr 23 17:19:00 2014 +0200
@@ -23,19 +23,11 @@
 #include "../config.h"
 #include "mbselib.h"
 
-// #define	DEBUG_CONFIG	1
 
-
-extern int	DebugEmu;
-extern char	*Private_Path;
-
+bool		debug = FALSE;
 static char	*mypath;
 static char	*k, *v;
 static int	linecnt = 0;
-
-extern int	MustSave;
-
-
 sys_config	Config;			/* System configuration		*/
 
 
@@ -45,14 +37,14 @@
 //static int getbyt(char **);
 //static int gethex(char **);
 
-
+#define XSTR(x) #x
+#define STR(x) XSTR(x)
 
 /*
  * System configuration table
  */
 key_list keytab[] = {
-    {(char *)"name",		getstr,		&Config.name},
-    {(char *)"mosq_server",	getstr,		&Config.mosq_server},
+    {(char *)"mosq_host",	getstr,		&Config.mosq_host},
     {(char *)"mosq_port",	getint,		(char **)&Config.mosq_port},
     {NULL,			NULL,		NULL}
 };
@@ -65,47 +57,15 @@
 	free(Config.name);
     Config.name = NULL;
 
+    if (Config.mosq_host)
+	free(Config.mosq_host);
+    Config.mosq_host= (char *)"localhost";
+    Config.mosq_port = 1883;
 }
 
 
 
-int wrconfig(char *machine)
-{
-    FILE	*fp;
-
-    /*
-     * Get config from the system path
-     */
-    mypath = xstrcpy(Private_Path);
-    mypath = xstrcat(mypath, (char *)"/data/machines/");
-    mypath = xstrcat(mypath, machine);
-    mypath = xstrcat(mypath, (char *)".conf");
-
-    if ((fp = fopen(mypath, "w")) == NULL) {
-//	Log_Msg("[rdconfig] could not rewrite %s", mypath);
-	return 1;
-    }
-
-    fprintf(fp, "# Configuration file for EC65K %s\n", VERSION);
-    fprintf(fp, "# Machine: `%s'\n", machine);
-    fprintf(fp, "#\n");
-//    fprintf(fp, "description        %s\n", Config.description);
-//    fprintf(fp, "\n");
-//    fprintf(fp, "# 65(C)02 CPU\n");
-//    fprintf(fp, "#\n");
-
-    fprintf(fp, "# End of generated configuration\n");
-    fclose(fp);
-    free(mypath);
-    mypath = NULL;
-    MustSave = FALSE;
-
-    return 0;
-}
-
-
-
-int rdconfig(char *machine) 
+int rdconfig(void) 
 {
     char	buf[256], *p;
     FILE	*fp;
@@ -116,13 +76,11 @@
     /*
      * Get config from the system path
      */
-    mypath = xstrcpy(Private_Path);
-    mypath = xstrcat(mypath, (char *)"/data/machines/");
-    mypath = xstrcat(mypath, machine);
-    mypath = xstrcat(mypath, (char *)".conf");
+    mypath = xstrcpy((char *)STR(ETCDIR));
+    mypath = xstrcat(mypath, (char *)"/mbsepi-apps.conf");
 
     if ((fp = fopen(mypath, "r")) == NULL) {
-//	Log_Msg("[rdconfig] could not open %s", mypath);
+	syslog(LOG_NOTICE, "rdconfig: could not open %s", mypath);
 	return 1;
     }
 
@@ -130,7 +88,7 @@
     while (fgets(buf, sizeof(buf) -1, fp)) {
 	linecnt++;
 	if (*(p = buf + strlen(buf) -1) != '\n') {
-//	    Log_Msg("[rdconfig] %s(%d): \"%s\" - line too long", mypath, linecnt, buf);
+	    syslog(LOG_NOTICE, "rdconfig: %s(%d): \"%s\" - line too long", mypath, linecnt, buf);
 	    rc = 1;
 	    break;
 	}
@@ -157,7 +115,7 @@
 		break;
 
 	if (keytab[i].key == NULL) {
-//	    Log_Msg("[rdconfig] %s(%d): %s %s - unknown keyword", mypath, linecnt, S(k), S(v));
+	    syslog(LOG_NOTICE, "rdconfig: %s(%d): %s %s - unknown keyword", mypath, linecnt, MBSE_SS(k), MBSE_SS(v));
 	    rc = 1;
 	    break;
 	} else if ((keytab[i].prc(keytab[i].dest))) {
@@ -170,7 +128,6 @@
 
     free(mypath);
     mypath = NULL;
-    MustSave = FALSE;
 
     return rc;
 }
@@ -179,7 +136,9 @@
 
 static int getstr(char **dest)
 {
-//    Log_Msg("[rdconfig] getstr: %s(%d): %s %s", mypath, linecnt, S(k), S(v));
+    if (debug)
+	syslog(LOG_NOTICE, "rdconfig: getstr: %s(%d): %s %s", mypath, linecnt, MBSE_SS(k), MBSE_SS(v));
+
     *dest = xstrcpy(v);
     return 0;
 }
@@ -188,10 +147,12 @@
 
 static int getint(char **dest)
 {
-//    Log_Msg("[rdconfig] getint: %s(%d): %s %s", mypath, linecnt, k, v);
-//    if (strspn(v,"0123456789") != strlen(v)) 
-//	Log_Msg("[rdconfig] %s(%d): %s %s - bad numeric", mypath, linecnt, S(k), S(v));
-//    else 
+    if (debug)
+	syslog(LOG_NOTICE, "rdconfig: getint: %s(%d): %s %s", mypath, linecnt, MBSE_SS(k), MBSE_SS(v));
+
+    if (strspn(v,"0123456789") != strlen(v)) 
+	syslog(LOG_NOTICE, "rdconfig: %s(%d): %s %s - bad numeric", mypath, linecnt, MBSE_SS(k), MBSE_SS(v));
+    else 
 	*((int*)dest)=atoi(v);
     return 0;
 }
--- a/thermometers/Makefile	Wed Apr 23 14:25:09 2014 +0200
+++ b/thermometers/Makefile	Wed Apr 23 17:19:00 2014 +0200
@@ -5,6 +5,7 @@
 SRCS		= main.c 
 HDRS		= main.h 
 OBJS		= main.o 
+SLIBS		= ../lib/libmbse.a
 TARGET		= thermometers
 OTHER		= Makefile
 
@@ -15,8 +16,8 @@
 
 all:		${TARGET}
 
-thermometers:	${OBJS}
-		${CC} -o thermometers ${OBJS} ${LDFLAGS} ${LIBS}
+thermometers:	${OBJS} ${SLIBS}
+		${CC} -o thermometers ${OBJS} ${LDFLAGS} ${LIBS} ${SLIBS}
 
 clean:
 		rm -f ${TARGET} *.o *.h~ *.c~ core filelist Makefile.bak
@@ -53,5 +54,5 @@
 
 # DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT
 # Dependencies generated by make depend
-main.o: main.h
+main.o: ../lib/mbselib.h main.h
 # End of generated dependencies
--- a/thermometers/main.c	Wed Apr 23 14:25:09 2014 +0200
+++ b/thermometers/main.c	Wed Apr 23 17:19:00 2014 +0200
@@ -20,18 +20,7 @@
  * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  *****************************************************************************/
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <string.h>
-#include <errno.h>
-
-#include <mosquitto.h>
-
-
+#include "../lib/mbselib.h"
 #include "main.h"
 
 
@@ -51,13 +40,15 @@
 static int last_mid = -1;
 static int last_mid_sent = -1;
 static bool connected = true;
-//static char *username = NULL;
-//static char *password = NULL;
 static bool disconnect_sent = false;
-static bool quiet = false;
-static bool debug = false;
 static bool shutdown = false;
 
+extern bool		debug;
+extern sys_config	Config;
+
+int server(void);
+void help(void);
+void die(int);
 
 
 void help(void)
@@ -72,13 +63,13 @@
 void die(int onsig)
 {
     switch (onsig) {
-	case SIGHUP:	fprintf(stdout, "[main] Hangup detected\n");
+	case SIGHUP:	syslog(LOG_NOTICE, "Got SIGHUP, shutting down");
 			break;
-	case SIGINT:	fprintf(stdout, "[main] Interrupt from keyboard\n");
+	case SIGINT:	syslog(LOG_NOTICE, "Keyboard interrupt, shutting down");
 			break;
-	case SIGTERM:	fprintf(stdout, "[main] Termination signal received\n");
+	case SIGTERM:	syslog(LOG_NOTICE, "Got SIGTERM, shutting down");
 			break;
-	default:	fprintf(stdout, "[main] die on signal %d\n", onsig);
+	default:	syslog(LOG_NOTICE, "die() on signal %d", onsig);
     }
 
     shutdown = true;
@@ -88,13 +79,10 @@
 
 void my_connect_callback(struct mosquitto *mosq, void *obj, int result)
 {
-    int rc = MOSQ_ERR_SUCCESS;
-
-    fprintf(stdout, (char *)"my_connect_callback result=%d\n", result);
     if (!result) {
 	status = STATUS_CONNACK_RECVD;
     } else {
-	fprintf(stderr, "%s\n", mosquitto_connack_string(result));
+	syslog(LOG_NOTICE, "my_connect_callback: %s\n", mosquitto_connack_string(result));
     }
 }
 
@@ -102,8 +90,18 @@
 
 void my_disconnect_callback(struct mosquitto *mosq, void *obj, int rc)
 {
-    fprintf(stdout, (char *)"my_disconnect_callback\n");
-    connected = false;
+    if (shutdown) {
+	syslog(LOG_NOTICE, "Acknowledged DISCONNECT from %s", Config.mosq_host);
+	connected = false;
+    } else {
+	/*
+	 * The remove server was brought down. We must keep running
+	 */
+	syslog(LOG_NOTICE, "Received DISCONNECT from %s but we want to run", Config.mosq_host);
+	/*
+	 * We need a temp state
+	 */
+    }
 }
 
 
@@ -119,22 +117,15 @@
 
 void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str)
 {
-        printf("log: %s\n", str);
+    syslog(LOG_NOTICE, "MQTT: %s", str);
+    printf("MQTT: %s\n", str);
 }
 
 
 
 int main(int argc, char *argv[])
 {
-    int			i, c, len, rc, rc2;
-    char		*id = NULL;
-    char		*host = (char *)"lx02.mbse.ym";
-    int			port = 1883;
-    struct mosquitto	*mosq = NULL;
-    char		hostname[256], buf[1024];
-    int			keepalive = 60;
-    unsigned int	max_inflight = 20;
-    char		err[1024];
+    int rc, c, i;
 
     while (1) {
 	int option_index = 0;
@@ -156,6 +147,15 @@
 	}
     }
 
+    openlog("thermometers", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_USER);
+    syslog(LOG_NOTICE, "mbsePi-apps thermometers v%s starting", VERSION);
+
+    if (rdconfig()) {
+	fprintf(stderr, "Error reading configuration\n");
+	syslog(LOG_NOTICE, "halted");
+	return 1;
+    }
+
     /*
      *  Catch all the signals we can, and ignore the rest. Note that SIGKILL can't be ignored
      *  but that's live. This daemon should only be stopped by SIGTERM.
@@ -166,22 +166,36 @@
 	    signal(i, (void (*))die);
     }
 
+    rc = server();
+    syslog(LOG_NOTICE, "Finished, rc=%d", rc);
+    return rc;
+}
+
+
+
+int server(void)
+{
+    char                *id = NULL, *state = NULL;
+    struct mosquitto    *mosq = NULL;
+    char                hostname[256], buf[1024];
+    int                 rc, keepalive = 60;
+    unsigned int        max_inflight = 20;
+    char                err[1024];
+
     /*
      * Initialize mosquitto communication
      */
     mosquitto_lib_init();
+
+    /*
+     * Build MQTT id
+     */
     hostname[0] = '\0';
     gethostname(hostname, 256);
     hostname[255] = '\0';
-    len = strlen("thermometers/") + 1 + strlen(hostname);
-    id = malloc(len);
-    if(!id) {
-	if (!quiet)
-	    fprintf(stderr, "Error: Out of memory.\n");
-	mosquitto_lib_cleanup();
-	return 1;
-    }
-    snprintf(id, len, "thermometers/%s", hostname);
+
+    id = xstrcpy((char *)"thermometers/");
+    id = xstrcat(id, hostname);
     if(strlen(id) > MOSQ_MQTT_ID_MAX_LENGTH) {
 	/*
 	 * Enforce maximum client id length of 23 characters
@@ -189,42 +203,40 @@
 	id[MOSQ_MQTT_ID_MAX_LENGTH] = '\0';
     }
 
-    fprintf(stdout, "id: %s\n", id);
-
     mosq = mosquitto_new(id, true, NULL);
     if(!mosq) {
 	switch(errno) {
 	    case ENOMEM:
-		if (!quiet)
-		    fprintf(stderr, "Error: Out of memory.\n");
+		syslog(LOG_NOTICE, "mosquitto_new: Out of memory");
 		break;
 	    case EINVAL:
-		if (!quiet)
-		    fprintf(stderr, "Error: Invalid id.\n");
+		syslog(LOG_NOTICE, "mosquitto_new: Invalid id");
 		break;
 	}
 	mosquitto_lib_cleanup();
 	return 1;
     }
 
-    if(debug) {
+    if (debug) {
 	mosquitto_log_callback_set(mosq, my_log_callback);
     }
 
     /*
      * Set our will
      */
-    topic = malloc(28 + strlen(hostname));
-    sprintf(topic, "clients/%s/thermometers/state", hostname);
+    state = xstrcpy((char *)"clients/");
+    state = xstrcat(state, hostname);
+    state = xstrcat(state, (char *)"/thermometers/state");
     sprintf(buf, "0");
-    rc = mosquitto_will_set(mosq, topic, strlen(buf), buf, qos, true);
+
+    rc = mosquitto_will_set(mosq, state, strlen(buf), buf, qos, true);
     if (rc) {
         if (rc == MOSQ_ERR_INVAL) {
-            fprintf(stderr, "Input parameters invalid\n");
+            syslog(LOG_NOTICE, "mosquitto_will_set: input parameters invalid");
         } else if (rc == MOSQ_ERR_NOMEM) {
-            fprintf(stderr, "Out of Memory\n");
+            syslog(LOG_NOTICE, "mosquitto_will_set: Out of Memory");
 	} else if (rc == MOSQ_ERR_PAYLOAD_SIZE) {
-	    fprintf(stderr, "Invalid payload size\n");
+	    syslog(LOG_NOTICE, "mosquitto_will_set: invalid payload size");
         }
         mosquitto_lib_cleanup();
         return rc;
@@ -235,48 +247,44 @@
     mosquitto_disconnect_callback_set(mosq, my_disconnect_callback);
     mosquitto_publish_callback_set(mosq, my_publish_callback);
 
-    rc = mosquitto_connect(mosq, host, port, keepalive);
+    rc = mosquitto_connect(mosq, Config.mosq_host, Config.mosq_port, keepalive);
     if (rc) {
 	if (rc == MOSQ_ERR_ERRNO) {
 	    strerror_r(errno, err, 1024);
-	    fprintf(stderr, "Error: %s\n", err);
+	    syslog(LOG_NOTICE, "mosquitto_connect: error: %s", err);
 	} else {
-	    fprintf(stderr, "Unable to connect (%d).\n", rc);
+	    syslog(LOG_NOTICE, "mosquitto_connect: unable to connect (%d)", rc);
 	}
 	mosquitto_lib_cleanup();
 	return rc;
     }
+    syslog(LOG_NOTICE, "Connected with %s:%d", Config.mosq_host, Config.mosq_port);
 
     /*
      * Initialise is complete, report our presence state
      */
     mosquitto_loop_start(mosq);
 
-//    topic = malloc(28 + strlen(hostname));
-    sprintf(topic, "clients/%s/thermometers/state", hostname);
     sprintf(buf, "1");
-    rc2 = mosquitto_publish(mosq, &mid_sent, topic, strlen(buf), buf, qos, 1);
-    free(topic);
-
+    rc = mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, 1);
 
     fprintf(stdout, (char *)"Enter loop, connected %d\n", connected);
     do {
 	if (status == STATUS_CONNACK_RECVD) {
-//	    fprintf(stdout, (char *)"Ok\n");
-//                                if(fgets(buf, 1024, stdin)){
-//                                        buf[strlen(buf)-1] = '\0';
-//                                        rc2 = mosquitto_publish(mosq, &mid_sent, topic, strlen(buf), buf, qos, retain);
-//                                        if(rc2){
-//                                                if(!quiet) fprintf(stderr, "Error: Publish returned %d, disconnecting.\n", rc2);
-//                                                mosquitto_disconnect(mosq);
-//                                        }
-//	    } else
+	    /*
+	     * Sleep just log enough to keep the system load low.
+	     */
+	    usleep(1);
+	    /*
+	     * Here send our sensors values
+	     */
+
 	    if (shutdown) {
-		fprintf(stdout, (char *)"Shutdown\n");
-		topic = malloc(28 + strlen(hostname));
-		sprintf(topic, "clients/%s/thermometers/state", hostname);
+		/*
+		 * Final publish 0 to clients/<hostname>/thermometers/state
+		 */
 		sprintf(buf, "0");
-		rc2 = mosquitto_publish(mosq, &mid_sent, topic, strlen(buf), buf, qos, true);
+		mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, true);
 		free(topic);
 		last_mid = mid_sent;
 		status = STATUS_WAITING;
@@ -299,7 +307,6 @@
     mosquitto_destroy(mosq);
     mosquitto_lib_cleanup();
 
-    fprintf(stdout, (char *)"Bye Bye\n");
     return 0;
 }
 

mercurial