V2GCommunicationSessionEVCC.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. /*******************************************************************************
  2. * The MIT License (MIT)
  3. *
  4. * Copyright (c) 2015 - 2019 Dr. Marc Mültin (V2G Clarity)
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. *******************************************************************************/
  24. package com.v2gclarity.risev2g.evcc.session;
  25. import java.util.ArrayList;
  26. import java.util.List;
  27. import java.util.Observable;
  28. import java.util.Observer;
  29. import com.v2gclarity.risev2g.evcc.evController.IEVController;
  30. import com.v2gclarity.risev2g.evcc.misc.EVCCImplementationFactory;
  31. import com.v2gclarity.risev2g.evcc.states.WaitForAuthorizationRes;
  32. import com.v2gclarity.risev2g.evcc.states.WaitForCableCheckRes;
  33. import com.v2gclarity.risev2g.evcc.states.WaitForCertificateInstallationRes;
  34. import com.v2gclarity.risev2g.evcc.states.WaitForCertificateUpdateRes;
  35. import com.v2gclarity.risev2g.evcc.states.WaitForChargeParameterDiscoveryRes;
  36. import com.v2gclarity.risev2g.evcc.states.WaitForChargingStatusRes;
  37. import com.v2gclarity.risev2g.evcc.states.WaitForCurrentDemandRes;
  38. import com.v2gclarity.risev2g.evcc.states.WaitForMeteringReceiptRes;
  39. import com.v2gclarity.risev2g.evcc.states.WaitForPaymentDetailsRes;
  40. import com.v2gclarity.risev2g.evcc.states.WaitForPaymentServiceSelectionRes;
  41. import com.v2gclarity.risev2g.evcc.states.WaitForPowerDeliveryRes;
  42. import com.v2gclarity.risev2g.evcc.states.WaitForPreChargeRes;
  43. import com.v2gclarity.risev2g.evcc.states.WaitForServiceDetailRes;
  44. import com.v2gclarity.risev2g.evcc.states.WaitForServiceDiscoveryRes;
  45. import com.v2gclarity.risev2g.evcc.states.WaitForSessionSetupRes;
  46. import com.v2gclarity.risev2g.evcc.states.WaitForSessionStopRes;
  47. import com.v2gclarity.risev2g.evcc.states.WaitForSupportedAppProtocolRes;
  48. import com.v2gclarity.risev2g.evcc.states.WaitForWeldingDetectionRes;
  49. import com.v2gclarity.risev2g.evcc.transportLayer.StatefulTransportLayerClient;
  50. import com.v2gclarity.risev2g.evcc.transportLayer.TCPClient;
  51. import com.v2gclarity.risev2g.evcc.transportLayer.TLSClient;
  52. import com.v2gclarity.risev2g.shared.enumerations.CPStates;
  53. import com.v2gclarity.risev2g.shared.enumerations.GlobalValues;
  54. import com.v2gclarity.risev2g.shared.enumerations.V2GMessages;
  55. import com.v2gclarity.risev2g.shared.messageHandling.ChangeProcessingState;
  56. import com.v2gclarity.risev2g.shared.messageHandling.PauseSession;
  57. import com.v2gclarity.risev2g.shared.messageHandling.ReactionToIncomingMessage;
  58. import com.v2gclarity.risev2g.shared.messageHandling.SendMessage;
  59. import com.v2gclarity.risev2g.shared.messageHandling.TerminateSession;
  60. import com.v2gclarity.risev2g.shared.misc.V2GCommunicationSession;
  61. import com.v2gclarity.risev2g.shared.misc.V2GTPMessage;
  62. import com.v2gclarity.risev2g.shared.utils.ByteUtils;
  63. import com.v2gclarity.risev2g.shared.utils.MiscUtils;
  64. import com.v2gclarity.risev2g.shared.utils.SecurityUtils.ContractCertificateStatus;
  65. import com.v2gclarity.risev2g.shared.v2gMessages.appProtocol.AppProtocolType;
  66. import com.v2gclarity.risev2g.shared.v2gMessages.appProtocol.SupportedAppProtocolRes;
  67. import com.v2gclarity.risev2g.shared.v2gMessages.msgDef.ChargeParameterDiscoveryReqType;
  68. import com.v2gclarity.risev2g.shared.v2gMessages.msgDef.ChargingProfileType;
  69. import com.v2gclarity.risev2g.shared.v2gMessages.msgDef.ChargingSessionType;
  70. import com.v2gclarity.risev2g.shared.v2gMessages.msgDef.EnergyTransferModeType;
  71. import com.v2gclarity.risev2g.shared.v2gMessages.msgDef.PaymentOptionType;
  72. import com.v2gclarity.risev2g.shared.v2gMessages.msgDef.SAScheduleListType;
  73. import com.v2gclarity.risev2g.shared.v2gMessages.msgDef.SelectedServiceListType;
  74. import com.v2gclarity.risev2g.shared.v2gMessages.msgDef.SelectedServiceType;
  75. import com.v2gclarity.risev2g.shared.v2gMessages.msgDef.ServiceListType;
  76. import com.v2gclarity.risev2g.shared.v2gMessages.msgDef.V2GMessage;
  77. // The state machine
  78. public class V2GCommunicationSessionEVCC extends V2GCommunicationSession implements Observer {
  79. private long v2gEVCCCommunicationSetupTimer;
  80. private String evseID;
  81. private PaymentOptionType selectedPaymentOption;
  82. private ReactionToIncomingMessage reactionToIncomingMessage;
  83. /*
  84. * chargeParameterDiscoveryReq is saved in the session because it might need to be resent in case
  85. * the EVSEProcessing parameter of the respective response message is set to "Ongoing"
  86. * (saves some processing time)
  87. */
  88. private ChargeParameterDiscoveryReqType chargeParameterDiscoveryReq;
  89. private ChargingSessionType chargingSession;
  90. private boolean renegotiationRequested;
  91. private ChargingProfileType chargingProfile;
  92. private ServiceListType offeredServices;
  93. private SelectedServiceListType selectedServices;
  94. private ArrayList<Integer> serviceDetailsToBeRequested;
  95. private EnergyTransferModeType requestedEnergyTransferMode;
  96. private long evseScheduleReceived; // The timestamp of receiving the SAScheduleList from the EVSE, is used as a reference
  97. private List<AppProtocolType> supportedAppProtocols;
  98. private AppProtocolType chosenAppProtocol;
  99. private boolean oldSessionJoined;
  100. private IEVController evController;
  101. private long evseTimeStamp;
  102. private SAScheduleListType saSchedules;
  103. private long saSchedulesReceived;
  104. private CPStates changeToState; // signals a needed state change (checked when sending the request message)
  105. private StatefulTransportLayerClient transportLayerClient;
  106. private ContractCertificateStatus contractCertStatus;
  107. private long ongoingTimer; // used for V2G_EVCC_Ongoing_Timer, V2G_EVCC_PreCharge_Timer, V2G_EVCC_CableCheck_Timer
  108. private boolean isOngoingTimerActive;
  109. private byte[] sentGenChallenge;
  110. public V2GCommunicationSessionEVCC(StatefulTransportLayerClient transportLayerClient) {
  111. setTransportLayerClient(transportLayerClient);
  112. getStates().put(V2GMessages.SUPPORTED_APP_PROTOCOL_RES, new WaitForSupportedAppProtocolRes(this));
  113. getStates().put(V2GMessages.SESSION_SETUP_RES, new WaitForSessionSetupRes(this));
  114. getStates().put(V2GMessages.SERVICE_DISCOVERY_RES, new WaitForServiceDiscoveryRes(this));
  115. getStates().put(V2GMessages.SERVICE_DETAIL_RES, new WaitForServiceDetailRes(this));
  116. getStates().put(V2GMessages.PAYMENT_SERVICE_SELECTION_RES, new WaitForPaymentServiceSelectionRes(this));
  117. getStates().put(V2GMessages.CERTIFICATE_INSTALLATION_RES, new WaitForCertificateInstallationRes(this));
  118. getStates().put(V2GMessages.CERTIFICATE_UPDATE_RES, new WaitForCertificateUpdateRes(this));
  119. getStates().put(V2GMessages.PAYMENT_DETAILS_RES, new WaitForPaymentDetailsRes(this));
  120. getStates().put(V2GMessages.AUTHORIZATION_RES, new WaitForAuthorizationRes(this));
  121. getStates().put(V2GMessages.CHARGE_PARAMETER_DISCOVERY_RES, new WaitForChargeParameterDiscoveryRes(this));
  122. getStates().put(V2GMessages.CABLE_CHECK_RES, new WaitForCableCheckRes(this));
  123. getStates().put(V2GMessages.PRE_CHARGE_RES, new WaitForPreChargeRes(this));
  124. getStates().put(V2GMessages.POWER_DELIVERY_RES, new WaitForPowerDeliveryRes(this));
  125. getStates().put(V2GMessages.CHARGING_STATUS_RES, new WaitForChargingStatusRes(this));
  126. getStates().put(V2GMessages.CURRENT_DEMAND_RES, new WaitForCurrentDemandRes(this));
  127. getStates().put(V2GMessages.METERING_RECEIPT_RES, new WaitForMeteringReceiptRes(this));
  128. getStates().put(V2GMessages.WELDING_DETECTION_RES, new WaitForWeldingDetectionRes(this));
  129. getStates().put(V2GMessages.SESSION_STOP_RES, new WaitForSessionStopRes(this));
  130. setStartState(getStates().get(V2GMessages.SUPPORTED_APP_PROTOCOL_RES));
  131. setCurrentState(getStartState());
  132. // configure which EV controller implementation to use
  133. // TODO the EV controller needs to run as a separate Thread (to receive notifications from the EV and to avoid blocking calls to the controller)
  134. setEvController(EVCCImplementationFactory.createEVController(this));
  135. /*
  136. * Is needed for measuring the time span between transition to state B (plug-in) and receipt
  137. * of a SessionSetupRes (see V2G_EVCC_COMMUNICATION_SETUP_TIMEOUT in TimeRestrictions.java)
  138. * TODO check if this timing requirement is still up to date
  139. */
  140. setV2gEVCCCommunicationSetupTimer(System.nanoTime());
  141. // Set default value for contract certificate status to UNKNOWN
  142. setContractCertStatus(ContractCertificateStatus.UNKNOWN);
  143. // ChargingSessionType only takes enum values "Pause" and "Terminate". Therefore, set it to null at beginning of charging session
  144. setChargingSession(null);
  145. getLogger().debug("\n*******************************************" +
  146. "\n* New V2G communication session initialized" +
  147. "\n*******************************************");
  148. }
  149. @Override
  150. public void update(Observable obs, Object obj) {
  151. if ((obs instanceof TCPClient || obs instanceof TLSClient) && obj instanceof byte[]) {
  152. setV2gTpMessage(new V2GTPMessage((byte[]) obj));
  153. if (getMessageHandler().isV2GTPMessageValid(getV2gTpMessage())) {
  154. /*
  155. * We need to decide which schema to use for decoding the EXI encoded message. Only
  156. * the supportedAppProtocolReq/Res message uses a different schema
  157. */
  158. if (getCurrentState().equals(getStates().get(V2GMessages.SUPPORTED_APP_PROTOCOL_RES))) {
  159. obj = (SupportedAppProtocolRes) getMessageHandler().exiToSuppAppProtocolMsg(getV2gTpMessage().getPayload());
  160. } else {
  161. try {
  162. obj = (V2GMessage) getMessageHandler().exiToV2gMsg(getV2gTpMessage().getPayload());
  163. } catch (ClassCastException e) {
  164. terminateSession("Received incoming message is not a valid V2GTPMessage\n" + e, false);
  165. }
  166. }
  167. processReaction(getCurrentState().processIncomingMessage(obj));
  168. } else {
  169. terminateSession("Received incoming message is not a valid V2GTPMessage", false);
  170. }
  171. } else if ((obs instanceof TCPClient || obs instanceof TLSClient) && obj == null) {
  172. terminateSession("Transport layer has notified an error", false);
  173. } else {
  174. terminateSession("Notification received, but sending entity or received object not identifiable", false);
  175. }
  176. }
  177. private void processReaction(ReactionToIncomingMessage reactionToIncomingMessage) {
  178. if (reactionToIncomingMessage instanceof SendMessage) {
  179. send((SendMessage) reactionToIncomingMessage);
  180. } else if (reactionToIncomingMessage instanceof TerminateSession) {
  181. deleteSessionProperties();
  182. terminateSession((TerminateSession) reactionToIncomingMessage);
  183. } else if (reactionToIncomingMessage instanceof PauseSession) {
  184. saveSessionProperties();
  185. pauseSession((PauseSession) reactionToIncomingMessage);
  186. } else if (reactionToIncomingMessage instanceof ChangeProcessingState) {
  187. setCurrentState(((ChangeProcessingState) reactionToIncomingMessage).getNewState());
  188. processReaction(
  189. getCurrentState().processIncomingMessage(reactionToIncomingMessage)
  190. ); // TODO ist das korrekt?! bspw. wenn Renegotiation angefragt wird von EVSE?
  191. } else {
  192. terminateSession("Reaction to incoming message is undefined", false);
  193. }
  194. }
  195. public void send(SendMessage sendingParams) {
  196. // Only EXI encoded messages starting from SessionSetupReq will be sent here
  197. setV2gTpMessage(new V2GTPMessage(GlobalValues.V2GTP_VERSION_1_IS.getByteValue(),
  198. GlobalValues.V2GTP_PAYLOAD_TYPE_EXI_ENCODED_V2G_MESSAGE.getByteArrayValue(),
  199. (byte[]) getMessageHandler().v2gMsgToExi(sendingParams.getPayload()))
  200. );
  201. getTransportLayerClient().send(getV2gTpMessage(), sendingParams.getTimeout());
  202. // Check for necessary CP state change (see [V2G2-847])
  203. if (getChangeToState() != null) {
  204. if (getEvController().setCPState(getChangeToState())) setChangeToState(null);
  205. else terminateSession("State change to " + getChangeToState().toString() + " not successful", false);
  206. }
  207. if (sendingParams.getNextState() != null) {
  208. setCurrentState(sendingParams.getNextState());
  209. } else {
  210. terminateSession("State machine interrupted, no new state provided", true);
  211. }
  212. }
  213. private void saveSessionProperties() {
  214. // According to [V2G2-740]
  215. MiscUtils.getProperties().setProperty("session.id", "" + ByteUtils.toHexString(getSessionID()));
  216. MiscUtils.getProperties().setProperty("authentication.mode", getSelectedPaymentOption().value());
  217. MiscUtils.getProperties().setProperty("energy.transfermode.requested", getRequestedEnergyTransferMode().value());
  218. MiscUtils.storeProperties(GlobalValues.EVCC_CONFIG_PROPERTIES_PATH.toString());
  219. }
  220. private void deleteSessionProperties() {
  221. // Reset the session ID and the authentication mode
  222. MiscUtils.getProperties().setProperty("session.id", "00");
  223. MiscUtils.getProperties().setProperty("authentication.mode", "");
  224. MiscUtils.storeProperties(GlobalValues.EVCC_CONFIG_PROPERTIES_PATH.toString());
  225. }
  226. private void setV2gEVCCCommunicationSetupTimer(
  227. long v2gEVCCCommunicationSetupTimer) {
  228. this.v2gEVCCCommunicationSetupTimer = v2gEVCCCommunicationSetupTimer;
  229. }
  230. public long getV2gEVCCCommunicationSetupTimer() {
  231. return v2gEVCCCommunicationSetupTimer;
  232. }
  233. public String getEvseID() {
  234. return evseID;
  235. }
  236. public void setEvseID(String evseID) {
  237. this.evseID = evseID;
  238. }
  239. public PaymentOptionType getSelectedPaymentOption() {
  240. return selectedPaymentOption;
  241. }
  242. public void setSelectedPaymentOption(PaymentOptionType selectedPaymentOption) {
  243. this.selectedPaymentOption = selectedPaymentOption;
  244. }
  245. public ChargeParameterDiscoveryReqType getChargeParameterDiscoveryReq() {
  246. return chargeParameterDiscoveryReq;
  247. }
  248. public void setChargeParameterDiscoveryReq(
  249. ChargeParameterDiscoveryReqType chargeParameterDiscoveryReq) {
  250. this.chargeParameterDiscoveryReq = chargeParameterDiscoveryReq;
  251. }
  252. public ReactionToIncomingMessage getReactionToIncomingMessage() {
  253. return reactionToIncomingMessage;
  254. }
  255. public void setReactionToIncomingMessage(ReactionToIncomingMessage reactionToIncomingMessage) {
  256. this.reactionToIncomingMessage = reactionToIncomingMessage;
  257. }
  258. public boolean isRenegotiationRequested() {
  259. return renegotiationRequested;
  260. }
  261. public void setRenegotiationRequested(boolean renegotiationRequested) {
  262. this.renegotiationRequested = renegotiationRequested;
  263. }
  264. public long getEvseScheduleReceived() {
  265. return evseScheduleReceived;
  266. }
  267. public void setEvseScheduleReceived(long evseScheduleReceived) {
  268. this.evseScheduleReceived = evseScheduleReceived;
  269. }
  270. public ChargingProfileType getChargingProfile() {
  271. return chargingProfile;
  272. }
  273. public void setChargingProfile(ChargingProfileType chargingProfile) {
  274. this.chargingProfile = chargingProfile;
  275. }
  276. public List<AppProtocolType> getSupportedAppProtocols() {
  277. return supportedAppProtocols;
  278. }
  279. public void setSupportedAppProtocols(List<AppProtocolType> supportedAppProtocols) {
  280. this.supportedAppProtocols = supportedAppProtocols;
  281. }
  282. public AppProtocolType getChosenAppProtocol() {
  283. return chosenAppProtocol;
  284. }
  285. public void setChosenAppProtocol(AppProtocolType chosenAppProtocol) {
  286. this.chosenAppProtocol = chosenAppProtocol;
  287. }
  288. public boolean isOldSessionJoined() {
  289. return oldSessionJoined;
  290. }
  291. public void setOldSessionJoined(boolean oldSessionJoined) {
  292. this.oldSessionJoined = oldSessionJoined;
  293. }
  294. public IEVController getEvController() {
  295. return evController;
  296. }
  297. public void setEvController(IEVController evController) {
  298. this.evController = evController;
  299. }
  300. public long getEvseTimeStamp() {
  301. return evseTimeStamp;
  302. }
  303. public void setEvseTimeStamp(long evseTimeStamp) {
  304. this.evseTimeStamp = evseTimeStamp;
  305. }
  306. public EnergyTransferModeType getRequestedEnergyTransferMode() {
  307. return requestedEnergyTransferMode;
  308. }
  309. public void setRequestedEnergyTransferMode(
  310. EnergyTransferModeType requestedEnergyTransferMode) {
  311. this.requestedEnergyTransferMode = requestedEnergyTransferMode;
  312. }
  313. public SAScheduleListType getSaSchedules() {
  314. return saSchedules;
  315. }
  316. public void setSaSchedules(SAScheduleListType saSchedules) {
  317. this.saSchedules = saSchedules;
  318. this.saSchedulesReceived = System.nanoTime();
  319. }
  320. public long getSaSchedulesReceived() {
  321. return saSchedulesReceived;
  322. }
  323. public CPStates getChangeToState() {
  324. return changeToState;
  325. }
  326. public void setChangeToState(CPStates changeToState) {
  327. this.changeToState = changeToState;
  328. }
  329. public StatefulTransportLayerClient getTransportLayerClient() {
  330. return transportLayerClient;
  331. }
  332. public void setTransportLayerClient(StatefulTransportLayerClient transportLayerClient) {
  333. this.transportLayerClient = transportLayerClient;
  334. }
  335. public SelectedServiceListType getSelectedServices() {
  336. if (selectedServices == null) setSelectedServices(new SelectedServiceListType());
  337. return selectedServices;
  338. }
  339. public void setSelectedServices(SelectedServiceListType selectedServices) {
  340. this.selectedServices = selectedServices;
  341. }
  342. public ServiceListType getOfferedServices() {
  343. if (offeredServices == null) setOfferedServices(new ServiceListType());
  344. return offeredServices;
  345. }
  346. public void setOfferedServices(ServiceListType offeredServices) {
  347. this.offeredServices = offeredServices;
  348. }
  349. public ArrayList<Integer> getServiceDetailsToBeRequested() {
  350. if (serviceDetailsToBeRequested == null) {
  351. serviceDetailsToBeRequested = new ArrayList<Integer>();
  352. }
  353. return serviceDetailsToBeRequested;
  354. }
  355. public void setServiceDetailsToBeRequested(
  356. ArrayList<Integer> serviceDetailsToBeRequested) {
  357. this.serviceDetailsToBeRequested = serviceDetailsToBeRequested;
  358. }
  359. /**
  360. * Checks if the respective service for installing or updating a certificate is offered by the SECC and
  361. * has been selected by the EVCC.
  362. *
  363. * @param parameterSetID 1 for installing a certificate, 2 for updating a certificate
  364. * @return True, if the respective certificate service is available, false otherwise
  365. */
  366. public boolean isCertificateServiceAvailable(short parameterSetID) {
  367. for (SelectedServiceType service : getSelectedServices().getSelectedService()) {
  368. if (service.getServiceID() == 2 && // ServiceID 2 refers to the 'Certificate' service
  369. service.getParameterSetID() != null &&
  370. service.getParameterSetID() == parameterSetID)
  371. return true;
  372. }
  373. return false;
  374. }
  375. public ContractCertificateStatus getContractCertStatus() {
  376. return contractCertStatus;
  377. }
  378. public void setContractCertStatus(ContractCertificateStatus contractCertStatus) {
  379. this.contractCertStatus = contractCertStatus;
  380. }
  381. public long getOngoingTimer() {
  382. return ongoingTimer;
  383. }
  384. public void setOngoingTimer(long ongoingTimer) {
  385. this.ongoingTimer = ongoingTimer;
  386. }
  387. public boolean isOngoingTimerActive() {
  388. return isOngoingTimerActive;
  389. }
  390. public void setOngoingTimerActive(boolean isOngoingTimerActive) {
  391. this.isOngoingTimerActive = isOngoingTimerActive;
  392. }
  393. public byte[] getSentGenChallenge() {
  394. return sentGenChallenge;
  395. }
  396. public void setSentGenChallenge(byte[] sentGenChallenge) {
  397. this.sentGenChallenge = sentGenChallenge;
  398. }
  399. public ChargingSessionType getChargingSession() {
  400. return chargingSession;
  401. }
  402. public void setChargingSession(ChargingSessionType chargingSession) {
  403. this.chargingSession = chargingSession;
  404. }
  405. }