blob: ab3aa58edc9fe774ddc53bafc6b4d4ff65d8e6e0 [file] [log] [blame]
Tom Josephbe5eaa12017-07-12 19:54:44 +05301#include "dcmihandler.hpp"
Patrick Williams37af7332016-09-02 21:21:42 -05002#include "host-ipmid/ipmid-api.h"
Tom Josephbe5eaa12017-07-12 19:54:44 +05303#include <phosphor-logging/elog-errors.hpp>
Andrew Geissler50c0c8f2017-07-11 16:18:51 -05004#include <phosphor-logging/log.hpp>
5#include <sdbusplus/bus.hpp>
6#include "utils.hpp"
Chris Austen1810bec2015-10-13 12:12:39 -05007#include <stdio.h>
8#include <string.h>
9#include <stdint.h>
Tom Josephbe5eaa12017-07-12 19:54:44 +053010#include "xyz/openbmc_project/Common/error.hpp"
11
12using namespace phosphor::logging;
13using InternalFailure =
14 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
Chris Austen1810bec2015-10-13 12:12:39 -050015
16void register_netfn_dcmi_functions() __attribute__((constructor));
17
Andrew Geissler50c0c8f2017-07-11 16:18:51 -050018constexpr auto PCAP_PATH = "/xyz/openbmc_project/control/host0/power_cap";
19constexpr auto PCAP_INTERFACE = "xyz.openbmc_project.Control.Power.Cap";
20
21constexpr auto POWER_CAP_PROP = "PowerCap";
22constexpr auto POWER_CAP_ENABLE_PROP = "PowerCapEnable";
23
24using namespace phosphor::logging;
25
Tom Josephb9d86f42017-07-26 18:03:47 +053026namespace dcmi
27{
28
Andrew Geissler50c0c8f2017-07-11 16:18:51 -050029uint32_t getPcap(sdbusplus::bus::bus& bus)
30{
31 auto settingService = ipmi::getService(bus,
Andrew Geisslera944d432017-07-19 17:53:44 -050032 PCAP_INTERFACE,PCAP_PATH);
Andrew Geissler50c0c8f2017-07-11 16:18:51 -050033
34 auto method = bus.new_method_call(settingService.c_str(),
35 PCAP_PATH,
36 "org.freedesktop.DBus.Properties",
37 "Get");
38
39 method.append(PCAP_INTERFACE, POWER_CAP_PROP);
40 auto reply = bus.call(method);
41
42 if (reply.is_method_error())
43 {
44 log<level::ERR>("Error in getPcap prop");
Tom Josephb9d86f42017-07-26 18:03:47 +053045 elog<InternalFailure>();
Andrew Geissler50c0c8f2017-07-11 16:18:51 -050046 }
47 sdbusplus::message::variant<uint32_t> pcap;
48 reply.read(pcap);
49
Tom Josephb9d86f42017-07-26 18:03:47 +053050 return pcap.get<uint32_t>();
Andrew Geissler50c0c8f2017-07-11 16:18:51 -050051}
52
53bool getPcapEnabled(sdbusplus::bus::bus& bus)
54{
55 auto settingService = ipmi::getService(bus,
Andrew Geisslera944d432017-07-19 17:53:44 -050056 PCAP_INTERFACE,PCAP_PATH);
Andrew Geissler50c0c8f2017-07-11 16:18:51 -050057
58 auto method = bus.new_method_call(settingService.c_str(),
59 PCAP_PATH,
60 "org.freedesktop.DBus.Properties",
61 "Get");
62
63 method.append(PCAP_INTERFACE, POWER_CAP_ENABLE_PROP);
64 auto reply = bus.call(method);
65
66 if (reply.is_method_error())
67 {
68 log<level::ERR>("Error in getPcapEnabled prop");
Tom Josephb9d86f42017-07-26 18:03:47 +053069 elog<InternalFailure>();
Andrew Geissler50c0c8f2017-07-11 16:18:51 -050070 }
71 sdbusplus::message::variant<bool> pcapEnabled;
72 reply.read(pcapEnabled);
73
Tom Josephb9d86f42017-07-26 18:03:47 +053074 return pcapEnabled.get<bool>();
Andrew Geissler50c0c8f2017-07-11 16:18:51 -050075}
Chris Austen1810bec2015-10-13 12:12:39 -050076
Tom Joseph46fa37d2017-07-26 18:11:55 +053077void setPcap(sdbusplus::bus::bus& bus, const uint32_t powerCap)
78{
79 auto service = ipmi::getService(bus, PCAP_INTERFACE, PCAP_PATH);
80
81 auto method = bus.new_method_call(service.c_str(),
82 PCAP_PATH,
83 "org.freedesktop.DBus.Properties",
84 "Set");
85
86 method.append(PCAP_INTERFACE, POWER_CAP_PROP);
87 method.append(sdbusplus::message::variant<uint32_t>(powerCap));
88
89 auto reply = bus.call(method);
90
91 if (reply.is_method_error())
92 {
93 log<level::ERR>("Error in setPcap property");
94 elog<InternalFailure>();
95 }
96}
97
Tom Joseph6c8d51b2017-07-26 18:18:06 +053098void setPcapEnable(sdbusplus::bus::bus& bus, bool enabled)
99{
100 auto service = ipmi::getService(bus, PCAP_INTERFACE, PCAP_PATH);
101
102 auto method = bus.new_method_call(service.c_str(),
103 PCAP_PATH,
104 "org.freedesktop.DBus.Properties",
105 "Set");
106
107 method.append(PCAP_INTERFACE, POWER_CAP_ENABLE_PROP);
108 method.append(sdbusplus::message::variant<bool>(enabled));
109
110 auto reply = bus.call(method);
111
112 if (reply.is_method_error())
113 {
114 log<level::ERR>("Error in setPcapEnabled property");
115 elog<InternalFailure>();
116 }
117}
118
Tom Josephbe5eaa12017-07-12 19:54:44 +0530119void readAssetTagObjectTree(dcmi::assettag::ObjectTree& objectTree)
120{
121 static constexpr auto mapperBusName = "xyz.openbmc_project.ObjectMapper";
122 static constexpr auto mapperObjPath = "/xyz/openbmc_project/object_mapper";
123 static constexpr auto mapperIface = "xyz.openbmc_project.ObjectMapper";
124 static constexpr auto inventoryRoot = "/xyz/openbmc_project/inventory/";
125
126 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
127 auto depth = 0;
128
129 auto mapperCall = bus.new_method_call(mapperBusName,
130 mapperObjPath,
131 mapperIface,
132 "GetSubTree");
133
134 mapperCall.append(inventoryRoot);
135 mapperCall.append(depth);
136 mapperCall.append(std::vector<std::string>({dcmi::assetTagIntf}));
137
138 auto mapperReply = bus.call(mapperCall);
139 if (mapperReply.is_method_error())
140 {
141 log<level::ERR>("Error in mapper call");
142 elog<InternalFailure>();
143 }
144
145 mapperReply.read(objectTree);
146
147 if (objectTree.empty())
148 {
149 log<level::ERR>("AssetTag property is not populated");
150 elog<InternalFailure>();
151 }
152}
153
154std::string readAssetTag()
155{
156 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
157 dcmi::assettag::ObjectTree objectTree;
158
159 // Read the object tree with the inventory root to figure out the object
160 // that has implemented the Asset tag interface.
161 readAssetTagObjectTree(objectTree);
162
163 auto method = bus.new_method_call(
164 (objectTree.begin()->second.begin()->first).c_str(),
165 (objectTree.begin()->first).c_str(),
166 dcmi::propIntf,
167 "Get");
168 method.append(dcmi::assetTagIntf);
169 method.append(dcmi::assetTagProp);
170
171 auto reply = bus.call(method);
172 if (reply.is_method_error())
173 {
174 log<level::ERR>("Error in reading asset tag");
175 elog<InternalFailure>();
176 }
177
178 sdbusplus::message::variant<std::string> assetTag;
179 reply.read(assetTag);
180
181 return assetTag.get<std::string>();
182}
183
Tom Josephbe5b9892017-07-15 00:55:23 +0530184void writeAssetTag(const std::string& assetTag)
185{
186 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
187 dcmi::assettag::ObjectTree objectTree;
188
189 // Read the object tree with the inventory root to figure out the object
190 // that has implemented the Asset tag interface.
191 readAssetTagObjectTree(objectTree);
192
193 auto method = bus.new_method_call(
194 (objectTree.begin()->second.begin()->first).c_str(),
195 (objectTree.begin()->first).c_str(),
196 dcmi::propIntf,
197 "Set");
198 method.append(dcmi::assetTagIntf);
199 method.append(dcmi::assetTagProp);
200 method.append(sdbusplus::message::variant<std::string>(assetTag));
201
202 auto reply = bus.call(method);
203 if (reply.is_method_error())
204 {
205 log<level::ERR>("Error in writing asset tag");
206 elog<InternalFailure>();
207 }
208}
209
Vladislav Vovchenko8f7a6f62017-08-17 00:31:14 +0300210std::string getHostName(void)
211{
212 sdbusplus::bus::bus bus{ ipmid_get_sd_bus_connection() };
213
214 auto service = ipmi::getService(bus, networkConfigIntf, networkConfigObj);
215 auto value = ipmi::getDbusProperty(bus, service,
216 networkConfigObj, networkConfigIntf, hostNameProp);
217
218 return value.get<std::string>();
219}
220
Tom Josephbe5eaa12017-07-12 19:54:44 +0530221} // namespace dcmi
Chris Austen1810bec2015-10-13 12:12:39 -0500222
Tom Josephb9d86f42017-07-26 18:03:47 +0530223ipmi_ret_t getPowerLimit(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
224 ipmi_request_t request, ipmi_response_t response,
225 ipmi_data_len_t data_len, ipmi_context_t context)
226{
227 auto requestData = reinterpret_cast<const dcmi::GetPowerLimitRequest*>
228 (request);
229 std::vector<uint8_t> outPayload(sizeof(dcmi::GetPowerLimitResponse));
230 auto responseData = reinterpret_cast<dcmi::GetPowerLimitResponse*>
231 (outPayload.data());
232
233 if (requestData->groupID != dcmi::groupExtId)
234 {
235 *data_len = 0;
236 return IPMI_CC_INVALID_FIELD_REQUEST;
237 }
238
239 sdbusplus::bus::bus sdbus {ipmid_get_sd_bus_connection()};
240 uint32_t pcapValue = 0;
241 bool pcapEnable = false;
242
243 try
244 {
245 pcapValue = dcmi::getPcap(sdbus);
246 pcapEnable = dcmi::getPcapEnabled(sdbus);
247 }
248 catch (InternalFailure& e)
249 {
250 *data_len = 0;
251 return IPMI_CC_UNSPECIFIED_ERROR;
252 }
253
254 responseData->groupID = dcmi::groupExtId;
255
256 /*
257 * Exception action if power limit is exceeded and cannot be controlled
258 * with the correction time limit is hardcoded to Hard Power Off system
259 * and log event to SEL.
260 */
261 constexpr auto exception = 0x01;
262 responseData->exceptionAction = exception;
263
264 responseData->powerLimit = static_cast<uint16_t>(pcapValue);
265
266 /*
267 * Correction time limit and Statistics sampling period is currently not
268 * populated.
269 */
270
271 *data_len = outPayload.size();
272 memcpy(response, outPayload.data(), *data_len);
273
274 if (pcapEnable)
275 {
276 return IPMI_CC_OK;
277 }
278 else
279 {
280 return IPMI_DCMI_CC_NO_ACTIVE_POWER_LIMIT;
281 }
282}
283
Tom Joseph46fa37d2017-07-26 18:11:55 +0530284ipmi_ret_t setPowerLimit(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
285 ipmi_request_t request, ipmi_response_t response,
286 ipmi_data_len_t data_len, ipmi_context_t context)
287{
288 auto requestData = reinterpret_cast<const dcmi::SetPowerLimitRequest*>
289 (request);
290 std::vector<uint8_t> outPayload(sizeof(dcmi::SetPowerLimitResponse));
291 auto responseData = reinterpret_cast<dcmi::SetPowerLimitResponse*>
292 (outPayload.data());
293
294 if (requestData->groupID != dcmi::groupExtId)
295 {
296 *data_len = 0;
297 return IPMI_CC_INVALID_FIELD_REQUEST;
298 }
299
300 sdbusplus::bus::bus sdbus {ipmid_get_sd_bus_connection()};
301
302 // Only process the power limit requested in watts.
303 try
304 {
305 dcmi::setPcap(sdbus, requestData->powerLimit);
306 }
307 catch (InternalFailure& e)
308 {
309 *data_len = 0;
310 return IPMI_CC_UNSPECIFIED_ERROR;
311 }
312
313 log<level::INFO>("Set Power Cap",
314 entry("POWERCAP=%u", requestData->powerLimit));
315
316 responseData->groupID = dcmi::groupExtId;
317 memcpy(response, outPayload.data(), outPayload.size());
318 *data_len = outPayload.size();
319
320 return IPMI_CC_OK;
321}
322
Tom Joseph6c8d51b2017-07-26 18:18:06 +0530323ipmi_ret_t applyPowerLimit(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
324 ipmi_request_t request, ipmi_response_t response,
325 ipmi_data_len_t data_len, ipmi_context_t context)
326{
327 auto requestData = reinterpret_cast<const dcmi::ApplyPowerLimitRequest*>
328 (request);
329 std::vector<uint8_t> outPayload(sizeof(dcmi::ApplyPowerLimitResponse));
330 auto responseData = reinterpret_cast<dcmi::ApplyPowerLimitResponse*>
331 (outPayload.data());
332
333 if (requestData->groupID != dcmi::groupExtId)
334 {
335 *data_len = 0;
336 return IPMI_CC_INVALID_FIELD_REQUEST;
337 }
338
339 sdbusplus::bus::bus sdbus {ipmid_get_sd_bus_connection()};
340
341 try
342 {
343 dcmi::setPcapEnable(sdbus,
344 static_cast<bool>(requestData->powerLimitAction));
345 }
346 catch (InternalFailure& e)
347 {
348 *data_len = 0;
349 return IPMI_CC_UNSPECIFIED_ERROR;
350 }
351
352 log<level::INFO>("Set Power Cap Enable",
353 entry("POWERCAPENABLE=%u", requestData->powerLimitAction));
354
355 responseData->groupID = dcmi::groupExtId;
356 memcpy(response, outPayload.data(), outPayload.size());
357 *data_len = outPayload.size();
358
359 return IPMI_CC_OK;
360}
361
Tom Joseph6f6dd4d2017-07-12 20:07:11 +0530362ipmi_ret_t getAssetTag(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
363 ipmi_request_t request, ipmi_response_t response,
364 ipmi_data_len_t data_len, ipmi_context_t context)
365{
366 auto requestData = reinterpret_cast<const dcmi::GetAssetTagRequest*>
367 (request);
368 std::vector<uint8_t> outPayload(sizeof(dcmi::GetAssetTagResponse));
369 auto responseData = reinterpret_cast<dcmi::GetAssetTagResponse*>
370 (outPayload.data());
371
372 if (requestData->groupID != dcmi::groupExtId)
373 {
374 *data_len = 0;
375 return IPMI_CC_INVALID_FIELD_REQUEST;
376 }
377
378 // Verify offset to read and number of bytes to read are not exceeding the
379 // range.
380 if ((requestData->offset > dcmi::assetTagMaxOffset) ||
381 (requestData->bytes > dcmi::maxBytes) ||
382 ((requestData->offset + requestData->bytes) > dcmi::assetTagMaxSize))
383 {
384 *data_len = 0;
385 return IPMI_CC_PARM_OUT_OF_RANGE;
386 }
387
388 std::string assetTag;
389
390 try
391 {
392 assetTag = dcmi::readAssetTag();
393 }
394 catch (InternalFailure& e)
395 {
396 *data_len = 0;
397 return IPMI_CC_UNSPECIFIED_ERROR;
398 }
399
400 responseData->groupID = dcmi::groupExtId;
401
402 // Return if the asset tag is not populated.
403 if (!assetTag.size())
404 {
405 responseData->tagLength = 0;
406 memcpy(response, outPayload.data(), outPayload.size());
407 *data_len = outPayload.size();
408 return IPMI_CC_OK;
409 }
410
411 // If the asset tag is longer than 63 bytes, restrict it to 63 bytes to suit
412 // Get Asset Tag command.
413 if (assetTag.size() > dcmi::assetTagMaxSize)
414 {
415 assetTag.resize(dcmi::assetTagMaxSize);
416 }
417
418 // If the requested offset is beyond the asset tag size.
419 if (requestData->offset >= assetTag.size())
420 {
421 *data_len = 0;
422 return IPMI_CC_PARM_OUT_OF_RANGE;
423 }
424
425 auto returnData = assetTag.substr(requestData->offset, requestData->bytes);
426
427 responseData->tagLength = assetTag.size();
428
429 memcpy(response, outPayload.data(), outPayload.size());
430 memcpy(static_cast<uint8_t*>(response) + outPayload.size(),
431 returnData.data(), returnData.size());
432 *data_len = outPayload.size() + returnData.size();
433
434 return IPMI_CC_OK;
435}
436
Tom Joseph545dd232017-07-12 20:20:49 +0530437ipmi_ret_t setAssetTag(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
438 ipmi_request_t request, ipmi_response_t response,
439 ipmi_data_len_t data_len, ipmi_context_t context)
440{
441 auto requestData = reinterpret_cast<const dcmi::SetAssetTagRequest*>
442 (request);
443 std::vector<uint8_t> outPayload(sizeof(dcmi::SetAssetTagResponse));
444 auto responseData = reinterpret_cast<dcmi::SetAssetTagResponse*>
445 (outPayload.data());
446
447 if (requestData->groupID != dcmi::groupExtId)
448 {
449 *data_len = 0;
450 return IPMI_CC_INVALID_FIELD_REQUEST;
451 }
452
453 // Verify offset to read and number of bytes to read are not exceeding the
454 // range.
455 if ((requestData->offset > dcmi::assetTagMaxOffset) ||
456 (requestData->bytes > dcmi::maxBytes) ||
457 ((requestData->offset + requestData->bytes) > dcmi::assetTagMaxSize))
458 {
459 *data_len = 0;
460 return IPMI_CC_PARM_OUT_OF_RANGE;
461 }
462
463 std::string assetTag;
464
465 try
466 {
467 assetTag = dcmi::readAssetTag();
468
469 if (requestData->offset > assetTag.size())
470 {
471 *data_len = 0;
472 return IPMI_CC_PARM_OUT_OF_RANGE;
473 }
474
475 assetTag.replace(requestData->offset,
476 assetTag.size() - requestData->offset,
477 static_cast<const char*>(request) +
478 sizeof(dcmi::SetAssetTagRequest),
479 requestData->bytes);
480
481 dcmi::writeAssetTag(assetTag);
482
483 responseData->groupID = dcmi::groupExtId;
484 responseData->tagLength = assetTag.size();
485 memcpy(response, outPayload.data(), outPayload.size());
486 *data_len = outPayload.size();
487
488 return IPMI_CC_OK;
489 }
490 catch (InternalFailure& e)
491 {
492 *data_len = 0;
493 return IPMI_CC_UNSPECIFIED_ERROR;
494 }
495}
496
Vladislav Vovchenko8f7a6f62017-08-17 00:31:14 +0300497ipmi_ret_t getMgmntCtrlIdStr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
498 ipmi_request_t request, ipmi_response_t response,
499 ipmi_data_len_t data_len, ipmi_context_t context)
500{
501 auto requestData = reinterpret_cast<const dcmi::GetMgmntCtrlIdStrRequest *>
502 (request);
503 auto responseData = reinterpret_cast<dcmi::GetMgmntCtrlIdStrResponse *>
504 (response);
505 std::string hostName;
506
507 *data_len = 0;
508
509 if (requestData->groupID != dcmi::groupExtId ||
510 requestData->bytes > dcmi::maxBytes ||
511 requestData->offset + requestData->bytes > dcmi::maxCtrlIdStrLen)
512 {
513 return IPMI_CC_INVALID_FIELD_REQUEST;
514 }
515
516 try
517 {
518 hostName = dcmi::getHostName();
519 }
520 catch (InternalFailure& e)
521 {
522 return IPMI_CC_UNSPECIFIED_ERROR;
523 }
524
525 if (requestData->offset > hostName.length())
526 {
527 return IPMI_CC_PARM_OUT_OF_RANGE;
528 }
529 auto responseStr = hostName.substr(requestData->offset, requestData->bytes);
530 auto responseStrLen = std::min(static_cast<std::size_t>(requestData->bytes),
531 responseStr.length() + 1);
532 responseData->groupID = dcmi::groupExtId;
533 responseData->strLen = hostName.length();
534 std::copy(begin(responseStr), end(responseStr), responseData->data);
535
536 *data_len = sizeof(*responseData) + responseStrLen;
537 return IPMI_CC_OK;
538}
539
540ipmi_ret_t setMgmntCtrlIdStr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
541 ipmi_request_t request, ipmi_response_t response,
542 ipmi_data_len_t data_len, ipmi_context_t context)
543{
544 static std::array<char, dcmi::maxCtrlIdStrLen + 1> newCtrlIdStr;
545
546 auto requestData = reinterpret_cast<const dcmi::SetMgmntCtrlIdStrRequest *>
547 (request);
548 auto responseData = reinterpret_cast<dcmi::SetMgmntCtrlIdStrResponse *>
549 (response);
550
551 *data_len = 0;
552
553 if (requestData->groupID != dcmi::groupExtId ||
554 requestData->bytes > dcmi::maxBytes ||
555 requestData->offset + requestData->bytes > dcmi::maxCtrlIdStrLen + 1 ||
556 (requestData->offset + requestData->bytes == dcmi::maxCtrlIdStrLen + 1 &&
557 requestData->data[requestData->bytes - 1] != '\0'))
558 {
559 return IPMI_CC_INVALID_FIELD_REQUEST;
560 }
561
562 try
563 {
564 /* if there is no old value and offset is not 0 */
565 if (newCtrlIdStr[0] == '\0' && requestData->offset != 0)
566 {
567 /* read old ctrlIdStr */
568 auto hostName = dcmi::getHostName();
569 hostName.resize(dcmi::maxCtrlIdStrLen);
570 std::copy(begin(hostName), end(hostName), begin(newCtrlIdStr));
571 newCtrlIdStr[hostName.length()] = '\0';
572 }
573
574 /* replace part of string and mark byte after the last as \0 */
575 auto restStrIter = std::copy_n(requestData->data,
576 requestData->bytes, begin(newCtrlIdStr) + requestData->offset);
577 /* if the last written byte is not 64th - add '\0' */
578 if (requestData->offset + requestData->bytes <= dcmi::maxCtrlIdStrLen)
579 {
580 *restStrIter = '\0';
581 }
582
583 /* if input data contains '\0' whole string is sent - update hostname */
584 auto it = std::find(requestData->data,
585 requestData->data + requestData->bytes, '\0');
586 if (it != requestData->data + requestData->bytes)
587 {
588 sdbusplus::bus::bus bus{ ipmid_get_sd_bus_connection() };
589 ipmi::setDbusProperty(bus, dcmi::networkServiceName,
590 dcmi::networkConfigObj, dcmi::networkConfigIntf,
591 dcmi::hostNameProp, std::string(newCtrlIdStr.data()));
592 }
593 }
594 catch (InternalFailure& e)
595 {
596 *data_len = 0;
597 return IPMI_CC_UNSPECIFIED_ERROR;
598 }
599
600 responseData->groupID = dcmi::groupExtId;
601 responseData->offset = requestData->offset + requestData->bytes;
602 *data_len = sizeof(*responseData);
603 return IPMI_CC_OK;
604}
605
Chris Austen1810bec2015-10-13 12:12:39 -0500606void register_netfn_dcmi_functions()
607{
Tom05732372016-09-06 17:21:23 +0530608 // <Get Power Limit>
Ratan Gupta11ddbd22017-08-05 11:59:39 +0530609 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",
610 NETFUN_GRPEXT, dcmi::Commands::GET_POWER_LIMIT);
611
612 ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::GET_POWER_LIMIT,
613 NULL, getPowerLimit, PRIVILEGE_USER);
Tom Joseph6f6dd4d2017-07-12 20:07:11 +0530614
Tom Joseph46fa37d2017-07-26 18:11:55 +0530615 // <Set Power Limit>
Ratan Gupta11ddbd22017-08-05 11:59:39 +0530616 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",
617 NETFUN_GRPEXT, dcmi::Commands::SET_POWER_LIMIT);
618
619 ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::SET_POWER_LIMIT,
620 NULL, setPowerLimit, PRIVILEGE_OPERATOR);
Tom Joseph46fa37d2017-07-26 18:11:55 +0530621
Tom Joseph6c8d51b2017-07-26 18:18:06 +0530622 // <Activate/Deactivate Power Limit>
Ratan Gupta11ddbd22017-08-05 11:59:39 +0530623 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",
624 NETFUN_GRPEXT, dcmi::Commands::APPLY_POWER_LIMIT);
625
626 ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::APPLY_POWER_LIMIT,
627 NULL, applyPowerLimit, PRIVILEGE_OPERATOR);
Tom Joseph6c8d51b2017-07-26 18:18:06 +0530628
Tom Joseph6f6dd4d2017-07-12 20:07:11 +0530629 // <Get Asset Tag>
Ratan Gupta11ddbd22017-08-05 11:59:39 +0530630 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",
631 NETFUN_GRPEXT, dcmi::Commands::GET_ASSET_TAG);
632
633 ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::GET_ASSET_TAG,
634 NULL, getAssetTag, PRIVILEGE_USER);
Tom Joseph545dd232017-07-12 20:20:49 +0530635
636 // <Set Asset Tag>
Ratan Gupta11ddbd22017-08-05 11:59:39 +0530637 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",
638 NETFUN_GRPEXT, dcmi::Commands::SET_ASSET_TAG);
639
640 ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::SET_ASSET_TAG,
641 NULL, setAssetTag, PRIVILEGE_OPERATOR);
Vladislav Vovchenko8f7a6f62017-08-17 00:31:14 +0300642
Gunnar Mills8991dd62017-10-25 17:11:29 -0500643 // <Get Management Controller Identifier String>
Vladislav Vovchenko8f7a6f62017-08-17 00:31:14 +0300644 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",
645 NETFUN_GRPEXT, dcmi::Commands::GET_MGMNT_CTRL_ID_STR);
646
647 ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::GET_MGMNT_CTRL_ID_STR,
648 NULL, getMgmntCtrlIdStr, PRIVILEGE_USER);
649
650 // <Set Management Controller Identifier String>
651 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",
652 NETFUN_GRPEXT, dcmi::Commands::SET_MGMNT_CTRL_ID_STR);
653 ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::SET_MGMNT_CTRL_ID_STR,
654 NULL, setMgmntCtrlIdStr, PRIVILEGE_ADMIN);
655
Chris Austen1810bec2015-10-13 12:12:39 -0500656 return;
657}
Tom05732372016-09-06 17:21:23 +0530658// 956379