aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard van der Hoff <richard@matrix.org>2015-10-22 17:08:58 +0100
committerRichard van der Hoff <richard@matrix.org>2015-10-22 17:17:04 +0100
commitcaff31061b68f3b26a889931503a61bf12b76329 (patch)
treee2068ca47d776c5c5760394a1807fcb7fb44dcb3
parente8c4ddde265c060eb1466f39d3feb09694dd3482 (diff)
downloadpurple-matrix-caff31061b68f3b26a889931503a61bf12b76329.tar.gz
Refactor the connection code
Move all matrix-login and bits of matrix-sync into matrix-connection, where it seems to make more sense. Also move MatrixConnectionData into matrix-connection.h
-rw-r--r--Makefile3
-rw-r--r--libmatrix.c28
-rw-r--r--libmatrix.h6
-rw-r--r--matrix-api.c2
-rw-r--r--matrix-api.h2
-rw-r--r--matrix-connection.c145
-rw-r--r--matrix-connection.h57
-rw-r--r--matrix-login.c72
-rw-r--r--matrix-login.h29
-rw-r--r--matrix-room.c3
-rw-r--r--matrix-room.h3
-rw-r--r--matrix-sync.c44
-rw-r--r--matrix-sync.h24
13 files changed, 250 insertions, 168 deletions
diff --git a/Makefile b/Makefile
index 4076d18..5f41767 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,8 @@ DATA_ROOT_DIR_PURPLE = $(shell $(PKG_CONFIG) --variable=datarootdir purple)
# generate .d files when compiling
CPPFLAGS+=-MMD
-OBJECTS=libmatrix.o matrix-api.o matrix-json.o matrix-login.o matrix-room.o \
+OBJECTS=libmatrix.o matrix-api.o matrix-connection.o matrix-json.o \
+ matrix-room.o \
matrix-sync.o
TARGET=libmatrix.so
diff --git a/libmatrix.c b/libmatrix.c
index 6712119..1a2a45f 100644
--- a/libmatrix.c
+++ b/libmatrix.c
@@ -45,7 +45,7 @@
#include "util.h"
#include "version.h"
-#include "matrix-login.h"
+#include "matrix-connection.h"
#include "matrix-room.h"
/**
@@ -62,6 +62,26 @@ static const char *matrixprpl_list_icon(PurpleAccount *acct, PurpleBuddy *buddy)
return "matrix";
}
+/**
+ * Start the connection to a matrix account
+ */
+void matrixprpl_login(PurpleAccount *acct)
+{
+ PurpleConnection *pc = purple_account_get_connection(acct);
+ matrix_connection_new(pc);
+ matrix_connection_start_login(pc);
+}
+
+
+/**
+ * Called to handle closing the connection to an account
+ */
+static void matrixprpl_close(PurpleConnection *pc)
+{
+ matrix_connection_free(pc);
+}
+
+
/* Get the list of information we need to add a chat to our buddy list */
static GList *matrixprpl_chat_info(PurpleConnection *gc)
{
@@ -396,12 +416,6 @@ static GList *matrixprpl_blist_node_menu(PurpleBlistNode *node) {
}
}
-static void matrixprpl_close(PurpleConnection *gc)
-{
- /* notify other matrixprpl accounts */
- foreach_matrixprpl_gc(report_status_change, gc, NULL);
-}
-
static int matrixprpl_send_im(PurpleConnection *gc, const char *who,
const char *message, PurpleMessageFlags flags)
{
diff --git a/libmatrix.h b/libmatrix.h
index 38063d6..e485512 100644
--- a/libmatrix.h
+++ b/libmatrix.h
@@ -50,10 +50,4 @@
/* identifiers for the chat info / "components" */
#define PRPL_CHAT_INFO_ROOM_ID "room_id"
-typedef struct _MatrixConnectionData {
- struct _PurpleConnection *pc;
- gchar *homeserver; /* hostname (:port) of the homeserver */
- gchar *access_token; /* access token corresponding to our user */
-} MatrixConnectionData;
-
#endif
diff --git a/matrix-api.c b/matrix-api.c
index 92ae55b..a9c5227 100644
--- a/matrix-api.c
+++ b/matrix-api.c
@@ -450,6 +450,8 @@ MatrixApiRequestData *matrix_api_password_login(MatrixConnectionData *conn,
if(purple_debug_is_unsafe())
purple_debug_info("matrixprpl", "request %s\n", request->str);
+ else
+ purple_debug_info("matrixprpl", "logging in %s\n", username);
fetch_data = matrix_api_start(url, request->str, conn, callback,
NULL, NULL, user_data, 0);
diff --git a/matrix-api.h b/matrix-api.h
index 8e09b70..4394564 100644
--- a/matrix-api.h
+++ b/matrix-api.h
@@ -33,7 +33,7 @@
/* libpurple */
#include "util.h"
-#include "libmatrix.h"
+#include "matrix-connection.h"
struct _JsonNode;
struct _JsonObject;
diff --git a/matrix-connection.c b/matrix-connection.c
new file mode 100644
index 0000000..7eb57b3
--- /dev/null
+++ b/matrix-connection.c
@@ -0,0 +1,145 @@
+/**
+ * Implementation of the matrix login process
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "matrix-connection.h"
+
+#include <string.h>
+
+/* json-glib */
+#include <json-glib/json-glib.h>
+
+/* libpurple */
+#include <debug.h>
+
+/* libmatrix */
+#include "libmatrix.h"
+#include "matrix-api.h"
+#include "matrix-json.h"
+#include "matrix-sync.h"
+
+static void _start_next_sync(MatrixConnectionData *ma,
+ const gchar *next_batch, int timeout);
+
+
+void matrix_connection_new(PurpleConnection *pc)
+{
+ MatrixConnectionData *conn;
+
+ g_assert(purple_connection_get_protocol_data(pc) == NULL);
+ conn = g_new0(MatrixConnectionData, 1);
+ conn->pc = pc;
+ purple_connection_set_protocol_data(pc, conn);
+}
+
+
+void matrix_connection_free(PurpleConnection *pc)
+{
+ MatrixConnectionData *conn = purple_connection_get_protocol_data(pc);
+
+ g_assert(conn != NULL);
+
+ purple_connection_set_protocol_data(pc, NULL);
+
+ g_free(conn->homeserver);
+ conn->homeserver = NULL;
+
+ g_free(conn->access_token);
+ conn->access_token = NULL;
+
+ conn->pc = NULL;
+
+ g_free(conn);
+}
+
+
+/* callback which is called when a /sync request completes */
+static void _sync_complete(MatrixConnectionData *ma, gpointer user_data,
+ JsonNode *body)
+{
+ PurpleConnection *pc = ma->pc;
+ const gchar *next_batch;
+
+ purple_connection_update_progress(pc, _("Connected"), 2, 3);
+ purple_connection_set_state(pc, PURPLE_CONNECTED);
+
+ matrix_sync_parse(pc, body, &next_batch);
+
+ /* Start the next sync */
+ if(next_batch == NULL) {
+ purple_connection_error_reason(pc,
+ PURPLE_CONNECTION_ERROR_OTHER_ERROR, "No next_batch field");
+ return;
+ }
+ purple_account_set_string(pc->account, PRPL_ACCOUNT_OPT_NEXT_BATCH,
+ next_batch);
+
+ _start_next_sync(ma, next_batch, 30000);
+}
+
+
+static void _start_next_sync(MatrixConnectionData *ma,
+ const gchar *next_batch, int timeout)
+{
+ matrix_api_sync(ma, next_batch, timeout, _sync_complete, NULL);
+}
+
+static void _login_completed(MatrixConnectionData *conn,
+ gpointer user_data,
+ JsonNode *json_root)
+{
+ PurpleConnection *pc = conn->pc;
+ JsonObject *root_obj;
+ const gchar *access_token;
+ const gchar *next_batch;
+
+ root_obj = matrix_json_node_get_object(json_root);
+ access_token = matrix_json_object_get_string_member(root_obj,
+ "access_token");
+ if(access_token == NULL) {
+ purple_connection_error_reason(pc,
+ PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ "No access_token in /login response");
+ return;
+ }
+ conn->access_token = g_strdup(access_token);
+
+ /* start the sync loop */
+ next_batch = purple_account_get_string(pc->account,
+ PRPL_ACCOUNT_OPT_NEXT_BATCH, NULL);
+
+ purple_connection_update_progress(pc, _("Initial Sync"), 1, 3);
+ _start_next_sync(conn, next_batch, 0);
+
+}
+
+
+void matrix_connection_start_login(PurpleConnection *pc)
+{
+ PurpleAccount *acct = pc->account;
+ MatrixConnectionData *conn = purple_connection_get_protocol_data(pc);
+
+ conn->homeserver = g_strdup(purple_account_get_string(pc->account,
+ PRPL_ACCOUNT_OPT_HOME_SERVER, DEFAULT_HOME_SERVER));
+
+ purple_connection_set_state(pc, PURPLE_CONNECTING);
+ purple_connection_update_progress(pc, _("Logging in"), 0, 3);
+
+ matrix_api_password_login(conn, acct->username,
+ purple_account_get_password(acct), _login_completed, conn);
+}
+
diff --git a/matrix-connection.h b/matrix-connection.h
new file mode 100644
index 0000000..aaea528
--- /dev/null
+++ b/matrix-connection.h
@@ -0,0 +1,57 @@
+/**
+ * matrix-connection.h: handle the connection to a matrix homeserver
+ *
+ * When matrix_connection_start_login is called, we first get an access
+ * token by calling /login. We then repeatedly poll the /sync API endpoint.
+ * Each time /sync returns, the returned events are dispatched to the
+ * relevant rooms, and another /sync request is started.
+ *
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef MATRIX_CONNECTION_H
+#define MATRIX_CONNECTION_H
+
+#include <glib.h>
+
+struct _PurpleConnection;
+
+typedef struct _MatrixConnectionData {
+ struct _PurpleConnection *pc;
+ gchar *homeserver; /* hostname (:port) of the homeserver */
+ gchar *access_token; /* access token corresponding to our user */
+} MatrixConnectionData;
+
+
+/**
+ * Allocate a new MatrixConnectionData for the given PurpleConnection
+ */
+void matrix_connection_new(struct _PurpleConnection *pc);
+
+/**
+ * Start the login process on a matrix connection. When this completes, it
+ * will start the /sync loop
+ */
+void matrix_connection_start_login(struct _PurpleConnection *pc);
+
+/**
+ * free the resources associated with a PurpleConnection
+ */
+void matrix_connection_free(struct _PurpleConnection *pc);
+
+
+#endif
diff --git a/matrix-login.c b/matrix-login.c
deleted file mode 100644
index 2d8bc5c..0000000
--- a/matrix-login.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Implementation of the matrix login process
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "matrix-login.h"
-
-#include <string.h>
-
-/* json-glib */
-#include <json-glib/json-glib.h>
-
-/* libpurple */
-#include <debug.h>
-
-/* libmatrix */
-#include "matrix-api.h"
-#include "matrix-json.h"
-#include "matrix-sync.h"
-
-static void _login_completed(MatrixConnectionData *conn,
- gpointer user_data,
- JsonNode *json_root)
-{
- JsonObject *root_obj;
- const gchar *access_token;
-
- root_obj = matrix_json_node_get_object(json_root);
- access_token = matrix_json_object_get_string_member(root_obj, "access_token");
- if(access_token == NULL) {
- purple_connection_error_reason(conn->pc,
- PURPLE_CONNECTION_ERROR_OTHER_ERROR,
- "No access_token in /login response");
- return;
- }
- conn->access_token = g_strdup(access_token); /* TODO: free */
- matrix_sync_start_loop(conn);
-}
-
-
-void matrixprpl_login(PurpleAccount *acct)
-{
- PurpleConnection *pc = purple_account_get_connection(acct);
- MatrixConnectionData *ma = g_new0(MatrixConnectionData, 1); /* TODO: free */
-
- purple_connection_set_protocol_data(pc, ma);
- ma->pc = pc;
-
- purple_connection_set_state(ma->pc, PURPLE_CONNECTING);
- purple_connection_update_progress(ma->pc, _("Logging in"), 0, 3);
-
- purple_debug_info("matrixprpl", "logging in %s\n", acct->username);
-
- ma->homeserver = g_strdup(purple_account_get_string(
- acct, PRPL_ACCOUNT_OPT_HOME_SERVER, DEFAULT_HOME_SERVER));
-
- matrix_api_password_login(ma, acct->username,
- purple_account_get_password(acct), _login_completed, ma);
-}
diff --git a/matrix-login.h b/matrix-login.h
deleted file mode 100644
index c3057fb..0000000
--- a/matrix-login.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Implementation of the matrix login process
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#ifndef MATRIX_LOGIN_H
-#define MATRIX_LOGIN_H
-
-#include "account.h"
-
-/**
- * Set off the login process
- */
-void matrixprpl_login(PurpleAccount *acct);
-
-#endif
diff --git a/matrix-room.c b/matrix-room.c
index cace33f..872eaa7 100644
--- a/matrix-room.c
+++ b/matrix-room.c
@@ -404,9 +404,8 @@ void matrix_room_handle_timeline_event(PurpleConversation *conv,
PurpleConversation *matrix_room_get_or_create_conversation(
- MatrixConnectionData *ma, const gchar *room_id)
+ PurpleConnection *pc, const gchar *room_id)
{
- PurpleConnection *pc = ma->pc;
PurpleConversation *conv = purple_find_conversation_with_account(
PURPLE_CONV_TYPE_CHAT, room_id, pc->account);
MatrixRoomStateEventTable *state_table;
diff --git a/matrix-room.h b/matrix-room.h
index 56a35bf..b454653 100644
--- a/matrix-room.h
+++ b/matrix-room.h
@@ -33,6 +33,7 @@
#include "libmatrix.h"
struct _PurpleConversation;
+struct _PurpleConnection;
/**
* Ensure the room is up to date in the buddy list (ie, it is present,
@@ -48,7 +49,7 @@ void matrix_room_update_buddy_list(struct _PurpleConversation *conv);
* @param ma account associated with the chat
*/
struct _PurpleConversation *matrix_room_get_or_create_conversation(
- MatrixConnectionData *ma, const gchar *room_id);
+ struct _PurpleConnection *pc, const gchar *room_id);
/**
* Leave a chat: notify the server that we are leaving, and (ultimately)
diff --git a/matrix-sync.c b/matrix-sync.c
index b86238e..5386917 100644
--- a/matrix-sync.c
+++ b/matrix-sync.c
@@ -27,7 +27,6 @@
#include "debug.h"
/* libmatrix */
-#include "matrix-api.h"
#include "matrix-json.h"
#include "matrix-room.h"
@@ -39,9 +38,6 @@ typedef struct _RoomEventParserData {
} RoomEventParserData;
-static void matrix_sync_complete(MatrixConnectionData *ma, gpointer user_data,
- JsonNode *body);
-
/**
* handle an event for a room
*
@@ -95,14 +91,14 @@ static void _parse_room_event_array(PurpleConversation *conv, JsonArray *events,
* handle a room within the sync response
*/
static void matrix_sync_room(const gchar *room_id,
- JsonObject *room_data, MatrixConnectionData *ma)
+ JsonObject *room_data, PurpleConnection *pc)
{
JsonObject *state_object, *timeline_object, *event_map;
JsonArray *state_array, *timeline_array;
PurpleConversation *conv;
event_map = matrix_json_object_get_object_member(room_data, "event_map");
- conv = matrix_room_get_or_create_conversation(ma, room_id);
+ conv = matrix_room_get_or_create_conversation(pc, room_id);
/* parse the room state */
state_object = matrix_json_object_get_object_member(room_data, "state");
@@ -126,13 +122,13 @@ static void matrix_sync_room(const gchar *room_id,
/**
* handle the results of the sync request
*/
-static void matrix_handle_sync(MatrixConnectionData *ma, JsonNode *body)
+void matrix_sync_parse(PurpleConnection *pc, JsonNode *body,
+ const gchar **next_batch)
{
JsonObject *rootObj;
JsonObject *rooms;
JsonObject *joined_rooms;
GList *room_ids, *elem;
- const gchar *next_batch;
rootObj = matrix_json_node_get_object(body);
rooms = matrix_json_object_get_object_member(rootObj, "rooms");
@@ -148,38 +144,10 @@ static void matrix_handle_sync(MatrixConnectionData *ma, JsonNode *body)
const gchar *room_id = elem->data;
JsonObject *room_data = matrix_json_object_get_object_member(
joined_rooms, room_id);
- matrix_sync_room(room_id, room_data, ma);
+ matrix_sync_room(room_id, room_data, pc);
}
g_list_free(room_ids);
- /* Start the next sync */
- next_batch = matrix_json_object_get_string_member(rootObj, "next_batch");
- if(next_batch == NULL) {
- purple_connection_error_reason(ma->pc,
- PURPLE_CONNECTION_ERROR_OTHER_ERROR, "No next_batch field");
- return;
- }
- purple_account_set_string(ma->pc->account, PRPL_ACCOUNT_OPT_NEXT_BATCH,
- next_batch);
- matrix_api_sync(ma, next_batch, 30000, matrix_sync_complete, NULL);
-}
-
-/* callback which is called when a /sync request completes */
-static void matrix_sync_complete(MatrixConnectionData *ma, gpointer user_data,
- JsonNode *body)
-{
- purple_connection_update_progress(ma->pc, _("Connected"), 2, 3);
- purple_connection_set_state(ma->pc, PURPLE_CONNECTED);
-
- matrix_handle_sync(ma, body);
+ *next_batch = matrix_json_object_get_string_member(rootObj, "next_batch");
}
-
-void matrix_sync_start_loop(MatrixConnectionData *ma)
-{
- const char *next_batch;
- purple_connection_update_progress(ma->pc, _("Initial Sync"), 1, 3);
- next_batch = purple_account_get_string(ma->pc->account,
- PRPL_ACCOUNT_OPT_NEXT_BATCH, NULL);
- matrix_api_sync(ma, next_batch, 0, matrix_sync_complete, NULL);
-}
diff --git a/matrix-sync.h b/matrix-sync.h
index 4f267dc..70361c1 100644
--- a/matrix-sync.h
+++ b/matrix-sync.h
@@ -1,13 +1,6 @@
/**
* matrix-sync.h
*
- * Receipt of events from the matrix homeserver works by continually polling the
- * /sync API endpoint. This module manages that process. It provides a single
- * method which initiates a /sync request for an authenticated MatrixConnectionData.
- *
- * On completion of the request, any events it returned are dispatched to the
- * relevant rooms, and another /sync request is started.
- *
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,12 +20,21 @@
#ifndef MATRIX_SYNC_H_
#define MATRIX_SYNC_H_
-#include "libmatrix.h"
+#include <glib.h>
+
+struct _PurpleConnection;
+struct _JsonNode;
/**
- * Start the sync loop for a matrix account. This will repeatedly call
- * '/sync' to get room information and new events.
+ * Parse and dispatch the results of a /sync call.
+ *
+ * @param pc Connection to which these results relate
+ * @param body Body of /sync response
+ * @param next_batch Returns a pointer to the next_batch setting, for the next
+ * sync (or NULL if none was found)
*/
-void matrix_sync_start_loop(MatrixConnectionData *ma);
+void matrix_sync_parse(struct _PurpleConnection *pc, struct _JsonNode *body,
+ const gchar **next_batch);
+
#endif /* MATRIX_SYNC_H_ */