mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-13 16:28:36 -07:00
Merge remote-tracking branch 'mntm/dev' into ofw-3822-nestednonces
This commit is contained in:
16
CHANGELOG.md
16
CHANGELOG.md
@@ -2,6 +2,7 @@
|
|||||||
- Apps:
|
- Apps:
|
||||||
- NFC: Cyborg Detector (by @RocketGod-git)
|
- NFC: Cyborg Detector (by @RocketGod-git)
|
||||||
- Sub-GHz: Radio Scanner (by @RocketGod-git)
|
- Sub-GHz: Radio Scanner (by @RocketGod-git)
|
||||||
|
- Games: Umpire Indicator (by @RocketGod-git)
|
||||||
- Sub-GHz:
|
- Sub-GHz:
|
||||||
- Show satellites count with an icon (#215 by @m7i-org)
|
- Show satellites count with an icon (#215 by @m7i-org)
|
||||||
- Add Bresser 3CH weather station protocol (#217 by @m7i-org)
|
- Add Bresser 3CH weather station protocol (#217 by @m7i-org)
|
||||||
@@ -30,14 +31,21 @@
|
|||||||
- Picopass: File loading improvements and fixes (by @bettse), force ISO15693 1OutOf4 mode (by @aaronjamt)
|
- Picopass: File loading improvements and fixes (by @bettse), force ISO15693 1OutOf4 mode (by @aaronjamt)
|
||||||
- Quac!: External IR board support (by @daniilty), import all IR from file, iButton support, code improvements (by @rdefeo)
|
- Quac!: External IR board support (by @daniilty), import all IR from file, iButton support, code improvements (by @rdefeo)
|
||||||
- DTMF Dolphin: Add EAS tone support (by @JendrBendr)
|
- DTMF Dolphin: Add EAS tone support (by @JendrBendr)
|
||||||
- NFC Playlist: Add playlist already exists error, general improvements (by @acegoal07)
|
- NFC Playlist: Error screens for playlist already exists and item already in playlist, general improvements (by @acegoal07)
|
||||||
- UL: Sub-GHz Bruteforcer: Add new protocols for existing dump option (by @xMasterX)
|
- CLI-GUI Bridge: Fixes and improvements (by @ranchordo)
|
||||||
|
- Seader: Enable T=1 (by @bettse)
|
||||||
|
- UL: Sub-GHz Bruteforcer: Add new protocols for existing dump option (by @xMasterX), use FW functions for top buttons (by @DerSkythe)
|
||||||
- UL: NRF24 Apps: Use string library compatible with OFW SDK (by @xMasterX)
|
- UL: NRF24 Apps: Use string library compatible with OFW SDK (by @xMasterX)
|
||||||
- OFW: SPI Mem Manager: Fixed UI rendering bug related to line breaks (by @portasynthinca3)
|
- OFW: SPI Mem Manager: Fixed UI rendering bug related to line breaks (by @portasynthinca3)
|
||||||
- CLI: Print plugin name on load fail (by @Willy-JL)
|
- CLI: Print plugin name on load fail (by @Willy-JL)
|
||||||
- NFC:
|
- NFC:
|
||||||
- Added 6 new Mifare Classic keys from Bulgaria Hotel (#216 by @z3r0l1nk)
|
- Added 6 new Mifare Classic keys from Bulgaria Hotel (#216 by @z3r0l1nk)
|
||||||
- OFW: Rename 'Detect Reader' to 'Extract MF Keys' (by @bettse)
|
- OFW: Rename 'Detect Reader' to 'Extract MF Keys' (by @bettse)
|
||||||
|
- Sub-GHz:
|
||||||
|
- UL: Frequency analyzer fixes and improvements (by @xMasterX):
|
||||||
|
- Enforce int module (like in OFW) usage due to lack of required hardware on external boards (PathIsolate (+rf switch for multiple paths)) and incorrect usage and/or understanding the purpose of frequency analyzer app by users, it should be used only to get frequency of the remote placed around 1-10cm around flipper's left corner
|
||||||
|
- Fix possible GSM mobile towers signal interference by limiting upper frequency to 920mhz max
|
||||||
|
- Fix duplicated frequency lists and use user config for nearest frequency selector too
|
||||||
- Infrared:
|
- Infrared:
|
||||||
- OFW: IR button operation fails now shows more informative messages (by @RebornedBrain)
|
- OFW: IR button operation fails now shows more informative messages (by @RebornedBrain)
|
||||||
- OFW: Add Airwell AW-HKD012-N91 to univeral AC remote (by @valeraOlexienko)
|
- OFW: Add Airwell AW-HKD012-N91 to univeral AC remote (by @valeraOlexienko)
|
||||||
@@ -56,7 +64,9 @@
|
|||||||
- OFW: Fix detection of GProx II cards and false detection of other cards (by @Astrrra)
|
- OFW: Fix detection of GProx II cards and false detection of other cards (by @Astrrra)
|
||||||
- OFW: Fix Guard GProxII False Positive and 36-bit Parsing (by @zinongli)
|
- OFW: Fix Guard GProxII False Positive and 36-bit Parsing (by @zinongli)
|
||||||
- OFW: GProxII Fix Writing and Rendering Conflict (by @zinongli)
|
- OFW: GProxII Fix Writing and Rendering Conflict (by @zinongli)
|
||||||
- Desktop: Fallback Poweroff prompt when power settings is unavailable (by @Willy-JL)
|
- Desktop:
|
||||||
|
- Fallback Poweroff prompt when power settings is unavailable (by @Willy-JL)
|
||||||
|
- OFW: Autolock fixes (by @portasynthinca3)
|
||||||
- Storage:
|
- Storage:
|
||||||
- Fallback SD format prompt when storage settings is unavailable (by @Willy-JL)
|
- Fallback SD format prompt when storage settings is unavailable (by @Willy-JL)
|
||||||
- OFW: Fix folder rename fails (by @portasynthinca3)
|
- OFW: Fix folder rename fails (by @portasynthinca3)
|
||||||
|
|||||||
Submodule applications/external updated: 4915916f6f...49c4239152
@@ -132,11 +132,8 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) {
|
|||||||
uint32_t current_frequency = subghz_setting_get_frequency(instance->setting, i);
|
uint32_t current_frequency = subghz_setting_get_frequency(instance->setting, i);
|
||||||
// if(furi_hal_subghz_is_frequency_valid(current_frequency) &&
|
// if(furi_hal_subghz_is_frequency_valid(current_frequency) &&
|
||||||
if(subghz_devices_is_frequency_valid(radio_device, current_frequency) &&
|
if(subghz_devices_is_frequency_valid(radio_device, current_frequency) &&
|
||||||
(current_frequency != 467750000) && (current_frequency != 464000000) &&
|
(((current_frequency != 467750000) && (current_frequency != 464000000)) &&
|
||||||
!((instance->ext_radio) &&
|
(current_frequency <= 920000000))) {
|
||||||
((current_frequency == 390000000) || (current_frequency == 312000000) ||
|
|
||||||
(current_frequency == 312100000) || (current_frequency == 312200000) ||
|
|
||||||
(current_frequency == 440175000)))) {
|
|
||||||
furi_hal_spi_acquire(spi_bus);
|
furi_hal_spi_acquire(spi_bus);
|
||||||
cc1101_switch_to_idle(spi_bus);
|
cc1101_switch_to_idle(spi_bus);
|
||||||
frequency = cc1101_set_frequency(spi_bus, current_frequency);
|
frequency = cc1101_set_frequency(spi_bus, current_frequency);
|
||||||
@@ -323,18 +320,21 @@ void subghz_frequency_analyzer_worker_start(
|
|||||||
furi_assert(instance);
|
furi_assert(instance);
|
||||||
furi_assert(!instance->worker_running);
|
furi_assert(!instance->worker_running);
|
||||||
|
|
||||||
|
/*
|
||||||
SubGhzRadioDeviceType radio_type = subghz_txrx_radio_device_get(txrx);
|
SubGhzRadioDeviceType radio_type = subghz_txrx_radio_device_get(txrx);
|
||||||
|
|
||||||
if(radio_type == SubGhzRadioDeviceTypeExternalCC1101) {
|
if(radio_type == SubGhzRadioDeviceTypeExternalCC1101) {
|
||||||
instance->spi_bus = &furi_hal_spi_bus_handle_external;
|
instance->spi_bus = &furi_hal_spi_bus_handle_external;
|
||||||
instance->ext_radio = true;
|
instance->ext_radio = true;
|
||||||
} else if(radio_type == SubGhzRadioDeviceTypeInternal) {
|
} else if(radio_type == SubGhzRadioDeviceTypeInternal) {
|
||||||
instance->spi_bus = &furi_hal_spi_bus_handle_subghz;
|
*/
|
||||||
instance->ext_radio = false;
|
instance->spi_bus = &furi_hal_spi_bus_handle_subghz;
|
||||||
|
/*
|
||||||
|
instance->ext_radio = false;
|
||||||
} else {
|
} else {
|
||||||
furi_crash("Unsuported external module");
|
furi_crash("Wrong subghz radio type");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
instance->radio_device = subghz_devices_get_by_name(subghz_txrx_radio_device_get_name(txrx));
|
instance->radio_device = subghz_devices_get_by_name(subghz_txrx_radio_device_get_name(txrx));
|
||||||
|
|
||||||
instance->worker_running = true;
|
instance->worker_running = true;
|
||||||
@@ -365,3 +365,33 @@ void subghz_frequency_analyzer_worker_set_trigger_level(
|
|||||||
float subghz_frequency_analyzer_worker_get_trigger_level(SubGhzFrequencyAnalyzerWorker* instance) {
|
float subghz_frequency_analyzer_worker_get_trigger_level(SubGhzFrequencyAnalyzerWorker* instance) {
|
||||||
return instance->trigger_level;
|
return instance->trigger_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t subghz_frequency_analyzer_get_nearest_frequency(
|
||||||
|
SubGhzFrequencyAnalyzerWorker* instance,
|
||||||
|
uint32_t input) {
|
||||||
|
uint32_t prev_freq = 0;
|
||||||
|
uint32_t result = 0;
|
||||||
|
uint32_t current;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < subghz_setting_get_frequency_count(instance->setting); i++) {
|
||||||
|
current = subghz_setting_get_frequency(instance->setting, i);
|
||||||
|
if(current == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(current == input) {
|
||||||
|
result = current;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(current > input && prev_freq < input) {
|
||||||
|
if(current - input < input - prev_freq) {
|
||||||
|
result = current;
|
||||||
|
} else {
|
||||||
|
result = prev_freq;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev_freq = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|||||||
@@ -78,3 +78,8 @@ void subghz_frequency_analyzer_worker_set_trigger_level(
|
|||||||
* @return RSSI trigger level
|
* @return RSSI trigger level
|
||||||
*/
|
*/
|
||||||
float subghz_frequency_analyzer_worker_get_trigger_level(SubGhzFrequencyAnalyzerWorker* instance);
|
float subghz_frequency_analyzer_worker_get_trigger_level(SubGhzFrequencyAnalyzerWorker* instance);
|
||||||
|
|
||||||
|
// Round up the frequency
|
||||||
|
uint32_t subghz_frequency_analyzer_get_nearest_frequency(
|
||||||
|
SubGhzFrequencyAnalyzerWorker* instance,
|
||||||
|
uint32_t input);
|
||||||
|
|||||||
@@ -20,71 +20,6 @@
|
|||||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const uint32_t subghz_frequency_list[] = {
|
|
||||||
/* 300 - 348 */
|
|
||||||
300000000,
|
|
||||||
302757000,
|
|
||||||
303875000,
|
|
||||||
303900000,
|
|
||||||
304250000,
|
|
||||||
307000000,
|
|
||||||
307500000,
|
|
||||||
307800000,
|
|
||||||
309000000,
|
|
||||||
310000000,
|
|
||||||
312000000,
|
|
||||||
312100000,
|
|
||||||
312200000,
|
|
||||||
313000000,
|
|
||||||
313850000,
|
|
||||||
314000000,
|
|
||||||
314350000,
|
|
||||||
314980000,
|
|
||||||
315000000,
|
|
||||||
318000000,
|
|
||||||
330000000,
|
|
||||||
345000000,
|
|
||||||
348000000,
|
|
||||||
350000000,
|
|
||||||
|
|
||||||
/* 387 - 464 */
|
|
||||||
387000000,
|
|
||||||
390000000,
|
|
||||||
418000000,
|
|
||||||
430000000,
|
|
||||||
430500000,
|
|
||||||
431000000,
|
|
||||||
431500000,
|
|
||||||
433075000, /* LPD433 first */
|
|
||||||
433220000,
|
|
||||||
433420000,
|
|
||||||
433657070,
|
|
||||||
433889000,
|
|
||||||
433920000, /* LPD433 mid */
|
|
||||||
434075000,
|
|
||||||
434176948,
|
|
||||||
434190000,
|
|
||||||
434390000,
|
|
||||||
434420000,
|
|
||||||
434620000,
|
|
||||||
434775000, /* LPD433 last channels */
|
|
||||||
438900000,
|
|
||||||
440175000,
|
|
||||||
464000000,
|
|
||||||
467750000,
|
|
||||||
|
|
||||||
/* 779 - 928 */
|
|
||||||
779000000,
|
|
||||||
868350000,
|
|
||||||
868400000,
|
|
||||||
868800000,
|
|
||||||
868950000,
|
|
||||||
906400000,
|
|
||||||
915000000,
|
|
||||||
925000000,
|
|
||||||
928000000,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SubGhzFrequencyAnalyzerStatusIDLE,
|
SubGhzFrequencyAnalyzerStatusIDLE,
|
||||||
} SubGhzFrequencyAnalyzerStatus;
|
} SubGhzFrequencyAnalyzerStatus;
|
||||||
@@ -225,7 +160,7 @@ void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel
|
|||||||
canvas_set_color(canvas, ColorBlack);
|
canvas_set_color(canvas, ColorBlack);
|
||||||
canvas_set_font(canvas, FontSecondary);
|
canvas_set_font(canvas, FontSecondary);
|
||||||
|
|
||||||
canvas_draw_str(canvas, 0, 7, model->is_ext_radio ? "Ext" : "Int");
|
//canvas_draw_str(canvas, 0, 7, model->is_ext_radio ? "Ext" : "Int");
|
||||||
canvas_draw_str(canvas, 20, 7, "Frequency Analyzer");
|
canvas_draw_str(canvas, 20, 7, "Frequency Analyzer");
|
||||||
|
|
||||||
// RSSI
|
// RSSI
|
||||||
@@ -278,34 +213,6 @@ void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel
|
|||||||
elements_button_right(canvas, "+T");
|
elements_button_right(canvas, "+T");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t subghz_frequency_find_correct(uint32_t input) {
|
|
||||||
uint32_t prev_freq = 0;
|
|
||||||
uint32_t result = 0;
|
|
||||||
uint32_t current;
|
|
||||||
|
|
||||||
for(size_t i = 0; i < ARRAY_SIZE(subghz_frequency_list) - 1; i++) {
|
|
||||||
current = subghz_frequency_list[i];
|
|
||||||
if(current == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(current == input) {
|
|
||||||
result = current;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(current > input && prev_freq < input) {
|
|
||||||
if(current - input < input - prev_freq) {
|
|
||||||
result = current;
|
|
||||||
} else {
|
|
||||||
result = prev_freq;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
prev_freq = current;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool subghz_frequency_analyzer_input(InputEvent* event, void* context) {
|
bool subghz_frequency_analyzer_input(InputEvent* event, void* context) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
SubGhzFrequencyAnalyzer* instance = (SubGhzFrequencyAnalyzer*)context;
|
SubGhzFrequencyAnalyzer* instance = (SubGhzFrequencyAnalyzer*)context;
|
||||||
@@ -364,7 +271,8 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) {
|
|||||||
} else if(
|
} else if(
|
||||||
(model->show_frame && model->signal) ||
|
(model->show_frame && model->signal) ||
|
||||||
(!model->show_frame && model->signal)) {
|
(!model->show_frame && model->signal)) {
|
||||||
frequency_candidate = subghz_frequency_find_correct(model->frequency);
|
frequency_candidate = subghz_frequency_analyzer_get_nearest_frequency(
|
||||||
|
instance->worker, model->frequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
frequency_candidate = frequency_candidate == 0 ||
|
frequency_candidate = frequency_candidate == 0 ||
|
||||||
@@ -372,7 +280,8 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) {
|
|||||||
instance->txrx, frequency_candidate) ||
|
instance->txrx, frequency_candidate) ||
|
||||||
prev_freq_to_save == frequency_candidate ?
|
prev_freq_to_save == frequency_candidate ?
|
||||||
0 :
|
0 :
|
||||||
subghz_frequency_find_correct(frequency_candidate);
|
subghz_frequency_analyzer_get_nearest_frequency(
|
||||||
|
instance->worker, frequency_candidate);
|
||||||
if(frequency_candidate > 0 && frequency_candidate != model->frequency_to_save) {
|
if(frequency_candidate > 0 && frequency_candidate != model->frequency_to_save) {
|
||||||
model->frequency_to_save = frequency_candidate;
|
model->frequency_to_save = frequency_candidate;
|
||||||
updated = true;
|
updated = true;
|
||||||
@@ -445,7 +354,8 @@ void subghz_frequency_analyzer_pair_callback(
|
|||||||
SubGhzFrequencyAnalyzerModel * model,
|
SubGhzFrequencyAnalyzerModel * model,
|
||||||
{
|
{
|
||||||
bool in_array = false;
|
bool in_array = false;
|
||||||
uint32_t normal_frequency = subghz_frequency_find_correct(model->frequency);
|
uint32_t normal_frequency = subghz_frequency_analyzer_get_nearest_frequency(
|
||||||
|
instance->worker, model->frequency);
|
||||||
for(size_t i = 0; i < MAX_HISTORY; i++) {
|
for(size_t i = 0; i < MAX_HISTORY; i++) {
|
||||||
if(model->history_frequency[i] == normal_frequency) {
|
if(model->history_frequency[i] == normal_frequency) {
|
||||||
in_array = true;
|
in_array = true;
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
#include <furi_hal_usb_cdc.h>
|
#include <furi_hal_usb_cdc.h>
|
||||||
#include <furi_hal.h>
|
#include <furi_hal.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
#include <gui/gui.h>
|
||||||
|
#include <gui/view_port.h>
|
||||||
|
#include <assets_icons.h>
|
||||||
|
#include <applications/services/desktop/desktop.h>
|
||||||
|
|
||||||
#define TAG "CliVcp"
|
#define TAG "CliVcp"
|
||||||
|
|
||||||
@@ -43,6 +47,13 @@ typedef struct {
|
|||||||
FuriHalUsbInterface* usb_if_prev;
|
FuriHalUsbInterface* usb_if_prev;
|
||||||
|
|
||||||
uint8_t data_buffer[USB_CDC_PKT_LEN];
|
uint8_t data_buffer[USB_CDC_PKT_LEN];
|
||||||
|
|
||||||
|
// CLI icon
|
||||||
|
Gui* gui;
|
||||||
|
ViewPort* view_port;
|
||||||
|
|
||||||
|
// Autolocking inhibition
|
||||||
|
Desktop* desktop;
|
||||||
} CliVcp;
|
} CliVcp;
|
||||||
|
|
||||||
static int32_t vcp_worker(void* context);
|
static int32_t vcp_worker(void* context);
|
||||||
@@ -64,6 +75,13 @@ static CliVcp* vcp = NULL;
|
|||||||
static const uint8_t ascii_soh = 0x01;
|
static const uint8_t ascii_soh = 0x01;
|
||||||
static const uint8_t ascii_eot = 0x04;
|
static const uint8_t ascii_eot = 0x04;
|
||||||
|
|
||||||
|
static void cli_vcp_icon_draw_callback(Canvas* canvas, void* context) {
|
||||||
|
furi_assert(canvas);
|
||||||
|
furi_assert(context);
|
||||||
|
const Icon* icon = context;
|
||||||
|
canvas_draw_icon(canvas, 0, 0, icon);
|
||||||
|
}
|
||||||
|
|
||||||
static void cli_vcp_init(void) {
|
static void cli_vcp_init(void) {
|
||||||
if(vcp == NULL) {
|
if(vcp == NULL) {
|
||||||
vcp = malloc(sizeof(CliVcp));
|
vcp = malloc(sizeof(CliVcp));
|
||||||
@@ -103,6 +121,15 @@ static int32_t vcp_worker(void* context) {
|
|||||||
FURI_LOG_D(TAG, "Start");
|
FURI_LOG_D(TAG, "Start");
|
||||||
vcp->running = true;
|
vcp->running = true;
|
||||||
|
|
||||||
|
// GUI icon
|
||||||
|
vcp->desktop = furi_record_open(RECORD_DESKTOP);
|
||||||
|
const Icon* icon = &I_Console_active_8x8;
|
||||||
|
vcp->gui = furi_record_open(RECORD_GUI);
|
||||||
|
vcp->view_port = view_port_alloc();
|
||||||
|
view_port_set_width(vcp->view_port, icon_get_width(icon));
|
||||||
|
// casting const away. we know that we cast it right back in the callback
|
||||||
|
view_port_draw_callback_set(vcp->view_port, cli_vcp_icon_draw_callback, (void*)icon);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
uint32_t flags =
|
uint32_t flags =
|
||||||
furi_thread_flags_wait(VCP_THREAD_FLAG_ALL, FuriFlagWaitAny, FuriWaitForever);
|
furi_thread_flags_wait(VCP_THREAD_FLAG_ALL, FuriFlagWaitAny, FuriWaitForever);
|
||||||
@@ -115,6 +142,8 @@ static int32_t vcp_worker(void* context) {
|
|||||||
if(vcp->connected == false) {
|
if(vcp->connected == false) {
|
||||||
vcp->connected = true;
|
vcp->connected = true;
|
||||||
furi_stream_buffer_send(vcp->rx_stream, &ascii_soh, 1, FuriWaitForever);
|
furi_stream_buffer_send(vcp->rx_stream, &ascii_soh, 1, FuriWaitForever);
|
||||||
|
gui_add_view_port(vcp->gui, vcp->view_port, GuiLayerStatusBarLeft);
|
||||||
|
desktop_api_add_external_inhibitor(vcp->desktop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,6 +155,8 @@ static int32_t vcp_worker(void* context) {
|
|||||||
vcp->connected = false;
|
vcp->connected = false;
|
||||||
furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0);
|
furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0);
|
||||||
furi_stream_buffer_send(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever);
|
furi_stream_buffer_send(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever);
|
||||||
|
gui_remove_view_port(vcp->gui, vcp->view_port);
|
||||||
|
desktop_api_remove_external_inhibitor(vcp->desktop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,6 +221,10 @@ static int32_t vcp_worker(void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(flags & VcpEvtStop) {
|
if(flags & VcpEvtStop) {
|
||||||
|
if(vcp->connected) {
|
||||||
|
gui_remove_view_port(vcp->gui, vcp->view_port);
|
||||||
|
desktop_api_remove_external_inhibitor(vcp->desktop);
|
||||||
|
}
|
||||||
vcp->connected = false;
|
vcp->connected = false;
|
||||||
vcp->running = false;
|
vcp->running = false;
|
||||||
furi_hal_cdc_set_callbacks(VCP_IF_NUM, NULL, NULL);
|
furi_hal_cdc_set_callbacks(VCP_IF_NUM, NULL, NULL);
|
||||||
@@ -203,6 +238,11 @@ static int32_t vcp_worker(void* context) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
view_port_free(vcp->view_port);
|
||||||
|
furi_record_close(RECORD_DESKTOP);
|
||||||
|
furi_record_close(RECORD_GUI);
|
||||||
|
|
||||||
FURI_LOG_D(TAG, "End");
|
FURI_LOG_D(TAG, "End");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ static void desktop_auto_lock_arm(Desktop*);
|
|||||||
static void desktop_auto_lock_inhibit(Desktop*);
|
static void desktop_auto_lock_inhibit(Desktop*);
|
||||||
static void desktop_start_auto_lock_timer(Desktop*);
|
static void desktop_start_auto_lock_timer(Desktop*);
|
||||||
static void desktop_apply_settings(Desktop*);
|
static void desktop_apply_settings(Desktop*);
|
||||||
|
static void desktop_auto_lock_add_inhibitor(Desktop* desktop);
|
||||||
|
static void desktop_auto_lock_remove_inhibitor(Desktop* desktop);
|
||||||
|
|
||||||
static void desktop_loader_callback(const void* message, void* context) {
|
static void desktop_loader_callback(const void* message, void* context) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
@@ -125,16 +127,22 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) {
|
|||||||
animation_manager_unload_and_stall_animation(desktop->animation_manager);
|
animation_manager_unload_and_stall_animation(desktop->animation_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
desktop_auto_lock_inhibit(desktop);
|
desktop_auto_lock_add_inhibitor(desktop);
|
||||||
desktop->app_running = true;
|
desktop->app_running = true;
|
||||||
|
|
||||||
furi_semaphore_release(desktop->animation_semaphore);
|
furi_semaphore_release(desktop->animation_semaphore);
|
||||||
|
|
||||||
} else if(event == DesktopGlobalAfterAppFinished) {
|
} else if(event == DesktopGlobalAfterAppFinished) {
|
||||||
animation_manager_load_and_continue_animation(desktop->animation_manager);
|
animation_manager_load_and_continue_animation(desktop->animation_manager);
|
||||||
desktop_auto_lock_arm(desktop);
|
desktop_auto_lock_remove_inhibitor(desktop);
|
||||||
desktop->app_running = false;
|
desktop->app_running = false;
|
||||||
|
|
||||||
|
} else if(event == DesktopGlobalAddExternalInhibitor) {
|
||||||
|
desktop_auto_lock_add_inhibitor(desktop);
|
||||||
|
|
||||||
|
} else if(event == DesktopGlobalRemoveExternalInhibitor) {
|
||||||
|
desktop_auto_lock_remove_inhibitor(desktop);
|
||||||
|
|
||||||
} else if(event == DesktopGlobalAutoLock) {
|
} else if(event == DesktopGlobalAutoLock) {
|
||||||
if(!desktop->app_running && !desktop->locked) {
|
if(!desktop->app_running && !desktop->locked) {
|
||||||
desktop_lock(desktop, desktop->settings.auto_lock_with_pin);
|
desktop_lock(desktop, desktop->settings.auto_lock_with_pin);
|
||||||
@@ -205,6 +213,24 @@ static void desktop_auto_lock_arm(Desktop* desktop) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void desktop_auto_lock_add_inhibitor(Desktop* desktop) {
|
||||||
|
furi_check(furi_semaphore_release(desktop->auto_lock_inhibitors) == FuriStatusOk);
|
||||||
|
FURI_LOG_D(
|
||||||
|
TAG,
|
||||||
|
"%lu autolock inhibitors (+1)",
|
||||||
|
furi_semaphore_get_count(desktop->auto_lock_inhibitors));
|
||||||
|
desktop_auto_lock_inhibit(desktop);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void desktop_auto_lock_remove_inhibitor(Desktop* desktop) {
|
||||||
|
furi_check(furi_semaphore_acquire(desktop->auto_lock_inhibitors, 0) == FuriStatusOk);
|
||||||
|
uint32_t inhibitors = furi_semaphore_get_count(desktop->auto_lock_inhibitors);
|
||||||
|
FURI_LOG_D(TAG, "%lu autolock inhibitors (-1)", inhibitors);
|
||||||
|
if(inhibitors == 0) {
|
||||||
|
desktop_auto_lock_arm(desktop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void desktop_auto_lock_inhibit(Desktop* desktop) {
|
static void desktop_auto_lock_inhibit(Desktop* desktop) {
|
||||||
desktop_stop_auto_lock_timer(desktop);
|
desktop_stop_auto_lock_timer(desktop);
|
||||||
if(desktop->input_events_subscription) {
|
if(desktop->input_events_subscription) {
|
||||||
@@ -361,6 +387,7 @@ static Desktop* desktop_alloc(void) {
|
|||||||
desktop->input_events_pubsub = furi_record_open(RECORD_INPUT_EVENTS);
|
desktop->input_events_pubsub = furi_record_open(RECORD_INPUT_EVENTS);
|
||||||
desktop->ascii_events_pubsub = furi_record_open(RECORD_ASCII_EVENTS);
|
desktop->ascii_events_pubsub = furi_record_open(RECORD_ASCII_EVENTS);
|
||||||
|
|
||||||
|
desktop->auto_lock_inhibitors = furi_semaphore_alloc(UINT32_MAX, 0);
|
||||||
desktop->auto_lock_timer =
|
desktop->auto_lock_timer =
|
||||||
furi_timer_alloc(desktop_auto_lock_timer_callback, FuriTimerTypeOnce, desktop);
|
furi_timer_alloc(desktop_auto_lock_timer_callback, FuriTimerTypeOnce, desktop);
|
||||||
|
|
||||||
@@ -519,6 +546,18 @@ void desktop_api_set_settings(Desktop* instance, const DesktopSettings* settings
|
|||||||
view_dispatcher_send_custom_event(instance->view_dispatcher, DesktopGlobalSaveSettings);
|
view_dispatcher_send_custom_event(instance->view_dispatcher, DesktopGlobalSaveSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void desktop_api_add_external_inhibitor(Desktop* instance) {
|
||||||
|
furi_assert(instance);
|
||||||
|
view_dispatcher_send_custom_event(
|
||||||
|
instance->view_dispatcher, DesktopGlobalAddExternalInhibitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void desktop_api_remove_external_inhibitor(Desktop* instance) {
|
||||||
|
furi_assert(instance);
|
||||||
|
view_dispatcher_send_custom_event(
|
||||||
|
instance->view_dispatcher, DesktopGlobalRemoveExternalInhibitor);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Application thread
|
* Application thread
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -21,3 +21,17 @@ FuriPubSub* desktop_api_get_status_pubsub(Desktop* instance);
|
|||||||
void desktop_api_get_settings(Desktop* instance, DesktopSettings* settings);
|
void desktop_api_get_settings(Desktop* instance, DesktopSettings* settings);
|
||||||
|
|
||||||
void desktop_api_set_settings(Desktop* instance, const DesktopSettings* settings);
|
void desktop_api_set_settings(Desktop* instance, const DesktopSettings* settings);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Adds 1 to the count of active external autolock inhibitors
|
||||||
|
*
|
||||||
|
* Autolocking will not get triggered while there's at least 1 inhibitor
|
||||||
|
*/
|
||||||
|
void desktop_api_add_external_inhibitor(Desktop* instance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Removes 1 from the count of active external autolock inhibitors
|
||||||
|
*
|
||||||
|
* Autolocking will not get triggered while there's at least 1 inhibitor
|
||||||
|
*/
|
||||||
|
void desktop_api_remove_external_inhibitor(Desktop* instance);
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ struct Desktop {
|
|||||||
FuriPubSub* input_events_pubsub;
|
FuriPubSub* input_events_pubsub;
|
||||||
FuriPubSubSubscription* input_events_subscription;
|
FuriPubSubSubscription* input_events_subscription;
|
||||||
|
|
||||||
|
FuriSemaphore* auto_lock_inhibitors;
|
||||||
FuriTimer* auto_lock_timer;
|
FuriTimer* auto_lock_timer;
|
||||||
FuriTimer* update_clock_timer;
|
FuriTimer* update_clock_timer;
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ typedef enum {
|
|||||||
DesktopGlobalApiUnlock,
|
DesktopGlobalApiUnlock,
|
||||||
DesktopGlobalSaveSettings,
|
DesktopGlobalSaveSettings,
|
||||||
DesktopGlobalReloadSettings,
|
DesktopGlobalReloadSettings,
|
||||||
|
DesktopGlobalAddExternalInhibitor,
|
||||||
|
DesktopGlobalRemoveExternalInhibitor,
|
||||||
|
|
||||||
DesktopMainEventLockKeypad,
|
DesktopMainEventLockKeypad,
|
||||||
DesktopLockedEventOpenPowerOff,
|
DesktopLockedEventOpenPowerOff,
|
||||||
|
|||||||
BIN
assets/icons/StatusBar/Console_active_8x8.png
Normal file
BIN
assets/icons/StatusBar/Console_active_8x8.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 75 B |
@@ -42,6 +42,8 @@ if you need your custom one, make sure it doesn't listed here
|
|||||||
314980000,
|
314980000,
|
||||||
315000000,
|
315000000,
|
||||||
318000000,
|
318000000,
|
||||||
|
320000000,
|
||||||
|
320150000,
|
||||||
330000000,
|
330000000,
|
||||||
345000000,
|
345000000,
|
||||||
348000000,
|
348000000,
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ static const uint32_t subghz_frequency_list[] = {
|
|||||||
314980000,
|
314980000,
|
||||||
315000000,
|
315000000,
|
||||||
318000000,
|
318000000,
|
||||||
|
320000000,
|
||||||
|
320150000,
|
||||||
330000000,
|
330000000,
|
||||||
345000000,
|
345000000,
|
||||||
348000000,
|
348000000,
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ def main():
|
|||||||
parser.add_argument("-p", "--port", help="CDC Port", default="auto")
|
parser.add_argument("-p", "--port", help="CDC Port", default="auto")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
if not (port := resolve_port(logger, args.port)):
|
if not (port := resolve_port(logger, args.port)):
|
||||||
logger.error("Is Flipper connected via USB and not in DFU mode?")
|
logger.error(
|
||||||
|
"Is Flipper connected via USB, currently unlocked and not in DFU mode?"
|
||||||
|
)
|
||||||
return 1
|
return 1
|
||||||
subprocess.call(
|
subprocess.call(
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -3916,6 +3916,7 @@ Variable,+,I_Circles_47x47,const Icon,
|
|||||||
Variable,+,I_Clock_18x18,const Icon,
|
Variable,+,I_Clock_18x18,const Icon,
|
||||||
Variable,+,I_Connect_me_62x31,const Icon,
|
Variable,+,I_Connect_me_62x31,const Icon,
|
||||||
Variable,+,I_Connected_62x31,const Icon,
|
Variable,+,I_Connected_62x31,const Icon,
|
||||||
|
Variable,+,I_Console_active_8x8,const Icon,
|
||||||
Variable,+,I_Cos_9x7,const Icon,
|
Variable,+,I_Cos_9x7,const Icon,
|
||||||
Variable,+,I_DFU_128x50,const Icon,
|
Variable,+,I_DFU_128x50,const Icon,
|
||||||
Variable,+,I_DolphinDone_80x58,const Icon,
|
Variable,+,I_DolphinDone_80x58,const Icon,
|
||||||
|
|||||||
|
Reference in New Issue
Block a user