blob: 835302a65522f3e61ffed7e9a08c669ad0b4e53a [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";
Yong Liba3e4f52019-10-31 18:19:58 +080037static constexpr uint8_t maxDataLen = 254;
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
James Feista73cb812019-08-14 10:17:02 -0700129ipmi_ret_t cmd_region_complete(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
130 ipmi_request_t request, ipmi_response_t response,
131 ipmi_data_len_t data_len, ipmi_context_t context)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700132{
James Feista73cb812019-08-14 10:17:02 -0700133 auto requestData = reinterpret_cast<const RegionCompleteRequest*>(request);
134 uint8_t status;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700135
James Feista73cb812019-08-14 10:17:02 -0700136 sdbusplus::message::variant<uint8_t, uint16_t> value;
137
138 if (*data_len != sizeof(RegionCompleteRequest))
139 {
140 *data_len = 0;
141 return IPMI_CC_REQ_DATA_LEN_INVALID;
142 }
143
144 uint8_t regionId = requestData->regionId - 1;
145 *data_len = 0;
146
147 if (regionId >= maxMDRId)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700148 {
149 phosphor::logging::log<level::ERR>("Invalid region");
James Feista73cb812019-08-14 10:17:02 -0700150 return IPMI_CC_PARM_OUT_OF_RANGE;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700151 }
152
Vernon Mauery15419dd2019-05-24 09:40:30 -0700153 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
154 std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700155
James Feista73cb812019-08-14 10:17:02 -0700156 if (set_regionId(regionId, service) < 0)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700157 {
158 phosphor::logging::log<level::ERR>("Error setting regionId");
James Feista73cb812019-08-14 10:17:02 -0700159 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700160 }
161
162 if (0 > sdplus_mdrv1_get_property("LockPolicy", value, service))
163 {
164 phosphor::logging::log<level::ERR>("Error getting lockPolicy");
James Feista73cb812019-08-14 10:17:02 -0700165 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700166 }
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700167 if (regionLockUnlocked == std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700168 {
James Feista73cb812019-08-14 10:17:02 -0700169 return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700170 }
171
172 if (0 > sdplus_mdrv1_get_property("SessionId", value, service))
173 {
174 phosphor::logging::log<level::ERR>("Error getting sessionId");
James Feista73cb812019-08-14 10:17:02 -0700175 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700176 }
James Feista73cb812019-08-14 10:17:02 -0700177 if (requestData->sessionId != std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700178 {
James Feista73cb812019-08-14 10:17:02 -0700179 return IPMI_CC_OEM_SET_IN_PROCESS;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700180 }
181
Vernon Mauery15419dd2019-05-24 09:40:30 -0700182 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
183 MDRV1_INTERFACE, "RegionComplete");
Vernon Mauerya3702c12019-05-22 13:20:59 -0700184
James Feista73cb812019-08-14 10:17:02 -0700185 method.append(regionId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700186
Vernon Mauery15419dd2019-05-24 09:40:30 -0700187 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700188 if (reply.is_method_error())
189 {
190 phosphor::logging::log<level::ERR>(
191 "Error set region complete",
192 phosphor::logging::entry("SERVICE=%s", service.c_str()),
193 phosphor::logging::entry("PATH=%s", MDRV1_PATH));
James Feista73cb812019-08-14 10:17:02 -0700194 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700195 }
196 reply.read(status);
197
198 if (status != 0)
199 phosphor::logging::log<level::ERR>(
200 "Error set region complete, unexpected error");
James Feista73cb812019-08-14 10:17:02 -0700201 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700202
James Feista73cb812019-08-14 10:17:02 -0700203 return IPMI_CC_OK;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700204}
205
206ipmi_ret_t cmd_region_read(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
207 ipmi_request_t request, ipmi_response_t response,
208 ipmi_data_len_t data_len, ipmi_context_t context)
209{
210 auto requestData = reinterpret_cast<const RegionReadRequest*>(request);
211 auto responseData = reinterpret_cast<RegionReadResponse*>(response);
212 sdbusplus::message::variant<uint8_t, uint16_t> regUsedVal;
213 sdbusplus::message::variant<uint8_t, uint16_t> lockPolicyVal;
214 std::vector<uint8_t> res;
215
216 if (*data_len < sizeof(RegionReadRequest))
217 {
218 *data_len = 0;
219 return IPMI_CC_REQ_DATA_LEN_INVALID;
220 }
221
222 uint8_t regionId = requestData->regionId - 1;
223
224 *data_len = 0;
225
226 if (regionId >= maxMDRId)
227 {
228 phosphor::logging::log<level::ERR>("Invalid region");
229 return IPMI_CC_PARM_OUT_OF_RANGE;
230 }
231
Vernon Mauery15419dd2019-05-24 09:40:30 -0700232 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
233 std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700234 // TODO to make sure the interface can get correct LockPolicy even
235 // regionId changed by another task.
236 if (set_regionId(regionId, service) < 0)
237 {
238 phosphor::logging::log<level::ERR>("Error setting regionId");
239 return IPMI_CC_UNSPECIFIED_ERROR;
240 }
241 if (0 > sdplus_mdrv1_get_property("RegionUsed", regUsedVal, service))
242 {
243 phosphor::logging::log<level::ERR>("Error getting regionUsed");
244 return IPMI_CC_UNSPECIFIED_ERROR;
245 }
Yong Liba3e4f52019-10-31 18:19:58 +0800246 if ((requestData->length >= maxDataLen) ||
247 (requestData->offset + requestData->length >
248 std::get<uint16_t>(regUsedVal)))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700249 {
Yong Liba3e4f52019-10-31 18:19:58 +0800250 phosphor::logging::log<level::INFO>(
251 "Invalid data request",
252 phosphor::logging::entry("OFFSET=%d", requestData->offset),
253 phosphor::logging::entry("LENGTH=%d", requestData->length),
254 phosphor::logging::entry("REGUSED=%d",
255 std::get<uint16_t>(regUsedVal)));
256 return IPMI_CC_INVALID_FIELD_REQUEST;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700257 }
258
259 if (0 > sdplus_mdrv1_get_property("LockPolicy", lockPolicyVal, service))
260 {
261 phosphor::logging::log<level::ERR>("Error getting lockPolicy");
262 return IPMI_CC_UNSPECIFIED_ERROR;
263 }
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700264 if (regionLockUnlocked != std::get<uint8_t>(lockPolicyVal))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700265 {
266 return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
267 }
268
Vernon Mauery15419dd2019-05-24 09:40:30 -0700269 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
270 MDRV1_INTERFACE, "RegionRead");
Vernon Mauerya3702c12019-05-22 13:20:59 -0700271
272 method.append(regionId, requestData->length, requestData->offset);
273
Vernon Mauery15419dd2019-05-24 09:40:30 -0700274 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700275 if (reply.is_method_error())
276 {
277 phosphor::logging::log<level::ERR>(
278 "Error read region data",
279 phosphor::logging::entry("SERVICE=%s", service.c_str()),
280 phosphor::logging::entry("PATH=%s", MDRV1_PATH));
281 return IPMI_CC_UNSPECIFIED_ERROR;
282 }
283 reply.read(res);
284
285 *data_len = responseData->length = res[0];
286 responseData->updateCount = res[1];
287
Yong Liba3e4f52019-10-31 18:19:58 +0800288 if ((*data_len == 0) || (*data_len >= maxDataLen))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700289 {
290 phosphor::logging::log<level::ERR>(
291 "Data length send from service is invalid");
292 *data_len = 0;
293 return IPMI_CC_RESPONSE_ERROR;
294 }
295
296 *data_len += 2 * sizeof(uint8_t);
297 std::copy(&res[2], &res[*data_len], responseData->data);
298 return IPMI_CC_OK;
299}
300
James Feista73cb812019-08-14 10:17:02 -0700301ipmi_ret_t cmd_region_write(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
302 ipmi_request_t request, ipmi_response_t response,
303 ipmi_data_len_t data_len, ipmi_context_t context)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700304{
James Feista73cb812019-08-14 10:17:02 -0700305 auto requestData = reinterpret_cast<const RegionWriteRequest*>(request);
306 uint8_t regionId = requestData->regionId - 1;
307 std::string res;
308 std::vector<uint8_t> writeData;
309 uint16_t index;
310 uint8_t tmp[255];
Vernon Mauerya3702c12019-05-22 13:20:59 -0700311
James Feista73cb812019-08-14 10:17:02 -0700312 size_t minInputLen = &requestData->data[0] - &requestData->sessionId + 1;
313 if (*data_len < minInputLen)
314 { // this command need at least 6 bytes input
315 *data_len = 0;
316 return IPMI_CC_REQ_DATA_LEN_INVALID;
317 }
318
319 sdbusplus::message::variant<uint8_t, uint16_t> value;
320
321 *data_len = 0;
322
323 if (regionId >= maxMDRId)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700324 {
325 phosphor::logging::log<level::ERR>("Invalid region");
James Feista73cb812019-08-14 10:17:02 -0700326 return IPMI_CC_PARM_OUT_OF_RANGE;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700327 }
328
Vernon Mauery15419dd2019-05-24 09:40:30 -0700329 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
330 std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700331
James Feista73cb812019-08-14 10:17:02 -0700332 if (set_regionId(regionId, service) < 0)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700333 {
334 phosphor::logging::log<level::ERR>("Error setting regionId");
James Feista73cb812019-08-14 10:17:02 -0700335 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700336 }
337
338 if (0 > sdplus_mdrv1_get_property("LockPolicy", value, service))
339 {
340 phosphor::logging::log<level::ERR>("Error getting lockPolicy");
James Feista73cb812019-08-14 10:17:02 -0700341 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700342 }
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700343 if (regionLockUnlocked == std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700344 {
James Feista73cb812019-08-14 10:17:02 -0700345 return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700346 }
347
348 if (0 > sdplus_mdrv1_get_property("SessionId", value, service))
349 {
350 phosphor::logging::log<level::ERR>("Error getting sessionId");
James Feista73cb812019-08-14 10:17:02 -0700351 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700352 }
James Feista73cb812019-08-14 10:17:02 -0700353 if (requestData->sessionId != std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700354 {
James Feista73cb812019-08-14 10:17:02 -0700355 return IPMI_CC_OEM_SET_IN_PROCESS;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700356 }
357
James Feista73cb812019-08-14 10:17:02 -0700358 std::copy(&(requestData->length), &(requestData->data[requestData->length]),
359 tmp);
360 writeData.push_back(regionId);
361 for (index = 0; index < minInputLen + requestData->length - 2; index++)
362 {
363 writeData.push_back(tmp[index]);
364 }
365
Vernon Mauery15419dd2019-05-24 09:40:30 -0700366 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
367 MDRV1_INTERFACE, "RegionWrite");
Vernon Mauerya3702c12019-05-22 13:20:59 -0700368
369 method.append(writeData);
370
Vernon Mauery15419dd2019-05-24 09:40:30 -0700371 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700372 if (reply.is_method_error())
373 {
374 phosphor::logging::log<level::ERR>(
375 "Error write region data",
376 phosphor::logging::entry("SERVICE=%s", service.c_str()),
377 phosphor::logging::entry("PATH=%s", MDRV1_PATH));
James Feista73cb812019-08-14 10:17:02 -0700378 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700379 }
380 reply.read(res);
381
382 if (res == "NoData")
383 {
James Feista73cb812019-08-14 10:17:02 -0700384 return IPMI_CC_PARM_OUT_OF_RANGE;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700385 }
386 else if (res != "Success")
387 {
388 phosphor::logging::log<level::ERR>(
389 "Error write region data, unexpected error");
James Feista73cb812019-08-14 10:17:02 -0700390 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700391 }
392
James Feista73cb812019-08-14 10:17:02 -0700393 return IPMI_CC_OK;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700394}
395
James Feista73cb812019-08-14 10:17:02 -0700396ipmi_ret_t cmd_region_lock(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
397 ipmi_request_t request, ipmi_response_t response,
398 ipmi_data_len_t data_len, ipmi_context_t context)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700399{
James Feista73cb812019-08-14 10:17:02 -0700400 auto requestData = reinterpret_cast<const RegionLockRequest*>(request);
401 uint8_t regionId = requestData->regionId - 1;
402 sdbusplus::message::variant<uint8_t, uint16_t> value;
403 auto res = reinterpret_cast<uint8_t*>(response);
404 uint8_t lockResponse;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700405
James Feista73cb812019-08-14 10:17:02 -0700406 if (*data_len != sizeof(RegionLockRequest))
407 {
408 *data_len = 0;
409 return IPMI_CC_REQ_DATA_LEN_INVALID;
410 }
411
412 *data_len = 0;
413
414 if (regionId >= maxMDRId)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700415 {
416 phosphor::logging::log<level::ERR>("Invalid region");
James Feista73cb812019-08-14 10:17:02 -0700417 return IPMI_CC_PARM_OUT_OF_RANGE;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700418 }
419
Vernon Mauery15419dd2019-05-24 09:40:30 -0700420 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
421 std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700422
James Feista73cb812019-08-14 10:17:02 -0700423 if (set_regionId(regionId, service) < 0)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700424 {
425 phosphor::logging::log<level::ERR>("Error setting regionId");
James Feista73cb812019-08-14 10:17:02 -0700426 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700427 }
428
429 if (0 > sdplus_mdrv1_get_property("LockPolicy", value, service))
430 {
431 phosphor::logging::log<level::ERR>("Error getting lockPolicy");
James Feista73cb812019-08-14 10:17:02 -0700432 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700433 }
James Feista73cb812019-08-14 10:17:02 -0700434 if (requestData->lockPolicy == regionLockUnlocked)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700435 {
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700436 if (regionLockUnlocked == std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700437 {
James Feista73cb812019-08-14 10:17:02 -0700438 return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700439 }
440 }
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700441 if (regionLockUnlocked != std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700442 {
443 if (0 > sdplus_mdrv1_get_property("SessionId", value, service))
444 {
445 phosphor::logging::log<level::ERR>("Error getting sessionId");
James Feista73cb812019-08-14 10:17:02 -0700446 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700447 }
James Feista73cb812019-08-14 10:17:02 -0700448 if (requestData->sessionId != std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700449 {
James Feista73cb812019-08-14 10:17:02 -0700450 if (requestData->lockPolicy != regionLockStrict)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700451 {
James Feista73cb812019-08-14 10:17:02 -0700452 return IPMI_CC_OEM_SET_IN_PROCESS;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700453 }
454 }
455 }
Vernon Mauery15419dd2019-05-24 09:40:30 -0700456 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
457 MDRV1_INTERFACE, "RegionLock");
Vernon Mauerya3702c12019-05-22 13:20:59 -0700458
James Feista73cb812019-08-14 10:17:02 -0700459 method.append(requestData->sessionId, regionId, requestData->lockPolicy,
460 requestData->msTimeout);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700461
Vernon Mauery15419dd2019-05-24 09:40:30 -0700462 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700463 if (reply.is_method_error())
464 {
465 phosphor::logging::log<level::ERR>(
466 "Error lock region ",
467 phosphor::logging::entry("SERVICE=%s", service.c_str()),
468 phosphor::logging::entry("PATH=%s", MDRV1_PATH));
James Feista73cb812019-08-14 10:17:02 -0700469 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700470 }
471 reply.read(lockResponse);
472
James Feista73cb812019-08-14 10:17:02 -0700473 *data_len = sizeof(lockResponse);
474 *res = lockResponse;
475 return IPMI_CC_OK;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700476}
477
478static void register_netfn_smbios_functions(void)
479{
480 // MDR V1 Command
481 // <Get MDR Status Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -0700482 ipmi_register_callback(ipmi::intel::netFnApp,
483 ipmi::intel::app::cmdMdrStatus, NULL,
Vernon Mauerya3702c12019-05-22 13:20:59 -0700484 cmd_region_status, PRIVILEGE_OPERATOR);
485
486 // <Update Complete Status Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -0700487 ipmi_register_callback(ipmi::intel::netFnApp,
488 ipmi::intel::app::cmdMdrComplete, NULL,
James Feista73cb812019-08-14 10:17:02 -0700489 cmd_region_complete, PRIVILEGE_OPERATOR);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700490
491 // <Read MDR Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -0700492 ipmi_register_callback(ipmi::intel::netFnApp, ipmi::intel::app::cmdMdrRead,
493 NULL, cmd_region_read, PRIVILEGE_OPERATOR);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700494
495 // <Write MDR Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -0700496 ipmi_register_callback(ipmi::intel::netFnApp, ipmi::intel::app::cmdMdrWrite,
497 NULL, cmd_region_write, PRIVILEGE_OPERATOR);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700498
499 // <Lock MDR Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -0700500 ipmi_register_callback(ipmi::intel::netFnApp, ipmi::intel::app::cmdMdrLock,
501 NULL, cmd_region_lock, PRIVILEGE_OPERATOR);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700502}