jingle/jingle.c
changeset 52 d803c882a182
parent 48 3c08b78be871
child 54 1c1153f9f945
equal deleted inserted replaced
51:0a13062d0a11 52:d803c882a182
    27 #include <mcabber/xmpp.h>
    27 #include <mcabber/xmpp.h>
    28 #include <mcabber/hooks.h>
    28 #include <mcabber/hooks.h>
    29 #include <mcabber/modules.h>
    29 #include <mcabber/modules.h>
    30 #include <mcabber/logprint.h>
    30 #include <mcabber/logprint.h>
    31 #include <mcabber/xmpp_helper.h>
    31 #include <mcabber/xmpp_helper.h>
       
    32 #include <mcabber/events.h>
    32 
    33 
    33 #include <jingle/jingle.h>
    34 #include <jingle/jingle.h>
    34 #include <jingle/check.h>
    35 #include <jingle/check.h>
    35 #include <jingle/action-handlers.h>
    36 #include <jingle/action-handlers.h>
    36 #include <jingle/register.h>
    37 #include <jingle/register.h>
    37 #include <jingle/send.h>
    38 #include <jingle/send.h>
    38 #include <jingle/general-handlers.h>
    39 
    39 
    40 
    40 static void  jingle_register_lm_handlers(void);
    41 static void  jingle_register_lm_handlers(void);
    41 static void  jingle_unregister_lm_handlers(void);
    42 static void  jingle_unregister_lm_handlers(void);
    42 static guint jingle_connect_hh(const gchar *hname, hk_arg_t *args,
    43 static guint jingle_connect_hh(const gchar *hname, hk_arg_t *args,
    43                                gpointer ignore);
    44                                gpointer ignore);
    47 static void  jingle_uninit(void);
    48 static void  jingle_uninit(void);
    48 static void lm_insert_jinglecontent(gpointer data, gpointer userdata);
    49 static void lm_insert_jinglecontent(gpointer data, gpointer userdata);
    49 
    50 
    50 
    51 
    51 static LmMessageHandler* jingle_iq_handler = NULL;
    52 static LmMessageHandler* jingle_iq_handler = NULL;
    52 LmMessageHandler* jingle_ack_iq_handler = NULL;
    53 static GSList *ack_handlers = NULL;
    53 static guint connect_hid = 0;
    54 static guint connect_hid = 0;
    54 static guint disconn_hid = 0;
    55 static guint disconn_hid = 0;
    55 
    56 
    56 /**
    57 /**
    57  * Must be aligned with the values in JingleAction
    58  * Must be aligned with the values in JingleAction
   132 
   133 
   133   return LM_HANDLER_RESULT_REMOVE_MESSAGE;
   134   return LM_HANDLER_RESULT_REMOVE_MESSAGE;
   134 }
   135 }
   135 
   136 
   136 /**
   137 /**
       
   138  * Handle incoming ack iq (type result or error).
       
   139  */
       
   140 LmHandlerResult jingle_handle_ack_iq(LmMessageHandler *handler,
       
   141                                      LmConnection *connection, 
       
   142                                      LmMessage *message, gpointer user_data)
       
   143 {
       
   144   ack_handlers = g_slist_remove(ack_handlers, handler);
       
   145   lm_message_handler_unref(handler);
       
   146 
       
   147   // TODO: check subtype
       
   148   if (user_data != NULL) {
       
   149     JingleAckHandle *ah = user_data;
       
   150     if(ah->callback != NULL)
       
   151       ah->callback(message, ah->user_data);
       
   152 
       
   153     g_free(ah);
       
   154   }
       
   155 
       
   156   return LM_HANDLER_RESULT_REMOVE_MESSAGE;
       
   157 }
       
   158 
       
   159 LmMessageHandler *jingle_new_ack_handler(JingleAckHandle *ah)
       
   160 {
       
   161   LmMessageHandler *h = lm_message_handler_new(jingle_handle_ack_iq,
       
   162                                                (gpointer) ah, NULL);
       
   163   ack_handlers = g_slist_append(ack_handlers, h);
       
   164   return h;
       
   165 }
       
   166 
       
   167 /**
       
   168  * mcabber /event callback.
       
   169  */
       
   170 gboolean evscallback_jingle(guint evcontext, const gchar *arg,
       
   171                             gpointer userdata)
       
   172 {
       
   173   JingleNode *jn = userdata;
       
   174 
       
   175   /*
       
   176   if (G_UNLIKELY(!jn)) {
       
   177     scr_LogPrint(LPRINT_LOGNORM, "Error in evs callback.");
       
   178     return FALSE;
       
   179   }
       
   180   */
       
   181 
       
   182   if (evcontext == EVS_CONTEXT_TIMEOUT) {
       
   183     scr_LogPrint(LPRINT_LOGNORM, "Jingle event from %s timed out, cancelled.",
       
   184                  jn->initiator);
       
   185     jingle_free_jinglenode(jn);
       
   186     return FALSE;
       
   187   }
       
   188   if (evcontext = EVS_CONTEXT_CANCEL) {
       
   189     scr_LogPrint(LPRINT_LOGNORM, "Jingle event from %s cancelled.",
       
   190                  jn->initiator);
       
   191     jingle_free_jinglenode(jn);
       
   192     return FALSE;
       
   193   }
       
   194   if (!(evcontext == EVS_CONTEXT_ACCEPT || evcontext == EVS_CONTEXT_REJECT)) {
       
   195     jingle_free_jinglenode(jn);
       
   196     return FALSE;
       
   197   }
       
   198   
       
   199   if (evcontext == EVS_CONTEXT_ACCEPT) {
       
   200     jingle_send_session_accept(jn);
       
   201   } else {
       
   202     jingle_send_session_terminate(jn, "decline");
       
   203     jingle_free_jinglenode(jn);
       
   204   }
       
   205 
       
   206   return FALSE;
       
   207 }
       
   208 
       
   209 /**
   137  * According to the specifications:
   210  * According to the specifications:
   138  * "An entity that receives an IQ request of type "get" or "set" MUST
   211  * "An entity that receives an IQ request of type "get" or "set" MUST
   139  * reply with an IQ response of type "result" or "error"."
   212  * reply with an IQ response of type "result" or "error"."
   140  * For Jingle's IQ, we have to reply with an empty "result" IQ to acknowledge
   213  * For Jingle's IQ, we have to reply with an empty "result" IQ to acknowledge
   141  * receipt.
   214  * receipt.
   181  * Reply to a Jingle IQ with an error.
   254  * Reply to a Jingle IQ with an error.
   182  */
   255  */
   183 void jingle_send_iq_error(LmMessage *m, const gchar *errtype,
   256 void jingle_send_iq_error(LmMessage *m, const gchar *errtype,
   184                           const gchar *cond, const gchar *jinglecond)
   257                           const gchar *cond, const gchar *jinglecond)
   185 {
   258 {
   186   ack_iq *elem;
       
   187   LmMessage *r = jingle_new_iq_error(m, errtype, cond, jinglecond);
   259   LmMessage *r = jingle_new_iq_error(m, errtype, cond, jinglecond);
   188   if (r) {
   260   if (r) {
   189 	  elem->id = g_strdup(lm_message_get_id(r));
   261     lm_connection_send(lconnection, r, NULL);
   190      elem->callback = NULL;
       
   191      elem->udata = NULL;
       
   192      add_ack_wait(elem);
       
   193      lm_connection_send_with_reply(lconnection, r, jingle_ack_iq_handler, NULL);
       
   194 	  lm_message_unref(r);
       
   195   }
   262   }
   196 }
   263 }
   197 
   264 
   198 /**
   265 /**
   199  * Find the jingle_action corresponding to a string
   266  * Find the jingle_action corresponding to a string
   249 }
   316 }
   250 
   317 
   251 static void jingle_init(void)
   318 static void jingle_init(void)
   252 {
   319 {
   253   jingle_iq_handler = lm_message_handler_new(jingle_handle_iq, NULL, NULL);
   320   jingle_iq_handler = lm_message_handler_new(jingle_handle_iq, NULL, NULL);
   254   jingle_ack_iq_handler = lm_message_handler_new(jingle_handle_ack_iq, NULL,
       
   255                                                  NULL);
       
   256   xmpp_add_feature(NS_JINGLE);
   321   xmpp_add_feature(NS_JINGLE);
   257 
   322 
   258   connect_hid = hk_add_handler(jingle_connect_hh, HOOK_POST_CONNECT,
   323   connect_hid = hk_add_handler(jingle_connect_hh, HOOK_POST_CONNECT,
   259       G_PRIORITY_DEFAULT_IDLE, NULL);
   324       G_PRIORITY_DEFAULT_IDLE, NULL);
   260   disconn_hid = hk_add_handler(jingle_disconn_hh, HOOK_PRE_DISCONNECT,
   325   disconn_hid = hk_add_handler(jingle_disconn_hh, HOOK_PRE_DISCONNECT,
   270   hk_del_handler(HOOK_PRE_DISCONNECT, disconn_hid);
   335   hk_del_handler(HOOK_PRE_DISCONNECT, disconn_hid);
   271   jingle_unregister_lm_handlers();
   336   jingle_unregister_lm_handlers();
   272 
   337 
   273   lm_message_handler_invalidate(jingle_iq_handler);
   338   lm_message_handler_invalidate(jingle_iq_handler);
   274   lm_message_handler_unref(jingle_iq_handler);
   339   lm_message_handler_unref(jingle_iq_handler);
   275   lm_message_handler_invalidate(jingle_ack_iq_handler);
       
   276   lm_message_handler_unref(jingle_ack_iq_handler);
       
   277 }
   340 }
   278 
   341 
   279 LmMessage *lm_message_from_jinglenode(const JingleNode *jn, const gchar *to)
   342 LmMessage *lm_message_from_jinglenode(const JingleNode *jn, const gchar *to)
   280 {
   343 {
   281   LmMessage* m; 
   344   LmMessage* m;