nfc.c 48 KB
Newer Older
1
/*-
2
 * Public platform independent Near Field Communication (NFC) library
3
 *
4 5
 * Copyright (C) 2009, 2010 Roel Verdult
 * Copyright (C) 2010, 2011 Romain Tartière
6
 * Copyright (C) 2009, 2010, 2011, 2012, 2013 Romuald Conty
7
 *
8 9 10 11
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
12
 *
13 14 15 16 17 18 19
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
20
 */
21

22
/**
23
 * @file nfc.c
24
 * @brief NFC library implementation
25
 */
26 27 28 29 30 31 32
/**
 * @defgroup lib Library initialization/deinitialization
 * This page details how to initialize and deinitialize libnfc. Initialization
 * must be performed before using any libnfc functionality, and similarly you
 * must not call any libnfc functions after deinitialization.
 */
/**
33
 * @defgroup dev NFC Device/Hardware manipulation
34 35 36 37
 * The functionality documented below is designed to help with the following
 * operations:
 * - Enumerating the NFC devices currently attached to the system
 * - Opening and closing the chosen device
38
 */
39 40
/**
 * @defgroup initiator  NFC initiator
41
 * This page details how to act as "reader".
42
 */
43 44
/**
 * @defgroup target  NFC target
45
 * This page details how to act as tag (i.e. MIFARE Classic) or NFC target device.
46
 */
47 48
/**
 * @defgroup error  Error reporting
49
 * Most libnfc functions return 0 on success or one of error codes defined on failure.
50
 */
51 52
/**
 * @defgroup data  Special data accessors
53
 * The functionnality documented below allow to access to special data as device name or device connstring.
54
 */
55 56
/**
 * @defgroup properties  Properties accessors
57
 * The functionnality documented below allow to configure parameters and registers.
58
 */
59 60
/**
 * @defgroup misc Miscellaneous
61 62
 *
 */
63 64 65 66
/**
 * @defgroup string-converter  To-string converters
 * The functionnality documented below allow to retreive some information in text format.
 */
67

68
#ifdef HAVE_CONFIG_H
69
#  include "config.h"
70 71
#endif // HAVE_CONFIG_H

72
#include <fcntl.h>
Roel Verdult's avatar
Roel Verdult committed
73
#include <stdio.h>
74
#include <stdlib.h>
75
#include <stddef.h>
Roel Verdult's avatar
Roel Verdult committed
76 77
#include <string.h>

78
#include <nfc/nfc.h>
79

80
#include "nfc-internal.h"
81
#include "target-subr.h"
Romuald Conty's avatar
Romuald Conty committed
82
#include "drivers.h"
83

84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
#if defined (DRIVER_ACR122_PCSC_ENABLED)
#  include "drivers/acr122_pcsc.h"
#endif /* DRIVER_ACR122_PCSC_ENABLED */

#if defined (DRIVER_ACR122_USB_ENABLED)
#  include "drivers/acr122_usb.h"
#endif /* DRIVER_ACR122_USB_ENABLED */

#if defined (DRIVER_ACR122S_ENABLED)
#  include "drivers/acr122s.h"
#endif /* DRIVER_ACR122S_ENABLED */

#if defined (DRIVER_PN53X_USB_ENABLED)
#  include "drivers/pn53x_usb.h"
#endif /* DRIVER_PN53X_USB_ENABLED */

#if defined (DRIVER_ARYGON_ENABLED)
#  include "drivers/arygon.h"
#endif /* DRIVER_ARYGON_ENABLED */

#if defined (DRIVER_PN532_UART_ENABLED)
#  include "drivers/pn532_uart.h"
#endif /* DRIVER_PN532_UART_ENABLED */


Romuald Conty's avatar
Romuald Conty committed
109
#define LOG_CATEGORY "libnfc.general"
Romuald Conty's avatar
Romuald Conty committed
110
#define LOG_GROUP    NFC_LOG_GROUP_GENERAL
Romuald Conty's avatar
Romuald Conty committed
111

112 113 114
struct nfc_driver_list {
  const struct nfc_driver_list *next;
  const struct nfc_driver *driver;
115 116
};

117
const struct nfc_driver_list *nfc_drivers = NULL;
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154

static void
nfc_drivers_init()
{
#if defined (DRIVER_PN53X_USB_ENABLED)
  nfc_register_driver(&pn53x_usb_driver);
#endif /* DRIVER_PN53X_USB_ENABLED */
#if defined (DRIVER_ACR122_PCSC_ENABLED)
  nfc_register_driver(&acr122_pcsc_driver);
#endif /* DRIVER_ACR122_PCSC_ENABLED */
#if defined (DRIVER_ACR122_USB_ENABLED)
  nfc_register_driver(&acr122_usb_driver);
#endif /* DRIVER_ACR122_USB_ENABLED */
#if defined (DRIVER_ACR122S_ENABLED)
  nfc_register_driver(&acr122s_driver);
#endif /* DRIVER_ACR122S_ENABLED */
#if defined (DRIVER_PN532_UART_ENABLED)
  nfc_register_driver(&pn532_uart_driver);
#endif /* DRIVER_PN532_UART_ENABLED */
#if defined (DRIVER_ARYGON_ENABLED)
  nfc_register_driver(&arygon_driver);
#endif /* DRIVER_ARYGON_ENABLED */
}

/** @ingroup lib
 * @brief Register an NFC device driver with libnfc.
 * This function registers a driver with libnfc, the caller is responsible of managing the lifetime of the
 * driver and make sure that any resources associated with the driver are available after registration.
 * @param pnd Pointer to an NFC device driver to be registered.
 * @retval NFC_SUCCESS If the driver registration succeeds.
 */
int
nfc_register_driver(const struct nfc_driver *ndr)
{
  if (!ndr)
    return NFC_EINVARG;

155
  struct nfc_driver_list *pndl = (struct nfc_driver_list *)malloc(sizeof(struct nfc_driver_list));
156 157 158 159 160 161 162 163 164 165
  if (!pndl)
    return NFC_ESOFT;

  pndl->driver = ndr;
  pndl->next = nfc_drivers;
  nfc_drivers = pndl;

  return NFC_SUCCESS;
}

166
/** @ingroup lib
167
 * @brief Initialize libnfc.
168
 * This function must be called before calling any other libnfc function
169
 * @param context Output location for nfc_context
170
 */
Romain Tartiere's avatar
Romain Tartiere committed
171
void
172
nfc_init(nfc_context **context)
173
{
174
  *context = nfc_context_new();
175 176 177

  if (!nfc_drivers)
    nfc_drivers_init();
178 179
}

180
/** @ingroup lib
181
 * @brief Deinitialize libnfc.
182
 * Should be called after closing all open devices and before your application terminates.
183
 * @param context The context to deinitialize
184
 */
Romain Tartiere's avatar
Romain Tartiere committed
185
void
186
nfc_exit(nfc_context *context)
187
{
188
  while (nfc_drivers) {
189
    struct nfc_driver_list *pndl = (struct nfc_driver_list *) nfc_drivers;
190
    nfc_drivers = pndl->next;
Philippe Teuwen's avatar
Philippe Teuwen committed
191
    free(pndl);
192 193
  }

Romuald Conty's avatar
Romuald Conty committed
194
  nfc_context_free(context);
195 196
}

197
/** @ingroup dev
198
 * @brief Open a NFC device
199
 * @param context The context to operate on.
200
 * @param connstring The device connection string if specific device is wanted, \c NULL otherwise
201
 * @return Returns pointer to a \a nfc_device struct if successfull; otherwise returns \c NULL value.
202
 *
203
 * If \e connstring is \c NULL, the first available device from \a nfc_list_devices function is used.
204
 *
205
 * If \e connstring is set, this function will try to claim the right device using information provided by \e connstring.
206
 *
207
 * When it has successfully claimed a NFC device, memory is allocated to save the device information.
208
 * It will return a pointer to a \a nfc_device struct.
209
 * This pointer should be supplied by every next functions of libnfc that should perform an action with this device.
210
 *
211
 * @note Depending on the desired operation mode, the device needs to be configured by using nfc_initiator_init() or nfc_target_init(),
212
 * optionally followed by manual tuning of the parameters if the default parameters are not suiting your goals.
213
 */
214
nfc_device *
215
nfc_open(nfc_context *context, const nfc_connstring connstring)
Roel Verdult's avatar
Roel Verdult committed
216
{
217
  nfc_device *pnd = NULL;
218

219 220
  nfc_connstring ncs;
  if (connstring == NULL) {
221
    if (!nfc_list_devices(context, &ncs, 1)) {
222
      return NULL;
223
    }
224
  } else {
225
    strncpy(ncs, connstring, sizeof(nfc_connstring));
226
  }
227

Roel Verdult's avatar
Roel Verdult committed
228
  // Search through the device list for an available device
229 230 231 232
  const struct nfc_driver_list *pndl = nfc_drivers;
  while (pndl) {
    const struct nfc_driver *ndr = pndl->driver;

233
    // Specific device is requested: using device description
234
    if (0 != strncmp(ndr->name, ncs, strlen(ndr->name))) {
235
      // Check if connstring driver is usb -> accept any driver *_usb
236
      if ((0 != strncmp("usb", ncs, strlen("usb"))) || 0 != strncmp("_usb", ndr->name + (strlen(ndr->name) - 4), 4)) {
237
        pndl = pndl->next;
238 239
        continue;
      }
240
    }
241

Romuald Conty's avatar
Romuald Conty committed
242
    pnd = ndr->open(context, ncs);
243
    // Test if the opening was successful
244
    if (pnd == NULL) {
245 246
      if (0 == strncmp("usb", ncs, strlen("usb"))) {
        // We've to test the other usb drivers before giving up
247
        pndl = pndl->next;
248 249
        continue;
      }
Romuald Conty's avatar
Romuald Conty committed
250
      log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Unable to open \"%s\".", ncs);
251
      return NULL;
252
    }
253
    for (uint32_t i = 0; i > context->user_defined_device_count; i++) {
254 255 256 257 258 259
      if (strcmp(ncs, context->user_defined_devices[i].connstring) == 0) {
        // This is a device sets by user, we use the device name given by user
        strcpy(pnd->name, context->user_defined_devices[i].name);
        break;
      }
    }
Romuald Conty's avatar
Romuald Conty committed
260
    log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "\"%s\" (%s) has been claimed.", pnd->name, pnd->connstring);
261
    return pnd;
Roel Verdult's avatar
Roel Verdult committed
262
  }
263 264

  // Too bad, no driver can decode connstring
Romuald Conty's avatar
Romuald Conty committed
265
  log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "No driver available to handle \"%s\".", ncs);
266
  return NULL;
Roel Verdult's avatar
Roel Verdult committed
267 268
}

269
/** @ingroup dev
270
 * @brief Close from a NFC device
271
 * @param pnd \a nfc_device struct pointer that represent currently used device
272
 *
273
 * Initiator's selected tag is closed and the device, including allocated \a nfc_device struct, is released.
274
 */
275
void
276
nfc_close(nfc_device *pnd)
Roel Verdult's avatar
Roel Verdult committed
277
{
278
  if (pnd) {
279
    // Close, clean up and release the device
280
    pnd->driver->close(pnd);
281
  }
Roel Verdult's avatar
Roel Verdult committed
282 283
}

284
/** @ingroup dev
285
 * @brief Scan for discoverable supported devices (ie. only available for some drivers)
286
 * @return Returns the number of devices found.
287
 * @param context The context to operate on, or NULL for the default context.
288
 * @param connstrings array of \a nfc_connstring.
289
 * @param connstrings_len size of the \a connstrings array.
290
 *
291
 */
292
size_t
293
nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len)
294
{
295
  size_t device_found = 0;
Romuald Conty's avatar
Romuald Conty committed
296

297
#ifdef CONFFILES
298 299
  // Load manually configured devices (from config file and env variables)
  // TODO From env var...
300
  for (uint32_t i = 0; i < context->user_defined_device_count; i++) {
301 302 303
    if (context->user_defined_devices[i].optional) {
      // let's make sure the device exists
      nfc_device *pnd = NULL;
304 305

#ifdef ENVVARS
306 307 308 309
      char *env_log_level = getenv("LIBNFC_LOG_LEVEL");
      char *old_env_log_level = NULL;
      // do it silently
      if (env_log_level) {
Romuald Conty's avatar
Romuald Conty committed
310 311 312 313
        if ((old_env_log_level = malloc(strlen(env_log_level) + 1)) == NULL) {
          log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to malloc()");
          return 0;
        }
314 315 316
        strcpy(old_env_log_level, env_log_level);
      }
      setenv("LIBNFC_LOG_LEVEL", "0", 1);
317 318
#endif // ENVVARS

319
      pnd = nfc_open(context, context->user_defined_devices[i].connstring);
320 321

#ifdef ENVVARS
322 323 324 325 326 327
      if (old_env_log_level) {
        setenv("LIBNFC_LOG_LEVEL", old_env_log_level, 1);
        free(old_env_log_level);
      } else {
        unsetenv("LIBNFC_LOG_LEVEL");
      }
328 329
#endif // ENVVARS

330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
      if (pnd) {
        nfc_close(pnd);
        log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "User device %s found", context->user_defined_devices[i].name);
        strcpy((char *)(connstrings + device_found), context->user_defined_devices[i].connstring);
        device_found ++;
        if (device_found == connstrings_len)
          break;
      }
    } else {
      // manual choice is not marked as optional so let's take it blindly
      strcpy((char *)(connstrings + device_found), context->user_defined_devices[i].connstring);
      device_found++;
      if (device_found >= connstrings_len)
        return device_found;
    }
345
  }
346
#endif // CONFFILES
347 348 349

  // Device auto-detection
  if (context->allow_autoscan) {
350 351 352
    const struct nfc_driver_list *pndl = nfc_drivers;
    while (pndl) {
      const struct nfc_driver *ndr = pndl->driver;
353
      size_t _device_found = 0;
354
      if ((ndr->scan_type == NOT_INTRUSIVE) || ((context->allow_intrusive_scan) && (ndr->scan_type == INTRUSIVE))) {
Romuald Conty's avatar
Romuald Conty committed
355 356
        _device_found = ndr->scan(context, connstrings + (device_found), connstrings_len - (device_found));
        log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%ld device(s) found using %s driver", (unsigned long) _device_found, ndr->name);
357 358 359 360 361 362
        if (_device_found > 0) {
          device_found += _device_found;
          if (device_found == connstrings_len)
            break;
        }
      } // scan_type is INTRUSIVE but not allowed or NOT_AVAILABLE
363
      pndl = pndl->next;
364
    }
365 366
  } else if (context->user_defined_device_count == 0) {
    log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "Warning: %s" , "user must specify device(s) manually when autoscan is disabled");
367
  }
368

369
  return device_found;
370 371
}

372
/** @ingroup properties
373 374 375 376 377 378 379 380 381 382
 * @brief Set a device's integer-property value
 * @return Returns 0 on success, otherwise returns libnfc's error code (negative value)
 * @param pnd \a nfc_device struct pointer that represent currently used device
 * @param property \a nfc_property which will be set
 * @param value integer value
 *
 * Sets integer property.
 *
 * @see nfc_property enum values
 */
383
int
384
nfc_device_set_property_int(nfc_device *pnd, const nfc_property property, const int value)
385
{
386
  HAL(device_set_property_int, pnd, property, value);
387 388
}

389

390
/** @ingroup properties
391 392 393 394 395
 * @brief Set a device's boolean-property value
 * @return Returns 0 on success, otherwise returns libnfc's error code (negative value)
 * @param pnd \a nfc_device struct pointer that represent currently used device
 * @param property \a nfc_property which will be set
 * @param bEnable boolean to activate/disactivate the property
396
 *
397 398 399 400
 * Configures parameters and registers that control for example timing,
 * modulation, frame and error handling.  There are different categories for
 * configuring the \e PN53X chip features (handle, activate, infinite and
 * accept).
401
 */
402
int
403
nfc_device_set_property_bool(nfc_device *pnd, const nfc_property property, const bool bEnable)
Roel Verdult's avatar
Roel Verdult committed
404
{
405
  HAL(device_set_property_bool, pnd, property, bEnable);
Roel Verdult's avatar
Roel Verdult committed
406 407
}

408
/** @ingroup initiator
409
 * @brief Initialize NFC device as initiator (reader)
410
 * @return Returns 0 on success, otherwise returns libnfc's error code (negative value)
411
 * @param pnd \a nfc_device struct pointer that represent currently used device
412
 *
413 414 415
 * The NFC device is configured to function as RFID reader.
 * After initialization it can be used to communicate to passive RFID tags and active NFC devices.
 * The reader will act as initiator to communicate peer 2 peer (NFCIP) to other active NFC devices.
416 417 418 419 420 421 422 423 424 425
 * - Crc is handled by the device (NP_HANDLE_CRC = true)
 * - Parity is handled the device (NP_HANDLE_PARITY = true)
 * - Cryto1 cipher is disabled (NP_ACTIVATE_CRYPTO1 = false)
 * - Easy framing is enabled (NP_EASY_FRAMING = true)
 * - Auto-switching in ISO14443-4 mode is enabled (NP_AUTO_ISO14443_4 = true)
 * - Invalid frames are not accepted (NP_ACCEPT_INVALID_FRAMES = false)
 * - Multiple frames are not accepted (NP_ACCEPT_MULTIPLE_FRAMES = false)
 * - 14443-A mode is activated (NP_FORCE_ISO14443_A = true)
 * - speed is set to 106 kbps (NP_FORCE_SPEED_106 = true)
 * - Let the device try forever to find a target (NP_INFINITE_SELECT = true)
426
 * - RF field is shortly dropped (if it was enabled) then activated again
427
 */
428
int
429
nfc_initiator_init(nfc_device *pnd)
Roel Verdult's avatar
Roel Verdult committed
430
{
431
  int res = 0;
432
  // Drop the field for a while
433
  if ((res = nfc_device_set_property_bool(pnd, NP_ACTIVATE_FIELD, false)) < 0)
434
    return res;
435
  // Enable field so more power consuming cards can power themselves up
436
  if ((res = nfc_device_set_property_bool(pnd, NP_ACTIVATE_FIELD, true)) < 0)
437
    return res;
438
  // Let the device try forever to find a target/tag
439
  if ((res = nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, true)) < 0)
440
    return res;
441
  // Activate auto ISO14443-4 switching by default
442
  if ((res = nfc_device_set_property_bool(pnd, NP_AUTO_ISO14443_4, true)) < 0)
443
    return res;
444
  // Force 14443-A mode
445
  if ((res = nfc_device_set_property_bool(pnd, NP_FORCE_ISO14443_A, true)) < 0)
446
    return res;
447
  // Force speed at 106kbps
448
  if ((res = nfc_device_set_property_bool(pnd, NP_FORCE_SPEED_106, true)) < 0)
449
    return res;
450
  // Disallow invalid frame
451
  if ((res = nfc_device_set_property_bool(pnd, NP_ACCEPT_INVALID_FRAMES, false)) < 0)
452
    return res;
453
  // Disallow multiple frames
454
  if ((res = nfc_device_set_property_bool(pnd, NP_ACCEPT_MULTIPLE_FRAMES, false)) < 0)
455
    return res;
456
  HAL(initiator_init, pnd);
Roel Verdult's avatar
Roel Verdult committed
457 458
}

459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
/** @ingroup initiator
 * @brief Initialize NFC device as initiator with its secure element initiator (reader)
 * @return Returns 0 on success, otherwise returns libnfc's error code (negative value)
 * @param pnd \a nfc_device struct pointer that represent currently used device
 *
 * The NFC device is configured to function as secure element reader.
 * After initialization it can be used to communicate with the secure element.
 * @note RF field is desactvated in order to some power
 */
int
nfc_initiator_init_secure_element(nfc_device *pnd)
{
  HAL(initiator_init_secure_element, pnd);
}

474
/** @ingroup initiator
475
 * @brief Select a passive or emulated tag
476
 * @return Returns selected passive target count on success, otherwise returns libnfc's error code (negative value)
477
 *
478
 * @param pnd \a nfc_device struct pointer that represent currently used device
479 480 481
 * @param nm desired modulation
 * @param pbtInitData optional initiator data used for Felica, ISO14443B, Topaz polling or to select a specific UID in ISO14443A.
 * @param szInitData length of initiator data \a pbtInitData.
Philippe Teuwen's avatar
Philippe Teuwen committed
482
 * @note pbtInitData is used with different kind of data depending on modulation type:
483 484 485 486
 * - for an ISO/IEC 14443 type A modulation, pbbInitData contains the UID you want to select;
 * - for an ISO/IEC 14443 type B modulation, pbbInitData contains Application Family Identifier (AFI) (see ISO/IEC 14443-3);
 * - for a FeliCa modulation, pbbInitData contains polling payload (see ISO/IEC 18092 11.2.2.5).
 *
487
 * @param[out] pnt \a nfc_target struct pointer which will filled if available
488
 *
489
 * The NFC device will try to find one available passive tag or emulated tag.
490
 *
491 492
 * The chip needs to know with what kind of tag it is dealing with, therefore
 * the initial modulation and speed (106, 212 or 424 kbps) should be supplied.
493
 */
494
int
495 496 497 498
nfc_initiator_select_passive_target(nfc_device *pnd,
                                    const nfc_modulation nm,
                                    const uint8_t *pbtInitData, const size_t szInitData,
                                    nfc_target *pnt)
Roel Verdult's avatar
Roel Verdult committed
499
{
500
  uint8_t  abtInit[MAX(12, szInitData)];
501
  size_t  szInit;
502

503
  switch (nm.nmt) {
504
    case NMT_ISO14443A:
505
      iso14443_cascade_uid(pbtInitData, szInitData, abtInit, &szInit);
506 507 508 509 510 511 512 513 514
      break;

    case NMT_JEWEL:
    case NMT_ISO14443B:
    case NMT_ISO14443BI:
    case NMT_ISO14443B2SR:
    case NMT_ISO14443B2CT:
    case NMT_FELICA:
    case NMT_DEP:
515
      memcpy(abtInit, pbtInitData, szInitData);
516 517
      szInit = szInitData;
      break;
518
  }
519

520
  HAL(initiator_select_passive_target, pnd, nm, abtInit, szInit, pnt);
Roel Verdult's avatar
Roel Verdult committed
521 522
}

523
/** @ingroup initiator
524
 * @brief List passive or emulated tags
525
 * @return Returns the number of targets found on success, otherwise returns libnfc's error code (negative value)
526
 *
527
 * @param pnd \a nfc_device struct pointer that represent currently used device
528
 * @param nm desired modulation
529
 * @param[out] ant array of \a nfc_target that will be filled with targets info
530
 * @param szTargets size of \a ant (will be the max targets listed)
531 532 533 534 535 536 537
 *
 * The NFC device will try to find the available passive tags. Some NFC devices
 * are capable to emulate passive tags. The standards (ISO18092 and ECMA-340)
 * describe the modulation that can be used for reader to passive
 * communications. The chip needs to know with what kind of tag it is dealing
 * with, therefore the initial modulation and speed (106, 212 or 424 kbps)
 * should be supplied.
538
 */
539
int
540 541 542
nfc_initiator_list_passive_targets(nfc_device *pnd,
                                   const nfc_modulation nm,
                                   nfc_target ant[], const size_t szTargets)
543
{
544
  nfc_target nt;
545
  size_t  szTargetFound = 0;
546
  uint8_t *pbtInitData = NULL;
547
  size_t  szInitDataLen = 0;
548
  int res = 0;
549

550
  pnd->last_error = 0;
551

552
  // Let the reader only try once to find a tag
553
  if ((res = nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false)) < 0) {
554
    return res;
555
  }
556

557
  prepare_initiator_data(nm, &pbtInitData, &szInitDataLen);
558

559
  while (nfc_initiator_select_passive_target(pnd, nm, pbtInitData, szInitDataLen, &nt) > 0) {
560
    size_t i;
561 562 563
    bool seen = false;
    // Check if we've already seen this tag
    for (i = 0; i < szTargetFound; i++) {
564
      if (memcmp(&(ant[i]), &nt, sizeof(nfc_target)) == 0) {
565 566 567 568
        seen = true;
      }
    }
    if (seen) {
569
      break;
570
    }
571
    memcpy(&(ant[szTargetFound]), &nt, sizeof(nfc_target));
572
    szTargetFound++;
573 574 575 576
    if (szTargets == szTargetFound) {
      break;
    }
    nfc_initiator_deselect_target(pnd);
577
    // deselect has no effect on FeliCa and Jewel cards so we'll stop after one...
578
    // ISO/IEC 14443 B' cards are polled at 100% probability so it's not possible to detect correctly two cards at the same time
579
    if ((nm.nmt == NMT_FELICA) || (nm.nmt == NMT_JEWEL) || (nm.nmt == NMT_ISO14443BI) || (nm.nmt == NMT_ISO14443B2SR) || (nm.nmt == NMT_ISO14443B2CT)) {
580
      break;
581
    }
582
  }
583
  return szTargetFound;
584 585
}

586
/** @ingroup initiator
587
 * @brief Polling for NFC targets
588
 * @return Returns polled targets count, otherwise returns libnfc's error code (negative value).
589
 *
590
 * @param pnd \a nfc_device struct pointer that represent currently used device
591
 * @param pnmModulations desired modulations
592
 * @param szModulations size of \a pnmModulations
593
 * @param uiPollNr specifies the number of polling (0x01 – 0xFE: 1 up to 254 polling, 0xFF: Endless polling)
594
 * @note one polling is a polling for each desired target type
595 596
 * @param uiPeriod indicates the polling period in units of 150 ms (0x01 – 0x0F: 150ms – 2.25s)
 * @note e.g. if uiPeriod=10, it will poll each desired target type during 1.5s
597
 * @param[out] pnt pointer on \a nfc_target (over)writable struct
598
 */
599
int
600 601 602 603
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)
604
{
605
  HAL(initiator_poll_target, pnd, pnmModulations, szModulations, uiPollNr, uiPeriod, pnt);
606 607
}

608

609
/** @ingroup initiator
610
 * @brief Select a target and request active or passive mode for D.E.P. (Data Exchange Protocol)
611
 * @return Returns selected D.E.P targets count on success, otherwise returns libnfc's error code (negative value).
612
 *
613
 * @param pnd \a nfc_device struct pointer that represent currently used device
614
 * @param ndm desired D.E.P. mode (\a NDM_ACTIVE or \a NDM_PASSIVE for active, respectively passive mode)
615
 * @param nbr desired baud rate
616 617
 * @param ndiInitiator pointer \a nfc_dep_info struct that contains \e NFCID3 and \e General \e Bytes to set to the initiator device (optionnal, can be \e NULL)
 * @param[out] pnt is a \a nfc_target struct pointer where target information will be put.
618
 * @param timeout in milliseconds
619
 *
620 621 622
 * The NFC device will try to find an available D.E.P. target. The standards
 * (ISO18092 and ECMA-340) describe the modulation that can be used for reader
 * to passive communications.
623
 *
624
 * @note \a nfc_dep_info will be returned when the target was acquired successfully.
625 626 627
 *
 * If timeout equals to 0, the function blocks indefinitely (until an error is raised or function is completed)
 * If timeout equals to -1, the default timeout will be used
628
 */
629
int
630 631 632
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)
Roel Verdult's avatar
Roel Verdult committed
633
{
634
  HAL(initiator_select_dep_target, pnd, ndm, nbr, pndiInitiator, pnt, timeout);
635
}
636

637
/** @ingroup initiator
638 639 640 641 642
 * @brief Poll a target and request active or passive mode for D.E.P. (Data Exchange Protocol)
 * @return Returns selected D.E.P targets count on success, otherwise returns libnfc's error code (negative value).
 *
 * @param pnd \a nfc_device struct pointer that represent currently used device
 * @param ndm desired D.E.P. mode (\a NDM_ACTIVE or \a NDM_PASSIVE for active, respectively passive mode)
643
 * @param nbr desired baud rate
644 645
 * @param ndiInitiator pointer \a nfc_dep_info struct that contains \e NFCID3 and \e General \e Bytes to set to the initiator device (optionnal, can be \e NULL)
 * @param[out] pnt is a \a nfc_target struct pointer where target information will be put.
646
 * @param timeout in milliseconds
647 648 649 650
 *
 * The NFC device will try to find an available D.E.P. target. The standards
 * (ISO18092 and ECMA-340) describe the modulation that can be used for reader
 * to passive communications.
651
 *
652 653 654
 * @note \a nfc_dep_info will be returned when the target was acquired successfully.
 */
int
655 656 657 658 659
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)
660 661 662 663
{
  const int period = 300;
  int remaining_time = timeout;
  int res;
664
  if ((res = nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, true)) < 0)
665 666
    return res;
  while (remaining_time > 0) {
667
    if ((res = nfc_initiator_select_dep_target(pnd, ndm, nbr, pndiInitiator, pnt, period)) < 0) {
668 669 670 671 672 673 674 675
      if (res != NFC_ETIMEOUT)
        return res;
    }
    if (res == 1)
      return res;
    remaining_time -= period;
  }
  return 0;
676
}
677

678
/** @ingroup initiator
679
 * @brief Deselect a selected passive or emulated tag
680
 * @return Returns 0 on success, otherwise returns libnfc's error code (negative value).
681
 * @param pnd \a nfc_device struct pointer that represents currently used device
682
 *
683
 * After selecting and communicating with a passive tag, this function could be
684
 * used to deactivate and release the tag. This is very useful when there are
685 686 687 688
 * multiple tags available in the field. It is possible to use the \fn
 * nfc_initiator_select_passive_target() function to select the first available
 * tag, test it for the available features and support, deselect it and skip to
 * the next tag until the correct tag is found.
689
 */
690
int
691
nfc_initiator_deselect_target(nfc_device *pnd)
692
{
693
  HAL(initiator_deselect_target, pnd);
Roel Verdult's avatar
Roel Verdult committed
694 695
}

696
/** @ingroup initiator
697
 * @brief Send data to target then retrieve data from target
698
 * @return Returns received bytes count on success, otherwise returns libnfc's error code
699
 *
700
 * @param pnd \a nfc_device struct pointer that represents currently used device
701 702
 * @param pbtTx contains a byte array of the frame that needs to be transmitted.
 * @param szTx contains the length in bytes.
703
 * @param[out] pbtRx response from the target
704
 * @param szRx size of \a pbtRx (Will return NFC_EOVFLOW if RX exceeds this size)
Audrey Diacre's avatar
Audrey Diacre committed
705
 * @param timeout in milliseconds
706
 *
707
 * The NFC device (configured as initiator) will transmit the supplied bytes (\a pbtTx) to the target.
708 709
 * It waits for the response and stores the received bytes in the \a pbtRx byte array.
 *
710
 * If \a NP_EASY_FRAMING option is disabled the frames will sent and received in raw mode: \e PN53x will not handle input neither output data.
711
 *
712 713
 * The parity bits are handled by the \e PN53x chip. The CRC can be generated automatically or handled manually.
 * Using this function, frames can be communicated very fast via the NFC initiator to the tag.
714 715 716
 *
 * Tests show that on average this way of communicating is much faster than using the regular driver/middle-ware (often supplied by manufacturers).
 *
717
 * @warning The configuration option \a NP_HANDLE_PARITY must be set to \c true (the default value).
718
 *
719
 * @note When used with MIFARE Classic, NFC_EMFCAUTHFAIL error is returned if authentication command failed. You need to re-select the tag to operate with.
720
 *
721 722
 * If timeout equals to 0, the function blocks indefinitely (until an error is raised or function is completed)
 * If timeout equals to -1, the default timeout will be used
723
 */
724
int
725 726
nfc_initiator_transceive_bytes(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx,
                               const size_t szRx, int timeout)
Roel Verdult's avatar
Roel Verdult committed
727
{
728
  HAL(initiator_transceive_bytes, pnd, pbtTx, szTx, pbtRx, szRx, timeout)
Roel Verdult's avatar
Roel Verdult committed
729 730
}

731
/** @ingroup initiator
732
 * @brief Transceive raw bit-frames to a target
733
 * @return Returns received bits count on success, otherwise returns libnfc's error code
734
 *
735
 * @param pnd \a nfc_device struct pointer that represents currently used device
736 737
 * @param pbtTx contains a byte array of the frame that needs to be transmitted.
 * @param szTxBits contains the length in bits.
738 739 740 741 742 743
 *
 * @note For example the REQA (0x26) command (first anti-collision command of
 * ISO14443-A) must be precise 7 bits long. This is not possible by using
 * nfc_initiator_transceive_bytes(). With that function you can only
 * communicate frames that consist of full bytes. When you send a full byte (8
 * bits + 1 parity) with the value of REQA (0x26), a tag will simply not
Philippe Teuwen's avatar
Philippe Teuwen committed
744
 * respond. More information about this can be found in the anti-collision
745 746
 * example (\e nfc-anticol).
 *
747 748
 * @param pbtTxPar parameter contains a byte array of the corresponding parity bits needed to send per byte.
 *
749 750 751 752 753 754
 * @note For example if you send the SELECT_ALL (0x93, 0x20) = [ 10010011,
 * 00100000 ] command, you have to supply the following parity bytes (0x01,
 * 0x00) to define the correct odd parity bits. This is only an example to
 * explain how it works, if you just are sending two bytes with ISO14443-A
 * compliant parity bits you better can use the
 * nfc_initiator_transceive_bytes() function.
755
 *
756 757
 * @param[out] pbtRx response from the target
 * @param szRx size of \a pbtRx (Will return NFC_EOVFLOW if RX exceeds this size)
758 759 760 761 762 763 764 765
 * @param[out] pbtRxPar parameter contains a byte array of the corresponding parity bits
 *
 * The NFC device (configured as \e initiator) will transmit low-level messages
 * where only the modulation is handled by the \e PN53x chip. Construction of
 * the frame (data, CRC and parity) is completely done by libnfc.  This can be
 * very useful for testing purposes. Some protocols (e.g. MIFARE Classic)
 * require to violate the ISO14443-A standard by sending incorrect parity and
 * CRC bytes. Using this feature you are able to simulate these frames.
766
 */
767
int
768
nfc_initiator_transceive_bits(nfc_device *pnd,
769 770 771
                              const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar,
                              uint8_t *pbtRx, const size_t szRx,
                              uint8_t *pbtRxPar)
772
{
773
  (void)szRx;
774
  HAL(initiator_transceive_bits, pnd, pbtTx, szTxBits, pbtTxPar, pbtRx, pbtRxPar);
775 776
}

777
/** @ingroup initiator
778
 * @brief Send data to target then retrieve data from target
779
 * @return Returns received bytes count on success, otherwise returns libnfc's error code.
780
 *
781 782 783 784 785 786
 * @param pnd \a nfc_device struct pointer that represents currently used device
 * @param pbtTx contains a byte array of the frame that needs to be transmitted.
 * @param szTx contains the length in bytes.
 * @param[out] pbtRx response from the target
 * @param szRx size of \a pbtRx (Will return NFC_EOVFLOW if RX exceeds this size)
 *
787 788
 * This function is similar to nfc_initiator_transceive_bytes() with the following differences:
 * - A precise cycles counter will indicate the number of cycles between emission & reception of frames.
789
 * - It only supports mode with \a NP_EASY_FRAMING option disabled.
790 791
 * - Overall communication with the host is heavier and slower.
 *
792
 * Timer control:
793 794 795
 * By default timer configuration tries to maximize the precision, which also limits the maximum
 * cycles count before saturation/timeout.
 * E.g. with PN53x it can count up to 65535 cycles, so about 4.8ms, with a precision of about 73ns.
796 797 798 799
 * - If you're ok with the defaults, set *cycles = 0 before calling this function.
 * - If you need to count more cycles, set *cycles to the maximum you expect but don't forget
 *   you'll loose in precision and it'll take more time before timeout, so don't abuse!
 *
800 801
 * @warning The configuration option \a NP_EASY_FRAMING must be set to \c false.
 * @warning The configuration option \a NP_HANDLE_PARITY must be set to \c true (the default value).
802
 */
803
int
804 805
nfc_initiator_transceive_bytes_timed(nfc_device *pnd,
                                     const uint8_t *pbtTx, const size_t szTx,
806 807
                                     uint8_t *pbtRx, const size_t szRx,
                                     uint32_t *cycles)
808
{
809
  HAL(initiator_transceive_bytes_timed, pnd, pbtTx, szTx, pbtRx, szRx, cycles);
810 811 812 813 814 815 816 817 818 819 820
}

/** @ingroup initiator
 * @brief Check target presence
 * @return Returns 0 on success, otherwise returns libnfc's error code.
 *
 * This function tests if \a nfc_target is currently present on NFC device.
 * @warning The target have to be selected before check its presence
 * @warning To run the test, one or more commands will be sent to target
*/
int
821
nfc_initiator_target_is_present(nfc_device *pnd, const nfc_target nt)
822
{
823
  HAL(initiator_target_is_present, pnd, nt);
824 825
}

826
/** @ingroup initiator
827
 * @brief Transceive raw bit-frames to a target
828
 * @return Returns received bits count on success, otherwise returns libnfc's error code
829 830 831
 *
 * This function is similar to nfc_initiator_transceive_bits() with the following differences:
 * - A precise cycles counter will indicate the number of cycles between emission & reception of frames.
832
 * - It only supports mode with \a NP_EASY_FRAMING option disabled and CRC must be handled manually.
833 834
 * - Overall communication with the host is heavier and slower.
 *
835
 * Timer control:
836 837 838
 * By default timer configuration tries to maximize the precision, which also limits the maximum
 * cycles count before saturation/timeout.
 * E.g. with PN53x it can count up to 65535 cycles, so about 4.8ms, with a precision of about 73ns.
839 840 841 842
 * - If you're ok with the defaults, set *cycles = 0 before calling this function.
 * - If you need to count more cycles, set *cycles to the maximum you expect but don't forget
 *   you'll loose in precision and it'll take more time before timeout, so don't abuse!
 *
843 844 845
 * @warning The configuration option \a NP_EASY_FRAMING must be set to \c false.
 * @warning The configuration option \a NP_HANDLE_CRC must be set to \c false.
 * @warning The configuration option \a NP_HANDLE_PARITY must be set to \c true (the default value).
846
 */
847
int
848
nfc_initiator_transceive_bits_timed(nfc_device *pnd,
849
                                    const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar,
850 851
                                    uint8_t *pbtRx, const size_t szRx,
                                    uint8_t *pbtRxPar,
852
                                    uint32_t *cycles)
853
{
854
  (void)szRx;
855
  HAL(initiator_transceive_bits_timed, pnd, pbtTx, szTxBits, pbtTxPar, pbtRx, pbtRxPar, cycles);
856 857
}

858
/** @ingroup target
859
 * @brief Initialize NFC device as an emulated tag
860
 * @return Returns received bytes count on success, otherwise returns libnfc's error code
861
 *
862 863
 * @param pnd \a nfc_device struct pointer that represent currently used device
 * @param pnt pointer to \a nfc_target struct that represents the wanted emulated target
864 865 866 867
 *
 * @note \a pnt can be updated by this function: if you set NBR_UNDEFINED
 * and/or NDM_UNDEFINED (ie. for DEP mode), these fields will be updated.
 *
Romuald Conty's avatar
Romuald Conty committed
868
 * @param[out] pbtRx Rx buffer pointer
869
 * @param[out] szRx received bytes count
870
 * @param timeout in milliseconds
871
 *
872
 * This function initializes NFC device in \e target mode in order to emulate a
873
 * tag using the specified \a nfc_target_mode_t.
874 875 876 877 878 879 880
 * - Crc is handled by the device (NP_HANDLE_CRC = true)
 * - Parity is handled the device (NP_HANDLE_PARITY = true)
 * - Cryto1 cipher is disabled (NP_ACTIVATE_CRYPTO1 = false)
 * - Auto-switching in ISO14443-4 mode is enabled (NP_AUTO_ISO14443_4 = true)
 * - Easy framing is disabled (NP_EASY_FRAMING = false)
 * - Invalid frames are not accepted (NP_ACCEPT_INVALID_FRAMES = false)
 * - Multiple frames are not accepted (NP_ACCEPT_MULTIPLE_FRAMES = false)
881
 * - RF field is dropped
882
 *
883 884 885 886
 * @warning Be aware that this function will wait (hang) until a command is
 * received that is not part of the anti-collision. The RATS command for
 * example would wake up the emulator. After this is received, the send and
 * receive functions can be used.
887 888 889
 *
 * If timeout equals to 0, the function blocks indefinitely (until an error is raised or function is completed)
 * If timeout equals to -1, the default timeout will be used
890
 */
891
int
892
nfc_target_init(nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRx, int timeout)
Roel Verdult's avatar
Roel Verdult committed
893
{
894
  int res = 0;
895
  // Disallow invalid frame
896
  if ((res = nfc_device_set_property_bool(pnd, NP_ACCEPT_INVALID_FRAMES, false)) < 0)
Audrey Diacre's avatar
Audrey Diacre committed
897
    return res;
898
  // Disallow multiple frames
899
  if ((res = nfc_device_set_property_bool(pnd, NP_ACCEPT_MULTIPLE_FRAMES, false)) < 0)
Audrey Diacre's avatar
Audrey Diacre committed
900
    return res;
901
  // Make sure we reset the CRC and parity to chip handling.
902
  if ((res = nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true)) < 0)
Audrey Diacre's avatar
Audrey Diacre committed
903
    return res;
904
  if ((res = nfc_device_set_property_bool(pnd, NP_HANDLE_PARITY, true)) < 0)
Audrey Diacre's avatar
Audrey Diacre committed
905
    return res;
906
  // Activate auto ISO14443-4 switching by default
907
  if ((res = nfc_device_set_property_bool(pnd, NP_AUTO_ISO14443_4, true)) < 0)
Audrey Diacre's avatar
Audrey Diacre committed
908
    return res;
909
  // Activate "easy framing" feature by default
910
  if ((res = nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, true)) < 0)
Audrey Diacre's avatar
Audrey Diacre committed
911
    return res;
912
  // Deactivate the CRYPTO1 cipher, it may could cause problems when still active
913
  if ((res = nfc_device_set_property_bool(pnd, NP_ACTIVATE_CRYPTO1, false)) < 0)
Audrey Diacre's avatar
Audrey Diacre committed
914
    return res;
915
  // Drop explicitely the field
916
  if ((res = nfc_device_set_property_bool(pnd, NP_ACTIVATE_FIELD, false)) < 0)
Audrey Diacre's avatar
Audrey Diacre committed
917
    return res;
918

919
  HAL(target_init, pnd, pnt, pbtRx, szRx, timeout);
Roel Verdult's avatar
Roel Verdult committed
920 921
}

922
/** @ingroup dev
923
 * @brief Turn NFC device in idle mode
924
 * @return Returns 0 on success, otherwise returns libnfc's error code.
925
 *
926
 * @param pnd \a nfc_device struct pointer that represent currently used device
927 928 929 930 931
 *
 * This function switch the device in idle mode.
 * In initiator mode, the RF field is turned off and the device is set to low power mode (if avaible);
 * In target mode, the emulation is stoped (no target available from external initiator) and the device is set to low power mode (if avaible).
 */
932
int
933
nfc_idle(nfc_device *pnd)
934
{
935
  HAL(idle, pnd);
936 937
}

938
/** @ingroup dev
939
 * @brief Abort current running command
940
 * @return Returns 0 on success, otherwise returns libnfc's error code.
941
 *
942
 * @param pnd \a nfc_device struct pointer that represent currently used device
943 944 945 946 947 948
 *
 * Some commands (ie. nfc_target_init()) are blocking functions and will return only in particular conditions (ie. external initiator request).
 * This function attempt to abort the current running command.
 *
 * @note The blocking function (ie. nfc_target_init()) will failed with DEABORT error.
 */
949
int
950
nfc_abort_command(nfc_device *pnd)
951
{
952
  HAL(abort_command, pnd);
953 954
}

955
/** @ingroup target
956
 * @brief Send bytes and APDU frames
957
 * @return Returns sent bytes count on success, otherwise returns libnfc's error code
958
 *
959
 * @param pnd \a nfc_device struct pointer that represent currently used device
960
 * @param pbtTx pointer to Tx buffer
961
 * @param szTx size of Tx buffer
Audrey Diacre's avatar
Audrey Diacre committed
962
 * @param timeout in milliseconds
963
 *
964 965
 * This function make the NFC device (configured as \e target) send byte frames
 * (e.g. APDU responses) to the \e initiator.
966
 *
967 968
 * If timeout equals to 0, the function blocks indefinitely (until an error is raised or function is completed)
 * If timeout equals to -1, the default timeout will be used
969
 */
970
int
971
nfc_target_send_bytes(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, int timeout)
Roel Verdult's avatar
Roel Verdult committed
972
{
973
  HAL(target_send_bytes, pnd, pbtTx, szTx, timeout);
Roel Verdult's avatar
Roel Verdult committed
974 975
}

976
/** @ingroup target
977
 * @brief Receive bytes and APDU frames
978
 * @return Returns received bytes count on success, otherwise returns libnfc's error code
979
 *
980
 * @param pnd \a nfc_device struct pointer that represent currently used device
981 982
 * @param pbtRx pointer to Rx buffer
 * @param szRx size of Rx buffer
Audrey Diacre's avatar
Audrey Diacre committed
983
 * @param timeout in milliseconds
984
 *
985
 * This function retrieves bytes frames (e.g. ADPU) sent by the \e initiator to the NFC device (configured as \e target).
986
 *
987 988
 * If timeout equals to 0, the function blocks indefinitely (until an error is raised or function is completed)
 * If timeout equals to -1, the default timeout will be used
989
 */
990
int
991
nfc_target_receive_bytes(nfc_device *pnd, uint8_t *pbtRx, const size_t szRx, int timeout)
Roel Verdult's avatar
Roel Verdult committed
992
{
993
  HAL(target_receive_bytes, pnd, pbtRx, szRx, timeout);
Roel Verdult's avatar
Roel Verdult committed
994 995
}

996
/** @ingroup target
997
 * @brief Send raw bit-frames
998
 * @return Returns sent bits count on success, otherwise returns libnfc's error code.
999
 *
1000 1001 1002 1003
 * @param pnd \a nfc_device struct pointer that represent currently used device
 * @param pbtTx pointer to Tx buffer
 * @param szTxBits size of Tx buffer
 * @param pbtTxPar parameter contains a byte array of the corresponding parity bits needed to send per byte.
1004 1005
 * This function can be used to transmit (raw) bit-frames to the \e initiator
 * using the specified NFC device (configured as \e target).
1006
 */
1007
int
1008
nfc_target_send_bits(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar)
Roel Verdult's avatar
Roel Verdult committed
1009
{
1010
  HAL(target_send_bits, pnd, pbtTx, szTxBits, pbtTxPar);
Roel Verdult's avatar
Roel Verdult committed
1011 1012
}

1013
/** @ingroup target
1014
 * @brief Receive bit-frames
1015
 * @return Returns received bits count on success, otherwise returns libnfc's error code
1016
 *