179 lines
10 KiB
JavaScript
179 lines
10 KiB
JavaScript
import "../shim.ts";
|
|
|
|
import assert from "assert";
|
|
|
|
import { XqBytesDec, XqBytesEnc } from "../func_replacements.js";
|
|
import { hexdump } from "../hexdump.js";
|
|
import { SendStartVideo, SendDevStatus, SendUsrChk, SendWifiDetails, parse_PunchPkt } from "../impl.ts";
|
|
import { placeholderTypes, sprintf } from "../utils.js";
|
|
|
|
describe("debug_tools", () => {
|
|
it("parses printed data", () => {
|
|
const fmt = "string: %s, int: %d, float: %f, hexint: %02x, newline: \n\n last int: %d";
|
|
const expected_placeholders = ["s", "d", "f", "x", "d"];
|
|
const actual_placeholders = placeholderTypes(fmt);
|
|
assert.deepEqual(actual_placeholders, expected_placeholders);
|
|
});
|
|
it("prints data back", () => {
|
|
const fmt = "string: %s, int: %d, float: %f, hexint: %02x, newline: \n\n last int: %d";
|
|
const in_values = ["potato", 5, 3.5, 0x20, 999];
|
|
const expected_string = "string: potato, int: 5, float: 3.5, hexint: 0x20, newline: \n\n last int: 999";
|
|
assert.deepEqual(sprintf(fmt, in_values), expected_string);
|
|
});
|
|
it("prints leftover after last formatter", () => {
|
|
const fmt = "string: %s and this bit is also printed";
|
|
const in_values = ["potato"];
|
|
const expected_string = "string: potato and this bit is also printed";
|
|
assert.deepEqual(sprintf(fmt, in_values), expected_string);
|
|
});
|
|
});
|
|
|
|
describe("module", () => {
|
|
const simple_enc_bytes = new Uint8Array([
|
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
|
|
]);
|
|
const simple_dec_bytes = new Uint8Array([
|
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
]);
|
|
const long_enc_bytes = new Uint8Array([
|
|
0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x01, 0x43, 0x40, 0x55, 0x42, 0x37, 0x31, 0x38, 0x34, 0x32, 0x30, 0x44, 0x59, 0x4d, 0x57, 0x52, 0x01, 0x01, 0x01,
|
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x30, 0x33, 0x32, 0x35, 0x34,
|
|
0x37, 0x36, 0x39, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x31, 0x2f, 0x33, 0x34, 0x34, 0x2f, 0x33, 0x34, 0x34, 0x2f,
|
|
0x33, 0x34, 0x34, 0x01, 0x01, 0x01, 0x31, 0x2f, 0x31, 0x2f, 0x31, 0x2f, 0x31, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x01, 0x01, 0x01, 0x31, 0x2f, 0x31, 0x2f, 0x31, 0x2f, 0x31, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x31, 0x2f, 0x31, 0x2f, 0x31, 0x2f, 0x31, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x31, 0x2f, 0x31,
|
|
0x2f, 0x31, 0x2f, 0x31, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
]);
|
|
const long_dec_bytes = new Uint8Array([
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x41, 0x54, 0x43, 0x36, 0x30, 0x39, 0x35, 0x33, 0x31, 0x45, 0x58, 0x4c, 0x56,
|
|
0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
|
|
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x2e, 0x32, 0x35, 0x35, 0x2e,
|
|
0x32, 0x35, 0x35, 0x2e, 0x32, 0x35, 0x35, 0x00, 0x00, 0x00, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
]);
|
|
it("encrypts without rotation", () => {
|
|
const in_buf = new DataView(new Uint8Array([1, 2, 3, 4]).buffer);
|
|
XqBytesEnc(in_buf, in_buf.byteLength, 0); // this mutates in_buf
|
|
assert.equal(in_buf.add(0).readU8(), 0);
|
|
assert.equal(in_buf.add(1).readU8(), 3);
|
|
assert.equal(in_buf.add(2).readU8(), 2);
|
|
assert.equal(in_buf.add(3).readU8(), 5);
|
|
});
|
|
it("decrypts without rotation", () => {
|
|
const in_buf = new DataView(new Uint8Array([1, 2, 3, 4]).buffer);
|
|
XqBytesDec(in_buf, in_buf.byteLength, 0); // this mutates in_buf
|
|
assert.equal(in_buf.add(0).readU8(), 0);
|
|
assert.equal(in_buf.add(1).readU8(), 3);
|
|
assert.equal(in_buf.add(2).readU8(), 2);
|
|
assert.equal(in_buf.add(3).readU8(), 5);
|
|
});
|
|
it("decrypts simple input", () => {
|
|
const in_buf = new DataView(simple_enc_bytes.buffer.slice(0));
|
|
XqBytesDec(in_buf, simple_enc_bytes.byteLength, 4); // this mutates in_buf
|
|
assert.deepEqual(new Uint8Array(in_buf.buffer), simple_dec_bytes);
|
|
});
|
|
it("decrypts more complex input", () => {
|
|
const in_buf = new DataView(long_enc_bytes.buffer.slice(0));
|
|
XqBytesDec(in_buf, long_enc_bytes.byteLength, 4); // this mutates in_buf
|
|
assert.deepEqual(new Uint8Array(in_buf.buffer), long_dec_bytes);
|
|
});
|
|
it("encrypts simple input", () => {
|
|
const in_buf = new DataView(simple_dec_bytes.buffer.slice(0));
|
|
XqBytesEnc(in_buf, simple_dec_bytes.byteLength, 4); // this mutates in_buf
|
|
assert.deepEqual(new Uint8Array(in_buf.buffer), simple_enc_bytes);
|
|
});
|
|
it("encrypts more complex input", () => {
|
|
const in_buf = new DataView(long_dec_bytes.buffer.slice(0));
|
|
XqBytesEnc(in_buf, long_dec_bytes.byteLength, 4); // this mutates in_buf
|
|
assert.deepEqual(new Uint8Array(in_buf.buffer), long_enc_bytes);
|
|
});
|
|
/* TODO
|
|
it("decrypts offset dataviews", () => {
|
|
const in_buf = new DataView(simple_enc_bytes.buffer.slice(0));
|
|
XqBytesDec(in_buf, simple_enc_bytes.byteLength, 4); // this mutates in_buf
|
|
assert.deepEqual(new Uint8Array(in_buf.buffer), simple_dec_bytes);
|
|
});
|
|
*/
|
|
it("reverts Enc with Dec", () => {
|
|
const in_buf = new DataView(long_dec_bytes.buffer.slice(0));
|
|
XqBytesEnc(in_buf, long_dec_bytes.byteLength, 4); // this mutates in_buf
|
|
assert.deepEqual(new Uint8Array(in_buf.buffer), long_enc_bytes); // ENC
|
|
XqBytesDec(in_buf, long_dec_bytes.byteLength, 4); // this mutates in_buf
|
|
assert.deepEqual(new Uint8Array(in_buf.buffer), long_dec_bytes); // DEC
|
|
});
|
|
});
|
|
|
|
const hstrToBA = (hs) => new Uint8Array(hs.match(/../g).map((h) => parseInt(h, 16))).buffer;
|
|
describe("events", () => {
|
|
it("emits login event upon logging in", () => {
|
|
// TODO
|
|
});
|
|
});
|
|
describe("parse packet", () => {
|
|
it("parses PunchPkt", () => {
|
|
const in_pkt_str = "f14100144241544400000000000262ca574f4e4a4d000000";
|
|
const pkt = new DataView(hstrToBA(in_pkt_str));
|
|
const expected = {
|
|
prefix: "BATD",
|
|
serial: "156362",
|
|
suffix: "WONJM",
|
|
serialU64: bigint(156362),
|
|
devId: "BATD156362WONJM",
|
|
};
|
|
|
|
assert.equal(parse_PunchPkt(pkt), expected);
|
|
});
|
|
});
|
|
describe("make packet", () => {
|
|
it("builds a good SendUsrChk", () => {
|
|
const expected_str =
|
|
"f1d000b0d1000000110a2010a400ff00000000006f01010101010101010101010101010101010101010101010101010160656c686f01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010160656c68";
|
|
const expected = hstrToBA(expected_str);
|
|
const sess = { outgoingCommandId: 0, ticket: [0, 0, 0, 0] };
|
|
assert.deepEqual(SendUsrChk(sess, "admin", "admin").buffer, expected);
|
|
});
|
|
it("builds a good SendStartVideo", () => {
|
|
const _expected_str = "f1d00010d1000000110a10300400000001020304";
|
|
const expected = hstrToBA(_expected_str);
|
|
|
|
const sess = { outgoingCommandId: 0, ticket: [1, 2, 3, 4] };
|
|
const got = SendStartVideo(sess);
|
|
assert.deepEqual(got.buffer, expected);
|
|
});
|
|
it("builds a good SendDevStatus", () => {
|
|
const sess = { outgoingCommandId: 0, ticket: [1, 2, 3, 4] };
|
|
const _expected_str = "f1d00010d1000000110a08100400000001020304";
|
|
const expected = hstrToBA(_expected_str);
|
|
|
|
const got = SendDevStatus(sess);
|
|
assert.deepEqual(got.buffer, expected);
|
|
});
|
|
it("builds a good WifiSettingsSet", () => {
|
|
const sess = { outgoingCommandId: 2, ticket: [1, 2, 3, 4] };
|
|
const _expected_str =
|
|
"f1d00118d1000002110a01600c010000010203040101010101010101010101010101010100010101726a786f647501010101010101010101010101010101010101010101010101017274716473627360710101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101312f3334342f3334342f333434010101312f312f312f31010101010101010101312f312f312f31010101010101010101312f312f312f31010101010101010101312f312f312f3101010101010101010101010101";
|
|
const expected = hstrToBA(_expected_str);
|
|
|
|
const got = SendWifiDetails(sess, "skynet", "supercrap", true);
|
|
assert.deepEqual(got.buffer, expected);
|
|
});
|
|
});
|