node-zserial 1.0.31 → 1.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/zserial.js +32 -21
package/package.json
CHANGED
package/zserial.js
CHANGED
|
@@ -1035,8 +1035,10 @@ module.exports = function (RED) {
|
|
|
1035
1035
|
|
|
1036
1036
|
// 698(68-LEN 变体):68 LL LH C ... DATA ... FCS(2) 16 ;兼容 FE* 前导
|
|
1037
1037
|
function tryParse698Len(input) {
|
|
1038
|
-
//
|
|
1039
|
-
|
|
1038
|
+
// 统计 FE 前导(用于 used/frame 回到原始 input)
|
|
1039
|
+
let feCount = 0;
|
|
1040
|
+
while (feCount < input.length && input[feCount] === 0xFE) feCount++;
|
|
1041
|
+
const b = input.slice(feCount);
|
|
1040
1042
|
if (b.length < 6 || b[0] !== 0x68) return { ok: false };
|
|
1041
1043
|
|
|
1042
1044
|
// ---- 读取长度域 ----
|
|
@@ -1072,7 +1074,7 @@ module.exports = function (RED) {
|
|
|
1072
1074
|
// 掉电次数等业务回包通常远小于 2KB;超出则高度可疑,丢 1 字节推进重同步
|
|
1073
1075
|
const MAX_698_LEN_L = 2048;
|
|
1074
1076
|
if (L > MAX_698_LEN_L) {
|
|
1075
|
-
return { ok: false, used: 1, frame:
|
|
1077
|
+
return { ok: false, used: feCount + 1, frame: input.slice(0, feCount + 1), err: "698_LEN_TOO_LARGE" };
|
|
1076
1078
|
}
|
|
1077
1079
|
|
|
1078
1080
|
// 约束 2:控制域 C 在 b[3],不可能是 0x16(结束符)
|
|
@@ -1093,7 +1095,7 @@ module.exports = function (RED) {
|
|
|
1093
1095
|
// 若 expectedEnd 位置不是 0x16,说明起点错位或存在脏字节
|
|
1094
1096
|
// 这里消费 1 字节,避免死循环卡住
|
|
1095
1097
|
if (b[expectedEnd] !== 0x16) {
|
|
1096
|
-
return { ok: false, used: 1, frame:
|
|
1098
|
+
return { ok: false, used: feCount + 1, frame: input.slice(0, feCount + 1), err: "698_LEN_BAD_END" };
|
|
1097
1099
|
}
|
|
1098
1100
|
|
|
1099
1101
|
// ------------------------ FCS 校验(CRC-16/X.25) ------------------------
|
|
@@ -1117,8 +1119,8 @@ module.exports = function (RED) {
|
|
|
1117
1119
|
if (!fcsOK) {
|
|
1118
1120
|
return {
|
|
1119
1121
|
ok: false,
|
|
1120
|
-
used: expectedEnd + 1,
|
|
1121
|
-
frame:
|
|
1122
|
+
used: feCount + expectedEnd + 1,
|
|
1123
|
+
frame: input.slice(0, feCount + expectedEnd + 1),
|
|
1122
1124
|
fcs_ok: false,
|
|
1123
1125
|
fcs_frame: fcs,
|
|
1124
1126
|
fcs_calc_a: calcA,
|
|
@@ -1130,8 +1132,8 @@ module.exports = function (RED) {
|
|
|
1130
1132
|
// FCS 通过:返回完整帧(含 0x68..0x16)
|
|
1131
1133
|
return {
|
|
1132
1134
|
ok: true,
|
|
1133
|
-
used: expectedEnd + 1,
|
|
1134
|
-
frame:
|
|
1135
|
+
used: feCount + expectedEnd + 1,
|
|
1136
|
+
frame: input.slice(0, feCount + expectedEnd + 1),
|
|
1135
1137
|
fcs_ok: true
|
|
1136
1138
|
};
|
|
1137
1139
|
}
|
|
@@ -1222,34 +1224,43 @@ module.exports = function (RED) {
|
|
|
1222
1224
|
continue;
|
|
1223
1225
|
}
|
|
1224
1226
|
if (r.used) {
|
|
1225
|
-
//
|
|
1226
|
-
|
|
1227
|
-
|
|
1227
|
+
// resync/drop1 类(通常 used 很小)不应上报 ERR_FRAME,否则会产生大量重复输出
|
|
1228
|
+
const used = r.used >>> 0;
|
|
1229
|
+
const frameBuf = r.frame ? Buffer.from(r.frame) : null;
|
|
1230
|
+
const frameLen = frameBuf ? frameBuf.length : 0;
|
|
1231
|
+
|
|
1232
|
+
// 判定是否为“仅推进同步点”的消费:
|
|
1233
|
+
// - used == 1 或 frameLen <= 1:典型 drop1
|
|
1234
|
+
// - 或 err 属于已知的 resync 类原因
|
|
1235
|
+
const errCode = (r && r.err) ? String(r.err) : "";
|
|
1236
|
+
const isResyncDrop = (used <= 1) || (frameLen <= 1) ||
|
|
1237
|
+
errCode === "DROP_7E_BADFRAME" ||
|
|
1238
|
+
errCode === "645_BAD_SHAPE_DROP1" ||
|
|
1239
|
+
errCode === "698_LEN_BAD_END" ||
|
|
1240
|
+
errCode === "698_LEN_TOO_LARGE" ||
|
|
1241
|
+
errCode === "645_SECOND_68_NOT_FOUND";
|
|
1242
|
+
|
|
1243
|
+
if (!isResyncDrop) {
|
|
1244
|
+
// 只有“闭合候选帧但校验/结构失败”的情况才上报 ERR_FRAME
|
|
1228
1245
|
try {
|
|
1229
1246
|
if (r.frame) {
|
|
1230
|
-
// 统一把元数据挂到 frame 上,避免引用未定义变量导致运行期异常
|
|
1231
1247
|
r.frame._meta = Object.assign({}, r.frame._meta || {}, {
|
|
1232
|
-
// proto:用于上层区分到底是 645 / 698-hdlc / 698-len / ble 等
|
|
1233
1248
|
proto: (r.fcs_ok === false) ? '698-len' : (r.proto || undefined),
|
|
1234
|
-
// FCS 校验信息(仅当 698-LEN 校验失败时有意义)
|
|
1235
1249
|
fcs_ok: (typeof r.fcs_ok === 'boolean') ? r.fcs_ok : undefined,
|
|
1236
1250
|
fcs_frame: r.fcs_frame,
|
|
1237
1251
|
fcs_calc_a: r.fcs_calc_a,
|
|
1238
1252
|
fcs_calc_b: r.fcs_calc_b,
|
|
1239
|
-
// err:更精确的错误原因
|
|
1240
1253
|
err: r.err || "FRAME_INVALID"
|
|
1241
1254
|
});
|
|
1242
1255
|
}
|
|
1243
1256
|
} catch (e) {
|
|
1244
|
-
// ignore
|
|
1257
|
+
// ignore
|
|
1245
1258
|
}
|
|
1259
|
+
emitErr(r.frame, errCode || "FRAME_INVALID");
|
|
1246
1260
|
}
|
|
1247
1261
|
|
|
1248
|
-
//
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
// 消费掉该段,防止 assembleBuf 卡死
|
|
1252
|
-
assembleBuf = assembleBuf.slice(r.used);
|
|
1262
|
+
// 无论是否上报,都必须消费,防止 assembleBuf 卡死
|
|
1263
|
+
assembleBuf = assembleBuf.slice(used);
|
|
1253
1264
|
continue;
|
|
1254
1265
|
}
|
|
1255
1266
|
break; // 需要更多数据
|