/* * Copyright (C) 2007-2018 Siemens AG * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /******************************************************************* * * @author Daniel.Peintner.EXT@siemens.com * @author Sebastian.Kaebisch@siemens.com * @version 0.9.4 * @contact Richard.Kuntschke@siemens.com * * ********************************************************************/ #include #include #include #include #include "../codec/EXITypes.h" #include "../appHandshake/appHandEXIDatatypes.h" #include "../appHandshake/appHandEXIDatatypesEncoder.h" #include "../appHandshake/appHandEXIDatatypesDecoder.h" /* Activate support for DIN */ #include "../din/dinEXIDatatypes.h" #if DEPLOY_DIN_CODEC == SUPPORT_YES #include "../din/dinEXIDatatypesEncoder.h" #include "../din/dinEXIDatatypesDecoder.h" #endif /* DEPLOY_DIN_CODEC == SUPPORT_YES */ /* Activate support for XMLDSIG */ #include "../xmldsig/xmldsigEXIDatatypes.h" #if DEPLOY_XMLDSIG_CODEC == SUPPORT_YES #include "../xmldsig/xmldsigEXIDatatypesEncoder.h" #include "../xmldsig/xmldsigEXIDatatypesDecoder.h" #endif /* DEPLOY_XMLDSIG_CODEC == SUPPORT_YES */ /* Activate support for ISO1 */ #include "../iso1/iso1EXIDatatypes.h" #if DEPLOY_ISO1_CODEC == SUPPORT_YES #include "../iso1/iso1EXIDatatypesEncoder.h" #include "../iso1/iso1EXIDatatypesDecoder.h" #endif /* DEPLOY_ISO1_CODEC == SUPPORT_YES */ /* Activate support for ISO2 */ #include "../iso2/iso2EXIDatatypes.h" #if DEPLOY_ISO2_CODEC == SUPPORT_YES #include "../iso2/iso2EXIDatatypesEncoder.h" #include "../iso2/iso2EXIDatatypesDecoder.h" #endif /* DEPLOY_ISO2_CODEC == SUPPORT_YES */ #include "../transport/v2gtp.h" //#include "../../SeccComm.h" #define BUFFER_SIZE 256 uint8_t buffer1[BUFFER_SIZE]; uint8_t buffer2[BUFFER_SIZE]; #define ERROR_UNEXPECTED_REQUEST_MESSAGE -601 #define ERROR_UNEXPECTED_SESSION_SETUP_RESP_MESSAGE -602 #define ERROR_UNEXPECTED_SERVICE_DISCOVERY_RESP_MESSAGE -602 #define ERROR_UNEXPECTED_SERVICE_DETAILS_RESP_MESSAGE -603 #define ERROR_UNEXPECTED_PAYMENT_SERVICE_SELECTION_RESP_MESSAGE -604 #define ERROR_UNEXPECTED_PAYMENT_DETAILS_RESP_MESSAGE -605 #define ERROR_UNEXPECTED_AUTHORIZATION_RESP_MESSAGE -606 #define ERROR_UNEXPECTED_CHARGE_PARAMETER_DISCOVERY_RESP_MESSAGE -607 #define ERROR_UNEXPECTED_POWER_DELIVERY_RESP_MESSAGE -608 #define ERROR_UNEXPECTED_CHARGING_STATUS_RESP_MESSAGE -609 #define ERROR_UNEXPECTED_METERING_RECEIPT_RESP_MESSAGE -610 #define ERROR_UNEXPECTED_SESSION_STOP_RESP_MESSAGE -611 #define ERROR_UNEXPECTED_CABLE_CHECK_RESP_MESSAGE -612 #define ERROR_UNEXPECTED_PRE_CHARGE_RESP_MESSAGE -612 #define ERROR_UNEXPECTED_CURRENT_DEMAND_RESP_MESSAGE -613 #define ERROR_UNEXPECTED_WELDING_DETECTION_RESP_MESSAGE -614 /*=========================================================================== FUNCTION: PRINT_XML_DOC_DIN_ServiceDiscoveryReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void PRINT_XML_DOC_DIN_ServiceDiscoveryReq(struct dinEXIDocument *exi_doc_DIN) { int i = 0; printf("\n\n⬇⨀⨀⨀⨀⨀ [START] Parsing ServiceDiscoveryReq ⨀⨀⨀⨀⨀⬇\n"); //Service Scope int leng = 0; leng = exi_doc_DIN->V2G_Message.Body.ServiceDiscoveryReq.ServiceScope.charactersLen; printf("\tServieScope (%d Bytes)= ", leng); for (i = 0; i V2G_Message.Body.ServiceDiscoveryReq.ServiceScope.characters[i]); } //Service Category printf("\n\tServiceCategory = %d (DEC)", exi_doc_DIN->V2G_Message.Body.ServiceDiscoveryReq.ServiceCategory); printf("\n\t([1]EVCharging, [2]Internet, [3]ContractCertificate, [4]OtherCustom)\n"); printf("⬆⨂⨂⨂⨂⨂ [END] Parsing ServiceDiscoveryReq ⨂⨂⨂⨂⨂⬆\n\n"); } static int writeStringToEXIString(char* string, exi_string_character_t* exiString) { int pos = 0; while(string[pos]!='\0') { exiString[pos] = string[pos]; pos++; } return pos; } static void printASCIIString(exi_string_character_t* string, uint16_t len) { unsigned int i; for(i=0; isize); printf("\t pos (DEC): %ld\n", *iStream->pos); printf("\t data (HEX): "); for (i=0; i<68; i++) //0x44 = 68, i.e. the length of payload { printf("%02X", iStream->data[i+8]); //V2GTP Payload without 8-Byte Header } printf("\n\n ----------- Content of iStream [END] ------------\n\n"); #endif if ( (errn = read_v2gtpHeader(iStream->data, &payloadLengthDec)) == 0) { *iStream->pos = V2GTP_HEADER_LENGTH; printf("\t pos: %ld\n", *iStream->pos); //added by Joseph if( (errn = decode_appHandExiDocument(iStream, &exiDoc)) ) { /* an error occured */ return errn; } } printf("EVSE side: List of application handshake protocols of the EV \n"); for(i=0;ipos = V2GTP_HEADER_LENGTH; if( (errn = encode_appHandExiDocument(oStream, &appHandResp)) == 0) { errn = write_v2gtpHeader(oStream->data, (*oStream->pos)-V2GTP_HEADER_LENGTH, V2GTP_EXI_TYPE); } return errn; } static int appHandshake() { bitstream_t stream1; bitstream_t stream2; uint32_t payloadLengthDec; size_t pos1 = V2GTP_HEADER_LENGTH; /* v2gtp header */ size_t pos2 = 0; struct appHandEXIDocument handshake; struct appHandEXIDocument handshakeResp; int errn = 0; char* ns0 = "urn:iso:15118:2:2010:MsgDef"; char* ns1 = "urn:din:70121:2012:MsgDef"; stream1.size = BUFFER_SIZE; stream1.data = buffer1; stream1.pos = &pos1; stream2.size = BUFFER_SIZE; stream2.data = buffer2; stream2.pos = &pos2; init_appHandEXIDocument(&handshake); printf("EV side: setup data for the supported application handshake request message\n"); /* set up ISO/IEC 15118 Version 1.0 information */ handshake.supportedAppProtocolReq_isUsed = 1u; handshake.supportedAppProtocolReq.AppProtocol.arrayLen = 2; /* we have only two protocols implemented */ handshake.supportedAppProtocolReq.AppProtocol.array[0].ProtocolNamespace.charactersLen = writeStringToEXIString(ns0, handshake.supportedAppProtocolReq.AppProtocol.array[0].ProtocolNamespace.characters); handshake.supportedAppProtocolReq.AppProtocol.array[0].SchemaID = 1; handshake.supportedAppProtocolReq.AppProtocol.array[0].VersionNumberMajor = 1; handshake.supportedAppProtocolReq.AppProtocol.array[0].VersionNumberMinor = 0; handshake.supportedAppProtocolReq.AppProtocol.array[0].Priority = 1; handshake.supportedAppProtocolReq.AppProtocol.array[1].ProtocolNamespace.charactersLen = writeStringToEXIString(ns1, handshake.supportedAppProtocolReq.AppProtocol.array[1].ProtocolNamespace.characters); handshake.supportedAppProtocolReq.AppProtocol.array[1].SchemaID = 2; handshake.supportedAppProtocolReq.AppProtocol.array[1].VersionNumberMajor = 1; handshake.supportedAppProtocolReq.AppProtocol.array[1].VersionNumberMinor = 0; handshake.supportedAppProtocolReq.AppProtocol.array[1].Priority = 2; /* send app handshake request */ if( (errn = encode_appHandExiDocument(&stream1, &handshake)) == 0) { if ( write_v2gtpHeader(stream1.data, pos1-V2GTP_HEADER_LENGTH, V2GTP_EXI_TYPE) == 0 ) { printf("EV side: send message to the EVSE\n"); } } if (errn == 0) { /* read app handshake request & generate response */ errn = appHandshakeHandler(&stream1, &stream2); } if (errn == 0) { /* check response */ if ( (errn = read_v2gtpHeader(stream2.data, &payloadLengthDec)) == 0) { pos2 = V2GTP_HEADER_LENGTH; if(decode_appHandExiDocument(&stream2, &handshakeResp) == 0) { printf("EV side: Response of the EVSE \n"); if(handshakeResp.supportedAppProtocolRes.ResponseCode == appHandresponseCodeType_OK_SuccessfulNegotiation) { printf("\t\tResponseCode=OK_SuccessfulNegotiation\n"); printf("\t\tSchemaID=%d\n",handshakeResp.supportedAppProtocolRes.SchemaID); } } } } if (errn != 0) { printf("appHandshake error %d \n", errn); } return errn; } #if DEPLOY_ISO2_CODEC == SUPPORT_YES static void printEVSEStatus2(struct iso2EVSEStatusType* status) { printf("\tEVSEStatus:\n"); printf("\t\tEVSENotification=%d\n", status->EVSENotification); printf("\t\tNotificationMaxDelay=%d\n", status->NotificationMaxDelay); } /* serializes EXI stream and adds V2G TP header */ static int serialize2EXI2Stream(struct iso2EXIDocument* exiIn, bitstream_t* stream) { int errn; *stream->pos = V2GTP_HEADER_LENGTH; /* v2gtp header */ if( (errn = encode_iso2ExiDocument(stream, exiIn)) == 0) { errn = write_v2gtpHeader(stream->data, (*stream->pos)-V2GTP_HEADER_LENGTH, V2GTP_EXI_TYPE); } return errn; } /* deserializes V2G TP header and decodes right away EXI stream */ static int deserialize2Stream2EXI(bitstream_t* streamIn, struct iso2EXIDocument* exi) { int errn; uint32_t payloadLength; *streamIn->pos = 0; if ( (errn = read_v2gtpHeader(streamIn->data, &payloadLength)) == 0) { *streamIn->pos += V2GTP_HEADER_LENGTH; errn = decode_iso2ExiDocument(streamIn, exi); } return errn; } static int sessionSetup2(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) { printf("EVSE side: sessionSetup called\n" ); printf("\tReceived data:\n"); printf("\tHeader SessionID="); printBinaryArray(exiIn->V2G_Message.Header.SessionID.bytes, exiIn->V2G_Message.Header.SessionID.bytesLen); printf("\t\t EVCCID=%d\n", exiIn->V2G_Message.Body.SessionSetupReq.EVCCID.bytes[0]); exiOut->V2G_Message_isUsed = 1u; /* generate an unique sessionID */ init_iso2MessageHeaderType(&exiOut->V2G_Message.Header); exiOut->V2G_Message.Header.SessionID.bytes[0] = 1; exiOut->V2G_Message.Header.SessionID.bytes[1] = 2; exiOut->V2G_Message.Header.SessionID.bytes[2] = 3; exiOut->V2G_Message.Header.SessionID.bytes[3] = 4; exiOut->V2G_Message.Header.SessionID.bytes[4] = 5; exiOut->V2G_Message.Header.SessionID.bytes[5] = 6; exiOut->V2G_Message.Header.SessionID.bytes[6] = 7; exiOut->V2G_Message.Header.SessionID.bytes[7] = 8; exiOut->V2G_Message.Header.SessionID.bytesLen = 8; /* Prepare data for EV */ init_iso2BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.SessionSetupRes_isUsed = 1u; init_iso2SessionSetupResType(&exiOut->V2G_Message.Body.SessionSetupRes); exiOut->V2G_Message.Body.SessionSetupRes.ResponseCode = iso2responseCodeType_OK; exiOut->V2G_Message.Body.SessionSetupRes.EVSEID.characters[0] = 0; exiOut->V2G_Message.Body.SessionSetupRes.EVSEID.characters[1] = 20; exiOut->V2G_Message.Body.SessionSetupRes.EVSEID.charactersLen = 2; exiOut->V2G_Message.Body.SessionSetupRes.EVSETimeStamp_isUsed = 1u; exiOut->V2G_Message.Body.SessionSetupRes.EVSETimeStamp = 123456789; return 0; } static int serviceDiscovery2(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) { int i; printf("EVSE side: serviceDiscovery called\n" ); printf("\tReceived data:\n"); printf("\tHeader SessionID="); printBinaryArray(exiIn->V2G_Message.Header.SessionID.bytes, exiIn->V2G_Message.Header.SessionID.bytesLen); if(exiIn->V2G_Message.Body.ServiceDiscoveryReq.SupportedServiceIDs_isUsed) { for(i=0;iV2G_Message.Body.ServiceDiscoveryReq.SupportedServiceIDs.ServiceID.arrayLen; i++) { printf("\t\tSupportedServiceID=%d\n", exiIn->V2G_Message.Body.ServiceDiscoveryReq.SupportedServiceIDs.ServiceID.array[i]); } } /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso2BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.ServiceDiscoveryRes_isUsed = 1u; init_iso2ServiceDiscoveryResType(&exiOut->V2G_Message.Body.ServiceDiscoveryRes); exiOut->V2G_Message.Body.ServiceDiscoveryRes.VASList_isUsed = 0u; /* we do not provide VAS */ exiOut->V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = iso2responseCodeType_OK; exiOut->V2G_Message.Body.ServiceDiscoveryRes.PaymentOptionList.PaymentOption.array[0] = iso2paymentOptionType_ExternalPayment; /* EVSE handles the payment */ exiOut->V2G_Message.Body.ServiceDiscoveryRes.PaymentOptionList.PaymentOption.array[1] = iso2paymentOptionType_Contract; exiOut->V2G_Message.Body.ServiceDiscoveryRes.PaymentOptionList.PaymentOption.arrayLen = 2; exiOut->V2G_Message.Body.ServiceDiscoveryRes.EnergyTransferServiceList.Service.arrayLen = 1; exiOut->V2G_Message.Body.ServiceDiscoveryRes.EnergyTransferServiceList.Service.array[0].ServiceID = 1; /* ID of the charge service */ exiOut->V2G_Message.Body.ServiceDiscoveryRes.EnergyTransferServiceList.Service.array[0].FreeService = 1; exiOut->V2G_Message.Body.ServiceDiscoveryRes.VASList_isUsed = 0u; /* no value added service requested */ return 0; } static int serviceDetail2(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) { printf("EVSE side: serviceDetail called\n" ); printf("\tReceived data:\n"); printf("\tHeader SessionID="); printBinaryArray(exiIn->V2G_Message.Header.SessionID.bytes, exiIn->V2G_Message.Header.SessionID.bytesLen); printf("\t\t ServiceDetailID=%d\n",exiIn->V2G_Message.Body.ServiceDetailReq.ServiceID); /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso2BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.ServiceDetailRes_isUsed= 1u; init_iso2ServiceDetailResType(&exiOut->V2G_Message.Body.ServiceDetailRes); exiOut->V2G_Message.Body.ServiceDetailRes.ServiceID = 1234; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList_isUsed = 1u; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.arrayLen = 2; /* Parameter Set 1*/ exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].ParameterSetID = 1; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.arrayLen = 2; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.charactersLen = 8; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[0] = 'P'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[1] = 'r'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[2] = 'o'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[3] = 't'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[4]= 'o'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[5] = 'c'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[6] = 'o'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[7] = 'l'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].intValue = 15119; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].intValue_isUsed = 1u; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.charactersLen = 4; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.characters[0] = 'N'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.characters[1] = 'a'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.characters[2] = 'm'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.characters[3] = 'e'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].stringValue_isUsed = 1u; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].stringValue.charactersLen = 3; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].stringValue.characters[0] = 'V'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].stringValue.characters[1] = '2'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].stringValue.characters[2] = 'G'; /* Parameter Set 2 */ exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].ParameterSetID = 2; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.arrayLen = 1; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.charactersLen = 7; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[0] = 'C'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[1] = 'h'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[2] = 'a'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[3] = 'n'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[4] = 'n'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[5] = 'e'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[6] = 'l'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].physicalValue_isUsed = 1u; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].physicalValue.Value = 1234; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].physicalValue.Exponent = 1; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].physicalValue.Value = 2; exiOut->V2G_Message.Body.ServiceDetailRes.ResponseCode = iso2responseCodeType_OK; return 0; } static int paymentServiceSelection2(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) { int i; printf("EVSE side: paymentServiceSelection called\n" ); printf("\tReceived data:\n"); printf("\tHeader SessionID="); printBinaryArray(exiIn->V2G_Message.Header.SessionID.bytes, exiIn->V2G_Message.Header.SessionID.bytesLen); if(exiIn->V2G_Message.Body.PaymentServiceSelectionReq.SelectedPaymentOption == iso2paymentOptionType_ExternalPayment) { printf("\t\t SelectedPaymentOption=ExternalPayment\n"); } if(exiIn->V2G_Message.Body.PaymentServiceSelectionReq.SelectedVASList_isUsed) { for(i=0; iV2G_Message.Body.PaymentServiceSelectionReq.SelectedVASList.SelectedService.arrayLen;i++) { printf("\t\t ServiceID=%d\n", exiIn->V2G_Message.Body.PaymentServiceSelectionReq.SelectedVASList.SelectedService.array[i].ServiceID); printf("\t\t ParameterSetID=%d\n", exiIn->V2G_Message.Body.PaymentServiceSelectionReq.SelectedVASList.SelectedService.array[i].ParameterSetID); } } /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso2BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.PaymentServiceSelectionRes_isUsed= 1u; init_iso2PaymentServiceSelectionResType(&exiOut->V2G_Message.Body.PaymentServiceSelectionRes); exiOut->V2G_Message.Body.ServiceDetailRes.ResponseCode = iso2responseCodeType_OK; return 0; } static int paymentDetails2(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) { printf("EVSE side: paymentDetails called\n" ); printf("\tReceived data:\n"); printf("\t\t eMAID=%d\n", exiIn->V2G_Message.Body.PaymentDetailsReq.eMAID.characters[0]); printf("\t\t ID=%c%c\n", exiIn->V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.Id.characters[0], exiIn->V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.Id.characters[1]); printf("\t\t Certificate=%c%c\n", exiIn->V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.Certificate.bytes[0], exiIn->V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.Certificate.bytes[1]); printf("\t\t SubCertificate 1=%c%c\n", exiIn->V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.SubCertificates.Certificate.array[0].bytes[0], exiIn->V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.SubCertificates.Certificate.array[0].bytes[1]); printf("\t\t SubCertificate 2=%c%c\n", exiIn->V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.SubCertificates.Certificate.array[1].bytes[0], exiIn->V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.SubCertificates.Certificate.array[1].bytes[1]); /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso2BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.PaymentDetailsRes_isUsed = 1u; init_iso2PaymentDetailsResType(&exiOut->V2G_Message.Body.PaymentDetailsRes); exiOut->V2G_Message.Body.PaymentDetailsRes.ResponseCode = iso2responseCodeType_OK; exiOut->V2G_Message.Body.PaymentDetailsRes.GenChallenge.bytesLen = 1; exiOut->V2G_Message.Body.PaymentDetailsRes.GenChallenge.bytes[0] = 1; exiOut->V2G_Message.Body.PaymentDetailsRes.EVSETimeStamp = 123456; return 0; } static int authorization2(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) { printf("EVSE: Authorization called\n" ); printf("\tReceived data:\n"); if(exiIn->V2G_Message.Body.AuthorizationReq.GenChallenge_isUsed) { printf("\t\t\t GenChallenge=%d\n", exiIn->V2G_Message.Body.AuthorizationReq.GenChallenge.bytes[0]); } if(exiIn->V2G_Message.Body.AuthorizationReq.Id_isUsed ) { printf("\t\t\t ID=%c%c%c\n", exiIn->V2G_Message.Body.AuthorizationReq.Id.characters[0], exiIn->V2G_Message.Body.AuthorizationReq.Id.characters[1], exiIn->V2G_Message.Body.AuthorizationReq.Id.characters[2]); } /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso2BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.AuthorizationRes_isUsed = 1u; init_iso2AuthorizationResType(&exiOut->V2G_Message.Body.AuthorizationRes); exiOut->V2G_Message.Body.AuthorizationRes.ResponseCode = iso2responseCodeType_OK; exiOut->V2G_Message.Body.AuthorizationRes.EVSEProcessing = iso2EVSEProcessingType_Finished; return 0; } static int chargeParameterDiscovery2(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) { printf("EVSE side: chargeParameterDiscovery called\n" ); printf("\tReceived data:\n"); if(exiIn->V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter_isUsed) { printf("\t\t DepartureTime=%d\n", exiIn->V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.DepartureTime); printf("\t\t EVMaximumChargeCurrent=%d\n", exiIn->V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMaximumChargeCurrent.Value); } /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso2BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.ChargeParameterDiscoveryRes_isUsed = 1u; init_iso2ChargeParameterDiscoveryResType(&exiOut->V2G_Message.Body.ChargeParameterDiscoveryRes); exiOut->V2G_Message.Body.ChargeParameterDiscoveryRes.ResponseCode = iso2responseCodeType_OK_CertificateExpiresSoon; exiOut->V2G_Message.Body.ChargeParameterDiscoveryRes.EVSEProcessing = iso2EVSEProcessingType_Ongoing; exiOut->V2G_Message.Body.ChargeParameterDiscoveryRes.EVSEEnergyTransferParameter_isUsed = 1u; /*exiOut->V2G_Message.Body.ChargeParameterDiscoveryRes.EVSEEnergyTransferParameter = 0;*/ return 0; } static int powerDelivery2(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) { printf("EVSE side: powerDelivery called\n" ); printf("\tReceived data:\n"); printf("\t\t ChargeProgress=%d\n", exiIn->V2G_Message.Body.PowerDeliveryReq.ChargeProgress); printf("\t\t SAScheduleTupleID=%d\n", exiIn->V2G_Message.Body.PowerDeliveryReq.SAScheduleTupleID); /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso2BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.PowerDeliveryRes_isUsed = 1u; init_iso2PowerDeliveryResType(&exiOut->V2G_Message.Body.PowerDeliveryRes); exiOut->V2G_Message.Body.PowerDeliveryRes.ResponseCode = iso2responseCodeType_OK; exiOut->V2G_Message.Body.PowerDeliveryRes.EVSEStatus_isUsed = 1; exiOut->V2G_Message.Body.PowerDeliveryRes.EVSEStatus.EVSENotification = iso2EVSENotificationType_StopCharging; exiOut->V2G_Message.Body.PowerDeliveryRes.EVSEStatus.NotificationMaxDelay=12; exiOut->V2G_Message.Body.PowerDeliveryRes.EVSEProcessing = iso2EVSEProcessingType_Ongoing_WaitingForCustomerInteraction; return 0; } static int chargingStatus2(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) { printf("EVSE side: chargingStatus called\n" ); /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso2BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.ChargingStatusRes_isUsed = 1u; init_iso2ChargingStatusResType(&exiOut->V2G_Message.Body.ChargingStatusRes); exiOut->V2G_Message.Body.ChargingStatusRes.ResponseCode = iso2responseCodeType_OK; exiOut->V2G_Message.Body.ChargingStatusRes.EVSEID.characters[0]= 'A'; exiOut->V2G_Message.Body.ChargingStatusRes.EVSEID.charactersLen =1; exiOut->V2G_Message.Body.ChargingStatusRes.EVSEStatus.EVSENotification = iso2EVSENotificationType_ReNegotiation; exiOut->V2G_Message.Body.ChargingStatusRes.EVSEStatus.NotificationMaxDelay=123; exiOut->V2G_Message.Body.ChargingStatusRes.ReceiptRequired = 1; exiOut->V2G_Message.Body.ChargingStatusRes.ReceiptRequired_isUsed = 1; return 0; } static int meteringReceipt2(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) { printf("EVSE side: meteringReceipt called\n" ); printf("\tReceived data:\n"); printf("\t\t ID=%c%c%c\n", exiIn->V2G_Message.Body.MeteringReceiptReq.Id.characters[0], exiIn->V2G_Message.Body.MeteringReceiptReq.Id.characters[1], exiIn->V2G_Message.Body.MeteringReceiptReq.Id.characters[2]); printf("\t\t SAScheduleTupleID=%d\n", exiIn->V2G_Message.Body.MeteringReceiptReq.SAScheduleTupleID); printf("\t\t SessionID=%d\n", exiIn->V2G_Message.Body.MeteringReceiptReq.SessionID.bytes[1]); printf("\t\t MeterInfo.MeterStatus=%d\n", exiIn->V2G_Message.Body.MeteringReceiptReq.MeterInfo.MeterStatus); printf("\t\t MeterInfo.MeterID=%d\n", exiIn->V2G_Message.Body.MeteringReceiptReq.MeterInfo.MeterID.characters[0]); /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso2BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.MeteringReceiptRes_isUsed = 1u; init_iso2MeteringReceiptResType(&exiOut->V2G_Message.Body.MeteringReceiptRes); exiOut->V2G_Message.Body.MeteringReceiptRes.ResponseCode = iso2responseCodeType_FAILED; return 0; } static int sessionStop2(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) { printf("EVSE side: sessionStop called\n" ); printf("\tReceived data:\n"); printf("\tHeader SessionID="); printBinaryArray(exiIn->V2G_Message.Header.SessionID.bytes, exiIn->V2G_Message.Header.SessionID.bytesLen); printf("\t\t ChargingSession=%d\n", exiIn->V2G_Message.Body.SessionStopReq.ChargingSession); /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso2BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.SessionStopRes_isUsed = 1u; init_iso2SessionStopResType(&exiOut->V2G_Message.Body.SessionStopRes); exiOut->V2G_Message.Body.SessionStopRes.ResponseCode = iso2responseCodeType_OK; return 0; } static int cableCheck2(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) { printf("EVSE side: cableCheck called\n" ); /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso2BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.CableCheckRes_isUsed = 1u; init_iso2CableCheckResType(&exiOut->V2G_Message.Body.CableCheckRes); exiOut->V2G_Message.Body.CableCheckRes.ResponseCode = iso2responseCodeType_OK; exiOut->V2G_Message.Body.CableCheckRes.EVSEStatus.NotificationMaxDelay = 1234; exiOut->V2G_Message.Body.CableCheckRes.EVSEStatus.EVSENotification= iso2EVSENotificationType_ReNegotiation; exiOut->V2G_Message.Body.CableCheckRes.EVSEProcessing = iso2EVSEProcessingType_Finished; return 0; } static int preCharge2(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) { printf("EVSE side: preCharge called\n" ); printf("\tReceived data:\n"); printf("\t\t EVTargetCurrent=%d (%d)\n", exiIn->V2G_Message.Body.PreChargeReq.EVTargetCurrent.Value, exiIn->V2G_Message.Body.PreChargeReq.EVTargetCurrent.Exponent); printf("\t\t EVTargetVoltage=%d (%d)\n", exiIn->V2G_Message.Body.PreChargeReq.EVTargetVoltage.Value, exiIn->V2G_Message.Body.PreChargeReq.EVTargetVoltage.Exponent); /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso2BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.PreChargeRes_isUsed = 1u; init_iso2PreChargeResType(&exiOut->V2G_Message.Body.PreChargeRes); exiOut->V2G_Message.Body.PreChargeRes.ResponseCode = iso2responseCodeType_OK; exiOut->V2G_Message.Body.PreChargeRes.EVSEStatus.EVSENotification = iso2EVSENotificationType_StopCharging; exiOut->V2G_Message.Body.PreChargeRes.EVSEStatus.NotificationMaxDelay= 1234; exiOut->V2G_Message.Body.PreChargeRes.EVSEPresentVoltage.Exponent = 3; exiOut->V2G_Message.Body.PreChargeRes.EVSEPresentVoltage.Value= 456; return 0; } static int create_response_message2(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) { int errn = ERROR_UNEXPECTED_REQUEST_MESSAGE; /* create response message as EXI document */ if(exiIn->V2G_Message_isUsed) { init_iso2EXIDocument(exiOut); if (exiIn->V2G_Message.Body.SessionSetupReq_isUsed) { errn = sessionSetup2(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.ServiceDiscoveryReq_isUsed) { errn = serviceDiscovery2(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.ServiceDetailReq_isUsed) { errn = serviceDetail2(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.PaymentServiceSelectionReq_isUsed) { errn = paymentServiceSelection2(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.PaymentDetailsReq_isUsed) { errn = paymentDetails2(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.AuthorizationReq_isUsed) { errn = authorization2(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.ChargeParameterDiscoveryReq_isUsed) { errn = chargeParameterDiscovery2(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.PowerDeliveryReq_isUsed) { errn = powerDelivery2(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.ChargingStatusReq_isUsed) { errn = chargingStatus2(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.MeteringReceiptReq_isUsed) { errn = meteringReceipt2(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.SessionStopReq_isUsed) { errn = sessionStop2(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.CableCheckReq_isUsed) { errn = cableCheck2(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.PreChargeReq_isUsed) { errn = preCharge2(exiIn, exiOut); } } return errn; } /* Adapt this to your system setup! */ /* In this situation EV and EVSE is the same party */ static int request_response2(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) { int errn; bitstream_t stream1; bitstream_t stream2; size_t pos1; size_t pos2; stream1.size = BUFFER_SIZE; stream1.data = buffer1; stream1.pos = &pos1; stream2.size = BUFFER_SIZE; stream2.data = buffer2; stream2.pos = &pos2; /* EV side */ errn = serialize2EXI2Stream(exiIn, &stream1); /* --> Start of EVSE side */ /* deserialize request message */ if (errn == 0) { errn = deserialize2Stream2EXI(&stream1, exiOut); } /* create response message */ if (errn == 0) { errn = create_response_message2(exiOut, exiIn); } /* serialize response message */ if (errn == 0) { errn = serialize2EXI2Stream(exiIn, &stream2); } /* <-- End of EVSE side */ /* EV side */ /* deserialize response message */ if (errn == 0) { errn = deserialize2Stream2EXI(&stream2, exiOut); } return errn; } static int charging2() { int errn = 0; int i, j; struct iso2EXIDocument exiIn; struct iso2EXIDocument exiOut; struct iso2ServiceDetailResType serviceDetailRes; struct iso2PaymentServiceSelectionResType paymentServiceSelectionRes; struct iso2PaymentDetailsResType paymentDetailsRes; /* setup header information */ init_iso2EXIDocument(&exiIn); exiIn.V2G_Message_isUsed = 1u; init_iso2MessageHeaderType(&exiIn.V2G_Message.Header); exiIn.V2G_Message.Header.SessionID.bytes[0] = 0; /* sessionID is always '0' at the beginning (the response contains the valid sessionID)*/ exiIn.V2G_Message.Header.SessionID.bytes[1] = 0; exiIn.V2G_Message.Header.SessionID.bytes[2] = 0; exiIn.V2G_Message.Header.SessionID.bytes[3] = 0; exiIn.V2G_Message.Header.SessionID.bytes[4] = 0; exiIn.V2G_Message.Header.SessionID.bytes[5] = 0; exiIn.V2G_Message.Header.SessionID.bytes[6] = 0; exiIn.V2G_Message.Header.SessionID.bytes[7] = 0; exiIn.V2G_Message.Header.SessionID.bytesLen = 8; exiIn.V2G_Message.Header.Signature_isUsed = 0u; /************************ * sessionSetup * ************************/ init_iso2BodyType(&exiIn.V2G_Message.Body); exiIn.V2G_Message.Body.SessionSetupReq_isUsed = 1u; init_iso2SessionSetupReqType(&exiIn.V2G_Message.Body.SessionSetupReq); exiIn.V2G_Message.Body.SessionSetupReq.EVCCID.bytesLen = 1; exiIn.V2G_Message.Body.SessionSetupReq.EVCCID.bytes[0] = 10; printf("EV side: call EVSE sessionSetup"); errn = request_response2(&exiIn, &exiOut); if(errn == 0) { /* check, if this is the right response message */ if(exiOut.V2G_Message.Body.SessionSetupRes_isUsed) { /* show results of EVSEs answer message */ printf("EV side: received response message from EVSE\n"); printf("\tHeader SessionID="); printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen); printf("\tResponseCode=%d\n", exiOut.V2G_Message.Body.SessionSetupRes.ResponseCode); printf("\tEVSEID=%d\n", exiOut.V2G_Message.Body.SessionSetupRes.EVSEID.characters[1]); printf("\tEVSETimeStamp=%li\n", (long int)exiOut.V2G_Message.Body.SessionSetupRes.EVSETimeStamp); } else { errn = ERROR_UNEXPECTED_SESSION_SETUP_RESP_MESSAGE; return errn; } } else { return errn; } /******************************************* * serviceDiscovery * *******************************************/ init_iso2BodyType(&exiIn.V2G_Message.Body); exiIn.V2G_Message.Body.ServiceDiscoveryReq_isUsed = 1u; init_iso2ServiceDiscoveryReqType(&exiIn.V2G_Message.Body.ServiceDiscoveryReq); exiIn.V2G_Message.Body.ServiceDiscoveryReq.SupportedServiceIDs_isUsed = 1u; exiIn.V2G_Message.Body.ServiceDiscoveryReq.SupportedServiceIDs.ServiceID.arrayLen = 1; exiIn.V2G_Message.Body.ServiceDiscoveryReq.SupportedServiceIDs.ServiceID.array[0] = iso2serviceCategoryType_Internet; printf("EV side: call EVSE serviceDiscovery"); errn = request_response2(&exiIn, &exiOut); if(errn == 0) { /* check, if this is the right response message */ if(exiOut.V2G_Message.Body.ServiceDiscoveryRes_isUsed) { /* show results of EVSEs answer message */ printf("EV side: received response message from EVSE\n"); printf("\tHeader SessionID="); printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen); printf("\t ResponseCode=%d\n", exiOut.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode); printf("\t Service ResponseCode=%d\n", exiOut.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode); /*printf("\t ServiceID=%d\n", exiOut.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceID); printf("\t ServiceName="); printASCIIString(serviceDiscoveryRes.ChargeService.ServiceName.characters, serviceDiscoveryRes.ChargeService.ServiceName.charactersLen); if(serviceDiscoveryRes.PaymentOptionList.PaymentOption.array[1] == v2gpaymentOptionType_Contract) { printf("\t PaymentOption=Contract_paymentOptionType\n"); } if(serviceDiscoveryRes.ChargeService.FreeService==1) { printf("\t ChargeService.FreeService=True\n"); } if(serviceDiscoveryRes.ChargeService.SupportedEnergyTransferMode.EnergyTransferMode.array[0] == v2gEnergyTransferModeType_DC_combo_core) { printf("\t EnergyTransferMode=AC_single_DC_core\n"); } if(serviceDiscoveryRes.ChargeService.SupportedEnergyTransferMode.EnergyTransferMode.array[1] == v2gEnergyTransferModeType_AC_single_phase_core) { printf("\t EnergyTransferMode=AC_single_phase_core_EnergyTransferModeType\n"); } printf("\t Value added service list:\n"); for(i=0;iEVSENotification); printf("\t\tNotificationMaxDelay=%d\n", status->NotificationMaxDelay); } /* serializes EXI stream and adds V2G TP header */ static int serialize1EXI2Stream(struct iso1EXIDocument* exiIn, bitstream_t* stream) { int errn; *stream->pos = V2GTP_HEADER_LENGTH; /* v2gtp header */ if( (errn = encode_iso1ExiDocument(stream, exiIn)) == 0) { errn = write_v2gtpHeader(stream->data, (*stream->pos)-V2GTP_HEADER_LENGTH, V2GTP_EXI_TYPE); } return errn; } /* deserializes V2G TP header and decodes right away EXI stream */ static int deserialize1Stream2EXI(bitstream_t* streamIn, struct iso1EXIDocument* exi) { int errn; uint32_t payloadLength; *streamIn->pos = 0; if ( (errn = read_v2gtpHeader(streamIn->data, &payloadLength)) == 0) { *streamIn->pos += V2GTP_HEADER_LENGTH; errn = decode_iso1ExiDocument(streamIn, exi); } return errn; } static int sessionSetup1(struct iso1EXIDocument* exiIn, struct iso1EXIDocument* exiOut) { printf("EVSE side: sessionSetup called\n" ); printf("\tReceived data:\n"); printf("\tHeader SessionID="); printBinaryArray(exiIn->V2G_Message.Header.SessionID.bytes, exiIn->V2G_Message.Header.SessionID.bytesLen); printf("\t\t EVCCID=%d\n", exiIn->V2G_Message.Body.SessionSetupReq.EVCCID.bytes[0]); exiOut->V2G_Message_isUsed = 1u; /* generate an unique sessionID */ init_iso1MessageHeaderType(&exiOut->V2G_Message.Header); exiOut->V2G_Message.Header.SessionID.bytes[0] = 1; exiOut->V2G_Message.Header.SessionID.bytes[1] = 2; exiOut->V2G_Message.Header.SessionID.bytes[2] = 3; exiOut->V2G_Message.Header.SessionID.bytes[3] = 4; exiOut->V2G_Message.Header.SessionID.bytes[4] = 5; exiOut->V2G_Message.Header.SessionID.bytes[5] = 6; exiOut->V2G_Message.Header.SessionID.bytes[6] = 7; exiOut->V2G_Message.Header.SessionID.bytes[7] = 8; exiOut->V2G_Message.Header.SessionID.bytesLen = 8; /* Prepare data for EV */ init_iso1BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.SessionSetupRes_isUsed = 1u; init_iso1SessionSetupResType(&exiOut->V2G_Message.Body.SessionSetupRes); exiOut->V2G_Message.Body.SessionSetupRes.ResponseCode = iso1responseCodeType_OK; exiOut->V2G_Message.Body.SessionSetupRes.EVSEID.characters[0] = 0; exiOut->V2G_Message.Body.SessionSetupRes.EVSEID.characters[1] = 20; exiOut->V2G_Message.Body.SessionSetupRes.EVSEID.charactersLen = 2; exiOut->V2G_Message.Body.SessionSetupRes.EVSETimeStamp_isUsed = 1u; exiOut->V2G_Message.Body.SessionSetupRes.EVSETimeStamp = 123456789; return 0; } static int serviceDetail1(struct iso1EXIDocument* exiIn, struct iso1EXIDocument* exiOut) { printf("EVSE side: serviceDetail called\n" ); printf("\tReceived data:\n"); printf("\tHeader SessionID="); printBinaryArray(exiIn->V2G_Message.Header.SessionID.bytes, exiIn->V2G_Message.Header.SessionID.bytesLen); printf("\t\t ServiceDetailID=%d\n",exiIn->V2G_Message.Body.ServiceDetailReq.ServiceID); /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso1BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.ServiceDetailRes_isUsed= 1u; init_iso1ServiceDetailResType(&exiOut->V2G_Message.Body.ServiceDetailRes); exiOut->V2G_Message.Body.ServiceDetailRes.ServiceID = 1234; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList_isUsed = 1u; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.arrayLen = 2; /* Parameter Set 1*/ exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].ParameterSetID = 1; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.arrayLen = 2; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.charactersLen = 8; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[0] = 'P'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[1] = 'r'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[2] = 'o'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[3] = 't'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[4]= 'o'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[5] = 'c'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[6] = 'o'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[7] = 'l'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].intValue = 15119; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].intValue_isUsed = 1u; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.charactersLen = 4; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.characters[0] = 'N'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.characters[1] = 'a'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.characters[2] = 'm'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.characters[3] = 'e'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].stringValue_isUsed = 1u; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].stringValue.charactersLen = 3; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].stringValue.characters[0] = 'V'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].stringValue.characters[1] = '2'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].stringValue.characters[2] = 'G'; /* Parameter Set 2 */ exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].ParameterSetID = 2; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.arrayLen = 1; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.charactersLen = 7; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[0] = 'C'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[1] = 'h'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[2] = 'a'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[3] = 'n'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[4] = 'n'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[5] = 'e'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[6] = 'l'; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].physicalValue_isUsed = 1u; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].physicalValue.Value = 1234; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].physicalValue.Multiplier = 1; exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].physicalValue.Value = 2; exiOut->V2G_Message.Body.ServiceDetailRes.ResponseCode = iso1responseCodeType_OK; return 0; } static int authorization1(struct iso1EXIDocument* exiIn, struct iso1EXIDocument* exiOut) { printf("EVSE: Authorization called\n" ); printf("\tReceived data:\n"); if(exiIn->V2G_Message.Body.AuthorizationReq.GenChallenge_isUsed) { printf("\t\t\t GenChallenge=%d\n", exiIn->V2G_Message.Body.AuthorizationReq.GenChallenge.bytes[0]); } if(exiIn->V2G_Message.Body.AuthorizationReq.Id_isUsed ) { printf("\t\t\t ID=%c%c%c\n", exiIn->V2G_Message.Body.AuthorizationReq.Id.characters[0], exiIn->V2G_Message.Body.AuthorizationReq.Id.characters[1], exiIn->V2G_Message.Body.AuthorizationReq.Id.characters[2]); } /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso1BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.AuthorizationRes_isUsed = 1u; init_iso1AuthorizationResType(&exiOut->V2G_Message.Body.AuthorizationRes); exiOut->V2G_Message.Body.AuthorizationRes.ResponseCode = iso1responseCodeType_OK; exiOut->V2G_Message.Body.AuthorizationRes.EVSEProcessing = iso1EVSEProcessingType_Finished; return 0; } static int powerDelivery1(struct iso1EXIDocument* exiIn, struct iso1EXIDocument* exiOut) { printf("EVSE side: powerDelivery called\n" ); printf("\tReceived data:\n"); printf("\t\t ChargeProgress=%d\n", exiIn->V2G_Message.Body.PowerDeliveryReq.ChargeProgress); printf("\t\t SAScheduleTupleID=%d\n", exiIn->V2G_Message.Body.PowerDeliveryReq.SAScheduleTupleID); /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso1BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.PowerDeliveryRes_isUsed = 1u; init_iso1PowerDeliveryResType(&exiOut->V2G_Message.Body.PowerDeliveryRes); exiOut->V2G_Message.Body.PowerDeliveryRes.ResponseCode = iso1responseCodeType_OK; exiOut->V2G_Message.Body.PowerDeliveryRes.EVSEStatus_isUsed = 1; exiOut->V2G_Message.Body.PowerDeliveryRes.EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging; exiOut->V2G_Message.Body.PowerDeliveryRes.EVSEStatus.NotificationMaxDelay=12; return 0; } static int chargingStatus1(struct iso1EXIDocument* exiIn, struct iso1EXIDocument* exiOut) { printf("EVSE side: chargingStatus called\n" ); /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso1BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.ChargingStatusRes_isUsed = 1u; init_iso1ChargingStatusResType(&exiOut->V2G_Message.Body.ChargingStatusRes); exiOut->V2G_Message.Body.ChargingStatusRes.ResponseCode = iso1responseCodeType_OK; exiOut->V2G_Message.Body.ChargingStatusRes.EVSEID.characters[0]= 'A'; exiOut->V2G_Message.Body.ChargingStatusRes.EVSEID.charactersLen =1; exiOut->V2G_Message.Body.ChargingStatusRes.ReceiptRequired = 1; exiOut->V2G_Message.Body.ChargingStatusRes.ReceiptRequired_isUsed = 1; return 0; } static int meteringReceipt1(struct iso1EXIDocument* exiIn, struct iso1EXIDocument* exiOut) { printf("EVSE side: meteringReceipt called\n" ); printf("\tReceived data:\n"); printf("\t\t ID=%c%c%c\n", exiIn->V2G_Message.Body.MeteringReceiptReq.Id.characters[0], exiIn->V2G_Message.Body.MeteringReceiptReq.Id.characters[1], exiIn->V2G_Message.Body.MeteringReceiptReq.Id.characters[2]); printf("\t\t SAScheduleTupleID=%d\n", exiIn->V2G_Message.Body.MeteringReceiptReq.SAScheduleTupleID); printf("\t\t SessionID=%d\n", exiIn->V2G_Message.Body.MeteringReceiptReq.SessionID.bytes[1]); printf("\t\t MeterInfo.MeterStatus=%d\n", exiIn->V2G_Message.Body.MeteringReceiptReq.MeterInfo.MeterStatus); printf("\t\t MeterInfo.MeterID=%d\n", exiIn->V2G_Message.Body.MeteringReceiptReq.MeterInfo.MeterID.characters[0]); /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso1BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.MeteringReceiptRes_isUsed = 1u; init_iso1MeteringReceiptResType(&exiOut->V2G_Message.Body.MeteringReceiptRes); exiOut->V2G_Message.Body.MeteringReceiptRes.ResponseCode = iso1responseCodeType_FAILED; return 0; } static int sessionStop1(struct iso1EXIDocument* exiIn, struct iso1EXIDocument* exiOut) { printf("EVSE side: sessionStop called\n" ); printf("\tReceived data:\n"); printf("\tHeader SessionID="); printBinaryArray(exiIn->V2G_Message.Header.SessionID.bytes, exiIn->V2G_Message.Header.SessionID.bytesLen); printf("\t\t ChargingSession=%d\n", exiIn->V2G_Message.Body.SessionStopReq.ChargingSession); /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso1BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.SessionStopRes_isUsed = 1u; init_iso1SessionStopResType(&exiOut->V2G_Message.Body.SessionStopRes); exiOut->V2G_Message.Body.SessionStopRes.ResponseCode = iso1responseCodeType_OK; return 0; } static int cableCheck1(struct iso1EXIDocument* exiIn, struct iso1EXIDocument* exiOut) { printf("EVSE side: cableCheck called\n" ); /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso1BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.CableCheckRes_isUsed = 1u; init_iso1CableCheckResType(&exiOut->V2G_Message.Body.CableCheckRes); exiOut->V2G_Message.Body.CableCheckRes.ResponseCode = iso1responseCodeType_OK; exiOut->V2G_Message.Body.CableCheckRes.DC_EVSEStatus.NotificationMaxDelay = 1234; exiOut->V2G_Message.Body.CableCheckRes.DC_EVSEStatus.EVSENotification= iso1EVSENotificationType_ReNegotiation; exiOut->V2G_Message.Body.CableCheckRes.EVSEProcessing = iso1EVSEProcessingType_Finished; return 0; } static int preCharge1(struct iso1EXIDocument* exiIn, struct iso1EXIDocument* exiOut) { printf("EVSE side: preCharge called\n" ); printf("\tReceived data:\n"); printf("\t\t EVTargetCurrent=%d (%d)\n", exiIn->V2G_Message.Body.PreChargeReq.EVTargetCurrent.Value, exiIn->V2G_Message.Body.PreChargeReq.EVTargetCurrent.Multiplier); printf("\t\t EVTargetVoltage=%d (%d)\n", exiIn->V2G_Message.Body.PreChargeReq.EVTargetVoltage.Value, exiIn->V2G_Message.Body.PreChargeReq.EVTargetVoltage.Multiplier); /* Prepare data for EV */ exiOut->V2G_Message_isUsed = 1u; init_iso1BodyType(&exiOut->V2G_Message.Body); exiOut->V2G_Message.Body.PreChargeRes_isUsed = 1u; init_iso1PreChargeResType(&exiOut->V2G_Message.Body.PreChargeRes); exiOut->V2G_Message.Body.PreChargeRes.ResponseCode = iso1responseCodeType_OK; exiOut->V2G_Message.Body.PreChargeRes.DC_EVSEStatus.EVSENotification = iso1EVSENotificationType_StopCharging; exiOut->V2G_Message.Body.PreChargeRes.DC_EVSEStatus.NotificationMaxDelay= 1234; exiOut->V2G_Message.Body.PreChargeRes.EVSEPresentVoltage.Multiplier = 3; exiOut->V2G_Message.Body.PreChargeRes.EVSEPresentVoltage.Value= 456; return 0; } static int create_response_message1(struct iso1EXIDocument* exiIn, struct iso1EXIDocument* exiOut) { int errn = ERROR_UNEXPECTED_REQUEST_MESSAGE; /* create response message as EXI document */ if(exiIn->V2G_Message_isUsed) { init_iso1EXIDocument(exiOut); if (exiIn->V2G_Message.Body.SessionSetupReq_isUsed) { errn = sessionSetup1(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.ServiceDetailReq_isUsed) { errn = serviceDetail1(exiIn, exiOut); /*} else if (exiIn->V2G_Message.Body.PaymentDetailsReq_isUsed) { errn = paymentDetails1(exiIn, exiOut);*/ } else if (exiIn->V2G_Message.Body.AuthorizationReq_isUsed) { errn = authorization1(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.PowerDeliveryReq_isUsed) { errn = powerDelivery1(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.ChargingStatusReq_isUsed) { errn = chargingStatus1(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.MeteringReceiptReq_isUsed) { errn = meteringReceipt1(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.SessionStopReq_isUsed) { errn = sessionStop1(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.CableCheckReq_isUsed) { errn = cableCheck1(exiIn, exiOut); } else if (exiIn->V2G_Message.Body.PreChargeReq_isUsed) { errn = preCharge1(exiIn, exiOut); } } return errn; } /* Adapt this to your system setup! */ /* In this situation EV and EVSE is the same party */ static int request_response1(struct iso1EXIDocument* exiIn, struct iso1EXIDocument* exiOut) { int errn; bitstream_t stream1; bitstream_t stream2; size_t pos1; size_t pos2; stream1.size = BUFFER_SIZE; stream1.data = buffer1; stream1.pos = &pos1; stream2.size = BUFFER_SIZE; stream2.data = buffer2; stream2.pos = &pos2; /* EV side */ errn = serialize1EXI2Stream(exiIn, &stream1); /* --> Start of EVSE side */ /* deserialize request message */ if (errn == 0) { errn = deserialize1Stream2EXI(&stream1, exiOut); } /* create response message */ if (errn == 0) { errn = create_response_message1(exiOut, exiIn); } /* serialize response message */ if (errn == 0) { errn = serialize1EXI2Stream(exiIn, &stream2); } /* <-- End of EVSE side */ /* EV side */ /* deserialize response message */ if (errn == 0) { errn = deserialize1Stream2EXI(&stream2, exiOut); } return errn; } static int charging1() { int errn = 0; int i, j; struct iso1EXIDocument exiIn; struct iso1EXIDocument exiOut; struct iso1ServiceDetailResType serviceDetailRes; struct iso1PaymentDetailsResType paymentDetailsRes; /* setup header information */ init_iso1EXIDocument(&exiIn); exiIn.V2G_Message_isUsed = 1u; init_iso1MessageHeaderType(&exiIn.V2G_Message.Header); exiIn.V2G_Message.Header.SessionID.bytes[0] = 0; /* sessionID is always '0' at the beginning (the response contains the valid sessionID)*/ exiIn.V2G_Message.Header.SessionID.bytes[1] = 0; exiIn.V2G_Message.Header.SessionID.bytes[2] = 0; exiIn.V2G_Message.Header.SessionID.bytes[3] = 0; exiIn.V2G_Message.Header.SessionID.bytes[4] = 0; exiIn.V2G_Message.Header.SessionID.bytes[5] = 0; exiIn.V2G_Message.Header.SessionID.bytes[6] = 0; exiIn.V2G_Message.Header.SessionID.bytes[7] = 0; exiIn.V2G_Message.Header.SessionID.bytesLen = 8; exiIn.V2G_Message.Header.Signature_isUsed = 0u; /************************ * sessionSetup * ************************/ init_iso1BodyType(&exiIn.V2G_Message.Body); exiIn.V2G_Message.Body.SessionSetupReq_isUsed = 1u; init_iso1SessionSetupReqType(&exiIn.V2G_Message.Body.SessionSetupReq); exiIn.V2G_Message.Body.SessionSetupReq.EVCCID.bytesLen = 1; exiIn.V2G_Message.Body.SessionSetupReq.EVCCID.bytes[0] = 10; printf("EV side: call EVSE sessionSetup"); errn = request_response1(&exiIn, &exiOut); if(errn == 0) { /* check, if this is the right response message */ if(exiOut.V2G_Message.Body.SessionSetupRes_isUsed) { /* show results of EVSEs answer message */ printf("EV side: received response message from EVSE\n"); printf("\tHeader SessionID="); printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen); printf("\tResponseCode=%d\n", exiOut.V2G_Message.Body.SessionSetupRes.ResponseCode); printf("\tEVSEID=%d\n", exiOut.V2G_Message.Body.SessionSetupRes.EVSEID.characters[1]); printf("\tEVSETimeStamp=%li\n", (long int)exiOut.V2G_Message.Body.SessionSetupRes.EVSETimeStamp); } else { errn = ERROR_UNEXPECTED_SESSION_SETUP_RESP_MESSAGE; return errn; } } else { return errn; } /********************************* * ServiceDetails * *********************************/ init_iso1BodyType(&exiIn.V2G_Message.Body); exiIn.V2G_Message.Body.ServiceDetailReq_isUsed = 1u; init_iso1ServiceDetailReqType(&exiIn.V2G_Message.Body.ServiceDetailReq); exiIn.V2G_Message.Body.ServiceDetailReq.ServiceID = 22; /* Value Added Server ID */ printf("EV side: call EVSE ServiceDetail \n"); errn = request_response1(&exiIn, &exiOut); if(errn == 0) { /* check, if this is the right response message */ if(exiOut.V2G_Message.Body.ServiceDetailRes_isUsed) { serviceDetailRes = exiOut.V2G_Message.Body.ServiceDetailRes; /* show results of EVSEs answer message */ printf("EV side: received response message from EVSE\n"); printf("\tHeader SessionID="); printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen); printf("\t ResponseCode=%d\n", exiOut.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode); printf("\t ServiceID=%d\n", exiOut.V2G_Message.Body.ServiceDetailRes.ServiceID); if(serviceDetailRes.ServiceParameterList_isUsed) { printf("\t\tLength=%d\n", serviceDetailRes.ServiceParameterList.ParameterSet.arrayLen );/*TEST*/ for(i=0; i U29tZSBSYW5kb20gRGF0YQ== */ init_iso2EXIFragment(&exiV2G_AR); exiV2G_AR.AuthorizationReq_isUsed = 1u; init_iso2AuthorizationReqType(&exiV2G_AR.AuthorizationReq); exiV2G_AR.AuthorizationReq.Id_isUsed = 1; exiV2G_AR.AuthorizationReq.Id.charactersLen = 3; exiV2G_AR.AuthorizationReq.Id.characters[0] = 'I'; exiV2G_AR.AuthorizationReq.Id.characters[1] = 'D'; exiV2G_AR.AuthorizationReq.Id.characters[2] = '1'; exiV2G_AR.AuthorizationReq.GenChallenge_isUsed = 1; /* base64 U29tZSBSYW5kb20gRGF0YQ== */ exiV2G_AR.AuthorizationReq.GenChallenge.bytesLen = 16; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[0] = 0x53; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[1] = 0x6F; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[2] = 0x6D; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[3] = 0x65; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[4] = 0x20; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[5] = 0x52; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[6] = 0x61; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[7] = 0x6E; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[8] = 0x64; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[9] = 0x6F; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[10] = 0x6D; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[11] = 0x20; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[12] = 0x44; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[13] = 0x61; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[14] = 0x74; exiV2G_AR.AuthorizationReq.GenChallenge.bytes[15] = 0x61; /* encode fragment with ISO schema */ errn = encode_iso2ExiFragment(&stream1, &exiV2G_AR); if((*stream1.pos) != sizeIsoStream1) { errn = -1; printf("EXI1 stream length does not match !\n"); return errn; } else { for(i=0; i 0bXgPQBlvuVrMXmERTBR61TK GPwOCRYXT4s8d6mPSqk= */ /* encode SignedInfo element with xmldsig schema */ const char arrayCanonicalEXI[35] = {"http://www.w3.org/TR/canonical-exi/"}; const char arrayxmldsigSHA256[51] = {"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"}; const char arrayxmlencSHA256[39] = {"http://www.w3.org/2001/04/xmlenc#sha256"}; init_xmldsigEXIFragment(&exiXMLDSIG_SI); exiXMLDSIG_SI.SignedInfo_isUsed = 1; init_xmldsigSignedInfoType(&exiXMLDSIG_SI.SignedInfo); { init_xmldsigCanonicalizationMethodType(&exiXMLDSIG_SI.SignedInfo.CanonicalizationMethod); exiXMLDSIG_SI.SignedInfo.CanonicalizationMethod.Algorithm.charactersLen = 35; strncpy(exiXMLDSIG_SI.SignedInfo.CanonicalizationMethod.Algorithm.characters, arrayCanonicalEXI, 35); exiXMLDSIG_SI.SignedInfo.SignatureMethod.HMACOutputLength_isUsed = 0; exiXMLDSIG_SI.SignedInfo.SignatureMethod.Algorithm.charactersLen = 51; strncpy(exiXMLDSIG_SI.SignedInfo.SignatureMethod.Algorithm.characters, arrayxmldsigSHA256, 51); exiXMLDSIG_SI.SignedInfo.Reference.arrayLen = 1; /* "#ID1" */ exiXMLDSIG_SI.SignedInfo.Reference.array[0].URI_isUsed = 1; exiXMLDSIG_SI.SignedInfo.Reference.array[0].URI.charactersLen = 4; exiXMLDSIG_SI.SignedInfo.Reference.array[0].URI.characters[0] = '#'; exiXMLDSIG_SI.SignedInfo.Reference.array[0].URI.characters[1] = 'I'; exiXMLDSIG_SI.SignedInfo.Reference.array[0].URI.characters[2] = 'D'; exiXMLDSIG_SI.SignedInfo.Reference.array[0].URI.characters[3] = '1'; /* "http://www.w3.org/TR/canonical-exi/" */ exiXMLDSIG_SI.SignedInfo.Reference.array[0].Transforms_isUsed = 1; exiXMLDSIG_SI.SignedInfo.Reference.array[0].Transforms.Transform.arrayLen = 1; exiXMLDSIG_SI.SignedInfo.Reference.array[0].Transforms.Transform.array[0].Algorithm.charactersLen = 35; strncpy(exiXMLDSIG_SI.SignedInfo.Reference.array[0].Transforms.Transform.array[0].Algorithm.characters, arrayCanonicalEXI, 35); /* Will copy 35 characters from arrayCanonicalEXI to characters */ exiXMLDSIG_SI.SignedInfo.Reference.array[0].Transforms.Transform.array[0].XPath.arrayLen = 0; exiXMLDSIG_SI.SignedInfo.Reference.array[0].DigestMethod.Algorithm.charactersLen = 39; strncpy(exiXMLDSIG_SI.SignedInfo.Reference.array[0].DigestMethod.Algorithm.characters, arrayxmlencSHA256, 39); /* "0bXgPQBlvuVrMXmERTBR61TKGPwOCRYXT4s8d6mPSqk=" --> 16 Bytes 536F6D652052616E646F6D2044617461 */ exiXMLDSIG_SI.SignedInfo.Reference.array[0].DigestValue.bytesLen = 32; memcpy(exiXMLDSIG_SI.SignedInfo.Reference.array[0].DigestValue.bytes, digestValue, 32); } errn = encode_xmldsigExiFragment(&stream2, &exiXMLDSIG_SI); if((*stream2.pos) != sizeIsoStream2) { errn = -1; printf("EXI2 stream length does not match !\n"); return errn; } else { for(i=0; i