summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2014-10-26 18:46:50 +0100
committerHarald Welte <laforge@gnumonks.org>2014-10-26 19:50:51 +0100
commit55790aa09a8f92d437ea06b3ef2c74465612fa8b (patch)
tree749a2f2e2a009644dde4c6f4ecd9c8384d006dce
parent586d710e0586a51ba19b71bf20f2bb12aa8c0aeb (diff)
sim: Prepare infrastructure for protocols != T=0 and other drivers
-rw-r--r--include/osmocom/sim/sim.h19
-rw-r--r--src/sim/reader.c48
-rw-r--r--src/sim/reader_pcsc.c6
-rw-r--r--src/sim/sim_int.h2
-rw-r--r--utils/osmo-sim-test.c4
5 files changed, 59 insertions, 20 deletions
diff --git a/include/osmocom/sim/sim.h b/include/osmocom/sim/sim.h
index 4c47afc4..d68d7c2c 100644
--- a/include/osmocom/sim/sim.h
+++ b/include/osmocom/sim/sim.h
@@ -320,10 +320,22 @@ struct msgb *osim_new_apdumsg(uint8_t cla, uint8_t ins, uint8_t p1,
struct osim_reader_ops;
+enum osim_proto {
+ OSIM_PROTO_T0 = 0,
+ OSIM_PROTO_T1 = 1,
+};
+
+enum osim_reader_driver {
+ OSIM_READER_DRV_PCSC = 0,
+ OSIM_READER_DRV_OPENCT = 1,
+ OSIM_READER_DRV_SERIAL = 2,
+};
+
struct osim_reader_hdl {
/*! \brief member in global list of readers */
struct llist_head list;
struct osim_reader_ops *ops;
+ uint32_t proto_supported;
void *priv;
/*! \brief current card, if any */
struct osim_card_hdl *card;
@@ -336,6 +348,8 @@ struct osim_card_hdl {
struct osim_reader_hdl *reader;
/*! \brief card profile */
struct osim_card_profile *prof;
+ /*! \brief card protocol */
+ enum osim_proto proto;
/*! \brief list of channels for this card */
struct llist_head channels;
@@ -351,6 +365,7 @@ struct osim_chan_hdl {
/* reader.c */
int osim_transceive_apdu(struct osim_chan_hdl *st, struct msgb *amsg);
-struct osim_reader_hdl *osim_reader_open(int idx, const char *name, void *ctx);
-struct osim_card_hdl *osim_card_open(struct osim_reader_hdl *rh);
+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);
#endif /* _OSMOCOM_SIM_H */
diff --git a/src/sim/reader.c b/src/sim/reader.c
index 4f72dd0f..160f1758 100644
--- a/src/sim/reader.c
+++ b/src/sim/reader.c
@@ -217,35 +217,55 @@ case_2s:
return sw;
}
-/* According to ISO7816-4 Annex B */
-static int transceive_apdu_t1(struct osim_card_hdl *st, struct msgb *amsg)
-{
- return -1;
-}
+/* FIXME: T=1 According to ISO7816-4 Annex B */
int osim_transceive_apdu(struct osim_chan_hdl *st, struct msgb *amsg)
{
- /* FIXME: check for protocol */
- return transceive_apdu_t0(st->card, amsg);
+ switch (st->card->proto) {
+ case OSIM_PROTO_T0:
+ return transceive_apdu_t0(st->card, amsg);
+ default:
+ return -ENOTSUP;
+ }
}
-
-
-struct osim_reader_hdl *osim_reader_open(int idx, const char *name, void *ctx)
+struct osim_reader_hdl *osim_reader_open(enum osim_reader_driver driver, int idx,
+ const char *name, void *ctx)
{
- /* FIXME: support multiple drivers */
- const struct osim_reader_ops *ops = &pcsc_reader_ops;
+ const struct osim_reader_ops *ops;
struct osim_reader_hdl *rh;
+ switch (driver) {
+ case OSIM_READER_DRV_PCSC:
+ ops = &pcsc_reader_ops;
+ break;
+ default:
+ return NULL;
+ }
+
rh = ops->reader_open(idx, name, ctx);
if (!rh)
return NULL;
rh->ops = ops;
+ /* FIXME: for now we only do T=0 on all readers */
+ rh->proto_supported = (1 << OSIM_PROTO_T0);
+
return rh;
}
-struct osim_card_hdl *osim_card_open(struct osim_reader_hdl *rh)
+struct osim_card_hdl *osim_card_open(struct osim_reader_hdl *rh, enum osim_proto proto)
{
- return rh->ops->card_open(rh);
+ struct osim_card_hdl *ch;
+
+ if (!(rh->proto_supported & (1 << proto)))
+ return NULL;
+
+ ch = rh->ops->card_open(rh, proto);
+ if (!ch)
+ return NULL;
+
+ ch->proto = proto;
+
+ return ch;
}
diff --git a/src/sim/reader_pcsc.c b/src/sim/reader_pcsc.c
index c5b8112b..5e670912 100644
--- a/src/sim/reader_pcsc.c
+++ b/src/sim/reader_pcsc.c
@@ -97,13 +97,17 @@ end:
return NULL;
}
-static struct osim_card_hdl *pcsc_card_open(struct osim_reader_hdl *rh)
+static struct osim_card_hdl *pcsc_card_open(struct osim_reader_hdl *rh,
+ enum osim_proto proto)
{
struct pcsc_reader_state *st = rh->priv;
struct osim_card_hdl *card;
struct osim_chan_hdl *chan;
LONG rc;
+ if (proto != OSIM_PROTO_T0)
+ return NULL;
+
rc = SCardConnect(st->hContext, st->name, SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0, &st->hCard, &st->dwActiveProtocol);
PCSC_ERROR(rc, "SCardConnect");
diff --git a/src/sim/sim_int.h b/src/sim/sim_int.h
index 0a3772bc..c10c5f08 100644
--- a/src/sim/sim_int.h
+++ b/src/sim/sim_int.h
@@ -32,7 +32,7 @@ add_adf_with_ef(struct osim_file_desc *parent,
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);
+ struct osim_card_hdl *(*card_open)(struct osim_reader_hdl *rh, enum osim_proto proto);
int (*transceive)(struct osim_reader_hdl *rh, struct msgb *msg);
};
diff --git a/utils/osmo-sim-test.c b/utils/osmo-sim-test.c
index 3acbd71d..244c2df3 100644
--- a/utils/osmo-sim-test.c
+++ b/utils/osmo-sim-test.c
@@ -374,10 +374,10 @@ int main(int argc, char **argv)
struct msgb *msg;
int rc;
- reader = osim_reader_open(0, "", NULL);
+ reader = osim_reader_open(OSIM_READER_DRV_PCSC, 0, "", NULL);
if (!reader)
exit(1);
- card = osim_card_open(reader);
+ card = osim_card_open(reader, OSIM_PROTO_T0);
if (!card)
exit(2);
chan = llist_entry(card->channels.next, struct osim_chan_hdl, list);