https://codeberg.org/cyberdream/ospal
OSPAL loggar POCSAG-meddelanden med en RTL-SDR-dongle
Eftersom jag saknade en bra POCSAG-logger för linux så har jag skapat den ultimata POCSAG-loggaren för linux. Med svartlistning – keywordfiltrering – flera loggnivåer och alerts via smtp och/eller ntfy. I tillägg finns möjlighet att köra tinker-vänliga externa script när filtrerade larm upptäcks. Följer med exempelscript (ir_alert.py) för att t.ex. styra en fjärrkontrollerad LED-lampa via IR-sändare på GPIO-pins på Raspberry Pi. Eller låta en LED blinka det larmade keywordet i morsekod. Tinkervänligheten slutar inte där, även script för att “lära” in dina egna fjärrkontroller följer med.
Open Source POCSAG Alert Logger – v0.7.1
OSPAL är ett headless, konfigurerbart verktyg för mottagning, avkodning och loggning av POCSAG-meddelanden via en RTL-SDR-dongle.
Det är byggt för att köras på en Raspberry Pi, annan enkortsdator eller vilken Linux-maskin som helst med en USB-port, styras via SSH och sköta sig självt som en systemd-tjänst, eller köras direkt i en terminal.
Bakgrund
OSPAL skapades delvis som ett alternativ till PDW – det välkända Windows-programmet för POCSAG-mottagning som länge varit standard bland radioamatörer och blåljusintresserade.
PDW är officiellt färdigutvecklat sedan 2013, saknar stöd för moderna SMTP-krav och körs inte under Linux.
Mycket av inspirationen till OSPAL:s filtreringsfunktioner kommer från PDW:s välgenomtänkta och flexibla filtreringssystem.
Trots att utvecklingen upphörde 2013 förtjänar PDW all heder för att ha satt standarden för vad ett POCSAG-verktyg bör kunna göra.
OSPAL är ett försök att föra arvet vidare på en ny plattform och utan GUI.
Projektet startade med en RTL-SDR-dongle och en enkortsdator, och växte fram genom praktisk testning mot ett verkligt räddningstjänstnät i Sverige samt Minicalls nationella personsökarnät.
Meddelandeflöde
rtl_fm -> multimon-ng
|
+-> [raw.log] (always, every line)
|
+-> terminal (if terminal_output = raw)
|
+-> parse_pocsag_line()
|
+-> (not a POCSAG line) -> discard
|
+-> apply_charset() (character mapping)
|
+-> (address/function in charset blacklist) -> skip mapping
|
+-> should_blacklist() [filtering.enabled]
|
+-> YES (address or keyword blacklisted)
| -> discard (not in filtered.log, no alerts)
|
+-> NO -> [filtered.log]
|
+-> terminal (if terminal_output = filtered)
|
+-> find_matching_rule()
|
+-> NO MATCH -> stop
|
+-> MATCH -> [keywords.log]
|
+-> terminal (if terminal_output = keywords)
|
+-> DuplicateSuppressor
|
+-> DUPLICATE -> stop
|
+-> NEW
+-> send alert mail
| [smtp.log]
| (if mail_enabled
| and mail_alerts)
|
+-> send ntfy notification
| [ntfy.log]
| (if ntfy_enabled
| and ntfy_alerts)
|
+-> run alert script
(if alert.enabled)
error.log <- startup, shutdown, restarts, exceptions (all levels)
silent_receiver <- varnar via mail/ntfy/alert-script om ingen output
från multimon-ng under X minuter
Krav
Hårdvara
- RTL-SDR-dongle med RTL2832U-chip (R820T/R820T2-tuner rekommenderas, FC0013 fungerar men med sämre VHF-känslighet)
- Enkortsdator eller annan Linux-maskin med USB-port och nätverk
- Antenn anpassad för din frekvens
Mjukvara
- Linux (Debian/Raspberry Pi OS/Armbian rekommenderas)
- Python 3.7 eller senare
rtl-sdrmultimon-ng
Installation
1. Installera beroenden
sudo apt update
sudo apt install -y rtl-sdr multimon-ng python3
2. Verifiera dongeln
rtl_test
3. Klona OSPAL
git clone https://codeberg.org/dittnamn/ospal.git
cd ospal
4. Konfigurera ospal.ini
nano ospal.ini
5. Gör kontrollscriptet körbart
chmod +x ospal-ctl.sh
6. Installera systemd-tjänst
sudo ./ospal-ctl.sh install-service
7. Kalibrera dongeln
./ospal-ctl.sh calibrate 15
Låt dongeln värmas upp 5-10 minuter innan kalibrering.
8. Testa mail och/eller ntfy
./ospal-ctl.sh testmail
./ospal-ctl.sh testntfy
9. Starta
./ospal-ctl.sh start
Användning
python3 -u ospal.py Starta mottagaren
python3 -u ospal.py -t [min] Kalibrera dongeln (PPM, gain, samplerate)
python3 -u ospal.py -m Skicka testmail
python3 -u ospal.py -n Skicka test-ntfy-notis
python3 -u ospal.py -c fil.ini Använd angiven konfigurationsfil
När OSPAL körs som systemd-tjänst används ospal-ctl.sh för kalibrering och testutskick.
Scriptet stoppar tjänsten automatiskt, kör kommandot och startar om efteråt:
./ospal-ctl.sh calibrate 15 # Kalibrering (motsvarar -t)
./ospal-ctl.sh testmail # Testmail (motsvarar -m)
./ospal-ctl.sh testntfy # Test-ntfy (motsvarar -n)
Konfiguration
[receiver]
frequency = 161.4375M ; Frekvens
gain = 19.7 ; Gain - sätts av calibrate
ppm = 0 ; PPM - sätts av calibrate
sample_rate = 22050 ; Samplerate - sätts av calibrate
decode_format = alpha ; alpha (rekommenderas), auto, numeric, skyper
[smtp]
mail_enabled = false ; Master-switch - false = inget mail alls
; Testmail fungerar alltid oavsett denna inställning
mail_alerts = true ; Skicka mail vid enskilda larm
retry_count = 3 ; Antal försök vid misslyckad sändning
retry_delay = 30 ; Sekunder mellan försök
mail_log_time = 06:00 ; Tid för dagliga logg-mail (HH:MM)
mail_log_raw = false
mail_log_filtered = false
mail_log_smtp = false
mail_log_ntfy = false
mail_log_error = false
mail_log_keywords = false
host = smtp.example.com
port = 465 ; 465=SSL/TLS, 587=STARTTLS
type = ssl
user = ospal@example.com
password = lösenord ; %-tecken i lösenord escapas som %%
recipient = du@example.com
[ntfy]
ntfy_enabled = false ; Aktivera ntfy push-notiser
ntfy_alerts = true ; Skicka ntfy-notis vid enskilda larm
url = https://ntfy.sh ; Eller din self-hosted instans
topic = ditt-topic
token = ; Access-token för autentiserade topics
ntfy_log_raw = false
ntfy_log_filtered = false
ntfy_log_smtp = false
ntfy_log_ntfy = false
ntfy_log_error = false
ntfy_log_keywords = false
[mail_format]
; Variabler: {keyword} {message} {message_preview} {address} {function}
; {timestamp} {uptime} {last_restart} {frequency}
; {errors_exist} {ospal_version} {priority}
subject = {keyword} - {message_preview}
body = {timestamp}
{message}
Address : {address}
Uptime : {uptime}
Errors : {errors_exist}
[filtering]
enabled = false
blacklist_addresses = 1600000
blacklist_keywords = PASSNINGSLARM,PROVLARM
[mail_rules]
; Regler är OR sinsemellan. AND/NOT (VERSALER) är operatorer.
; Adressregel: ADDRESS:320008
; Kombinerat: brand AND viskafors
; ntfy-prioritet per regel (min/low/default/high/max):
rule1 = brand
rule1_priority = high
rule2 = trafikolycka
rule2_priority = high
[logging]
; Relativ sökväg utgår från OSPAL-mappen, t.ex. logs -> /home/dk/OSPAL/logs
; Absolut sökväg fungerar också, t.ex. /var/log/ospal
log_dir = logs
log_level = info ; debug, info, warning, error, critical
raw_enabled = true
filtered_enabled = true
keywords_enabled = true
smtp_enabled = true
ntfy_log_enabled = true
error_enabled = true
terminal_output = raw ; raw, filtered eller keywords
duplicate_suppression = true
duplicate_window_seconds = 120
duplicate_match_chars = 32
archive_keep_days = 0
[charset]
91 = Ä
92 = Ö
93 = Å
123 = ä
124 = ö
125 = å
charset_blacklist_addresses = 1600000
charset_blacklist_functions =
[alert]
enabled = false
script = alert-scripts/ir_alarm/ir_alarm.py
mode = queue ; queue eller interrupt
timeout = 600
pass_message = keyword ; none, keyword eller message
queue_max = 2
I interrupt-läge skickas SIGTERM till det körande alert-scriptet vid nytt larm.
Ditt script bör fånga SIGTERM och städa upp innan det avslutas:
import signal, sys
def cleanup(sig, frame):
sys.exit(0)
signal.signal(signal.SIGTERM, cleanup)
[silent_receiver]
enabled = false
silent_minutes = 12 ; Minuter utan output innan varning skickas
max_warnings = 2 ; Max antal varningar per tystnadperiod
send_mail = true ; Skicka varning via mail
send_ntfy = false ; Skicka varning via ntfy
trigger_alert = true ; Trigga alert-script med OSPAL-SILENT
Loggfiler
| Fil | Innehåll |
|---|---|
YYYY-MM-DD-raw.log | All rådata från multimon-ng |
YYYY-MM-DD-filtered.log | Meddelanden som passerar blacklist-filtret |
YYYY-MM-DD-keywords.log | Meddelanden som matchade en regel |
YYYY-MM-DD-smtp.log | SMTP-händelser |
YYYY-MM-DD-ntfy.log | ntfy-händelser |
YYYY-MM-DD-error.log | Fel, undantag, start/stopp-händelser |
Alla loggfiler är lazy – de skapas bara om det finns något att logga. Vid midnatt arkiveras föregående dygns filer automatiskt till logs/archive/YYYY-MM/.
Kontrollscript – ospal-ctl.sh
./ospal-ctl.sh [kommando]
start Starta tjänsten
stop Stoppa tjänsten
restart Starta om (efter redigering av ospal.ini)
status Visa status + senaste filtered-loggen
status-live Visa live output via journalctl
(Ctrl+C avslutar visningen - OSPAL kör vidare)
calibrate [min] Stoppa, kalibrera, starta om. Standard: 15 min
testmail Stoppa, skicka testmail, starta om
testntfy Stoppa, skicka test-ntfy-notis, starta om
install-service Installera systemd-tjänst (kräver sudo)
install-service
sudo ./ospal-ctl.sh install-service
- Identifierar mappen scriptet körs från
- Identifierar användaren som körde sudo (tjänsten körs som denne, inte root)
- Hittar Python-binären automatiskt
- Skapar
/etc/systemd/system/ospal.servicemed-uför unbuffrad output - Kör
systemctl daemon-reload - Aktiverar tjänsten med
systemctl enable ospal
Avinstallera:
sudo systemctl disable ospal
sudo rm /etc/systemd/system/ospal.service
sudo systemctl daemon-reload
Rekommendationer vid headless drift
Visa output
./ospal-ctl.sh status-live
journalctl -u ospal -n 50
journalctl -u ospal --since "1 hour ago"
Stäng av WiFi-strömspararläget
På Raspberry Pi är WiFi-strömspararläget aktiverat som standard. Det kan göra att adaptern somnar och inte vaknar korrekt, vilket gör RPi:n onåbar via SSH trots att systemet kör.
Stäng av tillfälligt:
sudo iw dev wlan0 set power_save off
Gör det permanent:
sudo nano /etc/NetworkManager/conf.d/wifi-powersave-off.conf
[connection]
wifi.powersave = 2
sudo reboot
Verifiera:
iwconfig wlan0 | grep "Power Management"
Aktivera persistent systemd-journal
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
Windows och andra plattformar
OSPAL är utvecklat och testat på Linux. Om du lyckas köra OSPAL på Windows, macOS eller andra plattformar är du välkommen att bidra med instruktioner via ett pull request på Codeberg. Eller meddelande till ospal snabel-a cyberdream punkt se.
Juridisk information
Detta är inte juridisk rådgivning. Kontrollera alltid gällande lagstiftning.
Ansvarsfriskrivning: Utvecklaren tar inget ansvar för hur mjukvaran används. Användaren bär ensamt ansvar för laglig användning.
Användare i USA: Användning av OSPAL i USA är inte tillåten på grund av Electronic Communications Privacy Act (ECPA). Utvecklaren medger inte användning i USA eller andra jurisdiktioner där sådan användning strider mot lag.
Sverige
Att ta emot POCSAG-signaler är lagligt. Lag om elektronisk kommunikation (2003:389), 6 kap 23 paragraf förbjuder att föra vidare meddelandeinnehåll som inte är avsett för dig. mail_enabled är false som standard av detta skäl – använd med omdöme.
Storbritannien
Lagligt att scanna, olagligt att avslöja innehåll.
USA
Olagligt enligt ECPA. Se ovan.
Övriga länder
Kontrollera lokal lagstiftning. I de flesta länder är mottagning laglig men spridning olaglig.
Kända begränsningar
- En dongle kan bara lyssna på en frekvens åt gången
- FC0013 har sämre VHF-känslighet än R820T/R820T2
- PPM varierar med temperatur – kalibrera med varm dongle
%i lösenord måste escapas som%%i ini-filen
Framtida idéer
- Flerspråkighet – gettext med .po-filer (sv, de, es), auto-kompilering vid start
- Konfigurerbart format för loggmail – samma variabelsystem som för larmmail
- ntfy – djupdykning ur integritets/juridikperspektiv
- Google Maps-länkar – adressparsning + ortslista i mailinnehåll
- Flera frekvenser – scanning/växling mellan RTJ-nät och Minicall
- NVDB-integration – Lantmäteriets vägdatabas för adressparsning
- Display-stöd – visa larm på ansluten skärm
Licens
OSPAL är fri mjukvara licensierad under GNU General Public License v3.0 (GPL-3.0).
Se filen LICENSE för fullständig licenstext.
Källkod finns på Codeberg.
Bidra
Buggrapporter, förbättringsförslag och pull requests är välkomna på Codeberg. Eller skicka meddelande till ospal snabel-a cyberdream punkt se.