Expose Device type for outer developer using & format code file

This commit is contained in:
Eamon
2018-05-16 14:12:18 +08:00
parent 494e918db8
commit 57dc05360e

121
Device.go
View File

@@ -2,40 +2,44 @@ package goonvif
import ( import (
"encoding/xml" "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" "errors"
"fmt"
"io/ioutil"
"net/http"
"reflect" "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/goonvif/networking"
"github.com/yakovlevdmv/gosoap"
) )
var Xlmns = map[string]string { //Xlmns XML Scheam
"onvif":"http://www.onvif.org/ver10/schema", var Xlmns = map[string]string{
"tds":"http://www.onvif.org/ver10/device/wsdl", "onvif": "http://www.onvif.org/ver10/schema",
"trt":"http://www.onvif.org/ver10/media/wsdl", "tds": "http://www.onvif.org/ver10/device/wsdl",
"tev":"http://www.onvif.org/ver10/events/wsdl", "trt": "http://www.onvif.org/ver10/media/wsdl",
"tptz":"http://www.onvif.org/ver20/ptz/wsdl", "tev": "http://www.onvif.org/ver10/events/wsdl",
"timg":"http://www.onvif.org/ver20/imaging/wsdl", "tptz": "http://www.onvif.org/ver20/ptz/wsdl",
"tan":"http://www.onvif.org/ver20/analytics/wsdl", "timg": "http://www.onvif.org/ver20/imaging/wsdl",
"xmime":"http://www.w3.org/2005/05/xmlmime", "tan": "http://www.onvif.org/ver20/analytics/wsdl",
"wsnt":"http://docs.oasis-open.org/wsn/b-2", "xmime": "http://www.w3.org/2005/05/xmlmime",
"xop":"http://www.w3.org/2004/08/xop/include", "wsnt": "http://docs.oasis-open.org/wsn/b-2",
"wsa":"http://www.w3.org/2005/08/addressing", "xop": "http://www.w3.org/2004/08/xop/include",
"wstop":"http://docs.oasis-open.org/wsn/t-1", "wsa": "http://www.w3.org/2005/08/addressing",
"wsntw":"http://docs.oasis-open.org/wsn/bw-2", "wstop": "http://docs.oasis-open.org/wsn/t-1",
"wsrf-rw":"http://docs.oasis-open.org/wsrf/rw-2", "wsntw": "http://docs.oasis-open.org/wsn/bw-2",
"wsaw":"http://www.w3.org/2006/05/addressing/wsdl", "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 type DeviceType int
// Onvif Device Tyoe
const ( const (
NVD DeviceType = iota NVD DeviceType = iota
NVS NVS
@@ -44,7 +48,7 @@ const (
) )
func (devType DeviceType) String() string { func (devType DeviceType) String() string {
stringRepresentation := []string { stringRepresentation := []string{
"NetworkVideoDisplay", "NetworkVideoDisplay",
"NetworkVideoStorage", "NetworkVideoStorage",
"NetworkVideoAnalytics", "NetworkVideoAnalytics",
@@ -66,23 +70,21 @@ type deviceInfo struct {
FirmwareVersion string FirmwareVersion string
SerialNumber string SerialNumber string
HardwareId 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 //It contains methods, which helps to communicate with ONVIF device
type device struct { type Device struct {
xaddr string xaddr string
login string login string
password string password string
endpoints map[string]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 return dev.endpoints
} }
@@ -94,12 +96,13 @@ func readResponse(resp *http.Response) string {
return string(b) 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 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"}) 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) nvtDevices := make([]Device, 0)
////fmt.Println(devices) ////fmt.Println(devices)
for _, j := range devices { for _, j := range devices {
doc := etree.NewDocument() doc := etree.NewDocument()
@@ -140,7 +143,7 @@ func GetAvailableDevicesAtSpecificEthernetInterface(interfaceName string) []devi
return nvtDevices return nvtDevices
} }
func (dev *device) getSupportedServices(resp *http.Response) { func (dev *Device) getSupportedServices(resp *http.Response) {
//resp, err := dev.CallMethod(Device.GetCapabilities{Category:"All"}) //resp, err := dev.CallMethod(Device.GetCapabilities{Category:"All"})
//if err != nil { //if err != nil {
// log.Println(err.Error()) // log.Println(err.Error())
@@ -155,7 +158,7 @@ func (dev *device) getSupportedServices(resp *http.Response) {
return return
} }
services := doc.FindElements("./Envelope/Body/GetCapabilitiesResponse/Capabilities/*/XAddr") services := doc.FindElements("./Envelope/Body/GetCapabilitiesResponse/Capabilities/*/XAddr")
for _, j := range services{ for _, j := range services {
////fmt.Println(j.Text()) ////fmt.Println(j.Text())
////fmt.Println(j.Parent().Tag) ////fmt.Println(j.Parent().Tag)
dev.addEndpoint(j.Parent().Tag, j.Text()) dev.addEndpoint(j.Parent().Tag, j.Text())
@@ -164,13 +167,13 @@ func (dev *device) getSupportedServices(resp *http.Response) {
} }
//NewDevice function construct a ONVIF Device entity //NewDevice function construct a ONVIF Device entity
func NewDevice(xaddr string) (*device, error) { func NewDevice(xaddr string) (*Device, error) {
dev := new(device) dev := new(Device)
dev.xaddr = xaddr dev.xaddr = xaddr
dev.endpoints = make(map[string]string) dev.endpoints = make(map[string]string)
dev.addEndpoint("Device", "http://"+xaddr+"/onvif/device_service") dev.addEndpoint("Device", "http://"+xaddr+"/onvif/device_service")
getCapabilities := Device.GetCapabilities{Category: "All"} getCapabilities := device.GetCapabilities{Category: "All"}
resp, err := dev.CallMethod(getCapabilities) resp, err := dev.CallMethod(getCapabilities)
//fmt.Println(resp.Request.Host) //fmt.Println(resp.Request.Host)
@@ -184,25 +187,24 @@ func NewDevice(xaddr string) (*device, error) {
return dev, nil return dev, nil
} }
func (dev *device)addEndpoint(Key, Value string) { func (dev *Device) addEndpoint(Key, Value string) {
dev.endpoints[Key]=Value dev.endpoints[Key] = Value
} }
//Authenticate function authenticate client in the ONVIF Device. //Authenticate function authenticate client in the ONVIF Device.
//Function takes <username> and <password> params. //Function takes <username> and <password> params.
//You should use this function to allow authorized requests to the ONVIF Device //You should use this function to allow authorized requests to the ONVIF Device
//To change auth data call this function again. //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.login = username
dev.password = password dev.password = password
} }
//GetEndpoint returns specific ONVIF service endpoint address //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] return dev.endpoints[name]
} }
func buildMethodSOAP(msg string) (gosoap.SoapMessage, error) { func buildMethodSOAP(msg string) (gosoap.SoapMessage, error) {
doc := etree.NewDocument() doc := etree.NewDocument()
if err := doc.ReadFromString(msg); err != nil { if err := doc.ReadFromString(msg); err != nil {
@@ -212,7 +214,6 @@ func buildMethodSOAP(msg string) (gosoap.SoapMessage, error) {
} }
element := doc.Root() element := doc.Root()
soap := gosoap.NewEmptySOAP() soap := gosoap.NewEmptySOAP()
soap.AddBodyContent(element) soap.AddBodyContent(element)
//soap.AddRootNamespace("onvif", "http://www.onvif.org/ver10/device/wsdl") //soap.AddRootNamespace("onvif", "http://www.onvif.org/ver10/device/wsdl")
@@ -220,21 +221,24 @@ func buildMethodSOAP(msg string) (gosoap.SoapMessage, error) {
return soap, nil return soap, nil
} }
//CallMethod functions call an method, defined <method> struct. //CallMethod functions call an method, defined <method> struct.
//You should use Authenticate method to call authorized requests. //You should use Authenticate method to call authorized requests.
func (dev device) CallMethod(method interface{}) (*http.Response, error) { func (dev Device) CallMethod(method interface{}) (*http.Response, error) {
pkgPath := strings.Split(reflect.TypeOf(method).PkgPath(),"/") pkgPath := strings.Split(reflect.TypeOf(method).PkgPath(), "/")
pkg := pkgPath[len(pkgPath)-1] pkg := pkgPath[len(pkgPath)-1]
var endpoint string var endpoint string
switch pkg { switch pkg {
case "Device": endpoint = dev.endpoints["Device"] case "Device":
case "Event": endpoint = dev.endpoints["Event"] endpoint = dev.endpoints["Device"]
case "Imaging": endpoint = dev.endpoints["Imaging"] case "Event":
case "Media": endpoint = dev.endpoints["Media"] endpoint = dev.endpoints["Event"]
case "PTZ": endpoint = dev.endpoints["PTZ"] case "Imaging":
endpoint = dev.endpoints["Imaging"]
case "Media":
endpoint = dev.endpoints["Media"]
case "PTZ":
endpoint = dev.endpoints["PTZ"]
} }
//TODO: Get endpoint automatically //TODO: Get endpoint automatically
@@ -246,7 +250,7 @@ func (dev device) CallMethod(method interface{}) (*http.Response, error) {
} }
//CallNonAuthorizedMethod functions call an method, defined <method> struct without authentication data //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 //TODO: Get endpoint automatically
/* /*
Converting <method> struct to xml string representation Converting <method> struct to xml string representation
@@ -278,7 +282,7 @@ func (dev device) callNonAuthorizedMethod(endpoint string, method interface{}) (
} }
//CallMethod functions call an method, defined <method> struct with authentication data //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
*/ */
@@ -303,7 +307,6 @@ func (dev device) callAuthorizedMethod(endpoint string, method interface{}) (*ht
soap.AddRootNamespaces(Xlmns) soap.AddRootNamespaces(Xlmns)
soap.AddWSSecurity(dev.login, dev.password) soap.AddWSSecurity(dev.login, dev.password)
/* /*
Sending request and returns the response Sending request and returns the response
*/ */