mirror of
https://github.com/Sucareto/ESP32-CardReader.git
synced 2024-11-27 17:00:57 +01:00
复制库,删除未使用函数:
https://github.com/elechouse/PN532 https://github.com/spicetools/spicetools
This commit is contained in:
parent
abaf6d5fe3
commit
7a279737d3
191
src/PN532.cpp
191
src/PN532.cpp
@ -15,8 +15,7 @@
|
|||||||
|
|
||||||
#define HAL(func) (_interface->func)
|
#define HAL(func) (_interface->func)
|
||||||
|
|
||||||
PN532::PN532(PN532Interface &interface)
|
PN532::PN532(PN532Interface &interface) {
|
||||||
{
|
|
||||||
_interface = &interface;
|
_interface = &interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,10 +24,11 @@ PN532::PN532(PN532Interface &interface)
|
|||||||
@brief Setups the HW
|
@brief Setups the HW
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
void PN532::begin()
|
void PN532::begin() {
|
||||||
{
|
HAL(begin)
|
||||||
HAL(begin)();
|
();
|
||||||
HAL(wakeup)();
|
HAL(wakeup)
|
||||||
|
();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
@ -38,8 +38,7 @@ void PN532::begin()
|
|||||||
@returns The chip's firmware version and ID
|
@returns The chip's firmware version and ID
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
uint32_t PN532::getFirmwareVersion(void)
|
uint32_t PN532::getFirmwareVersion(void) {
|
||||||
{
|
|
||||||
uint32_t response;
|
uint32_t response;
|
||||||
|
|
||||||
pn532_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION;
|
pn532_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION;
|
||||||
@ -75,8 +74,7 @@ uint32_t PN532::getFirmwareVersion(void)
|
|||||||
@returns The register value.
|
@returns The register value.
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
uint32_t PN532::readRegister(uint16_t reg)
|
uint32_t PN532::readRegister(uint16_t reg) {
|
||||||
{
|
|
||||||
uint32_t response;
|
uint32_t response;
|
||||||
|
|
||||||
pn532_packetbuffer[0] = PN532_COMMAND_READREGISTER;
|
pn532_packetbuffer[0] = PN532_COMMAND_READREGISTER;
|
||||||
@ -108,8 +106,7 @@ uint32_t PN532::readRegister(uint16_t reg)
|
|||||||
@returns 0 for failure, 1 for success.
|
@returns 0 for failure, 1 for success.
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
uint32_t PN532::writeRegister(uint16_t reg, uint8_t val)
|
uint32_t PN532::writeRegister(uint16_t reg, uint8_t val) {
|
||||||
{
|
|
||||||
uint32_t response;
|
uint32_t response;
|
||||||
|
|
||||||
pn532_packetbuffer[0] = PN532_COMMAND_WRITEREGISTER;
|
pn532_packetbuffer[0] = PN532_COMMAND_WRITEREGISTER;
|
||||||
@ -136,8 +133,7 @@ uint32_t PN532::writeRegister(uint16_t reg, uint8_t val)
|
|||||||
@brief Configures the SAM (Secure Access Module)
|
@brief Configures the SAM (Secure Access Module)
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
bool PN532::SAMConfig(void)
|
bool PN532::SAMConfig(void) {
|
||||||
{
|
|
||||||
pn532_packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION;
|
pn532_packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION;
|
||||||
pn532_packetbuffer[1] = 0x01; // normal mode;
|
pn532_packetbuffer[1] = 0x01; // normal mode;
|
||||||
pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second
|
pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second
|
||||||
@ -159,8 +155,7 @@ bool PN532::SAMConfig(void)
|
|||||||
@returns 1 if everything executed properly, 0 for an error
|
@returns 1 if everything executed properly, 0 for an error
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
bool PN532::setPassiveActivationRetries(uint8_t maxRetries)
|
bool PN532::setPassiveActivationRetries(uint8_t maxRetries) {
|
||||||
{
|
|
||||||
pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION;
|
pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION;
|
||||||
pn532_packetbuffer[1] = 5; // Config item 5 (MaxRetries)
|
pn532_packetbuffer[1] = 5; // Config item 5 (MaxRetries)
|
||||||
pn532_packetbuffer[2] = 0xFF; // MxRtyATR (default = 0xFF)
|
pn532_packetbuffer[2] = 0xFF; // MxRtyATR (default = 0xFF)
|
||||||
@ -190,8 +185,7 @@ bool PN532::setPassiveActivationRetries(uint8_t maxRetries)
|
|||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
bool PN532::setRFField(uint8_t autoRFCA, uint8_t rFOnOff)
|
bool PN532::setRFField(uint8_t autoRFCA, uint8_t rFOnOff) {
|
||||||
{
|
|
||||||
pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION;
|
pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION;
|
||||||
pn532_packetbuffer[1] = 1;
|
pn532_packetbuffer[1] = 1;
|
||||||
pn532_packetbuffer[2] = 0x00 | autoRFCA | rFOnOff;
|
pn532_packetbuffer[2] = 0x00 | autoRFCA | rFOnOff;
|
||||||
@ -218,8 +212,7 @@ bool PN532::setRFField(uint8_t autoRFCA, uint8_t rFOnOff)
|
|||||||
@returns 1 if everything executed properly, 0 for an error
|
@returns 1 if everything executed properly, 0 for an error
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
bool PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout)
|
bool PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout) {
|
||||||
{
|
|
||||||
pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
|
pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
|
||||||
pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later)
|
pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later)
|
||||||
pn532_packetbuffer[2] = cardbaudrate;
|
pn532_packetbuffer[2] = cardbaudrate;
|
||||||
@ -272,8 +265,7 @@ bool PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uid
|
|||||||
in the sector (block 0 relative to the current sector)
|
in the sector (block 0 relative to the current sector)
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
bool PN532::mifareclassic_IsFirstBlock (uint32_t uiBlock)
|
bool PN532::mifareclassic_IsFirstBlock(uint32_t uiBlock) {
|
||||||
{
|
|
||||||
// Test if we are in the small or big sectors
|
// Test if we are in the small or big sectors
|
||||||
if (uiBlock < 128)
|
if (uiBlock < 128)
|
||||||
return ((uiBlock) % 4 == 0);
|
return ((uiBlock) % 4 == 0);
|
||||||
@ -286,8 +278,7 @@ bool PN532::mifareclassic_IsFirstBlock (uint32_t uiBlock)
|
|||||||
Indicates whether the specified block number is the sector trailer
|
Indicates whether the specified block number is the sector trailer
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
bool PN532::mifareclassic_IsTrailerBlock (uint32_t uiBlock)
|
bool PN532::mifareclassic_IsTrailerBlock(uint32_t uiBlock) {
|
||||||
{
|
|
||||||
// Test if we are in the small or big sectors
|
// Test if we are in the small or big sectors
|
||||||
if (uiBlock < 128)
|
if (uiBlock < 128)
|
||||||
return ((uiBlock + 1) % 4 == 0);
|
return ((uiBlock + 1) % 4 == 0);
|
||||||
@ -314,13 +305,12 @@ bool PN532::mifareclassic_IsTrailerBlock (uint32_t uiBlock)
|
|||||||
@returns 1 if everything executed properly, 0 for an error
|
@returns 1 if everything executed properly, 0 for an error
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
uint8_t PN532::mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData)
|
uint8_t PN532::mifareclassic_AuthenticateBlock(uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) {
|
||||||
{
|
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
// Hang on to the key and uid data
|
// Hang on to the key and uid data
|
||||||
memcpy (_key, keyData, 6);
|
memcpy(_key, keyData, 6);
|
||||||
memcpy (_uid, uid, uidLen);
|
memcpy(_uid, uid, uidLen);
|
||||||
_uidLen = uidLen;
|
_uidLen = uidLen;
|
||||||
|
|
||||||
// Prepare the authentication command //
|
// Prepare the authentication command //
|
||||||
@ -328,7 +318,7 @@ uint8_t PN532::mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, ui
|
|||||||
pn532_packetbuffer[1] = 1; /* Max card numbers */
|
pn532_packetbuffer[1] = 1; /* Max card numbers */
|
||||||
pn532_packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_B : MIFARE_CMD_AUTH_A;
|
pn532_packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_B : MIFARE_CMD_AUTH_A;
|
||||||
pn532_packetbuffer[3] = blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */
|
pn532_packetbuffer[3] = blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */
|
||||||
memcpy (pn532_packetbuffer + 4, _key, 6);
|
memcpy(pn532_packetbuffer + 4, _key, 6);
|
||||||
for (i = 0; i < _uidLen; i++) {
|
for (i = 0; i < _uidLen; i++) {
|
||||||
pn532_packetbuffer[10 + i] = _uid[i]; /* 4 bytes card ID */
|
pn532_packetbuffer[10 + i] = _uid[i]; /* 4 bytes card ID */
|
||||||
}
|
}
|
||||||
@ -337,7 +327,8 @@ uint8_t PN532::mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, ui
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Read the response packet
|
// Read the response packet
|
||||||
HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
|
HAL(readResponse)
|
||||||
|
(pn532_packetbuffer, sizeof(pn532_packetbuffer));
|
||||||
|
|
||||||
// Check if the response is valid and we are authenticated???
|
// Check if the response is valid and we are authenticated???
|
||||||
// for an auth success it should be bytes 5-7: 0xD5 0x41 0x00
|
// for an auth success it should be bytes 5-7: 0xD5 0x41 0x00
|
||||||
@ -362,8 +353,7 @@ uint8_t PN532::mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, ui
|
|||||||
@returns 1 if everything executed properly, 0 for an error
|
@returns 1 if everything executed properly, 0 for an error
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
uint8_t PN532::mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data)
|
uint8_t PN532::mifareclassic_ReadDataBlock(uint8_t blockNumber, uint8_t *data) {
|
||||||
{
|
|
||||||
|
|
||||||
/* Prepare the command */
|
/* Prepare the command */
|
||||||
pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
|
pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
|
||||||
@ -377,7 +367,8 @@ uint8_t PN532::mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read the response packet */
|
/* Read the response packet */
|
||||||
HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
|
HAL(readResponse)
|
||||||
|
(pn532_packetbuffer, sizeof(pn532_packetbuffer));
|
||||||
|
|
||||||
/* If byte 8 isn't 0x00 we probably have an error */
|
/* If byte 8 isn't 0x00 we probably have an error */
|
||||||
if (pn532_packetbuffer[0] != 0x00) {
|
if (pn532_packetbuffer[0] != 0x00) {
|
||||||
@ -386,7 +377,7 @@ uint8_t PN532::mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data)
|
|||||||
|
|
||||||
/* Copy the 16 data bytes to the output buffer */
|
/* Copy the 16 data bytes to the output buffer */
|
||||||
/* Block content starts at byte 9 of a valid response */
|
/* Block content starts at byte 9 of a valid response */
|
||||||
memcpy (data, pn532_packetbuffer + 1, 16);
|
memcpy(data, pn532_packetbuffer + 1, 16);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -403,14 +394,13 @@ uint8_t PN532::mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data)
|
|||||||
@returns 1 if everything executed properly, 0 for an error
|
@returns 1 if everything executed properly, 0 for an error
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
uint8_t PN532::mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data)
|
uint8_t PN532::mifareclassic_WriteDataBlock(uint8_t blockNumber, uint8_t *data) {
|
||||||
{
|
|
||||||
/* Prepare the first command */
|
/* Prepare the first command */
|
||||||
pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
|
pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
|
||||||
pn532_packetbuffer[1] = 1; /* Card number */
|
pn532_packetbuffer[1] = 1; /* Card number */
|
||||||
pn532_packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
|
pn532_packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
|
||||||
pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
|
pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
|
||||||
memcpy (pn532_packetbuffer + 4, data, 16); /* Data Payload */
|
memcpy(pn532_packetbuffer + 4, data, 16); /* Data Payload */
|
||||||
|
|
||||||
/* Send the command */
|
/* Send the command */
|
||||||
if (HAL(writeCommand)(pn532_packetbuffer, 20)) {
|
if (HAL(writeCommand)(pn532_packetbuffer, 20)) {
|
||||||
@ -431,8 +421,7 @@ uint8_t PN532::mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data)
|
|||||||
@param responseLength Pointer to the response data length
|
@param responseLength Pointer to the response data length
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
bool PN532::inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength)
|
bool PN532::inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength) {
|
||||||
{
|
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE;
|
pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE;
|
||||||
@ -472,8 +461,7 @@ bool PN532::inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response,
|
|||||||
peer acting as card/responder.
|
peer acting as card/responder.
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
bool PN532::inListPassiveTarget()
|
bool PN532::inListPassiveTarget() {
|
||||||
{
|
|
||||||
pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
|
pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
|
||||||
pn532_packetbuffer[1] = 1;
|
pn532_packetbuffer[1] = 1;
|
||||||
pn532_packetbuffer[2] = 0;
|
pn532_packetbuffer[2] = 0;
|
||||||
@ -496,7 +484,7 @@ bool PN532::inListPassiveTarget()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t PN532::tgInitAsTarget(const uint8_t* command, const uint8_t len, const uint16_t timeout){
|
int8_t PN532::tgInitAsTarget(const uint8_t *command, const uint8_t len, const uint16_t timeout) {
|
||||||
|
|
||||||
int8_t status = HAL(writeCommand)(command, len);
|
int8_t status = HAL(writeCommand)(command, len);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
@ -516,8 +504,7 @@ int8_t PN532::tgInitAsTarget(const uint8_t* command, const uint8_t len, const ui
|
|||||||
/**
|
/**
|
||||||
* Peer to Peer
|
* Peer to Peer
|
||||||
*/
|
*/
|
||||||
int8_t PN532::tgInitAsTarget(uint16_t timeout)
|
int8_t PN532::tgInitAsTarget(uint16_t timeout) {
|
||||||
{
|
|
||||||
const uint8_t command[] = {
|
const uint8_t command[] = {
|
||||||
PN532_COMMAND_TGINITASTARGET,
|
PN532_COMMAND_TGINITASTARGET,
|
||||||
0,
|
0,
|
||||||
@ -531,13 +518,12 @@ int8_t PN532::tgInitAsTarget(uint16_t timeout)
|
|||||||
|
|
||||||
0x01, 0xFE, 0x0F, 0xBB, 0xBA, 0xA6, 0xC9, 0x89, 0x00, 0x00, //NFCID3t: Change this to desired value
|
0x01, 0xFE, 0x0F, 0xBB, 0xBA, 0xA6, 0xC9, 0x89, 0x00, 0x00, //NFCID3t: Change this to desired value
|
||||||
|
|
||||||
0x06, 0x46, 0x66, 0x6D, 0x01, 0x01, 0x10, 0x00// LLCP magic number and version parameter
|
0x06, 0x46, 0x66, 0x6D, 0x01, 0x01, 0x10, 0x00 // LLCP magic number and version parameter
|
||||||
};
|
};
|
||||||
return tgInitAsTarget(command, sizeof(command), timeout);
|
return tgInitAsTarget(command, sizeof(command), timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t PN532::tgGetData(uint8_t *buf, uint8_t len)
|
int16_t PN532::tgGetData(uint8_t *buf, uint8_t len) {
|
||||||
{
|
|
||||||
buf[0] = PN532_COMMAND_TGGETDATA;
|
buf[0] = PN532_COMMAND_TGGETDATA;
|
||||||
|
|
||||||
if (HAL(writeCommand)(buf, 1)) {
|
if (HAL(writeCommand)(buf, 1)) {
|
||||||
@ -563,8 +549,7 @@ int16_t PN532::tgGetData(uint8_t *buf, uint8_t len)
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PN532::tgSetData(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
|
bool PN532::tgSetData(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen) {
|
||||||
{
|
|
||||||
if (hlen > (sizeof(pn532_packetbuffer) - 1)) {
|
if (hlen > (sizeof(pn532_packetbuffer) - 1)) {
|
||||||
if ((body != 0) || (header == pn532_packetbuffer)) {
|
if ((body != 0) || (header == pn532_packetbuffer)) {
|
||||||
return false;
|
return false;
|
||||||
@ -575,7 +560,7 @@ bool PN532::tgSetData(const uint8_t *header, uint8_t hlen, const uint8_t *body,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int8_t i = hlen - 1; i >= 0; i--){
|
for (int8_t i = hlen - 1; i >= 0; i--) {
|
||||||
pn532_packetbuffer[i + 1] = header[i];
|
pn532_packetbuffer[i + 1] = header[i];
|
||||||
}
|
}
|
||||||
pn532_packetbuffer[0] = PN532_COMMAND_TGSETDATA;
|
pn532_packetbuffer[0] = PN532_COMMAND_TGSETDATA;
|
||||||
@ -596,7 +581,7 @@ bool PN532::tgSetData(const uint8_t *header, uint8_t hlen, const uint8_t *body,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t PN532::inRelease(const uint8_t relevantTarget){
|
int16_t PN532::inRelease(const uint8_t relevantTarget) {
|
||||||
|
|
||||||
pn532_packetbuffer[0] = PN532_COMMAND_INRELEASE;
|
pn532_packetbuffer[0] = PN532_COMMAND_INRELEASE;
|
||||||
pn532_packetbuffer[1] = relevantTarget;
|
pn532_packetbuffer[1] = relevantTarget;
|
||||||
@ -629,8 +614,7 @@ int16_t PN532::inRelease(const uint8_t relevantTarget){
|
|||||||
< 0: error
|
< 0: error
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
int8_t PN532::felica_Polling(uint16_t systemCode, uint8_t requestCode, uint8_t * idm, uint8_t * pmm, uint16_t *systemCodeResponse, uint16_t timeout)
|
int8_t PN532::felica_Polling(uint16_t systemCode, uint8_t requestCode, uint8_t *idm, uint8_t *pmm, uint16_t *systemCodeResponse, uint16_t timeout) {
|
||||||
{
|
|
||||||
pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
|
pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
|
||||||
pn532_packetbuffer[1] = 1;
|
pn532_packetbuffer[1] = 1;
|
||||||
pn532_packetbuffer[2] = 1;
|
pn532_packetbuffer[2] = 1;
|
||||||
@ -665,14 +649,14 @@ int8_t PN532::felica_Polling(uint16_t systemCode, uint8_t requestCode, uint8_t *
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
for (i=0; i<8; ++i) {
|
for (i = 0; i < 8; ++i) {
|
||||||
idm[i] = pn532_packetbuffer[4+i];
|
idm[i] = pn532_packetbuffer[4 + i];
|
||||||
_felicaIDm[i] = pn532_packetbuffer[4+i];
|
_felicaIDm[i] = pn532_packetbuffer[4 + i];
|
||||||
pmm[i] = pn532_packetbuffer[12+i];
|
pmm[i] = pn532_packetbuffer[12 + i];
|
||||||
_felicaPMm[i] = pn532_packetbuffer[12+i];
|
_felicaPMm[i] = pn532_packetbuffer[12 + i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( responseLength == 20 ) {
|
if (responseLength == 20) {
|
||||||
*systemCodeResponse = (uint16_t)((pn532_packetbuffer[20] << 8) + pn532_packetbuffer[21]);
|
*systemCodeResponse = (uint16_t)((pn532_packetbuffer[20] << 8) + pn532_packetbuffer[21]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -691,8 +675,7 @@ int8_t PN532::felica_Polling(uint16_t systemCode, uint8_t requestCode, uint8_t *
|
|||||||
< 0: error
|
< 0: error
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
int8_t PN532::felica_SendCommand (const uint8_t *command, uint8_t commandlength, uint8_t *response, uint8_t *responseLength)
|
int8_t PN532::felica_SendCommand(const uint8_t *command, uint8_t commandlength, uint8_t *response, uint8_t *responseLength) {
|
||||||
{
|
|
||||||
if (commandlength > 0xFE) {
|
if (commandlength > 0xFE) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -712,13 +695,13 @@ int8_t PN532::felica_SendCommand (const uint8_t *command, uint8_t commandlength,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check status (pn532_packetbuffer[0])
|
// Check status (pn532_packetbuffer[0])
|
||||||
if ((pn532_packetbuffer[0] & 0x3F)!=0) {
|
if ((pn532_packetbuffer[0] & 0x3F) != 0) {
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// length check
|
// length check
|
||||||
*responseLength = pn532_packetbuffer[1] - 1;
|
*responseLength = pn532_packetbuffer[1] - 1;
|
||||||
if ( (status - 2) != *responseLength) {
|
if ((status - 2) != *responseLength) {
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -739,26 +722,25 @@ int8_t PN532::felica_SendCommand (const uint8_t *command, uint8_t commandlength,
|
|||||||
< 0: error
|
< 0: error
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
int8_t PN532::felica_RequestService(uint8_t numNode, uint16_t *nodeCodeList, uint16_t *keyVersions)
|
int8_t PN532::felica_RequestService(uint8_t numNode, uint16_t *nodeCodeList, uint16_t *keyVersions) {
|
||||||
{
|
|
||||||
if (numNode > FELICA_REQ_SERVICE_MAX_NODE_NUM) {
|
if (numNode > FELICA_REQ_SERVICE_MAX_NODE_NUM) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t i, j=0;
|
uint8_t i, j = 0;
|
||||||
uint8_t cmdLen = 1 + 8 + 1 + 2*numNode;
|
uint8_t cmdLen = 1 + 8 + 1 + 2 * numNode;
|
||||||
uint8_t cmd[cmdLen];
|
uint8_t cmd[cmdLen];
|
||||||
cmd[j++] = FELICA_CMD_REQUEST_SERVICE;
|
cmd[j++] = FELICA_CMD_REQUEST_SERVICE;
|
||||||
for (i=0; i<8; ++i) {
|
for (i = 0; i < 8; ++i) {
|
||||||
cmd[j++] = _felicaIDm[i];
|
cmd[j++] = _felicaIDm[i];
|
||||||
}
|
}
|
||||||
cmd[j++] = numNode;
|
cmd[j++] = numNode;
|
||||||
for (i=0; i<numNode; ++i) {
|
for (i = 0; i < numNode; ++i) {
|
||||||
cmd[j++] = nodeCodeList[i] & 0xFF;
|
cmd[j++] = nodeCodeList[i] & 0xFF;
|
||||||
cmd[j++] = (nodeCodeList[i] >> 8) & 0xff;
|
cmd[j++] = (nodeCodeList[i] >> 8) & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t response[10+2*numNode];
|
uint8_t response[10 + 2 * numNode];
|
||||||
uint8_t responseLength;
|
uint8_t responseLength;
|
||||||
|
|
||||||
if (felica_SendCommand(cmd, cmdLen, response, &responseLength) != 1) {
|
if (felica_SendCommand(cmd, cmdLen, response, &responseLength) != 1) {
|
||||||
@ -766,12 +748,12 @@ int8_t PN532::felica_RequestService(uint8_t numNode, uint16_t *nodeCodeList, uin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// length check
|
// length check
|
||||||
if ( responseLength != 10+2*numNode ) {
|
if (responseLength != 10 + 2 * numNode) {
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0; i<numNode; i++) {
|
for (i = 0; i < numNode; i++) {
|
||||||
keyVersions[i] = (uint16_t)(response[10+i*2] + (response[10+i*2+1] << 8));
|
keyVersions[i] = (uint16_t)(response[10 + i * 2] + (response[10 + i * 2 + 1] << 8));
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -786,8 +768,7 @@ int8_t PN532::felica_RequestService(uint8_t numNode, uint16_t *nodeCodeList, uin
|
|||||||
< 0: error
|
< 0: error
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
int8_t PN532::felica_RequestResponse(uint8_t * mode)
|
int8_t PN532::felica_RequestResponse(uint8_t *mode) {
|
||||||
{
|
|
||||||
uint8_t cmd[9];
|
uint8_t cmd[9];
|
||||||
cmd[0] = FELICA_CMD_REQUEST_RESPONSE;
|
cmd[0] = FELICA_CMD_REQUEST_RESPONSE;
|
||||||
memcpy(&cmd[1], _felicaIDm, 8);
|
memcpy(&cmd[1], _felicaIDm, 8);
|
||||||
@ -799,7 +780,7 @@ int8_t PN532::felica_RequestResponse(uint8_t * mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// length check
|
// length check
|
||||||
if ( responseLength != 10) {
|
if (responseLength != 10) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -820,8 +801,7 @@ int8_t PN532::felica_RequestResponse(uint8_t * mode)
|
|||||||
< 0: error
|
< 0: error
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
int8_t PN532::felica_ReadWithoutEncryption (uint8_t numService, const uint16_t *serviceCodeList, uint8_t numBlock, const uint16_t *blockList, uint8_t blockData[][16])
|
int8_t PN532::felica_ReadWithoutEncryption(uint8_t numService, const uint16_t *serviceCodeList, uint8_t numBlock, const uint16_t *blockList, uint8_t blockData[][16]) {
|
||||||
{
|
|
||||||
if (numService > FELICA_READ_MAX_SERVICE_NUM) {
|
if (numService > FELICA_READ_MAX_SERVICE_NUM) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -829,43 +809,43 @@ int8_t PN532::felica_ReadWithoutEncryption (uint8_t numService, const uint16_t *
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t i, j=0, k;
|
uint8_t i, j = 0, k;
|
||||||
uint8_t cmdLen = 1 + 8 + 1 + 2*numService + 1 + 2*numBlock;
|
uint8_t cmdLen = 1 + 8 + 1 + 2 * numService + 1 + 2 * numBlock;
|
||||||
uint8_t cmd[cmdLen];
|
uint8_t cmd[cmdLen];
|
||||||
cmd[j++] = FELICA_CMD_READ_WITHOUT_ENCRYPTION;
|
cmd[j++] = FELICA_CMD_READ_WITHOUT_ENCRYPTION;
|
||||||
for (i=0; i<8; ++i) {
|
for (i = 0; i < 8; ++i) {
|
||||||
cmd[j++] = _felicaIDm[i];
|
cmd[j++] = _felicaIDm[i];
|
||||||
}
|
}
|
||||||
cmd[j++] = numService;
|
cmd[j++] = numService;
|
||||||
for (i=0; i<numService; ++i) {
|
for (i = 0; i < numService; ++i) {
|
||||||
cmd[j++] = serviceCodeList[i] & 0xFF;
|
cmd[j++] = serviceCodeList[i] & 0xFF;
|
||||||
cmd[j++] = (serviceCodeList[i] >> 8) & 0xff;
|
cmd[j++] = (serviceCodeList[i] >> 8) & 0xff;
|
||||||
}
|
}
|
||||||
cmd[j++] = numBlock;
|
cmd[j++] = numBlock;
|
||||||
for (i=0; i<numBlock; ++i) {
|
for (i = 0; i < numBlock; ++i) {
|
||||||
cmd[j++] = (blockList[i] >> 8) & 0xFF;
|
cmd[j++] = (blockList[i] >> 8) & 0xFF;
|
||||||
cmd[j++] = blockList[i] & 0xff;
|
cmd[j++] = blockList[i] & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t response[12+16*numBlock];
|
uint8_t response[12 + 16 * numBlock];
|
||||||
uint8_t responseLength;
|
uint8_t responseLength;
|
||||||
if (felica_SendCommand(cmd, cmdLen, response, &responseLength) != 1) {
|
if (felica_SendCommand(cmd, cmdLen, response, &responseLength) != 1) {
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// length check
|
// length check
|
||||||
if ( responseLength != 12+16*numBlock ) {
|
if (responseLength != 12 + 16 * numBlock) {
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// status flag check
|
// status flag check
|
||||||
if ( response[9] != 0 || response[10] != 0 ) {
|
if (response[9] != 0 || response[10] != 0) {
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
k = 12;
|
k = 12;
|
||||||
for(i=0; i<numBlock; i++ ) {
|
for (i = 0; i < numBlock; i++) {
|
||||||
for(j=0; j<16; j++ ) {
|
for (j = 0; j < 16; j++) {
|
||||||
blockData[i][j] = response[k++];
|
blockData[i][j] = response[k++];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -887,8 +867,7 @@ int8_t PN532::felica_ReadWithoutEncryption (uint8_t numService, const uint16_t *
|
|||||||
< 0: error
|
< 0: error
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
int8_t PN532::felica_WriteWithoutEncryption (uint8_t numService, const uint16_t *serviceCodeList, uint8_t numBlock, const uint16_t *blockList, uint8_t blockData[][16])
|
int8_t PN532::felica_WriteWithoutEncryption(uint8_t numService, const uint16_t *serviceCodeList, uint8_t numBlock, const uint16_t *blockList, uint8_t blockData[][16]) {
|
||||||
{
|
|
||||||
if (numService > FELICA_WRITE_MAX_SERVICE_NUM) {
|
if (numService > FELICA_WRITE_MAX_SERVICE_NUM) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -896,25 +875,25 @@ int8_t PN532::felica_WriteWithoutEncryption (uint8_t numService, const uint16_t
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t i, j=0, k;
|
uint8_t i, j = 0, k;
|
||||||
uint8_t cmdLen = 1 + 8 + 1 + 2*numService + 1 + 2*numBlock + 16 * numBlock;
|
uint8_t cmdLen = 1 + 8 + 1 + 2 * numService + 1 + 2 * numBlock + 16 * numBlock;
|
||||||
uint8_t cmd[cmdLen];
|
uint8_t cmd[cmdLen];
|
||||||
cmd[j++] = FELICA_CMD_WRITE_WITHOUT_ENCRYPTION;
|
cmd[j++] = FELICA_CMD_WRITE_WITHOUT_ENCRYPTION;
|
||||||
for (i=0; i<8; ++i) {
|
for (i = 0; i < 8; ++i) {
|
||||||
cmd[j++] = _felicaIDm[i];
|
cmd[j++] = _felicaIDm[i];
|
||||||
}
|
}
|
||||||
cmd[j++] = numService;
|
cmd[j++] = numService;
|
||||||
for (i=0; i<numService; ++i) {
|
for (i = 0; i < numService; ++i) {
|
||||||
cmd[j++] = serviceCodeList[i] & 0xFF;
|
cmd[j++] = serviceCodeList[i] & 0xFF;
|
||||||
cmd[j++] = (serviceCodeList[i] >> 8) & 0xff;
|
cmd[j++] = (serviceCodeList[i] >> 8) & 0xff;
|
||||||
}
|
}
|
||||||
cmd[j++] = numBlock;
|
cmd[j++] = numBlock;
|
||||||
for (i=0; i<numBlock; ++i) {
|
for (i = 0; i < numBlock; ++i) {
|
||||||
cmd[j++] = (blockList[i] >> 8) & 0xFF;
|
cmd[j++] = (blockList[i] >> 8) & 0xFF;
|
||||||
cmd[j++] = blockList[i] & 0xff;
|
cmd[j++] = blockList[i] & 0xff;
|
||||||
}
|
}
|
||||||
for (i=0; i<numBlock; ++i) {
|
for (i = 0; i < numBlock; ++i) {
|
||||||
for(k=0; k<16; k++) {
|
for (k = 0; k < 16; k++) {
|
||||||
cmd[j++] = blockData[i][k];
|
cmd[j++] = blockData[i][k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -926,12 +905,12 @@ int8_t PN532::felica_WriteWithoutEncryption (uint8_t numService, const uint16_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
// length check
|
// length check
|
||||||
if ( responseLength != 11 ) {
|
if (responseLength != 11) {
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// status flag check
|
// status flag check
|
||||||
if ( response[9] != 0 || response[10] != 0 ) {
|
if (response[9] != 0 || response[10] != 0) {
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -948,8 +927,7 @@ int8_t PN532::felica_WriteWithoutEncryption (uint8_t numService, const uint16_t
|
|||||||
< 0: error
|
< 0: error
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
int8_t PN532::felica_RequestSystemCode(uint8_t * numSystemCode, uint16_t *systemCodeList)
|
int8_t PN532::felica_RequestSystemCode(uint8_t *numSystemCode, uint16_t *systemCodeList) {
|
||||||
{
|
|
||||||
uint8_t cmd[9];
|
uint8_t cmd[9];
|
||||||
cmd[0] = FELICA_CMD_REQUEST_SYSTEM_CODE;
|
cmd[0] = FELICA_CMD_REQUEST_SYSTEM_CODE;
|
||||||
memcpy(&cmd[1], _felicaIDm, 8);
|
memcpy(&cmd[1], _felicaIDm, 8);
|
||||||
@ -962,13 +940,13 @@ int8_t PN532::felica_RequestSystemCode(uint8_t * numSystemCode, uint16_t *system
|
|||||||
*numSystemCode = response[9];
|
*numSystemCode = response[9];
|
||||||
|
|
||||||
// length check
|
// length check
|
||||||
if ( responseLength < 10 + 2 * *numSystemCode ) {
|
if (responseLength < 10 + 2 * *numSystemCode) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
for(i=0; i<*numSystemCode; i++) {
|
for (i = 0; i < *numSystemCode; i++) {
|
||||||
systemCodeList[i] = (uint16_t)((response[10+i*2]<< 8) + response[10+i*2+1]);
|
systemCodeList[i] = (uint16_t)((response[10 + i * 2] << 8) + response[10 + i * 2 + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -982,8 +960,7 @@ int8_t PN532::felica_RequestSystemCode(uint8_t * numSystemCode, uint16_t *system
|
|||||||
< 0: error
|
< 0: error
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
int8_t PN532::felica_Release()
|
int8_t PN532::felica_Release() {
|
||||||
{
|
|
||||||
// InRelease
|
// InRelease
|
||||||
pn532_packetbuffer[0] = PN532_COMMAND_INRELEASE;
|
pn532_packetbuffer[0] = PN532_COMMAND_INRELEASE;
|
||||||
pn532_packetbuffer[1] = 0x00; // All target
|
pn532_packetbuffer[1] = 0x00; // All target
|
||||||
@ -999,7 +976,7 @@ int8_t PN532::felica_Release()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check status (pn532_packetbuffer[0])
|
// Check status (pn532_packetbuffer[0])
|
||||||
if ((pn532_packetbuffer[0] & 0x3F)!=0) {
|
if ((pn532_packetbuffer[0] & 0x3F) != 0) {
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
25
src/PN532.h
25
src/PN532.h
@ -81,8 +81,7 @@
|
|||||||
#define FELICA_WRITE_MAX_BLOCK_NUM 10 // for typical FeliCa card
|
#define FELICA_WRITE_MAX_BLOCK_NUM 10 // for typical FeliCa card
|
||||||
#define FELICA_REQ_SERVICE_MAX_NODE_NUM 32
|
#define FELICA_REQ_SERVICE_MAX_NODE_NUM 32
|
||||||
|
|
||||||
class PN532
|
class PN532 {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
PN532(PN532Interface &interface);
|
PN532(PN532Interface &interface);
|
||||||
|
|
||||||
@ -104,7 +103,7 @@ public:
|
|||||||
* < 0 failed
|
* < 0 failed
|
||||||
*/
|
*/
|
||||||
int8_t tgInitAsTarget(uint16_t timeout = 0);
|
int8_t tgInitAsTarget(uint16_t timeout = 0);
|
||||||
int8_t tgInitAsTarget(const uint8_t* command, const uint8_t len, const uint16_t timeout = 0);
|
int8_t tgInitAsTarget(const uint8_t *command, const uint8_t len, const uint16_t timeout = 0);
|
||||||
|
|
||||||
int16_t tgGetData(uint8_t *buf, uint8_t len);
|
int16_t tgGetData(uint8_t *buf, uint8_t len);
|
||||||
bool tgSetData(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0);
|
bool tgSetData(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0);
|
||||||
@ -117,19 +116,19 @@ public:
|
|||||||
bool inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength);
|
bool inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength);
|
||||||
|
|
||||||
// Mifare Classic functions
|
// Mifare Classic functions
|
||||||
bool mifareclassic_IsFirstBlock (uint32_t uiBlock);
|
bool mifareclassic_IsFirstBlock(uint32_t uiBlock);
|
||||||
bool mifareclassic_IsTrailerBlock (uint32_t uiBlock);
|
bool mifareclassic_IsTrailerBlock(uint32_t uiBlock);
|
||||||
uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData);
|
uint8_t mifareclassic_AuthenticateBlock(uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData);
|
||||||
uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data);
|
uint8_t mifareclassic_ReadDataBlock(uint8_t blockNumber, uint8_t *data);
|
||||||
uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data);
|
uint8_t mifareclassic_WriteDataBlock(uint8_t blockNumber, uint8_t *data);
|
||||||
|
|
||||||
// FeliCa Functions
|
// FeliCa Functions
|
||||||
int8_t felica_Polling(uint16_t systemCode, uint8_t requestCode, uint8_t *idm, uint8_t *pmm, uint16_t *systemCodeResponse, uint16_t timeout=1000);
|
int8_t felica_Polling(uint16_t systemCode, uint8_t requestCode, uint8_t *idm, uint8_t *pmm, uint16_t *systemCodeResponse, uint16_t timeout = 1000);
|
||||||
int8_t felica_SendCommand (const uint8_t * command, uint8_t commandlength, uint8_t * response, uint8_t * responseLength);
|
int8_t felica_SendCommand(const uint8_t *command, uint8_t commandlength, uint8_t *response, uint8_t *responseLength);
|
||||||
int8_t felica_RequestService(uint8_t numNode, uint16_t *nodeCodeList, uint16_t *keyVersions) ;
|
int8_t felica_RequestService(uint8_t numNode, uint16_t *nodeCodeList, uint16_t *keyVersions);
|
||||||
int8_t felica_RequestResponse(uint8_t *mode);
|
int8_t felica_RequestResponse(uint8_t *mode);
|
||||||
int8_t felica_ReadWithoutEncryption (uint8_t numService, const uint16_t *serviceCodeList, uint8_t numBlock, const uint16_t *blockList, uint8_t blockData[][16]);
|
int8_t felica_ReadWithoutEncryption(uint8_t numService, const uint16_t *serviceCodeList, uint8_t numBlock, const uint16_t *blockList, uint8_t blockData[][16]);
|
||||||
int8_t felica_WriteWithoutEncryption (uint8_t numService, const uint16_t *serviceCodeList, uint8_t numBlock, const uint16_t *blockList, uint8_t blockData[][16]);
|
int8_t felica_WriteWithoutEncryption(uint8_t numService, const uint16_t *serviceCodeList, uint8_t numBlock, const uint16_t *blockList, uint8_t blockData[][16]);
|
||||||
int8_t felica_RequestSystemCode(uint8_t *numSystemCode, uint16_t *systemCodeList);
|
int8_t felica_RequestSystemCode(uint8_t *numSystemCode, uint16_t *systemCodeList);
|
||||||
int8_t felica_Release();
|
int8_t felica_Release();
|
||||||
|
|
||||||
|
@ -20,12 +20,12 @@
|
|||||||
#define PN532_INVALID_FRAME (-3)
|
#define PN532_INVALID_FRAME (-3)
|
||||||
#define PN532_NO_SPACE (-4)
|
#define PN532_NO_SPACE (-4)
|
||||||
|
|
||||||
#define REVERSE_BITS_ORDER(b) b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; \
|
#define REVERSE_BITS_ORDER(b) \
|
||||||
|
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; \
|
||||||
b = (b & 0xCC) >> 2 | (b & 0x33) << 2; \
|
b = (b & 0xCC) >> 2 | (b & 0x33) << 2; \
|
||||||
b = (b & 0xAA) >> 1 | (b & 0x55) << 1
|
b = (b & 0xAA) >> 1 | (b & 0x55) << 1
|
||||||
|
|
||||||
class PN532Interface
|
class PN532Interface {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
virtual void begin() = 0;
|
virtual void begin() = 0;
|
||||||
virtual void wakeup() = 0;
|
virtual void wakeup() = 0;
|
||||||
@ -53,4 +53,3 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -9,15 +9,13 @@
|
|||||||
#define DATA_WRITE 1
|
#define DATA_WRITE 1
|
||||||
#define DATA_READ 3
|
#define DATA_READ 3
|
||||||
|
|
||||||
PN532_SPI::PN532_SPI(SPIClass &spi, uint8_t ss)
|
PN532_SPI::PN532_SPI(SPIClass &spi, uint8_t ss) {
|
||||||
{
|
|
||||||
command = 0;
|
command = 0;
|
||||||
_spi = &spi;
|
_spi = &spi;
|
||||||
_ss = ss;
|
_ss = ss;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PN532_SPI::begin()
|
void PN532_SPI::begin() {
|
||||||
{
|
|
||||||
pinMode(_ss, OUTPUT);
|
pinMode(_ss, OUTPUT);
|
||||||
|
|
||||||
_spi->begin();
|
_spi->begin();
|
||||||
@ -29,11 +27,9 @@ void PN532_SPI::begin()
|
|||||||
/** DUE spi library does not support SPI_CLOCK_DIV8 macro */
|
/** DUE spi library does not support SPI_CLOCK_DIV8 macro */
|
||||||
_spi->setClockDivider(42); // set clock 2MHz(max: 5MHz)
|
_spi->setClockDivider(42); // set clock 2MHz(max: 5MHz)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PN532_SPI::wakeup()
|
void PN532_SPI::wakeup() {
|
||||||
{
|
|
||||||
digitalWrite(_ss, LOW);
|
digitalWrite(_ss, LOW);
|
||||||
delay(2);
|
delay(2);
|
||||||
digitalWrite(_ss, HIGH);
|
digitalWrite(_ss, HIGH);
|
||||||
@ -41,8 +37,7 @@ void PN532_SPI::wakeup()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int8_t PN532_SPI::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
|
int8_t PN532_SPI::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen) {
|
||||||
{
|
|
||||||
command = header[0];
|
command = header[0];
|
||||||
writeFrame(header, hlen, body, blen);
|
writeFrame(header, hlen, body, blen);
|
||||||
|
|
||||||
@ -60,8 +55,7 @@ int8_t PN532_SPI::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t PN532_SPI::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout)
|
int16_t PN532_SPI::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout) {
|
||||||
{
|
|
||||||
uint16_t time = 0;
|
uint16_t time = 0;
|
||||||
while (!isReady()) {
|
while (!isReady()) {
|
||||||
delay(1);
|
delay(1);
|
||||||
@ -114,7 +108,6 @@ int16_t PN532_SPI::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout)
|
|||||||
for (uint8_t i = 0; i < length; i++) {
|
for (uint8_t i = 0; i < length; i++) {
|
||||||
buf[i] = read();
|
buf[i] = read();
|
||||||
sum += buf[i];
|
sum += buf[i];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t checksum = read();
|
uint8_t checksum = read();
|
||||||
@ -132,8 +125,7 @@ int16_t PN532_SPI::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PN532_SPI::isReady()
|
bool PN532_SPI::isReady() {
|
||||||
{
|
|
||||||
digitalWrite(_ss, LOW);
|
digitalWrite(_ss, LOW);
|
||||||
|
|
||||||
write(STATUS_READ);
|
write(STATUS_READ);
|
||||||
@ -142,8 +134,7 @@ bool PN532_SPI::isReady()
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PN532_SPI::writeFrame(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
|
void PN532_SPI::writeFrame(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen) {
|
||||||
{
|
|
||||||
digitalWrite(_ss, LOW);
|
digitalWrite(_ss, LOW);
|
||||||
delay(2); // wake up PN532
|
delay(2); // wake up PN532
|
||||||
|
|
||||||
@ -163,12 +154,10 @@ void PN532_SPI::writeFrame(const uint8_t *header, uint8_t hlen, const uint8_t *b
|
|||||||
for (uint8_t i = 0; i < hlen; i++) {
|
for (uint8_t i = 0; i < hlen; i++) {
|
||||||
write(header[i]);
|
write(header[i]);
|
||||||
sum += header[i];
|
sum += header[i];
|
||||||
|
|
||||||
}
|
}
|
||||||
for (uint8_t i = 0; i < blen; i++) {
|
for (uint8_t i = 0; i < blen; i++) {
|
||||||
write(body[i]);
|
write(body[i]);
|
||||||
sum += body[i];
|
sum += body[i];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t checksum = ~sum + 1; // checksum of TFI + DATA
|
uint8_t checksum = ~sum + 1; // checksum of TFI + DATA
|
||||||
@ -176,12 +165,10 @@ void PN532_SPI::writeFrame(const uint8_t *header, uint8_t hlen, const uint8_t *b
|
|||||||
write(PN532_POSTAMBLE);
|
write(PN532_POSTAMBLE);
|
||||||
|
|
||||||
digitalWrite(_ss, HIGH);
|
digitalWrite(_ss, HIGH);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t PN532_SPI::readAckFrame()
|
int8_t PN532_SPI::readAckFrame() {
|
||||||
{
|
const uint8_t PN532_ACK[] = { 0, 0, 0xFF, 0, 0xFF, 0 };
|
||||||
const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0};
|
|
||||||
|
|
||||||
uint8_t ackBuf[sizeof(PN532_ACK)];
|
uint8_t ackBuf[sizeof(PN532_ACK)];
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ public:
|
|||||||
int16_t readResponse(uint8_t buf[], uint8_t len, uint16_t timeout);
|
int16_t readResponse(uint8_t buf[], uint8_t len, uint16_t timeout);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SPIClass* _spi;
|
SPIClass *_spi;
|
||||||
uint8_t _ss;
|
uint8_t _ss;
|
||||||
uint8_t command;
|
uint8_t command;
|
||||||
|
|
||||||
|
76
src/connection.h
Normal file
76
src/connection.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
库代码来自:https://github.com/spicetools/spicetools/tree/master/api/resources/arduino
|
||||||
|
删除了未使用的函数。
|
||||||
|
*/
|
||||||
|
#ifndef SPICEAPI_CONNECTION_H
|
||||||
|
#define SPICEAPI_CONNECTION_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifndef SPICEAPI_INTERFACE
|
||||||
|
#define SPICEAPI_INTERFACE Serial
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace spiceapi {
|
||||||
|
|
||||||
|
class Connection {
|
||||||
|
private:
|
||||||
|
uint8_t* receive_buffer;
|
||||||
|
size_t receive_buffer_size;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Connection(size_t receive_buffer_size);
|
||||||
|
void reset();
|
||||||
|
const char* request(char* json);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
spiceapi::Connection::Connection(size_t receive_buffer_size) {
|
||||||
|
this->receive_buffer = new uint8_t[receive_buffer_size];
|
||||||
|
this->receive_buffer_size = receive_buffer_size;
|
||||||
|
this->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void spiceapi::Connection::reset() {
|
||||||
|
|
||||||
|
// drop all input
|
||||||
|
while (SPICEAPI_INTERFACE.available()) {
|
||||||
|
SPICEAPI_INTERFACE.read();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* spiceapi::Connection::request(char* json_data) {
|
||||||
|
auto json_len = strlen(json_data) + 1;
|
||||||
|
|
||||||
|
// send
|
||||||
|
auto send_result = SPICEAPI_INTERFACE.write((const char*)json_data, (int)json_len);
|
||||||
|
SPICEAPI_INTERFACE.flush();
|
||||||
|
if (send_result < (int)json_len) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// receive
|
||||||
|
size_t receive_data_len = 0;
|
||||||
|
while (SPICEAPI_INTERFACE) {
|
||||||
|
|
||||||
|
// read single byte
|
||||||
|
auto b = SPICEAPI_INTERFACE.read();
|
||||||
|
if (b < 0) continue;
|
||||||
|
receive_buffer[receive_data_len++] = b;
|
||||||
|
|
||||||
|
// check for buffer overflow
|
||||||
|
if (receive_data_len >= receive_buffer_size) {
|
||||||
|
this->reset();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for message end
|
||||||
|
if (receive_buffer[receive_data_len - 1] == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return resulting json
|
||||||
|
return (const char*)&receive_buffer[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //SPICEAPI_CONNECTION_H
|
140
src/wrappers.h
Normal file
140
src/wrappers.h
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
库代码来自:https://github.com/spicetools/spicetools/tree/master/api/resources/arduino
|
||||||
|
删除了未使用的函数。
|
||||||
|
*/
|
||||||
|
#ifndef SPICEAPI_WRAPPERS_H
|
||||||
|
#define SPICEAPI_WRAPPERS_H
|
||||||
|
|
||||||
|
#define ARDUINOJSON_USE_LONG_LONG 1
|
||||||
|
#include "ArduinoJson.h"
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "connection.h"
|
||||||
|
|
||||||
|
// default buffer sizes
|
||||||
|
#ifndef SPICEAPI_WRAPPER_BUFFER_SIZE
|
||||||
|
#define SPICEAPI_WRAPPER_BUFFER_SIZE 256
|
||||||
|
#endif
|
||||||
|
#ifndef SPICEAPI_WRAPPER_BUFFER_SIZE_STR
|
||||||
|
#define SPICEAPI_WRAPPER_BUFFER_SIZE_STR 256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace spiceapi {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structs
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct InfoAvs {
|
||||||
|
String model, dest, spec, rev, ext;
|
||||||
|
};
|
||||||
|
|
||||||
|
// static storage
|
||||||
|
char JSON_BUFFER_STR[SPICEAPI_WRAPPER_BUFFER_SIZE_STR];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helpers
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint64_t msg_gen_id() {
|
||||||
|
static uint64_t id_global = 0;
|
||||||
|
return ++id_global;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *doc2str(DynamicJsonDocument *doc) {
|
||||||
|
char *buf = JSON_BUFFER_STR;
|
||||||
|
serializeJson(*doc, buf, SPICEAPI_WRAPPER_BUFFER_SIZE_STR);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicJsonDocument *request_gen(const char *module, const char *function) {
|
||||||
|
|
||||||
|
// create document
|
||||||
|
auto doc = new DynamicJsonDocument(SPICEAPI_WRAPPER_BUFFER_SIZE);
|
||||||
|
|
||||||
|
// add attributes
|
||||||
|
(*doc)["id"] = msg_gen_id();
|
||||||
|
(*doc)["module"] = module;
|
||||||
|
(*doc)["function"] = function;
|
||||||
|
|
||||||
|
// add params
|
||||||
|
(*doc).createNestedArray("params");
|
||||||
|
|
||||||
|
// return document
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicJsonDocument *response_get(Connection &con, const char *json) {
|
||||||
|
|
||||||
|
// parse document
|
||||||
|
DynamicJsonDocument *doc = new DynamicJsonDocument(SPICEAPI_WRAPPER_BUFFER_SIZE);
|
||||||
|
auto err = deserializeJson(*doc, (char *)json);
|
||||||
|
|
||||||
|
// check for parse error
|
||||||
|
if (err) {
|
||||||
|
delete doc;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check id
|
||||||
|
if (!(*doc)["id"].is<int64_t>()) {
|
||||||
|
delete doc;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check errors
|
||||||
|
auto errors = (*doc)["errors"];
|
||||||
|
if (!errors.is<JsonArray>()) {
|
||||||
|
delete doc;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check error count
|
||||||
|
if (errors.as<JsonArray>().size() > 0) {
|
||||||
|
delete doc;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check data
|
||||||
|
if (!(*doc)["data"].is<JsonArray>()) {
|
||||||
|
delete doc;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return document
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool card_insert(Connection &con, size_t index, const char *card_id) {
|
||||||
|
auto req = request_gen("card", "insert");
|
||||||
|
auto params = (*req)["params"].as<JsonArray>();
|
||||||
|
params.add(index);
|
||||||
|
params.add(card_id);
|
||||||
|
auto req_str = doc2str(req);
|
||||||
|
delete req;
|
||||||
|
auto res = response_get(con, con.request(req_str));
|
||||||
|
if (!res)
|
||||||
|
return false;
|
||||||
|
delete res;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool info_avs(Connection &con, InfoAvs &info) {
|
||||||
|
auto req = request_gen("info", "avs");
|
||||||
|
auto req_str = doc2str(req);
|
||||||
|
delete req;
|
||||||
|
auto res = response_get(con, con.request(req_str));
|
||||||
|
if (!res)
|
||||||
|
return false;
|
||||||
|
auto data = (*res)["data"][0];
|
||||||
|
info.model = (const char *)data["model"];
|
||||||
|
info.dest = (const char *)data["dest"];
|
||||||
|
info.spec = (const char *)data["spec"];
|
||||||
|
info.rev = (const char *)data["rev"];
|
||||||
|
info.ext = (const char *)data["ext"];
|
||||||
|
delete res;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //SPICEAPI_WRAPPERS_H
|
Loading…
Reference in New Issue
Block a user