BACnet 标签头的长度 5 不是五字节:怎样处理扩展长度与上下文
BACnet 标签头低三位的 LVT=5 表示后面跟扩展长度,不表示内容恰好五字节。解析器还要识别应用/上下文标志、扩展标签号,以及上下文 opening、closing 标签,之后才能确定数据边界。
适用版本与输入范围
依据维护者 bacnet-stack 固定标签 bacnet-stack-1.4.0 的下列源码解释公开实现子集。该参考不是 ASHRAE 标准全文;涉及具体楼控设备时仍需记录型号、固件和对象支持范围。 本文所有输入均为原创合成数据,未接真实设备。
先拆标签号、类别与LVT
首字节高四位给标签号,中间一位给应用或上下文类别,低三位给Length/Value/Type。附件21 2A表示应用标签2、一字节内容;F9 14 01则先遇标签号15的扩展标志,下一字节14才给实际上下文标签号20,随后读取一字节值。若总以高四位作为最终标签号,所有扩展标签都会被误归为15,工程字段对应关系随即丢失。
扩展长度需要继续读取长度编码
当LVT为5时,程序读取下一字节;若该字节为254或255,还需再读两字节或四字节长度。示例65 05后面才是五字节内容,两个连续的5分别表示扩展标志和具体长度,含义不同。算法每次前进游标都先确认长度字段完整,再比较内容末尾与输入总长度,拒绝读到一半的值。长度字段是字节数,不是字符数,也不是数组元素数。
构造边界没有普通负载
上下文LVT=6与7分别表示opening与closing,示例3E与3F围住上下文标签3对应的构造内容。它们不能被读成六字节或七字节普通值。本附件单独展示每一个标签的结构,没有尝试解析整棵嵌套服务树;正式服务解析器仍需按预期语法配对开闭标签。应用Boolean也是特殊情况,本程序明确拒绝交给通用长度分支,避免把真值当成后续内容长度。
先保证边界,再解释业务类型
输出tag、context、kind、length和payload_hex,故意先不解释温度、对象或属性含义。相同标签号在不同上下文中可能代表不同字段,应用标签则有自身类型;后续解析必须结合服务结构。本题的截短负例只给扩展长度五却只有一字节内容,报告结构错误而非无值。工程日志应保存原始报文及游标位置,不要把读不出的字节直接丢弃后继续生成正常点位。
下载与复跑
将输入 fixture.json与独立程序 verify.py放在同一目录,用 Python 3.12 执行 python verify.py,无需安装第三方包。程序从自身目录读取输入并写入 report.json,不要求当前终端恰好位于下载目录。也可查看本次实跑报告和复跑说明。
本次实际运行通过 6 条输入断言,包括标有“显式负例”的记录;负例以JSON字段承载,不会把下载文件本身做成损坏编码。tag与context需结合服务语法解释;payload_hex保留内容原字节,kind区分值和构造边界。 修改输入后应同时审查期望结果,不能只改断言数字让测试变绿。
对象或字段的基础关系可回到BACnet 对象与服务入门核对,更多接口入口在设备协议库。若需要把已确认的数据点接入展项编排,可了解SoftControl 展厅中控;具体接入能力以项目确认和实际测试为准。
一级依据
来源核对日期:2026-10-24。离线结果只证明给定输入的解析或计算行为;现场兼容性、响应时间、硬件准确度和具体产品支持均未测量。
相关阅读
留言讨论
评论发布后会被人工复核,违规内容将被删除。
如果发表没有反应,可以前往联系我们告诉我们。