Search code examples
ccentosapduacr122lib-nfc

ACR122U Sending Direct commands returning -2 and Segmentation fault


I am trying to send a direct command to the ACR122U reader. The simplest one I have is: FF 00 48 00 00

This command is suppose to return the Firmware version. Using the ACR122U tool I can see that it works fine. I am trying to use nfc_initiator_transceive_bytes to send this and get the firmware version. This is how I am doing:

uint8_t abtCmd[] = {0xFF,0x00,0x48,0x00,0x00};
int res = nfc_initiator_transceive_bytes(
            pnd,           
            abtCmd,
            5,
            pbtRx,
            400,           
            2000
            );

This is always returning -2. Is nfc_initiator_transceive_bytes not the correct function? What am I doing wrong? Thanks!

PS: I have \xFF\x00\x00\x00\x05 on there because that's what the manual says to do (API_ACR122U_v1.4.pdf section 6.1 direct commands)

I have turned on debuging on libnfc and I am seeing this:

debug libnfc.driver.acr122_usb TX: 6f 0d 00 00 00 00 00 00 00 00 ff 00 00 00 08 d4 40 01 ff 00 48 00 00 debug
libnfc.driver.acr122_usb RX: 80 05 00 00 00 00 00 00 81 00 d5 41 27 90 00

I can see the ff 00 00 00 so I guess I don't have to specify that when I send a direct command, but this is still returning this:

debug libnfc.chip.pn53x Chip error: "Command Not Acceptable" (27), returned error: "Invalid argument(s)" (-2))

Is it the hex that libnfc is adding that is messing this up? Please anyone???

I have also changed the initial code.

I have also tried with nfc_target_send_bytes by doing:

nfc_target_send_bytes(pnd, abtCmd, 5,0);

This gives me a segmentation fault.


Solution

  • libnfc is an abstraction layer for the NFC functionality of NFC interface devices (like the ACR122U). So the method nfc_initiator_transceive_bytes() already handles the ACR122U device-specific protocol.

    In your case (you are using the acr122_usb interface driver), libnfc will directly interact with the NFC CCID device (exposed by the ACR122U) and will directly send CCID frames containing the reader-specific commands (APDU-wrapped native commands for the PN532 NFC controller inside the ACR122U).

    So in the case of nfc_initiator_transceive_bytes(), this means that libnfc will do the following:

    • Send the PN532 command InDataExchange (starting with d4 40) for sending data over NFC to the other NFC device.
    • Wrap the PN532 native command into an APDU for transport over CCID (starting with ff 00 00 00 08).
    • Wrap the whole command into a USB CCID-class frame (starting with 6f 0d).

    And for the answer:

    • Unwrap the answer CCID frame (starting with 80 05).
    • Unwrap the response APDU (d5 41 27 90 00).
    • Decode the native PN532 InDataExchange response (d5 41 27).

    For you this effectively means that you cannot use that method to send the ACR122U-specific APDU command (ff 00 48 00 00) to get the firmware-version of the reader using this method. Instead, you should use e.g. PC/SC to directly send APDU commands to the reader if you want to use such commands.