71 Commits

Author SHA1 Message Date
Kévin Redon
f48aac560c sniffing: decrease USB IRQ prioprity to prevent USART overrun
Change-Id: I870a0aa8e251bbb53249c54bfcaa45de5b5a9486

Handling the USB message queue is done in an ISR and take quite some time.
This can cause a USART/SIM sniffing buffer overrun, resulting in data loss.
By setting the USB IRQ lower than the USART IRQ, the USB ISR can be
interrupted (for short) and no data gets lost.
2018-07-03 16:18:00 +02:00
Kévin Redon
d28d3fc4c0 sniffing: fix procedure byte handling and make TPDU parsing for strict
Change-Id: If991152f11c4b864ab1386f21dc13c335e6b281f
2018-07-03 16:17:00 +02:00
Kévin Redon
50d071fb0e sniffer: also send incomplete (e.g. timeout) data (PPS/ATR/TPDU)
Change-Id: Ib070aca181042b477f1ffec48d63dc56c1e4609a
2018-07-03 16:15:58 +02:00
Kévin Redon
36be182ea2 sniffing: move conversion convertion and flag processing from ISR to main loop to keep ISR fast and focus on data capture
Change-Id: Ieefa8a5f81dbcc12c1ad3059660dbffa0c1a4961
2018-07-03 16:10:04 +02:00
Kévin Redon
bdb0795e61 buffer: increase buffer size to 512 to cope with fast and long TPDUs
Change-Id: I194c90cf09306a982d80c5bf1222397af6e658a9
2018-07-03 16:03:17 +02:00
Kévin Redon
b65e4b6823 console: drop data to be send when buffer is already full
Change-Id: Ia625b09eb30bb7b43edd3989f697d8ef33200f28

don't wait for space to be available in the buffer since since would
prevent from processing non-console (e.g. debug) more important data
2018-07-03 15:59:57 +02:00
Kévin Redon
05cc8bd36a sniffer: display F and D values frim PPS
Change-Id: I3641dcb6c24695a6d3dd3a1ee4333f56a07c99f0
2018-07-03 15:57:03 +02:00
Kévin Redon
de6e3488a0 Merge branch 'kredon/simtrace' of ssh://gerrit.osmocom.org:29418/simtrace2 into kredon/simtrace
Change-Id: Id868520d6603f2bcb79a0aaaf6413dc83938524b
2018-07-01 19:02:40 +02:00
Kévin Redon
f6c2f4def3 host USB: add host application to receive and display USB sniffing messages sent by firmware
Change-Id: Idefbf21e0bbd2a1e3647fe9aebaf88d1b62dae2d
2018-07-01 18:33:28 +02:00
Kévin Redon
f9f1261c18 sniffer USB: implement USB communication and send parsed messages
Change-Id: Ice7817480705f2124b08c1ff9a8826558b6d8b2b
2018-07-01 18:33:28 +02:00
Kévin Redon
310ad81bad USB device: add USB message structure for sniffer communication
Change-Id: Id2c6f32ade2fec9b9ef91bd8c5e1fd195f2d7351
2018-07-01 18:33:28 +02:00
Kévin Redon
1c84e5e312 host USB: use central SIMtrace USB ID definition header
Change-Id: Id18e64fba0a2c308a8aef7d3865200bf0237cae9
2018-07-01 18:33:28 +02:00
Kévin Redon
c06b1d6f7c host usb_util fix: used provided class, sub-class, and interfave when finding matching interfaces
Change-Id: Ibc06e751e6ca0f9e9a40d82c4eeddfb975240f91
2018-07-01 18:33:28 +02:00
Kévin Redon
0c9079f1ae USB: add central file to define USB IDs, classes, and endpoints
Change-Id: Iba81f32a92c68a973e8e7adbc4c2a1064ba5290f
2018-07-01 18:33:28 +02:00
Kévin Redon
cb700ef087 reintroduce adc2uv used in boardver_adc.c and mode_cardemu.c
Change-Id: I52e3919adfd1d888eb130b5ec9298315c4e507c9
2018-07-01 18:33:28 +02:00
Kévin Redon
4635c71c06 minor: fix typos in comment
Change-Id: I01b49e047a586dff449d4e134751108e391a8822
2018-07-01 18:33:28 +02:00
Kévin Redon
6123460055 sniff: add WT timeout detection using USART timeout (TC is not required)
Change-Id: I4ec6e812e7e1eb91005027d2e864fc315550d79c
2018-07-01 18:33:28 +02:00
Kévin Redon
15a3384e9a sniff: add TPDU parsing (TPDUs become APDUs on the upper layer)
Change-Id: I09d050d95bd2ab140fe6b4926a37278eb08cc347
2018-07-01 18:33:28 +02:00
Kévin Redon
f40c10d2f2 sniff: print parsed ATR and PPS; use red LED to show main application is running; use green LED to indicate activity (message parsed)
Change-Id: I8e906bdbf2c91e608757ae442dfb241f981b8f1e
2018-07-01 18:33:28 +02:00
Kévin Redon
8fd88b8a59 LED: add short LED pulse blinking pattern
Change-Id: I0fdc2f902a3b92da6aa9b9c8500abae8a2f79447
2018-07-01 18:33:28 +02:00
Kévin Redon
10553e7f0c update_fidi: remove debug output since this function is called in time critical ISR
Change-Id: I08f407d407a18dae3f360ddc64769ddfaeb5b559
2018-07-01 18:33:28 +02:00
Kévin Redon
833a540efa DFU: switch green LED on to indicate DFU mode, and red LED to indicate flashing activity
Change-Id: I8e34fd869ed94ad122d6a17f5a432f5a09b820bb
2018-07-01 18:33:28 +02:00
Kévin Redon
23d7306ef0 board: fix LED pin definition
Change-Id: Ia6c80c0268dec708845e1dad281caaa42027f9db
2018-07-01 18:33:28 +02:00
Kévin Redon
4646e04d1f DFU: remove force bootloader button debug message since the console is output message is not initialized yet
Change-Id: Ibea0105929a8dc38b43dacd9d1e576d7b51d0c6a
2018-07-01 18:33:28 +02:00
Kévin Redon
216a2149e1 sniffer: use ISR to store sniffed data in buffer, add ATR and PPS parsing, and PPS related FiDi update 2018-07-01 18:33:28 +02:00
Kévin Redon
13f720b650 trace: increase watchdog for 500 to 2000 ms to provide more time handling buffered data 2018-07-01 18:33:28 +02:00
Kévin Redon
ae1ce57d4c ISO7816: change update_fidi to use provided USART, and disable write protection for USART register if required 2018-07-01 18:33:28 +02:00
Kévin Redon
5dce338c6b SIMtrace: enable interrupt on edge dection for SIM_RST pin to reset the sniffer ISO state 2018-07-01 18:33:28 +02:00
Kévin Redon
ad6e7eff00 SIMtrace: fix default SIM_RST pin state to allow phone controlled reset 2018-07-01 18:33:28 +02:00
Kévin Redon
5b63e437bc SIMtrace: only enable main sniffing mode on SIMtrace board 2018-07-01 18:33:28 +02:00
Kévin Redon
915f1636b0 sniffer: add state definitions, improve IRQ handling, update pins configuration 2018-07-01 18:33:28 +02:00
Kévin Redon
04a63b386e simtrace: add support for sniffing on both USART 2018-07-01 18:33:28 +02:00
Kévin Redon
b88c73bcfd board: comment USART definitions and add corresponding IRQ numbers 2018-07-01 18:33:28 +02:00
Kévin Redon
1225e41aad simtrace: add dedicated power pins configuration for sniffing 2018-07-01 18:33:28 +02:00
Kévin Redon
7ddf46ce1c sniff: use USART 0 instead of USART 1
Use USART 0 connected to the SIM card side to sniff the communication.
The card side can also measure ETU times.
Do proper pin initialization.
This code can already capture the ATR communication between phone and card.
2018-07-01 18:33:28 +02:00
Kévin Redon
5a7c848b43 SIMtrace board: comment and fix pin definition 2018-07-01 18:33:28 +02:00
Kévin Redon
aa70887ce0 sniff mode: handle USART 1 RX interrupt to show sniffer data 2018-07-01 18:33:28 +02:00
Kévin Redon
baff8d2c22 add more USB configuration checks and error messages 2018-07-01 18:33:28 +02:00
Kévin Redon
7bcbae3ad9 enable (empty) sniffer support for SIMtrace board 2018-07-01 18:33:28 +02:00
Kévin Redon
33d62aa17a copy working cardem app to trace
because the applications share the board capabilities defined in
libboard/*/include/board.h and USB configurations are enabled according
to the previously defined capabilities in libcommon/source.usb.c, all
applications actually offer the same functions.
thus creating the trace application is only mainly a cosmetic change, as the
sniffer function will also be present and enabled in the cardem application.
2018-07-01 18:33:28 +02:00
Kévin Redon
e4cd52c2e3 fix: remove unused code
adc2uv is not used in boardver_adc.c.
a FIXME comment says it should be shared with mode_cardemu.c.
the exact same code is already available in mode_cardemu.c
2018-07-01 18:33:28 +02:00
Kévin Redon
a484b02271 sniffer: use ISR to store sniffed data in buffer, add ATR and PPS parsing, and PPS related FiDi update 2018-06-25 16:00:33 +02:00
Kévin Redon
8643420daa trace: increase watchdog for 500 to 2000 ms to provide more time handling buffered data 2018-06-25 15:57:44 +02:00
Kévin Redon
0aafbac7eb ring buffer: increase buffer size from 128 to 256 to cope with large debug output 2018-06-25 15:56:33 +02:00
Kévin Redon
67e181fb15 console: use buffer and interrupts instead of busy loops for UART debug output 2018-06-25 15:55:33 +02:00
Kévin Redon
2bac56494f ISO7816: change update_fidi to use provided USART, and disable write protection for USART register if required 2018-06-25 15:53:19 +02:00
Kévin Redon
f908f659fc SIMtrace: enable interrupt on edge dection for SIM_RST pin to reset the sniffer ISO state 2018-06-25 15:49:28 +02:00
Kévin Redon
42af4949a7 SIMtrace: fix default SIM_RST pin state to allow phone controlled reset 2018-06-24 11:31:36 +02:00
Kévin Redon
4814b15bbf SIMtrace: only enable main sniffing mode on SIMtrace board 2018-06-24 11:30:31 +02:00
Kévin Redon
78a8ab71e1 DFU: fix typo in USB strings 2018-06-24 11:27:09 +02:00
Kévin Redon
6b38297e20 DFU: incread watchdog timeout and restart watchdog before writing in flash to prevent the watchdog to trigger while flashing 2018-06-17 22:36:44 +02:00
Kévin Redon
3f8a4c28e8 DFU: only boot the application if it has a valid start 2018-06-17 22:35:17 +02:00
Kévin Redon
41d01b9d54 DFU: uncomment print message when DFU is forced using the button 2018-06-17 22:34:47 +02:00
Kévin Redon
88b2b077ef DFU: unlock the flash before writing, verify written data, and relock it 2018-06-17 22:33:29 +02:00
Kévin Redon
9a921ac630 USB: implement USB reset by setting the on-board pull-up on D+ low 2018-06-17 22:31:21 +02:00
Kévin Redon
2ab8f8e3fd sniffer: add state definitions, improve IRQ handling, update pins configuration 2018-06-11 13:46:35 +02:00
Kévin Redon
a34471d923 simtrace: add support for sniffing on both USART 2018-06-11 13:45:16 +02:00
Kévin Redon
762276e271 board: comment USART definitions and add corresponding IRQ numbers 2018-06-11 13:43:27 +02:00
Kévin Redon
2d972f5910 simtrace: add dedicated power pins configuration for sniffing 2018-06-11 13:42:23 +02:00
Kévin Redon
d0b4a9da81 sniff: use USART 0 instead of USART 1
Use USART 0 connected to the SIM card side to sniff the communication.
The card side can also measure ETU times.
Do proper pin initialization.
This code can already capture the ATR communication between phone and card.
2018-06-07 18:56:47 +02:00
Kévin Redon
7f4f8983dd USBD: send empty packet when non-existing descriptor string is requested
Sometimes descriptor string 0xee is requested.
This is a mechanism used by Microsoft Windows to further identify the USB device.
Instead of stalling, as is the original code, leading to an USB reset, we send an empty packet.
I am not sure if sending an empty string would be better, but an empty packet seems sufficient.
2018-06-06 17:03:24 +02:00
Kévin Redon
86ea4faef6 SIMtrace board: comment and fix pin definition 2018-06-06 17:02:33 +02:00
Kévin Redon
a1f198276d sniff mode: handle USART 1 RX interrupt to show sniffer data 2018-06-06 16:13:48 +02:00
Kévin Redon
b53ab5b4ef add more USB configuration checks and error messages 2018-06-04 16:30:48 +02:00
Kévin Redon
38a467e630 enable (empty) sniffer support for SIMtrace board 2018-06-04 16:30:01 +02:00
Kévin Redon
7b51f72e83 copy working cardem app to trace
because the applications share the board capabilities defined in
libboard/*/include/board.h and USB configurations are enabled according
to the previously defined capabilities in libcommon/source.usb.c, all
applications actually offer the same functions.
thus creating the trace application is only mainly a cosmetic change, as the
sniffer function will also be present and enabled in the cardem application.
2018-06-04 16:21:34 +02:00
Kévin Redon
f79ae1c54a dfu: fix address destination check and add stack overwrite check in USBDFU_handle_dnload
During DFU download the destination start address is checked to not exceed the
RAM or flash end address, but it is also necessary to check if the end of the
data to be downloaded is also within the allowed range.
When downloading to RAM it is also necessary to check if the data to be
downloaded does not overwrite (i.e. corrupt) the stack.
2018-06-01 11:02:56 +02:00
Kévin Redon
de2d03ca22 README: rewrite to better explain environment variables and point to the wiki for flashing 2018-05-21 19:35:56 +02:00
Kévin Redon
fe72bf11fd fix pointer casting warning
fixes following warning:
libboard/common/source/board_cstartup_gnu.c:137:11: warning: assignment to 'void (*)(void)' from 'unsigned int' makes pointer from integer without a cast [-Wint-conversion]
  appReset = pSrc[1];
2018-05-21 19:34:01 +02:00
Kévin Redon
0471d2a390 fix: initialize uninitialized variable in USBDFU_DFU_RequestHandler 2018-05-21 18:52:06 +02:00
Kévin Redon
5be1b612f7 fix: remove unused code
adc2uv is not used in boardver_adc.c.
a FIXME comment says it should be shared with mode_cardemu.c.
the exact same code is already available in mode_cardemu.c
2018-05-21 17:51:34 +02:00
31 changed files with 2139 additions and 340 deletions

View File

@@ -13,6 +13,12 @@ unsigned int g_unique_id[4];
/* remember if the watchdog has been configured in the main loop so we can kick it in the ISR */ /* remember if the watchdog has been configured in the main loop so we can kick it in the ISR */
static bool watchdog_configured = false; static bool watchdog_configured = false;
/* There is not enough space in the 16 KiB DFU bootloader to include led.h functions */
#ifdef PINS_LEDS
/** LED pin configurations */
static const Pin pinsLeds[] = { PINS_LEDS } ;
#endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
* Callbacks * Callbacks
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
@@ -42,53 +48,63 @@ int USBDFU_handle_dnload(uint8_t altif, unsigned int offset,
printf("dnload(altif=%u, offset=%u, len=%u)\n\r", altif, offset, len); printf("dnload(altif=%u, offset=%u, len=%u)\n\r", altif, offset, len);
#ifdef PINS_LEDS
PIO_Clear(&pinsLeds[LED_NUM_RED]);
#endif
switch (altif) { switch (altif) {
case ALTIF_RAM: case ALTIF_RAM:
addr = RAM_ADDR(offset); addr = RAM_ADDR(offset);
if (addr < IRAM_ADDR || addr + len >= IRAM_ADDR + IRAM_SIZE || addr + len >= stack_addr) { if (addr < IRAM_ADDR || addr + len >= IRAM_ADDR + IRAM_SIZE || addr + len >= stack_addr) {
g_dfu->state = DFU_STATE_dfuERROR; g_dfu->state = DFU_STATE_dfuERROR;
g_dfu->status = DFU_STATUS_errADDRESS; g_dfu->status = DFU_STATUS_errADDRESS;
return DFU_RET_STALL; rc = DFU_RET_STALL;
break;
} }
memcpy((void *)addr, data, len); memcpy((void *)addr, data, len);
return DFU_RET_ZLP; rc = DFU_RET_ZLP;
break;
case ALTIF_FLASH: case ALTIF_FLASH:
addr = FLASH_ADDR(offset); addr = FLASH_ADDR(offset);
if (addr < IFLASH_ADDR || addr + len >= IFLASH_ADDR + IFLASH_SIZE) { if (addr < IFLASH_ADDR || addr + len >= IFLASH_ADDR + IFLASH_SIZE) {
g_dfu->state = DFU_STATE_dfuERROR; g_dfu->state = DFU_STATE_dfuERROR;
g_dfu->status = DFU_STATUS_errADDRESS; g_dfu->status = DFU_STATUS_errADDRESS;
return DFU_RET_STALL; rc = DFU_RET_STALL;
break;
} }
rc = FLASHD_Unlock(addr, addr + len, 0, 0); rc = FLASHD_Unlock(addr, addr + len, 0, 0);
if (rc != 0) { if (rc != 0) {
TRACE_ERROR("DFU download flash unlock failed\n\r"); TRACE_ERROR("DFU download flash unlock failed\n\r");
/* FIXME: set error codes */ rc = DFU_RET_STALL;
return DFU_RET_STALL; break;
} }
rc = FLASHD_Write(addr, data, len); rc = FLASHD_Write(addr, data, len);
if (rc != 0) { if (rc != 0) {
TRACE_ERROR("DFU download flash erase failed\n\r"); TRACE_ERROR("DFU download flash erase failed\n\r");
/* FIXME: set error codes */ rc = DFU_RET_STALL;
return DFU_RET_STALL; break;
} }
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
if (((uint8_t*)addr)[i]!=data[i]) { if (((uint8_t*)addr)[i]!=data[i]) {
TRACE_ERROR("DFU download flash data written not correct\n\r"); TRACE_ERROR("DFU download flash data written not correct\n\r");
return DFU_RET_STALL; rc = DFU_RET_STALL;
break;
} }
} }
rc = FLASHD_Lock(addr, addr + len, 0, 0); rc = DFU_RET_ZLP;
if (rc != 0) { break;
TRACE_ERROR("DFU download flash lock failed\n\r");
/* FIXME: set error codes */
return DFU_RET_STALL;
}
return DFU_RET_ZLP;
default: default:
/* FIXME: set error codes */ /* FIXME: set error codes */
TRACE_ERROR("DFU download for unknown AltIf %d\n\r", altif); TRACE_ERROR("DFU download for unknown AltIf %d\n\r", altif);
return DFU_RET_STALL; rc = DFU_RET_STALL;
break;
} }
#ifdef PINS_LEDS
PIO_Set(&pinsLeds[LED_NUM_RED]);
#endif
return rc;
} }
/* incoming call-back: Host has requested to read back 'req_len' bytes /* incoming call-back: Host has requested to read back 'req_len' bytes
@@ -187,17 +203,22 @@ extern int main(void)
unsigned int i = 0; unsigned int i = 0;
uint32_t reset_cause = (RSTC->RSTC_SR & RSTC_SR_RSTTYP_Msk) >> RSTC_SR_RSTTYP_Pos; uint32_t reset_cause = (RSTC->RSTC_SR & RSTC_SR_RSTTYP_Msk) >> RSTC_SR_RSTTYP_Pos;
#if 0
led_init();
led_blink(LED_GREEN, BLINK_3O_30F);
led_blink(LED_RED, BLINK_3O_30F);
#endif
/* Enable watchdog for 2000ms, with no window */ /* Enable watchdog for 2000ms, with no window */
WDT_Enable(WDT, WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT | WDT_Enable(WDT, WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT |
(WDT_GetPeriod(2000) << 16) | WDT_GetPeriod(2000)); (WDT_GetPeriod(2000) << 16) | WDT_GetPeriod(2000));
watchdog_configured = true; watchdog_configured = true;
#ifdef PINS_LEDS
/* Configure LED */
PIO_Configure(pinsLeds, sizeof(pinsLeds));
PIO_Set(&pinsLeds[LED_NUM_RED]);
PIO_Clear(&pinsLeds[LED_NUM_GREEN]);
#endif
/* Enable watchdog for 500ms, with no window */
WDT_Enable(WDT, WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT |
(WDT_GetPeriod(500) << 16) | WDT_GetPeriod(500));
PIO_InitializeInterrupts(0); PIO_InitializeInterrupts(0);
EEFC_ReadUniqueID(g_unique_id); EEFC_ReadUniqueID(g_unique_id);

View File

@@ -0,0 +1,3 @@
C_FILES += $(C_LIBUSB_RT)
C_FILES += card_emu.c cciddriver.c iso7816_4.c iso7816_fidi.c mitm.c mode_cardemu.c mode_ccid.c simtrace_iso7816.c sniffer.c tc_etu.c usb.c

View File

@@ -0,0 +1,268 @@
/*
* (C) 2010-2017 by Harald Welte <hwelte@sysmocom.de>
* (C) 2018 by Kevin Redon <kredon@sysmocom.de>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*------------------------------------------------------------------------------
* Headers
*------------------------------------------------------------------------------*/
#include "board.h"
#include "simtrace.h"
#include "utils.h"
#include "osmocom/core/timer.h"
unsigned int g_unique_id[4];
/*------------------------------------------------------------------------------
* Internal variables
*------------------------------------------------------------------------------*/
typedef struct {
/* static initialization, called whether or not the usb config is active */
void (*configure) (void);
/* initialization function after the config was selected */
void (*init) (void);
/* de-initialization before selecting new config */
void (*exit) (void);
/* main loop content for given configuration */
void (*run) (void);
/* Interrupt handler for USART0 */
void (*usart0_irq) (void);
/* Interrupt handler for USART1 */
void (*usart1_irq) (void);
} conf_func;
static const conf_func config_func_ptrs[] = {
/* array slot 0 is empty, usb configs start at 1 */
#ifdef HAVE_SNIFFER
[CFG_NUM_SNIFF] = {
.configure = Sniffer_configure,
.init = Sniffer_init,
.exit = Sniffer_exit,
.run = Sniffer_run,
.usart0_irq = Sniffer_usart0_irq,
.usart1_irq = Sniffer_usart1_irq,
},
#endif
#ifdef HAVE_CCID
[CFG_NUM_CCID] = {
.configure = CCID_configure,
.init = CCID_init,
.exit = CCID_exit,
.run = CCID_run,
},
#endif
#ifdef HAVE_CARDEM
[CFG_NUM_PHONE] = {
.configure = mode_cardemu_configure,
.init = mode_cardemu_init,
.exit = mode_cardemu_exit,
.run = mode_cardemu_run,
.usart0_irq = mode_cardemu_usart0_irq,
.usart1_irq = mode_cardemu_usart1_irq,
},
#endif
#ifdef HAVE_MITM
[CFG_NUM_MITM] = {
.configure = MITM_configure,
.init = MITM_init,
.exit = MITM_exit,
.run = MITM_run,
},
#endif
};
/*------------------------------------------------------------------------------
* Internal variables
*------------------------------------------------------------------------------*/
#if defined(HAVE_SNIFFER)
static volatile enum confNum simtrace_config = CFG_NUM_SNIFF;
#elif defined(HAVE_CARDEM)
static volatile enum confNum simtrace_config = CFG_NUM_PHONE;
#elif defined(HAVE_CCID)
static volatile enum confNum simtrace_config = CFG_NUM_CCID;
#endif
/*----------------------------------------------------------------------------
* Callbacks
*----------------------------------------------------------------------------*/
void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
{
TRACE_INFO_WP("cfgChanged%d ", cfgnum);
if (cfgnum >= sizeof(config_func_ptrs)/sizeof(config_func_ptrs[0])) {
TRACE_FATAL_WP("no functions defined for configuration %d\n\r", cfgnum);
}
simtrace_config = cfgnum;
}
void USART1_IrqHandler(void)
{
if (config_func_ptrs[simtrace_config].usart1_irq)
config_func_ptrs[simtrace_config].usart1_irq();
}
void USART0_IrqHandler(void)
{
if (config_func_ptrs[simtrace_config].usart0_irq)
config_func_ptrs[simtrace_config].usart0_irq();
}
/* returns '1' in case we should break any endless loop */
static void check_exec_dbg_cmd(void)
{
int ch;
if (!UART_IsRxReady())
return;
ch = UART_GetChar();
board_exec_dbg_cmd(ch);
}
/*------------------------------------------------------------------------------
* Main
*------------------------------------------------------------------------------*/
#define MAX_USB_ITER BOARD_MCK/72 // This should be around a second
extern int main(void)
{
uint8_t isUsbConnected = 0;
enum confNum last_simtrace_config = simtrace_config;
unsigned int i = 0;
/* Configure LED output (red = on, green = activity */
led_init();
led_blink(LED_RED, BLINK_ALWAYS_ON);
led_blink(LED_GREEN, BLINK_ALWAYS_OFF);
/* Enable watchdog for 2000 ms, with no window */
WDT_Enable(WDT, WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT |
(WDT_GetPeriod(2000) << 16) | WDT_GetPeriod(2000));
PIO_InitializeInterrupts(0);
EEFC_ReadUniqueID(g_unique_id);
printf("\n\r\n\r"
"=============================================================================\n\r"
"SIMtrace2 firmware " GIT_VERSION " (C) 2010-2016 by Harald Welte\n\r"
"=============================================================================\n\r");
TRACE_INFO("Chip ID: 0x%08x (Ext 0x%08x)\n\r", CHIPID->CHIPID_CIDR, CHIPID->CHIPID_EXID);
TRACE_INFO("Serial Nr. %08x-%08x-%08x-%08x\n\r",
g_unique_id[0], g_unique_id[1],
g_unique_id[2], g_unique_id[3]);
TRACE_INFO("Reset Cause: 0x%x\n\r", (RSTC->RSTC_SR & RSTC_SR_RSTTYP_Msk) >> RSTC_SR_RSTTYP_Pos);
TRACE_INFO("USB configuration used: %d\n\r", simtrace_config);
board_main_top();
TRACE_INFO("USB init...\n\r");
SIMtrace_USB_Initialize();
TRACE_INFO_WP("USBD_Inited\n\r");
while (USBD_GetState() < USBD_STATE_CONFIGURED) {
WDT_Restart(WDT);
check_exec_dbg_cmd();
#if 0
if (i >= MAX_USB_ITER * 3) {
TRACE_ERROR("Resetting board (USB could "
"not be configured)\n\r");
USBD_Disconnect();
NVIC_SystemReset();
}
#endif
i++;
}
TRACE_INFO("calling configure of all configurations...\n\r");
for (i = 1; i < sizeof(config_func_ptrs) / sizeof(config_func_ptrs[0]); ++i) {
if (config_func_ptrs[i].configure) {
config_func_ptrs[i].configure();
} else {
TRACE_WARNING("no configure function defined for configuration %d\n\r", i);
}
}
TRACE_INFO("cfg %d\n\r", simtrace_config);
TRACE_INFO("calling init of config %u...\n\r", simtrace_config);
if (simtrace_config >= sizeof(config_func_ptrs)/sizeof(config_func_ptrs[0])) {
TRACE_ERROR("no functions defined for configuration %d\n\r", simtrace_config);
} else {
if (config_func_ptrs[simtrace_config].init) {
config_func_ptrs[simtrace_config].init();
} else {
TRACE_ERROR("no init function defined for configuration %d\n\r", simtrace_config);
}
}
last_simtrace_config = simtrace_config;
TRACE_INFO("entering main loop...\n\r");
while (1) {
WDT_Restart(WDT);
#if TRACE_LEVEL >= TRACE_LEVEL_DEBUG
const char rotor[] = { '-', '\\', '|', '/' };
putchar('\b');
putchar(rotor[i++ % ARRAY_SIZE(rotor)]);
#endif
check_exec_dbg_cmd();
osmo_timers_prepare();
osmo_timers_update();
if (USBD_GetState() < USBD_STATE_CONFIGURED) {
if (isUsbConnected) {
isUsbConnected = 0;
}
} else if (isUsbConnected == 0) {
TRACE_INFO("USB is now configured\n\r");
isUsbConnected = 1;
}
if (last_simtrace_config != simtrace_config) {
TRACE_INFO("USB config chg %u -> %u\n\r",
last_simtrace_config, simtrace_config);
if (last_simtrace_config < sizeof(config_func_ptrs)/sizeof(config_func_ptrs[0])) {
if (config_func_ptrs[last_simtrace_config].exit) {
config_func_ptrs[last_simtrace_config].exit();
} else {
TRACE_WARNING("exit not defined for configuration %d\n\r", last_simtrace_config);
}
} else {
TRACE_ERROR("no functions defined for configuration %d\n\r", last_simtrace_config);
}
if (simtrace_config < sizeof(config_func_ptrs)/sizeof(config_func_ptrs[0])) {
if (config_func_ptrs[simtrace_config].init) {
config_func_ptrs[simtrace_config].init();
} else {
TRACE_WARNING("init not defined for configuration %d\n\r", simtrace_config);
}
} else {
TRACE_FATAL("no functions defined for configuration %d\n\r", simtrace_config);
}
last_simtrace_config = simtrace_config;
} else {
if (config_func_ptrs[simtrace_config].run) {
config_func_ptrs[simtrace_config].run();
} else {
TRACE_ERROR("run not defined for configuration %d\n\r", simtrace_config);
}
}
}
}

View File

@@ -0,0 +1,10 @@
sysmocom - s.f.m.c. GmbH
SIMtrace 2 compatible device
SIMtrace Sniffer
SIMtrace CCID
SIMtrace Phone
SIMtrace MITM
CardEmulator Modem 1
CardEmulator Modem 2
CardEmulator Modem 3
CardEmulator Modem 4

View File

@@ -28,7 +28,7 @@ static const USBDeviceDescriptor fsDevice = {
.bDeviceClass = 0, .bDeviceClass = 0,
.bDeviceSubClass = 0, .bDeviceSubClass = 0,
.bDeviceProtocol = 0, .bDeviceProtocol = 0,
.bMaxPacketSize0 = BOARD_USB_ENDPOINTS_MAXPACKETSIZE(0), .bMaxPacketSize0 = USBEndpointDescriptor_MAXCTRLSIZE_FS,
.idVendor = BOARD_USB_VENDOR_ID, .idVendor = BOARD_USB_VENDOR_ID,
.idProduct = BOARD_DFU_USB_PRODUCT_ID, .idProduct = BOARD_DFU_USB_PRODUCT_ID,
.bcdDevice = BOARD_USB_RELEASE, .bcdDevice = BOARD_USB_RELEASE,

View File

@@ -39,8 +39,8 @@
#define BOARD_MCK 48000000 #define BOARD_MCK 48000000
#define PIO_LED_RED PIO_PA17 #define PIO_LED_RED PIO_PA17
#define PIO_LED_GREEN PIO_PA17 #define PIO_LED_GREEN PIO_PA18
#define PIN_LED_RED {PIO_LED_RED, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT} #define PIN_LED_RED {PIO_LED_RED, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
#define PIN_LED_GREEN {PIO_LED_GREEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT} #define PIN_LED_GREEN {PIO_LED_GREEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
@@ -81,10 +81,19 @@
#define BOARD_ISO7816_BASE_USART USART0 #define BOARD_ISO7816_BASE_USART USART0
#define BOARD_ISO7816_ID_USART ID_USART0 #define BOARD_ISO7816_ID_USART ID_USART0
/* USART peripherals for a phone and SIM card setup */
/* USART peripheral connected to the SIM card */
#define USART_SIM USART0 #define USART_SIM USART0
/* ID of USART peripheral connected to the SIM card */
#define ID_USART_SIM ID_USART0 #define ID_USART_SIM ID_USART0
#define USART_PHONE USART1 /* Interrupt request ID of USART peripheral connected to the SIM card */
#define ID_USART_PHONE ID_USART1 #define IRQ_USART_SIM USART0_IRQn
/* USART peripheral connected to the phone */
#define USART_PHONE USART1
/* ID of USART peripheral connected to the phone */
#define ID_USART_PHONE ID_USART1
/* Interrupt request ID of USART peripheral connected to the phone */
#define IRQ_USART_PHONE USART1_IRQn
#define SIM_PWEN PIO_PA5 #define SIM_PWEN PIO_PA5
#define VCC_FWD PIO_PA26 #define VCC_FWD PIO_PA26
@@ -99,21 +108,6 @@
// D+ has external pull-up // D+ has external pull-up
#define BOARD_USB_PULLUP_EXTERNAL #define BOARD_USB_PULLUP_EXTERNAL
#define BOARD_USB_NUMENDPOINTS 8
// FIXME: in all other cases return 0?
#define BOARD_USB_ENDPOINTS_MAXPACKETSIZE(i) (((i == 4) || (i == 5))? 512 : 64)
#define BOARD_USB_ENDPOINTS_BANKS(i) (((i == 0) || (i == 3)) ? 1 : 2)
#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
#define BOARD_USB_DFU #define BOARD_USB_DFU
#define BOARD_DFU_BOOT_SIZE (16 * 1024) #define BOARD_DFU_BOOT_SIZE (16 * 1024)
#define BOARD_DFU_RAM_SIZE (2 * 1024) #define BOARD_DFU_RAM_SIZE (2 * 1024)

View File

@@ -1,3 +1,4 @@
#pragma once #pragma once
uint32_t adc2uv(uint16_t adc);
int get_board_version_adc(void); int get_board_version_adc(void);

View File

@@ -13,9 +13,10 @@ enum led_pattern {
BLINK_3O_30F = 3, BLINK_3O_30F = 3,
BLINK_3O_1F_3O_30F = 4, BLINK_3O_1F_3O_30F = 4,
BLINK_3O_1F_3O_1F_3O_30F= 5, BLINK_3O_1F_3O_1F_3O_30F= 5,
BLINK_200O_F = 6, BLINK_2O_F = 6,
BLINK_600O_F = 7, BLINK_200O_F = 7,
BLINK_CUSTOM = 8, BLINK_600O_F = 8,
BLINK_CUSTOM = 9,
_NUM_LED_BLINK _NUM_LED_BLINK
}; };

View File

@@ -1,9 +1,8 @@
#include "board.h" #include "board.h"
#include "boardver_adc.h" #include "boardver_adc.h"
/* FIXME: share this with mode_cardemu.c */ #define UV_PER_LSB ((3300 * 1000) / 4096)
#define UV_PER_LSB ((3300 * 1000) / 4096) uint32_t adc2uv(uint16_t adc)
static uint32_t adc2uv(uint16_t adc)
{ {
uint32_t uv = (uint32_t) adc * UV_PER_LSB; uint32_t uv = (uint32_t) adc * UV_PER_LSB;
return uv; return uv;

View File

@@ -16,9 +16,9 @@ static void led_set(enum led led, int on)
ASSERT(led < PIO_LISTSIZE(pinsLeds)); ASSERT(led < PIO_LISTSIZE(pinsLeds));
if (on) if (on)
PIO_Set(&pinsLeds[led]);
else
PIO_Clear(&pinsLeds[led]); PIO_Clear(&pinsLeds[led]);
else
PIO_Set(&pinsLeds[led]);
} }
/* LED blinking code */ /* LED blinking code */
@@ -27,7 +27,7 @@ static void led_set(enum led led, int on)
struct blink_state { struct blink_state {
/* duration of the state in ms */ /* duration of the state in ms */
uint16_t duration; uint16_t duration;
/* bringhtness of LED during the state */ /* brightness of LED during the state */
uint8_t on; uint8_t on;
} __attribute__((packed)); } __attribute__((packed));
@@ -54,6 +54,9 @@ static const struct blink_state bs_3on_1off_3on_30off[] = {
static const struct blink_state bs_3on_1off_3on_1off_3on_30off[] = { static const struct blink_state bs_3on_1off_3on_1off_3on_30off[] = {
{ 300, 1 }, { 100, 0 }, { 300, 1 }, { 100, 0 }, { 300, 1 }, { 3000, 0 } { 300, 1 }, { 100, 0 }, { 300, 1 }, { 100, 0 }, { 300, 1 }, { 3000, 0 }
}; };
static const struct blink_state bs_2on_off[] = {
{ 200, 1 }, { 0, 0 },
};
static const struct blink_state bs_200on_off[] = { static const struct blink_state bs_200on_off[] = {
{ 20000, 1 }, { 0, 0 }, { 20000, 1 }, { 0, 0 },
}; };
@@ -94,6 +97,10 @@ static const struct blink_pattern patterns[] = {
.states = bs_3on_1off_3on_1off_3on_30off, .states = bs_3on_1off_3on_1off_3on_30off,
.size = ARRAY_SIZE(bs_3on_1off_3on_1off_3on_30off), .size = ARRAY_SIZE(bs_3on_1off_3on_1off_3on_30off),
}, },
[BLINK_2O_F] = {
.states = bs_2on_off,
.size = ARRAY_SIZE(bs_2on_off),
},
[BLINK_200O_F] = { [BLINK_200O_F] = {
.states = bs_200on_off, .states = bs_200on_off,
.size = ARRAY_SIZE(bs_200on_off), .size = ARRAY_SIZE(bs_200on_off),
@@ -158,16 +165,16 @@ static void blink_tmr_cb(void *data)
} }
static struct led_state led_state[] = { static struct led_state led_state[] = {
[LED_GREEN] = {
.led = LED_GREEN,
.timer.cb = blink_tmr_cb,
.timer.data = &led_state[LED_GREEN],
},
[LED_RED] = { [LED_RED] = {
.led = LED_RED, .led = LED_RED,
.timer.cb = blink_tmr_cb, .timer.cb = blink_tmr_cb,
.timer.data = &led_state[LED_RED], .timer.data = &led_state[LED_RED],
}, },
[LED_GREEN] = {
.led = LED_GREEN,
.timer.cb = blink_tmr_cb,
.timer.data = &led_state[LED_GREEN],
},
}; };
#endif /* PINS_LEDS */ #endif /* PINS_LEDS */

View File

@@ -133,17 +133,15 @@ extern void UART_PutChar( uint8_t c )
UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK); UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
} }
/* Wait until there is space in the buffer */ /* Only store input if buffer is not full, else drop it */
while (rbuf_is_full(&uart_tx_buffer)) { bool trigger_isr = false;
if (pUart->UART_SR & UART_SR_TXEMPTY) { if (rbuf_is_empty(&uart_tx_buffer)) {
pUart->UART_IER = UART_IER_TXRDY; trigger_isr = true;
CONSOLE_ISR();
}
} }
if (!rbuf_is_full(&uart_tx_buffer)) {
/* Put character into buffer */ rbuf_write(&uart_tx_buffer, c);
rbuf_write(&uart_tx_buffer, c); }
if (pUart->UART_SR & UART_SR_TXEMPTY) { if (trigger_isr) {
pUart->UART_IER = UART_IER_TXRDY; pUart->UART_IER = UART_IER_TXRDY;
CONSOLE_ISR(); CONSOLE_ISR();
} }

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "board_common.h" #include "board_common.h"
#include "simtrace_usb.h"
/** Name of the board */ /** Name of the board */
#define BOARD_NAME "OWHW" #define BOARD_NAME "OWHW"

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "board_common.h" #include "board_common.h"
#include "simtrace_usb.h"
#define LED_USIM1 LED_GREEN #define LED_USIM1 LED_GREEN
#define LED_USIM2 LED_RED #define LED_USIM2 LED_RED

View File

@@ -1,88 +1,121 @@
#pragma once #pragma once
#include "board_common.h" #include "board_common.h"
#include "simtrace_usb.h"
/** Name of the board */ /* Name of the board */
#define BOARD_NAME "SAM3S-SIMTRACE" #define BOARD_NAME "SAM3S-SIMTRACE"
/** Board definition */ /* Board definition */
#define simtrace #define simtrace
/* Board main oscillator frequency (in Hz) */
#define BOARD_MAINOSC 18432000 #define BOARD_MAINOSC 18432000
/** Phone (SIM card emulator)/CCID Reader/MITM configuration **/ /** Pin configuration **/
/* Normally the communication lines between phone and SIM card are disconnected */ /* Button to force bootloader start (shorted to ground when pressed */
// Disconnect SIM card I/O, VPP line from the phone lines #define PIN_BOOTLOADER_SW {PIO_PA31, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
// FIXME: Per default pins are input, therefore high-impedance, therefore they don not activate the bus switch, right? /* Enable powering the card using the second 3.3 V output of the LDO (active high) */
#define PIN_SC_SW_DEFAULT {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT} #define SIM_PWEN_PIN {SIM_PWEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
// Disconnect SIM card RST, CLK line from the phone lines /* Enable powering the SIM card */
#define PIN_IO_SW_DEFAULT {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT} #define PWR_PINS SIM_PWEN_PIN
#define PINS_BUS_DEFAULT PIN_SC_SW_DEFAULT, PIN_IO_SW_DEFAULT /* Card presence pin */
#define SW_SIM PIO_PA8
/* Pull card presence pin high (shorted to ground in card slot when card is present) */
#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE }
/** Smart card connection **/
/* Card RST reset signal input (active low; RST_SIM in schematic) */
#define PIN_SIM_RST {PIO_PA7, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/* Card I/O data signal input/output (I/O_SIM in schematic) */
#define PIN_SIM_IO {PIO_PA6A_TXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/* Card CLK clock input (CLK_SIM in schematic) */
#define PIN_SIM_CLK {PIO_PA2B_SCK0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
/* Pin to measure card I/O timing (to start measuring the ETU on I/O activity; connected I/O_SIM in schematic) */
#define PIN_SIM_IO_INPUT {PIO_PA1B_TIOB0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
/* Pin used as clock input (to measure the ETU duration; connected to CLK_SIM in schematic) */
#define PIN_SIM_CLK_INPUT {PIO_PA4B_TCLK0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
/* Pins used to measure ETU timing (using timer counter) */
#define PINS_TC PIN_SIM_IO_INPUT, PIN_SIM_CLK_INPUT
/** Phone connection **/
/* Phone USIM slot 1 VCC pin (VCC_PHONE in schematic) */
#define PIN_USIM1_VCC {PIO_PA25, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
/* Phone USIM slot 1 RST pin (active low; RST_PHONE in schematic) */
#define PIN_USIM1_nRST {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_IT_RISE_EDGE | PIO_DEGLITCH }
/* Phone I/O data signal input/output (I/O_PHONE in schematic) */
#define PIN_PHONE_IO {PIO_PA22A_TXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/* Phone CLK clock input (CLK_PHONE in schematic) */
#define PIN_PHONE_CLK {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/* Pin used for phone USIM slot 1 communication */
#define PINS_USIM1 PIN_PHONE_IO, PIN_PHONE_CLK, PIN_PHONE_CLK_INPUT, PIN_USIM1_VCC, PIN_PHONE_IO_INPUT, PIN_USIM1_nRST
/* Phone I/O data signal input/output (unused USART RX input; connected to I/O_PHONE in schematic) */
#define PIN_PHONE_IO_INPUT {PIO_PA21A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/* Pin used as clock input (to measure the ETU duration; connected to CLK_PHONE in schematic) */
#define PIN_PHONE_CLK_INPUT {PIO_PA29B_TCLK2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
/** Default pin configuration **/
/* Disconnect VPP, CLK, and RST lines between card and phone using bus switch (high sets bus switch to high-impedance) */
#define PIN_SC_SW_DEFAULT {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
/* Disconnect I/O line between card and phone using bus switch (high sets bus switch to high-impedance) */
#define PIN_IO_SW_DEFAULT {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
/* Disconnect all lines (VPP, CLK, RST, and I/O) between card and phone */
#define PINS_BUS_DEFAULT PIN_SC_SW_DEFAULT, PIN_IO_SW_DEFAULT
/** Sniffer configuration **/ /** Sniffer configuration **/
// Connect VPP, CLK and RST lines from smartcard to the phone /* Connect VPP, CLK, and RST lines between card and phone using bus switch (low connects signals on bus switch) */
#define PIN_SC_SW_SNIFF {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT} #define PIN_SC_SW_SNIFF {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/* Connect I/O line between card and phone using bus switch (low connects signals on bus switch) */
#define PIN_IO_SW_SNIFF {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT} #define PIN_IO_SW_SNIFF {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/* Connect all lines (VPP, CLK, RST, and I/O) between card and phone */
#define PINS_BUS_SNIFF PIN_SC_SW_SNIFF, PIN_IO_SW_SNIFF #define PINS_BUS_SNIFF PIN_SC_SW_SNIFF, PIN_IO_SW_SNIFF
/* Card RST reset signal input (use as input since the phone will drive it) */
#define PIN_SIM_RST_SNIFF {PIO_PA7, PIOA, ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_IT_EDGE}
/* Pins used to sniff phone-card communication */
#define PINS_SIM_SNIFF PIN_SIM_IO, PIN_SIM_CLK, PIN_SIM_RST_SNIFF
/* Disable power converter 4.5-6V to 3.3V (active high) */
#define PIN_SIM_PWEN_SNIFF {SIM_PWEN, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/* Enable power switch to forward VCC_PHONE to VCC_SIM (active high) */
#define PIN_VCC_FWD_SNIFF {VCC_FWD, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
/* Use phone VCC to power card */
#define PINS_PWR_SNIFF PIN_SIM_PWEN_SNIFF, PIN_VCC_FWD_SNIFF
#define PINS_SIM_SNIFF_SIM PIN_PHONE_IO, PIN_PHONE_CLK /** CCID configuration */
/* Card RST reset signal input (active low; RST_SIM in schematic) */
#define PIN_ISO7816_RSTMC {PIO_PA7, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/* ISO7816-communication related pins */
#define PINS_ISO7816 PIN_SIM_IO, PIN_SIM_CLK, PIN_ISO7816_RSTMC // SIM_PWEN_PIN, PIN_SIM_IO2, PIN_SIM_CLK2
#define SIM_PWEN_PIN {PIO_PA5, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT} /** External SPI flash interface **/
/* SPI MISO pin definition */
#define PWR_PINS \ #define PIN_SPI_MISO {PIO_PA12A_MISO, PIOA, PIOA, PIO_PERIPH_A, PIO_PULLUP}
/* Enable power converter 4.5-6V to 3.3V; low: off */ \ /* SPI MOSI pin definition */
{SIM_PWEN, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}, \ #define PIN_SPI_MOSI {PIO_PA13A_MOSI, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/* Enable second power converter: VCC_PHONE to VCC_SIM; high: on */ \ /* SPI SCK pin definition */
{VCC_FWD, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT} #define PIN_SPI_SCK {PIO_PA14A_SPCK, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/* SPI pins definition. Contains MISO, MOSI & SCK */
#define SW_SIM PIO_PA8 #define PINS_SPI PIN_SPI_MISO, PIN_SPI_MOSI, PIN_SPI_SCK
#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE } /* SPI chip select 0 pin definition */
//#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOB, ID_PIOB, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_EDGE} #define PIN_SPI_NPCS0 {PIO_PA11A_NPCS0, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/* SPI flash write protect pin (active low, pulled low) */
/// PIN used for resetting the smartcard #define PIN_SPI_WP {PA15, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
// FIXME: Card is resetted with pin set to 0 --> PIO_OUTPUT_1 as default is right?
#define PIN_ISO7816_RSTMC {PIO_PA7, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/// Pins used for connect the smartcard
#define PIN_SIM_IO_INPUT {PIO_PA1, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
#define PIN_SIM_IO {PIO_PA6, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_SIM_CLK {PIO_PA2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
#define PIN_SIM_CLK_INPUT {PIO_PA4, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
//#define PINS_ISO7816 PIN_USART1_TXD, PIN_USART1_SCK, PIN_ISO7816_RSTMC
#define PINS_ISO7816 PIN_SIM_IO, PIN_SIM_CLK, PIN_ISO7816_RSTMC // SIM_PWEN_PIN, PIN_SIM_IO2, PIN_SIM_CLK2
#define PINS_TC PIN_SIM_IO_INPUT, PIN_SIM_CLK_INPUT
#define PIN_USIM1_VCC {PIO_PA25, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
#define PIN_USIM1_nRST {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_IT_RISE_EDGE | PIO_DEGLITCH }
#define PIN_PHONE_IO_INPUT {PIO_PA21, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
#define PIN_PHONE_IO {PIO_PA22, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_PHONE_CLK {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT} // External Clock Input on PA28
//#define PIN_PHONE_CLK {PIO_PA23A_SCK1, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT} // External Clock Input on PA28
#define PIN_PHONE_CLK_INPUT {PIO_PA29, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
#define PINS_USIM1 PIN_PHONE_IO, PIN_PHONE_CLK, PIN_PHONE_CLK_INPUT, PIN_USIM1_VCC, PIN_PHONE_IO_INPUT, PIN_USIM1_nRST
//, VCC_PHONE
#define PIN_BOOTLOADER_SW {PIO_PA31, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
//** SPI interface **/
/// SPI MISO pin definition (PA12).
#define PIN_SPI_MISO {1 << 12, PIOA, PIOA, PIO_PERIPH_A, PIO_PULLUP}
/// SPI MOSI pin definition (PA13).
#define PIN_SPI_MOSI {1 << 13, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/// SPI SPCK pin definition (PA14).
#define PIN_SPI_SPCK {1 << 14, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/// SPI pins definition. Contains MISO, MOSI & SPCK (PA12, PA13 & PA14).
#define PINS_SPI PIN_SPI_MISO, PIN_SPI_MOSI, PIN_SPI_SPCK
/// SPI chip select 0 pin definition (PA11).
#define PIN_SPI_NPCS0 {1 << 11, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/** USB definitions */
/* OpenMoko SIMtrace 2 USB vendor ID */
#define BOARD_USB_VENDOR_ID USB_VENDOR_OPENMOKO
/* OpenMoko SIMtrace 2 USB product ID (main application/runtime mode) */
#define BOARD_USB_PRODUCT_ID USB_PRODUCT_SIMTRACE2
/* OpenMoko SIMtrace 2 DFU USB product ID (DFU bootloader/DFU mode) */
#define BOARD_DFU_USB_PRODUCT_ID USB_PRODUCT_SIMTRACE2_DFU
/* USB release number (bcdDevice, shown as 0.00) */
#define BOARD_USB_RELEASE 0x000
/* Indicate SIMtrace is bus power in USB attributes */
#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_BUSPOWERED_NORWAKEUP #define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_BUSPOWERED_NORWAKEUP
#define BOARD_USB_VENDOR_ID USB_VENDOR_OPENMOKO /** Supported modes */
#define BOARD_USB_PRODUCT_ID USB_PRODUCT_SIMTRACE2 /* SIMtrace board supports sniffer mode */
#define BOARD_DFU_USB_PRODUCT_ID USB_PRODUCT_SIMTRACE2_DFU #define HAVE_SNIFFER
#define BOARD_USB_RELEASE 0x000 /* SIMtrace board supports CCID mode */
//#define HAVE_CCID
//#define HAVE_SNIFFER /* SIMtrace board supports card emulation mode */
#define HAVE_CCID //#define HAVE_CARDEM
#define HAVE_CARDEM /* SIMtrace board supports man-in-the-middle mode */
//#define HAVE_MITM //#define HAVE_MITM

View File

@@ -44,7 +44,8 @@ int board_override_enter_dfu(void)
/* Enter DFU bootloader in case the respective button is pressed */ /* Enter DFU bootloader in case the respective button is pressed */
if (PIO_Get(&bl_sw_pin) == 0) { if (PIO_Get(&bl_sw_pin) == 0) {
printf("BOOTLOADER switch presssed -> Force DFU\n\r"); /* do not print to early since the console is not initialized yet */
//printf("BOOTLOADER switch pressed -> Force DFU\n\r");
return 1; return 1;
} else } else
return 0; return 0;

View File

@@ -2,5 +2,11 @@
#include <stdint.h> #include <stdint.h>
/* Table 7 of ISO 7816-3:2006 */
extern const uint16_t fi_table[];
/* Table 8 from ISO 7816-3:2006 */
extern const uint8_t di_table[];
/* compute the F/D ratio based on Fi and Di values */ /* compute the F/D ratio based on Fi and Di values */
int compute_fidi_ratio(uint8_t fi, uint8_t di); int compute_fidi_ratio(uint8_t fi, uint8_t di);

View File

@@ -5,7 +5,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <sys/types.h> #include <sys/types.h>
#define RING_BUFLEN 256 #define RING_BUFLEN 512
typedef struct ringbuf { typedef struct ringbuf {
uint8_t buf[RING_BUFLEN]; uint8_t buf[RING_BUFLEN];

View File

@@ -5,21 +5,8 @@
#include "board.h" #include "board.h"
#include <usb/device/dfu/dfu.h> #include <usb/device/dfu/dfu.h>
/* Endpoint numbers */
#define DATAOUT 1
#define DATAIN 2
#define INT 3
#define BUFLEN 512 #define BUFLEN 512
#define PHONE_DATAOUT 4
#define PHONE_DATAIN 5
#define PHONE_INT 6
#define CARDEM_USIM2_DATAOUT DATAOUT
#define CARDEM_USIM2_DATAIN DATAIN
#define CARDEM_USIM2_INT INT
#define CLK_MASTER true #define CLK_MASTER true
#define CLK_SLAVE false #define CLK_SLAVE false
@@ -77,8 +64,11 @@ typedef struct {
extern const USBConfigurationDescriptor *configurationDescriptorsArr[]; extern const USBConfigurationDescriptor *configurationDescriptorsArr[];
int check_data_from_phone(); /*! Update USART baud rate to Fi/Di ratio
void update_fidi(uint8_t fidi); * @param[io] usart USART peripheral base address
* @param[in] fidi FiDi value as provided in TA interface byte
*/
void update_fidi(Usart *usart, uint8_t fidi);
void ISR_PhoneRST( const Pin *pPin); void ISR_PhoneRST( const Pin *pPin);
@@ -108,6 +98,9 @@ extern void CCID_run( void );
extern void mode_cardemu_run(void); extern void mode_cardemu_run(void);
extern void MITM_run( void ); extern void MITM_run( void );
/* IRQ functions */
extern void Sniffer_usart0_irq(void);
extern void Sniffer_usart1_irq(void);
extern void mode_cardemu_usart0_irq(void); extern void mode_cardemu_usart0_irq(void);
extern void mode_cardemu_usart1_irq(void); extern void mode_cardemu_usart1_irq(void);

View File

@@ -1,7 +1,3 @@
#pragma once
#include <stdint.h>
/* SIMtrace2 USB protocol */ /* SIMtrace2 USB protocol */
/* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.de> /* (C) 2015-2017 by Harald Welte <hwelte@hmw-consulting.de>
@@ -21,6 +17,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
*/ */
#pragma once
#include <stdint.h>
#include <stdbool.h>
/*********************************************************************** /***********************************************************************
* COMMON HEADER * COMMON HEADER
@@ -30,10 +30,10 @@ enum simtrace_msg_class {
SIMTRACE_MSGC_GENERIC = 0, SIMTRACE_MSGC_GENERIC = 0,
/* Card Emulation / Forwarding */ /* Card Emulation / Forwarding */
SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGC_CARDEM,
/* Modem Control (if modem is attached next to device */ /* Modem Control (if modem is attached next to device) */
SIMTRACE_MSGC_MODEM, SIMTRACE_MSGC_MODEM,
/* SIM protocol tracing */ /* Reader/phone-car/SIM communication sniff */
SIMTRACE_MSGC_TRACE, SIMTRACE_MSGC_SNIFF,
/* first vendor-specific request */ /* first vendor-specific request */
_SIMTRACE_MGSC_VENDOR_FIRST = 127, _SIMTRACE_MGSC_VENDOR_FIRST = 127,
@@ -74,10 +74,18 @@ enum simtrace_msg_type_modem {
SIMTRACE_MSGT_BD_MODEM_STATUS, SIMTRACE_MSGT_BD_MODEM_STATUS,
}; };
/* SIMTRACE_MSGC_TRACE */ /* SIMTRACE_MSGC_SNIFF */
enum simtrace_msg_type_trace { enum simtrace_msg_type_sniff {
/* FIXME */ /* Status change (card inserted, reset, ...) */
_dummy, 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 */ /* common message header */
@@ -92,7 +100,7 @@ struct simtrace_msg_hdr {
} __attribute__ ((packed)); } __attribute__ ((packed));
/*********************************************************************** /***********************************************************************
* CARD EMULATOR / FORWARDER * Capabilities
***********************************************************************/ ***********************************************************************/
/* generic capabilities */ /* generic capabilities */
@@ -107,7 +115,7 @@ enum simtrace_capability_generic {
SIMTRACE_CAP_LED_1, SIMTRACE_CAP_LED_1,
/* Has LED2 */ /* Has LED2 */
SIMTRACE_CAP_LED_2, SIMTRACE_CAP_LED_2,
/* Has Single-Pole Dual-Throw (local/remote SIM */ /* Has Single-Pole Dual-Throw (local/remote SIM) */
SIMTRACE_CAP_SPDT, SIMTRACE_CAP_SPDT,
/* Has Bus-Switch (trace / MITM) */ /* Has Bus-Switch (trace / MITM) */
SIMTRACE_CAP_BUS_SWITCH, SIMTRACE_CAP_BUS_SWITCH,
@@ -127,7 +135,7 @@ enum simtrace_capability_generic {
SIMTRACE_CAP_ASSERT_MODEM_RST, SIMTRACE_CAP_ASSERT_MODEM_RST,
}; };
/* vendor-specific capabilities of sysmoocm devices */ /* vendor-specific capabilities of sysmocom devices */
enum simtrace_capability_vendor { enum simtrace_capability_vendor {
/* Can erase a peer SAM3 controller */ /* Can erase a peer SAM3 controller */
SIMTRACE_CAP_SYSMO_QMOD_ERASE_PEER, SIMTRACE_CAP_SYSMO_QMOD_ERASE_PEER,
@@ -137,7 +145,6 @@ enum simtrace_capability_vendor {
SIMTRACE_CAP_SYSMO_QMOD_RESET_HUB, SIMTRACE_CAP_SYSMO_QMOD_RESET_HUB,
}; };
/* SIMTRACE_CMD_BD_BOARD_INFO */ /* SIMTRACE_CMD_BD_BOARD_INFO */
struct simtrace_board_info { struct simtrace_board_info {
struct { struct {
@@ -253,7 +260,7 @@ struct cardemu_usb_msg_error {
/* SIMTRACE_MSGT_DT_MODEM_RESET */ /* SIMTRACE_MSGT_DT_MODEM_RESET */
struct st_modem_reset { struct st_modem_reset {
/* 0: de-assert reset, 1: assert reset, 2: poulse reset */ /* 0: de-assert reset, 1: assert reset, 2: pulse reset */
uint8_t asserted; uint8_t asserted;
/* if above is '2', duration of pulse in ms */ /* if above is '2', duration of pulse in ms */
uint16_t pulse_duration_msec; uint16_t pulse_duration_msec;
@@ -276,3 +283,36 @@ struct st_modem_status {
/* bit-field of changed status bits */ /* bit-field of changed status bits */
uint8_t changed_mask; uint8_t changed_mask;
} __attribute__((packed)); } __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_HOLD (1<<2)
#define SNIFF_CHANGE_FLAG_RESET_RELEASE (1<<3)
#define SNIFF_CHANGE_FLAG_TIMEOUT_WT (1<<4)
/* 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 {
/* if the data is complete (an error might have occurred during transmission */
bool complete;
/* data length */
uint16_t length;
/* data */
uint8_t data[0];
} __attribute__ ((packed));

View File

@@ -0,0 +1,66 @@
/* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* (C) 2018 by Kevin Redon <kredon@sysmocom.de>
* All Rights Reserved
*/
/* 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

View File

@@ -24,13 +24,13 @@
#include "iso7816_fidi.h" #include "iso7816_fidi.h"
/* Table 7 of ISO 7816-3:2006 */ /* Table 7 of ISO 7816-3:2006 */
static const uint16_t fi_table[] = { const uint16_t fi_table[] = {
372, 372, 558, 744, 1116, 1488, 1860, 0, 372, 372, 558, 744, 1116, 1488, 1860, 0,
0, 512, 768, 1024, 1536, 2048, 0, 0 0, 512, 768, 1024, 1536, 2048, 0, 0
}; };
/* Table 8 from ISO 7816-3:2006 */ /* Table 8 from ISO 7816-3:2006 */
static const uint8_t di_table[] = { const uint8_t di_table[] = {
0, 1, 2, 4, 8, 16, 32, 64, 0, 1, 2, 4, 8, 16, 32, 64,
12, 20, 2, 4, 8, 16, 32, 64, 12, 20, 2, 4, 8, 16, 32, 64,
}; };

View File

@@ -1,6 +1,7 @@
//#define TRACE_LEVEL 6 //#define TRACE_LEVEL 6
#include "board.h" #include "board.h"
#include "boardver_adc.h"
#include "simtrace.h" #include "simtrace.h"
#include "ringbuffer.h" #include "ringbuffer.h"
#include "card_emu.h" #include "card_emu.h"
@@ -10,6 +11,7 @@
#include <osmocom/core/msgb.h> #include <osmocom/core/msgb.h>
#include "llist_irqsafe.h" #include "llist_irqsafe.h"
#include "usb_buf.h" #include "usb_buf.h"
#include "simtrace_usb.h"
#include "simtrace_prot.h" #include "simtrace_prot.h"
#include "sim_switch.h" #include "sim_switch.h"
@@ -53,9 +55,9 @@ struct cardem_inst cardem_inst[] = {
.id = ID_USART1, .id = ID_USART1,
.state = USART_RCV .state = USART_RCV
}, },
.ep_out = PHONE_DATAOUT, .ep_out = SIMTRACE_CARDEM_USB_EP_USIM1_DATAOUT,
.ep_in = PHONE_DATAIN, .ep_in = SIMTRACE_CARDEM_USB_EP_USIM1_DATAIN,
.ep_int = PHONE_INT, .ep_int = SIMTRACE_CARDEM_USB_EP_USIM1_INT,
#ifdef PIN_SET_USIM1_PRES #ifdef PIN_SET_USIM1_PRES
.pin_insert = PIN_SET_USIM1_PRES, .pin_insert = PIN_SET_USIM1_PRES,
#endif #endif
@@ -68,9 +70,9 @@ struct cardem_inst cardem_inst[] = {
.id = ID_USART0, .id = ID_USART0,
.state = USART_RCV .state = USART_RCV
}, },
.ep_out = CARDEM_USIM2_DATAOUT, .ep_out = SIMTRACE_CARDEM_USB_EP_USIM2_DATAOUT,
.ep_in = CARDEM_USIM2_DATAIN, .ep_in = SIMTRACE_CARDEM_USB_EP_USIM2_DATAIN,
.ep_int = CARDEM_USIM2_INT, .ep_int = SIMTRACE_CARDEM_USB_EP_USIM2_INT,
#ifdef PIN_SET_USIM2_PRES #ifdef PIN_SET_USIM2_PRES
.pin_insert = PIN_SET_USIM2_PRES, .pin_insert = PIN_SET_USIM2_PRES,
#endif #endif
@@ -278,7 +280,6 @@ static int card_vcc_adc_init(void)
return 0; return 0;
} }
#define UV_PER_LSB ((3300 * 1000) / 4096)
#define VCC_UV_THRESH_1V8 1500000 #define VCC_UV_THRESH_1V8 1500000
#define VCC_UV_THRESH_3V 2800000 #define VCC_UV_THRESH_3V 2800000
@@ -298,12 +299,6 @@ static void process_vcc_adc(struct cardem_inst *ci)
ci->vcc_uv_last = ci->vcc_uv; ci->vcc_uv_last = ci->vcc_uv;
} }
static uint32_t adc2uv(uint16_t adc)
{
uint32_t uv = (uint32_t) adc * UV_PER_LSB;
return uv;
}
void ADC_IrqHandler(void) void ADC_IrqHandler(void)
{ {
#ifdef CARDEMU_SECOND_UART #ifdef CARDEMU_SECOND_UART
@@ -397,7 +392,7 @@ void mode_cardemu_init(void)
PIO_ConfigureIt(&pin_usim1_vcc, usim1_vcc_irqhandler); PIO_ConfigureIt(&pin_usim1_vcc, usim1_vcc_irqhandler);
PIO_EnableIt(&pin_usim1_vcc); PIO_EnableIt(&pin_usim1_vcc);
#endif /* DETECT_VCC_BY_ADC */ #endif /* DETECT_VCC_BY_ADC */
cardem_inst[0].ch = card_emu_init(0, 2, 0, PHONE_DATAIN, PHONE_INT); cardem_inst[0].ch = card_emu_init(0, 2, 0, SIMTRACE_CARDEM_USB_EP_USIM1_DATAIN, SIMTRACE_CARDEM_USB_EP_USIM1_INT);
sim_switch_use_physical(0, 1); sim_switch_use_physical(0, 1);
#ifdef CARDEMU_SECOND_UART #ifdef CARDEMU_SECOND_UART
@@ -412,7 +407,7 @@ void mode_cardemu_init(void)
PIO_ConfigureIt(&pin_usim2_vcc, usim2_vcc_irqhandler); PIO_ConfigureIt(&pin_usim2_vcc, usim2_vcc_irqhandler);
PIO_EnableIt(&pin_usim2_vcc); PIO_EnableIt(&pin_usim2_vcc);
#endif /* DETECT_VCC_BY_ADC */ #endif /* DETECT_VCC_BY_ADC */
cardem_inst[1].ch = card_emu_init(1, 0, 1, CARDEM_USIM2_DATAIN, CARDEM_USIM2_INT); cardem_inst[1].ch = card_emu_init(1, 0, 1, SIMTRACE_CARDEM_USB_EP_USIM2_DATAIN, SIMTRACE_CARDEM_USB_EP_USIM2_INT);
sim_switch_use_physical(1, 1); sim_switch_use_physical(1, 1);
#endif /* CARDEMU_SECOND_UART */ #endif /* CARDEMU_SECOND_UART */

View File

@@ -33,6 +33,7 @@
#include "board.h" #include "board.h"
#include "simtrace.h" #include "simtrace.h"
#include "simtrace_usb.h"
#include "ringbuffer.h" #include "ringbuffer.h"
#include "iso7816_fidi.h" #include "iso7816_fidi.h"
@@ -67,7 +68,7 @@ void ISR_PhoneRST(const Pin * pPin)
} }
if ((ret = if ((ret =
USBD_Write(PHONE_INT, "R", 1, USBD_Write(SIMTRACE_USB_EP_PHONE_INT, "R", 1,
(TransferCallback) & Callback_PhoneRST_ISR, (TransferCallback) & Callback_PhoneRST_ISR,
0)) != USBD_STATUS_SUCCESS) { 0)) != USBD_STATUS_SUCCESS) {
TRACE_ERROR("USB err status: %d (%s)\n", ret, __FUNCTION__); TRACE_ERROR("USB err status: %d (%s)\n", ret, __FUNCTION__);
@@ -116,20 +117,27 @@ void mode_trace_usart1_irq(void)
} }
/* FIDI update functions */ /* FIDI update functions */
void update_fidi(uint8_t fidi) void update_fidi(Usart *usart, uint8_t fidi)
{ {
int rc; if (NULL==usart) {
return;
}
uint8_t fi = fidi >> 4; uint8_t fi = fidi >> 4;
uint8_t di = fidi & 0xf; uint8_t di = fidi & 0xf;
int ratio = compute_fidi_ratio(fi, di);
rc = compute_fidi_ratio(fi, di); if (ratio > 0 && ratio < 0x8000) {
if (rc > 0 && rc < 0x400) { /* make sure USART uses new F/D ratio */
TRACE_INFO("computed Fi(%u) Di(%u) ratio: %d", fi, di, rc); usart->US_CR |= US_CR_RXDIS | US_CR_RSTRX;
/* make sure UART uses new F/D ratio */ /* disable write protection */
USART_PHONE->US_CR |= US_CR_RXDIS | US_CR_RSTRX; if (usart->US_WPMR) {
USART_PHONE->US_FIDI = rc & 0x3ff; usart->US_WPMR = US_WPMR_WPKEY(0x555341);
USART_PHONE->US_CR |= US_CR_RXEN | US_CR_STTTO; }
} else usart->US_FIDI = (ratio & 0x7ff);
TRACE_INFO("computed FiDi ratio %d unsupported", rc); usart->US_CR |= US_CR_RXEN | US_CR_STTTO;
//TRACE_INFO("updated USART Fi(%u)/Di(%u) ratio(%d): %u\n\r", fi, di, ratio, usart->US_FIDI); /* don't print since this is function is also called by ISRs */
} else {
//TRACE_WARNING("computed Fi/Di ratio %d unsupported\n\r", ratio); /* don't print since this is function is also called by ISRs */
}
} }

File diff suppressed because it is too large Load Diff

View File

@@ -33,15 +33,13 @@
#include "board.h" #include "board.h"
#include "simtrace.h" #include "simtrace.h"
#include "simtrace_usb.h"
#include "utils.h" #include "utils.h"
#include <cciddriverdescriptors.h> #include <cciddriverdescriptors.h>
#include <usb/common/dfu/usb_dfu.h> #include <usb/common/dfu/usb_dfu.h>
#include <usb/device/dfu/dfu.h> #include <usb/device/dfu/dfu.h>
#define SIMTRACE_SUBCLASS_SNIFFER 1
#define SIMTRACE_SUBCLASS_CARDEM 2
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* USB String descriptors * USB String descriptors
*------------------------------------------------------------------------------*/ *------------------------------------------------------------------------------*/
@@ -94,8 +92,8 @@ static const SIMTraceDriverConfigurationDescriptorSniffer
.bInterfaceNumber = 0, .bInterfaceNumber = 0,
.bAlternateSetting = 0, .bAlternateSetting = 0,
.bNumEndpoints = 3, .bNumEndpoints = 3,
.bInterfaceClass = 0xff, .bInterfaceClass = USB_CLASS_PROPRIETARY,
.bInterfaceSubClass = SIMTRACE_SUBCLASS_SNIFFER, .bInterfaceSubClass = SIMTRACE_SNIFFER_USB_SUBCLASS,
.bInterfaceProtocol = 0, .bInterfaceProtocol = 0,
.iInterface = SNIFFER_CONF_STR, .iInterface = SNIFFER_CONF_STR,
}, },
@@ -105,11 +103,9 @@ static const SIMTraceDriverConfigurationDescriptorSniffer
.bDescriptorType = USBGenericDescriptor_ENDPOINT, .bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS( .bEndpointAddress = USBEndpointDescriptor_ADDRESS(
USBEndpointDescriptor_OUT, USBEndpointDescriptor_OUT,
PHONE_DATAOUT), SIMTRACE_USB_EP_CARD_DATAOUT),
.bmAttributes = USBEndpointDescriptor_BULK, .bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE( .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS,
PHONE_DATAOUT),
USBEndpointDescriptor_MAXBULKSIZE_FS),
.bInterval = 0, .bInterval = 0,
}, },
/* Bulk-IN endpoint descriptor */ /* Bulk-IN endpoint descriptor */
@@ -118,11 +114,9 @@ static const SIMTraceDriverConfigurationDescriptorSniffer
.bDescriptorType = USBGenericDescriptor_ENDPOINT, .bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS( .bEndpointAddress = USBEndpointDescriptor_ADDRESS(
USBEndpointDescriptor_IN, USBEndpointDescriptor_IN,
PHONE_DATAIN), SIMTRACE_USB_EP_CARD_DATAIN),
.bmAttributes = USBEndpointDescriptor_BULK, .bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE( .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS,
PHONE_DATAIN),
USBEndpointDescriptor_MAXBULKSIZE_FS),
.bInterval = 0, .bInterval = 0,
}, },
// Notification endpoint descriptor // Notification endpoint descriptor
@@ -131,11 +125,9 @@ static const SIMTraceDriverConfigurationDescriptorSniffer
.bDescriptorType = USBGenericDescriptor_ENDPOINT, .bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS( .bEndpointAddress = USBEndpointDescriptor_ADDRESS(
USBEndpointDescriptor_IN, USBEndpointDescriptor_IN,
PHONE_INT), SIMTRACE_USB_EP_CARD_INT),
.bmAttributes = USBEndpointDescriptor_INTERRUPT, .bmAttributes = USBEndpointDescriptor_INTERRUPT,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE( .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS,
PHONE_INT),
USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
.bInterval = 0x10, .bInterval = 0x10,
}, },
DFURT_IF_DESCRIPTOR(1, 0), DFURT_IF_DESCRIPTOR(1, 0),
@@ -205,9 +197,7 @@ static const CCIDDriverConfigurationDescriptors configurationDescriptorCCID = {
USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT, USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
CCID_EPT_DATA_OUT), CCID_EPT_DATA_OUT),
.bmAttributes = USBEndpointDescriptor_BULK, .bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE( .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS,
CCID_EPT_DATA_OUT),
USBEndpointDescriptor_MAXBULKSIZE_FS),
.bInterval = 0x00, .bInterval = 0x00,
}, },
// Bulk-IN endpoint descriptor // Bulk-IN endpoint descriptor
@@ -218,9 +208,7 @@ static const CCIDDriverConfigurationDescriptors configurationDescriptorCCID = {
USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
CCID_EPT_DATA_IN), CCID_EPT_DATA_IN),
.bmAttributes = USBEndpointDescriptor_BULK, .bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE( .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS),
CCID_EPT_DATA_IN),
USBEndpointDescriptor_MAXBULKSIZE_FS),
.bInterval = 0x00, .bInterval = 0x00,
}, },
// Notification endpoint descriptor // Notification endpoint descriptor
@@ -231,9 +219,7 @@ static const CCIDDriverConfigurationDescriptors configurationDescriptorCCID = {
USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
CCID_EPT_NOTIFICATION), CCID_EPT_NOTIFICATION),
.bmAttributes = USBEndpointDescriptor_INTERRUPT, .bmAttributes = USBEndpointDescriptor_INTERRUPT,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE( .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS,
CCID_EPT_NOTIFICATION),
USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
.bInterval = 0x10, .bInterval = 0x10,
}, },
DFURT_IF_DESCRIPTOR(1, 0), DFURT_IF_DESCRIPTOR(1, 0),
@@ -282,8 +268,8 @@ static const SIMTraceDriverConfigurationDescriptorPhone
.bInterfaceNumber = 0, .bInterfaceNumber = 0,
.bAlternateSetting = 0, .bAlternateSetting = 0,
.bNumEndpoints = 3, .bNumEndpoints = 3,
.bInterfaceClass = 0xff, .bInterfaceClass = USB_CLASS_PROPRIETARY,
.bInterfaceSubClass = SIMTRACE_SUBCLASS_CARDEM, .bInterfaceSubClass = SIMTRACE_CARDEM_USB_SUBCLASS,
.bInterfaceProtocol = 0, .bInterfaceProtocol = 0,
.iInterface = CARDEM_USIM1_INTF_STR, .iInterface = CARDEM_USIM1_INTF_STR,
}, },
@@ -293,10 +279,9 @@ static const SIMTraceDriverConfigurationDescriptorPhone
.bDescriptorType = USBGenericDescriptor_ENDPOINT, .bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS( .bEndpointAddress = USBEndpointDescriptor_ADDRESS(
USBEndpointDescriptor_OUT, USBEndpointDescriptor_OUT,
PHONE_DATAOUT), SIMTRACE_CARDEM_USB_EP_USIM1_DATAOUT),
.bmAttributes = USBEndpointDescriptor_BULK, .bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(PHONE_DATAOUT), .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS,
USBEndpointDescriptor_MAXBULKSIZE_FS),
.bInterval = 0 /* Must be 0 for full-speed bulk endpoints */ .bInterval = 0 /* Must be 0 for full-speed bulk endpoints */
}, },
/* Bulk-IN endpoint descriptor */ /* Bulk-IN endpoint descriptor */
@@ -305,10 +290,9 @@ static const SIMTraceDriverConfigurationDescriptorPhone
.bDescriptorType = USBGenericDescriptor_ENDPOINT, .bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS( .bEndpointAddress = USBEndpointDescriptor_ADDRESS(
USBEndpointDescriptor_IN, USBEndpointDescriptor_IN,
PHONE_DATAIN), SIMTRACE_CARDEM_USB_EP_USIM1_DATAIN),
.bmAttributes = USBEndpointDescriptor_BULK, .bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(PHONE_DATAIN), .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS,
USBEndpointDescriptor_MAXBULKSIZE_FS),
.bInterval = 0 /* Must be 0 for full-speed bulk endpoints */ .bInterval = 0 /* Must be 0 for full-speed bulk endpoints */
}, },
/* Notification endpoint descriptor */ /* Notification endpoint descriptor */
@@ -317,10 +301,9 @@ static const SIMTraceDriverConfigurationDescriptorPhone
.bDescriptorType = USBGenericDescriptor_ENDPOINT, .bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS( .bEndpointAddress = USBEndpointDescriptor_ADDRESS(
USBEndpointDescriptor_IN, USBEndpointDescriptor_IN,
PHONE_INT), SIMTRACE_CARDEM_USB_EP_USIM1_INT),
.bmAttributes = USBEndpointDescriptor_INTERRUPT, .bmAttributes = USBEndpointDescriptor_INTERRUPT,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(PHONE_INT), .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS,
USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
.bInterval = 0x10 .bInterval = 0x10
}, },
#ifdef CARDEMU_SECOND_UART #ifdef CARDEMU_SECOND_UART
@@ -331,8 +314,8 @@ static const SIMTraceDriverConfigurationDescriptorPhone
.bInterfaceNumber = 1, .bInterfaceNumber = 1,
.bAlternateSetting = 0, .bAlternateSetting = 0,
.bNumEndpoints = 3, .bNumEndpoints = 3,
.bInterfaceClass = 0xff, .bInterfaceClass = USB_CLASS_PROPRIETARY,
.bInterfaceSubClass = SIMTRACE_SUBCLASS_CARDEM, .bInterfaceSubClass = SIMTRACE_CARDEM_USB_SUBCLASS,
.bInterfaceProtocol = 0, .bInterfaceProtocol = 0,
.iInterface = CARDEM_USIM2_INTF_STR, .iInterface = CARDEM_USIM2_INTF_STR,
}, },
@@ -342,10 +325,9 @@ static const SIMTraceDriverConfigurationDescriptorPhone
.bDescriptorType = USBGenericDescriptor_ENDPOINT, .bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS( .bEndpointAddress = USBEndpointDescriptor_ADDRESS(
USBEndpointDescriptor_OUT, USBEndpointDescriptor_OUT,
CARDEM_USIM2_DATAOUT), SIMTRACE_CARDEM_USB_EP_USIM2_DATAOUT),
.bmAttributes = USBEndpointDescriptor_BULK, .bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(CARDEM_USIM2_DATAOUT), .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS,
USBEndpointDescriptor_MAXBULKSIZE_FS),
.bInterval = 0 /* Must be 0 for full-speed bulk endpoints */ .bInterval = 0 /* Must be 0 for full-speed bulk endpoints */
} }
, ,
@@ -355,10 +337,9 @@ static const SIMTraceDriverConfigurationDescriptorPhone
.bDescriptorType = USBGenericDescriptor_ENDPOINT, .bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS( .bEndpointAddress = USBEndpointDescriptor_ADDRESS(
USBEndpointDescriptor_IN, USBEndpointDescriptor_IN,
CARDEM_USIM2_DATAIN), SIMTRACE_CARDEM_USB_EP_USIM2_DATAIN),
.bmAttributes = USBEndpointDescriptor_BULK, .bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(CARDEM_USIM2_DATAIN), .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS,
USBEndpointDescriptor_MAXBULKSIZE_FS),
.bInterval = 0 /* Must be 0 for full-speed bulk endpoints */ .bInterval = 0 /* Must be 0 for full-speed bulk endpoints */
}, },
/* Notification endpoint descriptor */ /* Notification endpoint descriptor */
@@ -367,10 +348,9 @@ static const SIMTraceDriverConfigurationDescriptorPhone
.bDescriptorType = USBGenericDescriptor_ENDPOINT, .bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS( .bEndpointAddress = USBEndpointDescriptor_ADDRESS(
USBEndpointDescriptor_IN, USBEndpointDescriptor_IN,
CARDEM_USIM2_INT), SIMTRACE_CARDEM_USB_EP_USIM2_INT),
.bmAttributes = USBEndpointDescriptor_INTERRUPT, .bmAttributes = USBEndpointDescriptor_INTERRUPT,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(CARDEM_USIM2_INT), .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS,
USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
.bInterval = 0x10, .bInterval = 0x10,
}, },
DFURT_IF_DESCRIPTOR(2, 0), DFURT_IF_DESCRIPTOR(2, 0),
@@ -466,9 +446,7 @@ static const SIMTraceDriverConfigurationDescriptorMITM
USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT, USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
CCID_EPT_DATA_OUT), CCID_EPT_DATA_OUT),
.bmAttributes = USBEndpointDescriptor_BULK, .bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE( .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS,
CCID_EPT_DATA_OUT),
USBEndpointDescriptor_MAXBULKSIZE_FS),
.bInterval = 0x00, .bInterval = 0x00,
}, },
// Bulk-IN endpoint descriptor // Bulk-IN endpoint descriptor
@@ -479,9 +457,7 @@ static const SIMTraceDriverConfigurationDescriptorMITM
USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
CCID_EPT_DATA_IN), CCID_EPT_DATA_IN),
.bmAttributes = USBEndpointDescriptor_BULK, .bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE( .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS,
CCID_EPT_DATA_IN),
USBEndpointDescriptor_MAXBULKSIZE_FS),
.bInterval = 0x00, .bInterval = 0x00,
}, },
// Notification endpoint descriptor // Notification endpoint descriptor
@@ -492,9 +468,7 @@ static const SIMTraceDriverConfigurationDescriptorMITM
USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN, USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
CCID_EPT_NOTIFICATION), CCID_EPT_NOTIFICATION),
.bmAttributes = USBEndpointDescriptor_INTERRUPT, .bmAttributes = USBEndpointDescriptor_INTERRUPT,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE( .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS,
CCID_EPT_NOTIFICATION),
USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
.bInterval = 0x10, .bInterval = 0x10,
}, },
@@ -516,10 +490,9 @@ static const SIMTraceDriverConfigurationDescriptorMITM
.bDescriptorType = USBGenericDescriptor_ENDPOINT, .bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS( .bEndpointAddress = USBEndpointDescriptor_ADDRESS(
USBEndpointDescriptor_OUT, USBEndpointDescriptor_OUT,
PHONE_DATAOUT), SIMTRACE_USB_EP_PHONE_DATAOUT),
.bmAttributes = USBEndpointDescriptor_BULK, .bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(PHONE_DATAOUT), .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS,
USBEndpointDescriptor_MAXBULKSIZE_FS),
.bInterval = 0, /* Must be 0 for full-speed bulk endpoints */ .bInterval = 0, /* Must be 0 for full-speed bulk endpoints */
}, },
/* Bulk-IN endpoint descriptor */ /* Bulk-IN endpoint descriptor */
@@ -528,10 +501,9 @@ static const SIMTraceDriverConfigurationDescriptorMITM
.bDescriptorType = USBGenericDescriptor_ENDPOINT, .bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS( .bEndpointAddress = USBEndpointDescriptor_ADDRESS(
USBEndpointDescriptor_IN, USBEndpointDescriptor_IN,
PHONE_DATAIN), SIMTRACE_USB_EP_PHONE_DATAIN),
.bmAttributes = USBEndpointDescriptor_BULK, .bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(PHONE_DATAIN), .wMaxPacketSize = USBEndpointDescriptor_MAXBULKSIZE_FS,
USBEndpointDescriptor_MAXBULKSIZE_FS),
.bInterval = 0, /* Must be 0 for full-speed bulk endpoints */ .bInterval = 0, /* Must be 0 for full-speed bulk endpoints */
}, },
/* Notification endpoint descriptor */ /* Notification endpoint descriptor */
@@ -540,10 +512,9 @@ static const SIMTraceDriverConfigurationDescriptorMITM
.bDescriptorType = USBGenericDescriptor_ENDPOINT, .bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS( .bEndpointAddress = USBEndpointDescriptor_ADDRESS(
USBEndpointDescriptor_IN, USBEndpointDescriptor_IN,
PHONE_INT), SIMTRACE_USB_EP_PHONE_INT),
.bmAttributes = USBEndpointDescriptor_INTERRUPT, .bmAttributes = USBEndpointDescriptor_INTERRUPT,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(PHONE_INT), .wMaxPacketSize = USBEndpointDescriptor_MAXINTERRUPTSIZE_FS,
USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
.bInterval = 0x10 .bInterval = 0x10
}, },
DFURT_IF_DESCRIPTOR(2, 0), DFURT_IF_DESCRIPTOR(2, 0),
@@ -573,7 +544,7 @@ const USBDeviceDescriptor deviceDescriptor = {
.bDeviceClass = 0, .bDeviceClass = 0,
.bDeviceSubClass = 0, .bDeviceSubClass = 0,
.bDeviceProtocol = 0, .bDeviceProtocol = 0,
.bMaxPacketSize0 = BOARD_USB_ENDPOINTS_MAXPACKETSIZE(0), .bMaxPacketSize0 = 64,
.idVendor = BOARD_USB_VENDOR_ID, .idVendor = BOARD_USB_VENDOR_ID,
.idProduct = BOARD_USB_PRODUCT_ID, .idProduct = BOARD_USB_PRODUCT_ID,
.bcdDevice = 2, /* Release number */ .bcdDevice = 2, /* Release number */

View File

@@ -1,6 +1,7 @@
#include "board.h" #include "board.h"
#include "trace.h" #include "trace.h"
#include "usb_buf.h" #include "usb_buf.h"
#include "simtrace_usb.h"
#include <osmocom/core/linuxlist.h> #include <osmocom/core/linuxlist.h>
#include <osmocom/core/msgb.h> #include <osmocom/core/msgb.h>

View File

@@ -1,7 +1,7 @@
LDFLAGS=`pkg-config --libs libusb-1.0 libosmocore` -losmocore LDFLAGS=`pkg-config --libs libusb-1.0 libosmocore` -losmocore
CFLAGS=-Wall -g CFLAGS=-Wall -g
all: simtrace2-remsim simtrace2-remsim-usb2udp simtrace2-list all: simtrace2-remsim simtrace2-remsim-usb2udp simtrace2-list simtrace2-sniff
simtrace2-remsim: simtrace2-remsim.o apdu_dispatch.o simtrace2-discovery.o libusb_util.o simtrace2-remsim: simtrace2-remsim.o apdu_dispatch.o simtrace2-discovery.o libusb_util.o
$(CC) -o $@ $^ $(LDFLAGS) -losmosim $(CC) -o $@ $^ $(LDFLAGS) -losmosim
@@ -12,6 +12,9 @@ simtrace2-remsim-usb2udp: usb2udp.o simtrace2-discovery.o
simtrace2-list: simtrace2_usb.o libusb_util.o simtrace2-list: simtrace2_usb.o libusb_util.o
$(CC) -o $@ $^ $(LDFLAGS) $(CC) -o $@ $^ $(LDFLAGS)
simtrace2-sniff: simtrace2-sniff.o simtrace2-discovery.o libusb_util.o
$(CC) -o $@ $^ $(LDFLAGS)
%.o: %.c %.o: %.c
$(CC) $(CFLAGS) `pkg-config --cflags libusb-1.0 libosmocore` -o $@ -c $^ $(CC) $(CFLAGS) `pkg-config --cflags libusb-1.0 libosmocore` -o $@ -c $^

View File

@@ -130,11 +130,11 @@ int dev_find_matching_interfaces(libusb_device *dev, int class, int sub_class, i
for (k = 0; k < intf->num_altsetting; k++) { for (k = 0; k < intf->num_altsetting; k++) {
const struct libusb_interface_descriptor *if_desc; const struct libusb_interface_descriptor *if_desc;
if_desc = &intf->altsetting[k]; if_desc = &intf->altsetting[k];
if (class > 0 && if_desc->bInterfaceClass != class) if (class >= 0 && if_desc->bInterfaceClass != class)
continue; continue;
if (sub_class > 0 && if_desc->bInterfaceSubClass != sub_class) if (sub_class >= 0 && if_desc->bInterfaceSubClass != sub_class)
continue; continue;
if (protocol > 0 && if_desc->bInterfaceProtocol != protocol) if (protocol >= 0 && if_desc->bInterfaceProtocol != protocol)
continue; continue;
/* MATCH! */ /* MATCH! */
out[out_idx].usb_dev = dev; out[out_idx].usb_dev = dev;
@@ -197,7 +197,7 @@ int usb_match_interfaces(libusb_context *ctx, const struct dev_id *dev_ids,
dev_desc.idVendor, dev_desc.idProduct, addr); dev_desc.idVendor, dev_desc.idProduct, addr);
#endif #endif
rc = dev_find_matching_interfaces(*dev, 255, 2, -1, out_cur, out_len_remain); rc = dev_find_matching_interfaces(*dev, class, sub_class, protocol, out_cur, out_len_remain);
if (rc < 0) if (rc < 0)
continue; continue;
out_cur += rc; out_cur += rc;

531
host/simtrace2-sniff.c Normal file
View File

@@ -0,0 +1,531 @@
/* simtrace2-sniff - main program for the host PC to communicate with the SIMtrace 2 firmware in sniffer mode */
/* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation
*
* 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
*
* (C) 2010-2017 by Harald Welte <hwelte@hmw-consulting.de>
* (C) 2018 by Kevin Redon <kredon@sysmocom.de>
*/
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <signal.h>
#include <time.h>
#define _GNU_SOURCE
#include <getopt.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <libusb.h>
#include "libusb_util.h"
#include "simtrace.h"
#include "simtrace_usb.h"
#include "simtrace_prot.h"
#include "simtrace2-discovery.h"
#include <osmocom/core/gsmtap.h>
#include <osmocom/core/gsmtap_util.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/socket.h>
#include <osmocom/core/msgb.h>
#include <osmocom/sim/class_tables.h>
#include <osmocom/sim/sim.h>
/* transport to a SIMtrace device */
struct st_transport {
/* USB */
struct libusb_device_handle *usb_devh;
struct {
uint8_t in;
uint8_t out;
uint8_t irq_in;
} usb_ep;
};
/* global GSMTAP instance */
static struct gsmtap_inst *g_gti;
static int gsmtap_send_sim(const uint8_t *apdu, unsigned int len)
{
struct gsmtap_hdr *gh;
unsigned int gross_len = len + sizeof(*gh);
uint8_t *buf = malloc(gross_len);
int rc;
if (!buf)
return -ENOMEM;
memset(buf, 0, sizeof(*gh));
gh = (struct gsmtap_hdr *) buf;
gh->version = GSMTAP_VERSION;
gh->hdr_len = sizeof(*gh)/4;
gh->type = GSMTAP_TYPE_SIM;
memcpy(buf + sizeof(*gh), apdu, len);
rc = write(gsmtap_inst_fd(g_gti), buf, gross_len);
if (rc < 0) {
perror("write gsmtap");
free(buf);
return rc;
}
free(buf);
return 0;
}
static int process_change(const uint8_t *buf, int len)
{
/* check if there is enough data for the structure */
if (len<sizeof(struct sniff_change)) {
return -1;
}
struct sniff_change *change = (struct sniff_change *)buf;
printf("Card state change: ");
if (change->flags&SNIFF_CHANGE_FLAG_CARD_INSERT) {
printf("card inserted ");
}
if (change->flags&SNIFF_CHANGE_FLAG_CARD_EJECT) {
printf("card ejected ");
}
if (change->flags&SNIFF_CHANGE_FLAG_RESET_HOLD) {
printf("reset hold ");
}
if (change->flags&SNIFF_CHANGE_FLAG_RESET_RELEASE) {
printf("reset release ");
}
if (change->flags&SNIFF_CHANGE_FLAG_TIMEOUT_WT) {
printf("data transfer timeout ");
}
printf("\n");
return 0;
}
/* Table 7 of ISO 7816-3:2006 */
static const uint16_t fi_table[] = { 372, 372, 558, 744, 1116, 1488, 1860, 0, 0, 512, 768, 1024, 1536, 2048, 0, 0, };
/* Table 8 from ISO 7816-3:2006 */
static const uint8_t di_table[] = { 0, 1, 2, 4, 8, 16, 32, 64, 12, 20, 2, 4, 8, 16, 32, 64, };
static int process_fidi(const uint8_t *buf, int len)
{
/* check if there is enough data for the structure */
if (len<sizeof(struct sniff_fidi)) {
return -1;
}
struct sniff_fidi *fidi = (struct sniff_fidi *)buf;
printf("Fi/Di switched to %u/%u\n", fi_table[fidi->fidi>>4], di_table[fidi->fidi&0x0f]);
return 0;
}
static int process_atr(const uint8_t *buf, int len)
{
/* check if there is enough data for the structure */
if (len<sizeof(struct sniff_data)) {
return -1;
}
struct sniff_data *atr = (struct sniff_data *)buf;
/* check if the data is available */
if (len<sizeof(struct sniff_data)+atr->length) {
return -2;
}
printf("ATR%s: ", atr->complete ? "" : " (incomplete)");
for (uint16_t i=0; i<atr->length; i++) {
printf("%02x ", atr->data[i]);
}
printf("\n");
return 0;
}
static int process_pps(const uint8_t *buf, int len)
{
/* check if there is enough data for the structure */
if (len<sizeof(struct sniff_data)) {
return -1;
}
struct sniff_data *pps = (struct sniff_data *)buf;
/* check if the data is available */
if (len<sizeof(struct sniff_data)+pps->length) {
return -2;
}
printf("PPS%s: ", pps->complete ? "" : " (incomplete) ");
for (uint16_t i=0; i<pps->length; i++) {
printf("%02x ", pps->data[i]);
}
printf("\n");
return 0;
}
static int process_tpdu(const uint8_t *buf, int len)
{
/* check if there is enough data for the structure */
if (len<sizeof(struct sniff_data)) {
return -1;
}
struct sniff_data *tpdu = (struct sniff_data *)buf;
/* check if the data is available */
if (len<sizeof(struct sniff_data)+tpdu->length) {
return -2;
}
/* print TPDU */
printf("TPDU%s: ", tpdu->complete ? "" : " (incomplete)");
for (uint16_t i=0; i<tpdu->length; i++) {
printf("%02x ", tpdu->data[i]);
}
printf("\n");
/* send TPDU (now considered as APDU) to GSMTAP */
gsmtap_send_sim(tpdu->data, tpdu->length);
return 0;
}
/*! \brief Process an incoming message from the SIMtrace2 */
static int process_usb_msg(const uint8_t *buf, int len)
{
/* check if enough data for the header is present */
if (len<sizeof(struct simtrace_msg_hdr)) {
return 0;
}
/* check if message is complete */
struct simtrace_msg_hdr *msg_hdr = (struct simtrace_msg_hdr *)buf;
if (len<msg_hdr->msg_len) {
return 0;
}
//printf("msg: %s\n", osmo_hexdump(buf, msg_hdr->msg_len));
/* check for message class */
if (SIMTRACE_MSGC_SNIFF!=msg_hdr->msg_class) { /* we only care about sniffing messages */
return msg_hdr->msg_len; /* discard non-sniffing messaged */
}
/* process sniff message payload */
buf += sizeof(struct simtrace_msg_hdr);
len -= sizeof(struct simtrace_msg_hdr);
switch (msg_hdr->msg_type) {
case SIMTRACE_MSGT_SNIFF_CHANGE:
process_change(buf, len);
break;
case SIMTRACE_MSGT_SNIFF_FIDI:
process_fidi(buf, len);
break;
case SIMTRACE_MSGT_SNIFF_ATR:
process_atr(buf, len);
break;
case SIMTRACE_MSGT_SNIFF_PPS:
process_pps(buf, len);
break;
case SIMTRACE_MSGT_SNIFF_TPDU:
process_tpdu(buf, len);
break;
default:
printf("unknown SIMtrace msg type 0x%02x\n", msg_hdr->msg_type);
break;
}
return msg_hdr->msg_len;
}
/*! Transport to SIMtrace device (e.g. USB handle) */
static struct st_transport _transp;
static void run_mainloop()
{
int rc;
uint8_t buf[16*256];
unsigned int buf_i = 0;
int xfer_len;
printf("Entering main loop\n");
while (true) {
/* read data from SIMtrace2 device (via USB) */
rc = libusb_bulk_transfer(_transp.usb_devh, _transp.usb_ep.in,
&buf[buf_i], sizeof(buf)-buf_i, &xfer_len, 100000);
if (rc < 0 && rc != LIBUSB_ERROR_TIMEOUT &&
rc != LIBUSB_ERROR_INTERRUPTED &&
rc != LIBUSB_ERROR_IO) {
fprintf(stderr, "BULK IN transfer error; rc=%d\n", rc);
return;
}
/* dispatch any incoming data */
if (xfer_len > 0) {
//printf("URB: %s\n", osmo_hexdump(&buf[buf_i], xfer_len));
buf_i += xfer_len;
if (buf_i>=sizeof(buf)) {
perror("preventing USB buffer overflow");
return;
}
int processed = process_usb_msg(buf, buf_i);
if (processed>0 && processed<=buf_i) {
for (unsigned int i=processed; i<buf_i; i++) {
buf[i-processed] = buf[i];
}
buf_i -= processed;
}
}
}
}
static void print_welcome(void)
{
printf("simtrace2-sniff - Phone-SIM card communication sniffer \n"
"(C) 2010-2017 by Harald Welte <laforge@gnumonks.org>\n"
"(C) 2018 by Kevin Redon <kredon@sysmocom.de>\n"
"\n"
);
}
static void print_help(void)
{
printf(
"\t-h\t--help\n"
"\t-i\t--gsmtap-ip\tA.B.C.D\n"
"\t-k\t--keep-running\n"
"\t-V\t--usb-vendor\tVENDOR_ID\n"
"\t-P\t--usb-product\tPRODUCT_ID\n"
"\t-C\t--usb-config\tCONFIG_ID\n"
"\t-I\t--usb-interface\tINTERFACE_ID\n"
"\t-S\t--usb-altsetting ALTSETTING_ID\n"
"\t-A\t--usb-address\tADDRESS\n"
"\n"
);
}
static const struct option opts[] = {
{ "help", 0, 0, 'h' },
{ "gsmtap-ip", 1, 0, 'i' },
{ "keep-running", 0, 0, 'k' },
{ "usb-vendor", 1, 0, 'V' },
{ "usb-product", 1, 0, 'P' },
{ "usb-config", 1, 0, 'C' },
{ "usb-interface", 1, 0, 'I' },
{ "usb-altsetting", 1, 0, 'S' },
{ "usb-address", 1, 0, 'A' },
{ NULL, 0, 0, 0 }
};
/* Known USB device with SIMtrace firmware supporting sniffer */
static const struct dev_id compatible_dev_ids[] = {
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_SIMTRACE2 },
{ 0, 0 }
};
static void signal_handler(int signal)
{
switch (signal) {
case SIGINT:
exit(0);
break;
default:
break;
}
}
int main(int argc, char **argv)
{
int rc, ret;
print_welcome();
/* Parse arguments */
char *gsmtap_host = "127.0.0.1";
int keep_running = 0;
int vendor_id = -1, product_id = -1, addr = -1, config_id = -1, if_num = -1, altsetting = -1;
while (1) {
int option_index = 0;
char c = getopt_long(argc, argv, "hi:kV:P:C:I:S:A:", opts, &option_index);
if (c == -1)
break;
switch (c) {
case 'h':
print_help();
exit(0);
break;
case 'i':
gsmtap_host = optarg;
break;
case 'k':
keep_running = 1;
break;
case 'V':
vendor_id = strtol(optarg, NULL, 16);
break;
case 'P':
product_id = strtol(optarg, NULL, 16);
break;
case 'C':
config_id = atoi(optarg);
break;
case 'I':
if_num = atoi(optarg);
break;
case 'S':
altsetting = atoi(optarg);
break;
case 'A':
addr = atoi(optarg);
break;
}
}
/* Scan for available SIMtrace USB devices supporting sniffing */
rc = libusb_init(NULL);
if (rc < 0) {
fprintf(stderr, "libusb initialization failed\n");
goto do_exit;
}
struct usb_interface_match ifm_scan[16];
int num_interfaces = usb_match_interfaces(NULL, compatible_dev_ids,
USB_CLASS_PROPRIETARY, SIMTRACE_SNIFFER_USB_SUBCLASS, -1, ifm_scan, ARRAY_SIZE(ifm_scan));
if (num_interfaces <= 0) {
perror("No compatible USB devices found");
goto do_exit;
}
/* Only keep USB matching arguments */
struct usb_interface_match ifm_filtered[ARRAY_SIZE(ifm_scan)];
int num_filtered = 0;
for (unsigned int i = 0; i < num_interfaces; i++) {
if (vendor_id>=0 && vendor_id!=ifm_scan[i].vendor) {
continue;
}
if (product_id>=0 && product_id!=ifm_scan[i].product) {
continue;
}
if (config_id>=0 && config_id!=ifm_scan[i].configuration) {
continue;
}
if (if_num>=0 && if_num!=ifm_scan[i].interface) {
continue;
}
if (altsetting>=0 && altsetting!=ifm_scan[i].altsetting) {
continue;
}
if (addr>=0 && addr!=ifm_scan[i].addr) {
continue;
}
ifm_filtered[num_filtered++] = ifm_scan[i];
}
if (1!=num_filtered) {
perror("No individual matching USB devices found");
printf("Available USB devices:\n");
for (unsigned int i = 0; i < num_interfaces; i++) {
printf("\t%04x:%04x Addr=%u, Path=%s, Cfg=%u, Intf=%u, Alt=%u: %d/%d/%d ",
ifm_scan[i].vendor, ifm_scan[i].product, ifm_scan[i].addr, ifm_scan[i].path,
ifm_scan[i].configuration, ifm_scan[i].interface, ifm_scan[i].altsetting,
ifm_scan[i].class, ifm_scan[i].sub_class, ifm_scan[i].protocol);
libusb_device_handle *dev_handle;
rc = libusb_open(ifm_scan[i].usb_dev, &dev_handle);
if (rc < 0) {
printf("\n");
perror("Cannot open device");
continue;
}
char strbuf[256];
rc = libusb_get_string_descriptor_ascii(dev_handle, ifm_scan[i].string_idx,
(unsigned char *)strbuf, sizeof(strbuf));
libusb_close(dev_handle);
if (rc < 0) {
printf("\n");
perror("Cannot read string");
continue;
}
printf("(%s)\n", strbuf);
}
goto do_exit;
}
struct usb_interface_match ifm_selected = ifm_filtered[0];
printf("Using USB device %04x:%04x Addr=%u, Path=%s, Cfg=%u, Intf=%u, Alt=%u: %d/%d/%d ",
ifm_selected.vendor, ifm_selected.product, ifm_selected.addr, ifm_selected.path,
ifm_selected.configuration, ifm_selected.interface, ifm_selected.altsetting,
ifm_selected.class, ifm_selected.sub_class, ifm_selected.protocol);
libusb_device_handle *dev_handle;
rc = libusb_open(ifm_selected.usb_dev, &dev_handle);
if (rc < 0) {
printf("\n");
perror("Cannot open device");
}
char strbuf[256];
rc = libusb_get_string_descriptor_ascii(dev_handle, ifm_selected.string_idx,
(unsigned char *)strbuf, sizeof(strbuf));
libusb_close(dev_handle);
if (rc < 0) {
printf("\n");
perror("Cannot read string");
}
printf("(%s)\n", strbuf);
g_gti = gsmtap_source_init(gsmtap_host, GSMTAP_UDP_PORT, 0);
if (!g_gti) {
perror("unable to open GSMTAP");
goto close_exit;
}
gsmtap_source_add_sink(g_gti);
signal(SIGINT, &signal_handler);
do {
_transp.usb_devh = usb_open_claim_interface(NULL, &ifm_selected);
if (!_transp.usb_devh) {
fprintf(stderr, "can't open USB device\n");
goto close_exit;
}
rc = libusb_claim_interface(_transp.usb_devh, ifm_selected.interface);
if (rc < 0) {
fprintf(stderr, "can't claim interface %d; rc=%d\n", ifm_selected.interface, rc);
goto close_exit;
}
rc = get_usb_ep_addrs(_transp.usb_devh, ifm_selected.interface, &_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;
}
run_mainloop();
ret = 0;
if (_transp.usb_devh)
libusb_release_interface(_transp.usb_devh, 0);
close_exit:
if (_transp.usb_devh)
libusb_close(_transp.usb_devh);
if (keep_running)
sleep(1);
} while (keep_running);
libusb_exit(NULL);
do_exit:
return ret;
}

View File

@@ -6,15 +6,7 @@
#include <osmocom/core/utils.h> #include <osmocom/core/utils.h>
#include "libusb_util.h" #include "libusb_util.h"
#include "simtrace_usb.h"
#define USB_VENDOR_OPENMOKO 0x1d50
#define USB_PRODUCT_OWHW_SAM3_DFU 0x4000
#define USB_PRODUCT_OWHW_SAM3 0x4001
#define USB_PRODUCT_QMOD_HUB 0x4002
#define USB_PRODUCT_QMOD_SAM3_DFU 0x4003
#define USB_PRODUCT_QMOD_SAM3 0x4004
#define USB_PRODUCT_SIMTRACE2_DFU 0x60e2
#define USB_PRODUCT_SIMTRACE2 0x60e3
static const struct dev_id compatible_dev_ids[] = { static const struct dev_id compatible_dev_ids[] = {
{ USB_VENDOR_OPENMOKO, USB_PRODUCT_OWHW_SAM3 }, { USB_VENDOR_OPENMOKO, USB_PRODUCT_OWHW_SAM3 },
@@ -23,15 +15,15 @@ static const struct dev_id compatible_dev_ids[] = {
{ 0, 0 } { 0, 0 }
}; };
//libusb_get_string_descriptor_ascii(hdl, idx, *data, len)
static int find_devices(void) static int find_devices(void)
{ {
struct usb_interface_match ifm[16]; struct usb_interface_match ifm[16];
int rc, i, num_interfaces; int rc, i, num_interfaces;
/* scan for USB devices matching SIMtrace USB ID with proprietary class */
rc = usb_match_interfaces(NULL, compatible_dev_ids, rc = usb_match_interfaces(NULL, compatible_dev_ids,
255, 2, -1, ifm, ARRAY_SIZE(ifm)); USB_CLASS_PROPRIETARY, -1, -1, ifm, ARRAY_SIZE(ifm));
printf("USB matches: %d\n", rc);
if (rc < 0) if (rc < 0)
return rc; return rc;
num_interfaces = rc; num_interfaces = rc;

1
host/simtrace_usb.h Symbolic link
View File

@@ -0,0 +1 @@
../firmware/libcommon/include/simtrace_usb.h