nx_iot_sc_emit_a64.nx source
↩ module page · 114 lines · 5404 B
1// nx_iot_sc_emit_a64.nx -- SOVEREIGN emitter: NishiLang -> aarch64 .s for the SmartConfig broadcaster
2// that runs ON the GL.iNet router (the 2.4GHz AP). The "send-loop shortcut": the complex ENCODING
3// runs here on x86 (reusing the GATED nx_sc_encode), and only the small SEND-LOOP is emitted as ARM
4// asm to be assembled by nxasm_arm64_main + deployed via routerfix. No full aarch64 compiler needed.
5//
6// Emits (to stdout): socket(AF_INET,DGRAM) -> SO_BROADCAST -> sockaddr (subnet-directed broadcast
7// 192.168.10.255:7001 -> routes out the IoT bridge onto the 2.4GHz air) -> an OUTER repeat loop over
8// the U8 length sequence, each length sent as a UDP packet via a `snd` subroutine (sendto + 5ms
9// nanosleep). Uses ONLY assembler-supported A64 ops (movz/movk/str/add/sub/mov/cmp/b.lt/bl/ret/svc).
10// aarch64 syscalls (asm-generic): socket=198 setsockopt=208 sendto=206 nanosleep=101 exit=93.
11// NEVER-BRICK #26: emits reversible Wi-Fi creds only. license_tier: ORIGINAL
12import "nx_iot_smartconfig.nx"
13import "nx_syscalls_x86_64.nx"
14const K_MAGIC_5000000: i64 = 5000000
15
16func e_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
17func e_nl() -> i64 { let b: *u8 = sys_mmap(1); b[0] = 10 as u8; sys_write(1, b, 1); return 0 }
18func e_n(v: i64) -> i64 {
19 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 }
20 let d: *u8 = sys_mmap(24); var m: i64 = v; var k: i64 = 0
21 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
22 let o: *u8 = sys_mmap(24); var i: i64 = 0
23 while i < k { o[i] = d[k - 1 - i]; i = i + 1 }
24 sys_write(1, o, k); return 0
25}
26// emit a full line: "<lit>\n"
27func e_line(s: *u8) -> i64 { e_w(s); e_nl(); return 0 }
28
29func main() -> i64 {
30 // ---- inputs (the IoT network the Tuya/ESP devices should join) ----
31 let ssid: *u8 = "GL-BE9300-558-IoT" as *u8
32 let ssid_n: i64 = 17
33 let pwd: *u8 = "goodlife" as *u8
34 let pwd_n: i64 = 8
35 let bssid: *u8 = sys_mmap(8)
36 var z: i64 = 0
37 while z < 6 { bssid[z] = 0 as u8; z = z + 1 } // bssid=0 (broadcast mode; device locks by SSID)
38 let ip: *u8 = sys_mmap(8)
39 ip[0] = 192 as u8; ip[1] = 168 as u8; ip[2] = 10 as u8; ip[3] = 1 as u8
40
41 let u8s: *i64 = sys_mmap(512 * 8) as *i64
42 let n: i64 = nx_sc_encode(ssid, ssid_n, bssid, pwd, pwd_n, ip, u8s, 512)
43 if n < 0 { e_line("// ENCODE FAILED" as *u8); return 1 }
44
45 // ---- emit the aarch64 send-loop ----
46 e_line("// auto-emitted by nx_iot_sc_emit_a64 -- SmartConfig broadcaster for the IoT AP" as *u8)
47 e_line("main:" as *u8)
48 e_line(" sub sp, sp, #1280" as *u8)
49 // socket(AF_INET=2, SOCK_DGRAM=2, 0)
50 e_line(" mov x0, #2" as *u8)
51 e_line(" mov x1, #2" as *u8)
52 e_line(" mov x2, #0" as *u8)
53 e_line(" mov x8, #198" as *u8)
54 e_line(" svc" as *u8)
55 e_line(" mov x19, x0" as *u8) // x19 = fd
56 // sockaddr_in @ [sp]: family=2, port=7001(BE 0x1B59), addr=192.168.10.255 (subnet bcast)
57 // bytes 02 00 1B 59 C0 A8 0A FF -> lanes 0x0002 / 0x591B / 0xA8C0 / 0xFF0A
58 e_line(" movz x1, #2" as *u8)
59 e_line(" movk x1, #22811, lsl #16" as *u8) // 0x591B port
60 e_line(" movk x1, #43200, lsl #32" as *u8) // 0xA8C0 -> 192.168
61 e_line(" movk x1, #65290, lsl #48" as *u8) // 0xFF0A -> .10.255
62 e_line(" str x1, [sp]" as *u8)
63 e_line(" mov x1, #0" as *u8)
64 e_line(" str x1, [sp, #8]" as *u8)
65 e_line(" mov x21, sp" as *u8) // x21 = &sockaddr
66 e_line(" add x20, sp, #16" as *u8) // x20 = payload (uninit, readable; len carries data)
67 // setsockopt(fd, SOL_SOCKET=1, SO_BROADCAST=6, &one, 4)
68 e_line(" mov x9, #1" as *u8)
69 e_line(" str x9, [sp, #1056]" as *u8)
70 e_line(" mov x0, x19" as *u8)
71 e_line(" mov x1, #1" as *u8)
72 e_line(" mov x2, #6" as *u8)
73 e_line(" add x3, sp, #1056" as *u8)
74 e_line(" mov x4, #4" as *u8)
75 e_line(" mov x8, #208" as *u8)
76 e_line(" svc" as *u8)
77 // timespec {0, 5000000ns = 5ms} @ [sp,#1040]
78 e_line(" mov x9, #0" as *u8)
79 e_line(" str x9, [sp, #1040]" as *u8)
80 e_line(" movz x9, #19264" as *u8) // K_MAGIC_5000000 = 0x4C4B40
81 e_line(" movk x9, #76, lsl #16" as *u8)
82 e_line(" str x9, [sp, #1048]" as *u8)
83 e_line(" add x22, sp, #1040" as *u8) // x22 = ×pec
84 // outer repeat loop (R rounds of the full guide+datum sequence)
85 e_line(" mov x26, #0" as *u8)
86 e_line("outer:" as *u8)
87 var i: i64 = 0
88 while i < n {
89 e_w(" mov x2, #" as *u8); e_n(u8s[i]); e_nl()
90 e_line(" bl snd" as *u8)
91 i = i + 1
92 }
93 e_line(" add x26, x26, #1" as *u8)
94 e_line(" cmp x26, #60" as *u8) // R = 60 rounds
95 e_line(" b.lt outer" as *u8)
96 e_line(" mov x0, #0" as *u8)
97 e_line(" mov x8, #93" as *u8)
98 e_line(" svc" as *u8)
99 // snd: sendto(fd, payload, x2=len, 0, &sockaddr, 16); nanosleep(5ms); ret
100 e_line("snd:" as *u8)
101 e_line(" mov x0, x19" as *u8)
102 e_line(" mov x1, x20" as *u8)
103 e_line(" mov x3, #0" as *u8)
104 e_line(" mov x4, x21" as *u8)
105 e_line(" mov x5, #16" as *u8)
106 e_line(" mov x8, #206" as *u8)
107 e_line(" svc" as *u8)
108 e_line(" mov x0, x22" as *u8)
109 e_line(" mov x1, #0" as *u8)
110 e_line(" mov x8, #101" as *u8)
111 e_line(" svc" as *u8)
112 e_line(" ret" as *u8)
113 return 0
114}