Introduction to GP-Jammer


GP-Jammer is a multi-channel RF jammer simulator designed to control multiple Adalm Pluto SDR devices with custom firmware. Its primary function is to generate various types of interference signals (such as noise, continuous wave, and modulated signals) for research and testing purposes, specifically aimed at improving the resilience of communication and navigation systems. GP-Jammer utilizes Python scripts to create IQ data, which is then loaded onto the Adalm Pluto SDR devices for continuous playback. 




How GP-Jammer Works with Python Files


The GP-Jammer app relies on Python files to generate small chunks of IQ data that are saved in a binary format with an .iq extension. These files are named based on the Python script itself, making it easy to identify which script generated which IQ file. Once generated, the IQ data is sent to the Adalm Pluto SDR device, which loops the data continuously. This eliminates the need for real-time streaming, reducing system load and simplifying the process of jamming signal simulation.




Structure of Python Files in GP-Jammer


Python files in the GP-Jammer system are structured to ensure seamless integration with both the software and Adalm Pluto SDR devices. The primary objective of each Python file is to generate a binary file containing IQ data, which is transferred to Adalm Pluto SDR.


  1. License Agreement
  2. Importing Necessary Libraries
    This block imports essential libraries like numpy for numerical operations and os for file system handling.
  3. <config> Section
    This is the most unique section of the file, designed to allow users to modify key IQ signal generation parameters directly from the GP-Jammer user interface. Any variables declared within this section become accessible in the signal configuration window of the GP-Jammer application. Additionally, for each parameter, you can specify a format that controls how it is displayed in the user interface, including units, ranges, and other constraints.
  4. Global Variables
    Defines global constants like DAC resolution or the maximum buffer size, which are used in IQ data generation.
  5. File Name Extraction
    Extracts the name of the current Python file to ensure that the generated IQ data file has the same name, but with a .iq extension.
  6. Validation Function
    Ensures that user-defined parameters (e.g., central_frequency and IQ_rate) are within valid ranges and that the generated IQ data doesn't exceed hardware limits of Adalm Pluto SDR.
  7. IQ Data Generation Function
    Generates IQ data based on the specified parameters, producing both I (In-phase) and Q (Quadrature) components for various types of signals.
  8. File Writing Function
    Saves the generated IQ data into a binary file with a .iq extension, which will later be used by GP-Jammer for signal playback.
  9. Main Execution Block
    The main part of the script that runs the validation, generates IQ data, and writes it to the file. It acts as the program’s entry point.




Python File Example

Example of single tone signal generation  

import numpy as np
import os

# <config>
# <description>Unmodulated carrier wave</description>
center_frequency = 1575.42e6    # Center frequency (Hz) <format>"number", 70e6, 6e9</format>
IQ_rate = 10e6                  # IQ rate (Hz)          <format>"number", 200e3, 60e6</format>
# </config>


resolution = 16                 # Adalm Pluto DAC resolution
max_buffer_length = 128*1024*1024  # Maximum IQ samples buffer length for Adalm Pluto, bytes 
amplitude = 2 ** (resolution - 1) - 1


# Extract the filename without the extension
file_name = os.path.splitext(os.path.basename(__file__))[0]


def validate_parameters(number_of_samples):
    """
    Validates parameters to ensure they meet specified constraints and do not exceed Adalm Pluto's specification.
    """
    # Validate center frequency
    if not (70e6 <= center_frequency <= 6000e6):
        raise ValueError("The center frequency must be between 70 MHz and 6000 MHz.")
    # Validate IQ rate
    if not (200e3 <= IQ_rate <= 60e6):
        raise ValueError("The IQ rate must be between 200 kHz and 60 MHz.")
    # Validate required buffer size
    required_buffer = 4 * number_of_samples  # 4 bytes per sample (2 bytes for I and 2 bytes for Q)
    if required_buffer > max_buffer_length:
        raise ValueError(f"The generated IQ data size ({required_buffer} bytes) exceeds the maximum buffer length ({max_buffer_length} bytes).")


def generate_IQ_data(number_of_samples):
    """
    Generates IQ data for the specified number of samples.
    Returns:
    - An interleaved array of I and Q components (I0, Q0, I1, Q1, ..., In, Qn).
    """
    I_component = np.full(number_of_samples, amplitude)  # Constant I component
    Q_component = np.zeros(number_of_samples)  # Q component set to 0
    
    return np.column_stack((I_component, Q_component)).ravel()


def write_IQ_data(signal, file_name):
    """
    Write the IQ data to a binary file.
    """
    with open(f"{file_name}.iq", "wb") as f:
        f.write(signal.astype(np.int16).tobytes())


# Main function
if __name__ == "__main__":
    number_of_samples = 1000  # number of generated samples
    try:
        validate_parameters(number_of_samples)  
        IQ_data = generate_IQ_data(number_of_samples)   
        write_IQ_data(IQ_data, file_name)
        print("IQ data generated and saved successfully.")
    except ValueError as e:
        print(f"Error: {e}")



Understanding and Using the <config> Section


The <config> section is one of the most important and unique parts of the Python files used within GP-Jammer. It allows users to modify specific parameters related to IQ signal generation directly from the GP-Jammer user interface without editing the Python code itself. This makes the system highly flexible and user-friendly, enabling non-programmers to adjust signal configurations as needed.


Purpose of the <config> Section

The main goal of the <config> section is to expose critical signal parameters to the GP-Jammer UI. This section is parsed by GP-Jammer, and the variables defined here are made accessible in the application's signal configuration window. Users can easily modify these variables, which directly affect the behavior and characteristics of the generated IQ signals, such as the signal's frequency, IQ sample rate, and other properties.


Variables in the <config> Section

Each variable declared in the <config> section is displayed in the GP-Jammer user interface, allowing users to tweak these values in real-time to generate the desired signal. 

This section must always include two mandatory variables:

  1. center_frequency – The center frequency of the generated signal.
  2. IQ_rate – The rate at which IQ samples are generated.


Optional <Description> Section

In addition to the required variables, the <config> section can contain an optional description section. This description provides a brief overview of the signal being generated and will be displayed in the GP-Jammer user interface next to the file name.


Comments as Explanations in the User Interface

For each variable in the <config> section, the comment immediately to the right of the variable will appear in the GP-Jammer user interface as an additional explanation for the user. This makes it easier to understand what each parameter does when modifying the signal settings.


Format of Variables

Each variable can include a <format> section that specifies how it should be displayed and validated in the GP-Jammer user interface. The format for a variable of type "number" contains the following:


  1. Type of the variable: Currently, GP-Jammer supports only the number type.
  2. Minimum value: The lowest allowed value for this parameter.
  3. Maximum value: The highest allowed value for this parameter.


Example <config> Section

# <config>
# <description>Gaussian noise signal with fixed period pulse modulation: A Gaussian noise-modulated signal further modulated by periodic pulses</description>
center_frequency = 1575.42e6   # Сenter frequency (Hz) <format>"number", 300e6, 6e9</format> 
IQ_rate = 60e6                         # IQ rate (Hz)                 <format>"number", 200e3, 60e6</format>
bandwidth = 10e6                     # Signal bandwidth (Hz)  <format>"number", 1e3, 60e6</format>          
pulse_period = 100e-6              # Pulse period (s)            <format>"number", 1e-6, 1e-1</format>
pulse_duty_cycle = 50              # Pulse duty cycle (%)     <format>"number", 1, 100</format>     
# </config>

In this example:

  • The center_frequency and IQ_rate are mandatory variables.
  • Additional parameters such as bandwidth, pulse_period, and pulse_duty_cycle are included to allow further configuration of the generated signal.
  • Each variable is followed by a comment that explains its function, and this explanation will appear in the GP-Jammer user interface.