I am trying to communicate with an ACR1252U NFC card reader (http://www.acs.com.hk/en/products/342/acr1252u-usb-nfc-reader-iii-nfc-forum-certified-reader/) using Node.js and the https://github.com/nonolith/node-usb NPM module.
I have created a simple script to get the reader USB device and listen for events.
When an NFC card comes in contact with the reader I receive a buffer:
<Buffer 50 03>
When the NFC card is taken away from the read I receive a buffer:
<Buffer 50 02>
This indicates that I am at least able to get some basic communication with the reader working.
My problem now is I am trying to get information about the NFC card when it comes in contact with the reader. I have tried to send data to the reader but cannot get a consistent response (sometimes I get a buffer response and sometimes I don't, running the same command over and over).
I decided to simplify the command I was sending to just turn on and off the reader's internal buzzer so I looked at the API documentation (http://www.acs.com.hk/download-manual/6402/API-ACR1252U-A1-1.07.pdf) which says that to activate the buzzer you send through:
E0h 00h 00h 28h 01h + 1 byte to determine duration of buzzer activation
With that in mind I created a buffer:
var buf = new Buffer(6);
buf.write('e00000280108', 'hex');
Then used the USB module's out endpoint to send the data:
outEndpoint.transfer(buf, function (err) {
console.log('out transfer', err);
});
The console logs "out transfer" with no error but nothing is received from the "in" endpoint.
If I create a 64 byte buffer instead:
var buf = new Buffer(64);
buf.write('e00000280108', 'hex');
outEndpoint.transfer(buf, function (err) {
console.log('out transfer', err);
});
I receive a response from the "in" endpoint:
<Buffer e0 00 00 00 00 01 00 42 ff 00>
This doesn't seem to correspond to what is expect from the manual and doesn't activate the buzzer at all.
I'm very new to directly communicating with USB devices like this and my last experience of this type was sending AT commands to modems back in the day :)
Could anyone shed any light on what I am doing wrong? I figure that sending 64 bytes instead of 6 has something to do with the USB standard requiring a set length or something like that?!? Has anyone else had experience communicating with an NFC reader (non-HID) with Node.js? Ultimately all I want to do is be able to write some data to an NFC tag and read it back later on when the tag is presented.
I thought it would be a pretty simple process but I'm stumped! Maybe I should be encoded the data differently? Maybe I'm not terminating the data properly? I just don't know!
I tried increasing the buffer size by 1 and adding a \0 terminator to the buffer via:
buf.write('\0', 6, 'utf-8');
But that didn't make any difference at all.
Thanks!
The commands described in the API specification are (pseudo) APDU commands to be exchange with the reader over PC/SC. When you access the reader directly through USB without a PS/SC abstraction layer (see http://www.pcscworkgroup.com/specifications/overview.php), you have to implement that abstraction yourself. Therefore, you have to implement the USB CCID (chip card interface device) class interface yourself. Essentially, this means that you have to encapsulate APDU commands in the CCID protocol. You can fin the specification here: http://www.usb.org/developers/docs/devclass_docs/
Related
I'm making a project with Esp32 whroom, so I bought the yj-16009 iBeacon DataSheet and I'm trying to get it to work as wireless Bluetooth proximity sensor like in this Video
I used the this code from the video and the esp32 is monitoring and showing BLT scanning results like this the results shown are after I turned off any BLT device around so first I don't understand what it is reading, and second after I turn on the iBeacon the results remain with the same range of numbers no matter if I get the iBeacon closer or farther, therefor I came to the conclusion that it doesn't recognize the iBeacon sensor for some reason.
I also download an app named LightBlue which does recognize the iBeacon sensor.
My question is if anyone knows how to make the esp32 recognize the iBeacon sensor. Another thing I tried to find any information about this sensor and there is no info about it anywhere. I have read on other questions here that it might need to be programmed somehow which I don't know how to do because there is no info online. So if anyone is familiar with this kind of sensor and can help me figure how to make the ibeacon to work like the video above as a Bluetooth Proximity device it would be a blessing.
The code you reference is just scanning for any BLE advertisements (iBeacon or otherwise) and printing out the RSSI signal strength of each detection. The reason you do not see the RSSI change when you move the beacon is because the ESP32 is probably picking up non-iBeacon adverts from your phone, laptop and other Bluetooth enabled devices in the vicinity which are not moving (there are more around you than you think!)
In order to make the device detect iBeacon only (and not all the other devices) you need to change the C code to do a few more things:
Access the bytes of the advertisement payload and use them as follows:
Compare the beginning of these bytes to see if they include the iBeacon byte sequence FF 4C 00 02 15
If the above byte sequence is not in the advertising data, ignore that detection — it is not an iBeacon advert
If it does include that byte sequence, decode the next 16 bytes as the iBeacon uuid, the next two bytes as the major and the next two bytes as the minor. See my answer here: What is the iBeacon Bluetooth Profile
Print out the identifiers along with the RSSI that the code already prints.
TLDR:
Is there a way to create a hex value between 0x20 and 0x7E with 5 volts? Is there a cheap component on the market or circuit logic that can achieve this?
I'm not sure what the proper terminology for this is, but here's what I'm trying to do:
I have a bluetooth module connected to my pico via UART0 TX and UART0 RX. The use for this is a bit long to explain, but essentially, I want the bluetooth module to work without my pico attached to it. I have a device that outputs a signal, the pico reads the signal, then it tells the bluetooth module to transmit to the receiver. However, since the data to transmit isn't actually important, it makes sense to cut out the pico and simply have the bluetooth module read the signal directly then transmit.
I have the device that outputs exactly when I want, but it outputs the equivalent of 00 in hex. My computer is connected via bluetooth and can read it just fine. However, the pico, reading the input through RX, can't. I've found no way for micropython using UART to read 00 - UART.any() and UART.read() want a character, and 00 only corresponds to NULL.
So essentially, I need some way to transmit a hex value between 0x20 and 0x7E without using the raspberry pi pico. Is there some kind of component that is able to do this? In practice, the bluetooth module will be connected to 5V power with up to 5 amps.
Any idea on how to get the Pico to read 00 in hex through the RX pin is welcomed too. The purpose of this is to not need multiple Picos, since the receiver and the transmitter will be a good distance from each other.
I found the issue. The pico actually can accept 0 through the UART RX pin. The issue was me having a wire misplaced. My computer saw the 0 input which made me think the pico couldn't handle it, but in fact it was never receiving it. Thanks for the help Kotzjan. Would have been interesting to fake a value into the port though!
I am using JC30M48CR Type B Javacard and JCIDE for compiling.
I searched for the whole forum to find out if it is possible to change ATQB response for JAVACARD. However, all topics are about change ATR as given in setATRHistBytes() method always returns false.
May I know whether it is possible to customise ATQB? For example, the request code for ISO14443B is 05 00 00, then the ATQB response is 50 00 00 00 00 D1 03 86 0C 00 80 80.
Thanks
No, because Java Card does not control the lower level protocols at that level. And actually, the historical bytes are not applicable to Type B cards; you'd need to have an ATR specific file in the root folder to be able to communicate the historical bytes, because they are simply not present in the ISO/IEC 14443 type B protocol.
If the communication parameters can be set then that specific functionality is OS specific. So in general - if you're big enough - then you can have chips delivered with special settings. You may also be able to set the parameters yourself through another OS provided initialization application on chip. Those are all vendor specific.
Of course the vendors do not want to let any applet change the communication parameters. For the historical bytes the Java Card Forum compromised on only allow the default selected applet change the historical bytes (instead of using a specific INSTALL for INSTALL flag or other authentication measures).
In short: contact your supplier and ask for the user manual.
I have tested several javacards (Feitian D11CR, Infineon JTOP, G&D Smart Cafe) over T=0 and here is what I have observed.
If applet returns some data in case 4 APDU, the JCRE signals with SW 0x61XX that there is data available which terminal should retrieve using GET RESPONSE APDU.
However, if applet returns some data in case 2 APDU and Le does not match number of bytes to be returned, JCRE signals with error SW 0x6CXX, instructing that the same C-APDU has to be resent with correct Le.
For legacy reasons there are terminals who know how to handle 0x61XX, but fail to handle 0x6CXX response. Is there a way how to force JCRE to handle case 2 APDUs using 0x61XX (GET RESPONSE) method?
This behavior is given by the T=0 protocol where the length of data bytes transmitted must be fixed from the beginning of the TPDU exchange (i.e. the interface device decides it) -- in contrast to T=1/T=CL where the response length is left open for the card to decide.
Which causes trouble when the interface device sends an unacceptable value as data bytes length for Case 2 command -- the card can not transmit a different number of data bytes and has to send a special status word instead.
In T=0 the command cases are transmitted this way (very simplified):
Case 1:
CLA INS P1 P2 00, card responds with: SW1 SW2
Case 2:
CLA INS P1 P2 P3,
card responds with:
[ P3 bytes of response data ] SW1 SW2 if the actual length of response data equals P3
6C XX if value of P3 is unacceptable
Case 3:
CLA INS P1 P2 P3 [P3 bytes of command data], card responds with: SW1 SW2
Case 4:
CLA INS P1 P2 P3 [P3 bytes of command data], card responds with: 61 YY
CLA C0 00 00 YY card responds with: [YY bytes of response data] SW1 SW2
See ISO 7816-3, section "Command-response pair transmission by T=0" for exact details.
(In theory,) to workaround that (i.e. to prevent JCRE from sending the 6C XX status word), you would have to implement all Case 2 commands as Case 1 commands (i.e. do not call the APDU.setOutgoing()), return 61 XX status word and implement the GET RESPONSE command yourself (JCRE should pass this command to your process() method if it does not have it's own response data).
This brings some unnecessary overhead for terminal supporting 6C XX.
Some additional (random) notes:
user-level processing of extra GET RESPONSE command in process() method just worked for me. I did not check the JC specifications regarding this, YMMV.
it is a pity you can't use T=1
the workaround proposed above is just a theory. I've never implemented that approach (but I am definitely interested in the results you might get)
Hope this answer makes some sense...good luck!
There is a trick for Feitian and Infinion cards how to force 0x61XX response in "case 2" APDUs where Le=0x00 - the trick is to call setIncomingAndReceive(). This, however, will not work with other Le values (calling setIncomingAndReceive() with positive Le will cause error).
For compatibility reasons I ended up implementing 0x61XX support in the applet. So if the Le received does not match the length to be returned, the applet buffers the response in RAM and returns SW 0x61XX. When the GET RESPONSE APDU is received by process(), the Le will match the length buffered and the data will be returned using setOutgoingAndSend().
I have two different smartcard chips with Visa Paywave inside (one is native, and other is Java Card).
I am trying to run select PPSE or select Application command, one card is giving the expected result while another card is giving status word 6700.
Command ---->CMD 00A404000E325041592E5359532E4444463031
Sw1-sw2 <----67 00
Command ---->CMD 00A4040007A0000000031010
Sw1-sw2 <----67 00
We have some other proprietary test tool that is receiving a good result for both cards. That means that both cards have a PPSE and application in it. I wonder why my tool is sending the same command but getting a different result.
Any advice would be helpful here.
As we know that there are 4 cases defined in ISO7816-4 like,
As per my experience maximum card does not worry about Le field in apdu command, card O.S just process the command and return data if require.
Here i am getting error -6700 because here my card is expecting Le byte too.( card expecting case 4 instead of case 3)
Send command like below solve my problem,
00 A4 04 00 0E 325041592E5359532E4444463031 00 ( adding Le = 0x00 at last)