14e0402cbSShawn McCarney /**
24e0402cbSShawn McCarney  * Copyright © 2021 IBM Corporation
34e0402cbSShawn McCarney  *
44e0402cbSShawn McCarney  * Licensed under the Apache License, Version 2.0 (the "License");
54e0402cbSShawn McCarney  * you may not use this file except in compliance with the License.
64e0402cbSShawn McCarney  * You may obtain a copy of the License at
74e0402cbSShawn McCarney  *
84e0402cbSShawn McCarney  *     http://www.apache.org/licenses/LICENSE-2.0
94e0402cbSShawn McCarney  *
104e0402cbSShawn McCarney  * Unless required by applicable law or agreed to in writing, software
114e0402cbSShawn McCarney  * distributed under the License is distributed on an "AS IS" BASIS,
124e0402cbSShawn McCarney  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134e0402cbSShawn McCarney  * See the License for the specific language governing permissions and
144e0402cbSShawn McCarney  * limitations under the License.
154e0402cbSShawn McCarney  */
164e0402cbSShawn McCarney 
174e0402cbSShawn McCarney #include "vpd.hpp"
184e0402cbSShawn McCarney 
194e0402cbSShawn McCarney #include "types.hpp"
204e0402cbSShawn McCarney #include "utility.hpp"
214e0402cbSShawn McCarney 
224e0402cbSShawn McCarney namespace phosphor::power::regulators
234e0402cbSShawn McCarney {
244e0402cbSShawn McCarney 
getValue(const std::string & inventoryPath,const std::string & keyword)25aacc2aafSMatt Spinler std::vector<uint8_t> DBusVPD::getValue(const std::string& inventoryPath,
264e0402cbSShawn McCarney                                        const std::string& keyword)
274e0402cbSShawn McCarney {
28aacc2aafSMatt Spinler     std::vector<uint8_t> value{};
294e0402cbSShawn McCarney 
304e0402cbSShawn McCarney     // Get cached keywords for the inventory path
314e0402cbSShawn McCarney     KeywordMap& cachedKeywords = cache[inventoryPath];
324e0402cbSShawn McCarney 
334e0402cbSShawn McCarney     // Check if the keyword value is already cached
344e0402cbSShawn McCarney     auto it = cachedKeywords.find(keyword);
354e0402cbSShawn McCarney     if (it != cachedKeywords.end())
364e0402cbSShawn McCarney     {
37*5e0346b3SShawn McCarney         // Get keyword value from cache
384e0402cbSShawn McCarney         value = it->second;
394e0402cbSShawn McCarney     }
404e0402cbSShawn McCarney     else
414e0402cbSShawn McCarney     {
42*5e0346b3SShawn McCarney         // Get keyword value from D-Bus interface/property
43*5e0346b3SShawn McCarney         getDBusProperty(inventoryPath, keyword, value);
444e0402cbSShawn McCarney 
454e0402cbSShawn McCarney         // Cache keyword value
464e0402cbSShawn McCarney         cachedKeywords[keyword] = value;
474e0402cbSShawn McCarney     }
484e0402cbSShawn McCarney 
494e0402cbSShawn McCarney     return value;
504e0402cbSShawn McCarney }
514e0402cbSShawn McCarney 
getDBusProperty(const std::string & inventoryPath,const std::string & keyword,std::vector<uint8_t> & value)52*5e0346b3SShawn McCarney void DBusVPD::getDBusProperty(const std::string& inventoryPath,
53*5e0346b3SShawn McCarney                               const std::string& keyword,
54*5e0346b3SShawn McCarney                               std::vector<uint8_t>& value)
55*5e0346b3SShawn McCarney {
56*5e0346b3SShawn McCarney     // Determine the D-Bus property name.  Normally this is the same as the VPD
57*5e0346b3SShawn McCarney     // keyword name.  However, the CCIN keyword is stored in the Model property.
58*5e0346b3SShawn McCarney     std::string property{(keyword == "CCIN") ? "Model" : keyword};
59*5e0346b3SShawn McCarney 
60*5e0346b3SShawn McCarney     value.clear();
61*5e0346b3SShawn McCarney     try
62*5e0346b3SShawn McCarney     {
63*5e0346b3SShawn McCarney         if (property == "HW")
64*5e0346b3SShawn McCarney         {
65*5e0346b3SShawn McCarney             // HW property in non-standard interface and has byte vector value
66*5e0346b3SShawn McCarney             util::getProperty("com.ibm.ipzvpd.VINI", property, inventoryPath,
67*5e0346b3SShawn McCarney                               INVENTORY_MGR_IFACE, bus, value);
68*5e0346b3SShawn McCarney         }
69*5e0346b3SShawn McCarney         else
70*5e0346b3SShawn McCarney         {
71*5e0346b3SShawn McCarney             // Other properties in standard interface and have string value
72*5e0346b3SShawn McCarney             std::string stringValue;
73*5e0346b3SShawn McCarney             util::getProperty(ASSET_IFACE, property, inventoryPath,
74*5e0346b3SShawn McCarney                               INVENTORY_MGR_IFACE, bus, stringValue);
75*5e0346b3SShawn McCarney             value.insert(value.begin(), stringValue.begin(), stringValue.end());
76*5e0346b3SShawn McCarney         }
77*5e0346b3SShawn McCarney     }
78*5e0346b3SShawn McCarney     catch (const sdbusplus::exception_t& e)
79*5e0346b3SShawn McCarney     {
80*5e0346b3SShawn McCarney         // If exception indicates VPD interface or property doesn't exist
81*5e0346b3SShawn McCarney         if (isUnknownPropertyException(e))
82*5e0346b3SShawn McCarney         {
83*5e0346b3SShawn McCarney             // Treat this as an empty keyword value
84*5e0346b3SShawn McCarney             value.clear();
85*5e0346b3SShawn McCarney         }
86*5e0346b3SShawn McCarney         else
87*5e0346b3SShawn McCarney         {
88*5e0346b3SShawn McCarney             // Re-throw other exceptions
89*5e0346b3SShawn McCarney             throw;
90*5e0346b3SShawn McCarney         }
91*5e0346b3SShawn McCarney     }
92*5e0346b3SShawn McCarney }
93*5e0346b3SShawn McCarney 
isUnknownPropertyException(const sdbusplus::exception_t & e)94*5e0346b3SShawn McCarney bool DBusVPD::isUnknownPropertyException(const sdbusplus::exception_t& e)
95*5e0346b3SShawn McCarney {
96*5e0346b3SShawn McCarney     // Initially assume exception was due to some other type of error
97*5e0346b3SShawn McCarney     bool isUnknownProperty{false};
98*5e0346b3SShawn McCarney 
99*5e0346b3SShawn McCarney     // If the D-Bus error name is set within the exception
100*5e0346b3SShawn McCarney     if (e.name() != nullptr)
101*5e0346b3SShawn McCarney     {
102*5e0346b3SShawn McCarney         // Check if the error name indicates the specified interface or property
103*5e0346b3SShawn McCarney         // does not exist on the specified object path
104*5e0346b3SShawn McCarney         std::string name = e.name();
105*5e0346b3SShawn McCarney         if ((name == SD_BUS_ERROR_UNKNOWN_INTERFACE) ||
106*5e0346b3SShawn McCarney             (name == SD_BUS_ERROR_UNKNOWN_PROPERTY))
107*5e0346b3SShawn McCarney         {
108*5e0346b3SShawn McCarney             isUnknownProperty = true;
109*5e0346b3SShawn McCarney         }
110*5e0346b3SShawn McCarney     }
111*5e0346b3SShawn McCarney 
112*5e0346b3SShawn McCarney     return isUnknownProperty;
113*5e0346b3SShawn McCarney }
114*5e0346b3SShawn McCarney 
1154e0402cbSShawn McCarney } // namespace phosphor::power::regulators
116