node-zserial 1.0.31 → 1.0.33
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 +2 -2
- package/zserial.js +41 -21
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-zserial",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.33",
|
|
4
4
|
"description": "Node-RED nodes to talk to serial ports",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"serialport": "^12.0.0"
|
|
7
7
|
},
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/bensonzhow/node-red-zserialport.git"
|
|
10
|
+
"url": "git+https://github.com/bensonzhow/node-red-zserialport.git"
|
|
11
11
|
},
|
|
12
12
|
"keywords": [
|
|
13
13
|
"node-red",
|
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(结束符)
|
|
@@ -1080,6 +1082,15 @@ module.exports = function (RED) {
|
|
|
1080
1082
|
if (b.length >= 4 && b[3] === 0x16) {
|
|
1081
1083
|
return { ok: false };
|
|
1082
1084
|
}
|
|
1085
|
+
// 约束 3:控制域 C 必须看起来像 698 的控制域(功能码通常为 1=链路管理 或 3=用户数据)
|
|
1086
|
+
// 目的:避免 645 的地址字节被当成 698 控制域,从而把 645 整帧误判为 698-LEN 候选帧并被消费掉。
|
|
1087
|
+
// 698 控制域:bit0..bit3 为功能码(1 或 3 最常见);其他位为 DIR/PRM/分帧/扰码标志。
|
|
1088
|
+
const C = b[3] >>> 0;
|
|
1089
|
+
const func = C & 0x0F;
|
|
1090
|
+
if (!(func === 0x01 || func === 0x03)) {
|
|
1091
|
+
// 不消费任何字节,让 645 解析器继续尝试
|
|
1092
|
+
return { ok: false };
|
|
1093
|
+
}
|
|
1083
1094
|
// ------------------------------------------------------------------------
|
|
1084
1095
|
|
|
1085
1096
|
// 期望 0x16 的位置(相对 b 起点):1 + L
|
|
@@ -1093,7 +1104,7 @@ module.exports = function (RED) {
|
|
|
1093
1104
|
// 若 expectedEnd 位置不是 0x16,说明起点错位或存在脏字节
|
|
1094
1105
|
// 这里消费 1 字节,避免死循环卡住
|
|
1095
1106
|
if (b[expectedEnd] !== 0x16) {
|
|
1096
|
-
return { ok: false, used: 1, frame:
|
|
1107
|
+
return { ok: false, used: feCount + 1, frame: input.slice(0, feCount + 1), err: "698_LEN_BAD_END" };
|
|
1097
1108
|
}
|
|
1098
1109
|
|
|
1099
1110
|
// ------------------------ FCS 校验(CRC-16/X.25) ------------------------
|
|
@@ -1117,8 +1128,8 @@ module.exports = function (RED) {
|
|
|
1117
1128
|
if (!fcsOK) {
|
|
1118
1129
|
return {
|
|
1119
1130
|
ok: false,
|
|
1120
|
-
used: expectedEnd + 1,
|
|
1121
|
-
frame:
|
|
1131
|
+
used: feCount + expectedEnd + 1,
|
|
1132
|
+
frame: input.slice(0, feCount + expectedEnd + 1),
|
|
1122
1133
|
fcs_ok: false,
|
|
1123
1134
|
fcs_frame: fcs,
|
|
1124
1135
|
fcs_calc_a: calcA,
|
|
@@ -1130,8 +1141,8 @@ module.exports = function (RED) {
|
|
|
1130
1141
|
// FCS 通过:返回完整帧(含 0x68..0x16)
|
|
1131
1142
|
return {
|
|
1132
1143
|
ok: true,
|
|
1133
|
-
used: expectedEnd + 1,
|
|
1134
|
-
frame:
|
|
1144
|
+
used: feCount + expectedEnd + 1,
|
|
1145
|
+
frame: input.slice(0, feCount + expectedEnd + 1),
|
|
1135
1146
|
fcs_ok: true
|
|
1136
1147
|
};
|
|
1137
1148
|
}
|
|
@@ -1222,34 +1233,43 @@ module.exports = function (RED) {
|
|
|
1222
1233
|
continue;
|
|
1223
1234
|
}
|
|
1224
1235
|
if (r.used) {
|
|
1225
|
-
//
|
|
1226
|
-
|
|
1227
|
-
|
|
1236
|
+
// resync/drop1 类(通常 used 很小)不应上报 ERR_FRAME,否则会产生大量重复输出
|
|
1237
|
+
const used = r.used >>> 0;
|
|
1238
|
+
const frameBuf = r.frame ? Buffer.from(r.frame) : null;
|
|
1239
|
+
const frameLen = frameBuf ? frameBuf.length : 0;
|
|
1240
|
+
|
|
1241
|
+
// 判定是否为“仅推进同步点”的消费:
|
|
1242
|
+
// - used == 1 或 frameLen <= 1:典型 drop1
|
|
1243
|
+
// - 或 err 属于已知的 resync 类原因
|
|
1244
|
+
const errCode = (r && r.err) ? String(r.err) : "";
|
|
1245
|
+
const isResyncDrop = (used <= 1) || (frameLen <= 1) ||
|
|
1246
|
+
errCode === "DROP_7E_BADFRAME" ||
|
|
1247
|
+
errCode === "645_BAD_SHAPE_DROP1" ||
|
|
1248
|
+
errCode === "698_LEN_BAD_END" ||
|
|
1249
|
+
errCode === "698_LEN_TOO_LARGE" ||
|
|
1250
|
+
errCode === "645_SECOND_68_NOT_FOUND";
|
|
1251
|
+
|
|
1252
|
+
if (!isResyncDrop) {
|
|
1253
|
+
// 只有“闭合候选帧但校验/结构失败”的情况才上报 ERR_FRAME
|
|
1228
1254
|
try {
|
|
1229
1255
|
if (r.frame) {
|
|
1230
|
-
// 统一把元数据挂到 frame 上,避免引用未定义变量导致运行期异常
|
|
1231
1256
|
r.frame._meta = Object.assign({}, r.frame._meta || {}, {
|
|
1232
|
-
// proto:用于上层区分到底是 645 / 698-hdlc / 698-len / ble 等
|
|
1233
1257
|
proto: (r.fcs_ok === false) ? '698-len' : (r.proto || undefined),
|
|
1234
|
-
// FCS 校验信息(仅当 698-LEN 校验失败时有意义)
|
|
1235
1258
|
fcs_ok: (typeof r.fcs_ok === 'boolean') ? r.fcs_ok : undefined,
|
|
1236
1259
|
fcs_frame: r.fcs_frame,
|
|
1237
1260
|
fcs_calc_a: r.fcs_calc_a,
|
|
1238
1261
|
fcs_calc_b: r.fcs_calc_b,
|
|
1239
|
-
// err:更精确的错误原因
|
|
1240
1262
|
err: r.err || "FRAME_INVALID"
|
|
1241
1263
|
});
|
|
1242
1264
|
}
|
|
1243
1265
|
} catch (e) {
|
|
1244
|
-
// ignore
|
|
1266
|
+
// ignore
|
|
1245
1267
|
}
|
|
1268
|
+
emitErr(r.frame, errCode || "FRAME_INVALID");
|
|
1246
1269
|
}
|
|
1247
1270
|
|
|
1248
|
-
//
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
// 消费掉该段,防止 assembleBuf 卡死
|
|
1252
|
-
assembleBuf = assembleBuf.slice(r.used);
|
|
1271
|
+
// 无论是否上报,都必须消费,防止 assembleBuf 卡死
|
|
1272
|
+
assembleBuf = assembleBuf.slice(used);
|
|
1253
1273
|
continue;
|
|
1254
1274
|
}
|
|
1255
1275
|
break; // 需要更多数据
|