mirror of
https://github.com/cedricve/go-onvif.git
synced 2025-09-27 21:02:09 +08:00
Cleaning code and only take one xAddr
This commit is contained in:
48
discovery.go
48
discovery.go
@@ -14,19 +14,19 @@ import (
|
|||||||
var errWrongDiscoveryResponse = errors.New("Response is not related to discovery request")
|
var errWrongDiscoveryResponse = errors.New("Response is not related to discovery request")
|
||||||
|
|
||||||
// StartDiscovery send a WS-Discovery message and wait for all matching device to respond
|
// StartDiscovery send a WS-Discovery message and wait for all matching device to respond
|
||||||
func StartDiscovery() ([]Device, error) {
|
func StartDiscovery(duration time.Duration) ([]Device, error) {
|
||||||
// Create initial discovery results
|
// Create initial discovery results
|
||||||
discoveryResults := []Device{}
|
discoveryResults := []Device{}
|
||||||
|
|
||||||
// Create WS-Discovery message
|
// Create WS-Discovery request
|
||||||
messageID := "uuid:" + uuid.NewV4().String()
|
requestID := "uuid:" + uuid.NewV4().String()
|
||||||
message := `<?xml version="1.0" encoding="UTF-8"?>
|
request := `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<s:Envelope
|
<s:Envelope
|
||||||
xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
||||||
xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing">
|
xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing">
|
||||||
<s:Header>
|
<s:Header>
|
||||||
<a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</a:Action>
|
<a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</a:Action>
|
||||||
<a:MessageID>` + messageID + `</a:MessageID>
|
<a:MessageID>` + requestID + `</a:MessageID>
|
||||||
<a:ReplyTo>
|
<a:ReplyTo>
|
||||||
<a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
|
<a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
|
||||||
</a:ReplyTo>
|
</a:ReplyTo>
|
||||||
@@ -44,8 +44,8 @@ func StartDiscovery() ([]Device, error) {
|
|||||||
</s:Envelope>`
|
</s:Envelope>`
|
||||||
|
|
||||||
// Clean WS-Discovery message
|
// Clean WS-Discovery message
|
||||||
message = regexp.MustCompile(`\>\s+\<`).ReplaceAllString(message, "><")
|
request = regexp.MustCompile(`\>\s+\<`).ReplaceAllString(request, "><")
|
||||||
message = regexp.MustCompile(`\s+`).ReplaceAllString(message, " ")
|
request = regexp.MustCompile(`\s+`).ReplaceAllString(request, " ")
|
||||||
|
|
||||||
// Create UDP address for local and multicast address
|
// Create UDP address for local and multicast address
|
||||||
localAddress, err := net.ResolveUDPAddr("udp4", ":0")
|
localAddress, err := net.ResolveUDPAddr("udp4", ":0")
|
||||||
@@ -66,13 +66,13 @@ func StartDiscovery() ([]Device, error) {
|
|||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
// Set connection's timeout
|
// Set connection's timeout
|
||||||
err = conn.SetDeadline(time.Now().Add(1 * time.Second))
|
err = conn.SetDeadline(time.Now().Add(duration))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return discoveryResults, err
|
return discoveryResults, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send WS-Discovery request to multicast address
|
// Send WS-Discovery request to multicast address
|
||||||
_, err = conn.WriteToUDP([]byte(message), multicastAddress)
|
_, err = conn.WriteToUDP([]byte(request), multicastAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return discoveryResults, err
|
return discoveryResults, err
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ func StartDiscovery() ([]Device, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read and parse WS-Discovery response
|
// Read and parse WS-Discovery response
|
||||||
device, err := readDiscoveryResponse(messageID, buffer)
|
device, err := readDiscoveryResponse(requestID, buffer)
|
||||||
if err != nil && err != errWrongDiscoveryResponse {
|
if err != nil && err != errWrongDiscoveryResponse {
|
||||||
return discoveryResults, err
|
return discoveryResults, err
|
||||||
}
|
}
|
||||||
@@ -117,29 +117,18 @@ func readDiscoveryResponse(messageID string, buffer []byte) (Device, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if this response is for our request
|
// Check if this response is for our request
|
||||||
responseMessageID, err := mapXML.ValueForPathString("Envelope.Header.RelatesTo")
|
responseMessageID, _ := mapXML.ValueForPathString("Envelope.Header.RelatesTo")
|
||||||
if err != nil {
|
|
||||||
return result, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if responseMessageID != messageID {
|
if responseMessageID != messageID {
|
||||||
return result, errWrongDiscoveryResponse
|
return result, errWrongDiscoveryResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get device's ID and clean it
|
// Get device's ID and clean it
|
||||||
deviceID, err := mapXML.ValueForPathString("Envelope.Body.ProbeMatches.ProbeMatch.EndpointReference.Address")
|
deviceID, _ := mapXML.ValueForPathString("Envelope.Body.ProbeMatches.ProbeMatch.EndpointReference.Address")
|
||||||
if err != nil {
|
|
||||||
return result, err
|
|
||||||
}
|
|
||||||
deviceID = strings.Replace(deviceID, "urn:uuid", "", 1)
|
deviceID = strings.Replace(deviceID, "urn:uuid", "", 1)
|
||||||
|
|
||||||
// Get device's name
|
// Get device's name
|
||||||
scopes, err := mapXML.ValueForPathString("Envelope.Body.ProbeMatches.ProbeMatch.Scopes")
|
|
||||||
if err != nil {
|
|
||||||
return result, err
|
|
||||||
}
|
|
||||||
|
|
||||||
deviceName := ""
|
deviceName := ""
|
||||||
|
scopes, _ := mapXML.ValueForPathString("Envelope.Body.ProbeMatches.ProbeMatch.Scopes")
|
||||||
for _, scope := range strings.Split(scopes, " ") {
|
for _, scope := range strings.Split(scopes, " ") {
|
||||||
if strings.HasPrefix(scope, "onvif://www.onvif.org/name/") {
|
if strings.HasPrefix(scope, "onvif://www.onvif.org/name/") {
|
||||||
deviceName = strings.Replace(scope, "onvif://www.onvif.org/name/", "", 1)
|
deviceName = strings.Replace(scope, "onvif://www.onvif.org/name/", "", 1)
|
||||||
@@ -148,16 +137,17 @@ func readDiscoveryResponse(messageID string, buffer []byte) (Device, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get device's XAddrs
|
// Get device's xAddrs
|
||||||
xAddrs, err := mapXML.ValueForPathString("Envelope.Body.ProbeMatches.ProbeMatch.XAddrs")
|
xAddrs, _ := mapXML.ValueForPathString("Envelope.Body.ProbeMatches.ProbeMatch.XAddrs")
|
||||||
if err != nil {
|
listXAddr := strings.Split(xAddrs, " ")
|
||||||
return result, err
|
if len(listXAddr) == 0 {
|
||||||
|
return result, errors.New("Device does not have any xAddr")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finalize result
|
// Finalize result
|
||||||
result.ID = deviceID
|
result.ID = deviceID
|
||||||
result.Name = deviceName
|
result.Name = deviceName
|
||||||
result.XAddrs = strings.Split(xAddrs, " ")
|
result.XAddr = listXAddr[0]
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user