summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Staudinger <robsta@linux.intel.com>2012-02-14 10:55:12 +0100
committerRob Staudinger <robsta@linux.intel.com>2012-02-14 10:55:12 +0100
commitdf8e6e7904be4f7ea632a956682eeb5471a5a95c (patch)
tree212a4ba0bfd4f7ce4273f1e2d17e22b92ff26a46
parent8ffc4a2d4eb38f5ce99ee765ca4d80a705059332 (diff)
file-transfer: Pass sender service-id in file metadata
The sender needs to add its own service-id to the metadata when transferring a file, so the recipient can look up who it is coming from. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=45733
-rw-r--r--examples/file-transfer.c20
-rw-r--r--ytstenut/yts-client.c57
-rw-r--r--ytstenut/yts-outgoing-file-internal.h1
-rw-r--r--ytstenut/yts-outgoing-file.c109
-rw-r--r--ytstenut/yts-outgoing-file.h1
5 files changed, 153 insertions, 35 deletions
diff --git a/examples/file-transfer.c b/examples/file-transfer.c
index da95e28..cccd021 100644
--- a/examples/file-transfer.c
+++ b/examples/file-transfer.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2012 Intel Corp.
+ * Copyright © 2011 Intel Corp.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -162,7 +162,7 @@ run_client (bool p2p,
roster = yts_client_get_roster (client);
g_signal_connect (roster, "service-added",
- G_CALLBACK (_client_roster_service_added), (void *) path);
+ G_CALLBACK (_client_roster_service_added), (gpointer) path);
yts_client_connect (client);
@@ -235,8 +235,8 @@ static int
run_server (bool p2p,
char const *path)
{
- YtsClient *client;
- GMainLoop *mainloop;
+ YtsClient *client;
+ GMainLoop *mainloop;
if (p2p)
client = yts_client_new_p2p (SERVER_UID);
@@ -250,8 +250,7 @@ run_server (bool p2p,
g_signal_connect (client, "disconnected",
G_CALLBACK (_server_disconnected), NULL);
g_signal_connect (client, "incoming-file",
- G_CALLBACK (_server_incoming_file), (void *) path);
-
+ G_CALLBACK (_server_incoming_file), (gpointer) path);
yts_client_connect (client);
@@ -284,7 +283,7 @@ main (int argc,
g_type_init ();
- context = g_option_context_new ("- Ytstenut file-transfer example");
+ context = g_option_context_new ("- Ytstenut echo example");
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_parse (context, &argc, &argv, &error);
if (error) {
@@ -292,11 +291,14 @@ main (int argc,
g_clear_error (&error);
}
- if (client) {
+ if (NULL == path) {
+ g_critical ("No file specified, see --help");
+ ret = -1;
+ } else if (client) {
g_message ("Running as client ...");
ret = run_client (p2p, path);
} else if (server) {
- g_message ("Running as server ... ");
+ g_message ("Running as server ...");
ret = run_server (p2p, path);
} else {
g_warning ("%s : Not running as server or client, quitting", G_STRLOC);
diff --git a/ytstenut/yts-client.c b/ytstenut/yts-client.c
index 79aa44b..2eb9101 100644
--- a/ytstenut/yts-client.c
+++ b/ytstenut/yts-client.c
@@ -790,6 +790,27 @@ yts_client_setup_debug (YtsClient *self)
g_free (busname);
}
+static char const *
+extract_remote_service_id (YtsClient *self,
+ GHashTable *channel_properties)
+{
+ GHashTable *metadata;
+ char const *remote_service_id = NULL;
+
+ metadata = tp_asv_get_boxed (channel_properties,
+ TP_PROP_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA_METADATA,
+ TP_HASH_TYPE_METADATA);
+
+ if (metadata) {
+ char **values = g_hash_table_lookup (metadata, (gpointer) "FromService");
+ if (values && values[0]) {
+ remote_service_id = values[0];
+ }
+ }
+
+ return remote_service_id;
+}
+
static void
_file_handler_handle_channels (TpSimpleHandler *handler,
TpAccount *account,
@@ -811,29 +832,36 @@ _file_handler_handle_channels (TpSimpleHandler *handler,
TpFileTransferChannel *channel = iter->data;
char const *remote_contact_id = tp_channel_get_initiator_identifier (TP_CHANNEL (channel));
GHashTable *props = tp_channel_borrow_immutable_properties (TP_CHANNEL (channel));
- char const *const key = "org.freedesktop.Telepathy.Channel.Interface.FileTransfer.Metadata.ServiceName";
- char const *remote_service_id = tp_asv_get_string (props, key);
+ char const *remote_service_id;
+ YtsService *service = NULL;
- YtsService *service = yts_roster_find_service_by_id (priv->roster,
- remote_contact_id,
- remote_service_id);
+ remote_service_id = extract_remote_service_id (self, props);
+ service = yts_roster_find_service_by_id (priv->roster,
+ remote_contact_id,
+ remote_service_id);
+ if (service) {
- YtsIncomingFile *incoming = yts_incoming_file_new (channel);
+ YtsIncomingFile *incoming = yts_incoming_file_new (channel);
+ GError *error = NULL;
- GError *error = NULL;
+ if (g_initable_init (G_INITABLE (incoming), NULL, &error)) {
- if (g_initable_init (G_INITABLE (incoming), NULL, &error)) {
+ g_signal_emit (self, signals[INCOMING_FILE], 0,
+ service, props, incoming);
- g_signal_emit (self, signals[INCOMING_FILE], 0,
- service, props, incoming);
+ } else {
- } else {
+ // TODO if (error) {}
+ g_critical ("Handling incoming file failed -- no handler");
+ }
+ g_clear_error (&error);
+ g_object_unref (incoming);
+
+ } else {
// TODO if (error) {}
- g_critical ("Handling incoming file failed");
+ g_critical ("Handling incoming file failed -- no recipient service");
}
-
- g_object_unref (incoming);
}
tp_handle_channels_context_accept (context);
@@ -1020,6 +1048,7 @@ _roster_send_file (YtsRoster *roster,
recipient_service_id = yts_service_get_id (service);
outgoing = yts_outgoing_file_new (priv->tp_account,
file,
+ priv->service_id,
recipient_contact_id,
recipient_service_id,
description);
diff --git a/ytstenut/yts-outgoing-file-internal.h b/ytstenut/yts-outgoing-file-internal.h
index f350f7c..3eec3e2 100644
--- a/ytstenut/yts-outgoing-file-internal.h
+++ b/ytstenut/yts-outgoing-file-internal.h
@@ -47,6 +47,7 @@ typedef struct {
YtsOutgoingFile *
yts_outgoing_file_new (TpAccount *tp_account,
GFile *file,
+ char const *sender_service_id,
char const *recipient_contact_id,
char const *recipient_service_id,
char const *description);
diff --git a/ytstenut/yts-outgoing-file.c b/ytstenut/yts-outgoing-file.c
index 034517d..3a1dfb2 100644
--- a/ytstenut/yts-outgoing-file.c
+++ b/ytstenut/yts-outgoing-file.c
@@ -67,7 +67,8 @@ enum {
PROP_TP_ACCOUNT,
PROP_DESCRIPTION,
PROP_RECIPIENT_CONTACT_ID,
- PROP_RECIPIENT_SERVICE_ID
+ PROP_RECIPIENT_SERVICE_ID,
+ PROP_SENDER_SERVICE_ID
};
typedef struct {
@@ -76,6 +77,7 @@ typedef struct {
GFile *file;
char *recipient_contact_id;
char *recipient_service_id;
+ char *sender_service_id;
char *description;
float progress;
/* Data */
@@ -172,6 +174,15 @@ validate (YtsOutgoingFile *self,
return false;
}
+ if (NULL == priv->sender_service_id) {
+ if (error_out) {
+ *error_out = g_error_new (YTS_OUTGOING_FILE_ERROR,
+ YTS_OUTGOING_FILE_ERROR_NO_SENDER_SERVICE,
+ "No sender service specified for file transfer");
+ }
+ return false;
+ }
+
return true;
}
@@ -343,6 +354,8 @@ _initable_init (GInitable *initable,
char const *name;
char const *mimetype;
GTimeVal mtime;
+ GHashTable *metadata;
+ char **values;
GHashTable *request;
TpAccountChannelRequest *channel_request;
GError *error = NULL;
@@ -373,20 +386,62 @@ _initable_init (GInitable *initable,
g_file_info_get_modification_time (info, &mtime);
priv->size = g_file_info_get_size (info);
+ metadata = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ values = g_new0 (char *, 2);
+ values[0] = priv->sender_service_id;
+ g_hash_table_insert (metadata,
+ g_strdup ("FromService"),
+ values);
+
/* Now we have everything prepared to continue, let's create the
* Ytstenut channel handler with service name specified. */
request = tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
- TP_PROP_CHANNEL_TARGET_ID, G_TYPE_STRING, priv->recipient_contact_id,
- TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_TYPE, G_TYPE_STRING, mimetype,
- TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_DATE, G_TYPE_INT64, (gint64) mtime.tv_sec,
- TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_DESCRIPTION, G_TYPE_STRING, priv->description,
- TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_FILENAME, G_TYPE_STRING, name,
- TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_INITIAL_OFFSET, G_TYPE_UINT64, (guint64) 0,
- TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_SIZE, G_TYPE_UINT64, (guint64) priv->size,
- /* here is the remote service */
- TP_PROP_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA_SERVICE_NAME, G_TYPE_STRING, priv->recipient_service_id,
+ TP_PROP_CHANNEL_CHANNEL_TYPE,
+ G_TYPE_STRING,
+ TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER,
+
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
+ G_TYPE_UINT,
+ TP_HANDLE_TYPE_CONTACT,
+
+ TP_PROP_CHANNEL_TARGET_ID,
+ G_TYPE_STRING,
+ priv->recipient_contact_id,
+
+ TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_TYPE,
+ G_TYPE_STRING,
+ mimetype,
+
+ TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_DATE,
+ G_TYPE_INT64,
+ (gint64) mtime.tv_sec,
+
+ TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_DESCRIPTION,
+ G_TYPE_STRING,
+ priv->description,
+
+ TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_FILENAME,
+ G_TYPE_STRING,
+ name,
+
+ TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_INITIAL_OFFSET,
+ G_TYPE_UINT64,
+ (guint64) 0,
+
+ TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_SIZE,
+ G_TYPE_UINT64,
+ (guint64) priv->size,
+
+ /* Here is the remote service */
+ TP_PROP_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA_SERVICE_NAME,
+ G_TYPE_STRING,
+ priv->recipient_service_id,
+
+ /* And include our own service name. FIXME this should be a define. */
+ TP_PROP_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA_METADATA,
+ TP_HASH_TYPE_METADATA,
+ metadata,
+
NULL);
channel_request = tp_account_channel_request_new (
@@ -436,6 +491,9 @@ _get_property (GObject *object,
case PROP_RECIPIENT_SERVICE_ID:
g_value_set_string (value, priv->recipient_service_id);
break;
+ case PROP_SENDER_SERVICE_ID:
+ g_value_set_string (value, priv->sender_service_id);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -476,6 +534,10 @@ _set_property (GObject *object,
/* Construct-only */
priv->recipient_service_id = g_value_dup_string (value);
break;
+ case PROP_SENDER_SERVICE_ID:
+ /* Construct-only */
+ priv->sender_service_id = g_value_dup_string (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -521,6 +583,11 @@ _finalize (GObject *object)
priv->recipient_service_id = NULL;
}
+ if (priv->sender_service_id) {
+ g_free (priv->sender_service_id);
+ priv->sender_service_id = NULL;
+ }
+
if (priv->description) {
g_free (priv->description);
priv->description = NULL;
@@ -610,6 +677,22 @@ yts_outgoing_file_class_init (YtsOutgoingFileClass *klass)
g_object_class_install_property (object_class,
PROP_RECIPIENT_SERVICE_ID,
pspec);
+
+ /**
+ * YtsOutgoingFile:sender-service-id:
+ *
+ * Service ID of the file sender.
+ *
+ * Since: 0.4
+ */
+ pspec = g_param_spec_string ("sender-service-id", "", "",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class,
+ PROP_SENDER_SERVICE_ID,
+ pspec);
}
static void
@@ -620,6 +703,7 @@ yts_outgoing_file_init (YtsOutgoingFile *self)
YtsOutgoingFile *
yts_outgoing_file_new (TpAccount *tp_account,
GFile *file,
+ char const *sender_service_id,
char const *recipient_contact_id,
char const *recipient_service_id,
char const *description)
@@ -627,6 +711,7 @@ yts_outgoing_file_new (TpAccount *tp_account,
return g_object_new (YTS_TYPE_OUTGOING_FILE,
"tp-account", tp_account,
"file", file,
+ "sender-service-id", sender_service_id,
"recipient-contact-id", recipient_contact_id,
"recipient-service-id", recipient_service_id,
"description", description,
diff --git a/ytstenut/yts-outgoing-file.h b/ytstenut/yts-outgoing-file.h
index a81390d..7bc22d3 100644
--- a/ytstenut/yts-outgoing-file.h
+++ b/ytstenut/yts-outgoing-file.h
@@ -47,6 +47,7 @@ enum {
YTS_OUTGOING_FILE_ERROR_READ_FAILED,
YTS_OUTGOING_FILE_ERROR_NO_RECIPIENT_CONTACT,
YTS_OUTGOING_FILE_ERROR_NO_RECIPIENT_SERVICE,
+ YTS_OUTGOING_FILE_ERROR_NO_SENDER_SERVICE,
YTS_OUTGOING_FILE_ERROR_CHANNEL_FAILED,
YTS_OUTGOING_FILE_ERROR_TRANSFER_FAILED,
YTS_OUTGOING_FILE_ERROR_LOCAL,