diff options
author | Harald Welte <laforge@gnumonks.org> | 2018-09-23 19:26:52 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2018-09-23 19:29:51 +0200 |
commit | 45c948cc107a367502a6c2db1bfdb354a9b93721 (patch) | |
tree | f924c329cc149cd3cc85c3d6570c2bf3d3e1564c | |
parent | 1266952242d047d093b7c6b0b012562eff583bd7 (diff) |
bankd_pcsc: Add CSV based mapping of bank-id/slot-nr to PC/SC reader name
In the PC/SC world, each slot is associated with a string name. In the
bankd for PC/SC readers, we need to establish a mapping which
bank_id/slot_nr maps to which given string name. We use a minimalistic
CSV file for defining those mappings. The file is read only once at
bankd startup time.
Change-Id: Ifd2caab670625e2e3fbc57b966dce2f43b690417
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/bankd.h | 5 | ||||
-rw-r--r-- | src/bankd_main.c | 12 | ||||
-rw-r--r-- | src/bankd_pcsc.c | 118 | ||||
-rw-r--r-- | src/bankd_pcsc_slots.csv | 6 |
5 files changed, 144 insertions, 3 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 2324831..1514a16 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,9 +19,9 @@ pcsc_test_SOURCES = driver_core.c driver_pcsc.c main.c pcsc_test_LDADD = $(OSMOCORE_LIBS) \ $(ASN1C_LIBS) $(PCSC_LIBS) libosmo-rspro.la -remsim_bankd_SOURCES = bankd_slotmap.c bankd_main.c -remsim_bankd_LDADD = $(OSMOCORE_LIBS) \ - $(ASN1C_LIBS) $(PCSC_LIBS) libosmo-rspro.la +remsim_bankd_SOURCES = bankd_slotmap.c bankd_main.c bankd_pcsc.c +remsim_bankd_LDADD = $(OSMOCORE_LIBS) $(OSMOGSM_LIBS) \ + $(ASN1C_LIBS) $(PCSC_LIBS) libosmo-rspro.la -lcsv remsim_client_SOURCES = remsim_client.c remsim_client_fsm.c remsim_client_LDADD = $(OSMOCORE_LIBS) $(OSMOGSM_LIBS) $(OSMOABIS_LIBS) \ diff --git a/src/bankd.h b/src/bankd.h index 61bf34a..2759478 100644 --- a/src/bankd.h +++ b/src/bankd.h @@ -138,4 +138,9 @@ struct bankd { /* list of bankd_workers. accessed/modified by multiple threads; protected by mutex */ struct llist_head workers; pthread_mutex_t workers_mutex; + + struct llist_head pcsc_slot_names; }; + +int bankd_pcsc_read_slotnames(struct bankd *bankd, const char *csv_file); +const char *bankd_pcsc_get_slot_name(struct bankd *bankd, const struct bank_slot *slot); diff --git a/src/bankd_main.c b/src/bankd_main.c index 96eee0e..7cb46d2 100644 --- a/src/bankd_main.c +++ b/src/bankd_main.c @@ -38,6 +38,12 @@ static void bankd_init(struct bankd *bankd) pthread_rwlock_init(&bankd->slot_mappings_rwlock, NULL); INIT_LLIST_HEAD(&bankd->workers); pthread_mutex_init(&bankd->workers_mutex, NULL); + + /* Np lock or mutex required for the pcsc_slot_names list, as this is only + * read once during bankd initialization, when the worker threads haven't + * started yet */ + INIT_LLIST_HEAD(&bankd->pcsc_slot_names); + OSMO_ASSERT(bankd_pcsc_read_slotnames(bankd, "bankd_pcsc_slots.csv") == 0); } /* create + start a new bankd_worker thread */ @@ -154,6 +160,12 @@ static int worker_open_card(struct bankd_worker *worker) { long rc; + /* resolve PC/SC reader name from slot_id -> name map */ + worker->reader.name = bankd_pcsc_get_slot_name(worker->bankd, &worker->slot); + OSMO_ASSERT(worker->reader.name); + + LOGW(worker, "Attempting to open card/slot '%s'\n", worker->reader.name); + /* The PC/SC context must be created inside the thread where we'll later use it */ rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &worker->reader.pcsc.hContext); PCSC_ERROR(worker, rc, "SCardEstablishContext") diff --git a/src/bankd_pcsc.c b/src/bankd_pcsc.c new file mode 100644 index 0000000..2ab768c --- /dev/null +++ b/src/bankd_pcsc.c @@ -0,0 +1,118 @@ + +#include <osmocom/core/linuxlist.h> +#include <osmocom/core/talloc.h> +#include <osmocom/core/utils.h> + +#include <csv.h> + +#include "bankd.h" + +struct pcsc_slot_name { + struct llist_head list; + /* RSPRO bank slot number */ + struct bank_slot slot; + /* String name of the reader in PC/SC world */ + const char *name; +}; + +enum parser_state_name { + ST_NONE, + ST_BANK_NR, + ST_SLOT_NR, + ST_PCSC_NAME, +}; +struct parser_state { + struct bankd *bankd; + enum parser_state_name state; + struct pcsc_slot_name *cur; +}; + + +static void parser_state_init(struct parser_state *ps) +{ + ps->state = ST_BANK_NR; + ps->cur = NULL; +} + +static void cb1(void *s, size_t len, void *data) +{ + char *field = (char *) s; + struct parser_state *ps = data; + + switch (ps->state) { + case ST_BANK_NR: + OSMO_ASSERT(!ps->cur); + ps->cur = talloc_zero(ps->bankd, struct pcsc_slot_name); + OSMO_ASSERT(ps->cur); + ps->cur->slot.bank_id = atoi(field); + ps->state = ST_SLOT_NR; + break; + case ST_SLOT_NR: + OSMO_ASSERT(ps->cur); + ps->cur->slot.slot_nr = atoi(field); + ps->state = ST_PCSC_NAME; + break; + case ST_PCSC_NAME: + OSMO_ASSERT(ps->cur); + ps->cur->name = talloc_strdup(ps->cur, field); + break; + default: + OSMO_ASSERT(0); + } +} + +static void cb2(int c, void *data) +{ + struct parser_state *ps = data; + struct pcsc_slot_name *sn = ps->cur; + + printf("PC/SC slot name: %u/%u -> '%s'\n", sn->slot.bank_id, sn->slot.slot_nr, sn->name); + llist_add_tail(&sn->list, &ps->bankd->pcsc_slot_names); + + ps->state = ST_BANK_NR; + ps->cur = NULL; +} + +int bankd_pcsc_read_slotnames(struct bankd *bankd, const char *csv_file) +{ + FILE *fp; + struct csv_parser p; + char buf[1024]; + size_t bytes_read; + struct parser_state ps; + + if (csv_init(&p, CSV_APPEND_NULL) != 0) + return -1; + + fp = fopen(csv_file, "rb"); + if (!fp) + return -1; + + parser_state_init(&ps); + ps.bankd = bankd; + + while ((bytes_read = fread(buf, 1, sizeof(buf), fp)) > 0) { + if (csv_parse(&p, buf, bytes_read, cb1, cb2, &ps) != bytes_read) { + fprintf(stderr, "Error parsing CSV: %s\n", csv_strerror(csv_error(&p))); + fclose(fp); + return -1; + } + } + + csv_fini(&p, cb1, cb2, &ps); + fclose(fp); + csv_free(&p); + + return 0; +} + +const char *bankd_pcsc_get_slot_name(struct bankd *bankd, const struct bank_slot *slot) +{ + struct pcsc_slot_name *cur; + + llist_for_each_entry(cur, &bankd->pcsc_slot_names, list) { + if (bank_slot_equals(&cur->slot, slot)) + return cur->name; + } + return NULL; +} diff --git a/src/bankd_pcsc_slots.csv b/src/bankd_pcsc_slots.csv new file mode 100644 index 0000000..38a22c9 --- /dev/null +++ b/src/bankd_pcsc_slots.csv @@ -0,0 +1,6 @@ +"1","0","ACS ACR33 ICC Reader 00 00" +"1","1","ACS ACR33 ICC Reader 00 01" +"1","2","ACS ACR33 ICC Reader 00 02" +"1","3","ACS ACR33 ICC Reader 00 03" +"1","4","ACS ACR33 ICC Reader 00 04" +"1","23","Alcor Micro AU9560 00 00" |