1 /** 2 * Copyright © 2021 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "vpd.hpp" 18 19 #include "types.hpp" 20 #include "utility.hpp" 21 22 namespace phosphor::power::regulators 23 { 24 25 std::vector<uint8_t> DBusVPD::getValue(const std::string& inventoryPath, 26 const std::string& keyword) 27 { 28 std::vector<uint8_t> value{}; 29 30 // Get cached keywords for the inventory path 31 KeywordMap& cachedKeywords = cache[inventoryPath]; 32 33 // Check if the keyword value is already cached 34 auto it = cachedKeywords.find(keyword); 35 if (it != cachedKeywords.end()) 36 { 37 // Get keyword value from cache 38 value = it->second; 39 } 40 else 41 { 42 // Get keyword value from D-Bus interface/property 43 getDBusProperty(inventoryPath, keyword, value); 44 45 // Cache keyword value 46 cachedKeywords[keyword] = value; 47 } 48 49 return value; 50 } 51 52 void DBusVPD::getDBusProperty(const std::string& inventoryPath, 53 const std::string& keyword, 54 std::vector<uint8_t>& value) 55 { 56 // Determine the D-Bus property name. Normally this is the same as the VPD 57 // keyword name. However, the CCIN keyword is stored in the Model property. 58 std::string property{(keyword == "CCIN") ? "Model" : keyword}; 59 60 value.clear(); 61 try 62 { 63 if (property == "HW") 64 { 65 // HW property in non-standard interface and has byte vector value 66 util::getProperty("com.ibm.ipzvpd.VINI", property, inventoryPath, 67 INVENTORY_MGR_IFACE, bus, value); 68 } 69 else 70 { 71 // Other properties in standard interface and have string value 72 std::string stringValue; 73 util::getProperty(ASSET_IFACE, property, inventoryPath, 74 INVENTORY_MGR_IFACE, bus, stringValue); 75 value.insert(value.begin(), stringValue.begin(), stringValue.end()); 76 } 77 } 78 catch (const sdbusplus::exception_t& e) 79 { 80 // If exception indicates VPD interface or property doesn't exist 81 if (isUnknownPropertyException(e)) 82 { 83 // Treat this as an empty keyword value 84 value.clear(); 85 } 86 else 87 { 88 // Re-throw other exceptions 89 throw; 90 } 91 } 92 } 93 94 bool DBusVPD::isUnknownPropertyException(const sdbusplus::exception_t& e) 95 { 96 // Initially assume exception was due to some other type of error 97 bool isUnknownProperty{false}; 98 99 // If the D-Bus error name is set within the exception 100 if (e.name() != nullptr) 101 { 102 // Check if the error name indicates the specified interface or property 103 // does not exist on the specified object path 104 std::string name = e.name(); 105 if ((name == SD_BUS_ERROR_UNKNOWN_INTERFACE) || 106 (name == SD_BUS_ERROR_UNKNOWN_PROPERTY)) 107 { 108 isUnknownProperty = true; 109 } 110 } 111 112 return isUnknownProperty; 113 } 114 115 } // namespace phosphor::power::regulators 116