Bladeren bron

更新科畅sdk

master
yangteng 5 maanden geleden
bovenliggende
commit
e572044cb9

+ 1
- 0
static/etc/kcBle/kcBleAPI.js Bestand weergeven

@@ -254,6 +254,7 @@ function scanBle(outTime, ScanDeviceResultCallBack) {
function etcHandleDeviceFound(res) {
for (let i = 0; i < res.devices.length; i++) {
let isHave = false;
console.log(res.devices[i].name);
for (let j = 0; j < foundDevices.length; j++) {
if (res.devices[i].deviceId === foundDevices[j].deviceId) {
isHave = true;

+ 230
- 88
static/etc/kcBle/kcDataDecode.js Bestand weergeven

@@ -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,

+ 2
- 3
static/etc/kcBle/kcService.js Bestand weergeven

@@ -82,14 +82,14 @@ function reallyScanConnect(s) {
})
}
function reallyConnect(device, callback) {
console.log("WeiXin ble SDK 20240606");
console.log("WeiXin ble SDK 20250107");
var result = {
code: -2,
msg: '连接失败'
};
var deviceName = device.device_name;
console.log("name", deviceName);
if (deviceName.includes("ETC-KC-") || deviceName.includes("K")) {
if (deviceName.includes("ETC-KC-")) {
connectedDeviceId = device.device_id;
wx.createBLEConnection({
deviceId: connectedDeviceId,
@@ -203,7 +203,6 @@ function _enableService(callback) {
serviceId: uuid,
success: function (charRes) {
var matchedChars = charRes.characteristics.filter(char => containsNotifyInPrefix(char.uuid) || containsWriteInPrefix(char.uuid)).length;
console.log("matchedChars", matchedChars);
if (matchedChars < 2) {
result.serviceCode = -1;
result.serviceInfo = "getBLEDeviceCharacteristics temp<2!";

+ 36
- 0
static/etc/kcBle/protoBuffer.js Bestand weergeven

@@ -0,0 +1,36 @@
// protoBuffer.js
import VarintElement from './varintElement.js'; // 导入 VarintElement

function findVarint(hexData) {
// hexData 是 Uint8Array,直接遍历字节
// 定义返回对象,初始化为 null
let ret = null;
for (let i = 0; i < hexData.length; i++) {
// 检查最高位是否为 1(即 & 0x80 是否非零)
if ((hexData[i] & 0x80) !== 0) {
continue; // 如果最高位为 1,则继续检查下一个字节
}

// 找到 Varint 终止字节
ret = new VarintElement();
ret.endPos = i + 1; // 结束位置,以字节为单位
ret.varint = hexData.slice(0, i + 1); // 提取 Varint 部分,返回 Uint8Array

// 如果需要将 varint 转换为字符串格式
/*
ret.varint = Array.from(hexData.slice(0, i + 1)) // 转为数组
.map(byte => byte.toString(16).padStart(2, '0')) // 转为两位十六进制字符串
.join(' ')
.toUpperCase();
*/

// 退出循环
break;
}

// 如果未找到 Varint 终止字节,返回 null
return ret;
}

// 使用 module.exports 导出
module.exports = { findVarint };

+ 18
- 0
static/etc/kcBle/varintElement.js Bestand weergeven

@@ -0,0 +1,18 @@

class VarintElement {
constructor() {
// 初始化属性
this.endPos = 0; // 结束位置
this.varint = new Uint8Array(); // 初始化为空的 Uint8Array
}
// 转换为字符串表示
toString() {
// 将 Uint8Array 转换为字符串(以十六进制形式或其他格式)
return Array.from(this.varint)
.map(byte => byte.toString(16).padStart(2, '0')) // 转为两位十六进制字符串
.join(' ');
}
}

// 使用 export 导出
export default VarintElement;

Laden…
Annuleren
Opslaan