aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Chtchetkine <vchtchetkine@google.com>2011-08-20 08:55:37 -0700
committerVladimir Chtchetkine <vchtchetkine@google.com>2011-08-25 14:54:56 -0700
commit4c414820910ba8553cab7ff30188575f972a9896 (patch)
tree2c4fac98fc43da2f21dc8f7c534fab5bca410085
parent4ffadf474d07bc3a5f1c9f61a69eef420bcb18a0 (diff)
downloadexternal_qemu-4c414820910ba8553cab7ff30188575f972a9896.zip
external_qemu-4c414820910ba8553cab7ff30188575f972a9896.tar.gz
external_qemu-4c414820910ba8553cab7ff30188575f972a9896.tar.bz2
Enable qemud clients to pass connection parameters to emulator.
This is useful for qemud pipe clients to be able to pass parameters to the emulator service when connecting. In particular, this would be extremely useful for camera emulation clients, which can pass name of the camera device, and other parameters that may be required to connect to the camera. Parameters are passed when opening the qemud pipe in form: /dev/qemu_pipe/camera:/dev/video0 I.e. parameters follow the service name, separated from it by ':' Change-Id: I67f0ef0ff27008e2b52652e58d72d5216b244646
-rw-r--r--android/boot-properties.c5
-rw-r--r--android/hw-control.c7
-rw-r--r--android/hw-qemud.c76
-rw-r--r--android/hw-qemud.h8
-rw-r--r--android/hw-sensors.c7
5 files changed, 83 insertions, 20 deletions
diff --git a/android/boot-properties.c b/android/boot-properties.c
index 1a86010..41b9b4d 100644
--- a/android/boot-properties.c
+++ b/android/boot-properties.c
@@ -319,11 +319,12 @@ boot_property_client_recv( void* opaque,
static QemudClient*
boot_property_service_connect( void* opaque,
QemudService* serv,
- int channel )
+ int channel,
+ const char* client_param )
{
QemudClient* client;
- client = qemud_client_new( serv, channel, NULL,
+ client = qemud_client_new( serv, channel, client_param, NULL,
boot_property_client_recv,
NULL, NULL, NULL );
diff --git a/android/hw-control.c b/android/hw-control.c
index 8164bc0..e010c6f 100644
--- a/android/hw-control.c
+++ b/android/hw-control.c
@@ -62,11 +62,14 @@ _hw_control_qemud_client_recv( void* opaque,
/* called when a qemud client connects to the service */
static QemudClient*
-_hw_control_qemud_connect( void* opaque, QemudService* service, int channel )
+_hw_control_qemud_connect( void* opaque,
+ QemudService* service,
+ int channel,
+ const char* client_param )
{
QemudClient* client;
- client = qemud_client_new( service, channel,
+ client = qemud_client_new( service, channel, client_param,
opaque,
_hw_control_qemud_client_recv,
NULL, NULL, NULL );
diff --git a/android/hw-qemud.c b/android/hw-qemud.c
index 44d9dd7..094421b 100644
--- a/android/hw-qemud.c
+++ b/android/hw-qemud.c
@@ -47,6 +47,8 @@
*/
#define QEMUD_SAVE_VERSION 1
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+
/* define SUPPORT_LEGACY_QEMUD to 1 if you want to support
* talking to a legacy qemud daemon. See docs/ANDROID-QEMUD.TXT
@@ -641,6 +643,7 @@ struct QemudClient {
QemudProtocol protocol;
/* Fields that are common for all protocols. */
+ char* param;
void* clie_opaque;
QemudClientRecv clie_recv;
QemudClientClose clie_close;
@@ -795,6 +798,28 @@ qemud_client_recv( void* opaque, uint8_t* msg, int msglen )
static void
_qemud_pipe_send(QemudClient* client, const uint8_t* msg, int msglen);
+/* Frees memory allocated for the qemud client.
+ */
+static void
+_qemud_client_free(QemudClient* c)
+{
+ if ( c != NULL) {
+ if (_is_pipe_client(c)) {
+ /* Free outstanding messages. */
+ QemudPipeMessage** msg_list = &c->ProtocolSelector.Pipe.messages;
+ while (*msg_list != NULL) {
+ QemudPipeMessage* to_free = *msg_list;
+ *msg_list = to_free->next;
+ free(to_free);
+ }
+ }
+ if (c->param != NULL) {
+ free(c->param);
+ }
+ AFREE(c);
+ }
+}
+
/* disconnect a client. this automatically frees the QemudClient.
* note that this also removes the client from the global list
* and from its service's list, if any.
@@ -841,7 +866,7 @@ qemud_client_disconnect( void* opaque )
c->service = NULL;
}
- AFREE(c);
+ _qemud_client_free(c);
}
/* allocate a new QemudClient object
@@ -850,6 +875,7 @@ qemud_client_disconnect( void* opaque )
* indicate that creating client is a pipe client. */
static QemudClient*
qemud_client_alloc( int channel_id,
+ const char* client_param,
void* clie_opaque,
QemudClientRecv clie_recv,
QemudClientClose clie_close,
@@ -873,6 +899,7 @@ qemud_client_alloc( int channel_id,
c->ProtocolSelector.Serial.serial = serial;
c->ProtocolSelector.Serial.channel = channel_id;
}
+ c->param = client_param ? ASTRDUP(client_param) : NULL;
c->clie_opaque = clie_opaque;
c->clie_recv = clie_recv;
c->clie_close = clie_close;
@@ -896,7 +923,8 @@ static char* qemud_service_load_name( QEMUFile* f );
static QemudService* qemud_service_find( QemudService* service_list,
const char* service_name );
static QemudClient* qemud_service_connect_client( QemudService *sv,
- int channel_id);
+ int channel_id,
+ const char* client_param);
/* Saves the client state needed to re-establish connections on load.
*/
@@ -959,7 +987,7 @@ qemud_client_load(QEMUFile* f, QemudService* current_services )
}
/* re-connect client */
- QemudClient* c = qemud_service_connect_client(sv, channel);
+ QemudClient* c = qemud_service_connect_client(sv, channel, NULL);
if(c == NULL)
return -EIO;
@@ -1106,9 +1134,12 @@ qemud_service_remove_client( QemudService* s, QemudClient* c )
* returns the client or NULL if an error occurred
*/
static QemudClient*
-qemud_service_connect_client(QemudService *sv, int channel_id)
+qemud_service_connect_client(QemudService *sv,
+ int channel_id,
+ const char* client_param)
{
- QemudClient* client = sv->serv_connect( sv->serv_opaque, sv, channel_id );
+ QemudClient* client =
+ sv->serv_connect( sv->serv_opaque, sv, channel_id, client_param );
if (client == NULL) {
D("%s: registration failed for '%s' service",
__FUNCTION__, sv->name);
@@ -1297,7 +1328,7 @@ qemud_multiplexer_connect( QemudMultiplexer* m,
}
/* connect a new client to the service on the given channel */
- if (qemud_service_connect_client(sv, channel_id) == NULL)
+ if (qemud_service_connect_client(sv, channel_id, NULL) == NULL)
return -1;
return 0;
@@ -1506,6 +1537,7 @@ qemud_multiplexer_init( QemudMultiplexer* mult,
/* setup listener for channel 0 */
control = qemud_client_alloc( 0,
+ NULL,
mult,
qemud_multiplexer_control_recv,
NULL, NULL, NULL,
@@ -1532,6 +1564,7 @@ static QemudMultiplexer _multiplexer[1];
QemudClient*
qemud_client_new( QemudService* service,
int channelId,
+ const char* client_param,
void* clie_opaque,
QemudClientRecv clie_recv,
QemudClientClose clie_close,
@@ -1540,6 +1573,7 @@ qemud_client_new( QemudService* service,
{
QemudMultiplexer* m = _multiplexer;
QemudClient* c = qemud_client_alloc( channelId,
+ client_param,
clie_opaque,
clie_recv,
clie_close,
@@ -1813,6 +1847,9 @@ _qemudPipe_init(void* hwpipe, void* _looper, const char* args)
QemudService* sv = m->services;
QemudClient* client;
QemudPipe* pipe = NULL;
+ char service_name[512];
+ const char* client_args;
+ size_t srv_name_len;
/* 'args' passed in this callback represents name of the service the guest is
* connecting to. It can't be NULL. */
@@ -1821,18 +1858,35 @@ _qemudPipe_init(void* hwpipe, void* _looper, const char* args)
return NULL;
}
+ /* 'args' contain service name, and optional parameters for the client that
+ * is about to be created in this call. The parameters are separated from the
+ * service name wit ':'. Separate service name from the client param. */
+ client_args = strchr(args, ':');
+ if (client_args != NULL) {
+ srv_name_len = min(client_args - args, sizeof(service_name) - 1);
+ client_args++; // Past the ':'
+ if (*client_args == '\0') {
+ /* No actual parameters. */
+ client_args = NULL;
+ }
+ } else {
+ srv_name_len = min(strlen(args), sizeof(service_name) - 1);
+ }
+ memcpy(service_name, args, srv_name_len);
+ service_name[srv_name_len] = '\0';
+
/* Lookup registered service by its name. */
- while (sv != NULL && strcmp(sv->name, args)) {
+ while (sv != NULL && strcmp(sv->name, service_name)) {
sv = sv->next;
}
if (sv == NULL) {
- D("%s: Service '%s' has not been registered!", __FUNCTION__, args);
+ D("%s: Service '%s' has not been registered!", __FUNCTION__, service_name);
return NULL;
}
/* Create a client for this connection. -1 as a channel ID signals that this
* is a pipe client. */
- client = qemud_service_connect_client(sv, -1);
+ client = qemud_service_connect_client(sv, -1, client_args);
if (client != NULL) {
ANEW0(pipe);
pipe->hwpipe = hwpipe;
@@ -1903,8 +1957,6 @@ _qemudPipe_sendBuffers(void* opaque,
return transferred;
}
-#define min(a, b) (((a) < (b)) ? (a) : (b))
-
/* Called when the guest is reading data from the client.
*/
static int
@@ -2198,7 +2250,7 @@ static QemudClient*
_qemud_char_service_connect( void* opaque, QemudService* sv, int channel )
{
CharDriverState* cs = opaque;
- QemudClient* c = qemud_client_new( sv, channel,
+ QemudClient* c = qemud_client_new( sv, channel, NULL,
cs,
_qemud_char_client_recv,
_qemud_char_client_close,
diff --git a/android/hw-qemud.h b/android/hw-qemud.h
index cd05737..6a2cc66 100644
--- a/android/hw-qemud.h
+++ b/android/hw-qemud.h
@@ -89,8 +89,9 @@ typedef int (*QemudClientLoad) ( QEMUFile* f, QemudClient* client, void* opaq
* You should typically use this function within a QemudServiceConnect callback
* (see below).
*/
-extern QemudClient* qemud_client_new( QemudService* service,
+extern QemudClient* qemud_client_new( QemudService* service,
int channel_id,
+ const char* client_param,
void* clie_opaque,
QemudClientRecv clie_recv,
QemudClientClose clie_close,
@@ -114,7 +115,10 @@ extern void qemud_client_close( QemudClient* client );
* system tries to connect to a given qemud service. This should typically
* call qemud_client_new() to register a new client.
*/
-typedef QemudClient* (*QemudServiceConnect)( void* opaque, QemudService* service, int channel );
+typedef QemudClient* (*QemudServiceConnect)( void* opaque,
+ QemudService* service,
+ int channel,
+ const char* client_param );
/* A function that will be called when the state of the service should be
* saved to a snapshot.
diff --git a/android/hw-sensors.c b/android/hw-sensors.c
index 7d77b62..9c39196 100644
--- a/android/hw-sensors.c
+++ b/android/hw-sensors.c
@@ -462,11 +462,14 @@ _hwSensorClient_load( QEMUFile* f, QemudClient* client, void* opaque )
}
static QemudClient*
-_hwSensors_connect( void* opaque, QemudService* service, int channel )
+_hwSensors_connect( void* opaque,
+ QemudService* service,
+ int channel,
+ const char* client_param )
{
HwSensors* sensors = opaque;
HwSensorClient* cl = _hwSensorClient_new(sensors);
- QemudClient* client = qemud_client_new(service, channel, cl,
+ QemudClient* client = qemud_client_new(service, channel, client_param, cl,
_hwSensorClient_recv,
_hwSensorClient_close,
_hwSensorClient_save,