remsim-client: Port from local copy to libosmousb + libosmo-simtrace2
We originally imported a copy of [most of] the code of simtrace2.git/host into this repository. That was a quick hack to get things going, but now that simtrace2.git is providing a shared library of simtrace2 utility functions, let's migrate over to it. At the same time, some functions (libusb_util) have been migrated to libosmousb (a new library in libosmocore.git), so we must add that as new dependency, too. This performs the minimally required changes and is *not* a proper port to the libosmousb osmocore select loop integration, whcih will follow in a separate patch. Change-Id: Idf5a861f4dacbec3c664f4ced6e03d8662c73112 Closes: OS#4298 Related: OS#4299 Depends: libosmocore.git I656a1a38cbb5b1f3a9145d2869d3b4d0adefcae3
This commit is contained in:
parent
0fd77a5790
commit
fd5dafc2a2
|
@ -39,6 +39,8 @@ PKG_CHECK_MODULES(OSMOCORE, libosmocore >= 0.11.0)
|
|||
PKG_CHECK_MODULES(OSMOGSM, libosmogsm >= 0.11.0)
|
||||
PKG_CHECK_MODULES(OSMOABIS, libosmoabis)
|
||||
PKG_CHECK_MODULES(OSMOSIM, libosmosim)
|
||||
PKG_CHECK_MODULES(OSMOUSB, libosmousb)
|
||||
PKG_CHECK_MODULES(OSMOSIMTRACE2, libosmo-simtrace2)
|
||||
PKG_CHECK_MODULES(USB, libusb-1.0)
|
||||
|
||||
AC_ARG_ENABLE([remsim-server],[AS_HELP_STRING([--disable-remsim-server], [Build osmo-remsim-server])],
|
||||
|
|
|
@ -25,6 +25,7 @@ export LD_LIBRARY_PATH="$inst/lib"
|
|||
osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||
osmo-build-dep.sh libosmo-abis
|
||||
osmo-build-dep.sh libosmo-netif
|
||||
osmo-build-dep.sh simtrace2
|
||||
|
||||
set +x
|
||||
echo
|
||||
|
|
|
@ -9,6 +9,7 @@ endif
|
|||
AM_CFLAGS = -Wall -I$(top_srcdir)/include -I$(top_builddir)/include \
|
||||
$(OSMOCORE_CFLAGS) $(OSMOGSM_CFLAGS) $(OSMOABIS_CFLAGS) \
|
||||
$(PCSC_CFLAGS) $(USB_CFLAGS) $(OSMOSIM_CFLAGS) \
|
||||
$(OSMOSIMTRACE2_CFLAGS) \
|
||||
-I$(top_srcdir)/include/osmocom/rspro
|
||||
|
||||
RSPRO_LIBVERSION=1:0:0
|
||||
|
@ -19,12 +20,7 @@ libosmo_rspro_la_LIBADD = $(OSMOCORE_LIBS) $(OSMOGSM_LIBS) $(OSMOABIS_LIBS) \
|
|||
libosmo_rspro_la_SOURCES = rspro_util.c asn1c_helpers.c
|
||||
|
||||
noinst_HEADERS = debug.h client.h rspro_util.h slotmap.h rspro_client_fsm.h \
|
||||
asn1c_helpers.h \
|
||||
simtrace2/apdu_dispatch.h \
|
||||
simtrace2/libusb_util.h \
|
||||
simtrace2/simtrace2-discovery.h \
|
||||
simtrace2/simtrace_prot.h \
|
||||
simtrace2/simtrace_usb.h
|
||||
asn1c_helpers.h
|
||||
|
||||
bin_PROGRAMS = osmo-remsim-client-st2
|
||||
|
||||
|
@ -33,9 +29,7 @@ remsim_client_LDADD = $(OSMOCORE_LIBS) $(OSMOGSM_LIBS) $(OSMOABIS_LIBS) \
|
|||
libosmo-rspro.la
|
||||
|
||||
osmo_remsim_client_st2_SOURCES = simtrace2-remsim_client.c \
|
||||
rspro_client_fsm.c debug.c \
|
||||
simtrace2/apdu_dispatch.c \
|
||||
simtrace2/simtrace2-discovery.c \
|
||||
simtrace2/libusb_util.c
|
||||
rspro_client_fsm.c debug.c
|
||||
osmo_remsim_client_st2_LDADD = $(OSMOCORE_LIBS) $(OSMOGSM_LIBS) $(OSMOABIS_LIBS) \
|
||||
$(OSMOUSB_LIBS) $(OSMOSIMTRACE2_LIBS) \
|
||||
$(USB_LIBS) $(OSMOSIM_LIBS) libosmo-rspro.la
|
||||
|
|
|
@ -50,11 +50,10 @@
|
|||
|
||||
#include <libusb.h>
|
||||
|
||||
#include "simtrace2/libusb_util.h"
|
||||
#include "simtrace2/simtrace_prot.h"
|
||||
#include "simtrace2/simtrace_usb.h"
|
||||
#include "simtrace2/apdu_dispatch.h"
|
||||
#include "simtrace2/simtrace2-discovery.h"
|
||||
#include <osmocom/usb/libusb.h>
|
||||
#include <osmocom/simtrace2/simtrace_prot.h>
|
||||
#include <osmocom/simtrace2/simtrace_usb.h>
|
||||
#include <osmocom/simtrace2/apdu_dispatch.h>
|
||||
|
||||
#include <osmocom/core/gsmtap.h>
|
||||
#include <osmocom/core/gsmtap_util.h>
|
||||
|
@ -406,7 +405,7 @@ __attribute__((unused)) static int process_do_error(struct cardem_inst *ci, uint
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct apdu_context ac; // this will hold the complete APDU (across calls)
|
||||
static struct osmo_apdu_context ac; // this will hold the complete APDU (across calls)
|
||||
|
||||
/*! \brief Process a RX-DATA indication message from the SIMtrace2 */
|
||||
static int process_do_rx_da(struct cardem_inst *ci, uint8_t *buf, int len)
|
||||
|
@ -417,8 +416,8 @@ static int process_do_rx_da(struct cardem_inst *ci, uint8_t *buf, int len)
|
|||
printf("SIMtrace => DATA: flags=%x, %s: ", data->flags,
|
||||
osmo_hexdump(data->data, data->data_len));
|
||||
|
||||
rc = apdu_segment_in(&ac, data->data, data->data_len,
|
||||
data->flags & CEMU_DATA_F_TPDU_HDR); // parse the APDU data in the USB message
|
||||
rc = osmo_apdu_segment_in(&ac, data->data, data->data_len,
|
||||
data->flags & CEMU_DATA_F_TPDU_HDR); // parse the APDU data in the USB message
|
||||
|
||||
if (rc & APDU_ACT_TX_CAPDU_TO_CARD) { // there is no pending data coming from the modem
|
||||
uint8_t apdu_command[sizeof(ac.hdr) + ac.lc.tot]; // to store the APDU command to send
|
||||
|
@ -864,7 +863,7 @@ int main(int argc, char **argv)
|
|||
ifm->addr = addr;
|
||||
if (path)
|
||||
osmo_strlcpy(ifm->path, path, sizeof(ifm->path));
|
||||
transp->usb_devh = usb_open_claim_interface(NULL, ifm);
|
||||
transp->usb_devh = osmo_libusb_open_claim_interface(NULL, NULL, ifm);
|
||||
if (!transp->usb_devh) {
|
||||
fprintf(stderr, "can't open USB device\n");
|
||||
goto close_exit;
|
||||
|
@ -876,8 +875,8 @@ int main(int argc, char **argv)
|
|||
goto close_exit;
|
||||
}
|
||||
|
||||
rc = get_usb_ep_addrs(transp->usb_devh, if_num, &transp->usb_ep.out,
|
||||
&transp->usb_ep.in, &transp->usb_ep.irq_in);
|
||||
rc = osmo_libusb_get_ep_addrs(transp->usb_devh, if_num, &transp->usb_ep.out,
|
||||
&transp->usb_ep.in, &transp->usb_ep.irq_in);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "can't obtain EP addrs; rc=%d\n", rc);
|
||||
goto close_exit;
|
||||
|
|
|
@ -1,173 +0,0 @@
|
|||
/* apdu_dispatch - State machine to determine Rx/Tx phases of APDU
|
||||
*
|
||||
* (C) 2016 by Harald Welte <hwelte@hmw-consulting.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/sim/sim.h>
|
||||
#include <osmocom/sim/class_tables.h>
|
||||
|
||||
#include "apdu_dispatch.h"
|
||||
|
||||
/*! \brief Has the command-data phase been completed yet? */
|
||||
static inline bool is_dc_complete(struct apdu_context *ac)
|
||||
{
|
||||
return (ac->lc.tot == ac->lc.cur);
|
||||
}
|
||||
|
||||
/*! \brief Has the expected-data phase been completed yet? */
|
||||
static inline bool is_de_complete(struct apdu_context *ac)
|
||||
{
|
||||
return (ac->le.tot == ac->le.cur);
|
||||
}
|
||||
|
||||
static const char *dump_apdu_hdr(const struct osim_apdu_cmd_hdr *h)
|
||||
{
|
||||
static char buf[256];
|
||||
sprintf(buf, "CLA=%02x INS=%02x P1=%02x P2=%02x P3=%02x",
|
||||
h->cla, h->ins, h->p1, h->p2, h->p3);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void dump_apdu_ctx(const struct apdu_context *ac)
|
||||
{
|
||||
printf("%s; case=%d, lc=%d(%d), le=%d(%d)\n",
|
||||
dump_apdu_hdr(&ac->hdr), ac->apdu_case,
|
||||
ac->lc.tot, ac->lc.cur,
|
||||
ac->le.tot, ac->le.cur);
|
||||
}
|
||||
|
||||
/*! \brief input function for APDU segmentation
|
||||
* \param ac APDU context across successive calls
|
||||
* \param[in] apdu_buf APDU inpud data buffer
|
||||
* \param[in] apdu_len Length of apdu_buf
|
||||
* \param[in] new_apdu Is this the beginning of a new APDU?
|
||||
*
|
||||
* The function returns APDU_ACT_TX_CAPDU_TO_CARD once there is
|
||||
* sufficient data of the APDU received to transmit the command-APDU to
|
||||
* the actual card.
|
||||
*
|
||||
* The function retunrs APDU_ACT_RX_MORE_CAPDU_FROM_READER when there
|
||||
* is more data to be received from the card reader (GSM Phone).
|
||||
*/
|
||||
int apdu_segment_in(struct apdu_context *ac, const uint8_t *apdu_buf,
|
||||
unsigned int apdu_len, bool new_apdu)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (new_apdu) {
|
||||
/* initialize the apdu context structure */
|
||||
memset(ac, 0, sizeof(*ac));
|
||||
/* copy APDU header over */
|
||||
memcpy(&ac->hdr, apdu_buf, sizeof(ac->hdr));
|
||||
ac->apdu_case = osim_determine_apdu_case(&osim_uicc_sim_cic_profile, apdu_buf);
|
||||
switch (ac->apdu_case) {
|
||||
case 1: /* P3 == 0, No Lc/Le */
|
||||
ac->le.tot = ac->lc.tot = 0;
|
||||
break;
|
||||
case 2: /* P3 == Le */
|
||||
ac->le.tot = ac->hdr.p3;
|
||||
break;
|
||||
case 3: /* P3 = Lc */
|
||||
ac->lc.tot = ac->hdr.p3;
|
||||
/* copy Dc */
|
||||
ac->lc.cur = apdu_len - sizeof(ac->hdr);
|
||||
memcpy(ac->dc, apdu_buf + sizeof(ac->hdr),
|
||||
ac->lc.cur);
|
||||
break;
|
||||
case 4: /* P3 = Lc; SW with Le */
|
||||
ac->lc.tot = ac->hdr.p3;
|
||||
/* copy Dc */
|
||||
ac->lc.cur = apdu_len - sizeof(ac->hdr);
|
||||
memcpy(ac->dc, apdu_buf + sizeof(ac->hdr),
|
||||
ac->lc.cur);
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
fprintf(stderr, "Unknown APDU case %d\n", ac->apdu_case);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* copy more data, if available */
|
||||
int cpy_len;
|
||||
switch (ac->apdu_case) {
|
||||
case 1:
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
cpy_len = ac->lc.tot - ac->lc.cur;
|
||||
if (cpy_len > apdu_len)
|
||||
cpy_len = apdu_len;
|
||||
memcpy(ac->dc+ac->lc.cur, apdu_buf, cpy_len);
|
||||
ac->lc.cur += cpy_len;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown APDU case %d\n", ac->apdu_case);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* take some decisions... */
|
||||
switch (ac->apdu_case) {
|
||||
case 1: /* P3 == 0, No Lc/Le */
|
||||
/* send C-APDU to card */
|
||||
/* receive SW from card, forward to reader */
|
||||
rc |= APDU_ACT_TX_CAPDU_TO_CARD;
|
||||
break;
|
||||
case 2: /* P3 == Le */
|
||||
/* send C-APDU to card */
|
||||
/* receive Le bytes + SW from card, forward to reader */
|
||||
rc |= APDU_ACT_TX_CAPDU_TO_CARD;
|
||||
break;
|
||||
case 3: /* P3 = Lc */
|
||||
if (!is_dc_complete(ac)) {
|
||||
/* send PB + read further Lc bytes from reader */
|
||||
rc |= APDU_ACT_RX_MORE_CAPDU_FROM_READER;
|
||||
} else {
|
||||
/* send C-APDU to card */
|
||||
/* receive SW from card, forward to reader */
|
||||
rc |= APDU_ACT_TX_CAPDU_TO_CARD;
|
||||
}
|
||||
break;
|
||||
case 4: /* P3 = Lc; SW with Le */
|
||||
if (!is_dc_complete(ac)) {
|
||||
/* send PB + read further Lc bytes from reader */
|
||||
rc |= APDU_ACT_RX_MORE_CAPDU_FROM_READER;
|
||||
} else {
|
||||
/* send C-APDU to card */
|
||||
/* receive SW from card, forward to reader */
|
||||
rc |= APDU_ACT_TX_CAPDU_TO_CARD;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
fprintf(stderr, "Unknown APDU case %d\n", ac->apdu_case);
|
||||
break;
|
||||
}
|
||||
|
||||
dump_apdu_ctx(ac);
|
||||
|
||||
return rc;
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/* apdu_dispatch - State machine to determine Rx/Tx phases of APDU
|
||||
*
|
||||
* (C) 2016 by Harald Welte <hwelte@hmw-consulting.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <osmocom/sim/sim.h>
|
||||
|
||||
struct apdu_context {
|
||||
struct osim_apdu_cmd_hdr hdr;
|
||||
uint8_t dc[256];
|
||||
uint8_t de[256];
|
||||
uint8_t sw[2];
|
||||
uint8_t apdu_case;
|
||||
struct {
|
||||
uint8_t tot;
|
||||
uint8_t cur;
|
||||
} lc;
|
||||
struct {
|
||||
uint8_t tot;
|
||||
uint8_t cur;
|
||||
} le;
|
||||
};
|
||||
|
||||
enum apdu_action {
|
||||
APDU_ACT_TX_CAPDU_TO_CARD = 0x0001,
|
||||
APDU_ACT_RX_MORE_CAPDU_FROM_READER = 0x0002,
|
||||
};
|
||||
|
||||
|
||||
int apdu_segment_in(struct apdu_context *ac, const uint8_t *apdu_buf,
|
||||
unsigned int apdu_len, bool new_apdu);
|
|
@ -1,297 +0,0 @@
|
|||
/* libisb utilities
|
||||
*
|
||||
* (C) 2010-2016 by Harald Welte <hwelte@hmw-consulting.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libusb.h>
|
||||
|
||||
#include "libusb_util.h"
|
||||
|
||||
static char path_buf[USB_MAX_PATH_LEN];
|
||||
|
||||
static char *get_path(libusb_device *dev)
|
||||
{
|
||||
#if (defined(LIBUSB_API_VERSION) && LIBUSB_API_VERSION >= 0x01000102) || (defined(LIBUSBX_API_VERSION) && LIBUSBX_API_VERSION >= 0x01000102)
|
||||
uint8_t path[8];
|
||||
int r,j;
|
||||
r = libusb_get_port_numbers(dev, path, sizeof(path));
|
||||
if (r > 0) {
|
||||
sprintf(path_buf,"%d-%d",libusb_get_bus_number(dev),path[0]);
|
||||
for (j = 1; j < r; j++){
|
||||
sprintf(path_buf+strlen(path_buf),".%d",path[j]);
|
||||
};
|
||||
}
|
||||
return path_buf;
|
||||
#else
|
||||
# warning "libusb too old - building without USB path support!"
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int match_dev_id(const struct libusb_device_descriptor *desc, const struct dev_id *id)
|
||||
{
|
||||
if ((desc->idVendor == id->vendor_id) && (desc->idProduct == id->product_id))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int match_dev_ids(const struct libusb_device_descriptor *desc, const struct dev_id *ids)
|
||||
{
|
||||
const struct dev_id *id;
|
||||
|
||||
for (id = ids; id->vendor_id || id->product_id; id++) {
|
||||
if (match_dev_id(desc, id))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
libusb_device **find_matching_usb_devs(const struct dev_id *dev_ids)
|
||||
{
|
||||
libusb_device **list;
|
||||
libusb_device **out = calloc(256, sizeof(libusb_device *));
|
||||
libusb_device **cur = out;
|
||||
unsigned int i;
|
||||
int rc;
|
||||
|
||||
if (!out)
|
||||
return NULL;
|
||||
|
||||
rc = libusb_get_device_list(NULL, &list);
|
||||
if (rc <= 0) {
|
||||
perror("No USB devices found");
|
||||
free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; list[i] != NULL; i++) {
|
||||
struct libusb_device_descriptor dev_desc;
|
||||
libusb_device *dev = list[i];
|
||||
|
||||
rc = libusb_get_device_descriptor(dev, &dev_desc);
|
||||
if (rc < 0) {
|
||||
perror("Couldn't get device descriptor\n");
|
||||
libusb_unref_device(dev);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (match_dev_ids(&dev_desc, dev_ids)) {
|
||||
*cur = dev;
|
||||
cur++;
|
||||
/* FIXME: overflow check */
|
||||
} else
|
||||
libusb_unref_device(dev);
|
||||
}
|
||||
if (cur == out) {
|
||||
libusb_free_device_list(list, 1);
|
||||
free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
libusb_free_device_list(list, 0);
|
||||
return out;
|
||||
}
|
||||
|
||||
int dev_find_matching_interfaces(libusb_device *dev, int class, int sub_class, int protocol,
|
||||
struct usb_interface_match *out, unsigned int out_len)
|
||||
{
|
||||
struct libusb_device_descriptor dev_desc;
|
||||
int rc, i, out_idx = 0;
|
||||
uint8_t addr;
|
||||
char *path;
|
||||
|
||||
rc = libusb_get_device_descriptor(dev, &dev_desc);
|
||||
if (rc < 0) {
|
||||
perror("Couldn't get device descriptor\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
addr = libusb_get_device_address(dev);
|
||||
path = get_path(dev);
|
||||
|
||||
/* iterate over all configurations */
|
||||
for (i = 0; i < dev_desc.bNumConfigurations; i++) {
|
||||
struct libusb_config_descriptor *conf_desc;
|
||||
int j;
|
||||
|
||||
rc = libusb_get_config_descriptor(dev, i, &conf_desc);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Couldn't get config descriptor %u\n", i);
|
||||
continue;
|
||||
}
|
||||
/* iterate over all interfaces */
|
||||
for (j = 0; j < conf_desc->bNumInterfaces; j++) {
|
||||
const struct libusb_interface *intf = &conf_desc->interface[j];
|
||||
int k;
|
||||
/* iterate over all alternate settings */
|
||||
for (k = 0; k < intf->num_altsetting; k++) {
|
||||
const struct libusb_interface_descriptor *if_desc;
|
||||
if_desc = &intf->altsetting[k];
|
||||
if (class >= 0 && if_desc->bInterfaceClass != class)
|
||||
continue;
|
||||
if (sub_class >= 0 && if_desc->bInterfaceSubClass != sub_class)
|
||||
continue;
|
||||
if (protocol >= 0 && if_desc->bInterfaceProtocol != protocol)
|
||||
continue;
|
||||
/* MATCH! */
|
||||
out[out_idx].usb_dev = dev;
|
||||
out[out_idx].vendor = dev_desc.idVendor;
|
||||
out[out_idx].product = dev_desc.idProduct;
|
||||
out[out_idx].addr = addr;
|
||||
strncpy(out[out_idx].path, path, sizeof(out[out_idx].path)-1);
|
||||
out[out_idx].path[sizeof(out[out_idx].path)-1] = '\0';
|
||||
out[out_idx].configuration = conf_desc->bConfigurationValue;
|
||||
out[out_idx].interface = if_desc->bInterfaceNumber;
|
||||
out[out_idx].altsetting = if_desc->bAlternateSetting;
|
||||
out[out_idx].class = if_desc->bInterfaceClass;
|
||||
out[out_idx].sub_class = if_desc->bInterfaceSubClass;
|
||||
out[out_idx].protocol = if_desc->bInterfaceProtocol;
|
||||
out[out_idx].string_idx = if_desc->iInterface;
|
||||
out_idx++;
|
||||
if (out_idx >= out_len)
|
||||
return out_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
return out_idx;
|
||||
}
|
||||
|
||||
int usb_match_interfaces(libusb_context *ctx, const struct dev_id *dev_ids,
|
||||
int class, int sub_class, int protocol,
|
||||
struct usb_interface_match *out, unsigned int out_len)
|
||||
{
|
||||
struct usb_interface_match *out_cur = out;
|
||||
unsigned int out_len_remain = out_len;
|
||||
libusb_device **list;
|
||||
libusb_device **dev;
|
||||
|
||||
list = find_matching_usb_devs(dev_ids);
|
||||
if (!list)
|
||||
return 0;
|
||||
|
||||
for (dev = list; *dev; dev++) {
|
||||
int rc;
|
||||
|
||||
#if 0
|
||||
struct libusb_device_descriptor dev_desc;
|
||||
uint8_t ports[8];
|
||||
uint8_t addr;
|
||||
rc = libusb_get_device_descriptor(*dev, &dev_desc);
|
||||
if (rc < 0) {
|
||||
perror("Cannot get device descriptor");
|
||||
continue;
|
||||
}
|
||||
|
||||
addr = libusb_get_device_address(*dev);
|
||||
|
||||
rc = libusb_get_port_numbers(*dev, ports, sizeof(ports));
|
||||
if (rc < 0) {
|
||||
perror("Cannot get device path");
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("Found USB Device %04x:%04x at address %d\n",
|
||||
dev_desc.idVendor, dev_desc.idProduct, addr);
|
||||
#endif
|
||||
|
||||
rc = dev_find_matching_interfaces(*dev, class, sub_class, protocol, out_cur, out_len_remain);
|
||||
if (rc < 0)
|
||||
continue;
|
||||
out_cur += rc;
|
||||
out_len_remain -= rc;
|
||||
|
||||
}
|
||||
return out_len - out_len_remain;
|
||||
}
|
||||
|
||||
libusb_device_handle *usb_open_claim_interface(libusb_context *ctx,
|
||||
const struct usb_interface_match *ifm)
|
||||
{
|
||||
int rc, config;
|
||||
struct dev_id dev_ids[] = { { ifm->vendor, ifm->product }, { 0, 0 } };
|
||||
libusb_device **list;
|
||||
libusb_device **dev;
|
||||
libusb_device_handle *usb_devh = NULL;
|
||||
|
||||
list = find_matching_usb_devs(dev_ids);
|
||||
if (!list) {
|
||||
perror("No USB device with matching VID/PID");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (dev = list; *dev; dev++) {
|
||||
int addr;
|
||||
char *path;
|
||||
|
||||
addr = libusb_get_device_address(*dev);
|
||||
path = get_path(*dev);
|
||||
if ((ifm->addr && addr == ifm->addr) ||
|
||||
(strlen(ifm->path) && !strcmp(path, ifm->path))) {
|
||||
rc = libusb_open(*dev, &usb_devh);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Cannot open device: %s\n", libusb_error_name(rc));
|
||||
usb_devh = NULL;
|
||||
break;
|
||||
}
|
||||
rc = libusb_get_configuration(usb_devh, &config);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Cannot get current configuration: %s\n", libusb_error_name(rc));
|
||||
libusb_close(usb_devh);
|
||||
usb_devh = NULL;
|
||||
break;
|
||||
}
|
||||
if (config != ifm->configuration) {
|
||||
rc = libusb_set_configuration(usb_devh, ifm->configuration);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Cannot set configuration: %s\n", libusb_error_name(rc));
|
||||
libusb_close(usb_devh);
|
||||
usb_devh = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rc = libusb_claim_interface(usb_devh, ifm->interface);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Cannot claim interface: %s\n", libusb_error_name(rc));
|
||||
libusb_close(usb_devh);
|
||||
usb_devh = NULL;
|
||||
break;
|
||||
}
|
||||
rc = libusb_set_interface_alt_setting(usb_devh, ifm->interface, ifm->altsetting);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Cannot set interface altsetting: %s\n", libusb_error_name(rc));
|
||||
libusb_release_interface(usb_devh, ifm->interface);
|
||||
libusb_close(usb_devh);
|
||||
usb_devh = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* unref / free list */
|
||||
for (dev = list; *dev; dev++)
|
||||
libusb_unref_device(*dev);
|
||||
free(list);
|
||||
|
||||
return usb_devh;
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
/* libisb utilities
|
||||
*
|
||||
* (C) 2010-2016 by Harald Welte <hwelte@hmw-consulting.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <libusb.h>
|
||||
|
||||
#define USB_MAX_PATH_LEN 20
|
||||
|
||||
struct dev_id {
|
||||
uint16_t vendor_id;
|
||||
uint16_t product_id;
|
||||
};
|
||||
|
||||
/* Find any USB devices in the system matching the given Vendor and
|
||||
* Product ID */
|
||||
libusb_device **find_matching_usb_devs(const struct dev_id *dev_ids);
|
||||
|
||||
/* structure describing a single matching interface found */
|
||||
struct usb_interface_match {
|
||||
/* libusb device E*/
|
||||
libusb_device *usb_dev;
|
||||
/* Vendor ID of the device running matching interface */
|
||||
uint16_t vendor;
|
||||
/* Product ID of the device running matching interface */
|
||||
uint16_t product;
|
||||
/* USB Bus Address */
|
||||
uint8_t addr;
|
||||
/* physical path */
|
||||
char path[USB_MAX_PATH_LEN];
|
||||
/* configuration of matching interface */
|
||||
uint8_t configuration;
|
||||
/* interface number of matching interface */
|
||||
uint8_t interface;
|
||||
/* altsetting of matching interface */
|
||||
uint8_t altsetting;
|
||||
/* bInterfaceClass of matching interface */
|
||||
uint8_t class;
|
||||
/* bInterfaceSubClass of matching interface */
|
||||
uint8_t sub_class;
|
||||
/* bInterfaceProtocol of matching interface */
|
||||
uint8_t protocol;
|
||||
/* index of string descriptor of matching interface */
|
||||
uint8_t string_idx;
|
||||
};
|
||||
|
||||
int dev_find_matching_interfaces(libusb_device *dev, int class, int sub_class, int protocol,
|
||||
struct usb_interface_match *out, unsigned int out_len);
|
||||
|
||||
int usb_match_interfaces(libusb_context *ctx, const struct dev_id *dev_ids,
|
||||
int class, int sub_class, int protocol,
|
||||
struct usb_interface_match *out, unsigned int out_len);
|
||||
|
||||
libusb_device_handle *usb_open_claim_interface(libusb_context *ctx,
|
||||
const struct usb_interface_match *ifm);
|
|
@ -1,94 +0,0 @@
|
|||
/* simtrace2-discovery - host PC library to scan for matching USB
|
||||
* devices
|
||||
*
|
||||
* (C) 2016 by Harald Welte <hwelte@hmw-consulting.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#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
|
|
@ -1,26 +0,0 @@
|
|||
/* simtrace2-discovery - host PC library to scan for matching USB
|
||||
* devices
|
||||
*
|
||||
* (C) 2016 by Harald Welte <hwelte@hmw-consulting.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#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);
|
|
@ -1,322 +0,0 @@
|
|||
/* SIMtrace2 USB protocol
|
||||
*
|
||||
* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.de>
|
||||
* (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/***********************************************************************
|
||||
* COMMON HEADER
|
||||
***********************************************************************/
|
||||
|
||||
enum simtrace_msg_class {
|
||||
SIMTRACE_MSGC_GENERIC = 0,
|
||||
/* Card Emulation / Forwarding */
|
||||
SIMTRACE_MSGC_CARDEM,
|
||||
/* Modem Control (if modem is attached next to device) */
|
||||
SIMTRACE_MSGC_MODEM,
|
||||
/* Reader/phone-car/SIM communication sniff */
|
||||
SIMTRACE_MSGC_SNIFF,
|
||||
|
||||
/* first vendor-specific request */
|
||||
_SIMTRACE_MGSC_VENDOR_FIRST = 127,
|
||||
};
|
||||
|
||||
enum simtrace_msg_type_generic {
|
||||
/* Generic Error Message */
|
||||
SIMTRACE_CMD_DO_ERROR = 0,
|
||||
/* Request/Response for simtrace_board_info */
|
||||
SIMTRACE_CMD_BD_BOARD_INFO,
|
||||
};
|
||||
|
||||
/* SIMTRACE_MSGC_CARDEM */
|
||||
enum simtrace_msg_type_cardem {
|
||||
/* TPDU Data to be transmitted to phone */
|
||||
SIMTRACE_MSGT_DT_CEMU_TX_DATA = 1,
|
||||
/* Set the ATR to be returned at phone-SIM reset */
|
||||
SIMTRACE_MSGT_DT_CEMU_SET_ATR,
|
||||
/* Get Statistics Request / Response */
|
||||
SIMTRACE_MSGT_BD_CEMU_STATS,
|
||||
/* Get Status Request / Response */
|
||||
SIMTRACE_MSGT_BD_CEMU_STATUS,
|
||||
/* Request / Confirm emulated card insert */
|
||||
SIMTRACE_MSGT_DT_CEMU_CARDINSERT,
|
||||
/* TPDU Data received from phomne */
|
||||
SIMTRACE_MSGT_DO_CEMU_RX_DATA,
|
||||
/* Indicate PTS request from phone */
|
||||
SIMTRACE_MSGT_DO_CEMU_PTS,
|
||||
};
|
||||
|
||||
/* SIMTRACE_MSGC_MODEM */
|
||||
enum simtrace_msg_type_modem {
|
||||
/* Modem Control: Reset an attached modem */
|
||||
SIMTRACE_MSGT_DT_MODEM_RESET = 1,
|
||||
/* Modem Control: Select local / remote SIM */
|
||||
SIMTRACE_MSGT_DT_MODEM_SIM_SELECT,
|
||||
/* Modem Control: Status (WWAN LED, SIM Presence) */
|
||||
SIMTRACE_MSGT_BD_MODEM_STATUS,
|
||||
};
|
||||
|
||||
/* SIMTRACE_MSGC_SNIFF */
|
||||
enum simtrace_msg_type_sniff {
|
||||
/* Status change (card inserted, reset, ...) */
|
||||
SIMTRACE_MSGT_SNIFF_CHANGE = 0,
|
||||
/* Fi/Di baudrate change */
|
||||
SIMTRACE_MSGT_SNIFF_FIDI,
|
||||
/* ATR data */
|
||||
SIMTRACE_MSGT_SNIFF_ATR,
|
||||
/* PPS (request or response) data */
|
||||
SIMTRACE_MSGT_SNIFF_PPS,
|
||||
/* TPDU data */
|
||||
SIMTRACE_MSGT_SNIFF_TPDU,
|
||||
};
|
||||
|
||||
/* common message header */
|
||||
struct simtrace_msg_hdr {
|
||||
uint8_t msg_class; /* simtrace_msg_class */
|
||||
uint8_t msg_type; /* simtrace_msg_type_xxx */
|
||||
uint8_t seq_nr;
|
||||
uint8_t slot_nr; /* SIM slot number */
|
||||
uint16_t _reserved;
|
||||
uint16_t msg_len; /* length including header */
|
||||
uint8_t payload[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/***********************************************************************
|
||||
* Capabilities
|
||||
***********************************************************************/
|
||||
|
||||
/* generic capabilities */
|
||||
enum simtrace_capability_generic {
|
||||
/* compatible with 5V SIM card interface */
|
||||
SIMTRACE_CAP_VOLT_5V,
|
||||
/* compatible with 3.3V SIM card interface */
|
||||
SIMTRACE_CAP_VOLT_3V3,
|
||||
/* compatible with 1.8V SIM card interface */
|
||||
SIMTRACE_CAP_VOLT_1V8,
|
||||
/* Has LED1 */
|
||||
SIMTRACE_CAP_LED_1,
|
||||
/* Has LED2 */
|
||||
SIMTRACE_CAP_LED_2,
|
||||
/* Has Single-Pole Dual-Throw (local/remote SIM) */
|
||||
SIMTRACE_CAP_SPDT,
|
||||
/* Has Bus-Switch (trace / MITM) */
|
||||
SIMTRACE_CAP_BUS_SWITCH,
|
||||
/* Can read VSIM via ADC */
|
||||
SIMTRACE_CAP_VSIM_ADC,
|
||||
/* Can read temperature via ADC */
|
||||
SIMTRACE_CAP_TEMP_ADC,
|
||||
/* Supports DFU for firmware update */
|
||||
SIMTRACE_CAP_DFU,
|
||||
/* Supports Ctrl EP command for erasing flash / return to SAM-BA */
|
||||
SIMTRACE_CAP_ERASE_FLASH,
|
||||
/* Can read the status of card insert contact */
|
||||
SIMTRACE_CAP_READ_CARD_DET,
|
||||
/* Can control the status of a simulated card insert */
|
||||
SIMTRACE_CAP_ASSERT_CARD_DET,
|
||||
/* Can toggle the hardware reset of an attached modem */
|
||||
SIMTRACE_CAP_ASSERT_MODEM_RST,
|
||||
};
|
||||
|
||||
/* vendor-specific capabilities of sysmocom devices */
|
||||
enum simtrace_capability_vendor {
|
||||
/* Can erase a peer SAM3 controller */
|
||||
SIMTRACE_CAP_SYSMO_QMOD_ERASE_PEER,
|
||||
/* Can read/write an attached EEPROM */
|
||||
SIMTRACE_CAP_SYSMO_QMOD_RW_EEPROM,
|
||||
/* can reset an attached USB hub */
|
||||
SIMTRACE_CAP_SYSMO_QMOD_RESET_HUB,
|
||||
};
|
||||
|
||||
/* SIMTRACE_CMD_BD_BOARD_INFO */
|
||||
struct simtrace_board_info {
|
||||
struct {
|
||||
char manufacturer[32];
|
||||
char model[32];
|
||||
char version[32];
|
||||
} hardware;
|
||||
struct {
|
||||
/* who provided this software? */
|
||||
char provider[32];
|
||||
/* name of software image */
|
||||
char name[32];
|
||||
/* (git) version at build time */
|
||||
char version[32];
|
||||
/* built on which machine? */
|
||||
char buildhost[32];
|
||||
/* CRC-32 over software image */
|
||||
uint32_t crc;
|
||||
} software;
|
||||
struct {
|
||||
/* Maximum baud rate supported */
|
||||
uint32_t max_baud_rate;
|
||||
} speed;
|
||||
/* number of bytes of generic capability bit-mask */
|
||||
uint8_t cap_generic_bytes;
|
||||
/* number of bytes of vendor capability bit-mask */
|
||||
uint8_t cap_vendor_bytes;
|
||||
uint8_t data[0];
|
||||
/* cap_generic + cap_vendor */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/***********************************************************************
|
||||
* CARD EMULATOR / FORWARDER
|
||||
***********************************************************************/
|
||||
|
||||
/* indicates a TPDU header is present in this message */
|
||||
#define CEMU_DATA_F_TPDU_HDR 0x00000001
|
||||
/* indicates last part of transmission in this direction */
|
||||
#define CEMU_DATA_F_FINAL 0x00000002
|
||||
/* incdicates a PB is present and we should continue with TX */
|
||||
#define CEMU_DATA_F_PB_AND_TX 0x00000004
|
||||
/* incdicates a PB is present and we should continue with RX */
|
||||
#define CEMU_DATA_F_PB_AND_RX 0x00000008
|
||||
|
||||
/* CEMU_USB_MSGT_DT_CARDINSERT */
|
||||
struct cardemu_usb_msg_cardinsert {
|
||||
uint8_t card_insert;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* CEMU_USB_MSGT_DT_SET_ATR */
|
||||
struct cardemu_usb_msg_set_atr {
|
||||
uint8_t atr_len;
|
||||
/* variable-length ATR data */
|
||||
uint8_t atr[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* CEMU_USB_MSGT_DT_TX_DATA */
|
||||
struct cardemu_usb_msg_tx_data {
|
||||
uint32_t flags;
|
||||
uint16_t data_len;
|
||||
/* variable-length TPDU data */
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* CEMU_USB_MSGT_DO_RX_DATA */
|
||||
struct cardemu_usb_msg_rx_data {
|
||||
uint32_t flags;
|
||||
uint16_t data_len;
|
||||
/* variable-length TPDU data */
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define CEMU_STATUS_F_VCC_PRESENT 0x00000001
|
||||
#define CEMU_STATUS_F_CLK_ACTIVE 0x00000002
|
||||
#define CEMU_STATUS_F_RCEMU_ACTIVE 0x00000004
|
||||
#define CEMU_STATUS_F_CARD_INSERT 0x00000008
|
||||
#define CEMU_STATUS_F_RESET_ACTIVE 0x00000010
|
||||
|
||||
/* CEMU_USB_MSGT_DO_STATUS */
|
||||
struct cardemu_usb_msg_status {
|
||||
uint32_t flags;
|
||||
/* phone-applied target voltage in mV */
|
||||
uint16_t voltage_mv;
|
||||
/* Fi/Di related information */
|
||||
uint8_t fi;
|
||||
uint8_t di;
|
||||
uint8_t wi;
|
||||
uint32_t waiting_time;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* CEMU_USB_MSGT_DO_PTS */
|
||||
struct cardemu_usb_msg_pts_info {
|
||||
uint8_t pts_len;
|
||||
/* PTS request as sent from reader */
|
||||
uint8_t req[6];
|
||||
/* PTS response as sent by card */
|
||||
uint8_t resp[6];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* CEMU_USB_MSGT_DO_ERROR */
|
||||
struct cardemu_usb_msg_error {
|
||||
uint8_t severity;
|
||||
uint8_t subsystem;
|
||||
uint16_t code;
|
||||
uint8_t msg_len;
|
||||
/* human-readable error message */
|
||||
uint8_t msg[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/***********************************************************************
|
||||
* MODEM CONTROL
|
||||
***********************************************************************/
|
||||
|
||||
/* SIMTRACE_MSGT_DT_MODEM_RESET */
|
||||
struct st_modem_reset {
|
||||
/* 0: de-assert reset, 1: assert reset, 2: pulse reset */
|
||||
uint8_t asserted;
|
||||
/* if above is '2', duration of pulse in ms */
|
||||
uint16_t pulse_duration_msec;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* SIMTRACE_MSGT_DT_MODEM_SIM_SELECT */
|
||||
struct st_modem_sim_select {
|
||||
/* remote (1), local (0) */
|
||||
uint8_t remote_sim;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* SIMTRACE_MSGT_BD_MODEM_STATUS */
|
||||
#define ST_MDM_STS_BIT_WWAN_LED (1 << 0)
|
||||
#define ST_MDM_STS_BIT_CARD_INSERTED (1 << 1)
|
||||
struct st_modem_status {
|
||||
/* bit-field of supported status bits */
|
||||
uint8_t supported_mask;
|
||||
/* bit-field of current status bits */
|
||||
uint8_t status_mask;
|
||||
/* bit-field of changed status bits */
|
||||
uint8_t changed_mask;
|
||||
} __attribute__((packed));
|
||||
|
||||
/***********************************************************************
|
||||
* SNIFF
|
||||
***********************************************************************/
|
||||
|
||||
/* SIMTRACE_MSGT_SNIFF_CHANGE flags */
|
||||
#define SNIFF_CHANGE_FLAG_CARD_INSERT (1<<0)
|
||||
#define SNIFF_CHANGE_FLAG_CARD_EJECT (1<<1)
|
||||
#define SNIFF_CHANGE_FLAG_RESET_ASSERT (1<<2)
|
||||
#define SNIFF_CHANGE_FLAG_RESET_DEASSERT (1<<3)
|
||||
#define SNIFF_CHANGE_FLAG_TIMEOUT_WT (1<<4)
|
||||
/* SIMTRACE_MSGT_SNIFF_ATR, SIMTRACE_MSGT_SNIFF_PPS, SIMTRACE_MSGT_SNIFF_TPDU flags */
|
||||
#define SNIFF_DATA_FLAG_ERROR_INCOMPLETE (1<<5)
|
||||
#define SNIFF_DATA_FLAG_ERROR_MALFORMED (1<<6)
|
||||
#define SNIFF_DATA_FLAG_ERROR_CHECKSUM (1<<7)
|
||||
|
||||
/* SIMTRACE_MSGT_SNIFF_CHANGE */
|
||||
struct sniff_change {
|
||||
/* SIMTRACE_MSGT_SNIFF_CHANGE flags */
|
||||
uint32_t flags;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* SIMTRACE_MSGT_SNIFF_FIDI */
|
||||
struct sniff_fidi {
|
||||
/* Fi/Di values as encoded in TA1 */
|
||||
uint8_t fidi;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* SIMTRACE_MSGT_SNIFF_ATR, SIMTRACE_MSGT_SNIFF_PPS, SIMTRACE_MSGT_SNIFF_TPDU */
|
||||
struct sniff_data {
|
||||
/* data flags */
|
||||
uint32_t flags;
|
||||
/* data length */
|
||||
uint16_t length;
|
||||
/* data */
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
|
@ -1,67 +0,0 @@
|
|||
/* SIMtrace 2 USB definitions
|
||||
*
|
||||
* (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
/* SIMtrace USB IDs */
|
||||
#define USB_VENDOR_OPENMOKO 0x1d50
|
||||
#define USB_PRODUCT_OWHW_SAM3_DFU 0x4001 /* was 0x4000 */
|
||||
#define USB_PRODUCT_OWHW_SAM3 0x4001
|
||||
#define USB_PRODUCT_QMOD_HUB 0x4002
|
||||
#define USB_PRODUCT_QMOD_SAM3_DFU 0x4004 /* was 0x4003 */
|
||||
#define USB_PRODUCT_QMOD_SAM3 0x4004
|
||||
#define USB_PRODUCT_SIMTRACE2_DFU 0x60e3 /* was 0x60e2 */
|
||||
#define USB_PRODUCT_SIMTRACE2 0x60e3
|
||||
|
||||
/* USB proprietary class */
|
||||
#define USB_CLASS_PROPRIETARY 0xff
|
||||
|
||||
/* SIMtrace USB sub-classes */
|
||||
/*! Sniffer USB sub-class */
|
||||
#define SIMTRACE_SNIFFER_USB_SUBCLASS 1
|
||||
/*! Card-emulation USB sub-class */
|
||||
#define SIMTRACE_CARDEM_USB_SUBCLASS 2
|
||||
|
||||
/* Generic USB endpoint numbers */
|
||||
/*! Card-side USB data out (host to device) endpoint number */
|
||||
#define SIMTRACE_USB_EP_CARD_DATAOUT 1
|
||||
/*! Card-side USB data in (device to host) endpoint number */
|
||||
#define SIMTRACE_USB_EP_CARD_DATAIN 2
|
||||
/*! Card-side USB interrupt endpoint number */
|
||||
#define SIMTRACE_USB_EP_CARD_INT 3
|
||||
/*! Phone-side USB data out (host to device) endpoint number */
|
||||
#define SIMTRACE_USB_EP_PHONE_DATAOUT 4
|
||||
/*! Phone-side USB data in (device to host) endpoint number */
|
||||
#define SIMTRACE_USB_EP_PHONE_DATAIN 5
|
||||
/*! Phone-side USB interrupt endpoint number */
|
||||
#define SIMTRACE_USB_EP_PHONE_INT 6
|
||||
|
||||
/* Card-emulation USB endpoint numbers */
|
||||
/*! USIM1 USB data out (host to device) endpoint number */
|
||||
#define SIMTRACE_CARDEM_USB_EP_USIM1_DATAOUT 4
|
||||
/*! USIM1 USB data in (device to host) endpoint number */
|
||||
#define SIMTRACE_CARDEM_USB_EP_USIM1_DATAIN 5
|
||||
/*! USIM1 USB interrupt endpoint number */
|
||||
#define SIMTRACE_CARDEM_USB_EP_USIM1_INT 6
|
||||
/*! USIM2 USB data out (host to device) endpoint number */
|
||||
#define SIMTRACE_CARDEM_USB_EP_USIM2_DATAOUT 1
|
||||
/*! USIM2 USB data in (device to host) endpoint number */
|
||||
#define SIMTRACE_CARDEM_USB_EP_USIM2_DATAIN 2
|
||||
/*! USIM2 USB interrupt endpoint number */
|
||||
#define SIMTRACE_CARDEM_USB_EP_USIM2_INT 3
|
||||
|
||||
/*! Maximum number of endpoints */
|
||||
#define BOARD_USB_NUMENDPOINTS 6
|
Loading…
Reference in New Issue