1f7f5da97SDeepak Kodihalli #include "pldm_fru_cmd.hpp" 2f7f5da97SDeepak Kodihalli 3f7f5da97SDeepak Kodihalli #include "pldm_cmd_helper.hpp" 4f7f5da97SDeepak Kodihalli 5b8baffa3SSridevi Ramesh #ifdef OEM_IBM 6c453e164SGeorge Liu #include <libpldm/fru_oem_ibm.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; 38f7f5da97SDeepak Kodihalli GetFruRecordTableMetadata& operator=(GetFruRecordTableMetadata&&) = default; 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); 103dd04990dSSridevi Ramesh output["FRU Record Type"] = 104dd04990dSSridevi Ramesh 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 { 127b8baffa3SSridevi Ramesh fruFieldValue = 128b8baffa3SSridevi Ramesh fruFieldParserU32(tlv->value, tlv->length); 1295bdde3a4SJohn Wang } 130b8baffa3SSridevi Ramesh else if (tlv->type == PLDM_FRU_FIELD_TYPE_MANUFAC_DATE) 131b8baffa3SSridevi Ramesh { 132b8baffa3SSridevi Ramesh fruFieldValue = 133b8baffa3SSridevi Ramesh fruFieldParserTimestamp(tlv->value, tlv->length); 134b8baffa3SSridevi Ramesh } 135*71689b8bSPotin Lai else 136*71689b8bSPotin Lai { 137*71689b8bSPotin Lai fruFieldValue = 138*71689b8bSPotin Lai fruFieldValuestring(tlv->value, tlv->length); 139*71689b8bSPotin Lai } 140c50c6cd7SSridevi Ramesh 141c50c6cd7SSridevi Ramesh frudata["FRU Field Type"] = 142c50c6cd7SSridevi Ramesh 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 { 152b8baffa3SSridevi Ramesh auto oemIPZValue = 153b8baffa3SSridevi Ramesh fruFieldValuestring(tlv->value, tlv->length); 154b8baffa3SSridevi Ramesh 155b8baffa3SSridevi Ramesh if (populateMaps.find(oemIPZValue) != 156b8baffa3SSridevi Ramesh populateMaps.end()) 157b8baffa3SSridevi Ramesh { 158b8baffa3SSridevi Ramesh const std::map<uint8_t, std::string> IPZTypes = 159b8baffa3SSridevi Ramesh populateMaps.at(oemIPZValue); 160b8baffa3SSridevi Ramesh FruFieldTypeMap.insert(IPZTypes.begin(), 161b8baffa3SSridevi Ramesh IPZTypes.end()); 162b8baffa3SSridevi Ramesh } 163b8baffa3SSridevi Ramesh } 164b8baffa3SSridevi Ramesh else 165b8baffa3SSridevi Ramesh { 166b8baffa3SSridevi Ramesh FruFieldTypeMap.insert(fruOemFieldTypes.begin(), 167b8baffa3SSridevi Ramesh fruOemFieldTypes.end()); 168b8baffa3SSridevi Ramesh } 169b8baffa3SSridevi Ramesh if (tlv->type == PLDM_OEM_FRU_FIELD_TYPE_IANA) 170b8baffa3SSridevi Ramesh { 171b8baffa3SSridevi Ramesh fruFieldValue = 172b8baffa3SSridevi Ramesh fruFieldParserU32(tlv->value, tlv->length); 173b8baffa3SSridevi Ramesh } 174c50c6cd7SSridevi Ramesh else if (tlv->type != 2) 175b8baffa3SSridevi Ramesh { 176c50c6cd7SSridevi Ramesh fruFieldValue = 177c50c6cd7SSridevi Ramesh fruFieldIPZParser(tlv->value, tlv->length); 178b8baffa3SSridevi Ramesh } 179b8baffa3SSridevi Ramesh else 180b8baffa3SSridevi Ramesh { 181b8baffa3SSridevi Ramesh fruFieldValue = 182b8baffa3SSridevi Ramesh fruFieldValuestring(tlv->value, tlv->length); 183b8baffa3SSridevi Ramesh } 184dd04990dSSridevi Ramesh frudata["FRU Field Type"] = 185dd04990dSSridevi Ramesh typeToString(FruFieldTypeMap, tlv->type); 186dd04990dSSridevi Ramesh frudata["FRU Field Length"] = (int)(tlv->length); 187dd04990dSSridevi Ramesh frudata["FRU Field Value"] = fruFieldValue; 188dd04990dSSridevi Ramesh frufielddata.emplace_back(frudata); 189c50c6cd7SSridevi Ramesh 190c50c6cd7SSridevi Ramesh #endif 191c50c6cd7SSridevi Ramesh } 1925bdde3a4SJohn Wang p += sizeof(pldm_fru_record_tlv) - 1 + tlv->length; 1935bdde3a4SJohn Wang } 194dd04990dSSridevi Ramesh frutable.emplace_back(frufielddata); 1955bdde3a4SJohn Wang } 196dd04990dSSridevi Ramesh pldmtool::helper::DisplayInJson(frutable); 1975bdde3a4SJohn Wang } 1985bdde3a4SJohn Wang 1995bdde3a4SJohn Wang private: 2005bdde3a4SJohn Wang const uint8_t* table; 2015bdde3a4SJohn Wang size_t table_size; 2025bdde3a4SJohn Wang 2035bdde3a4SJohn Wang bool isTableEnd(const uint8_t* p) 2045bdde3a4SJohn Wang { 2055bdde3a4SJohn Wang auto offset = p - table; 2065bdde3a4SJohn Wang return (table_size - offset) <= 7; 2075bdde3a4SJohn Wang } 2085bdde3a4SJohn Wang 209b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> fruEncodingType{ 2105bdde3a4SJohn Wang {PLDM_FRU_ENCODING_UNSPECIFIED, "Unspecified"}, 2115bdde3a4SJohn Wang {PLDM_FRU_ENCODING_ASCII, "ASCII"}, 2125bdde3a4SJohn Wang {PLDM_FRU_ENCODING_UTF8, "UTF8"}, 2135bdde3a4SJohn Wang {PLDM_FRU_ENCODING_UTF16, "UTF16"}, 2145bdde3a4SJohn Wang {PLDM_FRU_ENCODING_UTF16LE, "UTF16LE"}, 2155bdde3a4SJohn Wang {PLDM_FRU_ENCODING_UTF16BE, "UTF16BE"}}; 2165bdde3a4SJohn Wang 217b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> fruGeneralFieldTypes{ 218b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_CHASSIS, "Chassis"}, 219b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_MODEL, "Model"}, 220b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_PN, "Part Number"}, 221b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_SN, "Serial Number"}, 222b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_MANUFAC, "Manufacturer"}, 223b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_MANUFAC_DATE, "Manufacture Date"}, 224b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_VENDOR, "Vendor"}, 225b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_NAME, "Name"}, 226b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_SKU, "SKU"}, 227b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_VERSION, "Version"}, 228b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_ASSET_TAG, "Asset Tag"}, 229b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_DESC, "Description"}, 230b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_EC_LVL, "Engineering Change Level"}, 231b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_OTHER, "Other Information"}, 232b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_IANA, "Vendor IANA"}}; 233b8baffa3SSridevi Ramesh 234b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> fruRecordTypes{ 2355bdde3a4SJohn Wang {PLDM_FRU_RECORD_TYPE_GENERAL, "General"}, 2365bdde3a4SJohn Wang {PLDM_FRU_RECORD_TYPE_OEM, "OEM"}}; 2375bdde3a4SJohn Wang 238b8baffa3SSridevi Ramesh #ifdef OEM_IBM 239b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> fruOemFieldTypes{ 240b8baffa3SSridevi Ramesh {PLDM_OEM_FRU_FIELD_TYPE_IANA, "Vendor IANA"}, 241b8baffa3SSridevi Ramesh {PLDM_OEM_FRU_FIELD_TYPE_RT, "RT"}, 242b8baffa3SSridevi Ramesh {PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE, "Location Code"}}; 243b8baffa3SSridevi Ramesh 244b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> VINIFieldTypes{ 245b8baffa3SSridevi Ramesh {2, "RT"}, {3, "B3"}, {4, "B4"}, {5, "B7"}, {6, "CC"}, {7, "CE"}, 246b8baffa3SSridevi Ramesh {8, "CT"}, {9, "DR"}, {10, "FG"}, {11, "FN"}, {12, "HE"}, {13, "HW"}, 247b8baffa3SSridevi Ramesh {14, "HX"}, {15, "PN"}, {16, "SN"}, {17, "TS"}, {18, "VZ"}}; 248b8baffa3SSridevi Ramesh 249b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> VSYSFieldTypes{ 250b8baffa3SSridevi Ramesh {2, "RT"}, {3, "BR"}, {4, "DR"}, {5, "FV"}, {6, "ID"}, 251b8baffa3SSridevi Ramesh {7, "MN"}, {8, "NN"}, {9, "RB"}, {10, "RG"}, {11, "SE"}, 252b8baffa3SSridevi Ramesh {12, "SG"}, {13, "SU"}, {14, "TM"}, {15, "TN"}, {16, "WN"}}; 253b8baffa3SSridevi Ramesh 254b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> LXR0FieldTypes{ 255b8baffa3SSridevi Ramesh {2, "RT"}, {3, "LX"}, {4, "VZ"}}; 256b8baffa3SSridevi Ramesh 257b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> VW10FieldTypes{ 258b8baffa3SSridevi Ramesh {2, "RT"}, {3, "DR"}, {4, "GD"}}; 259b8baffa3SSridevi Ramesh 260b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> VR10FieldTypes{ 261b8baffa3SSridevi Ramesh {2, "RT"}, {3, "DC"}, {4, "DR"}, {5, "FL"}, {6, "WA"}}; 262b8baffa3SSridevi Ramesh 263b8baffa3SSridevi Ramesh static inline const std::map<std::string, 264b8baffa3SSridevi Ramesh const std::map<uint8_t, std::string>> 265b8baffa3SSridevi Ramesh populateMaps{{"VINI", VINIFieldTypes}, 266b8baffa3SSridevi Ramesh {"VSYS", VSYSFieldTypes}, 267b8baffa3SSridevi Ramesh {"LXR0", LXR0FieldTypes}, 268b8baffa3SSridevi Ramesh {"VWX10", VW10FieldTypes}, 269b8baffa3SSridevi Ramesh {"VR10", VR10FieldTypes}}; 270b8baffa3SSridevi Ramesh #endif 271b8baffa3SSridevi Ramesh 272b8baffa3SSridevi Ramesh std::string typeToString(std::map<uint8_t, std::string> typeMap, 2735bdde3a4SJohn Wang uint8_t type) 2745bdde3a4SJohn Wang { 2755bdde3a4SJohn Wang auto typeString = std::to_string(type); 2765bdde3a4SJohn Wang try 2775bdde3a4SJohn Wang { 278b8baffa3SSridevi Ramesh return std::string(typeMap.at(type)) + "(" + typeString + ")"; 2795bdde3a4SJohn Wang } 2805bdde3a4SJohn Wang catch (const std::out_of_range& e) 2815bdde3a4SJohn Wang { 2825bdde3a4SJohn Wang return typeString; 2835bdde3a4SJohn Wang } 2845bdde3a4SJohn Wang } 2855bdde3a4SJohn Wang 286b8baffa3SSridevi Ramesh std::string fruFieldValuestring(const uint8_t* value, uint8_t length) 2875bdde3a4SJohn Wang { 2885bdde3a4SJohn Wang return std::string(reinterpret_cast<const char*>(value), length); 2895bdde3a4SJohn Wang } 2905bdde3a4SJohn Wang 2915bdde3a4SJohn Wang static std::string fruFieldParserU32(const uint8_t* value, uint8_t length) 2925bdde3a4SJohn Wang { 2935bdde3a4SJohn Wang assert(length == 4); 2945bdde3a4SJohn Wang uint32_t v; 2955bdde3a4SJohn Wang std::memcpy(&v, value, length); 2965bdde3a4SJohn Wang return std::to_string(le32toh(v)); 2975bdde3a4SJohn Wang } 2985bdde3a4SJohn Wang 299b8baffa3SSridevi Ramesh static std::string fruFieldParserTimestamp(const uint8_t*, uint8_t) 3005bdde3a4SJohn Wang { 301b8baffa3SSridevi Ramesh return std::string("TODO"); 302b8baffa3SSridevi Ramesh } 3035bdde3a4SJohn Wang 304b8baffa3SSridevi Ramesh static std::string fruFieldIPZParser(const uint8_t* value, uint8_t length) 305b8baffa3SSridevi Ramesh { 306b8baffa3SSridevi Ramesh std::ostringstream tempStream; 307b8baffa3SSridevi Ramesh for (int i = 0; i < int(length); ++i) 308b8baffa3SSridevi Ramesh { 309b8baffa3SSridevi Ramesh tempStream << "0x" << std::setfill('0') << std::setw(2) << std::hex 310b8baffa3SSridevi Ramesh << (unsigned)value[i] << " "; 311b8baffa3SSridevi Ramesh } 312b8baffa3SSridevi Ramesh return tempStream.str(); 3135bdde3a4SJohn Wang } 3145bdde3a4SJohn Wang }; 3155bdde3a4SJohn Wang 3165bdde3a4SJohn Wang class GetFRURecordByOption : public CommandInterface 3175bdde3a4SJohn Wang { 3185bdde3a4SJohn Wang public: 3195bdde3a4SJohn Wang ~GetFRURecordByOption() = default; 3205bdde3a4SJohn Wang GetFRURecordByOption() = delete; 3215bdde3a4SJohn Wang GetFRURecordByOption(const GetFRURecordByOption&) = delete; 3225bdde3a4SJohn Wang GetFRURecordByOption(GetFruRecordTableMetadata&&) = delete; 3235bdde3a4SJohn Wang GetFRURecordByOption& operator=(const GetFRURecordByOption&) = delete; 3245bdde3a4SJohn Wang GetFRURecordByOption& operator=(GetFRURecordByOption&&) = delete; 3255bdde3a4SJohn Wang 3265bdde3a4SJohn Wang explicit GetFRURecordByOption(const char* type, const char* name, 3275bdde3a4SJohn Wang CLI::App* app) : 3285bdde3a4SJohn Wang CommandInterface(type, name, app) 3295bdde3a4SJohn Wang { 3305bdde3a4SJohn Wang app->add_option("-i, --identifier", recordSetIdentifier, 3315bdde3a4SJohn Wang "Record Set Identifier\n" 3325bdde3a4SJohn Wang "Possible values: {All record sets = 0, Specific " 3335bdde3a4SJohn Wang "record set = 1 – 65535}") 3345bdde3a4SJohn Wang ->required(); 3355bdde3a4SJohn Wang app->add_option("-r, --record", recordType, 3365bdde3a4SJohn Wang "Record Type\n" 3375bdde3a4SJohn Wang "Possible values: {All record types = 0, Specific " 3385bdde3a4SJohn Wang "record types = 1 – 255}") 3395bdde3a4SJohn Wang ->required(); 3405bdde3a4SJohn Wang app->add_option("-f, --field", fieldType, 3415bdde3a4SJohn Wang "Field Type\n" 3425bdde3a4SJohn Wang "Possible values: {All record field types = 0, " 3435bdde3a4SJohn Wang "Specific field types = 1 – 15}") 3445bdde3a4SJohn Wang ->required(); 3455bdde3a4SJohn Wang } 3465bdde3a4SJohn Wang 3475bdde3a4SJohn Wang std::pair<int, std::vector<uint8_t>> createRequestMsg() override 3485bdde3a4SJohn Wang { 3495bdde3a4SJohn Wang if (fieldType != 0 && recordType == 0) 3505bdde3a4SJohn Wang { 3515bdde3a4SJohn Wang throw std::invalid_argument("if field type is non-zero, the record " 3525bdde3a4SJohn Wang "type shall also be non-zero"); 3535bdde3a4SJohn Wang } 354b8baffa3SSridevi Ramesh if (recordType == 254 && (fieldType > 2 && fieldType < 254)) 355b8baffa3SSridevi Ramesh { 356b8baffa3SSridevi Ramesh throw std::invalid_argument( 357b8baffa3SSridevi Ramesh "GetFRURecordByOption is not supported for recordType : 254 " 358b8baffa3SSridevi Ramesh "and fieldType > 2"); 359b8baffa3SSridevi Ramesh } 3605bdde3a4SJohn Wang 3615bdde3a4SJohn Wang auto payloadLength = sizeof(pldm_get_fru_record_by_option_req); 3625bdde3a4SJohn Wang 3635bdde3a4SJohn Wang std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + payloadLength, 3645bdde3a4SJohn Wang 0); 3655bdde3a4SJohn Wang auto reqMsg = reinterpret_cast<pldm_msg*>(requestMsg.data()); 3665bdde3a4SJohn Wang 3675bdde3a4SJohn Wang auto rc = encode_get_fru_record_by_option_req( 3685bdde3a4SJohn Wang instanceId, 0 /* DataTransferHandle */, 0 /* FRUTableHandle */, 3695bdde3a4SJohn Wang recordSetIdentifier, recordType, fieldType, PLDM_GET_FIRSTPART, 3705bdde3a4SJohn Wang reqMsg, payloadLength); 3715bdde3a4SJohn Wang 3725bdde3a4SJohn Wang return {rc, requestMsg}; 3735bdde3a4SJohn Wang } 3745bdde3a4SJohn Wang 3755bdde3a4SJohn Wang void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override 3765bdde3a4SJohn Wang { 3775bdde3a4SJohn Wang uint8_t cc; 3785bdde3a4SJohn Wang uint32_t dataTransferHandle; 3795bdde3a4SJohn Wang uint8_t transferFlag; 3805bdde3a4SJohn Wang variable_field fruData; 3815bdde3a4SJohn Wang 3825bdde3a4SJohn Wang auto rc = decode_get_fru_record_by_option_resp( 3835bdde3a4SJohn Wang responsePtr, payloadLength, &cc, &dataTransferHandle, &transferFlag, 3845bdde3a4SJohn Wang &fruData); 3855bdde3a4SJohn Wang 3865bdde3a4SJohn Wang if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS) 3875bdde3a4SJohn Wang { 3885bdde3a4SJohn Wang std::cerr << "Response Message Error: " 3895bdde3a4SJohn Wang << "rc=" << rc << ",cc=" << (int)cc << std::endl; 3905bdde3a4SJohn Wang return; 3915bdde3a4SJohn Wang } 3925bdde3a4SJohn Wang 3935bdde3a4SJohn Wang FRUTablePrint tablePrint(fruData.ptr, fruData.length); 3945bdde3a4SJohn Wang tablePrint.print(); 3955bdde3a4SJohn Wang } 3965bdde3a4SJohn Wang 3975bdde3a4SJohn Wang private: 3985bdde3a4SJohn Wang uint16_t recordSetIdentifier; 3995bdde3a4SJohn Wang uint8_t recordType; 4005bdde3a4SJohn Wang uint8_t fieldType; 4015bdde3a4SJohn Wang }; 4025bdde3a4SJohn Wang 403bd9440bdSSridevi Ramesh class GetFruRecordTable : public CommandInterface 404bd9440bdSSridevi Ramesh { 405bd9440bdSSridevi Ramesh public: 406bd9440bdSSridevi Ramesh ~GetFruRecordTable() = default; 407bd9440bdSSridevi Ramesh GetFruRecordTable() = delete; 408bd9440bdSSridevi Ramesh GetFruRecordTable(const GetFruRecordTable&) = delete; 409bd9440bdSSridevi Ramesh GetFruRecordTable(GetFruRecordTable&&) = default; 410bd9440bdSSridevi Ramesh GetFruRecordTable& operator=(const GetFruRecordTable&) = delete; 411bd9440bdSSridevi Ramesh GetFruRecordTable& operator=(GetFruRecordTable&&) = default; 412bd9440bdSSridevi Ramesh 413bd9440bdSSridevi Ramesh using CommandInterface::CommandInterface; 414bd9440bdSSridevi Ramesh std::pair<int, std::vector<uint8_t>> createRequestMsg() override 415bd9440bdSSridevi Ramesh { 416bd9440bdSSridevi Ramesh std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 417bd9440bdSSridevi Ramesh PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES); 418bd9440bdSSridevi Ramesh auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 419bd9440bdSSridevi Ramesh 420bd9440bdSSridevi Ramesh auto rc = encode_get_fru_record_table_req( 421*71689b8bSPotin Lai instanceId, 0, PLDM_GET_FIRSTPART, request, 422bd9440bdSSridevi Ramesh requestMsg.size() - sizeof(pldm_msg_hdr)); 423bd9440bdSSridevi Ramesh return {rc, requestMsg}; 424bd9440bdSSridevi Ramesh } 425bd9440bdSSridevi Ramesh void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override 426bd9440bdSSridevi Ramesh { 427bd9440bdSSridevi Ramesh uint8_t cc = 0; 428bd9440bdSSridevi Ramesh uint32_t next_data_transfer_handle = 0; 429bd9440bdSSridevi Ramesh uint8_t transfer_flag = 0; 430bd9440bdSSridevi Ramesh size_t fru_record_table_length = 0; 431bd9440bdSSridevi Ramesh std::vector<uint8_t> fru_record_table_data(payloadLength); 432bd9440bdSSridevi Ramesh 433bd9440bdSSridevi Ramesh auto rc = decode_get_fru_record_table_resp( 434bd9440bdSSridevi Ramesh responsePtr, payloadLength, &cc, &next_data_transfer_handle, 435bd9440bdSSridevi Ramesh &transfer_flag, fru_record_table_data.data(), 436bd9440bdSSridevi Ramesh &fru_record_table_length); 437bd9440bdSSridevi Ramesh 438bd9440bdSSridevi Ramesh if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS) 439bd9440bdSSridevi Ramesh { 440bd9440bdSSridevi Ramesh std::cerr << "Response Message Error: " 441bd9440bdSSridevi Ramesh << "rc=" << rc << ",cc=" << (int)cc << std::endl; 442bd9440bdSSridevi Ramesh return; 443bd9440bdSSridevi Ramesh } 444bd9440bdSSridevi Ramesh 445bd9440bdSSridevi Ramesh FRUTablePrint tablePrint(fru_record_table_data.data(), 446bd9440bdSSridevi Ramesh fru_record_table_length); 447bd9440bdSSridevi Ramesh tablePrint.print(); 448bd9440bdSSridevi Ramesh } 449bd9440bdSSridevi Ramesh }; 450bd9440bdSSridevi Ramesh 451f7f5da97SDeepak Kodihalli void registerCommand(CLI::App& app) 452f7f5da97SDeepak Kodihalli { 453f7f5da97SDeepak Kodihalli auto fru = app.add_subcommand("fru", "FRU type command"); 454f7f5da97SDeepak Kodihalli fru->require_subcommand(1); 455f7f5da97SDeepak Kodihalli auto getFruRecordTableMetadata = fru->add_subcommand( 456f7f5da97SDeepak Kodihalli "GetFruRecordTableMetadata", "get FRU record table metadata"); 457f7f5da97SDeepak Kodihalli commands.push_back(std::make_unique<GetFruRecordTableMetadata>( 458f7f5da97SDeepak Kodihalli "fru", "GetFruRecordTableMetadata", getFruRecordTableMetadata)); 4595bdde3a4SJohn Wang 4605bdde3a4SJohn Wang auto getFRURecordByOption = 4615bdde3a4SJohn Wang fru->add_subcommand("GetFRURecordByOption", "get FRU Record By Option"); 4625bdde3a4SJohn Wang commands.push_back(std::make_unique<GetFRURecordByOption>( 4635bdde3a4SJohn Wang "fru", "GetFRURecordByOption", getFRURecordByOption)); 464bd9440bdSSridevi Ramesh 465bd9440bdSSridevi Ramesh auto getFruRecordTable = 466bd9440bdSSridevi Ramesh fru->add_subcommand("GetFruRecordTable", "get FRU Record Table"); 467bd9440bdSSridevi Ramesh commands.push_back(std::make_unique<GetFruRecordTable>( 468bd9440bdSSridevi Ramesh "fru", "GetFruRecordTable", getFruRecordTable)); 469f7f5da97SDeepak Kodihalli } 470f7f5da97SDeepak Kodihalli 471f7f5da97SDeepak Kodihalli } // namespace fru 472f7f5da97SDeepak Kodihalli 473f7f5da97SDeepak Kodihalli } // namespace pldmtool 474