ONVIF - beginning of Device discovery
Asked Answered
H

3

6

I am planning to do a java onvif application. I have created a new project and generated sources from devicemgmt.wsdl.Also generated the classes from remote discovery.wsdl. How can I discover a device in a network using theses generated classes? Thanks for any help.

Hairdresser answered 12/12, 2013 at 4:42 Comment(1)
possible duplicate of WS-Discovery Implementations for JavaGuibert
G
4

devicemgmt.wsdl is not related to discovery process, the ONVIF discovery process is based on http://specs.xmlsoap.org/ws/2005/04/discovery it use SOAP over UDP.

If you are using apache-cxf, this can be achieve using

org.apache.cxf.ws.discovery.WSDiscoveryClient

A simple sample code could be :

import java.util.List;
import javax.xml.ws.EndpointReference;
import org.apache.cxf.ws.discovery.WSDiscoveryClient;

public class Main 
{
    public static void main(String[] args) 
    {
        WSDiscoveryClient client = new WSDiscoveryClient();
        client.setVersion10(); // use WS-discovery 1.0
        client.setDefaultProbeTimeout(1000); // timeout 1s

        System.out.println("Probe:" + client.getAddress());
        List<EndpointReference> references = client.probe();

        System.out.println("Nb answsers:" + references.size());
        for (EndpointReference ref : references)
        {
            System.out.println(ref.toString());
        }
    }
}
Guibert answered 3/1, 2014 at 20:20 Comment(3)
What can be the reason (i'm using cxf) is device if found by WSDiscoveryClient(), but not found by any production-quality onvif client like "SmartICRSS" or "Onvifier" android appLouvain
@Louvain it could be soap version ? you should ask a question giving some network capture detailsGuibert
you're probably right. i've intercepted discovery requests/responses - read my separate SO question: #27191745Louvain
M
1

I had the same problem, CXF is simply to big, please check my approach: JavaWsDiscovery at https://github.com/thhart/javaWsDiscovery.

It uses a simple network probe as suggested by Onvif standards to be able to identify any devices on your local network, following line will return you all available devices:

final Collection urls = DeviceDiscovery.discoverWsDevicesAsUrls("^http$", ".onvif.");

Monostich answered 19/6, 2015 at 10:34 Comment(0)
P
1

Simple and complete example pure Java

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Ronald
 */
public class TestDiscoveryPureJava {
    
    public static void main(String cor[]) throws SocketException{
        discoverWsDevices();
    }

    public static  void discoverWsDevices() throws SocketException {
        final int WS_DISCOVERY_PORT = 3702;
        final String WS_DISCOVERY_ADDRESS_IPv4 = "239.255.255.250";

        Thread thread = new Thread() {
            @Override
            public void run() {
                
                final String probe = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">\n" +
"    <s:Header>\n" +
"        <a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</a:Action>\n" +
"        <a:MessageID>uuid:f0ded492-301a-4891-882b-cb2d7cac2e45</a:MessageID>\n" +
"        <a:ReplyTo>\n" +
"            <a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>\n" +
"        </a:ReplyTo>\n" +
"        <a:To s:mustUnderstand=\"1\">urn:schemas-xmlsoap-org:ws:2005:04:discovery</a:To>\n" +
"    </s:Header>\n" +
"    <s:Body>\n" +
"        <Probe xmlns=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\">\n" +
"            <d:Types xmlns:d=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\" xmlns:dp0=\"http://www.onvif.org/ver10/network/wsdl\">dp0:Device</d:Types>\n" +
"        </Probe>\n" +
"    </s:Body>\n" +
"</s:Envelope>";

                DatagramSocket datagramSocket = null;

                try {
                    datagramSocket = new DatagramSocket();
                    datagramSocket.setBroadcast(true);
                    datagramSocket.setSoTimeout(9000);
                } catch (SocketException e) {
                    System.out.println( "In discoverWsDevices datagram socket exception" + datagramSocket);
                    e.printStackTrace();
                }

                byte[] soapMessageByteArray = probe.getBytes();
                DatagramPacket datagramPacketSend = null;
                try {
                    datagramPacketSend = new DatagramPacket(
                            soapMessageByteArray,
                            soapMessageByteArray.length,
                            InetAddress.getByName(WS_DISCOVERY_ADDRESS_IPv4),
                            WS_DISCOVERY_PORT);
                } catch (UnknownHostException e) {
                    System.out.println("Unknown host in send packet");
                    e.printStackTrace();
                }

                try {
                    System.out.println("Send package");
                    datagramSocket.send(datagramPacketSend);
                    System.out.println("package sent");
                } catch (IOException e) {
                    System.out.println("In discoverWsDevices datagram socket IOException send " + datagramSocket);
                    e.printStackTrace();
                }
                System.out.println("Sending data");
                System.out.println(datagramPacketSend.getAddress().getHostName()+":"+WS_DISCOVERY_PORT);

                List<ByteArrayInputStream> probeMatches = new ArrayList<>();
                while (true) {

                    byte[] responseMessageByteArray = new byte[9000];

                    DatagramPacket datagramPacketRecieve = new DatagramPacket(responseMessageByteArray,responseMessageByteArray.length);
                    try {
                        System.out.println("Waiting response...");
                        datagramSocket.receive(datagramPacketRecieve);
                    } catch (SocketTimeoutException e) {
                        datagramSocket.close();
                        System.out.println("In discoverWsDevices datagram socket timeout exception");
                        break;
                    } catch (IOException e) {
                        System.out.println("In discoverWsDevices datagram socket ioexception");
                        e.printStackTrace();
                        break;
                    }
                    probeMatches.add(new ByteArrayInputStream(datagramPacketRecieve.getData(), 0, datagramPacketRecieve.getLength()));
                }

                for (ByteArrayInputStream input : probeMatches) {
                    byte[] bytes = new byte[input.available()];
                    input.read(bytes, 0, input.available());
                    String stream = new String(bytes);
                    System.out.println("stream" + stream);
                }
            }
        };
        thread.start();
    }
}
Persiflage answered 29/11, 2021 at 13:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.