From 4d7e03e61d7a27f0a80e837f945d896c4a7f0cce Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sun, 16 Mar 2014 13:08:09 +0100 Subject: usb-hid: usbdump example for control and interrupt IN This is verified to reproduce the same capture as done inside the VM. The differences are in time, bInterval, URB length, URB ID and the Copy of transfer flags. Signed-off-by: Peter Wu --- hw/usb/dev-hid.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'hw') diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c index f36e617632..7fef1ea41d 100644 --- a/hw/usb/dev-hid.c +++ b/hw/usb/dev-hid.c @@ -28,6 +28,7 @@ #include "hw/usb/desc.h" #include "qemu/timer.h" #include "hw/input/hid.h" +#include "hw/usb/dump.h" /* HID interface requests */ #define GET_REPORT 0xa101 @@ -47,6 +48,7 @@ typedef struct USBHIDState { USBEndpoint *intr; HIDState hid; uint32_t usb_version; + UsbDumpState *usb_dump_state; } USBHIDState; enum { @@ -448,8 +450,11 @@ static void usb_hid_handle_control(USBDevice *dev, USBPacket *p, HIDState *hs = &us->hid; int ret; + usb_dump_submit(us->usb_dump_state, p); + ret = usb_desc_handle_control(dev, p, request, value, index, length, data); if (ret >= 0) { + usb_dump_complete(us->usb_dump_state, p); return; } @@ -519,6 +524,7 @@ static void usb_hid_handle_control(USBDevice *dev, USBPacket *p, p->status = USB_RET_STALL; break; } + usb_dump_complete(us->usb_dump_state, p); } static void usb_hid_handle_data(USBDevice *dev, USBPacket *p) @@ -544,7 +550,11 @@ static void usb_hid_handle_data(USBDevice *dev, USBPacket *p) } else if (hs->kind == HID_KEYBOARD) { len = hid_keyboard_poll(hs, buf, p->iov.size); } + /* feed back data to host */ + usb_dump_complete_data(us->usb_dump_state, p, buf, len); usb_packet_copy(p, buf, len); + /* as this is an interrupt, pretend that host submitted request */ + usb_dump_submit(us->usb_dump_state, p); } else { goto fail; } @@ -561,6 +571,11 @@ static void usb_hid_handle_destroy(USBDevice *dev) { USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); + if (us->usb_dump_state) { + usb_dump_cleanup(us->usb_dump_state); + g_free(us->usb_dump_state); + us->usb_dump_state = NULL; + } hid_free(&us->hid); } @@ -574,6 +589,8 @@ static int usb_hid_initfn(USBDevice *dev, int kind) usb_desc_init(dev); us->intr = usb_ep_get(dev, USB_TOKEN_IN, 1); hid_init(&us->hid, kind, usb_hid_changed); + // TODO: API sucks... + us->usb_dump_state = usb_dump_init_alloc("/tmp/usbdump.pcap"); return 0; } -- cgit v1.2.1