7 Efficient XML编解码库
7.9 编码错误原因分析与结论
在前面两小节中,作者发现个别命令使用Efficient XML库编码得到的EXI结果与EXICodec.jar结果不同,而且不能互相解码。这将导致EVCC和SECC之间通信失败,带来严重的后果。因此必须分析编码结果不同的原因。
本节重点分析ChargeParameterDiscoveryRes编码过程。
json:
{
"V2G_Message": {
"Header": {
"Signature": {
"SignatureValue": {
"value": "MEUCICSta1OLLMIo3/H59qg4Dareuy/+UDr6p6fb/9TRPlFRAiEAx09IkrD7wL1f220dNKwH83WxRY6Yngx1BjAj3vMTDHw="
},
"SignedInfo": {
"Reference": [{
"Transforms": {
"Transform": [{
"Algorithm": "http://www.w3.org/TR/canonical-exi/"
}]
},
"DigestMethod": {
"Algorithm": "http://www.w3.org/2001/04/xmlenc#sha256"
},
"DigestValue": "FOPYeuJCS2wwX9XxiiT+Ly9ofNZY1Zu+UafOP1zwhvA=",
"URI": "#id1"
}],
"CanonicalizationMethod": {
"Algorithm": "http://www.w3.org/TR/canonical-exi/"
},
"SignatureMethod": {
"Algorithm": "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"
}
}
},
"SessionID": "225FFA52C1BDAE2F"
},
"Body": {
"ChargeParameterDiscoveryRes": {
"ResponseCode": "OK",
"EVSEProcessing": "Finished",
"AC_EVSEChargeParameter": {
"EVSEMaxCurrent": {
"Multiplier": 0,
"Value": 32,
"Unit": "A"
},
"AC_EVSEStatus": {
"RCD": false,
"NotificationMaxDelay": 0,
"EVSENotification": "None"
},
"EVSENominalVoltage": {
"Multiplier": 0,
"Value": 400,
"Unit": "V"
}
},
"SAScheduleList": {
"SAScheduleTuple": [{
"PMaxSchedule": {
"PMaxScheduleEntry": [{
"PMax": {
"Multiplier": 0,
"Value": 11000,
"Unit": "W"
},
"RelativeTimeInterval": {
"duration": 3600,
"start": 0
}
}]
},
"SAScheduleTupleID": 1,
"SalesTariff": {
"SalesTariffID": 10,
"NumEPriceLevels": 2,
"SalesTariffEntry": [{
"RelativeTimeInterval": {
"start": 0
},
"EPriceLevel": 1
}, {
"RelativeTimeInterval": {
"duration": 1799,
"start": 1801
},
"EPriceLevel": 2
}],
"Id": "id1"
}
}]
}
}
}
}
}
根据编码得到的exi,对比其他工具的编码结果,分析错误出现在Header.Signature.SignedInfo.CanonicalizationMethod字段编码前后。这个字段之前的编码数据都是相同的,在此之后,紧跟着的SignatureMethod字段编码就出现了分歧。这几个工具的编码结果都不一样,第一个不同的字节(第49字节)出现了好几种(C1/D0/E1) 。
作者推测各个工具内部对规范的实现还有微小差别, 这些差别造成了工具之间的数据不能互相解码。
Efficient XML库编码片段
E1 30 A2 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 04 35
11100001 00110000 10100010 00000010 00000010 00000010 00000010 ....
cbexigen编码片段
D0 D5 A1 D1 D1 C0 E8 BC BD DD DD DC B9 DC CC B9
11010000 11010101
ExiCodec.jar原始捕捉的数据:
C1 00 09 80 50
11000001 00000000
所以确定是CanonicalizationMethod这个数据之后出现了编码分歧~~~~·
第49字节的前2位是11,属于字段CanonicalizationMethod编码内容,紧接着的2位就是SignatureMethod字段的开始事件, 这时三种工具出现了3种事件代码: 10,01,00。
仔细分析CanonicalizationMethod字段类型,从对应的xsd中发现了隐藏<any>标签:
<element name="CanonicalizationMethod" type="ds:CanonicalizationMethodType"/>
<complexType name="CanonicalizationMethodType" mixed="true">
<sequence>
<any namespace="##any" minOccurs="0" maxOccurs="unbounded"/>
<!-- (0,unbounded) elements from (1,1) namespace -->
</sequence>
<attribute name="Algorithm" type="anyURI" use="required"/>
</complexType>
最终得到的结论是各种编码器对<any>标签的事件编码不同。
虽然各个编码器都能自编自解,但是这样特殊的命令编码结果不能互相解码导致不能使用在充电桩系统通信方面。 作者向agiledelta公司反馈这个问题,但是该公司坚持自己的编码器是标准的可靠的,无法对此问题给与支持。最终作者只能放弃Efficient XML编解码库,寻找其它更适合的编解码库。