This commit is contained in:
George Palanjyan
2018-04-04 22:04:13 +03:00
parent ec191635bd
commit c6ad810450
9 changed files with 25 additions and 234 deletions

View File

@@ -6,21 +6,31 @@ import (
"log"
"fmt"
"github.com/beevik/etree"
"github.com/yakovlevdmv/goonvif/Networking"
"github.com/yakovlevdmv/goonvif/networking"
"time"
"encoding/base64"
"crypto/sha1"
"github.com/elgs/gostrgen"
"github.com/yakovlevdmv/gosoap"
"reflect"
"strings"
"github.com/yakovlevdmv/goonvif/Device"
"github.com/yakovlevdmv/goonvif/Imaging"
"github.com/yakovlevdmv/goonvif/Media"
"github.com/yakovlevdmv/goonvif/PTZ"
"errors"
)
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",
"tpz":"http://www.onvif.org/ver20/ptz/wsdl",
"timg":"http://www.onvif.org/ver20/imaging/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",
}
type DeviceInfo struct {
Manufacturer string
Model string
@@ -52,7 +62,7 @@ func (dev *device) AddAuthentification(username, password string) {
dev.password = password
}
func buildMethodSOAP(msg, space string) (gosoap.SoapMessage, error) {
func buildMethodSOAP(msg string) (gosoap.SoapMessage, error) {
doc := etree.NewDocument()
if err := doc.ReadFromString(msg); err != nil {
log.Println("Got error")
@@ -64,29 +74,10 @@ func buildMethodSOAP(msg, space string) (gosoap.SoapMessage, error) {
soap := gosoap.NewEmptySOAP()
soap.AddBodyContent(element)
soap.AddRootNamespace("onvif", "http://www.onvif.org/ver10/device/wsdl")
soap.AddRootNamespace("wsdl", space)
return soap, nil
}
func setXMLNamespaces(strct interface{}) (string, error) {
pkgName := reflect.TypeOf( strct ).PkgPath()
pkgSplit := strings.Split(pkgName, "/")
pkgName = pkgSplit[len(pkgSplit)-1]
switch pkgName {
case "Device":
return Device.WSDL, nil
case "Imaging":
return Imaging.WSDL, nil
case "Media":
return Media.WSDL, nil
case "PTZ":
return PTZ.WSDL, nil
default:
return "", errors.New("Can't find Service")
}
}
//TODO: Get endpoint automatically
func (dev device) CallMethod(endpoint string, method interface{}) {
@@ -99,12 +90,11 @@ func (dev device) CallMethod(endpoint string, method interface{}) {
fmt.Println(string(output))
wsdlSpaces, err := setXMLNamespaces(method)
if err != nil {
fmt.Println(err)
}
soap, err := buildMethodSOAP(string(output), wsdlSpaces)
soap, err := buildMethodSOAP(string(output))
if err != nil {
log.Fatal(err)
}
@@ -113,7 +103,7 @@ func (dev device) CallMethod(endpoint string, method interface{}) {
fmt.Println("Send soap\n")
fmt.Println(soap.String())
Networking.SendSoap(endpoint, soap.String())
networking.SendSoap(endpoint, soap.String())
}
/*************************
@@ -168,12 +158,11 @@ func (dev device) CallAuthorizedMethod(endpoint string, method interface{}) {
log.Println("Marshalled struct: ", string(output))
}
wsdlSpaces, err := setXMLNamespaces(method)
if err != nil {
fmt.Println(err)
}
soap, err := buildMethodSOAP(string(output), wsdlSpaces)
soap, err := buildMethodSOAP(string(output))
if err != nil {
log.Fatal(err)
}
@@ -211,6 +200,6 @@ func (dev device) CallAuthorizedMethod(endpoint string, method interface{}) {
}
Networking.SendSoap(endpoint, soap.String())
networking.SendSoap(endpoint, soap.String())
//fmt.Println(string(output))
}

View File

@@ -5,8 +5,6 @@ import (
"github.com/yakovlevdmv/goonvif/xsd/onvif"
)
const WSDL = "http://www.onvif.org/ver10/device/wsdl"
type Service struct {
Namespace xsd.AnyURI
XAddr xsd.AnyURI

View File

@@ -4,8 +4,6 @@ import (
"github.com/yakovlevdmv/goonvif/xsd"
)
//const WSDL = "http://www.onvif.org/ver10/events/wsdl"
type FilterType struct { //wsnt http://docs.oasis-open.org/wsn/b-2.xsd
Any string
}

View File

@@ -5,8 +5,6 @@ import (
"github.com/yakovlevdmv/goonvif/xsd"
)
const WSDL = "http://www.onvif.org/ver20/imaging/wsdl"
type GetServiceCapabilities struct {
XMLName string `xml:"wsdl:GetServiceCapabilities"`
}

View File

@@ -5,8 +5,6 @@ import (
"github.com/yakovlevdmv/goonvif/xsd"
)
const WSDL = "http://www.onvif.org/ver10/media/wsdl"
type Capabilities struct {
SnapshotUri bool `xml:"SnapshotUri,attr"`
Rotation bool `xml:"Rotation,attr"`

View File

@@ -11,9 +11,6 @@ type Capabilities struct {
StatusPosition xsd.Boolean `xml:"StatusPosition,attr"`
}
const WSDL = "http://www.onvif.org/ver20/ptz/wsdl"
//PTZ main types
type GetServiceCapabilities struct {

View File

@@ -1,4 +1,4 @@
package Networking
package networking
import (
"net/http"

View File

@@ -1,161 +0,0 @@
package goonvif
import (
"encoding/xml"
"time"
"github.com/elgs/gostrgen"
"github.com/yakovlevdmv/goonvif/scheme"
"encoding/base64"
"crypto/sha1"
"fmt"
"log"
"net/http"
"bytes"
"io/ioutil"
)
var xlmns = map[string]string {
// SOAP namespase
"soap":"http://www.w3.org/2003/05/soap-envelope",
"xs":"http://www.w3.org/2001/XMLSchema",
// ONVIF namespace
"tt":"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",
"ter":"http://www.onvif.org/ver10/error",
"dn":"http://www.onvif.org/ver10/network/wsdl",
"tns1":"http://www.onvif.org/ver10/topics",
"tpz":"http://www.onvif.org/ver20/ptz/wsdl",
"dev":"https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl",
"xsi":"http://www.w3.org/2001/XMLSchema-instance",
"xsd":"http://www.w3.org/2001/XMLSchema",
"wsse":"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
"wsu":"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd",
}
var passwordType = "https://www.oasis-open.org/committees/download.php/13392/wss-v1.1-spec-pr-UsernameTokenProfile-01.htm#PasswordDigest"
type Envelope struct {
XMLName xml.Name `xml:"soap:Envelope"`
XmlnsSoap string `xml:"xmlns:soap,attr,omitempty"`
XmlnsXsi string `xml:"xmlns:xsi,attr,omitempty"`
XmlnsXsd string `xml:"xmlns:xsd,attr,omitempty"`
XmlnsTt string `xml:"xmlns:tt,attr,omitempty"`
XmlnsWsse string `xml:"xmlns:wsse,attr,omitempty"`
XmlnsWsu string `xml:"xmlns:wsu,attr,omitempty"`
XmlnsWsdl string `xml:"xmlns:wsdl,attr,omitempty"`
Header Header
Body Body
}
type Header struct {
XMLName xml.Name `xml:"soap:Header"`
WSAuth Security
}
type BodyContent struct {
XMLName xml.Name
Content string `xml:",innerxml"`
}
type Body struct {
XMLName xml.Name `xml:"soap:Body"`
Content BodyContent
}
type Security struct {
XMLName xml.Name `xml:"wsse:Security"`
Auth WSAuth
}
type Password struct {
XMLName xml.Name `xml:"wsse:Password"`
Type string `xml:"Type,attr"`
Password string `xml:",chardata"`
}
type WSAuth struct {
XMLName xml.Name `xml:"wsse:UsernameToken"`
Username string `xml:"wsse:Username"`
Password Password `xml:"wsse:Password"`
Nonce string `xml:"wsse:Nonce"`
Created string `xml:"wsse:Created"`
}
//Digest = B64ENCODE( SHA1( B64DECODE( Nonce ) + Date + Password ) )
func generateToken(Username string, Nonce string, Created time.Time, Password string) string {
sDec, _ := base64.StdEncoding.DecodeString(Nonce)
hasher := sha1.New()
//hasher.Write([]byte((base64.StdEncoding.EncodeToString([]byte(Nonce)) + Created.Format(time.RFC3339) + Password)))
hasher.Write([]byte(string(sDec) + Created.Format(time.RFC3339) + Password))
return base64.StdEncoding.EncodeToString(hasher.Sum(nil))
}
//func (t *emptyInput)createSelfCloseTag() string {
// t.EmptyInput
//}
func NewEnvelope( funcName string, data scheme.TypeWorker ) Envelope {
/** Generating Nonce sequence **/
charsToGenerate := 16
charSet := gostrgen.Lower | gostrgen.Digit
nonce, _ := gostrgen.RandGen(charsToGenerate, charSet, "", "")
output, err := xml.MarshalIndent(data, "", " ")
if err != nil {
log.Fatal(err)
}
var soapData = Envelope{
XmlnsSoap:xlmns["soap"],
XmlnsXsd:xlmns["xsd"],
XmlnsXsi:xlmns["xsi"],
XmlnsWsdl:xlmns["dev"],
XmlnsTt:xlmns["tt"],
XmlnsWsse:xlmns["wsse"],
XmlnsWsu:xlmns["wsu"],
Header:Header {
WSAuth:Security {
Auth:WSAuth {
Username:"admin",
Password:Password {
Type:passwordType,
Password:generateToken("admin", nonce, time.Now(), "Supervisor"),
},
Nonce: nonce,
Created: time.Now().Format(time.RFC3339),
},
},
},
Body:Body{
Content:BodyContent{
XMLName:xml.Name{Local:"wsdl:" + funcName},
Content:"\n\t"+string(output)+"\n",},
},
}
return soapData
}
func SendSoap() {
env := NewEnvelope("GetDNS", nil)
soapReq, _ := xml.MarshalIndent(env, "", " ")
httpClient := new(http.Client)
resp, _ := httpClient.Post("http://192.168.13.53", "application/soap+xml; charset=utf-8", bytes.NewBufferString(string(soapReq)))
b, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(b))
}

View File

@@ -4,8 +4,6 @@ import (
"github.com/yakovlevdmv/goonvif/xsd"
)
const ONVIF = "http://www.onvif.org/ver10/schema"
//TODO: rename package xsdTypes
//TODO: enumerations
//TODO: type <typeName> struct {Any string} convert to type <typeName> AnyType
@@ -1868,28 +1866,4 @@ type Date struct {
Year xsd.Int `xml:"onvif:Year"`
Month xsd.Int `xml:"onvif:Month"`
Day xsd.Int `xml:"onvif:Day"`
}
}