Merge branch 'master' into pn532_spi

* master: (43 commits)
  Windows: workaround as libusb is not automatically detected by CMake
  Add usbbus to Makefile.am EXTRA_DIST
  make style
  Add log_posix to Makefile.am
  Split logging internals so that platforms may choose additional or alternate spew mechanisms
  More explicitely ignoring return value as suggested by Ludovic
  Windows: Clean up all compiler warnings and link warnings
  API change
  make style
  pn53x-sam: fix print_nfc_target
  Convert by value passing of nfc_target to pointer for str_nfc_target and nfc_initiator_target_is_present
  Windows: Fix bug when compiling without libusb: skip usbbus.c
  Windows: Fix compilation due to new usbbus file
  Fix bug when compiling without libusb: skip usbbus.c
  Fix scan-build warning: cast increases required alignment from 1 to 4
  Fix cppcheck warning "Obsolete function 'usleep' called"
  Avoid warning about ignoring return value of 'read'
  Fix cppcheck warning "Non reentrant function 'readdir' called"
  conf.h: make it more standard
  uart_posix.c: remove redundant include
  ...
This commit is contained in:
Philippe Teuwen 2013-03-08 23:00:44 +01:00
commit 05b9cde966
53 changed files with 1168 additions and 708 deletions

View file

@ -12,7 +12,11 @@ SET(CHIPS_SOURCES chips/pn53x)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/chips)
# Library's buses
SET(BUSES_SOURCES buses/uart)
IF(LIBUSB_FOUND)
SET(BUSES_SOURCES buses/uart buses/usbbus)
ELSE(LIBUSB_FOUND)
SET(BUSES_SOURCES buses/uart)
ENDIF(LIBUSB_FOUND)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/buses)
INCLUDE(LibnfcDrivers)
@ -42,7 +46,12 @@ SET(LIBRARY_SOURCES nfc nfc-device nfc-emulation nfc-internal conf iso14443-subr
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
IF(LIBNFC_LOG)
LIST(APPEND LIBRARY_SOURCES log-printf)
IF(WIN32)
SET(CMAKE_C_FLAGS "-fgnu89-inline ${CMAKE_C_FLAGS}")
LIST(APPEND LIBRARY_SOURCES log-printf log_win32)
ELSE(WIN32)
LIST(APPEND LIBRARY_SOURCES log-printf log_posix)
ENDIF(WIN32)
ENDIF(LIBNFC_LOG)
ADD_LIBRARY(nfc SHARED ${LIBRARY_SOURCES})

View file

@ -40,10 +40,11 @@ if LIBUSB_ENABLED
endif
if WITH_LOG
libnfc_la_SOURCES += log-printf.c
libnfc_la_SOURCES += log-printf.c log_posix.c
endif
EXTRA_DIST = \
CMakeLists.txt \
log-printf.c
log-printf.c \
log_posix.c \
log_win32.c

View file

@ -1,10 +1,27 @@
# set the include path found by configure
AM_CPPFLAGS = $(all_includes) $(LIBNFC_CFLAGS)
noinst_LTLIBRARIES = libnfcbuses.la
libnfcbuses_la_SOURCES = spi.c spi.h uart.c uart.h usbbus.c usbbus.h
libnfcbuses_la_SOURCES =
libnfcbuses_la_CFLAGS = -I$(top_srcdir)/libnfc
libnfcbuses_la_LIBADD =
EXTRA_DIST = uart_posix.c uart_win32.c spi_posix.c
# SPI_ENABLED
libnfcbuses_la_SOURCES += spi.c spi.h
libnfcbuses_la_CFLAGS +=
libnfcbuses_la_LIBADD +=
EXTRA_DIST = spi_posix.c
# UART_ENABLED
libnfcbuses_la_SOURCES += uart.c uart.h
libnfcbuses_la_CFLAGS +=
libnfcbuses_la_LIBADD +=
EXTRA_DIST = uart_posix.c uart_win32.c
if LIBUSB_ENABLED
libnfcbuses_la_SOURCES += usbbus.c usbbus.h
libnfcbuses_la_CFLAGS += @libusb_CFLAGS@
libnfcbuses_la_LIBADD += @libusb_LIBS@
endif
EXTRA_DIST += usbbus.c usbbus.h

View file

@ -30,7 +30,6 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/types.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
@ -39,6 +38,7 @@
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include "nfc-internal.h"
@ -127,7 +127,7 @@ uart_flush_input(serial_port sp)
}
char *rx = malloc(available_bytes_count);
// There is something available, read the data
res = read(UART_DATA(sp)->fd, rx, available_bytes_count);
(void)read(UART_DATA(sp)->fd, rx, available_bytes_count);
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%d bytes have eatten.", available_bytes_count);
free(rx);
}
@ -337,26 +337,32 @@ uart_list_ports(void)
size_t szRes = 1;
res[0] = NULL;
DIR *pdDir = opendir("/dev");
struct dirent *pdDirEnt;
while ((pdDirEnt = readdir(pdDir)) != NULL) {
DIR *dir;
if ((dir = opendir("/dev")) == NULL) {
perror("opendir error: /dev");
return res;
}
struct dirent entry;
struct dirent *result;
while ((readdir_r(dir, &entry, &result) == 0) && (result != NULL)) {
#if !defined(__APPLE__)
if (!isdigit(pdDirEnt->d_name[strlen(pdDirEnt->d_name) - 1]))
if (!isdigit(entry.d_name[strlen(entry.d_name) - 1]))
continue;
#endif
const char **p = serial_ports_device_radix;
while (*p) {
if (!strncmp(pdDirEnt->d_name, *p, strlen(*p))) {
if (!strncmp(entry.d_name, *p, strlen(*p))) {
char **res2 = realloc(res, (szRes + 1) * sizeof(char *));
if (!res2)
if (!res2) {
perror("malloc");
goto oom;
}
res = res2;
if (!(res[szRes - 1] = malloc(6 + strlen(pdDirEnt->d_name))))
if (!(res[szRes - 1] = malloc(6 + strlen(entry.d_name)))) {
perror("malloc");
goto oom;
sprintf(res[szRes - 1], "/dev/%s", pdDirEnt->d_name);
}
sprintf(res[szRes - 1], "/dev/%s", entry.d_name);
szRes++;
res[szRes - 1] = NULL;
@ -365,7 +371,7 @@ uart_list_ports(void)
}
}
oom:
closedir(pdDir);
closedir(dir);
return res;
}

View file

@ -24,6 +24,7 @@
* @brief Windows UART driver
*/
#include <inttypes.h>
#include "log.h"
#define LOG_GROUP NFC_LOG_GROUP_COM
@ -164,7 +165,7 @@ uart_receive(serial_port sp, uint8_t *pbtRx, const size_t szRx, void *abort_p, i
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to apply new timeout settings.");
return NFC_EIO;
}
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Timeouts are set to %u ms", timeout_ms);
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Timeouts are set to %lu ms", timeout_ms);
// TODO Enhance the reception method
// - According to MSDN, it could be better to implement nfc_abort_command() mecanism using Cancello()
@ -179,7 +180,7 @@ uart_receive(serial_port sp, uint8_t *pbtRx, const size_t szRx, void *abort_p, i
if (!res) {
DWORD err = GetLastError();
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "ReadFile error: %u", err);
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "ReadFile error: %lu", err);
return NFC_EIO;
} else if (dwBytesReceived == 0) {
return NFC_ETIMEOUT;

View file

@ -28,6 +28,7 @@
# include "config.h"
#endif // HAVE_CONFIG_H
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -317,9 +318,9 @@ pn53x_set_parameters(struct nfc_device *pnd, const uint8_t ui8Parameter, const b
int
pn53x_set_tx_bits(struct nfc_device *pnd, const uint8_t ui8Bits)
{
int res = 0;
// Test if we need to update the transmission bits register setting
if (CHIP_DATA(pnd)->ui8TxBits != ui8Bits) {
int res = 0;
// Set the amount of transmission bits in the PN53X chip register
if ((res = pn53x_write_register(pnd, PN53X_REG_CIU_BitFraming, SYMBOL_TX_LAST_BITS, ui8Bits)) < 0)
return res;
@ -613,10 +614,10 @@ pn53x_WriteRegister(struct nfc_device *pnd, const uint16_t ui16RegisterAddress,
int
pn53x_write_register(struct nfc_device *pnd, const uint16_t ui16RegisterAddress, const uint8_t ui8SymbolMask, const uint8_t ui8Value)
{
int res = 0;
if ((ui16RegisterAddress < PN53X_CACHE_REGISTER_MIN_ADDRESS) || (ui16RegisterAddress > PN53X_CACHE_REGISTER_MAX_ADDRESS)) {
// Direct write
if (ui8SymbolMask != 0xff) {
int res = 0;
uint8_t ui8CurrentValue;
if ((res = pn53x_read_register(pnd, ui16RegisterAddress, &ui8CurrentValue)) < 0)
return res;
@ -1354,7 +1355,7 @@ pn53x_initiator_transceive_bytes(struct nfc_device *pnd, const uint8_t *pbtTx, c
const size_t szRxLen = (size_t)res - 1;
if (pbtRx != NULL) {
if (szRxLen > szRx) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Buffer size is too short: %zuo available(s), %zuo needed", szRx, szRxLen);
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Buffer size is too short: %" PRIuPTR " available(s), %" PRIuPTR " needed", szRx, szRxLen);
return NFC_EOVFLOW;
}
// Copy the received bytes
@ -1629,7 +1630,7 @@ pn53x_initiator_transceive_bytes_timed(struct nfc_device *pnd, const uint8_t *pb
}
if (pbtRx != NULL) {
if ((szRxLen + sz) > szRx) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Buffer size is too short: %zuo available(s), %zuo needed", szRx, szRxLen + sz);
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Buffer size is too short: %" PRIuPTR " available(s), %" PRIuPTR " needed", szRx, szRxLen + sz);
return NFC_EOVFLOW;
}
// Copy the received bytes
@ -1668,10 +1669,10 @@ pn53x_initiator_deselect_target(struct nfc_device *pnd)
}
int
pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target nt)
pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt)
{
// Check if the argument target nt is equals to current saved target
if (!pn53x_current_target_is(pnd, &nt)) {
if (!pn53x_current_target_is(pnd, pnt)) {
return NFC_ETGRELEASED;
}
@ -2711,7 +2712,7 @@ pn53x_build_frame(uint8_t *pbtFrame, size_t *pszFrame, const uint8_t *pbtData, c
(*pszFrame) = szData + PN53x_EXTENDED_FRAME__OVERHEAD;
} else {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "We can't send more than %d bytes in a raw (requested: %zd)", PN53x_EXTENDED_FRAME__DATA_MAX_LEN, szData);
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "We can't send more than %d bytes in a raw (requested: %" PRIdPTR ")", PN53x_EXTENDED_FRAME__DATA_MAX_LEN, szData);
return NFC_ECHIP;
}
return NFC_SUCCESS;

View file

@ -337,7 +337,7 @@ int pn53x_initiator_transceive_bits_timed(struct nfc_device *pnd, const uint8
int pn53x_initiator_transceive_bytes_timed(struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx,
uint8_t *pbtRx, const size_t szRx, uint32_t *cycles);
int pn53x_initiator_deselect_target(struct nfc_device *pnd);
int pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target nt);
int pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt);
// NFC device as Target functions
int pn53x_target_init(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRxLen, int timeout);

View file

@ -1,3 +1,4 @@
/*-
* Copyright (C) 2012, 2013 Romuald Conty
*
@ -15,12 +16,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "conf.h"
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif // HAVE_CONFIG_H
#include "conf.h"
#ifdef CONFFILES
#include <stdio.h>
#include <stdlib.h>
@ -163,7 +164,10 @@ conf_devices_load(const char *dirname, nfc_context *context)
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Unable to open directory: %s", dirname);
} else {
struct dirent *de;
while ((de = readdir(d))) {
struct dirent entry;
struct dirent *result;
while ((readdir_r(d, &entry, &result) == 0) && (result != NULL)) {
de = &entry;
if (de->d_name[0] != '.') {
const size_t filename_len = strlen(de->d_name);
const size_t extension_len = strlen(".conf");

View file

@ -14,7 +14,12 @@
* 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/>
*/
#include "nfc-internal.h"
#ifndef __NFC_CONF_H__
#define __NFC_CONF_H__
#include <nfc/nfc-types.h>
void conf_load(nfc_context *context);
#endif // __NFC_CONF_H__

View file

@ -227,9 +227,6 @@ acr122_pcsc_connstring_decode(const nfc_connstring connstring, struct acr122_pcs
free(cs);
return 2;
free(cs);
return 3;
}
static nfc_device *
@ -258,7 +255,7 @@ acr122_pcsc_open(const nfc_context *context, const nfc_connstring connstring)
if (strlen(ndd.pcsc_device_name) < 5) { // We can assume it's a reader ID as pcsc_name always ends with "NN NN"
// Device was not specified, only ID, retrieve it
size_t index;
if (sscanf(ndd.pcsc_device_name, "%lu", &index) != 1)
if (sscanf(ndd.pcsc_device_name, "%4" SCNuPTR, &index) != 1)
return NULL;
nfc_connstring *ncs = malloc(sizeof(nfc_connstring) * (index + 1));
if (!ncs) {
@ -271,6 +268,7 @@ acr122_pcsc_open(const nfc_context *context, const nfc_connstring connstring)
return NULL;
}
strncpy(fullconnstring, ncs[index], sizeof(nfc_connstring));
fullconnstring[sizeof(nfc_connstring) - 1] = '\0';
free(ncs);
connstring_decode_level = acr122_pcsc_connstring_decode(fullconnstring, &ndd);
if (connstring_decode_level < 2) {
@ -280,6 +278,10 @@ acr122_pcsc_open(const nfc_context *context, const nfc_connstring connstring)
char *pcFirmware;
nfc_device *pnd = nfc_device_new(context, fullconnstring);
if (!pnd) {
perror("malloc");
goto error;
}
pnd->driver_data = malloc(sizeof(struct acr122_pcsc_data));
if (!pnd->driver_data) {
perror("malloc");

View file

@ -372,7 +372,9 @@ acr122_usb_connstring_decode(const nfc_connstring connstring, struct acr122_usb_
driver_name[0] = '\0';
int res = sscanf(connstring, "%[^:]:%[^:]:%[^:]", driver_name, dirname, filename);
char format[32];
snprintf(format, sizeof(format), "%%%i[^:]:%%%i[^:]:%%%i[^:]", n - 1, n - 1, n - 1);
int res = sscanf(connstring, format, driver_name, dirname, filename);
if (!res || ((0 != strcmp(driver_name, ACR122_USB_DRIVER_NAME)) && (0 != strcmp(driver_name, "usb")))) {
// Driver name does not match.
@ -408,6 +410,7 @@ acr122_usb_get_usb_device_name(struct usb_device *dev, usb_dev_handle *udev, cha
if ((acr122_usb_supported_devices[n].vendor_id == dev->descriptor.idVendor) &&
(acr122_usb_supported_devices[n].product_id == dev->descriptor.idProduct)) {
strncpy(buffer, acr122_usb_supported_devices[n].name, len);
buffer[len - 1] = '\0';
return true;
}
}
@ -475,6 +478,10 @@ acr122_usb_open(const nfc_context *context, const nfc_connstring connstring)
data.model = acr122_usb_get_device_model(dev->descriptor.idVendor, dev->descriptor.idProduct);
// Allocate memory for the device info and specification, fill it and return the info
pnd = nfc_device_new(context, connstring);
if (!pnd) {
perror("malloc");
goto error;
}
acr122_usb_get_usb_device_name(dev, data.pudh, pnd->name, sizeof(pnd->name));
pnd->driver_data = malloc(sizeof(struct acr122_usb_data));
@ -547,13 +554,7 @@ uint32_t htole32(uint32_t u32);
uint32_t
htole32(uint32_t u32)
{
uint8_t u8[4];
for (int i = 0; i < 4; i++) {
u8[i] = (u32 & 0xff);
u32 >>= 8;
}
uint32_t *pu32 = (uint32_t *)u8;
return *pu32;
return (((u32 & 0xff) << 24) + ((u32 & 0xff00) << 8) + ((u32 & 0xff0000) >> 8) + (u32 >> 24));
}
static int
@ -717,7 +718,7 @@ read:
len -= 4; // We skip 2 bytes for PN532 direction byte (D5) and command byte (CMD+1), then 2 bytes for APDU status (90 00).
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);
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %" PRIuPTR ", len: %" PRIuPTR ")", szDataLen, len);
pnd->last_error = NFC_EOVFLOW;
return pnd->last_error;
}

View file

@ -438,7 +438,7 @@ acr122s_connstring_decode(const nfc_connstring connstring, struct acr122s_descri
return 2;
}
unsigned long speed;
if (sscanf(speed_s, "%lu", &speed) != 1) {
if (sscanf(speed_s, "%10lu", &speed) != 1) {
// speed_s is not a number
free(cs);
return 2;
@ -470,6 +470,10 @@ acr122s_scan(const nfc_context *context, nfc_connstring connstrings[], const siz
nfc_connstring connstring;
snprintf(connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, ACR122S_DRIVER_NAME, acPort, ACR122S_DEFAULT_SPEED);
nfc_device *pnd = nfc_device_new(context, connstring);
if (!pnd) {
perror("malloc");
return -1;
}
pnd->driver = &acr122s_driver;
pnd->driver_data = malloc(sizeof(struct acr122s_data));
@ -574,6 +578,10 @@ acr122s_open(const nfc_context *context, const nfc_connstring connstring)
uart_set_speed(sp, ndd.speed);
pnd = nfc_device_new(context, connstring);
if (!pnd) {
perror("malloc");
return NULL;
}
pnd->driver = &acr122s_driver;
strcpy(pnd->name, ACR122S_DRIVER_NAME);
@ -676,7 +684,7 @@ acr122s_receive(nfc_device *pnd, uint8_t *buf, size_t buf_len, int timeout)
size_t data_len = FRAME_SIZE(tmp) - 17;
if (data_len > buf_len) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Receive buffer too small. (buf_len: %zu, data_len: %zu)", buf_len, data_len);
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Receive buffer too small. (buf_len: %" PRIuPTR ", data_len: %" PRIuPTR ")", buf_len, data_len);
pnd->last_error = NFC_EIO;
return pnd->last_error;
}

View file

@ -114,6 +114,10 @@ arygon_scan(const nfc_context *context, nfc_connstring connstrings[], const size
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");
return 0;
}
pnd->driver = &arygon_driver;
pnd->driver_data = malloc(sizeof(struct arygon_data));
@ -203,7 +207,7 @@ arygon_connstring_decode(const nfc_connstring connstring, struct arygon_descript
return 2;
}
unsigned long speed;
if (sscanf(speed_s, "%lu", &speed) != 1) {
if (sscanf(speed_s, "%10lu", &speed) != 1) {
// speed_s is not a number
free(cs);
return 2;
@ -263,6 +267,10 @@ arygon_open(const nfc_context *context, const nfc_connstring connstring)
// We have a connection
pnd = nfc_device_new(context, connstring);
if (!pnd) {
perror("malloc");
return NULL;
}
snprintf(pnd->name, sizeof(pnd->name), "%s:%s", ARYGON_DRIVER_NAME, ndd.port);
pnd->driver_data = malloc(sizeof(struct arygon_data));
@ -322,7 +330,7 @@ arygon_tama_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, i
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: %zd)", PN53x_NORMAL_FRAME__DATA_MAX_LEN, szData);
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;
}
@ -430,7 +438,7 @@ arygon_tama_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, i
}
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);
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %" PRIuPTR ", len: %" PRIuPTR ")", szDataLen, len);
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
@ -511,7 +519,9 @@ arygon_firmware(nfc_device *pnd, char *str)
if (0 == memcmp(abtRx, arygon_error_none, 6)) {
uint8_t *p = abtRx + 6;
unsigned int szData;
sscanf((const char *)p, "%02x%s", &szData, p);
sscanf((const char *)p, "%02x%9s", &szData, p);
if (szData > 9)
szData = 9;
memcpy(str, p, szData);
*(str + szData) = '\0';
}

View file

@ -88,6 +88,10 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const
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);
if (!pnd) {
perror("malloc");
return 0;
}
pnd->driver = &pn532_uart_driver;
pnd->driver_data = malloc(sizeof(struct pn532_uart_data));
if (!pnd->driver_data) {
@ -180,7 +184,7 @@ pn532_connstring_decode(const nfc_connstring connstring, struct pn532_uart_descr
return 2;
}
unsigned long speed;
if (sscanf(speed_s, "%lu", &speed) != 1) {
if (sscanf(speed_s, "%10lu", &speed) != 1) {
// speed_s is not a number
free(cs);
return 2;
@ -240,6 +244,10 @@ pn532_uart_open(const nfc_context *context, const nfc_connstring connstring)
// We have a connection
pnd = nfc_device_new(context, connstring);
if (!pnd) {
perror("malloc");
return NULL;
}
snprintf(pnd->name, sizeof(pnd->name), "%s:%s", PN532_UART_DRIVER_NAME, ndd.port);
pnd->driver_data = malloc(sizeof(struct pn532_uart_data));
@ -416,7 +424,7 @@ pn532_uart_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, in
}
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);
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %" PRIuPTR ", len: %" PRIuPTR ")", szDataLen, len);
pnd->last_error = NFC_EIO;
goto error;
}
@ -481,8 +489,8 @@ error:
int
pn532_uart_ack(nfc_device *pnd)
{
int res = 0;
if (POWERDOWN == CHIP_DATA(pnd)->power_mode) {
int res = 0;
if ((res = pn532_uart_wakeup(pnd)) < 0) {
return res;
}

View file

@ -257,7 +257,9 @@ pn53x_usb_connstring_decode(const nfc_connstring connstring, struct pn53x_usb_de
driver_name[0] = '\0';
int res = sscanf(connstring, "%[^:]:%[^:]:%[^:]", driver_name, dirname, filename);
char format[32];
snprintf(format, sizeof(format), "%%%i[^:]:%%%i[^:]:%%%i[^:]", n - 1, n - 1, n - 1);
int res = sscanf(connstring, format, driver_name, dirname, filename);
if (!res || ((0 != strcmp(driver_name, PN53X_USB_DRIVER_NAME)) && (0 != strcmp(driver_name, "usb")))) {
// Driver name does not match.
@ -293,6 +295,7 @@ pn53x_usb_get_usb_device_name(struct usb_device *dev, usb_dev_handle *udev, char
if ((pn53x_usb_supported_devices[n].vendor_id == dev->descriptor.idVendor) &&
(pn53x_usb_supported_devices[n].product_id == dev->descriptor.idProduct)) {
strncpy(buffer, pn53x_usb_supported_devices[n].name, len);
buffer[len - 1] = '\0';
return true;
}
}
@ -360,6 +363,10 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring)
data.model = pn53x_usb_get_device_model(dev->descriptor.idVendor, dev->descriptor.idProduct);
// Allocate memory for the device info and specification, fill it and return the info
pnd = nfc_device_new(context, connstring);
if (!pnd) {
perror("malloc");
goto error;
}
pn53x_usb_get_usb_device_name(dev, data.pudh, pnd->name, sizeof(pnd->name));
pnd->driver_data = malloc(sizeof(struct pn53x_usb_data));
@ -581,7 +588,7 @@ read:
}
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);
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %" PRIuPTR ", len: %" PRIuPTR ")", szDataLen, len);
pnd->last_error = NFC_EIO;
return pnd->last_error;
}

View file

@ -1,6 +1,7 @@
/*-
* Copyright (C) 2011 Romain Tartière
* Copyright (C) 2011, 2012 Romuald Conty
* Copyright (C) 2013 Alex Lian
*
* 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
@ -31,6 +32,12 @@
#error "No logging defined, but log-printf.c still compiled."
#else // LOG
// Internal methods so different platforms can route the logging
// Offering both forms of the variadic function
// These are implemented in the log_<platform> specific file
void log_put_internal(const char *format, ...);
void log_vput_internal(const char *format, va_list args);
void
log_init(const nfc_context *context)
{
@ -71,11 +78,12 @@ log_put(const uint8_t group, const char *category, const uint8_t priority, const
if (log_level) { // If log is not disabled by log_level=none
if (((log_level & 0x00000003) >= priority) || // Global log level
(((log_level >> (group * 2)) & 0x00000003) >= priority)) { // Group log level
va_list va;
va_start(va, format);
fprintf(stderr, "%s\t%s\t", log_priority_to_str(priority), category);
vfprintf(stderr, format, va);
fprintf(stderr, "\n");
log_put_internal("%s\t%s\t", log_priority_to_str(priority), category);
log_vput_internal(format, va);
log_put_internal("\n");
va_end(va);
}
}

41
libnfc/log_posix.c Normal file
View file

@ -0,0 +1,41 @@
/*-
* Copyright (C) 2011 Romain Tartière
* Copyright (C) 2011, 2012 Romuald Conty
* Copyright (C) 2013 Alex Lian
*
* 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.
*
* 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/>
*/
#include "log.h"
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdarg.h>
void
log_vput_internal(const char *format, va_list args)
{
vfprintf(stderr, format, args);
}
void
log_put_internal(const char *format, ...)
{
va_list va;
va_start(va, format);
vfprintf(stderr, format, va);
va_end(va);
}

56
libnfc/log_win32.c Normal file
View file

@ -0,0 +1,56 @@
/*-
* Copyright (C) 2011 Romain Tartière
* Copyright (C) 2011, 2012 Romuald Conty
* Copyright (C) 2013 Alex Lian
*
* 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.
*
* 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/>
*/
#include "log.h"
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdarg.h>
#include <strsafe.h>
void
log_output_debug(const char *format, va_list args)
{
char buffer[1024];
HRESULT hr = StringCbVPrintf(buffer, sizeof(buffer), format, args);
// Spew what we got, even if the buffer is not sized large enough
if ((STRSAFE_E_INSUFFICIENT_BUFFER == hr) || (S_OK == hr))
OutputDebugString(buffer);
}
void
log_vput_internal(const char *format, va_list args)
{
vfprintf(stderr, format, args);
// Additional windows output to the debug window for debugging purposes
log_output_debug(format, args);
}
void
log_put_internal(const char *format, ...)
{
va_list va;
va_start(va, format);
vfprintf(stderr, format, va);
// Additional windows output to the debug window for debugging purposes
log_output_debug(format, va);
va_end(va);
}

View file

@ -38,7 +38,7 @@ nfc_device_new(const nfc_context *context, const nfc_connstring connstring)
nfc_device *res = malloc(sizeof(*res));
if (!res) {
err(EXIT_FAILURE, "nfc_device_new: malloc");
return NULL;
}
// Store associated context

View file

@ -68,7 +68,7 @@ nfc_context_new(void)
nfc_context *res = malloc(sizeof(*res));
if (!res) {
err(EXIT_FAILURE, "nfc_context_new: malloc");
return NULL;
}
// Set default context values

View file

@ -131,7 +131,7 @@ struct nfc_driver {
int (*initiator_transceive_bits)(struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtRx, uint8_t *pbtRxPar);
int (*initiator_transceive_bytes_timed)(struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, const size_t szRx, uint32_t *cycles);
int (*initiator_transceive_bits_timed)(struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtRx, uint8_t *pbtRxPar, uint32_t *cycles);
int (*initiator_target_is_present)(struct nfc_device *pnd, const nfc_target nt);
int (*initiator_target_is_present)(struct nfc_device *pnd, const nfc_target *pnt);
int (*target_init)(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRx, int timeout);
int (*target_send_bytes)(struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, int timeout);

View file

@ -179,7 +179,10 @@ void
nfc_init(nfc_context **context)
{
*context = nfc_context_new();
if (!*context) {
perror("malloc");
return;
}
if (!nfc_drivers)
nfc_drivers_init();
}
@ -230,6 +233,7 @@ nfc_open(nfc_context *context, const nfc_connstring connstring)
}
} else {
strncpy(ncs, connstring, sizeof(nfc_connstring));
ncs[sizeof(nfc_connstring) - 1] = '\0';
}
// Search through the device list for an available device
@ -357,9 +361,8 @@ nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_
const struct nfc_driver_list *pndl = nfc_drivers;
while (pndl) {
const struct nfc_driver *ndr = pndl->driver;
size_t _device_found = 0;
if ((ndr->scan_type == NOT_INTRUSIVE) || ((context->allow_intrusive_scan) && (ndr->scan_type == INTRUSIVE))) {
_device_found = ndr->scan(context, connstrings + (device_found), connstrings_len - (device_found));
size_t _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);
if (_device_found > 0) {
device_found += _device_found;
@ -825,9 +828,9 @@ nfc_initiator_transceive_bytes_timed(nfc_device *pnd,
* @warning To run the test, one or more commands will be sent to target
*/
int
nfc_initiator_target_is_present(nfc_device *pnd, const nfc_target nt)
nfc_initiator_target_is_present(nfc_device *pnd, const nfc_target *pnt)
{
HAL(initiator_target_is_present, pnd, nt);
HAL(initiator_target_is_present, pnd, pnt);
}
/** @ingroup initiator
@ -1291,12 +1294,12 @@ str_nfc_modulation_type(const nfc_modulation_type nmt)
* @warning *buf must be freed using nfc_free()
*/
int
str_nfc_target(char **buf, const nfc_target nt, bool verbose)
str_nfc_target(char **buf, const nfc_target *pnt, bool verbose)
{
*buf = malloc(4096);
if (! *buf)
return NFC_ESOFT;
(*buf)[0] = '\0';
sprint_nfc_target(*buf, nt, verbose);
snprint_nfc_target(*buf, 4096, pnt, verbose);
return strlen(*buf);
}

View file

@ -23,6 +23,7 @@
* @file target-subr.c
* @brief Target-related subroutines. (ie. determine target type, print target, etc.)
*/
#include <inttypes.h>
#include <nfc/nfc.h>
#include "target-subr.h"
@ -117,15 +118,14 @@ struct card_sak const_cs[] = {
};
int
sprint_hex(char *dst, const uint8_t *pbtData, const size_t szBytes)
snprint_hex(char *dst, size_t size, const uint8_t *pbtData, const size_t szBytes)
{
size_t szPos;
int res = 0;
size_t res = 0;
for (szPos = 0; szPos < szBytes; szPos++) {
res += sprintf(dst + res, "%02x ", pbtData[szPos]);
res += snprintf(dst + res, size - res, "%02x ", pbtData[szPos]);
}
res += sprintf(dst + res, "\n");
res += snprintf(dst + res, size - res, "\n");
return res;
}
@ -134,282 +134,283 @@ sprint_hex(char *dst, const uint8_t *pbtData, const size_t szBytes)
#define SAK_ISO18092_COMPLIANT 0x40
void
sprint_nfc_iso14443a_info(char *dst, const nfc_iso14443a_info nai, bool verbose)
snprint_nfc_iso14443a_info(char *dst, size_t size, const nfc_iso14443a_info *pnai, bool verbose)
{
dst += sprintf(dst, " ATQA (SENS_RES): ");
dst += sprint_hex(dst, nai.abtAtqa, 2);
int off = 0;
off += snprintf(dst + off, size - off, " ATQA (SENS_RES): ");
off += snprint_hex(dst + off, size - off, pnai->abtAtqa, 2);
if (verbose) {
dst += sprintf(dst, "* UID size: ");
switch ((nai.abtAtqa[1] & 0xc0) >> 6) {
off += snprintf(dst + off, size - off, "* UID size: ");
switch ((pnai->abtAtqa[1] & 0xc0) >> 6) {
case 0:
dst += sprintf(dst, "single\n");
off += snprintf(dst + off, size - off, "single\n");
break;
case 1:
dst += sprintf(dst, "double\n");
off += snprintf(dst + off, size - off, "double\n");
break;
case 2:
dst += sprintf(dst, "triple\n");
off += snprintf(dst + off, size - off, "triple\n");
break;
case 3:
dst += sprintf(dst, "RFU\n");
off += snprintf(dst + off, size - off, "RFU\n");
break;
}
dst += sprintf(dst, "* bit frame anticollision ");
switch (nai.abtAtqa[1] & 0x1f) {
off += snprintf(dst + off, size - off, "* bit frame anticollision ");
switch (pnai->abtAtqa[1] & 0x1f) {
case 0x01:
case 0x02:
case 0x04:
case 0x08:
case 0x10:
dst += sprintf(dst, "supported\n");
off += snprintf(dst + off, size - off, "supported\n");
break;
default:
dst += sprintf(dst, "not supported\n");
off += snprintf(dst + off, size - off, "not supported\n");
break;
}
}
dst += sprintf(dst, " UID (NFCID%c): ", (nai.abtUid[0] == 0x08 ? '3' : '1'));
dst += sprint_hex(dst, nai.abtUid, nai.szUidLen);
off += snprintf(dst + off, size - off, " UID (NFCID%c): ", (pnai->abtUid[0] == 0x08 ? '3' : '1'));
off += snprint_hex(dst + off, size - off, pnai->abtUid, pnai->szUidLen);
if (verbose) {
if (nai.abtUid[0] == 0x08) {
dst += sprintf(dst, "* Random UID\n");
if (pnai->abtUid[0] == 0x08) {
off += snprintf(dst + off, size - off, "* Random UID\n");
}
}
dst += sprintf(dst, " SAK (SEL_RES): ");
dst += sprint_hex(dst, &nai.btSak, 1);
off += snprintf(dst + off, size - off, " SAK (SEL_RES): ");
off += snprint_hex(dst + off, size - off, &pnai->btSak, 1);
if (verbose) {
if (nai.btSak & SAK_UID_NOT_COMPLETE) {
dst += sprintf(dst, "* Warning! Cascade bit set: UID not complete\n");
if (pnai->btSak & SAK_UID_NOT_COMPLETE) {
off += snprintf(dst + off, size - off, "* Warning! Cascade bit set: UID not complete\n");
}
if (nai.btSak & SAK_ISO14443_4_COMPLIANT) {
dst += sprintf(dst, "* Compliant with ISO/IEC 14443-4\n");
if (pnai->btSak & SAK_ISO14443_4_COMPLIANT) {
off += snprintf(dst + off, size - off, "* Compliant with ISO/IEC 14443-4\n");
} else {
dst += sprintf(dst, "* Not compliant with ISO/IEC 14443-4\n");
off += snprintf(dst + off, size - off, "* Not compliant with ISO/IEC 14443-4\n");
}
if (nai.btSak & SAK_ISO18092_COMPLIANT) {
dst += sprintf(dst, "* Compliant with ISO/IEC 18092\n");
if (pnai->btSak & SAK_ISO18092_COMPLIANT) {
off += snprintf(dst + off, size - off, "* Compliant with ISO/IEC 18092\n");
} else {
dst += sprintf(dst, "* Not compliant with ISO/IEC 18092\n");
off += snprintf(dst + off, size - off, "* Not compliant with ISO/IEC 18092\n");
}
}
if (nai.szAtsLen) {
dst += sprintf(dst, " ATS: ");
dst += sprint_hex(dst, nai.abtAts, nai.szAtsLen);
if (pnai->szAtsLen) {
off += snprintf(dst + off, size - off, " ATS: ");
off += snprint_hex(dst + off, size - off, pnai->abtAts, pnai->szAtsLen);
}
if (nai.szAtsLen && verbose) {
if (pnai->szAtsLen && verbose) {
// Decode ATS according to ISO/IEC 14443-4 (5.2 Answer to select)
const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
dst += sprintf(dst, "* Max Frame Size accepted by PICC: %d bytes\n", iMaxFrameSizes[nai.abtAts[0] & 0x0F]);
off += snprintf(dst + off, size - off, "* Max Frame Size accepted by PICC: %d bytes\n", iMaxFrameSizes[pnai->abtAts[0] & 0x0F]);
size_t offset = 1;
if (nai.abtAts[0] & 0x10) { // TA(1) present
uint8_t TA = nai.abtAts[offset];
if (pnai->abtAts[0] & 0x10) { // TA(1) present
uint8_t TA = pnai->abtAts[offset];
offset++;
dst += sprintf(dst, "* Bit Rate Capability:\n");
off += snprintf(dst + off, size - off, "* Bit Rate Capability:\n");
if (TA == 0) {
dst += sprintf(dst, " * PICC supports only 106 kbits/s in both directions\n");
off += snprintf(dst + off, size - off, " * PICC supports only 106 kbits/s in both directions\n");
}
if (TA & 1 << 7) {
dst += sprintf(dst, " * Same bitrate in both directions mandatory\n");
off += snprintf(dst + off, size - off, " * Same bitrate in both directions mandatory\n");
}
if (TA & 1 << 4) {
dst += sprintf(dst, " * PICC to PCD, DS=2, bitrate 212 kbits/s supported\n");
off += snprintf(dst + off, size - off, " * PICC to PCD, DS=2, bitrate 212 kbits/s supported\n");
}
if (TA & 1 << 5) {
dst += sprintf(dst, " * PICC to PCD, DS=4, bitrate 424 kbits/s supported\n");
off += snprintf(dst + off, size - off, " * PICC to PCD, DS=4, bitrate 424 kbits/s supported\n");
}
if (TA & 1 << 6) {
dst += sprintf(dst, " * PICC to PCD, DS=8, bitrate 847 kbits/s supported\n");
off += snprintf(dst + off, size - off, " * PICC to PCD, DS=8, bitrate 847 kbits/s supported\n");
}
if (TA & 1 << 0) {
dst += sprintf(dst, " * PCD to PICC, DR=2, bitrate 212 kbits/s supported\n");
off += snprintf(dst + off, size - off, " * PCD to PICC, DR=2, bitrate 212 kbits/s supported\n");
}
if (TA & 1 << 1) {
dst += sprintf(dst, " * PCD to PICC, DR=4, bitrate 424 kbits/s supported\n");
off += snprintf(dst + off, size - off, " * PCD to PICC, DR=4, bitrate 424 kbits/s supported\n");
}
if (TA & 1 << 2) {
dst += sprintf(dst, " * PCD to PICC, DR=8, bitrate 847 kbits/s supported\n");
off += snprintf(dst + off, size - off, " * PCD to PICC, DR=8, bitrate 847 kbits/s supported\n");
}
if (TA & 1 << 3) {
dst += sprintf(dst, " * ERROR unknown value\n");
off += snprintf(dst + off, size - off, " * ERROR unknown value\n");
}
}
if (nai.abtAts[0] & 0x20) { // TB(1) present
uint8_t TB = nai.abtAts[offset];
if (pnai->abtAts[0] & 0x20) { // TB(1) present
uint8_t TB = pnai->abtAts[offset];
offset++;
dst += sprintf(dst, "* Frame Waiting Time: %.4g ms\n", 256.0 * 16.0 * (1 << ((TB & 0xf0) >> 4)) / 13560.0);
off += snprintf(dst + off, size - off, "* Frame Waiting Time: %.4g ms\n", 256.0 * 16.0 * (1 << ((TB & 0xf0) >> 4)) / 13560.0);
if ((TB & 0x0f) == 0) {
dst += sprintf(dst, "* No Start-up Frame Guard Time required\n");
off += snprintf(dst + off, size - off, "* No Start-up Frame Guard Time required\n");
} else {
dst += sprintf(dst, "* Start-up Frame Guard Time: %.4g ms\n", 256.0 * 16.0 * (1 << (TB & 0x0f)) / 13560.0);
off += snprintf(dst + off, size - off, "* Start-up Frame Guard Time: %.4g ms\n", 256.0 * 16.0 * (1 << (TB & 0x0f)) / 13560.0);
}
}
if (nai.abtAts[0] & 0x40) { // TC(1) present
uint8_t TC = nai.abtAts[offset];
if (pnai->abtAts[0] & 0x40) { // TC(1) present
uint8_t TC = pnai->abtAts[offset];
offset++;
if (TC & 0x1) {
dst += sprintf(dst, "* Node ADdress supported\n");
off += snprintf(dst + off, size - off, "* Node Address supported\n");
} else {
dst += sprintf(dst, "* Node ADdress not supported\n");
off += snprintf(dst + off, size - off, "* Node Address not supported\n");
}
if (TC & 0x2) {
dst += sprintf(dst, "* Card IDentifier supported\n");
off += snprintf(dst + off, size - off, "* Card IDentifier supported\n");
} else {
dst += sprintf(dst, "* Card IDentifier not supported\n");
off += snprintf(dst + off, size - off, "* Card IDentifier not supported\n");
}
}
if (nai.szAtsLen > offset) {
dst += sprintf(dst, "* Historical bytes Tk: ");
dst += sprint_hex(dst, nai.abtAts + offset, (nai.szAtsLen - offset));
uint8_t CIB = nai.abtAts[offset];
if (pnai->szAtsLen > offset) {
off += snprintf(dst + off, size - off, "* Historical bytes Tk: ");
off += snprint_hex(dst + off, size - off, pnai->abtAts + offset, (pnai->szAtsLen - offset));
uint8_t CIB = pnai->abtAts[offset];
offset++;
if (CIB != 0x00 && CIB != 0x10 && (CIB & 0xf0) != 0x80) {
dst += sprintf(dst, " * Proprietary format\n");
off += snprintf(dst + off, size - off, " * Proprietary format\n");
if (CIB == 0xc1) {
dst += sprintf(dst, " * Tag byte: Mifare or virtual cards of various types\n");
uint8_t L = nai.abtAts[offset];
off += snprintf(dst + off, size - off, " * Tag byte: Mifare or virtual cards of various types\n");
uint8_t L = pnai->abtAts[offset];
offset++;
if (L != (nai.szAtsLen - offset)) {
dst += sprintf(dst, " * Warning: Type Identification Coding length (%i)", L);
dst += sprintf(dst, " not matching Tk length (%zi)\n", (nai.szAtsLen - offset));
if (L != (pnai->szAtsLen - offset)) {
off += snprintf(dst + off, size - off, " * Warning: Type Identification Coding length (%i)", L);
off += snprintf(dst + off, size - off, " not matching Tk length (%" PRIdPTR ")\n", (pnai->szAtsLen - offset));
}
if ((nai.szAtsLen - offset - 2) > 0) { // Omit 2 CRC bytes
uint8_t CTC = nai.abtAts[offset];
if ((pnai->szAtsLen - offset - 2) > 0) { // Omit 2 CRC bytes
uint8_t CTC = pnai->abtAts[offset];
offset++;
dst += sprintf(dst, " * Chip Type: ");
off += snprintf(dst + off, size - off, " * Chip Type: ");
switch (CTC & 0xf0) {
case 0x00:
dst += sprintf(dst, "(Multiple) Virtual Cards\n");
off += snprintf(dst + off, size - off, "(Multiple) Virtual Cards\n");
break;
case 0x10:
dst += sprintf(dst, "Mifare DESFire\n");
off += snprintf(dst + off, size - off, "Mifare DESFire\n");
break;
case 0x20:
dst += sprintf(dst, "Mifare Plus\n");
off += snprintf(dst + off, size - off, "Mifare Plus\n");
break;
default:
dst += sprintf(dst, "RFU\n");
off += snprintf(dst + off, size - off, "RFU\n");
break;
}
dst += sprintf(dst, " * Memory size: ");
off += snprintf(dst + off, size - off, " * Memory size: ");
switch (CTC & 0x0f) {
case 0x00:
dst += sprintf(dst, "<1 kbyte\n");
off += snprintf(dst + off, size - off, "<1 kbyte\n");
break;
case 0x01:
dst += sprintf(dst, "1 kbyte\n");
off += snprintf(dst + off, size - off, "1 kbyte\n");
break;
case 0x02:
dst += sprintf(dst, "2 kbyte\n");
off += snprintf(dst + off, size - off, "2 kbyte\n");
break;
case 0x03:
dst += sprintf(dst, "4 kbyte\n");
off += snprintf(dst + off, size - off, "4 kbyte\n");
break;
case 0x04:
dst += sprintf(dst, "8 kbyte\n");
off += snprintf(dst + off, size - off, "8 kbyte\n");
break;
case 0x0f:
dst += sprintf(dst, "Unspecified\n");
off += snprintf(dst + off, size - off, "Unspecified\n");
break;
default:
dst += sprintf(dst, "RFU\n");
off += snprintf(dst + off, size - off, "RFU\n");
break;
}
}
if ((nai.szAtsLen - offset) > 0) { // Omit 2 CRC bytes
uint8_t CVC = nai.abtAts[offset];
if ((pnai->szAtsLen - offset) > 0) { // Omit 2 CRC bytes
uint8_t CVC = pnai->abtAts[offset];
offset++;
dst += sprintf(dst, " * Chip Status: ");
off += snprintf(dst + off, size - off, " * Chip Status: ");
switch (CVC & 0xf0) {
case 0x00:
dst += sprintf(dst, "Engineering sample\n");
off += snprintf(dst + off, size - off, "Engineering sample\n");
break;
case 0x20:
dst += sprintf(dst, "Released\n");
off += snprintf(dst + off, size - off, "Released\n");
break;
default:
dst += sprintf(dst, "RFU\n");
off += snprintf(dst + off, size - off, "RFU\n");
break;
}
dst += sprintf(dst, " * Chip Generation: ");
off += snprintf(dst + off, size - off, " * Chip Generation: ");
switch (CVC & 0x0f) {
case 0x00:
dst += sprintf(dst, "Generation 1\n");
off += snprintf(dst + off, size - off, "Generation 1\n");
break;
case 0x01:
dst += sprintf(dst, "Generation 2\n");
off += snprintf(dst + off, size - off, "Generation 2\n");
break;
case 0x02:
dst += sprintf(dst, "Generation 3\n");
off += snprintf(dst + off, size - off, "Generation 3\n");
break;
case 0x0f:
dst += sprintf(dst, "Unspecified\n");
off += snprintf(dst + off, size - off, "Unspecified\n");
break;
default:
dst += sprintf(dst, "RFU\n");
off += snprintf(dst + off, size - off, "RFU\n");
break;
}
}
if ((nai.szAtsLen - offset) > 0) { // Omit 2 CRC bytes
uint8_t VCS = nai.abtAts[offset];
if ((pnai->szAtsLen - offset) > 0) { // Omit 2 CRC bytes
uint8_t VCS = pnai->abtAts[offset];
offset++;
dst += sprintf(dst, " * Specifics (Virtual Card Selection):\n");
off += snprintf(dst + off, size - off, " * Specifics (Virtual Card Selection):\n");
if ((VCS & 0x09) == 0x00) {
dst += sprintf(dst, " * Only VCSL supported\n");
off += snprintf(dst + off, size - off, " * Only VCSL supported\n");
} else if ((VCS & 0x09) == 0x01) {
dst += sprintf(dst, " * VCS, VCSL and SVC supported\n");
off += snprintf(dst + off, size - off, " * VCS, VCSL and SVC supported\n");
}
if ((VCS & 0x0e) == 0x00) {
dst += sprintf(dst, " * SL1, SL2(?), SL3 supported\n");
off += snprintf(dst + off, size - off, " * SL1, SL2(?), SL3 supported\n");
} else if ((VCS & 0x0e) == 0x02) {
dst += sprintf(dst, " * SL3 only card\n");
off += snprintf(dst + off, size - off, " * SL3 only card\n");
} else if ((VCS & 0x0f) == 0x0e) {
dst += sprintf(dst, " * No VCS command supported\n");
off += snprintf(dst + off, size - off, " * No VCS command supported\n");
} else if ((VCS & 0x0f) == 0x0f) {
dst += sprintf(dst, " * Unspecified\n");
off += snprintf(dst + off, size - off, " * Unspecified\n");
} else {
dst += sprintf(dst, " * RFU\n");
off += snprintf(dst + off, size - off, " * RFU\n");
}
}
}
} else {
if (CIB == 0x00) {
dst += sprintf(dst, " * Tk after 0x00 consist of optional consecutive COMPACT-TLV data objects\n");
dst += sprintf(dst, " followed by a mandatory status indicator (the last three bytes, not in TLV)\n");
dst += sprintf(dst, " See ISO/IEC 7816-4 8.1.1.3 for more info\n");
off += snprintf(dst + off, size - off, " * Tk after 0x00 consist of optional consecutive COMPACT-TLV data objects\n");
off += snprintf(dst + off, size - off, " followed by a mandatory status indicator (the last three bytes, not in TLV)\n");
off += snprintf(dst + off, size - off, " See ISO/IEC 7816-4 8.1.1.3 for more info\n");
}
if (CIB == 0x10) {
dst += sprintf(dst, " * DIR data reference: %02x\n", nai.abtAts[offset]);
off += snprintf(dst + off, size - off, " * DIR data reference: %02x\n", pnai->abtAts[offset]);
}
if (CIB == 0x80) {
if (nai.szAtsLen == offset) {
dst += sprintf(dst, " * No COMPACT-TLV objects found, no status found\n");
if (pnai->szAtsLen == offset) {
off += snprintf(dst + off, size - off, " * No COMPACT-TLV objects found, no status found\n");
} else {
dst += sprintf(dst, " * Tk after 0x80 consist of optional consecutive COMPACT-TLV data objects;\n");
dst += sprintf(dst, " the last data object may carry a status indicator of one, two or three bytes.\n");
dst += sprintf(dst, " See ISO/IEC 7816-4 8.1.1.3 for more info\n");
off += snprintf(dst + off, size - off, " * Tk after 0x80 consist of optional consecutive COMPACT-TLV data objects;\n");
off += snprintf(dst + off, size - off, " the last data object may carry a status indicator of one, two or three bytes.\n");
off += snprintf(dst + off, size - off, " See ISO/IEC 7816-4 8.1.1.3 for more info\n");
}
}
}
}
}
if (verbose) {
dst += sprintf(dst, "\nFingerprinting based on MIFARE type Identification Procedure:\n"); // AN10833
off += snprintf(dst + off, size - off, "\nFingerprinting based on MIFARE type Identification Procedure:\n"); // AN10833
uint16_t atqa = 0;
uint8_t sak = 0;
uint8_t i, j;
bool found_possible_match = false;
atqa = (((uint16_t)nai.abtAtqa[0] & 0xff) << 8);
atqa += (((uint16_t)nai.abtAtqa[1] & 0xff));
sak = ((uint8_t)nai.btSak & 0xff);
atqa = (((uint16_t)pnai->abtAtqa[0] & 0xff) << 8);
atqa += (((uint16_t)pnai->abtAtqa[1] & 0xff));
sak = ((uint8_t)pnai->btSak & 0xff);
for (i = 0; i < sizeof(const_ca) / sizeof(const_ca[0]); i++) {
if ((atqa & const_ca[i].mask) == const_ca[i].atqa) {
for (j = 0; (j < sizeof(const_ca[i].saklist)) && (const_ca[i].saklist[j] >= 0); j++) {
int sakindex = const_ca[i].saklist[j];
if ((sak & const_cs[sakindex].mask) == const_cs[sakindex].sak) {
dst += sprintf(dst, "* %s%s\n", const_ca[i].type, const_cs[sakindex].type);
off += snprintf(dst + off, size - off, "* %s%s\n", const_ca[i].type, const_cs[sakindex].type);
found_possible_match = true;
}
}
@ -418,226 +419,236 @@ sprint_nfc_iso14443a_info(char *dst, const nfc_iso14443a_info nai, bool verbose)
// Other matches not described in
// AN10833 MIFARE Type Identification Procedure
// but seen in the field:
dst += sprintf(dst, "Other possible matches based on ATQA & SAK values:\n");
off += snprintf(dst + off, size - off, "Other possible matches based on ATQA & SAK values:\n");
uint32_t atqasak = 0;
atqasak += (((uint32_t)nai.abtAtqa[0] & 0xff) << 16);
atqasak += (((uint32_t)nai.abtAtqa[1] & 0xff) << 8);
atqasak += ((uint32_t)nai.btSak & 0xff);
atqasak += (((uint32_t)pnai->abtAtqa[0] & 0xff) << 16);
atqasak += (((uint32_t)pnai->abtAtqa[1] & 0xff) << 8);
atqasak += ((uint32_t)pnai->btSak & 0xff);
switch (atqasak) {
case 0x000488:
dst += sprintf(dst, "* Mifare Classic 1K Infineon\n");
off += snprintf(dst + off, size - off, "* Mifare Classic 1K Infineon\n");
found_possible_match = true;
break;
case 0x000298:
dst += sprintf(dst, "* Gemplus MPCOS\n");
off += snprintf(dst + off, size - off, "* Gemplus MPCOS\n");
found_possible_match = true;
break;
case 0x030428:
dst += sprintf(dst, "* JCOP31\n");
off += snprintf(dst + off, size - off, "* JCOP31\n");
found_possible_match = true;
break;
case 0x004820:
dst += sprintf(dst, "* JCOP31 v2.4.1\n");
dst += sprintf(dst, "* JCOP31 v2.2\n");
off += snprintf(dst + off, size - off, "* JCOP31 v2.4.1\n");
off += snprintf(dst + off, size - off, "* JCOP31 v2.2\n");
found_possible_match = true;
break;
case 0x000428:
dst += sprintf(dst, "* JCOP31 v2.3.1\n");
off += snprintf(dst + off, size - off, "* JCOP31 v2.3.1\n");
found_possible_match = true;
break;
case 0x000453:
dst += sprintf(dst, "* Fudan FM1208SH01\n");
off += snprintf(dst + off, size - off, "* Fudan FM1208SH01\n");
found_possible_match = true;
break;
case 0x000820:
dst += sprintf(dst, "* Fudan FM1208\n");
off += snprintf(dst + off, size - off, "* Fudan FM1208\n");
found_possible_match = true;
break;
case 0x000238:
dst += sprintf(dst, "* MFC 4K emulated by Nokia 6212 Classic\n");
off += snprintf(dst + off, size - off, "* MFC 4K emulated by Nokia 6212 Classic\n");
found_possible_match = true;
break;
case 0x000838:
dst += sprintf(dst, "* MFC 4K emulated by Nokia 6131 NFC\n");
off += snprintf(dst + off, size - off, "* MFC 4K emulated by Nokia 6131 NFC\n");
found_possible_match = true;
break;
}
if (! found_possible_match) {
sprintf(dst, "* Unknown card, sorry\n");
snprintf(dst + off, size - off, "* Unknown card, sorry\n");
}
}
}
void
sprint_nfc_felica_info(char *dst, const nfc_felica_info nfi, bool verbose)
snprint_nfc_felica_info(char *dst, size_t size, const nfc_felica_info *pnfi, bool verbose)
{
(void) verbose;
dst += sprintf(dst, " ID (NFCID2): ");
dst += sprint_hex(dst, nfi.abtId, 8);
dst += sprintf(dst, " Parameter (PAD): ");
dst += sprint_hex(dst, nfi.abtPad, 8);
dst += sprintf(dst, " System Code (SC): ");
sprint_hex(dst, nfi.abtSysCode, 2);
int off = 0;
off += snprintf(dst + off, size - off, " ID (NFCID2): ");
off += snprint_hex(dst + off, size - off, pnfi->abtId, 8);
off += snprintf(dst + off, size - off, " Parameter (PAD): ");
off += snprint_hex(dst + off, size - off, pnfi->abtPad, 8);
off += snprintf(dst + off, size - off, " System Code (SC): ");
snprint_hex(dst + off, size - off, pnfi->abtSysCode, 2);
}
void
sprint_nfc_jewel_info(char *dst, const nfc_jewel_info nji, bool verbose)
snprint_nfc_jewel_info(char *dst, size_t size, const nfc_jewel_info *pnji, bool verbose)
{
(void) verbose;
dst += sprintf(dst, " ATQA (SENS_RES): ");
dst += sprint_hex(dst, nji.btSensRes, 2);
dst += sprintf(dst, " 4-LSB JEWELID: ");
sprint_hex(dst, nji.btId, 4);
int off = 0;
off += snprintf(dst + off, size - off, " ATQA (SENS_RES): ");
off += snprint_hex(dst + off, size - off, pnji->btSensRes, 2);
off += snprintf(dst + off, size - off, " 4-LSB JEWELID: ");
snprint_hex(dst + off, size - off, pnji->btId, 4);
}
#define PI_ISO14443_4_SUPPORTED 0x01
#define PI_NAD_SUPPORTED 0x01
#define PI_CID_SUPPORTED 0x02
void
sprint_nfc_iso14443b_info(char *dst, const nfc_iso14443b_info nbi, bool verbose)
snprint_nfc_iso14443b_info(char *dst, size_t size, const nfc_iso14443b_info *pnbi, bool verbose)
{
const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
dst += sprintf(dst, " PUPI: ");
dst += sprint_hex(dst, nbi.abtPupi, 4);
dst += sprintf(dst, " Application Data: ");
dst += sprint_hex(dst, nbi.abtApplicationData, 4);
dst += sprintf(dst, " Protocol Info: ");
dst += sprint_hex(dst, nbi.abtProtocolInfo, 3);
int off = 0;
off += snprintf(dst + off, size - off, " PUPI: ");
off += snprint_hex(dst + off, size - off, pnbi->abtPupi, 4);
off += snprintf(dst + off, size - off, " Application Data: ");
off += snprint_hex(dst + off, size - off, pnbi->abtApplicationData, 4);
off += snprintf(dst + off, size - off, " Protocol Info: ");
off += snprint_hex(dst + off, size - off, pnbi->abtProtocolInfo, 3);
if (verbose) {
dst += sprintf(dst, "* Bit Rate Capability:\n");
if (nbi.abtProtocolInfo[0] == 0) {
dst += sprintf(dst, " * PICC supports only 106 kbits/s in both directions\n");
off += snprintf(dst + off, size - off, "* Bit Rate Capability:\n");
if (pnbi->abtProtocolInfo[0] == 0) {
off += snprintf(dst + off, size - off, " * PICC supports only 106 kbits/s in both directions\n");
}
if (nbi.abtProtocolInfo[0] & 1 << 7) {
dst += sprintf(dst, " * Same bitrate in both directions mandatory\n");
if (pnbi->abtProtocolInfo[0] & 1 << 7) {
off += snprintf(dst + off, size - off, " * Same bitrate in both directions mandatory\n");
}
if (nbi.abtProtocolInfo[0] & 1 << 4) {
dst += sprintf(dst, " * PICC to PCD, 1etu=64/fc, bitrate 212 kbits/s supported\n");
if (pnbi->abtProtocolInfo[0] & 1 << 4) {
off += snprintf(dst + off, size - off, " * PICC to PCD, 1etu=64/fc, bitrate 212 kbits/s supported\n");
}
if (nbi.abtProtocolInfo[0] & 1 << 5) {
dst += sprintf(dst, " * PICC to PCD, 1etu=32/fc, bitrate 424 kbits/s supported\n");
if (pnbi->abtProtocolInfo[0] & 1 << 5) {
off += snprintf(dst + off, size - off, " * PICC to PCD, 1etu=32/fc, bitrate 424 kbits/s supported\n");
}
if (nbi.abtProtocolInfo[0] & 1 << 6) {
dst += sprintf(dst, " * PICC to PCD, 1etu=16/fc, bitrate 847 kbits/s supported\n");
if (pnbi->abtProtocolInfo[0] & 1 << 6) {
off += snprintf(dst + off, size - off, " * PICC to PCD, 1etu=16/fc, bitrate 847 kbits/s supported\n");
}
if (nbi.abtProtocolInfo[0] & 1 << 0) {
dst += sprintf(dst, " * PCD to PICC, 1etu=64/fc, bitrate 212 kbits/s supported\n");
if (pnbi->abtProtocolInfo[0] & 1 << 0) {
off += snprintf(dst + off, size - off, " * PCD to PICC, 1etu=64/fc, bitrate 212 kbits/s supported\n");
}
if (nbi.abtProtocolInfo[0] & 1 << 1) {
dst += sprintf(dst, " * PCD to PICC, 1etu=32/fc, bitrate 424 kbits/s supported\n");
if (pnbi->abtProtocolInfo[0] & 1 << 1) {
off += snprintf(dst + off, size - off, " * PCD to PICC, 1etu=32/fc, bitrate 424 kbits/s supported\n");
}
if (nbi.abtProtocolInfo[0] & 1 << 2) {
dst += sprintf(dst, " * PCD to PICC, 1etu=16/fc, bitrate 847 kbits/s supported\n");
if (pnbi->abtProtocolInfo[0] & 1 << 2) {
off += snprintf(dst + off, size - off, " * PCD to PICC, 1etu=16/fc, bitrate 847 kbits/s supported\n");
}
if (nbi.abtProtocolInfo[0] & 1 << 3) {
dst += sprintf(dst, " * ERROR unknown value\n");
if (pnbi->abtProtocolInfo[0] & 1 << 3) {
off += snprintf(dst + off, size - off, " * ERROR unknown value\n");
}
if ((nbi.abtProtocolInfo[1] & 0xf0) <= 0x80) {
dst += sprintf(dst, "* Maximum frame sizes: %d bytes\n", iMaxFrameSizes[((nbi.abtProtocolInfo[1] & 0xf0) >> 4)]);
if ((pnbi->abtProtocolInfo[1] & 0xf0) <= 0x80) {
const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
off += snprintf(dst + off, size - off, "* Maximum frame sizes: %d bytes\n", iMaxFrameSizes[((pnbi->abtProtocolInfo[1] & 0xf0) >> 4)]);
}
if ((nbi.abtProtocolInfo[1] & 0x0f) == PI_ISO14443_4_SUPPORTED) {
dst += sprintf(dst, "* Protocol types supported: ISO/IEC 14443-4\n");
if ((pnbi->abtProtocolInfo[1] & 0x0f) == PI_ISO14443_4_SUPPORTED) {
off += snprintf(dst + off, size - off, "* Protocol types supported: ISO/IEC 14443-4\n");
}
dst += sprintf(dst, "* Frame Waiting Time: %.4g ms\n", 256.0 * 16.0 * (1 << ((nbi.abtProtocolInfo[2] & 0xf0) >> 4)) / 13560.0);
if ((nbi.abtProtocolInfo[2] & (PI_NAD_SUPPORTED | PI_CID_SUPPORTED)) != 0) {
dst += sprintf(dst, "* Frame options supported: ");
if ((nbi.abtProtocolInfo[2] & PI_NAD_SUPPORTED) != 0) dst += sprintf(dst, "NAD ");
if ((nbi.abtProtocolInfo[2] & PI_CID_SUPPORTED) != 0) dst += sprintf(dst, "CID ");
sprintf(dst, "\n");
off += snprintf(dst + off, size - off, "* Frame Waiting Time: %.4g ms\n", 256.0 * 16.0 * (1 << ((pnbi->abtProtocolInfo[2] & 0xf0) >> 4)) / 13560.0);
if ((pnbi->abtProtocolInfo[2] & (PI_NAD_SUPPORTED | PI_CID_SUPPORTED)) != 0) {
off += snprintf(dst + off, size - off, "* Frame options supported: ");
if ((pnbi->abtProtocolInfo[2] & PI_NAD_SUPPORTED) != 0) off += snprintf(dst + off, size - off, "NAD ");
if ((pnbi->abtProtocolInfo[2] & PI_CID_SUPPORTED) != 0) off += snprintf(dst + off, size - off, "CID ");
snprintf(dst + off, size - off, "\n");
}
}
}
void
sprint_nfc_iso14443bi_info(char *dst, const nfc_iso14443bi_info nii, bool verbose)
snprint_nfc_iso14443bi_info(char *dst, size_t size, const nfc_iso14443bi_info *pnii, bool verbose)
{
dst += sprintf(dst, " DIV: ");
dst += sprint_hex(dst, nii.abtDIV, 4);
int off = 0;
off += snprintf(dst + off, size - off, " DIV: ");
off += snprint_hex(dst + off, size - off, pnii->abtDIV, 4);
if (verbose) {
int version = (nii.btVerLog & 0x1e) >> 1;
dst += sprintf(dst, " Software Version: ");
int version = (pnii->btVerLog & 0x1e) >> 1;
off += snprintf(dst + off, size - off, " Software Version: ");
if (version == 15) {
dst += sprintf(dst, "Undefined\n");
off += snprintf(dst + off, size - off, "Undefined\n");
} else {
dst += sprintf(dst, "%i\n", version);
off += snprintf(dst + off, size - off, "%i\n", version);
}
if ((nii.btVerLog & 0x80) && (nii.btConfig & 0x80)) {
dst += sprintf(dst, " Wait Enable: yes");
if ((pnii->btVerLog & 0x80) && (pnii->btConfig & 0x80)) {
off += snprintf(dst + off, size - off, " Wait Enable: yes");
}
}
if ((nii.btVerLog & 0x80) && (nii.btConfig & 0x40)) {
dst += sprintf(dst, " ATS: ");
sprint_hex(dst, nii.abtAtr, nii.szAtrLen);
if ((pnii->btVerLog & 0x80) && (pnii->btConfig & 0x40)) {
off += snprintf(dst + off, size - off, " ATS: ");
snprint_hex(dst + off, size - off, pnii->abtAtr, pnii->szAtrLen);
}
}
void
sprint_nfc_iso14443b2sr_info(char *dst, const nfc_iso14443b2sr_info nsi, bool verbose)
snprint_nfc_iso14443b2sr_info(char *dst, size_t size, const nfc_iso14443b2sr_info *pnsi, bool verbose)
{
(void) verbose;
dst += sprintf(dst, " UID: ");
sprint_hex(dst, nsi.abtUID, 8);
int off = 0;
off += snprintf(dst + off, size - off, " UID: ");
snprint_hex(dst + off, size - off, pnsi->abtUID, 8);
}
void
sprint_nfc_iso14443b2ct_info(char *dst, const nfc_iso14443b2ct_info nci, bool verbose)
snprint_nfc_iso14443b2ct_info(char *dst, size_t size, const nfc_iso14443b2ct_info *pnci, bool verbose)
{
(void) verbose;
int off = 0;
uint32_t uid;
uid = (nci.abtUID[3] << 24) + (nci.abtUID[2] << 16) + (nci.abtUID[1] << 8) + nci.abtUID[0];
dst += sprintf(dst, " UID: ");
dst += sprint_hex(dst, nci.abtUID, sizeof(nci.abtUID));
dst += sprintf(dst, " UID (decimal): %010u\n", uid);
dst += sprintf(dst, " Product Code: %02X\n", nci.btProdCode);
sprintf(dst, " Fab Code: %02X\n", nci.btFabCode);
uid = (pnci->abtUID[3] << 24) + (pnci->abtUID[2] << 16) + (pnci->abtUID[1] << 8) + pnci->abtUID[0];
off += snprintf(dst + off, size - off, " UID: ");
off += snprint_hex(dst + off, size - off, pnci->abtUID, sizeof(pnci->abtUID));
off += snprintf(dst + off, size - off, " UID (decimal): %010u\n", uid);
off += snprintf(dst + off, size - off, " Product Code: %02X\n", pnci->btProdCode);
snprintf(dst + off, size - off, " Fab Code: %02X\n", pnci->btFabCode);
}
void
sprint_nfc_dep_info(char *dst, const nfc_dep_info ndi, bool verbose)
snprint_nfc_dep_info(char *dst, size_t size, const nfc_dep_info *pndi, bool verbose)
{
(void) verbose;
dst += sprintf(dst, " NFCID3: ");
dst += sprint_hex(dst, ndi.abtNFCID3, 10);
dst += sprintf(dst, " BS: %02x\n", ndi.btBS);
dst += sprintf(dst, " BR: %02x\n", ndi.btBR);
dst += sprintf(dst, " TO: %02x\n", ndi.btTO);
dst += sprintf(dst, " PP: %02x\n", ndi.btPP);
if (ndi.szGB) {
dst += sprintf(dst, "General Bytes: ");
sprint_hex(dst, ndi.abtGB, ndi.szGB);
int off = 0;
off += snprintf(dst + off, size - off, " NFCID3: ");
off += snprint_hex(dst + off, size - off, pndi->abtNFCID3, 10);
off += snprintf(dst + off, size - off, " BS: %02x\n", pndi->btBS);
off += snprintf(dst + off, size - off, " BR: %02x\n", pndi->btBR);
off += snprintf(dst + off, size - off, " TO: %02x\n", pndi->btTO);
off += snprintf(dst + off, size - off, " PP: %02x\n", pndi->btPP);
if (pndi->szGB) {
off += snprintf(dst + off, size - off, "General Bytes: ");
snprint_hex(dst + off, size - off, pndi->abtGB, pndi->szGB);
}
}
void
sprint_nfc_target(char *dst, const nfc_target nt, bool verbose)
snprint_nfc_target(char *dst, size_t size, const nfc_target *pnt, bool verbose)
{
dst += sprintf(dst, "%s (%s%s) target:\n", str_nfc_modulation_type(nt.nm.nmt), str_nfc_baud_rate(nt.nm.nbr), (nt.nm.nmt != NMT_DEP) ? "" : (nt.nti.ndi.ndm == NDM_ACTIVE) ? "active mode" : "passive mode");
switch (nt.nm.nmt) {
case NMT_ISO14443A:
sprint_nfc_iso14443a_info(dst, nt.nti.nai, verbose);
break;
case NMT_JEWEL:
sprint_nfc_jewel_info(dst, nt.nti.nji, verbose);
break;
case NMT_FELICA:
sprint_nfc_felica_info(dst, nt.nti.nfi, verbose);
break;
case NMT_ISO14443B:
sprint_nfc_iso14443b_info(dst, nt.nti.nbi, verbose);
break;
case NMT_ISO14443BI:
sprint_nfc_iso14443bi_info(dst, nt.nti.nii, verbose);
break;
case NMT_ISO14443B2SR:
sprint_nfc_iso14443b2sr_info(dst, nt.nti.nsi, verbose);
break;
case NMT_ISO14443B2CT:
sprint_nfc_iso14443b2ct_info(dst, nt.nti.nci, verbose);
break;
case NMT_DEP:
sprint_nfc_dep_info(dst, nt.nti.ndi, verbose);
break;
if (NULL != pnt) {
int off = 0;
off += snprintf(dst + off, size - off, "%s (%s%s) target:\n", str_nfc_modulation_type(pnt->nm.nmt), str_nfc_baud_rate(pnt->nm.nbr), (pnt->nm.nmt != NMT_DEP) ? "" : (pnt->nti.ndi.ndm == NDM_ACTIVE) ? "active mode" : "passive mode");
switch (pnt->nm.nmt) {
case NMT_ISO14443A:
snprint_nfc_iso14443a_info(dst + off, size - off, &pnt->nti.nai, verbose);
break;
case NMT_JEWEL:
snprint_nfc_jewel_info(dst + off, size - off, &pnt->nti.nji, verbose);
break;
case NMT_FELICA:
snprint_nfc_felica_info(dst + off, size - off, &pnt->nti.nfi, verbose);
break;
case NMT_ISO14443B:
snprint_nfc_iso14443b_info(dst + off, size - off, &pnt->nti.nbi, verbose);
break;
case NMT_ISO14443BI:
snprint_nfc_iso14443bi_info(dst + off, size - off, &pnt->nti.nii, verbose);
break;
case NMT_ISO14443B2SR:
snprint_nfc_iso14443b2sr_info(dst + off, size - off, &pnt->nti.nsi, verbose);
break;
case NMT_ISO14443B2CT:
snprint_nfc_iso14443b2ct_info(dst + off, size - off, &pnt->nti.nci, verbose);
break;
case NMT_DEP:
snprint_nfc_dep_info(dst + off, size - off, &pnt->nti.ndi, verbose);
break;
}
}
}

View file

@ -27,15 +27,15 @@
#ifndef _TARGET_SUBR_H_
#define _TARGET_SUBR_H_
int sprint_hex(char *dst, const uint8_t *pbtData, const size_t szLen);
void sprint_nfc_iso14443a_info(char *dst, const nfc_iso14443a_info nai, bool verbose);
void sprint_nfc_iso14443b_info(char *dst, const nfc_iso14443b_info nbi, bool verbose);
void sprint_nfc_iso14443bi_info(char *dst, const nfc_iso14443bi_info nii, bool verbose);
void sprint_nfc_iso14443b2sr_info(char *dst, const nfc_iso14443b2sr_info nsi, bool verbose);
void sprint_nfc_iso14443b2ct_info(char *dst, const nfc_iso14443b2ct_info nci, bool verbose);
void sprint_nfc_felica_info(char *dst, const nfc_felica_info nfi, bool verbose);
void sprint_nfc_jewel_info(char *dst, const nfc_jewel_info nji, bool verbose);
void sprint_nfc_dep_info(char *dst, const nfc_dep_info ndi, bool verbose);
void sprint_nfc_target(char *dst, const nfc_target nt, bool verbose);
int snprint_hex(char *dst, size_t size, const uint8_t *pbtData, const size_t szLen);
void snprint_nfc_iso14443a_info(char *dst, size_t size, const nfc_iso14443a_info *pnai, bool verbose);
void snprint_nfc_iso14443b_info(char *dst, size_t size, const nfc_iso14443b_info *pnbi, bool verbose);
void snprint_nfc_iso14443bi_info(char *dst, size_t size, const nfc_iso14443bi_info *pnii, bool verbose);
void snprint_nfc_iso14443b2sr_info(char *dst, size_t size, const nfc_iso14443b2sr_info *pnsi, bool verbose);
void snprint_nfc_iso14443b2ct_info(char *dst, size_t size, const nfc_iso14443b2ct_info *pnci, bool verbose);
void snprint_nfc_felica_info(char *dst, size_t size, const nfc_felica_info *pnfi, bool verbose);
void snprint_nfc_jewel_info(char *dst, size_t size, const nfc_jewel_info *pnji, bool verbose);
void snprint_nfc_dep_info(char *dst, size_t size, const nfc_dep_info *pndi, bool verbose);
void snprint_nfc_target(char *dst, size_t size, const nfc_target *pnt, bool verbose);
#endif