Second attempt to reorganize tree

This commit is contained in:
Romuald Conty 2009-11-03 15:20:36 +00:00
parent ab62855d80
commit 507991ac2b
7 changed files with 0 additions and 0 deletions

View file

@ -1,190 +0,0 @@
/**
* Public platform independent Near Field Communication (NFC) library
*
* Copyright (C) 2009, Roel Verdult
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*
* @file bitutils.c
* @brief
*/
#include <stdio.h>
#include "bitutils.h"
const static byte_t OddParity[256] = {
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
};
const static byte_t ByteMirror[256] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30,
0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98,
0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64,
0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc,
0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02,
0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2,
0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a,
0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e,
0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81,
0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71,
0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9,
0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15,
0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad,
0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43,
0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b,
0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97,
0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f,
0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};
byte_t oddparity(const byte_t bt)
{
return OddParity[bt];
}
void oddparity_bytes(const byte_t* pbtData, const size_t szLen, byte_t* pbtPar)
{
size_t szByteNr;
// Calculate the parity bits for the command
for (szByteNr=0; szByteNr<szLen; szByteNr++)
{
pbtPar[szByteNr] = OddParity[pbtData[szByteNr]];
}
}
byte_t mirror(byte_t bt)
{
return ByteMirror[bt];
}
void mirror_bytes(byte_t *pbts, size_t szLen)
{
size_t szByteNr;
for (szByteNr=0; szByteNr<szLen; szByteNr++)
{
*pbts = ByteMirror[*pbts];
pbts++;
}
}
uint32_t mirror32(uint32_t ui32Bits)
{
mirror_bytes((byte_t*)&ui32Bits,4);
return ui32Bits;
}
uint64_t mirror64(uint64_t ui64Bits)
{
mirror_bytes((byte_t*)&ui64Bits,8);
return ui64Bits;
}
uint32_t swap_endian32(const void* pui32)
{
uint32_t ui32N = *((uint32_t*)pui32);
return (((ui32N&0xFF)<<24)+((ui32N&0xFF00)<<8)+((ui32N&0xFF0000)>>8)+((ui32N&0xFF000000)>>24));
}
uint64_t swap_endian64(const void* pui64)
{
uint64_t ui64N = *((uint64_t *)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, size_t szLen)
{
byte_t bt;
uint32_t wCrc = 0x6363;
do {
bt = *pbtData++;
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 (--szLen);
*pbtData++ = (byte_t) (wCrc & 0xFF);
*pbtData = (byte_t) ((wCrc >> 8) & 0xFF);
}
void print_hex(const byte_t* pbtData, const size_t szBytes)
{
size_t szPos;
for (szPos=0; szPos < szBytes; szPos++)
{
printf("%02x ",pbtData[szPos]);
}
printf("\n");
}
void print_hex_bits(const byte_t* pbtData, const size_t szBits)
{
size_t szPos;
size_t szBytes = szBits/8;
for (szPos=0; szPos < szBytes; szPos++)
{
printf("%02x ",pbtData[szPos]);
}
// Print the rest bits, these cannot have no parity bit
if (szBits%8 != 0) printf("%02x",pbtData[szBytes]);
printf("\n");
}
void print_hex_par(const byte_t* pbtData, const size_t szBits, const byte_t* pbtDataPar)
{
size_t szPos;
size_t szBytes = szBits/8;
for (szPos=0; szPos < szBytes; szPos++)
{
printf("%02x",pbtData[szPos]);
if (OddParity[pbtData[szPos]] != pbtDataPar[szPos])
{
printf("! ");
} else {
printf(" ");
}
}
// Print the rest bits, these cannot have no parity bit
if (szBits%8 != 0) printf("%02x",pbtData[szBytes]);
printf("\n");
}

59
src/lib/defines.h Normal file
View file

@ -0,0 +1,59 @@
/**
* Public platform independent Near Field Communication (NFC) library
*
* Copyright (C) 2009, Roel Verdult
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*
* @file defines.h
* @brief
*/
#ifndef _LIBNFC_DEFINES_H_
#define _LIBNFC_DEFINES_H_
//#define DEBUG /* DEBUG flag can also be enabled using ./configure --enable-debug */
typedef void* dev_spec; // Device connection specification
#define INVALID_DEVICE_INFO 0
#define MAX_FRAME_LEN 264
#define DEVICE_NAME_LENGTH 256
#define MAX_DEVICES 16
#if defined __cplusplus
#define LIBNFC_EXTERN_C extern "C"
#else
#define LIBNFC_EXTERN_C
#endif
#ifdef _WIN32
#ifdef nfc_EXPORTS
#define LIBNFC_DECLSPEC __declspec( dllexport )
#else
#define LIBNFC_DECLSPEC __declspec( dllimport )
#endif
#else
#define LIBNFC_DECLSPEC
#endif
#define LIBNFC_EXPORT LIBNFC_EXTERN_C LIBNFC_DECLSPEC
//#define MIN(a,b) (((a) < (b)) ? (a) : (b))
//#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#define INNER_XOR8(n) {n ^= (n >> 4); n ^= (n >> 2); n ^= (n >> 1); n &= 0x01; }
#define INNER_XOR32(n) {n ^= (n >> 16); n ^= (n >> 8); INNER_XOR8(n); }
#define INNER_XOR64(n) {n ^= (n >> 32); INNER_XOR32(n); }
#endif // _LIBNFC_DEFINES_H_

53
src/lib/drivers.h Normal file
View file

@ -0,0 +1,53 @@
/**
* Public platform independent Near Field Communication (NFC) library
*
* Copyright (C) 2009, Roel Verdult
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*
* @file devices.h
* @brief
*/
#ifndef _LIBNFC_DEVICES_H_
#define _LIBNFC_DEVICES_H_
#include "defines.h"
#include "types.h"
#ifdef HAVE_PCSC_LITE
#include "dev_acr122.h"
#endif /* HAVE_PCSC_LITE */
#ifdef HAVE_LIBUSB
#include "dev_pn531.h"
#include "dev_pn533.h"
#endif /* HAVE_LIBUSB */
#include "dev_arygon.h"
#include "dev_pn532_uart.h"
const static struct dev_callbacks dev_callbacks_list[] = {
// Driver Name Connect Transceive Disconnect
#ifdef HAVE_PCSC_LITE
{ "ACR122", dev_acr122_connect, dev_acr122_transceive, dev_acr122_disconnect },
#endif /* HAVE_PCSC_LITE */
#ifdef HAVE_LIBUSB
{ "PN531USB", dev_pn531_connect, dev_pn531_transceive, dev_pn531_disconnect },
{ "PN533USB", dev_pn533_connect, dev_pn533_transceive, dev_pn533_disconnect },
#endif /* HAVE_LIBUSB */
{ "PN532_UART", dev_pn532_uart_connect, dev_pn532_uart_transceive, dev_pn532_uart_disconnect },
{ "ARYGON", dev_arygon_connect, dev_arygon_transceive, dev_arygon_disconnect }
};
#endif // _LIBNFC_DEVICES_H_

41
src/lib/messages.h Normal file
View file

@ -0,0 +1,41 @@
/**
* Public platform independent Near Field Communication (NFC) library
*
* Copyright (C) 2009, Roel Verdult
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*
* @file messages.h
* @brief
*/
#ifndef _LIBNFC_MESSAGES_H_
#define _LIBNFC_MESSAGES_H_
// #define DEBUG /* DEBUG flag can also be enabled using ./configure --enable-debug */
// Useful macros
#ifdef DEBUG
// #define DBG(x, args...) printf("DBG %s:%d: " x "\n", __FILE__, __LINE__,## args )
#define DBG(x, ...) fprintf(stderr, "DBG %s:%d: " x "\n", __FILE__, __LINE__, ## __VA_ARGS__ )
#else
#define DBG(...) {}
#endif
#define INFO(x, ...) printf("INFO: " x "\n", ## __VA_ARGS__ )
#define WARN(x, ...) printf("WARNING: " x "\n", ## __VA_ARGS__ )
#define ERR(x, ...) fprintf(stderr, "ERROR: " x "\n", ## __VA_ARGS__ )
#endif // _LIBNFC_MESSAGES_H_

251
src/lib/nfc.h Normal file
View file

@ -0,0 +1,251 @@
/**
* Public platform independent Near Field Communication (NFC) library
*
* Copyright (C) 2009, Roel Verdult
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*
* @file libnfc.h
* @brief libnfc interface
*
* Provide all usefull functions (API) to handle NFC devices.
*/
#ifndef _LIBNFC_H_
#define _LIBNFC_H_
#include <stdint.h>
#include <stdbool.h>
#include "defines.h"
#include "types.h"
#ifdef __cplusplus
#define NFCAPI extern "C" {
#endif // __cplusplus
/**
* @fn dev_info* nfc_connect(nfc_device_desc_t* pndd)
* @brief Connect to a NFC device
* @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 \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 \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* pndd);
/**
* @fn void nfc_disconnect(dev_info* pdi)
* @brief Disconnect from a NFC device
* @param pdi dev_info struct pointer that represent currently used device
*
* Initiator is disconnected and the device, including allocated dev_info struct, is released.
*/
void nfc_disconnect(dev_info* pdi);
/**
* @fn nfc_configure(dev_info* pdi, const dev_config_option dco, const bool bEnable)
* @brief Configure advanced NFC device settings
* @return Returns true if action was successfully performed; otherwise returns false.
* @param pdi dev_info struct pointer that represent currently used device
* @param dco dev_config_option struct that contains options to set to device
* @param bEnable boolean
*
* Configures parameters and registers that control for example timing, modulation, frame and error handling.
* There are different categories for configuring the PN53X chip features (handle, activate, infinite and accept).
* These are defined to organize future settings that will become available when they are needed.
*/
bool nfc_configure(dev_info* pdi, const dev_config_option dco, const bool bEnable);
/**
* @fn nfc_initiator_init(const dev_info* pdi)
* @brief Initialize NFC device as initiator (reader)
* @return Returns true if action was successfully performed; otherwise returns false.
* @param pdi dev_info struct pointer that represent currently used device
*
* The NFC device is configured to function as RFID reader. After initialization it can be used to communicate to passive RFID tags and active NFC devices. The reader will act as initiator to communicate peer 2 peer (NFCIP) to other active NFC devices.
*/
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 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 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 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 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
* @param im Desired modulation (IM_ACTIVE_DEP or IM_PASSIVE_DEP for active, respectively passive mode)
* @param pbtPidData passive initiator data, 4 or 5 bytes long, (optional, only for IM_PASSIVE_DEP, can be NULL)
* @param pbtNFCID3i the NFCID3, 10 bytes long, of the initiator (optional, can be NULL)
* @param pbtGbData generic data of the initiator, max 48 bytes long, (optional, can be NULL)
*
* 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 size_t szPidDataLen, const byte_t* pbtNFCID3i, const size_t szNFCID3iDataLen, const byte_t *pbtGbData, const size_t szGbDataLen, tag_info* pti);
/**
* @fn nfc_initiator_deselect_tag(const dev_info* pdi);
* @brief Deselect a selected 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
*
* After selecting and communicating with a passive tag, this function could be used to deactivate and release the tag. This is very useful when there are multiple tags available in the field. It is possible to use the nfc_initiator_select_tag() function to select the first available tag, test it for the available features and support, deselect it and skip to the next tag until the correct tag is found.
*/
bool nfc_initiator_deselect_tag(const dev_info* pdi);
/**
* @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 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 (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 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 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 size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
/**
* @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 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)
* @brief Execute a MIFARE Classic Command
* @return Returns true if action was successfully performed; otherwise returns false.
* @param pmp Some commands need additional information. This information should be supplied in the mifare_param union.
*
* The specified MIFARE command will be executed on the tag. There are different commands possible, they all require the destination block number.
* @note There are three different types of information (Authenticate, Data and Value).
*
* First an authentication must take place using Key A or B. It requires a 48 bit Key (6 bytes) and the UID. They are both used to initialize the internal cipher-state of the PN53X chip (http://libnfc.org/hardware/pn53x-chip). After a successful authentication it will be possible to execute other commands (e.g. Read/Write). The MIFARE Classic Specification (http://www.nxp.com/acrobat/other/identification/M001053_MF1ICS50_rev5_3.pdf) explains more about this process.
*/
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, size_t* pszRxBits)
* @brief Initialize NFC device as an emulated tag
* @return Returns true if action was successfully performed; otherwise returns false.
*
* This functionality allows the NFC device to act as an emulated tag. There seems to be quite some options available for this feature. Not all of the PN53X modulations are tested and documented at the moment. At the moment it could best be seen as a preliminary functionality.
*
* @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, size_t* pszRxBits);
/**
* @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, size_t* pszRxBits, byte_t* pbtRxPar);
/**
* @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, size_t* pszRxLen);
/**
* @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, size_t* pszRxLen);
/**
* @fn nfc_target_send_bits(const dev_info* pdi, const byte_t* pbtTx, const size_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 size_t szTxBits, const byte_t* pbtTxPar);
/**
* @fn nfc_target_send_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_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 size_t szTxLen);
/**
* @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 size_t szTxLen);
/**
* @fn const char* nfc_version(void)
* @brief Returns the library version
* @return Returns a string with the library version
*/
const char* nfc_version(void);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // _LIBNFC_H_

262
src/lib/types.h Normal file
View file

@ -0,0 +1,262 @@
/**
* Public platform independent Near Field Communication (NFC) library
*
* Copyright (C) 2009, Roel Verdult
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*
* @file types.h
* @brief
*/
#ifndef _LIBNFC_TYPES_H_
#define _LIBNFC_TYPES_H_
/**
* @file types.h
* @brief libnfc-defined types
*
* Define libnfc specific types: typedef, enum, struct, etc.
*/
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "defines.h"
typedef uint8_t byte_t;
typedef enum {
CT_PN531 = 0x10,
CT_PN532 = 0x20,
CT_PN533 = 0x30,
} chip_type;
struct dev_callbacks; // Prototype the callback struct
/**
* @struct dev_info
* @brief NFC device information
*/
typedef struct {
/** Callback functions for handling device specific wrapping */
const struct dev_callbacks* pdc;
/** Device name string, including device wrapper firmware */
char acName[DEVICE_NAME_LENGTH];
/** PN53X chip type, this is useful for some "bug" work-arounds */
chip_type ct;
/** Pointer to the device connection specification */
dev_spec ds;
/** This represents if the PN53X device was initialized succesful */
bool bActive;
/** Is the crc automaticly added, checked and removed from the frames */
bool bCrc;
/** Does the PN53x chip handles parity bits, all parities are handled as data */
bool bPar;
/** The last tx bits setting, we need to reset this if it does not apply anymore */
uint8_t ui8TxBits;
} dev_info;
/**
* @struct nfc_device_desc_t
* @brief NFC device description
*
* This struct is used to try to connect to a specified nfc device when nfc_connect(...)
*/
typedef struct {
/** Driver name */
char* pcDriver;
/** Port (i.e. /dev/ttyUSB2) */
char* pcPort;
/** Port speed (i.e. 115200) */
uint32_t uiSpeed;
/** Device index for backward compatibility (used to choose one specific device in USB or PSCS devices list) */
uint32_t uiIndex;
} nfc_device_desc_t;
/**
* @struct dev_callbacks
* @brief NFC defice callbacks
*/
struct dev_callbacks {
/** Driver name */
const char* acDriver;
/** Connect callback */
dev_info* (*connect)(const nfc_device_desc_t* pndd);
/** Transceive callback */
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);
};
// Compiler directive, set struct alignment to 1 byte_t for compatibility
#pragma pack(1)
/**
* @enum dev_config_option
* @brief NFC device option
*/
typedef enum {
/** Let the PN53X chip handle the CRC bytes. This means that the chip appends the CRC bytes to the frames that are transmitted. It will parse the last bytes from received frames as incoming CRC bytes. They will be verified against the used modulation and protocol. If an frame is expected with incorrect CRC bytes this option should be disabled. Example frames where this is useful are the ATQA and UID+BCC that are transmitted without CRC bytes during the anti-collision phase of the ISO14443-A protocol. */
DCO_HANDLE_CRC = 0x00,
/** Parity bits in the network layer of ISO14443-A are by default generated and validated in the PN53X chip. This is a very convenient feature. On certain times though it is useful to get full control of the transmitted data. The proprietary MIFARE Classic protocol uses for example custom (encrypted) parity bits. For interoperability it is required to be completely compatible, including the arbitrary parity bits. When this option is disabled, the functions to communicating bits should be used. */
DCO_HANDLE_PARITY = 0x01,
/** This option can be used to enable or disable the electronic field of the NFC device. */
DCO_ACTIVATE_FIELD = 0x10,
/** The internal CRYPTO1 co-processor can be used to transmit messages encrypted. This option is automatically activated after a successful MIFARE Classic authentication. */
DCO_ACTIVATE_CRYPTO1 = 0x11,
/** The default configuration defines that the PN53X chip will try indefinitely to invite a tag in the field to respond. This could be desired when it is certain a tag will enter the field. On the other hand, when this is uncertain, it will block the application. This option could best be compared to the (NON)BLOCKING option used by (socket)network programming. */
DCO_INFINITE_SELECT = 0x20,
/** If this option is enabled, frames that carry less than 4 bits are allowed. According to the standards these frames should normally be handles as invalid frames. */
DCO_ACCEPT_INVALID_FRAMES = 0x30,
/** If the NFC device should only listen to frames, it could be useful to let it gather multiple frames in a sequence. They will be stored in the internal FIFO of the PN53X chip. This could be retrieved by using the receive data functions. Note that if the chip runs out of bytes (FIFO = 64 bytes long), it will overwrite the first received frames, so quick retrieving of the received data is desirable. */
DCO_ACCEPT_MULTIPLE_FRAMES = 0x31
}dev_config_option;
////////////////////////////////////////////////////////////////////
// nfc_reader_list_passive - using InListPassiveTarget
/**
* @enum init_modulation
* @brief NFC modulation
*/
typedef enum {
/** ISO14443-A (NXP MIFARE) http://en.wikipedia.org/wiki/MIFARE */
IM_ISO14443A_106 = 0x00,
/** JIS X 6319-4 (Sony Felica) http://en.wikipedia.org/wiki/FeliCa */
IM_FELICA_212 = 0x01,
/** JIS X 6319-4 (Sony Felica) http://en.wikipedia.org/wiki/FeliCa */
IM_FELICA_424 = 0x02,
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 */
IM_ISO14443B_106 = 0x03,
/** Jewel Topaz (Innovision Research & Development) */
IM_JEWEL_106 = 0x04,
/** Active DEP */
IM_ACTIVE_DEP = 0x05,
/** Passive DEP */
IM_PASSIVE_DEP = 0x06,
}init_modulation;
/**
* @struct tag_info_dep
* @brief NFC tag information in Data Exchange Protocol
*/
typedef struct {
byte_t NFCID3i[10];
byte_t btDID;
byte_t btBSt;
byte_t btBRt;
}tag_info_dep;
/**
* @struct tag_info_iso14443a
* @brief NFC ISO14443A tag (MIFARE) information
*/
typedef struct {
byte_t abtAtqa[2];
byte_t btSak;
size_t szUidLen;
byte_t abtUid[10];
size_t szAtsLen;
byte_t abtAts[36];
}tag_info_iso14443a;
/**
* @struct tag_info_felica
* @brief NFC FeLiCa tag information
*/
typedef struct {
size_t szLen;
byte_t btResCode;
byte_t abtId[8];
byte_t abtPad[8];
byte_t abtSysCode[2];
}tag_info_felica;
/**
* @struct tag_info_iso14443b
* @brief NFC ISO14443B tag information
*/
typedef struct {
byte_t abtAtqb[12];
byte_t abtId[4];
byte_t btParam1;
byte_t btParam2;
byte_t btParam3;
byte_t btParam4;
byte_t btCid;
size_t szInfLen;
byte_t abtInf[64];
}tag_info_iso14443b;
/**
* @struct tag_info_jewel
* @brief NFC Jewel tag information
*/
typedef struct {
byte_t btSensRes[2];
byte_t btId[4];
}tag_info_jewel;
/**
* @union tag_info
* @brief Union between all kind of tags information structures.
*/
typedef union {
tag_info_iso14443a tia;
tag_info_felica tif;
tag_info_iso14443b tib;
tag_info_jewel tij;
tag_info_dep tid;
}tag_info;
////////////////////////////////////////////////////////////////////
// InDataExchange, MIFARE Classic card
typedef enum {
MC_AUTH_A = 0x60,
MC_AUTH_B = 0x61,
MC_READ = 0x30,
MC_WRITE = 0xA0,
MC_TRANSFER = 0xB0,
MC_DECREMENT = 0xC0,
MC_INCREMENT = 0xC1,
MC_STORE = 0xC2,
}mifare_cmd;
// MIFARE Classic command params
typedef struct {
byte_t abtKey[6];
byte_t abtUid[4];
}mifare_param_auth;
typedef struct {
byte_t abtData[16];
}mifare_param_data;
typedef struct {
byte_t abtValue[4];
}mifare_param_value;
typedef union {
mifare_param_auth mpa;
mifare_param_data mpd;
mifare_param_value mpv;
}mifare_param;
// Reset struct alignment to default
#pragma pack()
#endif // _LIBNFC_TYPES_H_