# HG changeset patch # User Michiel Broek # Date 1398266340 -7200 # Node ID e584bc0177df9801ebf4f9296c734a50ee29ae3d # Parent d74b26b2f2175d772f88b85caef52f437e005d15 Server communication seems ok, can handle server shutdowns too. diff -r d74b26b2f217 -r e584bc0177df lib/mbselib.h --- 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 #include #include +#include +#include +#include +#include +#include + +#include + #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 */ diff -r d74b26b2f217 -r e584bc0177df lib/rdconfig.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; } diff -r d74b26b2f217 -r e584bc0177df thermometers/Makefile --- 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 diff -r d74b26b2f217 -r e584bc0177df thermometers/main.c --- 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 -#include -#include -#include -#include -#include -#include -#include - -#include - - +#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//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; }