Пример #1
0
BOOL q5_read_block(BYTE *response, BYTE block)
{
    BYTE tmp[39], retry, reset= FALSE;

    if(block > Q5_DATABLOCKS - 1)
        return FALSE;

    // create 6 or 38 bit command block: Q5_DIRECT_ACCESS + PWD_Mode + [PWD] + 3 bits address
    memset(tmp, '\0', 39);
    memcpy(tmp, Q5_DIRECT_ACCESS, 2);
    if(PWD_Mode)
    {
        tmp[2]= '1';
        hextobinstring(tmp + 3, Password);
        inttobinstring(tmp + 34, (unsigned int) block, 3);
    }
    else
    {
        tmp[2]= '0';
        inttobinstring(tmp + 3, (unsigned int) block, 3);
    }

    retry= RFIDlerConfig.Repeat;
    while(retry--)
    {
        //DEBUG_PIN_4= !DEBUG_PIN_4;
        //DEBUG_PIN_4= !DEBUG_PIN_4;
        if(q5_send_command(response, tmp, strlen(tmp), reset, NO_SYNC, 32))
            return TRUE;
        // try resetting tag
        reset= TRUE;
    }

    return FALSE;
}
Пример #2
0
// optional verify as writing config block may casue next read to fail
BOOL q5_write_block(BYTE block, BYTE *data, BOOL lock, BOOL verify)
{
    BYTE tmp[71], p;

    if(block > Q5_DATABLOCKS - 1)
        return FALSE;

    // create 38 or 70 bit command block: Q5_STD_WRITE_P0 + [PWD] + Lock Bit + 32 bits Data + 3 bits address
    memset(tmp, '\0', sizeof(tmp));

    // command
    memcpy(tmp, Q5_STD_WRITE_P0, 2);
    p= 2;

    // password
    if(PWD_Mode)
    {
        hextobinstring(tmp + p, Password);
        p += 32;
    }

    // lockbit
    inttobinstring(tmp + p, (unsigned int) lock, 1);
    ++p;

    // data
    hextobinstring(tmp + p, data);
    p += Q5_BLOCKSIZE;

    // address
    inttobinstring(tmp + p, (unsigned int) block, 3);
    p += 3;

    // send
    if(!q5_send_command(NULL, tmp, strlen(tmp), NO_RESET, NO_SYNC, 0))
        return FALSE;

    // no ack, so read back and verify
    // delay for long enough to allow write plus TX->RX period
    Delay_us((Q5_WRITE_DELAY * RFIDlerConfig.FrameClock + RFIDlerConfig.RWD_Wait_Switch_TX_RX * RFIDlerConfig.FrameClock) / 100L);

    if(!verify)
        return TRUE;

    if(!q5_read_block(tmp, block))
        return FALSE;
    if(memcmp(tmp, data, HEXDIGITS(Q5_BLOCKSIZE)) != 0)
        return FALSE;

    return TRUE;
}
Пример #3
0
// read page - 32 bits
// pages 2 - 15 are probably not readable!
BOOL hitag1_read_page(BYTE *response, BYTE block)
{
    BYTE tmp[HITAG1_BLOCKSIZE + 6]; // 32 bits plus 6 sync bits

    if(block > HITAG1_DATABLOCKS - 1)
        return FALSE;

    // get tag's UID for select command
    if(!hitag1_get_uid(tmp))
        return FALSE;

    // select for read/write
    hitag1_select(tmp, tmp);

    // create 12 bit command block: HITAG1_RDPPAGE + 8 bits address
    strcpy(tmp, HITAG1_RDPPAGE);
    inttobinstring(tmp + 4, (unsigned int) block, 8);
    tmp[12]= '\0';

    // ??? docs say 6 sync bits!
    if(!hitag1_send_command(tmp, tmp, NO_RESET, NO_SYNC, HITAG1_BLOCKSIZE + 1, NO_ACK))
        return FALSE;

    // check sync
    if(tmp[0] != 0x01)
        return FALSE;

    binarraytohex(response, tmp + 1, HITAG1_BLOCKSIZE);

    return TRUE;
}
Пример #4
0
BOOL hitag1_write_page(BYTE block, BYTE *data)
{
    BYTE crc, command[21], tmp[33], tmp1[4];

    if(block > HITAG1_DATABLOCKS - 1)
        return FALSE;

    // get tag's UID for select command
    if(!hitag1_get_uid(tmp))
        return FALSE;

    // select for read/write
    hitag1_select(tmp, tmp);

    // convert data to binstring for send
    if(hextobinstring(tmp, data) != 32)
        return FALSE;

    // create and send 12 bit command block: HITAG1_WRPPAGE (4 bits) + 8 bit address
    memcpy(command, HITAG1_WRPPAGE, 4);
    inttobinstring(command + 4, (unsigned int) block, 8);
    command[12]= '\0';
    if(!hitag1_send_command(tmp1, command, NO_RESET, NO_SYNC, 0, ACK))
        return FALSE;

    // delay to switch back to write mode
    Delay_us((RFIDlerConfig.RWD_Wait_Switch_RX_TX * RFIDlerConfig.FrameClock) / 100);

    // now send data
    if(!hitag1_send_command(tmp1, tmp, NO_RESET, NO_SYNC, 0, ACK))
        return FALSE;

    // read back and verify
    // delay for long enough to allow write plus RX->TX period
    Delay_us((HITAG1_WRITE_DELAY * RFIDlerConfig.FrameClock + RFIDlerConfig.RWD_Wait_Switch_RX_TX * RFIDlerConfig.FrameClock) / 100);
    if(!hitag1_read_page(tmp, block))
        return FALSE;

    if(memcmp(tmp, data, 8) != 0)
        return FALSE;

    return TRUE;
}
Пример #5
0
BOOL hitag2_read_page(BYTE *response, BYTE block)
{
    BYTE tmp[37];

    if(block > HITAG2_DATABLOCKS - 1)
        return FALSE;

    // create 10 bit command block: HITAG2_READ_PAGE + 3 bits address + invert(HITAG2_READ_PAGE + 3 bits address)
    memcpy(tmp, HITAG2_READ_PAGE, 2);
    inttobinstring(tmp + 2, (unsigned int) block, 3);
    invertbinstring(tmp + 5, tmp);
    tmp[10]= '\0';

    // encrypt command if in crypto mode
    if(CryptoActive)
        hitag2_binstring_crypt(tmp, tmp);

    // send with RX->TX delay and no reset
    if(!rwd_send(tmp, strlen(tmp), NO_RESET, BLOCK, RWD_STATE_WAKING, RFIDlerConfig.FrameClock, 0, RFIDlerConfig.RWD_Wait_Switch_RX_TX, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX))
        return FALSE;

    // skip 1/2 bit to synchronise manchester
    HW_Skip_Bits= 1;
    if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp, 37, RFIDlerConfig.Sync, RFIDlerConfig.SyncBits, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY) == 37)
    {
        // check sync bits
        if (memcmp(tmp, Hitag2Sync, 5) != 0)
            return FALSE;
        binarraytohex(response, tmp + 5, 32);

        // decrypt
        if(CryptoActive)
            return hitag2_hex_crypt(response, response);

        return TRUE;
    }
    return FALSE;
}
Пример #6
0
BOOL hitag2_write_page(BYTE block, BYTE *data)
{
    BYTE command[11], tmp[37], tmp1[37], tmp2[37], tmphex[9];

    if(block > HITAG2_DATABLOCKS - 1)
        return FALSE;

    // create 10 bit command block: HITAG2_WRIE_PAGE + 3 bits address + invert(HITAG2_WRITE_PAGE + 3 bits address)
    memcpy(command, HITAG2_WRITE_PAGE, 2);
    inttobinstring(command + 2, (unsigned int) block, 3);
    invertbinstring(command + 5, command);
    command[10]= '\0';

    // encrypt command if in crypto mode
    if(CryptoActive)
        hitag2_binstring_crypt(tmp, command);
    else
        memcpy(tmp, command, 11);

    // convert data to binstring for send
    if(hextobinstring(tmp1, data) != 32)
        return FALSE;

    // send command with RX->TX delay and no reset
    if(!rwd_send(tmp, strlen(tmp), NO_RESET, BLOCK, RWD_STATE_WAKING, RFIDlerConfig.FrameClock, 0, RFIDlerConfig.RWD_Wait_Switch_RX_TX, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX))
        return FALSE;

    // skip 1/2 bit to synchronise manchester
    HW_Skip_Bits= 1;
    // get ACK - 10 bytes + sync
    if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp2, 15, RFIDlerConfig.Sync, RFIDlerConfig.SyncBits, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY) == 15)
    {
        // check sync bits
        if (memcmp(tmp2, Hitag2Sync, 5) != 0)
            return FALSE;

        // decrypt
        if(CryptoActive)
            hitag2_binarray_crypt(tmp2 + 5, tmp2 + 5, 10);

        // check ACK - should be our original command echo'd back
        binarraytobinstring(tmp2 + 5, tmp2 + 5, 10);
        if(memcmp(command, tmp2 + 5, 10) != 0)
            return FALSE;
    }

    // encrypt data if in crypto mode
    if(CryptoActive)
        hitag2_binstring_crypt(tmp1, tmp1);

    // send data with RX->TX delay and no reset
    if(!rwd_send(tmp1, strlen(tmp1), NO_RESET, BLOCK, RWD_STATE_WAKING, RFIDlerConfig.FrameClock, 0, RFIDlerConfig.RWD_Wait_Switch_RX_TX, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX))
        return FALSE;

    // no ack, so read back and verify
    // delay for long enough to allow write plus RX->TX period
    Delay_us((HITAG2_WRITE_DELAY * RFIDlerConfig.FrameClock + RFIDlerConfig.RWD_Wait_Switch_RX_TX * RFIDlerConfig.FrameClock) / 100);
    if(!hitag2_read_page(tmp, block))
        return FALSE;
    if(memcmp(tmp, data, 8) != 0)
        return FALSE;

    return TRUE;
}