blob: 2ab768cf94688ebba17bfec2375820d9665c74af [file] [log] [blame]
Harald Welte45c948c2018-09-23 19:26:52 +02001
2#include <osmocom/core/linuxlist.h>
3#include <osmocom/core/talloc.h>
4#include <osmocom/core/utils.h>
5
6#include <csv.h>
7
8#include "bankd.h"
9
10struct pcsc_slot_name {
11 struct llist_head list;
12 /* RSPRO bank slot number */
13 struct bank_slot slot;
14 /* String name of the reader in PC/SC world */
15 const char *name;
16};
17
18enum parser_state_name {
19 ST_NONE,
20 ST_BANK_NR,
21 ST_SLOT_NR,
22 ST_PCSC_NAME,
23};
24struct parser_state {
25 struct bankd *bankd;
26 enum parser_state_name state;
27 struct pcsc_slot_name *cur;
28};
29
30
31static void parser_state_init(struct parser_state *ps)
32{
33 ps->state = ST_BANK_NR;
34 ps->cur = NULL;
35}
36
37static void cb1(void *s, size_t len, void *data)
38{
39 char *field = (char *) s;
40 struct parser_state *ps = data;
41
42 switch (ps->state) {
43 case ST_BANK_NR:
44 OSMO_ASSERT(!ps->cur);
45 ps->cur = talloc_zero(ps->bankd, struct pcsc_slot_name);
46 OSMO_ASSERT(ps->cur);
47 ps->cur->slot.bank_id = atoi(field);
48 ps->state = ST_SLOT_NR;
49 break;
50 case ST_SLOT_NR:
51 OSMO_ASSERT(ps->cur);
52 ps->cur->slot.slot_nr = atoi(field);
53 ps->state = ST_PCSC_NAME;
54 break;
55 case ST_PCSC_NAME:
56 OSMO_ASSERT(ps->cur);
57 ps->cur->name = talloc_strdup(ps->cur, field);
58 break;
59 default:
60 OSMO_ASSERT(0);
61 }
62}
63
64static void cb2(int c, void *data)
65{
66 struct parser_state *ps = data;
67 struct pcsc_slot_name *sn = ps->cur;
68
69 printf("PC/SC slot name: %u/%u -> '%s'\n", sn->slot.bank_id, sn->slot.slot_nr, sn->name);
70 llist_add_tail(&sn->list, &ps->bankd->pcsc_slot_names);
71
72 ps->state = ST_BANK_NR;
73 ps->cur = NULL;
74}
75
76int bankd_pcsc_read_slotnames(struct bankd *bankd, const char *csv_file)
77{
78 FILE *fp;
79 struct csv_parser p;
80 char buf[1024];
81 size_t bytes_read;
82 struct parser_state ps;
83
84 if (csv_init(&p, CSV_APPEND_NULL) != 0)
85 return -1;
86
87 fp = fopen(csv_file, "rb");
88 if (!fp)
89 return -1;
90
91 parser_state_init(&ps);
92 ps.bankd = bankd;
93
94 while ((bytes_read = fread(buf, 1, sizeof(buf), fp)) > 0) {
95 if (csv_parse(&p, buf, bytes_read, cb1, cb2, &ps) != bytes_read) {
96 fprintf(stderr, "Error parsing CSV: %s\n", csv_strerror(csv_error(&p)));
97 fclose(fp);
98 return -1;
99 }
100 }
101
102 csv_fini(&p, cb1, cb2, &ps);
103 fclose(fp);
104 csv_free(&p);
105
106 return 0;
107}
108
109const char *bankd_pcsc_get_slot_name(struct bankd *bankd, const struct bank_slot *slot)
110{
111 struct pcsc_slot_name *cur;
112
113 llist_for_each_entry(cur, &bankd->pcsc_slot_names, list) {
114 if (bank_slot_equals(&cur->slot, slot))
115 return cur->name;
116 }
117 return NULL;
118}