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:
Volker Ruppert 2021-04-17 09:30:58 +00:00
parent 6d5897217c
commit 30e24fa3d5
5 changed files with 43 additions and 13 deletions

View File

@ -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)

View File

@ -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);
};

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);
}