mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
Merge branch 'dev' of https://github.com/DarkFlippers/unleashed-firmware into xfw-dev
This commit is contained in:
@@ -12,7 +12,9 @@
|
||||
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
#include <lib/toolbox/path.h>
|
||||
#include <applications/main/subghz/subghz_i.h>
|
||||
#include <lib/subghz/receiver.h>
|
||||
#include <lib/subghz/transmitter.h>
|
||||
#include <lib/subghz/subghz_setting.h>
|
||||
|
||||
#include <lib/subghz/protocols/raw.h>
|
||||
#include <lib/subghz/protocols/protocol_items.h>
|
||||
@@ -355,7 +357,7 @@ bool subghz_remote_key_load(
|
||||
|
||||
bool res = false;
|
||||
|
||||
subghz_custom_btn_set(0);
|
||||
subghz_custom_btn_set(SUBGHZ_CUSTOM_BTN_OK);
|
||||
keeloq_reset_original_btn();
|
||||
subghz_custom_btns_reset();
|
||||
|
||||
|
||||
2
applications/external/totp/features_config.h
vendored
2
applications/external/totp/features_config.h
vendored
@@ -11,6 +11,4 @@
|
||||
// End of list
|
||||
|
||||
// Target firmware to build for
|
||||
#ifndef TOTP_TARGET_FIRMWARE
|
||||
#define TOTP_TARGET_FIRMWARE TOTP_FIRMWARE_XTREME
|
||||
#endif
|
||||
@@ -104,6 +104,13 @@ const WifiMarauderItem items[NUM_MENU_ITEMS] = {
|
||||
INPUT_ARGS,
|
||||
FOCUS_CONSOLE_END,
|
||||
SHOW_STOPSCAN_TIP},
|
||||
{"Sniff pmkid on selected aps",
|
||||
{""},
|
||||
1,
|
||||
{"sniffpmkid -d -l"},
|
||||
NO_ARGS,
|
||||
FOCUS_CONSOLE_END,
|
||||
NO_TIP},
|
||||
{"Channel",
|
||||
{"get", "set"},
|
||||
2,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WIFI_MARAUDER_APP_VERSION "v0.3.4"
|
||||
#define WIFI_MARAUDER_APP_VERSION "v0.3.5"
|
||||
|
||||
typedef struct WifiMarauderApp WifiMarauderApp;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <lib/toolbox/path.h>
|
||||
#include <dialogs/dialogs.h>
|
||||
|
||||
#define NUM_MENU_ITEMS (18)
|
||||
#define NUM_MENU_ITEMS (19)
|
||||
|
||||
#define WIFI_MARAUDER_TEXT_BOX_STORE_SIZE (4096)
|
||||
#define WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE (512)
|
||||
|
||||
@@ -91,3 +91,9 @@ typedef enum {
|
||||
SubGhzViewReceiverModeLive,
|
||||
SubGhzViewReceiverModeFile,
|
||||
} SubGhzViewReceiverMode;
|
||||
|
||||
typedef enum {
|
||||
SubGhzDecodeRawStateStart,
|
||||
SubGhzDecodeRawStateLoading,
|
||||
SubGhzDecodeRawStateLoaded,
|
||||
} SubGhzDecodeRawState;
|
||||
@@ -120,7 +120,8 @@ bool subghz_scene_decode_raw_next(SubGhz* subghz) {
|
||||
uint32_t duration = level_duration_get_duration(level_duration);
|
||||
subghz_receiver_decode(receiver, level, duration);
|
||||
} else {
|
||||
subghz->decode_raw_state = SubGhzDecodeRawStateLoaded;
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneDecodeRAW, SubGhzDecodeRawStateLoaded);
|
||||
subghz->state_notifications = SubGhzNotificationStateIDLE;
|
||||
|
||||
subghz_view_receiver_add_data_progress(subghz->subghz_receiver, "Done!");
|
||||
@@ -155,11 +156,13 @@ void subghz_scene_decode_raw_on_enter(void* context) {
|
||||
|
||||
subghz_txrx_receiver_set_filter(subghz->txrx, SubGhzProtocolFlag_Decodable);
|
||||
|
||||
if(subghz->decode_raw_state == SubGhzDecodeRawStateStart) {
|
||||
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneDecodeRAW) ==
|
||||
SubGhzDecodeRawStateStart) {
|
||||
//Decode RAW to history
|
||||
subghz_history_reset(subghz->history);
|
||||
if(subghz_scene_decode_raw_start(subghz)) {
|
||||
subghz->decode_raw_state = SubGhzDecodeRawStateLoading;
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneDecodeRAW, SubGhzDecodeRawStateLoading);
|
||||
subghz->state_notifications = SubGhzNotificationStateRx;
|
||||
}
|
||||
} else {
|
||||
@@ -192,10 +195,9 @@ bool subghz_scene_decode_raw_on_event(void* context, SceneManagerEvent event) {
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
switch(event.event) {
|
||||
case SubGhzCustomEventViewReceiverBack:
|
||||
subghz->decode_raw_state = SubGhzDecodeRawStateStart;
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneDecodeRAW, SubGhzDecodeRawStateStart);
|
||||
subghz->idx_menu_chosen = 0;
|
||||
subghz->in_decoder_scene = false;
|
||||
subghz->in_decoder_scene_skip = false;
|
||||
|
||||
subghz_txrx_set_rx_calback(subghz->txrx, NULL, subghz);
|
||||
|
||||
@@ -214,7 +216,6 @@ bool subghz_scene_decode_raw_on_event(void* context, SceneManagerEvent event) {
|
||||
case SubGhzCustomEventViewReceiverOK:
|
||||
subghz->idx_menu_chosen = subghz_view_receiver_get_idx_menu(subghz->subghz_receiver);
|
||||
subghz->state_notifications = SubGhzNotificationStateIDLE;
|
||||
subghz->in_decoder_scene = true;
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverInfo);
|
||||
consumed = true;
|
||||
break;
|
||||
@@ -242,7 +243,7 @@ bool subghz_scene_decode_raw_on_event(void* context, SceneManagerEvent event) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch(subghz->decode_raw_state) {
|
||||
switch(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneDecodeRAW)) {
|
||||
case SubGhzDecodeRawStateLoading:
|
||||
subghz_scene_decode_raw_next(subghz);
|
||||
break;
|
||||
|
||||
@@ -141,7 +141,7 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event)
|
||||
subghz_scene_receiver_info_draw_widget(subghz);
|
||||
|
||||
subghz_txrx_stop(subghz->txrx);
|
||||
if(!subghz->in_decoder_scene) {
|
||||
if(!scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneDecodeRAW)) {
|
||||
subghz_txrx_rx_start(subghz->txrx);
|
||||
|
||||
subghz_txrx_hopper_unpause(subghz->txrx);
|
||||
@@ -161,9 +161,6 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event)
|
||||
if(subghz_txrx_protocol_is_serializable(subghz->txrx)) {
|
||||
subghz_file_name_clear(subghz);
|
||||
|
||||
if(subghz->in_decoder_scene) {
|
||||
subghz->in_decoder_scene_skip = true;
|
||||
}
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName);
|
||||
}
|
||||
return true;
|
||||
@@ -192,9 +189,7 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event)
|
||||
|
||||
void subghz_scene_receiver_info_on_exit(void* context) {
|
||||
SubGhz* subghz = context;
|
||||
if(subghz->in_decoder_scene && !subghz->in_decoder_scene_skip) {
|
||||
subghz->in_decoder_scene = false;
|
||||
}
|
||||
|
||||
widget_reset(subghz->widget);
|
||||
keeloq_reset_mfname();
|
||||
keeloq_reset_kl_type();
|
||||
|
||||
@@ -127,7 +127,7 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) {
|
||||
if(!(strcmp(subghz->file_name_tmp, "") == 0) ||
|
||||
scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
|
||||
SubGhzCustomEventManagerNoSet) {
|
||||
if(!subghz->in_decoder_scene) {
|
||||
if(!scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneDecodeRAW)) {
|
||||
furi_string_set(subghz->file_path, subghz->file_path_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event)
|
||||
SubGhz* subghz = context;
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubGhzCustomEventSceneSaveSuccess) {
|
||||
if(!subghz->in_decoder_scene) {
|
||||
if(!scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneDecodeRAW)) {
|
||||
if(!scene_manager_search_and_switch_to_previous_scene(
|
||||
subghz->scene_manager, SubGhzSceneReceiver)) {
|
||||
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateRAWSave);
|
||||
@@ -39,7 +39,9 @@ bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
subghz->decode_raw_state = SubGhzDecodeRawStateStart;
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneDecodeRAW, SubGhzDecodeRawStateStart);
|
||||
|
||||
subghz->idx_menu_chosen = 0;
|
||||
subghz_txrx_set_rx_calback(subghz->txrx, NULL, subghz);
|
||||
|
||||
@@ -65,11 +67,6 @@ bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event)
|
||||
void subghz_scene_save_success_on_exit(void* context) {
|
||||
SubGhz* subghz = context;
|
||||
|
||||
if(subghz->in_decoder_scene) {
|
||||
subghz->in_decoder_scene = false;
|
||||
subghz->in_decoder_scene_skip = false;
|
||||
}
|
||||
|
||||
// Clear view
|
||||
Popup* popup = subghz->popup;
|
||||
|
||||
|
||||
@@ -100,8 +100,8 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
|
||||
} else if(event.event == SubGhzCustomEventViewTransmitterSendStop) {
|
||||
subghz->state_notifications = SubGhzNotificationStateIDLE;
|
||||
subghz_txrx_stop(subghz->txrx);
|
||||
if(subghz_custom_btn_get() != 0) {
|
||||
subghz_custom_btn_set(0);
|
||||
if(subghz_custom_btn_get() != SUBGHZ_CUSTOM_BTN_OK) {
|
||||
subghz_custom_btn_set(SUBGHZ_CUSTOM_BTN_OK);
|
||||
uint8_t tmp_counter = furi_hal_subghz_get_rolling_counter_mult();
|
||||
furi_hal_subghz_set_rolling_counter_mult(0);
|
||||
// Calling restore!
|
||||
|
||||
@@ -62,9 +62,6 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) {
|
||||
// GUI
|
||||
subghz->gui = furi_record_open(RECORD_GUI);
|
||||
|
||||
subghz->in_decoder_scene = false;
|
||||
subghz->in_decoder_scene_skip = false;
|
||||
|
||||
// View Dispatcher
|
||||
subghz->view_dispatcher = view_dispatcher_alloc();
|
||||
view_dispatcher_enable_queue(subghz->view_dispatcher);
|
||||
|
||||
@@ -54,12 +54,6 @@ typedef struct {
|
||||
uint8_t seed[4];
|
||||
} SecureData;
|
||||
|
||||
typedef enum {
|
||||
SubGhzDecodeRawStateStart,
|
||||
SubGhzDecodeRawStateLoading,
|
||||
SubGhzDecodeRawStateLoaded,
|
||||
} SubGhzDecodeRawState;
|
||||
|
||||
struct SubGhz {
|
||||
Gui* gui;
|
||||
NotificationApp* notifications;
|
||||
@@ -98,16 +92,12 @@ struct SubGhz {
|
||||
FuriString* error_str;
|
||||
SubGhzLock lock;
|
||||
|
||||
bool in_decoder_scene;
|
||||
bool in_decoder_scene_skip;
|
||||
|
||||
bool ignore_starline;
|
||||
bool ignore_auto_alarms;
|
||||
bool ignore_magellan;
|
||||
|
||||
SecureData* secure_data;
|
||||
|
||||
SubGhzDecodeRawState decode_raw_state;
|
||||
SubGhzFileEncoderWorker* decode_raw_file_worker_encoder;
|
||||
|
||||
SubGhzThresholdRssi* threshold_rssi;
|
||||
|
||||
@@ -109,7 +109,7 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) {
|
||||
},
|
||||
false);
|
||||
return false;
|
||||
}
|
||||
} // Finish "Back" key processing
|
||||
|
||||
with_view_model(
|
||||
subghz_transmitter->view,
|
||||
@@ -121,124 +121,67 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) {
|
||||
},
|
||||
true);
|
||||
|
||||
if(can_be_sent && event->key == InputKeyOk && event->type == InputTypePress) {
|
||||
subghz_custom_btn_set(0);
|
||||
with_view_model(
|
||||
subghz_transmitter->view,
|
||||
SubGhzViewTransmitterModel * model,
|
||||
{
|
||||
furi_string_reset(model->temp_button_id);
|
||||
model->draw_temp_button = false;
|
||||
},
|
||||
true);
|
||||
subghz_transmitter->callback(
|
||||
SubGhzCustomEventViewTransmitterSendStart, subghz_transmitter->context);
|
||||
return true;
|
||||
} else if(can_be_sent && event->key == InputKeyOk && event->type == InputTypeRelease) {
|
||||
subghz_transmitter->callback(
|
||||
SubGhzCustomEventViewTransmitterSendStop, subghz_transmitter->context);
|
||||
return true;
|
||||
}
|
||||
if(can_be_sent) {
|
||||
if(event->key == InputKeyOk && event->type == InputTypePress) {
|
||||
subghz_custom_btn_set(SUBGHZ_CUSTOM_BTN_OK);
|
||||
with_view_model(
|
||||
subghz_transmitter->view,
|
||||
SubGhzViewTransmitterModel * model,
|
||||
{
|
||||
furi_string_reset(model->temp_button_id);
|
||||
model->draw_temp_button = false;
|
||||
},
|
||||
true);
|
||||
subghz_transmitter->callback(
|
||||
SubGhzCustomEventViewTransmitterSendStart, subghz_transmitter->context);
|
||||
return true;
|
||||
} else if(event->key == InputKeyOk && event->type == InputTypeRelease) {
|
||||
subghz_transmitter->callback(
|
||||
SubGhzCustomEventViewTransmitterSendStop, subghz_transmitter->context);
|
||||
return true;
|
||||
} // Finish "OK" key processing
|
||||
|
||||
// Temp Buttons (UP)
|
||||
if(can_be_sent && event->key == InputKeyUp && event->type == InputTypePress) {
|
||||
subghz_custom_btn_set(1);
|
||||
with_view_model(
|
||||
subghz_transmitter->view,
|
||||
SubGhzViewTransmitterModel * model,
|
||||
{
|
||||
furi_string_reset(model->temp_button_id);
|
||||
if(subghz_custom_btn_get_original() != 0) {
|
||||
if(subghz_custom_btn_get() == 1) {
|
||||
furi_string_printf(
|
||||
model->temp_button_id, "%01X", subghz_custom_btn_get_original());
|
||||
model->draw_temp_button = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
true);
|
||||
subghz_transmitter->callback(
|
||||
SubGhzCustomEventViewTransmitterSendStart, subghz_transmitter->context);
|
||||
return true;
|
||||
} else if(can_be_sent && event->key == InputKeyUp && event->type == InputTypeRelease) {
|
||||
subghz_transmitter->callback(
|
||||
SubGhzCustomEventViewTransmitterSendStop, subghz_transmitter->context);
|
||||
return true;
|
||||
}
|
||||
// Down
|
||||
if(can_be_sent && event->key == InputKeyDown && event->type == InputTypePress) {
|
||||
subghz_custom_btn_set(2);
|
||||
with_view_model(
|
||||
subghz_transmitter->view,
|
||||
SubGhzViewTransmitterModel * model,
|
||||
{
|
||||
furi_string_reset(model->temp_button_id);
|
||||
if(subghz_custom_btn_get_original() != 0) {
|
||||
if(subghz_custom_btn_get() == 2) {
|
||||
furi_string_printf(
|
||||
model->temp_button_id, "%01X", subghz_custom_btn_get_original());
|
||||
model->draw_temp_button = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
true);
|
||||
subghz_transmitter->callback(
|
||||
SubGhzCustomEventViewTransmitterSendStart, subghz_transmitter->context);
|
||||
return true;
|
||||
} else if(can_be_sent && event->key == InputKeyDown && event->type == InputTypeRelease) {
|
||||
subghz_transmitter->callback(
|
||||
SubGhzCustomEventViewTransmitterSendStop, subghz_transmitter->context);
|
||||
return true;
|
||||
}
|
||||
// Left
|
||||
if(can_be_sent && event->key == InputKeyLeft && event->type == InputTypePress) {
|
||||
subghz_custom_btn_set(3);
|
||||
with_view_model(
|
||||
subghz_transmitter->view,
|
||||
SubGhzViewTransmitterModel * model,
|
||||
{
|
||||
furi_string_reset(model->temp_button_id);
|
||||
if(subghz_custom_btn_get_original() != 0) {
|
||||
if(subghz_custom_btn_get() == 3) {
|
||||
furi_string_printf(
|
||||
model->temp_button_id, "%01X", subghz_custom_btn_get_original());
|
||||
model->draw_temp_button = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
true);
|
||||
subghz_transmitter->callback(
|
||||
SubGhzCustomEventViewTransmitterSendStart, subghz_transmitter->context);
|
||||
return true;
|
||||
} else if(can_be_sent && event->key == InputKeyLeft && event->type == InputTypeRelease) {
|
||||
subghz_transmitter->callback(
|
||||
SubGhzCustomEventViewTransmitterSendStop, subghz_transmitter->context);
|
||||
return true;
|
||||
}
|
||||
// Right
|
||||
if(can_be_sent && event->key == InputKeyRight && event->type == InputTypePress) {
|
||||
subghz_custom_btn_set(4);
|
||||
with_view_model(
|
||||
subghz_transmitter->view,
|
||||
SubGhzViewTransmitterModel * model,
|
||||
{
|
||||
furi_string_reset(model->temp_button_id);
|
||||
if(subghz_custom_btn_get_original() != 0) {
|
||||
if(subghz_custom_btn_get() == 4) {
|
||||
furi_string_printf(
|
||||
model->temp_button_id, "%01X", subghz_custom_btn_get_original());
|
||||
model->draw_temp_button = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
true);
|
||||
subghz_transmitter->callback(
|
||||
SubGhzCustomEventViewTransmitterSendStart, subghz_transmitter->context);
|
||||
return true;
|
||||
} else if(can_be_sent && event->key == InputKeyRight && event->type == InputTypeRelease) {
|
||||
subghz_transmitter->callback(
|
||||
SubGhzCustomEventViewTransmitterSendStop, subghz_transmitter->context);
|
||||
return true;
|
||||
if(subghz_custom_btn_is_allowed()) {
|
||||
uint8_t temp_btn_id;
|
||||
if(event->key == InputKeyUp) {
|
||||
temp_btn_id = SUBGHZ_CUSTOM_BTN_UP;
|
||||
} else if(event->key == InputKeyDown) {
|
||||
temp_btn_id = SUBGHZ_CUSTOM_BTN_DOWN;
|
||||
} else if(event->key == InputKeyLeft) {
|
||||
temp_btn_id = SUBGHZ_CUSTOM_BTN_LEFT;
|
||||
} else if(event->key == InputKeyRight) {
|
||||
temp_btn_id = SUBGHZ_CUSTOM_BTN_RIGHT;
|
||||
} else {
|
||||
// Finish processing if the button is different
|
||||
return true;
|
||||
}
|
||||
|
||||
if(event->type == InputTypePress) {
|
||||
with_view_model(
|
||||
subghz_transmitter->view,
|
||||
SubGhzViewTransmitterModel * model,
|
||||
{
|
||||
furi_string_reset(model->temp_button_id);
|
||||
if(subghz_custom_btn_get_original() != 0) {
|
||||
if(subghz_custom_btn_set(temp_btn_id)) {
|
||||
furi_string_printf(
|
||||
model->temp_button_id,
|
||||
"%01X",
|
||||
subghz_custom_btn_get_original());
|
||||
model->draw_temp_button = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
true);
|
||||
subghz_transmitter->callback(
|
||||
SubGhzCustomEventViewTransmitterSendStart, subghz_transmitter->context);
|
||||
return true;
|
||||
} else if(event->type == InputTypeRelease) {
|
||||
subghz_transmitter->callback(
|
||||
SubGhzCustomEventViewTransmitterSendStop, subghz_transmitter->context);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -389,7 +389,7 @@ static inline FuriHalBtProfile get_hal_bt_profile(BtProfile profile) {
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_restart(Bt* bt) {
|
||||
void bt_restart(Bt* bt) {
|
||||
furi_hal_bt_change_app(get_hal_bt_profile(bt->profile), bt_on_gap_event_callback, bt);
|
||||
furi_hal_bt_start_advertising();
|
||||
}
|
||||
|
||||
@@ -41,28 +41,6 @@ typedef void (*BtStatusChangedCallback)(BtStatus status, void* context);
|
||||
*/
|
||||
bool bt_set_profile(Bt* bt, BtProfile profile);
|
||||
|
||||
void bt_set_profile_adv_name(Bt* bt, const char* fmt, ...);
|
||||
const char* bt_get_profile_adv_name(Bt* bt);
|
||||
|
||||
void bt_set_profile_mac_address(Bt* bt, const uint8_t mac[6]);
|
||||
const uint8_t* bt_get_profile_mac_address(Bt* bt);
|
||||
|
||||
bool bt_remote_rssi(Bt* bt, uint8_t* rssi);
|
||||
|
||||
void bt_set_profile_pairing_method(Bt* bt, GapPairing pairing_method);
|
||||
GapPairing bt_get_profile_pairing_method(Bt* bt);
|
||||
|
||||
/** Stop saving new peer key to flash (in .bt.keys file)
|
||||
*
|
||||
*/
|
||||
void bt_disable_peer_key_update(Bt* bt);
|
||||
|
||||
/** Enable saving peer key to internal flash (enable by default)
|
||||
*
|
||||
* @note This function should be called if bt_disable_peer_key_update was called before
|
||||
*/
|
||||
void bt_enable_peer_key_update(Bt* bt);
|
||||
|
||||
/** Disconnect from Central
|
||||
*
|
||||
* @param bt Bt instance
|
||||
@@ -97,6 +75,30 @@ void bt_keys_storage_set_storage_path(Bt* bt, const char* keys_storage_path);
|
||||
*/
|
||||
void bt_keys_storage_set_default_path(Bt* bt);
|
||||
|
||||
void bt_set_profile_adv_name(Bt* bt, const char* fmt, ...);
|
||||
|
||||
const char* bt_get_profile_adv_name(Bt* bt);
|
||||
|
||||
void bt_set_profile_mac_address(Bt* bt, const uint8_t mac[6]);
|
||||
|
||||
const uint8_t* bt_get_profile_mac_address(Bt* bt);
|
||||
|
||||
bool bt_remote_rssi(Bt* bt, uint8_t* rssi);
|
||||
|
||||
void bt_set_profile_pairing_method(Bt* bt, GapPairing pairing_method);
|
||||
GapPairing bt_get_profile_pairing_method(Bt* bt);
|
||||
|
||||
/** Stop saving new peer key to flash (in .bt.keys file)
|
||||
*
|
||||
*/
|
||||
void bt_disable_peer_key_update(Bt* bt);
|
||||
|
||||
/** Enable saving peer key to internal flash (enable by default)
|
||||
*
|
||||
* @note This function should be called if bt_disable_peer_key_update was called before
|
||||
*/
|
||||
void bt_enable_peer_key_update(Bt* bt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -41,7 +41,7 @@ void popup_free(Popup* popup);
|
||||
*/
|
||||
View* popup_get_view(Popup* popup);
|
||||
|
||||
/** Set popup header text
|
||||
/** Set popup callback function
|
||||
*
|
||||
* @param popup Popup instance
|
||||
* @param callback PopupCallback
|
||||
|
||||
@@ -467,12 +467,13 @@ static void text_input_handle_ok(TextInput* text_input, TextInputModel* model, I
|
||||
if(shift != (text_length == 0)) {
|
||||
selected = char_to_uppercase(selected);
|
||||
}
|
||||
const char replace[2] = {selected, 0};
|
||||
if(model->clear_default_text) {
|
||||
furi_string_set_str(model->temp_str, &selected);
|
||||
furi_string_set_str(model->temp_str, replace);
|
||||
model->cursor_pos = 1;
|
||||
} else {
|
||||
furi_string_set_str(model->temp_str, model->text_buffer);
|
||||
furi_string_replace_at(model->temp_str, model->cursor_pos, 0, &selected);
|
||||
furi_string_replace_at(model->temp_str, model->cursor_pos, 0, replace);
|
||||
model->cursor_pos++;
|
||||
}
|
||||
strcpy(model->text_buffer, furi_string_get_cstr(model->temp_str));
|
||||
@@ -602,6 +603,9 @@ TextInput* text_input_alloc() {
|
||||
{
|
||||
model->validator_text = furi_string_alloc();
|
||||
model->temp_str = furi_string_alloc();
|
||||
model->minimum_length = 1;
|
||||
model->cursor_pos = 0;
|
||||
model->cursor_select = false;
|
||||
},
|
||||
false);
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ bool bt_settings_scene_forget_dev_confirm_on_event(void* context, SceneManagerEv
|
||||
storage_simply_remove(storage, BAD_KB_KEYS_PATH);
|
||||
storage_simply_remove(
|
||||
storage, EXT_PATH("apps_data/hid_ble/") HID_BT_KEYS_STORAGE_NAME);
|
||||
storage_simply_remove(storage, EXT_PATH("authenticator/.bt_hid.keys"));
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
scene_manager_next_scene(app->scene_manager, BtSettingsAppSceneForgetDevSuccess);
|
||||
|
||||
@@ -2773,7 +2773,8 @@ Function,+,subghz_block_generic_get_preset_name,void,"const char*, FuriString*"
|
||||
Function,+,subghz_block_generic_serialize,SubGhzProtocolStatus,"SubGhzBlockGeneric*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_custom_btn_get,uint8_t,
|
||||
Function,-,subghz_custom_btn_get_original,uint8_t,
|
||||
Function,+,subghz_custom_btn_set,void,uint8_t
|
||||
Function,-,subghz_custom_btn_is_allowed,_Bool,
|
||||
Function,+,subghz_custom_btn_set,_Bool,uint8_t
|
||||
Function,-,subghz_custom_btn_set_max,void,uint8_t
|
||||
Function,-,subghz_custom_btn_set_original,void,uint8_t
|
||||
Function,+,subghz_custom_btns_reset,void,
|
||||
|
||||
|
@@ -54,6 +54,9 @@ static const uint8_t gap_erk[16] =
|
||||
|
||||
static Gap* gap = NULL;
|
||||
|
||||
static void gap_advertise_start(GapState new_state);
|
||||
static int32_t gap_app(void* context);
|
||||
|
||||
/** function for updating rssi informations in global Gap object
|
||||
*
|
||||
*/
|
||||
@@ -67,9 +70,6 @@ static inline void fetch_rssi() {
|
||||
FURI_LOG_D(TAG, "Failed to read RSSI");
|
||||
}
|
||||
|
||||
static void gap_advertise_start(GapState new_state);
|
||||
static int32_t gap_app(void* context);
|
||||
|
||||
static void gap_verify_connection_parameters(Gap* gap) {
|
||||
furi_assert(gap);
|
||||
|
||||
@@ -143,7 +143,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
|
||||
FURI_LOG_I(TAG, "Connection parameters event complete");
|
||||
gap_verify_connection_parameters(gap);
|
||||
|
||||
// save rssi for current connection
|
||||
// Save rssi for current connection
|
||||
fetch_rssi();
|
||||
break;
|
||||
}
|
||||
@@ -180,8 +180,8 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
|
||||
|
||||
gap_verify_connection_parameters(gap);
|
||||
|
||||
// Save rssi for current connection
|
||||
fetch_rssi();
|
||||
|
||||
// Start pairing by sending security request
|
||||
aci_gap_slave_security_req(event->Connection_Handle);
|
||||
} break;
|
||||
@@ -266,6 +266,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
|
||||
pairing_complete->Status);
|
||||
aci_gap_terminate(gap->service.connection_handle, 5);
|
||||
} else {
|
||||
// Save RSSI
|
||||
fetch_rssi();
|
||||
|
||||
FURI_LOG_I(TAG, "Pairing complete");
|
||||
@@ -371,9 +372,11 @@ static void gap_init_svc(Gap* gap) {
|
||||
hci_le_set_default_phy(ALL_PHYS_PREFERENCE, TX_2M_PREFERRED, RX_2M_PREFERRED);
|
||||
// Set I/O capability
|
||||
bool keypress_supported = false;
|
||||
// New things below
|
||||
uint8_t conf_mitm = CFG_MITM_PROTECTION;
|
||||
uint8_t conf_used_fixed_pin = CFG_USED_FIXED_PIN;
|
||||
bool conf_bonding = gap->config->bonding_mode;
|
||||
|
||||
if(gap->config->pairing_method == GapPairingPinCodeShow) {
|
||||
aci_gap_set_io_capability(IO_CAP_DISPLAY_ONLY);
|
||||
} else if(gap->config->pairing_method == GapPairingPinCodeVerifyYesNo) {
|
||||
@@ -558,6 +561,7 @@ bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get RSSI
|
||||
uint32_t gap_get_remote_conn_rssi(int8_t* rssi) {
|
||||
if(gap && gap->state == GapStateConnected) {
|
||||
fetch_rssi();
|
||||
|
||||
@@ -229,7 +229,7 @@ void hid_svc_start() {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// add led state output report
|
||||
// Add led state output report
|
||||
char_uuid.Char_UUID_16 = REPORT_CHAR_UUID;
|
||||
status = aci_gatt_add_char(
|
||||
hid_svc->svc_handle,
|
||||
@@ -246,7 +246,7 @@ void hid_svc_start() {
|
||||
FURI_LOG_E(TAG, "Failed to add led state characteristic: %d", status);
|
||||
}
|
||||
|
||||
// add led state char descriptor specifying it is an output report
|
||||
// Add led state char descriptor specifying it is an output report
|
||||
uint8_t buf[2] = {HID_SVC_REPORT_COUNT + 1, 2};
|
||||
desc_uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID;
|
||||
status = aci_gatt_add_char_desc(
|
||||
@@ -266,7 +266,6 @@ void hid_svc_start() {
|
||||
if(status) {
|
||||
FURI_LOG_E(TAG, "Failed to add led state descriptor: %d", status);
|
||||
}
|
||||
|
||||
// Add Report Map characteristic
|
||||
char_uuid.Char_UUID_16 = REPORT_MAP_CHAR_UUID;
|
||||
status = aci_gatt_add_char(
|
||||
|
||||
@@ -29,4 +29,4 @@ bool hid_svc_update_input_report(uint8_t input_report_num, uint8_t* data, uint16
|
||||
|
||||
bool hid_svc_update_info(uint8_t* data, uint16_t len);
|
||||
|
||||
void hid_svc_register_led_state_callback(HidLedStateEventCallback callback, void* context);
|
||||
void hid_svc_register_led_state_callback(HidLedStateEventCallback callback, void* context);
|
||||
|
||||
@@ -164,7 +164,7 @@ FuriHalBtHidLedState hid_host_led_state = {.s_value = 0};
|
||||
uint16_t furi_hal_bt_hid_led_state_cb(uint8_t state, void* ctx) {
|
||||
FuriHalBtHidLedState* led_state = (FuriHalBtHidLedState*)ctx;
|
||||
|
||||
FURI_LOG_D("HalBtHid", "LED state updated !");
|
||||
//FURI_LOG_D("HalBtHid", "LED state updated !");
|
||||
|
||||
led_state->s_value = state;
|
||||
|
||||
@@ -172,7 +172,7 @@ uint16_t furi_hal_bt_hid_led_state_cb(uint8_t state, void* ctx) {
|
||||
}
|
||||
|
||||
uint8_t furi_hal_bt_hid_get_led_state(void) {
|
||||
FURI_LOG_D(
|
||||
/*FURI_LOG_D(
|
||||
"HalBtHid",
|
||||
"LED state: RFU=%d NUMLOCK=%d CAPSLOCK=%d SCROLLLOCK=%d COMPOSE=%d KANA=%d POWER=%d SHIFT=%d",
|
||||
hid_host_led_state.s_undefined,
|
||||
@@ -183,6 +183,7 @@ uint8_t furi_hal_bt_hid_get_led_state(void) {
|
||||
hid_host_led_state.s_kana,
|
||||
hid_host_led_state.s_power,
|
||||
hid_host_led_state.s_shift);
|
||||
*/
|
||||
|
||||
return (hid_host_led_state.s_value >> 1); // bit 0 is undefined (after shift bit location
|
||||
// match with HID led state bits defines)
|
||||
@@ -203,7 +204,6 @@ void furi_hal_bt_hid_start() {
|
||||
hid_svc_start();
|
||||
}
|
||||
// Configure HID Keyboard
|
||||
|
||||
hid_svc_register_led_state_callback(furi_hal_bt_hid_led_state_cb, &hid_host_led_state);
|
||||
|
||||
kb_report = malloc(sizeof(FuriHalBtHidKbReport));
|
||||
|
||||
@@ -218,25 +218,6 @@ float furi_hal_bt_get_rssi();
|
||||
*/
|
||||
uint32_t furi_hal_bt_get_transmitted_packets();
|
||||
|
||||
/** Check & switch C2 to given mode
|
||||
*
|
||||
* @param[in] mode mode to switch into
|
||||
*/
|
||||
bool furi_hal_bt_ensure_c2_mode(BleGlueC2Mode mode);
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
uint32_t source_pc;
|
||||
uint32_t source_lr;
|
||||
uint32_t source_sp;
|
||||
} FuriHalBtHardfaultInfo;
|
||||
|
||||
/** Get hardfault info
|
||||
*
|
||||
* @return hardfault info. NULL if no hardfault
|
||||
*/
|
||||
const FuriHalBtHardfaultInfo* furi_hal_bt_get_hardfault_info();
|
||||
|
||||
/** Modify profile advertisement name and restart bluetooth
|
||||
* @param[in] profile profile type
|
||||
* @param[in] name new adv name
|
||||
@@ -265,6 +246,25 @@ GapPairing furi_hal_bt_get_profile_pairing_method(FuriHalBtProfile profile);
|
||||
|
||||
bool furi_hal_bt_is_connected(void);
|
||||
|
||||
/** Check & switch C2 to given mode
|
||||
*
|
||||
* @param[in] mode mode to switch into
|
||||
*/
|
||||
bool furi_hal_bt_ensure_c2_mode(BleGlueC2Mode mode);
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
uint32_t source_pc;
|
||||
uint32_t source_lr;
|
||||
uint32_t source_sp;
|
||||
} FuriHalBtHardfaultInfo;
|
||||
|
||||
/** Get hardfault info
|
||||
*
|
||||
* @return hardfault info. NULL if no hardfault
|
||||
*/
|
||||
const FuriHalBtHardfaultInfo* furi_hal_bt_get_hardfault_info();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -158,9 +158,6 @@ FuriHalVersionDisplay furi_hal_version_get_hw_display();
|
||||
*/
|
||||
uint32_t furi_hal_version_get_hw_timestamp();
|
||||
|
||||
// Set custom name
|
||||
void furi_hal_version_set_name(const char* name);
|
||||
|
||||
/** Get pointer to target name
|
||||
*
|
||||
* @return Hardware Name C-string
|
||||
@@ -179,6 +176,10 @@ const char* furi_hal_version_get_device_name_ptr();
|
||||
*/
|
||||
const char* furi_hal_version_get_ble_local_device_name_ptr();
|
||||
|
||||
/** Set flipper name
|
||||
*/
|
||||
void furi_hal_version_set_name(const char* name);
|
||||
|
||||
/** Get BLE MAC address
|
||||
*
|
||||
* @return pointer to BLE MAC address
|
||||
|
||||
@@ -54,8 +54,7 @@ struct ReaderAnalyzer {
|
||||
NfcDebugPcap* pcap;
|
||||
};
|
||||
|
||||
static FuriHalNfcDevData reader_analyzer_nfc_data[] = {
|
||||
//XXX
|
||||
const FuriHalNfcDevData reader_analyzer_nfc_data[] = {
|
||||
[ReaderAnalyzerNfcDataMfClassic] =
|
||||
{.interface = FuriHalNfcInterfaceRf,
|
||||
.type = FuriHalNfcTypeA,
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
#include "custom_btn.h"
|
||||
|
||||
static uint8_t custom_btn_id = 0;
|
||||
static uint8_t custom_btn_id = SUBGHZ_CUSTOM_BTN_OK;
|
||||
static uint8_t custom_btn_original = 0;
|
||||
static uint8_t custom_btn_max_btns = 0;
|
||||
|
||||
void subghz_custom_btn_set(uint8_t b) {
|
||||
if(b > custom_btn_max_btns) {
|
||||
custom_btn_id = 0;
|
||||
bool subghz_custom_btn_set(uint8_t btn_id) {
|
||||
if(btn_id > custom_btn_max_btns) {
|
||||
custom_btn_id = SUBGHZ_CUSTOM_BTN_OK;
|
||||
return false;
|
||||
} else {
|
||||
custom_btn_id = b;
|
||||
custom_btn_id = btn_id;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +18,8 @@ uint8_t subghz_custom_btn_get() {
|
||||
return custom_btn_id;
|
||||
}
|
||||
|
||||
void subghz_custom_btn_set_original(uint8_t b) {
|
||||
custom_btn_original = b;
|
||||
void subghz_custom_btn_set_original(uint8_t btn_code) {
|
||||
custom_btn_original = btn_code;
|
||||
}
|
||||
|
||||
uint8_t subghz_custom_btn_get_original() {
|
||||
@@ -31,4 +33,8 @@ void subghz_custom_btn_set_max(uint8_t b) {
|
||||
void subghz_custom_btns_reset() {
|
||||
custom_btn_original = 0;
|
||||
custom_btn_max_btns = 0;
|
||||
}
|
||||
|
||||
bool subghz_custom_btn_is_allowed() {
|
||||
return custom_btn_max_btns != 0;
|
||||
}
|
||||
@@ -8,11 +8,18 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void subghz_custom_btn_set(uint8_t b);
|
||||
// Default btn ID
|
||||
#define SUBGHZ_CUSTOM_BTN_OK (0U)
|
||||
#define SUBGHZ_CUSTOM_BTN_UP (1U)
|
||||
#define SUBGHZ_CUSTOM_BTN_DOWN (2U)
|
||||
#define SUBGHZ_CUSTOM_BTN_LEFT (3U)
|
||||
#define SUBGHZ_CUSTOM_BTN_RIGHT (4U)
|
||||
|
||||
bool subghz_custom_btn_set(uint8_t btn_id);
|
||||
|
||||
uint8_t subghz_custom_btn_get();
|
||||
|
||||
void subghz_custom_btn_set_original(uint8_t b);
|
||||
void subghz_custom_btn_set_original(uint8_t btn_code);
|
||||
|
||||
uint8_t subghz_custom_btn_get_original();
|
||||
|
||||
@@ -20,6 +27,8 @@ void subghz_custom_btn_set_max(uint8_t b);
|
||||
|
||||
void subghz_custom_btns_reset();
|
||||
|
||||
bool subghz_custom_btn_is_allowed();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -308,8 +308,8 @@ bool subghz_protocol_alutech_at_4n_create_data(
|
||||
instance->generic.data_count_bit = 72;
|
||||
bool res = subghz_protocol_alutech_at_4n_gen_data(instance, btn);
|
||||
if(res) {
|
||||
res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
|
||||
if((res == SubGhzProtocolStatusOk) &&
|
||||
if((subghz_block_generic_serialize(&instance->generic, flipper_format, preset) !=
|
||||
SubGhzProtocolStatusOk) ||
|
||||
!flipper_format_write_uint32(flipper_format, "CRC", &instance->crc, 1)) {
|
||||
FURI_LOG_E(TAG, "Unable to add CRC");
|
||||
res = false;
|
||||
@@ -318,6 +318,13 @@ bool subghz_protocol_alutech_at_4n_create_data(
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the button value for the current btn_id
|
||||
* Basic set | 0x11 | 0x22 | 0xFF | 0x44 | 0x33 |
|
||||
* @return Button code
|
||||
*/
|
||||
static uint8_t subghz_protocol_alutech_at_4n_get_btn_code();
|
||||
|
||||
/**
|
||||
* Generating an upload from data.
|
||||
* @param instance Pointer to a SubGhzProtocolEncoderAlutech instance
|
||||
@@ -333,102 +340,8 @@ static bool subghz_protocol_encoder_alutech_at_4n_get_upload(
|
||||
subghz_custom_btn_set_original(btn);
|
||||
}
|
||||
|
||||
uint8_t custom_btn_id = subghz_custom_btn_get();
|
||||
uint8_t original_btn_num = subghz_custom_btn_get_original();
|
||||
btn = subghz_protocol_alutech_at_4n_get_btn_code();
|
||||
|
||||
// Set custom button
|
||||
if(custom_btn_id == 1) {
|
||||
switch(original_btn_num) {
|
||||
case 0x11:
|
||||
btn = 0x22;
|
||||
break;
|
||||
case 0x22:
|
||||
btn = 0x11;
|
||||
break;
|
||||
case 0xFF:
|
||||
btn = 0x11;
|
||||
break;
|
||||
case 0x44:
|
||||
btn = 0x11;
|
||||
break;
|
||||
case 0x33:
|
||||
btn = 0x11;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(custom_btn_id == 2) {
|
||||
switch(original_btn_num) {
|
||||
case 0x11:
|
||||
btn = 0x44;
|
||||
break;
|
||||
case 0x22:
|
||||
btn = 0x44;
|
||||
break;
|
||||
case 0xFF:
|
||||
btn = 0x44;
|
||||
break;
|
||||
case 0x44:
|
||||
btn = 0xFF;
|
||||
break;
|
||||
case 0x33:
|
||||
btn = 0x44;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(custom_btn_id == 3) {
|
||||
switch(original_btn_num) {
|
||||
case 0x11:
|
||||
btn = 0x33;
|
||||
break;
|
||||
case 0x22:
|
||||
btn = 0x33;
|
||||
break;
|
||||
case 0xFF:
|
||||
btn = 0x33;
|
||||
break;
|
||||
case 0x44:
|
||||
btn = 0x33;
|
||||
break;
|
||||
case 0x33:
|
||||
btn = 0x22;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(custom_btn_id == 4) {
|
||||
switch(original_btn_num) {
|
||||
case 0x11:
|
||||
btn = 0xFF;
|
||||
break;
|
||||
case 0x22:
|
||||
btn = 0xFF;
|
||||
break;
|
||||
case 0xFF:
|
||||
btn = 0x22;
|
||||
break;
|
||||
case 0x44:
|
||||
btn = 0x22;
|
||||
break;
|
||||
case 0x33:
|
||||
btn = 0xFF;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if((custom_btn_id == 0) && (original_btn_num != 0)) {
|
||||
btn = original_btn_num;
|
||||
}
|
||||
// Gen new key
|
||||
if(!subghz_protocol_alutech_at_4n_gen_data(instance, btn)) {
|
||||
return false;
|
||||
@@ -788,6 +701,104 @@ SubGhzProtocolStatus subghz_protocol_decoder_alutech_at_4n_deserialize(
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t subghz_protocol_alutech_at_4n_get_btn_code() {
|
||||
uint8_t custom_btn_id = subghz_custom_btn_get();
|
||||
uint8_t original_btn_code = subghz_custom_btn_get_original();
|
||||
uint8_t btn = original_btn_code;
|
||||
|
||||
// Set custom button
|
||||
if((custom_btn_id == SUBGHZ_CUSTOM_BTN_OK) && (original_btn_code != 0)) {
|
||||
// Restore original button code
|
||||
btn = original_btn_code;
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_UP) {
|
||||
switch(original_btn_code) {
|
||||
case 0x11:
|
||||
btn = 0x22;
|
||||
break;
|
||||
case 0x22:
|
||||
btn = 0x11;
|
||||
break;
|
||||
case 0xFF:
|
||||
btn = 0x11;
|
||||
break;
|
||||
case 0x44:
|
||||
btn = 0x11;
|
||||
break;
|
||||
case 0x33:
|
||||
btn = 0x11;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_DOWN) {
|
||||
switch(original_btn_code) {
|
||||
case 0x11:
|
||||
btn = 0x44;
|
||||
break;
|
||||
case 0x22:
|
||||
btn = 0x44;
|
||||
break;
|
||||
case 0xFF:
|
||||
btn = 0x44;
|
||||
break;
|
||||
case 0x44:
|
||||
btn = 0xFF;
|
||||
break;
|
||||
case 0x33:
|
||||
btn = 0x44;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_LEFT) {
|
||||
switch(original_btn_code) {
|
||||
case 0x11:
|
||||
btn = 0x33;
|
||||
break;
|
||||
case 0x22:
|
||||
btn = 0x33;
|
||||
break;
|
||||
case 0xFF:
|
||||
btn = 0x33;
|
||||
break;
|
||||
case 0x44:
|
||||
btn = 0x33;
|
||||
break;
|
||||
case 0x33:
|
||||
btn = 0x22;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_RIGHT) {
|
||||
switch(original_btn_code) {
|
||||
case 0x11:
|
||||
btn = 0xFF;
|
||||
break;
|
||||
case 0x22:
|
||||
btn = 0xFF;
|
||||
break;
|
||||
case 0xFF:
|
||||
btn = 0x22;
|
||||
break;
|
||||
case 0x44:
|
||||
btn = 0x22;
|
||||
break;
|
||||
case 0x33:
|
||||
btn = 0xFF;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_alutech_at_4n_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderAlutech_at_4n* instance = context;
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
|
||||
#define TAG "SubGhzProtocolKeeloq"
|
||||
|
||||
#define KEELOQ_PROG_MODE_OFF (0U)
|
||||
#define KEELOQ_PROG_MODE_BFT (1U)
|
||||
#define KEELOQ_PROG_MODE_APRIMATIC (2U)
|
||||
|
||||
static const SubGhzBlockConst subghz_protocol_keeloq_const = {
|
||||
.te_short = 400,
|
||||
.te_long = 800,
|
||||
@@ -92,10 +96,9 @@ static uint8_t klq_prog_mode;
|
||||
static uint16_t temp_counter;
|
||||
|
||||
void keeloq_reset_original_btn() {
|
||||
subghz_custom_btn_set_original(0);
|
||||
subghz_custom_btn_set_max(0);
|
||||
subghz_custom_btns_reset();
|
||||
temp_counter = 0;
|
||||
klq_prog_mode = 0;
|
||||
klq_prog_mode = KEELOQ_PROG_MODE_OFF;
|
||||
}
|
||||
|
||||
void keeloq_reset_mfname() {
|
||||
@@ -146,6 +149,7 @@ void subghz_protocol_encoder_keeloq_free(void* context) {
|
||||
* Key generation from simple data
|
||||
* @param instance Pointer to a SubGhzProtocolEncoderKeeloq* instance
|
||||
* @param btn Button number, 4 bit
|
||||
* @param counter_up increasing the counter if the value is true
|
||||
*/
|
||||
static bool subghz_protocol_keeloq_gen_data(
|
||||
SubGhzProtocolEncoderKeeloq* instance,
|
||||
@@ -160,29 +164,30 @@ static bool subghz_protocol_keeloq_gen_data(
|
||||
instance->manufacture_name = "";
|
||||
}
|
||||
|
||||
// BFT programming mode on / off conditions
|
||||
if((strcmp(instance->manufacture_name, "BFT") == 0) && (btn == 0xF)) {
|
||||
klq_prog_mode = 1;
|
||||
}
|
||||
if((strcmp(instance->manufacture_name, "BFT") == 0) && (btn != 0xF) && (klq_prog_mode == 1)) {
|
||||
klq_prog_mode = 0;
|
||||
}
|
||||
// Aprimatic programming mode on / off conditions
|
||||
if((strcmp(instance->manufacture_name, "Aprimatic") == 0) && (btn == 0xF)) {
|
||||
klq_prog_mode = 2;
|
||||
}
|
||||
if((strcmp(instance->manufacture_name, "Aprimatic") == 0) && (btn != 0xF) &&
|
||||
(klq_prog_mode == 2)) {
|
||||
klq_prog_mode = 0;
|
||||
// programming mode on / off conditions
|
||||
if(strcmp(instance->manufacture_name, "BFT") == 0) {
|
||||
// BFT programming mode on / off conditions
|
||||
if(btn == 0xF) {
|
||||
klq_prog_mode = KEELOQ_PROG_MODE_BFT;
|
||||
} else if(klq_prog_mode == KEELOQ_PROG_MODE_BFT) {
|
||||
klq_prog_mode = KEELOQ_PROG_MODE_OFF;
|
||||
}
|
||||
} else if(strcmp(instance->manufacture_name, "Aprimatic") == 0) {
|
||||
// Aprimatic programming mode on / off conditions
|
||||
if(btn == 0xF) {
|
||||
klq_prog_mode = KEELOQ_PROG_MODE_APRIMATIC;
|
||||
} else if(klq_prog_mode == KEELOQ_PROG_MODE_APRIMATIC) {
|
||||
klq_prog_mode = KEELOQ_PROG_MODE_OFF;
|
||||
}
|
||||
}
|
||||
// If we using BFT programming mode we will trasmit its seed in hop part like original remote
|
||||
if(klq_prog_mode == 1) {
|
||||
if(klq_prog_mode == KEELOQ_PROG_MODE_BFT) {
|
||||
hop = instance->generic.seed;
|
||||
} else if(klq_prog_mode == 2) {
|
||||
} else if(klq_prog_mode == KEELOQ_PROG_MODE_APRIMATIC) {
|
||||
// If we using Aprimatic programming mode we will trasmit some strange looking hop value, why? cuz manufacturer did it this way :)
|
||||
hop = 0x1A2B3C4D;
|
||||
}
|
||||
if(counter_up && klq_prog_mode == 0) {
|
||||
if(counter_up && klq_prog_mode == KEELOQ_PROG_MODE_OFF) {
|
||||
if(instance->generic.cnt < 0xFFFF) {
|
||||
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) {
|
||||
instance->generic.cnt = 0;
|
||||
@@ -193,50 +198,8 @@ static bool subghz_protocol_keeloq_gen_data(
|
||||
instance->generic.cnt = 0;
|
||||
}
|
||||
}
|
||||
if(klq_prog_mode == 0) {
|
||||
uint32_t decrypt = (uint32_t)btn << 28 |
|
||||
(instance->generic.serial & 0x3FF)
|
||||
<< 16 | //ToDo in some protocols the discriminator is 0
|
||||
instance->generic.cnt;
|
||||
|
||||
if(strcmp(instance->manufacture_name, "Aprimatic") == 0) {
|
||||
// Aprimatic uses 12bit serial number + 2bit APR1 "parity" bit in front of it replacing first 2 bits of serial
|
||||
// Thats in theory! We need to check if this is true for all Aprimatic remotes but we got only 3 recordings to test
|
||||
// For now lets assume that this is true for all Aprimatic remotes, if not we will need to add some more code here
|
||||
uint32_t apri_serial = instance->generic.serial;
|
||||
uint8_t apr1 = 0;
|
||||
for(uint16_t i = 1; i != 0b10000000000; i <<= 1) {
|
||||
if(apri_serial & i) apr1++;
|
||||
}
|
||||
apri_serial &= 0b00001111111111;
|
||||
if(apr1 % 2 == 0) {
|
||||
apri_serial |= 0b110000000000;
|
||||
}
|
||||
decrypt = btn << 28 | (apri_serial & 0xFFF) << 16 | instance->generic.cnt;
|
||||
}
|
||||
|
||||
// DTM Neo, Came_Space uses 12bit -> simple learning -- FAAC_RC,XT , Mutanco_Mutancode, Stilmatic(Schellenberg) -> 12bit normal learning
|
||||
if((strcmp(instance->manufacture_name, "DTM_Neo") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "FAAC_RC,XT") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "Mutanco_Mutancode") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "Stilmatic") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "Came_Space") == 0)) {
|
||||
decrypt = btn << 28 | (instance->generic.serial & 0xFFF) << 16 | instance->generic.cnt;
|
||||
}
|
||||
|
||||
// Nice Smilo, MHouse, JCM, Normstahl -> 8bit serial - simple learning
|
||||
if((strcmp(instance->manufacture_name, "NICE_Smilo") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "NICE_MHOUSE") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "JCM_Tech") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "Normstahl") == 0)) {
|
||||
decrypt = btn << 28 | (instance->generic.serial & 0xFF) << 16 | instance->generic.cnt;
|
||||
}
|
||||
|
||||
// Beninca / Allmatic -> no serial - simple XOR
|
||||
if(strcmp(instance->manufacture_name, "Beninca") == 0) {
|
||||
decrypt = btn << 28 | (0x000) << 16 | instance->generic.cnt;
|
||||
}
|
||||
|
||||
if(klq_prog_mode == KEELOQ_PROG_MODE_OFF) {
|
||||
// Protocols that do not use encryption
|
||||
if(strcmp(instance->manufacture_name, "Unknown") == 0) {
|
||||
code_found_reverse = subghz_protocol_blocks_reverse_key(
|
||||
instance->generic.data, instance->generic.data_count_bit);
|
||||
@@ -247,72 +210,120 @@ static bool subghz_protocol_keeloq_gen_data(
|
||||
} else if(strcmp(instance->manufacture_name, "HCS101") == 0) {
|
||||
hop = instance->generic.cnt << 16 | (btn & 0xF) << 12 | 0x000;
|
||||
} else {
|
||||
for
|
||||
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
|
||||
res = strcmp(furi_string_get_cstr(manufacture_code->name), instance->manufacture_name);
|
||||
if(res == 0) {
|
||||
switch(manufacture_code->type) {
|
||||
case KEELOQ_LEARNING_SIMPLE:
|
||||
//Simple Learning
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, manufacture_code->key);
|
||||
break;
|
||||
case KEELOQ_LEARNING_NORMAL:
|
||||
//Simple Learning
|
||||
man =
|
||||
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
break;
|
||||
case KEELOQ_LEARNING_SECURE:
|
||||
//Secure Learning
|
||||
man = subghz_protocol_keeloq_common_secure_learning(
|
||||
fix, instance->generic.seed, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
break;
|
||||
case KEELOQ_LEARNING_MAGIC_XOR_TYPE_1:
|
||||
//Magic XOR type-1 Learning
|
||||
man = subghz_protocol_keeloq_common_magic_xor_type1_learning(
|
||||
instance->generic.serial, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
break;
|
||||
case KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_1:
|
||||
//Magic Serial Type 1 learning
|
||||
man = subghz_protocol_keeloq_common_magic_serial_type1_learning(
|
||||
fix, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
break;
|
||||
case KEELOQ_LEARNING_UNKNOWN:
|
||||
if(kl_type == 1) {
|
||||
hop =
|
||||
subghz_protocol_keeloq_common_encrypt(decrypt, manufacture_code->key);
|
||||
}
|
||||
if(kl_type == 2) {
|
||||
man = subghz_protocol_keeloq_common_normal_learning(
|
||||
fix, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
}
|
||||
if(kl_type == 3) {
|
||||
man = subghz_protocol_keeloq_common_secure_learning(
|
||||
fix, instance->generic.seed, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
}
|
||||
if(kl_type == 4) {
|
||||
man = subghz_protocol_keeloq_common_magic_xor_type1_learning(
|
||||
instance->generic.serial, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
}
|
||||
break;
|
||||
// Protocols that use encryption
|
||||
uint32_t decrypt = (uint32_t)btn << 28 |
|
||||
(instance->generic.serial & 0x3FF)
|
||||
<< 16 | //ToDo in some protocols the discriminator is 0
|
||||
instance->generic.cnt;
|
||||
|
||||
if(strcmp(instance->manufacture_name, "Aprimatic") == 0) {
|
||||
// Aprimatic uses 12bit serial number + 2bit APR1 "parity" bit in front of it replacing first 2 bits of serial
|
||||
// Thats in theory! We need to check if this is true for all Aprimatic remotes but we got only 3 recordings to test
|
||||
// For now lets assume that this is true for all Aprimatic remotes, if not we will need to add some more code here
|
||||
uint32_t apri_serial = instance->generic.serial;
|
||||
uint8_t apr1 = 0;
|
||||
for(uint16_t i = 1; i != 0b10000000000; i <<= 1) {
|
||||
if(apri_serial & i) apr1++;
|
||||
}
|
||||
break;
|
||||
apri_serial &= 0b00001111111111;
|
||||
if(apr1 % 2 == 0) {
|
||||
apri_serial |= 0b110000000000;
|
||||
}
|
||||
decrypt = btn << 28 | (apri_serial & 0xFFF) << 16 | instance->generic.cnt;
|
||||
} else if(
|
||||
(strcmp(instance->manufacture_name, "DTM_Neo") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "FAAC_RC,XT") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "Mutanco_Mutancode") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "Stilmatic") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "Came_Space") == 0)) {
|
||||
// DTM Neo, Came_Space uses 12bit serial -> simple learning
|
||||
// FAAC_RC,XT , Mutanco_Mutancode, Stilmatic(Schellenberg) 12bit serial -> normal learning
|
||||
decrypt = btn << 28 | (instance->generic.serial & 0xFFF) << 16 |
|
||||
instance->generic.cnt;
|
||||
} else if(
|
||||
(strcmp(instance->manufacture_name, "NICE_Smilo") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "NICE_MHOUSE") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "JCM_Tech") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "Normstahl") == 0)) {
|
||||
// Nice Smilo, MHouse, JCM, Normstahl -> 8bit serial - simple learning
|
||||
decrypt = btn << 28 | (instance->generic.serial & 0xFF) << 16 |
|
||||
instance->generic.cnt;
|
||||
} else if(strcmp(instance->manufacture_name, "Beninca") == 0) {
|
||||
decrypt = btn << 28 | (0x000) << 16 | instance->generic.cnt;
|
||||
// Beninca / Allmatic -> no serial - simple XOR
|
||||
}
|
||||
}
|
||||
|
||||
for
|
||||
M_EACH(
|
||||
manufacture_code,
|
||||
*subghz_keystore_get_data(instance->keystore),
|
||||
SubGhzKeyArray_t) {
|
||||
res = strcmp(
|
||||
furi_string_get_cstr(manufacture_code->name), instance->manufacture_name);
|
||||
if(res == 0) {
|
||||
switch(manufacture_code->type) {
|
||||
case KEELOQ_LEARNING_SIMPLE:
|
||||
//Simple Learning
|
||||
hop = subghz_protocol_keeloq_common_encrypt(
|
||||
decrypt, manufacture_code->key);
|
||||
break;
|
||||
case KEELOQ_LEARNING_NORMAL:
|
||||
//Simple Learning
|
||||
man = subghz_protocol_keeloq_common_normal_learning(
|
||||
fix, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
break;
|
||||
case KEELOQ_LEARNING_SECURE:
|
||||
//Secure Learning
|
||||
man = subghz_protocol_keeloq_common_secure_learning(
|
||||
fix, instance->generic.seed, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
break;
|
||||
case KEELOQ_LEARNING_MAGIC_XOR_TYPE_1:
|
||||
//Magic XOR type-1 Learning
|
||||
man = subghz_protocol_keeloq_common_magic_xor_type1_learning(
|
||||
instance->generic.serial, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
break;
|
||||
case KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_1:
|
||||
//Magic Serial Type 1 learning
|
||||
man = subghz_protocol_keeloq_common_magic_serial_type1_learning(
|
||||
fix, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
break;
|
||||
case KEELOQ_LEARNING_UNKNOWN:
|
||||
if(kl_type == 1) {
|
||||
hop = subghz_protocol_keeloq_common_encrypt(
|
||||
decrypt, manufacture_code->key);
|
||||
}
|
||||
if(kl_type == 2) {
|
||||
man = subghz_protocol_keeloq_common_normal_learning(
|
||||
fix, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
}
|
||||
if(kl_type == 3) {
|
||||
man = subghz_protocol_keeloq_common_secure_learning(
|
||||
fix, instance->generic.seed, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
}
|
||||
if(kl_type == 4) {
|
||||
man = subghz_protocol_keeloq_common_magic_xor_type1_learning(
|
||||
instance->generic.serial, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(hop) {
|
||||
uint64_t yek = (uint64_t)fix << 32 | hop;
|
||||
instance->generic.data =
|
||||
subghz_protocol_blocks_reverse_key(yek, instance->generic.data_count_bit);
|
||||
}
|
||||
return true;
|
||||
} // What should happen if seed = 0 in bft programming mode
|
||||
return true; // Always return true
|
||||
}
|
||||
|
||||
bool subghz_protocol_keeloq_create_data(
|
||||
@@ -363,6 +374,14 @@ bool subghz_protocol_keeloq_bft_create_data(
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the button value for the current btn_id
|
||||
* Basic set | 0x1 | 0x2 | 0x4 | 0x8 | 0xA or Special Learning Code |
|
||||
* @param last_btn_code Candidate for the last button
|
||||
* @return Button code
|
||||
*/
|
||||
static uint8_t subghz_protocol_keeloq_get_btn_code(uint8_t last_btn_code);
|
||||
|
||||
/**
|
||||
* Generating an upload from data.
|
||||
* @param instance Pointer to a SubGhzProtocolEncoderKeeloq instance
|
||||
@@ -380,9 +399,9 @@ static bool
|
||||
if(instance->manufacture_name == 0x0) {
|
||||
instance->manufacture_name = "";
|
||||
}
|
||||
if(klq_prog_mode == 1) {
|
||||
if(klq_prog_mode == KEELOQ_PROG_MODE_BFT) {
|
||||
instance->manufacture_name = "BFT";
|
||||
} else if(klq_prog_mode == 2) {
|
||||
} else if(klq_prog_mode == KEELOQ_PROG_MODE_APRIMATIC) {
|
||||
instance->manufacture_name = "Aprimatic";
|
||||
}
|
||||
uint8_t klq_last_custom_btn = 0xA;
|
||||
@@ -391,118 +410,9 @@ static bool
|
||||
klq_last_custom_btn = 0xF;
|
||||
}
|
||||
|
||||
uint8_t custom_btn_id = subghz_custom_btn_get();
|
||||
uint8_t original_btn_num = subghz_custom_btn_get_original();
|
||||
// Set custom button
|
||||
if(custom_btn_id == 1) {
|
||||
switch(original_btn_num) {
|
||||
case 0x1:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0xA:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0xF:
|
||||
btn = 0x1;
|
||||
break;
|
||||
btn = subghz_protocol_keeloq_get_btn_code(klq_last_custom_btn);
|
||||
|
||||
default:
|
||||
btn = 0x1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(custom_btn_id == 2) {
|
||||
switch(original_btn_num) {
|
||||
case 0x1:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0xA:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = klq_last_custom_btn;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0xF:
|
||||
btn = 0x4;
|
||||
break;
|
||||
|
||||
default:
|
||||
btn = 0x4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(custom_btn_id == 3) {
|
||||
switch(original_btn_num) {
|
||||
case 0x1:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0xA:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0xF:
|
||||
btn = 0x8;
|
||||
break;
|
||||
|
||||
default:
|
||||
btn = 0x8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(custom_btn_id == 4) {
|
||||
switch(original_btn_num) {
|
||||
case 0x1:
|
||||
btn = klq_last_custom_btn;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = klq_last_custom_btn;
|
||||
break;
|
||||
case 0xA:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = klq_last_custom_btn;
|
||||
break;
|
||||
case 0xF:
|
||||
btn = 0x2;
|
||||
break;
|
||||
|
||||
default:
|
||||
btn = 0x2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if((custom_btn_id == 0) && (original_btn_num != 0)) {
|
||||
btn = original_btn_num;
|
||||
}
|
||||
// Generate new key
|
||||
|
||||
if(subghz_protocol_keeloq_gen_data(instance, btn, true)) {
|
||||
// OK
|
||||
} else {
|
||||
@@ -669,7 +579,7 @@ void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment) {
|
||||
instance->keystore = subghz_environment_get_keystore(environment);
|
||||
instance->manufacture_from_file = furi_string_alloc();
|
||||
|
||||
klq_prog_mode = 0;
|
||||
klq_prog_mode = KEELOQ_PROG_MODE_OFF;
|
||||
|
||||
return instance;
|
||||
}
|
||||
@@ -829,185 +739,19 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
uint8_t btn = (uint8_t)(fix >> 28);
|
||||
uint32_t decrypt = 0;
|
||||
uint64_t man;
|
||||
int res = 0;
|
||||
bool mf_not_set = false;
|
||||
if(mfname == 0x0) {
|
||||
mfname = "";
|
||||
}
|
||||
|
||||
if(strcmp(mfname, "") == 0) {
|
||||
for
|
||||
M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) {
|
||||
switch(manufacture_code->type) {
|
||||
case KEELOQ_LEARNING_SIMPLE:
|
||||
// Simple Learning
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_NORMAL:
|
||||
// Normal Learning
|
||||
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
|
||||
man = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_SECURE:
|
||||
man = subghz_protocol_keeloq_common_secure_learning(
|
||||
fix, instance->seed, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_MAGIC_XOR_TYPE_1:
|
||||
man = subghz_protocol_keeloq_common_magic_xor_type1_learning(
|
||||
fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_1:
|
||||
man = subghz_protocol_keeloq_common_magic_serial_type1_learning(
|
||||
fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_2:
|
||||
man = subghz_protocol_keeloq_common_magic_serial_type2_learning(
|
||||
fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_3:
|
||||
man = subghz_protocol_keeloq_common_magic_serial_type3_learning(
|
||||
fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_UNKNOWN:
|
||||
// Simple Learning
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
kl_type = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check for mirrored man
|
||||
uint64_t man_rev = 0;
|
||||
uint64_t man_rev_byte = 0;
|
||||
for(uint8_t i = 0; i < 64; i += 8) {
|
||||
man_rev_byte = (uint8_t)(manufacture_code->key >> i);
|
||||
man_rev = man_rev | man_rev_byte << (56 - i);
|
||||
}
|
||||
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
kl_type = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
//###########################
|
||||
// Normal Learning
|
||||
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
|
||||
man = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
kl_type = 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check for mirrored man
|
||||
man = subghz_protocol_keeloq_common_normal_learning(fix, man_rev);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
kl_type = 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Secure Learning
|
||||
man = subghz_protocol_keeloq_common_secure_learning(
|
||||
fix, instance->seed, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
kl_type = 3;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check for mirrored man
|
||||
man = subghz_protocol_keeloq_common_secure_learning(fix, instance->seed, man_rev);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
kl_type = 3;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Magic xor type1 learning
|
||||
man = subghz_protocol_keeloq_common_magic_xor_type1_learning(
|
||||
fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
kl_type = 4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check for mirrored man
|
||||
man = subghz_protocol_keeloq_common_magic_xor_type1_learning(fix, man_rev);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
kl_type = 4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if(strcmp(mfname, "Unknown") == 0) {
|
||||
if(strcmp(mfname, "Unknown") == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
} else if(strcmp(mfname, "") == 0) {
|
||||
mf_not_set = true;
|
||||
}
|
||||
for
|
||||
M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) {
|
||||
res = strcmp(furi_string_get_cstr(manufacture_code->name), mfname);
|
||||
if(res == 0) {
|
||||
if(mf_not_set || (strcmp(furi_string_get_cstr(manufacture_code->name), mfname) == 0)) {
|
||||
switch(manufacture_code->type) {
|
||||
case KEELOQ_LEARNING_SIMPLE:
|
||||
// Simple Learning
|
||||
@@ -1060,6 +804,26 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_2:
|
||||
man = subghz_protocol_keeloq_common_magic_serial_type2_learning(
|
||||
fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_3:
|
||||
man = subghz_protocol_keeloq_common_magic_serial_type3_learning(
|
||||
fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_UNKNOWN:
|
||||
// Simple Learning
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
|
||||
@@ -1069,6 +833,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
kl_type = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check for mirrored man
|
||||
uint64_t man_rev = 0;
|
||||
uint64_t man_rev_byte = 0;
|
||||
@@ -1076,6 +841,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
man_rev_byte = (uint8_t)(manufacture_code->key >> i);
|
||||
man_rev = man_rev | man_rev_byte << (56 - i);
|
||||
}
|
||||
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev);
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
@@ -1083,6 +849,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
kl_type = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
//###########################
|
||||
// Normal Learning
|
||||
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
|
||||
@@ -1153,7 +920,6 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*manufacture_name = "Unknown";
|
||||
mfname = "Unknown";
|
||||
@@ -1170,8 +936,8 @@ static void subghz_protocol_keeloq_check_remote_controller(
|
||||
uint32_t key_fix = key >> 32;
|
||||
uint32_t key_hop = key & 0x00000000ffffffff;
|
||||
|
||||
// If we are in BFT programming mode we will set previous remembered counter and skip mf keys check
|
||||
if(klq_prog_mode == 0) {
|
||||
// If we are in BFT / Aprimatic programming mode we will set previous remembered counter and skip mf keys check
|
||||
if(klq_prog_mode == KEELOQ_PROG_MODE_OFF) {
|
||||
// Check key AN-Motors
|
||||
if((key_hop >> 24) == ((key_hop >> 16) & 0x00ff) &&
|
||||
(key_fix >> 28) == ((key_hop >> 12) & 0x0f) && (key_hop & 0xFFF) == 0x404) {
|
||||
@@ -1188,11 +954,11 @@ static void subghz_protocol_keeloq_check_remote_controller(
|
||||
}
|
||||
temp_counter = instance->cnt;
|
||||
|
||||
} else if(klq_prog_mode == 1) {
|
||||
} else if(klq_prog_mode == KEELOQ_PROG_MODE_BFT) {
|
||||
*manufacture_name = "BFT";
|
||||
mfname = *manufacture_name;
|
||||
instance->cnt = temp_counter;
|
||||
} else if(klq_prog_mode == 2) {
|
||||
} else if(klq_prog_mode == KEELOQ_PROG_MODE_APRIMATIC) {
|
||||
*manufacture_name = "Aprimatic";
|
||||
mfname = *manufacture_name;
|
||||
instance->cnt = temp_counter;
|
||||
@@ -1302,6 +1068,125 @@ SubGhzProtocolStatus
|
||||
return res;
|
||||
}
|
||||
|
||||
static uint8_t subghz_protocol_keeloq_get_btn_code(uint8_t last_btn_code) {
|
||||
uint8_t custom_btn_id = subghz_custom_btn_get();
|
||||
uint8_t original_btn_code = subghz_custom_btn_get_original();
|
||||
uint8_t btn = original_btn_code;
|
||||
|
||||
if(last_btn_code == 0) {
|
||||
last_btn_code = 0xA;
|
||||
}
|
||||
|
||||
// Set custom button
|
||||
// Basic set | 0x1 | 0x2 | 0x4 | 0x8 | 0xA or Special Learning Code |
|
||||
if((custom_btn_id == SUBGHZ_CUSTOM_BTN_OK) && (original_btn_code != 0)) {
|
||||
// Restore original button code
|
||||
btn = original_btn_code;
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_UP) {
|
||||
switch(original_btn_code) {
|
||||
case 0x1:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0xA:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0xF:
|
||||
btn = 0x1;
|
||||
break;
|
||||
|
||||
default:
|
||||
btn = 0x1;
|
||||
break;
|
||||
}
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_DOWN) {
|
||||
switch(original_btn_code) {
|
||||
case 0x1:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0xA:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = last_btn_code;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0xF:
|
||||
btn = 0x4;
|
||||
break;
|
||||
|
||||
default:
|
||||
btn = 0x4;
|
||||
break;
|
||||
}
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_LEFT) {
|
||||
switch(original_btn_code) {
|
||||
case 0x1:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0xA:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0xF:
|
||||
btn = 0x8;
|
||||
break;
|
||||
|
||||
default:
|
||||
btn = 0x8;
|
||||
break;
|
||||
}
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_RIGHT) {
|
||||
switch(original_btn_code) {
|
||||
case 0x1:
|
||||
btn = last_btn_code;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = last_btn_code;
|
||||
break;
|
||||
case 0xA:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = last_btn_code;
|
||||
break;
|
||||
case 0xF:
|
||||
btn = 0x2;
|
||||
break;
|
||||
|
||||
default:
|
||||
btn = 0x2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderKeeloq* instance = context;
|
||||
|
||||
@@ -117,6 +117,13 @@ void subghz_protocol_encoder_nice_flor_s_free(void* context) {
|
||||
|
||||
static void subghz_protocol_nice_one_get_data(uint8_t* p, uint8_t num_parcel, uint8_t hold_bit);
|
||||
|
||||
/**
|
||||
* Defines the button value for the current btn_id
|
||||
* Basic set | 0x1 | 0x2 | 0x4 | 0x8 |
|
||||
* @return Button code
|
||||
*/
|
||||
static uint8_t subghz_protocol_nice_flor_s_get_btn_code();
|
||||
|
||||
/**
|
||||
* Generating an upload from data.
|
||||
* @param instance Pointer to a SubGhzProtocolEncoderNiceFlorS instance
|
||||
@@ -135,71 +142,7 @@ static void subghz_protocol_encoder_nice_flor_s_get_upload(
|
||||
subghz_custom_btn_set_original(btn);
|
||||
}
|
||||
|
||||
uint8_t custom_btn_id = subghz_custom_btn_get();
|
||||
uint8_t original_btn_num = subghz_custom_btn_get_original();
|
||||
|
||||
// Set custom button
|
||||
if(custom_btn_id == 1) {
|
||||
switch(original_btn_num) {
|
||||
case 0x1:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(custom_btn_id == 2) {
|
||||
switch(original_btn_num) {
|
||||
case 0x1:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x4;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(custom_btn_id == 3) {
|
||||
switch(original_btn_num) {
|
||||
case 0x1:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if((custom_btn_id == 0) && (original_btn_num != 0)) {
|
||||
btn = original_btn_num;
|
||||
}
|
||||
btn = subghz_protocol_nice_flor_s_get_btn_code();
|
||||
|
||||
size_t size_upload = ((instance->generic.data_count_bit * 2) + ((37 + 2 + 2) * 2) * 16);
|
||||
if(size_upload > instance->encoder.size_upload) {
|
||||
@@ -808,6 +751,74 @@ SubGhzProtocolStatus
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t subghz_protocol_nice_flor_s_get_btn_code() {
|
||||
uint8_t custom_btn_id = subghz_custom_btn_get();
|
||||
uint8_t original_btn_code = subghz_custom_btn_get_original();
|
||||
uint8_t btn = original_btn_code;
|
||||
|
||||
// Set custom button
|
||||
if((custom_btn_id == SUBGHZ_CUSTOM_BTN_OK) && (original_btn_code != 0)) {
|
||||
// Restore original button code
|
||||
btn = original_btn_code;
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_UP) {
|
||||
switch(original_btn_code) {
|
||||
case 0x1:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_DOWN) {
|
||||
switch(original_btn_code) {
|
||||
case 0x1:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x4;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_LEFT) {
|
||||
switch(original_btn_code) {
|
||||
case 0x1:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_nice_flor_s_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderNiceFlorS* instance = context;
|
||||
|
||||
@@ -375,6 +375,13 @@ static uint64_t subghz_protocol_secplus_v2_encode_half(uint8_t roll_array[], uin
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the button value for the current btn_id
|
||||
* Basic set | 0x68 | 0x80 | 0x81 | 0xE2 |
|
||||
* @return Button code
|
||||
*/
|
||||
static uint8_t subghz_protocol_secplus_v2_get_btn_code();
|
||||
|
||||
/**
|
||||
* Security+ 2.0 message encoding
|
||||
* @param instance SubGhzProtocolEncoderSecPlus_v2*
|
||||
@@ -386,70 +393,8 @@ static void subghz_protocol_secplus_v2_encode(SubGhzProtocolEncoderSecPlus_v2* i
|
||||
subghz_custom_btn_set_original(instance->generic.btn);
|
||||
}
|
||||
|
||||
uint8_t custom_btn_id = subghz_custom_btn_get();
|
||||
uint8_t original_btn_num = subghz_custom_btn_get_original();
|
||||
instance->generic.btn = subghz_protocol_secplus_v2_get_btn_code();
|
||||
|
||||
// Set custom button
|
||||
if(custom_btn_id == 1) {
|
||||
switch(original_btn_num) {
|
||||
case 0x68:
|
||||
instance->generic.btn = 0x80;
|
||||
break;
|
||||
case 0x80:
|
||||
instance->generic.btn = 0x68;
|
||||
break;
|
||||
case 0x81:
|
||||
instance->generic.btn = 0x80;
|
||||
break;
|
||||
case 0xE2:
|
||||
instance->generic.btn = 0x80;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(custom_btn_id == 2) {
|
||||
switch(original_btn_num) {
|
||||
case 0x68:
|
||||
instance->generic.btn = 0x81;
|
||||
break;
|
||||
case 0x80:
|
||||
instance->generic.btn = 0x81;
|
||||
break;
|
||||
case 0x81:
|
||||
instance->generic.btn = 0x68;
|
||||
break;
|
||||
case 0xE2:
|
||||
instance->generic.btn = 0x81;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(custom_btn_id == 3) {
|
||||
switch(original_btn_num) {
|
||||
case 0x68:
|
||||
instance->generic.btn = 0xE2;
|
||||
break;
|
||||
case 0x80:
|
||||
instance->generic.btn = 0xE2;
|
||||
break;
|
||||
case 0x81:
|
||||
instance->generic.btn = 0xE2;
|
||||
break;
|
||||
case 0xE2:
|
||||
instance->generic.btn = 0x68;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if((custom_btn_id == 0) && (original_btn_num != 0)) {
|
||||
instance->generic.btn = original_btn_num;
|
||||
}
|
||||
uint32_t fixed_1[1] = {instance->generic.btn << 12 | instance->generic.serial >> 20};
|
||||
uint32_t fixed_2[1] = {instance->generic.serial & 0xFFFFF};
|
||||
uint8_t rolling_digits[18] = {0};
|
||||
@@ -888,6 +833,74 @@ SubGhzProtocolStatus
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t subghz_protocol_secplus_v2_get_btn_code() {
|
||||
uint8_t custom_btn_id = subghz_custom_btn_get();
|
||||
uint8_t original_btn_code = subghz_custom_btn_get_original();
|
||||
uint8_t btn = original_btn_code;
|
||||
|
||||
// Set custom button
|
||||
if((custom_btn_id == SUBGHZ_CUSTOM_BTN_OK) && (original_btn_code != 0)) {
|
||||
// Restore original button code
|
||||
btn = original_btn_code;
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_UP) {
|
||||
switch(original_btn_code) {
|
||||
case 0x68:
|
||||
btn = 0x80;
|
||||
break;
|
||||
case 0x80:
|
||||
btn = 0x68;
|
||||
break;
|
||||
case 0x81:
|
||||
btn = 0x80;
|
||||
break;
|
||||
case 0xE2:
|
||||
btn = 0x80;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_DOWN) {
|
||||
switch(original_btn_code) {
|
||||
case 0x68:
|
||||
btn = 0x81;
|
||||
break;
|
||||
case 0x80:
|
||||
btn = 0x81;
|
||||
break;
|
||||
case 0x81:
|
||||
btn = 0x68;
|
||||
break;
|
||||
case 0xE2:
|
||||
btn = 0x81;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_LEFT) {
|
||||
switch(original_btn_code) {
|
||||
case 0x68:
|
||||
btn = 0xE2;
|
||||
break;
|
||||
case 0x80:
|
||||
btn = 0xE2;
|
||||
break;
|
||||
case 0x81:
|
||||
btn = 0xE2;
|
||||
break;
|
||||
case 0xE2:
|
||||
btn = 0x68;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_secplus_v2_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderSecPlus_v2* instance = context;
|
||||
|
||||
@@ -97,6 +97,13 @@ void subghz_protocol_encoder_somfy_telis_free(void* context) {
|
||||
free(instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the button value for the current btn_id
|
||||
* Basic set | 0x1 | 0x2 | 0x4 | 0x8 |
|
||||
* @return Button code
|
||||
*/
|
||||
static uint8_t subghz_protocol_somfy_telis_get_btn_code();
|
||||
|
||||
static bool subghz_protocol_somfy_telis_gen_data(
|
||||
SubGhzProtocolEncoderSomfyTelis* instance,
|
||||
uint8_t btn,
|
||||
@@ -115,71 +122,7 @@ static bool subghz_protocol_somfy_telis_gen_data(
|
||||
subghz_custom_btn_set_original(btn);
|
||||
}
|
||||
|
||||
uint8_t custom_btn_id = subghz_custom_btn_get();
|
||||
uint8_t original_btn_num = subghz_custom_btn_get_original();
|
||||
|
||||
// Set custom button
|
||||
if(custom_btn_id == 1) {
|
||||
switch(original_btn_num) {
|
||||
case 0x1:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(custom_btn_id == 2) {
|
||||
switch(original_btn_num) {
|
||||
case 0x1:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x4;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(custom_btn_id == 3) {
|
||||
switch(original_btn_num) {
|
||||
case 0x1:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if((custom_btn_id == 0) && (original_btn_num != 0)) {
|
||||
btn = original_btn_num;
|
||||
}
|
||||
btn = subghz_protocol_somfy_telis_get_btn_code();
|
||||
|
||||
if(instance->generic.cnt < 0xFFFF) {
|
||||
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) {
|
||||
@@ -725,6 +668,74 @@ SubGhzProtocolStatus
|
||||
subghz_protocol_somfy_telis_const.min_count_bit_for_found);
|
||||
}
|
||||
|
||||
static uint8_t subghz_protocol_somfy_telis_get_btn_code() {
|
||||
uint8_t custom_btn_id = subghz_custom_btn_get();
|
||||
uint8_t original_btn_code = subghz_custom_btn_get_original();
|
||||
uint8_t btn = original_btn_code;
|
||||
|
||||
// Set custom button
|
||||
if((custom_btn_id == SUBGHZ_CUSTOM_BTN_OK) && (original_btn_code != 0)) {
|
||||
// Restore original button code
|
||||
btn = original_btn_code;
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_UP) {
|
||||
switch(original_btn_code) {
|
||||
case 0x1:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x1;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_DOWN) {
|
||||
switch(original_btn_code) {
|
||||
case 0x1:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x4;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x2;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x4;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_LEFT) {
|
||||
switch(original_btn_code) {
|
||||
case 0x1:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x2:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x4:
|
||||
btn = 0x8;
|
||||
break;
|
||||
case 0x8:
|
||||
btn = 0x2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_somfy_telis_get_string(void* context, FuriString* output) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderSomfyTelis* instance = context;
|
||||
|
||||
@@ -163,36 +163,41 @@ static bool
|
||||
instance->generic.data, instance->generic.data_count_bit);
|
||||
hop = code_found_reverse & 0x00000000ffffffff;
|
||||
} else {
|
||||
for
|
||||
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
|
||||
res = strcmp(furi_string_get_cstr(manufacture_code->name), instance->manufacture_name);
|
||||
if(res == 0) {
|
||||
switch(manufacture_code->type) {
|
||||
case KEELOQ_LEARNING_SIMPLE:
|
||||
//Simple Learning
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, manufacture_code->key);
|
||||
break;
|
||||
case KEELOQ_LEARNING_NORMAL:
|
||||
//Normal Learning
|
||||
man =
|
||||
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
break;
|
||||
case KEELOQ_LEARNING_UNKNOWN:
|
||||
if(kl_type == 1) {
|
||||
for
|
||||
M_EACH(
|
||||
manufacture_code,
|
||||
*subghz_keystore_get_data(instance->keystore),
|
||||
SubGhzKeyArray_t) {
|
||||
res = strcmp(
|
||||
furi_string_get_cstr(manufacture_code->name), instance->manufacture_name);
|
||||
if(res == 0) {
|
||||
switch(manufacture_code->type) {
|
||||
case KEELOQ_LEARNING_SIMPLE:
|
||||
//Simple Learning
|
||||
hop =
|
||||
subghz_protocol_keeloq_common_encrypt(decrypt, manufacture_code->key);
|
||||
}
|
||||
if(kl_type == 2) {
|
||||
break;
|
||||
case KEELOQ_LEARNING_NORMAL:
|
||||
//Normal Learning
|
||||
man = subghz_protocol_keeloq_common_normal_learning(
|
||||
fix, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
break;
|
||||
case KEELOQ_LEARNING_UNKNOWN:
|
||||
if(kl_type == 1) {
|
||||
hop = subghz_protocol_keeloq_common_encrypt(
|
||||
decrypt, manufacture_code->key);
|
||||
}
|
||||
if(kl_type == 2) {
|
||||
man = subghz_protocol_keeloq_common_normal_learning(
|
||||
fix, manufacture_code->key);
|
||||
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(hop) {
|
||||
uint64_t yek = (uint64_t)fix << 32 | hop;
|
||||
@@ -517,90 +522,19 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector(
|
||||
uint8_t btn = (uint8_t)(fix >> 24);
|
||||
uint32_t decrypt = 0;
|
||||
uint64_t man_normal_learning;
|
||||
int res = 0;
|
||||
bool mf_not_set = false;
|
||||
if(mfname == 0x0) {
|
||||
mfname = "";
|
||||
}
|
||||
|
||||
if(strcmp(mfname, "") == 0) {
|
||||
for
|
||||
M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) {
|
||||
switch(manufacture_code->type) {
|
||||
case KEELOQ_LEARNING_SIMPLE:
|
||||
// Simple Learning
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
|
||||
if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_NORMAL:
|
||||
// Normal Learning
|
||||
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
|
||||
man_normal_learning =
|
||||
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
|
||||
if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_UNKNOWN:
|
||||
// Simple Learning
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
|
||||
if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
kl_type = 1;
|
||||
return 1;
|
||||
}
|
||||
// Check for mirrored man
|
||||
uint64_t man_rev = 0;
|
||||
uint64_t man_rev_byte = 0;
|
||||
for(uint8_t i = 0; i < 64; i += 8) {
|
||||
man_rev_byte = (uint8_t)(manufacture_code->key >> i);
|
||||
man_rev = man_rev | man_rev_byte << (56 - i);
|
||||
}
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev);
|
||||
if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
kl_type = 1;
|
||||
return 1;
|
||||
}
|
||||
//###########################
|
||||
// Normal Learning
|
||||
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
|
||||
man_normal_learning =
|
||||
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
|
||||
if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
kl_type = 2;
|
||||
return 1;
|
||||
}
|
||||
// Check for mirrored man
|
||||
man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
|
||||
if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
mfname = *manufacture_name;
|
||||
kl_type = 2;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if(strcmp(mfname, "Unknown") == 0) {
|
||||
if(strcmp(mfname, "Unknown") == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
} else if(strcmp(mfname, "") == 0) {
|
||||
mf_not_set = true;
|
||||
}
|
||||
for
|
||||
M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) {
|
||||
res = strcmp(furi_string_get_cstr(manufacture_code->name), mfname);
|
||||
if(res == 0) {
|
||||
if(mf_not_set || (strcmp(furi_string_get_cstr(manufacture_code->name), mfname) == 0)) {
|
||||
switch(manufacture_code->type) {
|
||||
case KEELOQ_LEARNING_SIMPLE:
|
||||
// Simple Learning
|
||||
@@ -663,7 +597,6 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector(
|
||||
kl_type = 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check for mirrored man
|
||||
man_normal_learning =
|
||||
subghz_protocol_keeloq_common_normal_learning(fix, man_rev);
|
||||
@@ -679,7 +612,6 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*manufacture_name = "Unknown";
|
||||
mfname = "Unknown";
|
||||
|
||||
@@ -31,11 +31,7 @@ static Version version = {
|
||||
.git_hash = GIT_COMMIT,
|
||||
.git_branch = GIT_BRANCH,
|
||||
.build_date = BUILD_DATE,
|
||||
#ifdef FURI_CUSTOM_FLIPPER_NAME
|
||||
.custom_flipper_name = FURI_CUSTOM_FLIPPER_NAME,
|
||||
#else
|
||||
.custom_flipper_name = NULL,
|
||||
#endif
|
||||
.version = VERSION
|
||||
#ifdef FURI_RAM_EXEC
|
||||
" (RAM)"
|
||||
|
||||
@@ -65,7 +65,7 @@ const char* version_get_builddate(const Version* v);
|
||||
*/
|
||||
const char* version_get_version(const Version* v);
|
||||
|
||||
/** Get custom flipper name if set in ENV
|
||||
/** Get custom flipper name if set in version_set_custom_name
|
||||
*
|
||||
* @param v pointer to Version data. NULL for currently running
|
||||
* software.
|
||||
@@ -74,11 +74,11 @@ const char* version_get_version(const Version* v);
|
||||
*/
|
||||
const char* version_get_custom_name(const Version* v);
|
||||
|
||||
/** Get custom flipper name if set in ENV
|
||||
/** Set custom flipper name
|
||||
*
|
||||
* @param v pointer to Version data. NULL for currently running
|
||||
* software.
|
||||
* @param custom name or NULL
|
||||
* @param name Custom name or NULL
|
||||
*/
|
||||
void version_set_custom_name(Version* v, const char* name);
|
||||
|
||||
|
||||
@@ -249,18 +249,7 @@ class Main(App):
|
||||
)
|
||||
)
|
||||
bundle_args.extend(self.other_args)
|
||||
|
||||
log_custom_fz_name = environ.get("CUSTOM_FLIPPER_NAME", None) or ""
|
||||
if (
|
||||
(log_custom_fz_name != "")
|
||||
and (len(log_custom_fz_name) <= 8)
|
||||
and (log_custom_fz_name.isalnum())
|
||||
and (log_custom_fz_name.isascii())
|
||||
):
|
||||
self.logger.info(
|
||||
f"Flipper Custom Name is set:\n\tName: {log_custom_fz_name} : length - {len(log_custom_fz_name)} chars"
|
||||
)
|
||||
|
||||
|
||||
if (bundle_result := UpdateMain(no_exit=True)(bundle_args)) == 0:
|
||||
self.note_dist_component("update", "dir", bundle_dir)
|
||||
self.logger.info(
|
||||
|
||||
@@ -41,32 +41,16 @@ class GitVersion:
|
||||
|
||||
version = os.environ.get("DIST_SUFFIX", None) or VERSION or "unknown"
|
||||
|
||||
custom_fz_name = os.environ.get("CUSTOM_FLIPPER_NAME", None) or ""
|
||||
|
||||
force_no_dirty = os.environ.get("FORCE_NO_DIRTY", None) or ""
|
||||
if force_no_dirty != "":
|
||||
dirty = False
|
||||
|
||||
if (
|
||||
(custom_fz_name != "")
|
||||
and (len(custom_fz_name) <= 8)
|
||||
and (custom_fz_name.isalnum())
|
||||
and (custom_fz_name.isascii())
|
||||
):
|
||||
return {
|
||||
"GIT_COMMIT": commit,
|
||||
"GIT_BRANCH": branch,
|
||||
"FURI_CUSTOM_FLIPPER_NAME": custom_fz_name,
|
||||
"VERSION": version,
|
||||
"BUILD_DIRTY": dirty and 1 or 0,
|
||||
}
|
||||
else:
|
||||
return {
|
||||
"GIT_COMMIT": commit,
|
||||
"GIT_BRANCH": branch,
|
||||
"VERSION": version,
|
||||
"BUILD_DIRTY": dirty and 1 or 0,
|
||||
}
|
||||
return {
|
||||
"GIT_COMMIT": commit,
|
||||
"GIT_BRANCH": branch,
|
||||
"VERSION": version,
|
||||
"BUILD_DIRTY": dirty and 1 or 0,
|
||||
}
|
||||
|
||||
def _exec_git(self, args):
|
||||
cmd = ["git"]
|
||||
|
||||
@@ -100,11 +100,6 @@ vars.AddVariables(
|
||||
"Version string for updater package",
|
||||
"${DIST_SUFFIX}",
|
||||
),
|
||||
(
|
||||
"CUSTOM_FLIPPER_NAME",
|
||||
"Replaces OTP flipper name with custom string of 8 chars",
|
||||
"",
|
||||
),
|
||||
(
|
||||
"FORCE_NO_DIRTY",
|
||||
"Force disable dirty status of the build",
|
||||
|
||||
@@ -20,7 +20,6 @@ variables_to_forward = [
|
||||
# CI/CD variables
|
||||
"WORKFLOW_BRANCH_OR_TAG",
|
||||
"DIST_SUFFIX",
|
||||
"CUSTOM_FLIPPER_NAME",
|
||||
"FORCE_NO_DIRTY",
|
||||
# Python & other tools
|
||||
"HOME",
|
||||
|
||||
Reference in New Issue
Block a user