diff --git a/configurations/pdr/com.amd.Hardware.Chassis.Model.sp7/amd_soc_pdr.json b/configurations/pdr/com.amd.Hardware.Chassis.Model.sp7/amd_soc_pdr.json new file mode 100644 index 0000000000..ea44abf46d --- /dev/null +++ b/configurations/pdr/com.amd.Hardware.Chassis.Model.sp7/amd_soc_pdr.json @@ -0,0 +1,96 @@ +[ +{ + "recordHandle": 10, + "PDRHeaderVersion": 1, + "PDRType": 1, + "recordChangeNumber": 0, + "dataLength": 9, + "PLDMTerminusHandle": 0, + "validity": 1, + "TID": 1, + "containerID": 0, + "terminusLocatorType": 1, + "terminusLocatorValueSize": 1, + "EID": 9 +} +,{ + "recordHandle": 20, + "PDRHeaderVersion": 1, + "PDRType": 9, + "recordChangeNumber": 0, + "dataLength": 60, + "PLDMTerminusHandler": 0, + "effecterID": 1, + "entityType": 33, + "entityInstanceNumber": 1, + "containerID": 0, + "effecterSemanticID": 0, + "effecterInit": 1, + "effecterAuxiliaryNamesPDR": false, + "baseUnit": 21, + "unitModifier": 0, + "rateUnit": 0, + "baseOEMUnitHandle": 0, + "auxUnit": 0, + "auxUnitModifier": 0, + "auxRateUnit": 0, + "auxOEMUnitHandle": 0, + "isLinear": true, + "effecterDataSize": 2, + "resolution": 1.0, + "offset": 0.0, + "accuracy": 0, + "plusTolerance": 0, + "minusTolerance": 0, + "stateTransitionInterval": 0.0, + "transitionInterval": 0.0, + "maxSettable": 255, + "minSettable": 0, + "rangeFieldFormat": 0, + "rangeFieldSupport": 0, + "nominalValue": 0, + "normalMax": 0, + "normalMin": 0, + "ratedMax": 0, + "ratedMin": 0 +} +,{ + "recordHandle": 200, + "PDRHeaderVersion": 1, + "PDRType": 16, + "recordChangeNumber": 0, + "dataLength": 20, + "EntityType": 1, + "EntityInstanceNumber": 1, + "EntityContainerID": 0, + "SharedNameCount": 0, + "NameStringCount": 1, + "Names": [ + ["en", "pwmw"] + ] +} +,{ + "recordHandle": 2000, + "PDRHeaderVersion": 1, + "PDRType": 21, + "recordChangeNumber": 0, + "dataLength": 41 , + "PLDMTerminusHandle": 0, + "sensorID": 1, + "entityType": 135, + "entityInstanceNumber": 0, + "containerID": 0, + "sensorNameStringByteLength": 6, + "baseUnit": 7, + "unitModifier": -3, + "occuranceRate": 2, + "rangeFieldSupport": 0, + "warningHigh": 0, + "warningLow": 0, + "criticalHigh": 0, + "criticalLow": 0, + "fatalHigh": 0, + "fatalLow": 0, + "sensorNameString": "PkgPwr" +} +] diff --git a/platform-mc/platform_manager.cpp b/platform-mc/platform_manager.cpp index 2d070b52a1..eaec74dbba 100644 --- a/platform-mc/platform_manager.cpp +++ b/platform-mc/platform_manager.cpp @@ -7,6 +7,7 @@ #include #include +#include PHOSPHOR_LOG2_USING; @@ -15,6 +16,686 @@ namespace pldm namespace platform_mc { +#define EXTRACT_FIELD_FROM_JSON(jRecord, jField, structMember )\ + if (jRecord.contains(jField)) \ + structMember = jRecord[jField]; \ + else \ + std::cout << jRecord << "======= NOT FOUND.\n"; \ + std::cout << jField << ": " << std::hex << (unsigned) structMember << "(" << sizeof(structMember) << ")\n"; + +void pdrFromJson(auto& record, pldm_pdr_hdr& hdr) +{ + EXTRACT_FIELD_FROM_JSON(record, "recordHandle", hdr.record_handle); + std::cout << "pdrFromJson(): hdr.record_handle = " << hdr.record_handle << "\n"; + EXTRACT_FIELD_FROM_JSON(record, "PDRHeaderVersion", hdr.version); + std::cout << "pdrFromJson(): hdr.version = " << hdr.version << "\n"; + EXTRACT_FIELD_FROM_JSON(record, "PDRType", hdr.type); + std::cout << "pdrFromJson(): hdr.type = " << hdr.type << "\n"; + EXTRACT_FIELD_FROM_JSON(record, "recordChangeNumber", hdr.record_change_num); + EXTRACT_FIELD_FROM_JSON(record, "dataLength", hdr.length); + std::cout << "pdrFromJson(): hdr.dataLength = " << hdr.length << "\n"; +} +void pdrFromJson(auto& record, pldm_value_pdr_hdr& hdr) +{ + EXTRACT_FIELD_FROM_JSON(record, "recordHandle", hdr.record_handle); + EXTRACT_FIELD_FROM_JSON(record, "PDRHeaderVersion", hdr.version); + EXTRACT_FIELD_FROM_JSON(record, "PDRType", hdr.type); + EXTRACT_FIELD_FROM_JSON(record, "recordChangeNumber", hdr.record_change_num); + EXTRACT_FIELD_FROM_JSON(record, "dataLength", hdr.length); +} + +void pdrFromJson(auto& record, pldm_terminus_locator_pdr& pdr) +{ + pdrFromJson(record, pdr.hdr); + EXTRACT_FIELD_FROM_JSON(record, + "PLDMTerminusHandle", pdr.terminus_handle); + EXTRACT_FIELD_FROM_JSON(record, "validity", pdr.validity); + EXTRACT_FIELD_FROM_JSON(record, "TID", pdr.tid); + EXTRACT_FIELD_FROM_JSON(record, "containerID", pdr.container_id); + EXTRACT_FIELD_FROM_JSON(record, + "terminusLocatorType", pdr.terminus_locator_type); + EXTRACT_FIELD_FROM_JSON(record, + "terminusLocatorValueSize", pdr.terminus_locator_value_size); + EXTRACT_FIELD_FROM_JSON(record, "EID", pdr.terminus_locator_value[0]); +} + +void pdrPossibleStatesFromJson(auto& record, uint32_t i, std::vector& pdrBytes) +{ + auto stateSetId = "stateSetID["+std::to_string(i)+"]"; + if (record.contains(stateSetId)) + { + uint16_t state_set_id = record[stateSetId]; + pdrBytes.insert(pdrBytes.end(), (uint8_t)(state_set_id & 0xFF)); + pdrBytes.insert(pdrBytes.end(), (uint8_t)((state_set_id & 0xFF00) >> 8)); + } + + auto stateSize = "possibleStatesSize["+std::to_string(i)+"]"; + if (record.contains(stateSize)) + { + uint8_t possible_states_size = (uint8_t)record[stateSize]; + pdrBytes.insert(pdrBytes.end(), &possible_states_size, + &possible_states_size + sizeof(possible_states_size)); + } + + auto states = "possibleStates["+std::to_string(i)+"]"; + if (record.contains(states)) + { + for(uint8_t state: record[states]) + pdrBytes.insert(pdrBytes.end(), state); + } +} + +void pdrFromJson(auto& record, pldm_state_sensor_pdr& pdr, + std::vector& pdrBytes) +{ + pdrFromJson(record, pdr.hdr); + EXTRACT_FIELD_FROM_JSON(record, + "PLDMTerminusHandle", pdr.terminus_handle); + EXTRACT_FIELD_FROM_JSON(record, "sensorID", pdr.sensor_id); + EXTRACT_FIELD_FROM_JSON(record, "entityType", pdr.entity_type); + EXTRACT_FIELD_FROM_JSON(record, "entityInstanceNumber", + pdr.entity_instance); + EXTRACT_FIELD_FROM_JSON(record, "containerID", pdr.container_id); + EXTRACT_FIELD_FROM_JSON(record, "sensorInit", pdr.sensor_init); + EXTRACT_FIELD_FROM_JSON(record, "sensorAuxiliaryNamesPDR", + pdr.sensor_auxiliary_names_pdr); + EXTRACT_FIELD_FROM_JSON(record, "compositeSensorCount", + pdr.composite_sensor_count); + pdrBytes.resize(sizeof(pldm_state_sensor_pdr)-1); + std::memcpy(pdrBytes.data(), &pdr, sizeof(pldm_state_sensor_pdr)-1); + + // retrieve possible states + for(uint32_t i=0; i& pdrBytes) +{ + switch(sDataSize) + { + case 5: + case 4: + pdrBytes.insert(pdrBytes.end(), + (uint8_t)(field & 0xFF)); + pdrBytes.insert(pdrBytes.end(), (uint8_t)((field & 0xFF00) >> 8)); + pdrBytes.insert(pdrBytes.end(), + (uint8_t)((field & 0xFF0000) >> 16)); + pdrBytes.insert(pdrBytes.end(), + (uint8_t)((field & 0xFF000000) >> 24)); + break; + case 3: + case 2: + pdrBytes.insert(pdrBytes.end(), (uint8_t)(field & 0xFF)); + pdrBytes.insert(pdrBytes.end(), (uint8_t)((field & 0xFF00) >> 8)); + break; + + case 1: + case 0: + pdrBytes.insert(pdrBytes.end(), (uint8_t)(field & 0xFF)); + break; + default: + break; + } +} + +void rangeFieldFromJson(uint8_t rangeFieldFormat, + uint32_t field, + std::vector& pdrBytes) +{ + switch(rangeFieldFormat) + { + case PLDM_RANGE_FIELD_FORMAT_UINT32: + case PLDM_RANGE_FIELD_FORMAT_SINT32: + case PLDM_RANGE_FIELD_FORMAT_REAL32: + pdrBytes.insert(pdrBytes.end(), (uint8_t)(field & 0xFF)); + pdrBytes.insert(pdrBytes.end(), (uint8_t)((field & 0xFF00) >> 8)); + pdrBytes.insert(pdrBytes.end(), + (uint8_t)((field & 0xFF0000) >> 16)); + pdrBytes.insert(pdrBytes.end(), + (uint8_t)((field & 0xFF000000) >> 24)); + break; + case PLDM_RANGE_FIELD_FORMAT_UINT16: + case PLDM_RANGE_FIELD_FORMAT_SINT16: + pdrBytes.insert(pdrBytes.end(), (uint8_t)(field & 0xFF)); + pdrBytes.insert(pdrBytes.end(), (uint8_t)((field & 0xFF00) >> 8)); + break; + + case PLDM_RANGE_FIELD_FORMAT_UINT8: + case PLDM_RANGE_FIELD_FORMAT_SINT8: + pdrBytes.insert(pdrBytes.end(), (uint8_t)(field & 0xFF)); + break; + default: + break; + } +} + +void numericPdrFromJson(auto& record, std::vector& pdrBytes) +{ + pldm_numeric_sensor_value_pdr pdr = {}; + + pdrBytes.clear(); + + pdrFromJson(record, pdr.hdr); + pdrBytes.insert(pdrBytes.begin(), reinterpret_cast(&pdr.hdr.record_handle), + reinterpret_cast(&pdr.hdr.record_handle) + + sizeof(pdr.hdr.record_handle)); + pdrBytes.insert(pdrBytes.end(), (uint8_t)pdr.hdr.version); + pdrBytes.insert(pdrBytes.end(), (uint8_t)pdr.hdr.type); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.hdr.record_change_num), + reinterpret_cast(&pdr.hdr.record_change_num) + + sizeof(pdr.hdr.record_change_num)); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.hdr.length), + reinterpret_cast(&pdr.hdr.length) + + sizeof(pdr.hdr.length)); + EXTRACT_FIELD_FROM_JSON(record, + "PLDMTerminusHandle", pdr.terminus_handle); + EXTRACT_FIELD_FROM_JSON(record, "sensorID", pdr.sensor_id); + EXTRACT_FIELD_FROM_JSON(record, "entityType", pdr.entity_type); + EXTRACT_FIELD_FROM_JSON(record, "entityInstanceNumber", + pdr.entity_instance); + EXTRACT_FIELD_FROM_JSON(record, "containerID", pdr.container_id); + EXTRACT_FIELD_FROM_JSON(record, "sensorInit", pdr.sensor_init); + EXTRACT_FIELD_FROM_JSON(record, "sensorAuxiliaryNamesPDR", + pdr.sensor_auxiliary_names_pdr); + EXTRACT_FIELD_FROM_JSON(record, "baseUnit", pdr.base_unit); + EXTRACT_FIELD_FROM_JSON(record, "unitModifier", pdr.unit_modifier); + EXTRACT_FIELD_FROM_JSON(record, "rateUnit", pdr.rate_unit); + EXTRACT_FIELD_FROM_JSON(record, "baseOEMUnitHandle", + pdr.base_oem_unit_handle); + EXTRACT_FIELD_FROM_JSON(record, "auxUnit", pdr.aux_unit); + EXTRACT_FIELD_FROM_JSON(record, "auxUnitModifier", pdr.aux_unit_modifier); + EXTRACT_FIELD_FROM_JSON(record, "auxrateUnit", pdr.aux_rate_unit); + EXTRACT_FIELD_FROM_JSON(record, "rel", pdr.rel); + EXTRACT_FIELD_FROM_JSON(record, "auxOEMUnitHandle", + pdr.aux_oem_unit_handle); + EXTRACT_FIELD_FROM_JSON(record, "isLinear", pdr.is_linear); + pdrBytes.insert(pdrBytes.end(), + reinterpret_cast(&pdr.terminus_handle), + reinterpret_cast(&pdr.terminus_handle) + + offsetof(pldm_numeric_sensor_value_pdr, sensor_data_size) - + offsetof(pldm_numeric_sensor_value_pdr, terminus_handle)); + + EXTRACT_FIELD_FROM_JSON(record, "sensorDataSize", pdr.sensor_data_size); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.sensor_data_size), + reinterpret_cast(&pdr.sensor_data_size) + + sizeof(pdr.sensor_data_size)); + + EXTRACT_FIELD_FROM_JSON(record, "resolution", pdr.resolution); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.resolution), + reinterpret_cast(&pdr.resolution) + + sizeof(pdr.resolution)); + EXTRACT_FIELD_FROM_JSON(record, "offset", pdr.offset); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.offset), + reinterpret_cast(&pdr.offset) + + sizeof(pdr.offset)); + EXTRACT_FIELD_FROM_JSON(record, "accuracy", pdr.accuracy); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.accuracy), + reinterpret_cast(&pdr.accuracy) + + sizeof(pdr.accuracy)); + EXTRACT_FIELD_FROM_JSON(record, "plusTolerance", pdr.plus_tolerance); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.plus_tolerance), + reinterpret_cast(&pdr.plus_tolerance) + + sizeof(pdr.plus_tolerance)); + EXTRACT_FIELD_FROM_JSON(record, "minusTolerance", pdr.minus_tolerance); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.minus_tolerance), + reinterpret_cast(&pdr.minus_tolerance) + + sizeof(pdr.minus_tolerance)); + + // hysteresis - depends on sensorDataSize + uint32_t hysteresis; + EXTRACT_FIELD_FROM_JSON(record, "hysteresis", hysteresis); + sensorDataSizeFromJson(pdr.sensor_data_size, hysteresis, pdrBytes); + + uint8_t supported_thresholds; + EXTRACT_FIELD_FROM_JSON(record, "supportedThresholds", + supported_thresholds); + pdrBytes.insert(pdrBytes.end(), supported_thresholds); + + uint8_t threshold_and_hysteresis_volatility; + EXTRACT_FIELD_FROM_JSON(record, "thresholAndHysteresisVolatility", + threshold_and_hysteresis_volatility); + pdrBytes.insert(pdrBytes.end(), threshold_and_hysteresis_volatility); + + real32_t interval; + EXTRACT_FIELD_FROM_JSON(record, "stateTransitionInterval", interval); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&interval), + reinterpret_cast(&interval) + sizeof(interval)); + + EXTRACT_FIELD_FROM_JSON(record, "updateInterval", interval); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&interval), + reinterpret_cast(&interval) + sizeof(interval)); + + // maxReadable - depends on sensorDataSize. + int32_t maxReadable; + EXTRACT_FIELD_FROM_JSON(record, "maxReadable", maxReadable); + sensorDataSizeFromJson(pdr.sensor_data_size, maxReadable, pdrBytes); + + // minReadable - depends on sensorDataSize. + int32_t minReadable; + EXTRACT_FIELD_FROM_JSON(record, "minReadable", minReadable); + sensorDataSizeFromJson(pdr.sensor_data_size, minReadable, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "rangeFieldFormat", pdr.range_field_format); + pdrBytes.insert(pdrBytes.end(), (uint8_t)pdr.range_field_format); + + uint8_t range_field_support; + EXTRACT_FIELD_FROM_JSON(record, "rangeFieldSupport", range_field_support); + pdrBytes.insert(pdrBytes.end(), range_field_support); + + // nominalValue - size of this field is given by the rangeFieldFormat field in this PDR. + uint32_t field; + EXTRACT_FIELD_FROM_JSON(record, "nominalValue", field); + rangeFieldFromJson(pdr.range_field_format, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "normalMax", field); + rangeFieldFromJson(pdr.range_field_format, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "normalMin", field); + rangeFieldFromJson(pdr.range_field_format, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "warningHigh", field); + rangeFieldFromJson(pdr.range_field_format, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "warningLow", field); + rangeFieldFromJson(pdr.range_field_format, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "criticalHigh", field); + rangeFieldFromJson(pdr.range_field_format, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "criticalLow", field); + rangeFieldFromJson(pdr.range_field_format, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "fatalHigh", field); + rangeFieldFromJson(pdr.range_field_format, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "fatalLow", field); + rangeFieldFromJson(pdr.range_field_format, field, pdrBytes); +} + +void compactNumericPdrFromJson(auto& record, std::vector& pdrBytes) +{ + pldm_compact_numeric_sensor_pdr pdr = {}; + std::string sensorName; + uint32_t field; + + pdrBytes.clear(); + + pdrFromJson(record, pdr.hdr); + pdrBytes.insert(pdrBytes.begin(), reinterpret_cast(&pdr.hdr.record_handle), + reinterpret_cast(&pdr.hdr.record_handle) + + sizeof(pdr.hdr.record_handle)); + pdrBytes.insert(pdrBytes.end(), (uint8_t)pdr.hdr.version); + pdrBytes.insert(pdrBytes.end(), (uint8_t)pdr.hdr.type); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.hdr.record_change_num), + reinterpret_cast(&pdr.hdr.record_change_num) + + sizeof(pdr.hdr.record_change_num)); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.hdr.length), + reinterpret_cast(&pdr.hdr.length) + + sizeof(pdr.hdr.length)); + + EXTRACT_FIELD_FROM_JSON(record, "PLDMTerminusHandle", pdr.terminus_handle); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.terminus_handle), + reinterpret_cast(&pdr.terminus_handle) + sizeof(pdr.terminus_handle)); + + EXTRACT_FIELD_FROM_JSON(record, "sensorID", pdr.sensor_id); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.sensor_id), + reinterpret_cast(&pdr.sensor_id) + sizeof(pdr.sensor_id)); + + EXTRACT_FIELD_FROM_JSON(record, "entityType", pdr.entity_type); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.entity_type), + reinterpret_cast(&pdr.entity_type) + sizeof(pdr.entity_type)); + + EXTRACT_FIELD_FROM_JSON(record, "entityInstanceNumber", pdr.entity_instance); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.entity_instance), + reinterpret_cast(&pdr.entity_instance) + sizeof(pdr.entity_instance)); + + EXTRACT_FIELD_FROM_JSON(record, "containerID", pdr.container_id); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.container_id), + reinterpret_cast(&pdr.container_id) + sizeof(pdr.container_id)); + + EXTRACT_FIELD_FROM_JSON(record, "sensorNameStringByteLength", pdr.sensor_name_length); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.sensor_name_length), + reinterpret_cast(&pdr.sensor_name_length) + sizeof(pdr.sensor_name_length)); + + EXTRACT_FIELD_FROM_JSON(record, "baseUnit", pdr.base_unit); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.base_unit), + reinterpret_cast(&pdr.base_unit) + sizeof(pdr.base_unit)); + + EXTRACT_FIELD_FROM_JSON(record, "unitModifier", pdr.unit_modifier); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.unit_modifier), + reinterpret_cast(&pdr.unit_modifier) + sizeof(pdr.unit_modifier)); + + EXTRACT_FIELD_FROM_JSON(record, "occuranceRate", pdr.occurrence_rate); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.occurrence_rate), + reinterpret_cast(&pdr.occurrence_rate) + sizeof(pdr.occurrence_rate)); + + EXTRACT_FIELD_FROM_JSON(record, "rangeFieldSupport", pdr.range_field_support.byte); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.range_field_support.byte), + reinterpret_cast(&pdr.range_field_support.byte) + sizeof(pdr.range_field_support.byte)); + + EXTRACT_FIELD_FROM_JSON(record, "warningHigh", field); + rangeFieldFromJson(PLDM_RANGE_FIELD_FORMAT_SINT32, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "warningLow", field); + rangeFieldFromJson(PLDM_RANGE_FIELD_FORMAT_SINT32, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "criticalHigh", field); + rangeFieldFromJson(PLDM_RANGE_FIELD_FORMAT_SINT32, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "criticalLow", field); + rangeFieldFromJson(PLDM_RANGE_FIELD_FORMAT_SINT32, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "fatalHigh", field); + rangeFieldFromJson(PLDM_RANGE_FIELD_FORMAT_SINT32, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "fatalLow", field); + rangeFieldFromJson(PLDM_RANGE_FIELD_FORMAT_SINT32, field, pdrBytes); + + sensorName = record.at("sensorNameString").template get(); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(sensorName.data()), + reinterpret_cast(sensorName.data()) + sensorName.size()); +} + +void entityAuxNamesPdrFromJson(auto& record, std::vector& pdrBytes) +{ + pldm_entity_auxiliary_names_pdr pdr = {}; + + pdrBytes.clear(); + + pdrFromJson(record, pdr.hdr); + pdrBytes.insert(pdrBytes.begin(), reinterpret_cast(&pdr.hdr.record_handle), + reinterpret_cast(&pdr.hdr.record_handle) + sizeof(pdr.hdr.record_handle)); + pdrBytes.insert(pdrBytes.end(), (uint8_t)pdr.hdr.version); + pdrBytes.insert(pdrBytes.end(), (uint8_t)pdr.hdr.type); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.hdr.record_change_num), + reinterpret_cast(&pdr.hdr.record_change_num) + sizeof(pdr.hdr.record_change_num)); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.hdr.length), + reinterpret_cast(&pdr.hdr.length) + sizeof(pdr.hdr.length)); + + EXTRACT_FIELD_FROM_JSON(record, "EntityType", pdr.container.entity_type); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.container.entity_type), + reinterpret_cast(&pdr.container.entity_type) + sizeof(pdr.container.entity_type)); + + EXTRACT_FIELD_FROM_JSON(record, "EntityInstanceNumber", pdr.container.entity_instance_num); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.container.entity_instance_num), + reinterpret_cast(&pdr.container.entity_instance_num) + sizeof(pdr.container.entity_instance_num)); + + EXTRACT_FIELD_FROM_JSON(record, "EntityContainerID", pdr.container.entity_container_id); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.container.entity_container_id), + reinterpret_cast(&pdr.container.entity_container_id) + sizeof(pdr.container.entity_container_id)); + + + EXTRACT_FIELD_FROM_JSON(record, "SharedNameCount", pdr.shared_name_count); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.shared_name_count), + reinterpret_cast(&pdr.shared_name_count) + sizeof(pdr.shared_name_count)); + + EXTRACT_FIELD_FROM_JSON(record, "NameStringCount", pdr.name_string_count); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.name_string_count), + reinterpret_cast(&pdr.name_string_count) + sizeof(pdr.name_string_count)); + + std::string langTag = record["Names"][0][0].template get(); + pdrBytes.insert(pdrBytes.end(), langTag.begin(), langTag.end()); + pdrBytes.push_back('\0'); + + std::string nameTag = record["Names"][0][1].template get(); + for (char c : nameTag) { + uint16_t beChar = htons(static_cast(c)); + uint8_t bytes[2]; + std::memcpy(bytes, &beChar, 2); + pdrBytes.push_back(bytes[0]); + pdrBytes.push_back(bytes[1]); + } + pdrBytes.push_back(0x00); + pdrBytes.push_back(0x00); +} + +void numericEffecterValuePdrFromJson(auto& record, std::vector& pdrBytes) +{ + pldm_numeric_effecter_value_pdr pdr{}; + uint64_t field; + + pdrBytes.clear(); + + pdrFromJson(record, pdr.hdr); + pdrBytes.insert(pdrBytes.begin(), reinterpret_cast(&pdr.hdr.record_handle), + reinterpret_cast(&pdr.hdr.record_handle) + sizeof(pdr.hdr.record_handle)); + pdrBytes.insert(pdrBytes.end(), (uint8_t)pdr.hdr.version); + pdrBytes.insert(pdrBytes.end(), (uint8_t)pdr.hdr.type); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.hdr.record_change_num), + reinterpret_cast(&pdr.hdr.record_change_num) + sizeof(pdr.hdr.record_change_num)); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.hdr.length), + reinterpret_cast(&pdr.hdr.length) + sizeof(pdr.hdr.length)); + + EXTRACT_FIELD_FROM_JSON(record, "PLDMTerminusHandler", pdr.terminus_handle); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.terminus_handle), + reinterpret_cast(&pdr.terminus_handle) + sizeof(pdr.terminus_handle)); + + EXTRACT_FIELD_FROM_JSON(record, "effecterID", pdr.effecter_id); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.effecter_id), + reinterpret_cast(&pdr.effecter_id) + sizeof(pdr.effecter_id)); + + EXTRACT_FIELD_FROM_JSON(record, "entityType", pdr.entity_type); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.entity_type), + reinterpret_cast(&pdr.entity_type) + sizeof(pdr.entity_type)); + + EXTRACT_FIELD_FROM_JSON(record, "entityInstanceNumber", pdr.entity_instance); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.entity_instance), + reinterpret_cast(&pdr.entity_instance) + sizeof(pdr.entity_instance)); + + EXTRACT_FIELD_FROM_JSON(record, "containerID", pdr.container_id); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.container_id), + reinterpret_cast(&pdr.container_id) + sizeof(pdr.container_id)); + + EXTRACT_FIELD_FROM_JSON(record, "effecterSemanticID", pdr.effecter_semantic_id); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.effecter_semantic_id), + reinterpret_cast(&pdr.effecter_semantic_id) + sizeof(pdr.effecter_semantic_id)); + + EXTRACT_FIELD_FROM_JSON(record, "effecterInit", pdr.effecter_init); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.effecter_init), + reinterpret_cast(&pdr.effecter_init) + sizeof(pdr.effecter_init)); + + EXTRACT_FIELD_FROM_JSON(record, "effecterAuxiliaryNamesPDR", pdr.effecter_auxiliary_names); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.effecter_auxiliary_names), + reinterpret_cast(&pdr.effecter_auxiliary_names) + sizeof(pdr.effecter_auxiliary_names)); + + EXTRACT_FIELD_FROM_JSON(record, "baseUnit", pdr.base_unit); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.base_unit), + reinterpret_cast(&pdr.base_unit) + sizeof(pdr.base_unit)); + + EXTRACT_FIELD_FROM_JSON(record, "unitModifier", pdr.unit_modifier); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.unit_modifier), + reinterpret_cast(&pdr.unit_modifier) + sizeof(pdr.unit_modifier)); + + EXTRACT_FIELD_FROM_JSON(record, "rateUnit", pdr.rate_unit); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.rate_unit), + reinterpret_cast(&pdr.rate_unit) + sizeof(pdr.rate_unit)); + + EXTRACT_FIELD_FROM_JSON(record, "baseOEMUnitHandle", pdr.base_oem_unit_handle); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.base_oem_unit_handle), + reinterpret_cast(&pdr.base_oem_unit_handle) + sizeof(pdr.base_oem_unit_handle)); + + EXTRACT_FIELD_FROM_JSON(record, "auxUnit", pdr.aux_unit); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.aux_unit), + reinterpret_cast(&pdr.aux_unit) + sizeof(pdr.aux_unit)); + + EXTRACT_FIELD_FROM_JSON(record, "auxUnitModifier", pdr.aux_unit_modifier); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.aux_unit_modifier), + reinterpret_cast(&pdr.aux_unit_modifier) + sizeof(pdr.aux_unit_modifier)); + + EXTRACT_FIELD_FROM_JSON(record, "auxRateUnit", pdr.aux_rate_unit); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.aux_rate_unit), + reinterpret_cast(&pdr.aux_rate_unit) + sizeof(pdr.aux_rate_unit)); + + EXTRACT_FIELD_FROM_JSON(record, "auxOEMUnitHandle", pdr.aux_oem_unit_handle); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.aux_oem_unit_handle), + reinterpret_cast(&pdr.aux_oem_unit_handle) + sizeof(pdr.aux_oem_unit_handle)); + + EXTRACT_FIELD_FROM_JSON(record, "isLinear", pdr.is_linear); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.is_linear), + reinterpret_cast(&pdr.is_linear) + sizeof(pdr.is_linear)); + + EXTRACT_FIELD_FROM_JSON(record, "effecterDataSize", pdr.effecter_data_size); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.effecter_data_size), + reinterpret_cast(&pdr.effecter_data_size) + sizeof(pdr.effecter_data_size)); + + EXTRACT_FIELD_FROM_JSON(record, "resolution", pdr.resolution); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.resolution), + reinterpret_cast(&pdr.resolution) + sizeof(pdr.resolution)); + + EXTRACT_FIELD_FROM_JSON(record, "offset", pdr.offset); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.offset), + reinterpret_cast(&pdr.offset) + sizeof(pdr.offset)); + + EXTRACT_FIELD_FROM_JSON(record, "accuracy", pdr.accuracy); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.accuracy), + reinterpret_cast(&pdr.accuracy) + sizeof(pdr.accuracy)); + + EXTRACT_FIELD_FROM_JSON(record, "plusTolerance", pdr.plus_tolerance); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.plus_tolerance), + reinterpret_cast(&pdr.plus_tolerance) + sizeof(pdr.plus_tolerance)); + + EXTRACT_FIELD_FROM_JSON(record, "minusTolerance", pdr.minus_tolerance); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.minus_tolerance), + reinterpret_cast(&pdr.minus_tolerance) + sizeof(pdr.minus_tolerance)); + + EXTRACT_FIELD_FROM_JSON(record, "stateTransitionInterval", pdr.state_transition_interval); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.state_transition_interval), + reinterpret_cast(&pdr.state_transition_interval) + sizeof(pdr.state_transition_interval)); + + EXTRACT_FIELD_FROM_JSON(record, "transitionInterval", pdr.transition_interval); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.transition_interval), + reinterpret_cast(&pdr.transition_interval) + sizeof(pdr.transition_interval)); + + EXTRACT_FIELD_FROM_JSON(record, "maxSettable", field); + rangeFieldFromJson(field, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "minSettable", field); + rangeFieldFromJson(field, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "rangeFieldFormat", pdr.range_field_format); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.range_field_format), + reinterpret_cast(&pdr.range_field_format) + sizeof(pdr.range_field_format)); + + pdr.range_field_support.byte = record.value("rangeFieldSupport", 0); + pdrBytes.insert(pdrBytes.end(), reinterpret_cast(&pdr.range_field_support.byte), + reinterpret_cast(&pdr.range_field_support.byte) + sizeof(pdr.range_field_support.byte)); + + EXTRACT_FIELD_FROM_JSON(record, "nominalValue", field); + rangeFieldFromJson(field, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "normalMax", field); + rangeFieldFromJson(field, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "normalMin", field); + rangeFieldFromJson(field, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "ratedMax", field); + rangeFieldFromJson(field, field, pdrBytes); + + EXTRACT_FIELD_FROM_JSON(record, "ratedMin", field); + rangeFieldFromJson(field, field, pdrBytes); +} + +exec::task PlatformManager::getPDRsFromJson(std::shared_ptr terminus) +{ + pldm_tid_t tid = terminus->getTid(); + + /* Setting default values when getPDRRepositoryInfo fails or does not + * support */ + uint8_t repositoryState = PLDM_AVAILABLE; + uint32_t recordCount = std::numeric_limits::max(); + uint32_t repositorySize = 0; + uint32_t largestRecordSize = std::numeric_limits::max(); + if (terminus->doesSupportCommand(PLDM_PLATFORM, + PLDM_GET_PDR_REPOSITORY_INFO)) + { + auto rc = co_await getPDRRepositoryInfo(tid, repositoryState, + recordCount, repositorySize, + largestRecordSize); + if (rc) + { + lg2::error( + "Failed to get PDR Repository Info for terminus with TID: {TID}, error: {ERROR}", + "TID", tid, "ERROR", rc); + } + else + { + recordCount = std::min(recordCount + 1, + std::numeric_limits::max()); + largestRecordSize = std::min(largestRecordSize + 1, + std::numeric_limits::max()); + } + } + + if (repositoryState != PLDM_AVAILABLE) + { + co_return PLDM_ERROR_NOT_READY; + } + + std::ifstream jsonFile("/usr/share/pldm/pdr/com.amd.Hardware.Chassis.Model.sp7/amd_soc_pdr.json"); + auto jData = nlohmann::ordered_json::parse(jsonFile, nullptr, false); + if (jData.is_discarded()) + { + lg2::error("Parsing json file failed. File path {FILE_PATH}", + "FILE_PATH", std::string("jsonFile")); + co_return PLDM_ERROR_NOT_READY; + } + for (const auto& jRecord: jData) + { + std::cout << "PDRType: " << jRecord["PDRType"] << std::endl; + int pdrType = jRecord["PDRType"]; + pldm_terminus_locator_pdr terminusLocPdr = {}; + pldm_state_sensor_pdr stateSensorPdr = {}; + std::vector pdrBytes; + switch (pdrType) + { + case PLDM_TERMINUS_LOCATOR_PDR: + pdrFromJson(jRecord, terminusLocPdr); + pdrBytes.resize(sizeof(pldm_terminus_locator_pdr)); + std::memcpy(pdrBytes.data(), + &terminusLocPdr, sizeof(pldm_terminus_locator_pdr)); + terminus->pdrs.push_back(pdrBytes); + break; + case PLDM_NUMERIC_SENSOR_PDR: + numericPdrFromJson(jRecord, pdrBytes); + terminus->pdrs.push_back(pdrBytes); + break; + case PLDM_STATE_SENSOR_PDR: + pdrFromJson(jRecord, stateSensorPdr, pdrBytes); + terminus->pdrs.push_back(pdrBytes); + break; + case PLDM_NUMERIC_EFFECTER_PDR: + pdrBytes.resize(sizeof(pldm_numeric_effecter_value_pdr)); + numericEffecterValuePdrFromJson(jRecord, pdrBytes); + terminus->pdrs.push_back(pdrBytes); + break; + case PLDM_ENTITY_AUXILIARY_NAMES_PDR: + pdrBytes.resize(sizeof(pldm_compact_numeric_sensor_pdr)); + entityAuxNamesPdrFromJson(jRecord, pdrBytes); + terminus->pdrs.push_back(pdrBytes); + break; + case PLDM_COMPACT_NUMERIC_SENSOR_PDR: + pdrBytes.resize(sizeof(pldm_compact_numeric_sensor_pdr)); + compactNumericPdrFromJson(jRecord, pdrBytes); + terminus->pdrs.push_back(pdrBytes); + break; + default: + break; + } + std::cout<<"pdrBytes.size() = " << pdrBytes.size() << "\n"; + for (size_t i = 0; i < pdrBytes.size(); ++i) { + std::cout << std::setw(2) << std::setfill('0') << std::hex << unsigned(pdrBytes[i]) << " "; + } + std::cout << "\n"; + } + + co_return PLDM_SUCCESS; +} + exec::task PlatformManager::initTerminus() { for (auto& [tid, terminus] : termini) @@ -70,6 +751,20 @@ exec::task PlatformManager::initTerminus() terminus->parseTerminusPDRs(); } + else + { + // read from JSON file + auto rc = co_await getPDRsFromJson(terminus); + if (rc) + { + lg2::error( + "Failed to fetch PDRs for terminus with TID from JSON: {TID}, error: {ERROR}", + "TID", tid, "ERROR", rc); + continue; // Continue to next terminus + } + + terminus->parseTerminusPDRs(); + } /** * Need terminus name from PDRs before updating Inventory object with diff --git a/platform-mc/platform_manager.hpp b/platform-mc/platform_manager.hpp index 1a9a5f143a..5252738a38 100644 --- a/platform-mc/platform_manager.hpp +++ b/platform-mc/platform_manager.hpp @@ -56,6 +56,8 @@ class PlatformManager */ exec::task getPDRs(std::shared_ptr terminus); + exec::task getPDRsFromJson(std::shared_ptr terminus); + /** @brief Fetch PDR from terminus * * @param[in] tid - Destination TID diff --git a/platform-mc/terminus.cpp b/platform-mc/terminus.cpp index 4015bfef11..36d3dc4002 100644 --- a/platform-mc/terminus.cpp +++ b/platform-mc/terminus.cpp @@ -549,6 +549,7 @@ std::shared_ptr parsedPdr->critical_low = pdr->critical_low; parsedPdr->fatal_high = pdr->fatal_high; parsedPdr->fatal_low = pdr->fatal_low; + std::memcpy(parsedPdr->sensor_name, pdr->sensor_name, sizeof(parsedPdr->sensor_name)); return parsedPdr; }