summaryrefslogtreecommitdiff
path: root/lib/gibber
diff options
context:
space:
mode:
authorJonny Lamb <jonny.lamb@collabora.co.uk>2011-03-02 13:47:28 +0000
committerJonny Lamb <jonny.lamb@collabora.co.uk>2011-03-02 15:19:26 +0000
commit900449dfacf9518f3fcc52972f8ef0a4850f75af (patch)
treef239237f6cced7b8b0bca2af3c96b5668c8c4ae3 /lib/gibber
parent5b1e6d98e994e33d234db050fba28c533d41ac65 (diff)
downloadtelepathy-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.c108
-rw-r--r--lib/gibber/gibber-file-transfer.h5
-rw-r--r--lib/gibber/gibber-oob-file-transfer.c206
-rw-r--r--lib/gibber/gibber-oob-file-transfer.h3
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