-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add GetServiceCapabilities for media ver10 (#70)
- Loading branch information
1 parent
0a68201
commit 050db0f
Showing
4 changed files
with
223 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
defmodule Onvif.Media.Ver10.GetServiceCapabilities do | ||
import SweetXml | ||
import XmlBuilder | ||
|
||
require Logger | ||
|
||
alias Onvif.Device | ||
|
||
def soap_action, do: "http://www.onvif.org/ver10/media/wsdl/GetServiceCapabilities" | ||
|
||
@spec request(Device.t()) :: {:ok, any} | {:error, map()} | ||
def request(device), | ||
do: Onvif.Media.Ver10.Media.request(device, [], __MODULE__) | ||
|
||
def request_body do | ||
element(:"s:Body", [element(:"trt:GetServiceCapabilities")]) | ||
end | ||
|
||
def response(xml_response_body) do | ||
parsed = | ||
xml_response_body | ||
|> parse(namespace_conformant: true, quiet: true) | ||
|> xpath( | ||
~x"//s:Envelope/s:Body/trt:GetServiceCapabilitiesResponse/trt:Capabilities"e | ||
|> add_namespace("s", "http://www.w3.org/2003/05/soap-envelope") | ||
|> add_namespace("trt", "http://www.onvif.org/ver10/media/wsdl") | ||
|> add_namespace("tt", "http://www.onvif.org/ver10/schema") | ||
) | ||
|> Onvif.Media.Ver10.ServiceCapabilities.parse() | ||
|> Onvif.Media.Ver10.ServiceCapabilities.to_struct() | ||
|
||
response = | ||
case parsed do | ||
{:ok, sevice} -> | ||
sevice | ||
|
||
{:error, changeset} -> | ||
Logger.error("Discarding invalid service capability: #{inspect(changeset)}") | ||
%Onvif.Media.Ver10.ServiceCapabilities{} | ||
end | ||
|
||
{:ok, response} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
defmodule Onvif.Media.Ver10.ServiceCapabilities do | ||
@moduledoc false | ||
|
||
use Ecto.Schema | ||
import Ecto.Changeset | ||
import SweetXml | ||
|
||
@primary_key false | ||
@derive Jason.Encoder | ||
@required [] | ||
@optional [ | ||
:snapshot_uri, | ||
:rotation, | ||
:video_source_mode, | ||
:osd, | ||
:temporary_osd_text, | ||
:exi_compression | ||
] | ||
embedded_schema do | ||
field(:snapshot_uri, :boolean, default: false) | ||
field(:rotation, :boolean, default: false) | ||
field(:video_source_mode, :boolean, default: false) | ||
field(:osd, :boolean, default: false) | ||
field(:temporary_osd_text, :boolean, default: false) | ||
field(:exi_compression, :boolean, default: false) | ||
|
||
embeds_one :profile_capabilities, ProfileCapabilities, primary_key: false, on_replace: :update do | ||
@derive Jason.Encoder | ||
field(:maximum_number_of_profiles, :integer) | ||
end | ||
|
||
embeds_one :streaming_capabilities, StreamingCapabilities, | ||
primary_key: false, | ||
on_replace: :update do | ||
@derive Jason.Encoder | ||
field(:rtsp_multicast, :boolean, default: false) | ||
field(:rtp_tcp, :boolean, default: false) | ||
field(:rtp_rtsp_tcp, :boolean, default: false) | ||
field(:non_aggregated_control, :boolean, default: false) | ||
field(:no_rtsp_streaming, :boolean, default: false) | ||
end | ||
end | ||
|
||
def to_struct(parsed) do | ||
%__MODULE__{} | ||
|> changeset(parsed) | ||
|> apply_action(:validate) | ||
end | ||
|
||
@spec to_json(%Onvif.Media.Ver10.Profile.VideoEncoderConfiguration{}) :: | ||
{:error, | ||
%{ | ||
:__exception__ => any, | ||
:__struct__ => Jason.EncodeError | Protocol.UndefinedError, | ||
optional(atom) => any | ||
}} | ||
| {:ok, binary} | ||
def to_json(%__MODULE__{} = schema) do | ||
Jason.encode(schema) | ||
end | ||
|
||
def changeset(module, attrs) do | ||
module | ||
|> cast(attrs, @required ++ @optional) | ||
|> validate_required(@required) | ||
|> cast_embed(:profile_capabilities, with: &profile_capabilities_changeset/2) | ||
|> cast_embed(:streaming_capabilities, | ||
with: &streaming_capabilities_changeset/2 | ||
) | ||
end | ||
|
||
def parse(nil), do: nil | ||
def parse([]), do: nil | ||
|
||
def parse(doc) do | ||
xmap( | ||
doc, | ||
snapshot_uri: ~x"./@SnapshotUri"so, | ||
rotation: ~x"./@Rotation"so, | ||
video_source_mode: ~x"./@VideoSourceMode"so, | ||
osd: ~x"./@OSD"so, | ||
temporary_osd_text: ~x"./@TemporaryOSDText"so, | ||
exi_compression: ~x"./@EXICompression"so, | ||
profile_capabilities: | ||
~x"./trt:ProfileCapabilities"eo |> transform_by(&parse_profile_capabilities/1), | ||
streaming_capabilities: | ||
~x"./trt:StreamingCapabilities"eo |> transform_by(&parse_streaming_capabilities/1) | ||
) | ||
end | ||
|
||
defp profile_capabilities_changeset(module, attrs) do | ||
cast(module, attrs, [:maximum_number_of_profiles]) | ||
end | ||
|
||
defp streaming_capabilities_changeset(module, attrs) do | ||
cast(module, attrs, [ | ||
:rtsp_multicast, | ||
:rtp_tcp, | ||
:rtp_rtsp_tcp, | ||
:non_aggregated_control, | ||
:no_rtsp_streaming | ||
]) | ||
end | ||
|
||
defp parse_profile_capabilities([]), do: nil | ||
defp parse_profile_capabilities(nil), do: nil | ||
|
||
defp parse_profile_capabilities(doc) do | ||
xmap( | ||
doc, | ||
maximum_number_of_profiles: ~x"./@MaximumNumberOfProfiles"i | ||
) | ||
end | ||
|
||
defp parse_streaming_capabilities([]), do: nil | ||
defp parse_streaming_capabilities(nil), do: nil | ||
|
||
defp parse_streaming_capabilities(doc) do | ||
xmap( | ||
doc, | ||
rtsp_multicast: ~x"./@RTPMulticast "so, | ||
rtp_tcp: ~x"./@RTP_TCP"so, | ||
rtp_rtsp_tcp: ~x"./@RTP_RTSP_TCP"so, | ||
non_aggregated_control: ~x"./@NonAggregateControl"so, | ||
no_rtsp_streaming: ~x"./@NoRTSPStreaming"so | ||
) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
defmodule Onvif.Media.Ver10.GetServiceCapabilitiesTest do | ||
use ExUnit.Case, async: true | ||
|
||
@moduletag capture_log: true | ||
|
||
describe "GetServiceCapabilities/1" do | ||
test "should parse with correct values and defaults for non existing attributes" do | ||
xml_response = File.read!("test/media/ver10/fixtures/get_service_capabilities_response.xml") | ||
|
||
device = Onvif.Factory.device() | ||
|
||
Mimic.expect(Tesla, :request, fn _client, _opts -> | ||
{:ok, %{status: 200, body: xml_response}} | ||
end) | ||
|
||
{:ok, service_capabilities} = Onvif.Media.Ver10.GetServiceCapabilities.request(device) | ||
|
||
assert service_capabilities == %Onvif.Media.Ver10.ServiceCapabilities{ | ||
exi_compression: false, | ||
osd: true, | ||
profile_capabilities: %Onvif.Media.Ver10.ServiceCapabilities.ProfileCapabilities{ | ||
maximum_number_of_profiles: 24 | ||
}, | ||
rotation: false, | ||
snapshot_uri: true, | ||
streaming_capabilities: | ||
%Onvif.Media.Ver10.ServiceCapabilities.StreamingCapabilities{ | ||
no_rtsp_streaming: false, | ||
non_aggregated_control: false, | ||
rtp_rtsp_tcp: true, | ||
rtp_tcp: false, | ||
rtsp_multicast: false | ||
}, | ||
temporary_osd_text: false, | ||
video_source_mode: false | ||
} | ||
end | ||
end | ||
end |
12 changes: 12 additions & 0 deletions
12
test/media/ver10/fixtures/get_service_capabilities_response.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?xml version="1.0"?> | ||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://tempuri.org/tns.xsd" xmlns:tns1="http://www.onvif.org/ver10/topics" xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsa5="http://www.w3.org/2005/08/addressing" xmlns:xmime5="http://tempuri.org/xmime5.xsd" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:tplt="http://www.onvif.org/ver10/plus/schema" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:wsrfr="http://docs.oasis-open.org/wsrf/r-2" xmlns:wsrfbf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:tanae="http://www.onvif.org/ver20/analytics/wsdl/AnalyticsEngineBinding" xmlns:tanre="http://www.onvif.org/ver20/analytics/wsdl/RuleEngineBinding" xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:tes-cppb="http://www.onvif.org/ver10/events/wsdl/CreatePullPointBinding" xmlns:tes-e="http://www.onvif.org/ver10/events/wsdl/EventBinding" xmlns:tes-nc="http://www.onvif.org/ver10/events/wsdl/NotificationConsumerBinding" xmlns:tes-np="http://www.onvif.org/ver10/events/wsdl/NotificationProducerBinding" xmlns:tes-ppb="http://www.onvif.org/ver10/events/wsdl/PullPointBinding" xmlns:tes-pps="http://www.onvif.org/ver10/events/wsdl/PullPointSubscriptionBinding" xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:tes-psmb="http://www.onvif.org/ver10/events/wsdl/PausableSubscriptionManagerBinding" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:tes-sm="http://www.onvif.org/ver10/events/wsdl/SubscriptionManagerBinding" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tmd="http://www.onvif.org/ver10/deviceIO/wsdl" xmlns:tpl="http://www.onvif.org/ver10/plus/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:tr2="http://www.onvif.org/ver20/media/wsdl" xmlns:trc="http://www.onvif.org/ver10/recording/wsdl" xmlns:trp="http://www.onvif.org/ver10/replay/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:trv="http://www.onvif.org/ver10/receiver/wsdl" xmlns:tse="http://www.onvif.org/ver10/search/wsdl" xmlns:ter="http://www.onvif.org/ver10/error"> | ||
<SOAP-ENV:Header/> | ||
<SOAP-ENV:Body> | ||
<trt:GetServiceCapabilitiesResponse> | ||
<trt:Capabilities OSD="true" VideoSourceMode="false" Rotation="false" SnapshotUri="true"> | ||
<trt:ProfileCapabilities MaximumNumberOfProfiles="24"/> | ||
<trt:StreamingCapabilities NoRTSPStreaming="false" NonAggregateControl="false" RTP_RTSP_TCP="true" RTP_TCP="false" RTPMulticast="false"/> | ||
</trt:Capabilities> | ||
</trt:GetServiceCapabilitiesResponse> | ||
</SOAP-ENV:Body> | ||
</SOAP-ENV:Envelope> |