node-zserial 1.0.18 → 1.0.20

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/zserial.js +55 -15
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-zserial",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "description": "Node-RED nodes to talk to serial ports",
5
5
  "dependencies": {
6
6
  "serialport": "^12.0.0"
package/zserial.js CHANGED
@@ -697,7 +697,7 @@ module.exports = function (RED) {
697
697
  var olderr = "";
698
698
  var setupSerial = function () {
699
699
  obj._retryNum++;
700
- RED.log.info(obj._retryNum)
700
+ // RED.log.info(obj._retryNum)
701
701
  if (obj._retryNum > retryNum) {
702
702
  // serialPool.zlog("已经重试" + retryNum + "次,请检查串口是否正常!", {});
703
703
  obj._emitter.emit('retryerror', id, retryNum);
@@ -812,21 +812,61 @@ module.exports = function (RED) {
812
812
 
813
813
  // 645:FE* 68 + 6 addr + 68 + ctrl + len + data + cs + 16
814
814
  function tryParse645(input) {
815
- let b = stripFE(input);
815
+ // 统计 FE 前导(仅用于 used,不参与 CS 计算)
816
+ let feCount = 0;
817
+ while (feCount < input.length && input[feCount] === 0xFE) feCount++;
818
+ const b = input.slice(feCount);
816
819
  if (b.length < 12) return { ok: false };
817
- if (b[0] !== 0x68) return { ok: false };
818
- if (b.length >= 8 && b[7] !== 0x68) return { ok: false }; // 第二个 0x68
819
- const dataLen = b[9] >>> 0;
820
- const total = 12 + dataLen;
821
- if (b.length < total) return { ok: false }; // 半包
822
- const csIdx = total - 2, endIdx = total - 1;
823
- const csExpect = sum8(b, 8, csIdx);
824
- const csGot = b[csIdx];
825
- const endFlag = b[endIdx];
826
- const frame = b.slice(0, total);
827
- if (endFlag !== 0x16) return { ok: false, used: total, frame, err: "645_END_FLAG_16_MISSING" };
828
- if (csGot !== csExpect) return { ok: false, used: total, frame, err: "645_CHECKSUM_MISMATCH" };
829
- return { ok: true, used: total, frame };
820
+
821
+ // 形态:68 + addr(6) + 68 + CTRL + LEN + DATA + CS + 16
822
+ if (b[0] !== 0x68) {
823
+ const n = b.indexOf(0x68, 1);
824
+ if (n > 0) return { ok: false, used: feCount + n, frame: input.slice(0, feCount + n), err: "645_NO_68_AT_START" };
825
+ return { ok: false };
826
+ }
827
+ if (b.length >= 8 && b[7] !== 0x68) {
828
+ const n = b.indexOf(0x68, 1);
829
+ if (n > 0) return { ok: false, used: feCount + n, frame: input.slice(0, feCount + n), err: "645_SECOND_68_NOT_FOUND" };
830
+ return { ok: false };
831
+ }
832
+ if (b.length < 10) return { ok: false }; // 还缺 CTRL/LEN
833
+
834
+ const len = b[9] >>> 0;
835
+ const total = 12 + len; // 帧总长(含 CS 与 0x16)
836
+ const endIdx = total - 1; // 末尾 0x16 索引
837
+ const csIdx = total - 2; // ★ CS 在倒数第2个字节
838
+
839
+ // CS = 从第一个 0x68 起累加到 CS 之前(不含 CS)
840
+ const csOK = (end) => {
841
+ const e = end; // e == total
842
+ const cs = b[e - 2]; // csIdx
843
+ const s = sum8(b, 0, e - 2);
844
+ return cs === s;
845
+ };
846
+
847
+ // 1) 优先按 LEN 快速命中
848
+ if (b.length >= total && b[endIdx] === 0x16 && csOK(total)) {
849
+ return { ok: true, used: feCount + total, frame: input.slice(0, feCount + total) };
850
+ }
851
+
852
+ // 2) 回溯:向后找 0x16 做候选结尾,再校验 CS(兼容异常 LEN/粘包)
853
+ for (let end = 12; end <= b.length; end++) {
854
+ if (b[end - 1] !== 0x16) continue;
855
+ // 候选帧至少要有 …… + CS + 16,因此 end >= 13 且 csIdx=end-2 >= 0
856
+ if (end >= 13) {
857
+ const cs = b[end - 2];
858
+ const s = sum8(b, 0, end - 2);
859
+ if (cs === s) {
860
+ return { ok: true, used: feCount + end, frame: input.slice(0, feCount + end) };
861
+ }
862
+ }
863
+ }
864
+
865
+ // 3) 起始形态确定不对则丢 1 字节;否则继续等
866
+ if (b.length >= 8 && b[7] !== 0x68) {
867
+ return { ok: false, used: feCount + 1, frame: input.slice(0, feCount + 1), err: "645_BAD_SHAPE_DROP1" };
868
+ }
869
+ return { ok: false };
830
870
  }
831
871
 
832
872
  // 698(68-LEN 变体):68 LL LH C ... DATA ... CS 16 ;兼容 FE* 前导