bankd: Move all PC/SC specific code to bankd_pcsc
Change-Id: I435b42982b54d74447c435dcefa26d1e317d15e0
diff --git a/src/bankd_pcsc.c b/src/bankd_pcsc.c
index 671c6bf..a390782 100644
--- a/src/bankd_pcsc.c
+++ b/src/bankd_pcsc.c
@@ -138,3 +138,81 @@
}
return NULL;
}
+
+
+#include <wintypes.h>
+#include <winscard.h>
+#include <pcsclite.h>
+
+#define PCSC_ERROR(w, rv, text) \
+if (rv != SCARD_S_SUCCESS) { \
+ LOGW((w), text ": %s (0x%lX)\n", pcsc_stringify_error(rv), rv); \
+ goto end; \
+} else { \
+ LOGW((w), ": OK\n"); \
+}
+
+static int pcsc_open_card(struct bankd_worker *worker)
+{
+ long rc;
+
+ if (!worker->reader.pcsc.hContext) {
+ LOGW(worker, "Attempting to open PC/SC context\n");
+ /* The PC/SC context must be created inside the thread where we'll later use it */
+ rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &worker->reader.pcsc.hContext);
+ PCSC_ERROR(worker, rc, "SCardEstablishContext")
+ }
+
+ if (!worker->reader.pcsc.hCard) {
+ LOGW(worker, "Attempting to open card/slot '%s'\n", worker->reader.name);
+ DWORD dwActiveProtocol;
+ rc = SCardConnect(worker->reader.pcsc.hContext, worker->reader.name, SCARD_SHARE_SHARED,
+ SCARD_PROTOCOL_T0, &worker->reader.pcsc.hCard, &dwActiveProtocol);
+ 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));
+end:
+ return rc;
+}
+
+static int pcsc_transceive(struct bankd_worker *worker, const uint8_t *out, size_t out_len,
+ uint8_t *in, size_t *in_len)
+{
+ const SCARD_IO_REQUEST *pioSendPci = SCARD_PCI_T0;
+ SCARD_IO_REQUEST pioRecvPci;
+ long rc;
+
+ rc = SCardTransmit(worker->reader.pcsc.hCard, pioSendPci, out, out_len, &pioRecvPci, in, in_len);
+ PCSC_ERROR(worker, rc, "SCardTransmit");
+
+end:
+ return rc;
+}
+
+static void pcsc_cleanup(struct bankd_worker *worker)
+{
+ if (worker->reader.pcsc.hCard) {
+ SCardDisconnect(worker->reader.pcsc.hCard, SCARD_UNPOWER_CARD);
+ worker->reader.pcsc.hCard = 0;
+ }
+ if (worker->reader.pcsc.hContext) {
+ SCardReleaseContext(worker->reader.pcsc.hContext);
+ worker->reader.pcsc.hContext = 0;
+ }
+}
+
+const struct bankd_driver_ops pcsc_driver_ops = {
+ .open_card = pcsc_open_card,
+ .transceive = pcsc_transceive,
+ .cleanup = pcsc_cleanup,
+};