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
This commit is contained in:
parent
8c1ca1bb87
commit
32e2e006b1
|
@ -143,20 +143,50 @@ static void apdu_out_cb(uint8_t *buf, unsigned int len, void *user_data)
|
||||||
}
|
}
|
||||||
#endif
|
#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 */
|
/*! \brief Transmit a given command to the SIMtrace2 device */
|
||||||
int st_transp_tx_msg(struct st_transport *transp, struct msgb *msg)
|
int st_transp_tx_msg(struct st_transport *transp, struct msgb *msg)
|
||||||
{
|
{
|
||||||
|
struct libusb_transfer *xfer;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
printf("SIMtrace <- %s\n", msgb_hexdump(msg));
|
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,
|
/* submit the OUT transfer */
|
||||||
msgb_data(msg), msgb_length(msg),
|
rc = libusb_submit_transfer(xfer);
|
||||||
&xfer_len, 1000);
|
OSMO_ASSERT(rc == 0);
|
||||||
|
|
||||||
msgb_free(msg);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,38 +502,106 @@ static int process_usb_msg(struct cardem_inst *ci, uint8_t *buf, int len)
|
||||||
return rc;
|
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;
|
struct cardem_inst *ci = xfer->user_data;
|
||||||
unsigned int msg_count, byte_count = 0;
|
|
||||||
uint8_t buf[16*265];
|
|
||||||
int xfer_len;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
printf("Entering main loop\n");
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
while (1) {
|
/* re-submit the IN transfer */
|
||||||
/* read data from SIMtrace2 device (local or via USB) */
|
rc = libusb_submit_transfer(xfer);
|
||||||
rc = libusb_bulk_transfer(transp->usb_devh, transp->usb_ep.in,
|
OSMO_ASSERT(rc == 0);
|
||||||
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);
|
static void allocate_and_submit_in(struct cardem_inst *ci)
|
||||||
msg_count++;
|
{
|
||||||
byte_count += xfer_len;
|
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);
|
||||||
}
|
}
|
||||||
// handle remote SIM client fsm
|
|
||||||
// TODO register the USB fd for this select
|
|
||||||
osmo_select_main(true);
|
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_transport _transp;
|
||||||
|
|
||||||
static struct st_slot _slot = {
|
static struct st_slot _slot = {
|
||||||
|
@ -652,7 +750,7 @@ static void handle_sig_usr1(int signal)
|
||||||
static void print_welcome(void)
|
static void print_welcome(void)
|
||||||
{
|
{
|
||||||
printf("simtrace2-remsim-client - Remote SIM card client for SIMtrace\n"
|
printf("simtrace2-remsim-client - Remote SIM card client for SIMtrace\n"
|
||||||
"(C) 2010-2017, Harald Welte <laforge@gnumonks.org>\n"
|
"(C) 2010-2019, Harald Welte <laforge@gnumonks.org>\n"
|
||||||
"(C) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>\n\n");
|
"(C) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,7 +892,7 @@ int main(int argc, char **argv)
|
||||||
msgb_talloc_ctx_init(g_tall_ctx, 0);
|
msgb_talloc_ctx_init(g_tall_ctx, 0);
|
||||||
osmo_init_logging2(g_tall_ctx, &log_info);
|
osmo_init_logging2(g_tall_ctx, &log_info);
|
||||||
|
|
||||||
rc = libusb_init(NULL);
|
rc = osmo_libusb_init(NULL);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "libusb initialization failed\n");
|
fprintf(stderr, "libusb initialization failed\n");
|
||||||
goto do_exit;
|
goto do_exit;
|
||||||
|
@ -941,7 +1039,15 @@ int main(int argc, char **argv)
|
||||||
/* select remote (forwarded) SIM */
|
/* select remote (forwarded) SIM */
|
||||||
st_modem_reset_pulse(ci->slot, 300);
|
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;
|
ret = 0;
|
||||||
|
|
||||||
libusb_release_interface(transp->usb_devh, 0);
|
libusb_release_interface(transp->usb_devh, 0);
|
||||||
|
|
Loading…
Reference in New Issue