mirror of
https://github.com/kerberos-io/onvif.git
synced 2025-10-30 02:31:54 +08:00
Expose Device type for outer developer using & format code file
This commit is contained in:
199
Device.go
199
Device.go
@@ -2,40 +2,44 @@ package goonvif
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"github.com/beevik/etree"
|
||||
"github.com/yakovlevdmv/gosoap"
|
||||
"strconv"
|
||||
"net/http"
|
||||
"io/ioutil"
|
||||
"github.com/yakovlevdmv/WS-Discovery"
|
||||
"strings"
|
||||
"github.com/yakovlevdmv/goonvif/Device"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/beevik/etree"
|
||||
"github.com/use-go/go-onvif/device"
|
||||
"github.com/yakovlevdmv/WS-Discovery"
|
||||
"github.com/yakovlevdmv/goonvif/networking"
|
||||
"github.com/yakovlevdmv/gosoap"
|
||||
)
|
||||
|
||||
var Xlmns = map[string]string {
|
||||
"onvif":"http://www.onvif.org/ver10/schema",
|
||||
"tds":"http://www.onvif.org/ver10/device/wsdl",
|
||||
"trt":"http://www.onvif.org/ver10/media/wsdl",
|
||||
"tev":"http://www.onvif.org/ver10/events/wsdl",
|
||||
"tptz":"http://www.onvif.org/ver20/ptz/wsdl",
|
||||
"timg":"http://www.onvif.org/ver20/imaging/wsdl",
|
||||
"tan":"http://www.onvif.org/ver20/analytics/wsdl",
|
||||
"xmime":"http://www.w3.org/2005/05/xmlmime",
|
||||
"wsnt":"http://docs.oasis-open.org/wsn/b-2",
|
||||
"xop":"http://www.w3.org/2004/08/xop/include",
|
||||
"wsa":"http://www.w3.org/2005/08/addressing",
|
||||
"wstop":"http://docs.oasis-open.org/wsn/t-1",
|
||||
"wsntw":"http://docs.oasis-open.org/wsn/bw-2",
|
||||
"wsrf-rw":"http://docs.oasis-open.org/wsrf/rw-2",
|
||||
"wsaw":"http://www.w3.org/2006/05/addressing/wsdl",
|
||||
//Xlmns XML Scheam
|
||||
var Xlmns = map[string]string{
|
||||
"onvif": "http://www.onvif.org/ver10/schema",
|
||||
"tds": "http://www.onvif.org/ver10/device/wsdl",
|
||||
"trt": "http://www.onvif.org/ver10/media/wsdl",
|
||||
"tev": "http://www.onvif.org/ver10/events/wsdl",
|
||||
"tptz": "http://www.onvif.org/ver20/ptz/wsdl",
|
||||
"timg": "http://www.onvif.org/ver20/imaging/wsdl",
|
||||
"tan": "http://www.onvif.org/ver20/analytics/wsdl",
|
||||
"xmime": "http://www.w3.org/2005/05/xmlmime",
|
||||
"wsnt": "http://docs.oasis-open.org/wsn/b-2",
|
||||
"xop": "http://www.w3.org/2004/08/xop/include",
|
||||
"wsa": "http://www.w3.org/2005/08/addressing",
|
||||
"wstop": "http://docs.oasis-open.org/wsn/t-1",
|
||||
"wsntw": "http://docs.oasis-open.org/wsn/bw-2",
|
||||
"wsrf-rw": "http://docs.oasis-open.org/wsrf/rw-2",
|
||||
"wsaw": "http://www.w3.org/2006/05/addressing/wsdl",
|
||||
}
|
||||
|
||||
//DeviceType alias for int
|
||||
type DeviceType int
|
||||
|
||||
// Onvif Device Tyoe
|
||||
const (
|
||||
NVD DeviceType = iota
|
||||
NVS
|
||||
@@ -44,7 +48,7 @@ const (
|
||||
)
|
||||
|
||||
func (devType DeviceType) String() string {
|
||||
stringRepresentation := []string {
|
||||
stringRepresentation := []string{
|
||||
"NetworkVideoDisplay",
|
||||
"NetworkVideoStorage",
|
||||
"NetworkVideoAnalytics",
|
||||
@@ -61,28 +65,26 @@ func (devType DeviceType) String() string {
|
||||
|
||||
//deviceInfo struct contains general information about ONVIF device
|
||||
type deviceInfo struct {
|
||||
Manufacturer string
|
||||
Model string
|
||||
Manufacturer string
|
||||
Model string
|
||||
FirmwareVersion string
|
||||
SerialNumber string
|
||||
HardwareId string
|
||||
|
||||
SerialNumber string
|
||||
HardwareId string
|
||||
}
|
||||
|
||||
//deviceInfo struct represents an abstract ONVIF device.
|
||||
//Device for a new device of onvif and deviceInfo
|
||||
//struct represents an abstract ONVIF device.
|
||||
//It contains methods, which helps to communicate with ONVIF device
|
||||
type device struct {
|
||||
|
||||
xaddr string
|
||||
login string
|
||||
password string
|
||||
|
||||
type Device struct {
|
||||
xaddr string
|
||||
login string
|
||||
password string
|
||||
endpoints map[string]string
|
||||
info deviceInfo
|
||||
|
||||
info deviceInfo
|
||||
}
|
||||
|
||||
func (dev *device)GetServices() map[string]string {
|
||||
//GetServices return available endpoints
|
||||
func (dev *Device) GetServices() map[string]string {
|
||||
return dev.endpoints
|
||||
}
|
||||
|
||||
@@ -94,12 +96,13 @@ func readResponse(resp *http.Response) string {
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func GetAvailableDevicesAtSpecificEthernetInterface(interfaceName string) []device {
|
||||
//GetAvailableDevicesAtSpecificEthernetInterface ...
|
||||
func GetAvailableDevicesAtSpecificEthernetInterface(interfaceName string) []Device {
|
||||
/*
|
||||
Call an WS-Discovery Probe Message to Discover NVT type Devices
|
||||
*/
|
||||
devices := WS_Discovery.SendProbe(interfaceName, nil, []string{"dn:"+NVT.String()}, map[string]string{"dn":"http://www.onvif.org/ver10/network/wsdl"})
|
||||
nvtDevices := make([]device, 0)
|
||||
Call an WS-Discovery Probe Message to Discover NVT type Devices
|
||||
*/
|
||||
devices := WS_Discovery.SendProbe(interfaceName, nil, []string{"dn:" + NVT.String()}, map[string]string{"dn": "http://www.onvif.org/ver10/network/wsdl"})
|
||||
nvtDevices := make([]Device, 0)
|
||||
////fmt.Println(devices)
|
||||
for _, j := range devices {
|
||||
doc := etree.NewDocument()
|
||||
@@ -140,37 +143,37 @@ func GetAvailableDevicesAtSpecificEthernetInterface(interfaceName string) []devi
|
||||
return nvtDevices
|
||||
}
|
||||
|
||||
func (dev *device) getSupportedServices(resp *http.Response) {
|
||||
func (dev *Device) getSupportedServices(resp *http.Response) {
|
||||
//resp, err := dev.CallMethod(Device.GetCapabilities{Category:"All"})
|
||||
//if err != nil {
|
||||
// log.Println(err.Error())
|
||||
//return
|
||||
//return
|
||||
//} else {
|
||||
doc := etree.NewDocument()
|
||||
doc := etree.NewDocument()
|
||||
|
||||
data, _ := ioutil.ReadAll(resp.Body)
|
||||
data, _ := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err := doc.ReadFromBytes(data); err != nil {
|
||||
//log.Println(err.Error())
|
||||
return
|
||||
}
|
||||
services := doc.FindElements("./Envelope/Body/GetCapabilitiesResponse/Capabilities/*/XAddr")
|
||||
for _, j := range services{
|
||||
////fmt.Println(j.Text())
|
||||
////fmt.Println(j.Parent().Tag)
|
||||
dev.addEndpoint(j.Parent().Tag, j.Text())
|
||||
}
|
||||
if err := doc.ReadFromBytes(data); err != nil {
|
||||
//log.Println(err.Error())
|
||||
return
|
||||
}
|
||||
services := doc.FindElements("./Envelope/Body/GetCapabilitiesResponse/Capabilities/*/XAddr")
|
||||
for _, j := range services {
|
||||
////fmt.Println(j.Text())
|
||||
////fmt.Println(j.Parent().Tag)
|
||||
dev.addEndpoint(j.Parent().Tag, j.Text())
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
//NewDevice function construct a ONVIF Device entity
|
||||
func NewDevice(xaddr string) (*device, error) {
|
||||
dev := new(device)
|
||||
func NewDevice(xaddr string) (*Device, error) {
|
||||
dev := new(Device)
|
||||
dev.xaddr = xaddr
|
||||
dev.endpoints = make(map[string]string)
|
||||
dev.addEndpoint("Device", "http://"+xaddr+"/onvif/device_service")
|
||||
|
||||
getCapabilities := Device.GetCapabilities{Category: "All"}
|
||||
getCapabilities := device.GetCapabilities{Category: "All"}
|
||||
|
||||
resp, err := dev.CallMethod(getCapabilities)
|
||||
//fmt.Println(resp.Request.Host)
|
||||
@@ -184,25 +187,24 @@ func NewDevice(xaddr string) (*device, error) {
|
||||
return dev, nil
|
||||
}
|
||||
|
||||
func (dev *device)addEndpoint(Key, Value string) {
|
||||
dev.endpoints[Key]=Value
|
||||
func (dev *Device) addEndpoint(Key, Value string) {
|
||||
dev.endpoints[Key] = Value
|
||||
}
|
||||
|
||||
//Authenticate function authenticate client in the ONVIF Device.
|
||||
//Function takes <username> and <password> params.
|
||||
//You should use this function to allow authorized requests to the ONVIF Device
|
||||
//To change auth data call this function again.
|
||||
func (dev *device) Authenticate(username, password string) {
|
||||
func (dev *Device) Authenticate(username, password string) {
|
||||
dev.login = username
|
||||
dev.password = password
|
||||
}
|
||||
|
||||
//GetEndpoint returns specific ONVIF service endpoint address
|
||||
func (dev *device) GetEndpoint(name string) string {
|
||||
func (dev *Device) GetEndpoint(name string) string {
|
||||
return dev.endpoints[name]
|
||||
}
|
||||
|
||||
|
||||
func buildMethodSOAP(msg string) (gosoap.SoapMessage, error) {
|
||||
doc := etree.NewDocument()
|
||||
if err := doc.ReadFromString(msg); err != nil {
|
||||
@@ -212,7 +214,6 @@ func buildMethodSOAP(msg string) (gosoap.SoapMessage, error) {
|
||||
}
|
||||
element := doc.Root()
|
||||
|
||||
|
||||
soap := gosoap.NewEmptySOAP()
|
||||
soap.AddBodyContent(element)
|
||||
//soap.AddRootNamespace("onvif", "http://www.onvif.org/ver10/device/wsdl")
|
||||
@@ -220,21 +221,24 @@ func buildMethodSOAP(msg string) (gosoap.SoapMessage, error) {
|
||||
return soap, nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
//CallMethod functions call an method, defined <method> struct.
|
||||
//You should use Authenticate method to call authorized requests.
|
||||
func (dev device) CallMethod(method interface{}) (*http.Response, error) {
|
||||
pkgPath := strings.Split(reflect.TypeOf(method).PkgPath(),"/")
|
||||
func (dev Device) CallMethod(method interface{}) (*http.Response, error) {
|
||||
pkgPath := strings.Split(reflect.TypeOf(method).PkgPath(), "/")
|
||||
pkg := pkgPath[len(pkgPath)-1]
|
||||
|
||||
var endpoint string
|
||||
switch pkg {
|
||||
case "Device": endpoint = dev.endpoints["Device"]
|
||||
case "Event": endpoint = dev.endpoints["Event"]
|
||||
case "Imaging": endpoint = dev.endpoints["Imaging"]
|
||||
case "Media": endpoint = dev.endpoints["Media"]
|
||||
case "PTZ": endpoint = dev.endpoints["PTZ"]
|
||||
case "Device":
|
||||
endpoint = dev.endpoints["Device"]
|
||||
case "Event":
|
||||
endpoint = dev.endpoints["Event"]
|
||||
case "Imaging":
|
||||
endpoint = dev.endpoints["Imaging"]
|
||||
case "Media":
|
||||
endpoint = dev.endpoints["Media"]
|
||||
case "PTZ":
|
||||
endpoint = dev.endpoints["PTZ"]
|
||||
}
|
||||
|
||||
//TODO: Get endpoint automatically
|
||||
@@ -246,11 +250,11 @@ func (dev device) CallMethod(method interface{}) (*http.Response, error) {
|
||||
}
|
||||
|
||||
//CallNonAuthorizedMethod functions call an method, defined <method> struct without authentication data
|
||||
func (dev device) callNonAuthorizedMethod(endpoint string, method interface{}) (*http.Response, error) {
|
||||
func (dev Device) callNonAuthorizedMethod(endpoint string, method interface{}) (*http.Response, error) {
|
||||
//TODO: Get endpoint automatically
|
||||
/*
|
||||
Converting <method> struct to xml string representation
|
||||
*/
|
||||
Converting <method> struct to xml string representation
|
||||
*/
|
||||
output, err := xml.MarshalIndent(method, " ", " ")
|
||||
if err != nil {
|
||||
//log.Printf("error: %v\n", err.Error())
|
||||
@@ -258,8 +262,8 @@ func (dev device) callNonAuthorizedMethod(endpoint string, method interface{}) (
|
||||
}
|
||||
|
||||
/*
|
||||
Build an SOAP request with <method>
|
||||
*/
|
||||
Build an SOAP request with <method>
|
||||
*/
|
||||
soap, err := buildMethodSOAP(string(output))
|
||||
if err != nil {
|
||||
//log.Printf("error: %v\n", err)
|
||||
@@ -267,21 +271,21 @@ func (dev device) callNonAuthorizedMethod(endpoint string, method interface{}) (
|
||||
}
|
||||
|
||||
/*
|
||||
Adding namespaces
|
||||
*/
|
||||
Adding namespaces
|
||||
*/
|
||||
soap.AddRootNamespaces(Xlmns)
|
||||
|
||||
/*
|
||||
Sending request and returns the response
|
||||
*/
|
||||
Sending request and returns the response
|
||||
*/
|
||||
return networking.SendSoap(endpoint, soap.String())
|
||||
}
|
||||
|
||||
//CallMethod functions call an method, defined <method> struct with authentication data
|
||||
func (dev device) callAuthorizedMethod(endpoint string, method interface{}) (*http.Response, error) {
|
||||
func (dev Device) callAuthorizedMethod(endpoint string, method interface{}) (*http.Response, error) {
|
||||
/*
|
||||
Converting <method> struct to xml string representation
|
||||
*/
|
||||
Converting <method> struct to xml string representation
|
||||
*/
|
||||
output, err := xml.MarshalIndent(method, " ", " ")
|
||||
if err != nil {
|
||||
//log.Printf("error: %v\n", err.Error())
|
||||
@@ -289,8 +293,8 @@ func (dev device) callAuthorizedMethod(endpoint string, method interface{}) (*ht
|
||||
}
|
||||
|
||||
/*
|
||||
Build an SOAP request with <method>
|
||||
*/
|
||||
Build an SOAP request with <method>
|
||||
*/
|
||||
soap, err := buildMethodSOAP(string(output))
|
||||
if err != nil {
|
||||
//log.Printf("error: %v\n", err.Error())
|
||||
@@ -298,14 +302,13 @@ func (dev device) callAuthorizedMethod(endpoint string, method interface{}) (*ht
|
||||
}
|
||||
|
||||
/*
|
||||
Adding namespaces and WS-Security headers
|
||||
*/
|
||||
Adding namespaces and WS-Security headers
|
||||
*/
|
||||
soap.AddRootNamespaces(Xlmns)
|
||||
soap.AddWSSecurity(dev.login, dev.password)
|
||||
|
||||
|
||||
/*
|
||||
Sending request and returns the response
|
||||
*/
|
||||
Sending request and returns the response
|
||||
*/
|
||||
return networking.SendSoap(endpoint, soap.String())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user