diff options
author | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2011-03-02 13:47:28 +0000 |
---|---|---|
committer | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2011-03-02 15:19:26 +0000 |
commit | 900449dfacf9518f3fcc52972f8ef0a4850f75af (patch) | |
tree | f239237f6cced7b8b0bca2af3c96b5668c8c4ae3 /lib/gibber | |
parent | 5b1e6d98e994e33d234db050fba28c533d41ac65 (diff) | |
download | telepathy-salut-900449dfacf9518f3fcc52972f8ef0a4850f75af.tar.gz |
file transfers: stop using the XCM
Signed-off-by: Jonny Lamb <jonny.lamb@collabora.co.uk>
Diffstat (limited to 'lib/gibber')
-rw-r--r-- | lib/gibber/gibber-file-transfer.c | 108 | ||||
-rw-r--r-- | lib/gibber/gibber-file-transfer.h | 5 | ||||
-rw-r--r-- | lib/gibber/gibber-oob-file-transfer.c | 206 | ||||
-rw-r--r-- | lib/gibber/gibber-oob-file-transfer.h | 3 |
4 files changed, 217 insertions, 105 deletions
diff --git a/lib/gibber/gibber-file-transfer.c b/lib/gibber/gibber-file-transfer.c index 7f8d2843..a5ae5c20 100644 --- a/lib/gibber/gibber-file-transfer.c +++ b/lib/gibber/gibber-file-transfer.c @@ -55,7 +55,8 @@ enum PROP_PEER_ID, PROP_FILENAME, PROP_DIRECTION, - PROP_CONNECTION, + PROP_PORTER, + PROP_CONTACT, PROP_DESCRIPTION, PROP_CONTENT_TYPE, LAST_PROPERTY @@ -64,7 +65,10 @@ enum /* private structure */ struct _GibberFileTransferPrivate { - GibberXmppConnection *connection; + WockyPorter *porter; + WockyContact *contact; + + guint stanza_id; guint64 size; }; @@ -114,8 +118,11 @@ gibber_file_transfer_get_property (GObject *object, case PROP_DIRECTION: g_value_set_enum (value, self->direction); break; - case PROP_CONNECTION: - g_value_set_object (value, self->priv->connection); + case PROP_PORTER: + g_value_set_object (value, self->priv->porter); + break; + case PROP_CONTACT: + g_value_set_object (value, self->priv->contact); break; case PROP_DESCRIPTION: g_value_set_string (value, self->description); @@ -137,7 +144,7 @@ generate_id (void) return g_strdup_printf ("gibber-file-transfer-%d", id_num++); } -static void received_stanza_cb (GibberXmppConnection *conn, +static gboolean received_stanza_cb (WockyPorter *porter, WockyStanza *stanza, gpointer user_data); static void @@ -171,11 +178,22 @@ gibber_file_transfer_set_property (GObject *object, case PROP_DIRECTION: self->direction = g_value_get_enum (value); break; - case PROP_CONNECTION: - self->priv->connection = g_value_dup_object (value); - if (self->priv->connection != NULL) - g_signal_connect (self->priv->connection, "received-stanza", - G_CALLBACK (received_stanza_cb), self); + case PROP_PORTER: + { + self->priv->porter = g_value_dup_object (value); + + if (self->priv->porter != NULL) + { + self->priv->stanza_id = + wocky_porter_register_handler_from_anyone (self->priv->porter, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, + WOCKY_PORTER_HANDLER_PRIORITY_NORMAL, received_stanza_cb, + self, NULL); + } + } + break; + case PROP_CONTACT: + self->priv->contact = g_value_dup_object (value); break; case PROP_DESCRIPTION: self->description = g_value_dup_string (value); @@ -241,12 +259,19 @@ gibber_file_transfer_class_init (GibberFileTransferClass *gibber_file_transfer_c G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); g_object_class_install_property (object_class, PROP_DIRECTION, param_spec); - param_spec = g_param_spec_object ("connection", - "GibberXmppConnection object", "Gibber Connection used to send stanzas", - GIBBER_TYPE_XMPP_CONNECTION, + param_spec = g_param_spec_object ("porter", + "WockyPorter object", "Wocky porter used to send stanzas", + WOCKY_TYPE_PORTER, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | + G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); + g_object_class_install_property (object_class, PROP_PORTER, param_spec); + + param_spec = g_param_spec_object ("contact", + "WockyContact object", "Wocky Contact", + WOCKY_TYPE_CONTACT, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); - g_object_class_install_property (object_class, PROP_CONNECTION, param_spec); + g_object_class_install_property (object_class, PROP_CONTACT, param_spec); param_spec = g_param_spec_string ("description", "Description", @@ -303,12 +328,18 @@ gibber_file_transfer_dispose (GObject *object) { GibberFileTransfer *self = GIBBER_FILE_TRANSFER (object); - if (self->priv->connection != NULL) + if (self->priv->porter != NULL) + { + wocky_porter_unregister_handler (self->priv->porter, + self->priv->stanza_id); + g_object_unref (self->priv->porter); + self->priv->porter = NULL; + } + + if (self->priv->contact != NULL) { - g_signal_handlers_disconnect_matched (self->priv->connection, - G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self); - g_object_unref (self->priv->connection); - self->priv->connection = NULL; + g_object_unref (self->priv->contact); + self->priv->contact = NULL; } G_OBJECT_CLASS (gibber_file_transfer_parent_class)->dispose (object); @@ -329,8 +360,8 @@ gibber_file_transfer_finalize (GObject *object) G_OBJECT_CLASS (gibber_file_transfer_parent_class)->finalize (object); } -static void -received_stanza_cb (GibberXmppConnection *conn, +static gboolean +received_stanza_cb (WockyPorter *porter, WockyStanza *stanza, gpointer user_data) { @@ -340,7 +371,12 @@ received_stanza_cb (GibberXmppConnection *conn, id = wocky_node_get_attribute (wocky_stanza_get_top_node (stanza), "id"); if (id != NULL && strcmp (id, self->id) == 0) - GIBBER_FILE_TRANSFER_GET_CLASS (self)->received_stanza (self, stanza); + { + GIBBER_FILE_TRANSFER_GET_CLASS (self)->received_stanza (self, stanza); + return TRUE; + } + + return FALSE; } gboolean @@ -354,7 +390,8 @@ gibber_file_transfer_is_file_offer (WockyStanza *stanza) GibberFileTransfer * gibber_file_transfer_new_from_stanza_with_from ( WockyStanza *stanza, - GibberXmppConnection *connection, + WockyPorter *porter, + WockyContact *contact, const gchar *from, GError **error) { @@ -362,8 +399,8 @@ gibber_file_transfer_new_from_stanza_with_from ( * can handle the stanza */ GibberFileTransfer *ft; - ft = gibber_oob_file_transfer_new_from_stanza_with_from (stanza, connection, - from, error); + ft = gibber_oob_file_transfer_new_from_stanza_with_from (stanza, porter, + contact, from, error); /* it's not possible to have an outgoing transfer created from * a stanza */ g_assert (ft == NULL || @@ -374,15 +411,16 @@ gibber_file_transfer_new_from_stanza_with_from ( GibberFileTransfer * gibber_file_transfer_new_from_stanza (WockyStanza *stanza, - GibberXmppConnection *connection, + WockyPorter *porter, + WockyContact *contact, GError **error) { const gchar *from; from = wocky_node_get_attribute (wocky_stanza_get_top_node (stanza), "from"); - return gibber_file_transfer_new_from_stanza_with_from (stanza, connection, - from, error); + return gibber_file_transfer_new_from_stanza_with_from (stanza, porter, + contact, from, error); } void @@ -458,14 +496,10 @@ gibber_file_transfer_send_stanza (GibberFileTransfer *self, WockyStanza *stanza, GError **error) { - if (self->priv->connection->transport == NULL || - self->priv->connection->transport->state != GIBBER_TRANSPORT_CONNECTED) - { - g_set_error (error, GIBBER_FILE_TRANSFER_ERROR, - GIBBER_FILE_TRANSFER_ERROR_NOT_CONNECTED, - "XMPP connection not connected"); - return FALSE; - } + if (wocky_stanza_get_contact (stanza) == NULL) + wocky_stanza_set_contact (stanza, self->priv->contact); + + wocky_porter_send (self->priv->porter, stanza); - return gibber_xmpp_connection_send (self->priv->connection, stanza, error); + return TRUE; } diff --git a/lib/gibber/gibber-file-transfer.h b/lib/gibber/gibber-file-transfer.h index a1e8bfe3..411a2486 100644 --- a/lib/gibber/gibber-file-transfer.h +++ b/lib/gibber/gibber-file-transfer.h @@ -23,6 +23,7 @@ #include <glib.h> #include <glib-object.h> #include <wocky/wocky-stanza.h> +#include <wocky/wocky-porter.h> #include "gibber-xmpp-connection.h" G_BEGIN_DECLS @@ -106,10 +107,10 @@ GType gibber_file_transfer_get_type (void); gboolean gibber_file_transfer_is_file_offer (WockyStanza *stanza); GibberFileTransfer *gibber_file_transfer_new_from_stanza ( - WockyStanza *stanza, GibberXmppConnection *connection, + WockyStanza *stanza, WockyPorter *porter, WockyContact *contact, GError **error); GibberFileTransfer *gibber_file_transfer_new_from_stanza_with_from ( - WockyStanza *stanza, GibberXmppConnection *connection, + WockyStanza *stanza, WockyPorter *porter, WockyContact *contact, const gchar *from, GError **error); void gibber_file_transfer_offer (GibberFileTransfer *self); diff --git a/lib/gibber/gibber-oob-file-transfer.c b/lib/gibber/gibber-oob-file-transfer.c index b811f8b9..323b6456 100644 --- a/lib/gibber/gibber-oob-file-transfer.c +++ b/lib/gibber/gibber-oob-file-transfer.c @@ -27,6 +27,7 @@ #include <libsoup/soup-message.h> #include <wocky/wocky-stanza.h> +#include <wocky/wocky-meta-porter.h> #include "gibber-oob-file-transfer.h" #include "gibber-fd-transport.h" #include "gibber-namespaces.h" @@ -177,7 +178,8 @@ gibber_oob_file_transfer_is_file_offer (WockyStanza *stanza) GibberFileTransfer * gibber_oob_file_transfer_new_from_stanza_with_from ( WockyStanza *stanza, - GibberXmppConnection *connection, + WockyPorter *porter, + WockyContact *contact, const gchar *peer_id, GError **error) { @@ -303,7 +305,8 @@ gibber_oob_file_transfer_new_from_stanza_with_from ( "self-id", self_id, "peer-id", peer_id, "filename", filename, - "connection", connection, + "porter", porter, + "contact", contact, "direction", GIBBER_FILE_TRANSFER_DIRECTION_INCOMING, "description", description, "content-type", content_type, @@ -470,12 +473,15 @@ static WockyStanza * create_transfer_offer (GibberOobFileTransfer *self, GError **error) { - GibberXmppConnection *connection; + WockyMetaPorter *porter; + WockyContact *contact; + GSocketConnection *conn; + GSocketAddress *address; + GInetAddress *addr; + GSocketFamily family; /* local host name */ - gchar host_name[NI_MAXHOST]; - struct sockaddr_storage name_addr; - socklen_t name_addr_len = sizeof (name_addr); + gchar *host_name; gchar *host_escaped; WockyStanza *stanza; @@ -490,21 +496,32 @@ create_transfer_offer (GibberOobFileTransfer *self, guint64 size; - g_object_get (GIBBER_FILE_TRANSFER (self), "connection", &connection, NULL); - if (connection->transport == NULL) + g_object_get (GIBBER_FILE_TRANSFER (self), + "porter", &porter, + "contact", &contact, + NULL); + + conn = wocky_meta_porter_borrow_connection (porter, contact); + + g_object_unref (porter); + g_object_unref (contact); + + if (conn == NULL) { g_set_error (error, GIBBER_FILE_TRANSFER_ERROR, GIBBER_FILE_TRANSFER_ERROR_NOT_CONNECTED, "Null transport"); return NULL; } - gibber_transport_get_sockaddr (connection->transport, &name_addr, - &name_addr_len); - g_object_unref (connection); - getnameinfo ((struct sockaddr *) &name_addr, name_addr_len, host_name, - sizeof (host_name), NULL, 0, NI_NUMERICHOST); + address = g_socket_connection_get_local_address (conn, NULL); + addr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address)); + family = g_socket_address_get_family (address); + + host_name = g_inet_address_to_string (addr); - if (name_addr.ss_family == AF_INET6) + g_object_unref (address); + + if (family == SOUP_ADDRESS_FAMILY_IPV6) { /* put brackets around the IP6 */ host_escaped = g_strdup_printf ("[%s]", host_name); @@ -515,6 +532,8 @@ create_transfer_offer (GibberOobFileTransfer *self, host_escaped = g_strdup (host_name); } + g_free (host_name); + filename_escaped = g_uri_escape_string (GIBBER_FILE_TRANSFER (self)->filename, NULL, FALSE); url = g_strdup_printf ("http://%s:%d/%s/%s", host_escaped, @@ -718,58 +737,10 @@ http_server_cb (SoupServer *server, } static void -gibber_oob_file_transfer_offer (GibberFileTransfer *ft) +create_and_send_transfer_offer (GibberOobFileTransfer *self) { - GibberOobFileTransfer *self = GIBBER_OOB_FILE_TRANSFER (ft); - WockyStanza *stanza; GError *error = NULL; - - /* start the server if not running */ - /* FIXME we should have only a single server */ - if (self->priv->server == NULL) - { - /* FIXME: libsoup can't listen on IPv4 and IPv6 interfaces at the same - * time. http://bugzilla.gnome.org/show_bug.cgi?id=522519 - * We have to check which IP will be send when creating the stanza. */ - GibberXmppConnection *connection; - struct sockaddr_storage name_addr; - socklen_t name_addr_len = sizeof (name_addr); - - g_object_get (GIBBER_FILE_TRANSFER (self), "connection", &connection, - NULL); - if (connection->transport == NULL) - { - g_set_error (&error, GIBBER_FILE_TRANSFER_ERROR, - GIBBER_FILE_TRANSFER_ERROR_NOT_CONNECTED, "Null transport"); - gibber_file_transfer_emit_error (GIBBER_FILE_TRANSFER (self), - error); - g_error_free (error); - return; - } - - gibber_transport_get_peeraddr (connection->transport, &name_addr, - &name_addr_len); - g_object_unref (connection); - - if (name_addr.ss_family == AF_INET6) - { - /* IPv6 server */ - SoupAddress *addr; - - addr = soup_address_new_any (SOUP_ADDRESS_FAMILY_IPV6, 0); - self->priv->server = soup_server_new (SOUP_SERVER_INTERFACE, - addr, NULL); - - g_object_unref (addr); - } - else - { - /* IPv4 server */ - self->priv->server = soup_server_new (NULL, NULL); - } - - soup_server_run_async (self->priv->server); - } + WockyStanza *stanza; stanza = create_transfer_offer (self, &error); if (stanza == NULL) @@ -791,6 +762,113 @@ gibber_oob_file_transfer_offer (GibberFileTransfer *ft) } static void +porter_open_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + WockyMetaPorter *porter = WOCKY_META_PORTER (source_object); + GibberOobFileTransfer *self = GIBBER_OOB_FILE_TRANSFER (user_data); + GError *error = NULL; + + WockyContact *contact; + + GSocketConnection *conn; + GSocketAddress *address; + GSocketFamily family; + + if (!wocky_meta_porter_open_finish (porter, result, &error)) + { + DEBUG ("Failed to open connection: %s", error->message); + g_clear_error (&error); + + g_set_error (&error, GIBBER_FILE_TRANSFER_ERROR, + GIBBER_FILE_TRANSFER_ERROR_NOT_CONNECTED, "Couldn't open connection"); + gibber_file_transfer_emit_error (GIBBER_FILE_TRANSFER (self), + error); + g_error_free (error); + return; + } + + g_object_get (GIBBER_FILE_TRANSFER (self), + "contact", &contact, + NULL); + + /* FIXME we should have only a single server */ + + /* FIXME: libsoup can't listen on IPv4 and IPv6 interfaces at the same + * time. http://bugzilla.gnome.org/show_bug.cgi?id=522519 + * We have to check which IP will be send when creating the stanza. */ + + conn = wocky_meta_porter_borrow_connection (porter, contact); + + if (conn == NULL) + { + g_set_error (&error, GIBBER_FILE_TRANSFER_ERROR, + GIBBER_FILE_TRANSFER_ERROR_NOT_CONNECTED, "Null transport"); + gibber_file_transfer_emit_error (GIBBER_FILE_TRANSFER (self), + error); + g_error_free (error); + goto out; + } + + address = g_socket_connection_get_remote_address (conn, NULL); + family = g_socket_address_get_family (address); + g_object_unref (address); + + if (family == G_SOCKET_FAMILY_IPV6) + { + /* IPv6 server */ + SoupAddress *addr; + + addr = soup_address_new_any (SOUP_ADDRESS_FAMILY_IPV6, 0); + self->priv->server = soup_server_new (SOUP_SERVER_INTERFACE, + addr, NULL); + + g_object_unref (addr); + } + else + { + /* IPv4 server */ + self->priv->server = soup_server_new (NULL, NULL); + } + + soup_server_run_async (self->priv->server); + + create_and_send_transfer_offer (self); + +out: + /* this was reffed when calling open_async */ + wocky_meta_porter_unref (porter, contact); + g_object_unref (contact); +} + +static void +gibber_oob_file_transfer_offer (GibberFileTransfer *ft) +{ + GibberOobFileTransfer *self = GIBBER_OOB_FILE_TRANSFER (ft); + WockyMetaPorter *porter; + WockyContact *contact; + + if (self->priv->server != NULL) + { + create_and_send_transfer_offer (self); + return; + } + + /* we need to create the soup server */ + + g_object_get (ft, + "porter", &porter, + "contact", &contact, + NULL); + + wocky_meta_porter_open_async (porter, contact, NULL, porter_open_cb, ft); + + g_object_unref (contact); + g_object_unref (porter); +} + +static void http_server_wrote_chunk_cb (SoupMessage *msg, gpointer user_data) { diff --git a/lib/gibber/gibber-oob-file-transfer.h b/lib/gibber/gibber-oob-file-transfer.h index 85f1decc..ea29b9bf 100644 --- a/lib/gibber/gibber-oob-file-transfer.h +++ b/lib/gibber/gibber-oob-file-transfer.h @@ -22,7 +22,6 @@ #include <glib.h> #include <glib-object.h> -#include "gibber-xmpp-connection.h" #include "gibber-file-transfer.h" G_BEGIN_DECLS @@ -63,7 +62,7 @@ GType gibber_oob_file_transfer_get_type (void); gboolean gibber_oob_file_transfer_is_file_offer (WockyStanza *stanza); GibberFileTransfer *gibber_oob_file_transfer_new_from_stanza_with_from ( - WockyStanza *stanza, GibberXmppConnection *connection, + WockyStanza *stanza, WockyPorter *porter, WockyContact *contact, const gchar *from, GError **error); G_END_DECLS |