GUACAMOLE-25: Add stub callbacks for AUDIO_INPUT data handling.
This commit is contained in:
parent
9cd89e6580
commit
ac94fd4cd0
@ -37,6 +37,208 @@
|
|||||||
#include "compat/winpr-stream.h"
|
#include "compat/winpr-stream.h"
|
||||||
#endif
|
#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.
|
* Entry point for AUDIO_INPUT dynamic virtual channel.
|
||||||
*/
|
*/
|
||||||
@ -45,9 +247,25 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) {
|
|||||||
ADDIN_ARGV* args = pEntryPoints->GetPluginData(pEntryPoints);
|
ADDIN_ARGV* args = pEntryPoints->GetPluginData(pEntryPoints);
|
||||||
guac_client* client = (guac_client*) guac_rdp_string_to_ptr(args->argv[1]);
|
guac_client* client = (guac_client*) guac_rdp_string_to_ptr(args->argv[1]);
|
||||||
|
|
||||||
/* STUB */
|
/* Pull previously-allocated plugin */
|
||||||
guac_client_log(client, GUAC_LOG_DEBUG,
|
guac_rdp_ai_plugin* ai_plugin = (guac_rdp_ai_plugin*)
|
||||||
"STUB: AUDIO_INPUT DVC (entry point)");
|
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;
|
return 1;
|
||||||
|
|
||||||
|
@ -17,13 +17,86 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef GUAC_RDP_AI_SERVICE_H
|
#ifndef GUAC_RDP_AI_SERVICE_H
|
||||||
#define GUAC_RDP_AI_SERVICE_H
|
#define GUAC_RDP_AI_SERVICE_H
|
||||||
|
|
||||||
#include "config.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
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user