blob: 75a8a993142e7f18c180f6801b7287c879d9ee41 [file] [log] [blame]
Harald Welte9d3e3822015-11-09 00:50:54 +01001#include <stdint.h>
2#include <stdio.h>
3#include <string.h>
4#include <assert.h>
5#include <stdlib.h>
6
7#include "card_emu.h"
8#include "cardemu_prot.h"
9#include "tc_etu.h"
Harald Welte8e7fca32017-05-07 16:14:33 +020010#include "usb_buf.h"
11
12#define PHONE_DATAIN 1
13#define PHONE_INT 2
14#define PHONE_DATAOUT 3
Harald Welte9d3e3822015-11-09 00:50:54 +010015
16/* stub functions required by card_emu.c */
17
Harald Weltea1cd0f32017-02-27 14:29:07 +010018void card_emu_uart_wait_tx_idle(uint8_t uart_chan)
19{
20}
21
Harald Welte9d3e3822015-11-09 00:50:54 +010022int card_emu_uart_update_fidi(uint8_t uart_chan, unsigned int fidi)
23{
24 printf("uart_update_fidi(uart_chan=%u, fidi=%u)\n", uart_chan, fidi);
25 return 0;
26}
27
Harald Welte86d047b2016-02-25 00:26:17 +010028/* a buffer in which we store those bytes send by the UART towards the card
29 * reader, so we can verify in test cases what was actually written */
30static uint8_t tx_debug_buf[1024];
31static unsigned int tx_debug_buf_idx;
32
Harald Welte9d3e3822015-11-09 00:50:54 +010033int card_emu_uart_tx(uint8_t uart_chan, uint8_t byte)
34{
Harald Welte6bf8c122016-02-24 21:04:08 +010035 printf("UART_TX(%02x)\n", byte);
Harald Welte86d047b2016-02-25 00:26:17 +010036 tx_debug_buf[tx_debug_buf_idx++] = byte;
Harald Welte9d3e3822015-11-09 00:50:54 +010037 return 1;
38}
39
Harald Welte86d047b2016-02-25 00:26:17 +010040static void reader_check_and_clear(const uint8_t *data, unsigned int len)
41{
42 assert(len == tx_debug_buf_idx);
43 assert(!memcmp(tx_debug_buf, data, len));
44 tx_debug_buf_idx = 0;
45}
46
Harald Welte9d3e3822015-11-09 00:50:54 +010047void card_emu_uart_enable(uint8_t uart_chan, uint8_t rxtx)
48{
Harald Welteb4362862015-11-14 19:02:33 +010049 char *rts;
50 switch (rxtx) {
51 case 0:
52 rts = "OFF";
53 break;
54 case ENABLE_TX:
55 rts = "TX";
56 break;
57 case ENABLE_RX:
58 rts = "RX";
59 break;
60 default:
61 rts = "unknown";
62 break;
63 };
64
65 printf("uart_enable(uart_chan=%u, %s)\n", uart_chan, rts);
Harald Welte9d3e3822015-11-09 00:50:54 +010066}
67
68void tc_etu_set_wtime(uint8_t tc_chan, uint16_t wtime)
69{
70 printf("tc_etu_set_wtime(tc_chan=%u, wtime=%u)\n", tc_chan, wtime);
71}
72
73void tc_etu_set_etu(uint8_t tc_chan, uint16_t etu)
74{
75 printf("tc_etu_set_etu(tc_chan=%u, etu=%u)\n", tc_chan, etu);
76}
77
78void tc_etu_init(uint8_t chan_nr, void *handle)
79{
Harald Welte6bf8c122016-02-24 21:04:08 +010080 printf("tc_etu_init(tc_chan=%u)\n", chan_nr);
Harald Welte9d3e3822015-11-09 00:50:54 +010081}
82
Harald Welte6bf8c122016-02-24 21:04:08 +010083void tc_etu_enable(uint8_t chan_nr)
84{
85 printf("tc_etu_enable(tc_chan=%u)\n", chan_nr);
86}
Harald Welte9d3e3822015-11-09 00:50:54 +010087
Harald Welte6bf8c122016-02-24 21:04:08 +010088void tc_etu_disable(uint8_t chan_nr)
89{
90 printf("tc_etu_disable(tc_chan=%u)\n", chan_nr);
91}
Harald Welte9d3e3822015-11-09 00:50:54 +010092
Harald Welte86d047b2016-02-25 00:26:17 +010093const uint8_t atr[] = { 0x3b, 0x02, 0x14, 0x50 };
Harald Welte9d3e3822015-11-09 00:50:54 +010094
95static int verify_atr(struct card_handle *ch)
96{
Harald Welte9d3e3822015-11-09 00:50:54 +010097 unsigned int i;
98
Harald Welte6bf8c122016-02-24 21:04:08 +010099 printf("receiving + verifying ATR:\n");
Harald Welte9d3e3822015-11-09 00:50:54 +0100100 for (i = 0; i < sizeof(atr); i++) {
Harald Welte6bf8c122016-02-24 21:04:08 +0100101 assert(card_emu_tx_byte(ch) == 1);
Harald Welte9d3e3822015-11-09 00:50:54 +0100102 }
Harald Welte6bf8c122016-02-24 21:04:08 +0100103 assert(card_emu_tx_byte(ch) == 0);
Harald Welte86d047b2016-02-25 00:26:17 +0100104 reader_check_and_clear(atr, sizeof(atr));
Harald Welte9d3e3822015-11-09 00:50:54 +0100105
106 return 1;
107}
108
109static void io_start_card(struct card_handle *ch)
110{
Harald Welte86d047b2016-02-25 00:26:17 +0100111 card_emu_set_atr(ch, atr, sizeof(atr));
112
Harald Welte9d3e3822015-11-09 00:50:54 +0100113 /* bring the card up from the dead */
114 card_emu_io_statechg(ch, CARD_IO_VCC, 1);
Harald Welte6bf8c122016-02-24 21:04:08 +0100115 assert(card_emu_tx_byte(ch) == 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100116 card_emu_io_statechg(ch, CARD_IO_CLK, 1);
Harald Welte6bf8c122016-02-24 21:04:08 +0100117 assert(card_emu_tx_byte(ch) == 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100118 card_emu_io_statechg(ch, CARD_IO_RST, 1);
Harald Welte6bf8c122016-02-24 21:04:08 +0100119 assert(card_emu_tx_byte(ch) == 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100120
121 /* release from reset and verify th ATR */
122 card_emu_io_statechg(ch, CARD_IO_RST, 0);
123 verify_atr(ch);
124}
125
Harald Welteeef6c2a2016-02-24 22:19:03 +0100126static void reader_send_bytes(struct card_handle *ch, const uint8_t *bytes, unsigned int len)
Harald Welte9d3e3822015-11-09 00:50:54 +0100127{
128 unsigned int i;
Harald Welte84ec2522015-11-14 23:03:50 +0100129 for (i = 0; i < len; i++) {
130 printf("UART_RX(%02x)\n", bytes[i]);
Harald Welte9d3e3822015-11-09 00:50:54 +0100131 card_emu_process_rx_byte(ch, bytes[i]);
Harald Welte84ec2522015-11-14 23:03:50 +0100132 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100133}
134
Harald Welte8e7fca32017-05-07 16:14:33 +0200135static void dump_rctx(struct msgb *msg)
Harald Welte9d3e3822015-11-09 00:50:54 +0100136{
137 struct cardemu_usb_msg_hdr *mh =
Harald Welte8e7fca32017-05-07 16:14:33 +0200138 (struct cardemu_usb_msg_hdr *) msg->l1h;
Harald Welte9d3e3822015-11-09 00:50:54 +0100139 struct cardemu_usb_msg_rx_data *rxd;
140 int i;
Harald Welte8e7fca32017-05-07 16:14:33 +0200141#if 0
Harald Welte9d3e3822015-11-09 00:50:54 +0100142
143 printf("req_ctx(%p): state=%u, size=%u, tot_len=%u, idx=%u, data=%p\n",
144 rctx, rctx->state, rctx->size, rctx->tot_len, rctx->idx, rctx->data);
Harald Weltea1cd0f32017-02-27 14:29:07 +0100145 printf(" msg_type=%u, seq_nr=%u, msg_len=%u\n",
146 mh->msg_type, mh->seq_nr, mh->msg_len);
Harald Welte8e7fca32017-05-07 16:14:33 +0200147#endif
148 printf("%s\n", msgb_hexdump(msg));
Harald Welte9d3e3822015-11-09 00:50:54 +0100149
150 switch (mh->msg_type) {
151 case CEMU_USB_MSGT_DO_RX_DATA:
152 rxd = (struct cardemu_usb_msg_rx_data *)mh;
153 printf(" flags=%x, data=", rxd->flags);
Harald Welted295b922016-03-18 21:01:36 +0100154 for (i = 0; i < rxd->data_len; i++)
Harald Welte9d3e3822015-11-09 00:50:54 +0100155 printf(" %02x", rxd->data[i]);
156 printf("\n");
157 break;
158 }
159}
160
Harald Welte8e7fca32017-05-07 16:14:33 +0200161static void get_and_verify_rctx(uint8_t ep, const uint8_t *data, unsigned int len)
Harald Welte0ab6fcd2016-02-25 00:08:22 +0100162{
Harald Welte8e7fca32017-05-07 16:14:33 +0200163 struct llist_head *queue = usb_get_queue(ep);
164 struct msgb *msg;
Harald Welte0ab6fcd2016-02-25 00:08:22 +0100165 struct cardemu_usb_msg_tx_data *td;
166 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200167 struct cardemu_usb_msg_hdr *mh;
Harald Welte0ab6fcd2016-02-25 00:08:22 +0100168
Harald Welte8e7fca32017-05-07 16:14:33 +0200169 assert(queue);
170 msg = msgb_dequeue(queue);
171 assert(msg);
172 dump_rctx(msg);
173 assert(msg->l1h);
174 mh = (struct cardemu_usb_msg_hdr *) msg->l1h;
Harald Welte0ab6fcd2016-02-25 00:08:22 +0100175
176 /* verify the contents of the rctx */
Harald Welte8e7fca32017-05-07 16:14:33 +0200177 switch (mh->msg_type) {
178 case CEMU_USB_MSGT_DO_RX_DATA:
179 rd = (struct cardemu_usb_msg_rx_data *) msg->l1h;
180 assert(rd->hdr.msg_type == CEMU_USB_MSGT_DO_RX_DATA);
181 assert(rd->data_len == len);
182 assert(!memcmp(rd->data, data, len));
Harald Welte0ab6fcd2016-02-25 00:08:22 +0100183 break;
184#if 0
185 case RCTX_S_UART_RX_PENDING:
186 rd = (struct cardemu_usb_msg_rx_data *) rctx->data;
Harald Welted295b922016-03-18 21:01:36 +0100187 assert(rd->data_len == len);
Harald Welte0ab6fcd2016-02-25 00:08:22 +0100188 assert(!memcmp(rd->data, data, len));
189 break;
190#endif
191 default:
192 assert(0);
193 }
194
195 /* free the req_ctx, indicating it has fully arrived on the host */
Harald Welte8e7fca32017-05-07 16:14:33 +0200196 usb_buf_free(msg);
Harald Welte0ab6fcd2016-02-25 00:08:22 +0100197}
198
Harald Welte4ba66d02016-02-25 19:38:56 +0100199static void get_and_verify_rctx_pps(const uint8_t *data, unsigned int len)
200{
Harald Welte8e7fca32017-05-07 16:14:33 +0200201 struct llist_head *queue = usb_get_queue(PHONE_DATAIN);
202 struct msgb *msg;
Harald Welte4ba66d02016-02-25 19:38:56 +0100203 struct cardemu_usb_msg_pts_info *ptsi;
204
Harald Welte8e7fca32017-05-07 16:14:33 +0200205 assert(queue);
206 msg = msgb_dequeue(queue);
207 assert(msg);
208 dump_rctx(msg);
209 assert(msg->l1h);
Harald Welte4ba66d02016-02-25 19:38:56 +0100210
Harald Welte8e7fca32017-05-07 16:14:33 +0200211 ptsi = (struct cardemu_usb_msg_pts_info *) msg->l1h;
Harald Welte4ba66d02016-02-25 19:38:56 +0100212 /* FIXME: verify */
213 assert(ptsi->hdr.msg_type == CEMU_USB_MSGT_DO_PTS);
214 assert(!memcmp(ptsi->req, data, len));
215 assert(!memcmp(ptsi->resp, data, len));
216
217 /* free the req_ctx, indicating it has fully arrived on the host */
Harald Welte8e7fca32017-05-07 16:14:33 +0200218 usb_buf_free(msg);
Harald Welte4ba66d02016-02-25 19:38:56 +0100219}
220
Harald Welteb4362862015-11-14 19:02:33 +0100221/* emulate a TPDU header being sent by the reader/phone */
Harald Welteeef6c2a2016-02-24 22:19:03 +0100222static void rdr_send_tpdu_hdr(struct card_handle *ch, const uint8_t *tpdu_hdr)
Harald Welte9d3e3822015-11-09 00:50:54 +0100223{
Harald Welte8e7fca32017-05-07 16:14:33 +0200224 struct llist_head *queue = usb_get_queue(PHONE_DATAIN);
225
Harald Welte9d3e3822015-11-09 00:50:54 +0100226 /* we don't want a receive context to become available during
227 * the first four bytes */
Harald Welteeef6c2a2016-02-24 22:19:03 +0100228 reader_send_bytes(ch, tpdu_hdr, 4);
Harald Welte8e7fca32017-05-07 16:14:33 +0200229 assert(llist_empty(queue));
Harald Welte9d3e3822015-11-09 00:50:54 +0100230
Harald Welteeef6c2a2016-02-24 22:19:03 +0100231 reader_send_bytes(ch, tpdu_hdr+4, 1);
Harald Welte9d3e3822015-11-09 00:50:54 +0100232 /* but then after the final byte of the TPDU header, we want a
233 * receive context to be available for USB transmission */
Harald Welte8e7fca32017-05-07 16:14:33 +0200234 get_and_verify_rctx(PHONE_DATAIN, tpdu_hdr, 5);
Harald Welteb4362862015-11-14 19:02:33 +0100235}
236
237/* emulate a CEMU_USB_MSGT_DT_TX_DATA received from USB */
Harald Welte8e7fca32017-05-07 16:14:33 +0200238static void host_to_device_data(struct card_handle *ch, const uint8_t *data, uint16_t len,
239 unsigned int flags)
Harald Welteb4362862015-11-14 19:02:33 +0100240{
Harald Welte8e7fca32017-05-07 16:14:33 +0200241 struct msgb *msg;
Harald Welte84ec2522015-11-14 23:03:50 +0100242 struct cardemu_usb_msg_tx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200243 struct llist_head *queue;
Harald Welteb4362862015-11-14 19:02:33 +0100244
245 /* allocate a free req_ctx */
Harald Welte8e7fca32017-05-07 16:14:33 +0200246 msg = usb_buf_alloc(PHONE_DATAOUT);
247 assert(msg);
248 msg->l1h = msg->head;
Harald Welteb4362862015-11-14 19:02:33 +0100249
250 /* initialize the header */
Harald Welte8e7fca32017-05-07 16:14:33 +0200251 rd = (struct cardemu_usb_msg_tx_data *) msgb_put(msg, sizeof(*rd) + len);
Harald Welteb4362862015-11-14 19:02:33 +0100252 cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DT_TX_DATA);
Harald Welteeef6c2a2016-02-24 22:19:03 +0100253 rd->flags = flags;
Harald Welteb4362862015-11-14 19:02:33 +0100254 /* copy data and set length */
Harald Welted295b922016-03-18 21:01:36 +0100255 rd->data_len = len;
Harald Welteb4362862015-11-14 19:02:33 +0100256 memcpy(rd->data, data, len);
Harald Welted295b922016-03-18 21:01:36 +0100257 rd->hdr.msg_len = sizeof(*rd) + len;
Harald Welteb4362862015-11-14 19:02:33 +0100258
259 /* hand the req_ctx to the UART transmit code */
Harald Welte8e7fca32017-05-07 16:14:33 +0200260 queue = card_emu_get_uart_tx_queue(ch);
261 assert(queue);
262 msgb_enqueue(queue, msg);
Harald Welteb4362862015-11-14 19:02:33 +0100263}
264
Harald Welteeef6c2a2016-02-24 22:19:03 +0100265/* card-transmit any pending characters */
Harald Welte86d047b2016-02-25 00:26:17 +0100266static int card_tx_verify_chars(struct card_handle *ch, const uint8_t *data, unsigned int data_len)
Harald Welteb4362862015-11-14 19:02:33 +0100267{
Harald Welteb4362862015-11-14 19:02:33 +0100268 int count = 0;
269
Harald Welte6bf8c122016-02-24 21:04:08 +0100270 while (card_emu_tx_byte(ch)) {
Harald Welteb4362862015-11-14 19:02:33 +0100271 count++;
272 }
Harald Welte86d047b2016-02-25 00:26:17 +0100273
274 assert(count == data_len);
275 reader_check_and_clear(data, data_len);
276
Harald Welteb4362862015-11-14 19:02:33 +0100277 return count;
Harald Welte9d3e3822015-11-09 00:50:54 +0100278}
279
Harald Welte84ec2522015-11-14 23:03:50 +0100280const uint8_t tpdu_hdr_sel_mf[] = { 0xA0, 0xA4, 0x00, 0x00, 0x00 };
Harald Welte61bb30e2015-11-14 23:44:14 +0100281const uint8_t tpdu_pb_sw[] = { 0x90, 0x00 };
Harald Welte9d3e3822015-11-09 00:50:54 +0100282
Harald Weltec043e642016-02-24 23:26:55 +0100283static void
284test_tpdu_reader2card(struct card_handle *ch, const uint8_t *hdr, const uint8_t *body, uint8_t body_len)
285{
Harald Weltec043e642016-02-24 23:26:55 +0100286 printf("\n==> transmitting APDU (HDR + PB + card-RX)\n");
287
288 /* emulate the reader sending a TPDU header */
289 rdr_send_tpdu_hdr(ch, hdr);
290 /* we shouldn't have any pending card-TX yet */
Harald Welte86d047b2016-02-25 00:26:17 +0100291 card_tx_verify_chars(ch, NULL, 0);
Harald Welte0ab6fcd2016-02-25 00:08:22 +0100292
Harald Weltec043e642016-02-24 23:26:55 +0100293 /* card emulator PC sends a singly byte PB response via USB */
Harald Welte8e7fca32017-05-07 16:14:33 +0200294 host_to_device_data(ch, hdr+1, 1, CEMU_DATA_F_FINAL | CEMU_DATA_F_PB_AND_RX);
Harald Weltec043e642016-02-24 23:26:55 +0100295 /* card actually sends that single PB */
Harald Welte86d047b2016-02-25 00:26:17 +0100296 card_tx_verify_chars(ch, hdr+1, 1);
Harald Weltec043e642016-02-24 23:26:55 +0100297
298 /* emulate more characters from reader to card */
299 reader_send_bytes(ch, body, body_len);
300
301 /* check if we have received them on the USB side */
Harald Welte8e7fca32017-05-07 16:14:33 +0200302 get_and_verify_rctx(PHONE_DATAIN, body, body_len);
Harald Weltec043e642016-02-24 23:26:55 +0100303
304 /* ensure there is no extra data received on usb */
Harald Welte8e7fca32017-05-07 16:14:33 +0200305 assert(llist_empty(usb_get_queue(PHONE_DATAOUT)));
Harald Weltec043e642016-02-24 23:26:55 +0100306
307 /* card emulator sends SW via USB */
Harald Welte8e7fca32017-05-07 16:14:33 +0200308 host_to_device_data(ch, tpdu_pb_sw, sizeof(tpdu_pb_sw),
Harald Weltec043e642016-02-24 23:26:55 +0100309 CEMU_DATA_F_FINAL | CEMU_DATA_F_PB_AND_TX);
310 /* obtain any pending tx chars */
Harald Welte86d047b2016-02-25 00:26:17 +0100311 card_tx_verify_chars(ch, tpdu_pb_sw, sizeof(tpdu_pb_sw));
Harald Weltec043e642016-02-24 23:26:55 +0100312
313 /* simulate some clock stop */
314 card_emu_io_statechg(ch, CARD_IO_CLK, 0);
315 card_emu_io_statechg(ch, CARD_IO_CLK, 1);
316}
317
318static void
319test_tpdu_card2reader(struct card_handle *ch, const uint8_t *hdr, const uint8_t *body, uint8_t body_len)
320{
321 printf("\n==> transmitting APDU (HDR + PB + card-TX)\n");
322
323 /* emulate the reader sending a TPDU header */
324 rdr_send_tpdu_hdr(ch, hdr);
Harald Welte86d047b2016-02-25 00:26:17 +0100325 card_tx_verify_chars(ch, NULL, 0);
Harald Weltec043e642016-02-24 23:26:55 +0100326
327 /* card emulator PC sends a response PB via USB */
Harald Welte8e7fca32017-05-07 16:14:33 +0200328 host_to_device_data(ch, hdr+1, 1, CEMU_DATA_F_PB_AND_TX);
Harald Weltec043e642016-02-24 23:26:55 +0100329
330 /* card actually sends that PB */
Harald Welte86d047b2016-02-25 00:26:17 +0100331 card_tx_verify_chars(ch, hdr+1, 1);
Harald Weltec043e642016-02-24 23:26:55 +0100332
333 /* emulate more characters from card to reader */
Harald Welte8e7fca32017-05-07 16:14:33 +0200334 host_to_device_data(ch, body, body_len, 0);
Harald Weltec043e642016-02-24 23:26:55 +0100335 /* obtain those bytes as they arrvive on the card */
Harald Welte86d047b2016-02-25 00:26:17 +0100336 card_tx_verify_chars(ch, body, body_len);
Harald Weltec043e642016-02-24 23:26:55 +0100337
338 /* ensure there is no extra data received on usb */
Harald Welte8e7fca32017-05-07 16:14:33 +0200339 assert(llist_empty(usb_get_queue(PHONE_DATAOUT)));
Harald Weltec043e642016-02-24 23:26:55 +0100340
341 /* card emulator sends SW via USB */
Harald Welte8e7fca32017-05-07 16:14:33 +0200342 host_to_device_data(ch, tpdu_pb_sw, sizeof(tpdu_pb_sw), CEMU_DATA_F_FINAL);
Harald Weltec043e642016-02-24 23:26:55 +0100343
344 /* obtain any pending tx chars */
Harald Welte86d047b2016-02-25 00:26:17 +0100345 card_tx_verify_chars(ch, tpdu_pb_sw, sizeof(tpdu_pb_sw));
Harald Weltec043e642016-02-24 23:26:55 +0100346
347 /* simulate some clock stop */
348 card_emu_io_statechg(ch, CARD_IO_CLK, 0);
349 card_emu_io_statechg(ch, CARD_IO_CLK, 1);
350}
351
Harald Welte4ba66d02016-02-25 19:38:56 +0100352const uint8_t pps[] = {
353 /* PPSS identifies the PPS request or response and is set to
354 * 'FF'. */
355 0xFF, // PPSS
356 /* In PPS0, each bit 5, 6 or 7 set to 1 indicates the presence
357 * of an optional byte PPS 1 , PPS 2 , PPS 3 ,
358 * respectively. Bits 4 to 1 encode a type T to propose a
359 * transmission protocol. Bit 8 is reserved for future
360 * use and shall be set to 0. */
361 0b00010000, // PPS0: PPS1 present
362 0x00, // PPS1 proposed Fi/Di value
363 0xFF ^ 0b00010000// PCK
364};
365
366static void
367test_ppss(struct card_handle *ch)
368{
369 reader_send_bytes(ch, pps, sizeof(pps));
370 get_and_verify_rctx_pps(pps, sizeof(pps));
371 card_tx_verify_chars(ch, pps, sizeof(pps));
372}
Harald Weltec043e642016-02-24 23:26:55 +0100373
Harald Welteeef6c2a2016-02-24 22:19:03 +0100374/* READ RECORD (offset 0, 10 bytes) */
375const uint8_t tpdu_hdr_read_rec[] = { 0xA0, 0xB2, 0x00, 0x00, 0x0A };
376const uint8_t tpdu_body_read_rec[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
377
378/* WRITE RECORD */
379const uint8_t tpdu_hdr_write_rec[] = { 0xA0, 0xD2, 0x00, 0x00, 0x07 };
380const uint8_t tpdu_body_write_rec[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
Harald Welte84ec2522015-11-14 23:03:50 +0100381
Harald Welte9d3e3822015-11-09 00:50:54 +0100382int main(int argc, char **argv)
383{
384 struct card_handle *ch;
Harald Welte84ec2522015-11-14 23:03:50 +0100385 unsigned int i;
Harald Welte9d3e3822015-11-09 00:50:54 +0100386
Harald Welte8e7fca32017-05-07 16:14:33 +0200387 ch = card_emu_init(0, 23, 42, PHONE_DATAIN, PHONE_INT);
Harald Welte9d3e3822015-11-09 00:50:54 +0100388 assert(ch);
389
Harald Welte8e7fca32017-05-07 16:14:33 +0200390 usb_buf_init();
391
Harald Welteb4362862015-11-14 19:02:33 +0100392 /* start up the card (VCC/RST, ATR) */
Harald Welte9d3e3822015-11-09 00:50:54 +0100393 io_start_card(ch);
Harald Welte86d047b2016-02-25 00:26:17 +0100394 card_tx_verify_chars(ch, NULL, 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100395
Harald Welte4ba66d02016-02-25 19:38:56 +0100396 test_ppss(ch);
397
Harald Welte84ec2522015-11-14 23:03:50 +0100398 for (i = 0; i < 2; i++) {
Harald Weltec043e642016-02-24 23:26:55 +0100399 test_tpdu_reader2card(ch, tpdu_hdr_write_rec, tpdu_body_write_rec, sizeof(tpdu_body_write_rec));
Harald Welte84ec2522015-11-14 23:03:50 +0100400
Harald Weltec043e642016-02-24 23:26:55 +0100401 test_tpdu_card2reader(ch, tpdu_hdr_read_rec, tpdu_body_read_rec, sizeof(tpdu_body_read_rec));
Harald Welte84ec2522015-11-14 23:03:50 +0100402 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100403
404 exit(0);
405}