1f7f5da97SDeepak Kodihalli #include "pldm_fru_cmd.hpp" 2f7f5da97SDeepak Kodihalli 3f7f5da97SDeepak Kodihalli #include "pldm_cmd_helper.hpp" 4f7f5da97SDeepak Kodihalli 5*b8baffa3SSridevi Ramesh #ifdef OEM_IBM 6*b8baffa3SSridevi Ramesh #include "oem/ibm/libpldm/fru.h" 7*b8baffa3SSridevi Ramesh #endif 8*b8baffa3SSridevi 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 } 70f7f5da97SDeepak Kodihalli std::cout << "FRUDATAMajorVersion : " 71f7f5da97SDeepak Kodihalli << static_cast<uint32_t>(fru_data_major_version) << std::endl; 72f7f5da97SDeepak Kodihalli std::cout << "FRUDATAMinorVersion : " 73f7f5da97SDeepak Kodihalli << static_cast<uint32_t>(fru_data_minor_version) << std::endl; 74f7f5da97SDeepak Kodihalli std::cout << "FRUTableMaximumSize : " << fru_table_maximum_size 75f7f5da97SDeepak Kodihalli << std::endl; 76f7f5da97SDeepak Kodihalli std::cout << "FRUTableLength : " << fru_table_length << std::endl; 77f7f5da97SDeepak Kodihalli std::cout << "Total number of Record Set Identifiers in table : " 78f7f5da97SDeepak Kodihalli << total_record_set_identifiers << std::endl; 79f7f5da97SDeepak Kodihalli std::cout << "Total number of records in table : " 80f7f5da97SDeepak Kodihalli << total_table_records << std::endl; 81f7f5da97SDeepak Kodihalli std::cout << "FRU DATAStructureTableIntegrityChecksum : " << checksum 82f7f5da97SDeepak Kodihalli << std::endl; 83f7f5da97SDeepak Kodihalli } 84f7f5da97SDeepak Kodihalli }; 85f7f5da97SDeepak Kodihalli 865bdde3a4SJohn Wang class FRUTablePrint 875bdde3a4SJohn Wang { 885bdde3a4SJohn Wang public: 895bdde3a4SJohn Wang explicit FRUTablePrint(const uint8_t* table, size_t table_size) : 905bdde3a4SJohn Wang table(table), table_size(table_size) 915bdde3a4SJohn Wang {} 925bdde3a4SJohn Wang 935bdde3a4SJohn Wang void print() 945bdde3a4SJohn Wang { 955bdde3a4SJohn Wang auto p = table; 965bdde3a4SJohn Wang while (!isTableEnd(p)) 975bdde3a4SJohn Wang { 985bdde3a4SJohn Wang auto record = 995bdde3a4SJohn Wang reinterpret_cast<const pldm_fru_record_data_format*>(p); 1005bdde3a4SJohn Wang std::cout << "FRU Record Set Identifier: " 1015bdde3a4SJohn Wang << (int)le16toh(record->record_set_id) << std::endl; 1025bdde3a4SJohn Wang std::cout << "FRU Record Type: " 1035bdde3a4SJohn Wang << typeToString(fruRecordTypes, record->record_type) 1045bdde3a4SJohn Wang << std::endl; 1055bdde3a4SJohn Wang std::cout << "Number of FRU fields: " << (int)record->num_fru_fields 1065bdde3a4SJohn Wang << std::endl; 1075bdde3a4SJohn Wang std::cout << "Encoding Type for FRU fields: " 1085bdde3a4SJohn Wang << typeToString(fruEncodingType, record->encoding_type) 1095bdde3a4SJohn Wang << std::endl; 1105bdde3a4SJohn Wang 1115bdde3a4SJohn Wang p += sizeof(pldm_fru_record_data_format) - 1125bdde3a4SJohn Wang sizeof(pldm_fru_record_tlv); 113*b8baffa3SSridevi Ramesh 114*b8baffa3SSridevi Ramesh auto isIPZ = false; 115*b8baffa3SSridevi Ramesh std::map<uint8_t, std::string> FruFieldTypeMap; 116*b8baffa3SSridevi Ramesh std::string fruFieldValue; 117*b8baffa3SSridevi Ramesh 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); 121*b8baffa3SSridevi Ramesh if (record->record_type == PLDM_FRU_RECORD_TYPE_GENERAL) 1225bdde3a4SJohn Wang { 123*b8baffa3SSridevi Ramesh FruFieldTypeMap.insert(fruGeneralFieldTypes.begin(), 124*b8baffa3SSridevi Ramesh fruGeneralFieldTypes.end()); 125*b8baffa3SSridevi Ramesh if (tlv->type == PLDM_FRU_FIELD_TYPE_IANA) 126*b8baffa3SSridevi Ramesh { 127*b8baffa3SSridevi Ramesh fruFieldValue = 128*b8baffa3SSridevi Ramesh fruFieldParserU32(tlv->value, tlv->length); 1295bdde3a4SJohn Wang } 130*b8baffa3SSridevi Ramesh else if (tlv->type == PLDM_FRU_FIELD_TYPE_MANUFAC_DATE) 131*b8baffa3SSridevi Ramesh { 132*b8baffa3SSridevi Ramesh fruFieldValue = 133*b8baffa3SSridevi Ramesh fruFieldParserTimestamp(tlv->value, tlv->length); 134*b8baffa3SSridevi Ramesh } 135*b8baffa3SSridevi Ramesh } 136*b8baffa3SSridevi Ramesh else 137*b8baffa3SSridevi Ramesh { 138*b8baffa3SSridevi Ramesh #ifdef OEM_IBM 139*b8baffa3SSridevi Ramesh if (tlv->type == PLDM_OEM_FRU_FIELD_TYPE_RT) 140*b8baffa3SSridevi Ramesh { 141*b8baffa3SSridevi Ramesh auto oemIPZValue = 142*b8baffa3SSridevi Ramesh fruFieldValuestring(tlv->value, tlv->length); 143*b8baffa3SSridevi Ramesh 144*b8baffa3SSridevi Ramesh if (populateMaps.find(oemIPZValue) != 145*b8baffa3SSridevi Ramesh populateMaps.end()) 146*b8baffa3SSridevi Ramesh { 147*b8baffa3SSridevi Ramesh isIPZ = true; 148*b8baffa3SSridevi Ramesh const std::map<uint8_t, std::string> IPZTypes = 149*b8baffa3SSridevi Ramesh populateMaps.at(oemIPZValue); 150*b8baffa3SSridevi Ramesh FruFieldTypeMap.insert(IPZTypes.begin(), 151*b8baffa3SSridevi Ramesh IPZTypes.end()); 152*b8baffa3SSridevi Ramesh } 153*b8baffa3SSridevi Ramesh } 154*b8baffa3SSridevi Ramesh else 155*b8baffa3SSridevi Ramesh { 156*b8baffa3SSridevi Ramesh FruFieldTypeMap.insert(fruOemFieldTypes.begin(), 157*b8baffa3SSridevi Ramesh fruOemFieldTypes.end()); 158*b8baffa3SSridevi Ramesh } 159*b8baffa3SSridevi Ramesh if (tlv->type == PLDM_OEM_FRU_FIELD_TYPE_IANA) 160*b8baffa3SSridevi Ramesh { 161*b8baffa3SSridevi Ramesh fruFieldValue = 162*b8baffa3SSridevi Ramesh fruFieldParserU32(tlv->value, tlv->length); 163*b8baffa3SSridevi Ramesh } 164*b8baffa3SSridevi Ramesh #endif 165*b8baffa3SSridevi Ramesh } 166*b8baffa3SSridevi Ramesh 167*b8baffa3SSridevi Ramesh if (isIPZ && (tlv->type != 2)) 168*b8baffa3SSridevi Ramesh { 169*b8baffa3SSridevi Ramesh fruFieldValue = fruFieldIPZParser(tlv->value, tlv->length); 170*b8baffa3SSridevi Ramesh } 171*b8baffa3SSridevi Ramesh else 172*b8baffa3SSridevi Ramesh { 173*b8baffa3SSridevi Ramesh fruFieldValue = 174*b8baffa3SSridevi Ramesh fruFieldValuestring(tlv->value, tlv->length); 175*b8baffa3SSridevi Ramesh } 176*b8baffa3SSridevi Ramesh 177*b8baffa3SSridevi Ramesh std::cout << "\tFRU Field Type: " 178*b8baffa3SSridevi Ramesh << typeToString(FruFieldTypeMap, tlv->type) 179*b8baffa3SSridevi Ramesh << std::endl; 180*b8baffa3SSridevi Ramesh std::cout << "\tFRU Field Length: " << (int)(tlv->length) 181*b8baffa3SSridevi Ramesh << std::endl; 182*b8baffa3SSridevi Ramesh std::cout << "\tFRU Field Value: " << fruFieldValue 183*b8baffa3SSridevi Ramesh << std::endl; 184*b8baffa3SSridevi Ramesh 1855bdde3a4SJohn Wang p += sizeof(pldm_fru_record_tlv) - 1 + tlv->length; 1865bdde3a4SJohn Wang } 1875bdde3a4SJohn Wang } 1885bdde3a4SJohn Wang } 1895bdde3a4SJohn Wang 1905bdde3a4SJohn Wang private: 1915bdde3a4SJohn Wang const uint8_t* table; 1925bdde3a4SJohn Wang size_t table_size; 1935bdde3a4SJohn Wang 1945bdde3a4SJohn Wang bool isTableEnd(const uint8_t* p) 1955bdde3a4SJohn Wang { 1965bdde3a4SJohn Wang auto offset = p - table; 1975bdde3a4SJohn Wang return (table_size - offset) <= 7; 1985bdde3a4SJohn Wang } 1995bdde3a4SJohn Wang 200*b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> fruEncodingType{ 2015bdde3a4SJohn Wang {PLDM_FRU_ENCODING_UNSPECIFIED, "Unspecified"}, 2025bdde3a4SJohn Wang {PLDM_FRU_ENCODING_ASCII, "ASCII"}, 2035bdde3a4SJohn Wang {PLDM_FRU_ENCODING_UTF8, "UTF8"}, 2045bdde3a4SJohn Wang {PLDM_FRU_ENCODING_UTF16, "UTF16"}, 2055bdde3a4SJohn Wang {PLDM_FRU_ENCODING_UTF16LE, "UTF16LE"}, 2065bdde3a4SJohn Wang {PLDM_FRU_ENCODING_UTF16BE, "UTF16BE"}}; 2075bdde3a4SJohn Wang 208*b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> fruGeneralFieldTypes{ 209*b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_CHASSIS, "Chassis"}, 210*b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_MODEL, "Model"}, 211*b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_PN, "Part Number"}, 212*b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_SN, "Serial Number"}, 213*b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_MANUFAC, "Manufacturer"}, 214*b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_MANUFAC_DATE, "Manufacture Date"}, 215*b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_VENDOR, "Vendor"}, 216*b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_NAME, "Name"}, 217*b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_SKU, "SKU"}, 218*b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_VERSION, "Version"}, 219*b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_ASSET_TAG, "Asset Tag"}, 220*b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_DESC, "Description"}, 221*b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_EC_LVL, "Engineering Change Level"}, 222*b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_OTHER, "Other Information"}, 223*b8baffa3SSridevi Ramesh {PLDM_FRU_FIELD_TYPE_IANA, "Vendor IANA"}}; 224*b8baffa3SSridevi Ramesh 225*b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> fruRecordTypes{ 2265bdde3a4SJohn Wang {PLDM_FRU_RECORD_TYPE_GENERAL, "General"}, 2275bdde3a4SJohn Wang {PLDM_FRU_RECORD_TYPE_OEM, "OEM"}}; 2285bdde3a4SJohn Wang 229*b8baffa3SSridevi Ramesh #ifdef OEM_IBM 230*b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> fruOemFieldTypes{ 231*b8baffa3SSridevi Ramesh {PLDM_OEM_FRU_FIELD_TYPE_IANA, "Vendor IANA"}, 232*b8baffa3SSridevi Ramesh {PLDM_OEM_FRU_FIELD_TYPE_RT, "RT"}, 233*b8baffa3SSridevi Ramesh {PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE, "Location Code"}}; 234*b8baffa3SSridevi Ramesh 235*b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> VINIFieldTypes{ 236*b8baffa3SSridevi Ramesh {2, "RT"}, {3, "B3"}, {4, "B4"}, {5, "B7"}, {6, "CC"}, {7, "CE"}, 237*b8baffa3SSridevi Ramesh {8, "CT"}, {9, "DR"}, {10, "FG"}, {11, "FN"}, {12, "HE"}, {13, "HW"}, 238*b8baffa3SSridevi Ramesh {14, "HX"}, {15, "PN"}, {16, "SN"}, {17, "TS"}, {18, "VZ"}}; 239*b8baffa3SSridevi Ramesh 240*b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> VSYSFieldTypes{ 241*b8baffa3SSridevi Ramesh {2, "RT"}, {3, "BR"}, {4, "DR"}, {5, "FV"}, {6, "ID"}, 242*b8baffa3SSridevi Ramesh {7, "MN"}, {8, "NN"}, {9, "RB"}, {10, "RG"}, {11, "SE"}, 243*b8baffa3SSridevi Ramesh {12, "SG"}, {13, "SU"}, {14, "TM"}, {15, "TN"}, {16, "WN"}}; 244*b8baffa3SSridevi Ramesh 245*b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> LXR0FieldTypes{ 246*b8baffa3SSridevi Ramesh {2, "RT"}, {3, "LX"}, {4, "VZ"}}; 247*b8baffa3SSridevi Ramesh 248*b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> VW10FieldTypes{ 249*b8baffa3SSridevi Ramesh {2, "RT"}, {3, "DR"}, {4, "GD"}}; 250*b8baffa3SSridevi Ramesh 251*b8baffa3SSridevi Ramesh static inline const std::map<uint8_t, std::string> VR10FieldTypes{ 252*b8baffa3SSridevi Ramesh {2, "RT"}, {3, "DC"}, {4, "DR"}, {5, "FL"}, {6, "WA"}}; 253*b8baffa3SSridevi Ramesh 254*b8baffa3SSridevi Ramesh static inline const std::map<std::string, 255*b8baffa3SSridevi Ramesh const std::map<uint8_t, std::string>> 256*b8baffa3SSridevi Ramesh populateMaps{{"VINI", VINIFieldTypes}, 257*b8baffa3SSridevi Ramesh {"VSYS", VSYSFieldTypes}, 258*b8baffa3SSridevi Ramesh {"LXR0", LXR0FieldTypes}, 259*b8baffa3SSridevi Ramesh {"VWX10", VW10FieldTypes}, 260*b8baffa3SSridevi Ramesh {"VR10", VR10FieldTypes}}; 261*b8baffa3SSridevi Ramesh #endif 262*b8baffa3SSridevi Ramesh 263*b8baffa3SSridevi Ramesh std::string typeToString(std::map<uint8_t, std::string> typeMap, 2645bdde3a4SJohn Wang uint8_t type) 2655bdde3a4SJohn Wang { 2665bdde3a4SJohn Wang auto typeString = std::to_string(type); 2675bdde3a4SJohn Wang try 2685bdde3a4SJohn Wang { 269*b8baffa3SSridevi Ramesh return std::string(typeMap.at(type)) + "(" + typeString + ")"; 2705bdde3a4SJohn Wang } 2715bdde3a4SJohn Wang catch (const std::out_of_range& e) 2725bdde3a4SJohn Wang { 2735bdde3a4SJohn Wang return typeString; 2745bdde3a4SJohn Wang } 2755bdde3a4SJohn Wang } 2765bdde3a4SJohn Wang 277*b8baffa3SSridevi Ramesh std::string fruFieldValuestring(const uint8_t* value, uint8_t length) 2785bdde3a4SJohn Wang { 2795bdde3a4SJohn Wang return std::string(reinterpret_cast<const char*>(value), length); 2805bdde3a4SJohn Wang } 2815bdde3a4SJohn Wang 2825bdde3a4SJohn Wang static std::string fruFieldParserU32(const uint8_t* value, uint8_t length) 2835bdde3a4SJohn Wang { 2845bdde3a4SJohn Wang assert(length == 4); 2855bdde3a4SJohn Wang uint32_t v; 2865bdde3a4SJohn Wang std::memcpy(&v, value, length); 2875bdde3a4SJohn Wang return std::to_string(le32toh(v)); 2885bdde3a4SJohn Wang } 2895bdde3a4SJohn Wang 290*b8baffa3SSridevi Ramesh static std::string fruFieldParserTimestamp(const uint8_t*, uint8_t) 2915bdde3a4SJohn Wang { 292*b8baffa3SSridevi Ramesh return std::string("TODO"); 293*b8baffa3SSridevi Ramesh } 2945bdde3a4SJohn Wang 295*b8baffa3SSridevi Ramesh static std::string fruFieldIPZParser(const uint8_t* value, uint8_t length) 296*b8baffa3SSridevi Ramesh { 297*b8baffa3SSridevi Ramesh std::ostringstream tempStream; 298*b8baffa3SSridevi Ramesh for (int i = 0; i < int(length); ++i) 299*b8baffa3SSridevi Ramesh { 300*b8baffa3SSridevi Ramesh tempStream << "0x" << std::setfill('0') << std::setw(2) << std::hex 301*b8baffa3SSridevi Ramesh << (unsigned)value[i] << " "; 302*b8baffa3SSridevi Ramesh } 303*b8baffa3SSridevi Ramesh return tempStream.str(); 3045bdde3a4SJohn Wang } 3055bdde3a4SJohn Wang }; 3065bdde3a4SJohn Wang 3075bdde3a4SJohn Wang class GetFRURecordByOption : public CommandInterface 3085bdde3a4SJohn Wang { 3095bdde3a4SJohn Wang public: 3105bdde3a4SJohn Wang ~GetFRURecordByOption() = default; 3115bdde3a4SJohn Wang GetFRURecordByOption() = delete; 3125bdde3a4SJohn Wang GetFRURecordByOption(const GetFRURecordByOption&) = delete; 3135bdde3a4SJohn Wang GetFRURecordByOption(GetFruRecordTableMetadata&&) = delete; 3145bdde3a4SJohn Wang GetFRURecordByOption& operator=(const GetFRURecordByOption&) = delete; 3155bdde3a4SJohn Wang GetFRURecordByOption& operator=(GetFRURecordByOption&&) = delete; 3165bdde3a4SJohn Wang 3175bdde3a4SJohn Wang explicit GetFRURecordByOption(const char* type, const char* name, 3185bdde3a4SJohn Wang CLI::App* app) : 3195bdde3a4SJohn Wang CommandInterface(type, name, app) 3205bdde3a4SJohn Wang { 3215bdde3a4SJohn Wang app->add_option("-i, --identifier", recordSetIdentifier, 3225bdde3a4SJohn Wang "Record Set Identifier\n" 3235bdde3a4SJohn Wang "Possible values: {All record sets = 0, Specific " 3245bdde3a4SJohn Wang "record set = 1 – 65535}") 3255bdde3a4SJohn Wang ->required(); 3265bdde3a4SJohn Wang app->add_option("-r, --record", recordType, 3275bdde3a4SJohn Wang "Record Type\n" 3285bdde3a4SJohn Wang "Possible values: {All record types = 0, Specific " 3295bdde3a4SJohn Wang "record types = 1 – 255}") 3305bdde3a4SJohn Wang ->required(); 3315bdde3a4SJohn Wang app->add_option("-f, --field", fieldType, 3325bdde3a4SJohn Wang "Field Type\n" 3335bdde3a4SJohn Wang "Possible values: {All record field types = 0, " 3345bdde3a4SJohn Wang "Specific field types = 1 – 15}") 3355bdde3a4SJohn Wang ->required(); 3365bdde3a4SJohn Wang } 3375bdde3a4SJohn Wang 3385bdde3a4SJohn Wang std::pair<int, std::vector<uint8_t>> createRequestMsg() override 3395bdde3a4SJohn Wang { 3405bdde3a4SJohn Wang if (fieldType != 0 && recordType == 0) 3415bdde3a4SJohn Wang { 3425bdde3a4SJohn Wang throw std::invalid_argument("if field type is non-zero, the record " 3435bdde3a4SJohn Wang "type shall also be non-zero"); 3445bdde3a4SJohn Wang } 345*b8baffa3SSridevi Ramesh if (recordType == 254 && (fieldType > 2 && fieldType < 254)) 346*b8baffa3SSridevi Ramesh { 347*b8baffa3SSridevi Ramesh throw std::invalid_argument( 348*b8baffa3SSridevi Ramesh "GetFRURecordByOption is not supported for recordType : 254 " 349*b8baffa3SSridevi Ramesh "and fieldType > 2"); 350*b8baffa3SSridevi Ramesh } 3515bdde3a4SJohn Wang 3525bdde3a4SJohn Wang auto payloadLength = sizeof(pldm_get_fru_record_by_option_req); 3535bdde3a4SJohn Wang 3545bdde3a4SJohn Wang std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + payloadLength, 3555bdde3a4SJohn Wang 0); 3565bdde3a4SJohn Wang auto reqMsg = reinterpret_cast<pldm_msg*>(requestMsg.data()); 3575bdde3a4SJohn Wang 3585bdde3a4SJohn Wang auto rc = encode_get_fru_record_by_option_req( 3595bdde3a4SJohn Wang instanceId, 0 /* DataTransferHandle */, 0 /* FRUTableHandle */, 3605bdde3a4SJohn Wang recordSetIdentifier, recordType, fieldType, PLDM_GET_FIRSTPART, 3615bdde3a4SJohn Wang reqMsg, payloadLength); 3625bdde3a4SJohn Wang 3635bdde3a4SJohn Wang return {rc, requestMsg}; 3645bdde3a4SJohn Wang } 3655bdde3a4SJohn Wang 3665bdde3a4SJohn Wang void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override 3675bdde3a4SJohn Wang { 3685bdde3a4SJohn Wang uint8_t cc; 3695bdde3a4SJohn Wang uint32_t dataTransferHandle; 3705bdde3a4SJohn Wang uint8_t transferFlag; 3715bdde3a4SJohn Wang variable_field fruData; 3725bdde3a4SJohn Wang 3735bdde3a4SJohn Wang auto rc = decode_get_fru_record_by_option_resp( 3745bdde3a4SJohn Wang responsePtr, payloadLength, &cc, &dataTransferHandle, &transferFlag, 3755bdde3a4SJohn Wang &fruData); 3765bdde3a4SJohn Wang 3775bdde3a4SJohn Wang if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS) 3785bdde3a4SJohn Wang { 3795bdde3a4SJohn Wang std::cerr << "Response Message Error: " 3805bdde3a4SJohn Wang << "rc=" << rc << ",cc=" << (int)cc << std::endl; 3815bdde3a4SJohn Wang return; 3825bdde3a4SJohn Wang } 3835bdde3a4SJohn Wang 3845bdde3a4SJohn Wang FRUTablePrint tablePrint(fruData.ptr, fruData.length); 3855bdde3a4SJohn Wang tablePrint.print(); 3865bdde3a4SJohn Wang } 3875bdde3a4SJohn Wang 3885bdde3a4SJohn Wang private: 3895bdde3a4SJohn Wang uint16_t recordSetIdentifier; 3905bdde3a4SJohn Wang uint8_t recordType; 3915bdde3a4SJohn Wang uint8_t fieldType; 3925bdde3a4SJohn Wang }; 3935bdde3a4SJohn Wang 394bd9440bdSSridevi Ramesh class GetFruRecordTable : public CommandInterface 395bd9440bdSSridevi Ramesh { 396bd9440bdSSridevi Ramesh public: 397bd9440bdSSridevi Ramesh ~GetFruRecordTable() = default; 398bd9440bdSSridevi Ramesh GetFruRecordTable() = delete; 399bd9440bdSSridevi Ramesh GetFruRecordTable(const GetFruRecordTable&) = delete; 400bd9440bdSSridevi Ramesh GetFruRecordTable(GetFruRecordTable&&) = default; 401bd9440bdSSridevi Ramesh GetFruRecordTable& operator=(const GetFruRecordTable&) = delete; 402bd9440bdSSridevi Ramesh GetFruRecordTable& operator=(GetFruRecordTable&&) = default; 403bd9440bdSSridevi Ramesh 404bd9440bdSSridevi Ramesh using CommandInterface::CommandInterface; 405bd9440bdSSridevi Ramesh std::pair<int, std::vector<uint8_t>> createRequestMsg() override 406bd9440bdSSridevi Ramesh { 407bd9440bdSSridevi Ramesh std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 408bd9440bdSSridevi Ramesh PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES); 409bd9440bdSSridevi Ramesh auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 410bd9440bdSSridevi Ramesh 411bd9440bdSSridevi Ramesh auto rc = encode_get_fru_record_table_req( 412bd9440bdSSridevi Ramesh instanceId, 0, PLDM_START_AND_END, request, 413bd9440bdSSridevi Ramesh requestMsg.size() - sizeof(pldm_msg_hdr)); 414bd9440bdSSridevi Ramesh return {rc, requestMsg}; 415bd9440bdSSridevi Ramesh } 416bd9440bdSSridevi Ramesh void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override 417bd9440bdSSridevi Ramesh { 418bd9440bdSSridevi Ramesh uint8_t cc = 0; 419bd9440bdSSridevi Ramesh uint32_t next_data_transfer_handle = 0; 420bd9440bdSSridevi Ramesh uint8_t transfer_flag = 0; 421bd9440bdSSridevi Ramesh size_t fru_record_table_length = 0; 422bd9440bdSSridevi Ramesh std::vector<uint8_t> fru_record_table_data(payloadLength); 423bd9440bdSSridevi Ramesh 424bd9440bdSSridevi Ramesh auto rc = decode_get_fru_record_table_resp( 425bd9440bdSSridevi Ramesh responsePtr, payloadLength, &cc, &next_data_transfer_handle, 426bd9440bdSSridevi Ramesh &transfer_flag, fru_record_table_data.data(), 427bd9440bdSSridevi Ramesh &fru_record_table_length); 428bd9440bdSSridevi Ramesh 429bd9440bdSSridevi Ramesh if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS) 430bd9440bdSSridevi Ramesh { 431bd9440bdSSridevi Ramesh std::cerr << "Response Message Error: " 432bd9440bdSSridevi Ramesh << "rc=" << rc << ",cc=" << (int)cc << std::endl; 433bd9440bdSSridevi Ramesh return; 434bd9440bdSSridevi Ramesh } 435bd9440bdSSridevi Ramesh 436bd9440bdSSridevi Ramesh FRUTablePrint tablePrint(fru_record_table_data.data(), 437bd9440bdSSridevi Ramesh fru_record_table_length); 438bd9440bdSSridevi Ramesh tablePrint.print(); 439bd9440bdSSridevi Ramesh } 440bd9440bdSSridevi Ramesh }; 441bd9440bdSSridevi Ramesh 442f7f5da97SDeepak Kodihalli void registerCommand(CLI::App& app) 443f7f5da97SDeepak Kodihalli { 444f7f5da97SDeepak Kodihalli auto fru = app.add_subcommand("fru", "FRU type command"); 445f7f5da97SDeepak Kodihalli fru->require_subcommand(1); 446f7f5da97SDeepak Kodihalli auto getFruRecordTableMetadata = fru->add_subcommand( 447f7f5da97SDeepak Kodihalli "GetFruRecordTableMetadata", "get FRU record table metadata"); 448f7f5da97SDeepak Kodihalli commands.push_back(std::make_unique<GetFruRecordTableMetadata>( 449f7f5da97SDeepak Kodihalli "fru", "GetFruRecordTableMetadata", getFruRecordTableMetadata)); 4505bdde3a4SJohn Wang 4515bdde3a4SJohn Wang auto getFRURecordByOption = 4525bdde3a4SJohn Wang fru->add_subcommand("GetFRURecordByOption", "get FRU Record By Option"); 4535bdde3a4SJohn Wang commands.push_back(std::make_unique<GetFRURecordByOption>( 4545bdde3a4SJohn Wang "fru", "GetFRURecordByOption", getFRURecordByOption)); 455bd9440bdSSridevi Ramesh 456bd9440bdSSridevi Ramesh auto getFruRecordTable = 457bd9440bdSSridevi Ramesh fru->add_subcommand("GetFruRecordTable", "get FRU Record Table"); 458bd9440bdSSridevi Ramesh commands.push_back(std::make_unique<GetFruRecordTable>( 459bd9440bdSSridevi Ramesh "fru", "GetFruRecordTable", getFruRecordTable)); 460f7f5da97SDeepak Kodihalli } 461f7f5da97SDeepak Kodihalli 462f7f5da97SDeepak Kodihalli } // namespace fru 463f7f5da97SDeepak Kodihalli 464f7f5da97SDeepak Kodihalli } // namespace pldmtool 465