Compare commits

...

4 Commits

Author SHA1 Message Date
zix 6f6d863a14 refactor the serial log logic of BLE Rx (#2660) 2025-05-21 07:07:26 -07:00
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
OpenSourceSDRLab 0d02f431c7 Upload the PCB file of PortaPack H4 and update the schematic file (#2657)
* Create README.txt

* Update README.txt

* Add files via upload

The gerber files of the portapack h4.

* delete

* Upload the gerber files for H4

* Create README.txt

This is the V1.0 version PCB file of PortaPack H4.

* Upload the pcb file for H4

* Update README.txt

* Update LCD_TF_Schematic.pdf
2025-05-19 23:40:02 +12:00
Brumi-2021 322b06d670 Improve_RF_sensitivity_NOAA_signal (#2654) 2025-05-18 12:49:24 +02:00
14 changed files with 186 additions and 74 deletions
@@ -143,7 +143,7 @@ class WFMAMAptOptionsView : public View {
};
OptionsField options_config{
{3 * 8, 0 * 16},
15, // Max option char length "FM+AM(NOAA Apt)"
16, // Max option char length "80khz (NOAA Apt)" example.
{
// Using common messages from freqman_ui.cpp
}};
+7 -4
View File
@@ -33,6 +33,7 @@
#include "portapack_persistent_memory.hpp"
#include "ui_fileman.hpp"
#include "ui_textentry.hpp"
#include "usb_serial_asyncmsg.hpp"
using namespace portapack;
using namespace modems;
@@ -446,6 +447,8 @@ BLERxView::BLERxView(NavigationView& nav)
&button_switch,
&recent_entries_view});
async_tx_states_when_entered = portapack::async_tx_enabled;
recent_entries_view.on_select = [this](const BleRecentEntry& entry) {
nav_.push<BleRecentEntryDetailView>(entry);
};
@@ -453,9 +456,9 @@ BLERxView::BLERxView(NavigationView& nav)
check_serial_log.on_select = [this](Checkbox&, bool v) {
serial_logging = v;
if (v) {
usb_serial_thread = std::make_unique<UsbSerialThread>();
portapack::async_tx_enabled = true;
} else {
usb_serial_thread.reset();
portapack::async_tx_enabled = false;
}
};
check_serial_log.set_value(serial_logging);
@@ -755,8 +758,7 @@ void BLERxView::on_data(BlePacketData* packet) {
}
if (serial_logging) {
usb_serial_thread->serial_str = str_console + "\r\n";
usb_serial_thread->str_ready = true;
UsbSerialAsyncmsg::asyncmsg(str_console); // new line handled there, no need here.
}
str_console = "";
@@ -916,6 +918,7 @@ void BLERxView::set_parent_rect(const Rect new_parent_rect) {
}
BLERxView::~BLERxView() {
portapack::async_tx_enabled = async_tx_states_when_entered;
receiver_model.disable();
baseband::shutdown();
}
+1
View File
@@ -219,6 +219,7 @@ class BLERxView : public View {
std::string filter{};
bool logging{false};
bool serial_logging{false};
bool async_tx_states_when_entered{false};
bool name_enable{true};
app_settings::SettingsManager settings_{
+12 -6
View File
@@ -1,6 +1,7 @@
/*
* 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.
*
@@ -150,12 +151,17 @@ class JammerView : public View {
OptionsField options_type{
{7 * 8, 23 * 8},
8,
{
{"Rand FSK", 0},
{"FM tone", 1},
{"CW sweep", 2},
{"Rand CW", 3},
}};
{{"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},
+2 -1
View File
@@ -108,7 +108,8 @@ options_t freqman_bandwidths[6] = {
},
{
// WFMAM for NOAA satellites, 137 Mhz band
{"FM+AM(NOAA Apt)", 1}, // Fixed RX demod- WFM config Index 1 : FM+AM for Audio NOAA APT ones.
{"80kHz (NOAA Apt)", 0}, // Fixed RX demod- WFM config Index 1 : FM+AM for Audio NOAA APT ones.
{"38kHz (NOAA Apt)", 1},
},
};
+3 -2
View File
@@ -69,8 +69,9 @@ static constexpr std::array<baseband::WFMConfig, 3> wfm_configs{{
{taps_40k_wfm_decim_0, taps_40k_wfm_decim_1},
}};
static constexpr std::array<baseband::WFMAMConfig, 1> wfmam_configs{{
{taps_16k0_decim_0, taps_84k_wfmam_decim_1},
static constexpr std::array<baseband::WFMAMConfig, 2> wfmam_configs{{
{taps_16k0_decim_0, taps_80k_wfmam_decim_1},
{taps_16k0_decim_0, taps_38k_wfmam_decim_1},
}};
} /* namespace */
+51 -15
View File
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2014 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.
*
@@ -26,22 +27,26 @@
#include "event_m4.hpp"
#include <cstdint>
#include <random>
#include <cmath>
#ifndef M_PI
#define M_PI 3.14159265358979323846f
#endif
void JammerProcessor::execute(const buffer_c8_t& buffer) {
if (!configured) return;
for (size_t i = 0; i < buffer.count; i++) {
if (!jammer_duration) {
// Find next enabled range
do {
current_range++;
if (current_range == JAMMER_MAX_CH) current_range = 0;
} while (!jammer_channels[current_range].enabled);
jammer_duration = jammer_channels[current_range].duration;
jammer_bw = jammer_channels[current_range].width / 2; // TODO: Exact value
jammer_bw = jammer_channels[current_range].width / 2;
// Ask for retune
message.freq = jammer_channels[current_range].center;
message.range = current_range;
shared_memory.application_queue.push(message);
@@ -49,26 +54,51 @@ void JammerProcessor::execute(const buffer_c8_t& buffer) {
jammer_duration--;
}
// Phase noise
if (!period_counter) {
period_counter = noise_period;
if (noise_type == JammerType::TYPE_FSK) {
if (noise_type == jammer::JammerType::TYPE_FSK) {
sample = (sample + lfsr) >> 1;
} else if (noise_type == JammerType::TYPE_TONE) {
tone_delta = 150000 + (lfsr >> 9); // Approx 100Hz to 6kHz
} else if (noise_type == JammerType::TYPE_SWEEP) {
sample++; // This is like saw wave FM
} else if (noise_type == jammer::JammerType::TYPE_TONE) {
tone_delta = 150000 + (lfsr >> 9);
} else if (noise_type == jammer::JammerType::TYPE_SWEEP) {
sample++;
} else if (noise_type == jammer::JammerType::TYPE_RANDOM) {
sample = lfsr & 0xFF;
} else if (noise_type == jammer::JammerType::TYPE_SINE) {
wave_phase += 0x01000000;
sample = sine_table_i8[(wave_phase >> 24) & 0xFF];
} else if (noise_type == jammer::JammerType::TYPE_SQUARE) {
wave_index = (wave_index + 1) % 2;
sample = wave_index ? 127 : -128;
} else if (noise_type == jammer::JammerType::TYPE_SAWTOOTH) {
wave_index = (wave_index + 1) % 256;
sample = (wave_index * 127) / 255 - 128;
} else if (noise_type == jammer::JammerType::TYPE_TRIANGLE) {
wave_index = (wave_index + 1) % 256;
sample = (wave_index < 128 ? wave_index : (255 - wave_index)) * 127 / 127 - 128;
} else if (noise_type == jammer::JammerType::TYPE_CHIRP) {
chirp_freq += 0.01f;
if (chirp_freq > 1.0f) chirp_freq = 0.0f;
wave_phase += static_cast<uint32_t>(0x01000000 * (1.0f + chirp_freq));
sample = sine_table_i8[(wave_phase >> 24) & 0xFF];
} else if (noise_type == jammer::JammerType::TYPE_GAUSSIAN) {
float u1 = static_cast<float>(lfsr & 0xFFFF) / 0x10000;
float u2 = static_cast<float>((lfsr >> 16) & 0xFFFF) / 0x10000;
float gaussian = std::sqrt(-2.0f * std::log(u1)) * std::cos(2 * M_PI * u2);
sample = static_cast<int8_t>(gaussian * 32);
} else if (noise_type == jammer::JammerType::TYPE_BRUTEFORCE) {
sample = 127;
}
feedback = ((lfsr >> 31) ^ (lfsr >> 29) ^ (lfsr >> 15) ^ (lfsr >> 11)) & 1;
lfsr = (lfsr << 1) | feedback;
if (!lfsr) lfsr = 0x1337; // Shouldn't do this :(
if (!lfsr) lfsr = 0x1337;
} else {
period_counter--;
}
if (noise_type == JammerType::TYPE_TONE) {
if (noise_type == jammer::JammerType::TYPE_TONE) {
aphase += tone_delta;
sample = sine_table_i8[(aphase & 0xFF000000) >> 24];
}
@@ -78,12 +108,12 @@ void JammerProcessor::execute(const buffer_c8_t& buffer) {
phase += delta;
sphase = phase + (64 << 24);
re = (sine_table_i8[(sphase & 0xFF000000) >> 24]);
im = (sine_table_i8[(phase & 0xFF000000) >> 24]);
re = sine_table_i8[(sphase & 0xFF000000) >> 24];
im = sine_table_i8[(phase & 0xFF000000) >> 24];
buffer.p[i] = {re, im};
}
};
}
void JammerProcessor::on_message(const Message* const msg) {
if (msg->id == Message::ID::JammerConfigure) {
@@ -93,12 +123,18 @@ void JammerProcessor::on_message(const Message* const msg) {
jammer_channels = (JammerChannel*)shared_memory.bb_data.data;
noise_type = message.type;
noise_period = 3072000 / message.speed;
if (noise_type == JammerType::TYPE_SWEEP)
if (noise_type == jammer::JammerType::TYPE_SWEEP || noise_type == jammer::JammerType::TYPE_SINE ||
noise_type == jammer::JammerType::TYPE_SQUARE || noise_type == jammer::JammerType::TYPE_SAWTOOTH ||
noise_type == jammer::JammerType::TYPE_TRIANGLE || noise_type == jammer::JammerType::TYPE_CHIRP ||
noise_type == jammer::JammerType::TYPE_GAUSSIAN || noise_type == jammer::JammerType::TYPE_BRUTEFORCE)
noise_period >>= 8;
period_counter = 0;
jammer_duration = 0;
current_range = 0;
lfsr = 0xDEAD0012;
wave_phase = 0;
wave_index = 0;
chirp_freq = 0.0f;
configured = true;
} else {
+6 -1
View File
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2014 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.
*
@@ -27,6 +28,8 @@
#include "baseband_thread.hpp"
#include "portapack_shared_memory.hpp"
#include "jammer.hpp"
#include <random>
#include <cmath>
using namespace jammer;
@@ -50,9 +53,11 @@ class JammerProcessor : public BasebandProcessor {
uint32_t aphase{0}, phase{0}, delta{0}, sphase{0};
int8_t sample{0};
int8_t re{0}, im{0};
uint32_t wave_phase{0};
uint32_t wave_index{0};
float chirp_freq{0.0f};
RetuneMessage message{};
/* NB: Threads should be the last members in the class definition. */
BasebandThread baseband_thread{3072000, this, baseband::Direction::Transmit};
};
+4 -4
View File
@@ -146,16 +146,16 @@ void NoaaAptRx::configure(const NoaaAptRxConfigureMessage& message) {
// Temptatively , I splitted, in two WidebandFMAudio::configure_wfm / WidebandFMAudio::configure_wfmam and dynamically /2, /8 . (here /8)
// decim_1.set<dsp::decimate::FIRC16xR16x16Decim2>().configure(message.decim_1_filter.taps); // for wfm
// decim_1.set<dsp::decimate::FIRC16xR16x32Decim8>().configure(message.decim_1_filter.taps); // for wfmam
decim_1.configure(taps_84k_wfmam_decim_1.taps); // for wfmam
decim_1.configure(taps_38k_wfmam_decim_1.taps); // for wfmam
size_t decim_1_output_fs = decim_1_input_fs / decim_1.decimation_factor; // wfmam, decim_1.decimation_factor() = /8 ,if applied after the line, decim_1.set<dsp::decimate::FIRC16xR16x16Decim2>().configure(message.decim_1_filter.taps);
size_t demod_input_fs = decim_1_output_fs;
// spectrum_interval_samples = decim_1_output_fs / spectrum_rate_hz;
// spectrum_samples = 0;
channel_filter_low_f = taps_84k_wfmam_decim_1.low_frequency_normalized * decim_1_input_fs;
channel_filter_high_f = taps_84k_wfmam_decim_1.high_frequency_normalized * decim_1_input_fs;
channel_filter_transition = taps_84k_wfmam_decim_1.transition_normalized * decim_1_input_fs;
channel_filter_low_f = taps_38k_wfmam_decim_1.low_frequency_normalized * decim_1_input_fs;
channel_filter_high_f = taps_38k_wfmam_decim_1.high_frequency_normalized * decim_1_input_fs;
channel_filter_transition = taps_38k_wfmam_decim_1.transition_normalized * decim_1_input_fs;
demod.configure(demod_input_fs, 17000);
audio_filter.configure(taps_64_lp_1875_2166.taps);
audio_output.configure(apt_audio_12k_notch_2k4_config, apt_audio_12k_lpf_2000hz_config);
+80 -36
View File
@@ -1327,44 +1327,88 @@ constexpr fir_taps_real<16> taps_40k_wfm_decim_1 = {
// WFMAM decimation filters ////////////////////////////////////////////////
// Used for NOAA 137 Mhz APT sat demod.
// IFIR prototype filter: fs=768000, pass=42000, stop=95000, decim=8, fout=96000
constexpr fir_taps_real<32> taps_84k_wfmam_decim_1 = {
.low_frequency_normalized = -42000.0f / 768000.0f,
.high_frequency_normalized = 42000.0f / 768000.0f,
// IFIR prototype filter: fs=768000, pass=40000, stop=95000, decim=8, fout=96000
constexpr fir_taps_real<32> taps_80k_wfmam_decim_1 = {
.low_frequency_normalized = -40000.0f / 768000.0f,
.high_frequency_normalized = 40000.0f / 768000.0f,
.transition_normalized = 53000.0f / 768000.0f,
.taps = {{
13,
-6,
-47,
-116,
-207,
-294,
-332,
-266,
-39,
386,
1012,
1795,
2648,
3452,
4079,
4423,
4423,
4079,
3452,
2648,
1795,
1012,
386,
-39,
-266,
-332,
-294,
-207,
-116,
-47,
-6,
13,
5,
-37,
-120,
-248,
-397,
-519,
-535,
-354,
106,
896,
2006,
3355,
4797,
6136,
7171,
7736,
7736,
7171,
6136,
4797,
3355,
2006,
896,
106,
-354,
-535,
-519,
-397,
-248,
-120,
-37,
5,
}},
};
// WFMAM decimation filters ////////////////////////////////////////////////
// Used for NOAA 137 Mhz APT sat demod.
// IFIR prototype filter: fs=768000, pass=19000, stop=68000, decim=8, fout=96000
constexpr fir_taps_real<32> taps_38k_wfmam_decim_1 = {
.low_frequency_normalized = -19000.0f / 768000.0f,
.high_frequency_normalized = 19000.0f / 768000.0f,
.transition_normalized = 49000.0f / 768000.0f,
.taps = {{
49,
91,
175,
303,
483,
724,
1028,
1391,
1805,
2253,
2712,
3158,
3560,
3891,
4127,
4250,
4250,
4127,
3891,
3560,
3158,
2712,
2253,
1805,
1391,
1028,
724,
483,
303,
175,
91,
49,
}},
};
+13 -4
View File
@@ -1,6 +1,7 @@
/*
* 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.
*
@@ -20,12 +21,12 @@
* Boston, MA 02110-1301, USA.
*/
#define JAMMER_CH_WIDTH 1000000
#define JAMMER_MAX_CH 24
#ifndef __JAMMER_H__
#define __JAMMER_H__
#define JAMMER_CH_WIDTH 1000000
#define JAMMER_MAX_CH 24
namespace jammer {
typedef struct jammer_range {
@@ -37,7 +38,15 @@ typedef struct jammer_range {
enum JammerType : uint32_t {
TYPE_FSK = 0,
TYPE_TONE = 1,
TYPE_SWEEP = 2
TYPE_SWEEP = 2,
TYPE_RANDOM = 3,
TYPE_SINE = 4,
TYPE_SQUARE = 5,
TYPE_SAWTOOTH = 6,
TYPE_TRIANGLE = 7,
TYPE_CHIRP = 8,
TYPE_GAUSSIAN = 9,
TYPE_BRUTEFORCE = 10
};
} /* namespace jammer */
Binary file not shown.
File diff suppressed because one or more lines are too long
+5
View File
@@ -0,0 +1,5 @@
This folder contains the PCB files for PortaPack H4. If you have any questions about the PCB files, please feel free to contact me. Thank you!
My email addresses are:
support@opensourcesdrlab.com
opensourcesdrlab@gmail.com