Procházet zdrojové kódy

Merge pull request #27 from leedave/feature/subghz_update

Feature/subghz update
David Lee před 1 rokem
rodič
revize
96433766d5

+ 1 - 1
application.fam

@@ -6,7 +6,7 @@ App(
     stack_size=3 * 1024,
     stack_size=3 * 1024,
     fap_icon="icons/xremote_10px.png",
     fap_icon="icons/xremote_10px.png",
     fap_icon_assets="icons",
     fap_icon_assets="icons",
-    fap_version="2.7",
+    fap_version="2.8",
     fap_category="Infrared",
     fap_category="Infrared",
     fap_author="Leedave",
     fap_author="Leedave",
     fap_description="One-Click, sends multiple commands",
     fap_description="One-Click, sends multiple commands",

+ 3 - 0
docs/changelog.md

@@ -1,3 +1,6 @@
+## 2.8
+- Update SubGhz Protocoll to include flippers official rolling code support
+
 ## 2.7
 ## 2.7
 - Replaced custom keyboard for timing with new number_input from Firmware
 - Replaced custom keyboard for timing with new number_input from Firmware
 - Requires minimum OFW version 0.105.0 or custom firmware based on this
 - Requires minimum OFW version 0.105.0 or custom firmware based on this

+ 1 - 0
helpers/subghz/subghz.c

@@ -9,6 +9,7 @@ SubGhz* subghz_alloc() {
 
 
     subghz->file_path = furi_string_alloc();
     subghz->file_path = furi_string_alloc();
     subghz->txrx = subghz_txrx_alloc();
     subghz->txrx = subghz_txrx_alloc();
+    subghz_txrx_set_need_save_callback(subghz->txrx, subghz_save_to_file, subghz);
     subghz->dialogs = furi_record_open(RECORD_DIALOGS);
     subghz->dialogs = furi_record_open(RECORD_DIALOGS);
 
 
     return subghz;
     return subghz;

+ 56 - 2
helpers/subghz/subghz_i.c

@@ -187,6 +187,60 @@ SubGhzLoadTypeFile subghz_get_load_type_file(SubGhz* subghz) {
     return subghz->load_type_file;
     return subghz->load_type_file;
 }
 }
 
 
+bool subghz_save_protocol_to_file(
+    SubGhz* subghz,
+    FlipperFormat* flipper_format,
+    const char* dev_file_name) {
+    furi_assert(subghz);
+    furi_assert(flipper_format);
+    furi_assert(dev_file_name);
+
+    Storage* storage = furi_record_open(RECORD_STORAGE);
+    Stream* flipper_format_stream = flipper_format_get_raw_stream(flipper_format);
+
+    bool saved = false;
+    FuriString* file_dir = furi_string_alloc();
+
+    path_extract_dirname(dev_file_name, file_dir);
+    do {
+        //removing additional fields
+        flipper_format_delete_key(flipper_format, "Repeat");
+        flipper_format_delete_key(flipper_format, "Manufacture");
+
+        // Create subghz folder directory if necessary
+        if(!storage_simply_mkdir(storage, furi_string_get_cstr(file_dir))) {
+            dialog_message_show_storage_error(subghz->dialogs, "Cannot create\nfolder");
+            break;
+        }
+
+        if(!storage_simply_remove(storage, dev_file_name)) {
+            break;
+        }
+        stream_seek(flipper_format_stream, 0, StreamOffsetFromStart);
+        stream_save_to_file(flipper_format_stream, storage, dev_file_name, FSOM_CREATE_ALWAYS);
+
+        if(storage_common_stat(storage, dev_file_name, NULL) != FSE_OK) {
+            break;
+        }
+
+        saved = true;
+    } while(0);
+    furi_string_free(file_dir);
+    furi_record_close(RECORD_STORAGE);
+    return saved;
+}
+
+void subghz_save_to_file(void* context) {
+    furi_assert(context);
+    SubGhz* subghz = context;
+    if(subghz_path_is_file(subghz->file_path)) {
+        subghz_save_protocol_to_file(
+            subghz,
+            subghz_txrx_get_fff_data(subghz->txrx),
+            furi_string_get_cstr(subghz->file_path));
+    }
+}
+
 bool subghz_load_protocol_from_file(SubGhz* subghz, const char* path) {
 bool subghz_load_protocol_from_file(SubGhz* subghz, const char* path) {
     furi_assert(subghz);
     furi_assert(subghz);
 
 
@@ -213,9 +267,9 @@ bool subghz_load_protocol_from_file(SubGhz* subghz, const char* path) {
     return ret;
     return ret;
 }*/
 }*/
 
 
-/*bool subghz_path_is_file(FuriString* path) {
+bool subghz_path_is_file(FuriString* path) {
     return furi_string_end_with(path, SUBGHZ_APP_FILENAME_EXTENSION);
     return furi_string_end_with(path, SUBGHZ_APP_FILENAME_EXTENSION);
-}*/
+}
 
 
 /*void subghz_lock(SubGhz* subghz) {
 /*void subghz_lock(SubGhz* subghz) {
     furi_assert(subghz);
     furi_assert(subghz);

+ 7 - 0
helpers/subghz/subghz_i.h

@@ -37,6 +37,7 @@
 #include "subghz_txrx.h"
 #include "subghz_txrx.h"
 
 
 #define SUBGHZ_MAX_LEN_NAME 64
 #define SUBGHZ_MAX_LEN_NAME 64
+#define SUBGHZ_APP_FILENAME_EXTENSION ".sub"
 
 
 typedef struct SubGhz SubGhz;
 typedef struct SubGhz SubGhz;
 
 
@@ -67,6 +68,12 @@ struct SubGhz {
 //void subghz_set_default_preset(SubGhz* subghz);
 //void subghz_set_default_preset(SubGhz* subghz);
 //void subghz_blink_start(SubGhz* subghz);
 //void subghz_blink_start(SubGhz* subghz);
 //void subghz_blink_stop(SubGhz* subghz);
 //void subghz_blink_stop(SubGhz* subghz);
+bool subghz_save_protocol_to_file(
+    SubGhz* subghz,
+    FlipperFormat* flipper_format,
+    const char* dev_file_name);
+void subghz_save_to_file(void* context);
+bool subghz_path_is_file(FuriString* path);
 
 
 // Used on Encoded SubGhz
 // Used on Encoded SubGhz
 bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format);
 bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format);

+ 6 - 23
helpers/subghz/subghz_txrx.c

@@ -27,7 +27,7 @@ static void subghz_txrx_radio_device_power_off(SubGhzTxRx* instance) {
     if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg();
     if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg();
 }
 }
 
 
-SubGhzTxRx* subghz_txrx_alloc() {
+SubGhzTxRx* subghz_txrx_alloc(void) {
     SubGhzTxRx* instance = malloc(sizeof(SubGhzTxRx));
     SubGhzTxRx* instance = malloc(sizeof(SubGhzTxRx));
     instance->setting = subghz_setting_alloc();
     instance->setting = subghz_setting_alloc();
     subghz_setting_load(instance->setting, EXT_PATH("subghz/assets/setting_user"));
     subghz_setting_load(instance->setting, EXT_PATH("subghz/assets/setting_user"));
@@ -71,15 +71,12 @@ SubGhzTxRx* subghz_txrx_alloc() {
     instance->radio_device_type =
     instance->radio_device_type =
         subghz_txrx_radio_device_set(instance, SubGhzRadioDeviceTypeExternalCC1101);
         subghz_txrx_radio_device_set(instance, SubGhzRadioDeviceTypeExternalCC1101);
 
 
-    FURI_LOG_D(TAG, "completed TXRX alloc");
-
     return instance;
     return instance;
 }
 }
 
 
 void subghz_txrx_free(SubGhzTxRx* instance) {
 void subghz_txrx_free(SubGhzTxRx* instance) {
     furi_assert(instance);
     furi_assert(instance);
-    FURI_LOG_D(TAG, "freeing TXRX");
-
+    
     if(instance->radio_device_type != SubGhzRadioDeviceTypeInternal) {
     if(instance->radio_device_type != SubGhzRadioDeviceTypeInternal) {
         subghz_txrx_radio_device_power_off(instance);
         subghz_txrx_radio_device_power_off(instance);
         subghz_devices_end(instance->radio_device);
         subghz_devices_end(instance->radio_device);
@@ -194,7 +191,6 @@ static void subghz_txrx_idle(SubGhzTxRx* instance) {
         subghz_txrx_speaker_off(instance);
         subghz_txrx_speaker_off(instance);
         instance->txrx_state = SubGhzTxRxStateIDLE;
         instance->txrx_state = SubGhzTxRxStateIDLE;
     }
     }
-    FURI_LOG_D(TAG, "completed subghz_txrx_idle");
 }
 }
 
 
 /*static void subghz_txrx_rx_end(SubGhzTxRx* instance) {
 /*static void subghz_txrx_rx_end(SubGhzTxRx* instance) {
@@ -228,7 +224,6 @@ static bool subghz_txrx_tx(SubGhzTxRx* instance, uint32_t frequency) {
         instance->txrx_state = SubGhzTxRxStateTx;
         instance->txrx_state = SubGhzTxRxStateTx;
     }
     }
 
 
-    FURI_LOG_D(TAG, "completed subghz_txrx_tx");
     return ret;
     return ret;
 }
 }
 
 
@@ -241,10 +236,7 @@ SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat*
     SubGhzTxRxStartTxState ret = SubGhzTxRxStartTxStateErrorParserOthers;
     SubGhzTxRxStartTxState ret = SubGhzTxRxStartTxStateErrorParserOthers;
     FuriString* temp_str = furi_string_alloc();
     FuriString* temp_str = furi_string_alloc();
     uint32_t repeat = 200;
     uint32_t repeat = 200;
-
-    FURI_LOG_D(TAG, "starting loop in subghz_txrx_tx_start");
     do {
     do {
-        FURI_LOG_D(TAG, "looping");
         if(!flipper_format_rewind(flipper_format)) {
         if(!flipper_format_rewind(flipper_format)) {
             FURI_LOG_E(TAG, "Rewind error");
             FURI_LOG_E(TAG, "Rewind error");
             break;
             break;
@@ -257,7 +249,6 @@ SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat*
             FURI_LOG_E(TAG, "Unable Repeat");
             FURI_LOG_E(TAG, "Unable Repeat");
             break;
             break;
         }
         }
-        //FURI_LOG_D(TAG, "File loaded");
         ret = SubGhzTxRxStartTxStateOk;
         ret = SubGhzTxRxStartTxStateOk;
 
 
         SubGhzRadioPreset* preset = instance->preset;
         SubGhzRadioPreset* preset = instance->preset;
@@ -265,24 +256,18 @@ SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat*
             subghz_transmitter_alloc_init(instance->environment, furi_string_get_cstr(temp_str));
             subghz_transmitter_alloc_init(instance->environment, furi_string_get_cstr(temp_str));
 
 
         if(instance->transmitter) {
         if(instance->transmitter) {
-            FURI_LOG_D(TAG, "transmitter found");
             if(subghz_transmitter_deserialize(instance->transmitter, flipper_format) ==
             if(subghz_transmitter_deserialize(instance->transmitter, flipper_format) ==
                SubGhzProtocolStatusOk) {
                SubGhzProtocolStatusOk) {
-                //if (false) {
-                FURI_LOG_D(TAG, "deserialization");
                 if(strcmp(furi_string_get_cstr(preset->name), "") != 0) {
                 if(strcmp(furi_string_get_cstr(preset->name), "") != 0) {
-                    FURI_LOG_D(TAG, "got preset name");
                     subghz_txrx_begin(
                     subghz_txrx_begin(
                         instance,
                         instance,
                         subghz_setting_get_preset_data_by_name(
                         subghz_setting_get_preset_data_by_name(
                             instance->setting, furi_string_get_cstr(preset->name)));
                             instance->setting, furi_string_get_cstr(preset->name)));
-                    FURI_LOG_D(TAG, "loaded preset by name");
                     if(preset->frequency) {
                     if(preset->frequency) {
                         if(!subghz_txrx_tx(instance, preset->frequency)) {
                         if(!subghz_txrx_tx(instance, preset->frequency)) {
                             FURI_LOG_E(TAG, "Only Rx");
                             FURI_LOG_E(TAG, "Only Rx");
                             ret = SubGhzTxRxStartTxStateErrorOnlyRx;
                             ret = SubGhzTxRxStartTxStateErrorOnlyRx;
                         }
                         }
-                        FURI_LOG_D(TAG, "got frequency");
                     } else {
                     } else {
                         ret = SubGhzTxRxStartTxStateErrorParserOthers;
                         ret = SubGhzTxRxStartTxStateErrorParserOthers;
                     }
                     }
@@ -295,12 +280,10 @@ SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat*
 
 
                 if(ret == SubGhzTxRxStartTxStateOk) {
                 if(ret == SubGhzTxRxStartTxStateOk) {
                     //Start TX
                     //Start TX
-                    FURI_LOG_D(TAG, "starting Async TX");
                     subghz_devices_start_async_tx(
                     subghz_devices_start_async_tx(
                         instance->radio_device, subghz_transmitter_yield, instance->transmitter);
                         instance->radio_device, subghz_transmitter_yield, instance->transmitter);
                 }
                 }
             } else {
             } else {
-                FURI_LOG_D(TAG, "no deserialization");
                 ret = SubGhzTxRxStartTxStateErrorParserOthers;
                 ret = SubGhzTxRxStartTxStateErrorParserOthers;
             }
             }
         } else {
         } else {
@@ -328,14 +311,14 @@ SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat*
     subghz_txrx_rx(instance, instance->preset->frequency);
     subghz_txrx_rx(instance, instance->preset->frequency);
 }*/
 }*/
 
 
-/*void subghz_txrx_set_need_save_callback(
+void subghz_txrx_set_need_save_callback(
     SubGhzTxRx* instance,
     SubGhzTxRx* instance,
     SubGhzTxRxNeedSaveCallback callback,
     SubGhzTxRxNeedSaveCallback callback,
     void* context) {
     void* context) {
     furi_assert(instance);
     furi_assert(instance);
     instance->need_save_callback = callback;
     instance->need_save_callback = callback;
     instance->need_save_context = context;
     instance->need_save_context = context;
-}*/
+}
 
 
 static void subghz_txrx_tx_stop(SubGhzTxRx* instance) {
 static void subghz_txrx_tx_stop(SubGhzTxRx* instance) {
     furi_assert(instance);
     furi_assert(instance);
@@ -346,11 +329,11 @@ static void subghz_txrx_tx_stop(SubGhzTxRx* instance) {
     subghz_transmitter_free(instance->transmitter);
     subghz_transmitter_free(instance->transmitter);
 
 
     //if protocol dynamic then we save the last upload
     //if protocol dynamic then we save the last upload
-    /*if(instance->decoder_result->protocol->type == SubGhzProtocolTypeDynamic) {
+    if(instance->decoder_result->protocol->type == SubGhzProtocolTypeDynamic) {
         if(instance->need_save_callback) {
         if(instance->need_save_callback) {
             instance->need_save_callback(instance->need_save_context);
             instance->need_save_callback(instance->need_save_context);
         }
         }
-    }*/
+    }
     subghz_txrx_idle(instance);
     subghz_txrx_idle(instance);
     subghz_txrx_speaker_off(instance);
     subghz_txrx_speaker_off(instance);
 }
 }

+ 2 - 2
helpers/subghz/subghz_txrx.h

@@ -221,10 +221,10 @@ SubGhzProtocolDecoderBase* subghz_txrx_get_decoder(SubGhzTxRx* instance);
  * @param callback Callback for save data
  * @param callback Callback for save data
  * @param context Context for callback
  * @param context Context for callback
  */
  */
-/*void subghz_txrx_set_need_save_callback(
+void subghz_txrx_set_need_save_callback(
     SubGhzTxRx* instance,
     SubGhzTxRx* instance,
     SubGhzTxRxNeedSaveCallback callback,
     SubGhzTxRxNeedSaveCallback callback,
-    void* context);*/
+    void* context);
 
 
 /**
 /**
  * Get pointer to a load data key
  * Get pointer to a load data key

+ 1 - 1
xremote_i.h

@@ -51,7 +51,7 @@
 #define XREMOTE_TEXT_STORE_SIZE 128
 #define XREMOTE_TEXT_STORE_SIZE 128
 #define XREMOTE_MAX_ITEM_NAME_LENGTH 22
 #define XREMOTE_MAX_ITEM_NAME_LENGTH 22
 #define XREMOTE_MAX_REMOTE_NAME_LENGTH 22
 #define XREMOTE_MAX_REMOTE_NAME_LENGTH 22
-#define XREMOTE_VERSION "2.7"
+#define XREMOTE_VERSION "2.8"
 
 
 #define INFRARED_APP_EXTENSION ".ir"
 #define INFRARED_APP_EXTENSION ".ir"
 #define INFRARED_APP_FOLDER ANY_PATH("infrared")
 #define INFRARED_APP_FOLDER ANY_PATH("infrared")