Skip to content

Instantly share code, notes, and snippets.

@ifsnop
Last active April 19, 2026 10:43
Show Gist options
  • Select an option

  • Save ifsnop/5508df3ed3568aae1fbec26a263268bd to your computer and use it in GitHub Desktop.

Select an option

Save ifsnop/5508df3ed3568aae1fbec26a263268bd to your computer and use it in GitHub Desktop.
testing ogn aprs network with minimum php script (implementing keep alive msgs)
<?php
// time echo user KOK pass -1 vers tst 0.1 filter r/40/-3/600 | nc glidern1.glidernet.org 14580
$host = "glidern1.glidernet.org"; // Cambia por la IP o dominio
$port = 14580; // Cambia por el puerto
$user = "KOK";
$pass = makepass($user);
$message_hello = "user {$user} pass {$pass} vers tst 0.1 filter r/40/-3/600" . PHP_EOL; // Texto a enviar
$message_keepalive = "#" . PHP_EOL;
$interval = 600; // 10 minutos en segundos
// Crear conexión
$socket = @stream_socket_client("tcp://{$host}:{$port}", $errno, $errstr, 30);
if (!$socket) {
logger("E", "No se pudo conectar: $errstr ($errno)"); exit(-1);
}
logger("N", "Conectado a $host:$port");
fwrite($socket, $message_hello);
// Configurar el socket en no-bloqueante para poder enviar y leer a la vez
stream_set_blocking($socket, false);
$lastSent = time();
$buffer = "";
while (true) {
$now = time();
// Enviar mensaje cada $interval segundos
if ($now - $lastSent >= $interval) {
$bytesWritten = @fwrite($socket, $message_keepalive);
if ($bytesWritten === false) {
die("Error: no se pudo escribir en el socket\n");
} elseif ($bytesWritten < strlen($message_keepalive)) {
die("Advertencia: solo se enviaron $bytesWritten de " . strlen($message_keepalive) . " bytes\n");
} else {
logger("V", $message_keepalive);
}
$lastSent = $now;
// print "." . PHP_EOL;
}
$readSockets = [$socket];
$writeSockets = null;
$exceptSockets = null;
// Esperar hasta 1 segundo a que haya datos disponibles
$numChanged = stream_select($readSockets, $writeSockets, $exceptSockets, 1);
if ($numChanged === false) {
die("Error en stream_select()\n");
} else if ($numChanged > 0) {
// Leer datos disponibles
$buffer .= fread($socket, 4096);
while ( ($pos = strpos($buffer, "\n")) !== false ) {
$line = substr($buffer, 0, $pos + 1);
$buffer = substr($buffer, $pos + 1);
}
$line = trim($line);
logger("V" , $line);
// # aprsc 2.1.4-g408ed49 2 Nov 2019 14:48:58 GMT GLIDERN4 192.168.1.14:14580
}
if (feof($socket)) {
die("Conexión cerrada por el servidor\n");
}
// print "+" . PHP_EOL;
}
fclose($socket);
function logger($level, $message) {
$microtime = microtime(true);
$milliseconds = sprintf("%03d", ($microtime - floor($microtime)) * 1000);
// Formatear fecha y hora
$timestamp = date("Y-m-d H:i:s", (int)$microtime) . "." . $milliseconds;
// Construir línea de log
$logLine = sprintf("%s %s> %s" . PHP_EOL, $timestamp, strtoupper($level), $message);
// Imprimir por stderr
fwrite(STDERR, $logLine);
return true;
}
/// Genera la contraseña para logarse en la red APRS del OGN
function makepass($str) {
$str = strtoupper($str);
$pass = 29666;
$i = 0;
while ($i < strlen($str)) {
$pass = $pass ^ ord($str[$i])*256;
if ( $i+1 < strlen($str) )
$pass = $pass ^ ord($str[$i+1]);
$i+=2;
}
$pass &= 32767;
return $pass;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment