From e086ab5ce14c5ce11bcaa298fb9ba8041a77746b Mon Sep 17 00:00:00 2001 From: docker-debian Date: Fri, 12 Sep 2025 07:34:47 +0900 Subject: [PATCH] feat: Implement Phase 3 Extended Features in C - 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 - Add message detection logic for: - PaymentServiceSelectionReq/Res: Payment method selection - ChargingStatusReq/Res: AC charging status monitoring - SessionStopReq/Res: Session termination control - Implement comprehensive helper functions with: - Payment option analysis (Contract vs External) - Service list parsing and display - AC charging status with meter information - Session termination with ChargingSession enum handling - Fix struct member access for iso1SessionStopReqType.ChargingSession - Include emoji indicators for better UX and debugging - Phase 3 C implementation complete, ready for VC2022/dotnet ports πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- V2GDecoder.c | 207 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) diff --git a/V2GDecoder.c b/V2GDecoder.c index 32a2195..b400c8a 100644 --- a/V2GDecoder.c +++ b/V2GDecoder.c @@ -41,6 +41,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) { @@ -1059,6 +1067,31 @@ void print_iso1_message(struct iso1EXIDocument* doc) { printf("βœ… ChargeParameterDiscoveryRes: Charge parameter response\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("πŸ’³ PaymentServiceSelectionReq: Payment method selection request\n"); + print_payment_service_selection_req_details(&doc->V2G_Message.Body.PaymentServiceSelectionReq); + } + else if (doc->V2G_Message.Body.PaymentServiceSelectionRes_isUsed) { + printf("πŸ’³ PaymentServiceSelectionRes: Payment method selection response\n"); + print_payment_service_selection_res_details(&doc->V2G_Message.Body.PaymentServiceSelectionRes); + } + else if (doc->V2G_Message.Body.ChargingStatusReq_isUsed) { + printf("πŸ”‹ ChargingStatusReq: AC charging status request\n"); + print_charging_status_req_details(&doc->V2G_Message.Body.ChargingStatusReq); + } + else if (doc->V2G_Message.Body.ChargingStatusRes_isUsed) { + printf("πŸ”‹ ChargingStatusRes: AC charging status response\n"); + print_charging_status_res_details(&doc->V2G_Message.Body.ChargingStatusRes); + } + else if (doc->V2G_Message.Body.SessionStopReq_isUsed) { + printf("πŸ›‘ SessionStopReq: Session termination request\n"); + print_session_stop_req_details(&doc->V2G_Message.Body.SessionStopReq); + } + else if (doc->V2G_Message.Body.SessionStopRes_isUsed) { + printf("πŸ›‘ SessionStopRes: Session termination response\n"); + print_session_stop_res_details(&doc->V2G_Message.Body.SessionStopRes); + } else if (doc->V2G_Message.Body.CurrentDemandReq_isUsed) { printf("Message Type: CurrentDemandReq\n"); @@ -1599,4 +1632,178 @@ int main(int argc, char *argv[]) { } return -1; +} + +// Phase 3: Extended Features - Helper function implementations + +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