From 5e8159907cfc3d5c2d14aed9168f7a476022698e Mon Sep 17 00:00:00 2001 From: Samuel Yvon Date: Tue, 6 Feb 2024 14:50:04 -0500 Subject: [PATCH] Add support for the endpoint reference --- onvif/src/discovery/mod.rs | 27 +++++++++++++++++++++------ wsdl_rs/ws_discovery/src/lib.rs | 29 +++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/onvif/src/discovery/mod.rs b/onvif/src/discovery/mod.rs index 43a6c2e..acbc43e 100644 --- a/onvif/src/discovery/mod.rs +++ b/onvif/src/discovery/mod.rs @@ -33,6 +33,8 @@ pub enum Error { #[derive(Clone, Eq, Hash, PartialEq)] pub struct Device { + /// The WS-Discovery UUID / address reference + pub address: String, pub name: Option, pub urls: Vec, } @@ -42,6 +44,7 @@ impl Debug for Device { f.debug_struct("Device") .field("name", &self.name) .field("url", &DisplayList(&self.urls)) + .field("address", &self.address) .finish() } } @@ -226,8 +229,13 @@ fn device_from_envelope(envelope: probe_matches::Envelope) -> Option { let name = onvif_probe_match.name(); let urls = onvif_probe_match.x_addrs(); + let address = onvif_probe_match.endpoint_reference_address(); - Some(Device { name, urls }) + Some(Device { + name, + urls, + address, + }) } fn build_probe() -> probe::Envelope { @@ -245,7 +253,9 @@ fn build_probe() -> probe::Envelope { #[test] fn test_xaddrs_extraction() { - fn make_xml(relates_to: &str, xaddrs: &str) -> String { + const DEVICE_ADDRESS: &str = "an address"; + + let make_xml = |relates_to: &str, xaddrs: &str| -> String { format!( r#" http://something.else + + {device_address} + onvif://www.onvif.org/name/MyCamera2000 {xaddrs} @@ -270,9 +283,10 @@ fn test_xaddrs_extraction() { "#, relates_to = relates_to, - xaddrs = xaddrs + xaddrs = xaddrs, + device_address = DEVICE_ADDRESS ) - } + }; let our_uuid = "uuid:84ede3de-7dec-11d0-c360-F01234567890"; let bad_uuid = "uuid:84ede3de-7dec-11d0-c360-F00000000000"; @@ -298,9 +312,10 @@ fn test_xaddrs_extraction() { urls: vec![ Url::parse("http://addr_20").unwrap(), Url::parse("http://addr_21").unwrap(), - Url::parse("http://addr_22").unwrap() + Url::parse("http://addr_22").unwrap(), ], - name: Some("MyCamera2000".to_string()) + name: Some("MyCamera2000".to_string()), + address: DEVICE_ADDRESS.to_string(), }] ); } diff --git a/wsdl_rs/ws_discovery/src/lib.rs b/wsdl_rs/ws_discovery/src/lib.rs index 67ac2e4..08c700e 100644 --- a/wsdl_rs/ws_discovery/src/lib.rs +++ b/wsdl_rs/ws_discovery/src/lib.rs @@ -1,5 +1,4 @@ pub mod probe { - use yaserde_derive::YaSerialize; #[derive(Default, Eq, PartialEq, Debug, YaSerialize)] @@ -56,8 +55,22 @@ pub mod probe { } } -pub mod probe_matches { +pub mod endpoint_reference { + use yaserde_derive::YaDeserialize; + #[derive(Default, Eq, PartialEq, Debug, YaDeserialize)] + #[yaserde( + prefix = "wsa", + namespace = "wsa: http://schemas.xmlsoap.org/ws/2004/08/addressing" + )] + pub struct EndpointReference { + #[yaserde(prefix = "wsa", rename = "Address")] + pub address: String, + } +} + +pub mod probe_matches { + use crate::endpoint_reference::EndpointReference; use percent_encoding::percent_decode_str; use url::Url; use yaserde_derive::YaDeserialize; @@ -65,9 +78,13 @@ pub mod probe_matches { #[derive(Default, Eq, PartialEq, Debug, YaDeserialize)] #[yaserde( prefix = "d", - namespace = "d: http://schemas.xmlsoap.org/ws/2005/04/discovery" + namespace = "d: http://schemas.xmlsoap.org/ws/2005/04/discovery", + namespace = "wsa: http://schemas.xmlsoap.org/ws/2004/08/addressing" )] pub struct ProbeMatch { + #[yaserde(prefix = "wsa", rename = "EndpointReference")] + pub endpoint_reference: EndpointReference, + #[yaserde(prefix = "d", rename = "Types")] pub types: String, @@ -141,6 +158,10 @@ pub mod probe_matches { self.find_in_scopes("onvif://www.onvif.org/hardware/") } + pub fn endpoint_reference_address(&self) -> String { + self.endpoint_reference.address.to_string() + } + pub fn find_in_scopes(&self, prefix: &str) -> Option { self.scopes().iter().find_map(|url| { url.as_str() @@ -197,7 +218,7 @@ pub mod probe_matches { de.x_addrs(), vec![ Url::parse("http://192.168.0.100:80/onvif/device_service").unwrap(), - Url::parse("http://10.0.0.200:80/onvif/device_service").unwrap() + Url::parse("http://10.0.0.200:80/onvif/device_service").unwrap(), ] ); }