Prepared USB packet logging support in PCAP format (patch #560 by Ben Lunt).
- DONE: config option handling, usb_dump_packet() changes - TODO: add new file after compiling and testing new code on Windows
This commit is contained in:
parent
6d5897217c
commit
30e24fa3d5
@ -31,6 +31,7 @@
|
||||
|
||||
#if BX_SUPPORT_PCI && BX_SUPPORT_PCIUSB
|
||||
|
||||
//#include "usb_pcap.h"
|
||||
#include "usb_common.h"
|
||||
|
||||
#define LOG_THIS bx_usbdev_ctl.
|
||||
@ -193,6 +194,8 @@ void bx_usbdev_ctl_c::parse_port_options(usb_device_c *device, bx_list_c *portco
|
||||
}
|
||||
} else if (!strcmp(opts[i], "debug")) {
|
||||
device->set_debug_mode();
|
||||
} else if (!strncmp(opts[i], "pcap:", 5)) {
|
||||
device->set_pcap_mode(opts[i]+5);
|
||||
} else if (!device->set_option(opts[i])) {
|
||||
BX_ERROR(("ignoring unknown USB device option: '%s'", opts[i]));
|
||||
}
|
||||
@ -332,6 +335,7 @@ int usb_device_c::handle_packet(USBPacket *p)
|
||||
if (len != 8)
|
||||
goto fail;
|
||||
d.stall = 0;
|
||||
usb_dump_packet(data, 8, 0, p->devaddr, USB_DIR_OUT | p->devep, USB_TRANS_TYPE_CONTROL, true, false);
|
||||
memcpy(d.setup_buf, data, 8);
|
||||
d.setup_len = (d.setup_buf[7] << 8) | d.setup_buf[6];
|
||||
d.setup_index = 0;
|
||||
@ -366,6 +370,7 @@ int usb_device_c::handle_packet(USBPacket *p)
|
||||
(d.setup_buf[3] << 8) | d.setup_buf[2],
|
||||
(d.setup_buf[5] << 8) | d.setup_buf[4],
|
||||
d.setup_len, d.data_buf);
|
||||
usb_dump_packet(d.data_buf, ret, 0, p->devaddr, USB_DIR_IN | p->devep, USB_TRANS_TYPE_CONTROL, false, true);
|
||||
if (ret > 0)
|
||||
ret = 0;
|
||||
} else {
|
||||
@ -382,6 +387,7 @@ int usb_device_c::handle_packet(USBPacket *p)
|
||||
if (d.setup_index >= d.setup_len)
|
||||
d.setup_state = SETUP_STATE_ACK;
|
||||
ret = l;
|
||||
usb_dump_packet(data, ret, 0, p->devaddr, USB_DIR_IN | p->devep, USB_TRANS_TYPE_CONTROL, false, true);
|
||||
} else {
|
||||
d.setup_state = SETUP_STATE_IDLE;
|
||||
goto fail;
|
||||
@ -404,6 +410,7 @@ int usb_device_c::handle_packet(USBPacket *p)
|
||||
case 0:
|
||||
switch(d.setup_state) {
|
||||
case SETUP_STATE_ACK:
|
||||
usb_dump_packet(p->data, p->len, 0, p->devaddr, USB_DIR_OUT | p->devep, USB_TRANS_TYPE_CONTROL, false, true);
|
||||
if (d.setup_buf[0] & USB_DIR_IN) {
|
||||
d.setup_state = SETUP_STATE_IDLE;
|
||||
// transfer OK
|
||||
@ -421,6 +428,7 @@ int usb_device_c::handle_packet(USBPacket *p)
|
||||
if (d.setup_index >= d.setup_len)
|
||||
d.setup_state = SETUP_STATE_ACK;
|
||||
ret = l;
|
||||
usb_dump_packet(data, ret, 0, p->devaddr, USB_DIR_OUT | p->devep, USB_TRANS_TYPE_CONTROL, false, true);
|
||||
} else {
|
||||
// it is okay for a host to send an OUT before it reads
|
||||
// all of the expected IN. It is telling the controller
|
||||
@ -564,6 +572,11 @@ void usb_device_c::set_debug_mode()
|
||||
setonoff(LOGLEV_DEBUG, ACT_REPORT);
|
||||
}
|
||||
|
||||
void usb_device_c::set_pcap_mode(const char *pcap_name)
|
||||
{
|
||||
d.pcap_mode = 0; //(d.pcapture.create_pcap(pcap_name) >= 0);
|
||||
}
|
||||
|
||||
// Send an internal message to a USB device
|
||||
void usb_device_c::usb_send_msg(int msg)
|
||||
{
|
||||
@ -574,7 +587,7 @@ void usb_device_c::usb_send_msg(int msg)
|
||||
}
|
||||
|
||||
// Dumps the contents of a buffer to the log file
|
||||
void usb_device_c::usb_dump_packet(Bit8u *data, unsigned size)
|
||||
void usb_device_c::usb_dump_packet(Bit8u *data, unsigned size, int bus, int dev_addr, int ep, int type, bool is_setup, bool can_append)
|
||||
{
|
||||
char buf_str[1025], temp_str[17];
|
||||
|
||||
@ -591,6 +604,10 @@ void usb_device_c::usb_dump_packet(Bit8u *data, unsigned size)
|
||||
}
|
||||
if (strlen(buf_str) > 0) BX_DEBUG(("%s", buf_str));
|
||||
}
|
||||
|
||||
if (d.pcap_mode) {
|
||||
// d.pcapture.write_packet(data, size, bus, dev_addr, ep, type, is_setup, can_append);
|
||||
}
|
||||
}
|
||||
|
||||
int usb_device_c::set_usb_string(Bit8u *buf, const char *str)
|
||||
|
@ -30,6 +30,12 @@
|
||||
#ifndef BX_IODEV_USB_COMMON_H
|
||||
#define BX_IODEV_USB_COMMON_H
|
||||
|
||||
// for the Packet Capture code to work, these four must remain as is
|
||||
#define USB_TRANS_TYPE_ISO 0
|
||||
#define USB_TRANS_TYPE_INT 1
|
||||
#define USB_TRANS_TYPE_CONTROL 2
|
||||
#define USB_TRANS_TYPE_BULK 3
|
||||
|
||||
#define USB_TOKEN_IN 0x69
|
||||
#define USB_TOKEN_OUT 0xE1
|
||||
#define USB_TOKEN_SETUP 0x2D
|
||||
@ -127,6 +133,8 @@ typedef void USBCallback(int event, USBPacket *packet, void *dev, int port);
|
||||
|
||||
class usb_device_c;
|
||||
|
||||
//#include "usb_pcap.h"
|
||||
|
||||
struct USBPacket {
|
||||
int pid;
|
||||
Bit8u devaddr;
|
||||
@ -202,6 +210,7 @@ public:
|
||||
d.event.port = port;
|
||||
}
|
||||
void set_debug_mode();
|
||||
void set_pcap_mode(const char *pcap_name);
|
||||
|
||||
void usb_send_msg(int msg);
|
||||
|
||||
@ -240,10 +249,13 @@ protected:
|
||||
int port;
|
||||
} event;
|
||||
bx_list_c *sr;
|
||||
|
||||
bool pcap_mode;
|
||||
// pcap_image_t pcapture;
|
||||
} d;
|
||||
|
||||
int handle_control_common(int request, int value, int index, int length, Bit8u *data);
|
||||
void usb_dump_packet(Bit8u *data, unsigned size);
|
||||
void usb_dump_packet(Bit8u *data, unsigned size, int bus, int dev_addr, int ep, int type, bool is_setup, bool can_append);
|
||||
int set_usb_string(Bit8u *buf, const char *str);
|
||||
};
|
||||
|
||||
|
@ -852,7 +852,7 @@ bool usb_floppy_device_c::handle_command(Bit8u *command)
|
||||
case UFI_MODE_SELECT:
|
||||
default:
|
||||
BX_ERROR(("Unknown UFI/CBI Command: 0x%02X", s.cur_command));
|
||||
usb_dump_packet(command, 12);
|
||||
usb_dump_packet(command, 12, 0, d.addr, USB_DIR_OUT | 0, USB_TRANS_TYPE_BULK, false, false);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
@ -904,7 +904,7 @@ int usb_floppy_device_c::handle_data(USBPacket *p)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret > 0) usb_dump_packet(data, len);
|
||||
if (ret > 0) usb_dump_packet(data, len, 0, p->devaddr, USB_DIR_OUT | p->devep, USB_TRANS_TYPE_BULK, false, true);
|
||||
break;
|
||||
|
||||
case UFI_FORMAT_UNIT:
|
||||
@ -940,7 +940,7 @@ int usb_floppy_device_c::handle_data(USBPacket *p)
|
||||
} else {
|
||||
BX_ERROR(("FORMAT UNIT with no SINGLE TRACK bit set not yet supported"));
|
||||
}
|
||||
if (ret > 0) usb_dump_packet(data, len);
|
||||
if (ret > 0) usb_dump_packet(data, len, 0, p->devaddr, p->devep, USB_TRANS_TYPE_BULK, false, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1009,7 +1009,7 @@ int usb_floppy_device_c::handle_data(USBPacket *p)
|
||||
}
|
||||
ret = len;
|
||||
}
|
||||
if (ret > 0) usb_dump_packet(data, ret);
|
||||
if (ret > 0) usb_dump_packet(data, ret, 0, p->devaddr, USB_DIR_IN | p->devep, USB_TRANS_TYPE_BULK, false, true);
|
||||
break;
|
||||
|
||||
case UFI_READ_CAPACITY:
|
||||
@ -1022,7 +1022,7 @@ int usb_floppy_device_c::handle_data(USBPacket *p)
|
||||
memcpy(data, s.usb_buf, len);
|
||||
s.usb_buf += len;
|
||||
s.data_len -= len;
|
||||
usb_dump_packet(data, len);
|
||||
usb_dump_packet(data, len, 0, p->devaddr, USB_DIR_IN | p->devep, USB_TRANS_TYPE_BULK, false, true);
|
||||
ret = len;
|
||||
break;
|
||||
|
||||
@ -1120,7 +1120,7 @@ void usb_floppy_device_c::floppy_timer()
|
||||
}
|
||||
// ret: 0 = not complete / 1 = complete / -1 = error
|
||||
if ((s.packet != NULL) && (ret != 0)) {
|
||||
usb_dump_packet(p->data, p->len);
|
||||
usb_dump_packet(p->data, p->len, 0, p->devaddr, USB_DIR_OUT | p->devep, USB_TRANS_TYPE_BULK, false, true);
|
||||
s.packet = NULL;
|
||||
usb_packet_complete(p);
|
||||
}
|
||||
|
@ -689,7 +689,7 @@ int usb_msd_device_c::handle_data(USBPacket *p)
|
||||
|
||||
switch (p->pid) {
|
||||
case USB_TOKEN_OUT:
|
||||
usb_dump_packet(data, len);
|
||||
usb_dump_packet(data, len, 0, p->devaddr, USB_DIR_OUT | p->devep, USB_TRANS_TYPE_BULK, false, true);
|
||||
if (devep != 2)
|
||||
goto fail;
|
||||
|
||||
@ -815,7 +815,7 @@ int usb_msd_device_c::handle_data(USBPacket *p)
|
||||
BX_ERROR(("USB MSD handle_data: unexpected mode at USB_TOKEN_IN: (0x%02X)", s.mode));
|
||||
goto fail;
|
||||
}
|
||||
if (ret > 0) usb_dump_packet(data, ret);
|
||||
if (ret > 0) usb_dump_packet(data, ret, 0, p->devaddr, USB_DIR_IN | p->devep, USB_TRANS_TYPE_BULK, false, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -862,6 +862,8 @@ void usb_msd_device_c::send_status(USBPacket *p)
|
||||
csw.residue = htod32(s.residue);
|
||||
csw.status = s.result;
|
||||
memcpy(p->data, &csw, BX_MIN(p->len, 13));
|
||||
|
||||
usb_dump_packet(p->data, BX_MIN(p->len, 13), 0, p->devaddr, USB_DIR_IN | p->devep, USB_TRANS_TYPE_BULK, false, false);
|
||||
}
|
||||
|
||||
void usb_msd_device_c::usb_msd_command_complete(void *this_ptr, int reason, Bit32u tag, Bit32u arg)
|
||||
@ -885,7 +887,6 @@ void usb_msd_device_c::command_complete(int reason, Bit32u tag, Bit32u arg)
|
||||
if ((s.data_len == 0) && (s.mode == USB_MSDM_DATAOUT)) {
|
||||
send_status(p);
|
||||
s.mode = USB_MSDM_CBW;
|
||||
usb_dump_packet(p->data, p->len);
|
||||
} else if (s.mode == USB_MSDM_CSW) {
|
||||
send_status(p);
|
||||
s.mode = USB_MSDM_CBW;
|
||||
@ -910,7 +911,7 @@ void usb_msd_device_c::command_complete(int reason, Bit32u tag, Bit32u arg)
|
||||
s.scsi_buf = s.scsi_dev->scsi_get_buf(tag);
|
||||
if (p) {
|
||||
if ((s.scsi_len > 0) && (s.mode == USB_MSDM_DATAIN)) {
|
||||
usb_dump_packet(s.scsi_buf, p->len);
|
||||
usb_dump_packet(s.scsi_buf, p->len, 0, p->devaddr, USB_DIR_OUT | p->devep, USB_TRANS_TYPE_BULK, false, true);
|
||||
}
|
||||
copy_data();
|
||||
if (s.usb_len == 0) {
|
||||
|
@ -299,7 +299,7 @@ int usb_printer_device_c::handle_data(USBPacket *p)
|
||||
case USB_TOKEN_OUT:
|
||||
if (p->devep == 2) {
|
||||
BX_DEBUG(("Sent %i bytes to the 'usb printer': %s", p->len, s.fname));
|
||||
usb_dump_packet(p->data, p->len);
|
||||
usb_dump_packet(p->data, p->len, 0, p->devaddr, USB_DIR_OUT | p->devep, USB_TRANS_TYPE_CONTROL, false, true);
|
||||
if (s.fp != NULL) {
|
||||
fwrite(p->data, 1, p->len, s.fp);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user