blob: bd7130a9ee87de6b5bc769cbe2765addeb8adb03 [file] [log] [blame]
Harald Welte77911b02018-08-14 23:47:30 +02001#pragma once
2
3#include <stdbool.h>
4#include <sys/socket.h>
5#include <arpa/inet.h>
6#include <netinet/in.h>
7
8#include <pthread.h>
9
10#include <wintypes.h>
11#include <winscard.h>
12
13#include <osmocom/core/linuxlist.h>
14
Harald Weltef1dd1622018-09-24 14:54:23 +020015#include "rspro_util.h"
16
Harald Weltef94b9ee2018-09-25 15:04:21 +020017enum {
18 DMAIN,
19};
20
Harald Welte77911b02018-08-14 23:47:30 +020021struct bankd;
22
23struct bank_slot {
24 uint16_t bank_id;
25 uint16_t slot_nr;
26};
27
28static inline bool bank_slot_equals(const struct bank_slot *a, const struct bank_slot *b)
29{
30 if (a->bank_id == b->bank_id && a->slot_nr == b->slot_nr)
31 return true;
32 else
33 return false;
34}
35
36struct client_slot {
37 uint16_t client_id;
38 uint16_t slot_nr;
39};
40
41static inline bool client_slot_equals(const struct client_slot *a, const struct client_slot *b)
42{
43 if (a->client_id == b->client_id && a->slot_nr == b->slot_nr)
44 return true;
45 else
46 return false;
47}
48
Harald Welted08d5052018-10-03 20:43:31 +020049static inline ClientSlot_t client_slot2asn(const struct client_slot *in)
50{
51 ClientSlot_t out = {
52 .clientId = in->client_id,
53 .slotNr = in->slot_nr,
54 };
55 return out;
56}
57
Harald Welte77911b02018-08-14 23:47:30 +020058/* slot mappings are created / removed by the server */
59struct bankd_slot_mapping {
60 /* global lits of bankd slot mappings */
61 struct llist_head list;
62 /* slot on bank side */
63 struct bank_slot bank;
64 /* slot on client side */
65 struct client_slot client;
66};
67
68/* thread-safe lookup of map by client:slot */
69struct bankd_slot_mapping *bankd_slotmap_by_client(struct bankd *bankd,
70 const struct client_slot *client);
71
72/* thread-safe lookup of map by bank:slot */
73struct bankd_slot_mapping *bankd_slotmap_by_bank(struct bankd *bankd, const struct bank_slot *bank);
74
75/* thread-safe creating of a new bank<->client map */
76int bankd_slotmap_add(struct bankd *bankd, const struct bank_slot *bank,
77 const struct client_slot *client);
78
79/* thread-safe removal of a bank<->client map */
80void bankd_slotmap_del(struct bankd *bankd, struct bankd_slot_mapping *map);
81
Harald Welte8d858292018-08-15 23:36:46 +020082enum bankd_worker_state {
83 /* just started*/
84 BW_ST_INIT,
85 /* blocking in the accept() call on the server socket fd */
86 BW_ST_ACCEPTING,
87 /* TCP established, but peer not yet identified itself */
88 BW_ST_CONN_WAIT_ID,
89 /* TCP established, client has identified itself, no mapping */
90 BW_ST_CONN_CLIENT,
Harald Welteaf614732018-08-17 22:10:05 +020091 /* TCP established, client has identified itself, waiting for mapping */
92 BW_ST_CONN_CLIENT_WAIT_MAP,
Harald Welte8d858292018-08-15 23:36:46 +020093 /* TCP established, client has identified itself, mapping exists */
94 BW_ST_CONN_CLIENT_MAPPED,
95 /* TCP established, client identified, mapping exists, card opened */
96 BW_ST_CONN_CLIENT_MAPPED_CARD,
97};
98
Harald Welte77911b02018-08-14 23:47:30 +020099
100/* bankd worker instance; one per card/slot, includes thread */
101struct bankd_worker {
102 /* global list of workers */
103 struct llist_head list;
104 /* back-pointer to bankd */
105 struct bankd *bankd;
106
Harald Welte8d858292018-08-15 23:36:46 +0200107 /* thread number */
108 unsigned int num;
109 /* worker thread state */
110 enum bankd_worker_state state;
111
Harald Welted08d5052018-10-03 20:43:31 +0200112 uint8_t atr[32];
113 unsigned int atr_len;
114
Harald Welte77911b02018-08-14 23:47:30 +0200115 /* slot number we are representing */
116 struct bank_slot slot;
117
118 /* thread of this worker. */
119 pthread_t thread;
120
121 /* File descriptor of the TCP connection to the remsim-client (modem) */
122 struct {
123 int fd;
124 struct sockaddr_storage peer_addr;
125 socklen_t peer_addr_len;
Harald Welte371d0262018-08-16 15:23:58 +0200126 struct client_slot clslot;
Harald Welte77911b02018-08-14 23:47:30 +0200127 } client;
128
129 struct {
130 const char *name;
Harald Welted08d5052018-10-03 20:43:31 +0200131 struct osmo_fsm_inst *fi;
Harald Welte77911b02018-08-14 23:47:30 +0200132 union {
133 struct {
134 /* PC/SC context / application handle */
135 SCARDCONTEXT hContext;
136 /* PC/SC card handle */
137 SCARDHANDLE hCard;
Harald Welted08d5052018-10-03 20:43:31 +0200138 /* PC/SC slot status (SCARD_ABSENT, ...) bit-mask */
139 DWORD dwState;
Harald Welte77911b02018-08-14 23:47:30 +0200140 } pcsc;
141 };
142 } reader;
143};
144
145
146/* global bank deamon */
147struct bankd {
148 struct {
149 uint16_t bank_id;
150 } cfg;
151
Harald Weltef1dd1622018-09-24 14:54:23 +0200152 struct app_comp_id comp_id;
153
Harald Welte77911b02018-08-14 23:47:30 +0200154 /* TCP socket at which we are listening */
155 int accept_fd;
156
157 /* list of slit mappings. only ever modified in main thread! */
158 struct llist_head slot_mappings;
159 pthread_rwlock_t slot_mappings_rwlock;
160
161 /* list of bankd_workers. accessed/modified by multiple threads; protected by mutex */
162 struct llist_head workers;
163 pthread_mutex_t workers_mutex;
Harald Welte45c948c2018-09-23 19:26:52 +0200164
165 struct llist_head pcsc_slot_names;
Harald Welte77911b02018-08-14 23:47:30 +0200166};
Harald Welte45c948c2018-09-23 19:26:52 +0200167
168int bankd_pcsc_read_slotnames(struct bankd *bankd, const char *csv_file);
169const char *bankd_pcsc_get_slot_name(struct bankd *bankd, const struct bank_slot *slot);
Harald Welted08d5052018-10-03 20:43:31 +0200170
171enum sc_fsm_events {
172 SC_E_CONNECT_CMD,
173 SC_E_DISCONNECT_CMD,
174 SC_E_TPDU_CMD,
175};
176
177struct osmo_fsm_inst *sc_fsm_alloc(struct bankd_worker *worker);
178
179int worker_handle_tpduModemToCard(struct bankd_worker *worker, const RsproPDU_t *pdu);
180int worker_send_rspro(struct bankd_worker *worker, RsproPDU_t *pdu);