WARNING: API changed ! Some variable name have been changed to match with coding convention.

Changed length parmeters from uint32_t to size_t (Fix Issue 32).
Code cleanup.
This commit is contained in:
Romuald Conty 2009-10-02 09:52:02 +00:00
parent 5a77ad7a1e
commit 979f1fa518
22 changed files with 522 additions and 518 deletions

View file

@ -32,10 +32,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#define SAK_FLAG_ATS_SUPPORTED 0x20
static byte_t abtRx[MAX_FRAME_LEN];
static uint32_t uiRxBits;
static uint32_t uiRxLen;
static size_t szRxBits;
static size_t szRxLen;
static byte_t abtUid[10];
static uint32_t uiUidLen = 4;
static size_t szUidLen = 4;
static dev_info* pdi;
bool quiet_output = false;
@ -47,23 +47,23 @@ byte_t abtSelectTag [9] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
byte_t abtRats [4] = { 0xe0,0x50,0xbc,0xa5 };
byte_t abtHalt [4] = { 0x50,0x00,0x57,0xcd };
bool transmit_bits(const byte_t* pbtTx, const uint32_t uiTxBits)
bool transmit_bits(const byte_t* pbtTx, const size_t szTxBits)
{
// Show transmitted command
if(!quiet_output)
{
printf("R: ");
print_hex_bits(pbtTx,uiTxBits);
print_hex_bits(pbtTx,szTxBits);
}
// Transmit the bit frame command, we don't use the arbitrary parity feature
if (!nfc_initiator_transceive_bits(pdi,pbtTx,uiTxBits,NULL,abtRx,&uiRxBits,NULL)) return false;
if (!nfc_initiator_transceive_bits(pdi,pbtTx,szTxBits,NULL,abtRx,&szRxBits,NULL)) return false;
// Show received answer
if(!quiet_output)
{
printf("T: ");
print_hex_bits(abtRx,uiRxBits);
print_hex_bits(abtRx,szRxBits);
}
// Succesful transfer
@ -71,23 +71,23 @@ bool transmit_bits(const byte_t* pbtTx, const uint32_t uiTxBits)
}
bool transmit_bytes(const byte_t* pbtTx, const uint32_t uiTxLen)
bool transmit_bytes(const byte_t* pbtTx, const size_t szTxLen)
{
// Show transmitted command
if(!quiet_output)
{
printf("R: ");
print_hex(pbtTx,uiTxLen);
print_hex(pbtTx,szTxLen);
}
// Transmit the command bytes
if (!nfc_initiator_transceive_bytes(pdi,pbtTx,uiTxLen,abtRx,&uiRxLen)) return false;
if (!nfc_initiator_transceive_bytes(pdi,pbtTx,szTxLen,abtRx,&szRxLen)) return false;
// Show received answer
if(!quiet_output)
{
printf("T: ");
print_hex(abtRx,uiRxLen);
print_hex(abtRx,szRxLen);
}
// Succesful transfer
@ -140,7 +140,7 @@ int main(int argc,char* argv[])
// Enable field so more power consuming cards can power themselves up
nfc_configure(pdi,DCO_ACTIVATE_FIELD,true);
printf("\nConnected to NFC reader: %s\n\n",pdi->acName);
// Send the 7 bits request command specified in ISO 14443A (0x26)
@ -153,7 +153,7 @@ int main(int argc,char* argv[])
// Anti-collision
transmit_bytes(abtSelectAll,2);
// Save the UID
memcpy(abtUid,abtRx,4);
memcpy(abtSelectTag+2,abtRx,5);
@ -163,7 +163,7 @@ int main(int argc,char* argv[])
// Test if we are dealing with a 4 bytes uid
if (abtUid[0]!= 0x88)
{
uiUidLen = 4;
szUidLen = 4;
} else {
// We have to do the anti-collision for cascade level 2
abtSelectAll[0] = 0x95;
@ -171,23 +171,23 @@ int main(int argc,char* argv[])
// Anti-collision
transmit_bytes(abtSelectAll,2);
// Save the UID
memcpy(abtUid+4,abtRx,4);
memcpy(abtSelectTag+2,abtRx,5);
append_iso14443a_crc(abtSelectTag,7);
transmit_bytes(abtSelectTag,9);
uiUidLen = 7;
szUidLen = 7;
}
// Request ATS, this only applies to tags that support ISO 14443A-4
if (abtRx[0] & SAK_FLAG_ATS_SUPPORTED) transmit_bytes(abtRats,4);
// Done, halt the tag now
transmit_bytes(abtHalt,4);
printf("\nFound tag with UID: ");
if (uiUidLen == 4)
if (szUidLen == 4)
{
printf("%08x\n",swap_endian32(abtUid));
} else {

View file

@ -69,14 +69,14 @@ byte_t oddparity(const byte_t bt)
return OddParity[bt];
}
void oddparity_bytes(const byte_t* pbtData, const uint32_t uiLen, byte_t* pbtPar)
void oddparity_bytes(const byte_t* pbtData, const size_t szLen, byte_t* pbtPar)
{
uint32_t uiByteNr;
size_t szByteNr;
// Calculate the parity bits for the command
for (uiByteNr=0; uiByteNr<uiLen; uiByteNr++)
for (szByteNr=0; szByteNr<szLen; szByteNr++)
{
pbtPar[uiByteNr] = OddParity[pbtData[uiByteNr]];
pbtPar[szByteNr] = OddParity[pbtData[szByteNr]];
}
}
@ -85,11 +85,11 @@ byte_t mirror(byte_t bt)
return ByteMirror[bt];
}
void mirror_bytes(byte_t *pbts, uint32_t uiLen)
void mirror_bytes(byte_t *pbts, size_t szLen)
{
uint32_t btNr;
size_t szByteNr;
for (btNr=0; btNr<uiLen; btNr++)
for (szByteNr=0; szByteNr<szLen; szByteNr++)
{
*pbts = ByteMirror[*pbts];
pbts++;
@ -120,7 +120,7 @@ uint64_t swap_endian64(const void* pui64)
return (((ui64N&0xFF)<<56)+((ui64N&0xFF00)<<40)+((ui64N&0xFF0000)<<24)+((ui64N&0xFF000000)<<8)+((ui64N&0xFF00000000ull)>>8)+((ui64N&0xFF0000000000ull)>>24)+((ui64N&0xFF000000000000ull)>>40)+((ui64N&0xFF00000000000000ull)>>56));
}
void append_iso14443a_crc(byte_t* pbtData, uint32_t uiLen)
void append_iso14443a_crc(byte_t* pbtData, size_t szLen)
{
byte_t bt;
uint32_t wCrc = 0x6363;
@ -130,57 +130,57 @@ void append_iso14443a_crc(byte_t* pbtData, uint32_t uiLen)
bt = (bt^(byte_t)(wCrc & 0x00FF));
bt = (bt^(bt<<4));
wCrc = (wCrc >> 8)^((uint32_t)bt << 8)^((uint32_t)bt<<3)^((uint32_t)bt>>4);
} while (--uiLen);
} while (--szLen);
*pbtData++ = (byte_t) (wCrc & 0xFF);
*pbtData = (byte_t) ((wCrc >> 8) & 0xFF);
}
void print_hex(const byte_t* pbtData, const uint32_t uiBytes)
void print_hex(const byte_t* pbtData, const size_t szBytes)
{
uint32_t uiPos;
size_t szPos;
for (uiPos=0; uiPos < uiBytes; uiPos++)
for (szPos=0; szPos < szBytes; szPos++)
{
printf("%02x ",pbtData[uiPos]);
printf("%02x ",pbtData[szPos]);
}
printf("\n");
}
void print_hex_bits(const byte_t* pbtData, const uint32_t uiBits)
void print_hex_bits(const byte_t* pbtData, const size_t szBits)
{
uint32_t uiPos;
uint32_t uiBytes = uiBits/8;
size_t szPos;
size_t szBytes = szBits/8;
for (uiPos=0; uiPos < uiBytes; uiPos++)
for (szPos=0; szPos < szBytes; szPos++)
{
printf("%02x ",pbtData[uiPos]);
printf("%02x ",pbtData[szPos]);
}
// Print the rest bits, these cannot have no parity bit
if (uiBits%8 != 0) printf("%02x",pbtData[uiBytes]);
if (szBits%8 != 0) printf("%02x",pbtData[szBytes]);
printf("\n");
}
void print_hex_par(const byte_t* pbtData, const uint32_t uiBits, const byte_t* pbtDataPar)
void print_hex_par(const byte_t* pbtData, const size_t szBits, const byte_t* pbtDataPar)
{
uint32_t uiPos;
uint32_t uiBytes = uiBits/8;
size_t szPos;
size_t szBytes = szBits/8;
for (uiPos=0; uiPos < uiBytes; uiPos++)
for (szPos=0; szPos < szBytes; szPos++)
{
printf("%02x",pbtData[uiPos]);
if (OddParity[pbtData[uiPos]] != pbtDataPar[uiPos])
printf("%02x",pbtData[szPos]);
if (OddParity[pbtData[szPos]] != pbtDataPar[szPos])
{
printf("! ");
} else {
printf(" ");
}
}
// Print the rest bits, these cannot have no parity bit
if (uiBits%8 != 0) printf("%02x",pbtData[uiBytes]);
if (szBits%8 != 0) printf("%02x",pbtData[szBytes]);
printf("\n");
}

View file

@ -26,21 +26,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "types.h"
byte_t oddparity(const byte_t bt);
void oddparity_byte_ts(const byte_t* pbtData, const uint32_t uiLen, byte_t* pbtPar);
void oddparity_byte_ts(const byte_t* pbtData, const size_t szLen, byte_t* pbtPar);
byte_t mirror(byte_t bt);
uint32_t mirror32(uint32_t ui32Bits);
uint64_t mirror64(uint64_t ui64Bits);
void mirror_byte_ts(byte_t *pbts, uint32_t uiLen);
void mirror_byte_ts(byte_t *pbts, size_t szLen);
uint32_t swap_endian32(const void* pui32);
uint64_t swap_endian64(const void* pui64);
void append_iso14443a_crc(byte_t* pbtData, uint32_t uiLen);
void append_iso14443a_crc(byte_t* pbtData, size_t szLen);
void print_hex(const byte_t* pbtData, const uint32_t uiLen);
void print_hex_bits(const byte_t* pbtData, const uint32_t uiBits);
void print_hex_par(const byte_t* pbtData, const uint32_t uiBits, const byte_t* pbtDataPar);
void print_hex(const byte_t* pbtData, const size_t szLen);
void print_hex_bits(const byte_t* pbtData, const size_t szBits);
void print_hex_par(const byte_t* pbtData, const size_t szBits, const byte_t* pbtDataPar);
#endif // _LIBNFC_BITUTILS_H_

View file

@ -55,12 +55,12 @@ typedef struct {
SCARD_IO_REQUEST ioCard;
} dev_spec_acr122;
dev_info* dev_acr122_connect(const nfc_device_desc_t* device_desc)
dev_info* dev_acr122_connect(const nfc_device_desc_t* pndd)
{
char* pacReaders[MAX_DEVICES];
char acList[256+64*MAX_DEVICES];
size_t ulListLen = sizeof(acList);
uint32_t uiPos;
size_t szListLen = sizeof(acList);
size_t szPos;
uint32_t uiReaderCount;
uint32_t uiReader;
uint32_t uiDevIndex;
@ -70,45 +70,45 @@ dev_info* dev_acr122_connect(const nfc_device_desc_t* device_desc)
char* pcFirmware;
// Clear the reader list
memset(acList,0x00,ulListLen);
memset(acList,0x00,szListLen);
// Test if context succeeded
if (SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&(dsa.hCtx)) != SCARD_S_SUCCESS) return INVALID_DEVICE_INFO;
// Retrieve the string array of all available pcsc readers
if (SCardListReaders(dsa.hCtx,NULL,acList,(void*)&ulListLen) != SCARD_S_SUCCESS) return INVALID_DEVICE_INFO;
if (SCardListReaders(dsa.hCtx,NULL,acList,(void*)&szListLen) != SCARD_S_SUCCESS) return INVALID_DEVICE_INFO;
DBG("PCSC reports following device(s):");
DBG("- %s",acList);
pacReaders[0] = acList;
uiReaderCount = 1;
for (uiPos=0; uiPos<ulListLen; uiPos++)
for (szPos=0; szPos<szListLen; szPos++)
{
// Make sure don't break out of our reader array
if (uiReaderCount == MAX_DEVICES) break;
// Test if there is a next reader available
if (acList[uiPos] == 0x00)
if (acList[szPos] == 0x00)
{
// Test if we are at the end of the list
if (acList[uiPos+1] == 0x00)
if (acList[szPos+1] == 0x00)
{
break;
}
// Store the position of the next reader and search for more readers
pacReaders[uiReaderCount] = acList+uiPos+1;
pacReaders[uiReaderCount] = acList+szPos+1;
uiReaderCount++;
DBG("- %s",acList+uiPos+1);
DBG("- %s",acList+szPos+1);
}
}
// Initialize the device index we are seaching for
if( device_desc == NULL ) {
if( pndd == NULL ) {
uiDevIndex = 0;
} else {
uiDevIndex = device_desc->index;
uiDevIndex = pndd->uiIndex;
}
// Iterate through all readers and try to find the ACR122 on requested index
@ -169,63 +169,63 @@ void dev_acr122_disconnect(dev_info* pdi)
free(pdi);
}
bool dev_acr122_transceive(const dev_spec ds, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen)
bool dev_acr122_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
{
byte_t abtRxCmd[5] = { 0xFF,0xC0,0x00,0x00 };
byte_t uiRxCmdLen = sizeof(abtRxCmd);
size_t szRxCmdLen = sizeof(abtRxCmd);
byte_t abtRxBuf[ACR122_RESPONSE_LEN];
size_t ulRxBufLen;
size_t szRxBufLen;
byte_t abtTxBuf[ACR122_WRAP_LEN+ACR122_COMMAND_LEN] = { 0xFF, 0x00, 0x00, 0x00 };
dev_spec_acr122* pdsa = (dev_spec_acr122*)ds;
// Make sure the command does not overflow the send buffer
if (uiTxLen > ACR122_COMMAND_LEN) return false;
if (szTxLen > ACR122_COMMAND_LEN) return false;
// Store the length of the command we are going to send
abtTxBuf[4] = uiTxLen;
abtTxBuf[4] = szTxLen;
// Prepare and transmit the send buffer
memcpy(abtTxBuf+5,pbtTx,uiTxLen);
ulRxBufLen = sizeof(abtRxBuf);
memcpy(abtTxBuf+5,pbtTx,szTxLen);
szRxBufLen = sizeof(abtRxBuf);
#ifdef DEBUG
printf(" TX: ");
print_hex(abtTxBuf,uiTxLen+5);
print_hex(abtTxBuf,szTxLen+5);
#endif
if (pdsa->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED)
{
if (SCardControl(pdsa->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtTxBuf,uiTxLen+5,abtRxBuf,ulRxBufLen,(void*)&ulRxBufLen) != SCARD_S_SUCCESS) return false;
if (SCardControl(pdsa->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtTxBuf,szTxLen+5,abtRxBuf,szRxBufLen,(void*)&szRxBufLen) != SCARD_S_SUCCESS) return false;
} else {
if (SCardTransmit(pdsa->hCard,&(pdsa->ioCard),abtTxBuf,uiTxLen+5,NULL,abtRxBuf,(void*)&ulRxBufLen) != SCARD_S_SUCCESS) return false;
if (SCardTransmit(pdsa->hCard,&(pdsa->ioCard),abtTxBuf,szTxLen+5,NULL,abtRxBuf,(void*)&szRxBufLen) != SCARD_S_SUCCESS) return false;
}
if (pdsa->ioCard.dwProtocol == SCARD_PROTOCOL_T0)
{
// Make sure we received the byte-count we expected
if (ulRxBufLen != 2) return false;
if (szRxBufLen != 2) return false;
// Check if the operation was successful, so an answer is available
if (*abtRxBuf == SCARD_OPERATION_ERROR) return false;
// Retrieve the response bytes
abtRxCmd[4] = abtRxBuf[1];
ulRxBufLen = sizeof(abtRxBuf);
if (SCardTransmit(pdsa->hCard,&(pdsa->ioCard),abtRxCmd,uiRxCmdLen,NULL,abtRxBuf,(void*)&ulRxBufLen) != SCARD_S_SUCCESS) return false;
szRxBufLen = sizeof(abtRxBuf);
if (SCardTransmit(pdsa->hCard,&(pdsa->ioCard),abtRxCmd,szRxCmdLen,NULL,abtRxBuf,(void*)&szRxBufLen) != SCARD_S_SUCCESS) return false;
}
#ifdef DEBUG
printf(" RX: ");
print_hex(abtRxBuf,ulRxBufLen);
print_hex(abtRxBuf,szRxBufLen);
#endif
// When the answer should be ignored, just return a succesful result
if (pbtRx == NULL || puiRxLen == NULL) return true;
if (pbtRx == NULL || pszRxLen == NULL) return true;
// Make sure we have an emulated answer that fits the return buffer
if (ulRxBufLen < 4 || (ulRxBufLen-4) > *puiRxLen) return false;
if (szRxBufLen < 4 || (szRxBufLen-4) > *pszRxLen) return false;
// Wipe out the 4 APDU emulation bytes: D5 4B .. .. .. 90 00
*puiRxLen = ((uint32_t)ulRxBufLen)-4;
memcpy(pbtRx,abtRxBuf+2,*puiRxLen);
*pszRxLen = ((uint32_t)szRxBufLen)-4;
memcpy(pbtRx,abtRxBuf+2,*pszRxLen);
// Transmission went successful
return true;
@ -238,13 +238,13 @@ char* dev_acr122_firmware(const dev_spec ds)
dev_spec_acr122* pdsa = (dev_spec_acr122*)ds;
static char abtFw[11];
size_t ulFwLen = sizeof(abtFw);
memset(abtFw,0x00,ulFwLen);
size_t szFwLen = sizeof(abtFw);
memset(abtFw,0x00,szFwLen);
if (pdsa->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED)
{
uiResult = SCardControl(pdsa->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtGetFw,sizeof(abtGetFw),abtFw,ulFwLen,(void*)&ulFwLen);
uiResult = SCardControl(pdsa->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtGetFw,sizeof(abtGetFw),abtFw,szFwLen,(void*)&szFwLen);
} else {
uiResult = SCardTransmit(pdsa->hCard,&(pdsa->ioCard),abtGetFw,sizeof(abtGetFw),NULL,(byte_t*)abtFw,(void*)&ulFwLen);
uiResult = SCardTransmit(pdsa->hCard,&(pdsa->ioCard),abtGetFw,sizeof(abtGetFw),NULL,(byte_t*)abtFw,(void*)&szFwLen);
}
#ifdef DEBUG
@ -262,12 +262,12 @@ bool dev_acr122_led_red(const dev_spec ds, bool bOn)
byte_t abtLed[9] = { 0xFF,0x00,0x40,0x05,0x04,0x00,0x00,0x00,0x00 };
dev_spec_acr122* pdsa = (dev_spec_acr122*)ds;
byte_t abtBuf[2];
size_t ulBufLen = sizeof(abtBuf);
size_t szBufLen = sizeof(abtBuf);
if (pdsa->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED)
{
return (SCardControl(pdsa->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtLed,sizeof(abtLed),abtBuf,ulBufLen,(void*)&ulBufLen) == SCARD_S_SUCCESS);
return (SCardControl(pdsa->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtLed,sizeof(abtLed),abtBuf,szBufLen,(void*)&szBufLen) == SCARD_S_SUCCESS);
} else {
return (SCardTransmit(pdsa->hCard,&(pdsa->ioCard),abtLed,sizeof(abtLed),NULL,(byte_t*)abtBuf,(void*)&ulBufLen) == SCARD_S_SUCCESS);
return (SCardTransmit(pdsa->hCard,&(pdsa->ioCard),abtLed,sizeof(abtLed),NULL,(byte_t*)abtBuf,(void*)&szBufLen) == SCARD_S_SUCCESS);
}
}

View file

@ -28,11 +28,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "types.h"
// Functions used by developer to handle connection to this device
dev_info* dev_acr122_connect(const nfc_device_desc_t* device_desc);
dev_info* dev_acr122_connect(const nfc_device_desc_t* pndd);
void dev_acr122_disconnect(dev_info* pdi);
// Callback function used by libnfc to transmit commands to the PN53X chip
bool dev_acr122_transceive(const dev_spec ds, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen);
bool dev_acr122_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
// Various additional features this device supports
char* dev_acr122_firmware(const dev_spec ds);

View file

@ -104,14 +104,14 @@ dev_info* dev_arygon_connect(const nfc_device_desc_t* pndd)
// Test if we have found a device
if (uiDevNr == MAX_DEVICES) return INVALID_DEVICE_INFO;
} else {
DBG("Connecting to: %s at %d bauds.",pndd->port, pndd->speed);
strcpy(acConnect,pndd->port);
DBG("Connecting to: %s at %d bauds.",pndd->pcPort, pndd->uiSpeed);
strcpy(acConnect,pndd->pcPort);
sp = rs232_open(acConnect);
if (sp == INVALID_SERIAL_PORT) ERR("Invalid serial port: %s",acConnect);
if (sp == CLAIMED_SERIAL_PORT) ERR("Serial port already claimed: %s",acConnect);
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return INVALID_DEVICE_INFO;
rs232_set_speed(sp, pndd->speed);
rs232_set_speed(sp, pndd->uiSpeed);
}
DBG("Successfully connected to: %s",acConnect);
@ -134,35 +134,35 @@ void dev_arygon_disconnect(dev_info* pdi)
free(pdi);
}
bool dev_arygon_transceive(const dev_spec ds, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen)
bool dev_arygon_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
{
byte_t abtTxBuf[BUFFER_LENGTH] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
byte_t abtRxBuf[BUFFER_LENGTH];
uint32_t uiRxBufLen = BUFFER_LENGTH;
uint32_t uiPos;
size_t szRxBufLen = BUFFER_LENGTH;
size_t szPos;
// Packet length = data length (len) + checksum (1) + end of stream marker (1)
abtTxBuf[4] = uiTxLen;
abtTxBuf[4] = szTxLen;
// Packet length checksum
abtTxBuf[5] = BUFFER_LENGTH - abtTxBuf[4];
// Copy the PN53X command into the packet buffer
memmove(abtTxBuf+6,pbtTx,uiTxLen);
memmove(abtTxBuf+6,pbtTx,szTxLen);
// Calculate data payload checksum
abtTxBuf[uiTxLen+6] = 0;
for(uiPos=0; uiPos < uiTxLen; uiPos++)
abtTxBuf[szTxLen+6] = 0;
for(szPos=0; szPos < szTxLen; szPos++)
{
abtTxBuf[uiTxLen+6] -= abtTxBuf[uiPos+6];
abtTxBuf[szTxLen+6] -= abtTxBuf[szPos+6];
}
// End of stream marker
abtTxBuf[uiTxLen+7] = 0;
abtTxBuf[szTxLen+7] = 0;
#ifdef DEBUG
printf(" TX: ");
print_hex(abtTxBuf,uiTxLen+8);
print_hex(abtTxBuf,szTxLen+8);
#endif
if (!rs232_send((serial_port)ds,abtTxBuf,uiTxLen+8)) {
if (!rs232_send((serial_port)ds,abtTxBuf,szTxLen+8)) {
ERR("Unable to transmit data. (TX)");
return false;
}
@ -182,25 +182,25 @@ bool dev_arygon_transceive(const dev_spec ds, const byte_t* pbtTx, const uint32_
* For more information, see Issue 23 on development site : http://code.google.com/p/libnfc/issues/detail?id=23
*/
if (!rs232_receive((serial_port)ds,abtRxBuf,&uiRxBufLen)) {
if (!rs232_receive((serial_port)ds,abtRxBuf,&szRxBufLen)) {
ERR("Unable to receive data. (RX)");
return false;
}
#ifdef DEBUG
printf(" RX: ");
print_hex(abtRxBuf,uiRxBufLen);
print_hex(abtRxBuf,szRxBufLen);
#endif
// When the answer should be ignored, just return a successful result
if(pbtRx == NULL || puiRxLen == NULL) return true;
if(pbtRx == NULL || pszRxLen == NULL) return true;
// Only succeed when the result is at least 00 00 ff 00 ff 00 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable)
if(uiRxBufLen < 15) return false;
if(szRxBufLen < 15) return false;
// Remove the preceding and appending bytes 00 00 ff 00 ff 00 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
*puiRxLen = uiRxBufLen - 15;
memcpy(pbtRx, abtRxBuf+13, *puiRxLen);
*pszRxLen = szRxBufLen - 15;
memcpy(pbtRx, abtRxBuf+13, *pszRxLen);
return true;
}

View file

@ -78,7 +78,7 @@ static void get_end_points(struct usb_device *dev, dev_spec_pn531* pdsp)
}
}
dev_info* dev_pn531_connect(const nfc_device_desc_t* device_desc)
dev_info* dev_pn531_connect(const nfc_device_desc_t* pndd)
{
int idvendor = 0x04CC;
int idproduct = 0x0531;
@ -100,10 +100,10 @@ dev_info* dev_pn531_connect(const nfc_device_desc_t* device_desc)
if (usb_find_devices() < 0) return INVALID_DEVICE_INFO;
// Initialize the device index we are seaching for
if( device_desc == NULL ) {
if( pndd == NULL ) {
uiDevIndex = 0;
} else {
uiDevIndex = device_desc->index;
uiDevIndex = pndd->uiIndex;
}
for (bus = usb_get_busses(); bus; bus = bus->next)
@ -169,50 +169,66 @@ void dev_pn531_disconnect(dev_info* pdi)
free(pdi);
}
bool dev_pn531_transceive(const dev_spec ds, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen)
bool dev_pn531_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
{
uint32_t uiPos = 0;
int ret = 0;
char abtTx[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
char abtRx[BUFFER_LENGTH];
dev_spec_pn531* pdsp = (dev_spec_pn531*)ds;
size_t uiPos = 0;
int ret = 0;
char abtTx[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
char abtRx[BUFFER_LENGTH];
dev_spec_pn531* pdsp = (dev_spec_pn531*)ds;
// Packet length = data length (len) + checksum (1) + end of stream marker (1)
abtTx[3] = uiTxLen;
// Packet length checksum
abtTx[4] = BUFFER_LENGTH - abtTx[3];
// Copy the PN53X command into the packet abtTx
memmove(abtTx+5,pbtTx,uiTxLen);
// Packet length = data length (len) + checksum (1) + end of stream marker (1)
abtTx[3] = szTxLen;
// Packet length checksum
abtTx[4] = BUFFER_LENGTH - abtTx[3];
// Copy the PN53X command into the packet abtTx
memmove(abtTx+5,pbtTx,szTxLen);
// Calculate data payload checksum
abtTx[uiTxLen+5] = 0;
for(uiPos=0; uiPos < uiTxLen; uiPos++)
{
abtTx[uiTxLen+5] -= abtTx[uiPos+5];
}
// Calculate data payload checksum
abtTx[szTxLen+5] = 0;
for(uiPos=0; uiPos < szTxLen; uiPos++)
{
abtTx[szTxLen+5] -= abtTx[uiPos+5];
}
// End of stream marker
abtTx[uiTxLen+6] = 0;
// End of stream marker
abtTx[szTxLen+6] = 0;
#ifdef DEBUG
printf("Tx: ");
print_hex((byte_t*)abtTx,szTxLen+7);
#endif
ret = usb_bulk_write(pdsp->pudh, pdsp->uiEndPointOut, abtTx, szTxLen+7, USB_TIMEOUT);
if( ret < 0 )
{
#ifdef DEBUG
printf("Tx: ");
print_hex((byte_t*)abtTx,uiTxLen+7);
printf("usb_bulk_write failed with error %d\n", ret);
#endif
return false;
}
ret = usb_bulk_write(pdsp->pudh, pdsp->uiEndPointOut, abtTx, uiTxLen+7, USB_TIMEOUT);
if( ret < 0 )
{
#ifdef DEBUG
printf("usb_bulk_write failed with error %d\n", ret);
#endif
return false;
}
ret = usb_bulk_read(pdsp->pudh, pdsp->uiEndPointIn, abtRx, BUFFER_LENGTH, USB_TIMEOUT);
if( ret < 0 )
{
#ifdef DEBUG
printf( "usb_bulk_read failed with error %d\n", ret);
#endif
return false;
}
#ifdef DEBUG
printf("Rx: ");
print_hex((byte_t*)abtRx,ret);
#endif
if( ret == 6 )
{
ret = usb_bulk_read(pdsp->pudh, pdsp->uiEndPointIn, abtRx, BUFFER_LENGTH, USB_TIMEOUT);
if( ret < 0 )
{
#ifdef DEBUG
printf( "usb_bulk_read failed with error %d\n", ret);
printf("usb_bulk_read failed with error %d\n", ret);
#endif
return false;
}
@ -221,33 +237,17 @@ bool dev_pn531_transceive(const dev_spec ds, const byte_t* pbtTx, const uint32_t
printf("Rx: ");
print_hex((byte_t*)abtRx,ret);
#endif
}
if( ret == 6 )
{
ret = usb_bulk_read(pdsp->pudh, pdsp->uiEndPointIn, abtRx, BUFFER_LENGTH, USB_TIMEOUT);
if( ret < 0 )
{
#ifdef DEBUG
printf("usb_bulk_read failed with error %d\n", ret);
#endif
return false;
}
// When the answer should be ignored, just return a succesful result
if(pbtRx == NULL || pszRxLen == NULL) return true;
#ifdef DEBUG
printf("Rx: ");
print_hex((byte_t*)abtRx,ret);
#endif
}
// Only succeed when the result is at least 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable)
if(ret < 9) return false;
// When the answer should be ignored, just return a succesful result
if(pbtRx == NULL || puiRxLen == NULL) return true;
// Remove the preceding and appending bytes 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
*pszRxLen = ret - 7 - 2;
memcpy( pbtRx, abtRx + 7, *pszRxLen);
// Only succeed when the result is at least 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable)
if(ret < 9) return false;
// Remove the preceding and appending bytes 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
*puiRxLen = ret - 7 - 2;
memcpy( pbtRx, abtRx + 7, *puiRxLen);
return true;
return true;
}

View file

@ -28,11 +28,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "types.h"
// Functions used by developer to handle connection to this device
dev_info* dev_pn531_connect(const nfc_device_desc_t* device_desc);
dev_info* dev_pn531_connect(const nfc_device_desc_t* pndd);
void dev_pn531_disconnect(dev_info* pdi);
// Callback function used by libnfc to transmit commands to the PN53X chip
bool dev_pn531_transceive(const dev_spec ds, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen);
bool dev_pn531_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
#endif // _LIBNFC_DEV_PN531_H_

View file

@ -76,7 +76,7 @@ static void get_end_points(struct usb_device *dev, dev_spec_pn533* pdsp)
}
}
dev_info* dev_pn533_connect(const nfc_device_desc_t* device_desc)
dev_info* dev_pn533_connect(const nfc_device_desc_t* pndd)
{
int idvendor = 0x04e6;
int idproduct = 0x5591;
@ -96,10 +96,10 @@ dev_info* dev_pn533_connect(const nfc_device_desc_t* device_desc)
if (usb_find_devices() < 0) return INVALID_DEVICE_INFO;
// Initialize the device index we are seaching for
if( device_desc == NULL ) {
if( pndd == NULL ) {
uiDevIndex = 0;
} else {
uiDevIndex = device_desc->index;
uiDevIndex = pndd->uiIndex;
}
for (bus = usb_get_busses(); bus; bus = bus->next)
@ -164,50 +164,66 @@ void dev_pn533_disconnect(dev_info* pdi)
free(pdi);
}
bool dev_pn533_transceive(const dev_spec ds, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen)
bool dev_pn533_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
{
uint32_t uiPos = 0;
int ret = 0;
char abtTx[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
char abtRx[BUFFER_LENGTH];
dev_spec_pn533* pdsp = (dev_spec_pn533*)ds;
size_t uiPos = 0;
int ret = 0;
char abtTx[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
char abtRx[BUFFER_LENGTH];
dev_spec_pn533* pdsp = (dev_spec_pn533*)ds;
// Packet length = data length (len) + checksum (1) + end of stream marker (1)
abtTx[3] = uiTxLen;
// Packet length checksum
abtTx[4] = BUFFER_LENGTH - abtTx[3];
// Copy the PN53X command into the packet abtTx
memmove(abtTx+5,pbtTx,uiTxLen);
// Packet length = data length (len) + checksum (1) + end of stream marker (1)
abtTx[3] = szTxLen;
// Packet length checksum
abtTx[4] = BUFFER_LENGTH - abtTx[3];
// Copy the PN53X command into the packet abtTx
memmove(abtTx+5,pbtTx,szTxLen);
// Calculate data payload checksum
abtTx[uiTxLen+5] = 0;
for(uiPos=0; uiPos < uiTxLen; uiPos++)
{
abtTx[uiTxLen+5] -= abtTx[uiPos+5];
}
// Calculate data payload checksum
abtTx[szTxLen+5] = 0;
for(uiPos=0; uiPos < szTxLen; uiPos++)
{
abtTx[szTxLen+5] -= abtTx[uiPos+5];
}
// End of stream marker
abtTx[uiTxLen+6] = 0;
// End of stream marker
abtTx[szTxLen+6] = 0;
#ifdef DEBUG
printf(" TX: ");
print_hex((byte_t*)abtTx,szTxLen+7);
#endif
ret = usb_bulk_write(pdsp->pudh, pdsp->uiEndPointOut, abtTx, szTxLen+7, USB_TIMEOUT);
if( ret < 0 )
{
#ifdef DEBUG
printf(" TX: ");
print_hex((byte_t*)abtTx,uiTxLen+7);
printf("usb_bulk_write failed with error %d\n", ret);
#endif
return false;
}
ret = usb_bulk_write(pdsp->pudh, pdsp->uiEndPointOut, abtTx, uiTxLen+7, USB_TIMEOUT);
if( ret < 0 )
{
#ifdef DEBUG
printf("usb_bulk_write failed with error %d\n", ret);
#endif
return false;
}
ret = usb_bulk_read(pdsp->pudh, pdsp->uiEndPointIn, abtRx, BUFFER_LENGTH, USB_TIMEOUT);
if( ret < 0 )
{
#ifdef DEBUG
printf( "usb_bulk_read failed with error %d\n", ret);
#endif
return false;
}
#ifdef DEBUG
printf(" RX: ");
print_hex((byte_t*)abtRx,ret);
#endif
if( ret == 6 )
{
ret = usb_bulk_read(pdsp->pudh, pdsp->uiEndPointIn, abtRx, BUFFER_LENGTH, USB_TIMEOUT);
if( ret < 0 )
{
#ifdef DEBUG
printf( "usb_bulk_read failed with error %d\n", ret);
printf("usb_bulk_read failed with error %d\n", ret);
#endif
return false;
}
@ -216,42 +232,26 @@ bool dev_pn533_transceive(const dev_spec ds, const byte_t* pbtTx, const uint32_t
printf(" RX: ");
print_hex((byte_t*)abtRx,ret);
#endif
}
if( ret == 6 )
{
ret = usb_bulk_read(pdsp->pudh, pdsp->uiEndPointIn, abtRx, BUFFER_LENGTH, USB_TIMEOUT);
if( ret < 0 )
{
#ifdef DEBUG
printf("usb_bulk_read failed with error %d\n", ret);
#endif
return false;
}
// When the answer should be ignored, just return a succesful result
if(pbtRx == NULL || pszRxLen == NULL) return true;
#ifdef DEBUG
printf(" RX: ");
print_hex((byte_t*)abtRx,ret);
#endif
}
// Only succeed when the result is at least 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable)
if(ret < 9) return false;
// When the answer should be ignored, just return a succesful result
if(pbtRx == NULL || puiRxLen == NULL) return true;
// Remove the preceding and appending bytes 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
*pszRxLen = ret - 7 - 2;
// Only succeed when the result is at least 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable)
if(ret < 9) return false;
// Get register: nuke extra byte (awful hack)
if ((abtRx[5]==(char)0xd5) && (abtRx[6]==(char)0x07) && (*pszRxLen==2)) {
// printf("Got %02x %02x, keep %02x\n", abtRx[7], abtRx[8], abtRx[8]);
*pszRxLen = (*pszRxLen) - 1;
memcpy( pbtRx, abtRx + 8, *pszRxLen);
return true;
}
// Remove the preceding and appending bytes 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
*puiRxLen = ret - 7 - 2;
memcpy( pbtRx, abtRx + 7, *pszRxLen);
// Get register: nuke extra byte (awful hack)
if ((abtRx[5]==(char)0xd5) && (abtRx[6]==(char)0x07) && (*puiRxLen==2)) {
// printf("Got %02x %02x, keep %02x\n", abtRx[7], abtRx[8], abtRx[8]);
*puiRxLen = (*puiRxLen) - 1;
memcpy( pbtRx, abtRx + 8, *puiRxLen);
return true;
}
memcpy( pbtRx, abtRx + 7, *puiRxLen);
return true;
return true;
}

View file

@ -25,11 +25,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "types.h"
// Functions used by developer to handle connection to this device
dev_info* dev_pn533_connect(const nfc_device_desc_t* device_desc);
dev_info* dev_pn533_connect(const nfc_device_desc_t* pndd);
void dev_pn533_disconnect(dev_info* pdi);
// Callback function used by libnfc to transmit commands to the PN53X chip
bool dev_pn533_transceive(const dev_spec ds, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen);
bool dev_pn533_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
#endif // _LIBNFC_DEV_PN533_H_

View file

@ -28,7 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "messages.h"
static byte_t abtRecv[MAX_FRAME_LEN];
static uint32_t uiRecvBits;
static size_t szRecvBits;
static dev_info* pdi;
// ISO14443A Anti-Collision response
@ -49,7 +49,7 @@ void print_usage(void)
int main(int argc, char *argv[])
{
byte_t* pbtTx = NULL;
uint32_t uiTxBits;
size_t szTxBits;
bool quiet_output = false;
int arg, i;
@ -93,13 +93,13 @@ int main(int argc, char *argv[])
printf("[+] Try to break out the auto-emulation, this requires a second reader!\n");
printf("[+] To do this, please send any command after the anti-collision\n");
printf("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
if (!nfc_target_init(pdi,abtRecv,&uiRecvBits))
if (!nfc_target_init(pdi,abtRecv,&szRecvBits))
{
printf("Error: Could not come out of auto-emulation, no command was received\n");
return 1;
}
printf("[+] Received initiator command: ");
print_hex_bits(abtRecv,uiRecvBits);
print_hex_bits(abtRecv,szRecvBits);
printf("[+] Configuring communication\n");
nfc_configure(pdi,DCO_HANDLE_CRC,false);
nfc_configure(pdi,DCO_HANDLE_PARITY,true);
@ -108,48 +108,48 @@ int main(int argc, char *argv[])
while(true)
{
// Test if we received a frame
if (nfc_target_receive_bits(pdi,abtRecv,&uiRecvBits,NULL))
if (nfc_target_receive_bits(pdi,abtRecv,&szRecvBits,NULL))
{
// Prepare the command to send back for the anti-collision request
switch(uiRecvBits)
switch(szRecvBits)
{
case 7: // Request or Wakeup
pbtTx = abtAtqa;
uiTxBits = 16;
szTxBits = 16;
// New anti-collsion session started
if (!quiet_output) printf("\n");
break;
case 16: // Select All
pbtTx = abtUidBcc;
uiTxBits = 40;
szTxBits = 40;
break;
case 72: // Select Tag
pbtTx = abtSak;
uiTxBits = 24;
szTxBits = 24;
break;
default: // unknown length?
uiTxBits = 0;
szTxBits = 0;
break;
}
if(!quiet_output)
{
printf("R: ");
print_hex_bits(abtRecv,uiRecvBits);
print_hex_bits(abtRecv,szRecvBits);
}
// Test if we know how to respond
if(uiTxBits)
if(szTxBits)
{
// Send and print the command to the screen
nfc_target_send_bits(pdi,pbtTx,uiTxBits,NULL);
nfc_target_send_bits(pdi,pbtTx,szTxBits,NULL);
if(!quiet_output)
{
printf("T: ");
print_hex_bits(pbtTx,uiTxBits);
print_hex_bits(pbtTx,szTxBits);
}
}
}

View file

@ -7,7 +7,7 @@ int main(int argc, const char *argv[])
dev_info *pdi;
tag_info ti;
byte_t abtRecv[MAX_FRAME_LEN];
uint32_t uiRecvBits;
size_t szRecvBits;
byte_t send[] = "Hello World!";
pdi = nfc_connect(NULL);
@ -23,12 +23,12 @@ int main(int argc, const char *argv[])
if (!nfc_initiator_transceive_dep_bytes(pdi,
send,
strlen(send), abtRecv,
&uiRecvBits)) {
&szRecvBits)) {
printf("unable to send data\n");
return 1;
}
abtRecv[uiRecvBits] = 0;
abtRecv[szRecvBits] = 0;
printf("Received: %s\n", abtRecv);
nfc_initiator_deselect_tag(pdi);

View file

@ -97,21 +97,21 @@ const byte_t pncmd_target_receive [ 2] = { 0xD4,0x88 };
const byte_t pncmd_target_send [264] = { 0xD4,0x90 };
const byte_t pncmd_target_get_status [ 2] = { 0xD4,0x8A };
bool pn53x_transceive(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen)
bool pn53x_transceive(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
{
byte_t abtRx[MAX_FRAME_LEN];
uint32_t uiRxLen;
size_t szRxLen;
// Check if receiving buffers are available, if not, replace them
if (!puiRxLen || !pbtRx)
if (!pszRxLen || !pbtRx)
{
pbtRx = abtRx;
puiRxLen = &uiRxLen;
pszRxLen = &szRxLen;
}
*puiRxLen = MAX_FRAME_LEN;
*pszRxLen = MAX_FRAME_LEN;
// Call the tranceive callback function of the current device
if (!pdi->pdc->transceive(pdi->ds,pbtTx,uiTxLen,pbtRx,puiRxLen)) return false;
if (!pdi->pdc->transceive(pdi->ds,pbtTx,szTxLen,pbtRx,pszRxLen)) return false;
// Make sure there was no failure reported by the PN53X chip (0x00 == OK)
if (pbtRx[0] != 0) return false;
@ -123,14 +123,14 @@ bool pn53x_transceive(const dev_info* pdi, const byte_t* pbtTx, const uint32_t u
byte_t pn53x_get_reg(const dev_info* pdi, uint16_t ui16Reg)
{
uint8_t ui8Value;
uint32_t uiValueLen = 1;
size_t szValueLen = 1;
byte_t abtCmd[sizeof(pncmd_get_register)];
memcpy(abtCmd,pncmd_get_register,sizeof(pncmd_get_register));
abtCmd[2] = ui16Reg >> 8;
abtCmd[3] = ui16Reg & 0xff;
// We can not use pn53x_transceive() because abtRx[0] gives no status info
pdi->pdc->transceive(pdi->ds,abtCmd,4,&ui8Value,&uiValueLen);
pdi->pdc->transceive(pdi->ds,abtCmd,4,&ui8Value,&szValueLen);
return ui8Value;
}
@ -170,27 +170,27 @@ bool pn53x_set_tx_bits(const dev_info* pdi, uint8_t ui8Bits)
return true;
}
bool pn53x_wrap_frame(const byte_t* pbtTx, const uint32_t uiTxBits, const byte_t* pbtTxPar, byte_t* pbtFrame, uint32_t* puiFrameBits)
bool pn53x_wrap_frame(const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtFrame, size_t* pszFrameBits)
{
byte_t btFrame;
byte_t btData;
uint32_t uiBitPos;
uint32_t uiDataPos = 0;
uint32_t uiBitsLeft = uiTxBits;
size_t szBitsLeft = szTxBits;
// Make sure we should frame at least something
if (uiBitsLeft == 0) return false;
if (szBitsLeft == 0) return false;
// Handle a short response (1byte) as a special case
if (uiBitsLeft < 9)
if (szBitsLeft < 9)
{
*pbtFrame = *pbtTx;
*puiFrameBits = uiTxBits;
*pszFrameBits = szTxBits;
return true;
}
// We start by calculating the frame length in bits
*puiFrameBits = uiTxBits + (uiTxBits/8);
*pszFrameBits = szTxBits + (szTxBits/8);
// Parse the data bytes and add the parity bits
// This is really a sensitive process, mirror the frame bytes and append parity bits
@ -218,36 +218,36 @@ bool pn53x_wrap_frame(const byte_t* pbtTx, const uint32_t uiTxBits, const byte_t
// Increase the data (without parity bit) position
uiDataPos++;
// Test if we are done
if (uiBitsLeft < 9) return true;
uiBitsLeft -= 8;
if (szBitsLeft < 9) return true;
szBitsLeft -= 8;
}
// Every 8 data bytes we lose one frame byte to the parities
pbtFrame++;
}
}
bool pn53x_unwrap_frame(const byte_t* pbtFrame, const uint32_t uiFrameBits, byte_t* pbtRx, uint32_t* puiRxBits, byte_t* pbtRxPar)
bool pn53x_unwrap_frame(const byte_t* pbtFrame, const size_t szFrameBits, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
{
byte_t btFrame;
byte_t btData;
uint8_t uiBitPos;
uint32_t uiDataPos = 0;
byte_t* pbtFramePos = (byte_t*) pbtFrame;
uint32_t uiBitsLeft = uiFrameBits;
size_t szBitsLeft = szFrameBits;
// Make sure we should frame at least something
if (uiBitsLeft == 0) return false;
if (szBitsLeft == 0) return false;
// Handle a short response (1byte) as a special case
if (uiBitsLeft < 9)
if (szBitsLeft < 9)
{
*pbtRx = *pbtFrame;
*puiRxBits = uiFrameBits;
*pszRxBits = szFrameBits;
return true;
}
// Calculate the data length in bits
*puiRxBits = uiFrameBits - (uiFrameBits/9);
*pszRxBits = szFrameBits - (szFrameBits/9);
// Parse the frame bytes, remove the parity bits and store them in the parity array
// This process is the reverse of WrapFrame(), look there for more info
@ -264,36 +264,36 @@ bool pn53x_unwrap_frame(const byte_t* pbtFrame, const uint32_t uiFrameBits, byte
// Increase the data (without parity bit) position
uiDataPos++;
// Test if we are done
if (uiBitsLeft < 9) return true;
uiBitsLeft -= 9;
if (szBitsLeft < 9) return true;
szBitsLeft -= 9;
}
// Every 8 data bytes we lose one frame byte to the parities
pbtFramePos++;
}
}
dev_info* nfc_connect(nfc_device_desc_t* device_desc)
dev_info* nfc_connect(nfc_device_desc_t* pndd)
{
dev_info* pdi;
uint32_t uiDev;
byte_t abtFw[4];
uint32_t uiFwLen = sizeof(abtFw);
size_t szFwLen = sizeof(abtFw);
// Search through the device list for an available device
for (uiDev=0; uiDev<sizeof(dev_callbacks_list)/sizeof(dev_callbacks_list[0]); uiDev++)
{
if (device_desc == NULL) {
if (pndd == NULL) {
// No device description specified: try to automatically claim a device
pdi = dev_callbacks_list[uiDev].connect(device_desc);
pdi = dev_callbacks_list[uiDev].connect(pndd);
} else {
// Specific device is requested: using device description device_desc
if( 0 != strcmp(dev_callbacks_list[uiDev].acDriver, device_desc->driver ) )
// Specific device is requested: using device description pndd
if( 0 != strcmp(dev_callbacks_list[uiDev].acDriver, pndd->pcDriver ) )
{
DBG("Looking for %s, found %s... Skip it.", device_desc->driver, dev_callbacks_list[uiDev].acDriver);
DBG("Looking for %s, found %s... Skip it.", pndd->pcDriver, dev_callbacks_list[uiDev].acDriver);
continue;
} else {
DBG("Looking for %s, found %s... Use it.", device_desc->driver, dev_callbacks_list[uiDev].acDriver);
pdi = dev_callbacks_list[uiDev].connect(device_desc);
DBG("Looking for %s, found %s... Use it.", pndd->pcDriver, dev_callbacks_list[uiDev].acDriver);
pdi = dev_callbacks_list[uiDev].connect(pndd);
}
}
@ -306,7 +306,7 @@ dev_info* nfc_connect(nfc_device_desc_t* device_desc)
// Try to retrieve PN53x chip revision
// We can not use pn53x_transceive() because abtRx[0] gives no status info
if (!pdi->pdc->transceive(pdi->ds,pncmd_get_firmware_version,2,abtFw,&uiFwLen))
if (!pdi->pdc->transceive(pdi->ds,pncmd_get_firmware_version,2,abtFw,&szFwLen))
{
// Failed to get firmware revision??, whatever...let's disconnect and clean up and return err
ERR("Failed to get firmware revision for: %s", pdi->acName);
@ -354,7 +354,7 @@ bool nfc_configure(dev_info* pdi, const dev_config_option dco, const bool bEnabl
byte_t btValue;
byte_t abtCmd[sizeof(pncmd_rf_configure)];
memcpy(abtCmd,pncmd_rf_configure,sizeof(pncmd_rf_configure));
// Make sure we are dealing with a active device
if (!pdi->bActive) return false;
@ -410,7 +410,7 @@ bool nfc_configure(dev_info* pdi, const dev_config_option dco, const bool bEnabl
break;
}
// When we reach this, the configuration is completed and succesful
return true;
}
@ -429,14 +429,14 @@ bool nfc_initiator_init(const dev_info* pdi)
return true;
}
bool nfc_initiator_select_dep_target(const dev_info* pdi, const init_modulation im, const byte_t* pbtPidData, const uint32_t uiPidDataLen, const byte_t* pbtNFCID3i, const uint32_t uiNFCID3iDataLen, const byte_t *pbtGbData, const uint32_t uiGbDataLen, tag_info* pti)
bool nfc_initiator_select_dep_target(const dev_info* pdi, const init_modulation im, const byte_t* pbtPidData, const size_t szPidDataLen, const byte_t* pbtNFCID3i, const size_t szNFCID3iDataLen, const byte_t *pbtGbData, const size_t szGbDataLen, tag_info* pti)
{
byte_t abtRx[MAX_FRAME_LEN];
uint32_t uiRxLen;
uint32_t offset;
size_t szRxLen;
size_t offset;
byte_t abtCmd[sizeof(pncmd_initiator_jump_for_dep)];
memcpy(abtCmd,pncmd_initiator_jump_for_dep,sizeof(pncmd_initiator_jump_for_dep));
if(im == IM_ACTIVE_DEP) {
abtCmd[2] = 0x01; /* active DEP */
}
@ -445,24 +445,24 @@ bool nfc_initiator_select_dep_target(const dev_info* pdi, const init_modulation
offset = 5;
if(pbtPidData && im != IM_ACTIVE_DEP) { /* can't have passive initiator data when using active mode */
abtCmd[4] |= 0x01;
memcpy(abtCmd+offset,pbtPidData,uiPidDataLen);
offset+= uiPidDataLen;
}
memcpy(abtCmd+offset,pbtPidData,szPidDataLen);
offset+= szPidDataLen;
}
if(pbtNFCID3i) {
abtCmd[4] |= 0x02;
memcpy(abtCmd+offset,pbtNFCID3i,uiNFCID3iDataLen);
offset+= uiNFCID3iDataLen;
memcpy(abtCmd+offset,pbtNFCID3i,szNFCID3iDataLen);
offset+= szNFCID3iDataLen;
}
if(pbtGbData) {
abtCmd[4] |= 0x04;
memcpy(abtCmd+offset,pbtGbData,uiGbDataLen);
offset+= uiGbDataLen;
memcpy(abtCmd+offset,pbtGbData,szGbDataLen);
offset+= szGbDataLen;
}
// Try to find a target, call the transceive callback function of the current device
if (!pn53x_transceive(pdi,abtCmd,5+uiPidDataLen+uiNFCID3iDataLen+uiGbDataLen,abtRx,&uiRxLen)) return false;
if (!pn53x_transceive(pdi,abtCmd,5+szPidDataLen+szNFCID3iDataLen+szGbDataLen,abtRx,&szRxLen)) return false;
// Make sure one target has been found, the PN53X returns 0x00 if none was available
if (abtRx[1] != 1) return false;
@ -478,13 +478,13 @@ bool nfc_initiator_select_dep_target(const dev_info* pdi, const init_modulation
return true;
}
bool nfc_initiator_select_tag(const dev_info* pdi, const init_modulation im, const byte_t* pbtInitData, const uint32_t uiInitDataLen, tag_info* pti)
bool nfc_initiator_select_tag(const dev_info* pdi, const init_modulation im, const byte_t* pbtInitData, const size_t szInitDataLen, tag_info* pti)
{
byte_t abtRx[MAX_FRAME_LEN];
uint32_t uiRxLen;
size_t szRxLen;
byte_t abtCmd[sizeof(pncmd_initiator_list_passive)];
memcpy(abtCmd,pncmd_initiator_list_passive,sizeof(pncmd_initiator_list_passive));
// Make sure we are dealing with a active device
if (!pdi->bActive) return false;
@ -492,16 +492,16 @@ bool nfc_initiator_select_tag(const dev_info* pdi, const init_modulation im, con
abtCmd[3] = im; // BrTy, the type of init modulation used for polling a passive tag
// Set the optional initiator data (used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID).
if (pbtInitData) memcpy(abtCmd+4,pbtInitData,uiInitDataLen);
if (pbtInitData) memcpy(abtCmd+4,pbtInitData,szInitDataLen);
// Try to find a tag, call the tranceive callback function of the current device
uiRxLen = MAX_FRAME_LEN;
szRxLen = MAX_FRAME_LEN;
// We can not use pn53x_transceive() because abtRx[0] gives no status info
if (!pdi->pdc->transceive(pdi->ds,abtCmd,4+uiInitDataLen,abtRx,&uiRxLen)) return false;
if (!pdi->pdc->transceive(pdi->ds,abtCmd,4+szInitDataLen,abtRx,&szRxLen)) return false;
// Make sure one tag has been found, the PN53X returns 0x00 if none was available
if (abtRx[0] != 1) return false;
// Is a tag info struct available
if (pti)
{
@ -519,29 +519,29 @@ bool nfc_initiator_select_tag(const dev_info* pdi, const init_modulation im, con
}
pti->tia.btSak = abtRx[4];
// Copy the NFCID1
pti->tia.uiUidLen = abtRx[5];
memcpy(pti->tia.abtUid,abtRx+6,pti->tia.uiUidLen);
pti->tia.szUidLen = abtRx[5];
memcpy(pti->tia.abtUid,abtRx+6,pti->tia.szUidLen);
// Did we received an optional ATS (Smardcard ATR)
if (uiRxLen > pti->tia.uiUidLen+6)
if (szRxLen > pti->tia.szUidLen+6)
{
pti->tia.uiAtsLen = abtRx[pti->tia.uiUidLen+6];
memcpy(pti->tia.abtAts,abtRx+pti->tia.uiUidLen+6,pti->tia.uiAtsLen);
pti->tia.szAtsLen = abtRx[pti->tia.szUidLen+6];
memcpy(pti->tia.abtAts,abtRx+pti->tia.szUidLen+6,pti->tia.szAtsLen);
} else {
pti->tia.uiAtsLen = 0;
pti->tia.szAtsLen = 0;
}
break;
case IM_FELICA_212:
case IM_FELICA_424:
// Store the mandatory info
pti->tif.uiLen = abtRx[2];
pti->tif.szLen = abtRx[2];
pti->tif.btResCode = abtRx[3];
// Copy the NFCID2t
memcpy(pti->tif.abtId,abtRx+4,8);
// Copy the felica padding
memcpy(pti->tif.abtPad,abtRx+12,8);
// Test if the System code (SYST_CODE) is available
if (uiRxLen > 20)
if (szRxLen > 20)
{
memcpy(pti->tif.abtSysCode,abtRx+20,2);
}
@ -557,12 +557,12 @@ bool nfc_initiator_select_tag(const dev_info* pdi, const init_modulation im, con
pti->tib.btParam3 = abtRx[21];
pti->tib.btParam4 = abtRx[22];
// Test if the Higher layer (INF) is available
if (uiRxLen > 22)
if (szRxLen > 22)
{
pti->tib.uiInfLen = abtRx[23];
memcpy(pti->tib.abtInf,abtRx+24,pti->tib.uiInfLen);
pti->tib.szInfLen = abtRx[23];
memcpy(pti->tib.abtInf,abtRx+24,pti->tib.szInfLen);
} else {
pti->tib.uiInfLen = 0;
pti->tib.szInfLen = 0;
}
break;
@ -585,120 +585,120 @@ bool nfc_initiator_deselect_tag(const dev_info* pdi)
return (pn53x_transceive(pdi,pncmd_initiator_deselect,3,NULL,NULL));
}
bool nfc_initiator_transceive_bits(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, uint32_t* puiRxBits, byte_t* pbtRxPar)
bool nfc_initiator_transceive_bits(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
{
byte_t abtRx[MAX_FRAME_LEN];
uint32_t uiRxLen;
uint32_t uiFrameBits = 0;
uint32_t uiFrameBytes = 0;
size_t szRxLen;
size_t szFrameBits = 0;
size_t szFrameBytes = 0;
uint8_t ui8Bits = 0;
byte_t abtCmd[sizeof(pncmd_initiator_exchange_raw_data)];
memcpy(abtCmd,pncmd_initiator_exchange_raw_data,sizeof(pncmd_initiator_exchange_raw_data));
// Check if we should prepare the parity bits ourself
if (!pdi->bPar)
{
// Convert data with parity to a frame
pn53x_wrap_frame(pbtTx,uiTxBits,pbtTxPar,abtCmd+2,&uiFrameBits);
pn53x_wrap_frame(pbtTx,szTxBits,pbtTxPar,abtCmd+2,&szFrameBits);
} else {
uiFrameBits = uiTxBits;
szFrameBits = szTxBits;
}
// Retrieve the leading bits
ui8Bits = uiFrameBits%8;
ui8Bits = szFrameBits%8;
// Get the amount of frame bytes + optional (1 byte if there are leading bits)
uiFrameBytes = (uiFrameBits/8)+((ui8Bits==0)?0:1);
szFrameBytes = (szFrameBits/8)+((ui8Bits==0)?0:1);
// When the parity is handled before us, we just copy the data
if (pdi->bPar) memcpy(abtCmd+2,pbtTx,uiFrameBytes);
if (pdi->bPar) memcpy(abtCmd+2,pbtTx,szFrameBytes);
// Set the amount of transmission bits in the PN53X chip register
if (!pn53x_set_tx_bits(pdi,ui8Bits)) return false;
// Send the frame to the PN53X chip and get the answer
// We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
if (!pn53x_transceive(pdi,abtCmd,uiFrameBytes+2,abtRx,&uiRxLen)) return false;
if (!pn53x_transceive(pdi,abtCmd,szFrameBytes+2,abtRx,&szRxLen)) return false;
// Get the last bit-count that is stored in the received byte
ui8Bits = pn53x_get_reg(pdi,REG_CIU_CONTROL) & SYMBOL_RX_LAST_BITS;
// Recover the real frame length in bits
uiFrameBits = ((uiRxLen-1-((ui8Bits==0)?0:1))*8)+ui8Bits;
szFrameBits = ((szRxLen-1-((ui8Bits==0)?0:1))*8)+ui8Bits;
// Ignore the status byte from the PN53X here, it was checked earlier in pn53x_transceive()
// Check if we should recover the parity bits ourself
if (!pdi->bPar)
{
// Unwrap the response frame
pn53x_unwrap_frame(abtRx+1,uiFrameBits,pbtRx,puiRxBits,pbtRxPar);
pn53x_unwrap_frame(abtRx+1,szFrameBits,pbtRx,pszRxBits,pbtRxPar);
} else {
// Save the received bits
*puiRxBits = uiFrameBits;
*pszRxBits = szFrameBits;
// Copy the received bytes
memcpy(pbtRx,abtRx+1,uiRxLen-1);
memcpy(pbtRx,abtRx+1,szRxLen-1);
}
// Everything went successful
return true;
}
bool nfc_initiator_transceive_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen)
bool nfc_initiator_transceive_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
{
byte_t abtRx[MAX_FRAME_LEN];
uint32_t uiRxLen;
size_t szRxLen;
byte_t abtCmd[sizeof(pncmd_initiator_exchange_data)];
memcpy(abtCmd,pncmd_initiator_exchange_data,sizeof(pncmd_initiator_exchange_data));
// We can not just send bytes without parity if while the PN53X expects we handled them
if (!pdi->bPar) return false;
// Copy the data into the command frame
abtCmd[2] = 1; /* target number */
memcpy(abtCmd+3,pbtTx,uiTxLen);
memcpy(abtCmd+3,pbtTx,szTxLen);
// To transfer command frames bytes we can not have any leading bits, reset this to zero
if (!pn53x_set_tx_bits(pdi,0)) return false;
// Send the frame to the PN53X chip and get the answer
// We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
if (!pn53x_transceive(pdi,abtCmd,uiTxLen+3,abtRx,&uiRxLen)) return false;
if (!pn53x_transceive(pdi,abtCmd,szTxLen+3,abtRx,&szRxLen)) return false;
// Save the received byte count
*puiRxLen = uiRxLen-1;
*pszRxLen = szRxLen-1;
// Copy the received bytes
memcpy(pbtRx,abtRx+1,*puiRxLen);
memcpy(pbtRx,abtRx+1,*pszRxLen);
// Everything went successful
return true;
}
bool nfc_initiator_transceive_bytes(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen)
bool nfc_initiator_transceive_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
{
byte_t abtRx[MAX_FRAME_LEN];
uint32_t uiRxLen;
size_t szRxLen;
byte_t abtCmd[sizeof(pncmd_initiator_exchange_raw_data)];
memcpy(abtCmd,pncmd_initiator_exchange_raw_data,sizeof(pncmd_initiator_exchange_raw_data));
// We can not just send bytes without parity if while the PN53X expects we handled them
if (!pdi->bPar) return false;
// Copy the data into the command frame
memcpy(abtCmd+2,pbtTx,uiTxLen);
memcpy(abtCmd+2,pbtTx,szTxLen);
// To transfer command frames bytes we can not have any leading bits, reset this to zero
if (!pn53x_set_tx_bits(pdi,0)) return false;
// Send the frame to the PN53X chip and get the answer
// We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
if (!pn53x_transceive(pdi,abtCmd,uiTxLen+2,abtRx,&uiRxLen)) return false;
if (!pn53x_transceive(pdi,abtCmd,szTxLen+2,abtRx,&szRxLen)) return false;
// Save the received byte count
*puiRxLen = uiRxLen-1;
*pszRxLen = szRxLen-1;
// Copy the received bytes
memcpy(pbtRx,abtRx+1,*puiRxLen);
memcpy(pbtRx,abtRx+1,*pszRxLen);
// Everything went successful
return true;
@ -707,42 +707,42 @@ bool nfc_initiator_transceive_bytes(const dev_info* pdi, const byte_t* pbtTx, co
bool nfc_initiator_mifare_cmd(const dev_info* pdi, const mifare_cmd mc, const uint8_t ui8Block, mifare_param* pmp)
{
byte_t abtRx[MAX_FRAME_LEN];
uint32_t uiRxLen;
uint32_t uiParamLen;
size_t szRxLen;
size_t szParamLen;
byte_t abtCmd[sizeof(pncmd_initiator_exchange_data)];
memcpy(abtCmd,pncmd_initiator_exchange_data,sizeof(pncmd_initiator_exchange_data));
// Make sure we are dealing with a active device
// Make sure we are dealing with a active device
if (!pdi->bActive) return false;
abtCmd[2] = 0x01; // Use first target/card
abtCmd[3] = mc; // The MIFARE Classic command
abtCmd[4] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff)
switch (mc)
{
// Read and store command have no parameter
case MC_READ:
case MC_STORE:
uiParamLen = 0;
szParamLen = 0;
break;
// Authenticate command
case MC_AUTH_A:
case MC_AUTH_B:
uiParamLen = sizeof(mifare_param_auth);
szParamLen = sizeof(mifare_param_auth);
break;
// Data command
case MC_WRITE:
uiParamLen = sizeof(mifare_param_data);
szParamLen = sizeof(mifare_param_data);
break;
// Value command
case MC_DECREMENT:
case MC_INCREMENT:
case MC_TRANSFER:
uiParamLen = sizeof(mifare_param_value);
szParamLen = sizeof(mifare_param_value);
break;
// Please fix your code, you never should reach this statement
@ -750,46 +750,46 @@ bool nfc_initiator_mifare_cmd(const dev_info* pdi, const mifare_cmd mc, const ui
return false;
break;
}
// When available, copy the parameter bytes
if (uiParamLen) memcpy(abtCmd+5,(byte_t*)pmp,uiParamLen);
if (szParamLen) memcpy(abtCmd+5,(byte_t*)pmp,szParamLen);
// Fire the mifare command
if (!pn53x_transceive(pdi,abtCmd,5+uiParamLen,abtRx,&uiRxLen)) return false;
if (!pn53x_transceive(pdi,abtCmd,5+szParamLen,abtRx,&szRxLen)) return false;
// When we have executed a read command, copy the received bytes into the param
if (mc == MC_READ && uiRxLen == 17) memcpy(pmp->mpd.abtData,abtRx+1,16);
if (mc == MC_READ && szRxLen == 17) memcpy(pmp->mpd.abtData,abtRx+1,16);
// Command succesfully executed
return true;
}
bool nfc_target_init(const dev_info* pdi, byte_t* pbtRx, uint32_t* puiRxBits)
bool nfc_target_init(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxBits)
{
byte_t abtRx[MAX_FRAME_LEN];
uint32_t uiRxLen;
size_t szRxLen;
uint8_t ui8Bits;
// Save the current configuration settings
bool bCrc = pdi->bCrc;
bool bPar = pdi->bPar;
bool bPar = pdi->bPar;
byte_t abtCmd[sizeof(pncmd_target_init)];
memcpy(abtCmd,pncmd_target_init,sizeof(pncmd_target_init));
// Clear the target init struct, reset to all zeros
memset(abtCmd+2,0x00,37);
// Set ATQA (SENS_RES)
abtCmd[3] = 0x04;
abtCmd[4] = 0x00;
// Set ATQA (SENS_RES)
abtCmd[3] = 0x04;
abtCmd[4] = 0x00;
// Set SAK (SEL_RES)
// Set SAK (SEL_RES)
abtCmd[8] = 0x20;
// Set UID
abtCmd[5] = 0x00;
abtCmd[6] = 0xb0;
abtCmd[7] = 0x0b;
// Set UID
abtCmd[5] = 0x00;
abtCmd[6] = 0xb0;
abtCmd[7] = 0x0b;
// Make sure the CRC & parity are handled by the device, this is needed for target_init to work properly
if (!bCrc) nfc_configure((dev_info*)pdi,DCO_HANDLE_CRC,true);
if (!bPar) nfc_configure((dev_info*)pdi,DCO_HANDLE_CRC,true);
@ -799,16 +799,16 @@ bool nfc_target_init(const dev_info* pdi, byte_t* pbtRx, uint32_t* puiRxBits)
// Request the initialization as a target, we can not use pn53x_transceive() because
// abtRx[0] contains the emulation mode (baudrate, 14443-4?, DEP and framing type)
uiRxLen = MAX_FRAME_LEN;
if (!pdi->pdc->transceive(pdi->ds,abtCmd,39,abtRx,&uiRxLen)) return false;
szRxLen = MAX_FRAME_LEN;
if (!pdi->pdc->transceive(pdi->ds,abtCmd,39,abtRx,&szRxLen)) return false;
// Get the last bit-count that is stored in the received byte
ui8Bits = pn53x_get_reg(pdi,REG_CIU_CONTROL) & SYMBOL_RX_LAST_BITS;
// We are sure the parity is handled by the PN53X chip, so we handle it this way
*puiRxBits = ((uiRxLen-1-((ui8Bits==0)?0:1))*8)+ui8Bits;
*pszRxBits = ((szRxLen-1-((ui8Bits==0)?0:1))*8)+ui8Bits;
// Copy the received bytes
memcpy(pbtRx,abtRx+1,uiRxLen-1);
memcpy(pbtRx,abtRx+1,szRxLen-1);
// Restore the CRC & parity setting to the original value (if needed)
if (!bCrc) nfc_configure((dev_info*)pdi,DCO_HANDLE_CRC,false);
@ -817,142 +817,142 @@ bool nfc_target_init(const dev_info* pdi, byte_t* pbtRx, uint32_t* puiRxBits)
return true;
}
bool nfc_target_receive_bits(const dev_info* pdi, byte_t* pbtRx, uint32_t* puiRxBits, byte_t* pbtRxPar)
bool nfc_target_receive_bits(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
{
byte_t abtRx[MAX_FRAME_LEN];
uint32_t uiRxLen;
uint32_t uiFrameBits;
size_t szRxLen;
size_t szFrameBits;
uint8_t ui8Bits;
// Try to gather a received frame from the reader
if (!pn53x_transceive(pdi,pncmd_target_receive,2,abtRx,&uiRxLen)) return false;
// Try to gather a received frame from the reader
if (!pn53x_transceive(pdi,pncmd_target_receive,2,abtRx,&szRxLen)) return false;
// Get the last bit-count that is stored in the received byte
ui8Bits = pn53x_get_reg(pdi,REG_CIU_CONTROL) & SYMBOL_RX_LAST_BITS;
// Recover the real frame length in bits
uiFrameBits = ((uiRxLen-1-((ui8Bits==0)?0:1))*8)+ui8Bits;
szFrameBits = ((szRxLen-1-((ui8Bits==0)?0:1))*8)+ui8Bits;
// Ignore the status byte from the PN53X here, it was checked earlier in pn53x_transceive()
// Check if we should recover the parity bits ourself
if (!pdi->bPar)
{
// Unwrap the response frame
pn53x_unwrap_frame(abtRx+1,uiFrameBits,pbtRx,puiRxBits,pbtRxPar);
pn53x_unwrap_frame(abtRx+1,szFrameBits,pbtRx,pszRxBits,pbtRxPar);
} else {
// Save the received bits
*puiRxBits = uiFrameBits;
*pszRxBits = szFrameBits;
// Copy the received bytes
memcpy(pbtRx,abtRx+1,uiRxLen-1);
memcpy(pbtRx,abtRx+1,szRxLen-1);
}
// Everyting seems ok, return true
return true;
return true;
}
bool nfc_target_receive_dep_bytes(const dev_info* pdi, byte_t* pbtRx, uint32_t* puiRxLen)
bool nfc_target_receive_dep_bytes(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxLen)
{
byte_t abtRx[MAX_FRAME_LEN];
uint32_t uiRxLen;
size_t szRxLen;
// Try to gather a received frame from the reader
if (!pn53x_transceive(pdi,pncmd_target_get_data,2,abtRx,&uiRxLen)) return false;
// Try to gather a received frame from the reader
if (!pn53x_transceive(pdi,pncmd_target_get_data,2,abtRx,&szRxLen)) return false;
// Save the received byte count
*puiRxLen = uiRxLen-1;
*pszRxLen = szRxLen-1;
// Copy the received bytes
memcpy(pbtRx,abtRx+1,*puiRxLen);
memcpy(pbtRx,abtRx+1,*pszRxLen);
// Everyting seems ok, return true
return true;
}
bool nfc_target_receive_bytes(const dev_info* pdi, byte_t* pbtRx, uint32_t* puiRxLen)
bool nfc_target_receive_bytes(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxLen)
{
byte_t abtRx[MAX_FRAME_LEN];
uint32_t uiRxLen;
uint32_t szRxLen;
// Try to gather a received frame from the reader
if (!pn53x_transceive(pdi,pncmd_target_receive,2,abtRx,&uiRxLen)) return false;
// Try to gather a received frame from the reader
if (!pn53x_transceive(pdi,pncmd_target_receive,2,abtRx,&szRxLen)) return false;
// Save the received byte count
*puiRxLen = uiRxLen-1;
*pszRxLen = szRxLen-1;
// Copy the received bytes
memcpy(pbtRx,abtRx+1,*puiRxLen);
memcpy(pbtRx,abtRx+1,*pszRxLen);
// Everyting seems ok, return true
return true;
}
bool nfc_target_send_bits(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxBits, const byte_t* pbtTxPar)
bool nfc_target_send_bits(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar)
{
uint32_t uiFrameBits = 0;
uint32_t uiFrameBytes = 0;
size_t szFrameBits = 0;
size_t szFrameBytes = 0;
uint8_t ui8Bits = 0;
byte_t abtCmd[sizeof(pncmd_target_send)];
memcpy(abtCmd,pncmd_target_send,sizeof(pncmd_target_send));
// Check if we should prepare the parity bits ourself
if (!pdi->bPar)
{
// Convert data with parity to a frame
pn53x_wrap_frame(pbtTx,uiTxBits,pbtTxPar,abtCmd+2,&uiFrameBits);
pn53x_wrap_frame(pbtTx,szTxBits,pbtTxPar,abtCmd+2,&szFrameBits);
} else {
uiFrameBits = uiTxBits;
szFrameBits = szTxBits;
}
// Retrieve the leading bits
ui8Bits = uiFrameBits%8;
ui8Bits = szFrameBits%8;
// Get the amount of frame bytes + optional (1 byte if there are leading bits)
uiFrameBytes = (uiFrameBits/8)+((ui8Bits==0)?0:1);
szFrameBytes = (szFrameBits/8)+((ui8Bits==0)?0:1);
// When the parity is handled before us, we just copy the data
if (pdi->bPar) memcpy(abtCmd+2,pbtTx,uiFrameBytes);
if (pdi->bPar) memcpy(abtCmd+2,pbtTx,szFrameBytes);
// Set the amount of transmission bits in the PN53X chip register
if (!pn53x_set_tx_bits(pdi,ui8Bits)) return false;
// Try to send the bits to the reader
if (!pn53x_transceive(pdi,abtCmd,uiFrameBytes+2,NULL,NULL)) return false;
if (!pn53x_transceive(pdi,abtCmd,szFrameBytes+2,NULL,NULL)) return false;
// Everyting seems ok, return true
return true;
}
bool nfc_target_send_bytes(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxLen)
bool nfc_target_send_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen)
{
byte_t abtCmd[sizeof(pncmd_target_send)];
memcpy(abtCmd,pncmd_target_send,sizeof(pncmd_target_send));
// We can not just send bytes without parity if while the PN53X expects we handled them
if (!pdi->bPar) return false;
// Copy the data into the command frame
memcpy(abtCmd+2,pbtTx,uiTxLen);
memcpy(abtCmd+2,pbtTx,szTxLen);
// Try to send the bits to the reader
if (!pn53x_transceive(pdi,abtCmd,uiTxLen+2,NULL,NULL)) return false;
if (!pn53x_transceive(pdi,abtCmd,szTxLen+2,NULL,NULL)) return false;
// Everyting seems ok, return true
return true;
}
bool nfc_target_send_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxLen)
bool nfc_target_send_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen)
{
byte_t abtCmd[sizeof(pncmd_target_set_data)];
memcpy(abtCmd,pncmd_target_set_data,sizeof(pncmd_target_set_data));
// We can not just send bytes without parity if while the PN53X expects we handled them
if (!pdi->bPar) return false;
// Copy the data into the command frame
memcpy(abtCmd+2,pbtTx,uiTxLen);
memcpy(abtCmd+2,pbtTx,szTxLen);
// Try to send the bits to the reader
if (!pn53x_transceive(pdi,abtCmd,uiTxLen+2,NULL,NULL)) return false;
if (!pn53x_transceive(pdi,abtCmd,szTxLen+2,NULL,NULL)) return false;
// Everyting seems ok, return true
return true;

View file

@ -35,20 +35,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "bitutils.h"
/**
* @fn dev_info* nfc_connect(nfc_device_desc_t* device_desc)
* @fn dev_info* nfc_connect(nfc_device_desc_t* pndd)
* @brief Connect to a NFC device
* @param device_desc Device description if specific device is wanted, NULL otherwise
* @param pndd Device description if specific device is wanted, NULL otherwise
* @return Returns pointer to a dev_info struct if successfull; otherwise returns INVALID_DEVICE_INFO value.
*
* If device_desc is NULL, the first available NFC device is claimed by libnfc.
* If \a pndd is NULL, the first available NFC device is claimed by libnfc.
* It will automatically search the system using all available drivers to determine a device is free.
*
* If device_desc is passed then libnfc will try to claim the right device using information provided by this struct.
* If \a pndd is passed then libnfc will try to claim the right device using information provided by this struct.
*
* When it has successfully claimed a NFC device, memory is allocated to save the device information. It will return a pointer to a dev_info struct.
* This pointer should be supplied by every next function of libnfc that should perform an action with this device.
*/
dev_info* nfc_connect(nfc_device_desc_t* device_desc);
dev_info* nfc_connect(nfc_device_desc_t* pndd);
/**
* @fn void nfc_disconnect(dev_info* pdi)
@ -84,21 +84,21 @@ bool nfc_configure(dev_info* pdi, const dev_config_option dco, const bool bEnabl
bool nfc_initiator_init(const dev_info* pdi);
/**
* @fn nfc_initiator_select_tag(const dev_info* pdi, const init_modulation im, const byte_t* pbtInitData, const uint32_t uiInitDataLen, tag_info* pti)
* @fn nfc_initiator_select_tag(const dev_info* pdi, const init_modulation im, const byte_t* pbtInitData, const size_t szInitDataLen, tag_info* pti)
* @brief Select a passive or emulated tag
* @return Returns true if action was successfully performed; otherwise returns false.
* @param pdi dev_info struct pointer that represent currently used device
* @param im Desired modulation
* @param pbtInitData Optional initiator data used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID.
* @param uiInitDataLen Length of initiator data \a pbtInitData.
* @param szInitDataLen Length of initiator data \a pbtInitData.
*
* The NFC device will try to find the available passive tags. Some NFC devices are capable to emulate passive tags. The standards (ISO18092 and ECMA-340) describe the modulation that can be used for reader to passive communications. The chip needs to know with what kind of tag it is dealing with, therefore the initial modulation and speed (106, 212 or 424 kbps) should be supplied.
* @note For every initial modulation type there is a different collection of information returned (in tag_info pointer pti) They all fit in the data-type which is called tag_info. This is a union which contains the tag information that belongs to the according initial modulation type.
*/
bool nfc_initiator_select_tag(const dev_info* pdi, const init_modulation im, const byte_t* pbtInitData, const uint32_t uiInitDataLen, tag_info* pti);
bool nfc_initiator_select_tag(const dev_info* pdi, const init_modulation im, const byte_t* pbtInitData, const size_t szInitDataLen, tag_info* pti);
/**
* @fn nfc_initiator_select_dep_target(const dev_info *pdi, const init_modulation im, const byte_t *pbtPidData, const uint32_t uiPidDataLen, const byte_t *pbtNFCID3i, const uint32_t uiNFCID3iDataLen, const byte_t *pbtGbData, const uint32_t uiGbDataLen, tag_info * pti);
* @fn nfc_initiator_select_dep_target(const dev_info *pdi, const init_modulation im, const byte_t *pbtPidData, const size_t szPidDataLen, const byte_t *pbtNFCID3i, const size_t szNFCID3iDataLen, const byte_t *pbtGbData, const size_t szGbDataLen, tag_info * pti);
* @brief Select a target and request active or passive mode for DEP (Data Exchange Protocol)
* @return Returns true if action was successfully performed; otherwise returns false.
* @param pdi dev_info struct pointer that represent currently used device
@ -110,7 +110,7 @@ bool nfc_initiator_select_tag(const dev_info* pdi, const init_modulation im, con
* The NFC device will try to find the available target. The standards (ISO18092 and ECMA-340) describe the modulation that can be used for reader to passive communications.
* @note tag_info_dep will be returned when the target was acquired successfully.
*/
bool nfc_initiator_select_dep_target(const dev_info* pdi, const init_modulation im, const byte_t* pbtPidData, const uint32_t uiPidDataLen, const byte_t* pbtNFCID3i, const uint32_t uiNFCID3iDataLen, const byte_t *pbtGbData, const uint32_t uiGbDataLen, tag_info* pti);
bool nfc_initiator_select_dep_target(const dev_info* pdi, const init_modulation im, const byte_t* pbtPidData, const uint32_t szPidDataLen, const byte_t* pbtNFCID3i, const uint32_t szNFCID3iDataLen, const byte_t *pbtGbData, const uint32_t szGbDataLen, tag_info* pti);
/**
* @fn nfc_initiator_deselect_tag(const dev_info* pdi);
* @brief Deselect a selected passive or emulated tag
@ -122,38 +122,38 @@ bool nfc_initiator_select_dep_target(const dev_info* pdi, const init_modulation
bool nfc_initiator_deselect_tag(const dev_info* pdi);
/**
* @fn nfc_initiator_transceive_bits(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, uint32_t* puiRxBits, byte_t* pbtRxPar)
* @fn nfc_initiator_transceive_bits(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
* @brief Transceive raw bit-frames
* @return Returns true if action was successfully performed; otherwise returns false.
* @param pbtTx contains a byte array of the frame that needs to be transmitted.
* @param uiTxBits contains the length in bits.
* @note For example the REQA (0×26) command (first anti-collision command of ISO14443-A) must be precise 7 bits long. This is not possible by using nfc_initiator_transceive_bytes(). With that function you can only communicate frames that consist of full bytes. When you send a full byte (8 bits + 1 parity) with the value of REQA (0×26), a tag will simply not respond. More information about this can be found in the anti-colision example.
* @param szTxBits contains the length in bits.
* @note For example the REQA (0x26) command (first anti-collision command of ISO14443-A) must be precise 7 bits long. This is not possible by using nfc_initiator_transceive_bytes(). With that function you can only communicate frames that consist of full bytes. When you send a full byte (8 bits + 1 parity) with the value of REQA (0x26), a tag will simply not respond. More information about this can be found in the anti-colision example.
* @param pbtTxPar parameter contains a byte array of the corresponding parity bits needed to send per byte.
* @note For example if you send the SELECT_ALL (0×93, 0×20) = [ 10010011, 00100000 ] command, you have to supply the following parity bytes (0×01, 0×00) to define the correct odd parity bits. This is only an example to explain how it works, if you just are sending two bytes with ISO14443-A compliant parity bits you better can use the nfc_initiator_transceive_bytes() function.
* @returns The received response from the tag will be stored in the parameters (pbtRx, puiRxBits and pbtRxPar). They work the same way as the corresponding parameters for transmission.
* @note For example if you send the SELECT_ALL (0x93, 0x20) = [ 10010011, 00100000 ] command, you have to supply the following parity bytes (0x01, 0x00) to define the correct odd parity bits. This is only an example to explain how it works, if you just are sending two bytes with ISO14443-A compliant parity bits you better can use the nfc_initiator_transceive_bytes() function.
* @returns The received response from the tag will be stored in the parameters (pbtRx, pszRxBits and pbtRxPar). They work the same way as the corresponding parameters for transmission.
*
* The NFC reader will transmit low-level messages where only the modulation is handled by the PN53X chip. Construction of the frame (data, CRC and parity) is completely done by libnfc. This can be very useful for testing purposes. Some protocols (e.g. MIFARE Classic) require to violate the ISO14443-A standard by sending incorrect parity and CRC bytes. Using this feature you are able to simulate these frames.
*/
bool nfc_initiator_transceive_bits(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, uint32_t* puiRxBits, byte_t* pbtRxPar);
bool nfc_initiator_transceive_bits(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar);
/**
* @fn nfc_initiator_transceive_bytes(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen)
* @fn nfc_initiator_transceive_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
* @brief Transceive byte and APDU frames
* @return Returns true if action was successfully performed; otherwise returns false.
*
* The reader will transmit the supplied bytes in pbtTx to the target (tag). It waits for the response and stores the received bytes in the pbtRx byte array. The parity bits are handled by the PN53X chip. The CRC can be generated automatically or handled manually. Using this function, frames can be communicated very fast via the NFC reader to the tag. Tests show that on average this way of communicating is much faster than using the regular driver/middle-ware (often supplied by manufacturers).
* @warning The configuration option DCO_HANDLE_PARITY must be set to true (the default value).
*/
bool nfc_initiator_transceive_bytes(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen);
bool nfc_initiator_transceive_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
/**
* @fn nfc_initiator_transceive_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen)
* @fn nfc_initiator_transceive_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
* @brief Transceive data
* @return Returns true if action was successfully performed; otherwise returns false.
*
* The reader will transmit the supplied (data) bytes in pbtTx to the target (tag). It waits for the response and stores the received bytes in the pbtRx byte array. The difference between this function and nfc_initiator_transceive_bytes is that here pbtTx and pbtRx contain *only* the data sent and received and not any additional commands, that is all handled internally by the PN53X.
*/
bool nfc_initiator_transceive_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen);
bool nfc_initiator_transceive_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
/**
* @fn nfc_initiator_mifare_cmd(const dev_info* pdi, const mifare_cmd mc, const uint8_t ui8Block, mifare_param* pmp)
@ -169,7 +169,7 @@ bool nfc_initiator_transceive_dep_bytes(const dev_info* pdi, const byte_t* pbtTx
bool nfc_initiator_mifare_cmd(const dev_info* pdi, const mifare_cmd mc, const uint8_t ui8Block, mifare_param* pmp);
/**
* @fn nfc_target_init(const dev_info* pdi, byte_t* pbtRx, uint32_t* puiRxBits)
* @fn nfc_target_init(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxBits)
* @brief Initialize NFC device as an emulated tag
* @return Returns true if action was successfully performed; otherwise returns false.
*
@ -177,61 +177,61 @@ bool nfc_initiator_mifare_cmd(const dev_info* pdi, const mifare_cmd mc, const ui
*
* @warning Be aware that this function will wait (hang) until a command is received that is not part of the anti-collision. The RATS command for example would wake up the emulator. After this is received, the send and receive functions can be used.
*/
bool nfc_target_init(const dev_info* pdi, byte_t* pbtRx, uint32_t* puiRxBits);
bool nfc_target_init(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxBits);
/**
* @fn nfc_target_receive_bits(const dev_info* pdi, byte_t* pbtRx, uint32_t* puiRxBits, byte_t* pbtRxPar)
* @fn nfc_target_receive_bits(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
* @brief Receive bit-frames
* @return Returns true if action was successfully performed; otherwise returns false.
*
* This function makes it possible to receive (raw) bit-frames. It returns all the messages that are stored in the FIFO buffer of the PN53X chip. It does not require to send any frame and thereby could be used to snoop frames that are transmitted by a nearby reader. Check out the DCO_ACCEPT_MULTIPLE_FRAMES configuration option to avoid losing transmitted frames.
*/
bool nfc_target_receive_bits(const dev_info* pdi, byte_t* pbtRx, uint32_t* puiRxBits, byte_t* pbtRxPar);
bool nfc_target_receive_bits(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar);
/**
* @fn nfc_target_receive_bytes(const dev_info* pdi, byte_t* pbtRx, uint32_t* puiRxLen)
* @fn nfc_target_receive_bytes(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxLen)
* @brief Receive bytes and APDU frames
* @return Returns true if action was successfully performed; otherwise returns false.
*
* The main receive function that returns the received frames from a nearby reader.
*/
bool nfc_target_receive_bytes(const dev_info* pdi, byte_t* pbtRx, uint32_t* puiRxLen);
bool nfc_target_receive_bytes(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxLen);
/**
* @fn nfc_target_receive_dep_bytes(const dev_info* pdi, byte_t* pbtRx, uint32_t* puiRxLen)
* @fn nfc_target_receive_dep_bytes(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxLen)
* @brief Receive data
* @return Returns true if action was successfully performed; otherwise returns false.
*
* The main receive function that returns the received data from a nearby reader. The difference between this function and nfc_target_receive_bytes is that here pbtRx contains *only* the data received and not any additional commands, that is all handled internally by the PN53X.
*/
bool nfc_target_receive_dep_bytes(const dev_info* pdi, byte_t* pbtRx, uint32_t* puiRxLen);
bool nfc_target_receive_dep_bytes(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxLen);
/**
* @fn nfc_target_send_bits(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxBits, const byte_t* pbtTxPar)
* @fn nfc_target_send_bits(const dev_info* pdi, const byte_t* pbtTx, const uint32_t szTxBits, const byte_t* pbtTxPar)
* @brief Send raw bit-frames
* @return Returns true if action was successfully performed; otherwise returns false.
*
* This function can be used to transmit (raw) bit-frames to the reader.
*/
bool nfc_target_send_bits(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxBits, const byte_t* pbtTxPar);
bool nfc_target_send_bits(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar);
/**
* @fn nfc_target_send_bytes(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxLen)
* @fn nfc_target_send_bytes(const dev_info* pdi, const byte_t* pbtTx, const uint32_t szTxLen)
* @brief Send bytes and APDU frames
* @return Returns true if action was successfully performed; otherwise returns false.
*
* To communicate byte frames and APDU responses to the reader, this function could be used.
*/
bool nfc_target_send_bytes(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxLen);
bool nfc_target_send_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen);
/**
* @fn nfc_target_send_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxLen)
* @fn nfc_target_send_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen)
* @brief Send data
* @return Returns true if action was successfully performed; otherwise returns false.
*
* To communicate data to the reader, this function could be used. The difference between this function and nfc_target_send_bytes is that here pbtTx contains *only* the data sent and not any additional commands, that is all handled internally by the PN53X.
*/
bool nfc_target_send_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const uint32_t uiTxLen);
bool nfc_target_send_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen);
#endif // _LIBNFC_H_

View file

@ -39,11 +39,12 @@ int main(int argc, const char* argv[])
// If specific device is wanted, i.e. an ARYGON device on /dev/ttyUSB0
/*
nfc_device_desc_t device_desc;
device_desc.driver = "ARYGON";
device_desc.port = "/dev/ttyUSB0";
nfc_device_desc_t ndd;
ndd.pcDriver = "ARYGON";
ndd.pcPort = "/dev/ttyUSB0";
ndd.uiSpeed = 115200;
pdi = nfc_connect(&device_desc);
pdi = nfc_connect(&ndd);
*/
if (pdi == INVALID_DEVICE_INFO)
@ -66,19 +67,19 @@ int main(int argc, const char* argv[])
// Enable field so more power consuming cards can power themselves up
nfc_configure(pdi,DCO_ACTIVATE_FIELD,true);
printf("\nConnected to NFC reader: %s\n\n",pdi->acName);
printf("Connected to NFC reader: %s\n\n",pdi->acName);
// Poll for a ISO14443A (MIFARE) tag
if (nfc_initiator_select_tag(pdi,IM_ISO14443A_106,NULL,0,&ti))
{
printf("The following (NFC) ISO14443A tag was found:\n\n");
printf(" ATQA (SENS_RES): "); print_hex(ti.tia.abtAtqa,2);
printf(" UID (NFCID%c): ",(ti.tia.abtUid[0]==0x08?'3':'1')); print_hex(ti.tia.abtUid,ti.tia.uiUidLen);
printf(" UID (NFCID%c): ",(ti.tia.abtUid[0]==0x08?'3':'1')); print_hex(ti.tia.abtUid,ti.tia.szUidLen);
printf(" SAK (SEL_RES): "); print_hex(&ti.tia.btSak,1);
if (ti.tia.uiAtsLen)
if (ti.tia.szAtsLen)
{
printf(" ATS (ATR): ");
print_hex(ti.tia.abtAts,ti.tia.uiAtsLen);
print_hex(ti.tia.abtAts,ti.tia.szAtsLen);
}
}
@ -97,9 +98,9 @@ int main(int argc, const char* argv[])
printf(" ATQB: "); print_hex(ti.tib.abtAtqb,12);
printf(" ID: "); print_hex(ti.tib.abtId,4);
printf(" CID: %02x\n",ti.tib.btCid);
if (ti.tib.uiInfLen>0)
if (ti.tib.szInfLen>0)
{
printf(" INF: "); print_hex(ti.tib.abtInf,ti.tib.uiInfLen);
printf(" INF: "); print_hex(ti.tib.abtInf,ti.tib.szInfLen);
}
printf("PARAMS: %02x %02x %02x %02x\n",ti.tib.btParam1,ti.tib.btParam2,ti.tib.btParam3,ti.tib.btParam4);
}

View file

@ -178,7 +178,7 @@ bool write_card()
// Set the authentication information (uid)
memcpy(mp.mpa.abtUid,ti.tia.abtUid,4);
// Determin if we should use the a or the b key
if (bUseKeyA)
{
@ -196,7 +196,7 @@ bool write_card()
return false;
}
}
if (is_trailer_block(uiBlock))
{
// Copy the keys over from our key dump and store the retrieved access bits
@ -206,7 +206,7 @@ bool write_card()
// Try to write the trailer
nfc_initiator_mifare_cmd(pdi,MC_WRITE,uiBlock,&mp);
} else {
// The first block 0x00 is read only, skip this
@ -223,12 +223,12 @@ bool write_card()
}
printf("%c|\n",(bFailure)?'x':'.');
fflush(stdout);
return true;
}
int main(int argc, const char* argv[])
{
{
bool b4K;
bool bReadAction;
byte_t* pbtUID;
@ -301,7 +301,7 @@ int main(int argc, const char* argv[])
// Drop the field for a while
nfc_configure(pdi,DCO_ACTIVATE_FIELD,false);
// Let the reader only try once to find a tag
nfc_configure(pdi,DCO_INFINITE_SELECT,false);
nfc_configure(pdi,DCO_HANDLE_CRC,true);

View file

@ -61,7 +61,6 @@ bool write_card()
bool bFailure = false;
for (page = 0x4; page <= 0xF; page++) {
// Show if the readout went well
if (bFailure)
{
@ -81,7 +80,7 @@ bool write_card()
}
}
fflush(stdout);
// Make sure a earlier write did not fail
if (!bFailure)
{
@ -96,7 +95,7 @@ bool write_card()
}
printf("%c|\n",(bFailure)?'x':'.');
fflush(stdout);
return true;
}
@ -155,7 +154,7 @@ int main(int argc, const char* argv[])
// Drop the field for a while
nfc_configure(pdi,DCO_ACTIVATE_FIELD,false);
// Let the reader only try once to find a tag
nfc_configure(pdi,DCO_INFINITE_SELECT,false);
nfc_configure(pdi,DCO_HANDLE_CRC,true);

View file

@ -28,10 +28,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
static byte_t abtReaderRx[MAX_FRAME_LEN];
static byte_t abtReaderRxPar[MAX_FRAME_LEN];
static uint32_t uiReaderRxBits;
static size_t szReaderRxBits;
static byte_t abtTagRx[MAX_FRAME_LEN];
static byte_t abtTagRxPar[MAX_FRAME_LEN];
static uint32_t uiTagRxBits;
static size_t szTagRxBits;
static dev_info* pdiReader;
static dev_info* pdiTag;
@ -76,7 +76,7 @@ int main(int argc,char* argv[])
printf("[+] Try to break out the auto-emulation, this requires a second reader!\n");
printf("[+] To do this, please send any command after the anti-collision\n");
printf("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
nfc_target_init(pdiTag,abtReaderRx,&uiReaderRxBits);
nfc_target_init(pdiTag,abtReaderRx,&szReaderRxBits);
printf("[+] Configuring emulator settings\n");
nfc_configure(pdiTag,DCO_HANDLE_CRC,false);
nfc_configure(pdiTag,DCO_HANDLE_PARITY,false);
@ -95,10 +95,10 @@ int main(int argc,char* argv[])
while(true)
{
// Test if we received a frame from the reader
if (nfc_target_receive_bits(pdiTag,abtReaderRx,&uiReaderRxBits,abtReaderRxPar))
if (nfc_target_receive_bits(pdiTag,abtReaderRx,&szReaderRxBits,abtReaderRxPar))
{
// Drop down the field before sending a REQA command and start a new session
if (uiReaderRxBits == 7 && abtReaderRx[0] == 0x26)
if (szReaderRxBits == 7 && abtReaderRx[0] == 0x26)
{
// Drop down field for a very short time (original tag will reboot)
nfc_configure(pdiReader,DCO_ACTIVATE_FIELD,false);
@ -111,19 +111,19 @@ int main(int argc,char* argv[])
if(!quiet_output)
{
printf("R: ");
print_hex_par(abtReaderRx,uiReaderRxBits,abtReaderRxPar);
print_hex_par(abtReaderRx,szReaderRxBits,abtReaderRxPar);
}
// Forward the frame to the original tag
if (nfc_initiator_transceive_bits(pdiReader,abtReaderRx,uiReaderRxBits,abtReaderRxPar,abtTagRx,&uiTagRxBits,abtTagRxPar))
if (nfc_initiator_transceive_bits(pdiReader,abtReaderRx,szReaderRxBits,abtReaderRxPar,abtTagRx,&szTagRxBits,abtTagRxPar))
{
// Redirect the answer back to the reader
nfc_target_send_bits(pdiTag,abtTagRx,uiTagRxBits,abtTagRxPar);
nfc_target_send_bits(pdiTag,abtTagRx,szTagRxBits,abtTagRxPar);
// Print the tag frame to the screen
if(!quiet_output)
{
printf("T: ");
print_hex_par(abtTagRx,uiTagRxBits,abtTagRxPar);
print_hex_par(abtTagRx,szTagRxBits,abtTagRxPar);
}
}
}

View file

@ -117,7 +117,11 @@ void rs232_set_speed(serial_port sp, const uint32_t uiPortSpeed)
break;
#endif
default:
#ifdef B460800
ERR("Unable to set serial port speed to %d bauds. Speed value must be one of these constants: 9600 (default), 19200, 38400, 57600, 115200, 230400 or 460800.", uiPortSpeed);
#else
ERR("Unable to set serial port speed to %d bauds. Speed value must be one of these constants: 9600 (default), 19200, 38400, 57600, 115200 or 230400.", uiPortSpeed);
#endif
};
const serial_port_unix* spu = (serial_port_unix*)sp;
cfsetispeed(&spu->tiNew, stPortSpeed);

View file

@ -54,8 +54,8 @@ uint32_t rs232_get_speed(const serial_port sp);
bool rs232_cts(const serial_port sp);
bool rs232_receive(const serial_port sp, byte_t* pbtRx, uint32_t* puiRxLen);
bool rs232_send(const serial_port sp, const byte_t* pbtTx, const uint32_t uiTxLen);
bool rs232_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen);
bool rs232_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen);
#endif // _LIBNFC_RS232_H_

View file

@ -4,20 +4,20 @@
int main(int argc, const char *argv[])
{
byte_t abtRecv[MAX_FRAME_LEN];
uint32_t uiRecvBits;
size_t szRecvBits;
byte_t send[] = "Hello Mars!";
dev_info *pdi = nfc_connect(NULL);
if (!pdi || !nfc_target_init(pdi, abtRecv, &uiRecvBits)) {
if (!pdi || !nfc_target_init(pdi, abtRecv, &szRecvBits)) {
printf("unable to connect or initialize\n");
return 1;
}
if (!nfc_target_receive_dep_bytes(pdi, abtRecv, &uiRecvBits)) {
if (!nfc_target_receive_dep_bytes(pdi, abtRecv, &szRecvBits)) {
printf("unable to receive data\n");
return 1;
}
abtRecv[uiRecvBits] = 0;
abtRecv[szRecvBits] = 0;
printf("Received: %s\n", abtRecv);
printf("Sending : %s\n", send);

View file

@ -27,7 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
*
* Define libnfc specific types: typedef, enum, struct, etc.
*/
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
@ -77,13 +77,13 @@ typedef struct {
*/
typedef struct {
/** Driver name */
char* driver;
char* pcDriver;
/** Port (i.e. /dev/ttyUSB2) */
char* port;
char* pcPort;
/** Port speed (i.e. 115200) */
uint32_t speed;
uint32_t uiSpeed;
/** Device index for backward compatibility (used to choose one specific device in USB or PSCS devices list) */
uint32_t index;
uint32_t uiIndex;
} nfc_device_desc_t;
/**
@ -94,9 +94,9 @@ struct dev_callbacks {
/** Driver name */
const char* acDriver;
/** Connect callback */
dev_info* (*connect)(const nfc_device_desc_t* device_desc);
dev_info* (*connect)(const nfc_device_desc_t* pndd);
/** Transceive callback */
bool (*transceive)(const dev_spec ds, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen);
bool (*transceive)(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
/** Disconnect callback */
void (*disconnect)(dev_info* pdi);
};
@ -164,9 +164,9 @@ typedef struct {
typedef struct {
byte_t abtAtqa[2];
byte_t btSak;
uint32_t uiUidLen;
size_t szUidLen;
byte_t abtUid[10];
uint32_t uiAtsLen;
size_t szAtsLen;
byte_t abtAts[36];
}tag_info_iso14443a;
@ -175,7 +175,7 @@ typedef struct {
* @brief NFC FeLiCa tag information
*/
typedef struct {
uint32_t uiLen;
size_t szLen;
byte_t btResCode;
byte_t abtId[8];
byte_t abtPad[8];
@ -194,7 +194,7 @@ typedef struct {
byte_t btParam3;
byte_t btParam4;
byte_t btCid;
uint32_t uiInfLen;
size_t szInfLen;
byte_t abtInf[64];
}tag_info_iso14443b;