diff options
author | Will Thompson <will.thompson@collabora.co.uk> | 2011-10-11 17:01:13 +0100 |
---|---|---|
committer | Will Thompson <will.thompson@collabora.co.uk> | 2011-11-04 16:24:46 +0000 |
commit | deb5a15cb02344891f5871cd5f8dcf8faa464d4a (patch) | |
tree | d0bb44e72f9e61e649dde0adaa182616454f3993 | |
parent | 214c0b08245fc264985e4504309abb7b7e82f68c (diff) |
ImFactory: refactor creating unrequested channels
We'll need similar logic for handling incoming facebook:own-message
notifications.
-rw-r--r-- | src/im-factory.c | 106 |
1 files changed, 63 insertions, 43 deletions
diff --git a/src/im-factory.c b/src/im-factory.c index 6c61b91af..cd82810e4 100644 --- a/src/im-factory.c +++ b/src/im-factory.c @@ -185,8 +185,10 @@ gabble_im_factory_class_init (GabbleImFactoryClass *gabble_im_factory_class) } -static GabbleIMChannel *new_im_channel (GabbleImFactory *fac, - TpHandle handle, gpointer request_token); +static GabbleIMChannel *get_channel_for_incoming_message ( + GabbleImFactory *self, + const gchar *jid, + gboolean create_if_missing); /** * im_factory_message_cb: @@ -200,18 +202,14 @@ im_factory_message_cb (LmMessageHandler *handler, gpointer user_data) { GabbleImFactory *fac = GABBLE_IM_FACTORY (user_data); - GabbleImFactoryPrivate *priv = fac->priv; - TpBaseConnection *conn = (TpBaseConnection *) priv->conn; - TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (conn, - TP_HANDLE_TYPE_CONTACT); const gchar *from, *body, *id; time_t stamp; TpChannelTextMessageType msgtype; - TpHandle handle; GabbleIMChannel *chan; gint state; TpChannelTextSendError send_error; TpDeliveryStatus delivery_status; + gboolean create_if_missing; if (!gabble_message_util_parse_incoming_message (message, &from, &stamp, &msgtype, &id, &body, &state, &send_error, &delivery_status)) @@ -222,54 +220,34 @@ im_factory_message_cb (LmMessageHandler *handler, return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; } - handle = tp_handle_ensure (contact_repo, from, NULL, NULL); - if (handle == 0) - { - STANZA_DEBUG (message, "ignoring message node from malformed jid"); - return LM_HANDLER_RESULT_REMOVE_MESSAGE; - } - - chan = g_hash_table_lookup (priv->channels, GUINT_TO_POINTER (handle)); - + /* We don't want to open up a channel for the sole purpose of reporting a + * send error, nor if this is just a chat state notification. + */ + create_if_missing = + (send_error == GABBLE_TEXT_CHANNEL_SEND_NO_ERROR) && + (body != NULL); + chan = get_channel_for_incoming_message (fac, from, create_if_missing); if (chan == NULL) { - if (send_error != GABBLE_TEXT_CHANNEL_SEND_NO_ERROR) - { - DEBUG ("ignoring message error; no sending channel"); - tp_handle_unref (contact_repo, handle); - return LM_HANDLER_RESULT_REMOVE_MESSAGE; - } - - if (body == NULL) - { - /* don't create a new channel if all we have is a chat state */ - DEBUG ("ignoring message without body; no existing channel"); - tp_handle_unref (contact_repo, handle); - return LM_HANDLER_RESULT_REMOVE_MESSAGE; - } - - DEBUG ("found no IM channel, creating one"); + if (create_if_missing) + STANZA_DEBUG (message, "ignoring message from non-contact JID"); + else + DEBUG ("ignoring message error or chat state notification from '%s': " + "no existing channel", from); - chan = new_im_channel (fac, handle, NULL); + return LM_HANDLER_RESULT_REMOVE_MESSAGE; } - g_assert (chan != NULL); - - /* now the channel is referencing the handle, so if we unref it, that's - * not a problem */ - tp_handle_unref (contact_repo, handle); - if (send_error != GABBLE_TEXT_CHANNEL_SEND_NO_ERROR) { if (body == NULL) { - DEBUG ("ignoring error sending chat state to %s (handle %u)", from, - handle); + DEBUG ("ignoring error sending chat state to %s", from); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } - DEBUG ("got error sending to %s (handle %u), msgtype %u, body:\n%s", - from, handle, msgtype, body); + DEBUG ("got error sending to %s, msgtype %u, body:\n%s", + from, msgtype, body); } if (body != NULL) @@ -382,6 +360,48 @@ new_im_channel (GabbleImFactory *fac, return chan; } +/* + * get_channel_for_incoming_message: + * @self: a factory + * @jid: a contact's JID + * @create_if_missing: if %TRUE, a new channel will be created if there is no + * existing channel to @jid + * + * Retrieves a 1-1 text channel to a particular contact. If no channel is open + * to @jid, it will be created only if @create_if_missing is %TRUE. If @jid is + * not of the form 'user@domain' (optionally with a resource), no channel will + * be opened. + * + * Returns: an IM channel to @jid, or %NULL + */ +static GabbleIMChannel * +get_channel_for_incoming_message ( + GabbleImFactory *self, + const gchar *jid, + gboolean create_if_missing) +{ + GabbleImFactoryPrivate *priv = self->priv; + TpBaseConnection *conn = (TpBaseConnection *) priv->conn; + TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (conn, + TP_HANDLE_TYPE_CONTACT); + TpHandle handle; + GabbleIMChannel *chan; + + g_return_val_if_fail (jid != NULL, NULL); + + handle = tp_handle_ensure (contact_repo, jid, NULL, NULL); + if (handle == 0) + return NULL; + + chan = g_hash_table_lookup (priv->channels, GUINT_TO_POINTER (handle)); + if (chan != NULL) + return chan; + else if (create_if_missing) + return new_im_channel (self, handle, NULL); + else + return NULL; +} + static void gabble_im_factory_close_all (GabbleImFactory *self) { |