blob: ea1233b00509653c3e7f2754c4e8538dd3da3b17 [file] [log] [blame]
Patrick Ventureab296412020-12-30 13:39:37 -08001/*
2// Copyright (c) 2018 Intel 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/// \file FruUtils.hpp
17
18#pragma once
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053019#include <boost/container/flat_map.hpp>
Patrick Ventureab296412020-12-30 13:39:37 -080020
21#include <cstdint>
22#include <functional>
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053023#include <regex>
Patrick Ventureab296412020-12-30 13:39:37 -080024#include <string>
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053025#include <utility>
Patrick Ventureab296412020-12-30 13:39:37 -080026#include <vector>
Patrick Ventureab296412020-12-30 13:39:37 -080027extern "C"
28{
29// Include for I2C_SMBUS_BLOCK_MAX
30#include <linux/i2c.h>
31}
32
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053033constexpr size_t fruBlockSize = 8;
34
Kumar Thangavelc74e7512022-02-03 22:53:05 +053035using DeviceMap = boost::container::flat_map<int, std::vector<uint8_t>>;
36using BusMap = boost::container::flat_map<int, std::shared_ptr<DeviceMap>>;
37
38inline BusMap busMap;
39
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053040enum class DecodeState
41{
42 ok,
43 end,
44 err,
45};
46
47enum class resCodes
48{
49 resOK,
50 resWarn,
51 resErr
52};
53
Patrick Ventureab296412020-12-30 13:39:37 -080054enum class fruAreas
55{
56 fruAreaInternal = 0,
57 fruAreaChassis,
58 fruAreaBoard,
59 fruAreaProduct,
60 fruAreaMultirecord
61};
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053062
Ed Tanous07d467b2021-02-23 14:48:37 -080063const std::vector<std::string> fruAreaNames = {"INTERNAL", "CHASSIS", "BOARD",
64 "PRODUCT", "MULTIRECORD"};
65const std::regex nonAsciiRegex("[^\x01-\x7f]");
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053066
Ed Tanous07d467b2021-02-23 14:48:37 -080067const std::vector<std::string> chassisFruAreas = {"PART_NUMBER",
68 "SERIAL_NUMBER"};
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053069
Ed Tanous07d467b2021-02-23 14:48:37 -080070const std::vector<std::string> boardFruAreas = {"MANUFACTURER", "PRODUCT_NAME",
71 "SERIAL_NUMBER", "PART_NUMBER",
72 "FRU_VERSION_ID"};
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053073
Ed Tanous07d467b2021-02-23 14:48:37 -080074const std::vector<std::string> productFruAreas = {
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053075 "MANUFACTURER", "PRODUCT_NAME", "PART_NUMBER", "VERSION",
76 "SERIAL_NUMBER", "ASSET_TAG", "FRU_VERSION_ID"};
77
Ed Tanous07d467b2021-02-23 14:48:37 -080078const std::string fruCustomFieldName = "INFO_AM";
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053079
Patrick Ventureab296412020-12-30 13:39:37 -080080inline fruAreas operator++(fruAreas& x)
81{
82 return x = static_cast<fruAreas>(std::underlying_type<fruAreas>::type(x) +
83 1);
84}
85
Patrick Ventureab296412020-12-30 13:39:37 -080086using ReadBlockFunc =
87 std::function<int64_t(int flag, int file, uint16_t address, uint16_t offset,
88 uint8_t length, uint8_t* outBuf)>;
89
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053090inline const std::string& getFruAreaName(fruAreas area)
91{
Ed Tanous07d467b2021-02-23 14:48:37 -080092 return fruAreaNames[static_cast<unsigned int>(area)];
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053093}
94
Ed Tanous07d467b2021-02-23 14:48:37 -080095std::tm intelEpoch(void);
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053096
97char sixBitToChar(uint8_t val);
98
99/* 0xd - 0xf are reserved values, but not fatal; use a placeholder char. */
100const char bcdHighChars[] = {
101 ' ', '-', '.', 'X', 'X', 'X',
102};
103
104char bcdPlusToChar(uint8_t val);
105
106bool verifyOffset(const std::vector<uint8_t>& fruBytes, fruAreas currentArea,
107 uint8_t len);
108
109std::pair<DecodeState, std::string>
110 decodeFRUData(std::vector<uint8_t>::const_iterator& iter,
111 const std::vector<uint8_t>::const_iterator& end,
112 bool isLangEng);
113
114bool checkLangEng(uint8_t lang);
115
116resCodes
Michael Shen0961b112022-02-22 11:06:33 +0800117 formatIPMIFRU(const std::vector<uint8_t>& fruBytes,
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +0530118 boost::container::flat_map<std::string, std::string>& result);
119
120std::vector<uint8_t>& getFRUInfo(const uint8_t& bus, const uint8_t& address);
121
122uint8_t calculateChecksum(std::vector<uint8_t>::const_iterator iter,
123 std::vector<uint8_t>::const_iterator end);
124
125uint8_t calculateChecksum(std::vector<uint8_t>& fruAreaData);
126
127unsigned int updateFRUAreaLenAndChecksum(std::vector<uint8_t>& fruData,
128 size_t fruAreaStart,
129 size_t fruAreaEndOfFieldsOffset,
130 size_t fruAreaEndOffset);
131
132ssize_t getFieldLength(uint8_t fruFieldTypeLenValue);
133
Oskar Senftbd4075f2021-10-05 23:42:43 -0400134/// \brief Find a FRU header.
135/// \param flag the flag required for raw i2c
136/// \param file the open file handle
137/// \param address the i2c device address
138/// \param readBlock a read method
139/// \param errorHelp and a helper string for failures
140/// \param blockData buffer to return the last read block
141/// \param baseOffset the offset to start the search at;
142/// set to 0 to perform search;
143/// returns the offset at which a header was found
144/// \return whether a header was found
145bool findFRUHeader(int flag, int file, uint16_t address,
Kumar Thangavelc74e7512022-02-03 22:53:05 +0530146 const ReadBlockFunc& readBlock, const std::string& errorHelp,
Oskar Senftbd4075f2021-10-05 23:42:43 -0400147 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX>& blockData,
148 uint16_t& baseOffset);
149
Patrick Ventureab296412020-12-30 13:39:37 -0800150/// \brief Read and validate FRU contents.
151/// \param flag the flag required for raw i2c
152/// \param file the open file handle
153/// \param address the i2c device address
154/// \param readBlock a read method
155/// \param errorHelp and a helper string for failures
156/// \return the FRU contents from the file
157std::vector<uint8_t> readFRUContents(int flag, int file, uint16_t address,
Ed Tanous07d467b2021-02-23 14:48:37 -0800158 const ReadBlockFunc& readBlock,
Patrick Ventureab296412020-12-30 13:39:37 -0800159 const std::string& errorHelp);
160
161/// \brief Validate an IPMI FRU common header
162/// \param blockData the bytes comprising the common header
163/// \return true if valid
164bool validateHeader(const std::array<uint8_t, I2C_SMBUS_BLOCK_MAX>& blockData);
165
166/// \brief Get offset for a common header area
167/// \param area - the area
168/// \return the field offset
169unsigned int getHeaderAreaFieldOffset(fruAreas area);