diff --git a/TODO-RELEASE b/TODO-RELEASE new file mode 100644 index 00000000..5da461b6 --- /dev/null +++ b/TODO-RELEASE @@ -0,0 +1,10 @@ +# When cleaning up this file: bump API version in corresponding Makefile.am and rename corresponding debian/lib*.install +# according to https://osmocom.org/projects/cellular-infrastructure/wiki/Make_a_new_release +# In short: https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info +# LIBVERSION=c:r:a +# If the library source code has changed at all since the last update, then increment revision: c:r + 1:a. +# If any interfaces have been added, removed, or changed since the last update: c + 1:0:0. +# If any interfaces have been added since the last public release: c:r:a + 1. +# If any interfaces have been removed or changed since the last public release: c:r:0. +#library what description / commit summary line +simtrace2 API/ABI change osmo_st2_transport new member diff --git a/host/include/osmocom/simtrace2/simtrace2_api.h b/host/include/osmocom/simtrace2/simtrace2_api.h index aa1637d9..d658d161 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 b3e4e38a..4e16fd1f 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; - printf("<- %s\n", msgb_hexdump(msg)); - - 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)); + 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; } + msgb_free(msg); + libusb_free_transfer(xfer); +} + + +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) { - st_push_hdr(msg, msg_class, msg_type, slot->slot_nr); + struct osmo_st2_transport *transp = slot->transp; + int rc; - return osmo_st2_transp_tx_msg(slot->transp, msg); + OSMO_ASSERT(transp); + + st_push_hdr(msg, msg_class, msg_type, slot->slot_nr); + printf("SIMtrace <- %s\n", msgb_hexdump(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; } /***********************************************************************