19db372cdc
- Introduced comprehensive data structures for ONVIF device information, capabilities, media profiles, and configurations. - Added types for device services, network settings, imaging options, audio/video configurations, and user management. - Implemented structures for handling various ONVIF features including PTZ control, event subscriptions, and analytics configurations. - Enhanced support for network protocols, security settings, and system logging.
528 lines
18 KiB
Go
528 lines
18 KiB
Go
package onvif
|
|
|
|
import (
|
|
"context"
|
|
"encoding/xml"
|
|
"fmt"
|
|
|
|
"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(addr))
|
|
}
|
|
}
|
|
|
|
if len(filter.IPv6Address) > 0 {
|
|
req.IPv6Address = make([]prefixedIPv6AddressXML, 0, len(filter.IPv6Address))
|
|
for _, addr := range filter.IPv6Address {
|
|
req.IPv6Address = append(req.IPv6Address, prefixedIPv6AddressXML(addr))
|
|
}
|
|
}
|
|
|
|
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 getRemoteUserRequest struct {
|
|
XMLName xml.Name `xml:"tds:GetRemoteUser"`
|
|
Xmlns string `xml:"xmlns:tds,attr"`
|
|
}
|
|
|
|
type getRemoteUserResponse struct {
|
|
XMLName xml.Name `xml:"GetRemoteUserResponse"`
|
|
RemoteUser *struct {
|
|
Username string `xml:"Username"`
|
|
Password string `xml:"Password"`
|
|
UseDerivedPassword bool `xml:"UseDerivedPassword"`
|
|
} `xml:"RemoteUser"`
|
|
}
|
|
|
|
req := getRemoteUserRequest{
|
|
Xmlns: deviceNamespace,
|
|
}
|
|
|
|
var resp getRemoteUserResponse
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetRemoteUser failed: %w", err)
|
|
}
|
|
|
|
if resp.RemoteUser == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
return &RemoteUser{
|
|
Username: resp.RemoteUser.Username,
|
|
Password: resp.RemoteUser.Password,
|
|
UseDerivedPassword: resp.RemoteUser.UseDerivedPassword,
|
|
}, nil
|
|
}
|
|
|
|
// SetRemoteUser sets the remote user.
|
|
func (c *Client) SetRemoteUser(ctx context.Context, remoteUser *RemoteUser) error {
|
|
type remoteUserXML struct {
|
|
Username string `xml:"tds:Username"`
|
|
Password string `xml:"tds:Password,omitempty"`
|
|
UseDerivedPassword bool `xml:"tds:UseDerivedPassword"`
|
|
}
|
|
|
|
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 = &remoteUserXML{
|
|
Username: remoteUser.Username,
|
|
Password: remoteUser.Password,
|
|
UseDerivedPassword: remoteUser.UseDerivedPassword,
|
|
}
|
|
}
|
|
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetRemoteUser failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetIPAddressFilter gets the IP address filter settings from a device.
|
|
func (c *Client) GetIPAddressFilter(ctx context.Context) (*IPAddressFilter, error) {
|
|
type getIPAddressFilterRequest struct {
|
|
XMLName xml.Name `xml:"tds:GetIPAddressFilter"`
|
|
Xmlns string `xml:"xmlns:tds,attr"`
|
|
}
|
|
|
|
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 []prefixedAddressXML `xml:"IPv4Address"`
|
|
IPv6Address []prefixedAddressXML `xml:"IPv6Address"`
|
|
} `xml:"IPAddressFilter"`
|
|
}
|
|
|
|
req := getIPAddressFilterRequest{
|
|
Xmlns: deviceNamespace,
|
|
}
|
|
|
|
var resp getIPAddressFilterResponse
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetIPAddressFilter failed: %w", err)
|
|
}
|
|
|
|
filter := &IPAddressFilter{
|
|
Type: IPAddressFilterType(resp.IPAddressFilter.Type),
|
|
}
|
|
|
|
// 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(addr))
|
|
}
|
|
}
|
|
|
|
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(addr))
|
|
}
|
|
}
|
|
|
|
return filter, nil
|
|
}
|
|
|
|
// SetIPAddressFilter sets the IP address filter settings on a device.
|
|
func (c *Client) SetIPAddressFilter(ctx context.Context, filter *IPAddressFilter) error {
|
|
type setIPAddressFilterRequest struct {
|
|
XMLName xml.Name `xml:"tds:SetIPAddressFilter"`
|
|
Xmlns string `xml:"xmlns:tds,attr"`
|
|
IPAddressFilter ipAddressFilterRequest `xml:"tds:IPAddressFilter"`
|
|
}
|
|
|
|
req := setIPAddressFilterRequest{
|
|
Xmlns: deviceNamespace,
|
|
IPAddressFilter: buildIPAddressFilterRequest(filter),
|
|
}
|
|
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetIPAddressFilter failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AddIPAddressFilter adds an IP filter address to a device.
|
|
func (c *Client) AddIPAddressFilter(ctx context.Context, filter *IPAddressFilter) error {
|
|
type addIPAddressFilterRequest struct {
|
|
XMLName xml.Name `xml:"tds:AddIPAddressFilter"`
|
|
Xmlns string `xml:"xmlns:tds,attr"`
|
|
IPAddressFilter ipAddressFilterRequest `xml:"tds:IPAddressFilter"`
|
|
}
|
|
|
|
req := addIPAddressFilterRequest{
|
|
Xmlns: deviceNamespace,
|
|
IPAddressFilter: buildIPAddressFilterRequest(filter),
|
|
}
|
|
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("AddIPAddressFilter failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RemoveIPAddressFilter deletes an IP filter address from a device.
|
|
func (c *Client) RemoveIPAddressFilter(ctx context.Context, filter *IPAddressFilter) error {
|
|
type removeIPAddressFilterRequest struct {
|
|
XMLName xml.Name `xml:"tds:RemoveIPAddressFilter"`
|
|
Xmlns string `xml:"xmlns:tds,attr"`
|
|
IPAddressFilter ipAddressFilterRequest `xml:"tds:IPAddressFilter"`
|
|
}
|
|
|
|
req := removeIPAddressFilterRequest{
|
|
Xmlns: deviceNamespace,
|
|
IPAddressFilter: buildIPAddressFilterRequest(filter),
|
|
}
|
|
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("RemoveIPAddressFilter failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetZeroConfiguration gets the zero-configuration from a device.
|
|
func (c *Client) GetZeroConfiguration(ctx context.Context) (*NetworkZeroConfiguration, error) {
|
|
type getZeroConfigurationRequest struct {
|
|
XMLName xml.Name `xml:"tds:GetZeroConfiguration"`
|
|
Xmlns string `xml:"xmlns:tds,attr"`
|
|
}
|
|
|
|
type getZeroConfigurationResponse struct {
|
|
XMLName xml.Name `xml:"GetZeroConfigurationResponse"`
|
|
ZeroConfiguration struct {
|
|
InterfaceToken string `xml:"InterfaceToken"`
|
|
Enabled bool `xml:"Enabled"`
|
|
Addresses []string `xml:"Addresses"`
|
|
} `xml:"ZeroConfiguration"`
|
|
}
|
|
|
|
req := getZeroConfigurationRequest{
|
|
Xmlns: deviceNamespace,
|
|
}
|
|
|
|
var resp getZeroConfigurationResponse
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetZeroConfiguration failed: %w", err)
|
|
}
|
|
|
|
return &NetworkZeroConfiguration{
|
|
InterfaceToken: resp.ZeroConfiguration.InterfaceToken,
|
|
Enabled: resp.ZeroConfiguration.Enabled,
|
|
Addresses: resp.ZeroConfiguration.Addresses,
|
|
}, nil
|
|
}
|
|
|
|
// SetZeroConfiguration sets the zero-configuration.
|
|
func (c *Client) SetZeroConfiguration(ctx context.Context, interfaceToken string, enabled bool) error {
|
|
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 := setZeroConfigurationRequest{
|
|
Xmlns: deviceNamespace,
|
|
InterfaceToken: interfaceToken,
|
|
Enabled: enabled,
|
|
}
|
|
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetZeroConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetDynamicDNS gets the dynamic DNS settings from a device.
|
|
func (c *Client) GetDynamicDNS(ctx context.Context) (*DynamicDNSInformation, error) {
|
|
type getDynamicDNSRequest struct {
|
|
XMLName xml.Name `xml:"tds:GetDynamicDNS"`
|
|
Xmlns string `xml:"xmlns:tds,attr"`
|
|
}
|
|
|
|
type getDynamicDNSResponse struct {
|
|
XMLName xml.Name `xml:"GetDynamicDNSResponse"`
|
|
DynamicDNSInformation struct {
|
|
Type string `xml:"Type"`
|
|
Name string `xml:"Name"`
|
|
TTL string `xml:"TTL"`
|
|
} `xml:"DynamicDNSInformation"`
|
|
}
|
|
|
|
req := getDynamicDNSRequest{
|
|
Xmlns: deviceNamespace,
|
|
}
|
|
|
|
var resp getDynamicDNSResponse
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetDynamicDNS failed: %w", err)
|
|
}
|
|
|
|
return &DynamicDNSInformation{
|
|
Type: DynamicDNSType(resp.DynamicDNSInformation.Type),
|
|
Name: resp.DynamicDNSInformation.Name,
|
|
// TTL would need duration parsing
|
|
}, nil
|
|
}
|
|
|
|
// SetDynamicDNS sets the dynamic DNS settings on a device.
|
|
func (c *Client) SetDynamicDNS(ctx context.Context, dnsType DynamicDNSType, name string) error {
|
|
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 := setDynamicDNSRequest{
|
|
Xmlns: deviceNamespace,
|
|
Type: dnsType,
|
|
Name: name,
|
|
}
|
|
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetDynamicDNS failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetPasswordComplexityConfiguration retrieves the current password complexity configuration settings.
|
|
func (c *Client) GetPasswordComplexityConfiguration(ctx context.Context) (*PasswordComplexityConfiguration, error) {
|
|
type getPasswordComplexityConfigurationRequest struct {
|
|
XMLName xml.Name `xml:"tds:GetPasswordComplexityConfiguration"`
|
|
Xmlns string `xml:"xmlns:tds,attr"`
|
|
}
|
|
|
|
type getPasswordComplexityConfigurationResponse struct {
|
|
XMLName xml.Name `xml:"GetPasswordComplexityConfigurationResponse"`
|
|
MinLen int `xml:"MinLen"`
|
|
Uppercase int `xml:"Uppercase"`
|
|
Number int `xml:"Number"`
|
|
SpecialChars int `xml:"SpecialChars"`
|
|
BlockUsernameOccurrence bool `xml:"BlockUsernameOccurrence"`
|
|
PolicyConfigurationLocked bool `xml:"PolicyConfigurationLocked"`
|
|
}
|
|
|
|
req := getPasswordComplexityConfigurationRequest{
|
|
Xmlns: deviceNamespace,
|
|
}
|
|
|
|
var resp getPasswordComplexityConfigurationResponse
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetPasswordComplexityConfiguration failed: %w", err)
|
|
}
|
|
|
|
return &PasswordComplexityConfiguration{
|
|
MinLen: resp.MinLen,
|
|
Uppercase: resp.Uppercase,
|
|
Number: resp.Number,
|
|
SpecialChars: resp.SpecialChars,
|
|
BlockUsernameOccurrence: resp.BlockUsernameOccurrence,
|
|
PolicyConfigurationLocked: resp.PolicyConfigurationLocked,
|
|
}, nil
|
|
}
|
|
|
|
// SetPasswordComplexityConfiguration allows setting of the password complexity configuration.
|
|
func (c *Client) SetPasswordComplexityConfiguration(
|
|
ctx context.Context,
|
|
config *PasswordComplexityConfiguration,
|
|
) error {
|
|
type setPasswordComplexityConfigurationRequest struct {
|
|
XMLName xml.Name `xml:"tds:SetPasswordComplexityConfiguration"`
|
|
Xmlns string `xml:"xmlns:tds,attr"`
|
|
MinLen int `xml:"tds:MinLen,omitempty"`
|
|
Uppercase int `xml:"tds:Uppercase,omitempty"`
|
|
Number int `xml:"tds:Number,omitempty"`
|
|
SpecialChars int `xml:"tds:SpecialChars,omitempty"`
|
|
BlockUsernameOccurrence bool `xml:"tds:BlockUsernameOccurrence,omitempty"`
|
|
PolicyConfigurationLocked bool `xml:"tds:PolicyConfigurationLocked,omitempty"`
|
|
}
|
|
|
|
req := setPasswordComplexityConfigurationRequest{
|
|
Xmlns: deviceNamespace,
|
|
MinLen: config.MinLen,
|
|
Uppercase: config.Uppercase,
|
|
Number: config.Number,
|
|
SpecialChars: config.SpecialChars,
|
|
BlockUsernameOccurrence: config.BlockUsernameOccurrence,
|
|
PolicyConfigurationLocked: config.PolicyConfigurationLocked,
|
|
}
|
|
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetPasswordComplexityConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetPasswordHistoryConfiguration retrieves the current password history configuration settings.
|
|
func (c *Client) GetPasswordHistoryConfiguration(ctx context.Context) (*PasswordHistoryConfiguration, error) {
|
|
type getPasswordHistoryConfigurationRequest struct {
|
|
XMLName xml.Name `xml:"tds:GetPasswordHistoryConfiguration"`
|
|
Xmlns string `xml:"xmlns:tds,attr"`
|
|
}
|
|
|
|
type getPasswordHistoryConfigurationResponse struct {
|
|
XMLName xml.Name `xml:"GetPasswordHistoryConfigurationResponse"`
|
|
Enabled bool `xml:"Enabled"`
|
|
Length int `xml:"Length"`
|
|
}
|
|
|
|
req := getPasswordHistoryConfigurationRequest{
|
|
Xmlns: deviceNamespace,
|
|
}
|
|
|
|
var resp getPasswordHistoryConfigurationResponse
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetPasswordHistoryConfiguration failed: %w", err)
|
|
}
|
|
|
|
return &PasswordHistoryConfiguration{
|
|
Enabled: resp.Enabled,
|
|
Length: resp.Length,
|
|
}, nil
|
|
}
|
|
|
|
// SetPasswordHistoryConfiguration allows setting of the password history configuration.
|
|
func (c *Client) SetPasswordHistoryConfiguration(ctx context.Context, config *PasswordHistoryConfiguration) error {
|
|
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 := setPasswordHistoryConfigurationRequest{
|
|
Xmlns: deviceNamespace,
|
|
Enabled: config.Enabled,
|
|
Length: config.Length,
|
|
}
|
|
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetPasswordHistoryConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetAuthFailureWarningConfiguration retrieves the current authentication failure warning configuration.
|
|
func (c *Client) GetAuthFailureWarningConfiguration(ctx context.Context) (*AuthFailureWarningConfiguration, error) {
|
|
type getAuthFailureWarningConfigurationRequest struct {
|
|
XMLName xml.Name `xml:"tds:GetAuthFailureWarningConfiguration"`
|
|
Xmlns string `xml:"xmlns:tds,attr"`
|
|
}
|
|
|
|
type getAuthFailureWarningConfigurationResponse struct {
|
|
XMLName xml.Name `xml:"GetAuthFailureWarningConfigurationResponse"`
|
|
Enabled bool `xml:"Enabled"`
|
|
MonitorPeriod int `xml:"MonitorPeriod"`
|
|
MaxAuthFailures int `xml:"MaxAuthFailures"`
|
|
}
|
|
|
|
req := getAuthFailureWarningConfigurationRequest{
|
|
Xmlns: deviceNamespace,
|
|
}
|
|
|
|
var resp getAuthFailureWarningConfigurationResponse
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetAuthFailureWarningConfiguration failed: %w", err)
|
|
}
|
|
|
|
return &AuthFailureWarningConfiguration{
|
|
Enabled: resp.Enabled,
|
|
MonitorPeriod: resp.MonitorPeriod,
|
|
MaxAuthFailures: resp.MaxAuthFailures,
|
|
}, nil
|
|
}
|
|
|
|
// SetAuthFailureWarningConfiguration allows setting of the authentication failure warning configuration.
|
|
func (c *Client) SetAuthFailureWarningConfiguration(
|
|
ctx context.Context,
|
|
config *AuthFailureWarningConfiguration,
|
|
) error {
|
|
type setAuthFailureWarningConfigurationRequest struct {
|
|
XMLName xml.Name `xml:"tds:SetAuthFailureWarningConfiguration"`
|
|
Xmlns string `xml:"xmlns:tds,attr"`
|
|
Enabled bool `xml:"tds:Enabled"`
|
|
MonitorPeriod int `xml:"tds:MonitorPeriod"`
|
|
MaxAuthFailures int `xml:"tds:MaxAuthFailures"`
|
|
}
|
|
|
|
req := setAuthFailureWarningConfigurationRequest{
|
|
Xmlns: deviceNamespace,
|
|
Enabled: config.Enabled,
|
|
MonitorPeriod: config.MonitorPeriod,
|
|
MaxAuthFailures: config.MaxAuthFailures,
|
|
}
|
|
|
|
if err := c.newSOAPClient().Call(ctx, c.endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetAuthFailureWarningConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|