1f7f5da97SDeepak Kodihalli #include "pldm_fru_cmd.hpp"
2f7f5da97SDeepak Kodihalli
3f7f5da97SDeepak Kodihalli #include "pldm_cmd_helper.hpp"
4f7f5da97SDeepak Kodihalli
5b8baffa3SSridevi Ramesh #ifdef OEM_IBM
621f128d8SAndrew Jeffery #include <libpldm/oem/ibm/fru.h>
7b8baffa3SSridevi Ramesh #endif
8b8baffa3SSridevi Ramesh
95bdde3a4SJohn Wang #include <endian.h>
105bdde3a4SJohn Wang
115bdde3a4SJohn Wang #include <functional>
125bdde3a4SJohn Wang #include <tuple>
135bdde3a4SJohn Wang
14f7f5da97SDeepak Kodihalli namespace pldmtool
15f7f5da97SDeepak Kodihalli {
16f7f5da97SDeepak Kodihalli
17f7f5da97SDeepak Kodihalli namespace fru
18f7f5da97SDeepak Kodihalli {
19f7f5da97SDeepak Kodihalli
20f7f5da97SDeepak Kodihalli namespace
21f7f5da97SDeepak Kodihalli {
22f7f5da97SDeepak Kodihalli
23f7f5da97SDeepak Kodihalli using namespace pldmtool::helper;
24f7f5da97SDeepak Kodihalli
25f7f5da97SDeepak Kodihalli std::vector<std::unique_ptr<CommandInterface>> commands;
26f7f5da97SDeepak Kodihalli
27f7f5da97SDeepak Kodihalli } // namespace
28f7f5da97SDeepak Kodihalli
29f7f5da97SDeepak Kodihalli class GetFruRecordTableMetadata : public CommandInterface
30f7f5da97SDeepak Kodihalli {
31f7f5da97SDeepak Kodihalli public:
32f7f5da97SDeepak Kodihalli ~GetFruRecordTableMetadata() = default;
33f7f5da97SDeepak Kodihalli GetFruRecordTableMetadata() = delete;
34f7f5da97SDeepak Kodihalli GetFruRecordTableMetadata(const GetFruRecordTableMetadata&) = delete;
35f7f5da97SDeepak Kodihalli GetFruRecordTableMetadata(GetFruRecordTableMetadata&&) = default;
36f7f5da97SDeepak Kodihalli GetFruRecordTableMetadata&
37f7f5da97SDeepak Kodihalli operator=(const GetFruRecordTableMetadata&) = delete;
38a7dbca53SPavithra Barithaya GetFruRecordTableMetadata& operator=(GetFruRecordTableMetadata&&) = delete;
39f7f5da97SDeepak Kodihalli
40f7f5da97SDeepak Kodihalli using CommandInterface::CommandInterface;
41f7f5da97SDeepak Kodihalli
createRequestMsg()42f7f5da97SDeepak Kodihalli std::pair<int, std::vector<uint8_t>> createRequestMsg() override
43f7f5da97SDeepak Kodihalli {
44f7f5da97SDeepak Kodihalli std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
45f7f5da97SDeepak Kodihalli auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
46f7f5da97SDeepak Kodihalli
47f7f5da97SDeepak Kodihalli auto rc = encode_get_fru_record_table_metadata_req(
48f7f5da97SDeepak Kodihalli instanceId, request, PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES);
49f7f5da97SDeepak Kodihalli return {rc, requestMsg};
50f7f5da97SDeepak Kodihalli }
51f7f5da97SDeepak Kodihalli
parseResponseMsg(pldm_msg * responsePtr,size_t payloadLength)52f7f5da97SDeepak Kodihalli void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
53f7f5da97SDeepak Kodihalli {
54f7f5da97SDeepak Kodihalli uint8_t cc = 0;
55f7f5da97SDeepak Kodihalli uint8_t fru_data_major_version, fru_data_minor_version;
56f7f5da97SDeepak Kodihalli uint32_t fru_table_maximum_size, fru_table_length;
57f7f5da97SDeepak Kodihalli uint16_t total_record_set_identifiers, total_table_records;
58f7f5da97SDeepak Kodihalli uint32_t checksum;
59f7f5da97SDeepak Kodihalli
60f7f5da97SDeepak Kodihalli auto rc = decode_get_fru_record_table_metadata_resp(
61f7f5da97SDeepak Kodihalli responsePtr, payloadLength, &cc, &fru_data_major_version,
62f7f5da97SDeepak Kodihalli &fru_data_minor_version, &fru_table_maximum_size, &fru_table_length,
63f7f5da97SDeepak Kodihalli &total_record_set_identifiers, &total_table_records, &checksum);
64f7f5da97SDeepak Kodihalli if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
65f7f5da97SDeepak Kodihalli {
66f7f5da97SDeepak Kodihalli std::cerr << "Response Message Error: "
67f7f5da97SDeepak Kodihalli << "rc=" << rc << ",cc=" << (int)cc << std::endl;
68f7f5da97SDeepak Kodihalli return;
69f7f5da97SDeepak Kodihalli }
70dd04990dSSridevi Ramesh ordered_json output;
71dd04990dSSridevi Ramesh output["FRUDATAMajorVersion"] =
72dd04990dSSridevi Ramesh static_cast<uint32_t>(fru_data_major_version);
73dd04990dSSridevi Ramesh output["FRUDATAMinorVersion"] =
74dd04990dSSridevi Ramesh static_cast<uint32_t>(fru_data_minor_version);
75dd04990dSSridevi Ramesh output["FRUTableMaximumSize"] = fru_table_maximum_size;
76dd04990dSSridevi Ramesh output["FRUTableLength"] = fru_table_length;
77dd04990dSSridevi Ramesh output["Total number of Record Set Identifiers in table"] =
78dd04990dSSridevi Ramesh total_record_set_identifiers;
79dd04990dSSridevi Ramesh output["Total number of records in table"] = total_table_records;
80dd04990dSSridevi Ramesh output["FRU DATAStructureTableIntegrityChecksum"] = checksum;
81dd04990dSSridevi Ramesh pldmtool::helper::DisplayInJson(output);
82f7f5da97SDeepak Kodihalli }
83f7f5da97SDeepak Kodihalli };
84f7f5da97SDeepak Kodihalli
855bdde3a4SJohn Wang class FRUTablePrint
865bdde3a4SJohn Wang {
875bdde3a4SJohn Wang public:
FRUTablePrint(const uint8_t * table,size_t table_size)885bdde3a4SJohn Wang explicit FRUTablePrint(const uint8_t* table, size_t table_size) :
895bdde3a4SJohn Wang table(table), table_size(table_size)
905bdde3a4SJohn Wang {}
915bdde3a4SJohn Wang
print()925bdde3a4SJohn Wang void print()
935bdde3a4SJohn Wang {
945bdde3a4SJohn Wang auto p = table;
95dd04990dSSridevi Ramesh ordered_json frutable;
96dd04990dSSridevi Ramesh ordered_json output;
975bdde3a4SJohn Wang while (!isTableEnd(p))
985bdde3a4SJohn Wang {
995bdde3a4SJohn Wang auto record =
1005bdde3a4SJohn Wang reinterpret_cast<const pldm_fru_record_data_format*>(p);
101dd04990dSSridevi Ramesh output["FRU Record Set Identifier"] =
102dd04990dSSridevi Ramesh (int)le16toh(record->record_set_id);
103*16c2a0a0SPatrick Williams output["FRU Record Type"] =
104*16c2a0a0SPatrick Williams typeToString(fruRecordTypes, record->record_type);
105dd04990dSSridevi Ramesh output["Number of FRU fields"] = (int)record->num_fru_fields;
106dd04990dSSridevi Ramesh output["Encoding Type for FRU fields"] =
107dd04990dSSridevi Ramesh typeToString(fruEncodingType, record->encoding_type);
1085bdde3a4SJohn Wang
1095bdde3a4SJohn Wang p += sizeof(pldm_fru_record_data_format) -
1105bdde3a4SJohn Wang sizeof(pldm_fru_record_tlv);
111b8baffa3SSridevi Ramesh
112b8baffa3SSridevi Ramesh std::map<uint8_t, std::string> FruFieldTypeMap;
113b8baffa3SSridevi Ramesh std::string fruFieldValue;
114b8baffa3SSridevi Ramesh
115dd04990dSSridevi Ramesh ordered_json frudata;
116dd04990dSSridevi Ramesh ordered_json frufielddata;
117dd04990dSSridevi Ramesh frufielddata.emplace_back(output);
1185bdde3a4SJohn Wang for (int i = 0; i < record->num_fru_fields; i++)
1195bdde3a4SJohn Wang {
1205bdde3a4SJohn Wang auto tlv = reinterpret_cast<const pldm_fru_record_tlv*>(p);
121b8baffa3SSridevi Ramesh if (record->record_type == PLDM_FRU_RECORD_TYPE_GENERAL)
1225bdde3a4SJohn Wang {
123b8baffa3SSridevi Ramesh FruFieldTypeMap.insert(fruGeneralFieldTypes.begin(),
124b8baffa3SSridevi Ramesh fruGeneralFieldTypes.end());
125b8baffa3SSridevi Ramesh if (tlv->type == PLDM_FRU_FIELD_TYPE_IANA)
126b8baffa3SSridevi Ramesh {
127*16c2a0a0SPatrick Williams fruFieldValue =
128*16c2a0a0SPatrick Williams fruFieldParserU32(tlv->value, tlv->length);
1295bdde3a4SJohn Wang }
130b8baffa3SSridevi Ramesh else if (tlv->type == PLDM_FRU_FIELD_TYPE_MANUFAC_DATE)
131b8baffa3SSridevi Ramesh {
132*16c2a0a0SPatrick Williams fruFieldValue =
133*16c2a0a0SPatrick Williams fruFieldParserTimestamp(tlv->value, tlv->length);
134b8baffa3SSridevi Ramesh }
13571689b8bSPotin Lai else
13671689b8bSPotin Lai {
137*16c2a0a0SPatrick Williams fruFieldValue =
138*16c2a0a0SPatrick Williams fruFieldValuestring(tlv->value, tlv->length);
13971689b8bSPotin Lai }
140c50c6cd7SSridevi Ramesh
141*16c2a0a0SPatrick Williams frudata["FRU Field Type"] =
142*16c2a0a0SPatrick Williams typeToString(FruFieldTypeMap, tlv->type);
143c50c6cd7SSridevi Ramesh frudata["FRU Field Length"] = (int)(tlv->length);
144c50c6cd7SSridevi Ramesh frudata["FRU Field Value"] = fruFieldValue;
145c50c6cd7SSridevi Ramesh frufielddata.emplace_back(frudata);
146b8baffa3SSridevi Ramesh }
147b8baffa3SSridevi Ramesh else
148b8baffa3SSridevi Ramesh {
149b8baffa3SSridevi Ramesh #ifdef OEM_IBM
150b8baffa3SSridevi Ramesh if (tlv->type == PLDM_OEM_FRU_FIELD_TYPE_RT)
151b8baffa3SSridevi Ramesh {
152*16c2a0a0SPatrick Williams auto oemIPZValue =
153*16c2a0a0SPatrick Williams fruFieldValuestring(tlv->value, tlv->length);
154b8baffa3SSridevi Ramesh
15506f9b29eSSagar Srinivas if (populateMaps.contains(oemIPZValue))
156b8baffa3SSridevi Ramesh {
157b8baffa3SSridevi Ramesh const std::map<uint8_t, std::string> IPZTypes =
158b8baffa3SSridevi Ramesh populateMaps.at(oemIPZValue);
159b8baffa3SSridevi Ramesh FruFieldTypeMap.insert(IPZTypes.begin(),
160b8baffa3SSridevi Ramesh IPZTypes.end());
161b8baffa3SSridevi Ramesh }
162b8baffa3SSridevi Ramesh }
163b8baffa3SSridevi Ramesh else
164b8baffa3SSridevi Ramesh {
165b8baffa3SSridevi Ramesh FruFieldTypeMap.insert(fruOemFieldTypes.begin(),
166b8baffa3SSridevi Ramesh fruOemFieldTypes.end());
167b8baffa3SSridevi Ramesh }
168b8baffa3SSridevi Ramesh if (tlv->type == PLDM_OEM_FRU_FIELD_TYPE_IANA)
169b8baffa3SSridevi Ramesh {
170*16c2a0a0SPatrick Williams fruFieldValue =
171*16c2a0a0SPatrick Williams fruFieldParserU32(tlv->value, tlv->length);
172b8baffa3SSridevi Ramesh }
173c50c6cd7SSridevi Ramesh else if (tlv->type != 2)
174b8baffa3SSridevi Ramesh {
175*16c2a0a0SPatrick Williams fruFieldValue =
176*16c2a0a0SPatrick Williams fruFieldIPZParser(tlv->value, tlv->length);
177b8baffa3SSridevi Ramesh }
178b8baffa3SSridevi Ramesh else
179b8baffa3SSridevi Ramesh {
180*16c2a0a0SPatrick Williams fruFieldValue =
181*16c2a0a0SPatrick Williams fruFieldValuestring(tlv->value, tlv->length);
182b8baffa3SSridevi Ramesh }
183*16c2a0a0SPatrick Williams frudata["FRU Field Type"] =
184*16c2a0a0SPatrick Williams typeToString(FruFieldTypeMap, tlv->type);
185dd04990dSSridevi Ramesh frudata["FRU Field Length"] = (int)(tlv->length);
186dd04990dSSridevi Ramesh frudata["FRU Field Value"] = fruFieldValue;
187dd04990dSSridevi Ramesh frufielddata.emplace_back(frudata);
188c50c6cd7SSridevi Ramesh
189c50c6cd7SSridevi Ramesh #endif
190c50c6cd7SSridevi Ramesh }
1915bdde3a4SJohn Wang p += sizeof(pldm_fru_record_tlv) - 1 + tlv->length;
1925bdde3a4SJohn Wang }
193dd04990dSSridevi Ramesh frutable.emplace_back(frufielddata);
1945bdde3a4SJohn Wang }
195dd04990dSSridevi Ramesh pldmtool::helper::DisplayInJson(frutable);
1965bdde3a4SJohn Wang }
1975bdde3a4SJohn Wang
1985bdde3a4SJohn Wang private:
1995bdde3a4SJohn Wang const uint8_t* table;
2005bdde3a4SJohn Wang size_t table_size;
2015bdde3a4SJohn Wang
isTableEnd(const uint8_t * p)2025bdde3a4SJohn Wang bool isTableEnd(const uint8_t* p)
2035bdde3a4SJohn Wang {
2045bdde3a4SJohn Wang auto offset = p - table;
2055bdde3a4SJohn Wang return (table_size - offset) <= 7;
2065bdde3a4SJohn Wang }
2075bdde3a4SJohn Wang
208b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> fruEncodingType{
2095bdde3a4SJohn Wang {PLDM_FRU_ENCODING_UNSPECIFIED, "Unspecified"},
2105bdde3a4SJohn Wang {PLDM_FRU_ENCODING_ASCII, "ASCII"},
2115bdde3a4SJohn Wang {PLDM_FRU_ENCODING_UTF8, "UTF8"},
2125bdde3a4SJohn Wang {PLDM_FRU_ENCODING_UTF16, "UTF16"},
2135bdde3a4SJohn Wang {PLDM_FRU_ENCODING_UTF16LE, "UTF16LE"},
2145bdde3a4SJohn Wang {PLDM_FRU_ENCODING_UTF16BE, "UTF16BE"}};
2155bdde3a4SJohn Wang
216b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> fruGeneralFieldTypes{
217b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_CHASSIS, "Chassis"},
218b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_MODEL, "Model"},
219b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_PN, "Part Number"},
220b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_SN, "Serial Number"},
221b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_MANUFAC, "Manufacturer"},
222b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_MANUFAC_DATE, "Manufacture Date"},
223b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_VENDOR, "Vendor"},
224b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_NAME, "Name"},
225b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_SKU, "SKU"},
226b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_VERSION, "Version"},
227b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_ASSET_TAG, "Asset Tag"},
228b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_DESC, "Description"},
229b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_EC_LVL, "Engineering Change Level"},
230b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_OTHER, "Other Information"},
231b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_IANA, "Vendor IANA"}};
232b8baffa3SSridevi Ramesh
233b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> fruRecordTypes{
2345bdde3a4SJohn Wang {PLDM_FRU_RECORD_TYPE_GENERAL, "General"},
2355bdde3a4SJohn Wang {PLDM_FRU_RECORD_TYPE_OEM, "OEM"}};
2365bdde3a4SJohn Wang
237b8baffa3SSridevi Ramesh #ifdef OEM_IBM
238b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> fruOemFieldTypes{
239b8baffa3SSridevi Ramesh {PLDM_OEM_FRU_FIELD_TYPE_IANA, "Vendor IANA"},
240b8baffa3SSridevi Ramesh {PLDM_OEM_FRU_FIELD_TYPE_RT, "RT"},
241b8baffa3SSridevi Ramesh {PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE, "Location Code"}};
242b8baffa3SSridevi Ramesh
243b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> VINIFieldTypes{
244b8baffa3SSridevi Ramesh {2, "RT"}, {3, "B3"}, {4, "B4"}, {5, "B7"}, {6, "CC"}, {7, "CE"},
245b8baffa3SSridevi Ramesh {8, "CT"}, {9, "DR"}, {10, "FG"}, {11, "FN"}, {12, "HE"}, {13, "HW"},
246b8baffa3SSridevi Ramesh {14, "HX"}, {15, "PN"}, {16, "SN"}, {17, "TS"}, {18, "VZ"}};
247b8baffa3SSridevi Ramesh
248b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> VSYSFieldTypes{
249b8baffa3SSridevi Ramesh {2, "RT"}, {3, "BR"}, {4, "DR"}, {5, "FV"}, {6, "ID"},
250b8baffa3SSridevi Ramesh {7, "MN"}, {8, "NN"}, {9, "RB"}, {10, "RG"}, {11, "SE"},
251b8baffa3SSridevi Ramesh {12, "SG"}, {13, "SU"}, {14, "TM"}, {15, "TN"}, {16, "WN"}};
252b8baffa3SSridevi Ramesh
253b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> LXR0FieldTypes{
254b8baffa3SSridevi Ramesh {2, "RT"}, {3, "LX"}, {4, "VZ"}};
255b8baffa3SSridevi Ramesh
256b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> VW10FieldTypes{
257b8baffa3SSridevi Ramesh {2, "RT"}, {3, "DR"}, {4, "GD"}};
258b8baffa3SSridevi Ramesh
259b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> VR10FieldTypes{
260b8baffa3SSridevi Ramesh {2, "RT"}, {3, "DC"}, {4, "DR"}, {5, "FL"}, {6, "WA"}};
261b8baffa3SSridevi Ramesh
262b8baffa3SSridevi Ramesh static inline const std::map<std::string,
263b8baffa3SSridevi Ramesh const std::map<uint8_t, std::string>>
264b8baffa3SSridevi Ramesh populateMaps{{"VINI", VINIFieldTypes},
265b8baffa3SSridevi Ramesh {"VSYS", VSYSFieldTypes},
266b8baffa3SSridevi Ramesh {"LXR0", LXR0FieldTypes},
267b8baffa3SSridevi Ramesh {"VWX10", VW10FieldTypes},
268b8baffa3SSridevi Ramesh {"VR10", VR10FieldTypes}};
269b8baffa3SSridevi Ramesh #endif
270b8baffa3SSridevi Ramesh
typeToString(std::map<uint8_t,std::string> typeMap,uint8_t type)271b8baffa3SSridevi Ramesh std::string typeToString(std::map<uint8_t, std::string> typeMap,
2725bdde3a4SJohn Wang uint8_t type)
2735bdde3a4SJohn Wang {
2745bdde3a4SJohn Wang auto typeString = std::to_string(type);
2755bdde3a4SJohn Wang try
2765bdde3a4SJohn Wang {
277b8baffa3SSridevi Ramesh return std::string(typeMap.at(type)) + "(" + typeString + ")";
2785bdde3a4SJohn Wang }
2795bdde3a4SJohn Wang catch (const std::out_of_range& e)
2805bdde3a4SJohn Wang {
2815bdde3a4SJohn Wang return typeString;
2825bdde3a4SJohn Wang }
2835bdde3a4SJohn Wang }
2845bdde3a4SJohn Wang
fruFieldValuestring(const uint8_t * value,uint8_t length)285b8baffa3SSridevi Ramesh std::string fruFieldValuestring(const uint8_t* value, uint8_t length)
2865bdde3a4SJohn Wang {
2875bdde3a4SJohn Wang return std::string(reinterpret_cast<const char*>(value), length);
2885bdde3a4SJohn Wang }
2895bdde3a4SJohn Wang
fruFieldParserU32(const uint8_t * value,uint8_t length)2905bdde3a4SJohn Wang static std::string fruFieldParserU32(const uint8_t* value, uint8_t length)
2915bdde3a4SJohn Wang {
2925bdde3a4SJohn Wang assert(length == 4);
2935bdde3a4SJohn Wang uint32_t v;
2945bdde3a4SJohn Wang std::memcpy(&v, value, length);
2955bdde3a4SJohn Wang return std::to_string(le32toh(v));
2965bdde3a4SJohn Wang }
2975bdde3a4SJohn Wang
fruFieldParserTimestamp(const uint8_t *,uint8_t)298b8baffa3SSridevi Ramesh static std::string fruFieldParserTimestamp(const uint8_t*, uint8_t)
2995bdde3a4SJohn Wang {
300b8baffa3SSridevi Ramesh return std::string("TODO");
301b8baffa3SSridevi Ramesh }
3025bdde3a4SJohn Wang
fruFieldIPZParser(const uint8_t * value,uint8_t length)303b8baffa3SSridevi Ramesh static std::string fruFieldIPZParser(const uint8_t* value, uint8_t length)
304b8baffa3SSridevi Ramesh {
305b8baffa3SSridevi Ramesh std::ostringstream tempStream;
306b8baffa3SSridevi Ramesh for (int i = 0; i < int(length); ++i)
307b8baffa3SSridevi Ramesh {
308b8baffa3SSridevi Ramesh tempStream << "0x" << std::setfill('0') << std::setw(2) << std::hex
309b8baffa3SSridevi Ramesh << (unsigned)value[i] << " ";
310b8baffa3SSridevi Ramesh }
311b8baffa3SSridevi Ramesh return tempStream.str();
3125bdde3a4SJohn Wang }
3135bdde3a4SJohn Wang };
3145bdde3a4SJohn Wang
3155bdde3a4SJohn Wang class GetFRURecordByOption : public CommandInterface
3165bdde3a4SJohn Wang {
3175bdde3a4SJohn Wang public:
3185bdde3a4SJohn Wang ~GetFRURecordByOption() = default;
3195bdde3a4SJohn Wang GetFRURecordByOption() = delete;
3205bdde3a4SJohn Wang GetFRURecordByOption(const GetFRURecordByOption&) = delete;
3215bdde3a4SJohn Wang GetFRURecordByOption(GetFruRecordTableMetadata&&) = delete;
3225bdde3a4SJohn Wang GetFRURecordByOption& operator=(const GetFRURecordByOption&) = delete;
3235bdde3a4SJohn Wang GetFRURecordByOption& operator=(GetFRURecordByOption&&) = delete;
3245bdde3a4SJohn Wang
GetFRURecordByOption(const char * type,const char * name,CLI::App * app)3255bdde3a4SJohn Wang explicit GetFRURecordByOption(const char* type, const char* name,
3265bdde3a4SJohn Wang CLI::App* app) :
3275bdde3a4SJohn Wang CommandInterface(type, name, app)
3285bdde3a4SJohn Wang {
3295bdde3a4SJohn Wang app->add_option("-i, --identifier", recordSetIdentifier,
3305bdde3a4SJohn Wang "Record Set Identifier\n"
3315bdde3a4SJohn Wang "Possible values: {All record sets = 0, Specific "
3325bdde3a4SJohn Wang "record set = 1 – 65535}")
3335bdde3a4SJohn Wang ->required();
3345bdde3a4SJohn Wang app->add_option("-r, --record", recordType,
3355bdde3a4SJohn Wang "Record Type\n"
3365bdde3a4SJohn Wang "Possible values: {All record types = 0, Specific "
3375bdde3a4SJohn Wang "record types = 1 – 255}")
3385bdde3a4SJohn Wang ->required();
3395bdde3a4SJohn Wang app->add_option("-f, --field", fieldType,
3405bdde3a4SJohn Wang "Field Type\n"
3415bdde3a4SJohn Wang "Possible values: {All record field types = 0, "
3425bdde3a4SJohn Wang "Specific field types = 1 – 15}")
3435bdde3a4SJohn Wang ->required();
3445bdde3a4SJohn Wang }
3455bdde3a4SJohn Wang
createRequestMsg()3465bdde3a4SJohn Wang std::pair<int, std::vector<uint8_t>> createRequestMsg() override
3475bdde3a4SJohn Wang {
3485bdde3a4SJohn Wang if (fieldType != 0 && recordType == 0)
3495bdde3a4SJohn Wang {
3505bdde3a4SJohn Wang throw std::invalid_argument("if field type is non-zero, the record "
3515bdde3a4SJohn Wang "type shall also be non-zero");
3525bdde3a4SJohn Wang }
353b8baffa3SSridevi Ramesh if (recordType == 254 && (fieldType > 2 && fieldType < 254))
354b8baffa3SSridevi Ramesh {
355b8baffa3SSridevi Ramesh throw std::invalid_argument(
356b8baffa3SSridevi Ramesh "GetFRURecordByOption is not supported for recordType : 254 "
357b8baffa3SSridevi Ramesh "and fieldType > 2");
358b8baffa3SSridevi Ramesh }
3595bdde3a4SJohn Wang
3605bdde3a4SJohn Wang auto payloadLength = sizeof(pldm_get_fru_record_by_option_req);
3615bdde3a4SJohn Wang
3625bdde3a4SJohn Wang std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + payloadLength,
3635bdde3a4SJohn Wang 0);
3645bdde3a4SJohn Wang auto reqMsg = reinterpret_cast<pldm_msg*>(requestMsg.data());
3655bdde3a4SJohn Wang
3665bdde3a4SJohn Wang auto rc = encode_get_fru_record_by_option_req(
3675bdde3a4SJohn Wang instanceId, 0 /* DataTransferHandle */, 0 /* FRUTableHandle */,
3685bdde3a4SJohn Wang recordSetIdentifier, recordType, fieldType, PLDM_GET_FIRSTPART,
3695bdde3a4SJohn Wang reqMsg, payloadLength);
3705bdde3a4SJohn Wang
3715bdde3a4SJohn Wang return {rc, requestMsg};
3725bdde3a4SJohn Wang }
3735bdde3a4SJohn Wang
parseResponseMsg(pldm_msg * responsePtr,size_t payloadLength)3745bdde3a4SJohn Wang void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
3755bdde3a4SJohn Wang {
3765bdde3a4SJohn Wang uint8_t cc;
3775bdde3a4SJohn Wang uint32_t dataTransferHandle;
3785bdde3a4SJohn Wang uint8_t transferFlag;
3795bdde3a4SJohn Wang variable_field fruData;
3805bdde3a4SJohn Wang
3815bdde3a4SJohn Wang auto rc = decode_get_fru_record_by_option_resp(
3825bdde3a4SJohn Wang responsePtr, payloadLength, &cc, &dataTransferHandle, &transferFlag,
3835bdde3a4SJohn Wang &fruData);
3845bdde3a4SJohn Wang
3855bdde3a4SJohn Wang if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
3865bdde3a4SJohn Wang {
3875bdde3a4SJohn Wang std::cerr << "Response Message Error: "
3885bdde3a4SJohn Wang << "rc=" << rc << ",cc=" << (int)cc << std::endl;
3895bdde3a4SJohn Wang return;
3905bdde3a4SJohn Wang }
3915bdde3a4SJohn Wang
3925bdde3a4SJohn Wang FRUTablePrint tablePrint(fruData.ptr, fruData.length);
3935bdde3a4SJohn Wang tablePrint.print();
3945bdde3a4SJohn Wang }
3955bdde3a4SJohn Wang
3965bdde3a4SJohn Wang private:
3975bdde3a4SJohn Wang uint16_t recordSetIdentifier;
3985bdde3a4SJohn Wang uint8_t recordType;
3995bdde3a4SJohn Wang uint8_t fieldType;
4005bdde3a4SJohn Wang };
4015bdde3a4SJohn Wang
402bd9440bdSSridevi Ramesh class GetFruRecordTable : public CommandInterface
403bd9440bdSSridevi Ramesh {
404bd9440bdSSridevi Ramesh public:
405bd9440bdSSridevi Ramesh ~GetFruRecordTable() = default;
406bd9440bdSSridevi Ramesh GetFruRecordTable() = delete;
407bd9440bdSSridevi Ramesh GetFruRecordTable(const GetFruRecordTable&) = delete;
408bd9440bdSSridevi Ramesh GetFruRecordTable(GetFruRecordTable&&) = default;
409bd9440bdSSridevi Ramesh GetFruRecordTable& operator=(const GetFruRecordTable&) = delete;
410a7dbca53SPavithra Barithaya GetFruRecordTable& operator=(GetFruRecordTable&&) = delete;
411bd9440bdSSridevi Ramesh
412bd9440bdSSridevi Ramesh using CommandInterface::CommandInterface;
createRequestMsg()413bd9440bdSSridevi Ramesh std::pair<int, std::vector<uint8_t>> createRequestMsg() override
414bd9440bdSSridevi Ramesh {
415*16c2a0a0SPatrick Williams std::vector<uint8_t> requestMsg(
416*16c2a0a0SPatrick Williams sizeof(pldm_msg_hdr) + PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES);
417bd9440bdSSridevi Ramesh auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
418bd9440bdSSridevi Ramesh
419bd9440bdSSridevi Ramesh auto rc = encode_get_fru_record_table_req(
42071689b8bSPotin Lai instanceId, 0, PLDM_GET_FIRSTPART, request,
421bd9440bdSSridevi Ramesh requestMsg.size() - sizeof(pldm_msg_hdr));
422bd9440bdSSridevi Ramesh return {rc, requestMsg};
423bd9440bdSSridevi Ramesh }
parseResponseMsg(pldm_msg * responsePtr,size_t payloadLength)424bd9440bdSSridevi Ramesh void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
425bd9440bdSSridevi Ramesh {
426bd9440bdSSridevi Ramesh uint8_t cc = 0;
427bd9440bdSSridevi Ramesh uint32_t next_data_transfer_handle = 0;
428bd9440bdSSridevi Ramesh uint8_t transfer_flag = 0;
429bd9440bdSSridevi Ramesh size_t fru_record_table_length = 0;
430bd9440bdSSridevi Ramesh std::vector<uint8_t> fru_record_table_data(payloadLength);
431bd9440bdSSridevi Ramesh
432bd9440bdSSridevi Ramesh auto rc = decode_get_fru_record_table_resp(
433bd9440bdSSridevi Ramesh responsePtr, payloadLength, &cc, &next_data_transfer_handle,
434bd9440bdSSridevi Ramesh &transfer_flag, fru_record_table_data.data(),
435bd9440bdSSridevi Ramesh &fru_record_table_length);
436bd9440bdSSridevi Ramesh
437bd9440bdSSridevi Ramesh if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
438bd9440bdSSridevi Ramesh {
439bd9440bdSSridevi Ramesh std::cerr << "Response Message Error: "
440bd9440bdSSridevi Ramesh << "rc=" << rc << ",cc=" << (int)cc << std::endl;
441bd9440bdSSridevi Ramesh return;
442bd9440bdSSridevi Ramesh }
443bd9440bdSSridevi Ramesh
444bd9440bdSSridevi Ramesh FRUTablePrint tablePrint(fru_record_table_data.data(),
445bd9440bdSSridevi Ramesh fru_record_table_length);
446bd9440bdSSridevi Ramesh tablePrint.print();
447bd9440bdSSridevi Ramesh }
448bd9440bdSSridevi Ramesh };
449bd9440bdSSridevi Ramesh
registerCommand(CLI::App & app)450f7f5da97SDeepak Kodihalli void registerCommand(CLI::App& app)
451f7f5da97SDeepak Kodihalli {
452f7f5da97SDeepak Kodihalli auto fru = app.add_subcommand("fru", "FRU type command");
453f7f5da97SDeepak Kodihalli fru->require_subcommand(1);
454f7f5da97SDeepak Kodihalli auto getFruRecordTableMetadata = fru->add_subcommand(
455f7f5da97SDeepak Kodihalli "GetFruRecordTableMetadata", "get FRU record table metadata");
456f7f5da97SDeepak Kodihalli commands.push_back(std::make_unique<GetFruRecordTableMetadata>(
457f7f5da97SDeepak Kodihalli "fru", "GetFruRecordTableMetadata", getFruRecordTableMetadata));
4585bdde3a4SJohn Wang
459*16c2a0a0SPatrick Williams auto getFRURecordByOption =
460*16c2a0a0SPatrick Williams fru->add_subcommand("GetFRURecordByOption", "get FRU Record By Option");
4615bdde3a4SJohn Wang commands.push_back(std::make_unique<GetFRURecordByOption>(
4625bdde3a4SJohn Wang "fru", "GetFRURecordByOption", getFRURecordByOption));
463bd9440bdSSridevi Ramesh
464*16c2a0a0SPatrick Williams auto getFruRecordTable =
465*16c2a0a0SPatrick Williams fru->add_subcommand("GetFruRecordTable", "get FRU Record Table");
466bd9440bdSSridevi Ramesh commands.push_back(std::make_unique<GetFruRecordTable>(
467bd9440bdSSridevi Ramesh "fru", "GetFruRecordTable", getFruRecordTable));
468f7f5da97SDeepak Kodihalli }
469f7f5da97SDeepak Kodihalli
470f7f5da97SDeepak Kodihalli } // namespace fru
471f7f5da97SDeepak Kodihalli
472f7f5da97SDeepak Kodihalli } // namespace pldmtool
473