<?php function getMMDVMHostVersion() { // returns creation-time or version of MMDVMHost as version-number $filename = MMDVMHOSTPATH."/MMDVMHost"; exec($filename." -v 2>&1", $output); if (!startsWith(substr($output[0],18,8),"20")) { return getMMDVMHostFileVersion(); } else { return substr($output[0],18,8)." (compiled ".getMMDVMHostFileVersion().")"; } } function getMMDVMHostFileVersion() { // returns creation-time of MMDVMHost as version-number $filename = MMDVMHOSTPATH."/MMDVMHost"; if (file_exists($filename)) { return date("d M Y", filectime($filename)); } } function getMMDVMConfig() { // loads MMDVM.ini into array for further use $conf = array(); if ($configs = fopen(MMDVMINIPATH."/".MMDVMINIFILENAME, 'r')) { while ($config = fgets($configs)) { array_push($conf, trim ( $config, " \t\n\r\0\x0B")); } fclose($configs); } return $conf; } function getYSFGatewayConfig() { // loads YSFGateway.ini into array for further use $conf = array(); if ($configs = fopen(YSFGATEWAYINIPATH."/".YSFGATEWAYINIFILENAME, 'r')) { while ($config = fgets($configs)) { array_push($conf, trim ( $config, " \t\n\r\0\x0B")); } fclose($configs); } return $conf; } function getCallsign($mmdvmconfigs) { // returns Callsign from MMDVM-config return getConfigItem("General", "Callsign", $mmdvmconfigs); } function getConfigItem($section, $key, $configs) { // retrieves the corresponding config-entry within a [section] $sectionpos = array_search("[" . $section . "]", $configs) + 1; $len = count($configs); while(startsWith($configs[$sectionpos],$key."=") === false && $sectionpos <= ($len) ) { if (startsWith($configs[$sectionpos],"[")) { return null; } $sectionpos++; } return substr($configs[$sectionpos], strlen($key) + 1); } function getEnabled ($mode, $mmdvmconfigs) { // returns enabled/disabled-State of mode return getConfigItem($mode, "Enable", $mmdvmconfigs); } function showMode($mode, $mmdvmconfigs) { // shows if mode is enabled or not. ?> <td><span class="label <?php if (getEnabled($mode, $mmdvmconfigs) == 1) { switch ($mode) { case "D-Star Network": if (getConfigItem("D-Star Network", "GatewayAddress", $mmdvmconfigs) == "localhost" || getConfigItem("D-Star Network", "GatewayAddress", $mmdvmconfigs) == "127.0.0.1") { if (isProcessRunning(IRCDDBGATEWAY)) { echo "label-success"; } else { echo "label-danger\" title=\"ircddbgateway is down!"; } } else { echo "label-default\" title=\"Remote gateway configured - not checked!"; } break; case "System Fusion Network": if (getConfigItem("System Fusion Network", "GwyAddress", $mmdvmconfigs) == "localhost" || getConfigItem("System Fusion Network", "GwyAddress", $mmdvmconfigs) == "127.0.0.1") { if (isProcessRunning("YSFGateway")) { echo "label-success"; } else { echo "label-danger\" title=\"YSFGateway is down!"; } } else { echo "label-default\" title=\"Remote gateway configured - not checked!"; } break; default: if (isProcessRunning("MMDVMHost")) { echo "label-success"; } else { echo "label-danger\" title=\"MMDVMHost is down!"; } } } else { echo "label-default"; } ?>"><?php echo $mode ?></span></td> <?php } function getMMDVMLog() { // Open Logfile and copy loglines into LogLines-Array() $logPath = MMDVMLOGPATH."/".MMDVMLOGPREFIX."-".date("Y-m-d").".log"; $logLines = explode("\n", `grep M: $logPath`); return $logLines; } function getShortMMDVMLog() { // Open Logfile and copy loglines into LogLines-Array() $logPath = MMDVMLOGPATH."/".MMDVMLOGPREFIX."-".date("Y-m-d").".log"; //$logLines = explode("\n", `tail -n100 $logPath`); $logLines = explode("\n", `egrep -h "from|end|watchdog|lost" $logPath | tail -4`); return $logLines; } function getYSFGatewayLog() { // Open Logfile and copy loglines into LogLines-Array() $logPath = YSFGATEWAYLOGPATH."/".YSFGATEWAYLOGPREFIX."-".date("Y-m-d").".log"; $logLines = explode("\n", `grep D: $logPath`); return $logLines; } // 00000000001111111111222222222233333333334444444444555555555566666666667777777777888888888899999999990000000000111111111122 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901 // M: 2016-04-29 00:15:00.013 D-Star, received network header from DG9VH /ZEIT to CQCQCQ via DCS002 S // M: 2016-04-29 19:43:21.839 DMR Slot 2, received network voice header from DL1ESZ to TG 9 // M: 2016-04-30 14:57:43.072 DMR Slot 2, received RF voice header from DG9VH to 5000 // M: 2016-09-16 09:14:12.886 P25, received RF from DF2ET to TG10100 function getHeardList($logLines, $onlyLast) { $heardList = array(); $ts1duration = ""; $ts1loss = ""; $ts1ber = ""; $ts2duration = ""; $ts2loss = ""; $ts2ber = ""; $dstarduration = ""; $dstarloss = ""; $dstarber = ""; $ysfduration = ""; $ysfloss = ""; $ysfber = ""; foreach ($logLines as $logLine) { $duration = ""; $loss = ""; $ber = ""; //removing invalid lines if(strpos($logLine,"BS_Dwn_Act")) { continue; } else if(strpos($logLine,"invalid access")) { continue; } else if(strpos($logLine,"received RF header for wrong repeater")) { continue; } else if(strpos($logLine,"unable to decode the network CSBK")) { continue; } else if(strpos($logLine,"overflow in the DMR slot RF queue")) { continue; } if(strpos($logLine,"end of") || strpos($logLine,"watchdog has expired") || strpos($logLine,"ended RF data") || strpos($logLine,"ended network")) { $lineTokens = explode(", ",$logLine); if (array_key_exists(2,$lineTokens)) { $duration = strtok($lineTokens[2], " "); } if (array_key_exists(3,$lineTokens)) { $loss = $lineTokens[3]; } // if RF-Packet, no LOSS would be reported, so BER is in LOSS position if (startsWith($loss,"BER")) { $ber = substr($loss, 5); $loss = ""; } else { $loss = strtok($loss, " "); if (array_key_exists(4,$lineTokens)) { $ber = substr($lineTokens[4], 5); } } if (strpos($logLine,"ended RF data") || strpos($logLine,"ended network")) { switch (substr($logLine, 27, strpos($logLine,",") - 27)) { case "DMR Slot 1": $ts1duration = "SMS"; break; case "DMR Slot 2": $ts2duration = "SMS"; break; } } else { switch (substr($logLine, 27, strpos($logLine,",") - 27)) { case "D-Star": $dstarduration = $duration; $dstarloss = $loss; $dstarber = $ber; break; case "DMR Slot 1": $ts1duration = $duration; $ts1loss = $loss; $ts1ber = $ber; break; case "DMR Slot 2": $ts2duration = $duration; $ts2loss = $loss; $ts2ber = $ber; break; case "YSF": $ysfduration = $duration; $ysfloss = $loss; $ysfber = $ber; break; case "P25": $p25duration = $duration; $p25loss = $loss; $p25ber = $ber; break; } } } $timestamp = substr($logLine, 3, 19); $mode = substr($logLine, 27, strpos($logLine,",") - 27); $callsign2 = substr($logLine, strpos($logLine,"from") + 5, strpos($logLine,"to") - strpos($logLine,"from") - 6); $callsign = $callsign2; if (strpos($callsign2,"/") > 0) { $callsign = substr($callsign2, 0, strpos($callsign2,"/")); } $callsign = trim($callsign); $id =""; if ($mode == "D-Star") { $id = substr($callsign2, strpos($callsign2,"/") + 1); } $target = substr($logLine, strpos($logLine, "to") + 3); $source = "RF"; if (strpos($logLine,"network") > 0 ) { $source = "Net"; } switch ($mode) { case "D-Star": $duration = $dstarduration; $loss = $dstarloss; $ber = $dstarber; break; case "DMR Slot 1": $duration = $ts1duration; $loss = $ts1loss; $ber = $ts1ber; break; case "DMR Slot 2": $duration = $ts2duration; $loss = $ts2loss; $ber = $ts2ber; break; case "YSF": $duration = $ysfduration; $loss = $ysfloss; $ber = $ysfber; break; case "P25": $duration = $p25duration; $loss = $p25loss; $ber = $p25ber; break; } // Callsign or ID should be less than 11 chars long, otherwise it could be errorneous if ( strlen($callsign) < 11 ) { array_push($heardList, array($timestamp, $mode, $callsign, $id, $target, $source, $duration, $loss, $ber)); $duration = ""; $loss =""; $ber = ""; if ($onlyLast && count($heardList )> 4) { return $heardList; } } } return $heardList; } function getLastHeard($logLines, $onlyLast) { //returns last heard list from log $lastHeard = array(); $heardCalls = array(); $heardList = getHeardList($logLines, $onlyLast); $counter = 0; foreach ($heardList as $listElem) { if ( ($listElem[1] == "D-Star") || ($listElem[1] == "YSF") || ($listElem[1] == "P25") || (startsWith($listElem[1], "DMR")) ) { if(!(array_search($listElem[2]."#".$listElem[1].$listElem[3], $heardCalls) > -1)) { array_push($heardCalls, $listElem[2]."#".$listElem[1].$listElem[3]); array_push($lastHeard, $listElem); $counter++; } } } return $lastHeard; } function getActualMode($metaLastHeard, $mmdvmconfigs) { // returns mode of repeater actual working in $listElem = $metaLastHeard[0]; $timestamp = new DateTime($listElem[0]); $mode = $listElem[1]; if (startsWith($mode, "DMR")) { $mode = "DMR"; } if ($listElem[6] ==="") { return $mode; } else { $now = new DateTime(); $hangtime = getConfigItem("General", "ModeHang", $mmdvmconfigs); if ($hangtime != "") { $timestamp->add(new DateInterval('PT' . $hangtime . 'S')); } else { $source = $listElem[6]; if ($source === "Network") { $hangtime = getConfigItem("General", "NetModeHang", $mmdvmconfigs); } else { $hangtime = getConfigItem("General", "RFModeHang", $mmdvmconfigs); } $timestamp->add(new DateInterval('PT' . $hangtime . 'S')); } if ($now->format('U') > $timestamp->format('U')) { return "idle"; } else { return $mode; } } } function getDSTARLinks() { // returns link-states of all D-Star-modules if (filesize(LINKLOGPATH."/Links.log") == 0) { return "not linked"; } $out = "<table>"; if ($linkLog = fopen(LINKLOGPATH."/Links.log",'r')) { while ($linkLine = fgets($linkLog)) { $linkDate = " "; $protocol = " "; $linkType = " "; $linkSource = " "; $linkDest = " "; $linkDir = " "; // Reflector-Link, sample: // 2011-09-22 02:15:06: DExtra link - Type: Repeater Rptr: DB0LJ B Refl: XRF023 A Dir: Outgoing // 2012-04-03 08:40:07: DPlus link - Type: Dongle Rptr: DB0ERK B Refl: REF006 D Dir: Outgoing // 2012-04-03 08:40:07: DCS link - Type: Repeater Rptr: DB0ERK C Refl: DCS001 C Dir: Outgoing if(preg_match_all('/^(.{19}).*(D[A-Za-z]*).*Type: ([A-Za-z]*).*Rptr: (.{8}).*Refl: (.{8}).*Dir: (.{8})/',$linkLine,$linx) > 0){ $linkDate = $linx[1][0]; $protocol = $linx[2][0]; $linkType = $linx[3][0]; $linkSource = $linx[4][0]; $linkDest = $linx[5][0]; $linkDir = $linx[6][0]; } // CCS-Link, sample: // 2013-03-30 23:21:53: CCS link - Rptr: PE1AGO C Remote: PE1KZU Dir: Incoming if(preg_match_all('/^(.{19}).*(CC[A-Za-z]*).*Rptr: (.{8}).*Remote: (.{8}).*Dir: (.{8})/',$linkLine,$linx) > 0){ $linkDate = $linx[1][0]; $protocol = $linx[2][0]; $linkType = $linx[2][0]; $linkSource = $linx[3][0]; $linkDest = $linx[4][0]; $linkDir = $linx[5][0]; } // Dongle-Link, sample: // 2011-09-24 07:26:59: DPlus link - Type: Dongle User: DC1PIA Dir: Incoming // 2012-03-14 21:32:18: DPlus link - Type: Dongle User: DC1PIA Dir: Incoming if(preg_match_all('/^(.{19}).*(D[A-Za-z]*).*Type: ([A-Za-z]*).*User: (.{6,8}).*Dir: (.*)$/',$linkLine,$linx) > 0){ $linkDate = $linx[1][0]; $protocol = $linx[2][0]; $linkType = $linx[3][0]; $linkSource = " "; $linkDest = $linx[4][0]; $linkDir = $linx[5][0]; } $out .= "<tr><td>" . $linkSource . "</td><td> " . $protocol . "-link</td><td> to </td><td>" . $linkDest . "</td><td> " . $linkDir . "</td></tr>"; } } $out .= "</table>"; fclose($linkLog); return $out; } function getActualLink($logLines, $mode) { // returns actual link state of specific mode //M: 2016-05-02 07:04:10.504 D-Star link status set to "Verlinkt zu DCS002 S" //M: 2016-04-03 16:16:18.638 DMR Slot 2, received network voice header from 4000 to 2625094 //M: 2016-04-03 19:30:03.099 DMR Slot 2, received network voice header from 4020 to 2625094 switch ($mode) { case "D-Star": if (isProcessRunning(IRCDDBGATEWAY)) { return getDSTARLinks(); } else { return "ircddbgateway not running!"; } break; case "DMR Slot 1": foreach ($logLines as $logLine) { if(strpos($logLine,"unable to decode the network CSBK")) { continue; } else if(substr($logLine, 27, strpos($logLine,",") - 27) == "DMR Slot 1") { $to = ""; if (strpos($logLine,"to")) { $to = trim(substr($logLine, strpos($logLine,"to") + 3)); } if ($to !== "") { return $to; } } } return "not linked"; break; case "DMR Slot 2": foreach ($logLines as $logLine) { if(strpos($logLine,"unable to decode the network CSBK")) { continue; } else if(substr($logLine, 27, strpos($logLine,",") - 27) == "DMR Slot 2") { $to = ""; if (strpos($logLine,"to")) { $to = trim(substr($logLine, strpos($logLine,"to") + 3)); } if ($to !== "") { return $to; } } } return "not linked"; break; } return "something went wrong!"; } function getActualReflector($logLines, $mode) { // returns actual link state of specific mode //M: 2016-05-02 07:04:10.504 D-Star link status set to "Verlinkt zu DCS002 S" //M: 2016-04-03 16:16:18.638 DMR Slot 2, received network voice header from 4000 to 2625094 //M: 2016-04-03 19:30:03.099 DMR Slot 2, received network voice header from 4020 to 2625094 foreach ($logLines as $logLine) { if(substr($logLine, 27, strpos($logLine,",") - 27) == "DMR Slot 2") { $from = substr($logLine, strpos($logLine,"from") + 5, strpos($logLine,"to") - strpos($logLine,"from") - 6); if (strlen($from) == 4 && startsWith($from,"4")) { if ($from == "4000") { return "Reflector not linked"; } else { return "Reflector ".$from; } } $source = "RF"; if (strpos($logLine,"network") > 0 ) { $source = "Net"; } if ( $source == "RF") { $to = substr($logLine, strpos($logLine, "to") + 3); if (strlen($to) < 6 && startsWith($to, "4")) { return "Reflector ".$to." (not cfmd)"; } } } } return "Reflector not linked"; } function getActiveYSFReflectors($logLines) { // 00000000001111111111222222222233333333334444444444555555555566666666667777777777888888888899999999990000000000111111111122 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901 // D: 2016-06-11 19:09:31.371 Have reflector status reply from 89164/FUSIONBE2 /FusionBelgium /002 $reflectors = Array(); $reflectorlist = Array(); foreach ($logLines as $logLine) { if (strpos($logLine, "Have reflector status reply from")) { $timestamp = substr($logLine, 3, 19); $timestamp2 = new DateTime($timestamp); $now = new DateTime(); $timestamp2->add(new DateInterval('PT2H')); if ($now->format('U') <= $timestamp2->format('U')) { $str = substr($logLine, 60); $id = strtok($str, "/"); $name = strtok("/"); $description = strtok("/"); $concount = strtok("/"); if(!(array_search($name, $reflectors) > -1)) { array_push($reflectors,$name); array_push($reflectorlist, array($name, $description, $id, $concount, $timestamp)); } } } } array_multisort($reflectorlist); return $reflectorlist; } function getName($callsign) { if (is_numeric($callsign)) { return "---"; } $callsign = trim($callsign); if (strpos($callsign,"-")) { $callsign = substr($callsign,0,strpos($callsign,"-")); } $delimiter =" "; exec("grep -P '".$callsign.$delimiter."' ".DMRIDDATPATH, $output); if (count($output) == 0) { $delimiter = "\t"; exec("grep -P '".$callsign.$delimiter."' ".DMRIDDATPATH, $output); } $name = substr($output[0], strpos($output[0],$delimiter)+1); $name = substr($name, strpos($name,$delimiter)+1); return $name; } ?>