blob: 1151b3428e5cc20c56ccde9c3770b6f877385c2e [file] [log] [blame]
Harald Welte0b778c32019-09-29 12:10:02 +02001#include <unistd.h>
2#include <stdio.h>
3#include <errno.h>
4#include <signal.h>
5#include <osmocom/core/utils.h>
6#include <osmocom/core/logging.h>
7#include <osmocom/core/application.h>
8#include <osmocom/core/msgb.h>
9#include <osmocom/sim/sim.h>
10
11#include "logging.h"
12#include "cuart.h"
13#include "iso7816_fsm.h"
14
15static struct card_uart g_cuart;
16
17enum test_state {
18 ST_WAIT_ATR,
19 ST_ATR_DONE,
20 ST_IN_TPDU,
21};
22static enum test_state g_tstate = ST_WAIT_ATR;
23
24static void fsm_user_cb(struct osmo_fsm_inst *fi, int event, int cause, void *data)
25{
26 printf("Handle FSM User Event %d: cause=%d, data=%p\n", event, cause, data);
27 switch (event) {
28 case ISO7816_E_ATR_DONE_IND:
29 g_tstate = ST_ATR_DONE;
30 break;
31 case ISO7816_E_TPDU_DONE_IND:
32 printf("======= TPDU: %s\n", msgb_hexdump(data));
33 msgb_free(data);
34 g_tstate = ST_ATR_DONE;
35 default:
36 break;
37 }
38}
39
40static void *tall_main_ctx;
41
42static void signal_handler(int signal)
43{
44 switch (signal) {
45 case SIGUSR1:
46 talloc_report_full(tall_main_ctx, stderr);
47 break;
48 }
49}
50
51int main(int argc, char **argv)
52{
53 struct osmo_fsm_inst *fi;
54 uint8_t atr[64];
55 int rc;
56
57 tall_main_ctx = talloc_named_const(NULL, 0, "main");
58 msgb_talloc_ctx_init(tall_main_ctx, 0);
59 osmo_init_logging2(tall_main_ctx, &log_info);
60 osmo_fsm_log_addr(false);
61
62 signal(SIGUSR1, &signal_handler);
63
Harald Welte31313a62019-10-09 21:03:14 +020064 if (argc < 2) {
65 fprintf(stderr, "You must specify the UART tty device as argument\n");
66 exit(2);
67 }
68
69 printf("Opening UART device %s\n", argv[1]);
70
71 rc = card_uart_open(&g_cuart, "tty", argv[1]);
Harald Welte0b778c32019-09-29 12:10:02 +020072 if (rc < 0) {
73 perror("opening UART");
74 exit(1);
75 }
76
77 fi = iso7816_fsm_alloc(NULL, LOGL_DEBUG, "SIM0", &g_cuart, fsm_user_cb, NULL);
78 OSMO_ASSERT(fi);
79
80 /* activate reset, then power up */
81 card_uart_ctrl(&g_cuart, CUART_CTL_RST, true);
82 card_uart_ctrl(&g_cuart, CUART_CTL_POWER, true);
83 osmo_fsm_inst_dispatch(fi, ISO7816_E_POWER_UP_IND, NULL);
84
85 /* activate clock */
86 card_uart_ctrl(&g_cuart, CUART_CTL_CLOCK, true);
87
88 /* wait some time and release reset */
89 usleep(10000);
90 card_uart_ctrl(&g_cuart, CUART_CTL_RST, false);
91 osmo_fsm_inst_dispatch(fi, ISO7816_E_RESET_REL_IND, NULL);
92
93 /* process any events in polling mode for initial change */
94 osmo_select_main(1);
95
96 struct msgb *apdu;
97 while (1) {
98 /* check if the new state requires us to do something */
99 switch (g_tstate) {
100 case ST_ATR_DONE:
101 apdu = msgb_alloc(512, "TPDU");
102 msgb_put_u8(apdu, 0x00);
103 msgb_put_u8(apdu, 0xa4);
104 msgb_put_u8(apdu, 0x00);
105 msgb_put_u8(apdu, 0x04);
106 msgb_put_u8(apdu, 0x02);
107 msgb_put_u8(apdu, 0x2f);
108 msgb_put_u8(apdu, 0x00);
109 osmo_fsm_inst_dispatch(fi, ISO7816_E_XCEIVE_TPDU_CMD, apdu);
110 g_tstate = ST_IN_TPDU;
111 break;
112 default:
113 break;
114 }
115 osmo_select_main(0);
116 }
117
118 exit(0);
119}