magic.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #include "magic.h"
  2. #include <furi_hal_nfc.h>
  3. #define TAG "Magic"
  4. #define MAGIC_CMD_WUPA (0x40)
  5. #define MAGIC_CMD_WIPE (0x41)
  6. #define MAGIC_CMD_READ (0x43)
  7. #define MAGIC_CMD_WRITE (0x43)
  8. #define MAGIC_MIFARE_READ_CMD (0x30)
  9. #define MAGIC_MIFARE_WRITE_CMD (0xA0)
  10. #define MAGIC_ACK (0x0A)
  11. #define MAGIC_BUFFER_SIZE (32)
  12. bool magic_wupa() {
  13. bool magic_activated = false;
  14. uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
  15. uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
  16. uint16_t rx_len = 0;
  17. FuriHalNfcReturn ret = 0;
  18. do {
  19. // Setup nfc poller
  20. furi_hal_nfc_exit_sleep();
  21. furi_hal_nfc_ll_txrx_on();
  22. furi_hal_nfc_ll_poll();
  23. ret = furi_hal_nfc_ll_set_mode(
  24. FuriHalNfcModePollNfca, FuriHalNfcBitrate106, FuriHalNfcBitrate106);
  25. if(ret != FuriHalNfcReturnOk) break;
  26. furi_hal_nfc_ll_set_fdt_listen(FURI_HAL_NFC_LL_FDT_LISTEN_NFCA_POLLER);
  27. furi_hal_nfc_ll_set_fdt_poll(FURI_HAL_NFC_LL_FDT_POLL_NFCA_POLLER);
  28. furi_hal_nfc_ll_set_error_handling(FuriHalNfcErrorHandlingNfc);
  29. furi_hal_nfc_ll_set_guard_time(FURI_HAL_NFC_LL_GT_NFCA);
  30. // Start communication
  31. tx_data[0] = MAGIC_CMD_WUPA;
  32. ret = furi_hal_nfc_ll_txrx_bits(
  33. tx_data,
  34. 7,
  35. rx_data,
  36. sizeof(rx_data),
  37. &rx_len,
  38. FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON |
  39. FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
  40. furi_hal_nfc_ll_ms2fc(20));
  41. if(ret != FuriHalNfcReturnIncompleteByte) break;
  42. if(rx_len != 4) break;
  43. if(rx_data[0] != MAGIC_ACK) break;
  44. magic_activated = true;
  45. } while(false);
  46. if(!magic_activated) {
  47. furi_hal_nfc_ll_txrx_off();
  48. furi_hal_nfc_start_sleep();
  49. }
  50. return magic_activated;
  51. }
  52. bool magic_data_access_cmd() {
  53. bool write_cmd_success = false;
  54. uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
  55. uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
  56. uint16_t rx_len = 0;
  57. FuriHalNfcReturn ret = 0;
  58. do {
  59. tx_data[0] = MAGIC_CMD_WRITE;
  60. ret = furi_hal_nfc_ll_txrx_bits(
  61. tx_data,
  62. 8,
  63. rx_data,
  64. sizeof(rx_data),
  65. &rx_len,
  66. FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON |
  67. FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
  68. furi_hal_nfc_ll_ms2fc(20));
  69. if(ret != FuriHalNfcReturnIncompleteByte) break;
  70. if(rx_len != 4) break;
  71. if(rx_data[0] != MAGIC_ACK) break;
  72. write_cmd_success = true;
  73. } while(false);
  74. if(!write_cmd_success) {
  75. furi_hal_nfc_ll_txrx_off();
  76. furi_hal_nfc_start_sleep();
  77. }
  78. return write_cmd_success;
  79. }
  80. bool magic_read_block(uint8_t block_num, MfClassicBlock* data) {
  81. furi_assert(data);
  82. bool read_success = false;
  83. uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
  84. uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
  85. uint16_t rx_len = 0;
  86. FuriHalNfcReturn ret = 0;
  87. do {
  88. tx_data[0] = MAGIC_MIFARE_READ_CMD;
  89. tx_data[1] = block_num;
  90. ret = furi_hal_nfc_ll_txrx_bits(
  91. tx_data,
  92. 2 * 8,
  93. rx_data,
  94. sizeof(rx_data),
  95. &rx_len,
  96. FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON,
  97. furi_hal_nfc_ll_ms2fc(20));
  98. if(ret != FuriHalNfcReturnOk) break;
  99. if(rx_len != 16 * 8) break;
  100. memcpy(data->value, rx_data, sizeof(data->value));
  101. read_success = true;
  102. } while(false);
  103. if(!read_success) {
  104. furi_hal_nfc_ll_txrx_off();
  105. furi_hal_nfc_start_sleep();
  106. }
  107. return read_success;
  108. }
  109. bool magic_write_blk(uint8_t block_num, MfClassicBlock* data) {
  110. furi_assert(data);
  111. bool write_success = false;
  112. uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
  113. uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
  114. uint16_t rx_len = 0;
  115. FuriHalNfcReturn ret = 0;
  116. do {
  117. tx_data[0] = MAGIC_MIFARE_WRITE_CMD;
  118. tx_data[1] = block_num;
  119. ret = furi_hal_nfc_ll_txrx_bits(
  120. tx_data,
  121. 2 * 8,
  122. rx_data,
  123. sizeof(rx_data),
  124. &rx_len,
  125. FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
  126. furi_hal_nfc_ll_ms2fc(20));
  127. if(ret != FuriHalNfcReturnIncompleteByte) break;
  128. if(rx_len != 4) break;
  129. if(rx_data[0] != MAGIC_ACK) break;
  130. memcpy(tx_data, data->value, sizeof(data->value));
  131. ret = furi_hal_nfc_ll_txrx_bits(
  132. tx_data,
  133. 16 * 8,
  134. rx_data,
  135. sizeof(rx_data),
  136. &rx_len,
  137. FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
  138. furi_hal_nfc_ll_ms2fc(20));
  139. if(ret != FuriHalNfcReturnIncompleteByte) break;
  140. if(rx_len != 4) break;
  141. if(rx_data[0] != MAGIC_ACK) break;
  142. write_success = true;
  143. } while(false);
  144. if(!write_success) {
  145. furi_hal_nfc_ll_txrx_off();
  146. furi_hal_nfc_start_sleep();
  147. }
  148. return write_success;
  149. }
  150. bool magic_wipe() {
  151. bool wipe_success = false;
  152. uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
  153. uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
  154. uint16_t rx_len = 0;
  155. FuriHalNfcReturn ret = 0;
  156. do {
  157. tx_data[0] = MAGIC_CMD_WIPE;
  158. ret = furi_hal_nfc_ll_txrx_bits(
  159. tx_data,
  160. 8,
  161. rx_data,
  162. sizeof(rx_data),
  163. &rx_len,
  164. FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON |
  165. FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
  166. furi_hal_nfc_ll_ms2fc(2000));
  167. if(ret != FuriHalNfcReturnIncompleteByte) break;
  168. if(rx_len != 4) break;
  169. if(rx_data[0] != MAGIC_ACK) break;
  170. wipe_success = true;
  171. } while(false);
  172. return wipe_success;
  173. }
  174. void magic_deactivate() {
  175. furi_hal_nfc_ll_txrx_off();
  176. furi_hal_nfc_start_sleep();
  177. }