blob: 29adfa4d956e43c51b37ea58228f0bc3bb0a6707 [file] [log] [blame]
vishwabmcba0bd5f2015-09-30 16:50:23 +05301#include "apphandler.h"
Patrick Williams37af7332016-09-02 21:21:42 -05002#include "host-ipmid/ipmid-api.h"
Patrick Williams53a360e2016-08-12 22:01:02 -05003#include "ipmid.hpp"
Ratan Guptab8e99552017-07-27 07:07:48 +05304#include "types.hpp"
5#include "utils.hpp"
6
vishwabmcba0bd5f2015-09-30 16:50:23 +05307#include <stdio.h>
8#include <string.h>
Chris Austen6caf28b2015-10-13 12:40:40 -05009#include <stdint.h>
Adriana Kobylak3a552e12015-10-19 16:11:00 -050010#include <systemd/sd-bus.h>
Sergey Solomineb9b8142016-08-23 09:07:28 -050011#include <mapper.h>
Nan Liee0cb902016-07-11 15:38:03 +080012#include <array>
Tom Joseph69fabfe2017-08-04 10:15:01 +053013#include <vector>
Ratan Gupta62736ec2017-09-02 12:02:47 +053014#include <experimental/filesystem>
15
Nan Li3d0df912016-10-18 19:51:41 +080016#include <arpa/inet.h>
Ratan Guptab8e99552017-07-27 07:07:48 +053017#include "transporthandler.hpp"
18
19#include <phosphor-logging/log.hpp>
20#include <phosphor-logging/elog-errors.hpp>
21#include "xyz/openbmc_project/Common/error.hpp"
22
Adriana Kobylak3a552e12015-10-19 16:11:00 -050023extern sd_bus *bus;
vishwabmcba0bd5f2015-09-30 16:50:23 +053024
Nan Li3d0df912016-10-18 19:51:41 +080025constexpr auto app_obj = "/org/openbmc/NetworkManager/Interface";
26constexpr auto app_ifc = "org.openbmc.NetworkManager";
27constexpr auto app_nwinterface = "eth0";
28
Ratan Guptab8e99552017-07-27 07:07:48 +053029constexpr auto ipv4Protocol = "xyz.openbmc_project.Network.IP.Protocol.IPv4";
30
Chris Austen6caf28b2015-10-13 12:40:40 -050031void register_netfn_app_functions() __attribute__((constructor));
vishwabmcba0bd5f2015-09-30 16:50:23 +053032
Ratan Guptab8e99552017-07-27 07:07:48 +053033using namespace phosphor::logging;
34using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Ratan Gupta62736ec2017-09-02 12:02:47 +053035namespace fs = std::experimental::filesystem;
Ratan Guptab8e99552017-07-27 07:07:48 +053036
Nan Liee0cb902016-07-11 15:38:03 +080037// Offset in get device id command.
38typedef struct
39{
40 uint8_t id;
41 uint8_t revision;
42 uint8_t fw[2];
43 uint8_t ipmi_ver;
44 uint8_t addn_dev_support;
45 uint8_t manuf_id[3];
46 uint8_t prod_id[2];
47 uint8_t aux[4];
48}__attribute__((packed)) ipmi_device_id_t;
Chris Austen7303bdc2016-04-17 11:50:54 -050049
Adriana Kobylak3a552e12015-10-19 16:11:00 -050050ipmi_ret_t ipmi_app_set_acpi_power_state(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
51 ipmi_request_t request, ipmi_response_t response,
Chris Austen6caf28b2015-10-13 12:40:40 -050052 ipmi_data_len_t data_len, ipmi_context_t context)
53{
54 ipmi_ret_t rc = IPMI_CC_OK;
55 *data_len = 0;
56
57 printf("IPMI SET ACPI STATE Ignoring for now\n");
58 return rc;
59}
60
Chris Austen7303bdc2016-04-17 11:50:54 -050061
62typedef struct
63{
64 char major;
65 char minor;
Chris Austen176c9652016-04-30 16:32:17 -050066 uint16_t d[2];
Chris Austen7303bdc2016-04-17 11:50:54 -050067} rev_t;
68
69
70/* Currently only supports the vx.x-x-[-x] format Will return -1 if not in */
71/* the format this routine knows how to parse */
72/* version = v0.6-19-gf363f61-dirty */
73/* ^ ^ ^^ ^ */
74/* | | |----------|-- additional details */
75/* | |---------------- Minor */
76/* |------------------ Major */
77/* Additional details : If the option group exists it will force Auxiliary */
78/* Firmware Revision Information 4th byte to 1 indicating the build was */
79/* derived with additional edits */
80int convert_version(const char *p, rev_t *rev)
81{
82 char *s, *token;
Chris Austen176c9652016-04-30 16:32:17 -050083 uint16_t commits;
Chris Austen7303bdc2016-04-17 11:50:54 -050084
85 if (*p != 'v')
86 return -1;
87 p++;
88
89 s = strdup(p);
90 token = strtok(s,".-");
91
92 rev->major = (int8_t) atoi(token);
93
94 token = strtok(NULL, ".-");
95 rev->minor = (int8_t) atoi(token);
96
97 // Capture the number of commits on top of the minor tag.
98 // I'm using BE format like the ipmi spec asked for
99 token = strtok(NULL,".-");
Chris Austen7303bdc2016-04-17 11:50:54 -0500100
Chris Austen176c9652016-04-30 16:32:17 -0500101 if (token) {
102 commits = (int16_t) atoi(token);
103 rev->d[0] = (commits>>8) | (commits<<8);
Chris Austen7303bdc2016-04-17 11:50:54 -0500104
Chris Austen176c9652016-04-30 16:32:17 -0500105 // commit number we skip
106 token = strtok(NULL,".-");
Chris Austen7303bdc2016-04-17 11:50:54 -0500107
Chris Austen176c9652016-04-30 16:32:17 -0500108 } else {
109 rev->d[0] = 0;
110 }
Chris Austen7303bdc2016-04-17 11:50:54 -0500111
112 // Any value of the optional parameter forces it to 1
Chris Austen176c9652016-04-30 16:32:17 -0500113 if (token)
114 token = strtok(NULL,".-");
115
116 rev->d[1] = (token != NULL) ? 1 : 0;
Chris Austen7303bdc2016-04-17 11:50:54 -0500117
118 free(s);
119 return 0;
120}
121
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500122ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
123 ipmi_request_t request, ipmi_response_t response,
Chris Austen6caf28b2015-10-13 12:40:40 -0500124 ipmi_data_len_t data_len, ipmi_context_t context)
125{
126 ipmi_ret_t rc = IPMI_CC_OK;
Chris Austen7303bdc2016-04-17 11:50:54 -0500127 const char *objname = "/org/openbmc/inventory/system/chassis/motherboard/bmc";
128 const char *iface = "org.openbmc.InventoryItem";
129 char *ver = NULL;
Sergey Solomineb9b8142016-08-23 09:07:28 -0500130 char *busname = NULL;
Chris Austen7303bdc2016-04-17 11:50:54 -0500131 int r;
132 rev_t rev = {0};
Nan Liee0cb902016-07-11 15:38:03 +0800133 ipmi_device_id_t dev_id{};
Chris Austen6caf28b2015-10-13 12:40:40 -0500134
135 // Data length
Chris Austen7303bdc2016-04-17 11:50:54 -0500136 *data_len = sizeof(dev_id);
137
Nan Liee0cb902016-07-11 15:38:03 +0800138 // From IPMI spec, controller that have different application commands, or different
139 // definitions of OEM fields, are expected to have different Device ID values.
140 // Set to 0 now.
141
142 // Device Revision is set to 0 now.
143 // Bit7 identifies if device provide Device SDRs, obmc don't have SDR,we use ipmi to
144 // simulate SDR, hence the value:
145 dev_id.revision = 0x80;
146
147 // Firmware revision is already implemented, so get it from appropriate position.
Sergey Solomineb9b8142016-08-23 09:07:28 -0500148 r = mapper_get_service(bus, objname, &busname);
149 if (r < 0) {
Brad Bishop819ddd42016-10-05 21:19:19 -0400150 fprintf(stderr, "Failed to get %s bus name: %s\n",
151 objname, strerror(-r));
Sergey Solomineb9b8142016-08-23 09:07:28 -0500152 goto finish;
153 }
Chris Austen7303bdc2016-04-17 11:50:54 -0500154 r = sd_bus_get_property_string(bus,busname,objname,iface,"version", NULL, &ver);
155 if ( r < 0 ) {
156 fprintf(stderr, "Failed to obtain version property: %s\n", strerror(-r));
157 } else {
158 r = convert_version(ver, &rev);
159 if( r >= 0 ) {
Nan Liee0cb902016-07-11 15:38:03 +0800160 // bit7 identifies if the device is available, 0=normal operation,
161 // 1=device firmware, SDR update or self-initialization in progress.
162 // our SDR is normal working condition, so mask:
163 dev_id.fw[0] = 0x7F & rev.major;
Adriana Kobylak0e912642016-06-22 16:54:39 -0500164
165 rev.minor = (rev.minor > 99 ? 99 : rev.minor);
Nan Liee0cb902016-07-11 15:38:03 +0800166 dev_id.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16;
167 memcpy(&dev_id.aux, rev.d, 4);
Chris Austen7303bdc2016-04-17 11:50:54 -0500168 }
169 }
Chris Austen6caf28b2015-10-13 12:40:40 -0500170
Nan Liee0cb902016-07-11 15:38:03 +0800171 // IPMI Spec verison 2.0
172 dev_id.ipmi_ver = 2;
173
174 // Additional device Support.
175 // List the 'logical device' commands and functions that the controller supports
176 // that are in addition to the mandatory IPM and Application commands.
177 // [7] Chassis Device (device functions as chassis device per ICMB spec.)
178 // [6] Bridge (device responds to Bridge NetFn commands)
179 // [5] IPMB Event Generator
180 // [4] IPMB Event Receiver
181 // [3] FRU Inventory Device
182 // [2] SEL Device
183 // [1] SDR Repository Device
184 // [0] Sensor Device
185 // We support FRU/SEL/Sensor now:
186 dev_id.addn_dev_support = 0x8D;
187
188 // This value is the IANA number assigned to "IBM Platform Firmware
189 // Division", which is also used by our service processor. We may want
190 // a different number or at least a different version?
191 dev_id.manuf_id[0] = 0x41;
192 dev_id.manuf_id[1] = 0xA7;
193 dev_id.manuf_id[2] = 0x00;
194
195 // Witherspoon's product ID is hardcoded to 4F42(ASCII 'OB').
196 // TODO: openbmc/openbmc#495
197 dev_id.prod_id[0] = 0x4F;
198 dev_id.prod_id[1] = 0x42;
199
Chris Austen6caf28b2015-10-13 12:40:40 -0500200 // Pack the actual response
Chris Austen7303bdc2016-04-17 11:50:54 -0500201 memcpy(response, &dev_id, *data_len);
Sergey Solomineb9b8142016-08-23 09:07:28 -0500202finish:
203 free(busname);
Xo Wange5536382017-07-20 20:14:00 -0700204 free(ver);
Chris Austen6caf28b2015-10-13 12:40:40 -0500205 return rc;
206}
207
Nan Li41fa24a2016-11-10 20:12:37 +0800208ipmi_ret_t ipmi_app_get_self_test_results(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 ipmi_ret_t rc = IPMI_CC_OK;
213
214 // Byte 2:
215 // 55h - No error.
216 // 56h - Self Test funciton not implemented in this controller.
217 // 57h - Corrupted or inaccesssible data or devices.
218 // 58h - Fatal hardware error.
219 // FFh - reserved.
220 // all other: Device-specific 'internal failure'.
221 // Byte 3:
222 // For byte 2 = 55h, 56h, FFh: 00h
223 // For byte 2 = 58h, all other: Device-specific
224 // For byte 2 = 57h: self-test error bitfield.
225 // Note: returning 57h does not imply that all test were run.
226 // [7] 1b = Cannot access SEL device.
227 // [6] 1b = Cannot access SDR Repository.
228 // [5] 1b = Cannot access BMC FRU device.
229 // [4] 1b = IPMB signal lines do not respond.
230 // [3] 1b = SDR Repository empty.
231 // [2] 1b = Internal Use Area of BMC FRU corrupted.
232 // [1] 1b = controller update 'boot block' firmware corrupted.
233 // [0] 1b = controller operational firmware corrupted.
234
235 char selftestresults[2] = {0};
236
237 *data_len = 2;
238
239 selftestresults[0] = 0x56;
240 selftestresults[1] = 0;
241
242 memcpy(response, selftestresults, *data_len);
243
244 return rc;
245}
246
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500247ipmi_ret_t ipmi_app_get_device_guid(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
248 ipmi_request_t request, ipmi_response_t response,
249 ipmi_data_len_t data_len, ipmi_context_t context)
250{
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500251 const char *objname = "/org/openbmc/control/chassis0";
Adriana Kobylak31bccae2015-11-05 13:31:06 -0600252 const char *iface = "org.freedesktop.DBus.Properties";
253 const char *chassis_iface = "org.openbmc.control.Chassis";
vishwa1eaea4f2016-02-26 11:57:40 -0600254 sd_bus_message *reply = NULL;
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500255 sd_bus_error error = SD_BUS_ERROR_NULL;
256 int r = 0;
257 char *uuid = NULL;
Sergey Solomineb9b8142016-08-23 09:07:28 -0500258 char *busname = NULL;
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500259
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500260 // UUID is in RFC4122 format. Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
261 // Per IPMI Spec 2.0 need to convert to 16 hex bytes and reverse the byte order
262 // Ex: 0x2332fc2c40e66298e511f2782395a361
263
264 const int resp_size = 16; // Response is 16 hex bytes per IPMI Spec
265 uint8_t resp_uuid[resp_size]; // Array to hold the formatted response
266 int resp_loc = resp_size-1; // Point resp end of array to save in reverse order
267 int i = 0;
268 char *tokptr = NULL;
vishwa1eaea4f2016-02-26 11:57:40 -0600269 char *id_octet = NULL;
270
271 // Status code.
272 ipmi_ret_t rc = IPMI_CC_OK;
273 *data_len = 0;
274
275 printf("IPMI GET DEVICE GUID\n");
276
277 // Call Get properties method with the interface and property name
Sergey Solomineb9b8142016-08-23 09:07:28 -0500278 r = mapper_get_service(bus, objname, &busname);
279 if (r < 0) {
Brad Bishop819ddd42016-10-05 21:19:19 -0400280 fprintf(stderr, "Failed to get %s bus name: %s\n",
281 objname, strerror(-r));
Sergey Solomineb9b8142016-08-23 09:07:28 -0500282 goto finish;
283 }
vishwa1eaea4f2016-02-26 11:57:40 -0600284 r = sd_bus_call_method(bus,busname,objname,iface,
285 "Get",&error, &reply, "ss",
286 chassis_iface, "uuid");
287 if (r < 0)
288 {
289 fprintf(stderr, "Failed to call Get Method: %s\n", strerror(-r));
290 rc = IPMI_CC_UNSPECIFIED_ERROR;
291 goto finish;
292 }
293
294 r = sd_bus_message_read(reply, "v", "s", &uuid);
295 if (r < 0 || uuid == NULL)
296 {
297 fprintf(stderr, "Failed to get a response: %s", strerror(-r));
298 rc = IPMI_CC_RESPONSE_ERROR;
299 goto finish;
300 }
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500301
302 // Traverse the UUID
vishwa1eaea4f2016-02-26 11:57:40 -0600303 id_octet = strtok_r(uuid, "-", &tokptr); // Get the UUID octects separated by dash
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500304
305 if (id_octet == NULL)
vishwa1eaea4f2016-02-26 11:57:40 -0600306 {
307 // Error
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500308 fprintf(stderr, "Unexpected UUID format: %s", uuid);
vishwa1eaea4f2016-02-26 11:57:40 -0600309 rc = IPMI_CC_RESPONSE_ERROR;
310 goto finish;
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500311 }
312
313 while (id_octet != NULL)
314 {
315 // Calculate the octet string size since it varies
316 // Divide it by 2 for the array size since 1 byte is built from 2 chars
317 int tmp_size = strlen(id_octet)/2;
318
319 for(i = 0; i < tmp_size; i++)
320 {
Joel Stanley38310cd2015-11-25 17:32:08 +1030321 char tmp_array[3] = {0}; // Holder of the 2 chars that will become a byte
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500322 strncpy(tmp_array, id_octet, 2); // 2 chars at a time
323
324 int resp_byte = strtoul(tmp_array, NULL, 16); // Convert to hex byte
325 memcpy((void*)&resp_uuid[resp_loc], &resp_byte, 1); // Copy end to first
326 resp_loc--;
327 id_octet+=2; // Finished with the 2 chars, advance
328 }
329 id_octet=strtok_r(NULL, "-", &tokptr); // Get next octet
330 }
331
332 // Data length
333 *data_len = resp_size;
334
335 // Pack the actual response
336 memcpy(response, &resp_uuid, *data_len);
337
vishwa1eaea4f2016-02-26 11:57:40 -0600338finish:
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500339 sd_bus_error_free(&error);
vishwa1eaea4f2016-02-26 11:57:40 -0600340 reply = sd_bus_message_unref(reply);
Sergey Solomineb9b8142016-08-23 09:07:28 -0500341 free(busname);
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500342
343 return rc;
344}
Chris Austen6caf28b2015-10-13 12:40:40 -0500345
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500346ipmi_ret_t ipmi_app_get_bt_capabilities(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
347 ipmi_request_t request, ipmi_response_t response,
vishwabmcba0bd5f2015-09-30 16:50:23 +0530348 ipmi_data_len_t data_len, ipmi_context_t context)
349{
350 printf("Handling Netfn:[0x%X], Cmd:[0x%X]\n",netfn,cmd);
351
352 // Status code.
353 ipmi_ret_t rc = IPMI_CC_OK;
354
Adriana Kobylak88ad8152016-12-13 10:09:08 -0600355 // Per IPMI 2.0 spec, the input and output buffer size must be the max
356 // buffer size minus one byte to allocate space for the length byte.
357 uint8_t str[] = {0x01, MAX_IPMI_BUFFER-1, MAX_IPMI_BUFFER-1, 0x0A, 0x01};
vishwabmcba0bd5f2015-09-30 16:50:23 +0530358
359 // Data length
360 *data_len = sizeof(str);
361
362 // Pack the actual response
363 memcpy(response, &str, *data_len);
364
365 return rc;
366}
367
Chris Austen6caf28b2015-10-13 12:40:40 -0500368
369struct set_wd_data_t {
370 uint8_t t_use;
371 uint8_t t_action;
372 uint8_t preset;
373 uint8_t flags;
374 uint8_t ls;
375 uint8_t ms;
376} __attribute__ ((packed));
377
378
379
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500380ipmi_ret_t ipmi_app_set_watchdog(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
381 ipmi_request_t request, ipmi_response_t response,
Chris Austen6caf28b2015-10-13 12:40:40 -0500382 ipmi_data_len_t data_len, ipmi_context_t context)
383{
Vishwanatha Subbanna8fc09882017-06-12 19:57:37 +0530384 const char *objname = "/xyz/openbmc_project/watchdog/host0";
385 const char *iface = "xyz.openbmc_project.State.Watchdog";
386 const char *property_iface = "org.freedesktop.DBus.Properties";
vishwa1eaea4f2016-02-26 11:57:40 -0600387 sd_bus_message *reply = NULL;
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500388 sd_bus_error error = SD_BUS_ERROR_NULL;
389 int r = 0;
Chris Austen6caf28b2015-10-13 12:40:40 -0500390
391 set_wd_data_t *reqptr = (set_wd_data_t*) request;
392 uint16_t timer = 0;
Vishwanatha Subbanna8fc09882017-06-12 19:57:37 +0530393
394 // Making this uint64_t to match with provider
395 uint64_t timer_ms = 0;
Sergey Solomineb9b8142016-08-23 09:07:28 -0500396 char *busname = NULL;
Chris Austen6caf28b2015-10-13 12:40:40 -0500397 *data_len = 0;
398
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500399 // Get number of 100ms intervals
Chris Austen6caf28b2015-10-13 12:40:40 -0500400 timer = (((uint16_t)reqptr->ms) << 8) + reqptr->ls;
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500401 // Get timer value in ms
402 timer_ms = timer * 100;
Chris Austen6caf28b2015-10-13 12:40:40 -0500403
404 printf("WATCHDOG SET Timer:[0x%X] 100ms intervals\n",timer);
405
Sergey Solomineb9b8142016-08-23 09:07:28 -0500406 // Get bus name
407 r = mapper_get_service(bus, objname, &busname);
408 if (r < 0) {
Brad Bishop819ddd42016-10-05 21:19:19 -0400409 fprintf(stderr, "Failed to get %s bus name: %s\n",
410 objname, strerror(-r));
Sergey Solomineb9b8142016-08-23 09:07:28 -0500411 goto finish;
412 }
Adriana Kobylak0896be32015-10-22 13:27:23 -0500413
Vishwanatha Subbanna8fc09882017-06-12 19:57:37 +0530414 // Disable watchdog if running
415 r = sd_bus_call_method(bus, busname, objname, property_iface,
416 "Set", &error, &reply, "ssv",
417 iface, "Enabled", "b", false);
418 if(r < 0) {
419 fprintf(stderr, "Failed to disable Watchdog: %s\n",
420 strerror(-r));
vishwa1eaea4f2016-02-26 11:57:40 -0600421 goto finish;
422 }
423
Patrick Venture6c50ad92017-07-29 22:38:28 -0700424 /*
425 * If the action is 0, it means, do nothing. Multiple actions on timer
426 * expiration aren't supported by phosphor-watchdog yet, so when the
427 * action set is "none", we should just leave the timer disabled.
428 */
429 if (0 == reqptr->t_action)
430 {
431 goto finish;
432 }
433
vishwa1eaea4f2016-02-26 11:57:40 -0600434 if (reqptr->t_use & 0x40)
435 {
436 sd_bus_error_free(&error);
437 reply = sd_bus_message_unref(reply);
438
Patrick Venture00445242017-08-17 12:40:03 -0700439 // Set the Interval for the Watchdog
440 r = sd_bus_call_method(bus, busname, objname, property_iface,
441 "Set", &error, &reply, "ssv",
442 iface, "Interval", "t", timer_ms);
443 if(r < 0) {
444 fprintf(stderr, "Failed to set new expiration time: %s\n",
445 strerror(-r));
446 goto finish;
447 }
448
Vishwanatha Subbanna8fc09882017-06-12 19:57:37 +0530449 // Now Enable Watchdog
450 r = sd_bus_call_method(bus, busname, objname, property_iface,
451 "Set", &error, &reply, "ssv",
452 iface, "Enabled", "b", true);
453 if(r < 0) {
454 fprintf(stderr, "Failed to Enable Watchdog: %s\n",
455 strerror(-r));
456 goto finish;
457 }
vishwa1eaea4f2016-02-26 11:57:40 -0600458 }
459
460finish:
461 sd_bus_error_free(&error);
462 reply = sd_bus_message_unref(reply);
Sergey Solomineb9b8142016-08-23 09:07:28 -0500463 free(busname);
vishwa1eaea4f2016-02-26 11:57:40 -0600464
465 return (r < 0) ? -1 : IPMI_CC_OK;
Chris Austen6caf28b2015-10-13 12:40:40 -0500466}
467
468
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500469ipmi_ret_t ipmi_app_reset_watchdog(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
470 ipmi_request_t request, ipmi_response_t response,
Chris Austen6caf28b2015-10-13 12:40:40 -0500471 ipmi_data_len_t data_len, ipmi_context_t context)
472{
Vishwanatha Subbanna8fc09882017-06-12 19:57:37 +0530473 const char *objname = "/xyz/openbmc_project/watchdog/host0";
474 const char *iface = "xyz.openbmc_project.State.Watchdog";
475 const char *property_iface = "org.freedesktop.DBus.Properties";
vishwa1eaea4f2016-02-26 11:57:40 -0600476 sd_bus_message *reply = NULL;
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500477 sd_bus_error error = SD_BUS_ERROR_NULL;
478 int r = 0;
Sergey Solomineb9b8142016-08-23 09:07:28 -0500479 char *busname = NULL;
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500480
Vishwanatha Subbanna8fc09882017-06-12 19:57:37 +0530481 // Current time interval that is set in watchdog.
482 uint64_t interval = 0;
483
Chris Austen6caf28b2015-10-13 12:40:40 -0500484 // Status code.
485 ipmi_ret_t rc = IPMI_CC_OK;
486 *data_len = 0;
487
488 printf("WATCHDOG RESET\n");
Sergey Solomineb9b8142016-08-23 09:07:28 -0500489 // Get bus name
490 r = mapper_get_service(bus, objname, &busname);
491 if (r < 0) {
Brad Bishop819ddd42016-10-05 21:19:19 -0400492 fprintf(stderr, "Failed to get %s bus name: %s\n",
493 objname, strerror(-r));
Sergey Solomineb9b8142016-08-23 09:07:28 -0500494 goto finish;
495 }
Vishwanatha Subbanna8fc09882017-06-12 19:57:37 +0530496
497 // Get the current interval and set it back.
498 r = sd_bus_call_method(bus, busname, objname, property_iface,
499 "Get", &error, &reply, "ss",
500 iface, "Interval");
501
502 if(r < 0) {
503 fprintf(stderr, "Failed to get current Interval msg: %s\n",
504 strerror(-r));
505 goto finish;
506 }
507
508 // Now extract the value
509 r = sd_bus_message_read(reply, "v", "t", &interval);
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500510 if (r < 0) {
Vishwanatha Subbanna8fc09882017-06-12 19:57:37 +0530511 fprintf(stderr, "Failed to read current interval: %s\n",
512 strerror(-r));
513 goto finish;
514 }
515
516 sd_bus_error_free(&error);
517 reply = sd_bus_message_unref(reply);
518
519 // Set watchdog timer
520 r = sd_bus_call_method(bus, busname, objname, property_iface,
521 "Set", &error, &reply, "ssv",
522 iface, "TimeRemaining", "t", interval);
523 if(r < 0) {
524 fprintf(stderr, "Failed to refresh the timer: %s\n",
525 strerror(-r));
526 goto finish;
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500527 }
528
Sergey Solomineb9b8142016-08-23 09:07:28 -0500529finish:
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500530 sd_bus_error_free(&error);
vishwa1eaea4f2016-02-26 11:57:40 -0600531 reply = sd_bus_message_unref(reply);
Sergey Solomineb9b8142016-08-23 09:07:28 -0500532 free(busname);
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500533
Chris Austen6caf28b2015-10-13 12:40:40 -0500534 return rc;
535}
536
Ratan Guptab8e99552017-07-27 07:07:48 +0530537extern struct ChannelConfig_t channelConfig;
Nan Li3d0df912016-10-18 19:51:41 +0800538
Ratan Guptab8e99552017-07-27 07:07:48 +0530539ipmi_ret_t ipmi_set_channel_access(ipmi_netfn_t netfn,
540 ipmi_cmd_t cmd,
541 ipmi_request_t request,
542 ipmi_response_t response,
543 ipmi_data_len_t data_len,
544 ipmi_context_t context)
Nan Li3d0df912016-10-18 19:51:41 +0800545{
546 ipmi_ret_t rc = IPMI_CC_OK;
547
Ratan Guptab8e99552017-07-27 07:07:48 +0530548 std::string ipaddress;
549 std::string gateway;
550 uint8_t prefix {};
Ratan Gupta533d03b2017-07-30 10:39:22 +0530551 uint32_t vlanID {};
Ratan Gupta62736ec2017-09-02 12:02:47 +0530552 std::string networkInterfacePath;
553 ipmi::DbusObjectInfo ipObject;
554 ipmi::DbusObjectInfo systemObject;
Nan Li3d0df912016-10-18 19:51:41 +0800555
556 // Todo: parse the request data if needed.
Nan Li3d0df912016-10-18 19:51:41 +0800557 // Using Set Channel cmd to apply changes of Set Lan Cmd.
Ratan Guptab8e99552017-07-27 07:07:48 +0530558 try
559 {
Ratan Guptab8e99552017-07-27 07:07:48 +0530560 sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
561
562 log<level::INFO>("Network data from Cache",
563 entry("PREFIX=%s", channelConfig.netmask.c_str()),
564 entry("ADDRESS=%s", channelConfig.ipaddr.c_str()),
Ratan Gupta62736ec2017-09-02 12:02:47 +0530565 entry("GATEWAY=%s", channelConfig.gateway.c_str()),
566 entry("VLAN=%d", channelConfig.vlanID),
567 entry("IPSRC=%d", channelConfig.ipsrc));
Ratan Guptab8e99552017-07-27 07:07:48 +0530568
Ratan Gupta62736ec2017-09-02 12:02:47 +0530569 if (channelConfig.vlanID != ipmi::network::VLAN_ID_MASK)
Ratan Guptab8e99552017-07-27 07:07:48 +0530570 {
Ratan Gupta62736ec2017-09-02 12:02:47 +0530571 //get the first twelve bits which is vlan id
572 //not interested in rest of the bits.
573 channelConfig.vlanID = le32toh(channelConfig.vlanID);
574 vlanID = channelConfig.vlanID & ipmi::network::VLAN_ID_MASK;
Ratan Guptab8e99552017-07-27 07:07:48 +0530575 }
Ratan Gupta62736ec2017-09-02 12:02:47 +0530576
577 // if the asked ip src is DHCP then not interested in
578 // any given data except vlan.
579 if (channelConfig.ipsrc != ipmi::network::IPOrigin::DHCP)
Ratan Guptab8e99552017-07-27 07:07:48 +0530580 {
Ratan Gupta62736ec2017-09-02 12:02:47 +0530581 // always get the system object
582 systemObject = ipmi::getDbusObject(
583 bus,
584 ipmi::network::SYSTEMCONFIG_INTERFACE,
585 ipmi::network::ROOT);
Ratan Gupta533d03b2017-07-30 10:39:22 +0530586
Ratan Gupta62736ec2017-09-02 12:02:47 +0530587 // the below code is to determine the mode of the interface
588 // as the handling is same, if the system is configured with
589 // DHCP or user has given all the data.
Ratan Guptab8e99552017-07-27 07:07:48 +0530590 try
591 {
Ratan Gupta62736ec2017-09-02 12:02:47 +0530592 ipmi::ObjectTree ancestorMap;
593
594 ipmi::InterfaceList interfaces {
595 ipmi::network::ETHERNET_INTERFACE };
596
597 // if the system is having ip object,then
598 // get the IP object.
599 ipObject = ipmi::getDbusObject(bus,
600 ipmi::network::IP_INTERFACE,
601 ipmi::network::ROOT,
602 ipmi::network::IP_TYPE);
603
604 // Get the parent interface of the IP object.
605 try
606 {
607 ancestorMap = ipmi::getAllAncestors(bus,
608 ipObject.first,
609 std::move(interfaces));
610 }
611 catch (InternalFailure& e)
612 {
613 // if unable to get the parent interface
614 // then commit the error and return.
615 log<level::ERR>("Unable to get the parent interface",
616 entry("PATH=%s", ipObject.first.c_str()),
617 entry("INTERFACE=%s",
618 ipmi::network::ETHERNET_INTERFACE));
619 commit<InternalFailure>();
620 rc = IPMI_CC_UNSPECIFIED_ERROR;
621 channelConfig.clear();
622 return rc;
623 }
624
625 networkInterfacePath = ancestorMap.begin()->first;
626 }
627 catch (InternalFailure& e)
628 {
629 // TODO Currently IPMI supports single interface,need to handle
630 // Multiple interface through
631 // https://github.com/openbmc/openbmc/issues/2138
632
633 // if there is no ip configured on the system,then
634 // get the network interface object.
635 auto networkInterfaceObject = ipmi::getDbusObject(
636 bus,
637 ipmi::network::ETHERNET_INTERFACE,
Ratan Guptab8e99552017-07-27 07:07:48 +0530638 ipmi::network::ROOT,
Ratan Gupta62736ec2017-09-02 12:02:47 +0530639 ipmi::network::INTERFACE);
Ratan Guptab8e99552017-07-27 07:07:48 +0530640
Ratan Gupta62736ec2017-09-02 12:02:47 +0530641 networkInterfacePath = std::move(networkInterfaceObject.first);
642 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530643
Ratan Gupta62736ec2017-09-02 12:02:47 +0530644 // get the configured mode on the system.
645 auto enableDHCP = ipmi::getDbusProperty(
646 bus,
647 ipmi::network::SERVICE,
648 networkInterfacePath,
649 ipmi::network::ETHERNET_INTERFACE,
650 "DHCPEnabled").get<bool>();
Ratan Guptab8e99552017-07-27 07:07:48 +0530651
Ratan Gupta62736ec2017-09-02 12:02:47 +0530652 // check whether user has given all the data
653 // or the configured system interface is dhcp enabled,
654 // in both of the cases get the values from the cache.
655 if ((!channelConfig.ipaddr.empty() &&
656 !channelConfig.netmask.empty() &&
657 !channelConfig.gateway.empty()) ||
658 (enableDHCP)) // configured system interface mode = DHCP
659 {
660 //convert mask into prefix
661 ipaddress = channelConfig.ipaddr;
662 prefix = ipmi::network::toPrefix(AF_INET, channelConfig.netmask);
663 gateway = channelConfig.gateway;
Ratan Gupta533d03b2017-07-30 10:39:22 +0530664 if (channelConfig.vlanID != ipmi::network::VLAN_ID_MASK)
665 {
666 //get the first twelve bits which is vlan id
667 //not interested in rest of the bits.
Ratan Gupta533d03b2017-07-30 10:39:22 +0530668 channelConfig.vlanID = le32toh(channelConfig.vlanID);
Ratan Gupta62736ec2017-09-02 12:02:47 +0530669 vlanID = channelConfig.vlanID & ipmi::network::VLAN_ID_MASK;
Ratan Gupta533d03b2017-07-30 10:39:22 +0530670 }
671 else
672 {
Ratan Gupta62736ec2017-09-02 12:02:47 +0530673 vlanID = ipmi::network::getVLAN(networkInterfacePath);
Ratan Gupta533d03b2017-07-30 10:39:22 +0530674 }
675
Ratan Guptab8e99552017-07-27 07:07:48 +0530676 }
Ratan Gupta62736ec2017-09-02 12:02:47 +0530677 else // asked ip src = static and configured system src = static
678 // or partially given data.
Ratan Guptab8e99552017-07-27 07:07:48 +0530679 {
Ratan Gupta62736ec2017-09-02 12:02:47 +0530680 // We have partial filled cache so get the remaining
681 // info from the system.
682
683 // Get the network data from the system as user has
684 // not given all the data then use the data fetched from the
685 // system but it is implementation dependent,IPMI spec doesn't
686 // force it.
687
688 // if system is not having any ip object don't throw error,
689 try
690 {
691 auto properties = ipmi::getAllDbusProperties(
692 bus,
693 ipObject.second,
694 ipObject.first,
695 ipmi::network::IP_INTERFACE);
696
697 ipaddress = channelConfig.ipaddr.empty() ?
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500698 ipmi::getIPAddress(bus,
699 ipmi::network::IP_INTERFACE,
700 ipmi::network::ROOT,
701 ipmi::network::IP_TYPE) :
702 channelConfig.ipaddr;
Ratan Gupta62736ec2017-09-02 12:02:47 +0530703
704 prefix = channelConfig.netmask.empty() ?
705 properties["PrefixLength"].get<uint8_t>() :
706 ipmi::network::toPrefix(AF_INET,
707 channelConfig.netmask);
708
709 }
710 catch (InternalFailure& e)
711 {
712 log<level::INFO>("Failed to get IP object which matches",
713 entry("INTERFACE=%s", ipmi::network::IP_INTERFACE),
714 entry("MATCH=%s", ipmi::network::IP_TYPE));
715 }
716
717 auto systemProperties = ipmi::getAllDbusProperties(
718 bus,
719 systemObject.second,
720 systemObject.first,
721 ipmi::network::SYSTEMCONFIG_INTERFACE);
722
723 gateway = channelConfig.gateway.empty() ?
724 systemProperties["DefaultGateway"].get<std::string>() :
725 channelConfig.gateway;
726
Ratan Guptab8e99552017-07-27 07:07:48 +0530727 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530728 }
729
730 // Currently network manager doesn't support purging of all the
Ratan Gupta533d03b2017-07-30 10:39:22 +0530731 // ip addresses and the vlan interfaces from the parent interface,
Ratan Guptab8e99552017-07-27 07:07:48 +0530732 // TODO once the support is there, will make the change here.
733 // https://github.com/openbmc/openbmc/issues/2141.
734
735 // TODO Currently IPMI supports single interface,need to handle
736 // Multiple interface through
737 // https://github.com/openbmc/openbmc/issues/2138
738
Ratan Gupta62736ec2017-09-02 12:02:47 +0530739 // instead of deleting all the vlan interfaces and
740 // all the ipv4 address,we will call reset method.
Ratan Gupta533d03b2017-07-30 10:39:22 +0530741 //delete all the vlan interfaces
Ratan Gupta62736ec2017-09-02 12:02:47 +0530742
743 ipmi::deleteAllDbusObjects(bus,
744 ipmi::network::ROOT,
Ratan Gupta533d03b2017-07-30 10:39:22 +0530745 ipmi::network::VLAN_INTERFACE);
Ratan Gupta62736ec2017-09-02 12:02:47 +0530746
747 // set the interface mode to static
748 auto networkInterfaceObject = ipmi::getDbusObject(
749 bus,
750 ipmi::network::ETHERNET_INTERFACE,
751 ipmi::network::ROOT,
752 ipmi::network::INTERFACE);
753
754 // setting the physical interface mode to static.
755 ipmi::setDbusProperty(bus,
756 ipmi::network::SERVICE,
757 networkInterfaceObject.first,
758 ipmi::network::ETHERNET_INTERFACE,
759 "DHCPEnabled",
760 false);
761
762 networkInterfacePath = networkInterfaceObject.first;
763
764 //delete all the ipv4 addresses
765 ipmi::deleteAllDbusObjects(bus,
766 ipmi::network::ROOT,
Ratan Guptab8e99552017-07-27 07:07:48 +0530767 ipmi::network::IP_INTERFACE,
768 ipmi::network::IP_TYPE);
Ratan Gupta62736ec2017-09-02 12:02:47 +0530769
Ratan Gupta533d03b2017-07-30 10:39:22 +0530770 if (vlanID)
771 {
Ratan Gupta62736ec2017-09-02 12:02:47 +0530772 ipmi::network::createVLAN(bus,
773 ipmi::network::SERVICE,
Ratan Gupta533d03b2017-07-30 10:39:22 +0530774 ipmi::network::ROOT,
Ratan Gupta62736ec2017-09-02 12:02:47 +0530775 ipmi::network::INTERFACE,
776 vlanID);
Ratan Gupta533d03b2017-07-30 10:39:22 +0530777
Ratan Gupta62736ec2017-09-02 12:02:47 +0530778 auto networkInterfaceObject = ipmi::getDbusObject(
Ratan Gupta533d03b2017-07-30 10:39:22 +0530779 bus,
780 ipmi::network::VLAN_INTERFACE,
781 ipmi::network::ROOT);
Ratan Gupta62736ec2017-09-02 12:02:47 +0530782
783 networkInterfacePath = networkInterfaceObject.first;
Ratan Gupta533d03b2017-07-30 10:39:22 +0530784 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530785
Ratan Gupta62736ec2017-09-02 12:02:47 +0530786 if (channelConfig.ipsrc == ipmi::network::IPOrigin::DHCP)
787 {
788 ipmi::setDbusProperty(bus,
789 ipmi::network::SERVICE,
790 networkInterfacePath,
791 ipmi::network::ETHERNET_INTERFACE,
792 "DHCPEnabled",
793 true);
794 }
795 else
796 {
797 //change the mode to static
798 ipmi::setDbusProperty(bus,
799 ipmi::network::SERVICE,
800 networkInterfacePath,
801 ipmi::network::ETHERNET_INTERFACE,
802 "DHCPEnabled",
803 false);
Ratan Guptab8e99552017-07-27 07:07:48 +0530804
Ratan Gupta62736ec2017-09-02 12:02:47 +0530805 if (!ipaddress.empty())
806 {
807 ipmi::network::createIP(bus,
808 ipmi::network::SERVICE,
809 networkInterfacePath,
810 ipv4Protocol,
811 ipaddress,
812 prefix);
813 }
814
815 if (!gateway.empty())
816 {
817 ipmi::setDbusProperty(bus,
818 systemObject.second,
819 systemObject.first,
820 ipmi::network::SYSTEMCONFIG_INTERFACE,
821 "DefaultGateway",
822 std::string(gateway));
823 }
824 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530825
Nan Li3d0df912016-10-18 19:51:41 +0800826 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530827 catch (InternalFailure& e)
828 {
829 log<level::ERR>("Failed to set network data",
830 entry("PREFIX=%d", prefix),
Ratan Gupta62736ec2017-09-02 12:02:47 +0530831 entry("ADDRESS=%s", ipaddress.c_str()),
832 entry("GATEWAY=%s", gateway.c_str()),
833 entry("VLANID=%d", vlanID),
834 entry("IPSRC=%d", channelConfig.ipsrc));
Nan Li3d0df912016-10-18 19:51:41 +0800835
Ratan Guptab8e99552017-07-27 07:07:48 +0530836 commit<InternalFailure>();
Nan Li3d0df912016-10-18 19:51:41 +0800837 rc = IPMI_CC_UNSPECIFIED_ERROR;
838 }
839
Ratan Guptab8e99552017-07-27 07:07:48 +0530840 channelConfig.clear();
Nan Li3d0df912016-10-18 19:51:41 +0800841 return rc;
842}
843
Tom Joseph69fabfe2017-08-04 10:15:01 +0530844ipmi_ret_t getChannelAccess(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
845 ipmi_request_t request, ipmi_response_t response,
846 ipmi_data_len_t data_len, ipmi_context_t context)
847{
848 auto requestData = reinterpret_cast<const GetChannelAccessRequest*>
849 (request);
850 std::vector<uint8_t> outPayload(sizeof(GetChannelAccessResponse));
851 auto responseData = reinterpret_cast<GetChannelAccessResponse*>
852 (outPayload.data());
853
854 // Channel 1 is arbitrarily assigned to ETH0 channel
855 constexpr auto channelOne = 0x01;
856
857 /*
858 * The value Eh is used as a way to identify the current channel that
859 * the command is being received from.
860 */
861 constexpr auto channelE = 0x0E;
862
863 if (requestData->channelNumber != channelOne &&
864 requestData->channelNumber != channelE)
865 {
866 *data_len = 0;
867 return IPMI_CC_INVALID_FIELD_REQUEST;
868 }
869
870 /*
871 * [7:6] - reserved
872 * [5] - 1b = Alerting disabled
873 * [4] - 1b = per message authentication disabled
874 * [3] - 0b = User level authentication enabled
875 * [2:0] - 2h = always available
876 */
877 constexpr auto channelSetting = 0x32;
878
879 responseData->settings = channelSetting;
880 //Defaulting the channel privilege to administrator level.
881 responseData->privilegeLimit = PRIVILEGE_ADMIN;
882
883 *data_len = outPayload.size();
884 memcpy(response, outPayload.data(), *data_len);
885
886 return IPMI_CC_OK;
887}
Ratan Gupta533d03b2017-07-30 10:39:22 +0530888
Chris Austenc2cd29d2016-02-05 20:02:29 -0600889// ATTENTION: This ipmi function is very hardcoded on purpose
890// OpenBMC does not fully support IPMI. This command is useful
891// to have around because it enables testing of interfaces with
892// the IPMI tool.
893#define GET_CHANNEL_INFO_CHANNEL_OFFSET 0
894// IPMI Table 6-2
895#define IPMI_CHANNEL_TYPE_IPMB 1
896// IPMI Table 6-3
897#define IPMI_CHANNEL_MEDIUM_TYPE_OTHER 6
898
899ipmi_ret_t ipmi_app_channel_info(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
900 ipmi_request_t request, ipmi_response_t response,
901 ipmi_data_len_t data_len, ipmi_context_t context)
902{
903 ipmi_ret_t rc = IPMI_CC_OK;
904 uint8_t resp[] = {
905 1,
906 IPMI_CHANNEL_MEDIUM_TYPE_OTHER,
907 IPMI_CHANNEL_TYPE_IPMB,
908 1,0x41,0xA7,0x00,0,0};
909 uint8_t *p = (uint8_t*) request;
910
911 printf("IPMI APP GET CHANNEL INFO\n");
912
tomjose7ec0add2016-06-27 07:59:28 -0500913 // The supported channels numbers are 1 and 8.
914 // Channel Number E is used as way to identify the current channel
915 // that the command is being is received from.
tomjose13fb4412016-03-08 14:02:34 -0600916 if (*p == 0xe || *p == 1 || *p == 8) {
Chris Austenc2cd29d2016-02-05 20:02:29 -0600917
918 *data_len = sizeof(resp);
919 memcpy(response, resp, *data_len);
920
921 } else {
922 rc = IPMI_CC_PARM_OUT_OF_RANGE;
923 *data_len = 0;
924 }
925
926 return rc;
927}
928
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500929ipmi_ret_t ipmi_app_wildcard_handler(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
930 ipmi_request_t request, ipmi_response_t response,
vishwabmcba0bd5f2015-09-30 16:50:23 +0530931 ipmi_data_len_t data_len, ipmi_context_t context)
932{
933 printf("Handling WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
934
935 // Status code.
Nan Li70aa8d92016-08-29 00:11:10 +0800936 ipmi_ret_t rc = IPMI_CC_INVALID;
vishwabmcba0bd5f2015-09-30 16:50:23 +0530937
938 *data_len = strlen("THIS IS WILDCARD");
939
940 // Now pack actual response
941 memcpy(response, "THIS IS WILDCARD", *data_len);
942
943 return rc;
944}
945
Chris Austen6caf28b2015-10-13 12:40:40 -0500946void register_netfn_app_functions()
vishwabmcba0bd5f2015-09-30 16:50:23 +0530947{
Tom05732372016-09-06 17:21:23 +0530948 // <Get BT Interface Capabilities>
vishwabmcba0bd5f2015-09-30 16:50:23 +0530949 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_CAP_BIT);
Tom05732372016-09-06 17:21:23 +0530950 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CAP_BIT, NULL, ipmi_app_get_bt_capabilities,
951 PRIVILEGE_USER);
Chris Austen6caf28b2015-10-13 12:40:40 -0500952
Tom05732372016-09-06 17:21:23 +0530953 // <Wildcard Command>
Chris Austen6caf28b2015-10-13 12:40:40 -0500954 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_WILDCARD);
Tom05732372016-09-06 17:21:23 +0530955 ipmi_register_callback(NETFUN_APP, IPMI_CMD_WILDCARD, NULL, ipmi_app_wildcard_handler,
956 PRIVILEGE_USER);
Chris Austen6caf28b2015-10-13 12:40:40 -0500957
Tom05732372016-09-06 17:21:23 +0530958 // <Reset Watchdog Timer>
Chris Austen6caf28b2015-10-13 12:40:40 -0500959 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_RESET_WD);
Tom05732372016-09-06 17:21:23 +0530960 ipmi_register_callback(NETFUN_APP, IPMI_CMD_RESET_WD, NULL, ipmi_app_reset_watchdog,
961 PRIVILEGE_OPERATOR);
Chris Austen6caf28b2015-10-13 12:40:40 -0500962
Tom05732372016-09-06 17:21:23 +0530963 // <Set Watchdog Timer>
Chris Austen6caf28b2015-10-13 12:40:40 -0500964 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_SET_WD);
Tom05732372016-09-06 17:21:23 +0530965 ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_WD, NULL, ipmi_app_set_watchdog,
966 PRIVILEGE_OPERATOR);
Chris Austen6caf28b2015-10-13 12:40:40 -0500967
Tom05732372016-09-06 17:21:23 +0530968 // <Get Device ID>
Chris Austen6caf28b2015-10-13 12:40:40 -0500969 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_DEVICE_ID);
Tom05732372016-09-06 17:21:23 +0530970 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_DEVICE_ID, NULL, ipmi_app_get_device_id,
971 PRIVILEGE_USER);
Chris Austen6caf28b2015-10-13 12:40:40 -0500972
Tom05732372016-09-06 17:21:23 +0530973 // <Get Self Test Results>
Nan Li41fa24a2016-11-10 20:12:37 +0800974 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_SELF_TEST_RESULTS);
Tom05732372016-09-06 17:21:23 +0530975 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_SELF_TEST_RESULTS, NULL,
976 ipmi_app_get_self_test_results, PRIVILEGE_USER);
Nan Li41fa24a2016-11-10 20:12:37 +0800977
Tom05732372016-09-06 17:21:23 +0530978 // <Get Device GUID>
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500979 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_DEVICE_GUID);
Tom05732372016-09-06 17:21:23 +0530980 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_DEVICE_GUID, NULL, ipmi_app_get_device_guid,
981 PRIVILEGE_USER);
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500982
Tom05732372016-09-06 17:21:23 +0530983 // <Set ACPI Power State>
Chris Austen6caf28b2015-10-13 12:40:40 -0500984 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_SET_ACPI);
Tom05732372016-09-06 17:21:23 +0530985 ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_ACPI, NULL, ipmi_app_set_acpi_power_state,
986 PRIVILEGE_ADMIN);
Chris Austen6caf28b2015-10-13 12:40:40 -0500987
Tom05732372016-09-06 17:21:23 +0530988 // <Set Channel Access>
Nan Li3d0df912016-10-18 19:51:41 +0800989 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP,
990 IPMI_CMD_SET_CHAN_ACCESS);
991 ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_CHAN_ACCESS, NULL,
Tom05732372016-09-06 17:21:23 +0530992 ipmi_set_channel_access, PRIVILEGE_ADMIN);
Chris Austenc2cd29d2016-02-05 20:02:29 -0600993
Tom Joseph69fabfe2017-08-04 10:15:01 +0530994 // <Get Channel Access>
995 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_CHANNEL_ACCESS);
996 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHANNEL_ACCESS, NULL,
997 getChannelAccess, PRIVILEGE_USER);
998
Tom05732372016-09-06 17:21:23 +0530999 // <Get Channel Info Command>
Chris Austenc2cd29d2016-02-05 20:02:29 -06001000 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_CHAN_INFO);
Tom05732372016-09-06 17:21:23 +05301001 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHAN_INFO, NULL, ipmi_app_channel_info,
1002 PRIVILEGE_USER);
Chris Austenc2cd29d2016-02-05 20:02:29 -06001003
vishwabmcba0bd5f2015-09-30 16:50:23 +05301004 return;
1005}
1006
Chris Austen6caf28b2015-10-13 12:40:40 -05001007