classic_gen1.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #include "classic_gen1.h"
  2. #include <furi_hal_nfc.h>
  3. #define TAG "Magic"
  4. #define MAGIC_CMD_WUPA (0x40)
  5. #define MAGIC_CMD_ACCESS (0x43)
  6. #define MAGIC_MIFARE_READ_CMD (0x30)
  7. #define MAGIC_MIFARE_WRITE_CMD (0xA0)
  8. #define MAGIC_ACK (0x0A)
  9. #define MAGIC_BUFFER_SIZE (32)
  10. bool magic_gen1_wupa() {
  11. bool magic_activated = false;
  12. uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
  13. uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
  14. uint16_t rx_len = 0;
  15. FuriHalNfcReturn ret = 0;
  16. do {
  17. // Start communication
  18. tx_data[0] = MAGIC_CMD_WUPA;
  19. ret = furi_hal_nfc_ll_txrx_bits(
  20. tx_data,
  21. 7,
  22. rx_data,
  23. sizeof(rx_data),
  24. &rx_len,
  25. FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON |
  26. FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
  27. furi_hal_nfc_ll_ms2fc(20));
  28. if(ret != FuriHalNfcReturnIncompleteByte) break;
  29. if(rx_len != 4) break;
  30. if(rx_data[0] != MAGIC_ACK) break;
  31. magic_activated = true;
  32. } while(false);
  33. return magic_activated;
  34. }
  35. bool magic_gen1_data_access_cmd() {
  36. bool write_cmd_success = false;
  37. uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
  38. uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
  39. uint16_t rx_len = 0;
  40. FuriHalNfcReturn ret = 0;
  41. do {
  42. tx_data[0] = MAGIC_CMD_ACCESS;
  43. ret = furi_hal_nfc_ll_txrx_bits(
  44. tx_data,
  45. 8,
  46. rx_data,
  47. sizeof(rx_data),
  48. &rx_len,
  49. FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON |
  50. FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
  51. furi_hal_nfc_ll_ms2fc(20));
  52. if(ret != FuriHalNfcReturnIncompleteByte) break;
  53. if(rx_len != 4) break;
  54. if(rx_data[0] != MAGIC_ACK) break;
  55. write_cmd_success = true;
  56. } while(false);
  57. return write_cmd_success;
  58. }
  59. bool magic_gen1_read_block(uint8_t block_num, MfClassicBlock* data) {
  60. furi_assert(data);
  61. bool read_success = false;
  62. uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
  63. uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
  64. uint16_t rx_len = 0;
  65. FuriHalNfcReturn ret = 0;
  66. do {
  67. tx_data[0] = MAGIC_MIFARE_READ_CMD;
  68. tx_data[1] = block_num;
  69. ret = furi_hal_nfc_ll_txrx_bits(
  70. tx_data,
  71. 2 * 8,
  72. rx_data,
  73. sizeof(rx_data),
  74. &rx_len,
  75. FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON,
  76. furi_hal_nfc_ll_ms2fc(20));
  77. if(ret != FuriHalNfcReturnOk) break;
  78. if(rx_len != 16 * 8) break;
  79. memcpy(data->value, rx_data, sizeof(data->value));
  80. read_success = true;
  81. } while(false);
  82. return read_success;
  83. }
  84. bool magic_gen1_write_blk(uint8_t block_num, MfClassicBlock* data) {
  85. furi_assert(data);
  86. bool write_success = false;
  87. uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
  88. uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
  89. uint16_t rx_len = 0;
  90. FuriHalNfcReturn ret = 0;
  91. do {
  92. tx_data[0] = MAGIC_MIFARE_WRITE_CMD;
  93. tx_data[1] = block_num;
  94. ret = furi_hal_nfc_ll_txrx_bits(
  95. tx_data,
  96. 2 * 8,
  97. rx_data,
  98. sizeof(rx_data),
  99. &rx_len,
  100. FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
  101. furi_hal_nfc_ll_ms2fc(20));
  102. if(ret != FuriHalNfcReturnIncompleteByte) break;
  103. if(rx_len != 4) break;
  104. if(rx_data[0] != MAGIC_ACK) break;
  105. memcpy(tx_data, data->value, sizeof(data->value));
  106. ret = furi_hal_nfc_ll_txrx_bits(
  107. tx_data,
  108. 16 * 8,
  109. rx_data,
  110. sizeof(rx_data),
  111. &rx_len,
  112. FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
  113. furi_hal_nfc_ll_ms2fc(20));
  114. if(ret != FuriHalNfcReturnIncompleteByte) break;
  115. if(rx_len != 4) break;
  116. if(rx_data[0] != MAGIC_ACK) break;
  117. write_success = true;
  118. } while(false);
  119. return write_success;
  120. }