17d9157edSMarri Devender Rao #include <algorithm> 27d9157edSMarri Devender Rao #include <map> 37d9157edSMarri Devender Rao #include <numeric> 47d9157edSMarri Devender Rao #include "ipmi_fru_info_area.hpp" 57d9157edSMarri Devender Rao #include <phosphor-logging/elog.hpp> 67d9157edSMarri Devender Rao namespace ipmi 77d9157edSMarri Devender Rao { 87d9157edSMarri Devender Rao namespace fru 97d9157edSMarri Devender Rao { 107d9157edSMarri Devender Rao using namespace phosphor::logging; 117d9157edSMarri Devender Rao 127d9157edSMarri Devender Rao //Property variables 137d9157edSMarri Devender Rao static constexpr auto partNumber = "PartNumber"; 147d9157edSMarri Devender Rao static constexpr auto serialNumber = "SerialNumber"; 157d9157edSMarri Devender Rao static constexpr auto manufacturer = "Manufacturer"; 167d9157edSMarri Devender Rao static constexpr auto buildDate = "BuildDate"; 177d9157edSMarri Devender Rao static constexpr auto model = "Model"; 187d9157edSMarri Devender Rao static constexpr auto prettyName = "PrettyName"; 197d9157edSMarri Devender Rao static constexpr auto version = "Version"; 207d9157edSMarri Devender Rao 217d9157edSMarri Devender Rao //Board info areas 227d9157edSMarri Devender Rao static constexpr auto board = "Board"; 237d9157edSMarri Devender Rao static constexpr auto chassis = "Chassis"; 247d9157edSMarri Devender Rao static constexpr auto product = "Product"; 257d9157edSMarri Devender Rao 267d9157edSMarri Devender Rao static constexpr auto specVersion = 0x1; 277d9157edSMarri Devender Rao static constexpr auto recordUnitOfMeasurment = 0x8; //size in bytes 287d9157edSMarri Devender Rao static constexpr auto checksumSize = 0x1; //size in bytes 297d9157edSMarri Devender Rao static constexpr auto recordNotPresent = 0x0; 307d9157edSMarri Devender Rao static constexpr auto englishLanguageCode = 0x0; 317d9157edSMarri Devender Rao static constexpr auto typeLengthByteNull = 0x0; 327d9157edSMarri Devender Rao static constexpr auto endOfCustomFields = 0xC1; 337d9157edSMarri Devender Rao static constexpr auto commonHeaderFormatSize = 0x8; //size in bytes 347d9157edSMarri Devender Rao static constexpr auto manufacturingDateSize = 0x3; 357d9157edSMarri Devender Rao static constexpr auto areaSizeOffset = 0x1; 36*6edfc5c1SRatan Gupta static constexpr uint8_t typeASCII = 0xC0; 37*6edfc5c1SRatan Gupta static constexpr auto maxRecordAttributeValue = 0x1F; 387d9157edSMarri Devender Rao 397d9157edSMarri Devender Rao /** 407d9157edSMarri Devender Rao * @brief Format Beginning of Individual IPMI FRU Data Section 417d9157edSMarri Devender Rao * 427d9157edSMarri Devender Rao * @param[in] langCode Language code 437d9157edSMarri Devender Rao * @param[in/out] data FRU area data 447d9157edSMarri Devender Rao */ 457d9157edSMarri Devender Rao void preFormatProcessing(bool langCode, FruAreaData& data) 467d9157edSMarri Devender Rao { 477d9157edSMarri Devender Rao //Add id for version of FRU Info Storage Spec used 487d9157edSMarri Devender Rao data.emplace_back(specVersion); 497d9157edSMarri Devender Rao 507d9157edSMarri Devender Rao //Add Data Size - 0 as a placeholder, can edit after the data is finalized 517d9157edSMarri Devender Rao data.emplace_back(typeLengthByteNull); 527d9157edSMarri Devender Rao 537d9157edSMarri Devender Rao if (langCode) 547d9157edSMarri Devender Rao { 557d9157edSMarri Devender Rao data.emplace_back(englishLanguageCode); 567d9157edSMarri Devender Rao } 577d9157edSMarri Devender Rao } 587d9157edSMarri Devender Rao 597d9157edSMarri Devender Rao /** 607d9157edSMarri Devender Rao * @brief Append checksum of the FRU area data 617d9157edSMarri Devender Rao * 627d9157edSMarri Devender Rao * @param[in/out] data FRU area data 637d9157edSMarri Devender Rao */ 647d9157edSMarri Devender Rao void appendDataChecksum(FruAreaData& data) 657d9157edSMarri Devender Rao { 667d9157edSMarri Devender Rao uint8_t checksumVal = std::accumulate(data.begin(), data.end(), 0); 677d9157edSMarri Devender Rao // Push the Zero checksum as the last byte of this data 687d9157edSMarri Devender Rao // This appears to be a simple summation of all the bytes 697d9157edSMarri Devender Rao data.emplace_back(-checksumVal); 707d9157edSMarri Devender Rao } 717d9157edSMarri Devender Rao 727d9157edSMarri Devender Rao /** 737d9157edSMarri Devender Rao * @brief Append padding bytes for the FRU area data 747d9157edSMarri Devender Rao * 757d9157edSMarri Devender Rao * @param[in/out] data FRU area data 767d9157edSMarri Devender Rao */ 777d9157edSMarri Devender Rao void padData(FruAreaData& data) 787d9157edSMarri Devender Rao { 797d9157edSMarri Devender Rao uint8_t pad = (data.size() + checksumSize) % recordUnitOfMeasurment; 807d9157edSMarri Devender Rao if (pad) 817d9157edSMarri Devender Rao { 827d9157edSMarri Devender Rao data.resize((data.size() + recordUnitOfMeasurment - pad)); 837d9157edSMarri Devender Rao } 847d9157edSMarri Devender Rao } 857d9157edSMarri Devender Rao 867d9157edSMarri Devender Rao /** 877d9157edSMarri Devender Rao * @brief Format End of Individual IPMI FRU Data Section 887d9157edSMarri Devender Rao * 897d9157edSMarri Devender Rao * @param[in/out] fruAreaData FRU area info data 907d9157edSMarri Devender Rao */ 917d9157edSMarri Devender Rao void postFormatProcessing(FruAreaData& data) 927d9157edSMarri Devender Rao { 937d9157edSMarri Devender Rao //This area needs to be padded to a multiple of 8 bytes (after checksum) 947d9157edSMarri Devender Rao padData(data); 957d9157edSMarri Devender Rao 967d9157edSMarri Devender Rao //Set size of data info area 977d9157edSMarri Devender Rao data.at(areaSizeOffset) = (data.size() + checksumSize) / 987d9157edSMarri Devender Rao (recordUnitOfMeasurment); 997d9157edSMarri Devender Rao 1002f66f00eSRatan Gupta //Finally add area checksum 1017d9157edSMarri Devender Rao appendDataChecksum(data); 1027d9157edSMarri Devender Rao } 1037d9157edSMarri Devender Rao 1047d9157edSMarri Devender Rao /** 1057d9157edSMarri Devender Rao * @brief Read property value from inventory and append to the FRU area data 1067d9157edSMarri Devender Rao * 1077d9157edSMarri Devender Rao * @param[in] key key to search for in the property inventory data 1087d9157edSMarri Devender Rao * @param[in] propMap map of property values 1097d9157edSMarri Devender Rao * @param[in,out] data FRU area data to be appended 1107d9157edSMarri Devender Rao */ 1117d9157edSMarri Devender Rao void appendData(const Property& key, const PropertyMap& propMap, 1127d9157edSMarri Devender Rao FruAreaData& data) 1137d9157edSMarri Devender Rao { 1147d9157edSMarri Devender Rao auto iter = propMap.find(key); 1157d9157edSMarri Devender Rao if (iter != propMap.end()) 1167d9157edSMarri Devender Rao { 1177d9157edSMarri Devender Rao auto value = iter->second; 1187d9157edSMarri Devender Rao //If starts with 0x or 0X remove them 1197d9157edSMarri Devender Rao //ex: 0x123a just take 123a 1207d9157edSMarri Devender Rao if ((value.compare(0, 2, "0x")) == 0 || 1217d9157edSMarri Devender Rao (value.compare(0, 2, "0X") == 0)) 1227d9157edSMarri Devender Rao { 1237d9157edSMarri Devender Rao value.erase(0, 2); 1247d9157edSMarri Devender Rao } 125*6edfc5c1SRatan Gupta 126*6edfc5c1SRatan Gupta // 5 bits for length 127*6edfc5c1SRatan Gupta // if length is greater then 31(2^5) bytes then trim the data to 31 bytess. 128*6edfc5c1SRatan Gupta auto valueLength = (value.length() > maxRecordAttributeValue) ? 129*6edfc5c1SRatan Gupta maxRecordAttributeValue : value.length(); 130*6edfc5c1SRatan Gupta // 2 bits for type 131*6edfc5c1SRatan Gupta // Set the type to ascii 132*6edfc5c1SRatan Gupta uint8_t typeLength = valueLength | ipmi::fru::typeASCII; 133*6edfc5c1SRatan Gupta 134*6edfc5c1SRatan Gupta data.emplace_back(typeLength); 135*6edfc5c1SRatan Gupta std::copy(value.begin(), 136*6edfc5c1SRatan Gupta value.begin() + valueLength, 137*6edfc5c1SRatan Gupta std::back_inserter(data)); 1387d9157edSMarri Devender Rao } 1397d9157edSMarri Devender Rao else 1407d9157edSMarri Devender Rao { 1417d9157edSMarri Devender Rao //set 0 size 1427d9157edSMarri Devender Rao data.emplace_back(typeLengthByteNull); 1437d9157edSMarri Devender Rao } 1447d9157edSMarri Devender Rao } 1457d9157edSMarri Devender Rao 1467d9157edSMarri Devender Rao 1477d9157edSMarri Devender Rao /** 1487d9157edSMarri Devender Rao * @brief Appends Build Date 1497d9157edSMarri Devender Rao * 1507d9157edSMarri Devender Rao * @param[in] propMap map of property values 1517d9157edSMarri Devender Rao * @param[in/out] data FRU area to add the manfufacture date 1527d9157edSMarri Devender Rao */ 1537d9157edSMarri Devender Rao void appendMfgDate(const PropertyMap& propMap, FruAreaData& data) 1547d9157edSMarri Devender Rao { 1557d9157edSMarri Devender Rao //MFG Date/Time 1567d9157edSMarri Devender Rao auto iter = propMap.find(buildDate); 1577d9157edSMarri Devender Rao if (iter != propMap.end()) 1587d9157edSMarri Devender Rao { 1597d9157edSMarri Devender Rao auto& value = iter->second; 1607d9157edSMarri Devender Rao if (value.length() == manufacturingDateSize) 1617d9157edSMarri Devender Rao { 1627d9157edSMarri Devender Rao std::copy( 1637d9157edSMarri Devender Rao value.begin(), value.end(), std::back_inserter(data)); 1647d9157edSMarri Devender Rao return; 1657d9157edSMarri Devender Rao } 1667d9157edSMarri Devender Rao } 1677d9157edSMarri Devender Rao //Blank date 1687d9157edSMarri Devender Rao data.emplace_back(0); 1697d9157edSMarri Devender Rao data.emplace_back(0); 1707d9157edSMarri Devender Rao data.emplace_back(0); 1717d9157edSMarri Devender Rao } 1727d9157edSMarri Devender Rao 1737d9157edSMarri Devender Rao /** 1747d9157edSMarri Devender Rao * @brief Builds a section of the common header 1757d9157edSMarri Devender Rao * 1767d9157edSMarri Devender Rao * @param[in] infoAreaSize size of the FRU area to write 1777d9157edSMarri Devender Rao * @param[in] offset Current offset for data in overall record 1787d9157edSMarri Devender Rao * @param[in/out] data Common Header section data container 1797d9157edSMarri Devender Rao */ 1807d9157edSMarri Devender Rao void buildCommonHeaderSection( 1812f66f00eSRatan Gupta const uint32_t& infoAreaSize, uint16_t& offset, FruAreaData& data) 1827d9157edSMarri Devender Rao { 1837d9157edSMarri Devender Rao //Check if data for internal use section populated 1847d9157edSMarri Devender Rao if (infoAreaSize == 0) 1857d9157edSMarri Devender Rao { 1867d9157edSMarri Devender Rao //Indicate record not present 1877d9157edSMarri Devender Rao data.emplace_back(recordNotPresent); 1887d9157edSMarri Devender Rao } 1897d9157edSMarri Devender Rao else 1907d9157edSMarri Devender Rao { 1912f66f00eSRatan Gupta // offset should be multiple of 8. 1922f66f00eSRatan Gupta auto remainder = offset % recordUnitOfMeasurment; 1932f66f00eSRatan Gupta // add the padding bytes in the offset so that offset 1942f66f00eSRatan Gupta // will be multiple of 8 byte. 1952f66f00eSRatan Gupta offset += (remainder > 0) ? recordUnitOfMeasurment - remainder : 0; 1967d9157edSMarri Devender Rao //Place data to define offset to area data section 1972f66f00eSRatan Gupta data.emplace_back(offset / recordUnitOfMeasurment); 1982f66f00eSRatan Gupta 1997d9157edSMarri Devender Rao offset += infoAreaSize; 2007d9157edSMarri Devender Rao } 2017d9157edSMarri Devender Rao } 2027d9157edSMarri Devender Rao 2037d9157edSMarri Devender Rao /** 2047d9157edSMarri Devender Rao * @brief Builds the Chassis info area data section 2057d9157edSMarri Devender Rao * 2067d9157edSMarri Devender Rao * @param[in] propMap map of properties for chassis info area 2077d9157edSMarri Devender Rao * @return FruAreaData container with chassis info area 2087d9157edSMarri Devender Rao */ 2097d9157edSMarri Devender Rao FruAreaData buildChassisInfoArea(const PropertyMap& propMap) 2107d9157edSMarri Devender Rao { 2117d9157edSMarri Devender Rao FruAreaData fruAreaData; 2127d9157edSMarri Devender Rao if (!propMap.empty()) 2137d9157edSMarri Devender Rao { 2147d9157edSMarri Devender Rao //Set formatting data that goes at the beginning of the record 2157d9157edSMarri Devender Rao preFormatProcessing(false, fruAreaData); 2167d9157edSMarri Devender Rao 2177d9157edSMarri Devender Rao //chassis type 2187d9157edSMarri Devender Rao fruAreaData.emplace_back(0); 2197d9157edSMarri Devender Rao 2207d9157edSMarri Devender Rao //Chasiss part number, in config.yaml it is configured as model 2217d9157edSMarri Devender Rao appendData(model, propMap, fruAreaData); 2227d9157edSMarri Devender Rao 2237d9157edSMarri Devender Rao //Board serial number 2247d9157edSMarri Devender Rao appendData(serialNumber, propMap, fruAreaData); 2257d9157edSMarri Devender Rao 2267d9157edSMarri Devender Rao //Indicate End of Custom Fields 2277d9157edSMarri Devender Rao fruAreaData.emplace_back(endOfCustomFields); 2287d9157edSMarri Devender Rao 2297d9157edSMarri Devender Rao //Complete record data formatting 2307d9157edSMarri Devender Rao postFormatProcessing(fruAreaData); 2317d9157edSMarri Devender Rao } 2327d9157edSMarri Devender Rao return fruAreaData; 2337d9157edSMarri Devender Rao } 2347d9157edSMarri Devender Rao 2357d9157edSMarri Devender Rao /** 2367d9157edSMarri Devender Rao * @brief Builds the Board info area data section 2377d9157edSMarri Devender Rao * 2387d9157edSMarri Devender Rao * @param[in] propMap map of properties for board info area 2397d9157edSMarri Devender Rao * @return FruAreaData container with board info area 2407d9157edSMarri Devender Rao */ 2417d9157edSMarri Devender Rao FruAreaData buildBoardInfoArea(const PropertyMap& propMap) 2427d9157edSMarri Devender Rao { 2437d9157edSMarri Devender Rao FruAreaData fruAreaData; 2447d9157edSMarri Devender Rao if (!propMap.empty()) 2457d9157edSMarri Devender Rao { 2467d9157edSMarri Devender Rao preFormatProcessing(true, fruAreaData); 2477d9157edSMarri Devender Rao 2487d9157edSMarri Devender Rao //Manufacturing date 2497d9157edSMarri Devender Rao appendMfgDate(propMap, fruAreaData); 2507d9157edSMarri Devender Rao 2517d9157edSMarri Devender Rao //manufacturer 2527d9157edSMarri Devender Rao appendData(manufacturer, propMap, fruAreaData); 2537d9157edSMarri Devender Rao 2547d9157edSMarri Devender Rao //Product name/Pretty name 2557d9157edSMarri Devender Rao appendData(prettyName, propMap, fruAreaData); 2567d9157edSMarri Devender Rao 2577d9157edSMarri Devender Rao //Board serial number 2587d9157edSMarri Devender Rao appendData(serialNumber, propMap, fruAreaData); 2597d9157edSMarri Devender Rao 2607d9157edSMarri Devender Rao //Board part number 2617d9157edSMarri Devender Rao appendData(partNumber, propMap, fruAreaData); 2627d9157edSMarri Devender Rao 2637d9157edSMarri Devender Rao //FRU File ID - Empty 2647d9157edSMarri Devender Rao fruAreaData.emplace_back(typeLengthByteNull); 2657d9157edSMarri Devender Rao 2667d9157edSMarri Devender Rao // Empty FRU File ID bytes 2677d9157edSMarri Devender Rao fruAreaData.emplace_back(recordNotPresent); 2687d9157edSMarri Devender Rao 2697d9157edSMarri Devender Rao //End of custom fields 2707d9157edSMarri Devender Rao fruAreaData.emplace_back(endOfCustomFields); 2717d9157edSMarri Devender Rao 2727d9157edSMarri Devender Rao postFormatProcessing(fruAreaData); 2737d9157edSMarri Devender Rao } 2747d9157edSMarri Devender Rao return fruAreaData; 2757d9157edSMarri Devender Rao } 2767d9157edSMarri Devender Rao 2777d9157edSMarri Devender Rao /** 2787d9157edSMarri Devender Rao * @brief Builds the Product info area data section 2797d9157edSMarri Devender Rao * 2807d9157edSMarri Devender Rao * @param[in] propMap map of FRU properties for Board info area 2817d9157edSMarri Devender Rao * @return FruAreaData container with product info area data 2827d9157edSMarri Devender Rao */ 2837d9157edSMarri Devender Rao FruAreaData buildProductInfoArea(const PropertyMap& propMap) 2847d9157edSMarri Devender Rao { 2857d9157edSMarri Devender Rao FruAreaData fruAreaData; 2867d9157edSMarri Devender Rao if (!propMap.empty()) 2877d9157edSMarri Devender Rao { 2887d9157edSMarri Devender Rao //Set formatting data that goes at the beginning of the record 2897d9157edSMarri Devender Rao preFormatProcessing(true, fruAreaData); 2907d9157edSMarri Devender Rao 2917d9157edSMarri Devender Rao //manufacturer 2927d9157edSMarri Devender Rao appendData(manufacturer, propMap, fruAreaData); 2937d9157edSMarri Devender Rao 2947d9157edSMarri Devender Rao //Product name/Pretty name 2957d9157edSMarri Devender Rao appendData(prettyName, propMap, fruAreaData); 2967d9157edSMarri Devender Rao 2977d9157edSMarri Devender Rao //Product part/model number 2987d9157edSMarri Devender Rao appendData(model, propMap, fruAreaData); 2997d9157edSMarri Devender Rao 3007d9157edSMarri Devender Rao //Product version 3017d9157edSMarri Devender Rao appendData(version, propMap, fruAreaData); 3027d9157edSMarri Devender Rao 3037d9157edSMarri Devender Rao //Serial Number 3047d9157edSMarri Devender Rao appendData(serialNumber, propMap, fruAreaData); 3057d9157edSMarri Devender Rao 3067d9157edSMarri Devender Rao //Add Asset Tag 3077d9157edSMarri Devender Rao fruAreaData.emplace_back(recordNotPresent); 3087d9157edSMarri Devender Rao 3097d9157edSMarri Devender Rao //FRU File ID - Empty 3107d9157edSMarri Devender Rao fruAreaData.emplace_back(typeLengthByteNull); 3117d9157edSMarri Devender Rao 3127d9157edSMarri Devender Rao // Empty FRU File ID bytes 3137d9157edSMarri Devender Rao fruAreaData.emplace_back(recordNotPresent); 3147d9157edSMarri Devender Rao 3157d9157edSMarri Devender Rao //End of custom fields 3167d9157edSMarri Devender Rao fruAreaData.emplace_back(endOfCustomFields); 3177d9157edSMarri Devender Rao 3187d9157edSMarri Devender Rao postFormatProcessing(fruAreaData); 3197d9157edSMarri Devender Rao } 3207d9157edSMarri Devender Rao return fruAreaData; 3217d9157edSMarri Devender Rao } 3227d9157edSMarri Devender Rao 3237d9157edSMarri Devender Rao FruAreaData buildFruAreaData(const FruInventoryData& inventory) 3247d9157edSMarri Devender Rao { 3252f66f00eSRatan Gupta FruAreaData combFruArea{}; 3267d9157edSMarri Devender Rao //Now build common header with data for this FRU Inv Record 3277d9157edSMarri Devender Rao //Use this variable to increment size of header as we go along to determine 3287d9157edSMarri Devender Rao //offset for the subsequent area offsets 3292f66f00eSRatan Gupta uint16_t curDataOffset = commonHeaderFormatSize; 3307d9157edSMarri Devender Rao //First byte is id for version of FRU Info Storage Spec used 3317d9157edSMarri Devender Rao combFruArea.emplace_back(specVersion); 3327d9157edSMarri Devender Rao 3337d9157edSMarri Devender Rao //2nd byte is offset to internal use data 3347d9157edSMarri Devender Rao combFruArea.emplace_back(recordNotPresent); 3357d9157edSMarri Devender Rao 3367d9157edSMarri Devender Rao //3rd byte is offset to chassis data 3377d9157edSMarri Devender Rao FruAreaData chassisArea; 3387d9157edSMarri Devender Rao auto chassisIt = inventory.find(chassis); 3397d9157edSMarri Devender Rao if (chassisIt != inventory.end()) 3407d9157edSMarri Devender Rao { 3417d9157edSMarri Devender Rao chassisArea = std::move(buildChassisInfoArea(chassisIt->second)); 3427d9157edSMarri Devender Rao } 3432f66f00eSRatan Gupta // update the offset to chassis data. 3447d9157edSMarri Devender Rao buildCommonHeaderSection(chassisArea.size(), curDataOffset, combFruArea); 3457d9157edSMarri Devender Rao 3467d9157edSMarri Devender Rao //4th byte is offset to board data 3477d9157edSMarri Devender Rao FruAreaData boardArea; 3487d9157edSMarri Devender Rao auto boardIt = inventory.find(board); 3497d9157edSMarri Devender Rao if (boardIt != inventory.end()) 3507d9157edSMarri Devender Rao { 3517d9157edSMarri Devender Rao boardArea = std::move(buildBoardInfoArea(boardIt->second)); 3527d9157edSMarri Devender Rao } 3532f66f00eSRatan Gupta // update the offset to the board data. 3542f66f00eSRatan Gupta buildCommonHeaderSection(boardArea.size(), curDataOffset, combFruArea); 3557d9157edSMarri Devender Rao 3567d9157edSMarri Devender Rao //5th byte is offset to product data 3577d9157edSMarri Devender Rao FruAreaData prodArea; 3587d9157edSMarri Devender Rao auto prodIt = inventory.find(product); 3597d9157edSMarri Devender Rao if (prodIt != inventory.end()) 3607d9157edSMarri Devender Rao { 3617d9157edSMarri Devender Rao prodArea = std::move(buildProductInfoArea(prodIt->second)); 3627d9157edSMarri Devender Rao } 3632f66f00eSRatan Gupta // update the offset to the product data. 3647d9157edSMarri Devender Rao buildCommonHeaderSection(prodArea.size(), curDataOffset, combFruArea); 3657d9157edSMarri Devender Rao 3667d9157edSMarri Devender Rao //6th byte is offset to multirecord data 3677d9157edSMarri Devender Rao combFruArea.emplace_back(recordNotPresent); 3687d9157edSMarri Devender Rao 3697d9157edSMarri Devender Rao //7th byte is PAD 3702f66f00eSRatan Gupta combFruArea.emplace_back(recordNotPresent); 3717d9157edSMarri Devender Rao 3727d9157edSMarri Devender Rao //8th (Final byte of Header Format) is the checksum 3737d9157edSMarri Devender Rao appendDataChecksum(combFruArea); 3747d9157edSMarri Devender Rao 3757d9157edSMarri Devender Rao //Combine everything into one full IPMI FRU specification Record 3767d9157edSMarri Devender Rao //add chassis use area data 3777d9157edSMarri Devender Rao combFruArea.insert( 3787d9157edSMarri Devender Rao combFruArea.end(), chassisArea.begin(), chassisArea.end()); 3797d9157edSMarri Devender Rao 3807d9157edSMarri Devender Rao //add board area data 3817d9157edSMarri Devender Rao combFruArea.insert(combFruArea.end(), boardArea.begin(), boardArea.end()); 3827d9157edSMarri Devender Rao 3837d9157edSMarri Devender Rao //add product use area data 3847d9157edSMarri Devender Rao combFruArea.insert(combFruArea.end(), prodArea.begin(), prodArea.end()); 3857d9157edSMarri Devender Rao 3867d9157edSMarri Devender Rao return combFruArea; 3877d9157edSMarri Devender Rao } 3887d9157edSMarri Devender Rao 3897d9157edSMarri Devender Rao } //fru 3907d9157edSMarri Devender Rao } //ipmi 391