diff --git a/libnfc/drivers/pcsc.c b/libnfc/drivers/pcsc.c index 106d99ac..0bae4ed8 100644 --- a/libnfc/drivers/pcsc.c +++ b/libnfc/drivers/pcsc.c @@ -176,7 +176,8 @@ static int pcsc_get_status(struct nfc_device *pnd, int *target_present, uint8_t data->last_error = SCardStatus(data->hCard, NULL, &reader_len, &state, &protocol, atr, &dw_atr_len); if (data->last_error != SCARD_S_SUCCESS - && data->last_error != SCARD_W_RESET_CARD) { + && data->last_error != SCARD_W_RESET_CARD + && data->last_error != SCARD_W_REMOVED_CARD) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Get status failed"); return NFC_EIO; } @@ -193,7 +194,8 @@ static int pcsc_reconnect(struct nfc_device *pnd, DWORD share_mode, DWORD protoc data->last_error = SCardReconnect(data->hCard, share_mode, protocol, disposition, &data->ioCard.dwProtocol); if (data->last_error != SCARD_S_SUCCESS - && data->last_error != SCARD_W_RESET_CARD) { + && data->last_error != SCARD_W_RESET_CARD + && data->last_error != SCARD_E_NO_SMARTCARD) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Reconnect failed"); return NFC_EIO; } @@ -882,6 +884,38 @@ static int pcsc_initiator_transceive_bytes(struct nfc_device *pnd, const uint8_t return resp_len; } +static int +pcsc_initiator_poll_target(struct nfc_device *pnd, + const nfc_modulation *pnmModulations, const size_t szModulations, + const uint8_t uiPollNr, const uint8_t uiPeriod, + nfc_target *pnt) +{ + static int periodFactor = 150000; + int period = uiPeriod * periodFactor; + + if (pnd == NULL) + return 0; + + for (int j = 0; j < uiPollNr; j++) + { + for (unsigned int i = 0; i < szModulations; i++) + { + const nfc_modulation nm = pnmModulations[i]; + + nfc_target nt; + int res = pcsc_initiator_select_passive_target(pnd, nm, 0, 0, &nt); + if (res > 0 && pnt) + { + memcpy(pnt, &nt, sizeof(nfc_target)); + return res; + } + } + usleep(period); + } + + return 0; +} + static int pcsc_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt) { uint8_t atr[MAX_ATR_SIZE]; @@ -938,7 +972,7 @@ static int pcsc_device_set_property_bool(struct nfc_device *pnd, const nfc_prope case NP_ACTIVATE_FIELD: if (bEnable == false) { struct pcsc_data *data = pnd->driver_data; - pcsc_reconnect(pnd, data->dwShareMode, data->ioCard.dwProtocol, SCARD_RESET_CARD); + pcsc_reconnect(pnd, data->dwShareMode, data->ioCard.dwProtocol, SCARD_LEAVE_CARD); } return NFC_SUCCESS; default: @@ -1053,7 +1087,7 @@ const struct nfc_driver pcsc_driver = { .initiator_init = pcsc_initiator_init, .initiator_init_secure_element = NULL, // No secure-element support .initiator_select_passive_target = pcsc_initiator_select_passive_target, - .initiator_poll_target = NULL, + .initiator_poll_target = pcsc_initiator_poll_target, .initiator_select_dep_target = NULL, .initiator_deselect_target = NULL, .initiator_transceive_bytes = pcsc_initiator_transceive_bytes,