mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-16 21:28:33 +03:00
implement forwarding of PTS/PPS from emulator to host PC + test case
This commit is contained in:
@@ -165,6 +165,45 @@ static void flush_rx_buffer(struct card_handle *ch)
|
|||||||
* be transmitted now */
|
* be transmitted now */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* convert a non-contiguous PTS request/responsei into a contiguous
|
||||||
|
* buffer, returning the number of bytes used in the buffer */
|
||||||
|
static int serialize_pts(uint8_t *out, const uint8_t *in)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
out[i++] = in[_PTSS];
|
||||||
|
out[i++] = in[_PTS0];
|
||||||
|
if (in[_PTS0] & (1 << 4))
|
||||||
|
out[i++] = in[_PTS1];
|
||||||
|
if (in[_PTS0] & (1 << 5))
|
||||||
|
out[i++] = in[_PTS2];
|
||||||
|
if (in[_PTS0] & (1 << 6))
|
||||||
|
out[i++] = in[_PTS3];
|
||||||
|
out[i++] = in[_PCK];
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void flush_pts(struct card_handle *ch)
|
||||||
|
{
|
||||||
|
struct req_ctx *rctx;
|
||||||
|
struct cardemu_usb_msg_pts_info *ptsi;
|
||||||
|
|
||||||
|
rctx = req_ctx_find_get(0, RCTX_S_FREE, RCTX_S_UART_RX_BUSY);
|
||||||
|
if (!rctx)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ptsi = (struct cardemu_usb_msg_pts_info *) rctx->data;
|
||||||
|
ptsi->hdr.msg_type = CEMU_USB_MSGT_DO_PTS;
|
||||||
|
ptsi->hdr.data_len = serialize_pts(ptsi->req, ch->pts.req);
|
||||||
|
serialize_pts(ptsi->resp, ch->pts.resp);
|
||||||
|
|
||||||
|
req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING);
|
||||||
|
|
||||||
|
/* FIXME: call into USB code to see if this buffer can
|
||||||
|
* be transmitted now */
|
||||||
|
}
|
||||||
|
|
||||||
static void update_fidi(struct card_handle *ch)
|
static void update_fidi(struct card_handle *ch)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
@@ -310,6 +349,7 @@ process_byte_pts(struct card_handle *ch, uint8_t byte)
|
|||||||
case PTS_S_WAIT_REQ_PCK:
|
case PTS_S_WAIT_REQ_PCK:
|
||||||
ch->pts.req[_PCK] = byte;
|
ch->pts.req[_PCK] = byte;
|
||||||
/* FIXME: check PCK */
|
/* FIXME: check PCK */
|
||||||
|
/* FIXME: check if proposal matches capabilities in ATR */
|
||||||
memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
|
memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -320,6 +360,12 @@ process_byte_pts(struct card_handle *ch, uint8_t byte)
|
|||||||
/* calculate the next state and set it */
|
/* calculate the next state and set it */
|
||||||
set_pts_state(ch, next_pts_state(ch));
|
set_pts_state(ch, next_pts_state(ch));
|
||||||
|
|
||||||
|
if (ch->pts.state == PTS_S_WAIT_RESP_PTSS) {
|
||||||
|
flush_pts(ch);
|
||||||
|
/* activate UART TX to transmit PTS response */
|
||||||
|
card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
|
||||||
|
}
|
||||||
|
|
||||||
return ISO_S_IN_PTS;
|
return ISO_S_IN_PTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -180,6 +180,25 @@ static void get_and_verify_rctx(int state, const uint8_t *data, unsigned int len
|
|||||||
req_ctx_set_state(rctx, RCTX_S_FREE);
|
req_ctx_set_state(rctx, RCTX_S_FREE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void get_and_verify_rctx_pps(const uint8_t *data, unsigned int len)
|
||||||
|
{
|
||||||
|
struct req_ctx *rctx;
|
||||||
|
struct cardemu_usb_msg_pts_info *ptsi;
|
||||||
|
|
||||||
|
rctx = req_ctx_find_get(0, RCTX_S_USB_TX_PENDING, RCTX_S_USB_TX_BUSY);
|
||||||
|
assert(rctx);
|
||||||
|
dump_rctx(rctx);
|
||||||
|
|
||||||
|
ptsi = (struct cardemu_usb_msg_pts_info *) rctx->data;
|
||||||
|
/* FIXME: verify */
|
||||||
|
assert(ptsi->hdr.msg_type == CEMU_USB_MSGT_DO_PTS);
|
||||||
|
assert(!memcmp(ptsi->req, data, len));
|
||||||
|
assert(!memcmp(ptsi->resp, data, len));
|
||||||
|
|
||||||
|
/* free the req_ctx, indicating it has fully arrived on the host */
|
||||||
|
req_ctx_set_state(rctx, RCTX_S_FREE);
|
||||||
|
}
|
||||||
|
|
||||||
/* emulate a TPDU header being sent by the reader/phone */
|
/* emulate a TPDU header being sent by the reader/phone */
|
||||||
static void rdr_send_tpdu_hdr(struct card_handle *ch, const uint8_t *tpdu_hdr)
|
static void rdr_send_tpdu_hdr(struct card_handle *ch, const uint8_t *tpdu_hdr)
|
||||||
{
|
{
|
||||||
@@ -304,6 +323,27 @@ test_tpdu_card2reader(struct card_handle *ch, const uint8_t *hdr, const uint8_t
|
|||||||
card_emu_io_statechg(ch, CARD_IO_CLK, 1);
|
card_emu_io_statechg(ch, CARD_IO_CLK, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint8_t pps[] = {
|
||||||
|
/* PPSS identifies the PPS request or response and is set to
|
||||||
|
* 'FF'. */
|
||||||
|
0xFF, // PPSS
|
||||||
|
/* In PPS0, each bit 5, 6 or 7 set to 1 indicates the presence
|
||||||
|
* of an optional byte PPS 1 , PPS 2 , PPS 3 ,
|
||||||
|
* respectively. Bits 4 to 1 encode a type T to propose a
|
||||||
|
* transmission protocol. Bit 8 is reserved for future
|
||||||
|
* use and shall be set to 0. */
|
||||||
|
0b00010000, // PPS0: PPS1 present
|
||||||
|
0x00, // PPS1 proposed Fi/Di value
|
||||||
|
0xFF ^ 0b00010000// PCK
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_ppss(struct card_handle *ch)
|
||||||
|
{
|
||||||
|
reader_send_bytes(ch, pps, sizeof(pps));
|
||||||
|
get_and_verify_rctx_pps(pps, sizeof(pps));
|
||||||
|
card_tx_verify_chars(ch, pps, sizeof(pps));
|
||||||
|
}
|
||||||
|
|
||||||
/* READ RECORD (offset 0, 10 bytes) */
|
/* READ RECORD (offset 0, 10 bytes) */
|
||||||
const uint8_t tpdu_hdr_read_rec[] = { 0xA0, 0xB2, 0x00, 0x00, 0x0A };
|
const uint8_t tpdu_hdr_read_rec[] = { 0xA0, 0xB2, 0x00, 0x00, 0x0A };
|
||||||
@@ -327,6 +367,8 @@ int main(int argc, char **argv)
|
|||||||
io_start_card(ch);
|
io_start_card(ch);
|
||||||
card_tx_verify_chars(ch, NULL, 0);
|
card_tx_verify_chars(ch, NULL, 0);
|
||||||
|
|
||||||
|
test_ppss(ch);
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
test_tpdu_reader2card(ch, tpdu_hdr_write_rec, tpdu_body_write_rec, sizeof(tpdu_body_write_rec));
|
test_tpdu_reader2card(ch, tpdu_hdr_write_rec, tpdu_body_write_rec, sizeof(tpdu_body_write_rec));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user