Pldmtool change to fetch pdrs based on TerminusID
This commit adds a new option "-n" to getPDR in the pldmtool using
which we can retrieve the PDRs based on the terminus ID.
Tested:
./pldmtool platform getpdr -h
get platform descriptor records
Usage: ./pldmtool platform GetPDR [OPTIONS]
Options:
-h,--help Print this help message and exit
-m,--mctp_eid UINT MCTP endpoint ID
-v,--verbose
[Option Group: Required Option]
Retrieve individual PDR, all PDRs, PDRs of a requested type or retrieve all PDRs of the requested terminusID
[Exactly 1 of the following options is required]
Options:
-d,--data UINT retrieve individual PDRs from a PDR Repository
eg: The recordHandle value for the PDR to be retrieved and 0 means get first PDR in the repository.
-t,--type TEXT retrieve all PDRs of the requested type
supported types:
[terminusLocator, stateSensor, numericEffecter, stateEffecter, EntityAssociation, fruRecord, ... ]
-i,--terminusID UINT retrieve all PDRs of the requested terminusID
supported IDs:
[1, 2, 208...]
-a,--all retrieve all PDRs from a PDR repository
Example 1:
./pldmtool platform getpdr -i 0
[]
Example 2:
./pldmtool platform getpdr -i 2
Copied the output here:
https://gist.github.com/Pavithrab7/4218104bc7e58951ff91fe5b49e562b0
Change-Id: I8b78818abbbbb3678e180d2bd1f38017454fd0d3
Signed-off-by: Pavithra Barithaya <pavithra.b@ibm.com>
diff --git a/pldmtool/pldm_cmd_helper.hpp b/pldmtool/pldm_cmd_helper.hpp
index 6f185dd..1f21ea2 100644
--- a/pldmtool/pldm_cmd_helper.hpp
+++ b/pldmtool/pldm_cmd_helper.hpp
@@ -109,6 +109,26 @@
return mctp_eid;
}
+ /**
+ * @brief get PLDM type
+ *
+ * @return pldm type
+ */
+ inline std::string getPLDMType()
+ {
+ return pldmType;
+ }
+
+ /**
+ * @brief get command name
+ *
+ * @return the command name
+ */
+ inline std::string getCommandName()
+ {
+ return commandName;
+ }
+
private:
const std::string pldmType;
const std::string commandName;
diff --git a/pldmtool/pldm_platform_cmd.cpp b/pldmtool/pldm_platform_cmd.cpp
index e141312..d8b1b15 100644
--- a/pldmtool/pldm_platform_cmd.cpp
+++ b/pldmtool/pldm_platform_cmd.cpp
@@ -67,7 +67,7 @@
{
auto pdrOptionGroup = app->add_option_group(
"Required Option",
- "Retrieve individual PDR, all PDRs, or PDRs of a requested type");
+ "Retrieve individual PDR, all PDRs, PDRs of a requested type or retrieve all PDRs of the requested terminusID");
pdrOptionGroup->add_option(
"-d,--data", recordHandle,
"retrieve individual PDRs from a PDR Repository\n"
@@ -80,12 +80,59 @@
"[terminusLocator, stateSensor, "
"numericEffecter, stateEffecter, "
"EntityAssociation, fruRecord, ... ]");
+
+ getPDRGroupOption = pdrOptionGroup->add_option(
+ "-i, --terminusID", pdrTerminus,
+ "retrieve all PDRs of the requested terminusID\n"
+ "supported IDs:\n [1, 2, 208...]");
+
allPDRs = false;
pdrOptionGroup->add_flag("-a, --all", allPDRs,
"retrieve all PDRs from a PDR repository");
+
pdrOptionGroup->require_option(1);
}
+ void parseGetPDROptions()
+ {
+ optTIDSet = false;
+ if (getPDRGroupOption->count() > 0)
+ {
+ optTIDSet = true;
+ getPDRs();
+ }
+ }
+
+ void getPDRs()
+ {
+ // start the array
+ std::cout << "[";
+
+ recordHandle = 0;
+ do
+ {
+ CommandInterface::exec();
+ } while (recordHandle != 0);
+
+ // close the array
+ std::cout << "]\n";
+
+ if (handleFound)
+ {
+ recordHandle = 0;
+ uint32_t prevRecordHandle = 0;
+ do
+ {
+ CommandInterface::exec();
+ if (recordHandle == prevRecordHandle)
+ {
+ return;
+ }
+ prevRecordHandle = recordHandle;
+ } while (recordHandle != 0);
+ }
+ }
+
void exec() override
{
if (allPDRs || !pdrRecType.empty())
@@ -178,8 +225,26 @@
return;
}
- printPDRMsg(nextRecordHndl, respCnt, recordData);
- recordHandle = nextRecordHndl;
+ if (optTIDSet && !handleFound)
+ {
+ terminusHandle = getTerminusHandle(recordData, pdrTerminus);
+ if (terminusHandle.has_value())
+ {
+ recordHandle = 0;
+ return;
+ }
+ else
+ {
+ recordHandle = nextRecordHndl;
+ return;
+ }
+ }
+
+ else
+ {
+ printPDRMsg(nextRecordHndl, respCnt, recordData, terminusHandle);
+ recordHandle = nextRecordHndl;
+ }
}
private:
@@ -960,6 +1025,69 @@
}
}
+ bool checkTerminusHandle(const uint8_t* data,
+ std::optional<uint16_t> terminusHandle)
+ {
+ struct pldm_pdr_hdr* pdr = (struct pldm_pdr_hdr*)data;
+
+ if (pdr->type == PLDM_TERMINUS_LOCATOR_PDR)
+ {
+ auto tlpdr =
+ reinterpret_cast<const pldm_terminus_locator_pdr*>(data);
+
+ if (tlpdr->terminus_handle != terminusHandle)
+ {
+ return true;
+ }
+ }
+ else if (pdr->type == PLDM_STATE_SENSOR_PDR)
+ {
+ auto sensor = reinterpret_cast<const pldm_state_sensor_pdr*>(data);
+
+ if (sensor->terminus_handle != terminusHandle)
+ {
+ return true;
+ }
+ }
+ else if (pdr->type == PLDM_NUMERIC_EFFECTER_PDR)
+ {
+ auto numericEffecter =
+ reinterpret_cast<const pldm_numeric_effecter_value_pdr*>(data);
+
+ if (numericEffecter->terminus_handle != terminusHandle)
+ {
+ return true;
+ }
+ }
+
+ else if (pdr->type == PLDM_STATE_EFFECTER_PDR)
+ {
+ auto stateEffecter =
+ reinterpret_cast<const pldm_state_effecter_pdr*>(data);
+ if (stateEffecter->terminus_handle != terminusHandle)
+ {
+ return true;
+ }
+ }
+ else if (pdr->type == PLDM_PDR_FRU_RECORD_SET)
+ {
+ data += sizeof(pldm_pdr_hdr);
+ auto fru = reinterpret_cast<const pldm_pdr_fru_record_set*>(data);
+
+ if (fru->terminus_handle != terminusHandle)
+ {
+ return true;
+ }
+ }
+ else
+ {
+ // Entity association PDRs does not have terminus handle
+ return true;
+ }
+
+ return false;
+ }
+
void printTerminusLocatorPDR(const uint8_t* data, ordered_json& output)
{
const std::array<std::string_view, 4> terminusLocatorType = {
@@ -985,8 +1113,24 @@
}
}
+ std::optional<uint16_t> getTerminusHandle(uint8_t* data,
+ std::optional<uint8_t> tid)
+ {
+ struct pldm_pdr_hdr* pdr = (struct pldm_pdr_hdr*)data;
+ if (pdr->type == PLDM_TERMINUS_LOCATOR_PDR)
+ {
+ auto pdr = reinterpret_cast<const pldm_terminus_locator_pdr*>(data);
+ if (pdr->tid == tid)
+ {
+ handleFound = true;
+ return pdr->terminus_handle;
+ }
+ }
+ return std::nullopt;
+ }
+
void printPDRMsg(uint32_t& nextRecordHndl, const uint16_t respCnt,
- uint8_t* data)
+ uint8_t* data, std::optional<uint16_t> terminusHandle)
{
if (data == NULL)
{
@@ -1026,6 +1170,16 @@
}
}
+ if (pdrTerminus.has_value())
+ {
+ if (checkTerminusHandle(data, terminusHandle))
+ {
+ std::cerr << "The Terminus handle doesn't match return"
+ << std::endl;
+ return;
+ }
+ }
+
printCommonPDRHeader(pdr, output);
switch (pdr->type)
@@ -1055,9 +1209,14 @@
}
private:
+ bool optTIDSet = false;
uint32_t recordHandle;
bool allPDRs;
std::string pdrRecType;
+ std::optional<uint8_t> pdrTerminus;
+ std::optional<uint16_t> terminusHandle;
+ bool handleFound = false;
+ CLI::Option* getPDRGroupOption = nullptr;
};
class SetStateEffecter : public CommandInterface
@@ -1356,5 +1515,18 @@
"platform", "getStateSensorReadings", getStateSensorReadings));
}
+void parseGetPDROption()
+{
+ for (const auto& command : commands)
+ {
+ if (command.get()->getPLDMType() == "platform" &&
+ command.get()->getCommandName() == "getPDR")
+ {
+ auto getPDR = dynamic_cast<GetPDR*>(command.get());
+ getPDR->parseGetPDROptions();
+ }
+ }
+}
+
} // namespace platform
} // namespace pldmtool
diff --git a/pldmtool/pldm_platform_cmd.hpp b/pldmtool/pldm_platform_cmd.hpp
index 45f15ba..5d548dc 100644
--- a/pldmtool/pldm_platform_cmd.hpp
+++ b/pldmtool/pldm_platform_cmd.hpp
@@ -10,6 +10,13 @@
void registerCommand(CLI::App& app);
+/*@brief method to parse the command line option for
+ get PDR command.
+*/
+void parseGetPDROption();
+
+void getPDRs();
+
} // namespace platform
} // namespace pldmtool
diff --git a/pldmtool/pldmtool.cpp b/pldmtool/pldmtool.cpp
index cecc965..ff898d0 100644
--- a/pldmtool/pldmtool.cpp
+++ b/pldmtool/pldmtool.cpp
@@ -80,5 +80,6 @@
#endif
CLI11_PARSE(app, argc, argv);
+ pldmtool::platform::parseGetPDROption();
return 0;
}