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:
@@ -46,6 +46,16 @@ int EXI_DEBUG_MODE = 0;
|
||||
#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) {
|
||||
@@ -1138,13 +1148,252 @@ void print_iso1_message(struct iso1EXIDocument* doc) {
|
||||
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 {
|
||||
printf("Message Type: Other message type (not fully supported)\n");
|
||||
printf("Message Type: Other message type (not implemented)\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[]) {
|
||||
DEBUG_PRINTF(("DEBUG: argc=%d\n", argc));
|
||||
int xml_mode = 0;
|
||||
|
||||
Reference in New Issue
Block a user