jingle/action-handlers.c
changeset 38 121e5ae7c1e5
parent 37 fce6bdc1ff46
child 39 405518ad71de
equal deleted inserted replaced
37:fce6bdc1ff46 38:121e5ae7c1e5
    27 #include <jingle/check.h>
    27 #include <jingle/check.h>
    28 #include <jingle/sessions.h>
    28 #include <jingle/sessions.h>
    29 #include <jingle/register.h>
    29 #include <jingle/register.h>
    30 #include <jingle/send.h>
    30 #include <jingle/send.h>
    31 #include <jingle/action-handlers.h>
    31 #include <jingle/action-handlers.h>
       
    32 
       
    33 void handle_content_add(LmMessage *m, JingleNode *jn)
       
    34 {
       
    35   GError *err = NULL;
       
    36   GSList *child = NULL;
       
    37   JingleContent *cn;
       
    38   JingleAppFuncs *appfuncs; 
       
    39   JingleTransportFuncs *transfuncs;
       
    40   gconstpointer description, transport;
       
    41   const gchar *xmlns;
       
    42   JingleSession *sess;
       
    43 
       
    44   if (!check_contents(jn, &err)) {
       
    45     scr_log_print(LPRINT_DEBUG, "jingle: One of the content element was invalid (%s)",
       
    46                   err->message);
       
    47     jingle_send_iq_error(m, "cancel", "bad-request", NULL);
       
    48     return;
       
    49   }
       
    50 
       
    51   /* it's better if there is at least one content elem */
       
    52   if (g_slist_length(jn->content) < 1) {
       
    53     jingle_send_iq_error(m, "cancel", "bad-request", NULL);
       
    54     return;
       
    55   }
       
    56   
       
    57   // if a session with the same sid doesn't already exists
       
    58   if ((sess = session_find(jn)) == NULL) {
       
    59     jingle_send_iq_error(m, "cancel", "unexpected-request", "out-of-order");
       
    60     return;
       
    61   }
       
    62 
       
    63   jingle_ack_iq(m);
       
    64 
       
    65   for (child = jn->content; child; child = child->next) {
       
    66     cn = (JingleContent *)(child->data);
       
    67     
       
    68     xmlns = lm_message_node_get_attribute(cn->description, "xmlns");
       
    69     appfuncs = jingle_get_appfuncs(xmlns);
       
    70     if (appfuncs == NULL) continue;
       
    71     
       
    72     xmlns = lm_message_node_get_attribute(cn->transport, "xmlns");
       
    73     transfuncs = jingle_get_transportfuncs(xmlns);
       
    74     if (appfuncs == NULL) continue;
       
    75     
       
    76     description = appfuncs->check(cn, &err);
       
    77     if (description == NULL || err != NULL) continue;
       
    78     transport = transfuncs->check(cn, &err);
       
    79     if (transport == NULL || err != NULL) continue;
       
    80     session_add_content(sess, cn, ACTIVE);
       
    81   }
       
    82 }
       
    83 
       
    84 void handle_content_reject(LmMessage *m, JingleNode *jn)
       
    85 {
       
    86   GError *err = NULL;
       
    87   GSList *child = NULL;
       
    88   JingleContent *cn;
       
    89   JingleAppFuncs *appfuncs; 
       
    90   JingleTransportFuncs *transfuncs;
       
    91   gconstpointer description, transport;
       
    92   const gchar *xmlns;
       
    93   JingleSession *sess;
       
    94 
       
    95   if (!check_contents(jn, &err)) {
       
    96     scr_log_print(LPRINT_DEBUG, "jingle: One of the content element was invalid (%s)",
       
    97                   err->message);
       
    98     jingle_send_iq_error(m, "cancel", "bad-request", NULL);
       
    99     return;
       
   100   }
       
   101 
       
   102   /* it's better if there is at least one content elem */
       
   103   if (g_slist_length(jn->content) < 1) {
       
   104     jingle_send_iq_error(m, "cancel", "bad-request", NULL);
       
   105     return;
       
   106   }
       
   107   
       
   108   // if a session with the same sid doesn't already exists
       
   109   if ((sess = session_find(jn)) == NULL) {
       
   110     jingle_send_iq_error(m, "cancel", "unexpected-request", "out-of-order");
       
   111     return;
       
   112   }
       
   113 
       
   114   jingle_ack_iq(m);
       
   115 
       
   116   for (child = jn->content; child; child = child->next) {
       
   117     cn = (JingleContent *)(child->data);
       
   118     session_remove_sessioncontent(sess, cn->name);
       
   119   }
       
   120   
       
   121   // If there is nothing more to do, close the session
       
   122   if (g_slist_length(sess->content) == 0) {
       
   123     jingle_send_session_terminate(jn, "success");
       
   124     session_delete(sess);
       
   125     return;
       
   126   }
       
   127 }
       
   128 
       
   129 void handle_content_remove(LmMessage *m, JingleNode *jn)
       
   130 {
       
   131   GError *err = NULL;
       
   132   GSList *child = NULL;
       
   133   JingleContent *cn;
       
   134   JingleAppFuncs *appfuncs; 
       
   135   JingleTransportFuncs *transfuncs;
       
   136   gconstpointer description, transport;
       
   137   const gchar *xmlns;
       
   138   JingleSession *sess;
       
   139 
       
   140   if (!check_contents(jn, &err)) {
       
   141     scr_log_print(LPRINT_DEBUG, "jingle: One of the content element was invalid (%s)",
       
   142                   err->message);
       
   143     jingle_send_iq_error(m, "cancel", "bad-request", NULL);
       
   144     return;
       
   145   }
       
   146 
       
   147   /* it's better if there is at least one content elem */
       
   148   if (g_slist_length(jn->content) < 1) {
       
   149     jingle_send_iq_error(m, "cancel", "bad-request", NULL);
       
   150     return;
       
   151   }
       
   152   
       
   153   // if a session with the same sid doesn't already exists
       
   154   if ((sess = session_find(jn)) == NULL) {
       
   155     jingle_send_iq_error(m, "cancel", "unexpected-request", "out-of-order");
       
   156     return;
       
   157   }
       
   158 
       
   159   jingle_ack_iq(m);
       
   160 
       
   161   for (child = jn->content; child; child = child->next) {
       
   162     cn = (JingleContent *)(child->data);
       
   163     session_remove_sessioncontent(sess, cn->name);
       
   164   }
       
   165 }
    32 
   166 
    33 /* The session-initiate action is used to request negotiation of a new Jingle
   167 /* The session-initiate action is used to request negotiation of a new Jingle
    34  * session. When sending a session-initiate with one <content/> element, the
   168  * session. When sending a session-initiate with one <content/> element, the
    35  * value of the <content/> element's 'disposition' attribute MUST be "session"
   169  * value of the <content/> element's 'disposition' attribute MUST be "session"
    36  * (if there are multiple <content/> elements then at least one MUST have a
   170  * (if there are multiple <content/> elements then at least one MUST have a
    37  * disposition of "session"); if this rule is violated, the responder MUST
   171  * disposition of "session"); if this rule is violated, the responder MUST
    38  * return a <bad-request/> error to the initiator.
   172  * return a <bad-request/> error to the initiator.
    39  */
   173  */
    40 
       
    41 void handle_content_add(LmMessage *m, JingleNode *jn)
       
    42 {
       
    43   GError *err = NULL;
       
    44   GSList *child = NULL;
       
    45   JingleContent *cn;
       
    46   JingleAppFuncs *appfuncs; 
       
    47   JingleTransportFuncs *transfuncs;
       
    48   gconstpointer description, transport;
       
    49   const gchar *xmlns;
       
    50   JingleSession *sess;
       
    51 
       
    52   if (!check_contents(jn, &err)) {
       
    53     scr_log_print(LPRINT_DEBUG, "jingle: One of the content element was invalid (%s)",
       
    54                   err->message);
       
    55     jingle_send_iq_error(m, "cancel", "bad-request", NULL);
       
    56     return;
       
    57   }
       
    58 
       
    59   /* it's better if there is at least one content elem */
       
    60   if (g_slist_length(jn->content) < 1) {
       
    61     jingle_send_iq_error(m, "cancel", "bad-request", NULL);
       
    62     return;
       
    63   }
       
    64   
       
    65   // if a session with the same sid doesn't already exists
       
    66   if ((sess = session_find(jn)) == NULL) {
       
    67     jingle_send_iq_error(m, "cancel", "unexpected-request", "out-of-order");
       
    68     return;
       
    69   }
       
    70 
       
    71   jingle_ack_iq(m);
       
    72 
       
    73   for (child = jn->content; child; child = child->next) {
       
    74     cn = (JingleContent *)(child->data);
       
    75     
       
    76     xmlns = lm_message_node_get_attribute(cn->description, "xmlns");
       
    77     appfuncs = jingle_get_appfuncs(xmlns);
       
    78     if (appfuncs == NULL) continue;
       
    79     
       
    80     xmlns = lm_message_node_get_attribute(cn->transport, "xmlns");
       
    81     transfuncs = jingle_get_transportfuncs(xmlns);
       
    82     if (appfuncs == NULL) continue;
       
    83     
       
    84     description = appfuncs->check(cn, &err);
       
    85     if (description == NULL || err != NULL) continue;
       
    86     transport = transfuncs->check(cn, &err);
       
    87     if (transport == NULL || err != NULL) continue;
       
    88     session_add_content(sess, cn);
       
    89   }
       
    90 }
       
    91 
       
    92 void handle_content_remove(LmMessage *m, JingleNode *jn)
       
    93 {
       
    94   GError *err = NULL;
       
    95   GSList *child = NULL;
       
    96   JingleContent *cn;
       
    97   JingleAppFuncs *appfuncs; 
       
    98   JingleTransportFuncs *transfuncs;
       
    99   gconstpointer description, transport;
       
   100   const gchar *xmlns;
       
   101   JingleSession *sess;
       
   102 
       
   103   if (!check_contents(jn, &err)) {
       
   104     scr_log_print(LPRINT_DEBUG, "jingle: One of the content element was invalid (%s)",
       
   105                   err->message);
       
   106     jingle_send_iq_error(m, "cancel", "bad-request", NULL);
       
   107     return;
       
   108   }
       
   109 
       
   110   /* it's better if there is at least one content elem */
       
   111   if (g_slist_length(jn->content) < 1) {
       
   112     jingle_send_iq_error(m, "cancel", "bad-request", NULL);
       
   113     return;
       
   114   }
       
   115   
       
   116   // if a session with the same sid doesn't already exists
       
   117   if ((sess = session_find(jn)) == NULL) {
       
   118     jingle_send_iq_error(m, "cancel", "unexpected-request", "out-of-order");
       
   119     return;
       
   120   }
       
   121 
       
   122   jingle_ack_iq(m);
       
   123 
       
   124   for (child = jn->content; child; child = child->next) {
       
   125     cn = (JingleContent *)(child->data);
       
   126     
       
   127     xmlns = lm_message_node_get_attribute(cn->description, "xmlns");
       
   128     appfuncs = jingle_get_appfuncs(xmlns);
       
   129     if (appfuncs == NULL) continue;
       
   130     
       
   131     xmlns = lm_message_node_get_attribute(cn->transport, "xmlns");
       
   132     transfuncs = jingle_get_transportfuncs(xmlns);
       
   133     if (appfuncs == NULL) continue;
       
   134     
       
   135     description = appfuncs->check(cn, &err);
       
   136     if (description == NULL || err != NULL) continue;
       
   137     transport = transfuncs->check(cn, &err);
       
   138     if (transport == NULL || err != NULL) continue;
       
   139     session_add_content(sess, cn);
       
   140   }
       
   141 }
       
   142 
       
   143 void handle_session_initiate(LmMessage *m, JingleNode *jn)
   174 void handle_session_initiate(LmMessage *m, JingleNode *jn)
   144 {
   175 {
   145   GError *err = NULL;
   176   GError *err = NULL;
   146   GSList *child = NULL;
   177   GSList *child = NULL;
   147   gboolean valid_disposition = FALSE;
   178   gboolean valid_disposition = FALSE;
   203     description = appfuncs->check(cn, &err);
   234     description = appfuncs->check(cn, &err);
   204     if (description == NULL || err != NULL) continue;
   235     if (description == NULL || err != NULL) continue;
   205     transport = transfuncs->check(cn, &err);
   236     transport = transfuncs->check(cn, &err);
   206     if (transport == NULL || err != NULL) continue;
   237     if (transport == NULL || err != NULL) continue;
   207     
   238     
   208     session_add_content(sess, cn);
   239     session_add_content(sess, cn, ACTIVE);
   209   }
   240   }
   210   
   241   
   211   if(g_slist_length(sess->content) == 0) {
   242   if(g_slist_length(sess->content) == 0) {
   212     jingle_send_session_terminate(jn, "unsupported-applications");
   243     jingle_send_session_terminate(jn, "unsupported-applications");
   213   }
   244     session_delete(sess);
   214   
   245     return;
       
   246   }
       
   247   
       
   248   // Send a session-accept
   215   
   249   
   216 }
   250 }
   217 
   251 
   218 void handle_session_terminate(LmMessage *m, JingleNode *jn)
   252 void handle_session_terminate(LmMessage *m, JingleNode *jn)
   219 {
   253 {