feat: Port Phase 3 Extended Features to VC2022 - Payment, Charging Status, Session Stop

- 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 <noreply@anthropic.com>
This commit is contained in:
2025-09-12 07:36:32 +09:00
parent e086ab5ce1
commit fac366be0d

View File

@@ -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");
}