Open Zhairgling opened 7 years ago
I saw here (https://github.com/techniq/node-pn532/blob/emulate-tag/src/pn532.js) that there was a function intended to make emulation of code but when I test I am a little lost.
I want to clarify that I already manage to read and write on tags.
Hi @Zhairgling. The PN532 has the ability to be a writer as well as a reader, and I spent some time on the emulate-tag branch trying to get writing to work, but ultimately never had time to finish it. I also wasn't sure if being a simple writer was the same as Android Beam (if the later is more bi-directional communication). I do see Seeed Studios C library supports card emulation and snep (which I believe relates to Android Beam). I don't see me getting time to look at this for a while, but I accept PRs :). Between the User Guide and Datasheet (linked at the bottom of the README) and looking at Seeed Studio's implementation, it might not be too difficult to finish up.
First of all thank you @techniq for the answer. I do not want to communicate with an android device. I refer to this system of operation only as an example. I am only trying to exchange a json object between two pn532. Can you tell me what was not working when you were working.
To be honest, I don't remember exactly (it's been a little while). I remember I was trying to use my Android phone with NFC Tools to scan my pn532 breakout board but I think I was having trouble understanding how to attach the payload of the data to send.
Thank you for the advices you gave me. I'm a little lost though. I think I'll come back to you if I have any questions. But I confess that I am afraid of not being able to make it work.
Looking at the SimpleTag.ino
file within the test scripts on the Adafruit PR, it looks like you need to first initialize (nfc.TgInitAsTarget()
) and then setup a response buffer/handler (nfc.TgGetData(...)
) and then ultimately send the data (nfc.TgSetData(...)
)
#include <Adafruit_PN532.h>
#define SCK (2)
#define MOSI (3)
#define SS (4)
#define MISO (5)
boolean TgInit = false;
Adafruit_PN532 nfc(SCK, MISO, MOSI, SS);
void setup() {
Serial.begin(115200);
nfc.begin();
uint8_t versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
Serial.println("Didn't find PN532 on RX board!");
while (1); //halt
}
nfc.SAMConfig();
Serial.println("Boards initialized and ready...");
}
void loop() {
uint8_t sendbuf[] = {0x04, 0x03, 0x02, 0x01};
uint8_t resbuf[16];
uint8_t reslen;
if(nfc.TgInitAsTarget()) {
Serial.println("Tag Emulation Successful");
if(!nfc.TgGetData(resbuf, &reslen)) {
Serial.println("GetData Fail");
}
nfc.TgSetData(sendbuf, sizeof(sendbuf));
Serial.print("Response: ");
nfc.PrintHex(resbuf, reslen);
Serial.println("Sent data: ");
nfc.PrintHex(sendbuf, sizeof(sendbuf));
// while(1);
}
delay(1000);
}
I think I was on the right track with emulateTag
(i.e. TgInitAsTarget
), emulateGetData (i.e. TgGetData
) and emulateSetData (i.e. TgSetData
) but maybe not knowing I needed to call all 3 each time to setup the transfer...
Looking at what I had done, I think I was using Seeed Studio's emulatetag.cpp as reference, trying to figure it out. If you want to give it a shot, I would work from their impl. and see where `node-pn532' is lacking.
Page 21 of the User Manual titled ISO/IEC14443-4 PICC emulation concept
and pages 151-165 on TgInitAsTarget, TgGetData, and TgSetData might come in handy, but ultimately working by example (Seeed/Adafruit impl.) will probably give you the best idea on how to implement.
I wish I had more time to look at this, but as of right now, just giving comments/feedback is the best I can do (for a while at least).
Hello, I bent over it tonight. I prepared two PI and two pn532. They work well both. I even was able to test the emulation function of tag in the shell with the examples of the libnfc. I have needed a tip to choose the best way to implement it in the pn532 module. Should I load the old branch of your work or implement it myself in the latest version of the module?
I would definitely use the master branch and not the old branch. Will make merging easier.
On Wed, Jan 25, 2017, 5:35 AM Zhairgling notifications@github.com wrote:
Hello, I bent over it tonight. I prepared two PI and two pn532. They work well both. I even was able to test the emulation function of tag in the shell with the examples of the libnfc. I have needed a tip to choose the best way to implement it in the pn532 module. Should I load the old branch of your work or implement it myself in the latest version of the module?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/techniq/node-pn532/issues/12#issuecomment-275074312, or mute the thread https://github.com/notifications/unsubscribe-auth/AAK1RIPxRZdO1CJa84nGKkqECvfEzQ6eks5rVyWIgaJpZM4LsF1P .
I am currently working on it but I do not see very well the interest of the emulateSetData () function. Since there is one of the two configured as target the other just has to write on it, then reverse !?
Can you explain me the switch in the emulateGetData() function ?
emulateGetData() {
logger.info('Emulate get data...');
return this.sendCommand([c.COMMAND_TG_GET_DATA])
.then((frame) => {
var body = frame.getDataBody();
logger.debug('Frame data from emulate get data read:', util.inspect(body));
var status = body[0];
if (status === 0x13) {
logger.warn('The data format does not match to the specification.');
}
// var dataIn = body.slice(1, body.length - 1); // skip status byte and last byte (not part of memory)
// 00 00 a4 04 00 07 d2 76 00 00 85 01 01 00 26
var cla = body[1]
var instruction = body[2];
var parameter1 = body[3];
var parameter2 = body[4];
var commandLength = body[5];
var data = body.slice(6, commandLength);
logger.debug('instruction', instruction);
logger.debug('parameter1', parameter1);
logger.debug('parameter2', parameter2);
logger.debug('commandLength', commandLength);
logger.debug('data', util.inspect(data));
switch(instruction) { //////// <==========================
case c.ISO7816_SELECT_FILE:
logger.info('Select file');
if (parameter1 === 0x00) {
logger.info('Select by Id');
}
if (parameter1 === 0x04) {
logger.info('Select by name');
}
/* case C_APDU_P1_SELECT_BY_ID:
if(p2 != 0x0c){
DMSG("C_APDU_P2 != 0x0c\n");
// setResponse(COMMAND_COMPLETE, rwbuf, &sendlen);
} else if(lc == 2 && rwbuf[C_APDU_DATA] == 0xE1 && (rwbuf[C_APDU_DATA+1] == 0x03 || rwbuf[C_APDU_DATA+1] == 0x04)){
// setResponse(COMMAND_COMPLETE, rwbuf, &sendlen);
if(rwbuf[C_APDU_DATA+1] == 0x03){
currentFile = CC;
} else if(rwbuf[C_APDU_DATA+1] == 0x04){
currentFile = NDEF;
}
} else {
// setResponse(TAG_NOT_FOUND, rwbuf, &sendlen);
}
break;
case C_APDU_P1_SELECT_BY_NAME:
const uint8_t ndef_tag_application_name_v2[] = {0, 0x7, 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01 };
if(0 == memcmp(ndef_tag_application_name_v2, rwbuf + C_APDU_P2, sizeof(ndef_tag_application_name_v2))){
// setResponse(COMMAND_COMPLETE, rwbuf, &sendlen);
} else{
DMSG("function not supported\n");
// setResponse(FUNCTION_NOT_SUPPORTED, rwbuf, &sendlen);
}
break;
break;*/
case c.ISO7816_READ_BINARY:
logger.info('Read binary');
break;
case c.ISO7816_UPDATE_BINARY:
logger.info('Update binary');
break;
default:
logger.warn('Command not supported');
}
return data;
});
}
I'll be honest, I'm not sure what it does :D.
I think at the time I copied Seeed Studio's C++ implementation and was slowly trying to break it down to understand it, but I didn't get that far... :(
I think it would be best if we scraped that and looked at Adafruit's PR C++ implementation for TgGetData
since it looks to be simpler (and we can build it out after we have a better understanding...).
I have worked on the emulateTag() function.
here is my work :
emulateTag() {
logger.info('Emulating tag...');
var commAsTarget= 0x8C;
var mode = 0x05; // PICC only, Passive Only
var sens_res = [0x08, 0x00];
var nfcId1t = [0x12, 0x34, 0x56];
var sel_res = [0x60];
var mifareParams = [].concat(sens_res, nfcId1t, sel_res);
var felicaParams = [0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0];
var nfcId3t = [0,0,0,0,0,0,0,0,0,0];
var generalBytesLength = 0;
var historicalBytesLength = 0;
var commandBuffer = [
commAsTarget,
mode,
mifareParams,
felicaParams,
nfcId3t,
generalBytesLength,
historicalBytesLength
];
console.log('commandBuffer : '+ commandBuffer);
return this.sendCommand(commandBuffer)
.then((frame) => {
var body = frame.getDataBody();
logger.debug('body', util.inspect(body));
var mode = body[0];
console.log('mode', mode);
logger.debug('mode', mode);
});
}
but i can't have any response by the pn532 after send the commandBuffer.
Hmm, could you show me how you're calling emulateTag()
and run your example with logging enabled:
PN532_LOGGING=debug node examples/emulate_tag.js
Replacing emulate_tag.js
with whatever you called your file.
I'm simply calling it like that in my index.js file :
var SerialPort = require('serialport').SerialPort;
//ndef = require('ndef');
var serialPort = new SerialPort('/dev/ttyAMA0', { baudrate: 115200 });
var rfid = new pn532.PN532(serialPort);
rfid.on('ready', function() {
console.log('rfid ready');
rfid.emulateTag();
});
when I run with logging enabled i get that :
DEPRECATION: Please use `require('serialport')` instead of `require('serialport').SerialPort`
debug: [frame-emitter] listening to data
debug: [hsu] Initializing serial port...
debug: [hsu] Serial port initialized.
info: [pn532] Configuring secure access module (SAM)...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 05 fb d4 14 01 00 01 16 00>
debug: [hsu] Waking up PN532...
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
rfid ready
info: [pn532] Emulating tag...
commandBuffer : 140,5,8,0,18,52,86,96,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
debug: [pn532] Sending buffer: <Buffer 00 00 ff 08 f8 d4 8c 05 00 00 00 00 00 01 00>
Hmm, looking at the logs for the buffer being sent (last line)
00 00 ff 08 f8 d4 8c 05 00 00 00 00 00 01 00
The command is incorrect (or is being truncated). The command buffer we build for each different type of command (in this case, TgInitAsTarget
) is passed to sendCommand and is wrapped into a frame, which adds things such as the PREAMBLE
, START_CODE_1
/ 2
, calculates and appends the data length and the checksum of the data length, the direction of the communication (to/from the PN532), the actual data we're trying to send (commandBuffer
), the checksum of that data, and the POSTAMBLE
. You can see all of this by looking at DataFrame, and particularly these lines:
toBuffer() {
var array = [].concat([
PREAMBLE,
START_CODE_1,
START_CODE_2,
this.getDataLength(),
this.getDataLengthChecksum(),
this.getDirection()
], this._data, [
this.getDataChecksum(),
POSTAMBLE
]);
return new Buffer(array);
}
I think testing and fixing to make sure new DataFrame(commandBuffer)
produces the correct output should get you past this issue. If you look at page 150 of the user manual you can see the structure of the frame for a TgInitAsTarget frame (this only shows the direction (D4
) and then everything within the data
part.
Also, when you paste code/logs, if you could wrap them in triple single quotes (`) it would make reading them much easier 😄.
Hopefully you can track down the flaw in the building of DataFrame. It's likely we're taking for granted the type of data we've sent up to this far and some adjustments / special handling for this frame needs to occur.
I've had it on my backlog for a while, but I really need to get around to setting up some testing infrastructure (jest, mocha, ...) to make this type of development easier. Early on I thought it would be difficult to test since it was dependent on hardware / physical setup, but there is a lot of the code that could be tested without hardware, most importantly the building of the frames.
I think I might see the issue in your code...
var commandBuffer = [
commAsTarget,
mode,
mifareParams,
felicaParams,
nfcId3t,
generalBytesLength,
historicalBytesLength
];
Things such as mifareParams
, felicaParams
, etc are arrays within the commandBuffer
array, but commandBuffer
should be a "flat array" of all the data. I think you need to concat all of this together so commandBuffer.length
=== 38 (doing a quick count, I could be off by 1 or 2). It looks like currently DataFrame
saw 8
as indicated in the logs (00 00 ff 08...
), and makes since as your commandBuffer is a length of 7
and getDataLength() adds 1 to the commandBuffer (I forgot exactly way, but I think maybe to account for the data checksum byte).
Anyways, try to concat all of your command buffer together and let me know.
Thanks..
I have concat my buffer command and it seems ok :
here the result of the emulate() function :
emulateTag() {
logger.info('Emulating tag...');
var commAsTarget= 0x8C;
var mode = 0x05; // PICC only, Passive Only
var sens_res = [0x08, 0x00];
var nfcId1t = [0x12, 0x34, 0x56];
var sel_res = [0x60];
var mifareParams = [].concat(sens_res, nfcId1t, sel_res);
var felicaParams = [0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0];
var nfcId3t = [0,0,0,0,0,0,0,0,0,0];
var generalBytesLength = 0;
var historicalBytesLength = 0;
var commandBuffer = [].concat(
commAsTarget,
mode,
mifareParams,
felicaParams,
nfcId3t,
generalBytesLength,
historicalBytesLength
);
console.log('commandBuffer : '+ commandBuffer);
return this.sendCommand(commandBuffer)
.then((frame) => {
var body = frame.getDataBody();
logger.debug('body', util.inspect(body));
var mode = body[0];
console.log('mode', mode);
logger.debug('mode', mode);
// var initiatorCommand = ...
// var numberOfTags = body[0];
// if (numberOfTags === 1) {
// var tagNumber = body[1];
// var uidLength = body[5];
//
// var uid = body.slice(6, 6 + uidLength)
// .toString('hex')
// .match(/.{1,2}/g)
// .join(':');
//
// return {
// ATQA: body.slice(2, 4), // SENS_RES
// SAK: body[4], // SEL_RES
// uid: uid
// };
// }
});
}
and the result :
pi@raspberrypi:~/testNFCP2P $ PN532_LOGGING=debug node index.js
DEPRECATION: Please use `require('serialport')` instead of `require('serialport' ).SerialPort`
debug: [frame-emitter] listening to data
debug: [hsu] Initializing serial port...
debug: [hsu] Serial port initialized.
info: [pn532] Configuring secure access module (SAM)...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 05 fb d4 14 01 00 01 16 00>
debug: [hsu] Waking up PN532...
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00 00 00 ff 02 f e d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]} >
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","dat a":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0, 255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":21,"body":{"type":"Buf fer","data":[22]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":2 1,"body":{"type":"Buffer","data":[22]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":21,"body":{"type":" Buffer","data":[22]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
rfid ready
info: [pn532] Emulating tag...
commandBuffer : 140,5,8,0,18,52,86,96,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0
debug: [pn532] Sending buffer: <Buffer 00 00 ff 27 d9 d4 8c 05 08 00 12 34 56 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0 0 00 00 00 97 00>
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]} >
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","dat a":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0, 255,0]}>
debug: [frame-emitter] AckFrame found in buffer
when i use NFCTOOL from my phone i can read datas :D
Hi ,
I'm now working on the emulateGetData() fonction:
emulateGetData() {
logger.info('Emulate get data...');
return this.sendCommand([c.COMMAND_TG_GET_DATA])//0x86
.then((frame) => {
var body = frame.getDataBody();
logger.debug('Frame data from emulate get data read:', util.inspect(body));
var status = body[0];
if (status === 0x13) {
logger.warn('The data format does not match to the specification.');
}
// var dataIn = body.slice(1, body.length - 1); // skip status byte and last byte (not part of memory)
// 00 00 a4 04 00 07 d2 76 00 00 85 01 01 00 26
var cla = body[1]
var instruction = body[2];
var parameter1 = body[3];
var parameter2 = body[4];
var commandLength = body[5];
var data = body.slice(6, commandLength);
logger.debug('instruction', instruction);
logger.debug('parameter1', parameter1);
logger.debug('parameter2', parameter2);
logger.debug('commandLength', commandLength);
logger.debug('data', util.inspect(data));
console.log('Final data read : '+data);
return data;
});
}
used like that :
var pn532 = require('pn532');
var SerialPort = require('serialport').SerialPort;
//ndef = require('ndef');
var serialPort = new SerialPort('/dev/ttyAMA0', { baudrate: 115200 });
var rfid = new pn532.PN532(serialPort);
rfid.on('ready', function() {
console.log('rfid ready');
rfid.emulateTag()
rfid.emulateGetData().then(function(data) {
console.log('dataRead : ', data);
});
});
The output is :
pi@raspberrypi:~/testNFCP2P $ sudo PN532_LOGGING=debug node index.js
DEPRECATION: Please use `require('serialport')` instead of `require('serialport').SerialPort`
debug: [frame-emitter] listening to data
debug: [hsu] Initializing serial port...
debug: [hsu] Serial port initialized.
info: [pn532] Configuring secure access module (SAM)...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 05 fb d4 14 01 00 01 16 00>
debug: [hsu] Waking up PN532...
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
rfid ready
info: [pn532] Emulating tag...
commandBuffer : 140,5,8,0,18,52,86,96,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
debug: [pn532] Sending buffer: <Buffer 00 00 ff 27 d9 d4 8c 05 08 00 12 34 56 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 00>
info: [pn532] Emulate get data...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 02 fe d4 00 01 00>
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
What's wrong ? the AckFrame is not good ?
You should wait for emulateTag()
's promise to resolve (wait on its ACK) before sending emulateGetData()
.
rfid.emulateTag().then(function() {
console.log('emulateTag initialized');
rfid.emulateGetData().then(function(data) {
console.log('dataRead : ', data);
});
Ok when i use ur code, I can't write with NFCTOOLS, that say " error when writing". When i use the rfid.writeNdefData(data) function :
var pn532 = require('pn532');
var SerialPort = require('serialport').SerialPort;
var ndef = require('ndef');
var serialPort = new SerialPort('/dev/ttyAMA0', { baudrate: 115200 });
var rfid = new pn532.PN532(serialPort);
rfid.on('ready', function() {
console.log('rfid ready');
rfid.scanTag().then(function(tag) {
console.log('scan du taf');
var messages = [
ndef.uriRecord('http://www.google.com'),
ndef.textRecord('test')
];
console.log('messages: ',messages);
var data = ndef.encodeMessage(messages);
console.log('data: ',data);
rfid.writeNdefData(data).then(function(response) {
console.log('Write successful');
});
});
});
i get :
pi@raspberrypi:~/testNFCWrite $ PN532_LOGGING=debug node index.js
DEPRECATION: Please use `require('serialport')` instead of `require('serialport').SerialPort`
debug: [frame-emitter] listening to data
debug: [hsu] Initializing serial port...
debug: [hsu] Serial port initialized.
info: [pn532] Configuring secure access module (SAM)...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 05 fb d4 14 01 00 01 16 00>
debug: [hsu] Waking up PN532...
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
rfid ready
info: [pn532] Scanning tag...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 04 fc d4 4a 01 00 e1 00>
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Data received <Buffer 00 00 ff 11 ef d5 4b 01>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 11 ef d5 4b 01>
debug: [frame-emitter] Data received <Buffer 01 00 08 60 04 08 12 34 56 05 75 33 92 03 8c 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 11 ef d5 4b 01 01 00 08 60 04 08 12 34 56 05 75 33 92 03 8c 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":75,"body":{"type":"Buffer","data":[1,1,0,8,96,4,8,18,52,86,5,117,51,146,3,140]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":75,"body":{"type":"Buffer","data":[1,1,0,8,96,4,8,18,52,86,5,117,51,146,3,140]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":75,"body":{"type":"Buffer","data":[1,1,0,8,96,4,8,18,52,86,5,117,51,146,3,140]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
debug: [pn532] body <Buffer 01 01 00 08 60 04 08 12 34 56 05 75 33 92 03 8c>
scan du taf
messages: [ { tnf: 1,
type: 'U',
id: [],
payload: [ 1, 103, 111, 111, 103, 108, 101, 46, 99, 111, 109 ],
value: 'http://www.google.com' },
{ tnf: 1,
type: 'T',
id: [],
payload: [ 2, 101, 110, 116, 101, 115, 116 ],
value: 'test' } ]
data: [ 145,
1,
11,
85,
1,
103,
111,
111,
103,
108,
101,
46,
99,
111,
109,
81,
1,
7,
84,
2,
101,
110,
116,
101,
115,
116 ]
info: [pn532] Writing data...
debug: [pn532] block: <Buffer 03 1a 91 01 0b 55 01 67 6f 6f 67 6c 65 2e 63 6f 6d 51 01 07 54 02 65 6e 74 65 73 74 fe>
debug: [pn532] Writing block: 0 at blockAddress: 4
debug: [pn532] pageData: <Buffer 03 1a 91 01>
info: [pn532] Writing block...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 09 f7 d4 40 01 a2 04 03 1a 91 01 96 00>
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
and on the target i have :
pi@raspberrypi:~/testNFCP2P $ PN532_LOGGING=debug node index.js
DEPRECATION: Please use `require('serialport')` instead of `require('serialport').SerialPort`
debug: [frame-emitter] listening to data
debug: [hsu] Initializing serial port...
debug: [hsu] Serial port initialized.
info: [pn532] Configuring secure access module (SAM)...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 05 fb d4 14 01 00 01 16 00>
debug: [hsu] Waking up PN532...
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
info: [pn532] Emulating tag...
commandBuffer : 140,5,8,0,18,52,86,96,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
debug: [pn532] Sending buffer: <Buffer 00 00 ff 27 d9 d4 8c 05 08 00 12 34 56 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 00>
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Data received <Buffer 00 00 ff 05 fb d5 8d 08>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 05 fb d5 8d 08>
debug: [frame-emitter] Data received <Buffer e0 50 66 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 05 fb d5 8d 08 e0 50 66 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":141,"body":{"type":"Buffer","data":[8,224,80,102]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":141,"body":{"type":"Buffer","data":[8,224,80,102]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":141,"body":{"type":"Buffer","data":[8,224,80,102]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
debug: [pn532] body <Buffer 08 e0 50 66>
mode 8
debug: [pn532] mode 8
emulateTag initialized
info: [pn532] Emulate get data...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 02 fe d4 00 01 00>
It look like the target isn't waiting the good type of data.
here is a screen of reading the target with nfcTool from android phone
Nothing is jumping out at me so far. Receiving the 8D
(141) command after the 8C
(140) looks correct.
8C command mode (request): 5 (00000101
)
0000
)1
)0
)1
)8D command mode (response): 8 (00001000
):
0
)000
) 1
)0
)00
)Actually as I've been looking at a bunch of other things, something just stood out at me. The last command...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 02 fe d4 00 01 00>
It looks like it's sending 00
as the command for TgGetData
instead of 86
.
Actually it looks like:
emulateGetData() {
return this.sendCommand([c.COMMAND_TG_GET_DATA]) //0x86
should be
emulateGetData() {
return this.sendCommand([c.TG_GET_DATA]) //0x86
Sorry for the noise in the comment, I thought I would leave my train of thought (and I had already typed things before I figured more of it out) 😄
Btw, another Github comment tip: If you add js
after the first triple backtick, it will add javascript syntax highlighting to your pasted code (ignore the .
, I had to add it so it wouldn't be parsed and prematurely close the example:
.```js
// code here
.```
It supports a lot of other languages as well (I wouldn't put the js
on our log output)
Thank you for all advices you give me :) You are right, that was the wrong command. But when i provide the good one, it fail : And freez my pi
pi@raspberrypi:~/testNFCP2P $ PN532_LOGGING=debug node index.js
DEPRECATION: Please use `require('serialport')` instead of `require('serialport').SerialPort`
debug: [frame-emitter] listening to data
debug: [hsu] Initializing serial port...
debug: [hsu] Serial port initialized.
info: [pn532] Configuring secure access module (SAM)...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 05 fb d4 14 01 00 01 16 00>
debug: [hsu] Waking up PN532...
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
info: [pn532] Emulating tag...
commandBuffer : 140,5,8,0,18,52,86,96,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
debug: [pn532] Sending buffer: <Buffer 00 00 ff 27 d9 d4 8c 05 08 00 12 34 56 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 00>
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Data received <Buffer 00 00 ff 05 fb d5 8d 08>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 05 fb d5 8d 08>
debug: [frame-emitter] Data received <Buffer e0 50 66 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 05 fb d5 8d 08 e0 50 66 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":141,"body":{"type":"Buffer","data":[8,224,80,102]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":141,"body":{"type":"Buffer","data":[8,224,80,102]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":141,"body":{"type":"Buffer","data":[8,224,80,102]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
debug: [pn532] body <Buffer 08 e0 50 66>
mode 8
debug: [pn532] mode 8
emulateTag initialized
info: [pn532] Emulate get data...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 02 fe d4 86 a6 00>
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Data received <Buffer 00 00 ff 09 f7 d5 87 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 09 f7 d5 87 00>
debug: [frame-emitter] Data received <Buffer a2 04 03 1a 91 01 4f 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 09 f7 d5 87 00 a2 04 03 1a 91 01 4f 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":135,"body":{"type":"Buffer","data":[0,162,4,3,26,145,1,79]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":135,"body":{"type":"Buffer","data":[0,162,4,3,26,145,1,79]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":135,"body":{"type":"Buffer","data":[0,162,4,3,26,145,1,79]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
debug: [pn532] Frame data from emulate get data read: <Buffer 00 a2 04 03 1a 91 01 4f>
debug: [pn532] instruction 4
debug: [pn532] parameter1 3
debug: [pn532] parameter2 26
debug: [pn532] commandLength 145
debug: [pn532] data <Buffer 01 4f>
Final data read : O
dataRead : <Buffer 01 4f>
Well, incremental progress 😄.
Hmm, so looking at the data of command 0x87
(135
): 00 a2 04 03 1a 91 01 4f
, it looks like the first byte is for status and is 00
).
Looking at the User Manual, the following sections/pages look helpful:
7.3.16 TgGetData
(page 160)7.1 Error Handling
(page 67)I think a status of 00
is a good thing (otherwise it would be an error code from my understanding, but I just glossed over it).
It seems like you were breaking down the DataIn
part of the 87
response (a2 04 03 1a 91 01 4f
) into instruction
, parameter1
, etc. What exactly is failing (what are you expecting)?
Yes :) For me it's failing because I can't get the data that i write with the other pn532, i try to exchange datas in ndef format. But i can't retrieve what i send
You were writing the NDEF messages mentioned above right?
messages: [ { tnf: 1,
type: 'U',
id: [],
payload: [ 1, 103, 111, 111, 103, 108, 101, 46, 99, 111, 109 ],
value: 'http://www.google.com' },
{ tnf: 1,
type: 'T',
id: [],
payload: [ 2, 101, 110, 116, 101, 115, 116 ],
value: 'test' } ]
data: [ 145,
1,
11,
85,
1,
103,
111,
111,
103,
108,
101,
46,
99,
111,
109,
81,
1,
7,
84,
2,
101,
110,
116,
101,
115,
116 ]
Looking at the user guide, it appears DataIn
can be an array of data up to 262 bytes. Since you are trying to send more than this, I'm assuming it will need to come down in chunks/blocks, probably similarly to how readNdefData does. I do see 145 1
(or 91 01
in hex) in the your response, so that looks promising.
I don't fully understand what TgGetData
and TgSetData
are doing exactly TBH, although I think maybe TgSetData
is used to confirm the receipt of the TgGetData
.
In fact, looking at our data (response of ndef.encodeMessage(messages);
, the length of the data array to send is 26, or 1a
. Our response is:
0x00
/00
: Status0xa2
/162
: Instruction (C_APDU_INS)0x04
/4
: Parameter 1 (C_APDU_P1)
0x03
/3
: Parameter 2 (C_APDU_P2)0x1a
/26
: Length command (C_APDU_LC)0x91
/145
: data[0]0x01
/1
: data[1]0x4f
/79
: checksum?So my guess is we need to call TgSetData
to acknowledge and probably TgGetData
to get the next block of data. I don't know how we'll need to request the next block (maybe just calling TgGetData
again. I think now's the time to break down how Seeed-Studio's EmulateTag::emulate
works, with focus on the NDEF case statement (I saw ignore all the other case statements for now, just no-op them but leave placeholders so we know we need to handle them.
I read a little more into Seeed-Studio's emulatetag.cpp and I don't believe the last byte (0x4f
/79
) is a checksum, but I'm not sure why it's not 11
. It would be useful to:
TgSetData
command (8E
). I'm not exactly sure of the payload for this command though.I'm not sure how much more I can be right now. It would probably be helpful if you forked and committed your changes that way I can look at them as a whole (and maybe try to run it locally at some point if I get some time).
Btw, I also have this spreadsheet that I created a while back to help me decipher NFC tag data / NDEF messages.
If you look at the second tab (NDEF Header) you'll see 91
in your data means this is the first of 2 records/messages, which is correct (since you're trying to send a url and a text record). The next byte 01
is the length of the record type indicator, which is typically always 1 (for well known types). The third byte should be the length of the NDEF message, which for the first message (google URL) is 11
(0x0B
) but is in your logs as 4f
, which I'm not sure why. It would be nice to capture logs a few times, a few with the same NDEF messages (to see if 4f
changes) and a few with very simple payloads (maybe not even NDEF message, just a short byte array similar to Adafruit's test script mentioned above).
Hi, I think you are right. the writer want send many buffers but reader read only one .
I will fork the project as you said.
here is what you requested last time, trying do send only one single message in NDEF data.
the writer code :
var pn532 = require('pn532');
var SerialPort = require('serialport').SerialPort;
var ndef = require('ndef');
var serialPort = new SerialPort('/dev/ttyAMA0', { baudrate: 115200 });
var rfid = new pn532.PN532(serialPort);
rfid.on('ready', function() {
console.log('rfid ready');
rfid.scanTag().then(function(tag) {
console.log('scan du taf');
var messages = [
ndef.textRecord('test')
];
console.log('messages: ',messages);
var data = ndef.encodeMessage(messages);
console.log('data: ',data);
rfid.writeNdefData(data).then(function(response) {
console.log('Write successful');
});
});
});
the reader code as a target :
var pn532 = require('pn532');
var SerialPort = require('serialport').SerialPort;
//ndef = require('ndef');
var serialPort = new SerialPort('/dev/ttyAMA0', { baudrate: 115200 });
var rfid = new pn532.PN532(serialPort);
rfid.on('ready', function() {
rfid.emulateTag().then(function() {
console.log('emulateTag initialized');
rfid.emulateGetData().then(function(data) {
console.log('dataRead : ', data);
});
});
});
The output of the writer :
pi@raspberrypi:~/testNFCWrite $ PN532_LOGGING=debug node index.js
DEPRECATION: Please use `require('serialport')` instead of `require('serialport').SerialPort`
debug: [frame-emitter] listening to data
debug: [hsu] Initializing serial port...
debug: [hsu] Serial port initialized.
info: [pn532] Configuring secure access module (SAM)...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 05 fb d4 14 01 00 01 16 00>
debug: [hsu] Waking up PN532...
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
rfid ready
info: [pn532] Scanning tag...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 04 fc d4 4a 01 00 e1 00>
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Data received <Buffer 00 00 ff 11 ef d5 4b 01>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 11 ef d5 4b 01>
debug: [frame-emitter] Data received <Buffer 01 00 08 60 04 08 12 34 56 05 75 33 92 03 8c 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 11 ef d5 4b 01 01 00 08 60 04 08 12 34 56 05 75 33 92 03 8c 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":75,"body":{"type":"Buffer","data":[1,1,0,8,96,4,8,18,52,86,5,117,51,146,3,140]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":75,"body":{"type":"Buffer","data":[1,1,0,8,96,4,8,18,52,86,5,117,51,146,3,140]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":75,"body":{"type":"Buffer","data":[1,1,0,8,96,4,8,18,52,86,5,117,51,146,3,140]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
debug: [pn532] body <Buffer 01 01 00 08 60 04 08 12 34 56 05 75 33 92 03 8c>
scan du taf
messages: [ { tnf: 1,
type: 'T',
id: [],
payload: [ 2, 101, 110, 116, 101, 115, 116 ],
value: 'test' } ]
data: [ 209, 1, 7, 84, 2, 101, 110, 116, 101, 115, 116 ]
info: [pn532] Writing data...
debug: [pn532] block: <Buffer 03 0b d1 01 07 54 02 65 6e 74 65 73 74 fe>
debug: [pn532] Writing block: 0 at blockAddress: 4
debug: [pn532] pageData: <Buffer 03 0b d1 01>
info: [pn532] Writing block...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 09 f7 d4 40 01 a2 04 03 0b d1 01 65 00>
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Data received <Buffer 00 00 ff 03 fd d5 41 01>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 03 fd d5 41 01>
debug: [frame-emitter] Data received <Buffer e9 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 03 fd d5 41 01 e9 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":65,"body":{"type":"Buffer","data":[1,233]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":65,"body":{"type":"Buffer","data":[1,233]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":65,"body":{"type":"Buffer","data":[1,233]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
debug: [pn532] Frame data from block write: <Buffer 01 e9>
debug: [pn532] Writing block: 1 at blockAddress: 5
debug: [pn532] pageData: <Buffer 07 54 02 65>
info: [pn532] Writing block...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 09 f7 d4 40 01 a2 05 07 54 02 65 82 00>
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Data received <Buffer 00 00 ff 03 fd d5 41 02>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 03 fd d5 41 02>
debug: [frame-emitter] Data received <Buffer e8 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 03 fd d5 41 02 e8 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":65,"body":{"type":"Buffer","data":[2,232]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":65,"body":{"type":"Buffer","data":[2,232]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":65,"body":{"type":"Buffer","data":[2,232]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
debug: [pn532] Frame data from block write: <Buffer 02 e8>
debug: [pn532] Writing block: 2 at blockAddress: 6
debug: [pn532] pageData: <Buffer 6e 74 65 73>
info: [pn532] Writing block...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 09 f7 d4 40 01 a2 06 6e 74 65 73 89 00>
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Data received <Buffer 00 00 ff 03 fd d5 41 01 e9 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 03 fd d5 41 01 e9 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":65,"body":{"type":"Buffer","data":[1,233]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":65,"body":{"type":"Buffer","data":[1,233]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":65,"body":{"type":"Buffer","data":[1,233]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
debug: [pn532] Frame data from block write: <Buffer 01 e9>
debug: [pn532] Writing block: 3 at blockAddress: 7
debug: [pn532] pageData: <Buffer 74 fe 00 00>
info: [pn532] Writing block...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 09 f7 d4 40 01 a2 07 74 fe 00 00 d0 00>
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Data received <Buffer 00 00 ff 03 fd d5 41 01>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 03 fd d5 41 01>
debug: [frame-emitter] Data received <Buffer e9 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 03 fd d5 41 01 e9 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":65,"body":{"type":"Buffer","data":[1,233]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":65,"body":{"type":"Buffer","data":[1,233]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":65,"body":{"type":"Buffer","data":[1,233]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
debug: [pn532] Frame data from block write: <Buffer 01 e9>
Write successful
The output of the reader :
pi@raspberrypi:~/testNFCP2P $ PN532_LOGGING=debug node index.js
DEPRECATION: Please use `require('serialport')` instead of `require('serialport').SerialPort`
debug: [frame-emitter] listening to data
debug: [hsu] Initializing serial port...
debug: [hsu] Serial port initialized.
info: [pn532] Configuring secure access module (SAM)...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 05 fb d4 14 01 00 01 16 00>
debug: [hsu] Waking up PN532...
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 02 fe d5 15 16 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":21,"body":{"type":"Buffer","data":[22]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
info: [pn532] Emulating tag...
commandBuffer : 140,5,8,0,18,52,86,96,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
debug: [pn532] Sending buffer: <Buffer 00 00 ff 27 d9 d4 8c 05 08 00 12 34 56 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 00>
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Data received <Buffer 00 00 ff 05 fb d5 8d 08>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 05 fb d5 8d 08>
debug: [frame-emitter] Data received <Buffer e0 50 66 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 05 fb d5 8d 08 e0 50 66 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":141,"body":{"type":"Buffer","data":[8,224,80,102]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":141,"body":{"type":"Buffer","data":[8,224,80,102]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":141,"body":{"type":"Buffer","data":[8,224,80,102]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
debug: [pn532] body <Buffer 08 e0 50 66>
mode 8
debug: [pn532] mode 8
emulateTag initialized
info: [pn532] Emulate get data...
debug: [pn532] Sending buffer: <Buffer 00 00 ff 02 fe d4 86 a6 00>
debug: [frame-emitter] Data received <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 00 ff 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [pn532] Response received for sendCommand <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
info: [pn532] Command Acknowledged <AckFrame {"type":"Buffer","data":[0,0,255,0,255,0]}>
debug: [frame-emitter] AckFrame found in buffer
debug: [frame-emitter] Data received <Buffer 00 00 ff 09 f7 d5 87 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 09 f7 d5 87 00>
debug: [frame-emitter] Data received <Buffer a2 04 03 0b d1 01 1e 00>
debug: [frame-emitter] Processing buffer <Buffer 00 00 ff 09 f7 d5 87 00 a2 04 03 0b d1 01 1e 00>
debug: [frame-emitter] Frame found in buffer
info: [frame-emitter] Frame <DataFrame {"data":{"command":135,"body":{"type":"Buffer","data":[0,162,4,3,11,209,1,30]}}}>
debug: [pn532] Response received for sendCommand <DataFrame {"data":{"command":135,"body":{"type":"Buffer","data":[0,162,4,3,11,209,1,30]}}}>
info: [pn532] Command Response <DataFrame {"data":{"command":135,"body":{"type":"Buffer","data":[0,162,4,3,11,209,1,30]}}}>
debug: [pn532] Removing listeners
debug: [frame-emitter] DataFrame found in buffer
debug: [pn532] Frame data from emulate get data read: <Buffer 00 a2 04 03 0b d1 01 1e>
debug: [pn532] data <Buffer 01 1e>
debug: [pn532] instruction 4
debug: [pn532] parameter1 3
debug: [pn532] parameter2 11
debug: [pn532] commandLength 209
debug: [pn532] data <Buffer 01 1e>
Final data read :
dataRead : <Buffer 01 1e>
Hi @techniq did you have any news ? I am a little in trouble on my side .
@Zhairgling Sorry, I haven't had a chance to look at this any more, and just picked up an overtime project at my work so I'm going to be pretty busy for a while. I'll let you know if I do get some time to look into it, but I wouldn't expect anything from me for a bit.
@techniq Hi, I understand, I wish you success in your work. Currently it happens that this project is for my work too. I hope that I will find a solution too.
I have a question and am relative new to coding. I want to grab the data and compare it to a variable. For example if I want to read a block and store it as variable X then compare it to variable Y.
How would I store what nfc.PrintHexChar(data, 16); prints into variable X?
@danield12, you would do the following:
var x = nfc.PrintHexChar(data, 16);
although this library does not have a PrintHexChar
function so I'm not sure if you're in the right issues :)
Hi @techniq did you have any news ? I'm stuck with this project. Yet I feel that we are approaching the goal.
@techniq
I've worked on the 2 functions,
emulateTag and emulateGetData.
here is the code, could you please read and say what do you think about that.
'use strict';
var util = require('util');
//var Promise = require('bluebird');
var EventEmitter = require('events').EventEmitter;
var setupLogging = require('./logs');
setupLogging(process.env.PN532_LOGGING);
var logger = require('winston').loggers.get('pn532');
var FrameEmitter = require('./frame_emitter').FrameEmitter;
var frame = require('./frame');
var DataFrame = frame.DataFrame;
var AckFrame = frame.AckFrame;
var c = require('./constants');
class PN532 extends EventEmitter {
/*
@constructor
@param {object} hal - An instance of node-serialport's SerialPort or node-i2c's i2c
*/
constructor(hal, options) {
super();
options = options || {};
this.pollInterval = options.pollInterval || 1000;
if (hal.constructor.name === 'SerialPort') {
var PN532_UART = require('./pn532_uart');
this.hal = new PN532_UART(hal);
} else if (hal.constructor.name === 'i2c') {
var PN532_I2C = require('./pn532_i2c');
this.hal = new PN532_I2C(hal);
} else {
throw new Error('Unknown hardware type: ', hal.constructor.name);
}
this.frameEmitter = new FrameEmitter(this.hal);
this.hal.init().then(() => {
this.configureSecureAccessModule().then(() => this.emit('ready'));
});
this.on('newListener', (event) => {
// TODO: Only poll once (for each event type)
if (event === 'tag') {
logger.debug('Polling for tag scans...');
var scanTag = () => {
this.scanTag().then((tag) => {
this.emit('tag', tag);
setTimeout(() => scanTag(), this.pollInterval);
});
};
scanTag();
}
});
}
sendCommand(commandBuffer) {
return new Promise((resolve, reject) => {
var removeListeners = () => {
logger.debug('Removing listeners');
this.frameEmitter.removeListener('frame', onFrame);
this.frameEmitter.removeListener('error', onError);
};
// Wire up listening to wait for response (or error) from PN532
var onFrame = (frame) => {
logger.debug('Response received for sendCommand', util.inspect(frame));
// TODO: If no ACK after 15ms, resend? (page 40 of user guide, UART only)?
if (frame instanceof AckFrame) {
logger.info('Command Acknowledged', util.inspect(frame));
} else if (frame instanceof DataFrame) {
logger.info('Command Response', util.inspect(frame));
removeListeners();
resolve(frame);
}
};
this.frameEmitter.on('frame', onFrame);
var onError = (error) => {
logger.error('Error received for sendCommand', error);
removeListeners();
reject(error);
};
this.frameEmitter.on('error', onError);
// Send command to PN532
var dataFrame = new DataFrame(commandBuffer);
var buffer = dataFrame.toBuffer();
logger.debug('Sending buffer:', util.inspect(buffer));
this.hal.write(buffer);
});
}
configureSecureAccessModule() {
logger.info('Configuring secure access module (SAM)...');
// TODO: Test IRQ triggered reads
var timeout = 0x00; // 0x00-0xFF (12.75 seconds). Only valid for Virtual card mode (SAMCONFIGURATION_MODE_VIRTUAL_CARD)
var commandBuffer = [
c.COMMAND_SAMCONFIGURATION,
c.SAMCONFIGURATION_MODE_NORMAL,
timeout,
c.SAMCONFIGURATION_IRQ_ON // Use IRQ pin
];
return this.sendCommand(commandBuffer);
}
getFirmwareVersion() {
logger.info('Getting firmware version...');
return this.sendCommand([c.COMMAND_GET_FIRMWARE_VERSION])
.then((frame) => {
var body = frame.getDataBody();
return {
IC: body[0],
Ver: body[1],
Rev: body[2],
Support: body[3]
};
});
}
getGeneralStatus() {
logger.info('Getting general status...');
return this.sendCommand([c.COMMAND_GET_GENERAL_STATUS])
.then((frame) => {
var body = frame.getDataBody();
return body;
});
}
scanTag() {
logger.info('Scanning tag...');
var maxNumberOfTargets = 0x01;
var baudRate = c.CARD_ISO14443A;
var commandBuffer = [
c.COMMAND_IN_LIST_PASSIVE_TARGET,
maxNumberOfTargets,
baudRate
];
return this.sendCommand(commandBuffer)
.then((frame) => {
var body = frame.getDataBody();
logger.debug('body', util.inspect(body));
var numberOfTags = body[0];
if (numberOfTags === 1) {
var tagNumber = body[1];
var uidLength = body[5];
var uid = body.slice(6, 6 + uidLength)
.toString('hex')
.match(/.{1,2}/g)
.join(':');
return {
ATQA: body.slice(2, 4), // SENS_RES
SAK: body[4], // SEL_RES
uid: uid
};
}
});
}
readBlock(options) {
logger.info('Reading block...');
var options = options || {};
var tagNumber = options.tagNumber || 0x01;
var blockAddress = options.blockAddress || 0x01;
var commandBuffer = [
c.COMMAND_IN_DATA_EXCHANGE,
tagNumber,
c.MIFARE_COMMAND_READ,
blockAddress,
];
return this.sendCommand(commandBuffer)
.then((frame) => {
var body = frame.getDataBody();
logger.debug('Frame data from block read:', util.inspect(body));
var status = body[0];
if (status === 0x13) {
logger.warn('The data format does not match to the specification.');
}
var block = body.slice(1, body.length - 1); // skip status byte and last byte (not part of memory)
// var unknown = body[body.length];
return block;
});
}
readNdefData() {
logger.info('Reading data...');
return this.readBlock({blockAddress: 0x04})
.then((block) => {
logger.debug('block:', util.inspect(block));
// Find NDEF TLV (0x03) in block of data - See NFC Forum Type 2 Tag Operation Section 2.4 (TLV Blocks)
var ndefValueOffset = null;
var ndefLength = null;
var blockOffset = 0;
while (ndefValueOffset === null) {
logger.debug('blockOffset:', blockOffset, 'block.length:', block.length);
if (blockOffset >= block.length) {
throw new Error('Unable to locate NDEF TLV (0x03) byte in block:', block)
}
var type = block[blockOffset]; // Type of TLV
var length = block[blockOffset + 1]; // Length of TLV
logger.debug('blockOffset', blockOffset);
logger.debug('type', type, 'length', length);
if (type === c.TAG_MEM_NDEF_TLV) {
logger.debug('NDEF TLV found');
ndefLength = length; // Length proceeds NDEF_TLV type byte
ndefValueOffset = blockOffset + 2; // Value (NDEF data) proceeds NDEV_TLV length byte
logger.debug('ndefLength:', ndefLength);
logger.debug('ndefValueOffset:', ndefValueOffset);
} else {
// Skip TLV (type byte, length byte, plus length of value)
blockOffset = blockOffset + 2 + length;
}
}
var ndefData = block.slice(ndefValueOffset, block.length);
var additionalBlocks = Math.ceil((ndefValueOffset + ndefLength) / 16) - 1;
logger.debug('Additional blocks needing to retrieve:', additionalBlocks);
// Sequentially grab each additional 16-byte block (or 4x 4-byte pages) of data, chaining promises
var self = this;
var allDataPromise = (function retrieveBlock(blockNum) {
if (blockNum <= additionalBlocks) {
var blockAddress = 4 * (blockNum + 1);
logger.debug('Retrieving block:', blockNum, 'at blockAddress:', blockAddress);
return self.readBlock({blockAddress: blockAddress})
.then(function(block) {
blockNum++;
ndefData = Buffer.concat([ndefData, block]);
return retrieveBlock(blockNum);
});
}
})(1);
return allDataPromise.then(() => ndefData.slice(0, ndefLength));
})
.catch(function(error) {
logger.error('ERROR:', error);
});
}
writeBlock(block, options) {
logger.info('Writing block...');
var options = options || {};
var tagNumber = options.tagNumber || 0x01;
var blockAddress = options.blockAddress || 0x01;
var commandBuffer = [].concat([
c.COMMAND_IN_DATA_EXCHANGE,
tagNumber,
c.MIFARE_COMMAND_WRITE_4,
blockAddress
], block);
return this.sendCommand(commandBuffer)
.then((frame) => {
var body = frame.getDataBody();
logger.debug('Frame data from block write:', util.inspect(body));
var status = body[0];
if (status === 0x13) {
logger.warn('The data format does not match to the specification.');
}
var block = body.slice(1, body.length - 1); // skip status byte and last byte (not part of memory)
// var unknown = body[body.length];
return block;
});
}
writeNdefData(data) {
logger.info('Writing data...');
// Prepend data with NDEF type and length (TLV) and append terminator TLV
var block = [].concat([
c.TAG_MEM_NDEF_TLV,
data.length
], data, [
c.TAG_MEM_TERMINATOR_TLV
]);
logger.debug('block:', util.inspect(new Buffer(block)));
var PAGE_SIZE = 4;
var totalBlocks = Math.ceil(block.length / PAGE_SIZE);
// Sequentially write each additional 4-byte pages of data, chaining promises
var self = this;
var allPromises = (function writeBlock(blockNum) {
if (blockNum < totalBlocks) {
var blockAddress = 0x04 + blockNum;
var pageData = block.splice(0, PAGE_SIZE);
if (pageData.length < PAGE_SIZE) {
pageData.length = PAGE_SIZE; // Setting length will make sure NULL TLV (0x00) are written at the end of the page
}
logger.debug('Writing block:', blockNum, 'at blockAddress:', blockAddress);
logger.debug('pageData:', util.inspect(new Buffer(pageData)));
return self.writeBlock(pageData, {blockAddress: blockAddress})
.then(function(block) {
blockNum++;
// ndefData = Buffer.concat([ndefData, block]);
return writeBlock(blockNum);
});
}
})(0);
// return allDataPromise.then(() => ndefData.slice(0, ndefLength));
return allPromises;
}
// WIP
authenticateBlock(uid, options) {
logger.info('Authenticating block...');
var options = options || {};
var blockAddress = options.blockAddress || 0x04;
var authType = options.authType || c.MIFARE_COMMAND_AUTH_A
var authKey = options.authKey || [0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
var tagNumber = options.tagNumber || 0x01;
var uidArray = uid.split(':').map(s => Number('0x' + s));
var commandBuffer = [
c.COMMAND_IN_DATA_EXCHANGE,
tagNumber,
authType,
blockAddress
].concat(authKey).concat(uidArray);
return this.sendCommand(commandBuffer)
.then((frame) => {
var body = frame.getDataBody();
logger.info('Frame data from mifare classic authenticate', util.inspect(body));
console.log('body', body);
return body;
// var status = body[0];
// var tagData = body.slice(1, body.length);
// return {
// status: status.toString(16),
// tagData: tagData
// };
});
}
emulateTag() {
logger.info('Emulating tag...');
var commAsTarget= 0x8C;
var mode = 0x05; // PICC only, Passive Only
var sens_res = [0x04, 0x00];
var nfcId1t = [0x00, 0x00, 0x00];
var sel_res = [0x20];
var mifareParams = [].concat(sens_res, nfcId1t, sel_res);
var felicaParams = [0x01,0xFE,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
0xFF,0xFF];
var nfcId3t = [0xAA,0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,0x11];
var generalBytesLength = 0;
var historicalBytesLength = 0;
var commandBuffer = [].concat(
commAsTarget,
mode,
mifareParams,
felicaParams,
nfcId3t,
generalBytesLength,
historicalBytesLength
);
console.log('commandBuffer : '+ commandBuffer);
return this.sendCommand(commandBuffer)
.then((frame) => {
var body = frame.getDataBody();
logger.debug('body', util.inspect(body));
var mode = body[0];
console.log('mode', mode);
logger.debug('mode', mode);
/* var initiatorCommand = 0x88;
var numberOfTags = body[0];
if (numberOfTags === 1) {
var tagNumber = body[1];
var uidLength = body[5];
var uid = body.slice(6, 6 + uidLength)
.toString('hex')
.match(/.{1,2}/g)
.join(':');
return {
ATQA: body.slice(2, 4), // SENS_RES
SAK: body[4], // SEL_RES
uid: uid
};
}*/
});
}
emulateGetData() {
logger.info('Emulate get data...');
return this.sendCommand([c.TG_GET_DATA])//0x86
.then((frame) => {
var body = frame.getDataBody();
logger.debug('Frame data from emulate get data read:', util.inspect(body));
var status = body[0];
if (status === 0x13) {
logger.warn('The data format does not match to the specification.');
}
// var dataIn = body.slice(1, body.length - 1); // skip status byte and last byte (not part of memory)
// 00 00 a4 04 00 07 d2 76 00 00 85 01 01 00 26
var cla = body[1]
var instruction = body[2];
var parameter1 = body[3];
var parameter2 = body[4];
var commandLength = body[5];
var data = body.slice(6, commandLength);
logger.debug('status', status);
logger.debug('instruction', instruction);
logger.debug('parameter1', parameter1);
logger.debug('parameter2', parameter2);
logger.debug('commandLength', commandLength);
logger.debug('data', util.inspect(data));
logger.debug('Final data read : '+data);
switch(instruction) {
case c.ISO7816_SELECT_FILE:
logger.info('Select file');
if (parameter1 === 0x00) {
logger.info('Select by Id');
}
if (parameter1 === 0x04) {
logger.info('Select by name');
}
case c.C_APDU_P1_SELECT_BY_ID:
if(parameter2 != 0x0c){
// DMSG("C_APDU_P2 != 0x0c\n");
// setResponse(COMMAND_COMPLETE, rwbuf, &sendlen);
} else if(lc == 2 && rwbuf[c.C_APDU_DATA] == 0xE1 && (rwbuf[c.C_APDU_DATA+1] == 0x03 || rwbuf[c.C_APDU_DATA+1] == 0x04)){
// setResponse(COMMAND_COMPLETE, rwbuf, &sendlen);
if(rwbuf[C_APDU_DATA+1] == 0x03){
currentFile = CC;
} else if(rwbuf[C_APDU_DATA+1] == 0x04){
currentFile = NDEF;
}
} else {
// setResponse(TAG_NOT_FOUND, rwbuf, &sendlen);
}
break;
case c.C_APDU_P1_SELECT_BY_NAME:
logger.info('c la ==============================================');
// const uint8_t ndef_tag_application_name_v2[] = {0, 0x7, 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01 };
//if(0 == memcmp(ndef_tag_application_name_v2, rwbuf + c.C_APDU_P2, sizeof(ndef_tag_application_name_v2))){
logger.info('ca passe');
// setResponse(COMMAND_COMPLETE, rwbuf, &sendlen);
return this.sendCommand([c.R_APDU_SW1_COMMAND_COMPLETE,c.R_APDU_SW2_COMMAND_COMPLETE]);
// } else{
// DMSG("function not supported\n");
// setResponse(FUNCTION_NOT_SUPPORTED, rwbuf, &sendlen);
// }
break;
break;
case c.ISO7816_READ_BINARY:
logger.info('Read binary');
break;
case c.ISO7816_UPDATE_BINARY:
logger.info('Update binary');
break;
default:
logger.warn('Command not supported');
}
return data;
});
}
emulateSetData(data) {
logger.info('Writing data... bon code');
// Prepend data with NDEF type and length (TLV) and append terminator TLV
var block = [].concat([
c.TAG_MEM_NDEF_TLV,
data.length
], data, [
c.TAG_MEM_TERMINATOR_TLV
]);
logger.debug('block:', util.inspect(new Buffer(block)));
var PAGE_SIZE = 4;
var totalBlocks = Math.ceil(block.length / PAGE_SIZE);
// Sequentially write each additional 4-byte pages of data, chaining promises
var self = this;
var allPromises = (function writeBlock(blockNum) {
if (blockNum < totalBlocks) {
var blockAddress = 0x04 + blockNum;
var pageData = block.splice(0, PAGE_SIZE);
if (pageData.length < PAGE_SIZE) {
pageData.length = PAGE_SIZE; // Setting length will make sure NULL TLV (0x00) are written at the end of the page
}
logger.debug('Writing block:', blockNum, 'at blockAddress:', blockAddress);
logger.debug('pageData:', util.inspect(new Buffer(pageData)));
return self.writeBlock(pageData, {blockAddress: blockAddress})
.then(function(block) {
blockNum++;
// ndefData = Buffer.concat([ndefData, block]);
return writeBlock(blockNum);
});
}
})(0);
// return allDataPromise.then(() => ndefData.slice(0, ndefLength));
return allPromises;
// }
}
}
exports.PN532 = PN532;
exports.I2C_ADDRESS = c.I2C_ADDRESS;
@Zhairgling Sorry, I've just not had time to get back with you. I'm overcommitted as it is with my work/overtime I just don't have any time right now to help (at the level you need right now).
@techniq Hi can now make P2P exchange ;) Thanks for all the help you give me. If you want more informations i let you come to me. BTW you can now close this issue
Awesome. Glad you were able to figure it out. Can you commit your changes to your fork so I can see them?
On Mon, Mar 13, 2017, 5:18 AM Zhairgling notifications@github.com wrote:
@techniq https://github.com/techniq Hi can now make P2P exchange ;) Thanks for all the help you give me. If you want more informations i let you come to me. BTW you can now close this issue
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/techniq/node-pn532/issues/12#issuecomment-286052946, or mute the thread https://github.com/notifications/unsubscribe-auth/AAK1RHSty_Fl6mW4r0MkSM_GDAaZT1Cxks5rlQnLgaJpZM4LsF1P .
hi i am trying to get card emulation working, so my android phone can read some data from my rpi. I have had no luck in trying to get the my phone read anything from the card emulation..... while using nfc tools.... i can have my pn532 read some tags....
@Coollision I never got around to merging in @Zhairgling branch and never received a PR. I'm pretty sure he had success with emulation, so maybe give his fork a try and if it works for you, would you care to send a PR this way and I'll cut a release?
@Coollision I don't have any time and ressources atm for that PR. you can use my fork and do the job if you want. I did not try with android but between 2 rpi it works pretty well .
Can we transfer data between 2 pn532 ? like android beam ? I have a raspberry pi 3 and Pn532 from adafruit in uart mode.