Beispiel #1
0
bool KeyDuino::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout)
{
    pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
    pn532_packetbuffer[1] = 1;  // max 1 cards at once (we can set this to 2 later)
    pn532_packetbuffer[2] = cardbaudrate;

    if (HAL(writeCommand)(pn532_packetbuffer, 3)) {
        DMSG_STR("\nFailed writing");
        return 0x0;  // command failed
    }

    // read data packet
    if (HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout) < 0) {
        DMSG_STR("\nFailed reading response");
        return 0x0;
    }

    // check some basic stuff
    /* ISO14443A card response should be in the following format:

      byte            Description
      -------------   ------------------------------------------
      b0              Tags Found
      b1              Tag Number (only one used in this example)
      b2..3           SENS_RES
      b4              SEL_RES
      b5              NFCID Length
      b6..NFCIDLen    NFCID
    */

    if (pn532_packetbuffer[0] != 1)
        return 0;

    inListedTag = pn532_packetbuffer[1];

    uint16_t sens_res = pn532_packetbuffer[2];
    sens_res <<= 8;
    sens_res |= pn532_packetbuffer[3];

    DMSG("\nATQA: 0x");  DMSG_HEX(sens_res);
    DMSG("\nSAK: 0x");  DMSG_HEX(pn532_packetbuffer[4]);
    DMSG("\n");

    /* Card appears to be Mifare Classic */
    *uidLength = pn532_packetbuffer[5];
    this->_uidLen = pn532_packetbuffer[5];

    for (uint8_t i = 0; i < pn532_packetbuffer[5]; i++) {
        uid[i] = pn532_packetbuffer[6 + i];
	    this->_uid[i] = pn532_packetbuffer[6 + i];
    }
    return 1;
}
Beispiel #2
0
bool KeyDuino::inListPassiveTarget(uint8_t cardbaudrate, uint16_t timeout)
{
    pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
    pn532_packetbuffer[1] = 1;
    pn532_packetbuffer[2] = cardbaudrate;

    DMSG_STR("\ninList passive target");

    if(cardbaudrate == PN532_ISO14443B){
        pn532_packetbuffer[3] = 0x00;
        if (HAL(writeCommand)(pn532_packetbuffer, 4))
            return false;
    } else {
        if (HAL(writeCommand)(pn532_packetbuffer, 3))
            return false;
    }

    int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout);
    if (status < 0) {
        return false;
    }

    if (pn532_packetbuffer[0] != 1) {
        return false;
    }

    inListedTag = pn532_packetbuffer[1];

    return true;
}
Beispiel #3
0
int8_t PN532_SPI::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
{
    command = header[0];
    writeFrame(header, hlen, body, blen);
    
    uint8_t timeout = PN532_ACK_WAIT_TIME;
    while (!isReady()) {
        delay(1);
        timeout--;
        if (0 == timeout) {
            DMSG_STR("Time out when waiting for ACK");
            return -2;
        }
    }
    if (readAckFrame()) {
        DMSG_STR("Invalid ACK");
        return PN532_INVALID_ACK;
    }
    return 0;
}
Beispiel #4
0
bool KeyDuino::inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength)
{
    uint8_t i;

    DMSG_STR("\ninDataExchange");

    pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
    pn532_packetbuffer[1] = inListedTag;

    if (HAL(writeCommand)(pn532_packetbuffer, 2, send, sendLength)) {
        DMSG_STR("\nWrite error");
        return false;
    }

    int16_t status = HAL(readResponse)(response, *responseLength, 1000);
    if (status < 0) {
        DMSG("\nStatus error: ");
        DMSG_STR(status);
        return false;
    }

    if ((response[0] & 0x3f) != 0) {
        DMSG_STR("\nStatus code indicates an error");
        return false;
    }

    uint8_t length = status;
    length -= 1;

    if (length > *responseLength) {
        length = *responseLength; // silent truncation...
    }

    for (uint8_t i = 0; i < length; i++) {
        response[i] = response[i + 1];
    }
    *responseLength = length;

    return true;
}
Beispiel #5
0
bool KeyDuino::SAMConfig(void)
{
    pn532_packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION;
    pn532_packetbuffer[1] = 0x01; // normal mode;
    pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second
    pn532_packetbuffer[3] = 0x01; // use IRQ pin!

    DMSG_STR("SAMConfig");

    if (HAL(writeCommand)(pn532_packetbuffer, 4))
        return false;

    return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
}
Beispiel #6
0
bool KeyDuino::writeGPIO(uint8_t pinstate)
{
    // Make sure pinstate does not try to toggle P32 or P34
    pinstate |= (1 << PN532_GPIO_P32) | (1 << PN532_GPIO_P34);

    // Fill command buffer
    pn532_packetbuffer[0] = PN532_COMMAND_WRITEGPIO;
    pn532_packetbuffer[1] = PN532_GPIO_VALIDATIONBIT | pinstate;  // P3 Pins
    pn532_packetbuffer[2] = 0x00;    // P7 GPIO Pins (not used ... taken by I2C)

    DMSG_STR("Writing P3 GPIO: ");
    DMSG_HEX(pn532_packetbuffer[1]);
    DMSG("\n");

    // Send the WRITEGPIO command (0x0E)
    if (HAL(writeCommand)(pn532_packetbuffer, 3))
        return 0;

    return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
}
Beispiel #7
0
void PN532_SPI::writeFrame(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
{
    digitalWrite(_ss, LOW);
    delay(2);               // wake up PN532
    write(DATA_WRITE);
    write(PN532_PREAMBLE);
    write(PN532_STARTCODE1);
    write(PN532_STARTCODE2);

    uint8_t length = hlen + blen + 1;   // length of data field: TFI + DATA
    write(length);
    write(~length + 1);         // checksum of length

    write(PN532_HOSTTOPN532);
    uint8_t sum = PN532_HOSTTOPN532;    // sum of TFI + DATA

    DMSG("write: ");

    for (uint8_t i = 0; i < hlen; i++) {
        write(header[i]);
        sum += header[i];

        DMSG_HEX(header[i]);
    }
    for (uint8_t i = 0; i < blen; i++) {
        write(body[i]);
        sum += body[i];

        DMSG_HEX(body[i]);
    }

    uint8_t checksum = ~sum + 1;        // checksum of TFI + DATA
    write(checksum);
    write(PN532_POSTAMBLE);

    digitalWrite(_ss, HIGH);

    DMSG_STR();
}
Beispiel #8
0
int16_t PN532_SPI::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout)
{
    uint16_t time = 0;
    while (!isReady()) {
        delay(1);
        time++;
        if (timeout > 0 && time > timeout) {
            return PN532_TIMEOUT;
        }
    }

    digitalWrite(_ss, LOW);
    delay(1);

    int16_t result;
    do {
        write(DATA_READ);

        if (0x00 != read()      ||       // PREAMBLE
                0x00 != read()  ||       // STARTCODE1
                0xFF != read()           // STARTCODE2
           ) {

            result = PN532_INVALID_FRAME;
            break;
        }

        uint8_t length = read();
        if (0 != (uint8_t)(length + read())) {   // checksum of length
            result = PN532_INVALID_FRAME;
            break;
        }

        uint8_t cmd = command + 1;               // response command
        if (PN532_PN532TOHOST != read() || (cmd) != read()) {
            result = PN532_INVALID_FRAME;
            break;
        }

        DMSG("read:  ");
        DMSG_HEX(cmd);

        length -= 2;
        if (length > len) {
            for (uint8_t i = 0; i < length; i++) {
                DMSG_HEX(read());                 // dump message
            }
            DMSG_STR("\nNot enough space");
            read();
            read();
            result = PN532_NO_SPACE;  // not enough space
            break;
        }

        uint8_t sum = PN532_PN532TOHOST + cmd;
        for (uint8_t i = 0; i < length; i++) {
            buf[i] = read();
            sum += buf[i];

            DMSG_HEX(buf[i]);
        }
        DMSG_STR();

        uint8_t checksum = read();
        if (0 != (uint8_t)(sum + checksum)) {
            DMSG_STR("checksum is not ok");
            result = PN532_INVALID_FRAME;
            break;
        }
        read();         // POSTAMBLE

        result = length;
    } while (0);

    digitalWrite(_ss, HIGH);

    return result;
}
Beispiel #9
0
bool KeyDuino::readPassiveTargetID_B(uint8_t *uid, uint8_t *uidLength, uint16_t timeout)
{
    pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
    pn532_packetbuffer[1] = 1;  // max 1 cards at once (we can set this to 2 later)
    pn532_packetbuffer[2] = PN532_ISO14443B;
    pn532_packetbuffer[3] = 0x00; //AFI

    if (HAL(writeCommand)(pn532_packetbuffer, 4)) {
        DMSG_STR("\nFailed writing");
        return 0x0;  // command failed
    }

    // read data packet
    if (HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout) < 0) {
        DMSG_STR("\nFailed reading response");
        return 0x0;
    }


    /* ISO14443B card response should be in the following format:

      byte                  Description
      ------------------    ------------------------------------------
      b0                    Tags Found
      b1                    Tag Number (only one used in this example)
      b2..13                ATQB
      b14                   ATTRIB_RES Length
      b15..ATTRIB_RESLen    ATTRIB_RES
    */

    if (pn532_packetbuffer[0] != 1)
        return 0;

    inListedTag = pn532_packetbuffer[1];

    /* ISO14443B ATQ_B format:

      byte          Description
      -----         ------------------------------------------
      b0            0x50
      b1..4         PUPI
      b5..8         Application Data
      b9            Bit Rate Capacity
      b10           Max Frame Size/-4 Info
      b11           FWI/Coding Options
    */

    uint8_t atqb[12];
    DMSG("\nATQ_B: ");
    if (pn532_packetbuffer[2] == 0x50) {        //Looking for the 0x50 to check if ATQ_B is well shaped
        for (uint8_t i = 0; i < 12; i++) {
            atqb[i] = pn532_packetbuffer[i+2];
            DMSG_HEX(atqb[i]);
        }
        DMSG("\n");
    } else                                      //Sometimes there are remnant bytes, in that case just let it go ...
        return 0;

    DMSG_STR("\nATTRIB_RES: ");
    for (uint8_t i = 0; i < pn532_packetbuffer[14]; i++) {
        DMSG_HEX(pn532_packetbuffer[15 + i]);
    }
    DMSG("\n");

    *uidLength = 4;
    this->_uidLen = 4;

    for (uint8_t i = 0; i < 4; i++) {
        uid[i] = atqb[1 + i];
	    this->_uid[i] = atqb[1 + i];
    }
    
    return 1;
}