bin_raw.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148
  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. SubGhzProtocolStatus
  191. subghz_protocol_encoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format) {
  192. furi_assert(context);
  193. SubGhzProtocolEncoderBinRAW* instance = context;
  194. SubGhzProtocolStatus res = SubGhzProtocolStatusError;
  195. uint32_t temp_data = 0;
  196. do {
  197. if(!flipper_format_rewind(flipper_format)) {
  198. FURI_LOG_E(TAG, "Rewind error");
  199. res = SubGhzProtocolStatusErrorParserOthers;
  200. break;
  201. }
  202. if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) {
  203. FURI_LOG_E(TAG, "Missing Bit");
  204. res = SubGhzProtocolStatusErrorParserBitCount;
  205. break;
  206. }
  207. instance->generic.data_count_bit = (uint16_t)temp_data;
  208. if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
  209. FURI_LOG_E(TAG, "Missing TE");
  210. res = SubGhzProtocolStatusErrorParserTe;
  211. break;
  212. }
  213. temp_data = 0;
  214. uint16_t ind = 0;
  215. uint16_t byte_bias = 0;
  216. uint16_t byte_count = 0;
  217. memset(instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  218. while(flipper_format_read_uint32(flipper_format, "Bit_RAW", (uint32_t*)&temp_data, 1)) {
  219. if(ind >= BIN_RAW_MAX_MARKUP_COUNT) {
  220. FURI_LOG_E(TAG, "Markup overflow");
  221. res = SubGhzProtocolStatusErrorParserOthers;
  222. break;
  223. }
  224. byte_count += subghz_protocol_bin_raw_get_full_byte(temp_data);
  225. if(byte_count > BIN_RAW_BUF_DATA_SIZE) {
  226. FURI_LOG_E(TAG, "Receive buffer overflow");
  227. res = SubGhzProtocolStatusErrorParserOthers;
  228. break;
  229. }
  230. instance->data_markup[ind].bit_count = temp_data;
  231. instance->data_markup[ind].byte_bias = byte_bias;
  232. byte_bias += subghz_protocol_bin_raw_get_full_byte(temp_data);
  233. if(!flipper_format_read_hex(
  234. flipper_format,
  235. "Data_RAW",
  236. instance->data + instance->data_markup[ind].byte_bias,
  237. subghz_protocol_bin_raw_get_full_byte(temp_data))) {
  238. instance->data_markup[ind].bit_count = 0;
  239. FURI_LOG_E(TAG, "Missing Data_RAW");
  240. res = SubGhzProtocolStatusErrorParserOthers;
  241. break;
  242. }
  243. ind++;
  244. }
  245. #ifdef BIN_RAW_DEBUG
  246. uint16_t i = 0;
  247. bin_raw_debug_tag(TAG, "Download data to encoder\r\n");
  248. bin_raw_debug("\tind byte_bias\tbit_count\t\tbin_data");
  249. while((i < BIN_RAW_MAX_MARKUP_COUNT) && (instance->data_markup[i].bit_count != 0)) {
  250. bin_raw_debug(
  251. "\r\n\t%d\t%d\t%d :\t",
  252. i,
  253. instance->data_markup[i].byte_bias,
  254. instance->data_markup[i].bit_count);
  255. for(uint16_t y = instance->data_markup[i].byte_bias;
  256. y < instance->data_markup[i].byte_bias +
  257. subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count);
  258. y++) {
  259. bin_raw_debug("%02X ", instance->data[y]);
  260. }
  261. i++;
  262. }
  263. bin_raw_debug("\r\n\r\n");
  264. #endif
  265. if(!flipper_format_rewind(flipper_format)) {
  266. FURI_LOG_E(TAG, "Rewind error");
  267. res = SubGhzProtocolStatusErrorParserOthers;
  268. break;
  269. }
  270. //optional parameter parameter
  271. flipper_format_read_uint32(
  272. flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
  273. if(!subghz_protocol_encoder_bin_raw_get_upload(instance)) {
  274. break;
  275. res = SubGhzProtocolStatusErrorEncoderGetUpload;
  276. }
  277. instance->encoder.is_running = true;
  278. res = SubGhzProtocolStatusOk;
  279. } while(0);
  280. return res;
  281. }
  282. void subghz_protocol_encoder_bin_raw_stop(void* context) {
  283. SubGhzProtocolEncoderBinRAW* instance = context;
  284. instance->encoder.is_running = false;
  285. }
  286. LevelDuration subghz_protocol_encoder_bin_raw_yield(void* context) {
  287. SubGhzProtocolEncoderBinRAW* instance = context;
  288. if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
  289. instance->encoder.is_running = false;
  290. return level_duration_reset();
  291. }
  292. LevelDuration ret = instance->encoder.upload[instance->encoder.front];
  293. if(++instance->encoder.front == instance->encoder.size_upload) {
  294. instance->encoder.repeat--;
  295. instance->encoder.front = 0;
  296. }
  297. return ret;
  298. }
  299. void* subghz_protocol_decoder_bin_raw_alloc(SubGhzEnvironment* environment) {
  300. UNUSED(environment);
  301. SubGhzProtocolDecoderBinRAW* instance = malloc(sizeof(SubGhzProtocolDecoderBinRAW));
  302. instance->base.protocol = &subghz_protocol_bin_raw;
  303. instance->generic.protocol_name = instance->base.protocol->name;
  304. instance->data_raw_ind = 0;
  305. instance->data_raw = malloc(BIN_RAW_BUF_RAW_SIZE * sizeof(int32_t));
  306. instance->data = malloc(BIN_RAW_BUF_RAW_SIZE * sizeof(uint8_t));
  307. memset(instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  308. instance->adaptive_threshold_rssi = BIN_RAW_THRESHOLD_RSSI;
  309. return instance;
  310. }
  311. void subghz_protocol_decoder_bin_raw_free(void* context) {
  312. furi_assert(context);
  313. SubGhzProtocolDecoderBinRAW* instance = context;
  314. free(instance->data_raw);
  315. free(instance->data);
  316. free(instance);
  317. }
  318. void subghz_protocol_decoder_bin_raw_reset(void* context) {
  319. furi_assert(context);
  320. SubGhzProtocolDecoderBinRAW* instance = context;
  321. #ifdef BIN_RAW_DEBUG
  322. UNUSED(instance);
  323. #else
  324. instance->decoder.parser_step = BinRAWDecoderStepNoParse;
  325. instance->data_raw_ind = 0;
  326. #endif
  327. }
  328. void subghz_protocol_decoder_bin_raw_feed(void* context, bool level, uint32_t duration) {
  329. furi_assert(context);
  330. SubGhzProtocolDecoderBinRAW* instance = context;
  331. if(instance->decoder.parser_step == BinRAWDecoderStepWrite) {
  332. if(instance->data_raw_ind == BIN_RAW_BUF_RAW_SIZE) {
  333. instance->decoder.parser_step = BinRAWDecoderStepBufFull;
  334. } else {
  335. instance->data_raw[instance->data_raw_ind++] = (level ? duration : -duration);
  336. }
  337. }
  338. }
  339. /**
  340. * Analysis of received data
  341. * @param instance Pointer to a SubGhzProtocolDecoderBinRAW* instance
  342. */
  343. static bool
  344. subghz_protocol_bin_raw_check_remote_controller(SubGhzProtocolDecoderBinRAW* instance) {
  345. struct {
  346. float data;
  347. uint16_t count;
  348. } classes[BIN_RAW_SEARCH_CLASSES];
  349. size_t ind = 0;
  350. memset(classes, 0x00, sizeof(classes));
  351. uint16_t data_markup_ind = 0;
  352. memset(instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  353. if(instance->data_raw_ind < 512) {
  354. ind =
  355. instance->data_raw_ind -
  356. 100; //there is usually garbage at the end of the record, we exclude it from the classification
  357. } else {
  358. ind = 512;
  359. }
  360. //sort the durations to find the shortest correlated interval
  361. for(size_t i = 0; i < ind; i++) {
  362. for(size_t k = 0; k < BIN_RAW_SEARCH_CLASSES; k++) {
  363. if(classes[k].count == 0) {
  364. classes[k].data = (float)(abs(instance->data_raw[i]));
  365. classes[k].count++;
  366. break;
  367. } else if(
  368. DURATION_DIFF((float)(abs(instance->data_raw[i])), (classes[k].data)) <
  369. (classes[k].data / 4)) { //if the test value does not differ by more than 25%
  370. classes[k].data += ((float)(abs(instance->data_raw[i])) - classes[k].data) *
  371. 0.05f; //running average k=0.05
  372. classes[k].count++;
  373. break;
  374. }
  375. }
  376. }
  377. // if(classes[BIN_RAW_SEARCH_CLASSES - 1].count != 0) {
  378. // //filling the classifier, it means that they received an unclean signal
  379. // return false;
  380. // }
  381. //looking for the minimum te with an occurrence greater than BIN_RAW_TE_MIN_COUNT
  382. instance->te = subghz_protocol_bin_raw_const.te_long * 2;
  383. bool te_ok = false;
  384. uint16_t gap_ind = 0;
  385. uint16_t gap_delta = 0;
  386. uint32_t gap = 0;
  387. int data_temp = 0;
  388. BinRAWType bin_raw_type = BinRAWTypeUnknown;
  389. //sort by number of occurrences
  390. bool swap = true;
  391. while(swap) {
  392. swap = false;
  393. for(size_t i = 1; i < BIN_RAW_SEARCH_CLASSES; i++) {
  394. if(classes[i].count > classes[i - 1].count) {
  395. uint32_t data = classes[i - 1].data;
  396. uint32_t count = classes[i - 1].count;
  397. classes[i - 1].data = classes[i].data;
  398. classes[i - 1].count = classes[i].count;
  399. classes[i].data = data;
  400. classes[i].count = count;
  401. swap = true;
  402. }
  403. }
  404. }
  405. #ifdef BIN_RAW_DEBUG
  406. bin_raw_debug_tag(TAG, "Sorted durations\r\n");
  407. bin_raw_debug("\t\tind\tcount\tus\r\n");
  408. for(size_t k = 0; k < BIN_RAW_SEARCH_CLASSES; k++) {
  409. bin_raw_debug("\t\t%zu\t%u\t%lu\r\n", k, classes[k].count, (uint32_t)classes[k].data);
  410. }
  411. bin_raw_debug("\r\n");
  412. #endif
  413. if((classes[0].count > BIN_RAW_TE_MIN_COUNT) && (classes[1].count == 0)) {
  414. //adopted only the preamble
  415. instance->te = (uint32_t)classes[0].data;
  416. te_ok = true;
  417. gap = 0; //gap no
  418. } else {
  419. //take the 2 most common durations
  420. //check that there are enough
  421. if((classes[0].count < BIN_RAW_TE_MIN_COUNT) ||
  422. (classes[1].count < (BIN_RAW_TE_MIN_COUNT >> 1)))
  423. return false;
  424. //arrange the first 2 date values in ascending order
  425. if(classes[0].data > classes[1].data) {
  426. uint32_t data = classes[1].data;
  427. classes[0].data = classes[1].data;
  428. classes[1].data = data;
  429. }
  430. //determine the value to be corrected
  431. for(uint8_t k = 1; k < 5; k++) {
  432. float delta = (classes[1].data / (classes[0].data / k));
  433. bin_raw_debug_tag(TAG, "K_div= %f\r\n", (double)(delta));
  434. delta -= (uint32_t)delta;
  435. if((delta < 0.20f) || (delta > 0.80f)) {
  436. instance->te = (uint32_t)classes[0].data / k;
  437. bin_raw_debug_tag(TAG, "K= %d\r\n", k);
  438. te_ok = true; //found a correlated duration
  439. break;
  440. }
  441. }
  442. if(!te_ok) {
  443. //did not find the minimum TE satisfying the condition
  444. return false;
  445. }
  446. bin_raw_debug_tag(TAG, "TE= %lu\r\n\r\n", instance->te);
  447. //looking for a gap
  448. for(size_t k = 2; k < BIN_RAW_SEARCH_CLASSES; k++) {
  449. if((classes[k].count > 2) && (classes[k].data > gap)) {
  450. gap = (uint32_t)classes[k].data;
  451. gap_delta = gap / 5; //calculate 20% deviation from ideal value
  452. }
  453. }
  454. if((gap / instance->te) <
  455. 10) { //make an assumption, the longest gap should be more than 10 TE
  456. gap = 0; //check that our signal has a gap greater than 10*TE
  457. bin_raw_type = BinRAWTypeNoGap;
  458. } else {
  459. bin_raw_type = BinRAWTypeGap;
  460. //looking for the last occurrence of gap
  461. ind = instance->data_raw_ind - 1;
  462. while((ind > 0) && (DURATION_DIFF(abs(instance->data_raw[ind]), gap) > gap_delta)) {
  463. ind--;
  464. }
  465. gap_ind = ind;
  466. }
  467. }
  468. //if we consider that there is a gap, then we divide the signal with respect to this gap
  469. //processing input data from the end
  470. if(bin_raw_type == BinRAWTypeGap) {
  471. bin_raw_debug_tag(TAG, "Tinted sequence\r\n");
  472. ind = (BIN_RAW_BUF_DATA_SIZE * 8);
  473. uint16_t bit_count = 0;
  474. do {
  475. gap_ind--;
  476. data_temp = (int)(round((float)(instance->data_raw[gap_ind]) / instance->te));
  477. bin_raw_debug("%d ", data_temp);
  478. if(data_temp == 0) bit_count++; //there is noise in the package
  479. for(size_t i = 0; i < abs(data_temp); i++) {
  480. bit_count++;
  481. if(ind) {
  482. ind--;
  483. } else {
  484. break;
  485. }
  486. if(data_temp > 0) {
  487. subghz_protocol_blocks_set_bit_array(
  488. true, instance->data, ind, BIN_RAW_BUF_DATA_SIZE);
  489. } else {
  490. subghz_protocol_blocks_set_bit_array(
  491. false, instance->data, ind, BIN_RAW_BUF_DATA_SIZE);
  492. }
  493. }
  494. //split into full bytes if gap is caught
  495. if(DURATION_DIFF(abs(instance->data_raw[gap_ind]), gap) < gap_delta) {
  496. instance->data_markup[data_markup_ind].byte_bias = ind >> 3;
  497. instance->data_markup[data_markup_ind++].bit_count = bit_count;
  498. bit_count = 0;
  499. if(data_markup_ind == BIN_RAW_MAX_MARKUP_COUNT) break;
  500. ind &= 0xFFFFFFF8; //jump to the pre whole byte
  501. }
  502. } while(gap_ind != 0);
  503. if((data_markup_ind != BIN_RAW_MAX_MARKUP_COUNT) && (ind != 0)) {
  504. instance->data_markup[data_markup_ind].byte_bias = ind >> 3;
  505. instance->data_markup[data_markup_ind++].bit_count = bit_count;
  506. }
  507. bin_raw_debug("\r\n\t count bit= %zu\r\n\r\n", (BIN_RAW_BUF_DATA_SIZE * 8) - ind);
  508. //reset the classifier and classify the received data
  509. memset(classes, 0x00, sizeof(classes));
  510. bin_raw_debug_tag(TAG, "Sort the found pieces by the number of bits in them\r\n");
  511. for(size_t i = 0; i < data_markup_ind; i++) {
  512. for(size_t k = 0; k < BIN_RAW_SEARCH_CLASSES; k++) {
  513. if(classes[k].count == 0) {
  514. classes[k].data = instance->data_markup[i].bit_count;
  515. classes[k].count++;
  516. break;
  517. } else if(instance->data_markup[i].bit_count == (uint16_t)classes[k].data) {
  518. classes[k].count++;
  519. break;
  520. }
  521. }
  522. }
  523. #ifdef BIN_RAW_DEBUG
  524. bin_raw_debug("\t\tind\tcount\tus\r\n");
  525. for(size_t k = 0; k < BIN_RAW_SEARCH_CLASSES; k++) {
  526. bin_raw_debug("\t\t%zu\t%u\t%lu\r\n", k, classes[k].count, (uint32_t)classes[k].data);
  527. }
  528. bin_raw_debug("\r\n");
  529. #endif
  530. //choose the value with the maximum repetition
  531. data_temp = 0;
  532. for(size_t i = 0; i < BIN_RAW_SEARCH_CLASSES; i++) {
  533. if((classes[i].count > 1) && (data_temp < classes[i].count))
  534. data_temp = (int)classes[i].data;
  535. }
  536. //if(data_markup_ind == 0) return false;
  537. #ifdef BIN_RAW_DEBUG
  538. //output in reverse order
  539. bin_raw_debug_tag(TAG, "Found sequences\r\n");
  540. bin_raw_debug("\tind byte_bias\tbit_count\t\tbin_data\r\n");
  541. uint16_t data_markup_ind_temp = data_markup_ind;
  542. if(data_markup_ind) {
  543. data_markup_ind_temp--;
  544. for(size_t i = (ind / 8); i < BIN_RAW_BUF_DATA_SIZE; i++) {
  545. if(instance->data_markup[data_markup_ind_temp].byte_bias == i) {
  546. bin_raw_debug(
  547. "\r\n\t%d\t%d\t%d :\t",
  548. data_markup_ind_temp,
  549. instance->data_markup[data_markup_ind_temp].byte_bias,
  550. instance->data_markup[data_markup_ind_temp].bit_count);
  551. if(data_markup_ind_temp != 0) data_markup_ind_temp--;
  552. }
  553. bin_raw_debug("%02X ", instance->data[i]);
  554. }
  555. bin_raw_debug("\r\n\r\n");
  556. }
  557. //compare data in chunks with the same number of bits
  558. bin_raw_debug_tag(TAG, "Analyze sequences of long %d bit\r\n\r\n", data_temp);
  559. #endif
  560. //if(data_temp == 0) data_temp = (int)classes[0].data;
  561. if(data_temp != 0) {
  562. //check that data in transmission is repeated every packet
  563. for(uint16_t i = 0; i < data_markup_ind - 1; i++) {
  564. if((instance->data_markup[i].bit_count == data_temp) &&
  565. (instance->data_markup[i + 1].bit_count == data_temp)) {
  566. //if the number of bits in adjacent parcels is the same, compare the data
  567. bin_raw_debug_tag(
  568. TAG,
  569. "Comparison of neighboring sequences ind_1=%d ind_2=%d %02X=%02X .... %02X=%02X\r\n",
  570. i,
  571. i + 1,
  572. instance->data[instance->data_markup[i].byte_bias],
  573. instance->data[instance->data_markup[i + 1].byte_bias],
  574. instance->data
  575. [instance->data_markup[i].byte_bias +
  576. subghz_protocol_bin_raw_get_full_byte(
  577. instance->data_markup[i].bit_count) -
  578. 1],
  579. instance->data
  580. [instance->data_markup[i + 1].byte_bias +
  581. subghz_protocol_bin_raw_get_full_byte(
  582. instance->data_markup[i + 1].bit_count) -
  583. 1]);
  584. uint16_t byte_count =
  585. subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count);
  586. if(memcmp(
  587. instance->data + instance->data_markup[i].byte_bias,
  588. instance->data + instance->data_markup[i + 1].byte_bias,
  589. byte_count - 1) == 0) {
  590. bin_raw_debug_tag(
  591. TAG, "Match found bin_raw_type=BinRAWTypeGapRecurring\r\n\r\n");
  592. //place in 1 element the offset to valid data
  593. instance->data_markup[0].bit_count = instance->data_markup[i].bit_count;
  594. instance->data_markup[0].byte_bias = instance->data_markup[i].byte_bias;
  595. //markup end sign
  596. instance->data_markup[1].bit_count = 0;
  597. instance->data_markup[1].byte_bias = 0;
  598. bin_raw_type = BinRAWTypeGapRecurring;
  599. i = data_markup_ind;
  600. break;
  601. }
  602. }
  603. }
  604. }
  605. if(bin_raw_type == BinRAWTypeGap) {
  606. // check that retry occurs every n packets
  607. for(uint16_t i = 0; i < data_markup_ind - 2; i++) {
  608. uint16_t byte_count =
  609. subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count);
  610. for(uint16_t y = i + 1; y < data_markup_ind - 1; y++) {
  611. bin_raw_debug_tag(
  612. TAG,
  613. "Comparison every N sequences ind_1=%d ind_2=%d %02X=%02X .... %02X=%02X\r\n",
  614. i,
  615. y,
  616. instance->data[instance->data_markup[i].byte_bias],
  617. instance->data[instance->data_markup[y].byte_bias],
  618. instance->data
  619. [instance->data_markup[i].byte_bias +
  620. subghz_protocol_bin_raw_get_full_byte(
  621. instance->data_markup[i].bit_count) -
  622. 1],
  623. instance->data
  624. [instance->data_markup[y].byte_bias +
  625. subghz_protocol_bin_raw_get_full_byte(
  626. instance->data_markup[y].bit_count) -
  627. 1]);
  628. if(byte_count ==
  629. subghz_protocol_bin_raw_get_full_byte(
  630. instance->data_markup[y].bit_count)) { //if the length in bytes matches
  631. if((memcmp(
  632. instance->data + instance->data_markup[i].byte_bias,
  633. instance->data + instance->data_markup[y].byte_bias,
  634. byte_count - 1) == 0) &&
  635. (memcmp(
  636. instance->data + instance->data_markup[i + 1].byte_bias,
  637. instance->data + instance->data_markup[y + 1].byte_bias,
  638. byte_count - 1) == 0)) {
  639. uint8_t index = 0;
  640. #ifdef BIN_RAW_DEBUG
  641. bin_raw_debug_tag(
  642. TAG, "Match found bin_raw_type=BinRAWTypeGapRolling\r\n\r\n");
  643. //output in reverse order
  644. bin_raw_debug("\tind byte_bias\tbit_count\t\tbin_data\r\n");
  645. index = y - 1;
  646. for(size_t z = instance->data_markup[y].byte_bias + byte_count;
  647. z < instance->data_markup[i].byte_bias + byte_count;
  648. z++) {
  649. if(instance->data_markup[index].byte_bias == z) {
  650. bin_raw_debug(
  651. "\r\n\t%d\t%d\t%d :\t",
  652. index,
  653. instance->data_markup[index].byte_bias,
  654. instance->data_markup[index].bit_count);
  655. if(index != 0) index--;
  656. }
  657. bin_raw_debug("%02X ", instance->data[z]);
  658. }
  659. bin_raw_debug("\r\n\r\n");
  660. #endif
  661. //todo can be optimized
  662. BinRAW_Markup markup_temp[BIN_RAW_MAX_MARKUP_COUNT];
  663. memcpy(
  664. markup_temp,
  665. instance->data_markup,
  666. BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  667. memset(
  668. instance->data_markup,
  669. 0x00,
  670. BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  671. for(index = i; index < y; index++) {
  672. instance->data_markup[index - i].bit_count =
  673. markup_temp[y - index - 1].bit_count;
  674. instance->data_markup[index - i].byte_bias =
  675. markup_temp[y - index - 1].byte_bias;
  676. }
  677. bin_raw_type = BinRAWTypeGapRolling;
  678. i = data_markup_ind;
  679. break;
  680. }
  681. }
  682. }
  683. }
  684. }
  685. //todo can be optimized
  686. if(bin_raw_type == BinRAWTypeGap) {
  687. if(data_temp != 0) { //there are sequences with the same number of bits
  688. BinRAW_Markup markup_temp[BIN_RAW_MAX_MARKUP_COUNT];
  689. memcpy(
  690. markup_temp,
  691. instance->data_markup,
  692. BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  693. memset(
  694. instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  695. uint16_t byte_count = subghz_protocol_bin_raw_get_full_byte(data_temp);
  696. uint16_t index = 0;
  697. uint16_t it = BIN_RAW_MAX_MARKUP_COUNT;
  698. do {
  699. it--;
  700. if(subghz_protocol_bin_raw_get_full_byte(markup_temp[it].bit_count) ==
  701. byte_count) {
  702. instance->data_markup[index].bit_count = markup_temp[it].bit_count;
  703. instance->data_markup[index].byte_bias = markup_temp[it].byte_bias;
  704. index++;
  705. bin_raw_type = BinRAWTypeGapUnknown;
  706. }
  707. } while(it != 0);
  708. }
  709. }
  710. if(bin_raw_type != BinRAWTypeGap)
  711. return true;
  712. else
  713. return false;
  714. } else {
  715. // if bin_raw_type == BinRAWTypeGap
  716. bin_raw_debug_tag(TAG, "Sequence analysis without gap\r\n");
  717. ind = 0;
  718. for(size_t i = 0; i < instance->data_raw_ind; i++) {
  719. int data_temp = (int)(round((float)(instance->data_raw[i]) / instance->te));
  720. if(data_temp == 0) break; //found an interval 2 times shorter than TE, this is noise
  721. bin_raw_debug("%d ", data_temp);
  722. for(size_t k = 0; k < abs(data_temp); k++) {
  723. if(data_temp > 0) {
  724. subghz_protocol_blocks_set_bit_array(
  725. true, instance->data, ind++, BIN_RAW_BUF_DATA_SIZE);
  726. } else {
  727. subghz_protocol_blocks_set_bit_array(
  728. false, instance->data, ind++, BIN_RAW_BUF_DATA_SIZE);
  729. }
  730. if(ind == BIN_RAW_BUF_DATA_SIZE * 8) {
  731. i = instance->data_raw_ind;
  732. break;
  733. }
  734. }
  735. }
  736. if(ind != 0) {
  737. bin_raw_type = BinRAWTypeNoGap;
  738. //right alignment
  739. uint8_t bit_bias = (subghz_protocol_bin_raw_get_full_byte(ind) << 3) - ind;
  740. #ifdef BIN_RAW_DEBUG
  741. bin_raw_debug(
  742. "\r\n\t count bit= %zu\tcount full byte= %d\tbias bit= %d\r\n\r\n",
  743. ind,
  744. subghz_protocol_bin_raw_get_full_byte(ind),
  745. bit_bias);
  746. for(size_t i = 0; i < subghz_protocol_bin_raw_get_full_byte(ind); i++) {
  747. bin_raw_debug("%02X ", instance->data[i]);
  748. }
  749. bin_raw_debug("\r\n\r\n");
  750. #endif
  751. //checking that the received sequence contains useful data
  752. bool data_check = false;
  753. for(size_t i = 0; i < subghz_protocol_bin_raw_get_full_byte(ind); i++) {
  754. if(instance->data[i] != 0) {
  755. data_check = true;
  756. break;
  757. }
  758. }
  759. if(data_check) {
  760. for(size_t i = subghz_protocol_bin_raw_get_full_byte(ind) - 1; i > 0; i--) {
  761. instance->data[i] = (instance->data[i - 1] << (8 - bit_bias)) |
  762. (instance->data[i] >> bit_bias);
  763. }
  764. instance->data[0] = (instance->data[0] >> bit_bias);
  765. #ifdef BIN_RAW_DEBUG
  766. bin_raw_debug_tag(TAG, "Data right alignment\r\n");
  767. for(size_t i = 0; i < subghz_protocol_bin_raw_get_full_byte(ind); i++) {
  768. bin_raw_debug("%02X ", instance->data[i]);
  769. }
  770. bin_raw_debug("\r\n\r\n");
  771. #endif
  772. instance->data_markup[0].bit_count = ind;
  773. instance->data_markup[0].byte_bias = 0;
  774. return true;
  775. } else {
  776. return false;
  777. }
  778. } else {
  779. return false;
  780. }
  781. }
  782. return false;
  783. }
  784. void subghz_protocol_decoder_bin_raw_data_input_rssi(
  785. SubGhzProtocolDecoderBinRAW* instance,
  786. float rssi) {
  787. furi_assert(instance);
  788. switch(instance->decoder.parser_step) {
  789. case BinRAWDecoderStepReset:
  790. bin_raw_debug("%ld %ld :", (int32_t)rssi, (int32_t)instance->adaptive_threshold_rssi);
  791. if(rssi > (instance->adaptive_threshold_rssi + BIN_RAW_DELTA_RSSI)) {
  792. instance->data_raw_ind = 0;
  793. memset(instance->data_raw, 0x00, BIN_RAW_BUF_RAW_SIZE * sizeof(int32_t));
  794. memset(instance->data, 0x00, BIN_RAW_BUF_RAW_SIZE * sizeof(uint8_t));
  795. instance->decoder.parser_step = BinRAWDecoderStepWrite;
  796. bin_raw_debug_tag(TAG, "RSSI\r\n");
  797. } else {
  798. //adaptive noise level adjustment
  799. instance->adaptive_threshold_rssi += (rssi - instance->adaptive_threshold_rssi) * 0.2f;
  800. }
  801. break;
  802. case BinRAWDecoderStepBufFull:
  803. case BinRAWDecoderStepWrite:
  804. #ifdef BIN_RAW_DEBUG
  805. if(rssi > (instance->adaptive_threshold_rssi + BIN_RAW_DELTA_RSSI)) {
  806. bin_raw_debug("\033[0;32m%ld \033[0m ", (int32_t)rssi);
  807. } else {
  808. bin_raw_debug("%ld ", (int32_t)rssi);
  809. }
  810. #endif
  811. if(rssi < instance->adaptive_threshold_rssi + BIN_RAW_DELTA_RSSI) {
  812. #ifdef BIN_RAW_DEBUG
  813. bin_raw_debug("\r\n\r\n");
  814. bin_raw_debug_tag(TAG, "Data for analysis, positive high, negative low, us\r\n");
  815. for(size_t i = 0; i < instance->data_raw_ind; i++) {
  816. bin_raw_debug("%ld ", instance->data_raw[i]);
  817. }
  818. bin_raw_debug("\r\n\t count data= %zu\r\n\r\n", instance->data_raw_ind);
  819. #endif
  820. instance->decoder.parser_step = BinRAWDecoderStepReset;
  821. instance->generic.data_count_bit = 0;
  822. if(instance->data_raw_ind >= BIN_RAW_BUF_MIN_DATA_COUNT) {
  823. if(subghz_protocol_bin_raw_check_remote_controller(instance)) {
  824. bin_raw_debug_tag(TAG, "Sequence found\r\n");
  825. bin_raw_debug("\tind byte_bias\tbit_count\t\tbin_data");
  826. uint16_t i = 0;
  827. while((i < BIN_RAW_MAX_MARKUP_COUNT) &&
  828. (instance->data_markup[i].bit_count != 0)) {
  829. instance->generic.data_count_bit += instance->data_markup[i].bit_count;
  830. #ifdef BIN_RAW_DEBUG
  831. bin_raw_debug(
  832. "\r\n\t%d\t%d\t%d :\t",
  833. i,
  834. instance->data_markup[i].byte_bias,
  835. instance->data_markup[i].bit_count);
  836. for(uint16_t y = instance->data_markup[i].byte_bias;
  837. y < instance->data_markup[i].byte_bias +
  838. subghz_protocol_bin_raw_get_full_byte(
  839. instance->data_markup[i].bit_count);
  840. y++) {
  841. bin_raw_debug("%02X ", instance->data[y]);
  842. }
  843. #endif
  844. i++;
  845. }
  846. bin_raw_debug("\r\n");
  847. if(instance->base.callback)
  848. instance->base.callback(&instance->base, instance->base.context);
  849. }
  850. }
  851. }
  852. break;
  853. default:
  854. //if instance->decoder.parser_step == BinRAWDecoderStepNoParse or others, restore the initial state
  855. if(rssi < instance->adaptive_threshold_rssi + BIN_RAW_DELTA_RSSI) {
  856. instance->decoder.parser_step = BinRAWDecoderStepReset;
  857. }
  858. break;
  859. }
  860. }
  861. uint8_t subghz_protocol_decoder_bin_raw_get_hash_data(void* context) {
  862. furi_assert(context);
  863. SubGhzProtocolDecoderBinRAW* instance = context;
  864. return subghz_protocol_blocks_add_bytes(
  865. instance->data + instance->data_markup[0].byte_bias,
  866. subghz_protocol_bin_raw_get_full_byte(instance->data_markup[0].bit_count));
  867. }
  868. SubGhzProtocolStatus subghz_protocol_decoder_bin_raw_serialize(
  869. void* context,
  870. FlipperFormat* flipper_format,
  871. SubGhzRadioPreset* preset) {
  872. furi_assert(context);
  873. SubGhzProtocolDecoderBinRAW* instance = context;
  874. SubGhzProtocolStatus res = SubGhzProtocolStatusError;
  875. FuriString* temp_str;
  876. temp_str = furi_string_alloc();
  877. do {
  878. stream_clean(flipper_format_get_raw_stream(flipper_format));
  879. if(!flipper_format_write_header_cstr(
  880. flipper_format, SUBGHZ_KEY_FILE_TYPE, SUBGHZ_KEY_FILE_VERSION)) {
  881. FURI_LOG_E(TAG, "Unable to add header");
  882. res = SubGhzProtocolStatusErrorParserHeader;
  883. break;
  884. }
  885. if(!flipper_format_write_uint32(flipper_format, "Frequency", &preset->frequency, 1)) {
  886. FURI_LOG_E(TAG, "Unable to add Frequency");
  887. res = SubGhzProtocolStatusErrorParserFrequency;
  888. break;
  889. }
  890. subghz_block_generic_get_preset_name(furi_string_get_cstr(preset->name), temp_str);
  891. if(!flipper_format_write_string_cstr(
  892. flipper_format, "Preset", furi_string_get_cstr(temp_str))) {
  893. FURI_LOG_E(TAG, "Unable to add Preset");
  894. res = SubGhzProtocolStatusErrorParserPreset;
  895. break;
  896. }
  897. if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) {
  898. if(!flipper_format_write_string_cstr(
  899. flipper_format, "Custom_preset_module", "CC1101")) {
  900. FURI_LOG_E(TAG, "Unable to add Custom_preset_module");
  901. res = SubGhzProtocolStatusErrorParserCustomPreset;
  902. break;
  903. }
  904. if(!flipper_format_write_hex(
  905. flipper_format, "Custom_preset_data", preset->data, preset->data_size)) {
  906. FURI_LOG_E(TAG, "Unable to add Custom_preset_data");
  907. res = SubGhzProtocolStatusErrorParserCustomPreset;
  908. break;
  909. }
  910. }
  911. if(!flipper_format_write_string_cstr(
  912. flipper_format, "Protocol", instance->generic.protocol_name)) {
  913. FURI_LOG_E(TAG, "Unable to add Protocol");
  914. res = SubGhzProtocolStatusErrorParserProtocolName;
  915. break;
  916. }
  917. uint32_t temp = instance->generic.data_count_bit;
  918. if(!flipper_format_write_uint32(flipper_format, "Bit", &temp, 1)) {
  919. FURI_LOG_E(TAG, "Unable to add Bit");
  920. res = SubGhzProtocolStatusErrorParserBitCount;
  921. break;
  922. }
  923. if(!flipper_format_write_uint32(flipper_format, "TE", &instance->te, 1)) {
  924. FURI_LOG_E(TAG, "Unable to add TE");
  925. res = SubGhzProtocolStatusErrorParserTe;
  926. break;
  927. }
  928. uint16_t i = 0;
  929. while((i < BIN_RAW_MAX_MARKUP_COUNT) && (instance->data_markup[i].bit_count != 0)) {
  930. temp = instance->data_markup[i].bit_count;
  931. if(!flipper_format_write_uint32(flipper_format, "Bit_RAW", &temp, 1)) {
  932. FURI_LOG_E(TAG, "Bit_RAW");
  933. res = SubGhzProtocolStatusErrorParserOthers;
  934. break;
  935. }
  936. if(!flipper_format_write_hex(
  937. flipper_format,
  938. "Data_RAW",
  939. instance->data + instance->data_markup[i].byte_bias,
  940. subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count))) {
  941. FURI_LOG_E(TAG, "Unable to add Data_RAW");
  942. res = SubGhzProtocolStatusErrorParserOthers;
  943. break;
  944. }
  945. i++;
  946. }
  947. res = SubGhzProtocolStatusOk;
  948. } while(false);
  949. furi_string_free(temp_str);
  950. return res;
  951. }
  952. SubGhzProtocolStatus
  953. subghz_protocol_decoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format) {
  954. furi_assert(context);
  955. SubGhzProtocolDecoderBinRAW* instance = context;
  956. SubGhzProtocolStatus res = SubGhzProtocolStatusError;
  957. uint32_t temp_data = 0;
  958. do {
  959. if(!flipper_format_rewind(flipper_format)) {
  960. FURI_LOG_E(TAG, "Rewind error");
  961. res = SubGhzProtocolStatusErrorParserOthers;
  962. break;
  963. }
  964. if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) {
  965. FURI_LOG_E(TAG, "Missing Bit");
  966. res = SubGhzProtocolStatusErrorParserBitCount;
  967. break;
  968. }
  969. instance->generic.data_count_bit = (uint16_t)temp_data;
  970. if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) {
  971. FURI_LOG_E(TAG, "Missing TE");
  972. res = SubGhzProtocolStatusErrorParserTe;
  973. break;
  974. }
  975. temp_data = 0;
  976. uint16_t ind = 0;
  977. uint16_t byte_bias = 0;
  978. uint16_t byte_count = 0;
  979. memset(instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup));
  980. while(flipper_format_read_uint32(flipper_format, "Bit_RAW", (uint32_t*)&temp_data, 1)) {
  981. if(ind >= BIN_RAW_MAX_MARKUP_COUNT) {
  982. FURI_LOG_E(TAG, "Markup overflow");
  983. res = SubGhzProtocolStatusErrorParserOthers;
  984. break;
  985. }
  986. byte_count += subghz_protocol_bin_raw_get_full_byte(temp_data);
  987. if(byte_count > BIN_RAW_BUF_DATA_SIZE) {
  988. FURI_LOG_E(TAG, "Receive buffer overflow");
  989. res = SubGhzProtocolStatusErrorParserOthers;
  990. break;
  991. }
  992. instance->data_markup[ind].bit_count = temp_data;
  993. instance->data_markup[ind].byte_bias = byte_bias;
  994. byte_bias += subghz_protocol_bin_raw_get_full_byte(temp_data);
  995. if(!flipper_format_read_hex(
  996. flipper_format,
  997. "Data_RAW",
  998. instance->data + instance->data_markup[ind].byte_bias,
  999. subghz_protocol_bin_raw_get_full_byte(temp_data))) {
  1000. instance->data_markup[ind].bit_count = 0;
  1001. FURI_LOG_E(TAG, "Missing Data_RAW");
  1002. res = SubGhzProtocolStatusErrorParserOthers;
  1003. break;
  1004. }
  1005. ind++;
  1006. }
  1007. res = SubGhzProtocolStatusOk;
  1008. } while(0);
  1009. return res;
  1010. }
  1011. void subghz_protocol_decoder_bin_raw_get_string(void* context, FuriString* output) {
  1012. furi_assert(context);
  1013. SubGhzProtocolDecoderBinRAW* instance = context;
  1014. furi_string_cat_printf(
  1015. output,
  1016. "%s %dbit\r\n"
  1017. "Key:",
  1018. instance->generic.protocol_name,
  1019. instance->generic.data_count_bit);
  1020. uint16_t byte_count = subghz_protocol_bin_raw_get_full_byte(instance->generic.data_count_bit);
  1021. for(size_t i = 0; (byte_count < 36 ? i < byte_count : i < 36); i++) {
  1022. furi_string_cat_printf(output, "%02X", instance->data[i]);
  1023. }
  1024. furi_string_cat_printf(output, "\r\nTe:%luus\r\n", instance->te);
  1025. }