#!/usr/bin/php5 . */ $PORT = 2000; # TCP server socket number $DEVICE = $argv[1]; $BAUD_RATE = 38400; $CACHE_SIZE = 200; $CACHE_FILTER = array('!AIVDM,'); error_reporting(E_ALL); $debug = true; $cache = array(); $clients = array(); $cacheIndex = 0; $c = stream_context_create(array('dio' => array('data_rate' => $BAUD_RATE, 'data_bits' => 8, 'stop_bits' => 1, 'parity' => 0, 'flow_control' => 0, 'is_canonical' => 0, 'timeout_secs' => 1, 'timeout_usecs' => 1000))); $stream = fopen("dio.serial://" . $DEVICE, 'r+', false, $c); if (!$stream) { die("Unable to open NMEA port $DEVICE\n"); } if (($server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) { die("Failed to create socket: " . socket_strerror($server) . "\n"); } if (($ret = socket_bind($server, '0.0.0.0', $PORT)) < 0) { die("Failed to bind socket: " . socket_strerror($ret) . "\n"); } if (($ret = socket_listen($server)) < 0) { die("Failed to listen to socket: " . socket_strerror($ret) . "\n"); } socket_set_nonblock($server); while (!feof($stream)) { $read = rtrim(fgets($stream, 4000)); if ($debug) echo "READ: $read\n"; acceptNewClients(); sendMessageToClients($read . "\r\n"); } pclose($stream); return; function acceptNewClients() { global $clients, $cache, $server, $debug; while (($newClient = @socket_accept($server)) !== false) { if ($newClient < 0) { echo "Error on accept: " . socket_strerror($newClient) . "\n"; } else { $clients[] = $newClient; if ($debug) { if (socket_getpeername($newClient, $address)) { echo "New client ".$address."\n"; } else { echo "New client ".$newClient."\n"; } } sendCache($newClient); } } } function sendCache($client) { global $cache, $clients, $debug; $i = 0; foreach ($cache as $msg) { if (!updateClient($client, $msg)) { socket_close($client); unset($clients[$key]); return; } $i++; } if ($debug) echo "Sent cached ".$i." messages.\n"; } function sendMessageToClients($msg) { global $clients, $cache, $cacheIndex, $CACHE_SIZE, $CACHE_FILTER; foreach ($clients as $key => $client) { if (!updateClient($client, $msg)) { socket_close($client); unset($clients[$key]); } } foreach ($CACHE_FILTER as $filter) { if (strpos($msg, $filter) !== false) { $cacheIndex += 1; $cache[$cacheIndex] = $msg; if ($cacheIndex > $CACHE_SIZE) { unset($cache[$cacheIndex - $CACHE_SIZE]); } break; } } } function updateClient($client, $msg) { global $debug; if ($debug) echo "writing ".strlen($msg)." bytes to client $client\n"; for ($written = 0; $written < strlen($msg); $written += $fwrite) { $fwrite = socket_write($client, substr($msg, $written)); if ($fwrite === false) { return false; } if ($debug) echo "written $fwrite to client $client\n"; } return $written; } ?>