nx_iot_announce.nx
buildroot/runtime/nx_iot_announce.nx
about
nx_iot_announce.nx -- multi-vendor LAN smart-device discovery.
Roadmap: nxc2/docs/NISHI_IOT_HUB_ROADMAP.md Epoch 1 (DISCOVER).
First Epoch-1 primitive of the sovereign IoT hub. Listens on
UDP/6667 (Tuya v3.3 broadcast), UDP/38899 (WiZ JSON), and UDP/48899
(Magic Home / Flux LED). Captures every datagram and classifies
the sender by first-byte signature into a sealed vendor-family
enum.
What it does today:
- opens a UDP listener bound to INADDR_ANY:<port> with
SO_REUSEADDR + SO_BROADCAST + SO_RCVTIMEO
- sends one WiZ getPilot broadcast to 255.255.255.255:38899
- sends one Magic Home HF-A11ASSISTHREAD broadcast to
255.255.255.255:48899
- drains incoming datagrams until the wall-clock deadline
- classifies each by first-byte signature + source port
What it doesn't do yet:
- mDNS (RFC 6762/6763) -- deferred to v2 per roadmap
- per-family encrypted session -- that is the Epoch 2 primitives
(nx_iot_local_tuya_v33, nx_iot_local_magic_home, ...)
- Tuya local_key recovery -- that is the Epoch 3 primitive
(nx_iot_provision_softap) via factory-reset + SoftAP re-pair
genealogy_id: iot_hub_research/tuya_v33_lan + magic_home_protocol +
wiz_protocol + yeelight_protocol
license_tier: ORIGINAL
nx_capability_claims: (per docs/NISHI_INTELLIGENT_CAPABILITY_LAYER.md)
needs: [arena_alloc, syscall_socket, syscall_clock,
byte_arithmetic, pointer_arithmetic]
provides: [iot_family_classify, discovery_probe_build,
udp_announce_capture]
safety: [no_floating_point, bit_equal_reproducible]
verdict: [sealed_enum_5_family, sealed_enum_6_announce_verdict,
no_silent_failure]
license: ORIGINAL
kind: iot_runtime_primitive
dependencies 2 imports · 1 importers
imports: nx_syscalls_x86_64.nxnx_udp.nx
imported by: nx_iot_announce_test.nx
structs
| 140 | struct IotBeacon |
consts
| 87 | const NX_MAGIC_2048: i64 = 2048 |
| 95 | const NX_IOT_FAMILY_UNKNOWN: i64 = 0 |
| 96 | const NX_IOT_FAMILY_TUYA_V33: i64 = 1 |
| 97 | const NX_IOT_FAMILY_MAGIC_HOME: i64 = 2 |
| 98 | const NX_IOT_FAMILY_WIZ: i64 = 3 |
| 99 | const NX_IOT_FAMILY_YEELIGHT: i64 = 4 |
| 100 | const NX_IOT_FAMILY_N: i64 = 5 |
| 110 | const NX_IOT_ANN_VERDICT_UNKNOWN: i64 = 0 |
| 111 | const NX_IOT_ANN_VERDICT_OK: i64 = 1 |
| 112 | const NX_IOT_ANN_VERDICT_PARTIAL: i64 = 2 // some captured, cap hit |
| 113 | const NX_IOT_ANN_VERDICT_NO_DEVICES: i64 = 3 // none captured within timeout |
| 114 | const NX_IOT_ANN_VERDICT_SOCKET_FAIL: i64 = 4 |
| 115 | const NX_IOT_ANN_VERDICT_BIND_FAIL: i64 = 5 |
| 116 | const NX_IOT_ANN_VERDICT_N: i64 = 6 |
| 126 | const NX_IOT_SO_BROADCAST: i64 = 6 |
| 127 | const NX_IOT_SO_RCVTIMEO: i64 = 20 |
| 131 | const NX_IOT_PORT_TUYA_V33: i64 = 6667 |
| 132 | const NX_IOT_PORT_WIZ: i64 = 38899 |
| 133 | const NX_IOT_PORT_MAGIC_HOME: i64 = 48899 |
functions
| 102 | func nx_iot_family_is_valid(f: i64) -> i64 called by 1: main |
| 118 | func nx_iot_ann_verdict_is_valid(v: i64) -> i64 called by 1: main |
| 163 | func nx_iot_classify_beacon(buf: *u8, n: i64, src_port: i64) -> i64 |
| 212 | func _set_int_opt(fd: i64, level: i64, opt: i64, val: i64) -> i64 |
| 221 | func nx_iot_enable_broadcast(fd: i64) -> i64 |
| 225 | func nx_iot_enable_reuseaddr(fd: i64) -> i64 |
| 231 | func nx_iot_set_rcvtimeo_ms(fd: i64, ms: i64) -> i64 |
| 254 | func nx_iot_build_magic_home_discovery(buf: *u8) -> i64 |
| 279 | func nx_iot_build_wiz_discovery(buf: *u8) -> i64 |
| 318 | func nx_iot_send_wiz_discovery(fd: i64) -> i64 |
| 326 | func nx_iot_send_magic_home_discovery(fd: i64) -> i64 called by 1: nx_iot_announce_run calls 3: nx_udp_sockaddr_destnx_iot_build_magic_home_discoverynx_udp_send |
| 339 | func nx_iot_sockaddr_port(addr: *u8) -> i64 |
| 346 | func nx_iot_sockaddr_ip_be(addr: *u8) -> i64 |
| 362 | func nx_iot_announce_open(port: i64, timeout_ms: i64, |
| 392 | func nx_iot_announce_run(port: i64, timeout_ms: i64, |