Skip to content

Commit 6dc39ba

Browse files
authored
Merge pull request #1 from flipperdevices/dev
merge with flipperdevices
2 parents d147190 + e1ffb4a commit 6dc39ba

File tree

117 files changed

+4199
-420
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+4199
-420
lines changed

.vscode/ReadMe.md

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Visual Studio Code workspace for Flipper Zero
2+
3+
## Setup
4+
5+
* To start developing with VSCode, run `./fbt vscode_dist` in project root. _That should only be done once_
6+
* After that, open firmware folder in VSCode: "File" > "Open folder"
7+
8+
For more details on fbt, see [fbt docs](../documentation/fbt.md).
9+
10+
11+
## Workflow
12+
13+
Commands for building firmware are invoked through Build menu: Ctrl+Shift+B.
14+
15+
To attach a debugging session, first build and flash firmware, then choose your debug probe in Debug menu (Ctrl+Shift+D).
16+
17+
Note that you have to detach debugging session before rebuilding and re-flashing firmware.

.vscode/example/tasks.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@
5555
"label": "[Release] Build update bundle",
5656
"group": "build",
5757
"type": "shell",
58-
"command": "./fbt update_package COMPACT=1 DEBUG=0"
58+
"command": "./fbt updater_package COMPACT=1 DEBUG=0"
5959
},
6060
{
6161
"label": "[Debug] Build update bundle",
6262
"group": "build",
6363
"type": "shell",
64-
"command": "./fbt update_package"
64+
"command": "./fbt updater_package"
6565
},
6666
{
6767
"label": "[Release] Build updater",

applications/about/about.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <gui/modules/empty_screen.h>
66
#include <m-string.h>
77
#include <furi_hal_version.h>
8+
#include <furi_hal_region.h>
89
#include <furi_hal_bt.h>
910

1011
typedef DialogMessageButton (*AboutDialogScreen)(DialogsApp* dialogs, DialogMessage* message);
@@ -83,12 +84,13 @@ static DialogMessageButton hw_version_screen(DialogsApp* dialogs, DialogMessage*
8384

8485
string_cat_printf(
8586
buffer,
86-
"%d.F%dB%dC%d %s %s\n",
87+
"%d.F%dB%dC%d %s:%s %s\n",
8788
furi_hal_version_get_hw_version(),
8889
furi_hal_version_get_hw_target(),
8990
furi_hal_version_get_hw_body(),
9091
furi_hal_version_get_hw_connect(),
9192
furi_hal_version_get_hw_region_name(),
93+
furi_hal_region_get_name(),
9294
my_name ? my_name : "Unknown");
9395

9496
string_cat_printf(buffer, "Serial Number:\n");

applications/accessor/accessor_app.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ void AccessorApp::run(void) {
3232
}
3333

3434
AccessorApp::AccessorApp() {
35-
notification = static_cast<NotificationApp*>(furi_record_open("notification"));
35+
notification = static_cast<NotificationApp*>(furi_record_open(RECORD_NOTIFICATION));
3636
onewire_host = onewire_host_alloc();
3737
furi_hal_power_enable_otg();
3838
}
3939

4040
AccessorApp::~AccessorApp() {
4141
furi_hal_power_disable_otg();
42-
furi_record_close("notification");
42+
furi_record_close(RECORD_NOTIFICATION);
4343
onewire_host_free(onewire_host);
4444
}
4545

applications/accessor/accessor_view_manager.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ AccessorAppViewManager::AccessorAppViewManager() {
1515
popup = popup_alloc();
1616
add_view(ViewType::Popup, popup_get_view(popup));
1717

18-
gui = static_cast<Gui*>(furi_record_open("gui"));
18+
gui = static_cast<Gui*>(furi_record_open(RECORD_GUI));
1919
view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
2020

2121
// set previous view callback for all views
@@ -31,6 +31,7 @@ AccessorAppViewManager::~AccessorAppViewManager() {
3131
view_dispatcher, static_cast<uint32_t>(AccessorAppViewManager::ViewType::Popup));
3232

3333
// free view modules
34+
furi_record_close(RECORD_GUI);
3435
submenu_free(submenu);
3536
popup_free(popup);
3637

applications/applications.h

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ typedef struct {
1818

1919
typedef void (*FlipperOnStartHook)(void);
2020

21+
extern const char* FLIPPER_AUTORUN_APP_NAME;
22+
2123
/* Services list
2224
* Spawned on startup
2325
*/

applications/archive/helpers/archive_favorites.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ uint16_t archive_favorites_count(void* context) {
6464
break;
6565
}
6666
if(!string_size(buffer)) {
67-
break;
67+
continue; // Skip empty lines
6868
}
6969
++lines;
7070
}
@@ -93,7 +93,7 @@ static bool archive_favourites_rescan() {
9393
break;
9494
}
9595
if(!string_size(buffer)) {
96-
break;
96+
continue;
9797
}
9898

9999
if(string_search(buffer, "/app:") == 0) {
@@ -152,7 +152,7 @@ bool archive_favorites_read(void* context) {
152152
break;
153153
}
154154
if(!string_size(buffer)) {
155-
break;
155+
continue;
156156
}
157157

158158
if(string_search(buffer, "/app:") == 0) {
@@ -215,7 +215,7 @@ bool archive_favorites_delete(const char* format, ...) {
215215
break;
216216
}
217217
if(!string_size(buffer)) {
218-
break;
218+
continue;
219219
}
220220

221221
if(string_search(buffer, filename)) {
@@ -259,7 +259,7 @@ bool archive_is_favorite(const char* format, ...) {
259259
break;
260260
}
261261
if(!string_size(buffer)) {
262-
break;
262+
continue;
263263
}
264264
if(!string_search(buffer, filename)) {
265265
found = true;
@@ -299,7 +299,7 @@ bool archive_favorites_rename(const char* src, const char* dst) {
299299
break;
300300
}
301301
if(!string_size(buffer)) {
302-
break;
302+
continue;
303303
}
304304

305305
archive_file_append(

applications/cli/cli_commands.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
void cli_command_device_info_callback(const char* key, const char* value, bool last, void* context) {
1616
UNUSED(context);
1717
UNUSED(last);
18-
printf("%-24s: %s\r\n", key, value);
18+
printf("%-30s: %s\r\n", key, value);
1919
}
2020

2121
/*

applications/desktop/views/desktop_view_debug.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,13 @@ void desktop_debug_render(Canvas* canvas, void* model) {
3636
snprintf(
3737
buffer,
3838
sizeof(buffer),
39-
"%d.F%dB%dC%d %s %s",
39+
"%d.F%dB%dC%d %s:%s %s",
4040
furi_hal_version_get_hw_version(),
4141
furi_hal_version_get_hw_target(),
4242
furi_hal_version_get_hw_body(),
4343
furi_hal_version_get_hw_connect(),
4444
furi_hal_version_get_hw_region_name(),
45+
furi_hal_region_get_name(),
4546
my_name ? my_name : "Unknown");
4647
canvas_draw_str(canvas, 5, 19 + STATUS_BAR_Y_SHIFT, buffer);
4748

applications/gui/modules/text_input.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ static bool char_is_lowercase(char letter) {
131131
}
132132

133133
static char char_to_uppercase(const char letter) {
134-
if(isalpha(letter)) {
134+
if(letter == '_') {
135+
return 0x20;
136+
} else if(isalpha(letter)) {
135137
return (letter - 0x20);
136138
} else {
137139
return letter;

applications/ibutton/ibutton.c

+2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ static void ibutton_rpc_command_callback(RpcAppSystemEvent event, void* context)
8787
if(event == RpcAppEventSessionClose) {
8888
view_dispatcher_send_custom_event(
8989
ibutton->view_dispatcher, iButtonCustomEventRpcSessionClose);
90+
rpc_system_app_set_callback(ibutton->rpc_ctx, NULL, NULL);
91+
ibutton->rpc_ctx = NULL;
9092
} else if(event == RpcAppEventAppExit) {
9193
view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventRpcExit);
9294
} else if(event == RpcAppEventLoadFile) {

applications/ibutton/scenes/ibutton_scene_rpc.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) {
2929
if(event.event == iButtonCustomEventRpcLoad) {
3030
const char* arg = rpc_system_app_get_data(ibutton->rpc_ctx);
3131
bool result = false;
32-
if(arg) {
32+
if(arg && (string_empty_p(ibutton->file_path))) {
3333
string_set_str(ibutton->file_path, arg);
3434
if(ibutton_load_key_data(ibutton, ibutton->file_path, false)) {
3535
ibutton_worker_emulate_start(ibutton->key_worker, ibutton->key);
@@ -51,17 +51,17 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) {
5151

5252
string_clear(key_name);
5353
result = true;
54+
} else {
55+
string_reset(ibutton->file_path);
5456
}
5557
}
5658
rpc_system_app_confirm(ibutton->rpc_ctx, RpcAppEventLoadFile, result);
5759
} else if(event.event == iButtonCustomEventRpcExit) {
5860
rpc_system_app_confirm(ibutton->rpc_ctx, RpcAppEventAppExit, true);
59-
ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop);
61+
scene_manager_stop(ibutton->scene_manager);
6062
view_dispatcher_stop(ibutton->view_dispatcher);
6163
} else if(event.event == iButtonCustomEventRpcSessionClose) {
62-
rpc_system_app_set_callback(ibutton->rpc_ctx, NULL, NULL);
63-
ibutton->rpc_ctx = NULL;
64-
ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop);
64+
scene_manager_stop(ibutton->scene_manager);
6565
view_dispatcher_stop(ibutton->view_dispatcher);
6666
}
6767
}

applications/infrared/infrared.c

+22-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ static void infrared_rpc_command_callback(RpcAppSystemEvent event, void* context
4646
if(event == RpcAppEventSessionClose) {
4747
view_dispatcher_send_custom_event(
4848
infrared->view_dispatcher, InfraredCustomEventTypeRpcSessionClose);
49+
rpc_system_app_set_callback(infrared->rpc_ctx, NULL, NULL);
50+
infrared->rpc_ctx = NULL;
4951
} else if(event == RpcAppEventAppExit) {
5052
view_dispatcher_send_custom_event(
5153
infrared->view_dispatcher, InfraredCustomEventTypeRpcExit);
@@ -293,6 +295,13 @@ bool infrared_rename_current_remote(Infrared* infrared, const char* name) {
293295
}
294296

295297
void infrared_tx_start_signal(Infrared* infrared, InfraredSignal* signal) {
298+
if(infrared->app_state.is_transmitting) {
299+
FURI_LOG_D(INFRARED_LOG_TAG, "Transmitter is already active");
300+
return;
301+
} else {
302+
infrared->app_state.is_transmitting = true;
303+
}
304+
296305
if(infrared_signal_is_raw(signal)) {
297306
InfraredRawSignal* raw = infrared_signal_get_raw_signal(signal);
298307
infrared_worker_set_raw_signal(infrared->worker, raw->timings, raw->timings_size);
@@ -302,8 +311,11 @@ void infrared_tx_start_signal(Infrared* infrared, InfraredSignal* signal) {
302311
}
303312

304313
DOLPHIN_DEED(DolphinDeedIrSend);
305-
infrared_worker_tx_start(infrared->worker);
306314
infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStartSend);
315+
316+
infrared_worker_tx_set_get_signal_callback(
317+
infrared->worker, infrared_worker_tx_get_signal_steady_callback, infrared);
318+
infrared_worker_tx_start(infrared->worker);
307319
}
308320

309321
void infrared_tx_start_button_index(Infrared* infrared, size_t button_index) {
@@ -322,7 +334,16 @@ void infrared_tx_start_received(Infrared* infrared) {
322334
}
323335

324336
void infrared_tx_stop(Infrared* infrared) {
337+
if(!infrared->app_state.is_transmitting) {
338+
FURI_LOG_D(INFRARED_LOG_TAG, "Transmitter is already stopped");
339+
return;
340+
} else {
341+
infrared->app_state.is_transmitting = false;
342+
}
343+
325344
infrared_worker_tx_stop(infrared->worker);
345+
infrared_worker_tx_set_get_signal_callback(infrared->worker, NULL, NULL);
346+
326347
infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStop);
327348
}
328349

applications/infrared/infrared_i.h

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#define INFRARED_APP_EXTENSION ".ir"
4444

4545
#define INFRARED_DEFAULT_REMOTE_NAME "Remote"
46+
#define INFRARED_LOG_TAG "InfraredApp"
4647

4748
typedef enum {
4849
InfraredButtonIndexNone = -1,
@@ -63,6 +64,7 @@ typedef enum {
6364
typedef struct {
6465
bool is_learning_new_remote;
6566
bool is_debug_enabled;
67+
bool is_transmitting;
6668
InfraredEditTarget edit_target : 8;
6769
InfraredEditMode edit_mode : 8;
6870
int32_t current_button_index;

applications/infrared/scenes/infrared_scene_learn_success.c

+8-34
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22

33
#include <dolphin/dolphin.h>
44

5-
typedef enum {
6-
InfraredSceneLearnSuccessStateIdle = 0,
7-
InfraredSceneLearnSuccessStateSending = 1,
8-
} InfraredSceneLearnSuccessState;
9-
105
static void
116
infrared_scene_learn_success_dialog_result_callback(DialogExResult result, void* context) {
127
Infrared* infrared = context;
@@ -21,9 +16,6 @@ void infrared_scene_learn_success_on_enter(void* context) {
2116
DOLPHIN_DEED(DolphinDeedIrLearnSuccess);
2217
infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOn);
2318

24-
infrared_worker_tx_set_get_signal_callback(
25-
infrared->worker, infrared_worker_tx_get_signal_steady_callback, context);
26-
2719
if(infrared_signal_is_raw(signal)) {
2820
InfraredRawSignal* raw = infrared_signal_get_raw_signal(signal);
2921
dialog_ex_set_header(dialog_ex, "Unknown", 95, 10, AlignCenter, AlignCenter);
@@ -63,57 +55,42 @@ void infrared_scene_learn_success_on_enter(void* context) {
6355
dialog_ex_set_context(dialog_ex, context);
6456
dialog_ex_enable_extended_events(dialog_ex);
6557

66-
scene_manager_set_scene_state(
67-
infrared->scene_manager, InfraredSceneLearnSuccess, InfraredSceneLearnSuccessStateIdle);
6858
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewDialogEx);
6959
}
7060

7161
bool infrared_scene_learn_success_on_event(void* context, SceneManagerEvent event) {
7262
Infrared* infrared = context;
7363
SceneManager* scene_manager = infrared->scene_manager;
74-
uint32_t scene_state = scene_manager_get_scene_state(scene_manager, InfraredSceneLearnSuccess);
64+
const bool is_transmitter_idle = !infrared->app_state.is_transmitting;
7565
bool consumed = false;
7666

7767
if(event.type == SceneManagerEventTypeTick) {
78-
if(scene_state == InfraredSceneLearnSuccessStateIdle) {
68+
if(is_transmitter_idle) {
7969
infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOn);
8070
}
8171
consumed = true;
8272
} else if(event.type == SceneManagerEventTypeBack) {
83-
if(scene_state == InfraredSceneLearnSuccessStateIdle) {
73+
if(is_transmitter_idle) {
8474
scene_manager_next_scene(scene_manager, InfraredSceneAskBack);
8575
}
8676
consumed = true;
8777
} else if(event.type == SceneManagerEventTypeCustom) {
8878
if(event.event == DialogExResultLeft) {
89-
if(scene_state == InfraredSceneLearnSuccessStateIdle) {
79+
if(is_transmitter_idle) {
9080
scene_manager_next_scene(scene_manager, InfraredSceneAskRetry);
9181
}
9282
consumed = true;
9383
} else if(event.event == DialogExResultRight) {
94-
if(scene_state == InfraredSceneLearnSuccessStateIdle) {
84+
if(is_transmitter_idle) {
9585
scene_manager_next_scene(scene_manager, InfraredSceneLearnEnterName);
9686
}
9787
consumed = true;
9888
} else if(event.event == DialogExPressCenter) {
99-
if(scene_state == InfraredSceneLearnSuccessStateIdle) {
100-
scene_manager_set_scene_state(
101-
scene_manager,
102-
InfraredSceneLearnSuccess,
103-
InfraredSceneLearnSuccessStateSending);
104-
infrared_tx_start_received(infrared);
105-
infrared_play_notification_message(
106-
infrared, InfraredNotificationMessageBlinkStartSend);
107-
}
89+
infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOff);
90+
infrared_tx_start_received(infrared);
10891
consumed = true;
10992
} else if(event.event == DialogExReleaseCenter) {
110-
if(scene_state == InfraredSceneLearnSuccessStateSending) {
111-
scene_manager_set_scene_state(
112-
scene_manager, InfraredSceneLearnSuccess, InfraredSceneLearnSuccessStateIdle);
113-
infrared_tx_stop(infrared);
114-
infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStop);
115-
infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOff);
116-
}
93+
infrared_tx_stop(infrared);
11794
consumed = true;
11895
}
11996
}
@@ -123,9 +100,6 @@ bool infrared_scene_learn_success_on_event(void* context, SceneManagerEvent even
123100

124101
void infrared_scene_learn_success_on_exit(void* context) {
125102
Infrared* infrared = context;
126-
InfraredWorker* worker = infrared->worker;
127103
dialog_ex_reset(infrared->dialog_ex);
128-
infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStop);
129104
infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOff);
130-
infrared_worker_tx_set_get_signal_callback(worker, NULL, NULL);
131105
}

0 commit comments

Comments
 (0)