diff --git a/firmware/application/apps/ui_freqman.cpp b/firmware/application/apps/ui_freqman.cpp index 96416b68..65c8a730 100644 --- a/firmware/application/apps/ui_freqman.cpp +++ b/firmware/application/apps/ui_freqman.cpp @@ -95,6 +95,9 @@ void FreqManBaseView::change_category(int32_t category_id) { last_category_id = current_category_id = category_id; + std::vector().swap(database); + menu_view.set_db(database); + if (!load_freqman_file(file_list[categories[current_category_id].second], database)) error_ = ERROR_ACCESS; else { diff --git a/firmware/application/apps/ui_recon.cpp b/firmware/application/apps/ui_recon.cpp index 7decb8bf..26dd5ffd 100644 --- a/firmware/application/apps/ui_recon.cpp +++ b/firmware/application/apps/ui_recon.cpp @@ -930,7 +930,7 @@ void ReconView::frequency_file_load(bool stop_all_before) { button_scanner_mode.set_text("RECON"); } desc_cycle.set_style(&style_white); - if (!load_freqman_file_ex(file_input, frequency_list, load_freqs, load_ranges, load_hamradios)) { + if (!load_freqman_file_ex(file_input, frequency_list, load_freqs, load_ranges, load_hamradios, RECON_FREQMAN_MAX_PER_FILE)) { file_name.set_style(&style_red); desc_cycle.set_style(&style_red); desc_cycle.set(" NO " + file_input + ".TXT FILE ..."); @@ -943,7 +943,7 @@ void ReconView::frequency_file_load(bool stop_all_before) { desc_cycle.set("/0 no entries in list"); file_name.set("BadOrEmpty " + file_input); } else { - if (frequency_list.size() > FREQMAN_MAX_PER_FILE) { + if (frequency_list.size() > RECON_FREQMAN_MAX_PER_FILE) { file_name.set_style(&style_yellow); desc_cycle.set_style(&style_yellow); } diff --git a/firmware/application/apps/ui_recon.hpp b/firmware/application/apps/ui_recon.hpp index 13c40be8..b626f1ad 100644 --- a/firmware/application/apps/ui_recon.hpp +++ b/firmware/application/apps/ui_recon.hpp @@ -44,6 +44,7 @@ namespace ui { #define RECON_CFG_FILE "SETTINGS/recon.cfg" +#define RECON_FREQMAN_MAX_PER_FILE 99 // maximum tested limit for load frequency from freqman to work class ReconView : public View { public: diff --git a/firmware/application/freqman.cpp b/firmware/application/freqman.cpp index 82ce324d..0c75a27f 100644 --- a/firmware/application/freqman.cpp +++ b/firmware/application/freqman.cpp @@ -103,10 +103,13 @@ std::vector get_freqman_files() { }; bool load_freqman_file(std::string& file_stem, freqman_db& db) { - return load_freqman_file_ex(file_stem, db, true, true, true); + return load_freqman_file_ex(file_stem, db, true, true, true, FREQMAN_MAX_PER_FILE); } -bool load_freqman_file_ex(std::string& file_stem, freqman_db& db, bool load_freqs, bool load_ranges, bool load_hamradios) { +bool load_freqman_file_ex(std::string& file_stem, freqman_db& db, bool load_freqs, bool load_ranges, bool load_hamradios, uint8_t max_num_freqs = FREQMAN_MAX_PER_FILE) { + // swap with empty vector to ensure memory is immediately released + std::vector().swap(db); + File freqman_file; size_t length, n = 0, file_position = 0; char* pos; @@ -114,40 +117,33 @@ bool load_freqman_file_ex(std::string& file_stem, freqman_db& db, bool load_freq char* line_end; std::string description; rf::Frequency frequency_a, frequency_b; - const int read_buf_size = 128; - char file_data[read_buf_size + 1]; + char file_data[FREQMAN_READ_BUF_SIZE + 1]; freqman_entry_type type; freqman_index_t modulation = 0; freqman_index_t bandwidth = 0; freqman_index_t step = 0; freqman_index_t tone = 0; - // these are not enough to really start with a new, clean, empty vector - // swap is the only way to achieve a perfect memory liberation - // db.clear(); - // db.shrink_to_fit(): - std::vector().swap(db); - auto result = freqman_file.open("FREQMAN/" + file_stem + ".TXT"); if (result.is_valid()) return false; while (1) { - // Read a read_buf_size bytes block from file + // Read a FREQMAN_READ_BUF_SIZE block from file freqman_file.seek(file_position); - memset(file_data, 0, read_buf_size + 1); - auto read_size = freqman_file.read(file_data, read_buf_size); + memset(file_data, 0, FREQMAN_READ_BUF_SIZE + 1); + auto read_size = freqman_file.read(file_data, FREQMAN_READ_BUF_SIZE); if (read_size.is_error()) return false; // Read error - file_position += read_buf_size; + file_position += FREQMAN_READ_BUF_SIZE; // Reset line_start to beginning of buffer line_start = file_data; // If EOF reached, insert 0x0A after, in case the last line doesn't have a C/R - if (read_size.value() < read_buf_size) + if (read_size.value() < FREQMAN_READ_BUF_SIZE) *(line_start + read_size.value()) = 0x0A; // Look for complete lines in buffer @@ -231,18 +227,18 @@ bool load_freqman_file_ex(std::string& file_stem, freqman_db& db, bool load_freq if ((type == SINGLE && load_freqs) || (type == RANGE && load_ranges) || (type == HAMRADIO && load_hamradios)) { db.push_back({frequency_a, frequency_b, description, type, modulation, bandwidth, step, tone}); n++; - if (n > FREQMAN_MAX_PER_FILE) return true; + if (n > max_num_freqs) return true; } line_start = line_end + 1; - if (line_start - file_data >= read_buf_size) break; + if (line_start - file_data >= FREQMAN_READ_BUF_SIZE) break; } - if (read_size.value() != read_buf_size) + if (read_size.value() != FREQMAN_READ_BUF_SIZE) break; // End of file // Restart at beginning of last incomplete line - file_position -= (file_data + read_buf_size - line_start); + file_position -= (file_data + FREQMAN_READ_BUF_SIZE - line_start); } /* populate implicitly specified modulation / bandwidth */ diff --git a/firmware/application/freqman.hpp b/firmware/application/freqman.hpp index 0d93acde..8f07ae6a 100644 --- a/firmware/application/freqman.hpp +++ b/firmware/application/freqman.hpp @@ -36,6 +36,7 @@ #define FREQMAN_MAX_PER_FILE 60 // Maximum of entries we can read. This is a hardware limit // It was tested and lowered to leave a bit of space to the caller #define FREQMAN_MAX_PER_FILE_STR "60" // STRING OF FREQMAN_MAX_PER_FILE +#define FREQMAN_READ_BUF_SIZE 96 // max freqman line size including desc is 90, +6 for a bit of space using namespace ui; using namespace std; @@ -96,7 +97,7 @@ using freqman_db = std::vector; std::vector get_freqman_files(); bool load_freqman_file(std::string& file_stem, freqman_db& db); -bool load_freqman_file_ex(std::string& file_stem, freqman_db& db, bool load_freqs, bool load_ranges, bool load_hamradios); +bool load_freqman_file_ex(std::string& file_stem, freqman_db& db, bool load_freqs, bool load_ranges, bool load_hamradios, uint8_t limit); bool get_freq_string(freqman_entry& entry, std::string& item_string); bool save_freqman_file(std::string& file_stem, freqman_db& db); bool create_freqman_file(std::string& file_stem, File& freqman_file);