onvif-rs
onvif-rs copied to clipboard
advertised device mgmt uri not expected
I have a "Hikvision Compatible Outdoor 8MP PTZ PoE IP Camera Speed Dome, Pan Tilt 18xOptical Zoom 30x Digital Zoom with 165ft IR Night Vsion, Motion Detect,WDR,IP66,PTZ IP Camera(4818X-IZ)", and examples/camera.rs fails with this:
$ ./target/debug/examples/camera get-hostname --uri http://192.168.1.200:80/
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value:
"advertised device mgmt uri http://192.168.1.200:80/Device not expected http://192.168.1.200/onvif/device_service"', onvif/examples/camera.rs:404:45
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
if I comment out the code that performs that check, it seems to work:
$ ./target/debug/examples/camera get-hostname --uri http://192.168.1.200:80/
IPNC
$ ./target/debug/examples/camera get-system-date-and-time --uri http://192.168.1.200:80/
Ok(
GetSystemDateAndTimeResponse {
system_date_and_time: SystemDateTime {
date_time_type: Ntp,
daylight_savings: false,
time_zone: Some(
TimeZone {
tz: "CST-8",
},
),
# etc.
There is an option called '--service-path' that you can pass from the command line. Use like
$ ./target/debug/examples/camera get-hostname --uri http://192.168.1.200:80/ --service-path=Device
The problem is due to the fact that the URI in the reply contains :80 after the hostname and that doesn't match with the URI provided through the command line. Now even if you explicitly specify the port using --uri 192.168.1.200:80 when you invoke it, the Url parser will silently remove the :80 since that's the default for the http scheme..
I found the following change to onvif/examples/camera.rs to be sufficient to make it work (i.e. comparing Url instances instead of strings)
@@ -121,7 +121,9 @@ impl Clients {
);
match s.namespace.as_str() {
"http://www.onvif.org/ver10/device/wsdl" => {
- if s.x_addr != devicemgmt_uri.as_str() {
+ let advertised_uri =
+ Url::parse(s.x_addr.as_ref()).map_err(|e| e.to_string())?;
+ if advertised_uri != devicemgmt_uri {
return Err(format!(
"advertised device mgmt uri {} not expected {}",
&s.x_addr, &devicemgmt_uri
I can probably fork and PR this, but it doesn't seem like PRs are going through, aren't they?
EDIT: Just found out there's already #101 exactly for this, from last December..
This should be fixed in https://github.com/lumeohq/onvif-rs/pull/105 (the other PR failed CI checks, so hasn't been merged).
Right now, I don't have a camera that outputs a URL with the port number to test it, so feel free to comment here if it worked or not.
Confirming it now works. Thanks.