国网CMS(变电站二次系统通信报文规范)逐字节解码例
这方面的资料网上较少,AI解答比较碎片化,所以本人查阅了多个规范,比对抓包的报文做了一个典型的分析,供大家参考
数据编码
数据编码使用GB/T 16263.2或GB/T 33602规定的编码规则。使用GB/T 16263.2编码规则时,应采用BASIC-PER对齐编码方式。
和 BER 完全不同:PER 不传输 Tag,编码 / 解码必须预先知道 ASN.1 类型定义,不能脱离 schema 裸流自解析,也就是说结构体中的成员与需要与协议语法一一对应。
SEQUENCE 里 OPTIONAL/DEFAULT 成员:用存在位图(presence bitmap)标记哪些字段存在。
报文解析
下面是一段GetBRCBValues(读缓存报告控制块值) (91),ASDU应答报文:
0000 a9 00 80 01 e2 a0 4c 44 30 2f 4c 4c 4e 30 24 42
0010 52 24 62 72 63 62 41 6c 61 72 6d 8b 80 54 53 53
0020 31 30 30 4d 4c 44 30 2f 4c 4c 4e 30 2e 64 73 41
0030 6c 61 72 6d 01 01 7d 80 01 00 00 0b 48 03 04 93
0040 e0 00 00 00 00 00 00 00 00 0b 20 24 01 10 06 00
0050 80 64 0e 19 20 16 80 27 01 99 00
a9 00 ReqID(服务请求序号): 169 80 01 80表示moreFollows(80=false;00=true)从规范中没有找到出处,01表示brcb[1..n]数组大小n e2 a0 brcb可选项PresenceBitmap(0b1),value可选项PresenceBitmap(0b11),rptID描述串的长度VisibleString129长度用1字节表示21(0b00010101),剩下补齐5位 (00000),0b1110 0010 1010 0000 … LD0/LLN0$BR$brcbAlarm 8b 80 rptEna:true(1),datSet描述串的长度VisibleString129长度用1字节表示23(0b0001 0111) ,剩下补齐6位(00000),0b1000 1011 1000 0000 … TSS100MLD0/LLN0.dsAlarm 01 01 confRev INT32U可变长编码01表示长度,01为值 7d 80 optFlds RCBOptFlds(SIZE10)占2字节 01 00 bufTm INT32U,可变长编码01表示长度,00为值 00 0b sqNum INT16U,固定2字节 48 trgOps TriggerConditions(SIZE6)占1字节 03 04 93 e0 intgPd INT32U,可变长编码03表示长度 00 gi ,purgeBuf 00 00 00 00 00 00 00 0b EntryID长度固定为8字节 20 24 01 10 06 00 EntryTime长度固定为6字节 80 64 resvTms INT16,有符号数 0e 19 20 16 80 27 01 99 owner OCTET STRING(SIZE(0..64)),长度为7位(0b0000111) 00 moreFollows,false(0)这个与上面的moreFollows相反???wireshark抓包: