[Telepathy-commits] [telepathy-salut/master] SalutTubeStream implements the new tube API with the requestotron. Tube test updated.
Alban Crequy
alban.crequy at collabora.co.uk
Fri Feb 6 03:14:55 PST 2009
---
src/salut-connection.c | 2 -
src/salut-tubes-channel.c | 84 +++++--
src/salut-tubes-channel.h | 3 +
src/salut-tubes-manager.c | 6 +
src/tube-iface.c | 4 +-
src/tube-stream.c | 494 +++++++++++++++++++++++++++++++++++++-
src/tube-stream.h | 10 +-
tests/twisted/avahi/test-tube.py | 224 ++++++++++++++++-
8 files changed, 780 insertions(+), 47 deletions(-)
diff --git a/src/salut-connection.c b/src/salut-connection.c
index ffaaf2e..fbd81f0 100644
--- a/src/salut-connection.c
+++ b/src/salut-connection.c
@@ -2838,8 +2838,6 @@ salut_connection_create_channel_factories (TpBaseConnection *base)
G_CALLBACK (_olpc_activity_manager_activity_modified_cb), self);
#endif
- g_ptr_array_add (factories, priv->contact_manager);
-
return factories;
}
diff --git a/src/salut-tubes-channel.c b/src/salut-tubes-channel.c
index adefa16..0b89499 100644
--- a/src/salut-tubes-channel.c
+++ b/src/salut-tubes-channel.c
@@ -79,7 +79,6 @@ G_DEFINE_TYPE_WITH_CODE (SalutTubesChannel, salut_tubes_channel, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_TUBES, tubes_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP,
tp_external_group_mixin_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_EXPORTABLE_CHANNEL, NULL);
G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL);
);
@@ -176,7 +175,8 @@ static gboolean extract_tube_information (SalutTubesChannel *self,
GibberXmppNode *tube_node, TpTubeType *type, TpHandle *initiator_handle,
const gchar **service, GHashTable **parameters, guint *tube_id);
static SalutTubeIface * create_new_tube (SalutTubesChannel *self,
- TpTubeType type, TpHandle initiator, const gchar *service,
+ TpTubeType type, TpHandle initiator, SalutTubeChannelState initial_state,
+ const gchar *service,
GHashTable *parameters, guint tube_id, guint portnum,
GibberXmppStanza *iq_req);
@@ -857,7 +857,8 @@ salut_tubes_channel_muc_message_received (SalutTubesChannel *self,
}
tube = create_new_tube (self, type, initiator_handle,
- service, parameters, id, 0, NULL);
+ SALUT_TUBE_CHANNEL_STATE_LOCAL_PENDING, service, parameters,
+ tube_id, 0, NULL);
/* the tube has reffed its initiator, no need to keep a ref */
tp_handle_unref (contact_repo, initiator_handle);
@@ -947,7 +948,8 @@ salut_tubes_channel_message_received (SalutTubesChannel *self,
tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id));
if (tube == NULL)
{
- tube = create_new_tube (self, tube_type, initiator_handle, service,
+ tube = create_new_tube (self, tube_type, initiator_handle,
+ SALUT_TUBE_CHANNEL_STATE_LOCAL_PENDING, service,
parameters, tube_id, portnum, iq_req);
}
}
@@ -1033,7 +1035,8 @@ salut_tubes_channel_tube_request (SalutTubesChannel *self,
DEBUG ("Request a tube channel with type='%s' and service='%s'",
channel_type, service);
- tube = create_new_tube (self, type, priv->self_handle, service,
+ tube = create_new_tube (self, type, priv->self_handle,
+ SALUT_TUBE_CHANNEL_STATE_NOT_OFFERED, service,
parameters, tube_id, 0, NULL);
return tube;
@@ -1102,7 +1105,7 @@ copy_tube_in_ptr_array (gpointer key,
TpHandle initiator;
gchar *service;
GHashTable *parameters;
- TpTubeState state;
+ SalutTubeChannelState state;
TpTubeType type;
GPtrArray *array = (GPtrArray *) user_data;
GValue entry = {0,};
@@ -1217,6 +1220,7 @@ static SalutTubeIface *
create_new_tube (SalutTubesChannel *self,
TpTubeType type,
TpHandle initiator,
+ SalutTubeChannelState initial_state,
const gchar *service,
GHashTable *parameters,
guint tube_id,
@@ -1225,7 +1229,7 @@ create_new_tube (SalutTubesChannel *self,
{
SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
SalutTubeIface *tube;
- TpTubeState state;
+ SalutTubeChannelState state;
GibberMucConnection *muc_connection = NULL;
if (self->muc != NULL)
@@ -1241,8 +1245,8 @@ create_new_tube (SalutTubesChannel *self,
case TP_TUBE_TYPE_STREAM:
tube = SALUT_TUBE_IFACE (salut_tube_stream_new (priv->conn, self,
priv->xmpp_connection_manager, priv->handle, priv->handle_type,
- priv->self_handle, initiator, service, parameters, tube_id,
- portnum, iq_req));
+ priv->self_handle, initiator, initial_state, service, parameters,
+ tube_id, portnum, iq_req));
break;
default:
g_assert_not_reached ();
@@ -1460,7 +1464,7 @@ publish_tubes_in_node (gpointer key,
(struct _i_hate_g_hash_table_foreach *) user_data;
SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (
data->self);
- TpTubeState state;
+ SalutTubeChannelState state;
GibberXmppNode *tube_node;
TpTubeType type;
TpHandle initiator;
@@ -1550,6 +1554,8 @@ salut_tubes_channel_offer_d_bus_tube (TpSvcChannelTypeTubes *iface,
TpBaseConnection *base;
guint tube_id;
SalutTubeIface *tube;
+ GHashTable *parameters_copied;
+ SalutTubeChannelState initial_state;
g_assert (SALUT_IS_TUBES_CHANNEL (self));
@@ -1569,8 +1575,14 @@ salut_tubes_channel_offer_d_bus_tube (TpSvcChannelTypeTubes *iface,
tube_id = generate_tube_id ();
+ if (priv->handle_type == TP_HANDLE_TYPE_ROOM)
+ initial_state = SALUT_TUBE_CHANNEL_STATE_OPEN;
+ else
+ initial_state = SALUT_TUBE_CHANNEL_STATE_REMOTE_PENDING;
+
tube = create_new_tube (self, TP_TUBE_TYPE_DBUS, priv->self_handle,
- service, parameters, tube_id, 0, NULL);
+ initial_state, service, parameters_copied,
+ tube_id, 0, NULL);
tp_svc_channel_type_tubes_return_from_offer_d_bus_tube (context, tube_id);
}
@@ -1589,7 +1601,7 @@ salut_tubes_channel_accept_d_bus_tube (TpSvcChannelTypeTubes *iface,
SalutTubesChannel *self = SALUT_TUBES_CHANNEL (iface);
SalutTubesChannelPrivate *priv;
SalutTubeIface *tube;
- TpTubeState state;
+ SalutTubeChannelState state;
TpTubeType type;
gchar *addr;
@@ -1694,7 +1706,7 @@ salut_tubes_channel_get_d_bus_tube_address (TpSvcChannelTypeTubes *iface,
SalutTubeIface *tube;
gchar *addr;
TpTubeType type;
- TpTubeState state;
+ SalutTubeChannelState state;
g_assert (SALUT_IS_TUBES_CHANNEL (self));
@@ -1774,7 +1786,7 @@ salut_tubes_channel_get_d_bus_names (TpSvcChannelTypeTubes *iface,
GHashTable *names;
GPtrArray *ret;
TpTubeType type;
- TpTubeState state;
+ SalutTubeChannelState state;
guint i;
g_assert (SALUT_IS_TUBES_CHANNEL (self));
@@ -1882,7 +1894,7 @@ send_channel_iq_tube (gpointer key,
TpHandle initiator;
gchar *service;
GHashTable *parameters;
- TpTubeState state;
+ SalutTubeChannelState state;
TpTubeType type;
g_object_get (tube,
@@ -2027,6 +2039,7 @@ salut_tubes_channel_offer_stream_tube (TpSvcChannelTypeTubes *iface,
guint tube_id;
SalutTubeIface *tube;
GError *error = NULL;
+ SalutTubeChannelState initial_state;
priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
base = (TpBaseConnection *) priv->conn;
@@ -2052,8 +2065,13 @@ salut_tubes_channel_offer_stream_tube (TpSvcChannelTypeTubes *iface,
tube_id = generate_tube_id ();
+ if (priv->handle_type == TP_HANDLE_TYPE_ROOM)
+ initial_state = SALUT_TUBE_CHANNEL_STATE_OPEN;
+ else
+ initial_state = SALUT_TUBE_CHANNEL_STATE_REMOTE_PENDING;
+
tube = create_new_tube (self, TP_TUBE_TYPE_STREAM, priv->self_handle,
- service, parameters, tube_id, 0, NULL);
+ initial_state, service, parameters, tube_id, 0, NULL);
g_object_set (tube,
"address-type", address_type,
@@ -2091,7 +2109,7 @@ salut_tubes_channel_accept_stream_tube (TpSvcChannelTypeTubes *iface,
SalutTubesChannel *self = SALUT_TUBES_CHANNEL (iface);
SalutTubesChannelPrivate *priv;
SalutTubeIface *tube;
- TpTubeState state;
+ SalutTubeChannelState state;
TpTubeType type;
GValue *address;
GError *error = NULL;
@@ -2195,7 +2213,7 @@ salut_tubes_channel_get_stream_tube_socket_address (TpSvcChannelTypeTubes *iface
SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
SalutTubeIface *tube;
TpTubeType type;
- TpTubeState state;
+ SalutTubeChannelState state;
GValue *address;
TpSocketAddressType address_type;
@@ -2504,6 +2522,36 @@ emit_tube_closed_signal (gpointer key,
tp_svc_channel_type_tubes_emit_tube_closed (self, id);
}
+struct _ForeachData
+{
+ TpExportableChannelFunc foreach;
+ gpointer user_data;
+};
+
+static void
+foreach_slave (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ SalutTubeIface *tube = SALUT_TUBE_IFACE (value);
+ struct _ForeachData *data = (struct _ForeachData *) user_data;
+
+ data->foreach (TP_EXPORTABLE_CHANNEL (tube), data->user_data);
+}
+
+void salut_tubes_channel_foreach (SalutTubesChannel *self,
+ TpExportableChannelFunc foreach, gpointer user_data)
+{
+ struct _ForeachData data;
+ SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
+
+ data.user_data = user_data;
+ data.foreach = foreach;
+
+ g_hash_table_foreach (priv->tubes, foreach_slave, &data);
+}
+
+
void
salut_tubes_channel_close (SalutTubesChannel *self)
{
diff --git a/src/salut-tubes-channel.h b/src/salut-tubes-channel.h
index 6a3913e..1bf1945 100644
--- a/src/salut-tubes-channel.h
+++ b/src/salut-tubes-channel.h
@@ -66,6 +66,9 @@ GType salut_tubes_channel_get_type (void);
(G_TYPE_INSTANCE_GET_CLASS ((obj), SALUT_TYPE_TUBES_CHANNEL, \
SalutTubesChannelClass))
+void salut_tubes_channel_foreach (SalutTubesChannel *self,
+ TpExportableChannelFunc foreach, gpointer user_data);
+
void salut_tubes_channel_close (SalutTubesChannel *channel);
void salut_tubes_channel_bytestream_offered (SalutTubesChannel *chanel,
diff --git a/src/salut-tubes-manager.c b/src/salut-tubes-manager.c
index 808481b..1072d46 100644
--- a/src/salut-tubes-manager.c
+++ b/src/salut-tubes-manager.c
@@ -680,7 +680,13 @@ _foreach_slave (gpointer key,
struct _ForeachData *data = (struct _ForeachData *) user_data;
TpExportableChannel *chan = TP_EXPORTABLE_CHANNEL (value);
+ /* Add channels of type Channel.Type.Tubes */
data->foreach (chan, data->user_data);
+
+ /* Add channels of type Channel.Type.{Stream|DBus}Tube which live in the
+ * SalutTubesChannel object */
+ salut_tubes_channel_foreach (SALUT_TUBES_CHANNEL (chan), data->foreach,
+ data->user_data);
}
static void
diff --git a/src/tube-iface.c b/src/tube-iface.c
index 4ea7351..2a752b2 100644
--- a/src/tube-iface.c
+++ b/src/tube-iface.c
@@ -19,6 +19,8 @@
#include "tube-iface.h"
+#include <telepathy-glib/gtypes.h>
+
#include "salut-connection.h"
#include "salut-tubes-channel.h"
@@ -180,7 +182,7 @@ salut_tube_iface_base_init (gpointer klass)
"parameters",
"parameters GHashTable",
"GHashTable containing parameters of this DBUS tube object.",
- G_TYPE_HASH_TABLE,
+ TP_HASH_TYPE_STRING_VARIANT_MAP,
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_interface_install_property (klass, param_spec);
diff --git a/src/tube-stream.c b/src/tube-stream.c
index e382ae4..5b7ac72 100644
--- a/src/tube-stream.c
+++ b/src/tube-stream.c
@@ -34,6 +34,16 @@
#include <glib/gstdio.h>
#include <telepathy-glib/gtypes.h>
+#include <telepathy-glib/channel-iface.h>
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/exportable-channel.h>
+#include <telepathy-glib/gtypes.h>
+#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/svc-channel.h>
+#include <telepathy-glib/svc-generic.h>
+
+#include <gibber/gibber-xmpp-stanza.h>
+#include <gibber/gibber-namespaces.h>
#include <gibber/gibber-bytestream-direct.h>
#include <gibber/gibber-bytestream-iface.h>
#include <gibber/gibber-bytestream-oob.h>
@@ -54,12 +64,34 @@
#include "tube-iface.h"
#include "salut-si-bytestream-manager.h"
#include "salut-contact-manager.h"
+#include "salut-tubes-channel.h"
#include "salut-xmpp-connection-manager.h"
static void tube_iface_init (gpointer g_iface, gpointer iface_data);
+static void channel_iface_init (gpointer g_iface, gpointer iface_data);
+static void streamtube_iface_init (gpointer g_iface, gpointer iface_data);
G_DEFINE_TYPE_WITH_CODE (SalutTubeStream, salut_tube_stream, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (SALUT_TYPE_TUBE_IFACE, tube_iface_init));
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
+ tp_dbus_properties_mixin_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init);
+ G_IMPLEMENT_INTERFACE (SALUT_TYPE_TUBE_IFACE, tube_iface_init);
+ G_IMPLEMENT_INTERFACE (SALUT_TYPE_SVC_CHANNEL_TYPE_STREAM_TUBE,
+ streamtube_iface_init);
+ G_IMPLEMENT_INTERFACE (SALUT_TYPE_SVC_CHANNEL_INTERFACE_TUBE,
+ NULL);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_EXPORTABLE_CHANNEL, NULL);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL));
+
+static const gchar *salut_tube_stream_interfaces[] = {
+ TP_IFACE_CHANNEL_INTERFACE_GROUP,
+ /* If more interfaces are added, either keep Tube as the first, or change
+ * the implementations of salut_tube_stream_get_interfaces () and
+ * salut_tube_stream_get_property () too */
+ SALUT_IFACE_CHANNEL_INTERFACE_TUBE,
+ NULL
+};
+
/* Linux glibc bits/socket.h suggests that struct sockaddr_storage is
* not guaranteed to be big enough for AF_UNIX addresses */
@@ -87,6 +119,7 @@ enum
{
PROP_CONNECTION = 1,
PROP_TUBES_CHANNEL,
+ PROP_INTERFACES,
PROP_HANDLE,
PROP_HANDLE_TYPE,
PROP_SELF_HANDLE,
@@ -103,6 +136,11 @@ enum
PROP_XMPP_CONNECTION_MANAGER,
PROP_PORT,
PROP_IQ_REQ,
+ PROP_CHANNEL_DESTROYED,
+ PROP_CHANNEL_PROPERTIES,
+ PROP_OBJECT_PATH,
+ PROP_CHANNEL_TYPE,
+ PROP_TARGET_ID,
LAST_PROPERTY
};
@@ -118,6 +156,7 @@ struct _SalutTubeStreamPrivate
guint port;
GibberXmppConnection *xmpp_connection;
GibberXmppStanza *iq_req;
+ gchar *object_path;
/* Bytestreams for MUC tubes (using stream initiation) or 1-1 tubes (using
* direct TCP connections). One tube can have several bytestreams. The
@@ -144,7 +183,7 @@ struct _SalutTubeStreamPrivate
TpHandle initiator;
gchar *service;
GHashTable *parameters;
- TpTubeState state;
+ SalutTubeChannelState state;
TpSocketAddressType address_type;
GValue *address;
@@ -958,6 +997,7 @@ salut_tube_stream_get_property (GObject *object,
{
SalutTubeStream *self = SALUT_TUBE_STREAM (object);
SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self);
+ TpBaseConnection *base_conn = (TpBaseConnection *) priv->conn;
switch (property_id)
{
@@ -967,6 +1007,24 @@ salut_tube_stream_get_property (GObject *object,
case PROP_CONNECTION:
g_value_set_object (value, priv->conn);
break;
+ case PROP_OBJECT_PATH:
+ g_value_set_string (value, priv->object_path);
+ break;
+ case PROP_INTERFACES:
+ if (priv->handle_type == TP_HANDLE_TYPE_ROOM)
+ {
+ /* MUC tubes */
+ g_value_set_boxed (value, salut_tube_stream_interfaces);
+ }
+ else
+ {
+ /* 1-1 tubes - omit the Group interface */
+ g_value_set_boxed (value, salut_tube_stream_interfaces + 1);
+ }
+ break;
+ case PROP_CHANNEL_TYPE:
+ g_value_set_static_string (value, SALUT_IFACE_CHANNEL_TYPE_STREAM_TUBE);
+ break;
case PROP_HANDLE:
g_value_set_uint (value, priv->handle);
break;
@@ -1015,6 +1073,27 @@ salut_tube_stream_get_property (GObject *object,
case PROP_IQ_REQ:
g_value_set_pointer (value, priv->iq_req);
break;
+ case PROP_CHANNEL_DESTROYED:
+ g_value_set_boolean (value, priv->closed);
+ break;
+ case PROP_CHANNEL_PROPERTIES:
+ g_value_take_boxed (value,
+ tp_dbus_properties_mixin_make_properties_hash (object,
+ TP_IFACE_CHANNEL, "TargetHandle",
+ TP_IFACE_CHANNEL, "TargetHandleType",
+ TP_IFACE_CHANNEL, "ChannelType",
+ TP_IFACE_CHANNEL, "TargetID",
+ NULL));
+ break;
+ case PROP_TARGET_ID:
+ {
+ TpHandleRepoIface *repo = tp_base_connection_get_handles (
+ base_conn, priv->handle_type);
+
+ g_value_set_string (value,
+ tp_handle_inspect (repo, priv->handle));
+ }
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -1038,6 +1117,14 @@ salut_tube_stream_set_property (GObject *object,
case PROP_CONNECTION:
priv->conn = g_value_get_object (value);
break;
+ case PROP_OBJECT_PATH:
+ g_free (priv->object_path);
+ priv->object_path = g_value_dup_string (value);
+ break;
+ case PROP_CHANNEL_TYPE:
+ /* this property is writable in the interface, but not actually
+ * meaningfully changeable on this channel, so we do nothing */
+ break;
case PROP_HANDLE:
priv->handle = g_value_get_uint (value);
break;
@@ -1062,6 +1149,11 @@ salut_tube_stream_set_property (GObject *object,
g_hash_table_destroy (priv->parameters);
priv->parameters = g_value_dup_boxed (value);
break;
+ case PROP_STATE:
+ priv->state = g_value_get_uint (value);
+ if (priv->state == SALUT_TUBE_CHANNEL_STATE_OPEN)
+ g_signal_emit (G_OBJECT (self), signals[OPENED], 0);
+ break;
case PROP_ADDRESS_TYPE:
g_assert (g_value_get_uint (value) == TP_SOCKET_ADDRESS_TYPE_UNIX ||
g_value_get_uint (value) == TP_SOCKET_ADDRESS_TYPE_IPV4 ||
@@ -1190,6 +1282,7 @@ salut_tube_stream_constructor (GType type,
GObject *obj;
SalutTubeStreamPrivate *priv;
TpHandleRepoIface *contact_repo;
+ DBusGConnection *bus;
obj = G_OBJECT_CLASS (salut_tube_stream_parent_class)->
constructor (type, n_props, props);
@@ -1210,18 +1303,20 @@ salut_tube_stream_constructor (GType type,
if (priv->handle_type == TP_HANDLE_TYPE_CONTACT)
{
/* Private tube */
- priv->offer_needed = TRUE;
- priv->state = TP_TUBE_STATE_REMOTE_PENDING;
+ g_assert (priv->state == SALUT_TUBE_CHANNEL_STATE_NOT_OFFERED ||
+ priv->state == SALUT_TUBE_CHANNEL_STATE_REMOTE_PENDING);
+ if (priv->state == SALUT_TUBE_CHANNEL_STATE_REMOTE_PENDING)
+ priv->offer_needed = TRUE;
}
else
{
/* Muc tube */
- priv->state = TP_TUBE_STATE_OPEN;
+ g_assert (priv->state == SALUT_TUBE_CHANNEL_STATE_OPEN);
}
}
else
{
- priv->state = TP_TUBE_STATE_LOCAL_PENDING;
+ g_assert (priv->state == SALUT_TUBE_CHANNEL_STATE_LOCAL_PENDING);
}
if (priv->handle_type == TP_HANDLE_TYPE_CONTACT)
@@ -1236,12 +1331,88 @@ salut_tube_stream_constructor (GType type,
g_assert (priv->xmpp_connection_manager == NULL);
}
+ bus = tp_get_bus ();
+ dbus_g_connection_register_g_object (bus, priv->object_path, obj);
+
+ DEBUG ("Registering at '%s'", priv->object_path);
+
return obj;
}
+static gboolean
+tube_iface_props_setter (GObject *object,
+ GQuark interface,
+ GQuark name,
+ const GValue *value,
+ gpointer setter_data,
+ GError **error)
+{
+ SalutTubeStream *self = SALUT_TUBE_STREAM (object);
+ SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self);
+
+ g_return_val_if_fail (interface == SALUT_IFACE_QUARK_CHANNEL_INTERFACE_TUBE,
+ FALSE);
+
+ if (name != g_quark_from_static_string ("Parameters"))
+ {
+ g_object_set_property (object, setter_data, value);
+ return TRUE;
+ }
+
+ if (priv->state != SALUT_TUBE_CHANNEL_STATE_NOT_OFFERED)
+ {
+ g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
+ "Can change parameters only if the tube is not offered");
+ return FALSE;
+ }
+
+ priv->parameters = g_value_dup_boxed (value);
+
+ return TRUE;
+}
+
+
static void
salut_tube_stream_class_init (SalutTubeStreamClass *salut_tube_stream_class)
{
+ static TpDBusPropertiesMixinPropImpl channel_props[] = {
+ { "TargetHandleType", "handle-type", NULL },
+ { "TargetHandle", "handle", NULL },
+ { "ChannelType", "channel-type", NULL },
+ { "TargetID", "target-id", NULL },
+ { "Interfaces", "interfaces", NULL },
+ { NULL }
+ };
+ static TpDBusPropertiesMixinPropImpl stream_tube_props[] = {
+ { "Service", "service", NULL },
+ /*{ "AvailableStreamTubeTypes", NULL, NULL },*/
+ { NULL }
+ };
+ static TpDBusPropertiesMixinPropImpl tube_iface_props[] = {
+ { "Initiator", "initiator", NULL },
+ { "Parameters", "parameters", "parameters" },
+ { "Status", "state", NULL },
+ { NULL }
+ };
+ static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
+ { TP_IFACE_CHANNEL,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ NULL,
+ channel_props,
+ },
+ { SALUT_IFACE_CHANNEL_TYPE_STREAM_TUBE,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ NULL,
+ stream_tube_props,
+ },
+ { SALUT_IFACE_CHANNEL_INTERFACE_TUBE,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ tube_iface_props_setter,
+ tube_iface_props,
+ },
+ { NULL }
+ };
+
GObjectClass *object_class = G_OBJECT_CLASS (salut_tube_stream_class);
GParamSpec *param_spec;
@@ -1278,6 +1449,23 @@ salut_tube_stream_class_init (SalutTubeStreamClass *salut_tube_stream_class)
g_object_class_override_property (object_class, PROP_STATE,
"state");
+ g_object_class_override_property (object_class, PROP_OBJECT_PATH,
+ "object-path");
+ g_object_class_override_property (object_class, PROP_CHANNEL_TYPE,
+ "channel-type");
+
+ g_object_class_override_property (object_class, PROP_CHANNEL_DESTROYED,
+ "channel-destroyed");
+ g_object_class_override_property (object_class, PROP_CHANNEL_PROPERTIES,
+ "channel-properties");
+
+ param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
+ "Additional Channel.Interface.* interfaces",
+ G_TYPE_STRV,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME);
+ g_object_class_install_property (object_class, PROP_INTERFACES, param_spec);
+
param_spec = g_param_spec_uint (
"address-type",
"address type",
@@ -1317,6 +1505,13 @@ salut_tube_stream_class_init (SalutTubeStreamClass *salut_tube_stream_class)
g_object_class_install_property (object_class, PROP_ACCESS_CONTROL_PARAM,
param_spec);
+ param_spec = g_param_spec_string ("target-id", "Target JID",
+ "The string obtained by inspecting the target handle",
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME);
+ g_object_class_install_property (object_class, PROP_TARGET_ID, param_spec);
+
param_spec = g_param_spec_object (
"xmpp-connection-manager",
"SalutXmppConnectionManager object",
@@ -1381,6 +1576,10 @@ salut_tube_stream_class_init (SalutTubeStreamClass *salut_tube_stream_class)
NULL, NULL,
salut_signals_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+
+ salut_tube_stream_class->dbus_props_class.interfaces = prop_interfaces;
+ tp_dbus_properties_mixin_class_init (object_class,
+ G_STRUCT_OFFSET (SalutTubeStreamClass, dbus_props_class));
}
static void
@@ -1432,26 +1631,39 @@ salut_tube_stream_new (SalutConnection *conn,
TpHandleType handle_type,
TpHandle self_handle,
TpHandle initiator,
+ SalutTubeChannelState initial_state,
const gchar *service,
GHashTable *parameters,
guint id,
guint portnum,
GibberXmppStanza *iq_req)
{
- return g_object_new (SALUT_TYPE_TUBE_STREAM,
+ SalutTubeStream *obj;
+ char *object_path;
+
+ object_path = g_strdup_printf ("%s/StreamTubeChannel_%u_%u",
+ conn->parent.object_path, handle, id);
+
+ obj = g_object_new (SALUT_TYPE_TUBE_STREAM,
"connection", conn,
"tubes-channel", tubes_channel,
+ "object-path", object_path,
"xmpp-connection-manager", xmpp_connection_manager,
"handle", handle,
"handle-type", handle_type,
"self-handle", self_handle,
"initiator", initiator,
+ "state", initial_state,
"service", service,
"parameters", parameters,
"id", id,
"port", portnum,
"iq-req", iq_req,
NULL);
+
+ g_free (object_path);
+
+ return obj;
}
static void
@@ -1502,7 +1714,7 @@ salut_tube_stream_accept (SalutTubeIface *tube,
SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self);
GibberXmppStanza *reply;
- if (priv->state != TP_TUBE_STATE_LOCAL_PENDING)
+ if (priv->state != SALUT_TUBE_CHANNEL_STATE_LOCAL_PENDING)
return TRUE;
if (!tube_stream_open (self, error))
@@ -1526,7 +1738,7 @@ salut_tube_stream_accept (SalutTubeIface *tube,
}
}
- priv->state = TP_TUBE_STATE_OPEN;
+ priv->state = SALUT_TUBE_CHANNEL_STATE_OPEN;
g_signal_emit (G_OBJECT (self), signals[OPENED], 0);
return TRUE;
}
@@ -1559,8 +1771,11 @@ salut_tube_stream_offer_needed (SalutTubeIface *tube)
{
SalutTubeStream *self = SALUT_TUBE_STREAM (tube);
SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self);
+ gboolean ret = priv->offer_needed;
- return priv->offer_needed;
+ priv->offer_needed = FALSE;
+
+ return ret;
}
/* callback for listening connections from the contact's CM */
@@ -1753,10 +1968,10 @@ salut_tube_stream_add_bytestream (SalutTubeIface *tube,
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
(TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
- if (priv->state == TP_TUBE_STATE_REMOTE_PENDING)
+ if (priv->state == SALUT_TUBE_CHANNEL_STATE_REMOTE_PENDING)
{
DEBUG ("Received first connection. Tube is now open");
- priv->state = TP_TUBE_STATE_OPEN;
+ priv->state = SALUT_TUBE_CHANNEL_STATE_OPEN;
g_signal_emit (G_OBJECT (self), signals[OPENED], 0);
}
@@ -1956,6 +2171,231 @@ salut_tube_stream_check_params (TpSocketAddressType address_type,
}
static void
+stream_tube_new_connection_cb (SalutTubesChannel *self,
+ guint contact,
+ gpointer user_data)
+{
+ salut_svc_channel_type_stream_tube_emit_stream_tube_new_connection (
+ self, contact);
+}
+
+/**
+ * salut_tube_stream_offer_stream_tube
+ *
+ * Implements D-Bus method OfferStreamTube
+ * on org.freedesktop.Telepathy.Channel.Type.StreamTube
+ */
+static void
+salut_tube_stream_offer_stream_tube (SalutSvcChannelTypeStreamTube *iface,
+ guint address_type,
+ const GValue *address,
+ guint access_control,
+ const GValue *access_control_param,
+ DBusGMethodInvocation *context)
+{
+ SalutTubeStream *self = SALUT_TUBE_STREAM (iface);
+ SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self);
+ GError *error = NULL;
+
+ if (priv->state != SALUT_TUBE_CHANNEL_STATE_NOT_OFFERED)
+ {
+ g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+ "Tube is not in the not offered state");
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ if (!salut_tube_stream_check_params (address_type, address,
+ access_control, access_control_param, &error))
+ {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ g_assert (address_type == TP_SOCKET_ADDRESS_TYPE_UNIX ||
+ address_type == TP_SOCKET_ADDRESS_TYPE_IPV4 ||
+ address_type == TP_SOCKET_ADDRESS_TYPE_IPV6);
+ g_assert (priv->address == NULL);
+ priv->address_type = address_type;
+ priv->address = tp_g_value_slice_dup (address);
+ g_assert (priv->access_control == TP_SOCKET_ACCESS_CONTROL_LOCALHOST);
+ priv->access_control = access_control;
+ g_assert (priv->access_control_param == NULL);
+ priv->access_control_param = tp_g_value_slice_dup (access_control_param);
+
+ if (priv->handle_type == TP_HANDLE_TYPE_CONTACT)
+ {
+ salut_tubes_channel_send_iq_offer (priv->tubes_channel);
+
+ salut_svc_channel_interface_tube_emit_tube_channel_state_changed (
+ self, SALUT_TUBE_CHANNEL_STATE_REMOTE_PENDING);
+ }
+
+ g_signal_connect (self, "new-connection",
+ G_CALLBACK (stream_tube_new_connection_cb), self);
+
+ salut_svc_channel_type_stream_tube_return_from_offer_stream_tube (context);
+}
+
+/**
+ * salut_tube_stream_accept_stream_tube
+ *
+ * Implements D-Bus method AcceptStreamTube
+ * on org.freedesktop.Telepathy.Channel.Type.StreamTube
+ */
+static void
+salut_tube_stream_accept_stream_tube (SalutSvcChannelTypeStreamTube *iface,
+ guint address_type,
+ guint access_control,
+ const GValue *access_control_param,
+ DBusGMethodInvocation *context)
+{
+ SalutTubeStream *self = SALUT_TUBE_STREAM (iface);
+ SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self);
+ GError *error = NULL;
+
+ if (address_type != TP_SOCKET_ADDRESS_TYPE_UNIX &&
+ address_type != TP_SOCKET_ADDRESS_TYPE_IPV4 &&
+ address_type != TP_SOCKET_ADDRESS_TYPE_IPV6)
+ {
+ error = g_error_new (TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED,
+ "Address type %d not implemented", address_type);
+
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ if (access_control != TP_SOCKET_ACCESS_CONTROL_LOCALHOST)
+ {
+ GError e = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+ "Unix sockets only support localhost control access" };
+
+ dbus_g_method_return_error (context, &e);
+ return;
+ }
+
+ if (priv->state != SALUT_TUBE_CHANNEL_STATE_LOCAL_PENDING)
+ {
+ GError e = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+ "Tube is not in the local pending state" };
+
+ dbus_g_method_return_error (context, &e);
+ return;
+ }
+
+ if (!salut_tube_stream_accept (SALUT_TUBE_IFACE (self), &error))
+ {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+#if 0
+ /* TODO: add a property "muc" and set it at initialization */
+ if (priv->handle_type == TP_HANDLE_TYPE_ROOM)
+ salut_muc_channel_send_presence (self->muc, NULL);
+#endif
+
+ salut_svc_channel_type_stream_tube_return_from_accept_stream_tube (context,
+ priv->address);
+}
+
+/**
+ * salut_tube_stream_get_stream_tube_socket_address
+ *
+ * Implements D-Bus method GetStreamTubeSocketAddress
+ * on org.freedesktop.Telepathy.Channel.Type.StreamTube
+ */
+static void
+salut_tube_stream_get_stream_tube_socket_address (
+ SalutSvcChannelTypeStreamTube *iface,
+ DBusGMethodInvocation *context)
+{
+ SalutTubeStream *self = SALUT_TUBE_STREAM (iface);
+ SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self);
+
+ salut_svc_channel_type_stream_tube_return_from_get_stream_tube_socket_address
+ (context, priv->address_type, priv->address);
+}
+
+/**
+ * salut_tube_stream_close_async:
+ *
+ * Implements D-Bus method Close
+ * on interface org.freedesktop.Telepathy.Channel
+ */
+static void
+salut_tube_stream_close_async (TpSvcChannel *iface,
+ DBusGMethodInvocation *context)
+{
+ SalutTubeStream *self = SALUT_TUBE_STREAM (iface);
+
+ tp_svc_channel_emit_closed (self);
+ tp_svc_channel_return_from_close (context);
+}
+
+/**
+ * salut_tube_stream_get_channel_type
+ *
+ * Implements D-Bus method GetChannelType
+ * on interface org.freedesktop.Telepathy.Channel
+ */
+static void
+salut_tube_stream_get_channel_type (TpSvcChannel *iface,
+ DBusGMethodInvocation *context)
+{
+ tp_svc_channel_return_from_get_channel_type (context,
+ SALUT_IFACE_CHANNEL_TYPE_STREAM_TUBE);
+}
+
+/**
+ * salut_tube_stream_get_handle
+ *
+ * Implements D-Bus method GetHandle
+ * on interface org.freedesktop.Telepathy.Channel
+ */
+static void
+salut_tube_stream_get_handle (TpSvcChannel *iface,
+ DBusGMethodInvocation *context)
+{
+ SalutTubeStream *self = SALUT_TUBE_STREAM (iface);
+ SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self);
+
+ tp_svc_channel_return_from_get_handle (context, priv->handle_type,
+ priv->handle);
+}
+
+/**
+ * salut_tube_stream_get_interfaces
+ *
+ * Implements D-Bus method GetInterfaces
+ * on interface org.freedesktop.Telepathy.Channel
+ */
+static void
+salut_tube_stream_get_interfaces (TpSvcChannel *iface,
+ DBusGMethodInvocation *context)
+{
+ SalutTubeStream *self = SALUT_TUBE_STREAM (iface);
+ SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self);
+
+ if (priv->handle_type == TP_HANDLE_TYPE_CONTACT)
+ {
+ /* omit the Group interface */
+ tp_svc_channel_return_from_get_interfaces (context,
+ salut_tube_stream_interfaces + 1);
+ }
+ else
+ {
+ tp_svc_channel_return_from_get_interfaces (context,
+ salut_tube_stream_interfaces);
+ }
+}
+
+
+static void
tube_iface_init (gpointer g_iface,
gpointer iface_data)
{
@@ -1968,3 +2408,33 @@ tube_iface_init (gpointer g_iface,
klass->close = salut_tube_stream_close;
klass->add_bytestream = salut_tube_stream_add_bytestream;
}
+
+static void
+streamtube_iface_init (gpointer g_iface,
+ gpointer iface_data)
+{
+ SalutSvcChannelTypeStreamTubeClass *klass =
+ (SalutSvcChannelTypeStreamTubeClass *) g_iface;
+
+#define IMPLEMENT(x) salut_svc_channel_type_stream_tube_implement_##x (\
+ klass, salut_tube_stream_##x)
+ IMPLEMENT(offer_stream_tube);
+ IMPLEMENT(accept_stream_tube);
+ IMPLEMENT(get_stream_tube_socket_address);
+#undef IMPLEMENT
+}
+
+static void
+channel_iface_init (gpointer g_iface,
+ gpointer iface_data)
+{
+ TpSvcChannelClass *klass = (TpSvcChannelClass *) g_iface;
+
+#define IMPLEMENT(x, suffix) tp_svc_channel_implement_##x (\
+ klass, salut_tube_stream_##x##suffix)
+ IMPLEMENT(close,_async);
+ IMPLEMENT(get_channel_type,);
+ IMPLEMENT(get_handle,);
+ IMPLEMENT(get_interfaces,);
+#undef IMPLEMENT
+}
diff --git a/src/tube-stream.h b/src/tube-stream.h
index 61804a1..26cbfdb 100644
--- a/src/tube-stream.h
+++ b/src/tube-stream.h
@@ -24,6 +24,7 @@
#include <telepathy-glib/enums.h>
+#include "extensions/extensions.h"
#include "salut-connection.h"
#include "salut-tubes-channel.h"
@@ -34,6 +35,8 @@ typedef struct _SalutTubeStreamClass SalutTubeStreamClass;
struct _SalutTubeStreamClass {
GObjectClass parent_class;
+
+ TpDBusPropertiesMixinClass dbus_props_class;
};
struct _SalutTubeStream {
@@ -63,9 +66,10 @@ GType salut_tube_stream_get_type (void);
SalutTubeStream *salut_tube_stream_new (SalutConnection *conn,
SalutTubesChannel *tubes_channel,
SalutXmppConnectionManager *xmpp_connection_manager, TpHandle handle,
- TpHandleType handle_type, TpHandle self_handle, TpHandle initiator,
- const gchar *service, GHashTable *parameters, guint id, guint portnum,
- GibberXmppStanza *iq_req);
+ TpHandleType handle_type, TpHandle self_handle,
+ TpHandle initiator, SalutTubeChannelState initial_state,
+ const gchar *service, GHashTable *parameters, guint id,
+ guint portnum, GibberXmppStanza *iq_req);
gboolean salut_tube_stream_check_params (TpSocketAddressType address_type,
const GValue *address, TpSocketAccessControl access_control,
diff --git a/tests/twisted/avahi/test-tube.py b/tests/twisted/avahi/test-tube.py
index e2f1d89..363ff3c 100644
--- a/tests/twisted/avahi/test-tube.py
+++ b/tests/twisted/avahi/test-tube.py
@@ -8,7 +8,8 @@ import errno
import string
from xmppstream import setup_stream_listener, connect_to_stream
-from servicetest import make_channel_proxy, Event
+from servicetest import make_channel_proxy, Event, EventPattern, call_async, \
+ tp_name_prefix
from twisted.words.xish import xpath, domish
from twisted.internet.protocol import Factory, Protocol, ClientCreator
@@ -33,9 +34,108 @@ sample_parameters = dbus.Dictionary({
test_string = "This string travels on a tube !"
-print "FIXME: test-tube.py disabled because 1-1 tubes are disabled for now"
-# exiting 77 causes automake to consider the test to have been skipped
-raise SystemExit(77)
+def check_conn_properties(q, bus, conn, channel_list=None):
+ properties = conn.GetAll(
+ 'org.freedesktop.Telepathy.Connection.Interface.Requests',
+ dbus_interface='org.freedesktop.DBus.Properties')
+
+ if channel_list == None:
+ assert properties.get('Channels') == [], properties['Channels']
+ else:
+ for i in channel_list:
+ assert i in properties['Channels'], \
+ (i, properties['Channels'])
+
+ assert ({'org.freedesktop.Telepathy.Channel.ChannelType':
+ 'org.freedesktop.Telepathy.Channel.Type.Tubes',
+ 'org.freedesktop.Telepathy.Channel.TargetHandleType': 1,
+ },
+ ['org.freedesktop.Telepathy.Channel.TargetHandle',
+ ]
+ ) in properties.get('RequestableChannelClasses'),\
+ properties['RequestableChannelClasses']
+ assert ({'org.freedesktop.Telepathy.Channel.ChannelType':
+ 'org.freedesktop.Telepathy.Channel.Type.StreamTube.DRAFT',
+ 'org.freedesktop.Telepathy.Channel.TargetHandleType': 1,
+ },
+ ['org.freedesktop.Telepathy.Channel.TargetHandle',
+ 'org.freedesktop.Telepathy.Channel.Interface.Tube.DRAFT.Parameters',
+ 'org.freedesktop.Telepathy.Channel.Type.StreamTube.DRAFT.Service',
+ ]
+ ) in properties.get('RequestableChannelClasses'),\
+ properties['RequestableChannelClasses']
+
+def check_channel_properties(q, bus, conn, channel, channel_type,
+ contact_handle, contact_id, state=None):
+ # Exercise basic Channel Properties from spec 0.17.7
+ # on the channel of type channel_type
+ channel_props = channel.GetAll(
+ 'org.freedesktop.Telepathy.Channel',
+ dbus_interface='org.freedesktop.DBus.Properties')
+ assert channel_props.get('TargetHandle') == contact_handle,\
+ (channel_props.get('TargetHandle'), contact_handle)
+ assert channel_props.get('TargetHandleType') == 1,\
+ channel_props.get('TargetHandleType')
+ assert channel_props.get('ChannelType') == \
+ 'org.freedesktop.Telepathy.Channel.Type.' + channel_type,\
+ channel_props.get('ChannelType')
+ assert 'Interfaces' in channel_props, channel_props
+ assert 'org.freedesktop.Telepathy.Channel.Interface.Group' not in \
+ channel_props['Interfaces'], \
+ channel_props['Interfaces']
+ assert channel_props['TargetID'] == contact_id
+
+ if channel_type == "Tubes":
+ assert state is None
+ else:
+ assert state is not None
+ tube_props = channel.GetAll(
+ 'org.freedesktop.Telepathy.Channel.Interface.Tube.DRAFT',
+ dbus_interface='org.freedesktop.DBus.Properties')
+ assert tube_props['Status'] == state
+ # no strict check but at least check the properties exist
+ assert tube_props['Parameters'] is not None
+ assert tube_props['Initiator'] is not None
+
+ self_handle = conn.GetSelfHandle()
+
+ ## Exercise FUTURE properties
+ ## on the channel of type channel_type
+ #future_props = channel.GetAll(
+ # 'org.freedesktop.Telepathy.Channel.FUTURE',
+ # dbus_interface='org.freedesktop.DBus.Properties')
+ #assert future_props['Requested'] == True
+ #assert future_props['InitiatorID'] == 'test at localhost'
+ #assert future_props['InitiatorHandle'] == self_handle
+
+
+def check_NewChannel_signal(old_sig, channel_type, chan_path, contact_handle):
+ assert old_sig[0] == chan_path
+ assert old_sig[1] == tp_name_prefix + '.Channel.Type.' + channel_type
+ assert old_sig[2] == 1 # contact handle
+ assert old_sig[3] == contact_handle
+ assert old_sig[4] == True # suppress handler
+
+def check_NewChannels_signal(new_sig, channel_type, chan_path, contact_handle,
+ contact_id, initiator_handle):
+ assert len(new_sig) == 1
+ assert len(new_sig[0]) == 1 # one channel
+ assert len(new_sig[0][0]) == 2 # two struct members
+ assert new_sig[0][0][0] == chan_path
+ emitted_props = new_sig[0][0][1]
+
+ assert emitted_props[tp_name_prefix + '.Channel.ChannelType'] ==\
+ tp_name_prefix + '.Channel.Type.' + channel_type
+ assert emitted_props[tp_name_prefix + '.Channel.TargetHandleType'] == 1
+ assert emitted_props[tp_name_prefix + '.Channel.TargetHandle'] ==\
+ contact_handle
+ assert emitted_props[tp_name_prefix + '.Channel.TargetID'] == \
+ contact_id
+ #assert emitted_props[tp_name_prefix + '.Channel.FUTURE.Requested'] == True
+ #assert emitted_props[tp_name_prefix + '.Channel.FUTURE.InitiatorHandle'] \
+ # == initiator_handle
+ #assert emitted_props[tp_name_prefix + '.Channel.FUTURE.InitiatorID'] == \
+ # 'test at localhost'
def test(q, bus, conn):
@@ -67,11 +167,14 @@ def test(q, bus, conn):
raise
l = reactor.listenUNIX(server_socket_address, factory)
+
+ check_conn_properties(q, bus, conn)
+
conn.Connect()
q.expect('dbus-signal', signal='StatusChanged', args=[0L, 0L])
basic_txt = { "txtvers": "1", "status": "avail" }
- contact_name = PUBLISHED_NAME + get_host_name()
+ contact_name = PUBLISHED_NAME + "@" + get_host_name()
listener, port = setup_stream_listener(q, contact_name)
announcer = AvahiAnnouncer(contact_name, "_presence._tcp", port, basic_txt)
@@ -90,9 +193,106 @@ def test(q, bus, conn):
if name == contact_name:
handle = h
- t = conn.RequestChannel(CHANNEL_TYPE_TUBES, HT_CONTACT, handle,
- True)
- tubes_channel = make_channel_proxy(conn, t, "Channel.Type.Tubes")
+ # old requestotron
+ call_async(q, conn, 'RequestChannel',
+ CHANNEL_TYPE_TUBES, HT_CONTACT, handle, True);
+
+ ret, old_sig, new_sig = q.expect_many(
+ EventPattern('dbus-return', method='RequestChannel'),
+ EventPattern('dbus-signal', signal='NewChannel'),
+ EventPattern('dbus-signal', signal='NewChannels'),
+ )
+
+ assert len(ret.value) == 1
+ chan_path = ret.value[0]
+
+ check_NewChannel_signal(old_sig.args, "Tubes", chan_path, handle)
+ check_NewChannels_signal(new_sig.args, "Tubes", chan_path,
+ handle, contact_name, conn.GetSelfHandle())
+ old_tubes_channel_properties = new_sig.args[0][0]
+
+ check_conn_properties(q, bus, conn, [old_tubes_channel_properties])
+
+ # new requestotron
+ requestotron = dbus.Interface(conn,
+ 'org.freedesktop.Telepathy.Connection.Interface.Requests')
+
+ # Try to CreateChannel with unknown properties
+ # Salut must return an error
+ call_async(q, requestotron, 'CreateChannel',
+ {'org.freedesktop.Telepathy.Channel.ChannelType':
+ 'org.freedesktop.Telepathy.Channel.Type.StreamTube.DRAFT',
+ 'org.freedesktop.Telepathy.Channel.TargetHandleType':
+ 1,
+ 'org.freedesktop.Telepathy.Channel.TargetHandle':
+ handle,
+ 'this.property.does.not.exist':
+ 'this.value.should.not.exist'
+ });
+ ret = q.expect_many(EventPattern('dbus-error', method='CreateChannel'))
+ # CreateChannel failed, we expect no new channel
+ check_conn_properties(q, bus, conn, [old_tubes_channel_properties])
+
+ # Try to CreateChannel with missing properties ("Service")
+ # Salut must return an error
+ call_async(q, requestotron, 'CreateChannel',
+ {'org.freedesktop.Telepathy.Channel.ChannelType':
+ 'org.freedesktop.Telepathy.Channel.Type.StreamTube.DRAFT',
+ 'org.freedesktop.Telepathy.Channel.TargetHandleType':
+ 1,
+ 'org.freedesktop.Telepathy.Channel.TargetHandle':
+ handle
+ });
+ ret = q.expect_many(EventPattern('dbus-error', method='CreateChannel'))
+ # CreateChannel failed, we expect no new channel
+ check_conn_properties(q, bus, conn, [old_tubes_channel_properties])
+
+ # Try to CreateChannel with correct properties
+ # Salut must succeed
+ call_async(q, requestotron, 'CreateChannel',
+ {'org.freedesktop.Telepathy.Channel.ChannelType':
+ 'org.freedesktop.Telepathy.Channel.Type.StreamTube.DRAFT',
+ 'org.freedesktop.Telepathy.Channel.TargetHandleType':
+ 1,
+ 'org.freedesktop.Telepathy.Channel.TargetHandle':
+ handle,
+ 'org.freedesktop.Telepathy.Channel.Type.StreamTube.DRAFT.Service':
+ "newecho",
+ 'org.freedesktop.Telepathy.Channel.Interface.Tube.DRAFT.Parameters':
+ dbus.Dictionary({'foo': 'bar'}, signature='sv'),
+ });
+ ret, old_sig, new_sig = q.expect_many(
+ EventPattern('dbus-return', method='CreateChannel'),
+ EventPattern('dbus-signal', signal='NewChannel'),
+ EventPattern('dbus-signal', signal='NewChannels'),
+ )
+
+ assert len(ret.value) == 2 # CreateChannel returns 2 values: o, a{sv}
+ new_chan_path = ret.value[0]
+ new_chan_prop_asv = ret.value[1]
+ assert new_chan_path.find("StreamTube") != -1, new_chan_path
+ assert new_chan_path.find("SITubesChannel") == -1, new_chan_path
+ # The path of the Channel.Type.Tubes object MUST be different to the path
+ # of the Channel.Type.StreamTube object !
+ assert chan_path != new_chan_path
+
+ check_NewChannel_signal(old_sig.args, "StreamTube.DRAFT", \
+ new_chan_path, handle)
+ check_NewChannels_signal(new_sig.args, "StreamTube.DRAFT", new_chan_path, \
+ handle, contact_name, conn.GetSelfHandle())
+ stream_tube_channel_properties = new_sig.args[0][0]
+
+ check_conn_properties(q, bus, conn,
+ [old_tubes_channel_properties, stream_tube_channel_properties])
+
+ # continue
+ tubes_channel = make_channel_proxy(conn, chan_path, "Channel.Type.Tubes")
+ tube_channel = make_channel_proxy(conn, new_chan_path,
+ "Channel.Type.StreamTube.DRAFT")
+ check_channel_properties(q, bus, conn, tubes_channel, "Tubes", handle,
+ contact_name)
+ check_channel_properties(q, bus, conn, tube_channel, "StreamTube.DRAFT",
+ handle, contact_name, 3)
tube_id = tubes_channel.OfferStreamTube("http", sample_parameters,
SOCKET_ADDRESS_TYPE_UNIX, dbus.ByteArray(server_socket_address),
@@ -102,7 +302,8 @@ def test(q, bus, conn):
iq_tube = xpath.queryForNodes('/iq/tube', e.stanza)[0]
transport = xpath.queryForNodes('/iq/tube/transport', e.stanza)[0]
assert iq_tube.attributes['type'] == 'stream'
- assert iq_tube.attributes['service'] == 'http'
+ assert iq_tube.attributes['service'] == 'http', \
+ iq_tube.attributes['service']
assert iq_tube.attributes['id'] is not None
port = transport.attributes['port']
assert port is not None
@@ -146,8 +347,9 @@ def test(q, bus, conn):
e = q.expect('client-data-received')
assert e.data == string.swapcase(test_string)
- # Close the tube propertly
- tubes_channel.CloseTube(tube_id)
+ # Close the tubes propertly
+ for i in tubes_channel.ListTubes():
+ tubes_channel.CloseTube(i[0])
conn.Disconnect()
if __name__ == '__main__':
--
1.5.6.5
More information about the telepathy-commits
mailing list