[[remsim-bankd]] == osmo-remsim-bankd The `osmo-remsim-bankd` (SIM Bank Daemon) manages one given SIM bank. The initial implementation supports a PC/SC driver to expose any PC/SC compatible card readers as SIM bank. `osmo-remsim-bankd` initially connects via a RSPRO control connection to `osmo-remsim-server` at startup, and will in turn receive a set of initial [client,slot]:[bankd,slot] mappings. These mappings determine which slot on the client (corresponding to a modem) is mapped to which slot on the SIM bank. Mappings can be updated by `osmo-remsim-server` at any given point in time. `osmo-remsim-bankd` implements a RSPRO server, where it listens to connections from `osmo-remsim-clients`. As PC/SC only offers a blocking API, there is one thread per PC/SC slot. This thread will perform blocking I/O on the socket towards the client, and blocking API calls on PC/SC. In terms of thread handling, we do: * accept() handling in [spare] worker threads ** this means blocking I/O can be used, as each worker thread only has one TCP connection ** client identifies itself with client:slot ** lookup mapping based on client:slot (using mutex for protection) ** open the reader based on the lookup result The worker threads initially don't have any mapping to a specific reader, and that mapping is only established at a later point after the client has identified itself. The advantage is that the entire bankd can live without any non-blocking I/O. The main thread handles the connection to `osmo-remsim-server`, where it can also use non-blocking I/O. However, re-connection would be required, to avoid stalling all banks/cards in the event of a connection loss to the server. worker threads have the following states: * INIT (just started) * ACCEPTING (they're blocking in the accept() call on the server socket fd) * CONNECTED_WAIT_ID (TCP established, but peer not yet identified itself) * CONNECTED_CLIENT (TCP established, client has identified itself, no mapping) * CONNECTED_CLIENT_MAPPED (TCP established, client has identified itself, mapping exists) * CONNECTED_CLIENT_MAPPED_CARD (TCP established, client identified, mapping exists, card opened) * CONNECTED_SERVER (TCP established, server has identified itself) Once the client disconnects, or any other error occurs (such as card I/O errors), the worker thread either returns to INIT state (closing client socket and reader), or it terminates. Termination would mean that the main thread would have to do non-blocking join to detect client termination and then re-spawn clients, so the "return to INIT state" approach seems to make more sense. === Running `osmo-remsim-bankd` currently has the following command-line options: ==== SYNOPSIS *osmo-remsim-bankd* [-h] [-V] [-d LOGOPT] [-i A.B.C.D] [-p <1-65535>] [-b <1-1023>] [-n <1-1023>] [-I A.B.C.D] [-P <1-65535> ] ==== OPTIONS *-h, --help*:: Print a short help message about the supported options *-V, --version*:: Print the software version number *-d, --debug LOGOPT*:: Configure the logging verbosity, see <>. *-i, --server-host A.B.C.D*:: Specify the remote IP address/hostname of the `osmo-remsim-server` to which this bankd shall establish its RSPRO control connection *-p, --server-port <1-65535>*:: Specify the remote TCP port number of the `osmo-remsim-server` to which this bankd shall establish its RSPRO control connection *-b, --bank-id <1-1023>*:: Specify the numeric bank identifier of the SIM bank this bankd instance operates. Must be unique among all banks connecting to the same `osmo-remsim-server`. *-n, --num-slots <1-1023>*:: Specify the number of slots that this bankd handles. *-I, --bind-IP A.B.C.D*:: Specify the local IP address to which the socket for incoming connections from `osmo-remsim-clients` is bound to. *-P, --bind-port <1-65535>*:: Specify the local TCP port to which the socket for incoming connections from `osmo-remsim-client`s is bound to. ==== Examples .remsim-server is on 10.2.3.4, cardreader has 5 slots: ---- osmo-remsim-bankd -i 10.2.3.4 -n 5 ---- .remsim-server is on 10.2.3.4, cardreader has 4 slots, local ip is 10.5.4.3 ---- osmo-remsim-bankd -i 10.2.3.4 -n 4 -I 10.5.4.3 ---- === Logging `osmo-remsim-bankd` currently logs to stdout only, and the logging verbosity is not yet configurable. However, as the libosmocore logging framework is used, extending this is an easy modification. === `bankd_pcsc_slots.csv` CSV file bankd expects a CSV file `bankd_pcsc_slots.csv` in the current working directory at startup. This CSV file specifies the mapping between the string names of the PCSC readers and the RSPRO bandk/slot numbers. The format is as follows: * first column: bankd number * second column: slot number within bankd * third column: extended POSIX regular expression matching the slot .Example: CSV file mapping bankd slots 0..4 to an ACS ACR33U-A1 reader slots ---- "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" ---- You can obtain the exact string to use as PC/SC reader name from the output of the `pcsc_scan` utility (part of pcsc-lite package). The tool will produce output like: .Example: Output of `pcsc_scan` utility on a system with a single reader installed ---- Scanning present readers... 0: Alcor Micro AU9560 00 00 ---- In this example, there's only a single PC/SC reader available, and it has a string of "Alcor Micro AU9560 00 00" which needs to be used in the CSV file. NOTE:: If the reader name contains any special characters, they might need to be escaped according to the extended POSIX regular expression syntax. See `man 7 regex` for a reference. .Example: CSV file mapping bankd slots 0..7 to a sysmoOCTSIM: ---- "1","0","sysmocom sysmoOCTSIM \[CCID\] \(ab19180f3335355320202034463a15ff\) [0-9]{2} 00" "1","1","sysmocom sysmoOCTSIM \[CCID\] \(ab19180f3335355320202034463a15ff\) [0-9]{2} 01" "1","2","sysmocom sysmoOCTSIM \[CCID\] \(ab19180f3335355320202034463a15ff\) [0-9]{2} 02" "1","3","sysmocom sysmoOCTSIM \[CCID\] \(ab19180f3335355320202034463a15ff\) [0-9]{2} 03" "1","4","sysmocom sysmoOCTSIM \[CCID\] \(ab19180f3335355320202034463a15ff\) [0-9]{2} 04" "1","5","sysmocom sysmoOCTSIM \[CCID\] \(ab19180f3335355320202034463a15ff\) [0-9]{2} 05" "1","6","sysmocom sysmoOCTSIM \[CCID\] \(ab19180f3335355320202034463a15ff\) [0-9]{2} 06" "1","7","sysmocom sysmoOCTSIM \[CCID\] \(ab19180f3335355320202034463a15ff\) [0-9]{2} 07" ---- In the above example, the +\[CCID\]+ and the +\(serialnumber\)+ both had to be escaped. The +[0-9]\{2\}+ construct exists to perform wildcard matching, no matter which particular two-digit number pcscd decides to use.