static int pn532_uart_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout) { int res = 0; // Before sending anything, we need to discard from any junk bytes uart_flush_input(DRIVER_DATA(pnd)->port); switch (CHIP_DATA(pnd)->power_mode) { case LOWVBAT: { /** PN532C106 wakeup. */ if ((res = pn532_uart_wakeup(pnd)) < 0) { return res; } // According to PN532 application note, C106 appendix: to go out Low Vbat mode and enter in normal mode we need to send a SAMConfiguration command if ((res = pn532_SAMConfiguration(pnd, PSM_NORMAL, 1000)) < 0) { return res; } } break; case POWERDOWN: { if ((res = pn532_uart_wakeup(pnd)) < 0) { return res; } } break; case NORMAL: // Nothing to do :) break; }; uint8_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff" size_t szFrame = 0; if ((res = pn53x_build_frame(abtFrame, &szFrame, pbtData, szData)) < 0) { pnd->last_error = res; return pnd->last_error; } res = uart_send(DRIVER_DATA(pnd)->port, abtFrame, szFrame, timeout); if (res != 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)"); pnd->last_error = res; return pnd->last_error; } uint8_t abtRxBuf[6]; res = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 6, 0, timeout); if (res != 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "Unable to read ACK"); pnd->last_error = res; return pnd->last_error; } if (pn53x_check_ack_frame(pnd, abtRxBuf, sizeof(abtRxBuf)) == 0) { // The PN53x is running the sent command } else { return pnd->last_error; } return NFC_SUCCESS; }
/** * @brief UART Event Task Entry * * @param param task parameter */ static void uart_event_task_entry(void *param) { esp_modem_dte_t *esp_dte = (esp_modem_dte_t *)param; uart_event_t event; while (1) { if (xQueueReceive(esp_dte->event_queue, &event, pdMS_TO_TICKS(100))) { switch (event.type) { case UART_DATA: esp_handle_uart_data(esp_dte); break; case UART_FIFO_OVF: ESP_LOGW(MODEM_TAG, "HW FIFO Overflow"); uart_flush_input(esp_dte->uart_port); xQueueReset(esp_dte->event_queue); break; case UART_BUFFER_FULL: ESP_LOGW(MODEM_TAG, "Ring Buffer Full"); uart_flush_input(esp_dte->uart_port); xQueueReset(esp_dte->event_queue); break; case UART_BREAK: ESP_LOGW(MODEM_TAG, "Rx Break"); break; case UART_PARITY_ERR: ESP_LOGE(MODEM_TAG, "Parity Error"); break; case UART_FRAME_ERR: ESP_LOGE(MODEM_TAG, "Frame Error"); break; case UART_PATTERN_DET: esp_handle_uart_pattern(esp_dte); break; default: ESP_LOGW(MODEM_TAG, "unknown uart event type: %d", event.type); break; } } /* Drive the event loop */ esp_event_loop_run(esp_dte->event_loop_hdl, pdMS_TO_TICKS(50)); } vTaskDelete(NULL); }
static int arygon_tama_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout) { int res = 0; // Before sending anything, we need to discard from any junk bytes uart_flush_input(DRIVER_DATA(pnd)->port, false); uint8_t abtFrame[ARYGON_TX_BUFFER_LEN] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "0x32 0x00 0x00 0xff" size_t szFrame = 0; if (szData > PN53x_NORMAL_FRAME__DATA_MAX_LEN) { // ARYGON Reader with PN532 equipped does not support extended frame (bug in ARYGON firmware?) log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "ARYGON device does not support more than %d bytes as payload (requested: %" PRIdPTR ")", PN53x_NORMAL_FRAME__DATA_MAX_LEN, szData); pnd->last_error = NFC_EDEVNOTSUPP; return pnd->last_error; } if ((res = pn53x_build_frame(abtFrame + 1, &szFrame, pbtData, szData)) < 0) { pnd->last_error = res; return pnd->last_error; } if ((res = uart_send(DRIVER_DATA(pnd)->port, abtFrame, szFrame + 1, timeout)) != 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)"); pnd->last_error = res; return pnd->last_error; } uint8_t abtRxBuf[PN53x_ACK_FRAME__LEN]; if ((res = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, sizeof(abtRxBuf), 0, timeout)) != 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to read ACK"); pnd->last_error = res; return pnd->last_error; } if (pn53x_check_ack_frame(pnd, abtRxBuf, sizeof(abtRxBuf)) == 0) { // The PN53x is running the sent command } else if (0 == memcmp(arygon_error_unknown_mode, abtRxBuf, sizeof(abtRxBuf))) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Bad frame format."); // We have already read 6 bytes and arygon_error_unknown_mode is 10 bytes long // so we have to read 4 remaining bytes to be synchronized at the next receiving pass. pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 4, 0, timeout); return pnd->last_error; } else { return pnd->last_error; } return NFC_SUCCESS; }
int rc522_uart_write(struct nfc_device * pnd, uint8_t reg, const uint8_t * data, size_t size) { uint8_t cmd = rc522_uart_pack(reg, WRITE); int ret; while (size > 0) { // First: send write request if ((ret = uart_send(DRIVER_DATA(pnd)->port, &cmd, 1, IO_TIMEOUT)) < 0) { goto error; } // Second: wait for a reply uint8_t reply; if ((ret = uart_receive(DRIVER_DATA(pnd)->port, &reply, 1, NULL, IO_TIMEOUT)) < 0) { return ret; } // Third: compare sent and received. They must match. if (cmd != reply) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "rc522_uart_write ack does not match (sent %02X, received %02X)", cmd, reply); ret = NFC_ECHIP; goto error; } // Fourth: send register data if ((ret = uart_send(DRIVER_DATA(pnd)->port, data, 1, IO_TIMEOUT)) < 0) { goto error; } size--; data++; } return NFC_SUCCESS; error: uart_flush_input(DRIVER_DATA(pnd)->port, true); return ret; }
int rc522_uart_read(struct nfc_device * pnd, uint8_t reg, uint8_t * data, size_t size) { uint8_t cmd = rc522_uart_pack(reg, READ); int ret; while (size > 0) { if ((ret = uart_send(DRIVER_DATA(pnd)->port, &cmd, 1, IO_TIMEOUT)) < 0) { goto error; } if ((ret = uart_receive(DRIVER_DATA(pnd)->port, data, 1, NULL, IO_TIMEOUT)) < 0) { goto error; } size--; data++; } return NFC_SUCCESS; error: uart_flush_input(DRIVER_DATA(pnd)->port, true); return ret; }
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 int pn532_uart_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, int timeout) { uint8_t abtRxBuf[5]; size_t len; void *abort_p = NULL; #ifndef WIN32 abort_p = &(DRIVER_DATA(pnd)->iAbortFds[1]); #else abort_p = (void *) & (DRIVER_DATA(pnd)->abort_flag); #endif pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 5, abort_p, timeout); if (abort_p && (NFC_EOPABORTED == pnd->last_error)) { return pn532_uart_ack(pnd); } if (pnd->last_error < 0) { goto error; } const uint8_t pn53x_preamble[3] = { 0x00, 0x00, 0xff }; if (0 != (memcmp(abtRxBuf, pn53x_preamble, 3))) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch"); pnd->last_error = NFC_EIO; goto error; } if ((0x01 == abtRxBuf[3]) && (0xff == abtRxBuf[4])) { // Error frame uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Application level error detected"); pnd->last_error = NFC_EIO; goto error; } else if ((0xff == abtRxBuf[3]) && (0xff == abtRxBuf[4])) { // Extended frame pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout); if (pnd->last_error != 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)"); goto error; } // (abtRxBuf[0] << 8) + abtRxBuf[1] (LEN) include TFI + (CC+1) len = (abtRxBuf[0] << 8) + abtRxBuf[1] - 2; if (((abtRxBuf[0] + abtRxBuf[1] + abtRxBuf[2]) % 256) != 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Length checksum mismatch"); pnd->last_error = NFC_EIO; goto error; } } else { // Normal frame if (256 != (abtRxBuf[3] + abtRxBuf[4])) { // TODO: Retry log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Length checksum mismatch"); pnd->last_error = NFC_EIO; goto error; } // abtRxBuf[3] (LEN) include TFI + (CC+1) len = abtRxBuf[3] - 2; } if (len > szDataLen) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len); pnd->last_error = NFC_EIO; goto error; } // TFI + PD0 (CC+1) pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout); if (pnd->last_error != 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)"); goto error; } if (abtRxBuf[0] != 0xD5) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "TFI Mismatch"); pnd->last_error = NFC_EIO; goto error; } if (abtRxBuf[1] != CHIP_DATA(pnd)->last_command + 1) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Command Code verification failed"); pnd->last_error = NFC_EIO; goto error; } if (len) { pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, pbtData, len, 0, timeout); if (pnd->last_error != 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)"); goto error; } } pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout); if (pnd->last_error != 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)"); goto error; } uint8_t btDCS = (256 - 0xD5); btDCS -= CHIP_DATA(pnd)->last_command + 1; for (size_t szPos = 0; szPos < len; szPos++) { btDCS -= pbtData[szPos]; } if (btDCS != abtRxBuf[0]) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Data checksum mismatch"); pnd->last_error = NFC_EIO; goto error; } if (0x00 != abtRxBuf[1]) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Frame postamble mismatch"); pnd->last_error = NFC_EIO; goto error; } // The PN53x command is done and we successfully received the reply return len; error: uart_flush_input(DRIVER_DATA(pnd)->port); return pnd->last_error; }
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; }
int rc522_uart_create(const nfc_context * context, const nfc_connstring connstring, const char * portPath, uint32_t userBaudRate, struct nfc_device ** pndPtr) { //int ret; serial_port sp; log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Attempt to open: %s.", portPath); sp = uart_open(portPath); if (sp == INVALID_SERIAL_PORT) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Invalid serial port: %s", portPath); return NFC_EIO; } if (sp == CLAIMED_SERIAL_PORT) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Serial port already claimed: %s", portPath); return NFC_EIO; } // MODIF !!! // We need to flush input to be sure first reply does not comes from older byte transceive /*if ((ret = uart_flush_input(sp, true)) < 0) { return ret; }*/ uart_flush_input(sp, true); nfc_device * pnd = nfc_device_new(context, connstring); if (!pnd) { perror("nfc_device_new"); uart_close(sp); return NFC_ESOFT; } pnd->driver = &rc522_uart_driver; pnd->driver_data = malloc(sizeof(struct rc522_uart_data)); if (!pnd->driver_data) { perror("malloc"); uart_close(sp); nfc_device_free(pnd); return NFC_ESOFT; } DRIVER_DATA(pnd)->port = sp; DRIVER_DATA(pnd)->baudrate = userBaudRate; // Alloc and init chip's data if (rc522_data_new(pnd, &rc522_uart_io)) { perror("rc522_data_new"); uart_close(sp); nfc_device_free(pnd); return NFC_ESOFT; } // Here we'll have to address several posibilities: // - The hard reset trick did the work, and the RC522 is up and listening at 9600 // - The hard reset didn't work, but the RC522 hasn't been used yet and therefore listens at 9600 // - The hard reset didn't work and the RC522 is not using the default, so we'll use the custom provided baud rate // Let's try first with boot baud rate if ( !rc522_uart_test_baudrate(pnd, BOOT_BAUD_RATE) && !rc522_uart_test_baudrate(pnd, userBaudRate) ) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Could not connect with RC522 at %d or %d bps.", BOOT_BAUD_RATE, userBaudRate); rc522_uart_close(pnd); return NFC_EIO; } *pndPtr = pnd; return NFC_SUCCESS; }
static nfc_device * arygon_open(const nfc_context *context, const nfc_connstring connstring) { struct arygon_descriptor ndd; char *speed_s; int connstring_decode_level = connstring_decode(connstring, ARYGON_DRIVER_NAME, NULL, &ndd.port, &speed_s); if (connstring_decode_level == 3) { ndd.speed = 0; if (sscanf(speed_s, "%10"PRIu32, &ndd.speed) != 1) { // speed_s is not a number free(ndd.port); free(speed_s); return NULL; } free(speed_s); } if (connstring_decode_level < 2) { return NULL; } if (connstring_decode_level < 3) { ndd.speed = ARYGON_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 baud.", 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)) { free(ndd.port); return NULL; } // We need to flush input to be sure first reply does not comes from older byte transceive uart_flush_input(sp, true); uart_set_speed(sp, ndd.speed); // We have a connection pnd = nfc_device_new(context, connstring); if (!pnd) { perror("malloc"); free(ndd.port); uart_close(sp); return NULL; } snprintf(pnd->name, sizeof(pnd->name), "%s:%s", ARYGON_DRIVER_NAME, ndd.port); free(ndd.port); pnd->driver_data = malloc(sizeof(struct arygon_data)); if (!pnd->driver_data) { perror("malloc"); uart_close(sp); nfc_device_free(pnd); return NULL; } DRIVER_DATA(pnd)->port = sp; // Alloc and init chip's data if (pn53x_data_new(pnd, &arygon_tama_io) == NULL) { perror("malloc"); uart_close(DRIVER_DATA(pnd)->port); nfc_device_free(pnd); return NULL; } // The PN53x chip opened to ARYGON MCU doesn't seems to be in LowVBat mode CHIP_DATA(pnd)->power_mode = NORMAL; // empirical tuning CHIP_DATA(pnd)->timer_correction = 46; pnd->driver = &arygon_driver; #ifndef WIN32 // pipe-based abort mecanism if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) { uart_close(DRIVER_DATA(pnd)->port); pn53x_data_free(pnd); nfc_device_free(pnd); return NULL; } #else DRIVER_DATA(pnd)->abort_flag = false; #endif // Check communication using "Reset TAMA" command if (arygon_reset_tama(pnd) < 0) { arygon_close_step2(pnd); return NULL; } char arygon_firmware_version[10]; arygon_firmware(pnd, arygon_firmware_version); char *pcName; pcName = strdup(pnd->name); snprintf(pnd->name, sizeof(pnd->name), "%s %s", pcName, arygon_firmware_version); free(pcName); pn53x_init(pnd); return pnd; }
static size_t arygon_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 ARYGON device on serial port: %s at %d baud.", acPort, ARYGON_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, true); uart_set_speed(sp, ARYGON_DEFAULT_SPEED); nfc_connstring connstring; snprintf(connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, ARYGON_DRIVER_NAME, acPort, ARYGON_DEFAULT_SPEED); nfc_device *pnd = nfc_device_new(context, connstring); if (!pnd) { perror("malloc"); uart_close(sp); iDevice = 0; while ((acPort = acPorts[iDevice++])) { free((void *)acPort); } free(acPorts); return 0; } pnd->driver = &arygon_driver; pnd->driver_data = malloc(sizeof(struct arygon_data)); if (!pnd->driver_data) { perror("malloc"); uart_close(sp); nfc_device_free(pnd); iDevice = 0; while ((acPort = acPorts[iDevice++])) { free((void *)acPort); } free(acPorts); return 0; } DRIVER_DATA(pnd)->port = sp; // Alloc and init chip's data if (pn53x_data_new(pnd, &arygon_tama_io) == NULL) { perror("malloc"); uart_close(DRIVER_DATA(pnd)->port); nfc_device_free(pnd); iDevice = 0; while ((acPort = acPorts[iDevice++])) { free((void *)acPort); } free(acPorts); return 0; } #ifndef WIN32 // pipe-based abort mecanism if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) { uart_close(DRIVER_DATA(pnd)->port); pn53x_data_free(pnd); nfc_device_free(pnd); iDevice = 0; while ((acPort = acPorts[iDevice++])) { free((void *)acPort); } free(acPorts); return 0; } #else DRIVER_DATA(pnd)->abort_flag = false; #endif int res = arygon_reset_tama(pnd); uart_close(DRIVER_DATA(pnd)->port); pn53x_data_free(pnd); nfc_device_free(pnd); if (res < 0) { continue; } // ARYGON reader is found 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; }
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; }