Trigger express transit
This commit is contained in:
parent
e63eb4c620
commit
179cb05cbf
|
@ -131,6 +131,22 @@
|
|||
#define NDEF_URIPREFIX_URN_EPC (0x22) ///< URN EPC
|
||||
#define NDEF_URIPREFIX_URN_NFC (0x23) ///< URN NFC
|
||||
|
||||
// FeliCa Commands
|
||||
#define FELICA_CMD_POLLING (0x00)
|
||||
#define FELICA_CMD_REQUEST_SERVICE (0x02)
|
||||
#define FELICA_CMD_REQUEST_RESPONSE (0x04)
|
||||
#define FELICA_CMD_READ_WITHOUT_ENCRYPTION (0x06)
|
||||
#define FELICA_CMD_WRITE_WITHOUT_ENCRYPTION (0x08)
|
||||
#define FELICA_CMD_REQUEST_SYSTEM_CODE (0x0C)
|
||||
|
||||
// FeliCa consts
|
||||
#define FELICA_READ_MAX_SERVICE_NUM 16
|
||||
#define FELICA_READ_MAX_BLOCK_NUM 12 // for typical FeliCa card
|
||||
#define FELICA_WRITE_MAX_SERVICE_NUM 16
|
||||
#define FELICA_WRITE_MAX_BLOCK_NUM 10 // for typical FeliCa card
|
||||
#define FELICA_REQ_SERVICE_MAX_NODE_NUM 32
|
||||
|
||||
|
||||
#define PN532_GPIO_VALIDATIONBIT (0x80) ///< GPIO validation bit
|
||||
#define PN532_GPIO_P30 (0) ///< GPIO 30
|
||||
#define PN532_GPIO_P31 (1) ///< GPIO 31
|
||||
|
@ -170,7 +186,7 @@ public:
|
|||
uint16_t timeout = 0); // timeout 0 means no timeout - will block forever.
|
||||
bool startPassiveTargetIDDetection(uint8_t cardbaudrate);
|
||||
bool readDetectedPassiveTargetID(uint8_t* uid, uint8_t* uidLength);
|
||||
bool readDetectedPassiveTargetIDFeliCa(uint8_t* uid, uint8_t* uidLength);
|
||||
bool readDetectedPassiveTargetIDFeliCa(uint8_t* IDm, uint8_t* IDmLength);
|
||||
bool inDataExchange(uint8_t* send, uint8_t sendLength, uint8_t* response,
|
||||
uint8_t* responseLength);
|
||||
bool inListPassiveTarget();
|
||||
|
@ -221,6 +237,11 @@ private:
|
|||
Adafruit_SPIDevice* spi_dev = NULL;
|
||||
Adafruit_I2CDevice* i2c_dev = NULL;
|
||||
HardwareSerial* ser_dev = NULL;
|
||||
|
||||
bool releaseCardFeliCa();
|
||||
|
||||
int8_t requestServiceFeliCa(uint8_t numNode, const uint16_t* nodeCodeList, uint16_t* keyVersions, const uint8_t* idm);
|
||||
int8_t readWithoutEncryptionFeliCa(uint8_t numService, const uint16_t* serviceCodeList, uint8_t numBlock, const uint16_t* blockList, uint8_t blockData[][16], const uint8_t* idm);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -573,9 +573,10 @@ bool Adafruit_PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t* uid,
|
|||
return readDetectedPassiveTargetID(uid, uidLength);
|
||||
}
|
||||
else { // FeliCa
|
||||
pn532_packetbuffer[3] = 0x00;
|
||||
pn532_packetbuffer[4] = 0xFF;
|
||||
pn532_packetbuffer[5] = 0xFF;
|
||||
uint16_t systemCode = 0x0003; // Trigger express transit for CJRC Standard cards (Suica, PASMO, etc.)
|
||||
pn532_packetbuffer[3] = FELICA_CMD_POLLING;
|
||||
pn532_packetbuffer[4] = (systemCode >> 8) & 0xFF;
|
||||
pn532_packetbuffer[5] = systemCode & 0xFF;
|
||||
pn532_packetbuffer[6] = 0x01;
|
||||
pn532_packetbuffer[7] = 0x00;
|
||||
|
||||
|
@ -607,9 +608,10 @@ bool Adafruit_PN532::startPassiveTargetIDDetection(uint8_t cardbaudrate) {
|
|||
return sendCommandCheckAck(pn532_packetbuffer, 3);
|
||||
}
|
||||
else { // FeliCa
|
||||
pn532_packetbuffer[3] = 0x00;
|
||||
pn532_packetbuffer[4] = 0xFF;
|
||||
pn532_packetbuffer[5] = 0xFF;
|
||||
uint16_t systemCode = 0x0003; // Trigger express transit for CJRC Standard cards (Suica, PASMO, etc.)
|
||||
pn532_packetbuffer[3] = FELICA_CMD_POLLING;
|
||||
pn532_packetbuffer[4] = (systemCode >> 8) & 0xFF;
|
||||
pn532_packetbuffer[5] = systemCode & 0xFF;
|
||||
pn532_packetbuffer[6] = 0x01;
|
||||
pn532_packetbuffer[7] = 0x00;
|
||||
|
||||
|
@ -684,7 +686,7 @@ bool Adafruit_PN532::readDetectedPassiveTargetID(uint8_t* uid,
|
|||
return 1;
|
||||
}
|
||||
|
||||
bool Adafruit_PN532::readDetectedPassiveTargetIDFeliCa(uint8_t* uid, uint8_t* uidLength) {
|
||||
bool Adafruit_PN532::readDetectedPassiveTargetIDFeliCa(uint8_t* IDm, uint8_t* IDmLength) {
|
||||
// read data packet
|
||||
readdata(pn532_packetbuffer, 28);
|
||||
// check some basic stuff
|
||||
|
@ -711,15 +713,17 @@ bool Adafruit_PN532::readDetectedPassiveTargetIDFeliCa(uint8_t* uid, uint8_t* ui
|
|||
return 0;
|
||||
|
||||
uint8_t POL_RES = pn532_packetbuffer[9];
|
||||
uint8_t uid_length = 8; //this is hard set in the protocol
|
||||
uint8_t length = 8; //this is hard set in the protocol
|
||||
|
||||
/* Card appears to be Felica */
|
||||
*uidLength = uid_length;
|
||||
*IDmLength = length;
|
||||
#ifdef PN532CARDDEBUG
|
||||
PN532DEBUGPRINT.print(F("UID:"));
|
||||
#endif
|
||||
for (uint8_t i=0; i < uid_length; i++) {
|
||||
uid[i] = pn532_packetbuffer[11+i];
|
||||
for (uint8_t i=0; i < length; i++) {
|
||||
IDm[i] = pn532_packetbuffer[11 + i];
|
||||
|
||||
IDm[0] = (IDm[0] & 0x0F);
|
||||
#ifdef PN532CARDDEBUG
|
||||
PN532DEBUGPRINT.print(F(" 0x"));
|
||||
PN532DEBUGPRINT.print(uid[i], HEX);
|
||||
|
@ -729,6 +733,115 @@ bool Adafruit_PN532::readDetectedPassiveTargetIDFeliCa(uint8_t* uid, uint8_t* ui
|
|||
PN532DEBUGPRINT.println();
|
||||
#endif
|
||||
|
||||
uint16_t serviceCodeList[1];
|
||||
uint16_t returnKey[1];
|
||||
uint16_t blockList[1];
|
||||
uint8_t blockData[1][16];
|
||||
|
||||
|
||||
serviceCodeList[0] = 0x090f;
|
||||
blockList[0] = 0x8000;
|
||||
|
||||
//TODO: figure out how to release the card properly so the transaction doesn't time out on the Apple Pay side
|
||||
//requestServiceFeliCa(1, serviceCodeList, returnKey, IDm);
|
||||
//readWithoutEncryptionFeliCa(1, serviceCodeList, 1, blockList, blockData, IDm);
|
||||
//releaseCardFeliCa();
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Adafruit_PN532::releaseCardFeliCa() {
|
||||
Serial.println("Releasing FeliCa card");
|
||||
pn532_packetbuffer[0] = PN532_COMMAND_INRELEASE;
|
||||
pn532_packetbuffer[1] = 0x00; // All target
|
||||
return sendCommandCheckAck(pn532_packetbuffer, 2);
|
||||
}
|
||||
|
||||
int8_t Adafruit_PN532::requestServiceFeliCa(uint8_t numNode, const uint16_t* nodeCodeList, uint16_t* keyVersions, const uint8_t* idm)
|
||||
{
|
||||
if (numNode > FELICA_REQ_SERVICE_MAX_NODE_NUM) {
|
||||
Serial.println("numNode is too large\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t i, j=0;
|
||||
uint8_t cmdLen = 1 + 8 + 1 + 2*numNode;
|
||||
uint8_t cmd[cmdLen];
|
||||
cmd[j++] = FELICA_CMD_REQUEST_SERVICE;
|
||||
for (i=0; i<8; ++i) {
|
||||
cmd[j++] = idm[i];
|
||||
}
|
||||
cmd[j++] = numNode;
|
||||
for (i=0; i<numNode; ++i) {
|
||||
cmd[j++] = nodeCodeList[i] & 0xFF;
|
||||
cmd[j++] = (nodeCodeList[i] >> 8) & 0xff;
|
||||
}
|
||||
|
||||
uint8_t response[10+2*numNode];
|
||||
|
||||
if (!sendCommandCheckAck(cmd, cmdLen)) {
|
||||
Serial.println("Request Service command failed\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
for(i=0; i<numNode; i++) {
|
||||
keyVersions[i] = (uint16_t)(response[10+i*2] + (response[10+i*2+1] << 8));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int8_t Adafruit_PN532::readWithoutEncryptionFeliCa(uint8_t numService, const uint16_t* serviceCodeList, uint8_t numBlock, const uint16_t* blockList, uint8_t blockData[][16], const uint8_t* idm) {
|
||||
if (numService > FELICA_READ_MAX_SERVICE_NUM) {
|
||||
Serial.println("numService is too large\n");
|
||||
return -1;
|
||||
}
|
||||
if (numBlock > FELICA_READ_MAX_BLOCK_NUM) {
|
||||
Serial.println("numBlock is too large\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
uint8_t i, j = 0, k;
|
||||
uint8_t cmdLen = 1 + 8 + 1 + 2 * numService + 1 + 2 * numBlock;
|
||||
uint8_t cmd[cmdLen];
|
||||
cmd[j++] = FELICA_CMD_READ_WITHOUT_ENCRYPTION;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
cmd[j++] = idm[i];
|
||||
}
|
||||
cmd[j++] = numService;
|
||||
for (i = 0; i < numService; ++i) {
|
||||
cmd[j++] = serviceCodeList[i] & 0xFF;
|
||||
cmd[j++] = (serviceCodeList[i] >> 8) & 0xff;
|
||||
}
|
||||
cmd[j++] = numBlock;
|
||||
for (i = 0; i < numBlock; ++i) {
|
||||
cmd[j++] = (blockList[i] >> 8) & 0xFF;
|
||||
cmd[j++] = blockList[i] & 0xff;
|
||||
}
|
||||
|
||||
uint8_t response[12 + 16 * numBlock];
|
||||
uint8_t responseLength = 12 + 16 * numBlock;
|
||||
if (!sendCommandCheckAck(cmd, cmdLen)) {
|
||||
Serial.println("Read Without Encryption command failed\n");
|
||||
return -3;
|
||||
}
|
||||
|
||||
readdata(pn532_packetbuffer, responseLength);
|
||||
|
||||
// status flag check
|
||||
if (pn532_packetbuffer[9] != 0 || pn532_packetbuffer[10] != 0) {
|
||||
Serial.println("Read Without Encryption command failed (Status Flag: ");
|
||||
Serial.println(pn532_packetbuffer[9], HEX);
|
||||
Serial.println(pn532_packetbuffer[10], HEX);
|
||||
Serial.println(")\n");
|
||||
return -5;
|
||||
}
|
||||
|
||||
k = 12;
|
||||
for (i = 0; i < numBlock; i++) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
blockData[i][j] = pn532_packetbuffer[k++];
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ PN532Reader::PN532Reader(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t ss) {
|
|||
void PN532Reader::begin() {
|
||||
pn532->begin();
|
||||
irq = 0;
|
||||
mode = PN532_MIFARE_ISO14443A;
|
||||
mode = PN532_FELICA_424;
|
||||
pn532->startPassiveTargetIDDetection(mode);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue