From fac366be0dd13f5777258a45dc4dd7d7ed4ff075 Mon Sep 17 00:00:00 2001 From: docker-debian Date: Fri, 12 Sep 2025 07:36:32 +0900 Subject: [PATCH] feat: Port Phase 3 Extended Features to VC2022 - Payment, Charging Status, Session Stop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add function declarations for all 6 Phase 3 message handlers in VC2022 style - Add message detection logic without emoji indicators (VC2022 convention): - PaymentServiceSelectionReq/Res: Payment method selection - ChargingStatusReq/Res: AC charging status monitoring - SessionStopReq/Res: Session termination control - Implement comprehensive helper functions with traditional formatting: - Payment option analysis (Contract vs External payment) - Service list parsing and enumeration - AC charging status with detailed meter information - Session termination with ChargingSession enum handling - Maintain VC2022 coding style: no emojis, traditional printf formatting - All Phase 3 messages now implemented in both C and VC2022 - Ready for final .NET implementation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- Port/vc2022/V2GDecoder.c | 207 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) diff --git a/Port/vc2022/V2GDecoder.c b/Port/vc2022/V2GDecoder.c index 1bf49c2..7368aa7 100644 --- a/Port/vc2022/V2GDecoder.c +++ b/Port/vc2022/V2GDecoder.c @@ -56,6 +56,14 @@ void print_authorization_res_details(struct iso1AuthorizationResType *authorizat void print_charge_param_discovery_req_details(struct iso1ChargeParameterDiscoveryReqType *chargeParamReq); void print_charge_param_discovery_res_details(struct iso1ChargeParameterDiscoveryResType *chargeParamRes); +// Phase 3: Extended Features - Function declarations +void print_payment_service_selection_req_details(struct iso1PaymentServiceSelectionReqType *paymentServiceSelectionReq); +void print_payment_service_selection_res_details(struct iso1PaymentServiceSelectionResType *paymentServiceSelectionRes); +void print_charging_status_req_details(struct iso1ChargingStatusReqType *chargingStatusReq); +void print_charging_status_res_details(struct iso1ChargingStatusResType *chargingStatusRes); +void print_session_stop_req_details(struct iso1SessionStopReqType *sessionStopReq); +void print_session_stop_res_details(struct iso1SessionStopResType *sessionStopRes); + // Function to detect and extract EXI body from V2G Transfer Protocol data size_t extract_exi_body(uint8_t* input_data, size_t input_size, uint8_t* output_data, size_t output_size) { if (input_size < 8) { @@ -1181,6 +1189,31 @@ void print_iso1_message(struct iso1EXIDocument* doc) { printf("Message Type: ChargeParameterDiscoveryRes\n"); print_charge_param_discovery_res_details(&doc->V2G_Message.Body.ChargeParameterDiscoveryRes); } + // Phase 3: Extended Features - Message detection + else if (doc->V2G_Message.Body.PaymentServiceSelectionReq_isUsed) { + printf("Message Type: PaymentServiceSelectionReq\n"); + print_payment_service_selection_req_details(&doc->V2G_Message.Body.PaymentServiceSelectionReq); + } + else if (doc->V2G_Message.Body.PaymentServiceSelectionRes_isUsed) { + printf("Message Type: PaymentServiceSelectionRes\n"); + print_payment_service_selection_res_details(&doc->V2G_Message.Body.PaymentServiceSelectionRes); + } + else if (doc->V2G_Message.Body.ChargingStatusReq_isUsed) { + printf("Message Type: ChargingStatusReq\n"); + print_charging_status_req_details(&doc->V2G_Message.Body.ChargingStatusReq); + } + else if (doc->V2G_Message.Body.ChargingStatusRes_isUsed) { + printf("Message Type: ChargingStatusRes\n"); + print_charging_status_res_details(&doc->V2G_Message.Body.ChargingStatusRes); + } + else if (doc->V2G_Message.Body.SessionStopReq_isUsed) { + printf("Message Type: SessionStopReq\n"); + print_session_stop_req_details(&doc->V2G_Message.Body.SessionStopReq); + } + else if (doc->V2G_Message.Body.SessionStopRes_isUsed) { + printf("Message Type: SessionStopRes\n"); + print_session_stop_res_details(&doc->V2G_Message.Body.SessionStopRes); + } else { printf("Message Type: Other message type (not implemented)\n"); } @@ -1749,4 +1782,178 @@ int main(int argc, char *argv[]) { } return -1; +} + +// Phase 3: Extended Features - Helper function implementations (VC2022 style without emojis) + +void print_payment_service_selection_req_details(struct iso1PaymentServiceSelectionReqType *paymentServiceSelectionReq) { + printf("Payment Service Selection Request Details:\\n"); + printf(" Purpose: Select payment method for charging session\\n"); + + printf(" Selected Payment Option: "); + switch(paymentServiceSelectionReq->SelectedPaymentOption) { + case iso1paymentOptionType_Contract: + printf("Contract-based payment\\n"); + break; + case iso1paymentOptionType_ExternalPayment: + printf("External payment method\\n"); + break; + default: + printf("Unknown (%d)\\n", paymentServiceSelectionReq->SelectedPaymentOption); + } + + printf(" Selected Service List:\\n"); + if (paymentServiceSelectionReq->SelectedServiceList.SelectedService.arrayLen > 0) { + for (int i = 0; i < paymentServiceSelectionReq->SelectedServiceList.SelectedService.arrayLen; i++) { + printf(" %d. Service ID: %d, Parameter Set ID: %d\\n", + i + 1, + paymentServiceSelectionReq->SelectedServiceList.SelectedService.array[i].ServiceID, + paymentServiceSelectionReq->SelectedServiceList.SelectedService.array[i].ParameterSetID_isUsed ? + paymentServiceSelectionReq->SelectedServiceList.SelectedService.array[i].ParameterSetID : -1); + } + } else { + printf(" No services selected\\n"); + } + + printf(" Payment service selection requested\\n"); +} + +void print_payment_service_selection_res_details(struct iso1PaymentServiceSelectionResType *paymentServiceSelectionRes) { + printf("Payment Service Selection Response Details:\\n"); + printf(" Purpose: Confirm payment method selection\\n"); + + printf(" Response Code: "); + switch(paymentServiceSelectionRes->ResponseCode) { + case iso1responseCodeType_OK: + printf("OK - Payment selection accepted\\n"); + break; + case iso1responseCodeType_OK_NewSessionEstablished: + printf("OK - New session established\\n"); + break; + case iso1responseCodeType_FAILED: + printf("FAILED\\n"); + break; + default: + printf("Unknown (%d)\\n", paymentServiceSelectionRes->ResponseCode); + } + + printf(" Payment method selection completed\\n"); +} + +void print_charging_status_req_details(struct iso1ChargingStatusReqType *chargingStatusReq) { + printf("Charging Status Request Details:\\n"); + printf(" Purpose: Request AC charging status information\\n"); + + printf(" Requesting current charging status from EVSE\\n"); + printf(" Status inquiry for AC charging session\\n"); +} + +void print_charging_status_res_details(struct iso1ChargingStatusResType *chargingStatusRes) { + printf("Charging Status Response Details:\\n"); + printf(" Purpose: Provide AC charging status information\\n"); + + printf(" Response Code: "); + switch(chargingStatusRes->ResponseCode) { + case iso1responseCodeType_OK: + printf("OK\\n"); + break; + case iso1responseCodeType_OK_NewSessionEstablished: + printf("OK - New session established\\n"); + break; + case iso1responseCodeType_FAILED: + printf("FAILED\\n"); + break; + default: + printf("Unknown (%d)\\n", chargingStatusRes->ResponseCode); + } + + printf(" EVSE ID: "); + if (chargingStatusRes->EVSEID.charactersLen > 0) { + printf("%.*s\\n", (int)chargingStatusRes->EVSEID.charactersLen, chargingStatusRes->EVSEID.characters); + } else { + printf("Not provided\\n"); + } + + printf(" SA Schedule Tuple ID: %d\\n", chargingStatusRes->SAScheduleTupleID); + + if (chargingStatusRes->EVSEMaxCurrent_isUsed) { + printf(" EVSE Max Current: %d %s (10^%d)\\n", + chargingStatusRes->EVSEMaxCurrent.Value, + chargingStatusRes->EVSEMaxCurrent.Unit == 5 ? "A" : "Unknown Unit", + chargingStatusRes->EVSEMaxCurrent.Multiplier); + } + + if (chargingStatusRes->MeterInfo_isUsed) { + printf(" Meter Information:\\n"); + printf(" Meter ID: "); + if (chargingStatusRes->MeterInfo.MeterID.charactersLen > 0) { + printf("%.*s\\n", (int)chargingStatusRes->MeterInfo.MeterID.charactersLen, + chargingStatusRes->MeterInfo.MeterID.characters); + } else { + printf("Not provided\\n"); + } + + if (chargingStatusRes->MeterInfo.MeterReading_isUsed) { + printf(" Meter Reading: %llu Wh\\n", + (unsigned long long)chargingStatusRes->MeterInfo.MeterReading); + } + + if (chargingStatusRes->MeterInfo.SigMeterReading_isUsed) { + printf(" Signed Meter Reading: %.*s\\n", + (int)chargingStatusRes->MeterInfo.SigMeterReading.bytesLen, + (char*)chargingStatusRes->MeterInfo.SigMeterReading.bytes); + } + + if (chargingStatusRes->MeterInfo.MeterStatus_isUsed) { + printf(" Meter Status: %d\\n", chargingStatusRes->MeterInfo.MeterStatus); + } + } + + if (chargingStatusRes->ReceiptRequired_isUsed) { + printf(" Receipt Required: %s\\n", + chargingStatusRes->ReceiptRequired ? "Yes" : "No"); + } + + printf(" AC charging status provided\\n"); +} + +void print_session_stop_req_details(struct iso1SessionStopReqType *sessionStopReq) { + printf("Session Stop Request Details:\\n"); + printf(" Purpose: Request charging session termination\\n"); + + printf(" Charging Session: "); + switch(sessionStopReq->ChargingSession) { + case iso1chargingSessionType_Terminate: + printf("Terminate - Session ending completely\\n"); + break; + case iso1chargingSessionType_Pause: + printf("Pause - Session paused temporarily\\n"); + break; + default: + printf("Unknown (%d)\\n", sessionStopReq->ChargingSession); + } + + printf(" Requesting session termination\\n"); +} + +void print_session_stop_res_details(struct iso1SessionStopResType *sessionStopRes) { + printf("Session Stop Response Details:\\n"); + printf(" Purpose: Confirm charging session termination\\n"); + + printf(" Response Code: "); + switch(sessionStopRes->ResponseCode) { + case iso1responseCodeType_OK: + printf("OK - Session terminated successfully\\n"); + break; + case iso1responseCodeType_OK_NewSessionEstablished: + printf("OK - New session established\\n"); + break; + case iso1responseCodeType_FAILED: + printf("FAILED - Session termination failed\\n"); + break; + default: + printf("Unknown (%d)\\n", sessionStopRes->ResponseCode); + } + + printf(" Charging session terminated\\n"); } \ No newline at end of file