flipperdevices / flipperzero-firmware

Flipper Zero firmware source code
https://flipperzero.one
GNU General Public License v3.0
12.91k stars 2.74k forks source link

Problem writing Electra RFID tags (but not others) #3997

Open eblis opened 5 days ago

eblis commented 5 days ago

Describe the bug.

I have issues when trying to write an Electra tag to a T5577 tag. Flipper is stuck in trying to write tag. If I try to read back the tag the hex value is correctly written but the epilogue is stuck at 00000...

I added some comments to #1500 but there was no answer and that issue is not specific to Electra so I thought I should open a new one.

Trying to debug the issue a bit I see that Flipper is trying to send the epilogue to the T5577 tag, but when it reads back the epilogue is all 0s for some reason.

Reproduction

  1. Get hold of an Electra tag ID, either generate one or read an existing one (I read an existing one).
  2. Try to write to an unprotected (no password) T5577 tag.
  3. Flipper is stuck in "trying to write" mode and doesn't finish successfully.

Target

No response

Logs

No response

Anything else?

I've tried to debug the writing process but couldn't get it to work so I resorted to print debugging it to try and find out some things.

After playing around with the logs I found out the following: I added some logs to the encoder_start function:

bool protocol_electra_encoder_start(ProtocolElectra* proto) {
    // header
    proto->encoded_base_data = 0b111111111;

    // data
    for(uint8_t i = 0; i < ELECTRA_DECODED_BASE_DATA_SIZE; i++) {
        em_write_nibble(false, proto->data[i], &proto->encoded_base_data);
        em_write_nibble(true, proto->data[i], &proto->encoded_base_data);
    }

    for(int x = 0; x < 8; x++) {
        FURI_LOG_I(TAG, "Protocol data[%d] = %x", x, proto->data[x]);
    }

    // column parity and stop bit
    uint8_t parity_sum;

    for(uint8_t c = 0; c < EM_COLUMN_COUNT; c++) {
        parity_sum = 0;
        for(uint8_t i = 1; i <= EM_ROW_COUNT; i++) {
            uint8_t parity_bit = (proto->encoded_base_data >> (i * EM_BITS_PER_ROW_COUNT - 1)) & 1;
            parity_sum += parity_bit;
        }
        proto->encoded_base_data = (proto->encoded_base_data << 1) | ((parity_sum % 2) & 1);
    }

    // stop bit
    proto->encoded_base_data = (proto->encoded_base_data << 1) | 0;

    proto->encoded_data_index = 0;
    proto->encoded_polarity = true;

    // epilogue
    proto->encoded_epilogue = (proto->data[ELECTRA_DECODED_DATA_EPILOGUE_START_POS]);
    proto->encoded_epilogue <<= 8;
    proto->encoded_epilogue |= (proto->data[ELECTRA_DECODED_DATA_EPILOGUE_START_POS + 1]);

    FURI_LOG_I(TAG, "Initial encoded epilogue %llx", proto->encoded_epilogue);

    //fill bytes 2-7 by epilogue filler
    for(uint8_t i = 2; i < ELECTRA_ENCODED_EPILOGUE_SIZE; i++) {
        proto->encoded_epilogue <<= 8;
        proto->encoded_epilogue |= proto->data[ELECTRA_DECODED_DATA_EPILOGUE_START_POS + 2];
    }

    FURI_LOG_I(TAG, "Base data %llx", proto->encoded_base_data);
    FURI_LOG_I(TAG, "Encoded epilogue %llx", proto->encoded_epilogue);

    return true;
}

The logs show the following:

32946 [I][ELECTRA] Protocol data[0] = 3
32948 [I][ELECTRA] Protocol data[1] = e8
32950 [I][ELECTRA] Protocol data[2] = 89
32952 [I][ELECTRA] Protocol data[3] = 48
32955 [I][ELECTRA] Protocol data[4] = fc
32957 [I][ELECTRA] Protocol data[5] = 7e
32959 [I][ELECTRA] Protocol data[6] = 1e
32962 [I][ELECTRA] Protocol data[7] = 0
32964 [I][ELECTRA] Initial encoded epilogue 7e1e
32967 [I][ELECTRA] Base data ff80dd8c6498fb16
32969 [I][ELECTRA] Encoded epilogue 7e1e000000000000

So the tag and epilogue was correctly determined.

I also added some logs to the electra_decode function

static void electra_decode(
    const uint8_t* encoded_base_data,
    const uint8_t encoded_base_data_size,
    const uint8_t* encoded_epilogue,
    const uint8_t encoded_epilogue_size,
    uint8_t* decoded_data,
    const uint8_t decoded_data_size) {
    furi_check(decoded_data_size >= ELECTRA_DECODED_DATA_SIZE);
    furi_check(encoded_base_data_size >= ELECTRA_ENCODED_BASE_DATA_SIZE);
    furi_check(encoded_epilogue_size >= ELECTRA_ENCODED_EPILOGUE_SIZE);

    for(int x = 0; x < encoded_epilogue_size; x++) {
        FURI_LOG_D(TAG, "Epilogue[%d] = %08x", x, encoded_epilogue[x]);
    }

    uint8_t decoded_data_index = 0;
    ElectraDecodedData base_data = *((ElectraDecodedData*)(encoded_base_data));
    // ElectraDecodedData epilogue = *((ElectraDecodedData*)(encoded_epilogue));

    FURI_LOG_T(TAG, "Decoded data size %d", decoded_data_size);
    // clean result
    memset(decoded_data, 0, decoded_data_size);

    // header
    for(uint8_t i = 0; i < 9; i++) {
        base_data = base_data << 1;
    }

    // nibbles
    uint8_t value = 0;
    for(uint8_t r = 0; r < EM_ROW_COUNT; r++) {
        uint8_t nibble = 0;
        for(uint8_t i = 0; i < 5; i++) {
            if(i < 4) nibble = (nibble << 1) | (base_data & (1LLU << 63) ? 1 : 0);
            base_data = base_data << 1;
        }
        value = (value << 4) | nibble;
        if(r % 2) {
            decoded_data[decoded_data_index] |= value;
            decoded_data_index++;
            value = 0;
        }
    }
    for(int x = 0; x < decoded_data_size; x++) {
        FURI_LOG_I(TAG, "Initial data[%d] = %08x", x, decoded_data[x]);
    }

    // copy first 3 bytes of encoded epilogue to decoded data
    FURI_LOG_D(
        TAG,
        "ELECTRA_ENCODED_EPILOGUE_SIZE %d VS encoded_epilogue_size %d",
        ELECTRA_ENCODED_EPILOGUE_SIZE,
        encoded_epilogue_size);
    decoded_data[ELECTRA_DECODED_DATA_EPILOGUE_START_POS] =
        encoded_epilogue[encoded_epilogue_size - 1];
    decoded_data[ELECTRA_DECODED_DATA_EPILOGUE_START_POS + 1] =
        encoded_epilogue[encoded_epilogue_size - 2];
    decoded_data[ELECTRA_DECODED_DATA_EPILOGUE_START_POS + 2] =
        encoded_epilogue[encoded_epilogue_size - 3];

    for(int x = 0; x < decoded_data_size; x++) {
        FURI_LOG_W(TAG, "Final Data[%d] = %08x", x, decoded_data[x]);
    }
}

This is the log

32972 [D][ELECTRA] Epilogue[0] = 00000000
32974 [D][ELECTRA] Epilogue[1] = 00000000
32977 [D][ELECTRA] Epilogue[2] = 00000000
32979 [D][ELECTRA] Epilogue[3] = 00000000
32981 [D][ELECTRA] Epilogue[4] = 00000000
32984 [D][ELECTRA] Epilogue[5] = 00000000
32986 [D][ELECTRA] Epilogue[6] = 0000001e
32988 [D][ELECTRA] Epilogue[7] = 0000007e
32991 [T][ELECTRA] Decoded data size 8
32993 [I][ELECTRA] Initial data[0] = 00000003
32995 [I][ELECTRA] Initial data[1] = 000000e8
32998 [I][ELECTRA] Initial data[2] = 00000089
33000 [I][ELECTRA] Initial data[3] = 00000048
33003 [I][ELECTRA] Initial data[4] = 000000fc
33005 [I][ELECTRA] Initial data[5] = 00000000
33008 [I][ELECTRA] Initial data[6] = 00000000
33011 [I][ELECTRA] Initial data[7] = 00000000
33013 [D][ELECTRA] ELECTRA_ENCODED_EPILOGUE_SIZE 8 VS encoded_epilogue_size 8
33017 [W][ELECTRA] Final Data[0] = 00000003
33019 [W][ELECTRA] Final Data[1] = 000000e8
33022 [W][ELECTRA] Final Data[2] = 00000089
33024 [W][ELECTRA] Final Data[3] = 00000048
33027 [W][ELECTRA] Final Data[4] = 000000fc
33029 [W][ELECTRA] Final Data[5] = 0000007e
33032 [W][ELECTRA] Final Data[6] = 0000001e
33034 [W][ELECTRA] Final Data[7] = 00000000

Then after a while it writes the T5577 blocks, as such:

33115 [D][LfRfidWorker] Data write
33117 [D][T5577] About to write 5 blocks
33117 [D][T5577] Writing data block 148080
33117 [D][T5577] Writing data block ff80dd8c
33117 [D][T5577] Writing data block 6498fb16
33117 [D][T5577] Writing data block 7e1e0000
33117 [D][T5577] Writing data block 0
33117 [D][T5577] Finished writing 5 blocks

One question here, shouldn't block 4 (the epilogue) use the same Manchester encoding as the first 3 blocks ?

Then flipper I assume reads what was written and it reads everything, except the epilogue, which remains 00 00 00 ...

33118 [D][LfRfidWorker] Start ASK
33580 [D][LfRfidWorker] Read started
34646 [E][ELECTRA] Parity bit is wrong
34648 [E][ELECTRA] Parity bit is wrong
34650 [E][ELECTRA] Parity bit is wrong
34654 [E][ELECTRA] Parity bit is wrong
34657 [E][ELECTRA] Parity bit is wrong
34659 [E][ELECTRA] Parity bit is wrong
34661 [E][ELECTRA] Parity bit is wrong
34664 [E][ELECTRA] Parity bit is wrong
34667 [D][ELECTRA] Epilogue[0] = 00000000
34669 [D][ELECTRA] Epilogue[1] = 00000000
34671 [D][ELECTRA] Epilogue[2] = 00000000
34673 [D][ELECTRA] Epilogue[3] = 00000000
34676 [D][ELECTRA] Epilogue[4] = 00000000
34678 [D][ELECTRA] Epilogue[5] = 00000000
34681 [D][ELECTRA] Epilogue[6] = 00000000
34683 [D][ELECTRA] Epilogue[7] = 00000000
34685 [T][ELECTRA] Decoded data size 8
34687 [I][ELECTRA] Initial data[0] = 00000003
34690 [I][ELECTRA] Initial data[1] = 000000e8
34692 [I][ELECTRA] Initial data[2] = 00000089
34695 [I][ELECTRA] Initial data[3] = 00000048
34697 [I][ELECTRA] Initial data[4] = 000000fc
34700 [I][ELECTRA] Initial data[5] = 00000000
34703 [I][ELECTRA] Initial data[6] = 00000000
34705 [I][ELECTRA] Initial data[7] = 00000000
34708 [D][ELECTRA] ELECTRA_ENCODED_EPILOGUE_SIZE 8 VS encoded_epilogue_size 8
34711 [W][ELECTRA] Final Data[0] = 00000003
34714 [W][ELECTRA] Final Data[1] = 000000e8
34716 [W][ELECTRA] Final Data[2] = 00000089
34719 [W][ELECTRA] Final Data[3] = 00000048
34721 [W][ELECTRA] Final Data[4] = 000000fc
34724 [W][ELECTRA] Final Data[5] = 00000000
34726 [W][ELECTRA] Final Data[6] = 00000000
34729 [W][ELECTRA] Final Data[7] = 00000000
eblis commented 5 days ago

From what I can tell @Leptopt1los added the code for Electra protocol, maybe you have some ideas. I don't have a WiFi board which, from what I understand, makes debugging the code a lot harder so I resorted to print debugging various parts of the code.

These are the T5577 tags I bought. I understand that someone recommended some other tags from eMag in another issue but @itrack - who seems to have the same issue as me - tried those tags as well without success either.

itrack commented 4 days ago

@eblis I tested these tags from eMAG, same problem, these don't work