const { SerialPort } = require('serialport');
|
const PORT_NAME = 'COM9'; // 确认端口
|
|
// 尝试不同的目标节点和类型
|
const PROBES = [
|
{ dst: 0x53, type: 0x0F, desc: "Service Node: Get System Info" }, // 'S'
|
{ dst: 0x4D, type: 0x0F, desc: "Maint Node: Get System Info" }, // 'M'
|
{ dst: 0x53, type: 0x00, cond: 0x09, desc: "Service Node: Get Version (Cond=09)" },
|
{ dst: 0x4F, type: 0x0E, desc: "Operator Node: Service Request" } // 特殊类型
|
];
|
|
function buildProbe(dst, type, cond = 0x00) {
|
// 简化构建:Seq=01, Src=00, Param=0000, NumSpec=00 (无参数)
|
// 注意:如果没有 Spec,长度会变短
|
// 结构: Seq, Len, Src, Dst, Type, Cond, ParamH, ParamL, NumSpec
|
// 如果 NumSpec=0,后面就没有 SpecType/Idx
|
|
const numSpec = 0x00;
|
// Len = Src(1)+Dst(1)+Type(1)+Cond(1)+Param(2)+NumSpec(1) + CRC(1) = 8 (0x08)
|
const len = 0x08;
|
|
const raw = [0x01, len, 0x00, dst, type, cond, 0x00, 0x00, numSpec];
|
|
let sum = raw.reduce((a, b) => a + b, 0);
|
const crc = sum & 0xFF;
|
raw.push(crc);
|
|
// 转义
|
const special = new Set([0x02, 0x04, 0x06, 0x15, 0x1B]);
|
const escaped = [];
|
raw.forEach(b => {
|
if(special.has(b)) { escaped.push(0x1B); escaped.push((b+0x20)&0xFF); }
|
else escaped.push(b);
|
});
|
|
return Buffer.from([0x02, ...escaped, 0x04]);
|
}
|
|
async function runProbes() {
|
const port = new SerialPort({ path: PORT_NAME, baudRate: 9600 });
|
port.on('open', async () => {
|
console.log("🔍 开始探测维护模式...");
|
for (const p of PROBES) {
|
const pkt = buildProbe(p.dst, p.type, p.cond);
|
console.log(`\n尝试: ${p.desc}`);
|
console.log(`Hex: ${pkt.toString('hex').match(/.{1,2}/g).join(' ')}`);
|
|
port.write(pkt);
|
|
const resp = await new Promise(res => {
|
let t = setTimeout(() => res(null), 1000);
|
port.once('data', d => { clearTimeout(t); res(d); });
|
});
|
|
if (resp) {
|
if (resp[0] === 0x06) console.log("✅ SUCCESS! 发现隐藏入口!");
|
else if (resp[0] === 0x15) console.log("❌ NAK");
|
else console.log(`⚠️ 未知: ${resp.toString('hex')}`);
|
} else {
|
console.log("⏱️ 超时");
|
}
|
await new Promise(r => setTimeout(r, 300));
|
}
|
port.close();
|
});
|
}
|
runProbes();
|