sonos-sdk-callback-server 0.2.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](https://crates.io/crates/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:

```toml
[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:

```rust
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:

```bash
cd callback-server
cargo test
```

Or from the workspace root:

```bash
cargo test -p callback-server
```