Ero sivun ”Toistinaseman mainostaminen APRS-asemille” versioiden välillä
>OH6KTT Ei muokkausyhteenvetoa |
>OH6KTT p (väärä scripti äsken) |
||
(13 välissä olevaa versiota samalta käyttäjältä ei näytetä) | |||
Rivi 1: | Rivi 1: | ||
[[Category: R.NET]] | [[Category: R.NET]] | ||
Scripti joka tutkii ajastettuna [[OH6RUC]] toistimen linuxissa [[aprx]] ohjelman tekemää /tmp/aprx-rf.log tiedostoa. Jos logissa näkyy [[APRS]]-asema joka on lähempänä kuin 30km [[OH6RUC]] toistinta ja kyseistä [[APRS]]-asemaa ei ole kuultu edellisen 24h kuluessa, ja toistin on vapaana, scripti aukaisee toistimen ja mainostaa iseaään [[APRS]]-asemalle puheella. Puhe generoidaan festival puhesyntetisaattorilla. | |||
''"Tervetuloa OH6RUC toistinaseman kuuluvuusalueelle OH6KTT. Minä olen Kaustisen OH6RUC toistinasema taajuudella 434.900 MHz. Ripiitterierotukseni on -2 MHz. Toistan. Ripiitterierotus on -2 MHz. Automaattinen tiedote ripiitteriä lähestyville APRS-asemille päättyy."'' | |||
Sama scripti pitää logia suoraan RF:llä kuulluista APRS-asemista. | |||
Ideoita jatkokehitystä varten: | |||
* 2m tropokelit on mahdollista havaita suoraan RF:llä kuulluista asemista | |||
* Pitkän historian avulla db:stä voisi saada selville digiripiitterin kuuntelukyky eri ilmansuuntiin | |||
<pre> | <pre> | ||
#!/usr/bin/php -q | #!/usr/bin/php -q | ||
<?php | <?php | ||
ini_set('memory_limit','50M'); | |||
/* | /* | ||
aprs-repeater-advertiser.php v1. | aprs-repeater-advertiser.php v1.11 - repeater advertiser to APRS users | ||
Copyright (C) 2010 Kari Karvonen <oh6ktt@toimii.net> | Copyright (C) 2010 Kari Karvonen <oh6ktt@toimii.net> | ||
Rivi 26: | Rivi 34: | ||
*/ | */ | ||
$debug = 0; /* 0 = no debug, 1 = little debug, 2 = more debug, 3 = annoying */ | |||
$aprxrflogfile = "/tmp/aprx-rf.log"; | $aprxrflogfile = "/tmp/aprx-rf.log"; | ||
$stationdbfile = "/tmp/oh6ruc-aprs-db.txt"; | $stationdbfile = "/tmp/oh6ruc-aprs-db.txt"; | ||
Rivi 33: | Rivi 42: | ||
$floodprotect = 60*60*24; /* after this time old station will be notified again. Seconds. */ | $floodprotect = 60*60*24; /* after this time old station will be notified again. Seconds. */ | ||
$maxdistance = 30; /* km */ | $maxdistance = 30; /* km */ | ||
$denytxfile = "/tmp/ptt-on"; /* if this file exist, no | $maxloglines = 1000; /* max loglines to analyze (tail) */ | ||
$denytxfile = "/tmp/ptt-on"; /* if this file exist, no advertises will be send */ | |||
$prefixwave = "/opt/thelinkbox/wav/aprs-repeater-advertiser-1.wav"; /* wave before callsigns */ | $prefixwave = "/opt/thelinkbox/wav/aprs-repeater-advertiser-1.wav"; /* wave before callsigns */ | ||
$suffixwave = "/opt/thelinkbox/wav/aprs-repeater-advertiser-2.wav"; /* wave after callsigns */ | $suffixwave = "/opt/thelinkbox/wav/aprs-repeater-advertiser-2.wav"; /* wave after callsigns */ | ||
$tempwavetxt = "/tmp/aprs-repeater-advertiser.txt"; | $tempwavetxt = "/tmp/aprs-repeater-advertiser.txt"; | ||
$tempwave = "/tmp/aprs-repeater-advertiser.wav"; | $tempwave = "/tmp/aprs-repeater-advertiser.wav"; | ||
$repeatedmatch = ",OH"; /* if this is exists on path (eg APRS,OH6RUC*,OH8RDU*,WIDE) assume packet digirepeated and discard it */ | |||
$rangelimit = 2000; /* if range more than this then range is invalid. km. */ | |||
/* code begins */ | /* code begins */ | ||
Rivi 47: | Rivi 58: | ||
$aprxrflog = @file($aprxrflogfile); | $aprxrflog = @file($aprxrflogfile); | ||
if ($aprxrflog == false) die("Cannot open $aprxrflogfile\n"); | if ($aprxrflog == false) die("Cannot open $aprxrflogfile\n"); | ||
function min_to_dec($deg, $min, $decsec) { | |||
return($deg/1.0 + $min/60.0 + $decsec/10000.0); | |||
} | |||
function utctimenow() { | |||
$utcoffset = intval(date("O")/100)*60; | |||
return (time()-$utcoffset); | |||
} | |||
function latlongbearing($lat1, $lon1, $lat2, $lon2) { | |||
$lat1 = deg2rad($lat1); | |||
$lat2 = deg2rad($lat2); | |||
$lon1 = deg2rad ($lon1); | |||
$lon2 = deg2rad ($lon2); | |||
$dLon = $lon2-$lon1; | |||
$y = sin($dLon) * cos($lat2); | |||
$x = cos($lat1) * sin($lat2) - sin($lat1)*cos($lat2)*cos($dLon); | |||
$bearrad = atan2($y, $x); | |||
$beardeg = (rad2deg($bearrad)+360)%360; | |||
return ($beardeg); | |||
} | |||
function decimal_distance($lat1 = "", $lon1 = "", $lat2 = "", $lon2 = "") { | function decimal_distance($lat1 = "", $lon1 = "", $lat2 = "", $lon2 = "") { | ||
$radius = 6371; | |||
$radius = | |||
$lat1 = deg2rad ($lat1); | $lat1 = deg2rad ($lat1); | ||
$lat2 = deg2rad ($lat2); | $lat2 = deg2rad ($lat2); | ||
$lon1 = deg2rad ($lon1); | $lon1 = deg2rad ($lon1); | ||
$lon2 = deg2rad ($lon2); | $lon2 = deg2rad ($lon2); | ||
$dlon = $lon2-$lon1; | $dlon = $lon2-$lon1; | ||
$dlat = $lat2-$lat1; | $dlat = $lat2-$lat1; | ||
Rivi 68: | Rivi 95: | ||
$d = $radius * $c; | $d = $radius * $c; | ||
return round($d,2); | return round($d,2); | ||
} | } | ||
Rivi 140: | Rivi 140: | ||
$chartospeech["0"] = "nolla"; | $chartospeech["0"] = "nolla"; | ||
$msg = ""; | $msg = ""; | ||
for ($tmp = 0; $tmp<strlen($callsign); $tmp++) { | for ($tmp = 0; $tmp < strlen($callsign); $tmp++) { | ||
$character = substr($callsign,$tmp,1); | $character = substr($callsign, $tmp, 1); | ||
/* don't say -9 */ | /* don't say -9 */ | ||
if ($character == "-") { | if ($character == "-") { | ||
return $msg; | return $msg; | ||
} | } | ||
$ | $vocal = $chartospeech[$character]; | ||
$msg.= $ | $msg.= $vocal; | ||
} | } | ||
return ($msg); | return ($msg); | ||
} | } | ||
$aprxrfloglen = count($aprxrflog); | |||
if ($aprxrfloglen > $maxloglines) $loglinestart = $aprxrfloglen-$maxloglines; else $loglinestart=0; | |||
if ($debug>1) echo "aprxrfloglen $aprxrfloglen maxloglines $maxloglines loglinestart $loglinestart\n"; | |||
for ($tmp = $loglinestart; $tmp < $aprxrfloglen; $tmp++) { | |||
$line = $aprxrflog[$tmp]; | |||
if (preg_match('/^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{3}) '.$repeater_call.' R (.+)>(.+):(.{1})(.+)/', $line, $matches)) { | |||
$callsign = strtolower(trim($matches[8])); | |||
if (strpos($callsign,">")) { | |||
/* Callsign parse failed (ugly trace packets) */ | |||
if ($debug>2) echo "Ugly callsign $callsign. Discard.\n"; | |||
continue; | |||
} | |||
if (strstr($matches[9],$repeatedmatch)) { | |||
/* digirepeated patcket, discard */ | |||
if ($debug>2) echo "Digirepeated packet. Discard.\n"; | |||
continue; | |||
} | |||
if (strpos("\!=/@", $matches[10])) { | |||
/* ! Position without timestamp (no APRS messaging), or Ultimeter 2000 WX Station */ | |||
/* = Position without timestamp (with APRS messaging) */ | |||
/* / Position with timestamp (no APRS messaging) */ | |||
/* @ Position with timestamp (with APRS messaging) */ | |||
} else { | |||
/* is not position format */ | |||
if ($debug>1) echo "Unknown position identification ". $matches[10].". Discard.\n"; | |||
continue; | |||
} | |||
if (preg_match('/([0-9]{2})([0-9]{2}).([0-9]{1,})N(.{1})([0-9]{3})([0-9]{2}).([0-9]{1,})E/', $matches[11], $plaincoords)) { | |||
/* coordinates are plain format */ | |||
$coordtype = "plain"; | |||
$lat = min_to_dec($plaincoords[1], $plaincoords[2], $plaincoords[3]); | |||
$long = min_to_dec(intval($plaincoords[5]), $plaincoords[6], $plaincoords[7]); | |||
} else { | |||
/* coordinates are packed */ | |||
$coordtype = "packed"; | |||
$y1 = ord(substr($matches[11],1,1)); | |||
$y2 = ord(substr($matches[11],2,1)); | |||
$y3 = ord(substr($matches[11],3,1)); | |||
$y4 = ord(substr($matches[11],4,1)); | |||
$x1 = ord(substr($matches[11],5,1)); | |||
$x2 = ord(substr($matches[11],6,1)); | |||
$x3 = ord(substr($matches[11],7,1)); | |||
$x4 = ord(substr($matches[11],8,1)); | |||
$lat = 90 - (($y1-33) * 91*91*91 + ($y2-33) * 91*91 + ($y3-33) * 91 + $y4-33) / 380926; | |||
$long = -180 + (($x1-33) * 91*91*91 + ($x2-33) * 91*91 + ($x3-33) * 91 + $x4-33) / 190463; | |||
} | |||
$distance = decimal_distance($repeater_lat, $repeater_lon, $lat, $long); | |||
if ($distance > $rangelimit) { | |||
if ($debug > 1) "Calculated distance $distance km. Invalid range limit $rangelimit. Discard\n"; | |||
continue; | |||
} | |||
$bearing = latlongbearing($repeater_lat, $repeater_lon, $lat, $long); | |||
$lastheard = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]); | |||
$parserdb[$callsign] = array("lastheard" => $lastheard, "distance" => $distance, "bearing" => $bearing, "lat" => $lat, "long" => $long, "coordtype" => $coordtype); | |||
} | |||
} | |||
ksort($parserdb); | ksort($parserdb); | ||
foreach ($parserdb as $callsign => $ | foreach ($parserdb as $callsign => $attcheddata) { | ||
$distance = $ | $distance = $attcheddata["distance"]; | ||
$lastheard = $ | $lastheard = $attcheddata["lastheard"]; | ||
if ($debug) echo "Call $callsign. "; | $lat = $attcheddata["lat"]; | ||
$long = $attcheddata["long"]; | |||
$coordtype = $attcheddata["coordtype"]; | |||
$bearing = $attcheddata["bearing"]; | |||
$lastheardtxt = date("r", $lastheard); | |||
$advertisedtime = $stationdb[$callsign]["advertisedtime"]; | |||
$advertisedtimetxt = date("r",$advertisedtime); | |||
if ($debug>0) echo "Call $callsign. Lat $lat. Long $long. Coordtype $coordtype. Distance $distance. Bearing $bearing. Lastheard $lastheardtxt. Advertised $advertisedtimetxt. "; | |||
if (array_key_exists($callsign, $stationdb)) { | if (array_key_exists($callsign, $stationdb)) { | ||
if ($debug) echo "Found from stationdb. "; | if ($debug>0) echo "Found from stationdb. "; | ||
if ($ | if ($advertisedtime < (utctimenow()-$floodprotect) && $lastheard>$stationdb[$callsign]["lastheard"]) { | ||
if ($debug) echo "Floodprotect active. "; | if ($debug>0) if ($advertisedtime < (utctimenow()-$floodprotect)) echo "Floodprotect expired. "; else echo "Floodprotect active. "; | ||
if ($distance < $maxdistance) { | if ($distance < $maxdistance) { | ||
/* | /* Exists in stationdb. Too old and inside circle */ | ||
if ($debug) echo "Inside | if ($debug>0) echo "Inside $maxdistance km cicle. Add to victims."; | ||
$victims[] = $callsign; | $victims[] = $callsign; | ||
$ | $advertisedtime = utctimenow(); | ||
} else { | } else { | ||
/* | /* Station too far */ | ||
if ($debug) echo "Outside | if ($debug>0) echo "Outside $maxdistance km circle. Skip."; | ||
} | } | ||
} else { | } else { | ||
if ($debug) echo "Floodprotect active | if ($debug>0) if ($advertisedtime < (utctimenow()-$floodprotect)) echo "Floodprotect expired. "; else echo "Floodprotect active. "; | ||
if ($debug>0) if ($lastheard>$stationdb[$callsign]["lastheard"]) echo "New packet. "; else echo "Old packed. "; | |||
if ($debug>0) echo "Skip."; | |||
} | } | ||
} else { | } else { | ||
if ($debug) echo "Not found from stationdb. "; | if ($debug>0) echo "Not found from stationdb. "; | ||
if ($distance < $maxdistance) { | if ($distance < $maxdistance) { | ||
if ($debug) echo "Inside | if ($debug>0) echo "Inside ${maxdistance}km circle. Add to victims."; | ||
$victims[] = $callsign; | $victims[] = $callsign; | ||
$ | $advertisedtime = utctimenow(); | ||
} else { | } else { | ||
if ($debug) echo "Outside | if ($debug>0) echo "Outside ${maxdistance}km circle. Skip."; | ||
} | } | ||
} | } | ||
if ($debug) echo "\n"; | $stationdb[$callsign]["lastheard"] = $lastheard; | ||
$stationdb[$callsign]["distance"] = $distance; | |||
$stationdb[$callsign]["bearing"] = $bearing; | |||
$stationdb[$callsign]["lat"] = $lat; | |||
$stationdb[$callsign]["long"] = $long; | |||
$stationdb[$callsign]["coordtype"] = $coordtype; | |||
$stationdb[$callsign]["advertisedtime"] = $advertisedtime; | |||
if ($debug>0) echo "\n"; | |||
} | } | ||
if ($debug>0) echo "Updating $stationdbfile\n"; | |||
file_put_contents($stationdbfile, serialize($stationdb)); | file_put_contents($stationdbfile, serialize($stationdb)); | ||
Rivi 204: | Rivi 278: | ||
$msg .= callsign2finnish($victim).", "; | $msg .= callsign2finnish($victim).", "; | ||
} | } | ||
$msg=substr($msg,0,-2); | $msg = substr($msg,0,-2); | ||
file_put_contents($tempwavetxt, utf8_decode($msg)); | if ($debug>0) echo "$msg\n"; | ||
system("/usr/bin/text2wave -F 8000 < ".$tempwavetxt." -o ".$tempwave); | if ($debug<1) file_put_contents($tempwavetxt, utf8_decode($msg)); | ||
system("/usr/sbin/tlbcmd \"port OH6RUC-Kaustinen; say -c ".$prefixwave."; say -c ".$tempwave."; say -c ".$suffixwave."\""); | if ($debug<1) system("/usr/bin/text2wave -F 8000 < ".$tempwavetxt." -o ".$tempwave); | ||
if ($debug<1) system("/usr/sbin/tlbcmd \"port OH6RUC-Kaustinen; say -c ".$prefixwave."; say -c ".$tempwave."; say -c ".$suffixwave."\""); | |||
} else { | } else { | ||
if ($debug) echo "Cannot advertise. Advertises denied by $denytxfile lock file.\n"; | if ($debug>0) echo "Cannot advertise. Advertises denied by $denytxfile lock file.\n"; | ||
} | } | ||
} | } | ||
?> | ?> | ||
</pre> | </pre> | ||
Tämä scripti on ajastettu crontabissa | |||
# Katsotaan onko kuuluvuusalueella uusia APRS-asemia ja mainostetaan jos on | |||
4,8,12,16,20,24,28,32,36,40,44,48,52,56 * * * * tlb /opt/thelinkbox/scripts/aprs-repeater-advertiser.php > /dev/null |
Nykyinen versio 21. joulukuuta 2010 kello 18.05
Scripti joka tutkii ajastettuna OH6RUC toistimen linuxissa aprx ohjelman tekemää /tmp/aprx-rf.log tiedostoa. Jos logissa näkyy APRS-asema joka on lähempänä kuin 30km OH6RUC toistinta ja kyseistä APRS-asemaa ei ole kuultu edellisen 24h kuluessa, ja toistin on vapaana, scripti aukaisee toistimen ja mainostaa iseaään APRS-asemalle puheella. Puhe generoidaan festival puhesyntetisaattorilla.
"Tervetuloa OH6RUC toistinaseman kuuluvuusalueelle OH6KTT. Minä olen Kaustisen OH6RUC toistinasema taajuudella 434.900 MHz. Ripiitterierotukseni on -2 MHz. Toistan. Ripiitterierotus on -2 MHz. Automaattinen tiedote ripiitteriä lähestyville APRS-asemille päättyy."
Sama scripti pitää logia suoraan RF:llä kuulluista APRS-asemista.
Ideoita jatkokehitystä varten:
- 2m tropokelit on mahdollista havaita suoraan RF:llä kuulluista asemista
- Pitkän historian avulla db:stä voisi saada selville digiripiitterin kuuntelukyky eri ilmansuuntiin
#!/usr/bin/php -q <?php ini_set('memory_limit','50M'); /* aprs-repeater-advertiser.php v1.11 - repeater advertiser to APRS users Copyright (C) 2010 Kari Karvonen <oh6ktt@toimii.net> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ $debug = 0; /* 0 = no debug, 1 = little debug, 2 = more debug, 3 = annoying */ $aprxrflogfile = "/tmp/aprx-rf.log"; $stationdbfile = "/tmp/oh6ruc-aprs-db.txt"; $repeater_call = "OH6RUC"; /* need to match aprs-rf.log */ $repeater_lat = "63.53666"; $repeater_lon = "23.69180"; $floodprotect = 60*60*24; /* after this time old station will be notified again. Seconds. */ $maxdistance = 30; /* km */ $maxloglines = 1000; /* max loglines to analyze (tail) */ $denytxfile = "/tmp/ptt-on"; /* if this file exist, no advertises will be send */ $prefixwave = "/opt/thelinkbox/wav/aprs-repeater-advertiser-1.wav"; /* wave before callsigns */ $suffixwave = "/opt/thelinkbox/wav/aprs-repeater-advertiser-2.wav"; /* wave after callsigns */ $tempwavetxt = "/tmp/aprs-repeater-advertiser.txt"; $tempwave = "/tmp/aprs-repeater-advertiser.wav"; $repeatedmatch = ",OH"; /* if this is exists on path (eg APRS,OH6RUC*,OH8RDU*,WIDE) assume packet digirepeated and discard it */ $rangelimit = 2000; /* if range more than this then range is invalid. km. */ /* code begins */ $parserdb = array(); $victims = array(); $stationdb = unserialize(@file_get_contents($stationdbfile)); if (empty($stationdb)) $stationdb = array(); $aprxrflog = @file($aprxrflogfile); if ($aprxrflog == false) die("Cannot open $aprxrflogfile\n"); function min_to_dec($deg, $min, $decsec) { return($deg/1.0 + $min/60.0 + $decsec/10000.0); } function utctimenow() { $utcoffset = intval(date("O")/100)*60; return (time()-$utcoffset); } function latlongbearing($lat1, $lon1, $lat2, $lon2) { $lat1 = deg2rad($lat1); $lat2 = deg2rad($lat2); $lon1 = deg2rad ($lon1); $lon2 = deg2rad ($lon2); $dLon = $lon2-$lon1; $y = sin($dLon) * cos($lat2); $x = cos($lat1) * sin($lat2) - sin($lat1)*cos($lat2)*cos($dLon); $bearrad = atan2($y, $x); $beardeg = (rad2deg($bearrad)+360)%360; return ($beardeg); } function decimal_distance($lat1 = "", $lon1 = "", $lat2 = "", $lon2 = "") { $radius = 6371; $lat1 = deg2rad ($lat1); $lat2 = deg2rad ($lat2); $lon1 = deg2rad ($lon1); $lon2 = deg2rad ($lon2); $dlon = $lon2-$lon1; $dlat = $lat2-$lat1; $sinlat = sin($dlat/2); $sinlon = sin($dlon/2); $a = ($sinlat * $sinlat) + cos($lat1) * cos($lat2) * ($sinlon*$sinlon); $c = 2 * asin(min(1,sqrt($a))); $d = $radius * $c; return round($d,2); } function callsign2finnish($callsign) { $chartospeech = array(); $chartospeech["-"] = "viiva"; $chartospeech["a"] = "aa"; $chartospeech["b"] = "bee"; $chartospeech["c"] = "see"; $chartospeech["d"] = "dee"; $chartospeech["e"] = "ee"; $chartospeech["f"] = "äf"; $chartospeech["g"] = "gee"; $chartospeech["h"] = "hoo"; $chartospeech["i"] = "hee"; $chartospeech["j"] = "jii"; $chartospeech["k"] = "koo"; $chartospeech["l"] = "äl"; $chartospeech["m"] = "äm"; $chartospeech["n"] = "äm"; $chartospeech["o"] = "oo"; $chartospeech["p"] = "pee"; $chartospeech["q"] = "kuu"; $chartospeech["r"] = "är"; $chartospeech["s"] = "äs"; $chartospeech["t"] = "tee"; $chartospeech["u"] = "uu"; $chartospeech["v"] = "vee"; $chartospeech["w"] = "tuplavee"; $chartospeech["x"] = "äks"; $chartospeech["y"] = "yy"; $chartospeech["z"] = "tseta"; $chartospeech["å"] = "oo"; $chartospeech["ä"] = "ää"; $chartospeech["ö"] = "öö"; $chartospeech["1"] = "yks"; $chartospeech["2"] = "kaks"; $chartospeech["3"] = "kol"; $chartospeech["4"] = "nel"; $chartospeech["5"] = "viis"; $chartospeech["6"] = "kuus"; $chartospeech["7"] = "seiska"; $chartospeech["8"] = "kasi"; $chartospeech["9"] = "ysi"; $chartospeech["0"] = "nolla"; $msg = ""; for ($tmp = 0; $tmp < strlen($callsign); $tmp++) { $character = substr($callsign, $tmp, 1); /* don't say -9 */ if ($character == "-") { return $msg; } $vocal = $chartospeech[$character]; $msg.= $vocal; } return ($msg); } $aprxrfloglen = count($aprxrflog); if ($aprxrfloglen > $maxloglines) $loglinestart = $aprxrfloglen-$maxloglines; else $loglinestart=0; if ($debug>1) echo "aprxrfloglen $aprxrfloglen maxloglines $maxloglines loglinestart $loglinestart\n"; for ($tmp = $loglinestart; $tmp < $aprxrfloglen; $tmp++) { $line = $aprxrflog[$tmp]; if (preg_match('/^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{3}) '.$repeater_call.' R (.+)>(.+):(.{1})(.+)/', $line, $matches)) { $callsign = strtolower(trim($matches[8])); if (strpos($callsign,">")) { /* Callsign parse failed (ugly trace packets) */ if ($debug>2) echo "Ugly callsign $callsign. Discard.\n"; continue; } if (strstr($matches[9],$repeatedmatch)) { /* digirepeated patcket, discard */ if ($debug>2) echo "Digirepeated packet. Discard.\n"; continue; } if (strpos("\!=/@", $matches[10])) { /* ! Position without timestamp (no APRS messaging), or Ultimeter 2000 WX Station */ /* = Position without timestamp (with APRS messaging) */ /* / Position with timestamp (no APRS messaging) */ /* @ Position with timestamp (with APRS messaging) */ } else { /* is not position format */ if ($debug>1) echo "Unknown position identification ". $matches[10].". Discard.\n"; continue; } if (preg_match('/([0-9]{2})([0-9]{2}).([0-9]{1,})N(.{1})([0-9]{3})([0-9]{2}).([0-9]{1,})E/', $matches[11], $plaincoords)) { /* coordinates are plain format */ $coordtype = "plain"; $lat = min_to_dec($plaincoords[1], $plaincoords[2], $plaincoords[3]); $long = min_to_dec(intval($plaincoords[5]), $plaincoords[6], $plaincoords[7]); } else { /* coordinates are packed */ $coordtype = "packed"; $y1 = ord(substr($matches[11],1,1)); $y2 = ord(substr($matches[11],2,1)); $y3 = ord(substr($matches[11],3,1)); $y4 = ord(substr($matches[11],4,1)); $x1 = ord(substr($matches[11],5,1)); $x2 = ord(substr($matches[11],6,1)); $x3 = ord(substr($matches[11],7,1)); $x4 = ord(substr($matches[11],8,1)); $lat = 90 - (($y1-33) * 91*91*91 + ($y2-33) * 91*91 + ($y3-33) * 91 + $y4-33) / 380926; $long = -180 + (($x1-33) * 91*91*91 + ($x2-33) * 91*91 + ($x3-33) * 91 + $x4-33) / 190463; } $distance = decimal_distance($repeater_lat, $repeater_lon, $lat, $long); if ($distance > $rangelimit) { if ($debug > 1) "Calculated distance $distance km. Invalid range limit $rangelimit. Discard\n"; continue; } $bearing = latlongbearing($repeater_lat, $repeater_lon, $lat, $long); $lastheard = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]); $parserdb[$callsign] = array("lastheard" => $lastheard, "distance" => $distance, "bearing" => $bearing, "lat" => $lat, "long" => $long, "coordtype" => $coordtype); } } ksort($parserdb); foreach ($parserdb as $callsign => $attcheddata) { $distance = $attcheddata["distance"]; $lastheard = $attcheddata["lastheard"]; $lat = $attcheddata["lat"]; $long = $attcheddata["long"]; $coordtype = $attcheddata["coordtype"]; $bearing = $attcheddata["bearing"]; $lastheardtxt = date("r", $lastheard); $advertisedtime = $stationdb[$callsign]["advertisedtime"]; $advertisedtimetxt = date("r",$advertisedtime); if ($debug>0) echo "Call $callsign. Lat $lat. Long $long. Coordtype $coordtype. Distance $distance. Bearing $bearing. Lastheard $lastheardtxt. Advertised $advertisedtimetxt. "; if (array_key_exists($callsign, $stationdb)) { if ($debug>0) echo "Found from stationdb. "; if ($advertisedtime < (utctimenow()-$floodprotect) && $lastheard>$stationdb[$callsign]["lastheard"]) { if ($debug>0) if ($advertisedtime < (utctimenow()-$floodprotect)) echo "Floodprotect expired. "; else echo "Floodprotect active. "; if ($distance < $maxdistance) { /* Exists in stationdb. Too old and inside circle */ if ($debug>0) echo "Inside $maxdistance km cicle. Add to victims."; $victims[] = $callsign; $advertisedtime = utctimenow(); } else { /* Station too far */ if ($debug>0) echo "Outside $maxdistance km circle. Skip."; } } else { if ($debug>0) if ($advertisedtime < (utctimenow()-$floodprotect)) echo "Floodprotect expired. "; else echo "Floodprotect active. "; if ($debug>0) if ($lastheard>$stationdb[$callsign]["lastheard"]) echo "New packet. "; else echo "Old packed. "; if ($debug>0) echo "Skip."; } } else { if ($debug>0) echo "Not found from stationdb. "; if ($distance < $maxdistance) { if ($debug>0) echo "Inside ${maxdistance}km circle. Add to victims."; $victims[] = $callsign; $advertisedtime = utctimenow(); } else { if ($debug>0) echo "Outside ${maxdistance}km circle. Skip."; } } $stationdb[$callsign]["lastheard"] = $lastheard; $stationdb[$callsign]["distance"] = $distance; $stationdb[$callsign]["bearing"] = $bearing; $stationdb[$callsign]["lat"] = $lat; $stationdb[$callsign]["long"] = $long; $stationdb[$callsign]["coordtype"] = $coordtype; $stationdb[$callsign]["advertisedtime"] = $advertisedtime; if ($debug>0) echo "\n"; } if ($debug>0) echo "Updating $stationdbfile\n"; file_put_contents($stationdbfile, serialize($stationdb)); $msg = ""; if (count($victims) == 0) { /* do nothing */ } else { if (!file_exists($denytxfile)) { @unlink($tempwavetxt); @unlink($tempwave); foreach ($victims as $victim) { $msg .= callsign2finnish($victim).", "; } $msg = substr($msg,0,-2); if ($debug>0) echo "$msg\n"; if ($debug<1) file_put_contents($tempwavetxt, utf8_decode($msg)); if ($debug<1) system("/usr/bin/text2wave -F 8000 < ".$tempwavetxt." -o ".$tempwave); if ($debug<1) system("/usr/sbin/tlbcmd \"port OH6RUC-Kaustinen; say -c ".$prefixwave."; say -c ".$tempwave."; say -c ".$suffixwave."\""); } else { if ($debug>0) echo "Cannot advertise. Advertises denied by $denytxfile lock file.\n"; } } ?>
Tämä scripti on ajastettu crontabissa
# Katsotaan onko kuuluvuusalueella uusia APRS-asemia ja mainostetaan jos on 4,8,12,16,20,24,28,32,36,40,44,48,52,56 * * * * tlb /opt/thelinkbox/scripts/aprs-repeater-advertiser.php > /dev/null