blob: e330e5aafd0ca832b71ce05dc37669230d65ace7 [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>
Vernon Mauery15419dd2019-05-24 09:40:30 -070018#include <ipmid/api.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070019#include <ipmid/utils.hpp>
20#include <phosphor-logging/elog-errors.hpp>
21#include <phosphor-logging/log.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070022#include <smbioshandler.hpp>
James Feistfcd2d3a2020-05-28 10:38:15 -070023#include <xyz/openbmc_project/Common/error.hpp>
24
25#include <cstdint>
26#include <iostream>
Vernon Mauerya3702c12019-05-22 13:20:59 -070027#include <string>
28#include <vector>
Vernon Mauerya3702c12019-05-22 13:20:59 -070029
30using InternalFailure =
31 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
32
33using level = phosphor::logging::level;
34
35constexpr const char* DBUS_PROPERTIES = "org.freedesktop.DBus.Properties";
36constexpr const char* MDRV1_PATH = "/xyz/openbmc_project/Smbios/MDR_V1";
37constexpr const char* MDRV1_INTERFACE = "xyz.openbmc_project.Smbios.MDR_V1";
Yong Liba3e4f52019-10-31 18:19:58 +080038static constexpr uint8_t maxDataLen = 254;
Vernon Mauerya3702c12019-05-22 13:20:59 -070039
40static void register_netfn_smbios_functions() __attribute__((constructor));
Vernon Mauerya3702c12019-05-22 13:20:59 -070041
42ipmi_ret_t cmd_region_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
43 ipmi_request_t request, ipmi_response_t response,
44 ipmi_data_len_t data_len, ipmi_context_t context)
45{
46 auto requestData = reinterpret_cast<const RegionStatusRequest*>(request);
47 std::vector<uint8_t> status;
48
49 if (*data_len != sizeof(RegionStatusRequest))
50 {
51 *data_len = 0;
52 return IPMI_CC_REQ_DATA_LEN_INVALID;
53 }
54
55 uint8_t regionId = requestData->regionId - 1;
56 *data_len = 0;
57
58 if (regionId >= maxMDRId)
59 {
60 phosphor::logging::log<level::ERR>("Invalid region");
61 return IPMI_CC_PARM_OUT_OF_RANGE;
62 }
63
Vernon Mauery15419dd2019-05-24 09:40:30 -070064 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
65 std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -070066
Vernon Mauery15419dd2019-05-24 09:40:30 -070067 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
68 MDRV1_INTERFACE, "RegionStatus");
Vernon Mauerya3702c12019-05-22 13:20:59 -070069 method.append(regionId);
Vernon Mauery15419dd2019-05-24 09:40:30 -070070 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -070071 if (reply.is_method_error())
72 {
73 phosphor::logging::log<level::ERR>(
74 "Error get region status",
75 phosphor::logging::entry("SERVICE=%s", service.c_str()),
76 phosphor::logging::entry("PATH=%s", MDRV1_PATH));
77 return IPMI_CC_UNSPECIFIED_ERROR;
78 }
79 reply.read(status);
80
81 if (status.size() != sizeof(MDRState))
82 {
83 phosphor::logging::log<level::ERR>(
84 "Error get region status, return length invalid");
85 return IPMI_CC_UNSPECIFIED_ERROR;
86 }
87 *data_len = static_cast<size_t>(status.size());
88 auto dataOut = reinterpret_cast<uint8_t*>(response);
89 std::copy(&status[0], &status[*data_len], dataOut);
90 return IPMI_CC_OK;
91}
92
Patrick Williams886a48a2020-05-13 17:44:37 -050093int sdplus_mdrv1_get_property(const std::string& name,
94 std::variant<uint8_t, uint16_t>& value,
95 std::string& service)
Vernon Mauerya3702c12019-05-22 13:20:59 -070096{
Vernon Mauery15419dd2019-05-24 09:40:30 -070097 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
98 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
99 DBUS_PROPERTIES, "Get");
Vernon Mauerya3702c12019-05-22 13:20:59 -0700100 method.append(MDRV1_INTERFACE, name);
Vernon Mauery15419dd2019-05-24 09:40:30 -0700101 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700102 if (reply.is_method_error())
103 {
104 phosphor::logging::log<level::ERR>(
105 "Error getting property, sdbusplus call failed");
106 return -1;
107 }
108 reply.read(value);
109
110 return 0;
111}
112
113static int set_regionId(uint8_t regionId, std::string& service)
114{
Vernon Mauery15419dd2019-05-24 09:40:30 -0700115 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
116 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
117 DBUS_PROPERTIES, "Set");
Patrick Williams886a48a2020-05-13 17:44:37 -0500118 std::variant<uint8_t> value{regionId};
Vernon Mauerya3702c12019-05-22 13:20:59 -0700119 method.append(MDRV1_INTERFACE, "RegionId", value);
Vernon Mauery15419dd2019-05-24 09:40:30 -0700120 auto region = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700121 if (region.is_method_error())
122 {
123 phosphor::logging::log<level::ERR>(
124 "Error setting regionID, sdbusplus call failed");
125 return -1;
126 }
127 return 0;
128}
129
James Feista73cb812019-08-14 10:17:02 -0700130ipmi_ret_t cmd_region_complete(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
131 ipmi_request_t request, ipmi_response_t response,
132 ipmi_data_len_t data_len, ipmi_context_t context)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700133{
James Feista73cb812019-08-14 10:17:02 -0700134 auto requestData = reinterpret_cast<const RegionCompleteRequest*>(request);
135 uint8_t status;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700136
Patrick Williams886a48a2020-05-13 17:44:37 -0500137 std::variant<uint8_t, uint16_t> value;
James Feista73cb812019-08-14 10:17:02 -0700138
139 if (*data_len != sizeof(RegionCompleteRequest))
140 {
141 *data_len = 0;
142 return IPMI_CC_REQ_DATA_LEN_INVALID;
143 }
144
145 uint8_t regionId = requestData->regionId - 1;
146 *data_len = 0;
147
148 if (regionId >= maxMDRId)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700149 {
150 phosphor::logging::log<level::ERR>("Invalid region");
James Feista73cb812019-08-14 10:17:02 -0700151 return IPMI_CC_PARM_OUT_OF_RANGE;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700152 }
153
Vernon Mauery15419dd2019-05-24 09:40:30 -0700154 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
155 std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700156
James Feista73cb812019-08-14 10:17:02 -0700157 if (set_regionId(regionId, service) < 0)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700158 {
159 phosphor::logging::log<level::ERR>("Error setting regionId");
James Feista73cb812019-08-14 10:17:02 -0700160 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700161 }
162
163 if (0 > sdplus_mdrv1_get_property("LockPolicy", value, service))
164 {
165 phosphor::logging::log<level::ERR>("Error getting lockPolicy");
James Feista73cb812019-08-14 10:17:02 -0700166 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700167 }
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700168 if (regionLockUnlocked == std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700169 {
James Feista73cb812019-08-14 10:17:02 -0700170 return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700171 }
172
173 if (0 > sdplus_mdrv1_get_property("SessionId", value, service))
174 {
175 phosphor::logging::log<level::ERR>("Error getting sessionId");
James Feista73cb812019-08-14 10:17:02 -0700176 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700177 }
James Feista73cb812019-08-14 10:17:02 -0700178 if (requestData->sessionId != std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700179 {
James Feista73cb812019-08-14 10:17:02 -0700180 return IPMI_CC_OEM_SET_IN_PROCESS;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700181 }
182
Vernon Mauery15419dd2019-05-24 09:40:30 -0700183 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
184 MDRV1_INTERFACE, "RegionComplete");
Vernon Mauerya3702c12019-05-22 13:20:59 -0700185
James Feista73cb812019-08-14 10:17:02 -0700186 method.append(regionId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700187
Vernon Mauery15419dd2019-05-24 09:40:30 -0700188 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700189 if (reply.is_method_error())
190 {
191 phosphor::logging::log<level::ERR>(
192 "Error set region complete",
193 phosphor::logging::entry("SERVICE=%s", service.c_str()),
194 phosphor::logging::entry("PATH=%s", MDRV1_PATH));
James Feista73cb812019-08-14 10:17:02 -0700195 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700196 }
197 reply.read(status);
198
199 if (status != 0)
200 phosphor::logging::log<level::ERR>(
201 "Error set region complete, unexpected error");
James Feista73cb812019-08-14 10:17:02 -0700202 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700203
James Feista73cb812019-08-14 10:17:02 -0700204 return IPMI_CC_OK;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700205}
206
207ipmi_ret_t cmd_region_read(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
208 ipmi_request_t request, ipmi_response_t response,
209 ipmi_data_len_t data_len, ipmi_context_t context)
210{
211 auto requestData = reinterpret_cast<const RegionReadRequest*>(request);
212 auto responseData = reinterpret_cast<RegionReadResponse*>(response);
Patrick Williams886a48a2020-05-13 17:44:37 -0500213 std::variant<uint8_t, uint16_t> regUsedVal;
214 std::variant<uint8_t, uint16_t> lockPolicyVal;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700215 std::vector<uint8_t> res;
216
217 if (*data_len < sizeof(RegionReadRequest))
218 {
219 *data_len = 0;
220 return IPMI_CC_REQ_DATA_LEN_INVALID;
221 }
222
223 uint8_t regionId = requestData->regionId - 1;
224
225 *data_len = 0;
226
227 if (regionId >= maxMDRId)
228 {
229 phosphor::logging::log<level::ERR>("Invalid region");
230 return IPMI_CC_PARM_OUT_OF_RANGE;
231 }
232
Vernon Mauery15419dd2019-05-24 09:40:30 -0700233 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
234 std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700235 // TODO to make sure the interface can get correct LockPolicy even
236 // regionId changed by another task.
237 if (set_regionId(regionId, service) < 0)
238 {
239 phosphor::logging::log<level::ERR>("Error setting regionId");
240 return IPMI_CC_UNSPECIFIED_ERROR;
241 }
242 if (0 > sdplus_mdrv1_get_property("RegionUsed", regUsedVal, service))
243 {
244 phosphor::logging::log<level::ERR>("Error getting regionUsed");
245 return IPMI_CC_UNSPECIFIED_ERROR;
246 }
Yong Liba3e4f52019-10-31 18:19:58 +0800247 if ((requestData->length >= maxDataLen) ||
248 (requestData->offset + requestData->length >
249 std::get<uint16_t>(regUsedVal)))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700250 {
Yong Liba3e4f52019-10-31 18:19:58 +0800251 phosphor::logging::log<level::INFO>(
252 "Invalid data request",
253 phosphor::logging::entry("OFFSET=%d", requestData->offset),
254 phosphor::logging::entry("LENGTH=%d", requestData->length),
255 phosphor::logging::entry("REGUSED=%d",
256 std::get<uint16_t>(regUsedVal)));
257 return IPMI_CC_INVALID_FIELD_REQUEST;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700258 }
259
260 if (0 > sdplus_mdrv1_get_property("LockPolicy", lockPolicyVal, service))
261 {
262 phosphor::logging::log<level::ERR>("Error getting lockPolicy");
263 return IPMI_CC_UNSPECIFIED_ERROR;
264 }
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700265 if (regionLockUnlocked != std::get<uint8_t>(lockPolicyVal))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700266 {
267 return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
268 }
269
Vernon Mauery15419dd2019-05-24 09:40:30 -0700270 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
271 MDRV1_INTERFACE, "RegionRead");
Vernon Mauerya3702c12019-05-22 13:20:59 -0700272
273 method.append(regionId, requestData->length, requestData->offset);
274
Vernon Mauery15419dd2019-05-24 09:40:30 -0700275 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700276 if (reply.is_method_error())
277 {
278 phosphor::logging::log<level::ERR>(
279 "Error read region data",
280 phosphor::logging::entry("SERVICE=%s", service.c_str()),
281 phosphor::logging::entry("PATH=%s", MDRV1_PATH));
282 return IPMI_CC_UNSPECIFIED_ERROR;
283 }
284 reply.read(res);
285
286 *data_len = responseData->length = res[0];
287 responseData->updateCount = res[1];
288
Yong Liba3e4f52019-10-31 18:19:58 +0800289 if ((*data_len == 0) || (*data_len >= maxDataLen))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700290 {
291 phosphor::logging::log<level::ERR>(
292 "Data length send from service is invalid");
293 *data_len = 0;
294 return IPMI_CC_RESPONSE_ERROR;
295 }
296
297 *data_len += 2 * sizeof(uint8_t);
298 std::copy(&res[2], &res[*data_len], responseData->data);
299 return IPMI_CC_OK;
300}
301
James Feista73cb812019-08-14 10:17:02 -0700302ipmi_ret_t cmd_region_write(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
303 ipmi_request_t request, ipmi_response_t response,
304 ipmi_data_len_t data_len, ipmi_context_t context)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700305{
James Feista73cb812019-08-14 10:17:02 -0700306 auto requestData = reinterpret_cast<const RegionWriteRequest*>(request);
307 uint8_t regionId = requestData->regionId - 1;
308 std::string res;
309 std::vector<uint8_t> writeData;
310 uint16_t index;
311 uint8_t tmp[255];
Vernon Mauerya3702c12019-05-22 13:20:59 -0700312
James Feista73cb812019-08-14 10:17:02 -0700313 size_t minInputLen = &requestData->data[0] - &requestData->sessionId + 1;
314 if (*data_len < minInputLen)
315 { // this command need at least 6 bytes input
316 *data_len = 0;
317 return IPMI_CC_REQ_DATA_LEN_INVALID;
318 }
319
Patrick Williams886a48a2020-05-13 17:44:37 -0500320 std::variant<uint8_t, uint16_t> value;
James Feista73cb812019-08-14 10:17:02 -0700321
322 *data_len = 0;
323
324 if (regionId >= maxMDRId)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700325 {
326 phosphor::logging::log<level::ERR>("Invalid region");
James Feista73cb812019-08-14 10:17:02 -0700327 return IPMI_CC_PARM_OUT_OF_RANGE;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700328 }
329
Vernon Mauery15419dd2019-05-24 09:40:30 -0700330 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
331 std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700332
James Feista73cb812019-08-14 10:17:02 -0700333 if (set_regionId(regionId, service) < 0)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700334 {
335 phosphor::logging::log<level::ERR>("Error setting regionId");
James Feista73cb812019-08-14 10:17:02 -0700336 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700337 }
338
339 if (0 > sdplus_mdrv1_get_property("LockPolicy", value, service))
340 {
341 phosphor::logging::log<level::ERR>("Error getting lockPolicy");
James Feista73cb812019-08-14 10:17:02 -0700342 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700343 }
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700344 if (regionLockUnlocked == std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700345 {
James Feista73cb812019-08-14 10:17:02 -0700346 return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700347 }
348
349 if (0 > sdplus_mdrv1_get_property("SessionId", value, service))
350 {
351 phosphor::logging::log<level::ERR>("Error getting sessionId");
James Feista73cb812019-08-14 10:17:02 -0700352 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700353 }
James Feista73cb812019-08-14 10:17:02 -0700354 if (requestData->sessionId != std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700355 {
James Feista73cb812019-08-14 10:17:02 -0700356 return IPMI_CC_OEM_SET_IN_PROCESS;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700357 }
358
James Feista73cb812019-08-14 10:17:02 -0700359 std::copy(&(requestData->length), &(requestData->data[requestData->length]),
360 tmp);
361 writeData.push_back(regionId);
362 for (index = 0; index < minInputLen + requestData->length - 2; index++)
363 {
364 writeData.push_back(tmp[index]);
365 }
366
Vernon Mauery15419dd2019-05-24 09:40:30 -0700367 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
368 MDRV1_INTERFACE, "RegionWrite");
Vernon Mauerya3702c12019-05-22 13:20:59 -0700369
370 method.append(writeData);
371
Vernon Mauery15419dd2019-05-24 09:40:30 -0700372 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700373 if (reply.is_method_error())
374 {
375 phosphor::logging::log<level::ERR>(
376 "Error write region data",
377 phosphor::logging::entry("SERVICE=%s", service.c_str()),
378 phosphor::logging::entry("PATH=%s", MDRV1_PATH));
James Feista73cb812019-08-14 10:17:02 -0700379 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700380 }
381 reply.read(res);
382
383 if (res == "NoData")
384 {
James Feista73cb812019-08-14 10:17:02 -0700385 return IPMI_CC_PARM_OUT_OF_RANGE;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700386 }
387 else if (res != "Success")
388 {
389 phosphor::logging::log<level::ERR>(
390 "Error write region data, unexpected error");
James Feista73cb812019-08-14 10:17:02 -0700391 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700392 }
393
James Feista73cb812019-08-14 10:17:02 -0700394 return IPMI_CC_OK;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700395}
396
James Feista73cb812019-08-14 10:17:02 -0700397ipmi_ret_t cmd_region_lock(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
398 ipmi_request_t request, ipmi_response_t response,
399 ipmi_data_len_t data_len, ipmi_context_t context)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700400{
James Feista73cb812019-08-14 10:17:02 -0700401 auto requestData = reinterpret_cast<const RegionLockRequest*>(request);
402 uint8_t regionId = requestData->regionId - 1;
Patrick Williams886a48a2020-05-13 17:44:37 -0500403 std::variant<uint8_t, uint16_t> value;
James Feista73cb812019-08-14 10:17:02 -0700404 auto res = reinterpret_cast<uint8_t*>(response);
405 uint8_t lockResponse;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700406
James Feista73cb812019-08-14 10:17:02 -0700407 if (*data_len != sizeof(RegionLockRequest))
408 {
409 *data_len = 0;
410 return IPMI_CC_REQ_DATA_LEN_INVALID;
411 }
412
413 *data_len = 0;
414
415 if (regionId >= maxMDRId)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700416 {
417 phosphor::logging::log<level::ERR>("Invalid region");
James Feista73cb812019-08-14 10:17:02 -0700418 return IPMI_CC_PARM_OUT_OF_RANGE;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700419 }
420
Vernon Mauery15419dd2019-05-24 09:40:30 -0700421 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
422 std::string service = ipmi::getService(*bus, MDRV1_INTERFACE, MDRV1_PATH);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700423
James Feista73cb812019-08-14 10:17:02 -0700424 if (set_regionId(regionId, service) < 0)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700425 {
426 phosphor::logging::log<level::ERR>("Error setting regionId");
James Feista73cb812019-08-14 10:17:02 -0700427 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700428 }
429
430 if (0 > sdplus_mdrv1_get_property("LockPolicy", value, service))
431 {
432 phosphor::logging::log<level::ERR>("Error getting lockPolicy");
James Feista73cb812019-08-14 10:17:02 -0700433 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700434 }
James Feista73cb812019-08-14 10:17:02 -0700435 if (requestData->lockPolicy == regionLockUnlocked)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700436 {
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700437 if (regionLockUnlocked == std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700438 {
James Feista73cb812019-08-14 10:17:02 -0700439 return IPMI_CC_PARAMETER_NOT_SUPPORT_IN_PRESENT_STATE;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700440 }
441 }
Vernon Mauery8166c8d2019-05-23 11:22:30 -0700442 if (regionLockUnlocked != std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700443 {
444 if (0 > sdplus_mdrv1_get_property("SessionId", value, service))
445 {
446 phosphor::logging::log<level::ERR>("Error getting sessionId");
James Feista73cb812019-08-14 10:17:02 -0700447 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700448 }
James Feista73cb812019-08-14 10:17:02 -0700449 if (requestData->sessionId != std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700450 {
James Feista73cb812019-08-14 10:17:02 -0700451 if (requestData->lockPolicy != regionLockStrict)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700452 {
James Feista73cb812019-08-14 10:17:02 -0700453 return IPMI_CC_OEM_SET_IN_PROCESS;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700454 }
455 }
456 }
Vernon Mauery15419dd2019-05-24 09:40:30 -0700457 auto method = bus->new_method_call(service.c_str(), MDRV1_PATH,
458 MDRV1_INTERFACE, "RegionLock");
Vernon Mauerya3702c12019-05-22 13:20:59 -0700459
James Feista73cb812019-08-14 10:17:02 -0700460 method.append(requestData->sessionId, regionId, requestData->lockPolicy,
461 requestData->msTimeout);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700462
Vernon Mauery15419dd2019-05-24 09:40:30 -0700463 auto reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700464 if (reply.is_method_error())
465 {
466 phosphor::logging::log<level::ERR>(
467 "Error lock region ",
468 phosphor::logging::entry("SERVICE=%s", service.c_str()),
469 phosphor::logging::entry("PATH=%s", MDRV1_PATH));
James Feista73cb812019-08-14 10:17:02 -0700470 return IPMI_CC_UNSPECIFIED_ERROR;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700471 }
472 reply.read(lockResponse);
473
James Feista73cb812019-08-14 10:17:02 -0700474 *data_len = sizeof(lockResponse);
475 *res = lockResponse;
476 return IPMI_CC_OK;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700477}
478
479static void register_netfn_smbios_functions(void)
480{
Yong Li38b58f52019-12-24 09:29:25 +0800481#ifdef MDR_V1_SUPPORT
Vernon Mauerya3702c12019-05-22 13:20:59 -0700482 // MDR V1 Command
483 // <Get MDR Status Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -0700484 ipmi_register_callback(ipmi::intel::netFnApp,
485 ipmi::intel::app::cmdMdrStatus, NULL,
Vernon Mauerya3702c12019-05-22 13:20:59 -0700486 cmd_region_status, PRIVILEGE_OPERATOR);
487
488 // <Update Complete Status Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -0700489 ipmi_register_callback(ipmi::intel::netFnApp,
490 ipmi::intel::app::cmdMdrComplete, NULL,
James Feista73cb812019-08-14 10:17:02 -0700491 cmd_region_complete, PRIVILEGE_OPERATOR);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700492
493 // <Read MDR Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -0700494 ipmi_register_callback(ipmi::intel::netFnApp, ipmi::intel::app::cmdMdrRead,
495 NULL, cmd_region_read, PRIVILEGE_OPERATOR);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700496
497 // <Write MDR Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -0700498 ipmi_register_callback(ipmi::intel::netFnApp, ipmi::intel::app::cmdMdrWrite,
499 NULL, cmd_region_write, PRIVILEGE_OPERATOR);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700500
501 // <Lock MDR Command>
Vernon Mauery98bbf692019-09-16 11:14:59 -0700502 ipmi_register_callback(ipmi::intel::netFnApp, ipmi::intel::app::cmdMdrLock,
503 NULL, cmd_region_lock, PRIVILEGE_OPERATOR);
Yong Li38b58f52019-12-24 09:29:25 +0800504#endif
Vernon Mauerya3702c12019-05-22 13:20:59 -0700505}