summaryrefslogtreecommitdiff
path: root/examples/client
diff options
context:
space:
mode:
authorDanielle Madeley <danielle.madeley@collabora.co.uk>2010-07-21 16:45:41 +0100
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2010-09-28 10:15:20 +0200
commitfbcb3e1874a9f98b133f104ece684df2a3623f2e (patch)
treef01c91805d9eb3b28baa5aac3e295d2b43e9ac97 /examples/client
parent0c909e1711eebb9e0964cbf82c0c98ac005e2f11 (diff)
TpStreamTube + example
Diffstat (limited to 'examples/client')
-rw-r--r--examples/client/Makefile.am2
-rw-r--r--examples/client/stream-tubes/Makefile.am20
-rw-r--r--examples/client/stream-tubes/accepter.c155
-rw-r--r--examples/client/stream-tubes/offerer.c192
4 files changed, 369 insertions, 0 deletions
diff --git a/examples/client/Makefile.am b/examples/client/Makefile.am
index b81266d2b..d736caa1f 100644
--- a/examples/client/Makefile.am
+++ b/examples/client/Makefile.am
@@ -1,3 +1,5 @@
+SUBDIRS = stream-tubes
+
EXAMPLES =
EXAMPLES += telepathy-example-inspect-channel
diff --git a/examples/client/stream-tubes/Makefile.am b/examples/client/stream-tubes/Makefile.am
new file mode 100644
index 000000000..eaecbe4ce
--- /dev/null
+++ b/examples/client/stream-tubes/Makefile.am
@@ -0,0 +1,20 @@
+noinst_PROGRAMS = \
+ offerer \
+ accepter \
+ $(NULL)
+
+offerer_SOURCES = offerer.c
+accepter_SOURCES = accepter.c
+
+# In an external project you'd use $(TP_GLIB_LIBS) (obtained from
+# pkg-config via autoconf) instead of the .la path
+LDADD = \
+ @DBUS_LIBS@ \
+ @GLIB_LIBS@ \
+ $(top_builddir)/telepathy-glib/libtelepathy-glib.la
+
+AM_CFLAGS = \
+ $(ERROR_CFLAGS) \
+ @DBUS_CFLAGS@ \
+ @GLIB_CFLAGS@ \
+ @TP_GLIB_CFLAGS@
diff --git a/examples/client/stream-tubes/accepter.c b/examples/client/stream-tubes/accepter.c
new file mode 100644
index 000000000..0ca3f6344
--- /dev/null
+++ b/examples/client/stream-tubes/accepter.c
@@ -0,0 +1,155 @@
+#include <telepathy-glib/telepathy-glib.h>
+
+static GMainLoop *loop = NULL;
+
+
+static void
+_tube_accepted (GObject *tube,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ TpHandleChannelsContext *context = user_data;
+ GIOStream *iostream;
+ GInputStream *in;
+ GOutputStream *out;
+ char buf[128] = { 0, };
+ GError *error = NULL;
+
+ iostream = tp_stream_tube_accept_finish (TP_STREAM_TUBE (tube), res, &error);
+
+ if (error != NULL)
+ {
+ tp_handle_channels_context_fail (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ tp_handle_channels_context_accept (context);
+ g_object_unref (context);
+
+ g_debug ("Tube open, have IOStream");
+
+ in = g_io_stream_get_input_stream (iostream);
+ out = g_io_stream_get_output_stream (iostream);
+
+ /* this bit is not a good example */
+ g_output_stream_write (out, "Ping", 4, NULL, &error);
+ g_assert_no_error (error);
+
+ g_input_stream_read (in, &buf, sizeof (buf), NULL, &error);
+ g_assert_no_error (error);
+
+ g_debug ("Sent Ping got: %s", buf);
+
+ // FIXME: close the channel
+
+ g_object_unref (iostream);
+ g_object_unref (tube);
+
+ g_main_loop_quit (loop);
+}
+
+
+static void
+_handle_channels (TpSimpleHandler *handler,
+ TpAccount *account,
+ TpConnection *conn,
+ GList *channels,
+ GList *requests,
+ gint64 action_time,
+ TpHandleChannelsContext *context,
+ gpointer user_data)
+{
+ TpStreamTube *tube;
+ gboolean delay = FALSE;
+ GList *l;
+
+ g_debug ("Handling channels");
+
+ for (l = channels; l != NULL; l = l->next)
+ {
+ TpChannel *channel = l->data;
+ GHashTable *props = tp_channel_borrow_immutable_properties (channel);
+
+ if (tp_channel_get_channel_type_id (channel) !=
+ TP_IFACE_QUARK_CHANNEL_TYPE_STREAM_TUBE)
+ continue;
+
+ if (tp_strdiff (
+ tp_asv_get_string (props, TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE),
+ "ExampleService"))
+ continue;
+
+ g_debug ("Accepting tube");
+
+ /* the TpStreamTube holds the only ref to @channel */
+ tube = tp_stream_tube_new (channel);
+ tp_stream_tube_accept_async (tube, _tube_accepted, context);
+
+ delay = TRUE;
+ }
+
+ if (delay)
+ {
+ g_debug ("Delaying channel acceptance");
+
+ tp_handle_channels_context_delay (context);
+ g_object_ref (context);
+ }
+ else
+ {
+ GError *error;
+
+ g_debug ("Rejecting channels");
+
+ error = g_error_new (TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
+ "No channels to be handled");
+ tp_handle_channels_context_fail (context, error);
+
+ g_error_free (error);
+ }
+}
+
+
+int
+main (int argc,
+ const char **argv)
+{
+ TpDBusDaemon *dbus;
+ TpBaseClient *handler;
+ GError *error = NULL;
+
+ g_type_init ();
+
+ dbus = tp_dbus_daemon_dup (&error);
+ g_assert_no_error (error);
+
+ handler = tp_simple_handler_new (dbus, FALSE, FALSE, "ExampleServiceHandler",
+ FALSE, _handle_channels, NULL, NULL);
+
+ tp_base_client_take_handler_filter (handler, tp_asv_new (
+ TP_PROP_CHANNEL_CHANNEL_TYPE,
+ G_TYPE_STRING,
+ TP_IFACE_CHANNEL_TYPE_STREAM_TUBE,
+
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
+ G_TYPE_UINT,
+ TP_HANDLE_TYPE_CONTACT,
+
+ TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE,
+ G_TYPE_STRING,
+ "ExampleService",
+
+ NULL));
+
+ tp_base_client_register (handler, &error);
+ g_assert_no_error (error);
+
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+
+ g_main_loop_unref (loop);
+ g_object_unref (handler);
+
+ return 0;
+}
diff --git a/examples/client/stream-tubes/offerer.c b/examples/client/stream-tubes/offerer.c
new file mode 100644
index 000000000..a9724c2cb
--- /dev/null
+++ b/examples/client/stream-tubes/offerer.c
@@ -0,0 +1,192 @@
+#include <telepathy-glib/telepathy-glib.h>
+
+static GMainLoop *loop = NULL;
+
+
+static void
+_incoming_iostream (TpStreamTube *tube,
+ TpContact *contact,
+ GIOStream *iostream,
+ gpointer user_data)
+{
+ GInputStream *in;
+ GOutputStream *out;
+ char buf[128] = { 0, };
+ GError *error = NULL;
+
+ g_debug ("Got IOStream from %s",
+ tp_contact_get_identifier (contact));
+
+ in = g_io_stream_get_input_stream (iostream);
+ out = g_io_stream_get_output_stream (iostream);
+
+ /* this bit is not a good example */
+ g_output_stream_write (out, "Pong", 4, NULL, &error);
+ g_assert_no_error (error);
+
+ g_input_stream_read (in, &buf, sizeof (buf), NULL, &error);
+ g_assert_no_error (error);
+
+ g_debug ("Send Pong got: %s", buf);
+
+ // FIXME: close the channel
+
+ g_object_unref (tube);
+
+ g_main_loop_quit (loop);
+}
+
+
+static void
+_tube_offered (GObject *tube,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+
+ tp_stream_tube_offer_finish (TP_STREAM_TUBE (tube), res, &error);
+ g_assert_no_error (error);
+
+ g_debug ("Tube offered");
+}
+
+
+static void
+_channel_prepared (GObject *channel,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ TpStreamTube *tube;
+ GError *error = NULL;
+
+ tp_proxy_prepare_finish (channel, res, &error);
+ g_assert_no_error (error);
+
+ g_debug ("Channel prepared");
+
+ tube = tp_stream_tube_new (TP_CHANNEL (channel));
+ /* the TpStreamTube holds the only reference to @channel */
+ g_object_unref (channel);
+
+ g_signal_connect (tube, "incoming",
+ G_CALLBACK (_incoming_iostream), NULL);
+
+ tp_stream_tube_offer_async (tube, _tube_offered, NULL);
+}
+
+
+static void
+_channel_created (TpConnection *conn,
+ const gchar *channel_path,
+ GHashTable *props,
+ const GError *in_error,
+ gpointer user_data,
+ GObject *weak_obj)
+{
+ TpChannel *channel;
+ GError *error = NULL;
+
+ g_assert_no_error ((GError *) in_error);
+
+ g_debug ("Channel created: %s", channel_path);
+
+ channel = tp_channel_new_from_properties (conn, channel_path, props,
+ &error);
+ g_assert_no_error (error);
+
+ tp_proxy_prepare_async (channel, NULL, _channel_prepared, NULL);
+}
+
+
+static void
+_connection_prepared (GObject *conn,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GHashTable *request;
+ GError *error = NULL;
+
+ tp_proxy_prepare_finish (conn, res, &error);
+ g_assert_no_error (error);
+
+ g_debug ("Connection prepared");
+ g_debug ("Requesting channel");
+
+ request = tp_asv_new (
+ TP_PROP_CHANNEL_CHANNEL_TYPE,
+ G_TYPE_STRING,
+ TP_IFACE_CHANNEL_TYPE_STREAM_TUBE,
+
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
+ G_TYPE_UINT,
+ TP_HANDLE_TYPE_CONTACT,
+
+ TP_PROP_CHANNEL_TARGET_ID,
+ G_TYPE_STRING,
+ user_data,
+
+ TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE,
+ G_TYPE_STRING,
+ "ExampleService",
+
+ NULL);
+
+ tp_cli_connection_interface_requests_call_create_channel (
+ TP_CONNECTION (conn), -1,
+ request,
+ _channel_created,
+ NULL, NULL, NULL);
+
+ g_hash_table_destroy (request);
+}
+
+
+static void
+_account_prepared (GObject *account,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+
+ tp_proxy_prepare_finish (account, res, &error);
+ g_assert_no_error (error);
+
+ g_debug ("Account prepared");
+
+ tp_proxy_prepare_async (tp_account_get_connection (TP_ACCOUNT (account)),
+ NULL, _connection_prepared, user_data);
+}
+
+
+int
+main (int argc,
+ const char **argv)
+{
+ TpDBusDaemon *dbus;
+ TpAccount *account;
+ char *account_path;
+ GError *error = NULL;
+
+ g_assert (argc == 3);
+
+ g_type_init ();
+
+ dbus = tp_dbus_daemon_dup (&error);
+ g_assert_no_error (error);
+
+ account_path = g_strconcat (TP_ACCOUNT_OBJECT_PATH_BASE, argv[1], NULL);
+ account = tp_account_new (dbus, account_path, &error);
+ g_assert_no_error (error);
+ g_free (account_path);
+
+ tp_proxy_prepare_async (account, NULL, _account_prepared,
+ (gpointer) argv[2]);
+
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+
+ g_object_unref (account);
+ g_main_loop_unref (loop);
+
+ return 0;
+}