feat: Port Phase 2 Session & Service Management to VC2022

Ported all Phase 2 message types from C implementation to VC2022:
- SessionSetupReq/Res with EVCCID and EVSEID handling
- ServiceDiscoveryReq/Res with payment options and services
- AuthorizationReq/Res with ID and challenge processing
- ChargeParameterDiscoveryReq/Res with DC parameters

Maintains VC2022 coding style (no emoji indicators) while providing
comprehensive parameter parsing and display for all message types
including complex nested structures and optional fields.

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

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

View File

@@ -46,6 +46,16 @@ int EXI_DEBUG_MODE = 0;
#define V2G_PAYLOAD_ISO2 0x8002 // ISO 15118-20 payload type #define V2G_PAYLOAD_ISO2 0x8002 // ISO 15118-20 payload type
#define EXI_START_PATTERN 0x8098 // EXI document start pattern #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 // 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) {
@@ -1138,13 +1148,252 @@ void print_iso1_message(struct iso1EXIDocument* doc) {
printf(" Value: %d\n", doc->V2G_Message.Body.CurrentDemandReq.RemainingTimeToBulkSoC.Value); printf(" Value: %d\n", doc->V2G_Message.Body.CurrentDemandReq.RemainingTimeToBulkSoC.Value);
} }
} }
// Phase 2: Session & Service Management Messages
else if (doc->V2G_Message.Body.SessionSetupReq_isUsed) {
printf("Message Type: SessionSetupReq\n");
print_session_setup_req_details(&doc->V2G_Message.Body.SessionSetupReq);
}
else if (doc->V2G_Message.Body.SessionSetupRes_isUsed) {
printf("Message Type: SessionSetupRes\n");
print_session_setup_res_details(&doc->V2G_Message.Body.SessionSetupRes);
}
else if (doc->V2G_Message.Body.ServiceDiscoveryReq_isUsed) {
printf("Message Type: ServiceDiscoveryReq\n");
print_service_discovery_req_details(&doc->V2G_Message.Body.ServiceDiscoveryReq);
}
else if (doc->V2G_Message.Body.ServiceDiscoveryRes_isUsed) {
printf("Message Type: ServiceDiscoveryRes\n");
print_service_discovery_res_details(&doc->V2G_Message.Body.ServiceDiscoveryRes);
}
else if (doc->V2G_Message.Body.AuthorizationReq_isUsed) {
printf("Message Type: AuthorizationReq\n");
print_authorization_req_details(&doc->V2G_Message.Body.AuthorizationReq);
}
else if (doc->V2G_Message.Body.AuthorizationRes_isUsed) {
printf("Message Type: AuthorizationRes\n");
print_authorization_res_details(&doc->V2G_Message.Body.AuthorizationRes);
}
else if (doc->V2G_Message.Body.ChargeParameterDiscoveryReq_isUsed) {
printf("Message Type: ChargeParameterDiscoveryReq\n");
print_charge_param_discovery_req_details(&doc->V2G_Message.Body.ChargeParameterDiscoveryReq);
}
else if (doc->V2G_Message.Body.ChargeParameterDiscoveryRes_isUsed) {
printf("Message Type: ChargeParameterDiscoveryRes\n");
print_charge_param_discovery_res_details(&doc->V2G_Message.Body.ChargeParameterDiscoveryRes);
}
else { else {
printf("Message Type: Other message type (not fully supported)\n"); printf("Message Type: Other message type (not implemented)\n");
} }
} }
printf("\n"); printf("\n");
} }
// Phase 2 Session & Service Management helper functions
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");
}
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);
}
}
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);
}
}
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);
}
}
}
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");
}
}
void print_authorization_res_details(struct iso1AuthorizationResType *authorizationRes) {
printf(" Response Code: %d\n", authorizationRes->ResponseCode);
printf(" EVSEProcessing: %d\n", authorizationRes->EVSEProcessing);
}
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);
}
}
}
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(" SAScheduleList:\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 main(int argc, char *argv[]) {
DEBUG_PRINTF(("DEBUG: argc=%d\n", argc)); DEBUG_PRINTF(("DEBUG: argc=%d\n", argc));
int xml_mode = 0; int xml_mode = 0;