sonos-sdk-callback-server 0.4.0

Internal HTTP callback server for sonos-sdk UPnP event reception
Documentation

callback-server

A generic UPnP callback server for receiving event notifications.

Overview

This is an internal implementation detail of sonos-sdk. It is published to crates.io as a transitive dependency but is not intended for direct use.

The callback-server crate provides a lightweight HTTP server for handling UPnP NOTIFY requests. It is completely generic and has no knowledge of device-specific protocols or implementations.

Purpose

This crate was extracted from device-specific implementations to:

  • Separate HTTP server concerns from business logic
  • Provide a reusable foundation for UPnP event handling
  • Keep device-specific crates focused on their domain
  • Enable easier testing and maintenance

Components

  • CallbackServer: HTTP server that receives UPnP NOTIFY requests on a local port
  • EventRouter: Routes incoming events based on subscription IDs
  • NotificationPayload: Generic data structure containing subscription ID and event XML

Usage

This crate is used by adding it as a path dependency in other workspace crates:

[dependencies]
callback-server = { path = "../callback-server" }

Device-specific crates should create adapter layers that wrap the generic types and add domain-specific context.

Adapter Pattern

The recommended pattern for using this crate is to create an adapter layer in the consuming crate:

  1. Create a channel for receiving generic NotificationPayload from callback-server
  2. Spawn an adapter task that receives notifications and adds device-specific context
  3. Maintain a mapping from subscription IDs to device-specific information
  4. Convert generic notifications into domain-specific events
  5. Send enriched events to your application's event processor

Example adapter structure:

pub struct DeviceCallbackServer {
    inner: callback_server::CallbackServer,
    subscription_map: Arc<RwLock<HashMap<String, DeviceContext>>>,
    device_event_sender: mpsc::UnboundedSender<DeviceEvent>,
}

This pattern keeps the callback-server generic while allowing device-specific crates to add their own context and types.

Architecture

The callback-server is designed to be a thin layer that:

  1. Binds to an available port in a specified range
  2. Validates incoming UPnP NOTIFY requests
  3. Extracts subscription IDs and event XML
  4. Routes events to registered handlers via channels

All device-specific logic (speaker IDs, service types, event parsing) should be handled by the consuming crate.

Dependencies

  • tokio: Async runtime
  • warp: HTTP server framework
  • bytes: Efficient byte buffer handling

Testing

Run tests from the crate directory:

cd callback-server
cargo test

Or from the workspace root:

cargo test -p callback-server