├── .gitignore
├── go.mod
├── README.md
├── go.sum
├── examples
├── discovery
│ └── discovery.go
└── recording
│ └── recording.go
├── discovery
└── discovery.go
├── wsdl
├── uplink.wsdl
├── replay.wsdl
├── bin
│ └── fixgen.py
├── common.xsd
├── receiver.wsdl
├── display.wsdl
├── provisioning.wsdl
└── imaging.wsdl
├── soap
└── soap.go
├── LICENSE
└── profiles
└── accessrules
└── accessrules.go
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pcap
2 | ptz_onvif
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/videonext/onvif
2 |
3 | go 1.24.0
4 |
5 | toolchain go1.24.4
6 |
7 | require (
8 | github.com/clbanning/mxj v1.8.4
9 | github.com/kr/pretty v0.1.0
10 | github.com/satori/go.uuid v1.2.0
11 | )
12 |
13 | require (
14 | github.com/kr/text v0.1.0 // indirect
15 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
16 | )
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Golang ONVIF client
2 | Goal is create full featured golang client using ONVIF specifications. Project is in alpha stage. All profiles defined in the [https://www.onvif.org/profiles/specifications/](https://www.onvif.org/profiles/specifications/) implemented, but was not carefully tested. See examples directory for usage details.
3 |
4 | ## Credits
5 | - [https://github.com/hooklift/gowsdl](https://github.com/hooklift/gowsdl)
6 | - [https://github.com/RadhiFadlillah/go-onvif/](https://github.com/RadhiFadlillah/go-onvif/)
7 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I=
2 | github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
3 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
4 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
5 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
6 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
7 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
8 | github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
9 | github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
10 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
11 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
12 |
--------------------------------------------------------------------------------
/examples/discovery/discovery.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "time"
7 |
8 | "github.com/kr/pretty"
9 | "github.com/videonext/onvif/discovery"
10 | "github.com/videonext/onvif/profiles/devicemgmt"
11 | "github.com/videonext/onvif/soap"
12 | )
13 |
14 | func main() {
15 |
16 | // discovery devices
17 | devices, err := discovery.StartDiscovery(5 * time.Second)
18 | if err != nil {
19 | fmt.Println(err.Error())
20 | }
21 | if len(devices) == 0 {
22 | fmt.Printf("No devices descovered\n")
23 |
24 | return
25 | }
26 |
27 | fmt.Printf("Discovered %d devices\n", len(devices))
28 | pretty.Println(devices)
29 |
30 | // Create soap client
31 | client := soap.NewClient(
32 | soap.WithTimeout(time.Second * 5),
33 | )
34 | client.AddHeader(soap.NewWSSSecurityHeader("root", "rootpass"))
35 |
36 | for _, d := range devices {
37 | // Create devicemgmt service instance and specify xaddr (which could be received in the discovery)
38 | dev := devicemgmt.NewDevice(client, d.XAddr)
39 |
40 | log.Println("devicemgmt.GetDeviceInformation", d.XAddr)
41 | {
42 | reply, err := dev.GetDeviceInformation(&devicemgmt.GetDeviceInformation{})
43 | if err != nil {
44 | if serr, ok := err.(*soap.SOAPFault); ok {
45 | pretty.Println(serr)
46 | }
47 | log.Fatalf("Request failed: %s", err.Error())
48 | }
49 | pretty.Println(reply)
50 | }
51 |
52 | log.Println("devicemgmt.GetServices", d.XAddr)
53 | {
54 | reply, err := dev.GetServices(&devicemgmt.GetServices{})
55 | if err != nil {
56 | if serr, ok := err.(*soap.SOAPFault); ok {
57 | pretty.Println(serr)
58 | }
59 | log.Fatalf("Request failed: %s", err.Error())
60 | }
61 | pretty.Println(reply)
62 | }
63 |
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/examples/recording/recording.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "time"
7 |
8 | "github.com/kr/pretty"
9 | "github.com/videonext/onvif/profiles/recording"
10 | "github.com/videonext/onvif/soap"
11 | )
12 |
13 | func main() {
14 |
15 | // Create soap client
16 | client := soap.NewClient(
17 | soap.WithTimeout(time.Second * 5),
18 | )
19 | client.AddHeader(soap.NewWSSSecurityHeader("root", "pass"))
20 |
21 | var token recording.RecordingReference
22 | // Create service instance and specify xaddr (which could be received in the devicemgmt.GetServices())
23 | r := recording.NewRecordingPort(client, "http://192.168.27.66/onvif/services")
24 | {
25 | cr := recording.CreateRecording{RecordingConfiguration: recording.RecordingConfiguration{}}
26 | cr.RecordingConfiguration.Content = "mycontent"
27 | cr.RecordingConfiguration.MaximumRetentionTime = "P7D" //"PT0M30S"
28 | cr.RecordingConfiguration.Source =
29 | recording.RecordingSourceInformation{
30 | SourceId: "http://192.168.27.66/onvif/services",
31 | Name: "mysourcename",
32 | Location: "mysourcelocation",
33 | Description: "mysourcedescription",
34 | Address: "http://192.168.27.66/onvif/services"}
35 |
36 | reply, err := r.CreateRecording(&cr)
37 |
38 | if err != nil {
39 | if serr, ok := err.(*soap.SOAPFault); ok {
40 | pretty.Println(serr)
41 | }
42 | log.Fatalf("Request failed: %s", err.Error())
43 | }
44 | pretty.Println(reply)
45 | token = reply.RecordingToken
46 | fmt.Printf("Token: %s\n", token)
47 |
48 | dr := recording.DeleteRecording{RecordingToken: token}
49 | reply2, err := r.DeleteRecording(&dr)
50 | if err != nil {
51 | if serr, ok := err.(*soap.SOAPFault); ok {
52 | pretty.Println(serr)
53 | }
54 | log.Fatalf("Request failed: %s", err.Error())
55 | }
56 | pretty.Println(reply2)
57 |
58 | fmt.Println("Getting all records")
59 | reply3, err := r.GetRecordings(&recording.GetRecordings{})
60 | if err != nil {
61 | if serr, ok := err.(*soap.SOAPFault); ok {
62 | pretty.Println(serr)
63 | }
64 | log.Fatalf("Request failed: %s", err.Error())
65 | }
66 | pretty.Println(reply3)
67 |
68 | }
69 |
70 | // .............
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/discovery/discovery.go:
--------------------------------------------------------------------------------
1 | package discovery
2 |
3 | import (
4 | "errors"
5 | "net"
6 | "regexp"
7 | "strings"
8 | "time"
9 |
10 | "github.com/clbanning/mxj"
11 | uuid "github.com/satori/go.uuid"
12 | )
13 |
14 | var errWrongDiscoveryResponse = errors.New("Response is not related to discovery request")
15 |
16 | // Device contains data of ONVIF camera
17 | type Device struct {
18 | ID string
19 | Name string
20 | XAddr string
21 | }
22 |
23 | // StartDiscovery send a WS-Discovery message and wait for all matching device to respond
24 | func StartDiscovery(duration time.Duration) ([]Device, error) {
25 | // Get list of interface address
26 | addrs, err := net.InterfaceAddrs()
27 | if err != nil {
28 | return []Device{}, err
29 | }
30 |
31 | // Fetch IPv4 address
32 | ipAddrs := []string{}
33 | for _, addr := range addrs {
34 | ipAddr, ok := addr.(*net.IPNet)
35 | if ok && !ipAddr.IP.IsLoopback() && ipAddr.IP.To4() != nil {
36 | ipAddrs = append(ipAddrs, ipAddr.IP.String())
37 | }
38 | }
39 |
40 | // Create initial discovery results
41 | discoveryResults := []Device{}
42 |
43 | // Discover device on each interface's network
44 | for _, ipAddr := range ipAddrs {
45 | devices, err := discoverDevices(ipAddr, duration)
46 | if err != nil {
47 | // return []Device{}, err
48 | continue
49 | }
50 |
51 | for _, dd := range devices {
52 | var found bool
53 |
54 | for _, d := range discoveryResults {
55 | if d.ID == dd.ID {
56 | found = true
57 | break
58 | }
59 | }
60 |
61 | if !found {
62 | discoveryResults = append(discoveryResults, dd)
63 | }
64 | }
65 |
66 | }
67 |
68 | if len(discoveryResults) == 0 && err != nil {
69 | return []Device{}, err
70 | }
71 |
72 | return discoveryResults, nil
73 | }
74 |
75 | func discoverDevices(ipAddr string, duration time.Duration) ([]Device, error) {
76 | // Create WS-Discovery request
77 | requestID := "uuid:" + uuid.NewV4().String()
78 | request := `
79 |
80 |
85 |
86 | ` + requestID + `
87 | urn:schemas-xmlsoap-org:ws:2005:04:discovery
88 | http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe
89 |
90 |
91 |
92 |
93 | dn:NetworkVideoTransmitter
94 |
95 |
96 | `
97 |
98 | // Clean WS-Discovery message
99 | request = regexp.MustCompile(`\>\s+\<`).ReplaceAllString(request, "><")
100 | request = regexp.MustCompile(`\s+`).ReplaceAllString(request, " ")
101 |
102 | // Create UDP address for local and multicast address
103 | localAddress, err := net.ResolveUDPAddr("udp4", ipAddr+":0")
104 | if err != nil {
105 | return []Device{}, err
106 | }
107 |
108 | multicastAddress, err := net.ResolveUDPAddr("udp4", "239.255.255.250:3702")
109 | if err != nil {
110 | return []Device{}, err
111 | }
112 |
113 | // Create UDP connection to listen for respond from matching device
114 | conn, err := net.ListenUDP("udp", localAddress)
115 | if err != nil {
116 | return []Device{}, err
117 | }
118 | defer conn.Close()
119 |
120 | // Set connection's timeout
121 | err = conn.SetDeadline(time.Now().Add(duration))
122 | if err != nil {
123 | return []Device{}, err
124 | }
125 |
126 | // Send WS-Discovery request to multicast address
127 | _, err = conn.WriteToUDP([]byte(request), multicastAddress)
128 | if err != nil {
129 | return []Device{}, err
130 | }
131 |
132 | // Create initial discovery results
133 | discoveryResults := []Device{}
134 |
135 | // Keep reading UDP message until timeout
136 | for {
137 | // Create buffer and receive UDP response
138 | buffer := make([]byte, 10*1024)
139 | _, _, err = conn.ReadFromUDP(buffer)
140 |
141 | //fmt.Println(string(buffer))
142 | // pretty.Println(buffer)
143 | // Check if connection timeout
144 | if err != nil {
145 | if udpErr, ok := err.(net.Error); ok && udpErr.Timeout() {
146 | break
147 | } else {
148 | return discoveryResults, err
149 | }
150 | }
151 |
152 | // Read and parse WS-Discovery response
153 | device, err := readDiscoveryResponse(requestID, buffer)
154 | if err != nil && err != errWrongDiscoveryResponse {
155 | return discoveryResults, err
156 | }
157 |
158 | // Push device to results
159 | discoveryResults = append(discoveryResults, device)
160 | }
161 |
162 | return discoveryResults, nil
163 | }
164 |
165 | // readDiscoveryResponse reads and parses WS-Discovery response
166 | func readDiscoveryResponse(messageID string, buffer []byte) (Device, error) {
167 | // Inital result
168 | result := Device{}
169 |
170 | // fmt.Println("!!!!readDiscoveryResponse")
171 |
172 | // Parse XML to map
173 | mapXML, err := mxj.NewMapXml(buffer)
174 | if err != nil {
175 | return result, err
176 | }
177 |
178 | // Check if this response is for our request
179 | responseMessageID, _ := mapXML.ValueForPathString("Envelope.Header.RelatesTo")
180 | if responseMessageID != messageID {
181 | return result, errWrongDiscoveryResponse
182 | }
183 |
184 | // Get device's ID and clean it
185 | deviceID, _ := mapXML.ValueForPathString("Envelope.Body.ProbeMatches.ProbeMatch.EndpointReference.Address")
186 | deviceID = strings.Replace(deviceID, "urn:uuid:", "", 1)
187 |
188 | // Get device's name
189 | deviceName := ""
190 | scopes, _ := mapXML.ValueForPathString("Envelope.Body.ProbeMatches.ProbeMatch.Scopes")
191 | for _, scope := range strings.Split(scopes, " ") {
192 | if strings.HasPrefix(scope, "onvif://www.onvif.org/name/") {
193 | deviceName = strings.Replace(scope, "onvif://www.onvif.org/name/", "", 1)
194 | deviceName = strings.Replace(deviceName, "_", " ", -1)
195 | break
196 | }
197 | }
198 |
199 | // Get device's xAddrs
200 | xAddrs, _ := mapXML.ValueForPathString("Envelope.Body.ProbeMatches.ProbeMatch.XAddrs")
201 | listXAddr := strings.Split(xAddrs, " ")
202 | if len(listXAddr) == 0 {
203 | return result, errors.New("Device does not have any xAddr")
204 | }
205 |
206 | // Finalize result
207 | result.ID = deviceID
208 | result.Name = deviceName
209 | result.XAddr = listXAddr[0]
210 |
211 | return result, nil
212 | }
213 |
--------------------------------------------------------------------------------
/wsdl/uplink.wsdl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | The capabilities for the uplink service is returned in the Capabilities element.
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | Maximum number of uplink connections that can be configured.
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | Uniform resource locator by which the remote client can be reached.
58 |
59 |
60 | ID of the certificate to be used for client authentication.
61 |
62 |
63 | Authorization level that will be assigned to the uplink connection.
64 |
65 |
66 | Current connection status (see tup:ConnectionStatus for possible values).
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | List of configured uplinks.
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 | SConfiguration to be added or modified.
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 | Uniform resource locator of the configuration to be deleted.
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 | Returns the capabilities of the uplink service.
150 |
151 |
152 |
153 |
154 |
155 | A device supporting uplinks shall support this command to retrieve the configured uplink configurations.
156 | The Status field shall signal whether a connection is Offline, Connecting or Online.
157 |
158 |
159 |
160 |
161 |
162 |
163 | A device supporting uplinks shall support this command to add or modify an uplink configuration.
164 | The Status property of the UplinkConfiguration shall be ignored by the device. A device shall
165 | use the field RemoteAddress to decide whether to update an existing entry or create a new entry.
166 |
167 |
168 |
169 |
170 |
171 |
172 | A device supporting uplinks shall support this command to remove an uplink configuration.
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
--------------------------------------------------------------------------------
/wsdl/replay.wsdl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | The capabilities for the replay service is returned in the Capabilities element.
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | Indicator that the Device supports reverse playback as defined in the ONVIF Streaming Specification.
41 |
42 |
43 |
44 |
45 | The list contains two elements defining the minimum and maximum valid values supported as session timeout in seconds.
46 |
47 |
48 |
49 |
50 | Indicates support for RTP/RTSP/TCP.
51 |
52 |
53 |
54 |
55 | If playback streaming over WebSocket is supported, this shall return the RTSP WebSocket URI as described in Streaming Specification Section 5.1.1.5.
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | Specifies the connection parameters to be used for the stream. The URI that is returned may depend on these parameters.
68 |
69 |
70 |
71 |
72 | The identifier of the recording to be streamed.
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | The URI to which the client should connect in order to stream the recording.
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 | Description of the new replay configuration parameters.
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | The current replay configuration parameters.
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 | Returns the capabilities of the replay service. The result is returned in a typed answer.
152 |
153 |
154 |
155 |
156 |
157 | Requests a URI that can be used to initiate playback of a recorded stream
158 | using RTSP as the control protocol. The URI is valid only as it is
159 | specified in the response.
160 | This operation is mandatory.
161 |
162 |
163 |
164 |
165 |
166 |
167 | Returns the current configuration of the replay service.
168 | This operation is mandatory.
169 |
170 |
171 |
172 |
173 |
174 |
175 | Changes the current configuration of the replay service.
176 | This operation is mandatory.
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
--------------------------------------------------------------------------------
/soap/soap.go:
--------------------------------------------------------------------------------
1 | package soap
2 |
3 | import (
4 | "bytes"
5 | "context"
6 | "crypto/rand"
7 | "crypto/sha1"
8 | "crypto/tls"
9 | "encoding/base64"
10 | "encoding/xml"
11 | "net"
12 | "net/http"
13 | "reflect"
14 | "time"
15 |
16 | "golang.org/x/net/html/charset"
17 | )
18 |
19 | type SOAPEncoder interface {
20 | Encode(v interface{}) error
21 | Flush() error
22 | }
23 |
24 | type SOAPDecoder interface {
25 | Decode(v interface{}) error
26 | }
27 |
28 | type SOAPHeader struct {
29 | XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Header"`
30 | Headers []interface{} `xml:"http://www.w3.org/2003/05/soap-envelope Header"`
31 | }
32 |
33 | type SOAPEnvelope struct {
34 | XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Envelope"`
35 | Header SOAPHeader
36 | Body SOAPBody
37 | }
38 |
39 | type SOAPBody struct {
40 | XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Body"`
41 |
42 | Fault *SOAPFault `xml:",omitempty"`
43 | Content interface{} `xml:",omitempty"`
44 | }
45 |
46 | // UnmarshalXML unmarshals SOAPBody xml
47 | func (b *SOAPBody) UnmarshalXML(d *Decoder, _ StartElement) error {
48 | if b.Content == nil {
49 | return xml.UnmarshalError("Content must be a pointer to a struct")
50 | }
51 |
52 | var (
53 | token xml.Token
54 | err error
55 | consumed bool
56 | )
57 |
58 | Loop:
59 | for {
60 | if token, err = d.Token(); err != nil {
61 | return err
62 | }
63 |
64 | if token == nil {
65 | break
66 | }
67 |
68 | switch se := token.(type) {
69 | case StartElement:
70 | if consumed {
71 | return xml.UnmarshalError("Found multiple elements inside SOAP body; not wrapped-document/literal WS-I compliant")
72 | } else if se.Name.Space == "http://www.w3.org/2003/05/soap-envelope" && se.Name.Local == "Fault" {
73 | b.Fault = &SOAPFault{}
74 | b.Content = nil
75 |
76 | err = d.DecodeElement(b.Fault, &se)
77 | if err != nil {
78 | return err
79 | }
80 |
81 | consumed = true
82 | } else {
83 | if err = d.DecodeElement(b.Content, &se); err != nil {
84 | return err
85 | }
86 |
87 | consumed = true
88 | }
89 | case EndElement:
90 | break Loop
91 |
92 | }
93 | }
94 |
95 | return nil
96 | }
97 |
98 | type SOAPFaultSubCode struct {
99 | XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Subcode"`
100 |
101 | Value string
102 | }
103 |
104 | type SOAPFaultCode struct {
105 | XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Code"`
106 |
107 | Value string
108 | Subcode SOAPFaultSubCode
109 | }
110 |
111 | type SOAPFaultReason struct {
112 | XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Reason"`
113 |
114 | Text string
115 | }
116 |
117 | type SOAPFaultDetail struct {
118 | XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Detail"`
119 |
120 | Text string
121 | }
122 |
123 | type SOAPFault struct {
124 | XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Fault"`
125 |
126 | Code SOAPFaultCode
127 | Reason SOAPFaultReason `xml:",omitempty"`
128 | Detail SOAPFaultDetail `xml:",omitempty"`
129 | }
130 |
131 | func (f *SOAPFault) Error() string {
132 | s := f.Reason.Text
133 | if f.Detail.Text != "" {
134 | s += ". Details: " + f.Detail.Text
135 | }
136 | if s == "" {
137 | if f.Code.Value != "" {
138 | s = f.Code.Value + ". "
139 | }
140 |
141 | if f.Code.Subcode.Value != "" {
142 | s += f.Code.Subcode.Value
143 | }
144 | }
145 | return s
146 | }
147 |
148 | const (
149 | // Predefined WSS namespaces to be used in
150 | WssNsWSSE string = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
151 | WssNsWSU string = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
152 | WssNsType string = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"
153 | mtomContentType string = `multipart/related; start-info="application/soap+xml"; type="application/xop+xml"; boundary="%s"`
154 | )
155 |
156 | type WSSPassword struct {
157 | Type string `xml:",attr"`
158 | Value string `xml:",chardata"`
159 | }
160 |
161 | type WSSNonce struct {
162 | EncodingType string `xml:",attr"`
163 | Value string `xml:",chardata"`
164 | }
165 |
166 | type WSSCreated struct {
167 | XMLName xml.Name `xml:"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd Created"`
168 | Value string `xml:",chardata"`
169 | }
170 |
171 | type WSSUsernameToken struct {
172 | Username string
173 |
174 | Password WSSPassword
175 |
176 | Nonce WSSNonce
177 |
178 | Created WSSCreated
179 | }
180 |
181 | type WSSSecurityHeader struct {
182 | XMLName xml.Name `xml:"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd Security"`
183 |
184 | MustUnderstand string `xml:"mustUnderstand,attr"`
185 |
186 | UsernameToken WSSUsernameToken
187 | }
188 |
189 | // NewWSSSecurityHeader creates WSSSecurityHeader instance
190 | func NewWSSSecurityHeader(user, pass string, created time.Time) *WSSSecurityHeader {
191 | hdr := &WSSSecurityHeader{MustUnderstand: "1"}
192 |
193 | // Username
194 | hdr.UsernameToken.Username = user
195 |
196 | // Created
197 | if created.Year() != 0 {
198 | hdr.UsernameToken.Created.Value = created.Format("2006-01-02T15:04:05.999") + "Z"
199 | //fmt.Println("------", hdr.UsernameToken.Created.Value, created.Nanosecond())
200 |
201 | } else {
202 | hdr.UsernameToken.Created.Value = time.Now().Format("2006-01-02T15:04:05.999") + "Z"
203 | }
204 |
205 | // Nonce
206 | b := make([]byte, 16)
207 | rand.Read(b)
208 | hdr.UsernameToken.Nonce.EncodingType = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
209 | hdr.UsernameToken.Nonce.Value = base64.StdEncoding.EncodeToString(b)
210 |
211 | // Password
212 | h := sha1.New()
213 | h.Write([]byte(hdr.UsernameToken.Nonce.Value + hdr.UsernameToken.Created.Value + pass))
214 | hdr.UsernameToken.Password.Type = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"
215 | hdr.UsernameToken.Password.Value = base64.StdEncoding.EncodeToString(h.Sum(nil))
216 |
217 | return hdr
218 | }
219 |
220 | type basicAuth struct {
221 | Login string
222 | Password string
223 | }
224 |
225 | type options struct {
226 | tlsCfg *tls.Config
227 | auth *basicAuth
228 | timeout time.Duration
229 | contimeout time.Duration
230 | tlshshaketimeout time.Duration
231 | client HTTPClient
232 | httpHeaders map[string]string
233 | wssCallback func() *WSSSecurityHeader
234 | }
235 |
236 | var defaultOptions = options{
237 | timeout: time.Duration(30 * time.Second),
238 | contimeout: time.Duration(90 * time.Second),
239 | tlshshaketimeout: time.Duration(15 * time.Second),
240 | }
241 |
242 | // A Option sets options such as credentials, tls, etc.
243 | type Option func(*options)
244 |
245 | // WithWSSCallback is an Option to set the callback for WSSSecurityHeader
246 | func WithWSSCallback(c func() *WSSSecurityHeader) Option {
247 | return func(o *options) {
248 | o.wssCallback = c
249 | }
250 | }
251 |
252 | // WithHTTPClient is an Option to set the HTTP client to use
253 | // This cannot be used with WithTLSHandshakeTimeout, WithTLS,
254 | // WithTimeout options
255 | func WithHTTPClient(c HTTPClient) Option {
256 | return func(o *options) {
257 | o.client = c
258 | }
259 | }
260 |
261 | // WithTLSHandshakeTimeout is an Option to set default tls handshake timeout
262 | // This option cannot be used with WithHTTPClient
263 | func WithTLSHandshakeTimeout(t time.Duration) Option {
264 | return func(o *options) {
265 | o.tlshshaketimeout = t
266 | }
267 | }
268 |
269 | // WithRequestTimeout is an Option to set default end-end connection timeout
270 | // This option cannot be used with WithHTTPClient
271 | func WithRequestTimeout(t time.Duration) Option {
272 | return func(o *options) {
273 | o.contimeout = t
274 | }
275 | }
276 |
277 | // WithBasicAuth is an Option to set BasicAuth
278 | func WithBasicAuth(login, password string) Option {
279 | return func(o *options) {
280 | o.auth = &basicAuth{Login: login, Password: password}
281 | }
282 | }
283 |
284 | // WithTLS is an Option to set tls config
285 | // This option cannot be used with WithHTTPClient
286 | func WithTLS(tls *tls.Config) Option {
287 | return func(o *options) {
288 | o.tlsCfg = tls
289 | }
290 | }
291 |
292 | // WithTimeout is an Option to set default HTTP dial timeout
293 | func WithTimeout(t time.Duration) Option {
294 | return func(o *options) {
295 | o.timeout = t
296 | }
297 | }
298 |
299 | // WithHTTPHeaders is an Option to set global HTTP headers for all requests
300 | func WithHTTPHeaders(headers map[string]string) Option {
301 | return func(o *options) {
302 | o.httpHeaders = headers
303 | }
304 | }
305 |
306 | // Client is soap client
307 | type Client struct {
308 | opts *options
309 | headers []interface{}
310 | }
311 |
312 | // HTTPClient is a client which can make HTTP requests
313 | // An example implementation is net/http.Client
314 | type HTTPClient interface {
315 | Do(req *http.Request) (*http.Response, error)
316 | }
317 |
318 | // NewClient creates new SOAP client instance
319 | func NewClient(opt ...Option) *Client {
320 | opts := defaultOptions
321 | for _, o := range opt {
322 | o(&opts)
323 | }
324 | return &Client{
325 | opts: &opts,
326 | }
327 | }
328 |
329 | // AddHeader adds envelope header
330 | func (s *Client) AddHeader(header interface{}) {
331 | s.headers = append(s.headers, header)
332 | }
333 |
334 | // ReplaceHeader replaces envelope header matching by Type
335 | func (s *Client) ReplaceHeader(header interface{}) {
336 | found := false
337 | i := 0
338 | for i = 0; i < len(s.headers); i++ {
339 | if reflect.TypeOf(s.headers[i]).Name() == reflect.TypeOf(header).Name() {
340 | found = true
341 | break
342 | }
343 | }
344 | if found {
345 | s.headers[i] = s.headers[len(s.headers)-1] // Copy last element to index i.
346 | s.headers[len(s.headers)-1] = "" // Erase last element (write zero value).
347 | s.headers = s.headers[:len(s.headers)-1] // Truncate slice.
348 | }
349 | s.headers = append(s.headers, header)
350 | }
351 |
352 | // CallContext performs HTTP POST request with a context
353 | func (s *Client) CallContext(ctx context.Context, xaddr string, soapAction string, request, response interface{}) error {
354 | return s.call(ctx, xaddr, soapAction, request, response)
355 | }
356 |
357 | // Call performs HTTP POST request
358 | func (s *Client) Call(xaddr string, soapAction string, request, response interface{}) error {
359 | return s.call(context.Background(), xaddr, soapAction, request, response)
360 | }
361 |
362 | func (s *Client) call(ctx context.Context, xaddr string, soapAction string, request, response interface{}) error {
363 | envelope := SOAPEnvelope{}
364 |
365 | if s.opts.wssCallback != nil {
366 | wssHdr := s.opts.wssCallback()
367 | if wssHdr != nil {
368 | s.ReplaceHeader(wssHdr)
369 | }
370 | }
371 | if s.headers != nil && len(s.headers) > 0 {
372 | envelope.Header.Headers = s.headers
373 | }
374 |
375 | envelope.Body.Content = request
376 | buffer := new(bytes.Buffer)
377 | var encoder SOAPEncoder
378 | encoder = xml.NewEncoder(buffer)
379 |
380 | if err := encoder.Encode(envelope); err != nil {
381 | return err
382 | }
383 |
384 | if err := encoder.Flush(); err != nil {
385 | return err
386 | }
387 |
388 | req, err := http.NewRequest("POST", xaddr, buffer)
389 | if err != nil {
390 | return err
391 | }
392 | if s.opts.auth != nil {
393 | req.SetBasicAuth(s.opts.auth.Login, s.opts.auth.Password)
394 | }
395 |
396 | req.WithContext(ctx)
397 |
398 | req.Header.Add("Content-Type", "application/soap+xml; charset=utf-8; action=\""+soapAction+"\"")
399 | req.Header.Add("Soapaction", "\""+soapAction+"\"")
400 | req.Header.Set("User-Agent", "videonext-onvif-go/0.1")
401 | if s.opts.httpHeaders != nil {
402 | for k, v := range s.opts.httpHeaders {
403 | req.Header.Set(k, v)
404 | }
405 | }
406 | req.Close = true
407 |
408 | client := s.opts.client
409 | if client == nil {
410 | tr := &http.Transport{
411 | TLSClientConfig: s.opts.tlsCfg,
412 | DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
413 | d := net.Dialer{Timeout: s.opts.timeout}
414 | return d.DialContext(ctx, network, addr)
415 | },
416 | TLSHandshakeTimeout: s.opts.tlshshaketimeout,
417 | }
418 | client = &http.Client{Timeout: s.opts.contimeout, Transport: tr}
419 | }
420 |
421 | res, err := client.Do(req)
422 | if err != nil {
423 | return err
424 | }
425 | defer res.Body.Close()
426 |
427 | respEnvelope := new(SOAPEnvelope)
428 | respEnvelope.Body = SOAPBody{Content: response}
429 |
430 | dec := NewDecoder(res.Body)
431 | dec.CharsetReader = charset.NewReaderLabel
432 |
433 | if err := dec.Decode(respEnvelope); err != nil {
434 | return err
435 | }
436 |
437 | fault := respEnvelope.Body.Fault
438 | if fault != nil {
439 | return fault
440 | }
441 |
442 | return nil
443 | }
444 |
--------------------------------------------------------------------------------
/wsdl/bin/fixgen.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import sys
3 | import os
4 | import re
5 | from urllib.request import urlopen
6 |
7 | # How to use:
8 | # go get github.com/hooklift/gowsdl/...
9 | # ./fixgen.py [onvif profile file name without .wsdl]
10 |
11 | if len(sys.argv) != 2:
12 | print("Usage:\n./fixgen.py [path to profile file without .wsdl]")
13 | exit(1)
14 |
15 | go_package = os.path.basename(sys.argv[1])
16 | go_src = os.path.basename(sys.argv[1]) + '.go'
17 | wsdl_file = sys.argv[1] + '.wsdl'
18 |
19 | with open(wsdl_file, 'r', encoding="utf-8") as file:
20 | wsdl = file.read()
21 |
22 | r = re.findall(r'targetNamespace="(http://www.onvif.org/.+)"', wsdl)
23 | if len(r):
24 | targetNamespace = r[0]
25 |
26 | os.system('gowsdl -o ' + go_src + ' -p ' + go_package + ' ' + wsdl_file + ' | grep -v expected')
27 |
28 | with open(go_package + '/' + go_src, 'r', encoding="utf-8") as file:
29 | data = file.read()
30 |
31 | data = data.replace('// Code generated by gowsdl DO NOT EDIT.', '')
32 | print(' - Replace import')
33 | data = data.replace('"github.com/hooklift/gowsdl/soap"',
34 | '"github.com/videonext/onvif/soap"')
35 | ########################################################################
36 |
37 | print(' - Working around some bugs in the gowsdl')
38 | data = data.replace('interface{}', '')
39 | data = data.replace('TLS1.0 bool', 'TLS1_0 bool')
40 | data = data.replace('TLS1.1 bool', 'TLS1_1 bool')
41 | data = data.replace('TLS1.2 bool', 'TLS1_2 bool')
42 | data = data.replace('X.509Token bool', 'X_509Token bool')
43 | ########################################################################
44 |
45 | print(' - Adding wsdl\'s namespace and method name to the SOAP action')
46 | data = re.sub(r'(?s)func \(service (\*\w+\)) (\w+)Context\s*\(ctx context.Context, request (\*\w+\)) \((\*\w+), error\)(.+?)service\.client\.CallContext\(ctx, "(\'\')",',
47 | r'func (service \1 \2Context(ctx context.Context, request \3 (\4, error)\5service.client.CallContext(ctx, "' + targetNamespace + '/' + r'\2",', data)
48 | ########################################################################
49 |
50 | print(' - Patching object, CallContext and New* functions: add xaddr field/arg')
51 | data = re.sub(r'(?s)type\s+(\w+?)\s+struct\s+\{\s+?client\s+\*soap\.Client',
52 | r'type \1 struct {\nclient *soap.Client\nxaddr string\n', data)
53 | data = data.replace('service.client.CallContext(ctx,', 'service.client.CallContext(ctx, service.xaddr,')
54 | data = re.sub(r'(?s)func New(.+?)\(client \*soap.Client\) (.+?) \{.+?return \&(\w+)\{.+?}',
55 | r'func New\1(client *soap.Client, xaddr string) \2 {\n return &\3{\nclient: client,\nxaddr: xaddr,\n}', data)
56 | ########################################################################
57 |
58 | print(' - Fixing namespaces in the xsd types')
59 | type_map = {}
60 | xsds = ['http://www.onvif.org/ver10/schema/common.xsd',
61 | 'http://www.onvif.org/ver10/schema/onvif.xsd',
62 | 'http://www.w3.org/2001/xml.xsd',
63 | 'http://www.onvif.org/ver10/schema/metadatastream.xsd',
64 | 'http://www.onvif.org/ver10/pacs/types.xsd',
65 | 'http://www.onvif.org/ver20/analytics/rules.xsd',
66 | 'http://www.onvif.org/ver20/analytics/radiometry.xsd']
67 | for xsd in xsds:
68 | xsd_data = urlopen(xsd).read().decode('utf-8')
69 | r = re.findall(r'targetNamespace="(http://.+?)"', xsd_data)
70 | if len(r):
71 | ns = r[0]
72 | else:
73 | raise Exception('No namespace in the ' + xsd)
74 | r = re.findall(r'\', xsd_data)
75 | for t in r:
76 | if not t[0].isupper():
77 | t = t.title()
78 | if t in type_map:
79 | continue
80 | type_map[t] = ns
81 | # reading used types from onvif.xsd
82 | onvif_xsd_data = urlopen('http://www.onvif.org/ver10/schema/onvif.xsd').read().decode('utf-8')
83 | r = re.findall(r'type="xs:(.+?)"', onvif_xsd_data)
84 | for t in r:
85 | if not t[0].isupper():
86 | t = t.title()
87 | if t in type_map:
88 | continue
89 | type_map[t] = 'http://www.onvif.org/ver10/schema'
90 | # reading used types from common.xsd
91 | common_xsd_data = urlopen('http://www.onvif.org/ver10/schema/common.xsd').read().decode('utf-8')
92 | r = re.findall(r'type="xs:(.+?)"', common_xsd_data)
93 | for t in r:
94 | if not t[0].isupper():
95 | t = t.title()
96 | if t in type_map:
97 | continue
98 | type_map[t] = 'http://www.onvif.org/ver10/schema'
99 | # reading types from wsdl
100 | r = re.findall(r'\', wsdl)
101 | for t in r:
102 | if not t[0].isupper():
103 | t = t.title()
104 | if t in type_map:
105 | continue
106 | type_map[t] = targetNamespace
107 | # some other types
108 | type_map['String'] = 'http://www.onvif.org/ver10/schema'
109 | type_map['string'] = 'http://www.onvif.org/ver10/schema'
110 | type_map['time.Time'] = 'http://www.onvif.org/ver10/schema'
111 | type_map['byte'] = 'http://www.onvif.org/ver10/schema'
112 | type_map['int'] = 'http://www.onvif.org/ver10/schema'
113 | type_map['uint'] = 'http://www.onvif.org/ver10/schema'
114 | type_map['int8'] = 'http://www.onvif.org/ver10/schema'
115 | type_map['uint8'] = 'http://www.onvif.org/ver10/schema'
116 | type_map['int16'] = 'http://www.onvif.org/ver10/schema'
117 | type_map['uint16'] = 'http://www.onvif.org/ver10/schema'
118 | type_map['int32'] = 'http://www.onvif.org/ver10/schema'
119 | type_map['uint32'] = 'http://www.onvif.org/ver10/schema'
120 | type_map['int64'] = 'http://www.onvif.org/ver10/schema'
121 | type_map['uint64'] = 'http://www.onvif.org/ver10/schema'
122 | type_map['float32'] = 'http://www.onvif.org/ver10/schema'
123 | type_map['float64'] = 'http://www.onvif.org/ver10/schema'
124 | type_map['bool'] = 'http://www.onvif.org/ver10/schema'
125 | type_map['[]string'] = 'http://www.onvif.org/ver10/schema'
126 | type_map['ReferenceToken'] = 'http://www.onvif.org/ver10/schema'
127 | type_map['time.Time'] = 'http://www.onvif.org/ver10/schema'
128 | type_map['NonNegativeInteger'] = 'http://www.onvif.org/ver10/schema'
129 | if type_map['Anyuri'] != None:
130 | type_map['AnyURI'] = type_map['Anyuri']
131 | # print(type_map)
132 | for k, v in type_map.items():
133 | ns = v
134 | # # check if type used in the wsdl we are processing
135 | r = re.findall(r'type="\w+:' + re.escape(k), wsdl)
136 | # if len(r) and (re.search(r'complexType name="' + k + '"', common_xsd_data) or re.search(r'complexType name="' + k + '"', onvif_xsd_data)):
137 | # ns = targetNamespace
138 | if len(r):
139 | ns = targetNamespace
140 | data = re.sub(r"(?s)(\w+)\s+\*" + re.escape(k) + r"\s+`xml:\"\1(.*?)\"`",
141 | r"\1 *" + k + r' `xml:"' + ns + r' \1\2"`',
142 | data)
143 | data = re.sub(r"(?s)(\w+)\s+\[\]\*" + re.escape(k) + r"\s+`xml:\"\1(.*?)\"`",
144 | r"\1 []*" + k + r' `xml:"' + ns + r' \1\2"`',
145 | data)
146 | data = re.sub(r"(?s)(\w+)\s+\[\]" + re.escape(k) + r"\s+`xml:\"\1(.*?)\"`",
147 | r"\1 []" + k + r' `xml:"' + ns + r' \1\2"`',
148 | data)
149 | data = re.sub(r"(?s)(\w+)\s+" + re.escape(k) + r"\s+`xml:\"\1(.*?)\"`",
150 | r"\1 " + k + r' `xml:"' + ns + r' \1\2"`',
151 | data)
152 | ########################################################################
153 |
154 | with open(go_package + '/' + go_src, 'w', encoding="utf-8") as file:
155 | file.write(data)
156 |
157 | os.system("gofmt -w " + go_package + '/' + go_src)
158 |
159 | with open(go_package + '/' + go_src, 'r', encoding="utf-8") as file:
160 | data = file.read()
161 |
162 | print(' - Adding missed simple types')
163 | data += "\ntype AnyURI string\n"
164 | data += "type Duration string\n"
165 | data += "type QName string\n"
166 | data += "type NCName string\n"
167 | data += "type NonNegativeInteger int64\n"
168 | data += "type PositiveInteger int64\n"
169 | data += "type NonPositiveInteger int64\n"
170 | data += "type AnySimpleType string\n"
171 | data += "type String string\n"
172 | ########################################################################
173 |
174 | print(' - Removing unused types')
175 | for k, v in type_map.items():
176 | r0 = re.findall(r"(\w+)\s+" + re.escape(k) + r"\s+`xml:\"", data)
177 | r1 = re.findall(r"(\w+)\s+\*" + re.escape(k) + r"\s+`xml:\"", data)
178 | r2 = re.findall(r"(\w+)\s+\[\]" + re.escape(k) + r"\s+`xml:\"", data)
179 | r3 = re.findall(r"(\w+)\s+\[\]\*" + re.escape(k) + r"\s+`xml:\"", data)
180 | r4 = re.findall(r"\*" + re.escape(k), data)
181 | r5 = re.findall(r"\[\]" + re.escape(k), data)
182 | r6 = re.findall(re.escape(k) + r' = ', data)
183 | r7 = re.findall(r'type \w+ ' + re.escape(k), data)
184 | if len(r0) == 0 and len(r1) == 0 and len(r2) == 0 and len(r3) == 0 and len(r4) == 0 and len(r5) == 0 and len(r6) == 0 and len(r7) == 0:
185 | regex = re.compile(r"(?s)type\s+" + re.escape(k) + r"\s+struct\s+\{(.+?)^\}", re.MULTILINE)
186 | data = re.sub(regex, '', data)
187 | regex = re.compile(r"(?s)type\s+" + re.escape(k) + r"\s+\w+\n", re.MULTILINE)
188 | data = re.sub(regex, '', data)
189 | r = re.findall(r"type (\w+) ", data)
190 | for t in r:
191 | r0 = re.findall(r"(\w+)\s+" + re.escape(t) + r"\s+`xml:\"", data)
192 | r1 = re.findall(r"(\w+)\s+\*" + re.escape(t) + r"\s+`xml:\"", data)
193 | r2 = re.findall(r"(\w+)\s+\[\]" + re.escape(t) + r"\s+`xml:\"", data)
194 | r3 = re.findall(r"(\w+)\s+\[\]\*" + re.escape(t) + r"\s+`xml:\"", data)
195 | r4 = re.findall(r"\*" + re.escape(t), data)
196 | r5 = re.findall(r"\[\]" + re.escape(t), data)
197 | r6 = re.findall(re.escape(t) + r' = ', data)
198 | r7 = re.findall(r'type \w+ ' + re.escape(t), data)
199 | if len(r0) == 0 and len(r1) == 0 and len(r2) == 0 and len(r3) == 0 and len(r4) == 0 and len(r5) == 0 and len(r6) == 0 and len(r7) == 0:
200 | regex = re.compile(r"(?s)type\s+" + re.escape(t) + r"\s+struct\s+\{(.+?)^\}", re.MULTILINE)
201 | data = re.sub(regex, '', data)
202 | regex = re.compile(r"(?s)type\s+" + re.escape(t) + r"\s+\w+\n", re.MULTILINE)
203 | data = re.sub(regex, '', data)
204 |
205 |
206 | ########################################################################
207 |
208 | print(' - Removing pointers for simple types')
209 | data = data.replace('*AnyURI', 'AnyURI')
210 | data = data.replace('*Duration', 'Duration')
211 | data = data.replace('*QName', 'QName')
212 | data = data.replace('*NonNegativeInteger', 'NonNegativeInteger')
213 | data = data.replace('*PositiveInteger', 'PositiveInteger')
214 | data = data.replace('*NonPositiveInteger', 'NonPositiveInteger')
215 | data = data.replace('*AnySimpleType', 'AnySimpleType')
216 | data = data.replace('*Description', 'Description')
217 | data = data.replace('*Name `xml', 'Name `xml')
218 | data = data.replace('*string `xml', 'string `xml')
219 | data = data.replace('*String `xml', 'String `xml')
220 | data = data.replace('*int32 `xml', 'int32 `xml')
221 | data = data.replace('*float32 `xml', 'float32 `xml')
222 | data = data.replace('*bool `xml', 'bool `xml')
223 | data = data.replace('*time.Time `xml', 'string `xml')
224 | data = data.replace('time.Time `xml', 'string `xml')
225 | data = data.replace('[]*', '[]')
226 | data = data.replace('*NCName', 'NCName')
227 | ########################################################################
228 |
229 | print(' - Removing duplicated types')
230 | data = re.sub(r'type \b(\w+)\s+\1\b', '', data)
231 | data = data.replace('type IntList IntAttrList', '')
232 | data = data.replace('type FloatList FloatAttrList', '')
233 | data = data.replace('type Capabilities DeviceServiceCapabilities', '')
234 | data = data.replace('type FaultcodeEnum *QName', 'type FaultcodeEnum QName')
235 | data = data.replace('type FaultCodesType *QName', 'type FaultCodesType QName')
236 | data = data.replace('type RelationshipType *AnyURI', 'type RelationshipType AnyURI')
237 | data = re.sub(r'(?s)type QueryExpressionType struct \{\n\s+XMLName xml\.Name `xml:"http://docs\.oasis-open\.org/wsn/b-2 ProducerProperties(.+?)\}',
238 | r'// Removed QueryExpressionType', data)
239 | r = re.findall(r'(?s)(type Capabilities struct(.+?)\})', data)
240 | if len(r) == 2:
241 | data = data.replace(r[1][0], '/* Removed ' + r[1][0] + ' Removed*/')
242 | ########################################################################
243 |
244 | print(' - Removing pointers to xml data types')
245 | data = re.sub(r"(\w+)\s+\*(\w+)\s+`xml:\"(.*?)\"`",
246 | r'\1 \2 `xml:"\3"`',
247 | data)
248 | data = re.sub(r"(\w+)\s+\[\]\*(\w+)\s+`xml:\"(.*?)\"`",
249 | r'\1 []\2 `xml:"\3"`',
250 | data)
251 | # keep some of them to prevent recursion
252 | data = data.replace('Extension NetworkZeroConfigurationExtension `xml:"', 'Extension *NetworkZeroConfigurationExtension `xml:"')
253 | data = data.replace('Tunnel Transport `xml:"', 'Tunnel *Transport `xml:"')
254 | data = data.replace('Subcode Subcode `xml:"', 'Subcode *Subcode `xml:"')
255 | data = data.replace('*Ref', 'Ref')
256 | ########################################################################
257 |
258 | # add comments to exported types
259 | regex = re.compile(r'^type\s+(.+?)\s+', re.MULTILINE)
260 | data = re.sub(regex, r'// \1 type\ntype \1 ', data)
261 | # add comments to exported constants
262 | regex = re.compile(r'(\w+) (\w+) = "(.+?)"', re.MULTILINE)
263 | data = re.sub(regex, r'// \1 const\n\1 \2 = "\3" ', data)
264 |
265 | # remove ns from *Response* types
266 | regex = re.compile(r'(?s)^(type \w+Response\w+ struct \{.+?\})', re.MULTILINE)
267 | r = re.findall(regex, data)
268 | regex = re.compile(r'(?s)^(type \w+Response struct \{.+?\})', re.MULTILINE)
269 | r += re.findall(regex, data)
270 | for block in r:
271 | block2 = re.sub(r'xml:"http.+? ', 'xml:"', block)
272 | data = data.replace(block, block2)
273 |
274 |
275 | with open(go_package + '/' + go_src, 'w', encoding="utf-8") as file:
276 | file.write(data)
277 |
278 |
279 | os.system("gofmt -w " + go_package + '/' + go_src)
280 |
281 |
282 | print('Done')
283 |
--------------------------------------------------------------------------------
/wsdl/common.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Unique identifier for a physical or logical resource.
10 | Tokens should be assigned such that they are unique within a device. Tokens must be at least unique within its class.
11 | Length up to 64 characters.
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Range of values greater equal Min value and less equal Max value.
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | Pan/tilt coordinate space selector. The following options are defined:
37 | - http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace
38 | - http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace
39 | - http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace
40 | - http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | Zoom coordinate space selector. The following options are defined:
52 | - http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace
53 | - http://www.onvif.org/ver10/tptz/ZoomSpaces/TranslationGenericSpace
54 | - http://www.onvif.org/ver10/tptz/ZoomSpaces/VelocityGenericSpace
55 | - http://www.onvif.org/ver10/tptz/ZoomSpaces/ZoomGenericSpeedSpace
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | Pan and tilt position. The x component corresponds to pan and the y component to tilt.
66 |
67 |
68 |
69 |
70 |
71 | A zoom position.
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | Specifies the absolute position of the PTZ unit together with the Space references. The default absolute spaces of the corresponding PTZ configuration MUST be referenced within the Position element.
83 |
84 |
85 |
86 |
87 |
88 |
89 | Indicates if the Pan/Tilt/Zoom device unit is currently moving, idle or in an unknown state.
90 |
91 |
92 |
93 |
94 |
95 |
96 | States a current PTZ error.
97 |
98 |
99 |
100 |
101 |
102 |
103 | Specifies the UTC time when this status was generated.
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 | Acceptable values:
161 |
162 | - http://www.onvif.org/ver10/colorspace/YCbCr - YCbCr
163 |
- X attribute = Y value
164 | - Y attribute = Cb value
165 | - Z attribute = Cr value
166 |
167 | - http://www.onvif.org/ver10/colorspace/RGB - RGB
168 |
- X attribute = R value
169 | - Y attribute = G value
170 | - Z attribute = B value
171 |
172 |
173 | If the Colorspace attribute is absent, YCbCr is implied.
174 |
175 | Deprecated values:
176 |
177 | - http://www.onvif.org/ver10/colorspace/CIELUV - CIE LUV
178 | - http://www.onvif.org/ver10/colorspace/CIELAB - CIE 1976 (L*a*b*)
179 | - http://www.onvif.org/ver10/colorspace/HSV - HSV
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 | Acceptable values are the same as in tt:Color.
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 | East west location as angle.
226 |
227 |
228 |
229 |
230 | North south location as angle.
231 |
232 |
233 |
234 |
235 | Hight in meters above sea level.
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 | Rotation around the x axis.
248 |
249 |
250 |
251 |
252 | Rotation around the y axis.
253 |
254 |
255 |
256 |
257 | Rotation around the z axis.
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 | East west location as angle.
270 |
271 |
272 |
273 |
274 | North south location as angle.
275 |
276 |
277 |
278 |
279 | Offset in meters from the sea level.
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 | Rotation around the y axis.
292 |
293 |
294 |
295 |
296 | Rotation around the z axis.
297 |
298 |
299 |
300 |
301 | Rotation around the x axis.
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 | Location on earth.
319 |
320 |
321 | Orientation relative to earth.
322 |
323 |
324 | Indoor location offset.
325 |
326 |
327 | Indoor orientation offset.
328 |
329 |
330 |
331 | Entity type the entry refers to, use a value from the tt:Entity enumeration.
332 |
333 |
334 | Optional entity token.
335 |
336 |
337 | If this value is true the entity cannot be deleted.
338 |
339 |
340 | Optional reference to the XAddr of another devices DeviceManagement service.
341 |
342 |
343 | If set the geo location is obtained internally.
344 |
345 |
346 |
347 |
348 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Mozilla Public License Version 2.0
2 | ==================================
3 |
4 | 1. Definitions
5 | --------------
6 |
7 | 1.1. "Contributor"
8 | means each individual or legal entity that creates, contributes to
9 | the creation of, or owns Covered Software.
10 |
11 | 1.2. "Contributor Version"
12 | means the combination of the Contributions of others (if any) used
13 | by a Contributor and that particular Contributor's Contribution.
14 |
15 | 1.3. "Contribution"
16 | means Covered Software of a particular Contributor.
17 |
18 | 1.4. "Covered Software"
19 | means Source Code Form to which the initial Contributor has attached
20 | the notice in Exhibit A, the Executable Form of such Source Code
21 | Form, and Modifications of such Source Code Form, in each case
22 | including portions thereof.
23 |
24 | 1.5. "Incompatible With Secondary Licenses"
25 | means
26 |
27 | (a) that the initial Contributor has attached the notice described
28 | in Exhibit B to the Covered Software; or
29 |
30 | (b) that the Covered Software was made available under the terms of
31 | version 1.1 or earlier of the License, but not also under the
32 | terms of a Secondary License.
33 |
34 | 1.6. "Executable Form"
35 | means any form of the work other than Source Code Form.
36 |
37 | 1.7. "Larger Work"
38 | means a work that combines Covered Software with other material, in
39 | a separate file or files, that is not Covered Software.
40 |
41 | 1.8. "License"
42 | means this document.
43 |
44 | 1.9. "Licensable"
45 | means having the right to grant, to the maximum extent possible,
46 | whether at the time of the initial grant or subsequently, any and
47 | all of the rights conveyed by this License.
48 |
49 | 1.10. "Modifications"
50 | means any of the following:
51 |
52 | (a) any file in Source Code Form that results from an addition to,
53 | deletion from, or modification of the contents of Covered
54 | Software; or
55 |
56 | (b) any new file in Source Code Form that contains any Covered
57 | Software.
58 |
59 | 1.11. "Patent Claims" of a Contributor
60 | means any patent claim(s), including without limitation, method,
61 | process, and apparatus claims, in any patent Licensable by such
62 | Contributor that would be infringed, but for the grant of the
63 | License, by the making, using, selling, offering for sale, having
64 | made, import, or transfer of either its Contributions or its
65 | Contributor Version.
66 |
67 | 1.12. "Secondary License"
68 | means either the GNU General Public License, Version 2.0, the GNU
69 | Lesser General Public License, Version 2.1, the GNU Affero General
70 | Public License, Version 3.0, or any later versions of those
71 | licenses.
72 |
73 | 1.13. "Source Code Form"
74 | means the form of the work preferred for making modifications.
75 |
76 | 1.14. "You" (or "Your")
77 | means an individual or a legal entity exercising rights under this
78 | License. For legal entities, "You" includes any entity that
79 | controls, is controlled by, or is under common control with You. For
80 | purposes of this definition, "control" means (a) the power, direct
81 | or indirect, to cause the direction or management of such entity,
82 | whether by contract or otherwise, or (b) ownership of more than
83 | fifty percent (50%) of the outstanding shares or beneficial
84 | ownership of such entity.
85 |
86 | 2. License Grants and Conditions
87 | --------------------------------
88 |
89 | 2.1. Grants
90 |
91 | Each Contributor hereby grants You a world-wide, royalty-free,
92 | non-exclusive license:
93 |
94 | (a) under intellectual property rights (other than patent or trademark)
95 | Licensable by such Contributor to use, reproduce, make available,
96 | modify, display, perform, distribute, and otherwise exploit its
97 | Contributions, either on an unmodified basis, with Modifications, or
98 | as part of a Larger Work; and
99 |
100 | (b) under Patent Claims of such Contributor to make, use, sell, offer
101 | for sale, have made, import, and otherwise transfer either its
102 | Contributions or its Contributor Version.
103 |
104 | 2.2. Effective Date
105 |
106 | The licenses granted in Section 2.1 with respect to any Contribution
107 | become effective for each Contribution on the date the Contributor first
108 | distributes such Contribution.
109 |
110 | 2.3. Limitations on Grant Scope
111 |
112 | The licenses granted in this Section 2 are the only rights granted under
113 | this License. No additional rights or licenses will be implied from the
114 | distribution or licensing of Covered Software under this License.
115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a
116 | Contributor:
117 |
118 | (a) for any code that a Contributor has removed from Covered Software;
119 | or
120 |
121 | (b) for infringements caused by: (i) Your and any other third party's
122 | modifications of Covered Software, or (ii) the combination of its
123 | Contributions with other software (except as part of its Contributor
124 | Version); or
125 |
126 | (c) under Patent Claims infringed by Covered Software in the absence of
127 | its Contributions.
128 |
129 | This License does not grant any rights in the trademarks, service marks,
130 | or logos of any Contributor (except as may be necessary to comply with
131 | the notice requirements in Section 3.4).
132 |
133 | 2.4. Subsequent Licenses
134 |
135 | No Contributor makes additional grants as a result of Your choice to
136 | distribute the Covered Software under a subsequent version of this
137 | License (see Section 10.2) or under the terms of a Secondary License (if
138 | permitted under the terms of Section 3.3).
139 |
140 | 2.5. Representation
141 |
142 | Each Contributor represents that the Contributor believes its
143 | Contributions are its original creation(s) or it has sufficient rights
144 | to grant the rights to its Contributions conveyed by this License.
145 |
146 | 2.6. Fair Use
147 |
148 | This License is not intended to limit any rights You have under
149 | applicable copyright doctrines of fair use, fair dealing, or other
150 | equivalents.
151 |
152 | 2.7. Conditions
153 |
154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
155 | in Section 2.1.
156 |
157 | 3. Responsibilities
158 | -------------------
159 |
160 | 3.1. Distribution of Source Form
161 |
162 | All distribution of Covered Software in Source Code Form, including any
163 | Modifications that You create or to which You contribute, must be under
164 | the terms of this License. You must inform recipients that the Source
165 | Code Form of the Covered Software is governed by the terms of this
166 | License, and how they can obtain a copy of this License. You may not
167 | attempt to alter or restrict the recipients' rights in the Source Code
168 | Form.
169 |
170 | 3.2. Distribution of Executable Form
171 |
172 | If You distribute Covered Software in Executable Form then:
173 |
174 | (a) such Covered Software must also be made available in Source Code
175 | Form, as described in Section 3.1, and You must inform recipients of
176 | the Executable Form how they can obtain a copy of such Source Code
177 | Form by reasonable means in a timely manner, at a charge no more
178 | than the cost of distribution to the recipient; and
179 |
180 | (b) You may distribute such Executable Form under the terms of this
181 | License, or sublicense it under different terms, provided that the
182 | license for the Executable Form does not attempt to limit or alter
183 | the recipients' rights in the Source Code Form under this License.
184 |
185 | 3.3. Distribution of a Larger Work
186 |
187 | You may create and distribute a Larger Work under terms of Your choice,
188 | provided that You also comply with the requirements of this License for
189 | the Covered Software. If the Larger Work is a combination of Covered
190 | Software with a work governed by one or more Secondary Licenses, and the
191 | Covered Software is not Incompatible With Secondary Licenses, this
192 | License permits You to additionally distribute such Covered Software
193 | under the terms of such Secondary License(s), so that the recipient of
194 | the Larger Work may, at their option, further distribute the Covered
195 | Software under the terms of either this License or such Secondary
196 | License(s).
197 |
198 | 3.4. Notices
199 |
200 | You may not remove or alter the substance of any license notices
201 | (including copyright notices, patent notices, disclaimers of warranty,
202 | or limitations of liability) contained within the Source Code Form of
203 | the Covered Software, except that You may alter any license notices to
204 | the extent required to remedy known factual inaccuracies.
205 |
206 | 3.5. Application of Additional Terms
207 |
208 | You may choose to offer, and to charge a fee for, warranty, support,
209 | indemnity or liability obligations to one or more recipients of Covered
210 | Software. However, You may do so only on Your own behalf, and not on
211 | behalf of any Contributor. You must make it absolutely clear that any
212 | such warranty, support, indemnity, or liability obligation is offered by
213 | You alone, and You hereby agree to indemnify every Contributor for any
214 | liability incurred by such Contributor as a result of warranty, support,
215 | indemnity or liability terms You offer. You may include additional
216 | disclaimers of warranty and limitations of liability specific to any
217 | jurisdiction.
218 |
219 | 4. Inability to Comply Due to Statute or Regulation
220 | ---------------------------------------------------
221 |
222 | If it is impossible for You to comply with any of the terms of this
223 | License with respect to some or all of the Covered Software due to
224 | statute, judicial order, or regulation then You must: (a) comply with
225 | the terms of this License to the maximum extent possible; and (b)
226 | describe the limitations and the code they affect. Such description must
227 | be placed in a text file included with all distributions of the Covered
228 | Software under this License. Except to the extent prohibited by statute
229 | or regulation, such description must be sufficiently detailed for a
230 | recipient of ordinary skill to be able to understand it.
231 |
232 | 5. Termination
233 | --------------
234 |
235 | 5.1. The rights granted under this License will terminate automatically
236 | if You fail to comply with any of its terms. However, if You become
237 | compliant, then the rights granted under this License from a particular
238 | Contributor are reinstated (a) provisionally, unless and until such
239 | Contributor explicitly and finally terminates Your grants, and (b) on an
240 | ongoing basis, if such Contributor fails to notify You of the
241 | non-compliance by some reasonable means prior to 60 days after You have
242 | come back into compliance. Moreover, Your grants from a particular
243 | Contributor are reinstated on an ongoing basis if such Contributor
244 | notifies You of the non-compliance by some reasonable means, this is the
245 | first time You have received notice of non-compliance with this License
246 | from such Contributor, and You become compliant prior to 30 days after
247 | Your receipt of the notice.
248 |
249 | 5.2. If You initiate litigation against any entity by asserting a patent
250 | infringement claim (excluding declaratory judgment actions,
251 | counter-claims, and cross-claims) alleging that a Contributor Version
252 | directly or indirectly infringes any patent, then the rights granted to
253 | You by any and all Contributors for the Covered Software under Section
254 | 2.1 of this License shall terminate.
255 |
256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all
257 | end user license agreements (excluding distributors and resellers) which
258 | have been validly granted by You or Your distributors under this License
259 | prior to termination shall survive termination.
260 |
261 | ************************************************************************
262 | * *
263 | * 6. Disclaimer of Warranty *
264 | * ------------------------- *
265 | * *
266 | * Covered Software is provided under this License on an "as is" *
267 | * basis, without warranty of any kind, either expressed, implied, or *
268 | * statutory, including, without limitation, warranties that the *
269 | * Covered Software is free of defects, merchantable, fit for a *
270 | * particular purpose or non-infringing. The entire risk as to the *
271 | * quality and performance of the Covered Software is with You. *
272 | * Should any Covered Software prove defective in any respect, You *
273 | * (not any Contributor) assume the cost of any necessary servicing, *
274 | * repair, or correction. This disclaimer of warranty constitutes an *
275 | * essential part of this License. No use of any Covered Software is *
276 | * authorized under this License except under this disclaimer. *
277 | * *
278 | ************************************************************************
279 |
280 | ************************************************************************
281 | * *
282 | * 7. Limitation of Liability *
283 | * -------------------------- *
284 | * *
285 | * Under no circumstances and under no legal theory, whether tort *
286 | * (including negligence), contract, or otherwise, shall any *
287 | * Contributor, or anyone who distributes Covered Software as *
288 | * permitted above, be liable to You for any direct, indirect, *
289 | * special, incidental, or consequential damages of any character *
290 | * including, without limitation, damages for lost profits, loss of *
291 | * goodwill, work stoppage, computer failure or malfunction, or any *
292 | * and all other commercial damages or losses, even if such party *
293 | * shall have been informed of the possibility of such damages. This *
294 | * limitation of liability shall not apply to liability for death or *
295 | * personal injury resulting from such party's negligence to the *
296 | * extent applicable law prohibits such limitation. Some *
297 | * jurisdictions do not allow the exclusion or limitation of *
298 | * incidental or consequential damages, so this exclusion and *
299 | * limitation may not apply to You. *
300 | * *
301 | ************************************************************************
302 |
303 | 8. Litigation
304 | -------------
305 |
306 | Any litigation relating to this License may be brought only in the
307 | courts of a jurisdiction where the defendant maintains its principal
308 | place of business and such litigation shall be governed by laws of that
309 | jurisdiction, without reference to its conflict-of-law provisions.
310 | Nothing in this Section shall prevent a party's ability to bring
311 | cross-claims or counter-claims.
312 |
313 | 9. Miscellaneous
314 | ----------------
315 |
316 | This License represents the complete agreement concerning the subject
317 | matter hereof. If any provision of this License is held to be
318 | unenforceable, such provision shall be reformed only to the extent
319 | necessary to make it enforceable. Any law or regulation which provides
320 | that the language of a contract shall be construed against the drafter
321 | shall not be used to construe this License against a Contributor.
322 |
323 | 10. Versions of the License
324 | ---------------------------
325 |
326 | 10.1. New Versions
327 |
328 | Mozilla Foundation is the license steward. Except as provided in Section
329 | 10.3, no one other than the license steward has the right to modify or
330 | publish new versions of this License. Each version will be given a
331 | distinguishing version number.
332 |
333 | 10.2. Effect of New Versions
334 |
335 | You may distribute the Covered Software under the terms of the version
336 | of the License under which You originally received the Covered Software,
337 | or under the terms of any subsequent version published by the license
338 | steward.
339 |
340 | 10.3. Modified Versions
341 |
342 | If you create software not governed by this License, and you want to
343 | create a new license for such software, you may create and use a
344 | modified version of this License if you rename the license and remove
345 | any references to the name of the license steward (except to note that
346 | such modified license differs from this License).
347 |
348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary
349 | Licenses
350 |
351 | If You choose to distribute Source Code Form that is Incompatible With
352 | Secondary Licenses under the terms of this version of the License, the
353 | notice described in Exhibit B of this License must be attached.
354 |
355 | Exhibit A - Source Code Form License Notice
356 | -------------------------------------------
357 |
358 | This Source Code Form is subject to the terms of the Mozilla Public
359 | License, v. 2.0. If a copy of the MPL was not distributed with this
360 | file, You can obtain one at http://mozilla.org/MPL/2.0/.
361 |
362 | If it is not possible or desirable to put the notice in a particular
363 | file, then You may include the notice in a location (such as a LICENSE
364 | file in a relevant directory) where a recipient would be likely to look
365 | for such a notice.
366 |
367 | You may add additional accurate notices of copyright ownership.
368 |
369 | Exhibit B - "Incompatible With Secondary Licenses" Notice
370 | ---------------------------------------------------------
371 |
372 | This Source Code Form is "Incompatible With Secondary Licenses", as
373 | defined by the Mozilla Public License, v. 2.0.
374 |
--------------------------------------------------------------------------------
/wsdl/receiver.wsdl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | The capabilities for the receiver service is returned in the Capabilities element.
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | Indicates that the device can receive RTP multicast streams.
41 |
42 |
43 |
44 |
45 | Indicates that the device can receive RTP/TCP streams
46 |
47 |
48 |
49 |
50 | Indicates that the device can receive RTP/RTSP/TCP streams.
51 |
52 |
53 |
54 |
55 | The maximum number of receivers supported by the device.
56 |
57 |
58 |
59 |
60 | The maximum allowed length for RTSP URIs (Minimum and default value is 128 octet).
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | A list of all receivers that currently exist on the device.
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | The token of the receiver to be retrieved.
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | The details of the receiver.
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | The initial configuration for the new receiver.
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | The details of the receiver that was created.
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 | The token of the receiver to be deleted.
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 | The token of the receiver to be configured.
151 |
152 |
153 |
154 |
155 | The new configuration for the receiver.
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 | The token of the receiver to be changed.
173 |
174 |
175 |
176 |
177 | The new receiver mode. Options available are:
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 | The token of the receiver to be queried.
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 | Description of the current receiver state.
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 | Returns the capabilities of the receiver service. The result is returned in a typed answer.
264 |
265 |
266 |
267 |
268 |
269 | Lists all receivers currently present on a device. This operation is mandatory.
270 |
271 |
272 |
273 |
274 |
275 |
276 | Retrieves the details of a specific receiver. This operation is mandatory.
277 |
278 |
279 |
280 |
281 |
282 |
283 | Creates a new receiver. This operation is mandatory, although the service may
284 | raise a fault if the receiver cannot be created.
285 |
286 |
287 |
288 |
289 |
290 |
291 | Deletes an existing receiver. A receiver may be deleted only if it is not
292 | currently in use; otherwise a fault shall be raised.
293 | This operation is mandatory.
294 |
295 |
296 |
297 |
298 |
299 |
300 | Configures an existing receiver. This operation is mandatory.
301 |
302 |
303 |
304 |
305 |
306 |
307 | Sets the mode of the receiver without affecting the rest of its configuration.
308 | This operation is mandatory.
309 |
310 |
311 |
312 |
313 |
314 |
315 | Determines whether the receiver is currently disconnected, connected or
316 | attempting to connect.
317 | This operation is mandatory.
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
--------------------------------------------------------------------------------
/profiles/accessrules/accessrules.go:
--------------------------------------------------------------------------------
1 | package accessrules
2 |
3 | import (
4 | "context"
5 | "encoding/xml"
6 | "github.com/videonext/onvif/soap"
7 | "time"
8 | )
9 |
10 | // against "unused imports"
11 | var _ time.Time
12 | var _ xml.Name
13 |
14 | // GetServiceCapabilities type
15 | type GetServiceCapabilities struct {
16 | XMLName xml.Name `xml:"http://www.onvif.org/ver10/accessrules/wsdl GetServiceCapabilities"`
17 | }
18 |
19 | // GetServiceCapabilitiesResponse type
20 | type GetServiceCapabilitiesResponse struct {
21 | XMLName xml.Name `xml:"GetServiceCapabilitiesResponse"`
22 |
23 | // The capability response message contains the requested access rules
24 | // service capabilities using a hierarchical XML capability structure.
25 | //
26 | Capabilities ServiceCapabilities `xml:"Capabilities,omitempty"`
27 | }
28 |
29 | // GetAccessProfileInfo type
30 | type GetAccessProfileInfo struct {
31 | XMLName xml.Name `xml:"http://www.onvif.org/ver10/accessrules/wsdl GetAccessProfileInfo"`
32 |
33 | // Tokens of AccessProfileInfo items to get.
34 | Token []ReferenceToken `xml:"http://www.onvif.org/ver10/accessrules/wsdl Token,omitempty"`
35 | }
36 |
37 | // GetAccessProfileInfoResponse type
38 | type GetAccessProfileInfoResponse struct {
39 | XMLName xml.Name `xml:"GetAccessProfileInfoResponse"`
40 |
41 | // List of AccessProfileInfo items.
42 | AccessProfileInfo []AccessProfileInfo `xml:"AccessProfileInfo,omitempty"`
43 | }
44 |
45 | // GetAccessProfileInfoList type
46 | type GetAccessProfileInfoList struct {
47 | XMLName xml.Name `xml:"http://www.onvif.org/ver10/accessrules/wsdl GetAccessProfileInfoList"`
48 |
49 | // Maximum number of entries to return. If not specified, less than one
50 | // or higher than what the device supports, the number of items is determined by the
51 | // device.
52 | //
53 | Limit int32 `xml:"http://www.onvif.org/ver10/schema Limit,omitempty"`
54 |
55 | // Start returning entries from this start reference. If not specified,
56 | // entries shall start from the beginning of the dataset.
57 | //
58 | StartReference string `xml:"http://www.onvif.org/ver10/accessrules/wsdl StartReference,omitempty"`
59 | }
60 |
61 | // GetAccessProfileInfoListResponse type
62 | type GetAccessProfileInfoListResponse struct {
63 | XMLName xml.Name `xml:"GetAccessProfileInfoListResponse"`
64 |
65 | // StartReference to use in next call to get the following items. If
66 | // absent, no more items to get.
67 | //
68 | NextStartReference string `xml:"NextStartReference,omitempty"`
69 |
70 | // List of AccessProfileInfo items.
71 | AccessProfileInfo []AccessProfileInfo `xml:"AccessProfileInfo,omitempty"`
72 | }
73 |
74 | // GetAccessProfiles type
75 | type GetAccessProfiles struct {
76 | XMLName xml.Name `xml:"http://www.onvif.org/ver10/accessrules/wsdl GetAccessProfiles"`
77 |
78 | // Tokens of AccessProfile items to get.
79 | Token []ReferenceToken `xml:"http://www.onvif.org/ver10/accessrules/wsdl Token,omitempty"`
80 | }
81 |
82 | // GetAccessProfilesResponse type
83 | type GetAccessProfilesResponse struct {
84 | XMLName xml.Name `xml:"GetAccessProfilesResponse"`
85 |
86 | // List of Access Profile items.
87 | AccessProfile []AccessProfile `xml:"AccessProfile,omitempty"`
88 | }
89 |
90 | // GetAccessProfileList type
91 | type GetAccessProfileList struct {
92 | XMLName xml.Name `xml:"http://www.onvif.org/ver10/accessrules/wsdl GetAccessProfileList"`
93 |
94 | // Maximum number of entries to return. If not specified, less than one
95 | // or higher than what the device supports, the number of items is determined by the
96 | // device.
97 | //
98 | Limit int32 `xml:"http://www.onvif.org/ver10/schema Limit,omitempty"`
99 |
100 | // Start returning entries from this start reference. If not specified,
101 | // entries shall start from the beginning of the dataset.
102 | //
103 | StartReference string `xml:"http://www.onvif.org/ver10/accessrules/wsdl StartReference,omitempty"`
104 | }
105 |
106 | // GetAccessProfileListResponse type
107 | type GetAccessProfileListResponse struct {
108 | XMLName xml.Name `xml:"GetAccessProfileListResponse"`
109 |
110 | // StartReference to use in next call to get the following items. If
111 | // absent, no more items to get.
112 | //
113 | NextStartReference string `xml:"NextStartReference,omitempty"`
114 |
115 | // List of Access Profile items.
116 | AccessProfile []AccessProfile `xml:"AccessProfile,omitempty"`
117 | }
118 |
119 | // CreateAccessProfile type
120 | type CreateAccessProfile struct {
121 | XMLName xml.Name `xml:"http://www.onvif.org/ver10/accessrules/wsdl CreateAccessProfile"`
122 |
123 | // The AccessProfile to create.
124 | AccessProfile AccessProfile `xml:"http://www.onvif.org/ver10/accessrules/wsdl AccessProfile,omitempty"`
125 | }
126 |
127 | // CreateAccessProfileResponse type
128 | type CreateAccessProfileResponse struct {
129 | XMLName xml.Name `xml:"CreateAccessProfileResponse"`
130 |
131 | // The Token of created AccessProfile.
132 | Token ReferenceToken `xml:"Token,omitempty"`
133 | }
134 |
135 | // ModifyAccessProfile type
136 | type ModifyAccessProfile struct {
137 | XMLName xml.Name `xml:"http://www.onvif.org/ver10/accessrules/wsdl ModifyAccessProfile"`
138 |
139 | // The details of Access Profile
140 | AccessProfile AccessProfile `xml:"http://www.onvif.org/ver10/accessrules/wsdl AccessProfile,omitempty"`
141 | }
142 |
143 | // ModifyAccessProfileResponse type
144 | type ModifyAccessProfileResponse struct {
145 | XMLName xml.Name `xml:"ModifyAccessProfileResponse"`
146 | }
147 |
148 | // SetAccessProfile type
149 | type SetAccessProfile struct {
150 | XMLName xml.Name `xml:"http://www.onvif.org/ver10/accessrules/wsdl SetAccessProfile"`
151 |
152 | // The AccessProfile item to create or modify
153 | AccessProfile AccessProfile `xml:"http://www.onvif.org/ver10/accessrules/wsdl AccessProfile,omitempty"`
154 | }
155 |
156 | // SetAccessProfileResponse type
157 | type SetAccessProfileResponse struct {
158 | XMLName xml.Name `xml:"SetAccessProfileResponse"`
159 | }
160 |
161 | // DeleteAccessProfile type
162 | type DeleteAccessProfile struct {
163 | XMLName xml.Name `xml:"http://www.onvif.org/ver10/accessrules/wsdl DeleteAccessProfile"`
164 |
165 | // The token of the access profile to delete.
166 | Token ReferenceToken `xml:"http://www.onvif.org/ver10/accessrules/wsdl Token,omitempty"`
167 | }
168 |
169 | // DeleteAccessProfileResponse type
170 | type DeleteAccessProfileResponse struct {
171 | XMLName xml.Name `xml:"DeleteAccessProfileResponse"`
172 | }
173 |
174 | // ServiceCapabilities type
175 | type ServiceCapabilities struct {
176 | XMLName xml.Name `xml:"http://www.onvif.org/ver10/accessrules/wsdl Capabilities"`
177 |
178 | //
179 | // The maximum number of entries returned by a single GetList or Get
180 | // request. The device shall never return more than this number of entities in a single
181 | // response.
182 | //
183 |
184 | MaxLimit uint32 `xml:"http://www.onvif.org/ver10/schema MaxLimit,attr,omitempty"`
185 |
186 | //
187 | // Indicates the maximum number of access profiles supported by the device.
188 | //
189 |
190 | MaxAccessProfiles uint32 `xml:"http://www.onvif.org/ver10/schema MaxAccessProfiles,attr,omitempty"`
191 |
192 | //
193 | // Indicates the maximum number of access policies per access profile supported by the device.
194 | //
195 |
196 | MaxAccessPoliciesPerAccessProfile uint32 `xml:"http://www.onvif.org/ver10/schema MaxAccessPoliciesPerAccessProfile,attr,omitempty"`
197 |
198 | //
199 | // Indicates whether or not several access policies can refer to the same access point in an
200 | // access profile.
201 | //
202 |
203 | MultipleSchedulesPerAccessPointSupported bool `xml:"http://www.onvif.org/ver10/accessrules/wsdl MultipleSchedulesPerAccessPointSupported,attr,omitempty"`
204 |
205 | //
206 | // Indicates that the client is allowed to supply the token when creating access profiles. To
207 | // enable the use of the command SetAccessProfile, the value must be set to true.
208 | //
209 |
210 | ClientSuppliedTokenSupported bool `xml:"http://www.onvif.org/ver10/accessrules/wsdl ClientSuppliedTokenSupported,attr,omitempty"`
211 | }
212 |
213 | // AccessPolicy type
214 | type AccessPolicy struct {
215 |
216 | // Reference to the schedule used by the access policy.
217 | ScheduleToken ReferenceToken `xml:"http://www.onvif.org/ver10/accessrules/wsdl ScheduleToken,omitempty"`
218 |
219 | //
220 | // Reference to the entity used by the rule engine, the entity type may be specified by the
221 | // optional EntityType field explained below but is typically an access point.
222 | //
223 | Entity ReferenceToken `xml:"http://www.onvif.org/ver10/accessrules/wsdl Entity,omitempty"`
224 |
225 | //
226 | // Optional entity type; if missing, an access point type as defined by the ONVIF Access
227 | // Control Service Specification should be assumed. This can also be represented by the
228 | // QName value “tac:AccessPoint” where tac is the namespace of ONVIF Access Control
229 | // Service Specification. This field is provided for future extensions; it will allow an
230 | // access policy being extended to cover entity types other than access points as well.
231 | //
232 | EntityType QName `xml:"http://www.onvif.org/ver10/accessrules/wsdl EntityType,omitempty"`
233 |
234 | Extension AccessPolicyExtension `xml:"http://www.onvif.org/ver10/accessrules/wsdl Extension,omitempty"`
235 | }
236 |
237 | // AccessPolicyExtension type
238 | type AccessPolicyExtension struct {
239 | }
240 |
241 | // AccessProfileInfo type
242 | type AccessProfileInfo struct {
243 | *DataEntity
244 |
245 | // A user readable name. It shall be up to 64 characters.
246 | //
247 | Name Name `xml:"http://www.onvif.org/ver10/accessrules/wsdl Name,omitempty"`
248 |
249 | // User readable description for the access profile. It shall be up
250 | // to 1024 characters.
251 | //
252 | Description Description `xml:"http://www.onvif.org/ver10/accessrules/wsdl Description,omitempty"`
253 | }
254 |
255 | // AccessProfile type
256 | type AccessProfile struct {
257 | *AccessProfileInfo
258 |
259 | // A list of access policy structures, where each access policy
260 | // defines during which schedule an access point can be accessed.
261 | //
262 | AccessPolicy []AccessPolicy `xml:"http://www.onvif.org/ver10/accessrules/wsdl AccessPolicy,omitempty"`
263 |
264 | Extension AccessProfileExtension `xml:"http://www.onvif.org/ver10/accessrules/wsdl Extension,omitempty"`
265 | }
266 |
267 | // AccessProfileExtension type
268 | type AccessProfileExtension struct {
269 | }
270 |
271 | // Type used to reference logical and physical entities.
272 |
273 | // ReferenceToken type
274 | type ReferenceToken string
275 |
276 | // Type used for names of logical and physical entities.
277 |
278 | // Name type
279 | type Name string
280 |
281 | // Description is optional and the maximum length is device specific.
282 | // If the length is more than maximum length, it is silently chopped to the maximum length
283 | // supported by the device/service (which may be 0).
284 | //
285 |
286 | // Description type
287 | type Description string
288 |
289 | // Type used to represent the numbers from 1 ,2 , 3,...
290 |
291 | // DataEntity type
292 | type DataEntity struct {
293 |
294 | // A service-unique identifier of the item.
295 |
296 | Token ReferenceToken `xml:"token,attr,omitempty"`
297 | }
298 |
299 | // AccessRulesPort type
300 | type AccessRulesPort interface {
301 |
302 | /* This operation returns the capabilities of the access rules service.
303 | */
304 | GetServiceCapabilities(request *GetServiceCapabilities) (*GetServiceCapabilitiesResponse, error)
305 |
306 | GetServiceCapabilitiesContext(ctx context.Context, request *GetServiceCapabilities) (*GetServiceCapabilitiesResponse, error)
307 |
308 | /*
309 | This operation requests a list of AccessProfileInfo items matching the given tokens. The device shall
310 | ignore tokens it cannot resolve and shall return an empty list if there are no items matching the
311 | specified tokens. The device shall not return a fault in this case.
312 | If the number of requested items is greater than MaxLimit, a TooManyItems fault shall be returned.
313 | */
314 | GetAccessProfileInfo(request *GetAccessProfileInfo) (*GetAccessProfileInfoResponse, error)
315 |
316 | GetAccessProfileInfoContext(ctx context.Context, request *GetAccessProfileInfo) (*GetAccessProfileInfoResponse, error)
317 |
318 | /*
319 | This operation requests a list of all of AccessProfileInfo items provided by the device.
320 | A call to this method shall return a StartReference when not all data is returned and more data is
321 | available. The reference shall be valid for retrieving the next set of data.
322 | The number of items returned shall not be greater than the Limit parameter.
323 | */
324 | GetAccessProfileInfoList(request *GetAccessProfileInfoList) (*GetAccessProfileInfoListResponse, error)
325 |
326 | GetAccessProfileInfoListContext(ctx context.Context, request *GetAccessProfileInfoList) (*GetAccessProfileInfoListResponse, error)
327 |
328 | /*
329 | This operation returns the specified access profile item matching the given tokens.
330 | The device shall ignore tokens it cannot resolve and shall return an empty list if there are no items
331 | matching specified tokens. The device shall not return a fault in this case.
332 | If the number of requested items is greater than MaxLimit, a TooManyItems fault shall be returned.
333 | */
334 | GetAccessProfiles(request *GetAccessProfiles) (*GetAccessProfilesResponse, error)
335 |
336 | GetAccessProfilesContext(ctx context.Context, request *GetAccessProfiles) (*GetAccessProfilesResponse, error)
337 |
338 | /*
339 | This operation requests a list of all of access profile items provided by the device.
340 | A call to this method shall return a StartReference when not all data is returned and more data is
341 | available. The reference shall be valid for retrieving the next set of data.
342 | The number of items returned shall not be greater than the Limit parameter.
343 | */
344 | GetAccessProfileList(request *GetAccessProfileList) (*GetAccessProfileListResponse, error)
345 |
346 | GetAccessProfileListContext(ctx context.Context, request *GetAccessProfileList) (*GetAccessProfileListResponse, error)
347 |
348 | /*
349 | This operation creates the specified access profile in the device. The token field of the access profile shall be
350 | empty, the service shall allocate a token for the access profile. The allocated token shall be returned
351 | in the response. If the client sends any value in the token field, the device shall return InvalidArgVal
352 | as generic fault code.
353 | In an access profile, if several access policies specifying different schedules for the same access
354 | point will result in a union of the schedules.
355 | */
356 | CreateAccessProfile(request *CreateAccessProfile) (*CreateAccessProfileResponse, error)
357 |
358 | CreateAccessProfileContext(ctx context.Context, request *CreateAccessProfile) (*CreateAccessProfileResponse, error)
359 |
360 | /*
361 | This operation will modify the access profile for the specified access profile token. The token of the
362 | access profile to modify is specified in the token field of the AccessProile structure and shall not
363 | be empty. All other fields in the structure shall overwrite the fields in the specified access profile.
364 | If several access policies specifying different schedules for the same access point will result in a
365 | union of the schedules.
366 | If the device could not store the access profile information then a fault will be generated.
367 | */
368 | ModifyAccessProfile(request *ModifyAccessProfile) (*ModifyAccessProfileResponse, error)
369 |
370 | ModifyAccessProfileContext(ctx context.Context, request *ModifyAccessProfile) (*ModifyAccessProfileResponse, error)
371 |
372 | /*
373 | This operation will synchronize an access profile in a client with the device.
374 | If an access profile with the specified token does not exist in the device, the access profile is
375 | created. If an access profile with the specified token exists, then the access profile is modified.
376 | A call to this method takes an access profile structure as input parameter. The token field of the
377 | access profile must not be empty.
378 | A device that signals support for the ClientSuppliedTokenSupported capability shall implement this command.
379 | */
380 | SetAccessProfile(request *SetAccessProfile) (*SetAccessProfileResponse, error)
381 |
382 | SetAccessProfileContext(ctx context.Context, request *SetAccessProfile) (*SetAccessProfileResponse, error)
383 |
384 | /*
385 | This operation will delete the specified access profile.
386 | If the access profile is deleted, all access policies associated to the access profile will also be
387 | deleted.
388 | If it is associated with one or more entities some devices may not be able to delete the access profile,
389 | and consequently a ReferenceInUse fault shall be generated.
390 | */
391 | DeleteAccessProfile(request *DeleteAccessProfile) (*DeleteAccessProfileResponse, error)
392 |
393 | DeleteAccessProfileContext(ctx context.Context, request *DeleteAccessProfile) (*DeleteAccessProfileResponse, error)
394 | }
395 |
396 | // accessRulesPort type
397 | type accessRulesPort struct {
398 | client *soap.Client
399 | xaddr string
400 | }
401 |
402 | func NewAccessRulesPort(client *soap.Client, xaddr string) AccessRulesPort {
403 | return &accessRulesPort{
404 | client: client,
405 | xaddr: xaddr,
406 | }
407 | }
408 |
409 | func (service *accessRulesPort) GetServiceCapabilitiesContext(ctx context.Context, request *GetServiceCapabilities) (*GetServiceCapabilitiesResponse, error) {
410 | response := new(GetServiceCapabilitiesResponse)
411 | err := service.client.CallContext(ctx, service.xaddr, "http://www.onvif.org/ver10/accessrules/wsdl/GetServiceCapabilities", request, response)
412 | if err != nil {
413 | return nil, err
414 | }
415 |
416 | return response, nil
417 | }
418 |
419 | func (service *accessRulesPort) GetServiceCapabilities(request *GetServiceCapabilities) (*GetServiceCapabilitiesResponse, error) {
420 | return service.GetServiceCapabilitiesContext(
421 | context.Background(),
422 | request,
423 | )
424 | }
425 |
426 | func (service *accessRulesPort) GetAccessProfileInfoContext(ctx context.Context, request *GetAccessProfileInfo) (*GetAccessProfileInfoResponse, error) {
427 | response := new(GetAccessProfileInfoResponse)
428 | err := service.client.CallContext(ctx, service.xaddr, "http://www.onvif.org/ver10/accessrules/wsdl/GetAccessProfileInfo", request, response)
429 | if err != nil {
430 | return nil, err
431 | }
432 |
433 | return response, nil
434 | }
435 |
436 | func (service *accessRulesPort) GetAccessProfileInfo(request *GetAccessProfileInfo) (*GetAccessProfileInfoResponse, error) {
437 | return service.GetAccessProfileInfoContext(
438 | context.Background(),
439 | request,
440 | )
441 | }
442 |
443 | func (service *accessRulesPort) GetAccessProfileInfoListContext(ctx context.Context, request *GetAccessProfileInfoList) (*GetAccessProfileInfoListResponse, error) {
444 | response := new(GetAccessProfileInfoListResponse)
445 | err := service.client.CallContext(ctx, service.xaddr, "http://www.onvif.org/ver10/accessrules/wsdl/GetAccessProfileInfoList", request, response)
446 | if err != nil {
447 | return nil, err
448 | }
449 |
450 | return response, nil
451 | }
452 |
453 | func (service *accessRulesPort) GetAccessProfileInfoList(request *GetAccessProfileInfoList) (*GetAccessProfileInfoListResponse, error) {
454 | return service.GetAccessProfileInfoListContext(
455 | context.Background(),
456 | request,
457 | )
458 | }
459 |
460 | func (service *accessRulesPort) GetAccessProfilesContext(ctx context.Context, request *GetAccessProfiles) (*GetAccessProfilesResponse, error) {
461 | response := new(GetAccessProfilesResponse)
462 | err := service.client.CallContext(ctx, service.xaddr, "http://www.onvif.org/ver10/accessrules/wsdl/GetAccessProfiles", request, response)
463 | if err != nil {
464 | return nil, err
465 | }
466 |
467 | return response, nil
468 | }
469 |
470 | func (service *accessRulesPort) GetAccessProfiles(request *GetAccessProfiles) (*GetAccessProfilesResponse, error) {
471 | return service.GetAccessProfilesContext(
472 | context.Background(),
473 | request,
474 | )
475 | }
476 |
477 | func (service *accessRulesPort) GetAccessProfileListContext(ctx context.Context, request *GetAccessProfileList) (*GetAccessProfileListResponse, error) {
478 | response := new(GetAccessProfileListResponse)
479 | err := service.client.CallContext(ctx, service.xaddr, "http://www.onvif.org/ver10/accessrules/wsdl/GetAccessProfileList", request, response)
480 | if err != nil {
481 | return nil, err
482 | }
483 |
484 | return response, nil
485 | }
486 |
487 | func (service *accessRulesPort) GetAccessProfileList(request *GetAccessProfileList) (*GetAccessProfileListResponse, error) {
488 | return service.GetAccessProfileListContext(
489 | context.Background(),
490 | request,
491 | )
492 | }
493 |
494 | func (service *accessRulesPort) CreateAccessProfileContext(ctx context.Context, request *CreateAccessProfile) (*CreateAccessProfileResponse, error) {
495 | response := new(CreateAccessProfileResponse)
496 | err := service.client.CallContext(ctx, service.xaddr, "http://www.onvif.org/ver10/accessrules/wsdl/CreateAccessProfile", request, response)
497 | if err != nil {
498 | return nil, err
499 | }
500 |
501 | return response, nil
502 | }
503 |
504 | func (service *accessRulesPort) CreateAccessProfile(request *CreateAccessProfile) (*CreateAccessProfileResponse, error) {
505 | return service.CreateAccessProfileContext(
506 | context.Background(),
507 | request,
508 | )
509 | }
510 |
511 | func (service *accessRulesPort) ModifyAccessProfileContext(ctx context.Context, request *ModifyAccessProfile) (*ModifyAccessProfileResponse, error) {
512 | response := new(ModifyAccessProfileResponse)
513 | err := service.client.CallContext(ctx, service.xaddr, "http://www.onvif.org/ver10/accessrules/wsdl/ModifyAccessProfile", request, response)
514 | if err != nil {
515 | return nil, err
516 | }
517 |
518 | return response, nil
519 | }
520 |
521 | func (service *accessRulesPort) ModifyAccessProfile(request *ModifyAccessProfile) (*ModifyAccessProfileResponse, error) {
522 | return service.ModifyAccessProfileContext(
523 | context.Background(),
524 | request,
525 | )
526 | }
527 |
528 | func (service *accessRulesPort) SetAccessProfileContext(ctx context.Context, request *SetAccessProfile) (*SetAccessProfileResponse, error) {
529 | response := new(SetAccessProfileResponse)
530 | err := service.client.CallContext(ctx, service.xaddr, "http://www.onvif.org/ver10/accessrules/wsdl/SetAccessProfile", request, response)
531 | if err != nil {
532 | return nil, err
533 | }
534 |
535 | return response, nil
536 | }
537 |
538 | func (service *accessRulesPort) SetAccessProfile(request *SetAccessProfile) (*SetAccessProfileResponse, error) {
539 | return service.SetAccessProfileContext(
540 | context.Background(),
541 | request,
542 | )
543 | }
544 |
545 | func (service *accessRulesPort) DeleteAccessProfileContext(ctx context.Context, request *DeleteAccessProfile) (*DeleteAccessProfileResponse, error) {
546 | response := new(DeleteAccessProfileResponse)
547 | err := service.client.CallContext(ctx, service.xaddr, "http://www.onvif.org/ver10/accessrules/wsdl/DeleteAccessProfile", request, response)
548 | if err != nil {
549 | return nil, err
550 | }
551 |
552 | return response, nil
553 | }
554 |
555 | func (service *accessRulesPort) DeleteAccessProfile(request *DeleteAccessProfile) (*DeleteAccessProfileResponse, error) {
556 | return service.DeleteAccessProfileContext(
557 | context.Background(),
558 | request,
559 | )
560 | }
561 |
562 | // QName type
563 | type QName string
564 |
--------------------------------------------------------------------------------
/wsdl/display.wsdl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | The capabilities for the display service is returned in the Capabilities element.
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | Indication that the SetLayout command supports only predefined layouts.
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | Token of the Video Output whose Layout is requested
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | Current layout of the video output.
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | Token of the Video Output whose Layout shall be changed.
74 |
75 |
76 |
77 |
78 | Layout to be set
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | Token of the Video Output whose options are requested
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 | The LayoutOptions describe the fixed and predefined layouts of a device. If the device does
113 | not offer fixed layouts and allows setting the layout free this element is empty.
114 |
115 |
116 |
117 |
118 | decoding and encoding capabilities of the device
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 | Reference Token of the Video Output whose Pane Configurations are requested
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 | Contains a list of defined Panes of the specified VideoOutput. Each VideoOutput has at least one PaneConfiguration.
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 | Reference Token of the Video Output the requested pane belongs to
157 |
158 |
159 |
160 |
161 | Reference Token of the Pane whose Configuration is requested
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 | returns the configuration of the requested pane.
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 | Token of the video output whose panes to set.
188 |
189 |
190 |
191 |
192 | Pane Configuration to be set.
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 | Token of the video output whose panes to set.
213 |
214 |
215 |
216 |
217 | Pane Configuration to be set.
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 | Token of the video output where the pane shall be created.
239 |
240 |
241 |
242 |
243 | Configuration of the pane to be created.
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 | Token of the new pane configuration.
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 | Token of the video output where the pane shall be deleted.
270 |
271 |
272 |
273 |
274 | Token of the pane to be deleted.
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 | Returns the capabilities of the display service. The result is returned in a typed answer.
354 |
355 |
356 |
357 |
358 | Return the current layout of a video output. The Layout assigns a pane configuration to a certain area of the display. The layout settings
359 | directly affect a specific video output. The layout consists of a list of PaneConfigurations and
360 | their associated display areas.
361 |
362 |
363 |
364 |
365 | Change the layout of a display (e.g. change from
366 | single view to split screen view).The Layout assigns a pane configuration to a certain area of the display. The layout settings
367 | directly affect a specific video output. The layout consists of a list of PaneConfigurations and
368 | their associated display areas.
369 | A device implementation shall be tolerant against rounding errors when matching a layout against its fixed set of layouts by accepting differences of at least one percent.
370 |
371 |
372 |
373 |
374 |
375 | The Display Options contain the supported layouts (LayoutOptions) and the decoding and
376 | encoding capabilities (CodingCapabilities) of the device. The GetDisplayOptions command
377 | returns both, Layout and Coding Capabilities, of a VideoOutput.
378 |
379 |
380 |
381 |
382 | List all currently defined panes of a device for a specified video output
383 | (regardless if this pane is visible at a moment). A Pane is a display area on the monitor that is attached to a video output. A pane has a
384 | PaneConfiguration that describes which entities are associated with the pane. A client has to configure the pane according to the connection to be established by setting the
385 | AudioOutput and/or AudioSourceToken. If a Token is not set, the corresponding session will
386 | not be established.
387 |
388 |
389 |
390 |
391 | Retrieve the pane configuration for a pane token.
392 |
393 |
394 |
395 |
396 | Modify one or more configurations of the specified video output.
397 | This method will only modify the provided configurations and leave the others unchanged.
398 | Use DeletePaneConfiguration to remove pane configurations.
399 |
400 |
401 |
402 |
403 | This command changes the configuration of the specified pane (tbd)
404 |
405 |
406 |
407 |
408 | Create a new pane configuration describing the streaming and coding settings for a display area.
409 | This optional method is only supported by devices that signal support of dynamic pane creation via their capabilities.
410 | The content of the Token field may be ignored by the device.
411 |
412 |
413 |
414 |
415 |
416 | Delete a pane configuration. A service must respond with an error if the pane configuration
417 | is in use by the current layout.
418 | This optional method is only supported by devices that signal support of dynamic pane creation via their capabilities.
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
--------------------------------------------------------------------------------
/wsdl/provisioning.wsdl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | The direction for PanMove to move the device.
21 |
22 |
23 |
24 |
25 | Move left in relation to the video source image.
26 |
27 |
28 |
29 |
30 | Move right in relation to the video source image.
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | The direction for TiltMove to move the device.
39 |
40 |
41 |
42 |
43 | Move up in relation to the video source image.
44 |
45 |
46 |
47 |
48 | Move down in relation to the video source image.
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | The direction for ZoomMove to change the focal length in relation to the video source.
57 |
58 |
59 |
60 |
61 | Move video source lens toward a wider field of view.
62 |
63 |
64 |
65 |
66 | Move video source lens toward a narrower field of view.
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | The direction for RollMove to move the device.
75 |
76 |
77 |
78 |
79 | Move clockwise in relation to the video source image.
80 |
81 |
82 |
83 |
84 | Move counterclockwise in relation to the video source image.
85 |
86 |
87 |
88 |
89 | Automatically level the device in relation to the video source image.
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | The direction for FocusMove to move the focal plane in relation to the video source.
98 |
99 |
100 |
101 |
102 | Move to focus on close objects.
103 |
104 |
105 |
106 |
107 | Move to focus on distant objects.
108 |
109 |
110 |
111 |
112 | Automatically focus for the sharpest video source image.
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 | The quantity of movement events that have occured over the lifetime of the device.
121 |
122 |
123 |
124 |
125 | The quantity of pan movement events over the life of the device.
126 |
127 |
128 |
129 |
130 | The quantity of tilt movement events over the life of the device.
131 |
132 |
133 |
134 |
135 | The quantity of zoom movement events over the life of the device.
136 |
137 |
138 |
139 |
140 | The quantity of roll movement events over the life of the device.
141 |
142 |
143 |
144 |
145 | The quantity of focus movement events over the life of the device.
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 | The provisioning capabilities of a video source on the device.
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 | Unique identifier of a video source.
165 |
166 |
167 |
168 |
169 | Lifetime limit of pan moves for this video source. Presence of this attribute indicates support of pan move.
170 |
171 |
172 |
173 |
174 | Lifetime limit of tilt moves for this video source. Presence of this attribute indicates support of tilt move.
175 |
176 |
177 |
178 |
179 | Lifetime limit of zoom moves for this video source. Presence of this attribute indicates support of zoom move.
180 |
181 |
182 |
183 |
184 | Lifetime limit of roll moves for this video source. Presence of this attribute indicates support of roll move.
185 |
186 |
187 |
188 |
189 | Indicates "auto" as a valid enum for Direction in RollMove.
190 |
191 |
192 |
193 |
194 | Lifetime limit of focus moves for this video source. Presence of this attribute indicates support of focus move.
195 |
196 |
197 |
198 |
199 | Indicates "auto" as a valid enum for Direction in FocusMove.
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 | The capabilities of Provisioning Service on the device.
208 |
209 |
210 |
211 |
212 | Maximum time before stopping movement after a move operation.
213 |
214 |
215 |
216 |
217 | Capabilities per video source.
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 | The capabilities for the provisioning service on this device.
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 | The video source associated with the provisioning.
252 |
253 |
254 |
255 |
256 | "left" or "right".
257 |
258 |
259 |
260 |
261 | "Operation timeout, if less than default timeout.
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 | The video source associated with the provisioning.
279 |
280 |
281 |
282 |
283 | "up" or "down".
284 |
285 |
286 |
287 |
288 | "Operation timeout, if less than default timeout.
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 | The video source associated with the provisioning.
306 |
307 |
308 |
309 |
310 | "wide" or "telephoto".
311 |
312 |
313 |
314 |
315 | "Operation timeout, if less than default timeout.
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 | The video source associated with the provisioning.
333 |
334 |
335 |
336 |
337 | "clockwise", "counterclockwise", or "auto".
338 |
339 |
340 |
341 |
342 | "Operation timeout, if less than default timeout.
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 | The video source associated with the provisioning.
360 |
361 |
362 |
363 |
364 | "near", "far", or "auto".
365 |
366 |
367 |
368 |
369 | "Operation timeout, if less than default timeout.
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 | The video source associated with the provisioning.
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 | The video source associated with the provisioning.
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 | The set of lifetime usage values for the provisioning associated with the video source.
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 | Functionality for all provisioning service operations.
472 |
473 | Returns the capabilities of the provisioning service.
474 |
475 |
476 |
477 |
478 | Moves device on the pan axis.
479 |
480 |
481 |
482 |
483 | Moves device on the tilt axis.
484 |
485 |
486 |
487 |
488 | Moves device on the zoom axis.
489 |
490 |
491 |
492 |
493 | Moves device on the roll axis.
494 |
495 |
496 |
497 |
498 | Moves device on the focus axis.
499 |
500 |
501 |
502 |
503 | Stops device motion on all axes.
504 |
505 |
506 |
507 |
508 | Returns the lifetime move counts.
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
--------------------------------------------------------------------------------
/wsdl/imaging.wsdl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | The capabilities for the imaging service is returned in the Capabilities element.
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | Indicates whether or not Image Stabilization feature is supported.
41 | The use of this capability is deprecated, a client should use GetOption to find out if image stabilization is supported.
42 |
43 |
44 |
45 |
46 | Indicates whether or not Imaging Presets feature is supported.
47 |
48 |
49 |
50 |
51 | Indicates whether or not imaging preset settings can be updated.
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | Reference token to the VideoSource for which the ImagingSettings.
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | ImagingSettings for the VideoSource that was requested.
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | Reference token to the VideoSource for which the imaging parameter options are requested.
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | Valid ranges for the imaging parameters that are categorized as device specific.
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 | Reference to the VideoSource for the requested move (focus) operation.
132 |
133 |
134 |
135 |
136 |
137 |
138 | Content of the requested move (focus) operation.
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 | Reference token to the VideoSource for the requested move options.
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 | Valid ranges for the focus lens move options.
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 | Reference token to the VideoSource where the focus movement should be stopped.
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 | Reference token to the VideoSource where the imaging status should be requested.
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 | Requested imaging status.
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 | Describes standard Imaging Preset types, used to facilitate Multi-language support and client display.
228 | "Custom" Type shall be used when Imaging Preset Name does not match any of the types included in the standard classification.
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 | Type describing the Imaging Preset settings.
261 |
262 |
263 |
264 |
265 | Human readable name of the Imaging Preset.
266 |
267 |
268 |
269 |
270 |
271 | Unique identifier of this Imaging Preset.
272 |
273 |
274 |
275 |
276 | Indicates Imaging Preset Type. Use timg:ImagingPresetType.
277 | Used for multi-language support and display.
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 | A reference to the VideoSource where the operation should take place.
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 | List of Imaging Presets which are available for the requested VideoSource.
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 | Reference token to the VideoSource where the current Imaging Preset should be requested.
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 | Current Imaging Preset in use for the specified Video Source.
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 | Reference token to the VideoSource to which the specified Imaging Preset should be applied.
340 |
341 |
342 |
343 |
344 |
345 | Reference token to the Imaging Preset to be applied to the specified Video Source.
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 | Returns the capabilities of the imaging service. The result is returned in a typed answer.
428 |
429 |
430 |
431 |
432 | Get the ImagingConfiguration for the requested VideoSource.
433 |
434 |
435 |
436 |
437 | Set the ImagingConfiguration for the requested VideoSource.
438 |
439 |
440 |
441 |
442 | This operation gets the valid ranges for the imaging parameters that have device specific ranges.
443 | This command is mandatory for all device implementing the imaging service. The command returns all supported parameters and their ranges
444 | such that these can be applied to the SetImagingSettings command.
445 | For read-only parameters which cannot be modified via the SetImagingSettings command only a single option or identical Min and Max values
446 | is provided.
447 |
448 |
449 |
450 |
451 | The Move command moves the focus lens in an absolute, a relative or in a continuous manner from its current position.
452 | The speed argument is optional for absolute and relative control, but required for continuous. If no speed argument is used, the default speed is used.
453 | Focus adjustments through this operation will turn off the autofocus. A device with support for remote focus control should support absolute,
454 | relative or continuous control through the Move operation. The supported MoveOpions are signalled via the GetMoveOptions command.
455 | At least one focus control capability is required for this operation to be functional.
456 | The move operation contains the following commands:
457 | Absolute – Requires position parameter and optionally takes a speed argument. A unitless type is used by default for focus positioning and speed. Optionally, if supported, the position may be requested in m-1 units.
458 | Relative – Requires distance parameter and optionally takes a speed argument. Negative distance means negative direction.
459 | Continuous – Requires a speed argument. Negative speed argument means negative direction.
460 |
461 |
462 |
463 |
464 |
465 | Imaging move operation options supported for the Video source.
466 |
467 |
468 |
469 |
470 | The Stop command stops all ongoing focus movements of the lense. A device with support for remote focus control as signalled via
471 | the GetMoveOptions supports this command.
The operation will not affect ongoing autofocus operation.
472 |
473 |
474 |
475 |
476 | Via this command the current status of the Move operation can be requested. Supported for this command is available if the support for the Move operation is signalled via GetMoveOptions.
477 |
478 |
479 |
480 |
481 | Via this command the list of available Imaging Presets can be requested.
482 |
483 |
484 |
485 |
486 | Via this command the last Imaging Preset applied can be requested.
487 | If the camera configuration does not match any of the existing Imaging Presets, the output of GetCurrentPreset shall be Empty.
488 | GetCurrentPreset shall return 0 if Imaging Presets are not supported by the Video Source.
489 |
490 |
491 |
492 |
493 | The SetCurrentPreset command shall request a given Imaging Preset to be applied to the specified Video Source.
494 | SetCurrentPreset shall only be available for Video Sources with Imaging Presets Capability.
495 | Imaging Presets are defined by the Manufacturer, and offered as a tool to simplify Imaging Settings adjustments for specific scene content.
496 | When the new Imaging Preset is applied by SetCurrentPreset, the Device shall adjust the Video Source settings to match those defined by the specified Imaging Preset.
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
--------------------------------------------------------------------------------