Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Docker Publish

on:
push:
branches:
- main
tags:
- "v*"
- "[0-9]*.[0-9]*.[0-9]*"
- "[0-9]*.[0-9]*.[0-9]*-*"
workflow_dispatch:

permissions:
contents: read
packages: write

jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log into registry ghcr.io
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
# Configuração Padrão Ouro para tagueamento múltiplo
tags: |
type=ref,event=branch
type=ref,event=pr
type=ref,event=tag
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/') }}

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

[submodule "frontend"]
path = frontend
url = https://github.com/Steven9101/frontend
url = https://github.com/xnetinho/NovaSDR-frontend
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Changelog

## [Release] v0.1.0 — Squelch Híbrido: Code Review & Refatoração

### O que foi modificado

- [x] **Backend (`crates/novasdr-server/src/ws/audio.rs`):** Eliminados magic numbers `10` — declarada constante `SQUELCH_HYSTERESIS_FRAMES: u8 = 10` e substituída em ambos os pontos de uso (modo manual e modo auto).
- [x] **Backend (`audio.rs`):** Removidos 3 comentários didáticos/decorativos que violavam as Engineering Rules (proibição de comentários óbvios).
- [x] **Documentação (`docs/AUDIO.md`):** Seção Squelch reescrita para documentar ambos os modos (Auto e Manual), incluindo payload `level: Option<f32>`, tabela de campos e constante de histerese.
- [x] **Frontend (`frontend/src/components/receiver/panels/AudioPanel.tsx`):** Slider do squelch alterado de opacity/pointer-events para **renderização condicional** — desaparece completamente quando `squelchAuto` é `true`.
- [x] **Frontend (`types.ts`, `useAudioClient.ts`):** Auditados e confirmados sem comentários inúteis (nenhuma modificação necessária).
128 changes: 38 additions & 90 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,127 +1,75 @@
# Multi-stage Dockerfile for NovaSDR
# Builds frontend, Rust backend with SoapySDR and OpenCL support

# Stage 1: Build the frontend
# ESTÁGIO 1: Frontend
FROM node:20-slim AS frontend-builder

WORKDIR /build

# Copy frontend package files
COPY frontend/package*.json ./

# Install dependencies
RUN npm ci

# Copy frontend source
# Ajuste para resiliência de submódulo
RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi
COPY frontend/ ./

# Build the frontend
RUN npm run build

# Stage 2: Build the Rust backend
# ESTÁGIO 2: Planejamento
FROM rustlang/rust:nightly-bookworm-slim AS planner
WORKDIR /build
RUN cargo install cargo-chef
COPY . .
RUN cargo chef prepare --recipe-path recipe.json

# ESTÁGIO 3: Backend Builder
FROM rustlang/rust:nightly-bookworm-slim AS backend-builder
WORKDIR /build

# Install build dependencies
# Instalação unificada de todas as dependências de build detectadas
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
cmake \
pkg-config \
clang \
libclang-dev \
swig \
python3 \
python3-dev \
python3-numpy \
ocl-icd-opencl-dev \
libclfft-dev \
libusb-1.0-0-dev \
git \
ca-certificates \
build-essential cmake pkg-config clang libclang-dev swig \
python3 python3-dev python3-numpy ocl-icd-opencl-dev \
libclfft-dev libusb-1.0-0-dev git ca-certificates \
rtl-sdr librtlsdr-dev libopus-dev \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /build

# Copy Cargo workspace files
COPY Cargo.toml ./
COPY crates/ ./crates/
RUN cargo install cargo-chef
COPY --from=planner /build/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json

# Build SoapySDR from source (for better compatibility)
# Compilação de Drivers (Padrão Ouro: explicitando diretórios de build)
RUN git clone https://github.com/pothosware/SoapySDR.git /tmp/SoapySDR && \
cd /tmp/SoapySDR && \
mkdir build && cd build && \
cmake .. && \
make -j$(nproc) && \
make install && \
ldconfig && \
rm -rf /tmp/SoapySDR

# Build SoapyRTLSDR (RTL-SDR support)
RUN apt-get update && apt-get install -y --no-install-recommends rtl-sdr librtlsdr-dev && \
cmake -S /tmp/SoapySDR -B /tmp/SoapySDR/build -DCMAKE_BUILD_TYPE=Release && \
make -C /tmp/SoapySDR/build -j$(nproc) install && \
git clone https://github.com/pothosware/SoapyRTLSDR.git /tmp/SoapyRTLSDR && \
cd /tmp/SoapyRTLSDR && \
mkdir build && cd build && \
cmake .. && \
make -j$(nproc) && \
make install && \
rm -rf /tmp/SoapyRTLSDR && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Build the Rust backend with SoapySDR and clFFT support
RUN cargo build --release --features "soapysdr,clfft" -p novasdr-server
cmake -S /tmp/SoapyRTLSDR -B /tmp/SoapyRTLSDR/build -DCMAKE_BUILD_TYPE=Release && \
make -C /tmp/SoapyRTLSDR/build -j$(nproc) install && \
ldconfig && rm -rf /tmp/Soapy*

# Build the ws_probe utility
RUN cargo build --release -p ws_probe
COPY . .
RUN cargo build --release --features "soapysdr,clfft" -p novasdr-server && \
cargo build --release -p ws_probe

# Stage 3: Final runtime image
# ESTÁGIO 4: Runtime Final
FROM debian:bookworm-slim
WORKDIR /app

# Install runtime dependencies
# Adicionado libopus0 e garantido paridade de pacotes
RUN apt-get update && apt-get install -y --no-install-recommends \
libusb-1.0-0 \
ocl-icd-libopencl1 \
libclfft2 \
rtl-sdr \
python3 \
python3-numpy \
ca-certificates \
netcat-openbsd \
libusb-1.0-0 ocl-icd-libopencl1 libclfft2 rtl-sdr \
python3 python3-numpy ca-certificates netcat-openbsd \
libopus0 \
&& rm -rf /var/lib/apt/lists/*

# Copy SoapySDR runtime from builder
# Cópia completa de bibliotecas e INCLUDES (conforme original)
COPY --from=backend-builder /usr/local/lib/libSoapySDR* /usr/local/lib/
COPY --from=backend-builder /usr/local/lib/SoapySDR /usr/local/lib/SoapySDR
COPY --from=backend-builder /usr/local/include/SoapySDR /usr/local/include/SoapySDR
COPY --from=backend-builder /usr/local/bin/SoapySDRUtil /usr/local/bin/

# Update library cache
RUN ldconfig

# Create application directory
WORKDIR /app

# Copy built binaries from backend builder
# Binários e Recursos (Caminhos de origem corrigidos para /build)
COPY --from=backend-builder /build/target/release/novasdr-server /app/
COPY --from=backend-builder /build/target/release/ws_probe /app/

# Copy built frontend from frontend builder
COPY --from=frontend-builder /build/dist /app/frontend/dist

# Copy configuration files
COPY config/ /app/config/

# Copy resources (default bands, etc.)
COPY crates/novasdr-server/resources/ /app/resources/

# Create directories for runtime data
RUN mkdir -p /app/logs /app/data

# Expose the default port
EXPOSE 9002
ENV RUST_LOG=info RUST_BACKTRACE=1

# Set environment variables
ENV RUST_LOG=info
ENV RUST_BACKTRACE=1

# Run the server
CMD ["/app/novasdr-server", "-c", "/app/config/config.json", "-r", "/app/config/receivers.json"]
2 changes: 2 additions & 0 deletions crates/novasdr-core/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ pub enum ClientCommand {
},
Squelch {
enabled: bool,
#[serde(default)]
level: Option<f32>,
},
Chat {
message: String,
Expand Down
1 change: 1 addition & 0 deletions crates/novasdr-server/src/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ fn ssb_benchmark(iterations: usize) -> anyhow::Result<()> {
r: 2000,
mute: false,
squelch_enabled: false,
squelch_level: None,
demodulation: DemodulationMode::Usb,
agc_speed: AgcSpeed::Off,
agc_attack_ms: None,
Expand Down
1 change: 1 addition & 0 deletions crates/novasdr-server/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ pub struct AudioParams {
pub r: i32,
pub mute: bool,
pub squelch_enabled: bool,
pub squelch_level: Option<f32>,
pub demodulation: novasdr_core::dsp::demod::DemodulationMode,
pub agc_speed: AgcSpeed,
pub agc_attack_ms: Option<f32>,
Expand Down
Loading