--- a/jingle-filetransfer/filetransfer.c Fri Aug 13 20:34:44 2010 +0200
+++ b/jingle-filetransfer/filetransfer.c Fri Aug 13 22:42:29 2010 +0200
@@ -45,6 +45,7 @@
gconstpointer jingle_ft_check(JingleContent *cn, GError **err);
+gboolean jingle_ft_handle(JingleAction action, gconstpointer data, LmMessageNode *node);
void jingle_ft_tomessage(gconstpointer data, LmMessageNode *node);
gboolean jingle_ft_handle_data(gconstpointer data, const gchar *data2, guint len);
void jingle_ft_start(session_content *sc, gsize size);
@@ -59,12 +60,13 @@
const gchar *deps[] = { "jingle", NULL };
static JingleAppFuncs funcs = {
- jingle_ft_check,
- jingle_ft_tomessage,
- jingle_ft_handle_data,
- jingle_ft_start,
- jingle_ft_send,
- jingle_ft_stop
+ .check = jingle_ft_check,
+ .handle = jingle_ft_handle,
+ .tomessage = jingle_ft_tomessage,
+ .handle_data = jingle_ft_handle_data,
+ .start = jingle_ft_start,
+ .send = jingle_ft_send,
+ .stop = jingle_ft_stop
};
module_info_t info_jingle_filetransfer = {
@@ -160,6 +162,16 @@
return (gconstpointer) ft;
}
+gboolean jingle_ft_handle(JingleAction action, gconstpointer data, LmMessageNode *node)
+{
+ if (action == JINGLE_SESSION_INFO) {
+ if (!g_strcmp0(lm_message_node_get_attribute(node, "xmlns"), NS_JINGLE_APP_FT_INFO)
+ && !g_strcmp0(node->name, "hash")) {
+ ((JingleFT *)data)->hash = lm_message_node_get_value(node);
+ }
+ }
+}
+
static gboolean is_md5_hash(const gchar *hash)
{
int i = 0;
@@ -420,21 +432,21 @@
void jingle_ft_stop(gconstpointer data)
{
JingleFT *jft = (JingleFT*)data;
-
+
if (jft->hash != NULL) {
if (g_strcmp0(jft->hash, g_checksum_get_string(jft->md5))) {
scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: File corrupt (%s)", jft->name);
} else {
- scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: transfer finish (%s) and verified", jft->name);
+ scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: transfer finished (%s) and verified", jft->name);
}
} else {
- scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: transfer finish (%s) but not verified", jft->name);
+ scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: transfer finished (%s) but not verified", jft->name);
}
-
+
g_checksum_free(jft->md5);
-
+
g_io_channel_flush(jft->outfile, NULL);
-
+
g_io_channel_unref(jft->outfile);
}
--- a/jingle/action-handlers.c Fri Aug 13 20:34:44 2010 +0200
+++ b/jingle/action-handlers.c Fri Aug 13 22:42:29 2010 +0200
@@ -336,6 +336,48 @@
g_free(disp);
}
+void handle_session_info(JingleNode *jn)
+{
+ JingleSession *sess;
+ SessionContent *sc;
+ GSList *el;
+
+ if ((sess = session_find(jn)) == NULL) {
+ jingle_send_iq_error(jn->message, "cancel", "item-not-found", "unknown-session");
+ return;
+ }
+
+ /* "If either party receives an empty session-info message
+ * for an active session, it MUST send an empty IQ result;
+ * this usage functions as a "ping" to determine session
+ * vitality via the XMPP signalling channel." */
+ if (jn->node->children == NULL) {
+ jingle_ack_iq(jn->message);
+ return;
+ }
+
+ /* We don't know the app to which the message is addressed.
+ * Only the app module itself may know, based on the element
+ * name and its xmlns, so we need to try every app module. */
+ for (el = sess->content; el; el = el->next) {
+ sc = (SessionContent*)el->data;
+ if (sc->appfuncs->handle == NULL)
+ continue;
+
+ if (sc->appfuncs->handle(JINGLE_SESSION_INFO, sc->description,
+ jn->node->children)) {
+ jingle_ack_iq(jn->message);
+ return;
+ }
+ }
+ /* "If the party that receives an informational message
+ * does not understand the payload, it MUST return a
+ * <feature-not-implemented/> error with a Jingle-specific
+ * error condition of <unsupported-info/>." */
+ jingle_send_iq_error(jn->message, "modify", "feature-not-implemented",
+ "unsupported-info");
+}
+
void handle_session_accept(JingleNode *jn)
{
JingleSession *sess;
--- a/jingle/action-handlers.h Fri Aug 13 20:34:44 2010 +0200
+++ b/jingle/action-handlers.h Fri Aug 13 22:42:29 2010 +0200
@@ -4,11 +4,14 @@
#include <glib.h>
#include <loudmouth/loudmouth.h>
+
void handle_content_accept(JingleNode *jn);
void handle_content_add(JingleNode *jn);
void handle_content_reject(JingleNode *jn);
void handle_content_remove(JingleNode *jn);
void handle_session_accept(JingleNode *jn);
+void handle_session_info(JingleNode *jn);
void handle_session_initiate(JingleNode *jn);
void handle_session_terminate(JingleNode *jn);
+
#endif
--- a/jingle/jingle.c Fri Aug 13 20:34:44 2010 +0200
+++ b/jingle/jingle.c Fri Aug 13 22:42:29 2010 +0200
@@ -69,7 +69,7 @@
{ "description-info", NULL },
{ "security-info", NULL },
{ "session-accept", handle_session_accept },
- { "session-info", NULL },
+ { "session-info", handle_session_info },
{ "session-initiate", handle_session_initiate },
{ "session-terminate", handle_session_terminate },
{ "transport-accept", NULL },
--- a/jingle/register.h Fri Aug 13 20:34:44 2010 +0200
+++ b/jingle/register.h Fri Aug 13 22:42:29 2010 +0200
@@ -35,6 +35,7 @@
} JingleTransportPriority;
typedef gconstpointer (*JingleAppCheck) (JingleContent *cn, GError **err);
+typedef gboolean (*JingleAppHandle) (JingleAction action, gconstpointer data, LmMessageNode *node);
typedef void (*JingleAppToMessage) (gconstpointer data, LmMessageNode *node);
typedef gboolean (*JingleAppHandleData) (gconstpointer data, const gchar *data2, guint len);
typedef void (*JingleAppStart) (session_content *sc, gsize size);
@@ -52,30 +53,35 @@
/* check if the description of a JingleContent is correct */
JingleAppCheck check;
+ /* handle an incoming jingle message (session-info, description-info...).
+ * If the function could not handle the incoming data, the caller should
+ * reply to the incoming message with an error iq */
+ JingleAppHandle handle;
+
/* Insert data from the gconstpointer to the node given as an argument */
JingleAppToMessage tomessage;
-
+
JingleAppHandleData handle_data;
-
+
JingleAppStart start;
-
+
JingleAppSend send;
-
+
JingleAppStop stop;
} JingleAppFuncs;
typedef struct {
JingleTransportxmlns xmlns;
-
+
JingleTransportCheck check;
JingleTransportToMessage tomessage;
-
+
JingleTransportCmp cmp;
-
+
JingleTransportNew new;
-
+
JingleTransportSend send;
} JingleTransportFuncs;