mirror of https://gerrit.osmocom.org/simtrace2
remote-sim host tools: Auto-discover the endpoint addresses
We now auto-discover the end-point addresses based on the interface descriptor. The user can also use the new "--interface" command line argument to set a non-zero intrerface. In combination, this should enable support for the remote-sim functionality on the second UART on OWHW.
This commit is contained in:
parent
095ac6cbe2
commit
236caf68eb
|
@ -2,10 +2,10 @@ LDFLAGS=`pkg-config --libs libusb-1.0 libosmocore` -losmocore
|
|||
|
||||
all: simtrace2-remsim simtrace2-remsim-usb2udp
|
||||
|
||||
simtrace2-remsim: simtrace2-remsim.o apdu_dispatch.o
|
||||
simtrace2-remsim: simtrace2-remsim.o apdu_dispatch.o simtrace2-discovery.o
|
||||
$(CC) -o $@ $^ $(LDFLAGS) -losmosim
|
||||
|
||||
simtrace2-remsim-usb2udp: usb2udp.o
|
||||
simtrace2-remsim-usb2udp: usb2udp.o simtrace2-discovery.o
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
%.o: %.c
|
||||
|
|
|
@ -4,10 +4,4 @@
|
|||
#define SIMTRACE_USB_VENDOR 0x1d50
|
||||
#define SIMTRACE_USB_PRODUCT 0x60e3
|
||||
|
||||
/* FIXME: automatically determine those values based on the usb config /
|
||||
* interface descriptors */
|
||||
#define SIMTRACE_OUT_EP 0x04
|
||||
#define SIMTRACE_IN_EP 0x85
|
||||
#define SIMTRACE_INT_EP 0x86
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include <libusb.h>
|
||||
|
||||
/*! \brief obtain the endpoint addresses for a given USB interface */
|
||||
int get_usb_ep_addrs(libusb_device_handle *devh, unsigned int if_num,
|
||||
uint8_t *out, uint8_t *in, uint8_t *irq)
|
||||
{
|
||||
libusb_device *dev = libusb_get_device(devh);
|
||||
struct libusb_config_descriptor *cdesc;
|
||||
const struct libusb_interface_descriptor *idesc;
|
||||
const struct libusb_interface *iface;
|
||||
int rc, l;
|
||||
|
||||
rc = libusb_get_active_config_descriptor(dev, &cdesc);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
iface = &cdesc->interface[if_num];
|
||||
/* FIXME: we assume there's no altsetting */
|
||||
idesc = &iface->altsetting[0];
|
||||
|
||||
for (l = 0; l < idesc->bNumEndpoints; l++) {
|
||||
const struct libusb_endpoint_descriptor *edesc = &idesc->endpoint[l];
|
||||
switch (edesc->bmAttributes & 3) {
|
||||
case LIBUSB_TRANSFER_TYPE_BULK:
|
||||
if (edesc->bEndpointAddress & 0x80) {
|
||||
if (in)
|
||||
*in = edesc->bEndpointAddress;
|
||||
} else {
|
||||
if (out)
|
||||
*out = edesc->bEndpointAddress;
|
||||
}
|
||||
break;
|
||||
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
||||
if (irq)
|
||||
*irq = edesc->bEndpointAddress;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
struct libusb_device_descriptor ddesc;
|
||||
int rc, i, j, k;
|
||||
|
||||
rc = libusb_get_device_descriptor(devh, &ddesc);
|
||||
if (rc < 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < ddesc.bNumConfigurations; i++) {
|
||||
struct libusb_config_descriptor *cdesc;
|
||||
rc = libusb_get_config_descriptor(devh, i, &cdesc);
|
||||
if (rc < 0)
|
||||
return;
|
||||
|
||||
for (j = 0; j < cdesc->bNumInterfaces; j++) {
|
||||
const struct libusb_interface *iface = cdesc->interface[j];
|
||||
for (k = 0; k < iface->num_altsetting; k++) {
|
||||
const struct libusb_interface_descriptor *idesc = iface->altsetting[k];
|
||||
/* make sure this is the interface we're looking for */
|
||||
if (idesc->bInterfaceClass != 0xFF ||
|
||||
idesc->bInterfaceSubClass != if_class ||
|
||||
idsec->bInterfaceProtocol != if_proto)
|
||||
continue;
|
||||
/* FIXME */
|
||||
}
|
||||
}
|
||||
|
||||
libusb_free_config_descriptor(cdesc);
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <libusb.h>
|
||||
|
||||
int get_usb_ep_addrs(libusb_device_handle *devh, unsigned int if_num,
|
||||
uint8_t *out, uint8_t *in, uint8_t *irq);
|
|
@ -37,6 +37,7 @@
|
|||
#include "simtrace.h"
|
||||
#include "cardemu_prot.h"
|
||||
#include "apdu_dispatch.h"
|
||||
#include "simtrace2-discovery.h"
|
||||
|
||||
#include <osmocom/core/gsmtap.h>
|
||||
#include <osmocom/core/gsmtap_util.h>
|
||||
|
@ -48,6 +49,8 @@
|
|||
static struct gsmtap_inst *g_gti;
|
||||
struct libusb_device_handle *g_devh;
|
||||
const struct osim_cla_ins_card_profile *g_prof;
|
||||
static uint8_t g_in_ep;
|
||||
static uint8_t g_out_ep;
|
||||
static int g_udp_fd = -1;
|
||||
static struct osim_chan_hdl *g_chan;
|
||||
|
||||
|
@ -99,7 +102,7 @@ static int tx_to_dev(uint8_t *buf, unsigned int len)
|
|||
printf("<- %s\n", osmo_hexdump(buf, len));
|
||||
|
||||
if (g_udp_fd < 0) {
|
||||
return libusb_bulk_transfer(g_devh, SIMTRACE_OUT_EP, buf, len,
|
||||
return libusb_bulk_transfer(g_devh, g_out_ep, buf, len,
|
||||
&xfer_len, 100000);
|
||||
} else {
|
||||
return write(g_udp_fd, buf, len);
|
||||
|
@ -331,7 +334,7 @@ static void run_mainloop(void)
|
|||
while (1) {
|
||||
/* read data from SIMtrace2 device (local or via USB) */
|
||||
if (g_udp_fd < 0) {
|
||||
rc = libusb_bulk_transfer(g_devh, SIMTRACE_IN_EP, buf, sizeof(buf), &xfer_len, 100000);
|
||||
rc = libusb_bulk_transfer(g_devh, g_in_ep, buf, sizeof(buf), &xfer_len, 100000);
|
||||
if (rc < 0 && rc != LIBUSB_ERROR_TIMEOUT) {
|
||||
fprintf(stderr, "BULK IN transfer error; rc=%d\n", rc);
|
||||
return;
|
||||
|
@ -362,6 +365,7 @@ int main(int argc, char **argv)
|
|||
int skip_atr = 0;
|
||||
int keep_running = 0;
|
||||
int remote_udp_port = 52342;
|
||||
int if_num = 0;
|
||||
char *remote_udp_host = NULL;
|
||||
struct osim_reader_hdl *reader;
|
||||
struct osim_card_hdl *card;
|
||||
|
@ -371,7 +375,7 @@ int main(int argc, char **argv)
|
|||
while (1) {
|
||||
int option_index = 0;
|
||||
|
||||
c = getopt_long(argc, argv, "r:p:hi:ak", opts, &option_index);
|
||||
c = getopt_long(argc, argv, "r:p:hi:I:ak", opts, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
switch (c) {
|
||||
|
@ -388,6 +392,9 @@ int main(int argc, char **argv)
|
|||
case 'i':
|
||||
gsmtap_host = optarg;
|
||||
break;
|
||||
case 'I':
|
||||
if_num = atoi(optarg);
|
||||
break;
|
||||
case 'a':
|
||||
skip_atr = 1;
|
||||
break;
|
||||
|
@ -407,7 +414,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
} else {
|
||||
g_udp_fd = osmo_sock_init(AF_INET, SOCK_DGRAM, IPPROTO_UDP, remote_udp_host,
|
||||
remote_udp_port, OSMO_SOCK_F_CONNECT);
|
||||
remote_udp_port+if_num, OSMO_SOCK_F_CONNECT);
|
||||
if (g_udp_fd < 0) {
|
||||
fprintf(stderr, "error binding UDP port\n");
|
||||
goto do_exit;
|
||||
|
@ -447,9 +454,15 @@ int main(int argc, char **argv)
|
|||
goto close_exit;
|
||||
}
|
||||
|
||||
rc = libusb_claim_interface(g_devh, 0);
|
||||
rc = libusb_claim_interface(g_devh, if_num);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "can't claim interface; rc=%d\n", rc);
|
||||
fprintf(stderr, "can't claim interface %d; rc=%d\n", if_num, rc);
|
||||
goto close_exit;
|
||||
}
|
||||
|
||||
rc = get_usb_ep_addrs(g_devh, if_num, &g_out_ep, &g_in_ep, NULL);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "can't obtain EP addrs; rc=%d\n", rc);
|
||||
goto close_exit;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "simtrace.h"
|
||||
#include "cardemu_prot.h"
|
||||
#include "apdu_dispatch.h"
|
||||
#include "simtrace2-discovery.h"
|
||||
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
|
@ -56,6 +57,7 @@ static void print_welcome(void)
|
|||
static void print_help(void)
|
||||
{
|
||||
printf( "\t-h\t--help\n"
|
||||
"\t-i\t--interface <0-255>\n"
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
|
@ -76,8 +78,7 @@ static void usb_in_xfer_cb(struct libusb_transfer *xfer)
|
|||
xfer->endpoint, xfer->status, xfer->flags, xfer->type, xfer->length, xfer->actual_length);
|
||||
switch (xfer->status) {
|
||||
case LIBUSB_TRANSFER_COMPLETED:
|
||||
switch (xfer->endpoint) {
|
||||
case SIMTRACE_IN_EP:
|
||||
if (xfer->endpoint == g_buf_in.ep) {
|
||||
/* process the data */
|
||||
printf("read %d bytes from SIMTRACE, forwarding to UDP\n", xfer->actual_length);
|
||||
rc = sendto(g_udp_ofd.fd, xfer->buffer, xfer->actual_length, 0, (struct sockaddr *)&g_sa_remote, sizeof(g_sa_remote));
|
||||
|
@ -86,11 +87,9 @@ static void usb_in_xfer_cb(struct libusb_transfer *xfer)
|
|||
}
|
||||
/* and re-submit the URB */
|
||||
libusb_submit_transfer(xfer);
|
||||
break;
|
||||
case SIMTRACE_OUT_EP:
|
||||
} else if (xfer->endpoint == g_buf_out.ep) {
|
||||
/* re-enable reading from the UDP side */
|
||||
g_udp_ofd.when |= BSC_FD_READ;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -99,9 +98,8 @@ static void usb_in_xfer_cb(struct libusb_transfer *xfer)
|
|||
}
|
||||
}
|
||||
|
||||
static void init_ep_buf(int ep, struct ep_buf *epb)
|
||||
static void init_ep_buf(struct ep_buf *epb)
|
||||
{
|
||||
epb->ep = ep;
|
||||
if (!epb->xfer)
|
||||
epb->xfer = libusb_alloc_transfer(0);
|
||||
|
||||
|
@ -208,6 +206,7 @@ int main(int argc, char **argv)
|
|||
int c, ret = 1;
|
||||
char *remote_host = NULL;
|
||||
int local_udp_port = 52342;
|
||||
unsigned int if_num = 0;
|
||||
|
||||
print_welcome();
|
||||
|
||||
|
@ -215,17 +214,21 @@ int main(int argc, char **argv)
|
|||
int option_index = 0;
|
||||
static const struct option opts[] = {
|
||||
{ "udp-port", 1, 0, 'u' },
|
||||
{ "interface", 1, 0, 'I' },
|
||||
{ "help", 0, 0, 'h' },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "u:p:h", opts, &option_index);
|
||||
c = getopt_long(argc, argv, "u:I:h", opts, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
switch (c) {
|
||||
case 'u':
|
||||
local_udp_port = atoi(optarg);
|
||||
break;
|
||||
case 'I':
|
||||
if_num = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
print_help();
|
||||
exit(0);
|
||||
|
@ -247,20 +250,25 @@ int main(int argc, char **argv)
|
|||
goto close_exit;
|
||||
}
|
||||
|
||||
rc = libusb_claim_interface(g_devh, 0);
|
||||
rc = libusb_claim_interface(g_devh, if_num);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "can't claim interface; rc=%d\n", rc);
|
||||
fprintf(stderr, "can't claim interface %u; rc=%d\n", if_num, rc);
|
||||
goto close_exit;
|
||||
}
|
||||
|
||||
/* open UDP socket, register with select handling and mark it
|
||||
* readable */
|
||||
g_udp_ofd.cb = ofd_udp_cb;
|
||||
osmo_sock_init_ofd(&g_udp_ofd, AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, local_udp_port, OSMO_SOCK_F_BIND);
|
||||
osmo_sock_init_ofd(&g_udp_ofd, AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, local_udp_port + if_num, OSMO_SOCK_F_BIND);
|
||||
|
||||
rc = get_usb_ep_addrs(g_devh, if_num, &g_buf_out.ep, &g_buf_in.ep, NULL);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "couldn't find enpdoint addresses; rc=%d\n", rc);
|
||||
goto close_exit;
|
||||
}
|
||||
/* initialize USB buffers / transfers */
|
||||
init_ep_buf(SIMTRACE_OUT_EP, &g_buf_out);
|
||||
init_ep_buf(SIMTRACE_IN_EP, &g_buf_in);
|
||||
init_ep_buf(&g_buf_out);
|
||||
init_ep_buf(&g_buf_in);
|
||||
|
||||
/* submit the first transfer for the IN endpoint */
|
||||
libusb_submit_transfer(g_buf_in.xfer);
|
||||
|
|
Loading…
Reference in New Issue