88 #include "target-subr.h"
91 #if defined (DRIVER_PCSC_ENABLED)
92 # include "drivers/pcsc.h"
95 #if defined (DRIVER_ACR122_PCSC_ENABLED)
96 # include "drivers/acr122_pcsc.h"
99 #if defined (DRIVER_ACR122_USB_ENABLED)
100 # include "drivers/acr122_usb.h"
103 #if defined (DRIVER_ACR122S_ENABLED)
104 # include "drivers/acr122s.h"
107 #if defined (DRIVER_PN53X_USB_ENABLED)
108 # include "drivers/pn53x_usb.h"
111 #if defined (DRIVER_ARYGON_ENABLED)
112 # include "drivers/arygon.h"
115 #if defined (DRIVER_PN532_UART_ENABLED)
116 # include "drivers/pn532_uart.h"
119 #if defined (DRIVER_PN532_SPI_ENABLED)
120 # include "drivers/pn532_spi.h"
123 #if defined (DRIVER_PN532_I2C_ENABLED)
124 # include "drivers/pn532_i2c.h"
127 #if defined (DRIVER_PN71XX_ENABLED)
128 # include "drivers/pn71xx.h"
132 #define LOG_CATEGORY "libnfc.general"
133 #define LOG_GROUP NFC_LOG_GROUP_GENERAL
135 struct nfc_driver_list {
136 const struct nfc_driver_list *next;
140 const struct nfc_driver_list *nfc_drivers = NULL;
143 const char *nfc_property_name[] = {
144 "NP_TIMEOUT_COMMAND",
150 "NP_ACTIVATE_CRYPTO1",
151 "NP_INFINITE_SELECT",
152 "NP_ACCEPT_INVALID_FRAMES",
153 "NP_ACCEPT_MULTIPLE_FRAMES",
154 "NP_AUTO_ISO14443_4",
156 "NP_FORCE_ISO14443_A",
157 "NP_FORCE_ISO14443_B",
162 nfc_drivers_init(
void)
164 #if defined (DRIVER_PN53X_USB_ENABLED)
167 #if defined (DRIVER_PCSC_ENABLED)
170 #if defined (DRIVER_ACR122_PCSC_ENABLED)
173 #if defined (DRIVER_ACR122_USB_ENABLED)
176 #if defined (DRIVER_ACR122S_ENABLED)
179 #if defined (DRIVER_PN532_UART_ENABLED)
182 #if defined (DRIVER_PN532_SPI_ENABLED)
185 #if defined (DRIVER_PN532_I2C_ENABLED)
188 #if defined (DRIVER_ARYGON_ENABLED)
191 #if defined (DRIVER_PN71XX_ENABLED)
210 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"nfc_register_driver returning NFC_EINVARG");
214 struct nfc_driver_list *pndl = (
struct nfc_driver_list *)malloc(
sizeof(
struct nfc_driver_list));
219 pndl->next = nfc_drivers;
233 *context = nfc_context_new();
250 while (nfc_drivers) {
251 struct nfc_driver_list *pndl = (
struct nfc_driver_list *) nfc_drivers;
252 nfc_drivers = pndl->next;
256 nfc_context_free(context);
282 if (connstring == NULL) {
292 const struct nfc_driver_list *pndl = nfc_drivers;
297 if (0 != strncmp(ndr->name, ncs, strlen(ndr->name))) {
299 if ((0 != strncmp(
"usb", ncs, strlen(
"usb"))) || 0 != strncmp(
"_usb", ndr->name + (strlen(ndr->name) - 4), 4)) {
305 pnd = ndr->open(context, ncs);
308 if (0 == strncmp(
"usb", ncs, strlen(
"usb"))) {
313 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"Unable to open \"%s\".", ncs);
316 for (uint32_t i = 0; i < context->user_defined_device_count; i++) {
317 if (strcmp(ncs, context->user_defined_devices[i].connstring) == 0) {
319 strcpy(pnd->
name, context->user_defined_devices[i].name);
323 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"\"%s\" (%s) has been claimed.", pnd->
name, pnd->
connstring);
328 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"No driver available to handle \"%s\".", ncs);
343 pnd->driver->close(pnd);
358 size_t device_found = 0;
363 for (uint32_t i = 0; i < context->user_defined_device_count; i++) {
364 if (context->user_defined_devices[i].optional) {
369 char *env_log_level = getenv(
"LIBNFC_LOG_LEVEL");
370 char *old_env_log_level = NULL;
373 if ((old_env_log_level = malloc(strlen(env_log_level) + 1)) == NULL) {
374 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR,
"%s",
"Unable to malloc()");
377 strcpy(old_env_log_level, env_log_level);
379 setenv(
"LIBNFC_LOG_LEVEL",
"0", 1);
382 pnd =
nfc_open(context, context->user_defined_devices[i].connstring);
385 if (old_env_log_level) {
386 setenv(
"LIBNFC_LOG_LEVEL", old_env_log_level, 1);
387 free(old_env_log_level);
389 unsetenv(
"LIBNFC_LOG_LEVEL");
395 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"User device %s found", context->user_defined_devices[i].name);
396 strcpy((
char *)(connstrings + device_found), context->user_defined_devices[i].connstring);
398 if (device_found == connstrings_len)
403 strcpy((
char *)(connstrings + device_found), context->user_defined_devices[i].connstring);
405 if (device_found >= connstrings_len)
412 if (context->allow_autoscan) {
413 const struct nfc_driver_list *pndl = nfc_drivers;
416 if ((ndr->scan_type == NOT_INTRUSIVE) || ((context->allow_intrusive_scan) && (ndr->scan_type == INTRUSIVE))) {
417 size_t _device_found = ndr->scan(context, connstrings + (device_found), connstrings_len - (device_found));
418 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"%ld device(s) found using %s driver", (
unsigned long) _device_found, ndr->name);
419 if (_device_found > 0) {
420 device_found += _device_found;
421 if (device_found == connstrings_len)
427 }
else if (context->user_defined_device_count == 0) {
428 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO,
"Warning: %s",
"user must specify device(s) manually when autoscan is disabled");
448 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"set_property_int %s %s", nfc_property_name[property], value ?
"True" :
"False");
449 HAL(device_set_property_int, pnd, property, value);
468 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"set_property_bool %s %s", nfc_property_name[property], bEnable ?
"True" :
"False");
469 HAL(device_set_property_bool, pnd, property, bEnable);
520 HAL(initiator_init, pnd);
535 HAL(initiator_init_secure_element, pnd);
564 const uint8_t *pbtInitData,
const size_t szInitData,
567 uint8_t *abtInit = NULL;
568 uint8_t abtTmpInit[MAX(12, szInitData)];
573 if (szInitData == 0) {
575 prepare_initiator_data(nm, &abtInit, &szInit);
576 }
else if (nm.nmt == NMT_ISO14443A) {
577 abtInit = abtTmpInit;
578 iso14443_cascade_uid(pbtInitData, szInitData, abtInit, &szInit);
580 abtInit = abtTmpInit;
581 memcpy(abtInit, pbtInitData, szInitData);
585 HAL(initiator_select_passive_target, pnd, nm, abtInit, szInit, pnt);
610 size_t szTargetFound = 0;
611 uint8_t *pbtInitData = NULL;
612 size_t szInitDataLen = 0;
623 prepare_initiator_data(nm, &pbtInitData, &szInitDataLen);
629 for (i = 0; i < szTargetFound; i++) {
630 if (memcmp(&(ant[i]), &nt,
sizeof(
nfc_target)) == 0) {
637 memcpy(&(ant[szTargetFound]), &nt,
sizeof(
nfc_target));
639 if (szTargets == szTargetFound) {
642 nfc_initiator_deselect_target(pnd);
645 if ((nm.nmt == NMT_FELICA) || (nm.nmt == NMT_JEWEL) || (nm.nmt == NMT_BARCODE) ||
646 (nm.nmt == NMT_ISO14443BI) || (nm.nmt == NMT_ISO14443B2SR) || (nm.nmt == NMT_ISO14443B2CT)) {
650 if (bInfiniteSelect) {
655 return szTargetFound;
674 const uint8_t uiPollNr,
const uint8_t uiPeriod,
677 HAL(initiator_poll_target, pnd, pnmModulations, szModulations, uiPollNr, uiPeriod, pnt);
706 HAL(initiator_select_dep_target, pnd, ndm, nbr, pndiInitiator, pnt, timeout);
733 const int period = 300;
734 int remaining_time = timeout;
740 while (remaining_time > 0) {
751 remaining_time -= period;
754 if (! bInfiniteSelect) {
775 nfc_initiator_deselect_target(
nfc_device *pnd)
777 HAL(initiator_deselect_target, pnd);
810 const size_t szRx,
int timeout)
812 HAL(initiator_transceive_bytes, pnd, pbtTx, szTx, pbtRx, szRx, timeout)
853 const uint8_t *pbtTx,
const size_t szTxBits,
const uint8_t *pbtTxPar,
854 uint8_t *pbtRx,
const size_t szRx,
858 HAL(initiator_transceive_bits, pnd, pbtTx, szTxBits, pbtTxPar, pbtRx, pbtRxPar);
889 const uint8_t *pbtTx,
const size_t szTx,
890 uint8_t *pbtRx,
const size_t szRx,
893 HAL(initiator_transceive_bytes_timed, pnd, pbtTx, szTx, pbtRx, szRx, cycles);
909 HAL(initiator_target_is_present, pnd, pnt);
935 const uint8_t *pbtTx,
const size_t szTxBits,
const uint8_t *pbtTxPar,
936 uint8_t *pbtRx,
const size_t szRx,
941 HAL(initiator_transceive_bits_timed, pnd, pbtTx, szTxBits, pbtTxPar, pbtRx, pbtRxPar, cycles);
1005 HAL(target_init, pnd, pnt, pbtRx, szRx, timeout);
1038 HAL(abort_command, pnd);
1059 HAL(target_send_bytes, pnd, pbtTx, szTx, timeout);
1079 HAL(target_receive_bytes, pnd, pbtRx, szRx, timeout);
1096 HAL(target_send_bits, pnd, pbtTx, szTxBits, pbtTxPar);
1118 HAL(target_receive_bits, pnd, pbtRx, szRx, pbtRxPar);
1121 static struct sErrorMessage {
1123 const char *pcErrorMsg;
1124 } sErrorMessages[] = {
1127 {
NFC_EIO,
"Input / Output Error" },
1138 {
NFC_ECHIP,
"Device's Internal Chip Error" },
1150 const char *pcRes =
"Unknown error";
1152 for (i = 0; i < (
sizeof(sErrorMessages) /
sizeof(
struct sErrorMessage)); i++) {
1153 if (sErrorMessages[i].iErrorCode == pnd->
last_error) {
1154 pcRes = sErrorMessages[i].pcErrorMsg;
1173 return (snprintf(pcStrErrBuf, szBufLen,
"%s",
nfc_strerror(pnd)) < 0) ? -1 : 0;
1185 fprintf(stderr,
"%s: %s\n", pcString,
nfc_strerror(pnd));
1237 HAL(get_supported_modulation, pnd, mode, supported_mt);
1251 HAL(get_supported_baud_rate, pnd, N_INITIATOR, nmt, supported_br);
1265 HAL(get_supported_baud_rate, pnd, N_TARGET, nmt, supported_br);
1284 assert(nmt != NULL);
1285 for (
int i = 0; nmt[i]; i++) {
1286 if (nmt[i] == nm->nmt) {
1288 if (mode == N_INITIATOR) {
1297 assert(nbr != NULL);
1298 for (
int j = 0; nbr[j]; j++) {
1299 if (nbr[j] == nm->nbr)
1302 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"nfc_device_validate_modulation returning NFC_EINVARG");
1306 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"nfc_device_validate_modulation returning NFC_EINVARG");
1322 return GIT_REVISION;
1324 return PACKAGE_VERSION;
1350 HAL(device_get_information_about, pnd, buf);
1363 return "undefined baud rate";
1387 return "ISO/IEC 14443A";
1389 return "ISO/IEC 14443-4B";
1390 case NMT_ISO14443BI:
1391 return "ISO/IEC 14443-4B'";
1392 case NMT_ISO14443BICLASS:
1393 return "ISO/IEC 14443-2B-3B iClass (Picopass)";
1394 case NMT_ISO14443B2CT:
1395 return "ISO/IEC 14443-2B ASK CTx";
1396 case NMT_ISO14443B2SR:
1397 return "ISO/IEC 14443-2B ST SRx";
1401 return "Innovision Jewel";
1403 return "Thinfilm NFC Barcode";
1423 *buf = malloc(4096);
1427 snprint_nfc_target(*buf, 4096, pnt, verbose);
1428 return strlen(*buf);
int nfc_device_get_supported_baud_rate_target_mode(nfc_device *pnd, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br)
Get supported baud rates for target mode.
int nfc_device_get_supported_modulation(nfc_device *pnd, const nfc_mode mode, const nfc_modulation_type **const supported_mt)
Get supported modulations.
int nfc_device_get_supported_baud_rate(nfc_device *pnd, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br)
Get supported baud rates (initiator mode).
const char * nfc_device_get_connstring(nfc_device *pnd)
Returns the device connection string.
const char * nfc_device_get_name(nfc_device *pnd)
Returns the device name.
static int nfc_device_validate_modulation(nfc_device *pnd, const nfc_mode mode, const nfc_modulation *nm)
Validate combination of modulation and baud rate on the currently used device.
void nfc_close(nfc_device *pnd)
Close from a NFC device.
int nfc_idle(nfc_device *pnd)
Turn NFC device in idle mode.
nfc_device * nfc_open(nfc_context *context, const nfc_connstring connstring)
Open a NFC device.
int nfc_abort_command(nfc_device *pnd)
Abort current running command.
size_t nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len)
Scan for discoverable supported devices (ie. only available for some drivers)
void nfc_perror(const nfc_device *pnd, const char *pcString)
Display the last error occured on a nfc_device.
int nfc_strerror_r(const nfc_device *pnd, char *pcStrErrBuf, size_t szBufLen)
Renders the last error in pcStrErrBuf for a maximum size of szBufLen chars.
const char * nfc_strerror(const nfc_device *pnd)
Return the last error string.
int nfc_device_get_last_error(const nfc_device *pnd)
Returns last error occured on a nfc_device.
int nfc_initiator_transceive_bytes(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, const size_t szRx, int timeout)
Send data to target then retrieve data from target.
int nfc_initiator_transceive_bits(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtRx, const size_t szRx, uint8_t *pbtRxPar)
Transceive raw bit-frames to a target.
int nfc_initiator_transceive_bits_timed(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtRx, const size_t szRx, uint8_t *pbtRxPar, uint32_t *cycles)
Transceive raw bit-frames to a target.
int nfc_initiator_init(nfc_device *pnd)
Initialize NFC device as initiator (reader)
int nfc_initiator_init_secure_element(nfc_device *pnd)
Initialize NFC device as initiator with its secure element as target (reader)
int nfc_initiator_poll_dep_target(struct nfc_device *pnd, const nfc_dep_mode ndm, const nfc_baud_rate nbr, const nfc_dep_info *pndiInitiator, nfc_target *pnt, const int timeout)
Poll a target and request active or passive mode for D.E.P. (Data Exchange Protocol)
int nfc_initiator_transceive_bytes_timed(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, const size_t szRx, uint32_t *cycles)
Send data to target then retrieve data from target.
int nfc_initiator_target_is_present(nfc_device *pnd, const nfc_target *pnt)
Check target presence.
int nfc_initiator_list_passive_targets(nfc_device *pnd, const nfc_modulation nm, nfc_target ant[], const size_t szTargets)
List passive or emulated tags.
int nfc_initiator_select_dep_target(nfc_device *pnd, const nfc_dep_mode ndm, const nfc_baud_rate nbr, const nfc_dep_info *pndiInitiator, nfc_target *pnt, const int timeout)
Select a target and request active or passive mode for D.E.P. (Data Exchange Protocol)
int nfc_initiator_select_passive_target(nfc_device *pnd, const nfc_modulation nm, const uint8_t *pbtInitData, const size_t szInitData, nfc_target *pnt)
Select a passive or emulated tag.
int nfc_initiator_poll_target(nfc_device *pnd, const nfc_modulation *pnmModulations, const size_t szModulations, const uint8_t uiPollNr, const uint8_t uiPeriod, nfc_target *pnt)
Polling for NFC targets.
int nfc_register_driver(const struct nfc_driver *ndr)
Register an NFC device driver with libnfc. This function registers a driver with libnfc,...
void nfc_exit(nfc_context *context)
Deinitialize libnfc. Should be called after closing all open devices and before your application term...
void nfc_init(nfc_context **context)
Initialize libnfc. This function must be called before calling any other libnfc function.
const char * nfc_version(void)
Returns the library version.
void nfc_free(void *p)
Free buffer allocated by libnfc.
int nfc_device_get_information_about(nfc_device *pnd, char **buf)
Print information about NFC device.
int nfc_device_set_property_int(nfc_device *pnd, const nfc_property property, const int value)
Set a device's integer-property value.
int nfc_device_set_property_bool(nfc_device *pnd, const nfc_property property, const bool bEnable)
Set a device's boolean-property value.
int str_nfc_target(char **buf, const nfc_target *pnt, bool verbose)
Convert nfc_target content to string.
const char * str_nfc_baud_rate(const nfc_baud_rate nbr)
Convert nfc_baud_rate value to string.
const char * str_nfc_modulation_type(const nfc_modulation_type nmt)
Convert nfc_modulation_type value to string.
int nfc_target_send_bytes(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, int timeout)
Send bytes and APDU frames.
int nfc_target_send_bits(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar)
Send raw bit-frames.
int nfc_target_init(nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRx, int timeout)
Initialize NFC device as an emulated tag.
int nfc_target_receive_bytes(nfc_device *pnd, uint8_t *pbtRx, const size_t szRx, int timeout)
Receive bytes and APDU frames.
int nfc_target_receive_bits(nfc_device *pnd, uint8_t *pbtRx, const size_t szRx, uint8_t *pbtRxPar)
Receive bit-frames.
Internal defines and macros.
#define HAL(FUNCTION,...)
Execute corresponding driver function if exists.
nfc_mode
NFC mode type enumeration.
struct nfc_driver nfc_driver
@ NP_ACCEPT_INVALID_FRAMES
@ NP_ACCEPT_MULTIPLE_FRAMES
char nfc_connstring[NFC_BUFSIZE_CONNSTRING]
nfc_dep_mode
NFC D.E.P. (Data Exchange Protocol) active/passive mode.
nfc_modulation_type
NFC modulation type enumeration.
nfc_baud_rate
NFC baud rate enumeration.
NFC library context Struct which contains internal options, references, pointers, etc....
NFC target information in D.E.P. (Data Exchange Protocol) see ISO/IEC 18092 (NFCIP-1)
char name[DEVICE_NAME_LENGTH]
nfc_connstring connstring
NFC modulation structure.