', $output); ZM\Error("Unable to probe network cameras, status is '$status'. Output was: $html_output Please run the following command from a command line for more information: $shell_command" ); } else { ZM\Logger::Debug('Results from probe: '.implode('
', $output)); } return $output; } function probeCameras($localIp) { $cameras = array(); $lines = @execONVIF('probe 1.1,1.2'.(isset($_REQUEST['interface']) ? ' '.isset($_REQUEST['interface']) : '' )); if ( $lines ) { foreach ( $lines as $line ) { $line = rtrim($line); if ( preg_match('|^(.+),(.+),\s\((.*)\)$|', $line, $matches) ) { $device_ep = $matches[1]; $soapversion = $matches[2]; $camera = array( 'model' => 'Unknown ONVIF Camera', 'monitor' => array( 'Function' => 'Monitor', 'Type' => 'Ffmpeg', 'Host' => $device_ep, 'SOAP' => $soapversion, 'ConfigURL' => $device_ep, 'ConfigOptions' => 'SOAP' . $soapversion, 'Notes' => '', ), ); foreach ( preg_split('|,\s*|', $matches[3]) as $attr_val ) { if ( preg_match('|(.+)=\'(.*)\'|', $attr_val, $tokens) ) { if ( $tokens[1] == 'hardware' ) { $camera['model'] = $tokens[2]; } else if ( $tokens[1] == 'name' ) { $camera['monitor']['Name'] = $tokens[2]; } else if ( $tokens[1] == 'type' ) { } else if ( $tokens[1] == 'location' or $tokens[1] == 'location/city' or $tokens[1] == 'location/country' ) { $camera['monitor']['Notes'] .= $tokens[1].'='.$tokens[2]."\n"; // $camera['location'] = $tokens[2]; } else { ZM\Logger::Debug('Unknown token '.$tokens[1].' = '.$tokens[2]); } } } // end foreach token $cameras[] = $camera; } } // end foreach line } // end if results from execOnvif return $cameras; } // end function probeCameras function probeProfiles($device_ep, $soapversion, $username, $password) { $profiles = array(); if ( $lines = @execONVIF("profiles $device_ep $soapversion $username $password") ) { foreach ( $lines as $line ) { $line = rtrim( $line ); if ( preg_match('|^([^,]+),\s*([^,]+),\s*([^,]+),\s*(\d+),\s*(\d+),\s*(\d+),\s*([^,]+),\s*(.+)\s*$|', $line, $matches) ) { $stream_uri = $matches[8]; // add user@pass to URI if ( preg_match('|^(\S+://)(.+)$|', $stream_uri, $tokens) ) { $stream_uri = $tokens[1].$username.':'.$password.'@'.$tokens[2]; } ZM\Warning(print_r($matches,1)); $profile = array( # 'monitor' part of camera 'Type' => 'Ffmpeg', 'Width' => $matches[4], 'Height' => $matches[5], 'MaxFPS' => $matches[6], 'Path' => $stream_uri, // local-only: 'Profile' => $matches[1], 'Name' => $matches[2], 'Encoding' => $matches[3], 'Transport' => $matches[7], ); $profiles[] = $profile; } else { ZM\Logger::Debug("Line did not match preg: $line"); } } // end foreach line } // end if results from execONVIF return $profiles; } // end function probeProfiles //==== STEP 1 ============================================================ $focusWindow = true; xhtmlHeaders(__FILE__, translate('MonitorProbe')); getBodyTopHTML(); if ( !isset($_REQUEST['step']) || ($_REQUEST['step'] == '1') ) { $monitors = array(); foreach ( dbFetchAll("SELECT Id, Name, Host FROM Monitors WHERE Type='Remote' ORDER BY Host") as $monitor ) { if ( preg_match('/^(.+)@(.+)$/', $monitor['Host'], $matches) ) { //echo "1: ".$matches[2]." = ".gethostbyname($matches[2])."
"; $monitors[gethostbyname($matches[2])] = $monitor; } else { //echo "2: ".$monitor['Host']." = ".gethostbyname($monitor['Host'])."
"; $monitors[gethostbyname($monitor['Host'])] = $monitor; } } $detcameras = probeCameras(''); foreach ( $detcameras as $camera ) { if ( preg_match('|([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)|', $camera['monitor']['Host'], $matches) ) { $ip = $matches[1]; } $host = $ip; $sourceDesc = base64_encode(json_encode($camera['monitor'])); $sourceString = $camera['model'].' @ '.$host.' using version '.$camera['monitor']['SOAP']; $cameras[$sourceDesc] = $sourceString; } if ( count($cameras) <= 0 ) $cameras[0] = translate('NoDetectedCameras'); ?>

', $output); ZM\Error("Unable to list network interfaces, status is '$status'. Output was:

$html_output"); } else { foreach ( $output as $line ) { if ( preg_match('/^\d+: ([[:alnum:]]+):/', $line, $matches ) ) { if ( $matches[1] != 'lo' ) { $interfaces[$matches[1]] = $matches[1]; } else { ZM\Logger::Debug("No match for $line"); } } } } $routes = array(); exec('ip route', $output, $status); if ( $status ) { $html_output = implode('
', $output); ZM\Error("Unable to list network interfaces, status is '$status'. Output was:

$html_output"); } else { foreach ( $output as $line ) { if ( preg_match('/^default via [.[:digit:]]+ dev ([[:alnum:]]+)/', $line, $matches) ) { $default_interface = $matches[1]; } else if ( preg_match('/^([.\/[:digit:]]+) dev ([[:alnum:]]+)/', $line, $matches) ) { $interfaces[$matches[2]] .= ' ' . $matches[1]; } } # end foreach line of output } echo htmlSelect('interface', $interfaces, (isset($_REQUEST['interface']) ? $_REQUEST['interface'] : $default_interface), array('data-on-change-this'=>'changeInterface') ); ?>

'configureButtons')); ?>

$value ) { if ( isset($value) ) { $monitor[$name] = $value; } } $camera['monitor'] = $monitor; //print $monitor['Host'].", ".$_REQUEST['username'].", ".$_REQUEST['password']."
"; $detprofiles = probeProfiles($monitor['Host'], $monitor['SOAP'], $_REQUEST['Username'], $_REQUEST['Password']); foreach ( $detprofiles as $profile ) { $monitor = $camera['monitor']; $sourceString = "${profile['Name']} : ${profile['Encoding']}" . " (${profile['Width']}x${profile['Height']} @ ${profile['MaxFPS']}fps ${profile['Transport']})"; // copy technical details $monitor['Width'] = $profile['Width']; $monitor['Height'] = $profile['Height']; if ( $profile['Transport'] == 'RTP-Multicast' ) { $monitor['Method'] = 'rtpMulti'; } else if ( $profile['Transport'] == 'RTP-Unicast' ) { $monitor['Method'] = 'rtpUni'; } else { $monitor['Method'] = 'rtpRtsp'; } // The maxfps fields do not work for ip streams. Can re-enable if that is fixed. // $monitor['MaxFPS'] = $profile['MaxFPS']; // $monitor['AlarmMaxFPS'] = $profile['AlarmMaxFPS']; $monitor['Path'] = $profile['Path']; $monitor['ControlDevice'] = $profile['Profile']; # Netcat needs this for ProfileToken $sourceDesc = base64_encode(json_encode($monitor)); $profiles[$sourceDesc] = $sourceString; } if ( count($profiles) <= 0 ) $profiles[0] = translate('NoDetectedProfiles'); ?>

'configureButtons')); ?>