Exemple #1
0
static int
arygon_abort(nfc_device *pnd)
{
  // Send a valid TAMA packet to wakup the PN53x (we will not have an answer, according to Arygon manual)
  uint8_t dummy[] = { 0x32, 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd4, 0x00, 0x00, 0x6c, 0x69, 0x62, 0x6e, 0x66, 0x63, 0xbe, 0x00 };

  uart_send(DRIVER_DATA(pnd)->port, dummy, sizeof(dummy), 0);

  // Using Arygon device we can't send ACK frame to abort the running command
  return pn53x_check_communication(pnd);
}
Exemple #2
0
static size_t
pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len)
{
  size_t device_found = 0;
  serial_port sp;
  char **acPorts = uart_list_ports();
  const char *acPort;
  int     iDevice = 0;

  while ((acPort = acPorts[iDevice++])) {
    sp = uart_open(acPort);
    log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Trying to find PN532 device on serial port: %s at %d bauds.", acPort, PN532_UART_DEFAULT_SPEED);

    if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
      // We need to flush input to be sure first reply does not comes from older byte transceive
      uart_flush_input(sp);
      // Serial port claimed but we need to check if a PN532_UART is opened.
      uart_set_speed(sp, PN532_UART_DEFAULT_SPEED);

      nfc_connstring connstring;
      snprintf(connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, PN532_UART_DRIVER_NAME, acPort, PN532_UART_DEFAULT_SPEED);
      nfc_device *pnd = nfc_device_new(context, connstring);
      pnd->driver = &pn532_uart_driver;
      pnd->driver_data = malloc(sizeof(struct pn532_uart_data));
      DRIVER_DATA(pnd)->port = sp;

      // Alloc and init chip's data
      pn53x_data_new(pnd, &pn532_uart_io);
      // SAMConfiguration command if needed to wakeup the chip and pn53x_SAMConfiguration check if the chip is a PN532
      CHIP_DATA(pnd)->type = PN532;
      // This device starts in LowVBat power mode
      CHIP_DATA(pnd)->power_mode = LOWVBAT;

#ifndef WIN32
      // pipe-based abort mecanism
      if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
        return 0;
      }
#else
      DRIVER_DATA(pnd)->abort_flag = false;
#endif

      // Check communication using "Diagnose" command, with "Communication test" (0x00)
      int res = pn53x_check_communication(pnd);
      pn53x_data_free(pnd);
      nfc_device_free(pnd);
      uart_close(sp);
      if (res < 0) {
        continue;
      }

      memcpy(connstrings[device_found], connstring, sizeof(nfc_connstring));
      device_found++;

      // Test if we reach the maximum "wanted" devices
      if (device_found >= connstrings_len)
        break;
    }
  }
  iDevice = 0;
  while ((acPort = acPorts[iDevice++])) {
    free((void *)acPort);
  }
  free(acPorts);
  return device_found;
}
Exemple #3
0
static nfc_device *
pn532_uart_open(const nfc_context *context, const nfc_connstring connstring)
{
  struct pn532_uart_descriptor ndd;
  int connstring_decode_level = pn532_connstring_decode(connstring, &ndd);

  if (connstring_decode_level < 2) {
    return NULL;
  }
  if (connstring_decode_level < 3) {
    ndd.speed = PN532_UART_DEFAULT_SPEED;
  }
  serial_port sp;
  nfc_device *pnd = NULL;

  log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Attempt to open: %s at %d bauds.", ndd.port, ndd.speed);
  sp = uart_open(ndd.port);

  if (sp == INVALID_SERIAL_PORT)
    log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Invalid serial port: %s", ndd.port);
  if (sp == CLAIMED_SERIAL_PORT)
    log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Serial port already claimed: %s", ndd.port);
  if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT))
    return NULL;

  // We need to flush input to be sure first reply does not comes from older byte transceive
  uart_flush_input(sp);
  uart_set_speed(sp, ndd.speed);

  // We have a connection
  pnd = nfc_device_new(context, connstring);
  snprintf(pnd->name, sizeof(pnd->name), "%s:%s", PN532_UART_DRIVER_NAME, ndd.port);

  pnd->driver_data = malloc(sizeof(struct pn532_uart_data));
  DRIVER_DATA(pnd)->port = sp;

  // Alloc and init chip's data
  pn53x_data_new(pnd, &pn532_uart_io);
  // SAMConfiguration command if needed to wakeup the chip and pn53x_SAMConfiguration check if the chip is a PN532
  CHIP_DATA(pnd)->type = PN532;
  // This device starts in LowVBat mode
  CHIP_DATA(pnd)->power_mode = LOWVBAT;

  // empirical tuning
  CHIP_DATA(pnd)->timer_correction = 48;
  pnd->driver = &pn532_uart_driver;

#ifndef WIN32
  // pipe-based abort mecanism
  if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
    return NULL;
  }
#else
  DRIVER_DATA(pnd)->abort_flag = false;
#endif

  // Check communication using "Diagnose" command, with "Communication test" (0x00)
  if (pn53x_check_communication(pnd) < 0) {
    nfc_perror(pnd, "pn53x_check_communication");
    pn532_uart_close(pnd);
    return NULL;
  }

  pn53x_init(pnd);
  return pnd;
}
Exemple #4
0
bool
pn532_uart_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t *pszDeviceFound)
{
  /** @note: Due to UART bus we can't know if its really a pn532 without
  * sending some PN53x commands. But using this way to probe devices, we can
  * have serious problem with other device on this bus */
#ifndef SERIAL_AUTOPROBE_ENABLED
  (void) connstrings;
  (void) connstrings_len;
  *pszDeviceFound = 0;
  log_put (LOG_CATEGORY, NFC_PRIORITY_INFO, "%s", "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
  return false;
#else /* SERIAL_AUTOPROBE_ENABLED */
  *pszDeviceFound = 0;

  serial_port sp;
  char **acPorts = uart_list_ports ();
  const char *acPort;
  int     iDevice = 0;

  while ((acPort = acPorts[iDevice++])) {
    sp = uart_open (acPort);
    log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Trying to find PN532 device on serial port: %s at %d bauds.", acPort, PN532_UART_DEFAULT_SPEED);

    if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
      // We need to flush input to be sure first reply does not comes from older byte transceive
      uart_flush_input (sp);
      // Serial port claimed but we need to check if a PN532_UART is opened.
      uart_set_speed (sp, PN532_UART_DEFAULT_SPEED);

      nfc_connstring connstring;
      snprintf (connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, PN532_UART_DRIVER_NAME, acPort, PN532_UART_DEFAULT_SPEED);
      nfc_device *pnd = nfc_device_new (connstring);
      pnd->driver = &pn532_uart_driver;
      pnd->driver_data = malloc(sizeof(struct pn532_uart_data));
      DRIVER_DATA (pnd)->port = sp;

      // Alloc and init chip's data
      pn53x_data_new (pnd, &pn532_uart_io);
      // SAMConfiguration command if needed to wakeup the chip and pn53x_SAMConfiguration check if the chip is a PN532
      CHIP_DATA (pnd)->type = PN532;
      // This device starts in LowVBat power mode
      CHIP_DATA (pnd)->power_mode = LOWVBAT;

#ifndef WIN32
      // pipe-based abort mecanism
      pipe (DRIVER_DATA (pnd)->iAbortFds);
#else
      DRIVER_DATA (pnd)->abort_flag = false;
#endif

      // Check communication using "Diagnose" command, with "Communication test" (0x00)
      int res = pn53x_check_communication (pnd);
      pn53x_data_free (pnd);
      nfc_device_free (pnd);
      uart_close (sp);
      if(res < 0) {
        continue;
      }

      memcpy (connstrings[*pszDeviceFound], connstring, sizeof (nfc_connstring));
      (*pszDeviceFound)++;

      // Test if we reach the maximum "wanted" devices
      if ((*pszDeviceFound) >= connstrings_len)
        break;
    }
  }
  iDevice = 0;
  while ((acPort = acPorts[iDevice++])) {
    free ((void*)acPort);
  }
  free (acPorts);
#endif /* SERIAL_AUTOPROBE_ENABLED */
  return true;
}