mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-07 05:29:09 -07:00
Merge remote-tracking branch 'UFW/dev' into archive
This commit is contained in:
@@ -4,5 +4,6 @@ App(
|
||||
targets=["f7"],
|
||||
entry_point="subghz_device_cc1101_ext_ep",
|
||||
requires=["subghz"],
|
||||
sdk_headers=["cc1101_ext/cc1101_ext_interconnect.h"],
|
||||
fap_libs=["hwdrivers"],
|
||||
)
|
||||
|
||||
@@ -18,7 +18,7 @@ Before launching the application, connect the sensor to Flipper's external GPIO
|
||||
In order to launch this demo, follow the steps below:
|
||||
1. Make sure your Flipper has an SD card installed.
|
||||
2. Connect your Flipper to the computer via a USB cable.
|
||||
3. Run `./fbt launch_app APPSRC=example_thermo` in your terminal emulator of choice.
|
||||
3. Run `./fbt launch APPSRC=example_thermo` in your terminal emulator of choice.
|
||||
|
||||
## Changing the data pin
|
||||
It is possible to use other GPIO pin as a 1-Wire data pin. In order to change it, set the `THERMO_GPIO_PIN` macro to any of the options listed below:
|
||||
|
||||
@@ -517,4 +517,14 @@ uint8_t nrf24_find_channel(
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
bool nrf24_check_connected(FuriHalSpiBusHandle* handle) {
|
||||
uint8_t status = nrf24_status(handle);
|
||||
|
||||
if(status != 0x00) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -361,6 +361,13 @@ void int32_to_bytes(uint32_t val, uint8_t* out, bool bigendian);
|
||||
*/
|
||||
uint32_t bytes_to_int32(uint8_t* bytes, bool bigendian);
|
||||
|
||||
/** Check if the nrf24 is connected
|
||||
* @param handle - pointer to FuriHalSpiHandle
|
||||
*
|
||||
* @return true if connected, otherwise false
|
||||
*/
|
||||
bool nrf24_check_connected(FuriHalSpiBusHandle* handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
70
applications/external/mousejacker/mousejacker.c
vendored
70
applications/external/mousejacker/mousejacker.c
vendored
@@ -9,15 +9,14 @@
|
||||
#include <furi_hal_interrupt.h>
|
||||
#include <furi_hal_resources.h>
|
||||
#include <nrf24.h>
|
||||
#include <notification/notification_messages.h>
|
||||
#include "mousejacker_ducky.h"
|
||||
#include <nrf24_mouse_jacker_icons.h>
|
||||
|
||||
#define TAG "mousejacker"
|
||||
#define LOGITECH_MAX_CHANNEL 85
|
||||
#define NRFSNIFF_APP_PATH_FOLDER "/ext/nrfsniff"
|
||||
#define NRFSNIFF_APP_PATH_EXTENSION ".txt"
|
||||
#define NRFSNIFF_APP_FILENAME "addresses.txt"
|
||||
#define MOUSEJACKER_APP_PATH_FOLDER "/ext/mousejacker"
|
||||
#define NRFSNIFF_APP_PATH_FOLDER_ADDRESSES EXT_PATH("apps_data/nrf24sniff/addresses.txt")
|
||||
#define LOCAL_BADUSB_FOLDER EXT_PATH("badusb")
|
||||
#define MOUSEJACKER_APP_PATH_EXTENSION ".txt"
|
||||
#define MAX_ADDRS 100
|
||||
|
||||
@@ -32,12 +31,13 @@ typedef struct {
|
||||
} PluginEvent;
|
||||
|
||||
uint8_t addrs_count = 0;
|
||||
uint8_t addr_idx = 0;
|
||||
int8_t addr_idx = 0;
|
||||
uint8_t loaded_addrs[MAX_ADDRS][6]; // first byte is rate, the rest are the address
|
||||
|
||||
char target_fmt_text[] = "Target addr: %s";
|
||||
char target_address_str[12] = "None";
|
||||
char target_text[30];
|
||||
char index_text[30];
|
||||
|
||||
static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
furi_assert(ctx);
|
||||
@@ -53,8 +53,15 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
snprintf(target_text, sizeof(target_text), target_fmt_text, target_address_str);
|
||||
canvas_draw_str_aligned(canvas, 7, 10, AlignLeft, AlignBottom, target_text);
|
||||
canvas_draw_str_aligned(canvas, 22, 20, AlignLeft, AlignBottom, "<- select address ->");
|
||||
canvas_draw_str_aligned(canvas, 10, 30, AlignLeft, AlignBottom, "Press Ok button to ");
|
||||
canvas_draw_str_aligned(canvas, 10, 40, AlignLeft, AlignBottom, "browse for ducky script");
|
||||
snprintf(
|
||||
index_text, sizeof(index_text), "Address index: %d/%d", addr_idx + 1, addrs_count);
|
||||
canvas_draw_str_aligned(canvas, 10, 30, AlignLeft, AlignBottom, index_text);
|
||||
canvas_draw_str_aligned(canvas, 10, 40, AlignLeft, AlignBottom, "Press Ok button to ");
|
||||
canvas_draw_str_aligned(canvas, 10, 50, AlignLeft, AlignBottom, "browse for ducky script");
|
||||
if(!plugin_state->is_nrf24_connected) {
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 10, 60, AlignLeft, AlignBottom, "Connect NRF24 to GPIO!");
|
||||
}
|
||||
} else if(plugin_state->addr_err) {
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 10, 10, AlignLeft, AlignBottom, "Error: No nrfsniff folder");
|
||||
@@ -94,6 +101,7 @@ static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queu
|
||||
|
||||
static void mousejacker_state_init(PluginState* const plugin_state) {
|
||||
plugin_state->is_thread_running = false;
|
||||
plugin_state->is_nrf24_connected = true;
|
||||
}
|
||||
|
||||
static void hexlify(uint8_t* in, uint8_t size, char* out) {
|
||||
@@ -107,7 +115,7 @@ static bool open_ducky_script(Stream* stream, PluginState* plugin_state) {
|
||||
bool result = false;
|
||||
FuriString* path;
|
||||
path = furi_string_alloc();
|
||||
furi_string_set(path, MOUSEJACKER_APP_PATH_FOLDER);
|
||||
furi_string_set(path, LOCAL_BADUSB_FOLDER);
|
||||
|
||||
DialogsFileBrowserOptions browser_options;
|
||||
dialog_file_browser_set_basic_options(
|
||||
@@ -132,27 +140,17 @@ static bool open_ducky_script(Stream* stream, PluginState* plugin_state) {
|
||||
}
|
||||
|
||||
static bool open_addrs_file(Stream* stream) {
|
||||
DialogsApp* dialogs = furi_record_open("dialogs");
|
||||
bool result = false;
|
||||
FuriString* path;
|
||||
path = furi_string_alloc();
|
||||
furi_string_set(path, NRFSNIFF_APP_PATH_FOLDER);
|
||||
furi_string_set(path, NRFSNIFF_APP_PATH_FOLDER_ADDRESSES);
|
||||
|
||||
DialogsFileBrowserOptions browser_options;
|
||||
dialog_file_browser_set_basic_options(
|
||||
&browser_options, NRFSNIFF_APP_PATH_EXTENSION, &I_sub1_10px);
|
||||
browser_options.hide_ext = false;
|
||||
|
||||
bool ret = dialog_file_browser_show(dialogs, path, path, &browser_options);
|
||||
|
||||
furi_record_close("dialogs");
|
||||
if(ret) {
|
||||
if(!file_stream_open(stream, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
FURI_LOG_D(TAG, "Cannot open file \"%s\"", furi_string_get_cstr(path));
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
if(!file_stream_open(stream, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
FURI_LOG_D(TAG, "Cannot open file \"%s\"", furi_string_get_cstr(path));
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
|
||||
furi_string_free(path);
|
||||
return result;
|
||||
}
|
||||
@@ -277,12 +275,6 @@ static int32_t mj_worker_thread(void* ctx) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void start_mjthread(PluginState* plugin_state) {
|
||||
if(!plugin_state->is_thread_running) {
|
||||
furi_thread_start(plugin_state->mjthread);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t mousejacker_app(void* p) {
|
||||
UNUSED(p);
|
||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent));
|
||||
@@ -297,6 +289,8 @@ int32_t mousejacker_app(void* p) {
|
||||
return 255;
|
||||
}
|
||||
|
||||
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, render_callback, plugin_state);
|
||||
@@ -307,7 +301,6 @@ int32_t mousejacker_app(void* p) {
|
||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||
|
||||
plugin_state->storage = furi_record_open(RECORD_STORAGE);
|
||||
storage_common_mkdir(plugin_state->storage, MOUSEJACKER_APP_PATH_FOLDER);
|
||||
plugin_state->file_stream = file_stream_alloc(plugin_state->storage);
|
||||
|
||||
plugin_state->mjthread = furi_thread_alloc();
|
||||
@@ -344,21 +337,25 @@ int32_t mousejacker_app(void* p) {
|
||||
case InputKeyRight:
|
||||
if(!plugin_state->addr_err) {
|
||||
addr_idx++;
|
||||
if(addr_idx > addrs_count) addr_idx = 0;
|
||||
if(addr_idx >= addrs_count) addr_idx = 0;
|
||||
hexlify(loaded_addrs[addr_idx] + 1, 5, target_address_str);
|
||||
}
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
if(!plugin_state->addr_err) {
|
||||
addr_idx--;
|
||||
if(addr_idx == 0) addr_idx = addrs_count - 1;
|
||||
if(addr_idx < 0) addr_idx = addrs_count - 1;
|
||||
hexlify(loaded_addrs[addr_idx] + 1, 5, target_address_str);
|
||||
}
|
||||
break;
|
||||
case InputKeyOk:
|
||||
if(!plugin_state->addr_err) {
|
||||
if(!plugin_state->is_thread_running) {
|
||||
start_mjthread(plugin_state);
|
||||
if(!nrf24_check_connected(nrf24_HANDLE)) {
|
||||
plugin_state->is_nrf24_connected = false;
|
||||
view_port_update(view_port);
|
||||
notification_message(notification, &sequence_error);
|
||||
} else if(!plugin_state->is_thread_running) {
|
||||
furi_thread_start(plugin_state->mjthread);
|
||||
view_port_update(view_port);
|
||||
}
|
||||
}
|
||||
@@ -388,6 +385,7 @@ int32_t mousejacker_app(void* p) {
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(gui, view_port);
|
||||
furi_record_close(RECORD_GUI);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
view_port_free(view_port);
|
||||
furi_message_queue_free(event_queue);
|
||||
@@ -395,4 +393,4 @@ int32_t mousejacker_app(void* p) {
|
||||
free(plugin_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ typedef struct {
|
||||
bool addr_err;
|
||||
bool is_thread_running;
|
||||
bool is_ducky_running;
|
||||
bool is_nrf24_connected;
|
||||
bool close_thread_please;
|
||||
Storage* storage;
|
||||
FuriThread* mjthread;
|
||||
|
||||
10
applications/external/nrfsniff/lib/nrf24/nrf24.c
vendored
10
applications/external/nrfsniff/lib/nrf24/nrf24.c
vendored
@@ -517,4 +517,14 @@ uint8_t nrf24_find_channel(
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
bool nrf24_check_connected(FuriHalSpiBusHandle* handle) {
|
||||
uint8_t status = nrf24_status(handle);
|
||||
|
||||
if(status != 0x00) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -361,6 +361,13 @@ void int32_to_bytes(uint32_t val, uint8_t* out, bool bigendian);
|
||||
*/
|
||||
uint32_t bytes_to_int32(uint8_t* bytes, bool bigendian);
|
||||
|
||||
/** Check if the nrf24 is connected
|
||||
* @param handle - pointer to FuriHalSpiHandle
|
||||
*
|
||||
* @return true if connected, otherwise false
|
||||
*/
|
||||
bool nrf24_check_connected(FuriHalSpiBusHandle* handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
25
applications/external/nrfsniff/nrfsniff.c
vendored
25
applications/external/nrfsniff/nrfsniff.c
vendored
@@ -10,11 +10,11 @@
|
||||
|
||||
#define LOGITECH_MAX_CHANNEL 85
|
||||
#define COUNT_THRESHOLD 2
|
||||
#define DEFAULT_SAMPLE_TIME 8000
|
||||
#define DEFAULT_SAMPLE_TIME 4000
|
||||
#define MAX_ADDRS 100
|
||||
#define MAX_CONFIRMED 32
|
||||
|
||||
#define NRFSNIFF_APP_PATH_FOLDER "/ext/nrfsniff"
|
||||
#define NRFSNIFF_APP_PATH_FOLDER STORAGE_APP_DATA_PATH_PREFIX
|
||||
#define NRFSNIFF_APP_FILENAME "addresses.txt"
|
||||
#define TAG "nrfsniff"
|
||||
|
||||
@@ -341,6 +341,7 @@ int32_t nrfsniff_app(void* p) {
|
||||
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
storage_common_migrate(storage, EXT_PATH("nrfsniff"), NRFSNIFF_APP_PATH_FOLDER);
|
||||
storage_common_mkdir(storage, NRFSNIFF_APP_PATH_FOLDER);
|
||||
|
||||
PluginEvent event;
|
||||
@@ -387,13 +388,19 @@ int32_t nrfsniff_app(void* p) {
|
||||
break;
|
||||
case InputKeyOk:
|
||||
// toggle sniffing
|
||||
sniffing_state = !sniffing_state;
|
||||
if(sniffing_state) {
|
||||
clear_cache();
|
||||
start_sniffing();
|
||||
start = furi_get_tick();
|
||||
} else
|
||||
wrap_up(storage, notification);
|
||||
if(nrf24_check_connected(nrf24_HANDLE)) {
|
||||
sniffing_state = !sniffing_state;
|
||||
if(sniffing_state) {
|
||||
clear_cache();
|
||||
start_sniffing();
|
||||
start = furi_get_tick();
|
||||
} else {
|
||||
wrap_up(storage, notification);
|
||||
}
|
||||
} else {
|
||||
notification_message(notification, &sequence_error);
|
||||
}
|
||||
|
||||
break;
|
||||
case InputKeyBack:
|
||||
if(event.input.type == InputTypeLong) processing = false;
|
||||
|
||||
@@ -12,15 +12,15 @@ void ibutton_scene_delete_confirm_on_enter(void* context) {
|
||||
widget_add_button_element(
|
||||
widget, GuiButtonTypeRight, "Delete", ibutton_widget_callback, context);
|
||||
|
||||
furi_string_printf(tmp, "Delete %s?", ibutton->key_name);
|
||||
widget_add_string_element(
|
||||
widget, 128 / 2, 0, AlignCenter, AlignTop, FontPrimary, furi_string_get_cstr(tmp));
|
||||
furi_string_printf(tmp, "\e#Delete %s?\e#", ibutton->key_name);
|
||||
widget_add_text_box_element(
|
||||
widget, 0, 0, 128, 23, AlignCenter, AlignCenter, furi_string_get_cstr(tmp), false);
|
||||
|
||||
furi_string_reset(tmp);
|
||||
ibutton_protocols_render_brief_data(ibutton->protocols, key, tmp);
|
||||
|
||||
widget_add_string_multiline_element(
|
||||
widget, 128 / 2, 16, AlignCenter, AlignTop, FontSecondary, furi_string_get_cstr(tmp));
|
||||
widget, 128 / 2, 24, AlignCenter, AlignTop, FontSecondary, furi_string_get_cstr(tmp));
|
||||
|
||||
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget);
|
||||
furi_string_free(tmp);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
App(
|
||||
appid="subghz",
|
||||
name="Sub-GHz",
|
||||
apptype=FlipperAppType.MENUEXTERNAL,
|
||||
apptype=FlipperAppType.APP,
|
||||
targets=["f7"],
|
||||
cdefines=["APP_SUBGHZ"],
|
||||
entry_point="subghz_app",
|
||||
requires=[
|
||||
"gui",
|
||||
@@ -15,7 +16,7 @@ App(
|
||||
],
|
||||
icon="A_Sub1ghz_14",
|
||||
stack_size=3 * 1024,
|
||||
order=10,
|
||||
order=1,
|
||||
fap_libs=["assets", "hwdrivers"],
|
||||
fap_icon="icon.png",
|
||||
fap_category="Sub-GHz",
|
||||
@@ -26,6 +27,7 @@ App(
|
||||
targets=["f7"],
|
||||
apptype=FlipperAppType.STARTUP,
|
||||
entry_point="subghz_on_system_start",
|
||||
requires=["subghz"],
|
||||
order=40,
|
||||
)
|
||||
|
||||
|
||||
@@ -94,7 +94,25 @@ static uint32_t loader_menu_exit(void* context) {
|
||||
}
|
||||
|
||||
static void loader_menu_build_menu(LoaderMenuApp* app, LoaderMenu* menu) {
|
||||
size_t i;
|
||||
size_t i = 0;
|
||||
|
||||
menu_add_item(
|
||||
app->primary_menu,
|
||||
LOADER_APPLICATIONS_NAME,
|
||||
&A_Plugins_14,
|
||||
i++,
|
||||
loader_menu_applications_callback,
|
||||
(void*)menu);
|
||||
|
||||
for(i = 0; i < FLIPPER_APPS_COUNT; i++) {
|
||||
menu_add_item(
|
||||
app->primary_menu,
|
||||
FLIPPER_APPS[i].name,
|
||||
FLIPPER_APPS[i].icon,
|
||||
i,
|
||||
loader_menu_apps_callback,
|
||||
(void*)menu);
|
||||
}
|
||||
|
||||
for(i = 0; i < FLIPPER_EXTERNAL_APPS_COUNT; i++) {
|
||||
menu_add_item(
|
||||
@@ -106,24 +124,8 @@ static void loader_menu_build_menu(LoaderMenuApp* app, LoaderMenu* menu) {
|
||||
(void*)menu);
|
||||
}
|
||||
|
||||
for(i = 0; i < FLIPPER_APPS_COUNT; i++) {
|
||||
menu_add_item(
|
||||
app->primary_menu,
|
||||
FLIPPER_APPS[i].name,
|
||||
FLIPPER_APPS[i].icon,
|
||||
i,
|
||||
loader_menu_apps_callback,
|
||||
(void*)menu);
|
||||
}
|
||||
menu_add_item(
|
||||
app->primary_menu, "Settings", &A_Settings_14, i++, loader_menu_switch_to_settings, app);
|
||||
menu_add_item(
|
||||
app->primary_menu,
|
||||
LOADER_APPLICATIONS_NAME,
|
||||
&A_Plugins_14,
|
||||
i++,
|
||||
loader_menu_applications_callback,
|
||||
(void*)menu);
|
||||
};
|
||||
|
||||
static void loader_menu_build_submenu(LoaderMenuApp* app, LoaderMenu* loader_menu) {
|
||||
|
||||
@@ -300,6 +300,7 @@ static bool power_update_info(Power* power) {
|
||||
|
||||
info.is_charging = furi_hal_power_is_charging();
|
||||
info.gauge_is_ok = furi_hal_power_gauge_is_ok();
|
||||
info.is_shutdown_requested = furi_hal_power_is_shutdown_requested();
|
||||
info.charge = furi_hal_power_get_pct();
|
||||
info.health = furi_hal_power_get_bat_health_pct();
|
||||
info.capacity_remaining = furi_hal_power_get_battery_remaining_capacity();
|
||||
@@ -328,7 +329,7 @@ static void power_check_low_battery(Power* power) {
|
||||
}
|
||||
|
||||
// Check battery charge and vbus voltage
|
||||
if((power->info.charge == 0) && (power->info.voltage_vbus < 4.0f) &&
|
||||
if((power->info.is_shutdown_requested) && (power->info.voltage_vbus < 4.0f) &&
|
||||
power->show_low_bat_level_message) {
|
||||
if(!power->battery_low) {
|
||||
view_dispatcher_send_to_front(power->view_dispatcher);
|
||||
|
||||
@@ -37,6 +37,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
bool gauge_is_ok;
|
||||
bool is_charging;
|
||||
bool is_shutdown_requested;
|
||||
|
||||
float current_charger;
|
||||
float current_gauge;
|
||||
|
||||
@@ -54,8 +54,7 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) {
|
||||
(uint32_t)(data->vbus_voltage * 10) % 10,
|
||||
current);
|
||||
} else if(current < -5) {
|
||||
// Often gauge reports anything in the range 1~5ma as 5ma
|
||||
// That brings confusion, so we'll treat it as Napping
|
||||
// 0-5ma deadband
|
||||
snprintf(
|
||||
emote,
|
||||
sizeof(emote),
|
||||
|
||||
Reference in New Issue
Block a user