basic interactions work
This commit is contained in:
110
README.md
110
README.md
@@ -86,23 +86,122 @@ Or with any other CoAP client, e.g. [`coap-cli`](https://www.npmjs.com/package/c
|
||||
coap get "coap://localhost:5683/hello?name=Imran"
|
||||
```
|
||||
|
||||
## Streaming media
|
||||
|
||||
The server also streams two static files, loaded into memory at startup from
|
||||
`MEDIA_DIR` (default `media/`):
|
||||
|
||||
| Route | File | Format |
|
||||
|--------------|----------------------|-----------------------------------------------|
|
||||
| `GET /audio` | `media/audio.wav` | PCM WAV, mono, 16-bit, 16 kHz |
|
||||
| `GET /image` | `media/image.rgb565` | raw RGB565 little-endian, 320×240 (153,600 B) |
|
||||
|
||||
A file that is missing or in the wrong format is reported at startup and its
|
||||
route answers `4.04` with the reason; the rest of the server still runs.
|
||||
|
||||
Neither file fits in one datagram, so they go out with block-wise transfer
|
||||
(Block2, RFC 7959): the client asks for block 0, 1, 2 … and each reply carries
|
||||
1024 bytes. The server keeps no per-client state — every request names the
|
||||
block it wants, so it just slices the in-memory file. Every block carries an
|
||||
ETag (so the client can tell the file did not change mid-transfer), block 0
|
||||
carries Size2 (the total size), and a block past the end gets `4.02`.
|
||||
|
||||
### Make test media
|
||||
|
||||
```bash
|
||||
mkdir -p media
|
||||
```
|
||||
|
||||
```bash
|
||||
ffmpeg -f lavfi -i "sine=frequency=440:duration=10" -ac 1 -ar 16000 -c:a pcm_s16le media/audio.wav
|
||||
```
|
||||
|
||||
```bash
|
||||
ffmpeg -f lavfi -i "testsrc=size=320x240" -frames:v 1 -f rawvideo -pix_fmt rgb565le media/image.rgb565
|
||||
```
|
||||
|
||||
Or convert your own files:
|
||||
|
||||
```bash
|
||||
ffmpeg -i input.mp3 -ac 1 -ar 16000 -c:a pcm_s16le media/audio.wav
|
||||
```
|
||||
|
||||
```bash
|
||||
ffmpeg -i photo.png -vf scale=320:240 -f rawvideo -pix_fmt rgb565le media/image.rgb565
|
||||
```
|
||||
|
||||
`media/` is gitignored.
|
||||
|
||||
### Play it
|
||||
|
||||
`src/bin/stream.rs` downloads a file block by block and pipes it into `ffplay`
|
||||
(part of ffmpeg), which opens the window:
|
||||
|
||||
```bash
|
||||
cargo run --release --bin stream -- image
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo run --release --bin stream -- audio
|
||||
```
|
||||
|
||||
The image opens in a 320×240 window that stays until you close it; the audio
|
||||
plays with a waveform window. Closing the window stops the download.
|
||||
|
||||
| Flag | Effect |
|
||||
|------------------|----------------------------------------------------|
|
||||
| `--out FILE` | Also save the received bytes |
|
||||
| `--no-play` | Don't start ffplay (download only) |
|
||||
| `--timeout-ms N` | First retransmission timeout (default 2000, doubles, 4 retries) |
|
||||
|
||||
Measured on localhost:
|
||||
|
||||
| File | Blocks | Download, `--no-play` | Retransmits |
|
||||
|-------|--------|-----------------------|-------------|
|
||||
| image | 150 | under 1 s | 0 |
|
||||
| audio | 313 | 0.16 s | 0 |
|
||||
|
||||
Each block reply is 1050 B on the wire (26 B of CoAP header and options plus
|
||||
1024 B of data). When playing, blocks are written to ffplay as they arrive and
|
||||
a full pipe slows the download down, but ffplay buffers several seconds ahead:
|
||||
a 10 s clip finishes downloading after about 2.4 s while it plays.
|
||||
|
||||
To see one block byte by byte:
|
||||
|
||||
```bash
|
||||
./coap-inspect.py get /image --block 0
|
||||
```
|
||||
|
||||
To test streaming end to end (generates its own media and server):
|
||||
|
||||
```bash
|
||||
./test-stream.sh
|
||||
```
|
||||
|
||||
Limits: at most 65,536 blocks per file (about 67 MB, roughly 35 minutes of this
|
||||
audio), download only, and no encryption.
|
||||
|
||||
## Test
|
||||
|
||||
```bash
|
||||
cargo test
|
||||
```
|
||||
|
||||
Five unit tests cover the greeting, payload parsing (text + JSON) and query
|
||||
decoding.
|
||||
Unit tests cover the greeting, payload parsing (text + JSON), query decoding,
|
||||
block selection, WAV and RGB565 validation, and the Block2/ETag/Size2 reply.
|
||||
|
||||
## Layout
|
||||
|
||||
| Path | What it is |
|
||||
|---------------------|---------------------------------------------------------|
|
||||
| `src/main.rs` | The server: socket, read loop, route table, helpers. |
|
||||
| `src/lib.rs` | Shared CoAP client used by the CLI and the bridge. |
|
||||
| `src/lib.rs` | Shared CoAP client, including block-wise downloads. |
|
||||
| `src/bin/client.rs` | CLI client for smoke tests. |
|
||||
| `src/bin/bridge.rs` | HTTP -> CoAP proxy so a browser can reach the server. |
|
||||
| `src/bin/stream.rs` | Streams `/audio` or `/image` into an ffplay window. |
|
||||
| `media/` | Audio and image files the server streams (gitignored). |
|
||||
| `coap-inspect.py` | Sends one request and shows both packets byte by byte. |
|
||||
| `test-stream.sh` | End-to-end streaming test with its own server and media. |
|
||||
| `static/index.html` | CoAP reference page: routes, codes, copyable commands. |
|
||||
| `nodejs/` | The earlier Node.js version, kept for reference. |
|
||||
|
||||
@@ -113,6 +212,7 @@ decoding.
|
||||
| `COAP_PORT` | `5683` | server, client, bridge |
|
||||
| `COAP_HOST` | `0.0.0.0` | server, client, bridge |
|
||||
| `HTTP_PORT` | `8080` | bridge |
|
||||
| `MEDIA_DIR` | `media` | server |
|
||||
|
||||
## Design notes
|
||||
|
||||
@@ -136,8 +236,8 @@ decoding.
|
||||
|
||||
- **DTLS.** Plaintext CoAP has no encryption or authentication. Production uses
|
||||
`coaps://` on port 5684 — see `webrtc-dtls` or a gateway like `libcoap`.
|
||||
- **Block-wise transfer** (RFC 7959) for payloads past ~1 KB; `coap-lite` ships
|
||||
a `BlockHandler` for this.
|
||||
- **Block-wise upload** (Block1, RFC 7959). Downloads already use Block2 (see
|
||||
Streaming media); `coap-lite`'s `BlockHandler` can reassemble uploads.
|
||||
- **Observe** (RFC 7641) for server-pushed updates; `coap-lite` provides
|
||||
`Subject` and `create_notification`.
|
||||
- **Deduplication.** A CoAP server should track recent message IDs and replay
|
||||
|
||||
Reference in New Issue
Block a user