subghz_setting.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. #include "subghz_setting.h"
  2. #include "subghz_i.h"
  3. #include <furi.h>
  4. #include <m-list.h>
  5. #include <lib/flipper_format/flipper_format.h>
  6. #define TAG "SubGhzSetting"
  7. #define SUBGHZ_SETTING_FILE_TYPE "Flipper SubGhz Setting File"
  8. #define SUBGHZ_SETTING_FILE_VERSION 1
  9. #define FREQUENCY_FLAG_DEFAULT (1 << 31)
  10. #define FREQUENCY_MASK (0xFFFFFFFF ^ FREQUENCY_FLAG_DEFAULT)
  11. /* Default */
  12. static const uint32_t subghz_frequency_list[] = {
  13. /* 300 - 348 */
  14. 300000000,
  15. 303875000,
  16. 304250000,
  17. 310000000,
  18. 315000000,
  19. 318000000,
  20. /* 387 - 464 */
  21. 390000000,
  22. 418000000,
  23. 433075000, /* LPD433 first */
  24. 433420000,
  25. 433920000 | FREQUENCY_FLAG_DEFAULT, /* LPD433 mid */
  26. 434420000,
  27. 434775000, /* LPD433 last channels */
  28. 438900000,
  29. /* 779 - 928 */
  30. 868350000,
  31. 915000000,
  32. 925000000,
  33. 0,
  34. };
  35. static const uint32_t subghz_hopper_frequency_list[] = {
  36. 310000000,
  37. 315000000,
  38. 318000000,
  39. 390000000,
  40. 433920000,
  41. 868350000,
  42. 0,
  43. };
  44. /* Europe and Russia */
  45. static const uint32_t subghz_frequency_list_region_eu_ru[] = {
  46. /* 300 - 348 */
  47. 300000000,
  48. 303875000,
  49. 304250000,
  50. 310000000,
  51. 315000000,
  52. 318000000,
  53. /* 387 - 464 */
  54. 390000000,
  55. 418000000,
  56. 433075000, /* LPD433 first */
  57. 433420000,
  58. 433920000 | FREQUENCY_FLAG_DEFAULT, /* LPD433 mid */
  59. 434420000,
  60. 434775000, /* LPD433 last channels */
  61. 438900000,
  62. /* 779 - 928 */
  63. 868350000,
  64. 915000000,
  65. 925000000,
  66. 0,
  67. };
  68. static const uint32_t subghz_hopper_frequency_list_region_eu_ru[] = {
  69. 310000000,
  70. 315000000,
  71. 318000000,
  72. 390000000,
  73. 433920000,
  74. 868350000,
  75. 0,
  76. };
  77. /* Region 0 */
  78. static const uint32_t subghz_frequency_list_region_us_ca_au[] = {
  79. /* 300 - 348 */
  80. 300000000,
  81. 303875000,
  82. 304250000,
  83. 310000000,
  84. 315000000,
  85. 318000000,
  86. /* 387 - 464 */
  87. 390000000,
  88. 418000000,
  89. 433075000, /* LPD433 first */
  90. 433420000,
  91. 433920000 | FREQUENCY_FLAG_DEFAULT, /* LPD433 mid */
  92. 434420000,
  93. 434775000, /* LPD433 last channels */
  94. 438900000,
  95. /* 779 - 928 */
  96. 868350000,
  97. 915000000,
  98. 925000000,
  99. 0,
  100. };
  101. static const uint32_t subghz_hopper_frequency_list_region_us_ca_au[] = {
  102. 310000000,
  103. 315000000,
  104. 318000000,
  105. 390000000,
  106. 433920000,
  107. 868350000,
  108. 0,
  109. };
  110. static const uint32_t subghz_frequency_list_region_jp[] = {
  111. /* 300 - 348 */
  112. 300000000,
  113. 303875000,
  114. 304250000,
  115. 310000000,
  116. 315000000,
  117. 318000000,
  118. /* 387 - 464 */
  119. 390000000,
  120. 418000000,
  121. 433075000, /* LPD433 first */
  122. 433420000,
  123. 433920000 | FREQUENCY_FLAG_DEFAULT, /* LPD433 mid */
  124. 434420000,
  125. 434775000, /* LPD433 last channels */
  126. 438900000,
  127. /* 779 - 928 */
  128. 868350000,
  129. 915000000,
  130. 925000000,
  131. 0,
  132. };
  133. static const uint32_t subghz_hopper_frequency_list_region_jp[] = {
  134. 310000000,
  135. 315000000,
  136. 318000000,
  137. 390000000,
  138. 433920000,
  139. 868350000,
  140. 0,
  141. };
  142. LIST_DEF(FrequencyList, uint32_t)
  143. #define M_OPL_FrequencyList_t() LIST_OPLIST(FrequencyList)
  144. struct SubGhzSetting {
  145. FrequencyList_t frequencies;
  146. FrequencyList_t hopper_frequencies;
  147. };
  148. SubGhzSetting* subghz_setting_alloc(void) {
  149. SubGhzSetting* instance = malloc(sizeof(SubGhzSetting));
  150. FrequencyList_init(instance->frequencies);
  151. FrequencyList_init(instance->hopper_frequencies);
  152. return instance;
  153. }
  154. void subghz_setting_free(SubGhzSetting* instance) {
  155. furi_assert(instance);
  156. FrequencyList_clear(instance->frequencies);
  157. FrequencyList_clear(instance->hopper_frequencies);
  158. free(instance);
  159. }
  160. static void subghz_setting_load_default_region(
  161. SubGhzSetting* instance,
  162. const uint32_t frequencies[],
  163. const uint32_t hopper_frequencies[]) {
  164. furi_assert(instance);
  165. FrequencyList_reset(instance->frequencies);
  166. FrequencyList_reset(instance->hopper_frequencies);
  167. while(*frequencies) {
  168. FrequencyList_push_back(instance->frequencies, *frequencies);
  169. frequencies++;
  170. }
  171. while(*hopper_frequencies) {
  172. FrequencyList_push_back(instance->hopper_frequencies, *hopper_frequencies);
  173. hopper_frequencies++;
  174. }
  175. }
  176. void subghz_setting_load_default(SubGhzSetting* instance) {
  177. switch(furi_hal_version_get_hw_region()) {
  178. case FuriHalVersionRegionEuRu:
  179. subghz_setting_load_default_region(
  180. instance,
  181. subghz_frequency_list_region_eu_ru,
  182. subghz_hopper_frequency_list_region_eu_ru);
  183. break;
  184. case FuriHalVersionRegionUsCaAu:
  185. subghz_setting_load_default_region(
  186. instance,
  187. subghz_frequency_list_region_us_ca_au,
  188. subghz_hopper_frequency_list_region_us_ca_au);
  189. break;
  190. case FuriHalVersionRegionJp:
  191. subghz_setting_load_default_region(
  192. instance, subghz_frequency_list_region_jp, subghz_hopper_frequency_list_region_jp);
  193. break;
  194. default:
  195. subghz_setting_load_default_region(
  196. instance, subghz_frequency_list, subghz_hopper_frequency_list);
  197. break;
  198. }
  199. }
  200. void subghz_setting_load(SubGhzSetting* instance, const char* file_path) {
  201. furi_assert(instance);
  202. Storage* storage = furi_record_open("storage");
  203. FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
  204. string_t temp_str;
  205. string_init(temp_str);
  206. uint32_t temp_data32;
  207. bool temp_bool;
  208. subghz_setting_load_default(instance);
  209. if(file_path) {
  210. do {
  211. if(!flipper_format_file_open_existing(fff_data_file, file_path)) {
  212. FURI_LOG_E(TAG, "Error open file %s", file_path);
  213. break;
  214. }
  215. if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) {
  216. FURI_LOG_E(TAG, "Missing or incorrect header");
  217. break;
  218. }
  219. if((!strcmp(string_get_cstr(temp_str), SUBGHZ_SETTING_FILE_TYPE)) &&
  220. temp_data32 == SUBGHZ_SETTING_FILE_VERSION) {
  221. } else {
  222. FURI_LOG_E(TAG, "Type or version mismatch");
  223. break;
  224. }
  225. // Standard frequencies (optional)
  226. temp_bool = true;
  227. flipper_format_read_bool(fff_data_file, "add_standard_frequencies", &temp_bool, 1);
  228. if(!temp_bool) {
  229. FURI_LOG_I(TAG, "Removing standard frequencies");
  230. FrequencyList_reset(instance->frequencies);
  231. FrequencyList_reset(instance->hopper_frequencies);
  232. } else {
  233. FURI_LOG_I(TAG, "Keeping standard frequencies");
  234. }
  235. // Load frequencies
  236. if(!flipper_format_rewind(fff_data_file)) {
  237. FURI_LOG_E(TAG, "Rewind error");
  238. break;
  239. }
  240. while(flipper_format_read_uint32(
  241. fff_data_file, "frequency", (uint32_t*)&temp_data32, 1)) {
  242. if(furi_hal_subghz_is_frequency_valid(temp_data32)) {
  243. FURI_LOG_I(TAG, "Frequency loaded %lu", temp_data32);
  244. FrequencyList_push_back(instance->frequencies, temp_data32);
  245. } else {
  246. FURI_LOG_E(TAG, "Frequency not supported %lu", temp_data32);
  247. }
  248. }
  249. // Load hopper frequencies
  250. if(!flipper_format_rewind(fff_data_file)) {
  251. FURI_LOG_E(TAG, "Rewind error");
  252. break;
  253. }
  254. while(flipper_format_read_uint32(
  255. fff_data_file, "hopper_frequency", (uint32_t*)&temp_data32, 1)) {
  256. if(furi_hal_subghz_is_frequency_valid(temp_data32)) {
  257. FURI_LOG_I(TAG, "Hopper frequency loaded %lu", temp_data32);
  258. FrequencyList_push_back(instance->hopper_frequencies, temp_data32);
  259. } else {
  260. FURI_LOG_E(TAG, "Hopper frequency not supported %lu", temp_data32);
  261. }
  262. }
  263. // Default frequency (optional)
  264. if(!flipper_format_rewind(fff_data_file)) {
  265. FURI_LOG_E(TAG, "Rewind error");
  266. break;
  267. }
  268. if(flipper_format_read_uint32(fff_data_file, "default_frequency", &temp_data32, 1)) {
  269. for
  270. M_EACH(frequency, instance->frequencies, FrequencyList_t) {
  271. *frequency &= FREQUENCY_MASK;
  272. if(*frequency == temp_data32) {
  273. *frequency |= FREQUENCY_FLAG_DEFAULT;
  274. }
  275. }
  276. }
  277. } while(false);
  278. }
  279. string_clear(temp_str);
  280. flipper_format_free(fff_data_file);
  281. furi_record_close("storage");
  282. if(!FrequencyList_size(instance->frequencies) ||
  283. !FrequencyList_size(instance->hopper_frequencies)) {
  284. FURI_LOG_E(TAG, "Error loading user settings, loading default settings");
  285. subghz_setting_load_default(instance);
  286. }
  287. }
  288. size_t subghz_setting_get_frequency_count(SubGhzSetting* instance) {
  289. furi_assert(instance);
  290. return FrequencyList_size(instance->frequencies);
  291. }
  292. size_t subghz_setting_get_hopper_frequency_count(SubGhzSetting* instance) {
  293. furi_assert(instance);
  294. return FrequencyList_size(instance->hopper_frequencies);
  295. }
  296. uint32_t subghz_setting_get_frequency(SubGhzSetting* instance, size_t idx) {
  297. furi_assert(instance);
  298. uint32_t* ret = FrequencyList_get(instance->frequencies, idx);
  299. if(ret) {
  300. return (*ret) & FREQUENCY_MASK;
  301. } else {
  302. return 0;
  303. }
  304. }
  305. uint32_t subghz_setting_get_hopper_frequency(SubGhzSetting* instance, size_t idx) {
  306. furi_assert(instance);
  307. uint32_t* ret = FrequencyList_get(instance->hopper_frequencies, idx);
  308. if(ret) {
  309. return *ret;
  310. } else {
  311. return 0;
  312. }
  313. }
  314. uint32_t subghz_setting_get_frequency_default_index(SubGhzSetting* instance) {
  315. furi_assert(instance);
  316. for(size_t i = 0; i < FrequencyList_size(instance->frequencies); i++) {
  317. uint32_t frequency = *FrequencyList_get(instance->frequencies, i);
  318. if(frequency & FREQUENCY_FLAG_DEFAULT) {
  319. return i;
  320. }
  321. }
  322. return 0;
  323. }
  324. uint32_t subghz_setting_get_default_frequency(SubGhzSetting* instance) {
  325. furi_assert(instance);
  326. return subghz_setting_get_frequency(
  327. instance, subghz_setting_get_frequency_default_index(instance));
  328. }