mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-06-07 19:01:54 -07:00
Merge remote-tracking branch 'ofw/dev' into mntm-dev
This commit is contained in:
+2
-1
@@ -234,7 +234,7 @@ firmware_debug = distenv.PhonyTarget(
|
|||||||
)
|
)
|
||||||
distenv.Depends(firmware_debug, firmware_flash)
|
distenv.Depends(firmware_debug, firmware_flash)
|
||||||
|
|
||||||
distenv.PhonyTarget(
|
firmware_blackmagic = distenv.PhonyTarget(
|
||||||
"blackmagic",
|
"blackmagic",
|
||||||
"${GDBPYCOM}",
|
"${GDBPYCOM}",
|
||||||
source=firmware_env["FW_ELF"],
|
source=firmware_env["FW_ELF"],
|
||||||
@@ -242,6 +242,7 @@ distenv.PhonyTarget(
|
|||||||
GDBREMOTE="${BLACKMAGIC_ADDR}",
|
GDBREMOTE="${BLACKMAGIC_ADDR}",
|
||||||
FBT_FAP_DEBUG_ELF_ROOT=firmware_env["FBT_FAP_DEBUG_ELF_ROOT"],
|
FBT_FAP_DEBUG_ELF_ROOT=firmware_env["FBT_FAP_DEBUG_ELF_ROOT"],
|
||||||
)
|
)
|
||||||
|
distenv.Depends(firmware_blackmagic, firmware_flash)
|
||||||
|
|
||||||
# Debug alien elf
|
# Debug alien elf
|
||||||
debug_other_opts = [
|
debug_other_opts = [
|
||||||
|
|||||||
@@ -1,22 +1,26 @@
|
|||||||
#include "../ibutton_i.h"
|
#include "../ibutton_i.h"
|
||||||
|
|
||||||
void ibutton_scene_rpc_on_enter(void* context) {
|
void ibutton_scene_rpc_on_enter(void* context) {
|
||||||
iButton* ibutton = context;
|
UNUSED(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ibutton_rpc_start_emulation(iButton* ibutton) {
|
||||||
Popup* popup = ibutton->popup;
|
Popup* popup = ibutton->popup;
|
||||||
|
|
||||||
popup_set_header(popup, "iButton", 82, 28, AlignCenter, AlignBottom);
|
popup_set_header(popup, "iButton", 82, 28, AlignCenter, AlignBottom);
|
||||||
popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop);
|
popup_set_text(popup, ibutton->key_name, 82, 32, AlignCenter, AlignTop);
|
||||||
|
|
||||||
popup_set_icon(popup, 2, 14, &I_iButtonKey_49x44);
|
popup_set_icon(popup, 2, 14, &I_iButtonKey_49x44);
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup);
|
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup);
|
||||||
|
|
||||||
|
ibutton_worker_emulate_start(ibutton->worker, ibutton->key);
|
||||||
|
|
||||||
|
ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart);
|
||||||
notification_message(ibutton->notifications, &sequence_display_backlight_on);
|
notification_message(ibutton->notifications, &sequence_display_backlight_on);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
||||||
iButton* ibutton = context;
|
iButton* ibutton = context;
|
||||||
Popup* popup = ibutton->popup;
|
|
||||||
|
|
||||||
bool consumed = false;
|
bool consumed = false;
|
||||||
|
|
||||||
@@ -27,17 +31,13 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if(ibutton_load_key(ibutton, false)) {
|
if(ibutton_load_key(ibutton, false)) {
|
||||||
popup_set_text(popup, ibutton->key_name, 82, 32, AlignCenter, AlignTop);
|
ibutton_rpc_start_emulation(ibutton);
|
||||||
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup);
|
|
||||||
|
|
||||||
ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart);
|
|
||||||
ibutton_worker_emulate_start(ibutton->worker, ibutton->key);
|
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
|
} else {
|
||||||
|
rpc_system_app_set_error_code(ibutton->rpc, RpcAppSystemErrorCodeParseFile);
|
||||||
|
rpc_system_app_set_error_text(ibutton->rpc, "Cannot load key file");
|
||||||
}
|
}
|
||||||
|
|
||||||
rpc_system_app_confirm(ibutton->rpc, result);
|
rpc_system_app_confirm(ibutton->rpc, result);
|
||||||
|
|
||||||
} else if(event.event == iButtonCustomEventRpcExit) {
|
} else if(event.event == iButtonCustomEventRpcExit) {
|
||||||
rpc_system_app_confirm(ibutton->rpc, true);
|
rpc_system_app_confirm(ibutton->rpc, true);
|
||||||
scene_manager_stop(ibutton->scene_manager);
|
scene_manager_stop(ibutton->scene_manager);
|
||||||
|
|||||||
@@ -373,17 +373,15 @@ void infrared_tx_start(InfraredApp* infrared) {
|
|||||||
infrared->app_state.is_transmitting = true;
|
infrared->app_state.is_transmitting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void infrared_tx_start_button_index(InfraredApp* infrared, size_t button_index) {
|
bool infrared_tx_start_button_index(InfraredApp* infrared, size_t button_index) {
|
||||||
furi_assert(button_index < infrared_remote_get_signal_count(infrared->remote));
|
furi_assert(button_index < infrared_remote_get_signal_count(infrared->remote));
|
||||||
|
|
||||||
if(infrared_remote_load_signal(infrared->remote, infrared->current_signal, button_index)) {
|
bool result =
|
||||||
|
infrared_remote_load_signal(infrared->remote, infrared->current_signal, button_index);
|
||||||
|
if(result) {
|
||||||
infrared_tx_start(infrared);
|
infrared_tx_start(infrared);
|
||||||
} else {
|
|
||||||
infrared_show_error_message(
|
|
||||||
infrared,
|
|
||||||
"Failed to load\n\"%s\"",
|
|
||||||
infrared_remote_get_signal_name(infrared->remote, button_index));
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void infrared_tx_stop(InfraredApp* infrared) {
|
void infrared_tx_stop(InfraredApp* infrared) {
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ void infrared_tx_start(InfraredApp* infrared);
|
|||||||
* @param[in] button_index index of the signal to be loaded.
|
* @param[in] button_index index of the signal to be loaded.
|
||||||
* @returns true if the signal could be loaded, false otherwise.
|
* @returns true if the signal could be loaded, false otherwise.
|
||||||
*/
|
*/
|
||||||
void infrared_tx_start_button_index(InfraredApp* infrared, size_t button_index);
|
bool infrared_tx_start_button_index(InfraredApp* infrared, size_t button_index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Stop transmission of the currently loaded signal.
|
* @brief Stop transmission of the currently loaded signal.
|
||||||
|
|||||||
@@ -1091,3 +1091,41 @@ type: raw
|
|||||||
frequency: 38000
|
frequency: 38000
|
||||||
duty_cycle: 0.330000
|
duty_cycle: 0.330000
|
||||||
data: 4348 4439 520 1646 520 1646 520 1646 519 1646 520 561 520 561 520 1646 519 561 520 561 520 562 519 562 519 561 520 1646 520 1647 518 563 518 1646 519 562 519 561 520 561 520 562 519 562 519 561 520 1648 517 1647 519 1646 519 1647 519 1646 520 1646 520 1645 520 1647 519 561 520 561 520 562 519 562 519 562 519 562 519 561 520 562 519 561 520 1646 520 562 519 1647 518 1646 520 562 519 560 521 561 520 561 520 561 520 562 519 562 519 560 521 562 519 562 519 560 521 1646 520 1646 520 561 520 562 519 561 520 562 519 561 520 561 520 561 520 561 520 561 520 1647 518 1646 520 562 519 562 519 561 520 1646 520 561 520 5409 4348 4440 519 1645 521 1646 519 1645 521 1645 521 561 520 561 520 1644 522 561 520 561 520 561 520 560 521 562 519 1646 520 1646 520 562 519 1644 522 561 520 561 520 561 520 561 520 561 520 561 520 1646 520 1645 520 1646 520 1645 521 1646 520 1646 520 1644 522 1645 521 560 521 560 521 561 520 561 520 560 521 560 521 561 520 561 520 561 520 1645 521 562 519 1645 521 1645 520 561 520 562 519 561 520 561 520 561 520 560 521 560 521 560 521 560 521 561 520 560 521 1646 520 1646 520 561 520 560 521 559 522 560 521 561 520 561 520 560 521 560 521 560 521 1646 520 1645 520 561 520 560 521 560 521 1645 521 561 520
|
data: 4348 4439 520 1646 520 1646 520 1646 519 1646 520 561 520 561 520 1646 519 561 520 561 520 562 519 562 519 561 520 1646 520 1647 518 563 518 1646 519 562 519 561 520 561 520 562 519 562 519 561 520 1648 517 1647 519 1646 519 1647 519 1646 520 1646 520 1645 520 1647 519 561 520 561 520 562 519 562 519 562 519 562 519 561 520 562 519 561 520 1646 520 562 519 1647 518 1646 520 562 519 560 521 561 520 561 520 561 520 562 519 562 519 560 521 562 519 562 519 560 521 1646 520 1646 520 561 520 562 519 561 520 562 519 561 520 561 520 561 520 561 520 561 520 1647 518 1646 520 562 519 562 519 561 520 1646 520 561 520 5409 4348 4440 519 1645 521 1646 519 1645 521 1645 521 561 520 561 520 1644 522 561 520 561 520 561 520 560 521 562 519 1646 520 1646 520 562 519 1644 522 561 520 561 520 561 520 561 520 561 520 561 520 1646 520 1645 520 1646 520 1645 521 1646 520 1646 520 1644 522 1645 521 560 521 560 521 561 520 561 520 560 521 560 521 561 520 561 520 561 520 1645 521 562 519 1645 521 1645 520 561 520 562 519 561 520 561 520 561 520 560 521 560 521 560 521 560 521 561 520 560 521 1646 520 1646 520 561 520 560 521 559 522 560 521 561 520 561 520 560 521 560 521 560 521 1646 520 1645 520 561 520 560 521 560 521 1645 521 561 520
|
||||||
|
#
|
||||||
|
# Model: Airwell AW-HKD012-N91
|
||||||
|
#
|
||||||
|
name: Dh
|
||||||
|
type: raw
|
||||||
|
frequency: 38000
|
||||||
|
duty_cycle: 0.330000
|
||||||
|
data: 4387 4398 547 1609 547 530 547 1610 547 1611 545 530 547 530 547 1608 547 530 548 530 547 1611 545 532 546 532 547 1609 547 1610 547 531 547 1608 548 530 547 530 548 530 547 1610 546 1609 547 1610 547 1609 547 1609 547 1611 545 1609 548 1610 546 530 547 530 548 529 549 531 547 531 546 531 547 1608 548 1610 547 1608 548 533 545 1608 548 532 546 532 546 1611 545 532 547 532 545 530 548 1608 547 530 549 1608 547 1609 548 5203 4386 4398 547 1609 546 530 547 1609 546 1607 548 531 547 531 547 1609 547 530 548 531 547 1609 547 531 547 531 547 1608 547 1613 544 531 546 1609 547 531 547 531 547 532 546 1609 547 1609 546 1609 547 1609 547 1608 547 1608 548 1608 548 1609 547 530 547 530 547 530 547 532 546 530 547 530 548 1610 546 1608 547 1609 547 530 547 1609 547 530 547 530 548 1609 546 530 548 530 547 532 546 1610 546 531 546 1608 548 1608 548
|
||||||
|
#
|
||||||
|
name: Cool_hi
|
||||||
|
type: raw
|
||||||
|
frequency: 38000
|
||||||
|
duty_cycle: 0.330000
|
||||||
|
data: 4388 4398 547 1608 548 531 546 1610 546 1609 547 530 547 529 548 1608 548 532 547 530 548 1612 544 529 549 530 548 1608 547 1609 547 531 546 1608 548 1607 549 529 549 1608 549 1609 548 1608 548 1608 548 1611 545 1608 548 530 548 1609 547 531 547 530 548 530 548 531 547 529 549 530 548 530 547 531 547 530 548 530 547 529 549 530 548 532 547 530 548 1609 547 1610 547 1608 548 1609 547 1608 548 1608 548 1608 548 1608 548 5203 4388 4396 549 1609 547 529 549 1610 546 1608 548 529 549 530 547 1609 547 530 548 529 549 1608 548 531 547 532 546 1609 547 1609 547 530 548 1609 548 1609 548 529 548 1608 548 1609 548 1609 547 1609 547 1608 548 1609 547 532 546 1608 548 531 548 531 548 530 548 530 548 531 547 530 548 531 548 531 547 530 548 530 548 530 548 531 547 529 549 529 549 1609 548 1608 548 1609 547 1608 548 1608 548 1608 548 1607 549 1607 549
|
||||||
|
#
|
||||||
|
name: Cool_lo
|
||||||
|
type: raw
|
||||||
|
frequency: 38000
|
||||||
|
duty_cycle: 0.330000
|
||||||
|
data: 4384 4400 572 1585 571 505 572 1583 573 1584 572 508 570 503 575 1584 572 505 572 506 572 1583 573 504 573 506 571 1586 570 1585 572 532 546 1586 570 1585 571 506 571 1585 571 1583 573 1586 570 1583 573 1584 572 1589 569 505 572 1585 571 506 571 506 573 506 572 505 573 532 545 504 574 509 570 1611 545 506 572 1582 574 506 572 507 571 507 571 507 570 1584 572 507 571 1587 569 506 572 1584 572 1585 571 1583 573 1612 544 5179 4386 4400 570 1584 572 507 571 1583 572 1585 571 506 572 506 572 1584 572 505 572 504 574 1584 572 507 571 504 574 1583 573 1585 572 507 571 1584 572 1610 545 508 571 1587 569 1583 573 1583 573 1585 571 1585 572 1585 572 505 572 1584 572 505 573 507 572 506 571 504 574 505 573 505 574 508 571 1585 571 507 571 1585 571 506 571 506 572 504 574 505 572 1586 570 507 571 1586 570 505 573 1584 572 1585 571 1587 569 1584 573
|
||||||
|
#
|
||||||
|
name: Heat_hi
|
||||||
|
type: raw
|
||||||
|
frequency: 38000
|
||||||
|
duty_cycle: 0.330000
|
||||||
|
data: 4386 4398 575 1582 574 503 575 1583 573 1582 574 505 573 504 574 1582 574 506 572 508 570 1583 573 504 574 505 573 1583 573 1584 573 505 573 1582 575 1583 574 504 574 1582 574 1583 573 1583 573 1583 573 1585 571 1586 572 504 573 1584 572 504 573 505 573 505 573 505 573 504 573 506 571 1583 574 505 573 1583 573 1583 573 1584 572 1583 573 505 572 505 573 504 574 1583 574 505 573 505 573 504 574 505 572 1584 572 1584 573 5178 4387 4400 571 1583 573 504 574 1584 572 1584 572 507 572 504 574 1582 574 505 572 505 573 1583 573 504 574 504 574 1582 574 1584 573 503 574 1583 573 1582 574 505 573 1583 573 1582 575 1583 573 1610 546 1584 572 1583 573 505 573 1610 546 506 572 505 573 504 574 504 574 505 573 505 573 1584 573 505 573 1582 574 1584 572 1583 573 1583 573 504 574 503 575 504 574 1585 571 507 571 504 573 506 572 505 572 1584 572 1585 571
|
||||||
|
#
|
||||||
|
name: Heat_lo
|
||||||
|
type: raw
|
||||||
|
frequency: 38000
|
||||||
|
duty_cycle: 0.330000
|
||||||
|
data: 4388 4399 547 1608 548 530 548 1610 547 1610 547 529 549 529 548 1608 548 530 548 530 548 1607 549 533 545 531 548 1608 548 1610 546 531 547 1609 547 1608 548 529 549 1609 547 1609 547 1609 547 1609 547 1609 547 1608 548 529 548 1638 519 530 548 530 548 530 548 529 550 528 549 530 548 530 548 1608 548 530 548 1609 548 1610 547 1609 547 531 546 529 549 1608 548 530 548 1609 548 530 548 529 548 530 548 1609 548 1609 548 5205 4387 4398 547 1609 548 531 546 1609 547 1609 547 530 548 531 546 1609 547 531 548 530 573 1583 573 507 571 506 572 1583 573 1582 574 504 574 1581 575 1582 574 506 572 1583 574 1583 573 1583 573 1585 571 1584 572 1585 570 507 571 1582 574 505 574 532 545 505 573 505 572 506 571 505 573 505 573 1584 572 506 572 1583 573 1584 572 1583 573 505 572 504 573 1583 573 505 573 1586 571 506 572 505 573 507 572 1583 573 1584 572
|
||||||
|
#
|
||||||
|
name: Off
|
||||||
|
type: raw
|
||||||
|
frequency: 38000
|
||||||
|
duty_cycle: 0.330000
|
||||||
|
data: 4388 4399 572 1583 573 532 546 1585 571 1583 574 503 575 505 573 1584 572 504 574 505 573 1584 573 506 572 504 573 1584 573 1584 572 505 574 1611 545 506 573 1583 573 1585 571 1586 545 1609 547 531 547 1611 545 1608 548 1607 549 530 548 529 548 531 548 532 546 1610 546 533 545 530 547 1609 547 1610 547 1609 547 533 545 529 548 530 548 530 547 531 546 530 547 530 548 533 544 1608 548 1608 548 1610 546 1606 550 1609 547 5203 4388 4397 548 1609 547 531 547 1608 548 1608 548 530 548 530 548 1608 548 531 547 531 547 1610 546 531 547 530 548 1609 547 1611 546 532 547 1609 547 531 547 1608 548 1610 546 1609 547 1608 548 530 547 1609 547 1608 548 1609 547 531 546 530 548 530 547 530 547 1608 548 532 547 534 545 1608 548 1608 548 1609 547 530 548 531 547 531 547 532 546 531 546 531 547 532 546 530 548 1608 547 1608 548 1610 546 1608 548 1608 548
|
||||||
@@ -85,7 +85,12 @@ bool infrared_scene_remote_on_event(void* context, SceneManagerEvent event) {
|
|||||||
|
|
||||||
if(custom_type == InfraredCustomEventTypeTransmitStarted) {
|
if(custom_type == InfraredCustomEventTypeTransmitStarted) {
|
||||||
furi_assert(button_index >= 0);
|
furi_assert(button_index >= 0);
|
||||||
infrared_tx_start_button_index(infrared, button_index);
|
if(!infrared_tx_start_button_index(infrared, button_index)) {
|
||||||
|
infrared_show_error_message(
|
||||||
|
infrared,
|
||||||
|
"Failed to load\n\"%s\"",
|
||||||
|
infrared_remote_get_signal_name(infrared->remote, button_index));
|
||||||
|
}
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(custom_type == InfraredCustomEventTypeTransmitStopped) {
|
} else if(custom_type == InfraredCustomEventTypeTransmitStopped) {
|
||||||
infrared_tx_stop(infrared);
|
infrared_tx_stop(infrared);
|
||||||
|
|||||||
@@ -20,18 +20,24 @@ static int32_t infrared_scene_rpc_task_callback(void* context) {
|
|||||||
|
|
||||||
void infrared_scene_rpc_on_enter(void* context) {
|
void infrared_scene_rpc_on_enter(void* context) {
|
||||||
InfraredApp* infrared = context;
|
InfraredApp* infrared = context;
|
||||||
|
scene_manager_set_scene_state(infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateIdle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void infrared_scene_rpc_show(InfraredApp* infrared) {
|
||||||
Popup* popup = infrared->popup;
|
Popup* popup = infrared->popup;
|
||||||
|
|
||||||
popup_set_header(popup, "Infrared", 89, 42, AlignCenter, AlignBottom);
|
popup_set_header(popup, "Infrared", 89, 42, AlignCenter, AlignBottom);
|
||||||
popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop);
|
popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop);
|
||||||
|
popup_set_text(popup, infrared->text_store[0], 89, 44, AlignCenter, AlignTop);
|
||||||
|
|
||||||
popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61);
|
popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61);
|
||||||
|
|
||||||
popup_set_context(popup, context);
|
popup_set_context(popup, infrared);
|
||||||
popup_set_callback(popup, infrared_popup_closed_callback);
|
popup_set_callback(popup, infrared_popup_closed_callback);
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup);
|
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup);
|
||||||
scene_manager_set_scene_state(infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateIdle);
|
scene_manager_set_scene_state(
|
||||||
|
infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateSending);
|
||||||
notification_message(infrared->notifications, &sequence_display_backlight_on);
|
notification_message(infrared->notifications, &sequence_display_backlight_on);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,24 +58,20 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
|||||||
|
|
||||||
} else if(event.event == InfraredCustomEventTypeTaskFinished) {
|
} else if(event.event == InfraredCustomEventTypeTaskFinished) {
|
||||||
const bool task_success = infrared_blocking_task_finalize(infrared);
|
const bool task_success = infrared_blocking_task_finalize(infrared);
|
||||||
|
|
||||||
if(task_success) {
|
if(task_success) {
|
||||||
const char* remote_name = infrared_remote_get_name(infrared->remote);
|
|
||||||
infrared_text_store_set(infrared, 0, "loaded\n%s", remote_name);
|
|
||||||
scene_manager_set_scene_state(
|
scene_manager_set_scene_state(
|
||||||
infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateLoaded);
|
infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateLoaded);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
infrared_text_store_set(
|
FuriString* str = furi_string_alloc();
|
||||||
infrared, 0, "failed to load\n%s", furi_string_get_cstr(infrared->file_path));
|
furi_string_printf(
|
||||||
|
str, "Failed to load\n%s", furi_string_get_cstr(infrared->file_path));
|
||||||
|
|
||||||
|
rpc_system_app_set_error_code(infrared->rpc_ctx, RpcAppSystemErrorCodeParseFile);
|
||||||
|
rpc_system_app_set_error_text(infrared->rpc_ctx, furi_string_get_cstr(str));
|
||||||
|
|
||||||
|
furi_string_free(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
popup_set_text(
|
|
||||||
infrared->popup, infrared->text_store[0], 89, 44, AlignCenter, AlignTop);
|
|
||||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup);
|
|
||||||
|
|
||||||
rpc_system_app_confirm(infrared->rpc_ctx, task_success);
|
rpc_system_app_confirm(infrared->rpc_ctx, task_success);
|
||||||
|
|
||||||
} else if(
|
} else if(
|
||||||
event.event == InfraredCustomEventTypeRpcButtonPressName ||
|
event.event == InfraredCustomEventTypeRpcButtonPressName ||
|
||||||
event.event == InfraredCustomEventTypeRpcButtonPressIndex) {
|
event.event == InfraredCustomEventTypeRpcButtonPressIndex) {
|
||||||
@@ -88,10 +90,19 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
|||||||
TAG, "Sending signal with index \"%ld\"", app_state->current_button_index);
|
TAG, "Sending signal with index \"%ld\"", app_state->current_button_index);
|
||||||
}
|
}
|
||||||
if(infrared->app_state.current_button_index != InfraredButtonIndexNone) {
|
if(infrared->app_state.current_button_index != InfraredButtonIndexNone) {
|
||||||
infrared_tx_start_button_index(infrared, app_state->current_button_index);
|
if(infrared_tx_start_button_index(infrared, app_state->current_button_index)) {
|
||||||
scene_manager_set_scene_state(
|
const char* remote_name = infrared_remote_get_name(infrared->remote);
|
||||||
infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateSending);
|
infrared_text_store_set(infrared, 0, "emulating\n%s", remote_name);
|
||||||
result = true;
|
|
||||||
|
infrared_scene_rpc_show(infrared);
|
||||||
|
result = true;
|
||||||
|
} else {
|
||||||
|
rpc_system_app_set_error_code(
|
||||||
|
infrared->rpc_ctx, RpcAppSystemErrorCodeInternalParse);
|
||||||
|
rpc_system_app_set_error_text(
|
||||||
|
infrared->rpc_ctx, "Cannot load button data");
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rpc_system_app_confirm(infrared->rpc_ctx, result);
|
rpc_system_app_confirm(infrared->rpc_ctx, result);
|
||||||
|
|||||||
@@ -2,23 +2,30 @@
|
|||||||
|
|
||||||
void lfrfid_scene_rpc_on_enter(void* context) {
|
void lfrfid_scene_rpc_on_enter(void* context) {
|
||||||
LfRfid* app = context;
|
LfRfid* app = context;
|
||||||
|
app->rpc_state = LfRfidRpcStateIdle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lfrfid_rpc_start_emulation(LfRfid* app) {
|
||||||
Popup* popup = app->popup;
|
Popup* popup = app->popup;
|
||||||
|
|
||||||
|
lfrfid_text_store_set(app, "emulating\n%s", furi_string_get_cstr(app->file_name));
|
||||||
|
|
||||||
popup_set_header(popup, "LF RFID", 89, 42, AlignCenter, AlignBottom);
|
popup_set_header(popup, "LF RFID", 89, 42, AlignCenter, AlignBottom);
|
||||||
popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop);
|
popup_set_text(popup, app->text_store, 89, 44, AlignCenter, AlignTop);
|
||||||
popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61);
|
popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61);
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup);
|
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup);
|
||||||
|
|
||||||
notification_message(app->notifications, &sequence_display_backlight_on);
|
lfrfid_worker_start_thread(app->lfworker);
|
||||||
|
lfrfid_worker_emulate_start(app->lfworker, (LFRFIDProtocol)app->protocol_id);
|
||||||
|
|
||||||
app->rpc_state = LfRfidRpcStateIdle;
|
notification_message(app->notifications, &sequence_display_backlight_on);
|
||||||
|
notification_message(app->notifications, &sequence_blink_start_magenta);
|
||||||
|
app->rpc_state = LfRfidRpcStateEmulating;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lfrfid_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
bool lfrfid_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
||||||
LfRfid* app = context;
|
LfRfid* app = context;
|
||||||
Popup* popup = app->popup;
|
|
||||||
UNUSED(event);
|
|
||||||
bool consumed = false;
|
bool consumed = false;
|
||||||
|
|
||||||
if(event.type == SceneManagerEventTypeCustom) {
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
@@ -34,16 +41,11 @@ bool lfrfid_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
if(app->rpc_state == LfRfidRpcStateIdle) {
|
if(app->rpc_state == LfRfidRpcStateIdle) {
|
||||||
if(lfrfid_load_key_data(app, app->file_path, false)) {
|
if(lfrfid_load_key_data(app, app->file_path, false)) {
|
||||||
lfrfid_worker_start_thread(app->lfworker);
|
lfrfid_rpc_start_emulation(app);
|
||||||
lfrfid_worker_emulate_start(app->lfworker, (LFRFIDProtocol)app->protocol_id);
|
|
||||||
app->rpc_state = LfRfidRpcStateEmulating;
|
|
||||||
|
|
||||||
lfrfid_text_store_set(
|
|
||||||
app, "emulating\n%s", furi_string_get_cstr(app->file_name));
|
|
||||||
popup_set_text(popup, app->text_store, 89, 44, AlignCenter, AlignTop);
|
|
||||||
|
|
||||||
notification_message(app->notifications, &sequence_blink_start_magenta);
|
|
||||||
result = true;
|
result = true;
|
||||||
|
} else {
|
||||||
|
rpc_system_app_set_error_code(app->rpc_ctx, RpcAppSystemErrorCodeParseFile);
|
||||||
|
rpc_system_app_set_error_text(app->rpc_ctx, "Cannot load key file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rpc_system_app_confirm(app->rpc_ctx, result);
|
rpc_system_app_confirm(app->rpc_ctx, result);
|
||||||
|
|||||||
@@ -731,6 +731,10 @@ static bool nfc_protocol_support_scene_rpc_on_event(NfcApp* instance, SceneManag
|
|||||||
if(nfc_load_file(instance, instance->file_path, false)) {
|
if(nfc_load_file(instance, instance->file_path, false)) {
|
||||||
nfc_protocol_support_scene_rpc_setup_ui_and_emulate(instance);
|
nfc_protocol_support_scene_rpc_setup_ui_and_emulate(instance);
|
||||||
success = true;
|
success = true;
|
||||||
|
} else {
|
||||||
|
rpc_system_app_set_error_code(
|
||||||
|
instance->rpc_ctx, RpcAppSystemErrorCodeParseFile);
|
||||||
|
rpc_system_app_set_error_text(instance->rpc_ctx, "Cannot load key file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rpc_system_app_confirm(instance->rpc_ctx, success);
|
rpc_system_app_confirm(instance->rpc_ctx, success);
|
||||||
|
|||||||
@@ -496,7 +496,7 @@ int32_t nfc_app(void* p) {
|
|||||||
nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen);
|
nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen);
|
||||||
|
|
||||||
furi_string_set(nfc->file_path, args);
|
furi_string_set(nfc->file_path, args);
|
||||||
if(nfc_load_file(nfc, nfc->file_path, false)) {
|
if(nfc_load_file(nfc, nfc->file_path, true)) {
|
||||||
nfc->fav_timeout = is_favorite;
|
nfc->fav_timeout = is_favorite;
|
||||||
nfc_show_initial_scene_for_device(nfc);
|
nfc_show_initial_scene_for_device(nfc);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <furi.h>
|
|
||||||
#include <furi_hal.h>
|
|
||||||
|
|
||||||
/** SubGhzErrorType */
|
|
||||||
typedef enum {
|
|
||||||
SubGhzErrorTypeNoError = 0, /** There are no errors */
|
|
||||||
SubGhzErrorTypeParseFile =
|
|
||||||
1, /** File parsing error, or wrong file structure, or missing required parameters. more accurate data can be obtained through the debug port */
|
|
||||||
SubGhzErrorTypeOnlyRX =
|
|
||||||
2, /** Transmission on this frequency is blocked by regional settings */
|
|
||||||
SubGhzErrorTypeParserOthers = 3, /** Error in protocol parameters description */
|
|
||||||
} SubGhzErrorType;
|
|
||||||
@@ -10,23 +10,33 @@ typedef enum {
|
|||||||
|
|
||||||
void subghz_scene_rpc_on_enter(void* context) {
|
void subghz_scene_rpc_on_enter(void* context) {
|
||||||
SubGhz* subghz = context;
|
SubGhz* subghz = context;
|
||||||
|
scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateIdle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void subghz_format_file_name_tmp(SubGhz* subghz) {
|
||||||
|
FuriString* file_name;
|
||||||
|
file_name = furi_string_alloc();
|
||||||
|
path_extract_filename(subghz->file_path, file_name, true);
|
||||||
|
snprintf(
|
||||||
|
subghz->file_name_tmp, SUBGHZ_MAX_LEN_NAME, "loaded\n%s", furi_string_get_cstr(file_name));
|
||||||
|
furi_string_free(file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void subghz_scene_rpc_emulation_show(SubGhz* subghz) {
|
||||||
Popup* popup = subghz->popup;
|
Popup* popup = subghz->popup;
|
||||||
|
|
||||||
|
subghz_format_file_name_tmp(subghz);
|
||||||
popup_set_header(popup, "Sub-GHz", 89, 42, AlignCenter, AlignBottom);
|
popup_set_header(popup, "Sub-GHz", 89, 42, AlignCenter, AlignBottom);
|
||||||
popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop);
|
|
||||||
|
|
||||||
popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61);
|
popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61);
|
||||||
|
popup_set_text(popup, subghz->file_name_tmp, 89, 44, AlignCenter, AlignTop);
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup);
|
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup);
|
||||||
|
|
||||||
scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateIdle);
|
|
||||||
|
|
||||||
notification_message(subghz->notifications, &sequence_display_backlight_on);
|
notification_message(subghz->notifications, &sequence_display_backlight_on);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
||||||
SubGhz* subghz = context;
|
SubGhz* subghz = context;
|
||||||
Popup* popup = subghz->popup;
|
|
||||||
bool consumed = false;
|
bool consumed = false;
|
||||||
SubGhzRpcState state = scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneRpc);
|
SubGhzRpcState state = scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneRpc);
|
||||||
|
|
||||||
@@ -45,13 +55,15 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
|||||||
switch(
|
switch(
|
||||||
subghz_txrx_tx_start(subghz->txrx, subghz_txrx_get_fff_data(subghz->txrx))) {
|
subghz_txrx_tx_start(subghz->txrx, subghz_txrx_get_fff_data(subghz->txrx))) {
|
||||||
case SubGhzTxRxStartTxStateErrorOnlyRx:
|
case SubGhzTxRxStartTxStateErrorOnlyRx:
|
||||||
rpc_system_app_set_error_code(subghz->rpc_ctx, SubGhzErrorTypeOnlyRX);
|
rpc_system_app_set_error_code(
|
||||||
|
subghz->rpc_ctx, RpcAppSystemErrorCodeRegionLock);
|
||||||
rpc_system_app_set_error_text(
|
rpc_system_app_set_error_text(
|
||||||
subghz->rpc_ctx,
|
subghz->rpc_ctx,
|
||||||
"Transmission on this frequency is restricted in your settings");
|
"Transmission on this frequency is restricted in your settings");
|
||||||
break;
|
break;
|
||||||
case SubGhzTxRxStartTxStateErrorParserOthers:
|
case SubGhzTxRxStartTxStateErrorParserOthers:
|
||||||
rpc_system_app_set_error_code(subghz->rpc_ctx, SubGhzErrorTypeParserOthers);
|
rpc_system_app_set_error_code(
|
||||||
|
subghz->rpc_ctx, RpcAppSystemErrorCodeInternalParse);
|
||||||
rpc_system_app_set_error_text(
|
rpc_system_app_set_error_text(
|
||||||
subghz->rpc_ctx, "Error in protocol parameters description");
|
subghz->rpc_ctx, "Error in protocol parameters description");
|
||||||
break;
|
break;
|
||||||
@@ -79,22 +91,12 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
if(state == SubGhzRpcStateIdle) {
|
if(state == SubGhzRpcStateIdle) {
|
||||||
if(subghz_key_load(subghz, furi_string_get_cstr(subghz->file_path), false)) {
|
if(subghz_key_load(subghz, furi_string_get_cstr(subghz->file_path), false)) {
|
||||||
|
subghz_scene_rpc_emulation_show(subghz);
|
||||||
scene_manager_set_scene_state(
|
scene_manager_set_scene_state(
|
||||||
subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateLoaded);
|
subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateLoaded);
|
||||||
result = true;
|
result = true;
|
||||||
FuriString* file_name = furi_string_alloc();
|
|
||||||
path_extract_filename(subghz->file_path, file_name, true);
|
|
||||||
|
|
||||||
snprintf(
|
|
||||||
subghz->file_name_tmp,
|
|
||||||
SUBGHZ_MAX_LEN_NAME,
|
|
||||||
"loaded\n%s",
|
|
||||||
furi_string_get_cstr(file_name));
|
|
||||||
popup_set_text(popup, subghz->file_name_tmp, 89, 44, AlignCenter, AlignTop);
|
|
||||||
|
|
||||||
furi_string_free(file_name);
|
|
||||||
} else {
|
} else {
|
||||||
rpc_system_app_set_error_code(subghz->rpc_ctx, SubGhzErrorTypeParseFile);
|
rpc_system_app_set_error_code(subghz->rpc_ctx, RpcAppSystemErrorCodeParseFile);
|
||||||
rpc_system_app_set_error_text(subghz->rpc_ctx, "Cannot parse file");
|
rpc_system_app_set_error_text(subghz->rpc_ctx, "Cannot parse file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "helpers/subghz_types.h"
|
#include "helpers/subghz_types.h"
|
||||||
#include "helpers/subghz_error_type.h"
|
|
||||||
#include <lib/subghz/types.h>
|
#include <lib/subghz/types.h>
|
||||||
#include "subghz.h"
|
#include "subghz.h"
|
||||||
#include "views/receiver.h"
|
#include "views/receiver.h"
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ void dialog_ex_set_header(
|
|||||||
dialog_ex->view,
|
dialog_ex->view,
|
||||||
DialogExModel * model,
|
DialogExModel * model,
|
||||||
{
|
{
|
||||||
furi_string_set(model->header.text, text);
|
furi_string_set(model->header.text, text ? text : "");
|
||||||
model->header.x = x;
|
model->header.x = x;
|
||||||
model->header.y = y;
|
model->header.y = y;
|
||||||
model->header.horizontal = horizontal;
|
model->header.horizontal = horizontal;
|
||||||
@@ -243,7 +243,7 @@ void dialog_ex_set_text(
|
|||||||
dialog_ex->view,
|
dialog_ex->view,
|
||||||
DialogExModel * model,
|
DialogExModel * model,
|
||||||
{
|
{
|
||||||
furi_string_set(model->text.text, text);
|
furi_string_set(model->text.text, text ? text : "");
|
||||||
model->text.x = x;
|
model->text.x = x;
|
||||||
model->text.y = y;
|
model->text.y = y;
|
||||||
model->text.horizontal = horizontal;
|
model->text.horizontal = horizontal;
|
||||||
@@ -268,7 +268,10 @@ void dialog_ex_set_icon(DialogEx* dialog_ex, uint8_t x, uint8_t y, const Icon* i
|
|||||||
void dialog_ex_set_left_button_text(DialogEx* dialog_ex, const char* text) {
|
void dialog_ex_set_left_button_text(DialogEx* dialog_ex, const char* text) {
|
||||||
furi_check(dialog_ex);
|
furi_check(dialog_ex);
|
||||||
with_view_model(
|
with_view_model(
|
||||||
dialog_ex->view, DialogExModel * model, { furi_string_set(model->left_text, text); }, true);
|
dialog_ex->view,
|
||||||
|
DialogExModel * model,
|
||||||
|
{ furi_string_set(model->left_text, text ? text : ""); },
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dialog_ex_set_center_button_text(DialogEx* dialog_ex, const char* text) {
|
void dialog_ex_set_center_button_text(DialogEx* dialog_ex, const char* text) {
|
||||||
@@ -276,7 +279,7 @@ void dialog_ex_set_center_button_text(DialogEx* dialog_ex, const char* text) {
|
|||||||
with_view_model(
|
with_view_model(
|
||||||
dialog_ex->view,
|
dialog_ex->view,
|
||||||
DialogExModel * model,
|
DialogExModel * model,
|
||||||
{ furi_string_set(model->center_text, text); },
|
{ furi_string_set(model->center_text, text ? text : ""); },
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,7 +288,7 @@ void dialog_ex_set_right_button_text(DialogEx* dialog_ex, const char* text) {
|
|||||||
with_view_model(
|
with_view_model(
|
||||||
dialog_ex->view,
|
dialog_ex->view,
|
||||||
DialogExModel * model,
|
DialogExModel * model,
|
||||||
{ furi_string_set(model->right_text, text); },
|
{ furi_string_set(model->right_text, text ? text : ""); },
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "rpc.h"
|
#include "rpc.h"
|
||||||
|
#include "rpc_app_error_codes.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enumeration of possible error codes for application which can be started through rpc
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
RpcAppSystemErrorCodeNone, /** There are no errors */
|
||||||
|
RpcAppSystemErrorCodeParseFile, /** File parsing error, or wrong file structure, or missing required parameters. more accurate data can be obtained through the debug port */
|
||||||
|
RpcAppSystemErrorCodeRegionLock, /** Requested function is blocked by regional settings */
|
||||||
|
RpcAppSystemErrorCodeInternalParse, /** Error in protocol parameters description, or some data in opened file are unsupported */
|
||||||
|
} RpcAppSystemErrorCode;
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
#include <storage/storage.h>
|
#include <storage/storage.h>
|
||||||
#include <lib/toolbox/md5_calc.h>
|
#include <lib/toolbox/md5_calc.h>
|
||||||
#include <lib/toolbox/path.h>
|
#include <lib/toolbox/path.h>
|
||||||
#include <update_util/lfs_backup.h>
|
#include <update_util/int_backup.h>
|
||||||
#include <toolbox/tar/tar_archive.h>
|
#include <toolbox/tar/tar_archive.h>
|
||||||
|
|
||||||
#include <pb_decode.h>
|
#include <pb_decode.h>
|
||||||
@@ -656,7 +656,7 @@ static void rpc_system_storage_backup_create_process(const PB_Main* request, voi
|
|||||||
|
|
||||||
rpc_system_storage_reset_state(rpc_storage, session, true);
|
rpc_system_storage_reset_state(rpc_storage, session, true);
|
||||||
|
|
||||||
bool backup_ok = lfs_backup_create(
|
bool backup_ok = int_backup_create(
|
||||||
rpc_storage->api, request->content.storage_backup_create_request.archive_path);
|
rpc_storage->api, request->content.storage_backup_create_request.archive_path);
|
||||||
|
|
||||||
rpc_send_and_release_empty(
|
rpc_send_and_release_empty(
|
||||||
@@ -676,7 +676,7 @@ static void rpc_system_storage_backup_restore_process(const PB_Main* request, vo
|
|||||||
|
|
||||||
rpc_system_storage_reset_state(rpc_storage, session, true);
|
rpc_system_storage_reset_state(rpc_storage, session, true);
|
||||||
|
|
||||||
bool backup_ok = lfs_backup_unpack(
|
bool backup_ok = int_backup_unpack(
|
||||||
rpc_storage->api, request->content.storage_backup_restore_request.archive_path);
|
rpc_storage->api, request->content.storage_backup_restore_request.archive_path);
|
||||||
|
|
||||||
rpc_send_and_release_empty(
|
rpc_send_and_release_empty(
|
||||||
|
|||||||
@@ -531,7 +531,7 @@ FS_Error storage_sd_info(Storage* storage, SDInfo* info);
|
|||||||
*/
|
*/
|
||||||
FS_Error storage_sd_status(Storage* storage);
|
FS_Error storage_sd_status(Storage* storage);
|
||||||
|
|
||||||
/******************* Internal LFS Functions *******************/
|
/************ Internal Storage Backup/Restore ************/
|
||||||
|
|
||||||
typedef void (*StorageNameConverter)(FuriString*);
|
typedef void (*StorageNameConverter)(FuriString*);
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include <toolbox/tar/tar_archive.h>
|
#include <toolbox/tar/tar_archive.h>
|
||||||
#include <toolbox/args.h>
|
#include <toolbox/args.h>
|
||||||
#include <update_util/update_manifest.h>
|
#include <update_util/update_manifest.h>
|
||||||
#include <update_util/lfs_backup.h>
|
#include <update_util/int_backup.h>
|
||||||
#include <update_util/update_operation.h>
|
#include <update_util/update_operation.h>
|
||||||
|
|
||||||
typedef void (*cmd_handler)(FuriString* args);
|
typedef void (*cmd_handler)(FuriString* args);
|
||||||
@@ -35,7 +35,7 @@ static void updater_cli_install(FuriString* manifest_path) {
|
|||||||
static void updater_cli_backup(FuriString* args) {
|
static void updater_cli_backup(FuriString* args) {
|
||||||
printf("Backup /int to '%s'\r\n", furi_string_get_cstr(args));
|
printf("Backup /int to '%s'\r\n", furi_string_get_cstr(args));
|
||||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||||
bool success = lfs_backup_create(storage, furi_string_get_cstr(args));
|
bool success = int_backup_create(storage, furi_string_get_cstr(args));
|
||||||
furi_record_close(RECORD_STORAGE);
|
furi_record_close(RECORD_STORAGE);
|
||||||
printf("Result: %s\r\n", success ? "OK" : "FAIL");
|
printf("Result: %s\r\n", success ? "OK" : "FAIL");
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ static void updater_cli_backup(FuriString* args) {
|
|||||||
static void updater_cli_restore(FuriString* args) {
|
static void updater_cli_restore(FuriString* args) {
|
||||||
printf("Restore /int from '%s'\r\n", furi_string_get_cstr(args));
|
printf("Restore /int from '%s'\r\n", furi_string_get_cstr(args));
|
||||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||||
bool success = lfs_backup_unpack(storage, furi_string_get_cstr(args));
|
bool success = int_backup_unpack(storage, furi_string_get_cstr(args));
|
||||||
furi_record_close(RECORD_STORAGE);
|
furi_record_close(RECORD_STORAGE);
|
||||||
printf("Result: %s\r\n", success ? "OK" : "FAIL");
|
printf("Result: %s\r\n", success ? "OK" : "FAIL");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ static const char* update_task_stage_descr[] = {
|
|||||||
[UpdateTaskStageRadioInstall] = "Installing radio FW",
|
[UpdateTaskStageRadioInstall] = "Installing radio FW",
|
||||||
[UpdateTaskStageRadioBusy] = "Core 2 busy",
|
[UpdateTaskStageRadioBusy] = "Core 2 busy",
|
||||||
[UpdateTaskStageOBValidation] = "Validating opt. bytes",
|
[UpdateTaskStageOBValidation] = "Validating opt. bytes",
|
||||||
[UpdateTaskStageLfsBackup] = "Backing up LFS",
|
[UpdateTaskStageIntBackup] = "Backing up configuration",
|
||||||
[UpdateTaskStageLfsRestore] = "Restoring LFS",
|
[UpdateTaskStageIntRestore] = "Restoring configuration",
|
||||||
[UpdateTaskStageResourcesFileCleanup] = "Cleaning up files",
|
[UpdateTaskStageResourcesFileCleanup] = "Cleaning up files",
|
||||||
[UpdateTaskStageResourcesDirCleanup] = "Cleaning up directories",
|
[UpdateTaskStageResourcesDirCleanup] = "Cleaning up directories",
|
||||||
[UpdateTaskStageResourcesFileUnpack] = "Extracting resources",
|
[UpdateTaskStageResourcesFileUnpack] = "Extracting resources",
|
||||||
@@ -82,7 +82,7 @@ static const struct {
|
|||||||
},
|
},
|
||||||
#ifndef FURI_RAM_EXEC
|
#ifndef FURI_RAM_EXEC
|
||||||
{
|
{
|
||||||
.stage = UpdateTaskStageLfsBackup,
|
.stage = UpdateTaskStageIntBackup,
|
||||||
.percent_min = 0,
|
.percent_min = 0,
|
||||||
.percent_max = 100,
|
.percent_max = 100,
|
||||||
.descr = "FS R/W error",
|
.descr = "FS R/W error",
|
||||||
@@ -193,10 +193,10 @@ static const struct {
|
|||||||
#endif
|
#endif
|
||||||
#ifndef FURI_RAM_EXEC
|
#ifndef FURI_RAM_EXEC
|
||||||
{
|
{
|
||||||
.stage = UpdateTaskStageLfsRestore,
|
.stage = UpdateTaskStageIntRestore,
|
||||||
.percent_min = 0,
|
.percent_min = 0,
|
||||||
.percent_max = 100,
|
.percent_max = 100,
|
||||||
.descr = "LFS I/O error",
|
.descr = "SD card I/O error",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.stage = UpdateTaskStageResourcesFileCleanup,
|
.stage = UpdateTaskStageResourcesFileCleanup,
|
||||||
@@ -245,7 +245,7 @@ static const UpdateTaskStageGroupMap update_task_stage_progress[] = {
|
|||||||
[UpdateTaskStageProgress] = STAGE_DEF(UpdateTaskStageGroupMisc, 0),
|
[UpdateTaskStageProgress] = STAGE_DEF(UpdateTaskStageGroupMisc, 0),
|
||||||
|
|
||||||
[UpdateTaskStageReadManifest] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 45),
|
[UpdateTaskStageReadManifest] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 45),
|
||||||
[UpdateTaskStageLfsBackup] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 5),
|
[UpdateTaskStageIntBackup] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 5),
|
||||||
|
|
||||||
[UpdateTaskStageRadioImageValidate] = STAGE_DEF(UpdateTaskStageGroupRadio, 15),
|
[UpdateTaskStageRadioImageValidate] = STAGE_DEF(UpdateTaskStageGroupRadio, 15),
|
||||||
[UpdateTaskStageRadioErase] = STAGE_DEF(UpdateTaskStageGroupRadio, 25),
|
[UpdateTaskStageRadioErase] = STAGE_DEF(UpdateTaskStageGroupRadio, 25),
|
||||||
@@ -259,7 +259,7 @@ static const UpdateTaskStageGroupMap update_task_stage_progress[] = {
|
|||||||
[UpdateTaskStageFlashWrite] = STAGE_DEF(UpdateTaskStageGroupFirmware, 100),
|
[UpdateTaskStageFlashWrite] = STAGE_DEF(UpdateTaskStageGroupFirmware, 100),
|
||||||
[UpdateTaskStageFlashValidate] = STAGE_DEF(UpdateTaskStageGroupFirmware, 20),
|
[UpdateTaskStageFlashValidate] = STAGE_DEF(UpdateTaskStageGroupFirmware, 20),
|
||||||
|
|
||||||
[UpdateTaskStageLfsRestore] = STAGE_DEF(UpdateTaskStageGroupPostUpdate, 5),
|
[UpdateTaskStageIntRestore] = STAGE_DEF(UpdateTaskStageGroupPostUpdate, 5),
|
||||||
|
|
||||||
[UpdateTaskStageResourcesFileCleanup] = STAGE_DEF(UpdateTaskStageGroupResources, 100),
|
[UpdateTaskStageResourcesFileCleanup] = STAGE_DEF(UpdateTaskStageGroupResources, 100),
|
||||||
[UpdateTaskStageResourcesDirCleanup] = STAGE_DEF(UpdateTaskStageGroupResources, 50),
|
[UpdateTaskStageResourcesDirCleanup] = STAGE_DEF(UpdateTaskStageGroupResources, 50),
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ typedef enum {
|
|||||||
UpdateTaskStageProgress = 0,
|
UpdateTaskStageProgress = 0,
|
||||||
|
|
||||||
UpdateTaskStageReadManifest,
|
UpdateTaskStageReadManifest,
|
||||||
UpdateTaskStageLfsBackup,
|
UpdateTaskStageIntBackup,
|
||||||
|
|
||||||
UpdateTaskStageRadioImageValidate,
|
UpdateTaskStageRadioImageValidate,
|
||||||
UpdateTaskStageRadioErase,
|
UpdateTaskStageRadioErase,
|
||||||
@@ -30,7 +30,7 @@ typedef enum {
|
|||||||
UpdateTaskStageFlashWrite,
|
UpdateTaskStageFlashWrite,
|
||||||
UpdateTaskStageFlashValidate,
|
UpdateTaskStageFlashValidate,
|
||||||
|
|
||||||
UpdateTaskStageLfsRestore,
|
UpdateTaskStageIntRestore,
|
||||||
UpdateTaskStageResourcesFileCleanup,
|
UpdateTaskStageResourcesFileCleanup,
|
||||||
UpdateTaskStageResourcesDirCleanup,
|
UpdateTaskStageResourcesDirCleanup,
|
||||||
UpdateTaskStageResourcesFileUnpack,
|
UpdateTaskStageResourcesFileUnpack,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include <desktop/views/desktop_view_slideshow.h>
|
#include <desktop/views/desktop_view_slideshow.h>
|
||||||
#include <toolbox/path.h>
|
#include <toolbox/path.h>
|
||||||
#include <update_util/dfu_file.h>
|
#include <update_util/dfu_file.h>
|
||||||
#include <update_util/lfs_backup.h>
|
#include <update_util/int_backup.h>
|
||||||
#include <update_util/update_operation.h>
|
#include <update_util/update_operation.h>
|
||||||
#include <update_util/resources/manifest.h>
|
#include <update_util/resources/manifest.h>
|
||||||
#include <toolbox/tar/tar_archive.h>
|
#include <toolbox/tar/tar_archive.h>
|
||||||
@@ -23,14 +23,14 @@ static bool update_task_pre_update(UpdateTask* update_task) {
|
|||||||
backup_file_path = furi_string_alloc();
|
backup_file_path = furi_string_alloc();
|
||||||
path_concat(
|
path_concat(
|
||||||
furi_string_get_cstr(update_task->update_path),
|
furi_string_get_cstr(update_task->update_path),
|
||||||
LFS_BACKUP_DEFAULT_FILENAME,
|
INT_BACKUP_DEFAULT_FILENAME,
|
||||||
backup_file_path);
|
backup_file_path);
|
||||||
|
|
||||||
update_task_set_progress(update_task, UpdateTaskStageLfsBackup, 0);
|
update_task_set_progress(update_task, UpdateTaskStageIntBackup, 0);
|
||||||
/* to avoid bootloops */
|
/* to avoid bootloops */
|
||||||
furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal);
|
furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal);
|
||||||
if((success =
|
if((success =
|
||||||
lfs_backup_create(update_task->storage, furi_string_get_cstr(backup_file_path)))) {
|
int_backup_create(update_task->storage, furi_string_get_cstr(backup_file_path)))) {
|
||||||
furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeUpdate);
|
furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,12 +131,12 @@ static bool update_task_post_update(UpdateTask* update_task) {
|
|||||||
do {
|
do {
|
||||||
path_concat(
|
path_concat(
|
||||||
furi_string_get_cstr(update_task->update_path),
|
furi_string_get_cstr(update_task->update_path),
|
||||||
LFS_BACKUP_DEFAULT_FILENAME,
|
INT_BACKUP_DEFAULT_FILENAME,
|
||||||
file_path);
|
file_path);
|
||||||
|
|
||||||
update_task_set_progress(update_task, UpdateTaskStageLfsRestore, 0);
|
update_task_set_progress(update_task, UpdateTaskStageIntRestore, 0);
|
||||||
|
|
||||||
CHECK_RESULT(lfs_backup_unpack(update_task->storage, furi_string_get_cstr(file_path)));
|
CHECK_RESULT(int_backup_unpack(update_task->storage, furi_string_get_cstr(file_path)));
|
||||||
|
|
||||||
// Fix flags for production / development
|
// Fix flags for production / development
|
||||||
#ifdef FURI_DEBUG
|
#ifdef FURI_DEBUG
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ int32_t update_task_worker_flash_writer(void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePostUpdate);
|
furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePostUpdate);
|
||||||
// Format LFS before restoring backup on next boot
|
// Clean up /int before restoring backup on next boot
|
||||||
furi_hal_rtc_set_flag(FuriHalRtcFlagStorageFormatInternal);
|
furi_hal_rtc_set_flag(FuriHalRtcFlagStorageFormatInternal);
|
||||||
|
|
||||||
update_task_set_progress(update_task, UpdateTaskStageCompleted, 100);
|
update_task_set_progress(update_task, UpdateTaskStageCompleted, 100);
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ Even if something goes wrong, updater allows you to retry failed operations and
|
|||||||
| | | **50** | Package has mismatching HW target |
|
| | | **50** | Package has mismatching HW target |
|
||||||
| | | **60** | Missing DFU file |
|
| | | **60** | Missing DFU file |
|
||||||
| | | **80** | Missing radio firmware file |
|
| | | **80** | Missing radio firmware file |
|
||||||
| Backing up LFS | **2** | **0-100** | FS read/write error |
|
| Backing up configuration| **2** | **0-100** | FS read/write error |
|
||||||
| Checking radio FW | **3** | **0-99** | Error reading radio firmware file |
|
| Checking radio FW | **3** | **0-99** | Error reading radio firmware file |
|
||||||
| | | **100** | CRC mismatch |
|
| | | **100** | CRC mismatch |
|
||||||
| Uninstalling radio FW | **4** | **0** | SHCI Delete command error |
|
| Uninstalling radio FW | **4** | **0** | SHCI Delete command error |
|
||||||
@@ -101,7 +101,7 @@ Even if something goes wrong, updater allows you to retry failed operations and
|
|||||||
| | | **99-100** | Corrupted DFU file |
|
| | | **99-100** | Corrupted DFU file |
|
||||||
| Writing flash | **10** | **0-100** | Block read/write error |
|
| Writing flash | **10** | **0-100** | Block read/write error |
|
||||||
| Validating flash | **11** | **0-100** | Block read/write error |
|
| Validating flash | **11** | **0-100** | Block read/write error |
|
||||||
| Restoring LFS | **12** | **0-100** | FS read/write error |
|
| Restoring configuration | **12** | **0-100** | FS read/write error |
|
||||||
| Updating resources | **13-15** | **0-100** | SD card read/write error |
|
| Updating resources | **13-15** | **0-100** | SD card read/write error |
|
||||||
|
|
||||||
## Building update packages
|
## Building update packages
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#include "int_backup.h"
|
||||||
|
|
||||||
|
#include <toolbox/tar/tar_archive.h>
|
||||||
|
|
||||||
|
#include <bt/bt_settings_filename.h>
|
||||||
|
#include <bt/bt_service/bt_keys_filename.h>
|
||||||
|
#include <dolphin/helpers/dolphin_state_filename.h>
|
||||||
|
#include <desktop/helpers/slideshow_filename.h>
|
||||||
|
#include <desktop/desktop_settings_filename.h>
|
||||||
|
#include <notification/notification_settings_filename.h>
|
||||||
|
|
||||||
|
#define INT_BACKUP_DEFAULT_LOCATION EXT_PATH(INT_BACKUP_DEFAULT_FILENAME)
|
||||||
|
|
||||||
|
static void backup_name_converter(FuriString* filename) {
|
||||||
|
if(furi_string_empty(filename) || (furi_string_get_char(filename, 0) == '.')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Filenames are already prefixed with '.' */
|
||||||
|
const char* const names[] = {
|
||||||
|
BT_SETTINGS_FILE_NAME,
|
||||||
|
BT_KEYS_STORAGE_FILE_NAME,
|
||||||
|
DESKTOP_SETTINGS_FILE_NAME,
|
||||||
|
NOTIFICATION_SETTINGS_FILE_NAME,
|
||||||
|
SLIDESHOW_FILE_NAME,
|
||||||
|
DOLPHIN_STATE_FILE_NAME,
|
||||||
|
};
|
||||||
|
|
||||||
|
for(size_t i = 0; i < COUNT_OF(names); i++) {
|
||||||
|
if(furi_string_equal(filename, &names[i][1])) {
|
||||||
|
furi_string_set(filename, names[i]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool int_backup_create(Storage* storage, const char* destination) {
|
||||||
|
const char* final_destination =
|
||||||
|
destination && strlen(destination) ? destination : INT_BACKUP_DEFAULT_LOCATION;
|
||||||
|
return storage_int_backup(storage, final_destination) == FSE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool int_backup_exists(Storage* storage, const char* source) {
|
||||||
|
const char* final_source = source && strlen(source) ? source : INT_BACKUP_DEFAULT_LOCATION;
|
||||||
|
return storage_common_stat(storage, final_source, NULL) == FSE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool int_backup_unpack(Storage* storage, const char* source) {
|
||||||
|
const char* final_source = source && strlen(source) ? source : INT_BACKUP_DEFAULT_LOCATION;
|
||||||
|
return storage_int_restore(storage, final_source, backup_name_converter) == FSE_OK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <storage/storage.h>
|
||||||
|
|
||||||
|
#define INT_BACKUP_DEFAULT_FILENAME "backup.tar"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool int_backup_create(Storage* storage, const char* destination);
|
||||||
|
bool int_backup_exists(Storage* storage, const char* source);
|
||||||
|
bool int_backup_unpack(Storage* storage, const char* source);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#include "lfs_backup.h"
|
|
||||||
|
|
||||||
#include <toolbox/tar/tar_archive.h>
|
|
||||||
|
|
||||||
#define LFS_BACKUP_DEFAULT_LOCATION EXT_PATH(LFS_BACKUP_DEFAULT_FILENAME)
|
|
||||||
|
|
||||||
bool lfs_backup_create(Storage* storage, const char* destination) {
|
|
||||||
const char* final_destination =
|
|
||||||
destination && strlen(destination) ? destination : LFS_BACKUP_DEFAULT_LOCATION;
|
|
||||||
return storage_int_backup(storage, final_destination) == FSE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lfs_backup_exists(Storage* storage, const char* source) {
|
|
||||||
const char* final_source = source && strlen(source) ? source : LFS_BACKUP_DEFAULT_LOCATION;
|
|
||||||
return storage_common_stat(storage, final_source, NULL) == FSE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lfs_backup_unpack(Storage* storage, const char* source) {
|
|
||||||
const char* final_source = source && strlen(source) ? source : LFS_BACKUP_DEFAULT_LOCATION;
|
|
||||||
return storage_int_restore(storage, final_source, NULL) == FSE_OK;
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <storage/storage.h>
|
|
||||||
|
|
||||||
#define LFS_BACKUP_DEFAULT_FILENAME "backup.tar"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool lfs_backup_create(Storage* storage, const char* destination);
|
|
||||||
bool lfs_backup_exists(Storage* storage, const char* source);
|
|
||||||
bool lfs_backup_unpack(Storage* storage, const char* source);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -124,7 +124,7 @@ class SetFapDebugElfRoot(gdb.Command):
|
|||||||
print(f"Set '{arg}' as debug info lookup path for Flipper external apps")
|
print(f"Set '{arg}' as debug info lookup path for Flipper external apps")
|
||||||
helper.attach_to_fw()
|
helper.attach_to_fw()
|
||||||
gdb.events.stop.connect(helper.handle_stop)
|
gdb.events.stop.connect(helper.handle_stop)
|
||||||
gdb.events.exited.connect(helper.handle_exit)
|
gdb.events.gdb_exiting.connect(helper.handle_exit)
|
||||||
except gdb.error as e:
|
except gdb.error as e:
|
||||||
print(f"Support for Flipper external apps debug is not available: {e}")
|
print(f"Support for Flipper external apps debug is not available: {e}")
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include <datetime/datetime.h>
|
#include <datetime/datetime.h>
|
||||||
|
#include <core/common_defines.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -44,7 +45,7 @@ typedef enum {
|
|||||||
FuriHalRtcRegisterHeader, /**< RTC structure header */
|
FuriHalRtcRegisterHeader, /**< RTC structure header */
|
||||||
FuriHalRtcRegisterSystem, /**< Various system bits */
|
FuriHalRtcRegisterSystem, /**< Various system bits */
|
||||||
FuriHalRtcRegisterVersion, /**< Pointer to Version */
|
FuriHalRtcRegisterVersion, /**< Pointer to Version */
|
||||||
FuriHalRtcRegisterLfsFingerprint, /**< LFS geometry fingerprint */
|
FuriHalRtcRegisterLfsFingerprint FURI_DEPRECATED, /**< LFS geometry fingerprint */
|
||||||
FuriHalRtcRegisterFaultData, /**< Pointer to last fault message */
|
FuriHalRtcRegisterFaultData, /**< Pointer to last fault message */
|
||||||
FuriHalRtcRegisterPinFails, /**< Failed PINs count */
|
FuriHalRtcRegisterPinFails, /**< Failed PINs count */
|
||||||
/* Index of FS directory entry corresponding to FW update to be applied */
|
/* Index of FS directory entry corresponding to FW update to be applied */
|
||||||
|
|||||||
Reference in New Issue
Block a user