├── .gitignore
├── LICENSE
├── README.md
├── device
├── device.wsdl
└── types.go
├── deviceService.go
├── events
├── addressing.go
├── events.wsdl
└── types.go
├── eventsService.go
├── go.mod
├── go.sum
├── main
└── main.go
├── media
├── media.wsdl
└── types.go
├── mediaService.go
├── onvif
├── common.xsd
├── itemlist.go
├── message.go
├── onvif.xsd
├── posix_timezone.go
└── types.go
├── onvifClient.go
├── onvifdevice.go
├── pullPointSubscription.go
├── soap
├── client.go
├── types.go
└── wsSecurity.go
└── xsd
├── anytype.go
├── duration.go
└── types.go
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | *.exe
3 | *.DS_Store
4 | .project
5 | .vscode/
6 | coverage.out
7 | debug
8 | *.dll
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 faceterteam
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # onvif4go
2 |
3 | ```
4 | device := onvif4go.NewOnvifDevice("192.168.1.1:80")
5 | device.Auth("admin", "1234456")
6 | err := device.Initialize()
7 | ...
8 | ```
9 |
10 | ```
11 | deviceInformation, err := device.Device.GetDeviceInformation()
12 | ...
13 | ```
14 |
15 | ```
16 | err := device.Media.AddVideoAnalyticsConfiguration("Profile_0", "VideoAnalyticsConfiguration_000")
17 | ...
18 | ```
19 |
20 | ```
21 | response := CustomDeviceResponse{}
22 | err := device.Device.Call(CustomDeviceRequest{}, &response)
23 | ...
24 | ```
25 |
26 | ```
27 | response := trt.GetProfilesResponse{}
28 | media, ok := device.On("media")
29 | err := media.Call(trt.GetProfiles{}, &response)
30 | ...
31 | ```
32 |
33 | ```
34 | response := xsd.AnyType{}
35 | analytics, _ := device.On("analytics")
36 | err = analytics.Call(xsd.AnyType{
37 | XMLName: xml.Name{"http://www.onvif.org/ver20/analytics/wsdl", "GetSupportedAnalyticsModules"},
38 | Childs: []xsd.AnyType{
39 | xsd.AnyType{
40 | XMLName: xml.Name{"http://www.onvif.org/ver20/analytics/wsdl", "ConfigurationToken"},
41 | Text: "VideoAnalyticsConfiguration_000",
42 | },
43 | },
44 | }, &response)
45 | ```
--------------------------------------------------------------------------------
/device/types.go:
--------------------------------------------------------------------------------
1 | package device
2 |
3 | import (
4 | "time"
5 |
6 | "github.com/faceterteam/onvif4go/onvif"
7 | "github.com/faceterteam/onvif4go/xsd"
8 | )
9 |
10 | type Service struct {
11 | Namespace xsd.AnyURI
12 | XAddr xsd.AnyURI
13 | Capabilities
14 | Version onvif.OnvifVersion
15 | }
16 |
17 | type Capabilities struct {
18 | Any string
19 | }
20 |
21 | type DeviceServiceCapabilities struct {
22 | Network NetworkCapabilities
23 | Security SecurityCapabilities
24 | System SystemCapabilities
25 | Misc *MiscCapabilities
26 | }
27 |
28 | type NetworkCapabilities struct {
29 | IPFilter bool `xml:"IPFilter,attr"`
30 | ZeroConfiguration bool `xml:"ZeroConfiguration,attr"`
31 | IPVersion6 bool `xml:"IPVersion6,attr"`
32 | DynDNS bool `xml:"DynDNS,attr"`
33 | Dot11Configuration bool `xml:"Dot11Configuration,attr"`
34 | Dot1XConfigurations int `xml:"Dot1XConfigurations,attr"`
35 | HostnameFromDHCP bool `xml:"HostnameFromDHCP,attr"`
36 | NTP int `xml:"NTP,attr"`
37 | DHCPv6 bool `xml:"DHCPv6,attr"`
38 | }
39 |
40 | type SecurityCapabilities struct {
41 | TLS1_0 bool `xml:"TLS1_0,attr"`
42 | TLS1_1 bool `xml:"TLS1_1,attr"`
43 | TLS1_2 bool `xml:"TLS1_2,attr"`
44 | OnboardKeyGeneration bool `xml:"OnboardKeyGeneration,attr"`
45 | AccessPolicyConfig bool `xml:"AccessPolicyConfig,attr"`
46 | DefaultAccessPolicy bool `xml:"DefaultAccessPolicy,attr"`
47 | Dot1X bool `xml:"Dot1X,attr"`
48 | RemoteUserHandling bool `xml:"RemoteUserHandling,attr"`
49 | X509Token bool `xml:"X_509Token,attr"`
50 | SAMLToken bool `xml:"SAMLToken,attr"`
51 | KerberosToken bool `xml:"KerberosToken,attr"`
52 | UsernameToken bool `xml:"UsernameToken,attr"`
53 | HTTPDigest bool `xml:"HttpDigest,attr"`
54 | RELToken bool `xml:"RELToken,attr"`
55 | SupportedEAPMethods EAPMethodTypes `xml:"SupportedEAPMethods,attr"`
56 | MaxUsers int `xml:"MaxUsers,attr"`
57 | MaxUserNameLength int `xml:"MaxUserNameLength,attr"`
58 | MaxPasswordLength int `xml:"MaxPasswordLength,attr"`
59 | }
60 |
61 | //TODO:
62 | type EAPMethodTypes struct {
63 | Types []int
64 | }
65 |
66 | type SystemCapabilities struct {
67 | DiscoveryResolve bool `xml:"DiscoveryResolve,attr"`
68 | DiscoveryBye bool `xml:"DiscoveryBye,attr"`
69 | RemoteDiscovery bool `xml:"RemoteDiscovery,attr"`
70 | SystemBackup bool `xml:"SystemBackup,attr"`
71 | SystemLogging bool `xml:"SystemLogging,attr"`
72 | FirmwareUpgrade bool `xml:"FirmwareUpgrade,attr"`
73 | HTTPFirmwareUpgrade bool `xml:"HttpFirmwareUpgrade,attr"`
74 | HTTPSystemBackup bool `xml:"HttpSystemBackup,attr"`
75 | HTTPSystemLogging bool `xml:"HttpSystemLogging,attr"`
76 | HTTPSupportInformation bool `xml:"HttpSupportInformation,attr"`
77 | StorageConfiguration bool `xml:"StorageConfiguration,attr"`
78 | MaxStorageConfigurations int `xml:"MaxStorageConfigurations,attr"`
79 | GeoLocationEntries int `xml:"GeoLocationEntries,attr"`
80 | AutoGeo string `xml:"AutoGeo,attr"`
81 | }
82 |
83 | type MiscCapabilities struct {
84 | AuxiliaryCommands onvif.StringAttrList `xml:"AuxiliaryCommands,attr"`
85 | }
86 |
87 | type StorageConfiguration struct {
88 | onvif.DeviceEntity
89 | Data StorageConfigurationData `xml:"http://www.onvif.org/ver10/device/wsdl Data"`
90 | }
91 |
92 | type StorageConfigurationData struct {
93 | Type string `xml:"type,attr"`
94 | LocalPath *xsd.AnyURI `xml:"http://www.onvif.org/ver10/device/wsdl LocalPath"`
95 | StorageURI *xsd.AnyURI `xml:"http://www.onvif.org/ver10/device/wsdl StorageUri"`
96 | User *UserCredential `xml:"http://www.onvif.org/ver10/device/wsdl User"`
97 | Extension *xsd.AnyType `xml:"http://www.onvif.org/ver10/device/wsdl Extension"`
98 | }
99 |
100 | type UserCredential struct {
101 | UserName string `xml:"http://www.onvif.org/ver10/device/wsdl UserName"`
102 | Password *string `xml:"http://www.onvif.org/ver10/device/wsdl Password"`
103 | Extension *xsd.AnyType `xml:"http://www.onvif.org/ver10/device/wsdl Extension"`
104 | }
105 |
106 | type GetServices struct {
107 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetServices"`
108 | IncludeCapability bool `xml:"http://www.onvif.org/ver10/device/wsdl IncludeCapability"`
109 | }
110 |
111 | type GetServicesResponse struct {
112 | Service []Service
113 | }
114 |
115 | type GetServiceCapabilities struct {
116 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetServiceCapabilities"`
117 | }
118 |
119 | type GetServiceCapabilitiesResponse struct {
120 | Capabilities DeviceServiceCapabilities
121 | }
122 |
123 | type GetDeviceInformation struct {
124 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetDeviceInformation"`
125 | }
126 |
127 | type GetDeviceInformationResponse struct {
128 | Manufacturer string `xml:"http://www.onvif.org/ver10/device/wsdl Manufacturer"`
129 | Model string `xml:"http://www.onvif.org/ver10/device/wsdl Model"`
130 | FirmwareVersion string `xml:"http://www.onvif.org/ver10/device/wsdl FirmwareVersion"`
131 | SerialNumber string `xml:"http://www.onvif.org/ver10/device/wsdl SerialNumber"`
132 | HardwareID string `xml:"http://www.onvif.org/ver10/device/wsdl HardwareId"`
133 | }
134 |
135 | type SetSystemDateAndTime struct {
136 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetSystemDateAndTime"`
137 | DateTimeType onvif.SetDateTimeType `xml:"http://www.onvif.org/ver10/device/wsdl DateTimeType"`
138 | DaylightSavings bool `xml:"http://www.onvif.org/ver10/device/wsdl DaylightSavings"`
139 | TimeZone *onvif.TimeZone `xml:"http://www.onvif.org/ver10/device/wsdl TimeZone"`
140 | UTCDateTime *onvif.DateTime `xml:"http://www.onvif.org/ver10/device/wsdl UTCDateTime"`
141 | }
142 |
143 | func NewSetSystemDateAndTimeNTP(timeZone string, useDST bool) (s SetSystemDateAndTime, err error) {
144 | if timeZone != "" {
145 | var ns xsd.NormalizedString
146 | ns, err = xsd.NewNormalizedString(timeZone)
147 | if err != nil {
148 | return
149 | }
150 |
151 | var token xsd.Token
152 | token, err = xsd.NewToken(ns)
153 | if err != nil {
154 | return
155 | }
156 | tz := onvif.TimeZone{TZ:token}
157 | s.TimeZone = &tz
158 | }
159 |
160 | s.DaylightSavings = useDST
161 |
162 | s.DateTimeType = onvif.SetDateTimeType("NTP")
163 |
164 | return
165 | }
166 |
167 | func NewSetSystemDateAndTimeManual(datetime time.Time, timeZone string, useDST bool) (s SetSystemDateAndTime, err error) {
168 | if timeZone != "" {
169 | var ns xsd.NormalizedString
170 | ns, err = xsd.NewNormalizedString(timeZone)
171 | if err != nil {
172 | return
173 | }
174 |
175 | var token xsd.Token
176 | token, err = xsd.NewToken(ns)
177 | if err != nil {
178 | return
179 | }
180 | tz := onvif.TimeZone{TZ:token}
181 | s.TimeZone = &tz
182 | }
183 |
184 | dt := onvif.DateTime{
185 | Time: onvif.Time{
186 | Hour: datetime.Hour(),
187 | Minute: datetime.Minute(),
188 | Second: datetime.Second(),
189 | },
190 | Date: onvif.Date{
191 | Day: datetime.Day(),
192 | Month: int(datetime.Month()),
193 | Year: datetime.Year(),
194 | },
195 | }
196 |
197 | s.UTCDateTime = &dt
198 | s.DaylightSavings = useDST
199 |
200 | s.DateTimeType = onvif.SetDateTimeType("Manual")
201 |
202 | return
203 | }
204 |
205 | type SetSystemDateAndTimeResponse struct {
206 | }
207 |
208 | type GetSystemDateAndTime struct {
209 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetSystemDateAndTime"`
210 | }
211 |
212 | type GetSystemDateAndTimeResponse struct {
213 | SystemDateAndTime onvif.SystemDateTime
214 | }
215 |
216 | type SetSystemFactoryDefault struct {
217 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetSystemFactoryDefault"`
218 | FactoryDefault onvif.FactoryDefaultType `xml:"http://www.onvif.org/ver10/device/wsdl FactoryDefault"`
219 | }
220 |
221 | type SetSystemFactoryDefaultResponse struct {
222 | }
223 |
224 | type UpgradeSystemFirmware struct {
225 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl UpgradeSystemFirmware"`
226 | Firmware onvif.AttachmentData `xml:"http://www.onvif.org/ver10/device/wsdl Firmware"`
227 | }
228 |
229 | type UpgradeSystemFirmwareResponse struct {
230 | Message string
231 | }
232 |
233 | type SystemReboot struct {
234 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SystemReboot"`
235 | }
236 |
237 | type SystemRebootResponse struct {
238 | Message string
239 | }
240 |
241 | type RestoreSystem struct {
242 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl RestoreSystem"`
243 | BackupFiles []onvif.BackupFile `xml:"http://www.onvif.org/ver10/device/wsdl BackupFiles"`
244 | }
245 |
246 | type RestoreSystemResponse struct {
247 | }
248 |
249 | type GetSystemBackup struct {
250 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetSystemBackup"`
251 | }
252 |
253 | type GetSystemBackupResponse struct {
254 | BackupFiles []onvif.BackupFile
255 | }
256 |
257 | type GetSystemLog struct {
258 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetSystemLog"`
259 | LogType onvif.SystemLogType `xml:"http://www.onvif.org/ver10/device/wsdl LogType"`
260 | }
261 |
262 | type GetSystemLogResponse struct {
263 | SystemLog onvif.SystemLog
264 | }
265 |
266 | type GetSystemSupportInformation struct {
267 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetSystemSupportInformation"`
268 | }
269 |
270 | type GetSystemSupportInformationResponse struct {
271 | SupportInformation onvif.SupportInformation
272 | }
273 |
274 | type GetScopes struct {
275 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetScopes"`
276 | }
277 |
278 | type GetScopesResponse struct {
279 | Scopes []onvif.Scope
280 | }
281 |
282 | type SetScopes struct {
283 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetScopes"`
284 | Scopes []xsd.AnyURI `xml:"http://www.onvif.org/ver10/device/wsdl Scopes"`
285 | }
286 |
287 | type SetScopesResponse struct {
288 | }
289 |
290 | type AddScopes struct {
291 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl AddScopes"`
292 | ScopeItem []xsd.AnyURI `xml:"http://www.onvif.org/ver10/device/wsdl ScopeItem"`
293 | }
294 |
295 | type AddScopesResponse struct {
296 | }
297 |
298 | type RemoveScopes struct {
299 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl RemoveScopes"`
300 | ScopeItem []xsd.AnyURI `xml:"http://www.onvif.org/ver10/schema onvif:ScopeItem"`
301 | }
302 |
303 | type RemoveScopesResponse struct {
304 | ScopeItem []xsd.AnyURI `xml:"http://www.onvif.org/ver10/device/wsdl ScopeItem"`
305 | }
306 |
307 | type GetDiscoveryMode struct {
308 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetDiscoveryMode"`
309 | }
310 |
311 | type GetDiscoveryModeResponse struct {
312 | DiscoveryMode onvif.DiscoveryMode
313 | }
314 |
315 | type SetDiscoveryMode struct {
316 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetDiscoveryMode"`
317 | DiscoveryMode onvif.DiscoveryMode `xml:"http://www.onvif.org/ver10/device/wsdl DiscoveryMode"`
318 | }
319 |
320 | type SetDiscoveryModeResponse struct {
321 | }
322 |
323 | type GetRemoteDiscoveryMode struct {
324 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetRemoteDiscoveryMode"`
325 | }
326 |
327 | type GetRemoteDiscoveryModeResponse struct {
328 | RemoteDiscoveryMode onvif.DiscoveryMode
329 | }
330 |
331 | type SetRemoteDiscoveryMode struct {
332 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetRemoteDiscoveryMode"`
333 | RemoteDiscoveryMode onvif.DiscoveryMode `xml:"http://www.onvif.org/ver10/device/wsdl RemoteDiscoveryMode"`
334 | }
335 |
336 | type SetRemoteDiscoveryModeResponse struct {
337 | }
338 |
339 | type GetDPAddresses struct {
340 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetDPAddresses"`
341 | }
342 |
343 | type GetDPAddressesResponse struct {
344 | DPAddress []onvif.NetworkHost
345 | }
346 |
347 | type SetDPAddresses struct {
348 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetDPAddresses"`
349 | DPAddress []onvif.NetworkHost `xml:"http://www.onvif.org/ver10/device/wsdl DPAddress"`
350 | }
351 |
352 | type SetDPAddressesResponse struct {
353 | }
354 |
355 | type GetEndpointReference struct {
356 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetEndpointReference"`
357 | }
358 |
359 | type GetEndpointReferenceResponse struct {
360 | GUID string
361 | }
362 |
363 | type GetRemoteUser struct {
364 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetRemoteUser"`
365 | }
366 |
367 | type GetRemoteUserResponse struct {
368 | RemoteUser *onvif.RemoteUser
369 | }
370 |
371 | type SetRemoteUser struct {
372 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetRemoteUser"`
373 | RemoteUser *onvif.RemoteUser `xml:"http://www.onvif.org/ver10/device/wsdl RemoteUser"`
374 | }
375 |
376 | type SetRemoteUserResponse struct {
377 | }
378 |
379 | type GetUsers struct {
380 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetUsers"`
381 | }
382 |
383 | type GetUsersResponse struct {
384 | User []onvif.User
385 | }
386 |
387 | type CreateUsers struct {
388 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl CreateUsers"`
389 | Users []onvif.User `xml:"http://www.onvif.org/ver10/device/wsdl User"`
390 | }
391 |
392 | type CreateUsersResponse struct {
393 | }
394 |
395 | type DeleteUsers struct {
396 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl DeleteUsers"`
397 | Usernames []string `xml:"http://www.onvif.org/ver10/device/wsdl Username"`
398 | }
399 |
400 | type DeleteUsersResponse struct {
401 | }
402 |
403 | type SetUser struct {
404 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetUser"`
405 | Users []onvif.User `xml:"http://www.onvif.org/ver10/device/wsdl User"`
406 | }
407 |
408 | type SetUserResponse struct {
409 | }
410 |
411 | type GetWsdlUrl struct {
412 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetWsdlUrl"`
413 | }
414 |
415 | type GetWsdlUrlResponse struct {
416 | WsdlURL xsd.AnyURI `xml:"http://www.onvif.org/ver10/device/wsdl WsdlUrl"`
417 | }
418 |
419 | type GetCapabilities struct {
420 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetCapabilities"`
421 | Category []onvif.CapabilityCategory `xml:"http://www.onvif.org/ver10/device/wsdl Category"`
422 | }
423 |
424 | type GetCapabilitiesResponse struct {
425 | Capabilities onvif.Capabilities
426 | }
427 |
428 | type GetHostname struct {
429 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetHostname"`
430 | }
431 |
432 | type GetHostnameResponse struct {
433 | HostnameInformation onvif.HostnameInformation
434 | }
435 |
436 | type SetHostname struct {
437 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetHostname"`
438 | Name xsd.Token `xml:"http://www.onvif.org/ver10/device/wsdl Name"`
439 | }
440 |
441 | type SetHostnameResponse struct {
442 | }
443 |
444 | type SetHostnameFromDHCP struct {
445 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetHostnameFromDHCP"`
446 | FromDHCP bool `xml:"http://www.onvif.org/ver10/device/wsdl FromDHCP"`
447 | }
448 |
449 | type SetHostnameFromDHCPResponse struct {
450 | RebootNeeded bool
451 | }
452 |
453 | type GetDNS struct {
454 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetDNS"`
455 | }
456 |
457 | type GetDNSResponse struct {
458 | DNSInformation onvif.DNSInformation
459 | }
460 |
461 | type SetDNS struct {
462 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetDNS"`
463 | FromDHCP bool `xml:"http://www.onvif.org/ver10/device/wsdl FromDHCP"`
464 | SearchDomain []xsd.Token `xml:"http://www.onvif.org/ver10/device/wsdl SearchDomain"`
465 | DNSManual []onvif.IPAddress `xml:"http://www.onvif.org/ver10/device/wsdl DNSManual"`
466 | }
467 |
468 | type SetDNSResponse struct {
469 | }
470 |
471 | type GetNTP struct {
472 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetNTP"`
473 | }
474 |
475 | type GetNTPResponse struct {
476 | NTPInformation onvif.NTPInformation
477 | }
478 |
479 | type SetNTP struct {
480 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetNTP"`
481 | FromDHCP bool `xml:"http://www.onvif.org/ver10/device/wsdl FromDHCP"`
482 | NTPManual []onvif.NetworkHost `xml:"http://www.onvif.org/ver10/device/wsdl NTPManual"`
483 | }
484 |
485 | type SetNTPResponse struct {
486 | }
487 |
488 | type GetDynamicDNS struct {
489 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetDynamicDNS"`
490 | }
491 |
492 | type GetDynamicDNSResponse struct {
493 | DynamicDNSInformation onvif.DynamicDNSInformation
494 | }
495 |
496 | type SetDynamicDNS struct {
497 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetDynamicDNS"`
498 | Type onvif.DynamicDNSType `xml:"http://www.onvif.org/ver10/device/wsdl Type"`
499 | Name *onvif.DNSName `xml:"http://www.onvif.org/ver10/device/wsdl Name"`
500 | TTL *xsd.Duration `xml:"http://www.onvif.org/ver10/device/wsdl TTL"`
501 | }
502 |
503 | type SetDynamicDNSResponse struct {
504 | }
505 |
506 | type GetNetworkInterfaces struct {
507 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetNetworkInterfaces"`
508 | }
509 |
510 | type GetNetworkInterfacesResponse struct {
511 | NetworkInterfaces []onvif.NetworkInterface
512 | }
513 |
514 | type SetNetworkInterfaces struct {
515 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetNetworkInterfaces"`
516 | InterfaceToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/device/wsdl InterfaceToken"`
517 | NetworkInterface onvif.NetworkInterfaceSetConfiguration `xml:"http://www.onvif.org/ver10/device/wsdl NetworkInterface"`
518 | }
519 |
520 | type SetNetworkInterfacesResponse struct {
521 | RebootNeeded bool
522 | }
523 |
524 | type GetNetworkProtocols struct {
525 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetNetworkProtocols"`
526 | }
527 |
528 | type GetNetworkProtocolsResponse struct {
529 | NetworkProtocols []onvif.NetworkProtocol
530 | }
531 |
532 | type SetNetworkProtocols struct {
533 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetNetworkProtocols"`
534 | NetworkProtocols []onvif.NetworkProtocol `xml:"http://www.onvif.org/ver10/device/wsdl NetworkProtocols"`
535 | }
536 |
537 | type SetNetworkProtocolsResponse struct {
538 | }
539 |
540 | type GetNetworkDefaultGateway struct {
541 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetNetworkDefaultGateway"`
542 | }
543 |
544 | type GetNetworkDefaultGatewayResponse struct {
545 | NetworkGateway onvif.NetworkGateway
546 | }
547 |
548 | type SetNetworkDefaultGateway struct {
549 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetNetworkDefaultGateway"`
550 | IPv4Address []onvif.IPv4Address `xml:"http://www.onvif.org/ver10/device/wsdl IPv4Address"`
551 | IPv6Address []onvif.IPv6Address `xml:"http://www.onvif.org/ver10/device/wsdl IPv6Address"`
552 | }
553 |
554 | type SetNetworkDefaultGatewayResponse struct {
555 | }
556 |
557 | type GetZeroConfiguration struct {
558 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetZeroConfiguration"`
559 | }
560 |
561 | type GetZeroConfigurationResponse struct {
562 | ZeroConfiguration onvif.NetworkZeroConfiguration
563 | }
564 |
565 | type SetZeroConfiguration struct {
566 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetZeroConfiguration"`
567 | InterfaceToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/device/wsdl InterfaceToken"`
568 | Enabled bool `xml:"http://www.onvif.org/ver10/device/wsdl Enabled"`
569 | }
570 |
571 | type SetZeroConfigurationResponse struct {
572 | }
573 |
574 | type GetIPAddressFilter struct {
575 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetIPAddressFilter"`
576 | }
577 |
578 | type GetIPAddressFilterResponse struct {
579 | IPAddressFilter onvif.IPAddressFilter
580 | }
581 |
582 | type SetIPAddressFilter struct {
583 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetIPAddressFilter"`
584 | IPAddressFilter onvif.IPAddressFilter `xml:"http://www.onvif.org/ver10/device/wsdl IPAddressFilter"`
585 | }
586 |
587 | type SetIPAddressFilterResponse struct {
588 | }
589 |
590 | type AddIPAddressFilter struct {
591 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl AddIPAddressFilter"`
592 | IPAddressFilter onvif.IPAddressFilter `xml:"http://www.onvif.org/ver10/device/wsdl IPAddressFilter"`
593 | }
594 |
595 | type AddIPAddressFilterResponse struct {
596 | }
597 |
598 | type RemoveIPAddressFilter struct {
599 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl RemoveIPAddressFilter"`
600 | IPAddressFilter onvif.IPAddressFilter `xml:"http://www.onvif.org/ver10/schema onvif:IPAddressFilter"`
601 | }
602 |
603 | type RemoveIPAddressFilterResponse struct {
604 | }
605 |
606 | type GetAccessPolicy struct {
607 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetAccessPolicy"`
608 | }
609 |
610 | type GetAccessPolicyResponse struct {
611 | PolicyFile onvif.BinaryData
612 | }
613 |
614 | type SetAccessPolicy struct {
615 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetAccessPolicy"`
616 | PolicyFile onvif.BinaryData `xml:"http://www.onvif.org/ver10/device/wsdl PolicyFile"`
617 | }
618 |
619 | type SetAccessPolicyResponse struct {
620 | }
621 |
622 | type CreateCertificate struct {
623 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl CreateCertificate"`
624 | CertificateID *xsd.Token `xml:"http://www.onvif.org/ver10/device/wsdl CertificateID,omitempty"`
625 | Subject *string `xml:"http://www.onvif.org/ver10/device/wsdl Subject,omitempty"`
626 | ValidNotBefore *xsd.DateTime `xml:"http://www.onvif.org/ver10/device/wsdl ValidNotBefore,omitempty"`
627 | ValidNotAfter *xsd.DateTime `xml:"http://www.onvif.org/ver10/device/wsdl ValidNotAfter,omitempty"`
628 | }
629 |
630 | type CreateCertificateResponse struct {
631 | NvtCertificate onvif.Certificate
632 | }
633 |
634 | type GetCertificates struct {
635 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetCertificates"`
636 | }
637 |
638 | type GetCertificatesResponse struct {
639 | NvtCertificate []onvif.Certificate `xml:"http://www.onvif.org/ver10/device/wsdl NvtCertificate"`
640 | }
641 |
642 | type GetCertificatesStatus struct {
643 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetCertificatesStatus"`
644 | }
645 |
646 | type GetCertificatesStatusResponse struct {
647 | CertificateStatus []onvif.CertificateStatus `xml:"http://www.onvif.org/ver10/device/wsdl CertificateStatus"`
648 | }
649 |
650 | type SetCertificatesStatus struct {
651 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetCertificatesStatus"`
652 | CertificateStatus []onvif.CertificateStatus `xml:"http://www.onvif.org/ver10/device/wsdl CertificateStatus"`
653 | }
654 |
655 | type SetCertificatesStatusResponse struct {
656 | }
657 |
658 | type DeleteCertificates struct {
659 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl DeleteCertificates"`
660 | CertificateID []xsd.Token `xml:"http://www.onvif.org/ver10/device/wsdl CertificateID"`
661 | }
662 |
663 | type DeleteCertificatesResponse struct {
664 | }
665 |
666 | type GetPkcs10Request struct {
667 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetPkcs10Request"`
668 | CertificateID xsd.Token `xml:"http://www.onvif.org/ver10/device/wsdl CertificateID"`
669 | Subject *string `xml:"http://www.onvif.org/ver10/device/wsdl Subject"`
670 | Attributes *onvif.BinaryData `xml:"http://www.onvif.org/ver10/device/wsdl Attributes"`
671 | }
672 |
673 | type GetPkcs10RequestResponse struct {
674 | Pkcs10Request onvif.BinaryData
675 | }
676 |
677 | type LoadCertificates struct {
678 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl LoadCertificates"`
679 | NVTCertificate []onvif.Certificate `xml:"http://www.onvif.org/ver10/device/wsdl NVTCertificate"`
680 | }
681 |
682 | type LoadCertificatesResponse struct {
683 | }
684 |
685 | type GetClientCertificateMode struct {
686 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetClientCertificateMode"`
687 | }
688 |
689 | type GetClientCertificateModeResponse struct {
690 | Enabled bool
691 | }
692 |
693 | type SetClientCertificateMode struct {
694 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetClientCertificateMode"`
695 | Enabled bool `xml:"http://www.onvif.org/ver10/device/wsdl Enabled"`
696 | }
697 |
698 | type SetClientCertificateModeResponse struct {
699 | }
700 |
701 | type GetRelayOutputs struct {
702 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetRelayOutputs"`
703 | }
704 |
705 | type GetRelayOutputsResponse struct {
706 | RelayOutputs []onvif.RelayOutput `xml:"http://www.onvif.org/ver10/device/wsdl RelayOutputs"`
707 | }
708 |
709 | type SetRelayOutputSettings struct {
710 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetRelayOutputSettings"`
711 | RelayOutputToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/device/wsdl RelayOutputToken"`
712 | Properties onvif.RelayOutputSettings `xml:"http://www.onvif.org/ver10/device/wsdl Properties"`
713 | }
714 |
715 | type SetRelayOutputSettingsResponse struct {
716 | }
717 |
718 | type SetRelayOutputState struct {
719 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetRelayOutputState"`
720 | RelayOutputToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/device/wsdl RelayOutputToken"`
721 | LogicalState onvif.RelayLogicalState `xml:"http://www.onvif.org/ver10/device/wsdl LogicalState"`
722 | }
723 |
724 | type SetRelayOutputStateResponse struct {
725 | }
726 |
727 | type SendAuxiliaryCommand struct {
728 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SendAuxiliaryCommand"`
729 | AuxiliaryCommand onvif.AuxiliaryData `xml:"http://www.onvif.org/ver10/device/wsdl AuxiliaryCommand"`
730 | }
731 |
732 | type SendAuxiliaryCommandResponse struct {
733 | AuxiliaryCommandResponse *onvif.AuxiliaryData
734 | }
735 |
736 | type GetCACertificates struct {
737 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetCACertificates"`
738 | }
739 |
740 | type GetCACertificatesResponse struct {
741 | CACertificate []onvif.Certificate
742 | }
743 |
744 | type LoadCertificateWithPrivateKey struct {
745 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl LoadCertificateWithPrivateKey"`
746 | CertificateWithPrivateKey []onvif.CertificateWithPrivateKey `xml:"http://www.onvif.org/ver10/device/wsdl CertificateWithPrivateKey"`
747 | }
748 |
749 | type LoadCertificateWithPrivateKeyResponse struct {
750 | }
751 |
752 | type GetCertificateInformation struct {
753 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetCertificateInformation"`
754 | CertificateID xsd.Token `xml:"http://www.onvif.org/ver10/device/wsdl CertificateID"`
755 | }
756 |
757 | type GetCertificateInformationResponse struct {
758 | CertificateInformation onvif.CertificateInformation
759 | }
760 |
761 | type LoadCACertificates struct {
762 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl LoadCACertificates"`
763 | CACertificate []onvif.Certificate `xml:"http://www.onvif.org/ver10/device/wsdl CACertificate"`
764 | }
765 |
766 | type LoadCACertificatesResponse struct {
767 | }
768 |
769 | type CreateDot1XConfiguration struct {
770 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl CreateDot1XConfiguration"`
771 | Dot1XConfiguration onvif.Dot1XConfiguration `xml:"http://www.onvif.org/ver10/device/wsdl Dot1XConfiguration"`
772 | }
773 |
774 | type CreateDot1XConfigurationResponse struct {
775 | }
776 |
777 | type SetDot1XConfiguration struct {
778 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetDot1XConfiguration"`
779 | Dot1XConfiguration onvif.Dot1XConfiguration `xml:"http://www.onvif.org/ver10/device/wsdl Dot1XConfiguration"`
780 | }
781 |
782 | type SetDot1XConfigurationResponse struct {
783 | }
784 |
785 | type GetDot1XConfiguration struct {
786 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetDot1XConfiguration"`
787 | Dot1XConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/device/wsdl Dot1XConfigurationToken"`
788 | }
789 |
790 | type GetDot1XConfigurationResponse struct {
791 | Dot1XConfiguration onvif.Dot1XConfiguration
792 | }
793 |
794 | type GetDot1XConfigurations struct {
795 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetDot1XConfigurations"`
796 | }
797 |
798 | type GetDot1XConfigurationsResponse struct {
799 | Dot1XConfiguration []onvif.Dot1XConfiguration
800 | }
801 |
802 | type DeleteDot1XConfiguration struct {
803 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl DeleteDot1XConfiguration"`
804 | Dot1XConfigurationToken []onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/device/wsdl Dot1XConfigurationToken"`
805 | }
806 |
807 | type DeleteDot1XConfigurationResponse struct {
808 | }
809 |
810 | type GetDot11Capabilities struct {
811 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetDot11Capabilities"`
812 | }
813 |
814 | type GetDot11CapabilitiesResponse struct {
815 | Capabilities onvif.Dot11Capabilities
816 | }
817 |
818 | type GetDot11Status struct {
819 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetDot11Status"`
820 | InterfaceToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/device/wsdl InterfaceToken"`
821 | }
822 |
823 | type GetDot11StatusResponse struct {
824 | Status onvif.Dot11Status
825 | }
826 |
827 | type ScanAvailableDot11Networks struct {
828 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl ScanAvailableDot11Networks"`
829 | InterfaceToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/device/wsdl InterfaceToken"`
830 | }
831 |
832 | type ScanAvailableDot11NetworksResponse struct {
833 | Networks []onvif.Dot11AvailableNetworks `xml:"http://www.onvif.org/ver10/device/wsdl Networks"`
834 | }
835 |
836 | type GetSystemUris struct {
837 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetSystemUris"`
838 | }
839 |
840 | type GetSystemUrisResponse struct {
841 | SystemLogUris *onvif.SystemLogUriList `xml:"http://www.onvif.org/ver10/device/wsdl SystemLogUris"`
842 | SupportInfoURI *xsd.AnyURI `xml:"http://www.onvif.org/ver10/device/wsdl SupportInfoUri"`
843 | SystemBackupURI *xsd.AnyURI `xml:"http://www.onvif.org/ver10/device/wsdl SystemBackupUri"`
844 | Extension *xsd.AnyType `xml:"http://www.onvif.org/ver10/device/wsdl Extension"`
845 | }
846 |
847 | type StartFirmwareUpgrade struct {
848 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl StartFirmwareUpgrade"`
849 | }
850 |
851 | type StartFirmwareUpgradeResponse struct {
852 | UploadUri xsd.AnyURI
853 | UploadDelay xsd.Duration
854 | ExpectedDownTime xsd.Duration
855 | }
856 |
857 | type StartSystemRestore struct {
858 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl StartSystemRestore"`
859 | }
860 |
861 | type StartSystemRestoreResponse struct {
862 | UploadUri xsd.AnyURI
863 | ExpectedDownTime xsd.Duration
864 | }
865 |
866 | type GetStorageConfigurations struct {
867 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetStorageConfigurations"`
868 | }
869 |
870 | type GetStorageConfigurationsResponse struct {
871 | StorageConfigurations []StorageConfiguration `xml:"http://www.onvif.org/ver10/device/wsdl StorageConfigurations"`
872 | }
873 |
874 | type CreateStorageConfiguration struct {
875 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl CreateStorageConfiguration"`
876 | StorageConfiguration StorageConfigurationData
877 | }
878 |
879 | type CreateStorageConfigurationResponse struct {
880 | Token onvif.ReferenceToken
881 | }
882 |
883 | type GetStorageConfiguration struct {
884 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetStorageConfiguration"`
885 | Token onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/device/wsdl Token"`
886 | }
887 |
888 | type GetStorageConfigurationResponse struct {
889 | StorageConfiguration StorageConfiguration
890 | }
891 |
892 | type SetStorageConfiguration struct {
893 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetStorageConfiguration"`
894 | StorageConfiguration StorageConfiguration `xml:"http://www.onvif.org/ver10/device/wsdl StorageConfiguration"`
895 | }
896 |
897 | type SetStorageConfigurationResponse struct {
898 | }
899 |
900 | type DeleteStorageConfiguration struct {
901 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl DeleteStorageConfiguration"`
902 | Token onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/device/wsdl Token"`
903 | }
904 |
905 | type DeleteStorageConfigurationResponse struct {
906 | }
907 |
908 | type GetGeoLocation struct {
909 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl GetGeoLocation"`
910 | }
911 |
912 | type GetGeoLocationResponse struct {
913 | Location []onvif.LocationEntity `xml:"http://www.onvif.org/ver10/device/wsdl Location"`
914 | }
915 |
916 | type SetGeoLocation struct {
917 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl SetGeoLocation"`
918 | Location []onvif.LocationEntity `xml:"http://www.onvif.org/ver10/device/wsdl Location"`
919 | }
920 |
921 | type SetGeoLocationResponse struct {
922 | }
923 |
924 | type DeleteGeoLocation struct {
925 | XMLName string `xml:"http://www.onvif.org/ver10/device/wsdl DeleteGeoLocation"`
926 | Location []onvif.LocationEntity `xml:"http://www.onvif.org/ver10/device/wsdl Location"`
927 | }
928 |
929 | type DeleteGeoLocationResponse struct {
930 | }
931 |
--------------------------------------------------------------------------------
/events/addressing.go:
--------------------------------------------------------------------------------
1 | package events
2 |
3 | import "encoding/xml"
4 |
5 | type addressingAction struct {
6 | XMLName xml.Name `xml:"http://www.w3.org/2005/08/addressing Action"`
7 | Value string `xml:",chardata"`
8 | }
9 |
10 | type addressingMessageID struct {
11 | XMLName xml.Name `xml:"http://www.w3.org/2005/08/addressing MessageID"`
12 | Value string `xml:",chardata"` // urn:uuid:5e6558cf-e5dc-42e5-9417-6372b3ed9a65
13 | }
14 |
15 | type addressingReplyTo struct {
16 | XMLName xml.Name `xml:"http://www.w3.org/2005/08/addressing ReplyTo"`
17 | Address string `xml:"http://www.w3.org/2005/08/addressing Address"` // http://www.w3.org/2005/08/addressing/anonymous
18 | }
19 |
20 | type addressingTo struct {
21 | XMLName xml.Name `xml:"http://www.w3.org/2005/08/addressing To"`
22 | Value string `xml:",chardata"`
23 | }
24 |
25 | func MakeAnonymousAddressingHeaders(action, to string) []interface{} {
26 | return []interface{}{
27 | addressingAction {
28 | Value: action,
29 | },
30 | addressingReplyTo {
31 | Address: "http://www.w3.org/2005/08/addressing/anonymous",
32 | },
33 | addressingTo {
34 | Value: to,
35 | },
36 | }
37 | }
38 |
39 | // http://www.onvif.org/ver10/events/wsdl/PullPointSubscription/PullMessagesRequest
40 | // urn:uuid:5e6558cf-e5dc-42e5-9417-6372b3ed9a65
41 | //
42 | // http://www.w3.org/2005/08/addressing/anonymous
43 | //
44 | // http://10.110.3.252/onvif/event/subsription_4352
45 | // http://www.w3.org/2005/08/addressing/anonymous
46 | //
47 | // http://10.110.3.252/onvif/event/subsription_4352
48 |
--------------------------------------------------------------------------------
/events/events.wsdl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | The capabilities for the event service is returned in the Capabilities element.
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | Indicates that the WS Subscription policy is supported.
46 |
47 |
48 |
49 |
50 | Indicates that the WS Pull Point is supported.
51 |
52 |
53 |
54 |
55 | Indicates that the WS Pausable Subscription Manager Interface is supported.
56 |
57 |
58 |
59 |
60 | Maximum number of supported notification producers as defined by WS-BaseNotification.
61 |
62 |
63 |
64 |
65 | Maximum supported number of notification pull points.
66 |
67 |
68 |
69 |
70 | Indication if the device supports persistent notification storage.
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | Optional XPATH expression to select specific topics.
83 |
84 |
85 |
86 |
87 | Initial termination time.
88 |
89 |
90 |
91 |
92 | Refer to Web Services Base Notification 1.3 (WS-BaseNotification).
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | Endpoint reference of the subscription to be used for pulling the messages.
110 |
111 |
112 |
113 |
114 | Current time of the server for synchronization purposes.
115 |
116 |
117 |
118 |
119 | Date time when the PullPoint will be shut down without further pull requests.
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 | Maximum time to block until this method returns.
133 |
134 |
135 |
136 |
137 | Upper limit for the number of messages to return at once. A server implementation may decide to return less messages.
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 | The date and time when the messages have been delivered by the web server to the client.
150 |
151 |
152 |
153 |
154 | Date time when the PullPoint will be shut down without further pull requests.
155 |
156 |
157 |
158 |
159 | List of messages. This list shall be empty in case of a timeout.
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 | Maximum timeout supported by the device.
171 |
172 |
173 |
174 |
175 | Maximum message limit supported by the device.
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 | The date and time to match against stored messages.
187 | Reverse the pull direction of PullMessages.
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 | List of topic namespaces supported.
220 |
221 |
222 |
223 |
224 | True when topicset is fixed for all times.
225 |
226 |
227 |
228 |
229 | Set of topics supported.
230 |
231 |
232 |
233 |
234 |
235 | Defines the XPath expression syntax supported for matching topic expressions.
236 | The following TopicExpressionDialects are mandatory for an ONVIF compliant device :
237 |
238 | - http://docs.oasis-open.org/wsn/t-1/TopicExpression/Concrete
239 | - http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet.
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 | Defines the XPath function set supported for message content filtering.
248 | The following MessageContentFilterDialects should be returned if a device supports the message content filtering:
249 |
250 | - http://www.onvif.org/ver10/tev/messageContentFilter/ItemFilter.
251 |
252 | A device that does not support any MessageContentFilterDialect returns a single empty url.
253 |
254 |
255 |
256 |
257 |
258 |
259 | Optional ProducerPropertiesDialects. Refer to Web Services Base Notification 1.3 (WS-BaseNotification) for advanced filtering.
260 |
261 |
262 |
263 |
264 |
265 | The Message Content Description Language allows referencing
266 | of vendor-specific types. In order to ease the integration of such types into a client application,
267 | the GetEventPropertiesResponse shall list all URI locations to schema files whose types are
268 | used in the description of notifications, with MessageContentSchemaLocation elements.
269 | This list shall at least contain the URI of the ONVIF schema file.
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 | Optional ONVIF defined pull point subscription policies
283 |
284 |
285 |
286 |
287 | The pullpoint should not provide Initialized nor Deleted events for Properties.
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 | Returns the capabilities of the event service. The result is returned in a typed answer.
336 |
337 |
338 |
339 |
340 | This method returns a PullPointSubscription that can be polled using PullMessages.
341 | This message contains the same elements as the SubscriptionRequest of the WS-BaseNotification without the ConsumerReference.
342 | If no Filter is specified the pullpoint notifies all occurring events to the client.
343 | This method is mandatory.
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 | The WS-BaseNotification specification defines a set of OPTIONAL WS-ResouceProperties.
361 | This specification does not require the implementation of the WS-ResourceProperty interface.
362 | Instead, the subsequent direct interface shall be implemented by an ONVIF compliant device
363 | in order to provide information about the FilterDialects, Schema files and topics supported by
364 | the device.
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 | This method pulls one or more messages from a PullPoint.
373 | The device shall provide the following PullMessages command for all SubscriptionManager
374 | endpoints returned by the CreatePullPointSubscription command. This method shall not wait until
375 | the requested number of messages is available but return as soon as at least one message is available.
376 | The command shall at least support a Timeout of one minute. In case a device supports retrieval of less messages
377 | than requested it shall return these without generating a fault.
378 |
379 |
380 |
381 |
382 |
383 |
384 | This method readjusts the pull pointer into the past.
385 | A device supporting persistent notification storage shall provide the
386 | following Seek command for all SubscriptionManager endpoints returned by
387 | the CreatePullPointSubscription command. The optional Reverse argument can
388 | be used to reverse the pull direction of the PullMessages command.
389 | The UtcTime argument will be matched against the UtcTime attribute on a
390 | NotificationMessage.
391 |
392 |
393 |
394 |
395 |
396 | Properties inform a client about property creation, changes and
397 | deletion in a uniform way. When a client wants to synchronize its properties with the
398 | properties of the device, it can request a synchronization point which repeats the current
399 | status of all properties to which a client has subscribed. The PropertyOperation of all
400 | produced notifications is set to “Initialized”. The Synchronization Point is
401 | requested directly from the SubscriptionManager which was returned in either the
402 | SubscriptionResponse or in the CreatePullPointSubscriptionResponse. The property update is
403 | transmitted via the notification transportation of the notification interface. This method is mandatory.
404 |
405 |
406 |
407 |
408 |
409 | The device shall provide the following Unsubscribe command for all SubscriptionManager endpoints returned by the CreatePullPointSubscription command.
410 | This command shall terminate the lifetime of a pull point.
411 |
412 |
413 |
414 |
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 |
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 |
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 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
--------------------------------------------------------------------------------
/events/types.go:
--------------------------------------------------------------------------------
1 | package events
2 |
3 | import (
4 | "time"
5 |
6 | tt "github.com/faceterteam/onvif4go/onvif"
7 | "github.com/faceterteam/onvif4go/xsd"
8 | )
9 |
10 | type FilterType string
11 |
12 | // AbsoluteOrRelativeTimeType
13 | type AbsoluteOrRelativeTimeType struct { //wsnt http://docs.oasis-open.org/wsn/b-2.xsd
14 | duration *xsd.Duration
15 | dateTime *time.Time
16 | }
17 |
18 | // UnmarshalText unmarshal AbsoluteOrRelativeTimeType from text
19 | func (v *AbsoluteOrRelativeTimeType) UnmarshalText(text []byte) error {
20 | str := string(text)
21 | if str[0] == 'P' {
22 | var duration xsd.Duration
23 | err := duration.UnmarshalText(text)
24 | if err != nil {
25 | return err
26 | }
27 | v.duration = &duration
28 | } else {
29 | t, err := time.Parse(time.RFC3339Nano, str)
30 | if err != nil {
31 | return err
32 | }
33 | v.dateTime = &t
34 | }
35 |
36 | return nil
37 | }
38 |
39 | // MarshalText marshal AbsoluteOrRelativeTimeType to text
40 | func (v AbsoluteOrRelativeTimeType) MarshalText() ([]byte, error) {
41 | if v.duration == nil {
42 | return v.dateTime.MarshalText()
43 | }
44 | return v.duration.MarshalText()
45 | }
46 |
47 | // NewAbsoluteTimeType make *AbsoluteOrRelativeTimeType from time.Time
48 | func NewAbsoluteTimeType(dateTime time.Time) *AbsoluteOrRelativeTimeType {
49 | return &AbsoluteOrRelativeTimeType{dateTime: &dateTime}
50 | }
51 |
52 | // NewRelativeTimeType make *AbsoluteOrRelativeTimeType from time.Duration
53 | func NewRelativeTimeType(duration time.Duration) *AbsoluteOrRelativeTimeType {
54 | d := xsd.Duration(duration)
55 | return &AbsoluteOrRelativeTimeType{duration: &d}
56 | }
57 |
58 | type SubscriptionPolicy struct { //tev http://www.onvif.org/ver10/events/wsdl
59 | ChangedOnly bool `xml:"ChangedOnly,attr"`
60 | }
61 |
62 | type Capabilities struct { //tev
63 | WSSubscriptionPolicySupport bool `xml:"WSSubscriptionPolicySupport,attr"`
64 | WSPullPointSupport bool `xml:"WSPullPointSupport,attr"`
65 | WSPausableSubscriptionManagerInterfaceSupport bool `xml:"WSPausableSubscriptionManagerInterfaceSupport,attr"`
66 | MaxNotificationProducers int `xml:"MaxNotificationProducers,attr"`
67 | MaxPullPoints int `xml:"MaxPullPoints,attr"`
68 | PersistentNotificationStorage bool `xml:"PersistentNotificationStorage,attr"`
69 | }
70 |
71 | type EndpointReferenceType struct { //wsa http://www.w3.org/2005/08/addressing/ws-addr.xsd
72 | Address AttributedURIType `xml:"http://www.w3.org/2005/08/addressing Address"`
73 | ReferenceParameters *ReferenceParametersType
74 | Metadata
75 | }
76 |
77 | type AttributedURIType struct { //wsa https://www.w3.org/2005/08/addressing/ws-addr.xsd
78 | Content xsd.AnyURI `xml:",chardata"`
79 | //Here can be anyAttribute
80 | }
81 |
82 | type ReferenceParametersType struct { //wsa https://www.w3.org/2005/08/addressing/ws-addr.xsd
83 | Any string
84 | //Here can be anyAttribute
85 | }
86 |
87 | type Metadata MetadataType //wsa https://www.w3.org/2005/08/addressing/ws-addr.xsd
88 |
89 | type MetadataType struct { //wsa https://www.w3.org/2005/08/addressing/ws-addr.xsd
90 | Any string
91 | //Here can be anyAttribute
92 | }
93 |
94 | type CurrentTime xsd.DateTime //wsnt http://docs.oasis-open.org/wsn/b-2.xsd
95 | type TerminationTime xsd.DateTime //wsnt http://docs.oasis-open.org/wsn/b-2.xsd
96 | type FixedTopicSet bool //wsnt http://docs.oasis-open.org/wsn/b-2.xsd
97 |
98 | type TopicSet TopicSetType //wstop http://docs.oasis-open.org/wsn/t-1.xsd
99 |
100 | type TopicSetType struct { //wstop http://docs.oasis-open.org/wsn/t-1.xsd
101 | ExtensibleDocumented
102 | //here can be any element
103 | }
104 |
105 | type ExtensibleDocumented struct { //wstop http://docs.oasis-open.org/wsn/t-1.xsd
106 | Documentation Documentation //к xsd-документе documentation с маленькой буквы начинается
107 | //here can be anyAttribute
108 | }
109 |
110 | type Documentation xsd.AnyType //wstop http://docs.oasis-open.org/wsn/t-1.xsd
111 |
112 | type TopicExpressionDialect xsd.AnyURI
113 |
114 | type NotificationMessage NotificationMessageHolderType //wsnt http://docs.oasis-open.org/wsn/b-2.xsd
115 |
116 | type NotificationMessageHolderType struct {
117 | SubscriptionReference *SubscriptionReference //wsnt http://docs.oasis-open.org/wsn/b-2.xsd
118 | Topic Topic
119 | ProducerReference *ProducerReference
120 | Message OnvifEventsMessage
121 | }
122 |
123 | type SubscriptionReference EndpointReferenceType
124 | type Topic TopicExpressionType
125 | type ProducerReference EndpointReferenceType
126 |
127 | type OnvifEventsMessage struct {
128 | Messages []tt.Message `xml:"http://www.onvif.org/ver10/schema Message"`
129 | }
130 |
131 | type TopicExpressionType struct { //wsnt http://docs.oasis-open.org/wsn/b-2.xsd
132 | Dialect xsd.AnyURI `xml:"Dialect,attr"`
133 | Value string `xml:",chardata"`
134 | }
135 |
136 | //Event main types
137 |
138 | type GetServiceCapabilities struct {
139 | XMLName string `xml:"http://www.onvif.org/ver10/events/wsdl GetServiceCapabilities"`
140 | }
141 |
142 | type GetServiceCapabilitiesResponse struct {
143 | Capabilities Capabilities
144 | }
145 |
146 | type CreatePullPointSubscription struct {
147 | XMLName string `xml:"http://www.onvif.org/ver10/events/wsdl CreatePullPointSubscription"`
148 | Filter FilterType `xml:"http://www.onvif.org/ver10/events/wsdl Filter,omitempty"`
149 | InitialTerminationTime *AbsoluteOrRelativeTimeType `xml:"http://www.onvif.org/ver10/events/wsdl InitialTerminationTime,omitempty"`
150 | SubscriptionPolicy *SubscriptionPolicy `xml:"http://www.onvif.org/ver10/events/wsdl SubscriptionPolicy,omitempty"`
151 | }
152 |
153 | type CreatePullPointSubscriptionResponse struct {
154 | SubscriptionReference EndpointReferenceType `xml:"http://www.onvif.org/ver10/events/wsdl SubscriptionReference"`
155 | CurrentTime CurrentTime
156 | TerminationTime TerminationTime
157 | }
158 |
159 | type ResourceUnknownFault struct {
160 | }
161 |
162 | type InvalidFilterFault struct {
163 | }
164 |
165 | type TopicExpressionDialectUnknownFault struct {
166 | }
167 |
168 | type InvalidTopicExpressionFault struct {
169 | }
170 |
171 | type TopicNotSupportedFault struct {
172 | }
173 |
174 | type InvalidProducerPropertiesExpressionFault struct {
175 | }
176 |
177 | type InvalidMessageContentExpressionFault struct {
178 | }
179 |
180 | type UnacceptableInitialTerminationTimeFault struct {
181 | }
182 |
183 | type UnrecognizedPolicyRequestFault struct {
184 | }
185 |
186 | type UnsupportedPolicyRequestFault struct {
187 | }
188 |
189 | type NotifyMessageNotSupportedFault struct {
190 | }
191 |
192 | type SubscribeCreationFailedFault struct {
193 | }
194 |
195 | type GetEventProperties struct {
196 | XMLName string `xml:"http://www.onvif.org/ver10/events/wsdl GetEventProperties"`
197 | }
198 |
199 | type GetEventPropertiesResponse struct {
200 | TopicNamespaceLocation xsd.AnyURI
201 | FixedTopicSet FixedTopicSet
202 | TopicSet TopicSet
203 | TopicExpressionDialect TopicExpressionDialect
204 | MessageContentFilterDialect xsd.AnyURI
205 | ProducerPropertiesFilterDialect xsd.AnyURI
206 | MessageContentSchemaLocation xsd.AnyURI
207 | }
208 |
209 | //Port type PullPointSubscription
210 |
211 | type PullMessages struct {
212 | XMLName string `xml:"http://www.onvif.org/ver10/events/wsdl PullMessages"`
213 | Timeout xsd.Duration `xml:"http://www.onvif.org/ver10/events/wsdl Timeout"`
214 | MessageLimit int `xml:"http://www.onvif.org/ver10/events/wsdl MessageLimit"`
215 | }
216 |
217 | type PullMessagesResponse struct {
218 | CurrentTime CurrentTime
219 | TerminationTime TerminationTime
220 | NotificationMessages []NotificationMessage `xml:"http://docs.oasis-open.org/wsn/b-2 NotificationMessage"`
221 | }
222 |
223 | type PullMessagesFaultResponse struct {
224 | MaxTimeout xsd.Duration
225 | MaxMessageLimit int
226 | }
227 |
228 | type Seek struct {
229 | XMLName string `xml:"http://www.onvif.org/ver10/events/wsdl Seek"`
230 | UtcTime xsd.DateTime `xml:"http://www.onvif.org/ver10/events/wsdl UtcTime"`
231 | Reverse bool `xml:"http://www.onvif.org/ver10/events/wsdl Reverse"`
232 | }
233 |
234 | type SeekResponse struct {
235 | }
236 |
237 | type SetSynchronizationPoint struct {
238 | XMLName string `xml:"http://www.onvif.org/ver10/events/wsdl SetSynchronizationPoint"`
239 | }
240 |
241 | type SetSynchronizationPointResponse struct {
242 | }
243 |
244 | type UnsubscribeRequest struct {
245 | XMLName string `xml:"http://www.onvif.org/ver10/events/wsdl UnsubscribeRequest"`
246 | }
247 |
248 | type UnsubscribeResponse struct {
249 | }
250 |
--------------------------------------------------------------------------------
/eventsService.go:
--------------------------------------------------------------------------------
1 | package onvif4go
2 |
3 | import (
4 | tev "github.com/faceterteam/onvif4go/events"
5 | )
6 |
7 | type EventsService struct {
8 | Client onvifCaller
9 | endpoint string
10 | }
11 |
12 | func NewEventsService(endpoint string, onvifDevice *OnvifDevice) *EventsService {
13 | return &EventsService{
14 | Client: NewOnvifClient(endpoint, &onvifDevice.auth),
15 | endpoint: endpoint,
16 | }
17 | }
18 |
19 | func (s *EventsService) makeAddressingHeaders(action string) []interface{} {
20 | return tev.MakeAnonymousAddressingHeaders(action, s.endpoint)
21 | }
22 |
23 | // GetServiceCapabilities returns the capabilities of the event service.
24 | func (s *EventsService) GetServiceCapabilities() (res tev.GetServiceCapabilitiesResponse, err error) {
25 | headers := s.makeAddressingHeaders("http://www.onvif.org/ver10/events/wsdl/EventPortType/GetServiceCapabilitiesRequest")
26 | err = s.Client.Call(tev.GetServiceCapabilities{}, &res, headers...)
27 | return
28 | }
29 |
30 | /*
31 | GetEventProperties returns information about the FilterDialects, Schema files and
32 | topics supported by the device.
33 |
34 | The WS-BaseNotification specification defines a set of OPTIONAL WS-ResouceProperties.
35 | This specification does not require the implementation of the WS-ResourceProperty interface.
36 | Instead, the subsequent direct interface shall be implemented by an ONVIF compliant device
37 | in order to provide information about the FilterDialects, Schema files and topics supported by
38 | the device.
39 | */
40 | func (s *EventsService) GetEventProperties() (res tev.GetEventPropertiesResponse, err error) {
41 | headers := s.makeAddressingHeaders("http://www.onvif.org/ver10/events/wsdl/EventPortType/GetEventPropertiesRequest")
42 | err = s.Client.Call(tev.GetEventProperties{}, &res, headers...)
43 | return
44 | }
45 |
46 | /*
47 | CreatePullPointSubscription returns a PullPointSubscription that can be polled using PullMessages.
48 | This message contains the same elements as the SubscriptionRequest of the WS-BaseNotification
49 | without the ConsumerReference.
50 |
51 | If no Filter is specified the pullpoint notifies all occurring events to the client.
52 | */
53 | func (s *EventsService) CreatePullPointSubscription(filter string, changeOnly bool, initialTerminationTime *tev.AbsoluteOrRelativeTimeType) (res tev.CreatePullPointSubscriptionResponse, err error) {
54 | headers := s.makeAddressingHeaders("http://www.onvif.org/ver10/events/wsdl/EventPortType/CreatePullPointSubscriptionRequest")
55 | err = s.Client.Call(tev.CreatePullPointSubscription{
56 | Filter: tev.FilterType(filter),
57 | SubscriptionPolicy: &tev.SubscriptionPolicy{
58 | ChangedOnly: changeOnly,
59 | },
60 | InitialTerminationTime: initialTerminationTime,
61 | }, &res, headers...)
62 |
63 | /*
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | */
77 |
78 | return
79 | }
80 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/faceterteam/onvif4go
2 |
3 | go 1.12
4 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/faceterteam/onvif4go/8994ff013c81b76917ecb8954d1d409a632a2e92/go.sum
--------------------------------------------------------------------------------
/main/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "strconv"
6 | "time"
7 |
8 | "github.com/faceterteam/onvif4go"
9 | tev "github.com/faceterteam/onvif4go/events"
10 | )
11 |
12 | func main() {
13 | camera := onvif4go.NewOnvifDevice("10.110.3.235:8899") // OK
14 |
15 | camera.Auth("admin", "12345678q")
16 |
17 | err := camera.Initialize()
18 | if err != nil {
19 | fmt.Println("camera.Initialize error:", err.Error())
20 | return
21 | }
22 |
23 | di, err := camera.Device.GetDeviceInformation()
24 | fmt.Println(di)
25 | users, err := camera.Device.GetUsers()
26 | fmt.Println(users)
27 |
28 | //camera.Media.Client.SetLogger(logClient, logClient)
29 | // profiles, _ := camera.Media.GetProfiles()
30 | // for _, profile := range profiles.Profiles {
31 | // fmt.Println(profile.VideoEncoderConfiguration.SessionTimeout.String())
32 | // }
33 |
34 | eventServiceCapabilities, err := camera.Events.GetServiceCapabilities()
35 | if err != nil {
36 | fmt.Println("Events.GetServiceCapabilities error:", err.Error())
37 | //return
38 | } else {
39 | fmt.Println(eventServiceCapabilities.Capabilities)
40 | }
41 |
42 | //camera.Events.Client.SetLogger(logClient, logClient)
43 |
44 | pullPoint, err := camera.Events.CreatePullPointSubscription("", false, tev.NewRelativeTimeType(time.Second*600))
45 | if err != nil {
46 | fmt.Println("Events.CreatePullPointSubscription error:", err.Error())
47 | return
48 | }
49 |
50 | fmt.Println(pullPoint.SubscriptionReference.Address.Content)
51 |
52 | pullPointSubscription := onvif4go.NewPullPointSubscription(pullPoint, camera)
53 | //pullPointSubscription.Client.SetLogger(logClient, logClient)
54 |
55 | pullPointTicker := time.NewTicker(time.Second * 30)
56 |
57 | go func() {
58 |
59 | //currentTime := time.Now()
60 | currentState := false
61 |
62 | for {
63 | select {
64 | case _ = <-pullPointTicker.C:
65 | //fmt.Println("SetSynchronizationPoint", t)
66 |
67 | err := pullPointSubscription.SetSynchronizationPoint()
68 | if err != nil {
69 | fmt.Println("pullPoint.SetSynchronizationPoint error:", err.Error())
70 | }
71 | default:
72 | messages, err := pullPointSubscription.PullMessages(time.Second*5, 1024)
73 | if err != nil {
74 | fmt.Println("pullPoint.PullMessages error:", err.Error())
75 | return
76 | }
77 |
78 | //fmt.Println(messages.CurrentTime, messages.TerminationTime, len(messages.NotificationMessages))
79 |
80 | for _, message := range messages.NotificationMessages {
81 | if message.Topic.Value == "tns1:RuleEngine/CellMotionDetector/Motion" {
82 | for _, onvifMessage := range message.Message.Messages {
83 | isMotion, _ := strconv.ParseBool(onvifMessage.Data.SimpleItems["IsMotion"])
84 | if currentState != isMotion {
85 | currentState = isMotion
86 | //currentTime = onvifMessage.UtcTime
87 |
88 | fmt.Println(
89 | message.Topic.Value,
90 | *onvifMessage.PropertyOperation,
91 | onvifMessage.UtcTime,
92 | onvifMessage.Data.SimpleItems["IsMotion"])
93 | }
94 | }
95 | } else if message.Topic.Value == "tns1:VideoSource/MotionAlarm" {
96 | for _, onvifMessage := range message.Message.Messages {
97 | state, _ := strconv.ParseBool(onvifMessage.Data.SimpleItems["State"])
98 |
99 | if currentState != state {
100 | currentState = state
101 | //currentTime = onvifMessage.UtcTime
102 |
103 | fmt.Println(
104 | message.Topic.Value,
105 | *onvifMessage.PropertyOperation,
106 | onvifMessage.UtcTime,
107 | onvifMessage.Data.SimpleItems["State"])
108 | }
109 | }
110 | } else {
111 | fmt.Println(message.Topic.Value)
112 | }
113 | }
114 | }
115 | }
116 |
117 | pullPointSubscription.Unsubscribe()
118 | }()
119 |
120 | time.Sleep(60 * time.Minute)
121 | }
122 |
123 | func logClient(message string) {
124 | fmt.Println(message)
125 | }
126 |
--------------------------------------------------------------------------------
/media/types.go:
--------------------------------------------------------------------------------
1 | package media
2 |
3 | import (
4 | "github.com/faceterteam/onvif4go/onvif"
5 | )
6 |
7 | type Capabilities struct {
8 | SnapshotUri bool `xml:"SnapshotUri,attr"`
9 | Rotation bool `xml:"Rotation,attr"`
10 | VideoSourceMode bool `xml:"VideoSourceMode,attr"`
11 | OSD bool `xml:"OSD,attr"`
12 | TemporaryOSDText bool `xml:"TemporaryOSDText,attr"`
13 | EXICompression bool `xml:"EXICompression,attr"`
14 | ProfileCapabilities ProfileCapabilities
15 | StreamingCapabilities StreamingCapabilities
16 | }
17 |
18 | type ProfileCapabilities struct {
19 | MaximumNumberOfProfiles int `xml:"MaximumNumberOfProfiles,attr"`
20 | }
21 |
22 | type StreamingCapabilities struct {
23 | RTPMulticast bool `xml:"RTPMulticast,attr"`
24 | RTP_TCP bool `xml:"RTP_TCP,attr"`
25 | RTP_RTSP_TCP bool `xml:"RTP_RTSP_TCP,attr"`
26 | NonAggregateControl bool `xml:"NonAggregateControl,attr"`
27 | NoRTSPStreaming bool `xml:"NoRTSPStreaming,attr"`
28 | }
29 |
30 | //Media main types
31 |
32 | type GetServiceCapabilities struct {
33 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetServiceCapabilities"`
34 | }
35 |
36 | type GetServiceCapabilitiesResponse struct {
37 | Capabilities Capabilities
38 | }
39 |
40 | type GetVideoSources struct {
41 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetVideoSources"`
42 | }
43 |
44 | type GetVideoSourcesResponse struct {
45 | VideoSources []onvif.VideoSource
46 | }
47 |
48 | type GetAudioSources struct {
49 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetAudioSources"`
50 | }
51 |
52 | type GetAudioSourcesResponse struct {
53 | AudioSources []onvif.AudioSource
54 | }
55 |
56 | type GetAudioOutputs struct {
57 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetAudioOutputs"`
58 | }
59 |
60 | type GetAudioOutputsResponse struct {
61 | AudioOutputs []onvif.AudioOutput
62 | }
63 |
64 | type CreateProfile struct {
65 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl CreateProfile"`
66 | Name onvif.Name `xml:"http://www.onvif.org/ver10/media/wsdl Name"`
67 | Token onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl Token"`
68 | }
69 |
70 | type CreateProfileResponse struct {
71 | Profile onvif.Profile
72 | }
73 |
74 | type GetProfile struct {
75 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetProfile"`
76 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
77 | }
78 |
79 | type GetProfileResponse struct {
80 | Profiles onvif.Profile
81 | }
82 |
83 | type GetProfiles struct {
84 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetProfiles"`
85 | }
86 |
87 | type GetProfilesResponse struct {
88 | Profiles []onvif.Profile
89 | }
90 |
91 | type AddVideoEncoderConfiguration struct {
92 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl AddVideoEncoderConfiguration"`
93 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
94 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
95 | }
96 |
97 | type AddVideoEncoderConfigurationResponse struct {
98 | }
99 |
100 | type RemoveVideoEncoderConfiguration struct {
101 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl RemoveVideoEncoderConfiguration"`
102 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
103 | }
104 |
105 | type RemoveVideoEncoderConfigurationResponse struct {
106 | }
107 |
108 | type AddVideoSourceConfiguration struct {
109 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl AddVideoSourceConfiguration"`
110 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
111 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
112 | }
113 |
114 | type AddVideoSourceConfigurationResponse struct {
115 | }
116 |
117 | type RemoveVideoSourceConfiguration struct {
118 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl RemoveVideoSourceConfiguration"`
119 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
120 | }
121 |
122 | type RemoveVideoSourceConfigurationResponse struct {
123 | }
124 |
125 | type AddAudioEncoderConfiguration struct {
126 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl AddAudioEncoderConfiguration"`
127 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
128 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
129 | }
130 |
131 | type AddAudioEncoderConfigurationResponse struct {
132 | }
133 |
134 | type RemoveAudioEncoderConfiguration struct {
135 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl RemoveAudioEncoderConfiguration"`
136 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
137 | }
138 |
139 | type RemoveAudioEncoderConfigurationResponse struct {
140 | }
141 |
142 | type AddAudioSourceConfiguration struct {
143 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl AddAudioSourceConfiguration"`
144 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
145 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
146 | }
147 |
148 | type AddAudioSourceConfigurationResponse struct {
149 | }
150 |
151 | type RemoveAudioSourceConfiguration struct {
152 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl RemoveAudioSourceConfiguration"`
153 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
154 | }
155 |
156 | type RemoveAudioSourceConfigurationResponse struct {
157 | }
158 |
159 | type AddPTZConfiguration struct {
160 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl AddPTZConfiguration"`
161 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
162 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
163 | }
164 |
165 | type AddPTZConfigurationResponse struct {
166 | }
167 |
168 | type RemovePTZConfiguration struct {
169 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl RemovePTZConfiguration"`
170 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
171 | }
172 |
173 | type RemovePTZConfigurationResponse struct {
174 | }
175 |
176 | type AddVideoAnalyticsConfiguration struct {
177 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl AddVideoAnalyticsConfiguration"`
178 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
179 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
180 | }
181 |
182 | type AddVideoAnalyticsConfigurationResponse struct {
183 | }
184 |
185 | type RemoveVideoAnalyticsConfiguration struct {
186 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl RemoveVideoAnalyticsConfiguration"`
187 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
188 | }
189 |
190 | type RemoveVideoAnalyticsConfigurationResponse struct {
191 | }
192 |
193 | type AddMetadataConfiguration struct {
194 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl AddMetadataConfiguration"`
195 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
196 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
197 | }
198 |
199 | type AddMetadataConfigurationResponse struct {
200 | }
201 |
202 | type RemoveMetadataConfiguration struct {
203 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl RemoveMetadataConfiguration"`
204 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
205 | }
206 |
207 | type RemoveMetadataConfigurationResponse struct {
208 | }
209 |
210 | type AddAudioOutputConfiguration struct {
211 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl AddAudioOutputConfiguration"`
212 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
213 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
214 | }
215 |
216 | type AddAudioOutputConfigurationResponse struct {
217 | }
218 |
219 | type RemoveAudioOutputConfiguration struct {
220 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl RemoveAudioOutputConfiguration"`
221 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
222 | }
223 |
224 | type RemoveAudioOutputConfigurationResponse struct {
225 | }
226 |
227 | type AddAudioDecoderConfiguration struct {
228 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl AddAudioDecoderConfiguration"`
229 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
230 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
231 | }
232 |
233 | type AddAudioDecoderConfigurationResponse struct {
234 | }
235 |
236 | type RemoveAudioDecoderConfiguration struct {
237 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl RemoveAudioDecoderConfiguration"`
238 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
239 | }
240 |
241 | type RemoveAudioDecoderConfigurationResponse struct {
242 | }
243 |
244 | type DeleteProfile struct {
245 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl DeleteProfile"`
246 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
247 | }
248 |
249 | type DeleteProfileResponse struct {
250 | }
251 |
252 | type GetVideoSourceConfigurations struct {
253 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetVideoSourceConfigurations"`
254 | }
255 |
256 | type GetVideoSourceConfigurationsResponse struct {
257 | Configurations []onvif.VideoSourceConfiguration
258 | }
259 |
260 | type GetVideoEncoderConfigurations struct {
261 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetVideoEncoderConfigurations"`
262 | }
263 |
264 | type GetVideoEncoderConfigurationsResponse struct {
265 | Configurations []onvif.VideoEncoderConfiguration
266 | }
267 |
268 | type GetAudioSourceConfigurations struct {
269 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetAudioSourceConfigurations"`
270 | }
271 |
272 | type GetAudioSourceConfigurationsResponse struct {
273 | Configurations []onvif.AudioSourceConfiguration
274 | }
275 |
276 | type GetAudioEncoderConfigurations struct {
277 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetAudioEncoderConfigurations"`
278 | }
279 |
280 | type GetAudioEncoderConfigurationsResponse struct {
281 | Configurations []onvif.AudioEncoderConfiguration
282 | }
283 |
284 | type GetVideoAnalyticsConfigurations struct {
285 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetVideoAnalyticsConfigurations"`
286 | }
287 |
288 | type GetVideoAnalyticsConfigurationsResponse struct {
289 | Configurations []onvif.VideoAnalyticsConfiguration
290 | }
291 |
292 | type GetMetadataConfigurations struct {
293 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetMetadataConfigurations"`
294 | }
295 |
296 | type GetMetadataConfigurationsResponse struct {
297 | Configurations []onvif.MetadataConfiguration
298 | }
299 |
300 | type GetAudioOutputConfigurations struct {
301 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetAudioOutputConfigurations"`
302 | }
303 |
304 | type GetAudioOutputConfigurationsResponse struct {
305 | Configurations []onvif.AudioOutputConfiguration
306 | }
307 |
308 | type GetAudioDecoderConfigurations struct {
309 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetAudioDecoderConfigurations"`
310 | }
311 |
312 | type GetAudioDecoderConfigurationsResponse struct {
313 | Configurations []onvif.AudioDecoderConfiguration
314 | }
315 |
316 | type GetVideoSourceConfiguration struct {
317 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetVideoSourceConfiguration"`
318 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
319 | }
320 |
321 | type GetVideoSourceConfigurationResponse struct {
322 | Configuration onvif.VideoSourceConfiguration
323 | }
324 |
325 | type GetVideoEncoderConfiguration struct {
326 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetVideoEncoderConfiguration"`
327 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
328 | }
329 |
330 | type GetVideoEncoderConfigurationResponse struct {
331 | Configuration onvif.VideoEncoderConfiguration
332 | }
333 |
334 | type GetAudioSourceConfiguration struct {
335 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetAudioSourceConfiguration"`
336 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
337 | }
338 |
339 | type GetAudioSourceConfigurationResponse struct {
340 | Configuration onvif.AudioSourceConfiguration
341 | }
342 |
343 | type GetAudioEncoderConfiguration struct {
344 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetAudioEncoderConfiguration"`
345 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
346 | }
347 |
348 | type GetAudioEncoderConfigurationResponse struct {
349 | Configuration onvif.AudioEncoderConfiguration
350 | }
351 |
352 | type GetVideoAnalyticsConfiguration struct {
353 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetVideoAnalyticsConfiguration"`
354 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
355 | }
356 |
357 | type GetVideoAnalyticsConfigurationResponse struct {
358 | Configuration onvif.VideoAnalyticsConfiguration
359 | }
360 |
361 | type GetMetadataConfiguration struct {
362 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetMetadataConfiguration"`
363 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
364 | }
365 |
366 | type GetMetadataConfigurationResponse struct {
367 | Configuration onvif.MetadataConfiguration
368 | }
369 |
370 | type GetAudioOutputConfiguration struct {
371 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetAudioOutputConfiguration"`
372 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
373 | }
374 |
375 | type GetAudioOutputConfigurationResponse struct {
376 | Configuration onvif.AudioOutputConfiguration
377 | }
378 |
379 | type GetAudioDecoderConfiguration struct {
380 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetAudioDecoderConfiguration"`
381 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
382 | }
383 |
384 | type GetAudioDecoderConfigurationResponse struct {
385 | Configuration onvif.AudioDecoderConfiguration
386 | }
387 |
388 | type GetCompatibleVideoEncoderConfigurations struct {
389 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetCompatibleVideoEncoderConfigurations"`
390 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
391 | }
392 |
393 | type GetCompatibleVideoEncoderConfigurationsResponse struct {
394 | Configurations []onvif.VideoEncoderConfiguration
395 | }
396 |
397 | type GetCompatibleVideoSourceConfigurations struct {
398 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetCompatibleVideoSourceConfigurations"`
399 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
400 | }
401 |
402 | type GetCompatibleVideoSourceConfigurationsResponse struct {
403 | Configurations []onvif.VideoSourceConfiguration
404 | }
405 |
406 | type GetCompatibleAudioEncoderConfigurations struct {
407 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetCompatibleAudioEncoderConfigurations"`
408 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
409 | }
410 |
411 | type GetCompatibleAudioEncoderConfigurationsResponse struct {
412 | Configurations []onvif.AudioEncoderConfiguration
413 | }
414 |
415 | type GetCompatibleAudioSourceConfigurations struct {
416 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetCompatibleAudioSourceConfigurations"`
417 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
418 | }
419 |
420 | type GetCompatibleAudioSourceConfigurationsResponse struct {
421 | Configurations []onvif.AudioSourceConfiguration
422 | }
423 |
424 | type GetCompatibleVideoAnalyticsConfigurations struct {
425 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetCompatibleVideoAnalyticsConfigurations"`
426 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
427 | }
428 |
429 | type GetCompatibleVideoAnalyticsConfigurationsResponse struct {
430 | Configurations []onvif.VideoAnalyticsConfiguration
431 | }
432 |
433 | type GetCompatibleMetadataConfigurations struct {
434 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetCompatibleMetadataConfigurations"`
435 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
436 | }
437 |
438 | type GetCompatibleMetadataConfigurationsResponse struct {
439 | Configurations []onvif.MetadataConfiguration
440 | }
441 |
442 | type GetCompatibleAudioOutputConfigurations struct {
443 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetCompatibleAudioOutputConfigurations"`
444 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
445 | }
446 |
447 | type GetCompatibleAudioOutputConfigurationsResponse struct {
448 | Configurations []onvif.AudioOutputConfiguration
449 | }
450 |
451 | type GetCompatibleAudioDecoderConfigurations struct {
452 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetCompatibleAudioDecoderConfigurations"`
453 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
454 | }
455 |
456 | type GetCompatibleAudioDecoderConfigurationsResponse struct {
457 | Configurations []onvif.AudioDecoderConfiguration
458 | }
459 |
460 | type SetVideoSourceConfiguration struct {
461 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl SetVideoSourceConfiguration"`
462 | Configuration onvif.VideoSourceConfiguration `xml:"http://www.onvif.org/ver10/media/wsdl Configuration"`
463 | ForcePersistence bool `xml:"http://www.onvif.org/ver10/media/wsdl ForcePersistence"`
464 | }
465 |
466 | type SetVideoSourceConfigurationResponse struct {
467 | }
468 |
469 | type SetVideoEncoderConfiguration struct {
470 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl SetVideoEncoderConfiguration"`
471 | Configuration onvif.VideoEncoderConfiguration `xml:"http://www.onvif.org/ver10/media/wsdl Configuration"`
472 | ForcePersistence bool `xml:"http://www.onvif.org/ver10/media/wsdl ForcePersistence"`
473 | }
474 |
475 | type SetVideoEncoderConfigurationResponse struct {
476 | }
477 |
478 | type SetAudioSourceConfiguration struct {
479 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl SetAudioSourceConfiguration"`
480 | Configuration onvif.AudioSourceConfiguration `xml:"http://www.onvif.org/ver10/media/wsdl Configuration"`
481 | ForcePersistence bool `xml:"http://www.onvif.org/ver10/media/wsdl ForcePersistence"`
482 | }
483 |
484 | type SetAudioSourceConfigurationResponse struct {
485 | }
486 |
487 | type SetAudioEncoderConfiguration struct {
488 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl SetAudioEncoderConfiguration"`
489 | Configuration onvif.AudioEncoderConfiguration `xml:"http://www.onvif.org/ver10/media/wsdl Configuration"`
490 | ForcePersistence bool `xml:"http://www.onvif.org/ver10/media/wsdl ForcePersistence"`
491 | }
492 |
493 | type SetAudioEncoderConfigurationResponse struct {
494 | }
495 |
496 | type SetVideoAnalyticsConfiguration struct {
497 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl SetVideoAnalyticsConfiguration"`
498 | Configuration onvif.VideoAnalyticsConfiguration `xml:"http://www.onvif.org/ver10/media/wsdl Configuration"`
499 | ForcePersistence bool `xml:"http://www.onvif.org/ver10/media/wsdl ForcePersistence"`
500 | }
501 |
502 | type SetVideoAnalyticsConfigurationResponse struct {
503 | }
504 |
505 | type SetMetadataConfiguration struct {
506 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetDeviceInformation"`
507 | Configuration onvif.MetadataConfiguration `xml:"http://www.onvif.org/ver10/media/wsdl Configuration"`
508 | ForcePersistence bool `xml:"http://www.onvif.org/ver10/media/wsdl ForcePersistence"`
509 | }
510 |
511 | type SetMetadataConfigurationResponse struct {
512 | }
513 |
514 | type SetAudioOutputConfiguration struct {
515 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl SetAudioOutputConfiguration"`
516 | Configuration onvif.AudioOutputConfiguration `xml:"http://www.onvif.org/ver10/media/wsdl Configuration"`
517 | ForcePersistence bool `xml:"http://www.onvif.org/ver10/media/wsdl ForcePersistence"`
518 | }
519 |
520 | type SetAudioOutputConfigurationResponse struct {
521 | }
522 |
523 | type SetAudioDecoderConfiguration struct {
524 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl SetAudioDecoderConfiguration"`
525 | Configuration onvif.AudioDecoderConfiguration `xml:"http://www.onvif.org/ver10/media/wsdl Configuration"`
526 | ForcePersistence bool `xml:"http://www.onvif.org/ver10/media/wsdl ForcePersistence"`
527 | }
528 |
529 | type SetAudioDecoderConfigurationResponse struct {
530 | }
531 |
532 | type GetVideoSourceConfigurationOptions struct {
533 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetVideoSourceConfigurationOptions"`
534 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
535 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
536 | }
537 |
538 | type GetVideoSourceConfigurationOptionsResponse struct {
539 | Options onvif.VideoSourceConfigurationOptions
540 | }
541 |
542 | type GetVideoEncoderConfigurationOptions struct {
543 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetVideoEncoderConfigurationOptions"`
544 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
545 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
546 | }
547 |
548 | type GetVideoEncoderConfigurationOptionsResponse struct {
549 | Options onvif.VideoEncoderConfigurationOptions
550 | }
551 |
552 | type GetAudioSourceConfigurationOptions struct {
553 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetAudioSourceConfigurationOptions"`
554 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
555 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
556 | }
557 |
558 | type GetAudioSourceConfigurationOptionsResponse struct {
559 | Options onvif.AudioSourceConfigurationOptions
560 | }
561 |
562 | type GetAudioEncoderConfigurationOptions struct {
563 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetAudioEncoderConfigurationOptions"`
564 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
565 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
566 | }
567 |
568 | type GetAudioEncoderConfigurationOptionsResponse struct {
569 | Options onvif.AudioEncoderConfigurationOptions
570 | }
571 |
572 | type GetMetadataConfigurationOptions struct {
573 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetMetadataConfigurationOptions"`
574 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
575 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
576 | }
577 |
578 | type GetMetadataConfigurationOptionsResponse struct {
579 | Options onvif.MetadataConfigurationOptions
580 | }
581 |
582 | type GetAudioOutputConfigurationOptions struct {
583 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetAudioOutputConfigurationOptions"`
584 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
585 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
586 | }
587 |
588 | type GetAudioOutputConfigurationOptionsResponse struct {
589 | Options onvif.AudioOutputConfigurationOptions
590 | }
591 |
592 | type GetAudioDecoderConfigurationOptions struct {
593 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetAudioDecoderConfigurationOptions"`
594 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
595 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
596 | }
597 |
598 | type GetAudioDecoderConfigurationOptionsResponse struct {
599 | Options onvif.AudioDecoderConfigurationOptions
600 | }
601 |
602 | type GetGuaranteedNumberOfVideoEncoderInstances struct {
603 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetGuaranteedNumberOfVideoEncoderInstances"`
604 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
605 | }
606 |
607 | type GetGuaranteedNumberOfVideoEncoderInstancesResponse struct {
608 | TotalNumber int
609 | JPEG int
610 | H264 int
611 | MPEG4 int
612 | }
613 |
614 | type GetStreamUri struct {
615 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetStreamUri"`
616 | StreamSetup onvif.StreamSetup `xml:"http://www.onvif.org/ver10/media/wsdl StreamSetup"`
617 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
618 | }
619 |
620 | type GetStreamUriResponse struct {
621 | MediaUri onvif.MediaUri
622 | }
623 |
624 | type StartMulticastStreaming struct {
625 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl StartMulticastStreaming"`
626 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
627 | }
628 |
629 | type StartMulticastStreamingResponse struct {
630 | }
631 |
632 | type StopMulticastStreaming struct {
633 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl StopMulticastStreaming"`
634 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
635 | }
636 |
637 | type StopMulticastStreamingResponse struct {
638 | }
639 |
640 | type SetSynchronizationPoint struct {
641 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl SetSynchronizationPoint"`
642 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
643 | }
644 |
645 | type SetSynchronizationPointResponse struct {
646 | }
647 |
648 | type GetSnapshotUri struct {
649 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetSnapshotUri"`
650 | ProfileToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ProfileToken"`
651 | }
652 |
653 | type GetSnapshotUriResponse struct {
654 | MediaUri onvif.MediaUri
655 | }
656 |
657 | type GetVideoSourceModes struct {
658 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetVideoSourceModes"`
659 | VideoSourceToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl VideoSourceToken"`
660 | }
661 |
662 | type GetVideoSourceModesResponse struct {
663 | VideoSourceModes []onvif.VideoSourceMode
664 | }
665 |
666 | type SetVideoSourceMode struct {
667 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl SetVideoSourceMode"`
668 | VideoSourceToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl VideoSourceToken"`
669 | VideoSourceModeToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl VideoSourceModeToken"`
670 | }
671 |
672 | type SetVideoSourceModeResponse struct {
673 | Reboot bool
674 | }
675 |
676 | type GetOSDs struct {
677 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetOSDs"`
678 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
679 | }
680 |
681 | type GetOSDsResponse struct {
682 | OSDs []onvif.OSDConfiguration
683 | }
684 |
685 | type GetOSD struct {
686 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetOSD"`
687 | OSDToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl OSDToken"`
688 | }
689 |
690 | type GetOSDResponse struct {
691 | OSD onvif.OSDConfiguration
692 | }
693 |
694 | type GetOSDOptions struct {
695 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl GetOSDOptions"`
696 | ConfigurationToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl ConfigurationToken"`
697 | }
698 |
699 | type GetOSDOptionsResponse struct {
700 | OSDOptions onvif.OSDConfigurationOptions
701 | }
702 |
703 | type SetOSD struct {
704 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl SetOSD"`
705 | OSD onvif.OSDConfiguration `xml:"http://www.onvif.org/ver10/media/wsdl OSD"`
706 | }
707 |
708 | type SetOSDResponse struct {
709 | }
710 |
711 | type CreateOSD struct {
712 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl CreateOSD"`
713 | OSD onvif.OSDConfiguration `xml:"http://www.onvif.org/ver10/media/wsdl OSD"`
714 | }
715 |
716 | type CreateOSDResponse struct {
717 | OSDToken onvif.ReferenceToken
718 | }
719 |
720 | type DeleteOSD struct {
721 | XMLName string `xml:"http://www.onvif.org/ver10/media/wsdl DeleteOSD"`
722 | OSDToken onvif.ReferenceToken `xml:"http://www.onvif.org/ver10/media/wsdl OSDToken"`
723 | }
724 |
725 | type DeleteOSDResponse struct {
726 | }
727 |
--------------------------------------------------------------------------------
/onvif/common.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Unique identifier for a physical or logical resource.
11 | Tokens should be assigned such that they are unique within a device. Tokens must be at least unique within its class.
12 | Length up to 64 characters.
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | Pan/tilt coordinate space selector. The following options are defined:
28 | - http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace
29 | - http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace
30 | - http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace
31 | - http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | Zoom coordinate space selector. The following options are defined:
43 | - http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace
44 | - http://www.onvif.org/ver10/tptz/ZoomSpaces/TranslationGenericSpace
45 | - http://www.onvif.org/ver10/tptz/ZoomSpaces/VelocityGenericSpace
46 | - http://www.onvif.org/ver10/tptz/ZoomSpaces/ZoomGenericSpeedSpace
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | Pan and tilt position. The x component corresponds to pan and the y component to tilt.
57 |
58 |
59 |
60 |
61 |
62 | A zoom position.
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | 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.
74 |
75 |
76 |
77 |
78 |
79 |
80 | Indicates if the Pan/Tilt/Zoom device unit is currently moving, idle or in an unknown state.
81 |
82 |
83 |
84 |
85 |
86 |
87 | States a current PTZ error.
88 |
89 |
90 |
91 |
92 |
93 |
94 | Specifies the UTC time when this status was generated.
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
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 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 | East west location as angle.
185 |
186 |
187 |
188 |
189 | North south location as angle.
190 |
191 |
192 |
193 |
194 | Hight in meters above sea level.
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 | Rotation around the x axis.
207 |
208 |
209 |
210 |
211 | Rotation around the y axis.
212 |
213 |
214 |
215 |
216 | Rotation around the z axis.
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 | East west location as angle.
229 |
230 |
231 |
232 |
233 | North south location as angle.
234 |
235 |
236 |
237 |
238 | Offset in meters from the sea level.
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 | Rotation around the y axis.
251 |
252 |
253 |
254 |
255 | Rotation around the z axis.
256 |
257 |
258 |
259 |
260 | Rotation around the x axis.
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 | Location on earth.
278 |
279 |
280 | Orientation relative to earth.
281 |
282 |
283 | Indoor location offset.
284 |
285 |
286 | Indoor orientation offset.
287 |
288 |
289 |
290 | Entity type the entry refers to, use a value from the tt:Entity enumeration.
291 |
292 |
293 | Optional entity token.
294 |
295 |
296 | If this value is true the entity cannot be deleted.
297 |
298 |
299 | Optional reference to the XAddr of another devices DeviceManagement service.
300 |
301 |
302 | If set the geo location is obtained internally.
303 |
304 |
305 |
306 |
307 |
--------------------------------------------------------------------------------
/onvif/itemlist.go:
--------------------------------------------------------------------------------
1 | package onvif
2 |
3 | import (
4 | "encoding/xml"
5 |
6 | "github.com/faceterteam/onvif4go/xsd"
7 | )
8 |
9 | type ItemList struct {
10 | SimpleItems map[string]string `xml:"http://www.onvif.org/ver10/schema SimpleItem"`
11 | ElementItems map[string][]xsd.AnyType `xml:"http://www.onvif.org/ver10/schema ElementItem"`
12 | Extension *ItemListExtension `xml:"http://www.onvif.org/ver10/schema Extension"`
13 | }
14 |
15 | func (l *ItemList) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
16 | *l = ItemList{}
17 |
18 | var (
19 | token xml.Token
20 | err error
21 | )
22 |
23 | Loop:
24 | for {
25 | if token, err = d.Token(); err != nil {
26 | return err
27 | }
28 | if token == nil {
29 | break
30 | }
31 |
32 | switch se := token.(type) {
33 | case xml.StartElement:
34 | if se.Name.Space != "http://www.onvif.org/ver10/schema" {
35 | return xml.UnmarshalError("expected tt:SimpleItem, tt:ElementItem... but receive")
36 | }
37 |
38 | if se.Name.Local == "SimpleItem" {
39 | simpleItem := &ItemListSimpleItem{}
40 | err = d.DecodeElement(simpleItem, &se)
41 | if err != nil {
42 | return err
43 | }
44 | if l.SimpleItems == nil {
45 | l.SimpleItems = make(map[string]string, 0)
46 | }
47 | l.SimpleItems[simpleItem.Name] = simpleItem.Value
48 | } else if se.Name.Local == "ElementItem" {
49 | elementItem := &ItemListElementItem{}
50 | err = d.DecodeElement(elementItem, &se)
51 | if err != nil {
52 | return err
53 | }
54 | if l.ElementItems == nil {
55 | l.ElementItems = make(map[string][]xsd.AnyType, 0)
56 | }
57 | l.ElementItems[elementItem.Name] = elementItem.Elements
58 | } else if se.Name.Local == "Extension" {
59 | err = d.DecodeElement(l.Extension, &se)
60 | if err != nil {
61 | return err
62 | }
63 | } else {
64 | return xml.UnmarshalError("expected tt:SimpleItem, tt:ElementItem... but receive")
65 | }
66 | case xml.EndElement:
67 | break Loop
68 | }
69 | }
70 |
71 | return nil
72 | }
73 |
74 | type ItemListSimpleItem struct {
75 | Name string `xml:"Name,attr"`
76 | Value string `xml:"Value,attr"`
77 | }
78 |
79 | type ItemListElementItem struct {
80 | Name string `xml:"Name,attr"`
81 | Elements []xsd.AnyType `xml:",any"`
82 | }
83 |
84 | type ItemListExtension xsd.AnyType
85 |
--------------------------------------------------------------------------------
/onvif/message.go:
--------------------------------------------------------------------------------
1 | package onvif
2 |
3 | import (
4 | "github.com/faceterteam/onvif4go/xsd"
5 | )
6 |
7 | type Message struct {
8 | UtcTime xsd.DateTime `xml:"UtcTime,attr"`
9 | PropertyOperation *string `xml:"PropertyOperation,attr"`
10 | Source *ItemList `xml:"http://www.onvif.org/ver10/schema Source"`
11 | Key *ItemList `xml:"http://www.onvif.org/ver10/schema Key"`
12 | Data *ItemList `xml:"http://www.onvif.org/ver10/schema Data"`
13 | Extension *MessageExtension `xml:"http://www.onvif.org/ver10/schema Extension"`
14 | }
15 |
16 | type MessageExtension xsd.AnyType
17 |
--------------------------------------------------------------------------------
/onvif/posix_timezone.go:
--------------------------------------------------------------------------------
1 | package onvif
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | "strconv"
7 | "strings"
8 | "time"
9 | )
10 |
11 | type PosixTimezone struct {
12 | Name string
13 | Offset posixTimezoneOffset
14 | Dailing *posixTimezoneDailing
15 | }
16 |
17 | type posixTimezoneOffset struct {
18 | Hours int
19 | Minutes int
20 | }
21 |
22 | type posixTimezoneDailing struct {
23 | Name string
24 | Offset posixTimezoneOffset
25 | From posixTimezoneTime
26 | To posixTimezoneTime
27 | }
28 |
29 | type posixTimezoneTime struct {
30 | Month int
31 | Week int
32 | Weekday int
33 | Hours int
34 | Minutes int
35 | Seconds int
36 | }
37 |
38 | func newPosixTimezoneDailing(st *posixTimezoneOffset, name string) *posixTimezoneDailing {
39 | return &posixTimezoneDailing{
40 | Name: name,
41 | Offset: posixTimezoneOffset{
42 | Hours: st.Hours + 1, //TODO: + или -
43 | },
44 | From: posixTimezoneTime{
45 | Month: 3,
46 | Week: 2,
47 | Weekday: 0,
48 | Hours: 2,
49 | },
50 | To: posixTimezoneTime{
51 | Month: 11,
52 | Week: 1,
53 | Weekday: 0,
54 | Hours: 2,
55 | },
56 | }
57 | }
58 |
59 | func ParsePosixTimezone(timezone string) (*PosixTimezone, error) {
60 | type PosixTimezonePart int
61 | const (
62 | ST PosixTimezonePart = iota + 1
63 | STOFFSET
64 | STOFFSETMINUTES
65 | DT
66 | DTOFFSET
67 | DTOFFSETMINUTES
68 | )
69 |
70 | var err error
71 | tz := PosixTimezone{}
72 |
73 | parts := strings.Split(timezone, `,`)
74 | if len(parts) != 1 && len(parts) != 3 {
75 | return nil, errors.New("invalid format")
76 | }
77 |
78 | local := parts[0]
79 | state, start := ST, 0
80 |
81 | for i, ch := range local {
82 | nstate, nstart := state, start
83 |
84 | switch state {
85 | case ST:
86 | if ch < 'A' || ch > 'Z' {
87 | tz.Name = local[start:i]
88 | nstate, nstart = STOFFSET, i
89 | }
90 | case STOFFSET:
91 | if ch >= 'A' && ch <= 'Z' {
92 | tz.Offset.Hours, err = strconv.Atoi(local[start:i])
93 | nstate, nstart = DT, i
94 | }
95 | if ch == ':' || ch == ' ' {
96 | tz.Offset.Hours, err = strconv.Atoi(local[start:i])
97 | nstate, nstart = STOFFSETMINUTES, i+1
98 | }
99 | case STOFFSETMINUTES:
100 | if ch >= 'A' && ch <= 'Z' {
101 | tz.Offset.Minutes, err = strconv.Atoi(local[start:i])
102 | nstate, nstart = DT, i
103 | }
104 | case DT:
105 | if ch < 'A' && ch > 'Z' {
106 | tz.Dailing = newPosixTimezoneDailing(&tz.Offset, local[start:i])
107 | nstate, nstart = DTOFFSET, i
108 | }
109 | case DTOFFSET:
110 | if ch == ':' || ch == ' ' {
111 | tz.Dailing.Offset.Hours, err = strconv.Atoi(local[start:i])
112 | nstate, nstart = DTOFFSETMINUTES, i+1
113 | }
114 | case DTOFFSETMINUTES:
115 | }
116 |
117 | if err != nil {
118 | //TODO: add state, start to err desc
119 | return nil, err
120 | }
121 | state, start = nstate, nstart
122 | }
123 |
124 | switch state {
125 | case ST:
126 | tz.Name = local[start:]
127 | case STOFFSET:
128 | tz.Offset.Hours, err = strconv.Atoi(local[start:])
129 | case STOFFSETMINUTES:
130 | tz.Offset.Minutes, err = strconv.Atoi(local[start:])
131 | case DT:
132 | tz.Dailing = newPosixTimezoneDailing(&tz.Offset, local[start:])
133 | case DTOFFSET:
134 | tz.Dailing.Offset.Hours, err = strconv.Atoi(local[start:])
135 | case DTOFFSETMINUTES:
136 | tz.Dailing.Offset.Minutes, err = strconv.Atoi(local[start:])
137 | }
138 | if err != nil {
139 | //TODO: add state, start to err desc
140 | return nil, err
141 | }
142 |
143 | if len(parts) > 1 {
144 | err = parsePosixTimezoneTime(&tz.Dailing.From, parts[1])
145 | if err != nil {
146 | return &tz, err
147 | }
148 | err = parsePosixTimezoneTime(&tz.Dailing.To, parts[2])
149 | if err != nil {
150 | return &tz, err
151 | }
152 | }
153 |
154 | return &tz, nil
155 | }
156 |
157 | // date/time, time is optional.
158 | // Here, date is in the Mm.n.d format, where:
159 | // * Mm (1-12) for 12 months
160 | // * n (1-5) 1 for the first week and 5 for the last week in the month
161 | // * d (0-6) 0 for Sunday and 6 for Saturday
162 | // Example: M3.2.0/2:00:00
163 | func parsePosixTimezoneTime(t *posixTimezoneTime, timePart string) error {
164 | type PosixTimezoneTimePart int
165 | const (
166 | M PosixTimezoneTimePart = iota + 1
167 | month
168 | week
169 | weekend
170 | hours
171 | minutes
172 | seconds
173 | )
174 |
175 | state, start := M, 0
176 |
177 | for i, ch := range timePart {
178 | nstate, nstart := state, start
179 | var err error
180 |
181 | switch state {
182 | case M:
183 | if ch != 'M' {
184 | return errors.New("invalid format")
185 | }
186 | nstate, nstart = month, i+1
187 | case month:
188 | if ch == '.' {
189 | t.Month, err = strconv.Atoi(timePart[start:i])
190 | nstate, nstart = week, i+1
191 | }
192 | case week:
193 | if ch == '.' {
194 | t.Week, err = strconv.Atoi(timePart[start:i])
195 | nstate, nstart = weekend, i+1
196 | }
197 | case weekend:
198 | if ch == '/' {
199 | t.Weekday, err = strconv.Atoi(timePart[start:i])
200 | nstate, nstart = hours, i+1
201 | }
202 | case hours:
203 | if ch == ':' {
204 | t.Hours, err = strconv.Atoi(timePart[start:i])
205 | nstate, nstart = minutes, i+1
206 | }
207 | case minutes:
208 | if ch == ':' {
209 | t.Minutes, err = strconv.Atoi(timePart[start:i])
210 | nstate, nstart = seconds, i+1
211 | }
212 | case seconds:
213 | }
214 |
215 | if err != nil {
216 | //TODO: add state, start to err desc
217 | return err
218 | }
219 | state, start = nstate, nstart
220 | }
221 |
222 | var err error
223 | switch state {
224 | case weekend:
225 | t.Weekday, err = strconv.Atoi(timePart[start:])
226 | case hours:
227 | t.Hours, err = strconv.Atoi(timePart[start:])
228 | t.Minutes, t.Seconds = 0, 0
229 | case minutes:
230 | t.Minutes, err = strconv.Atoi(timePart[start:])
231 | t.Seconds = 0
232 | case seconds:
233 | t.Seconds, err = strconv.Atoi(timePart[start:])
234 | }
235 | if err != nil {
236 | //TODO: add state, start to err desc
237 | return err
238 | }
239 |
240 | return nil
241 | }
242 |
243 | func getTimeOfYear(year int, t posixTimezoneTime) time.Time {
244 | res := time.Date(
245 | year, time.Month(t.Month), 1,
246 | t.Hours, t.Minutes, t.Seconds, 0,
247 | time.UTC)
248 |
249 | weekday := int(res.Weekday())
250 | res = res.AddDate(0, 0, (7-weekday+t.Weekday)%7)
251 |
252 | if t.Week < 5 {
253 | res = res.AddDate(0, 0, 7*(t.Week-1))
254 | } else {
255 | res = res.AddDate(0, 0, 7*(t.Week-1))
256 | tt := res.AddDate(0, 0, 7)
257 | if int(tt.Month()) != t.Month {
258 | return res
259 | } else {
260 | return tt
261 | }
262 | }
263 |
264 | return res
265 | }
266 |
267 | func (tz *PosixTimezone) LocalToUTC(t time.Time) time.Time {
268 | offset := tz.Offset
269 |
270 | if tz.Dailing != nil {
271 | from := getTimeOfYear(t.Year(), tz.Dailing.From)
272 | to := getTimeOfYear(t.Year(), tz.Dailing.To)
273 | diffFrom, diffTo := t.Sub(from), t.Sub(to)
274 |
275 | fmt.Println(t, from, to)
276 |
277 | if tz.Dailing.From.Month < tz.Dailing.To.Month {
278 | if int64(diffFrom) > 0 && int64(diffTo) < 0 {
279 | offset = tz.Dailing.Offset
280 | }
281 | } else {
282 | if int64(diffFrom) > 0 || int64(diffTo) < 0 {
283 | offset = tz.Dailing.Offset
284 | }
285 | }
286 | }
287 |
288 | duration := time.Duration(offset.Hours)*time.Hour + time.Duration(offset.Minutes)*time.Minute
289 |
290 | return t.Add(duration)
291 | }
292 |
--------------------------------------------------------------------------------
/onvifClient.go:
--------------------------------------------------------------------------------
1 | package onvif4go
2 |
3 | import (
4 | "time"
5 |
6 | "github.com/faceterteam/onvif4go/soap"
7 | )
8 |
9 | type onvifCaller interface {
10 | Call(request, response interface{}, headers ...interface{}) error
11 |
12 | WithoutAuth() onvifCaller
13 |
14 | SetLogger(logRequest, logResponse func(message string))
15 | }
16 |
17 | type onvifAuth struct {
18 | login string
19 | password string
20 | timeDiff time.Duration
21 | }
22 |
23 | type onvifClient struct {
24 | soapClient *soap.SoapClient
25 | auth *onvifAuth
26 | }
27 |
28 | func NewOnvifClient(endpoint string, auth *onvifAuth) *onvifClient {
29 | return &onvifClient{
30 | soapClient: soap.NewSoapClient(endpoint),
31 | auth: auth,
32 | }
33 | }
34 |
35 | func (c *onvifClient) Call(request, response interface{}, headers ...interface{}) error {
36 | if c.auth.login != "" {
37 | headers = append(headers, soap.MakeWSSecurity(c.auth.login, c.auth.password, c.auth.timeDiff))
38 | }
39 |
40 | return c.soapClient.Do(request, response, headers...)
41 | }
42 |
43 | func (c *onvifClient) SetLogger(logRequest, logResponse func(message string)) {
44 | c.soapClient.LogRequest = logRequest
45 | c.soapClient.LogResponse = logResponse
46 | }
47 |
48 | func (c *onvifClient) WithoutAuth() onvifCaller {
49 | return &onvifClient{
50 | soapClient: c.soapClient,
51 | auth: &onvifAuth{},
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/onvifdevice.go:
--------------------------------------------------------------------------------
1 | package onvif4go
2 |
3 | import (
4 | "errors"
5 | "net/url"
6 | "reflect"
7 | "strings"
8 | "time"
9 |
10 | "github.com/faceterteam/onvif4go/onvif"
11 | "github.com/faceterteam/onvif4go/xsd"
12 | )
13 |
14 | type OnvifDevice struct {
15 | xaddr string
16 | auth onvifAuth
17 |
18 | Capabilities onvif.Capabilities
19 |
20 | endpoints map[string]onvifCaller
21 |
22 | Device *DeviceService
23 | Media *MediaService
24 | Events *EventsService
25 | }
26 |
27 | func (onvifDevice *OnvifDevice) Call(request, response interface{}) error {
28 | pkgPath := strings.Split(reflect.TypeOf(request).PkgPath(), "/")
29 | pkg := pkgPath[len(pkgPath)-1]
30 |
31 | client, ok := onvifDevice.On(strings.ToLower(pkg))
32 | if !ok {
33 | return errors.New("no endpoint")
34 | }
35 | return client.Call(request, response)
36 | }
37 |
38 | func (onvifDevice *OnvifDevice) On(endpoint string) (caller onvifCaller, ok bool) {
39 | caller, ok = onvifDevice.endpoints[endpoint]
40 | return
41 | }
42 |
43 | func NewOnvifDevice(xaddr string) *OnvifDevice {
44 | return &OnvifDevice{
45 | xaddr: xaddr,
46 | endpoints: make(map[string]onvifCaller),
47 | }
48 | }
49 |
50 | func (onvifDevice *OnvifDevice) Auth(login, password string) {
51 | onvifDevice.auth.login = login
52 | onvifDevice.auth.password = password
53 | }
54 |
55 | func fixXAddr(uri xsd.AnyURI, xaddr string) string {
56 | u, _ := url.Parse(string(uri))
57 | u.Host = xaddr
58 | return u.String()
59 | }
60 |
61 | func (onvifDevice *OnvifDevice) Initialize() error {
62 | deviceService := NewDeviceService(onvifDevice)
63 |
64 | currentTime := time.Now().UTC()
65 | systemDateAndTimeResponse, err := deviceService.WithoutAuth().GetSystemDateAndTime()
66 | if err == nil {
67 | //TODO: warn if GetSystemDateAndTime return err
68 | deviceTime, _ := systemDateAndTimeResponse.SystemDateAndTime.GetUTCTime()
69 | //TODO: error mean parse error of Timezone. deviceTime equal time.Now().UTC()
70 | onvifDevice.auth.timeDiff = deviceTime.Sub(currentTime)
71 | }
72 |
73 | capabilitiesResponse, err := deviceService.GetCapabilities()
74 | if err != nil {
75 | return err
76 | }
77 |
78 | capabilities := capabilitiesResponse.Capabilities
79 | if capabilities.Device != nil {
80 | onvifDevice.endpoints["device"] = deviceService.Client
81 | onvifDevice.Device = deviceService
82 | }
83 | if capabilities.Events != nil {
84 | xaddr := fixXAddr(capabilities.Events.XAddr, onvifDevice.xaddr)
85 | onvifDevice.Events = NewEventsService(xaddr, onvifDevice)
86 | onvifDevice.endpoints["events"] = onvifDevice.Events.Client
87 | }
88 | if capabilities.Media != nil {
89 | mediaURI := fixXAddr(capabilities.Media.XAddr, onvifDevice.xaddr)
90 | onvifDevice.Media = NewMediaService(mediaURI, onvifDevice)
91 | onvifDevice.endpoints["media"] = onvifDevice.Media.Client
92 | }
93 | if capabilities.Imaging != nil {
94 | xaddr := fixXAddr(capabilities.Imaging.XAddr, onvifDevice.xaddr)
95 | onvifDevice.endpoints["imaging"] = NewOnvifClient(xaddr, &onvifDevice.auth)
96 | }
97 | if capabilities.Analytics != nil {
98 | xaddr := fixXAddr(capabilities.Analytics.XAddr, onvifDevice.xaddr)
99 | onvifDevice.endpoints["analytics"] = NewOnvifClient(xaddr, &onvifDevice.auth)
100 | }
101 | if capabilities.PTZ != nil {
102 | xaddr := fixXAddr(capabilities.PTZ.XAddr, onvifDevice.xaddr)
103 | onvifDevice.endpoints["ptz"] = NewOnvifClient(xaddr, &onvifDevice.auth)
104 | }
105 |
106 | if capabilities.Extension != nil {
107 | extension := capabilities.Extension
108 | if extension.AnalyticsDevice != nil {
109 | xaddr := fixXAddr(extension.AnalyticsDevice.XAddr, onvifDevice.xaddr)
110 | onvifDevice.endpoints["analyticsdevice"] = NewOnvifClient(xaddr, &onvifDevice.auth)
111 | }
112 | if extension.DeviceIO != nil {
113 | xaddr := fixXAddr(extension.DeviceIO.XAddr, onvifDevice.xaddr)
114 | onvifDevice.endpoints["deviceio"] = NewOnvifClient(xaddr, &onvifDevice.auth)
115 | }
116 | if extension.Display != nil {
117 | xaddr := fixXAddr(extension.Display.XAddr, onvifDevice.xaddr)
118 | onvifDevice.endpoints["display"] = NewOnvifClient(xaddr, &onvifDevice.auth)
119 | }
120 | if extension.Receiver != nil {
121 | xaddr := fixXAddr(extension.Receiver.XAddr, onvifDevice.xaddr)
122 | onvifDevice.endpoints["receiver"] = NewOnvifClient(xaddr, &onvifDevice.auth)
123 | }
124 | if extension.Recording != nil {
125 | xaddr := fixXAddr(extension.Recording.XAddr, onvifDevice.xaddr)
126 | onvifDevice.endpoints["recording"] = NewOnvifClient(xaddr, &onvifDevice.auth)
127 | }
128 | if extension.Replay != nil {
129 | xaddr := fixXAddr(extension.Replay.XAddr, onvifDevice.xaddr)
130 | onvifDevice.endpoints["replay"] = NewOnvifClient(xaddr, &onvifDevice.auth)
131 | }
132 | if extension.Search != nil {
133 | xaddr := fixXAddr(extension.Search.XAddr, onvifDevice.xaddr)
134 | onvifDevice.endpoints["search"] = NewOnvifClient(xaddr, &onvifDevice.auth)
135 | }
136 | }
137 |
138 | onvifDevice.Capabilities = capabilities
139 |
140 | return nil
141 | }
142 |
--------------------------------------------------------------------------------
/pullPointSubscription.go:
--------------------------------------------------------------------------------
1 | package onvif4go
2 |
3 | import (
4 | "time"
5 |
6 | tev "github.com/faceterteam/onvif4go/events"
7 | "github.com/faceterteam/onvif4go/xsd"
8 | )
9 |
10 | type PullPointSubscription struct {
11 | Client onvifCaller
12 | Settings tev.CreatePullPointSubscriptionResponse
13 | }
14 |
15 | func NewPullPointSubscription(settings tev.CreatePullPointSubscriptionResponse, onvifDevice *OnvifDevice) *PullPointSubscription {
16 | return &PullPointSubscription{
17 | Client: NewOnvifClient(string(settings.SubscriptionReference.Address.Content), &onvifDevice.auth),
18 | Settings: settings,
19 | }
20 | }
21 |
22 | func (s *PullPointSubscription) makeAddressingHeaders(action string) []interface{} {
23 | return tev.MakeAnonymousAddressingHeaders(action, string(s.Settings.SubscriptionReference.Address.Content))
24 | }
25 |
26 | /*
27 | PullMessages pulls one or more messages from a PullPoint.
28 | The device shall provide the following PullMessages command for all SubscriptionManager
29 | endpoints returned by the CreatePullPointSubscription command. This method shall not wait until
30 | the requested number of messages is available but return as soon as at least one message is available.
31 |
32 | The command shall at least support a Timeout of one minute. In case a device supports retrieval
33 | of less messages than requested it shall return these without generating a fault.
34 | */
35 | func (s *PullPointSubscription) PullMessages(timeout time.Duration, messageLimit int) (res tev.PullMessagesResponse, err error) {
36 | headers := s.makeAddressingHeaders("http://www.onvif.org/ver10/events/wsdl/PullPointSubscription/PullMessagesRequest")
37 | err = s.Client.Call(tev.PullMessages{
38 | Timeout: xsd.Duration(timeout),
39 | MessageLimit: messageLimit,
40 | }, &res, headers...)
41 | return
42 | //
43 | }
44 |
45 | /*
46 | Unsubscribe shall terminate the lifetime of a pull point
47 | */
48 | func (s *PullPointSubscription) Unsubscribe() (err error) {
49 | headers := s.makeAddressingHeaders("http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/UnsubscribeRequest")
50 | var res tev.UnsubscribeResponse
51 | err = s.Client.Call(tev.UnsubscribeRequest{}, &res, headers...)
52 | return
53 | //
54 | //
55 | }
56 |
57 | /*
58 | Seek readjusts the pull pointer into the past.
59 | A device supporting persistent notification storage shall provide the
60 | following Seek command for all SubscriptionManager endpoints returned by
61 | the CreatePullPointSubscription command. The optional Reverse argument can
62 | be used to reverse the pull direction of the PullMessages command.
63 |
64 | The UtcTime argument will be matched against the UtcTime attribute on a
65 | NotificationMessage.
66 | */
67 | func (s *PullPointSubscription) Seek(time time.Time, reverse bool) (err error) {
68 | headers := s.makeAddressingHeaders("http://www.onvif.org/ver10/events/wsdl/PullPointSubscription/SeekRequest")
69 | var res tev.SeekResponse
70 | err = s.Client.Call(tev.Seek{
71 | UtcTime: xsd.MakeDateTime(time),
72 | Reverse: reverse,
73 | }, &res, headers...)
74 | return
75 | }
76 |
77 | /*
78 | SetSynchronizationPoint inform a client about property creation, changes and
79 | deletion in a uniform way. When a client wants to synchronize its properties with the
80 | properties of the device, it can request a synchronization point which repeats the current
81 | status of all properties to which a client has subscribed. The PropertyOperation of all
82 | produced notifications is set to “Initialized”. The Synchronization Point is
83 | requested directly from the SubscriptionManager which was returned in either the
84 | SubscriptionResponse or in the CreatePullPointSubscriptionResponse. The property update is
85 | transmitted via the notification transportation of the notification interface. This method is mandatory.
86 | */
87 | func (s *PullPointSubscription) SetSynchronizationPoint() (err error) {
88 | headers := s.makeAddressingHeaders("http://www.onvif.org/ver10/events/wsdl/PullPointSubscription/SetSynchronizationPointRequest")
89 | var res tev.SetSynchronizationPointResponse
90 | err = s.Client.Call(tev.SetSynchronizationPoint{}, &res, headers...)
91 | return
92 | }
93 |
--------------------------------------------------------------------------------
/soap/client.go:
--------------------------------------------------------------------------------
1 | package soap
2 |
3 | import (
4 | "bytes"
5 | "encoding/xml"
6 | "errors"
7 | "io/ioutil"
8 | "net/http"
9 | "strings"
10 | "time"
11 | )
12 |
13 | type SoapClient struct {
14 | Endpoint string
15 | LogRequest func(request string)
16 | LogResponse func(response string)
17 | }
18 |
19 | func NewSoapClient(endpoint string) *SoapClient {
20 | return &SoapClient{
21 | Endpoint: endpoint,
22 | }
23 | }
24 |
25 | func readResponse(resp *http.Response) string {
26 | b, err := ioutil.ReadAll(resp.Body)
27 | if err != nil {
28 | panic(err)
29 | }
30 | return string(b)
31 | }
32 |
33 | func (soap *SoapClient) Do(request, response interface{}, headers ...interface{}) error {
34 | envelope := NewSOAPEnvelope(request)
35 | for _, header := range headers {
36 | envelope.AddHeader(header)
37 | }
38 |
39 | message, err := xml.Marshal(envelope)
40 | if err != nil {
41 | return err
42 | }
43 |
44 | if soap.LogRequest != nil {
45 | soap.LogRequest(string(message))
46 | }
47 |
48 | httpClient := &http.Client{
49 | Timeout: time.Duration(10 * time.Second),
50 | }
51 | resp, err := httpClient.Post(soap.Endpoint, "application/soap+xml; charset=utf-8", bytes.NewBuffer(message))
52 | if err != nil {
53 | return err
54 | }
55 | defer resp.Body.Close()
56 |
57 | if resp.StatusCode != http.StatusOK &&
58 | resp.StatusCode != http.StatusInternalServerError &&
59 | resp.StatusCode != http.StatusBadRequest {
60 |
61 | //respBody := readResponse(resp)
62 |
63 | return errors.New("camera is not available at " + soap.Endpoint + " or it does not support ONVIF services")
64 | }
65 |
66 | responseEnvelope := NewSOAPEnvelope(response)
67 |
68 | respBody := readResponse(resp)
69 |
70 | if soap.LogResponse != nil {
71 | soap.LogResponse(string(respBody))
72 | }
73 |
74 | decoder := xml.NewDecoder(strings.NewReader(respBody))
75 | err = decoder.Decode(responseEnvelope)
76 | if err != nil {
77 | return err
78 | }
79 | if responseEnvelope.Body.Fault != nil {
80 | return responseEnvelope.Body.Fault
81 | }
82 |
83 | return nil
84 | }
85 |
--------------------------------------------------------------------------------
/soap/types.go:
--------------------------------------------------------------------------------
1 | package soap
2 |
3 | import "encoding/xml"
4 |
5 | type SOAPEnvelope struct {
6 | XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Envelope"`
7 | Header SOAPHeader
8 | Body SOAPBody
9 | }
10 |
11 | type SOAPHeader struct {
12 | XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Header"`
13 |
14 | Headers []interface{}
15 | }
16 |
17 | type SOAPBody struct {
18 | XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Body"`
19 |
20 | Fault *SOAPFault `xml:",omitempty"`
21 | Content interface{} `xml:",omitempty"`
22 | }
23 |
24 | type SOAPFault struct {
25 | XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Fault"`
26 |
27 | Code SOAPFaultCode `xml:"Code"`
28 | //TODO: text, details
29 | }
30 |
31 | type SOAPFaultCode struct {
32 | Value string `xml:"Value"`
33 | Subcode *SOAPFaultCode `xml:"Subcode,omitempty"`
34 | }
35 |
36 | func (f *SOAPFault) Error() string {
37 | errorString := f.Code.Value
38 | code := &f.Code
39 | for code.Subcode != nil {
40 | errorString = errorString + " > " + code.Subcode.Value
41 | code = code.Subcode
42 | }
43 | return errorString
44 | }
45 |
46 | func (b *SOAPBody) UnmarshalXML(d *xml.Decoder, _ xml.StartElement) error {
47 | if b.Content == nil {
48 | return xml.UnmarshalError("Content must be a pointer to a struct")
49 | }
50 |
51 | var (
52 | token xml.Token
53 | err error
54 | consumed bool
55 | )
56 |
57 | Loop:
58 | for {
59 | if token, err = d.Token(); err != nil {
60 | return err
61 | }
62 |
63 | if token == nil {
64 | break
65 | }
66 |
67 | switch se := token.(type) {
68 | case xml.StartElement:
69 | if consumed {
70 | return xml.UnmarshalError("Found multiple elements inside SOAP body; not wrapped-document/literal WS-I compliant")
71 | } else if se.Name.Space == "http://www.w3.org/2003/05/soap-envelope" && se.Name.Local == "Fault" {
72 | b.Fault = &SOAPFault{}
73 | b.Content = nil
74 |
75 | err = d.DecodeElement(b.Fault, &se)
76 | if err != nil {
77 | return err
78 | }
79 |
80 | consumed = true
81 | } else {
82 | if err = d.DecodeElement(b.Content, &se); err != nil {
83 | return err
84 | }
85 |
86 | consumed = true
87 | }
88 | case xml.EndElement:
89 | break Loop
90 | }
91 | }
92 |
93 | return nil
94 | }
95 |
96 | func (envelope *SOAPEnvelope) AddHeader(header interface{}) {
97 | envelope.Header.Headers = append(envelope.Header.Headers, header)
98 | }
99 |
100 | func NewSOAPEnvelope(content interface{}) *SOAPEnvelope {
101 | return &SOAPEnvelope{
102 | Body: SOAPBody{
103 | Content: content,
104 | },
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/soap/wsSecurity.go:
--------------------------------------------------------------------------------
1 | package soap
2 |
3 | import (
4 | "crypto/rand"
5 | "crypto/sha1"
6 | "encoding/base64"
7 | "encoding/xml"
8 | "io"
9 | "time"
10 | )
11 |
12 | type wsSecurity struct {
13 | XMLName xml.Name `xml:"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd Security"`
14 | UsernameToken wssUsernameToken
15 | }
16 |
17 | type wssUsernameToken struct {
18 | XMLName xml.Name `xml:"UsernameToken"`
19 | Username string `xml:"Username"`
20 | Password wssPassword `xml:"Password"`
21 | Nonce wssNonce `xml:"Nonce"`
22 | Created string `xml:"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd Created"`
23 | }
24 |
25 | type wssPassword struct {
26 | Type string `xml:"Type,attr"`
27 | Password string `xml:",chardata"`
28 | }
29 |
30 | type wssNonce struct {
31 | Type string `xml:"EncodingType,attr"`
32 | Nonce string `xml:",chardata"`
33 | }
34 |
35 | func newUUIDVer4() ([]byte, error) {
36 | u := new([16]byte)
37 | if _, err := io.ReadFull(rand.Reader, u[:]); err != nil {
38 | return u[:], err
39 | }
40 | // u.SetVersion(V4)
41 | // u.SetVariant(VariantRFC4122)
42 |
43 | return u[:], nil
44 | }
45 |
46 | func MakeWSSecurity(username string, password string, timeDiff time.Duration) wsSecurity {
47 | created := time.Now().UTC().Add(timeDiff).Format(time.RFC3339Nano)
48 |
49 | nonce, _ := newUUIDVer4()
50 | nonce64 := base64.StdEncoding.EncodeToString(nonce)
51 | hasher := sha1.New()
52 | hasher.Write(nonce)
53 | hasher.Write([]byte(created + password))
54 | shaToken := hasher.Sum(nil)
55 | shaDigest64 := base64.StdEncoding.EncodeToString(shaToken)
56 |
57 | return wsSecurity{
58 | UsernameToken: wssUsernameToken{
59 | Username: username,
60 | Created: created,
61 | Password: wssPassword{
62 | Type: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest",
63 | Password: shaDigest64,
64 | },
65 | Nonce: wssNonce{
66 | Type: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary",
67 | Nonce: nonce64,
68 | },
69 | },
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/xsd/anytype.go:
--------------------------------------------------------------------------------
1 | package xsd
2 |
3 | import (
4 | "encoding/xml"
5 | )
6 |
7 | type AnyType struct {
8 | XMLName xml.Name
9 | Attrs []xml.Attr `xml:",any,attr"`
10 | Childs []AnyType `xml:",any"`
11 | Text string `xml:",chardata"`
12 | }
13 |
--------------------------------------------------------------------------------
/xsd/duration.go:
--------------------------------------------------------------------------------
1 | package xsd
2 |
3 | import (
4 | "errors"
5 | "regexp"
6 | "strconv"
7 | "time"
8 | )
9 |
10 | var (
11 | nanosecondsPerDay = 24 * int64(time.Hour)
12 | nanosecondsPerMonth = 30 * nanosecondsPerDay
13 | nanosecondsPerYear = 365 * nanosecondsPerDay
14 | )
15 |
16 | /*
17 | Duration is the [ISO 8601] extended format PnYn MnDTnH nMnS,
18 | where nY represents the number of years, nM the number of months,
19 | nD the number of days, 'T' is the date/time separator,
20 | nH the number of hours, nM the number of minutes and nS the number of seconds.
21 | The number of seconds can include decimal digits to arbitrary precision.
22 | PnYnMnDTnHnMnS
23 |
24 | Duration has the following ·constraining facets·:
25 |
26 | • pattern
27 | • enumeration
28 | • whiteSpace
29 | • maxInclusive
30 | • maxExclusive
31 | • minInclusive
32 | • minExclusive
33 |
34 | More info: https://www.w3.org/TR/xmlschema-2/#duration
35 |
36 | TODO: process restrictions
37 | TODO: Look at time.Duration go type
38 | */
39 |
40 | type Duration time.Duration
41 |
42 | func (d Duration) String() string {
43 | td := time.Duration(d).Nanoseconds()
44 |
45 | seconds := td % int64(time.Minute)
46 | if seconds > 0 {
47 | td -= seconds
48 | seconds = seconds / int64(time.Second)
49 | }
50 | minutes := td % int64(time.Hour)
51 | if minutes > 0 {
52 | td -= minutes
53 | minutes = minutes / int64(time.Minute)
54 | }
55 | hours := td % int64(24*time.Hour)
56 | if hours > 0 {
57 | td -= hours
58 | hours = hours / int64(time.Hour)
59 | }
60 |
61 | days := td / int64(24*time.Hour)
62 |
63 | result := "P" // time duration designator
64 | //years
65 | // if years > 0 {
66 | // result += strconv.FormatInt(years, 10) + "Y"
67 | // }
68 | // if months > 0 {
69 | // result += strconv.FormatInt(months, 10) + "M"
70 | // }
71 | if days > 0 {
72 | result += strconv.FormatInt(days, 10) + "D"
73 | }
74 |
75 | if hours > 0 || minutes > 0 || seconds > 0 {
76 | result += "T"
77 | if hours > 0 {
78 | result += strconv.FormatInt(hours, 10) + "H"
79 | }
80 | if minutes > 0 {
81 | result += strconv.FormatInt(minutes, 10) + "M"
82 | }
83 | if seconds > 0 {
84 | result += strconv.FormatInt(seconds, 10) + "S"
85 | }
86 | }
87 |
88 | if len(result) == 1 {
89 | result += "T0S"
90 | }
91 |
92 | return result
93 | }
94 |
95 | func (d *Duration) UnmarshalText(text []byte) error {
96 | durationRegex, _ := regexp.Compile(`^(-?)P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d*(?:\.\d+)?)S)?)?$`)
97 |
98 | if !durationRegex.MatchString(string(text)) {
99 | return errors.New("invalid format")
100 | }
101 |
102 | groups := durationRegex.FindStringSubmatch(string(text))
103 |
104 | var duration int64
105 |
106 | if groups[2] != "" {
107 | years, _ := strconv.Atoi(groups[2])
108 | duration += int64(years) * nanosecondsPerYear
109 | }
110 | if groups[3] != "" {
111 | months, _ := strconv.Atoi(groups[3])
112 | duration += int64(months) * nanosecondsPerMonth
113 | }
114 | if groups[4] != "" {
115 | days, _ := strconv.Atoi(groups[4])
116 | duration += int64(days) * nanosecondsPerDay
117 | }
118 |
119 | if groups[5] != "" {
120 | hours, _ := strconv.Atoi(groups[5])
121 | duration += int64(hours) * int64(time.Hour)
122 | }
123 | if groups[6] != "" {
124 | minutes, _ := strconv.Atoi(groups[6])
125 | duration += int64(minutes) * int64(time.Minute)
126 | }
127 | if groups[7] != "" {
128 | seconds, _ := strconv.Atoi(groups[7])
129 | duration += int64(seconds) * int64(time.Second)
130 | }
131 |
132 | *d = Duration(duration)
133 |
134 | return nil
135 | }
136 |
137 | func (d Duration) MarshalText() ([]byte, error) {
138 | return []byte(d.String()), nil
139 | }
140 |
--------------------------------------------------------------------------------
/xsd/types.go:
--------------------------------------------------------------------------------
1 | package xsd
2 |
3 | import (
4 | "encoding/base64"
5 | "encoding/hex"
6 | "errors"
7 | "net/url"
8 | "regexp"
9 | "strings"
10 | "time"
11 | )
12 |
13 | /*
14 | TODO: XML SOURCE: https://www.w3.org/2001/05/datatypes.xsd
15 | */
16 |
17 | type AnySimpleType string
18 |
19 | /***********************************************************
20 | Non-derived types
21 | ***********************************************************/
22 |
23 | /*
24 | The string datatype represents character strings in XML.
25 | The ·value space· of string is the set of finite-length sequences of characters.
26 | String has the following constraining facets:
27 | • length
28 | • minLength
29 | • maxLength
30 | • pattern
31 | • enumeration
32 | • whiteSpace
33 |
34 | More info: https://www.w3.org/TR/xmlschema-2/#string
35 |
36 | //TODO: valid/invalid character declaration and process restrictions
37 | */
38 | type String string
39 |
40 | /*
41 | Construct an instance of xsd String type
42 | */
43 | func (tp String) NewString(data string) String {
44 | return String(data)
45 | }
46 |
47 | /*
48 | Float is patterned after the IEEE single-precision 32-bit floating point type
49 | Float has the following ·constraining facets·:
50 | • pattern
51 | • enumeration
52 | • whiteSpace
53 | • maxInclusive
54 | • maxExclusive
55 | • minInclusive
56 | • minExclusive
57 |
58 | More info: https://www.w3.org/TR/xmlschema-2/#float
59 |
60 | //TODO: process restrictions
61 | */
62 | type Float float32
63 |
64 | /*
65 | Construct an instance of xsd Float type
66 | */
67 | func (tp Float) NewFloat(data float32) Float {
68 | return Float(data)
69 | }
70 |
71 | /*
72 | The double datatype is patterned after the IEEE double-precision 64-bit floating point type
73 | Double has the following ·constraining facets·:
74 | • pattern
75 | • enumeration
76 | • whiteSpace
77 | • maxInclusive
78 | • maxExclusive
79 | • minInclusive
80 | • minExclusive
81 |
82 | More info: https://www.w3.org/TR/xmlschema-2/#double
83 |
84 | //TODO: process restrictions
85 | */
86 | type Double float64
87 |
88 | /*
89 | Construct an instance of xsd Double type
90 | */
91 | func (tp Double) NewDouble(data float64) Double {
92 | return Double(data)
93 | }
94 |
95 | /*
96 | The type decimal represents a decimal number of arbitrary precision.
97 | Schema processors vary in the number of significant digits they support,
98 | but a conforming processor must support a minimum of 18 significant digits.
99 | The format of xsd:decimal is a sequence of digits optionally preceded by a sign ("+" or "-")
100 | and optionally containing a period. The value may start or end with a period.
101 | If the fractional part is 0 then the period and trailing zeros may be omitted.
102 | Leading and trailing zeros are permitted, but they are not considered significant.
103 | That is, the decimal values 3.0 and 3.0000 are considered equal.
104 |
105 | Source: http://www.datypic.com/sc/xsd/t-xsd_decimal.html
106 |
107 | Decimal has the following ·constraining facets·:
108 | • totalDigits
109 | • fractionDigits
110 | • pattern
111 | • whiteSpace
112 | • enumeration
113 | • maxInclusive
114 | • maxExclusive
115 | • minInclusive
116 | • minExclusive
117 |
118 | More info: https://www.w3.org/TR/xmlschema-2/#decimal
119 |
120 | //TODO: process restrictions, valid/invalid characters(commas are not permitted; the decimal separator must be a period)
121 |
122 | */
123 | type Decimal string
124 |
125 | /*
126 | Construct an instance of xsd Decimal type
127 | */
128 | func (tp Decimal) NewDecimal(data string) Decimal {
129 | return Decimal(data)
130 | }
131 |
132 | /*
133 | DateTime values may be viewed as objects with integer-valued year, month, day, hour
134 | and minute properties, a decimal-valued second property, and a boolean timezoned property.
135 |
136 |
137 | The ·lexical space· of dateTime consists of finite-length sequences of characters of the form:
138 | '-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?,
139 |
140 |
141 | DateTime has the following ·constraining facets·:
142 |
143 | • pattern
144 | • enumeration
145 | • whiteSpace
146 | • maxInclusive
147 | • maxExclusive
148 | • minInclusive
149 | • minExclusive
150 |
151 | More info: https://www.w3.org/TR/xmlschema-2/#dateTime
152 |
153 | TODO: decide good type for time with proper format
154 | TODO: process restrictions
155 | */
156 | type DateTime AnySimpleType
157 |
158 | /*
159 | Construct an instance of xsd dateTime type
160 | */
161 | func MakeDateTime(time time.Time) DateTime {
162 | return DateTime(time.Format("2002-10-10T12:00:00-05:00"))
163 | }
164 |
165 | /*
166 | Time represents an instant of time that recurs every day.
167 | The ·value space· of time is the space of time of day values
168 | as defined in § 5.3 of [ISO 8601]. Specifically, it is a set
169 | of zero-duration daily time instances.
170 |
171 | Time has the following ·constraining facets·:
172 |
173 | • pattern
174 | • enumeration
175 | • whiteSpace
176 | • maxInclusive
177 | • maxExclusive
178 | • minInclusive
179 | • minExclusive
180 |
181 | More info: https://www.w3.org/TR/xmlschema-2/#time
182 |
183 | TODO: process restrictions
184 | */
185 | type Time AnySimpleType
186 |
187 | /*
188 | Construct an instance of xsd time type
189 | */
190 | func (tp DateTime) NewTime(time time.Time) DateTime {
191 | return DateTime(time.Format("15:04:05"))
192 | }
193 |
194 | /*
195 | The ·value space· of date consists of top-open intervals of
196 | exactly one day in length on the timelines of dateTime, beginning
197 | on the beginning moment of each day (in each timezone),
198 | i.e. '00:00:00', up to but not including '24:00:00'
199 | (which is identical with '00:00:00' of the next day).
200 | For nontimezoned values, the top-open intervals disjointly
201 | cover the nontimezoned timeline, one per day. For timezoned
202 | values, the intervals begin at every minute and therefore overlap.
203 | */
204 | type Date AnySimpleType
205 |
206 | /*
207 | Construct an instance of xsd date type
208 | */
209 | func (tp Date) NewDate(time time.Time) Date {
210 | return Date(time.Format("2004-04-12-05:00"))
211 | }
212 |
213 | /*
214 | The type xsd:gYearMonth represents a specific month of a specific
215 | year. The letter g signifies "Gregorian." The format of
216 | xsd:gYearMonth is CCYY-MM. No left truncation is allowed on
217 | either part. To represents years later than 9999, additional
218 | digits can be added to the left of the year value.
219 | To represent years before 0001, a preceding minus sign ("-")
220 | is permitted.
221 |
222 | Source: http://www.datypic.com/sc/xsd/t-xsd_gYearMonth.html
223 |
224 | More info: https://www.w3.org/TR/xmlschema-2/#gYearMonth
225 | */
226 | type GYearMonth AnySimpleType
227 |
228 | /*
229 | Construct an instance of xsd GYearMonth type
230 | */
231 | func (tp GYearMonth) NewGYearMonth(time time.Time) GYearMonth {
232 | return GYearMonth(time.Format("2006-01"))
233 | }
234 |
235 | /*
236 | The type xsd:gYear represents a specific calendar year.
237 | The letter g signifies "Gregorian." The format of xsd:gYear
238 | is CCYY. No left truncation is allowed. To represent years
239 | later than 9999, additional digits can be added to the left
240 | of the year value. To represent years before 0001, a preceding
241 | minus sign ("-") is allowed.
242 |
243 | Source: http://www.datypic.com/sc/xsd/t-xsd_gYear.html
244 |
245 | More info: https://www.w3.org/TR/xmlschema-2/#gYear
246 | */
247 | type GYear AnySimpleType
248 |
249 | /*
250 | Construct an instance of xsd GYear type
251 | */
252 | func (tp GYear) NewGYear(time time.Time) GYear {
253 | return GYear(time.Format("2006"))
254 | }
255 |
256 | /*
257 | The type xsd:gMonthDay represents a specific day that recurs
258 | every year. The letter g signifies "Gregorian." xsd:gMonthDay
259 | can be used to say, for example, that your birthday is on the
260 | 14th of April every year. The format of xsd:gMonthDay is --MM-DD.
261 |
262 | Source: http://www.datypic.com/sc/xsd/t-xsd_gMonthDay.html
263 |
264 | More info: https://www.w3.org/TR/xmlschema-2/#gMonthDay
265 | */
266 | type GMonthDay AnySimpleType
267 |
268 | // NewGMonthDay Construct an instance of xsd GMonthDay type
269 | func (tp GMonthDay) NewGMonthDay(time time.Time) GMonthDay {
270 | return GMonthDay(time.Format("--01-02"))
271 | }
272 |
273 | /*
274 | The type xsd:gDay represents a day that recurs every month.
275 | The letter g signifies "Gregorian." xsd:gDay can be used to say,
276 | for example, that checks are paid on the 5th of each month.
277 | To represent a duration of days, use the duration type instead.
278 | The format of gDay is ---DD.
279 |
280 | Source: http://www.datypic.com/sc/xsd/t-xsd_gDay.html
281 |
282 | More info: https://www.w3.org/TR/xmlschema-2/#gDay
283 | */
284 | type GDay AnySimpleType
285 |
286 | // NewGDay Construct an instance of xsd GDay type
287 | func (tp GDay) NewGDay(time time.Time) GDay {
288 | return GDay(time.Format("---02"))
289 | }
290 |
291 | /*
292 | The type xsd:gMonth represents a specific month that recurs
293 | every year. The letter g signifies "Gregorian." xsd:gMonth
294 | can be used to indicate, for example, that fiscal year-end
295 | processing occurs in September of every year. To represent
296 | a duration of months, use the duration type instead. The format
297 | of xsd:gMonth is --MM.
298 |
299 | Source: http://www.datypic.com/sc/xsd/t-xsd_gMonth.html
300 |
301 | More info: https://www.w3.org/TR/xmlschema-2/#gMonth
302 | */
303 | type GMonth AnySimpleType
304 |
305 | func (tp GMonth) NewGMonth(time time.Time) GMonth {
306 | return GMonth(time.Format("--01"))
307 | }
308 |
309 | /*
310 | The xsd:hexBinary type represents binary data as a sequence
311 | of binary octets. It uses hexadecimal encoding, where each
312 | binary octet is a two-character hexadecimal number.
313 | Lowercase and uppercase letters A through F are permitted.
314 | For example, 0FB8 and 0fb8 are two equal xsd:hexBinary
315 | representations consisting of two octets.
316 |
317 | Source: http://www.datypic.com/sc/xsd/t-xsd_hexBinary.html
318 |
319 | More info: https://www.w3.org/TR/xmlschema-2/#hexBinary
320 | */
321 | type HexBinary AnySimpleType
322 |
323 | func (tp HexBinary) NewHexBinary(data []byte) HexBinary {
324 | return HexBinary(hex.EncodeToString(data))
325 | }
326 |
327 | /*
328 | base64Binary represents Base64-encoded arbitrary binary data.
329 | The ·value space· of base64Binary is the set of finite-length sequences of binary octets.
330 | For base64Binary data the entire binary stream is encoded using the Base64 Alphabet in [RFC 2045].
331 |
332 | base64Binary has the following ·constraining facets·:
333 | • length
334 | • minLength
335 | • maxLength
336 | • pattern
337 | • enumeration
338 | • whiteSpace
339 |
340 | More info: https://www.w3.org/TR/xmlschema-2/#base64Binary
341 | */
342 | type Base64Binary AnySimpleType
343 |
344 | func (tp Base64Binary) NewBase64Binary(data []byte) Base64Binary {
345 | return Base64Binary(base64.StdEncoding.EncodeToString(data))
346 | }
347 |
348 | /*
349 | anyURI represents a Uniform Resource Identifier Reference (URI).
350 | An anyURI value can be absolute or relative, and may have an optional
351 | fragment identifier (i.e., it may be a URI Reference).
352 | This type should be used to specify the intention that the
353 | value fulfills the role of a URI as defined by [RFC 2396], as amended by [RFC 2732].
354 |
355 | anyURI has the following ·constraining facets·:
356 | • length
357 | • minLength
358 | • maxLength
359 | • pattern
360 | • enumeration
361 | • whiteSpace
362 |
363 | More info: https://www.w3.org/TR/xmlschema-2/#anyURI
364 | */
365 | type AnyURI AnySimpleType
366 |
367 | func (tp AnyURI) NewAnyURI(data url.URL) AnyURI {
368 | return AnyURI(data.String())
369 | }
370 |
371 | /*
372 | QName represents XML qualified names. The ·value space· of QName is the set of tuples
373 | {namespace name, local part}, where namespace name is an anyURI and local part is an NCName.
374 | The ·lexical space· of QName is the set of strings that ·match· the QName production of [Namespaces in XML].
375 |
376 | QName has the following ·constraining facets·:
377 | • length
378 | • minLength
379 | • maxLength
380 | • pattern
381 | • enumeration
382 | • whiteSpace
383 |
384 | More info: https://www.w3.org/TR/xmlschema-2/#QName
385 | */
386 | type QName AnySimpleType
387 |
388 | func (tp QName) NewQName(prefix, local string) QName {
389 | var result string
390 | if len(prefix) == 0 {
391 | result += local
392 | } else {
393 | result = prefix + ":" + local
394 | }
395 | return QName(result)
396 | }
397 |
398 | //TODO: NOTATION datatype
399 | //type NOTATION AnySimpleType
400 |
401 | /*
402 | Derived types
403 | */
404 |
405 | type NormalizedString String
406 |
407 | //TODO: check normalization
408 | func NewNormalizedString(data string) (NormalizedString, error) {
409 | if strings.ContainsAny(data, "\r\n\t<>&") {
410 | return NormalizedString(""), errors.New("String " + data + " contains forbidden symbols")
411 | }
412 | return NormalizedString(data), nil
413 | }
414 |
415 | type Token NormalizedString
416 |
417 | func NewToken(data NormalizedString) (Token, error) {
418 | trailing_leading_whitespaces := regexp.MustCompile(`^[\s\p{Zs}]+|[\s\p{Zs}]+$`)
419 | multiple_whitespaces := regexp.MustCompile(`[\s\p{Zs}]{2,}`)
420 | //Removing trailing and leading whitespaces and multiple spaces
421 | /*final := re_leadclose_whtsp.ReplaceAllString(data, "")
422 | final = re_inside_whtsp.ReplaceAllString(final, " ")*/
423 | if strings.ContainsAny(string(data), "\r\n\t<>&") || trailing_leading_whitespaces.MatchString(string(data)) || multiple_whitespaces.MatchString(string(data)) {
424 | return Token(""), errors.New("String " + string(data) + " contains forbidden symbols or whitespaces")
425 | }
426 |
427 | return Token(data), nil
428 | }
429 |
430 | type Language Token
431 |
432 | func (tp Language) NewLanguage(data Token) (Language, error) {
433 | //Pattern was given from https://www.w3.org/2001/05/datatypes.xsd
434 | rgxp := regexp.MustCompile(`([a-zA-Z]{2}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*`)
435 | if rgxp.MatchString(string(data)) {
436 | return Language(""), errors.New("String does not match pattern ([a-zA-Z]{2}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*")
437 | }
438 | return Language(data), nil
439 | }
440 |
441 | type NMTOKEN Token
442 |
443 | //TODO: check for valid symbols: https://www.w3.org/TR/xml/#NT-Nmtoken
444 | func (tp NMTOKEN) NewNMTOKEN(data string) NMTOKEN {
445 | return NMTOKEN(data)
446 | }
447 |
448 | type NMTOKENS []NMTOKEN
449 |
450 | func (tp NMTOKENS) NewNMTOKENS(data []NMTOKEN) NMTOKENS {
451 | result := make(NMTOKENS, len(data))
452 | for i, j := range data {
453 | result[i] = j
454 | }
455 | return result
456 | }
457 |
458 | type Name Token
459 |
460 | //TODO: implements https://www.w3.org/TR/xml/#NT-Name
461 | func (tp Name) NewName(data Token) Name {
462 | return Name(data)
463 | }
464 |
465 | type NCName Name
466 |
467 | //TODO: https://www.w3.org/TR/REC-xml/#NT-Name and https://www.w3.org/TR/xml-names/#NT-NCName
468 | func (tp NCName) NewNCName(data Name) NCName {
469 | return NCName(data)
470 | }
471 |
472 | //TODO: improve next types to correspond to XMLSchema
473 | type ID NCName
474 |
475 | func (tp ID) NewID(data NCName) ID {
476 | return ID(data)
477 | }
478 |
479 | type IDREF NCName
480 |
481 | func (tp IDREF) NewIDREF(data NCName) IDREF {
482 | return IDREF(data)
483 | }
484 |
485 | type IDREFS []IDREF
486 |
487 | func (tp IDREFS) NewIDREFS(data []IDREF) IDREFS {
488 | result := make(IDREFS, len(data))
489 | for i, j := range data {
490 | result[i] = j
491 | }
492 | return result
493 | }
494 |
495 | type ENTITY NCName
496 |
497 | func (tp ENTITY) NewENTITY(data NCName) ENTITY {
498 | return ENTITY(data)
499 | }
500 |
501 | type ENTITIES []ENTITY
502 |
503 | func (tp ENTITIES) NewENTITIES(data []ENTITY) ENTITIES {
504 | result := make(ENTITIES, len(data))
505 | for i, j := range data {
506 | result[i] = j
507 | }
508 | return result
509 | }
510 |
511 | type Integer int64
512 |
513 | func (tp Integer) NewInteger(data int64) Integer {
514 | return Integer(data)
515 | }
516 |
517 | type Short int16
518 |
519 | func (tp Short) NewShort(data int16) Short {
520 | return Short(data)
521 | }
522 |
523 | type Byte int8
524 |
525 | func (tp Byte) NewByte(data int8) Byte {
526 | return Byte(data)
527 | }
528 |
529 | type UnsignedLong uint64
530 |
531 | func (tp UnsignedLong) NewUnsignedLong(data uint64) UnsignedLong {
532 | return UnsignedLong(data)
533 | }
534 |
535 | type UnsignedInt uint32
536 |
537 | func (tp UnsignedInt) NewUnsignedInt(data uint32) UnsignedInt {
538 | return UnsignedInt(data)
539 | }
540 |
541 | type UnsignedShort uint16
542 |
543 | func (tp UnsignedShort) NewUnsignedShort(data uint16) UnsignedShort {
544 | return UnsignedShort(data)
545 | }
546 |
547 | type UnsignedByte uint8
548 |
549 | func (tp UnsignedByte) NewUnsignedByte(data uint8) UnsignedByte {
550 | return UnsignedByte(data)
551 | }
552 |
553 | type PositiveInteger int64
554 |
555 | func (tp PositiveInteger) NewPositiveInteger(data int64) (PositiveInteger, error) {
556 | if data >= 0 {
557 | return 0, errors.New("Value must be more than 0")
558 | }
559 | return PositiveInteger(data), nil
560 | }
561 |
--------------------------------------------------------------------------------