mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
rfbsrc: Port to GSocketClient
Using GSocketClient we can simplify a lot the read/write operation. This also provide an GSocketConnection (a GIOStream) which can then be used with the GTlsClientConnection for secure connections. Note that we use _write_all() to ensure all bytes have been read. This is to follow the fact the none of the _send() calls check the return value.
This commit is contained in:
parent
4e0a5c101f
commit
21b322c8f3
4 changed files with 49 additions and 100 deletions
|
@ -5,10 +5,18 @@ plugin_LTLIBRARIES = libgstrfbsrc.la
|
||||||
libgstrfbsrc_la_SOURCES = gstrfbsrc.c \
|
libgstrfbsrc_la_SOURCES = gstrfbsrc.c \
|
||||||
rfbdecoder.c \
|
rfbdecoder.c \
|
||||||
d3des.c
|
d3des.c
|
||||||
libgstrfbsrc_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(X11_CFLAGS) -I$(srcdir)/..
|
libgstrfbsrc_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \
|
||||||
libgstrfbsrc_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_API_VERSION) \
|
$(GST_BASE_CFLAGS) \
|
||||||
$(GST_BASE_LIBS) $(GST_LIBS) $(X11_LIBS)
|
$(GST_CFLAGS) \
|
||||||
libgstrfbsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
$(X11_CFLAGS) \
|
||||||
|
$(GIO_CFLAGS)
|
||||||
|
libgstrfbsrc_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
|
||||||
|
-lgstvideo-$(GST_API_VERSION) \
|
||||||
|
$(GST_BASE_LIBS) \
|
||||||
|
$(GST_LIBS) \
|
||||||
|
$(X11_LIBS) \
|
||||||
|
$(GIO_LIBS)
|
||||||
|
libgstrfbsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(GIO_LDFLAGS)
|
||||||
libgstrfbsrc_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
|
libgstrfbsrc_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
|
|
|
@ -516,9 +516,9 @@ gst_rfb_src_stop (GstBaseSrc * bsrc)
|
||||||
{
|
{
|
||||||
GstRfbSrc *src = GST_RFB_SRC (bsrc);
|
GstRfbSrc *src = GST_RFB_SRC (bsrc);
|
||||||
|
|
||||||
if (src->decoder->socket) {
|
if (src->decoder->connection) {
|
||||||
g_object_unref (src->decoder->socket);
|
g_object_unref (src->decoder->connection);
|
||||||
src->decoder->socket = NULL;
|
src->decoder->connection = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src->decoder->frame) {
|
if (src->decoder->frame) {
|
||||||
|
|
|
@ -51,7 +51,8 @@ rfb_decoder_new (void)
|
||||||
{
|
{
|
||||||
RfbDecoder *decoder = g_new0 (RfbDecoder, 1);
|
RfbDecoder *decoder = g_new0 (RfbDecoder, 1);
|
||||||
|
|
||||||
decoder->socket = NULL;
|
decoder->socket_client = g_socket_client_new ();
|
||||||
|
decoder->connection = NULL;
|
||||||
decoder->cancellable = g_cancellable_new ();
|
decoder->cancellable = g_cancellable_new ();
|
||||||
|
|
||||||
decoder->password = NULL;
|
decoder->password = NULL;
|
||||||
|
@ -82,15 +83,10 @@ rfb_decoder_free (RfbDecoder * decoder)
|
||||||
decoder->cancellable = NULL;
|
decoder->cancellable = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decoder->socket) {
|
g_clear_object (&decoder->connection);
|
||||||
g_object_unref (decoder->socket);
|
g_clear_object (&decoder->socket_client);
|
||||||
decoder->socket = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_clear_error (&decoder->error);
|
g_clear_error (&decoder->error);
|
||||||
|
|
||||||
g_free (decoder->data);
|
g_free (decoder->data);
|
||||||
|
|
||||||
g_free (decoder);
|
g_free (decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,78 +94,26 @@ gboolean
|
||||||
rfb_decoder_connect_tcp (RfbDecoder * decoder, gchar * host, guint port)
|
rfb_decoder_connect_tcp (RfbDecoder * decoder, gchar * host, guint port)
|
||||||
{
|
{
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
GInetAddress *addr;
|
GSocketConnection *connection;
|
||||||
GSocketAddress *saddr;
|
|
||||||
GResolver *resolver;
|
|
||||||
|
|
||||||
GST_DEBUG ("connecting to the rfb server");
|
GST_DEBUG ("connecting to the rfb server");
|
||||||
|
|
||||||
g_return_val_if_fail (decoder != NULL, FALSE);
|
g_return_val_if_fail (decoder != NULL, FALSE);
|
||||||
g_return_val_if_fail (decoder->socket == NULL, FALSE);
|
g_return_val_if_fail (decoder->connection == NULL, FALSE);
|
||||||
g_return_val_if_fail (host != NULL, FALSE);
|
g_return_val_if_fail (host != NULL, FALSE);
|
||||||
|
|
||||||
/* look up name if we need to */
|
connection =
|
||||||
addr = g_inet_address_new_from_string (host);
|
g_socket_client_connect_to_host (decoder->socket_client, host, port,
|
||||||
if (!addr) {
|
decoder->cancellable, &err);
|
||||||
GList *results;
|
|
||||||
|
|
||||||
resolver = g_resolver_get_default ();
|
if (!connection)
|
||||||
|
|
||||||
results =
|
|
||||||
g_resolver_lookup_by_name (resolver, host, decoder->cancellable, &err);
|
|
||||||
if (!results)
|
|
||||||
goto name_resolve;
|
|
||||||
addr = G_INET_ADDRESS (g_object_ref (results->data));
|
|
||||||
|
|
||||||
g_resolver_free_addresses (results);
|
|
||||||
g_object_unref (resolver);
|
|
||||||
}
|
|
||||||
|
|
||||||
saddr = g_inet_socket_address_new (addr, port);
|
|
||||||
|
|
||||||
decoder->socket =
|
|
||||||
g_socket_new (g_socket_address_get_family (saddr), G_SOCKET_TYPE_STREAM,
|
|
||||||
G_SOCKET_PROTOCOL_TCP, &err);
|
|
||||||
|
|
||||||
if (!decoder->socket)
|
|
||||||
goto no_socket;
|
|
||||||
|
|
||||||
GST_DEBUG ("opened receiving client socket");
|
|
||||||
|
|
||||||
if (!g_socket_connect (decoder->socket, saddr, decoder->cancellable, &err))
|
|
||||||
goto connect_failed;
|
goto connect_failed;
|
||||||
|
|
||||||
g_object_unref (saddr);
|
decoder->connection = connection;
|
||||||
|
|
||||||
decoder->disconnected = FALSE;
|
decoder->disconnected = FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
no_socket:
|
|
||||||
{
|
|
||||||
GST_WARNING ("Failed to create socket: %s", err->message);
|
|
||||||
if (decoder->error == NULL)
|
|
||||||
decoder->error = err;
|
|
||||||
else
|
|
||||||
g_clear_error (&err);
|
|
||||||
g_object_unref (saddr);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
name_resolve:
|
|
||||||
{
|
|
||||||
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
|
||||||
GST_DEBUG ("Cancelled name resolval");
|
|
||||||
} else {
|
|
||||||
GST_WARNING ("Failed to resolve host '%s': %s", host, err->message);
|
|
||||||
if (decoder->error == NULL) {
|
|
||||||
decoder->error = err;
|
|
||||||
err = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_clear_error (&err);
|
|
||||||
g_object_unref (resolver);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
connect_failed:
|
connect_failed:
|
||||||
{
|
{
|
||||||
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
||||||
|
@ -183,7 +127,6 @@ connect_failed:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_clear_error (&err);
|
g_clear_error (&err);
|
||||||
g_object_unref (saddr);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,7 +145,7 @@ rfb_decoder_iterate (RfbDecoder * decoder)
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
|
||||||
g_return_val_if_fail (decoder != NULL, FALSE);
|
g_return_val_if_fail (decoder != NULL, FALSE);
|
||||||
g_return_val_if_fail (decoder->socket != NULL, FALSE);
|
g_return_val_if_fail (decoder->connection != NULL, FALSE);
|
||||||
|
|
||||||
if (decoder->state == NULL) {
|
if (decoder->state == NULL) {
|
||||||
GST_DEBUG ("First iteration: set state to -> wait for protocol version");
|
GST_DEBUG ("First iteration: set state to -> wait for protocol version");
|
||||||
|
@ -225,28 +168,26 @@ rfb_decoder_iterate (RfbDecoder * decoder)
|
||||||
static guint8 *
|
static guint8 *
|
||||||
rfb_decoder_read (RfbDecoder * decoder, guint32 len)
|
rfb_decoder_read (RfbDecoder * decoder, guint32 len)
|
||||||
{
|
{
|
||||||
guint32 total = 0;
|
GInputStream *in;
|
||||||
gssize now = 0;
|
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (decoder->socket != NULL, NULL);
|
g_return_val_if_fail (decoder->connection != NULL, NULL);
|
||||||
g_return_val_if_fail (len > 0, NULL);
|
g_return_val_if_fail (len > 0, NULL);
|
||||||
|
|
||||||
|
in = g_io_stream_get_input_stream (G_IO_STREAM (decoder->connection));
|
||||||
|
|
||||||
|
g_return_val_if_fail (in != NULL, NULL);
|
||||||
|
|
||||||
if (G_UNLIKELY (len > decoder->data_len)) {
|
if (G_UNLIKELY (len > decoder->data_len)) {
|
||||||
g_free (decoder->data);
|
g_free (decoder->data);
|
||||||
decoder->data = g_malloc (len);
|
decoder->data = g_malloc (len);
|
||||||
decoder->data_len = len;
|
decoder->data_len = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (total < len) {
|
if (!g_input_stream_read_all (in, decoder->data, len, NULL,
|
||||||
now = g_socket_receive (decoder->socket, (gchar *) decoder->data + total,
|
decoder->cancellable, &err))
|
||||||
len - total, decoder->cancellable, &err);
|
goto recv_error;
|
||||||
|
|
||||||
if (now < 0)
|
|
||||||
goto recv_error;
|
|
||||||
|
|
||||||
total += now;
|
|
||||||
}
|
|
||||||
return decoder->data;
|
return decoder->data;
|
||||||
|
|
||||||
recv_error:
|
recv_error:
|
||||||
|
@ -266,24 +207,23 @@ recv_error:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gboolean
|
||||||
rfb_decoder_send (RfbDecoder * decoder, guint8 * buffer, guint len)
|
rfb_decoder_send (RfbDecoder * decoder, guint8 * buffer, guint len)
|
||||||
{
|
{
|
||||||
gssize now = 0;
|
GOutputStream *out;
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (decoder->socket != NULL, 0);
|
g_return_val_if_fail (decoder->connection != NULL, 0);
|
||||||
g_return_val_if_fail (buffer != NULL, 0);
|
g_return_val_if_fail (buffer != NULL, 0);
|
||||||
g_return_val_if_fail (len > 0, 0);
|
g_return_val_if_fail (len > 0, 0);
|
||||||
|
|
||||||
now = g_socket_send (decoder->socket, (gchar *) buffer, len,
|
out = g_io_stream_get_output_stream (G_IO_STREAM (decoder->connection));
|
||||||
decoder->cancellable, &err);
|
|
||||||
|
|
||||||
if (now < 0)
|
if (!g_output_stream_write_all (out, buffer, len, NULL, decoder->cancellable,
|
||||||
|
&err))
|
||||||
goto send_error;
|
goto send_error;
|
||||||
|
|
||||||
done:
|
return TRUE;
|
||||||
return now;
|
|
||||||
|
|
||||||
send_error:
|
send_error:
|
||||||
{
|
{
|
||||||
|
@ -297,7 +237,7 @@ send_error:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_clear_error (&err);
|
g_clear_error (&err);
|
||||||
goto done;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,7 +248,7 @@ rfb_decoder_send_update_request (RfbDecoder * decoder,
|
||||||
guint8 data[10];
|
guint8 data[10];
|
||||||
|
|
||||||
g_return_if_fail (decoder != NULL);
|
g_return_if_fail (decoder != NULL);
|
||||||
g_return_if_fail (decoder->socket != NULL);
|
g_return_if_fail (decoder->connection != NULL);
|
||||||
|
|
||||||
data[0] = 3;
|
data[0] = 3;
|
||||||
data[1] = incremental;
|
data[1] = incremental;
|
||||||
|
@ -334,7 +274,7 @@ rfb_decoder_send_key_event (RfbDecoder * decoder, guint key, gboolean down_flag)
|
||||||
guint8 data[8];
|
guint8 data[8];
|
||||||
|
|
||||||
g_return_if_fail (decoder != NULL);
|
g_return_if_fail (decoder != NULL);
|
||||||
g_return_if_fail (decoder->socket != NULL);
|
g_return_if_fail (decoder->connection != NULL);
|
||||||
|
|
||||||
data[0] = 4;
|
data[0] = 4;
|
||||||
data[1] = down_flag;
|
data[1] = down_flag;
|
||||||
|
@ -351,7 +291,7 @@ rfb_decoder_send_pointer_event (RfbDecoder * decoder,
|
||||||
guint8 data[6];
|
guint8 data[6];
|
||||||
|
|
||||||
g_return_if_fail (decoder != NULL);
|
g_return_if_fail (decoder != NULL);
|
||||||
g_return_if_fail (decoder->socket != NULL);
|
g_return_if_fail (decoder->connection != NULL);
|
||||||
|
|
||||||
data[0] = 5;
|
data[0] = 5;
|
||||||
data[1] = button_mask;
|
data[1] = button_mask;
|
||||||
|
|
|
@ -42,7 +42,8 @@ struct _RfbDecoder
|
||||||
|
|
||||||
gpointer buffer_handler_data;
|
gpointer buffer_handler_data;
|
||||||
|
|
||||||
GSocket *socket;
|
GSocketClient *socket_client;
|
||||||
|
GSocketConnection *connection;
|
||||||
GCancellable *cancellable;
|
GCancellable *cancellable;
|
||||||
|
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
|
|
Loading…
Reference in a new issue