key_emulator.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. #include "key_emulator.h"
  2. #include <callback-connector.h>
  3. KeyEmulator::~KeyEmulator() {
  4. stop();
  5. }
  6. KeyEmulator::KeyEmulator(OneWireSlave* _onewire_slave)
  7. : dallas_key{0, 0, 0, 0, 0, 0, 0} {
  8. onewire_slave = _onewire_slave;
  9. auto cb = cbc::obtain_connector(this, &KeyEmulator::result_callback);
  10. onewire_slave->set_result_callback(cb, this);
  11. }
  12. void KeyEmulator::start(iButtonKey* key) {
  13. anything_emulated = false;
  14. stop();
  15. // pulldown pull pin, to prevent low-pass filtering by the RFID part of the schematic
  16. furi_hal_rfid_pin_pull_pulldown();
  17. switch(key->get_key_type()) {
  18. case iButtonKeyType::KeyDallas:
  19. start_dallas_emulate(key);
  20. break;
  21. case iButtonKeyType::KeyCyfral:
  22. start_cyfral_emulate(key);
  23. break;
  24. case iButtonKeyType::KeyMetakom:
  25. start_metakom_emulate(key);
  26. break;
  27. }
  28. }
  29. bool KeyEmulator::emulated() {
  30. bool result = false;
  31. if(anything_emulated) {
  32. anything_emulated = false;
  33. result = true;
  34. }
  35. return result;
  36. }
  37. void KeyEmulator::stop() {
  38. onewire_slave->stop();
  39. pulser.stop();
  40. furi_hal_rfid_pins_reset();
  41. }
  42. void KeyEmulator::start_cyfral_emulate(iButtonKey* key) {
  43. furi_assert(key->get_key_type() == iButtonKeyType::KeyCyfral);
  44. furi_assert(key->get_type_data_size() == 2);
  45. const uint32_t cyfral_period_full = 8000;
  46. const uint32_t cyfral_period_one[2] = {
  47. uint32_t(cyfral_period_full * 0.33f), uint32_t(cyfral_period_full * 0.66f)};
  48. const uint32_t cyfral_period_zero[2] = {
  49. uint32_t(cyfral_period_full * 0.66f), uint32_t(cyfral_period_full * 0.33f)};
  50. uint8_t pd_index = 0;
  51. uint8_t* key_data = key->get_data();
  52. // start nibble
  53. set_pulse_data_cyfral(pd_index, cyfral_period_zero);
  54. pd_index++;
  55. set_pulse_data_cyfral(pd_index, cyfral_period_zero);
  56. pd_index++;
  57. set_pulse_data_cyfral(pd_index, cyfral_period_zero);
  58. pd_index++;
  59. set_pulse_data_cyfral(pd_index, cyfral_period_one);
  60. pd_index++;
  61. // data nibbles x 8
  62. for(int8_t i = key->get_type_data_size() - 1; i >= 0; i--) {
  63. for(int8_t j = 3; j >= 0; j--) {
  64. switch((key_data[i] >> (j * 2)) & 0b00000011) {
  65. case 0b11:
  66. set_pulse_data_cyfral(pd_index, cyfral_period_one);
  67. pd_index++;
  68. set_pulse_data_cyfral(pd_index, cyfral_period_one);
  69. pd_index++;
  70. set_pulse_data_cyfral(pd_index, cyfral_period_one);
  71. pd_index++;
  72. set_pulse_data_cyfral(pd_index, cyfral_period_zero);
  73. pd_index++;
  74. break;
  75. case 0b10:
  76. set_pulse_data_cyfral(pd_index, cyfral_period_one);
  77. pd_index++;
  78. set_pulse_data_cyfral(pd_index, cyfral_period_one);
  79. pd_index++;
  80. set_pulse_data_cyfral(pd_index, cyfral_period_zero);
  81. pd_index++;
  82. set_pulse_data_cyfral(pd_index, cyfral_period_one);
  83. pd_index++;
  84. break;
  85. case 0b01:
  86. set_pulse_data_cyfral(pd_index, cyfral_period_one);
  87. pd_index++;
  88. set_pulse_data_cyfral(pd_index, cyfral_period_zero);
  89. pd_index++;
  90. set_pulse_data_cyfral(pd_index, cyfral_period_one);
  91. pd_index++;
  92. set_pulse_data_cyfral(pd_index, cyfral_period_one);
  93. pd_index++;
  94. break;
  95. case 0b00:
  96. set_pulse_data_cyfral(pd_index, cyfral_period_zero);
  97. pd_index++;
  98. set_pulse_data_cyfral(pd_index, cyfral_period_one);
  99. pd_index++;
  100. set_pulse_data_cyfral(pd_index, cyfral_period_one);
  101. pd_index++;
  102. set_pulse_data_cyfral(pd_index, cyfral_period_one);
  103. pd_index++;
  104. break;
  105. default:
  106. // cannot be anyway
  107. furi_check(false);
  108. break;
  109. }
  110. }
  111. }
  112. // 4 (nibbles) x (8 data + 1 start) = 4 x 9 = 36
  113. if(pd_index != 36) {
  114. // something is very wrong
  115. furi_check(false);
  116. }
  117. pulser.set_periods(pulse_data, 72, false);
  118. pulser.start();
  119. }
  120. void KeyEmulator::start_metakom_emulate(iButtonKey* key) {
  121. furi_assert(key->get_key_type() == iButtonKeyType::KeyMetakom);
  122. furi_assert(key->get_type_data_size() == 4);
  123. const uint32_t metakom_period_full = 8000;
  124. const uint32_t metakom_period_zero[2] = {
  125. uint32_t(metakom_period_full * 0.33f), uint32_t(metakom_period_full * 0.66f)};
  126. const uint32_t metakom_period_one[2] = {
  127. uint32_t(metakom_period_full * 0.66f), uint32_t(metakom_period_full * 0.33f)};
  128. uint8_t pd_index = 0;
  129. uint8_t* key_data = key->get_data();
  130. // start pulse
  131. pulse_data[0] = metakom_period_full;
  132. // start triplet
  133. set_pulse_data_metakom(pd_index, metakom_period_zero);
  134. pd_index++;
  135. set_pulse_data_metakom(pd_index, metakom_period_one);
  136. pd_index++;
  137. set_pulse_data_metakom(pd_index, metakom_period_zero);
  138. pd_index++;
  139. for(int8_t i = key->get_type_data_size() - 1; i >= 0; i--) {
  140. for(int8_t j = 7; j >= 0; j--) {
  141. if(((key_data[i] >> j) & 0b00000001) == 1) {
  142. set_pulse_data_metakom(pd_index, metakom_period_one);
  143. pd_index++;
  144. } else {
  145. set_pulse_data_metakom(pd_index, metakom_period_zero);
  146. pd_index++;
  147. }
  148. }
  149. }
  150. // 4 byte x 8 bits + 3 start bits = 35
  151. if(pd_index != 35) {
  152. // something is very wrong
  153. furi_check(false);
  154. }
  155. pulser.set_periods(pulse_data, 71, false);
  156. pulser.start();
  157. }
  158. void KeyEmulator::start_dallas_emulate(iButtonKey* key) {
  159. furi_assert(key->get_key_type() == iButtonKeyType::KeyDallas);
  160. furi_assert(key->get_type_data_size() == 8);
  161. onewire_slave->deattach();
  162. memcpy(dallas_key.id_storage, key->get_data(), key->get_type_data_size());
  163. onewire_slave->attach(&dallas_key);
  164. onewire_slave->start();
  165. }
  166. void KeyEmulator::set_pulse_data_cyfral(uint8_t index, const uint32_t* data) {
  167. pulse_data[index * 2] = data[0];
  168. pulse_data[index * 2 + 1] = data[1];
  169. }
  170. void KeyEmulator::set_pulse_data_metakom(uint8_t index, const uint32_t* data) {
  171. // damn start pulse
  172. pulse_data[(index * 2) + 1] = data[0];
  173. pulse_data[(index * 2) + 2] = data[1];
  174. }
  175. void KeyEmulator::result_callback(bool success, void* ctx) {
  176. KeyEmulator* _this = static_cast<KeyEmulator*>(ctx);
  177. _this->anything_emulated = true;
  178. }