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 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 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: 885bdde3a4SJohn Wang explicit FRUTablePrint(const uint8_t* table, size_t table_size) : 895bdde3a4SJohn Wang table(table), table_size(table_size) 905bdde3a4SJohn Wang {} 915bdde3a4SJohn Wang 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); 1036da4f91bSPatrick Williams output["FRU Record Type"] = typeToString(fruRecordTypes, 1046da4f91bSPatrick Williams 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 { 1276da4f91bSPatrick Williams fruFieldValue = fruFieldParserU32(tlv->value, 1286da4f91bSPatrick Williams tlv->length); 1295bdde3a4SJohn Wang } 130b8baffa3SSridevi Ramesh else if (tlv->type == PLDM_FRU_FIELD_TYPE_MANUFAC_DATE) 131b8baffa3SSridevi Ramesh { 1326da4f91bSPatrick Williams fruFieldValue = fruFieldParserTimestamp(tlv->value, 1336da4f91bSPatrick Williams tlv->length); 134b8baffa3SSridevi Ramesh } 13571689b8bSPotin Lai else 13671689b8bSPotin Lai { 1376da4f91bSPatrick Williams fruFieldValue = fruFieldValuestring(tlv->value, 1386da4f91bSPatrick Williams tlv->length); 13971689b8bSPotin Lai } 140c50c6cd7SSridevi Ramesh 1416da4f91bSPatrick Williams frudata["FRU Field Type"] = typeToString(FruFieldTypeMap, 1426da4f91bSPatrick Williams 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 { 1526da4f91bSPatrick Williams auto oemIPZValue = fruFieldValuestring(tlv->value, 1536da4f91bSPatrick Williams tlv->length); 154b8baffa3SSridevi Ramesh 155*06f9b29eSSagar 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 { 1706da4f91bSPatrick Williams fruFieldValue = fruFieldParserU32(tlv->value, 1716da4f91bSPatrick Williams tlv->length); 172b8baffa3SSridevi Ramesh } 173c50c6cd7SSridevi Ramesh else if (tlv->type != 2) 174b8baffa3SSridevi Ramesh { 1756da4f91bSPatrick Williams fruFieldValue = fruFieldIPZParser(tlv->value, 1766da4f91bSPatrick Williams tlv->length); 177b8baffa3SSridevi Ramesh } 178b8baffa3SSridevi Ramesh else 179b8baffa3SSridevi Ramesh { 1806da4f91bSPatrick Williams fruFieldValue = fruFieldValuestring(tlv->value, 1816da4f91bSPatrick Williams tlv->length); 182b8baffa3SSridevi Ramesh } 1836da4f91bSPatrick Williams frudata["FRU Field Type"] = typeToString(FruFieldTypeMap, 1846da4f91bSPatrick Williams 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 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 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 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 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 298b8baffa3SSridevi Ramesh static std::string fruFieldParserTimestamp(const uint8_t*, uint8_t) 2995bdde3a4SJohn Wang { 300b8baffa3SSridevi Ramesh return std::string("TODO"); 301b8baffa3SSridevi Ramesh } 3025bdde3a4SJohn Wang 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 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 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 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; 413bd9440bdSSridevi Ramesh std::pair<int, std::vector<uint8_t>> createRequestMsg() override 414bd9440bdSSridevi Ramesh { 415bd9440bdSSridevi Ramesh std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 416bd9440bdSSridevi Ramesh 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 } 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 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 4596da4f91bSPatrick Williams auto getFRURecordByOption = fru->add_subcommand("GetFRURecordByOption", 4606da4f91bSPatrick Williams "get FRU Record By Option"); 4615bdde3a4SJohn Wang commands.push_back(std::make_unique<GetFRURecordByOption>( 4625bdde3a4SJohn Wang "fru", "GetFRURecordByOption", getFRURecordByOption)); 463bd9440bdSSridevi Ramesh 4646da4f91bSPatrick Williams auto getFruRecordTable = fru->add_subcommand("GetFruRecordTable", 4656da4f91bSPatrick Williams "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