about summary refs log tree commit diff stats
path: root/src/xmpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmpp')
-rw-r--r--src/xmpp/iq.c75
-rw-r--r--src/xmpp/stanza.c80
-rw-r--r--src/xmpp/stanza.h15
-rw-r--r--src/xmpp/xmpp.h14
4 files changed, 165 insertions, 19 deletions
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index 17269fe2..ab3a29a0 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -75,6 +75,8 @@ static int _disco_items_get_handler(xmpp_conn_t * const conn,
     xmpp_stanza_t * const stanza, void * const userdata);
 static int _destroy_room_result_handler(xmpp_conn_t * const conn,
     xmpp_stanza_t * const stanza, void * const userdata);
+static int _room_config_handler(xmpp_conn_t * const conn,
+    xmpp_stanza_t * const stanza, void * const userdata);
 static int _manual_pong_handler(xmpp_conn_t *const conn,
     xmpp_stanza_t * const stanza, void * const userdata);
 static int _ping_timed_handler(xmpp_conn_t * const conn,
@@ -99,8 +101,6 @@ iq_add_handlers(void)
 
     HANDLE(STANZA_NS_PING,      STANZA_TYPE_GET,    _ping_get_handler);
 
-    HANDLE(NULL,                STANZA_TYPE_RESULT, _destroy_room_result_handler);
-
     if (prefs_get_autoping() != 0) {
         int millis = prefs_get_autoping() * 1000;
         xmpp_timed_handler_add(conn, _ping_timed_handler, millis, ctx);
@@ -189,6 +189,30 @@ _iq_destroy_instant_room(const char * const room_jid)
 }
 
 static void
+_iq_request_room_config_form(const char * const room_jid)
+{
+    xmpp_conn_t * const conn = connection_get_conn();
+    xmpp_ctx_t * const ctx = connection_get_ctx();
+    xmpp_stanza_t *iq = stanza_create_room_config_request_iq(ctx, room_jid);
+
+    char *id = xmpp_stanza_get_id(iq);
+    xmpp_id_handler_add(conn, _room_config_handler, id, NULL);
+
+    xmpp_send(conn, iq);
+    xmpp_stanza_release(iq);
+}
+
+static void
+_iq_room_config_cancel(const char * const room_jid)
+{
+    xmpp_conn_t * const conn = connection_get_conn();
+    xmpp_ctx_t * const ctx = connection_get_ctx();
+    xmpp_stanza_t *iq = stanza_create_room_config_cancel_iq(ctx, room_jid);
+    xmpp_send(conn, iq);
+    xmpp_stanza_release(iq);
+}
+
+static void
 _iq_send_ping(const char * const target)
 {
     xmpp_conn_t * const conn = connection_get_conn();
@@ -551,6 +575,51 @@ _destroy_room_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const sta
     return 0;
 }
 
+static int
+_room_config_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
+    void * const userdata)
+{
+    const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
+
+    if (id != NULL) {
+        log_debug("IQ room config handler fired, id: %s.", id);
+    } else {
+        log_debug("IQ room config handler fired.");
+    }
+
+    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
+    if (from == NULL) {
+        log_error("No from attribute for IQ destroy room result");
+    } else {
+        // get form
+        xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
+        if (query == NULL) {
+            log_error("No query element found parsing room config response");
+            handle_room_configuration_form_error();
+            return 0;
+        }
+
+        xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(query, STANZA_NS_DATA);
+        if (x == NULL) {
+            log_error("No x element found with %s namespace parsing room config response", STANZA_NS_DATA);
+            handle_room_configuration_form_error();
+            return 0;
+        }
+
+        char *type = xmpp_stanza_get_attribute(x, STANZA_ATTR_TYPE);
+        if (g_strcmp0(type, "form") != 0) {
+            log_error("x element not of type 'form' parsing room config response");
+            handle_room_configuration_form_error();
+            return 0;
+        }
+
+        DataForm *form = stanza_create_form(x);
+        handle_room_configure(from, form);
+    }
+
+    return 0;
+}
+
 static void
 _identity_destroy(DiscoIdentity *identity)
 {
@@ -800,4 +869,6 @@ iq_init_module(void)
     iq_confirm_instant_room = _iq_confirm_instant_room;
     iq_destroy_instant_room = _iq_destroy_instant_room;
     iq_send_ping = _iq_send_ping;
+    iq_request_room_config_form = _iq_request_room_config_form;
+    iq_room_config_cancel = _iq_room_config_cancel;
 }
diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c
index e068eeed..e78f5b9f 100644
--- a/src/xmpp/stanza.c
+++ b/src/xmpp/stanza.c
@@ -430,7 +430,7 @@ stanza_create_instant_room_request_iq(xmpp_ctx_t *ctx, const char * const room_j
     xmpp_stanza_set_name(iq, STANZA_NAME_IQ);
     xmpp_stanza_set_type(iq, STANZA_TYPE_SET);
     xmpp_stanza_set_attribute(iq, STANZA_ATTR_TO, room_jid);
-    char *id = create_unique_id("leave");
+    char *id = create_unique_id("room");
     xmpp_stanza_set_id(iq, id);
     free(id);
 
@@ -459,7 +459,7 @@ stanza_create_instant_room_destroy_iq(xmpp_ctx_t *ctx, const char * const room_j
     xmpp_stanza_set_name(iq, STANZA_NAME_IQ);
     xmpp_stanza_set_type(iq, STANZA_TYPE_SET);
     xmpp_stanza_set_attribute(iq, STANZA_ATTR_TO, room_jid);
-    char *id = create_unique_id("leave");
+    char *id = create_unique_id("room");
     xmpp_stanza_set_id(iq, id);
     free(id);
 
@@ -480,6 +480,56 @@ stanza_create_instant_room_destroy_iq(xmpp_ctx_t *ctx, const char * const room_j
 }
 
 xmpp_stanza_t *
+stanza_create_room_config_request_iq(xmpp_ctx_t *ctx, const char * const room_jid)
+{
+    xmpp_stanza_t *iq = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(iq, STANZA_NAME_IQ);
+    xmpp_stanza_set_type(iq, STANZA_TYPE_GET);
+    xmpp_stanza_set_attribute(iq, STANZA_ATTR_TO, room_jid);
+    char *id = create_unique_id("room");
+    xmpp_stanza_set_id(iq, id);
+    free(id);
+
+    xmpp_stanza_t *query = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
+    xmpp_stanza_set_ns(query, STANZA_NS_MUC_OWNER);
+
+    xmpp_stanza_add_child(iq, query);
+    xmpp_stanza_release(query);
+
+    return iq;
+}
+
+xmpp_stanza_t *
+stanza_create_room_config_cancel_iq(xmpp_ctx_t *ctx, const char * const room_jid)
+{
+    xmpp_stanza_t *iq = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(iq, STANZA_NAME_IQ);
+    xmpp_stanza_set_type(iq, STANZA_TYPE_SET);
+    xmpp_stanza_set_attribute(iq, STANZA_ATTR_TO, room_jid);
+    char *id = create_unique_id("room");
+    xmpp_stanza_set_id(iq, id);
+    free(id);
+
+    xmpp_stanza_t *query = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
+    xmpp_stanza_set_ns(query, STANZA_NS_MUC_OWNER);
+
+    xmpp_stanza_t *x = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(x, STANZA_NAME_X);
+    xmpp_stanza_set_type(x, "cancel");
+    xmpp_stanza_set_ns(x, STANZA_NS_DATA);
+
+    xmpp_stanza_add_child(query, x);
+    xmpp_stanza_release(x);
+
+    xmpp_stanza_add_child(iq, query);
+    xmpp_stanza_release(query);
+
+    return iq;
+}
+
+xmpp_stanza_t *
 stanza_create_presence(xmpp_ctx_t * const ctx)
 {
     xmpp_stanza_t *presence = xmpp_stanza_new(ctx);
@@ -1037,23 +1087,39 @@ stanza_create_form(xmpp_stanza_t * const stanza)
 
     //handle fields
     while (child != NULL) {
+        char *label = xmpp_stanza_get_attribute(child, "label");
+        char *type = xmpp_stanza_get_attribute(child, "type");
         char *var = xmpp_stanza_get_attribute(child, "var");
 
         // handle FORM_TYPE
         if (g_strcmp0(var, "FORM_TYPE") == 0) {
             xmpp_stanza_t *value = xmpp_stanza_get_child_by_name(child, "value");
             char *value_text = xmpp_stanza_get_text(value);
-            result->form_type = strdup(value_text);
-            xmpp_free(ctx, value_text);
+            if (value_text != NULL) {
+                result->form_type = strdup(value_text);
+                xmpp_free(ctx, value_text);
+            }
 
         // handle regular fields
         } else {
             FormField *field = malloc(sizeof(FormField));
-            field->var = strdup(var);
-            field->values = NULL;
-            xmpp_stanza_t *value = xmpp_stanza_get_children(child);
+            field->label = NULL;
+            field->type = NULL;
+            field->var = NULL;
+
+            if (label != NULL) {
+                field->label = strdup(label);
+            }
+            if (type != NULL) {
+                field->type = strdup(type);
+            }
+            if (var != NULL) {
+                field->var = strdup(var);
+            }
 
             // handle values
+            field->values = NULL;
+            xmpp_stanza_t *value = xmpp_stanza_get_children(child);
             while (value != NULL) {
                 char *text = xmpp_stanza_get_text(value);
                 if (text != NULL) {
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index 3d925787..b13c2960 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -36,6 +36,7 @@
 #define XMPP_STANZA_H
 
 #include <strophe.h>
+#include <xmpp/xmpp.h>
 
 #define STANZA_NAME_ACTIVE "active"
 #define STANZA_NAME_INACTIVE "inactive"
@@ -154,16 +155,6 @@
 
 #define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo"
 
-typedef struct form_field_t {
-    char *var;
-    GSList *values;
-} FormField;
-
-typedef struct data_form_t {
-    char *form_type;
-    GSList *fields;
-} DataForm;
-
 xmpp_stanza_t* stanza_create_bookmarks_storage_request(xmpp_ctx_t *ctx);
 
 xmpp_stanza_t* stanza_create_chat_state(xmpp_ctx_t *ctx,
@@ -207,6 +198,10 @@ xmpp_stanza_t* stanza_create_instant_room_request_iq(xmpp_ctx_t *ctx,
     const char * const room_jid);
 xmpp_stanza_t* stanza_create_instant_room_destroy_iq(xmpp_ctx_t *ctx,
     const char * const room_jid);
+xmpp_stanza_t* stanza_create_room_config_request_iq(xmpp_ctx_t *ctx,
+    const char * const room_jid);
+xmpp_stanza_t* stanza_create_room_config_cancel_iq(xmpp_ctx_t *ctx,
+    const char * const room_jid);
 
 int stanza_get_idle_time(xmpp_stanza_t * const stanza);
 char * stanza_get_caps_str(xmpp_stanza_t * const stanza);
diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index 78703230..cdb19c27 100644
--- a/src/xmpp/xmpp.h
+++ b/src/xmpp/xmpp.h
@@ -86,6 +86,18 @@ typedef struct disco_identity_t {
     char *category;
 } DiscoIdentity;
 
+typedef struct form_field_t {
+    char *label;
+    char *type;
+    char *var;
+    GSList *values;
+} FormField;
+
+typedef struct data_form_t {
+    char *form_type;
+    GSList *fields;
+} DataForm;
+
 void jabber_init_module(void);
 void bookmark_init_module(void);
 void capabilities_init_module(void);
@@ -141,6 +153,8 @@ void (*iq_disco_items_request)(gchar *jid);
 void (*iq_set_autoping)(int seconds);
 void (*iq_confirm_instant_room)(const char * const room_jid);
 void (*iq_destroy_instant_room)(const char * const room_jid);
+void (*iq_request_room_config_form)(const char * const room_jid);
+void (*iq_room_config_cancel)(const char * const room_jid);
 void (*iq_send_ping)(const char * const target);
 
 // caps functions