1*7d9157edSMarri Devender Rao #include <algorithm>
2*7d9157edSMarri Devender Rao #include <map>
3*7d9157edSMarri Devender Rao #include <numeric>
4*7d9157edSMarri Devender Rao #include "ipmi_fru_info_area.hpp"
5*7d9157edSMarri Devender Rao #include <phosphor-logging/elog.hpp>
6*7d9157edSMarri Devender Rao namespace ipmi
7*7d9157edSMarri Devender Rao {
8*7d9157edSMarri Devender Rao namespace fru
9*7d9157edSMarri Devender Rao {
10*7d9157edSMarri Devender Rao using namespace phosphor::logging;
11*7d9157edSMarri Devender Rao 
12*7d9157edSMarri Devender Rao //Property variables
13*7d9157edSMarri Devender Rao static constexpr auto partNumber       = "PartNumber";
14*7d9157edSMarri Devender Rao static constexpr auto serialNumber     = "SerialNumber";
15*7d9157edSMarri Devender Rao static constexpr auto manufacturer     = "Manufacturer";
16*7d9157edSMarri Devender Rao static constexpr auto buildDate        = "BuildDate";
17*7d9157edSMarri Devender Rao static constexpr auto model            = "Model";
18*7d9157edSMarri Devender Rao static constexpr auto prettyName       = "PrettyName";
19*7d9157edSMarri Devender Rao static constexpr auto version          = "Version";
20*7d9157edSMarri Devender Rao 
21*7d9157edSMarri Devender Rao //Board info areas
22*7d9157edSMarri Devender Rao static constexpr auto board            = "Board";
23*7d9157edSMarri Devender Rao static constexpr auto chassis          = "Chassis";
24*7d9157edSMarri Devender Rao static constexpr auto product          = "Product";
25*7d9157edSMarri Devender Rao 
26*7d9157edSMarri Devender Rao static constexpr auto specVersion              = 0x1;
27*7d9157edSMarri Devender Rao static constexpr auto recordUnitOfMeasurment   = 0x8; //size in bytes
28*7d9157edSMarri Devender Rao static constexpr auto checksumSize             = 0x1; //size in bytes
29*7d9157edSMarri Devender Rao static constexpr auto recordNotPresent         = 0x0;
30*7d9157edSMarri Devender Rao static constexpr auto englishLanguageCode      = 0x0;
31*7d9157edSMarri Devender Rao static constexpr auto typeLengthByteNull       = 0x0;
32*7d9157edSMarri Devender Rao static constexpr auto endOfCustomFields        = 0xC1;
33*7d9157edSMarri Devender Rao static constexpr auto commonHeaderFormatSize   = 0x8; //size in bytes
34*7d9157edSMarri Devender Rao static constexpr auto manufacturingDateSize     = 0x3;
35*7d9157edSMarri Devender Rao static constexpr auto areaSizeOffset           = 0x1;
36*7d9157edSMarri Devender Rao 
37*7d9157edSMarri Devender Rao /**
38*7d9157edSMarri Devender Rao  * @brief Format Beginning of Individual IPMI FRU Data Section
39*7d9157edSMarri Devender Rao  *
40*7d9157edSMarri Devender Rao  * @param[in] langCode Language code
41*7d9157edSMarri Devender Rao  * @param[in/out] data FRU area data
42*7d9157edSMarri Devender Rao  */
43*7d9157edSMarri Devender Rao void preFormatProcessing(bool langCode, FruAreaData& data)
44*7d9157edSMarri Devender Rao {
45*7d9157edSMarri Devender Rao     //Add id for version of FRU Info Storage Spec used
46*7d9157edSMarri Devender Rao     data.emplace_back(specVersion);
47*7d9157edSMarri Devender Rao 
48*7d9157edSMarri Devender Rao     //Add Data Size - 0 as a placeholder, can edit after the data is finalized
49*7d9157edSMarri Devender Rao     data.emplace_back(typeLengthByteNull);
50*7d9157edSMarri Devender Rao 
51*7d9157edSMarri Devender Rao     if (langCode)
52*7d9157edSMarri Devender Rao     {
53*7d9157edSMarri Devender Rao         data.emplace_back(englishLanguageCode);
54*7d9157edSMarri Devender Rao     }
55*7d9157edSMarri Devender Rao }
56*7d9157edSMarri Devender Rao 
57*7d9157edSMarri Devender Rao /**
58*7d9157edSMarri Devender Rao  * @brief Append checksum of the FRU area data
59*7d9157edSMarri Devender Rao  *
60*7d9157edSMarri Devender Rao  * @param[in/out] data FRU area data
61*7d9157edSMarri Devender Rao  */
62*7d9157edSMarri Devender Rao void appendDataChecksum(FruAreaData& data)
63*7d9157edSMarri Devender Rao {
64*7d9157edSMarri Devender Rao     uint8_t checksumVal = std::accumulate(data.begin(), data.end(), 0);
65*7d9157edSMarri Devender Rao     // Push the Zero checksum as the last byte of this data
66*7d9157edSMarri Devender Rao     // This appears to be a simple summation of all the bytes
67*7d9157edSMarri Devender Rao     data.emplace_back(-checksumVal);
68*7d9157edSMarri Devender Rao }
69*7d9157edSMarri Devender Rao 
70*7d9157edSMarri Devender Rao /**
71*7d9157edSMarri Devender Rao  * @brief Append padding bytes for the FRU area data
72*7d9157edSMarri Devender Rao  *
73*7d9157edSMarri Devender Rao  * @param[in/out] data FRU area data
74*7d9157edSMarri Devender Rao  */
75*7d9157edSMarri Devender Rao void padData(FruAreaData& data)
76*7d9157edSMarri Devender Rao {
77*7d9157edSMarri Devender Rao     uint8_t pad = (data.size() + checksumSize) % recordUnitOfMeasurment;
78*7d9157edSMarri Devender Rao     if (pad)
79*7d9157edSMarri Devender Rao     {
80*7d9157edSMarri Devender Rao         data.resize((data.size() + recordUnitOfMeasurment - pad));
81*7d9157edSMarri Devender Rao     }
82*7d9157edSMarri Devender Rao }
83*7d9157edSMarri Devender Rao 
84*7d9157edSMarri Devender Rao /**
85*7d9157edSMarri Devender Rao  * @brief Format End of Individual IPMI FRU Data Section
86*7d9157edSMarri Devender Rao  *
87*7d9157edSMarri Devender Rao  * @param[in/out] fruAreaData FRU area info data
88*7d9157edSMarri Devender Rao  */
89*7d9157edSMarri Devender Rao void postFormatProcessing(FruAreaData& data)
90*7d9157edSMarri Devender Rao {
91*7d9157edSMarri Devender Rao     //This area needs to be padded to a multiple of 8 bytes (after checksum)
92*7d9157edSMarri Devender Rao     padData(data);
93*7d9157edSMarri Devender Rao 
94*7d9157edSMarri Devender Rao     //Set size of data info area
95*7d9157edSMarri Devender Rao     data.at(areaSizeOffset) = (data.size() + checksumSize) /
96*7d9157edSMarri Devender Rao         (recordUnitOfMeasurment);
97*7d9157edSMarri Devender Rao 
98*7d9157edSMarri Devender Rao     //Finally add board info checksum
99*7d9157edSMarri Devender Rao     appendDataChecksum(data);
100*7d9157edSMarri Devender Rao }
101*7d9157edSMarri Devender Rao 
102*7d9157edSMarri Devender Rao /**
103*7d9157edSMarri Devender Rao  * @brief Read property value from inventory and append to the FRU area data
104*7d9157edSMarri Devender Rao  *
105*7d9157edSMarri Devender Rao  * @param[in] key key to search for in the property inventory data
106*7d9157edSMarri Devender Rao  * @param[in] propMap map of property values
107*7d9157edSMarri Devender Rao  * @param[in,out] data FRU area data to be appended
108*7d9157edSMarri Devender Rao  */
109*7d9157edSMarri Devender Rao void appendData(const Property& key, const PropertyMap& propMap,
110*7d9157edSMarri Devender Rao                 FruAreaData& data)
111*7d9157edSMarri Devender Rao {
112*7d9157edSMarri Devender Rao     auto iter = propMap.find(key);
113*7d9157edSMarri Devender Rao     if (iter != propMap.end())
114*7d9157edSMarri Devender Rao     {
115*7d9157edSMarri Devender Rao         auto value = iter->second;
116*7d9157edSMarri Devender Rao         //If starts with 0x or 0X remove them
117*7d9157edSMarri Devender Rao         //ex: 0x123a just take 123a
118*7d9157edSMarri Devender Rao         if ((value.compare(0, 2, "0x")) == 0 ||
119*7d9157edSMarri Devender Rao            (value.compare(0, 2, "0X") == 0))
120*7d9157edSMarri Devender Rao         {
121*7d9157edSMarri Devender Rao             value.erase(0, 2);
122*7d9157edSMarri Devender Rao         }
123*7d9157edSMarri Devender Rao         data.emplace_back(value.length());
124*7d9157edSMarri Devender Rao         std::copy(value.begin(), value.end(), std::back_inserter(data));
125*7d9157edSMarri Devender Rao     }
126*7d9157edSMarri Devender Rao     else
127*7d9157edSMarri Devender Rao     {
128*7d9157edSMarri Devender Rao         //set 0 size
129*7d9157edSMarri Devender Rao         data.emplace_back(typeLengthByteNull);
130*7d9157edSMarri Devender Rao     }
131*7d9157edSMarri Devender Rao }
132*7d9157edSMarri Devender Rao 
133*7d9157edSMarri Devender Rao 
134*7d9157edSMarri Devender Rao /**
135*7d9157edSMarri Devender Rao  * @brief Appends Build Date
136*7d9157edSMarri Devender Rao  *
137*7d9157edSMarri Devender Rao  * @param[in] propMap map of property values
138*7d9157edSMarri Devender Rao  * @param[in/out] data FRU area to add the manfufacture date
139*7d9157edSMarri Devender Rao  */
140*7d9157edSMarri Devender Rao void appendMfgDate(const PropertyMap& propMap, FruAreaData& data)
141*7d9157edSMarri Devender Rao {
142*7d9157edSMarri Devender Rao     //MFG Date/Time
143*7d9157edSMarri Devender Rao     auto iter = propMap.find(buildDate);
144*7d9157edSMarri Devender Rao     if (iter != propMap.end())
145*7d9157edSMarri Devender Rao     {
146*7d9157edSMarri Devender Rao         auto& value = iter->second;
147*7d9157edSMarri Devender Rao         if (value.length() == manufacturingDateSize)
148*7d9157edSMarri Devender Rao         {
149*7d9157edSMarri Devender Rao             std::copy(
150*7d9157edSMarri Devender Rao                 value.begin(), value.end(), std::back_inserter(data));
151*7d9157edSMarri Devender Rao             return;
152*7d9157edSMarri Devender Rao         }
153*7d9157edSMarri Devender Rao     }
154*7d9157edSMarri Devender Rao     //Blank date
155*7d9157edSMarri Devender Rao     data.emplace_back(0);
156*7d9157edSMarri Devender Rao     data.emplace_back(0);
157*7d9157edSMarri Devender Rao     data.emplace_back(0);
158*7d9157edSMarri Devender Rao }
159*7d9157edSMarri Devender Rao 
160*7d9157edSMarri Devender Rao /**
161*7d9157edSMarri Devender Rao  * @brief Builds a section of the common header
162*7d9157edSMarri Devender Rao  *
163*7d9157edSMarri Devender Rao  * @param[in] infoAreaSize size of the FRU area to write
164*7d9157edSMarri Devender Rao  * @param[in] offset Current offset for data in overall record
165*7d9157edSMarri Devender Rao  * @param[in/out] data Common Header section data container
166*7d9157edSMarri Devender Rao  */
167*7d9157edSMarri Devender Rao void buildCommonHeaderSection(
168*7d9157edSMarri Devender Rao     const uint32_t& infoAreaSize, uint32_t& offset, FruAreaData& data)
169*7d9157edSMarri Devender Rao {
170*7d9157edSMarri Devender Rao     //Check if data for internal use section populated
171*7d9157edSMarri Devender Rao     if (infoAreaSize == 0)
172*7d9157edSMarri Devender Rao     {
173*7d9157edSMarri Devender Rao         //Indicate record not present
174*7d9157edSMarri Devender Rao         data.emplace_back(recordNotPresent);
175*7d9157edSMarri Devender Rao     }
176*7d9157edSMarri Devender Rao     else
177*7d9157edSMarri Devender Rao     {
178*7d9157edSMarri Devender Rao         //Place data to define offset to area data section
179*7d9157edSMarri Devender Rao         data.emplace_back((offset + commonHeaderFormatSize)
180*7d9157edSMarri Devender Rao             / recordUnitOfMeasurment);
181*7d9157edSMarri Devender Rao         offset += infoAreaSize;
182*7d9157edSMarri Devender Rao     }
183*7d9157edSMarri Devender Rao }
184*7d9157edSMarri Devender Rao 
185*7d9157edSMarri Devender Rao /**
186*7d9157edSMarri Devender Rao  * @brief Builds the Chassis info area data section
187*7d9157edSMarri Devender Rao  *
188*7d9157edSMarri Devender Rao  * @param[in] propMap map of properties for chassis info area
189*7d9157edSMarri Devender Rao  * @return FruAreaData container with chassis info area
190*7d9157edSMarri Devender Rao  */
191*7d9157edSMarri Devender Rao FruAreaData buildChassisInfoArea(const PropertyMap& propMap)
192*7d9157edSMarri Devender Rao {
193*7d9157edSMarri Devender Rao     FruAreaData fruAreaData;
194*7d9157edSMarri Devender Rao     if (!propMap.empty())
195*7d9157edSMarri Devender Rao     {
196*7d9157edSMarri Devender Rao         //Set formatting data that goes at the beginning of the record
197*7d9157edSMarri Devender Rao         preFormatProcessing(false, fruAreaData);
198*7d9157edSMarri Devender Rao 
199*7d9157edSMarri Devender Rao         //chassis type
200*7d9157edSMarri Devender Rao         fruAreaData.emplace_back(0);
201*7d9157edSMarri Devender Rao 
202*7d9157edSMarri Devender Rao         //Chasiss part number, in config.yaml it is configured as model
203*7d9157edSMarri Devender Rao         appendData(model, propMap, fruAreaData);
204*7d9157edSMarri Devender Rao 
205*7d9157edSMarri Devender Rao         //Board serial number
206*7d9157edSMarri Devender Rao         appendData(serialNumber, propMap, fruAreaData);
207*7d9157edSMarri Devender Rao 
208*7d9157edSMarri Devender Rao         //Indicate End of Custom Fields
209*7d9157edSMarri Devender Rao         fruAreaData.emplace_back(endOfCustomFields);
210*7d9157edSMarri Devender Rao 
211*7d9157edSMarri Devender Rao         //Complete record data formatting
212*7d9157edSMarri Devender Rao         postFormatProcessing(fruAreaData);
213*7d9157edSMarri Devender Rao     }
214*7d9157edSMarri Devender Rao     return fruAreaData;
215*7d9157edSMarri Devender Rao }
216*7d9157edSMarri Devender Rao 
217*7d9157edSMarri Devender Rao /**
218*7d9157edSMarri Devender Rao  * @brief Builds the Board info area data section
219*7d9157edSMarri Devender Rao  *
220*7d9157edSMarri Devender Rao  * @param[in] propMap map of properties for board info area
221*7d9157edSMarri Devender Rao  * @return FruAreaData container with board info area
222*7d9157edSMarri Devender Rao  */
223*7d9157edSMarri Devender Rao FruAreaData buildBoardInfoArea(const PropertyMap& propMap)
224*7d9157edSMarri Devender Rao {
225*7d9157edSMarri Devender Rao     FruAreaData fruAreaData;
226*7d9157edSMarri Devender Rao     if (!propMap.empty())
227*7d9157edSMarri Devender Rao     {
228*7d9157edSMarri Devender Rao         preFormatProcessing(true, fruAreaData);
229*7d9157edSMarri Devender Rao 
230*7d9157edSMarri Devender Rao         //Manufacturing date
231*7d9157edSMarri Devender Rao         appendMfgDate(propMap, fruAreaData);
232*7d9157edSMarri Devender Rao 
233*7d9157edSMarri Devender Rao         //manufacturer
234*7d9157edSMarri Devender Rao         appendData(manufacturer, propMap, fruAreaData);
235*7d9157edSMarri Devender Rao 
236*7d9157edSMarri Devender Rao         //Product name/Pretty name
237*7d9157edSMarri Devender Rao         appendData(prettyName, propMap, fruAreaData);
238*7d9157edSMarri Devender Rao 
239*7d9157edSMarri Devender Rao         //Board serial number
240*7d9157edSMarri Devender Rao         appendData(serialNumber, propMap, fruAreaData);
241*7d9157edSMarri Devender Rao 
242*7d9157edSMarri Devender Rao         //Board part number
243*7d9157edSMarri Devender Rao         appendData(partNumber, propMap, fruAreaData);
244*7d9157edSMarri Devender Rao 
245*7d9157edSMarri Devender Rao         //FRU File ID - Empty
246*7d9157edSMarri Devender Rao         fruAreaData.emplace_back(typeLengthByteNull);
247*7d9157edSMarri Devender Rao 
248*7d9157edSMarri Devender Rao         // Empty FRU File ID bytes
249*7d9157edSMarri Devender Rao         fruAreaData.emplace_back(recordNotPresent);
250*7d9157edSMarri Devender Rao 
251*7d9157edSMarri Devender Rao         //End of custom fields
252*7d9157edSMarri Devender Rao         fruAreaData.emplace_back(endOfCustomFields);
253*7d9157edSMarri Devender Rao 
254*7d9157edSMarri Devender Rao         postFormatProcessing(fruAreaData);
255*7d9157edSMarri Devender Rao     }
256*7d9157edSMarri Devender Rao     return fruAreaData;
257*7d9157edSMarri Devender Rao }
258*7d9157edSMarri Devender Rao 
259*7d9157edSMarri Devender Rao /**
260*7d9157edSMarri Devender Rao  * @brief Builds the Product info area data section
261*7d9157edSMarri Devender Rao  *
262*7d9157edSMarri Devender Rao  * @param[in] propMap map of FRU properties for Board info area
263*7d9157edSMarri Devender Rao  * @return FruAreaData container with product info area data
264*7d9157edSMarri Devender Rao  */
265*7d9157edSMarri Devender Rao FruAreaData buildProductInfoArea(const PropertyMap& propMap)
266*7d9157edSMarri Devender Rao {
267*7d9157edSMarri Devender Rao     FruAreaData fruAreaData;
268*7d9157edSMarri Devender Rao     if (!propMap.empty())
269*7d9157edSMarri Devender Rao     {
270*7d9157edSMarri Devender Rao         //Set formatting data that goes at the beginning of the record
271*7d9157edSMarri Devender Rao         preFormatProcessing(true, fruAreaData);
272*7d9157edSMarri Devender Rao 
273*7d9157edSMarri Devender Rao         //manufacturer
274*7d9157edSMarri Devender Rao         appendData(manufacturer, propMap, fruAreaData);
275*7d9157edSMarri Devender Rao 
276*7d9157edSMarri Devender Rao         //Product name/Pretty name
277*7d9157edSMarri Devender Rao         appendData(prettyName, propMap, fruAreaData);
278*7d9157edSMarri Devender Rao 
279*7d9157edSMarri Devender Rao         //Product part/model number
280*7d9157edSMarri Devender Rao         appendData(model, propMap, fruAreaData);
281*7d9157edSMarri Devender Rao 
282*7d9157edSMarri Devender Rao         //Product version
283*7d9157edSMarri Devender Rao         appendData(version, propMap, fruAreaData);
284*7d9157edSMarri Devender Rao 
285*7d9157edSMarri Devender Rao         //Serial Number
286*7d9157edSMarri Devender Rao         appendData(serialNumber, propMap, fruAreaData);
287*7d9157edSMarri Devender Rao 
288*7d9157edSMarri Devender Rao         //Add Asset Tag
289*7d9157edSMarri Devender Rao         fruAreaData.emplace_back(recordNotPresent);
290*7d9157edSMarri Devender Rao 
291*7d9157edSMarri Devender Rao         //FRU File ID - Empty
292*7d9157edSMarri Devender Rao         fruAreaData.emplace_back(typeLengthByteNull);
293*7d9157edSMarri Devender Rao 
294*7d9157edSMarri Devender Rao         // Empty FRU File ID bytes
295*7d9157edSMarri Devender Rao         fruAreaData.emplace_back(recordNotPresent);
296*7d9157edSMarri Devender Rao 
297*7d9157edSMarri Devender Rao         //End of custom fields
298*7d9157edSMarri Devender Rao         fruAreaData.emplace_back(endOfCustomFields);
299*7d9157edSMarri Devender Rao 
300*7d9157edSMarri Devender Rao         postFormatProcessing(fruAreaData);
301*7d9157edSMarri Devender Rao     }
302*7d9157edSMarri Devender Rao     return fruAreaData;
303*7d9157edSMarri Devender Rao }
304*7d9157edSMarri Devender Rao 
305*7d9157edSMarri Devender Rao FruAreaData buildFruAreaData(const FruInventoryData& inventory)
306*7d9157edSMarri Devender Rao {
307*7d9157edSMarri Devender Rao     FruAreaData combFruArea;
308*7d9157edSMarri Devender Rao     //Now build common header with data for this FRU Inv Record
309*7d9157edSMarri Devender Rao     //Use this variable to increment size of header as we go along to determine
310*7d9157edSMarri Devender Rao     //offset for the subsequent area offsets
311*7d9157edSMarri Devender Rao     uint32_t curDataOffset = 0;
312*7d9157edSMarri Devender Rao 
313*7d9157edSMarri Devender Rao     //First byte is id for version of FRU Info Storage Spec used
314*7d9157edSMarri Devender Rao     combFruArea.emplace_back(specVersion);
315*7d9157edSMarri Devender Rao 
316*7d9157edSMarri Devender Rao     //2nd byte is offset to internal use data
317*7d9157edSMarri Devender Rao     combFruArea.emplace_back(recordNotPresent);
318*7d9157edSMarri Devender Rao 
319*7d9157edSMarri Devender Rao     //3rd byte is offset to chassis data
320*7d9157edSMarri Devender Rao     FruAreaData chassisArea;
321*7d9157edSMarri Devender Rao     auto chassisIt = inventory.find(chassis);
322*7d9157edSMarri Devender Rao     if (chassisIt != inventory.end())
323*7d9157edSMarri Devender Rao     {
324*7d9157edSMarri Devender Rao         chassisArea = std::move(buildChassisInfoArea(chassisIt->second));
325*7d9157edSMarri Devender Rao     }
326*7d9157edSMarri Devender Rao     buildCommonHeaderSection(chassisArea.size(), curDataOffset, combFruArea);
327*7d9157edSMarri Devender Rao 
328*7d9157edSMarri Devender Rao     //4th byte is offset to board data
329*7d9157edSMarri Devender Rao     FruAreaData boardArea;
330*7d9157edSMarri Devender Rao     auto boardIt = inventory.find(board);
331*7d9157edSMarri Devender Rao     if (boardIt != inventory.end())
332*7d9157edSMarri Devender Rao     {
333*7d9157edSMarri Devender Rao         boardArea = std::move(buildBoardInfoArea(boardIt->second));
334*7d9157edSMarri Devender Rao     }
335*7d9157edSMarri Devender Rao 
336*7d9157edSMarri Devender Rao     //5th byte is offset to product data
337*7d9157edSMarri Devender Rao     FruAreaData prodArea;
338*7d9157edSMarri Devender Rao     auto prodIt = inventory.find(product);
339*7d9157edSMarri Devender Rao     if (prodIt != inventory.end())
340*7d9157edSMarri Devender Rao     {
341*7d9157edSMarri Devender Rao         prodArea = std::move(buildProductInfoArea(prodIt->second));
342*7d9157edSMarri Devender Rao     }
343*7d9157edSMarri Devender Rao     buildCommonHeaderSection(prodArea.size(), curDataOffset, combFruArea);
344*7d9157edSMarri Devender Rao 
345*7d9157edSMarri Devender Rao     //6th byte is offset to multirecord data
346*7d9157edSMarri Devender Rao     combFruArea.emplace_back(recordNotPresent);
347*7d9157edSMarri Devender Rao 
348*7d9157edSMarri Devender Rao     //7th byte is PAD
349*7d9157edSMarri Devender Rao     padData(combFruArea);
350*7d9157edSMarri Devender Rao 
351*7d9157edSMarri Devender Rao     //8th (Final byte of Header Format) is the checksum
352*7d9157edSMarri Devender Rao     appendDataChecksum(combFruArea);
353*7d9157edSMarri Devender Rao 
354*7d9157edSMarri Devender Rao     //Combine everything into one full IPMI FRU specification Record
355*7d9157edSMarri Devender Rao     //add chassis use area data
356*7d9157edSMarri Devender Rao     combFruArea.insert(
357*7d9157edSMarri Devender Rao             combFruArea.end(), chassisArea.begin(), chassisArea.end());
358*7d9157edSMarri Devender Rao 
359*7d9157edSMarri Devender Rao     //add board area data
360*7d9157edSMarri Devender Rao     combFruArea.insert(combFruArea.end(), boardArea.begin(), boardArea.end());
361*7d9157edSMarri Devender Rao 
362*7d9157edSMarri Devender Rao     //add product use area data
363*7d9157edSMarri Devender Rao     combFruArea.insert(combFruArea.end(), prodArea.begin(), prodArea.end());
364*7d9157edSMarri Devender Rao 
365*7d9157edSMarri Devender Rao     return combFruArea;
366*7d9157edSMarri Devender Rao }
367*7d9157edSMarri Devender Rao 
368*7d9157edSMarri Devender Rao } //fru
369*7d9157edSMarri Devender Rao } //ipmi
370