3. HSMS消息格式详解:Message Header(10字节)结构、Session ID、Message ID、S/F类型解析
HSMS(High-Speed SECS Message Services)是SECS/GEM协议在TCP/IP网络上的传输层实现。所有设备间的通信数据,无论是控制消息还是数据消息,都必须封装在HSMS消息帧中传输。理解HSMS消息头的10字节结构,是进行设备连接调试、报文解析和故障定位的基础。
核心要点: HSMS消息头固定为10字节,包含会话标识、消息ID、优先级、S/F类型等关键字段。任何HSMS消息(包括控制消息和数据消息)都以此10字节头部开始。
3.1 HSMS消息帧整体结构
一个完整的HSMS消息帧由消息长度(4字节)和消息头(10字节)以及可选的消息正文组成。消息长度字段指示后续消息头+正文的总字节数。
3.2 10字节消息头字段详解
HSMS消息头的10个字节被划分为6个字段,每个字段承载特定的协议信息。下表列出了各字段的偏移位置、长度和用途:
| 字节偏移 | 字段名称 | 长度(字节) | 说明 |
|---|---|---|---|
| 0-1 | Session ID(设备ID) | 2 | 标识会话或设备,范围0-32767,高位bit15为0表示数据消息,为1表示控制消息 |
| 2 | Header Byte 2(保留/标志) | 1 | 通常为0x00;在某些实现中用于扩展标志位 |
| 3 | Header Byte 3(保留/标志) | 1 | 通常为0x00;在某些实现中用于扩展标志位 |
| 4-5 | Message ID(消息ID) | 2 | 消息的唯一标识,用于请求-响应匹配和消息去重 |
| 6 | S(Stream字节) | 1 | SECS消息的流编号(Stream),范围0-127;bit7为0表示数据消息,为1表示控制消息 |
| 7 | F(Function字节) | 1 | SECS消息的功能编号(Function),范围0-255;bit7为0表示Primary消息,为1表示Reply消息 |
| 8 | P/Bit(优先级/块标志) | 1 | bit7-6:优先级(0-3);bit5:块标志(0=非块,1=块);bit4-0:保留 |
| 9 | Header Byte 9(保留/系统字节) | 1 | 通常为0x00;在某些实现中用于系统扩展 |
调试提示: 在Wireshark或SECS调试工具中,10字节消息头通常以十六进制形式显示。例如:
00 01 00 00 00 05 01 01 00 00 表示Session ID=1,Message ID=5,S=1,F=1(Primary)。
3.3 Session ID(设备ID)深度解析
Session ID(也称为Device ID)是HSMS消息头的前2个字节,用于标识通信会话或设备。其结构如下:
关键规则:
- bit15(最高位):区分消息类型。0表示数据消息(携带SECS-II数据),1表示控制消息(用于连接管理)。
- bit14-bit0:15位设备ID,有效范围0-32767。在设备连接建立时由双方协商确定。
- 调试常见问题:Session ID不匹配是连接失败的常见原因之一。设备端和主机端必须使用相同的Session ID。
3.4 Message ID(消息ID)详解
Message ID是消息头的第4-5字节(2字节),用于唯一标识一条消息。它在请求-响应匹配中起关键作用:
- 唯一性:发送方为每条发出的消息分配一个唯一的Message ID,接收方在响应消息中回传相同的ID。
- 范围:0-65535(16位无符号整数)。
- 循环使用:Message ID通常从0开始递增,达到65535后回绕到0。
- 调试价值:通过Message ID可以追踪消息的请求-响应配对,判断是否存在超时或丢失。
常见陷阱: 某些设备实现中,Message ID的递增规则不标准(如跳跃式递增或固定值),这会导致主机端消息匹配逻辑异常。调试时应先确认Message ID的生成策略。
3.5 S/F类型解析:Stream与Function
S(Stream)和F(Function)是SECS-II消息的核心标识,共同决定消息的语义。S/F字节位于消息头的第6和第7字节。
3.5.1 Stream字节(第6字节)
- bit7:消息类型标志。0表示数据消息(Data Message),1表示控制消息(Control Message)。
- bit6-bit0:Stream编号,范围0-127。常见的Stream编号如:S1(设备状态)、S2(设备控制)、S6(数据收集)、S7(设备ID)等。
3.5.2 Function字节(第7字节)
- bit7:消息方向标志。0表示Primary(请求/主消息),1表示Reply(响应/从消息)。
- bit6-bit0:Function编号,范围0-127。每个Stream下包含多个Function。
S/F组合示例:
| S/F表示 | Stream | Function | 方向 | 含义 |
|---|---|---|---|---|
| S1F1 | 1 | 1 | Primary | Are You There?(设备状态查询) |
| S1F2 | 1 | 2 | Reply | Are You There? 的响应 |
| S6F11 | 6 | 11 | Primary | Data Report(数据上报) |
| S6F12 | 6 | 12 | Reply | Data Report 的确认 |
3.6 控制消息与数据消息的区分
HSMS协议定义了两种消息类型,通过Session ID的bit15和Stream字节的bit7共同标识:
| 消息类型 | Session ID bit15 | Stream字节 bit7 | 用途 | 示例 |
|---|---|---|---|---|
| 数据消息 | 0 | 0 | 承载SECS-II数据(设备状态、数据收集、控制命令等) | S1F1, S6F11 |
| 控制消息 | 1 | 1 | HSMS连接管理(建立、测试、关闭) | Select.req, Linktest.req |
调试实战要点: 在抓包分析时,如果看到Session ID的bit15为1,说明这是一个控制消息,不要尝试用SECS-II解析器去解析其正文。控制消息的正文格式由HSMS协议定义,而非SECS-II。
3.7 消息头完整示例解析
以下是一个实际的HSMS消息头十六进制数据,我们逐字节解析:
原始数据:00 0A 00 00 00 1E 01 01 00 00
字节0-1 (Session ID): 00 0A → 设备ID = 10 (bit15=0, 数据消息)
字节2-3 (保留): 00 00
字节4-5 (Message ID): 00 1E → 消息ID = 30
字节6 (Stream): 01 → Stream = 1 (bit7=0, 数据消息)
字节7 (Function): 01 → Function = 1 (bit7=0, Primary方向)
字节8 (P/Bit): 00 → 优先级=0, 非块消息
字节9 (保留): 00
解析结果:S1F1 (Are You There? 请求), 设备ID=10, 消息ID=30
3.8 调试常见问题与排查方法
- Session ID不匹配:设备端和主机端配置的Session ID不一致,导致消息被丢弃。检查双方配置文件。
- Message ID重复:短时间内出现相同的Message ID,可能导致响应匹配混乱。检查发送方ID生成逻辑。
- S/F方向错误:Primary消息的Function字节bit7应为0,Reply消息应为1。方向错误会导致接收方无法正确解析。
- 控制消息误解析:将控制消息(Session ID bit15=1)当作数据消息解析,导致乱码或解析失败。先判断消息类型。
推荐工具: 使用Wireshark配合SECS/GEM解析插件,可以直观地看到10字节消息头的每个字段。在调试初期,建议逐字节对照协议规范进行验证。