From 89534822abf67b2a0ce8077423b36e2016351c7f Mon Sep 17 00:00:00 2001 From: DavidVentura Date: Wed, 31 Jan 2024 14:30:30 +0100 Subject: [PATCH] more refactor --- handlers.ts | 35 +++++++++++------------------------ impl.ts | 8 ++++---- session.ts | 19 ++++++++++++++++--- tests/fn.test.js | 17 +++++++++-------- 4 files changed, 40 insertions(+), 39 deletions(-) diff --git a/handlers.ts b/handlers.ts index 7ccb9a2..d490f5e 100644 --- a/handlers.ts +++ b/handlers.ts @@ -3,16 +3,7 @@ import { RemoteInfo } from "node:dgram"; import { Commands, CommandsByValue, ControlCommands } from "./datatypes.js"; import { XqBytesDec } from "./func_replacements.js"; import { hexdump } from "./hexdump.js"; -import { - create_P2pClose, - create_P2pRdy, - SendDevStatus, - SendListWifi, - SendReboot, - SendStartVideo, - SendUsrChk, - SendWifiSettings, -} from "./impl.js"; +import { create_P2pRdy, SendListWifi, SendUsrChk } from "./impl.js"; import { Session } from "./session.js"; import { u16_swap, u32_swap } from "./utils.js"; @@ -53,14 +44,14 @@ export const handle_PunchPkt = (session: Session, dv: DataView, rinfo: RemoteInf session.send(create_P2pRdy(dv.add(4).readByteArray(len))); }; -export const createResponseForControlCommand = (session: Session, dv: DataView): DataView | undefined => { +export const createResponseForControlCommand = (session: Session, dv: DataView): DataView[] => { const start_type = dv.add(8).readU16(); // 0xa11 on control; data starts here on DATA pkt const cmd_id = dv.add(10).readU16(); // 0x1120 const payload_len = u16_swap(dv.add(0xc).readU16()); if (start_type != 0x110a) { console.error(`Expected start_type to be 0xa11, got 0x${start_type.toString(16)}`); - return; + return []; } const rotate_chr = 4; if (payload_len > rotate_chr) { @@ -73,11 +64,12 @@ export const createResponseForControlCommand = (session: Session, dv: DataView): if (cmd_id == ControlCommands.ConnectUserAck) { let c = new Uint8Array(dv.add(0x18).readByteArray(4).buffer); session.ticket = [...c]; - const buf = SendStartVideo(session); - return buf; + session.eventEmitter.emit("login"); + return []; } if (cmd_id == ControlCommands.DevStatusAck) { + // ParseDevStatus -> offset relevant? let charging = u32_swap(dv.add(0x28).readU32()) & 1; // 0x14000101 v 0x14000100 let power = u16_swap(dv.add(0x18).readU16()); // '3730' or '3765', milliVolts? let dbm = dv.add(0x24).readU8() - 0x100; // 0xbf - 0x100 = -65dbm .. constant?? @@ -104,12 +96,7 @@ export const createResponseForControlCommand = (session: Session, dv: DataView): }; const buf = SendListWifi(session); console.log(`Current wifi settings: ${JSON.stringify(wifiSettings, null, 2)}`); - setTimeout(() => { - console.log("send now??"); - const buf = SendListWifi(session); - session.send(buf); - }, 8000); - return buf; + return [buf]; } if (cmd_id == ControlCommands.ListWifiAck) { @@ -138,6 +125,7 @@ export const createResponseForControlCommand = (session: Session, dv: DataView): items.push(wifiListItem); } } + return []; }; let seq = 0; @@ -184,7 +172,8 @@ const deal_with_data = (session: Session, dv: DataView) => { return; } if (pkt_id > seq + 1) { - // missed some packets -- filling with zeroes still produces a broken image + // missed some packets -- filling with zeroes still produces a broken + // image frame_is_bad = true; return; } @@ -221,8 +210,6 @@ export const handle_Drw = (session: Session, dv: DataView) => { deal_with_data(session, dv); } else { const b = createResponseForControlCommand(session, dv); - if (b != undefined) { - session.send(b); - } + b.forEach(session.send); } }; diff --git a/impl.ts b/impl.ts index d6f20c0..44886ea 100644 --- a/impl.ts +++ b/impl.ts @@ -43,6 +43,7 @@ const makeDataReadWrite = (session: Session, command: number, data: DataView | n ret.add(20).writeByteArray(bufCopy); } + session.outgoingCommandId++; return ret; }; @@ -76,7 +77,7 @@ export const getVideoKey = (session: Session): void => { } }; -export const SendVideoResolution = (session: Session, resol: 1 | 2 | 3 | 4): null => { +export const SendVideoResolution = (session: Session, resol: 1 | 2 | 3 | 4): DataView[] => { // seems like 0x1 = resolution, and is specified by ID not by size // unclear what 0x2-0xf achieve - they report back as '0' always -- ignored? const pairs = { @@ -103,11 +104,10 @@ export const SendVideoResolution = (session: Session, resol: 1 | 2 | 3 | 4): nul // maybe the 0x7 = bitrate?? }; - pairs[resol].forEach((payload: number[]) => { + return pairs[resol].map((payload: number[]) => { const dv = new DataView(new Uint8Array(payload).buffer); - session.send(makeDataReadWrite(session, ControlCommands.VideoParamSet, dv)); + return makeDataReadWrite(session, ControlCommands.VideoParamSet, dv); }); - return null; }; export const SendReboot = (session: Session): DataView => { diff --git a/session.ts b/session.ts index d5f4d22..d74dce7 100644 --- a/session.ts +++ b/session.ts @@ -4,6 +4,7 @@ import { Commands, CommandsByValue } from "./datatypes.js"; import { handle_P2PAlive, handle_PunchPkt, handle_P2PRdy, handle_Drw, notImpl, noop } from "./handlers.js"; import { hexdump } from "./hexdump.js"; import EventEmitter from "node:events"; +import { SendVideoResolution, SendStartVideo, SendWifiDetails } from "./impl.js"; export type Session = { send: (msg: DataView) => void; @@ -14,6 +15,7 @@ export type Session = { dst_ip: string; lastReceivedPacket: number; connected: boolean; + devName: string; timers: ReturnType[]; }; @@ -82,6 +84,7 @@ export const makeSession = (handlers: Record { const raw = msg.readU16(); const cmd = CommandsByValue[raw]; @@ -91,9 +94,6 @@ export const makeSession = (handlers: Record { @@ -115,6 +115,7 @@ export const makeSession = (handlers: Record { const delta = Date.now() - session.lastReceivedPacket; @@ -128,9 +129,21 @@ export const makeSession = (handlers: Record { + console.log(`Logged in - ${session.devName}`); + startVideoStream(session); + }); return session; }; +const startVideoStream = (s: Session) => { + [ + ...SendVideoResolution(s, 2), // 640x480 + SendStartVideo(s), + ].forEach(s.send); +}; + export const Handlers: Record = { PunchPkt: handle_PunchPkt, P2PAlive: handle_P2PAlive, diff --git a/tests/fn.test.js b/tests/fn.test.js index 78f4c65..3d4df96 100644 --- a/tests/fn.test.js +++ b/tests/fn.test.js @@ -5,7 +5,7 @@ import assert from "assert"; import { XqBytesDec, XqBytesEnc } from "../func_replacements.js"; import { createResponseForControlCommand } from "../handlers.js"; import { hexdump } from "../hexdump.js"; -import { SendDevStatus, SendUsrChk, SendWifiDetails } from "../impl.ts"; +import { SendStartVideo, SendDevStatus, SendUsrChk, SendWifiDetails } from "../impl.ts"; import { placeholderTypes, sprintf } from "../utils.js"; describe("debug_tools", () => { @@ -123,6 +123,11 @@ describe("module", () => { }); 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("make packet", () => { it("builds a good SendUsrChk", () => { const expected_str = @@ -132,16 +137,12 @@ describe("make packet", () => { assert.deepEqual(SendUsrChk(sess, "admin", "admin").buffer, expected); }); it("builds a good SendStartVideo", () => { - const input_pkt_str = "f1d00018d1000000110a20110c00ff000000000064504737fe010101"; - // token-in = 0x64 0x50 0x47 0x37 - const _expected_str = "f1d00010d1000000110a10300400000065514636"; - // output is 0x3010; 'start video'; hardcoded but shouldnt + const _expected_str = "f1d00010d1000000110a10300400000001020304"; const expected = hstrToBA(_expected_str); - const sess = { outgoingCommandId: 0, ticket: [0, 0, 0, 0] }; - const got = createResponseForControlCommand(sess, new DataView(hstrToBA(input_pkt_str))); + const sess = { outgoingCommandId: 0, ticket: [1, 2, 3, 4] }; + const got = SendStartVideo(sess); assert.deepEqual(got.buffer, expected); - assert.deepEqual(sess.ticket, [0x65, 0x51, 0x46, 0x36]); }); it("builds a good SendDevStatus", () => { const sess = { outgoingCommandId: 0, ticket: [1, 2, 3, 4] };