blob: db14779b76b6001b9fbddaab51e6241f0de5dbf2 [file] [log] [blame]
Harald Weltea67be5f2020-09-03 10:04:36 +02001/* Minimal test program for the ISO7816-3 FSM
2 * expects a Smart Card attached to a UART reachable as /dev/ttyXXX
3 *
4 * (C) 2019-2020 by Harald Welte <laforge@gnumonks.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
19 */
20
Harald Welte0b778c32019-09-29 12:10:02 +020021#include <unistd.h>
22#include <stdio.h>
23#include <errno.h>
24#include <signal.h>
25#include <osmocom/core/utils.h>
26#include <osmocom/core/logging.h>
27#include <osmocom/core/application.h>
28#include <osmocom/core/msgb.h>
29#include <osmocom/sim/sim.h>
30
31#include "logging.h"
32#include "cuart.h"
33#include "iso7816_fsm.h"
34
35static struct card_uart g_cuart;
36
37enum test_state {
38 ST_WAIT_ATR,
39 ST_ATR_DONE,
40 ST_IN_TPDU,
41};
42static enum test_state g_tstate = ST_WAIT_ATR;
43
44static void fsm_user_cb(struct osmo_fsm_inst *fi, int event, int cause, void *data)
45{
46 printf("Handle FSM User Event %d: cause=%d, data=%p\n", event, cause, data);
47 switch (event) {
48 case ISO7816_E_ATR_DONE_IND:
49 g_tstate = ST_ATR_DONE;
50 break;
51 case ISO7816_E_TPDU_DONE_IND:
52 printf("======= TPDU: %s\n", msgb_hexdump(data));
53 msgb_free(data);
54 g_tstate = ST_ATR_DONE;
55 default:
56 break;
57 }
58}
59
Eric Wilddd2e82e2019-12-02 14:11:23 +010060static void *g_tall_ctx;
Harald Welte0b778c32019-09-29 12:10:02 +020061
62static void signal_handler(int signal)
63{
64 switch (signal) {
65 case SIGUSR1:
Eric Wilddd2e82e2019-12-02 14:11:23 +010066 talloc_report_full(g_tall_ctx, stderr);
Harald Welte0b778c32019-09-29 12:10:02 +020067 break;
68 }
69}
70
71int main(int argc, char **argv)
72{
73 struct osmo_fsm_inst *fi;
74 uint8_t atr[64];
75 int rc;
76
Eric Wilddd2e82e2019-12-02 14:11:23 +010077 g_tall_ctx = talloc_named_const(NULL, 0, "main");
78 msgb_talloc_ctx_init(g_tall_ctx, 0);
79 osmo_init_logging2(g_tall_ctx, &log_info);
Harald Welte0b778c32019-09-29 12:10:02 +020080 osmo_fsm_log_addr(false);
81
82 signal(SIGUSR1, &signal_handler);
83
Harald Welte31313a62019-10-09 21:03:14 +020084 if (argc < 2) {
85 fprintf(stderr, "You must specify the UART tty device as argument\n");
86 exit(2);
87 }
88
89 printf("Opening UART device %s\n", argv[1]);
90
91 rc = card_uart_open(&g_cuart, "tty", argv[1]);
Harald Welte0b778c32019-09-29 12:10:02 +020092 if (rc < 0) {
93 perror("opening UART");
94 exit(1);
95 }
96
97 fi = iso7816_fsm_alloc(NULL, LOGL_DEBUG, "SIM0", &g_cuart, fsm_user_cb, NULL);
98 OSMO_ASSERT(fi);
99
100 /* activate reset, then power up */
101 card_uart_ctrl(&g_cuart, CUART_CTL_RST, true);
Eric Wild70f36912020-04-03 22:29:02 +0200102 card_uart_ctrl(&g_cuart, CUART_CTL_POWER_1V8, true);
Harald Welte0b778c32019-09-29 12:10:02 +0200103 osmo_fsm_inst_dispatch(fi, ISO7816_E_POWER_UP_IND, NULL);
104
105 /* activate clock */
106 card_uart_ctrl(&g_cuart, CUART_CTL_CLOCK, true);
107
108 /* wait some time and release reset */
109 usleep(10000);
110 card_uart_ctrl(&g_cuart, CUART_CTL_RST, false);
111 osmo_fsm_inst_dispatch(fi, ISO7816_E_RESET_REL_IND, NULL);
112
113 /* process any events in polling mode for initial change */
114 osmo_select_main(1);
115
116 struct msgb *apdu;
117 while (1) {
118 /* check if the new state requires us to do something */
119 switch (g_tstate) {
120 case ST_ATR_DONE:
121 apdu = msgb_alloc(512, "TPDU");
122 msgb_put_u8(apdu, 0x00);
123 msgb_put_u8(apdu, 0xa4);
124 msgb_put_u8(apdu, 0x00);
125 msgb_put_u8(apdu, 0x04);
126 msgb_put_u8(apdu, 0x02);
127 msgb_put_u8(apdu, 0x2f);
128 msgb_put_u8(apdu, 0x00);
129 osmo_fsm_inst_dispatch(fi, ISO7816_E_XCEIVE_TPDU_CMD, apdu);
130 g_tstate = ST_IN_TPDU;
131 break;
132 default:
133 break;
134 }
135 osmo_select_main(0);
136 }
137
138 exit(0);
139}