protocol_group_misc.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. #include "protocol_group_misc.h"
  2. #include <furi_hal_rfid.h>
  3. #include <furi_hal_ibutton.h>
  4. #include <toolbox/protocols/protocol_dict.h>
  5. #include "protocol_group_misc_defs.h"
  6. #define IBUTTON_MISC_READ_TIMEOUT 100
  7. #define IBUTTON_MISC_DATA_KEY_KEY_COMMON "Data"
  8. typedef struct {
  9. ProtocolDict* dict;
  10. ProtocolId emulate_id;
  11. } iButtonProtocolGroupMisc;
  12. static iButtonProtocolGroupMisc* ibutton_protocol_group_misc_alloc() {
  13. iButtonProtocolGroupMisc* group = malloc(sizeof(iButtonProtocolGroupMisc));
  14. group->dict = protocol_dict_alloc(ibutton_protocols_misc, iButtonProtocolMiscMax);
  15. group->emulate_id = PROTOCOL_NO;
  16. return group;
  17. }
  18. static void ibutton_protocol_group_misc_free(iButtonProtocolGroupMisc* group) {
  19. protocol_dict_free(group->dict);
  20. free(group);
  21. }
  22. static size_t ibutton_protocol_group_misc_get_max_data_size(iButtonProtocolGroupMisc* group) {
  23. return protocol_dict_get_max_data_size(group->dict);
  24. }
  25. static bool ibutton_protocol_group_misc_get_id_by_name(
  26. iButtonProtocolGroupMisc* group,
  27. iButtonProtocolLocalId* id,
  28. const char* name) {
  29. const ProtocolId found_id = protocol_dict_get_protocol_by_name(group->dict, name);
  30. if(found_id != PROTOCOL_NO) {
  31. *id = found_id;
  32. return true;
  33. }
  34. return false;
  35. }
  36. static uint32_t ibutton_protocol_group_misc_get_features(
  37. iButtonProtocolGroupMisc* group,
  38. iButtonProtocolLocalId id) {
  39. UNUSED(group);
  40. UNUSED(id);
  41. return 0;
  42. }
  43. static const char* ibutton_protocol_group_misc_get_manufacturer(
  44. iButtonProtocolGroupMisc* group,
  45. iButtonProtocolLocalId id) {
  46. return protocol_dict_get_manufacturer(group->dict, id);
  47. }
  48. static const char* ibutton_protocol_group_misc_get_name(
  49. iButtonProtocolGroupMisc* group,
  50. iButtonProtocolLocalId id) {
  51. return protocol_dict_get_name(group->dict, id);
  52. }
  53. typedef struct {
  54. uint32_t last_dwt_value;
  55. FuriStreamBuffer* stream;
  56. } iButtonReadContext;
  57. static void ibutton_protocols_comparator_callback(bool level, void* context) {
  58. iButtonReadContext* read_context = context;
  59. uint32_t current_dwt_value = DWT->CYCCNT;
  60. LevelDuration data =
  61. level_duration_make(level, current_dwt_value - read_context->last_dwt_value);
  62. furi_stream_buffer_send(read_context->stream, &data, sizeof(LevelDuration), 0);
  63. read_context->last_dwt_value = current_dwt_value;
  64. }
  65. static bool ibutton_protocol_group_misc_read(
  66. iButtonProtocolGroupMisc* group,
  67. iButtonProtocolData* data,
  68. iButtonProtocolLocalId* id) {
  69. bool result = false;
  70. protocol_dict_decoders_start(group->dict);
  71. furi_hal_rfid_pins_reset();
  72. // pulldown pull pin, we sense the signal through the analog part of the RFID schematic
  73. furi_hal_rfid_pin_pull_pulldown();
  74. iButtonReadContext read_context = {
  75. .last_dwt_value = DWT->CYCCNT,
  76. .stream = furi_stream_buffer_alloc(sizeof(LevelDuration) * 512, 1),
  77. };
  78. furi_hal_rfid_comp_set_callback(ibutton_protocols_comparator_callback, &read_context);
  79. furi_hal_rfid_comp_start();
  80. const uint32_t tick_start = furi_get_tick();
  81. for(;;) {
  82. LevelDuration level;
  83. size_t ret = furi_stream_buffer_receive(
  84. read_context.stream, &level, sizeof(LevelDuration), IBUTTON_MISC_READ_TIMEOUT);
  85. if((furi_get_tick() - tick_start) > IBUTTON_MISC_READ_TIMEOUT) {
  86. break;
  87. }
  88. if(ret > 0) {
  89. ProtocolId decoded_index = protocol_dict_decoders_feed(
  90. group->dict, level_duration_get_level(level), level_duration_get_duration(level));
  91. if(decoded_index == PROTOCOL_NO) continue;
  92. *id = decoded_index;
  93. protocol_dict_get_data(
  94. group->dict,
  95. decoded_index,
  96. data,
  97. protocol_dict_get_data_size(group->dict, decoded_index));
  98. result = true;
  99. }
  100. }
  101. furi_hal_rfid_comp_stop();
  102. furi_hal_rfid_comp_set_callback(NULL, NULL);
  103. furi_hal_rfid_pins_reset();
  104. furi_stream_buffer_free(read_context.stream);
  105. return result;
  106. }
  107. static void ibutton_protocol_group_misc_emulate_callback(void* context) {
  108. iButtonProtocolGroupMisc* group = context;
  109. const LevelDuration level_duration =
  110. protocol_dict_encoder_yield(group->dict, group->emulate_id);
  111. furi_hal_ibutton_emulate_set_next(level_duration_get_duration(level_duration));
  112. furi_hal_ibutton_pin_write(level_duration_get_level(level_duration));
  113. }
  114. static void ibutton_protocol_group_misc_emulate_start(
  115. iButtonProtocolGroupMisc* group,
  116. iButtonProtocolData* data,
  117. iButtonProtocolLocalId id) {
  118. group->emulate_id = id;
  119. protocol_dict_set_data(group->dict, id, data, protocol_dict_get_data_size(group->dict, id));
  120. protocol_dict_encoder_start(group->dict, group->emulate_id);
  121. furi_hal_ibutton_pin_configure();
  122. furi_hal_ibutton_emulate_start(0, ibutton_protocol_group_misc_emulate_callback, group);
  123. }
  124. static void ibutton_protocol_group_misc_emulate_stop(
  125. iButtonProtocolGroupMisc* group,
  126. iButtonProtocolData* data,
  127. iButtonProtocolLocalId id) {
  128. UNUSED(group);
  129. UNUSED(data);
  130. UNUSED(id);
  131. furi_hal_ibutton_emulate_stop();
  132. furi_hal_ibutton_pin_reset();
  133. }
  134. static bool ibutton_protocol_group_misc_save(
  135. iButtonProtocolGroupMisc* group,
  136. const iButtonProtocolData* data,
  137. iButtonProtocolLocalId id,
  138. FlipperFormat* ff) {
  139. const size_t data_size = protocol_dict_get_data_size(group->dict, id);
  140. return flipper_format_write_hex(ff, IBUTTON_MISC_DATA_KEY_KEY_COMMON, data, data_size);
  141. }
  142. static bool ibutton_protocol_group_misc_load(
  143. iButtonProtocolGroupMisc* group,
  144. iButtonProtocolData* data,
  145. iButtonProtocolLocalId id,
  146. uint32_t version,
  147. FlipperFormat* ff) {
  148. const size_t data_size = protocol_dict_get_data_size(group->dict, id);
  149. switch(version) {
  150. case 1:
  151. case 2:
  152. return flipper_format_read_hex(ff, IBUTTON_MISC_DATA_KEY_KEY_COMMON, data, data_size);
  153. default:
  154. return false;
  155. }
  156. }
  157. static void ibutton_protocol_group_misc_render_data(
  158. iButtonProtocolGroupMisc* group,
  159. const iButtonProtocolData* data,
  160. iButtonProtocolLocalId id,
  161. FuriString* result) {
  162. const size_t data_size = protocol_dict_get_data_size(group->dict, id);
  163. protocol_dict_set_data(group->dict, id, data, data_size);
  164. protocol_dict_render_data(group->dict, result, id);
  165. }
  166. static void ibutton_protocol_group_misc_render_brief_data(
  167. iButtonProtocolGroupMisc* group,
  168. const iButtonProtocolData* data,
  169. iButtonProtocolLocalId id,
  170. FuriString* result) {
  171. const size_t data_size = protocol_dict_get_data_size(group->dict, id);
  172. protocol_dict_set_data(group->dict, id, data, data_size);
  173. protocol_dict_render_brief_data(group->dict, result, id);
  174. }
  175. static void ibutton_protocol_group_misc_render_error(
  176. iButtonProtocolGroupMisc* group,
  177. const iButtonProtocolData* data,
  178. iButtonProtocolLocalId id,
  179. FuriString* result) {
  180. UNUSED(group);
  181. UNUSED(data);
  182. UNUSED(id);
  183. UNUSED(result);
  184. }
  185. static bool ibutton_protocol_group_misc_is_valid(
  186. iButtonProtocolGroupMisc* group,
  187. const iButtonProtocolData* data,
  188. iButtonProtocolLocalId id) {
  189. UNUSED(group);
  190. UNUSED(data);
  191. UNUSED(id);
  192. return true;
  193. }
  194. static void ibutton_protocol_group_misc_get_editable_data(
  195. iButtonProtocolGroupMisc* group,
  196. iButtonProtocolData* data,
  197. iButtonProtocolLocalId id,
  198. iButtonEditableData* editable) {
  199. editable->ptr = data;
  200. editable->size = protocol_dict_get_data_size(group->dict, id);
  201. }
  202. static void ibutton_protocol_group_misc_apply_edits(
  203. iButtonProtocolGroupMisc* group,
  204. iButtonProtocolData* data,
  205. iButtonProtocolLocalId id) {
  206. const size_t data_size = protocol_dict_get_data_size(group->dict, id);
  207. protocol_dict_set_data(group->dict, id, data, data_size);
  208. }
  209. const iButtonProtocolGroupBase ibutton_protocol_group_misc = {
  210. .protocol_count = iButtonProtocolMiscMax,
  211. .alloc = (iButtonProtocolGroupAllocFunc)ibutton_protocol_group_misc_alloc,
  212. .free = (iButtonProtocolGroupFreeFunc)ibutton_protocol_group_misc_free,
  213. .get_max_data_size =
  214. (iButtonProtocolGropuGetSizeFunc)ibutton_protocol_group_misc_get_max_data_size,
  215. .get_id_by_name = (iButtonProtocolGroupGetIdFunc)ibutton_protocol_group_misc_get_id_by_name,
  216. .get_features = (iButtonProtocolGroupGetFeaturesFunc)ibutton_protocol_group_misc_get_features,
  217. .get_manufacturer =
  218. (iButtonProtocolGroupGetStringFunc)ibutton_protocol_group_misc_get_manufacturer,
  219. .get_name = (iButtonProtocolGroupGetStringFunc)ibutton_protocol_group_misc_get_name,
  220. .read = (iButtonProtocolGroupReadFunc)ibutton_protocol_group_misc_read,
  221. .write_blank = NULL,
  222. .write_copy = NULL,
  223. .emulate_start = (iButtonProtocolGroupApplyFunc)ibutton_protocol_group_misc_emulate_start,
  224. .emulate_stop = (iButtonProtocolGroupApplyFunc)ibutton_protocol_group_misc_emulate_stop,
  225. .save = (iButtonProtocolGroupSaveFunc)ibutton_protocol_group_misc_save,
  226. .load = (iButtonProtocolGroupLoadFunc)ibutton_protocol_group_misc_load,
  227. .render_data = (iButtonProtocolGroupRenderFunc)ibutton_protocol_group_misc_render_data,
  228. .render_brief_data =
  229. (iButtonProtocolGroupRenderFunc)ibutton_protocol_group_misc_render_brief_data,
  230. .render_error = (iButtonProtocolGroupRenderFunc)ibutton_protocol_group_misc_render_error,
  231. .is_valid = (iButtonProtocolGroupIsValidFunc)ibutton_protocol_group_misc_is_valid,
  232. .get_editable_data =
  233. (iButtonProtocolGroupGetDataFunc)ibutton_protocol_group_misc_get_editable_data,
  234. .apply_edits = (iButtonProtocolGroupApplyFunc)ibutton_protocol_group_misc_apply_edits,
  235. };