RC522 и Проездные Метро

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Долго волялся у меня RC522, но вот недвно был в москве - и после проезда на метро остались проездные с надписью "Единый". После загрузки примера(Dump) из библиотеки https://github.com/miguelbalboa/rfid - карта определилась как Mifare Ultralight. Дамп карточки показал что 15 страниц по 4 байта - из которых не заблокированны страницы 8...15 - тоесть локбайт 2(отвечающий за эти страницы) = 0х00 - это значит что их можно и писать и читать.

Единственная особенность работы с картами - для каждой команды записи нужно выполнить поиск крты:

        if ( ! mfrc522.PICC_IsNewCardPresent()) {
		return;
	}

	// Select one of the cards
	if ( ! mfrc522.PICC_ReadCardSerial()) {
		return;
	}
        byte buf[] = {0x00, 0x00, 0x00, 0x00};
        //Запись на карту на страницу 8 - 4 байта 0х00 и вывод результата в текстовом виде 
        Serial.println(mfrc522.GetStatusCodeName(mfrc522.MIFARE_Ultralight_Write(8, buf, 4))); 

 

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

P.S. Почему то модуль копризничал и заработал только на одной из плат - пробовал и Leonardo и две Mega2560 - только на одной заработал, хотя обе платы рабочие - запитывал от 5 вольт и от 3.3 - не сдох, но и не работал, но некоторые карточки читались только когда подцепил на 5 вольт - мощьности им чтоли нехватало...

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

жаль только читать умеет

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

У меня и записать получилось :P - о чем я и написал выше.

Поеду в москву надо будеть набрать побольше - пригодятся. 32байта в каждом доступно на запись...

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

прикольно что пишется

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Вот дамп билета № 2158620281

Card UID: 34 24 87 09 FC DC 56
PICC type: MIFARE Ultralight or Ultralight C
Page  0  1  2  3
  0   34 24 87 1F
  1   09 FC DC 56
  2   7F 0B F0 00
  3   FF FF FF FC
  4   45 D9 B8 0A
  5   9E E7 9D 00
  6   20 15 00 00
  7   20 15 00 00
  8   20 11 05 00
  9   40 00 30 73
 10   80 32 59 84
 11   20 11 29 C8
 12   20 11 05 00
 13   40 00 30 73
 14   80 32 59 84
 15   20 11 29 C8
 

как известно байты 3 и 4 страницы 2 (F0 00) отвечают за блокировку - это значит что 4,5,6,7 страницы не доступны для записи.

Из статьи журнала Хакер мы находим номер билета, который на нем напечатан

0x80A9EE79 = 2158620281

Теперь осталось найти как правильно его получить. При чтении карты будут получены данные с 4...7 страниц (по 4 страницы за раз )

	byte byteCount;
	byte buffer[18];
	byteCount = sizeof(buffer);
	status = mfrc522.MIFARE_Read(4, buffer, &byteCount);
	if (status != mfrc522.STATUS_OK) {
		Serial.print("MIFARE_Read() failed: ");
		Serial.println(mfrc522.GetStatusCodeName(status));
	}

 тоесть 45 D9 B8 0A 9E E7 9D 00 20 15 00 00 20 15 00 00 будет в буфере чтения.

вот эти байты (B8 0A 9E E7 9D) нужно преобразовать в число и выполнить операцию сдвига вправо на 4бита и XOR c 0B 00 00 00 00

Как это правильно реализовать на языке C применительно к Arduino.

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

http://www.youtube.com/watch?v=z6-q_BS9LmQ

там похоже все преобразования сделаны

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Посмотрел. Черезжопу сделано - можно лучше...

unsigned long GetTicket(byte * buffer){
  unsigned long ticket;
  ticket = (byte)buffer[2]<<4;
  ticket = (ticket << 4)|buffer[3];
  ticket = (ticket << 8)|buffer[4];
  ticket = (ticket << 8)|buffer[5];
  ticket = (ticket << 4)|(buffer[6]>>4);
  return ticket;
}

Но мне все равно не нравится.

junior_developer
Offline
Зарегистрирован: 27.11.2017

NeiroN пишет:
Единственная особенность работы с картами - для каждой команды записи нужно выполнить поиск крты:

        if ( ! mfrc522.PICC_IsNewCardPresent()) {
		return;
	}

	// Select one of the cards
	if ( ! mfrc522.PICC_ReadCardSerial()) {
		return;
	}
        byte buf[] = {0x00, 0x00, 0x00, 0x00};
        //Запись на карту на страницу 8 - 4 байта 0х00 и вывод результата в текстовом виде 
        Serial.println(mfrc522.GetStatusCodeName(mfrc522.MIFARE_Ultralight_Write(8, buf, 4))); 

Переменная buf - массив  значений? А если поместить в неё не 4 байта, а 20? Можно ли записать все их одной командой так:

byte buf[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,};
	
mfrc522.MIFARE_Ultralight_Write(8, buf, 20); // записать их вот так???
Байты сами распределятся по страницам 8, 9, 10, 11? Или нужно каждый раз указывать страницу для записи?
Подскажите пожалуйста, кто знает!