nx_tuya_emit_a64.nx source
↩ module page · 116 lines · 4963 B
1// nx_tuya_emit_a64.nx -- SOVEREIGN emitter: NishiLang -> aarch64 .s for the TUYA smartconfig
2// broadcaster that runs ON the GL.iNet router (the 2.4GHz AP). Same send-loop shortcut as the
3// ESP-Touch one, but uses the GATED nx_tuya_bcast encoding (broadcast_head [1,3,6,10] + body) and
4// Tuya's port 30011. Sends UDP packets of each length to 192.168.10.255:30011 (subnet-directed bcast
5// out the IoT bridge -> 2.4GHz air), 5ms gap, outer-looped. tuya-convert proves AP-broadcast reaches
6// an unassociated sniffing device, so the router-AP IS a valid sender for Tuya (our earlier ESP-Touch
7// failure was protocol, not RF). aarch64 syscalls: socket=198 setsockopt=208 sendto=206 nanosleep=101.
8// NEVER-BRICK #26: reversible Wi-Fi creds only. license_tier: ORIGINAL
9import "nx_tuya_smartconfig.nx"
10const K_MAGIC_30011: i64 = 30011
11
12func 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 }
13func e_nl() -> i64 { let b: *u8 = sys_mmap(1); b[0] = 10 as u8; sys_write(1, b, 1); return 0 }
14func e_n(v: i64) -> i64 {
15 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 }
16 let d: *u8 = sys_mmap(24); var m: i64 = v; var k: i64 = 0
17 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
18 let o: *u8 = sys_mmap(24); var i: i64 = 0
19 while i < k { o[i] = d[k - 1 - i]; i = i + 1 }
20 sys_write(1, o, k); return 0
21}
22func e_line(s: *u8) -> i64 { e_w(s); e_nl(); return 0 }
23
24func main() -> i64 {
25 let ssid: *u8 = "GL-BE9300-558-IoT" as *u8
26 let ssid_n: i64 = 17
27 let pwd: *u8 = "goodlife" as *u8
28 let pwd_n: i64 = 8
29 let tok: *u8 = "00000000000000" as *u8 // placeholder token_group: device joins SSID regardless (token is cloud-reg only)
30 let tok_n: i64 = 14
31
32 let seq: *i64 = sys_mmap(512 * 8) as *i64
33 seq[0] = 1; seq[1] = 3; seq[2] = 6; seq[3] = 10 // broadcast_head
34 let bodyout: *i64 = ((seq as i64) + 32) as *i64
35 let bn: i64 = nx_tuya_bcast(pwd, pwd_n, ssid, ssid_n, tok, tok_n, bodyout, 504)
36 if bn < 0 { e_line("// ENCODE FAILED" as *u8); return 1 }
37 let n: i64 = 4 + bn
38
39 e_line("// auto-emitted by nx_tuya_emit_a64 -- TUYA smartconfig broadcaster for the IoT AP" as *u8)
40 e_line("main:" as *u8)
41 e_line(" sub sp, sp, #1280" as *u8)
42 e_line(" mov x0, #2" as *u8)
43 e_line(" mov x1, #2" as *u8)
44 e_line(" mov x2, #0" as *u8)
45 e_line(" mov x8, #198" as *u8)
46 e_line(" svc" as *u8)
47 e_line(" mov x19, x0" as *u8)
48 // sockaddr_in @ [sp]: family=2, port=30011 (BE 0x753B), addr=192.168.10.255
49 e_line(" movz x1, #2" as *u8)
50 e_line(" movk x1, #15221, lsl #16" as *u8) // 0x3B75 -> port K_MAGIC_30011
51 e_line(" movk x1, #43200, lsl #32" as *u8) // 0xA8C0 -> 192.168
52 e_line(" movk x1, #65290, lsl #48" as *u8) // 0xFF0A -> .10.255
53 e_line(" str x1, [sp]" as *u8)
54 e_line(" mov x1, #0" as *u8)
55 e_line(" str x1, [sp, #8]" as *u8)
56 e_line(" mov x21, sp" as *u8)
57 e_line(" add x20, sp, #16" as *u8)
58 // setsockopt SO_BROADCAST
59 e_line(" mov x9, #1" as *u8)
60 e_line(" str x9, [sp, #1056]" as *u8)
61 e_line(" mov x0, x19" as *u8)
62 e_line(" mov x1, #1" as *u8)
63 e_line(" mov x2, #6" as *u8)
64 e_line(" add x3, sp, #1056" as *u8)
65 e_line(" mov x4, #4" as *u8)
66 e_line(" mov x8, #208" as *u8)
67 e_line(" svc" as *u8)
68 // timespec {0, 5000000ns}
69 e_line(" mov x9, #0" as *u8)
70 e_line(" str x9, [sp, #1040]" as *u8)
71 e_line(" movz x9, #19264" as *u8)
72 e_line(" movk x9, #76, lsl #16" as *u8)
73 e_line(" str x9, [sp, #1048]" as *u8)
74 e_line(" add x22, sp, #1040" as *u8)
75 // HEADER PHASE: broadcast_head [1,3,6,10] x40 (pure guide -> device locks), per smartconfig.py
76 e_line(" mov x26, #0" as *u8)
77 e_line("hphase:" as *u8)
78 var hi: i64 = 0
79 while hi < 4 {
80 e_w(" mov x2, #" as *u8); e_n(seq[hi]); e_nl()
81 e_line(" bl snd" as *u8)
82 hi = hi + 1
83 }
84 e_line(" add x26, x26, #1" as *u8)
85 e_line(" cmp x26, #40" as *u8)
86 e_line(" b.lt hphase" as *u8)
87 // BODY PHASE: broadcast_body x30 (the data, after lock)
88 e_line(" mov x26, #0" as *u8)
89 e_line("bphase:" as *u8)
90 var bi: i64 = 4
91 while bi < n {
92 e_w(" mov x2, #" as *u8); e_n(seq[bi]); e_nl()
93 e_line(" bl snd" as *u8)
94 bi = bi + 1
95 }
96 e_line(" add x26, x26, #1" as *u8)
97 e_line(" cmp x26, #10" as *u8)
98 e_line(" b.lt bphase" as *u8)
99 e_line(" mov x0, #0" as *u8)
100 e_line(" mov x8, #93" as *u8)
101 e_line(" svc" as *u8)
102 e_line("snd:" as *u8)
103 e_line(" mov x0, x19" as *u8)
104 e_line(" mov x1, x20" as *u8)
105 e_line(" mov x3, #0" as *u8)
106 e_line(" mov x4, x21" as *u8)
107 e_line(" mov x5, #16" as *u8)
108 e_line(" mov x8, #206" as *u8)
109 e_line(" svc" as *u8)
110 e_line(" mov x0, x22" as *u8)
111 e_line(" mov x1, #0" as *u8)
112 e_line(" mov x8, #101" as *u8)
113 e_line(" svc" as *u8)
114 e_line(" ret" as *u8)
115 return 0
116}