/*
* 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