diff options
author | Stef Walter <stefw@collaora.co.uk> | 2011-03-24 16:39:25 +0100 |
---|---|---|
committer | Stef Walter <stefw@collaora.co.uk> | 2011-03-30 12:27:05 +0200 |
commit | 663c28e67bfe366674eea794daae7b42d2f0e772 (patch) | |
tree | c3b914c2bc0e9755e0683329ca3bffa2daeffb63 | |
parent | d0a7d32072858cb2ceb76716201a97caeb5565ca (diff) |
Complete basic implementation of TpYtsChannel
Including TpYtsClient, and TpYtsChannelFactory
-rw-r--r-- | telepathy-ytstenut-glib/Makefile.am | 24 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/channel-factory.c | 95 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/channel-factory.h | 63 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/channel.c | 289 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/channel.h | 94 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/client.c | 380 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/client.h | 78 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/generated.h | 16 | ||||
-rw-r--r-- | telepathy-ytstenut-glib/telepathy-ytstenut-glib.h | 21 |
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 */ |