blob: 906b77efb33a571bb93f63f2656ba49cc45750a1 [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
35enum class DecodeState
36{
37 ok,
38 end,
39 err,
40};
41
42enum class resCodes
43{
44 resOK,
45 resWarn,
46 resErr
47};
48
Patrick Ventureab296412020-12-30 13:39:37 -080049enum class fruAreas
50{
51 fruAreaInternal = 0,
52 fruAreaChassis,
53 fruAreaBoard,
54 fruAreaProduct,
55 fruAreaMultirecord
56};
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053057
Ed Tanous07d467b2021-02-23 14:48:37 -080058const std::vector<std::string> fruAreaNames = {"INTERNAL", "CHASSIS", "BOARD",
59 "PRODUCT", "MULTIRECORD"};
60const std::regex nonAsciiRegex("[^\x01-\x7f]");
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053061
Ed Tanous07d467b2021-02-23 14:48:37 -080062const std::vector<std::string> chassisFruAreas = {"PART_NUMBER",
63 "SERIAL_NUMBER"};
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053064
Ed Tanous07d467b2021-02-23 14:48:37 -080065const std::vector<std::string> boardFruAreas = {"MANUFACTURER", "PRODUCT_NAME",
66 "SERIAL_NUMBER", "PART_NUMBER",
67 "FRU_VERSION_ID"};
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053068
Ed Tanous07d467b2021-02-23 14:48:37 -080069const std::vector<std::string> productFruAreas = {
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053070 "MANUFACTURER", "PRODUCT_NAME", "PART_NUMBER", "VERSION",
71 "SERIAL_NUMBER", "ASSET_TAG", "FRU_VERSION_ID"};
72
Ed Tanous07d467b2021-02-23 14:48:37 -080073const std::string fruCustomFieldName = "INFO_AM";
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053074
Patrick Ventureab296412020-12-30 13:39:37 -080075inline fruAreas operator++(fruAreas& x)
76{
77 return x = static_cast<fruAreas>(std::underlying_type<fruAreas>::type(x) +
78 1);
79}
80
Patrick Ventureab296412020-12-30 13:39:37 -080081using ReadBlockFunc =
82 std::function<int64_t(int flag, int file, uint16_t address, uint16_t offset,
83 uint8_t length, uint8_t* outBuf)>;
84
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053085inline const std::string& getFruAreaName(fruAreas area)
86{
Ed Tanous07d467b2021-02-23 14:48:37 -080087 return fruAreaNames[static_cast<unsigned int>(area)];
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053088}
89
Ed Tanous07d467b2021-02-23 14:48:37 -080090std::tm intelEpoch(void);
Kumar Thangavelc8dc4af2021-01-12 10:36:38 +053091
92char sixBitToChar(uint8_t val);
93
94/* 0xd - 0xf are reserved values, but not fatal; use a placeholder char. */
95const char bcdHighChars[] = {
96 ' ', '-', '.', 'X', 'X', 'X',
97};
98
99char bcdPlusToChar(uint8_t val);
100
101bool verifyOffset(const std::vector<uint8_t>& fruBytes, fruAreas currentArea,
102 uint8_t len);
103
104std::pair<DecodeState, std::string>
105 decodeFRUData(std::vector<uint8_t>::const_iterator& iter,
106 const std::vector<uint8_t>::const_iterator& end,
107 bool isLangEng);
108
109bool checkLangEng(uint8_t lang);
110
111resCodes
112 formatFRU(const std::vector<uint8_t>& fruBytes,
113 boost::container::flat_map<std::string, std::string>& result);
114
115std::vector<uint8_t>& getFRUInfo(const uint8_t& bus, const uint8_t& address);
116
117uint8_t calculateChecksum(std::vector<uint8_t>::const_iterator iter,
118 std::vector<uint8_t>::const_iterator end);
119
120uint8_t calculateChecksum(std::vector<uint8_t>& fruAreaData);
121
122unsigned int updateFRUAreaLenAndChecksum(std::vector<uint8_t>& fruData,
123 size_t fruAreaStart,
124 size_t fruAreaEndOfFieldsOffset,
125 size_t fruAreaEndOffset);
126
127ssize_t getFieldLength(uint8_t fruFieldTypeLenValue);
128
Oskar Senftbd4075f2021-10-05 23:42:43 -0400129/// \brief Find a FRU header.
130/// \param flag the flag required for raw i2c
131/// \param file the open file handle
132/// \param address the i2c device address
133/// \param readBlock a read method
134/// \param errorHelp and a helper string for failures
135/// \param blockData buffer to return the last read block
136/// \param baseOffset the offset to start the search at;
137/// set to 0 to perform search;
138/// returns the offset at which a header was found
139/// \return whether a header was found
140bool findFRUHeader(int flag, int file, uint16_t address,
141 const ReadBlockFunc& readBlock,
142 const std::string& errorHelp,
143 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX>& blockData,
144 uint16_t& baseOffset);
145
Patrick Ventureab296412020-12-30 13:39:37 -0800146/// \brief Read and validate FRU contents.
147/// \param flag the flag required for raw i2c
148/// \param file the open file handle
149/// \param address the i2c device address
150/// \param readBlock a read method
151/// \param errorHelp and a helper string for failures
152/// \return the FRU contents from the file
153std::vector<uint8_t> readFRUContents(int flag, int file, uint16_t address,
Ed Tanous07d467b2021-02-23 14:48:37 -0800154 const ReadBlockFunc& readBlock,
Patrick Ventureab296412020-12-30 13:39:37 -0800155 const std::string& errorHelp);
156
157/// \brief Validate an IPMI FRU common header
158/// \param blockData the bytes comprising the common header
159/// \return true if valid
160bool validateHeader(const std::array<uint8_t, I2C_SMBUS_BLOCK_MAX>& blockData);
161
162/// \brief Get offset for a common header area
163/// \param area - the area
164/// \return the field offset
165unsigned int getHeaderAreaFieldOffset(fruAreas area);