mirror of
https://github.com/nfc-tools/libnfc.git
synced 2026-07-20 10:41:50 +00:00
New NFC modulation type NMT_BARCODE
This commit is contained in:
@@ -57,6 +57,7 @@ const nfc_baud_rate pn533_iso14443a_supported_baud_rates[] = { NBR_847, NBR_424,
|
||||
const nfc_baud_rate pn53x_felica_supported_baud_rates[] = { NBR_424, NBR_212, 0 };
|
||||
const nfc_baud_rate pn53x_dep_supported_baud_rates[] = { NBR_424, NBR_212, NBR_106, 0 };
|
||||
const nfc_baud_rate pn53x_jewel_supported_baud_rates[] = { NBR_106, 0 };
|
||||
const nfc_baud_rate pn53x_barcode_supported_baud_rates[] = { NBR_106, 0 };
|
||||
const nfc_baud_rate pn532_iso14443b_supported_baud_rates[] = { NBR_106, 0 };
|
||||
const nfc_baud_rate pn533_iso14443b_supported_baud_rates[] = { NBR_847, NBR_424, NBR_212, NBR_106, 0 };
|
||||
const nfc_modulation_type pn53x_supported_modulation_as_target[] = {NMT_ISO14443A, NMT_FELICA, NMT_DEP, 0};
|
||||
@@ -107,6 +108,8 @@ pn53x_init(struct nfc_device *pnd)
|
||||
if (CHIP_DATA(pnd)->type != PN531) {
|
||||
CHIP_DATA(pnd)->supported_modulation_as_initiator[nbSupportedModulation] = NMT_JEWEL;
|
||||
nbSupportedModulation++;
|
||||
CHIP_DATA(pnd)->supported_modulation_as_initiator[nbSupportedModulation] = NMT_BARCODE;
|
||||
nbSupportedModulation++;
|
||||
}
|
||||
CHIP_DATA(pnd)->supported_modulation_as_initiator[nbSupportedModulation] = NMT_DEP;
|
||||
nbSupportedModulation++;
|
||||
@@ -610,6 +613,10 @@ pn53x_decode_target_data(const uint8_t *pbtRawData, size_t szRawData, pn53x_type
|
||||
pbtRawData += 2;
|
||||
memcpy(pnti->nji.btId, pbtRawData, 4);
|
||||
break;
|
||||
case NMT_BARCODE:
|
||||
pnti->nti.szDataLen = szRawData;
|
||||
memcpy(pnti->nti.abtData, pbtRawData, szRawData);
|
||||
break;
|
||||
// Should not happend...
|
||||
case NMT_DEP:
|
||||
return NFC_ECHIP;
|
||||
@@ -1147,6 +1154,87 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd,
|
||||
} while (pnd->bInfiniteSelect);
|
||||
if (! found)
|
||||
return 0;
|
||||
} else if (nm.nmt == NMT_BARCODE) {
|
||||
if (CHIP_DATA(pnd)->type == RCS360) {
|
||||
// TODO add support for RC-S360, at the moment it refuses to send raw frames without a first select
|
||||
pnd->last_error = NFC_ENOTIMPL;
|
||||
return pnd->last_error;
|
||||
}
|
||||
// No native support in InListPassiveTarget so we do discovery by hand
|
||||
|
||||
// We turn RF field off first for a better detection rate but this doesn't work well with ASK LoGO
|
||||
if ((! CHIP_DATA(pnd)->progressive_field) && (res = nfc_device_set_property_bool(pnd, NP_ACTIVATE_FIELD, false)) < 0) {
|
||||
return res;
|
||||
}
|
||||
if ((res = nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false)) < 0) {
|
||||
return res;
|
||||
}
|
||||
if ((res = nfc_device_set_property_bool(pnd, NP_HANDLE_PARITY, false)) < 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
do {
|
||||
uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
||||
uint8_t abtRxPar[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
||||
if ((res = nfc_initiator_transceive_bits(pnd, NULL, 0, NULL, abtRx, sizeof(abtRx), abtRxPar)) < 0) {
|
||||
if ((res == NFC_ERFTRANS) || (res == NFC_ECHIP)) { // Broken reception
|
||||
continue;
|
||||
} else {
|
||||
nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true);
|
||||
nfc_device_set_property_bool(pnd, NP_HANDLE_PARITY, true);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// Shuffle bits to produce NFC Barcode bitstream
|
||||
uint8_t uRemainder;
|
||||
size_t szPos;
|
||||
size_t szBytes = res / 8;
|
||||
size_t off = 0;
|
||||
uint8_t i;
|
||||
memset(abtTargetsData, 0x00, sizeof(abtTargetsData));
|
||||
// Reinject S bit
|
||||
abtTargetsData[off / 8] |= 1 << (7 - (off % 8));
|
||||
off++;
|
||||
|
||||
for (szPos = 0; szPos < szBytes; szPos++) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
abtTargetsData[off / 8] |= ((abtRx[szPos] >> i) & 1) << (7 - (off % 8));
|
||||
off++;
|
||||
}
|
||||
abtTargetsData[off / 8] |= abtRxPar[szPos] << (7 - (off % 8));
|
||||
off++;
|
||||
}
|
||||
uRemainder = res % 8;
|
||||
for (i = 0; i < uRemainder; i++) {
|
||||
abtTargetsData[off / 8] |= ((abtRx[szPos] >> i) & 1) << (7 - (off % 8));
|
||||
off++;
|
||||
}
|
||||
|
||||
if (off % 128 != 0) {
|
||||
// NFC Barcode seems incomplete
|
||||
continue;
|
||||
}
|
||||
|
||||
szTargetsData = (size_t)off / 8;
|
||||
|
||||
// validate CRC
|
||||
uint8_t pbtCrc[2];
|
||||
iso14443a_crc(abtTargetsData, szTargetsData - 2, pbtCrc);
|
||||
if ((pbtCrc[1] != abtTargetsData[szTargetsData - 2]) || (pbtCrc[0] != abtTargetsData[szTargetsData - 1])) {
|
||||
continue;
|
||||
}
|
||||
nttmp.nm = nm;
|
||||
if ((res = pn53x_decode_target_data(abtTargetsData, szTargetsData, CHIP_DATA(pnd)->type, nm.nmt, &(nttmp.nti))) < 0) {
|
||||
return res;
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
} while (pnd->bInfiniteSelect);
|
||||
if (! found) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
const pn53x_modulation pm = pn53x_nm_to_pm(nm);
|
||||
if ((PM_UNDEFINED == pm) || (NBR_UNDEFINED == nm.nbr)) {
|
||||
@@ -1846,6 +1934,40 @@ static int pn53x_ISO14443A_Jewel_is_present(struct nfc_device *pnd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pn53x_ISO14443A_Barcode_is_present(struct nfc_device *pnd)
|
||||
{
|
||||
int ret;
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "target_is_present(): Ping Barcode");
|
||||
|
||||
// We turn RF field off first for a better detection rate but this doesn't work well with ASK LoGO
|
||||
if ((! CHIP_DATA(pnd)->progressive_field) && (ret = nfc_device_set_property_bool(pnd, NP_ACTIVATE_FIELD, false)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false)) < 0)
|
||||
return ret;
|
||||
if ((ret = nfc_device_set_property_bool(pnd, NP_HANDLE_PARITY, false)) < 0)
|
||||
return ret;
|
||||
|
||||
int failures = 0;
|
||||
while (failures < 3) {
|
||||
if ((! CHIP_DATA(pnd)->progressive_field) && (ret = nfc_device_set_property_bool(pnd, NP_ACTIVATE_FIELD, false)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
||||
uint8_t abtRxPar[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
||||
if ((ret = nfc_initiator_transceive_bits(pnd, NULL, 0, NULL, abtRx, sizeof(abtRx), abtRxPar)) < 1) {
|
||||
failures++;
|
||||
} else {
|
||||
nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true);
|
||||
nfc_device_set_property_bool(pnd, NP_HANDLE_PARITY, true);
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
}
|
||||
nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true);
|
||||
nfc_device_set_property_bool(pnd, NP_HANDLE_PARITY, true);
|
||||
return NFC_ETGRELEASED;
|
||||
}
|
||||
|
||||
static int pn53x_ISO14443A_MFUL_is_present(struct nfc_device *pnd)
|
||||
{
|
||||
int ret;
|
||||
@@ -2081,6 +2203,9 @@ pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt)
|
||||
case NMT_JEWEL:
|
||||
ret = pn53x_ISO14443A_Jewel_is_present(pnd);
|
||||
break;
|
||||
case NMT_BARCODE:
|
||||
ret = pn53x_ISO14443A_Barcode_is_present(pnd);
|
||||
break;
|
||||
case NMT_ISO14443B:
|
||||
ret = pn53x_ISO14443B_4_is_present(pnd);
|
||||
break;
|
||||
@@ -2144,6 +2269,7 @@ pn53x_target_init(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const
|
||||
case NMT_ISO14443B2SR:
|
||||
case NMT_ISO14443B2CT:
|
||||
case NMT_JEWEL:
|
||||
case NMT_BARCODE:
|
||||
pnd->last_error = NFC_EDEVNOTSUPP;
|
||||
return pnd->last_error;
|
||||
}
|
||||
@@ -2245,6 +2371,7 @@ pn53x_target_init(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const
|
||||
case NMT_ISO14443B2SR:
|
||||
case NMT_ISO14443B2CT:
|
||||
case NMT_JEWEL:
|
||||
case NMT_BARCODE:
|
||||
pnd->last_error = NFC_EDEVNOTSUPP;
|
||||
return pnd->last_error;
|
||||
}
|
||||
@@ -2393,6 +2520,7 @@ pn53x_target_receive_bytes(struct nfc_device *pnd, uint8_t *pbtRx, const size_t
|
||||
}
|
||||
// NO BREAK
|
||||
case NMT_JEWEL:
|
||||
case NMT_BARCODE:
|
||||
case NMT_ISO14443B:
|
||||
case NMT_ISO14443BI:
|
||||
case NMT_ISO14443B2SR:
|
||||
@@ -2498,6 +2626,7 @@ pn53x_target_send_bytes(struct nfc_device *pnd, const uint8_t *pbtTx, const size
|
||||
}
|
||||
// NO BREAK
|
||||
case NMT_JEWEL:
|
||||
case NMT_BARCODE:
|
||||
case NMT_ISO14443B:
|
||||
case NMT_ISO14443BI:
|
||||
case NMT_ISO14443B2SR:
|
||||
@@ -2714,6 +2843,7 @@ pn53x_InListPassiveTarget(struct nfc_device *pnd,
|
||||
}
|
||||
break;
|
||||
case PM_JEWEL_106:
|
||||
case PM_BARCODE_106:
|
||||
if (CHIP_DATA(pnd)->type == PN531) {
|
||||
// These modulations are not supported by pn531
|
||||
pnd->last_error = NFC_EDEVNOTSUPP;
|
||||
@@ -3141,6 +3271,9 @@ pn53x_nm_to_pm(const nfc_modulation nm)
|
||||
case NMT_JEWEL:
|
||||
return PM_JEWEL_106;
|
||||
|
||||
case NMT_BARCODE:
|
||||
return PM_BARCODE_106;
|
||||
|
||||
case NMT_FELICA:
|
||||
switch (nm.nbr) {
|
||||
case NBR_212:
|
||||
@@ -3253,6 +3386,7 @@ pn53x_nm_to_ptt(const nfc_modulation nm)
|
||||
case NMT_ISO14443BI:
|
||||
case NMT_ISO14443B2SR:
|
||||
case NMT_ISO14443B2CT:
|
||||
case NMT_BARCODE:
|
||||
case NMT_DEP:
|
||||
// Nothing to do...
|
||||
break;
|
||||
@@ -3307,6 +3441,9 @@ pn53x_get_supported_baud_rate(nfc_device *pnd, const nfc_mode mode, const nfc_mo
|
||||
case NMT_JEWEL:
|
||||
*supported_br = (nfc_baud_rate *)pn53x_jewel_supported_baud_rates;
|
||||
break;
|
||||
case NMT_BARCODE:
|
||||
*supported_br = (nfc_baud_rate *)pn53x_barcode_supported_baud_rates;
|
||||
break;
|
||||
case NMT_DEP:
|
||||
*supported_br = (nfc_baud_rate *)pn53x_dep_supported_baud_rates;
|
||||
break;
|
||||
@@ -3560,6 +3697,9 @@ pn53x_data_new(struct nfc_device *pnd, const struct pn53x_io *io)
|
||||
|
||||
CHIP_DATA(pnd)->supported_modulation_as_target = NULL;
|
||||
|
||||
// Set default progressive field flag
|
||||
CHIP_DATA(pnd)->progressive_field = false;
|
||||
|
||||
return pnd->chip_data;
|
||||
}
|
||||
|
||||
|
||||
@@ -210,6 +210,7 @@ struct pn53x_data {
|
||||
/** Supported modulation type */
|
||||
nfc_modulation_type *supported_modulation_as_initiator;
|
||||
nfc_modulation_type *supported_modulation_as_target;
|
||||
bool progressive_field;
|
||||
};
|
||||
|
||||
#define CHIP_DATA(pnd) ((struct pn53x_data*)(pnd->chip_data))
|
||||
@@ -231,6 +232,8 @@ typedef enum {
|
||||
PM_ISO14443B_106 = 0x03,
|
||||
/** Jewel Topaz (Innovision Research & Development) (Not supported by PN531) */
|
||||
PM_JEWEL_106 = 0x04,
|
||||
/** Thinfilm NFC Barcode (Not supported by PN531) */
|
||||
PM_BARCODE_106 = 0x05,
|
||||
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 (Not supported by PN531 nor PN532) */
|
||||
PM_ISO14443B_212 = 0x06,
|
||||
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 (Not supported by PN531 nor PN532) */
|
||||
|
||||
Reference in New Issue
Block a user