code wiki / _hdl_build / nx_printer_ctl_lib.nx
nx_printer_ctl_lib.nx
buildroot/runtime/_hdl_build/nx_printer_ctl_lib.nx
about
nx_printer_ctl_lib.nx -- sovereign 3D-printer / home-IoT control LIB (no main).
The reusable core behind nx_printer_ctl (CLI organ) + nx_printer_ctl_gate.
Composes the shipped Moonraker primitives (nx_moonraker_client request
builders + nx_moonraker_io arbitrary-IPv4 roundtrip) into a cap-gated,
JSON-emitting device-control surface that the sovereign edge reaches over
the LAN.
ARCHITECTURE (the operator's browser->edge->mTLS-home->printer design,
realized sovereignly): the sovereign edge (sites.elf :8443) already does
OPAQUE cap-token auth + reverse-proxy. This organ is the "home gateway"
leg -- BUT the NAS that runs the edge is ITSELF on the home LAN, so the
organ reaches the printer at <lan-ip>:7125 directly. The printer never
sees the WAN; only the cap-gated organ ever touches it => "zero external
exposure" holds BY CONSTRUCTION, no Node/nginx/WAN-mTLS-tunnel required.
NEVER-BRICK (CLAUDE rule 26, ABSOLUTE): every control verb maps to a FIXED
allowlisted Moonraker endpoint (info / emergency_stop / print pause|resume
|cancel). There is NO raw-G-code passthrough, so no path can ever carry a
firmware-flash / EEPROM-write G-code (M500/M502/etc.). emergency_stop is a
Klipper RUNTIME MCU halt (recovered by a soft FIRMWARE_RESTART, RAM-only) --
it writes NO persistent hardware state. The safe-endpoint allowlist is
proven mechanically by nx_printer_ctl_gate (a control path outside the
allowlist => gate RED).
license_tier: ORIGINAL No hw writes (Rule 26).
dependencies 4 imports · 2 importers
imports: nx_syscalls.nxnx_moonraker_client.nxnx_moonraker_io.nxnx_lan_scan.nx
imported by: nx_printer_ctl.nxnx_printer_ctl_gate.nx
structs
| none |
consts
| 32 | const PCTL_SCRATCH: i64 = 8192 |
| 33 | const PCTL_RESP: i64 = 16384 |
| 34 | const PCTL_OUT: i64 = 32768 |
| 37 | const PCTL_V_INFO: i64 = 1 |
| 38 | const PCTL_V_ESTOP: i64 = 2 |
| 39 | const PCTL_V_PAUSE: i64 = 3 |
| 40 | const PCTL_V_RESUME: i64 = 4 |
| 41 | const PCTL_V_CANCEL: i64 = 5 |
| 42 | const PCTL_V_CONTRACT: i64 = 6 |
| 43 | const PCTL_V_STATUS: i64 = 7 |
| 44 | const PCTL_V_READY: i64 = 8 |
| 45 | const PCTL_V_DISCOVER: i64 = 9 |
| 46 | const PCTL_V_SURVEY: i64 = 10 |
| 47 | const PCTL_V_MONITOR: i64 = 11 |
| 48 | const PCTL_V_FILES: i64 = 12 |
| 49 | const PCTL_V_PROGRESS: i64 = 13 |
| 50 | const PCTL_V_PRINTSTART: i64 = 14 |
| 51 | const PCTL_V_UPLOAD: i64 = 15 |
| 52 | const PCTL_V_BAD: i64 = 0 |
| 53 | const PCTL_TEMP_NONE: i64 = 0 - 32768 |
| 54 | const PCTL_SOCK_NONBLOCK: i64 = 2048 // SOCK_NONBLOCK |
| 55 | const PCTL_POLLOUT: i64 = 4 |
| 56 | const PCTL_POLLERR: i64 = 8 |
| 57 | const PCTL_POLLHUP: i64 = 16 |
| 60 | const PCTL_SURVEY_NPORTS: i64 = 4 |
functions
| 63 | func pctl_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 64 | func pctl_streq(a: *u8, b: *u8) -> i64 |
| 70 | func pctl_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { d[o] = s[i]; o = o + 1; i = i + 1 } return o } |
| 71 | func pctl_catn(d: *u8, o: i64, v: i64) -> i64 called by 14: pctl_build_hostpctl_emit_resultpctl_cat_num_or_nullpctl_emit_statuspctl_emit_readypctl_cat_ip+8 calls 1: sys_mmap |
| 83 | func pctl_cat_esc(d: *u8, o: i64, q: *u8, s: i64, e: i64) -> i64 called by 1: pctl_emit_result |
| 100 | func pctl_parse_ip(s: *u8) -> i64 |
| 138 | func pctl_parse_port(s: *u8) -> i64 called by 1: main |
| 155 | func pctl_build_host(ip: *u8, port: i64, host: *u8) -> i64 |
| 169 | func pctl_verb_id(v: *u8) -> i64 |
| 187 | func pctl_verb_is_get(id: i64) -> i64 |
| 196 | func pctl_verb_path(id: i64) -> *u8 |
| 209 | func pctl_verb_name(id: i64) -> *u8 called by 1: pctl_emit_result |
| 229 | func pctl_body_start(resp: *u8, n: i64) -> i64 |
| 242 | func pctl_call(id: i64, ipv4: i64, port: i64, |
| 263 | func pctl_emit_result(out: *u8, id: i64, host: *u8, status: i64, resp: *u8, n: i64) -> i64 |
| 290 | func pctl_find(body: *u8, n: i64, start: i64, needle: *u8) -> i64 |
| 309 | func pctl_parse_int_deg(body: *u8, off: i64, n: i64) -> i64 called by 1: pctl_temp_in |
| 347 | func pctl_temp_in(body: *u8, n: i64, objkey: *u8, field: *u8) -> i64 |
| 355 | func pctl_cat_num_or_null(d: *u8, o: i64, v: i64) -> i64 |
| 359 | func pctl_ready_flag(body: *u8, n: i64) -> i64 |
| 364 | func pctl_state_of(body: *u8, n: i64, rdy: i64) -> *u8 |
| 371 | func pctl_cat_netresult(d: *u8, o: i64, status: i64) -> i64 called by 5: pctl_emit_statuspctl_emit_readypctl_emit_progresspctl_printstartpctl_upload_send calls 1: pctl_cat |
| 377 | func pctl_emit_status(out: *u8, host: *u8, status: i64, resp: *u8, n: i64) -> i64 |
| 410 | func pctl_emit_ready(out: *u8, host: *u8, status: i64, resp: *u8, n: i64) -> i64 |
| 446 | func pctl_parse_prefix(s: *u8) -> i64 { return lscan_parse_prefix(s) } |
| 448 | func pctl_probe_host(ipv4: i64, port: i64, timeout_ms: i64) -> i64 calls 1: lscan_probe_host |
| 454 | func pctl_discover_scan(base24: i64, port: i64, timeout_ms: i64, out_ips: *i64, max: i64) -> i64 |
| 457 | func pctl_cat_ip(d: *u8, o: i64, ipv4: i64) -> i64 |
| 470 | func pctl_emit_discover(out: *u8, prefix: *u8, port: i64, ips: *i64, count: i64) -> i64 |
| 493 | func pctl_survey_port(pi: i64) -> i64 |
| 502 | func pctl_survey_scan(base24: i64, budget_per_port: i64, mask: *i64) -> i64 |
| 519 | func pctl_survey_kind(bits: i64) -> *u8 |
| 526 | func pctl_emit_survey(out: *u8, prefix: *u8, base24: i64, mask: *i64) -> i64 called by 2: mainpctl_build_monitor calls 5: pctl_catpctl_cat_ippctl_survey_kindpctl_catnpctl_survey_port |
| 566 | func pctl_ip_to_str(pip: i64, buf: *u8) -> i64 |
| 581 | func pctl_build_monitor(out: *u8, subnet: *u8, base24: i64) -> i64 called by 2: mainmain calls 12: sys_mmapsys_clock_gettime_realpctl_discover_scanpctl_survey_scanpctl_catpctl_catn+6 |
| 641 | func pctl_cat_jsonstr_after(out: *u8, o: i64, body: *u8, n: i64, anchor: *u8, keyq: *u8) -> i64 |
| 663 | func pctl_pct_after(body: *u8, n: i64, anchor: *u8, keyq: *u8) -> i64 |
| 691 | func pctl_emit_progress(out: *u8, host: *u8, status: i64, resp: *u8, n: i64) -> i64 called by 1: main calls 6: pctl_catpctl_catnpctl_body_startpctl_cat_jsonstr_afterpctl_pct_afterpctl_cat_netresult |
| 725 | func pctl_printstart(out: *u8, ipv4: i64, port: i64, host: *u8, hl: i64, fn: *u8, fnlen: i64) -> i64 called by 1: main calls 7: sys_mmapnx_mr_build_print_start_bodypctl_catnx_mr_post_ipv4nx_mr_parse_statuspctl_catn+1 |
| 754 | func pctl_build_upload_req(req: *u8, host: *u8, filename: *u8, gcode: *u8, gcode_len: i64) -> i64 |
| 789 | func pctl_upload_send(out: *u8, ipv4: i64, port: i64, host: *u8, filename: *u8, gcode: *u8, gcode_len: i64) -> i64 called by 1: main calls 10: sys_mmappctl_build_upload_reqnx_mr_tcp_connect_ipv4sys_writesys_readsys_close+4 |
| 822 | func pctl_emit_contract(out: *u8) -> i64 |