summaryrefslogtreecommitdiff
path: root/limox.c
diff options
context:
space:
mode:
Diffstat (limited to 'limox.c')
-rw-r--r--limox.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/limox.c b/limox.c
new file mode 100644
index 0000000..618c2ef
--- /dev/null
+++ b/limox.c
@@ -0,0 +1,148 @@
+
+
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <strophe.h>
+
+#include <limox.h>
+
+
+// the state of limox
+typedef enum {
+ DISCONNECTED, // initial state
+ CONNECTING, // connection was requested but is not yet established
+ CONNECTED, // there is an active XMPP connetion to the server
+ SUSPENDED // not connected, but there is an open XMPP stream to be
+ // reconnected (see XEP-0198 for details)
+} limox_state_t;
+
+
+// these variables stay initialized for the whole runtime
+static limox_state_t state;
+static xmpp_log_t* log;
+static xmpp_ctx_t* ctx;
+
+// these variables stay initialized while the application is not disconnected
+static xmpp_conn_t* conn;
+static long flags;
+
+// this variable stays initialized while the connection is suspended
+static xmpp_sm_state_t* sm_state;
+
+static void conn_handler(xmpp_conn_t *conn, xmpp_conn_event_t status,int error,
+ xmpp_stream_error_t *stream_error, void *userdata) {
+
+ if (status == XMPP_CONN_CONNECT) {
+ printf("DEBUG: connected\n");
+
+ // send initial presence
+ xmpp_stanza_t* presence;
+ presence = xmpp_presence_new(ctx);
+ xmpp_send(conn, presence);
+ xmpp_stanza_release(presence);
+ } else if (status == XMPP_CONN_DISCONNECT) {
+ printf("got XMPP_CONN_DISCONNECT\n");
+ } else {
+ printf("Unhandled connection event!\n");
+ }
+}
+
+void limox_init(void) {
+
+ printf("limox_init()\n");
+
+ xmpp_initialize();
+ log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG); // or NULL for silence
+ ctx = xmpp_ctx_new(NULL, log);
+
+ state = DISCONNECTED;
+
+}
+
+static void delay(unsigned long int micros) {
+
+ unsigned long int now = clock();
+ while ((clock() - now) < micros) {}
+
+}
+
+void limox_run_once(void) {
+
+ if (state == CONNECTING) {
+ if (xmpp_connect_client(conn, NULL, 0, conn_handler, NULL)
+ == XMPP_EOK) {
+ state = CONNECTED;
+ } else {
+ limox_disconnect();
+ }
+ }
+
+ if (state != DISCONNECTED) {
+ xmpp_run_once(ctx, 200);
+ }
+
+ // TODO This delay is useless. But without it this function gets only
+ // called once by GTK. This could be a GTK bug.
+ delay(10000);
+
+}
+
+void limox_quit(void) {
+
+ printf("limox_quit()\n");
+
+ limox_disconnect();
+ // TODO is it possible to free xmpp_log_t ?
+ log = NULL;
+ xmpp_ctx_free(ctx);
+ xmpp_shutdown();
+
+}
+
+void limox_connect(const char* jid, const char* password) {
+
+ printf("limox_connect()\n");
+
+ conn = xmpp_conn_new(ctx);
+
+ flags = 0;
+ flags |= XMPP_CONN_FLAG_MANDATORY_TLS;
+ xmpp_conn_set_flags(conn, flags);
+
+ xmpp_conn_set_jid(conn, jid);
+ xmpp_conn_set_pass(conn, password);
+
+ state = CONNECTING;
+
+}
+
+void limox_disconnect(void) {
+
+ printf("limox_disconnect()\n");
+
+ if (sm_state) {
+ xmpp_free_sm_state(sm_state);
+ sm_state = NULL;
+ }
+
+ if (conn != NULL && xmpp_conn_is_connected(conn)) {
+ xmpp_disconnect(conn);
+ while (xmpp_conn_is_connected(conn)) {
+ xmpp_run_once(ctx, 200);
+ }
+ xmpp_conn_release(conn);
+ }
+
+ // TODO free conn
+ conn = NULL;
+
+ flags = 0;
+
+ state = DISCONNECTED;
+
+}