From 2dca408e45579237d97638d662318c228f021f07 Mon Sep 17 00:00:00 2001 From: Totoo Date: Fri, 29 Mar 2024 01:25:23 +0100 Subject: [PATCH] Wardrive Map app (#2050) * WardriveMap app * better txt * Count only displayed markers --- firmware/application/external/external.cmake | 5 + firmware/application/external/external.ld | 7 + .../external/foxhunt/ui_foxhunt_rx.cpp | 3 +- .../application/external/wardrivemap/main.cpp | 82 ++++++++++ .../external/wardrivemap/ui_wardrivemap.cpp | 143 ++++++++++++++++++ .../external/wardrivemap/ui_wardrivemap.hpp | 85 +++++++++++ 6 files changed, 323 insertions(+), 2 deletions(-) create mode 100644 firmware/application/external/wardrivemap/main.cpp create mode 100644 firmware/application/external/wardrivemap/ui_wardrivemap.cpp create mode 100644 firmware/application/external/wardrivemap/ui_wardrivemap.hpp diff --git a/firmware/application/external/external.cmake b/firmware/application/external/external.cmake index 120e58db..c8c3878b 100644 --- a/firmware/application/external/external.cmake +++ b/firmware/application/external/external.cmake @@ -76,6 +76,10 @@ set(EXTCPPSRC #audio_test external/audio_test/main.cpp external/audio_test/ui_audio_test.cpp + + #wardrivemap + external/wardrivemap/main.cpp + external/wardrivemap/ui_wardrivemap.cpp ) set(EXTAPPLIST @@ -97,4 +101,5 @@ set(EXTAPPLIST extsensors foxhunt_rx audio_test + wardrivemap ) diff --git a/firmware/application/external/external.ld b/firmware/application/external/external.ld index 4e3f1268..d42fee55 100644 --- a/firmware/application/external/external.ld +++ b/firmware/application/external/external.ld @@ -41,6 +41,7 @@ MEMORY ram_external_app_extsensors(rwx) : org = 0xADBF0000, len = 32k ram_external_app_foxhunt_rx(rwx) : org = 0xADC00000, len = 32k ram_external_app_audio_test(rwx) : org = 0xADC10000, len = 32k + ram_external_app_wardrivemap(rwx) : org = 0xADC20000, len = 32k } SECTIONS @@ -153,4 +154,10 @@ SECTIONS *(*ui*external_app*audio_test*); } > ram_external_app_audio_test + .external_app_wardrivemap : ALIGN(4) SUBALIGN(4) + { + KEEP(*(.external_app.app_wardrivemap.application_information)); + *(*ui*external_app*wardrivemap*); + } > ram_external_app_wardrivemap + } diff --git a/firmware/application/external/foxhunt/ui_foxhunt_rx.cpp b/firmware/application/external/foxhunt/ui_foxhunt_rx.cpp index cac19c30..3c8bfb11 100644 --- a/firmware/application/external/foxhunt/ui_foxhunt_rx.cpp +++ b/firmware/application/external/foxhunt/ui_foxhunt_rx.cpp @@ -62,8 +62,7 @@ FoxhuntRxView::FoxhuntRxView(NavigationView& nav) }; geomap.set_mode(DISPLAY); geomap.set_manual_panning(false); - // geomap.set_enable_additional_zoom(true); - // geomap.set_hide_center_marker(true); //todo hide again after testing + // geomap.set_hide_center_marker(true); //todo test if needed geomap.set_focusable(true); geomap.clear_markers(); receiver_model.set_modulation(ReceiverModel::Mode::AMAudio); diff --git a/firmware/application/external/wardrivemap/main.cpp b/firmware/application/external/wardrivemap/main.cpp new file mode 100644 index 00000000..fb5fb7eb --- /dev/null +++ b/firmware/application/external/wardrivemap/main.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2023 Bernd Herzog + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "ui.hpp" +#include "ui_wardrivemap.hpp" +#include "ui_navigation.hpp" +#include "external_app.hpp" + +namespace ui::external_app::wardrivemap { +void initialize_app(ui::NavigationView& nav) { + nav.push(); +} +} // namespace ui::external_app::wardrivemap + +extern "C" { + +__attribute__((section(".external_app.app_wardrivemap.application_information"), used)) application_information_t _application_information_wardrivemap = { + /*.memory_location = */ (uint8_t*)0x00000000, + /*.externalAppEntry = */ ui::external_app::wardrivemap::initialize_app, + /*.header_version = */ CURRENT_HEADER_VERSION, + /*.app_version = */ VERSION_MD5, + + /*.app_name = */ "WardriveMap", + /*.bitmap_data = */ { + 0x00, + 0x00, + 0x00, + 0x00, + 0x04, + 0x20, + 0x12, + 0x48, + 0x8A, + 0x51, + 0xCA, + 0x53, + 0xCA, + 0x53, + 0x8A, + 0x51, + 0x12, + 0x48, + 0x84, + 0x21, + 0xC0, + 0x03, + 0x40, + 0x02, + 0x60, + 0x06, + 0x20, + 0x04, + 0x30, + 0x0C, + 0xF0, + 0x0F, + }, + /*.icon_color = */ ui::Color::yellow().v, + /*.menu_location = */ app_location_t::UTILITIES, + + /*.m4_app_tag = portapack::spi_flash::image_tag_none */ {0, 0, 0, 0}, + /*.m4_app_offset = */ 0x00000000, // will be filled at compile time +}; +} diff --git a/firmware/application/external/wardrivemap/ui_wardrivemap.cpp b/firmware/application/external/wardrivemap/ui_wardrivemap.cpp new file mode 100644 index 00000000..39052b3d --- /dev/null +++ b/firmware/application/external/wardrivemap/ui_wardrivemap.cpp @@ -0,0 +1,143 @@ +/* + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "ui_wardrivemap.hpp" + +#include "rtc_time.hpp" +#include "string_format.hpp" +#include "file_path.hpp" +#include "metadata_file.hpp" +#include "portapack_persistent_memory.hpp" + +using namespace portapack; +using namespace ui; + +namespace ui::external_app::wardrivemap { + +void WardriveMapView::focus() { + geopos.focus(); +} + +// needs to load on every map change, because won't store or draw all while marker is not in the current view. +// todo optimize this somehow +bool WardriveMapView::load_markers() { + uint16_t cnt = 0; + uint16_t displayed_cnt = 0; + geomap.clear_markers(); + // serach for files with geotag, and add it to geomap as marker with tag. limit to N bc of mem limit. + for (const auto& entry : std::filesystem::directory_iterator(captures_dir, u"*.txt")) { + if (std::filesystem::is_regular_file(entry.status())) { + if (displayed_cnt > 30) break; + std::filesystem::path pth = captures_dir; + pth += u"/" + entry.path(); + auto metadata_path = get_metadata_path(pth); + auto metadata = read_metadata_file(metadata_path); + + if (metadata) { + if (metadata.value().latitude != 0 && metadata.value().longitude != 0 && metadata.value().latitude < 400 && metadata.value().longitude < 400) { + if (first_init == false) { + // move map there before add, so will display this. + geopos.set_report_change(false); + geopos.set_lat(metadata.value().latitude); + geopos.set_lon(metadata.value().longitude); + geopos.set_report_change(true); + geomap.move(metadata.value().longitude, metadata.value().latitude); + first_init = true; + } + GeoMarker tmp{metadata.value().latitude, metadata.value().longitude, 400, entry.path().filename().string()}; + if (geomap.store_marker(tmp) == MapMarkerStored::MARKER_STORED) displayed_cnt++; + cnt++; + } + } + } + } + return (cnt > 0); +} + +WardriveMapView::WardriveMapView(NavigationView& nav) + : nav_{nav} { + add_children({&text_info, + &geomap, + &geopos, + &text_notfound}); + + geomap.set_mode(DISPLAY); + geomap.set_manual_panning(false); + geomap.set_focusable(true); + geomap.set_hide_center_marker(true); + geomap.clear_markers(); + + geopos.set_report_change(false); + geopos.set_lat(0); + geopos.set_lon(0); + geopos.set_altitude(0); + geopos.set_speed(0); + geopos.set_read_only(true); + geopos.hide_altandspeed(); + geopos.set_report_change(true); + + geopos.on_change = [this](int32_t altitude, float lat, float lon, int32_t speed) { + (void)altitude; + (void)speed; + geomap.set_manual_panning(true); + geomap.move(lon, lat); + load_markers(); + geomap.set_dirty(); + }; + text_notfound.hidden(true); + geomap.init(); + // load markers + if (load_markers()) { + text_notfound.hidden(true); + geomap.set_dirty(); + } else { + geomap.hidden(true); + geopos.hidden(true); + } + geomap.on_move = [this](float lon, float lat) { + (void)lon; + (void)lat; + load_markers(); + }; +} + +WardriveMapView::~WardriveMapView() { +} + +void WardriveMapView::on_gps(const GPSPosDataMessage* msg) { + geomap.update_my_position(msg->lat, msg->lon, msg->altitude); + if (geomap.manual_panning() == false) { + geopos.set_report_change(false); + geopos.set_lat(msg->lat); + geopos.set_lon(msg->lon); + geopos.set_altitude(msg->altitude); + geopos.set_speed(msg->speed); + geopos.set_report_change(true); + geomap.move(msg->lon, msg->lat); + load_markers(); + } + geomap.set_dirty(); +} + +void WardriveMapView::on_orientation(const OrientationDataMessage* msg) { + geomap.set_angle(msg->angle); + geomap.update_my_orientation(msg->angle, true); +} + +} // namespace ui::external_app::wardrivemap \ No newline at end of file diff --git a/firmware/application/external/wardrivemap/ui_wardrivemap.hpp b/firmware/application/external/wardrivemap/ui_wardrivemap.hpp new file mode 100644 index 00000000..8ec9f570 --- /dev/null +++ b/firmware/application/external/wardrivemap/ui_wardrivemap.hpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2017 Furrtek + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// Code from https://github.com/Flipper-XFW/Xtreme-Apps/tree/04c3a60093e2c2378e79498b4505aa8072980a42/ble_spam/protocols +// Thanks for the work of the original creators! +// Saying thanks in the main view! + +#ifndef __UI_WARDRIVEMAP_H__ +#define __UI_WARDRIVEMAP_H__ + +#include "ui.hpp" +#include "ui_language.hpp" +#include "ui_navigation.hpp" +#include "ui_geomap.hpp" +#include "app_settings.hpp" +#include "utility.hpp" + +using namespace ui; + +namespace ui::external_app::wardrivemap { + +class WardriveMapView : public View { + public: + WardriveMapView(NavigationView& nav); + ~WardriveMapView(); + + void focus() override; + + std::string title() const override { + return "WardriveMap"; + }; + + private: + NavigationView& nav_; + + Text text_info{{0 * 8, 0 * 8, 30 * 8, 16 * 1}, "All GEOTAG from CAPTURES"}; + Text text_notfound{{0 * 8, 3 * 8, 30 * 8, 16 * 1}, "No GeoTagged captures found"}; + GeoPos geopos{ + {0, 20}, + GeoPos::alt_unit::METERS, + GeoPos::spd_unit::HIDDEN}; + GeoMap geomap{{0, 75, 240, 320 - 75}}; + + void on_gps(const GPSPosDataMessage* msg); + void on_orientation(const OrientationDataMessage* msg); + + bool load_markers(); // returns true if any exists, false if none. + + bool first_init = false; + + MessageHandlerRegistration message_handler_gps{ + Message::ID::GPSPosData, + [this](Message* const p) { + const auto message = static_cast(p); + this->on_gps(message); + }}; + MessageHandlerRegistration message_handler_orientation{ + Message::ID::OrientationData, + [this](Message* const p) { + const auto message = static_cast(p); + this->on_orientation(message); + }}; +}; +}; // namespace ui::external_app::wardrivemap + +#endif /*__UI_WARDRIVEMAP_H__*/