From 271f7fbb2fea735da02b726875a4a254448f1334 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 27 Oct 2013 19:53:34 -0700 Subject: [PATCH] Add ack instruction handler. --- src/libguac/client-handlers.c | 24 ++++++++++++++++++++++++ src/libguac/client-handlers.h | 7 +++++++ src/libguac/guacamole/client.h | 26 ++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/src/libguac/client-handlers.c b/src/libguac/client-handlers.c index 4f1e253f..7a69d72d 100644 --- a/src/libguac/client-handlers.c +++ b/src/libguac/client-handlers.c @@ -52,6 +52,7 @@ __guac_instruction_handler_mapping __guac_instruction_handler_map[] = { {"disconnect", __guac_handle_disconnect}, {"size", __guac_handle_size}, {"file", __guac_handle_file}, + {"ack", __guac_handle_ack}, {"blob", __guac_handle_blob}, {"end", __guac_handle_end}, {NULL, NULL} @@ -166,6 +167,29 @@ int __guac_handle_file(guac_client* client, guac_instruction* instruction) { return 0; } +int __guac_handle_ack(guac_client* client, guac_instruction* instruction) { + + guac_stream* stream; + + /* Validate stream index */ + int stream_index = atoi(instruction->argv[0]); + if (stream_index < 0 || stream_index >= GUAC_CLIENT_MAX_STREAMS) + return 0; + + stream = &(client->__streams[stream_index]); + + /* Validate initialization of stream */ + if (stream->index == GUAC_CLIENT_CLOSED_STREAM_INDEX) + return 0; + + /* If handler defined, call it */ + if (client->ack_handler) + return client->ack_handler(client, stream, instruction->argv[1], + atoi(instruction->argv[2])); + + return 0; +} + int __guac_handle_blob(guac_client* client, guac_instruction* instruction) { guac_stream* stream; diff --git a/src/libguac/client-handlers.h b/src/libguac/client-handlers.h index 28ac7fa2..b09efaab 100644 --- a/src/libguac/client-handlers.h +++ b/src/libguac/client-handlers.h @@ -106,6 +106,13 @@ int __guac_handle_clipboard(guac_client* client, guac_instruction* instruction); */ int __guac_handle_file(guac_client* client, guac_instruction* instruction); +/** + * Internal initial handler for the ack instruction. When a ack instruction + * is received, this handler will be called. The client's ack handler will + * be invoked if defined. + */ +int __guac_handle_ack(guac_client* client, guac_instruction* instruction); + /** * Internal initial handler for the blob instruction. When a blob instruction * is received, this handler will be called. The client's blob handler will diff --git a/src/libguac/guacamole/client.h b/src/libguac/guacamole/client.h index c738ee46..f1f79d4d 100644 --- a/src/libguac/guacamole/client.h +++ b/src/libguac/guacamole/client.h @@ -44,6 +44,7 @@ #include "instruction.h" #include "layer.h" #include "pool.h" +#include "protocol.h" #include "socket.h" #include "stream.h" #include "timestamp.h" @@ -105,6 +106,12 @@ typedef int guac_client_file_handler(guac_client* client, guac_stream* stream, typedef int guac_client_blob_handler(guac_client* client, guac_stream* stream, void* data, int length); +/** + * Handler for Guacamole stream ack events. + */ +typedef int guac_client_ack_handler(guac_client* client, guac_stream* stream, + char* error, guac_protocol_status status); + /** * Handler for Guacamole stream end events. */ @@ -401,6 +408,25 @@ struct guac_client { */ guac_client_file_handler* file_handler; + /** + * Handler for ack events sent by the Guacamole web-client. + * + * The handler takes a guac_stream which contains the stream index and + * will persist through the duration of the transfer, a string containing + * the error or status message, and a status code. + * + * Example: + * @code + * int ack_handler(guac_client* client, guac_stream* stream, + * char* error, guac_protocol_status status); + * + * int guac_client_init(guac_client* client, int argc, char** argv) { + * client->ack_handler = ack_handler; + * } + * @endcode + */ + guac_client_ack_handler* ack_handler; + /** * Handler for blob events sent by the Guacamole web-client. *