Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 69 additions & 1 deletion src/protocols/rdp/channels/rdpsnd/rdpsnd-messages.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ void guac_rdpsnd_formats_handler(guac_rdp_common_svc* svc,

/* Version and padding */
Stream_Write_UINT8(output_stream, 0);
Stream_Write_UINT16(output_stream, 6);
Stream_Write_UINT16(output_stream, 8);
Stream_Write_UINT8(output_stream, 0);

/* Check each server format, respond if supported and audio is enabled */
Expand Down Expand Up @@ -360,6 +360,74 @@ void guac_rdpsnd_wave_handler(guac_rdp_common_svc* svc,

}

void guac_rdpsnd_wave2_handler(guac_rdp_common_svc* svc,
wStream* input_stream, guac_rdpsnd_pdu_header* header) {

int format;
int block_number;

guac_client* client = svc->client;
guac_rdpsnd* rdpsnd = (guac_rdpsnd*) svc->data;

guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
guac_audio_stream* audio = rdp_client->audio;

int wave_size;
wStream* output_stream;

/* Wave2 body must include 12-byte header before payload. */
if (Stream_GetRemainingLength(input_stream) < 12) {
guac_client_log(client, GUAC_LOG_WARNING, "Audio Wave2 PDU does not "
"contain the expected number of bytes. Sound may not work as "
"expected.");
return;
}

Stream_Read_UINT16(input_stream, rdpsnd->server_timestamp);
Stream_Read_UINT16(input_stream, format);
Stream_Read_UINT8(input_stream, block_number);
Stream_Seek(input_stream, 3); /* bPad */
Stream_Seek(input_stream, 4); /* dwAudioTimeStamp */

wave_size = header->body_size - 12;
if (wave_size <= 0 || Stream_GetRemainingLength(input_stream) < (size_t) wave_size) {
guac_client_log(client, GUAC_LOG_WARNING, "Audio Wave2 PDU contains "
"invalid payload length. Sound may not work as expected.");
return;
}

if (audio != NULL) {

if (format < GUAC_RDP_MAX_FORMATS)
guac_audio_stream_reset(audio, NULL,
rdpsnd->formats[format].rate,
rdpsnd->formats[format].channels,
rdpsnd->formats[format].bps);

else {
guac_client_log(client, GUAC_LOG_WARNING, "RDP server attempted "
"to specify an invalid Wave2 audio format. Sound may not "
"work as expected.");
return;
}

guac_audio_stream_write_pcm(audio, Stream_Pointer(input_stream), wave_size);
guac_audio_stream_flush(audio);

}

output_stream = Stream_New(NULL, 8);
Stream_Write_UINT8(output_stream, SNDC_WAVECONFIRM);
Stream_Write_UINT8(output_stream, 0);
Stream_Write_UINT16(output_stream, 4);
Stream_Write_UINT16(output_stream, rdpsnd->server_timestamp);
Stream_Write_UINT8(output_stream, block_number);
Stream_Write_UINT8(output_stream, 0);

guac_rdp_common_svc_write(svc, output_stream);

}

void guac_rdpsnd_close_handler(guac_rdp_common_svc* svc,
wStream* input_stream, guac_rdpsnd_pdu_header* header) {

Expand Down
18 changes: 17 additions & 1 deletion src/protocols/rdp/channels/rdpsnd/rdpsnd-messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,23 @@ void guac_rdpsnd_wave_info_handler(guac_rdp_common_svc* svc,
void guac_rdpsnd_wave_handler(guac_rdp_common_svc* svc,
wStream* input_stream, guac_rdpsnd_pdu_header* header);

/**
* Handler for the SNDC_WAVE2 PDU. Unlike SNDC_WAVE/SNDWAV, SNDC_WAVE2 carries
* both wave metadata and audio payload within a single message body.
*
* @param svc
* The RDPSND channel receiving the SNDC_WAVE2 PDU.
*
* @param input_stream
* The FreeRDP input stream containing the remaining raw bytes (after the
* common header) of the SNDC_WAVE2 PDU.
*
* @param header
* The header content of the SNDC_WAVE2 PDU.
*/
void guac_rdpsnd_wave2_handler(guac_rdp_common_svc* svc,
wStream* input_stream, guac_rdpsnd_pdu_header* header);

/**
* Handler for the SNDC_CLOSE (Close) PDU. This PDU is sent when audio
* streaming has stopped. This PDU is currently ignored by Guacamole. See:
Expand All @@ -144,4 +161,3 @@ void guac_rdpsnd_close_handler(guac_rdp_common_svc* svc,
wStream* input_stream, guac_rdpsnd_pdu_header* header);

#endif

6 changes: 5 additions & 1 deletion src/protocols/rdp/channels/rdpsnd/rdpsnd.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ void guac_rdpsnd_process_receive(guac_rdp_common_svc* svc,
guac_rdpsnd_wave_info_handler(svc, input_stream, &header);
break;

/* Wave2 PDU */
case SNDC_WAVE2:
guac_rdpsnd_wave2_handler(svc, input_stream, &header);
break;

/* Close PDU */
case SNDC_CLOSE:
guac_rdpsnd_close_handler(svc, input_stream, &header);
Expand Down Expand Up @@ -110,4 +115,3 @@ void guac_rdpsnd_load_plugin(rdpContext* context) {
}

}

Loading