Phase 4 of the docs portion of the rfc-5737-cleanup. Replaces all 192.168.1.x example IPs in tracked .md / .txt files with the equivalent last-octet under 192.0.2.x. 192.168.1.x is RFC-1918 private space and routes on real networks, which leaves readers guessing whether a documented IP is a placeholder or a documented LAN. 192.0.2.0/24 is reserved by RFC 5737 exclusively for documentation — readers know on sight that they're examples. 58 files touched, 551 line pairs. Includes .github issue/PR templates, all docs/ references, example READMEs, and one script doc. No code changes, no test changes; test files still carry the 192.168.1.x placeholder pending Phase 2 in _/RFC-5737-cleanup/assessment.md. Also fixed a small fallout in docs/analysis/ANONYMIZATION-SUMMARY.md where the explanatory sentence "a reader can't tell whether 192.168.1.10 is a placeholder or a documented LAN address" had itself been swept by the regex (inverting the point); restored the literal example and noted the sweep progress inline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
10 KiB
ZeroConf Analysis - Spotify Connect Integration for Bose SoundTouch
Overview
This document provides a comprehensive analysis of the Spotify Connect ZeroConf protocol as implemented by Bose SoundTouch speakers. ZeroConf enables seamless integration between Spotify clients and SoundTouch hardware without requiring manual configuration.
What is ZeroConf in This Context?
ZeroConf (Zero Configuration) in the Bose SoundTouch ecosystem is a Spotify Connect integration protocol that allows Spotify clients (mobile apps, desktop applications) to discover and control SoundTouch speakers automatically. The speakers expose an HTTP API on port 8200 that implements Spotify's official ZeroConf specification.
Network Discovery
mDNS/Bonjour Advertisement
SoundTouch speakers advertise themselves on the local network using:
- Service Type:
_spotify-connect._tcp - Port: 8200
- TXT Record:
CPath=/zc(points to the ZeroConf endpoint)
This allows Spotify applications to automatically discover available speakers without manual configuration.
Endpoint Structure
http://[SPEAKER_IP]:8200/zc?action=[ACTION]&[PARAMETERS]
Example: http://192.0.2.100:8200/zc?action=getInfo
The getInfo Action
Purpose
The getInfo action retrieves comprehensive device information and current status. This is the most commonly used ZeroConf action for:
- Device discovery and identification
- Checking Spotify authentication status
- Retrieving device capabilities
- Monitoring multiroom configurations
Request Format
GET http://[SPEAKER_IP]:8200/zc?action=getInfo&version=2.10.0
The version parameter is optional but recommended for compatibility.
Response Properties
Mandatory Fields (Present in All Responses)
| Property | Type | Description |
|---|---|---|
status |
Integer | Operation result code (101 = success) |
statusString |
String | Human-readable status description |
spotifyError |
Integer | Last Spotify SDK error code (0 = no error) |
responseSource |
String | Entity identifier (e.g., "Bose") |
Device Information Fields
| Property | Required | Type | Description |
|---|---|---|---|
version |
Yes | String | ZeroConf API version (e.g., "2.10.0") |
deviceID |
Yes | String | Unique device identifier (MAC-based) |
publicKey |
Yes | String | Device's public key for secure communication |
remoteName |
Yes | String | User-friendly device name shown in Spotify |
deviceType |
No | String | Device category (e.g., "SPEAKER") |
brandDisplayName |
Yes | String | Brand name displayed in Spotify apps |
modelDisplayName |
No | String | Model name for user display |
libraryVersion |
Yes | String | Spotify Connect library version |
resolverVersion |
Yes | String | DNS resolution version |
groupStatus |
Yes | String | Multiroom status: "NONE", "GROUP", or "SLAVE" |
tokenType |
Yes | String | Authentication token type ("accesstoken") |
clientID |
Yes | String | Spotify client identifier |
productID |
Yes | Integer | Spotify product identifier |
scope |
Yes | String | Permission scope (typically "streaming") |
availability |
Yes | String | Device availability status |
Status Fields
| Property | Required | Type | Description |
|---|---|---|---|
activeUser |
No | String | Currently logged-in Spotify username (if any) |
Advanced Fields (Optional)
| Property | Type | Description |
|---|---|---|
aliases |
Array | Virtual devices for multiroom zones |
supported_drm_media_formats |
Array | Supported audio formats with DRM capabilities |
supported_capabilities |
Integer | Bitmasked device capabilities |
Example Response
{
"status": 101,
"statusString": "OK",
"spotifyError": 0,
"responseSource": "Bose",
"version": "2.10.0",
"deviceID": "0007F537F5ED",
"deviceType": "SPEAKER",
"remoteName": "Living Room Speaker",
"publicKey": "BgIwVfz9ZXQG...",
"brandDisplayName": "Bose",
"modelDisplayName": "SoundTouch 30",
"libraryVersion": "master-v3.15.1-g7890abcd",
"resolverVersion": "1",
"groupStatus": "NONE",
"tokenType": "accesstoken",
"clientID": "65b708073fc0480ea92a077233ca87bd",
"productID": 0,
"scope": "streaming",
"availability": "",
"activeUser": "spotify_username",
"supported_drm_media_formats": [
{"drm": 0, "formats": 35},
{"drm": 1, "formats": 35},
{"drm": 3, "formats": 1168}
],
"supported_capabilities": 1
}
Key Properties Analysis
Critical Status Indicators
-
activeUser: Most important field for determining if Spotify is active- Present and non-empty: Spotify is authenticated and ready
- Empty or missing: No active Spotify session
-
remoteName: The display name users see in Spotify Connect device lists- Should be descriptive and user-friendly
- Can contain UTF-8 characters and special symbols
Device Identification
-
deviceID: Unique identifier for targeting specific speakers- Typically derived from MAC address
- Used for device-specific API calls
-
groupStatus: Critical for multiroom functionality"NONE": Standalone device"GROUP": Multiroom master/coordinator"SLAVE": Member of a multiroom group
Display Properties
brandDisplayNameandmodelDisplayName: Shown in Spotify client UIs- Should be marketing-appropriate names
- Support UTF-8 for international markets
Practical Usage Examples
1. Status Checking
# Check if Spotify is active
curl -s "http://192.0.2.100:8200/zc?action=getInfo" | \
grep -o '"activeUser" *: *"[^"]*"' | \
sed 's/"activeUser" *: *"//;s/"$//'
2. Device Discovery
# Get device name and ID
info=$(curl -s "http://192.0.2.100:8200/zc?action=getInfo")
device_name=$(echo "$info" | grep -o '"remoteName" *: *"[^"]*"' | sed 's/"remoteName" *: *"//;s/"$//')
device_id=$(echo "$info" | grep -o '"deviceID" *: *"[^"]*"' | sed 's/"deviceID" *: *"//;s/"$//')
3. Multiroom Detection
# Check multiroom status
group_status=$(curl -s "http://192.0.2.100:8200/zc?action=getInfo" | \
grep -o '"groupStatus" *: *"[^"]*"' | \
sed 's/"groupStatus" *: *"//;s/"$//')
Authentication Flow
The ZeroConf API supports the addUser action for Spotify authentication:
curl -X POST "http://192.0.2.100:8200/zc" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "action=addUser&userName=${SPOTIFY_USER}&blob=${ACCESS_TOKEN}&clientKey=&tokenType=accesstoken"
Token Requirements
- Access Token: Valid Spotify OAuth access token
- Username: Spotify username associated with the token
- Token Type: Always "accesstoken" for current implementations
- Client Key: Empty string for current protocol version
Token Lifecycle
- Tokens expire after 1 hour (3600 seconds)
- Speakers must be re-primed after reboot
- Use
getInfoto verify successful authentication viaactiveUserfield
Security Considerations
Communication Security
- Protocol: HTTP (plain text) is standard, HTTPS supported but optional
- Network Scope: Local network only (port 8200 typically not exposed externally)
- Authentication: Token-based, no permanent credentials stored
Best Practices
-
Token Management:
- Never store long-lived tokens on devices
- Implement token refresh mechanisms
- Use centralized token servers when possible
-
Network Security:
- Ensure port 8200 is not accessible from external networks
- Consider HTTPS for enhanced security
- Implement proper firewall rules
-
Error Handling:
- Always check
statusandspotifyErrorfields - Implement retry mechanisms for network failures
- Log authentication failures for debugging
- Always check
Integration Patterns
Boot-time Automation
See spotify-boot-primer.sh for a complete example of:
- Waiting for ZeroConf endpoint availability
- Checking current authentication status
- Fetching fresh tokens from a management server
- Automatically priming speakers at startup
Manual Priming
See spotify-prime-speaker.sh for standalone token injection:
- Validate access tokens against Spotify API
- Extract username from token metadata
- Prime individual speakers
- Verify successful authentication
Monitoring and Health Checks
#!/bin/bash
# Health check script
SPEAKER_IP="192.0.2.100"
info=$(curl -sf --max-time 5 "http://${SPEAKER_IP}:8200/zc?action=getInfo" 2>/dev/null)
if [ $? -eq 0 ]; then
active_user=$(echo "$info" | grep -o '"activeUser" *: *"[^"]*"' | sed 's/"activeUser" *: *"//;s/"$//')
if [ -n "$active_user" ]; then
echo "✅ Spotify active (user: $active_user)"
else
echo "⚠️ Speaker reachable but Spotify not active"
fi
else
echo "❌ Speaker unreachable"
fi
Troubleshooting
Common Issues
-
Port 8200 Unreachable
- Check network connectivity
- Verify speaker is powered on
- Confirm IP address is correct
-
Empty
activeUserAfter Authentication- Wait 2-5 seconds after
addUserrequest - Verify access token is valid and not expired
- Check
spotifyErrorfield for SDK errors
- Wait 2-5 seconds after
-
Authentication Failures
- Ensure token has correct scopes
- Verify username matches token owner
- Check token expiration time
Diagnostic Commands
# Test basic connectivity
curl -sf --max-time 5 "http://192.0.2.100:8200/zc?action=getInfo"
# Check detailed response
curl -s "http://192.0.2.100:8200/zc?action=getInfo" | jq .
# Monitor authentication status
while true; do
active=$(curl -s "http://192.0.2.100:8200/zc?action=getInfo" | \
grep -o '"activeUser" *: *"[^"]*"' | sed 's/"activeUser" *: *"//;s/"$//')
echo "$(date): activeUser = '$active'"
sleep 10
done
References
- Spotify ZeroConf API Documentation
- Bose SoundTouch Toolkit
- Scripts in this directory:
spotify-boot-primer.sh: Automated boot-time primingspotify-prime-speaker.sh: Manual speaker primingspotify-primer.conf.example: Configuration template
This analysis is based on Spotify's official ZeroConf specification and practical implementation experience with Bose SoundTouch speakers.