22 Commits

Author SHA1 Message Date
Harald Welte
87c5bdf329 assert: Use printf_sync() to ensure printing of assert / panic
Change-Id: Icc202e60445d9be1cdcd61176db5ed1704d583e7
2021-06-01 18:38:25 +02:00
Kévin Redon
76c73aaa99 card_emu: use edge-triggered VCC ADC logic
Before this patch, we used to st ci->vcc_active depending on the
instantaneous ADC reading of VCC.  Is it > .5v, we claim VCC is active,
and if it's below, VCC is inactive.

With this patch we move to an edge triggered approach: Only change
ci->vcc_active if the previous reading was different from the current
reading.

FIXME: why?

Change-Id: I71b703162219484e43638f1f2f692e9dd554ef55
2021-06-01 18:38:25 +02:00
Harald Welte
e33c2907bc jenkins.sh: build 'cardem' firmware also for simtrace board
Now that it is supported, we should also build + publish the related
binaries.

Change-Id: I9231503b865adc863959d74d98e7f24f83c293e9
2021-06-01 18:38:25 +02:00
Harald Welte
0f75d6ef1e simtrace board.h: Enable HAVE_CARDEM if we build the cardem firmware
likewise, enable HAVE_SNIFFER currently only if we build the sniffer
firmware.

It's been many years too long to finally get those all merged in one
firmware :(

Change-Id: Ib433f180746f75458a44f4988643465bd846b04b
2021-06-01 18:38:21 +02:00
Harald Welte
c690a1f130 st2-cardem-pcsc: Use ATR of real card by default
Before this patch, we would always use either a hard-coded default
ATR from the source code, or we would use one that the user specified
on the command line.

The more sane default is to pass-through the real ATR of the card.

Change-Id: I75bf618a6b0d983727de4c2f19b4b48ec3e12af8
Closes: OS#5107
Requires: libosmocore.git 22117a7164012d6d88fc202cd63df79c6068484d
2021-04-25 21:30:47 +02:00
Harald Welte
8e6ba005d4 st2-cardem-pcsc: Fix goto-in-while mess
There's some code that wasnts to goto within the while loop, and there's
some other code that wants to goto after the while loop.  Don't jump
from outside the while loop into the while loop.

Change-Id: Ic2a94ad034dd259f15712687443b569f0d18ff3f
2021-04-25 21:30:47 +02:00
Harald Welte
206d613b4d contrib/jenkins.sh: Switch from rita -> ftp.osmocom.org
We should use service-aliases and not the primary host name, as
that makes migration between machines hard.

Change-Id: I34b18457268ae6f8ae3a053c5424210074a4d52e
2021-04-22 11:21:12 +02:00
Harald Welte
7b681981ea card_emu: Fix computation of waiting time
As we store the waiting time (WT) in 'etu', we must adjust the formula
from ISO 7816-3.  The 'Fi' component in the formula only exists to
compute clock cycles from the etu, which we don't need here.

Without this patch, the waiting time would be way too large (by a factor
of 372 in the default case).

Change-Id: Ia21bc7303f9b38834b5b1753983ed2a99bfc7d95
Related: OS#1704
2021-04-08 21:28:37 +00:00
Harald Welte
e410842d8e card_emu: Fix USART timer, particularly in re-start situations
The existing code started the timer once (and expired once) but didn't
properly handle re-starting of the timer.  Neither did it handle
the 'half time expiration' case.  If we want to call a function after
half the WT expiring, we must of course program the hardware for half
the timeout, and not the full timeout...

Change-Id: Ia999d97f835c27597fcd1cf7ac78bac0ab9c98c1
Related: OS#1704
2021-04-08 21:28:37 +00:00
Harald Welte
752bc7f4b5 card_emu: Use USART timeout for waiting time
Instead of using the timer/counter peripheral to handle the waiting time
and corresponding timeout, the USART peripheral internal timeout
mechanism is used.

This is particularly important for the SIMtrace board since there
(contrary to other boards) the I/O signal is not wired to a TIO pin
of the timer/counter block, and hence Rx/Tx data cannot reset that
timer/counter.

As a result of this migration, cardem is now supported not only on
owhw + qmod, but also on the simtrace board.

The guts of this change have been lifted out of Change-Id
Ibcb2c8cace9137695adf5fb3de43566f7cfb93b5 by Kevin Redon, which was
unfortunately touching various different topics at the same time and
hence was split up. Some improvements are the introduction of the
ENABLE_TX_TIMER_ONLY mode, which avoids the USART interrupt handler
getting hammered with TXRDY between release of RST and start of the ATR.

Change-Id: Ibcb2c8cace9137695adf5fb3de43566f7cfb93b5
Related: OS#1704
2021-04-08 21:28:37 +00:00
Harald Welte
7f421ef014 card_emu: explicitly initialize PTS and TPDU states
Those are already initialized at various transitions of the master
7816 FSM, but let's properly initialize them at start-up, too.

Change-Id: I81b2a8ef3284559164700d94717e4ccf008f53df
2021-04-08 21:28:37 +00:00
Harald Welte
a708ea1d99 card_emu: improve reset detection conditions
* enter ISO_S_WAIT_RST when RST is asserted
* enter ISO_S_WAIT_ATR only when we RST is released while in state ISO_S_WAIT_RST

Change-Id: I620333aa8d45561a8028b948955a27f667b58406
2021-04-08 21:28:37 +00:00
Harald Welte
c1ffc8a603 iso7816_fidi: Add iso7816_3_ prefix to symbols; fix terminology
Fi/Di are not the index into the table, but the contents of the table
as resolved by Fi_index / Di_index.  Let's clarify the terminology.

Change-Id: If364e08e7c9a3a9707e6d54b9267c6a7c088e415
2021-04-08 21:28:37 +00:00
Harald Welte
79f0ea73a2 card_emu: Clarify and differentiate F/Fi/F_index/Fi_index
The ISO7816 spec terms are well-defined, let's not abuse them. We used
to consider "Fi" as the "index into the table of F values", while the
spec actually considers Fi as the initial value for F.

Let's make sure we use the terms quite clearly:
* Fi and Di are the initial values for F and D
* F*_index and D*_index are the indexes into the ISO7816-3 Tables

Furthermore, let's track Fi separately from F, as e.g. the waiting
time definition only considers Fi as indicated in the ATR, despite
an actually different F value might have been negotiated via PTS
meanwhile.

Change-Id: Ieb2425e8380a81b79df7b2bd072902994e9c3ee7
Related: OS##1704
2021-04-08 21:28:37 +00:00
Harald Welte
9454a062b5 card_emu: Rename fi to Fi and di to Di
As we will soon introduce the distinction between Fi and F, we should
use uppercase letters, as lower-case 'f' is defined in ISO7816-3 as
the frequency, which is different from the upper-case 'F'.

Change-Id: Iaede621551520576e9b9af878fa46fbc88e59c2a
2021-04-08 21:28:37 +00:00
Kévin Redon
6b7f8d142f make sim switch board specific
the simtrace board uses a bus switch not used on qmod and owhw to
switch the SIM between physical and virtual

Change-Id: Ieaf2ed4761fc3e04f33f9aac5c04a768c9a6f71e
Related: OS#1704
2021-04-08 21:28:37 +00:00
Harald Welte
9c95162d5c card_emu: waiting_time is stored in etu, not clocks.
The comment didn't reflect the source.  I checked all users and
the code consistently stores the waiting time in units of 'etu'.

Change-Id: I2bc4a7c19cee5fb487ad639ee48ecaea706f6172
2021-04-08 21:28:37 +00:00
Oliver Smith
878fadd74f firmware: disable stack protector by default
Disable stack protector for all boards/apps by default, not only
qmod-dfu. Use 'make STACK_PROTECTOR=1' to enable.

This was recommened by Eric:
"I'd argue that we do not want this in general, since it adds canaries
to all functions that deal with buffers, and therefore impacts the
overall timing in a non determinstic way depending on inlining and
optimizations, while contributing nothing in non debug builds."

Related: OS#5081
Change-Id: I30ad97f231ea5b401def650bc9adc7e9f2770df0
2021-04-08 12:04:47 +02:00
Oliver Smith
9e0e0ddd5a firmware: qmod-dfu: disable stack protector
Prevent build failure on debian 9, ubuntu 20.04, 20.10, where
bin/qmod-dfu-flash.elf does not fit the ROM.

Fixes: OS#5081
Change-Id: I9fffe4c323094679062428f41a4246b1c1b30ca2
2021-04-07 15:23:55 +02:00
Harald Welte
7a3d93682f Revert "add library providing ISO 7816-3 utilities"
This reverts commit 4a29f64cbe.

The code replicates to a large extent what is already present in iso7816_fidi.c
and I have serious doubts about the correctness of the computation in
its iso7816_3_calculate_wt() function.

Change-Id: I80dab4401d13306d573a6a35ce8729d2acc141e4
2021-04-06 02:17:38 +02:00
Harald Welte
01868775ba Revert "add ISO 7816-3 library to remsim project"
This reverts commit 4a58c08d67.

The code replicates to a large extent what is already present in iso7816_fidi.c
and I have serious doubts about the correctness of the computation in
its iso7816_3_calculate_wt() function.

Change-Id: I3f26da4e9aa8d7b0f4b4b7992269cf365a643ec7
2021-04-06 02:17:37 +02:00
Harald Welte
9ec3de9346 simtrace2-cardem-pcsc: Make it work again
* support Interrupt STATUS notifications
* use osmocom libusb abstraction
* use asynchronous URBs for interrupt + bulk

Change-Id: Ib04798572295f25477719124530b6584780c5b75
2021-04-05 20:37:00 +02:00
11 changed files with 139 additions and 107 deletions

View File

@@ -28,7 +28,7 @@ export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="$inst/lib"
BUILDS=""
BUILDS+="simtrace/dfu simtrace/trace "
BUILDS+="simtrace/dfu simtrace/trace simtrace/cardem "
BUILDS+="qmod/dfu qmod/cardem "
BUILDS+="owhw/dfu owhw/cardem "
@@ -71,13 +71,13 @@ if [ "x$publish" = "x--publish" ]; then
$TOPDIR/contrib/prepare_upload.sh
cat > "/build/known_hosts" <<EOF
[rita.osmocom.org]:48 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDgQ9HntlpWNmh953a2Gc8NysKE4orOatVT1wQkyzhARnfYUerRuwyNr1GqMyBKdSI9amYVBXJIOUFcpV81niA7zQRUs66bpIMkE9/rHxBd81SkorEPOIS84W4vm3SZtuNqa+fADcqe88Hcb0ZdTzjKILuwi19gzrQyME2knHY71EOETe9Yow5RD2hTIpB5ecNxI0LUKDq+Ii8HfBvndPBIr0BWYDugckQ3Bocf+yn/tn2/GZieFEyFpBGF/MnLbAAfUKIdeyFRX7ufaiWWz5yKAfEhtziqdAGZaXNaLG6gkpy3EixOAy6ZXuTAk3b3Y0FUmDjhOHllbPmTOcKMry9
[rita.osmocom.org]:48 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPdWn1kEousXuKsZ+qJEZTt/NSeASxCrUfNDW3LWtH+d8Ust7ZuKp/vuyG+5pe5pwpPOgFu7TjN+0lVjYJVXH54=
[rita.osmocom.org]:48 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK8iivY70EiR5NiGChV39gRLjNpC8lvu1ZdHtdMw2zuX
[ftp.osmocom.org]:48 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDgQ9HntlpWNmh953a2Gc8NysKE4orOatVT1wQkyzhARnfYUerRuwyNr1GqMyBKdSI9amYVBXJIOUFcpV81niA7zQRUs66bpIMkE9/rHxBd81SkorEPOIS84W4vm3SZtuNqa+fADcqe88Hcb0ZdTzjKILuwi19gzrQyME2knHY71EOETe9Yow5RD2hTIpB5ecNxI0LUKDq+Ii8HfBvndPBIr0BWYDugckQ3Bocf+yn/tn2/GZieFEyFpBGF/MnLbAAfUKIdeyFRX7ufaiWWz5yKAfEhtziqdAGZaXNaLG6gkpy3EixOAy6ZXuTAk3b3Y0FUmDjhOHllbPmTOcKMry9
[ftp.osmocom.org]:48 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPdWn1kEousXuKsZ+qJEZTt/NSeASxCrUfNDW3LWtH+d8Ust7ZuKp/vuyG+5pe5pwpPOgFu7TjN+0lVjYJVXH54=
[ftp.osmocom.org]:48 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK8iivY70EiR5NiGChV39gRLjNpC8lvu1ZdHtdMw2zuX
EOF
SSH_COMMAND="ssh -o 'UserKnownHostsFile=/build/known_hosts' -p 48"
rsync --archive --verbose --compress --delete --rsh "$SSH_COMMAND" $TOPDIR/firmware/bin/*-latest.{bin,elf} binaries@rita.osmocom.org:web-files/simtrace2/firmware/latest/
rsync --archive --verbose --compress --rsh "$SSH_COMMAND" --exclude $TOPDIR/firmware/bin/*-latest.{bin,elf} $TOPDIR/firmware/bin/*-*-*-*.{bin,elf} binaries@rita.osmocom.org:web-files/simtrace2/firmware/all/
rsync --archive --verbose --compress --delete --rsh "$SSH_COMMAND" $TOPDIR/firmware/bin/*-latest.{bin,elf} binaries@ftp.osmocom.org:web-files/simtrace2/firmware/latest/
rsync --archive --verbose --compress --rsh "$SSH_COMMAND" --exclude $TOPDIR/firmware/bin/*-latest.{bin,elf} $TOPDIR/firmware/bin/*-*-*-*.{bin,elf} binaries@ftp.osmocom.org:web-files/simtrace2/firmware/all/
fi
echo

View File

@@ -178,6 +178,14 @@ CFLAGS += -ffunction-sections -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -DTRACE_L
CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
CFLAGS += -DBOARD=\"$(BOARD)\" -DBOARD_$(BOARD)
CFLAGS += -DAPPLICATION=\"$(APP)\" -DAPPLICATION_$(APP)
# Disable stack protector by default (OS#5081)
ifeq ($(STACK_PROTECTOR), 1)
CFLAGS += -fstack-protector
else
CFLAGS += -fno-stack-protector
endif
ASFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
LDFLAGS = -mcpu=cortex-m3 -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=ResetException -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--print-memory-usage -Wl,--no-undefined $(LIB)
#LD_OPTIONAL=-Wl,--print-gc-sections -Wl,--stats

View File

@@ -153,10 +153,14 @@
/** Supported modes */
/* SIMtrace board supports sniffer mode */
#ifdef APPLICATION_trace
#define HAVE_SNIFFER
#endif
/* SIMtrace board supports CCID mode */
//#define HAVE_CCID
/* SIMtrace board supports card emulation mode */
//#define HAVE_CARDEM
#ifdef APPLICATION_cardem
#define HAVE_CARDEM
#endif
/* SIMtrace board supports man-in-the-middle mode */
//#define HAVE_MITM

View File

@@ -89,7 +89,7 @@
/// \param condition Condition to verify.
#define ASSERT(condition) { \
if (!(condition)) { \
printf("-F- ASSERT: %s %s:%d\n\r", #condition, __BASE_FILE__, __LINE__); \
printf_sync("-F- ASSERT: %s %s:%d\n\r", #condition, __BASE_FILE__, __LINE__); \
while (1); \
} \
}

View File

@@ -31,7 +31,6 @@ enum card_io {
/** initialise card slot
* @param[in] slot_num slot number (arbitrary number)
* @param[in] tc_chan timer counter channel (to measure the ETU)
* @param[in] uart_chan UART peripheral channel
* @param[in] in_ep USB IN end point number
* @param[in] irq_ep USB INTerrupt end point number
@@ -40,7 +39,7 @@ enum card_io {
* @param[in] clocked initial CLK signat state (true = active)
* @return main card handle reference
*/
struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan, uint8_t in_ep, uint8_t irq_ep, bool vcc_active, bool in_reset, bool clocked);
struct card_handle *card_emu_init(uint8_t slot_num, uint8_t uart_chan, uint8_t in_ep, uint8_t irq_ep, bool vcc_active, bool in_reset, bool clocked);
/* process a single byte received from the reader */
void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte);

View File

@@ -230,9 +230,15 @@ struct cardemu_usb_msg_status {
uint32_t flags;
/* phone-applied target voltage in mV */
uint16_t voltage_mv;
/* Fi/Di related information */
uint8_t F_index; /* <! Index to ISO7816-3 Table 7 (F and f_max values) */
uint8_t D_index; /* <! Index into ISO7816-3 Table 8 (D value) */
/* F/D related information. Not actual Fn/Dn values but indexes into tables! */
union {
uint8_t F_index; /* <! Index to ISO7816-3 Table 7 (F and f_max values) */
uint8_t fi; /* <! old, wrong name for API compatibility */
};
union {
uint8_t D_index; /* <! Index to ISO7816-3 Table 8 (D value) */
uint8_t di; /* <! old, wrong name for API compatibility */
};
uint8_t wi; /* <! Waiting Integer as defined in ISO7816-3 Section 10.2 */
uint32_t waiting_time; /* <! Waiting Time in etu as defined in ISO7816-3 Section 8.1 */
} __attribute__ ((packed));

View File

@@ -176,7 +176,6 @@ struct card_handle {
* \note this depends on Fi, Di, and WI if T=0 is used */
uint32_t waiting_time; /* in etu */
uint8_t tc_chan; /* TC channel number */
uint8_t uart_chan; /* UART channel */
uint8_t in_ep; /* USB IN EP */
@@ -431,7 +430,7 @@ static void card_set_state(struct card_handle *ch,
/* update waiting time to initial waiting time */
ch->waiting_time = ISO7816_3_INIT_WTIME;
/* set initial waiting time */
card_emu_uart_update_wt(ch->tc_chan, ch->waiting_time);
card_emu_uart_update_wt(ch->uart_chan, ch->waiting_time);
/* Set ATR sub-state to initial state */
ch->atr.idx = 0;
/* enable USART transmission to reader */
@@ -506,8 +505,11 @@ static int tx_byte_atr(struct card_handle *ch)
}
}
}
/* update waiting time (see ISO 7816-3 10.2) */
ch->waiting_time = ch->wi * 960 * iso7816_3_fi_table[ch->F_index];
/* update waiting time (see ISO 7816-3 10.2). We can drop the Fi
* multiplier as we store the waiting time in units of 'etu', and
* don't really care what the number of clock cycles or the absolute
* wall clock time is */
ch->waiting_time = ch->wi * 960;
/* go to next state */
card_set_state(ch, ISO_S_WAIT_TPDU);
return 0;
@@ -1245,7 +1247,7 @@ int card_emu_set_config(struct card_handle *ch, const struct cardemu_usb_msg_con
return 0;
}
struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan, uint8_t in_ep, uint8_t irq_ep, bool vcc_active, bool in_reset, bool clocked)
struct card_handle *card_emu_init(uint8_t slot_num, uint8_t uart_chan, uint8_t in_ep, uint8_t irq_ep, bool vcc_active, bool in_reset, bool clocked)
{
struct card_handle *ch;
@@ -1270,7 +1272,6 @@ struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uar
ch->Di_index = ch->D_index = 1;
ch->wi = ISO7816_3_DEFAULT_WI;
ch->tc_chan = tc_chan;
ch->uart_chan = uart_chan;
ch->waiting_time = ISO7816_3_INIT_WTIME;

View File

@@ -213,6 +213,22 @@ int card_emu_uart_tx(uint8_t uart_chan, uint8_t byte)
return 1;
}
static uint16_t compute_next_timeout(struct cardem_inst *ci)
{
uint32_t want_to_expire;
if (ci->wt.total == 0)
return 0;
if (!ci->wt.half_time_notified) {
/* we need to make sure to expire after half the total waiting time */
OSMO_ASSERT(ci->wt.remaining > (ci->wt.total / 2));
want_to_expire = ci->wt.remaining - (ci->wt.total / 2);
} else
want_to_expire = ci->wt.remaining;
/* if value exceeds the USART TO range, use the maximum possible value for one round */
return OSMO_MIN(want_to_expire, 0xffff);
}
/*! common handler if interrupt was received.
* \param[in] inst_num Instance number, range 0..1 (some boards only '0' permitted) */
@@ -256,6 +272,9 @@ static void usart_irq_rx(uint8_t inst_num)
* how many etu have expired since we last sent a byte. See section
* 33.7.3.11 "Receiver Time-out" of the SAM3S8 Data Sheet */
if (csr & US_CSR_TIMEOUT) {
/* clear timeout flag (and stop timeout until next character is received) */
usart->US_CR |= US_CR_STTTO;
/* RX has been inactive for some time */
if (ci->wt.remaining <= (usart->US_RTOR & 0xffff)) {
/* waiting time is over; will stop the timer */
@@ -268,17 +287,26 @@ static void usart_irq_rx(uint8_t inst_num)
if (ci->wt.remaining == 0) {
/* let the FSM know that WT has expired */
card_emu_wtime_expired(ci->ch);
} else if (ci->wt.remaining <= ci->wt.total / 2 && !ci->wt.half_time_notified) {
/* let the FS know that half of the WT has expired */
card_emu_wtime_half_expired(ci->ch);
ci->wt.half_time_notified = true;
/* don't automatically re-start in this case */
} else {
bool half_time_just_reached = false;
if (ci->wt.remaining <= ci->wt.total / 2 && !ci->wt.half_time_notified) {
ci->wt.half_time_notified = true;
/* don't immediately call card_emu_wtime_half_expired(), as that
* in turn may calls card_emu_uart_update_wt() which will change
* the timeout but would be overridden 4 lines below */
half_time_just_reached = true;
}
/* update the counter no matter if we reached half time or not */
usart->US_RTOR = compute_next_timeout(ci);
/* restart the counter (if wt is 0, the timeout is not started) */
usart->US_CR |= US_CR_RETTO;
if (half_time_just_reached)
card_emu_wtime_half_expired(ci->ch);
}
/* if value exceeds the USART TO range, use the maximum for now */
usart->US_RTOR = OSMO_MIN(ci->wt.remaining, 0xffff);
/* clear timeout flag (and stop timeout until next character is received) */
usart->US_CR |= US_CR_STTTO;
/* restart the counter (it wt is 0, the timeout is not started) */
usart->US_CR |= US_CR_RETTO;
}
}
@@ -317,10 +345,14 @@ void card_emu_uart_update_wt(uint8_t uart_chan, uint32_t wt)
struct cardem_inst *ci = &cardem_inst[uart_chan];
Usart *usart = get_usart_by_chan(uart_chan);
if (ci->wt.total != wt) {
TRACE_DEBUG("%u: USART WT changed from %lu to %lu ETU\r\n", uart_chan,
ci->wt.total, wt);
}
ci->wt.total = wt;
/* reset and start the timer */
card_emu_uart_reset_wt(uart_chan);
TRACE_INFO("%u: USART WT set to %lu ETU\r\n", uart_chan, wt);
}
/*! Reset and re-start waiting timeout count down on USART peripheral.
@@ -334,8 +366,7 @@ void card_emu_uart_reset_wt(uint8_t uart_chan)
/* FIXME: guard against race with interrupt handler */
ci->wt.remaining = ci->wt.total;
ci->wt.half_time_notified = false;
/* if value exceeds the USART TO range, use the maximum for now */
usart->US_RTOR = OSMO_MIN(ci->wt.remaining, 0xffff);
usart->US_RTOR = compute_next_timeout(ci);
/* restart the counter (if wt is 0, the timeout is not started) */
usart->US_CR |= US_CR_RETTO;
}
@@ -520,20 +551,7 @@ void mode_cardemu_init(void)
/* configure USART as ISO-7816 slave (e.g. card) */
ISO7816_Init(&cardem_inst[0].usart_info, CLK_SLAVE);
#ifdef BOARD_simtrace
/* simtrace board uses uart timeouts */
/* don't use receive timeout timer for now */
cardem_inst[0].usart_info.base->US_RTOR = 0;
/* enable interrupts to indicate when data has been received or timeout occurred */
USART_EnableIt(cardem_inst[0].usart_info.base, US_IER_RXRDY | US_IER_TIMEOUT);
#else
/* enable interrupts to indicate when data has been received */
USART_EnableIt(cardem_inst[0].usart_info.base, US_IER_RXRDY );
#endif
/* enable interrupt requests for the USART peripheral */
NVIC_EnableIRQ(USART1_IRQn);
PIO_ConfigureIt(&pin_usim1_rst, usim1_rst_irqhandler);
PIO_EnableIt(&pin_usim1_rst);
@@ -549,7 +567,7 @@ void mode_cardemu_init(void)
do {} while (!adc_triggered); /* wait for first ADC reading */
#endif /* DETECT_VCC_BY_ADC */
cardem_inst[0].ch = card_emu_init(0, 2, 0, SIMTRACE_CARDEM_USB_EP_USIM1_DATAIN,
cardem_inst[0].ch = card_emu_init(0, 0, SIMTRACE_CARDEM_USB_EP_USIM1_DATAIN,
SIMTRACE_CARDEM_USB_EP_USIM1_INT, cardem_inst[0].vcc_active,
cardem_inst[0].rst_active, cardem_inst[0].vcc_active);
sim_switch_use_physical(0, 1);
@@ -572,7 +590,7 @@ void mode_cardemu_init(void)
do {} while (!adc_triggered); /* wait for first ADC reading */
#endif /* DETECT_VCC_BY_ADC */
cardem_inst[1].ch = card_emu_init(1, 0, 1, SIMTRACE_CARDEM_USB_EP_USIM2_DATAIN,
cardem_inst[1].ch = card_emu_init(1, 1, SIMTRACE_CARDEM_USB_EP_USIM2_DATAIN,
SIMTRACE_CARDEM_USB_EP_USIM2_INT, cardem_inst[1].vcc_active,
cardem_inst[1].rst_active, cardem_inst[1].vcc_active);
sim_switch_use_physical(1, 1);

View File

@@ -46,7 +46,7 @@ static osmo_panic_handler_t osmo_panic_handler = (void*)0;
__attribute__ ((format (printf, 1, 0)))
static void osmo_panic_default(const char *fmt, va_list args)
{
vfprintf(stderr, fmt, args);
vfprintf_sync(stderr, fmt, args);
osmo_generate_backtrace();
assert(0);
}

View File

@@ -13,6 +13,20 @@
#define PHONE_INT 2
#define PHONE_DATAOUT 3
/* stub for stdio */
signed int printf_sync(const char *pFormat, ...)
{
va_list ap;
signed int result;
va_start(ap, pFormat);
result = vprintf(pFormat, ap);
va_end(ap);
return result;
}
/***********************************************************************
* stub functions required by card_emu.c
***********************************************************************/
@@ -50,6 +64,9 @@ void card_emu_uart_enable(uint8_t uart_chan, uint8_t rxtx)
case ENABLE_TX:
rts = "TX";
break;
case ENABLE_TX_TIMER_ONLY:
rts = "TX-TIMER-ONLY";
break;
case ENABLE_RX:
rts = "RX";
break;
@@ -66,29 +83,14 @@ void card_emu_uart_interrupt(uint8_t uart_chan)
printf("uart_interrupt(uart_chan=%u)\n", uart_chan);
}
void tc_etu_set_wtime(uint8_t tc_chan, uint16_t wtime)
void card_emu_uart_update_wt(uint8_t uart_chan, uint32_t wt)
{
printf("tc_etu_set_wtime(tc_chan=%u, wtime=%u)\n", tc_chan, wtime);
printf("%s(uart_chan=%u, wtime=%u)\n", __func__, uart_chan, wt);
}
void tc_etu_set_etu(uint8_t tc_chan, uint16_t etu)
void card_emu_uart_reset_wt(uint8_t uart_chan)
{
printf("tc_etu_set_etu(tc_chan=%u, etu=%u)\n", tc_chan, etu);
}
void tc_etu_init(uint8_t chan_nr, void *handle)
{
printf("tc_etu_init(tc_chan=%u)\n", chan_nr);
}
void tc_etu_enable(uint8_t chan_nr)
{
printf("tc_etu_enable(tc_chan=%u)\n", chan_nr);
}
void tc_etu_disable(uint8_t chan_nr)
{
printf("tc_etu_disable(tc_chan=%u)\n", chan_nr);
printf("%s(uart_chan=%u\n", __func__, uart_chan);
}
@@ -136,7 +138,7 @@ static void io_start_card(struct card_handle *ch)
/* release from reset and verify th ATR */
card_emu_io_statechg(ch, CARD_IO_RST, 0);
/* simulate waiting time before ATR expired */
tc_etu_wtime_expired(ch);
card_emu_wtime_expired(ch);
verify_atr(ch);
}
@@ -408,7 +410,7 @@ int main(int argc, char **argv)
struct card_handle *ch;
unsigned int i;
ch = card_emu_init(0, 23, 42, PHONE_DATAIN, PHONE_INT, false, true, false);
ch = card_emu_init(0, 42, PHONE_DATAIN, PHONE_INT, false, true, false);
assert(ch);
usb_buf_init();

View File

@@ -1,7 +1,7 @@
/* simtrace2-cardem-pcsc - main program for the host PC to provide a remote SIM
* using the SIMtrace 2 firmware in card emulation mode
*
* (C) 2016-2020 by Harald Welte <hwelte@hmw-consulting.de>
* (C) 2016-2021 by Harald Welte <hwelte@hmw-consulting.de>
* (C) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
*
* This program is free software; you can redistribute it and/or
@@ -51,29 +51,8 @@
#include <osmocom/sim/class_tables.h>
#include <osmocom/sim/sim.h>
#define ATR_MAX_LEN 33
#define LOGCI(ci, lvl, fmt, args ...) printf(fmt, ## args)
/* reasonable ATR offering all protocols and voltages
* smartphones might not care, but other readers do
*
* TS = 0x3B Direct Convention
* T0 = 0x80 Y(1): b1000, K: 0 (historical bytes)
* TD(1) = 0x80 Y(i+1) = b1000, Protocol T=0
* ----
* TD(2) = 0x81 Y(i+1) = b1000, Protocol T=1
* ----
* TD(3) = 0x1F Y(i+1) = b0001, Protocol T=15
* ----
* TA(4) = 0xC7 Clock stop: no preference - Class accepted by the card: (3G) A 5V B 3V C 1.8V
* ----
* Historical bytes
* TCK = 0x59 correct checksum
*/
#define DEFAULT_ATR_STR "3B8080811FC759"
static void atr_update_csum(uint8_t *atr, unsigned int atr_len)
{
uint8_t csum = 0;
@@ -200,7 +179,7 @@ static int process_irq_status(struct osmo_st2_cardem_inst *ci, const uint8_t *bu
const struct cardemu_usb_msg_status *status = (struct cardemu_usb_msg_status *) buf;
LOGCI(ci, LOGL_INFO, "SIMtrace IRQ STATUS: flags=0x%x, fi=%u, di=%u, wi=%u wtime=%u\n",
status->flags, status->F_index, status->D_index, status->wi,
status->flags, status->fi, status->di, status->wi,
status->waiting_time);
return 0;
@@ -415,9 +394,9 @@ int main(int argc, char **argv)
int rc;
int c, ret = 1;
int skip_atr = 0;
char *atr = DEFAULT_ATR_STR;
uint8_t real_atr[ATR_MAX_LEN];
int atr_len;
char *atr = NULL;
uint8_t override_atr[OSIM_MAX_ATR_LEN];
int override_atr_len = 0;
int keep_running = 0;
int if_num = 0, vendor_id = -1, product_id = -1;
int config_id = -1, altsetting = 0, addr = -1;
@@ -484,11 +463,13 @@ int main(int argc, char **argv)
}
}
atr_len = osmo_hexparse(atr,real_atr,ATR_MAX_LEN);
if (atr_len < 2) {
fprintf(stderr, "Invalid ATR - please omit a leading 0x and only use valid hex "
"digits and whitespace. ATRs need to be between 2 and 33 bytes long.\n");
goto do_exit;
if (atr) {
override_atr_len = osmo_hexparse(atr, override_atr, sizeof(override_atr));
if (override_atr_len < 2) {
fprintf(stderr, "Invalid ATR - please omit a leading 0x and only use valid hex "
"digits and whitespace. ATRs need to be between 2 and 33 bytes long.\n");
goto do_exit;
}
}
if (vendor_id < 0 || product_id < 0) {
@@ -545,20 +526,20 @@ int main(int argc, char **argv)
transp->usb_devh = osmo_libusb_open_claim_interface(NULL, NULL, ifm);
if (!transp->usb_devh) {
fprintf(stderr, "can't open USB device\n");
goto close_exit;
goto close;
}
rc = libusb_claim_interface(transp->usb_devh, if_num);
if (rc < 0) {
fprintf(stderr, "can't claim interface %d; rc=%d\n", if_num, rc);
goto close_exit;
goto close;
}
rc = osmo_libusb_get_ep_addrs(transp->usb_devh, if_num, &transp->usb_ep.out,
&transp->usb_ep.in, &transp->usb_ep.irq_in);
if (rc < 0) {
fprintf(stderr, "can't obtain EP addrs; rc=%d\n", rc);
goto close_exit;
goto close;
}
allocate_and_submit_irq(ci);
@@ -576,8 +557,14 @@ int main(int argc, char **argv)
if (!skip_atr) {
/* set the ATR */
atr_update_csum(real_atr, atr_len);
osmo_st2_cardem_request_set_atr(ci, real_atr, atr_len);
if (override_atr_len) {
/* user has specified an override-ATR */
atr_update_csum(override_atr, override_atr_len);
osmo_st2_cardem_request_set_atr(ci, override_atr, override_atr_len);
} else {
/* use the real ATR of the card */
osmo_st2_cardem_request_set_atr(ci, card->atr, card->atr_len);
}
}
/* select remote (forwarded) SIM */
@@ -587,13 +574,20 @@ int main(int argc, char **argv)
ret = 0;
libusb_release_interface(transp->usb_devh, 0);
close_exit:
if (transp->usb_devh)
close:
if (transp->usb_devh) {
libusb_close(transp->usb_devh);
transp->usb_devh = NULL;
}
if (keep_running)
sleep(1);
} while (keep_running);
close_exit:
if (transp->usb_devh)
libusb_close(transp->usb_devh);
libusb_exit(NULL);
do_exit:
return ret;