RFID циклы, аутентификация, чтение из памяти

RockHammer
Offline
Зарегистрирован: 21.08.2017

Взял код из примеров библиотеки, немного "допилил" до того, что мне нужно.. Видимо, не смог допилить. Функция не работает.

По порядку:

Сам код из примера расчитан на один проход, тоесть ты задаешь номер блока, который хочешь прочесть и он его читает, я хотел прочесть все блоки по порядку с 0 по 63, в цикле, разумеется. Но что-то пошло не так.

В конце кода, где цикл for(byte i = 0; i < 64; i++) я говорю, что хочу прочитать все блоки по порядку. 

Проблема в том, что код выполняется один раз, читая только нулевой блок и дальше оно выполняться не хочет, хотя были два прецендента, когда он читал после 0 сразу 32 блок, с задержкой.

Как это исправить? В чем проблема?

P.s. да, я знаю, что метод немного извращенский для дампа карты, но мне почему-то приглянулся имено этот исходник. Буду рад вашему ответу.

#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN         9           // Configurable, see typical pin layout above
#define SS_PIN          10          // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

// Number of known default keys (hard-coded)
// NOTE: Synchronize the NR_KNOWN_KEYS define with the defaultKeys[] array
#define NR_KNOWN_KEYS   25
// Known keys, see: https://code.google.com/p/mfcuk/wiki/MifareClassicDefaultKeys
byte knownKeys[NR_KNOWN_KEYS][MFRC522::MF_KEY_SIZE] =  {
    {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // FF FF FF FF FF FF = factory default
    {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5}, // A0 A1 A2 A3 A4 A5 0 sector
    {0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5}, // B0 B1 B2 B3 B4 B5
    {0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd}, // 4D 3A 99 C3 51 DD
    {0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a}, // 1A 98 2C 7E 45 9A
    {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}, // D3 F7 D3 F7 D3 F7
    {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, // AA BB CC DD EE FF
    {0x86, 0xFD, 0x65, 0x1B, 0x5E, 0x98}, // 86 FD 65 1B 5E 98
    {0x78, 0x6D, 0x80, 0xC7, 0xB8, 0x32}, // 78 6D 80 C7 B8 32 8 sector
    {0x78, 0x6D, 0x80, 0xC7, 0xB8, 0x32}  // B1 F1 94 BF B1 D4 1 sector
    
};

/*
 * Initialize.
 */
void setup() {
    Serial.begin(9600);         // Initialize serial communications with the PC
    while (!Serial);            // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
    SPI.begin();                // Init SPI bus
    mfrc522.PCD_Init();         // Init MFRC522 card
    Serial.println(F("Try the most used default keys to print block 0 of a MIFARE PICC."));
}

/*
 * Helper routine to dump a byte array as hex values to Serial.
 */
void dump_byte_array(byte *buffer, byte bufferSize) {
    for (byte i = 0; i < bufferSize; i++) {
        Serial.print(buffer[i] < 0x10 ? " 0" : " ");
        Serial.print(buffer[i], HEX);
    }
}

/*
 * Try using the PICC (the tag/card) with the given key to access block 0.
 * On success, it will show the key details, and dump the block data on Serial.
 *
 * @return true when the given key worked, false otherwise.
 */
boolean try_key(MFRC522::MIFARE_Key *key, byte block)
{
    boolean result = false;
    byte buffer[18];
    MFRC522::StatusCode status;
    
    // http://arduino.stackexchange.com/a/14316
    if ( ! mfrc522.PICC_IsNewCardPresent())
        return false;
    if ( ! mfrc522.PICC_ReadCardSerial())
        return false;
    // Serial.println(F("Authenticating using key A..."));
    status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, key, &(mfrc522.uid));
    if (status != MFRC522::STATUS_OK) {
        // Serial.print(F("PCD_Authenticate() failed: "));
        // Serial.println(mfrc522.GetStatusCodeName(status));
        Serial.println("аутентификэйшон не окай");
        return false;
    }
    
        // Read block
        byte byteCount = sizeof(buffer);
        status = mfrc522.MIFARE_Read(block, buffer, &byteCount);
        if (status != MFRC522::STATUS_OK) {
             //Serial.print(F("MIFARE_Read() failed: "));
             //Serial.println(mfrc522.GetStatusCodeName(status));
        }
        else {
            // Successful read
            result = true;
            Serial.print(F("Success with key:"));
            dump_byte_array((*key).keyByte, MFRC522::MF_KEY_SIZE);
            Serial.println();
            // Dump block data
            Serial.print(F("Block ")); Serial.print(block); Serial.print(F(":"));
            dump_byte_array(buffer, 16);
            Serial.println();
        } 
    
    Serial.println();
       //mfrc522.PICC_HaltA();       // Halt PICC
       //mfrc522.PCD_StopCrypto1();  // Stop encryption on PCD
    buffer[18] = NULL;
    return result;
}

/*
 * Main loop.
 */
void loop() {
    // Look for new cards
    if ( ! mfrc522.PICC_IsNewCardPresent())
        return;

    // Select one of the cards
    if ( ! mfrc522.PICC_ReadCardSerial())
        return;
    Serial.println("next itteration"); //костыль, чтоб понять на каком пункте ошибка
    // Show some details of the PICC (that is: the tag/card)
    Serial.print(F("Card UID:"));
    dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
    Serial.println();
    //Serial.print(F("PICC type: "));
    MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
    //Serial.println(mfrc522.PICC_GetTypeName(piccType));
    
    // Try the known default keys
    MFRC522::MIFARE_Key key;
    
        // Try the key
              for (byte i = 0; i < 64; i++){
                   for (byte k = 0; k < NR_KNOWN_KEYS; k++) {
                   // Copy the known key into the MIFARE_Key structure
                   for (byte m = 0; m < MFRC522::MF_KEY_SIZE; m++) {
                   key.keyByte[m] = knownKeys[k][m];
              }
            if (try_key(&key, i)) {
                // Found and reported on the key and block,
                // no need to try other keys for this PICC
                Serial.println("inside FOR"); //костыль, чтоб понять на каком пункте ошибка
                key.keyByte[6] = NULL; //здесь я предположил, будто он не читает, т.к.ключ для аутентификации не заполняется снова, поэтому почистил переменную с ним после иттерации.
            }
        }
        
    }
}

 

То, что выходит в порт:

b707
Offline
Зарегистрирован: 26.05.2017

Кто же так диагностику добавляет? Что вам дает ваш вывод "Inside for", который, во-первых, неверно расположен, а во-вторых, не содержит никакой информации? Поместите этот вывод на пару строк выше - до строки 130 - чтобы он был снаружи условия if(try_key()) и добавьте в вывод номер читаемого блока i

Раскомментируйте диагностику ошибок в строках 78 и 79 - ведь вам надо понять, почему не читаются блоки! - а у вас в этом месте в случае ошибки чтения программа просто "молчит".

 

RockHammer
Offline
Зарегистрирован: 21.08.2017

b707 пишет:

Кто же так диагностику добавляет? Что вам дает ваш вывод "Inside for", который, во-первых, неверно расположен, а во-вторых, не содержит никакой информации? Поместите этот вывод на пару строк выше - до строки 130 - чтобы он был снаружи условия if(try_key()) и добавьте в вывод номер читаемого блока i

Раскомментируйте диагностику ошибок в строках 78 и 79 - ведь вам надо понять, почему не читаются блоки! - а у вас в этом месте в случае ошибки чтения программа просто "молчит".

раскоментировал, никаких ошибок он не выдавал, хотя если немного изменить код (я уже не помню как) то он пишет Error in communication, чтобы это не значило.

Ведь странно, почему он ничего не пишет, хотя строки раскоментированы? помоему здесь ошибка в самой функции try_key. 

Ещё, как один из вариантов - ключи с каждой новой иттерацией постоянно копируются в структуру Mifare Key, может поэтому он дико тормозит? Я добавил кое что в код, в последние строки:

for (byte i = 0; i < 64; i++){
                   for (byte k = 0; k < NR_KNOWN_KEYS; k++) {
                    Serial.println("копируем ключи"); //чтобы знать сколько раз он их копирует
                   // Copy the known key into the MIFARE_Key structure
                   for (byte m = 0; m < MFRC522::MF_KEY_SIZE; m++) {
                   key.keyByte[m] = knownKeys[k][m];}
            if (try_key(&key, i)) {
                // Found and reported on the key and block,
                // no need to try other keys for this PICC
                
                Serial.println("прочли"); //здесь выводится сообщение, если чтение успешно
            } else {Serial.println("не прочли");} //добавил ветвь else, просто для информации в выводе
        
                   }
                   
    }
}

так вот, после этих изменений вот что прозошло:

Try the most used default keys to print block 0 of a MIFARE PICC.
next itteration
Card UID: DC 7D 27 1B
копируем ключи
не прочли
копируем ключи
Success with key: A0 A1 A2 A3 A4 A5
Block 0: DC 7D 27 1B 9D 08 04 00 01 E4 8E E9 E3 D5 29 1D

прочли
копируем ключи
не прочли
копируем ключи
не прочли
копируем ключи
не прочли

дальше он продолжает повторять эти две строки: копируем ключи и не прочли, даже если убрать карту.

может быть в этом ошибка? Куда можно переместить это цикл по вводу ключей, чтобы не нарушить работа кода.

Я вынес цикл по вводу ключей "за скобки", т.е. за цикл, вкотором крутиться try_key и вот что получилось:

он выводит юайди и прочее, затем 64 раза мне выдает аутентификейшен эррор: эррор ин комьюникейшен и дальше новая иттерация loop. Я думаю, проблема как раз в ключах и в самой функции try_key. 

Я могу ошибаться, конечно же. Как это лучше исправить? Вынос цикла с ключами за скобки не помог.