bankd_main: Obtain ATR of card via PC/SC API
Change-Id: Ie73806e2190e604cab96b3f632b4bbfffb7d0112changes/97/13497/1
parent
e57334ed9d
commit
1f699b405a
|
@ -83,6 +83,11 @@ struct bankd_worker {
|
|||
} pcsc;
|
||||
};
|
||||
} reader;
|
||||
|
||||
struct {
|
||||
uint8_t atr[MAX_ATR_SIZE];
|
||||
unsigned int atr_len;
|
||||
} card;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -311,6 +311,8 @@ if (rv != SCARD_S_SUCCESS) { \
|
|||
LOGW((w), ": OK\n"); \
|
||||
}
|
||||
|
||||
static int worker_send_rspro(struct bankd_worker *worker, RsproPDU_t *pdu);
|
||||
|
||||
static void worker_set_state(struct bankd_worker *worker, enum bankd_worker_state new_state)
|
||||
{
|
||||
LOGW(worker, "Changing state to %s\n", get_value_string(worker_state_names, new_state));
|
||||
|
@ -404,6 +406,17 @@ static int worker_open_card(struct bankd_worker *worker)
|
|||
PCSC_ERROR(worker, rc, "SCardConnect")
|
||||
}
|
||||
|
||||
/* use DWORD type as this is what the PC/SC API expects */
|
||||
char pbReader[MAX_READERNAME];
|
||||
DWORD dwReaderLen = sizeof(pbReader);
|
||||
DWORD dwAtrLen = worker->card.atr_len = sizeof(worker->card.atr);
|
||||
DWORD dwState, dwProt;
|
||||
rc = SCardStatus(worker->reader.pcsc.hCard, pbReader, &dwReaderLen, &dwState, &dwProt,
|
||||
worker->card.atr, &dwAtrLen);
|
||||
PCSC_ERROR(worker, rc, "SCardStatus")
|
||||
worker->card.atr_len = dwAtrLen;
|
||||
LOGW(worker, "Card ATR: %s\n", osmo_hexdump_nospc(worker->card.atr, worker->card.atr_len));
|
||||
|
||||
worker_set_state(worker, BW_ST_CONN_CLIENT_MAPPED_CARD);
|
||||
/* FIXME: notify client about this state change */
|
||||
|
||||
|
@ -508,6 +521,17 @@ static int worker_try_slotmap(struct bankd_worker *worker)
|
|||
}
|
||||
}
|
||||
|
||||
/* inform the remote end (client) about the (new) ATR */
|
||||
static int worker_send_atr(struct bankd_worker *worker)
|
||||
{
|
||||
RsproPDU_t *set_atr;
|
||||
set_atr = rspro_gen_SetAtrReq(worker->client.clslot.client_id,
|
||||
worker->client.clslot.slot_nr,
|
||||
worker->card.atr, worker->card.atr_len);
|
||||
if (!set_atr)
|
||||
return -1;
|
||||
return worker_send_rspro(worker, set_atr);
|
||||
}
|
||||
|
||||
static int worker_handle_connectClientReq(struct bankd_worker *worker, const RsproPDU_t *pdu)
|
||||
{
|
||||
|
@ -544,7 +568,14 @@ static int worker_handle_connectClientReq(struct bankd_worker *worker, const Rsp
|
|||
res = ResultCode_cardNotPresent;
|
||||
|
||||
resp = rspro_gen_ConnectClientRes(&worker->bankd->comp_id, res);
|
||||
return worker_send_rspro(worker, resp);
|
||||
rc = worker_send_rspro(worker, resp);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (res == ResultCode_ok)
|
||||
rc = worker_send_atr(worker);
|
||||
|
||||
return rc;
|
||||
|
||||
respond_and_err:
|
||||
if (res) {
|
||||
|
@ -658,15 +689,17 @@ restart_wait:
|
|||
switch (worker->state) {
|
||||
case BW_ST_CONN_CLIENT_WAIT_MAP:
|
||||
/* re-check if mapping exists meanwhile? */
|
||||
worker_try_slotmap(worker);
|
||||
rc = worker_try_slotmap(worker);
|
||||
break;
|
||||
case BW_ST_CONN_CLIENT_MAPPED:
|
||||
/* re-check if reader/card can be opened meanwhile? */
|
||||
worker_open_card(worker);
|
||||
rc = worker_open_card(worker);
|
||||
break;
|
||||
default:
|
||||
OSMO_ASSERT(0);
|
||||
}
|
||||
if (rc == 0)
|
||||
worker_send_atr(worker);
|
||||
/* return early, so we do another select rather than the blocking read below */
|
||||
return 0;
|
||||
};
|
||||
|
@ -794,6 +827,7 @@ static void *worker_main(void *arg)
|
|||
LOGW(g_worker, "Error %d occurred: Cleaning up state\n", rc);
|
||||
|
||||
/* clean-up: reset to sane state */
|
||||
memset(&g_worker->card, 0, sizeof(g_worker->card));
|
||||
if (g_worker->reader.pcsc.hCard) {
|
||||
SCardDisconnect(g_worker->reader.pcsc.hCard, SCARD_UNPOWER_CARD);
|
||||
g_worker->reader.pcsc.hCard = 0;
|
||||
|
|
Loading…
Reference in New Issue