/** * Encode a number as varint bytes (little-endian, continuation bit). * @param {number} value - Value to encode * @param {number[]} bytes - Accumulated bytes (default empty) * @returns {number[]} Varint bytes */ const encodeVarint = (value, bytes = []) => { const byte = value & 0x7F const remaining = value >>> 7 if (remaining === 0) { return [...bytes, byte] } return encodeVarint(remaining, [...bytes, byte | 0x80]) } /** * Build a TAK Protocol stream frame: 0xBF, varint payload length, payload. * @param {string|Buffer} payload - UTF-8 payload (e.g. CoT XML) * @returns {Buffer} TAK stream frame buffer. */ export function buildTakFrame(payload) { const buf = Buffer.isBuffer(payload) ? payload : Buffer.from(payload, 'utf8') const varint = encodeVarint(buf.length) return Buffer.concat([Buffer.from([0xBF]), Buffer.from(varint), buf]) } /** * Build CoT XML for a position update (event + point + optional contact). * @param {object} opts - Position options * @param {string} opts.uid - Entity UID * @param {number} opts.lat - Latitude * @param {number} opts.lon - Longitude * @param {string} [opts.callsign] - Optional callsign * @param {string} [opts.type] - Optional event type (default a-f-G) * @returns {string} CoT XML string. */ export function buildPositionCotXml({ uid, lat, lon, callsign, type = 'a-f-G' }) { const contact = callsign ? `` : '' return `${contact}` } /** * Build CoT XML for auth (username/password). * @param {object} opts - Auth options * @param {string} opts.username - Username * @param {string} opts.password - Password * @returns {string} CoT XML string. */ export function buildAuthCotXml({ username, password }) { return `` } function escapeXml(s) { return String(s) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') }