key-emulator.cpp 6.4 KB

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