PN532 Shield - Issues with packets > 25 bytes

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
thracky
 
Posts: 1
Joined: Sat Feb 08, 2014 5:26 pm

PN532 Shield - Issues with packets > 25 bytes

Post by thracky »

Hi everyone!

I am currently working on a project to implement the majority of MiFare DESFire into an Arduino UNO R3 utilizing the PN532 Shield and the Adafruit PN532 I2C library as a base for my work. I have been successful in authenticating to the card and performing some rudimentary tasks but I have encountered an issue when attempting to change the master encryption key used on the card.

Like all of the mifare classic commands already existing in the library, I make use of the pn532_packetbuffer to hold my command packet before executing sendCommandCheckAck, passing the buffer and the size of the packet as parameters. So far, most of my packets have been relatively small, at most 12 bytes, and have functioned perfectly. However, in order to change the encryption key on the DESFire card, I must send 26 bytes of data to the card directly, and adding the additional 2 bytes for the PN532 InDataExchange Command and the logical PICC number means my packetbuffer will contain 28 bytes.

Currently the code looks as follows:

Code: Select all

uint8_t Adafruit_NFCShield_I2C::mifaredesfire_ChangeKey(uint8_t keynum, uint8_t* enc_keydata, uint8_t keydatalen) {
        pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
        pn532_packetbuffer[1] = 0x01; //Select 1st logical card.
        pn532_packetbuffer[2] = DESFIRE_CMD_CHANGE_KEY; //0xC4
        pn532_packetbuffer[3] = 0x00; //Key number, for testing will only use the first key
        memcpy(pn532_packetbuffer+4, enc_keydata, keydatalen); //incoming key data length is always 24 right now.

        if(! sendCommandCheckAck(pn532_packetbuffer, 4+keydatalen)) {
                  return 0;
        }
        delay(500);

        wirereaddata(pn532_packetbuffer, 32);
        Serial.print("Reply from key change");
        Adafruit_NFCShield_I2C::PrintHex(pn532_packetbuffer, 32);
        return 1;

}
Strangely enough, when I truncate the packetbuffer to a length of 25 or less, I at least get a reply back from the PN532 and the PICC, the reply from the PICC telling me the command length is incorrect. However, as soon as I increase the length to 26, the PN532 gives me no reply whatsoever, but I am free to execute further commands without issue.

I understand this is way outside the scope of the provided libraries but I'm a bit puzzled as to why it is behaving this way, and any help would be much appreciated.

EDIT 2: Might this have something to do with the I2C frame limit of 32 bytes? I'm not particularly familiar with how this is handled though. Is a frame considered to be all data sent between beginning transmission and ending? If so, I guess it makes sense that the reader does not reply since there would be checksum information likely missing and the postamble. If this is the case, how might I solve this? Is there some form of chaining mechanism for I2C frames?

User avatar
ktownsend
 
Posts: 1447
Joined: Thu Nov 05, 2009 2:18 am

Re: PN532 Shield - Issues with packets > 25 bytes

Post by ktownsend »

I don't have any ideas off the top of my head but it's been a long time since I've worked with this code as well, and it's hard to reproduce anything without seeing the code and having access to HW. The 32-bytes sounds very plausible, though. Do you have a logic analyzer to capture a transactions that passes and one that fails (Saleae Logic, etc.)?

User avatar
mikesand
 
Posts: 1
Joined: Wed Oct 28, 2015 9:37 am

Re: PN532 Shield - Issues with packets > 25 bytes

Post by mikesand »

thracky wrote:Hi everyone!

Strangely enough, when I truncate the packetbuffer to a length of 25 or less, I at least get a reply back from the PN532 and the PICC, the reply from the PICC telling me the command length is incorrect. However, as soon as I increase the length to 26, the PN532 gives me no reply whatsoever, but I am free to execute further commands without issue.
I am having the same issue. A length of 24 (after inDataExchange adds 2 leading bytes, which thracky did manually) completes successfully and I get a message back from the peer, but if it goes up to 25 everything else exactly the same then it fails with TIMEOUT!. The deepest I can figure out is isready() in the library:

Code: Select all

    // I2C check if status is ready by IRQ line being pulled low.
    uint8_t x = digitalRead(_irq);
    return x == 0;
So for whatever reason this is failing based on the message length. The logic analyzer suggestion went right over my head.

I have the identical setup to thracky - Arduino UNO R3 utilizing the PN532 Shield and the Adafruit PN532 I2C library. Could it have to do with the UNO R3 then?

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”