v2g_serviceDispatcher.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178
  1. /*
  2. * Copyright (C) 2007-2010 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 Sebastian.Kaebisch.EXT@siemens.com
  20. * @version 0.3.1
  21. * @contact Joerg.Heuer@siemens.com
  22. *
  23. ********************************************************************/
  24. #include "v2g_service.h"
  25. #include "v2g_serviceDispatcher.h"
  26. #include "v2g_serviceDataTypes.h"
  27. #include "v2g_serviceDataTypes.c"
  28. #include "v2g_serviceMethods.h"
  29. #include "v2g_serviceDataSerialization.c"
  30. #include "EXITypes.h"
  31. #include "EXIDecoder.h"
  32. #include "EXIEncoder.h"
  33. static int deserializeMessage(struct EXIService* service);
  34. /**
  35. * Deserialize an element value of the EXI stream and assign it to the
  36. * service data structure
  37. */
  38. static int deserializeElementCharacter(struct EXIService* service)
  39. {
  40. switch(service->eqn.namespaceURI) {
  41. case 4:
  42. switch(service->eqn.localPart) {
  43. case 24: /*PEVID*/
  44. if(service->val.type == STRING)
  45. {
  46. if(service->idPath.id[2] == 56)
  47. {
  48. /* string copy and string length assignment */
  49. memcpy(service->exiMsg.V2G_Message.Body.SessionSetupReq->PEVID.data, service->val.string.codepoints,service->val.string.len*sizeof(uint32_t));
  50. service->exiMsg.V2G_Message.Body.SessionSetupReq->PEVID.arraylen.data = service->val.string.len;
  51. service->exiMsg.V2G_Message.Body.SessionSetupReq->isused.PEVID=1;
  52. }
  53. else
  54. {
  55. /* string copy and string length assignment */
  56. memcpy(service->exiMsg.V2G_Message.Body.MeteringReceiptReq->PEVID.data, service->val.string.codepoints,service->val.string.len*sizeof(uint32_t));
  57. service->exiMsg.V2G_Message.Body.MeteringReceiptReq->PEVID.arraylen.data = service->val.string.len;
  58. service->exiMsg.V2G_Message.Body.MeteringReceiptReq->isused.PEVID=1;
  59. }
  60. }
  61. else
  62. {
  63. return -1; /* wrong data type */
  64. }
  65. break;
  66. case 55: /*ServiceType*/
  67. if(service->val.type == ENUMERATION)
  68. {
  69. if(service->idPath.id[1] == 0)
  70. {
  71. service->exiMsg.V2G_Message.Body.ServiceDiscoveryReq->ServiceType=service->val.enumeration;
  72. service->exiMsg.V2G_Message.Body.ServiceDiscoveryReq->isused.ServiceType=1;
  73. } else if(service->idPath.id[1] == 0)
  74. {
  75. service->exiMsg.V2G_Message.Body.ServiceDiscoveryRes->ServiceList.Service[service->exiMsg.V2G_Message.Body.ServiceDiscoveryRes->ServiceList.arraylen.Service].ServiceType=service->val.enumeration;
  76. service->exiMsg.V2G_Message.Body.ServiceDiscoveryRes->ServiceList.Service[service->exiMsg.V2G_Message.Body.ServiceDiscoveryRes->ServiceList.arraylen.Service].isused.ServiceType=1;
  77. }
  78. }
  79. else
  80. {
  81. return -1; /* wrong data type */
  82. }
  83. /* is used */
  84. /*service->exiMsg.V2G_Message.Body.ServiceDiscoveryReq->isused.ServiceType=1;*/
  85. break;
  86. case 54: /*ServiceScope*/
  87. if(service->val.type == STRING)
  88. {
  89. /* string copy and string length assignment */
  90. memcpy(service->exiMsg.V2G_Message.Body.ServiceDiscoveryReq->ServiceScope.data, service->val.string.codepoints,service->val.string.len*sizeof(uint32_t));
  91. service->exiMsg.V2G_Message.Body.ServiceDiscoveryReq->ServiceScope.arraylen.data = service->val.string.len;
  92. }
  93. else
  94. {
  95. return -1; /* wrong data type */
  96. }
  97. /* is used */
  98. /*service->exiMsg.V2G_Message.Body.ServiceDiscoveryReq->isused.ServiceScope=1;*/
  99. break;
  100. case 0: /*ContractID*/
  101. if(service->val.type == STRING)
  102. {
  103. /* string copy and string length assignment */
  104. memcpy(service->exiMsg.V2G_Message.Body.PaymentDetailsReq->ContractID.data, service->val.string.codepoints,service->val.string.len*sizeof(uint32_t));
  105. service->exiMsg.V2G_Message.Body.PaymentDetailsReq->ContractID.arraylen.data = service->val.string.len;
  106. }
  107. else
  108. {
  109. return -1; /* wrong data type */
  110. }
  111. break;
  112. case 9: /*EoC*/
  113. if(service->val.type == INTEGER_32)
  114. {
  115. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->EoC=service->val.int32;
  116. }
  117. else
  118. {
  119. return -1; /* wrong data type */
  120. }
  121. break;
  122. case 25: /*PEVMaxPhases*/
  123. if(service->val.type == INTEGER_16)
  124. {
  125. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->PEVMaxPhases=service->val.int32;
  126. }
  127. else
  128. {
  129. return -1; /* wrong data type */
  130. }
  131. break;
  132. case 42: /*ReqLockStatus*/
  133. if(service->val.type == BOOLEAN)
  134. {
  135. service->exiMsg.V2G_Message.Body.LineLockReq->ReqLockStatus=service->val.boolean;
  136. }
  137. else
  138. {
  139. return -1; /* wrong data type */
  140. }
  141. break;
  142. case 43: /*ReqSwitchStatus*/
  143. if(service->val.type == BOOLEAN)
  144. {
  145. service->exiMsg.V2G_Message.Body.PowerDeliveryReq->ReqSwitchStatus=service->val.boolean;
  146. }
  147. else
  148. {
  149. return -1; /* wrong data type */
  150. }
  151. break;
  152. case 61: /*Tariff*/
  153. if(service->val.type == ENUMERATION)
  154. {
  155. if(service->idPath.id[2] == 34)
  156. {
  157. service->exiMsg.V2G_Message.Body.PowerDeliveryReq->Tariff=service->val.enumeration;
  158. service->exiMsg.V2G_Message.Body.PowerDeliveryReq->isused.Tariff=1;
  159. } else if(service->idPath.id[2] == 15)
  160. {
  161. service->exiMsg.V2G_Message.Body.MeteringReceiptReq->Tariff=service->val.enumeration;
  162. }
  163. }
  164. else
  165. {
  166. return -1; /* wrong data type */
  167. }
  168. /* is used */
  169. /*service->exiMsg.V2G_Message.Body.PowerDeliveryReq->isused.Tariff=1;*/
  170. break;
  171. case 60: /*TCurrent*/
  172. if(service->val.type == INTEGER_32)
  173. {
  174. service->exiMsg.V2G_Message.Body.MeteringReceiptReq->TCurrent=service->val.int32;
  175. }
  176. else
  177. {
  178. return -1; /* wrong data type */
  179. }
  180. /* is used */
  181. /*service->exiMsg.V2G_Message.Body.MeteringReceiptReq->isused.TCurrent=1;*/
  182. break;
  183. } /* close switch(service->eqn.localPart) */
  184. break;
  185. case 5:
  186. switch(service->eqn.localPart) {
  187. case 34: /*SessionID*/
  188. if(service->val.type == BINARY_HEX)
  189. {
  190. /* array copy and array length assignment */
  191. memcpy(service->exiMsg.V2G_Message.Header->SessionInformation.SessionID.data, service->val.binary.data,service->val.binary.len);
  192. service->exiMsg.V2G_Message.Header->SessionInformation.SessionID.arraylen.data = service->val.binary.len;
  193. }
  194. else
  195. {
  196. return -1; /* wrong data type */
  197. }
  198. break;
  199. case 32: /*ServiceSessionID*/
  200. if(service->val.type == BINARY_HEX)
  201. {
  202. /* array copy and array length assignment */
  203. memcpy(service->exiMsg.V2G_Message.Header->SessionInformation.ServiceSessionID.data, service->val.binary.data,service->val.binary.len);
  204. service->exiMsg.V2G_Message.Header->SessionInformation.ServiceSessionID.arraylen.data = service->val.binary.len;
  205. }
  206. else
  207. {
  208. return -1; /* wrong data type */
  209. }
  210. /* is used */
  211. /*service->exiMsg.V2G_Message.Header->SessionInformation.isused.ServiceSessionID=1;*/
  212. break;
  213. case 24: /*ProtocolVersion*/
  214. if(service->val.type == STRING)
  215. {
  216. /* string copy and string length assignment */
  217. memcpy(service->exiMsg.V2G_Message.Header->SessionInformation.ProtocolVersion.data, service->val.string.codepoints,service->val.string.len*sizeof(uint32_t));
  218. service->exiMsg.V2G_Message.Header->SessionInformation.ProtocolVersion.arraylen.data = service->val.string.len;
  219. }
  220. else
  221. {
  222. return -1; /* wrong data type */
  223. }
  224. /* is used */
  225. /*service->exiMsg.V2G_Message.Header->SessionInformation.isused.ProtocolVersion=1;*/
  226. break;
  227. case 9: /*Event*/
  228. if(service->val.type == ENUMERATION)
  229. {
  230. service->exiMsg.V2G_Message.Header->Notification.EventList.Event=service->val.enumeration;
  231. }
  232. else
  233. {
  234. return -1; /* wrong data type */
  235. }
  236. break;
  237. case 13: /*FaultCode*/
  238. if(service->val.type == ENUMERATION)
  239. {
  240. service->exiMsg.V2G_Message.Header->Notification.FaultCode=service->val.enumeration;
  241. }
  242. else
  243. {
  244. return -1; /* wrong data type */
  245. }
  246. /* is used */
  247. /*service->exiMsg.V2G_Message.Header->Notification.isused.FaultCode=1;*/
  248. break;
  249. case 14: /*FaultMsg*/
  250. if(service->val.type == STRING)
  251. {
  252. /* string copy and string length assignment */
  253. memcpy(service->exiMsg.V2G_Message.Header->Notification.FaultMsg.data, service->val.string.codepoints,service->val.string.len*sizeof(uint32_t));
  254. service->exiMsg.V2G_Message.Header->Notification.FaultMsg.arraylen.data = service->val.string.len;
  255. }
  256. else
  257. {
  258. return -1; /* wrong data type */
  259. }
  260. /* is used */
  261. /*service->exiMsg.V2G_Message.Header->Notification.isused.FaultMsg=1;*/
  262. break;
  263. case 4: /*ConnectorLocked*/
  264. if(service->val.type == BOOLEAN)
  265. {
  266. if(service->idPath.id[2] == 56)
  267. {
  268. service->exiMsg.V2G_Message.Body.SessionSetupReq->PEVStatus.ConnectorLocked=service->val.boolean;
  269. } else if(service->idPath.id[2] == 38)
  270. {
  271. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->PEVStatus.ConnectorLocked=service->val.boolean;
  272. } else if(service->idPath.id[2] == 10)
  273. {
  274. service->exiMsg.V2G_Message.Body.LineLockReq->PEVStatus.ConnectorLocked=service->val.boolean;
  275. } else if(service->idPath.id[2] == 34)
  276. {
  277. service->exiMsg.V2G_Message.Body.PowerDeliveryReq->PEVStatus.ConnectorLocked=service->val.boolean;
  278. } else if(service->idPath.id[2] == 15)
  279. {
  280. service->exiMsg.V2G_Message.Body.MeteringReceiptReq->PEVStatus.ConnectorLocked=service->val.boolean;
  281. }
  282. }
  283. else
  284. {
  285. return -1; /* wrong data type */
  286. }
  287. break;
  288. case 0: /*ChargerStandby*/
  289. if(service->val.type == BOOLEAN)
  290. {
  291. if(service->idPath.id[2] == 56)
  292. {
  293. service->exiMsg.V2G_Message.Body.SessionSetupReq->PEVStatus.ChargerStandby=service->val.boolean;
  294. } else if(service->idPath.id[2] == 38)
  295. {
  296. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->PEVStatus.ChargerStandby=service->val.boolean;
  297. } else if(service->idPath.id[2] == 10)
  298. {
  299. service->exiMsg.V2G_Message.Body.LineLockReq->PEVStatus.ChargerStandby=service->val.boolean;
  300. } else if(service->idPath.id[2] == 34)
  301. {
  302. service->exiMsg.V2G_Message.Body.PowerDeliveryReq->PEVStatus.ChargerStandby=service->val.boolean;
  303. } else if(service->idPath.id[2] == 15)
  304. {
  305. service->exiMsg.V2G_Message.Body.MeteringReceiptReq->PEVStatus.ChargerStandby=service->val.boolean;
  306. }
  307. }
  308. else
  309. {
  310. return -1; /* wrong data type */
  311. }
  312. break;
  313. case 20: /*Multiplier*/
  314. if(service->val.type == ENUMERATION)
  315. {
  316. if(service->idPath.id[3] == 1)
  317. {
  318. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->EAmount.Multiplier=service->val.enumeration;
  319. } else if(service->idPath.id[3] == 26)
  320. {
  321. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->PEVMaxPower.Multiplier=service->val.enumeration;
  322. } else if(service->idPath.id[3] == 27)
  323. {
  324. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->PEVMaxVoltage.Multiplier=service->val.enumeration;
  325. } else if(service->idPath.id[3] == 28)
  326. {
  327. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->PEVMinVoltage.Multiplier=service->val.enumeration;
  328. }else if(service->idPath.id[3] == 14)
  329. {
  330. service->exiMsg.V2G_Message.Body.MeteringReceiptReq->MeterInfo.MeterReading.Multiplier=service->val.enumeration;
  331. }
  332. }
  333. else
  334. {
  335. return -1; /* wrong data type */
  336. }
  337. break;
  338. case 49: /*Unit*/
  339. if(service->val.type == ENUMERATION)
  340. {
  341. if(service->idPath.id[3] == 1)
  342. {
  343. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->EAmount.Unit=service->val.enumeration;
  344. } else if(service->idPath.id[3] == 26)
  345. {
  346. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->PEVMaxPower.Unit=service->val.enumeration;
  347. } else if(service->idPath.id[3] == 27)
  348. {
  349. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->PEVMaxVoltage.Unit=service->val.enumeration;
  350. } else if(service->idPath.id[3] == 28)
  351. {
  352. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->PEVMinVoltage.Unit=service->val.enumeration;
  353. } else if(service->idPath.id[3] == 14)
  354. {
  355. service->exiMsg.V2G_Message.Body.MeteringReceiptReq->MeterInfo.MeterReading.Unit=service->val.enumeration;
  356. }
  357. }
  358. else
  359. {
  360. return -1; /* wrong data type */
  361. }
  362. break;
  363. case 50: /*Value*/
  364. if(service->val.type == INTEGER_32)
  365. {
  366. if(service->idPath.id[3] == 1)
  367. {
  368. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->EAmount.Value=service->val.int32;
  369. } else if(service->idPath.id[3] == 26)
  370. {
  371. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->PEVMaxPower.Value=service->val.int32;
  372. } else if(service->idPath.id[3] == 27)
  373. {
  374. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->PEVMaxVoltage.Value=service->val.int32;
  375. } else if(service->idPath.id[3] == 28)
  376. {
  377. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq->PEVMinVoltage.Value=service->val.int32;
  378. }else if(service->idPath.id[3] == 14)
  379. {
  380. service->exiMsg.V2G_Message.Body.MeteringReceiptReq->MeterInfo.MeterReading.Value=service->val.int32;
  381. }
  382. }
  383. else
  384. {
  385. return -1; /* wrong data type */
  386. }
  387. break;
  388. case 16: /*MeterID*/
  389. if(service->val.type == STRING)
  390. {
  391. /* string copy and string length assignment */
  392. memcpy(service->exiMsg.V2G_Message.Body.MeteringReceiptReq->MeterInfo.MeterID.data, service->val.string.codepoints,service->val.string.len*sizeof(uint32_t));
  393. service->exiMsg.V2G_Message.Body.MeteringReceiptReq->MeterInfo.MeterID.arraylen.data = service->val.string.len;
  394. }
  395. else
  396. {
  397. return -1; /* wrong data type */
  398. }
  399. /* is used */
  400. /*service->exiMsg.V2G_Message.Body.MeteringStatusRes->MeterInfo.isused.MeterID=1;*/
  401. break;
  402. case 19: /*MeterStatus*/
  403. if(service->val.type == INTEGER_16)
  404. {
  405. service->exiMsg.V2G_Message.Body.MeteringReceiptReq->MeterInfo.MeterStatus=service->val.int32;
  406. }
  407. else
  408. {
  409. return -1; /* wrong data type */
  410. }
  411. /* is used */
  412. /*service->exiMsg.V2G_Message.Body.MeteringStatusRes->MeterInfo.isused.MeterStatus=1;*/
  413. break;
  414. case 37: /*TMeter*/
  415. if(service->val.type == INTEGER_32)
  416. {
  417. service->exiMsg.V2G_Message.Body.MeteringReceiptReq->MeterInfo.TMeter=service->val.int32;
  418. }
  419. else
  420. {
  421. return -1; /* wrong data type */
  422. }
  423. /* is used */
  424. /*service->exiMsg.V2G_Message.Body.MeteringStatusRes->MeterInfo.isused.TMeter=1;*/
  425. break;
  426. } /* close switch(service->eqn.localPart) */
  427. break;
  428. } /* close switch(service->eqn.namespaceURI) */
  429. return 0;
  430. }
  431. /**
  432. * Depending on the current EXI event a message element is deserialized or a
  433. * defined service method is called in here
  434. */
  435. static int deserializeElementOrServiceCall(struct EXIService* service)
  436. {
  437. switch(service->eqn.namespaceURI) {
  438. case 4:
  439. switch(service->eqn.localPart) {
  440. case 54:/* ServiceScope */
  441. /* is used */
  442. service->exiMsg.V2G_Message.Body.ServiceDiscoveryReq->isused.ServiceScope=1;
  443. break;
  444. case 60:/* TCurrent */
  445. /* is used */
  446. service->exiMsg.V2G_Message.Body.MeteringReceiptReq->isused.TCurrent=1;
  447. break;
  448. case 56:/* SessionSetupReq */
  449. /* test, if data length is unequal to the expected payload */
  450. if((service->inStream.size)!= *(service->inStream.pos))
  451. {
  452. service->errorCode = EXI_NON_VALID_MESSAGE;
  453. return -1;
  454. }
  455. /* service call */
  456. sessionSetup((service->exiMsg.V2G_Message.Body.SessionSetupReq), (service->exiMsg.V2G_Message.Body.SessionSetupRes));
  457. /* signalize the response message */
  458. service->exiMsg.V2G_Message.Body.isused.SessionSetupRes=1;
  459. /* serialize the response data */
  460. if(serialize_message(service))
  461. {
  462. /* serializiation error*/
  463. service->errorCode= EXI_SERIALIZATION_FAILED;
  464. }
  465. break;
  466. case 45:/* ServiceDiscoveryReq */
  467. /* test, if data length is unequal to the expected payload */
  468. if((service->inStream.size)!= *(service->inStream.pos))
  469. {
  470. service->errorCode = EXI_NON_VALID_MESSAGE;
  471. return -1;
  472. }
  473. /* service call */
  474. serviceDiscovery((service->exiMsg.V2G_Message.Body.ServiceDiscoveryReq), (service->exiMsg.V2G_Message.Body.ServiceDiscoveryRes));
  475. /* signalize the response message */
  476. service->exiMsg.V2G_Message.Body.isused.ServiceDiscoveryRes=1;
  477. /* serialize the response data */
  478. if(serialize_message(service))
  479. {
  480. /* serializiation error*/
  481. service->errorCode= EXI_SERIALIZATION_FAILED;
  482. }
  483. break;
  484. case 50:/* ServicePaymentSelectionReq */
  485. /* test, if data length is unequal to the expected payload */
  486. if((service->inStream.size)!= *(service->inStream.pos))
  487. {
  488. service->errorCode = EXI_NON_VALID_MESSAGE;
  489. return -1;
  490. }
  491. /* service call */
  492. selectedServicePayment((service->exiMsg.V2G_Message.Body.ServicePaymentSelectionReq), (service->exiMsg.V2G_Message.Body.ServicePaymentSelectionRes));
  493. /* signalize the response message */
  494. service->exiMsg.V2G_Message.Body.isused.ServicePaymentSelectionRes=1;
  495. /* serialize the response data */
  496. if(serialize_message(service))
  497. {
  498. /* serializiation error*/
  499. service->errorCode= EXI_SERIALIZATION_FAILED;
  500. }
  501. break;
  502. case 30:/* PaymentDetailsReq */
  503. /* test, if data length is unequal to the expected payload */
  504. if((service->inStream.size)!= *(service->inStream.pos))
  505. {
  506. service->errorCode = EXI_NON_VALID_MESSAGE;
  507. return -1;
  508. }
  509. /* service call */
  510. paymentDetails((service->exiMsg.V2G_Message.Body.PaymentDetailsReq), (service->exiMsg.V2G_Message.Body.PaymentDetailsRes));
  511. /* signalize the response message */
  512. service->exiMsg.V2G_Message.Body.isused.PaymentDetailsRes=1;
  513. /* serialize the response data */
  514. if(serialize_message(service))
  515. {
  516. /* serializiation error*/
  517. service->errorCode= EXI_SERIALIZATION_FAILED;
  518. }
  519. break;
  520. case 38:/* PowerDiscoveryReq */
  521. /* test, if data length is unequal to the expected payload */
  522. if((service->inStream.size)!= *(service->inStream.pos))
  523. {
  524. service->errorCode = EXI_NON_VALID_MESSAGE;
  525. return -1;
  526. }
  527. /* service call */
  528. powerDiscovery((service->exiMsg.V2G_Message.Body.PowerDiscoveryReq), (service->exiMsg.V2G_Message.Body.PowerDiscoveryRes));
  529. /* signalize the response message */
  530. service->exiMsg.V2G_Message.Body.isused.PowerDiscoveryRes=1;
  531. /* serialize the response data */
  532. if(serialize_message(service))
  533. {
  534. /* serializiation error*/
  535. service->errorCode= EXI_SERIALIZATION_FAILED;
  536. }
  537. break;
  538. case 10:/* LineLockReq */
  539. /* test, if data length is unequal to the expected payload */
  540. if((service->inStream.size)!= *(service->inStream.pos))
  541. {
  542. service->errorCode = EXI_NON_VALID_MESSAGE;
  543. return -1;
  544. }
  545. /* service call */
  546. lineLock((service->exiMsg.V2G_Message.Body.LineLockReq), (service->exiMsg.V2G_Message.Body.LineLockRes));
  547. /* signalize the response message */
  548. service->exiMsg.V2G_Message.Body.isused.LineLockRes=1;
  549. /* serialize the response data */
  550. if(serialize_message(service))
  551. {
  552. /* serializiation error*/
  553. service->errorCode= EXI_SERIALIZATION_FAILED;
  554. }
  555. break;
  556. case 34:/* PowerDeliveryReq */
  557. /* test, if data length is unequal to the expected payload */
  558. if((service->inStream.size)!= *(service->inStream.pos))
  559. {
  560. service->errorCode = EXI_NON_VALID_MESSAGE;
  561. return -1;
  562. }
  563. /* service call */
  564. powerDelivery((service->exiMsg.V2G_Message.Body.PowerDeliveryReq), (service->exiMsg.V2G_Message.Body.PowerDeliveryRes));
  565. /* signalize the response message */
  566. service->exiMsg.V2G_Message.Body.isused.PowerDeliveryRes=1;
  567. /* serialize the response data */
  568. if(serialize_message(service))
  569. {
  570. /* serializiation error*/
  571. service->errorCode= EXI_SERIALIZATION_FAILED;
  572. }
  573. break;
  574. case 19:/* MeteringStatusReq */
  575. /* test, if data length is unequal to the expected payload */
  576. if((service->inStream.size)!= *(service->inStream.pos))
  577. {
  578. service->errorCode = EXI_NON_VALID_MESSAGE;
  579. return -1;
  580. }
  581. /* service call */
  582. meteringStatus((service->exiMsg.V2G_Message.Body.MeteringStatusReq), (service->exiMsg.V2G_Message.Body.MeteringStatusRes));
  583. /* signalize the response message */
  584. service->exiMsg.V2G_Message.Body.isused.MeteringStatusRes=1;
  585. /* serialize the response data */
  586. if(serialize_message(service))
  587. {
  588. /* serializiation error*/
  589. service->errorCode= EXI_SERIALIZATION_FAILED;
  590. }
  591. break;
  592. case 15:/* MeteringReceiptReq */
  593. /* test, if data length is unequal to the expected payload */
  594. if((service->inStream.size)!= *(service->inStream.pos))
  595. {
  596. service->errorCode = EXI_NON_VALID_MESSAGE;
  597. return -1;
  598. }
  599. /* service call */
  600. meteringReceipt((service->exiMsg.V2G_Message.Body.MeteringReceiptReq), (service->exiMsg.V2G_Message.Body.MeteringReceiptRes));
  601. /* signalize the response message */
  602. service->exiMsg.V2G_Message.Body.isused.MeteringReceiptRes=1;
  603. /* serialize the response data */
  604. if(serialize_message(service))
  605. {
  606. /* serializiation error*/
  607. service->errorCode= EXI_SERIALIZATION_FAILED;
  608. }
  609. break;
  610. }
  611. break;
  612. case 5:
  613. switch(service->eqn.localPart) {
  614. case 32:/* ServiceSessionID */
  615. /* is used */
  616. service->exiMsg.V2G_Message.Header->SessionInformation.isused.ServiceSessionID=1;
  617. break;
  618. case 24:/* ProtocolVersion */
  619. /* is used */
  620. service->exiMsg.V2G_Message.Header->SessionInformation.isused.ProtocolVersion=1;
  621. break;
  622. case 13:/* FaultCode */
  623. /* is used */
  624. service->exiMsg.V2G_Message.Header->Notification.isused.FaultCode=1;
  625. break;
  626. case 14:/* FaultMsg */
  627. /* is used */
  628. service->exiMsg.V2G_Message.Header->Notification.isused.FaultMsg=1;
  629. break;
  630. case 10:/* EventList */
  631. /* is used */
  632. service->exiMsg.V2G_Message.Header->Notification.isused.EventList=1;
  633. break;
  634. case 26:/* Service */
  635. /* increment*/
  636. service->exiMsg.V2G_Message.Body.ServicePaymentSelectionReq->ServiceList.arraylen.Service++;
  637. break;
  638. case 16:/* MeterID */
  639. /* is used */
  640. service->exiMsg.V2G_Message.Body.MeteringReceiptReq->MeterInfo.isused.MeterID=1;
  641. break;
  642. case 18:/* MeterReading */
  643. /* is used */
  644. service->exiMsg.V2G_Message.Body.MeteringReceiptReq->MeterInfo.isused.MeterReading=1;
  645. break;
  646. }
  647. break;
  648. case 7:
  649. switch(service->eqn.localPart) {
  650. case 1:/* Notification */
  651. /* is used */
  652. service->exiMsg.V2G_Message.Header->isused.Notification=1;
  653. break;
  654. }
  655. break;
  656. }
  657. return 0;
  658. }
  659. static int deserializeSessionSetupReqMsg(struct EXIService* service)
  660. {
  661. struct SessionSetupReqType reqMsg;
  662. struct SessionSetupResType resMsg;
  663. init_SessionSetupReqType(&reqMsg);
  664. service->exiMsg.V2G_Message.Body.SessionSetupReq = &reqMsg;
  665. service->exiMsg.V2G_Message.Body.SessionSetupRes = &resMsg;
  666. return deserializeMessage(service);
  667. }
  668. static int deserializeServiceDiscoveryReqMsg(struct EXIService* service)
  669. {
  670. struct ServiceDiscoveryReqType reqMsg;
  671. struct ServiceDiscoveryResType resMsg;
  672. init_ServiceDiscoveryReqType(&reqMsg);
  673. service->exiMsg.V2G_Message.Body.ServiceDiscoveryReq = &reqMsg;
  674. service->exiMsg.V2G_Message.Body.ServiceDiscoveryRes = &resMsg;
  675. return deserializeMessage(service);
  676. }
  677. static int deserializeServicePaymentSelectionReqMsg(struct EXIService* service)
  678. {
  679. struct ServicePaymentSelectionReqType reqMsg;
  680. struct ServicePaymentSelectionResType resMsg;
  681. service->exiMsg.V2G_Message.Body.ServicePaymentSelectionReq = &reqMsg;
  682. service->exiMsg.V2G_Message.Body.ServicePaymentSelectionRes = &resMsg;
  683. return deserializeMessage(service);
  684. }
  685. static int deserializePaymentDetailsReqMsg(struct EXIService* service)
  686. {
  687. struct PaymentDetailsReqType reqMsg;
  688. struct PaymentDetailsResType resMsg;
  689. service->exiMsg.V2G_Message.Body.PaymentDetailsReq = &reqMsg;
  690. service->exiMsg.V2G_Message.Body.PaymentDetailsRes = &resMsg;
  691. return deserializeMessage(service);
  692. }
  693. static int deserializePowerDiscoveryReqMsg(struct EXIService* service)
  694. {
  695. struct PowerDiscoveryReqType reqMsg;
  696. struct PowerDiscoveryResType resMsg;
  697. init_PowerDiscoveryReqType(&reqMsg);
  698. service->exiMsg.V2G_Message.Body.PowerDiscoveryReq = &reqMsg;
  699. service->exiMsg.V2G_Message.Body.PowerDiscoveryRes = &resMsg;
  700. return deserializeMessage(service);
  701. }
  702. static int deserializeLineLockReqMsg(struct EXIService* service)
  703. {
  704. struct LineLockReqType reqMsg;
  705. struct LineLockResType resMsg;
  706. init_LineLockReqType(&reqMsg);
  707. service->exiMsg.V2G_Message.Body.LineLockReq = &reqMsg;
  708. service->exiMsg.V2G_Message.Body.LineLockRes = &resMsg;
  709. return deserializeMessage(service);
  710. }
  711. static int deserializePowerDeliveryReqMsg(struct EXIService* service)
  712. {
  713. struct PowerDeliveryReqType reqMsg;
  714. struct PowerDeliveryResType resMsg;
  715. init_PowerDeliveryReqType(&reqMsg);
  716. service->exiMsg.V2G_Message.Body.PowerDeliveryReq = &reqMsg;
  717. service->exiMsg.V2G_Message.Body.PowerDeliveryRes = &resMsg;
  718. return deserializeMessage(service);
  719. }
  720. static int deserializeMeteringStatusReqMsg(struct EXIService* service)
  721. {
  722. struct MeteringStatusReqType reqMsg;
  723. struct MeteringStatusResType resMsg;
  724. service->exiMsg.V2G_Message.Body.MeteringStatusReq = &reqMsg;
  725. service->exiMsg.V2G_Message.Body.MeteringStatusRes = &resMsg;
  726. return deserializeMessage(service);
  727. }
  728. static int deserializeMeteringReceiptReqMsg(struct EXIService* service)
  729. {
  730. struct MeteringReceiptReqType reqMsg;
  731. struct MeteringReceiptResType resMsg;
  732. init_MeteringReceiptReqType(&reqMsg);
  733. service->exiMsg.V2G_Message.Body.MeteringReceiptReq = &reqMsg;
  734. service->exiMsg.V2G_Message.Body.MeteringReceiptRes = &resMsg;
  735. return deserializeMessage(service);
  736. }
  737. /**
  738. * Deserialize the EXI stream
  739. * @return 0 = 0K; -1 = ERROR
  740. */
  741. static int deserializeMessage(struct EXIService* service)
  742. {
  743. int noEndOfDocument = 1; /* true */
  744. int returnCode=0;
  745. do {
  746. exiDecodeNextEvent(&(service->inStream), &(service->stateDecode), &(service->event));
  747. if (returnCode)
  748. {
  749. if(service->errorCode==0)
  750. {
  751. service->errorCode= EXI_NON_VALID_MESSAGE;
  752. }
  753. return returnCode;
  754. }
  755. switch (service->event) {
  756. case START_DOCUMENT:
  757. returnCode = exiDecodeStartDocument(&(service->inStream), &(service->stateDecode));
  758. break;
  759. case END_DOCUMENT:
  760. returnCode = exiDecodeEndDocument(&(service->inStream), &(service->stateDecode));
  761. noEndOfDocument = 0; /* false */
  762. break;
  763. case START_ELEMENT:
  764. returnCode = exiDecodeStartElement(&(service->inStream), &(service->stateDecode), &(service->eqn));
  765. service->idPath.id[service->idPath.pos++]=service->eqn.localPart;
  766. /* setup the request context*/
  767. if(service->eqn.localPart==56 && service->eqn.namespaceURI==4)
  768. {
  769. return deserializeSessionSetupReqMsg(service);
  770. } else if(service->eqn.localPart==45 && service->eqn.namespaceURI==4)
  771. {
  772. return deserializeServiceDiscoveryReqMsg(service);
  773. } else if(service->eqn.localPart==50 && service->eqn.namespaceURI==4)
  774. {
  775. return deserializeServicePaymentSelectionReqMsg(service);
  776. } else if(service->eqn.localPart==30 && service->eqn.namespaceURI==4)
  777. {
  778. return deserializePaymentDetailsReqMsg(service);
  779. } else if(service->eqn.localPart==38 && service->eqn.namespaceURI==4)
  780. {
  781. return deserializePowerDiscoveryReqMsg(service);
  782. } else if(service->eqn.localPart==10 && service->eqn.namespaceURI==4)
  783. {
  784. return deserializeLineLockReqMsg(service);
  785. } else if(service->eqn.localPart==34 && service->eqn.namespaceURI==4)
  786. {
  787. return deserializePowerDeliveryReqMsg(service);
  788. } else if(service->eqn.localPart==19 && service->eqn.namespaceURI==4)
  789. {
  790. return deserializeMeteringStatusReqMsg(service);
  791. } else if(service->eqn.localPart==15 && service->eqn.namespaceURI==4)
  792. {
  793. return deserializeMeteringReceiptReqMsg(service);
  794. }
  795. break;
  796. case END_ELEMENT:
  797. returnCode = exiDecodeEndElement(&(service->inStream), &(service->stateDecode), &(service->eqn));
  798. returnCode = deserializeElementOrServiceCall(service);
  799. service->idPath.pos--;
  800. break;
  801. case CHARACTERS:
  802. /* decode */
  803. returnCode = exiDecodeCharacters(&(service->inStream), &(service->stateDecode), &(service->val));
  804. /* assign data to the EXI message structure */
  805. returnCode = deserializeElementCharacter(service);
  806. break;
  807. case ATTRIBUTE:
  808. /* decode */
  809. /* returnCode = exiDecodeAttribute(&isStream, &stateDecode, &eqn, &val); */
  810. break;
  811. default:
  812. /* ERROR */
  813. return -1;
  814. }
  815. } while (noEndOfDocument);
  816. return 0;
  817. }
  818. /**
  819. * \brief Takes the EXI stream, invokes the called service method, and provides the response EXI stream
  820. * \param service struct EXIService* Represent the service data structure
  821. * \param inStream uint8_t* EXI in stream
  822. * \param sizeInStream uint16_t Length of the inStream
  823. * \param outStream uint8_t* Represent the out stream
  824. * \param sizeOutStream uint16_t Size of the out stream
  825. * \param outStreamLength uint16_t* Length of the stream
  826. * \return 0 = 0K; -1 = ERROR
  827. */
  828. int messageDispatcher(struct EXIService* service, uint8_t* inStream, uint16_t sizeInStream, uint8_t* outStream, uint16_t sizeOutStream, uint16_t* outStreamLength)
  829. {
  830. struct HeaderType header;
  831. uint16_t inPos, outPos;
  832. /* assign inStream data to service EXI structure */
  833. inPos = service->transportHeaderOffset;
  834. service->inStream.data = inStream;
  835. service->inStream.size = sizeInStream+inPos;
  836. service->inStream.pos = &inPos;
  837. service->inStream.buffer=0;
  838. service->inStream.capacity=0;
  839. /* assign outStream data to service EXI structure */
  840. outPos=service->transportHeaderOffset;
  841. service->outStream.data = outStream;
  842. service->outStream.size = sizeOutStream;
  843. service->outStream.pos = &outPos;
  844. service->outStream.buffer=0;
  845. service->outStream.capacity=8;
  846. /* clear error code */
  847. service->errorCode = 0;
  848. /* init EXI decoder (read header, set initial state) */
  849. exiInitDecoder(&(service->inStream), &(service->stateDecode));
  850. /* init EXI encoder (write header, set initial state) */
  851. exiInitEncoder(&(service->outStream), &(service->stateEncode));
  852. /* init uniqueID stack */
  853. service->idPath.pos=0;
  854. init_HeaderType(&header);
  855. service->exiMsg.V2G_Message.Header = &header;
  856. /* init EXI message */
  857. init_EXIDocumentType(&(service->exiMsg));
  858. /* deserialize the input stream and call the corresponding service */
  859. if(deserializeMessage(service))
  860. {
  861. return -1; /* something went wrong */
  862. }
  863. /* determine payload size (without transport offset) */
  864. outPos -= service->transportHeaderOffset;
  865. *outStreamLength = outPos;
  866. return 0;
  867. }
  868. /**
  869. * \brief Init the v2g service data structure
  870. * \param service struct EXIService* Service data structure
  871. * \param bytes bytes_t setted up byte data structure
  872. * \param string_ucs_t setted up string data structure
  873. * \param transportHeaderOffset uint16_t Transport protocol offset
  874. * \return 0 = 0K; -1 = ERROR
  875. */
  876. int init_v2gservice(struct EXIService* service, bytes_t bytes, string_ucs_t string, uint16_t transportHeaderOffset)
  877. {
  878. /* init byte array */
  879. service->val.binary = bytes;
  880. /* init string array */
  881. service->val.string = string;
  882. /* init offset for transport protocoll */
  883. service->transportHeaderOffset=transportHeaderOffset;
  884. return 0;
  885. }