2

We're trying to get a basic Onvif discovery C# program to discover cameras on a local network. We can discover the cameras using an off the shelf tool, like Onvif Device Manager. Using Wireshark, we can see the UDP requests that Onvif DM sends out, and the responses from the cameras.

When we run our basic Onvif discovery console app, Wireshark shows us almost identical UDP requests being broadcast, and within 1 second we can see responses on the network from the 3 cameras. But our application does not see the responses: our DiscoveryClient FindProgressChanged event handler is never invoked, and the collection of Endpoints returned by the DiscoveryClient's Find method is empty.

Here's our Discovery console app:

using System;
using System.ServiceModel.Discovery;
using System.Xml;

namespace DiscoveryClient
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var endPoint = new UdpDiscoveryEndpoint(DiscoveryVersion.WSDiscoveryApril2005);

            var discoveryClient = new System.ServiceModel.Discovery.DiscoveryClient(endPoint);

            discoveryClient.FindProgressChanged += DiscoveryClient_FindProgressChanged;

            var findCriteria = new FindCriteria
            {
                Duration = TimeSpan.FromSeconds(10),
                MaxResults = int.MaxValue
            };

            findCriteria.ContractTypeNames.Add(new XmlQualifiedName("NetworkVideoTransmitter", @"http://www.onvif.org/ver10/network/wsdl"));

            Console.WriteLine("Initiating find operation.");
            var response = discoveryClient.Find(findCriteria);
            Console.WriteLine($"Operation returned - Found {response.Endpoints.Count} endpoints.");

            Console.ReadKey();
        }

        private static void DiscoveryClient_FindProgressChanged(object sender, FindProgressChangedEventArgs e)
        {
            Console.WriteLine($"Found this: {e}");
        }
    }
}

And here's an example UDP discovery request generated by the App (the only difference between this, and a request generated by Onvif DM is the Duration element within the Probe)

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing">
<s:Header>
    <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</a:Action>
    <a:MessageID>urn:uuid:3445e6a6-0751-4953-9071-394ab3f85fcb</a:MessageID>
    <a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>
    <a:To s:mustUnderstand="1">urn:schemas-xmlsoap-org:ws:2005:04:discovery</a:To>
</s:Header>
<s:Body>
    <Probe xmlns="http://schemas.xmlsoap.org/ws/2005/04/discovery">
        <d:Types xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery" xmlns:dp0="http://www.onvif.org/ver10/network/wsdl">dp0:NetworkVideoTransmitter</d:Types>
        <Duration xmlns="http://schemas.microsoft.com/ws/2008/06/discovery">PT10S</Duration>
    </Probe>
</s:Body>

Any ideas as to what's going on here - why does our application not see the responses to it's discovery request?

  • 1
    Did you tried closing your firewall? I had the same issue and this helped. – LoukMouk Sep 05 '18 at 13:10
  • 1
    Yes - thank you! Switching off the firewall did the trick - interesting that Onvif Device Manager works fine with the firewall enabled... I think that, and the fact we could see UDP responses from the cameras in Wireshark meant we never thought to try disabling it earlier. – Steve Blomeley Sep 05 '18 at 13:25
  • 1
    I think that the onvif device manager changes/adds firewall rules to its use when it gets installed... If you want to use your app without turning off the firewall, I suggest you to add your own rules to your firewall! (I have no idea how to do that, I need to do so also haha) – LoukMouk Sep 05 '18 at 13:33
  • 1
    Yep, our firewall has a couple of inbound rules (one for TCP and one for UDP) named "odm" that apply to onvif device manager - I tried copying them and adjusting them to apply to our console app's executable, but that didn't work. So I just created a blanket "allow an app through the firewall" rule for our console app - and that did the trick. – Steve Blomeley Sep 05 '18 at 16:13

0 Answers0