Files
onvif-go/device_additional.go
T
ProtoTess b4e4982876 Refactor XML response handling in device extended and security tests
- Adjusted formatting in XML response strings for consistency in device_extended_test.go and device_security_test.go.
- Improved readability by aligning XML declaration and body content.
- Updated mock server responses to ensure proper handling of various ONVIF operations.

Enhance device security and storage handling

- Refactored struct field declarations in device_security.go and device_storage_test.go for improved clarity.
- Ensured consistent formatting across struct definitions and XML tags.

Standardize whitespace and formatting across multiple files

- Removed unnecessary blank lines and adjusted indentation in discovery, imaging, media, and PTZ server files.
- Improved overall code readability and maintainability by ensuring consistent formatting.

Update example applications for better readability

- Cleaned up whitespace in example applications to enhance code clarity.
- Ensured consistent formatting in main.go files across various examples.

Refactor server and SOAP handler code for consistency

- Standardized struct field declarations and XML tag formatting in server and SOAP handler files.
- Improved readability by aligning struct fields and ensuring consistent use of whitespace.

General code cleanup and formatting adjustments

- Applied consistent formatting across various files, including types.go and test files.
- Enhanced readability by aligning struct fields and removing unnecessary blank lines.
2025-12-01 00:49:36 +00:00

253 lines
7.4 KiB
Go

package onvif
import (
"context"
"encoding/xml"
"fmt"
"github.com/0x524a/onvif-go/internal/soap"
)
// GetGeoLocation retrieves the current geographic location of the device.
// This includes latitude, longitude, and elevation if GPS is available.
//
// ONVIF Specification: GetGeoLocation operation
func (c *Client) GetGeoLocation(ctx context.Context) ([]LocationEntity, error) {
type GetGeoLocationBody struct {
XMLName xml.Name `xml:"tds:GetGeoLocation"`
Xmlns string `xml:"xmlns:tds,attr"`
}
type GetGeoLocationResponse struct {
XMLName xml.Name `xml:"GetGeoLocationResponse"`
Location []LocationEntity `xml:"Location"`
}
request := GetGeoLocationBody{
Xmlns: deviceNamespace,
}
var response GetGeoLocationResponse
username, password := c.GetCredentials()
soapClient := soap.NewClient(c.httpClient, username, password)
if err := soapClient.Call(ctx, c.endpoint, "", request, &response); err != nil {
return nil, fmt.Errorf("GetGeoLocation failed: %w", err)
}
return response.Location, nil
}
// SetGeoLocation sets the geographic location of the device.
// Latitude and longitude are in degrees, elevation is in meters.
//
// ONVIF Specification: SetGeoLocation operation
func (c *Client) SetGeoLocation(ctx context.Context, location []LocationEntity) error {
type SetGeoLocationBody struct {
XMLName xml.Name `xml:"tds:SetGeoLocation"`
Xmlns string `xml:"xmlns:tds,attr"`
Location []LocationEntity `xml:"tds:Location"`
}
type SetGeoLocationResponse struct {
XMLName xml.Name `xml:"SetGeoLocationResponse"`
}
request := SetGeoLocationBody{
Xmlns: deviceNamespace,
Location: location,
}
var response SetGeoLocationResponse
username, password := c.GetCredentials()
soapClient := soap.NewClient(c.httpClient, username, password)
if err := soapClient.Call(ctx, c.endpoint, "", request, &response); err != nil {
return fmt.Errorf("SetGeoLocation failed: %w", err)
}
return nil
}
// DeleteGeoLocation removes geographic location information from the device.
//
// ONVIF Specification: DeleteGeoLocation operation
func (c *Client) DeleteGeoLocation(ctx context.Context, location []LocationEntity) error {
type DeleteGeoLocationBody struct {
XMLName xml.Name `xml:"tds:DeleteGeoLocation"`
Xmlns string `xml:"xmlns:tds,attr"`
Location []LocationEntity `xml:"tds:Location"`
}
type DeleteGeoLocationResponse struct {
XMLName xml.Name `xml:"DeleteGeoLocationResponse"`
}
request := DeleteGeoLocationBody{
Xmlns: deviceNamespace,
Location: location,
}
var response DeleteGeoLocationResponse
username, password := c.GetCredentials()
soapClient := soap.NewClient(c.httpClient, username, password)
if err := soapClient.Call(ctx, c.endpoint, "", request, &response); err != nil {
return fmt.Errorf("DeleteGeoLocation failed: %w", err)
}
return nil
}
// GetDPAddresses retrieves the discovery protocol (DP) multicast addresses.
// These addresses are used for WS-Discovery.
//
// ONVIF Specification: GetDPAddresses operation
func (c *Client) GetDPAddresses(ctx context.Context) ([]NetworkHost, error) {
type GetDPAddressesBody struct {
XMLName xml.Name `xml:"tds:GetDPAddresses"`
Xmlns string `xml:"xmlns:tds,attr"`
}
type GetDPAddressesResponse struct {
XMLName xml.Name `xml:"GetDPAddressesResponse"`
DPAddress []NetworkHost `xml:"DPAddress"`
}
request := GetDPAddressesBody{
Xmlns: deviceNamespace,
}
var response GetDPAddressesResponse
username, password := c.GetCredentials()
soapClient := soap.NewClient(c.httpClient, username, password)
if err := soapClient.Call(ctx, c.endpoint, "", request, &response); err != nil {
return nil, fmt.Errorf("GetDPAddresses failed: %w", err)
}
return response.DPAddress, nil
}
// SetDPAddresses sets the discovery protocol (DP) multicast addresses.
// These addresses are used for WS-Discovery. Setting to empty list restores defaults.
//
// ONVIF Specification: SetDPAddresses operation
func (c *Client) SetDPAddresses(ctx context.Context, dpAddress []NetworkHost) error {
type SetDPAddressesBody struct {
XMLName xml.Name `xml:"tds:SetDPAddresses"`
Xmlns string `xml:"xmlns:tds,attr"`
DPAddress []NetworkHost `xml:"tds:DPAddress"`
}
type SetDPAddressesResponse struct {
XMLName xml.Name `xml:"SetDPAddressesResponse"`
}
request := SetDPAddressesBody{
Xmlns: deviceNamespace,
DPAddress: dpAddress,
}
var response SetDPAddressesResponse
username, password := c.GetCredentials()
soapClient := soap.NewClient(c.httpClient, username, password)
if err := soapClient.Call(ctx, c.endpoint, "", request, &response); err != nil {
return fmt.Errorf("SetDPAddresses failed: %w", err)
}
return nil
}
// GetAccessPolicy retrieves the device's access policy configuration.
// The access policy defines rules for accessing the device.
//
// ONVIF Specification: GetAccessPolicy operation
func (c *Client) GetAccessPolicy(ctx context.Context) (*AccessPolicy, error) {
type GetAccessPolicyBody struct {
XMLName xml.Name `xml:"tds:GetAccessPolicy"`
Xmlns string `xml:"xmlns:tds,attr"`
}
type GetAccessPolicyResponse struct {
XMLName xml.Name `xml:"GetAccessPolicyResponse"`
PolicyFile *BinaryData `xml:"PolicyFile"`
}
request := GetAccessPolicyBody{
Xmlns: deviceNamespace,
}
var response GetAccessPolicyResponse
username, password := c.GetCredentials()
soapClient := soap.NewClient(c.httpClient, username, password)
if err := soapClient.Call(ctx, c.endpoint, "", request, &response); err != nil {
return nil, fmt.Errorf("GetAccessPolicy failed: %w", err)
}
return &AccessPolicy{PolicyFile: response.PolicyFile}, nil
}
// SetAccessPolicy sets the device's access policy configuration.
// The policy defines rules for who can access the device and what operations they can perform.
//
// ONVIF Specification: SetAccessPolicy operation
func (c *Client) SetAccessPolicy(ctx context.Context, policy *AccessPolicy) error {
type SetAccessPolicyBody struct {
XMLName xml.Name `xml:"tds:SetAccessPolicy"`
Xmlns string `xml:"xmlns:tds,attr"`
PolicyFile *BinaryData `xml:"tds:PolicyFile"`
}
type SetAccessPolicyResponse struct {
XMLName xml.Name `xml:"SetAccessPolicyResponse"`
}
request := SetAccessPolicyBody{
Xmlns: deviceNamespace,
PolicyFile: policy.PolicyFile,
}
var response SetAccessPolicyResponse
username, password := c.GetCredentials()
soapClient := soap.NewClient(c.httpClient, username, password)
if err := soapClient.Call(ctx, c.endpoint, "", request, &response); err != nil {
return fmt.Errorf("SetAccessPolicy failed: %w", err)
}
return nil
}
// GetWsdlUrl retrieves the URL of the device's WSDL file.
// Note: This operation is deprecated in newer ONVIF specifications.
//
// ONVIF Specification: GetWsdlUrl operation (deprecated)
func (c *Client) GetWsdlUrl(ctx context.Context) (string, error) {
type GetWsdlUrlBody struct {
XMLName xml.Name `xml:"tds:GetWsdlUrl"`
Xmlns string `xml:"xmlns:tds,attr"`
}
type GetWsdlUrlResponse struct {
XMLName xml.Name `xml:"GetWsdlUrlResponse"`
WsdlUrl string `xml:"WsdlUrl"`
}
request := GetWsdlUrlBody{
Xmlns: deviceNamespace,
}
var response GetWsdlUrlResponse
username, password := c.GetCredentials()
soapClient := soap.NewClient(c.httpClient, username, password)
if err := soapClient.Call(ctx, c.endpoint, "", request, &response); err != nil {
return "", fmt.Errorf("GetWsdlUrl failed: %w", err)
}
return response.WsdlUrl, nil
}