sim: Prepare infrastructure for protocols != T=0 and other drivers
diff --git a/include/osmocom/sim/sim.h b/include/osmocom/sim/sim.h
index 4c47afc..d68d7c2 100644
--- a/include/osmocom/sim/sim.h
+++ b/include/osmocom/sim/sim.h
@@ -320,10 +320,22 @@
 
 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_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 @@
 
 /* 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 4f72dd0..160f175 100644
--- a/src/sim/reader.c
+++ b/src/sim/reader.c
@@ -217,35 +217,55 @@
 	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 c5b8112..5e67091 100644
--- a/src/sim/reader_pcsc.c
+++ b/src/sim/reader_pcsc.c
@@ -97,13 +97,17 @@
 	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 0a3772b..c10c5f0 100644
--- a/src/sim/sim_int.h
+++ b/src/sim/sim_int.h
@@ -32,7 +32,7 @@
 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 3acbd71..244c2df 100644
--- a/utils/osmo-sim-test.c
+++ b/utils/osmo-sim-test.c
@@ -374,10 +374,10 @@
 	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);