blob: 0c288b1b92803dc74fe06fff144fdde64adbf184 [file] [log] [blame]
Vernon Mauerya3702c12019-05-22 13:20:59 -07001/*
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
Vernon Mauerya3702c12019-05-22 13:20:59 -070017#include <commandutils.hpp>
18#include <cstdint>
19#include <iostream>
Vernon Mauery15419dd2019-05-24 09:40:30 -070020#include <ipmid/api.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070021#include <ipmid/utils.hpp>
22#include <phosphor-logging/elog-errors.hpp>
23#include <phosphor-logging/log.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070024#include <smbioshandler.hpp>
25#include <string>
26#include <vector>
27#include <xyz/openbmc_project/Common/error.hpp>
28
29using InternalFailure =
30 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
31
32using level = phosphor::logging::level;
33
34constexpr const char* DBUS_PROPERTIES = "org.freedesktop.DBus.Properties";
35constexpr const char* MDRV1_PATH = "/xyz/openbmc_project/Smbios/MDR_V1";
36constexpr const char* MDRV1_INTERFACE = "xyz.openbmc_project.Smbios.MDR_V1";
jayaprakash Mutyala946723b2019-06-07 16:27:23 +000037static constexpr const uint8_t ccOemSetInProcess = 0x81;
Vernon Mauerya3702c12019-05-22 13:20:59 -070038
39static void register_netfn_smbios_functions() __attribute__((constructor));
Vernon Mauerya3702c12019-05-22 13:20:59 -070040
41ipmi_ret_t cmd_region_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
42 ipmi_request_t request, ipmi_response_t response,
43 ipmi_data_len_t data_len, ipmi_context_t context)
44{
45 auto requestData = reinterpret_cast<const RegionStatusRequest*>(request);
46 std::vector<uint8_t> status;
47
48 if (*data_len != sizeof(RegionStatusRequest))
49 {
50 *data_len = 0;
51 return IPMI_CC_REQ_DATA_LEN_INVALID;
52 }
53
54 uint8_t regionId = requestData->regionId - 1;
55 *data_len = 0;
56
57 if (regionId >= maxMDRId)
58 {
59 phosphor::logging::log<level::ERR>("Invalid region");
60 return IPMI_CC_PARM_OUT_OF_RANGE;
61 }
62
Vernon Mauery15419dd2019-05-24 09:40:30 -070063 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
64 std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -070065
Vernon Mauery15419dd2019-05-24 09:40:30 -070066 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
67 MDRV1_INTERFACE, "RegionStatus");
Vernon Mauerya3702c12019-05-22 13:20:59 -070068 method.append(regionId);
Vernon Mauery15419dd2019-05-24 09:40:30 -070069 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -070070 if (reply.is_method_error())
71 {
72 phosphor::logging::log<level::ERR>(
73 "Error get region status",
74 phosphor::logging::entry("SERVICE=%s", service.c_str()),
75 phosphor::logging::entry("PATH=%s", MDRV1_PATH));
76 return IPMI_CC_UNSPECIFIED_ERROR;
77 }
78 reply.read(status);
79
80 if (status.size() != sizeof(MDRState))
81 {
82 phosphor::logging::log<level::ERR>(
83 "Error get region status, return length invalid");
84 return IPMI_CC_UNSPECIFIED_ERROR;
85 }
86 *data_len = static_cast<size_t>(status.size());
87 auto dataOut = reinterpret_cast<uint8_t*>(response);
88 std::copy(&status[0], &status[*data_len], dataOut);
89 return IPMI_CC_OK;
90}
91
92int sdplus_mdrv1_get_property(
93 const std::string& name,
94 sdbusplus::message::variant<uint8_t, uint16_t>& value, std::string& service)
95{
Vernon Mauery15419dd2019-05-24 09:40:30 -070096 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
97 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
98 DBUS_PROPERTIES, "Get");
Vernon Mauerya3702c12019-05-22 13:20:59 -070099 method.append(MDRV1_INTERFACE, name);
Vernon Mauery15419dd2019-05-24 09:40:30 -0700100 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700101 if (reply.is_method_error())
102 {
103 phosphor::logging::log<level::ERR>(
104 "Error getting property, sdbusplus call failed");
105 return -1;
106 }
107 reply.read(value);
108
109 return 0;
110}
111
112static int set_regionId(uint8_t regionId, std::string& service)
113{
Vernon Mauery15419dd2019-05-24 09:40:30 -0700114 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
115 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
116 DBUS_PROPERTIES, "Set");
Vernon Mauerya3702c12019-05-22 13:20:59 -0700117 sdbusplus::message::variant<uint8_t> value{regionId};
118 method.append(MDRV1_INTERFACE, "RegionId", value);
Vernon Mauery15419dd2019-05-24 09:40:30 -0700119 auto region = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700120 if (region.is_method_error())
121 {
122 phosphor::logging::log<level::ERR>(
123 "Error setting regionID, sdbusplus call failed");
124 return -1;
125 }
126 return 0;
127}
128
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000129/** @brief implements bmc region update Complete command
130 * @param sessionId - session Lock Handle
131 * @param regionId - data Region
132 *
133 * @returns IPMI completion code
134 */
135ipmi::RspType<> bmcRegionUpdateComplete(uint8_t sessionId, uint8_t regionId)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700136{
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000137 std::variant<uint8_t, uint16_t> value;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700138
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000139 if ((regionId >= maxMDRId) || (regionId == 0))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700140 {
141 phosphor::logging::log<level::ERR>("Invalid region");
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000142 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700143 }
144
Vernon Mauery15419dd2019-05-24 09:40:30 -0700145 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
146 std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700147
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000148 uint8_t regionIdLocal = regionId - 1;
149
150 if (regionIdLocal == 0)
151 {
152 phosphor::logging::log<level::ERR>("Invalid region");
153 return ipmi::responseParmOutOfRange();
154 }
155 if (set_regionId(regionIdLocal, service) < 0)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700156 {
157 phosphor::logging::log<level::ERR>("Error setting regionId");
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000158 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700159 }
160
161 if (0 > sdplus_mdrv1_get_property("LockPolicy", value, service))
162 {
163 phosphor::logging::log<level::ERR>("Error getting lockPolicy");
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000164 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700165 }
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700166 if (regionLockUnlocked == std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700167 {
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000168 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700169 }
170
171 if (0 > sdplus_mdrv1_get_property("SessionId", value, service))
172 {
173 phosphor::logging::log<level::ERR>("Error getting sessionId");
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000174 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700175 }
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000176 if (sessionId != std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700177 {
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000178 return ipmi::response(ccOemSetInProcess);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700179 }
180
Vernon Mauery15419dd2019-05-24 09:40:30 -0700181 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
182 MDRV1_INTERFACE, "RegionComplete");
Vernon Mauerya3702c12019-05-22 13:20:59 -0700183
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000184 method.append(regionIdLocal);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700185
Vernon Mauery15419dd2019-05-24 09:40:30 -0700186 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700187 if (reply.is_method_error())
188 {
189 phosphor::logging::log<level::ERR>(
190 "Error set region complete",
191 phosphor::logging::entry("SERVICE=%s", service.c_str()),
192 phosphor::logging::entry("PATH=%s", MDRV1_PATH));
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000193 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700194 }
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000195 uint8_t status = 0;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700196 reply.read(status);
197
198 if (status != 0)
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000199 {
Vernon Mauerya3702c12019-05-22 13:20:59 -0700200 phosphor::logging::log<level::ERR>(
201 "Error set region complete, unexpected error");
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000202 return ipmi::responseUnspecifiedError();
203 }
Vernon Mauerya3702c12019-05-22 13:20:59 -0700204
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000205 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700206}
207
208ipmi_ret_t cmd_region_read(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
209 ipmi_request_t request, ipmi_response_t response,
210 ipmi_data_len_t data_len, ipmi_context_t context)
211{
212 auto requestData = reinterpret_cast<const RegionReadRequest*>(request);
213 auto responseData = reinterpret_cast<RegionReadResponse*>(response);
214 sdbusplus::message::variant<uint8_t, uint16_t> regUsedVal;
215 sdbusplus::message::variant<uint8_t, uint16_t> lockPolicyVal;
216 std::vector<uint8_t> res;
217
218 if (*data_len < sizeof(RegionReadRequest))
219 {
220 *data_len = 0;
221 return IPMI_CC_REQ_DATA_LEN_INVALID;
222 }
223
224 uint8_t regionId = requestData->regionId - 1;
225
226 *data_len = 0;
227
228 if (regionId >= maxMDRId)
229 {
230 phosphor::logging::log<level::ERR>("Invalid region");
231 return IPMI_CC_PARM_OUT_OF_RANGE;
232 }
233
Vernon Mauery15419dd2019-05-24 09:40:30 -0700234 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
235 std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700236 // TODO to make sure the interface can get correct LockPolicy even
237 // regionId changed by another task.
238 if (set_regionId(regionId, service) < 0)
239 {
240 phosphor::logging::log<level::ERR>("Error setting regionId");
241 return IPMI_CC_UNSPECIFIED_ERROR;
242 }
243 if (0 > sdplus_mdrv1_get_property("RegionUsed", regUsedVal, service))
244 {
245 phosphor::logging::log<level::ERR>("Error getting regionUsed");
246 return IPMI_CC_UNSPECIFIED_ERROR;
247 }
248 if (requestData->offset + requestData->length >
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700249 std::get<uint16_t>(regUsedVal))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700250 {
251 return IPMI_CC_REQ_DATA_LEN_INVALID;
252 }
253
254 if (0 > sdplus_mdrv1_get_property("LockPolicy", lockPolicyVal, service))
255 {
256 phosphor::logging::log<level::ERR>("Error getting lockPolicy");
257 return IPMI_CC_UNSPECIFIED_ERROR;
258 }
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700259 if (regionLockUnlocked != std::get<uint8_t>(lockPolicyVal))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700260 {
261 return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
262 }
263
Vernon Mauery15419dd2019-05-24 09:40:30 -0700264 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
265 MDRV1_INTERFACE, "RegionRead");
Vernon Mauerya3702c12019-05-22 13:20:59 -0700266
267 method.append(regionId, requestData->length, requestData->offset);
268
Vernon Mauery15419dd2019-05-24 09:40:30 -0700269 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700270 if (reply.is_method_error())
271 {
272 phosphor::logging::log<level::ERR>(
273 "Error read region data",
274 phosphor::logging::entry("SERVICE=%s", service.c_str()),
275 phosphor::logging::entry("PATH=%s", MDRV1_PATH));
276 return IPMI_CC_UNSPECIFIED_ERROR;
277 }
278 reply.read(res);
279
280 *data_len = responseData->length = res[0];
281 responseData->updateCount = res[1];
282
283 if ((*data_len == 0) || (*data_len >= 254))
284 {
285 phosphor::logging::log<level::ERR>(
286 "Data length send from service is invalid");
287 *data_len = 0;
288 return IPMI_CC_RESPONSE_ERROR;
289 }
290
291 *data_len += 2 * sizeof(uint8_t);
292 std::copy(&res[2], &res[*data_len], responseData->data);
293 return IPMI_CC_OK;
294}
295
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000296/** @brief implements bmc region write command
297 * @parameter
298 * - sessionId - session Lock Handle
299 * - regionId - data Region
300 * - length - data Length
301 * - offset - data Offset
302 * - data - data to be written
303 *
304 * @returns IPMI completion code plus response data
305 * - writeData - contains data Region, valid Data,
306 * lock Status, max Region Length, region Used (in bytes)
307 */
308ipmi::RspType<std::vector<uint8_t>>
309 bmcRegionWrite(uint8_t sessionId, uint8_t regionId, uint8_t length,
310 uint16_t offset, std::vector<uint8_t> data)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700311{
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000312 std::variant<uint8_t, uint16_t> value;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700313
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000314 if ((regionId >= maxMDRId) || (regionId == 0))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700315 {
316 phosphor::logging::log<level::ERR>("Invalid region");
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000317 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700318 }
319
Vernon Mauery15419dd2019-05-24 09:40:30 -0700320 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
321 std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700322
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000323 uint8_t regionIdLocal = regionId - 1;
324
325 if (set_regionId(regionIdLocal, service) < 0)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700326 {
327 phosphor::logging::log<level::ERR>("Error setting regionId");
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000328 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700329 }
330
331 if (0 > sdplus_mdrv1_get_property("LockPolicy", value, service))
332 {
333 phosphor::logging::log<level::ERR>("Error getting lockPolicy");
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000334 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700335 }
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700336 if (regionLockUnlocked == std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700337 {
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000338 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700339 }
340
341 if (0 > sdplus_mdrv1_get_property("SessionId", value, service))
342 {
343 phosphor::logging::log<level::ERR>("Error getting sessionId");
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000344 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700345 }
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000346 if (sessionId != std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700347 {
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000348 return ipmi::response(ccOemSetInProcess);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700349 }
350
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000351 std::vector<uint8_t> writeData;
352 std::copy(data.begin(), data.begin() + length,
353 writeData.data() + sizeof(regionIdLocal) + sizeof(length));
Vernon Mauery15419dd2019-05-24 09:40:30 -0700354 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
355 MDRV1_INTERFACE, "RegionWrite");
Vernon Mauerya3702c12019-05-22 13:20:59 -0700356
357 method.append(writeData);
358
Vernon Mauery15419dd2019-05-24 09:40:30 -0700359 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700360 if (reply.is_method_error())
361 {
362 phosphor::logging::log<level::ERR>(
363 "Error write region data",
364 phosphor::logging::entry("SERVICE=%s", service.c_str()),
365 phosphor::logging::entry("PATH=%s", MDRV1_PATH));
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000366 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700367 }
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000368 std::string res;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700369 reply.read(res);
370
371 if (res == "NoData")
372 {
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000373 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700374 }
375 else if (res != "Success")
376 {
377 phosphor::logging::log<level::ERR>(
378 "Error write region data, unexpected error");
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000379 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700380 }
381
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000382 return ipmi::responseSuccess(writeData);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700383}
384
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000385/** @brief implements bmc region lock command
386 * @parameter
387 * - sessionId - session Lock Handle
388 * - regionId - data Region
389 * - lockPolicy - Lock Type
390 * - msTimeout - timeout. Number of milliseconds allowed before lock is
391 * released
392 *
393 * @returns IPMI completion code plus response data
394 * - lockResponse - session Lock Handle
395 */
396ipmi::RspType<uint8_t> // lockResponse
397 bmcRegionLock(uint8_t sessionId, uint8_t regionId, uint8_t lockPolicy,
398 uint16_t msTimeout)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700399{
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000400 std::variant<uint8_t, uint16_t> value;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700401
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000402 if ((regionId >= maxMDRId) || (regionId == 0))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700403 {
404 phosphor::logging::log<level::ERR>("Invalid region");
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000405 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700406 }
407
Vernon Mauery15419dd2019-05-24 09:40:30 -0700408 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
409 std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700410
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000411 uint8_t regionIdLocal = regionId - 1;
412 if (set_regionId(regionIdLocal, service) < 0)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700413 {
414 phosphor::logging::log<level::ERR>("Error setting regionId");
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000415 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700416 }
417
418 if (0 > sdplus_mdrv1_get_property("LockPolicy", value, service))
419 {
420 phosphor::logging::log<level::ERR>("Error getting lockPolicy");
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000421 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700422 }
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000423 if (lockPolicy == regionLockUnlocked)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700424 {
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700425 if (regionLockUnlocked == std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700426 {
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000427 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700428 }
429 }
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700430 if (regionLockUnlocked != std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700431 {
432 if (0 > sdplus_mdrv1_get_property("SessionId", value, service))
433 {
434 phosphor::logging::log<level::ERR>("Error getting sessionId");
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000435 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700436 }
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000437 if (sessionId != std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700438 {
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000439 if (lockPolicy != regionLockStrict)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700440 {
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000441 return ipmi::response(ccOemSetInProcess);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700442 }
443 }
444 }
Vernon Mauery15419dd2019-05-24 09:40:30 -0700445 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
446 MDRV1_INTERFACE, "RegionLock");
Vernon Mauerya3702c12019-05-22 13:20:59 -0700447
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000448 method.append(sessionId, regionIdLocal, lockPolicy, msTimeout);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700449
Vernon Mauery15419dd2019-05-24 09:40:30 -0700450 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700451 if (reply.is_method_error())
452 {
453 phosphor::logging::log<level::ERR>(
454 "Error lock region ",
455 phosphor::logging::entry("SERVICE=%s", service.c_str()),
456 phosphor::logging::entry("PATH=%s", MDRV1_PATH));
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000457 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700458 }
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000459 uint8_t lockResponse = 0;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700460 reply.read(lockResponse);
461
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000462 return ipmi::responseSuccess(lockResponse);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700463}
464
465static void register_netfn_smbios_functions(void)
466{
467 // MDR V1 Command
468 // <Get MDR Status Command>
469 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
470 IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_STATUS, NULL,
471 cmd_region_status, PRIVILEGE_OPERATOR);
472
473 // <Update Complete Status Command>
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000474 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
475 IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_COMPLETE,
476 ipmi::Privilege::Operator, bmcRegionUpdateComplete);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700477
478 // <Read MDR Command>
479 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
480 IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_READ, NULL,
481 cmd_region_read, PRIVILEGE_OPERATOR);
482
483 // <Write MDR Command>
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000484 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
485 IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_WRITE,
486 ipmi::Privilege::Operator, bmcRegionWrite);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700487
488 // <Lock MDR Command>
jayaprakash Mutyala946723b2019-06-07 16:27:23 +0000489 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
490 IPMI_NETFN_INTEL_OEM_APP_CMD::MDR_LOCK,
491 ipmi::Privilege::Operator, bmcRegionLock);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700492}