pldm: Optimized parsing of PDR JSON files
Move the generateStateEffecterRepo method of parse JSON to
pdr_state_effecter.hpp.
Tested with JSON files:
https://gist.github.com/lxwinspur/2c3fd68cdb35e06480c4a5f7890e3a06#file-effecter_pdr-json.
pldmtool platform GetPDR -d 1
Encode request successfully
Request Message:
08 01 80 02 51 01 00 00 00 00 00 00 00 01 80 00 00 00
Success in creating the socket : RC = 3
Success in connecting to socket : RC = 0
Success in sending message type as pldm to mctp : RC = 0
Write to socket successful : RC = 18
Total length:18
Loopback response message:
08 01 80 02 51 01 00 00 00 00 00 00 00 01 80 00 00 00
On first recv(),response == request : RC = 0
Total length: 46
Shutdown Socket successful : RC = 0
Response Message:
08 01 00 02 51 00 02 00 00 00 00 00 00 00 01 1d 00 01 00 00 00 01 0b 00 00 13 00 00 00 01 00 21 00 00 00 00 00 00 00 00 00 01 c4 00 01 06
Parsed Response Msg:
nextRecordHandle: 2
responseCount: 29
recordHandle: 1
PDRHeaderVersion: 1
PDRType: 11
recordChangeNumber: 0
dataLength: 19
PLDMTerminusHandle: 0
effecterID: 1
entityType: 33
entityInstanceNumber: 0
containerID: 0
effecterSemanticID: 0
effecterInit: 0
effecterDescriptionPDR: false
compositeEffecterCount: 1
stateSetID: 196
possibleStatesSize: 1
possibleStates: 6
Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I8428ed042fb0a90ecc448073f059f66360066306
diff --git a/libpldmresponder/platform.cpp b/libpldmresponder/platform.cpp
index 45bd041..6aef73d 100644
--- a/libpldmresponder/platform.cpp
+++ b/libpldmresponder/platform.cpp
@@ -1,6 +1,7 @@
#include "platform.hpp"
+#include "pdr_state_effecter.hpp"
#include "utils.hpp"
namespace pldm
@@ -15,130 +16,32 @@
static const Json empty{};
-void Handler::addDbusObjMaps(uint16_t effecterId,
- std::tuple<DbusMappings, DbusValMaps> dbusObj)
+void Handler::addDbusObjMaps(
+ uint16_t effecterId,
+ std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> dbusObj)
{
dbusObjMaps.emplace(effecterId, dbusObj);
}
-const std::tuple<DbusMappings, DbusValMaps>&
+const std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>&
Handler::getDbusObjMaps(uint16_t effecterId) const
{
return dbusObjMaps.at(effecterId);
}
-void Handler::generateStateEffecterRepo(const Json& json, Repo& repo)
-{
- static const std::vector<Json> emptyList{};
- auto entries = json.value("entries", emptyList);
- for (const auto& e : entries)
- {
- size_t pdrSize = 0;
- auto effecters = e.value("effecters", emptyList);
- for (const auto& effecter : effecters)
- {
- auto set = effecter.value("set", empty);
- auto statesSize = set.value("size", 0);
- if (!statesSize)
- {
- std::cerr << "Malformed PDR JSON return "
- "pdrEntry;- no state set "
- "info, TYPE="
- << PLDM_STATE_EFFECTER_PDR << "\n";
- throw InternalFailure();
- }
- pdrSize += sizeof(state_effecter_possible_states) -
- sizeof(bitfield8_t) + (sizeof(bitfield8_t) * statesSize);
- }
- pdrSize += sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t);
-
- std::vector<uint8_t> entry{};
- entry.resize(pdrSize);
-
- pldm_state_effecter_pdr* pdr =
- reinterpret_cast<pldm_state_effecter_pdr*>(entry.data());
- pdr->hdr.record_handle = 0;
- pdr->hdr.version = 1;
- pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
- pdr->hdr.record_change_num = 0;
- pdr->hdr.length = pdrSize - sizeof(pldm_pdr_hdr);
-
- pdr->terminus_handle = 0;
- pdr->effecter_id = this->getNextEffecterId();
- pdr->entity_type = e.value("type", 0);
- pdr->entity_instance = e.value("instance", 0);
- pdr->container_id = e.value("container", 0);
- pdr->effecter_semantic_id = 0;
- pdr->effecter_init = PLDM_NO_INIT;
- pdr->has_description_pdr = false;
- pdr->composite_effecter_count = effecters.size();
-
- DbusMappings dbusMappings{};
- DbusValMaps dbusValMaps{};
- uint8_t* start =
- entry.data() + sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t);
- for (const auto& effecter : effecters)
- {
- auto set = effecter.value("set", empty);
- state_effecter_possible_states* possibleStates =
- reinterpret_cast<state_effecter_possible_states*>(start);
- possibleStates->state_set_id = set.value("id", 0);
- possibleStates->possible_states_size = set.value("size", 0);
-
- start += sizeof(possibleStates->state_set_id) +
- sizeof(possibleStates->possible_states_size);
- static const std::vector<uint8_t> emptyStates{};
- PossibleValues stateValues;
- auto states = set.value("states", emptyStates);
- for (const auto& state : states)
- {
- auto index = state / 8;
- auto bit = state - (index * 8);
- bitfield8_t* bf = reinterpret_cast<bitfield8_t*>(start + index);
- bf->byte |= 1 << bit;
- stateValues.emplace_back(std::move(state));
- }
- start += possibleStates->possible_states_size;
-
- auto dbusEntry = effecter.value("dbus", empty);
- auto objectPath = dbusEntry.value("path", "");
- auto interface = dbusEntry.value("interface", "");
- auto propertyName = dbusEntry.value("property_name", "");
- auto propertyType = dbusEntry.value("property_type", "");
- pldm::utils::DBusMapping dbusMapping{objectPath, interface,
- propertyName, propertyType};
- dbusMappings.emplace_back(std::move(dbusMapping));
-
- Json propValues = dbusEntry["property_values"];
- StatestoDbusVal dbusIdToValMap =
- populateMapping(propertyType, propValues, stateValues);
- if (!dbusIdToValMap.empty())
- {
- dbusValMaps.emplace_back(std::move(dbusIdToValMap));
- }
- }
-
- addDbusObjMaps(
- pdr->effecter_id,
- std::make_tuple(std::move(dbusMappings), std::move(dbusValMaps)));
- PdrEntry pdrEntry{};
- pdrEntry.data = entry.data();
- pdrEntry.size = pdrSize;
- repo.addRecord(pdrEntry);
- }
-}
-
void Handler::generate(const std::string& dir, Repo& repo)
{
// A map of PDR type to a lambda that handles creation of that PDR type.
// The lambda essentially would parse the platform specific PDR JSONs to
// generate the PDR structures. This function iterates through the map to
// invoke all lambdas, so that all PDR types can be created.
- const std::map<Type, std::function<void(const Json& json, Repo& repo)>>
- generators = {
- {PLDM_STATE_EFFECTER_PDR, [this](const auto& json, Repo& repo) {
- generateStateEffecterRepo(json, repo);
- }}};
+
+ const std::map<Type, generatePDR> generateHandlers = {
+ {PLDM_STATE_EFFECTER_PDR,
+ [this](const auto& json, RepoInterface& repo) {
+ pdr_state_effecter::generateStateEffecterPDR<Handler>(json, *this,
+ repo);
+ }}};
Type pdrType{};
for (const auto& dirEntry : fs::directory_iterator(dir))
@@ -152,7 +55,7 @@
for (const auto& effecter : effecterPDRs)
{
pdrType = effecter.value("pdrType", 0);
- generators.at(pdrType)(effecter, repo);
+ generateHandlers.at(pdrType)(effecter, repo);
}
}
}