Can connect and disconnect

Tue, 22 Apr 2014 23:28:17 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Tue, 22 Apr 2014 23:28:17 +0200
changeset 6
9db76e20e21e
parent 5
8c44725dc4ad
child 7
d74b26b2f217

Can connect and disconnect

configure file | annotate | diff | comparison | revisions
configure.ac file | annotate | diff | comparison | revisions
thermometers/main.c file | annotate | diff | comparison | revisions
--- a/configure	Tue Apr 22 17:34:24 2014 +0200
+++ b/configure	Tue Apr 22 23:28:17 2014 +0200
@@ -1396,6 +1396,52 @@
 
 } # ac_fn_c_try_compile
 
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
 # ac_fn_c_try_cpp LINENO
 # ----------------------
 # Try to preprocess conftest.$ac_ext, and return whether this succeeded.
@@ -2845,6 +2891,58 @@
 
 
 #
+# Libraries for mbsePi-apps
+#
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mosquitto_lib_init in -lmosquitto" >&5
+$as_echo_n "checking for mosquitto_lib_init in -lmosquitto... " >&6; }
+if ${ac_cv_lib_mosquitto_mosquitto_lib_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmosquitto  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char mosquitto_lib_init ();
+int
+main ()
+{
+return mosquitto_lib_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_mosquitto_mosquitto_lib_init=yes
+else
+  ac_cv_lib_mosquitto_mosquitto_lib_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mosquitto_mosquitto_lib_init" >&5
+$as_echo "$ac_cv_lib_mosquitto_mosquitto_lib_init" >&6; }
+if test "x$ac_cv_lib_mosquitto_mosquitto_lib_init" = xyes; then :
+  result=yes
+else
+  result=no
+fi
+
+if test "$result" = "yes"; then
+  LIBS="$LIBS -lmosquitto"
+else
+  as_fn_error $? "libmosquitto not found" "$LINENO" 5
+fi
+
+#
 # Additional commandline switches
 #
 # Check whether --enable-experiment was given.
@@ -2872,7 +2970,6 @@
   CFLAGS="-g -O2 -fomit-frame-pointer -fno-strict-aliasing -Wall -Wshadow -Wwrite-strings -Wstrict-prototypes -Winline"
 fi
 
-
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
--- a/configure.ac	Tue Apr 22 17:34:24 2014 +0200
+++ b/configure.ac	Tue Apr 22 23:28:17 2014 +0200
@@ -31,6 +31,16 @@
 AC_CHECK_PROG(TAR, tar, tar)
 
 #
+# Libraries for mbsePi-apps
+#
+AC_CHECK_LIB(mosquitto,mosquitto_lib_init,result=yes,result=no)
+if test "$result" = "yes"; then
+  LIBS="$LIBS -lmosquitto"
+else
+  AC_MSG_ERROR(libmosquitto not found)
+fi
+
+#
 # Additional commandline switches
 #
 AC_ARG_ENABLE(experiment,  [  --enable-experiment     Compile experimental code],     [ experiment=$enableval ], [ experiment=no ])
--- a/thermometers/main.c	Tue Apr 22 17:34:24 2014 +0200
+++ b/thermometers/main.c	Tue Apr 22 23:28:17 2014 +0200
@@ -26,11 +26,40 @@
 #include <getopt.h>
 #include <sys/types.h>
 #include <signal.h>
+#include <string.h>
+#include <errno.h>
+
+#include <mosquitto.h>
 
 
 #include "main.h"
 
 
+#define STATUS_CONNECTING 0
+#define STATUS_CONNACK_RECVD 1
+#define STATUS_WAITING 2
+
+/* Global variables for use in callbacks. See sub_client.c for an example of
+ * using a struct to hold variables for use in callbacks. */
+static char *topic = NULL;
+//static char *message = NULL;
+//static long msglen = 0;
+static int qos = 0;
+//static int retain = 0;
+static int status = STATUS_CONNECTING;
+static int mid_sent = 0;
+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;
+
+
+
 void help(void)
 {
     fprintf(stdout, "Usage: thermomeneters [-d] [-h]\n");
@@ -43,23 +72,78 @@
 void die(int onsig)
 {
     switch (onsig) {
-	case SIGHUP:	fprintf(stdout, "[main] Hangup detected");
+	case SIGHUP:	fprintf(stdout, "[main] Hangup detected\n");
 			break;
-	case SIGINT:	fprintf(stdout, "[main] Interrupt from keyboard");
+	case SIGINT:	fprintf(stdout, "[main] Interrupt from keyboard\n");
 			break;
-	case SIGTERM:	fprintf(stdout, "[main] Termination signal received");
+	case SIGTERM:	fprintf(stdout, "[main] Termination signal received\n");
 			break;
-	default:	fprintf(stdout, "[main] die on signal %d", onsig);
+	default:	fprintf(stdout, "[main] die on signal %d\n", onsig);
     }
 
-    exit(onsig);
+    shutdown = true;
+}
+
+
+
+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));
+    }
+}
+
+
+
+void my_disconnect_callback(struct mosquitto *mosq, void *obj, int rc)
+{
+    fprintf(stdout, (char *)"my_disconnect_callback\n");
+    connected = false;
+}
+
+
+
+void my_publish_callback(struct mosquitto *mosq, void *obj, int mid)
+{
+    fprintf(stdout, (char *)"my_publish_callback mid=%d\n", mid);
+
+    last_mid_sent = mid;
+//        if(mode == MSGMODE_STDIN_LINE){
+//                if(mid == last_mid){
+//                        mosquitto_disconnect(mosq);
+//                        disconnect_sent = true;
+//                }
+//        }else if(disconnect_sent == false){
+//                mosquitto_disconnect(mosq);
+//                disconnect_sent = true;
+//        }
+}
+
+
+
+void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str)
+{
+        printf("%s\n", str);
 }
 
 
 
 int main(int argc, char *argv[])
 {
-    int		i, c;
+    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];
 
     while (1) {
 	int option_index = 0;
@@ -74,7 +158,7 @@
 	    break;
 
 	switch (c) {
-	    case 'd':	
+	    case 'd':	debug = true;
 			break;
 	    case 'h':	help();
 			return 1;
@@ -91,7 +175,140 @@
 	    signal(i, (void (*))die);
     }
 
+    /*
+     * Initialize mosquitto communication
+     */
+    mosquitto_lib_init();
+    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);
+    if(strlen(id) > MOSQ_MQTT_ID_MAX_LENGTH) {
+	/*
+	 * Enforce maximum client id length of 23 characters
+	 */
+	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");
+		break;
+	    case EINVAL:
+		if (!quiet)
+		    fprintf(stderr, "Error: Invalid id.\n");
+		break;
+	}
+	mosquitto_lib_cleanup();
+	return 1;
+    }
+
+    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);
+    sprintf(buf, "0");
+    rc = mosquitto_will_set(mosq, topic, strlen(buf), buf, qos, true);
+    if (rc) {
+        if (rc == MOSQ_ERR_INVAL) {
+            fprintf(stderr, "Input parameters invalid\n");
+        } else if (rc == MOSQ_ERR_NOMEM) {
+            fprintf(stderr, "Out of Memory\n");
+	} else if (rc == MOSQ_ERR_PAYLOAD_SIZE) {
+	    fprintf(stderr, "Invalid payload size\n");
+        }
+        mosquitto_lib_cleanup();
+        return rc;
+    }
+
+    mosquitto_max_inflight_messages_set(mosq, max_inflight);
+    mosquitto_connect_callback_set(mosq, my_connect_callback);
+    mosquitto_disconnect_callback_set(mosq, my_disconnect_callback);
+    mosquitto_publish_callback_set(mosq, my_publish_callback);
+
+    rc = mosquitto_connect(mosq, host, port, keepalive);
+    if (rc) {
+	if (rc == MOSQ_ERR_ERRNO) {
+	    strerror_r(errno, err, 1024);
+	    fprintf(stderr, "Error: %s\n", err);
+	} else {
+	    fprintf(stderr, "Unable to connect (%d).\n", rc);
+	}
+	mosquitto_lib_cleanup();
+	return rc;
+    }
+
+    /*
+     * 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);
+
+
+    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
+	    if (shutdown) {
+		fprintf(stdout, (char *)"Shutdown\n");
+		topic = malloc(28 + strlen(hostname));
+		sprintf(topic, "clients/%s/thermometers/state", hostname);
+		sprintf(buf, "0");
+		rc2 = mosquitto_publish(mosq, &mid_sent, topic, strlen(buf), buf, qos, true);
+		free(topic);
+		last_mid = mid_sent;
+		status = STATUS_WAITING;
+	    }
+	} else if (status == STATUS_WAITING) {
+	    fprintf(stdout, (char *)"Waiting\n");
+	    if (last_mid_sent == last_mid && disconnect_sent == false) {
+		mosquitto_disconnect(mosq);
+		disconnect_sent = true;
+	    }
+	    usleep(100000);
+	}
+	rc = MOSQ_ERR_SUCCESS;
+
+    } while(rc == MOSQ_ERR_SUCCESS && connected);
+    fprintf(stdout, (char *)"Out of loop\n");
+
+    mosquitto_loop_stop(mosq, false);
+
+    mosquitto_destroy(mosq);
+    mosquitto_lib_cleanup();
+
+    fprintf(stdout, (char *)"Bye Bye\n");
     return 0;
 }
 

mercurial