diff options
author | Danielle Madeley <danielle.madeley@collabora.co.uk> | 2010-07-21 16:45:41 +0100 |
---|---|---|
committer | Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> | 2010-09-28 10:15:20 +0200 |
commit | fbcb3e1874a9f98b133f104ece684df2a3623f2e (patch) | |
tree | f01c91805d9eb3b28baa5aac3e295d2b43e9ac97 /examples/client | |
parent | 0c909e1711eebb9e0964cbf82c0c98ac005e2f11 (diff) |
TpStreamTube + example
Diffstat (limited to 'examples/client')
-rw-r--r-- | examples/client/Makefile.am | 2 | ||||
-rw-r--r-- | examples/client/stream-tubes/Makefile.am | 20 | ||||
-rw-r--r-- | examples/client/stream-tubes/accepter.c | 155 | ||||
-rw-r--r-- | examples/client/stream-tubes/offerer.c | 192 |
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; +} |