"use strict"; var _kcUtils = require("./kcUtils.js") , _kcUtils2 = _interopRequireDefault(_kcUtils); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e } } function encode(content, dataType, cmdType, ST = "33", isPrivate = false) { // 1. 获取当前协议类型(0=国标GB协议,1=微信WX协议) var protocolType = _kcUtils2.default.getProtocolType(); // 2. 构建ETC应用层数据帧 var etcData = getETCData(content, dataType, cmdType, isPrivate); var encodedFrame; // 3. 根据协议类型选择编码方式 if (protocolType === 0) { // 国标GB28181协议编码 encodedFrame = encode_GB(etcData); } else if (protocolType === 1) { // 微信协议编码 encodedFrame = encode_WX(etcData, ST); } console.log('Encoded Frame:', encodedFrame); return encodedFrame; } function getETCData(content, dataType, cmdType) { var r = "" , r = "A0" == cmdType || "A3" == cmdType || "A4" == cmdType || "82" == cmdType || "AC" == cmdType ? cmdType + dataType + (r = getCommand(content)) : cmdType + content; return _kcUtils2.default.showLog("组拼ETCData完毕:", r.length / 2, r), r } function getCommand(e) { var t, a = e, r = _kcUtils2.default.getDATA_TYPE(), e = e.length / 2, n = new ArrayBuffer(10), s = new DataView(n); return 0 == r ? (t = 256 < e ? (s.setInt8(0, 4 + e & 255), s.setInt8(1, 4 + e >> 8 & 255), s.setInt8(2, 128), s.setInt8(3, 130), s.setInt8(4, e >> 8 & 255), s.setInt8(5, 255 & e), n.slice(0, 6)) : 128 < e && e <= 256 ? (s.setInt8(0, 3 + e & 255), s.setInt8(1, 3 + e >> 8 & 255), s.setInt8(2, 128), s.setInt8(3, 129), s.setInt8(4, e), n.slice(0, 5)) : (s.setInt8(0, 2 + e & 255), s.setInt8(1, 2 + e >> 8 & 255), s.setInt8(2, 128), s.setInt8(3, e), n.slice(0, 4)), a = _kcUtils2.default.byteArray2hexStr(t) + a) : 1 == r && (s.setInt8(0, 255 & e), s.setInt8(1, e >> 8 & 255), t = n.slice(0, 2), a = _kcUtils2.default.byteArray2hexStr(t) + a), a } function encode_GB(e) { var t = {} , a = _kcUtils2.default.getPagLenMax() , r = parseInt(e.length / 2 / a) , n = (e.length / 2 % a != 0 && (r += 1), new ArrayBuffer(10)); new DataView(n); t.serviceCode = 0, t.serviceInfo = "encode ok", t.serviceData = {}, t.serviceData.dataEncode = new Array; for (var s = 0; s < r - 1; s++) t.serviceData.dataEncode[s] = e.substr(s * a * 2, 2 * a), t.serviceData.dataEncode[s] = getGBFrame(t.serviceData.dataEncode[s], s, r); return t.serviceData.dataEncode[r - 1] = e.substring((r - 1) * a * 2), t.serviceData.dataEncode[r - 1] = getGBFrame(t.serviceData.dataEncode[r - 1], r - 1, r), t } function encode_WX(e, ST = "33") { for (var t = {}, a = _kcUtils2.default.getPagLenMax(), r = parseInt(e.length / 2 / a), n = (e.length / 2 % a != 0 && (r += 1), t.serviceCode = 0, t.serviceInfo = "encode ok", t.serviceData = {}, t.serviceData.dataEncode = new Array, 0), n = 0; n < r - 1; n++) t.serviceData.dataEncode[n] = e.substr(n * a * 2, 2 * a), t.serviceData.dataEncode[n] = getWXFrame(t.serviceData.dataEncode[n], n, r, ST); return t.serviceData.dataEncode[r - 1] = e.substring((r - 1) * a * 2), t.serviceData.dataEncode[r - 1] = getWXFrame(t.serviceData.dataEncode[r - 1], r - 1, r, ST), t } function getWXFrame(rawData, currentFrameIndex, totalFrames, ST = "33") { // 初始化字节缓冲区和数据视图 var buffer = new ArrayBuffer(10); var dataView = new DataView(buffer); var headerHex = ""; var xorChecksum = 0; var SN = "01"; var dataByteLength = rawData.length / 2; // 原始数据字节长度(16进制字符串长度/2) // --- 步骤1: 构建帧头序号 --- if (currentFrameIndex === 0) { // 首帧:序号 = 128 + (总帧数-1) dataView.setUint8(0, 128 + (totalFrames - 1 - currentFrameIndex) & 0xFF); } else { // 后续帧:序号 = (总帧数-1-当前帧索引) dataView.setUint8(0, (totalFrames - 1 - currentFrameIndex) & 0xFF); } headerHex = _kcUtils2.default.byteArray2hexStr(buffer).substring(0, 2); // --- 步骤2: 拼接基础协议头 --- var frameContent = ST + SN + // 协议标识(固定值) headerHex + // 帧序号(1字节) _kcUtils2.default.byte2hexStr(dataByteLength & 0xFF) + // 数据长度(1字节) rawData; // 原始数据 // --- 步骤3: 计算异或校验值(从第2字节开始)--- var byteArray = _kcUtils2.default.hexStr2byteArray(frameContent); for (var i = 1; i < byteArray.length; i++) { xorChecksum ^= byteArray[i]; } frameContent += _kcUtils2.default.byte2hexStr(xorChecksum); // 附加校验值 var fullFrameLength = byteArray.length + 1; // 包含校验后的总长度 // --- 步骤4: 动态构造完整帧结构 --- if (fullFrameLength > 127) { // 长帧格式:0x80 + 低7位长度,后跟高位长度 dataView.setUint8(0, 0x80 | (fullFrameLength & 0x7F)); dataView.setUint8(1, fullFrameLength >>> 7); headerHex = _kcUtils2.default.byteArray2hexStr(buffer).substring(0, 4); var totalFrameSize = fullFrameLength + 15; // 数据长 + 固定头尾(8+4+3) dataView.setUint8(0, (totalFrameSize >>> 8) & 0xFF); dataView.setUint8(1, totalFrameSize & 0xFF); } else { // 短帧格式:直接写入长度 dataView.setUint8(0, fullFrameLength & 0xFF); headerHex = _kcUtils2.default.byteArray2hexStr(buffer).substring(0, 2); var totalFrameSize = fullFrameLength + 14; // 数据长 + 固定头尾(8+4+2) dataView.setUint8(0, (totalFrameSize >>> 8) & 0xFF); dataView.setUint8(1, totalFrameSize & 0xFF); } // --- 步骤5: 组装最终帧(微信协议固定结构)--- return "FE01" + // 帧起始标识(2字节) _kcUtils2.default.byteArray2hexStr(buffer).substring(0, 4) + // 动态长度字段(2-4字节) "753100000A0012" + // 固定协议头(微信设备标识,8字节) headerHex + // 动态帧头(序号+长度) frameContent + // 数据+校验 "1800"; // 帧结束标识(2字节) } function getWXFrame1(e, t, a) { for (var r = e, n = new ArrayBuffer(10), s = new DataView(n), i = "", l = 0, e = e.length / 2, d = (0 == t ? s.setInt8(0, 128 + (a - 1 - t & 255)) : s.setInt8(0, a - 1 - t & 255), r = "3301" + (i = _kcUtils2.default.byteArray2hexStr(n).substring(0, 2)) + _kcUtils2.default.byte2hexStr(255 & e) + r, _kcUtils2.default.hexStr2byteArray(r)), c = 1; c < d.length; c++) l ^= d[c]; r += _kcUtils2.default.byte2hexStr(l); var o, a = _kcUtils2.default.hexStr2byteArray(r).length; return 127 < a ? (s.setInt8(0, 128 + (a % 128 & 255)), s.setInt8(1, a / 128 & 255), i = _kcUtils2.default.byteArray2hexStr(n).substring(0, 4), s.setInt8(0, (o = a + 8 + 4 + 3) >> 8 & 255)) : (s.setInt8(0, 255 & a), i = _kcUtils2.default.byteArray2hexStr(n).substring(0, 2), s.setInt8(0, (o = a + 8 + 4 + 2) >> 8 & 255)), s.setInt8(1, 255 & o), r = "FE01" + _kcUtils2.default.byteArray2hexStr(n).substring(0, 4) + "753100000A0012" + i + r + "1800" } function getGBFrame(e, t, a) { for (var r = e, n = new ArrayBuffer(10), s = new DataView(n), i = 0, e = e.length / 2, l = (0 == t ? (s.setInt8(0, 128 + (a >> 8 & 255)), s.setInt8(1, 255 & a)) : (s.setInt8(0, t + 1 >> 8 & 255), s.setInt8(1, t + 1 & 255)), s.setInt8(2, 255 & e), a = _kcUtils2.default.byteArray2hexStr(n).substring(0, 6), _kcUtils2.default.hexStr2byteArray(r = "50" + a + r)), d = 0; d < l.length; d++) i ^= l[d]; return r += _kcUtils2.default.byte2hexStr(i) } module.exports = { encode: encode };