From d0f980b38f9865a12525a356204960e9b7d1a4e9 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 22 Feb 2020 16:45:05 +0100 Subject: WIP: Introduce support for asynchronous USB transmission Change-Id: Ib8939bdb7f533cd20a34a30a97f12b782b9816c2 --- host/include/osmocom/simtrace2/simtrace2_api.h | 4 +- host/lib/simtrace2_api.c | 78 +++++++++++++++++++++----- 2 files changed, 67 insertions(+), 15 deletions(-) diff --git a/host/include/osmocom/simtrace2/simtrace2_api.h b/host/include/osmocom/simtrace2/simtrace2_api.h index aa1637d..d658d16 100644 --- a/host/include/osmocom/simtrace2/simtrace2_api.h +++ b/host/include/osmocom/simtrace2/simtrace2_api.h @@ -12,6 +12,8 @@ struct osmo_st2_transport { uint8_t out; uint8_t irq_in; } usb_ep; + /* use non-blocking / asynchronous libusb I/O */ + bool usb_async; /* UDP */ int udp_fd; @@ -39,8 +41,6 @@ struct osmo_st2_cardem_inst { void *priv; }; -int osmo_st2_transp_tx_msg(struct osmo_st2_transport *transp, struct msgb *msg); - int osmo_st2_slot_tx_msg(struct osmo_st2_slot *slot, struct msgb *msg, uint8_t msg_class, uint8_t msg_type); diff --git a/host/lib/simtrace2_api.c b/host/lib/simtrace2_api.c index b3e4e38..4e16fd1 100644 --- a/host/lib/simtrace2_api.c +++ b/host/lib/simtrace2_api.c @@ -57,23 +57,60 @@ static struct msgb *st_msgb_alloc(void) return msgb_alloc_headroom(1024+32, 32, "SIMtrace"); } -/*! \brief Transmit a given command to the SIMtrace2 device */ -int osmo_st2_transp_tx_msg(struct osmo_st2_transport *transp, struct msgb *msg) + +static void usb_out_xfer_cb(struct libusb_transfer *xfer) { - int rc; + struct msgb *msg = xfer->user_data; + + switch (xfer->status) { + case LIBUSB_TRANSFER_COMPLETED: + break; + case LIBUSB_TRANSFER_NO_DEVICE: + fprintf(stderr, "USB device disappeared\n"); + exit(1); + break; + default: + fprintf(stderr, "USB OUT transfer failed, status=%u\n", xfer->status); + exit(1); + break; + } - printf("<- %s\n", msgb_hexdump(msg)); + msgb_free(msg); + libusb_free_transfer(xfer); +} - if (transp->udp_fd < 0) { - int xfer_len; - rc = libusb_bulk_transfer(transp->usb_devh, transp->usb_ep.out, - msgb_data(msg), msgb_length(msg), - &xfer_len, 100000); - } else { - rc = write(transp->udp_fd, msgb_data(msg), msgb_length(msg)); - } +static int st2_transp_tx_msg_usb_async(struct osmo_st2_transport *transp, struct msgb *msg) +{ + struct libusb_transfer *xfer; + int rc; + + xfer = libusb_alloc_transfer(0); + OSMO_ASSERT(xfer); + xfer->dev_handle = transp->usb_devh; + xfer->flags = 0; + xfer->type = LIBUSB_TRANSFER_TYPE_BULK; + xfer->endpoint = transp->usb_ep.out; + xfer->timeout = 100000; + xfer->user_data = msg; + xfer->length = msgb_length(msg); + xfer->buffer = msgb_data(msg); + xfer->callback = usb_out_xfer_cb; + + rc = libusb_submit_transfer(xfer); + OSMO_ASSERT(rc == 0); + return rc; +} + +/*! \brief Transmit a given command to the SIMtrace2 device */ +static int st2_transp_tx_msg_usb_sync(struct osmo_st2_transport *transp, struct msgb *msg) +{ + int rc; + int xfer_len; + rc = libusb_bulk_transfer(transp->usb_devh, transp->usb_ep.out, + msgb_data(msg), msgb_length(msg), + &xfer_len, 100000); msgb_free(msg); return rc; } @@ -98,9 +135,24 @@ static struct simtrace_msg_hdr *st_push_hdr(struct msgb *msg, uint8_t msg_class, int osmo_st2_slot_tx_msg(struct osmo_st2_slot *slot, struct msgb *msg, uint8_t msg_class, uint8_t msg_type) { + struct osmo_st2_transport *transp = slot->transp; + int rc; + + OSMO_ASSERT(transp); + st_push_hdr(msg, msg_class, msg_type, slot->slot_nr); + printf("SIMtrace <- %s\n", msgb_hexdump(msg)); - return osmo_st2_transp_tx_msg(slot->transp, msg); + if (transp->udp_fd < 0) { + if (transp->usb_async) + rc = st2_transp_tx_msg_usb_async(transp, msg); + else + rc = st2_transp_tx_msg_usb_sync(transp, msg); + } else { + rc = write(transp->udp_fd, msgb_data(msg), msgb_length(msg)); + msgb_free(msg); + } + return rc; } /*********************************************************************** -- cgit v1.2.3