|
|
@@ -1,4 +1,5 @@ |
|
|
|
"use strict"; |
|
|
|
import { findVarint } from './protoBuffer.js'; |
|
|
|
var iPackageLen, _kcUtils = require("./kcUtils.js"), _kcUtils2 = _interopRequireDefault(_kcUtils); |
|
|
|
function _interopRequireDefault(t) { |
|
|
|
return t && t.__esModule ? t : { |
|
|
@@ -39,116 +40,257 @@ function decode_GB(t) { |
|
|
|
a.serviceInfo = "数据接收中。。。"), |
|
|
|
a |
|
|
|
} |
|
|
|
function decode_WX(t) { |
|
|
|
// 初始化变量 e 为 0,用于后续计算或状态跟踪 |
|
|
|
var e = 0; |
|
|
|
// 初始化一个空对象 a,用于存储后续处理的结果或状态 |
|
|
|
var a = {}; |
|
|
|
// 使用工具函数将字节数组 t 转换为十六进制字符串 |
|
|
|
var tHexStr = _kcUtils2.default.byteArray2hexStr(t); |
|
|
|
// 打印当前接收到的数据包的十六进制字符串 |
|
|
|
_kcUtils2.default.showLog("kc当前接受包的数据:", tHexStr); |
|
|
|
// 再将十六进制字符串转换回字节数组,并赋值给变量 r |
|
|
|
var r = _kcUtils2.default.hexStr2byteArray(tHexStr); |
|
|
|
// console.log(r); |
|
|
|
// 检查数据包的前两个字节是否符合特定格式,并处理数据包 |
|
|
|
if (r.byteLength > 1 && r[0] === 254 && r[1] === 1 && isPagFinish) { |
|
|
|
// 如果数据包是新的,重置 isPagFinish 和相关变量 |
|
|
|
isPagFinish = false; |
|
|
|
iPackageLen = (r[2] & 255) << 8; |
|
|
|
iPackageLen += r[3] & 255; |
|
|
|
strTemData = tHexStr; |
|
|
|
|
|
|
|
function decode_WX(inputData) { |
|
|
|
// 初始化变量 |
|
|
|
var checksum = 0; // 校验变量 |
|
|
|
var result = {}; // 返回的结果对象 |
|
|
|
var hexString = _kcUtils2.default.byteArray2hexStr(inputData); // 将输入数据转换为16进制字符串 |
|
|
|
var byteArray = _kcUtils2.default.hexStr2byteArray(hexString); // 转换为字节数组 |
|
|
|
|
|
|
|
// 打印接收到的数据 |
|
|
|
_kcUtils2.default.showLog("kc当前接受包的数据:", hexString); |
|
|
|
|
|
|
|
// 判断是否是大包开始 |
|
|
|
if ( |
|
|
|
byteArray.byteLength > 1 && |
|
|
|
byteArray[0] === 254 && // 包头标识 |
|
|
|
byteArray[1] === 1 && // 版本号 |
|
|
|
isPagFinish === true // 是否为分页结束 |
|
|
|
) { |
|
|
|
isPagFinish = false; // 标记分页未完成 |
|
|
|
iPackageLen = ((255 & byteArray[2]) << 8) + (255 & byteArray[3]); // 计算大包总长度 |
|
|
|
strTemData = hexString; // 保存当前数据 |
|
|
|
} else { |
|
|
|
// 如果数据包是分片的,追加到 strTemData |
|
|
|
strTemData += tHexStr; |
|
|
|
// 如果是数据的续传部分 |
|
|
|
strTemData += hexString; // 累加数据 |
|
|
|
} |
|
|
|
// 如果已接收的数据长度大于或等于预期的数据包长度,开始解析 |
|
|
|
|
|
|
|
// 如果接收的数据长度已达到或超过大包长度 |
|
|
|
if (strTemData.length / 2 >= iPackageLen) { |
|
|
|
console.log("大包长度:", iPackageLen, strTemData.length); |
|
|
|
isPagFinish = true; |
|
|
|
rxCount += 1; |
|
|
|
var s = _kcUtils2.default.hexStr2byteArray(strTemData); |
|
|
|
var r = {}; |
|
|
|
var i = 0, o = 0; |
|
|
|
// 解析固定头部信息 |
|
|
|
r.FixHead = {}; |
|
|
|
r.FixHead.MagicNumber = strTemData.substr(2 * i, 2); |
|
|
|
r.FixHead.Ver = strTemData.substring(2 * ++i, 2); |
|
|
|
r.FixHead.Len = (s[++i] << 8) + s[i + 1]; |
|
|
|
r.FixHead.CmdId = (s[i += 2] << 8) + s[i + 1]; |
|
|
|
r.FixHead.Seq = (s[i += 2] << 8) + s[i + 1]; |
|
|
|
i += 2; |
|
|
|
// 解析 ProtoBuf 的 BaseRequest 部分 |
|
|
|
r.ProtoBuf = {}; |
|
|
|
r.ProtoBuf.BaseRequest = {}; |
|
|
|
r.ProtoBuf.BaseRequest.Mark = strTemData.substr(2 * i, 2); |
|
|
|
i++; |
|
|
|
o = 0; |
|
|
|
//解析 ProtoBuf 的 BaseRequest 部分长度 |
|
|
|
o += s[i]; |
|
|
|
r.ProtoBuf.BaseRequest.Data = strTemData.substr(2 * ++i, 2 * o); |
|
|
|
i += o; |
|
|
|
// 解析 ProtoBuf 的 Data 部分 |
|
|
|
r.ProtoBuf.Data = {}; |
|
|
|
r.ProtoBuf.Data.Mark = strTemData.substr(2 * i, 2); |
|
|
|
i++; |
|
|
|
o = 0; |
|
|
|
// 解析 ProtoBuf 的 Data 部分长度 |
|
|
|
o += s[i]; |
|
|
|
while (205 === s[i]) { |
|
|
|
if(1 === s[i + 1] && 51 === s[i + 2]){ |
|
|
|
i++; |
|
|
|
} |
|
|
|
isPagFinish = true; // 标记分页完成 |
|
|
|
rxCount += 1; // 接收到的包计数+1 |
|
|
|
|
|
|
|
// 解析接收到的完整数据 |
|
|
|
const completeData = _kcUtils2.default.hexStr2byteArray(strTemData); |
|
|
|
|
|
|
|
// 初始化解析对象 |
|
|
|
let parsedData = {}; |
|
|
|
let index = 0; |
|
|
|
// 解析固定头部 |
|
|
|
const headFields = [ |
|
|
|
// 魔数 |
|
|
|
{ key: "MagicNumber", size: 1 }, |
|
|
|
// 版本号 |
|
|
|
{ key: "Ver", size: 1 }, |
|
|
|
// 长度 |
|
|
|
{ key: "Len", size: 2 }, |
|
|
|
// 命令ID |
|
|
|
{ key: "CmdId", size: 2 }, |
|
|
|
// 序列号 |
|
|
|
{ key: "Seq", size: 2 } |
|
|
|
]; |
|
|
|
// 解析固定头部 |
|
|
|
parsedData.FixHead = {}; |
|
|
|
headFields.forEach(field => { |
|
|
|
if (field.size === 1) { |
|
|
|
parsedData.FixHead[field.key] = completeData[index]; |
|
|
|
index += 1; |
|
|
|
} else { |
|
|
|
parsedData.FixHead[field.key] = (completeData[index] << 8) + completeData[index + 1]; |
|
|
|
index += 2; |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// 解析 ProtoBuf 数据 |
|
|
|
parsedData.ProtoBuf = {}; |
|
|
|
parsedData.ProtoBuf.BaseRequest = {}; |
|
|
|
parsedData.ProtoBuf.BaseRequest.Mark = strTemData.substr(2 * index, 2); // BaseRequest标记 |
|
|
|
index++; |
|
|
|
|
|
|
|
// 解码 BaseRequest 数据长度 |
|
|
|
var length = 0, shift = 0; |
|
|
|
while ((128 & completeData[index]) === 128) { |
|
|
|
length += (127 & completeData[index]) << (7 * shift); |
|
|
|
index++; |
|
|
|
shift++; |
|
|
|
} |
|
|
|
length += (127 & completeData[index]) << (7 * shift); |
|
|
|
index++; |
|
|
|
|
|
|
|
// 提取 BaseRequest 数据 |
|
|
|
parsedData.ProtoBuf.BaseRequest.Data = strTemData.substr(2 * index, 2 * length); |
|
|
|
index += length; |
|
|
|
|
|
|
|
// 解析 Data 部分 |
|
|
|
parsedData.ProtoBuf.Data = {}; |
|
|
|
parsedData.ProtoBuf.Data.Mark = strTemData.substr(2 * index, 2); // Data标记 |
|
|
|
index++; |
|
|
|
|
|
|
|
// 解码 Data 数据长度 |
|
|
|
length = 0; |
|
|
|
shift = 0; |
|
|
|
const veLength = findVarint(completeData.slice(index, completeData.length)); |
|
|
|
let tempLength = decodeVarint(veLength.varint); |
|
|
|
console.log("解码 Data 前:", completeData[index]); |
|
|
|
console.log("解码 Data index 前:", index); |
|
|
|
// 检查 length 是否超出范围 |
|
|
|
if (index + tempLength > completeData.length) { |
|
|
|
veLength.endPos -= 1; |
|
|
|
veLength.varint = veLength.varint.slice(0, veLength.endPos); |
|
|
|
let tempVarint = encodeVarint(veLength.varint); |
|
|
|
length = decodeVarint(tempVarint); |
|
|
|
index += veLength.endPos; |
|
|
|
} else { |
|
|
|
while ((128 & completeData[index]) === 128) { |
|
|
|
length += (127 & completeData[index]) << (7 * shift); |
|
|
|
index++; |
|
|
|
shift++; |
|
|
|
} |
|
|
|
length += (127 & completeData[index]) << (7 * shift); |
|
|
|
index++; |
|
|
|
} |
|
|
|
r.ProtoBuf.Data.Data = strTemData.substr(2 * ++i, 2 * o); |
|
|
|
i += o; |
|
|
|
// 解析 ProtoBuf 的 DataType 部分 |
|
|
|
r.ProtoBuf.DataType = {}; |
|
|
|
r.ProtoBuf.DataType.Mark = strTemData.substr(2 * i, 2); |
|
|
|
i++; |
|
|
|
o = 0; |
|
|
|
o += s[i]; |
|
|
|
i++; |
|
|
|
r.ProtoBuf.DataType.Varint = o; |
|
|
|
// 计算并校验数据包的校验和 |
|
|
|
var n = _kcUtils2.default.hexStr2byteArray(r.ProtoBuf.Data.Data); |
|
|
|
for (var f = 1; f < n.byteLength - 1; f++) { |
|
|
|
e ^= n[f]; |
|
|
|
console.log("解码 Data 后:", completeData[index]); |
|
|
|
console.log("解码 Data index 后:", index); |
|
|
|
|
|
|
|
// 提取 Data 数据 |
|
|
|
parsedData.ProtoBuf.Data.Data = strTemData.substr(2 * index, 2 * length); |
|
|
|
index += length; |
|
|
|
|
|
|
|
// 解析 DataType 部分 |
|
|
|
parsedData.ProtoBuf.DataType = {}; |
|
|
|
parsedData.ProtoBuf.DataType.Mark = strTemData.substr(2 * index, 2); // DataType标记 |
|
|
|
index++; |
|
|
|
|
|
|
|
// 解码 DataType 数据长度 |
|
|
|
length = 0; |
|
|
|
shift = 0; |
|
|
|
while ((128 & completeData[index]) === 128) { |
|
|
|
length += (127 & completeData[index]) << (7 * shift); |
|
|
|
index++; |
|
|
|
shift++; |
|
|
|
} |
|
|
|
// 校验失败处理 |
|
|
|
if (n[n.byteLength - 1] != e) { |
|
|
|
length += (127 & completeData[index]) << (7 * shift); |
|
|
|
index++; |
|
|
|
|
|
|
|
// 提取 Varint 数据 |
|
|
|
parsedData.ProtoBuf.DataType.Varint = length; |
|
|
|
|
|
|
|
// 校验数据完整性 |
|
|
|
var dataContent = _kcUtils2.default.hexStr2byteArray(parsedData.ProtoBuf.Data.Data); |
|
|
|
for (var i = 1; i < dataContent.byteLength - 1; i++) { |
|
|
|
checksum ^= dataContent[i]; // 计算校验和 |
|
|
|
} |
|
|
|
|
|
|
|
if (dataContent[dataContent.byteLength - 1] !== checksum) { |
|
|
|
// 如果校验失败 |
|
|
|
_kcUtils2.default.showError("kc第", rxCount, " 包校验bcc:Error!"); |
|
|
|
a.serviceCode = -1; |
|
|
|
a.serviceInfo = "校验错误。。。"; |
|
|
|
return a; |
|
|
|
result.serviceCode = -1; |
|
|
|
result.serviceInfo = "bcc 校验错误。。。"; |
|
|
|
return result; |
|
|
|
} |
|
|
|
// 检查并处理多包数据 |
|
|
|
if (128 === (128 & n[2])) { |
|
|
|
bleCount = 1 + (127 & n[2]); |
|
|
|
|
|
|
|
// 如果校验成功,解析大包信息 |
|
|
|
if ((128 & dataContent[2]) === 128) { |
|
|
|
bleCount = 1 + (127 & dataContent[2]); // 总包数 |
|
|
|
_kcUtils2.default.showLog("总共:", bleCount, "大包"); |
|
|
|
} |
|
|
|
strRxBuffer += r.ProtoBuf.Data.Data.substr(8, 2 * n[3]); |
|
|
|
// 打印调试信息 |
|
|
|
|
|
|
|
// 累加接收到的有效数据 |
|
|
|
strRxBuffer += parsedData.ProtoBuf.Data.Data.substr(8, 2 * dataContent[3]); |
|
|
|
console.log("kc第", rxCount, " 包校验bcc:ok!"); |
|
|
|
_kcUtils2.default.showLog("接受完第", rxCount, "大包数据,内容 ", strTemData); |
|
|
|
} |
|
|
|
|
|
|
|
// 判断接收是否完成 |
|
|
|
// 判断是否所有包接收完成 |
|
|
|
if (bleCount <= rxCount) { |
|
|
|
a.serviceCode = 0; |
|
|
|
a.serviceInfo = "数据接收完成!"; |
|
|
|
a.serviceData = {}; |
|
|
|
a.serviceData.strData = strRxBuffer; |
|
|
|
result.serviceCode = 0; // 数据接收完成 |
|
|
|
result.serviceInfo = "数据接收完成!"; |
|
|
|
result.serviceData = { strData: strRxBuffer }; // 返回接收的数据 |
|
|
|
} else { |
|
|
|
a.serviceCode = 1; |
|
|
|
a.serviceInfo = "数据接收中。。。"; |
|
|
|
result.serviceCode = 1; // 数据接收中 |
|
|
|
result.serviceInfo = "数据接收中。。。"; |
|
|
|
} |
|
|
|
return a; |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
function init() { |
|
|
|
rxCount = iPackageLen = 0, |
|
|
|
isPagFinish = !(strRxBuffer = strTemData = "") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 对单个数值进行 Varint 编码 |
|
|
|
* @param {number} val - 要编码的值 |
|
|
|
* @returns {number[]} - 编码后的字节数组 |
|
|
|
*/ |
|
|
|
function encodeSingleValue(val) { |
|
|
|
const bytes = []; |
|
|
|
while (val >= 0x80) { |
|
|
|
// 提取低 7 位,加上最高位 1 |
|
|
|
bytes.push((val & 0x7F) | 0x80); |
|
|
|
val >>= 7; // 右移 7 位 |
|
|
|
} |
|
|
|
// 添加最后一个字节,最高位为 0 |
|
|
|
bytes.push(val & 0x7F); |
|
|
|
return bytes; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 对单个值或 Uint8Array 进行 Varint 编码 |
|
|
|
* @param {number|Uint8Array} value - 要编码的值,可以是单个数值或 Uint8Array |
|
|
|
* @returns {Uint8Array} - 编码后的字节流 |
|
|
|
*/ |
|
|
|
function encodeVarint(value) { |
|
|
|
// 如果是 Uint8Array 类型 |
|
|
|
if (value instanceof Uint8Array) { |
|
|
|
const result = []; |
|
|
|
for (const v of value) { |
|
|
|
result.push(...encodeSingleValue(v)); // 对每个字节进行编码 |
|
|
|
} |
|
|
|
return new Uint8Array(result); // 返回 Uint8Array 类型的结果 |
|
|
|
} |
|
|
|
|
|
|
|
// 如果是单个值,直接编码 |
|
|
|
if (typeof value === 'number') { |
|
|
|
return new Uint8Array(encodeSingleValue(value)); |
|
|
|
} |
|
|
|
|
|
|
|
// 其他类型不支持,抛出错误 |
|
|
|
throw new TypeError("Input must be a number or a Uint8Array."); |
|
|
|
} |
|
|
|
|
|
|
|
function encodeVarint1(value) { |
|
|
|
const bytes = []; |
|
|
|
while (value >= 0x80) { |
|
|
|
// 提取低 7 位,加上最高位 1 |
|
|
|
bytes.push((value & 0x7F) | 0x80); |
|
|
|
value >>= 7; // 右移 7 位 |
|
|
|
} |
|
|
|
// 添加最后一个字节,最高位为 0 |
|
|
|
bytes.push(value & 0x7F); |
|
|
|
return bytes; |
|
|
|
} |
|
|
|
|
|
|
|
function decodeVarint(bytes) { |
|
|
|
let result = 0; |
|
|
|
let shift = 0; |
|
|
|
for (let i = 0; i < bytes.length; i++) { |
|
|
|
const byte = bytes[i]; |
|
|
|
// 提取低 7 位并合成结果 |
|
|
|
result |= (byte & 0x7F) << shift; |
|
|
|
// 如果最高位是 0,结束解码 |
|
|
|
if ((byte & 0x80) === 0) { |
|
|
|
break; |
|
|
|
} |
|
|
|
shift += 7; |
|
|
|
} |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
module.exports = { |
|
|
|
decode_GB: decode_GB, |
|
|
|
decode_WX: decode_WX, |