logging added.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
;; with by higher-level modules.
|
||||
|
||||
(require racket/list
|
||||
simple-log
|
||||
racket/string
|
||||
racket/udp)
|
||||
|
||||
@@ -21,6 +22,8 @@
|
||||
ssdp-group-responses
|
||||
ssdp-discover)
|
||||
|
||||
(sl-def-log upnp-ssdp)
|
||||
|
||||
(define ssdp-multicast-address "239.255.255.250")
|
||||
(define ssdp-multicast-port 1900)
|
||||
|
||||
@@ -112,18 +115,29 @@
|
||||
(ssdp-response-target response "")
|
||||
(ssdp-response-location response "")))
|
||||
|
||||
(define (receive-responses socket timeout)
|
||||
(define (receive-responses socket timeout started-at)
|
||||
(dbg-upnp-ssdp "Waiting up to ~a seconds for SSDP responses" timeout)
|
||||
(let ([buffer (make-bytes 65535)]
|
||||
[deadline (+ (current-inexact-milliseconds) (* timeout 1000.0))])
|
||||
(let loop ([responses '()]
|
||||
[seen (hash)])
|
||||
(let ([remaining (/ (- deadline (current-inexact-milliseconds)) 1000.0)])
|
||||
(if (<= remaining 0)
|
||||
(reverse responses)
|
||||
(begin
|
||||
(dbg-upnp-ssdp
|
||||
"SSDP receive window closed after ~a ms with ~a unique responses"
|
||||
(inexact->exact (round (- (current-inexact-milliseconds) started-at)))
|
||||
(length responses))
|
||||
(reverse responses))
|
||||
(let ([received (sync/timeout remaining
|
||||
(udp-receive!-evt socket buffer))])
|
||||
(if (not received)
|
||||
(reverse responses)
|
||||
(begin
|
||||
(dbg-upnp-ssdp
|
||||
"SSDP receive timed out after ~a ms with ~a unique responses"
|
||||
(inexact->exact (round (- (current-inexact-milliseconds) started-at)))
|
||||
(length responses))
|
||||
(reverse responses))
|
||||
(let* ([length (car received)]
|
||||
[address (cadr received)]
|
||||
[port (caddr received)]
|
||||
@@ -131,9 +145,20 @@
|
||||
[response (parse-response packet address port)]
|
||||
[key (and response (response-key response))])
|
||||
(if (or (not response) (hash-has-key? seen key))
|
||||
(loop responses seen)
|
||||
(loop (cons response responses)
|
||||
(hash-set seen key #t)))))))))))
|
||||
(begin
|
||||
(when response
|
||||
(dbg-upnp-ssdp "Ignoring duplicate SSDP response from ~a:~a (~a)" address port (ssdp-response-usn response "unknown USN")))
|
||||
(loop responses seen))
|
||||
(begin
|
||||
(dbg-upnp-ssdp
|
||||
"Received SSDP response after ~a ms from ~a:~a, target=~a, location=~a"
|
||||
(inexact->exact (round (- (current-inexact-milliseconds) started-at)))
|
||||
address
|
||||
port
|
||||
(ssdp-response-target response "unknown")
|
||||
(ssdp-response-location response "unknown"))
|
||||
(loop (cons response responses)
|
||||
(hash-set seen key #t))))))))))))
|
||||
|
||||
;; Group responses by LOCATION so each device-description document only needs
|
||||
;; to be downloaded once.
|
||||
@@ -155,13 +180,13 @@
|
||||
;; advertised device and service targets. #:interface may be a local IPv4
|
||||
;; address such as "10.7.3.118" when the machine has multiple interfaces.
|
||||
(define (ssdp-discover [search-target "ssdp:all"]
|
||||
#:mx [mx 2]
|
||||
#:mx [mx 3]
|
||||
#:timeout [timeout #f]
|
||||
#:repeat [repeat 2]
|
||||
#:repeat [repeat 3]
|
||||
#:interface [interface #f]
|
||||
#:ttl [ttl 2]
|
||||
#:user-agent [user-agent #f])
|
||||
(let ([effective-timeout (or timeout (+ mx 0.5))])
|
||||
(let ([effective-timeout (or timeout (+ mx 1.0))])
|
||||
(check-discovery-arguments search-target
|
||||
mx
|
||||
effective-timeout
|
||||
@@ -169,21 +194,26 @@
|
||||
interface
|
||||
ttl
|
||||
user-agent)
|
||||
(dbg-upnp-ssdp "Starting SSDP discovery target=~a mx=~a timeout=~a repeat=~a interface=~a ttl=~a" search-target mx effective-timeout repeat (or interface "default") ttl)
|
||||
(let ([socket (udp-open-socket ssdp-multicast-address ssdp-multicast-port)]
|
||||
[request (make-search-request search-target mx user-agent)])
|
||||
(dynamic-wind
|
||||
void
|
||||
(lambda ()
|
||||
(define started-at (current-inexact-milliseconds))
|
||||
(udp-bind! socket interface 0)
|
||||
(dbg-upnp-ssdp "SSDP socket bound to interface ~a" (or interface "default"))
|
||||
(udp-multicast-set-interface! socket interface)
|
||||
(udp-multicast-set-ttl! socket ttl)
|
||||
(for ([attempt (in-range repeat)])
|
||||
(dbg-upnp-ssdp "Sending SSDP M-SEARCH attempt ~a of ~a" (add1 attempt) repeat)
|
||||
(udp-send-to socket
|
||||
ssdp-multicast-address
|
||||
ssdp-multicast-port
|
||||
request)
|
||||
(when (< attempt (sub1 repeat))
|
||||
(sleep 0.1)))
|
||||
(receive-responses socket effective-timeout))
|
||||
(sleep 0.25)))
|
||||
(receive-responses socket effective-timeout started-at))
|
||||
(lambda ()
|
||||
(dbg-upnp-ssdp "Closing SSDP socket")
|
||||
(udp-close socket))))))
|
||||
|
||||
Reference in New Issue
Block a user