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 I656a1a38cbb5b1f3a9145d2869d3b4d0adefcae3changes/09/16609/4
parent
0fd77a5790
commit
fd5dafc2a2
@ -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