Change in osmo-remsim[master]: remsim_client: Port to async libosmousb select loop

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Sun Dec 15 22:45:59 UTC 2019


laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-remsim/+/16610 )


Change subject: remsim_client: Port to async libosmousb select loop
......................................................................

remsim_client: Port to async libosmousb select loop

By using the non-blocking / asynchronous libusb via the newly-
introduced libosmousb (integration to libosmocore select loop),
we can not only get a cleaner code-base, but we also get a
considerable speed-up.

In my tests with a Quectel E25 and a sysmoUSIM-SJS1 card,
I am down from 41.4s to 4.7s for the initial reading of the SIM
at start-up.

Change-Id: Ic18690b3c2cbc5e99de0665c0b68b7555433b3cd
Closes: OS#4299
Depends: libosmocore.git I656a1a38cbb5b1f3a9145d2869d3b4d0adefcae3
---
M src/simtrace2-remsim_client.c
1 file changed, 140 insertions(+), 34 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-remsim refs/changes/10/16610/1

diff --git a/src/simtrace2-remsim_client.c b/src/simtrace2-remsim_client.c
index 30a9c5b..fa6b102 100644
--- a/src/simtrace2-remsim_client.c
+++ b/src/simtrace2-remsim_client.c
@@ -143,20 +143,50 @@
 }
 #endif
 
+static void usb_out_xfer_cb(struct libusb_transfer *xfer)
+{
+	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(23);
+		break;
+	default:
+		osmo_panic("USB OUT transfer failed, status=%u\n", xfer->status);
+		break;
+	}
+
+	msgb_free(msg);
+	libusb_free_transfer(xfer);
+}
+
 /*! \brief Transmit a given command to the SIMtrace2 device */
 int st_transp_tx_msg(struct st_transport *transp, struct msgb *msg)
 {
+	struct libusb_transfer *xfer;
 	int rc;
 
 	printf("SIMtrace <- %s\n", msgb_hexdump(msg));
 
-	int xfer_len;
+	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 = 1000;
+	xfer->user_data = msg;
+	xfer->length = msgb_length(msg);
+	xfer->buffer = msgb_data(msg);
+	xfer->callback = usb_out_xfer_cb;
 
-	rc = libusb_bulk_transfer(transp->usb_devh, transp->usb_ep.out,
-		msgb_data(msg), msgb_length(msg),
-		&xfer_len, 1000);
+	/* submit the OUT transfer */
+	rc = libusb_submit_transfer(xfer);
+	OSMO_ASSERT(rc == 0);
 
-	msgb_free(msg);
 	return rc;
 }
 
@@ -472,38 +502,106 @@
 	return rc;
 }
 
-static void run_mainloop(struct cardem_inst *ci)
+static void usb_in_xfer_cb(struct libusb_transfer *xfer)
 {
-	struct st_transport *transp = ci->slot->transp;
-	unsigned int msg_count, byte_count = 0;
-	uint8_t buf[16*265];
-	int xfer_len;
+	struct cardem_inst *ci = xfer->user_data;
 	int rc;
 
-	printf("Entering main loop\n");
-
-	while (1) {
-		/* read data from SIMtrace2 device (local or via USB) */
-		rc = libusb_bulk_transfer(transp->usb_devh, transp->usb_ep.in,
-			 buf, sizeof(buf), &xfer_len, 100);
-		if (rc < 0 && rc != LIBUSB_ERROR_TIMEOUT &&
-			rc != LIBUSB_ERROR_INTERRUPTED &&
-			rc != LIBUSB_ERROR_IO) {
-			fprintf(stderr, "BULK IN transfer error: %s\n", libusb_error_name(rc));
-			return;
-		}
-		/* dispatch any incoming data */
-		if (xfer_len > 0) {
-			process_usb_msg(ci, buf, xfer_len);
-			msg_count++;
-			byte_count += xfer_len;
-		}
-		// handle remote SIM client fsm
-		// TODO register the USB fd for this select
-		osmo_select_main(true);
+	switch (xfer->status) {
+	case LIBUSB_TRANSFER_COMPLETED:
+		/* hand the message up the stack */
+		process_usb_msg(ci, xfer->buffer, xfer->actual_length);
+		break;
+	case LIBUSB_TRANSFER_NO_DEVICE:
+		fprintf(stderr, "USB device disappeared\n");
+		exit(23);
+		break;
+	default:
+		osmo_panic("USB IN transfer failed, status=%u\n", xfer->status);
+		break;
 	}
+
+	/* re-submit the IN transfer */
+	rc = libusb_submit_transfer(xfer);
+	OSMO_ASSERT(rc == 0);
 }
 
+
+static void allocate_and_submit_in(struct cardem_inst *ci)
+{
+	struct st_transport *transp = ci->slot->transp;
+	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.in;
+	xfer->timeout = 0;
+	xfer->user_data = ci;
+	xfer->length = 16*256;
+
+	xfer->buffer = libusb_dev_mem_alloc(xfer->dev_handle, xfer->length);
+	OSMO_ASSERT(xfer->buffer);
+	xfer->callback = usb_in_xfer_cb;
+
+	/* submit the IN transfer */
+	rc = libusb_submit_transfer(xfer);
+	OSMO_ASSERT(rc == 0);
+}
+
+
+static void usb_irq_xfer_cb(struct libusb_transfer *xfer)
+{
+	int rc;
+
+	switch (xfer->status) {
+	case LIBUSB_TRANSFER_COMPLETED:
+		/* FIXME: do something with the received data */
+		break;
+	case LIBUSB_TRANSFER_NO_DEVICE:
+		fprintf(stderr, "USB device disappeared\n");
+		exit(23);
+		break;
+	default:
+		osmo_panic("USB IRQ transfer failed, status=%u\n", xfer->status);
+		break;
+	}
+
+	/* re-submit the IN transfer */
+	rc = libusb_submit_transfer(xfer);
+	OSMO_ASSERT(rc == 0);
+}
+
+
+static void allocate_and_submit_irq(struct cardem_inst *ci)
+{
+	struct st_transport *transp = ci->slot->transp;
+	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_INTERRUPT;
+	xfer->endpoint = transp->usb_ep.irq_in;
+	xfer->timeout = 0;
+	xfer->user_data = ci;
+	xfer->length = 64;
+
+	xfer->buffer = libusb_dev_mem_alloc(xfer->dev_handle, xfer->length);
+	OSMO_ASSERT(xfer->buffer);
+	xfer->callback = usb_irq_xfer_cb;
+
+	/* submit the IN transfer */
+	rc = libusb_submit_transfer(xfer);
+	OSMO_ASSERT(rc == 0);
+}
+
+
 static struct st_transport _transp;
 
 static struct st_slot _slot = {
@@ -652,7 +750,7 @@
 static void print_welcome(void)
 {
 	printf("simtrace2-remsim-client - Remote SIM card client for SIMtrace\n"
-	       "(C) 2010-2017, Harald Welte <laforge at gnumonks.org>\n"
+	       "(C) 2010-2019, Harald Welte <laforge at gnumonks.org>\n"
 	       "(C) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon at sysmocom.de>\n\n");
 }
 
@@ -794,7 +892,7 @@
 	msgb_talloc_ctx_init(g_tall_ctx, 0);
 	osmo_init_logging2(g_tall_ctx, &log_info);
 
-	rc = libusb_init(NULL);
+	rc = osmo_libusb_init(NULL);
 	if (rc < 0) {
 		fprintf(stderr, "libusb initialization failed\n");
 		goto do_exit;
@@ -941,7 +1039,15 @@
 		/* select remote (forwarded) SIM */
 		st_modem_reset_pulse(ci->slot, 300);
 
-		run_mainloop(ci);
+		printf("Entering main loop\n");
+
+		allocate_and_submit_irq(ci);
+		allocate_and_submit_in(ci);
+
+		while (1) {
+			osmo_select_main(false);
+		}
+
 		ret = 0;
 
 		libusb_release_interface(transp->usb_devh, 0);

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-remsim/+/16610
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-remsim
Gerrit-Branch: master
Gerrit-Change-Id: Ic18690b3c2cbc5e99de0665c0b68b7555433b3cd
Gerrit-Change-Number: 16610
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20191215/26b76b95/attachment.htm>


More information about the gerrit-log mailing list