const storageAccessService = require('../storage-access/service.js') const transport = require('../../transport/ble-core.js') const { AREA } = require('../../protocols/storage-access/index.js') const { bytesToHex, stringToUtf8Bytes } = require('../../utils/binary-utils.js') const { STORAGE_ACCESS_AREA_OPTIONS, STORAGE_ACCESS_COMMAND_OPTIONS, normalizeSerialState, parseHexBytes, validateHexText } = require('./view-model.js') function getStorageAccessCommand(index) { return STORAGE_ACCESS_COMMAND_OPTIONS[Number(index) || 0] || STORAGE_ACCESS_COMMAND_OPTIONS[0] } function getStorageAccessArea(index) { return STORAGE_ACCESS_AREA_OPTIONS[Number(index) || 0] || STORAGE_ACCESS_AREA_OPTIONS[0] } async function sendSerialFrame(data = {}) { const serialInputText = String(data.serialInputText || '') const serialState = normalizeSerialState(data) const mode = serialState.serialMode if (!data.connectedDevice) { return { errorText: '请先连接蓝牙设备', ok: false } } if (serialState.serialErrorText) { return { errorText: serialState.serialErrorText, ok: false } } if (mode === 'hex') { const errorText = validateHexText(serialInputText) if (errorText) { return { errorText, ok: false } } const bytes = parseHexBytes(serialInputText) const previewHex = bytesToHex(bytes, ' ') const ok = await transport.sendRawFrameExact(new Uint8Array(bytes), 'SERIAL') return { bytes, ok, previewHex, serialState } } const bytes = stringToUtf8Bytes(serialInputText) if (!bytes.length) { return { errorText: '请输入要发送的文本', ok: false } } const ok = await transport.sendRawFrameExact(new Uint8Array(bytes), 'SERIAL') return { bytes, ok, previewHex: bytesToHex(bytes, ' '), serialState } } async function syncStorageAccessCodeInfo(data = {}) { const result = await storageAccessService.syncCodeInfo({ maxPacketLength: data.parameterMaxPacketLength, showModal: true }) if (!result || !result.ok) { return { ok: false } } const codeInfoAddressText = result.codeInfoAddressText || Number(result.codeInfoAddress || 0).toString(16).toUpperCase().padStart(4, '0') const codeInfoByteLengthText = result.codeInfoByteLengthText || Number(result.codeInfoByteLength || 0).toString(16).toUpperCase().padStart(4, '0') return { codeInfoAddress: result.codeInfoAddress, codeInfoAddressText, codeInfoByteLength: result.codeInfoByteLength, codeInfoByteLengthText, ok: true, syncInfoText: `0x0F info ${codeInfoAddressText}/${codeInfoByteLengthText}` } } async function executeStorageAccessProtocol(data = {}) { const command = getStorageAccessCommand(data.storageAccessCommandIndex) const area = getStorageAccessArea(data.storageAccessAreaIndex) const address = parseInt(data.storageAccessAddress || '0000', 16) || 0 const length = parseInt(data.storageAccessLength || '0004', 16) || 0 const dataBytes = parseHexBytes(data.storageAccessDataText || '') if (!data.connectedDevice) { return { errorText: '请先连接蓝牙设备', ok: false } } if (data.storageAccessErrorText) { return { errorText: data.storageAccessErrorText, ok: false } } if (command.key === 'sync') { return syncStorageAccessCodeInfo(data) } if (command.key === 'write' && (area.key === AREA.CODE || area.key === AREA.INFO)) { return { errorText: 'code/info 区暂不支持写入', ok: false } } if (command.key === 'read') { const bytes = await storageAccessService.readMemory( area.key, address, length, '私有协议读取', 'communication-storage-read', { maxPacketLength: data.parameterMaxPacketLength, showModal: true } ) return { bytes, ok: !!bytes, previewHex: bytes ? bytesToHex(bytes, ' ') : '' } } const errorText = validateHexText(data.storageAccessDataText) if (errorText) { return { errorText, ok: false } } if (dataBytes.length !== length) { return { errorText: `写入长度为 ${length} 字节,当前数据为 ${dataBytes.length} 字节`, ok: false } } const ok = await storageAccessService.writeMemory( area.key, address, dataBytes, '私有协议写入', 'communication-storage-write', { maxPacketLength: data.parameterMaxPacketLength, showModal: true } ) return { ok } } module.exports = { executeStorageAccessProtocol, sendSerialFrame }