use super::OnvifClient;
use crate::error::OnvifError;
use crate::soap::{find_response, parse_soap_body};
use crate::types::{EventProperties, NotificationMessage, PullPointSubscription};
impl OnvifClient {
pub async fn get_event_properties(
&self,
events_url: &str,
) -> Result<EventProperties, OnvifError> {
const ACTION: &str =
"http://www.onvif.org/ver10/events/wsdl/EventPortType/GetEventPropertiesRequest";
const BODY: &str = "<tev:GetEventProperties/>";
let xml = self.call(events_url, ACTION, BODY).await?;
let body_node = parse_soap_body(&xml)?;
let resp = find_response(&body_node, "GetEventPropertiesResponse")?;
EventProperties::from_xml(resp)
}
pub async fn create_pull_point_subscription(
&self,
events_url: &str,
filter: Option<&str>,
initial_termination_time: Option<&str>,
) -> Result<PullPointSubscription, OnvifError> {
const ACTION: &str = "http://www.onvif.org/ver10/events/wsdl/EventPortType/CreatePullPointSubscriptionRequest";
let filter_el = filter
.map(|f| {
format!(
"<tev:Filter>\
<wsnt:TopicExpression \
Dialect=\"http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet\"\
>{f}</wsnt:TopicExpression>\
</tev:Filter>"
)
})
.unwrap_or_default();
let termination_el = initial_termination_time
.map(|t| format!("<tev:InitialTerminationTime>{t}</tev:InitialTerminationTime>"))
.unwrap_or_default();
let body = format!(
"<tev:CreatePullPointSubscription>\
{filter_el}{termination_el}\
</tev:CreatePullPointSubscription>"
);
let xml = self.call(events_url, ACTION, &body).await?;
let body_node = parse_soap_body(&xml)?;
let resp = find_response(&body_node, "CreatePullPointSubscriptionResponse")?;
PullPointSubscription::from_xml(resp)
}
pub async fn pull_messages(
&self,
subscription_url: &str,
timeout: &str,
max_messages: u32,
) -> Result<Vec<NotificationMessage>, OnvifError> {
const ACTION: &str =
"http://www.onvif.org/ver10/events/wsdl/PullPointSubscription/PullMessagesRequest";
let body = format!(
"<tev:PullMessages>\
<tev:Timeout>{timeout}</tev:Timeout>\
<tev:MessageLimit>{max_messages}</tev:MessageLimit>\
</tev:PullMessages>"
);
let xml = self.call(subscription_url, ACTION, &body).await?;
let body_node = parse_soap_body(&xml)?;
let resp = find_response(&body_node, "PullMessagesResponse")?;
Ok(NotificationMessage::vec_from_xml(resp))
}
pub async fn renew_subscription(
&self,
subscription_url: &str,
termination_time: &str,
) -> Result<String, OnvifError> {
const ACTION: &str =
"http://www.onvif.org/ver10/events/wsdl/SubscriptionManager/RenewRequest";
let body = format!(
"<wsnt:Renew>\
<wsnt:TerminationTime>{termination_time}</wsnt:TerminationTime>\
</wsnt:Renew>"
);
let xml = self.call(subscription_url, ACTION, &body).await?;
let body_node = parse_soap_body(&xml)?;
let resp = find_response(&body_node, "RenewResponse")?;
Ok(resp
.child("TerminationTime")
.map(|n| n.text().to_string())
.unwrap_or_default())
}
pub async fn unsubscribe(&self, subscription_url: &str) -> Result<(), OnvifError> {
const ACTION: &str =
"http://www.onvif.org/ver10/events/wsdl/SubscriptionManager/UnsubscribeRequest";
const BODY: &str = "<wsnt:Unsubscribe/>";
let xml = self.call(subscription_url, ACTION, BODY).await?;
let body_node = parse_soap_body(&xml)?;
find_response(&body_node, "UnsubscribeResponse")?;
Ok(())
}
}