tibet-iot
IoT Transport Layer for TIBET — UDP transport, LAN discovery, and mesh relay.
The missing wire layer. tibet-ping defines the protocol, tibet-iot sends it over the network.
How It Fits Together
tibet-core tibet-ping tibet-iot
(provenance) (protocol) (transport)
Token, Chain ───► PingPacket ───► UDP, multicast
Store, HMAC Airlock, Trust LAN discovery
NetworkBridge Vouching, Beacon Mesh relay
pip install pip install pip install
tibet-core tibet-ping tibet-iot
- tibet-core stores every action as an immutable, verifiable token
- tibet-ping defines the protocol — packets, trust zones, vouching, beacons
- tibet-iot sends them over the wire — UDP transport, multicast discovery, mesh relay (this package)
tibet-iot wraps tibet-ping (sync) with async transport. First async package in the TIBET ecosystem.
Install
pip install tibet-iot
Optional msgpack for compact wire format:
pip install tibet-iot[msgpack]
Quick Start
import asyncio
from tibet_iot import IoTNode, TransportConfig
async def main():
node = IoTNode("jis:home:hub", config=TransportConfig(bind_port=7150))
node.set_trust("jis:home:sensor", 0.9)
await node.start()
# Send a real ping over UDP
response = await node.send_ping(
target="jis:home:sensor",
addr=("192.168.1.42", 7150),
intent="temperature.read",
purpose="Check room temperature",
)
if response:
print(f"{response.decision} — zone: {response.airlock_zone}")
await node.stop()
asyncio.run(main())
CLI
# Listen for incoming pings
tibet-iot listen --did jis:home:hub
# Send a ping to a device
tibet-iot send jis:home:sensor 192.168.1.42:7150 temperature.read --my-did jis:home:hub
# Discover devices on LAN (multicast)
tibet-iot discover
# Demo mode (starts two nodes, pings between them)
tibet-iot demo
Architecture
IoTNode (async, this package)
├── PingNode (sync, tibet-ping) — protocol layer
│ ├── Airlock — trust-gated access (GROEN/GEEL/ROOD)
│ ├── NonceTracker — replay protection
│ └── TrustStore — per-DID trust scores
├── UDPTransport — asyncio DatagramProtocol
├── PacketCodec — wire framing (8-byte header + JSON/msgpack)
├── PeerTracker — connection state, stale detection
├── NetworkDiscovery — LAN multicast beacons
└── MeshRelay — multi-hop forwarding with loop detection
IoTNode uses composition, not inheritance. PingNode handles protocol logic synchronously; IoTNode handles I/O asynchronously.
Wire Format
Offset Size Field
0 2 Magic: 0x54 0x50 ("TP")
2 1 Version: 0x01
3 1 Flags: bit 0 = is_response, bit 1 = msgpack
4 4 Payload length (uint32, big-endian)
8 N Payload (JSON or msgpack)
Network
| Port | Purpose |
|---|---|
| 7150/udp | Main transport |
| 7151/udp | Discovery multicast |
| 224.0.71.50 | Multicast group (TTL 2, LAN only) |
Background Tasks
IoTNode runs three background loops:
| Task | Interval | Purpose |
|---|---|---|
| Heartbeat | 30s | Announce presence to known peers |
| Discovery | 60s | Multicast beacon for LAN discovery |
| Peer cleanup | 45s | Prune stale peers (>120s inactive) |
Mesh Relay
Multi-hop forwarding for devices not directly reachable:
# Packet with routing_mode=MESH gets relayed
packet = sensor.ping(
target="jis:remote:device",
intent="data.sync",
routing_mode=RoutingMode.MESH,
)
# IoTNode automatically:
# 1. Checks if target is a known peer → forward directly
# 2. If not → broadcast to all known peers
# 3. Loop detection via seen-cache (OrderedDict)
# 4. Max 10 hops, then drop
Recording Provenance
Connect network events to tibet-core audit trail:
from tibet_core import Provider, NetworkBridge
tibet = Provider(actor="jis:home:hub")
bridge = NetworkBridge(tibet)
# Every network event becomes a verifiable token
bridge.record_ping(packet, response)
bridge.record_discovery("jis:new:sensor", ("192.168.1.50", 7150), "accepted")
bridge.record_heartbeat("jis:sensor:temp1", addr=("192.168.1.50", 7150))
bridge.record_trust_change("jis:sensor:temp1", 0.5, 0.9, "Vouched by admin")
# Full audit chain of all network activity
for token in tibet.find(action="discovery"):
print(f"{token.timestamp}: {token.erachter}")
Real-World Example
Tested on a real network: laptop (Kali) → DL360 server over LAN.
# On the hub (DL360, 192.168.4.76):
python3 listen_hub.py
# Hub listening on 0.0.0.0:7150 as jis:dl360:hub
# From the laptop:
tibet-iot send jis:dl360:hub 192.168.4.76:7150 hello.world --my-did jis:laptop:jasper
# GROEN — trust: 0.95 — RTT: 0.383ms
Trust Zones
Inherited from tibet-ping. No configuration needed — just set trust scores.
| Zone | Score | Behavior |
|---|---|---|
| GROEN | >= 0.7 | Auto-accept, response sent |
| GEEL | 0.3 - 0.7 | Pending review |
| ROOD | < 0.3 | Silent drop — no response at all |
License
MIT — Humotica
Links
- tibet-core — Provenance engine (tokens, chains, stores, NetworkBridge)
- tibet-ping — Protocol layer (packets, trust, airlock, vouching)
- tibet-overlay — Encrypted mesh networking (WireGuard + noise)
- Humotica
- IETF TIBET Draft
- IETF JIS Draft
Metadata
Release files for tibet-iot 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tibet_iot-0.1.1.tar.gz | 12.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tibet_iot-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.9 kB
Release files / tibet_iot-0.1.1.tar.gz
| Download URL | tibet_iot-0.1.1.tar.gz |
|---|---|
| Size | 12.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f2efea3e3bc667e895dc4db7c4ba4908bc4fddd0ef32d52ce1e4a42c4490591a
|
|
BLAKE2b-256 checksum How to use checksums |
c1613ac30bf6e2af727c256a60504f3fc9a8bc63c3360ce85a513f9d25e5450f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / tibet_iot-0.1.1-py3-none-any.whl
| Download URL | tibet_iot-0.1.1-py3-none-any.whl |
|---|---|
| Size | 16.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dc9e13aaccfe5e760e2bd18b75052dee3018627048bddb55e84bd4191c7d567c
|
|
BLAKE2b-256 checksum How to use checksums |
577e665ceeb12c8a89e2810307231fed4c2d2b2740c3c843aa1aa1e9b95d92a2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|