From 0dddf47af06cf6462390960b8b917c88d76837a7 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 2 Nov 2015 15:55:52 -0800 Subject: [PATCH 1/4] GUAC-1196: Use guac_client to access guac_audio_stream rather than storing the audio stream directly. --- src/protocols/rdp/client.c | 4 +- .../rdp/guac_rdpsnd/rdpsnd_messages.c | 61 +++++++++++-------- .../rdp/guac_rdpsnd/rdpsnd_messages.h | 19 ++---- .../rdp/guac_rdpsnd/rdpsnd_service.c | 30 ++++----- .../rdp/guac_rdpsnd/rdpsnd_service.h | 9 +-- 5 files changed, 60 insertions(+), 63 deletions(-) diff --git a/src/protocols/rdp/client.c b/src/protocols/rdp/client.c index a669a101..49915dcf 100644 --- a/src/protocols/rdp/client.c +++ b/src/protocols/rdp/client.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Glyptodon LLC + * Copyright (C) 2015 Glyptodon LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -296,7 +296,7 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) { /* Load sound plugin */ if (freerdp_channels_load_plugin(channels, instance->settings, - "guacsnd", guac_client_data->audio)) + "guacsnd", client)) guac_client_log(client, GUAC_LOG_WARNING, "Failed to load guacsnd plugin. Audio will not work."); diff --git a/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c b/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c index b2488dfd..7bb2e541 100644 --- a/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c +++ b/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Glyptodon LLC + * Copyright (C) 2015 Glyptodon LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -44,8 +44,7 @@ /* MESSAGE HANDLERS */ void guac_rdpsnd_formats_handler(guac_rdpsndPlugin* rdpsnd, - guac_audio_stream* audio, wStream* input_stream, - guac_rdpsnd_pdu_header* header) { + wStream* input_stream, guac_rdpsnd_pdu_header* header) { int server_format_count; int server_version; @@ -55,8 +54,12 @@ void guac_rdpsnd_formats_handler(guac_rdpsndPlugin* rdpsnd, int output_body_size; unsigned char* output_stream_end; - rdp_guac_client_data* guac_client_data = - (rdp_guac_client_data*) audio->client->data; + /* Get associated client data */ + guac_client* client = rdpsnd->client; + rdp_guac_client_data* client_data = (rdp_guac_client_data*) client->data; + + /* Get audio stream from client data */ + guac_audio_stream* audio = client_data->audio; /* Format header */ Stream_Seek(input_stream, 14); @@ -128,7 +131,7 @@ void guac_rdpsnd_formats_handler(guac_rdpsndPlugin* rdpsnd, rdpsnd->formats[current].bps = bps; /* Log format */ - guac_client_log(audio->client, GUAC_LOG_INFO, + guac_client_log(client, GUAC_LOG_INFO, "Accepted format: %i-bit PCM with %i channels at " "%i Hz", bps, channels, rate); @@ -149,7 +152,7 @@ void guac_rdpsnd_formats_handler(guac_rdpsndPlugin* rdpsnd, /* Otherwise, log that we dropped one */ else - guac_client_log(audio->client, GUAC_LOG_INFO, + guac_client_log(client, GUAC_LOG_INFO, "Dropped valid format: %i-bit PCM with %i channels at " "%i Hz", bps, channels, rate); @@ -174,7 +177,7 @@ void guac_rdpsnd_formats_handler(guac_rdpsndPlugin* rdpsnd, Stream_SetPointer(output_stream, output_stream_end); /* Send accepted formats */ - pthread_mutex_lock(&(guac_client_data->rdp_lock)); + pthread_mutex_lock(&(client_data->rdp_lock)); svc_plugin_send((rdpSvcPlugin*)rdpsnd, output_stream); /* If version greater than 6, must send Quality Mode PDU */ @@ -191,20 +194,20 @@ void guac_rdpsnd_formats_handler(guac_rdpsndPlugin* rdpsnd, svc_plugin_send((rdpSvcPlugin*)rdpsnd, output_stream); } - pthread_mutex_unlock(&(guac_client_data->rdp_lock)); + pthread_mutex_unlock(&(client_data->rdp_lock)); } /* server is getting a feel of the round trip time */ void guac_rdpsnd_training_handler(guac_rdpsndPlugin* rdpsnd, - guac_audio_stream* audio, wStream* input_stream, - guac_rdpsnd_pdu_header* header) { + wStream* input_stream, guac_rdpsnd_pdu_header* header) { int data_size; wStream* output_stream; - rdp_guac_client_data* guac_client_data = - (rdp_guac_client_data*) audio->client->data; + /* Get associated client data */ + guac_client* client = rdpsnd->client; + rdp_guac_client_data* client_data = (rdp_guac_client_data*) client->data; /* Read timestamp and data size */ Stream_Read_UINT16(input_stream, rdpsnd->server_timestamp); @@ -218,18 +221,24 @@ void guac_rdpsnd_training_handler(guac_rdpsndPlugin* rdpsnd, Stream_Write_UINT16(output_stream, rdpsnd->server_timestamp); Stream_Write_UINT16(output_stream, data_size); - pthread_mutex_lock(&(guac_client_data->rdp_lock)); + pthread_mutex_lock(&(client_data->rdp_lock)); svc_plugin_send((rdpSvcPlugin*) rdpsnd, output_stream); - pthread_mutex_unlock(&(guac_client_data->rdp_lock)); + pthread_mutex_unlock(&(client_data->rdp_lock)); } void guac_rdpsnd_wave_info_handler(guac_rdpsndPlugin* rdpsnd, - guac_audio_stream* audio, wStream* input_stream, - guac_rdpsnd_pdu_header* header) { + wStream* input_stream, guac_rdpsnd_pdu_header* header) { int format; + /* Get associated client data */ + guac_client* client = rdpsnd->client; + rdp_guac_client_data* client_data = (rdp_guac_client_data*) client->data; + + /* Get audio stream from client data */ + guac_audio_stream* audio = client_data->audio; + /* Read wave information */ Stream_Read_UINT16(input_stream, rdpsnd->server_timestamp); Stream_Read_UINT16(input_stream, format); @@ -256,13 +265,16 @@ void guac_rdpsnd_wave_info_handler(guac_rdpsndPlugin* rdpsnd, } void guac_rdpsnd_wave_handler(guac_rdpsndPlugin* rdpsnd, - guac_audio_stream* audio, wStream* input_stream, - guac_rdpsnd_pdu_header* header) { + wStream* input_stream, guac_rdpsnd_pdu_header* header) { rdpSvcPlugin* plugin = (rdpSvcPlugin*)rdpsnd; - rdp_guac_client_data* guac_client_data = - (rdp_guac_client_data*) audio->client->data; + /* Get associated client data */ + guac_client* client = rdpsnd->client; + rdp_guac_client_data* client_data = (rdp_guac_client_data*) client->data; + + /* Get audio stream from client data */ + guac_audio_stream* audio = client_data->audio; /* Wave Confirmation PDU */ wStream* output_stream = Stream_New(NULL, 8); @@ -286,9 +298,9 @@ void guac_rdpsnd_wave_handler(guac_rdpsndPlugin* rdpsnd, Stream_Write_UINT8(output_stream, 0); /* Send Wave Confirmation PDU */ - pthread_mutex_lock(&(guac_client_data->rdp_lock)); + pthread_mutex_lock(&(client_data->rdp_lock)); svc_plugin_send(plugin, output_stream); - pthread_mutex_unlock(&(guac_client_data->rdp_lock)); + pthread_mutex_unlock(&(client_data->rdp_lock)); /* We no longer expect to receive wave data */ rdpsnd->next_pdu_is_wave = FALSE; @@ -296,8 +308,7 @@ void guac_rdpsnd_wave_handler(guac_rdpsndPlugin* rdpsnd, } void guac_rdpsnd_close_handler(guac_rdpsndPlugin* rdpsnd, - guac_audio_stream* audio, wStream* input_stream, - guac_rdpsnd_pdu_header* header) { + wStream* input_stream, guac_rdpsnd_pdu_header* header) { /* STUB: Do nothing for now */ diff --git a/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.h b/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.h index 82339d09..8050c4a9 100644 --- a/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.h +++ b/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Glyptodon LLC + * Copyright (C) 2015 Glyptodon LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,8 +28,6 @@ #include "rdpsnd_service.h" -#include - #ifdef ENABLE_WINPR #include #else @@ -125,36 +123,31 @@ typedef struct guac_rdpsnd_pdu_header { * Handler for the SNDC_FORMATS (Server Audio Formats and Version) PDU. */ void guac_rdpsnd_formats_handler(guac_rdpsndPlugin* rdpsnd, - guac_audio_stream* audio, wStream* input_stream, - guac_rdpsnd_pdu_header* header); + wStream* input_stream, guac_rdpsnd_pdu_header* header); /** * Handler for the SNDC_TRAINING (Training) PDU. */ void guac_rdpsnd_training_handler(guac_rdpsndPlugin* rdpsnd, - guac_audio_stream* audio, wStream* input_stream, - guac_rdpsnd_pdu_header* header); + wStream* input_stream, guac_rdpsnd_pdu_header* header); /** * Handler for the SNDC_WAVE (WaveInfo) PDU. */ void guac_rdpsnd_wave_info_handler(guac_rdpsndPlugin* rdpsnd, - guac_audio_stream* audio, wStream* input_stream, - guac_rdpsnd_pdu_header* header); + wStream* input_stream, guac_rdpsnd_pdu_header* header); /** * Handler for the SNDWAV (Wave) PDU which follows any WaveInfo PDU. */ void guac_rdpsnd_wave_handler(guac_rdpsndPlugin* rdpsnd, - guac_audio_stream* audio, wStream* input_stream, - guac_rdpsnd_pdu_header* header); + wStream* input_stream, guac_rdpsnd_pdu_header* header); /** * Handler for the SNDC_CLOSE (Close) PDU. */ void guac_rdpsnd_close_handler(guac_rdpsndPlugin* rdpsnd, - guac_audio_stream* audio, wStream* input_stream, - guac_rdpsnd_pdu_header* header); + wStream* input_stream, guac_rdpsnd_pdu_header* header); #endif diff --git a/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.c b/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.c index 7ed4dfcc..30810ef7 100644 --- a/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.c +++ b/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Glyptodon LLC + * Copyright (C) 2015 Glyptodon LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,7 +30,6 @@ #include #include -#include #include #ifdef ENABLE_WINPR @@ -73,11 +72,11 @@ void guac_rdpsnd_process_connect(rdpSvcPlugin* plugin) { guac_rdpsndPlugin* rdpsnd = (guac_rdpsndPlugin*) plugin; - /* Get audio stream from plugin parameters */ - guac_audio_stream* audio = rdpsnd->audio = - (guac_audio_stream*) plugin->channel_entry_points.pExtendedData; + /* Get client from plugin parameters */ + guac_client* client = rdpsnd->client = + (guac_client*) plugin->channel_entry_points.pExtendedData; - /* NULL out pExtendedData so we don't lose our guac_audio_stream due to an + /* NULL out pExtendedData so we don't lose our guac_client due to an * automatic free() within libfreerdp */ plugin->channel_entry_points.pExtendedData = NULL; @@ -87,7 +86,7 @@ void guac_rdpsnd_process_connect(rdpSvcPlugin* plugin) { #endif /* Log that sound has been loaded */ - guac_client_log(audio->client, GUAC_LOG_INFO, "guacsnd connected."); + guac_client_log(client, GUAC_LOG_INFO, "guacsnd connected."); } @@ -105,9 +104,6 @@ void guac_rdpsnd_process_receive(rdpSvcPlugin* plugin, guac_rdpsndPlugin* rdpsnd = (guac_rdpsndPlugin*) plugin; guac_rdpsnd_pdu_header header; - /* Get audio stream from plugin */ - guac_audio_stream* audio = rdpsnd->audio; - /* Read RDPSND PDU header */ Stream_Read_UINT8(input_stream, header.message_type); Stream_Seek_UINT8(input_stream); @@ -118,7 +114,7 @@ void guac_rdpsnd_process_receive(rdpSvcPlugin* plugin, * ignore the header and parse as a Wave PDU. */ if (rdpsnd->next_pdu_is_wave) { - guac_rdpsnd_wave_handler(rdpsnd, audio, input_stream, &header); + guac_rdpsnd_wave_handler(rdpsnd, input_stream, &header); return; } @@ -127,26 +123,22 @@ void guac_rdpsnd_process_receive(rdpSvcPlugin* plugin, /* Server Audio Formats and Version PDU */ case SNDC_FORMATS: - guac_rdpsnd_formats_handler(rdpsnd, audio, - input_stream, &header); + guac_rdpsnd_formats_handler(rdpsnd, input_stream, &header); break; /* Training PDU */ case SNDC_TRAINING: - guac_rdpsnd_training_handler(rdpsnd, audio, - input_stream, &header); + guac_rdpsnd_training_handler(rdpsnd, input_stream, &header); break; /* WaveInfo PDU */ case SNDC_WAVE: - guac_rdpsnd_wave_info_handler(rdpsnd, audio, - input_stream, &header); + guac_rdpsnd_wave_info_handler(rdpsnd, input_stream, &header); break; /* Close PDU */ case SNDC_CLOSE: - guac_rdpsnd_close_handler(rdpsnd, audio, - input_stream, &header); + guac_rdpsnd_close_handler(rdpsnd, input_stream, &header); break; } diff --git a/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.h b/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.h index 8e6b976d..dadf7fff 100644 --- a/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.h +++ b/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Glyptodon LLC + * Copyright (C) 2015 Glyptodon LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ #include "config.h" #include -#include +#include #ifdef ENABLE_WINPR #include @@ -80,9 +80,10 @@ typedef struct guac_rdpsndPlugin { rdpSvcPlugin plugin; /** - * The current audio stream. + * The Guacamole client associated with the guac_audio_stream that this + * plugin should use to stream received audio packets. */ - guac_audio_stream* audio; + guac_client* client; /** * The block number of the last SNDC_WAVE (WaveInfo) PDU received. From c3e2754ec45826e838ced2334c5ba59ca1565faf Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 2 Nov 2015 16:54:37 -0800 Subject: [PATCH 2/4] GUAC-1196: Load RDPSND if RDPDR is loaded, but do not actually handle audio unless enabled. --- src/protocols/rdp/client.c | 26 ++-- .../rdp/guac_rdpsnd/rdpsnd_messages.c | 129 ++++++++++-------- 2 files changed, 85 insertions(+), 70 deletions(-) diff --git a/src/protocols/rdp/client.c b/src/protocols/rdp/client.c index 49915dcf..71f2ea11 100644 --- a/src/protocols/rdp/client.c +++ b/src/protocols/rdp/client.c @@ -291,17 +291,8 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) { GUAC_RDP_AUDIO_CHANNELS, GUAC_RDP_AUDIO_BPS); - /* If an encoding is available, load the sound plugin */ - if (guac_client_data->audio != NULL) { - - /* Load sound plugin */ - if (freerdp_channels_load_plugin(channels, instance->settings, - "guacsnd", client)) - guac_client_log(client, GUAC_LOG_WARNING, - "Failed to load guacsnd plugin. Audio will not work."); - - } - else + /* Warn if no audio encoding is available */ + if (guac_client_data->audio == NULL) guac_client_log(client, GUAC_LOG_INFO, "No available audio encoding. Sound disabled."); @@ -321,7 +312,7 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) { } - /* If RDPDR required, load it */ + /* If RDPSND/RDPDR required, load them */ if (guac_client_data->settings.printing_enabled || guac_client_data->settings.drive_enabled || guac_client_data->settings.audio_enabled) { @@ -330,7 +321,16 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) { if (freerdp_channels_load_plugin(channels, instance->settings, "guacdr", client)) guac_client_log(client, GUAC_LOG_WARNING, - "Failed to load guacdr plugin. Drive redirection and printing will not work."); + "Failed to load guacdr plugin. Drive redirection and " + "printing will not work. Sound MAY not work."); + + /* Load RDPSND plugin */ + if (freerdp_channels_load_plugin(channels, instance->settings, + "guacsnd", client)) + guac_client_log(client, GUAC_LOG_WARNING, + "Failed to load guacsnd alongside guacdr plugin. Sound " + "will not work. Drive redirection and printing MAY not " + "work."); } diff --git a/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c b/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c index 7bb2e541..09817c39 100644 --- a/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c +++ b/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c @@ -92,75 +92,86 @@ void guac_rdpsnd_formats_handler(guac_rdpsndPlugin* rdpsnd, Stream_Write_UINT16(output_stream, 6); Stream_Write_UINT8(output_stream, 0); - /* Check each server format, respond if supported */ - for (i=0; i < server_format_count; i++) { + /* Check each server format, respond if supported and audio is enabled */ + if (audio != NULL) { + for (i=0; i < server_format_count; i++) { - unsigned char* format_start; + unsigned char* format_start; - int format_tag; - int channels; - int rate; - int bps; - int body_size; + int format_tag; + int channels; + int rate; + int bps; + int body_size; - /* Remember position in stream */ - Stream_GetPointer(input_stream, format_start); + /* Remember position in stream */ + Stream_GetPointer(input_stream, format_start); - /* Read format */ - Stream_Read_UINT16(input_stream, format_tag); - Stream_Read_UINT16(input_stream, channels); - Stream_Read_UINT32(input_stream, rate); - Stream_Seek_UINT32(input_stream); - Stream_Seek_UINT16(input_stream); - Stream_Read_UINT16(input_stream, bps); + /* Read format */ + Stream_Read_UINT16(input_stream, format_tag); + Stream_Read_UINT16(input_stream, channels); + Stream_Read_UINT32(input_stream, rate); + Stream_Seek_UINT32(input_stream); + Stream_Seek_UINT16(input_stream); + Stream_Read_UINT16(input_stream, bps); - /* Skip past extra data */ - Stream_Read_UINT16(input_stream, body_size); - Stream_Seek(input_stream, body_size); + /* Skip past extra data */ + Stream_Read_UINT16(input_stream, body_size); + Stream_Seek(input_stream, body_size); - /* If PCM, accept */ - if (format_tag == WAVE_FORMAT_PCM) { + /* If PCM, accept */ + if (format_tag == WAVE_FORMAT_PCM) { - /* If can fit another format, accept it */ - if (rdpsnd->format_count < GUAC_RDP_MAX_FORMATS) { + /* If can fit another format, accept it */ + if (rdpsnd->format_count < GUAC_RDP_MAX_FORMATS) { - /* Add channel */ - int current = rdpsnd->format_count++; - rdpsnd->formats[current].rate = rate; - rdpsnd->formats[current].channels = channels; - rdpsnd->formats[current].bps = bps; + /* Add channel */ + int current = rdpsnd->format_count++; + rdpsnd->formats[current].rate = rate; + rdpsnd->formats[current].channels = channels; + rdpsnd->formats[current].bps = bps; - /* Log format */ - guac_client_log(client, GUAC_LOG_INFO, - "Accepted format: %i-bit PCM with %i channels at " - "%i Hz", - bps, channels, rate); + /* Log format */ + guac_client_log(client, GUAC_LOG_INFO, + "Accepted format: %i-bit PCM with %i channels at " + "%i Hz", + bps, channels, rate); - /* Ensure audio stream is configured to use accepted format */ - guac_audio_stream_reset(audio, NULL, rate, channels, bps); + /* Ensure audio stream is configured to use accepted + * format */ + guac_audio_stream_reset(audio, NULL, rate, channels, bps); - /* Queue format for sending as accepted */ - Stream_EnsureRemainingCapacity(output_stream, 18 + body_size); - Stream_Write(output_stream, format_start, 18 + body_size); + /* Queue format for sending as accepted */ + Stream_EnsureRemainingCapacity(output_stream, + 18 + body_size); + Stream_Write(output_stream, format_start, 18 + body_size); - /* - * BEWARE that using Stream_EnsureRemainingCapacity means that any - * pointers returned via Stream_GetPointer on output_stream are invalid. - */ + /* + * BEWARE that using Stream_EnsureRemainingCapacity means + * that any pointers returned via Stream_GetPointer on + * output_stream are invalid. + */ + + } + + /* Otherwise, log that we dropped one */ + else + guac_client_log(client, GUAC_LOG_INFO, + "Dropped valid format: %i-bit PCM with %i " + "channels at %i Hz", + bps, channels, rate); } - /* Otherwise, log that we dropped one */ - else - guac_client_log(client, GUAC_LOG_INFO, - "Dropped valid format: %i-bit PCM with %i channels at " - "%i Hz", - bps, channels, rate); - } - } + /* Otherwise, ignore all supported formats as we do not intend to actually + * receive audio */ + else + guac_client_log(client, GUAC_LOG_DEBUG, + "Audio explicitly disabled. Ignoring supported formats."); + /* Calculate size of PDU */ output_body_size = Stream_GetPosition(output_stream) - 4; Stream_GetPointer(output_stream, output_stream_end); @@ -257,10 +268,11 @@ void guac_rdpsnd_wave_info_handler(guac_rdpsndPlugin* rdpsnd, rdpsnd->next_pdu_is_wave = TRUE; /* Reset audio stream if format has changed */ - guac_audio_stream_reset(audio, NULL, - rdpsnd->formats[format].rate, - rdpsnd->formats[format].channels, - rdpsnd->formats[format].bps); + if (audio != NULL) + guac_audio_stream_reset(audio, NULL, + rdpsnd->formats[format].rate, + rdpsnd->formats[format].channels, + rdpsnd->formats[format].bps); } @@ -286,8 +298,11 @@ void guac_rdpsnd_wave_handler(guac_rdpsndPlugin* rdpsnd, memcpy(buffer, rdpsnd->initial_wave_data, 4); /* Write rest of audio packet */ - guac_audio_stream_write_pcm(audio, buffer, rdpsnd->incoming_wave_size + 4); - guac_audio_stream_flush(audio); + if (audio != NULL) { + guac_audio_stream_write_pcm(audio, buffer, + rdpsnd->incoming_wave_size + 4); + guac_audio_stream_flush(audio); + } /* Write Wave Confirmation PDU */ Stream_Write_UINT8(output_stream, SNDC_WAVECONFIRM); From 63f3652c54c8a1d13689baa147ae8a405c2f84d8 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 2 Nov 2015 17:15:35 -0800 Subject: [PATCH 3/4] GUAC-1196: Document RDPSND message handlers. --- .../rdp/guac_rdpsnd/rdpsnd_messages.h | 82 +++++++++++++++++-- 1 file changed, 77 insertions(+), 5 deletions(-) diff --git a/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.h b/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.h index 8050c4a9..f75235a9 100644 --- a/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.h +++ b/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.h @@ -120,31 +120,103 @@ typedef struct guac_rdpsnd_pdu_header { } guac_rdpsnd_pdu_header; /** - * Handler for the SNDC_FORMATS (Server Audio Formats and Version) PDU. + * Handler for the SNDC_FORMATS (Server Audio Formats and Version) PDU. The + * SNDC_FORMATS PDU describes all audio formats supported by the RDP server, as + * well as the version of RDPSND implemented. + * + * @param rdpsnd + * The Guacamole RDPSND plugin receiving the SNDC_FORMATS PDU. + * + * @param input_stream + * The FreeRDP input stream containing the remaining raw bytes (after the + * common header) of the SNDC_FORMATS PDU. + * + * @param header + * The header content of the SNDC_FORMATS PDU. All RDPSND messages contain + * the same header information. */ void guac_rdpsnd_formats_handler(guac_rdpsndPlugin* rdpsnd, wStream* input_stream, guac_rdpsnd_pdu_header* header); /** - * Handler for the SNDC_TRAINING (Training) PDU. + * Handler for the SNDC_TRAINING (Training) PDU. The SNDC_TRAINING PDU is used + * to by RDP servers to test audio streaming latency, etc. without actually + * sending audio data. See: + * + * https://msdn.microsoft.com/en-us/library/cc240961.aspx + * + * @param rdpsnd + * The Guacamole RDPSND plugin receiving the SNDC_TRAINING PDU. + * + * @param input_stream + * The FreeRDP input stream containing the remaining raw bytes (after the + * common header) of the SNDC_TRAINING PDU. + * + * @param header + * The header content of the SNDC_TRAINING PDU. All RDPSND messages contain + * the same header information. */ void guac_rdpsnd_training_handler(guac_rdpsndPlugin* rdpsnd, wStream* input_stream, guac_rdpsnd_pdu_header* header); /** - * Handler for the SNDC_WAVE (WaveInfo) PDU. + * Handler for the SNDC_WAVE (WaveInfo) PDU. The SNDC_WAVE immediately precedes + * a SNDWAV PDU and describes the data about to be received. It also (very + * strangely) contains exactly 4 bytes of audio data. The following SNDWAV PDU + * then contains 4 bytes of padding prior to the audio data where it would make + * perfect sense for this data to go. See: + * + * https://msdn.microsoft.com/en-us/library/cc240963.aspx + * + * @param rdpsnd + * The Guacamole RDPSND plugin receiving the SNDC_WAVE PDU. + * + * @param input_stream + * The FreeRDP input stream containing the remaining raw bytes (after the + * common header) of the SNDC_WAVE PDU. + * + * @param header + * The header content of the SNDC_WAVE PDU. All RDPSND messages contain + * the same header information. */ void guac_rdpsnd_wave_info_handler(guac_rdpsndPlugin* rdpsnd, wStream* input_stream, guac_rdpsnd_pdu_header* header); /** - * Handler for the SNDWAV (Wave) PDU which follows any WaveInfo PDU. + * Handler for the SNDWAV (Wave) PDU which follows any WaveInfo PDU. The SNDWAV + * PDU contains the actual audio data, less the four bytes of audio data + * included in the SNDC_WAVE PDU. + * + * @param rdpsnd + * The Guacamole RDPSND plugin receiving the SNDWAV PDU. + * + * @param input_stream + * The FreeRDP input stream containing the remaining raw bytes (after the + * common header) of the SNDWAV PDU. + * + * @param header + * The header content of the SNDWAV PDU. All RDPSND messages contain + * the same header information. */ void guac_rdpsnd_wave_handler(guac_rdpsndPlugin* rdpsnd, wStream* input_stream, guac_rdpsnd_pdu_header* header); /** - * Handler for the SNDC_CLOSE (Close) PDU. + * Handler for the SNDC_CLOSE (Close) PDU. This PDU is sent when audio + * streaming has stopped. This PDU is currently ignored by Guacamole. See: + * + * https://msdn.microsoft.com/en-us/library/cc240970.aspx + * + * @param rdpsnd + * The Guacamole RDPSND plugin receiving the SNDC_CLOSE PDU. + * + * @param input_stream + * The FreeRDP input stream containing the remaining raw bytes (after the + * common header) of the SNDC_CLOSE PDU. + * + * @param header + * The header content of the SNDC_CLOSE PDU. All RDPSND messages contain + * the same header information. */ void guac_rdpsnd_close_handler(guac_rdpsndPlugin* rdpsnd, wStream* input_stream, guac_rdpsnd_pdu_header* header); From 7fdbc4557515ce19e979a75c46496a54cb68412d Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 2 Nov 2015 17:17:40 -0800 Subject: [PATCH 4/4] GUAC-1196: The close handler should do nothing - it is not a stub. --- src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c b/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c index 09817c39..a0827d3f 100644 --- a/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c +++ b/src/protocols/rdp/guac_rdpsnd/rdpsnd_messages.c @@ -325,7 +325,7 @@ void guac_rdpsnd_wave_handler(guac_rdpsndPlugin* rdpsnd, void guac_rdpsnd_close_handler(guac_rdpsndPlugin* rdpsnd, wStream* input_stream, guac_rdpsnd_pdu_header* header) { - /* STUB: Do nothing for now */ + /* Do nothing */ }