code wiki / (root) / nx_tuya_smartconfig.nx

nx_tuya_smartconfig.nx source

↩ module page · 89 lines · 3378 B

1// nx_tuya_smartconfig.nx -- SOVEREIGN Tuya smartconfig BROADCAST encoder. 2// 3// Faithful port of tuya-convert's broadcast.py + crc.py (kueblc 2019, broadcast ported from 4// tuyapi/link), sovereignly fetched to knowledge/fetched/tuya_{broadcast,crc}.raw. Produces the UDP 5// packet-LENGTH body a Tuya device in EZ mode sniffs. The FULL broadcast = broadcast_head [1,3,6,10] 6// (sent in the header phase) + this body, sent as UDP to 255.255.255.255:30011 (payload = `\0`*len), 7// 5ms gap. Tuya CRC-8 is its OWN polynomial (per-bit: if (r^b)&1: r^=0x18;r>>=1;r|=0x80 else r>>=1) -- 8// NOT the Dallas/Maxim of ESP-Touch. The device DECODES the lengths -> SSID+password+token -> joins. 9// NEVER-BRICK #26: emits reversible Wi-Fi creds only. license_tier: ORIGINAL 10import "nx_syscalls_x86_64.nx" 11const K_MAGIC_1024: i64 = 1024 12 13// Tuya CRC-8 of one byte (local r starts 0). 14func nx_tuya_crc8_byte(bIn: i64) -> i64 { 15 var r: i64 = 0 16 var b: i64 = bIn 17 var i: i64 = 0 18 while i < 8 { 19 if ((r ^ b) & 1) != 0 { r = r ^ 0x18; r = r >> 1; r = r | 0x80 } else { r = r >> 1 } 20 b = b >> 1 21 i = i + 1 22 } 23 return r 24} 25// crc_8 fold over n i64 values: r=0; for b: r = crc8byte(r ^ b) 26func nx_tuya_crc8(arr: *i64, n: i64) -> i64 { 27 var r: i64 = 0 28 var i: i64 = 0 29 while i < n { r = nx_tuya_crc8_byte(r ^ arr[i]); i = i + 1 } 30 return r 31} 32 33// encode_broadcast_body -> out[] body lengths; returns count or -1 on overflow. 34// r = [len(pw)] + pw + [len(tok)] + tok + ssid ; device decodes pw/token/ssid from these. 35func nx_tuya_bcast(pw: *u8, pw_n: i64, ssid: *u8, ssid_n: i64, tok: *u8, tok_n: i64, 36 out: *i64, cap: i64) -> i64 { 37 let r: *i64 = sys_mmap(8 * K_MAGIC_1024) as *i64 38 var rn: i64 = 0 39 r[rn] = pw_n; rn = rn + 1 40 var i: i64 = 0 41 while i < pw_n { r[rn] = (pw[i] as i64) & 0xff; rn = rn + 1; i = i + 1 } 42 r[rn] = tok_n; rn = rn + 1 43 i = 0 44 while i < tok_n { r[rn] = (tok[i] as i64) & 0xff; rn = rn + 1; i = i + 1 } 45 i = 0 46 while i < ssid_n { r[rn] = (ssid[i] as i64) & 0xff; rn = rn + 1; i = i + 1 } 47 let length: i64 = rn 48 49 let onev: *i64 = sys_mmap(16) as *i64 50 onev[0] = length 51 let lcrc: i64 = nx_tuya_crc8(onev, 1) 52 53 if cap < 4 { return 0 - 1 } 54 var o: i64 = 0 55 out[o] = (length >> 4) | 16; o = o + 1 56 out[o] = (length & 0xF) | 32; o = o + 1 57 out[o] = (lcrc >> 4) | 48; o = o + 1 58 out[o] = (lcrc & 0xF) | 64; o = o + 1 59 60 var seq: i64 = 0 61 var idx: i64 = 0 62 var last_i: i64 = 0 63 while idx < length { 64 last_i = idx 65 // group_crc = crc_8([seq, r[idx..idx+4] padded to 0]) 66 var gcrc: i64 = nx_tuya_crc8_byte(0 ^ seq) 67 var k: i64 = 0 68 while k < 4 { 69 var bv: i64 = 0 70 if (idx + k) < length { bv = r[idx + k] } 71 gcrc = nx_tuya_crc8_byte(gcrc ^ bv) 72 k = k + 1 73 } 74 if (o + 2) > cap { return 0 - 1 } 75 out[o] = (gcrc & 0x7F) | 128; o = o + 1 76 out[o] = seq | 128; o = o + 1 77 k = 0 78 while k < 4 { 79 if (idx + k) < length { if o >= cap { return 0 - 1 } out[o] = r[idx + k] | 256; o = o + 1 } 80 k = k + 1 81 } 82 seq = seq + 1 83 idx = idx + 4 84 } 85 var pad: i64 = length - last_i 86 var p: i64 = 0 87 while p < pad { if o >= cap { return 0 - 1 } out[o] = 256; o = o + 1; p = p + 1 } 88 return o 89}