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); }
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; }
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; }
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; }