Add cuart_fsm_test program
Change-Id: I2b4be908b1bbd9b02f591a79b0eefaeae04badb8
diff --git a/ccid_host/cuart_fsm_test.c b/ccid_host/cuart_fsm_test.c
new file mode 100644
index 0000000..92f3437
--- /dev/null
+++ b/ccid_host/cuart_fsm_test.c
@@ -0,0 +1,112 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/application.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/sim/sim.h>
+
+#include "logging.h"
+#include "cuart.h"
+#include "iso7816_fsm.h"
+
+static struct card_uart g_cuart;
+
+enum test_state {
+ ST_WAIT_ATR,
+ ST_ATR_DONE,
+ ST_IN_TPDU,
+};
+static enum test_state g_tstate = ST_WAIT_ATR;
+
+static void fsm_user_cb(struct osmo_fsm_inst *fi, int event, int cause, void *data)
+{
+ printf("Handle FSM User Event %d: cause=%d, data=%p\n", event, cause, data);
+ switch (event) {
+ case ISO7816_E_ATR_DONE_IND:
+ g_tstate = ST_ATR_DONE;
+ break;
+ case ISO7816_E_TPDU_DONE_IND:
+ printf("======= TPDU: %s\n", msgb_hexdump(data));
+ msgb_free(data);
+ g_tstate = ST_ATR_DONE;
+ default:
+ break;
+ }
+}
+
+static void *tall_main_ctx;
+
+static void signal_handler(int signal)
+{
+ switch (signal) {
+ case SIGUSR1:
+ talloc_report_full(tall_main_ctx, stderr);
+ break;
+ }
+}
+
+int main(int argc, char **argv)
+{
+ struct osmo_fsm_inst *fi;
+ uint8_t atr[64];
+ int rc;
+
+ tall_main_ctx = talloc_named_const(NULL, 0, "main");
+ msgb_talloc_ctx_init(tall_main_ctx, 0);
+ osmo_init_logging2(tall_main_ctx, &log_info);
+ osmo_fsm_log_addr(false);
+
+ signal(SIGUSR1, &signal_handler);
+
+ rc = card_uart_open(&g_cuart, "tty", "/dev/ttyUSB5");
+ if (rc < 0) {
+ perror("opening UART");
+ exit(1);
+ }
+
+ fi = iso7816_fsm_alloc(NULL, LOGL_DEBUG, "SIM0", &g_cuart, fsm_user_cb, NULL);
+ OSMO_ASSERT(fi);
+
+ /* activate reset, then power up */
+ card_uart_ctrl(&g_cuart, CUART_CTL_RST, true);
+ card_uart_ctrl(&g_cuart, CUART_CTL_POWER, true);
+ osmo_fsm_inst_dispatch(fi, ISO7816_E_POWER_UP_IND, NULL);
+
+ /* activate clock */
+ card_uart_ctrl(&g_cuart, CUART_CTL_CLOCK, true);
+
+ /* wait some time and release reset */
+ usleep(10000);
+ card_uart_ctrl(&g_cuart, CUART_CTL_RST, false);
+ osmo_fsm_inst_dispatch(fi, ISO7816_E_RESET_REL_IND, NULL);
+
+ /* process any events in polling mode for initial change */
+ osmo_select_main(1);
+
+ struct msgb *apdu;
+ while (1) {
+ /* check if the new state requires us to do something */
+ switch (g_tstate) {
+ case ST_ATR_DONE:
+ apdu = msgb_alloc(512, "TPDU");
+ msgb_put_u8(apdu, 0x00);
+ msgb_put_u8(apdu, 0xa4);
+ msgb_put_u8(apdu, 0x00);
+ msgb_put_u8(apdu, 0x04);
+ msgb_put_u8(apdu, 0x02);
+ msgb_put_u8(apdu, 0x2f);
+ msgb_put_u8(apdu, 0x00);
+ osmo_fsm_inst_dispatch(fi, ISO7816_E_XCEIVE_TPDU_CMD, apdu);
+ g_tstate = ST_IN_TPDU;
+ break;
+ default:
+ break;
+ }
+ osmo_select_main(0);
+ }
+
+ exit(0);
+}