blob: 0806317e501f69879796de5467e91a6fbe969412 [file] [log] [blame]
Jia, Chunhuia835eaa2018-09-05 09:00:41 +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
Jason M. Bills64796042018-10-03 16:51:55 -070017#include "xyz/openbmc_project/Common/error.hpp"
18
Jason M. Bills6d9c83f2019-02-08 14:02:19 -080019#include <ipmid/api.h>
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080020
21#include <array>
Jason M. Bills64796042018-10-03 16:51:55 -070022#include <commandutils.hpp>
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080023#include <iostream>
24#include <oemcommands.hpp>
Jason M. Bills3f7c5e42018-10-03 14:00:41 -070025#include <phosphor-ipmi-host/utils.hpp>
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080026#include <phosphor-logging/log.hpp>
27#include <sdbusplus/bus.hpp>
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080028#include <string>
29#include <vector>
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080030
31namespace ipmi
32{
Jason M. Bills64796042018-10-03 16:51:55 -070033static void registerOEMFunctions() __attribute__((constructor));
Jason M. Bills6d9c83f2019-02-08 14:02:19 -080034sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection()); // from ipmid/api.h
Jason M. Bills64796042018-10-03 16:51:55 -070035static constexpr size_t maxFRUStringLength = 0x3F;
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080036
37// return code: 0 successful
38int8_t getChassisSerialNumber(sdbusplus::bus::bus& bus, std::string& serial)
39{
40 std::string objpath = "/xyz/openbmc_project/FruDevice";
41 std::string intf = "xyz.openbmc_project.FruDeviceManager";
42 std::string service = getService(bus, intf, objpath);
43 ObjectValueTree valueTree = getManagedObjects(bus, service, "/");
44 if (valueTree.empty())
45 {
46 phosphor::logging::log<phosphor::logging::level::ERR>(
47 "No object implements interface",
48 phosphor::logging::entry("INTF=%s", intf.c_str()));
49 return -1;
50 }
51
Jason M. Bills64796042018-10-03 16:51:55 -070052 for (const auto& item : valueTree)
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080053 {
54 auto interface = item.second.find("xyz.openbmc_project.FruDevice");
55 if (interface == item.second.end())
56 {
57 continue;
58 }
59
60 auto property = interface->second.find("CHASSIS_SERIAL_NUMBER");
61 if (property == interface->second.end())
62 {
63 continue;
64 }
65
66 try
67 {
68 Value variant = property->second;
Jason M. Bills64796042018-10-03 16:51:55 -070069 std::string& result =
70 sdbusplus::message::variant_ns::get<std::string>(variant);
71 if (result.size() > maxFRUStringLength)
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080072 {
73 phosphor::logging::log<phosphor::logging::level::ERR>(
74 "FRU serial number exceed maximum length");
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080075 return -1;
76 }
Jason M. Bills64796042018-10-03 16:51:55 -070077 serial = result;
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080078 return 0;
79 }
Jason M. Bills64796042018-10-03 16:51:55 -070080 catch (sdbusplus::message::variant_ns::bad_variant_access& e)
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080081 {
Jason M. Bills64796042018-10-03 16:51:55 -070082 phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080083 return -1;
84 }
85 }
86 return -1;
87}
Jason M. Bills64796042018-10-03 16:51:55 -070088
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080089ipmi_ret_t ipmiOEMWildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
90 ipmi_request_t request, ipmi_response_t response,
Jason M. Bills64796042018-10-03 16:51:55 -070091 ipmi_data_len_t dataLen, ipmi_context_t context)
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080092{
Jason M. Bills64796042018-10-03 16:51:55 -070093 printCommand(+netfn, +cmd);
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080094 // Status code.
95 ipmi_ret_t rc = IPMI_CC_INVALID;
Jason M. Bills64796042018-10-03 16:51:55 -070096 *dataLen = 0;
Jia, Chunhuia835eaa2018-09-05 09:00:41 +080097 return rc;
98}
99
100// Returns the Chassis Identifier (serial #)
101ipmi_ret_t ipmiOEMGetChassisIdentifier(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
102 ipmi_request_t request,
103 ipmi_response_t response,
Jason M. Bills64796042018-10-03 16:51:55 -0700104 ipmi_data_len_t dataLen,
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800105 ipmi_context_t context)
106{
107 std::string serial;
Jason M. Bills64796042018-10-03 16:51:55 -0700108 if (*dataLen != 0) // invalid request if there are extra parameters
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800109 {
Jason M. Bills64796042018-10-03 16:51:55 -0700110 *dataLen = 0;
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800111 return IPMI_CC_REQ_DATA_LEN_INVALID;
112 }
Jason M. Bills64796042018-10-03 16:51:55 -0700113 if (getChassisSerialNumber(dbus, serial) == 0)
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800114 {
Jason M. Bills64796042018-10-03 16:51:55 -0700115 *dataLen = serial.size(); // length will never exceed response length
116 // as it is checked in getChassisSerialNumber
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800117 char* resp = static_cast<char*>(response);
Jason M. Bills64796042018-10-03 16:51:55 -0700118 serial.copy(resp, *dataLen);
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800119 return IPMI_CC_OK;
120 }
Jason M. Bills64796042018-10-03 16:51:55 -0700121 *dataLen = 0;
122 return IPMI_CC_RESPONSE_ERROR;
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800123}
124
125ipmi_ret_t ipmiOEMSetSystemGUID(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
126 ipmi_request_t request,
127 ipmi_response_t response,
Jason M. Bills64796042018-10-03 16:51:55 -0700128 ipmi_data_len_t dataLen, ipmi_context_t context)
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800129{
130 static constexpr size_t safeBufferLength = 50;
131 char buf[safeBufferLength] = {0};
132 GUIDData* Data = reinterpret_cast<GUIDData*>(request);
133
Jason M. Bills64796042018-10-03 16:51:55 -0700134 if (*dataLen != sizeof(GUIDData)) // 16bytes
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800135 {
Jason M. Bills64796042018-10-03 16:51:55 -0700136 *dataLen = 0;
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800137 return IPMI_CC_REQ_DATA_LEN_INVALID;
138 }
139
Jason M. Bills64796042018-10-03 16:51:55 -0700140 *dataLen = 0;
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800141
142 snprintf(
143 buf, safeBufferLength,
144 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
145 Data->timeLow4, Data->timeLow3, Data->timeLow2, Data->timeLow1,
146 Data->timeMid2, Data->timeMid1, Data->timeHigh2, Data->timeHigh1,
147 Data->clock2, Data->clock1, Data->node6, Data->node5, Data->node4,
148 Data->node3, Data->node2, Data->node1);
149 // UUID is in RFC4122 format. Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
150 std::string guid = buf;
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800151
152 std::string objpath = "/xyz/openbmc_project/control/host0/systemGUID";
153 std::string intf = "xyz.openbmc_project.Common.UUID";
Jason M. Bills64796042018-10-03 16:51:55 -0700154 std::string service = getService(dbus, intf, objpath);
155 setDbusProperty(dbus, service, objpath, intf, "UUID", guid);
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800156 return IPMI_CC_OK;
157}
158
159ipmi_ret_t ipmiOEMSetBIOSID(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
160 ipmi_request_t request, ipmi_response_t response,
161 ipmi_data_len_t dataLen, ipmi_context_t context)
162{
163 DeviceInfo* data = reinterpret_cast<DeviceInfo*>(request);
164
Jason M. Bills64796042018-10-03 16:51:55 -0700165 if ((*dataLen < 2) || (*dataLen != (1 + data->biosIDLength)))
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800166 {
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800167 *dataLen = 0;
168 return IPMI_CC_REQ_DATA_LEN_INVALID;
169 }
Jason M. Bills64796042018-10-03 16:51:55 -0700170 std::string idString((char*)data->biosId, data->biosIDLength);
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800171
Jason M. Bills64796042018-10-03 16:51:55 -0700172 std::string service = getService(dbus, biosIntf, biosObjPath);
173 setDbusProperty(dbus, service, biosObjPath, biosIntf, biosProp, idString);
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800174 uint8_t* bytesWritten = static_cast<uint8_t*>(response);
175 *bytesWritten =
Jason M. Bills64796042018-10-03 16:51:55 -0700176 data->biosIDLength; // how many bytes are written into storage
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800177 *dataLen = 1;
178 return IPMI_CC_OK;
179}
180
181ipmi_ret_t ipmiOEMGetDeviceInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
182 ipmi_request_t request,
183 ipmi_response_t response,
184 ipmi_data_len_t dataLen, ipmi_context_t context)
185{
186 GetOemDeviceInfoReq* req = reinterpret_cast<GetOemDeviceInfoReq*>(request);
187 GetOemDeviceInfoRes* res = reinterpret_cast<GetOemDeviceInfoRes*>(response);
188
189 if (*dataLen == 0)
190 {
Jason M. Bills64796042018-10-03 16:51:55 -0700191 *dataLen = 0;
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800192 return IPMI_CC_REQ_DATA_LEN_INVALID;
193 }
194
195 size_t reqDataLen = *dataLen;
196 *dataLen = 0;
Jason M. Bills64796042018-10-03 16:51:55 -0700197 if (req->entityType > static_cast<uint8_t>(OEMDevEntityType::sdrVer))
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800198 {
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800199 return IPMI_CC_INVALID_FIELD_REQUEST;
200 }
201
202 // handle OEM command items
Jason M. Bills64796042018-10-03 16:51:55 -0700203 switch (OEMDevEntityType(req->entityType))
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800204 {
205 case OEMDevEntityType::biosId:
206 {
207 if (sizeof(GetOemDeviceInfoReq) != reqDataLen)
208 {
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800209 return IPMI_CC_REQ_DATA_LEN_INVALID;
210 }
211
Jason M. Bills64796042018-10-03 16:51:55 -0700212 std::string service = getService(dbus, biosIntf, biosObjPath);
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800213 try
214 {
Jason M. Bills64796042018-10-03 16:51:55 -0700215 Value variant = getDbusProperty(dbus, service, biosObjPath,
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800216 biosIntf, biosProp);
Jason M. Bills64796042018-10-03 16:51:55 -0700217 std::string& idString =
218 sdbusplus::message::variant_ns::get<std::string>(variant);
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800219 if (req->offset >= idString.size())
220 {
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800221 return IPMI_CC_PARM_OUT_OF_RANGE;
222 }
Jason M. Bills64796042018-10-03 16:51:55 -0700223 size_t length = 0;
224 if (req->countToRead > (idString.size() - req->offset))
225 {
226 length = idString.size() - req->offset;
227 }
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800228 else
229 {
Jason M. Bills64796042018-10-03 16:51:55 -0700230 length = req->countToRead;
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800231 }
Jason M. Bills64796042018-10-03 16:51:55 -0700232 std::copy(idString.begin() + req->offset, idString.end(),
233 res->data);
234 res->resDatalen = length;
235 *dataLen = res->resDatalen + 1;
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800236 }
Jason M. Bills64796042018-10-03 16:51:55 -0700237 catch (sdbusplus::message::variant_ns::bad_variant_access& e)
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800238 {
Jason M. Bills64796042018-10-03 16:51:55 -0700239 phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800240 return IPMI_CC_UNSPECIFIED_ERROR;
241 }
242 }
243 break;
244
245 case OEMDevEntityType::devVer:
246 case OEMDevEntityType::sdrVer:
247 // TODO:
248 return IPMI_CC_ILLEGAL_COMMAND;
249 default:
250 return IPMI_CC_INVALID_FIELD_REQUEST;
251 }
252 return IPMI_CC_OK;
253}
254
255ipmi_ret_t ipmiOEMGetAICFRU(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
256 ipmi_request_t request, ipmi_response_t response,
257 ipmi_data_len_t dataLen, ipmi_context_t context)
258{
259 if (*dataLen != 0)
260 {
Jason M. Bills64796042018-10-03 16:51:55 -0700261 *dataLen = 0;
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800262 return IPMI_CC_REQ_DATA_LEN_INVALID;
263 }
264
265 *dataLen = 1;
266 uint8_t* res = reinterpret_cast<uint8_t*>(response);
267 // temporary fix. We don't support AIC FRU now. Just tell BIOS that no
268 // AIC is available so that BIOS will not timeout repeatly which leads to
269 // slow booting.
270 *res = 0; // Byte1=Count of SlotPosition/FruID records.
271 return IPMI_CC_OK;
272}
273
Jason M. Bills64796042018-10-03 16:51:55 -0700274ipmi_ret_t ipmiOEMGetPowerRestoreDelay(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
275 ipmi_request_t request,
276 ipmi_response_t response,
277 ipmi_data_len_t dataLen,
278 ipmi_context_t context)
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800279{
Jason M. Bills64796042018-10-03 16:51:55 -0700280 GetPowerRestoreDelayRes* resp =
281 reinterpret_cast<GetPowerRestoreDelayRes*>(response);
282
283 if (*dataLen != 0)
284 {
285 *dataLen = 0;
286 return IPMI_CC_REQ_DATA_LEN_INVALID;
287 }
288
289 std::string service =
290 getService(dbus, powerRestoreDelayIntf, powerRestoreDelayObjPath);
291 Value variant =
292 getDbusProperty(dbus, service, powerRestoreDelayObjPath,
293 powerRestoreDelayIntf, powerRestoreDelayProp);
294
295 uint16_t delay = sdbusplus::message::variant_ns::get<uint16_t>(variant);
296 resp->byteLSB = delay;
297 resp->byteMSB = delay >> 8;
298
299 *dataLen = sizeof(GetPowerRestoreDelayRes);
300
301 return IPMI_CC_OK;
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800302}
303
Jason M. Bills64796042018-10-03 16:51:55 -0700304ipmi_ret_t ipmiOEMSetPowerRestoreDelay(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
305 ipmi_request_t request,
306 ipmi_response_t response,
307 ipmi_data_len_t dataLen,
308 ipmi_context_t context)
309{
310 SetPowerRestoreDelayReq* data =
311 reinterpret_cast<SetPowerRestoreDelayReq*>(request);
312 uint16_t delay = 0;
313
314 if (*dataLen != sizeof(SetPowerRestoreDelayReq))
315 {
316 *dataLen = 0;
317 return IPMI_CC_REQ_DATA_LEN_INVALID;
318 }
319 delay = data->byteMSB;
320 delay = (delay << 8) | data->byteLSB;
321 std::string service =
322 getService(dbus, powerRestoreDelayIntf, powerRestoreDelayObjPath);
323 setDbusProperty(dbus, service, powerRestoreDelayObjPath,
324 powerRestoreDelayIntf, powerRestoreDelayProp, delay);
325 *dataLen = 0;
326
327 return IPMI_CC_OK;
328}
329
330ipmi_ret_t ipmiOEMGetProcessorErrConfig(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
331 ipmi_request_t request,
332 ipmi_response_t response,
333 ipmi_data_len_t dataLen,
334 ipmi_context_t context)
335{
336 GetProcessorErrConfigRes* resp =
337 reinterpret_cast<GetProcessorErrConfigRes*>(response);
338
339 if (*dataLen != 0)
340 {
341 *dataLen = 0;
342 return IPMI_CC_REQ_DATA_LEN_INVALID;
343 }
344
345 std::string service =
346 getService(dbus, processorErrConfigIntf, processorErrConfigObjPath);
347 Value variant = getDbusProperty(dbus, service, processorErrConfigObjPath,
348 processorErrConfigIntf, "ResetCfg");
349 resp->resetCfg = sdbusplus::message::variant_ns::get<uint8_t>(variant);
350
351 std::vector<uint8_t> caterrStatus;
Kuiying Wangbc546672018-11-23 15:41:05 +0800352 sdbusplus::message::variant<std::vector<uint8_t>> message;
Jason M. Bills64796042018-10-03 16:51:55 -0700353
354 auto method =
355 dbus.new_method_call(service.c_str(), processorErrConfigObjPath,
356 "org.freedesktop.DBus.Properties", "Get");
357
358 method.append(processorErrConfigIntf, "CATERRStatus");
Kuiying Wangbc546672018-11-23 15:41:05 +0800359 auto reply = dbus.call(method);
Jason M. Bills64796042018-10-03 16:51:55 -0700360
361 try
362 {
Kuiying Wangbc546672018-11-23 15:41:05 +0800363 reply.read(message);
364 caterrStatus =
365 sdbusplus::message::variant_ns::get<std::vector<uint8_t>>(message);
Jason M. Bills64796042018-10-03 16:51:55 -0700366 }
367 catch (sdbusplus::exception_t&)
368 {
Kuiying Wangbc546672018-11-23 15:41:05 +0800369 phosphor::logging::log<phosphor::logging::level::ERR>(
Jason M. Bills64796042018-10-03 16:51:55 -0700370 "ipmiOEMGetProcessorErrConfig: error on dbus",
371 phosphor::logging::entry("PRORPERTY=CATERRStatus"),
372 phosphor::logging::entry("PATH=%s", processorErrConfigObjPath),
373 phosphor::logging::entry("INTERFACE=%s", processorErrConfigIntf));
374 return IPMI_CC_UNSPECIFIED_ERROR;
375 }
376
377 size_t len =
378 maxCPUNum <= caterrStatus.size() ? maxCPUNum : caterrStatus.size();
379 caterrStatus.resize(len);
380 std::copy(caterrStatus.begin(), caterrStatus.end(), resp->caterrStatus);
381 *dataLen = sizeof(GetProcessorErrConfigRes);
382
383 return IPMI_CC_OK;
384}
385
386ipmi_ret_t ipmiOEMSetProcessorErrConfig(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
387 ipmi_request_t request,
388 ipmi_response_t response,
389 ipmi_data_len_t dataLen,
390 ipmi_context_t context)
391{
392 SetProcessorErrConfigReq* req =
393 reinterpret_cast<SetProcessorErrConfigReq*>(request);
394
395 if (*dataLen != sizeof(SetProcessorErrConfigReq))
396 {
397 *dataLen = 0;
398 return IPMI_CC_REQ_DATA_LEN_INVALID;
399 }
400 std::string service =
401 getService(dbus, processorErrConfigIntf, processorErrConfigObjPath);
402 setDbusProperty(dbus, service, processorErrConfigObjPath,
403 processorErrConfigIntf, "ResetCfg", req->resetCfg);
404
405 setDbusProperty(dbus, service, processorErrConfigObjPath,
406 processorErrConfigIntf, "ResetErrorOccurrenceCounts",
407 req->resetErrorOccurrenceCounts);
408 *dataLen = 0;
409
410 return IPMI_CC_OK;
411}
412
Yong Li703922d2018-11-06 13:25:31 +0800413ipmi_ret_t ipmiOEMGetShutdownPolicy(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
414 ipmi_request_t request,
415 ipmi_response_t response,
416 ipmi_data_len_t dataLen,
417 ipmi_context_t context)
418{
419 GetOEMShutdownPolicyRes* resp =
420 reinterpret_cast<GetOEMShutdownPolicyRes*>(response);
421
422 if (*dataLen != 0)
423 {
424 phosphor::logging::log<phosphor::logging::level::ERR>(
425 "oem_set_shutdown_policy: invalid input len!");
426 *dataLen = 0;
427 return IPMI_CC_REQ_DATA_LEN_INVALID;
428 }
429
430 *dataLen = 0;
431
432 try
433 {
434 std::string service =
435 getService(dbus, oemShutdownPolicyIntf, oemShutdownPolicyObjPath);
436 Value variant = getDbusProperty(dbus, service, oemShutdownPolicyObjPath,
437 oemShutdownPolicyIntf,
438 oemShutdownPolicyObjPathProp);
439 resp->policy = sdbusplus::message::variant_ns::get<uint8_t>(variant);
440 // TODO needs to check if it is multi-node products,
441 // policy is only supported on node 3/4
442 resp->policySupport = shutdownPolicySupported;
443 }
444 catch (sdbusplus::exception_t& e)
445 {
446 phosphor::logging::log<phosphor::logging::level::ERR>(e.description());
447 return IPMI_CC_UNSPECIFIED_ERROR;
448 }
449
450 *dataLen = sizeof(GetOEMShutdownPolicyRes);
451 return IPMI_CC_OK;
452}
453
454ipmi_ret_t ipmiOEMSetShutdownPolicy(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
455 ipmi_request_t request,
456 ipmi_response_t response,
457 ipmi_data_len_t dataLen,
458 ipmi_context_t context)
459{
460 uint8_t* req = reinterpret_cast<uint8_t*>(request);
461
462 // TODO needs to check if it is multi-node products,
463 // policy is only supported on node 3/4
464 if (*dataLen != 1)
465 {
466 phosphor::logging::log<phosphor::logging::level::ERR>(
467 "oem_set_shutdown_policy: invalid input len!");
468 *dataLen = 0;
469 return IPMI_CC_REQ_DATA_LEN_INVALID;
470 }
471
472 *dataLen = 0;
473 if ((*req != noShutdownOnOCOT) && (*req != shutdownOnOCOT))
474 {
475 phosphor::logging::log<phosphor::logging::level::ERR>(
476 "oem_set_shutdown_policy: invalid input!");
477 return IPMI_CC_INVALID_FIELD_REQUEST;
478 }
479
480 try
481 {
482 std::string service =
483 getService(dbus, oemShutdownPolicyIntf, oemShutdownPolicyObjPath);
484 setDbusProperty(dbus, service, oemShutdownPolicyObjPath,
485 oemShutdownPolicyIntf, oemShutdownPolicyObjPathProp,
486 *req);
487 }
488 catch (sdbusplus::exception_t& e)
489 {
490 phosphor::logging::log<phosphor::logging::level::ERR>(e.description());
491 return IPMI_CC_UNSPECIFIED_ERROR;
492 }
493
494 return IPMI_CC_OK;
495}
496
Jason M. Bills64796042018-10-03 16:51:55 -0700497static void registerOEMFunctions(void)
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800498{
499 phosphor::logging::log<phosphor::logging::level::INFO>(
500 "Registering OEM commands");
Jason M. Bills64796042018-10-03 16:51:55 -0700501 ipmiPrintAndRegister(netfnIntcOEMGeneral, IPMI_CMD_WILDCARD, NULL,
502 ipmiOEMWildcard,
503 PRIVILEGE_USER); // wildcard default handler
504 ipmiPrintAndRegister(netfunIntelAppOEM, IPMI_CMD_WILDCARD, NULL,
505 ipmiOEMWildcard,
506 PRIVILEGE_USER); // wildcard default handler
507 ipmiPrintAndRegister(
508 netfnIntcOEMGeneral,
509 static_cast<ipmi_cmd_t>(
510 IPMINetfnIntelOEMGeneralCmd::cmdGetChassisIdentifier),
511 NULL, ipmiOEMGetChassisIdentifier,
512 PRIVILEGE_USER); // get chassis identifier
513 ipmiPrintAndRegister(
514 netfnIntcOEMGeneral,
515 static_cast<ipmi_cmd_t>(IPMINetfnIntelOEMGeneralCmd::cmdSetSystemGUID),
516 NULL, ipmiOEMSetSystemGUID,
517 PRIVILEGE_ADMIN); // set system guid
518 ipmiPrintAndRegister(
519 netfnIntcOEMGeneral,
520 static_cast<ipmi_cmd_t>(IPMINetfnIntelOEMGeneralCmd::cmdSetBIOSID),
521 NULL, ipmiOEMSetBIOSID, PRIVILEGE_ADMIN);
522 ipmiPrintAndRegister(netfnIntcOEMGeneral,
523 static_cast<ipmi_cmd_t>(
524 IPMINetfnIntelOEMGeneralCmd::cmdGetOEMDeviceInfo),
525 NULL, ipmiOEMGetDeviceInfo, PRIVILEGE_USER);
526 ipmiPrintAndRegister(
527 netfnIntcOEMGeneral,
528 static_cast<ipmi_cmd_t>(
529 IPMINetfnIntelOEMGeneralCmd::cmdGetAICSlotFRUIDSlotPosRecords),
530 NULL, ipmiOEMGetAICFRU, PRIVILEGE_USER);
531 ipmiPrintAndRegister(
532 netfnIntcOEMGeneral,
533 static_cast<ipmi_cmd_t>(
534 IPMINetfnIntelOEMGeneralCmd::cmdSetPowerRestoreDelay),
535 NULL, ipmiOEMSetPowerRestoreDelay, PRIVILEGE_OPERATOR);
536 ipmiPrintAndRegister(
537 netfnIntcOEMGeneral,
538 static_cast<ipmi_cmd_t>(
539 IPMINetfnIntelOEMGeneralCmd::cmdGetPowerRestoreDelay),
540 NULL, ipmiOEMGetPowerRestoreDelay, PRIVILEGE_USER);
541 ipmiPrintAndRegister(
542 netfnIntcOEMGeneral,
543 static_cast<ipmi_cmd_t>(
544 IPMINetfnIntelOEMGeneralCmd::cmdGetProcessorErrConfig),
545 NULL, ipmiOEMGetProcessorErrConfig, PRIVILEGE_USER);
546 ipmiPrintAndRegister(
547 netfnIntcOEMGeneral,
548 static_cast<ipmi_cmd_t>(
549 IPMINetfnIntelOEMGeneralCmd::cmdSetProcessorErrConfig),
550 NULL, ipmiOEMSetProcessorErrConfig, PRIVILEGE_ADMIN);
Yong Li703922d2018-11-06 13:25:31 +0800551 ipmiPrintAndRegister(netfnIntcOEMGeneral,
552 static_cast<ipmi_cmd_t>(
553 IPMINetfnIntelOEMGeneralCmd::cmdSetShutdownPolicy),
554 NULL, ipmiOEMSetShutdownPolicy, PRIVILEGE_ADMIN);
555 ipmiPrintAndRegister(netfnIntcOEMGeneral,
556 static_cast<ipmi_cmd_t>(
557 IPMINetfnIntelOEMGeneralCmd::cmdGetShutdownPolicy),
558 NULL, ipmiOEMGetShutdownPolicy, PRIVILEGE_ADMIN);
Jia, Chunhuia835eaa2018-09-05 09:00:41 +0800559 return;
560}
561
562} // namespace ipmi