diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dc889d2f..23e815ba9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,12 @@ * Misc: Name changer code moved to proper place, load after system startup + extra checks * Plugins: NMEA GPS UART - stability fix * Plugins: Port XFW keyboard with extra symbols to WiFi Marauder instead of using UART Term keyboard (thanks to @Willy-JL) +* Plugins: Update NMEA GPS UART [(by ezod)](https://github.com/ezod/flipperzero-gps) * Plugins: Update WiFi Marauder [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion) +* OFW: Services: remove deallocator for persistent services +* OFW: Storage: common_rename is now POSIX compliant +* OFW: Removed user-specific data from tar artifacts +* OFW: fbt: Fix tar uid overflow when packaging * OFW: fbt: Use union for old py (Fix builds if using older python versions) * OFW PR 2682: USB HID report timeout (by nminaylov) diff --git a/applications/external/gps_nmea_uart/gps_uart.c b/applications/external/gps_nmea_uart/gps_uart.c index ada8f04f9..d44cf22ef 100644 --- a/applications/external/gps_nmea_uart/gps_uart.c +++ b/applications/external/gps_nmea_uart/gps_uart.c @@ -66,6 +66,19 @@ static void gps_uart_parse_nmea(GpsUart* gps_uart, char* line) { } } break; + case MINMEA_SENTENCE_GLL: { + struct minmea_sentence_gll frame; + if(minmea_parse_gll(&frame, line)) { + gps_uart->status.latitude = minmea_tocoord(&frame.latitude); + gps_uart->status.longitude = minmea_tocoord(&frame.longitude); + gps_uart->status.time_hours = frame.time.hours; + gps_uart->status.time_minutes = frame.time.minutes; + gps_uart->status.time_seconds = frame.time.seconds; + + notification_message_block(gps_uart->notifications, &sequence_blink_red_10); + } + } break; + default: break; } @@ -88,35 +101,53 @@ static int32_t gps_uart_worker(void* context) { if(events & WorkerEvtRxDone) { size_t len = 0; do { + // receive serial bytes into rx_buf, starting at rx_offset from the start of the buffer + // the maximum we can receive is RX_BUF_SIZE - 1 - rx_offset len = furi_stream_buffer_receive( gps_uart->rx_stream, gps_uart->rx_buf + rx_offset, RX_BUF_SIZE - 1 - rx_offset, 0); if(len > 0) { + // increase rx_offset by the number of bytes received, and null-terminate rx_buf rx_offset += len; gps_uart->rx_buf[rx_offset] = '\0'; + // look for strings ending in newlines, starting at the start of rx_buf char* line_current = (char*)gps_uart->rx_buf; while(1) { + // skip null characters while(*line_current == '\0' && line_current < (char*)gps_uart->rx_buf + rx_offset - 1) { line_current++; } + // find the next newline char* newline = strchr(line_current, '\n'); - if(newline) { + if(newline) // newline found + { + // put a null terminator in place of the newline, to delimit the line string *newline = '\0'; + + // attempt to parse the line as a NMEA sentence gps_uart_parse_nmea(gps_uart, line_current); + + // move the cursor to the character after the newline line_current = newline + 1; - } else { - if(line_current > (char*)gps_uart->rx_buf) { + } else // no more newlines found + { + if(line_current > + (char*)gps_uart->rx_buf) // at least one line was found + { + // clear parsed lines, and move any leftover bytes to the start of rx_buf rx_offset = 0; - while(*line_current) { + while( + *line_current) // stop when the original rx_offset terminator is reached + { gps_uart->rx_buf[rx_offset++] = *(line_current++); } } - break; + break; // go back to receiving bytes from the serial stream } } } diff --git a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_start.c b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_start.c index 28a3ed2a9..b2bd39d3e 100644 --- a/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_start.c +++ b/applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_start.c @@ -97,6 +97,7 @@ const WifiMarauderItem items[NUM_MENU_ITEMS] = { NO_ARGS, FOCUS_CONSOLE_END, SHOW_STOPSCAN_TIP}, + {"Signal Monitor", {""}, 1, {"sigmon"}, NO_ARGS, FOCUS_CONSOLE_END, SHOW_STOPSCAN_TIP}, {"Channel", {"get", "set"}, 2, diff --git a/applications/external/wifi_marauder_companion/wifi_marauder_app.h b/applications/external/wifi_marauder_companion/wifi_marauder_app.h index 7e3856059..5457f89d8 100644 --- a/applications/external/wifi_marauder_companion/wifi_marauder_app.h +++ b/applications/external/wifi_marauder_companion/wifi_marauder_app.h @@ -4,7 +4,7 @@ extern "C" { #endif -#define WIFI_MARAUDER_APP_VERSION "v0.3.6" +#define WIFI_MARAUDER_APP_VERSION "v0.3.7" typedef struct WifiMarauderApp WifiMarauderApp; diff --git a/applications/external/wifi_marauder_companion/wifi_marauder_app_i.h b/applications/external/wifi_marauder_companion/wifi_marauder_app_i.h index 45e1e5920..2a16522bb 100644 --- a/applications/external/wifi_marauder_companion/wifi_marauder_app_i.h +++ b/applications/external/wifi_marauder_companion/wifi_marauder_app_i.h @@ -26,7 +26,7 @@ #include #include -#define NUM_MENU_ITEMS (17) +#define NUM_MENU_ITEMS (18) #define WIFI_MARAUDER_TEXT_BOX_STORE_SIZE (4096) #define WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE (512) diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index c25af0da5..33a99b07e 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -434,59 +434,6 @@ Desktop* desktop_alloc() { return desktop; } -void desktop_free(Desktop* desktop) { - furi_assert(desktop); - furi_check(furi_record_destroy(RECORD_DESKTOP)); - - furi_pubsub_unsubscribe( - loader_get_pubsub(desktop->loader), desktop->app_start_stop_subscription); - - if(desktop->input_events_subscription) { - furi_pubsub_unsubscribe(desktop->input_events_pubsub, desktop->input_events_subscription); - desktop->input_events_subscription = NULL; - } - - desktop->loader = NULL; - desktop->input_events_pubsub = NULL; - furi_record_close(RECORD_LOADER); - furi_record_close(RECORD_NOTIFICATION); - furi_record_close(RECORD_INPUT_EVENTS); - - view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdMain); - view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdLockMenu); - view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdLocked); - view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdDebug); - view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdHwMismatch); - view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdPinInput); - view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdPinTimeout); - - view_dispatcher_free(desktop->view_dispatcher); - scene_manager_free(desktop->scene_manager); - - animation_manager_free(desktop->animation_manager); - view_stack_free(desktop->main_view_stack); - desktop_main_free(desktop->main_view); - view_stack_free(desktop->locked_view_stack); - desktop_view_locked_free(desktop->locked_view); - desktop_lock_menu_free(desktop->lock_menu); - desktop_view_locked_free(desktop->locked_view); - desktop_debug_free(desktop->debug_view); - popup_free(desktop->hw_mismatch_popup); - desktop_view_pin_timeout_free(desktop->pin_timeout_view); - - furi_record_close(RECORD_GUI); - desktop->gui = NULL; - - furi_thread_free(desktop->scene_thread); - - furi_record_close("menu"); - - furi_timer_free(desktop->auto_lock_timer); - furi_timer_free(desktop->update_clock_timer); - - free(desktop); -} - static bool desktop_check_file_flag(const char* flag_path) { Storage* storage = furi_record_open(RECORD_STORAGE); bool exists = storage_common_stat(storage, flag_path, NULL) == FSE_OK; @@ -552,7 +499,8 @@ int32_t desktop_srv(void* p) { } view_dispatcher_run(desktop->view_dispatcher); - desktop_free(desktop); + + furi_crash("That was unexpected"); return 0; } diff --git a/applications/services/dolphin/dolphin.c b/applications/services/dolphin/dolphin.c index dd8b7105f..93a9b3095 100644 --- a/applications/services/dolphin/dolphin.c +++ b/applications/services/dolphin/dolphin.c @@ -89,15 +89,6 @@ Dolphin* dolphin_alloc() { return dolphin; } -void dolphin_free(Dolphin* dolphin) { - furi_assert(dolphin); - - dolphin_state_free(dolphin->state); - furi_message_queue_free(dolphin->event_queue); - - free(dolphin); -} - void dolphin_event_send_async(Dolphin* dolphin, DolphinEvent* event) { furi_assert(dolphin); furi_assert(event); @@ -204,7 +195,7 @@ int32_t dolphin_srv(void* p) { } } - dolphin_free(dolphin); + furi_crash("That was unexpected"); return 0; } diff --git a/applications/services/dolphin/dolphin_i.h b/applications/services/dolphin/dolphin_i.h index 4bb0df08e..ceeff1e1a 100644 --- a/applications/services/dolphin/dolphin_i.h +++ b/applications/services/dolphin/dolphin_i.h @@ -37,8 +37,6 @@ struct Dolphin { Dolphin* dolphin_alloc(); -void dolphin_free(Dolphin* dolphin); - void dolphin_event_send_async(Dolphin* dolphin, DolphinEvent* event); void dolphin_event_send_wait(Dolphin* dolphin, DolphinEvent* event); diff --git a/applications/services/power/power_service/power.c b/applications/services/power/power_service/power.c index e61776060..a495e5d6c 100644 --- a/applications/services/power/power_service/power.c +++ b/applications/services/power/power_service/power.c @@ -268,30 +268,6 @@ Power* power_alloc() { return power; } -void power_free(Power* power) { - furi_assert(power); - - // Gui - view_dispatcher_remove_view(power->view_dispatcher, PowerViewOff); - power_off_free(power->power_off); - view_dispatcher_remove_view(power->view_dispatcher, PowerViewUnplugUsb); - power_unplug_usb_free(power->power_unplug_usb); - - view_port_free(power->battery_view_port); - - // State - furi_mutex_free(power->api_mtx); - - // FuriPubSub - furi_pubsub_free(power->event_pubsub); - - // Records - furi_record_close(RECORD_NOTIFICATION); - furi_record_close(RECORD_GUI); - - free(power); -} - static void power_check_charging_state(Power* power) { if(furi_hal_power_is_charging()) { if((power->info.charge == 100) || (furi_hal_power_is_charging_done())) { @@ -454,7 +430,7 @@ int32_t power_srv(void* p) { furi_delay_ms(1000); } - power_free(power); + furi_crash("That was unexpected"); return 0; } diff --git a/applications/services/storage/storage.h b/applications/services/storage/storage.h index 5991e765f..bcd1d0df6 100644 --- a/applications/services/storage/storage.h +++ b/applications/services/storage/storage.h @@ -226,7 +226,7 @@ FS_Error storage_common_stat(Storage* storage, const char* path, FileInfo* filei */ FS_Error storage_common_remove(Storage* storage, const char* path); -/** Renames file/directory, file/directory must not be open +/** Renames file/directory, file/directory must not be open. Will overwrite existing file. * @param app pointer to the api * @param old_path old path * @param new_path new path diff --git a/applications/services/storage/storage_external_api.c b/applications/services/storage/storage_external_api.c index bf474bc9d..549397c87 100644 --- a/applications/services/storage/storage_external_api.c +++ b/applications/services/storage/storage_external_api.c @@ -422,7 +422,16 @@ FS_Error storage_common_remove(Storage* storage, const char* path) { } FS_Error storage_common_rename(Storage* storage, const char* old_path, const char* new_path) { - FS_Error error = storage_common_copy(storage, old_path, new_path); + FS_Error error; + + if(storage_file_exists(storage, new_path)) { + error = storage_common_remove(storage, new_path); + if(error != FSE_OK) { + return error; + } + } + + error = storage_common_copy(storage, old_path, new_path); if(error == FSE_OK) { if(!storage_simply_remove_recursive(storage, old_path)) { error = FSE_INTERNAL; diff --git a/scripts/sconsdist.py b/scripts/sconsdist.py index fbb4214fe..fc121390d 100644 --- a/scripts/sconsdist.py +++ b/scripts/sconsdist.py @@ -275,6 +275,8 @@ class Main(App): # Strip uid and gid in case of overflow def tar_filter(tarinfo): tarinfo.uid = tarinfo.gid = 0 + tarinfo.mtime = 0 + tarinfo.uname = tarinfo.gname = "furippa" return tarinfo tar.add(bundle_dir, arcname=bundle_dir_name, filter=tar_filter) diff --git a/scripts/update.py b/scripts/update.py index 0f3ee6ea8..9f0d95d94 100755 --- a/scripts/update.py +++ b/scripts/update.py @@ -211,6 +211,9 @@ class Main(App): f"Cannot package resource: name '{tarinfo.name}' too long" ) raise ValueError("Resource name too long") + tarinfo.gid = tarinfo.uid = 0 + tarinfo.mtime = 0 + tarinfo.uname = tarinfo.gname = "furippa" return tarinfo def package_resources(self, srcdir: str, dst_name: str):