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:
@@ -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_req_details(struct iso1ChargeParameterDiscoveryReqType *chargeParamReq);
|
||||||
void print_charge_param_discovery_res_details(struct iso1ChargeParameterDiscoveryResType *chargeParamRes);
|
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
|
// 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) {
|
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) {
|
if (input_size < 8) {
|
||||||
@@ -1181,6 +1189,31 @@ void print_iso1_message(struct iso1EXIDocument* doc) {
|
|||||||
printf("Message Type: ChargeParameterDiscoveryRes\n");
|
printf("Message Type: ChargeParameterDiscoveryRes\n");
|
||||||
print_charge_param_discovery_res_details(&doc->V2G_Message.Body.ChargeParameterDiscoveryRes);
|
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 {
|
else {
|
||||||
printf("Message Type: Other message type (not implemented)\n");
|
printf("Message Type: Other message type (not implemented)\n");
|
||||||
}
|
}
|
||||||
@@ -1749,4 +1782,178 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
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");
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user