第二章 EXI协议原理与实现--8.4 对-2/-20所有命令的测试结果
8.4 对ISO15118-2/-20所有命令的测试结果
上节对supportedAppProtocolReq/Res命令编解码结果与EXICodec.jar完全相同,cbExiGen初步测试成功。本节将对全部-2/-20命令展开测试,检查是否与EXICodec.jar完全相同。 作者编写了大量测试代码,解决了一些cbExiGen代码中的bug和问题,最终得到了结论: cbExiGen编解码和EXICodec.jar完全相同,通过了交叉测试,在实际的充电流程中也成功运行。
8.4.1 对ISO15118-2的测试
按照上节做法,对每个命令Req/Res编写测试代码, 每个文件包含请求和应答两条命令的编码和解码。
2023/10/07 10:38 5,612 test_AuthorizationReq.c
2023/10/07 10:38 6,388 test_CableCheckReq.c
2023/10/07 14:18 23,549 test_CertificateInstallationReq.c
2023/10/16 14:42 17,222 test_ChargeParameterDiscoveryReq.c
2023/10/07 10:39 6,370 test_ChargingStatusReq.c
2023/10/07 10:39 11,092 test_CurrentDemandReq.c
2023/10/07 10:39 10,506 test_MeteringReceiptReq.c
2023/10/07 10:39 17,953 test_PaymentDetailsReq.c
2023/10/07 10:39 6,291 test_PaymentServiceSelectionReq.c
2023/10/07 10:40 7,545 test_PowerDeliveryReq.c
2023/10/07 10:40 7,187 test_PreChargeReq.c
2023/10/07 10:40 6,469 test_ServiceDetailReq.c
2023/10/07 10:40 7,569 test_ServiceDiscoveryReq.c
2023/10/07 10:40 6,385 test_SessionSetupReq.c
2023/10/07 10:40 5,536 test_SessionStopReq.c
2023/10/07 15:50 4,974 test_supportedAppProtocolReq.c
2023/10/07 10:41 6,807 test_WeldingDetectionReq.c
示例代码 test_CertificateInstallationReq.c:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include "appHand_Encoder.h"
#include "iso2_msgDefDatatypes.h"
#include "iso2_msgDefEncoder.h"
#include "iso2_msgDefDecoder.h"
#include "base64Codec.h"
#include "ReadWriteFile.h"
//CertificateInstallationReq
//encode resule is OK!
static const uint8_t CertificateInstallationReq[] = {
0x80, 0x98, 0x02, 0x0B, 0xE0, 0xBE, 0xB9, 0x5B, 0xD1, 0x10, 0xB8, 0x8A, 0x89, 0x5A, 0x1D, 0x1D, 0x1C, 0x0E, 0x8B, 0xCB, 0xDD, 0xDD, 0xDD, 0xCB, 0x9D, 0xCC, 0xCB, 0x9B, 0xDC, 0x99, 0xCB, 0xD5, 0x14, 0x8B, 0xD8, 0xD8, 0x5B, 0x9B, 0xDB, 0x9A, 0x58, 0xD8, 0x5B, 0x0B, 0x59, 0x5E, 0x1A, 0x4B, 0xC1, 0x00, 0x09, 0x80, 0x50, 0x00, 0xC6, 0x4A, 0xD0, 0xE8, 0xE8, 0xE0, 0x74, 0x5E, 0x5E, 0xEE, 0xEE, 0xEE, 0x5C, 0xEE, 0x66, 0x5C, 0xDE, 0xE4, 0xCE, 0x5E, 0xA8, 0xA4, 0x5E, 0xC6, 0xC2, 0xDC, 0xDE, 0xDC, 0xD2, 0xC6, 0xC2, 0xD8, 0x5A, 0xCA, 0xF0, 0xD2, 0x5E, 0xA1, 0xAB, 0x43, 0xA3, 0xA3, 0x81, 0xD1, 0x79, 0x7B, 0xBB, 0xBB, 0xB9, 0x73, 0xB9, 0x99, 0x73, 0x7B, 0x93, 0x39, 0x79, 0x91, 0x81, 0x81, 0x89, 0x79, 0x81, 0xA1, 0x7B, 0xC3, 0x6B, 0x63, 0x23, 0x9B, 0x4B, 0x39, 0x6B, 0x6B, 0x7B, 0x93, 0x29, 0x1B, 0x2B, 0x1B, 0x23, 0x9B, 0x09, 0x6B, 0x9B, 0x43, 0x09, 0x91, 0xA9, 0xB1, 0x10, 0x01, 0x4C, 0x02, 0x80, 0x06, 0x33, 0x56, 0x87, 0x47, 0x47, 0x03, 0xA2, 0xF2, 0xF7, 0x77, 0x77, 0x72, 0xE7, 0x73, 0x32, 0xE6, 0xF7, 0x26, 0x72, 0xF3, 0x23, 0x03, 0x03, 0x12, 0xF3, 0x03, 0x42, 0xF7, 0x86, 0xD6, 0xC6, 0x47, 0x36, 0x96, 0x72, 0xD6, 0xD6, 0xF7, 0x26, 0x52, 0x36, 0x56, 0x36, 0x47, 0x36, 0x12, 0xD7, 0x36, 0x86, 0x13, 0x23, 0x53, 0x65, 0x20, 0x62, 0x36, 0x96, 0x43, 0x10, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x33, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x54, 0x52, 0x2F, 0x63, 0x61, 0x6E, 0x6F, 0x6E, 0x69, 0x63, 0x61, 0x6C, 0x2D, 0x65, 0x78, 0x69, 0x2F, 0x22, 0x00, 0x29, 0x80, 0x50, 0x00, 0xC6, 0x4A, 0xD0, 0xE8, 0xE8, 0xE0, 0x74, 0x5E, 0x5E, 0xEE, 0xEE, 0xEE, 0x5C, 0xEE, 0x66, 0x5C, 0xDE, 0xE4, 0xCE, 0x5E, 0xA8, 0xA4, 0x5E, 0xC6, 0xC2, 0xDC, 0xDE, 0xDC, 0xD2, 0xC6, 0xC2, 0xD8, 0x5A, 0xCA, 0xF0, 0xD2, 0x5E, 0xA4, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x33, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x32, 0x30, 0x30, 0x31, 0x2F, 0x30, 0x34, 0x2F, 0x78, 0x6D, 0x6C, 0x65, 0x6E, 0x63, 0x23, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x04, 0x00, 0x53, 0x00, 0xA0, 0x01, 0x8C, 0xA5, 0xA1, 0xD1, 0xD1, 0xC0, 0xE8, 0xBC, 0xBD, 0xDD, 0xDD, 0xDC, 0xB9, 0xDC, 0xCC, 0xB9, 0xBD, 0xC9, 0x9C, 0xBC, 0xC8, 0xC0, 0xC0, 0xC4, 0xBC, 0xC0, 0xD0, 0xBD, 0xE1, 0xB5, 0xB1, 0x95, 0xB9, 0x8C, 0x8D, 0xCD, 0xA1, 0x84, 0xC8, 0xD4, 0xD9, 0x42, 0x0D, 0x78, 0xAD, 0x52, 0x73, 0xB2, 0x43, 0x75, 0xA2, 0x53, 0x9A, 0x39, 0x64, 0x51, 0x11, 0x98, 0x1A, 0x6C, 0xF2, 0x7C, 0x34, 0x57, 0xA2, 0x96, 0x6F, 0x24, 0x6A, 0xA4, 0x81, 0x10, 0x48, 0x22, 0x01, 0x29, 0x06, 0x08, 0xC0, 0x44, 0x20, 0x19, 0xED, 0xC1, 0xF4, 0x53, 0xA1, 0x4D, 0x12, 0xB1, 0xA4, 0xF3, 0xB1, 0xB6, 0xD3, 0xF9, 0xC4, 0xFE, 0xFC, 0xE8, 0xE2, 0x74, 0xDB, 0x06, 0xA5, 0x41, 0xCC, 0x27, 0x7B, 0x2E, 0x59, 0x89, 0x1A, 0x60, 0x44, 0x20, 0x18, 0x75, 0x4F, 0x03, 0x40, 0x6B, 0xB9, 0x81, 0xCD, 0x38, 0x18, 0x05, 0x2E, 0xED, 0xFC, 0xDE, 0xA5, 0xEC, 0xA1, 0x37, 0x3A, 0x87, 0x05, 0xA3, 0x52, 0xA9, 0x77, 0x9A, 0x5F, 0x14, 0xE4, 0x76, 0xA8, 0x14, 0x0A, 0xD2, 0xC8, 0x62, 0x6A, 0x81, 0x98, 0x41, 0x00, 0xE8, 0x98, 0x41, 0x00, 0xBC, 0x50, 0x01, 0x81, 0x00, 0x81, 0x01, 0x00, 0x84, 0x98, 0x05, 0x03, 0x04, 0x15, 0x43, 0x24, 0x67, 0x1E, 0x82, 0x01, 0x81, 0x18, 0x2E, 0x18, 0x90, 0x98, 0x0F, 0x83, 0x01, 0xAA, 0x82, 0x01, 0x86, 0x0C, 0x28, 0x25, 0xA4, 0x96, 0x98, 0xAF, 0xA1, 0xA9, 0x2A, 0x2F, 0xA7, 0xA2, 0xA6, 0xAF, 0xA9, 0xAA, 0xA1, 0x19, 0x2F, 0xAB, 0x20, 0xA6, 0x24, 0xA2, 0x18, 0x8A, 0x98, 0x09, 0x83, 0x01, 0xAA, 0x82, 0x05, 0x06, 0x06, 0x3B, 0x32, 0xB9, 0x34, 0xB9, 0xB1, 0xB7, 0x90, 0x23, 0xB6, 0xB1, 0x24, 0x18, 0x85, 0x98, 0x04, 0x83, 0x01, 0xAA, 0x82, 0x03, 0x09, 0x81, 0x22, 0x22, 0x98, 0x89, 0x98, 0x08, 0x83, 0x05, 0x04, 0xC9, 0x13, 0x44, 0xC9, 0xF9, 0x16, 0x32, 0x00, 0x8C, 0x8B, 0x01, 0xA7, 0xA2, 0xA6, 0x98, 0x0F, 0x0B, 0x86, 0x99, 0x18, 0x98, 0x1C, 0x98, 0x19, 0x18, 0x99, 0x99, 0x18, 0x99, 0x9C, 0x2D, 0x0B, 0x86, 0x99, 0x18, 0x98, 0x98, 0x18, 0x19, 0x98, 0x99, 0x99, 0x18, 0x99, 0x9C, 0x2D, 0x18, 0x24, 0x18, 0x8D, 0x18, 0x0C, 0x03, 0x01, 0xAA, 0x82, 0x01, 0x86, 0x08, 0xAB, 0x98, 0x18, 0x2B, 0x22, 0xA9, 0x24, 0xA9, 0xA1, 0xA7, 0x98, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x8A, 0x98, 0x09, 0x83, 0x01, 0xAA, 0x82, 0x05, 0x06, 0x06, 0x3B, 0x32, 0xB9, 0x34, 0xB9, 0xB1, 0xB7, 0x90, 0x23, 0xB6, 0xB1, 0x24, 0x18, 0x89, 0x98, 0x08, 0x83, 0x05, 0x04, 0xC9, 0x13, 0x44, 0xC9, 0xF9, 0x16, 0x32, 0x00, 0x8C, 0x8B, 0x01, 0xA7, 0xA2, 0xA6, 0x98, 0x2C, 0x98, 0x09, 0x83, 0x03, 0x95, 0x43, 0x24, 0x67, 0x1E, 0x81, 0x00, 0x83, 0x04, 0x15, 0x43, 0x24, 0x67, 0x1E, 0x81, 0x80, 0x83, 0x81, 0xA1, 0x00, 0x02, 0x3C, 0x7B, 0x7C, 0xD9, 0x37, 0x92, 0x96, 0xC3, 0xF7, 0x3C, 0xF4, 0x56, 0x95, 0x5B, 0x41, 0x91, 0x85, 0x4A, 0xD4, 0xDF, 0x3B, 0x75, 0x00, 0xA9, 0x89, 0x58, 0xC6, 0xF5, 0xE7, 0xE9, 0x0B, 0x3A, 0x0F, 0xC7, 0x2B, 0x07, 0xF9, 0x7D, 0xD2, 0xB3, 0x25, 0xA8, 0xC1, 0xB0, 0xDA, 0xB5, 0x55, 0xBF, 0xAE, 0x3D, 0xB3, 0x27, 0x0C, 0x5E, 0xDE, 0x5B, 0x8A, 0xFC, 0x73, 0x58, 0x94, 0x88, 0xC2, 0x69, 0x51, 0x9F, 0x98, 0x1E, 0x98, 0x06, 0x03, 0x01, 0xAA, 0x8E, 0x89, 0x80, 0x80, 0xFF, 0x82, 0x01, 0x18, 0x00, 0x18, 0x07, 0x03, 0x01, 0xAA, 0x8E, 0x87, 0x80, 0x80, 0xFF, 0x82, 0x02, 0x01, 0x81, 0x01, 0xC4, 0x18, 0x0E, 0x83, 0x01, 0xAA, 0x8E, 0x87, 0x02, 0x0B, 0x02, 0x0A, 0x7C, 0x13, 0x6A, 0xA2, 0x05, 0x84, 0x4C, 0x1C, 0xDA, 0x9F, 0x26, 0x4C, 0xB0, 0xD6, 0xC9, 0x90, 0xDD, 0x82, 0xE3, 0xBE, 0x98, 0x05, 0x03, 0x04, 0x15, 0x43, 0x24, 0x67, 0x1E, 0x82, 0x01, 0x81, 0x01, 0xA3, 0x80, 0x18, 0x22, 0x01, 0x10, 0x01, 0x7E, 0xDD, 0x89, 0x08, 0x1D, 0x00, 0x87, 0x47, 0x09, 0x91, 0x67, 0x4C, 0x99, 0x8E, 0x24, 0x1A, 0xB2, 0x6A, 0x14, 0x4A, 0x86, 0x81, 0xAC, 0x52, 0xDC, 0xF0, 0xD9, 0x99, 0xC8, 0xE3, 0xBC, 0x01, 0x10, 0x2E, 0xDC, 0x43, 0x65, 0x8A, 0x74, 0xFC, 0x8E, 0xA4, 0x97, 0xA3, 0xC9, 0x12, 0x91, 0xCF, 0xDC, 0x6A, 0xCA, 0xBF, 0xFE, 0x13, 0xE2, 0x04, 0xA5, 0x0C, 0x4E, 0xF1, 0x67, 0x7B, 0xAE, 0x54, 0xF0, 0x81, 0x00, 0xF1, 0x39, 0x85, 0xB5, 0x94, 0xA1, 0x0D, 0x38, 0xF5, 0x41, 0x2D, 0x24, 0xB4, 0xC5, 0x7D, 0x0D, 0x49, 0x51, 0x7D, 0x58, 0xC9, 0x1D, 0x7D, 0x49, 0x3D, 0x3D, 0x51, 0x7D, 0x59, 0x05, 0x31, 0x25, 0x10, 0xB1, 0x3C, 0xF5, 0xD9, 0x95, 0xC9, 0xA5, 0xCD, 0x8D, 0xBC, 0x81, 0x1D, 0xB5, 0x89, 0x20, 0xB1, 0x0C, 0xF5, 0x11, 0x14, 0xB1, 0x11, 0x0C, 0xF5, 0x58, 0xC9, 0x1C, 0xA4, 0xF8, 0x00, 0x44, 0x00
};
static const char * ns = "urn:iso:15118:2:2013:MsgDef";
int log_hexdump(const char *title, const unsigned char *data, int len);
int StringHextoHex(char *str, unsigned char *out, int *outlen);
int main() {
char buf[80];
getcwd(buf, sizeof(buf));
printf("current working directory: %s\n", buf);
//开始根据xml编码 CertificateInstallationReq
dealReq();
//开始根据xml编码 CertificateInstallationRes
dealRes();
return 0;
}
int dealReq(){
//开始根据xml编码 CertificateInstallationReq
// init for structs
struct iso2_exiDocument exiDoc;
struct iso2_V2G_Message V2G_Message;
struct iso2_MessageHeaderType Header;
struct iso2_BodyType Body;
struct iso2_CertificateInstallationReqType CertificateInstallationReq;
// fill Header
struct iso2_SignatureType Signature;
init_iso2_SignatureType(&Signature);
//fill SignedInfo
struct iso2_SignedInfoType SignedInfo;
init_iso2_SignedInfoType(&SignedInfo);
struct iso2_CanonicalizationMethodType CanonicalizationMethod;
init_iso2_CanonicalizationMethodType(&CanonicalizationMethod);
strcpy(CanonicalizationMethod.Algorithm.characters,"http://www.w3.org/TR/canonical-exi/");
CanonicalizationMethod.Algorithm.charactersLen = strlen("http://www.w3.org/TR/canonical-exi/");
CanonicalizationMethod.ANY_isUsed = 0u;
struct iso2_SignatureMethodType SignatureMethod;
init_iso2_SignatureMethodType(&SignatureMethod);
strcpy(SignatureMethod.Algorithm.characters,"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256");
SignatureMethod.Algorithm.charactersLen = strlen("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256");
SignatureMethod.ANY_isUsed = 0u;
//fill Reference, 3 Attributes(Id,URI,Type) + 3 elements(Transforms,DigestMethod,DigestValue)
struct iso2_ReferenceType Reference;
init_iso2_ReferenceType(&Reference);
strcpy(Reference.URI.characters,"#id1");
Reference.URI.charactersLen = strlen("#id1");
Reference.URI_isUsed = 1u;
struct iso2_TransformsType Transforms;
struct iso2_TransformType Transform;
init_iso2_TransformType(&Transform);
strcpy(Transform.Algorithm.characters,"http://www.w3.org/TR/canonical-exi/");
Transform.Algorithm.charactersLen = strlen("http://www.w3.org/TR/canonical-exi/");
Transform.ANY_isUsed = 0u;
Transforms.Transform = Transform;
Reference.Transforms = Transforms;
Reference.Transforms_isUsed = 1u;
struct iso2_DigestMethodType DigestMethod;
init_iso2_DigestMethodType(&DigestMethod);
strcpy(DigestMethod.Algorithm.characters,"http://www.w3.org/2001/04/xmlenc#sha256");
DigestMethod.Algorithm.charactersLen = strlen("http://www.w3.org/2001/04/xmlenc#sha256");
DigestMethod.ANY_isUsed = 0u;
Reference.DigestMethod = DigestMethod;
char *indata1 = "14rVJzskN1olOaOWRREZgabPJ8NFeilm8kaqSBEEgiA=";
int ret = base64_decode(indata1, strlen(indata1), Reference.DigestValue.bytes, &Reference.DigestValue.bytesLen);
printf("ret= %d\n", ret);
SignedInfo.CanonicalizationMethod = CanonicalizationMethod;
SignedInfo.SignatureMethod = SignatureMethod;
SignedInfo.Reference = Reference;
Signature.SignedInfo = SignedInfo;
struct iso2_SignatureValueType SignatureValue;
init_iso2_SignatureValueType(&SignatureValue);
char *indata2 = "MEYCIQDPbg+inQpolY0nnY22n84n9+dHE6bYNSoOYTvZcsxI0wIhAMOqeBoDXcwOacDAKXdv5vUvZQm51DgtGpVLvNL4pyO1";
ret = base64_decode(indata2, strlen(indata2), SignatureValue.CONTENT.bytes, &SignatureValue.CONTENT.bytesLen);
printf("ret= %d\n", ret);
Signature.SignatureValue = SignatureValue;
//fill Header
init_iso2_MessageHeaderType(&Header);
// fill Header, id max length=8字节
StringHextoHex("2F82FAE56F4442E2", Header.SessionID.bytes, &Header.SessionID.bytesLen);
Header.Signature = Signature;
Header.Signature_isUsed = 1u;
//-------------Body--------------------------------------------------------
strcpy(CertificateInstallationReq.Id.characters,"id1");
CertificateInstallationReq.Id.charactersLen = strlen("id1");
char *indata3 = "MEYCIQDPbg+inQpolY0nnY22n84n9+dHE6bYNSoOYTvZcsxI0wIhAMOqeBoDXcwOacDAKXdv5vUvZQm51DgtGpVLvNL4pyO1";
ret = base64_decode(indata3, strlen(indata3), CertificateInstallationReq.OEMProvisioningCert.bytes, &CertificateInstallationReq.OEMProvisioningCert.bytesLen);
printf("ret= %d\n", ret);
struct iso2_ListOfRootCertificateIDsType ListOfRootCertificateIDs;
init_iso2_ListOfRootCertificateIDsType(&ListOfRootCertificateIDs);
struct iso2_X509IssuerSerialType RootCertificateID;
init_iso2_X509IssuerSerialType(&RootCertificateID);
strcpy(RootCertificateID.X509IssuerName.characters,"<Name(CN=PKI-1_CRT_V2G_ROOT_VALID,O=verisco GmbH,C=DE,DC=V2G)>");
RootCertificateID.X509IssuerName.charactersLen = strlen("<Name(CN=PKI-1_CRT_V2G_ROOT_VALID,O=verisco GmbH,C=DE,DC=V2G)>");
RootCertificateID.X509SerialNumber = 1;
ListOfRootCertificateIDs.RootCertificateID.array[0] = RootCertificateID;
ListOfRootCertificateIDs.RootCertificateID.arrayLen = 1;
CertificateInstallationReq.ListOfRootCertificateIDs = ListOfRootCertificateIDs;
// fill Body
init_iso2_BodyType(&Body);
Body.CertificateInstallationReq = CertificateInstallationReq;
Body.CertificateInstallationReq_isUsed = 1u;
init_iso2_V2G_Message(&V2G_Message);
V2G_Message.Header = Header;
V2G_Message.Body = Body;
init_iso2_exiDocument( &exiDoc );
exiDoc.V2G_Message = V2G_Message;
//define out stream
exi_bitstream_t stream;
uint8_t* dataReq = (uint8_t*)malloc(2048);
// uint8_t dataReq[1024]={0};
memset(dataReq, 0, 2048);
exi_bitstream_init(&stream, dataReq, 2048, 0, NULL);
int ret1 = encode_iso2_exiDocument(&stream, &exiDoc);
printf("ret1= %d \n",ret1);
printf("stream.byte_pos =%ld \n",stream.byte_pos);
log_hexdump("dataReq", dataReq, stream.byte_pos+1);
//write to file
exiWrite2File("./bin/CertificateInstallationReq_out.exi", dataReq, stream.byte_pos+1);
//根据exi解码
exi_bitstream_reset(&stream);
struct iso2_exiDocument exiDoc2;
int ret2 = decode_iso2_exiDocument(&stream, &exiDoc2);
printf("ret2= %d \n",ret2);
free(dataReq);
}
int dealRes(){
//开始根据xml编码 CertificateInstallationRes
// init for structs
struct iso2_exiDocument exiDoc;
struct iso2_V2G_Message V2G_Message;
struct iso2_MessageHeaderType Header;
struct iso2_BodyType Body;
struct iso2_CertificateInstallationResType CertificateInstallationRes;
// fill Header
init_iso2_MessageHeaderType(&Header);
StringHextoHex("3554EEC6F808A383", Header.SessionID.bytes, &Header.SessionID.bytesLen);
//-------------Body--------------------------------------------------------
init_iso2_CertificateInstallationResType(&CertificateInstallationRes);
CertificateInstallationRes.ResponseCode = iso2_responseCodeType_OK;
struct iso2_CertificateChainType SAProvisioningCertificateChain;
init_iso2_CertificateChainType(&SAProvisioningCertificateChain);
char *indata1 = "MIIB5zCCAY6gAwIBAgIBGDAKBggqhkjOPQQDAjBdMSIwIAYDVQQDDBlQS0ktMV9DUlRfUFJPVl9TVUIyX1ZBTElEMRUwEwYDVQQKDAx2ZXJpc2NvIEdtYkgxCzAJBgNVBAYTAkRFMRMwEQYKCZImiZPyLGQBGRYDQ1BTMB4XDTIxMDkwMjEzMjE0MFoXDTIxMTAwMzEzMjE0MFowXTEiMCAGA1UEAwwZUEtJLTFfQ1JUX1BST1ZfTEVBRl9WQUxJRDEVMBMGA1UECgwMdmVyaXNjbyBHbWJIMQswCQYDVQQGEwJERTETMBEGCgmSJomT8ixkARkWA0NQUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDah/kgaA+vKDNHU3Vp+6cw8tIxkN/72kIknAj/99oMP9iRM8FHGNLaPzq2J0pcDpzmZexzbToaqbkdQ6p4Y/AmjPzA9MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMB0GA1UdDgQWBBQp31ArJBS/DX68uwG2lum2Wuj6sTAKBggqhkjOPQQDAgNHADBEAiBsuwGK22QitrfSXTywE+d4v5ABq3nKlV7MzaSJ3qpvzwIge2zPajjyCextKm3TMhs303uUwmfm99D6mS4tt1uR7wI=";
int ret = base64_decode(indata1, strlen(indata1), SAProvisioningCertificateChain.Certificate.bytes, &SAProvisioningCertificateChain.Certificate.bytesLen);
printf("ret= %d\n", ret);
struct iso2_SubCertificatesType SubCertificates;
init_iso2_SubCertificatesType(&SubCertificates);
SubCertificates.Certificate.arrayLen = 2;
char *indata2 = "MIIB7zCCAZSgAwIBAgIBFzAKBggqhkjOPQQDAjBdMSIwIAYDVQQDDBlQS0ktMV9DUlRfUFJPVl9TVUIxX1ZBTElEMRUwEwYDVQQKDAx2ZXJpc2NvIEdtYkgxCzAJBgNVBAYTAkRFMRMwEQYKCZImiZPyLGQBGRYDQ1BTMB4XDTIxMDkwMjEzMjEzOVoXDTIzMDkwMjEzMjEzOVowXTEiMCAGA1UEAwwZUEtJLTFfQ1JUX1BST1ZfU1VCMl9WQUxJRDEVMBMGA1UECgwMdmVyaXNjbyBHbWJIMQswCQYDVQQGEwJERTETMBEGCgmSJomT8ixkARkWA0NQUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDBjKGihEkDHZtQZXJYXe3XhjtKvHktoK9ulVVljGRYZZPrLUDQQ2lFIm/DKqRIUsrVhlolfu3BGJQUjpUmtk7ujRTBDMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjLL8CwMeGQ4nEVnuAc10mDUEJJTAKBggqhkjOPQQDAgNJADBGAiEAl6t2/7D7AB/6kF5tVqK0IDNM6wPsxGFC2U5IxTzngAsCIQClTvD2kXOp7El1TSfG4eVB83D5YimExEIvvONqUKbuMA==";
ret = base64_decode(indata2, strlen(indata2), SubCertificates.Certificate.array[0].bytes, &SubCertificates.Certificate.array[0].bytesLen);
printf("ret= %d\n", ret);
char *indata3 = "MIIB7TCCAZOgAwIBAgIBFjAKBggqhkjOPQQDAjBcMSEwHwYDVQQDDBhQS0ktMV9DUlRfVjJHX1JPT1RfVkFMSUQxFTATBgNVBAoMDHZlcmlzY28gR21iSDELMAkGA1UEBhMCREUxEzARBgoJkiaJk/IsZAEZFgNWMkcwHhcNMjEwOTAyMTMyMTM5WhcNMjUwOTAxMTMyMTM5WjBdMSIwIAYDVQQDDBlQS0ktMV9DUlRfUFJPVl9TVUIxX1ZBTElEMRUwEwYDVQQKDAx2ZXJpc2NvIEdtYkgxCzAJBgNVBAYTAkRFMRMwEQYKCZImiZPyLGQBGRYDQ1BTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuIkmcmiqntz1RGeq9v/nct1vm+7ygfDqO5/YfTrEpwPDbE1Z1X5rmfUvjZ1N0ZXGiy2CtKTGmhd/naQKGvUj4qNFMEMwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFFKoBvqCka1q03Wa8y7Uen6EWjuGMAoGCCqGSM49BAMCA0gAMEUCIQDi/X96c6e7HoIJQ/PCzRA9oebrwA0/e00MJ/dOjvpOdwIgbZyOBu8BtwBsv5HTOGNJzJbiUkf8b7Nj85KJjFeHgIw=";
ret = base64_decode(indata3, strlen(indata3), SubCertificates.Certificate.array[1].bytes, &SubCertificates.Certificate.array[1].bytesLen);
printf("ret= %d\n", ret);
SAProvisioningCertificateChain.SubCertificates = SubCertificates;
SAProvisioningCertificateChain.SubCertificates_isUsed = 1u;
struct iso2_CertificateChainType ContractSignatureCertChain;
init_iso2_CertificateChainType(&ContractSignatureCertChain);
strcpy(ContractSignatureCertChain.Id.characters,"id1");
ContractSignatureCertChain.Id.charactersLen = strlen("id1");
ContractSignatureCertChain.Id_isUsed = 1u;
char *indata4 = "MIIByzCCAXKgAwIBAgIBDzAKBggqhkjOPQQDAjBaMSAwHgYDVQQDDBdQS0ktMV9DUlRfTU9fU1VCMl9WQUxJRDEVMBMGA1UECgwMdmVyaXNjbyBHbWJIMQswCQYDVQQGEwJERTESMBAGCgmSJomT8ixkARkWAk1PMB4XDTIxMDkwMjEzMjEzOFoXDTIzMDkwMjEzMjEzOFowRDEXMBUGA1UEAwwOREUxQUJDRDJFRjM1N0ExFTATBgNVBAoMDHZlcmlzY28gR21iSDESMBAGCgmSJomT8ixkARkWAk1PMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEaJJ9IFNgGUzaJxpjcZhOYIal3loOXuKwXly+6FlZkaMPdUclMreEAWHKTzrqXzaolWQW8xBHG17/AyynDIhgPqM/MD0wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCA+gwHQYDVR0OBBYEFBPjJKg9jlTxyTUagyAmt3ej13R4MAoGCCqGSM49BAMCA0cAMEQCIFdZO1XVMtwk9/RuJUZHuCoazTSyexAyzKoURmRwNrHQAiB10WMXVNm+6Y4XXQuawoYABuyyoOXUuV4qG+3us3IS3A==";
ret = base64_decode(indata4, strlen(indata4), ContractSignatureCertChain.Certificate.bytes, &ContractSignatureCertChain.Certificate.bytesLen);
printf("ret= %d\n", ret);
struct iso2_SubCertificatesType SubCertificates2;
init_iso2_SubCertificatesType(&SubCertificates2);
SubCertificates2.Certificate.arrayLen = 2;
char *indata5 = "MIIB6DCCAY6gAwIBAgIBDTAKBggqhkjOPQQDAjBaMSAwHgYDVQQDDBdQS0ktMV9DUlRfTU9fU1VCMV9WQUxJRDEVMBMGA1UECgwMdmVyaXNjbyBHbWJIMQswCQYDVQQGEwJERTESMBAGCgmSJomT8ixkARkWAk1PMB4XDTIxMDkwMjEzMjEzOFoXDTI1MDkwMTEzMjEzOFowWjEgMB4GA1UEAwwXUEtJLTFfQ1JUX01PX1NVQjJfVkFMSUQxFTATBgNVBAoMDHZlcmlzY28gR21iSDELMAkGA1UEBhMCREUxEjAQBgoJkiaJk/IsZAEZFgJNTzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABA9h8psbI/mdtOsqHTmQsh+oMbkRrR/I6YNeAl0sjWvo64RZiHPA81nv/TYgUz1ZktjLU9cIElLFACj+CS4xalqjRTBDMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBSQiNhe8kxPxU2YZShx5Ui+pXt3jjAKBggqhkjOPQQDAgNIADBFAiAF0QxlfjVuqomAL/rmzzl1T/d3V7bb2vW8U/ITAMwmnwIhAPvxFX+FMCWUDdnZ9vsg5UdcAoo0RD0uLgXgjoRSRkqv";
ret = base64_decode(indata5, strlen(indata5), SubCertificates2.Certificate.array[0].bytes, &SubCertificates2.Certificate.array[0].bytesLen);
printf("ret= %d\n", ret);
char *indata6 = "MIIB6DCCAY6gAwIBAgIBDDAKBggqhkjOPQQDAjBaMSAwHgYDVQQDDBdQS0ktMV9DUlRfTU9fUk9PVF9WQUxJRDEVMBMGA1UECgwMdmVyaXNjbyBHbWJIMQswCQYDVQQGEwJERTESMBAGCgmSJomT8ixkARkWAk1PMB4XDTIxMDkwMjEzMjEzOFoXDTI1MDkwMTEzMjEzOFowWjEgMB4GA1UEAwwXUEtJLTFfQ1JUX01PX1NVQjFfVkFMSUQxFTATBgNVBAoMDHZlcmlzY28gR21iSDELMAkGA1UEBhMCREUxEjAQBgoJkiaJk/IsZAEZFgJNTzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDVarDqUpBKFNnNkssVwvuxnQn3n5mmzKtTQ77ZW8E/yqR6dcWJGfmmOPHYruYZhPFnOGUOej2M6r/0QFhmr55ajRTBDMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSo3fgLPv91YCZfWdnipVvlXkP2pDAKBggqhkjOPQQDAgNIADBFAiEAhvm1ML5evLMHizVr04n4h2SakiNFzgGirk9FieQyVVoCIBqA2ZNiEflgdM8KINThkXwONYxJMctgySB6kl/LQ+qL";
ret = base64_decode(indata6, strlen(indata6), SubCertificates.Certificate.array[1].bytes, &SubCertificates.Certificate.array[1].bytesLen);
printf("ret= %d\n", ret);
ContractSignatureCertChain.SubCertificates = SubCertificates;
ContractSignatureCertChain.SubCertificates_isUsed = 1u;
struct iso2_ContractSignatureEncryptedPrivateKeyType ContractSignatureEncryptedPrivateKey;
init_iso2_ContractSignatureEncryptedPrivateKeyType(&ContractSignatureEncryptedPrivateKey);
strcpy(ContractSignatureEncryptedPrivateKey.Id.characters,"id2");
ContractSignatureEncryptedPrivateKey.Id.charactersLen = strlen("id2");
char *indata7 = "AA==";
ret = base64_decode(indata7, strlen(indata7), ContractSignatureEncryptedPrivateKey.CONTENT.bytes, &ContractSignatureEncryptedPrivateKey.CONTENT.bytesLen);
printf("ret= %d\n", ret);
struct iso2_DiffieHellmanPublickeyType DHpublickey;
init_iso2_DiffieHellmanPublickeyType(&DHpublickey);
strcpy(DHpublickey.Id.characters,"id3");
DHpublickey.Id.charactersLen = strlen("id3");
char *indata8 = "AA==";
ret = base64_decode(indata8, strlen(indata8), DHpublickey.CONTENT.bytes, &DHpublickey.CONTENT.bytesLen);
printf("ret= %d\n", ret);
struct iso2_EMAIDType eMAID;
init_iso2_EMAIDType(&eMAID);
strcpy(eMAID.Id.characters,"id4");
eMAID.Id.charactersLen = strlen("id4");
strcpy(eMAID.CONTENT.characters,"DE1ABCD2EF357A");
eMAID.CONTENT.charactersLen = strlen("DE1ABCD2EF357A");
CertificateInstallationRes.SAProvisioningCertificateChain = SAProvisioningCertificateChain;
CertificateInstallationRes.ContractSignatureCertChain = ContractSignatureCertChain;
CertificateInstallationRes.ContractSignatureEncryptedPrivateKey = ContractSignatureEncryptedPrivateKey;
CertificateInstallationRes.DHpublickey = DHpublickey;
CertificateInstallationRes.eMAID = eMAID;
// fill Body
init_iso2_BodyType(&Body);
Body.CertificateInstallationRes = CertificateInstallationRes;
Body.CertificateInstallationRes_isUsed = 1u;
init_iso2_V2G_Message(&V2G_Message);
V2G_Message.Header = Header;
V2G_Message.Body = Body;
init_iso2_exiDocument( &exiDoc );
exiDoc.V2G_Message = V2G_Message;
//define out stream
exi_bitstream_t stream;
uint8_t* dataReq = (uint8_t*)malloc(4096);
// uint8_t dataReq[1024]={0};
memset(dataReq, 0, 4096);
exi_bitstream_init(&stream, dataReq, 4096, 0, NULL);
int ret1 = encode_iso2_exiDocument(&stream, &exiDoc);
printf("ret1= %d \n",ret1);
printf("stream.byte_pos =%ld \n",stream.byte_pos);
log_hexdump("dataReq", dataReq, stream.byte_pos+1);
//write to file
exiWrite2File("./bin/CertificateInstallationRes_out.exi", dataReq, stream.byte_pos+1);
//根据exi解码
exi_bitstream_reset(&stream);
struct iso2_exiDocument exiDoc2;
int ret2 = decode_iso2_exiDocument(&stream, &exiDoc2);
printf("ret2= %d \n",ret2);
free(dataReq);
}
int log_hexdump(const char *title, const unsigned char *data, int len) {
char str[160], octet[10];
int ofs, i, k, d;
const unsigned char *buf = (const unsigned char*) data;
const char dimm[] =
"+------------------------------------------------------------------------------+";
printf("%s (%d bytes):\r\n", title, len);
printf("%s\r\n", dimm);
printf(
"| Offset : 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEF |\r\n");
printf("%s\r\n", dimm);
for (ofs = 0; ofs < (int) len; ofs += 16) {
d = snprintf(str, sizeof(str), "| %08X: ", ofs);
for (i = 0; i < 16; i++) {
if ((i + ofs) < (int) len) {
snprintf(octet, sizeof(octet), "%02X ", buf[ofs + i]);
} else {
snprintf(octet, sizeof(octet), " ");
}
d += snprintf(&str[d], sizeof(str) - d, "%s", octet);
}
d += snprintf(&str[d], sizeof(str) - d, " ");
k = d;
for (i = 0; i < 16; i++) {
if ((i + ofs) < (int) len) {
str[k++] =
(0x20 <= (buf[ofs + i]) && (buf[ofs + i]) <= 0x7E) ?
buf[ofs + i] : '.';
} else {
str[k++] = ' ';
}
}
str[k] = '\0';
printf("%s |\r\n", str);
}
printf("%s\r\n", dimm);
return 0;
}
int StringHextoHex(char *str, unsigned char *out, int *outlen)
{
if (str == NULL || out == NULL)
return -1;
int i = 0, ret = 0;
ret = (strlen(str) / (2 * sizeof(char))) + strlen(str) % (2 * sizeof(char));
for (i = 0; i < ret; i++)
sscanf(str + 2 * i, "%02X", (unsigned int *)(out + i));
if (outlen!= NULL)
*outlen = ret;
return ret;
}
运行后输出文件:CertificateInstallationReq_out.exi、CertificateInstallationRes_out.exi。
二者比较内容完全相同。
【结论】完成对所有33条命令编码结果验证(cbexigen与EXICodec.jar)完全相同。解码内容相同。
8.4.2 对ISO15118-20的测试
作者还针对-20的所有命令进行了代码测试,解决了一些问题(测试命令内容错误、遗漏,EXICodec.jar编码结果错误,编码bug),终于获得了全部命令的正确编码,结果与EXICodec.jar的编码完全相同。至此,终于可以宣布cbExiGen编解码库验证成功,能和EXICodec.jar进行正常通信。
99999