[Spice-devel] [PATCH 2/2] server: add subtype to SpiceCharDeviceInterface, use for vdagent

Alon Levy alevy at redhat.com
Thu Aug 26 01:45:27 PDT 2010


---
 server/reds.c               |   56 +++++++++++++++++++++++++++++++++++++-----
 server/spice-experimental.h |    2 +
 2 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/server/reds.c b/server/reds.c
index 0870612..e5a61cb 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -184,6 +184,15 @@ typedef struct __attribute__ ((__packed__)) VDIChunkHeader {
     uint32_t size;
 } VDIChunkHeader;
 
+struct SpiceCharDeviceState {
+    void (*wakeup)(SpiceCharDeviceInstance *sin);
+};
+
+void vdagent_char_device_wakeup(SpiceCharDeviceInstance *sin);
+struct SpiceCharDeviceState vdagent_char_device_state = {
+    .wakeup = &vdagent_char_device_wakeup,
+};
+
 typedef struct VDIPortState {
     int connected;
     uint32_t plug_generation;
@@ -1310,7 +1319,7 @@ static int read_from_vdi_port(void)
     return total;
 }
 
-__visible__ void spice_server_char_device_wakeup(SpiceCharDeviceInstance *sin)
+void vdagent_char_device_wakeup(SpiceCharDeviceInstance *sin)
 {
     while (read_from_vdi_port());
 }
@@ -3415,6 +3424,43 @@ static void attach_to_red_agent(SpiceCharDeviceInstance *sin)
     reds_send_agent_connected();
 }
 
+__visible__ void spice_server_char_device_wakeup(SpiceCharDeviceInstance* sin)
+{
+    (*sin->st->wakeup)(sin);
+}
+
+#define SUBTYPE_VDAGENT "vdagent"
+
+const char *spice_server_char_device_recognized_subtypes_list[] = {
+    SUBTYPE_VDAGENT,
+    NULL,
+};
+
+__visible__ const char** spice_server_char_device_recognized_subtypes()
+{
+    return spice_server_char_device_recognized_subtypes_list;
+}
+
+int spice_server_char_device_add_interface(SpiceServer *s,
+                                           SpiceBaseInstance *sin)
+{
+    SpiceCharDeviceInstance* char_device =
+            SPICE_CONTAINEROF(sin, SpiceCharDeviceInstance, base);
+    SpiceCharDeviceInterface* sif;
+
+    sif = SPICE_CONTAINEROF(char_device->base.sif, SpiceCharDeviceInterface, base);
+    const char* subtype = sif->subtype(char_device);
+    if (strcmp(subtype, SUBTYPE_VDAGENT) == 0) {
+        if (vdagent) {
+            red_printf("vdi port already attached");
+            return -1;
+        }
+        char_device->st = &vdagent_char_device_state;
+        attach_to_red_agent(char_device);
+    }
+    return 0;
+}
+
 __visible__ int spice_server_add_interface(SpiceServer *s,
                                            SpiceBaseInstance *sin)
 {
@@ -3506,16 +3552,12 @@ __visible__ int spice_server_add_interface(SpiceServer *s,
 
     } else if (strcmp(interface->type, SPICE_INTERFACE_CHAR_DEVICE) == 0) {
         red_printf("SPICE_INTERFACE_CHAR_DEVICE");
-        if (vdagent) {
-            red_printf("vdi port already attached");
-            return -1;
-        }
         if (interface->major_version != SPICE_INTERFACE_CHAR_DEVICE_MAJOR ||
             interface->minor_version < SPICE_INTERFACE_CHAR_DEVICE_MINOR) {
             red_printf("unsupported char device interface");
             return -1;
         }
-        attach_to_red_agent(SPICE_CONTAINEROF(sin, SpiceCharDeviceInstance, base));
+        spice_server_char_device_add_interface(s, sin);
 
     } else if (strcmp(interface->type, SPICE_INTERFACE_NET_WIRE) == 0) {
 #ifdef USE_TUNNEL
@@ -3563,7 +3605,7 @@ __visible__ int spice_server_remove_interface(SpiceBaseInstance *sin)
 
     } else if (strcmp(interface->type, SPICE_INTERFACE_CHAR_DEVICE) == 0) {
         red_printf("remove SPICE_INTERFACE_CHAR_DEVICE");
-        if (sin == &vdagent->base) {
+        if (vdagent && sin == &vdagent->base) {
             reds_agent_remove();
         }
 
diff --git a/server/spice-experimental.h b/server/spice-experimental.h
index e40b3ec..fd8ef67 100644
--- a/server/spice-experimental.h
+++ b/server/spice-experimental.h
@@ -10,6 +10,7 @@ typedef struct SpiceCharDeviceState SpiceCharDeviceState;
 struct SpiceCharDeviceInterface {
     SpiceBaseInterface base;
 
+    const char* (*subtype)(SpiceCharDeviceInstance *sin);
     void (*state)(SpiceCharDeviceInstance *sin, int connected);
     int (*write)(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len);
     int (*read)(SpiceCharDeviceInstance *sin, uint8_t *buf, int len);
@@ -21,6 +22,7 @@ struct SpiceCharDeviceInstance {
 };
 
 void spice_server_char_device_wakeup(SpiceCharDeviceInstance *sin);
+const char** spice_server_char_device_recognized_subtypes(void);
 
 /* tunnel interface */
 
-- 
1.7.2



More information about the Spice-devel mailing list