blob: 4f8d7242e1ce97cf0c6e304001911a1484517b60 [file] [log] [blame]
Lei YU6505e9d2020-09-21 17:34:32 +08001#include "inspur_oem.hpp"
2
3#include <ipmid/api.h>
4
Lei YU8a454c52020-09-23 16:52:46 +08005#include <phosphor-logging/log.hpp>
6#include <sdbusplus/bus.hpp>
7
8#include <optional>
9
Lei YU6505e9d2020-09-21 17:34:32 +080010namespace ipmi
11{
12
Lei YU8a454c52020-09-23 16:52:46 +080013#define UNUSED(x) (void)(x)
Lei YU6505e9d2020-09-21 17:34:32 +080014
Lei YU8a454c52020-09-23 16:52:46 +080015using namespace phosphor::logging;
16
17static void registerOEMFunctions() __attribute__((constructor));
18sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
19
20struct ParsedAssetInfo
Lei YU6505e9d2020-09-21 17:34:32 +080021{
Lei YU8a454c52020-09-23 16:52:46 +080022 uint8_t rwFlag;
23 uint8_t deviceType;
24 uint8_t infoType;
25 uint8_t maskAllPresentLen;
26 std::vector<uint8_t> enableStatus;
27 std::vector<uint8_t> maskPresent;
28 std::vector<uint8_t> maskAllPresent;
29 uint8_t allInfoDone;
30 uint16_t totalMessageLen;
31 std::vector<uint8_t> data;
32};
33
34void dumpAssetInfo(const ParsedAssetInfo& info)
35{
Lei YU6505e9d2020-09-21 17:34:32 +080036 fprintf(stderr,
Lei YU8a454c52020-09-23 16:52:46 +080037 "AssetInfo: rw %d, deviceType 0x%02x, infoType 0x%02x, "
38 "maskAllPresentLen %u\n",
39 info.rwFlag, info.deviceType, info.infoType,
40 info.maskAllPresentLen);
41 fprintf(stderr, "enableStatus ");
42 for (const auto& d : info.enableStatus)
43 {
44 fprintf(stderr, "0x%02x ", d);
45 }
46 fprintf(stderr, "\nmaskPresent ");
47 for (const auto& d : info.maskPresent)
48 {
49 fprintf(stderr, "0x%02x ", d);
50 }
51 fprintf(stderr, "\nmaskAllPresent ");
52 for (const auto& d : info.maskAllPresent)
53 {
54 fprintf(stderr, "0x%02x ", d);
55 }
56 fprintf(stderr, "\nallInfoDone %d, totalMessageLen %u\n", info.allInfoDone,
57 info.totalMessageLen);
58 fprintf(stderr, "data: ");
59 for (const auto& d : info.data)
60 {
61 fprintf(stderr, "0x%02x ", d);
62 }
63 fprintf(stderr, "\n");
64}
65
66std::optional<ParsedAssetInfo> parseAssetInfo(const AssetInfoHeader* h)
67{
68 auto len = h->maskAllPresentLen;
69 if (len == 0)
70 {
71 // This is invalid
72 return {};
73 }
74
75 ParsedAssetInfo info;
76 info.rwFlag = h->rwFlag;
77 info.deviceType = h->deviceType;
78 info.infoType = h->infoType;
79 info.maskAllPresentLen = len;
80 info.enableStatus.resize(len);
81 info.maskPresent.resize(len);
82 info.maskAllPresent.resize(len);
83 const uint8_t* p = &h->enableStatus;
84 memcpy(info.enableStatus.data(), p, len);
85 p += len;
86 memcpy(info.maskPresent.data(), p, len);
87 p += len;
88 memcpy(info.maskAllPresent.data(), p, len);
89 p += len;
90 info.allInfoDone = *p++;
91 info.totalMessageLen = *reinterpret_cast<const uint16_t*>(p);
92 p += sizeof(uint16_t);
93 auto dataLen = info.totalMessageLen - (sizeof(AssetInfoHeader) + 3 * len);
94 info.data.resize(dataLen);
95 memcpy(info.data.data(), p, dataLen);
96
97 dumpAssetInfo(info);
98 return info;
99}
100
101ipmi_ret_t ipmiOemInspurAssetInfo(ipmi_netfn_t /* netfn */,
102 ipmi_cmd_t /* cmd */, ipmi_request_t request,
103 ipmi_response_t response,
104 ipmi_data_len_t /* data_len */,
105 ipmi_context_t /* context */)
106{
107 auto header = reinterpret_cast<AssetInfoHeader*>(request);
108 uint8_t* res = reinterpret_cast<uint8_t*>(response);
109 UNUSED(res);
110
111 auto info = parseAssetInfo(header);
112 auto deviceType = info->deviceType;
113 if (deviceType != 0x05)
114 {
115 log<level::WARNING>("Device type not supported yet");
116 return IPMI_CC_UNSPECIFIED_ERROR;
117 }
118
119 // For now we only support BIOS type
120 printf("%s: Received BIOS info\n", __func__);
121
122 return IPMI_CC_UNSPECIFIED_ERROR;
Lei YU6505e9d2020-09-21 17:34:32 +0800123}
124
125void registerOEMFunctions(void)
126{
127 ipmi_register_callback(NETFN_OEM_INSPUR, CMD_OEM_ASSET_INFO, nullptr,
128 ipmiOemInspurAssetInfo, SYSTEM_INTERFACE);
129}
130
131} // namespace ipmi