Osmocom Remote SIM Software Suite https://osmocom.org/projects/osmo-remsim
Go to file
Harald Welte 38d990b0be client: Work around "stock on PTS" problem
I can occasionally see osmo-remsim-client-st2 get stuck when the Modem
(in this case a Quectel EC20) is performing PTS with the card.

In the log of osmo-remsim-client-st2 I can see:

SIMtrace => PTS req: ff 10 94 7b 00 00
SIMtrace -> 01 07 00 00 00 00 15 00 04 ff 10 94 7b 00 00 ff 10 94 7b
SIMtrace => PTS req: ff 10 94 7b 00 00
SIMtrace IRQ 01 04 00 00 00 00 15 00 13 00 00 00 00 00 09 04 0a 80 25 00 00

after which the communication doesn't proceed. After a long time, the
modem seems to retry without PTS and then proceeds with normal SIM card
communication.

Interestingly, both the firmware and a usbmon trace agree that the first
APDU header after the PTS is actually sent in an USB IN transfer:

-I- 0: computed Fi(1) Di(1) ratio: 372
-I- 0: computed Fi(9) Di(4) ratio: 64
-I- 0: send_tpdu_header: 00 a4 00 04 02
-I- 0: flush_rx_buffer (5)

usbmon shows 010600000000130001000000050000a4000402

It's unclear why the host program doesn't get the data from the IN
transfer.  However, if multiple asynchronous IN EP URB are submited,
the problem can be reproducibly avoided.  Let's do that.

Change-Id: I2fa5f71869b124b73e0c312befce1ca268e9a9a2
Closes: OS#4409
2020-02-21 22:09:45 +01:00
asn1 RSPRO: Add new ResetState{Req,Res} 2019-12-04 21:52:58 +01:00
contrib jenkins.sh: don't verify (possibly outdated) deps 2019-12-17 13:31:20 +01:00
debian require minimum version 1.3.0 of libosmocore 2020-01-12 19:41:36 +01:00
doc remsim-client: Call an external script in specific situations 2020-02-16 15:41:56 +01:00
ffasn1c add ffasn1c example for RSPRO 2018-09-24 17:46:05 +02:00
include RSPRO: Add new ResetState{Req,Res} 2019-12-04 21:52:58 +01:00
src client: Work around "stock on PTS" problem 2020-02-21 22:09:45 +01:00
.gitignore update .gitignore 2019-04-03 13:15:53 +02:00
.gitreview Add git-review config 2019-02-14 19:07:32 +01:00
COPYING add missing copyright / license headers everywhere 2019-03-09 13:11:56 +01:00
Makefile.am add contrib/remsim-apitool.py to control the REST-interface of osmo-remsim-server 2019-07-30 11:39:15 +02:00
README.md README.md: add 'osmo-' prefix to remsim-{server,bankd,client} 2019-04-03 17:24:42 +02:00
configure.ac remsim-client: move from common 'src' directory to 'src/client' 2020-02-16 15:41:12 +01:00
git-version-gen initial checkin of osmo-remsim 2018-08-15 08:54:50 +02:00
libosmo-rspro.pc.in Add libosmo-rspro.pc.in for pkg-config integration 2019-04-03 09:35:48 +02:00
move-asn1-header-files.sh initial checkin of osmo-remsim 2018-08-15 08:54:50 +02:00

README.md

osmo-remsim - Osmocom remote SIM software suite

This software suite is a work in progress.

osmo-remsim-client

The client interfaces with GSM phones / modems via dedicated "Card Emulation" devices such as the Osmocom SIMtrace2 or sysmocom sysmoQMOD board + firmware. This hardware implements the ISO7816-3 electrical interface and protocol handling and passes any TPDU headers received from the phone/modem to osmo-remsim-client for further processing of the TPDUs associated to the given APDU transfer.

osmo-remsim-client connects via a RSPRO control connection to osmo-remsim-server at startup and registers itself. It will receive configuration data such as the osmo-remsim-bankd IP+Port and the ClientId from osmo-remsim-server.

After receiving the configuration, osmo-remsim-client will establish a RSPRO data connection to the osmo-remsim-bankd IP:Port.

As the USB interface for remote SIM in simtrace2.git uses one interface per slot, we can implement the client in blocking mode, i.e. use blocking I/O on the TCP/RSPRO side. This simplifies the code compared to a more complex async implementation.

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.

Open topics:

  • detecting multiple connections from a server, logging this or even avoiding that situation