mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-18 08:36:13 +00:00
fix(player,discovery): normalize uuid: prefix for STORED_MUSIC accounts; fill MediaServer.Address
The DLNA UDN from discovery carries a "uuid:" prefix (e.g. uuid:fa095ecc-...), but a SoundTouch STORED_MUSIC account is the bare UUID plus /0 (the speaker's /sources reports the bare form). The mismatch made the player Library tab show an "Add" button for an already-registered server, and an Add via the UI would have registered a wrong "uuid:.../0" account. Normalize (strip "uuid:") when mapping discovery results to the DTO and when building the account in HandleAddLibraryServer, so the LAN list and the registered list agree and Add builds the correct account. Verified live: discover now returns the bare UDN, matching /sources. Also populate the previously-unset MediaServer.Address from the ContentDirectory control URL host. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
ab7c857630
commit
e399b5ab00
@@ -3,6 +3,7 @@ package discovery
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"net/url"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@@ -140,6 +141,13 @@ func mediaServerFromDescription(desc *Description) (MediaServer, bool) {
|
||||
CDSControlURL: svc.ControlURL,
|
||||
}
|
||||
|
||||
// Populate Address from the CDS control URL host so callers know which
|
||||
// host:port to reach the device on. The control URL is absolute after
|
||||
// FetchDescription resolves it; parse errors leave Address empty.
|
||||
if u, err := url.Parse(svc.ControlURL); err == nil {
|
||||
srv.Address = u.Host
|
||||
}
|
||||
|
||||
// Walk sub-devices to fill in UDN / FriendlyName if the root is sparse
|
||||
// (some devices put it all in the sub-device, e.g. FRITZ!Box).
|
||||
fillFromTree(desc, &srv)
|
||||
|
||||
@@ -47,8 +47,19 @@ func TestMediaServerFromDescription_WithCDS(t *testing.T) {
|
||||
t.Errorf("IconURL %q is not absolute", srv.IconURL)
|
||||
}
|
||||
|
||||
t.Logf("MediaServer: UDN=%q FriendlyName=%q CDSControlURL=%q IconURL=%q",
|
||||
srv.UDN, srv.FriendlyName, srv.CDSControlURL, srv.IconURL)
|
||||
// Address must be the host:port from the CDS control URL.
|
||||
// cannedDescriptionXML has URLBase http://192.0.2.1:49000 and CDS
|
||||
// controlURL /ctl/ContentDir, so Address = "192.0.2.1:49000".
|
||||
if srv.Address == "" {
|
||||
t.Error("Address is empty")
|
||||
}
|
||||
|
||||
if srv.Address != "192.0.2.1:49000" {
|
||||
t.Errorf("Address = %q, want %q", srv.Address, "192.0.2.1:49000")
|
||||
}
|
||||
|
||||
t.Logf("MediaServer: UDN=%q FriendlyName=%q CDSControlURL=%q IconURL=%q Address=%q",
|
||||
srv.UDN, srv.FriendlyName, srv.CDSControlURL, srv.IconURL, srv.Address)
|
||||
}
|
||||
|
||||
// TestMediaServerFromDescription_WithoutCDS verifies that a description
|
||||
@@ -147,6 +158,12 @@ func TestMediaServerFromDescription_FlatServer(t *testing.T) {
|
||||
if srv.IconURL != wantIcon {
|
||||
t.Errorf("IconURL = %q, want %q", srv.IconURL, wantIcon)
|
||||
}
|
||||
|
||||
// Address must reflect the host:port of the CDS control URL.
|
||||
// URLBase is http://198.51.100.20:8200 and CDS controlURL is /ctl/ContentDir.
|
||||
if srv.Address != "198.51.100.20:8200" {
|
||||
t.Errorf("Address = %q, want %q", srv.Address, "198.51.100.20:8200")
|
||||
}
|
||||
}
|
||||
|
||||
// isAbsoluteURL returns true when s starts with "http://" or "https://".
|
||||
|
||||
Reference in New Issue
Block a user