jtavares has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-remsim/+/30140 )
Change subject: bankd: edge detect RESET and VCC indications ......................................................................
bankd: edge detect RESET and VCC indications
- perform edge detection on RESET and VCC client indications to filter out duplicate resets - prior to this change, unrelated changes in the client slot status indication (such as CLK change) could trigger duplicate resets - these resets could happen in rapid succession and lead to reader libusb communication errors that lock-up the PC/SC daemon - a drop in VCC will always induce a cold reset, even if a warm reset is already in progress. - overall, this change better matches what the hardware would do
Change-Id: I36d30d176c0a03d97554112ca712d658d986c752 --- M src/bankd/bankd.h M src/bankd/bankd_main.c 2 files changed, 28 insertions(+), 4 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-remsim refs/changes/40/30140/1
diff --git a/src/bankd/bankd.h b/src/bankd/bankd.h index 0f94818..e340b5a 100644 --- a/src/bankd/bankd.h +++ b/src/bankd/bankd.h @@ -96,6 +96,12 @@ uint8_t atr[MAX_ATR_SIZE]; unsigned int atr_len; } card; + + /* last known state of the SIM card VCC indication */ + bool last_vccPresent; + + /* last known state of the SIM card reset indication */ + bool last_resetActive; };
/* bankd card reader driver operations */ diff --git a/src/bankd/bankd_main.c b/src/bankd/bankd_main.c index b3b8dff..10334ff 100644 --- a/src/bankd/bankd_main.c +++ b/src/bankd/bankd_main.c @@ -115,6 +115,8 @@ worker->bankd = bankd; worker->num = i; worker->ops = &pcsc_driver_ops; + worker->last_vccPresent = true; /* allow cold reset should first indication be false */ + worker->last_resetActive = false; /* allow warm reset should first indication be true */
/* in the initial state, the worker has no client.fd, bank_slot or pcsc handle yet */
@@ -774,10 +776,26 @@ sps->clkActive ? *sps->clkActive ? "ACTIVE" : "INACTIVE" : "NULL");
/* perform cold or warm reset */ - if (sps->vccPresent && *sps->vccPresent == 0) - rc = worker->ops->reset_card(worker, true); - else if (sps->resetActive) - rc = worker->ops->reset_card(worker, false); + if (sps->vccPresent && *sps->vccPresent == 0) { + /* VCC is not present */ + + if (worker->last_vccPresent) { + /* falling edge detected on VCC; perform cold reset */ + rc = worker->ops->reset_card(worker, true); + } + } else if (sps->resetActive) { + if (!worker->last_resetActive) { + /* VCC is present (or not reported) and rising edge detected on reset; perform warm reset */ + rc = worker->ops->reset_card(worker, false); + } + } + + /* update last known states */ + if (sps->vccPresent) { + worker->last_vccPresent = *sps->vccPresent != 0; + } + + worker->last_resetActive = sps->resetActive != 0;
return rc; }