| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- #include "xremote_cross_remote.h"
- ARRAY_DEF(CrossRemoteItemArray, CrossRemoteItem*, M_PTR_OPLIST);
- struct CrossRemote {
- FuriString* name;
- FuriString* path;
- CrossRemoteItemArray_t items;
- int transmitting;
- };
- static void xremote_cross_remote_clear_items(CrossRemote* remote) {
- CrossRemoteItemArray_it_t it;
- for(CrossRemoteItemArray_it(it, remote->items); !CrossRemoteItemArray_end_p(it);
- CrossRemoteItemArray_next(it)) {
- xremote_cross_remote_item_free(*CrossRemoteItemArray_cref(it));
- }
- CrossRemoteItemArray_reset(remote->items);
- }
- static void xremote_cross_remote_find_vacant_remote_name(FuriString* name, const char* path) {
- Storage* storage = furi_record_open(RECORD_STORAGE);
- FuriString* base_path;
- base_path = furi_string_alloc_set(path);
- if(furi_string_end_with(base_path, XREMOTE_APP_EXTENSION)) {
- size_t filename_start = furi_string_search_rchar(base_path, '/');
- furi_string_left(base_path, filename_start);
- }
- furi_string_printf(
- base_path, "%s/%s%s", path, furi_string_get_cstr(name), XREMOTE_APP_EXTENSION);
- FS_Error status = storage_common_stat(storage, furi_string_get_cstr(base_path), NULL);
- if(status == FSE_OK) {
- // If name is taken, try another name2, name3 etc
- size_t dot = furi_string_search_rchar(base_path, '.');
- furi_string_left(base_path, dot);
- FuriString* path_temp;
- path_temp = furi_string_alloc();
- uint32_t i = 1;
- do {
- furi_string_printf(
- path_temp, "%s%lu%s", furi_string_get_cstr(base_path), ++i, XREMOTE_APP_EXTENSION);
- status = storage_common_stat(storage, furi_string_get_cstr(path_temp), NULL);
- } while(status == FSE_OK);
- furi_string_free(path_temp);
- if(status == FSE_NOT_EXIST) {
- furi_string_cat_printf(name, "%lu", i);
- }
- }
- furi_string_free(base_path);
- furi_record_close(RECORD_STORAGE);
- }
- CrossRemote* xremote_cross_remote_alloc() {
- CrossRemote* remote = malloc(sizeof(CrossRemote));
- CrossRemoteItemArray_init(remote->items);
- remote->name = furi_string_alloc();
- remote->path = furi_string_alloc();
- remote->transmitting = 0;
- return remote;
- }
- void xremote_cross_remote_set_transmitting(CrossRemote* remote, int status) {
- remote->transmitting = status;
- }
- int xremote_cross_remote_get_transmitting(CrossRemote* remote) {
- return remote->transmitting;
- }
- void xremote_cross_remote_free(CrossRemote* remote) {
- furi_string_free(remote->name);
- furi_string_free(remote->path);
- xremote_cross_remote_clear_items(remote);
- CrossRemoteItemArray_clear(remote->items);
- free(remote);
- }
- const char* xremote_cross_remote_get_name(CrossRemote* remote) {
- return furi_string_get_cstr(remote->name);
- }
- bool xremote_cross_remote_add_ir_item(
- CrossRemote* remote,
- const char* name,
- InfraredSignal* signal,
- uint32_t timing) {
- CrossRemoteItem* item = xremote_cross_remote_item_alloc();
- xremote_cross_remote_item_set_type(item, XRemoteRemoteItemTypeInfrared);
- xremote_cross_remote_item_set_name(item, name);
- xremote_cross_remote_item_set_time(item, timing);
- xremote_cross_remote_item_set_ir_signal(item, signal);
- CrossRemoteItemArray_push_back(remote->items, item);
- return true;
- }
- bool xremote_cross_remote_add_pause(CrossRemote* remote, int time) {
- CrossRemoteItem* item = xremote_cross_remote_item_alloc();
- xremote_cross_remote_item_set_type(item, XRemoteRemoteItemTypePause);
- char name[9];
- snprintf(name, 9, CROSS_REMOTE_PAUSE_NAME, time);
- xremote_cross_remote_item_set_name(item, name);
- xremote_cross_remote_item_set_time(item, time);
- CrossRemoteItemArray_push_back(remote->items, item);
- return true;
- }
- bool xremote_cross_remote_add_subghz(CrossRemote* remote, SubGhzRemote* subghz) {
- CrossRemoteItem* item = xremote_cross_remote_item_alloc();
- xremote_cross_remote_item_set_type(item, XRemoteRemoteItemTypeSubGhz);
- xremote_cross_remote_item_set_name(item, xremote_sg_remote_get_name(subghz));
- xremote_cross_remote_item_set_filename(item, xremote_sg_remote_get_filename(subghz));
- FURI_LOG_D(TAG, "add subghz: %s", xremote_sg_remote_get_filename(subghz));
- xremote_cross_remote_item_set_sg_signal(item, subghz);
- CrossRemoteItemArray_push_back(remote->items, item);
- return true;
- }
- size_t xremote_cross_remote_get_item_count(CrossRemote* remote) {
- return CrossRemoteItemArray_size(remote->items);
- }
- CrossRemoteItem* xremote_cross_remote_get_item(CrossRemote* remote, size_t index) {
- furi_assert(index < CrossRemoteItemArray_size(remote->items));
- return *CrossRemoteItemArray_get(remote->items, index);
- }
- void xremote_cross_remote_remove_item(CrossRemote* remote, size_t index) {
- CrossRemoteItemArray_erase(remote->items, index);
- }
- void xremote_cross_remote_rename_item(CrossRemote* remote, size_t index, const char* name) {
- CrossRemoteItem* item = xremote_cross_remote_get_item(remote, index);
- xremote_cross_remote_item_set_name(item, name);
- }
- int16_t xremote_cross_remote_get_item_type(CrossRemote* remote, size_t index) {
- CrossRemoteItem* item = xremote_cross_remote_get_item(remote, index);
- return xremote_cross_remote_item_get_type(item);
- }
- static void xremote_cross_remote_set_name(CrossRemote* remote, const char* name) {
- furi_string_set(remote->name, name);
- }
- static void xremote_cross_remote_set_path(CrossRemote* remote, const char* path) {
- furi_string_set(remote->path, path);
- }
- bool xremote_cross_remote_load(CrossRemote* remote, FuriString* path) {
- Storage* storage = furi_record_open(RECORD_STORAGE);
- FlipperFormat* ff = flipper_format_buffered_file_alloc(storage);
- FuriString* buf;
- buf = furi_string_alloc();
- FURI_LOG_I(TAG, "loading file: \'%s\'", furi_string_get_cstr(path));
- bool success = false;
- do {
- // File not found
- if(!flipper_format_buffered_file_open_existing(ff, furi_string_get_cstr(path))) break;
- uint32_t version;
- // Read Version & Type
- if(!flipper_format_read_header(ff, buf, &version)) break;
- if(!furi_string_equal(buf, XREMOTE_FILE_TYPE) || (version != XREMOTE_FILE_VERSION)) break;
- // Init Remote
- path_extract_filename(path, buf, true);
- xremote_cross_remote_clear_items(remote);
- xremote_cross_remote_set_name(remote, furi_string_get_cstr(buf));
- xremote_cross_remote_set_path(remote, furi_string_get_cstr(path));
- // Load Items
- for(bool can_read = true; can_read;) {
- CrossRemoteItem* item = xremote_cross_remote_item_alloc();
- can_read = xremote_cross_remote_item_read(item, ff);
- if(can_read) {
- CrossRemoteItemArray_push_back(remote->items, item);
- } else {
- xremote_cross_remote_item_free(item);
- }
- }
- success = true;
- } while(false);
- furi_string_free(buf);
- flipper_format_buffered_file_close(ff);
- flipper_format_free(ff);
- furi_record_close(RECORD_STORAGE);
- return success;
- }
- static bool xremote_cross_remote_store(CrossRemote* remote) {
- Storage* storage = furi_record_open(RECORD_STORAGE);
- FlipperFormat* ff = flipper_format_file_alloc(storage);
- const char* path = furi_string_get_cstr(remote->path);
- FURI_LOG_I(TAG, "Storing file: \'%s\'", path);
- bool success = flipper_format_file_open_always(ff, path) &&
- flipper_format_write_header_cstr(ff, XREMOTE_FILE_TYPE, XREMOTE_FILE_VERSION);
- // save Items
- if(success) {
- CrossRemoteItemArray_it_t it;
- for(CrossRemoteItemArray_it(it, remote->items); !CrossRemoteItemArray_end_p(it);
- CrossRemoteItemArray_next(it)) {
- CrossRemoteItem* item = *CrossRemoteItemArray_cref(it);
- success = false;
- if(item->type == XRemoteRemoteItemTypeInfrared) {
- success = xremote_cross_remote_item_ir_signal_save(
- xremote_cross_remote_item_get_ir_signal(item),
- ff,
- xremote_cross_remote_item_get_name(item),
- xremote_cross_remote_item_get_time(item));
- } else if(item->type == XRemoteRemoteItemTypePause) {
- success = xremote_cross_remote_item_pause_save(
- ff, item->time, xremote_cross_remote_item_get_name(item));
- } else if(item->type == XRemoteRemoteItemTypeSubGhz) {
- success = xremote_cross_remote_item_sg_signal_save(
- xremote_cross_remote_item_get_sg_signal(item),
- ff,
- xremote_cross_remote_item_get_name(item),
- xremote_cross_remote_item_get_filename(item));
- }
- if(!success) {
- break;
- }
- }
- }
- flipper_format_free(ff);
- furi_record_close(RECORD_STORAGE);
- return success;
- }
- bool xremote_cross_remote_save_new(CrossRemote* remote, const char* name) {
- FuriString *new_name, *new_path;
- new_name = furi_string_alloc_set(name);
- new_path = furi_string_alloc_set(XREMOTE_APP_FOLDER);
- xremote_cross_remote_find_vacant_remote_name(new_name, furi_string_get_cstr(new_path));
- furi_string_cat_printf(
- new_path, "/%s%s", furi_string_get_cstr(new_name), XREMOTE_APP_EXTENSION);
- xremote_cross_remote_set_name(remote, furi_string_get_cstr(new_name));
- xremote_cross_remote_set_path(remote, furi_string_get_cstr(new_path));
- furi_string_free(new_name);
- furi_string_free(new_path);
- return xremote_cross_remote_store(remote);
- }
- static void xremote_cross_remote_reset(CrossRemote* remote) {
- furi_string_reset(remote->name);
- furi_string_reset(remote->path);
- xremote_cross_remote_clear_items(remote);
- remote->transmitting = 0;
- }
- bool xremote_cross_remote_delete(CrossRemote* remote) {
- Storage* storage = furi_record_open(RECORD_STORAGE);
- FS_Error status = storage_common_remove(storage, furi_string_get_cstr(remote->path));
- furi_record_close(RECORD_STORAGE);
- xremote_cross_remote_reset(remote);
- return (status == FSE_OK || status == FSE_NOT_EXIST);
- }
|