summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stefw@collaora.co.uk>2011-03-24 16:39:25 +0100
committerStef Walter <stefw@collaora.co.uk>2011-03-30 12:27:05 +0200
commit663c28e67bfe366674eea794daae7b42d2f0e772 (patch)
treec3b914c2bc0e9755e0683329ca3bffa2daeffb63
parentd0a7d32072858cb2ceb76716201a97caeb5565ca (diff)
Complete basic implementation of TpYtsChannel
Including TpYtsClient, and TpYtsChannelFactory
-rw-r--r--telepathy-ytstenut-glib/Makefile.am24
-rw-r--r--telepathy-ytstenut-glib/channel-factory.c95
-rw-r--r--telepathy-ytstenut-glib/channel-factory.h63
-rw-r--r--telepathy-ytstenut-glib/channel.c289
-rw-r--r--telepathy-ytstenut-glib/channel.h94
-rw-r--r--telepathy-ytstenut-glib/client.c380
-rw-r--r--telepathy-ytstenut-glib/client.h78
-rw-r--r--telepathy-ytstenut-glib/generated.h16
-rw-r--r--telepathy-ytstenut-glib/telepathy-ytstenut-glib.h21
9 files changed, 1046 insertions, 14 deletions
diff --git a/telepathy-ytstenut-glib/Makefile.am b/telepathy-ytstenut-glib/Makefile.am
index 4c871db..c3e9e34 100644
--- a/telepathy-ytstenut-glib/Makefile.am
+++ b/telepathy-ytstenut-glib/Makefile.am
@@ -12,8 +12,15 @@ lib_LTLIBRARIES = libtelepathy-ytstenut-glib.la
libtelepathy_ytstenut_glib_la_SOURCES = \
account-manager.c \
account-manager.h \
+ channel.c \
+ channel.h \
+ channel-factory.c \
+ channel-factory.h \
+ client.c \
+ client.h \
errors.c \
errors.h \
+ generated.h \
status.c \
status.h \
telepathy-ytstenut-glib.c \
@@ -30,6 +37,8 @@ nodist_libtelepathy_ytstenut_glib_la_SOURCES = \
_gen/interfaces-body.h \
_gen/cli-account-manager.h \
_gen/cli-account-manager-body.h \
+ _gen/cli-channel.h \
+ _gen/cli-channel-body.h \
_gen/cli-status.h \
_gen/cli-status-body.h \
_gen/svc.h \
@@ -47,7 +56,11 @@ BUILT_SOURCES = \
tpytstenutglibinclude_HEADERS = \
account-manager.h \
+ channel.h \
+ channel-factory.h \
+ client.h \
errors.h \
+ generated.h \
status.h \
telepathy-ytstenut-glib.h
@@ -56,6 +69,7 @@ nodist_geninclude_HEADERS = \
_gen/gtypes.h \
_gen/interfaces.h \
_gen/cli-account-manager.h \
+ _gen/cli-channel.h \
_gen/cli-status.h \
_gen/svc.h
@@ -105,6 +119,16 @@ _gen/cli-status-body.h _gen/cli-status.h: $(top_srcdir)/spec/Status.xml \
--tp-proxy-api=0.10.0 \
$< Tp_Yts _gen/cli-status
+_gen/cli-channel-body.h _gen/cli-channel.h: $(top_srcdir)/spec/Channel.xml \
+ $(tools_dir)/glib-client-gen.py
+ $(AM_V_GEN)$(PYTHON) $(tools_dir)/glib-client-gen.py \
+ --group=channel \
+ --subclass=TpYtsChannel \
+ --subclass-assert=TP_IS_YTS_CHANNEL \
+ --iface-quark-prefix=TP_YTS_IFACE_QUARK \
+ --tp-proxy-api=0.10.0 \
+ $< Tp_Yts _gen/cli-channel
+
_gen/svc.c _gen/svc.h: _gen/all.xml $(tools_dir)/glib-ginterface-gen.py \
Makefile.am
$(AM_V_GEN)$(PYTHON) $(tools_dir)/glib-ginterface-gen.py \
diff --git a/telepathy-ytstenut-glib/channel-factory.c b/telepathy-ytstenut-glib/channel-factory.c
new file mode 100644
index 0000000..8aace7d
--- /dev/null
+++ b/telepathy-ytstenut-glib/channel-factory.c
@@ -0,0 +1,95 @@
+/*
+ * channel-fectory.c - channel factory for TpYtsChannel
+ *
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include "channel-factory.h"
+#include "channel.h"
+
+#include <telepathy-glib/defs.h>
+
+#define DEBUG(msg, ...) \
+ g_debug ("%s: " msg, G_STRFUNC, ##__VA_ARGS__)
+
+/**
+ * SECTION:channel-factory
+ * @title: TpYtsChannelFactory
+ * @short_description: channel factory for #TpYtsStatus
+ *
+ * A #TpClientChannelFactory for creating #TpYtsStatus objects.
+ */
+
+/**
+ * TpYtsChannelFactory:
+ *
+ * The #TpYtsChannelFactory is used with
+ * tp_channel_request_set_channel_factory() so that #TpChannelRequest
+ * will create #TpYtsChannel objects.
+ */
+
+/**
+ * TpYtsChannelFactoryClass:
+ *
+ * The class of a #TpYtsChannelFactory.
+ */
+
+static void factory_iface_init (TpClientChannelFactoryInterface *iface,
+ gpointer iface_data);
+
+G_DEFINE_TYPE_WITH_CODE (TpYtsChannelFactory, tp_yts_channel_factory,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_CLIENT_CHANNEL_FACTORY, factory_iface_init)
+);
+
+static void
+tp_yts_channel_factory_init (TpYtsChannelFactory *self)
+{
+
+}
+
+static void
+tp_yts_channel_factory_class_init (TpYtsChannelFactoryClass *klass)
+{
+
+}
+
+static TpChannel *
+tp_yts_channel_factory_obj_create_channel (TpClientChannelFactory *factory,
+ TpConnection *conn,
+ const gchar *path,
+ GHashTable *properties,
+ GError **error)
+{
+ return tp_yts_channel_new_from_properties (conn, path, properties, error);
+}
+
+static void factory_iface_init (TpClientChannelFactoryInterface *iface,
+ gpointer iface_data)
+{
+#define IMPLEMENT(x) iface->x = tp_yts_channel_factory_##x;
+ IMPLEMENT (obj_create_channel);
+#undef IMPLEMENT
+}
+
+TpClientChannelFactory *
+tp_yts_channel_factory_new (void)
+{
+ return g_object_new (TP_TYPE_YTS_CHANNEL_FACTORY, NULL);
+}
diff --git a/telepathy-ytstenut-glib/channel-factory.h b/telepathy-ytstenut-glib/channel-factory.h
new file mode 100644
index 0000000..8d8106b
--- /dev/null
+++ b/telepathy-ytstenut-glib/channel-factory.h
@@ -0,0 +1,63 @@
+/*
+ * channel-factory.h - channel factory for TpYtsChannel
+ *
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef TP_YTS_CHANNEL_FACTORY_H
+#define TP_YTS_CHANNEL_FACTORY_H
+
+#include <telepathy-glib/client-channel-factory.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TpYtsChannelFactory TpYtsChannelFactory;
+typedef struct _TpYtsChannelFactoryClass TpYtsChannelFactoryClass;
+typedef struct _TpYtsChannelFactoryPrivate TpYtsChannelFactoryPrivate;
+
+struct _TpYtsChannelFactory {
+ /*<private>*/
+ GObject parent;
+ TpYtsChannelFactoryPrivate *priv;
+};
+
+struct _TpYtsChannelFactoryClass {
+ /*<private>*/
+ GObjectClass parent_class;
+ GCallback _padding[7];
+};
+
+GType tp_yts_channel_factory_get_type (void);
+
+#define TP_TYPE_YTS_CHANNEL_FACTORY (tp_yts_channel_factory_get_type ())
+#define TP_YTS_CHANNEL_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ TP_TYPE_YTS_CHANNEL_FACTORY, TpYtsChannelFactory))
+#define TP_YTS_CHANNEL_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ TP_TYPE_YTS_CHANNEL_FACTORY, TpYtsChannelFactoryClass))
+#define TP_IS_YTS_CHANNEL_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ TP_TYPE_YTS_CHANNEL_FACTORY))
+#define TP_IS_YTS_CHANNEL_FACTORY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TYPE_YTS_CHANNEL_FACTORY))
+#define TP_YTS_CHANNEL_FACTORY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TYPE_YTS_CHANNEL_FACTORY, \
+ TpYtsChannelFactoryClass))
+
+TpClientChannelFactory *tp_yts_channel_factory_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/telepathy-ytstenut-glib/channel.c b/telepathy-ytstenut-glib/channel.c
new file mode 100644
index 0000000..5e0fc42
--- /dev/null
+++ b/telepathy-ytstenut-glib/channel.c
@@ -0,0 +1,289 @@
+/*
+ * status.c - proxy for Ytstenut service status
+ *
+ * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include "channel.h"
+
+#include <telepathy-glib/defs.h>
+#include <telepathy-glib/gtypes.h>
+#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/proxy-subclass.h>
+#include <telepathy-glib/util.h>
+
+#include "_gen/interfaces.h"
+#include "_gen/cli-channel-body.h"
+
+#define DEBUG(msg, ...) \
+ g_debug ("%s: " msg, G_STRFUNC, ##__VA_ARGS__)
+
+/**
+ * SECTION:channel
+ * @title: TpYtsChannel
+ * @short_description: proxy object for Ytstenut message channel
+ *
+ * The #TpYtsChannel object is used to communicate with the Ytstenut
+ * Channel service.
+ */
+
+/**
+ * TpYtsChannel:
+ *
+ * The Ytstenut Channel holds information about a single Ytstenut request
+ * and reply. It should be created using the channel dispatcher, and the
+ * relevant properties.
+ */
+
+/**
+ * TpYtsChannelClass:
+ *
+ * The class of a #TpYtsChannel.
+ */
+
+G_DEFINE_TYPE (TpYtsChannel, tp_yts_channel, TP_TYPE_PROXY);
+
+static void
+tp_yts_channel_init (TpYtsChannel *self)
+{
+
+}
+
+static void
+tp_yts_channel_class_init (TpYtsChannelClass *klass)
+{
+ TpProxyClass *proxy_class = (TpProxyClass *) klass;
+ GType tp_type = TP_TYPE_YTS_CHANNEL;
+
+ proxy_class->interface = TP_YTS_IFACE_QUARK_CHANNEL;
+
+ tp_proxy_init_known_interfaces ();
+ tp_proxy_or_subclass_hook_on_interface_add (tp_type,
+ tp_yts_channel_add_signals);
+ tp_proxy_subclass_add_error_mapping (tp_type,
+ TP_ERROR_PREFIX, TP_ERRORS, TP_TYPE_ERROR);
+}
+
+TpChannel *
+tp_yts_channel_new_from_properties (TpConnection *conn,
+ const gchar *object_path,
+ GHashTable *immutable_properties,
+ GError **error)
+{
+ TpProxy *conn_proxy = TP_PROXY (conn);
+ TpChannel *ret = NULL;
+
+ g_return_val_if_fail (TP_IS_CONNECTION (conn), NULL);
+ g_return_val_if_fail (object_path != NULL, NULL);
+ g_return_val_if_fail (immutable_properties != NULL, NULL);
+
+ if (!tp_dbus_check_valid_object_path (object_path, error))
+ goto finally;
+
+ ret = TP_CHANNEL (g_object_new (TP_TYPE_CHANNEL,
+ "connection", conn,
+ "dbus-daemon", conn_proxy->dbus_daemon,
+ "bus-name", conn_proxy->bus_name,
+ "object-path", object_path,
+ "handle-type", (guint) TP_UNKNOWN_HANDLE_TYPE,
+ "channel-properties", immutable_properties,
+ NULL));
+
+finally:
+ return ret;
+}
+
+
+static void
+on_channel_request_returned (TpYtsChannel *self,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+
+ if (error != NULL)
+ {
+ DEBUG ("Channel.Request failed: %s", error->message);
+ g_simple_async_result_set_from_error (res, error);
+ }
+
+ g_simple_async_result_complete_in_idle (res);
+}
+
+void
+tp_yts_channel_request_async (TpYtsChannel *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+
+ g_return_if_fail (TP_IS_YTS_CHANNEL (self));
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ tp_yts_channel_request_async);
+
+ tp_yts_channel_call_request (self, -1, on_channel_request_returned, res,
+ g_object_unref, G_OBJECT (self));
+}
+
+gboolean
+tp_yts_channel_request_finish (TpYtsChannel *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *res;
+
+ g_return_val_if_fail (TP_IS_YTS_CHANNEL (self), FALSE);
+ g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
+
+ res = G_SIMPLE_ASYNC_RESULT (result);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result,
+ G_OBJECT (self), tp_yts_channel_request_async), FALSE);
+
+ if (g_simple_async_result_propagate_error (res, error))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+on_channel_reply_returned (TpYtsChannel *self,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+
+ if (error != NULL)
+ {
+ DEBUG ("Channel.Reply failed: %s", error->message);
+ g_simple_async_result_set_from_error (res, error);
+ }
+
+ g_simple_async_result_complete_in_idle (res);
+}
+
+void
+tp_yts_channel_reply_async (TpYtsChannel *self,
+ GHashTable *reply_attributes,
+ const gchar *reply_body,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+
+ g_return_if_fail (TP_IS_YTS_CHANNEL (self));
+ g_return_if_fail (reply_attributes);
+
+ if (!reply_body)
+ reply_body = "";
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ tp_yts_channel_reply_async);
+
+ tp_yts_channel_call_reply (self, -1, reply_attributes, reply_body,
+ on_channel_reply_returned, res, g_object_unref, G_OBJECT (self));
+}
+
+gboolean
+tp_yts_channel_reply_finish (TpYtsChannel *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *res;
+
+ g_return_val_if_fail (TP_IS_YTS_CHANNEL (self), FALSE);
+ g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
+
+ res = G_SIMPLE_ASYNC_RESULT (result);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result,
+ G_OBJECT (self), tp_yts_channel_reply_async), FALSE);
+
+ if (g_simple_async_result_propagate_error (res, error))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+on_channel_fail_returned (TpYtsChannel *self,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+
+ if (error != NULL)
+ {
+ DEBUG ("Channel.Fail failed: %s", error->message);
+ g_simple_async_result_set_from_error (res, error);
+ }
+
+ g_simple_async_result_complete_in_idle (res);
+}
+
+void
+tp_yts_channel_fail_async (TpYtsChannel *self,
+ TpYtsErrorType error_type,
+ const gchar *stanza_error_name,
+ const gchar *ytstenut_error_name,
+ const gchar *error_text,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+
+ g_return_if_fail (TP_IS_YTS_CHANNEL (self));
+ g_return_if_fail (stanza_error_name);
+ g_return_if_fail (ytstenut_error_name);
+ g_return_if_fail (error_text);
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ tp_yts_channel_fail_async);
+
+ tp_yts_channel_call_fail (self, -1, error_type, stanza_error_name,
+ ytstenut_error_name, error_text, on_channel_fail_returned,
+ res, g_object_unref, G_OBJECT (self));
+}
+
+gboolean
+tp_yts_channel_fail_finish (TpYtsChannel *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *res;
+
+ g_return_val_if_fail (TP_IS_YTS_CHANNEL (self), FALSE);
+ g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
+
+ res = G_SIMPLE_ASYNC_RESULT (result);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result,
+ G_OBJECT (self), tp_yts_channel_fail_async), FALSE);
+
+ if (g_simple_async_result_propagate_error (res, error))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/telepathy-ytstenut-glib/channel.h b/telepathy-ytstenut-glib/channel.h
new file mode 100644
index 0000000..4942f02
--- /dev/null
+++ b/telepathy-ytstenut-glib/channel.h
@@ -0,0 +1,94 @@
+/*
+ * channel - proxy for Ytstenut channel
+ *
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef TP_YTS_CHANNEL_H
+#define TP_YTS_CHANNEL_H
+
+#include "generated.h"
+
+#include <telepathy-glib/channel.h>
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/defs.h>
+#include <telepathy-glib/proxy.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TpYtsChannel TpYtsChannel;
+typedef struct _TpYtsChannelClass TpYtsChannelClass;
+typedef struct _TpYtsChannelPrivate TpYtsChannelPrivate;
+
+struct _TpYtsChannel {
+ /*<private>*/
+ TpChannel parent;
+ TpYtsChannelPrivate *priv;
+};
+
+struct _TpYtsChannelClass {
+ /*<private>*/
+ TpChannelClass parent_class;
+ GCallback _padding[7];
+};
+
+GType tp_yts_channel_get_type (void);
+
+#define TP_TYPE_YTS_CHANNEL (tp_yts_channel_get_type ())
+#define TP_YTS_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ TP_TYPE_YTS_CHANNEL, TpYtsChannel))
+#define TP_YTS_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ TP_TYPE_YTS_CHANNEL, TpYtsChannelClass))
+#define TP_IS_YTS_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ TP_TYPE_YTS_CHANNEL))
+#define TP_IS_YTS_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ TP_TYPE_YTS_CHANNEL))
+#define TP_YTS_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ TP_TYPE_YTS_CHANNEL, TpYtsChannelClass))
+
+TpChannel *tp_yts_channel_new_from_properties (TpConnection *conn,
+ const gchar *object_path, GHashTable *immutable_properties, GError **error);
+
+void tp_yts_channel_request_async (TpYtsChannel *self,
+ GCancellable *cancellable, GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean tp_yts_channel_request_finish (TpYtsChannel *self,
+ GAsyncResult *result, GError **error);
+
+void tp_yts_channel_reply_async (TpYtsChannel *self,
+ GHashTable *reply_attributes, const gchar *reply_body,
+ GCancellable *cancellable, GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean tp_yts_channel_reply_finish (TpYtsChannel *self,
+ GAsyncResult *result, GError **error);
+
+void tp_yts_channel_fail_async (TpYtsChannel *self,
+ TpYtsErrorType error_type, const gchar *stanza_error_name,
+ const gchar *ytstenut_error_name, const gchar *error_text,
+ GCancellable *cancellable, GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean tp_yts_channel_fail_finish (TpYtsChannel *self,
+ GAsyncResult *result, GError **error);
+
+G_END_DECLS
+
+#include <telepathy-ytstenut-glib/_gen/cli-channel.h>
+
+#endif
diff --git a/telepathy-ytstenut-glib/client.c b/telepathy-ytstenut-glib/client.c
new file mode 100644
index 0000000..27c4eb7
--- /dev/null
+++ b/telepathy-ytstenut-glib/client.c
@@ -0,0 +1,380 @@
+/*
+ * client.c - client side Ytstenut implementation
+ *
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include "client.h"
+#include "channel.h"
+#include "channel-factory.h"
+
+#include <telepathy-glib/account-channel-request.h>
+#include <telepathy-glib/contact.h>
+#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/gtypes.h>
+#include <telepathy-glib/util.h>
+
+#define DEBUG(msg, ...) \
+ g_debug ("%s: " msg, G_STRFUNC, ##__VA_ARGS__)
+
+enum {
+ PROP_0,
+ PROP_ACCOUNT,
+ PROP_SERVICE_NAME,
+};
+
+enum {
+ RECEIVED_CHANNELS,
+ LAST_SIGNAL,
+};
+
+G_DEFINE_TYPE (TpYtsClient, tp_yts_client, TP_TYPE_BASE_CLIENT);
+
+static gint signals[LAST_SIGNAL] = { 0, };
+
+struct _TpYtsClientPrivate {
+ gchar *service_name;
+ TpAccount *account;
+ TpClientChannelFactory *factory;
+ GQueue incoming_channels;
+};
+
+static void
+tp_yts_client_handle_channels (TpBaseClient *client,
+ TpAccount *account,
+ TpConnection *connection,
+ GList *channels,
+ GList *requests_satisfied,
+ gint64 user_action_time,
+ TpHandleChannelsContext *context)
+{
+ TpYtsClient *self = TP_YTS_CLIENT (client);
+ GList *l;
+
+ for (l = channels; l != NULL; l = g_list_next (l))
+ {
+ TpChannel *channel = l->data;
+
+ if (!TP_IS_YTS_CHANNEL (channel))
+ continue;
+
+ g_queue_push_tail (&self->priv->incoming_channels,
+ g_object_ref (channel));
+ }
+
+ tp_handle_channels_context_accept (context);
+ g_signal_emit (self, signals[RECEIVED_CHANNELS], 0);
+}
+
+static void
+tp_yts_client_init (TpYtsClient *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TP_TYPE_YTS_CLIENT,
+ TpYtsClientPrivate);
+
+ g_queue_init (&self->priv->incoming_channels);
+ self->priv->factory = tp_yts_channel_factory_new ();
+}
+
+static void
+tp_yts_client_constructed (GObject *obj)
+{
+ TpYtsClient *self = TP_YTS_CLIENT (obj);
+ TpBaseClient *client = TP_BASE_CLIENT (self);
+
+ /* chain up to TpBaseClient first */
+ G_OBJECT_CLASS (tp_yts_client_parent_class)->constructed (obj);
+
+ tp_base_client_set_channel_factory (client, self->priv->factory);
+
+ tp_base_client_set_handler_bypass_approval (client, FALSE);
+
+ /* Handle ServerTLSConnection and ServerAuthentication channels */
+ tp_base_client_take_handler_filter (client, tp_asv_new (
+ /* ChannelType */
+ TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_YTS_IFACE_CHANNEL,
+ /* TargetService */
+ TP_YTS_IFACE_CHANNEL ".TargetService", G_TYPE_STRING,
+ self->priv->service_name,
+ NULL));
+}
+
+static void
+tp_yts_client_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TpYtsClient *self = TP_YTS_CLIENT (object);
+
+ switch (property_id)
+ {
+ case PROP_SERVICE_NAME:
+ self->priv->service_name = g_value_dup_string (value);
+ break;
+ case PROP_ACCOUNT:
+ self->priv->account = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+tp_yts_client_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TpYtsClient *self = TP_YTS_CLIENT (object);
+
+ switch (property_id)
+ {
+ case PROP_SERVICE_NAME:
+ g_value_set_string (value, self->priv->service_name);
+ break;
+ case PROP_ACCOUNT:
+ g_value_set_object (value, self->priv->account);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+on_channel_close_returned (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ TpChannel *channel = TP_CHANNEL (user_data);
+ GError *error = NULL;
+
+ tp_channel_close_finish (channel, result, &error);
+ if (error != NULL)
+ {
+ DEBUG ("Channel.Close() failed: %s", error->message);
+ g_clear_error (&error);
+ }
+
+ g_object_unref (channel);
+}
+
+static void
+tp_yts_client_dispose (GObject *object)
+{
+ TpYtsClient *self = TP_YTS_CLIENT (object);
+ TpChannel *channel;
+
+ tp_clear_object (&self->priv->factory);
+
+ while (!g_queue_is_empty(&self->priv->incoming_channels))
+ {
+ channel = g_queue_pop_head (&self->priv->incoming_channels);
+ tp_channel_close_async (channel, on_channel_close_returned, channel);
+ }
+
+ G_OBJECT_CLASS (tp_yts_client_parent_class)->dispose(object);
+}
+
+
+static void
+tp_yts_client_finalize (GObject *object)
+{
+ TpYtsClient *self = TP_YTS_CLIENT (object);
+
+ g_free (self->priv->service_name);
+
+ G_OBJECT_CLASS (tp_yts_client_parent_class)->finalize(object);
+}
+
+static void
+tp_yts_client_class_init (TpYtsClientClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ TpBaseClientClass *base_class = TP_BASE_CLIENT_CLASS (klass);
+
+ object_class->constructed = tp_yts_client_constructed;
+ object_class->dispose = tp_yts_client_dispose;
+ object_class->finalize = tp_yts_client_finalize;
+ object_class->get_property = tp_yts_client_get_property;
+ object_class->set_property = tp_yts_client_set_property;
+
+ base_class->handle_channels = tp_yts_client_handle_channels;
+
+ g_type_class_add_private (klass, sizeof (TpYtsClientPrivate));
+
+ g_object_class_install_property (object_class, PROP_SERVICE_NAME,
+ g_param_spec_string ("service-name", "Service Name",
+ "Ytstenut Service Name", NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (object_class, PROP_ACCOUNT,
+ g_param_spec_string ("account", "Account", "Local Ytstenut Account", NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ signals[RECEIVED_CHANNELS] =
+ g_signal_new ("received-channels",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+}
+
+TpYtsClient *
+tp_yts_client_new (const gchar *service_name)
+{
+ TpYtsClient *out = NULL;
+ TpDBusDaemon *bus;
+ gchar *name;
+
+ g_return_val_if_fail (tp_dbus_check_valid_interface_name (service_name, NULL),
+ NULL);
+
+ name = g_strdup_printf ("Ytsenut.Client.%s", service_name);
+ bus = tp_dbus_daemon_dup (NULL);
+
+ out = g_object_new (TP_TYPE_YTS_CLIENT,
+ "dbus-daemon", bus,
+ "name", name,
+ "uniquify-name", TRUE,
+ NULL);
+
+ g_object_unref (bus);
+ g_free (name);
+
+ return out;
+}
+
+gboolean
+tp_yts_client_register (TpYtsClient *self,
+ GError **error)
+{
+ return tp_base_client_register (TP_BASE_CLIENT (self), error);
+}
+
+TpYtsChannel *
+tp_yts_client_accept_channel (TpYtsClient *self)
+{
+ g_return_val_if_fail (TP_IS_YTS_CHANNEL (self), NULL);
+ return g_queue_pop_head (&self->priv->incoming_channels);
+}
+
+static void
+on_channel_request_create_and_handle_channel_returned (GObject *source_object,
+ GAsyncResult *result, gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ TpChannel *channel;
+ GError *error = NULL;
+
+ channel = tp_account_channel_request_create_and_handle_channel_finish (
+ TP_ACCOUNT_CHANNEL_REQUEST (source_object), result, NULL, &error);
+ if (error == NULL)
+ {
+ g_simple_async_result_set_op_res_gpointer (res, channel, g_object_unref);
+ }
+ else
+ {
+ g_simple_async_result_set_from_error (res, error);
+ g_clear_error (&error);
+ }
+
+ g_simple_async_result_complete (res);
+}
+
+void
+tp_yts_client_request_channel_async (TpYtsClient *self,
+ TpContact *target_contact,
+ const gchar *target_service,
+ TpYtsRequestType request_type,
+ GHashTable *request_attributes,
+ const gchar *request_body,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ TpAccountChannelRequest *channel_request;
+ GSimpleAsyncResult *res;
+ GHashTable *request_properties;
+ TpHandle target_handle;
+
+ g_return_if_fail (TP_IS_YTS_CLIENT (self));
+ g_return_if_fail (TP_IS_CONTACT (target_contact));
+ g_return_if_fail (tp_dbus_check_valid_interface_name (target_service, NULL));
+
+ if (!request_body)
+ request_body = "";
+
+ g_return_if_fail (g_utf8_validate (request_body, -1, NULL));
+
+ target_handle = tp_contact_get_handle (target_contact);
+ g_return_if_fail (target_handle);
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ tp_yts_client_request_channel_async);
+
+ request_properties = tp_asv_new (
+ TP_IFACE_CHANNEL ".ChannelType", G_TYPE_STRING, TP_YTS_IFACE_CHANNEL,
+ TP_IFACE_CHANNEL ".TargetHandleType", G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
+ TP_IFACE_CHANNEL ".TargetHandle", G_TYPE_UINT, target_handle,
+ TP_YTS_IFACE_CHANNEL ".TargetService", G_TYPE_STRING, target_service,
+ TP_YTS_IFACE_CHANNEL ".InitiatorService", G_TYPE_STRING,
+ self->priv->service_name,
+ TP_YTS_IFACE_CHANNEL ".RequestType", G_TYPE_UINT, request_type,
+ TP_YTS_IFACE_CHANNEL ".RequestBody", G_TYPE_STRING, request_body,
+ NULL);
+
+ if (request_attributes)
+ tp_asv_set_boxed (request_properties,
+ TP_YTS_IFACE_CHANNEL ".RequestAttributes",
+ TP_HASH_TYPE_STRING_STRING_MAP, request_attributes);
+
+ channel_request = tp_account_channel_request_new (self->priv->account,
+ request_properties, 0);
+
+ tp_account_channel_request_set_channel_factory (channel_request,
+ self->priv->factory);
+
+ tp_account_channel_request_create_and_handle_channel_async (channel_request,
+ cancellable, on_channel_request_create_and_handle_channel_returned, res);
+
+ g_hash_table_unref (request_properties);
+}
+
+TpYtsChannel *
+tp_yts_client_request_channel_finish (TpYtsClient *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *res;
+
+ g_return_val_if_fail (TP_IS_YTS_CLIENT (self), NULL);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+ tp_yts_client_request_channel_async), NULL);
+
+ res = G_SIMPLE_ASYNC_RESULT (result);
+ if (g_simple_async_result_propagate_error (res, error))
+ return NULL;
+
+ return g_object_ref (g_simple_async_result_get_op_res_gpointer (res));
+}
diff --git a/telepathy-ytstenut-glib/client.h b/telepathy-ytstenut-glib/client.h
new file mode 100644
index 0000000..319a970
--- /dev/null
+++ b/telepathy-ytstenut-glib/client.h
@@ -0,0 +1,78 @@
+/*
+ * client - client side Ytstenut implementation
+ *
+ * Copyright (C) 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef TP_YTS_CLIENT_H
+#define TP_YTS_CLIENT_H
+
+#include "generated.h"
+#include "channel.h"
+
+#include <telepathy-glib/base-client.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TpYtsClient TpYtsClient;
+typedef struct _TpYtsClientClass TpYtsClientClass;
+typedef struct _TpYtsClientPrivate TpYtsClientPrivate;
+
+struct _TpYtsClient {
+ /*<private>*/
+ TpBaseClient parent;
+ TpYtsClientPrivate *priv;
+};
+
+struct _TpYtsClientClass {
+ /*<private>*/
+ TpBaseClientClass parent_class;
+ GCallback _padding[7];
+};
+
+GType tp_yts_client_get_type (void);
+
+#define TP_TYPE_YTS_CLIENT (tp_yts_client_get_type ())
+#define TP_YTS_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ TP_TYPE_YTS_CLIENT, TpYtsClient))
+#define TP_YTS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ TP_TYPE_YTS_CLIENT, TpYtsClientClass))
+#define TP_IS_YTS_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ TP_TYPE_YTS_CLIENT))
+#define TP_IS_YTS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ TP_TYPE_YTS_CLIENT))
+#define TP_YTS_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ TP_TYPE_YTS_CLIENT, TpYtsClientClass))
+
+TpYtsClient *tp_yts_client_new (const gchar *service_name);
+
+gboolean tp_yts_client_register (TpYtsClient *self, GError **error);
+
+TpYtsChannel *tp_yts_client_accept_channel (TpYtsClient *self);
+
+void tp_yts_client_request_channel_async (TpYtsClient *self,
+ TpContact *target_contact, const gchar *target_service,
+ TpYtsRequestType request_type, GHashTable *request_attributes,
+ const gchar *request_body, GCancellable *cancellable,
+ GAsyncReadyCallback callback, gpointer user_data);
+
+TpYtsChannel *tp_yts_client_request_channel_finish (TpYtsClient *self,
+ GAsyncResult *result, GError **error);
+
+G_END_DECLS
+
+#endif
diff --git a/telepathy-ytstenut-glib/generated.h b/telepathy-ytstenut-glib/generated.h
new file mode 100644
index 0000000..a227f26
--- /dev/null
+++ b/telepathy-ytstenut-glib/generated.h
@@ -0,0 +1,16 @@
+#ifndef TP_YTS_GENERATED_H
+#define TP_YTS_GENERATED_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#include "telepathy-ytstenut-glib/_gen/enums.h"
+#include "telepathy-ytstenut-glib/_gen/gtypes.h"
+#include "telepathy-ytstenut-glib/_gen/interfaces.h"
+#include "telepathy-ytstenut-glib/_gen/svc.h"
+
+G_END_DECLS
+
+#endif /* TP_YTS_GENERATED_H */
diff --git a/telepathy-ytstenut-glib/telepathy-ytstenut-glib.h b/telepathy-ytstenut-glib/telepathy-ytstenut-glib.h
index 334671f..7bac60a 100644
--- a/telepathy-ytstenut-glib/telepathy-ytstenut-glib.h
+++ b/telepathy-ytstenut-glib/telepathy-ytstenut-glib.h
@@ -1,22 +1,15 @@
-#ifndef TP_YTSTENUT_H
-#define TP_YTSTENUT_H
+#ifndef TP_YTSTENUT_GLIB_H
+#define TP_YTSTENUT_GLIB_H
#include <glib.h>
-#include <telepathy-glib/proxy-subclass.h>
-
-#include "telepathy-ytstenut-glib/_gen/enums.h"
-#include "telepathy-ytstenut-glib/_gen/svc.h"
-#include "telepathy-ytstenut-glib/errors.h"
+#include "telepathy-ytstenut-glib/generated.h"
#include "telepathy-ytstenut-glib/account-manager.h"
+#include "telepathy-ytstenut-glib/channel-factory.h"
+#include "telepathy-ytstenut-glib/channel.h"
+#include "telepathy-ytstenut-glib/client.h"
-G_BEGIN_DECLS
-
-#include "telepathy-ytstenut-glib/_gen/gtypes.h"
-#include "telepathy-ytstenut-glib/_gen/interfaces.h"
-
-G_END_DECLS
-#endif /* TP_YTSTENUT_H */
+#endif /* TP_YTSTENUT_GLIB_H */