[telepathy-doc/master] A GNIO based receiver example
Davyd Madeley
davyd at madeley.id.au
Tue Apr 7 22:01:17 PDT 2009
---
configure.ac | 2 +-
docs/examples/glib_salut_ft/Makefile.am | 10 +-
docs/examples/glib_salut_ft/gnio-receiver.c | 180 ++++++++++++++------------
3 files changed, 103 insertions(+), 89 deletions(-)
diff --git a/configure.ac b/configure.ac
index 4f1c711..5dec4d9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14,7 +14,7 @@ PKG_CHECK_MODULES(TELEPATHY_GLIB, telepathy-glib >= 0.7.3 gtk+-2.0 >= 2.12.0)
AC_SUBST(TELEPATHY_GLIB_CFLAGS)
AC_SUBST(TELEPATHY_GLIB_LIBS)
-PKG_CHECK_MODULES(GNIO, gnio, HAVE_GNIO=yes, HAVE_GNIO=no)
+PKG_CHECK_MODULES(GNIO, gnio gio-unix-2.0, HAVE_GNIO=yes, HAVE_GNIO=no)
AC_SUBST(GNIO_CFLAGS)
AC_SUBST(GNIO_LIBS)
AM_CONDITIONAL(HAVE_GNIO, test "x$HAVE_GNIO" = "xyes")
diff --git a/docs/examples/glib_salut_ft/Makefile.am b/docs/examples/glib_salut_ft/Makefile.am
index 7efd48b..617e0cc 100644
--- a/docs/examples/glib_salut_ft/Makefile.am
+++ b/docs/examples/glib_salut_ft/Makefile.am
@@ -15,13 +15,13 @@ if HAVE_GNIO
noinst_PROGRAMS += \
gnio-receiver
-gnio_receiver_INCLUDES = \
- $(TELEPATHY_GLIB_CFLAGS) \
- $(GNIO_CFLAGS)
+gnio_receiver_CFLAGS = \
+ $(GNIO_CFLAGS) \
+ $(TELEPATHY_GLIB_CFLAGS)
gnio_receiver_LDADD = \
- $(TELEPATHY_GLIB_LIBS) \
- $(GNIO_LIBS)
+ $(GNIO_LIBS) \
+ $(TELEPATHY_GLIB_LIBS)
gnio_receiver_SOURCES = \
gnio-receiver.c
diff --git a/docs/examples/glib_salut_ft/gnio-receiver.c b/docs/examples/glib_salut_ft/gnio-receiver.c
index 5d558cf..7e5d424 100644
--- a/docs/examples/glib_salut_ft/gnio-receiver.c
+++ b/docs/examples/glib_salut_ft/gnio-receiver.c
@@ -1,12 +1,10 @@
#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <errno.h>
-#include <string.h>
#include <glib.h>
#include <glib-object.h>
+#include <gio/gio.h>
+#include <gio/gunixoutputstream.h>
+#include <gio/gnio.h>
#include <telepathy-glib/connection-manager.h>
#include <telepathy-glib/connection.h>
@@ -25,10 +23,12 @@ static TpConnection *conn = NULL;
struct ft_state
{
- GIOChannel *channel;
- guint64 offset;
+ GSocketClient *client;
+ GSocketConnection *connection;
+ GSocketAddress *address;
- struct sockaddr_un sa;
+ GOutputStream *output;
+ guint64 offset;
};
static void
@@ -43,50 +43,49 @@ handle_error (const GError *error)
}
static void
-file_transfer_unix_cb (TpChannel *channel,
- const GValue *addressv,
- const GError *in_error,
- gpointer user_data,
- GObject *weak_obj)
+accept_file_cb (TpChannel *channel,
+ const GValue *addressv,
+ const GError *in_error,
+ gpointer user_data,
+ GObject *weak_obj)
{
- struct ft_state *state = (struct ft_state *) user_data;
-
- handle_error (in_error);
-
- const char *address = g_value_get_string (addressv);
- strncpy (state->sa.sun_path, address, UNIX_PATH_MAX);
-
- g_print (" > file_transfer_unix_cb (%s)\n", address);
-}
-
-static gboolean
-file_transfer_data_received (GIOChannel *channel,
- GIOCondition condition,
- gpointer data)
-{
- char buf[1024];
- gsize bytes_read;
+ struct ft_state *ftstate = (struct ft_state *) user_data;
GError *error = NULL;
- if (condition & G_IO_HUP) return FALSE; /* this channel is done */
-
- g_io_channel_read_chars (channel, buf, sizeof (buf), &bytes_read,
- &error);
- handle_error (error);
+ handle_error (in_error);
- buf[bytes_read] = '\0';
- g_print ("%s", buf);
+ if (G_IS_UNIX_CLIENT (ftstate->client))
+ {
+ const char *address = g_value_get_string (addressv);
+ g_print (" > file_transfer_cb (unix:%s)\n", address);
- return TRUE;
+ ftstate->address = G_SOCKET_ADDRESS (
+ g_unix_socket_address_new (address));
+ }
+ else if (G_IS_TCP_CLIENT (ftstate->client))
+ {
+ GValueArray *address = g_value_get_boxed (addressv);
+ const char *host = g_value_get_string (
+ g_value_array_get_nth (address, 0));
+ guint port = g_value_get_uint (
+ g_value_array_get_nth (address, 1));
+ g_print (" > file_transfer_cb (tcp:%s:%i)\n", host, port);
+
+ /* RYAN!
+ ftstate->address = G_SOCKET_ADDRESS (
+ g_tcp_client_get_connectable (host, port, &error));
+ handle_error (error);
+ */
+ }
}
static void
-file_transfer_unix_state_changed_cb (TpChannel *channel,
- guint state,
- guint reason,
- gpointer user_data,
- GObject *weak_obj)
+file_transfer_state_changed_cb (TpChannel *channel,
+ guint state,
+ guint reason,
+ gpointer user_data,
+ GObject *weak_obj)
{
struct ft_state *ftstate = (struct ft_state *) user_data;
GError *error = NULL;
@@ -95,36 +94,48 @@ file_transfer_unix_state_changed_cb (TpChannel *channel,
if (state == TP_FILE_TRANSFER_STATE_OPEN)
{
- int sock = socket (ftstate->sa.sun_family, SOCK_STREAM, 0);
- if (sock == -1)
+ if (G_IS_UNIX_CLIENT (ftstate->client))
{
- int e = errno;
- g_error ("UNABLE TO GET SOCKET: %s", strerror (e));
+ ftstate->connection = G_SOCKET_CONNECTION (
+ g_unix_client_connect (
+ G_UNIX_CLIENT (ftstate->client),
+ G_SOCKET_CONNECTABLE (ftstate->address),
+ NULL, &error));
}
-
- if (connect (sock, (struct sockaddr *) &ftstate->sa,
- sizeof (struct sockaddr_un)))
+ else if (G_IS_TCP_CLIENT (ftstate->client))
{
- int e = errno;
- g_error ("UNABLE TO CONNECT: %s", strerror (e));
+ ftstate->connection = G_SOCKET_CONNECTION (
+ g_tcp_client_connect (
+ G_TCP_CLIENT (ftstate->client),
+ G_SOCKET_CONNECTABLE (ftstate->address),
+ NULL, &error));
}
+ handle_error (error);
- /* turn the socket into an IOChannel, so that we can work
- * with our main loop */
- ftstate->channel = g_io_channel_unix_new (sock);
- g_io_add_watch (ftstate->channel, G_IO_IN | G_IO_HUP,
- file_transfer_data_received,
- ftstate);
+ /* we can now use the stream like any other GIO stream.
+ * Open an output stream for writing to */
+ GInputStream *input = g_io_stream_get_input_stream (
+ G_IO_STREAM (ftstate->connection));
+ ftstate->output = g_unix_output_stream_new (STDOUT_FILENO,
+ FALSE);
+ /* splice the input stream into the output stream and GIO
+ * takes care of the rest */
+ g_output_stream_splice (ftstate->output, input,
+ G_OUTPUT_STREAM_SPLICE_NONE,
+ NULL, &error);
+ handle_error (error);
}
else if (state == TP_FILE_TRANSFER_STATE_COMPLETED ||
state == TP_FILE_TRANSFER_STATE_CANCELLED)
{
- g_print ("\n--------------EOF--------------\n");
/* close the socket */
- g_io_channel_shutdown (ftstate->channel, TRUE, &error);
- handle_error (error);
- /* release our resources */
- g_io_channel_unref (ftstate->channel);
+ g_socket_connection_close (ftstate->connection);
+
+ /* free the resources */
+ g_object_unref (ftstate->output);
+ g_object_unref (ftstate->connection);
+ g_object_unref (ftstate->address);
+ g_object_unref (ftstate->client);
g_slice_free (struct ft_state, ftstate);
tp_cli_channel_call_close (channel, -1, NULL, NULL, NULL, NULL);
}
@@ -140,7 +151,6 @@ file_transfer_channel_ready (TpChannel *channel,
handle_error (in_error);
GHashTable *map = tp_channel_borrow_immutable_properties (channel);
- tp_asv_dump (map);
const char *filename = tp_asv_get_string (map,
TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER ".Filename");
@@ -158,35 +168,39 @@ file_transfer_channel_ready (TpChannel *channel,
TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER ".AvailableSocketTypes",
TP_HASH_TYPE_SUPPORTED_SOCKET_MAP);
+ struct ft_state *ftstate = g_slice_new (struct ft_state);
+ guint socket_type, access_control;
+
/* let's try for IPv4 */
if (g_hash_table_lookup (sockets,
GINT_TO_POINTER (TP_SOCKET_ADDRESS_TYPE_IPV4)))
{
- g_print ("ipv4 supported\n");
+ socket_type = TP_SOCKET_ADDRESS_TYPE_IPV4;
+ access_control = TP_SOCKET_ACCESS_CONTROL_LOCALHOST;
+ ftstate->client = G_SOCKET_CLIENT (g_tcp_client_new ());
}
else if (g_hash_table_lookup (sockets,
GINT_TO_POINTER (TP_SOCKET_ADDRESS_TYPE_UNIX)))
{
- struct ft_state *state = g_slice_new (struct ft_state);
- state->sa.sun_family = AF_UNIX;
-
- tp_cli_channel_type_file_transfer_connect_to_file_transfer_state_changed (
- channel, file_transfer_unix_state_changed_cb,
- state, NULL, NULL, &error);
- handle_error (error);
-
- GValue *value = tp_g_value_slice_new_static_string ("");
+ socket_type = TP_SOCKET_ADDRESS_TYPE_UNIX;
+ access_control = TP_SOCKET_ACCESS_CONTROL_LOCALHOST;
+ ftstate->client = G_SOCKET_CLIENT (g_unix_client_new ());
+ }
- /* let us accept the file */
- tp_cli_channel_type_file_transfer_call_accept_file (channel,
- -1, TP_SOCKET_ADDRESS_TYPE_UNIX,
- TP_SOCKET_ACCESS_CONTROL_LOCALHOST,
- value, 0,
- file_transfer_unix_cb,
- state, NULL, NULL);
+ tp_cli_channel_type_file_transfer_connect_to_file_transfer_state_changed (
+ channel, file_transfer_state_changed_cb,
+ ftstate, NULL, NULL, &error);
+ handle_error (error);
- tp_g_value_slice_free (value);
- }
+ /* let us accept the file */
+ GValue *value = tp_g_value_slice_new_static_string ("");
+ tp_cli_channel_type_file_transfer_call_accept_file (channel,
+ -1, TP_SOCKET_ADDRESS_TYPE_UNIX,
+ TP_SOCKET_ACCESS_CONTROL_LOCALHOST,
+ value, 0,
+ accept_file_cb,
+ ftstate, NULL, NULL);
+ tp_g_value_slice_free (value);
}
static void
--
1.5.6.5
More information about the telepathy-commits
mailing list