feat: Complete Phase 2 Session & Service Management messages in C

Implemented comprehensive support for ISO 15118-2 Phase 2 messages:
- SessionSetupReq/Res with EVCCID and EVSEID parsing
- ServiceDiscoveryReq/Res with payment options and charge services
- AuthorizationReq/Res with ID and challenge handling
- ChargeParameterDiscoveryReq/Res with DC parameters and schedules

Added 8 detailed helper functions with emoji indicators for improved
readability and comprehensive parameter parsing including physical
values, status codes, and complex nested structures.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-12 07:24:52 +09:00
parent a40dd6ff9d
commit 27c5824b57

View File

@@ -31,6 +31,16 @@
#define V2G_PAYLOAD_ISO2 0x8002 // ISO 15118-20 payload type
#define EXI_START_PATTERN 0x8098 // EXI document start pattern
// Function declarations for Phase 2 Session & Service Management helper functions
void print_session_setup_req_details(struct iso1SessionSetupReqType *sessionSetupReq);
void print_session_setup_res_details(struct iso1SessionSetupResType *sessionSetupRes);
void print_service_discovery_req_details(struct iso1ServiceDiscoveryReqType *serviceDiscoveryReq);
void print_service_discovery_res_details(struct iso1ServiceDiscoveryResType *serviceDiscoveryRes);
void print_authorization_req_details(struct iso1AuthorizationReqType *authorizationReq);
void print_authorization_res_details(struct iso1AuthorizationResType *authorizationRes);
void print_charge_param_discovery_req_details(struct iso1ChargeParameterDiscoveryReqType *chargeParamReq);
void print_charge_param_discovery_res_details(struct iso1ChargeParameterDiscoveryResType *chargeParamRes);
// 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) {
@@ -1017,6 +1027,38 @@ void print_iso1_message(struct iso1EXIDocument* doc) {
doc->V2G_Message.Body.CurrentDemandRes.EVSEID.characters);
printf("SAScheduleTupleID: %d\n", doc->V2G_Message.Body.CurrentDemandRes.SAScheduleTupleID);
}
else if (doc->V2G_Message.Body.SessionSetupReq_isUsed) {
printf("🔐 SessionSetupReq: Charging session initialization\n");
print_session_setup_req_details(&doc->V2G_Message.Body.SessionSetupReq);
}
else if (doc->V2G_Message.Body.SessionSetupRes_isUsed) {
printf("✅ SessionSetupRes: Session setup response\n");
print_session_setup_res_details(&doc->V2G_Message.Body.SessionSetupRes);
}
else if (doc->V2G_Message.Body.ServiceDiscoveryReq_isUsed) {
printf("🔍 ServiceDiscoveryReq: Available charging services discovery\n");
print_service_discovery_req_details(&doc->V2G_Message.Body.ServiceDiscoveryReq);
}
else if (doc->V2G_Message.Body.ServiceDiscoveryRes_isUsed) {
printf("✅ ServiceDiscoveryRes: Service discovery response\n");
print_service_discovery_res_details(&doc->V2G_Message.Body.ServiceDiscoveryRes);
}
else if (doc->V2G_Message.Body.AuthorizationReq_isUsed) {
printf("🔑 AuthorizationReq: Charging authorization verification\n");
print_authorization_req_details(&doc->V2G_Message.Body.AuthorizationReq);
}
else if (doc->V2G_Message.Body.AuthorizationRes_isUsed) {
printf("✅ AuthorizationRes: Authorization response\n");
print_authorization_res_details(&doc->V2G_Message.Body.AuthorizationRes);
}
else if (doc->V2G_Message.Body.ChargeParameterDiscoveryReq_isUsed) {
printf("⚙️ ChargeParameterDiscoveryReq: Charging parameter exchange\n");
print_charge_param_discovery_req_details(&doc->V2G_Message.Body.ChargeParameterDiscoveryReq);
}
else if (doc->V2G_Message.Body.ChargeParameterDiscoveryRes_isUsed) {
printf("✅ ChargeParameterDiscoveryRes: Charge parameter response\n");
print_charge_param_discovery_res_details(&doc->V2G_Message.Body.ChargeParameterDiscoveryRes);
}
else if (doc->V2G_Message.Body.CurrentDemandReq_isUsed) {
printf("Message Type: CurrentDemandReq\n");
@@ -1083,6 +1125,218 @@ void print_iso1_message(struct iso1EXIDocument* doc) {
printf("\n");
}
// Helper function to parse and print session setup request details
void print_session_setup_req_details(struct iso1SessionSetupReqType *sessionSetupReq) {
printf(" 🆔 EVCCID: ");
for(int i = 0; i < sessionSetupReq->EVCCID.bytesLen; i++) {
printf("%02X", sessionSetupReq->EVCCID.bytes[i]);
}
printf("\n");
}
// Helper function to parse and print session setup response details
void print_session_setup_res_details(struct iso1SessionSetupResType *sessionSetupRes) {
printf(" 📋 Response Code: %d\n", sessionSetupRes->ResponseCode);
printf(" 🆔 EVSEID: %.*s\n",
sessionSetupRes->EVSEID.charactersLen,
sessionSetupRes->EVSEID.characters);
if(sessionSetupRes->EVSETimeStamp_isUsed) {
printf(" ⏰ EVSETimeStamp: %ld\n", sessionSetupRes->EVSETimeStamp);
}
}
// Helper function to parse and print service discovery request details
void print_service_discovery_req_details(struct iso1ServiceDiscoveryReqType *serviceDiscoveryReq) {
if(serviceDiscoveryReq->ServiceScope_isUsed) {
printf(" 🔍 ServiceScope: %.*s\n",
serviceDiscoveryReq->ServiceScope.charactersLen,
serviceDiscoveryReq->ServiceScope.characters);
}
if(serviceDiscoveryReq->ServiceCategory_isUsed) {
printf(" 📂 ServiceCategory: %d\n", serviceDiscoveryReq->ServiceCategory);
}
}
// Helper function to parse and print service discovery response details
void print_service_discovery_res_details(struct iso1ServiceDiscoveryResType *serviceDiscoveryRes) {
printf(" 📋 Response Code: %d\n", serviceDiscoveryRes->ResponseCode);
printf(" ⚡ PaymentOptionList:\n");
for(int i = 0; i < serviceDiscoveryRes->PaymentOptionList.PaymentOption.arrayLen; i++) {
printf(" Payment Option %d: %d\n", i+1, serviceDiscoveryRes->PaymentOptionList.PaymentOption.array[i]);
}
printf(" 🔧 ChargeService:\n");
printf(" ServiceID: %d\n", serviceDiscoveryRes->ChargeService.ServiceID);
printf(" ServiceName: %.*s\n",
serviceDiscoveryRes->ChargeService.ServiceName_isUsed ? serviceDiscoveryRes->ChargeService.ServiceName.charactersLen : 0,
serviceDiscoveryRes->ChargeService.ServiceName_isUsed ? serviceDiscoveryRes->ChargeService.ServiceName.characters : "");
printf(" ServiceCategory: %d\n", serviceDiscoveryRes->ChargeService.ServiceCategory);
printf(" FreeService: %s\n", serviceDiscoveryRes->ChargeService.FreeService ? "true" : "false");
if(serviceDiscoveryRes->ServiceList_isUsed && serviceDiscoveryRes->ServiceList.Service.arrayLen > 0) {
printf(" 📋 ServiceList:\n");
for(int i = 0; i < serviceDiscoveryRes->ServiceList.Service.arrayLen; i++) {
printf(" Service %d - ID: %d, Category: %d\n",
i+1,
serviceDiscoveryRes->ServiceList.Service.array[i].ServiceID,
serviceDiscoveryRes->ServiceList.Service.array[i].ServiceCategory);
}
}
}
// Helper function to parse and print authorization request details
void print_authorization_req_details(struct iso1AuthorizationReqType *authorizationReq) {
if(authorizationReq->Id_isUsed) {
printf(" 🆔 ID: %.*s\n",
authorizationReq->Id.charactersLen,
authorizationReq->Id.characters);
}
if(authorizationReq->GenChallenge_isUsed) {
printf(" 🎲 GenChallenge: ");
for(int i = 0; i < authorizationReq->GenChallenge.bytesLen; i++) {
printf("%02X", authorizationReq->GenChallenge.bytes[i]);
}
printf("\n");
}
}
// Helper function to parse and print authorization response details
void print_authorization_res_details(struct iso1AuthorizationResType *authorizationRes) {
printf(" 📋 Response Code: %d\n", authorizationRes->ResponseCode);
printf(" ⚡ EVSEProcessing: %d\n", authorizationRes->EVSEProcessing);
}
// Helper function to parse and print charge parameter discovery request details
void print_charge_param_discovery_req_details(struct iso1ChargeParameterDiscoveryReqType *chargeParamReq) {
if(chargeParamReq->MaxEntriesSAScheduleTuple_isUsed) {
printf(" 📊 MaxEntriesSAScheduleTuple: %d\n", chargeParamReq->MaxEntriesSAScheduleTuple);
}
printf(" 🔌 RequestedEnergyTransferMode: %d\n", chargeParamReq->RequestedEnergyTransferMode);
if(chargeParamReq->DC_EVChargeParameter_isUsed) {
printf(" ⚡ DC_EVChargeParameter:\n");
printf(" 📋 DC_EVStatus:\n");
printf(" 🔋 EVReady: %s\n", chargeParamReq->DC_EVChargeParameter.DC_EVStatus.EVReady ? "true" : "false");
printf(" ⚡ EVErrorCode: %d\n", chargeParamReq->DC_EVChargeParameter.DC_EVStatus.EVErrorCode);
printf(" 🔌 EVRESSSOC: %d%%\n", chargeParamReq->DC_EVChargeParameter.DC_EVStatus.EVRESSSOC);
printf(" 🔋 EVMaximumCurrentLimit:\n");
printf(" 📊 Multiplier: %d\n", chargeParamReq->DC_EVChargeParameter.EVMaximumCurrentLimit.Multiplier);
printf(" 🔢 Unit: %d\n", chargeParamReq->DC_EVChargeParameter.EVMaximumCurrentLimit.Unit);
printf(" 💯 Value: %d\n", chargeParamReq->DC_EVChargeParameter.EVMaximumCurrentLimit.Value);
printf(" ⚡ EVMaximumVoltageLimit:\n");
printf(" 📊 Multiplier: %d\n", chargeParamReq->DC_EVChargeParameter.EVMaximumVoltageLimit.Multiplier);
printf(" 🔢 Unit: %d\n", chargeParamReq->DC_EVChargeParameter.EVMaximumVoltageLimit.Unit);
printf(" 💯 Value: %d\n", chargeParamReq->DC_EVChargeParameter.EVMaximumVoltageLimit.Value);
if(chargeParamReq->DC_EVChargeParameter.EVMaximumPowerLimit_isUsed) {
printf(" 🔌 EVMaximumPowerLimit:\n");
printf(" 📊 Multiplier: %d\n", chargeParamReq->DC_EVChargeParameter.EVMaximumPowerLimit.Multiplier);
printf(" 🔢 Unit: %d\n", chargeParamReq->DC_EVChargeParameter.EVMaximumPowerLimit.Unit);
printf(" 💯 Value: %d\n", chargeParamReq->DC_EVChargeParameter.EVMaximumPowerLimit.Value);
}
if(chargeParamReq->DC_EVChargeParameter.EVEnergyCapacity_isUsed) {
printf(" 🔋 EVEnergyCapacity:\n");
printf(" 📊 Multiplier: %d\n", chargeParamReq->DC_EVChargeParameter.EVEnergyCapacity.Multiplier);
printf(" 🔢 Unit: %d\n", chargeParamReq->DC_EVChargeParameter.EVEnergyCapacity.Unit);
printf(" 💯 Value: %d\n", chargeParamReq->DC_EVChargeParameter.EVEnergyCapacity.Value);
}
if(chargeParamReq->DC_EVChargeParameter.EVEnergyRequest_isUsed) {
printf(" ⚡ EVEnergyRequest:\n");
printf(" 📊 Multiplier: %d\n", chargeParamReq->DC_EVChargeParameter.EVEnergyRequest.Multiplier);
printf(" 🔢 Unit: %d\n", chargeParamReq->DC_EVChargeParameter.EVEnergyRequest.Unit);
printf(" 💯 Value: %d\n", chargeParamReq->DC_EVChargeParameter.EVEnergyRequest.Value);
}
if(chargeParamReq->DC_EVChargeParameter.FullSOC_isUsed) {
printf(" 🔋 FullSOC: %d%%\n", chargeParamReq->DC_EVChargeParameter.FullSOC);
}
if(chargeParamReq->DC_EVChargeParameter.BulkSOC_isUsed) {
printf(" 📊 BulkSOC: %d%%\n", chargeParamReq->DC_EVChargeParameter.BulkSOC);
}
}
}
// Helper function to parse and print charge parameter discovery response details
void print_charge_param_discovery_res_details(struct iso1ChargeParameterDiscoveryResType *chargeParamRes) {
printf(" 📋 Response Code: %d\n", chargeParamRes->ResponseCode);
printf(" ⚡ EVSEProcessing: %d\n", chargeParamRes->EVSEProcessing);
if(chargeParamRes->SAScheduleList_isUsed) {
printf(" 📅 SASchedules:\n");
printf(" Schedule Entries: %d\n", chargeParamRes->SAScheduleList.SAScheduleTuple.arrayLen);
for(int i = 0; i < chargeParamRes->SAScheduleList.SAScheduleTuple.arrayLen; i++) {
printf(" Schedule %d:\n", i+1);
printf(" SAScheduleTupleID: %d\n", chargeParamRes->SAScheduleList.SAScheduleTuple.array[i].SAScheduleTupleID);
if(chargeParamRes->SAScheduleList.SAScheduleTuple.array[i].PMaxSchedule.PMaxScheduleEntry.arrayLen > 0) {
printf(" PMaxScheduleEntries: %d\n",
chargeParamRes->SAScheduleList.SAScheduleTuple.array[i].PMaxSchedule.PMaxScheduleEntry.arrayLen);
}
}
}
if(chargeParamRes->DC_EVSEChargeParameter_isUsed) {
printf(" 🔌 DC_EVSEChargeParameter:\n");
printf(" 📊 DC_EVSEStatus:\n");
printf(" 🔌 EVSEIsolationStatus: %d\n", chargeParamRes->DC_EVSEChargeParameter.DC_EVSEStatus.EVSEIsolationStatus);
printf(" ⚡ EVSEStatusCode: %d\n", chargeParamRes->DC_EVSEChargeParameter.DC_EVSEStatus.EVSEStatusCode);
printf(" ⚡ EVSEMaximumCurrentLimit:\n");
printf(" 📊 Multiplier: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEMaximumCurrentLimit.Multiplier);
printf(" 🔢 Unit: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEMaximumCurrentLimit.Unit);
printf(" 💯 Value: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEMaximumCurrentLimit.Value);
printf(" 🔋 EVSEMaximumVoltageLimit:\n");
printf(" 📊 Multiplier: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEMaximumVoltageLimit.Multiplier);
printf(" 🔢 Unit: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEMaximumVoltageLimit.Unit);
printf(" 💯 Value: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEMaximumVoltageLimit.Value);
printf(" 🔌 EVSEMaximumPowerLimit:\n");
printf(" 📊 Multiplier: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEMaximumPowerLimit.Multiplier);
printf(" 🔢 Unit: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEMaximumPowerLimit.Unit);
printf(" 💯 Value: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEMaximumPowerLimit.Value);
printf(" ⚡ EVSEMinimumCurrentLimit:\n");
printf(" 📊 Multiplier: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEMinimumCurrentLimit.Multiplier);
printf(" 🔢 Unit: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEMinimumCurrentLimit.Unit);
printf(" 💯 Value: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEMinimumCurrentLimit.Value);
printf(" 🔋 EVSEMinimumVoltageLimit:\n");
printf(" 📊 Multiplier: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEMinimumVoltageLimit.Multiplier);
printf(" 🔢 Unit: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEMinimumVoltageLimit.Unit);
printf(" 💯 Value: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEMinimumVoltageLimit.Value);
if(chargeParamRes->DC_EVSEChargeParameter.EVSECurrentRegulationTolerance_isUsed) {
printf(" 📊 EVSECurrentRegulationTolerance:\n");
printf(" 📊 Multiplier: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSECurrentRegulationTolerance.Multiplier);
printf(" 🔢 Unit: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSECurrentRegulationTolerance.Unit);
printf(" 💯 Value: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSECurrentRegulationTolerance.Value);
}
printf(" ⚡ EVSEPeakCurrentRipple:\n");
printf(" 📊 Multiplier: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEPeakCurrentRipple.Multiplier);
printf(" 🔢 Unit: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEPeakCurrentRipple.Unit);
printf(" 💯 Value: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEPeakCurrentRipple.Value);
if(chargeParamRes->DC_EVSEChargeParameter.EVSEEnergyToBeDelivered_isUsed) {
printf(" 🔋 EVSEEnergyToBeDelivered:\n");
printf(" 📊 Multiplier: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEEnergyToBeDelivered.Multiplier);
printf(" 🔢 Unit: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEEnergyToBeDelivered.Unit);
printf(" 💯 Value: %d\n", chargeParamRes->DC_EVSEChargeParameter.EVSEEnergyToBeDelivered.Value);
}
}
}
int main(int argc, char *argv[]) {
int xml_mode = 0;
int encode_mode = 0;