1
0

main_example.c 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777
  1. /*
  2. * Copyright (C) 2007-2017 Siemens AG
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License as published
  6. * by the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. /*******************************************************************
  18. *
  19. * @author Daniel.Peintner.EXT@siemens.com
  20. * @author Sebastian.Kaebisch@siemens.com
  21. * @version 1.0.0alpha
  22. * @contact Richard.Kuntschke@siemens.com
  23. *
  24. *
  25. ********************************************************************/
  26. #include <stdio.h>
  27. #include <stdarg.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include "EXITypes.h"
  31. #include "appHandEXIDatatypes.h"
  32. #include "appHandEXIDatatypesEncoder.h"
  33. #include "appHandEXIDatatypesDecoder.h"
  34. /* Activate support for DIN */
  35. #include "dinEXIDatatypes.h"
  36. #if DEPLOY_DIN_CODEC == SUPPORT_YES
  37. #include "dinEXIDatatypesEncoder.h"
  38. #include "dinEXIDatatypesDecoder.h"
  39. #endif /* DEPLOY_DIN_CODEC == SUPPORT_YES */
  40. /* Activate support for XMLDSIG */
  41. #include "xmldsigEXIDatatypes.h"
  42. #if DEPLOY_XMLDSIG_CODEC == SUPPORT_YES
  43. #include "xmldsigEXIDatatypesEncoder.h"
  44. #include "xmldsigEXIDatatypesDecoder.h"
  45. #endif /* DEPLOY_XMLDSIG_CODEC == SUPPORT_YES */
  46. /* Activate support for ISO2 */
  47. #include "iso2EXIDatatypes.h"
  48. #if DEPLOY_ISO2_CODEC == SUPPORT_YES
  49. #include "iso2EXIDatatypesEncoder.h"
  50. #include "iso2EXIDatatypesDecoder.h"
  51. #endif /* DEPLOY_ISO2_CODEC == SUPPORT_YES */
  52. #include "v2gtp.h"
  53. #define BUFFER_SIZE 256
  54. uint8_t buffer1[BUFFER_SIZE];
  55. uint8_t buffer2[BUFFER_SIZE];
  56. #define ERROR_UNEXPECTED_REQUEST_MESSAGE -601
  57. #define ERROR_UNEXPECTED_SESSION_SETUP_RESP_MESSAGE -602
  58. #define ERROR_UNEXPECTED_SERVICE_DISCOVERY_RESP_MESSAGE -602
  59. #define ERROR_UNEXPECTED_SERVICE_DETAILS_RESP_MESSAGE -603
  60. #define ERROR_UNEXPECTED_PAYMENT_SERVICE_SELECTION_RESP_MESSAGE -604
  61. #define ERROR_UNEXPECTED_PAYMENT_DETAILS_RESP_MESSAGE -605
  62. #define ERROR_UNEXPECTED_AUTHORIZATION_RESP_MESSAGE -606
  63. #define ERROR_UNEXPECTED_CHARGE_PARAMETER_DISCOVERY_RESP_MESSAGE -607
  64. #define ERROR_UNEXPECTED_POWER_DELIVERY_RESP_MESSAGE -608
  65. #define ERROR_UNEXPECTED_CHARGING_STATUS_RESP_MESSAGE -609
  66. #define ERROR_UNEXPECTED_METERING_RECEIPT_RESP_MESSAGE -610
  67. #define ERROR_UNEXPECTED_SESSION_STOP_RESP_MESSAGE -611
  68. #define ERROR_UNEXPECTED_CABLE_CHECK_RESP_MESSAGE -612
  69. #define ERROR_UNEXPECTED_PRE_CHARGE_RESP_MESSAGE -612
  70. #define ERROR_UNEXPECTED_CURRENT_DEMAND_RESP_MESSAGE -613
  71. #define ERROR_UNEXPECTED_WELDING_DETECTION_RESP_MESSAGE -614
  72. static int writeStringToEXIString(char* string, exi_string_character_t* exiString) {
  73. int pos = 0;
  74. while(string[pos]!='\0')
  75. {
  76. exiString[pos] = string[pos];
  77. pos++;
  78. }
  79. return pos;
  80. }
  81. static void printASCIIString(exi_string_character_t* string, uint16_t len) {
  82. unsigned int i;
  83. for(i=0; i<len; i++) {
  84. printf("%c",(char)string[i]);
  85. }
  86. printf("\n");
  87. }
  88. static void printEVSEStatus(struct iso2EVSEStatusType* status)
  89. {
  90. printf("\tEVSEStatus:\n");
  91. printf("\t\tEVSENotification=%d\n", status->EVSENotification);
  92. printf("\t\tNotificationMaxDelay=%d\n", status->NotificationMaxDelay);
  93. }
  94. static void printBinaryArray(uint8_t* byte, uint16_t len) {
  95. unsigned int i;
  96. for(i=0; i<len; i++) {
  97. printf("%d ",byte[i]);
  98. }
  99. printf("\n");
  100. }
  101. static void copyBytes(uint8_t* from, uint16_t len, uint8_t* to) {
  102. int i;
  103. for(i=0; i<len; i++) {
  104. to[i] = from[i];
  105. }
  106. }
  107. /* serializes EXI stream and adds V2G TP header */
  108. static int serializeEXI2Stream(struct iso2EXIDocument* exiIn, bitstream_t* stream) {
  109. int errn;
  110. *stream->pos = V2GTP_HEADER_LENGTH; /* v2gtp header */
  111. if( (errn = encode_iso2ExiDocument(stream, exiIn)) == 0) {
  112. errn = write_v2gtpHeader(stream->data, (*stream->pos)-V2GTP_HEADER_LENGTH, V2GTP_EXI_TYPE);
  113. }
  114. return errn;
  115. }
  116. /* deserializes V2G TP header and decodes right away EXI stream */
  117. static int deserializeStream2EXI(bitstream_t* streamIn, struct iso2EXIDocument* exi) {
  118. int errn;
  119. uint32_t payloadLength;
  120. *streamIn->pos = 0;
  121. if ( (errn = read_v2gtpHeader(streamIn->data, &payloadLength)) == 0) {
  122. *streamIn->pos += V2GTP_HEADER_LENGTH;
  123. errn = decode_iso2ExiDocument(streamIn, exi);
  124. }
  125. return errn;
  126. }
  127. /** Example implementation of the app handshake protocol for the EVSE side */
  128. static int appHandshakeHandler(bitstream_t* iStream, bitstream_t* oStream) {
  129. struct appHandEXIDocument appHandResp;
  130. int i;
  131. struct appHandEXIDocument exiDoc;
  132. int errn = 0;
  133. uint32_t payloadLengthDec;
  134. if ( (errn = read_v2gtpHeader(iStream->data, &payloadLengthDec)) == 0) {
  135. *iStream->pos = V2GTP_HEADER_LENGTH;
  136. if( (errn = decode_appHandExiDocument(iStream, &exiDoc)) ) {
  137. /* an error occured */
  138. return errn;
  139. }
  140. }
  141. printf("EVSE side: List of application handshake protocols of the EV \n");
  142. for(i=0;i<exiDoc.supportedAppProtocolReq.AppProtocol.arrayLen;i++) {
  143. printf("\tProtocol entry #=%d\n",(i+1));
  144. printf("\t\tProtocolNamespace=");
  145. printASCIIString(exiDoc.supportedAppProtocolReq.AppProtocol.array[i].ProtocolNamespace.characters, exiDoc.supportedAppProtocolReq.AppProtocol.array[i].ProtocolNamespace.charactersLen);
  146. printf("\t\tVersion=%d.%d\n", exiDoc.supportedAppProtocolReq.AppProtocol.array[i].VersionNumberMajor, exiDoc.supportedAppProtocolReq.AppProtocol.array[i].VersionNumberMinor);
  147. printf("\t\tSchemaID=%d\n", exiDoc.supportedAppProtocolReq.AppProtocol.array[i].SchemaID);
  148. printf("\t\tPriority=%d\n", exiDoc.supportedAppProtocolReq.AppProtocol.array[i].Priority);
  149. }
  150. /* prepare response handshake response:
  151. * it is assumed, we support the 15118 1.0 version :-) */
  152. init_appHandEXIDocument(&appHandResp);
  153. appHandResp.supportedAppProtocolRes_isUsed = 1u;
  154. appHandResp.supportedAppProtocolRes.ResponseCode = appHandresponseCodeType_OK_SuccessfulNegotiation;
  155. appHandResp.supportedAppProtocolRes.SchemaID = exiDoc.supportedAppProtocolReq.AppProtocol.array[0].SchemaID; /* signal the protocol by the provided schema id*/
  156. appHandResp.supportedAppProtocolRes.SchemaID_isUsed = 1u;
  157. *oStream->pos = V2GTP_HEADER_LENGTH;
  158. if( (errn = encode_appHandExiDocument(oStream, &appHandResp)) == 0) {
  159. errn = write_v2gtpHeader(oStream->data, (*oStream->pos)-V2GTP_HEADER_LENGTH, V2GTP_EXI_TYPE);
  160. }
  161. return errn;
  162. }
  163. static int appHandshake()
  164. {
  165. bitstream_t stream1;
  166. bitstream_t stream2;
  167. uint32_t payloadLengthDec;
  168. size_t pos1 = V2GTP_HEADER_LENGTH; /* v2gtp header */
  169. size_t pos2 = 0;
  170. struct appHandEXIDocument handshake;
  171. struct appHandEXIDocument handshakeResp;
  172. int errn = 0;
  173. char* ns0 = "urn:iso:15118:2:2010:MsgDef";
  174. char* ns1 = "urn:din:70121:2012:MsgDef";
  175. stream1.size = BUFFER_SIZE;
  176. stream1.data = buffer1;
  177. stream1.pos = &pos1;
  178. stream2.size = BUFFER_SIZE;
  179. stream2.data = buffer2;
  180. stream2.pos = &pos2;
  181. init_appHandEXIDocument(&handshake);
  182. printf("EV side: setup data for the supported application handshake request message\n");
  183. /* set up ISO/IEC 15118 Version 1.0 information */
  184. handshake.supportedAppProtocolReq_isUsed = 1u;
  185. handshake.supportedAppProtocolReq.AppProtocol.arrayLen = 2; /* we have only two protocols implemented */
  186. handshake.supportedAppProtocolReq.AppProtocol.array[0].ProtocolNamespace.charactersLen =
  187. writeStringToEXIString(ns0, handshake.supportedAppProtocolReq.AppProtocol.array[0].ProtocolNamespace.characters);
  188. handshake.supportedAppProtocolReq.AppProtocol.array[0].SchemaID = 1;
  189. handshake.supportedAppProtocolReq.AppProtocol.array[0].VersionNumberMajor = 1;
  190. handshake.supportedAppProtocolReq.AppProtocol.array[0].VersionNumberMinor = 0;
  191. handshake.supportedAppProtocolReq.AppProtocol.array[0].Priority = 1;
  192. handshake.supportedAppProtocolReq.AppProtocol.array[1].ProtocolNamespace.charactersLen =
  193. writeStringToEXIString(ns1, handshake.supportedAppProtocolReq.AppProtocol.array[1].ProtocolNamespace.characters);
  194. handshake.supportedAppProtocolReq.AppProtocol.array[1].SchemaID = 2;
  195. handshake.supportedAppProtocolReq.AppProtocol.array[1].VersionNumberMajor = 1;
  196. handshake.supportedAppProtocolReq.AppProtocol.array[1].VersionNumberMinor = 0;
  197. handshake.supportedAppProtocolReq.AppProtocol.array[1].Priority = 2;
  198. /* send app handshake request */
  199. if( (errn = encode_appHandExiDocument(&stream1, &handshake)) == 0) {
  200. if ( write_v2gtpHeader(stream1.data, pos1-V2GTP_HEADER_LENGTH, V2GTP_EXI_TYPE) == 0 ) {
  201. printf("EV side: send message to the EVSE\n");
  202. }
  203. }
  204. if (errn == 0) {
  205. /* read app handshake request & generate response */
  206. errn = appHandshakeHandler(&stream1, &stream2);
  207. }
  208. if (errn == 0) {
  209. /* check response */
  210. if ( (errn = read_v2gtpHeader(stream2.data, &payloadLengthDec)) == 0) {
  211. pos2 = V2GTP_HEADER_LENGTH;
  212. if(decode_appHandExiDocument(&stream2, &handshakeResp) == 0) {
  213. printf("EV side: Response of the EVSE \n");
  214. if(handshakeResp.supportedAppProtocolRes.ResponseCode == appHandresponseCodeType_OK_SuccessfulNegotiation) {
  215. printf("\t\tResponseCode=OK_SuccessfulNegotiation\n");
  216. printf("\t\tSchemaID=%d\n",handshakeResp.supportedAppProtocolRes.SchemaID);
  217. }
  218. }
  219. }
  220. }
  221. if (errn != 0) {
  222. printf("appHandshake error %d \n", errn);
  223. }
  224. return errn;
  225. }
  226. static int sessionSetup(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) {
  227. printf("EVSE side: sessionSetup called\n" );
  228. printf("\tReceived data:\n");
  229. printf("\tHeader SessionID=");
  230. printBinaryArray(exiIn->V2G_Message.Header.SessionID.bytes, exiIn->V2G_Message.Header.SessionID.bytesLen);
  231. printf("\t\t EVCCID=%d\n", exiIn->V2G_Message.Body.SessionSetupReq.EVCCID.bytes[0]);
  232. exiOut->V2G_Message_isUsed = 1u;
  233. /* generate an unique sessionID */
  234. init_iso2MessageHeaderType(&exiOut->V2G_Message.Header);
  235. exiOut->V2G_Message.Header.SessionID.bytes[0] = 1;
  236. exiOut->V2G_Message.Header.SessionID.bytes[1] = 2;
  237. exiOut->V2G_Message.Header.SessionID.bytes[2] = 3;
  238. exiOut->V2G_Message.Header.SessionID.bytes[3] = 4;
  239. exiOut->V2G_Message.Header.SessionID.bytes[4] = 5;
  240. exiOut->V2G_Message.Header.SessionID.bytes[5] = 6;
  241. exiOut->V2G_Message.Header.SessionID.bytes[6] = 7;
  242. exiOut->V2G_Message.Header.SessionID.bytes[7] = 8;
  243. exiOut->V2G_Message.Header.SessionID.bytesLen = 8;
  244. /* Prepare data for EV */
  245. init_iso2BodyType(&exiOut->V2G_Message.Body);
  246. exiOut->V2G_Message.Body.SessionSetupRes_isUsed = 1u;
  247. init_iso2SessionSetupResType(&exiOut->V2G_Message.Body.SessionSetupRes);
  248. exiOut->V2G_Message.Body.SessionSetupRes.ResponseCode = iso2responseCodeType_OK;
  249. exiOut->V2G_Message.Body.SessionSetupRes.EVSEID.characters[0] = 0;
  250. exiOut->V2G_Message.Body.SessionSetupRes.EVSEID.characters[1] = 20;
  251. exiOut->V2G_Message.Body.SessionSetupRes.EVSEID.charactersLen = 2;
  252. exiOut->V2G_Message.Body.SessionSetupRes.EVSETimeStamp_isUsed = 1u;
  253. exiOut->V2G_Message.Body.SessionSetupRes.EVSETimeStamp = 123456789;
  254. return 0;
  255. }
  256. static int serviceDiscovery(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) {
  257. int i;
  258. printf("EVSE side: serviceDiscovery called\n" );
  259. printf("\tReceived data:\n");
  260. printf("\tHeader SessionID=");
  261. printBinaryArray(exiIn->V2G_Message.Header.SessionID.bytes, exiIn->V2G_Message.Header.SessionID.bytesLen);
  262. if(exiIn->V2G_Message.Body.ServiceDiscoveryReq.SupportedServiceIDs_isUsed) {
  263. for(i=0;i<exiIn->V2G_Message.Body.ServiceDiscoveryReq.SupportedServiceIDs.ServiceID.arrayLen; i++) {
  264. printf("\t\tSupportedServiceID=%d\n", exiIn->V2G_Message.Body.ServiceDiscoveryReq.SupportedServiceIDs.ServiceID.array[i]);
  265. }
  266. }
  267. /* Prepare data for EV */
  268. exiOut->V2G_Message_isUsed = 1u;
  269. init_iso2BodyType(&exiOut->V2G_Message.Body);
  270. exiOut->V2G_Message.Body.ServiceDiscoveryRes_isUsed = 1u;
  271. init_iso2ServiceDiscoveryResType(&exiOut->V2G_Message.Body.ServiceDiscoveryRes);
  272. exiOut->V2G_Message.Body.ServiceDiscoveryRes.VASList_isUsed = 0u; /* we do not provide VAS */
  273. exiOut->V2G_Message.Body.ServiceDiscoveryRes.ResponseCode = iso2responseCodeType_OK;
  274. exiOut->V2G_Message.Body.ServiceDiscoveryRes.PaymentOptionList.PaymentOption.array[0] = iso2paymentOptionType_ExternalPayment; /* EVSE handles the payment */
  275. exiOut->V2G_Message.Body.ServiceDiscoveryRes.PaymentOptionList.PaymentOption.array[1] = iso2paymentOptionType_Contract;
  276. exiOut->V2G_Message.Body.ServiceDiscoveryRes.PaymentOptionList.PaymentOption.arrayLen = 2;
  277. exiOut->V2G_Message.Body.ServiceDiscoveryRes.EnergyTransferServiceList.Service.arrayLen = 1;
  278. exiOut->V2G_Message.Body.ServiceDiscoveryRes.EnergyTransferServiceList.Service.array[0].ServiceID = 1; /* ID of the charge service */
  279. exiOut->V2G_Message.Body.ServiceDiscoveryRes.EnergyTransferServiceList.Service.array[0].FreeService = 1;
  280. exiOut->V2G_Message.Body.ServiceDiscoveryRes.VASList_isUsed = 0u; /* no value added service requested */
  281. return 0;
  282. }
  283. static int serviceDetail(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) {
  284. printf("EVSE side: serviceDetail called\n" );
  285. printf("\tReceived data:\n");
  286. printf("\tHeader SessionID=");
  287. printBinaryArray(exiIn->V2G_Message.Header.SessionID.bytes, exiIn->V2G_Message.Header.SessionID.bytesLen);
  288. printf("\t\t ServiceDetailID=%d\n",exiIn->V2G_Message.Body.ServiceDetailReq.ServiceID);
  289. /* Prepare data for EV */
  290. exiOut->V2G_Message_isUsed = 1u;
  291. init_iso2BodyType(&exiOut->V2G_Message.Body);
  292. exiOut->V2G_Message.Body.ServiceDetailRes_isUsed= 1u;
  293. init_iso2ServiceDetailResType(&exiOut->V2G_Message.Body.ServiceDetailRes);
  294. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceID = 1234;
  295. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList_isUsed = 1u;
  296. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.arrayLen = 2;
  297. /* Parameter Set 1*/
  298. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].ParameterSetID = 1;
  299. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.arrayLen = 2;
  300. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.charactersLen = 8;
  301. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[0] = 'P';
  302. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[1] = 'r';
  303. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[2] = 'o';
  304. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[3] = 't';
  305. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[4]= 'o';
  306. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[5] = 'c';
  307. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[6] = 'o';
  308. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].Name.characters[7] = 'l';
  309. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].intValue = 15119;
  310. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[0].intValue_isUsed = 1u;
  311. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.charactersLen = 4;
  312. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.characters[0] = 'N';
  313. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.characters[1] = 'a';
  314. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.characters[2] = 'm';
  315. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].Name.characters[3] = 'e';
  316. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].stringValue_isUsed = 1u;
  317. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].stringValue.charactersLen = 3;
  318. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].stringValue.characters[0] = 'V';
  319. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].stringValue.characters[1] = '2';
  320. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[0].Parameter.array[1].stringValue.characters[2] = 'G';
  321. /* Parameter Set 2 */
  322. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].ParameterSetID = 2;
  323. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.arrayLen = 1;
  324. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.charactersLen = 7;
  325. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[0] = 'C';
  326. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[1] = 'h';
  327. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[2] = 'a';
  328. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[3] = 'n';
  329. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[4] = 'n';
  330. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[5] = 'e';
  331. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].Name.characters[6] = 'l';
  332. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].physicalValue_isUsed = 1u;
  333. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].physicalValue.Value = 1234;
  334. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].physicalValue.Exponent = 1;
  335. exiOut->V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[1].Parameter.array[0].physicalValue.Value = 2;
  336. exiOut->V2G_Message.Body.ServiceDetailRes.ResponseCode = iso2responseCodeType_OK;
  337. return 0;
  338. }
  339. static int paymentServiceSelection(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) {
  340. int i;
  341. printf("EVSE side: paymentServiceSelection called\n" );
  342. printf("\tReceived data:\n");
  343. printf("\tHeader SessionID=");
  344. printBinaryArray(exiIn->V2G_Message.Header.SessionID.bytes, exiIn->V2G_Message.Header.SessionID.bytesLen);
  345. if(exiIn->V2G_Message.Body.PaymentServiceSelectionReq.SelectedPaymentOption == iso2paymentOptionType_ExternalPayment) {
  346. printf("\t\t SelectedPaymentOption=ExternalPayment\n");
  347. }
  348. if(exiIn->V2G_Message.Body.PaymentServiceSelectionReq.SelectedVASList_isUsed) {
  349. for(i=0; i<exiIn->V2G_Message.Body.PaymentServiceSelectionReq.SelectedVASList.SelectedService.arrayLen;i++)
  350. {
  351. printf("\t\t ServiceID=%d\n", exiIn->V2G_Message.Body.PaymentServiceSelectionReq.SelectedVASList.SelectedService.array[i].ServiceID);
  352. printf("\t\t ParameterSetID=%d\n", exiIn->V2G_Message.Body.PaymentServiceSelectionReq.SelectedVASList.SelectedService.array[i].ParameterSetID);
  353. }
  354. }
  355. /* Prepare data for EV */
  356. exiOut->V2G_Message_isUsed = 1u;
  357. init_iso2BodyType(&exiOut->V2G_Message.Body);
  358. exiOut->V2G_Message.Body.PaymentServiceSelectionRes_isUsed= 1u;
  359. init_iso2PaymentServiceSelectionResType(&exiOut->V2G_Message.Body.PaymentServiceSelectionRes);
  360. exiOut->V2G_Message.Body.ServiceDetailRes.ResponseCode = iso2responseCodeType_OK;
  361. return 0;
  362. }
  363. static int paymentDetails(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) {
  364. printf("EVSE side: paymentDetails called\n" );
  365. printf("\tReceived data:\n");
  366. printf("\t\t eMAID=%d\n", exiIn->V2G_Message.Body.PaymentDetailsReq.eMAID.characters[0]);
  367. 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]);
  368. 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]);
  369. 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]);
  370. 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]);
  371. /* Prepare data for EV */
  372. exiOut->V2G_Message_isUsed = 1u;
  373. init_iso2BodyType(&exiOut->V2G_Message.Body);
  374. exiOut->V2G_Message.Body.PaymentDetailsRes_isUsed = 1u;
  375. init_iso2PaymentDetailsResType(&exiOut->V2G_Message.Body.PaymentDetailsRes);
  376. exiOut->V2G_Message.Body.PaymentDetailsRes.ResponseCode = iso2responseCodeType_OK;
  377. exiOut->V2G_Message.Body.PaymentDetailsRes.GenChallenge.bytesLen = 1;
  378. exiOut->V2G_Message.Body.PaymentDetailsRes.GenChallenge.bytes[0] = 1;
  379. exiOut->V2G_Message.Body.PaymentDetailsRes.EVSETimeStamp = 123456;
  380. return 0;
  381. }
  382. static int authorization(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) {
  383. printf("EVSE: Authorization called\n" );
  384. printf("\tReceived data:\n");
  385. if(exiIn->V2G_Message.Body.AuthorizationReq.GenChallenge_isUsed) {
  386. printf("\t\t\t GenChallenge=%d\n", exiIn->V2G_Message.Body.AuthorizationReq.GenChallenge.bytes[0]);
  387. }
  388. if(exiIn->V2G_Message.Body.AuthorizationReq.Id_isUsed ) {
  389. 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]);
  390. }
  391. /* Prepare data for EV */
  392. exiOut->V2G_Message_isUsed = 1u;
  393. init_iso2BodyType(&exiOut->V2G_Message.Body);
  394. exiOut->V2G_Message.Body.AuthorizationRes_isUsed = 1u;
  395. init_iso2AuthorizationResType(&exiOut->V2G_Message.Body.AuthorizationRes);
  396. exiOut->V2G_Message.Body.AuthorizationRes.ResponseCode = iso2responseCodeType_OK;
  397. exiOut->V2G_Message.Body.AuthorizationRes.EVSEProcessing = iso2EVSEProcessingType_Finished;
  398. return 0;
  399. }
  400. static int chargeParameterDiscovery(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) {
  401. printf("EVSE side: chargeParameterDiscovery called\n" );
  402. printf("\tReceived data:\n");
  403. if(exiIn->V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter_isUsed) {
  404. printf("\t\t DepartureTime=%d\n", exiIn->V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.DepartureTime);
  405. printf("\t\t EVMaximumChargeCurrent=%d\n", exiIn->V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMaximumChargeCurrent.Value);
  406. }
  407. /* Prepare data for EV */
  408. exiOut->V2G_Message_isUsed = 1u;
  409. init_iso2BodyType(&exiOut->V2G_Message.Body);
  410. exiOut->V2G_Message.Body.ChargeParameterDiscoveryRes_isUsed = 1u;
  411. init_iso2ChargeParameterDiscoveryResType(&exiOut->V2G_Message.Body.ChargeParameterDiscoveryRes);
  412. exiOut->V2G_Message.Body.ChargeParameterDiscoveryRes.ResponseCode = iso2responseCodeType_OK_CertificateExpiresSoon;
  413. exiOut->V2G_Message.Body.ChargeParameterDiscoveryRes.EVSEProcessing = iso2EVSEProcessingType_Ongoing;
  414. exiOut->V2G_Message.Body.ChargeParameterDiscoveryRes.EVSEEnergyTransferParameter_isUsed = 1u;
  415. /*exiOut->V2G_Message.Body.ChargeParameterDiscoveryRes.EVSEEnergyTransferParameter = 0;*/
  416. return 0;
  417. }
  418. static int powerDelivery(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) {
  419. printf("EVSE side: powerDelivery called\n" );
  420. printf("\tReceived data:\n");
  421. printf("\t\t ChargeProgress=%d\n", exiIn->V2G_Message.Body.PowerDeliveryReq.ChargeProgress);
  422. printf("\t\t SAScheduleTupleID=%d\n", exiIn->V2G_Message.Body.PowerDeliveryReq.SAScheduleTupleID);
  423. /* Prepare data for EV */
  424. exiOut->V2G_Message_isUsed = 1u;
  425. init_iso2BodyType(&exiOut->V2G_Message.Body);
  426. exiOut->V2G_Message.Body.PowerDeliveryRes_isUsed = 1u;
  427. init_iso2PowerDeliveryResType(&exiOut->V2G_Message.Body.PowerDeliveryRes);
  428. exiOut->V2G_Message.Body.PowerDeliveryRes.ResponseCode = iso2responseCodeType_OK;
  429. exiOut->V2G_Message.Body.PowerDeliveryRes.EVSEStatus_isUsed = 1;
  430. exiOut->V2G_Message.Body.PowerDeliveryRes.EVSEStatus.EVSENotification = iso2EVSENotificationType_StopCharging;
  431. exiOut->V2G_Message.Body.PowerDeliveryRes.EVSEStatus.NotificationMaxDelay=12;
  432. exiOut->V2G_Message.Body.PowerDeliveryRes.EVSEProcessing = iso2EVSEProcessingType_Ongoing_WaitingForCustomerInteraction;
  433. return 0;
  434. }
  435. static int chargingStatus(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) {
  436. printf("EVSE side: chargingStatus called\n" );
  437. /* Prepare data for EV */
  438. exiOut->V2G_Message_isUsed = 1u;
  439. init_iso2BodyType(&exiOut->V2G_Message.Body);
  440. exiOut->V2G_Message.Body.ChargingStatusRes_isUsed = 1u;
  441. init_iso2ChargingStatusResType(&exiOut->V2G_Message.Body.ChargingStatusRes);
  442. exiOut->V2G_Message.Body.ChargingStatusRes.ResponseCode = iso2responseCodeType_OK;
  443. exiOut->V2G_Message.Body.ChargingStatusRes.EVSEID.characters[0]= 'A';
  444. exiOut->V2G_Message.Body.ChargingStatusRes.EVSEID.charactersLen =1;
  445. exiOut->V2G_Message.Body.ChargingStatusRes.EVSEStatus.EVSENotification = iso2EVSENotificationType_ReNegotiation;
  446. exiOut->V2G_Message.Body.ChargingStatusRes.EVSEStatus.NotificationMaxDelay=123;
  447. exiOut->V2G_Message.Body.ChargingStatusRes.ReceiptRequired = 1;
  448. exiOut->V2G_Message.Body.ChargingStatusRes.ReceiptRequired_isUsed = 1;
  449. return 0;
  450. }
  451. static int meteringReceipt(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) {
  452. printf("EVSE side: meteringReceipt called\n" );
  453. printf("\tReceived data:\n");
  454. 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]);
  455. printf("\t\t SAScheduleTupleID=%d\n", exiIn->V2G_Message.Body.MeteringReceiptReq.SAScheduleTupleID);
  456. printf("\t\t SessionID=%d\n", exiIn->V2G_Message.Body.MeteringReceiptReq.SessionID.bytes[1]);
  457. printf("\t\t MeterInfo.MeterStatus=%d\n", exiIn->V2G_Message.Body.MeteringReceiptReq.MeterInfo.MeterStatus);
  458. printf("\t\t MeterInfo.MeterID=%d\n", exiIn->V2G_Message.Body.MeteringReceiptReq.MeterInfo.MeterID.characters[0]);
  459. /* Prepare data for EV */
  460. exiOut->V2G_Message_isUsed = 1u;
  461. init_iso2BodyType(&exiOut->V2G_Message.Body);
  462. exiOut->V2G_Message.Body.MeteringReceiptRes_isUsed = 1u;
  463. init_iso2MeteringReceiptResType(&exiOut->V2G_Message.Body.MeteringReceiptRes);
  464. exiOut->V2G_Message.Body.MeteringReceiptRes.ResponseCode = iso2responseCodeType_FAILED;
  465. return 0;
  466. }
  467. static int sessionStop(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) {
  468. printf("EVSE side: sessionStop called\n" );
  469. printf("\tReceived data:\n");
  470. printf("\tHeader SessionID=");
  471. printBinaryArray(exiIn->V2G_Message.Header.SessionID.bytes, exiIn->V2G_Message.Header.SessionID.bytesLen);
  472. printf("\t\t ChargingSession=%d\n", exiIn->V2G_Message.Body.SessionStopReq.ChargingSession);
  473. /* Prepare data for EV */
  474. exiOut->V2G_Message_isUsed = 1u;
  475. init_iso2BodyType(&exiOut->V2G_Message.Body);
  476. exiOut->V2G_Message.Body.SessionStopRes_isUsed = 1u;
  477. init_iso2SessionStopResType(&exiOut->V2G_Message.Body.SessionStopRes);
  478. exiOut->V2G_Message.Body.SessionStopRes.ResponseCode = iso2responseCodeType_OK;
  479. return 0;
  480. }
  481. static int cableCheck(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) {
  482. printf("EVSE side: cableCheck called\n" );
  483. /* Prepare data for EV */
  484. exiOut->V2G_Message_isUsed = 1u;
  485. init_iso2BodyType(&exiOut->V2G_Message.Body);
  486. exiOut->V2G_Message.Body.CableCheckRes_isUsed = 1u;
  487. init_iso2CableCheckResType(&exiOut->V2G_Message.Body.CableCheckRes);
  488. exiOut->V2G_Message.Body.CableCheckRes.ResponseCode = iso2responseCodeType_OK;
  489. exiOut->V2G_Message.Body.CableCheckRes.EVSEStatus.NotificationMaxDelay = 1234;
  490. exiOut->V2G_Message.Body.CableCheckRes.EVSEStatus.EVSENotification= iso2EVSENotificationType_ReNegotiation;
  491. exiOut->V2G_Message.Body.CableCheckRes.EVSEProcessing = iso2EVSEProcessingType_Finished;
  492. return 0;
  493. }
  494. static int preCharge(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) {
  495. printf("EVSE side: preCharge called\n" );
  496. printf("\tReceived data:\n");
  497. printf("\t\t EVTargetCurrent=%d (%d)\n", exiIn->V2G_Message.Body.PreChargeReq.EVTargetCurrent.Value, exiIn->V2G_Message.Body.PreChargeReq.EVTargetCurrent.Exponent);
  498. printf("\t\t EVTargetVoltage=%d (%d)\n", exiIn->V2G_Message.Body.PreChargeReq.EVTargetVoltage.Value, exiIn->V2G_Message.Body.PreChargeReq.EVTargetVoltage.Exponent);
  499. /* Prepare data for EV */
  500. exiOut->V2G_Message_isUsed = 1u;
  501. init_iso2BodyType(&exiOut->V2G_Message.Body);
  502. exiOut->V2G_Message.Body.PreChargeRes_isUsed = 1u;
  503. init_iso2PreChargeResType(&exiOut->V2G_Message.Body.PreChargeRes);
  504. exiOut->V2G_Message.Body.PreChargeRes.ResponseCode = iso2responseCodeType_OK;
  505. exiOut->V2G_Message.Body.PreChargeRes.EVSEStatus.EVSENotification = iso2EVSENotificationType_StopCharging;
  506. exiOut->V2G_Message.Body.PreChargeRes.EVSEStatus.NotificationMaxDelay= 1234;
  507. exiOut->V2G_Message.Body.PreChargeRes.EVSEPresentVoltage.Exponent = 3;
  508. exiOut->V2G_Message.Body.PreChargeRes.EVSEPresentVoltage.Value= 456;
  509. return 0;
  510. }
  511. static int create_response_message(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) {
  512. int errn = ERROR_UNEXPECTED_REQUEST_MESSAGE;
  513. /* create response message as EXI document */
  514. if(exiIn->V2G_Message_isUsed) {
  515. init_iso2EXIDocument(exiOut);
  516. if (exiIn->V2G_Message.Body.SessionSetupReq_isUsed) {
  517. errn = sessionSetup(exiIn, exiOut);
  518. } else if (exiIn->V2G_Message.Body.ServiceDiscoveryReq_isUsed) {
  519. errn = serviceDiscovery(exiIn, exiOut);
  520. } else if (exiIn->V2G_Message.Body.ServiceDetailReq_isUsed) {
  521. errn = serviceDetail(exiIn, exiOut);
  522. } else if (exiIn->V2G_Message.Body.PaymentServiceSelectionReq_isUsed) {
  523. errn = paymentServiceSelection(exiIn, exiOut);
  524. } else if (exiIn->V2G_Message.Body.PaymentDetailsReq_isUsed) {
  525. errn = paymentDetails(exiIn, exiOut);
  526. } else if (exiIn->V2G_Message.Body.AuthorizationReq_isUsed) {
  527. errn = authorization(exiIn, exiOut);
  528. } else if (exiIn->V2G_Message.Body.ChargeParameterDiscoveryReq_isUsed) {
  529. errn = chargeParameterDiscovery(exiIn, exiOut);
  530. } else if (exiIn->V2G_Message.Body.PowerDeliveryReq_isUsed) {
  531. errn = powerDelivery(exiIn, exiOut);
  532. } else if (exiIn->V2G_Message.Body.ChargingStatusReq_isUsed) {
  533. errn = chargingStatus(exiIn, exiOut);
  534. } else if (exiIn->V2G_Message.Body.MeteringReceiptReq_isUsed) {
  535. errn = meteringReceipt(exiIn, exiOut);
  536. } else if (exiIn->V2G_Message.Body.SessionStopReq_isUsed) {
  537. errn = sessionStop(exiIn, exiOut);
  538. } else if (exiIn->V2G_Message.Body.CableCheckReq_isUsed) {
  539. errn = cableCheck(exiIn, exiOut);
  540. } else if (exiIn->V2G_Message.Body.PreChargeReq_isUsed) {
  541. errn = preCharge(exiIn, exiOut);
  542. }
  543. }
  544. return errn;
  545. }
  546. /* Adapt this to your system setup! */
  547. /* In this situation EV and EVSE is the same party */
  548. static int request_response(struct iso2EXIDocument* exiIn, struct iso2EXIDocument* exiOut) {
  549. int errn;
  550. bitstream_t stream1;
  551. bitstream_t stream2;
  552. size_t pos1;
  553. size_t pos2;
  554. stream1.size = BUFFER_SIZE;
  555. stream1.data = buffer1;
  556. stream1.pos = &pos1;
  557. stream2.size = BUFFER_SIZE;
  558. stream2.data = buffer2;
  559. stream2.pos = &pos2;
  560. /* EV side */
  561. errn = serializeEXI2Stream(exiIn, &stream1);
  562. /* --> Start of EVSE side */
  563. /* deserialize request message */
  564. if (errn == 0) {
  565. errn = deserializeStream2EXI(&stream1, exiOut);
  566. }
  567. /* create response message */
  568. if (errn == 0) {
  569. errn = create_response_message(exiOut, exiIn);
  570. }
  571. /* serialize response message */
  572. if (errn == 0) {
  573. errn = serializeEXI2Stream(exiIn, &stream2);
  574. }
  575. /* <-- End of EVSE side */
  576. /* EV side */
  577. /* deserialize response message */
  578. if (errn == 0) {
  579. errn = deserializeStream2EXI(&stream2, exiOut);
  580. }
  581. return errn;
  582. }
  583. static int charging()
  584. {
  585. int errn = 0;
  586. int i, j;
  587. struct iso2EXIDocument exiIn;
  588. struct iso2EXIDocument exiOut;
  589. struct iso2ServiceDetailResType serviceDetailRes;
  590. struct iso2PaymentServiceSelectionResType paymentServiceSelectionRes;
  591. struct iso2PaymentDetailsResType paymentDetailsRes;
  592. /* setup header information */
  593. init_iso2EXIDocument(&exiIn);
  594. exiIn.V2G_Message_isUsed = 1u;
  595. init_iso2MessageHeaderType(&exiIn.V2G_Message.Header);
  596. exiIn.V2G_Message.Header.SessionID.bytes[0] = 0; /* sessionID is always '0' at the beginning (the response contains the valid sessionID)*/
  597. exiIn.V2G_Message.Header.SessionID.bytes[1] = 0;
  598. exiIn.V2G_Message.Header.SessionID.bytes[2] = 0;
  599. exiIn.V2G_Message.Header.SessionID.bytes[3] = 0;
  600. exiIn.V2G_Message.Header.SessionID.bytes[4] = 0;
  601. exiIn.V2G_Message.Header.SessionID.bytes[5] = 0;
  602. exiIn.V2G_Message.Header.SessionID.bytes[6] = 0;
  603. exiIn.V2G_Message.Header.SessionID.bytes[7] = 0;
  604. exiIn.V2G_Message.Header.SessionID.bytesLen = 8;
  605. exiIn.V2G_Message.Header.Signature_isUsed = 0u;
  606. /************************
  607. * sessionSetup *
  608. ************************/
  609. init_iso2BodyType(&exiIn.V2G_Message.Body);
  610. exiIn.V2G_Message.Body.SessionSetupReq_isUsed = 1u;
  611. init_iso2SessionSetupReqType(&exiIn.V2G_Message.Body.SessionSetupReq);
  612. exiIn.V2G_Message.Body.SessionSetupReq.EVCCID.bytesLen = 1;
  613. exiIn.V2G_Message.Body.SessionSetupReq.EVCCID.bytes[0] = 10;
  614. printf("EV side: call EVSE sessionSetup");
  615. errn = request_response(&exiIn, &exiOut);
  616. if(errn == 0) {
  617. /* check, if this is the right response message */
  618. if(exiOut.V2G_Message.Body.SessionSetupRes_isUsed) {
  619. /* show results of EVSEs answer message */
  620. printf("EV side: received response message from EVSE\n");
  621. printf("\tHeader SessionID=");
  622. printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen);
  623. printf("\tResponseCode=%d\n", exiOut.V2G_Message.Body.SessionSetupRes.ResponseCode);
  624. printf("\tEVSEID=%d\n", exiOut.V2G_Message.Body.SessionSetupRes.EVSEID.characters[1]);
  625. printf("\tEVSETimeStamp=%li\n", (long int)exiOut.V2G_Message.Body.SessionSetupRes.EVSETimeStamp);
  626. } else {
  627. errn = ERROR_UNEXPECTED_SESSION_SETUP_RESP_MESSAGE;
  628. return errn;
  629. }
  630. } else {
  631. return errn;
  632. }
  633. /*******************************************
  634. * serviceDiscovery *
  635. *******************************************/
  636. init_iso2BodyType(&exiIn.V2G_Message.Body);
  637. exiIn.V2G_Message.Body.ServiceDiscoveryReq_isUsed = 1u;
  638. init_iso2ServiceDiscoveryReqType(&exiIn.V2G_Message.Body.ServiceDiscoveryReq);
  639. exiIn.V2G_Message.Body.ServiceDiscoveryReq.SupportedServiceIDs_isUsed = 1u;
  640. exiIn.V2G_Message.Body.ServiceDiscoveryReq.SupportedServiceIDs.ServiceID.arrayLen = 1;
  641. exiIn.V2G_Message.Body.ServiceDiscoveryReq.SupportedServiceIDs.ServiceID.array[0] = iso2serviceCategoryType_Internet;
  642. printf("EV side: call EVSE serviceDiscovery");
  643. errn = request_response(&exiIn, &exiOut);
  644. if(errn == 0) {
  645. /* check, if this is the right response message */
  646. if(exiOut.V2G_Message.Body.ServiceDiscoveryRes_isUsed) {
  647. /* show results of EVSEs answer message */
  648. printf("EV side: received response message from EVSE\n");
  649. printf("\tHeader SessionID=");
  650. printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen);
  651. printf("\t ResponseCode=%d\n", exiOut.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode);
  652. printf("\t Service ResponseCode=%d\n", exiOut.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode);
  653. /*printf("\t ServiceID=%d\n", exiOut.V2G_Message.Body.ServiceDiscoveryRes.ChargeService.ServiceID);
  654. printf("\t ServiceName=");
  655. printASCIIString(serviceDiscoveryRes.ChargeService.ServiceName.characters, serviceDiscoveryRes.ChargeService.ServiceName.charactersLen);
  656. if(serviceDiscoveryRes.PaymentOptionList.PaymentOption.array[1] == v2gpaymentOptionType_Contract) {
  657. printf("\t PaymentOption=Contract_paymentOptionType\n");
  658. }
  659. if(serviceDiscoveryRes.ChargeService.FreeService==1) {
  660. printf("\t ChargeService.FreeService=True\n");
  661. }
  662. if(serviceDiscoveryRes.ChargeService.SupportedEnergyTransferMode.EnergyTransferMode.array[0] == v2gEnergyTransferModeType_DC_combo_core) {
  663. printf("\t EnergyTransferMode=AC_single_DC_core\n");
  664. }
  665. if(serviceDiscoveryRes.ChargeService.SupportedEnergyTransferMode.EnergyTransferMode.array[1] == v2gEnergyTransferModeType_AC_single_phase_core) {
  666. printf("\t EnergyTransferMode=AC_single_phase_core_EnergyTransferModeType\n");
  667. }
  668. printf("\t Value added service list:\n");
  669. for(i=0;i<serviceDiscoveryRes.ServiceList.Service.arrayLen;i++)
  670. {
  671. printf("\n\t\t ServiceID=%d\n", serviceDiscoveryRes.ServiceList.Service.array[i].ServiceID);
  672. printf("\t\t ServiceName=");
  673. printASCIIString(serviceDiscoveryRes.ServiceList.Service.array[i].ServiceName.characters, exiOut.V2G_Message.Body.ServiceDiscoveryRes.ServiceList.Service.array[i].ServiceName.charactersLen );
  674. if(serviceDiscoveryRes.ServiceList.Service.array[i].ServiceCategory == v2gserviceCategoryType_Internet) {
  675. printf("\t\t ServiceCategory=Internet\n");
  676. }
  677. if(serviceDiscoveryRes.ServiceList.Service.array[i].FreeService==1) {
  678. printf("\t\t FreeService=True\n");
  679. }
  680. }*/
  681. } else {
  682. errn = ERROR_UNEXPECTED_SERVICE_DISCOVERY_RESP_MESSAGE;
  683. return errn;
  684. }
  685. } else {
  686. return errn;
  687. }
  688. /*********************************
  689. * ServiceDetails *
  690. *********************************/
  691. init_iso2BodyType(&exiIn.V2G_Message.Body);
  692. exiIn.V2G_Message.Body.ServiceDetailReq_isUsed = 1u;
  693. init_iso2ServiceDetailReqType(&exiIn.V2G_Message.Body.ServiceDetailReq);
  694. exiIn.V2G_Message.Body.ServiceDetailReq.ServiceID = 22; /* Value Added Server ID */
  695. printf("EV side: call EVSE ServiceDetail \n");
  696. errn = request_response(&exiIn, &exiOut);
  697. if(errn == 0) {
  698. /* check, if this is the right response message */
  699. if(exiOut.V2G_Message.Body.ServiceDetailRes_isUsed) {
  700. serviceDetailRes = exiOut.V2G_Message.Body.ServiceDetailRes;
  701. /* show results of EVSEs answer message */
  702. printf("EV side: received response message from EVSE\n");
  703. printf("\tHeader SessionID=");
  704. printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen);
  705. printf("\t ResponseCode=%d\n", exiOut.V2G_Message.Body.ServiceDiscoveryRes.ResponseCode);
  706. printf("\t ServiceID=%d\n", exiOut.V2G_Message.Body.ServiceDetailRes.ServiceID);
  707. if(serviceDetailRes.ServiceParameterList_isUsed) {
  708. printf("\t\tLength=%d\n", serviceDetailRes.ServiceParameterList.ParameterSet.arrayLen );/*TEST*/
  709. for(i=0; i<serviceDetailRes.ServiceParameterList.ParameterSet.arrayLen; i++)
  710. {
  711. printf("\t\tServiceSetID=%d\n", serviceDetailRes.ServiceParameterList.ParameterSet.array[i].ParameterSetID);
  712. printf("\t\tParameters=%d\n", serviceDetailRes.ServiceParameterList.ParameterSet.array[i].Parameter.arrayLen);
  713. for(j=0; j<serviceDetailRes.ServiceParameterList.ParameterSet.array[i].Parameter.arrayLen; j++)
  714. {
  715. printf("\t\t\t %d: ParameterName=", j+1);
  716. printASCIIString(serviceDetailRes.ServiceParameterList.ParameterSet.array[i].Parameter.array[j].Name.characters, exiOut.V2G_Message.Body.ServiceDetailRes.ServiceParameterList.ParameterSet.array[i].Parameter.array[j].Name.charactersLen);
  717. /*if(serviceDetailRes.ServiceParameterList.ParameterSet.array[i].Parameter.array[j].shortValue_isUsed == 1u) {
  718. printf("\t\t\t %d: StringValue=", j+1);
  719. printASCIIString(serviceDetailRes.ServiceParameterList.ParameterSet.array[i].Parameter.array[j].stringValue.characters, serviceDetailRes.ServiceParameterList.ParameterSet.array[i].Parameter.array[j].stringValue.charactersLen);
  720. } else if(serviceDetailRes.ServiceParameterList.ParameterSet.array[i].Parameter.array[j].intValue_isUsed == 1u) {
  721. printf("\t\t\t %d: IntValue=%d\n", j+1, serviceDetailRes.ServiceParameterList.ParameterSet.array[i].Parameter.array[j].intValue);
  722. } else if(serviceDetailRes.ServiceParameterList.ParameterSet.array[i].Parameter.array[j].physicalValue_isUsed == 1u) {
  723. printf("\t\t\t %d: PhysicalValue=%d (%d)\n", j+1, serviceDetailRes.ServiceParameterList.ParameterSet.array[i].Parameter.array[j].physicalValue.Value, serviceDetailRes.ServiceParameterList.ParameterSet.array[i].Parameter.array[j].physicalValue.Multiplier);
  724. }*/
  725. }
  726. }
  727. }
  728. } else {
  729. errn = ERROR_UNEXPECTED_SERVICE_DETAILS_RESP_MESSAGE;
  730. return errn;
  731. }
  732. } else {
  733. return errn;
  734. }
  735. /*******************************************
  736. * ServicePaymentSelection *
  737. *******************************************/
  738. init_iso2BodyType(&exiIn.V2G_Message.Body);
  739. exiIn.V2G_Message.Body.PaymentServiceSelectionReq_isUsed = 1u;
  740. init_iso2PaymentServiceSelectionReqType(&exiIn.V2G_Message.Body.PaymentServiceSelectionReq);
  741. exiIn.V2G_Message.Body.PaymentServiceSelectionReq.SelectedPaymentOption = iso2paymentOptionType_ExternalPayment;
  742. exiIn.V2G_Message.Body.PaymentServiceSelectionReq.SelectedVASList_isUsed = 0u;
  743. exiIn.V2G_Message.Body.PaymentServiceSelectionReq.SelectedEnergyTransferService.ServiceID = 1;
  744. exiIn.V2G_Message.Body.PaymentServiceSelectionReq.SelectedEnergyTransferService.ParameterSetID = 4;
  745. printf("EV side: call EVSE ServicePaymentSelection \n");
  746. errn = request_response(&exiIn, &exiOut);
  747. if(errn == 0) {
  748. /* check, if this is the right response message */
  749. if(exiOut.V2G_Message.Body.PaymentServiceSelectionRes_isUsed) {
  750. paymentServiceSelectionRes = exiOut.V2G_Message.Body.PaymentServiceSelectionRes;
  751. /* show results of EVSEs answer message */
  752. printf("EV side: received response message from EVSE\n");
  753. if(exiOut.V2G_Message.Body.PaymentServiceSelectionRes.EVSEStatus_isUsed) {
  754. printf("\tHeader SessionID=");
  755. printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen);
  756. }
  757. printf("\t ResponseCode=%d\n", paymentServiceSelectionRes.ResponseCode);
  758. } else {
  759. errn = ERROR_UNEXPECTED_PAYMENT_SERVICE_SELECTION_RESP_MESSAGE;
  760. return errn;
  761. }
  762. } else {
  763. return errn;
  764. }
  765. /**********************************
  766. * PaymentDetails *
  767. **********************************/
  768. init_iso2BodyType(&exiIn.V2G_Message.Body);
  769. exiIn.V2G_Message.Body.PaymentDetailsReq_isUsed = 1u;
  770. init_iso2PaymentDetailsReqType(&exiIn.V2G_Message.Body.PaymentDetailsReq);
  771. exiIn.V2G_Message.Body.PaymentDetailsReq.eMAID.characters[0] = 1;
  772. exiIn.V2G_Message.Body.PaymentDetailsReq.eMAID.characters[1] = 123;
  773. exiIn.V2G_Message.Body.PaymentDetailsReq.eMAID.charactersLen =2;
  774. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.Certificate.bytes[0] = 'C';
  775. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.Certificate.bytes[1] = 'e';
  776. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.Certificate.bytesLen = 2;
  777. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.SubCertificates_isUsed = 1u;
  778. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.SubCertificates.Certificate.array[0].bytes[0] = 'S';
  779. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.SubCertificates.Certificate.array[0].bytes[1] = 'u';
  780. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.SubCertificates.Certificate.array[0].bytesLen = 2;
  781. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.SubCertificates.Certificate.array[1].bytes[0] = 'S';
  782. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.SubCertificates.Certificate.array[1].bytes[1] = 'u';
  783. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.SubCertificates.Certificate.array[1].bytes[2] = '2';
  784. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.SubCertificates.Certificate.array[1].bytesLen = 3;
  785. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.SubCertificates.Certificate.arrayLen =2;
  786. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.Id_isUsed = 1u;
  787. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.Id.charactersLen = 2;
  788. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.Id.characters[0] = 'I';
  789. exiIn.V2G_Message.Body.PaymentDetailsReq.ContractSignatureCertChain.Id.characters[0] = 'd';
  790. printf("EV side: call EVSE ServiceDetail \n");
  791. errn = request_response(&exiIn, &exiOut);
  792. if(errn == 0) {
  793. /* check, if this is the right response message */
  794. if(exiOut.V2G_Message.Body.PaymentDetailsRes_isUsed) {
  795. paymentDetailsRes = exiOut.V2G_Message.Body.PaymentDetailsRes;
  796. printf("EV side: received response message from EVSE\n");
  797. /* show results of EVSEs answer message */
  798. printf("\tHeader SessionID=");
  799. printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen);
  800. printf("\t ResponseCode=%d\n", paymentDetailsRes.ResponseCode);
  801. printf("\tEVSETimeStamp=%li\n", (long int) paymentDetailsRes.EVSETimeStamp);
  802. printf("\tGenChallenge=%d\n", paymentDetailsRes.GenChallenge.bytes[0]);
  803. } else {
  804. errn = ERROR_UNEXPECTED_PAYMENT_DETAILS_RESP_MESSAGE;
  805. return errn;
  806. }
  807. } else {
  808. return errn;
  809. }
  810. /*******************************************
  811. * Authorization *
  812. *******************************************/
  813. init_iso2BodyType(&exiIn.V2G_Message.Body);
  814. exiIn.V2G_Message.Body.AuthorizationReq_isUsed = 1u;
  815. init_iso2AuthorizationReqType(&exiIn.V2G_Message.Body.AuthorizationReq);
  816. copyBytes(paymentDetailsRes.GenChallenge.bytes, paymentDetailsRes.GenChallenge.bytesLen, exiIn.V2G_Message.Body.AuthorizationReq.GenChallenge.bytes);
  817. exiIn.V2G_Message.Body.AuthorizationReq.GenChallenge.bytesLen = paymentDetailsRes.GenChallenge.bytesLen;
  818. exiIn.V2G_Message.Body.AuthorizationReq.GenChallenge_isUsed = 1u; /* no challenge needed here*/
  819. exiIn.V2G_Message.Body.AuthorizationReq.Id_isUsed = 1u; /* no signature needed here */
  820. exiIn.V2G_Message.Body.AuthorizationReq.Id.charactersLen = 3;
  821. exiIn.V2G_Message.Body.AuthorizationReq.Id.characters[0] = 'I';
  822. exiIn.V2G_Message.Body.AuthorizationReq.Id.characters[1] = 'd';
  823. exiIn.V2G_Message.Body.AuthorizationReq.Id.characters[2] = '2';
  824. printf("EV side: call EVSE Authorization \n");
  825. errn = request_response(&exiIn, &exiOut);
  826. if(errn == 0) {
  827. /* check, if this is the right response message */
  828. if(exiOut.V2G_Message.Body.AuthorizationRes_isUsed) {
  829. /* show results of EVSEs answer message */
  830. printf("EV side: received response message from EVSE\n");
  831. printf("\tHeader SessionID=");
  832. printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen);
  833. printf("\t ResponseCode=%d\n", exiOut.V2G_Message.Body.AuthorizationRes.ResponseCode);
  834. if(exiOut.V2G_Message.Body.AuthorizationRes.EVSEProcessing == iso2EVSEProcessingType_Finished) {
  835. printf("\t EVSEProcessing=Finished\n");
  836. }
  837. } else {
  838. errn = ERROR_UNEXPECTED_AUTHORIZATION_RESP_MESSAGE;
  839. return errn;
  840. }
  841. } else {
  842. return errn;
  843. }
  844. /*******************************************
  845. * chargeParameterDiscovery *
  846. *******************************************/
  847. init_iso2BodyType(&exiIn.V2G_Message.Body);
  848. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq_isUsed = 1u;
  849. init_iso2ChargeParameterDiscoveryReqType(&exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq);
  850. /* we use here AC based charging parameters */
  851. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.MaxSupportingPoints_isUsed = 1u;
  852. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.MaxSupportingPoints = 1234;
  853. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter_isUsed = 1u;
  854. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.DepartureTime = 12345;
  855. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMaximumChargePower.Exponent = 0;
  856. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMaximumChargePower.Value = 100;
  857. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMaximumChargeCurrent.Exponent = 0;
  858. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMaximumChargeCurrent.Value = 400;
  859. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMinimumChargeCurrent.Exponent = 0;
  860. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMinimumChargeCurrent.Value = 200;
  861. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMaximumVoltage.Exponent = 0;
  862. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMaximumVoltage.Value = 400;
  863. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMaximumDischargePower.Exponent = 0;
  864. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMaximumDischargePower.Value = 200;
  865. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMaximumDischargeCurrent.Exponent = 0;
  866. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMaximumDischargeCurrent.Value = 400;
  867. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMinimumDischargeCurrent.Exponent = 0;
  868. exiIn.V2G_Message.Body.ChargeParameterDiscoveryReq.AC_EVBidirectionalParameter.EVMinimumDischargeCurrent.Value = 200;
  869. printf("EV side: call EVSE chargeParameterDiscovery");
  870. errn = request_response(&exiIn, &exiOut);
  871. if(errn == 0) {
  872. /* check, if this is the right response message */
  873. if(exiOut.V2G_Message.Body.ChargeParameterDiscoveryRes_isUsed) {
  874. /* show results of EVSEs answer message */
  875. printf("EV side: received response message from EVSE\n");
  876. printf("\tHeader SessionID=");
  877. printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen);
  878. printf("\t ResponseCode=%d\n", exiOut.V2G_Message.Body.ChargeParameterDiscoveryRes.ResponseCode);
  879. /*printACEVSEStatus(&(exiOut.V2G_Message.Body.ChargeParameterDiscoveryRes.AC_EVSEChargeParameter.AC_EVSEStatus));
  880. printf("\t EVSEProcessing=%d\n", exiOut.V2G_Message.Body.ChargeParameterDiscoveryRes.EVSEProcessing);
  881. printf("\t EVSEMaxCurrent=%d\n", exiOut.V2G_Message.Body.ChargeParameterDiscoveryRes.AC_EVSEChargeParameter.EVSEMaxCurrent.Value);
  882. printf("\t EVSENominalVoltage=%d\n", exiOut.V2G_Message.Body.ChargeParameterDiscoveryRes.AC_EVSEChargeParameter.EVSENominalVoltage.Value);*/
  883. } else {
  884. errn = ERROR_UNEXPECTED_CHARGE_PARAMETER_DISCOVERY_RESP_MESSAGE;
  885. return errn;
  886. }
  887. } else {
  888. return errn;
  889. }
  890. /*****************************
  891. * cableCheck *
  892. *****************************/
  893. init_iso2BodyType(&exiIn.V2G_Message.Body);
  894. exiIn.V2G_Message.Body.CableCheckReq_isUsed = 1u;
  895. /*init_v2gCableCheckReqType(&exiIn.V2G_Message.Body.CableCheckReq);*/
  896. printf("EV side: call EVSE cableCheck \n");
  897. errn = request_response(&exiIn, &exiOut);
  898. if(errn == 0) {
  899. /* check, if this is the right response message */
  900. if(exiOut.V2G_Message.Body.CableCheckRes_isUsed) {
  901. /* show results of EVSEs answer message */
  902. printf("EV side: received response message from EVSE\n");
  903. printf("\tHeader SessionID=");
  904. printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen);
  905. printf("\t ResponseCode=%d\n", exiOut.V2G_Message.Body.CableCheckRes.ResponseCode);
  906. if(exiOut.V2G_Message.Body.CableCheckRes.EVSEProcessing==iso2EVSEProcessingType_Finished) {
  907. printf("\tEVSEProcessing=Finished\n");
  908. }
  909. printEVSEStatus(&(exiOut.V2G_Message.Body.CableCheckRes.EVSEStatus));
  910. } else {
  911. errn = ERROR_UNEXPECTED_CABLE_CHECK_RESP_MESSAGE;
  912. return errn;
  913. }
  914. } else {
  915. return errn;
  916. }
  917. /*****************************
  918. * preCharge *
  919. *****************************/
  920. init_iso2BodyType(&exiIn.V2G_Message.Body);
  921. exiIn.V2G_Message.Body.PreChargeReq_isUsed = 1u;
  922. init_iso2PreChargeReqType(&exiIn.V2G_Message.Body.PreChargeReq);
  923. exiIn.V2G_Message.Body.PreChargeReq.EVTargetCurrent.Exponent = 1;
  924. exiIn.V2G_Message.Body.PreChargeReq.EVTargetCurrent.Value = 234;
  925. exiIn.V2G_Message.Body.PreChargeReq.EVTargetVoltage.Exponent = 1;
  926. exiIn.V2G_Message.Body.PreChargeReq.EVTargetVoltage.Value = 100;
  927. printf("EV side: call EVSE preCharge \n");
  928. errn = request_response(&exiIn, &exiOut);
  929. if(errn == 0) {
  930. /* check, if this is the right response message */
  931. if(exiOut.V2G_Message.Body.PreChargeRes_isUsed) {
  932. /* show results of EVSEs answer message */
  933. printf("EV side: received response message from EVSE\n");
  934. printf("\tHeader SessionID=");
  935. printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen);
  936. printf("\t ResponseCode=%d\n", exiOut.V2G_Message.Body.PreChargeRes.ResponseCode);
  937. printEVSEStatus(&exiOut.V2G_Message.Body.PreChargeRes.EVSEStatus);
  938. printf("\tEVSEPresentVoltage=%d (%d %d)\n", exiOut.V2G_Message.Body.PreChargeRes.EVSEPresentVoltage.Value, exiOut.V2G_Message.Body.PreChargeRes.EVSEPresentVoltage.Value, exiOut.V2G_Message.Body.PreChargeRes.EVSEPresentVoltage.Exponent);
  939. } else {
  940. errn = ERROR_UNEXPECTED_PRE_CHARGE_RESP_MESSAGE;
  941. return errn;
  942. }
  943. } else {
  944. return errn;
  945. }
  946. /*********************************
  947. * PowerDelivery *
  948. *********************************/
  949. init_iso2BodyType(&exiIn.V2G_Message.Body);
  950. exiIn.V2G_Message.Body.PowerDeliveryReq_isUsed = 1u;
  951. init_iso2PowerDeliveryReqType(&exiIn.V2G_Message.Body.PowerDeliveryReq);
  952. exiIn.V2G_Message.Body.PowerDeliveryReq.ChargeProgress = iso2chargeProgressType_Start;
  953. exiIn.V2G_Message.Body.PowerDeliveryReq.SAScheduleTupleID_isUsed = 1u;
  954. exiIn.V2G_Message.Body.PowerDeliveryReq.SAScheduleTupleID = exiOut.V2G_Message.Body.ChargeParameterDiscoveryRes.SAScheduleList.SAScheduleTuple.array[0].SAScheduleTupleID;
  955. printf("EV side: call EVSE powerDelivery \n");
  956. errn = request_response(&exiIn, &exiOut);
  957. if(errn == 0) {
  958. /* check, if this is the right response message */
  959. if(exiOut.V2G_Message.Body.PowerDeliveryRes_isUsed) {
  960. /* show results of EVSEs answer message */
  961. printf("EV side: received response message from EVSE\n");
  962. printf("\tHeader SessionID=");
  963. printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen);
  964. printf("\t ResponseCode=%d\n", exiOut.V2G_Message.Body.PowerDeliveryRes.ResponseCode);
  965. /*printACEVSEStatus(&(exiOut.V2G_Message.Body.PowerDeliveryRes.AC_EVSEStatus));*/
  966. } else {
  967. errn = ERROR_UNEXPECTED_POWER_DELIVERY_RESP_MESSAGE;
  968. return errn;
  969. }
  970. } else {
  971. return errn;
  972. }
  973. /*********************************
  974. * Setup data for chargingStatus *
  975. *********************************/
  976. init_iso2BodyType(&exiIn.V2G_Message.Body);
  977. exiIn.V2G_Message.Body.ChargingStatusReq_isUsed = 1u;
  978. init_iso2ChargingStatusReqType(&exiIn.V2G_Message.Body.ChargingStatusReq);
  979. exiIn.V2G_Message.Body.ChargingStatusReq.EVTargetEnergyRequest.Exponent = 2;
  980. exiIn.V2G_Message.Body.ChargingStatusReq.EVTargetEnergyRequest.Value = 100;
  981. printf("EV side: call EVSE chargingStatus \n");
  982. errn = request_response(&exiIn, &exiOut);
  983. if(errn == 0) {
  984. /* check, if this is the right response message */
  985. if(exiOut.V2G_Message.Body.ChargingStatusRes_isUsed) {
  986. /* show results of EVSEs answer message */
  987. printf("EV side: received response message from EVSE\n");
  988. printf("\tHeader SessionID=");
  989. printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen);
  990. printf("\t ResponseCode=%d\n", exiOut.V2G_Message.Body.ChargingStatusRes.ResponseCode);
  991. /*printACEVSEStatus(&(exiOut.V2G_Message.Body.ChargingStatusRes.AC_EVSEStatus));
  992. printf("\tReceiptRequired=%d\n", exiOut.V2G_Message.Body.ChargingStatusRes.ReceiptRequired);
  993. printf("\tEVSEID=%d\n", exiOut.V2G_Message.Body.ChargingStatusRes.EVSEID.characters[0]);
  994. printf("\tSAScheduleTupleID=%d\n", exiOut.V2G_Message.Body.ChargingStatusRes.SAScheduleTupleID);
  995. printf("\tEVSEMaxCurrent=%d (%d %d)\n", exiOut.V2G_Message.Body.ChargingStatusRes.EVSEMaxCurrent.Value, exiOut.V2G_Message.Body.ChargingStatusRes.EVSEMaxCurrent.Unit, exiOut.V2G_Message.Body.ChargingStatusRes.EVSEMaxCurrent.Multiplier);
  996. printf("\tisused.MeterInfo=%d\n", exiOut.V2G_Message.Body.ChargingStatusRes.MeterInfo_isUsed);
  997. printf("\t\tMeterInfo.MeterID=%d\n", exiOut.V2G_Message.Body.ChargingStatusRes.MeterInfo.MeterID.characters[0]);
  998. printf("\t\tMeterInfo.MeterReading.Value=%li\n", (long int)exiOut.V2G_Message.Body.ChargingStatusRes.MeterInfo.MeterReading);
  999. printf("\t\tMeterInfo.MeterStatus=%d\n", exiOut.V2G_Message.Body.ChargingStatusRes.MeterInfo.MeterStatus);
  1000. printf("\t\tMeterInfo.TMeter=%li\n", (long int)exiOut.V2G_Message.Body.ChargingStatusRes.MeterInfo.TMeter);
  1001. printf("\t\tMeterInfo.SigMeterReading.data=%d\n", exiOut.V2G_Message.Body.ChargingStatusRes.MeterInfo.SigMeterReading.bytes[0]);*/
  1002. } else {
  1003. errn = ERROR_UNEXPECTED_CHARGING_STATUS_RESP_MESSAGE;
  1004. return errn;
  1005. }
  1006. } else {
  1007. return errn;
  1008. }
  1009. /***********************************
  1010. * MeteringReceipt *
  1011. ***********************************/
  1012. init_iso2BodyType(&exiIn.V2G_Message.Body);
  1013. exiIn.V2G_Message.Body.MeteringReceiptReq_isUsed = 1u;
  1014. init_iso2MeteringReceiptReqType(&exiIn.V2G_Message.Body.MeteringReceiptReq);
  1015. exiIn.V2G_Message.Body.MeteringReceiptReq.Id.characters[0]='I';
  1016. exiIn.V2G_Message.Body.MeteringReceiptReq.Id.characters[1]='d';
  1017. exiIn.V2G_Message.Body.MeteringReceiptReq.Id.characters[2]='3';
  1018. exiIn.V2G_Message.Body.MeteringReceiptReq.Id.charactersLen =3;
  1019. exiIn.V2G_Message.Body.MeteringReceiptReq.SessionID.bytes[0] = 22;
  1020. exiIn.V2G_Message.Body.MeteringReceiptReq.SessionID.bytesLen = 1;
  1021. init_iso2MeterInfoType(&exiIn.V2G_Message.Body.MeteringReceiptReq.MeterInfo);
  1022. exiIn.V2G_Message.Body.MeteringReceiptReq.MeterInfo.MeterID.characters[0] = 'M';
  1023. exiIn.V2G_Message.Body.MeteringReceiptReq.MeterInfo.MeterID.characters[1] = 'i';
  1024. exiIn.V2G_Message.Body.MeteringReceiptReq.MeterInfo.MeterID.characters[2] = 'd';
  1025. exiIn.V2G_Message.Body.MeteringReceiptReq.MeterInfo.MeterID.charactersLen = 3;
  1026. printf("EV side: call EVSE meteringReceipt \n");
  1027. errn = request_response(&exiIn, &exiOut);
  1028. if(errn == 0) {
  1029. /* check, if this is the right response message */
  1030. if(exiOut.V2G_Message.Body.MeteringReceiptRes_isUsed) {
  1031. /* show results of EVSEs answer message */
  1032. printf("EV side: received response message from EVSE\n");
  1033. printf("\tHeader SessionID=");
  1034. printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen);
  1035. printf("\t ResponseCode=%d\n", exiOut.V2G_Message.Body.MeteringReceiptRes.ResponseCode);
  1036. } else {
  1037. errn = ERROR_UNEXPECTED_METERING_RECEIPT_RESP_MESSAGE;
  1038. return errn;
  1039. }
  1040. } else {
  1041. return errn;
  1042. }
  1043. /***********************************
  1044. * SessionStop *
  1045. ***********************************/
  1046. init_iso2BodyType(&exiIn.V2G_Message.Body);
  1047. exiIn.V2G_Message.Body.SessionStopReq_isUsed = 1u;
  1048. init_iso2SessionStopReqType(&exiIn.V2G_Message.Body.SessionStopReq);
  1049. exiIn.V2G_Message.Body.SessionStopReq.ChargingSession = iso2chargingSessionType_Pause;
  1050. printf("EV side: call EVSE stopSession \n");
  1051. errn = request_response(&exiIn, &exiOut);
  1052. if(errn == 0) {
  1053. /* check, if this is the right response message */
  1054. if(exiOut.V2G_Message.Body.SessionStopRes_isUsed) {
  1055. /* show results of EVSEs answer message */
  1056. printf("EV side: received response message from EVSE\n");
  1057. printf("\tHeader SessionID=");
  1058. printBinaryArray(exiOut.V2G_Message.Header.SessionID.bytes, exiOut.V2G_Message.Header.SessionID.bytesLen);
  1059. printf("\t ResponseCode=%d\n", exiOut.V2G_Message.Body.SessionStopRes.ResponseCode);
  1060. } else {
  1061. errn = ERROR_UNEXPECTED_SESSION_STOP_RESP_MESSAGE;
  1062. return errn;
  1063. }
  1064. } else {
  1065. return errn;
  1066. }
  1067. return errn;
  1068. }
  1069. #if DEPLOY_DIN_CODEC == SUPPORT_YES
  1070. static int din_test() {
  1071. int errn = 0;
  1072. struct dinEXIDocument exiDin1;
  1073. struct dinEXIDocument exiDin2;
  1074. bitstream_t stream1;
  1075. bitstream_t stream2;
  1076. size_t pos1 = 0;
  1077. size_t pos2 = 0;
  1078. stream1.size = BUFFER_SIZE;
  1079. stream1.data = buffer1;
  1080. stream1.pos = &pos1;
  1081. stream2.size = BUFFER_SIZE;
  1082. stream2.data = buffer2;
  1083. stream2.pos = &pos2;
  1084. /* SetupSessionReq */
  1085. /* BMW: 80 9A 00 11 D0 20 00 03 C1 FC 30 00 43 F8 00 */
  1086. buffer1[0] = 0x80;
  1087. buffer1[1] = 0x9A;
  1088. buffer1[2] = 0x00;
  1089. buffer1[3] = 0x11;
  1090. buffer1[4] = 0xD0;
  1091. buffer1[5] = 0x20;
  1092. buffer1[6] = 0x00;
  1093. buffer1[7] = 0x03;
  1094. buffer1[8] = 0xC1;
  1095. buffer1[9] = 0xFC;
  1096. buffer1[10] = 0x30;
  1097. buffer1[11] = 0x00;
  1098. buffer1[12] = 0x43;
  1099. buffer1[13] = 0xF8;
  1100. buffer1[14] = 0x00;
  1101. errn = decode_dinExiDocument(&stream1, &exiDin1);
  1102. if(errn != 0) {
  1103. printf("\n\nDIN test error %d!\n", errn);
  1104. return errn;
  1105. } else if (pos1 != 15) {
  1106. printf("\n\nDIN warning. not all bytes read!\n");
  1107. errn = -1;
  1108. return errn;
  1109. }
  1110. /* SetupSessionReq */
  1111. /* Chevy: 80 9A 02 00 00 00 00 00 00 00 00 11 D0 18 00 60 8C 44 09 94 00 */
  1112. buffer2[0] = 0x80;
  1113. buffer2[1] = 0x9A;
  1114. buffer2[2] = 0x02;
  1115. buffer2[3] = 0x00;
  1116. buffer2[4] = 0x00;
  1117. buffer2[5] = 0x00;
  1118. buffer2[6] = 0x00;
  1119. buffer2[7] = 0x00;
  1120. buffer2[8] = 0x00;
  1121. buffer2[9] = 0x00;
  1122. buffer2[10] = 0x00;
  1123. buffer2[11] = 0x11;
  1124. buffer2[12] = 0xD0;
  1125. buffer2[13] = 0x18;
  1126. buffer2[14] = 0x00;
  1127. buffer2[15] = 0x60;
  1128. buffer2[16] = 0x8C;
  1129. buffer2[17] = 0x44;
  1130. buffer2[18] = 0x09;
  1131. buffer2[19] = 0x94;
  1132. buffer2[20] = 0x00;
  1133. errn = decode_dinExiDocument(&stream2, &exiDin2);
  1134. if(errn != 0) {
  1135. printf("\n\nDIN test error %d!\n", errn);
  1136. return errn;
  1137. } else if (pos2 != 21) {
  1138. printf("\n\nDIN warning. not all bytes read!\n");
  1139. errn = -1;
  1140. return errn;
  1141. }
  1142. /* sessionStopReq */
  1143. pos2 = 0; /* reset position */
  1144. /* V: 0x80, 0x9a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x91, 0xf0 */
  1145. buffer2[0] = 0x80;
  1146. buffer2[1] = 0x9a;
  1147. buffer2[2] = 0x02;
  1148. buffer2[3] = 0x00;
  1149. buffer2[4] = 0x00;
  1150. buffer2[5] = 0x00;
  1151. buffer2[6] = 0x00;
  1152. buffer2[7] = 0x00;
  1153. buffer2[8] = 0x00;
  1154. buffer2[9] = 0x00;
  1155. buffer2[10] = 0x03;
  1156. buffer2[11] = 0x91;
  1157. buffer2[12] = 0xf0;
  1158. errn = decode_dinExiDocument(&stream2, &exiDin2);
  1159. if(errn != 0) {
  1160. printf("\n\nDIN test error %d!\n", errn);
  1161. return errn;
  1162. } else if (pos2 != 13) {
  1163. printf("\n\nDIN warning. not all bytes read!\n");
  1164. errn = -1;
  1165. return errn;
  1166. } else if(exiDin2.V2G_Message_isUsed == 0 || exiDin2.V2G_Message.Body.SessionStopReq_isUsed == 0) {
  1167. printf("\n\nDIN warning. no sessionStopReq message!\n");
  1168. errn = -1;
  1169. return errn;
  1170. }
  1171. if(errn == 0) {
  1172. printf("DIN test passed\n");
  1173. } else {
  1174. printf("DIN test error %d!\n", errn);
  1175. }
  1176. return errn;
  1177. }
  1178. #endif /* DEPLOY_DIN_CODEC == SUPPORT_YES */
  1179. #if DEPLOY_XMLDSIG_CODEC == SUPPORT_YES
  1180. #if DEPLOY_ISO_CODEC_FRAGMENT == SUPPORT_YES
  1181. static int xmldsig_test() {
  1182. int errn = 0, i;
  1183. bitstream_t stream1;
  1184. size_t pos1 = 0;
  1185. stream1.size = BUFFER_SIZE;
  1186. stream1.data = buffer1;
  1187. stream1.pos = &pos1;
  1188. bitstream_t stream2;
  1189. size_t pos2 = 0;
  1190. stream2.size = BUFFER_SIZE;
  1191. stream2.data = buffer2;
  1192. stream2.pos = &pos2;
  1193. struct iso2EXIFragment exiV2G_AR;
  1194. struct xmldsigEXIFragment exiXMLDSIG_SI;
  1195. int sizeIsoStream1 = 25;
  1196. int isoStream1[] = {0x80, 0x04, 0x01, 0x52, 0x51, 0x0C, 0x40, 0x82, 0x9B, 0x7B, 0x6B, 0x29, 0x02, 0x93, 0x0B, 0x73, 0x23, 0x7B, 0x69, 0x02, 0x23, 0x0B, 0xA3, 0x09, 0xE8};
  1197. int sizeIsoStream2 = 209;
  1198. int isoStream2[] = {0x80, 0x81, 0x12, 0xB4, 0x3A, 0x3A, 0x38, 0x1D, 0x17, 0x97, 0xBB, 0xBB, 0xBB, 0x97, 0x3B, 0x99, 0x97, 0x37, 0xB9, 0x33, 0x97, 0xAA, 0x29, 0x17, 0xB1, 0xB0, 0xB7, 0x37, 0xB7, 0x34, 0xB1, 0xB0, 0xB6, 0x16, 0xB2, 0xBC, 0x34, 0x97, 0xA1, 0xAB, 0x43, 0xA3, 0xA3, 0x81, 0xD1, 0x79, 0x7B, 0xBB, 0xBB, 0xB9, 0x73, 0xB9, 0x99, 0x73, 0x7B, 0x93, 0x39, 0x79, 0x91, 0x81, 0x81, 0x89, 0x79, 0x81, 0xA1, 0x7B, 0xC3, 0x6B, 0x63, 0x23, 0x9B, 0x4B, 0x39, 0x6B, 0x6B, 0x7B, 0x93, 0x29, 0x1B, 0x2B, 0x1B, 0x23, 0x9B, 0x09, 0x6B, 0x9B, 0x43, 0x09, 0x91, 0xA9, 0xB2, 0x20, 0x62, 0x34, 0x94, 0x43, 0x10, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x33, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x54, 0x52, 0x2F, 0x63, 0x61, 0x6E, 0x6F, 0x6E, 0x69, 0x63, 0x61, 0x6C, 0x2D, 0x65, 0x78, 0x69, 0x2F, 0x48, 0x52, 0xD0, 0xE8, 0xE8, 0xE0, 0x74, 0x5E, 0x5E, 0xEE, 0xEE, 0xEE, 0x5C, 0xEE, 0x66, 0x5C, 0xDE, 0xE4, 0xCE, 0x5E, 0x64, 0x60, 0x60, 0x62, 0x5E, 0x60, 0x68, 0x5E, 0xF0, 0xDA, 0xD8, 0xCA, 0xDC, 0xC6, 0x46, 0xE6, 0xD0, 0xC2, 0x64, 0x6A, 0x6C, 0x84, 0x1A, 0x36, 0xBC, 0x07, 0xA0, 0x0C, 0xB7, 0xDC, 0xAD, 0x66, 0x2F, 0x30, 0x88, 0xA6, 0x0A, 0x3D, 0x6A, 0x99, 0x43, 0x1F, 0x81, 0xC1, 0x22, 0xC2, 0xE9, 0xF1, 0x67, 0x8E, 0xF5, 0x31, 0xE9, 0x55, 0x23, 0x70};
  1199. uint8_t digestValue[] = {0xD1, 0xB5, 0xE0, 0x3D, 0x00, 0x65, 0xBE, 0xE5, 0x6B, 0x31, 0x79, 0x84, 0x45, 0x30, 0x51, 0xEB, 0x54, 0xCA, 0x18, 0xFC, 0x0E, 0x09, 0x16, 0x17, 0x4F, 0x8B, 0x3C, 0x77, 0xA9, 0x8F, 0x4A, 0xA9}; /* 32 Bytes */
  1200. /*
  1201. <v2gci_b:AuthorizationReq xmlns:v2gci_b="urn:iso:15118:2:2013:MsgBody" v2gci_b:Id="ID1">
  1202. <v2gci_b:GenChallenge>U29tZSBSYW5kb20gRGF0YQ==</v2gci_b:GenChallenge>
  1203. </v2gci_b:AuthorizationReq>
  1204. */
  1205. init_iso2EXIFragment(&exiV2G_AR);
  1206. exiV2G_AR.AuthorizationReq_isUsed = 1u;
  1207. init_iso2AuthorizationReqType(&exiV2G_AR.AuthorizationReq);
  1208. exiV2G_AR.AuthorizationReq.Id_isUsed = 1;
  1209. exiV2G_AR.AuthorizationReq.Id.charactersLen = 3;
  1210. exiV2G_AR.AuthorizationReq.Id.characters[0] = 'I';
  1211. exiV2G_AR.AuthorizationReq.Id.characters[1] = 'D';
  1212. exiV2G_AR.AuthorizationReq.Id.characters[2] = '1';
  1213. exiV2G_AR.AuthorizationReq.GenChallenge_isUsed = 1;
  1214. /* base64 U29tZSBSYW5kb20gRGF0YQ== */
  1215. exiV2G_AR.AuthorizationReq.GenChallenge.bytesLen = 16;
  1216. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[0] = 0x53;
  1217. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[1] = 0x6F;
  1218. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[2] = 0x6D;
  1219. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[3] = 0x65;
  1220. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[4] = 0x20;
  1221. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[5] = 0x52;
  1222. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[6] = 0x61;
  1223. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[7] = 0x6E;
  1224. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[8] = 0x64;
  1225. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[9] = 0x6F;
  1226. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[10] = 0x6D;
  1227. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[11] = 0x20;
  1228. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[12] = 0x44;
  1229. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[13] = 0x61;
  1230. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[14] = 0x74;
  1231. exiV2G_AR.AuthorizationReq.GenChallenge.bytes[15] = 0x61;
  1232. /* encode fragment with ISO schema */
  1233. errn = encode_iso2ExiFragment(&stream1, &exiV2G_AR);
  1234. if((*stream1.pos) != sizeIsoStream1) {
  1235. errn = -1;
  1236. printf("EXI1 stream length does not match !\n");
  1237. return errn;
  1238. } else {
  1239. for(i=0; i<sizeIsoStream1; i++) {
  1240. if(stream1.data[i] != isoStream1[i]) {
  1241. errn = -1;
  1242. printf("EXI1 stream does not match at position %d !\n", i);
  1243. return errn;
  1244. }
  1245. }
  1246. }
  1247. /* TODO Create Hash for stream 1 etc ... */
  1248. /* SHA-256 is "0bXgPQBlvuVrMXmERTBR61TKGPwOCRYXT4s8d6mPSqk=" */
  1249. /*
  1250. <xmlsig:SignedInfo xmlns:xmlsig="http://www.w3.org/2000/09/xmldsig#" >
  1251. <xmlsig:CanonicalizationMethod Algorithm="http://www.w3.org/TR/canonical-exi/"/>
  1252. <xmlsig:SignatureMethod
  1253. Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"/>
  1254. <xmlsig:Reference URI="#ID1">
  1255. <xmlsig:Transforms>
  1256. <xmlsig:Transform Algorithm="http://www.w3.org/TR/canonical-exi/"/>
  1257. </xmlsig:Transforms>
  1258. <xmlsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
  1259. <xmlsig:DigestValue>0bXgPQBlvuVrMXmERTBR61TK
  1260. GPwOCRYXT4s8d6mPSqk=</xmlsig:DigestValue>
  1261. </xmlsig:Reference>
  1262. </xmlsig:SignedInfo>
  1263. */
  1264. /* encode SignedInfo element with xmldsig schema */
  1265. const char arrayCanonicalEXI[35] = {"http://www.w3.org/TR/canonical-exi/"};
  1266. const char arrayxmldsigSHA256[51] = {"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"};
  1267. const char arrayxmlencSHA256[39] = {"http://www.w3.org/2001/04/xmlenc#sha256"};
  1268. init_xmldsigEXIFragment(&exiXMLDSIG_SI);
  1269. exiXMLDSIG_SI.SignedInfo_isUsed = 1;
  1270. init_xmldsigSignedInfoType(&exiXMLDSIG_SI.SignedInfo);
  1271. {
  1272. init_xmldsigCanonicalizationMethodType(&exiXMLDSIG_SI.SignedInfo.CanonicalizationMethod);
  1273. exiXMLDSIG_SI.SignedInfo.CanonicalizationMethod.Algorithm.charactersLen = 35;
  1274. strncpy(exiXMLDSIG_SI.SignedInfo.CanonicalizationMethod.Algorithm.characters, arrayCanonicalEXI, 35);
  1275. exiXMLDSIG_SI.SignedInfo.SignatureMethod.HMACOutputLength_isUsed = 0;
  1276. exiXMLDSIG_SI.SignedInfo.SignatureMethod.Algorithm.charactersLen = 51;
  1277. strncpy(exiXMLDSIG_SI.SignedInfo.SignatureMethod.Algorithm.characters, arrayxmldsigSHA256, 51);
  1278. exiXMLDSIG_SI.SignedInfo.Reference.arrayLen = 1;
  1279. /* "#ID1" */
  1280. exiXMLDSIG_SI.SignedInfo.Reference.array[0].URI_isUsed = 1;
  1281. exiXMLDSIG_SI.SignedInfo.Reference.array[0].URI.charactersLen = 4;
  1282. exiXMLDSIG_SI.SignedInfo.Reference.array[0].URI.characters[0] = '#';
  1283. exiXMLDSIG_SI.SignedInfo.Reference.array[0].URI.characters[1] = 'I';
  1284. exiXMLDSIG_SI.SignedInfo.Reference.array[0].URI.characters[2] = 'D';
  1285. exiXMLDSIG_SI.SignedInfo.Reference.array[0].URI.characters[3] = '1';
  1286. /* "http://www.w3.org/TR/canonical-exi/" */
  1287. exiXMLDSIG_SI.SignedInfo.Reference.array[0].Transforms_isUsed = 1;
  1288. exiXMLDSIG_SI.SignedInfo.Reference.array[0].Transforms.Transform.arrayLen = 1;
  1289. exiXMLDSIG_SI.SignedInfo.Reference.array[0].Transforms.Transform.array[0].Algorithm.charactersLen = 35;
  1290. strncpy(exiXMLDSIG_SI.SignedInfo.Reference.array[0].Transforms.Transform.array[0].Algorithm.characters, arrayCanonicalEXI, 35); /* Will copy 35 characters from arrayCanonicalEXI to characters */
  1291. exiXMLDSIG_SI.SignedInfo.Reference.array[0].Transforms.Transform.array[0].XPath.arrayLen = 0;
  1292. exiXMLDSIG_SI.SignedInfo.Reference.array[0].DigestMethod.Algorithm.charactersLen = 39;
  1293. strncpy(exiXMLDSIG_SI.SignedInfo.Reference.array[0].DigestMethod.Algorithm.characters, arrayxmlencSHA256, 39);
  1294. /* "0bXgPQBlvuVrMXmERTBR61TKGPwOCRYXT4s8d6mPSqk=" --> 16 Bytes 536F6D652052616E646F6D2044617461 */
  1295. exiXMLDSIG_SI.SignedInfo.Reference.array[0].DigestValue.bytesLen = 32;
  1296. memcpy(exiXMLDSIG_SI.SignedInfo.Reference.array[0].DigestValue.bytes, digestValue, 32);
  1297. }
  1298. errn = encode_xmldsigExiFragment(&stream2, &exiXMLDSIG_SI);
  1299. if((*stream2.pos) != sizeIsoStream2) {
  1300. errn = -1;
  1301. printf("EXI2 stream length does not match !\n");
  1302. return errn;
  1303. } else {
  1304. for(i=0; i<sizeIsoStream2; i++) {
  1305. if(stream2.data[i] != isoStream2[i]) {
  1306. errn = -1;
  1307. printf("EXI2 stream does not match at position %d !\n", i);
  1308. return errn;
  1309. }
  1310. }
  1311. }
  1312. if(errn == 0) {
  1313. printf("XMLDSIG test passed\n");
  1314. } else {
  1315. printf("XMLDSIG test error %d!\n", errn);
  1316. }
  1317. return errn;
  1318. }
  1319. #endif /* DEPLOY_ISO_CODEC_FRAGMENT */
  1320. #endif /* DEPLOY_XMLDSIG_CODEC == SUPPORT_YES */
  1321. int main_example(int argc, char *argv[]) {
  1322. int errn = 0;
  1323. printf("+++ Start application handshake protocol example +++\n\n");
  1324. errn = appHandshake();
  1325. printf("+++ Terminate application handshake protocol example with errn = %d +++\n\n", errn);
  1326. if(errn != 0) {
  1327. printf("\n\nHandshake error %d!\n", errn);
  1328. return errn;
  1329. }
  1330. printf("+++ Start V2G client / service example for charging +++\n\n");
  1331. errn = charging();
  1332. printf("\n+++Terminate V2G Client / Service example for charging with errn = %d +++\n\n", errn);
  1333. if(errn != 0) {
  1334. printf("\n\ncharging error %d!\n", errn);
  1335. return errn;
  1336. }
  1337. #if DEPLOY_DIN_CODEC == SUPPORT_YES
  1338. printf("+++ Start simple DIN test +++\n");
  1339. errn = din_test();
  1340. printf("+++ Terminate simple DIN test with errn = %d +++\n\n", errn);
  1341. if(errn != 0) {
  1342. printf("\nDIN test error %d!\n", errn);
  1343. return errn;
  1344. }
  1345. #endif /* DEPLOY_DIN_CODEC == SUPPORT_YES */
  1346. #if DEPLOY_XMLDSIG_CODEC == SUPPORT_YES
  1347. #if DEPLOY_ISO_CODEC_FRAGMENT == SUPPORT_YES
  1348. printf("+++ Start simple XMLDSIG test +++\n");
  1349. errn = xmldsig_test();
  1350. printf("+++ Terminate simple XMLDSIG test with errn = %d +++\n\n", errn);
  1351. if(errn != 0) {
  1352. printf("\nXMLDSIG test error %d!\n", errn);
  1353. return errn;
  1354. }
  1355. #endif /* DEPLOY_ISO_CODEC_FRAGMENT */
  1356. #endif /* DEPLOY_XMLDSIG_CODEC == SUPPORT_YES */
  1357. return errn;
  1358. }