global.wx = global.wx || { onBLEConnectionStateChange: function () {} } const ble = require('../services/ble') function assert(condition, message) { if (!condition) throw new Error(message) } function bytes(buffer) { return Array.from(new Uint8Array(buffer)) } function xor(arr) { return arr.reduce((acc, item) => acc ^ item, 0) } function testBuildFrameChecksum() { const frame = bytes(ble.buildFrame(0x02, [0x7F, 0x01])) assert(frame[0] === 0xAA && frame[1] === 0x55, 'frame header mismatch') assert(frame[2] === 0x02, 'frame length mismatch') assert(frame[3] === 0x02, 'frame type mismatch') assert(frame[frame.length - 1] === xor(frame.slice(0, -1)), 'checksum must include header, len, type, payload') } function testParseStatusFrame() { const payload = [0x02, 0x7F, 0x02, 200, 0x00, 0x09, 0x27, 0xC0, 0x00, 0x01, 86, 36, 1, 2] const frame = ble.buildFrame(0x21, payload) const parsed = ble.parseFrame(frame) assert(parsed.type === 0x21, 'status type mismatch') const status = ble.parseStatusReport(parsed.payload) assert(status.mode_state === 0x02, 'mode_state mismatch') assert(status.region_mask === 0x7F, 'region mask mismatch') assert(status.remaining_ms === 600000, 'remaining_ms mismatch') assert(status.battery === 86, 'battery mismatch') assert(status.temperature === 36, 'temperature mismatch') } function testBindPayloadLength() { const userBytes = ble.hexToBytes('0000000000000001') const tokenBytes = ble.hexToBytes('0011223344556677') assert(userBytes.length === 8, 'user id must be 8 bytes') assert(tokenBytes.length === 8, 'bind token must be 8 bytes') } function testVendorCommand33() { const command = ble.buildVendorCommand33({ region_mask: 0x1F, wavelength: ble.WAVELENGTH.R, brightness: 200, duration_ms: 600000 }) assert(command.length === 33, 'vendor command must be 33 bytes') assert(command[32] === xor(command.slice(0, 32)), 'vendor command checksum mismatch') } testBuildFrameChecksum() testParseStatusFrame() testBindPayloadLength() testVendorCommand33() console.log('BLE frame tests passed')