blob: d56734c961823c0b1bb11d3d97a4aefdc2596315 [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 Welte707c85a2019-03-09 12:56:35 +010017#include "client.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...) \
23 printf("[%03u %s] %s:%u " fmt, (w)->num, get_value_string(worker_state_names, (w)->state), \
24 __FILE__, __LINE__, ## args)
25
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;
Harald Welte77911b02018-08-14 23:47:30 +020099};
100
Harald Welte297d72e2019-03-28 18:42:35 +0100101/* bankd card reader driver operations */
102struct bankd_driver_ops {
103 /* open a given card/slot: called once client + mapping exists */
104 int (*open_card)(struct bankd_worker *worker);
105 int (*transceive)(struct bankd_worker *worker, const uint8_t *out, size_t out_len,
106 uint8_t *in, size_t *in_len);
107 /* called at cleanup time of a worker thread: clear any driver related state */
108 void (*cleanup)(struct bankd_worker *worker);
109};
Harald Welte77911b02018-08-14 23:47:30 +0200110
111/* global bank deamon */
112struct bankd {
113 struct {
114 uint16_t bank_id;
Harald Weltea0f39502019-03-09 20:59:34 +0100115 uint16_t num_slots;
Harald Welte77911b02018-08-14 23:47:30 +0200116 } cfg;
117
Harald Weltef1dd1622018-09-24 14:54:23 +0200118 struct app_comp_id comp_id;
Harald Welte707c85a2019-03-09 12:56:35 +0100119 /* RSPRO connection to the remsim-server */
120 struct rspro_server_conn srvc;
Harald Weltef1dd1622018-09-24 14:54:23 +0200121
Harald Welte77911b02018-08-14 23:47:30 +0200122 /* TCP socket at which we are listening */
123 int accept_fd;
124
Harald Weltecbd18962019-03-03 19:02:38 +0100125 /* list of slot mappings. only ever modified in main thread! */
126 struct slotmaps *slotmaps;
Harald Welte77911b02018-08-14 23:47:30 +0200127
Harald Welte25075972019-03-11 17:33:17 +0100128 /* pthread ID of main thread */
129 pthread_t main;
130
Harald Welte77911b02018-08-14 23:47:30 +0200131 /* list of bankd_workers. accessed/modified by multiple threads; protected by mutex */
132 struct llist_head workers;
133 pthread_mutex_t workers_mutex;
Harald Welte45c948c2018-09-23 19:26:52 +0200134
135 struct llist_head pcsc_slot_names;
Harald Welte77911b02018-08-14 23:47:30 +0200136};
Harald Welte45c948c2018-09-23 19:26:52 +0200137
138int bankd_pcsc_read_slotnames(struct bankd *bankd, const char *csv_file);
139const char *bankd_pcsc_get_slot_name(struct bankd *bankd, const struct bank_slot *slot);
Harald Welte297d72e2019-03-28 18:42:35 +0100140
141extern const struct bankd_driver_ops pcsc_driver_ops;