mirror of
https://gitcode.com/gh_mirrors/on/onvif.git
synced 2025-12-30 13:32:27 +00:00
* Working with original dependency versions.
This commit is contained in:
@@ -22,6 +22,7 @@ repositories {
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
clean.dependsOn(":onvif-ws-client:clean")
|
||||
|
||||
dependencies {
|
||||
@@ -37,9 +38,9 @@ dependencies {
|
||||
api 'javax.xml.bind:jaxb-api:2.3.1'
|
||||
api 'com.sun.xml.bind:jaxb-core:2.3.0.1'
|
||||
api 'com.sun.xml.bind:jaxb-impl:2.3.1'
|
||||
api testImplementation(project(':onvif-ws-client'))
|
||||
api testFixtures(project(':onvif-ws-client'))
|
||||
api testImplementation('org.slf4j:slf4j-simple:1.7.26')
|
||||
implementation project(':onvif-ws-client')
|
||||
// implementation project(':onvif-ws-client')
|
||||
// testCompileOnly(testFixtures(project(':onvif-ws-client')))
|
||||
}
|
||||
|
||||
|
||||
40
onvif-java/src/main/java/tests/AuthTest.java
Normal file
40
onvif-java/src/main/java/tests/AuthTest.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package tests;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Base64;
|
||||
|
||||
public class AuthTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
String date = "2024-03-06T06:04:30Z";
|
||||
String nonce = "gHV4Y/cV8KE7OSY7+qGv0g==";
|
||||
String password = "abcd1234";
|
||||
|
||||
try {
|
||||
// 1. Base64 decode the nonce
|
||||
byte[] decodedNonce = Base64.getDecoder().decode(nonce);
|
||||
|
||||
// 2. Concatenate decodedNonce, date, and password
|
||||
byte[] dateBytes = date.getBytes();
|
||||
byte[] passwordBytes = password.getBytes();
|
||||
byte[] toBeHashed = new byte[decodedNonce.length + dateBytes.length + passwordBytes.length];
|
||||
|
||||
System.arraycopy(decodedNonce, 0, toBeHashed, 0, decodedNonce.length);
|
||||
System.arraycopy(dateBytes, 0, toBeHashed, decodedNonce.length, dateBytes.length);
|
||||
System.arraycopy(passwordBytes, 0, toBeHashed, decodedNonce.length + dateBytes.length, passwordBytes.length);
|
||||
|
||||
// 3. SHA-1 hash the concatenated bytes
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
||||
byte[] sha1Hash = digest.digest(toBeHashed);
|
||||
|
||||
// 4. Base64 encode the SHA-1 hash
|
||||
String digestBase64 = Base64.getEncoder().encodeToString(sha1Hash);
|
||||
|
||||
System.out.println("Digest: " + digestBase64);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
28
onvif-java/src/main/java/tests/Base64Test.java
Normal file
28
onvif-java/src/main/java/tests/Base64Test.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package tests;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
public class Base64Test {
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
String base64String = "4AUTXXJ214OBnsdeYBXatQ==";
|
||||
|
||||
// decode Base64
|
||||
byte[] decodedBytes = Base64.getDecoder().decode(base64String);
|
||||
|
||||
// turn byte[] to hex
|
||||
StringBuilder hexStringBuilder = new StringBuilder();
|
||||
for (byte b : decodedBytes) {
|
||||
String hex = Integer.toHexString(0xff & b);
|
||||
if (hex.length() == 1) {
|
||||
hexStringBuilder.append('0');
|
||||
}
|
||||
hexStringBuilder.append(hex);
|
||||
}
|
||||
String hexString = hexStringBuilder.toString();
|
||||
|
||||
System.out.println("hex:" + hexString);
|
||||
}
|
||||
|
||||
}
|
||||
76
onvif-java/src/main/java/tests/DiscoverAndTest.java
Normal file
76
onvif-java/src/main/java/tests/DiscoverAndTest.java
Normal file
@@ -0,0 +1,76 @@
|
||||
package tests;
|
||||
|
||||
import de.onvif.discovery.OnvifDiscovery;
|
||||
//import org.onvif.client.TestDevice;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Class calls OnvifDiscovery and for each device URL found, calls TestDevice This assumes all onvif
|
||||
* devices on your network use the same username and password.
|
||||
*
|
||||
* @author Brad Lowe
|
||||
*/
|
||||
public class DiscoverAndTest {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TestDevice.class);
|
||||
|
||||
public static String discoverAndTest(String user, String password) {
|
||||
String sep = "\n";
|
||||
StringBuffer out = new StringBuffer();
|
||||
|
||||
Collection<URL> urls = OnvifDiscovery.discoverOnvifURLs();
|
||||
for (URL u : urls) {
|
||||
out.append("Discovered URL:" + u.toString() + sep);
|
||||
}
|
||||
ArrayList<String> results = new ArrayList<>();
|
||||
|
||||
int good = 0, bad = 0;
|
||||
|
||||
for (URL u : urls) {
|
||||
|
||||
try {
|
||||
String result = TestDevice.testCamera(u, user, password);
|
||||
LOG.info(u + "->" + result);
|
||||
good++;
|
||||
results.add(u.toString() + ":" + result);
|
||||
} catch (Throwable e) {
|
||||
bad++;
|
||||
LOG.error("error:" + u, e);
|
||||
// This is a bit of a hack. When a camera is password protected (it should be!)
|
||||
// and the password is not provided or wrong, a "Unable to Send Message" exception
|
||||
// may be thrown. This is not clear-- buried in the stack track is the real cause.
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
String trace = sw.getBuffer().toString();
|
||||
if (trace.contains("Unauthorized")) results.add(u + ":Unauthorized:");
|
||||
else results.add(u + ":" + trace);
|
||||
}
|
||||
}
|
||||
out.append("RESULTS: " + sep);
|
||||
for (String s : results) out.append(s + sep);
|
||||
out.append("cameras found:" + urls.size() + " good=" + good + ", bad=" + bad + sep);
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// get user and password.. we will ignore device host
|
||||
String user = "";
|
||||
String password = "";
|
||||
if (args.length > 0) user = args[0];
|
||||
if (args.length > 1) password = args[1];
|
||||
|
||||
if (password.isEmpty()) {
|
||||
LOG.warn(
|
||||
"Warning: No password for discover and test... run with common user password as arguments");
|
||||
}
|
||||
// OnvifDevice.setVerbose(true);
|
||||
LOG.info(discoverAndTest(user, password));
|
||||
}
|
||||
}
|
||||
19
onvif-java/src/main/java/tests/DiscoveryTest.java
Normal file
19
onvif-java/src/main/java/tests/DiscoveryTest.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package tests;
|
||||
|
||||
import de.onvif.discovery.OnvifDiscovery;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
|
||||
public class DiscoveryTest {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DiscoveryTest.class);
|
||||
|
||||
public static void main(String[] args) {
|
||||
Collection<URL> urls = OnvifDiscovery.discoverOnvifURLs();
|
||||
for (URL u : urls) {
|
||||
LOG.info(u.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
134
onvif-java/src/main/java/tests/GetTestDevice.java
Normal file
134
onvif-java/src/main/java/tests/GetTestDevice.java
Normal file
@@ -0,0 +1,134 @@
|
||||
package tests;
|
||||
|
||||
//import org.onvif.client.OnvifCredentials;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class GetTestDevice {
|
||||
|
||||
static String PROPERTY_NAME = "ONVIF_HOST";
|
||||
private static final Logger LOG = LoggerFactory.getLogger(GetTestDevice.class);
|
||||
|
||||
// Get a camera host, user name, and password for tests.
|
||||
// Add an environment variable or java Property called "TEST_CAM" and set to
|
||||
// host,user,password,profile
|
||||
// or modify resource/onvif.properties
|
||||
|
||||
public static OnvifCredentials getOnvifCredentials(String[] args) {
|
||||
|
||||
OnvifCredentials creds = getFromArgs(args);
|
||||
if (creds != null)
|
||||
return creds;
|
||||
|
||||
creds = getFromProperties();
|
||||
if (creds != null)
|
||||
return creds;
|
||||
try {
|
||||
creds = getFirstFromResource("/onvif.properties");
|
||||
if (creds != null)
|
||||
return creds;
|
||||
} catch (IOException ioe) {
|
||||
LOG.error("Error", ioe);
|
||||
}
|
||||
try {
|
||||
creds = getFromStandardInput();
|
||||
if (creds != null)
|
||||
return creds;
|
||||
} catch (IOException ioe) {
|
||||
LOG.error("Error", ioe);
|
||||
}
|
||||
|
||||
LOG.info("Unable to get default test onvif credentials");
|
||||
return new OnvifCredentials("", "", "", "");
|
||||
}
|
||||
|
||||
// arguments to any test app can be host user password profilename
|
||||
// if no arguments passed, returns null.
|
||||
// All arguments optional.
|
||||
public static OnvifCredentials getFromArgs(String[] args) {
|
||||
if (args == null || args.length == 0)
|
||||
return null;
|
||||
String host = "", user = "", password = "", profile = "";
|
||||
host = args[0];
|
||||
if (args.length > 1)
|
||||
user = args[1];
|
||||
if (args.length > 2)
|
||||
password = args[2];
|
||||
if (args.length > 3)
|
||||
profile = args[3];
|
||||
return new OnvifCredentials(host, user, password, profile);
|
||||
}
|
||||
|
||||
public static OnvifCredentials getFromProperties() {
|
||||
String test = null;
|
||||
if (test == null)
|
||||
test = System.getProperty(PROPERTY_NAME);
|
||||
if (test == null)
|
||||
test = System.getenv(PROPERTY_NAME);
|
||||
|
||||
if (test != null) {
|
||||
return parse(test);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static OnvifCredentials getFromStandardInput() throws IOException {
|
||||
|
||||
System.out.println("Getting camera credentials from standard input");
|
||||
InputStreamReader inputStream = new InputStreamReader(System.in, StandardCharsets.UTF_8);
|
||||
BufferedReader keyboardInput = new BufferedReader(inputStream);
|
||||
System.out.println("Please enter camera IP (with port if not 80):");
|
||||
String cameraAddress = keyboardInput.readLine();
|
||||
System.out.println("Please enter camera username:");
|
||||
String user = keyboardInput.readLine();
|
||||
System.out.println("Please enter camera password:");
|
||||
String password = keyboardInput.readLine();
|
||||
System.out.println("Please enter camera profile [or enter to use first]:");
|
||||
String profile = keyboardInput.readLine();
|
||||
OnvifCredentials creds = new OnvifCredentials(cameraAddress, user, password, profile);
|
||||
return creds;
|
||||
}
|
||||
|
||||
private static OnvifCredentials getFirstFromResource(String resource) throws IOException {
|
||||
InputStream res = GetTestDevice.class.getResourceAsStream(resource);
|
||||
if (res != null) {
|
||||
try (Scanner s = new Scanner(res, StandardCharsets.UTF_8)) {
|
||||
s.useDelimiter("\\A");
|
||||
while (s.hasNextLine()) {
|
||||
String line = s.nextLine();
|
||||
if (!line.isEmpty() && !line.startsWith("#"))
|
||||
return parse(line.substring(line.indexOf("=") + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// warning, this breaks if password contains a comma.
|
||||
public static OnvifCredentials parse(String i) {
|
||||
String host = "", user = "", password = "", profile = "";
|
||||
if (i != null) {
|
||||
if (i.contains(",")) {
|
||||
String[] sp = i.split(",");
|
||||
if (sp.length > 0)
|
||||
host = sp[0];
|
||||
if (sp.length > 1)
|
||||
user = sp[1];
|
||||
if (sp.length > 2)
|
||||
password = sp[2];
|
||||
if (sp.length > 3)
|
||||
profile = sp[3];
|
||||
|
||||
} else
|
||||
host = i;
|
||||
}
|
||||
return new OnvifCredentials(host, user, password, profile);
|
||||
}
|
||||
}
|
||||
55
onvif-java/src/main/java/tests/OnvifCredentials.java
Normal file
55
onvif-java/src/main/java/tests/OnvifCredentials.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package tests;
|
||||
|
||||
public class OnvifCredentials {
|
||||
private String host; // 92.168.xx.yy, or http://host[:port]
|
||||
private String user; // admin
|
||||
private String password; // secret
|
||||
private String profile; // "MediaProfile000" If empty, will use first profile.
|
||||
|
||||
public OnvifCredentials(String host, String user, String password, String profile) {
|
||||
this.host = host;
|
||||
this.user = user;
|
||||
this.password = password;
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(String user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getProfile() {
|
||||
return profile;
|
||||
}
|
||||
|
||||
public void setProfile(String profile) {
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return host; // + "," + user+ "," + "****,"++ "#" + profile;
|
||||
}
|
||||
|
||||
public String details() {
|
||||
return host + "," + user + "," + password + "," + profile;
|
||||
}
|
||||
}
|
||||
98
onvif-java/src/main/java/tests/ReadCommandsFromStdInput.java
Normal file
98
onvif-java/src/main/java/tests/ReadCommandsFromStdInput.java
Normal file
@@ -0,0 +1,98 @@
|
||||
package tests;
|
||||
|
||||
import de.onvif.soap.OnvifDevice;
|
||||
//import org.onvif.client.TestDevice;
|
||||
import org.onvif.ver10.schema.Profile;
|
||||
|
||||
import javax.xml.soap.SOAPException;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.ConnectException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.List;
|
||||
|
||||
public class ReadCommandsFromStdInput {
|
||||
|
||||
private static final String INFO =
|
||||
"Commands:\n \n url: Get snapshort URL.\n info: Get information about each valid command.\n profiles: Get all profiles.\n inspect: Get device details.\n exit: Exit this application.";
|
||||
|
||||
public static void main(String[] args) {
|
||||
InputStreamReader inputStream = new InputStreamReader(System.in);
|
||||
BufferedReader keyboardInput = new BufferedReader(inputStream);
|
||||
String input, cameraAddress, user, password;
|
||||
|
||||
try {
|
||||
System.out.println("Please enter camera IP (with port if not 80):");
|
||||
cameraAddress = keyboardInput.readLine();
|
||||
System.out.println("Please enter camera username:");
|
||||
user = keyboardInput.readLine();
|
||||
System.out.println("Please enter camera password:");
|
||||
password = keyboardInput.readLine();
|
||||
if (cameraAddress == null || user == null || password == null)
|
||||
throw new IOException("No input");
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("Connect to camera, please wait ...");
|
||||
OnvifDevice cam;
|
||||
try {
|
||||
cam = new OnvifDevice(cameraAddress, user, password);
|
||||
} catch (MalformedURLException | ConnectException | SOAPException e1) {
|
||||
System.err.println("No connection to camera, please try again.");
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("Connection to camera successful!");
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
System.out.println();
|
||||
System.out.println("Enter a command (type \"info\" to get commands):");
|
||||
input = keyboardInput.readLine();
|
||||
if (input == null) break;
|
||||
switch (input) {
|
||||
case "url":
|
||||
{
|
||||
List<Profile> profiles = cam.getMedia().getProfiles();
|
||||
for (Profile p : profiles) {
|
||||
System.out.println(
|
||||
"URL from Profile '"
|
||||
+ p.getName()
|
||||
+ "': "
|
||||
+ cam.getMedia().getSnapshotUri(p.getToken()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "profiles":
|
||||
List<Profile> profiles = cam.getMedia().getProfiles();
|
||||
System.out.println("Number of profiles: " + profiles.size());
|
||||
for (Profile p : profiles) {
|
||||
System.out.println(" Profile " + p.getName() + " token is: " + p.getToken());
|
||||
}
|
||||
break;
|
||||
case "info":
|
||||
System.out.println(INFO);
|
||||
break;
|
||||
case "inspect":
|
||||
System.out.println(TestDevice.inspect(cam));
|
||||
break;
|
||||
|
||||
case "quit":
|
||||
case "exit":
|
||||
case "end":
|
||||
return;
|
||||
default:
|
||||
System.out.println("Unknown command!");
|
||||
System.out.println();
|
||||
System.out.println(INFO);
|
||||
break;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
58
onvif-java/src/main/java/tests/SimpleTest.java
Normal file
58
onvif-java/src/main/java/tests/SimpleTest.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package tests;
|
||||
|
||||
import de.onvif.soap.OnvifDevice;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
//import org.onvif.client.OnvifCredentials;
|
||||
//import org.onvif.client.TestDevice;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class SimpleTest {
|
||||
|
||||
// This test reads connection params from a properties file and take a
|
||||
// screenshot
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
final Map<String, OnvifDevice> onvifCameras = new HashMap<>();
|
||||
final Map<String, OnvifCredentials> credentialsMap = new HashMap<>();
|
||||
final String propFileRelativePath = "onvif-java/src/test/resources/onvif.properties";
|
||||
final Properties config = new Properties();
|
||||
final File f = new File(propFileRelativePath);
|
||||
if (!f.exists()) throw new Exception("fnf: " + f.getAbsolutePath());
|
||||
config.load(new FileInputStream(f));
|
||||
|
||||
for (Object k : config.keySet()) {
|
||||
String line = config.get(k.toString()).toString();
|
||||
OnvifCredentials credentials = GetTestDevice.parse(line);
|
||||
if (credentials != null) {
|
||||
try {
|
||||
System.out.println("Connect to camera, please wait ...");
|
||||
OnvifDevice cam =
|
||||
new OnvifDevice(
|
||||
credentials.getHost(), credentials.getUser(), credentials.getPassword());
|
||||
System.out.printf("Connected to device %s (%s)%n", cam.getDeviceInfo(), k);
|
||||
System.out.println(TestDevice.inspect(cam));
|
||||
|
||||
String snapshotUri = cam.getSnapshotUri();
|
||||
if (!snapshotUri.isEmpty()) {
|
||||
File tempFile = File.createTempFile("tmp", ".jpg");
|
||||
|
||||
// Note: This will likely fail if the camera/device is password protected.
|
||||
// embedding the user:password@ into the URL will not work with FileUtils.copyURLToFile
|
||||
FileUtils.copyURLToFile(new URL(snapshotUri), tempFile);
|
||||
System.out.println(
|
||||
"snapshot: " + tempFile.getAbsolutePath() + " length:" + tempFile.length());
|
||||
}
|
||||
|
||||
} catch (Throwable th) {System.err.println("Error on device: " + k);
|
||||
th.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
194
onvif-java/src/main/java/tests/TestDevice.java
Normal file
194
onvif-java/src/main/java/tests/TestDevice.java
Normal file
@@ -0,0 +1,194 @@
|
||||
package tests;
|
||||
|
||||
import de.onvif.beans.DeviceInfo;
|
||||
import de.onvif.soap.OnvifDevice;
|
||||
import de.onvif.utils.OnvifUtils;
|
||||
import org.onvif.ver10.device.wsdl.DeviceServiceCapabilities;
|
||||
import org.onvif.ver10.events.wsdl.EventPortType;
|
||||
import org.onvif.ver10.events.wsdl.GetEventProperties;
|
||||
import org.onvif.ver10.events.wsdl.GetEventPropertiesResponse;
|
||||
import org.onvif.ver10.media.wsdl.Media;
|
||||
import org.onvif.ver10.schema.*;
|
||||
import org.onvif.ver20.imaging.wsdl.ImagingPort;
|
||||
import org.onvif.ver20.ptz.wsdl.Capabilities;
|
||||
import org.onvif.ver20.ptz.wsdl.PTZ;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import javax.xml.soap.SOAPException;
|
||||
import java.io.IOException;
|
||||
import java.lang.Object;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
/** @author Brad Lowe */
|
||||
public class TestDevice {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TestDevice.class);
|
||||
|
||||
public static String testCamera(OnvifCredentials creds) throws SOAPException, IOException {
|
||||
URL u =
|
||||
creds.getHost().startsWith("http")
|
||||
? new URL(creds.getHost())
|
||||
: new URL("http://" + creds.getHost());
|
||||
return testCamera(u, creds.getUser(), creds.getPassword());
|
||||
}
|
||||
|
||||
static String sep = "\n";
|
||||
|
||||
// This method returns information about an initialized OnvifDevice.
|
||||
// This could throw an uncaught SOAP or other error on some cameras...
|
||||
// Would accept Pull Requests on printing out additional information about devices.
|
||||
public static String inspect(OnvifDevice device) {
|
||||
String out = "";
|
||||
DeviceInfo info = device.getDeviceInfo();
|
||||
out += "DeviceInfo:" + sep + "\t" + info + sep;
|
||||
DeviceServiceCapabilities caps = device.getDevice().getServiceCapabilities();
|
||||
String sysCaps = OnvifUtils.format(caps);
|
||||
sysCaps = sysCaps.replace("],", "],\t\n");
|
||||
|
||||
out += "\tgetServiceCapabilities: " + sysCaps + sep;
|
||||
// out += "\tgetServiceCapabilities.getSystem: " + OnvifUtils.format(caps.getSystem()) + sep;
|
||||
|
||||
Media media = device.getMedia();
|
||||
|
||||
media.getVideoSources();
|
||||
List<Profile> profiles = media.getProfiles();
|
||||
out += "Media Profiles: " + profiles.size() + sep;
|
||||
for (Profile profile : profiles) {
|
||||
String profileToken = profile.getToken();
|
||||
String rtsp = device.getStreamUri(profileToken);
|
||||
out += "\tProfile: " + profile.getName() + " token=" + profile.getToken() + sep;
|
||||
out += "\t\tstream: " + rtsp + sep;
|
||||
out += "\t\tsnapshot: " + device.getSnapshotUri(profileToken) + sep;
|
||||
out += "\t\tdetails:" + OnvifUtils.format(profile) + sep;
|
||||
}
|
||||
|
||||
try {
|
||||
List<VideoSource> videoSources = media.getVideoSources();
|
||||
out += "VideoSources: " + videoSources.size() + sep;
|
||||
for (VideoSource v : videoSources) out += "\t" + OnvifUtils.format(v) + sep;
|
||||
|
||||
ImagingPort imaging = device.getImaging();
|
||||
if (imaging != null && videoSources.size() > 0) {
|
||||
String token = videoSources.get(0).getToken();
|
||||
|
||||
out += "Imaging:" + token + sep;
|
||||
try {
|
||||
org.onvif.ver20.imaging.wsdl.Capabilities image_caps = imaging.getServiceCapabilities();
|
||||
out += "\tgetServiceCapabilities=" + OnvifUtils.format(image_caps) + sep;
|
||||
|
||||
if (token != null) {
|
||||
out +=
|
||||
"\tgetImagingSettings="
|
||||
+ OnvifUtils.format(imaging.getImagingSettings(token))
|
||||
+ sep;
|
||||
out += "\tgetMoveOptions=" + OnvifUtils.format(imaging.getMoveOptions(token)) + sep;
|
||||
out += "\tgetStatus=" + OnvifUtils.format(imaging.getStatus(token)) + sep;
|
||||
out += "\tgetOptions=" + OnvifUtils.format(imaging.getOptions(token)) + sep;
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
out += "Imaging unavailable:" + th.getMessage() + sep;
|
||||
}
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
// this can fail if the device doesn't support video sources.
|
||||
out += "VideoSources: " + th.getMessage() + sep;
|
||||
}
|
||||
try {
|
||||
// This may throw a SoapFaultException with the message "This device does not support audio"
|
||||
List<AudioSource> audioSources = media.getAudioSources();
|
||||
out += "AudioSources: " + audioSources.size() + sep;
|
||||
for (AudioSource a : audioSources) out += "\t" + OnvifUtils.format(a) + sep;
|
||||
} catch (Throwable th) {
|
||||
out += "AudioSources Unavailable: " + th.getMessage() + sep;
|
||||
}
|
||||
|
||||
try {
|
||||
EventPortType events = device.getEvents();
|
||||
if (events != null) {
|
||||
out += "Events:" + sep;
|
||||
out +=
|
||||
"\tgetServiceCapabilities=" + OnvifUtils.format(events.getServiceCapabilities()) + sep;
|
||||
|
||||
GetEventProperties getEventProperties = new GetEventProperties();
|
||||
GetEventPropertiesResponse getEventPropertiesResp =
|
||||
events.getEventProperties(getEventProperties);
|
||||
out += "\tMessageContentFilterDialects:" + sep;
|
||||
for (String f : getEventPropertiesResp.getMessageContentFilterDialect())
|
||||
out += ("\t\t" + f + sep);
|
||||
out += "\tTopicExpressionDialects:" + sep;
|
||||
for (String f : getEventPropertiesResp.getTopicExpressionDialect())
|
||||
out += ("\t\t" + f + sep);
|
||||
|
||||
out += "\tTopics:" + sep;
|
||||
StringBuffer tree = new StringBuffer();
|
||||
for (Object object : getEventPropertiesResp.getTopicSet().getAny()) {
|
||||
Element e = (Element) object;
|
||||
printTree(e, e.getNodeName(), tree);
|
||||
// WsNotificationTest.printTree(e, e.getNodeName());
|
||||
}
|
||||
out += tree;
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
out += "Events Unavailable: " + th.getMessage() + sep;
|
||||
}
|
||||
PTZ ptz = device.getPtz();
|
||||
if (ptz != null) {
|
||||
|
||||
String profileToken = profiles.get(0).getToken();
|
||||
try {
|
||||
Capabilities ptz_caps = ptz.getServiceCapabilities();
|
||||
out += "PTZ:" + sep;
|
||||
out += "\tgetServiceCapabilities=" + OnvifUtils.format(ptz_caps) + sep;
|
||||
PTZStatus s = ptz.getStatus(profileToken);
|
||||
out += "\tgetStatus=" + OnvifUtils.format(s) + sep;
|
||||
// out += "ptz.getConfiguration=" + ptz.getConfiguration(profileToken) + sep;
|
||||
List<PTZPreset> presets = ptz.getPresets(profileToken);
|
||||
if (presets != null && !presets.isEmpty()) {
|
||||
out += "\tPresets:" + presets.size() + sep;
|
||||
for (PTZPreset p : presets) out += "\t\t" + OnvifUtils.format(p) + sep;
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
out += "PTZ: Unavailable" + th.getMessage() + sep;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
public static void printTree(Node node, String name, StringBuffer buffer) {
|
||||
|
||||
if (node.hasChildNodes()) {
|
||||
NodeList nodes = node.getChildNodes();
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
Node n = nodes.item(i);
|
||||
printTree(n, name + " - " + n.getNodeName(), buffer);
|
||||
}
|
||||
} else {
|
||||
buffer.append("\t\t" + name + " - " + node.getNodeName() + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
public static String testCamera(URL url, String user, String password)
|
||||
throws SOAPException, IOException {
|
||||
LOG.info("Testing camera:" + url);
|
||||
OnvifDevice device = new OnvifDevice(url, user, password);
|
||||
return inspect(device);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
OnvifCredentials creds = GetTestDevice.getOnvifCredentials(args);
|
||||
try {
|
||||
// OnvifDevice.setVerbose(true);
|
||||
String out = testCamera(creds);
|
||||
|
||||
LOG.info("\n" + out + "\n");
|
||||
} catch (Throwable th) {
|
||||
LOG.error("Failed for " + creds, th);
|
||||
th.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
258
onvif-java/src/main/java/tests/WsNotificationTest.java
Normal file
258
onvif-java/src/main/java/tests/WsNotificationTest.java
Normal file
@@ -0,0 +1,258 @@
|
||||
package tests;
|
||||
|
||||
import de.onvif.soap.OnvifDevice;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.cxf.wsn.client.Consumer;
|
||||
import org.apache.cxf.wsn.client.NotificationBroker;
|
||||
import org.apache.cxf.wsn.client.Publisher;
|
||||
import org.apache.cxf.wsn.client.Subscription;
|
||||
import org.apache.cxf.wsn.services.JaxwsNotificationBroker;
|
||||
import org.oasis_open.docs.wsn.b_2.FilterType;
|
||||
import org.oasis_open.docs.wsn.b_2.NotificationMessageHolderType;
|
||||
import org.oasis_open.docs.wsn.b_2.TopicExpressionType;
|
||||
import org.oasis_open.docs.wsn.bw_2.*;
|
||||
import org.oasis_open.docs.wsrf.rw_2.ResourceUnknownFault;
|
||||
//import org.onvif.client.OnvifCredentials;
|
||||
import org.onvif.ver10.events.wsdl.*;
|
||||
import org.onvif.ver10.events.wsdl.CreatePullPointSubscription.SubscriptionPolicy;
|
||||
import org.onvif.ver10.schema.Capabilities;
|
||||
import org.onvif.ver10.schema.CapabilityCategory;
|
||||
import org.onvif.ver10.schema.MediaUri;
|
||||
import org.onvif.ver10.schema.Profile;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class WsNotificationTest {
|
||||
|
||||
// This is a work in progress class...any help is welcome ;)
|
||||
// A good idea could be to follow this guide:
|
||||
// https://access.redhat.com/documentation/en-us/red_hat_jboss_a-mq/6.1/html-single/ws-notification_guide/index#WSNTutorial
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
OnvifCredentials creds = GetTestDevice.getOnvifCredentials(args);
|
||||
System.out.println("Connect to camera, please wait ...");
|
||||
|
||||
OnvifDevice cam = null;
|
||||
try {
|
||||
cam = new OnvifDevice(creds.getHost(), creds.getUser(), creds.getPassword());
|
||||
} catch (ConnectException | SOAPException e1) {
|
||||
System.err.println("No connection to device with ip " + creds + ", please try again.");
|
||||
System.exit(0);
|
||||
}
|
||||
System.out.println("Connected to device " + cam.getDeviceInfo());
|
||||
|
||||
// get device capabilities
|
||||
Capabilities cap = cam.getDevice().getCapabilities(List.of(CapabilityCategory.ALL));
|
||||
System.out.println(cap.getDevice().toString());
|
||||
// print profiles
|
||||
printProfiles(cam);
|
||||
// takeScreenShot(profileToken, cam);
|
||||
// presets
|
||||
// List<PTZPreset> presets = cam.getPtz().getPresets(profileToken);
|
||||
// presets.forEach(x->System.out.println(x.getName()));
|
||||
|
||||
EventPortType eventWs = cam.getEvents();
|
||||
GetEventProperties getEventProperties = new GetEventProperties();
|
||||
GetEventPropertiesResponse getEventPropertiesResp =
|
||||
eventWs.getEventProperties(getEventProperties);
|
||||
getEventPropertiesResp.getMessageContentFilterDialect().forEach(x -> System.out.println(x));
|
||||
getEventPropertiesResp.getTopicExpressionDialect().forEach(x -> System.out.println(x));
|
||||
for (Object object : getEventPropertiesResp.getTopicSet().getAny()) {
|
||||
Element e = (Element) object;
|
||||
printTree(e, e.getNodeName());
|
||||
}
|
||||
|
||||
org.oasis_open.docs.wsn.b_2.ObjectFactory objectFactory =
|
||||
new org.oasis_open.docs.wsn.b_2.ObjectFactory();
|
||||
CreatePullPointSubscription pullPointSubscription = new CreatePullPointSubscription();
|
||||
FilterType filter = new FilterType();
|
||||
TopicExpressionType topicExp = new TopicExpressionType();
|
||||
topicExp.getContent().add("tns1:RuleEngine//."); // every event in that
|
||||
// topic
|
||||
topicExp.setDialect("http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet");
|
||||
JAXBElement<?> topicExpElem = objectFactory.createTopicExpression(topicExp);
|
||||
filter.getAny().add(topicExpElem);
|
||||
pullPointSubscription.setFilter(filter);
|
||||
org.onvif.ver10.events.wsdl.ObjectFactory eventObjFactory =
|
||||
new org.onvif.ver10.events.wsdl.ObjectFactory();
|
||||
SubscriptionPolicy subcriptionPolicy =
|
||||
eventObjFactory.createCreatePullPointSubscriptionSubscriptionPolicy();
|
||||
pullPointSubscription.setSubscriptionPolicy(subcriptionPolicy);
|
||||
String timespan = "PT10S"; // every 10 seconds
|
||||
// String timespan = "PT1M";//every 1 minute
|
||||
pullPointSubscription.setInitialTerminationTime(
|
||||
objectFactory.createSubscribeInitialTerminationTime(timespan));
|
||||
|
||||
try {
|
||||
CreatePullPointSubscriptionResponse resp =
|
||||
eventWs.createPullPointSubscription(pullPointSubscription);
|
||||
|
||||
// Start a consumer that will listen for notification messages
|
||||
// We'll just print the text content out for now.
|
||||
String eventConsumerAddress = "http://localhost:9001/MyConsumer";
|
||||
Consumer consumer =
|
||||
new Consumer(
|
||||
new Consumer.Callback() {
|
||||
public void notify(NotificationMessageHolderType message) {
|
||||
Object o = message.getMessage().getAny();
|
||||
System.out.println(message.getMessage().getAny());
|
||||
if (o instanceof Element) {
|
||||
System.out.println(((Element) o).getTextContent());
|
||||
}
|
||||
}
|
||||
},
|
||||
eventConsumerAddress);
|
||||
|
||||
String queuePort = "8182";
|
||||
String brokerPort = "8181";
|
||||
String brokerAddress = "http://localhost:" + brokerPort + "/wsn/NotificationBroker";
|
||||
ActiveMQConnectionFactory activemq =
|
||||
new ActiveMQConnectionFactory(
|
||||
"vm:(broker:(tcp://localhost:" + queuePort + ")?persistent=false)");
|
||||
JaxwsNotificationBroker notificationBrokerServer =
|
||||
new JaxwsNotificationBroker("WSNotificationBroker", activemq);
|
||||
notificationBrokerServer.setAddress(brokerAddress);
|
||||
notificationBrokerServer.init();
|
||||
|
||||
// Create a subscription for a Topic on the broker
|
||||
NotificationBroker notificationBroker = new NotificationBroker(brokerAddress);
|
||||
// PublisherCallback publisherCallback = new PublisherCallback();
|
||||
// Publisher publisher = new Publisher(publisherCallback,
|
||||
// "http://localhost:" + port2 + "/test/publisher");
|
||||
Subscription subscription = notificationBroker.subscribe(consumer, "tns1:RuleEngine");
|
||||
|
||||
// Device
|
||||
// Trigger/Relay
|
||||
// OperationMode/ShutdownInitiated
|
||||
// OperationMode/UploadInitiated
|
||||
// HardwareFailure/FanFailure
|
||||
// HardwareFailure/PowerSupplyFailure
|
||||
// HardwareFailure/StorageFailure
|
||||
// HardwareFailure/TemperatureCritical
|
||||
// VideoSource
|
||||
// tns1:VideoSource/CameraRedirected
|
||||
// tns1:VideoSource/SignalLoss
|
||||
// tns1:VideoSource/MotionAlarm
|
||||
// VideoEncoder
|
||||
// VideoAnalytics
|
||||
// RuleEngine
|
||||
// LineDetector/Crossed
|
||||
// FieldDetector/ObjectsInside
|
||||
// PTZController
|
||||
// PTZPresets/Invoked
|
||||
// PTZPresets/Reached
|
||||
// PTZPresets/Aborted
|
||||
// PTZPresets/Left
|
||||
// AudioSource
|
||||
// AudioEncoder
|
||||
// UserAlarm
|
||||
// MediaControl
|
||||
// RecordingConfig
|
||||
// RecordingHistory
|
||||
// VideoOutput
|
||||
// AudioOutput
|
||||
// VideoDecoder
|
||||
// AudioDecoder
|
||||
// Receiver
|
||||
// MediaConfiguration
|
||||
// VideoSourceConfiguration
|
||||
// AudioSourceConfiguration
|
||||
// VideoEncoderConfiguration
|
||||
// AudioEncoderConfiguration
|
||||
// VideoAnalyticsConfiguration
|
||||
// PTZConfiguration
|
||||
// MetaDataConfiguration
|
||||
|
||||
// Wait for some messages to accumulate in the pull point
|
||||
Thread.sleep(50_000);
|
||||
|
||||
// Cleanup and exit
|
||||
subscription.unsubscribe();
|
||||
consumer.stop();
|
||||
|
||||
} catch (TopicNotSupportedFault
|
||||
| TopicExpressionDialectUnknownFault
|
||||
| InvalidTopicExpressionFault
|
||||
| InvalidMessageContentExpressionFault
|
||||
| InvalidProducerPropertiesExpressionFault
|
||||
| UnacceptableInitialTerminationTimeFault
|
||||
| NotifyMessageNotSupportedFault
|
||||
| ResourceUnknownFault
|
||||
| UnsupportedPolicyRequestFault
|
||||
| InvalidFilterFault
|
||||
| SubscribeCreationFailedFault
|
||||
| UnrecognizedPolicyRequestFault e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void printTree(Node node, String name) {
|
||||
if (node.hasChildNodes()) {
|
||||
NodeList nodes = node.getChildNodes();
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
Node n = nodes.item(i);
|
||||
printTree(n, name + " - " + n.getNodeName());
|
||||
}
|
||||
} else System.out.println(name + " - " + node.getNodeName());
|
||||
}
|
||||
|
||||
private static void takeScreenShot(String profileToken, OnvifDevice cam) {
|
||||
try {
|
||||
MediaUri sceenshotUri = cam.getMedia().getSnapshotUri(profileToken);
|
||||
File tempFile = File.createTempFile("bosc", ".jpg");
|
||||
// tempFile.deleteOnExit();
|
||||
FileUtils.copyURLToFile(new URL(sceenshotUri.getUri()), tempFile);
|
||||
Runtime.getRuntime().exec("nautilus " + tempFile.getAbsolutePath());
|
||||
Thread.sleep(10000);
|
||||
} catch (ConnectException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void printProfiles(OnvifDevice cam) {
|
||||
|
||||
List<Profile> profiles = cam.getMedia().getProfiles();
|
||||
for (Profile p : profiles) {
|
||||
System.out.printf(
|
||||
"Profile: [token=%s,name=%s,snapshotUri=%s]%n",
|
||||
p.getToken(), p.getName(), cam.getMedia().getSnapshotUri(p.getToken()).getUri());
|
||||
}
|
||||
}
|
||||
|
||||
public static class PublisherCallback implements Publisher.Callback {
|
||||
final CountDownLatch subscribed = new CountDownLatch(1);
|
||||
final CountDownLatch unsubscribed = new CountDownLatch(1);
|
||||
|
||||
public void subscribe(TopicExpressionType topic) {
|
||||
subscribed.countDown();
|
||||
}
|
||||
|
||||
public void unsubscribe(TopicExpressionType topic) {
|
||||
unsubscribed.countDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user