new handlers
authorNicolas Cornu <nicolas.cornu@ensi-bourges.fr>
Thu, 08 Jul 2010 13:54:57 +0200
changeset 38 121e5ae7c1e5
parent 37 fce6bdc1ff46
child 39 405518ad71de
new handlers
jingle/action-handlers.c
jingle/action-handlers.h
jingle/send.c
jingle/sessions.c
jingle/sessions.h
--- a/jingle/action-handlers.c	Thu Jul 08 00:35:37 2010 +0200
+++ b/jingle/action-handlers.c	Thu Jul 08 13:54:57 2010 +0200
@@ -30,14 +30,6 @@
 #include <jingle/send.h>
 #include <jingle/action-handlers.h>
 
-/* The session-initiate action is used to request negotiation of a new Jingle
- * session. When sending a session-initiate with one <content/> element, the
- * value of the <content/> element's 'disposition' attribute MUST be "session"
- * (if there are multiple <content/> elements then at least one MUST have a
- * disposition of "session"); if this rule is violated, the responder MUST
- * return a <bad-request/> error to the initiator.
- */
-
 void handle_content_add(LmMessage *m, JingleNode *jn)
 {
   GError *err = NULL;
@@ -85,7 +77,52 @@
     if (description == NULL || err != NULL) continue;
     transport = transfuncs->check(cn, &err);
     if (transport == NULL || err != NULL) continue;
-    session_add_content(sess, cn);
+    session_add_content(sess, cn, ACTIVE);
+  }
+}
+
+void handle_content_reject(LmMessage *m, JingleNode *jn)
+{
+  GError *err = NULL;
+  GSList *child = NULL;
+  JingleContent *cn;
+  JingleAppFuncs *appfuncs; 
+  JingleTransportFuncs *transfuncs;
+  gconstpointer description, transport;
+  const gchar *xmlns;
+  JingleSession *sess;
+
+  if (!check_contents(jn, &err)) {
+    scr_log_print(LPRINT_DEBUG, "jingle: One of the content element was invalid (%s)",
+                  err->message);
+    jingle_send_iq_error(m, "cancel", "bad-request", NULL);
+    return;
+  }
+
+  /* it's better if there is at least one content elem */
+  if (g_slist_length(jn->content) < 1) {
+    jingle_send_iq_error(m, "cancel", "bad-request", NULL);
+    return;
+  }
+  
+  // if a session with the same sid doesn't already exists
+  if ((sess = session_find(jn)) == NULL) {
+    jingle_send_iq_error(m, "cancel", "unexpected-request", "out-of-order");
+    return;
+  }
+
+  jingle_ack_iq(m);
+
+  for (child = jn->content; child; child = child->next) {
+    cn = (JingleContent *)(child->data);
+    session_remove_sessioncontent(sess, cn->name);
+  }
+  
+  // If there is nothing more to do, close the session
+  if (g_slist_length(sess->content) == 0) {
+    jingle_send_session_terminate(jn, "success");
+    session_delete(sess);
+    return;
   }
 }
 
@@ -123,23 +160,17 @@
 
   for (child = jn->content; child; child = child->next) {
     cn = (JingleContent *)(child->data);
-    
-    xmlns = lm_message_node_get_attribute(cn->description, "xmlns");
-    appfuncs = jingle_get_appfuncs(xmlns);
-    if (appfuncs == NULL) continue;
-    
-    xmlns = lm_message_node_get_attribute(cn->transport, "xmlns");
-    transfuncs = jingle_get_transportfuncs(xmlns);
-    if (appfuncs == NULL) continue;
-    
-    description = appfuncs->check(cn, &err);
-    if (description == NULL || err != NULL) continue;
-    transport = transfuncs->check(cn, &err);
-    if (transport == NULL || err != NULL) continue;
-    session_add_content(sess, cn);
+    session_remove_sessioncontent(sess, cn->name);
   }
 }
 
+/* The session-initiate action is used to request negotiation of a new Jingle
+ * session. When sending a session-initiate with one <content/> element, the
+ * value of the <content/> element's 'disposition' attribute MUST be "session"
+ * (if there are multiple <content/> elements then at least one MUST have a
+ * disposition of "session"); if this rule is violated, the responder MUST
+ * return a <bad-request/> error to the initiator.
+ */
 void handle_session_initiate(LmMessage *m, JingleNode *jn)
 {
   GError *err = NULL;
@@ -205,13 +236,16 @@
     transport = transfuncs->check(cn, &err);
     if (transport == NULL || err != NULL) continue;
     
-    session_add_content(sess, cn);
+    session_add_content(sess, cn, ACTIVE);
   }
   
   if(g_slist_length(sess->content) == 0) {
     jingle_send_session_terminate(jn, "unsupported-applications");
+    session_delete(sess);
+    return;
   }
   
+  // Send a session-accept
   
 }
 
--- a/jingle/action-handlers.h	Thu Jul 08 00:35:37 2010 +0200
+++ b/jingle/action-handlers.h	Thu Jul 08 13:54:57 2010 +0200
@@ -5,6 +5,8 @@
 #include <loudmouth/loudmouth.h>
 
 void handle_content_add(LmMessage *m, JingleNode *jn);
+void handle_content_reject(LmMessage *m, JingleNode *jn);
+void handle_content_remove(LmMessage *m, JingleNode *jn);
 void handle_session_initiate(LmMessage *m, JingleNode *jn);
 void handle_session_terminate(LmMessage *m, JingleNode *jn);
 const gchar* get_xmlnsdesc(const GSList* list);
--- a/jingle/send.c	Thu Jul 08 00:35:37 2010 +0200
+++ b/jingle/send.c	Thu Jul 08 13:54:57 2010 +0200
@@ -51,3 +51,4 @@
     lm_message_unref(r);
   }
 }
+
--- a/jingle/sessions.c	Thu Jul 08 00:35:37 2010 +0200
+++ b/jingle/sessions.c	Thu Jul 08 13:54:57 2010 +0200
@@ -70,11 +70,13 @@
   return session_find_by_sid(jn->sid, from);
 }
 
-void session_add_content(JingleSession *sess, JingleContent *cn)
+void session_add_content(JingleSession *sess, JingleContent *cn,
+                         SessionState state)
 {
   SessionContent *sc = g_new0(SessionContent, 1);
   
   sc->name = cn->name;
+  sc->state = state;
   
   const gchar *tmpchar = lm_message_node_get_attribute(cn->description,
                                                        "xmlns");
@@ -105,8 +107,20 @@
 {
   SessionContent *sc;
   sc = session_find_sessioncontent(sess, name);
+  if(sc == NULL) return;
+
+  if (sc->state == ACTIVE); // We should stop the transfert
+
+  sess->content = g_slist_remove(sess->content, sc);
+}
+
+void session_changestate_sessioncontent(JingleSession *sess, const gchar *name,
+                                        SessionState state)
+{
+  SessionContent *sc;
+  sc = session_find_sessioncontent(sess, name);
   if(sc != NULL)
-    sess->content = g_slist_remove(sess->content, sc);
+    sc->state = state;
 }
 
 /**
--- a/jingle/sessions.h	Thu Jul 08 00:35:37 2010 +0200
+++ b/jingle/sessions.h	Thu Jul 08 13:54:57 2010 +0200
@@ -10,6 +10,11 @@
   JINGLE_SESSION_
 } JingleStatus;
 
+typedef enum {
+  ACTIVE,
+  PENDING,
+} SessionState;
+
 typedef struct {
   JingleStatus  status;
   gchar *sid;
@@ -20,6 +25,7 @@
 
 typedef struct {
   const gchar *name;
+  SessionState state;
   gconstpointer description;
   JingleAppFuncs *appfuncs;
   gconstpointer transport;
@@ -30,9 +36,11 @@
 JingleSession *session_new(JingleNode *jn);
 JingleSession *session_find_by_sid(const gchar *sid, const gchar *from);
 JingleSession *session_find(const JingleNode *jn);
-void session_add_content(JingleSession *sess, JingleContent *cn);
+void session_add_content(JingleSession *sess, JingleContent *cn, SessionState state);
 SessionContent *session_find_sessioncontent(JingleSession *sess, const gchar *name);
 void session_remove_sessioncontent(JingleSession *sess, const gchar *name);
+void session_changestate_sessioncontent(JingleSession *sess, const gchar *name,
+                                        SessionState state);
 void session_delete(JingleSession *sess);
 void session_remove(JingleSession *sess);
 void session_free(JingleSession *sess);