I am trying to discover ONVIF devices with some Java code. Specifically, I am trying to get their device service address (which is just their IP address I believe?), as the ONVIF Core Spec notes (in Section 4.3) that "A successful discovery provides the device service address. Once a client has the device service address it can receive detailed device information through the device service...". Ultimately getting this detailed information of the ONVIF devices on the network is my goal. In general I'm also looking for some guidance relating to using the ONVIF Spec.
I am still new to the web service world (and networking in general), so forgive me if I say anything dumb. However, I have put in a lot of effort into this myself: I have read a good deal of ONVIF Core Spec, ONVIF Application Programmer's Guide, and WS-Discovery Specification. If I may I'll just summarize what I know so you can tell me if I'm on the right track:
- "Web Services" is the name of a standard technology using platform and language independent web service standards such as XML, SOAP, and WSDL over an IP Network. The basic idea is that we want to be able to call what are effectively methods/functions (a service) from any programming language.
- A web service is typically hosted on a server; but in the ONVIF use case, the web service provider is the ONVIF device (eg, an IP Camera). Thus to interact with the device from any language we use web service operations / calls, as web service calls can be implemented in any language.
- XML is the data description syntax (used because it's language agnostic; any language can parse it). SOAP is the communication protocol used to get SOAP-infused XML documents back and forth (basically, make our method calls). WSDL is used for describing the services (it's an XML based description of the web services' interface). I have downloaded the WSDL for device management here, and generated via WSDL compiler
wsimport
(provided by JDK) the Java classes from the WSDL to use in my code. But I understand that calling these methods will come after device discovery, correct? - ONVIF Devices are discovered according WS-Discovery specification. You send a
Probe
message, and devices that match the Probe's constraints send back aProbeMatch
message, as described on page 13 and 14 in ONVIF Application Programmers Guide
Here is where I begin to get confused. How exactly do I send this message in Java? The ONVIF Application Programmer's Guide provides some pseudocode on page 15, but I can't figure out how to implement it. Section 4.3.1 in that guide specifically is what I'm stuck on. I understand that the "scopes" and "types" are just constraints you can embed in a probe, but they are not required (as per page 5 of WS discovery spec). Since I want to discover all devices I figure I need no constraints to start, right?
So that guide also provides a sample SOAP Message on page 110 used for discovery. Removing the type declaration out of it (because I don't want that constraint), I understand that my SOAP Message to send would be (I believe?) this:
<?xml version="1.0" encoding="UTF-8"?>
<e:Envelope xmlns:e="http://www.w3.org/2003/05/soap-envelope"
xmlns:w="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery"
xmlns:dn="http://www.onvif.org/ver10/network/wsdl">
<e:Header>
<w:MessageID>uuid:84ede3de-7dec-11d0-c360-f01234567890</w:MessageID>
<w:To e:mustUnderstand="true">urn:schemas-xmlsoap-org:ws:2005:04:discovery</w:To>
<w:Action
a:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2005/04/discovery/Pr
obe</w:Action>
</e:Header>
<e:Body>
<d:Probe>
</d:Probe>
</e:Body>
</e:Envelope>
And I also understand the WS-Discovery technology used address 239.255.255.259 with UDP port 3702... but that's the end of what I get. How do I send that SOAP Message to that address and port in Java? How do I read the response (I think that I'll get back a ProbeMatch message, in the form of an SOAP-infused XML document, so I'll need to parse that XML to get the XAddrs
, but not sure). Do I need to send a UDP broadcast of that SOAP message to that address somehow?
TL;DR: I believe to do ONVIF Device Discovery I need to send that SOAP message above to address 239.255.255.259 on UDP Port 3702. I have no clue how to do that in Java and was just looking for some guidance; I'm not even sure I'm on the right track to do device discovery.