portapack-mayhem/firmware/application/external/jammer/ui_jammer.hpp
RocketGod 43a1bc0445
Jammer app add modes (#2659)
* Add new jammer modes

Overview

This PR enhances the PortaPack Jammer app by introducing eight new signal types, ported from my Flipper Zero RF Jammer app (https://github.com/RocketGod-git/flipper-zero-rf-jammer). These modes expand the app's capability to disrupt a wide range of RF communication protocols, from analog radios to modern digital systems. The implementation preserves the original app structure, resolves namespace conflicts, and ensures compatibility with the Mayhem firmware.

New Modes

The following modes have been added to the options_type in ui_jammer.hpp, with corresponding signal generation in proc_jammer.cpp:

Noise: Generates broadband white noise to interfere with analog and digital signals (e.g., Wi-Fi, Bluetooth, key fobs). Highly effective for overwhelming receivers across a frequency range.

Sine: Produces a continuous, unmodulated sine wave to jam narrowband receivers, ideal for analog FM/AM radios or telemetry systems.

Square: Emits a harmonic-rich square wave, disrupting digital protocols (e.g., OOK, ASK) and systems sensitive to sharp transitions, such as remote keyless entry.

Sawtooth (Experimental): Generates a sawtooth wave with a unique harmonic profile, useful for testing interference against PWM-based or niche analog systems.

Triangle (Experimental): Creates a triangle wave with minimal harmonics, suitable for exploratory jamming of narrowband systems or receiver linearity testing.

Chirp: Outputs a rapid frequency-sweeping chirp signal, effective against frequency-hopping and spread-spectrum systems (e.g., some Wi-Fi, Bluetooth, or military radios).

Gauss: Generates Gaussian noise to mimic natural interference, targeting digital systems like GPS or data links by degrading signal-to-noise ratios.

Brute (Experimental): Transmits a constant maximum-amplitude signal to saturate simple receiver front-ends, useful for brute-force jamming of basic analog devices.

* Add new jammer modes

Overview

This PR enhances the PortaPack Jammer app by introducing eight new signal types, ported from my Flipper Zero RF Jammer app (https://github.com/RocketGod-git/flipper-zero-rf-jammer). These modes expand the app's capability to disrupt a wide range of RF communication protocols, from analog radios to modern digital systems. The implementation preserves the original app structure, resolves namespace conflicts, and ensures compatibility with the Mayhem firmware.

New Modes

The following modes have been added to the options_type in ui_jammer.hpp, with corresponding signal generation in proc_jammer.cpp:

Noise: Generates broadband white noise to interfere with analog and digital signals (e.g., Wi-Fi, Bluetooth, key fobs). Highly effective for overwhelming receivers across a frequency range.

Sine: Produces a continuous, unmodulated sine wave to jam narrowband receivers, ideal for analog FM/AM radios or telemetry systems.

Square: Emits a harmonic-rich square wave, disrupting digital protocols (e.g., OOK, ASK) and systems sensitive to sharp transitions, such as remote keyless entry.

Sawtooth (Experimental): Generates a sawtooth wave with a unique harmonic profile, useful for testing interference against PWM-based or niche analog systems.

Triangle (Experimental): Creates a triangle wave with minimal harmonics, suitable for exploratory jamming of narrowband systems or receiver linearity testing.

Chirp: Outputs a rapid frequency-sweeping chirp signal, effective against frequency-hopping and spread-spectrum systems (e.g., some Wi-Fi, Bluetooth, or military radios).

Gauss: Generates Gaussian noise to mimic natural interference, targeting digital systems like GPS or data links by degrading signal-to-noise ratios.

Brute (Experimental): Transmits a constant maximum-amplitude signal to saturate simple receiver front-ends, useful for brute-force jamming of basic analog devices.
2025-05-19 19:16:28 +02:00

251 lines
7.5 KiB
C++

/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
* Copyright (C) 2025 RocketGod - Added modes from my Flipper Zero RF Jammer App - https://betaskynet.com
*
* 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_language.hpp"
#include "ui_widget.hpp"
#include "ui_navigation.hpp"
#include "ui_tabview.hpp"
#include "transmitter_model.hpp"
#include "message.hpp"
#include "jammer.hpp"
#include "lfsr_random.hpp"
#include "radio_state.hpp"
using namespace jammer;
namespace ui::external_app::jammer {
class RangeView : public View {
public:
RangeView(NavigationView& nav);
void focus() override;
void paint(Painter&) override;
jammer_range_t frequency_range{false, 0, 0};
private:
void update_start(rf::Frequency f);
void update_stop(rf::Frequency f);
void update_center(rf::Frequency f);
void update_width(uint32_t w);
uint32_t width{};
rf::Frequency center{};
const Style& style_info = *Theme::getInstance()->fg_medium;
Labels labels{
{{2 * 8, 8 * 8 + 4}, LanguageHelper::currentMessages[LANG_START], Theme::getInstance()->fg_light->foreground},
{{23 * 8, 8 * 8 + 4}, LanguageHelper::currentMessages[LANG_STOP], Theme::getInstance()->fg_light->foreground},
{{12 * 8, 5 * 8 - 4}, "Center", Theme::getInstance()->fg_light->foreground},
{{12 * 8 + 4, 13 * 8}, "Width", Theme::getInstance()->fg_light->foreground}};
Checkbox check_enabled{
{1 * 8, 4},
12,
"Enable range"};
Button button_load_range{
{18 * 8, 4, 12 * 8, 24},
"Load range"};
Button button_start{
{0 * 8, 11 * 8, 11 * 8, 28},
""};
Button button_stop{
{19 * 8, 11 * 8, 11 * 8, 28},
""};
Button button_center{
{76, 4 * 15 - 4, 11 * 8, 28},
""};
Button button_width{
{76, 8 * 15, 11 * 8, 28},
""};
};
class JammerView : public View {
public:
JammerView(NavigationView& nav);
~JammerView();
JammerView(const JammerView&) = delete;
JammerView(JammerView&&) = delete;
JammerView& operator=(const JammerView&) = delete;
JammerView& operator=(JammerView&&) = delete;
void focus() override;
std::string title() const override { return "Jammer TX"; };
private:
NavigationView& nav_;
TxRadioState radio_state_{
0 /* frequency */,
3500000 /* bandwidth */,
3072000 /* sampling rate */
};
void start_tx();
void on_timer();
void stop_tx();
void set_jammer_channel(uint32_t i, uint32_t width, uint64_t center, uint32_t duration);
void on_retune(const rf::Frequency freq, const uint32_t range);
JammerChannel* jammer_channels = (JammerChannel*)shared_memory.bb_data.data;
bool jamming{false};
bool cooling{false}; // euquiq: Indicates jammer in cooldown
uint16_t seconds = 0; // euquiq: seconds counter for toggling tx / cooldown
int16_t mscounter = 0; // euquiq: Internal ms counter for do_timer()
lfsr_word_t lfsr_v = 1; // euquiq: Used to generate "random" Jitter
const Style& style_val = *Theme::getInstance()->fg_green;
const Style& style_cancel = *Theme::getInstance()->fg_red;
RangeView view_range_a{nav_};
RangeView view_range_b{nav_};
RangeView view_range_c{nav_};
std::array<RangeView*, 3> range_views{{&view_range_a, &view_range_b, &view_range_c}};
TabView tab_view{
{"Range 1", Theme::getInstance()->bg_darkest->foreground, range_views[0]},
{"Range 2", Theme::getInstance()->bg_darkest->foreground, range_views[1]},
{"Range 3", Theme::getInstance()->bg_darkest->foreground, range_views[2]},
};
Labels labels{
{{2 * 8, 23 * 8}, "Type:", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 25 * 8}, "Speed:", Theme::getInstance()->fg_light->foreground},
{{3 * 8, 27 * 8}, "Hop:", Theme::getInstance()->fg_light->foreground},
{{4 * 8, 29 * 8}, "TX:", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 31 * 8}, "Sle3p:", Theme::getInstance()->fg_light->foreground}, // euquiq: Token of appreciation to TheSle3p, which made this ehnancement a reality with his bounty.
{{0 * 8, 33 * 8}, "Jitter:", Theme::getInstance()->fg_light->foreground}, // Maybe the repository curator can keep the "mystype" for some versions.
{{11 * 8, 29 * 8}, "Secs.", Theme::getInstance()->fg_light->foreground},
{{11 * 8, 31 * 8}, "Secs.", Theme::getInstance()->fg_light->foreground},
{{11 * 8, 33 * 8}, "/60", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 35 * 8}, "Gain:", Theme::getInstance()->fg_light->foreground},
{{11 * 8, 35 * 8}, "A:", Theme::getInstance()->fg_light->foreground}};
OptionsField options_type{
{7 * 8, 23 * 8},
8,
{{"Rand FSK", 0},
{"FM tone", 1},
{"CW sweep", 2},
{"Noise", 3},
{"Sine", 4},
{"Square", 5},
{"Sawtooth", 6},
{"Triangle", 7},
{"Chirp", 8},
{"Gauss", 9},
{"Brute", 10}}};
Text text_range_number{
{16 * 8, 23 * 8, 2 * 8, 16},
"--"};
Text text_range_total{
{18 * 8, 23 * 8, 3 * 8, 16},
"/--"};
OptionsField options_speed{
{7 * 8, 25 * 8},
6,
{{"10Hz ", 10},
{"100Hz ", 100},
{"1kHz ", 1000},
{"10kHz ", 10000},
{"100kHz", 100000}}};
OptionsField options_hop{
{7 * 8, 27 * 8},
5,
{{"10ms ", 1},
{"50ms ", 5},
{"100ms", 10},
{"1s ", 100},
{"2s ", 200},
{"5s ", 500},
{"10s ", 1000}}};
NumberField field_timetx{
{7 * 8, 29 * 8},
3,
{1, 180},
1,
' ',
};
NumberField field_timepause{
{8 * 8, 31 * 8},
2,
{1, 60},
1,
' ',
};
NumberField field_jitter{
{8 * 8, 33 * 8},
2,
{1, 60},
1,
' ',
};
NumberField field_gain{
{8 * 8, 35 * 8},
2,
{0, 47},
1,
' ',
};
NumberField field_amp{
{13 * 8, 35 * 8},
1,
{0, 1},
1,
' ',
};
Button button_transmit{
{148, 216, 80, 80},
LanguageHelper::currentMessages[LANG_START]};
MessageHandlerRegistration message_handler_retune{
Message::ID::Retune,
[this](Message* const p) {
const auto message = static_cast<const RetuneMessage*>(p);
this->on_retune(message->freq, message->range);
}};
MessageHandlerRegistration message_handler_frame_sync{
Message::ID::DisplayFrameSync,
[this](const Message* const) {
this->on_timer();
}};
};
} // namespace ui::external_app::jammer