nx_ipp_codec.nx
buildroot/runtime/nx_ipp_codec.nx
about
nx_ipp_codec.nx -- sovereign IPP/1.1 wire codec (RFC 8010 encoding) -- R0 keystone of the
"better printer standard that works with ANY printer" arc.
WHY this is the foundation:
IPP (Internet Printing Protocol) / IPP Everywhere is the vendor-neutral standard every modern
printer speaks -- it is what AirPrint and CUPS "driverless" printing use under the hood. A Brother,
HP, Canon or Epson all answer the SAME Get-Printer-Attributes operation. So a correct IPP codec is
the one primitive that lets us manage every printer without a per-vendor driver. This file is the
pure byte layer: build a request, parse a response. Transport (TCP/HTTP) is R1; semantics/model
(printer-state -> human meaning, waste accounting) is R2+.
WHY it kills silent failure (the operator's core complaint):
An IPP response carries "printer-state" (idle/processing/stopped) and "printer-state-reasons" --
a 1setOf keyword list that enumerates EVERY reason the device is stuck (media-empty, media-jam,
marker-supply-low, cover-open, ...). Brother's own UI swallows these; this parser surfaces them.
The parser NEVER returns a silent success on bad bytes: every length is bounds-checked and a
malformed message yields the sealed NX_IPP_MALFORMED verdict (no_silent_failure by construction).
NEVER-BRICK (global rule #26): this is a pure codec. It performs NO syscalls, touches no hardware,
and cannot write firmware/NVRAM. Safe BY CONSTRUCTION -- the safest possible bottom rung.
Sovereign: pure integer/byte arithmetic, no imports, no 3rd-party. nx_cc -> nxasm, no gcc.
CITED EVIDENCE (fetched by the sovereign researcher over its own TLS-1.3, saved under
knowledge/fetched/):
ipp_rfc8010.raw RFC 8010 "IPP/1.1: Encoding and Transport" (Jan 2017)
- msg = version(2) op/status(2) request-id(4) *attr-group end-tag(0x03) data (sec 3.1.1)
- delimiter-tags: operation=0x01 job=0x02 end=0x03 printer=0x04 unsupported=0x05 (Table 2)
- value-tags: integer=0x21 boolean=0x22 enum=0x23 keyword=0x44 uri=0x45 charset=0x47
naturalLanguage=0x48 mimeMediaType=0x49 nameWithoutLanguage=0x42 (Tables 4-6)
- delimiters are 0x00-0x0f, value-tags are 0x10-0xff (sec 3.5.1 -- the walker's key rule)
- attr = value-tag(1) name-length(2) name value-length(2) value; lengths are SIGNED-SHORT,
big-endian; integer/enum = exactly 4 octets; boolean = 1 octet; 1setOf extra values use
name-length 0 "additional-value" (sec 3.1.2, 3.8, 3.9 Table 7)
ipp_rfc8011.raw RFC 8011 "IPP/1.1: Model and Semantics" (Jan 2017)
- operation-ids (Table): Print-Job=0x0002 Validate-Job=0x0004 Get-Jobs=0x000a
Get-Printer-Attributes=0x000b
- printer-state (sec 5.4.11): idle=3 processing=4 stopped=5
- printer-state-reasons keywords (sec 5.4.12): media-empty media-jam media-needed
marker-supply-low marker-supply-empty toner-low toner-empty cover-open door-open
dependencies 0 imports · 26 importers
diagram shows first 10 each side; +0 more imports, +16 more importers in the complete lists below.
imports: none
imported by: nx_doc_print.nxnx_img_print.nxnx_ipp_codec_test.nxnx_ipp_submit.nxnx_ipp_submit_test.nxnx_ipp_transport.nxnx_ipp_transport_test.nxnx_job_poll.nxnx_print_send.nxnx_print_validate.nxnx_printer_conform.nxnx_printer_conform_test.nxnx_printer_dump.nxnx_printer_exceed.nxnx_printer_health.nxnx_printer_health_test.nxnx_printer_query.nxnx_printer_security.nxnx_printer_security_test.nxnx_printer_waste.nxnx_printer_waste_test.nxnx_printers_page.nxnx_printers_render.nxnx_printers_render_test.nxnx_toner_liberate.nxnx_toner_liberate_test.nx
structs
| none |
consts
| 58 | const NX_IPP_OP_PRINT_JOB: i64 = 0x0002 |
| 59 | const NX_IPP_OP_VALIDATE_JOB: i64 = 0x0004 |
| 60 | const NX_IPP_OP_GET_JOBS: i64 = 0x000a |
| 61 | const NX_IPP_OP_GET_PRINTER_ATTRIBUTES: i64 = 0x000b |
| 62 | const NX_IPP_OP_CANCEL_JOB: i64 = 0x0008 |
| 63 | const NX_IPP_OP_GET_JOB_ATTRIBUTES: i64 = 0x0009 |
| 66 | const NX_IPP_STATUS_OK: i64 = 0x0000 // successful-ok |
| 69 | const NX_IPP_GRP_OPERATION: i64 = 0x01 |
| 70 | const NX_IPP_GRP_JOB: i64 = 0x02 |
| 71 | const NX_IPP_TAG_END: i64 = 0x03 |
| 72 | const NX_IPP_GRP_PRINTER: i64 = 0x04 |
| 73 | const NX_IPP_GRP_UNSUPPORTED: i64 = 0x05 |
| 76 | const NX_IPP_VT_INTEGER: i64 = 0x21 |
| 77 | const NX_IPP_VT_BOOLEAN: i64 = 0x22 |
| 78 | const NX_IPP_VT_ENUM: i64 = 0x23 |
| 79 | const NX_IPP_VT_KEYWORD: i64 = 0x44 |
| 80 | const NX_IPP_VT_URI: i64 = 0x45 |
| 81 | const NX_IPP_VT_CHARSET: i64 = 0x47 |
| 82 | const NX_IPP_VT_NATLANG: i64 = 0x48 |
| 83 | const NX_IPP_VT_MIMETYPE: i64 = 0x49 |
| 84 | const NX_IPP_VT_NAME: i64 = 0x42 // nameWithoutLanguage |
| 85 | const NX_IPP_VT_TEXT: i64 = 0x41 // textWithoutLanguage |
| 88 | const NX_IPP_PSTATE_IDLE: i64 = 3 |
| 89 | const NX_IPP_PSTATE_PROCESSING: i64 = 4 |
| 90 | const NX_IPP_PSTATE_STOPPED: i64 = 5 |
| 93 | const NX_IPP_OK: i64 = 1 |
| 94 | const NX_IPP_NOT_FOUND: i64 = 2 |
| 95 | const NX_IPP_MALFORMED: i64 = 3 |
| 96 | const NX_IPP_VERDICT_N: i64 = 4 |
functions
| 98 | func nx_ipp_verdict_is_valid(v: i64) -> i64 |
| 106 | func nx_ipp_strlen(s: *u8) -> i64 |
| 112 | func nx_ipp_put_u16(buf: *u8, off: i64, v: i64) -> i64 |
| 118 | func nx_ipp_put_u32(buf: *u8, off: i64, v: i64) -> i64 |
| 126 | func nx_ipp_get_u16(buf: *u8, off: i64) -> i64 |
| 132 | func nx_ipp_get_u32(buf: *u8, off: i64) -> i64 |
| 140 | func nx_ipp_memcpy(dst: *u8, doff: i64, src: *u8, n: i64) -> i64 |
| 150 | func nx_ipp_name_eq(buf: *u8, off: i64, s: *u8, n: i64) -> i64 |
| 168 | func nx_ipp_begin(buf: *u8, vmaj: i64, vmin: i64, op_or_status: i64, request_id: i64) -> i64 called by 17: mainmainbuild_brotherbuild_hpbuild_dupmisnx_obs_head+11 calls 2: nx_ipp_put_u16nx_ipp_put_u32 |
| 178 | func nx_ipp_group(buf: *u8, off: i64, group_tag: i64) -> i64 |
| 184 | func nx_ipp_attr(buf: *u8, off: i64, value_tag: i64, called by 16: mainbuild_brotherbuild_hpbuild_dupmisnx_obs_case1nx_obs_case2+10 calls 2: nx_ipp_put_u16nx_ipp_memcpy |
| 197 | func nx_ipp_attr_int(buf: *u8, off: i64, value_tag: i64, called by 15: mainbuild_brotherbuild_hpbuild_dupmisnx_obs_headnx_sec_adv2+9 calls 3: nx_ipp_put_u16nx_ipp_memcpynx_ipp_put_u32 |
| 210 | func nx_ipp_attr_bool(buf: *u8, off: i64, name: *u8, nlen: i64, bval: i64) -> i64 |
| 223 | func nx_ipp_attr_add(buf: *u8, off: i64, value_tag: i64, val: *u8, vlen: i64) -> i64 called by 11: build_brotherbuild_hpbuild_dupmisnx_obs_case2nx_obs_case3nx_obs_case4+5 calls 2: nx_ipp_put_u16nx_ipp_memcpy |
| 234 | func nx_ipp_end(buf: *u8, off: i64) -> i64 |
| 241 | func nx_ipp_ver_major(buf: *u8) -> i64 { return buf[0] as i64 } |
| 242 | func nx_ipp_ver_minor(buf: *u8) -> i64 { return buf[1] as i64 } |
| 243 | func nx_ipp_status(buf: *u8) -> i64 { return nx_ipp_get_u16(buf, 2) } // response status-code |
| 244 | func nx_ipp_op_id(buf: *u8) -> i64 { return nx_ipp_get_u16(buf, 2) } // request operation-id |
| 245 | func nx_ipp_request_id(buf: *u8) -> i64 { return nx_ipp_get_u32(buf, 4) } |
| 259 | func nx_ipp_find(buf: *u8, n: i64, target: *u8, |
| 319 | func nx_ipp_get_enum(buf: *u8, n: i64, target: *u8, scratch3: *i64, out_val: *i64) -> i64 |
| 336 | func nx_ipp_get_i32(buf: *u8, off: i64) -> i64 |
| 343 | func nx_ipp_attr_add_int(buf: *u8, off: i64, value_tag: i64, ival: i64) -> i64 |
| 355 | func nx_ipp_set_contains(body: *u8, n: i64, name: *u8, target: *u8) -> i64 |
| 405 | func nx_ipp_set_int_at(body: *u8, n: i64, name: *u8, idx: i64, out_val: *i64) -> i64 |