--- a/jingle.c Tue Jun 01 09:24:02 2010 +0200
+++ b/jingle.c Tue Jun 01 11:51:25 2010 +0200
@@ -1,7 +1,7 @@
/*
- * jingle.c -- Base jingle functions
+ * jingle.c
*
- * Copyrigth (C) 2010 Nicolas Cornu <nicolas.cornu@ensi-bourges.fr>
+ * Copyrigth (C) 2010 Nicolas Cornu <nicolas.cornu@ensi-bourges.fr>
*
* 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
@@ -21,7 +21,6 @@
#include <glib.h>
#include <loudmouth/loudmouth.h>
-#include <string.h>
#include <mcabber/xmpp.h>
#include <mcabber/hooks.h>
@@ -31,9 +30,9 @@
#include <mcabber/xmpp_defines.h>
#include "jingle.h"
-#include "jingle_register.h"
-#include "parse.h"
-#include "error.h"
+#include "check.h"
+#include "register.h"
+
static void jingle_register_lm_handlers(void);
static void jingle_unregister_lm_handlers(void);
@@ -47,6 +46,28 @@
static guint connect_hid = 0;
static guint disconn_hid = 0;
+/**
+ * Must be aligned with the values in JingleAction
+ * for easy acces.
+ */
+struct JingleActionList jingle_action_list[] = {
+ { NULL, NULL }, // for JINGLE_UNKNOWN_ACTION
+ { "content-accept", NULL },
+ { "content-add", NULL },
+ { "content-modify", NULL },
+ { "content-reject", NULL },
+ { "content-remove", NULL },
+ { "description-info", NULL },
+ { "security-info", NULL },
+ { "session-accept", NULL },
+ { "session-info", NULL },
+ { "session-initiate", NULL },
+ { "session-terminate", NULL },
+ { "transport-accept", NULL },
+ { "transport-info", NULL },
+ { "transport-reject", NULL },
+ { "transport-replace", NULL },
+};
module_info_t info_jingle = {
.branch = MCABBER_BRANCH,
@@ -70,7 +91,8 @@
if (iqtype != LM_MESSAGE_SUB_TYPE_SET)
return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
- struct jingle_data ij;
+ JingleData jd;
+ GError *error;
LmMessageNode *root = lm_message_get_node(message)->children;
LmMessageNode *node = lm_message_node_get_child(root, "jingle");
@@ -82,14 +104,21 @@
return LM_HANDLER_RESULT_REMOVE_MESSAGE;
}
- if (parse_jingle(node, &ij) != PARSE_OK) {
- jingle_error_bad_request(message);
+ check_jingle(node, &jd, &error);
+ if (error != NULL) {
+ if (error->code == JINGLE_CHECK_ERROR) {
+ // request malformed, we reply with a bad-request
+ jingle_error_iq(message, "cancel", "bad-request", NULL);
+ }
return LM_HANDLER_RESULT_REMOVE_MESSAGE;
}
-
- scr_log_print(LPRINT_DEBUG, "jingle: Received a jingle IQ");
-
- jingle_error_iq(message, "cancel", "feature-not-implemented", "unsupported-info");
+
+ scr_log_print(LPRINT_DEBUG, "jingle: Received a valid jingle IQ");
+
+ if (jingle_action_list[jd.action].handler != NULL)
+ jingle_action_list[jd.action].handler(NULL);
+ else
+ jingle_error_iq(message, "cancel", "feature-not-implemented", "unsupported-info");
return LM_HANDLER_RESULT_REMOVE_MESSAGE;
}
@@ -110,6 +139,48 @@
lm_message_unref(r);
}
+/**
+ * Reply to a Jingle IQ with an error.
+ */
+void jingle_error_iq(LmMessage *m, const gchar *errtype,
+ const gchar *cond, const gchar *jinglecond)
+{
+ LmMessage *r;
+ LmMessageNode *err, *tmpnode;
+
+ r = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_ERROR);
+ err = lm_message_node_add_child(r->node, "error", NULL);
+ lm_message_node_set_attribute(err, "type", errtype);
+
+ // error condition as defined by RFC 3920bis section 8.3.3
+ if (cond != NULL) {
+ tmpnode = lm_message_node_add_child(err, cond, NULL);
+ lm_message_node_set_attribute(tmpnode, "xmlns", NS_XMPP_STANZAS);
+ }
+
+ // jingle error condition as defined by XEP-0166 section 10
+ if (jinglecond != NULL) {
+ tmpnode = lm_message_node_add_child(err, jinglecond, NULL);
+ lm_message_node_set_attribute(tmpnode, "xmlns", NS_JINGLE_ERRORS);
+ }
+
+ lm_connection_send(lconnection, r, NULL);
+ lm_message_unref(r);
+}
+
+/**
+ * Find the jingle_action corresponding to a string
+ */
+JingleAction jingle_action_from_str(const gchar* string)
+{
+ guint i, actstrlen = sizeof(jingle_action_list)/sizeof(struct JingleActionList);
+ for (i = 0; i < actstrlen; i++)
+ if (!g_strcmp0(jingle_action_list[i].name, string))
+ return (JingleAction) i;
+
+ return JINGLE_UNKNOWN_ACTION;
+}
+
static void jingle_unregister_lm_handlers(void)
{
if (lconnection) {