aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO-RELEASE1
-rw-r--r--include/osmocom/sim/sim.h4
-rw-r--r--src/sim/reader.c21
-rw-r--r--src/sim/reader_pcsc.c30
4 files changed, 56 insertions, 0 deletions
diff --git a/TODO-RELEASE b/TODO-RELEASE
index e57ffaba..ad644aaf 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -12,3 +12,4 @@ libosmogsm gsm0808_old_bss_to_new_bss_info ABI break (struct changes size),
libosmosim osim_card_hdl ABI + API breakage due to new struct members
libosmocore osmo_tdef_fsm_inst_state_chg change default_timeout arg from unsigned long to long type (API breakage, not ABI)
libosmovty vty_read_config_filep New API
+libosmosim osim_card_{reset,close} New API
diff --git a/include/osmocom/sim/sim.h b/include/osmocom/sim/sim.h
index 16b9f1fa..5e7099f4 100644
--- a/include/osmocom/sim/sim.h
+++ b/include/osmocom/sim/sim.h
@@ -375,6 +375,8 @@ struct osim_reader_ops {
const char *name;
struct osim_reader_hdl *(*reader_open)(int idx, const char *name, void *ctx);
struct osim_card_hdl *(*card_open)(struct osim_reader_hdl *rh, enum osim_proto proto);
+ int (*card_reset)(struct osim_card_hdl *card, bool cold_reset);
+ int (*card_close)(struct osim_card_hdl *card);
int (*transceive)(struct osim_reader_hdl *rh, struct msgb *msg);
};
@@ -441,4 +443,6 @@ int osim_transceive_apdu(struct osim_chan_hdl *st, struct msgb *amsg);
struct osim_reader_hdl *osim_reader_open(enum osim_reader_driver drv, int idx,
const char *name, void *ctx);
struct osim_card_hdl *osim_card_open(struct osim_reader_hdl *rh, enum osim_proto proto);
+int osim_card_reset(struct osim_card_hdl *card, bool cold_reset);
+int osim_card_close(struct osim_card_hdl *card);
#endif /* _OSMOCOM_SIM_H */
diff --git a/src/sim/reader.c b/src/sim/reader.c
index ae0aba94..7f3f18d9 100644
--- a/src/sim/reader.c
+++ b/src/sim/reader.c
@@ -277,3 +277,24 @@ struct osim_card_hdl *osim_card_open(struct osim_reader_hdl *rh, enum osim_proto
return ch;
}
+
+int osim_card_reset(struct osim_card_hdl *card, bool cold_reset)
+{
+ struct osim_reader_hdl *rh = card->reader;
+
+ return rh->ops->card_reset(card, cold_reset);
+}
+
+int osim_card_close(struct osim_card_hdl *card)
+{
+ struct osim_reader_hdl *rh = card->reader;
+ int rc;
+
+ rc = rh->ops->card_close(card);
+
+ card->reader = NULL;
+ talloc_free(card);
+ rh->card = NULL;
+
+ return rc;
+}
diff --git a/src/sim/reader_pcsc.c b/src/sim/reader_pcsc.c
index 234a9a77..fa867c08 100644
--- a/src/sim/reader_pcsc.c
+++ b/src/sim/reader_pcsc.c
@@ -156,6 +156,34 @@ end:
return NULL;
}
+static int pcsc_card_reset(struct osim_card_hdl *card, bool cold_reset)
+{
+ struct pcsc_reader_state *st = card->reader->priv;
+ LONG rc;
+
+ rc = SCardReconnect(st->hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0,
+ cold_reset ? SCARD_UNPOWER_CARD : SCARD_RESET_CARD,
+ &st->dwActiveProtocol);
+ PCSC_ERROR(rc, "SCardReconnect");
+
+ return 0;
+end:
+ return -EIO;
+}
+
+static int pcsc_card_close(struct osim_card_hdl *card)
+{
+ struct pcsc_reader_state *st = card->reader->priv;
+ LONG rc;
+
+ rc = SCardDisconnect(st->hCard, SCARD_UNPOWER_CARD);
+ PCSC_ERROR(rc, "SCardDisconnect");
+
+ return 0;
+end:
+ return -EIO;
+}
+
static int pcsc_transceive(struct osim_reader_hdl *rh, struct msgb *msg)
{
@@ -179,6 +207,8 @@ const struct osim_reader_ops pcsc_reader_ops = {
.name = "PC/SC",
.reader_open = pcsc_reader_open,
.card_open = pcsc_card_open,
+ .card_reset = pcsc_card_reset,
+ .card_close = pcsc_card_close,
.transceive = pcsc_transceive,
};