Merge pull request #48 from 0x524a/46-feature-add-more-event-operations
46 feature add more event operations
This commit is contained in:
@@ -302,3 +302,4 @@ The library provides **complete coverage** of all essential ONVIF Media and Devi
|
||||
*Camera: Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)*
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -101,3 +101,4 @@ New types added to `types.go`:
|
||||
*Total Operations: 79/79 (100%)*
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -168,3 +168,4 @@ The library provides **complete coverage** of all essential ONVIF operations req
|
||||
*Camera: Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)*
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -229,3 +229,4 @@ The missing operations are primarily **optional discovery and management operati
|
||||
*Last Updated: December 1, 2025*
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -209,3 +209,4 @@ Implement Video Analytics and Audio Decoder operations if needed for specific us
|
||||
*Last Updated: December 2, 2025*
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -506,15 +506,10 @@ func extractParam(authHeader, param string) string {
|
||||
}
|
||||
|
||||
func md5Hash(s string) string {
|
||||
return fmt.Sprintf("%x", md5sum(s))
|
||||
}
|
||||
|
||||
func md5sum(s string) interface{} {
|
||||
// Use crypto/md5 - import it if not already present
|
||||
h := md5.New() //nolint:gosec // MD5 required for ONVIF digest auth
|
||||
h.Write([]byte(s))
|
||||
|
||||
return h.Sum(nil)
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
// generateNonce generates a cryptographically secure random nonce for digest authentication.
|
||||
|
||||
+171
-253
@@ -8,14 +8,73 @@ import (
|
||||
"github.com/0x524a/onvif-go/internal/soap"
|
||||
)
|
||||
|
||||
// Common XML request/response types for device security operations.
|
||||
// These are defined at package level to avoid repeated inline struct definitions.
|
||||
|
||||
// ipAddressFilterRequest is the common structure for IP address filter SOAP requests.
|
||||
type ipAddressFilterRequest struct {
|
||||
Type string `xml:"tds:Type"`
|
||||
IPv4Address []prefixedIPv4AddressXML `xml:"tds:IPv4Address,omitempty"`
|
||||
IPv6Address []prefixedIPv6AddressXML `xml:"tds:IPv6Address,omitempty"`
|
||||
}
|
||||
|
||||
// prefixedIPv4AddressXML is the XML representation of a prefixed IPv4 address.
|
||||
type prefixedIPv4AddressXML struct {
|
||||
Address string `xml:"tds:Address"`
|
||||
PrefixLength int `xml:"tds:PrefixLength"`
|
||||
}
|
||||
|
||||
// prefixedIPv6AddressXML is the XML representation of a prefixed IPv6 address.
|
||||
type prefixedIPv6AddressXML struct {
|
||||
Address string `xml:"tds:Address"`
|
||||
PrefixLength int `xml:"tds:PrefixLength"`
|
||||
}
|
||||
|
||||
// buildIPAddressFilterRequest converts an IPAddressFilter to the XML request format.
|
||||
// Pre-allocates slices for efficiency when the source length is known.
|
||||
func buildIPAddressFilterRequest(filter *IPAddressFilter) ipAddressFilterRequest {
|
||||
req := ipAddressFilterRequest{
|
||||
Type: string(filter.Type),
|
||||
}
|
||||
|
||||
// Pre-allocate slices with known capacity
|
||||
if len(filter.IPv4Address) > 0 {
|
||||
req.IPv4Address = make([]prefixedIPv4AddressXML, 0, len(filter.IPv4Address))
|
||||
for _, addr := range filter.IPv4Address {
|
||||
req.IPv4Address = append(req.IPv4Address, prefixedIPv4AddressXML{
|
||||
Address: addr.Address,
|
||||
PrefixLength: addr.PrefixLength,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if len(filter.IPv6Address) > 0 {
|
||||
req.IPv6Address = make([]prefixedIPv6AddressXML, 0, len(filter.IPv6Address))
|
||||
for _, addr := range filter.IPv6Address {
|
||||
req.IPv6Address = append(req.IPv6Address, prefixedIPv6AddressXML{
|
||||
Address: addr.Address,
|
||||
PrefixLength: addr.PrefixLength,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
// newSOAPClient creates a SOAP client with the current client credentials.
|
||||
func (c *Client) newSOAPClient() *soap.Client {
|
||||
username, password := c.GetCredentials()
|
||||
return soap.NewClient(c.httpClient, username, password)
|
||||
}
|
||||
|
||||
// GetRemoteUser returns the configured remote user.
|
||||
func (c *Client) GetRemoteUser(ctx context.Context) (*RemoteUser, error) {
|
||||
type GetRemoteUser struct {
|
||||
type getRemoteUserRequest struct {
|
||||
XMLName xml.Name `xml:"tds:GetRemoteUser"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
}
|
||||
|
||||
type GetRemoteUserResponse struct {
|
||||
type getRemoteUserResponse struct {
|
||||
XMLName xml.Name `xml:"GetRemoteUserResponse"`
|
||||
RemoteUser *struct {
|
||||
Username string `xml:"Username"`
|
||||
@@ -24,16 +83,12 @@ func (c *Client) GetRemoteUser(ctx context.Context) (*RemoteUser, error) {
|
||||
} `xml:"RemoteUser"`
|
||||
}
|
||||
|
||||
req := GetRemoteUser{
|
||||
req := getRemoteUserRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
|
||||
var resp GetRemoteUserResponse
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
var resp getRemoteUserResponse
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetRemoteUser failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -50,36 +105,31 @@ func (c *Client) GetRemoteUser(ctx context.Context) (*RemoteUser, error) {
|
||||
|
||||
// SetRemoteUser sets the remote user.
|
||||
func (c *Client) SetRemoteUser(ctx context.Context, remoteUser *RemoteUser) error {
|
||||
type SetRemoteUser struct {
|
||||
XMLName xml.Name `xml:"tds:SetRemoteUser"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
RemoteUser *struct {
|
||||
Username string `xml:"tds:Username"`
|
||||
Password string `xml:"tds:Password,omitempty"`
|
||||
UseDerivedPassword bool `xml:"tds:UseDerivedPassword"`
|
||||
} `xml:"tds:RemoteUser,omitempty"`
|
||||
type remoteUserXML struct {
|
||||
Username string `xml:"tds:Username"`
|
||||
Password string `xml:"tds:Password,omitempty"`
|
||||
UseDerivedPassword bool `xml:"tds:UseDerivedPassword"`
|
||||
}
|
||||
|
||||
req := SetRemoteUser{
|
||||
type setRemoteUserRequest struct {
|
||||
XMLName xml.Name `xml:"tds:SetRemoteUser"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
RemoteUser *remoteUserXML `xml:"tds:RemoteUser,omitempty"`
|
||||
}
|
||||
|
||||
req := setRemoteUserRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
|
||||
if remoteUser != nil {
|
||||
req.RemoteUser = &struct {
|
||||
Username string `xml:"tds:Username"`
|
||||
Password string `xml:"tds:Password,omitempty"`
|
||||
UseDerivedPassword bool `xml:"tds:UseDerivedPassword"`
|
||||
}{
|
||||
req.RemoteUser = &remoteUserXML{
|
||||
Username: remoteUser.Username,
|
||||
Password: remoteUser.Password,
|
||||
UseDerivedPassword: remoteUser.UseDerivedPassword,
|
||||
}
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
return fmt.Errorf("SetRemoteUser failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -88,36 +138,31 @@ func (c *Client) SetRemoteUser(ctx context.Context, remoteUser *RemoteUser) erro
|
||||
|
||||
// GetIPAddressFilter gets the IP address filter settings from a device.
|
||||
func (c *Client) GetIPAddressFilter(ctx context.Context) (*IPAddressFilter, error) {
|
||||
type GetIPAddressFilter struct {
|
||||
type getIPAddressFilterRequest struct {
|
||||
XMLName xml.Name `xml:"tds:GetIPAddressFilter"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
}
|
||||
|
||||
type GetIPAddressFilterResponse struct {
|
||||
type prefixedAddressXML struct {
|
||||
Address string `xml:"Address"`
|
||||
PrefixLength int `xml:"PrefixLength"`
|
||||
}
|
||||
|
||||
type getIPAddressFilterResponse struct {
|
||||
XMLName xml.Name `xml:"GetIPAddressFilterResponse"`
|
||||
IPAddressFilter struct {
|
||||
Type string `xml:"Type"`
|
||||
IPv4Address []struct {
|
||||
Address string `xml:"Address"`
|
||||
PrefixLength int `xml:"PrefixLength"`
|
||||
} `xml:"IPv4Address"`
|
||||
IPv6Address []struct {
|
||||
Address string `xml:"Address"`
|
||||
PrefixLength int `xml:"PrefixLength"`
|
||||
} `xml:"IPv6Address"`
|
||||
Type string `xml:"Type"`
|
||||
IPv4Address []prefixedAddressXML `xml:"IPv4Address"`
|
||||
IPv6Address []prefixedAddressXML `xml:"IPv6Address"`
|
||||
} `xml:"IPAddressFilter"`
|
||||
}
|
||||
|
||||
req := GetIPAddressFilter{
|
||||
req := getIPAddressFilterRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
|
||||
var resp GetIPAddressFilterResponse
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
var resp getIPAddressFilterResponse
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetIPAddressFilter failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -125,18 +170,25 @@ func (c *Client) GetIPAddressFilter(ctx context.Context) (*IPAddressFilter, erro
|
||||
Type: IPAddressFilterType(resp.IPAddressFilter.Type),
|
||||
}
|
||||
|
||||
for _, addr := range resp.IPAddressFilter.IPv4Address {
|
||||
filter.IPv4Address = append(filter.IPv4Address, PrefixedIPv4Address{
|
||||
Address: addr.Address,
|
||||
PrefixLength: addr.PrefixLength,
|
||||
})
|
||||
// Pre-allocate slices with known capacity
|
||||
if len(resp.IPAddressFilter.IPv4Address) > 0 {
|
||||
filter.IPv4Address = make([]PrefixedIPv4Address, 0, len(resp.IPAddressFilter.IPv4Address))
|
||||
for _, addr := range resp.IPAddressFilter.IPv4Address {
|
||||
filter.IPv4Address = append(filter.IPv4Address, PrefixedIPv4Address{
|
||||
Address: addr.Address,
|
||||
PrefixLength: addr.PrefixLength,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for _, addr := range resp.IPAddressFilter.IPv6Address {
|
||||
filter.IPv6Address = append(filter.IPv6Address, PrefixedIPv6Address{
|
||||
Address: addr.Address,
|
||||
PrefixLength: addr.PrefixLength,
|
||||
})
|
||||
if len(resp.IPAddressFilter.IPv6Address) > 0 {
|
||||
filter.IPv6Address = make([]PrefixedIPv6Address, 0, len(resp.IPAddressFilter.IPv6Address))
|
||||
for _, addr := range resp.IPAddressFilter.IPv6Address {
|
||||
filter.IPv6Address = append(filter.IPv6Address, PrefixedIPv6Address{
|
||||
Address: addr.Address,
|
||||
PrefixLength: addr.PrefixLength,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return filter, nil
|
||||
@@ -144,51 +196,18 @@ func (c *Client) GetIPAddressFilter(ctx context.Context) (*IPAddressFilter, erro
|
||||
|
||||
// SetIPAddressFilter sets the IP address filter settings on a device.
|
||||
func (c *Client) SetIPAddressFilter(ctx context.Context, filter *IPAddressFilter) error {
|
||||
type SetIPAddressFilter struct {
|
||||
XMLName xml.Name `xml:"tds:SetIPAddressFilter"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
IPAddressFilter struct {
|
||||
Type string `xml:"tds:Type"`
|
||||
IPv4Address []struct {
|
||||
Address string `xml:"tds:Address"`
|
||||
PrefixLength int `xml:"tds:PrefixLength"`
|
||||
} `xml:"tds:IPv4Address,omitempty"`
|
||||
IPv6Address []struct {
|
||||
Address string `xml:"tds:Address"`
|
||||
PrefixLength int `xml:"tds:PrefixLength"`
|
||||
} `xml:"tds:IPv6Address,omitempty"`
|
||||
} `xml:"tds:IPAddressFilter"`
|
||||
type setIPAddressFilterRequest struct {
|
||||
XMLName xml.Name `xml:"tds:SetIPAddressFilter"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
IPAddressFilter ipAddressFilterRequest `xml:"tds:IPAddressFilter"`
|
||||
}
|
||||
|
||||
req := SetIPAddressFilter{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
req.IPAddressFilter.Type = string(filter.Type)
|
||||
|
||||
for _, addr := range filter.IPv4Address {
|
||||
req.IPAddressFilter.IPv4Address = append(req.IPAddressFilter.IPv4Address, struct {
|
||||
Address string `xml:"tds:Address"`
|
||||
PrefixLength int `xml:"tds:PrefixLength"`
|
||||
}{
|
||||
Address: addr.Address,
|
||||
PrefixLength: addr.PrefixLength,
|
||||
})
|
||||
req := setIPAddressFilterRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
IPAddressFilter: buildIPAddressFilterRequest(filter),
|
||||
}
|
||||
|
||||
for _, addr := range filter.IPv6Address {
|
||||
req.IPAddressFilter.IPv6Address = append(req.IPAddressFilter.IPv6Address, struct {
|
||||
Address string `xml:"tds:Address"`
|
||||
PrefixLength int `xml:"tds:PrefixLength"`
|
||||
}{
|
||||
Address: addr.Address,
|
||||
PrefixLength: addr.PrefixLength,
|
||||
})
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
return fmt.Errorf("SetIPAddressFilter failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -197,51 +216,18 @@ func (c *Client) SetIPAddressFilter(ctx context.Context, filter *IPAddressFilter
|
||||
|
||||
// AddIPAddressFilter adds an IP filter address to a device.
|
||||
func (c *Client) AddIPAddressFilter(ctx context.Context, filter *IPAddressFilter) error {
|
||||
type AddIPAddressFilter struct {
|
||||
XMLName xml.Name `xml:"tds:AddIPAddressFilter"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
IPAddressFilter struct {
|
||||
Type string `xml:"tds:Type"`
|
||||
IPv4Address []struct {
|
||||
Address string `xml:"tds:Address"`
|
||||
PrefixLength int `xml:"tds:PrefixLength"`
|
||||
} `xml:"tds:IPv4Address,omitempty"`
|
||||
IPv6Address []struct {
|
||||
Address string `xml:"tds:Address"`
|
||||
PrefixLength int `xml:"tds:PrefixLength"`
|
||||
} `xml:"tds:IPv6Address,omitempty"`
|
||||
} `xml:"tds:IPAddressFilter"`
|
||||
type addIPAddressFilterRequest struct {
|
||||
XMLName xml.Name `xml:"tds:AddIPAddressFilter"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
IPAddressFilter ipAddressFilterRequest `xml:"tds:IPAddressFilter"`
|
||||
}
|
||||
|
||||
req := AddIPAddressFilter{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
req.IPAddressFilter.Type = string(filter.Type)
|
||||
|
||||
for _, addr := range filter.IPv4Address {
|
||||
req.IPAddressFilter.IPv4Address = append(req.IPAddressFilter.IPv4Address, struct {
|
||||
Address string `xml:"tds:Address"`
|
||||
PrefixLength int `xml:"tds:PrefixLength"`
|
||||
}{
|
||||
Address: addr.Address,
|
||||
PrefixLength: addr.PrefixLength,
|
||||
})
|
||||
req := addIPAddressFilterRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
IPAddressFilter: buildIPAddressFilterRequest(filter),
|
||||
}
|
||||
|
||||
for _, addr := range filter.IPv6Address {
|
||||
req.IPAddressFilter.IPv6Address = append(req.IPAddressFilter.IPv6Address, struct {
|
||||
Address string `xml:"tds:Address"`
|
||||
PrefixLength int `xml:"tds:PrefixLength"`
|
||||
}{
|
||||
Address: addr.Address,
|
||||
PrefixLength: addr.PrefixLength,
|
||||
})
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
return fmt.Errorf("AddIPAddressFilter failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -250,51 +236,18 @@ func (c *Client) AddIPAddressFilter(ctx context.Context, filter *IPAddressFilter
|
||||
|
||||
// RemoveIPAddressFilter deletes an IP filter address from a device.
|
||||
func (c *Client) RemoveIPAddressFilter(ctx context.Context, filter *IPAddressFilter) error {
|
||||
type RemoveIPAddressFilter struct {
|
||||
XMLName xml.Name `xml:"tds:RemoveIPAddressFilter"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
IPAddressFilter struct {
|
||||
Type string `xml:"tds:Type"`
|
||||
IPv4Address []struct {
|
||||
Address string `xml:"tds:Address"`
|
||||
PrefixLength int `xml:"tds:PrefixLength"`
|
||||
} `xml:"tds:IPv4Address,omitempty"`
|
||||
IPv6Address []struct {
|
||||
Address string `xml:"tds:Address"`
|
||||
PrefixLength int `xml:"tds:PrefixLength"`
|
||||
} `xml:"tds:IPv6Address,omitempty"`
|
||||
} `xml:"tds:IPAddressFilter"`
|
||||
type removeIPAddressFilterRequest struct {
|
||||
XMLName xml.Name `xml:"tds:RemoveIPAddressFilter"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
IPAddressFilter ipAddressFilterRequest `xml:"tds:IPAddressFilter"`
|
||||
}
|
||||
|
||||
req := RemoveIPAddressFilter{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
req.IPAddressFilter.Type = string(filter.Type)
|
||||
|
||||
for _, addr := range filter.IPv4Address {
|
||||
req.IPAddressFilter.IPv4Address = append(req.IPAddressFilter.IPv4Address, struct {
|
||||
Address string `xml:"tds:Address"`
|
||||
PrefixLength int `xml:"tds:PrefixLength"`
|
||||
}{
|
||||
Address: addr.Address,
|
||||
PrefixLength: addr.PrefixLength,
|
||||
})
|
||||
req := removeIPAddressFilterRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
IPAddressFilter: buildIPAddressFilterRequest(filter),
|
||||
}
|
||||
|
||||
for _, addr := range filter.IPv6Address {
|
||||
req.IPAddressFilter.IPv6Address = append(req.IPAddressFilter.IPv6Address, struct {
|
||||
Address string `xml:"tds:Address"`
|
||||
PrefixLength int `xml:"tds:PrefixLength"`
|
||||
}{
|
||||
Address: addr.Address,
|
||||
PrefixLength: addr.PrefixLength,
|
||||
})
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
return fmt.Errorf("RemoveIPAddressFilter failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -303,12 +256,12 @@ func (c *Client) RemoveIPAddressFilter(ctx context.Context, filter *IPAddressFil
|
||||
|
||||
// GetZeroConfiguration gets the zero-configuration from a device.
|
||||
func (c *Client) GetZeroConfiguration(ctx context.Context) (*NetworkZeroConfiguration, error) {
|
||||
type GetZeroConfiguration struct {
|
||||
type getZeroConfigurationRequest struct {
|
||||
XMLName xml.Name `xml:"tds:GetZeroConfiguration"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
}
|
||||
|
||||
type GetZeroConfigurationResponse struct {
|
||||
type getZeroConfigurationResponse struct {
|
||||
XMLName xml.Name `xml:"GetZeroConfigurationResponse"`
|
||||
ZeroConfiguration struct {
|
||||
InterfaceToken string `xml:"InterfaceToken"`
|
||||
@@ -317,16 +270,12 @@ func (c *Client) GetZeroConfiguration(ctx context.Context) (*NetworkZeroConfigur
|
||||
} `xml:"ZeroConfiguration"`
|
||||
}
|
||||
|
||||
req := GetZeroConfiguration{
|
||||
req := getZeroConfigurationRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
|
||||
var resp GetZeroConfigurationResponse
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
var resp getZeroConfigurationResponse
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetZeroConfiguration failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -339,23 +288,20 @@ func (c *Client) GetZeroConfiguration(ctx context.Context) (*NetworkZeroConfigur
|
||||
|
||||
// SetZeroConfiguration sets the zero-configuration.
|
||||
func (c *Client) SetZeroConfiguration(ctx context.Context, interfaceToken string, enabled bool) error {
|
||||
type SetZeroConfiguration struct {
|
||||
type setZeroConfigurationRequest struct {
|
||||
XMLName xml.Name `xml:"tds:SetZeroConfiguration"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
InterfaceToken string `xml:"tds:InterfaceToken"`
|
||||
Enabled bool `xml:"tds:Enabled"`
|
||||
}
|
||||
|
||||
req := SetZeroConfiguration{
|
||||
req := setZeroConfigurationRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
InterfaceToken: interfaceToken,
|
||||
Enabled: enabled,
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
return fmt.Errorf("SetZeroConfiguration failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -364,12 +310,12 @@ func (c *Client) SetZeroConfiguration(ctx context.Context, interfaceToken string
|
||||
|
||||
// GetDynamicDNS gets the dynamic DNS settings from a device.
|
||||
func (c *Client) GetDynamicDNS(ctx context.Context) (*DynamicDNSInformation, error) {
|
||||
type GetDynamicDNS struct {
|
||||
type getDynamicDNSRequest struct {
|
||||
XMLName xml.Name `xml:"tds:GetDynamicDNS"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
}
|
||||
|
||||
type GetDynamicDNSResponse struct {
|
||||
type getDynamicDNSResponse struct {
|
||||
XMLName xml.Name `xml:"GetDynamicDNSResponse"`
|
||||
DynamicDNSInformation struct {
|
||||
Type string `xml:"Type"`
|
||||
@@ -378,16 +324,12 @@ func (c *Client) GetDynamicDNS(ctx context.Context) (*DynamicDNSInformation, err
|
||||
} `xml:"DynamicDNSInformation"`
|
||||
}
|
||||
|
||||
req := GetDynamicDNS{
|
||||
req := getDynamicDNSRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
|
||||
var resp GetDynamicDNSResponse
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
var resp getDynamicDNSResponse
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetDynamicDNS failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -400,23 +342,20 @@ func (c *Client) GetDynamicDNS(ctx context.Context) (*DynamicDNSInformation, err
|
||||
|
||||
// SetDynamicDNS sets the dynamic DNS settings on a device.
|
||||
func (c *Client) SetDynamicDNS(ctx context.Context, dnsType DynamicDNSType, name string) error {
|
||||
type SetDynamicDNS struct {
|
||||
type setDynamicDNSRequest struct {
|
||||
XMLName xml.Name `xml:"tds:SetDynamicDNS"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
Type DynamicDNSType `xml:"tds:Type"`
|
||||
Name string `xml:"tds:Name,omitempty"`
|
||||
}
|
||||
|
||||
req := SetDynamicDNS{
|
||||
req := setDynamicDNSRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
Type: dnsType,
|
||||
Name: name,
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
return fmt.Errorf("SetDynamicDNS failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -425,12 +364,12 @@ func (c *Client) SetDynamicDNS(ctx context.Context, dnsType DynamicDNSType, name
|
||||
|
||||
// GetPasswordComplexityConfiguration retrieves the current password complexity configuration settings.
|
||||
func (c *Client) GetPasswordComplexityConfiguration(ctx context.Context) (*PasswordComplexityConfiguration, error) {
|
||||
type GetPasswordComplexityConfiguration struct {
|
||||
type getPasswordComplexityConfigurationRequest struct {
|
||||
XMLName xml.Name `xml:"tds:GetPasswordComplexityConfiguration"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
}
|
||||
|
||||
type GetPasswordComplexityConfigurationResponse struct {
|
||||
type getPasswordComplexityConfigurationResponse struct {
|
||||
XMLName xml.Name `xml:"GetPasswordComplexityConfigurationResponse"`
|
||||
MinLen int `xml:"MinLen"`
|
||||
Uppercase int `xml:"Uppercase"`
|
||||
@@ -440,16 +379,12 @@ func (c *Client) GetPasswordComplexityConfiguration(ctx context.Context) (*Passw
|
||||
PolicyConfigurationLocked bool `xml:"PolicyConfigurationLocked"`
|
||||
}
|
||||
|
||||
req := GetPasswordComplexityConfiguration{
|
||||
req := getPasswordComplexityConfigurationRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
|
||||
var resp GetPasswordComplexityConfigurationResponse
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
var resp getPasswordComplexityConfigurationResponse
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetPasswordComplexityConfiguration failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -468,7 +403,7 @@ func (c *Client) SetPasswordComplexityConfiguration(
|
||||
ctx context.Context,
|
||||
config *PasswordComplexityConfiguration,
|
||||
) error {
|
||||
type SetPasswordComplexityConfiguration struct {
|
||||
type setPasswordComplexityConfigurationRequest struct {
|
||||
XMLName xml.Name `xml:"tds:SetPasswordComplexityConfiguration"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
MinLen int `xml:"tds:MinLen,omitempty"`
|
||||
@@ -479,7 +414,7 @@ func (c *Client) SetPasswordComplexityConfiguration(
|
||||
PolicyConfigurationLocked bool `xml:"tds:PolicyConfigurationLocked,omitempty"`
|
||||
}
|
||||
|
||||
req := SetPasswordComplexityConfiguration{
|
||||
req := setPasswordComplexityConfigurationRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
MinLen: config.MinLen,
|
||||
Uppercase: config.Uppercase,
|
||||
@@ -489,10 +424,7 @@ func (c *Client) SetPasswordComplexityConfiguration(
|
||||
PolicyConfigurationLocked: config.PolicyConfigurationLocked,
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
return fmt.Errorf("SetPasswordComplexityConfiguration failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -501,27 +433,23 @@ func (c *Client) SetPasswordComplexityConfiguration(
|
||||
|
||||
// GetPasswordHistoryConfiguration retrieves the current password history configuration settings.
|
||||
func (c *Client) GetPasswordHistoryConfiguration(ctx context.Context) (*PasswordHistoryConfiguration, error) {
|
||||
type GetPasswordHistoryConfiguration struct {
|
||||
type getPasswordHistoryConfigurationRequest struct {
|
||||
XMLName xml.Name `xml:"tds:GetPasswordHistoryConfiguration"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
}
|
||||
|
||||
type GetPasswordHistoryConfigurationResponse struct {
|
||||
type getPasswordHistoryConfigurationResponse struct {
|
||||
XMLName xml.Name `xml:"GetPasswordHistoryConfigurationResponse"`
|
||||
Enabled bool `xml:"Enabled"`
|
||||
Length int `xml:"Length"`
|
||||
}
|
||||
|
||||
req := GetPasswordHistoryConfiguration{
|
||||
req := getPasswordHistoryConfigurationRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
|
||||
var resp GetPasswordHistoryConfigurationResponse
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
var resp getPasswordHistoryConfigurationResponse
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetPasswordHistoryConfiguration failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -533,23 +461,20 @@ func (c *Client) GetPasswordHistoryConfiguration(ctx context.Context) (*Password
|
||||
|
||||
// SetPasswordHistoryConfiguration allows setting of the password history configuration.
|
||||
func (c *Client) SetPasswordHistoryConfiguration(ctx context.Context, config *PasswordHistoryConfiguration) error {
|
||||
type SetPasswordHistoryConfiguration struct {
|
||||
type setPasswordHistoryConfigurationRequest struct {
|
||||
XMLName xml.Name `xml:"tds:SetPasswordHistoryConfiguration"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
Enabled bool `xml:"tds:Enabled"`
|
||||
Length int `xml:"tds:Length"`
|
||||
}
|
||||
|
||||
req := SetPasswordHistoryConfiguration{
|
||||
req := setPasswordHistoryConfigurationRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
Enabled: config.Enabled,
|
||||
Length: config.Length,
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
return fmt.Errorf("SetPasswordHistoryConfiguration failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -558,28 +483,24 @@ func (c *Client) SetPasswordHistoryConfiguration(ctx context.Context, config *Pa
|
||||
|
||||
// GetAuthFailureWarningConfiguration retrieves the current authentication failure warning configuration.
|
||||
func (c *Client) GetAuthFailureWarningConfiguration(ctx context.Context) (*AuthFailureWarningConfiguration, error) {
|
||||
type GetAuthFailureWarningConfiguration struct {
|
||||
type getAuthFailureWarningConfigurationRequest struct {
|
||||
XMLName xml.Name `xml:"tds:GetAuthFailureWarningConfiguration"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
}
|
||||
|
||||
type GetAuthFailureWarningConfigurationResponse struct {
|
||||
type getAuthFailureWarningConfigurationResponse struct {
|
||||
XMLName xml.Name `xml:"GetAuthFailureWarningConfigurationResponse"`
|
||||
Enabled bool `xml:"Enabled"`
|
||||
MonitorPeriod int `xml:"MonitorPeriod"`
|
||||
MaxAuthFailures int `xml:"MaxAuthFailures"`
|
||||
}
|
||||
|
||||
req := GetAuthFailureWarningConfiguration{
|
||||
req := getAuthFailureWarningConfigurationRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
|
||||
var resp GetAuthFailureWarningConfigurationResponse
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
var resp getAuthFailureWarningConfigurationResponse
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetAuthFailureWarningConfiguration failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -595,7 +516,7 @@ func (c *Client) SetAuthFailureWarningConfiguration(
|
||||
ctx context.Context,
|
||||
config *AuthFailureWarningConfiguration,
|
||||
) error {
|
||||
type SetAuthFailureWarningConfiguration struct {
|
||||
type setAuthFailureWarningConfigurationRequest struct {
|
||||
XMLName xml.Name `xml:"tds:SetAuthFailureWarningConfiguration"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
Enabled bool `xml:"tds:Enabled"`
|
||||
@@ -603,17 +524,14 @@ func (c *Client) SetAuthFailureWarningConfiguration(
|
||||
MaxAuthFailures int `xml:"tds:MaxAuthFailures"`
|
||||
}
|
||||
|
||||
req := SetAuthFailureWarningConfiguration{
|
||||
req := setAuthFailureWarningConfigurationRequest{
|
||||
Xmlns: deviceNamespace,
|
||||
Enabled: config.Enabled,
|
||||
MonitorPeriod: config.MonitorPeriod,
|
||||
MaxAuthFailures: config.MaxAuthFailures,
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
return fmt.Errorf("SetAuthFailureWarningConfiguration failed: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -521,3 +521,266 @@ func TestIPAddressFilterTypeConstants(t *testing.T) {
|
||||
t.Errorf("IPAddressFilterDeny should be 'Deny', got %s", IPAddressFilterDeny)
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmarks for device security operations.
|
||||
|
||||
func BenchmarkGetRemoteUser(b *testing.B) {
|
||||
server := newMockDeviceSecurityServer()
|
||||
defer server.Close()
|
||||
|
||||
client, _ := NewClient(server.URL)
|
||||
ctx := context.Background()
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = client.GetRemoteUser(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSetRemoteUser(b *testing.B) {
|
||||
server := newMockDeviceSecurityServer()
|
||||
defer server.Close()
|
||||
|
||||
client, _ := NewClient(server.URL)
|
||||
ctx := context.Background()
|
||||
remoteUser := &RemoteUser{
|
||||
Username: "test_user",
|
||||
Password: "password123",
|
||||
UseDerivedPassword: true,
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = client.SetRemoteUser(ctx, remoteUser)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetIPAddressFilter(b *testing.B) {
|
||||
server := newMockDeviceSecurityServer()
|
||||
defer server.Close()
|
||||
|
||||
client, _ := NewClient(server.URL)
|
||||
ctx := context.Background()
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = client.GetIPAddressFilter(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSetIPAddressFilter(b *testing.B) {
|
||||
server := newMockDeviceSecurityServer()
|
||||
defer server.Close()
|
||||
|
||||
client, _ := NewClient(server.URL)
|
||||
ctx := context.Background()
|
||||
filter := &IPAddressFilter{
|
||||
Type: IPAddressFilterAllow,
|
||||
IPv4Address: []PrefixedIPv4Address{
|
||||
{Address: "192.168.1.0", PrefixLength: 24},
|
||||
{Address: "10.0.0.0", PrefixLength: 8},
|
||||
},
|
||||
IPv6Address: []PrefixedIPv6Address{
|
||||
{Address: "fe80::", PrefixLength: 64},
|
||||
},
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = client.SetIPAddressFilter(ctx, filter)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAddIPAddressFilter(b *testing.B) {
|
||||
server := newMockDeviceSecurityServer()
|
||||
defer server.Close()
|
||||
|
||||
client, _ := NewClient(server.URL)
|
||||
ctx := context.Background()
|
||||
filter := &IPAddressFilter{
|
||||
Type: IPAddressFilterAllow,
|
||||
IPv4Address: []PrefixedIPv4Address{
|
||||
{Address: "172.16.0.0", PrefixLength: 12},
|
||||
},
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = client.AddIPAddressFilter(ctx, filter)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkRemoveIPAddressFilter(b *testing.B) {
|
||||
server := newMockDeviceSecurityServer()
|
||||
defer server.Close()
|
||||
|
||||
client, _ := NewClient(server.URL)
|
||||
ctx := context.Background()
|
||||
filter := &IPAddressFilter{
|
||||
Type: IPAddressFilterAllow,
|
||||
IPv4Address: []PrefixedIPv4Address{
|
||||
{Address: "172.16.0.0", PrefixLength: 12},
|
||||
},
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = client.RemoveIPAddressFilter(ctx, filter)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetZeroConfiguration(b *testing.B) {
|
||||
server := newMockDeviceSecurityServer()
|
||||
defer server.Close()
|
||||
|
||||
client, _ := NewClient(server.URL)
|
||||
ctx := context.Background()
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = client.GetZeroConfiguration(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSetZeroConfiguration(b *testing.B) {
|
||||
server := newMockDeviceSecurityServer()
|
||||
defer server.Close()
|
||||
|
||||
client, _ := NewClient(server.URL)
|
||||
ctx := context.Background()
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = client.SetZeroConfiguration(ctx, "eth0", true)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetPasswordComplexityConfiguration(b *testing.B) {
|
||||
server := newMockDeviceSecurityServer()
|
||||
defer server.Close()
|
||||
|
||||
client, _ := NewClient(server.URL)
|
||||
ctx := context.Background()
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = client.GetPasswordComplexityConfiguration(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSetPasswordComplexityConfiguration(b *testing.B) {
|
||||
server := newMockDeviceSecurityServer()
|
||||
defer server.Close()
|
||||
|
||||
client, _ := NewClient(server.URL)
|
||||
ctx := context.Background()
|
||||
config := &PasswordComplexityConfiguration{
|
||||
MinLen: 10,
|
||||
Uppercase: 2,
|
||||
Number: 2,
|
||||
SpecialChars: 1,
|
||||
BlockUsernameOccurrence: true,
|
||||
PolicyConfigurationLocked: false,
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = client.SetPasswordComplexityConfiguration(ctx, config)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetPasswordHistoryConfiguration(b *testing.B) {
|
||||
server := newMockDeviceSecurityServer()
|
||||
defer server.Close()
|
||||
|
||||
client, _ := NewClient(server.URL)
|
||||
ctx := context.Background()
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = client.GetPasswordHistoryConfiguration(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSetPasswordHistoryConfiguration(b *testing.B) {
|
||||
server := newMockDeviceSecurityServer()
|
||||
defer server.Close()
|
||||
|
||||
client, _ := NewClient(server.URL)
|
||||
ctx := context.Background()
|
||||
config := &PasswordHistoryConfiguration{
|
||||
Enabled: true,
|
||||
Length: 10,
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = client.SetPasswordHistoryConfiguration(ctx, config)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetAuthFailureWarningConfiguration(b *testing.B) {
|
||||
server := newMockDeviceSecurityServer()
|
||||
defer server.Close()
|
||||
|
||||
client, _ := NewClient(server.URL)
|
||||
ctx := context.Background()
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = client.GetAuthFailureWarningConfiguration(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSetAuthFailureWarningConfiguration(b *testing.B) {
|
||||
server := newMockDeviceSecurityServer()
|
||||
defer server.Close()
|
||||
|
||||
client, _ := NewClient(server.URL)
|
||||
ctx := context.Background()
|
||||
config := &AuthFailureWarningConfiguration{
|
||||
Enabled: true,
|
||||
MonitorPeriod: 120,
|
||||
MaxAuthFailures: 3,
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = client.SetAuthFailureWarningConfiguration(ctx, config)
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkIPAddressFilterWithManyAddresses tests performance with larger address lists.
|
||||
func BenchmarkIPAddressFilterWithManyAddresses(b *testing.B) {
|
||||
server := newMockDeviceSecurityServer()
|
||||
defer server.Close()
|
||||
|
||||
client, _ := NewClient(server.URL)
|
||||
ctx := context.Background()
|
||||
|
||||
// Create filter with many addresses to test pre-allocation efficiency
|
||||
filter := &IPAddressFilter{
|
||||
Type: IPAddressFilterAllow,
|
||||
IPv4Address: make([]PrefixedIPv4Address, 100),
|
||||
IPv6Address: make([]PrefixedIPv6Address, 50),
|
||||
}
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
filter.IPv4Address[i] = PrefixedIPv4Address{
|
||||
Address: "192.168.1.0",
|
||||
PrefixLength: 24,
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < 50; i++ {
|
||||
filter.IPv6Address[i] = PrefixedIPv6Address{
|
||||
Address: "fe80::",
|
||||
PrefixLength: 64,
|
||||
}
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = client.SetIPAddressFilter(ctx, filter)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,12 +227,16 @@ func deviceMapToSlice(m map[string]*Device) []*Device {
|
||||
|
||||
// generateUUID generates a simple UUID (not cryptographically secure).
|
||||
func generateUUID() string {
|
||||
now := time.Now()
|
||||
nanos := now.UnixNano()
|
||||
secs := now.Unix()
|
||||
|
||||
return fmt.Sprintf("%d-%d-%d-%d-%d",
|
||||
time.Now().UnixNano(),
|
||||
time.Now().Unix(),
|
||||
time.Now().UnixNano()%uuidMod1000,
|
||||
time.Now().Unix()%uuidMod1000,
|
||||
time.Now().UnixNano()%uuidMod10000)
|
||||
nanos,
|
||||
secs,
|
||||
nanos%uuidMod1000,
|
||||
secs%uuidMod1000,
|
||||
nanos%uuidMod10000)
|
||||
}
|
||||
|
||||
// resolveNetworkInterface resolves a network interface by name or IP address.
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/0x524a/onvif-go/internal/soap"
|
||||
@@ -751,28 +752,5 @@ func splitSpaceSeparated(s string) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
var result []string
|
||||
|
||||
start := 0
|
||||
inWord := false
|
||||
|
||||
for i, r := range s {
|
||||
if r == ' ' || r == '\t' {
|
||||
if inWord {
|
||||
result = append(result, s[start:i])
|
||||
inWord = false
|
||||
}
|
||||
} else {
|
||||
if !inWord {
|
||||
start = i
|
||||
inWord = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if inWord {
|
||||
result = append(result, s[start:])
|
||||
}
|
||||
|
||||
return result
|
||||
return strings.Fields(s)
|
||||
}
|
||||
|
||||
@@ -20,21 +20,11 @@ func (c *Client) getMediaEndpoint() string {
|
||||
return c.endpoint
|
||||
}
|
||||
|
||||
// getMediaSoapClient creates a new SOAP client for media operations.
|
||||
func (c *Client) getMediaSoapClient() *soap.Client {
|
||||
username, password := c.GetCredentials()
|
||||
|
||||
return soap.NewClient(c.httpClient, username, password)
|
||||
}
|
||||
|
||||
// GetProfiles retrieves all media profiles.
|
||||
//
|
||||
//nolint:funlen // GetProfiles has many statements due to parsing complex profile structures
|
||||
func (c *Client) GetProfiles(ctx context.Context) ([]*Profile, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetProfiles struct {
|
||||
XMLName xml.Name `xml:"trt:GetProfiles"`
|
||||
@@ -160,10 +150,7 @@ func (c *Client) GetProfiles(ctx context.Context) ([]*Profile, error) {
|
||||
|
||||
// GetStreamURI retrieves the stream URI for a profile.
|
||||
func (c *Client) GetStreamURI(ctx context.Context, profileToken string) (*MediaURI, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetStreamURI struct {
|
||||
XMLName xml.Name `xml:"trt:GetStreamUri"`
|
||||
@@ -214,10 +201,7 @@ func (c *Client) GetStreamURI(ctx context.Context, profileToken string) (*MediaU
|
||||
|
||||
// GetSnapshotURI retrieves the snapshot URI for a profile.
|
||||
func (c *Client) GetSnapshotURI(ctx context.Context, profileToken string) (*MediaURI, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetSnapshotURI struct {
|
||||
XMLName xml.Name `xml:"trt:GetSnapshotUri"`
|
||||
@@ -261,10 +245,7 @@ func (c *Client) GetVideoEncoderConfiguration(
|
||||
ctx context.Context,
|
||||
configurationToken string,
|
||||
) (*VideoEncoderConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetVideoEncoderConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:GetVideoEncoderConfiguration"`
|
||||
@@ -334,10 +315,7 @@ func (c *Client) GetVideoEncoderConfiguration(
|
||||
|
||||
// GetVideoSources retrieves all video sources.
|
||||
func (c *Client) GetVideoSources(ctx context.Context) ([]*VideoSource, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetVideoSources struct {
|
||||
XMLName xml.Name `xml:"trt:GetVideoSources"`
|
||||
@@ -386,10 +364,7 @@ func (c *Client) GetVideoSources(ctx context.Context) ([]*VideoSource, error) {
|
||||
|
||||
// GetAudioSources retrieves all audio sources.
|
||||
func (c *Client) GetAudioSources(ctx context.Context) ([]*AudioSource, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetAudioSources struct {
|
||||
XMLName xml.Name `xml:"trt:GetAudioSources"`
|
||||
@@ -430,10 +405,7 @@ func (c *Client) GetAudioSources(ctx context.Context) ([]*AudioSource, error) {
|
||||
|
||||
// GetAudioOutputs retrieves all audio outputs.
|
||||
func (c *Client) GetAudioOutputs(ctx context.Context) ([]*AudioOutput, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetAudioOutputs struct {
|
||||
XMLName xml.Name `xml:"trt:GetAudioOutputs"`
|
||||
@@ -472,10 +444,7 @@ func (c *Client) GetAudioOutputs(ctx context.Context) ([]*AudioOutput, error) {
|
||||
|
||||
// CreateProfile creates a new media profile.
|
||||
func (c *Client) CreateProfile(ctx context.Context, name, token string) (*Profile, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type CreateProfile struct {
|
||||
XMLName xml.Name `xml:"trt:CreateProfile"`
|
||||
@@ -517,10 +486,7 @@ func (c *Client) CreateProfile(ctx context.Context, name, token string) (*Profil
|
||||
|
||||
// DeleteProfile deletes a media profile.
|
||||
func (c *Client) DeleteProfile(ctx context.Context, profileToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type DeleteProfile struct {
|
||||
XMLName xml.Name `xml:"trt:DeleteProfile"`
|
||||
@@ -549,10 +515,7 @@ func (c *Client) SetVideoEncoderConfiguration(
|
||||
config *VideoEncoderConfiguration,
|
||||
forcePersistence bool,
|
||||
) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type SetVideoEncoderConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:SetVideoEncoderConfiguration"`
|
||||
@@ -626,10 +589,7 @@ func (c *Client) SetVideoEncoderConfiguration(
|
||||
|
||||
// GetMediaServiceCapabilities retrieves media service capabilities.
|
||||
func (c *Client) GetMediaServiceCapabilities(ctx context.Context) (*MediaServiceCapabilities, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetServiceCapabilities struct {
|
||||
XMLName xml.Name `xml:"trt:GetServiceCapabilities"`
|
||||
@@ -697,10 +657,7 @@ func (c *Client) GetMediaServiceCapabilities(ctx context.Context) (*MediaService
|
||||
func (c *Client) GetVideoEncoderConfigurationOptions(
|
||||
ctx context.Context, configurationToken string,
|
||||
) (*VideoEncoderConfigurationOptions, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetVideoEncoderConfigurationOptions struct {
|
||||
XMLName xml.Name `xml:"trt:GetVideoEncoderConfigurationOptions"`
|
||||
@@ -839,10 +796,7 @@ func (c *Client) GetAudioEncoderConfiguration(
|
||||
ctx context.Context,
|
||||
configurationToken string,
|
||||
) (*AudioEncoderConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetAudioEncoderConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:GetAudioEncoderConfiguration"`
|
||||
@@ -920,10 +874,7 @@ func (c *Client) SetAudioEncoderConfiguration(
|
||||
config *AudioEncoderConfiguration,
|
||||
forcePersistence bool,
|
||||
) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type SetAudioEncoderConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:SetAudioEncoderConfiguration"`
|
||||
@@ -1011,10 +962,7 @@ func (c *Client) GetMetadataConfiguration(
|
||||
ctx context.Context,
|
||||
configurationToken string,
|
||||
) (*MetadataConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetMetadataConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:GetMetadataConfiguration"`
|
||||
@@ -1104,10 +1052,7 @@ func (c *Client) SetMetadataConfiguration(
|
||||
config *MetadataConfiguration,
|
||||
forcePersistence bool,
|
||||
) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type SetMetadataConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:SetMetadataConfiguration"`
|
||||
@@ -1203,10 +1148,7 @@ func (c *Client) SetMetadataConfiguration(
|
||||
|
||||
// GetVideoSourceModes retrieves available video source modes.
|
||||
func (c *Client) GetVideoSourceModes(ctx context.Context, videoSourceToken string) ([]*VideoSourceMode, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetVideoSourceModes struct {
|
||||
XMLName xml.Name `xml:"trt:GetVideoSourceModes"`
|
||||
@@ -1257,10 +1199,7 @@ func (c *Client) GetVideoSourceModes(ctx context.Context, videoSourceToken strin
|
||||
|
||||
// SetVideoSourceMode sets the video source mode.
|
||||
func (c *Client) SetVideoSourceMode(ctx context.Context, videoSourceToken, modeToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type SetVideoSourceMode struct {
|
||||
XMLName xml.Name `xml:"trt:SetVideoSourceMode"`
|
||||
@@ -1287,10 +1226,7 @@ func (c *Client) SetVideoSourceMode(ctx context.Context, videoSourceToken, modeT
|
||||
|
||||
// SetSynchronizationPoint sets a synchronization point for the stream.
|
||||
func (c *Client) SetSynchronizationPoint(ctx context.Context, profileToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type SetSynchronizationPoint struct {
|
||||
XMLName xml.Name `xml:"trt:SetSynchronizationPoint"`
|
||||
@@ -1315,10 +1251,7 @@ func (c *Client) SetSynchronizationPoint(ctx context.Context, profileToken strin
|
||||
|
||||
// GetOSDs retrieves all OSD configurations.
|
||||
func (c *Client) GetOSDs(ctx context.Context, configurationToken string) ([]*OSDConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetOSDs struct {
|
||||
XMLName xml.Name `xml:"trt:GetOSDs"`
|
||||
@@ -1361,10 +1294,7 @@ func (c *Client) GetOSDs(ctx context.Context, configurationToken string) ([]*OSD
|
||||
|
||||
// GetOSD retrieves a specific OSD configuration.
|
||||
func (c *Client) GetOSD(ctx context.Context, osdToken string) (*OSDConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetOSD struct {
|
||||
XMLName xml.Name `xml:"trt:GetOSD"`
|
||||
@@ -1400,10 +1330,7 @@ func (c *Client) GetOSD(ctx context.Context, osdToken string) (*OSDConfiguration
|
||||
|
||||
// SetOSD sets OSD configuration.
|
||||
func (c *Client) SetOSD(ctx context.Context, osd *OSDConfiguration) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type SetOSD struct {
|
||||
XMLName xml.Name `xml:"trt:SetOSD"`
|
||||
@@ -1436,10 +1363,7 @@ func (c *Client) CreateOSD(
|
||||
videoSourceConfigurationToken string,
|
||||
osd *OSDConfiguration,
|
||||
) (*OSDConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type CreateOSD struct {
|
||||
XMLName xml.Name `xml:"trt:CreateOSD"`
|
||||
@@ -1483,10 +1407,7 @@ func (c *Client) CreateOSD(
|
||||
|
||||
// DeleteOSD deletes an OSD configuration.
|
||||
func (c *Client) DeleteOSD(ctx context.Context, osdToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type DeleteOSD struct {
|
||||
XMLName xml.Name `xml:"trt:DeleteOSD"`
|
||||
@@ -1511,10 +1432,7 @@ func (c *Client) DeleteOSD(ctx context.Context, osdToken string) error {
|
||||
|
||||
// StartMulticastStreaming starts multicast streaming.
|
||||
func (c *Client) StartMulticastStreaming(ctx context.Context, profileToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type StartMulticastStreaming struct {
|
||||
XMLName xml.Name `xml:"trt:StartMulticastStreaming"`
|
||||
@@ -1539,10 +1457,7 @@ func (c *Client) StartMulticastStreaming(ctx context.Context, profileToken strin
|
||||
|
||||
// StopMulticastStreaming stops multicast streaming.
|
||||
func (c *Client) StopMulticastStreaming(ctx context.Context, profileToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type StopMulticastStreaming struct {
|
||||
XMLName xml.Name `xml:"trt:StopMulticastStreaming"`
|
||||
@@ -1567,10 +1482,7 @@ func (c *Client) StopMulticastStreaming(ctx context.Context, profileToken string
|
||||
|
||||
// GetProfile retrieves a specific media profile.
|
||||
func (c *Client) GetProfile(ctx context.Context, profileToken string) (*Profile, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetProfile struct {
|
||||
XMLName xml.Name `xml:"trt:GetProfile"`
|
||||
@@ -1608,10 +1520,7 @@ func (c *Client) GetProfile(ctx context.Context, profileToken string) (*Profile,
|
||||
|
||||
// SetProfile sets profile configuration.
|
||||
func (c *Client) SetProfile(ctx context.Context, profile *Profile) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type SetProfile struct {
|
||||
XMLName xml.Name `xml:"trt:SetProfile"`
|
||||
@@ -1642,10 +1551,7 @@ func (c *Client) SetProfile(ctx context.Context, profile *Profile) error {
|
||||
|
||||
// AddVideoEncoderConfiguration adds video encoder configuration to a profile.
|
||||
func (c *Client) AddVideoEncoderConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type AddVideoEncoderConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:AddVideoEncoderConfiguration"`
|
||||
@@ -1672,10 +1578,7 @@ func (c *Client) AddVideoEncoderConfiguration(ctx context.Context, profileToken,
|
||||
|
||||
// RemoveVideoEncoderConfiguration removes video encoder configuration from a profile.
|
||||
func (c *Client) RemoveVideoEncoderConfiguration(ctx context.Context, profileToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type RemoveVideoEncoderConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:RemoveVideoEncoderConfiguration"`
|
||||
@@ -1700,10 +1603,7 @@ func (c *Client) RemoveVideoEncoderConfiguration(ctx context.Context, profileTok
|
||||
|
||||
// AddAudioEncoderConfiguration adds audio encoder configuration to a profile.
|
||||
func (c *Client) AddAudioEncoderConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type AddAudioEncoderConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:AddAudioEncoderConfiguration"`
|
||||
@@ -1730,10 +1630,7 @@ func (c *Client) AddAudioEncoderConfiguration(ctx context.Context, profileToken,
|
||||
|
||||
// RemoveAudioEncoderConfiguration removes audio encoder configuration from a profile.
|
||||
func (c *Client) RemoveAudioEncoderConfiguration(ctx context.Context, profileToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type RemoveAudioEncoderConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:RemoveAudioEncoderConfiguration"`
|
||||
@@ -1758,10 +1655,7 @@ func (c *Client) RemoveAudioEncoderConfiguration(ctx context.Context, profileTok
|
||||
|
||||
// AddAudioSourceConfiguration adds audio source configuration to a profile.
|
||||
func (c *Client) AddAudioSourceConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type AddAudioSourceConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:AddAudioSourceConfiguration"`
|
||||
@@ -1788,10 +1682,7 @@ func (c *Client) AddAudioSourceConfiguration(ctx context.Context, profileToken,
|
||||
|
||||
// RemoveAudioSourceConfiguration removes audio source configuration from a profile.
|
||||
func (c *Client) RemoveAudioSourceConfiguration(ctx context.Context, profileToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type RemoveAudioSourceConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:RemoveAudioSourceConfiguration"`
|
||||
@@ -1816,10 +1707,7 @@ func (c *Client) RemoveAudioSourceConfiguration(ctx context.Context, profileToke
|
||||
|
||||
// AddVideoSourceConfiguration adds video source configuration to a profile.
|
||||
func (c *Client) AddVideoSourceConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type AddVideoSourceConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:AddVideoSourceConfiguration"`
|
||||
@@ -1846,10 +1734,7 @@ func (c *Client) AddVideoSourceConfiguration(ctx context.Context, profileToken,
|
||||
|
||||
// RemoveVideoSourceConfiguration removes video source configuration from a profile.
|
||||
func (c *Client) RemoveVideoSourceConfiguration(ctx context.Context, profileToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type RemoveVideoSourceConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:RemoveVideoSourceConfiguration"`
|
||||
@@ -1874,10 +1759,7 @@ func (c *Client) RemoveVideoSourceConfiguration(ctx context.Context, profileToke
|
||||
|
||||
// AddPTZConfiguration adds PTZ configuration to a profile.
|
||||
func (c *Client) AddPTZConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type AddPTZConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:AddPTZConfiguration"`
|
||||
@@ -1904,10 +1786,7 @@ func (c *Client) AddPTZConfiguration(ctx context.Context, profileToken, configur
|
||||
|
||||
// RemovePTZConfiguration removes PTZ configuration from a profile.
|
||||
func (c *Client) RemovePTZConfiguration(ctx context.Context, profileToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type RemovePTZConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:RemovePTZConfiguration"`
|
||||
@@ -1932,10 +1811,7 @@ func (c *Client) RemovePTZConfiguration(ctx context.Context, profileToken string
|
||||
|
||||
// AddMetadataConfiguration adds metadata configuration to a profile.
|
||||
func (c *Client) AddMetadataConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type AddMetadataConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:AddMetadataConfiguration"`
|
||||
@@ -1962,10 +1838,7 @@ func (c *Client) AddMetadataConfiguration(ctx context.Context, profileToken, con
|
||||
|
||||
// RemoveMetadataConfiguration removes metadata configuration from a profile.
|
||||
func (c *Client) RemoveMetadataConfiguration(ctx context.Context, profileToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type RemoveMetadataConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:RemoveMetadataConfiguration"`
|
||||
@@ -1993,10 +1866,7 @@ func (c *Client) GetAudioEncoderConfigurationOptions(
|
||||
ctx context.Context,
|
||||
configurationToken, profileToken string,
|
||||
) (*AudioEncoderConfigurationOptions, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetAudioEncoderConfigurationOptions struct {
|
||||
XMLName xml.Name `xml:"trt:GetAudioEncoderConfigurationOptions"`
|
||||
@@ -2045,10 +1915,7 @@ func (c *Client) GetMetadataConfigurationOptions(
|
||||
ctx context.Context,
|
||||
configurationToken, profileToken string,
|
||||
) (*MetadataConfigurationOptions, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetMetadataConfigurationOptions struct {
|
||||
XMLName xml.Name `xml:"trt:GetMetadataConfigurationOptions"`
|
||||
@@ -2124,7 +1991,9 @@ func (c *Client) GetAudioOutputConfiguration(ctx context.Context, configurationT
|
||||
}
|
||||
|
||||
var resp GetAudioOutputConfigurationResponse
|
||||
soapClient := c.getMediaSoapClient()
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetAudioOutputConfiguration failed: %w", err)
|
||||
@@ -2140,10 +2009,7 @@ func (c *Client) GetAudioOutputConfiguration(ctx context.Context, configurationT
|
||||
|
||||
// SetAudioOutputConfiguration sets audio output configuration.
|
||||
func (c *Client) SetAudioOutputConfiguration(ctx context.Context, config *AudioOutputConfiguration, forcePersistence bool) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type SetAudioOutputConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:SetAudioOutputConfiguration"`
|
||||
@@ -2184,10 +2050,7 @@ func (c *Client) GetAudioOutputConfigurationOptions(
|
||||
ctx context.Context,
|
||||
configurationToken string,
|
||||
) (*AudioOutputConfigurationOptions, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetAudioOutputConfigurationOptions struct {
|
||||
XMLName xml.Name `xml:"trt:GetAudioOutputConfigurationOptions"`
|
||||
@@ -2228,10 +2091,7 @@ func (c *Client) GetAudioDecoderConfigurationOptions(
|
||||
ctx context.Context,
|
||||
configurationToken string,
|
||||
) (*AudioDecoderConfigurationOptions, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetAudioDecoderConfigurationOptions struct {
|
||||
XMLName xml.Name `xml:"trt:GetAudioDecoderConfigurationOptions"`
|
||||
@@ -2297,10 +2157,7 @@ func (c *Client) GetGuaranteedNumberOfVideoEncoderInstances(
|
||||
ctx context.Context,
|
||||
configurationToken string,
|
||||
) (*GuaranteedNumberOfVideoEncoderInstances, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetGuaranteedNumberOfVideoEncoderInstances struct {
|
||||
XMLName xml.Name `xml:"trt:GetGuaranteedNumberOfVideoEncoderInstances"`
|
||||
@@ -2340,10 +2197,7 @@ func (c *Client) GetGuaranteedNumberOfVideoEncoderInstances(
|
||||
|
||||
// GetOSDOptions retrieves available options for OSD configuration.
|
||||
func (c *Client) GetOSDOptions(ctx context.Context, configurationToken string) (*OSDConfigurationOptions, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetOSDOptions struct {
|
||||
XMLName xml.Name `xml:"trt:GetOSDOptions"`
|
||||
@@ -2381,10 +2235,7 @@ func (c *Client) GetOSDOptions(ctx context.Context, configurationToken string) (
|
||||
|
||||
// GetVideoSourceConfigurations retrieves all video source configurations.
|
||||
func (c *Client) GetVideoSourceConfigurations(ctx context.Context) ([]*VideoSourceConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetVideoSourceConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetVideoSourceConfigurations"`
|
||||
@@ -2444,10 +2295,7 @@ func (c *Client) GetVideoSourceConfigurations(ctx context.Context) ([]*VideoSour
|
||||
|
||||
// GetAudioSourceConfigurations retrieves all audio source configurations.
|
||||
func (c *Client) GetAudioSourceConfigurations(ctx context.Context) ([]*AudioSourceConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetAudioSourceConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetAudioSourceConfigurations"`
|
||||
@@ -2492,10 +2340,7 @@ func (c *Client) GetAudioSourceConfigurations(ctx context.Context) ([]*AudioSour
|
||||
|
||||
// GetVideoEncoderConfigurations retrieves all video encoder configurations.
|
||||
func (c *Client) GetVideoEncoderConfigurations(ctx context.Context) ([]*VideoEncoderConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetVideoEncoderConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetVideoEncoderConfigurations"`
|
||||
@@ -2616,10 +2461,7 @@ func (c *Client) GetVideoEncoderConfigurations(ctx context.Context) ([]*VideoEnc
|
||||
|
||||
// GetAudioEncoderConfigurations retrieves all audio encoder configurations.
|
||||
func (c *Client) GetAudioEncoderConfigurations(ctx context.Context) ([]*AudioEncoderConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetAudioEncoderConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetAudioEncoderConfigurations"`
|
||||
@@ -2699,10 +2541,7 @@ func (c *Client) GetVideoSourceConfiguration(
|
||||
ctx context.Context,
|
||||
configurationToken string,
|
||||
) (*VideoSourceConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetVideoSourceConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:GetVideoSourceConfiguration"`
|
||||
@@ -2785,7 +2624,9 @@ func (c *Client) GetAudioSourceConfiguration(ctx context.Context, configurationT
|
||||
}
|
||||
|
||||
var resp GetAudioSourceConfigurationResponse
|
||||
soapClient := c.getMediaSoapClient()
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetAudioSourceConfiguration failed: %w", err)
|
||||
@@ -2804,10 +2645,7 @@ func (c *Client) GetVideoSourceConfigurationOptions(
|
||||
ctx context.Context,
|
||||
configurationToken, profileToken string,
|
||||
) (*VideoSourceConfigurationOptions, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetVideoSourceConfigurationOptions struct {
|
||||
XMLName xml.Name `xml:"trt:GetVideoSourceConfigurationOptions"`
|
||||
@@ -2867,10 +2705,7 @@ func (c *Client) GetAudioSourceConfigurationOptions(
|
||||
ctx context.Context,
|
||||
configurationToken, profileToken string,
|
||||
) (*AudioSourceConfigurationOptions, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetAudioSourceConfigurationOptions struct {
|
||||
XMLName xml.Name `xml:"trt:GetAudioSourceConfigurationOptions"`
|
||||
@@ -2916,10 +2751,7 @@ func (c *Client) SetVideoSourceConfiguration(
|
||||
config *VideoSourceConfiguration,
|
||||
forcePersistence bool,
|
||||
) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type SetVideoSourceConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:SetVideoSourceConfiguration"`
|
||||
@@ -2977,10 +2809,7 @@ func (c *Client) SetVideoSourceConfiguration(
|
||||
|
||||
// SetAudioSourceConfiguration sets audio source configuration.
|
||||
func (c *Client) SetAudioSourceConfiguration(ctx context.Context, config *AudioSourceConfiguration, forcePersistence bool) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type SetAudioSourceConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:SetAudioSourceConfiguration"`
|
||||
@@ -3021,10 +2850,7 @@ func (c *Client) GetCompatibleVideoEncoderConfigurations(
|
||||
ctx context.Context,
|
||||
profileToken string,
|
||||
) ([]*VideoEncoderConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetCompatibleVideoEncoderConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetCompatibleVideoEncoderConfigurations"`
|
||||
@@ -3102,10 +2928,7 @@ func (c *Client) GetCompatibleVideoSourceConfigurations(
|
||||
ctx context.Context,
|
||||
profileToken string,
|
||||
) ([]*VideoSourceConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetCompatibleVideoSourceConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetCompatibleVideoSourceConfigurations"`
|
||||
@@ -3170,10 +2993,7 @@ func (c *Client) GetCompatibleAudioEncoderConfigurations(
|
||||
ctx context.Context,
|
||||
profileToken string,
|
||||
) ([]*AudioEncoderConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetCompatibleAudioEncoderConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetCompatibleAudioEncoderConfigurations"`
|
||||
@@ -3224,10 +3044,7 @@ func (c *Client) GetCompatibleAudioEncoderConfigurations(
|
||||
|
||||
// GetCompatibleAudioSourceConfigurations retrieves compatible audio source configurations for a profile.
|
||||
func (c *Client) GetCompatibleAudioSourceConfigurations(ctx context.Context, profileToken string) ([]*AudioSourceConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetCompatibleAudioSourceConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetCompatibleAudioSourceConfigurations"`
|
||||
@@ -3274,10 +3091,7 @@ func (c *Client) GetCompatibleAudioSourceConfigurations(ctx context.Context, pro
|
||||
|
||||
// GetCompatiblePTZConfigurations retrieves compatible PTZ configurations for a profile.
|
||||
func (c *Client) GetCompatiblePTZConfigurations(ctx context.Context, profileToken string) ([]*PTZConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetCompatiblePTZConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetCompatiblePTZConfigurations"`
|
||||
@@ -3324,10 +3138,7 @@ func (c *Client) GetCompatiblePTZConfigurations(ctx context.Context, profileToke
|
||||
|
||||
// GetCompatibleMetadataConfigurations retrieves compatible metadata configurations for a profile.
|
||||
func (c *Client) GetCompatibleMetadataConfigurations(ctx context.Context, profileToken string) ([]*MetadataConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetCompatibleMetadataConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetCompatibleMetadataConfigurations"`
|
||||
@@ -3374,10 +3185,7 @@ func (c *Client) GetCompatibleMetadataConfigurations(ctx context.Context, profil
|
||||
|
||||
// GetCompatibleAudioOutputConfigurations retrieves compatible audio output configurations for a profile.
|
||||
func (c *Client) GetCompatibleAudioOutputConfigurations(ctx context.Context, profileToken string) ([]*AudioOutputConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetCompatibleAudioOutputConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetCompatibleAudioOutputConfigurations"`
|
||||
@@ -3424,10 +3232,7 @@ func (c *Client) GetCompatibleAudioOutputConfigurations(ctx context.Context, pro
|
||||
|
||||
// GetCompatibleAudioDecoderConfigurations retrieves compatible audio decoder configurations for a profile.
|
||||
func (c *Client) GetCompatibleAudioDecoderConfigurations(ctx context.Context, profileToken string) ([]*AudioDecoderConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetCompatibleAudioDecoderConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetCompatibleAudioDecoderConfigurations"`
|
||||
@@ -3472,10 +3277,7 @@ func (c *Client) GetCompatibleAudioDecoderConfigurations(ctx context.Context, pr
|
||||
|
||||
// GetMetadataConfigurations retrieves all metadata configurations.
|
||||
func (c *Client) GetMetadataConfigurations(ctx context.Context) ([]*MetadataConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetMetadataConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetMetadataConfigurations"`
|
||||
@@ -3520,10 +3322,7 @@ func (c *Client) GetMetadataConfigurations(ctx context.Context) ([]*MetadataConf
|
||||
|
||||
// GetAudioOutputConfigurations retrieves all audio output configurations.
|
||||
func (c *Client) GetAudioOutputConfigurations(ctx context.Context) ([]*AudioOutputConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetAudioOutputConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetAudioOutputConfigurations"`
|
||||
@@ -3568,10 +3367,7 @@ func (c *Client) GetAudioOutputConfigurations(ctx context.Context) ([]*AudioOutp
|
||||
|
||||
// GetAudioDecoderConfigurations retrieves all audio decoder configurations.
|
||||
func (c *Client) GetAudioDecoderConfigurations(ctx context.Context) ([]*AudioDecoderConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetAudioDecoderConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetAudioDecoderConfigurations"`
|
||||
@@ -3617,10 +3413,7 @@ func (c *Client) GetAudioDecoderConfiguration(
|
||||
ctx context.Context,
|
||||
configurationToken string,
|
||||
) (*AudioDecoderConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetAudioDecoderConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:GetAudioDecoderConfiguration"`
|
||||
@@ -3660,10 +3453,7 @@ func (c *Client) GetAudioDecoderConfiguration(
|
||||
|
||||
// SetAudioDecoderConfiguration sets audio decoder configuration.
|
||||
func (c *Client) SetAudioDecoderConfiguration(ctx context.Context, config *AudioDecoderConfiguration, forcePersistence bool) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type SetAudioDecoderConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:SetAudioDecoderConfiguration"`
|
||||
@@ -3699,10 +3489,7 @@ func (c *Client) SetAudioDecoderConfiguration(ctx context.Context, config *Audio
|
||||
|
||||
// GetVideoAnalyticsConfigurations retrieves all video analytics configurations.
|
||||
func (c *Client) GetVideoAnalyticsConfigurations(ctx context.Context) ([]*VideoAnalyticsConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetVideoAnalyticsConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetVideoAnalyticsConfigurations"`
|
||||
@@ -3748,10 +3535,7 @@ func (c *Client) GetVideoAnalyticsConfiguration(
|
||||
ctx context.Context,
|
||||
configurationToken string,
|
||||
) (*VideoAnalyticsConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetVideoAnalyticsConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:GetVideoAnalyticsConfiguration"`
|
||||
@@ -3791,10 +3575,7 @@ func (c *Client) GetVideoAnalyticsConfiguration(
|
||||
|
||||
// GetCompatibleVideoAnalyticsConfigurations retrieves compatible video analytics configurations for a profile.
|
||||
func (c *Client) GetCompatibleVideoAnalyticsConfigurations(ctx context.Context, profileToken string) ([]*VideoAnalyticsConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetCompatibleVideoAnalyticsConfigurations struct {
|
||||
XMLName xml.Name `xml:"trt:GetCompatibleVideoAnalyticsConfigurations"`
|
||||
@@ -3839,10 +3620,7 @@ func (c *Client) GetCompatibleVideoAnalyticsConfigurations(ctx context.Context,
|
||||
|
||||
// SetVideoAnalyticsConfiguration sets video analytics configuration.
|
||||
func (c *Client) SetVideoAnalyticsConfiguration(ctx context.Context, config *VideoAnalyticsConfiguration, forcePersistence bool) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type SetVideoAnalyticsConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:SetVideoAnalyticsConfiguration"`
|
||||
@@ -3881,10 +3659,7 @@ func (c *Client) GetVideoAnalyticsConfigurationOptions(
|
||||
ctx context.Context,
|
||||
configurationToken, profileToken string,
|
||||
) (*VideoAnalyticsConfigurationOptions, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetVideoAnalyticsConfigurationOptions struct {
|
||||
XMLName xml.Name `xml:"trt:GetVideoAnalyticsConfigurationOptions"`
|
||||
@@ -3922,10 +3697,7 @@ func (c *Client) GetVideoAnalyticsConfigurationOptions(
|
||||
|
||||
// AddVideoAnalyticsConfiguration adds a video analytics configuration to a profile.
|
||||
func (c *Client) AddVideoAnalyticsConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type AddVideoAnalyticsConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:AddVideoAnalyticsConfiguration"`
|
||||
@@ -3952,10 +3724,7 @@ func (c *Client) AddVideoAnalyticsConfiguration(ctx context.Context, profileToke
|
||||
|
||||
// RemoveVideoAnalyticsConfiguration removes a video analytics configuration from a profile.
|
||||
func (c *Client) RemoveVideoAnalyticsConfiguration(ctx context.Context, profileToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type RemoveVideoAnalyticsConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:RemoveVideoAnalyticsConfiguration"`
|
||||
@@ -3980,10 +3749,7 @@ func (c *Client) RemoveVideoAnalyticsConfiguration(ctx context.Context, profileT
|
||||
|
||||
// AddAudioOutputConfiguration adds an audio output configuration to a profile.
|
||||
func (c *Client) AddAudioOutputConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type AddAudioOutputConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:AddAudioOutputConfiguration"`
|
||||
@@ -4010,10 +3776,7 @@ func (c *Client) AddAudioOutputConfiguration(ctx context.Context, profileToken,
|
||||
|
||||
// RemoveAudioOutputConfiguration removes an audio output configuration from a profile.
|
||||
func (c *Client) RemoveAudioOutputConfiguration(ctx context.Context, profileToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type RemoveAudioOutputConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:RemoveAudioOutputConfiguration"`
|
||||
@@ -4038,10 +3801,7 @@ func (c *Client) RemoveAudioOutputConfiguration(ctx context.Context, profileToke
|
||||
|
||||
// AddAudioDecoderConfiguration adds an audio decoder configuration to a profile.
|
||||
func (c *Client) AddAudioDecoderConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type AddAudioDecoderConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:AddAudioDecoderConfiguration"`
|
||||
@@ -4068,10 +3828,7 @@ func (c *Client) AddAudioDecoderConfiguration(ctx context.Context, profileToken,
|
||||
|
||||
// RemoveAudioDecoderConfiguration removes an audio decoder configuration from a profile.
|
||||
func (c *Client) RemoveAudioDecoderConfiguration(ctx context.Context, profileToken string) error {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type RemoveAudioDecoderConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:RemoveAudioDecoderConfiguration"`
|
||||
|
||||
@@ -11,6 +11,61 @@ import (
|
||||
// PTZ service namespace.
|
||||
const ptzNamespace = "http://www.onvif.org/ver20/ptz/wsdl"
|
||||
|
||||
// ptzPanTiltXML is a shared type for PTZ pan/tilt XML serialization.
|
||||
type ptzPanTiltXML struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}
|
||||
|
||||
// ptzZoomXML is a shared type for PTZ zoom XML serialization.
|
||||
type ptzZoomXML struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}
|
||||
|
||||
// ptzVectorXML is a shared type for PTZ position/velocity XML serialization.
|
||||
type ptzVectorXML struct {
|
||||
PanTilt *ptzPanTiltXML `xml:"PanTilt,omitempty"`
|
||||
Zoom *ptzZoomXML `xml:"Zoom,omitempty"`
|
||||
}
|
||||
|
||||
// ptzSpeedXML is a shared type for PTZ speed XML serialization.
|
||||
type ptzSpeedXML struct {
|
||||
PanTilt *ptzPanTiltXML `xml:"PanTilt,omitempty"`
|
||||
Zoom *ptzZoomXML `xml:"Zoom,omitempty"`
|
||||
}
|
||||
|
||||
// convertToPTZVectorXML converts PTZVector to XML struct.
|
||||
func convertToPTZVectorXML(v *PTZVector) *ptzVectorXML {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
result := &ptzVectorXML{}
|
||||
if v.PanTilt != nil {
|
||||
result.PanTilt = &ptzPanTiltXML{X: v.PanTilt.X, Y: v.PanTilt.Y, Space: v.PanTilt.Space}
|
||||
}
|
||||
if v.Zoom != nil {
|
||||
result.Zoom = &ptzZoomXML{X: v.Zoom.X, Space: v.Zoom.Space}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// convertToPTZSpeedXML converts PTZSpeed to XML struct.
|
||||
func convertToPTZSpeedXML(s *PTZSpeed) *ptzSpeedXML {
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
result := &ptzSpeedXML{}
|
||||
if s.PanTilt != nil {
|
||||
result.PanTilt = &ptzPanTiltXML{X: s.PanTilt.X, Y: s.PanTilt.Y, Space: s.PanTilt.Space}
|
||||
}
|
||||
if s.Zoom != nil {
|
||||
result.Zoom = &ptzZoomXML{X: s.Zoom.X, Space: s.Zoom.Space}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// ContinuousMove starts continuous PTZ movement.
|
||||
func (c *Client) ContinuousMove(ctx context.Context, profileToken string, velocity *PTZSpeed, timeout *string) error {
|
||||
endpoint := c.ptzEndpoint
|
||||
@@ -19,65 +74,20 @@ func (c *Client) ContinuousMove(ctx context.Context, profileToken string, veloci
|
||||
}
|
||||
|
||||
type ContinuousMove struct {
|
||||
XMLName xml.Name `xml:"tptz:ContinuousMove"`
|
||||
Xmlns string `xml:"xmlns:tptz,attr"`
|
||||
ProfileToken string `xml:"tptz:ProfileToken"`
|
||||
Velocity *struct {
|
||||
PanTilt *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"PanTilt,omitempty"`
|
||||
Zoom *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"Zoom,omitempty"`
|
||||
} `xml:"tptz:Velocity"`
|
||||
Timeout *string `xml:"tptz:Timeout,omitempty"`
|
||||
XMLName xml.Name `xml:"tptz:ContinuousMove"`
|
||||
Xmlns string `xml:"xmlns:tptz,attr"`
|
||||
ProfileToken string `xml:"tptz:ProfileToken"`
|
||||
Velocity *ptzSpeedXML `xml:"tptz:Velocity"`
|
||||
Timeout *string `xml:"tptz:Timeout,omitempty"`
|
||||
}
|
||||
|
||||
req := ContinuousMove{
|
||||
Xmlns: ptzNamespace,
|
||||
ProfileToken: profileToken,
|
||||
Velocity: convertToPTZSpeedXML(velocity),
|
||||
Timeout: timeout,
|
||||
}
|
||||
|
||||
if velocity != nil {
|
||||
req.Velocity = &struct {
|
||||
PanTilt *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"PanTilt,omitempty"`
|
||||
Zoom *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"Zoom,omitempty"`
|
||||
}{}
|
||||
|
||||
if velocity.PanTilt != nil {
|
||||
req.Velocity.PanTilt = &struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}{
|
||||
X: velocity.PanTilt.X,
|
||||
Y: velocity.PanTilt.Y,
|
||||
Space: velocity.PanTilt.Space,
|
||||
}
|
||||
}
|
||||
|
||||
if velocity.Zoom != nil {
|
||||
req.Velocity.Zoom = &struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}{
|
||||
X: velocity.Zoom.X,
|
||||
Space: velocity.Zoom.Space,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
@@ -96,108 +106,18 @@ func (c *Client) AbsoluteMove(ctx context.Context, profileToken string, position
|
||||
}
|
||||
|
||||
type AbsoluteMove struct {
|
||||
XMLName xml.Name `xml:"tptz:AbsoluteMove"`
|
||||
Xmlns string `xml:"xmlns:tptz,attr"`
|
||||
ProfileToken string `xml:"tptz:ProfileToken"`
|
||||
Position *struct {
|
||||
PanTilt *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"PanTilt,omitempty"`
|
||||
Zoom *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"Zoom,omitempty"`
|
||||
} `xml:"tptz:Position"`
|
||||
Speed *struct {
|
||||
PanTilt *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"PanTilt,omitempty"`
|
||||
Zoom *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"Zoom,omitempty"`
|
||||
} `xml:"tptz:Speed,omitempty"`
|
||||
XMLName xml.Name `xml:"tptz:AbsoluteMove"`
|
||||
Xmlns string `xml:"xmlns:tptz,attr"`
|
||||
ProfileToken string `xml:"tptz:ProfileToken"`
|
||||
Position *ptzVectorXML `xml:"tptz:Position"`
|
||||
Speed *ptzSpeedXML `xml:"tptz:Speed,omitempty"`
|
||||
}
|
||||
|
||||
req := AbsoluteMove{
|
||||
Xmlns: ptzNamespace,
|
||||
ProfileToken: profileToken,
|
||||
}
|
||||
|
||||
if position != nil {
|
||||
req.Position = &struct {
|
||||
PanTilt *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"PanTilt,omitempty"`
|
||||
Zoom *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"Zoom,omitempty"`
|
||||
}{}
|
||||
|
||||
if position.PanTilt != nil {
|
||||
req.Position.PanTilt = &struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}{
|
||||
X: position.PanTilt.X,
|
||||
Y: position.PanTilt.Y,
|
||||
Space: position.PanTilt.Space,
|
||||
}
|
||||
}
|
||||
|
||||
if position.Zoom != nil {
|
||||
req.Position.Zoom = &struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}{
|
||||
X: position.Zoom.X,
|
||||
Space: position.Zoom.Space,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if speed != nil {
|
||||
req.Speed = &struct {
|
||||
PanTilt *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"PanTilt,omitempty"`
|
||||
Zoom *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"Zoom,omitempty"`
|
||||
}{}
|
||||
|
||||
if speed.PanTilt != nil {
|
||||
req.Speed.PanTilt = &struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}{
|
||||
X: speed.PanTilt.X,
|
||||
Y: speed.PanTilt.Y,
|
||||
Space: speed.PanTilt.Space,
|
||||
}
|
||||
}
|
||||
|
||||
if speed.Zoom != nil {
|
||||
req.Speed.Zoom = &struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}{
|
||||
X: speed.Zoom.X,
|
||||
Space: speed.Zoom.Space,
|
||||
}
|
||||
}
|
||||
Position: convertToPTZVectorXML(position),
|
||||
Speed: convertToPTZSpeedXML(speed),
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
@@ -218,108 +138,18 @@ func (c *Client) RelativeMove(ctx context.Context, profileToken string, translat
|
||||
}
|
||||
|
||||
type RelativeMove struct {
|
||||
XMLName xml.Name `xml:"tptz:RelativeMove"`
|
||||
Xmlns string `xml:"xmlns:tptz,attr"`
|
||||
ProfileToken string `xml:"tptz:ProfileToken"`
|
||||
Translation *struct {
|
||||
PanTilt *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"PanTilt,omitempty"`
|
||||
Zoom *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"Zoom,omitempty"`
|
||||
} `xml:"tptz:Translation"`
|
||||
Speed *struct {
|
||||
PanTilt *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"PanTilt,omitempty"`
|
||||
Zoom *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"Zoom,omitempty"`
|
||||
} `xml:"tptz:Speed,omitempty"`
|
||||
XMLName xml.Name `xml:"tptz:RelativeMove"`
|
||||
Xmlns string `xml:"xmlns:tptz,attr"`
|
||||
ProfileToken string `xml:"tptz:ProfileToken"`
|
||||
Translation *ptzVectorXML `xml:"tptz:Translation"`
|
||||
Speed *ptzSpeedXML `xml:"tptz:Speed,omitempty"`
|
||||
}
|
||||
|
||||
req := RelativeMove{
|
||||
Xmlns: ptzNamespace,
|
||||
ProfileToken: profileToken,
|
||||
}
|
||||
|
||||
if translation != nil {
|
||||
req.Translation = &struct {
|
||||
PanTilt *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"PanTilt,omitempty"`
|
||||
Zoom *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"Zoom,omitempty"`
|
||||
}{}
|
||||
|
||||
if translation.PanTilt != nil {
|
||||
req.Translation.PanTilt = &struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}{
|
||||
X: translation.PanTilt.X,
|
||||
Y: translation.PanTilt.Y,
|
||||
Space: translation.PanTilt.Space,
|
||||
}
|
||||
}
|
||||
|
||||
if translation.Zoom != nil {
|
||||
req.Translation.Zoom = &struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}{
|
||||
X: translation.Zoom.X,
|
||||
Space: translation.Zoom.Space,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if speed != nil {
|
||||
req.Speed = &struct {
|
||||
PanTilt *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"PanTilt,omitempty"`
|
||||
Zoom *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"Zoom,omitempty"`
|
||||
}{}
|
||||
|
||||
if speed.PanTilt != nil {
|
||||
req.Speed.PanTilt = &struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}{
|
||||
X: speed.PanTilt.X,
|
||||
Y: speed.PanTilt.Y,
|
||||
Space: speed.PanTilt.Space,
|
||||
}
|
||||
}
|
||||
|
||||
if speed.Zoom != nil {
|
||||
req.Speed.Zoom = &struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}{
|
||||
X: speed.Zoom.X,
|
||||
Space: speed.Zoom.Space,
|
||||
}
|
||||
}
|
||||
Translation: convertToPTZVectorXML(translation),
|
||||
Speed: convertToPTZSpeedXML(speed),
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
@@ -534,63 +364,18 @@ func (c *Client) GotoPreset(ctx context.Context, profileToken, presetToken strin
|
||||
}
|
||||
|
||||
type GotoPreset struct {
|
||||
XMLName xml.Name `xml:"tptz:GotoPreset"`
|
||||
Xmlns string `xml:"xmlns:tptz,attr"`
|
||||
ProfileToken string `xml:"tptz:ProfileToken"`
|
||||
PresetToken string `xml:"tptz:PresetToken"`
|
||||
Speed *struct {
|
||||
PanTilt *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"PanTilt,omitempty"`
|
||||
Zoom *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"Zoom,omitempty"`
|
||||
} `xml:"tptz:Speed,omitempty"`
|
||||
XMLName xml.Name `xml:"tptz:GotoPreset"`
|
||||
Xmlns string `xml:"xmlns:tptz,attr"`
|
||||
ProfileToken string `xml:"tptz:ProfileToken"`
|
||||
PresetToken string `xml:"tptz:PresetToken"`
|
||||
Speed *ptzSpeedXML `xml:"tptz:Speed,omitempty"`
|
||||
}
|
||||
|
||||
req := GotoPreset{
|
||||
Xmlns: ptzNamespace,
|
||||
ProfileToken: profileToken,
|
||||
PresetToken: presetToken,
|
||||
}
|
||||
|
||||
if speed != nil {
|
||||
req.Speed = &struct {
|
||||
PanTilt *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"PanTilt,omitempty"`
|
||||
Zoom *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"Zoom,omitempty"`
|
||||
}{}
|
||||
|
||||
if speed.PanTilt != nil {
|
||||
req.Speed.PanTilt = &struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}{
|
||||
X: speed.PanTilt.X,
|
||||
Y: speed.PanTilt.Y,
|
||||
Space: speed.PanTilt.Space,
|
||||
}
|
||||
}
|
||||
|
||||
if speed.Zoom != nil {
|
||||
req.Speed.Zoom = &struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}{
|
||||
X: speed.Zoom.X,
|
||||
Space: speed.Zoom.Space,
|
||||
}
|
||||
}
|
||||
Speed: convertToPTZSpeedXML(speed),
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
@@ -685,61 +470,16 @@ func (c *Client) GotoHomePosition(ctx context.Context, profileToken string, spee
|
||||
}
|
||||
|
||||
type GotoHomePosition struct {
|
||||
XMLName xml.Name `xml:"tptz:GotoHomePosition"`
|
||||
Xmlns string `xml:"xmlns:tptz,attr"`
|
||||
ProfileToken string `xml:"tptz:ProfileToken"`
|
||||
Speed *struct {
|
||||
PanTilt *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"PanTilt,omitempty"`
|
||||
Zoom *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"Zoom,omitempty"`
|
||||
} `xml:"tptz:Speed,omitempty"`
|
||||
XMLName xml.Name `xml:"tptz:GotoHomePosition"`
|
||||
Xmlns string `xml:"xmlns:tptz,attr"`
|
||||
ProfileToken string `xml:"tptz:ProfileToken"`
|
||||
Speed *ptzSpeedXML `xml:"tptz:Speed,omitempty"`
|
||||
}
|
||||
|
||||
req := GotoHomePosition{
|
||||
Xmlns: ptzNamespace,
|
||||
ProfileToken: profileToken,
|
||||
}
|
||||
|
||||
if speed != nil {
|
||||
req.Speed = &struct {
|
||||
PanTilt *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"PanTilt,omitempty"`
|
||||
Zoom *struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
} `xml:"Zoom,omitempty"`
|
||||
}{}
|
||||
|
||||
if speed.PanTilt != nil {
|
||||
req.Speed.PanTilt = &struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}{
|
||||
X: speed.PanTilt.X,
|
||||
Y: speed.PanTilt.Y,
|
||||
Space: speed.PanTilt.Space,
|
||||
}
|
||||
}
|
||||
|
||||
if speed.Zoom != nil {
|
||||
req.Speed.Zoom = &struct {
|
||||
X float64 `xml:"x,attr"`
|
||||
Space string `xml:"space,attr,omitempty"`
|
||||
}{
|
||||
X: speed.Zoom.X,
|
||||
Space: speed.Zoom.Space,
|
||||
}
|
||||
}
|
||||
Speed: convertToPTZSpeedXML(speed),
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
|
||||
Reference in New Issue
Block a user