Handle incoming session-info
authorNicolas Cornu <nicolas.cornu@ensi-bourges.fr>
Fri, 13 Aug 2010 22:42:29 +0200
changeset 111 76ce876f7935
parent 110 c0341c164405
child 112 77d68793ce61
Handle incoming session-info
jingle-filetransfer/filetransfer.c
jingle/action-handlers.c
jingle/action-handlers.h
jingle/jingle.c
jingle/register.h
--- 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;