import { splitUint8Array, toUint8Array } from '../utils/bytes' import { utf8ToBytes } from '../utils/hex' /** * 按协议将 payload 拆成 A7 分包: * 第 1 字节固定包头 0xA7,第 2 字节高4位为总包数、低4位为包序号。 */ export function buildA7Packets(payload, packetConfig = {}) { const { head = 0xA7, chunkSize = 18, maxChunk = 15 } = packetConfig const bytes = typeof payload === 'string' ? utf8ToBytes(payload) : toUint8Array(payload) const chunks = splitUint8Array(bytes, chunkSize) if (chunks.length > maxChunk) { throw new Error(`分包数量超过上限: ${chunks.length} > ${maxChunk}`) } return chunks.map((chunk, index) => { const packetIndex = index + 1 const lenByte = ((chunks.length & 0x0F) << 4) | (packetIndex & 0x0F) const packet = new Uint8Array(2 + chunk.length) packet[0] = head packet[1] = lenByte packet.set(chunk, 2) return packet }) } /** * 合并多个 A7 分包数据体(去掉前两字节头信息后拼接)。 */ export function concatA7PacketData(packets = []) { const sorted = [...packets].sort((a, b) => { const indexA = a[1] & 0x0F const indexB = b[1] & 0x0F return indexA - indexB }) const totalLength = sorted.reduce((sum, packet) => sum + Math.max(packet.length - 2, 0), 0) const merged = new Uint8Array(totalLength) let offset = 0 sorted.forEach((packet) => { const body = packet.slice(2) merged.set(body, offset) offset += body.length }) return merged }