sim: Prepare infrastructure for protocols != T=0 and other drivers

This commit is contained in:
Harald Welte 2014-10-26 18:46:50 +01:00
parent 586d710e05
commit 55790aa09a
5 changed files with 59 additions and 20 deletions

View File

@ -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 */

View File

@ -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;
}

View File

@ -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");

View File

@ -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);
};

View File

@ -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);