bin_raw.c 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  1. #include "bin_raw.h"
  2. #include "../blocks/const.h"
  3. #include "../blocks/decoder.h"
  4. #include "../blocks/encoder.h"
  5. #include "../blocks/generic.h"
  6. #include "../blocks/math.h"
  7. #include <lib/toolbox/float_tools.h>
  8. #include <lib/toolbox/stream/stream.h>
  9. #include <lib/flipper_format/flipper_format_i.h>
  10. #define TAG "SubGhzProtocolBinRAW"
  11. //change very carefully, RAM ends at the most inopportune moment
  12. #define BIN_RAW_BUF_RAW_SIZE 2048
  13. #define BIN_RAW_BUF_DATA_SIZE 512
  14. #define BIN_RAW_THRESHOLD_RSSI -85.0f
  15. #define BIN_RAW_DELTA_RSSI 7.0f
  16. #define BIN_RAW_SEARCH_CLASSES 20
  17. #define BIN_RAW_TE_MIN_COUNT 40
  18. #define BIN_RAW_BUF_MIN_DATA_COUNT 128
  19. #define BIN_RAW_MAX_MARKUP_COUNT 20
  20. //#define BIN_RAW_DEBUG
  21. #ifdef BIN_RAW_DEBUG
  22. #define bin_raw_debug(...) FURI_LOG_RAW_D(__VA_ARGS__)
  23. #define bin_raw_debug_tag(tag, ...) \
  24. FURI_LOG_RAW_D("\033[0;32m[" tag "]\033[0m "); \
  25. FURI_LOG_RAW_D(__VA_ARGS__)
  26. #else
  27. #define bin_raw_debug(...)
  28. #define bin_raw_debug_tag(...)
  29. #endif
  30. static const SubGhzBlockConst subghz_protocol_bin_raw_const = {
  31. .te_short = 30,
  32. .te_long = 65000,
  33. .te_delta = 0,
  34. .min_count_bit_for_found = 0,
  35. };
  36. typedef enum {
  37. BinRAWDecoderStepReset = 0,
  38. BinRAWDecoderStepWrite,
  39. BinRAWDecoderStepBufFull,
  40. BinRAWDecoderStepNoParse,
  41. } BinRAWDecoderStep;
  42. typedef enum {
  43. BinRAWTypeUnknown = 0,
  44. BinRAWTypeNoGap,
  45. BinRAWTypeGap,
  46. BinRAWTypeGapRecurring,
  47. BinRAWTypeGapRolling,
  48. BinRAWTypeGapUnknown,
  49. } BinRAWType;
  50. struct BinRAW_Markup {
  51. uint16_t byte_bias;
  52. uint16_t bit_count;
  53. };
  54. typedef struct BinRAW_Markup BinRAW_Markup;
  55. struct SubGhzProtocolDecoderBinRAW {
  56. SubGhzProtocolDecoderBase base;
  57. SubGhzBlockDecoder decoder;
  58. SubGhzBlockGeneric generic;
  59. int32_t* data_raw;
  60. uint8_t* data;
  61. BinRAW_Markup data_markup[BIN_RAW_MAX_MARKUP_COUNT];
  62. size_t data_raw_ind;
  63. uint32_t te;
  64. float adaptive_threshold_rssi;
  65. };
  66. struct SubGhzProtocolEncoderBinRAW {
  67. SubGhzProtocolEncoderBase base;
  68. SubGhzProtocolBlockEncoder encoder;
  69. SubGhzBlockGeneric generic;
  70. uint8_t* data;
  71. BinRAW_Markup data_markup[BIN_RAW_MAX_MARKUP_COUNT];
  72. uint32_t te;
  73. };
  74. const SubGhzProtocolDecoder subghz_protocol_bin_raw_decoder = {
  75. .alloc = subghz_protocol_decoder_bin_raw_alloc,
  76. .free = subghz_protocol_decoder_bin_raw_free,
  77. .feed = subghz_protocol_decoder_bin_raw_feed,
  78. .reset = subghz_protocol_decoder_bin_raw_reset,
  79. .get_hash_data = subghz_protocol_decoder_bin_raw_get_hash_data,
  80. .serialize = subghz_protocol_decoder_bin_raw_serialize,
  81. .deserialize = subghz_protocol_decoder_bin_raw_deserialize,
  82. .get_string = subghz_protocol_decoder_bin_raw_get_string,
  83. };
  84. const SubGhzProtocolEncoder subghz_protocol_bin_raw_encoder = {
  85. .alloc = subghz_protocol_encoder_bin_raw_alloc,
  86. .free = subghz_protocol_encoder_bin_raw_free,
  87. .deserialize = subghz_protocol_encoder_bin_raw_deserialize,
  88. .stop = subghz_protocol_encoder_bin_raw_stop,
  89. .yield = subghz_protocol_encoder_bin_raw_yield,
  90. };
  91. const SubGhzProtocol subghz_protocol_bin_raw = {
  92. .name = SUBGHZ_PROTOCOL_BIN_RAW_NAME,
  93. .type = SubGhzProtocolTypeStatic,
  94. #ifdef BIN_RAW_DEBUG
  95. .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 |
  96. SubGhzProtocolFlag_AM | SubGhzProtocolFlag_FM | SubGhzProtocolFlag_Decodable |
  97. SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send,
  98. #else
  99. .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 |
  100. SubGhzProtocolFlag_AM | SubGhzProtocolFlag_FM | SubGhzProtocolFlag_BinRAW |
  101. SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send,
  102. #endif
  103. .decoder = &subghz_protocol_bin_raw_decoder,
  104. .encoder = &subghz_protocol_bin_raw_encoder,
  105. };
  106. static uint16_t subghz_protocol_bin_raw_get_full_byte(uint16_t bit_count) {
  107. if(bit_count & 0x7) {
  108. return (bit_count >> 3) + 1;
  109. } else {
  110. return (bit_count >> 3);
  111. }
  112. }
  113. void* subghz_protocol_encoder_bin_raw_alloc(SubGhzEnvironment* environment) {
  114. UNUSED(environment);
  115. SubGhzProtocolEncoderBinRAW* instance = malloc(sizeof(SubGhzProtocolEncoderBinRAW));
  116. instance->base.protocol = &subghz_protocol_bin_raw;
  117. instance->generic.protocol_name = instance->base.protocol->name;
  118. instance->encoder.repeat = 10;
  119. instance->encoder.size_upload = BIN_RAW_BUF_DATA_SIZE * 5;
  120. instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
  121. instance->data = malloc(instance->encoder.size_upload * sizeof(uint8_t));
  122. memset(instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  123. instance->encoder.is_running = false;
  124. return instance;
  125. }
  126. void subghz_protocol_encoder_bin_raw_free(void* context) {
  127. furi_assert(context);
  128. SubGhzProtocolEncoderBinRAW* instance = context;
  129. free(instance->encoder.upload);
  130. free(instance->data);
  131. free(instance);
  132. }
  133. /**
  134. * Generating an upload from data.
  135. * @param instance Pointer to a SubGhzProtocolEncoderBinRAW instance
  136. * @return true On success
  137. */
  138. static bool subghz_protocol_encoder_bin_raw_get_upload(SubGhzProtocolEncoderBinRAW* instance) {
  139. furi_assert(instance);
  140. //we glue all the pieces of the package into 1 long sequence with left alignment,
  141. //in the uploaded data we have right alignment.
  142. bin_raw_debug_tag(TAG, "Recovery of offset bits in sequences\r\n");
  143. uint16_t i = 0;
  144. uint16_t ind = 0;
  145. bin_raw_debug("\tind byte_bias\tbit_count\tbit_bias\r\n");
  146. while((i < BIN_RAW_MAX_MARKUP_COUNT) && (instance->data_markup[i].bit_count != 0)) {
  147. uint8_t bit_bias =
  148. subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count) * 8 -
  149. instance->data_markup[i].bit_count;
  150. bin_raw_debug(
  151. "\t%d\t%d\t%d :\t\t%d\r\n",
  152. i,
  153. instance->data_markup[i].byte_bias,
  154. instance->data_markup[i].bit_count,
  155. bit_bias);
  156. for(uint16_t y = instance->data_markup[i].byte_bias * 8;
  157. y < instance->data_markup[i].byte_bias * 8 +
  158. subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count) * 8 -
  159. bit_bias;
  160. y++) {
  161. subghz_protocol_blocks_set_bit_array(
  162. subghz_protocol_blocks_get_bit_array(instance->data, y + bit_bias),
  163. instance->data,
  164. ind++,
  165. BIN_RAW_BUF_DATA_SIZE);
  166. }
  167. i++;
  168. }
  169. bin_raw_debug("\r\n");
  170. #ifdef BIN_RAW_DEBUG
  171. bin_raw_debug_tag(TAG, "Restored Sequence left aligned\r\n");
  172. for(uint16_t y = 0; y < subghz_protocol_bin_raw_get_full_byte(ind); y++) {
  173. bin_raw_debug("%02X ", instance->data[y]);
  174. }
  175. bin_raw_debug("\r\n\tbin_count_result= %d\r\n\r\n", ind);
  176. bin_raw_debug_tag(
  177. TAG, "Maximum levels encoded in upload %zu\r\n", instance->encoder.size_upload);
  178. #endif
  179. instance->encoder.size_upload = subghz_protocol_blocks_get_upload_from_bit_array(
  180. instance->data,
  181. ind,
  182. instance->encoder.upload,
  183. instance->encoder.size_upload,
  184. instance->te,
  185. SubGhzProtocolBlockAlignBitLeft);
  186. bin_raw_debug_tag(TAG, "The result %zu is levels\r\n", instance->encoder.size_upload);
  187. bin_raw_debug_tag(TAG, "Remaining free memory %zu\r\n", memmgr_get_free_heap());
  188. return true;
  189. }
  190. bool subghz_protocol_encoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format) {
  191. furi_assert(context);
  192. SubGhzProtocolEncoderBinRAW* instance = context;
  193. bool res = false;
  194. uint32_t temp_data = 0;
  195. do {
  196. if(!flipper_format_rewind(flipper_format)) {
  197. FURI_LOG_E(TAG, "Rewind error");
  198. break;
  199. }
  200. if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) {
  201. FURI_LOG_E(TAG, "Missing Bit");
  202. break;
  203. }
  204. instance->generic.data_count_bit = (uint16_t)temp_data;
  205. if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
  206. FURI_LOG_E(TAG, "Missing TE");
  207. break;
  208. }
  209. temp_data = 0;
  210. uint16_t ind = 0;
  211. uint16_t byte_bias = 0;
  212. uint16_t byte_count = 0;
  213. memset(instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  214. while(flipper_format_read_uint32(flipper_format, "Bit_RAW", (uint32_t*)&temp_data, 1)) {
  215. if(ind >= BIN_RAW_MAX_MARKUP_COUNT) {
  216. FURI_LOG_E(TAG, "Markup overflow");
  217. break;
  218. }
  219. byte_count += subghz_protocol_bin_raw_get_full_byte(temp_data);
  220. if(byte_count > BIN_RAW_BUF_DATA_SIZE) {
  221. FURI_LOG_E(TAG, "Receive buffer overflow");
  222. break;
  223. }
  224. instance->data_markup[ind].bit_count = temp_data;
  225. instance->data_markup[ind].byte_bias = byte_bias;
  226. byte_bias += subghz_protocol_bin_raw_get_full_byte(temp_data);
  227. if(!flipper_format_read_hex(
  228. flipper_format,
  229. "Data_RAW",
  230. instance->data + instance->data_markup[ind].byte_bias,
  231. subghz_protocol_bin_raw_get_full_byte(temp_data))) {
  232. instance->data_markup[ind].bit_count = 0;
  233. FURI_LOG_E(TAG, "Missing Data_RAW");
  234. break;
  235. }
  236. ind++;
  237. }
  238. #ifdef BIN_RAW_DEBUG
  239. uint16_t i = 0;
  240. bin_raw_debug_tag(TAG, "Download data to encoder\r\n");
  241. bin_raw_debug("\tind byte_bias\tbit_count\t\tbin_data");
  242. while((i < BIN_RAW_MAX_MARKUP_COUNT) && (instance->data_markup[i].bit_count != 0)) {
  243. bin_raw_debug(
  244. "\r\n\t%d\t%d\t%d :\t",
  245. i,
  246. instance->data_markup[i].byte_bias,
  247. instance->data_markup[i].bit_count);
  248. for(uint16_t y = instance->data_markup[i].byte_bias;
  249. y < instance->data_markup[i].byte_bias +
  250. subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count);
  251. y++) {
  252. bin_raw_debug("%02X ", instance->data[y]);
  253. }
  254. i++;
  255. }
  256. bin_raw_debug("\r\n\r\n");
  257. #endif
  258. if(!flipper_format_rewind(flipper_format)) {
  259. FURI_LOG_E(TAG, "Rewind error");
  260. break;
  261. }
  262. //optional parameter parameter
  263. flipper_format_read_uint32(
  264. flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
  265. if(!subghz_protocol_encoder_bin_raw_get_upload(instance)) break;
  266. instance->encoder.is_running = true;
  267. res = true;
  268. } while(0);
  269. return res;
  270. }
  271. void subghz_protocol_encoder_bin_raw_stop(void* context) {
  272. SubGhzProtocolEncoderBinRAW* instance = context;
  273. instance->encoder.is_running = false;
  274. }
  275. LevelDuration subghz_protocol_encoder_bin_raw_yield(void* context) {
  276. SubGhzProtocolEncoderBinRAW* instance = context;
  277. if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
  278. instance->encoder.is_running = false;
  279. return level_duration_reset();
  280. }
  281. LevelDuration ret = instance->encoder.upload[instance->encoder.front];
  282. if(++instance->encoder.front == instance->encoder.size_upload) {
  283. instance->encoder.repeat--;
  284. instance->encoder.front = 0;
  285. }
  286. return ret;
  287. }
  288. void* subghz_protocol_decoder_bin_raw_alloc(SubGhzEnvironment* environment) {
  289. UNUSED(environment);
  290. SubGhzProtocolDecoderBinRAW* instance = malloc(sizeof(SubGhzProtocolDecoderBinRAW));
  291. instance->base.protocol = &subghz_protocol_bin_raw;
  292. instance->generic.protocol_name = instance->base.protocol->name;
  293. instance->data_raw_ind = 0;
  294. instance->data_raw = malloc(BIN_RAW_BUF_RAW_SIZE * sizeof(int32_t));
  295. instance->data = malloc(BIN_RAW_BUF_RAW_SIZE * sizeof(uint8_t));
  296. memset(instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  297. instance->adaptive_threshold_rssi = BIN_RAW_THRESHOLD_RSSI;
  298. return instance;
  299. }
  300. void subghz_protocol_decoder_bin_raw_free(void* context) {
  301. furi_assert(context);
  302. SubGhzProtocolDecoderBinRAW* instance = context;
  303. free(instance->data_raw);
  304. free(instance->data);
  305. free(instance);
  306. }
  307. void subghz_protocol_decoder_bin_raw_reset(void* context) {
  308. furi_assert(context);
  309. SubGhzProtocolDecoderBinRAW* instance = context;
  310. #ifdef BIN_RAW_DEBUG
  311. UNUSED(instance);
  312. #else
  313. instance->decoder.parser_step = BinRAWDecoderStepNoParse;
  314. instance->data_raw_ind = 0;
  315. #endif
  316. }
  317. void subghz_protocol_decoder_bin_raw_feed(void* context, bool level, uint32_t duration) {
  318. furi_assert(context);
  319. SubGhzProtocolDecoderBinRAW* instance = context;
  320. if(instance->decoder.parser_step == BinRAWDecoderStepWrite) {
  321. if(instance->data_raw_ind == BIN_RAW_BUF_RAW_SIZE) {
  322. instance->decoder.parser_step = BinRAWDecoderStepBufFull;
  323. } else {
  324. instance->data_raw[instance->data_raw_ind++] = (level ? duration : -duration);
  325. }
  326. }
  327. }
  328. /**
  329. * Analysis of received data
  330. * @param instance Pointer to a SubGhzProtocolDecoderBinRAW* instance
  331. */
  332. static bool
  333. subghz_protocol_bin_raw_check_remote_controller(SubGhzProtocolDecoderBinRAW* instance) {
  334. struct {
  335. float data;
  336. uint16_t count;
  337. } classes[BIN_RAW_SEARCH_CLASSES];
  338. size_t ind = 0;
  339. memset(classes, 0x00, sizeof(classes));
  340. uint16_t data_markup_ind = 0;
  341. memset(instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  342. if(instance->data_raw_ind < 512) {
  343. ind =
  344. instance->data_raw_ind -
  345. 100; //there is usually garbage at the end of the record, we exclude it from the classification
  346. } else {
  347. ind = 512;
  348. }
  349. //sort the durations to find the shortest correlated interval
  350. for(size_t i = 0; i < ind; i++) {
  351. for(size_t k = 0; k < BIN_RAW_SEARCH_CLASSES; k++) {
  352. if(classes[k].count == 0) {
  353. classes[k].data = (float)(abs(instance->data_raw[i]));
  354. classes[k].count++;
  355. break;
  356. } else if(
  357. DURATION_DIFF((float)(abs(instance->data_raw[i])), (classes[k].data)) <
  358. (classes[k].data / 4)) { //if the test value does not differ by more than 25%
  359. classes[k].data += ((float)(abs(instance->data_raw[i])) - classes[k].data) *
  360. 0.05f; //running average k=0.05
  361. classes[k].count++;
  362. break;
  363. }
  364. }
  365. }
  366. // if(classes[BIN_RAW_SEARCH_CLASSES - 1].count != 0) {
  367. // //filling the classifier, it means that they received an unclean signal
  368. // return false;
  369. // }
  370. //looking for the minimum te with an occurrence greater than BIN_RAW_TE_MIN_COUNT
  371. instance->te = subghz_protocol_bin_raw_const.te_long * 2;
  372. bool te_ok = false;
  373. uint16_t gap_ind = 0;
  374. uint16_t gap_delta = 0;
  375. uint32_t gap = 0;
  376. int data_temp = 0;
  377. BinRAWType bin_raw_type = BinRAWTypeUnknown;
  378. //sort by number of occurrences
  379. bool swap = true;
  380. while(swap) {
  381. swap = false;
  382. for(size_t i = 1; i < BIN_RAW_SEARCH_CLASSES; i++) {
  383. if(classes[i].count > classes[i - 1].count) {
  384. uint32_t data = classes[i - 1].data;
  385. uint32_t count = classes[i - 1].count;
  386. classes[i - 1].data = classes[i].data;
  387. classes[i - 1].count = classes[i].count;
  388. classes[i].data = data;
  389. classes[i].count = count;
  390. swap = true;
  391. }
  392. }
  393. }
  394. #ifdef BIN_RAW_DEBUG
  395. bin_raw_debug_tag(TAG, "Sorted durations\r\n");
  396. bin_raw_debug("\t\tind\tcount\tus\r\n");
  397. for(size_t k = 0; k < BIN_RAW_SEARCH_CLASSES; k++) {
  398. bin_raw_debug("\t\t%zu\t%u\t%lu\r\n", k, classes[k].count, (uint32_t)classes[k].data);
  399. }
  400. bin_raw_debug("\r\n");
  401. #endif
  402. if((classes[0].count > BIN_RAW_TE_MIN_COUNT) && (classes[1].count == 0)) {
  403. //adopted only the preamble
  404. instance->te = (uint32_t)classes[0].data;
  405. te_ok = true;
  406. gap = 0; //gap no
  407. } else {
  408. //take the 2 most common durations
  409. //check that there are enough
  410. if((classes[0].count < BIN_RAW_TE_MIN_COUNT) ||
  411. (classes[1].count < (BIN_RAW_TE_MIN_COUNT >> 1)))
  412. return false;
  413. //arrange the first 2 date values in ascending order
  414. if(classes[0].data > classes[1].data) {
  415. uint32_t data = classes[1].data;
  416. classes[0].data = classes[1].data;
  417. classes[1].data = data;
  418. }
  419. //determine the value to be corrected
  420. for(uint8_t k = 1; k < 5; k++) {
  421. float delta = (classes[1].data / (classes[0].data / k));
  422. bin_raw_debug_tag(TAG, "K_div= %f\r\n", (double)(delta));
  423. delta -= (uint32_t)delta;
  424. if((delta < 0.20f) || (delta > 0.80f)) {
  425. instance->te = (uint32_t)classes[0].data / k;
  426. bin_raw_debug_tag(TAG, "K= %d\r\n", k);
  427. te_ok = true; //found a correlated duration
  428. break;
  429. }
  430. }
  431. if(!te_ok) {
  432. //did not find the minimum TE satisfying the condition
  433. return false;
  434. }
  435. bin_raw_debug_tag(TAG, "TE= %lu\r\n\r\n", instance->te);
  436. //looking for a gap
  437. for(size_t k = 2; k < BIN_RAW_SEARCH_CLASSES; k++) {
  438. if((classes[k].count > 2) && (classes[k].data > gap)) {
  439. gap = (uint32_t)classes[k].data;
  440. gap_delta = gap / 5; //calculate 20% deviation from ideal value
  441. }
  442. }
  443. if((gap / instance->te) <
  444. 10) { //make an assumption, the longest gap should be more than 10 TE
  445. gap = 0; //check that our signal has a gap greater than 10*TE
  446. bin_raw_type = BinRAWTypeNoGap;
  447. } else {
  448. bin_raw_type = BinRAWTypeGap;
  449. //looking for the last occurrence of gap
  450. ind = instance->data_raw_ind - 1;
  451. while((ind > 0) && (DURATION_DIFF(abs(instance->data_raw[ind]), gap) > gap_delta)) {
  452. ind--;
  453. }
  454. gap_ind = ind;
  455. }
  456. }
  457. //if we consider that there is a gap, then we divide the signal with respect to this gap
  458. //processing input data from the end
  459. if(bin_raw_type == BinRAWTypeGap) {
  460. bin_raw_debug_tag(TAG, "Tinted sequence\r\n");
  461. ind = (BIN_RAW_BUF_DATA_SIZE * 8);
  462. uint16_t bit_count = 0;
  463. do {
  464. gap_ind--;
  465. data_temp = (int)(round((float)(instance->data_raw[gap_ind]) / instance->te));
  466. bin_raw_debug("%d ", data_temp);
  467. if(data_temp == 0) bit_count++; //there is noise in the package
  468. for(size_t i = 0; i < abs(data_temp); i++) {
  469. bit_count++;
  470. if(ind) {
  471. ind--;
  472. } else {
  473. break;
  474. }
  475. if(data_temp > 0) {
  476. subghz_protocol_blocks_set_bit_array(
  477. true, instance->data, ind, BIN_RAW_BUF_DATA_SIZE);
  478. } else {
  479. subghz_protocol_blocks_set_bit_array(
  480. false, instance->data, ind, BIN_RAW_BUF_DATA_SIZE);
  481. }
  482. }
  483. //split into full bytes if gap is caught
  484. if(DURATION_DIFF(abs(instance->data_raw[gap_ind]), gap) < gap_delta) {
  485. instance->data_markup[data_markup_ind].byte_bias = ind >> 3;
  486. instance->data_markup[data_markup_ind++].bit_count = bit_count;
  487. bit_count = 0;
  488. if(data_markup_ind == BIN_RAW_MAX_MARKUP_COUNT) break;
  489. ind &= 0xFFFFFFF8; //jump to the pre whole byte
  490. }
  491. } while(gap_ind != 0);
  492. if((data_markup_ind != BIN_RAW_MAX_MARKUP_COUNT) && (ind != 0)) {
  493. instance->data_markup[data_markup_ind].byte_bias = ind >> 3;
  494. instance->data_markup[data_markup_ind++].bit_count = bit_count;
  495. }
  496. bin_raw_debug("\r\n\t count bit= %zu\r\n\r\n", (BIN_RAW_BUF_DATA_SIZE * 8) - ind);
  497. //reset the classifier and classify the received data
  498. memset(classes, 0x00, sizeof(classes));
  499. bin_raw_debug_tag(TAG, "Sort the found pieces by the number of bits in them\r\n");
  500. for(size_t i = 0; i < data_markup_ind; i++) {
  501. for(size_t k = 0; k < BIN_RAW_SEARCH_CLASSES; k++) {
  502. if(classes[k].count == 0) {
  503. classes[k].data = instance->data_markup[i].bit_count;
  504. classes[k].count++;
  505. break;
  506. } else if(instance->data_markup[i].bit_count == (uint16_t)classes[k].data) {
  507. classes[k].count++;
  508. break;
  509. }
  510. }
  511. }
  512. #ifdef BIN_RAW_DEBUG
  513. bin_raw_debug("\t\tind\tcount\tus\r\n");
  514. for(size_t k = 0; k < BIN_RAW_SEARCH_CLASSES; k++) {
  515. bin_raw_debug("\t\t%zu\t%u\t%lu\r\n", k, classes[k].count, (uint32_t)classes[k].data);
  516. }
  517. bin_raw_debug("\r\n");
  518. #endif
  519. //choose the value with the maximum repetition
  520. data_temp = 0;
  521. for(size_t i = 0; i < BIN_RAW_SEARCH_CLASSES; i++) {
  522. if((classes[i].count > 1) && (data_temp < classes[i].count))
  523. data_temp = (int)classes[i].data;
  524. }
  525. //if(data_markup_ind == 0) return false;
  526. #ifdef BIN_RAW_DEBUG
  527. //output in reverse order
  528. bin_raw_debug_tag(TAG, "Found sequences\r\n");
  529. bin_raw_debug("\tind byte_bias\tbit_count\t\tbin_data\r\n");
  530. uint16_t data_markup_ind_temp = data_markup_ind;
  531. if(data_markup_ind) {
  532. data_markup_ind_temp--;
  533. for(size_t i = (ind / 8); i < BIN_RAW_BUF_DATA_SIZE; i++) {
  534. if(instance->data_markup[data_markup_ind_temp].byte_bias == i) {
  535. bin_raw_debug(
  536. "\r\n\t%d\t%d\t%d :\t",
  537. data_markup_ind_temp,
  538. instance->data_markup[data_markup_ind_temp].byte_bias,
  539. instance->data_markup[data_markup_ind_temp].bit_count);
  540. if(data_markup_ind_temp != 0) data_markup_ind_temp--;
  541. }
  542. bin_raw_debug("%02X ", instance->data[i]);
  543. }
  544. bin_raw_debug("\r\n\r\n");
  545. }
  546. //compare data in chunks with the same number of bits
  547. bin_raw_debug_tag(TAG, "Analyze sequences of long %d bit\r\n\r\n", data_temp);
  548. #endif
  549. //if(data_temp == 0) data_temp = (int)classes[0].data;
  550. if(data_temp != 0) {
  551. //check that data in transmission is repeated every packet
  552. for(uint16_t i = 0; i < data_markup_ind - 1; i++) {
  553. if((instance->data_markup[i].bit_count == data_temp) &&
  554. (instance->data_markup[i + 1].bit_count == data_temp)) {
  555. //if the number of bits in adjacent parcels is the same, compare the data
  556. bin_raw_debug_tag(
  557. TAG,
  558. "Comparison of neighboring sequences ind_1=%d ind_2=%d %02X=%02X .... %02X=%02X\r\n",
  559. i,
  560. i + 1,
  561. instance->data[instance->data_markup[i].byte_bias],
  562. instance->data[instance->data_markup[i + 1].byte_bias],
  563. instance->data
  564. [instance->data_markup[i].byte_bias +
  565. subghz_protocol_bin_raw_get_full_byte(
  566. instance->data_markup[i].bit_count) -
  567. 1],
  568. instance->data
  569. [instance->data_markup[i + 1].byte_bias +
  570. subghz_protocol_bin_raw_get_full_byte(
  571. instance->data_markup[i + 1].bit_count) -
  572. 1]);
  573. uint16_t byte_count =
  574. subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count);
  575. if(memcmp(
  576. instance->data + instance->data_markup[i].byte_bias,
  577. instance->data + instance->data_markup[i + 1].byte_bias,
  578. byte_count - 1) == 0) {
  579. bin_raw_debug_tag(
  580. TAG, "Match found bin_raw_type=BinRAWTypeGapRecurring\r\n\r\n");
  581. //place in 1 element the offset to valid data
  582. instance->data_markup[0].bit_count = instance->data_markup[i].bit_count;
  583. instance->data_markup[0].byte_bias = instance->data_markup[i].byte_bias;
  584. //markup end sign
  585. instance->data_markup[1].bit_count = 0;
  586. instance->data_markup[1].byte_bias = 0;
  587. bin_raw_type = BinRAWTypeGapRecurring;
  588. i = data_markup_ind;
  589. break;
  590. }
  591. }
  592. }
  593. }
  594. if(bin_raw_type == BinRAWTypeGap) {
  595. // check that retry occurs every n packets
  596. for(uint16_t i = 0; i < data_markup_ind - 2; i++) {
  597. uint16_t byte_count =
  598. subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count);
  599. for(uint16_t y = i + 1; y < data_markup_ind - 1; y++) {
  600. bin_raw_debug_tag(
  601. TAG,
  602. "Comparison every N sequences ind_1=%d ind_2=%d %02X=%02X .... %02X=%02X\r\n",
  603. i,
  604. y,
  605. instance->data[instance->data_markup[i].byte_bias],
  606. instance->data[instance->data_markup[y].byte_bias],
  607. instance->data
  608. [instance->data_markup[i].byte_bias +
  609. subghz_protocol_bin_raw_get_full_byte(
  610. instance->data_markup[i].bit_count) -
  611. 1],
  612. instance->data
  613. [instance->data_markup[y].byte_bias +
  614. subghz_protocol_bin_raw_get_full_byte(
  615. instance->data_markup[y].bit_count) -
  616. 1]);
  617. if(byte_count ==
  618. subghz_protocol_bin_raw_get_full_byte(
  619. instance->data_markup[y].bit_count)) { //if the length in bytes matches
  620. if((memcmp(
  621. instance->data + instance->data_markup[i].byte_bias,
  622. instance->data + instance->data_markup[y].byte_bias,
  623. byte_count - 1) == 0) &&
  624. (memcmp(
  625. instance->data + instance->data_markup[i + 1].byte_bias,
  626. instance->data + instance->data_markup[y + 1].byte_bias,
  627. byte_count - 1) == 0)) {
  628. uint8_t index = 0;
  629. #ifdef BIN_RAW_DEBUG
  630. bin_raw_debug_tag(
  631. TAG, "Match found bin_raw_type=BinRAWTypeGapRolling\r\n\r\n");
  632. //output in reverse order
  633. bin_raw_debug("\tind byte_bias\tbit_count\t\tbin_data\r\n");
  634. index = y - 1;
  635. for(size_t z = instance->data_markup[y].byte_bias + byte_count;
  636. z < instance->data_markup[i].byte_bias + byte_count;
  637. z++) {
  638. if(instance->data_markup[index].byte_bias == z) {
  639. bin_raw_debug(
  640. "\r\n\t%d\t%d\t%d :\t",
  641. index,
  642. instance->data_markup[index].byte_bias,
  643. instance->data_markup[index].bit_count);
  644. if(index != 0) index--;
  645. }
  646. bin_raw_debug("%02X ", instance->data[z]);
  647. }
  648. bin_raw_debug("\r\n\r\n");
  649. #endif
  650. //todo can be optimized
  651. BinRAW_Markup markup_temp[BIN_RAW_MAX_MARKUP_COUNT];
  652. memcpy(
  653. markup_temp,
  654. instance->data_markup,
  655. BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  656. memset(
  657. instance->data_markup,
  658. 0x00,
  659. BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  660. for(index = i; index < y; index++) {
  661. instance->data_markup[index - i].bit_count =
  662. markup_temp[y - index - 1].bit_count;
  663. instance->data_markup[index - i].byte_bias =
  664. markup_temp[y - index - 1].byte_bias;
  665. }
  666. bin_raw_type = BinRAWTypeGapRolling;
  667. i = data_markup_ind;
  668. break;
  669. }
  670. }
  671. }
  672. }
  673. }
  674. //todo can be optimized
  675. if(bin_raw_type == BinRAWTypeGap) {
  676. if(data_temp != 0) { //there are sequences with the same number of bits
  677. BinRAW_Markup markup_temp[BIN_RAW_MAX_MARKUP_COUNT];
  678. memcpy(
  679. markup_temp,
  680. instance->data_markup,
  681. BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  682. memset(
  683. instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  684. uint16_t byte_count = subghz_protocol_bin_raw_get_full_byte(data_temp);
  685. uint16_t index = 0;
  686. uint16_t it = BIN_RAW_MAX_MARKUP_COUNT;
  687. do {
  688. it--;
  689. if(subghz_protocol_bin_raw_get_full_byte(markup_temp[it].bit_count) ==
  690. byte_count) {
  691. instance->data_markup[index].bit_count = markup_temp[it].bit_count;
  692. instance->data_markup[index].byte_bias = markup_temp[it].byte_bias;
  693. index++;
  694. bin_raw_type = BinRAWTypeGapUnknown;
  695. }
  696. } while(it != 0);
  697. }
  698. }
  699. if(bin_raw_type != BinRAWTypeGap)
  700. return true;
  701. else
  702. return false;
  703. } else {
  704. // if bin_raw_type == BinRAWTypeGap
  705. bin_raw_debug_tag(TAG, "Sequence analysis without gap\r\n");
  706. ind = 0;
  707. for(size_t i = 0; i < instance->data_raw_ind; i++) {
  708. int data_temp = (int)(round((float)(instance->data_raw[i]) / instance->te));
  709. if(data_temp == 0) break; //found an interval 2 times shorter than TE, this is noise
  710. bin_raw_debug("%d ", data_temp);
  711. for(size_t k = 0; k < abs(data_temp); k++) {
  712. if(data_temp > 0) {
  713. subghz_protocol_blocks_set_bit_array(
  714. true, instance->data, ind++, BIN_RAW_BUF_DATA_SIZE);
  715. } else {
  716. subghz_protocol_blocks_set_bit_array(
  717. false, instance->data, ind++, BIN_RAW_BUF_DATA_SIZE);
  718. }
  719. if(ind == BIN_RAW_BUF_DATA_SIZE * 8) {
  720. i = instance->data_raw_ind;
  721. break;
  722. }
  723. }
  724. }
  725. if(ind != 0) {
  726. bin_raw_type = BinRAWTypeNoGap;
  727. //right alignment
  728. uint8_t bit_bias = (subghz_protocol_bin_raw_get_full_byte(ind) << 3) - ind;
  729. #ifdef BIN_RAW_DEBUG
  730. bin_raw_debug(
  731. "\r\n\t count bit= %zu\tcount full byte= %d\tbias bit= %d\r\n\r\n",
  732. ind,
  733. subghz_protocol_bin_raw_get_full_byte(ind),
  734. bit_bias);
  735. for(size_t i = 0; i < subghz_protocol_bin_raw_get_full_byte(ind); i++) {
  736. bin_raw_debug("%02X ", instance->data[i]);
  737. }
  738. bin_raw_debug("\r\n\r\n");
  739. #endif
  740. //checking that the received sequence contains useful data
  741. bool data_check = false;
  742. for(size_t i = 0; i < subghz_protocol_bin_raw_get_full_byte(ind); i++) {
  743. if(instance->data[i] != 0) {
  744. data_check = true;
  745. break;
  746. }
  747. }
  748. if(data_check) {
  749. for(size_t i = subghz_protocol_bin_raw_get_full_byte(ind) - 1; i > 0; i--) {
  750. instance->data[i] = (instance->data[i - 1] << (8 - bit_bias)) |
  751. (instance->data[i] >> bit_bias);
  752. }
  753. instance->data[0] = (instance->data[0] >> bit_bias);
  754. #ifdef BIN_RAW_DEBUG
  755. bin_raw_debug_tag(TAG, "Data right alignment\r\n");
  756. for(size_t i = 0; i < subghz_protocol_bin_raw_get_full_byte(ind); i++) {
  757. bin_raw_debug("%02X ", instance->data[i]);
  758. }
  759. bin_raw_debug("\r\n\r\n");
  760. #endif
  761. instance->data_markup[0].bit_count = ind;
  762. instance->data_markup[0].byte_bias = 0;
  763. return true;
  764. } else {
  765. return false;
  766. }
  767. } else {
  768. return false;
  769. }
  770. }
  771. return false;
  772. }
  773. void subghz_protocol_decoder_bin_raw_data_input_rssi(
  774. SubGhzProtocolDecoderBinRAW* instance,
  775. float rssi) {
  776. furi_assert(instance);
  777. switch(instance->decoder.parser_step) {
  778. case BinRAWDecoderStepReset:
  779. bin_raw_debug("%ld %ld :", (int32_t)rssi, (int32_t)instance->adaptive_threshold_rssi);
  780. if(rssi > (instance->adaptive_threshold_rssi + BIN_RAW_DELTA_RSSI)) {
  781. instance->data_raw_ind = 0;
  782. memset(instance->data_raw, 0x00, BIN_RAW_BUF_RAW_SIZE * sizeof(int32_t));
  783. memset(instance->data, 0x00, BIN_RAW_BUF_RAW_SIZE * sizeof(uint8_t));
  784. instance->decoder.parser_step = BinRAWDecoderStepWrite;
  785. bin_raw_debug_tag(TAG, "RSSI\r\n");
  786. } else {
  787. //adaptive noise level adjustment
  788. instance->adaptive_threshold_rssi += (rssi - instance->adaptive_threshold_rssi) * 0.2f;
  789. }
  790. break;
  791. case BinRAWDecoderStepBufFull:
  792. case BinRAWDecoderStepWrite:
  793. #ifdef BIN_RAW_DEBUG
  794. if(rssi > (instance->adaptive_threshold_rssi + BIN_RAW_DELTA_RSSI)) {
  795. bin_raw_debug("\033[0;32m%ld \033[0m ", (int32_t)rssi);
  796. } else {
  797. bin_raw_debug("%ld ", (int32_t)rssi);
  798. }
  799. #endif
  800. if(rssi < instance->adaptive_threshold_rssi + BIN_RAW_DELTA_RSSI) {
  801. #ifdef BIN_RAW_DEBUG
  802. bin_raw_debug("\r\n\r\n");
  803. bin_raw_debug_tag(TAG, "Data for analysis, positive high, negative low, us\r\n");
  804. for(size_t i = 0; i < instance->data_raw_ind; i++) {
  805. bin_raw_debug("%ld ", instance->data_raw[i]);
  806. }
  807. bin_raw_debug("\r\n\t count data= %zu\r\n\r\n", instance->data_raw_ind);
  808. #endif
  809. instance->decoder.parser_step = BinRAWDecoderStepReset;
  810. instance->generic.data_count_bit = 0;
  811. if(instance->data_raw_ind >= BIN_RAW_BUF_MIN_DATA_COUNT) {
  812. if(subghz_protocol_bin_raw_check_remote_controller(instance)) {
  813. bin_raw_debug_tag(TAG, "Sequence found\r\n");
  814. bin_raw_debug("\tind byte_bias\tbit_count\t\tbin_data");
  815. uint16_t i = 0;
  816. while((i < BIN_RAW_MAX_MARKUP_COUNT) &&
  817. (instance->data_markup[i].bit_count != 0)) {
  818. instance->generic.data_count_bit += instance->data_markup[i].bit_count;
  819. #ifdef BIN_RAW_DEBUG
  820. bin_raw_debug(
  821. "\r\n\t%d\t%d\t%d :\t",
  822. i,
  823. instance->data_markup[i].byte_bias,
  824. instance->data_markup[i].bit_count);
  825. for(uint16_t y = instance->data_markup[i].byte_bias;
  826. y < instance->data_markup[i].byte_bias +
  827. subghz_protocol_bin_raw_get_full_byte(
  828. instance->data_markup[i].bit_count);
  829. y++) {
  830. bin_raw_debug("%02X ", instance->data[y]);
  831. }
  832. #endif
  833. i++;
  834. }
  835. bin_raw_debug("\r\n");
  836. if(instance->base.callback)
  837. instance->base.callback(&instance->base, instance->base.context);
  838. }
  839. }
  840. }
  841. break;
  842. default:
  843. //if instance->decoder.parser_step == BinRAWDecoderStepNoParse or others, restore the initial state
  844. if(rssi < instance->adaptive_threshold_rssi + BIN_RAW_DELTA_RSSI) {
  845. instance->decoder.parser_step = BinRAWDecoderStepReset;
  846. }
  847. break;
  848. }
  849. }
  850. uint8_t subghz_protocol_decoder_bin_raw_get_hash_data(void* context) {
  851. furi_assert(context);
  852. SubGhzProtocolDecoderBinRAW* instance = context;
  853. return subghz_protocol_blocks_add_bytes(
  854. instance->data + instance->data_markup[0].byte_bias,
  855. subghz_protocol_bin_raw_get_full_byte(instance->data_markup[0].bit_count));
  856. }
  857. bool subghz_protocol_decoder_bin_raw_serialize(
  858. void* context,
  859. FlipperFormat* flipper_format,
  860. SubGhzRadioPreset* preset) {
  861. furi_assert(context);
  862. SubGhzProtocolDecoderBinRAW* instance = context;
  863. bool res = false;
  864. FuriString* temp_str;
  865. temp_str = furi_string_alloc();
  866. do {
  867. stream_clean(flipper_format_get_raw_stream(flipper_format));
  868. if(!flipper_format_write_header_cstr(
  869. flipper_format, SUBGHZ_KEY_FILE_TYPE, SUBGHZ_KEY_FILE_VERSION)) {
  870. FURI_LOG_E(TAG, "Unable to add header");
  871. break;
  872. }
  873. if(!flipper_format_write_uint32(flipper_format, "Frequency", &preset->frequency, 1)) {
  874. FURI_LOG_E(TAG, "Unable to add Frequency");
  875. break;
  876. }
  877. subghz_block_generic_get_preset_name(furi_string_get_cstr(preset->name), temp_str);
  878. if(!flipper_format_write_string_cstr(
  879. flipper_format, "Preset", furi_string_get_cstr(temp_str))) {
  880. FURI_LOG_E(TAG, "Unable to add Preset");
  881. break;
  882. }
  883. if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) {
  884. if(!flipper_format_write_string_cstr(
  885. flipper_format, "Custom_preset_module", "CC1101")) {
  886. FURI_LOG_E(TAG, "Unable to add Custom_preset_module");
  887. break;
  888. }
  889. if(!flipper_format_write_hex(
  890. flipper_format, "Custom_preset_data", preset->data, preset->data_size)) {
  891. FURI_LOG_E(TAG, "Unable to add Custom_preset_data");
  892. break;
  893. }
  894. }
  895. if(!flipper_format_write_string_cstr(
  896. flipper_format, "Protocol", instance->generic.protocol_name)) {
  897. FURI_LOG_E(TAG, "Unable to add Protocol");
  898. break;
  899. }
  900. uint32_t temp = instance->generic.data_count_bit;
  901. if(!flipper_format_write_uint32(flipper_format, "Bit", &temp, 1)) {
  902. FURI_LOG_E(TAG, "Unable to add Bit");
  903. break;
  904. }
  905. if(!flipper_format_write_uint32(flipper_format, "TE", &instance->te, 1)) {
  906. FURI_LOG_E(TAG, "Unable to add TE");
  907. break;
  908. }
  909. uint16_t i = 0;
  910. while((i < BIN_RAW_MAX_MARKUP_COUNT) && (instance->data_markup[i].bit_count != 0)) {
  911. temp = instance->data_markup[i].bit_count;
  912. if(!flipper_format_write_uint32(flipper_format, "Bit_RAW", &temp, 1)) {
  913. FURI_LOG_E(TAG, "Bit_RAW");
  914. break;
  915. }
  916. if(!flipper_format_write_hex(
  917. flipper_format,
  918. "Data_RAW",
  919. instance->data + instance->data_markup[i].byte_bias,
  920. subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count))) {
  921. FURI_LOG_E(TAG, "Unable to add Data_RAW");
  922. break;
  923. }
  924. i++;
  925. }
  926. res = true;
  927. } while(false);
  928. furi_string_free(temp_str);
  929. return res;
  930. }
  931. bool subghz_protocol_decoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format) {
  932. furi_assert(context);
  933. SubGhzProtocolDecoderBinRAW* instance = context;
  934. bool res = false;
  935. uint32_t temp_data = 0;
  936. do {
  937. if(!flipper_format_rewind(flipper_format)) {
  938. FURI_LOG_E(TAG, "Rewind error");
  939. break;
  940. }
  941. if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) {
  942. FURI_LOG_E(TAG, "Missing Bit");
  943. break;
  944. }
  945. instance->generic.data_count_bit = (uint16_t)temp_data;
  946. if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
  947. FURI_LOG_E(TAG, "Missing TE");
  948. break;
  949. }
  950. temp_data = 0;
  951. uint16_t ind = 0;
  952. uint16_t byte_bias = 0;
  953. uint16_t byte_count = 0;
  954. memset(instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  955. while(flipper_format_read_uint32(flipper_format, "Bit_RAW", (uint32_t*)&temp_data, 1)) {
  956. if(ind >= BIN_RAW_MAX_MARKUP_COUNT) {
  957. FURI_LOG_E(TAG, "Markup overflow");
  958. break;
  959. }
  960. byte_count += subghz_protocol_bin_raw_get_full_byte(temp_data);
  961. if(byte_count > BIN_RAW_BUF_DATA_SIZE) {
  962. FURI_LOG_E(TAG, "Receive buffer overflow");
  963. break;
  964. }
  965. instance->data_markup[ind].bit_count = temp_data;
  966. instance->data_markup[ind].byte_bias = byte_bias;
  967. byte_bias += subghz_protocol_bin_raw_get_full_byte(temp_data);
  968. if(!flipper_format_read_hex(
  969. flipper_format,
  970. "Data_RAW",
  971. instance->data + instance->data_markup[ind].byte_bias,
  972. subghz_protocol_bin_raw_get_full_byte(temp_data))) {
  973. instance->data_markup[ind].bit_count = 0;
  974. FURI_LOG_E(TAG, "Missing Data_RAW");
  975. break;
  976. }
  977. ind++;
  978. }
  979. res = true;
  980. } while(0);
  981. return res;
  982. }
  983. void subghz_protocol_decoder_bin_raw_get_string(void* context, FuriString* output) {
  984. furi_assert(context);
  985. SubGhzProtocolDecoderBinRAW* instance = context;
  986. furi_string_cat_printf(
  987. output,
  988. "%s %dbit\r\n"
  989. "Key:",
  990. instance->generic.protocol_name,
  991. instance->generic.data_count_bit);
  992. uint16_t byte_count = subghz_protocol_bin_raw_get_full_byte(instance->generic.data_count_bit);
  993. for(size_t i = 0; (byte_count < 36 ? i < byte_count : i < 36); i++) {
  994. furi_string_cat_printf(output, "%02X", instance->data[i]);
  995. }
  996. furi_string_cat_printf(output, "\r\nTe:%luus\r\n", instance->te);
  997. }