Skip to content

Commit 525e44a

Browse files
committed
docs: publish v0.1.1 guides and measured evidence
1 parent 15dfc03 commit 525e44a

18 files changed

Lines changed: 748 additions & 121 deletions

CHANGELOG.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,31 @@ All notable changes are documented here. OpenNet follows
55

66
## [Unreleased]
77

8+
## [0.1.1] - 2026-07-29
9+
10+
### Added
11+
12+
- Unified `opennet` CLI with `serve`, `send`, `ping`, and `benchmark` commands.
13+
- Acknowledgement retries using stable IDs and the ONP/1 `DUPLICATE` flag.
14+
- Bounded server duplicate suppression, connection limits, operational counters,
15+
receive queues, and connect timeouts.
16+
- Mutual TLS options and secure-by-default remote CLI behavior.
17+
- Generic Arduino `Stream` support for UART and Bluetooth Classic SPP transports.
18+
- Typed Arduino receive accessors, readable error names, and ACK lookup helper.
19+
- Hardened Linux/systemd installer bundle, checksums, and deterministic packages.
20+
- Native C++ protocol tests, malformed-control tests, and retry/disconnect tests.
21+
- Measured TCP/TLS/load benchmarks, protocol comparisons, tutorials, tips,
22+
transport boundaries, security guidance, and honest adoption analytics.
23+
24+
### Fixed
25+
26+
- Partial Arduino transport writes now complete the whole frame.
27+
- Python receivers now wake with an error when a peer disconnects.
28+
- Handler errors no longer expose exception details to remote peers.
29+
- Control-frame validation is consistent across Python and Arduino.
30+
31+
## [0.1.0] - 2026-07-29
32+
833
### Added
934

1035
- ONP/1 protocol specification and typed binary framing.
@@ -13,4 +38,6 @@ All notable changes are documented here. OpenNet follows
1338
- Arduino IDE, PlatformIO, and Python examples.
1439
- Cross-platform tests, CI, packaging, and contributor documentation.
1540

16-
[Unreleased]: https://github.com/devkyato/OpenNet/compare/v0.1.0...HEAD
41+
[Unreleased]: https://github.com/devkyato/OpenNet/compare/v0.1.1...HEAD
42+
[0.1.1]: https://github.com/devkyato/OpenNet/compare/v0.1.0...v0.1.1
43+
[0.1.0]: https://github.com/devkyato/OpenNet/releases/tag/v0.1.0

README.md

Lines changed: 97 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,78 +3,122 @@
33
![OpenNet cover](docs/assets/opennet-cover.png)
44

55
[![CI](https://github.com/devkyato/OpenNet/actions/workflows/ci.yml/badge.svg)](https://github.com/devkyato/OpenNet/actions/workflows/ci.yml)
6+
[![Release](https://img.shields.io/github/v/release/devkyato/OpenNet)](https://github.com/devkyato/OpenNet/releases)
67
[![License: MIT](https://img.shields.io/badge/license-MIT-4a638f.svg)](LICENSE)
78
[![Protocol](https://img.shields.io/badge/protocol-ONP%2F1-4a638f.svg)](docs/protocol.md)
89

9-
OpenNet is a small, typed messaging protocol and library for sending JSON, text,
10-
numbers, and arbitrary binary data between ESP32 devices, Raspberry Pi computers,
11-
and backend services over Wi-Fi or Ethernet.
10+
OpenNet is a dependency-free typed messaging protocol for direct communication
11+
between ESP32 devices, Raspberry Pi computers, and backend services. It sends
12+
JSON, text, signed integers, finite doubles, booleans, null, and arbitrary binary
13+
data over TCP/TLS or another reliable ordered stream.
14+
15+
Version 0.1.1 is an alpha release for real projects and learning. It has a
16+
documented wire format, bounded resource use, retries and duplicate suppression,
17+
native Arduino protocol tests, Python tests across 3.9–3.14, reproducible release
18+
packages, measured local performance, and security guidance. It does not claim
19+
that a radio or internet route exists when the underlying hardware/network is
20+
unavailable.
21+
22+
## Why OpenNet
23+
24+
- One small API and one frame format across ESP32 and Python.
25+
- Typed values without a JSON dependency for every scalar or binary payload.
26+
- Optional application ACKs, retry with stable message IDs, and bounded
27+
duplicate suppression.
28+
- TCP/TLS over Wi-Fi, Ethernet, or routed networks.
29+
- Generic Arduino `Stream` support for UART, USB serial, and Bluetooth Classic
30+
SPP on compatible ESP32 hardware.
31+
- Strict control frames, CRC-32 corruption detection, payload limits, bounded
32+
queues, connection limits, and partial transport-write handling.
33+
- CLI tools to serve, send, ping, and benchmark.
34+
- Arduino IDE, PlatformIO/VS Code, Python, Linux/systemd, and security tutorials.
35+
36+
## Install
37+
38+
Python wheel from the release page:
39+
40+
```sh
41+
python -m pip install \
42+
https://github.com/devkyato/OpenNet/releases/download/v0.1.1/opennet_protocol-0.1.1-py3-none-any.whl
43+
opennet --version
44+
```
45+
46+
For an isolated command:
1247

13-
The first release deliberately targets one dependable path: an ESP32 client and a
14-
Python 3.9+ client/server communicating over TCP. The wire format is documented and
15-
language-neutral, so additional transports and language bindings can be added
16-
without inventing incompatible message formats.
48+
```sh
49+
pipx install \
50+
https://github.com/devkyato/OpenNet/releases/download/v0.1.1/opennet_protocol-0.1.1-py3-none-any.whl
51+
```
1752

18-
## What it provides
53+
For Raspberry Pi/Linux, extract `OpenNet-linux-0.1.1.tar.gz` and run
54+
`sudo ./install.sh`. It creates a hardened, unprivileged systemd service with a
55+
loopback-only default. For Arduino IDE, install `OpenNet-0.1.1.zip` through
56+
**Sketch > Include Library > Add .ZIP Library**.
1957

20-
- A compact binary frame with versioning, message IDs, type information, CRC-32,
21-
and a 16 MiB defensive payload limit.
22-
- JSON, UTF-8 text, signed integers, IEEE-754 doubles, booleans, null, and raw bytes.
23-
- Async Python client/server APIs for Raspberry Pi and backend systems.
24-
- An Arduino-compatible ESP32 client with reconnect, heartbeat, and delivery ACKs.
25-
- Optional TLS at the transport layer.
26-
- Arduino IDE, PlatformIO, Python, and VS Code examples.
27-
- Protocol conformance tests and cross-platform CI.
58+
The Python distribution is installable with pip, but v0.1.1 is distributed from
59+
GitHub Releases rather than the public PyPI index.
2860

29-
## Five-minute start
61+
## Five-minute local test
3062

31-
Run the Python server:
63+
Terminal one:
3264

33-
```bash
34-
python -m pip install -e "./python[dev]"
35-
opennet-server --host 0.0.0.0 --port 8765
65+
```sh
66+
opennet serve --echo
3667
```
3768

38-
Install this repository as an Arduino library, open
39-
`File > Examples > OpenNet > TelemetryClient`, set the Wi-Fi credentials and
40-
server address, then upload it to an ESP32.
69+
Terminal two:
4170

42-
Python clients are equally small:
71+
```sh
72+
opennet ping --count 5
73+
opennet send sensor/temperature 24.7 --type float
74+
opennet send device/state '{"online":true}' --type json
75+
opennet benchmark --count 1000 --payload-size 64
76+
```
77+
78+
Python code is equally small:
4379

4480
```python
4581
import asyncio
4682
from opennet import OpenNetClient
4783

4884
async def main():
49-
async with OpenNetClient("192.168.1.50", 8765) as client:
50-
await client.send("temperature", {"celsius": 24.7})
85+
async with OpenNetClient("127.0.0.1") as client:
86+
message_id = await client.send(
87+
"lab/temperature", 24.7, retries=2
88+
)
89+
print("acknowledged", message_id)
5190

5291
asyncio.run(main())
5392
```
5493

55-
See the [getting-started guide](docs/getting-started.md), [protocol
56-
specification](docs/protocol.md), and [compatibility policy](docs/compatibility.md).
57-
58-
## Project status
59-
60-
OpenNet is pre-1.0 software. ONP/1 framing is stable for the v0.x series, while
61-
higher-level APIs may improve based on real hardware feedback. Do not represent
62-
untested boards or operating systems as supported; add a compatibility report when
63-
you test one.
64-
65-
## Contributing
66-
67-
Student contributions are welcome. Good first tasks are labeled in the issue
68-
tracker, and every feature should include tests or a reproducible hardware test
69-
report. Read [CONTRIBUTING.md](CONTRIBUTING.md) and the
70-
[code of conduct](CODE_OF_CONDUCT.md) before opening a pull request.
71-
72-
## Security
73-
74-
CRC detects accidental corruption; it is not encryption or authentication. Use TLS
75-
on untrusted networks. See [SECURITY.md](SECURITY.md) for the threat model and
76-
private reporting instructions.
77-
78-
## License
79-
80-
OpenNet is available under the [MIT License](LICENSE).
94+
The CLI defaults to loopback and refuses remote plaintext unless it is explicitly
95+
allowed for a trusted development network. Use verified TLS—and mutual TLS when
96+
device identity matters—outside isolated local testing.
97+
98+
## Evidence and design
99+
100+
- [Measured TCP/TLS and 20-client load results](docs/benchmarks.md)
101+
- [Comparison with raw TCP, MQTT, WebSocket, and HTTP](docs/comparison.md)
102+
- [Architecture, ACK retry, and defensive boundaries](docs/architecture.md)
103+
- [Actual GitHub adoption counters and analytics limits](docs/adoption-analytics.md)
104+
- [Transport support, including Bluetooth boundaries](docs/transports.md)
105+
106+
Measured loopback results are software baselines, not invented Wi-Fi or hardware
107+
claims. Hardware field reports are welcome through the
108+
[compatibility process](docs/compatibility.md).
109+
110+
## Learn and build
111+
112+
- [Tutorials](docs/tutorials.md)
113+
- [CLI reference](docs/cli.md)
114+
- [Linux/Raspberry Pi service guide](docs/linux-service.md)
115+
- [Getting started](docs/getting-started.md)
116+
- [Development tips](docs/tips.md)
117+
- [Security guide](docs/security.md)
118+
- [ONP/1 protocol specification](docs/protocol.md)
119+
- [Contributing](CONTRIBUTING.md)
120+
121+
Student contributions are welcome. Good changes include a reproducible test,
122+
clear documentation, or a complete compatibility report. OpenNet follows
123+
[Semantic Versioning](https://semver.org/) and is licensed under the
124+
[MIT License](LICENSE).

SECURITY.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,7 @@ coordinate disclosure after a fix is available.
2525
- Applications must authorize topics and validate payloads.
2626
- The 16 MiB frame limit reduces memory-exhaustion risk; deployments should choose
2727
a smaller application limit appropriate for their hardware.
28+
29+
The CLI defaults to loopback and requires an explicit flag for remote plaintext.
30+
Mutual TLS is available when deployments must authenticate client devices. See the
31+
[security guide](docs/security.md) for commands, limits, and deployment checklists.

docs/adoption-analytics.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Adoption analytics
2+
3+
OpenNet does not collect telemetry from library users. The only current adoption
4+
signals are aggregate GitHub repository and release counters.
5+
6+
Snapshot queried from the GitHub API on 2026-07-29:
7+
8+
| Signal | Actual value |
9+
|---|---:|
10+
| GitHub views in returned 14-day window | 0 |
11+
| Unique viewers in returned window | 0 |
12+
| Git clones in returned window | 1 |
13+
| Unique cloners in returned window | 1 |
14+
| Stars | 0 |
15+
| Forks | 0 |
16+
| Watchers/subscribers | 1 |
17+
| Open issues | 3 |
18+
| v0.1.0 release asset downloads | 0 |
19+
20+
```mermaid
21+
xychart-beta
22+
title "Current public adoption signals (2026-07-29 snapshot)"
23+
x-axis ["Unique clones", "Subscribers", "Stars", "Forks", "Downloads"]
24+
y-axis "Count" 0 --> 1
25+
bar [1, 1, 0, 0, 0]
26+
```
27+
28+
These values are a transparent early-project baseline, not evidence of a user
29+
population. GitHub traffic is a rolling window and may lag. Demographic data
30+
(age, location, school, occupation, or device ownership) is unavailable and
31+
should not be guessed. Future releases can report platform compatibility and
32+
opt-in survey results without adding tracking to the library.

docs/architecture.md

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,55 @@
11
# Architecture
22

3-
OpenNet separates the parts that must interoperate from platform-specific I/O.
4-
5-
```text
6-
Application values and topics
7-
|
8-
OpenNet API
9-
|
10-
ONP/1 frame codec <- language-neutral and tested with vectors
11-
|
12-
TCP or TLS byte stream <- reliable ordered transport
13-
|
14-
Wi-Fi / Ethernet / OS networking
3+
OpenNet separates ONP/1 framing from the byte stream carrying it. Both endpoints
4+
must provide a reliable, ordered stream; Wi-Fi itself is not required.
5+
6+
```mermaid
7+
flowchart LR
8+
A["Application values<br/>JSON · text · numbers · bytes"] --> B["OpenNet API"]
9+
B --> C["ONP/1 codec<br/>24-byte header · type · topic · CRC-32"]
10+
C --> D{"Reliable ordered stream"}
11+
D --> E["TCP/TLS<br/>Wi-Fi, Ethernet, internet"]
12+
D --> F["Arduino Stream<br/>UART, USB serial"]
13+
D --> G["Bluetooth Classic SPP<br/>supported ESP32 models"]
1514
```
1615

17-
The Python package provides the reference codec plus asyncio client and server. The
18-
Arduino library uses the ESP32 networking clients and a bounded receive state
19-
machine. Both implementations use the same 24-byte header.
20-
21-
## Reliability
22-
23-
TCP already retransmits lost packets and preserves order. ONP/1 acknowledgements
24-
add application-level evidence that a complete frame was parsed and accepted.
25-
Applications needing durable delivery must persist outgoing messages and decide
26-
how to handle duplicates after reconnecting; OpenNet does not pretend RAM queues
27-
survive power loss.
28-
29-
## Latency
16+
The Python package provides the reference codec and asyncio TCP/TLS client and
17+
server. The Arduino implementation accepts either a `Client` (`WiFiClient`,
18+
`WiFiClientSecure`) or an already-open Arduino `Stream` (`Serial`,
19+
`BluetoothSerial`). The frame bytes are identical across transports.
20+
21+
BLE GATT is packet-oriented, not a continuous byte stream. It needs an adapter
22+
that fragments and reassembles ONP frames; v0.1.1 does not claim direct BLE
23+
support. ESP32-C3/S3 boards also do not provide Bluetooth Classic SPP.
24+
25+
## Delivery and retry
26+
27+
```mermaid
28+
sequenceDiagram
29+
participant C as Client
30+
participant S as Server
31+
C->>S: DATA id=42, ACK_REQUIRED
32+
Note over C: ACK timeout
33+
C->>S: DATA id=42, ACK_REQUIRED + DUPLICATE
34+
Note over S: bounded recent-ID window
35+
S-->>C: ACK id=42, DUPLICATE
36+
Note over C: delivery confirmed
37+
```
3038

31-
OpenNet disables Nagle's algorithm where supported, uses a compact header, and
32-
does not require a broker round trip. Actual latency still depends on radio
33-
conditions, access-point load, power-saving mode, operating-system scheduling, and
34-
the application. Low-signal or disconnected areas cannot be made reliable by a
35-
software library alone.
39+
Python retries reuse the message ID, and the server suppresses duplicate handler
40+
execution within a configurable bounded window. An ACK proves that the peer
41+
parsed and accepted the frame; it does not make delivery durable across power
42+
loss. Durable applications must persist outbound messages and application state.
3643

37-
## Planned extensions
44+
## Defensive boundaries
3845

39-
- Authenticated session handshake and topic authorization helpers.
40-
- Optional service discovery for trusted LANs.
41-
- Persistent outbound queues.
42-
- TypeScript and portable C bindings.
46+
- Payload, topic, receive-queue, connection, and duplicate-window bounds prevent
47+
unbounded routine growth.
48+
- The CRC-32 catches accidental corruption before the application sees a value.
49+
- Strict type and control-frame validation rejects malformed inputs.
50+
- Remote CLI connections require TLS unless plaintext is explicitly enabled.
51+
- TLS provides confidentiality and server identity; mutual TLS can also identify
52+
clients.
4353

44-
Extensions will be proposed in issues and specified before implementation.
54+
See [Security](security.md) for the trust model and [Transports](transports.md)
55+
for supported connection types.

docs/benchmarks.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Measured performance
2+
3+
These are actual controlled measurements from the v0.1.1 worktree on
4+
2026-07-29. They are reproducible with `benchmarks/loopback.py`; they are not
5+
estimates and are not presented as Wi-Fi, Bluetooth, Raspberry Pi, or ESP32
6+
field results.
7+
8+
Environment: Windows 11 build 26200, AMD64 Family 25 Model 68, CPython 3.14.4,
9+
IPv4 loopback. Each row uses one warm-up message per client and then times a
10+
complete DATA-to-ACK round trip. TLS used a locally generated RSA-2048
11+
certificate with certificate validation enabled.
12+
13+
| Transport | Clients | Payload | Messages | p50 | p95 | Mean | Throughput |
14+
|---|---:|---:|---:|---:|---:|---:|---:|
15+
| TCP | 1 | 0 B | 1,000 | 0.164 ms | 0.279 ms | 0.195 ms | 5,069.6 msg/s |
16+
| TCP | 1 | 64 B | 1,000 | 0.156 ms | 0.264 ms | 0.178 ms | 5,566.1 msg/s |
17+
| TCP | 1 | 1 KiB | 1,000 | 0.159 ms | 0.265 ms | 0.186 ms | 5,346.0 msg/s |
18+
| TCP | 1 | 64 KiB | 1,000 | 0.224 ms | 0.329 ms | 0.245 ms | 4,045.8 msg/s |
19+
| TLS | 1 | 0 B | 1,000 | 0.231 ms | 0.351 ms | 0.262 ms | 3,578.0 msg/s |
20+
| TLS | 1 | 64 B | 1,000 | 0.226 ms | 0.340 ms | 0.254 ms | 3,843.5 msg/s |
21+
| TLS | 1 | 1 KiB | 1,000 | 0.236 ms | 0.357 ms | 0.265 ms | 3,712.9 msg/s |
22+
| TLS | 1 | 64 KiB | 1,000 | 0.361 ms | 0.572 ms | 0.434 ms | 2,270.7 msg/s |
23+
| TCP load | 20 | 64 B | 2,000 | 2.879 ms | 5.296 ms | 3.177 ms | 5,861.5 msg/s |
24+
25+
```mermaid
26+
xychart-beta
27+
title "Single-client p95 ACK latency on this host"
28+
x-axis ["0 B", "64 B", "1 KiB", "64 KiB"]
29+
y-axis "Milliseconds" 0 --> 0.6
30+
line "TCP" [0.279, 0.264, 0.265, 0.329]
31+
line "TLS" [0.351, 0.340, 0.357, 0.572]
32+
```
33+
34+
## Interpretation and limits
35+
36+
The run proves that the codec, client, server, ACK path, concurrency handling,
37+
and verified TLS path work together on this local device under the stated load.
38+
Loopback removes radio interference and network hops, so these numbers are a
39+
software baseline—not a prediction for a real deployment. Wi-Fi latency depends
40+
on signal, access-point congestion, power saving, and hardware. Bluetooth SPP
41+
depends on radio and serial baud/stack behavior.
42+
43+
For a field report, record the exact board, firmware, access point, distance/RSSI,
44+
payload mix, TLS mode, run duration, reconnects, failures, and p50/p95/p99. The
45+
[compatibility guide](compatibility.md) contains a report checklist.

0 commit comments

Comments
 (0)