summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2022-08-14 16:07:34 +0200
committerxengineering <me@xengineering.eu>2022-08-15 19:01:15 +0200
commit21a2b2033485c106a537e5e2302f4e4d96a66b94 (patch)
tree8457f0057596540eb193fcb3410d07071160aca3
parent2acca5d84a318f6c8858acb8ee7eca7e59369160 (diff)
downloadlimox-21a2b2033485c106a537e5e2302f4e4d96a66b94.tar
limox-21a2b2033485c106a537e5e2302f4e4d96a66b94.tar.zst
limox-21a2b2033485c106a537e5e2302f4e4d96a66b94.zip
Implement XMPP connect / disconnect
-rw-r--r--.gitignore2
-rw-r--r--README.txt1
-rw-r--r--gtk.c (renamed from gui.c)20
-rw-r--r--gui.h11
-rw-r--r--limox.c148
-rw-r--r--limox.h8
-rw-r--r--main.c4
-rw-r--r--meson.build2
8 files changed, 179 insertions, 17 deletions
diff --git a/.gitignore b/.gitignore
index e1ab00c..a103539 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-limox_oldrepo.tar
+.local
diff --git a/README.txt b/README.txt
index 5efd598..c35763e 100644
--- a/README.txt
+++ b/README.txt
@@ -15,6 +15,7 @@ Roadmap
- [ ] finish minimal viable product (MVP) to send and receive text messages
- [x] static GUI widgets
- [x] dynamic GUI widgets (like text messages)
+ - [ ] connection, stream and presence management
- [ ] roster request
- [ ] receiving one-to-one text messages
- [ ] sending one-to-one text messages
diff --git a/gui.c b/gtk.c
index 760d66a..3139cbb 100644
--- a/gui.c
+++ b/gtk.c
@@ -1,9 +1,10 @@
-#include <time.h>
#include <gtk/gtk.h>
#include <stdio.h>
+#include "limox.h"
+
struct chat {
GtkWidget* roster_item; // the button in the roster list
@@ -42,6 +43,7 @@ static GtkWidget* roster_button;
static void quit_cb(void) {
+ limox_quit();
g_application_quit(G_APPLICATION(app));
}
@@ -54,6 +56,8 @@ static void connect_cb(void) {
// just dummy output
printf("Connecting with:\nJID: %s\nPWD: %s\n", jid_text, pwd_text);
+
+ limox_connect(jid_text, pwd_text);
}
static void disconnect_cb(void) {
@@ -62,6 +66,8 @@ static void disconnect_cb(void) {
// just dummy output
printf("Disconnected!\n");
+
+ limox_disconnect();
}
static void to_chat(GtkWidget* layout_box) {
@@ -237,21 +243,13 @@ static void activate(void) {
gtk_widget_show(window);
}
-static void delay(unsigned long int micros) {
-
- unsigned long int now = clock();
- while ((clock() - now) < micros) {}
-
-}
-
static void idle_cb(void) {
- // just a dummy workload
- delay(1000);
+ limox_run_once();
}
-void run_gui(void) {
+void gui_run(void) {
#ifdef GTK_SRCDIR
g_chdir(GTK_SRCDIR);
diff --git a/gui.h b/gui.h
index 5df3576..057e0b1 100644
--- a/gui.h
+++ b/gui.h
@@ -1,3 +1,8 @@
-void run_gui(void);
-void add_chat(char* jid);
-void add_incoming_text_message(char* sender_jid, char* content);
+// interface for main.c
+void gui_run(void);
+
+// interface for limox.c
+void gui_connected(char* jid, char* password);
+void gui_disconnected(void);
+void gui_suspended(void);
+void gui_resumed(void);
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;
+
+}
diff --git a/limox.h b/limox.h
new file mode 100644
index 0000000..90a3b76
--- /dev/null
+++ b/limox.h
@@ -0,0 +1,8 @@
+// life cycle / event loop related functions
+void limox_init(void); // initialize limox
+void limox_run_once(void); // process event loop for a short amount of time
+void limox_quit(void); // disconnect and clean up
+
+// interface for the GUI implementation
+void limox_connect(const char* jid, const char* password);
+void limox_disconnect(void);
diff --git a/main.c b/main.c
index 2d2b330..c94b023 100644
--- a/main.c
+++ b/main.c
@@ -5,6 +5,7 @@
#include <unistd.h>
#include "gui.h"
+#include "limox.h"
// error code definition
@@ -37,7 +38,8 @@ int main(int argc, char* argv[]) {
if (opts.unknown || opts.help) {
print_help();
} else {
- run_gui();
+ limox_init();
+ gui_run();
}
}
diff --git a/meson.build b/meson.build
index a743460..34a33e4 100644
--- a/meson.build
+++ b/meson.build
@@ -1,4 +1,4 @@
project('LimoX', 'c')
gtkdep = dependency('gtk4')
strophedep = dependency('libstrophe')
-executable('limox', ['main.c', 'gui.c'], dependencies : [gtkdep, strophedep])
+executable('limox', ['main.c', 'gtk.c', 'limox.c'], dependencies : [gtkdep, strophedep])