some findbug edits and google style applied

This commit is contained in:
bhlowe
2019-07-31 07:10:35 -07:00
parent ae86e25035
commit a8f03062d1
131 changed files with 36459 additions and 30555 deletions

View File

@@ -2,54 +2,78 @@ package de.onvif.beans;
public class DeviceInfo {
private String manufacturer;
private String model;
private String firmwareVersion;
private String serialNumber;
private String hardwareId;
public DeviceInfo(String manufacturer, String model, String firmwareVersion, String serialNumber,
String hardwareId) {
super();
this.manufacturer = manufacturer;
this.model = model;
this.firmwareVersion = firmwareVersion;
this.serialNumber = serialNumber;
this.hardwareId = hardwareId;
}
@Override
public String toString() {
return "DeviceInfo [manufacturer=" + manufacturer + ", model=" + model + ", firmwareVersion=" + firmwareVersion
+ ", serialNumber=" + serialNumber + ", hardwareId=" + hardwareId + "]";
}
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getFirmwareVersion() {
return firmwareVersion;
}
public void setFirmwareVersion(String firmwareVersion) {
this.firmwareVersion = firmwareVersion;
}
public String getSerialNumber() {
return serialNumber;
}
public void setSerialNumber(String serialNumber) {
this.serialNumber = serialNumber;
}
public String getHardwareId() {
return hardwareId;
}
public void setHardwareId(String hardwareId) {
this.hardwareId = hardwareId;
}
private String manufacturer;
private String model;
private String firmwareVersion;
private String serialNumber;
private String hardwareId;
public DeviceInfo(
String manufacturer,
String model,
String firmwareVersion,
String serialNumber,
String hardwareId) {
super();
this.manufacturer = manufacturer;
this.model = model;
this.firmwareVersion = firmwareVersion;
this.serialNumber = serialNumber;
this.hardwareId = hardwareId;
}
@Override
public String toString() {
return "DeviceInfo [manufacturer="
+ manufacturer
+ ", model="
+ model
+ ", firmwareVersion="
+ firmwareVersion
+ ", serialNumber="
+ serialNumber
+ ", hardwareId="
+ hardwareId
+ "]";
}
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getFirmwareVersion() {
return firmwareVersion;
}
public void setFirmwareVersion(String firmwareVersion) {
this.firmwareVersion = firmwareVersion;
}
public String getSerialNumber() {
return serialNumber;
}
public void setSerialNumber(String serialNumber) {
this.serialNumber = serialNumber;
}
public String getHardwareId() {
return hardwareId;
}
public void setHardwareId(String hardwareId) {
this.hardwareId = hardwareId;
}
}

View File

@@ -1,15 +1,41 @@
package de.onvif.discovery;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.soap.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.MalformedURLException;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.*;
import java.util.concurrent.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;
import java.util.Random;
import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Device discovery class to list local accessible devices probed per UDP probe messages.
@@ -20,193 +46,207 @@ import java.util.concurrent.*;
*/
@SuppressWarnings({"unused", "UseOfSystemOutOrSystemErr", "CallToPrintStackTrace"})
public class DeviceDiscovery {
public static String WS_DISCOVERY_SOAP_VERSION = "SOAP 1.2 Protocol";
public static String WS_DISCOVERY_CONTENT_TYPE = "application/soap+xml";
public static int WS_DISCOVERY_TIMEOUT = 4000;
public static int WS_DISCOVERY_PORT = 3702;
public static String WS_DISCOVERY_ADDRESS_IPv4 = "239.255.255.250";
public static final String WS_DISCOVERY_SOAP_VERSION = "SOAP 1.2 Protocol";
public static final String WS_DISCOVERY_CONTENT_TYPE = "application/soap+xml";
public static final int WS_DISCOVERY_TIMEOUT = 4000;
public static final int WS_DISCOVERY_PORT = 3702;
public static final String WS_DISCOVERY_ADDRESS_IPv4 = "239.255.255.250";
/**
* IPv6 not supported yet. set enableIPv6 to true for testing if you need IP6 discovery.
*/
public static boolean enableIPv6 = false;
public static String WS_DISCOVERY_ADDRESS_IPv6 = "[FF02::C]";
public static String WS_DISCOVERY_PROBE_MESSAGE = "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" xmlns:tns=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\"><soap:Header><wsa:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</wsa:Action><wsa:MessageID>urn:uuid:c032cfdd-c3ca-49dc-820e-ee6696ad63e2</wsa:MessageID><wsa:To>urn:schemas-xmlsoap-org:ws:2005:04:discovery</wsa:To></soap:Header><soap:Body><tns:Probe/></soap:Body></soap:Envelope>";
private static final Random random = new SecureRandom();
/** IPv6 not supported yet. set enableIPv6 to true for testing if you need IP6 discovery. */
public static final boolean enableIPv6 = false;
public static void main(String[] args) throws InterruptedException {
for (URL url : discoverWsDevicesAsUrls()) {
System.out.println("Device discovered: " + url.toString());
}
}
public static final String WS_DISCOVERY_ADDRESS_IPv6 = "[FF02::C]";
public static final String WS_DISCOVERY_PROBE_MESSAGE =
"<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" xmlns:tns=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\"><soap:Header><wsa:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</wsa:Action><wsa:MessageID>urn:uuid:c032cfdd-c3ca-49dc-820e-ee6696ad63e2</wsa:MessageID><wsa:To>urn:schemas-xmlsoap-org:ws:2005:04:discovery</wsa:To></soap:Header><soap:Body><tns:Probe/></soap:Body></soap:Envelope>";
private static final Random random = new SecureRandom();
/**
* Discover WS device on the local network and returns Urls
*
* @return list of unique device urls
*/
public static Collection<URL> discoverWsDevicesAsUrls() {
return discoverWsDevicesAsUrls("", "");
}
public static void main(String[] args) throws InterruptedException {
for (URL url : discoverWsDevicesAsUrls()) {
System.out.println("Device discovered: " + url.toString());
}
}
/**
* Discover WS device on the local network with specified filter
*
* @param regexpProtocol url protocol matching regexp like "^http$", might be empty ""
* @param regexpPath url path matching regexp like "onvif", might be empty ""
* @return list of unique device urls filtered
*/
public static Collection<URL> discoverWsDevicesAsUrls(String regexpProtocol, String regexpPath) {
final Collection<URL> urls = new TreeSet<>(new Comparator<URL>() {
public int compare(URL o1, URL o2) {
return o1.toString().compareTo(o2.toString());
}
});
for (String key : discoverWsDevices()) {
try {
final URL url = new URL(key);
boolean ok = true;
if (regexpProtocol.length() > 0 && !url.getProtocol().matches(regexpProtocol))
ok = false;
if (regexpPath.length() > 0 && !url.getPath().matches(regexpPath))
ok = false;
// ignore ip6 hosts
if (ok && !enableIPv6 && url.getHost().startsWith("["))
ok = false;
if (ok) urls.add(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
return urls;
}
/**
* Discover WS device on the local network and returns Urls
*
* @return list of unique device urls
*/
public static Collection<URL> discoverWsDevicesAsUrls() {
return discoverWsDevicesAsUrls("", "");
}
/**
* Discover WS device on the local network
*
* @return list of unique devices access strings which might be URLs in most cases
*/
public static Collection<String> discoverWsDevices() {
final Collection<String> addresses = new ConcurrentSkipListSet<>();
final CountDownLatch serverStarted = new CountDownLatch(1);
final CountDownLatch serverFinished = new CountDownLatch(1);
final Collection<InetAddress> addressList = new ArrayList<>();
try {
final Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
if (interfaces != null) {
while (interfaces.hasMoreElements()) {
NetworkInterface anInterface = interfaces.nextElement();
if (!anInterface.isLoopback()) {
final List<InterfaceAddress> interfaceAddresses = anInterface.getInterfaceAddresses();
for (InterfaceAddress address : interfaceAddresses) {
Class clz = address.getAddress().getClass();
/**
* Discover WS device on the local network with specified filter
*
* @param regexpProtocol url protocol matching regexp like "^http$", might be empty ""
* @param regexpPath url path matching regexp like "onvif", might be empty ""
* @return list of unique device urls filtered
*/
public static Collection<URL> discoverWsDevicesAsUrls(String regexpProtocol, String regexpPath) {
final Collection<URL> urls =
new TreeSet<>(
new Comparator<URL>() {
public int compare(URL o1, URL o2) {
return o1.toString().compareTo(o2.toString());
}
});
for (String key : discoverWsDevices()) {
try {
final URL url = new URL(key);
boolean ok = true;
if (regexpProtocol.length() > 0 && !url.getProtocol().matches(regexpProtocol)) ok = false;
if (regexpPath.length() > 0 && !url.getPath().matches(regexpPath)) ok = false;
// ignore ip6 hosts
if (ok && !enableIPv6 && url.getHost().startsWith("[")) ok = false;
if (ok) urls.add(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
return urls;
}
if (!enableIPv6 && address.getAddress() instanceof Inet6Address)
continue;
addressList.add(address.getAddress());
}
}
}
}
} catch (SocketException e) {
e.printStackTrace();
}
/**
* Discover WS device on the local network
*
* @return list of unique devices access strings which might be URLs in most cases
*/
public static Collection<String> discoverWsDevices() {
final Collection<String> addresses = new ConcurrentSkipListSet<>();
final CountDownLatch serverStarted = new CountDownLatch(1);
final CountDownLatch serverFinished = new CountDownLatch(1);
final Collection<InetAddress> addressList = new ArrayList<>();
try {
final Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
if (interfaces != null) {
while (interfaces.hasMoreElements()) {
NetworkInterface anInterface = interfaces.nextElement();
if (!anInterface.isLoopback()) {
final List<InterfaceAddress> interfaceAddresses = anInterface.getInterfaceAddresses();
for (InterfaceAddress address : interfaceAddresses) {
Class clz = address.getAddress().getClass();
if (!enableIPv6 && address.getAddress() instanceof Inet6Address) continue;
addressList.add(address.getAddress());
}
}
}
}
} catch (SocketException e) {
e.printStackTrace();
}
ExecutorService executorService = Executors.newCachedThreadPool();
for (final InetAddress address : addressList) {
Runnable runnable = new Runnable() {
public void run() {
try {
final String uuid = UUID.randomUUID().toString();
final String probe = WS_DISCOVERY_PROBE_MESSAGE.replaceAll("<wsa:MessageID>urn:uuid:.*</wsa:MessageID>", "<wsa:MessageID>urn:uuid:" + uuid + "</wsa:MessageID>");
final int port = random.nextInt(20000) + 40000;
@SuppressWarnings("SocketOpenedButNotSafelyClosed") final DatagramSocket server = new DatagramSocket(port, address);
new Thread() {
public void run() {
try {
final DatagramPacket packet = new DatagramPacket(new byte[4096], 4096);
server.setSoTimeout(WS_DISCOVERY_TIMEOUT);
long timerStarted = System.currentTimeMillis();
while (System.currentTimeMillis() - timerStarted < (WS_DISCOVERY_TIMEOUT)) {
serverStarted.countDown();
server.receive(packet);
final Collection<String> collection = parseSoapResponseForUrls(Arrays.copyOf(packet.getData(), packet.getLength()));
for (String key : collection) {
addresses.add(key);
}
}
} catch (SocketTimeoutException ignored) {
} catch (Exception e) {
e.printStackTrace();
} finally {
serverFinished.countDown();
server.close();
}
}
}.start();
try {
serverStarted.await(1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (address instanceof Inet4Address) {
server.send(new DatagramPacket(probe.getBytes(), probe.length(), InetAddress.getByName(WS_DISCOVERY_ADDRESS_IPv4), WS_DISCOVERY_PORT));
} else {
if (address instanceof Inet6Address) {
if (enableIPv6)
server.send(new DatagramPacket(probe.getBytes(), probe.length(), InetAddress.getByName(WS_DISCOVERY_ADDRESS_IPv6), WS_DISCOVERY_PORT));
} else
{
assert(false); // unknown network type.. ignore or warn developer
}
}
ExecutorService executorService = Executors.newCachedThreadPool();
for (final InetAddress address : addressList) {
Runnable runnable =
new Runnable() {
public void run() {
try {
final String uuid = UUID.randomUUID().toString();
final String probe =
WS_DISCOVERY_PROBE_MESSAGE.replaceAll(
"<wsa:MessageID>urn:uuid:.*</wsa:MessageID>",
"<wsa:MessageID>urn:uuid:" + uuid + "</wsa:MessageID>");
final int port = random.nextInt(20000) + 40000;
@SuppressWarnings("SocketOpenedButNotSafelyClosed")
final DatagramSocket server = new DatagramSocket(port, address);
new Thread() {
public void run() {
try {
final DatagramPacket packet = new DatagramPacket(new byte[4096], 4096);
server.setSoTimeout(WS_DISCOVERY_TIMEOUT);
long timerStarted = System.currentTimeMillis();
while (System.currentTimeMillis() - timerStarted < (WS_DISCOVERY_TIMEOUT)) {
serverStarted.countDown();
server.receive(packet);
final Collection<String> collection =
parseSoapResponseForUrls(
Arrays.copyOf(packet.getData(), packet.getLength()));
for (String key : collection) {
addresses.add(key);
}
}
} catch (SocketTimeoutException ignored) {
} catch (Exception e) {
e.printStackTrace();
} finally {
serverFinished.countDown();
server.close();
}
}
}.start();
try {
serverStarted.await(1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (address instanceof Inet4Address) {
server.send(
new DatagramPacket(
probe.getBytes(StandardCharsets.UTF_8),
probe.length(),
InetAddress.getByName(WS_DISCOVERY_ADDRESS_IPv4),
WS_DISCOVERY_PORT));
} else {
if (address instanceof Inet6Address) {
if (enableIPv6)
server.send(
new DatagramPacket(
probe.getBytes(StandardCharsets.UTF_8),
probe.length(),
InetAddress.getByName(WS_DISCOVERY_ADDRESS_IPv6),
WS_DISCOVERY_PORT));
} else {
assert (false); // unknown network type.. ignore or warn developer
}
}
} catch (Exception e) {
e.printStackTrace();
}
try {
serverFinished.await((WS_DISCOVERY_TIMEOUT), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
executorService.submit(runnable);
}
try {
executorService.shutdown();
executorService.awaitTermination(WS_DISCOVERY_TIMEOUT + 2000, TimeUnit.MILLISECONDS);
} catch (InterruptedException ignored) {
}
return addresses;
}
} catch (Exception e) {
e.printStackTrace();
}
try {
serverFinished.await((WS_DISCOVERY_TIMEOUT), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
executorService.submit(runnable);
}
try {
executorService.shutdown();
executorService.awaitTermination(WS_DISCOVERY_TIMEOUT + 2000, TimeUnit.MILLISECONDS);
} catch (InterruptedException ignored) {
}
return addresses;
}
private static Collection<Node> getNodeMatching(Node body, String regexp) {
final Collection<Node> nodes = new ArrayList<>();
if (body.getNodeName().matches(regexp)) nodes.add(body);
if (body.getChildNodes().getLength() == 0) return nodes;
NodeList returnList = body.getChildNodes();
for (int k = 0; k < returnList.getLength(); k++) {
final Node node = returnList.item(k);
nodes.addAll(getNodeMatching(node, regexp));
}
return nodes;
}
private static Collection<Node> getNodeMatching(Node body, String regexp) {
final Collection<Node> nodes = new ArrayList<>();
if (body.getNodeName().matches(regexp)) nodes.add(body);
if (body.getChildNodes().getLength() == 0) return nodes;
NodeList returnList = body.getChildNodes();
for (int k = 0; k < returnList.getLength(); k++) {
final Node node = returnList.item(k);
nodes.addAll(getNodeMatching(node, regexp));
}
return nodes;
}
private static Collection<String> parseSoapResponseForUrls(byte[] data) throws SOAPException, IOException {
//System.out.println(new String(data));
final Collection<String> urls = new ArrayList<>();
MessageFactory factory = MessageFactory.newInstance(WS_DISCOVERY_SOAP_VERSION);
final MimeHeaders headers = new MimeHeaders();
headers.addHeader("Content-type", WS_DISCOVERY_CONTENT_TYPE);
SOAPMessage message = factory.createMessage(headers, new ByteArrayInputStream(data));
SOAPBody body = message.getSOAPBody();
for (Node node : getNodeMatching(body, ".*:XAddrs")) {
if (node.getTextContent().length() > 0) {
urls.addAll(Arrays.asList(node.getTextContent().split(" ")));
}
}
return urls;
}
private static Collection<String> parseSoapResponseForUrls(byte[] data)
throws SOAPException, IOException {
// System.out.println(new String(data));
final Collection<String> urls = new ArrayList<>();
MessageFactory factory = MessageFactory.newInstance(WS_DISCOVERY_SOAP_VERSION);
final MimeHeaders headers = new MimeHeaders();
headers.addHeader("Content-type", WS_DISCOVERY_CONTENT_TYPE);
SOAPMessage message = factory.createMessage(headers, new ByteArrayInputStream(data));
SOAPBody body = message.getSOAPBody();
for (Node node : getNodeMatching(body, ".*:XAddrs")) {
if (node.getTextContent().length() > 0) {
urls.addAll(Arrays.asList(node.getTextContent().split(" ")));
}
}
return urls;
}
}

View File

@@ -3,15 +3,13 @@ package de.onvif.discovery;
import java.net.URL;
import java.util.Collection;
/**
* @author th
* @date 2015-06-18
*/
public class OnvifDiscovery {
public static Collection<URL> discoverOnvifURLs() {
return DeviceDiscovery.discoverWsDevicesAsUrls("^http$", ".*onvif.*");
}
public static Collection<URL> discoverOnvifURLs() {
return DeviceDiscovery.discoverWsDevicesAsUrls("^http$", ".*onvif.*");
}
}

View File

@@ -1,6 +1,17 @@
package de.onvif.soap;
import de.onvif.beans.DeviceInfo;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import javax.xml.soap.SOAPException;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Holder;
import org.apache.cxf.binding.soap.Soap12;
import org.apache.cxf.binding.soap.SoapBindingConfiguration;
import org.apache.cxf.endpoint.Client;
@@ -16,7 +27,15 @@ import org.onvif.ver10.events.wsdl.EventPortType;
import org.onvif.ver10.events.wsdl.EventService;
import org.onvif.ver10.media.wsdl.Media;
import org.onvif.ver10.media.wsdl.MediaService;
import org.onvif.ver10.schema.*;
import org.onvif.ver10.schema.Capabilities;
import org.onvif.ver10.schema.CapabilityCategory;
import org.onvif.ver10.schema.DateTime;
import org.onvif.ver10.schema.MediaUri;
import org.onvif.ver10.schema.SetDateTimeType;
import org.onvif.ver10.schema.StreamSetup;
import org.onvif.ver10.schema.StreamType;
import org.onvif.ver10.schema.Transport;
import org.onvif.ver10.schema.TransportProtocol;
import org.onvif.ver20.imaging.wsdl.ImagingPort;
import org.onvif.ver20.imaging.wsdl.ImagingService;
import org.onvif.ver20.ptz.wsdl.PTZ;
@@ -24,271 +43,283 @@ import org.onvif.ver20.ptz.wsdl.PtzService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.xml.soap.SOAPException;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Holder;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
/**
* @author Robin Dick
* @author Modified by Brad Lowe
*/
public class OnvifDevice {
private static final Logger logger = LoggerFactory.getLogger(OnvifDevice.class);
private static final String DEVICE_SERVICE = "/onvif/device_service";
private static final Logger logger = LoggerFactory.getLogger(OnvifDevice.class);
private static final String DEVICE_SERVICE = "/onvif/device_service";
final private URL url; // Example http://host:port, https://host, http://host, http://ip_address
private final URL url; // Example http://host:port, https://host, http://host, http://ip_address
private Device device;
private Media media;
private PTZ ptz;
private ImagingPort imaging;
private EventPortType events;
public static boolean verbose = false; // enable/disable logging of SOAP messages
final SimpleSecurityHandler securityHandler;
private Device device;
private Media media;
private PTZ ptz;
private ImagingPort imaging;
private EventPortType events;
/*
* @param url is http://host or http://host:port or https://host or https://host:port
* @param user Username you need to login, or "" for none
* @param password User's password to login, or "" for none
*/
public OnvifDevice(URL url, String user, String password) throws ConnectException, SOAPException, MalformedURLException {
this.url = url;
String f = url.getFile();
if (!f.isEmpty()) throw new MalformedURLException("Expected empty file in URL, not:" + f);
securityHandler = !user.isEmpty() && !password.isEmpty() ? new SimpleSecurityHandler(user, password) : null;
init();
}
private static boolean verbose = false; // enable/disable logging of SOAP messages
final SimpleSecurityHandler securityHandler;
/*
* @param url is http://host or http://host:port or https://host or https://host:port
* @param user Username you need to login, or "" for none
* @param password User's password to login, or "" for none
*/
public OnvifDevice(URL url, String user, String password)
throws ConnectException, SOAPException, MalformedURLException {
this.url = url;
String f = url.getFile();
if (!f.isEmpty()) throw new MalformedURLException("Expected empty file in URL, not:" + f);
securityHandler =
!user.isEmpty() && !password.isEmpty() ? new SimpleSecurityHandler(user, password) : null;
init();
}
/**
* Initializes an Onvif device, e.g. a Network Video Transmitter (NVT) with
* logindata.
*
* @param deviceIp The IP address or host name of your device, you can also add a port
* @param user Username you need to login
* @param password User's password to login
* @throws ConnectException Exception gets thrown, if device isn't accessible or invalid
* and doesn't answer to SOAP messages
* @throws SOAPException
*/
public OnvifDevice(String deviceIp, String user, String password) throws ConnectException, SOAPException, MalformedURLException {
this(deviceIp.startsWith("http")? new URL(deviceIp):new URL("http://" + deviceIp), user, password);
}
/**
* Initializes an Onvif device, e.g. a Network Video Transmitter (NVT) with logindata.
*
* @param deviceIp The IP address or host name of your device, you can also add a port
* @param user Username you need to login
* @param password User's password to login
* @throws ConnectException Exception gets thrown, if device isn't accessible or invalid and
* doesn't answer to SOAP messages
* @throws SOAPException
*/
public OnvifDevice(String deviceIp, String user, String password)
throws ConnectException, SOAPException, MalformedURLException {
this(
deviceIp.startsWith("http") ? new URL(deviceIp) : new URL("http://" + deviceIp),
user,
password);
}
/**
* Initializes an Onvif device, e.g. a Network Video Transmitter (NVT) with
* logindata.
*
* @param hostIp The IP address of your device, you can also add a port but
* noch protocol (e.g. http://)
* @throws ConnectException Exception gets thrown, if device isn't accessible or invalid
* and doesn't answer to SOAP messages
* @throws SOAPException
*/
public OnvifDevice(String hostIp) throws ConnectException, SOAPException, MalformedURLException {
this(hostIp, null, null);
}
/**
* Initializes an Onvif device, e.g. a Network Video Transmitter (NVT) with logindata.
*
* @param hostIp The IP address of your device, you can also add a port but noch protocol (e.g.
* http://)
* @throws ConnectException Exception gets thrown, if device isn't accessible or invalid and
* doesn't answer to SOAP messages
* @throws SOAPException
*/
public OnvifDevice(String hostIp) throws ConnectException, SOAPException, MalformedURLException {
this(hostIp, null, null);
}
/**
* Initalizes the addresses used for SOAP messages and to get the internal IP, if given IP is a
* proxy.
*
* @throws ConnectException Get thrown if device doesn't give answers to GetCapabilities()
* @throws SOAPException
*/
protected void init() throws ConnectException, SOAPException {
/**
* Initalizes the addresses used for SOAP messages and to get the internal
* IP, if given IP is a proxy.
*
* @throws ConnectException Get thrown if device doesn't give answers to
* GetCapabilities()
* @throws SOAPException
*/
protected void init() throws ConnectException, SOAPException {
DeviceService deviceService = new DeviceService(null, DeviceService.SERVICE);
DeviceService deviceService = new DeviceService(null, DeviceService.SERVICE);
BindingProvider deviceServicePort = (BindingProvider) deviceService.getDevicePort();
this.device =
getServiceProxy(deviceServicePort, url.toString() + DEVICE_SERVICE).create(Device.class);
BindingProvider deviceServicePort = (BindingProvider) deviceService.getDevicePort();
this.device = getServiceProxy(deviceServicePort, url.toString() + DEVICE_SERVICE).create(Device.class);
// resetSystemDateAndTime(); // don't modify the camera in a constructor.. :)
// resetSystemDateAndTime(); // don't modify the camera in a constructor.. :)
Capabilities capabilities = this.device.getCapabilities(Arrays.asList(CapabilityCategory.ALL));
if (capabilities == null) {
throw new ConnectException("Capabilities not reachable.");
}
Capabilities capabilities = this.device.getCapabilities(Arrays.asList(CapabilityCategory.ALL));
if (capabilities == null) {
throw new ConnectException("Capabilities not reachable.");
}
if (capabilities.getMedia() != null && capabilities.getMedia().getXAddr() != null) {
this.media = new MediaService().getMediaPort();
this.media =
getServiceProxy((BindingProvider) media, capabilities.getMedia().getXAddr())
.create(Media.class);
}
if (capabilities.getMedia() != null && capabilities.getMedia().getXAddr() != null) {
this.media = new MediaService().getMediaPort();
this.media = getServiceProxy((BindingProvider) media, capabilities.getMedia().getXAddr()).create(Media.class);
}
if (capabilities.getPTZ() != null && capabilities.getPTZ().getXAddr() != null) {
this.ptz = new PtzService().getPtzPort();
this.ptz =
getServiceProxy((BindingProvider) ptz, capabilities.getPTZ().getXAddr())
.create(PTZ.class);
}
if (capabilities.getPTZ() != null && capabilities.getPTZ().getXAddr() != null) {
this.ptz = new PtzService().getPtzPort();
this.ptz = getServiceProxy((BindingProvider) ptz, capabilities.getPTZ().getXAddr()).create(PTZ.class);
}
if (capabilities.getImaging() != null && capabilities.getImaging().getXAddr() != null) {
this.imaging = new ImagingService().getImagingPort();
this.imaging =
getServiceProxy((BindingProvider) imaging, capabilities.getImaging().getXAddr())
.create(ImagingPort.class);
}
if (capabilities.getImaging() != null && capabilities.getImaging().getXAddr() != null) {
this.imaging = new ImagingService().getImagingPort();
this.imaging = getServiceProxy((BindingProvider) imaging, capabilities.getImaging().getXAddr()).create(ImagingPort.class);
}
if (capabilities.getEvents() != null && capabilities.getEvents().getXAddr() != null) {
this.events = new EventService().getEventPort();
this.events =
getServiceProxy((BindingProvider) events, capabilities.getEvents().getXAddr())
.create(EventPortType.class);
}
}
if (capabilities.getEvents() != null && capabilities.getEvents().getXAddr() != null) {
this.events = new EventService().getEventPort();
this.events = getServiceProxy((BindingProvider) events, capabilities.getEvents().getXAddr()).create(EventPortType.class);
}
}
public JaxWsProxyFactoryBean getServiceProxy(BindingProvider servicePort, String serviceAddr) {
JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean();
proxyFactory.getHandlers();
public JaxWsProxyFactoryBean getServiceProxy(BindingProvider servicePort, String serviceAddr) {
if (serviceAddr != null) proxyFactory.setAddress(serviceAddr);
proxyFactory.setServiceClass(servicePort.getClass());
JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean();
proxyFactory.getHandlers();
SoapBindingConfiguration config = new SoapBindingConfiguration();
if (serviceAddr != null)
proxyFactory.setAddress(serviceAddr);
proxyFactory.setServiceClass(servicePort.getClass());
config.setVersion(Soap12.getInstance());
proxyFactory.setBindingConfig(config);
Client deviceClient = ClientProxy.getClient(servicePort);
SoapBindingConfiguration config = new SoapBindingConfiguration();
if (verbose) {
// these logging interceptors are depreciated, but should be fine for debugging/development
// use.
proxyFactory.getOutInterceptors().add(new LoggingOutInterceptor());
proxyFactory.getInInterceptors().add(new LoggingInInterceptor());
}
config.setVersion(Soap12.getInstance());
proxyFactory.setBindingConfig(config);
Client deviceClient = ClientProxy.getClient(servicePort);
HTTPConduit http = (HTTPConduit) deviceClient.getConduit();
if (securityHandler != null) proxyFactory.getHandlers().add(securityHandler);
HTTPClientPolicy httpClientPolicy = http.getClient();
httpClientPolicy.setConnectionTimeout(36000);
httpClientPolicy.setReceiveTimeout(32000);
httpClientPolicy.setAllowChunking(false);
if (verbose) {
// these logging interceptors are depreciated, but should be fine for debugging/development use.
proxyFactory.getOutInterceptors().add(new LoggingOutInterceptor());
proxyFactory.getInInterceptors().add(new LoggingInInterceptor());
}
return proxyFactory;
}
HTTPConduit http = (HTTPConduit) deviceClient.getConduit();
if (securityHandler != null)
proxyFactory.getHandlers().add(securityHandler);
HTTPClientPolicy httpClientPolicy = http.getClient();
httpClientPolicy.setConnectionTimeout(36000);
httpClientPolicy.setReceiveTimeout(32000);
httpClientPolicy.setAllowChunking(false);
public void resetSystemDateAndTime() {
Calendar calendar = Calendar.getInstance();
Date currentDate = new Date();
boolean daylightSavings = calendar.getTimeZone().inDaylightTime(currentDate);
org.onvif.ver10.schema.TimeZone timeZone = new org.onvif.ver10.schema.TimeZone();
timeZone.setTZ(displayTimeZone(calendar.getTimeZone()));
org.onvif.ver10.schema.Time time = new org.onvif.ver10.schema.Time();
time.setHour(calendar.get(Calendar.HOUR_OF_DAY));
time.setMinute(calendar.get(Calendar.MINUTE));
time.setSecond(calendar.get(Calendar.SECOND));
org.onvif.ver10.schema.Date date = new org.onvif.ver10.schema.Date();
date.setYear(calendar.get(Calendar.YEAR));
date.setMonth(calendar.get(Calendar.MONTH) + 1);
date.setDay(calendar.get(Calendar.DAY_OF_MONTH));
org.onvif.ver10.schema.DateTime utcDateTime = new org.onvif.ver10.schema.DateTime();
utcDateTime.setDate(date);
utcDateTime.setTime(time);
device.setSystemDateAndTime(SetDateTimeType.MANUAL, daylightSavings, timeZone, utcDateTime);
}
return proxyFactory;
}
private static String displayTimeZone(TimeZone tz) {
long hours = TimeUnit.MILLISECONDS.toHours(tz.getRawOffset());
long minutes =
TimeUnit.MILLISECONDS.toMinutes(tz.getRawOffset()) - TimeUnit.HOURS.toMinutes(hours);
// avoid -4:-30 issue
minutes = Math.abs(minutes);
public void resetSystemDateAndTime() {
Calendar calendar = Calendar.getInstance();
Date currentDate = new Date();
boolean daylightSavings = calendar.getTimeZone().inDaylightTime(currentDate);
org.onvif.ver10.schema.TimeZone timeZone = new org.onvif.ver10.schema.TimeZone();
timeZone.setTZ(displayTimeZone(calendar.getTimeZone()));
org.onvif.ver10.schema.Time time = new org.onvif.ver10.schema.Time();
time.setHour(calendar.get(Calendar.HOUR_OF_DAY));
time.setMinute(calendar.get(Calendar.MINUTE));
time.setSecond(calendar.get(Calendar.SECOND));
org.onvif.ver10.schema.Date date = new org.onvif.ver10.schema.Date();
date.setYear(calendar.get(Calendar.YEAR));
date.setMonth(calendar.get(Calendar.MONTH) + 1);
date.setDay(calendar.get(Calendar.DAY_OF_MONTH));
org.onvif.ver10.schema.DateTime utcDateTime = new org.onvif.ver10.schema.DateTime();
utcDateTime.setDate(date);
utcDateTime.setTime(time);
device.setSystemDateAndTime(SetDateTimeType.MANUAL, daylightSavings, timeZone, utcDateTime);
}
String result = "";
if (hours > 0) {
result = String.format("GMT+%02d:%02d", hours, minutes);
} else {
result = String.format("GMT%02d:%02d", hours, minutes);
}
private static String displayTimeZone(TimeZone tz) {
return result;
}
long hours = TimeUnit.MILLISECONDS.toHours(tz.getRawOffset());
long minutes = TimeUnit.MILLISECONDS.toMinutes(tz.getRawOffset()) - TimeUnit.HOURS.toMinutes(hours);
// avoid -4:-30 issue
minutes = Math.abs(minutes);
/** Is used for basic devices and requests of given Onvif Device */
public Device getDevice() {
return device;
}
String result = "";
if (hours > 0) {
result = String.format("GMT+%02d:%02d", hours, minutes);
} else {
result = String.format("GMT%02d:%02d", hours, minutes);
}
public PTZ getPtz() {
return ptz;
}
return result;
}
public Media getMedia() {
return media;
}
/**
* Is used for basic devices and requests of given Onvif Device
*/
public Device getDevice() {
return device;
}
public ImagingPort getImaging() {
return imaging;
}
public PTZ getPtz() {
return ptz;
}
public EventPortType getEvents() {
return events;
}
public Media getMedia() {
return media;
}
public DateTime getDate() {
return device.getSystemDateAndTime().getLocalDateTime();
}
public ImagingPort getImaging() {
return imaging;
}
public DeviceInfo getDeviceInfo() {
Holder<String> manufacturer = new Holder<>();
Holder<String> model = new Holder<>();
Holder<String> firmwareVersion = new Holder<>();
Holder<String> serialNumber = new Holder<>();
Holder<String> hardwareId = new Holder<>();
device.getDeviceInformation(manufacturer, model, firmwareVersion, serialNumber, hardwareId);
return new DeviceInfo(
manufacturer.value,
model.value,
firmwareVersion.value,
serialNumber.value,
hardwareId.value);
}
public EventPortType getEvents() {
return events;
}
public String getHostname() {
return device.getHostname().getName();
}
public DateTime getDate() {
return device.getSystemDateAndTime().getLocalDateTime();
}
public String reboot() throws ConnectException, SOAPException {
return device.systemReboot();
}
public DeviceInfo getDeviceInfo() {
Holder<String> manufacturer = new Holder<>();
Holder<String> model = new Holder<>();
Holder<String> firmwareVersion = new Holder<>();
Holder<String> serialNumber = new Holder<>();
Holder<String> hardwareId = new Holder<>();
device.getDeviceInformation(manufacturer, model, firmwareVersion, serialNumber, hardwareId);
return new DeviceInfo(manufacturer.value, model.value, firmwareVersion.value, serialNumber.value,
hardwareId.value);
}
// returns http://host[:port]/path_for_snapshot
public String getSnapshotUri(String profileToken) {
MediaUri sceenshotUri = media.getSnapshotUri(profileToken);
if (sceenshotUri != null) {
return sceenshotUri.getUri();
}
return "";
}
public String getHostname() {
return device.getHostname().getName();
}
public String getSnapshotUri() {
return getSnapshotUri(0);
}
public String reboot() throws ConnectException, SOAPException {
return device.systemReboot();
}
public String getRTSPUri() {
return getRTSPUri(0);
}
// returns http://host[:port]/path_for_snapshot
public String getSnapshotUri(String profileToken) {
MediaUri sceenshotUri = media.getSnapshotUri(profileToken);
if (sceenshotUri!=null)
{
try {
URL u = new URL(sceenshotUri.getUri());
// if using port forwarding, this URL may be incorrect..
// Here we can normalize the URL to use the
String up = url.toString() + u.getFile();
return up;
}catch(MalformedURLException m)
{
// This should never happen.
logger.error(sceenshotUri.getUri(), m);
}
}
return "";
}
// Get snapshot uri for profile with index
public String getSnapshotUri(int index) {
if (media.getProfiles().size() >= index)
return getSnapshotUri(media.getProfiles().get(index).getToken());
return "";
}
// returns rtsp://host[:port]/path_for_rtsp
public String getRTSPURL(String profileToken) {
StreamSetup streamSetup = new StreamSetup();
Transport t = new Transport();
t.setProtocol(TransportProtocol.RTSP);
streamSetup.setTransport(t);
streamSetup.setStream(StreamType.RTP_UNICAST);
MediaUri rtsp = media.getStreamUri(streamSetup, profileToken);
public String getRTSPUri(int index) {
return getRTSPUri(media.getProfiles().get(index).getToken());
}
return rtsp!=null ? rtsp.getUri():"";
}
// returns rtsp://host[:port]/path_for_rtsp
public String getRTSPUri(String profileToken) {
StreamSetup streamSetup = new StreamSetup();
Transport t = new Transport();
t.setProtocol(TransportProtocol.RTSP);
streamSetup.setTransport(t);
streamSetup.setStream(StreamType.RTP_UNICAST);
MediaUri rtsp = media.getStreamUri(streamSetup, profileToken);
return rtsp != null ? rtsp.getUri() : "";
}
public static boolean isVerbose() {
return verbose;
}
public static void setVerbose(boolean verbose) {
OnvifDevice.verbose = verbose;
}
}

View File

@@ -0,0 +1,282 @@
package de.onvif.soap;
/** @author schrepfler */
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
/**
* This class provide various static methods that relax X509 certificate and hostname verification
* while using the SSL over the HTTP protocol.
*
* @author Francis Labrie
*/
public final class SSLUtilities {
/**
* Hostname verifier for the Sun's deprecated API.
*
* @deprecated see {@link #_hostnameVerifier}.
*/
private static HostnameVerifier __hostnameVerifier;
/**
* Thrust managers for the Sun's deprecated API.
*
* @deprecated see {@link #_trustManagers}.
*/
private static TrustManager[] __trustManagers;
/** Hostname verifier. */
private static HostnameVerifier _hostnameVerifier;
/** Thrust managers. */
private static TrustManager[] _trustManagers;
/**
* Set the default Hostname Verifier to an instance of a fake class that trust all hostnames. This
* method uses the old deprecated API from the com.sun.ssl package.
*
* @deprecated see {@link #_trustAllHostnames()}.
*/
private static void __trustAllHostnames() {
// Create a trust manager that does not validate certificate chains
if (__hostnameVerifier == null) {
__hostnameVerifier = new _FakeHostnameVerifier();
} // if
// Install the all-trusting host name verifier
HttpsURLConnection.setDefaultHostnameVerifier(__hostnameVerifier);
} // __trustAllHttpsCertificates
/**
* Set the default X509 Trust Manager to an instance of a fake class that trust all certificates,
* even the self-signed ones. This method uses the old deprecated API from the com.sun.ssl
* package.
*
* @deprecated see {@link #_trustAllHttpsCertificates()}.
*/
private static void __trustAllHttpsCertificates() {
SSLContext context;
// Create a trust manager that does not validate certificate chains
if (__trustManagers == null) {
__trustManagers = new TrustManager[] {new _FakeX509TrustManager()};
} // if
// Install the all-trusting trust manager
try {
context = SSLContext.getInstance("SSL");
context.init(null, __trustManagers, new SecureRandom());
} catch (GeneralSecurityException gse) {
throw new IllegalStateException(gse.getMessage());
} // catch
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
} // __trustAllHttpsCertificates
/**
* Return true if the protocol handler property java. protocol.handler.pkgs is set to the Sun's
* com.sun.net.ssl. internal.www.protocol deprecated one, false otherwise.
*
* @return true if the protocol handler property is set to the Sun's deprecated one, false
* otherwise.
*/
private static boolean isDeprecatedSSLProtocol() {
return ("com.sun.net.ssl.internal.www.protocol"
.equals(System.getProperty("java.protocol.handler.pkgs")));
} // isDeprecatedSSLProtocol
/** Set the default Hostname Verifier to an instance of a fake class that trust all hostnames. */
private static void _trustAllHostnames() {
// Create a trust manager that does not validate certificate chains
if (_hostnameVerifier == null) {
_hostnameVerifier = new FakeHostnameVerifier();
} // if
// Install the all-trusting host name verifier:
HttpsURLConnection.setDefaultHostnameVerifier(_hostnameVerifier);
} // _trustAllHttpsCertificates
/**
* Set the default X509 Trust Manager to an instance of a fake class that trust all certificates,
* even the self-signed ones.
*/
private static void _trustAllHttpsCertificates() {
SSLContext context;
// Create a trust manager that does not validate certificate chains
if (_trustManagers == null) {
_trustManagers = new TrustManager[] {new FakeX509TrustManager()};
} // if
// Install the all-trusting trust manager:
try {
context = SSLContext.getInstance("SSL");
context.init(null, _trustManagers, new SecureRandom());
} catch (GeneralSecurityException gse) {
throw new IllegalStateException(gse.getMessage());
} // catch
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
} // _trustAllHttpsCertificates
/** Set the default Hostname Verifier to an instance of a fake class that trust all hostnames. */
public static void trustAllHostnames() {
// Is the deprecated protocol setted?
if (isDeprecatedSSLProtocol()) {
__trustAllHostnames();
} else {
_trustAllHostnames();
} // else
} // trustAllHostnames
/**
* Set the default X509 Trust Manager to an instance of a fake class that trust all certificates,
* even the self-signed ones.
*/
public static void trustAllHttpsCertificates() {
// Is the deprecated protocol setted?
if (isDeprecatedSSLProtocol()) {
__trustAllHttpsCertificates();
} else {
_trustAllHttpsCertificates();
} // else
} // trustAllHttpsCertificates
/**
* This class implements a fake hostname verificator, trusting any host name. This class uses the
* old deprecated API from the com.sun. ssl package.
*
* @author Francis Labrie
* @deprecated see {@link SSLUtilities.FakeHostnameVerifier}.
*/
public static class _FakeHostnameVerifier implements HostnameVerifier {
/**
* Always return true, indicating that the host name is an acceptable match with the server's
* authentication scheme.
*
* @param hostname the host name.
* @param session the SSL session used on the connection to host.
* @return the true boolean value indicating the host name is trusted.
*/
public boolean verify(String hostname, SSLSession session) {
return (true);
}
} // _FakeHostnameVerifier
/**
* This class allow any X509 certificates to be used to authenticate the remote side of a secure
* socket, including self-signed certificates. This class uses the old deprecated API from the
* com.sun.ssl package.
*
* @author Francis Labrie
* @deprecated see {@link SSLUtilities.FakeX509TrustManager}.
*/
public static class _FakeX509TrustManager implements X509TrustManager {
/** Empty array of certificate authority certificates. */
private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[] {};
/**
* Always return true, trusting for client SSL chain peer certificate chain.
*
* @param chain the peer certificate chain.
* @return the true boolean value indicating the chain is trusted.
*/
public boolean isClientTrusted(X509Certificate[] chain) {
return (true);
} // checkClientTrusted
/**
* Always return true, trusting for server SSL chain peer certificate chain.
*
* @param chain the peer certificate chain.
* @return the true boolean value indicating the chain is trusted.
*/
public boolean isServerTrusted(X509Certificate[] chain) {
return (true);
} // checkServerTrusted
/**
* Return an empty array of certificate authority certificates which are trusted for
* authenticating peers.
*
* @return a empty array of issuer certificates.
*/
public X509Certificate[] getAcceptedIssuers() {
return (_AcceptedIssuers);
} // getAcceptedIssuers
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
throw new UnsupportedOperationException("Not supported yet.");
}
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
throw new UnsupportedOperationException("Not supported yet.");
}
} // _FakeX509TrustManager
/**
* This class implements a fake hostname verificator, trusting any host name.
*
* @author Francis Labrie
*/
public static class FakeHostnameVerifier implements HostnameVerifier {
/**
* Always return true, indicating that the host name is an acceptable match with the server's
* authentication scheme.
*
* @param hostname the host name.
* @param session the SSL session used on the connection to host.
* @return the true boolean value indicating the host name is trusted.
*/
public boolean verify(String hostname, SSLSession session) {
return (true);
} // verify
} // FakeHostnameVerifier
/**
* This class allow any X509 certificates to be used to authenticate the remote side of a secure
* socket, including self-signed certificates.
*
* @author Francis Labrie
*/
public static class FakeX509TrustManager implements X509TrustManager {
/** Empty array of certificate authority certificates. */
private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[] {};
/**
* Always trust for client SSL chain peer certificate chain with any authType authentication
* types.
*
* @param chain the peer certificate chain.
* @param authType the authentication type based on the client certificate.
*/
public void checkClientTrusted(
X509Certificate[] chain, String authType) {} // checkClientTrusted
/**
* Always trust for server SSL chain peer certificate chain with any authType exchange algorithm
* types.
*
* @param chain the peer certificate chain.
* @param authType the key exchange algorithm used.
*/
public void checkServerTrusted(
X509Certificate[] chain, String authType) {} // checkServerTrusted
/**
* Return an empty array of certificate authority certificates which are trusted for
* authenticating peers.
*
* @return a empty array of issuer certificates.
*/
public X509Certificate[] getAcceptedIssuers() {
return (_AcceptedIssuers);
} // getAcceptedIssuers
} // FakeX509TrustManager
} // SSLUtilities

View File

@@ -1,129 +1,154 @@
package de.onvif.soap;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.MessageDigestAlgorithms;
import static org.apache.wss4j.common.WSS4JConstants.BASE64_ENCODING;
import static org.apache.wss4j.common.WSS4JConstants.CREATED_LN;
import static org.apache.wss4j.common.WSS4JConstants.NONCE_LN;
import static org.apache.wss4j.common.WSS4JConstants.PASSWORD_DIGEST;
import static org.apache.wss4j.common.WSS4JConstants.PASSWORD_LN;
import static org.apache.wss4j.common.WSS4JConstants.PASSWORD_TYPE_ATTR;
import static org.apache.wss4j.common.WSS4JConstants.USERNAME_LN;
import static org.apache.wss4j.common.WSS4JConstants.USERNAME_TOKEN_LN;
import static org.apache.wss4j.common.WSS4JConstants.WSSE_LN;
import static org.apache.wss4j.common.WSS4JConstants.WSSE_NS;
import static org.apache.wss4j.common.WSS4JConstants.WSSE_PREFIX;
import static org.apache.wss4j.common.WSS4JConstants.WSU_NS;
import static org.apache.wss4j.common.WSS4JConstants.WSU_PREFIX;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Random;
import java.util.Set;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
import javax.xml.namespace.QName;
import javax.xml.soap.*;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
import static org.apache.wss4j.common.WSS4JConstants.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.MessageDigestAlgorithms;
/*
Utility class to add user/password onvif credentials to SOAP communications
*/
public class SimpleSecurityHandler implements SOAPHandler<SOAPMessageContext> {
private String username;
private String password;
private String nonce;
private String utcTime;
public SimpleSecurityHandler(String username,String password){
this.username = username;
this.password = password;
this.nonce = "" + new Random().nextInt();
}
private final String username;
private final String password;
private final String nonce;
private String utcTime;
private static Random rnd = new SecureRandom();
@Override
public boolean handleMessage(final SOAPMessageContext msgCtx) {
// System.out.println("SimpleSecurityHandler");
public SimpleSecurityHandler(String username, String password) {
this.username = username;
this.password = password;
this.nonce = "" + rnd.nextInt();
}
// Indicator telling us which direction this message is going in
final Boolean outInd = (Boolean) msgCtx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
@Override
public boolean handleMessage(final SOAPMessageContext msgCtx) {
// System.out.println("SimpleSecurityHandler");
// Handler must only add security headers to outbound messages
if (outInd.booleanValue()) {
try {
// Create the xml
SOAPMessage soapMessage = msgCtx.getMessage();
SOAPEnvelope envelope = soapMessage.getSOAPPart().getEnvelope();
SOAPHeader header = envelope.getHeader();
if (header == null)
header = envelope.addHeader();
// Indicator telling us which direction this message is going in
final Boolean outInd = (Boolean) msgCtx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
SOAPPart sp = soapMessage.getSOAPPart();
SOAPEnvelope se = sp.getEnvelope();
se.addNamespaceDeclaration(WSSE_PREFIX, WSSE_NS);
se.addNamespaceDeclaration(WSU_PREFIX, WSU_NS);
// Handler must only add security headers to outbound messages
if (outInd.booleanValue()) {
try {
// Create the xml
SOAPMessage soapMessage = msgCtx.getMessage();
SOAPEnvelope envelope = soapMessage.getSOAPPart().getEnvelope();
SOAPHeader header = envelope.getHeader();
if (header == null) header = envelope.addHeader();
SOAPElement securityElem = header.addChildElement(WSSE_LN, WSSE_PREFIX);
// securityElem.setAttribute("SOAP-ENV:mustUnderstand", "1");
SOAPPart sp = soapMessage.getSOAPPart();
SOAPEnvelope se = sp.getEnvelope();
se.addNamespaceDeclaration(WSSE_PREFIX, WSSE_NS);
se.addNamespaceDeclaration(WSU_PREFIX, WSU_NS);
SOAPElement usernameTokenElem = securityElem.addChildElement(USERNAME_TOKEN_LN, WSSE_PREFIX);
SOAPElement securityElem = header.addChildElement(WSSE_LN, WSSE_PREFIX);
// securityElem.setAttribute("SOAP-ENV:mustUnderstand", "1");
SOAPElement usernameElem = usernameTokenElem.addChildElement(USERNAME_LN, WSSE_PREFIX);
usernameElem.setTextContent(username);
SOAPElement usernameTokenElem =
securityElem.addChildElement(USERNAME_TOKEN_LN, WSSE_PREFIX);
SOAPElement passwordElem = usernameTokenElem.addChildElement(PASSWORD_LN, WSSE_PREFIX);
passwordElem.setAttribute(PASSWORD_TYPE_ATTR, PASSWORD_DIGEST);
passwordElem.setTextContent(encryptPassword(password));
SOAPElement usernameElem = usernameTokenElem.addChildElement(USERNAME_LN, WSSE_PREFIX);
usernameElem.setTextContent(username);
SOAPElement nonceElem = usernameTokenElem.addChildElement(NONCE_LN, WSSE_PREFIX);
nonceElem.setAttribute("EncodingType", BASE64_ENCODING);
nonceElem.setTextContent(Base64.encodeBase64String(nonce.getBytes()));
SOAPElement passwordElem = usernameTokenElem.addChildElement(PASSWORD_LN, WSSE_PREFIX);
passwordElem.setAttribute(PASSWORD_TYPE_ATTR, PASSWORD_DIGEST);
passwordElem.setTextContent(encryptPassword(password));
SOAPElement createdElem = usernameTokenElem.addChildElement(CREATED_LN, WSU_PREFIX);
createdElem.setTextContent(getLastUTCTime());
} catch (final Exception e) {
e.printStackTrace();
return false;
}
SOAPElement nonceElem = usernameTokenElem.addChildElement(NONCE_LN, WSSE_PREFIX);
nonceElem.setAttribute("EncodingType", BASE64_ENCODING);
nonceElem.setTextContent(Base64.encodeBase64String(nonce.getBytes()));
}
return true;
}
public String getLastUTCTime() {
return utcTime;
}
public String getUTCTime() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-d'T'HH:mm:ss'Z'");
sdf.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
String utcTime = sdf.format(cal.getTime());
this.utcTime = utcTime;
return utcTime;
}
public String encryptPassword(String password) {
String timestamp = getUTCTime();
String beforeEncryption = nonce + timestamp + password;
byte[] encryptedRaw;
try {
encryptedRaw = sha1(beforeEncryption);
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
String encoded = Base64.encodeBase64String(encryptedRaw);
return encoded;
}
// Other required methods on interface need no guts
private static byte[] sha1(String s) throws NoSuchAlgorithmException {
MessageDigest SHA1 = MessageDigest.getInstance(MessageDigestAlgorithms.SHA_1);
SHA1.reset();
SHA1.update(s.getBytes());
return SHA1.digest();
}
@Override
public boolean handleFault(SOAPMessageContext context) {
// TODO Auto-generated method stub
SOAPElement createdElem = usernameTokenElem.addChildElement(CREATED_LN, WSU_PREFIX);
createdElem.setTextContent(getLastUTCTime());
} catch (final Exception e) {
e.printStackTrace();
return false;
}
}
return true;
}
@Override
public void close(MessageContext context) {
// TODO Auto-generated method stub
public String getLastUTCTime() {
return utcTime;
}
public String getUTCTime() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-d'T'HH:mm:ss'Z'");
sdf.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
String utcTime = sdf.format(cal.getTime());
this.utcTime = utcTime;
return utcTime;
}
public String encryptPassword(String password) {
String timestamp = getUTCTime();
String beforeEncryption = nonce + timestamp + password;
byte[] encryptedRaw;
try {
encryptedRaw = sha1(beforeEncryption);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
String encoded = Base64.encodeBase64String(encryptedRaw);
return encoded;
}
// Other required methods on interface need no guts
private static byte[] sha1(String s) throws NoSuchAlgorithmException {
MessageDigest SHA1 = MessageDigest.getInstance(MessageDigestAlgorithms.SHA_1);
SHA1.reset();
SHA1.update(s.getBytes());
return SHA1.digest();
}
@Override
public Set<QName> getHeaders() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
// TODO Auto-generated method stub
return false;
}
@Override
public void close(MessageContext context) {
// TODO Auto-generated method stub
}
@Override
public Set<QName> getHeaders() {
// TODO Auto-generated method stub
return null;
}
}

View File

@@ -6,59 +6,63 @@ import org.onvif.ver10.schema.PTZVector;
public class OnvifUtils {
public static String format(PTZVector vector)
{
String out = "";
if (vector!=null)
{
out += "["+vector.getPanTilt().getX()+","+vector.getPanTilt().getY();
if (vector.getZoom()!=null) out += ","+vector.getZoom().getX();
out += "]";
}
return out;
}
public static String format(PTZPreset preset)
{
String out = "";
if (preset!=null)
{
out += preset.getToken()+"/"+preset.getName()+":"+format(preset.getPTZPosition());
}
return out;
}
public static String format(PTZStatus status)
{
String out = "";
if (status!=null)
{
out += "moveStatus="+format(status.getMoveStatus())+" position="+format(status.getPosition())+" time="+status.getUtcTime();
public static String format(PTZVector vector) {
String out = "";
if (vector != null) {
out += "[" + vector.getPanTilt().getX() + "," + vector.getPanTilt().getY();
if (vector.getZoom() != null) out += "," + vector.getZoom().getX();
out += "]";
}
return out;
}
}
return out;
public static String format(PTZPreset preset) {
String out = "";
if (preset != null) {
out += preset.getToken() + "/" + preset.getName() + ":" + format(preset.getPTZPosition());
}
return out;
}
}
public static String format(Object o)
{
String out = "";
if (o!=null)
{
out = o.toString();
for (;;)
{
int ch = out.indexOf("org.onvif.ver");
if (ch==-1) break;
int end = out.indexOf("[", ch);
if (end==-1) { assert(false); break; }//
int at = out.indexOf("@", ch);
if (at==-1||at>end) { assert(false); break;}
public static String format(PTZStatus status) {
String out = "";
if (status != null) {
out +=
"moveStatus="
+ format(status.getMoveStatus())
+ " position="
+ format(status.getPosition())
+ " time="
+ status.getUtcTime();
}
return out;
}
out = out.substring(0, ch)+out.substring(end);
}
public static String format(Object o) {
String out = "";
if (o != null) {
out = o.toString();
for (; ; ) {
int ch = out.indexOf("org.onvif.ver");
if (ch == -1) break;
int end = out.indexOf("[", ch);
if (end == -1) {
assert (false);
break;
} //
int at = out.indexOf("@", ch);
if (at == -1 || at > end) {
assert (false);
break;
}
out = out.replaceAll("<null>",""); // speed=<null>,foo=bar to just speed=,foo=bar
out = out.substring(0, ch) + out.substring(end);
}
// out += preset.getToken()+"/"+preset.getName()+":"+format(preset.getPTZPosition());
}
return out;
}
out = out.replaceAll("<null>", ""); // speed=<null>,foo=bar to just speed=,foo=bar
// out += preset.getToken()+"/"+preset.getName()+":"+format(preset.getPTZPosition());
}
return out;
}
}

View File

@@ -1,10 +0,0 @@
package de.onvif.utils;
import java.net.URL;
import java.util.Comparator;
public class URLComparator implements Comparator<URL> {
public int compare(URL o1, URL o2) {
return o1.toString().compareTo(o2.toString());
}
}

View File

@@ -1,79 +1,65 @@
package org.onvif.client;
import de.onvif.discovery.OnvifDiscovery;
import org.apache.cxf.common.logging.LogUtils;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.logging.Logger;
/* Class calls OnvifDiscovery and for each device URL found, calls TestDevice */
import org.apache.cxf.common.logging.LogUtils;
/**
* 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 = LogUtils.getL7dLogger(TestDevice.class);
private static final Logger LOG = LogUtils.getL7dLogger(TestDevice.class);
public static String discoverAndTest(String user, String password)
{
String out ="";
String sep = "\n";
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 += ("Discovered URL:"+u.toString())+sep;
}
ArrayList<String> results = new ArrayList<>();
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;
int good = 0, bad = 0;
for (URL u : urls) {
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.severe("error:" + u + " " + e.toString());
try {
String result = TestDevice.testCamera(u, user, password);
LOG.info(u + "->" + result);
good++;
results.add(u.toString() + ":" + result);
} catch (Throwable e) {
bad++;
LOG.severe("error:" + u + " " + e.toString());
// 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
// is 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();
}
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 += "RESULTS: "+sep;
for (String s : results)
out += s+sep;
out +=("cameras found:" + urls.size() + " good=" + good + ", bad=" + bad)+sep;
return out;
}
public static void main(String[] args) {
OnvifCredentials creds = GetTestDevice.getOnvifCredentials(args);
String user=null,pass;
if (args.length==3) {
user = args[1];
pass = args[2];
} else
{
user=System.getProperty("ONVIF_USER");
pass=System.getProperty("ONVIF_PASSWORD");;
if (user==null) user="";
if (pass==null) pass="";
}
if (creds.getPassword().isEmpty()) LOG.info("Warning: No password for discover and test...");
LOG.info(discoverAndTest(creds.getUser(),creds.getPassword()));
}
public static void main(String[] args) {
// get user and password.. we will ignore device host
OnvifCredentials creds = GetTestDevice.getOnvifCredentials(args);
if (creds.getPassword().isEmpty()) LOG.info("Warning: No password for discover and test...");
LOG.info(discoverAndTest(creds.getUser(), creds.getPassword()));
}
}

View File

@@ -45,17 +45,20 @@ public class GetTestDevice {
return new OnvifCredentials("","","","");
}
private static OnvifCredentials getFromArgs(String[] args) {
if (args==null||args.length<2) return null;
// 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="";
if (args.length > 0) host = args[0];
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);
}
private static OnvifCredentials getFromProperties() {
public static OnvifCredentials getFromProperties() {
String test = null;
if (test == null) test = System.getProperty(PROPERTY_NAME);
if (test == null) test = System.getenv(PROPERTY_NAME);
@@ -69,7 +72,7 @@ public class GetTestDevice {
private static OnvifCredentials getFromStandardInput() throws IOException {
System.out.println("Getting camera credentials from standard input");
InputStreamReader inputStream = new InputStreamReader(System.in);
InputStreamReader inputStream = new InputStreamReader(System.in, "utf-8");
BufferedReader keyboardInput = new BufferedReader(inputStream);
System.out.println("Please enter camera IP (with port if not 80):");
String cameraAddress = keyboardInput.readLine();

View File

@@ -1,10 +1,10 @@
package org.onvif.client;
public class OnvifCredentials {
private String host; // 92.168.xx.yy
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.
private String profile; // "MediaProfile000" If empty, will use first profile.
public OnvifCredentials(String host, String user, String password, String profile) {
this.host = host;

View File

@@ -27,6 +27,7 @@ public class ReadCommandsFromStdInput {
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;
@@ -48,7 +49,7 @@ public class ReadCommandsFromStdInput {
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();

View File

@@ -1,6 +1,7 @@
package org.onvif.client;
import de.onvif.soap.OnvifDevice;
import de.onvif.utils.OnvifUtils;
import org.apache.commons.io.FileUtils;
import org.onvif.ver10.media.wsdl.Media;
import org.onvif.ver10.schema.*;
@@ -27,72 +28,41 @@ public class SimpleTest {
final Map<String, OnvifDevice> onvifCameras = new HashMap<>();
final Map<String, String> onvifCamerasTokens = new HashMap<>();
final Map<String, OnvifCredentials> credentialsMap = new HashMap<>();
final String propFileRelativePath = "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));
String firstCamId = null;
for (Entry<Object, Object> entry : config.entrySet()) {
String deviceName = (String) entry.getKey();
String[] confStr = ((String) entry.getValue()).split(",");
String deviceIp = confStr[0];
String user = confStr[1];
String password = confStr[2];
// profileToken = "MediaProfile000"/"MediaProfile001";
String profileToken = confStr[3];
try {
System.out.println("Connect to camera, please wait ...");
OnvifDevice cam = new OnvifDevice(deviceIp, user, password);
System.out.printf("Connected to device %s (%s)\n", cam.getDeviceInfo(), deviceName);
onvifCameras.put(deviceName, cam);
onvifCamerasTokens.put(deviceName, profileToken);
if (firstCamId == null)
firstCamId = deviceName;
} catch (ConnectException | SOAPException e1) {
e1.printStackTrace();
System.err.println("No connection to device with ip " + deviceIp + ", please try again.");
System.exit(0);
}
}
if (firstCamId == null) {
System.out.println("No ONVIF devices found");
return;
}
// take the first OnvifDevice
OnvifDevice firstCam = onvifCameras.get(firstCamId);
String profileToken = onvifCamerasTokens.get(firstCamId);
Media media = firstCam.getMedia();
StreamSetup streamSetup = new StreamSetup();
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.toString());
System.out.println(TestDevice.inspect(cam));
Transport t = new Transport();
String snapshotUri = cam.getSnapshotUri();
if (!snapshotUri.isEmpty()) {
File tempFile = File.createTempFile("tmp", ".jpg");
t.setProtocol(TransportProtocol.RTSP);
streamSetup.setTransport(t);
streamSetup.setStream(StreamType.RTP_UNICAST);
// 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());
}
MediaUri rtsp = media.getStreamUri(streamSetup, profileToken);
System.out.println("rtspURL: " + rtsp + ": " + rtsp.getUri());
Profile profile = media.getProfile(profileToken);
// Example 1 - take a snapshot (the file gets deleted once the app ends..)
MediaUri sceenshotUri = media.getSnapshotUri(profileToken);
File tempFile = File.createTempFile("tmp", ".jpg");
FileUtils.copyURLToFile(new URL(sceenshotUri.getUri()), tempFile);
System.out.println("snapshot: " + tempFile.getAbsolutePath() + " length:" + tempFile.length());
PTZ ptz = firstCam.getPtz();
if (ptz != null) {
List<PTZPreset> presets = ptz.getPresets(profileToken);
if (presets != null && !presets.isEmpty()) {
System.out.println("Found " + presets.size() + " presets");
}catch(Throwable th)
{
System.err.println("Error on device: "+k);
th.printStackTrace();
}
}
}

View File

@@ -5,7 +5,6 @@ import de.onvif.soap.OnvifDevice;
import de.onvif.utils.OnvifUtils;
import org.apache.cxf.common.logging.LogUtils;
import org.onvif.ver10.device.wsdl.DeviceServiceCapabilities;
import org.onvif.ver10.device.wsdl.SystemCapabilities;
import org.onvif.ver10.events.wsdl.EventPortType;
import org.onvif.ver10.events.wsdl.GetEventProperties;
import org.onvif.ver10.events.wsdl.GetEventPropertiesResponse;
@@ -15,6 +14,8 @@ import org.onvif.ver20.imaging.wsdl.ImagingPort;
import org.onvif.ver20.ptz.wsdl.Capabilities;
import org.onvif.ver20.ptz.wsdl.PTZ;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.soap.SOAPException;
import java.io.IOException;
@@ -23,7 +24,9 @@ import java.net.URL;
import java.util.List;
import java.util.logging.Logger;
/**
* @author Brad Lowe
*/
public class TestDevice {
private static final Logger LOG = LogUtils.getL7dLogger(TestDevice.class);
@@ -40,19 +43,19 @@ public class TestDevice {
public static String inspect(OnvifDevice device) {
String out = "";
DeviceInfo info = device.getDeviceInfo();
out += "DeviceInfo:" + info + sep;
out += "DeviceInfo:" +sep + "\t" + info + sep;
DeviceServiceCapabilities caps = device.getDevice().getServiceCapabilities();
out += "\tgetServiceCapabilities: " + OnvifUtils.format(caps) + 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.getRTSPURL(profileToken);
String rtsp = device.getRTSPUri(profileToken);
out += "\tProfile: " + profile.getName() + " token=" + profile.getToken() + sep;
out += "\t\trtsp: " + rtsp + sep;
out += "\t\tsnapshot: " + device.getSnapshotUri(profileToken) + sep;
@@ -63,15 +66,12 @@ public class TestDevice {
out += "VideoSources: " + videoSources.size() + sep;
for (VideoSource v : videoSources)
out += "\t" + OnvifUtils.format(v) + sep;
List<AudioSource> audioSources = media.getAudioSources();
out += "AudioSources: " + audioSources.size() + sep;
for (AudioSource a : audioSources)
out += "\t" + OnvifUtils.format(a) + sep;
out += "hostName=" + device.getHostname() + sep;
DeviceServiceCapabilities caps = device.getDevice().getServiceCapabilities();
out += "getServiceCapabilities=" + OnvifUtils.format(caps) + sep;
out += "getServiceCapabilities.getSystem=" + OnvifUtils.format(caps.getSystem()) + sep;
ImagingPort imaging = device.getImaging();
if (imaging != null && videoSources.size() > 0) {
@@ -102,13 +102,21 @@ public class TestDevice {
GetEventProperties getEventProperties = new GetEventProperties();
GetEventPropertiesResponse getEventPropertiesResp = events.getEventProperties(getEventProperties);
getEventPropertiesResp.getMessageContentFilterDialect().forEach(x -> System.out.println(x));
getEventPropertiesResp.getTopicExpressionDialect().forEach(x -> System.out.println(x));
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;
WsNotificationTest.printTree(e, e.getNodeName());
printTree(e, e.getNodeName(), tree);
// WsNotificationTest.printTree(e, e.getNodeName());
}
out += tree;
}
@@ -116,7 +124,7 @@ public class TestDevice {
PTZ ptz = device.getPtz();
if (ptz != null) {
out += "PTZ:" + sep;
out += "PTZ:" + sep;
String profileToken = profiles.get(0).getToken();
Capabilities ptz_caps = ptz.getServiceCapabilities();
@@ -126,7 +134,7 @@ public class TestDevice {
// out += "ptz.getConfiguration=" + ptz.getConfiguration(profileToken) + sep;
List<PTZPreset> presets = ptz.getPresets(profileToken);
if (presets != null && !presets.isEmpty()) {
out += "\tPresets:" + presets.size() +sep;
out += "\tPresets:" + presets.size() + sep;
for (PTZPreset p : presets)
out += "\t\t" + OnvifUtils.format(p) + sep;
}
@@ -136,6 +144,20 @@ public class TestDevice {
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 {
OnvifDevice device = new OnvifDevice(url, user, password);
return inspect(device);
@@ -146,8 +168,9 @@ public class TestDevice {
try {
OnvifCredentials creds = GetTestDevice.getOnvifCredentials(args);
String out = testCamera(creds);
LOG.info("\n"+out+"\n");
LOG.info("\n" + out + "\n");
} catch (Throwable th) {
LOG.warning("Error "+th);
th.printStackTrace();
}
}

View File

@@ -222,7 +222,7 @@ public class WsNotificationTest {
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(),
System.out.printf("Profile: [token=%s,name=%s,snapshotUri=%s]%n", p.getToken(), p.getName(),
cam.getMedia().getSnapshotUri(p.getToken()).getUri());
}
}