0
votes

I'm am trying to construct a somewhat complete ONVIF device manager using only UDP. I understand certain features require TCP, but for now I can accept that these features will be unavailable to me. I am struggling to get the system date and time without setting up an HTTPClient. According to Onvif this SOAP does not require authentication and is instead information needed for the complete authentication process.

I am able to send out a probe on UDP and get responses, and even get PTZ settings with basic authentication. When I use the following SOAP provided by the Onvif Applications Programmers Guide, however, I see that the message is sent but no response is received (using wire shark).

According to the Programmers Guide the following....

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
 xmlns:tds="http://www.onvif.org/ver10/device/wsdl">
 <SOAP-ENV:Body>
 <tds:GetSystemDateAndTime/>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope> 

Should generate the following response....

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
 xmlns:tt="http://www.onvif.org/ver10/schema"
 xmlns:tds="http://www.onvif.org/ver10/device/wsdl">
 <SOAP-ENV:Body>
 <tds:GetSystemDateAndTimeResponse>
 <tds:SystemDateAndTime>
 <tt:DateTimeType>NTP</tt:DateTimeType>
 <tt:DaylightSavings>true</tt:DaylightSavings>
 <tt:TimeZone>
 <tt:TZ>CET-1CEST,M3.5.0,M10.5.0</tt:TZ>
 </tt:TimeZone>
 <tt:UTCDateTime>
 <tt:Time>
 <tt:Hour>15</tt:Hour>
 <tt:Minute>52</tt:Minute>
 <tt:Second>25</tt:Second>
 </tt:Time>
 <tt:Date>
 <tt:Year>2010</tt:Year>
 <tt:Month>10</tt:Month>
 <tt:Day>29</tt:Day>
 </tt:Date>
 </tt:UTCDateTime>
 <tt:LocalDateTime>
 <tt:Time>
 <tt:Hour>17</tt:Hour>
 <tt:Minute>52</tt:Minute>
 <tt:Second>25</tt:Second>
 </tt:Time>
 <tt:Date>
 <tt:Year>2010</tt:Year>
 <tt:Month>10</tt:Month>
 <tt:Day>29</tt:Day>
 </tt:Date>
 </tt:LocalDateTime>
 </tds:SystemDateAndTime>
 </tds:GetSystemDateAndTimeResponse>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope> 

Here is a stripped version of the code I'm using. This approach has worked in all attempts other than the soap listed above.

public static async Task<List<string>> GetSoapRes_Time_and_DateAsync()
{
    //Create a variable called result to store returned string. Code omitted for clarity.

    using (var client = new UdpClient())
    {
        var ipEndpoint = new IPEndPoint(IPAddress.Parse("192.168.1.64"), 3702);
        client.EnableBroadcast = true;
        try
        {
            var soapMessage = GetBytes(CreateSoapRequest());
            await client.SendAsync(soapMessage, soapMessage.Length, ipEndpoint);
            //ToDo: check if we have bits back and if we do process and store in result.
        }
        catch (Exception exception)
        {
            //Do something 
        }
    }
//Return results 
        return result;
    }

private static string CreateSoapRequest()
{
    Guid messageId = Guid.NewGuid();
    const string soap = ************Place Soap string here***********
    var result = string.Format(soap, messageId);
    return result;
}

private static byte[] GetBytes(string text)
{
    return Encoding.ASCII.GetBytes(text);
}

Would anyone be familiar enough with Onvif to know what is going wrong? I'm assuming that either A) I'm missing something obvious B) Onvif only accepts this soap with a TCP header.

1

1 Answers

1
votes

You cannot do that.

From the core specs in section 4.1:

This framework is built upon Web Services standards. All configuration services defined in the standard are expressed as Web Services operations and defined in WSDL with HTTP as the underlying transport mechanism.

By using only UDP, you can only have device discovery and getting streaming if the camera is configured for starting multicast streaming automatically at boot. For any other functionality, at least one TCP connection is required.