diff --git a/cmd/example-mdns/main.go b/cmd/example-mdns/main.go index 818922e..e0faecc 100644 --- a/cmd/example-mdns/main.go +++ b/cmd/example-mdns/main.go @@ -15,6 +15,7 @@ import ( func main() { verbose := flag.Bool("v", false, "Enable verbose logging") timeout := flag.Duration("timeout", 5*time.Second, "Discovery timeout") + flag.Parse() // Configure logging @@ -38,11 +39,13 @@ func main() { ctx, cancel := context.WithTimeout(context.Background(), *timeout+2*time.Second) defer cancel() - fmt.Println("Searching for SoundTouch devices via mDNS...") - fmt.Println("This will search for devices advertising _soundtouch._tcp.local. service") + fmt.Println("Searching for SoundTouch devices via mDNS (Bonjour)...") + fmt.Printf("Timeout: %v\n", *timeout) + if *verbose { fmt.Println("Verbose logging enabled - watch for technical details...") } + fmt.Println() start := time.Now() @@ -64,6 +67,7 @@ func main() { fmt.Println("No SoundTouch devices found via mDNS") fmt.Println() fmt.Println("Technical Status:") + if *verbose { fmt.Println("āœ“ mDNS query was sent (check logs above for details)") fmt.Println("āœ“ No network errors during discovery process") @@ -71,12 +75,14 @@ func main() { } else { fmt.Println("Run with -v flag for detailed technical information") } + fmt.Println() fmt.Println("This could mean:") fmt.Println("- No SoundTouch devices on network") fmt.Println("- Devices don't support Bonjour/mDNS") fmt.Println("- Network blocks multicast traffic (common in corporate networks)") fmt.Println("- Devices use different service name than '_soundtouch._tcp.local.'") + return } diff --git a/cmd/example-upnp/main.go b/cmd/example-upnp/main.go index dbdc15e..69af271 100644 --- a/cmd/example-upnp/main.go +++ b/cmd/example-upnp/main.go @@ -16,6 +16,7 @@ import ( func main() { verbose := flag.Bool("v", false, "Enable verbose logging") timeout := flag.Duration("timeout", 5*time.Second, "Discovery timeout") + flag.Parse() // Configure logging @@ -38,9 +39,11 @@ func main() { fmt.Println("Searching for SoundTouch devices via UPnP/SSDP...") fmt.Println("This will send M-SEARCH requests to multicast address 239.255.255.250:1900") + if *verbose { fmt.Println("Verbose logging enabled - watch for technical details...") } + fmt.Println() start := time.Now() @@ -72,6 +75,7 @@ func main() { fmt.Println("No SoundTouch devices found via UPnP/SSDP") fmt.Println() fmt.Println("Technical Status:") + if *verbose { fmt.Println("āœ“ SSDP M-SEARCH request was sent (check logs above for details)") fmt.Println("āœ“ UDP multicast connection established") @@ -86,6 +90,7 @@ func main() { fmt.Println("- Network blocks multicast traffic (common in corporate networks)") fmt.Println("- Firewall blocks UDP port 1900") fmt.Println("- Devices are not advertising MediaRenderer service") + return } diff --git a/cmd/mdns-scanner/main.go b/cmd/mdns-scanner/main.go index 7d920bc..5fa9830 100644 --- a/cmd/mdns-scanner/main.go +++ b/cmd/mdns-scanner/main.go @@ -18,6 +18,7 @@ func main() { verbose := flag.Bool("v", false, "Enable verbose logging") timeout := flag.Duration("timeout", 10*time.Second, "Discovery timeout") service := flag.String("service", "_services._dns-sd._udp", "Service type to scan for (use _services._dns-sd._udp to find all)") + flag.Parse() // Configure logging @@ -58,7 +59,6 @@ func main() { Timeout: *timeout, Entries: entries, }) - if err != nil { if *verbose { log.Printf("mDNS query completed with error: %v", err) @@ -72,6 +72,7 @@ func main() { // Collect discovered services start := time.Now() + for { select { case <-ctx.Done(): @@ -139,10 +140,12 @@ done: if service.Port > 0 { fmt.Printf(" Port: %d\n", service.Port) } + if len(service.TxtRecords) > 0 { fmt.Printf(" TXT Records: %v\n", service.TxtRecords) } } + fmt.Println() } } @@ -205,6 +208,7 @@ func parseServiceEntry(entry *mdns.ServiceEntry, verbose bool) *ServiceInfo { if entry.AddrV4 != nil { service.IPv4 = entry.AddrV4.String() } + if entry.AddrV6 != nil { service.IPv6 = entry.AddrV6.String() } diff --git a/cmd/soundtouch-cli/main.go b/cmd/soundtouch-cli/main.go index 8520ffd..8ada22f 100644 --- a/cmd/soundtouch-cli/main.go +++ b/cmd/soundtouch-cli/main.go @@ -556,6 +556,7 @@ func handleDiscovery(showInfo bool, timeout time.Duration) error { } discoveryService := discovery.NewUnifiedDiscoveryService(cfg) + ctx, cancel := context.WithTimeout(context.Background(), cfg.DiscoveryTimeout+5*time.Second) defer cancel() @@ -657,6 +658,7 @@ func showDeviceInfoWithConfig(host string, port int, cfg *config.Config) error { if len(deviceInfo.NetworkInfo) > 0 { fmt.Printf(" Network Info:\n") + for _, net := range deviceInfo.NetworkInfo { fmt.Printf(" - Type: %s\n", net.Type) fmt.Printf(" MAC Address: %s\n", net.MacAddress) @@ -666,6 +668,7 @@ func showDeviceInfoWithConfig(host string, port int, cfg *config.Config) error { if len(deviceInfo.Components) > 0 { fmt.Printf(" Components:\n") + for _, component := range deviceInfo.Components { fmt.Printf(" - Category: %s\n", component.ComponentCategory) if component.SoftwareVersion != "" { @@ -1733,6 +1736,7 @@ func handleClockCommands(host string, port int, timeout time.Duration, getClockT fmt.Printf("Setting clock format to %s on %s:%d...\n", clockFormat, host, port) var format models.ClockFormat + switch clockFormat { case "12": format = models.ClockFormat12Hour @@ -1994,6 +1998,7 @@ func handleGetZone(client *client.Client) error { fmt.Printf(" Status: Active multiroom zone\n") fmt.Printf(" Total Devices: %d\n", zone.GetTotalDeviceCount()) fmt.Printf(" Zone Members:\n") + for i, member := range zone.Members { fmt.Printf(" %d. %s", i+1, member.DeviceID) if member.IP != "" { diff --git a/cmd/websocket-demo/main.go b/cmd/websocket-demo/main.go index 1226474..390ff63 100644 --- a/cmd/websocket-demo/main.go +++ b/cmd/websocket-demo/main.go @@ -72,6 +72,7 @@ func main() { var filters map[string]bool if *eventFilter != "" { filters = make(map[string]bool) + filterList := strings.Split(*eventFilter, ",") for _, f := range filterList { f = strings.TrimSpace(f) @@ -79,6 +80,7 @@ func main() { fmt.Printf("Invalid filter '%s'. Valid filters: nowPlaying, volume, connection, preset, zone, bass\n", f) os.Exit(1) } + filters[f] = true } } @@ -99,6 +101,7 @@ func main() { CacheEnabled: false, } discoveryService := discovery.NewUnifiedDiscoveryService(cfg) + devices, err := discoveryService.DiscoverDevices(ctx) if err != nil { fmt.Printf("Discovery failed: %v\n", err) @@ -139,10 +142,12 @@ func main() { fmt.Printf("Failed to connect to device: %v\n", err) return } + macAddress := "" if len(deviceInfo.NetworkInfo) > 0 { macAddress = deviceInfo.NetworkInfo[0].MacAddress } + fmt.Printf("Connected to: %s (Type: %s, MAC: %s)\n", deviceInfo.Name, deviceInfo.Type, macAddress) @@ -171,6 +176,7 @@ func main() { // Connect to WebSocket fmt.Println("Connecting to WebSocket...") + err = wsClient.ConnectWithConfig(wsConfig) if err != nil { fmt.Printf("Failed to connect to WebSocket: %v\n", err) @@ -247,6 +253,7 @@ func setupEventHandlers(wsClient *client.WebSocketClient, filters map[string]boo if np.Album != "" { fmt.Printf(" šŸ’æ %s\n", np.Album) } + fmt.Printf(" šŸ“» Source: %s\n", np.Source) fmt.Printf(" ā–¶ļø Status: %s\n", np.PlayStatus.String()) @@ -338,6 +345,7 @@ func setupEventHandlers(wsClient *client.WebSocketClient, filters map[string]boo if len(zone.Members) > 0 { fmt.Printf(" šŸ‘„ Members (%d):\n", len(zone.Members)) + for i, member := range zone.Members { fmt.Printf(" %d. %s (%s)\n", i+1, member.DeviceID, member.IP) } @@ -372,6 +380,7 @@ func setupEventHandlers(wsClient *client.WebSocketClient, filters map[string]boo wsClient.OnUnknownEvent(func(event *models.WebSocketEvent) { fmt.Printf("\nā“ Unknown Event [%s]:\n", event.DeviceID) types := event.GetEventTypes() + for _, eventType := range types { fmt.Printf(" šŸ“ Type: %s\n", eventType) } @@ -389,6 +398,7 @@ func getFilterKeys(filters map[string]bool) []string { for k := range filters { keys = append(keys, k) } + return keys } diff --git a/pkg/client/balance_test.go b/pkg/client/balance_test.go index 4ec0d83..b4cff9a 100644 --- a/pkg/client/balance_test.go +++ b/pkg/client/balance_test.go @@ -351,6 +351,7 @@ func TestClient_IncreaseBalance(t *testing.T) { w.WriteHeader(http.StatusOK) } })) + defer server.Close() config := &Config{ @@ -438,6 +439,7 @@ func TestClient_DecreaseBalance(t *testing.T) { w.WriteHeader(http.StatusOK) } })) + defer server.Close() config := &Config{ diff --git a/pkg/client/bass_integration_test.go b/pkg/client/bass_integration_test.go index 0669fa3..9b0466c 100644 --- a/pkg/client/bass_integration_test.go +++ b/pkg/client/bass_integration_test.go @@ -366,6 +366,7 @@ func BenchmarkClient_Bass_Integration(b *testing.B) { b.Run("GetBass", func(b *testing.B) { b.ResetTimer() + for i := 0; i < b.N; i++ { _, err := client.GetBass() if err != nil { @@ -377,6 +378,7 @@ func BenchmarkClient_Bass_Integration(b *testing.B) { b.Run("SetBass", func(b *testing.B) { bassLevels := []int{-3, 0, 3, -1, 1} // Cycle through different levels b.ResetTimer() + for i := 0; i < b.N; i++ { level := bassLevels[i%len(bassLevels)] err := client.SetBass(level) diff --git a/pkg/client/client.go b/pkg/client/client.go index faa65a6..73aa7e4 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -248,6 +248,7 @@ func (c *Client) VolumeDown() error { // SelectPreset sends a preset key command (1-6) func (c *Client) SelectPreset(presetNumber int) error { var keyValue string + switch presetNumber { case 1: keyValue = models.KeyPreset1 @@ -648,6 +649,7 @@ func (c *Client) get(endpoint string, result interface{}) error { if err != nil { return fmt.Errorf("failed to execute request: %w", err) } + defer func() { if closeErr := resp.Body.Close(); closeErr != nil { // Log the error but don't override the main error @@ -704,6 +706,7 @@ func (c *Client) post(endpoint string, payload, result interface{}) error { if err != nil { return fmt.Errorf("failed to execute request: %w", err) } + defer func() { if closeErr := resp.Body.Close(); closeErr != nil { // Log the error but don't override the main error diff --git a/pkg/client/websocket.go b/pkg/client/websocket.go index 684c7a4..58e3a2a 100644 --- a/pkg/client/websocket.go +++ b/pkg/client/websocket.go @@ -362,6 +362,7 @@ func (ws *WebSocketClient) handleEvent(event *models.WebSocketEvent) { for _, eventType := range eventTypes { hasKnownEvent = true + switch eventType { case models.EventTypeNowPlaying: if handlers.OnNowPlaying != nil && event.NowPlayingUpdated != nil {