You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by jm...@apache.org on 2016/06/02 18:45:08 UTC
[01/26] incubator-guacamole-server git commit: GUACAMOLE-25:
Implement buffer attachment in Stream_New() and Stream_Free() compatibility
functions.
Repository: incubator-guacamole-server
Updated Branches:
refs/heads/master ec93a2989 -> 995b6d669
GUACAMOLE-25: Implement buffer attachment in Stream_New() and Stream_Free() compatibility functions.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/f1d4393e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/f1d4393e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/f1d4393e
Branch: refs/heads/master
Commit: f1d4393eb8cedeec0214c497c73a528806ae2118
Parents: 1393358
Author: Michael Jumper <mj...@apache.org>
Authored: Mon May 9 22:18:49 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/compat/winpr-stream.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/f1d4393e/src/protocols/rdp/compat/winpr-stream.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/compat/winpr-stream.c b/src/protocols/rdp/compat/winpr-stream.c
index 528177d..8be4546 100644
--- a/src/protocols/rdp/compat/winpr-stream.c
+++ b/src/protocols/rdp/compat/winpr-stream.c
@@ -22,17 +22,26 @@
#include "winpr-stream.h"
#include "winpr-wtypes.h"
-/*
- * NOTE: Because the old API did not support local allocation of the buffer
- * for each stream, these compatibility implementations ignore
- * the parameters of Stream_New() and Stream_Free() that provide them.
- */
-
wStream* Stream_New(BYTE* buffer, size_t size) {
- return stream_new(size);
+
+ /* If no buffer is provided, allocate a new stream of the given size */
+ if (buffer == NULL)
+ return stream_new(size);
+
+ /* Otherwise allocate an empty stream and assign the given buffer */
+ wStream* stream = stream_new(0);
+ stream_attach(stream, buffer, size);
+ return stream;
+
}
void Stream_Free(wStream* s, BOOL bFreeBuffer) {
+
+ /* Disassociate buffer if it will be freed externally */
+ if (!bFreeBuffer)
+ stream_detach(s);
+
stream_free(s);
+
}
[16/26] incubator-guacamole-server git commit: GUACAMOLE-25:
Partially handle the Open PDU.
Posted by jm...@apache.org.
GUACAMOLE-25: Partially handle the Open PDU.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/63cd2ce5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/63cd2ce5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/63cd2ce5
Branch: refs/heads/master
Commit: 63cd2ce512a92a31f497d09d5e1903aeab57fd8f
Parents: 86806a3
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Apr 17 02:36:32 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/guac_ai/ai_messages.c | 82 +++++++++++++++++++++++++---
1 file changed, 74 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/63cd2ce5/src/protocols/rdp/guac_ai/ai_messages.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_messages.c b/src/protocols/rdp/guac_ai/ai_messages.c
index d4cc28d..8b2d0d7 100644
--- a/src/protocols/rdp/guac_ai/ai_messages.c
+++ b/src/protocols/rdp/guac_ai/ai_messages.c
@@ -101,14 +101,14 @@ static void guac_rdp_ai_write_format(wStream* stream,
*/
static void guac_rdp_ai_send_incoming_data(IWTSVirtualChannel* channel) {
- /* Build response version PDU */
- wStream* response = Stream_New(NULL, 1);
- Stream_Write_UINT8(response, GUAC_RDP_MSG_SNDIN_DATA_INCOMING); /* MessageId */
+ /* Build data incoming PDU */
+ wStream* stream = Stream_New(NULL, 1);
+ Stream_Write_UINT8(stream, GUAC_RDP_MSG_SNDIN_DATA_INCOMING); /* MessageId */
- /* Send response */
- channel->Write(channel, (UINT32) Stream_GetPosition(response),
- Stream_Buffer(response), NULL);
- Stream_Free(response, TRUE);
+ /* Send stream */
+ channel->Write(channel, (UINT32) Stream_GetPosition(stream),
+ Stream_Buffer(stream), NULL);
+ Stream_Free(stream, TRUE);
}
@@ -155,6 +155,60 @@ static void guac_rdp_ai_send_formats(IWTSVirtualChannel* channel,
}
+/**
+ * Sends an Open Reply PDU along the given channel. An Open Reply PDU is
+ * used by the client to acknowledge the successful opening of the AUDIO_INPUT
+ * channel.
+ *
+ * @param channel
+ * The channel along which the PDU should be sent.
+ *
+ * @param result
+ * The HRESULT code to send to the server indicating success, failure, etc.
+ */
+static void guac_rdp_ai_send_open_reply(IWTSVirtualChannel* channel,
+ UINT32 result) {
+
+ /* Build open reply PDU */
+ wStream* stream = Stream_New(NULL, 5);
+ Stream_Write_UINT8(stream, GUAC_RDP_MSG_SNDIN_OPEN_REPLY); /* MessageId */
+ Stream_Write_UINT32(stream, result); /* Result */
+
+ /* Send stream */
+ channel->Write(channel, (UINT32) Stream_GetPosition(stream),
+ Stream_Buffer(stream), NULL);
+ Stream_Free(stream, TRUE);
+
+}
+
+/**
+ * Sends a Format Change PDU along the given channel. A Format Change PDU is
+ * used by the client to acknowledge the format being used for data sent
+ * along the AUDIO_INPUT channel.
+ *
+ * @param channel
+ * The channel along which the PDU should be sent.
+ *
+ * @param format
+ * The index of the format being acknowledged, which must be the index of
+ * the format within the original Sound Formats PDU received from the
+ * server.
+ */
+static void guac_rdp_ai_send_formatchange(IWTSVirtualChannel* channel,
+ UINT32 format) {
+
+ /* Build format change PDU */
+ wStream* stream = Stream_New(NULL, 5);
+ Stream_Write_UINT8(stream, GUAC_RDP_MSG_SNDIN_FORMATCHANGE); /* MessageId */
+ Stream_Write_UINT32(stream, format); /* NewFormat */
+
+ /* Send stream */
+ channel->Write(channel, (UINT32) Stream_GetPosition(stream),
+ Stream_Buffer(stream), NULL);
+ Stream_Free(stream, TRUE);
+
+}
+
void guac_rdp_ai_process_version(guac_client* client,
IWTSVirtualChannel* channel, wStream* stream) {
@@ -212,8 +266,20 @@ void guac_rdp_ai_process_formats(guac_client* client,
void guac_rdp_ai_process_open(guac_client* client,
IWTSVirtualChannel* channel, wStream* stream) {
+ UINT32 packet_frames;
+ UINT32 initial_format;
+
+ Stream_Read_UINT32(stream, packet_frames); /* FramesPerPacket */
+ Stream_Read_UINT32(stream, initial_format); /* InitialFormat */
+
/* STUB */
- guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT: open");
+ guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT: open: "
+ "packet_frames=%i, initial_format=%i",
+ packet_frames, initial_format);
+
+ /* Success */
+ guac_rdp_ai_send_formatchange(channel, initial_format);
+ guac_rdp_ai_send_open_reply(channel, 0);
}
[25/26] incubator-guacamole-server git commit: GUACAMOLE-25: Update
documentation regarding loading of dynamic virtual channel plugins.
Posted by jm...@apache.org.
GUACAMOLE-25: Update documentation regarding loading of dynamic virtual channel plugins.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/402b0393
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/402b0393
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/402b0393
Branch: refs/heads/master
Commit: 402b0393844fb2d6180ccaed341108b349404c83
Parents: 0d29694
Author: Michael Jumper <mj...@apache.org>
Authored: Wed Jun 1 22:06:17 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed Jun 1 22:06:17 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/audio_input.h | 12 +++++++++---
src/protocols/rdp/rdp_disp.h | 20 ++++++++++++++++----
2 files changed, 25 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/402b0393/src/protocols/rdp/audio_input.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.h b/src/protocols/rdp/audio_input.h
index bd84fe1..6280662 100644
--- a/src/protocols/rdp/audio_input.h
+++ b/src/protocols/rdp/audio_input.h
@@ -294,12 +294,18 @@ guac_user_blob_handler guac_rdp_audio_blob_handler;
guac_user_end_handler guac_rdp_audio_end_handler;
/**
- * Loads Guacamole's "guacai" plugin for FreeRDP, adding support for the
- * "AUDIO_INPUT" dynamic virtual channel. This function must ONLY be called
- * after FreeRDP's "drdynvc" virtual channel plugin has been loaded.
+ * Adds Guacamole's "guacai" plugin to the list of dynamic virtual channel
+ * plugins to be loaded by FreeRDP's "drdynvc" plugin. The plugin will only
+ * be loaded once guac_rdp_load_drdynvc() is invoked with the guac_rdp_dvc_list
+ * passed to this function. The "guacai" plugin ultimately adds support for the
+ * "AUDIO_INPUT" dynamic virtual channel.
*
* @param context
* The rdpContext associated with the active RDP session.
+ *
+ * @param list
+ * The guac_rdp_dvc_list to which the "guacai" plugin should be added, such
+ * that it may later be loaded by guac_rdp_load_drdynvc().
*/
void guac_rdp_audio_load_plugin(rdpContext* context, guac_rdp_dvc_list* list);
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/402b0393/src/protocols/rdp/rdp_disp.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_disp.h b/src/protocols/rdp/rdp_disp.h
index 093e7ed..0f34fe1 100644
--- a/src/protocols/rdp/rdp_disp.h
+++ b/src/protocols/rdp/rdp_disp.h
@@ -97,12 +97,24 @@ guac_rdp_disp* guac_rdp_disp_alloc();
void guac_rdp_disp_free(guac_rdp_disp* disp);
/**
- * Loads the "disp" plugin for FreeRDP. It is still up to external code to
- * detect when the "disp" channel is connected, and update the guac_rdp_disp
- * with a call to guac_rdp_disp_connect().
- *
* @param context The rdpContext associated with the active RDP session.
*/
+/**
+ * Adds FreeRDP's "disp" plugin to the list of dynamic virtual channel plugins
+ * to be loaded by FreeRDP's "drdynvc" plugin. The plugin will only be loaded
+ * once guac_rdp_load_drdynvc() is invoked with the guac_rdp_dvc_list passed to
+ * this function. The "disp" plugin ultimately adds support for the Display
+ * Update channel. NOTE: It is still up to external code to detect when the
+ * "disp" channel is connected, and update the guac_rdp_disp with a call to
+ * guac_rdp_disp_connect().
+ *
+ * @param context
+ * The rdpContext associated with the active RDP session.
+ *
+ * @param list
+ * The guac_rdp_dvc_list to which the "disp" plugin should be added, such
+ * that it may later be loaded by guac_rdp_load_drdynvc().
+ */
void guac_rdp_disp_load_plugin(rdpContext* context, guac_rdp_dvc_list* list);
#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
[20/26] incubator-guacamole-server git commit: GUACAMOLE-25: Remove
STUB.
Posted by jm...@apache.org.
GUACAMOLE-25: Remove STUB.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/260d0cd3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/260d0cd3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/260d0cd3
Branch: refs/heads/master
Commit: 260d0cd340f78c91dd29acd6de97bf57f2e46cc9
Parents: 533a47f
Author: Michael Jumper <mj...@apache.org>
Authored: Wed May 11 14:09:48 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:29 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/guac_ai/ai_messages.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/260d0cd3/src/protocols/rdp/guac_ai/ai_messages.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_messages.c b/src/protocols/rdp/guac_ai/ai_messages.c
index 520416c..eeb3e28 100644
--- a/src/protocols/rdp/guac_ai/ai_messages.c
+++ b/src/protocols/rdp/guac_ai/ai_messages.c
@@ -319,8 +319,10 @@ void guac_rdp_ai_process_open(guac_client* client,
void guac_rdp_ai_process_formatchange(guac_client* client,
IWTSVirtualChannel* channel, wStream* stream) {
- /* STUB: Should not be called as we only accept one format */
- guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT: formatchange");
+ /* Should not be called as we only accept one format */
+ guac_client_log(client, GUAC_LOG_DEBUG,
+ "RDP server requesting AUDIO_INPUT format change despite only one "
+ "format available.");
}
[14/26] incubator-guacamole-server git commit: GUACAMOLE-25: Add
support for multiple versions of IWTSVirtualChannelCallback.
Posted by jm...@apache.org.
GUACAMOLE-25: Add support for multiple versions of IWTSVirtualChannelCallback.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/10883323
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/10883323
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/10883323
Branch: refs/heads/master
Commit: 1088332376343c52ca6c66fbd2053146e5b72d22
Parents: ac94fd4
Author: Michael Jumper <mj...@apache.org>
Authored: Sat Apr 16 23:28:50 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
configure.ac | 22 ++++++++++++++++++++++
src/protocols/rdp/guac_ai/ai_service.c | 29 +++++++++++++++++++++++++++++
2 files changed, 51 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/10883323/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 485c10d..04cb6bb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -765,6 +765,28 @@ then
fi
#
+# FreeRDP: IWTSVirtualChannelCallback
+#
+
+if test "x${have_freerdp}" = "xyes"
+then
+ AC_MSG_CHECKING([whether IWTSVirtualChannelCallback.OnDataReceived() uses a wStream])
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <winpr/wtypes.h>
+ #include <freerdp/dvc.h>
+ #include <freerdp/freerdp.h>
+ int __data_received(
+ IWTSVirtualChannelCallback* channel_callback,
+ wStream* stream);
+ IWTSVirtualChannelCallback cb = {
+ .OnDataReceived = __data_received
+ };]])],
+ [AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])
+ AC_DEFINE([LEGACY_IWTSVIRTUALCHANNELCALLBACK],,
+ [Whether the legacy IWTSVirtualChannelCallback API was found])])
+fi
+
+#
# FreeRDP: Decompression function variants
#
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/10883323/src/protocols/rdp/guac_ai/ai_service.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_service.c b/src/protocols/rdp/guac_ai/ai_service.c
index 5b72354..e822f90 100644
--- a/src/protocols/rdp/guac_ai/ai_service.c
+++ b/src/protocols/rdp/guac_ai/ai_service.c
@@ -62,6 +62,7 @@ static void guac_rdp_ai_handle_data(guac_client* client, wStream* stream) {
}
+#if LEGACY_IWTSVIRTUALCHANNELCALLBACK
/**
* Callback which is invoked when data is received along a connection to the
* AUDIO_INPUT plugin. This callback is specific to FreeRDP 1.1 and older.
@@ -93,6 +94,34 @@ static int guac_rdp_ai_data(IWTSVirtualChannelCallback* channel_callback,
return 0;
}
+#else
+/**
+ * Callback which is invoked when data is received along a connection to the
+ * AUDIO_INPUT plugin. This callback is specific to FreeRDP 1.2 and newer.
+ *
+ * @param channel_callback
+ * The IWTSVirtualChannelCallback structure to which this callback was
+ * originally assigned.
+ *
+ * @param stream
+ * The data received.
+ *
+ * @return
+ * Always zero.
+ */
+static int guac_rdp_ai_data(IWTSVirtualChannelCallback* channel_callback,
+ wStream* stream) {
+
+ guac_rdp_ai_channel_callback* ai_channel_callback =
+ (guac_rdp_ai_channel_callback*) channel_callback;
+
+ /* Invoke generalized (API-independent) data handler */
+ guac_rdp_ai_handle_data(ai_channel_callback->client, stream);
+
+ return 0;
+
+}
+#endif
/**
* Callback which is invoked when a connection to the AUDIO_INPUT plugin is
[21/26] incubator-guacamole-server git commit: GUACAMOLE-25: Store
audio format within common structure.
Posted by jm...@apache.org.
GUACAMOLE-25: Store audio format within common structure.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/ad00cce0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/ad00cce0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/ad00cce0
Branch: refs/heads/master
Commit: ad00cce0ad882e8e549c74212cf33826ea44c4e1
Parents: 260d0cd
Author: Michael Jumper <mj...@apache.org>
Authored: Wed May 25 14:38:22 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 14:38:22 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/audio_input.c | 12 +++----
src/protocols/rdp/audio_input.h | 62 +++++++++++++++++-------------------
2 files changed, 36 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/ad00cce0/src/protocols/rdp/audio_input.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.c b/src/protocols/rdp/audio_input.c
index b2f61bd..9e88fb5 100644
--- a/src/protocols/rdp/audio_input.c
+++ b/src/protocols/rdp/audio_input.c
@@ -242,9 +242,9 @@ void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
/* Associate received stream */
audio_buffer->user = user;
audio_buffer->stream = stream;
- audio_buffer->in_rate = rate;
- audio_buffer->in_channels = channels;
- audio_buffer->in_bps = bps;
+ audio_buffer->in_format.rate = rate;
+ audio_buffer->in_format.channels = channels;
+ audio_buffer->in_format.bps = bps;
/* Acknowledge stream creation (if buffer is ready to receive) */
guac_rdp_audio_buffer_ack(audio_buffer,
@@ -262,9 +262,9 @@ void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
/* Reset buffer state to provided values */
audio_buffer->bytes_written = 0;
- audio_buffer->out_rate = rate;
- audio_buffer->out_channels = channels;
- audio_buffer->out_bps = bps;
+ audio_buffer->out_format.rate = rate;
+ audio_buffer->out_format.channels = channels;
+ audio_buffer->out_format.bps = bps;
audio_buffer->packet_size = packet_size;
audio_buffer->flush_handler = flush_handler;
audio_buffer->data = data;
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/ad00cce0/src/protocols/rdp/audio_input.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.h b/src/protocols/rdp/audio_input.h
index 2514b50..0970671 100644
--- a/src/protocols/rdp/audio_input.h
+++ b/src/protocols/rdp/audio_input.h
@@ -49,6 +49,29 @@ typedef void guac_rdp_audio_buffer_flush_handler(char* buffer, int length,
void* data);
/**
+ * A description of an arbitrary PCM audio format.
+ */
+typedef struct guac_rdp_audio_format {
+
+ /**
+ * The rate of the audio data in samples per second.
+ */
+ int rate;
+
+ /**
+ * The number of channels included in the audio data. This will be 1 for
+ * monaural audio and 2 for stereo.
+ */
+ int channels;
+
+ /**
+ * The size of each sample within the audio data, in bytes.
+ */
+ int bps;
+
+} guac_rdp_audio_format;
+
+/**
* A buffer of arbitrary audio data. Received audio data can be written to this
* buffer, and will automatically be flushed via a given handler once the
* internal buffer reaches capacity.
@@ -74,43 +97,18 @@ typedef struct guac_rdp_audio_buffer {
guac_stream* stream;
/**
- * The rate of the audio stream being received from the user, if any, in
- * samples per second. If no stream is yet associated, this value is
+ * The PCM format of the audio stream being received from the user, if any.
+ * If no stream is yet associated, the values stored within this format are
* undefined.
*/
- int in_rate;
-
- /**
- * The number of channels included in the audio stream being received from
- * the user, if any. If no stream is yet associated, this value is
- * undefined.
- */
- int in_channels;
-
- /**
- * The size of each sample within the audio stream being received from the
- * user, if any, in bytes. If no stream is yet associated, this value is
- * undefined.
- */
- int in_bps;
-
- /**
- * The rate of the audio stream expected by RDP, if any, in samples per
- * second. If no stream is yet associated, this value is undefined.
- */
- int out_rate;
-
- /**
- * The number of channels included in the audio stream expected by RDP, if
- * any. If no stream is yet associated, this value is undefined.
- */
- int out_channels;
+ guac_rdp_audio_format in_format;
/**
- * The size of each sample within the audio stream expected by RDP, if any,
- * in bytes. If no stream is yet associated, this value is undefined.
+ * The PCM format of the audio stream expected by RDP, if any. If no audio
+ * stream has yet been requested by the RDP server, the values stored
+ * within this format are undefined.
*/
- int out_bps;
+ guac_rdp_audio_format out_format;
/**
* The size that each audio packet must be, in bytes. The packet buffer
[10/26] incubator-guacamole-server git commit: GUACAMOLE-25: Handle
the server's Sound Formats PDU.
Posted by jm...@apache.org.
GUACAMOLE-25: Handle the server's Sound Formats PDU.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/86806a37
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/86806a37
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/86806a37
Branch: refs/heads/master
Commit: 86806a37592624707aaa7450f6b4fe06bb1cf469
Parents: 503ffb0
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Apr 17 02:11:29 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/guac_ai/ai_messages.c | 147 ++++++++++++++++++++++++++-
src/protocols/rdp/guac_ai/ai_messages.h | 59 +++++++++++
2 files changed, 204 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/86806a37/src/protocols/rdp/guac_ai/ai_messages.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_messages.c b/src/protocols/rdp/guac_ai/ai_messages.c
index c799a44..d4cc28d 100644
--- a/src/protocols/rdp/guac_ai/ai_messages.c
+++ b/src/protocols/rdp/guac_ai/ai_messages.c
@@ -35,6 +35,126 @@
#include "compat/winpr-stream.h"
#endif
+/**
+ * Reads AUDIO_FORMAT data from the given stream into the given struct.
+ *
+ * @param stream
+ * The stream to read AUDIO_FORMAT data from.
+ *
+ * @param format
+ * The structure to populate with data from the stream.
+ */
+static void guac_rdp_ai_read_format(wStream* stream,
+ guac_rdp_ai_format* format) {
+
+ /* Read audio format into structure */
+ Stream_Read_UINT16(stream, format->tag); /* wFormatTag */
+ Stream_Read_UINT16(stream, format->channels); /* nChannels */
+ Stream_Read_UINT32(stream, format->rate); /* nSamplesPerSec */
+ Stream_Read_UINT32(stream, format->bytes_per_sec); /* nAvgBytesPerSec */
+ Stream_Read_UINT16(stream, format->block_align); /* nBlockAlign */
+ Stream_Read_UINT16(stream, format->bps); /* wBitsPerSample */
+ Stream_Read_UINT16(stream, format->data_size); /* cbSize */
+
+ /* Read arbitrary data block (if applicable) */
+ if (format->data_size != 0) {
+ format->data = Stream_Pointer(stream); /* data */
+ Stream_Seek(stream, format->data_size);
+ }
+
+}
+
+/**
+ * Writes AUDIO_FORMAT data to the given stream from the given struct.
+ *
+ * @param stream
+ * The stream to write AUDIO_FORMAT data to.
+ *
+ * @param format
+ * The structure containing the data that should be written to the stream.
+ */
+static void guac_rdp_ai_write_format(wStream* stream,
+ guac_rdp_ai_format* format) {
+
+ /* Write audio format into structure */
+ Stream_Write_UINT16(stream, format->tag); /* wFormatTag */
+ Stream_Write_UINT16(stream, format->channels); /* nChannels */
+ Stream_Write_UINT32(stream, format->rate); /* nSamplesPerSec */
+ Stream_Write_UINT32(stream, format->bytes_per_sec); /* nAvgBytesPerSec */
+ Stream_Write_UINT16(stream, format->block_align); /* nBlockAlign */
+ Stream_Write_UINT16(stream, format->bps); /* wBitsPerSample */
+ Stream_Write_UINT16(stream, format->data_size); /* cbSize */
+
+ /* Write arbitrary data block (if applicable) */
+ if (format->data_size != 0)
+ Stream_Write(stream, format->data, format->data_size);
+
+}
+
+/**
+ * Sends a Data Incoming PDU along the given channel. A Data Incoming PDU is
+ * used by the client to indicate to the server that format or audio data is
+ * about to be sent.
+ *
+ * @param channel
+ * The channel along which the PDU should be sent.
+ */
+static void guac_rdp_ai_send_incoming_data(IWTSVirtualChannel* channel) {
+
+ /* Build response version PDU */
+ wStream* response = Stream_New(NULL, 1);
+ Stream_Write_UINT8(response, GUAC_RDP_MSG_SNDIN_DATA_INCOMING); /* MessageId */
+
+ /* Send response */
+ channel->Write(channel, (UINT32) Stream_GetPosition(response),
+ Stream_Buffer(response), NULL);
+ Stream_Free(response, TRUE);
+
+}
+
+/**
+ * Sends a Sound Formats PDU along the given channel. A Sound Formats PDU is
+ * used by the client to indicate to the server which formats of audio it
+ * supports (in response to the server sending exactly the same type of PDU).
+ * This PDU MUST be preceded by the Data Incoming PDU.
+ *
+ * @param channel
+ * The channel along which the PDU should be sent.
+ *
+ * @param formats
+ * An array of all supported formats.
+ *
+ * @param num_formats
+ * The number of entries in the formats array.
+ */
+static void guac_rdp_ai_send_formats(IWTSVirtualChannel* channel,
+ guac_rdp_ai_format* formats, int num_formats) {
+
+ int index;
+ int packet_size = 9;
+
+ /* Calculate packet size */
+ for (index = 0; index < num_formats; index++)
+ packet_size += 18 + formats[index].data_size;
+
+ wStream* stream = Stream_New(NULL, packet_size);
+
+ /* Write header */
+ Stream_Write_UINT8(stream, GUAC_RDP_MSG_SNDIN_FORMATS); /* MessageId */
+ Stream_Write_UINT32(stream, num_formats); /* NumFormats */
+ Stream_Write_UINT32(stream, packet_size); /* cbSizeFormatsPacket */
+
+ /* Write all formats */
+ for (index = 0; index < num_formats; index++)
+ guac_rdp_ai_write_format(stream, &(formats[index]));
+
+ /* Send PDU */
+ channel->Write(channel, (UINT32) Stream_GetPosition(stream),
+ Stream_Buffer(stream), NULL);
+ Stream_Free(stream, TRUE);
+
+}
+
void guac_rdp_ai_process_version(guac_client* client,
IWTSVirtualChannel* channel, wStream* stream) {
@@ -61,8 +181,31 @@ void guac_rdp_ai_process_version(guac_client* client,
void guac_rdp_ai_process_formats(guac_client* client,
IWTSVirtualChannel* channel, wStream* stream) {
- /* STUB */
- guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT: formats");
+ UINT32 num_formats;
+ Stream_Read_UINT32(stream, num_formats); /* NumFormats */
+ Stream_Seek_UINT32(stream); /* cbSizeFormatsPacket (MUST BE IGNORED) */
+
+ UINT32 index;
+ for (index = 0; index < num_formats; index++) {
+
+ guac_rdp_ai_format format;
+ guac_rdp_ai_read_format(stream, &format);
+
+ /* Ignore anything but WAVE_FORMAT_PCM */
+ if (format.tag != GUAC_RDP_WAVE_FORMAT_PCM)
+ continue;
+
+ /* Accept single format */
+ guac_rdp_ai_send_incoming_data(channel);
+ guac_rdp_ai_send_formats(channel, &format, 1);
+ return;
+
+ }
+
+ /* No formats available */
+ guac_client_log(client, GUAC_LOG_WARNING, "AUDIO_INPUT: No WAVE format.");
+ guac_rdp_ai_send_incoming_data(channel);
+ guac_rdp_ai_send_formats(channel, NULL, 0);
}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/86806a37/src/protocols/rdp/guac_ai/ai_messages.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_messages.h b/src/protocols/rdp/guac_ai/ai_messages.h
index 96282e5..55cf6e9 100644
--- a/src/protocols/rdp/guac_ai/ai_messages.h
+++ b/src/protocols/rdp/guac_ai/ai_messages.h
@@ -32,6 +32,12 @@
#endif
/**
+ * The format tag associated with raw wave audio (WAVE_FORMAT_PCM). This format
+ * is required to be supported by all RDP servers.
+ */
+#define GUAC_RDP_WAVE_FORMAT_PCM 0x01
+
+/**
* The message ID associated with the AUDIO_INPUT Version PDU. The Version PDU
* is sent by both the client and the server to indicate their version of the
* AUDIO_INPUT channel protocol (which must always be 1).
@@ -80,6 +86,59 @@
#define GUAC_RDP_MSG_SNDIN_FORMATCHANGE 0x07
/**
+ * An AUDIO_INPUT format, analogous to the AUDIO_FORMAT structure defined
+ * within Microsoft's RDP documentation.
+ */
+typedef struct guac_rdp_ai_format {
+
+ /**
+ * The "format tag" denoting the overall format of audio data received,
+ * such as WAVE_FORMAT_PCM.
+ */
+ UINT16 tag;
+
+ /**
+ * The number of audio channels.
+ */
+ UINT16 channels;
+
+ /**
+ * The number of samples per second.
+ */
+ UINT32 rate;
+
+ /**
+ * The average number of bytes required for one second of audio.
+ */
+ UINT32 bytes_per_sec;
+
+ /**
+ * The absolute minimum number of bytes required to process audio in this
+ * format.
+ */
+ UINT16 block_align;
+
+ /**
+ * The number of bits per sample.
+ */
+ UINT16 bps;
+
+ /**
+ * The size of the arbitrary data block, if any. The meaning of the data
+ * within the arbitrary data block is determined by the format tag.
+ * WAVE_FORMAT_PCM audio has no associated arbitrary data.
+ */
+ UINT16 data_size;
+
+ /**
+ * Optional arbitrary data whose meaning is determined by the format tag.
+ * WAVE_FORMAT_PCM audio has no associated arbitrary data.
+ */
+ BYTE* data;
+
+} guac_rdp_ai_format;
+
+/**
* Processes a Version PDU received from the RDP server. The Version PDU is
* sent by the server to indicate its version of the AUDIO_INPUT channel
* protocol (which must always be 1).
[19/26] incubator-guacamole-server git commit: GUACAMOLE-25:
Implement parsing of audio mimetypes.
Posted by jm...@apache.org.
GUACAMOLE-25: Implement parsing of audio mimetypes.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/320f564d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/320f564d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/320f564d
Branch: refs/heads/master
Commit: 320f564daf2e67ce2e746b1b5697320dc191815f
Parents: 8ccf61e
Author: Michael Jumper <mj...@apache.org>
Authored: Wed May 11 13:34:29 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:29 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/audio_input.c | 114 +++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/320f564d/src/protocols/rdp/audio_input.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.c b/src/protocols/rdp/audio_input.c
index f2fd84a..b7f605d 100644
--- a/src/protocols/rdp/audio_input.c
+++ b/src/protocols/rdp/audio_input.c
@@ -30,16 +30,130 @@
#include <guacamole/stream.h>
#include <guacamole/user.h>
+#include <errno.h>
#include <stdlib.h>
#include <pthread.h>
+/**
+ * Parses the given raw audio mimetype, producing the corresponding rate,
+ * number of channels, and bytes per sample.
+ *
+ * @param mimetype
+ * The raw auduio mimetype to parse.
+ *
+ * @param rate
+ * A pointer to an int where the sample rate for the PCM format described
+ * by the given mimetype should be stored.
+ *
+ * @param channels
+ * A pointer to an int where the number of channels used by the PCM format
+ * described by the given mimetype should be stored.
+ *
+ * @param bps
+ * A pointer to an int where the number of bytes used the PCM format for
+ * each sample (independent of number of channels) described by the given
+ * mimetype should be stored.
+ *
+ * @return
+ * Zero if the given mimetype is a raw audio mimetype and has been parsed
+ * successfully, non-zero otherwise.
+ */
+static int guac_rdp_audio_parse_mimetype(const char* mimetype,
+ int* rate, int* channels, int* bps) {
+
+ int parsed_rate = -1;
+ int parsed_channels = 1;
+ int parsed_bps;
+
+ /* PCM audio with one byte per sample */
+ if (strncmp(mimetype, "audio/L8;", 9) == 0) {
+ mimetype += 8; /* Advance to semicolon ONLY */
+ parsed_bps = 1;
+ }
+
+ /* PCM audio with two bytes per sample */
+ else if (strncmp(mimetype, "audio/L16;", 10) == 0) {
+ mimetype += 9; /* Advance to semicolon ONLY */
+ parsed_bps = 2;
+ }
+
+ /* Unsupported mimetype */
+ else
+ return 1;
+
+ /* Parse each parameter name/value pair within the mimetype */
+ do {
+
+ /* Advance to first character of parameter (current is either a
+ * semicolon or a comma) */
+ mimetype++;
+
+ /* Parse number of channels */
+ if (strncmp(mimetype, "channels=", 9) == 0) {
+
+ mimetype += 9;
+ parsed_channels = strtol(mimetype, (char**) &mimetype, 10);
+
+ /* Fail if value invalid / out of range */
+ if (errno == EINVAL || errno == ERANGE)
+ return 1;
+
+ }
+
+ /* Parse number of rate */
+ else if (strncmp(mimetype, "rate=", 5) == 0) {
+
+ mimetype += 5;
+ parsed_rate = strtol(mimetype, (char**) &mimetype, 10);
+
+ /* Fail if value invalid / out of range */
+ if (errno == EINVAL || errno == ERANGE)
+ return 1;
+
+ }
+
+ /* Advance to next parameter */
+ mimetype = strchr(mimetype, ',');
+
+ } while (mimetype != NULL);
+
+ /* Mimetype is invalid if rate was not specified */
+ if (rate == -1)
+ return 1;
+
+ /* Parse success */
+ *rate = parsed_rate;
+ *channels = parsed_channels;
+ *bps = parsed_bps;
+
+ return 0;
+
+}
+
int guac_rdp_audio_handler(guac_user* user, guac_stream* stream,
char* mimetype) {
guac_client* client = user->client;
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+ int rate;
+ int channels;
+ int bps;
+
+ /* Parse mimetype, abort on parse error */
+ if (guac_rdp_audio_parse_mimetype(mimetype, &rate, &channels, &bps)) {
+ guac_user_log(user, GUAC_LOG_WARN, "Denying user audio stream with "
+ "unsupported mimetype: \"%s\"", mimetype);
+ guac_protocol_send_ack(user->socket, stream, "Unsupported audio "
+ "mimetype", GUAC_PROTOCOL_STATUS_CLIENT_BAD_TYPE);
+ return 0;
+ }
+
/* FIXME: Assuming mimetype of "audio/L16;rate=44100,channels=2" */
+ else {
+ guac_user_log(user, GUAC_LOG_DEBUG, "rate=%i, channels=%i, bps=%i",
+ rate, channels, bps);
+ }
/* Init stream data */
stream->blob_handler = guac_rdp_audio_blob_handler;
[04/26] incubator-guacamole-server git commit: GUACAMOLE-25: Fix
pointer update in audio input buffer transfer.
Posted by jm...@apache.org.
GUACAMOLE-25: Fix pointer update in audio input buffer transfer.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/166eba11
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/166eba11
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/166eba11
Branch: refs/heads/master
Commit: 166eba11b728ffa4501bea9d0ad7afaf9a755911
Parents: 4e4dbd6
Author: Michael Jumper <mj...@apache.org>
Authored: Sun May 1 00:04:40 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/audio_input.c | 3 +++
1 file changed, 3 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/166eba11/src/protocols/rdp/audio_input.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.c b/src/protocols/rdp/audio_input.c
index 1bea175..8839d35 100644
--- a/src/protocols/rdp/audio_input.c
+++ b/src/protocols/rdp/audio_input.c
@@ -128,6 +128,9 @@ void guac_rdp_audio_buffer_write(guac_rdp_audio_buffer* audio_buffer,
length -= chunk_size;
audio_buffer->bytes_written += chunk_size;
+ /* Advance to next chunk */
+ buffer += chunk_size;
+
/* Invoke flush handler if full */
if (audio_buffer->bytes_written == audio_buffer->packet_size) {
[08/26] incubator-guacamole-server git commit: GUACAMOLE-25: Allocate
proper number of argument entries.
Posted by jm...@apache.org.
GUACAMOLE-25: Allocate proper number of argument entries.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/9cd89e65
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/9cd89e65
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/9cd89e65
Branch: refs/heads/master
Commit: 9cd89e6580615249cb0dbd8773934b871bc0ddb0
Parents: 4fdcfeb
Author: Michael Jumper <mj...@apache.org>
Authored: Sat Apr 16 21:44:14 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/audio_input.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/9cd89e65/src/protocols/rdp/audio_input.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.c b/src/protocols/rdp/audio_input.c
index b5c3f96..9d5d505 100644
--- a/src/protocols/rdp/audio_input.c
+++ b/src/protocols/rdp/audio_input.c
@@ -69,8 +69,8 @@ void guac_rdp_audio_load_plugin(rdpContext* context) {
/* Add "AUDIO_INPUT" channel */
ADDIN_ARGV* args = malloc(sizeof(ADDIN_ARGV));
- args->argc = 1;
- args->argv = malloc(sizeof(char**) * 1);
+ args->argc = 2;
+ args->argv = malloc(sizeof(char**) * 2);
args->argv[0] = strdup("guacai");
args->argv[1] = guac_rdp_ptr_to_string(client);
freerdp_dynamic_channel_collection_add(context->settings, args);
[22/26] incubator-guacamole-server git commit: GUACAMOLE-25: Store
PCM format expected by RDP server.
Posted by jm...@apache.org.
GUACAMOLE-25: Store PCM format expected by RDP server.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/1c2890b4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/1c2890b4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/1c2890b4
Branch: refs/heads/master
Commit: 1c2890b47c77b324efb6420df43998eff7104333
Parents: ad00cce
Author: Michael Jumper <mj...@apache.org>
Authored: Thu May 26 10:39:33 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu May 26 10:39:33 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/audio_input.c | 35 +++++++++++++++++-----
src/protocols/rdp/audio_input.h | 44 ++++++++++++++++++----------
src/protocols/rdp/guac_ai/ai_messages.c | 22 +++++++++-----
3 files changed, 72 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/1c2890b4/src/protocols/rdp/audio_input.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.c b/src/protocols/rdp/audio_input.c
index 9e88fb5..0eb757d 100644
--- a/src/protocols/rdp/audio_input.c
+++ b/src/protocols/rdp/audio_input.c
@@ -250,28 +250,49 @@ void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
guac_rdp_audio_buffer_ack(audio_buffer,
"OK", GUAC_PROTOCOL_STATUS_SUCCESS);
+ guac_user_log(user, GUAC_LOG_DEBUG, "User is requesting to provide audio "
+ "input as %i-channel, %i Hz PCM audio at %i bytes/sample.",
+ audio_buffer->in_format.channels,
+ audio_buffer->in_format.rate,
+ audio_buffer->in_format.bps);
+
pthread_mutex_unlock(&(audio_buffer->lock));
}
-void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
- int rate, int channels, int bps, int packet_size,
- guac_rdp_audio_buffer_flush_handler* flush_handler, void* data) {
+void guac_rdp_audio_buffer_set_output(guac_rdp_audio_buffer* audio_buffer,
+ int rate, int channels, int bps) {
pthread_mutex_lock(&(audio_buffer->lock));
- /* Reset buffer state to provided values */
- audio_buffer->bytes_written = 0;
+ /* Set output format */
audio_buffer->out_format.rate = rate;
audio_buffer->out_format.channels = channels;
audio_buffer->out_format.bps = bps;
- audio_buffer->packet_size = packet_size;
+
+ pthread_mutex_unlock(&(audio_buffer->lock));
+
+}
+
+void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
+ int packet_frames, guac_rdp_audio_buffer_flush_handler* flush_handler,
+ void* data) {
+
+ pthread_mutex_lock(&(audio_buffer->lock));
+
+ /* Reset buffer state to provided values */
+ audio_buffer->bytes_written = 0;
audio_buffer->flush_handler = flush_handler;
audio_buffer->data = data;
+ /* Calculate size of each packet in bytes */
+ audio_buffer->packet_size = packet_frames
+ * audio_buffer->out_format.channels
+ * audio_buffer->out_format.bps;
+
/* Allocate new buffer */
free(audio_buffer->packet);
- audio_buffer->packet = malloc(packet_size);
+ audio_buffer->packet = malloc(audio_buffer->packet_size);
/* Acknowledge stream creation (if stream is ready to receive) */
guac_rdp_audio_buffer_ack(audio_buffer,
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/1c2890b4/src/protocols/rdp/audio_input.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.h b/src/protocols/rdp/audio_input.h
index 0970671..87eee9a 100644
--- a/src/protocols/rdp/audio_input.h
+++ b/src/protocols/rdp/audio_input.h
@@ -181,28 +181,42 @@ void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
guac_user* user, guac_stream* stream, int rate, int channels, int bps);
/**
- * Begins handling of audio data received via guac_rdp_audio_buffer_write() and
- * allocates the necessary underlying packet buffer. Audio packets of exactly
- * packet_size bytes will be flushed as available using the provided
- * flush_handler.
+ * Defines the output format that should be used by the audio buffer when
+ * flushing packets of audio data received via guac_rdp_audio_buffer_write().
+ * As this format determines how the underlying packet buffer will be
+ * allocated, this function MUST be called prior to the call to
+ * guac_rdp_audio_buffer_begin().
*
* @param audio_buffer
- * The audio buffer to begin.
+ * The audio buffer to set the output format of.
*
* @param rate
- * The rate of the audio stream expected by RDP, if any, in samples per
- * second.
+ * The rate of the audio stream expected by RDP, in samples per second.
*
* @param channels
- * The number of channels included in the audio stream expected by RDP, if
- * any.
+ * The number of channels included in the audio stream expected by RDP.
*
* @param bps
- * The size of each sample within the audio stream expected by RDP, if any,
- * in bytes.
+ * The size of each sample within the audio stream expected by RDP, in
+ * bytes.
+ */
+void guac_rdp_audio_buffer_set_output(guac_rdp_audio_buffer* audio_buffer,
+ int rate, int channels, int bps);
+
+/**
+ * Begins handling of audio data received via guac_rdp_audio_buffer_write() and
+ * allocates the necessary underlying packet buffer. Audio packets having
+ * exactly packet_frames frames will be flushed as available using the provided
+ * flush_handler. An audio frame is a set of single samples, one sample per
+ * channel. The guac_rdp_audio_buffer_set_output() function MUST have
+ * been invoked first.
*
- * @param packet_size
- * The number of bytes to include in all audio packets provided to the
+ * @param audio_buffer
+ * The audio buffer to begin.
+ *
+ * @param packet_frames
+ * The exact number of frames (a set of samples, one for each channel)
+ * which MUST be included in all audio packets provided to the
* given flush_handler.
*
* @param flush_handler
@@ -213,8 +227,8 @@ void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
* needs to be flushed.
*/
void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
- int rate, int channels, int bps, int packet_size,
- guac_rdp_audio_buffer_flush_handler* flush_handler, void* data);
+ int packet_frames, guac_rdp_audio_buffer_flush_handler* flush_handler,
+ void* data);
/**
* Writes the given buffer of audio data to the given audio buffer. A new
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/1c2890b4/src/protocols/rdp/guac_ai/ai_messages.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_messages.c b/src/protocols/rdp/guac_ai/ai_messages.c
index eeb3e28..c346587 100644
--- a/src/protocols/rdp/guac_ai/ai_messages.c
+++ b/src/protocols/rdp/guac_ai/ai_messages.c
@@ -251,6 +251,9 @@ void guac_rdp_ai_process_version(guac_client* client,
void guac_rdp_ai_process_formats(guac_client* client,
IWTSVirtualChannel* channel, wStream* stream) {
+ guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+ guac_rdp_audio_buffer* audio_buffer = rdp_client->audio_input;
+
UINT32 num_formats;
Stream_Read_UINT32(stream, num_formats); /* NumFormats */
Stream_Seek_UINT32(stream); /* cbSizeFormatsPacket (MUST BE IGNORED) */
@@ -265,6 +268,10 @@ void guac_rdp_ai_process_formats(guac_client* client,
if (format.tag != GUAC_RDP_WAVE_FORMAT_PCM)
continue;
+ /* Set output format of internal audio buffer to match RDP server */
+ guac_rdp_audio_buffer_set_output(audio_buffer, format.rate,
+ format.channels, format.bps / 8);
+
/* Accept single format */
guac_rdp_ai_send_incoming_data(channel);
guac_rdp_ai_send_formats(channel, &format, 1);
@@ -301,18 +308,19 @@ void guac_rdp_ai_process_open(guac_client* client,
Stream_Read_UINT32(stream, packet_frames); /* FramesPerPacket */
Stream_Read_UINT32(stream, initial_format); /* InitialFormat */
- /* STUB */
- guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT: open: "
- "packet_frames=%i, initial_format=%i",
- packet_frames, initial_format);
+ guac_client_log(client, GUAC_LOG_DEBUG, "RDP server is accepting audio "
+ "input as %i-channel, %i Hz PCM audio at %i bytes/sample.",
+ audio_buffer->out_format.channels,
+ audio_buffer->out_format.rate,
+ audio_buffer->out_format.bps);
/* Success */
guac_rdp_ai_send_formatchange(channel, initial_format);
guac_rdp_ai_send_open_reply(channel, 0);
- /* FIXME: Assuming mimetype of 16-bit 44100 Hz stereo PCM */
- guac_rdp_audio_buffer_begin(audio_buffer, packet_frames * 2 * 2,
- 44100, 2, 2, guac_rdp_ai_flush_packet, channel);
+ /* Begin receiving audio data */
+ guac_rdp_audio_buffer_begin(audio_buffer, packet_frames,
+ guac_rdp_ai_flush_packet, channel);
}
[18/26] incubator-guacamole-server git commit: GUACAMOLE-25: Store
input and output audio format.
Posted by jm...@apache.org.
GUACAMOLE-25: Store input and output audio format.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/533a47f0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/533a47f0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/533a47f0
Branch: refs/heads/master
Commit: 533a47f06da3559ab66161fe8af8f431add167f0
Parents: 320f564
Author: Michael Jumper <mj...@apache.org>
Authored: Wed May 11 13:48:40 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:29 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/audio_input.c | 27 ++++++-----
src/protocols/rdp/audio_input.h | 69 ++++++++++++++++++++++++++--
src/protocols/rdp/guac_ai/ai_messages.c | 2 +-
3 files changed, 82 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/533a47f0/src/protocols/rdp/audio_input.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.c b/src/protocols/rdp/audio_input.c
index b7f605d..b2f61bd 100644
--- a/src/protocols/rdp/audio_input.c
+++ b/src/protocols/rdp/audio_input.c
@@ -118,7 +118,7 @@ static int guac_rdp_audio_parse_mimetype(const char* mimetype,
} while (mimetype != NULL);
/* Mimetype is invalid if rate was not specified */
- if (rate == -1)
+ if (parsed_rate == -1)
return 1;
/* Parse success */
@@ -142,25 +142,20 @@ int guac_rdp_audio_handler(guac_user* user, guac_stream* stream,
/* Parse mimetype, abort on parse error */
if (guac_rdp_audio_parse_mimetype(mimetype, &rate, &channels, &bps)) {
- guac_user_log(user, GUAC_LOG_WARN, "Denying user audio stream with "
+ guac_user_log(user, GUAC_LOG_WARNING, "Denying user audio stream with "
"unsupported mimetype: \"%s\"", mimetype);
guac_protocol_send_ack(user->socket, stream, "Unsupported audio "
"mimetype", GUAC_PROTOCOL_STATUS_CLIENT_BAD_TYPE);
return 0;
}
- /* FIXME: Assuming mimetype of "audio/L16;rate=44100,channels=2" */
- else {
- guac_user_log(user, GUAC_LOG_DEBUG, "rate=%i, channels=%i, bps=%i",
- rate, channels, bps);
- }
-
/* Init stream data */
stream->blob_handler = guac_rdp_audio_blob_handler;
stream->end_handler = guac_rdp_audio_end_handler;
/* Associate stream with audio buffer */
- guac_rdp_audio_buffer_set_stream(rdp_client->audio_input, user, stream);
+ guac_rdp_audio_buffer_set_stream(rdp_client->audio_input, user, stream,
+ rate, channels, bps);
return 0;
@@ -240,13 +235,16 @@ static void guac_rdp_audio_buffer_ack(guac_rdp_audio_buffer* audio_buffer,
}
void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
- guac_user* user, guac_stream* stream) {
+ guac_user* user, guac_stream* stream, int rate, int channels, int bps) {
pthread_mutex_lock(&(audio_buffer->lock));
/* Associate received stream */
audio_buffer->user = user;
audio_buffer->stream = stream;
+ audio_buffer->in_rate = rate;
+ audio_buffer->in_channels = channels;
+ audio_buffer->in_bps = bps;
/* Acknowledge stream creation (if buffer is ready to receive) */
guac_rdp_audio_buffer_ack(audio_buffer,
@@ -257,13 +255,16 @@ void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
}
void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
- int packet_size, guac_rdp_audio_buffer_flush_handler* flush_handler,
- void* data) {
+ int rate, int channels, int bps, int packet_size,
+ guac_rdp_audio_buffer_flush_handler* flush_handler, void* data) {
pthread_mutex_lock(&(audio_buffer->lock));
/* Reset buffer state to provided values */
audio_buffer->bytes_written = 0;
+ audio_buffer->out_rate = rate;
+ audio_buffer->out_channels = channels;
+ audio_buffer->out_bps = bps;
audio_buffer->packet_size = packet_size;
audio_buffer->flush_handler = flush_handler;
audio_buffer->data = data;
@@ -285,6 +286,8 @@ void guac_rdp_audio_buffer_write(guac_rdp_audio_buffer* audio_buffer,
pthread_mutex_lock(&(audio_buffer->lock));
+ /* FIXME: Assuming mimetype of "audio/L16;rate=44100,channels=2" */
+
/* Ignore packet if there is no buffer */
if (audio_buffer->packet_size == 0 || audio_buffer->packet == NULL) {
pthread_mutex_unlock(&(audio_buffer->lock));
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/533a47f0/src/protocols/rdp/audio_input.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.h b/src/protocols/rdp/audio_input.h
index e13b41e..2514b50 100644
--- a/src/protocols/rdp/audio_input.h
+++ b/src/protocols/rdp/audio_input.h
@@ -74,6 +74,45 @@ typedef struct guac_rdp_audio_buffer {
guac_stream* stream;
/**
+ * The rate of the audio stream being received from the user, if any, in
+ * samples per second. If no stream is yet associated, this value is
+ * undefined.
+ */
+ int in_rate;
+
+ /**
+ * The number of channels included in the audio stream being received from
+ * the user, if any. If no stream is yet associated, this value is
+ * undefined.
+ */
+ int in_channels;
+
+ /**
+ * The size of each sample within the audio stream being received from the
+ * user, if any, in bytes. If no stream is yet associated, this value is
+ * undefined.
+ */
+ int in_bps;
+
+ /**
+ * The rate of the audio stream expected by RDP, if any, in samples per
+ * second. If no stream is yet associated, this value is undefined.
+ */
+ int out_rate;
+
+ /**
+ * The number of channels included in the audio stream expected by RDP, if
+ * any. If no stream is yet associated, this value is undefined.
+ */
+ int out_channels;
+
+ /**
+ * The size of each sample within the audio stream expected by RDP, if any,
+ * in bytes. If no stream is yet associated, this value is undefined.
+ */
+ int out_bps;
+
+ /**
* The size that each audio packet must be, in bytes. The packet buffer
* within this structure will be at least this size.
*/
@@ -127,9 +166,21 @@ guac_rdp_audio_buffer* guac_rdp_audio_buffer_alloc();
*
* @param stream
* The guac_stream object representing the audio stream.
+ *
+ * @param rate
+ * The rate of the audio stream being received from the user, if any, in
+ * samples per second.
+ *
+ * @param channels
+ * The number of channels included in the audio stream being received from
+ * the user, if any.
+ *
+ * @param bps
+ * The size of each sample within the audio stream being received from the
+ * user, if any, in bytes.
*/
void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
- guac_user* user, guac_stream* stream);
+ guac_user* user, guac_stream* stream, int rate, int channels, int bps);
/**
* Begins handling of audio data received via guac_rdp_audio_buffer_write() and
@@ -140,6 +191,18 @@ void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
* @param audio_buffer
* The audio buffer to begin.
*
+ * @param rate
+ * The rate of the audio stream expected by RDP, if any, in samples per
+ * second.
+ *
+ * @param channels
+ * The number of channels included in the audio stream expected by RDP, if
+ * any.
+ *
+ * @param bps
+ * The size of each sample within the audio stream expected by RDP, if any,
+ * in bytes.
+ *
* @param packet_size
* The number of bytes to include in all audio packets provided to the
* given flush_handler.
@@ -152,8 +215,8 @@ void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
* needs to be flushed.
*/
void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
- int packet_size, guac_rdp_audio_buffer_flush_handler* flush_handler,
- void* data);
+ int rate, int channels, int bps, int packet_size,
+ guac_rdp_audio_buffer_flush_handler* flush_handler, void* data);
/**
* Writes the given buffer of audio data to the given audio buffer. A new
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/533a47f0/src/protocols/rdp/guac_ai/ai_messages.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_messages.c b/src/protocols/rdp/guac_ai/ai_messages.c
index b0eb6cf..520416c 100644
--- a/src/protocols/rdp/guac_ai/ai_messages.c
+++ b/src/protocols/rdp/guac_ai/ai_messages.c
@@ -312,7 +312,7 @@ void guac_rdp_ai_process_open(guac_client* client,
/* FIXME: Assuming mimetype of 16-bit 44100 Hz stereo PCM */
guac_rdp_audio_buffer_begin(audio_buffer, packet_frames * 2 * 2,
- guac_rdp_ai_flush_packet, channel);
+ 44100, 2, 2, guac_rdp_ai_flush_packet, channel);
}
[11/26] incubator-guacamole-server git commit: GUACAMOLE-25: Fix
configure test for FreeRDP variations.
Posted by jm...@apache.org.
GUACAMOLE-25: Fix configure test for FreeRDP variations.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/4e4dbd6a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/4e4dbd6a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/4e4dbd6a
Branch: refs/heads/master
Commit: 4e4dbd6a2d9e882a2a23baf758a209621b5334fc
Parents: 9d5871a
Author: Michael Jumper <mj...@apache.org>
Authored: Wed Apr 20 22:02:01 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
configure.ac | 6 +++++-
src/protocols/rdp/guac_ai/ai_service.c | 2 +-
2 files changed, 6 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/4e4dbd6a/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 04cb6bb..7dec629 100644
--- a/configure.ac
+++ b/configure.ac
@@ -779,7 +779,11 @@ then
wStream* stream);
IWTSVirtualChannelCallback cb = {
.OnDataReceived = __data_received
- };]])],
+ };
+ int main() {
+ return
+ cb.OnDataReceived(NULL, NULL);
+ }]])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
AC_DEFINE([LEGACY_IWTSVIRTUALCHANNELCALLBACK],,
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/4e4dbd6a/src/protocols/rdp/guac_ai/ai_service.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_service.c b/src/protocols/rdp/guac_ai/ai_service.c
index 945f039..2fbf2ac 100644
--- a/src/protocols/rdp/guac_ai/ai_service.c
+++ b/src/protocols/rdp/guac_ai/ai_service.c
@@ -95,7 +95,7 @@ static void guac_rdp_ai_handle_data(guac_client* client,
}
-#if LEGACY_IWTSVIRTUALCHANNELCALLBACK
+#ifdef LEGACY_IWTSVIRTUALCHANNELCALLBACK
/**
* Callback which is invoked when data is received along a connection to the
* AUDIO_INPUT plugin. This callback is specific to FreeRDP 1.1 and older.
[06/26] incubator-guacamole-server git commit: GUACAMOLE-25: Delay
sending of "ack" until RDP has opened the AUDIO_INPUT stream. Close audio
stream with another "ack" when RDP has closed the AUDIO_INPUT stream.
Posted by jm...@apache.org.
GUACAMOLE-25: Delay sending of "ack" until RDP has opened the AUDIO_INPUT stream. Close audio stream with another "ack" when RDP has closed the AUDIO_INPUT stream.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/46bdf069
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/46bdf069
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/46bdf069
Branch: refs/heads/master
Commit: 46bdf0692fca50d74c964701f163cc0df58ba76b
Parents: 5030c06
Author: Michael Jumper <mj...@apache.org>
Authored: Mon May 2 00:11:38 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/audio_input.c | 97 ++++++++++++++++++++++++++++++++++--
src/protocols/rdp/audio_input.h | 39 +++++++++++++++
2 files changed, 131 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/46bdf069/src/protocols/rdp/audio_input.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.c b/src/protocols/rdp/audio_input.c
index 8839d35..93c492b 100644
--- a/src/protocols/rdp/audio_input.c
+++ b/src/protocols/rdp/audio_input.c
@@ -30,19 +30,22 @@
#include <guacamole/user.h>
#include <stdlib.h>
+#include <pthread.h>
int guac_rdp_audio_handler(guac_user* user, guac_stream* stream,
char* mimetype) {
+ guac_client* client = user->client;
+ guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+
/* FIXME: Assuming mimetype of "audio/L16;rate=44100,channels=2" */
/* Init stream data */
stream->blob_handler = guac_rdp_audio_blob_handler;
stream->end_handler = guac_rdp_audio_end_handler;
- guac_protocol_send_ack(user->socket, stream,
- "OK", GUAC_PROTOCOL_STATUS_SUCCESS);
- guac_socket_flush(user->socket);
+ /* Associate stream with audio buffer */
+ guac_rdp_audio_buffer_set_stream(rdp_client->audio_input, user, stream);
return 0;
@@ -83,13 +86,72 @@ void guac_rdp_audio_load_plugin(rdpContext* context) {
}
guac_rdp_audio_buffer* guac_rdp_audio_buffer_alloc() {
- return calloc(1, sizeof(guac_rdp_audio_buffer));
+ guac_rdp_audio_buffer* buffer = calloc(1, sizeof(guac_rdp_audio_buffer));
+ pthread_mutex_init(&(buffer->lock), NULL);
+ return buffer;
+}
+
+/**
+ * Sends an "ack" instruction over the socket associated with the Guacamole
+ * stream over which audio data is being received. The "ack" instruction will
+ * only be sent if the Guacamole audio stream has been established (through
+ * receipt of an "audio" instruction), is still open (has not received an "end"
+ * instruction nor been associated with an "ack" having an error code), and is
+ * associated with an active RDP AUDIO_INPUT channel.
+ *
+ * @param audio_buffer
+ * The audio buffer associated with the guac_stream for which the "ack"
+ * instruction should be sent, if any. If there is no associated
+ * guac_stream, this function has no effect.
+ *
+ * @param message
+ * An arbitrary human-readable message to send along with the "ack".
+ *
+ * @param status
+ * The Guacamole protocol status code to send with the "ack". This should
+ * be GUAC_PROTOCOL_STATUS_SUCCESS if the audio stream has been set up
+ * successfully or GUAC_PROTOCOL_STATUS_RESOURCE_CLOSED if the audio stream
+ * has been closed (but may usable again if reopened).
+ */
+static void guac_rdp_audio_buffer_ack(guac_rdp_audio_buffer* audio_buffer,
+ const char* message, guac_protocol_status status) {
+
+ guac_user* user = audio_buffer->user;
+ guac_stream* stream = audio_buffer->stream;
+
+ /* Do not send ack unless both sides of the audio stream are ready */
+ if (user == NULL || stream == NULL || audio_buffer->packet == NULL)
+ return;
+
+ /* Send ack instruction */
+ guac_protocol_send_ack(user->socket, stream, message, status);
+ guac_socket_flush(user->socket);
+
+}
+
+void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
+ guac_user* user, guac_stream* stream) {
+
+ pthread_mutex_lock(&(audio_buffer->lock));
+
+ /* Associate received stream */
+ audio_buffer->user = user;
+ audio_buffer->stream = stream;
+
+ /* Acknowledge stream creation (if buffer is ready to receive) */
+ guac_rdp_audio_buffer_ack(audio_buffer,
+ "OK", GUAC_PROTOCOL_STATUS_SUCCESS);
+
+ pthread_mutex_unlock(&(audio_buffer->lock));
+
}
void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
int packet_size, guac_rdp_audio_buffer_flush_handler* flush_handler,
void* data) {
+ pthread_mutex_lock(&(audio_buffer->lock));
+
/* Reset buffer state to provided values */
audio_buffer->bytes_written = 0;
audio_buffer->packet_size = packet_size;
@@ -100,14 +162,24 @@ void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
free(audio_buffer->packet);
audio_buffer->packet = malloc(packet_size);
+ /* Acknowledge stream creation (if stream is ready to receive) */
+ guac_rdp_audio_buffer_ack(audio_buffer,
+ "OK", GUAC_PROTOCOL_STATUS_SUCCESS);
+
+ pthread_mutex_unlock(&(audio_buffer->lock));
+
}
void guac_rdp_audio_buffer_write(guac_rdp_audio_buffer* audio_buffer,
char* buffer, int length) {
+ pthread_mutex_lock(&(audio_buffer->lock));
+
/* Ignore packet if there is no buffer */
- if (audio_buffer->packet_size == 0 || audio_buffer->packet == NULL)
+ if (audio_buffer->packet_size == 0 || audio_buffer->packet == NULL) {
+ pthread_mutex_unlock(&(audio_buffer->lock));
return;
+ }
/* Continuously write packets until no data remains */
while (length > 0) {
@@ -146,10 +218,22 @@ void guac_rdp_audio_buffer_write(guac_rdp_audio_buffer* audio_buffer,
} /* end packet write loop */
+ pthread_mutex_unlock(&(audio_buffer->lock));
+
}
void guac_rdp_audio_buffer_end(guac_rdp_audio_buffer* audio_buffer) {
+ pthread_mutex_lock(&(audio_buffer->lock));
+
+ /* The stream is now closed */
+ guac_rdp_audio_buffer_ack(audio_buffer,
+ "CLOSED", GUAC_PROTOCOL_STATUS_RESOURCE_CLOSED);
+
+ /* Unset user and stream */
+ audio_buffer->user = NULL;
+ audio_buffer->stream = NULL;
+
/* Reset buffer state */
audio_buffer->bytes_written = 0;
audio_buffer->packet_size = 0;
@@ -159,9 +243,12 @@ void guac_rdp_audio_buffer_end(guac_rdp_audio_buffer* audio_buffer) {
free(audio_buffer->packet);
audio_buffer->packet = NULL;
+ pthread_mutex_unlock(&(audio_buffer->lock));
+
}
void guac_rdp_audio_buffer_free(guac_rdp_audio_buffer* audio_buffer) {
+ pthread_mutex_destroy(&(audio_buffer->lock));
free(audio_buffer->packet);
free(audio_buffer);
}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/46bdf069/src/protocols/rdp/audio_input.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.h b/src/protocols/rdp/audio_input.h
index c89de15..776f0a5 100644
--- a/src/protocols/rdp/audio_input.h
+++ b/src/protocols/rdp/audio_input.h
@@ -23,8 +23,11 @@
#include "config.h"
#include <freerdp/freerdp.h>
+#include <guacamole/stream.h>
#include <guacamole/user.h>
+#include <pthread.h>
+
/**
* Handler which is invoked when a guac_rdp_audio_buffer's internal packet
* buffer has reached capacity and must be flushed.
@@ -52,6 +55,24 @@ typedef void guac_rdp_audio_buffer_flush_handler(char* buffer, int length,
typedef struct guac_rdp_audio_buffer {
/**
+ * Lock which is acquired/released to ensure accesses to the audio buffer
+ * are atomic.
+ */
+ pthread_mutex_t lock;
+
+ /**
+ * The user from which this audio buffer will receive data. If no user has
+ * yet opened an associated audio stream, this will be NULL.
+ */
+ guac_user* user;
+
+ /**
+ * The stream from which this audio buffer will receive data. If no user
+ * has yet opened an associated audio stream, this will be NULL.
+ */
+ guac_stream* stream;
+
+ /**
* The size that each audio packet must be, in bytes. The packet buffer
* within this structure will be at least this size.
*/
@@ -92,6 +113,24 @@ typedef struct guac_rdp_audio_buffer {
guac_rdp_audio_buffer* guac_rdp_audio_buffer_alloc();
/**
+ * Associates the given audio buffer with the underlying audio stream which
+ * has been received from the given Guacamole user. Once both the Guacamole
+ * audio stream and the RDP audio stream are ready, an appropriate "ack"
+ * message will be sent.
+ *
+ * @param audio_buffer
+ * The audio buffer associated with the audio stream just received.
+ *
+ * @param user
+ * The Guacamole user that created the audio stream.
+ *
+ * @param stream
+ * The guac_stream object representing the audio stream.
+ */
+void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
+ guac_user* user, guac_stream* stream);
+
+/**
* Begins handling of audio data received via guac_rdp_audio_buffer_write() and
* allocates the necessary underlying packet buffer. Audio packets of exactly
* packet_size bytes will be flushed as available using the provided
[17/26] incubator-guacamole-server git commit: GUACAMOLE-25: Support
FreeRDP stable-1.0 and compatible.
Posted by jm...@apache.org.
GUACAMOLE-25: Support FreeRDP stable-1.0 and compatible.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/8ccf61e6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/8ccf61e6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/8ccf61e6
Branch: refs/heads/master
Commit: 8ccf61e6b1d9198b073b17f5bafe96e12ca65c06
Parents: f1d4393
Author: Michael Jumper <mj...@apache.org>
Authored: Mon May 9 22:23:46 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:29 2016 -0700
----------------------------------------------------------------------
configure.ac | 9 ++++++++
src/protocols/rdp/dvc.c | 33 +++++++++++++++++++++++++++--
src/protocols/rdp/guac_ai/ai_service.c | 6 ++++++
3 files changed, 46 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/8ccf61e6/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 7dec629..446a36e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -579,6 +579,15 @@ then
[#include <freerdp/channels/channels.h>])
fi
+# Availability of ADDIN_ARGV structure for configuring plugins
+if test "x${have_freerdp}" = "xyes"
+then
+ AC_CHECK_TYPE([ADDIN_ARGV],
+ [AC_DEFINE([HAVE_ADDIN_ARGV],,
+ [Whether the ADDIN_ARGV type is available])],,
+ [#include <freerdp/settings.h>])
+fi
+
#
# FreeRDP: WinPR
#
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/8ccf61e6/src/protocols/rdp/dvc.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/dvc.c b/src/protocols/rdp/dvc.c
index 0f0e835..10c65d7 100644
--- a/src/protocols/rdp/dvc.c
+++ b/src/protocols/rdp/dvc.c
@@ -117,6 +117,14 @@ int guac_rdp_load_drdynvc(rdpContext* context, guac_rdp_dvc_list* list) {
if (list->channel_count == 0)
return 0;
+#ifndef HAVE_ADDIN_ARGV
+ /* Allocate plugin data array */
+ RDP_PLUGIN_DATA* all_plugin_data =
+ calloc(list->channel_count + 1, sizeof(RDP_PLUGIN_DATA));
+
+ RDP_PLUGIN_DATA* current_plugin_data = all_plugin_data;
+#endif
+
/* For each channel */
guac_common_list_element* current = list->channels->head;
while (current != NULL) {
@@ -135,20 +143,41 @@ int guac_rdp_load_drdynvc(rdpContext* context, guac_rdp_dvc_list* list) {
guac_client_log(client, GUAC_LOG_DEBUG,
"Registering DVC plugin \"%s\"", dvc->argv[0]);
+#ifdef HAVE_ADDIN_ARGV
/* Register plugin with FreeRDP */
ADDIN_ARGV* args = malloc(sizeof(ADDIN_ARGV));
args->argc = dvc->argc;
args->argv = dvc->argv;
freerdp_dynamic_channel_collection_add(context->settings, args);
+#else
+ /* Copy all arguments */
+ for (int i = 0; i < dvc->argc; i++)
+ current_plugin_data->data[i] = dvc->argv[i];
+
+ /* Store size of entry */
+ current_plugin_data->size = sizeof(*current_plugin_data);
+
+ /* Advance to next set of plugin data */
+ current_plugin_data++;
+#endif
/* Rely on FreeRDP to free argv storage */
dvc->argv = NULL;
}
+#ifdef HAVE_ADDIN_ARGV
+ /* Load virtual channel management plugin */
+ return freerdp_channels_load_plugin(channels, context->instance->settings,
+ "drdynvc", context->instance->settings);
+#else
+ /* Terminate with empty RDP_PLUGIN_DATA element */
+ current_plugin_data->size = 0;
+
/* Load virtual channel management plugin */
- return freerdp_channels_load_plugin(channels, context->settings,
- "drdynvc", context->settings);
+ return freerdp_channels_load_plugin(channels, context->instance->settings,
+ "drdynvc", all_plugin_data);
+#endif
}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/8ccf61e6/src/protocols/rdp/guac_ai/ai_service.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_service.c b/src/protocols/rdp/guac_ai/ai_service.c
index 2fbf2ac..5058ea0 100644
--- a/src/protocols/rdp/guac_ai/ai_service.c
+++ b/src/protocols/rdp/guac_ai/ai_service.c
@@ -314,8 +314,14 @@ static int guac_rdp_ai_terminated(IWTSPlugin* plugin) {
*/
int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) {
+ /* Pull guac_client from arguments */
+#ifdef HAVE_ADDIN_ARGV
ADDIN_ARGV* args = pEntryPoints->GetPluginData(pEntryPoints);
guac_client* client = (guac_client*) guac_rdp_string_to_ptr(args->argv[1]);
+#else
+ RDP_PLUGIN_DATA* data = pEntryPoints->GetPluginData(pEntryPoints);
+ guac_client* client = (guac_client*) guac_rdp_string_to_ptr(data->data[1]);
+#endif
/* Pull previously-allocated plugin */
guac_rdp_ai_plugin* ai_plugin = (guac_rdp_ai_plugin*)
[05/26] incubator-guacamole-server git commit: GUACAMOLE-25: Convert
guac_client pointer to/from a string for sake of FreeRDP's DVC API.
Posted by jm...@apache.org.
GUACAMOLE-25: Convert guac_client pointer to/from a string for sake of FreeRDP's DVC API.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/36cc9f49
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/36cc9f49
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/36cc9f49
Branch: refs/heads/master
Commit: 36cc9f492fb0424d32aaa041383d8e8ab8e3cd90
Parents: 21ab9d7
Author: Michael Jumper <mj...@apache.org>
Authored: Sat Apr 16 17:13:39 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/Makefile.am | 5 ++-
src/protocols/rdp/audio_input.c | 5 +++
src/protocols/rdp/guac_ai/ai_service.c | 7 ++--
src/protocols/rdp/ptr_string.c | 55 ++++++++++++++++++++++++++++
src/protocols/rdp/ptr_string.h | 57 +++++++++++++++++++++++++++++
5 files changed, 124 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/36cc9f49/src/protocols/rdp/Makefile.am
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/Makefile.am b/src/protocols/rdp/Makefile.am
index 44f248a..0ac074a 100644
--- a/src/protocols/rdp/Makefile.am
+++ b/src/protocols/rdp/Makefile.am
@@ -27,6 +27,7 @@ libguac_client_rdp_la_SOURCES = \
audio_input.c \
client.c \
input.c \
+ ptr_string.c \
rdp.c \
rdp_bitmap.c \
rdp_cliprdr.c \
@@ -46,7 +47,8 @@ libguac_client_rdp_la_SOURCES = \
user.c
guacai_sources = \
- guac_ai/ai_service.c
+ guac_ai/ai_service.c \
+ ptr_string.c
guacsvc_sources = \
guac_svc/svc_service.c \
@@ -87,6 +89,7 @@ noinst_HEADERS = \
audio_input.h \
client.h \
input.h \
+ ptr_string.h \
rdp.h \
rdp_bitmap.h \
rdp_cliprdr.h \
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/36cc9f49/src/protocols/rdp/audio_input.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.c b/src/protocols/rdp/audio_input.c
index 8233184..b5c3f96 100644
--- a/src/protocols/rdp/audio_input.c
+++ b/src/protocols/rdp/audio_input.c
@@ -19,6 +19,8 @@
#include "config.h"
#include "audio_input.h"
+#include "ptr_string.h"
+#include "rdp.h"
#include <freerdp/freerdp.h>
#include <freerdp/channels/channels.h>
@@ -63,11 +65,14 @@ int guac_rdp_audio_end_handler(guac_user* user, guac_stream* stream) {
void guac_rdp_audio_load_plugin(rdpContext* context) {
+ guac_client* client = ((rdp_freerdp_context*) context)->client;
+
/* Add "AUDIO_INPUT" channel */
ADDIN_ARGV* args = malloc(sizeof(ADDIN_ARGV));
args->argc = 1;
args->argv = malloc(sizeof(char**) * 1);
args->argv[0] = strdup("guacai");
+ args->argv[1] = guac_rdp_ptr_to_string(client);
freerdp_dynamic_channel_collection_add(context->settings, args);
}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/36cc9f49/src/protocols/rdp/guac_ai/ai_service.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_service.c b/src/protocols/rdp/guac_ai/ai_service.c
index 15490a0..c6ff47b 100644
--- a/src/protocols/rdp/guac_ai/ai_service.c
+++ b/src/protocols/rdp/guac_ai/ai_service.c
@@ -20,6 +20,7 @@
#include "config.h"
#include "ai_service.h"
+#include "ptr_string.h"
#include "rdp.h"
#include <stdlib.h>
@@ -41,10 +42,8 @@
*/
int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) {
- rdpSettings* settings = pEntryPoints->GetRdpSettings(pEntryPoints);
- freerdp* instance = settings->instance;
- rdpContext* context = instance->context;
- guac_client* client = ((rdp_freerdp_context*) context)->client;
+ ADDIN_ARGV* args = pEntryPoints->GetPluginData(pEntryPoints);
+ guac_client* client = (guac_client*) guac_rdp_string_to_ptr(args->argv[1]);
/* STUB */
guac_client_log(client, GUAC_LOG_DEBUG,
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/36cc9f49/src/protocols/rdp/ptr_string.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/ptr_string.c b/src/protocols/rdp/ptr_string.c
new file mode 100644
index 0000000..1e79121
--- /dev/null
+++ b/src/protocols/rdp/ptr_string.c
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+#include "ptr_string.h"
+
+#include <guacamole/client.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/**
+ * The maximum number of bytes required to represent a pointer printed using
+ * printf()'s "%p". This will be the size of the hex prefix ("0x"), null
+ * terminator, plus two bytes for every byte required by a pointer.
+ */
+#define GUAC_RDP_PTR_STRING_LENGTH (sizeof("0x") + (sizeof(void*) * 2))
+
+char* guac_rdp_ptr_to_string(void* data) {
+
+ /* Convert pointer to string */
+ char* str = malloc(GUAC_RDP_PTR_STRING_LENGTH);
+ sprintf(str, "%p", data);
+
+ return str;
+
+}
+
+void* guac_rdp_string_to_ptr(const char* str) {
+
+ void* data;
+
+ /* Convert string to pointer */
+ sscanf(str, "%p", &data);
+
+ return data;
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/36cc9f49/src/protocols/rdp/ptr_string.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/ptr_string.h b/src/protocols/rdp/ptr_string.h
new file mode 100644
index 0000000..6b27721
--- /dev/null
+++ b/src/protocols/rdp/ptr_string.h
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef GUAC_RDP_PTR_STRING_H
+#define GUAC_RDP_PTR_STRING_H
+
+#include "config.h"
+
+#include <guacamole/client.h>
+
+/**
+ * Converts the given string back into a void pointer. The string MUST have
+ * been produced via guac_rdp_ptr_to_string().
+ *
+ * @param str
+ * The string to convert back to a pointer.
+ *
+ * @return
+ * The pointer value of the given string, as originally passed to
+ * guac_rdp_ptr_to_string().
+ */
+void* guac_rdp_string_to_ptr(const char* str);
+
+/**
+ * Converts a void pointer into a string representation, safe for use with
+ * parts of the FreeRDP API which provide only for passing arbitrary strings,
+ * despite being within the same memory area. The returned string must
+ * eventually be freed with a call to free().
+ *
+ * @param data
+ * The void pointer to convert to a string.
+ *
+ * @return
+ * A newly-allocated string containing the string representation of the
+ * given void pointer. This string must eventually be freed with a call to
+ * free().
+ */
+char* guac_rdp_ptr_to_string(void* data);
+
+#endif
+
[23/26] incubator-guacamole-server git commit: GUACAMOLE-25: Resample
received audio as necessary.
Posted by jm...@apache.org.
GUACAMOLE-25: Resample received audio as necessary.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/0be04ea5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/0be04ea5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/0be04ea5
Branch: refs/heads/master
Commit: 0be04ea54d0ce8dea9c57d29da15249b7c2db1f3
Parents: 1c2890b
Author: Michael Jumper <mj...@apache.org>
Authored: Wed Jun 1 15:25:42 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed Jun 1 15:25:42 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/audio_input.c | 131 ++++++++++++++++++++++++++++++-----
src/protocols/rdp/audio_input.h | 12 ++++
2 files changed, 126 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/0be04ea5/src/protocols/rdp/audio_input.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.c b/src/protocols/rdp/audio_input.c
index 0eb757d..eefb231 100644
--- a/src/protocols/rdp/audio_input.c
+++ b/src/protocols/rdp/audio_input.c
@@ -30,6 +30,7 @@
#include <guacamole/stream.h>
#include <guacamole/user.h>
+#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <pthread.h>
@@ -246,6 +247,9 @@ void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
audio_buffer->in_format.channels = channels;
audio_buffer->in_format.bps = bps;
+ /* Reset input counter */
+ audio_buffer->total_bytes_received = 0;
+
/* Acknowledge stream creation (if buffer is ready to receive) */
guac_rdp_audio_buffer_ack(audio_buffer,
"OK", GUAC_PROTOCOL_STATUS_SUCCESS);
@@ -270,6 +274,9 @@ void guac_rdp_audio_buffer_set_output(guac_rdp_audio_buffer* audio_buffer,
audio_buffer->out_format.channels = channels;
audio_buffer->out_format.bps = bps;
+ /* Reset output counter */
+ audio_buffer->total_bytes_sent = 0;
+
pthread_mutex_unlock(&(audio_buffer->lock));
}
@@ -302,12 +309,99 @@ void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
}
+/**
+ * Reads a single sample from the given buffer of data, using the input
+ * format defined within the given audio buffer. Each read sample is
+ * translated to a signed 16-bit value, even if the input format is 8-bit.
+ * The offset into the given buffer will be determined according to the
+ * input and output formats, the number of bytes sent thus far, and the
+ * number of bytes received (excluding the contents of the buffer).
+ *
+ * @param audio_buffer
+ * The audio buffer dictating the format of the given data buffer, as
+ * well as the offset from which the sample should be read.
+ *
+ * @param buffer
+ * The buffer of raw PCM audio data from which the sample should be read.
+ * This buffer MUST NOT contain data already taken into account by the
+ * audio buffer's total_bytes_received counter.
+ *
+ * @param length
+ * The number of bytes within the given buffer of PCM data.
+ *
+ * @param sample
+ * A pointer to the int16_t in which the read sample should be stored. If
+ * the input format is 8-bit, the sample will be shifted left by 8 bits
+ * to produce a 16-bit sample.
+ *
+ * @return
+ * Non-zero if a sample was successfully read, zero if no data remains
+ * within the given buffer that has not already been mapped to an
+ * output sample.
+ */
+static int guac_rdp_audio_buffer_read_sample(
+ guac_rdp_audio_buffer* audio_buffer, const char* buffer, int length,
+ int16_t* sample) {
+
+ int in_bps = audio_buffer->in_format.bps;
+ int in_rate = audio_buffer->in_format.rate;
+ int in_channels = audio_buffer->in_format.channels;
+
+ int out_bps = audio_buffer->out_format.bps;
+ int out_rate = audio_buffer->out_format.rate;
+ int out_channels = audio_buffer->out_format.channels;
+
+ /* Calculate position within audio output */
+ int current_sample = audio_buffer->total_bytes_sent / out_bps;
+ int current_frame = current_sample / out_channels;
+ int current_channel = current_sample % out_channels;
+
+ /* Map output channel to input channel */
+ if (current_channel >= in_channels)
+ current_channel = in_channels - 1;
+
+ /* Transform output position to input position */
+ current_frame = (int) current_frame * ((double) in_rate / out_rate);
+ current_sample = current_frame * in_channels + current_channel;
+
+ /* Calculate offset within given buffer from absolute input position */
+ int offset = current_sample * in_bps
+ - audio_buffer->total_bytes_received;
+
+ /* It should be impossible for the offset to ever go negative */
+ assert(offset >= 0);
+
+ /* Apply offset to buffer */
+ buffer += offset;
+ length -= offset;
+
+ /* Read only if sufficient data is present in the given buffer */
+ if (length < in_bps)
+ return 0;
+
+ /* Simply read sample directly if input is 16-bit */
+ if (in_bps == 2) {
+ *sample = *((int16_t*) buffer);
+ return 1;
+ }
+
+ /* Translate to 16-bit if input is 8-bit */
+ if (in_bps == 1) {
+ *sample = *buffer << 8;
+ return 1;
+ }
+
+ /* Accepted audio formats are required to be 8- or 16-bit */
+ return 0;
+
+}
+
void guac_rdp_audio_buffer_write(guac_rdp_audio_buffer* audio_buffer,
char* buffer, int length) {
- pthread_mutex_lock(&(audio_buffer->lock));
+ int16_t sample;
- /* FIXME: Assuming mimetype of "audio/L16;rate=44100,channels=2" */
+ pthread_mutex_lock(&(audio_buffer->lock));
/* Ignore packet if there is no buffer */
if (audio_buffer->packet_size == 0 || audio_buffer->packet == NULL) {
@@ -315,27 +409,27 @@ void guac_rdp_audio_buffer_write(guac_rdp_audio_buffer* audio_buffer,
return;
}
+ int out_bps = audio_buffer->out_format.bps;
+
/* Continuously write packets until no data remains */
- while (length > 0) {
+ while (guac_rdp_audio_buffer_read_sample(audio_buffer,
+ buffer, length, &sample) > 0) {
- /* Calculate ideal size of chunk based on available space */
- int chunk_size = audio_buffer->packet_size
- - audio_buffer->bytes_written;
+ char* current = audio_buffer->packet + audio_buffer->bytes_written;
- /* Shrink chunk size if insufficient bytes are provided */
- if (length < chunk_size)
- chunk_size = length;
+ /* Store as 16-bit or 8-bit, depending on output format */
+ if (out_bps == 2)
+ *((int16_t*) current) = sample;
+ else if (out_bps == 1)
+ *current = sample >> 8;
- /* Append buffer */
- memcpy(audio_buffer->packet + audio_buffer->bytes_written,
- buffer, chunk_size);
+ /* Accepted audio formats are required to be 8- or 16-bit */
+ else
+ assert(0);
/* Update byte counters */
- length -= chunk_size;
- audio_buffer->bytes_written += chunk_size;
-
- /* Advance to next chunk */
- buffer += chunk_size;
+ audio_buffer->bytes_written += out_bps;
+ audio_buffer->total_bytes_sent += out_bps;
/* Invoke flush handler if full */
if (audio_buffer->bytes_written == audio_buffer->packet_size) {
@@ -352,6 +446,9 @@ void guac_rdp_audio_buffer_write(guac_rdp_audio_buffer* audio_buffer,
} /* end packet write loop */
+ /* Track current position in audio stream */
+ audio_buffer->total_bytes_received += length;
+
pthread_mutex_unlock(&(audio_buffer->lock));
}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/0be04ea5/src/protocols/rdp/audio_input.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.h b/src/protocols/rdp/audio_input.h
index 87eee9a..bd84fe1 100644
--- a/src/protocols/rdp/audio_input.h
+++ b/src/protocols/rdp/audio_input.h
@@ -122,6 +122,18 @@ typedef struct guac_rdp_audio_buffer {
int bytes_written;
/**
+ * The total number of bytes having ever been received by the Guacamole
+ * server for the current audio stream.
+ */
+ int total_bytes_received;
+
+ /**
+ * The total number of bytes having ever been sent to the RDP server for
+ * the current audio stream.
+ */
+ int total_bytes_sent;
+
+ /**
* All audio data being prepared for sending to the AUDIO_INPUT channel.
*/
char* packet;
[09/26] incubator-guacamole-server git commit: GUACAMOLE-25: Set
AudioCapture flag if audio input is enabled.
Posted by jm...@apache.org.
GUACAMOLE-25: Set AudioCapture flag if audio input is enabled.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/4fdcfebf
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/4fdcfebf
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/4fdcfebf
Branch: refs/heads/master
Commit: 4fdcfebf2548161d771e430bead6ce7c29a3fc98
Parents: 36cc9f4
Author: Michael Jumper <mj...@apache.org>
Authored: Sat Apr 16 21:42:31 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
configure.ac | 12 ++++++++++++
src/protocols/rdp/rdp_settings.c | 11 +++++++++++
2 files changed, 23 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/4fdcfebf/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index edd49b8..485c10d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -436,6 +436,7 @@ then
have_freerdp=yes
legacy_freerdp_extensions=no
rdpsettings_interface=unknown
+ rdpsettings_audiocapture=yes
rdpsettings_audioplayback=yes
rdpsettings_deviceredirection=yes
freerdp_interface=unknown
@@ -686,6 +687,11 @@ then
[rdpsettings_audioplayback=no],
[[#include <freerdp/freerdp.h>]])
+ # Legacy interface may not have AudioCapture settings
+ AC_CHECK_MEMBERS([rdpSettings.audio_capture],,
+ [rdpsettings_audiocapture=no],
+ [[#include <freerdp/freerdp.h>]])
+
# Legacy interface may not have DeviceRedirection settings
AC_CHECK_MEMBERS([rdpSettings.device_redirection],,
[rdpsettings_deviceredirection=no],
@@ -707,6 +713,12 @@ if test "x${have_freerdp}" = "xyes" -a "x${rdpsettings_audioplayback}" = "xyes";
[Whether the rdpSettings structure has AudioPlayback settings])
fi
+# Activate audio capture settings if present
+if test "x${have_freerdp}" = "xyes" -a "x${rdpsettings_audiocapture}" = "xyes"; then
+ AC_DEFINE([HAVE_RDPSETTINGS_AUDIOCAPTURE],,
+ [Whether the rdpSettings structure has AudioCapture settings])
+fi
+
# Activate device redirection settings if present
if test "x${have_freerdp}" = "xyes" -a "x${rdpsettings_deviceredirection}" = "xyes"; then
AC_DEFINE([HAVE_RDPSETTINGS_DEVICEREDIRECTION],,
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/4fdcfebf/src/protocols/rdp/rdp_settings.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_settings.c b/src/protocols/rdp/rdp_settings.c
index 4f9343c..82af859 100644
--- a/src/protocols/rdp/rdp_settings.c
+++ b/src/protocols/rdp/rdp_settings.c
@@ -995,6 +995,17 @@ void guac_rdp_push_settings(guac_rdp_settings* guac_settings, freerdp* rdp) {
#endif
#endif
+ /* Audio capture */
+#ifdef LEGACY_RDPSETTINGS
+#ifdef HAVE_RDPSETTINGS_AUDIOCAPTURE
+ rdp_settings->audio_capture = guac_settings->enable_audio_input;
+#endif
+#else
+#ifdef HAVE_RDPSETTINGS_AUDIOCAPTURE
+ rdp_settings->AudioCapture = guac_settings->enable_audio_input;
+#endif
+#endif
+
/* Device redirection */
#ifdef LEGACY_RDPSETTINGS
#ifdef HAVE_RDPSETTINGS_DEVICEREDIRECTION
[02/26] incubator-guacamole-server git commit: GUACAMOLE-25: Abstract
DVC management away from FreeRDP for sake of API compatibility.
Posted by jm...@apache.org.
GUACAMOLE-25: Abstract DVC management away from FreeRDP for sake of API compatibility.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/13933584
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/13933584
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/13933584
Branch: refs/heads/master
Commit: 13933584691f20c7d88294ac41aa6dd4c4f8bf04
Parents: 46bdf06
Author: Michael Jumper <mj...@apache.org>
Authored: Mon May 9 18:20:04 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/Makefile.am | 2 +
src/protocols/rdp/audio_input.c | 10 +--
src/protocols/rdp/audio_input.h | 3 +-
src/protocols/rdp/dvc.c | 154 +++++++++++++++++++++++++++++++++++
src/protocols/rdp/dvc.h | 138 +++++++++++++++++++++++++++++++
src/protocols/rdp/rdp.c | 44 +++++-----
src/protocols/rdp/rdp_disp.c | 11 +--
src/protocols/rdp/rdp_disp.h | 3 +-
8 files changed, 323 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/13933584/src/protocols/rdp/Makefile.am
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/Makefile.am b/src/protocols/rdp/Makefile.am
index f76c33e..3669b3d 100644
--- a/src/protocols/rdp/Makefile.am
+++ b/src/protocols/rdp/Makefile.am
@@ -26,6 +26,7 @@ libguac_client_rdp_la_SOURCES = \
_generated_keymaps.c \
audio_input.c \
client.c \
+ dvc.c \
input.c \
ptr_string.c \
rdp.c \
@@ -91,6 +92,7 @@ noinst_HEADERS = \
guac_svc/svc_service.h \
audio_input.h \
client.h \
+ dvc.h \
input.h \
ptr_string.h \
rdp.h \
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/13933584/src/protocols/rdp/audio_input.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.c b/src/protocols/rdp/audio_input.c
index 93c492b..f2fd84a 100644
--- a/src/protocols/rdp/audio_input.c
+++ b/src/protocols/rdp/audio_input.c
@@ -19,6 +19,7 @@
#include "config.h"
#include "audio_input.h"
+#include "dvc.h"
#include "ptr_string.h"
#include "rdp.h"
@@ -71,17 +72,12 @@ int guac_rdp_audio_end_handler(guac_user* user, guac_stream* stream) {
}
-void guac_rdp_audio_load_plugin(rdpContext* context) {
+void guac_rdp_audio_load_plugin(rdpContext* context, guac_rdp_dvc_list* list) {
guac_client* client = ((rdp_freerdp_context*) context)->client;
/* Add "AUDIO_INPUT" channel */
- ADDIN_ARGV* args = malloc(sizeof(ADDIN_ARGV));
- args->argc = 2;
- args->argv = malloc(sizeof(char**) * 2);
- args->argv[0] = strdup("guacai");
- args->argv[1] = guac_rdp_ptr_to_string(client);
- freerdp_dynamic_channel_collection_add(context->settings, args);
+ guac_rdp_dvc_list_add(list, "guacai", guac_rdp_ptr_to_string(client), NULL);
}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/13933584/src/protocols/rdp/audio_input.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.h b/src/protocols/rdp/audio_input.h
index 776f0a5..e13b41e 100644
--- a/src/protocols/rdp/audio_input.h
+++ b/src/protocols/rdp/audio_input.h
@@ -21,6 +21,7 @@
#define GUAC_RDP_AUDIO_INPUT_H
#include "config.h"
+#include "dvc.h"
#include <freerdp/freerdp.h>
#include <guacamole/stream.h>
@@ -213,7 +214,7 @@ guac_user_end_handler guac_rdp_audio_end_handler;
* @param context
* The rdpContext associated with the active RDP session.
*/
-void guac_rdp_audio_load_plugin(rdpContext* context);
+void guac_rdp_audio_load_plugin(rdpContext* context, guac_rdp_dvc_list* list);
#endif
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/13933584/src/protocols/rdp/dvc.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/dvc.c b/src/protocols/rdp/dvc.c
new file mode 100644
index 0000000..0f0e835
--- /dev/null
+++ b/src/protocols/rdp/dvc.c
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+#include "dvc.h"
+#include "guac_list.h"
+#include "rdp.h"
+
+#include <freerdp/channels/channels.h>
+#include <freerdp/freerdp.h>
+#include <guacamole/client.h>
+
+#include <assert.h>
+#include <stdarg.h>
+
+guac_rdp_dvc_list* guac_rdp_dvc_list_alloc() {
+
+ guac_rdp_dvc_list* list = malloc(sizeof(guac_rdp_dvc_list));
+
+ /* Initialize with empty backing list */
+ list->channels = guac_common_list_alloc();
+ list->channel_count = 0;
+
+ return list;
+
+}
+
+void guac_rdp_dvc_list_add(guac_rdp_dvc_list* list, const char* name, ...) {
+
+ va_list args;
+
+ guac_rdp_dvc* dvc = malloc(sizeof(guac_rdp_dvc));
+
+ va_start(args, name);
+
+ /* Count number of arguments (excluding terminating NULL) */
+ dvc->argc = 1;
+ while (va_arg(args, char*) != NULL)
+ dvc->argc++;
+
+ /* Reset va_list */
+ va_end(args);
+ va_start(args, name);
+
+ /* Copy argument values into DVC entry */
+ dvc->argv = malloc(sizeof(char*) * dvc->argc);
+ dvc->argv[0] = strdup(name);
+ int i;
+ for (i = 1; i < dvc->argc; i++)
+ dvc->argv[i] = strdup(va_arg(args, char*));
+
+ va_end(args);
+
+ /* Add entry to DVC list */
+ guac_common_list_add(list->channels, dvc);
+
+ /* Update channel count */
+ list->channel_count++;
+
+}
+
+void guac_rdp_dvc_list_free(guac_rdp_dvc_list* list) {
+
+ /* For each channel */
+ guac_common_list_element* current = list->channels->head;
+ while (current != NULL) {
+
+ /* Free arguments declaration for current channel */
+ guac_rdp_dvc* dvc = (guac_rdp_dvc*) current->data;
+
+ /* Free the underlying arguments list if not delegated to FreeRDP */
+ if (dvc->argv != NULL) {
+
+ /* Free each argument value */
+ for (int i = 0; i < dvc->argc; i++)
+ free(dvc->argv[i]);
+
+ free(dvc->argv);
+ }
+
+ free(dvc);
+
+ current = current->next;
+
+ }
+
+ /* Free underlying list */
+ guac_common_list_free(list->channels);
+
+ /* Free the DVC list itself */
+ free(list);
+
+}
+
+int guac_rdp_load_drdynvc(rdpContext* context, guac_rdp_dvc_list* list) {
+
+ guac_client* client = ((rdp_freerdp_context*) context)->client;
+ rdpChannels* channels = context->channels;
+
+ /* Skip if no channels will be loaded */
+ if (list->channel_count == 0)
+ return 0;
+
+ /* For each channel */
+ guac_common_list_element* current = list->channels->head;
+ while (current != NULL) {
+
+ /* Get channel arguments */
+ guac_rdp_dvc* dvc = (guac_rdp_dvc*) current->data;
+ current = current->next;
+
+ /* guac_rdp_dvc_list_add() guarantees at one argument */
+ assert(dvc->argc >= 1);
+
+ /* guac_rdp_load_drdynvc() MUST only be invoked once */
+ assert(dvc->argv != NULL);
+
+ /* Log registration of plugin for current channel */
+ guac_client_log(client, GUAC_LOG_DEBUG,
+ "Registering DVC plugin \"%s\"", dvc->argv[0]);
+
+ /* Register plugin with FreeRDP */
+ ADDIN_ARGV* args = malloc(sizeof(ADDIN_ARGV));
+ args->argc = dvc->argc;
+ args->argv = dvc->argv;
+ freerdp_dynamic_channel_collection_add(context->settings, args);
+
+ /* Rely on FreeRDP to free argv storage */
+ dvc->argv = NULL;
+
+ }
+
+ /* Load virtual channel management plugin */
+ return freerdp_channels_load_plugin(channels, context->settings,
+ "drdynvc", context->settings);
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/13933584/src/protocols/rdp/dvc.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/dvc.h b/src/protocols/rdp/dvc.h
new file mode 100644
index 0000000..02ca643
--- /dev/null
+++ b/src/protocols/rdp/dvc.h
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef GUAC_RDP_DVC_H
+#define GUAC_RDP_DVC_H
+
+#include "config.h"
+#include "guac_list.h"
+
+#include <freerdp/freerdp.h>
+
+/**
+ * The set of all arguments that should be passed to a given dynamic virtual
+ * channel plugin, including the name of that plugin.
+ */
+typedef struct guac_rdp_dvc {
+
+ /**
+ * The number of arguments in the argv array. This MUST be at least 1.
+ */
+ int argc;
+
+ /**
+ * The argument values being passed to the dynamic virtual channel plugin.
+ * The first entry in this array is always the name of the plugin. If
+ * guac_rdp_load_drdynvc() has been invoked, and freeing the argument
+ * values is being delegated to FreeRDP, this will be NULL.
+ */
+ char** argv;
+
+} guac_rdp_dvc;
+
+/**
+ * A list of dynamic virtual channels which should be provided to the DRDYNVC
+ * plugin once loaded via guac_rdp_load_drdynvc(). This interface exists purely
+ * to bridge incompatibilities between differing versions of FreeRDP and its
+ * DRDYNVC plugin. Any allocated guac_rdp_dvc_list is unlikely to be needed
+ * after the DRDYNVC plugin has been loaded.
+ */
+typedef struct guac_rdp_dvc_list {
+
+ /**
+ * Array of all dynamic virtual channels which should be registered with
+ * the DRDYNVC plugin once loaded. Each list element will point to a
+ * guac_rdp_dvc structure which must eventually be freed.
+ */
+ guac_common_list* channels;
+
+ /**
+ * The number of channels within the list.
+ */
+ int channel_count;
+
+} guac_rdp_dvc_list;
+
+/**
+ * Allocates a new, empty list of dynamic virtual channels. New channels may
+ * be added via guac_rdp_dvc_list_add(). The loading of those channels'
+ * associated plugins will be deferred until guac_rdp_load_drdynvc() is
+ * invoked.
+ *
+ * @return
+ * A newly-allocated, empty list of dynamic virtual channels.
+ */
+guac_rdp_dvc_list* guac_rdp_dvc_list_alloc();
+
+/**
+ * Adds the given dynamic virtual channel plugin name and associated arguments
+ * to the list. The provied arguments list is NOT optional and MUST be
+ * NULL-terminated, even if there are no arguments for the named dynamic
+ * virtual channel plugin. Though FreeRDP requires that the arguments for a
+ * dynamic virtual channel plugin contain the name of the plugin itself as the
+ * first argument, the name must be excluded from the arguments provided here.
+ * This function will automatically take care of adding the plugin name to
+ * the arguments.
+ *
+ * @param list
+ * The guac_rdp_dvc_list to which the given plugin name and arguments
+ * should be added, for later bulk registration via
+ * guac_rdp_load_drdynvc().
+ *
+ * @param name
+ * The name of the dynamic virtual channel plugin that should be given
+ * the provided arguments when guac_rdp_load_drdynvc() is invoked.
+ *
+ * @param ...
+ * The string (char*) arguments which should be passed to the dynamic
+ * virtual channel plugin when it is loaded via guac_rdp_load_drdynvc(),
+ * excluding the plugin name itself.
+ */
+void guac_rdp_dvc_list_add(guac_rdp_dvc_list* list, const char* name, ...);
+
+/**
+ * Frees the given list of dynamic virtual channels. Note that, while each
+ * individual entry within this list will be freed, it is partially up to
+ * FreeRDP to free the storage associated with the arguments passed to the
+ * virtual channels.
+ *
+ * @param list
+ * The list to free.
+ */
+void guac_rdp_dvc_list_free(guac_rdp_dvc_list* list);
+
+/**
+ * Loads FreeRDP's DRDYNVC plugin and registers the dynamic virtual channel
+ * plugins described by the given guac_rdp_dvc_list. This function MUST be
+ * invoked no more than once per RDP connection. Invoking this function
+ * multiple times, even if the guac_rdp_dvc_list is different each time, will
+ * result in undefined behavior.
+ *
+ * @param context
+ * The rdpContext associated with the RDP connection for which the DRDYNVC
+ * plugin should be loaded.
+ *
+ * @param list
+ * A guac_rdp_dvc_list describing the dynamic virtual channel plugins that
+ * should be registered with the DRDYNVC plugin, along with any arguments.
+ */
+int guac_rdp_load_drdynvc(rdpContext* context, guac_rdp_dvc_list* list);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/13933584/src/protocols/rdp/rdp.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c
index f461369..d515fb1 100644
--- a/src/protocols/rdp/rdp.c
+++ b/src/protocols/rdp/rdp.c
@@ -21,6 +21,7 @@
#include "audio_input.h"
#include "client.h"
+#include "dvc.h"
#include "guac_cursor.h"
#include "guac_display.h"
#include "guac_recording.h"
@@ -212,6 +213,7 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
rdpPrimaryUpdate* primary;
CLRCONV* clrconv;
+ guac_rdp_dvc_list* dvc_list = guac_rdp_dvc_list_alloc();
#ifdef HAVE_FREERDP_REGISTER_ADDIN_PROVIDER
/* Init FreeRDP add-in provider */
@@ -224,34 +226,17 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
(pChannelConnectedEventHandler) guac_rdp_channel_connected);
#endif
- /* Load DRDYNVC plugin if required */
- if (settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE
- || settings->enable_audio_input) {
-
- /* Load virtual channel management plugin */
- if (freerdp_channels_load_plugin(channels, instance->settings,
- "drdynvc", instance->settings))
- guac_client_log(client, GUAC_LOG_WARNING,
- "Failed to load drdynvc plugin. Display update and audio "
- "input support will be disabled.");
-
- /* Init display update plugin if "drdynvc" was loaded successfully */
- else {
#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
- /* Load "disp" plugin for display update */
- if (settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE)
- guac_rdp_disp_load_plugin(instance->context);
+ /* Load "disp" plugin for display update */
+ if (settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE)
+ guac_rdp_disp_load_plugin(instance->context, dvc_list);
#endif
- /* Load "AUDIO_INPUT" plugin for audio input*/
- if (settings->enable_audio_input) {
- rdp_client->audio_input = guac_rdp_audio_buffer_alloc();
- guac_rdp_audio_load_plugin(instance->context);
- }
-
- }
-
- } /* end if drdynvc required */
+ /* Load "AUDIO_INPUT" plugin for audio input*/
+ if (settings->enable_audio_input) {
+ rdp_client->audio_input = guac_rdp_audio_buffer_alloc();
+ guac_rdp_audio_load_plugin(instance->context, dvc_list);
+ }
/* Load clipboard plugin */
if (freerdp_channels_load_plugin(channels, instance->settings,
@@ -338,6 +323,15 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
}
+ /* Load DRDYNVC plugin if required */
+ if (guac_rdp_load_drdynvc(instance->context, dvc_list))
+ guac_client_log(client, GUAC_LOG_WARNING,
+ "Failed to load drdynvc plugin. Display update and audio "
+ "input support will be disabled.");
+
+ /* Dynamic virtual channel list is no longer needed */
+ guac_rdp_dvc_list_free(dvc_list);
+
/* Init color conversion structure */
clrconv = calloc(1, sizeof(CLRCONV));
clrconv->alpha = 1;
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/13933584/src/protocols/rdp/rdp_disp.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_disp.c b/src/protocols/rdp/rdp_disp.c
index eb14286..7c7e059 100644
--- a/src/protocols/rdp/rdp_disp.c
+++ b/src/protocols/rdp/rdp_disp.c
@@ -19,6 +19,7 @@
#include "config.h"
#include "client.h"
+#include "dvc.h"
#include "rdp.h"
#include "rdp_disp.h"
#include "rdp_settings.h"
@@ -54,20 +55,14 @@ void guac_rdp_disp_free(guac_rdp_disp* disp) {
free(disp);
}
-void guac_rdp_disp_load_plugin(rdpContext* context) {
+void guac_rdp_disp_load_plugin(rdpContext* context, guac_rdp_dvc_list* list) {
-#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
#ifdef HAVE_RDPSETTINGS_SUPPORTDISPLAYCONTROL
context->settings->SupportDisplayControl = TRUE;
#endif
/* Add "disp" channel */
- ADDIN_ARGV* args = malloc(sizeof(ADDIN_ARGV));
- args->argc = 1;
- args->argv = malloc(sizeof(char**) * 1);
- args->argv[0] = strdup("disp");
- freerdp_dynamic_channel_collection_add(context->settings, args);
-#endif
+ guac_rdp_dvc_list_add(list, "disp", NULL);
}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/13933584/src/protocols/rdp/rdp_disp.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_disp.h b/src/protocols/rdp/rdp_disp.h
index 3378cf7..093e7ed 100644
--- a/src/protocols/rdp/rdp_disp.h
+++ b/src/protocols/rdp/rdp_disp.h
@@ -20,6 +20,7 @@
#ifndef GUAC_RDP_DISP_H
#define GUAC_RDP_DISP_H
+#include "dvc.h"
#include "rdp_settings.h"
#include <freerdp/freerdp.h>
@@ -102,7 +103,7 @@ void guac_rdp_disp_free(guac_rdp_disp* disp);
*
* @param context The rdpContext associated with the active RDP session.
*/
-void guac_rdp_disp_load_plugin(rdpContext* context);
+void guac_rdp_disp_load_plugin(rdpContext* context, guac_rdp_dvc_list* list);
#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
/**
[12/26] incubator-guacamole-server git commit: GUACAMOLE-25:
Implement message processing. Stub handlers.
Posted by jm...@apache.org.
GUACAMOLE-25: Implement message processing. Stub handlers.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/503ffb0d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/503ffb0d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/503ffb0d
Branch: refs/heads/master
Commit: 503ffb0d450a8dde8da4faff5fc65551ef4f1376
Parents: 1088332
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Apr 17 01:00:42 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/Makefile.am | 8 +-
src/protocols/rdp/guac_ai/ai_messages.c | 84 ++++++++++++++
src/protocols/rdp/guac_ai/ai_messages.h | 157 +++++++++++++++++++++++++++
src/protocols/rdp/guac_ai/ai_service.c | 47 +++++++-
src/protocols/rdp/guac_ai/ai_service.h | 6 +
5 files changed, 293 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/503ffb0d/src/protocols/rdp/Makefile.am
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/Makefile.am b/src/protocols/rdp/Makefile.am
index 0ac074a..0d07a74 100644
--- a/src/protocols/rdp/Makefile.am
+++ b/src/protocols/rdp/Makefile.am
@@ -46,9 +46,10 @@ libguac_client_rdp_la_SOURCES = \
unicode.c \
user.c
-guacai_sources = \
- guac_ai/ai_service.c \
- ptr_string.c
+guacai_sources = \
+ guac_ai/ai_messages.c \
+ guac_ai/ai_service.c \
+ ptr_string.c
guacsvc_sources = \
guac_svc/svc_service.c \
@@ -74,6 +75,7 @@ guacdr_sources = \
noinst_HEADERS = \
compat/client-cliprdr.h \
compat/rail.h \
+ guac_ai/ai_messages.h \
guac_ai/ai_service.h \
guac_rdpdr/rdpdr_fs_messages.h \
guac_rdpdr/rdpdr_fs_messages_dir_info.h \
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/503ffb0d/src/protocols/rdp/guac_ai/ai_messages.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_messages.c b/src/protocols/rdp/guac_ai/ai_messages.c
new file mode 100644
index 0000000..c799a44
--- /dev/null
+++ b/src/protocols/rdp/guac_ai/ai_messages.c
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+
+#include "ai_messages.h"
+#include "rdp.h"
+
+#include <stdlib.h>
+
+#include <freerdp/freerdp.h>
+#include <freerdp/constants.h>
+#include <freerdp/dvc.h>
+#include <guacamole/client.h>
+
+#ifdef ENABLE_WINPR
+#include <winpr/stream.h>
+#else
+#include "compat/winpr-stream.h"
+#endif
+
+void guac_rdp_ai_process_version(guac_client* client,
+ IWTSVirtualChannel* channel, wStream* stream) {
+
+ UINT32 version;
+ Stream_Read_UINT32(stream, version);
+
+ /* Warn if server's version number is incorrect */
+ if (version != 1)
+ guac_client_log(client, GUAC_LOG_WARNING,
+ "Server reports AUDIO_INPUT version %i, not 1", version);
+
+ /* Build response version PDU */
+ wStream* response = Stream_New(NULL, 5);
+ Stream_Write_UINT8(response, GUAC_RDP_MSG_SNDIN_VERSION); /* MessageId */
+ Stream_Write_UINT32(response, 1); /* Version */
+
+ /* Send response */
+ channel->Write(channel, (UINT32) Stream_GetPosition(response),
+ Stream_Buffer(response), NULL);
+ Stream_Free(response, TRUE);
+
+}
+
+void guac_rdp_ai_process_formats(guac_client* client,
+ IWTSVirtualChannel* channel, wStream* stream) {
+
+ /* STUB */
+ guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT: formats");
+
+}
+
+void guac_rdp_ai_process_open(guac_client* client,
+ IWTSVirtualChannel* channel, wStream* stream) {
+
+ /* STUB */
+ guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT: open");
+
+}
+
+void guac_rdp_ai_process_formatchange(guac_client* client,
+ IWTSVirtualChannel* channel, wStream* stream) {
+
+ /* STUB */
+ guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT: formatchange");
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/503ffb0d/src/protocols/rdp/guac_ai/ai_messages.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_messages.h b/src/protocols/rdp/guac_ai/ai_messages.h
new file mode 100644
index 0000000..96282e5
--- /dev/null
+++ b/src/protocols/rdp/guac_ai/ai_messages.h
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef GUAC_RDP_AI_MESSAGES_H
+#define GUAC_RDP_AI_MESSAGES_H
+
+#include "config.h"
+
+#include <freerdp/dvc.h>
+#include <guacamole/client.h>
+
+#ifdef ENABLE_WINPR
+#include <winpr/stream.h>
+#else
+#include "compat/winpr-stream.h"
+#endif
+
+/**
+ * The message ID associated with the AUDIO_INPUT Version PDU. The Version PDU
+ * is sent by both the client and the server to indicate their version of the
+ * AUDIO_INPUT channel protocol (which must always be 1).
+ */
+#define GUAC_RDP_MSG_SNDIN_VERSION 0x01
+
+/**
+ * The message ID associated with the AUDIO_INPUT Sound Formats PDU. The
+ * Sound Formats PDU is sent by the client and the server to indicate the
+ * formats of audio supported.
+ */
+#define GUAC_RDP_MSG_SNDIN_FORMATS 0x02
+
+/**
+ * The message ID associated with the AUDIO_INPUT Open PDU. The Open PDU is
+ * sent by the server to inform the client that the AUDIO_INPUT channel is
+ * now open.
+ */
+#define GUAC_RDP_MSG_SNDIN_OPEN 0x03
+
+/**
+ * The message ID associated with the AUDIO_INPUT Open Reply PDU. The Open
+ * Reply PDU is sent by the client (after sending a Format Change PDU) to
+ * acknowledge that the AUDIO_INPUT channel is open.
+ */
+#define GUAC_RDP_MSG_SNDIN_OPEN_REPLY 0x04
+
+/**
+ * The message ID associated with the AUDIO_INPUT Incoming Data PDU. The
+ * Incoming Data PDU is sent by the client to inform the server of incoming
+ * sound format or audio data.
+ */
+#define GUAC_RDP_MSG_SNDIN_DATA_INCOMING 0x05
+
+/**
+ * The message ID associated with the AUDIO_INPUT Data PDU. The Data PDU is
+ * sent by the client and contains audio data read from the microphone.
+ */
+#define GUAC_RDP_MSG_SNDIN_DATA 0x06
+
+/**
+ * The message ID associated with the AUDIO_INPUT Format Change PDU. The Format
+ * Change PDU is sent by the client to acknowledge the current sound format, or
+ * by the server to request a different sound format.
+ */
+#define GUAC_RDP_MSG_SNDIN_FORMATCHANGE 0x07
+
+/**
+ * Processes a Version PDU received from the RDP server. The Version PDU is
+ * sent by the server to indicate its version of the AUDIO_INPUT channel
+ * protocol (which must always be 1).
+ *
+ * @param client
+ * The guac_client associated with the current RDP connection.
+ *
+ * @param channel
+ * The IWTSVirtualChannel instance associated with the connected
+ * AUDIO_INPUT channel.
+ *
+ * @param stream
+ * The received PDU, with the read position just after the message ID field
+ * common to all AUDIO_INPUT PDUs.
+ */
+void guac_rdp_ai_process_version(guac_client* client,
+ IWTSVirtualChannel* channel, wStream* stream);
+
+/**
+ * Processes a Sound Formats PDU received from the RDP server. The Sound
+ * Formats PDU is sent by the server to indicate the formats of audio
+ * supported.
+ *
+ * @param client
+ * The guac_client associated with the current RDP connection.
+ *
+ * @param channel
+ * The IWTSVirtualChannel instance associated with the connected
+ * AUDIO_INPUT channel.
+ *
+ * @param stream
+ * The received PDU, with the read position just after the message ID field
+ * common to all AUDIO_INPUT PDUs.
+ */
+void guac_rdp_ai_process_formats(guac_client* client,
+ IWTSVirtualChannel* channel, wStream* stream);
+
+/**
+ * Processes a Open PDU received from the RDP server. The Open PDU is sent by
+ * the server to inform the client that the AUDIO_INPUT channel is now open.
+ *
+ * @param client
+ * The guac_client associated with the current RDP connection.
+ *
+ * @param channel
+ * The IWTSVirtualChannel instance associated with the connected
+ * AUDIO_INPUT channel.
+ *
+ * @param stream
+ * The received PDU, with the read position just after the message ID field
+ * common to all AUDIO_INPUT PDUs.
+ */
+void guac_rdp_ai_process_open(guac_client* client,
+ IWTSVirtualChannel* channel, wStream* stream);
+
+/**
+ * Processes a Format Change PDU received from the RDP server. The Format
+ * Change PDU is sent by the server to request a different sound format.
+ *
+ * @param client
+ * The guac_client associated with the current RDP connection.
+ *
+ * @param channel
+ * The IWTSVirtualChannel instance associated with the connected
+ * AUDIO_INPUT channel.
+ *
+ * @param stream
+ * The received PDU, with the read position just after the message ID field
+ * common to all AUDIO_INPUT PDUs.
+ */
+void guac_rdp_ai_process_formatchange(guac_client* client,
+ IWTSVirtualChannel* channel, wStream* stream);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/503ffb0d/src/protocols/rdp/guac_ai/ai_service.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_service.c b/src/protocols/rdp/guac_ai/ai_service.c
index e822f90..d6538bc 100644
--- a/src/protocols/rdp/guac_ai/ai_service.c
+++ b/src/protocols/rdp/guac_ai/ai_service.c
@@ -19,6 +19,7 @@
#include "config.h"
+#include "ai_messages.h"
#include "ai_service.h"
#include "ptr_string.h"
#include "rdp.h"
@@ -47,18 +48,49 @@
* The guac_client associated with RDP connection having the AUDIO_INPUT
* connection along which the given data was received.
*
+ * @param channel
+ * A reference to the IWTSVirtualChannel instance along which responses
+ * should be sent.
+ *
* @param stream
* The data received along the AUDIO_INPUT channel.
*/
-static void guac_rdp_ai_handle_data(guac_client* client, wStream* stream) {
+static void guac_rdp_ai_handle_data(guac_client* client,
+ IWTSVirtualChannel* channel, wStream* stream) {
/* Read message ID from received PDU */
BYTE message_id;
Stream_Read_UINT8(stream, message_id);
- /* STUB */
- guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT data received: 0x%x",
- message_id);
+ /* Invoke appropriate message processor based on ID */
+ switch (message_id) {
+
+ /* Version PDU */
+ case GUAC_RDP_MSG_SNDIN_VERSION:
+ guac_rdp_ai_process_version(client, channel, stream);
+ break;
+
+ /* Sound Formats PDU */
+ case GUAC_RDP_MSG_SNDIN_FORMATS:
+ guac_rdp_ai_process_formats(client, channel, stream);
+ break;
+
+ /* Open PDU */
+ case GUAC_RDP_MSG_SNDIN_OPEN:
+ guac_rdp_ai_process_open(client, channel, stream);
+ break;
+
+ /* Format Change PDU */
+ case GUAC_RDP_MSG_SNDIN_FORMATCHANGE:
+ guac_rdp_ai_process_formatchange(client, channel, stream);
+ break;
+
+ /* Log unknown message IDs */
+ default:
+ guac_client_log(client, GUAC_LOG_DEBUG,
+ "Unknown AUDIO_INPUT message ID: 0x%x", message_id);
+
+ }
}
@@ -85,10 +117,11 @@ static int guac_rdp_ai_data(IWTSVirtualChannelCallback* channel_callback,
guac_rdp_ai_channel_callback* ai_channel_callback =
(guac_rdp_ai_channel_callback*) channel_callback;
+ IWTSVirtualChannel* channel = ai_channel_callback->channel;
/* Invoke generalized (API-independent) data handler */
wStream* stream = Stream_New(buffer, size);
- guac_rdp_ai_handle_data(ai_channel_callback->client, stream);
+ guac_rdp_ai_handle_data(ai_channel_callback->client, channel, stream);
Stream_Free(stream, FALSE);
return 0;
@@ -114,9 +147,10 @@ static int guac_rdp_ai_data(IWTSVirtualChannelCallback* channel_callback,
guac_rdp_ai_channel_callback* ai_channel_callback =
(guac_rdp_ai_channel_callback*) channel_callback;
+ IWTSVirtualChannel* channel = ai_channel_callback->channel;
/* Invoke generalized (API-independent) data handler */
- guac_rdp_ai_handle_data(ai_channel_callback->client, stream);
+ guac_rdp_ai_handle_data(ai_channel_callback->client, channel, stream);
return 0;
@@ -197,6 +231,7 @@ static int guac_rdp_ai_new_connection(
/* Init listener callback with data from plugin */
ai_channel_callback->client = ai_listener_callback->client;
+ ai_channel_callback->channel = channel;
ai_channel_callback->parent.OnDataReceived = guac_rdp_ai_data;
ai_channel_callback->parent.OnClose = guac_rdp_ai_close;
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/503ffb0d/src/protocols/rdp/guac_ai/ai_service.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_service.h b/src/protocols/rdp/guac_ai/ai_service.h
index 4377812..28f2227 100644
--- a/src/protocols/rdp/guac_ai/ai_service.h
+++ b/src/protocols/rdp/guac_ai/ai_service.h
@@ -64,6 +64,12 @@ typedef struct guac_rdp_ai_channel_callback {
IWTSVirtualChannelCallback parent;
/**
+ * The actual virtual channel instance along which the AUDIO_INPUT plugin
+ * should send any responses.
+ */
+ IWTSVirtualChannel* channel;
+
+ /**
* The guac_client instance associated with the RDP connection using the
* AUDIO_INPUT plugin.
*/
[13/26] incubator-guacamole-server git commit: GUACAMOLE-25: Add stub
callbacks for AUDIO_INPUT data handling.
Posted by jm...@apache.org.
GUACAMOLE-25: Add stub callbacks for AUDIO_INPUT data handling.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/ac94fd4c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/ac94fd4c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/ac94fd4c
Branch: refs/heads/master
Commit: ac94fd4cd02f819cceb66206d6216e12c3ab93e2
Parents: 9cd89e6
Author: Michael Jumper <mj...@apache.org>
Authored: Sat Apr 16 22:48:27 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/guac_ai/ai_service.c | 224 +++++++++++++++++++++++++++-
src/protocols/rdp/guac_ai/ai_service.h | 77 +++++++++-
2 files changed, 296 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/ac94fd4c/src/protocols/rdp/guac_ai/ai_service.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_service.c b/src/protocols/rdp/guac_ai/ai_service.c
index c6ff47b..5b72354 100644
--- a/src/protocols/rdp/guac_ai/ai_service.c
+++ b/src/protocols/rdp/guac_ai/ai_service.c
@@ -38,6 +38,208 @@
#endif
/**
+ * Handles the given data received along the AUDIO_INPUT channel of the RDP
+ * connection associated with the given guac_client. This handler is
+ * API-independent and is invoked by API-dependent guac_rdp_ai_data callback
+ * specific to the version of FreeRDP installed.
+ *
+ * @param client
+ * The guac_client associated with RDP connection having the AUDIO_INPUT
+ * connection along which the given data was received.
+ *
+ * @param stream
+ * The data received along the AUDIO_INPUT channel.
+ */
+static void guac_rdp_ai_handle_data(guac_client* client, wStream* stream) {
+
+ /* Read message ID from received PDU */
+ BYTE message_id;
+ Stream_Read_UINT8(stream, message_id);
+
+ /* STUB */
+ guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT data received: 0x%x",
+ message_id);
+
+}
+
+/**
+ * Callback which is invoked when data is received along a connection to the
+ * AUDIO_INPUT plugin. This callback is specific to FreeRDP 1.1 and older.
+ *
+ * @param channel_callback
+ * The IWTSVirtualChannelCallback structure to which this callback was
+ * originally assigned.
+ *
+ * @param size
+ * The number of bytes received.
+ *
+ * @param buffer
+ * A buffer containing all bytes received.
+ *
+ * @return
+ * Always zero.
+ */
+static int guac_rdp_ai_data(IWTSVirtualChannelCallback* channel_callback,
+ UINT32 size, BYTE* buffer) {
+
+ guac_rdp_ai_channel_callback* ai_channel_callback =
+ (guac_rdp_ai_channel_callback*) channel_callback;
+
+ /* Invoke generalized (API-independent) data handler */
+ wStream* stream = Stream_New(buffer, size);
+ guac_rdp_ai_handle_data(ai_channel_callback->client, stream);
+ Stream_Free(stream, FALSE);
+
+ return 0;
+
+}
+
+/**
+ * Callback which is invoked when a connection to the AUDIO_INPUT plugin is
+ * closed.
+ *
+ * @param channel_callback
+ * The IWTSVirtualChannelCallback structure to which this callback was
+ * originally assigned.
+ *
+ * @return
+ * Always zero.
+ */
+static int guac_rdp_ai_close(IWTSVirtualChannelCallback* channel_callback) {
+
+ guac_rdp_ai_channel_callback* ai_channel_callback =
+ (guac_rdp_ai_channel_callback*) channel_callback;
+
+ /* Log closure of AUDIO_INPUT channel */
+ guac_client_log(ai_channel_callback->client, GUAC_LOG_DEBUG,
+ "AUDIO_INPUT channel connection closed");
+
+ free(ai_channel_callback);
+ return 0;
+
+}
+
+/**
+ * Callback which is invoked when a new connection is received by the
+ * AUDIO_INPUT plugin. Additional callbacks required to handle received data
+ * and closure of the connection must be installed at this point.
+ *
+ * @param listener_callback
+ * The IWTSListenerCallback structure associated with the AUDIO_INPUT
+ * plugin receiving the new connection.
+ *
+ * @param channel
+ * A reference to the IWTSVirtualChannel instance along which data related
+ * to the AUDIO_INPUT channel should be sent.
+ *
+ * @param data
+ * Absolutely no idea. According to Microsoft's documentation for the
+ * function prototype on which FreeRDP's API appears to be based: "This
+ * parameter is not implemented and is reserved for future use."
+ *
+ * @param accept
+ * Pointer to a flag which should be set to TRUE if the connection should
+ * be accepted or FALSE otherwise. In the case of FreeRDP, this value
+ * defaults to TRUE, and TRUE absolutely MUST be identically 1 or it will
+ * be interpreted as FALSE.
+ *
+ * @param channel_callback
+ * A pointer to the location that the new IWTSVirtualChannelCallback
+ * structure containing the required callbacks should be assigned.
+ *
+ * @return
+ * Always zero.
+ */
+static int guac_rdp_ai_new_connection(
+ IWTSListenerCallback* listener_callback, IWTSVirtualChannel* channel,
+ BYTE* data, int* accept,
+ IWTSVirtualChannelCallback** channel_callback) {
+
+ guac_rdp_ai_listener_callback* ai_listener_callback =
+ (guac_rdp_ai_listener_callback*) listener_callback;
+
+ /* Log new AUDIO_INPUT connection */
+ guac_client_log(ai_listener_callback->client, GUAC_LOG_DEBUG,
+ "New AUDIO_INPUT channel connection");
+
+ /* Allocate new channel callback */
+ guac_rdp_ai_channel_callback* ai_channel_callback =
+ calloc(1, sizeof(guac_rdp_ai_channel_callback));
+
+ /* Init listener callback with data from plugin */
+ ai_channel_callback->client = ai_listener_callback->client;
+ ai_channel_callback->parent.OnDataReceived = guac_rdp_ai_data;
+ ai_channel_callback->parent.OnClose = guac_rdp_ai_close;
+
+ /* Return callback through pointer */
+ *channel_callback = (IWTSVirtualChannelCallback*) ai_channel_callback;
+ return 0;
+
+}
+
+/**
+ * Callback which is invoked when the AUDIO_INPUT plugin has been loaded and
+ * needs to be initialized with other callbacks and data.
+ *
+ * @param plugin
+ * The AUDIO_INPUT plugin that needs to be initialied.
+ *
+ * @param manager
+ * The IWTSVirtualChannelManager instance with which the AUDIO_INPUT plugin
+ * must be registered.
+ *
+ * @return
+ * Always zero.
+ */
+static int guac_rdp_ai_initialize(IWTSPlugin* plugin,
+ IWTSVirtualChannelManager* manager) {
+
+ /* Allocate new listener callback */
+ guac_rdp_ai_listener_callback* ai_listener_callback =
+ calloc(1, sizeof(guac_rdp_ai_listener_callback));
+
+ /* Ensure listener callback is freed when plugin is terminated */
+ guac_rdp_ai_plugin* ai_plugin = (guac_rdp_ai_plugin*) plugin;
+ ai_plugin->listener_callback = ai_listener_callback;
+
+ /* Init listener callback with data from plugin */
+ ai_listener_callback->client = ai_plugin->client;
+ ai_listener_callback->parent.OnNewChannelConnection =
+ guac_rdp_ai_new_connection;
+
+ /* Register listener for "AUDIO_INPUT" channel */
+ manager->CreateListener(manager, "AUDIO_INPUT", 0,
+ (IWTSListenerCallback*) ai_listener_callback, NULL);
+
+ return 0;
+
+}
+
+/**
+ * Callback which is invoked when all connections to the AUDIO_INPUT plugin
+ * have closed and the plugin is being unloaded.
+ *
+ * @param plugin
+ * The AUDIO_INPUT plugin being unloaded.
+ *
+ * @return
+ * Always zero.
+ */
+static int guac_rdp_ai_terminated(IWTSPlugin* plugin) {
+
+ guac_rdp_ai_plugin* ai_plugin = (guac_rdp_ai_plugin*) plugin;
+ guac_client* client = ai_plugin->client;
+
+ /* Free all non-FreeRDP data */
+ free(ai_plugin->listener_callback);
+ free(ai_plugin);
+
+ guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT plugin unloaded.");
+ return 0;
+
+}
+
+/**
* Entry point for AUDIO_INPUT dynamic virtual channel.
*/
int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) {
@@ -45,9 +247,25 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) {
ADDIN_ARGV* args = pEntryPoints->GetPluginData(pEntryPoints);
guac_client* client = (guac_client*) guac_rdp_string_to_ptr(args->argv[1]);
- /* STUB */
- guac_client_log(client, GUAC_LOG_DEBUG,
- "STUB: AUDIO_INPUT DVC (entry point)");
+ /* Pull previously-allocated plugin */
+ guac_rdp_ai_plugin* ai_plugin = (guac_rdp_ai_plugin*)
+ pEntryPoints->GetPlugin(pEntryPoints, "guacai");
+
+ /* If no such plugin allocated, allocate and register it now */
+ if (ai_plugin == NULL) {
+
+ /* Init plugin callbacks and data */
+ ai_plugin = calloc(1, sizeof(guac_rdp_ai_plugin));
+ ai_plugin->parent.Initialize = guac_rdp_ai_initialize;
+ ai_plugin->parent.Terminated = guac_rdp_ai_terminated;
+ ai_plugin->client = client;
+
+ /* Register plugin as "guacai" for later retrieval */
+ pEntryPoints->RegisterPlugin(pEntryPoints, "guacai",
+ (IWTSPlugin*) ai_plugin);
+
+ guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT plugin loaded.");
+ }
return 1;
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/ac94fd4c/src/protocols/rdp/guac_ai/ai_service.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_service.h b/src/protocols/rdp/guac_ai/ai_service.h
index caa62ad..4377812 100644
--- a/src/protocols/rdp/guac_ai/ai_service.h
+++ b/src/protocols/rdp/guac_ai/ai_service.h
@@ -17,13 +17,86 @@
* under the License.
*/
-
#ifndef GUAC_RDP_AI_SERVICE_H
#define GUAC_RDP_AI_SERVICE_H
#include "config.h"
-/* STUB */
+#include <freerdp/freerdp.h>
+#include <freerdp/constants.h>
+#include <freerdp/dvc.h>
+#include <guacamole/client.h>
+
+/**
+ * Extended version of the IWTSListenerCallback structure, providing additional
+ * access to Guacamole-specific data. The IWTSListenerCallback provides access
+ * to callbacks related to the receipt of new connections to the AUDIO_INPUT
+ * channel.
+ */
+typedef struct guac_rdp_ai_listener_callback {
+
+ /**
+ * The parent IWTSListenerCallback structure that this structure extends.
+ * THIS MEMBER MUST BE FIRST!
+ */
+ IWTSListenerCallback parent;
+
+ /**
+ * The guac_client instance associated with the RDP connection using the
+ * AUDIO_INPUT plugin.
+ */
+ guac_client* client;
+
+} guac_rdp_ai_listener_callback;
+
+/**
+ * Extended version of the IWTSVirtualChannelCallback structure, providing
+ * additional access to Guacamole-specific data. The IWTSVirtualChannelCallback
+ * provides access to callbacks related to an active connection to the
+ * AUDIO_INPUT channel, including receipt of data.
+ */
+typedef struct guac_rdp_ai_channel_callback {
+
+ /**
+ * The parent IWTSVirtualChannelCallback structure that this structure
+ * extends. THIS MEMBER MUST BE FIRST!
+ */
+ IWTSVirtualChannelCallback parent;
+
+ /**
+ * The guac_client instance associated with the RDP connection using the
+ * AUDIO_INPUT plugin.
+ */
+ guac_client* client;
+
+} guac_rdp_ai_channel_callback;
+
+/**
+ * All data associated with Guacamole's AUDIO_INPUT plugin for FreeRDP.
+ */
+typedef struct guac_rdp_ai_plugin {
+
+ /**
+ * The parent IWTSPlugin structure that this structure extends. THIS
+ * MEMBER MUST BE FIRST!
+ */
+ IWTSPlugin parent;
+
+ /**
+ * The listener callback structure allocated when the AUDIO_INPUT plugin
+ * was loaded, if any. If the plugin did not fully load, this will be NULL.
+ * If non-NULL, this callback structure must be freed when the plugin is
+ * terminated.
+ */
+ guac_rdp_ai_listener_callback* listener_callback;
+
+ /**
+ * The guac_client instance associated with the RDP connection using the
+ * AUDIO_INPUT plugin.
+ */
+ guac_client* client;
+
+} guac_rdp_ai_plugin;
#endif
[24/26] incubator-guacamole-server git commit: GUACAMOLE-25: Reset
I/O counters upon end-of-stream.
Posted by jm...@apache.org.
GUACAMOLE-25: Reset I/O counters upon end-of-stream.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/0d29694a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/0d29694a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/0d29694a
Branch: refs/heads/master
Commit: 0d29694afc2c7eb1fa8a8fea011bd5a7ec9a99ac
Parents: 0be04ea
Author: Michael Jumper <mj...@apache.org>
Authored: Wed Jun 1 16:20:38 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed Jun 1 16:20:38 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/audio_input.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/0d29694a/src/protocols/rdp/audio_input.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.c b/src/protocols/rdp/audio_input.c
index eefb231..dc078dc 100644
--- a/src/protocols/rdp/audio_input.c
+++ b/src/protocols/rdp/audio_input.c
@@ -247,9 +247,6 @@ void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
audio_buffer->in_format.channels = channels;
audio_buffer->in_format.bps = bps;
- /* Reset input counter */
- audio_buffer->total_bytes_received = 0;
-
/* Acknowledge stream creation (if buffer is ready to receive) */
guac_rdp_audio_buffer_ack(audio_buffer,
"OK", GUAC_PROTOCOL_STATUS_SUCCESS);
@@ -274,9 +271,6 @@ void guac_rdp_audio_buffer_set_output(guac_rdp_audio_buffer* audio_buffer,
audio_buffer->out_format.channels = channels;
audio_buffer->out_format.bps = bps;
- /* Reset output counter */
- audio_buffer->total_bytes_sent = 0;
-
pthread_mutex_unlock(&(audio_buffer->lock));
}
@@ -470,6 +464,10 @@ void guac_rdp_audio_buffer_end(guac_rdp_audio_buffer* audio_buffer) {
audio_buffer->packet_size = 0;
audio_buffer->flush_handler = NULL;
+ /* Reset I/O counters */
+ audio_buffer->total_bytes_sent = 0;
+ audio_buffer->total_bytes_received = 0;
+
/* Free packet (if any) */
free(audio_buffer->packet);
audio_buffer->packet = NULL;
[15/26] incubator-guacamole-server git commit: GUACAMOLE-25: Buffer
and send Data PDUs as necessary.
Posted by jm...@apache.org.
GUACAMOLE-25: Buffer and send Data PDUs as necessary.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/9d5871a3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/9d5871a3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/9d5871a3
Branch: refs/heads/master
Commit: 9d5871a3c8a9af7522beed65d80f7630cc90f7a7
Parents: 63cd2ce
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Apr 18 00:32:51 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/Makefile.am | 1 +
src/protocols/rdp/audio_input.c | 90 ++++++++++++++++++-
src/protocols/rdp/audio_input.h | 126 +++++++++++++++++++++++++++
src/protocols/rdp/client.c | 5 ++
src/protocols/rdp/guac_ai/ai_messages.c | 35 +++++++-
src/protocols/rdp/guac_ai/ai_service.c | 8 +-
src/protocols/rdp/rdp.c | 4 +-
src/protocols/rdp/rdp.h | 6 ++
8 files changed, 270 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/9d5871a3/src/protocols/rdp/Makefile.am
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/Makefile.am b/src/protocols/rdp/Makefile.am
index 0d07a74..f76c33e 100644
--- a/src/protocols/rdp/Makefile.am
+++ b/src/protocols/rdp/Makefile.am
@@ -47,6 +47,7 @@ libguac_client_rdp_la_SOURCES = \
user.c
guacai_sources = \
+ audio_input.c \
guac_ai/ai_messages.c \
guac_ai/ai_service.c \
ptr_string.c
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/9d5871a3/src/protocols/rdp/audio_input.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.c b/src/protocols/rdp/audio_input.c
index 9d5d505..1bea175 100644
--- a/src/protocols/rdp/audio_input.c
+++ b/src/protocols/rdp/audio_input.c
@@ -51,14 +51,19 @@ int guac_rdp_audio_handler(guac_user* user, guac_stream* stream,
int guac_rdp_audio_blob_handler(guac_user* user, guac_stream* stream,
void* data, int length) {
- /* STUB */
+ guac_client* client = user->client;
+ guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+
+ /* Write blob to audio stream, buffering if necessary */
+ guac_rdp_audio_buffer_write(rdp_client->audio_input, data, length);
+
return 0;
}
int guac_rdp_audio_end_handler(guac_user* user, guac_stream* stream) {
- /* STUB */
+ /* Ignore - the AUDIO_INPUT channel will simply not receive anything */
return 0;
}
@@ -77,3 +82,84 @@ void guac_rdp_audio_load_plugin(rdpContext* context) {
}
+guac_rdp_audio_buffer* guac_rdp_audio_buffer_alloc() {
+ return calloc(1, sizeof(guac_rdp_audio_buffer));
+}
+
+void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
+ int packet_size, guac_rdp_audio_buffer_flush_handler* flush_handler,
+ void* data) {
+
+ /* Reset buffer state to provided values */
+ audio_buffer->bytes_written = 0;
+ audio_buffer->packet_size = packet_size;
+ audio_buffer->flush_handler = flush_handler;
+ audio_buffer->data = data;
+
+ /* Allocate new buffer */
+ free(audio_buffer->packet);
+ audio_buffer->packet = malloc(packet_size);
+
+}
+
+void guac_rdp_audio_buffer_write(guac_rdp_audio_buffer* audio_buffer,
+ char* buffer, int length) {
+
+ /* Ignore packet if there is no buffer */
+ if (audio_buffer->packet_size == 0 || audio_buffer->packet == NULL)
+ return;
+
+ /* Continuously write packets until no data remains */
+ while (length > 0) {
+
+ /* Calculate ideal size of chunk based on available space */
+ int chunk_size = audio_buffer->packet_size
+ - audio_buffer->bytes_written;
+
+ /* Shrink chunk size if insufficient bytes are provided */
+ if (length < chunk_size)
+ chunk_size = length;
+
+ /* Append buffer */
+ memcpy(audio_buffer->packet + audio_buffer->bytes_written,
+ buffer, chunk_size);
+
+ /* Update byte counters */
+ length -= chunk_size;
+ audio_buffer->bytes_written += chunk_size;
+
+ /* Invoke flush handler if full */
+ if (audio_buffer->bytes_written == audio_buffer->packet_size) {
+
+ /* Only actually invoke if defined */
+ if (audio_buffer->flush_handler)
+ audio_buffer->flush_handler(audio_buffer->packet,
+ audio_buffer->bytes_written, audio_buffer->data);
+
+ /* Reset buffer in all cases */
+ audio_buffer->bytes_written = 0;
+
+ }
+
+ } /* end packet write loop */
+
+}
+
+void guac_rdp_audio_buffer_end(guac_rdp_audio_buffer* audio_buffer) {
+
+ /* Reset buffer state */
+ audio_buffer->bytes_written = 0;
+ audio_buffer->packet_size = 0;
+ audio_buffer->flush_handler = NULL;
+
+ /* Free packet (if any) */
+ free(audio_buffer->packet);
+ audio_buffer->packet = NULL;
+
+}
+
+void guac_rdp_audio_buffer_free(guac_rdp_audio_buffer* audio_buffer) {
+ free(audio_buffer->packet);
+ free(audio_buffer);
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/9d5871a3/src/protocols/rdp/audio_input.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.h b/src/protocols/rdp/audio_input.h
index d32cda1..c89de15 100644
--- a/src/protocols/rdp/audio_input.h
+++ b/src/protocols/rdp/audio_input.h
@@ -26,6 +26,132 @@
#include <guacamole/user.h>
/**
+ * Handler which is invoked when a guac_rdp_audio_buffer's internal packet
+ * buffer has reached capacity and must be flushed.
+ *
+ * @param buffer
+ * The buffer which needs to be flushed as an audio packet.
+ *
+ * @param length
+ * The number of bytes stored within the buffer. This is guaranteed to be
+ * identical to the packet_size value specified when the audio buffer was
+ * initialized.
+ *
+ * @param data
+ * The arbitrary data pointer provided when the audio buffer was
+ * initialized.
+ */
+typedef void guac_rdp_audio_buffer_flush_handler(char* buffer, int length,
+ void* data);
+
+/**
+ * A buffer of arbitrary audio data. Received audio data can be written to this
+ * buffer, and will automatically be flushed via a given handler once the
+ * internal buffer reaches capacity.
+ */
+typedef struct guac_rdp_audio_buffer {
+
+ /**
+ * The size that each audio packet must be, in bytes. The packet buffer
+ * within this structure will be at least this size.
+ */
+ int packet_size;
+
+ /**
+ * The number of bytes currently stored within the packet buffer.
+ */
+ int bytes_written;
+
+ /**
+ * All audio data being prepared for sending to the AUDIO_INPUT channel.
+ */
+ char* packet;
+
+ /**
+ * Handler function which will be invoked when a full audio packet is
+ * ready to be flushed to the AUDIO_INPUT channel, if defined. If NULL,
+ * audio packets will simply be ignored.
+ */
+ guac_rdp_audio_buffer_flush_handler* flush_handler;
+
+ /**
+ * Arbitrary data assigned by the AUDIO_INPUT plugin implementation.
+ */
+ void* data;
+
+} guac_rdp_audio_buffer;
+
+/**
+ * Allocates a new audio buffer. The new audio buffer will ignore any received
+ * data until guac_rdp_audio_buffer_begin() is invoked, and will resume
+ * ignoring received data once guac_rdp_audio_buffer_end() is invoked.
+ *
+ * @return
+ * A newly-allocated audio buffer.
+ */
+guac_rdp_audio_buffer* guac_rdp_audio_buffer_alloc();
+
+/**
+ * Begins handling of audio data received via guac_rdp_audio_buffer_write() and
+ * allocates the necessary underlying packet buffer. Audio packets of exactly
+ * packet_size bytes will be flushed as available using the provided
+ * flush_handler.
+ *
+ * @param audio_buffer
+ * The audio buffer to begin.
+ *
+ * @param packet_size
+ * The number of bytes to include in all audio packets provided to the
+ * given flush_handler.
+ *
+ * @param flush_handler
+ * The function to invoke when an audio packet must be flushed.
+ *
+ * @param data
+ * Arbitrary data to provide to the flush_handler when an audio packet
+ * needs to be flushed.
+ */
+void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
+ int packet_size, guac_rdp_audio_buffer_flush_handler* flush_handler,
+ void* data);
+
+/**
+ * Writes the given buffer of audio data to the given audio buffer. A new
+ * packet will be flushed using the associated flush handler once sufficient
+ * bytes have been accumulated.
+ *
+ * @param audio_buffer
+ * The audio buffer to which the given audio data should be written.
+ *
+ * @param buffer
+ * The buffer of audio data to write to the given audio buffer.
+ *
+ * @param length
+ * The number of bytes to write.
+ */
+void guac_rdp_audio_buffer_write(guac_rdp_audio_buffer* audio_buffer,
+ char* buffer, int length);
+
+/**
+ * Stops handling of audio data received via guac_rdp_audio_buffer_write() and
+ * frees the underlying packet buffer. Further audio data will be ignored until
+ * guac_rdp_audio_buffer_begin() is invoked again.
+ *
+ * @param audio_buffer
+ * The audio buffer to end.
+ */
+void guac_rdp_audio_buffer_end(guac_rdp_audio_buffer* audio_buffer);
+
+/**
+ * Frees the given audio buffer. If guac_rdp_audio_buffer_end() has not yet
+ * been called, its associated packet buffer will also be freed.
+ *
+ * @param audio_buffer
+ * The audio buffer to free.
+ */
+void guac_rdp_audio_buffer_free(guac_rdp_audio_buffer* audio_buffer);
+
+/**
* Handler for inbound audio data (audio input).
*/
guac_user_audio_handler guac_rdp_audio_handler;
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/9d5871a3/src/protocols/rdp/client.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/client.c b/src/protocols/rdp/client.c
index 5132125..362f0aa 100644
--- a/src/protocols/rdp/client.c
+++ b/src/protocols/rdp/client.c
@@ -19,6 +19,7 @@
#include "config.h"
+#include "audio_input.h"
#include "client.h"
#include "rdp.h"
#include "rdp_disp.h"
@@ -129,6 +130,10 @@ int guac_rdp_client_free_handler(guac_client* client) {
if (rdp_client->audio != NULL)
guac_audio_stream_free(rdp_client->audio);
+ /* Clean up audio input buffer, if allocated */
+ if (rdp_client->audio_input != NULL)
+ guac_rdp_audio_buffer_free(rdp_client->audio_input);
+
/* Free client data */
guac_common_clipboard_free(rdp_client->clipboard);
free(rdp_client);
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/9d5871a3/src/protocols/rdp/guac_ai/ai_messages.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_messages.c b/src/protocols/rdp/guac_ai/ai_messages.c
index 8b2d0d7..b0eb6cf 100644
--- a/src/protocols/rdp/guac_ai/ai_messages.c
+++ b/src/protocols/rdp/guac_ai/ai_messages.c
@@ -20,6 +20,7 @@
#include "config.h"
#include "ai_messages.h"
+#include "audio_input.h"
#include "rdp.h"
#include <stdlib.h>
@@ -112,6 +113,21 @@ static void guac_rdp_ai_send_incoming_data(IWTSVirtualChannel* channel) {
}
+static void guac_rdp_ai_send_data(IWTSVirtualChannel* channel,
+ char* buffer, int length) {
+
+ /* Build data PDU */
+ wStream* stream = Stream_New(NULL, length + 1);
+ Stream_Write_UINT8(stream, GUAC_RDP_MSG_SNDIN_DATA); /* MessageId */
+ Stream_Write(stream, buffer, length); /* Data */
+
+ /* Send stream */
+ channel->Write(channel, (UINT32) Stream_GetPosition(stream),
+ Stream_Buffer(stream), NULL);
+ Stream_Free(stream, TRUE);
+
+}
+
/**
* Sends a Sound Formats PDU along the given channel. A Sound Formats PDU is
* used by the client to indicate to the server which formats of audio it
@@ -263,9 +279,22 @@ void guac_rdp_ai_process_formats(guac_client* client,
}
+static void guac_rdp_ai_flush_packet(char* buffer, int length, void* data) {
+
+ IWTSVirtualChannel* channel = (IWTSVirtualChannel*) data;
+
+ /* Send data over channel */
+ guac_rdp_ai_send_incoming_data(channel);
+ guac_rdp_ai_send_data(channel, buffer, length);
+
+}
+
void guac_rdp_ai_process_open(guac_client* client,
IWTSVirtualChannel* channel, wStream* stream) {
+ guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+ guac_rdp_audio_buffer* audio_buffer = rdp_client->audio_input;
+
UINT32 packet_frames;
UINT32 initial_format;
@@ -281,12 +310,16 @@ void guac_rdp_ai_process_open(guac_client* client,
guac_rdp_ai_send_formatchange(channel, initial_format);
guac_rdp_ai_send_open_reply(channel, 0);
+ /* FIXME: Assuming mimetype of 16-bit 44100 Hz stereo PCM */
+ guac_rdp_audio_buffer_begin(audio_buffer, packet_frames * 2 * 2,
+ guac_rdp_ai_flush_packet, channel);
+
}
void guac_rdp_ai_process_formatchange(guac_client* client,
IWTSVirtualChannel* channel, wStream* stream) {
- /* STUB */
+ /* STUB: Should not be called as we only accept one format */
guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT: formatchange");
}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/9d5871a3/src/protocols/rdp/guac_ai/ai_service.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_service.c b/src/protocols/rdp/guac_ai/ai_service.c
index d6538bc..945f039 100644
--- a/src/protocols/rdp/guac_ai/ai_service.c
+++ b/src/protocols/rdp/guac_ai/ai_service.c
@@ -21,6 +21,7 @@
#include "ai_messages.h"
#include "ai_service.h"
+#include "audio_input.h"
#include "ptr_string.h"
#include "rdp.h"
@@ -173,10 +174,15 @@ static int guac_rdp_ai_close(IWTSVirtualChannelCallback* channel_callback) {
guac_rdp_ai_channel_callback* ai_channel_callback =
(guac_rdp_ai_channel_callback*) channel_callback;
+ guac_client* client = ai_channel_callback->client;
+ guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
+ guac_rdp_audio_buffer* audio_buffer = rdp_client->audio_input;
+
/* Log closure of AUDIO_INPUT channel */
- guac_client_log(ai_channel_callback->client, GUAC_LOG_DEBUG,
+ guac_client_log(client, GUAC_LOG_DEBUG,
"AUDIO_INPUT channel connection closed");
+ guac_rdp_audio_buffer_end(audio_buffer);
free(ai_channel_callback);
return 0;
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/9d5871a3/src/protocols/rdp/rdp.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c
index 7859e20..f461369 100644
--- a/src/protocols/rdp/rdp.c
+++ b/src/protocols/rdp/rdp.c
@@ -244,8 +244,10 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
#endif
/* Load "AUDIO_INPUT" plugin for audio input*/
- if (settings->enable_audio_input)
+ if (settings->enable_audio_input) {
+ rdp_client->audio_input = guac_rdp_audio_buffer_alloc();
guac_rdp_audio_load_plugin(instance->context);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/9d5871a3/src/protocols/rdp/rdp.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp.h b/src/protocols/rdp/rdp.h
index 9325a18..02d9ac6 100644
--- a/src/protocols/rdp/rdp.h
+++ b/src/protocols/rdp/rdp.h
@@ -22,6 +22,7 @@
#include "config.h"
+#include "audio_input.h"
#include "guac_clipboard.h"
#include "guac_display.h"
#include "guac_surface.h"
@@ -121,6 +122,11 @@ typedef struct guac_rdp_client {
guac_audio_stream* audio;
/**
+ * Audio input buffer, if audio input is enabled.
+ */
+ guac_rdp_audio_buffer* audio_input;
+
+ /**
* The filesystem being shared, if any.
*/
guac_rdp_fs* filesystem;
[07/26] incubator-guacamole-server git commit: GUACAMOLE-25: Add stub
"guacai" plugin for AUDIO_INPUT channel support.
Posted by jm...@apache.org.
GUACAMOLE-25: Add stub "guacai" plugin for AUDIO_INPUT channel support.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/21ab9d76
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/21ab9d76
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/21ab9d76
Branch: refs/heads/master
Commit: 21ab9d765da8c0b519d6aa7c90813adf4fb9705e
Parents: ec93a29
Author: Michael Jumper <mj...@apache.org>
Authored: Sat Apr 16 15:54:26 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
src/protocols/rdp/Makefile.am | 38 +++++++++++++++
src/protocols/rdp/audio_input.c | 74 +++++++++++++++++++++++++++++
src/protocols/rdp/audio_input.h | 54 +++++++++++++++++++++
src/protocols/rdp/guac_ai/ai_service.c | 56 ++++++++++++++++++++++
src/protocols/rdp/guac_ai/ai_service.h | 29 +++++++++++
src/protocols/rdp/rdp.c | 30 ++++++++----
src/protocols/rdp/rdp_settings.c | 12 +++++
src/protocols/rdp/rdp_settings.h | 5 ++
src/protocols/rdp/user.c | 5 ++
9 files changed, 293 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/21ab9d76/src/protocols/rdp/Makefile.am
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/Makefile.am b/src/protocols/rdp/Makefile.am
index 91593cb..44f248a 100644
--- a/src/protocols/rdp/Makefile.am
+++ b/src/protocols/rdp/Makefile.am
@@ -24,6 +24,7 @@ lib_LTLIBRARIES = libguac-client-rdp.la
libguac_client_rdp_la_SOURCES = \
_generated_keymaps.c \
+ audio_input.c \
client.c \
input.c \
rdp.c \
@@ -44,6 +45,9 @@ libguac_client_rdp_la_SOURCES = \
unicode.c \
user.c
+guacai_sources = \
+ guac_ai/ai_service.c
+
guacsvc_sources = \
guac_svc/svc_service.c \
rdp_svc.c
@@ -68,6 +72,7 @@ guacdr_sources = \
noinst_HEADERS = \
compat/client-cliprdr.h \
compat/rail.h \
+ guac_ai/ai_service.h \
guac_rdpdr/rdpdr_fs_messages.h \
guac_rdpdr/rdpdr_fs_messages_dir_info.h \
guac_rdpdr/rdpdr_fs_messages_file_info.h \
@@ -79,6 +84,7 @@ noinst_HEADERS = \
guac_rdpsnd/rdpsnd_messages.h \
guac_rdpsnd/rdpsnd_service.h \
guac_svc/svc_service.h \
+ audio_input.h \
client.h \
input.h \
rdp.h \
@@ -104,6 +110,7 @@ noinst_HEADERS = \
if ! ENABLE_WINPR
noinst_HEADERS += compat/winpr-stream.h compat/winpr-wtypes.h
libguac_client_rdp_la_SOURCES += compat/winpr-stream.c
+guacai_sources += compat/winpr-stream.c
guacsvc_sources += compat/winpr-stream.c
guacsnd_sources += compat/winpr-stream.c
guacdr_sources += compat/winpr-stream.c
@@ -149,6 +156,25 @@ guacdr_libadd = \
@LIBGUAC_LTLIB@
#
+# Audio Input
+#
+
+guacai_cflags = \
+ -Werror -Wall -Iinclude \
+ @COMMON_INCLUDE@ \
+ @COMMON_SSH_INCLUDE@ \
+ @LIBGUAC_INCLUDE@
+
+guacai_ldflags = \
+ -module -avoid-version -shared \
+ @PTHREAD_LIBS@ \
+ @RDP_LIBS@
+
+guacai_libadd = \
+ @COMMON_LTLIB@ \
+ @LIBGUAC_LTLIB@
+
+#
# RDPSND
#
@@ -224,10 +250,16 @@ if LEGACY_FREERDP_EXTENSIONS
# FreeRDP 1.0-style extensions
freerdp_LTLIBRARIES = \
+ guacai.la \
guacdr.la \
guacsnd.la \
guacsvc.la
+guacai_la_SOURCES = ${guacai_sources}
+guacai_la_CFLAGS = ${guacai_cflags}
+guacai_la_LDFLAGS = ${guacai_ldflags}
+guacai_la_LIBADD = ${guacai_libadd}
+
guacdr_la_SOURCES = ${guacdr_sources}
guacdr_la_CFLAGS = ${guacdr_cflags}
guacdr_la_LDFLAGS = ${guacdr_ldflags}
@@ -247,10 +279,16 @@ else
# FreeRDP 1.1 (and hopefully onward) extensions
freerdp_LTLIBRARIES = \
+ guacai-client.la \
guacdr-client.la \
guacsnd-client.la \
guacsvc-client.la
+guacai_client_la_SOURCES = ${guacai_sources}
+guacai_client_la_CFLAGS = ${guacai_cflags}
+guacai_client_la_LDFLAGS = ${guacai_ldflags}
+guacai_client_la_LIBADD = ${guacai_libadd}
+
guacdr_client_la_SOURCES = ${guacdr_sources}
guacdr_client_la_CFLAGS = ${guacdr_cflags}
guacdr_client_la_LDFLAGS = ${guacdr_ldflags}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/21ab9d76/src/protocols/rdp/audio_input.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.c b/src/protocols/rdp/audio_input.c
new file mode 100644
index 0000000..8233184
--- /dev/null
+++ b/src/protocols/rdp/audio_input.c
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+#include "audio_input.h"
+
+#include <freerdp/freerdp.h>
+#include <freerdp/channels/channels.h>
+#include <guacamole/protocol.h>
+#include <guacamole/socket.h>
+#include <guacamole/stream.h>
+#include <guacamole/user.h>
+
+#include <stdlib.h>
+
+int guac_rdp_audio_handler(guac_user* user, guac_stream* stream,
+ char* mimetype) {
+
+ /* FIXME: Assuming mimetype of "audio/L16;rate=44100,channels=2" */
+
+ /* Init stream data */
+ stream->blob_handler = guac_rdp_audio_blob_handler;
+ stream->end_handler = guac_rdp_audio_end_handler;
+
+ guac_protocol_send_ack(user->socket, stream,
+ "OK", GUAC_PROTOCOL_STATUS_SUCCESS);
+ guac_socket_flush(user->socket);
+
+ return 0;
+
+}
+
+int guac_rdp_audio_blob_handler(guac_user* user, guac_stream* stream,
+ void* data, int length) {
+
+ /* STUB */
+ return 0;
+
+}
+
+int guac_rdp_audio_end_handler(guac_user* user, guac_stream* stream) {
+
+ /* STUB */
+ return 0;
+
+}
+
+void guac_rdp_audio_load_plugin(rdpContext* context) {
+
+ /* Add "AUDIO_INPUT" channel */
+ ADDIN_ARGV* args = malloc(sizeof(ADDIN_ARGV));
+ args->argc = 1;
+ args->argv = malloc(sizeof(char**) * 1);
+ args->argv[0] = strdup("guacai");
+ freerdp_dynamic_channel_collection_add(context->settings, args);
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/21ab9d76/src/protocols/rdp/audio_input.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/audio_input.h b/src/protocols/rdp/audio_input.h
new file mode 100644
index 0000000..d32cda1
--- /dev/null
+++ b/src/protocols/rdp/audio_input.h
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef GUAC_RDP_AUDIO_INPUT_H
+#define GUAC_RDP_AUDIO_INPUT_H
+
+#include "config.h"
+
+#include <freerdp/freerdp.h>
+#include <guacamole/user.h>
+
+/**
+ * Handler for inbound audio data (audio input).
+ */
+guac_user_audio_handler guac_rdp_audio_handler;
+
+/**
+ * Handler for stream data related to audio input.
+ */
+guac_user_blob_handler guac_rdp_audio_blob_handler;
+
+/**
+ * Handler for end-of-stream related to audio input.
+ */
+guac_user_end_handler guac_rdp_audio_end_handler;
+
+/**
+ * Loads Guacamole's "guacai" plugin for FreeRDP, adding support for the
+ * "AUDIO_INPUT" dynamic virtual channel. This function must ONLY be called
+ * after FreeRDP's "drdynvc" virtual channel plugin has been loaded.
+ *
+ * @param context
+ * The rdpContext associated with the active RDP session.
+ */
+void guac_rdp_audio_load_plugin(rdpContext* context);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/21ab9d76/src/protocols/rdp/guac_ai/ai_service.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_service.c b/src/protocols/rdp/guac_ai/ai_service.c
new file mode 100644
index 0000000..15490a0
--- /dev/null
+++ b/src/protocols/rdp/guac_ai/ai_service.c
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+
+#include "ai_service.h"
+#include "rdp.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <freerdp/freerdp.h>
+#include <freerdp/constants.h>
+#include <freerdp/dvc.h>
+#include <guacamole/client.h>
+
+#ifdef ENABLE_WINPR
+#include <winpr/stream.h>
+#else
+#include "compat/winpr-stream.h"
+#endif
+
+/**
+ * Entry point for AUDIO_INPUT dynamic virtual channel.
+ */
+int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) {
+
+ rdpSettings* settings = pEntryPoints->GetRdpSettings(pEntryPoints);
+ freerdp* instance = settings->instance;
+ rdpContext* context = instance->context;
+ guac_client* client = ((rdp_freerdp_context*) context)->client;
+
+ /* STUB */
+ guac_client_log(client, GUAC_LOG_DEBUG,
+ "STUB: AUDIO_INPUT DVC (entry point)");
+
+ return 1;
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/21ab9d76/src/protocols/rdp/guac_ai/ai_service.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/guac_ai/ai_service.h b/src/protocols/rdp/guac_ai/ai_service.h
new file mode 100644
index 0000000..caa62ad
--- /dev/null
+++ b/src/protocols/rdp/guac_ai/ai_service.h
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+#ifndef GUAC_RDP_AI_SERVICE_H
+#define GUAC_RDP_AI_SERVICE_H
+
+#include "config.h"
+
+/* STUB */
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/21ab9d76/src/protocols/rdp/rdp.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c
index cd3ee23..7859e20 100644
--- a/src/protocols/rdp/rdp.c
+++ b/src/protocols/rdp/rdp.c
@@ -19,6 +19,7 @@
#include "config.h"
+#include "audio_input.h"
#include "client.h"
#include "guac_cursor.h"
#include "guac_display.h"
@@ -223,24 +224,33 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
(pChannelConnectedEventHandler) guac_rdp_channel_connected);
#endif
-#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
- /* Load required plugins if display update is enabled */
- if (settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE) {
+ /* Load DRDYNVC plugin if required */
+ if (settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE
+ || settings->enable_audio_input) {
- /* Load virtual channel management plugin (needed by display update) */
+ /* Load virtual channel management plugin */
if (freerdp_channels_load_plugin(channels, instance->settings,
"drdynvc", instance->settings))
guac_client_log(client, GUAC_LOG_WARNING,
- "Failed to load drdynvc plugin. Display update support "
- "will be disabled.");
+ "Failed to load drdynvc plugin. Display update and audio "
+ "input support will be disabled.");
/* Init display update plugin if "drdynvc" was loaded successfully */
- else
- guac_rdp_disp_load_plugin(instance->context);
-
- }
+ else {
+#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
+ /* Load "disp" plugin for display update */
+ if (settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE)
+ guac_rdp_disp_load_plugin(instance->context);
#endif
+ /* Load "AUDIO_INPUT" plugin for audio input*/
+ if (settings->enable_audio_input)
+ guac_rdp_audio_load_plugin(instance->context);
+
+ }
+
+ } /* end if drdynvc required */
+
/* Load clipboard plugin */
if (freerdp_channels_load_plugin(channels, instance->settings,
"cliprdr", NULL))
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/21ab9d76/src/protocols/rdp/rdp_settings.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_settings.c b/src/protocols/rdp/rdp_settings.c
index bc1d831..4f9343c 100644
--- a/src/protocols/rdp/rdp_settings.c
+++ b/src/protocols/rdp/rdp_settings.c
@@ -90,6 +90,7 @@ const char* GUAC_RDP_CLIENT_ARGS[] = {
"recording-name",
"create-recording-path",
"resize-method",
+ "enable-audio-input",
NULL
};
@@ -378,6 +379,12 @@ enum RDP_ARGS_IDX {
*/
IDX_RESIZE_METHOD,
+ /**
+ * "true" if audio input (microphone) should be enabled for the RDP
+ * connection, "false" or blank otherwise.
+ */
+ IDX_ENABLE_AUDIO_INPUT,
+
RDP_ARGS_COUNT
};
@@ -739,6 +746,11 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user,
settings->resize_method = GUAC_RESIZE_NONE;
}
+ /* Audio input enable/disable */
+ settings->enable_audio_input =
+ guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
+ IDX_ENABLE_AUDIO_INPUT, 0);
+
/* Success */
return settings;
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/21ab9d76/src/protocols/rdp/rdp_settings.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_settings.h b/src/protocols/rdp/rdp_settings.h
index 7e3fec9..90c79ce 100644
--- a/src/protocols/rdp/rdp_settings.h
+++ b/src/protocols/rdp/rdp_settings.h
@@ -378,6 +378,11 @@ typedef struct guac_rdp_settings {
*/
guac_rdp_resize_method resize_method;
+ /**
+ * Whether audio input (microphone) is enabled.
+ */
+ int enable_audio_input;
+
} guac_rdp_settings;
/**
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/21ab9d76/src/protocols/rdp/user.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/user.c b/src/protocols/rdp/user.c
index af597db..ef13205 100644
--- a/src/protocols/rdp/user.c
+++ b/src/protocols/rdp/user.c
@@ -19,6 +19,7 @@
#include "config.h"
+#include "audio_input.h"
#include "input.h"
#include "guac_display.h"
#include "user.h"
@@ -65,6 +66,10 @@ int guac_rdp_user_join_handler(guac_user* user, int argc, char** argv) {
return 1;
}
+ /* Handle inbound audio streams if audio input is enabled */
+ if (settings->enable_audio_input)
+ user->audio_handler = guac_rdp_audio_handler;
+
}
/* If not owner, synchronize with current state */
[03/26] incubator-guacamole-server git commit: GUACAMOLE-25: Add
status code reporting the normal closure of a resource.
Posted by jm...@apache.org.
GUACAMOLE-25: Add status code reporting the normal closure of a resource.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/5030c060
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/5030c060
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/5030c060
Branch: refs/heads/master
Commit: 5030c0603a9d8aa4a65c31afcb20e50ca71136f4
Parents: 166eba1
Author: Michael Jumper <mj...@apache.org>
Authored: Mon May 2 00:09:17 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Wed May 25 13:50:28 2016 -0700
----------------------------------------------------------------------
src/libguac/guacamole/protocol-types.h | 6 ++++++
1 file changed, 6 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/5030c060/src/libguac/guacamole/protocol-types.h
----------------------------------------------------------------------
diff --git a/src/libguac/guacamole/protocol-types.h b/src/libguac/guacamole/protocol-types.h
index ee9c668..ea76910 100644
--- a/src/libguac/guacamole/protocol-types.h
+++ b/src/libguac/guacamole/protocol-types.h
@@ -88,6 +88,12 @@ typedef enum guac_protocol_status {
GUAC_PROTOCOL_STATUS_RESOURCE_CONFLICT = 0x205,
/**
+ * The operation could not be performed as the requested resource is now
+ * closed.
+ */
+ GUAC_PROTOCOL_STATUS_RESOURCE_CLOSED = 0x0206,
+
+ /**
* The operation could not be performed because bad parameters were
* given.
*/
[26/26] incubator-guacamole-server git commit: GUACAMOLE-25: Merge
RDP audio input addition."
Posted by jm...@apache.org.
GUACAMOLE-25: Merge RDP audio input addition."
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/995b6d66
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/995b6d66
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/995b6d66
Branch: refs/heads/master
Commit: 995b6d669ac4bfd620aa5fe123c6dc4212956e28
Parents: ec93a29 402b039
Author: James Muehlner <ja...@guac-dev.org>
Authored: Thu Jun 2 11:44:16 2016 -0700
Committer: James Muehlner <ja...@guac-dev.org>
Committed: Thu Jun 2 11:44:16 2016 -0700
----------------------------------------------------------------------
configure.ac | 47 +++
src/libguac/guacamole/protocol-types.h | 6 +
src/protocols/rdp/Makefile.am | 46 +++
src/protocols/rdp/audio_input.c | 484 +++++++++++++++++++++++++++
src/protocols/rdp/audio_input.h | 313 +++++++++++++++++
src/protocols/rdp/client.c | 5 +
src/protocols/rdp/compat/winpr-stream.c | 23 +-
src/protocols/rdp/dvc.c | 183 ++++++++++
src/protocols/rdp/dvc.h | 138 ++++++++
src/protocols/rdp/guac_ai/ai_messages.c | 336 +++++++++++++++++++
src/protocols/rdp/guac_ai/ai_messages.h | 216 ++++++++++++
src/protocols/rdp/guac_ai/ai_service.c | 349 +++++++++++++++++++
src/protocols/rdp/guac_ai/ai_service.h | 108 ++++++
src/protocols/rdp/ptr_string.c | 55 +++
src/protocols/rdp/ptr_string.h | 57 ++++
src/protocols/rdp/rdp.c | 34 +-
src/protocols/rdp/rdp.h | 6 +
src/protocols/rdp/rdp_disp.c | 11 +-
src/protocols/rdp/rdp_disp.h | 23 +-
src/protocols/rdp/rdp_settings.c | 23 ++
src/protocols/rdp/rdp_settings.h | 5 +
src/protocols/rdp/user.c | 5 +
22 files changed, 2439 insertions(+), 34 deletions(-)
----------------------------------------------------------------------