diff --git a/firmware/application/ui_jammer.cpp b/firmware/application/ui_jammer.cpp index 68267ad3a..23db90cd4 100644 --- a/firmware/application/ui_jammer.cpp +++ b/firmware/application/ui_jammer.cpp @@ -47,53 +47,55 @@ JammerView::~JammerView() { baseband::shutdown(); } -void JammerView::update_text(uint8_t id, rf::Frequency f) { - char finalstr[25] = {0}; - rf::Frequency center; - std::string bw; - uint8_t c; - - /* - auto mhz = to_string_dec_int(f / 1000000, 3); - auto hz100 = to_string_dec_int((f / 100) % 10000, 4, '0'); - - strcat(finalstr, mhz.c_str()); - strcat(finalstr, "."); - strcat(finalstr, hz100.c_str()); - strcat(finalstr, "M"); - - while (strlen(finalstr) < 10) - strcat(finalstr, " "); - - buttons_freq[id].set_text(finalstr); - */ +void JammerView::update_range(const uint32_t n) { + std::string label; + jammer_range_t * range_ptr; + rf::Frequency center, bw_khz; - for (c = 0; c < 3; c++) { - center = (frequency_range[c].min + frequency_range[c].max) / 2; - bw = to_string_dec_int(abs(frequency_range[c].max - frequency_range[c].min) / 1000, 5); - - auto center_mhz = to_string_dec_int(center / 1000000, 4); - auto center_hz100 = to_string_dec_int((center / 100) % 10000, 4, '0'); + range_ptr = &frequency_range[n]; + + center = (range_ptr->min + range_ptr->max) / 2; + bw_khz = abs(range_ptr->max - range_ptr->min) / 1000; + + auto center_mhz = to_string_dec_int(center / 1000000, 4); + auto center_hz100 = to_string_dec_int((center / 1000) % 1000, 3, '0'); - strcpy(finalstr, "C:"); - strcat(finalstr, center_mhz.c_str()); - strcat(finalstr, "."); - strcat(finalstr, center_hz100.c_str()); - strcat(finalstr, "M W:"); - strcat(finalstr, bw.c_str()); - strcat(finalstr, "kHz"); - - while (strlen(finalstr) < 23) - strcat(finalstr, " "); - - texts_info[c].set(finalstr); + label = "C:" + center_mhz + "." + center_hz100 + "M W:"; + + if (bw_khz < 1000) { + label += to_string_dec_int(bw_khz, 3) + "kHz"; + } else { + bw_khz /= 1000; + label += to_string_dec_int(bw_khz, 3) + "MHz"; } + + while (label.length() < 23) + label += " "; + + texts_info[n].set(label); +} + +void JammerView::update_button(const uint32_t n) { + std::string label; + rf::Frequency f; + + if (n & 1) + f = frequency_range[n / 2].max; + else + f = frequency_range[n / 2].min; + + auto f_mhz = to_string_dec_int(f / 1000000, 4); + auto f_hz100 = to_string_dec_int((f / 1000) % 1000, 3, '0'); + + label = f_mhz + "." + f_hz100 + "M"; + + buttons_freq[n].set_text(label); } void JammerView::on_retune(const rf::Frequency freq, const uint32_t range) { if (freq) { transmitter_model.set_tuning_frequency(freq); - text_range_number.set(to_string_dec_uint(range, 2, ' ')); + text_range_number.set(to_string_dec_uint(range, 1)); } } @@ -124,10 +126,11 @@ JammerView::JammerView(NavigationView& nav) { add_children({ &text_type, + &options_type, &text_range_number, - &options_modulation, - &text_sweep, - &options_sweep, + &text_range_total, + &text_speed, + &options_speed, &text_preset, &options_preset, &text_hop, @@ -159,11 +162,10 @@ JammerView::JammerView(NavigationView& nav) { button.on_select = button_freq_fn; button.set_parent_rect({ static_cast(13 * 8), - static_cast(((n >> 1) * 52) + 90 + (18 * (n & 1))), - 88, 18 + static_cast(76 + ((n >> 1) * 58) + (20 * (n & 1))), + 96, 20 }); button.id = n; - button.set_text("----.----M"); add_child(&button); n++; } @@ -173,7 +175,7 @@ JammerView::JammerView(NavigationView& nav) { checkbox.on_select = checkbox_fn; checkbox.set_parent_rect({ static_cast(8), - static_cast(96 + (n * 52)), + static_cast(86 + (n * 58)), 24, 24 }); checkbox.id = n; @@ -186,102 +188,105 @@ JammerView::JammerView(NavigationView& nav) { for (auto& text : texts_info) { text.set_parent_rect({ static_cast(3 * 8), - static_cast(126 + (n * 52)), + static_cast(116 + (n * 58)), 25 * 8, 16 }); - text.set("C:----.----M W:-----kHz"); text.set_style(&style_info); add_child(&text); n++; } - button_transmit.set_style(&style_val); - options_hop.set_selected_index(1); - options_preset.on_change = [this](size_t, OptionsField::value_t v) { - for (uint32_t c = 0; c < 3; c++) { - frequency_range[c].min = range_presets[v][c].min; - frequency_range[c].max = range_presets[v][c].max; - checkboxes[c].set_value(range_presets[v][c].enabled); + const jammer_range_t * preset_ptr; + uint32_t c; + + for (c = 0; c < 3; c++) { + preset_ptr = &range_presets[v][c]; + + frequency_range[c].min = preset_ptr->min; + frequency_range[c].max = preset_ptr->max; + checkboxes[c].set_value(preset_ptr->enabled); + update_button(c * 2); + update_button(c * 2 + 1); + update_range(c); } - update_text(0, 0); }; - options_preset.set_selected_index(9); // GPS + options_type.set_selected_index(1); // Noise + options_speed.set_selected_index(2); // 10kHz + options_preset.set_selected_index(8); // ISM 868 + options_hop.set_selected_index(1); // 50ms + button_transmit.set_style(&style_val); button_transmit.on_select = [this, &nav, jammer_channels](Button&) { - uint8_t c, i = 0; + uint32_t c, i = 0; size_t num_channels; rf::Frequency start_freq, range_bw, range_bw_sub, ch_width; bool out_of_ranges = false; - // Disable all ranges by default - for (c = 0; c < 9; c++) - jammer_channels[c].enabled = false; - - // Generate jamming "channels", maximum: 9 - // Convert ranges min/max to center/bw - for (size_t r = 0; r < 3; r++) { + if (jamming) { + button_transmit.set_style(&style_val); + button_transmit.set_text("START"); + transmitter_model.disable(); + radio::disable(); + baseband::set_jammer(false); + jamming = false; + } else { - if (frequency_range[r].enabled) { - range_bw = abs(frequency_range[r].max - frequency_range[r].min); + // Disable all ranges by default + for (c = 0; c < 9; c++) + jammer_channels[c].enabled = false; + + // Generate jamming "channels", maximum: 9 + // Convert ranges min/max to center/bw + for (size_t r = 0; r < 3; r++) { - // Sort - if (frequency_range[r].min < frequency_range[r].max) - start_freq = frequency_range[r].min; - else - start_freq = frequency_range[r].max; - - if (range_bw >= JAMMER_CH_WIDTH) { - // Example: 600kHz - // int(600000 / 500000) = 2 - // CH-BW = 600000 / 2 = 300000 - // Center-A = min + CH-BW / 2 = 150000 - // BW-A = CH-BW = 300000 - // Center-B = min + CH-BW + Center-A = 450000 - // BW-B = CH-BW = 300000 - num_channels = 0; - range_bw_sub = range_bw; - do { - range_bw_sub -= JAMMER_CH_WIDTH; - num_channels++; - } while (range_bw_sub >= JAMMER_CH_WIDTH); - ch_width = range_bw / num_channels; - for (c = 0; c < num_channels; c++) { + if (frequency_range[r].enabled) { + range_bw = abs(frequency_range[r].max - frequency_range[r].min); + + // Sort + if (frequency_range[r].min < frequency_range[r].max) + start_freq = frequency_range[r].min; + else + start_freq = frequency_range[r].max; + + if (range_bw >= JAMMER_CH_WIDTH) { + num_channels = 0; + range_bw_sub = range_bw; + do { + range_bw_sub -= JAMMER_CH_WIDTH; + num_channels++; + } while (range_bw_sub >= JAMMER_CH_WIDTH); + ch_width = range_bw / num_channels; + for (c = 0; c < num_channels; c++) { + if (i >= 9) { + out_of_ranges = true; + break; + } + jammer_channels[i].enabled = true; + jammer_channels[i].width = ch_width; + jammer_channels[i].center = start_freq + (ch_width / 2) + (ch_width * c); + jammer_channels[i].duration = 15360 * options_hop.selected_index_value(); + i++; + } + } else { if (i >= 9) { out_of_ranges = true; - break; + } else { + jammer_channels[i].enabled = true; + jammer_channels[i].width = range_bw; + jammer_channels[i].center = start_freq + (range_bw / 2); + jammer_channels[i].duration = 15360 * options_hop.selected_index_value(); + i++; } - jammer_channels[i].enabled = true; - jammer_channels[i].width = ch_width; - jammer_channels[i].center = start_freq + (ch_width / 2) + (ch_width * c); - jammer_channels[i].duration = 15360 * options_hop.selected_index_value(); - i++; - } - } else { - if (i >= 9) { - out_of_ranges = true; - } else { - jammer_channels[i].enabled = true; - jammer_channels[i].width = range_bw; - jammer_channels[i].center = start_freq + (range_bw / 2); - jammer_channels[i].duration = 15360 * options_hop.selected_index_value(); - i++; } } } - } - - if (!out_of_ranges) { - if (jamming == true) { - jamming = false; - button_transmit.set_style(&style_val); - button_transmit.set_text("START"); - transmitter_model.disable(); - radio::disable(); - baseband::set_jammer(false); - } else { + + if (!out_of_ranges) { + text_range_total.set("/" + to_string_dec_uint(i, 1)); + jamming = true; button_transmit.set_style(&style_cancel); button_transmit.set_text("STOP"); @@ -293,9 +298,9 @@ JammerView::JammerView(NavigationView& nav) { transmitter_model.enable(); baseband::set_jammer(true); + } else { + nav.display_modal("Error", "Jamming bandwidth too large."); } - } else { - nav.display_modal("Error", "Jamming bandwidth too large."); } }; diff --git a/firmware/application/ui_jammer.hpp b/firmware/application/ui_jammer.hpp index 3697d378d..99bcb49e2 100644 --- a/firmware/application/ui_jammer.hpp +++ b/firmware/application/ui_jammer.hpp @@ -39,45 +39,43 @@ public: std::string title() const override { return "Jammer"; }; private: - // range_t from utility.hpp is const only - typedef struct freq_range { + typedef struct jammer_range { bool enabled; rf::Frequency min; rf::Frequency max; - } freq_range_t; + } jammer_range_t; - freq_range_t frequency_range[3]; + jammer_range_t frequency_range[3]; - void update_text(uint8_t id, rf::Frequency f); + void update_range(const uint32_t n); + void update_button(const uint32_t n); void on_retune(const rf::Frequency freq, const uint32_t range); - - // TODO: TDD UMTS, voir doc Arcep - // TODO: BT: 2 400 et 2 483,5 MHz - const freq_range_t range_presets[23][3] = { + + const jammer_range_t range_presets[23][3] = { // Orange - {{ true, 935000000, 945000000 }, // GSM 900 - { true, 1808000000, 1832000000 }, // GSM 1800 - { true, 2154900000, 2169700000 }}, // UMTS + {{ true, 935000000, 945000000 }, // GSM 900 BW:10M + { false, 1808000000, 1832000000 }, // GSM 1800 BW:24M + { false, 0, 0 }}, // SFR - {{ true, 950000000, 960000000 }, // GSM 900 - { true, 1832000000, 1853000000 }, // GSM 1800 - { true, 2110500000, 2125300000 }}, // UMTS + {{ true, 950000000, 960000000 }, // GSM 900 BW:10M + { false, 1832000000, 1853000000 }, // GSM 1800 BW:21M + { false, 0, 0 }}, // Bouygues - {{ true, 925000000, 935000000 }, // GSM 900 - { true, 1858000000, 1880000000 }, // GSM 1800 - { true, 2125300000, 2140100000 }}, // UMTS + {{ true, 925000000, 935000000 }, // GSM 900 BW:10M + { false, 1858000000, 1880000000 }, // GSM 1800 BW:22M + { false, 0, 0 }}, // Free - {{ true, 945000000, 950000000 }, // GSM 900 - { false, 0, 0 }, // GSM 1800 ? - { true, 2144900000, 2149900000 }}, // UMTS + {{ true, 945000000, 950000000 }, // GSM 900 BW:5M + { false, 0, 0 }, + { true, 0, 0 }}, // GSM-R - {{ true, 921000000, 925000000 }, // GSM 900 - { false, 0, 0 }, // GSM 1800 - { false, 0, 0 }}, // UMTS + {{ true, 921000000, 925000000 }, // GSM 900 BW:4M + { false, 0, 0 }, + { false, 0, 0 }}, // DECT {{ true, 1880000000, 1900000000 }, // BW: 20MHz @@ -160,71 +158,52 @@ private: }; bool jamming = false; - rf::Frequency f; Text text_type { - { 1 * 8, 1 * 16, 40, 16 }, + { 3 * 8, 4, 5 * 8, 16 }, "Type:" }; - OptionsField options_modulation { - { 7 * 8, 1 * 16 }, - 4, + OptionsField options_type { + { 9 * 8, 4 }, + 5, { { "Ramp ", 0 }, - { "FM ", 1 }, - { "Phase", 2 }, - { "Tones", 3 } + { "Noise", 1 }, + { "Tones", 2 } } }; Text text_range_number { - { 14 * 8, 1 * 16, 2 * 8, 16 }, - "--" + { 18 * 8, 4, 1 * 8, 16 }, + "-" + }; + Text text_range_total { + { 19 * 8, 4, 2 * 8, 16 }, + "/-" }; - Text text_sweep { - { 1 * 8, 2 * 16, 6 * 8, 16 }, - "Sweep:" + Text text_speed { + { 2 * 8, 20, 6 * 8, 16 }, + "Speed:" }; - OptionsField options_sweep { - { 8 * 8, 2 * 16 }, - 8, + OptionsField options_speed { + { 9 * 8, 20 }, + 6, { - { " 1Hz", 0 }, - { " 10Hz", 1 }, - { "100Hz", 2 }, - { " 1kHz", 3 }, - { " 5kHz", 4 }, - { "10kHz", 5 }, - { "20kHz", 6 }, - { "50kHz", 7 } - } - }; - - Text text_hop { - { 1 * 8, 4 * 16, 10 * 8, 16 }, - "Range hop:" - }; - OptionsField options_hop { - { 12 * 8, 4 * 16 }, - 5, - { - { " 10ms", 1 }, - { " 50ms", 5 }, - { "100ms", 10 }, - { " 1s", 100 }, - { " 2s", 200 }, - { " 5s", 500 }, - { " 10s", 1000 } + { "10Hz ", 0 }, + { "100Hz ", 1 }, + { "1kHz ", 2 }, + { "10kHz ", 3 }, + { "100kHz", 4 } } }; Text text_preset { - { 1 * 8, 3 * 16, 8 * 8, 16 }, - "Presets:" + { 1 * 8, 36, 7 * 8, 16 }, + "Preset:" }; OptionsField options_preset { - { 10 * 8, 3 * 16 }, + { 9 * 8, 36 }, 16, { { "GSM Orange FR ", 0 }, @@ -252,18 +231,36 @@ private: { "WLAN 2.4G CH13 ", 22 } } }; + + Text text_hop { + { 5 * 8, 52, 10 * 8, 16 }, + "Hop:" + }; + OptionsField options_hop { + { 9 * 8, 52 }, + 5, + { + { "10ms ", 1 }, + { "50ms ", 5 }, + { "100ms", 10 }, + { "1s ", 100 }, + { "2s ", 200 }, + { "5s ", 500 }, + { "10s ", 1000 } + } + }; std::array checkboxes { }; std::array buttons_freq { }; std::array texts_info { }; Button button_transmit { - { 2 * 8, 16 * 16, 64, 32 }, + { 1 * 8, 16 * 16, 80, 48 }, "START" }; Button button_exit { - { 21 * 8, 16 * 16, 64, 32 }, + { 19 * 8, 16 * 16, 80, 48 }, "Exit" }; diff --git a/firmware/baseband/hackrf.img b/firmware/baseband/hackrf.img new file mode 100644 index 000000000..7b17e2671 Binary files /dev/null and b/firmware/baseband/hackrf.img differ diff --git a/firmware/baseband/terminator.img b/firmware/baseband/terminator.img new file mode 100644 index 000000000..1b1cb4d44 Binary files /dev/null and b/firmware/baseband/terminator.img differ diff --git a/firmware/bootstrap/bootstrap.bin b/firmware/bootstrap/bootstrap.bin new file mode 100755 index 000000000..784058649 Binary files /dev/null and b/firmware/bootstrap/bootstrap.bin differ diff --git a/firmware/portapack-h1-havoc.bin b/firmware/portapack-h1-havoc.bin index bbd084594..75a770acf 100644 Binary files a/firmware/portapack-h1-havoc.bin and b/firmware/portapack-h1-havoc.bin differ