Skip to content

Commit c456f61

Browse files
authored
add pcsc support (#79)
1 parent a8de32f commit c456f61

9 files changed

Lines changed: 274 additions & 80 deletions

File tree

Taskfile.dist.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ env:
44
GO111MODULE: on
55
GOPROXY: https://goproxy.io,direct
66
CGO_ENABLED: 1
7-
CGO_LDFLAGS: -lnfc -lusb -lcurses
7+
CGO_LDFLAGS: -lpcsclite -lnfc -lusb -lcurses
88

99
dotenv: [".env"]
1010

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ require (
2828
github.com/mattn/go-colorable v0.1.13 // indirect
2929
github.com/mattn/go-isatty v0.0.20 // indirect
3030
github.com/stretchr/testify v1.9.0 // indirect
31-
go.bug.st/serial v1.6.2 // indirect
3231
golang.org/x/term v0.22.0 // indirect
3332
)
3433

@@ -42,6 +41,7 @@ require (
4241
github.com/hsanjuan/go-ndef v0.0.1
4342
github.com/rs/zerolog v1.31.0
4443
github.com/wizzomafizzo/mrext v0.0.0-20240705120538-5efdc40f9c08
44+
go.bug.st/serial v1.6.2
4545
go.etcd.io/bbolt v1.3.9
4646
golang.org/x/sync v0.7.0
4747
)

scripts/linux_arm64/build/Dockerfile

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,39 @@ RUN apt-get install -y ca-certificates openssl && \
1111
# install go and app dependencies
1212
RUN apt-get install build-essential git curl wget ncurses-dev -y && \
1313
apt-get install golang-doc golang-go golang-src golang -y
14+
RUN mkdir /internal
15+
16+
# install pcsc-lite and ccid dependencies
17+
RUN apt-get install -y flex libusb-1.0-0-dev zlib1g-dev
18+
# install custom version of pcsc-lite
19+
RUN cd /internal && \
20+
wget https://pcsclite.apdu.fr/files/pcsc-lite-2.0.0.tar.bz2 && \
21+
tar xf pcsc-lite-2.0.0.tar.bz2 && \
22+
cd pcsc-lite-2.0.0 && \
23+
./configure --disable-libsystemd --disable-libudev -enable-static && \
24+
make -j "$(nproc)" && \
25+
make install
26+
# install custom version of ccid
27+
RUN cd /internal && \
28+
wget https://ccid.apdu.fr/files/ccid-1.5.4.tar.bz2 && \
29+
tar xf ccid-1.5.4.tar.bz2 && \
30+
cd ccid-1.5.4 && \
31+
./configure -enable-static && \
32+
make -j "$(nproc)" && \
33+
make install
1434

1535
# install libnfc dependencies
1636
RUN apt-get install -y libusb-dev libtool autoconf automake
17-
# install custom version of libnfc
18-
RUN mkdir /internal && cd /internal && \
19-
git clone --depth 1 https://github.com/sam1902/libnfc && \
20-
cd libnfc && \
37+
RUN cd /internal && \
38+
git clone --depth 1 https://github.com/nfc-tools/libnfc.git
39+
# apply patches
40+
COPY patches/pcsc-initiator_poll_target.patch /internal/libnfc/pcsc-initiator_poll_target.patch
41+
RUN cd /internal/libnfc && \
42+
patch -p1 < pcsc-initiator_poll_target.patch
43+
# build and install libnfc
44+
RUN cd /internal/libnfc && \
2145
autoreconf -vis && \
22-
./configure && \
46+
./configure --with-drivers=all && \
2347
make -j "$(nproc)" && \
2448
make install
2549

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
From 1e5cd05357b11381f5505f345afa4892804986f7 Mon Sep 17 00:00:00 2001
2+
From: Roberto Jung Drebes <drebes@users.noreply.github.com>
3+
Date: Wed, 29 May 2024 15:54:42 -0400
4+
Subject: [PATCH] initiator_poll_target for PCSC
5+
6+
---
7+
libnfc/drivers/pcsc.c | 42 ++++++++++++++++++++++++++++++++++++++----
8+
1 file changed, 38 insertions(+), 4 deletions(-)
9+
10+
diff --git a/libnfc/drivers/pcsc.c b/libnfc/drivers/pcsc.c
11+
index 106d99ac..0bae4ed8 100644
12+
--- a/libnfc/drivers/pcsc.c
13+
+++ b/libnfc/drivers/pcsc.c
14+
@@ -176,7 +176,8 @@ static int pcsc_get_status(struct nfc_device *pnd, int *target_present, uint8_t
15+
16+
data->last_error = SCardStatus(data->hCard, NULL, &reader_len, &state, &protocol, atr, &dw_atr_len);
17+
if (data->last_error != SCARD_S_SUCCESS
18+
- && data->last_error != SCARD_W_RESET_CARD) {
19+
+ && data->last_error != SCARD_W_RESET_CARD
20+
+ && data->last_error != SCARD_W_REMOVED_CARD) {
21+
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Get status failed");
22+
return NFC_EIO;
23+
}
24+
@@ -193,7 +194,8 @@ static int pcsc_reconnect(struct nfc_device *pnd, DWORD share_mode, DWORD protoc
25+
26+
data->last_error = SCardReconnect(data->hCard, share_mode, protocol, disposition, &data->ioCard.dwProtocol);
27+
if (data->last_error != SCARD_S_SUCCESS
28+
- && data->last_error != SCARD_W_RESET_CARD) {
29+
+ && data->last_error != SCARD_W_RESET_CARD
30+
+ && data->last_error != SCARD_E_NO_SMARTCARD) {
31+
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Reconnect failed");
32+
return NFC_EIO;
33+
}
34+
@@ -882,6 +884,38 @@ static int pcsc_initiator_transceive_bytes(struct nfc_device *pnd, const uint8_t
35+
return resp_len;
36+
}
37+
38+
+static int
39+
+pcsc_initiator_poll_target(struct nfc_device *pnd,
40+
+ const nfc_modulation *pnmModulations, const size_t szModulations,
41+
+ const uint8_t uiPollNr, const uint8_t uiPeriod,
42+
+ nfc_target *pnt)
43+
+{
44+
+ static int periodFactor = 150000;
45+
+ int period = uiPeriod * periodFactor;
46+
+
47+
+ if (pnd == NULL)
48+
+ return 0;
49+
+
50+
+ for (int j = 0; j < uiPollNr; j++)
51+
+ {
52+
+ for (unsigned int i = 0; i < szModulations; i++)
53+
+ {
54+
+ const nfc_modulation nm = pnmModulations[i];
55+
+
56+
+ nfc_target nt;
57+
+ int res = pcsc_initiator_select_passive_target(pnd, nm, 0, 0, &nt);
58+
+ if (res > 0 && pnt)
59+
+ {
60+
+ memcpy(pnt, &nt, sizeof(nfc_target));
61+
+ return res;
62+
+ }
63+
+ }
64+
+ usleep(period);
65+
+ }
66+
+
67+
+ return 0;
68+
+}
69+
+
70+
static int pcsc_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt)
71+
{
72+
uint8_t atr[MAX_ATR_SIZE];
73+
@@ -938,7 +972,7 @@ static int pcsc_device_set_property_bool(struct nfc_device *pnd, const nfc_prope
74+
case NP_ACTIVATE_FIELD:
75+
if (bEnable == false) {
76+
struct pcsc_data *data = pnd->driver_data;
77+
- pcsc_reconnect(pnd, data->dwShareMode, data->ioCard.dwProtocol, SCARD_RESET_CARD);
78+
+ pcsc_reconnect(pnd, data->dwShareMode, data->ioCard.dwProtocol, SCARD_LEAVE_CARD);
79+
}
80+
return NFC_SUCCESS;
81+
default:
82+
@@ -1053,7 +1087,7 @@ const struct nfc_driver pcsc_driver = {
83+
.initiator_init = pcsc_initiator_init,
84+
.initiator_init_secure_element = NULL, // No secure-element support
85+
.initiator_select_passive_target = pcsc_initiator_select_passive_target,
86+
- .initiator_poll_target = NULL,
87+
+ .initiator_poll_target = pcsc_initiator_poll_target,
88+
.initiator_select_dep_target = NULL,
89+
.initiator_deselect_target = NULL,
90+
.initiator_transceive_bytes = pcsc_initiator_transceive_bytes,

scripts/mister/build/Dockerfile

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,39 @@ RUN apt-get install -y ca-certificates openssl && \
1212
# install go and app dependencies
1313
RUN apt-get install build-essential git curl wget ncurses-dev -y && \
1414
apt-get install golang-doc/bullseye-backports golang-go/bullseye-backports golang-src/bullseye-backports golang/bullseye-backports -y
15+
RUN mkdir /internal
16+
17+
# install pcsc-lite and ccid dependencies
18+
RUN apt-get install -y flex libusb-1.0-0-dev zlib1g-dev
19+
# install custom version of pcsc-lite
20+
RUN cd /internal && \
21+
wget https://pcsclite.apdu.fr/files/pcsc-lite-2.0.0.tar.bz2 && \
22+
tar xf pcsc-lite-2.0.0.tar.bz2 && \
23+
cd pcsc-lite-2.0.0 && \
24+
./configure --disable-libsystemd --disable-libudev -enable-static && \
25+
make -j "$(nproc)" && \
26+
make install
27+
# install custom version of ccid
28+
RUN cd /internal && \
29+
wget https://ccid.apdu.fr/files/ccid-1.5.4.tar.bz2 && \
30+
tar xf ccid-1.5.4.tar.bz2 && \
31+
cd ccid-1.5.4 && \
32+
./configure -enable-static && \
33+
make -j "$(nproc)" && \
34+
make install
1535

1636
# install libnfc dependencies
1737
RUN apt-get install -y libusb-dev libtool autoconf automake
18-
# install custom version of libnfc
19-
RUN mkdir /internal && cd /internal && \
20-
git clone --depth 1 https://github.com/sam1902/libnfc && \
21-
cd libnfc && \
38+
RUN cd /internal && \
39+
git clone --depth 1 https://github.com/nfc-tools/libnfc.git
40+
# apply patches
41+
COPY patches/pcsc-initiator_poll_target.patch /internal/libnfc/pcsc-initiator_poll_target.patch
42+
RUN cd /internal/libnfc && \
43+
patch -p1 < pcsc-initiator_poll_target.patch
44+
# build and install libnfc
45+
RUN cd /internal/libnfc && \
2246
autoreconf -vis && \
23-
./configure && \
47+
./configure --with-drivers=all && \
2448
make -j "$(nproc)" && \
2549
make install
2650

scripts/mister/build/build.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#!/bin/bash
22

3-
GO111MODULE=on GOPROXY=https://goproxy.io,direct CGO_ENABLED=1 CGO_LDFLAGS="-lnfc -lusb -lcurses" go build \
3+
export GO111MODULE=on
4+
export GOPROXY=https://goproxy.io,direct
5+
export CGO_ENABLED=1
6+
export CGO_LDFLAGS="-lpcsclite -lnfc -lusb -lcurses"
7+
8+
go build \
49
--ldflags "-linkmode external -extldflags -static -s -w" \
510
-o _build/mister_arm/tapto.sh ./cmd/mister

scripts/mister/build/patches/acr122u-fix.patch

Lines changed: 0 additions & 67 deletions
This file was deleted.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
From 1e5cd05357b11381f5505f345afa4892804986f7 Mon Sep 17 00:00:00 2001
2+
From: Roberto Jung Drebes <drebes@users.noreply.github.com>
3+
Date: Wed, 29 May 2024 15:54:42 -0400
4+
Subject: [PATCH] initiator_poll_target for PCSC
5+
6+
---
7+
libnfc/drivers/pcsc.c | 42 ++++++++++++++++++++++++++++++++++++++----
8+
1 file changed, 38 insertions(+), 4 deletions(-)
9+
10+
diff --git a/libnfc/drivers/pcsc.c b/libnfc/drivers/pcsc.c
11+
index 106d99ac..0bae4ed8 100644
12+
--- a/libnfc/drivers/pcsc.c
13+
+++ b/libnfc/drivers/pcsc.c
14+
@@ -176,7 +176,8 @@ static int pcsc_get_status(struct nfc_device *pnd, int *target_present, uint8_t
15+
16+
data->last_error = SCardStatus(data->hCard, NULL, &reader_len, &state, &protocol, atr, &dw_atr_len);
17+
if (data->last_error != SCARD_S_SUCCESS
18+
- && data->last_error != SCARD_W_RESET_CARD) {
19+
+ && data->last_error != SCARD_W_RESET_CARD
20+
+ && data->last_error != SCARD_W_REMOVED_CARD) {
21+
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Get status failed");
22+
return NFC_EIO;
23+
}
24+
@@ -193,7 +194,8 @@ static int pcsc_reconnect(struct nfc_device *pnd, DWORD share_mode, DWORD protoc
25+
26+
data->last_error = SCardReconnect(data->hCard, share_mode, protocol, disposition, &data->ioCard.dwProtocol);
27+
if (data->last_error != SCARD_S_SUCCESS
28+
- && data->last_error != SCARD_W_RESET_CARD) {
29+
+ && data->last_error != SCARD_W_RESET_CARD
30+
+ && data->last_error != SCARD_E_NO_SMARTCARD) {
31+
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Reconnect failed");
32+
return NFC_EIO;
33+
}
34+
@@ -882,6 +884,38 @@ static int pcsc_initiator_transceive_bytes(struct nfc_device *pnd, const uint8_t
35+
return resp_len;
36+
}
37+
38+
+static int
39+
+pcsc_initiator_poll_target(struct nfc_device *pnd,
40+
+ const nfc_modulation *pnmModulations, const size_t szModulations,
41+
+ const uint8_t uiPollNr, const uint8_t uiPeriod,
42+
+ nfc_target *pnt)
43+
+{
44+
+ static int periodFactor = 150000;
45+
+ int period = uiPeriod * periodFactor;
46+
+
47+
+ if (pnd == NULL)
48+
+ return 0;
49+
+
50+
+ for (int j = 0; j < uiPollNr; j++)
51+
+ {
52+
+ for (unsigned int i = 0; i < szModulations; i++)
53+
+ {
54+
+ const nfc_modulation nm = pnmModulations[i];
55+
+
56+
+ nfc_target nt;
57+
+ int res = pcsc_initiator_select_passive_target(pnd, nm, 0, 0, &nt);
58+
+ if (res > 0 && pnt)
59+
+ {
60+
+ memcpy(pnt, &nt, sizeof(nfc_target));
61+
+ return res;
62+
+ }
63+
+ }
64+
+ usleep(period);
65+
+ }
66+
+
67+
+ return 0;
68+
+}
69+
+
70+
static int pcsc_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt)
71+
{
72+
uint8_t atr[MAX_ATR_SIZE];
73+
@@ -938,7 +972,7 @@ static int pcsc_device_set_property_bool(struct nfc_device *pnd, const nfc_prope
74+
case NP_ACTIVATE_FIELD:
75+
if (bEnable == false) {
76+
struct pcsc_data *data = pnd->driver_data;
77+
- pcsc_reconnect(pnd, data->dwShareMode, data->ioCard.dwProtocol, SCARD_RESET_CARD);
78+
+ pcsc_reconnect(pnd, data->dwShareMode, data->ioCard.dwProtocol, SCARD_LEAVE_CARD);
79+
}
80+
return NFC_SUCCESS;
81+
default:
82+
@@ -1053,7 +1087,7 @@ const struct nfc_driver pcsc_driver = {
83+
.initiator_init = pcsc_initiator_init,
84+
.initiator_init_secure_element = NULL, // No secure-element support
85+
.initiator_select_passive_target = pcsc_initiator_select_passive_target,
86+
- .initiator_poll_target = NULL,
87+
+ .initiator_poll_target = pcsc_initiator_poll_target,
88+
.initiator_select_dep_target = NULL,
89+
.initiator_deselect_target = NULL,
90+
.initiator_transceive_bytes = pcsc_initiator_transceive_bytes,

0 commit comments

Comments
 (0)