Compare commits

...

3 commits

Author SHA1 Message Date
Wolfgang 08a1672c97 add infos and installation instructions 2024-01-04 16:26:22 +01:00
Wolfgang 5e6e486290 add systemd user .service file 2024-01-04 16:26:22 +01:00
Wolfgang d715fa5337 inital commit of .pl file 2024-01-04 16:26:22 +01:00
3 changed files with 253 additions and 0 deletions

View file

@ -1,2 +1,47 @@
# dapnet2ntfy # dapnet2ntfy
**dapnet2ntfy** forwards messages from the [DAPNET](https://hampager.de/) to [ntfy](https://ntfy.sh/).
Similar to other [gateways](https://hampager.de/dokuwiki/doku.php#gateways_apps), especially the [Telegram Bot DB0USD](https://hampager.de/dokuwiki/doku.php?id=usecasetelegrambot), it allows receiving messages, when there is no pager with reception at hand.
## Prerequisites
### DAPNET account
A normal account at [hampager.de](https://support.hampager.de/open.php) (select 'Help Topic -> New DAPNET Account with or without RIC').
A transmitter registered at [hampager.de](https://support.hampager.de/open.php) (select 'Help Topic -> New DAPNET Transmitter').
### ntfy account
Use ntfy.sh or set up your own server: [DOCS](https://docs.ntfy.sh/).
### perl modules
- IO::Socket::INET
- IO::Socket::Timeout
- Errno
- HTTP::Request
- LWP::UserAgent
- MIME::Base64
- POSIX
- utf8
#### For Debian:
```console
apt install perl-base libio-socket-timeout-perl libhttp-message-perl libwww-perl
```
## Installation
Instructions for installing the script to $HOME/bin/
```console
mkdir -p $HOME/.config/systemd/user/
cp dapnet2ntfy.service $HOME/.config/systemd/user/
mkdir -p $HOME/bin
install -m 700 dapnet2ntfy.pl $HOME/bin/
# edit the configuration section to your needs
systemctl --user daemon-reload
systemctl --user enable dapnet2ntfy.service --now
```

197
dapnet2ntfy.pl Executable file
View file

@ -0,0 +1,197 @@
#!/usr/bin/env perl
# Protocol for connecting transmitters to DAPNET:
# https://hampager.de/dokuwiki/doku.php?id=dapnetprotocol
use strict;
use warnings;
# configuration
my $version = '0.5.0';
my $dapnet_username = '';
my $dapnet_password = '';
my $dapnet_server = 'dapnet.afu.rwth-aachen.de';
#my $dapnet_server = 'db0dbn.ig-funk-siebengebirge.de';
my $dapnet_port = '43434',
my $ntfy_username = '';
my $ntfy_password = '';
my $ntfy_url = 'https://server/topic';
my $debug = 1;
my $dapnet_timeout_read_seconds = 125;
my $dapnet_timeout_write_seconds = 5;
my %rics = (
# on pager
'630224' => 'PM',
'1041' => 'MOWAS',
'1063' => 'METAR',
'1064' => 'WX-Lokal',
'1080' => 'APRS-WX',
'1081' => 'DWD',
# for info
# all
'1001' => 'DAPNET-News',
'1028' => 'Clubnews',
#'1060' => 'Stats',
# dl-all
'1016' => 'DL-HH',
'1040' => 'Notfunk-DL',
'1044' => 'HAMNET',
'1055' => 'DAPNET-Team',
'1058' => 'xOTA',
# dl-hh
'1042' => 'Notfunk-Lokal',
'1083' => 'Feinstaub',
);
# start of program
use IO::Socket::INET;
use IO::Socket::Timeout;;
use Errno qw(ETIMEDOUT EWOULDBLOCK);
use HTTP::Request ();
use LWP::UserAgent;
use MIME::Base64;
use POSIX qw(strftime);
use utf8;
my $run = 1;
$SIG{INT} = sub {
print STDERR "terminating\n";
$run = 0;
};
sub debug_print {
if ($debug) {
print STDERR strftime("%F %T", localtime) . " $_[0]";
}
}
sub decode_umlauts {
# [\]{|}~ -> ÄÖÜäöüß
my $s = $_[0];
$s =~ tr/[\\]{|}~/ÄÖÜäöüß/;
utf8::encode($s);
return $s;
}
sub decode_skyper
{
# message is ROT-1 encoded
my $s = '';
foreach my $c (split('', $_[0])) {
$s = $s . chr(ord($c) - 1);
}
$s = decode_umlauts($s);
return $s;
}
# replace decimal RIC with hex value
# better to do this now, not every time a message arrives
%rics = map { sprintf("%X", $_) => $rics{$_} } keys %rics;
my $ntfy_auth_header = 'Basic ' . encode_base64($ntfy_username . ':' . $ntfy_password);
while ($run) {
debug_print "connecting to $dapnet_server\n";
my $socket = IO::Socket::INET->new(
PeerAddr => $dapnet_server,
PeerPort => $dapnet_port,
Timeout => $dapnet_timeout_read_seconds,
Proto => 'tcp',
);
if (! $socket) {
print STDERR "connection problem, reconnect\n";
next;
}
# set up timeout for reading/writing
IO::Socket::Timeout->enable_timeouts_on($socket);
$socket->read_timeout($dapnet_timeout_read_seconds);
$socket->write_timeout($dapnet_timeout_write_seconds);
my $reconnect = 0;
#my $last_received = time;
# login
$socket->send("[dapnet2ntfy v$version $dapnet_username $dapnet_password]\r\n");
while (!$reconnect) {
$reconnect = 0;
my $data = <$socket>;
if (! $data && ( 0+$! == ETIMEDOUT || 0+$! == EWOULDBLOCK )) {
print STDERR "timeout, reconnect\n";
$reconnect = 1;
next;
}
#$socket->recv($data,1024);
chomp $data;
debug_print "received: $data.\n" ;
if ($data =~ /^2:(.*)$/) {
# ident to server
# example: 2:00AF
$socket->send("2:$1:0000\r\n+\r\n");
} elsif ($data =~ /^([34]):.*$/) {
# time sync and time slot
# example: 3:+0090
# example: 4:048C
$socket->send("+\r\n");
if ($1 == '4') {
print STDERR "listening to $dapnet_server\n";
}
} elsif ($data =~ /^7/) {
# login failed
print STDERR "login to $dapnet_server failed:\n";
print STDERR "$data\n";
$run = 0;
} elsif ($data =~ /^#([0-9a-fA-F]+) (.*)$/) {
# messages
# example: #02 6:1:D8:3:YYYYMMDDHHMMSS231222141600
# increase counter and send it back
my $cnt = hex $1;
if ($cnt >= 255) {
# reset counter on FF
$cnt = 0;
} else {
++$cnt;
}
$socket->send('#' . sprintf("%02X", $cnt) . " +\r\n");
# parse message
my ($type, $speed, $ric, $bit, $msg) = split(/:/, $2, 5);
# ignore speed, and bit
# split only 5 times, message can contain :
if ($type == '6') {
# type 6 is for messages
if (exists($rics{$ric})) {
# ric is in wanted list
# send to ntfy
my $ua = LWP::UserAgent->new;
my $request = HTTP::Request->new(
'POST',
$ntfy_url,
[ 'Authorization' => $ntfy_auth_header ],
"DAPNET: $rics{$ric}: " . decode_umlauts($msg)
);
my $response = $ua->request($request);
} elsif ($debug && ($ric =~ /^11A[08]$/)) {
# skyper message
debug_print "Skyper message: " . decode_skyper($msg) . "\n";
}
}
} elsif ($data eq '') {
print STDERR "connection problem, reconnect\n";
$reconnect = 1;
}
#if (time - $last_received > $dapnet_timeout_read_seconds) {
# print STDERR "timeout, reconnect\n";
# $reconnect = 1;
#} else {
# $last_received = time;
#}
sleep(1);
}
#$socket->close();
$socket->shutdown(SHUT_RDWR);
}

11
dapnet2ntfy.service Normal file
View file

@ -0,0 +1,11 @@
[Unit]
Description=Gateway for messages from DAPNET to ntfy
After=network-online.target
[Service]
ExecStart=%h/bin/dapnet2ntfy.pl
Restart=always
[Install]
WantedBy=default.target