blob: e340b5a3d90d3c34a544bce0ebc881e306d64542 [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"
Harald Weltecbd18962019-03-03 19:02:38 +010016#include "slotmap.h"
Harald Weltef7598fe2019-12-16 16:52:45 +010017#include "rspro_client_fsm.h"
Harald Weltea4e0a232018-10-14 17:44:25 +020018#include "debug.h"
Harald Weltef94b9ee2018-09-25 15:04:21 +020019
Harald Welte297d72e2019-03-28 18:42:35 +010020extern struct value_string worker_state_names[];
21
22#define LOGW(w, fmt, args...) \
Harald Weltebc2e6e32022-07-11 22:14:17 +020023 LOGP(DBANKDW, LOGL_INFO, "[%03u B%u:%u %s] " fmt, (w)->num, (w)->slot.bank_id, (w)->slot.slot_nr, get_value_string(worker_state_names, (w)->state), \
Harald Weltea9d7ad12021-12-08 21:09:12 +010024 ## args)
Harald Welte297d72e2019-03-28 18:42:35 +010025
Harald Welte77911b02018-08-14 23:47:30 +020026struct bankd;
27
Harald Welte8d858292018-08-15 23:36:46 +020028enum bankd_worker_state {
29 /* just started*/
30 BW_ST_INIT,
31 /* blocking in the accept() call on the server socket fd */
32 BW_ST_ACCEPTING,
33 /* TCP established, but peer not yet identified itself */
34 BW_ST_CONN_WAIT_ID,
35 /* TCP established, client has identified itself, no mapping */
36 BW_ST_CONN_CLIENT,
Harald Welteaf614732018-08-17 22:10:05 +020037 /* TCP established, client has identified itself, waiting for mapping */
38 BW_ST_CONN_CLIENT_WAIT_MAP,
Harald Welte8d858292018-08-15 23:36:46 +020039 /* TCP established, client has identified itself, mapping exists */
40 BW_ST_CONN_CLIENT_MAPPED,
41 /* TCP established, client identified, mapping exists, card opened */
42 BW_ST_CONN_CLIENT_MAPPED_CARD,
Harald Welte00a96732019-03-11 17:18:02 +010043 /* TCP established, client identified, but mapping [meanwhile] removed */
44 BW_ST_CONN_CLIENT_UNMAPPED
Harald Welte8d858292018-08-15 23:36:46 +020045};
46
Harald Welte77911b02018-08-14 23:47:30 +020047
48/* bankd worker instance; one per card/slot, includes thread */
49struct bankd_worker {
50 /* global list of workers */
51 struct llist_head list;
52 /* back-pointer to bankd */
53 struct bankd *bankd;
54
Harald Welte286a2be2019-03-11 17:36:58 +010055 /* name of the worker */
56 char *name;
57
Harald Welte8d858292018-08-15 23:36:46 +020058 /* thread number */
59 unsigned int num;
60 /* worker thread state */
61 enum bankd_worker_state state;
Harald Welte694df832018-10-03 22:47:52 +020062 /* timeout to use for blocking read */
63 unsigned int timeout;
Harald Welte8d858292018-08-15 23:36:46 +020064
Harald Welte77911b02018-08-14 23:47:30 +020065 /* slot number we are representing */
66 struct bank_slot slot;
67
68 /* thread of this worker. */
69 pthread_t thread;
Harald Welte25075972019-03-11 17:33:17 +010070 /* top talloc context for this worker/thread */
71 void *tall_ctx;
Harald Welte77911b02018-08-14 23:47:30 +020072
Harald Welte297d72e2019-03-28 18:42:35 +010073 const struct bankd_driver_ops *ops;
74
Harald Welte77911b02018-08-14 23:47:30 +020075 /* File descriptor of the TCP connection to the remsim-client (modem) */
76 struct {
77 int fd;
78 struct sockaddr_storage peer_addr;
79 socklen_t peer_addr_len;
Harald Welte371d0262018-08-16 15:23:58 +020080 struct client_slot clslot;
Harald Welte77911b02018-08-14 23:47:30 +020081 } client;
82
83 struct {
84 const char *name;
85 union {
86 struct {
87 /* PC/SC context / application handle */
88 SCARDCONTEXT hContext;
89 /* PC/SC card handle */
90 SCARDHANDLE hCard;
91 } pcsc;
92 };
93 } reader;
Harald Welte1f699b42019-03-28 13:41:08 +010094
95 struct {
96 uint8_t atr[MAX_ATR_SIZE];
97 unsigned int atr_len;
98 } card;
James Tavaresf74d1da2022-11-14 00:21:12 -050099
100 /* last known state of the SIM card VCC indication */
101 bool last_vccPresent;
102
103 /* last known state of the SIM card reset indication */
104 bool last_resetActive;
Harald Welte77911b02018-08-14 23:47:30 +0200105};
106
Harald Welte297d72e2019-03-28 18:42:35 +0100107/* bankd card reader driver operations */
108struct bankd_driver_ops {
109 /* open a given card/slot: called once client + mapping exists */
110 int (*open_card)(struct bankd_worker *worker);
Harald Weltebbd18bd2019-12-16 13:11:50 +0100111 /* reset a given card/slot with either cold or warm reset */
112 int (*reset_card)(struct bankd_worker *worker, bool cold_reset);
Harald Welte297d72e2019-03-28 18:42:35 +0100113 int (*transceive)(struct bankd_worker *worker, const uint8_t *out, size_t out_len,
114 uint8_t *in, size_t *in_len);
115 /* called at cleanup time of a worker thread: clear any driver related state */
116 void (*cleanup)(struct bankd_worker *worker);
117};
Harald Welte77911b02018-08-14 23:47:30 +0200118
119/* global bank deamon */
120struct bankd {
Harald Weltef1dd1622018-09-24 14:54:23 +0200121 struct app_comp_id comp_id;
Harald Welte707c85a2019-03-09 12:56:35 +0100122 /* RSPRO connection to the remsim-server */
123 struct rspro_server_conn srvc;
Harald Weltef1dd1622018-09-24 14:54:23 +0200124
Harald Welte77911b02018-08-14 23:47:30 +0200125 /* TCP socket at which we are listening */
126 int accept_fd;
127
Harald Weltecbd18962019-03-03 19:02:38 +0100128 /* list of slot mappings. only ever modified in main thread! */
129 struct slotmaps *slotmaps;
Harald Welte77911b02018-08-14 23:47:30 +0200130
Harald Welte25075972019-03-11 17:33:17 +0100131 /* pthread ID of main thread */
132 pthread_t main;
133
Harald Welte77911b02018-08-14 23:47:30 +0200134 /* list of bankd_workers. accessed/modified by multiple threads; protected by mutex */
135 struct llist_head workers;
136 pthread_mutex_t workers_mutex;
Harald Welte45c948c2018-09-23 19:26:52 +0200137
138 struct llist_head pcsc_slot_names;
Harald Welte628672b2022-07-13 15:20:13 +0200139
140 struct {
141 bool permit_shared_pcsc;
142 } cfg;
Harald Welte77911b02018-08-14 23:47:30 +0200143};
Harald Welte45c948c2018-09-23 19:26:52 +0200144
145int bankd_pcsc_read_slotnames(struct bankd *bankd, const char *csv_file);
146const char *bankd_pcsc_get_slot_name(struct bankd *bankd, const struct bank_slot *slot);
Harald Welte297d72e2019-03-28 18:42:35 +0100147
148extern const struct bankd_driver_ops pcsc_driver_ops;