Add comprehensive mDNS/Bonjour discovery with unified service and diagnostic tools

Features Added:
• mDNS/Bonjour discovery using hashicorp/mdns library
• Unified discovery service combining UPnP + mDNS + configuration
• Parallel discovery execution for optimal performance
• Comprehensive logging for both UPnP and mDNS discovery
• Network diagnostic tools for troubleshooting

New Discovery Methods:
• Configuration-based (fastest, most reliable)
• UPnP/SSDP discovery (widely supported, enhanced logging)
• mDNS/Bonjour discovery (Apple ecosystem friendly)

New Programs & Tools:
• cmd/example-mdns - Standalone mDNS discovery testing
• cmd/example-upnp - Isolated UPnP/SSDP discovery testing
• cmd/mdns-scanner - Network diagnostic tool for mDNS services

Enhanced Build System:
• make dev-mdns / dev-mdns-verbose (mDNS testing)
• make dev-upnp / dev-upnp-verbose (UPnP testing)
• make dev-scan-all (scan all network services)
• make dev-scan-soundtouch (scan for SoundTouch services)

Documentation:
• docs/DISCOVERY.md - Comprehensive discovery guide
• Updated README.md with new features and commands
• Full API documentation and troubleshooting guide

Technical Improvements:
• Detailed request/response logging for UPnP M-SEARCH
• Step-by-step mDNS service discovery tracking
• IP address resolution with IPv4/IPv6 handling
• Service name parsing and device info extraction
• Robust error handling and network diagnostics

Backward Compatibility:
• No breaking changes to existing APIs
• All existing tests pass
• CLI interface unchanged but enhanced
• Legacy UPnP-only service still available
This commit is contained in:
Tobias Gesellchen
2026-01-09 08:49:33 +01:00
parent ea2b6502b2
commit f4c71eaa53
18 changed files with 1812 additions and 28 deletions
+268
View File
@@ -0,0 +1,268 @@
# SoundTouch Device Discovery
This document describes the various methods available for discovering Bose SoundTouch devices on your network.
## Overview
The SoundTouch library supports multiple discovery methods to find devices on your network:
1. **Configuration-based discovery** - Manually configured devices in `.env` file
2. **UPnP/SSDP discovery** - Automatic discovery using Universal Plug and Play protocol
3. **mDNS/Bonjour discovery** - Automatic discovery using multicast DNS
## Discovery Methods
### 1. Configuration-based Discovery
You can manually configure known devices in your `.env` file:
```bash
PREFERRED_DEVICES=Living Room:192.168.1.100:8090,Kitchen:192.168.1.101:8090
```
This method is:
- ✅ Most reliable
- ✅ Fastest (no network scanning)
- ✅ Works in all network configurations
- ❌ Requires manual setup
### 2. UPnP/SSDP Discovery
Uses the Universal Plug and Play protocol to discover devices automatically. This is enabled by default.
Configuration:
```bash
UPNP_ENABLED=true # Default: true
```
This method is:
- ✅ Widely supported by SoundTouch devices
- ✅ Standard protocol
- ❌ May be blocked by some firewalls/networks
- ❌ Requires multicast support
### 3. mDNS/Bonjour Discovery
Uses multicast DNS to discover devices advertising the `_soundtouch._tcp` service.
Configuration:
```bash
MDNS_ENABLED=true # Default: true
```
This method is:
- ✅ Works well in home networks
- ✅ Apple/Bonjour compatible
- ❌ Depends on device advertising the service
- ❌ May not work in corporate networks
- ❌ Requires multicast support
## Configuration Options
### Environment Variables
```bash
# Discovery timeouts
DISCOVERY_TIMEOUT=5s # How long to wait for discovery
# Protocol enablement
UPNP_ENABLED=true # Enable UPnP/SSDP discovery
MDNS_ENABLED=true # Enable mDNS/Bonjour discovery
# Caching
CACHE_ENABLED=true # Enable discovery result caching
CACHE_TTL=30s # How long to cache results
# Manual device configuration
PREFERRED_DEVICES=Name:IP:Port,Name2:IP2:Port2
```
### .env File Example
```bash
# Discovery settings
DISCOVERY_TIMEOUT=10s
UPNP_ENABLED=true
MDNS_ENABLED=true
# Cache settings
CACHE_ENABLED=true
CACHE_TTL=60s
# Known devices (fastest method)
PREFERRED_DEVICES=Living Room:192.168.1.100:8090,Kitchen:192.168.1.101:8090,Bedroom:192.168.1.102
```
## Usage Examples
### CLI Discovery
```bash
# Discover all devices using all methods
./soundtouch-cli -discover
# Discover with custom timeout
./soundtouch-cli -discover -timeout 10s
# Show detailed device information
./soundtouch-cli -discover-all
```
### Programmatic Usage
```go
package main
import (
"context"
"fmt"
"time"
"github.com/user_account/bose-soundtouch/pkg/config"
"github.com/user_account/bose-soundtouch/pkg/discovery"
)
func main() {
// Load configuration
cfg, err := config.LoadFromEnv()
if err != nil {
cfg = config.DefaultConfig()
}
// Create unified discovery service
discoveryService := discovery.NewUnifiedDiscoveryService(cfg)
// Discover devices
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
devices, err := discoveryService.DiscoverDevices(ctx)
if err != nil {
fmt.Printf("Discovery failed: %v\n", err)
return
}
// Print results
for _, device := range devices {
fmt.Printf("Found: %s at %s:%d\n", device.Name, device.Host, device.Port)
}
}
```
### mDNS-only Discovery
```go
package main
import (
"context"
"time"
"github.com/user_account/bose-soundtouch/pkg/discovery"
)
func main() {
// Create mDNS-only discovery service
mdnsService := discovery.NewMDNSDiscoveryService(5 * time.Second)
ctx := context.Background()
devices, err := mdnsService.DiscoverDevices(ctx)
// Handle results...
}
```
## Troubleshooting
### No devices found
1. **Check network connectivity**: Ensure devices are on the same network
2. **Verify multicast support**: Some corporate networks block multicast traffic
3. **Try configuration-based discovery**: Add devices manually to `.env` file
4. **Increase timeout**: Some networks may be slow
5. **Check firewall settings**: Ensure UDP multicast is allowed
### Slow discovery
1. **Enable caching**: Set `CACHE_ENABLED=true`
2. **Use manual configuration**: Fastest method for known devices
3. **Disable unused protocols**: Turn off UPnP or mDNS if not needed
4. **Reduce timeout**: If you know devices respond quickly
### mDNS specific issues
mDNS discovery may fail if:
- Devices don't advertise `_soundtouch._tcp` service
- Network blocks multicast DNS (port 5353)
- IPv6 is misconfigured (common error: "no route to host")
### UPnP specific issues
UPnP discovery may fail if:
- Network blocks SSDP multicast (239.255.255.250:1900)
- Devices don't respond to M-SEARCH requests
- Corporate firewalls block UPnP traffic
## Discovery Flow
The unified discovery service uses this flow:
1. **Check cache** (if enabled and not expired)
2. **Load configured devices** from environment/config
3. **Start parallel discovery**:
- UPnP/SSDP discovery (if enabled)
- mDNS discovery (if enabled)
4. **Merge results** (removing duplicates by IP)
5. **Update cache** for future requests
6. **Return combined device list**
## Device Information
Each discovered device includes:
- `Name`: Device name (from config or auto-detected)
- `Host`: IP address
- `Port`: Port number (usually 8090)
- `Location`: Full device URL
- `LastSeen`: When the device was discovered
## Performance Considerations
- **Caching**: Enabled by default, reduces repeated network scanning
- **Parallel discovery**: UPnP and mDNS run simultaneously
- **Timeouts**: Balance between speed and completeness
- **Configuration priority**: Manual config devices are added first
## Security Notes
- Discovery traffic is sent over multicast (inherently insecure)
- No authentication is performed during discovery
- Device communication after discovery may require authentication
- Consider network segmentation for IoT devices
## API Reference
### Core Types
```go
type DiscoveredDevice struct {
Name string
Host string
Port int
Location string
LastSeen time.Time
}
```
### Services
- `UnifiedDiscoveryService`: Uses all available discovery methods
- `DiscoveryService`: UPnP/SSDP only (legacy)
- `MDNSDiscoveryService`: mDNS/Bonjour only
### Methods
- `DiscoverDevices(ctx)`: Discover all devices
- `DiscoverDevice(ctx, host)`: Find specific device
- `GetCachedDevices()`: Get cached results
- `ClearCache()`: Clear discovery cache