diff --git a/Device.go b/Device.go index e9ed85f..0c3bfa7 100644 --- a/Device.go +++ b/Device.go @@ -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)) } diff --git a/Device/types.go b/Device/types.go index d37dd72..66bd131 100644 --- a/Device/types.go +++ b/Device/types.go @@ -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 diff --git a/Event/types.go b/Event/types.go index 3e25b83..d669d50 100644 --- a/Event/types.go +++ b/Event/types.go @@ -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 } diff --git a/Imaging/types.go b/Imaging/types.go index 6e03db2..a9674d9 100644 --- a/Imaging/types.go +++ b/Imaging/types.go @@ -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"` } diff --git a/Media/types.go b/Media/types.go index 2572108..317f8d8 100644 --- a/Media/types.go +++ b/Media/types.go @@ -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"` diff --git a/PTZ/types.go b/PTZ/types.go index 029cc34..3825d07 100644 --- a/PTZ/types.go +++ b/PTZ/types.go @@ -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 { diff --git a/Networking/networking.go b/networking/networking.go similarity index 94% rename from Networking/networking.go rename to networking/networking.go index 6ebe662..8f1cc70 100644 --- a/Networking/networking.go +++ b/networking/networking.go @@ -1,4 +1,4 @@ -package Networking +package networking import ( "net/http" diff --git a/soap/soap.go b/soap/soap.go deleted file mode 100644 index c9ef791..0000000 --- a/soap/soap.go +++ /dev/null @@ -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)) -} \ No newline at end of file diff --git a/xsd/onvif/onvif.go b/xsd/onvif/onvif.go index c592477..7d7d454 100644 --- a/xsd/onvif/onvif.go +++ b/xsd/onvif/onvif.go @@ -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 struct {Any string} convert to type 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"` -} - - - - - - - - - - - - - - - - - - - - - - - - +} \ No newline at end of file