# HG changeset patch # User Nicolas Cornu # Date 1281805587 -7200 # Node ID 0b9a7b505079c9954ce8aebd886897e92678b5de # Parent f3408f4fe61a7c34ca6dc3f6688f4d73318cff84 create the session when receiving a session-initiate diff -r f3408f4fe61a -r 0b9a7b505079 jingle-filetransfer/filetransfer.c --- a/jingle-filetransfer/filetransfer.c Sat Aug 14 12:00:59 2010 +0200 +++ b/jingle-filetransfer/filetransfer.c Sat Aug 14 19:06:27 2010 +0200 @@ -152,7 +152,7 @@ // check if the md5 hash is valid ([a-fA-F0-9){32}) if (ft->hash != NULL && (strlen(ft->hash) != 32 || !is_md5_hash(ft->hash))) { g_set_error(err, JINGLE_CHECK_ERROR, JINGLE_CHECK_ERROR_BADVALUE, - "the offered file has an invalid filename"); + "the offered file has an invalid hash"); g_free(ft->name); g_free(ft); return NULL; @@ -162,12 +162,14 @@ return (gconstpointer) ft; } -gboolean jingle_ft_handle(JingleAction action, gconstpointer data, LmMessageNode *node) +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) + 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); + ((JingleFT *)data)->hash = g_strdup(lm_message_node_get_value(node)); return TRUE; } return FALSE; @@ -276,6 +278,7 @@ jft->desc = g_strdup(args[0]); jft->type = JINGLE_FT_OFFER; jft->name = g_path_get_basename(filename); + // TODO: Transform date to a good format (ios8601) jft->date = fileinfo.st_mtime; jft->size = fileinfo.st_size; jft->outfile = g_io_channel_new_file (filename, "r", NULL); @@ -435,7 +438,7 @@ { JingleFT *jft = (JingleFT*)data; - if (jft->hash != NULL) { + if (jft->hash != NULL && jft->md5 != 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 { @@ -447,9 +450,11 @@ g_checksum_free(jft->md5); - g_io_channel_flush(jft->outfile, NULL); + if (jft->outfile != NULL) { + g_io_channel_flush(jft->outfile, NULL); - g_io_channel_unref(jft->outfile); + g_io_channel_unref(jft->outfile); + } } static void jingle_ft_init(void) diff -r f3408f4fe61a -r 0b9a7b505079 jingle-ibb/ibb.c --- a/jingle-ibb/ibb.c Sat Aug 14 12:00:59 2010 +0200 +++ b/jingle-ibb/ibb.c Sat Aug 14 19:06:27 2010 +0200 @@ -88,7 +88,7 @@ ibb = g_new0(JingleIBB, 1); blocksize = lm_message_node_get_attribute(node, "block-size"); - ibb->sid = lm_message_node_get_attribute(node, "sid"); + ibb->sid = g_strdup(lm_message_node_get_attribute(node, "sid")); if (!ibb->sid || !blocksize) { g_set_error(err, JINGLE_CHECK_ERROR, JINGLE_CHECK_ERROR_MISSING, diff -r f3408f4fe61a -r 0b9a7b505079 jingle/action-handlers.c --- a/jingle/action-handlers.c Sat Aug 14 12:00:59 2010 +0200 +++ b/jingle/action-handlers.c Sat Aug 14 19:06:27 2010 +0200 @@ -75,6 +75,7 @@ cn = (JingleContent *)(child->data); session_changestate_sessioncontent(sess, cn->name, JINGLE_SESSION_STATE_ACTIVE); } + jingle_free_jinglenode(jn); } void handle_content_add(JingleNode *jn) @@ -172,6 +173,7 @@ } } } + jingle_free_jinglenode(jn); } void handle_content_reject(JingleNode *jn) @@ -215,6 +217,7 @@ session_delete(sess); return; } + jingle_free_jinglenode(jn); } void handle_content_remove(JingleNode *jn) @@ -232,18 +235,22 @@ scr_log_print(LPRINT_DEBUG, "jingle: One of the content element was invalid (%s)", err->message); jingle_send_iq_error(jn->message, "cancel", "bad-request", NULL); + jingle_free_jinglenode(jn); return; } /* it's better if there is at least one content elem */ if (g_slist_length(jn->content) < 1) { jingle_send_iq_error(jn->message, "cancel", "bad-request", NULL); + jingle_free_jinglenode(jn); return; } // if a session with the same sid doesn't already exists if ((sess = session_find(jn)) == NULL) { + // TODO: look if it's really that jingle_send_iq_error(jn->message, "cancel", "item-not-found", "unknown-session"); + jingle_free_jinglenode(jn); return; } @@ -253,6 +260,7 @@ cn = (JingleContent *)(child->data); session_remove_sessioncontent(sess, cn->name); } + jingle_free_jinglenode(jn); } void handle_session_initiate(JingleNode *jn) @@ -264,11 +272,17 @@ GSList *child = NULL; LmMessage *r; gchar *disp; + JingleSession *sess; + const gchar *xmlns; + JingleAppFuncs *appfuncs; + JingleTransportFuncs *transfuncs; + gconstpointer description, transport; // Make sure the request come from an user in our roster disp = jidtodisp(lm_message_get_from(jn->message)); if (!roster_find(disp, jidsearch, 0)) { - // jingle_send_session_terminate(jn, "decline"); + // We say that we doesn't support jingle. + jingle_send_iq_error(jn->message, "cancel", "service-unavailable", NULL); jingle_free_jinglenode(jn); g_free(disp); return; @@ -278,6 +292,7 @@ scr_log_print(LPRINT_DEBUG, "jingle: One of the content element was invalid (%s)", err->message); jingle_send_iq_error(jn->message, "cancel", "bad-request", NULL); + jingle_free_jinglenode(jn); g_free(disp); return; } @@ -285,6 +300,7 @@ // a session-initiate message must contains at least one element if (g_slist_length(jn->content) < 1) { jingle_send_iq_error(jn->message, "cancel", "bad-request", NULL); + jingle_free_jinglenode(jn); g_free(disp); return; } @@ -301,6 +317,7 @@ if (!valid_disposition) { jingle_send_iq_error(jn->message, "cancel", "bad-request", NULL); g_free(disp); + jingle_free_jinglenode(jn); return; } @@ -308,23 +325,55 @@ if (session_find(jn) != NULL) { jingle_send_iq_error(jn->message, "cancel", "unexpected-request", "out-of-order"); g_free(disp); + jingle_free_jinglenode(jn); return; } jingle_ack_iq(jn->message); + // We create a session + sess = session_new_from_jinglenode(jn); + + 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 (transfuncs == 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_from_jinglecontent(sess, cn, + JINGLE_SESSION_STATE_PENDING); + } + + if(g_slist_length(sess->content) == 0) { + jingle_send_session_terminate(sess, "unsupported-applications"); + session_delete(sess); + return; + } + // Wait that user accept the jingle sbuf = g_string_new(""); - g_string_printf(sbuf, "Received an invitation for a jingle session from <%s>", lm_message_get_from(jn->message)); + g_string_printf(sbuf, "Received an invitation for a jingle session from <%s>", + lm_message_get_from(jn->message)); scr_WriteIncomingMessage(disp, sbuf->str, 0, HBB_PREFIX_INFO, 0); scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str); { const char *id; - char *desc = g_strdup_printf("<%s> invites you to do a jingle session", lm_message_get_from(jn->message)); + char *desc = g_strdup_printf("<%s> invites you to do a jingle session", + lm_message_get_from(jn->message)); - id = evs_new(desc, NULL, 0, evscallback_jingle, jn, NULL); + id = evs_new(desc, NULL, 0, evscallback_jingle, sess, NULL); g_free(desc); if (id) g_string_printf(sbuf, "Please use /event %s accept|reject", id); @@ -334,6 +383,7 @@ scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str); } g_free(disp); + jingle_free_jinglenode(jn); } void handle_session_info(JingleNode *jn) @@ -376,6 +426,7 @@ * error condition of ." */ jingle_send_iq_error(jn->message, "modify", "feature-not-implemented", "unsupported-info"); + jingle_free_jinglenode(jn); } void handle_session_accept(JingleNode *jn) @@ -421,7 +472,7 @@ sc2->name = sc->name; sc->appfuncs->start(sc2, 2048); } - + jingle_free_jinglenode(jn); } void handle_session_terminate(JingleNode *jn) @@ -444,4 +495,5 @@ } session_delete(sess); jingle_ack_iq(jn->message); + jingle_free_jinglenode(jn); } diff -r f3408f4fe61a -r 0b9a7b505079 jingle/jingle.c --- a/jingle/jingle.c Sat Aug 14 12:00:59 2010 +0200 +++ b/jingle/jingle.c Sat Aug 14 19:06:27 2010 +0200 @@ -173,7 +173,7 @@ gboolean evscallback_jingle(guint evcontext, const gchar *arg, gpointer userdata) { - JingleNode *jn = userdata; + JingleSession *js = (JingleSession*)userdata; /* if (G_UNLIKELY(!jn)) { @@ -184,33 +184,28 @@ if (evcontext == EVS_CONTEXT_TIMEOUT) { scr_LogPrint(LPRINT_LOGNORM, "Jingle event from %s timed out, cancelled.", - jn->initiator); - jingle_free_jinglenode(jn); + js->from); return FALSE; } if (evcontext == EVS_CONTEXT_CANCEL) { scr_LogPrint(LPRINT_LOGNORM, "Jingle event from %s cancelled.", - jn->initiator); - jingle_free_jinglenode(jn); + js->from); return FALSE; } if (!(evcontext == EVS_CONTEXT_ACCEPT || evcontext == EVS_CONTEXT_REJECT)) { scr_LogPrint(LPRINT_LOGNORM, "Jingle event from %s cancelled.", - jn->initiator); - jingle_free_jinglenode(jn); + js->from); return FALSE; } if (evcontext == EVS_CONTEXT_ACCEPT) { scr_LogPrint(LPRINT_LOGNORM, "Jingle event from %s accepted.", - jn->initiator); - jingle_send_session_accept(jn); - + js->from); + jingle_send_session_accept(js); } else { scr_LogPrint(LPRINT_LOGNORM, "Jingle event from %s cancelled.", - jn->initiator); - // TODO: jingle_send_session_terminate(jn, "decline"); - jingle_free_jinglenode(jn); + js->from); + jingle_send_session_terminate(js, "decline"); } return FALSE; diff -r f3408f4fe61a -r 0b9a7b505079 jingle/send.c --- a/jingle/send.c Sat Aug 14 12:00:59 2010 +0200 +++ b/jingle/send.c Sat Aug 14 19:06:27 2010 +0200 @@ -84,54 +84,19 @@ session_delete(sess); } -void jingle_send_session_accept(JingleNode *jn) +void jingle_send_session_accept(JingleSession *js) { - JingleSession *sess; - JingleContent *cn; LmMessage *mess; - GSList *child = NULL; - JingleAppFuncs *appfuncs; - JingleTransportFuncs *transfuncs; - gconstpointer description, transport; - const gchar *xmlns; - GError *err = NULL; JingleAckHandle *ackhandle; - - sess = session_new_from_jinglenode(jn); - - 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 (transfuncs == NULL) continue; - description = appfuncs->check(cn, &err); - if (description == NULL || err != NULL) continue; - transport = transfuncs->check(cn, &err); - if (transport == NULL || err != NULL) continue; - - scr_log_print(LPRINT_DEBUG, "jingle: New content accepted: %s", cn->name); - session_add_content_from_jinglecontent(sess, cn, JINGLE_SESSION_STATE_ACTIVE); - } - - if(g_slist_length(sess->content) == 0) { - jingle_send_session_terminate(sess, "unsupported-applications"); - session_delete(sess); - return; - } - - mess = lm_message_from_jinglesession(sess, JINGLE_SESSION_ACCEPT); + mess = lm_message_from_jinglesession(js, JINGLE_SESSION_ACCEPT); if (mess) { ackhandle = g_new0(JingleAckHandle, 1); ackhandle->callback = jingle_handle_ack_iq_sa; - ackhandle->user_data = (gpointer)sess; + ackhandle->user_data = (gpointer)js; lm_connection_send_with_reply(lconnection, mess, jingle_new_ack_handler(ackhandle), NULL); lm_message_unref(mess); diff -r f3408f4fe61a -r 0b9a7b505079 jingle/send.h --- a/jingle/send.h Sat Aug 14 12:00:59 2010 +0200 +++ b/jingle/send.h Sat Aug 14 19:06:27 2010 +0200 @@ -9,6 +9,6 @@ void jingle_send_session_terminate(JingleSession *js, const gchar *reason); void jingle_send_session_initiate(JingleSession *js); -void jingle_send_session_accept(JingleNode *jn); +void jingle_send_session_accept(JingleSession *js); #endif diff -r f3408f4fe61a -r 0b9a7b505079 jingle/sessions.c --- a/jingle/sessions.c Sat Aug 14 12:00:59 2010 +0200 +++ b/jingle/sessions.c Sat Aug 14 19:06:27 2010 +0200 @@ -90,7 +90,7 @@ { SessionContent *sc = g_new0(SessionContent, 1); - sc->name = name; + sc->name = g_strdup(name); sc->state = state; sess->content = g_slist_append(sess->content, sc); @@ -101,23 +101,24 @@ { SessionContent *sc = session_find_sessioncontent(sess, name); - sc->xmlns_desc = xmlns; + sc->xmlns_desc = g_strdup(xmlns); sc->appfuncs = jingle_get_appfuncs(xmlns); sc->description = data; } void session_add_trans(JingleSession *sess, const gchar *name, - const gchar *xmlns, gconstpointer data) + const gchar *xmlns, gconstpointer data) { SessionContent *sc = session_find_sessioncontent(sess, name); - sc->xmlns_trans = xmlns; + sc->xmlns_trans = g_strdup(xmlns); sc->transfuncs = jingle_get_transportfuncs(xmlns); sc->transport = data; } -void session_add_content_from_jinglecontent(JingleSession *sess, JingleContent *cn, - SessionState state) +void session_add_content_from_jinglecontent(JingleSession *sess, + JingleContent *cn, + SessionState state) { const gchar *xmlns; JingleAppFuncs *app_funcs; @@ -168,8 +169,10 @@ sc = session_find_sessioncontent(sess, name); if(sc == NULL) return; - if (sc->state == JINGLE_SESSION_STATE_ACTIVE); // We should stop the transfer - + if (sc->state == JINGLE_SESSION_STATE_ACTIVE) { + // TODO: stop the transfer + } + sess->content = g_slist_remove(sess->content, sc); return g_slist_length(sess->content); @@ -206,8 +209,19 @@ */ void session_free(JingleSession *sess) { + GSList *el; + SessionContent *sc; + g_free(sess->sid); g_free(sess->from); + g_free(sess->to); + + // Remove and free contents + for (el = sess->content; el; el = el->next) { + sc = (SessionContent*)el->data; + session_remove_sessioncontent(sess, sc->name); + } + g_free(sess); } diff -r f3408f4fe61a -r 0b9a7b505079 jingle/sessions.h --- a/jingle/sessions.h Sat Aug 14 12:00:59 2010 +0200 +++ b/jingle/sessions.h Sat Aug 14 19:06:27 2010 +0200 @@ -46,13 +46,13 @@ typedef struct { /* "A unique name or identifier for the content type * according to the creator" */ - const gchar *name; + gchar *name; /* */ SessionState state; /* The namespace of the app */ - const gchar *xmlns_desc; + gchar *xmlns_desc; /* The internal struct of the app module */ gconstpointer description; @@ -61,7 +61,7 @@ JingleAppFuncs *appfuncs; /* The namespace of the transport */ - const gchar *xmlns_trans; + gchar *xmlns_trans; /* The internal struct of the transport module */ gconstpointer transport;