blob: 5d37e9704db51c25363ff1023d39938a3c9dd262 [file] [log] [blame]
Harald Welte1200c822020-02-13 20:43:27 +01001#include <errno.h>
2#include <unistd.h>
3
4#include <osmocom/core/select.h>
5
6#include "client.h"
7
8/* This is a remsim-client with an interactive 'shell', where the user
9 * can type in C-APDUs in hex formats, which will be sent to the bankd /
10 * SIM-card. Responses received from SIM Card via bankd will be printed
11 * in return. */
12
13
14/***********************************************************************
Harald Welte0e968cc2020-02-22 18:16:16 +010015 * stdin frontend code to remsim-client
Harald Welte1200c822020-02-13 20:43:27 +010016 ***********************************************************************/
17
Harald Welte0e968cc2020-02-22 18:16:16 +010018int frontend_request_card_insert(struct bankd_client *bc)
Harald Welte1200c822020-02-13 20:43:27 +010019{
Harald Welte0e968cc2020-02-22 18:16:16 +010020 return 0;
21}
Harald Welte1200c822020-02-13 20:43:27 +010022
Harald Welte7b87ba12021-09-08 21:38:35 +020023int frontend_request_card_remove(struct bankd_client *bc)
24{
25 return 0;
26}
27
Harald Welte0e968cc2020-02-22 18:16:16 +010028int frontend_request_sim_remote(struct bankd_client *bc)
29{
30 return 0;
31}
Harald Welte1200c822020-02-13 20:43:27 +010032
Harald Welte7b87ba12021-09-08 21:38:35 +020033int frontend_request_sim_local(struct bankd_client *bc)
34{
35 return 0;
36}
37
Harald Welte0e968cc2020-02-22 18:16:16 +010038int frontend_request_modem_reset(struct bankd_client *bc)
39{
40 return 0;
41}
42
43int frontend_handle_card2modem(struct bankd_client *bc, const uint8_t *data, size_t len)
44{
45 OSMO_ASSERT(data);
46 printf("R-APDU: %s\n", osmo_hexdump(data, len));
Harald Welte82368402020-02-18 22:59:37 +010047 fflush(stdout);
Harald Welte1200c822020-02-13 20:43:27 +010048
49 return 0;
50}
51
Harald Welte0e968cc2020-02-22 18:16:16 +010052int frontend_handle_set_atr(struct bankd_client *bc, const uint8_t *data, size_t len)
Harald Welte1200c822020-02-13 20:43:27 +010053{
Harald Welte0e968cc2020-02-22 18:16:16 +010054 OSMO_ASSERT(data);
Harald Welte1200c822020-02-13 20:43:27 +010055
Harald Welte0e968cc2020-02-22 18:16:16 +010056 printf("SET_ATR: %s\n", osmo_hexdump(data, len));
Harald Welte82368402020-02-18 22:59:37 +010057 fflush(stdout);
Harald Welte1200c822020-02-13 20:43:27 +010058
Harald Welte1200c822020-02-13 20:43:27 +010059 return 0;
60}
61
Harald Welte0e968cc2020-02-22 18:16:16 +010062int frontend_handle_slot_status(struct bankd_client *bc, const SlotPhysStatus_t *sts)
Harald Welte1200c822020-02-13 20:43:27 +010063{
Harald Welte1200c822020-02-13 20:43:27 +010064 return 0;
65}
66
Harald Weltee580c932020-05-24 16:03:56 +020067int frontend_append_script_env(struct bankd_client *bc, char **env, int idx, size_t max_env)
Harald Welte0e968cc2020-02-22 18:16:16 +010068{
Harald Weltee580c932020-05-24 16:03:56 +020069 return idx;
Harald Welte0e968cc2020-02-22 18:16:16 +010070}
71
72
Harald Welte1200c822020-02-13 20:43:27 +010073/***********************************************************************
74 * Incoming command from the user application (stdin shell in our case)
75 ***********************************************************************/
76
77struct stdin_state {
78 struct osmo_fd ofd;
79 struct msgb *rx_msg;
Harald Welte8e46ab62020-02-14 12:55:43 +010080 struct bankd_client *bc;
Harald Welte1200c822020-02-13 20:43:27 +010081};
82
83/* called every time a command on stdin was received */
84static void handle_stdin_command(struct stdin_state *ss, char *cmd)
85{
Harald Welte8e46ab62020-02-14 12:55:43 +010086 struct bankd_client *bc = ss->bc;
Harald Welte1200c822020-02-13 20:43:27 +010087 int rc;
88
Harald Welte1200c822020-02-13 20:43:27 +010089 OSMO_ASSERT(ss->rx_msg);
90
Harald Welte1200c822020-02-13 20:43:27 +010091 if (!strcasecmp(cmd, "RESET")) {
92 /* reset the [remote] card */
Harald Welteaa66d912020-05-25 23:05:31 +020093 struct frontend_phys_status pstatus = {
94 .flags = {
95 .reset_active = true,
96 .vcc_present = false,
97 .clk_active = false,
98 .card_present = true,
99 },
100 .voltage_mv = 0,
101 .fi = 0,
102 .di = 0,
103 .wi = 0,
104 .waiting_time = 0,
105 };
106 osmo_fsm_inst_dispatch(bc->main_fi, MF_E_MDM_STATUS_IND, &pstatus);
Harald Welte1200c822020-02-13 20:43:27 +0100107 } else {
Harald Welteaa66d912020-05-25 23:05:31 +0200108 struct frontend_tpdu ftpdu;
109 uint8_t buf[1024];
110
Harald Welte1200c822020-02-13 20:43:27 +0100111 /* we assume the user has entered a C-APDU as hex string. parse + send */
112 rc = osmo_hexparse(cmd, buf, sizeof(buf));
113 if (rc < 0) {
114 fprintf(stderr, "ERROR parsing C-APDU `%s'!\n", cmd);
115 return;
116 }
Harald Welte8e46ab62020-02-14 12:55:43 +0100117 if (!bc->srv_conn.clslot) {
Harald Welte1200c822020-02-13 20:43:27 +0100118 fprintf(stderr, "Cannot send command; no client slot\n");
119 return;
120 }
121
122 /* Send CMD APDU to [remote] card */
Harald Welteaa66d912020-05-25 23:05:31 +0200123 ftpdu.buf = buf;
124 ftpdu.len = rc;
125 osmo_fsm_inst_dispatch(bc->main_fi, MF_E_MDM_TPDU, &ftpdu);
Harald Welte1200c822020-02-13 20:43:27 +0100126 }
127}
128
129/* call-back function for stdin read. Gather bytes in buffer until CR/LF received */
130static int stdin_fd_cb(struct osmo_fd *ofd, unsigned int what)
131{
132 struct stdin_state *ss = ofd->data;
133 char *cur;
134 int rc, i;
135
136 OSMO_ASSERT(what & OSMO_FD_READ);
137
138 if (!ss->rx_msg) {
139 ss->rx_msg = msgb_alloc(1024, "stdin");
140 OSMO_ASSERT(ss->rx_msg);
141 }
142
143 cur = (char *) ss->rx_msg->tail;
144 rc = read(ofd->fd, cur, msgb_tailroom(ss->rx_msg));
145 if (rc < 0)
146 return rc;
Harald Welte3f659722020-07-19 09:54:11 +0200147 if (rc == 0) {
148 fprintf(stderr, "STDIN was closed, terminating");
149 exit(0);
150 }
Harald Welte1200c822020-02-13 20:43:27 +0100151 msgb_put(ss->rx_msg, rc);
152
153 for (i = 0; i < rc; i++) {
154 if (cur[i] == '\r' || cur[i] == '\n') {
155 cur[i] = '\0';
156 /* dispatch the command */
157 handle_stdin_command(ss, cur);
158 /* FIXME: possibly other commands */
159 msgb_free(ss->rx_msg);
160 ss->rx_msg = NULL;
161 }
162 }
163
164 return 0;
165}
166
167
168
169/* main function */
Harald Welte8e46ab62020-02-14 12:55:43 +0100170int client_user_main(struct bankd_client *bc)
Harald Welte1200c822020-02-13 20:43:27 +0100171{
172 struct stdin_state ss;
173
174 /* register stdin file descriptor with osmocom select loop abstraction */
175 memset(&ss, 0, sizeof(ss));
176 osmo_fd_setup(&ss.ofd, fileno(stdin), OSMO_FD_READ, &stdin_fd_cb, &ss, 0);
177 osmo_fd_register(&ss.ofd);
Harald Welte8e46ab62020-02-14 12:55:43 +0100178 ss.bc = bc;
Harald Welte1200c822020-02-13 20:43:27 +0100179
180 while (1) {
181 osmo_select_main(0);
182 }
183}