blob: d5ebe2e3621f8a10b06b7a532deb60c7f2d9b1e5 [file] [log] [blame]
vishwabmcba0bd5f2015-09-30 16:50:23 +05301#include "apphandler.h"
2#include "ipmid-api.h"
Chris Austen6caf28b2015-10-13 12:40:40 -05003#include "ipmid.H"
vishwabmcba0bd5f2015-09-30 16:50:23 +05304#include <stdio.h>
5#include <string.h>
Chris Austen6caf28b2015-10-13 12:40:40 -05006#include <stdint.h>
Adriana Kobylak3a552e12015-10-19 16:11:00 -05007#include <systemd/sd-bus.h>
Nan Liee0cb902016-07-11 15:38:03 +08008#include <array>
Adriana Kobylak3a552e12015-10-19 16:11:00 -05009
10extern sd_bus *bus;
vishwabmcba0bd5f2015-09-30 16:50:23 +053011
Chris Austen6caf28b2015-10-13 12:40:40 -050012void register_netfn_app_functions() __attribute__((constructor));
vishwabmcba0bd5f2015-09-30 16:50:23 +053013
Nan Liee0cb902016-07-11 15:38:03 +080014// Offset in get device id command.
15typedef struct
16{
17 uint8_t id;
18 uint8_t revision;
19 uint8_t fw[2];
20 uint8_t ipmi_ver;
21 uint8_t addn_dev_support;
22 uint8_t manuf_id[3];
23 uint8_t prod_id[2];
24 uint8_t aux[4];
25}__attribute__((packed)) ipmi_device_id_t;
Chris Austen7303bdc2016-04-17 11:50:54 -050026
vishwa36993272015-11-20 12:43:49 -060027//---------------------------------------------------------------------
28// Called by Host on seeing a SMS_ATN bit set. Return a hardcoded
29// value of 0x2 indicating we need Host read some data.
30//-------------------------------------------------------------------
31ipmi_ret_t ipmi_app_get_msg_flags(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
32 ipmi_request_t request, ipmi_response_t response,
33 ipmi_data_len_t data_len, ipmi_context_t context)
34{
35 // Generic return from IPMI commands.
36 ipmi_ret_t rc = IPMI_CC_OK;
Chris Austen6caf28b2015-10-13 12:40:40 -050037
vishwa36993272015-11-20 12:43:49 -060038 printf("IPMI APP GET MSG FLAGS returning with [bit:2] set\n");
39
40 // From IPMI spec V2.0 for Get Message Flags Command :
41 // bit:[1] from LSB : 1b = Event Message Buffer Full.
42 // Return as 0 if Event Message Buffer is not supported,
43 // or when the Event Message buffer is disabled.
44 // TODO. For now. assume its not disabled and send "0x2" anyway:
45
46 uint8_t set_event_msg_buffer_full = 0x2;
47 *data_len = sizeof(set_event_msg_buffer_full);
48
49 // Pack the actual response
50 memcpy(response, &set_event_msg_buffer_full, *data_len);
51
52 return rc;
53}
54
55//-------------------------------------------------------------------
56// Called by Host post response from Get_Message_Flags
57//-------------------------------------------------------------------
Adriana Kobylak3a552e12015-10-19 16:11:00 -050058ipmi_ret_t ipmi_app_read_event(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
59 ipmi_request_t request, ipmi_response_t response,
Chris Austen6caf28b2015-10-13 12:40:40 -050060 ipmi_data_len_t data_len, ipmi_context_t context)
61{
62 ipmi_ret_t rc = IPMI_CC_OK;
vishwa36993272015-11-20 12:43:49 -060063 printf("IPMI APP READ EVENT command received\n");
Chris Austen6caf28b2015-10-13 12:40:40 -050064
vishwa36993272015-11-20 12:43:49 -060065 // TODO : For now, this is catering only to the Soft Power Off via OEM SEL
66 // mechanism. If we need to make this generically used for some
67 // other conditions, then we can take advantage of context pointer.
68
69 struct oem_sel_timestamped soft_off = {0};
70 *data_len = sizeof(struct oem_sel_timestamped);
71
72 // either id[0] -or- id[1] can be filled in. We will use id[0]
73 soft_off.id[0] = SEL_OEM_ID_0;
74 soft_off.id[1] = SEL_OEM_ID_0;
75 soft_off.type = SEL_RECORD_TYPE_OEM;
76
77 // Following 3 bytes are from IANA Manufactre_Id field. See below
78 soft_off.manuf_id[0]= 0x41;
79 soft_off.manuf_id[1]= 0xA7;
80 soft_off.manuf_id[2]= 0x00;
81
82 // per IPMI spec NetFuntion for OEM
83 soft_off.netfun = 0x3A;
84
85 // Mechanism to kick start soft shutdown.
86 soft_off.cmd = CMD_POWER;
87 soft_off.data[0] = SOFT_OFF;
88
89 // All '0xFF' since unused.
90 memset(&soft_off.data[1], 0xFF, 3);
91
92 // Pack the actual response
93 memcpy(response, &soft_off, *data_len);
Chris Austen6caf28b2015-10-13 12:40:40 -050094 return rc;
Chris Austen6caf28b2015-10-13 12:40:40 -050095}
96
Adriana Kobylak3a552e12015-10-19 16:11:00 -050097ipmi_ret_t ipmi_app_set_acpi_power_state(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
98 ipmi_request_t request, ipmi_response_t response,
Chris Austen6caf28b2015-10-13 12:40:40 -050099 ipmi_data_len_t data_len, ipmi_context_t context)
100{
101 ipmi_ret_t rc = IPMI_CC_OK;
102 *data_len = 0;
103
104 printf("IPMI SET ACPI STATE Ignoring for now\n");
105 return rc;
106}
107
Chris Austen7303bdc2016-04-17 11:50:54 -0500108
109typedef struct
110{
111 char major;
112 char minor;
Chris Austen176c9652016-04-30 16:32:17 -0500113 uint16_t d[2];
Chris Austen7303bdc2016-04-17 11:50:54 -0500114} rev_t;
115
116
117/* Currently only supports the vx.x-x-[-x] format Will return -1 if not in */
118/* the format this routine knows how to parse */
119/* version = v0.6-19-gf363f61-dirty */
120/* ^ ^ ^^ ^ */
121/* | | |----------|-- additional details */
122/* | |---------------- Minor */
123/* |------------------ Major */
124/* Additional details : If the option group exists it will force Auxiliary */
125/* Firmware Revision Information 4th byte to 1 indicating the build was */
126/* derived with additional edits */
127int convert_version(const char *p, rev_t *rev)
128{
129 char *s, *token;
130 char hexbyte[5];
131 int l;
Chris Austen176c9652016-04-30 16:32:17 -0500132 uint16_t commits;
Chris Austen7303bdc2016-04-17 11:50:54 -0500133
134 if (*p != 'v')
135 return -1;
136 p++;
137
138 s = strdup(p);
139 token = strtok(s,".-");
140
141 rev->major = (int8_t) atoi(token);
142
143 token = strtok(NULL, ".-");
144 rev->minor = (int8_t) atoi(token);
145
146 // Capture the number of commits on top of the minor tag.
147 // I'm using BE format like the ipmi spec asked for
148 token = strtok(NULL,".-");
Chris Austen7303bdc2016-04-17 11:50:54 -0500149
Chris Austen176c9652016-04-30 16:32:17 -0500150 if (token) {
151 commits = (int16_t) atoi(token);
152 rev->d[0] = (commits>>8) | (commits<<8);
Chris Austen7303bdc2016-04-17 11:50:54 -0500153
Chris Austen176c9652016-04-30 16:32:17 -0500154 // commit number we skip
155 token = strtok(NULL,".-");
Chris Austen7303bdc2016-04-17 11:50:54 -0500156
Chris Austen176c9652016-04-30 16:32:17 -0500157 } else {
158 rev->d[0] = 0;
159 }
Chris Austen7303bdc2016-04-17 11:50:54 -0500160
161 // Any value of the optional parameter forces it to 1
Chris Austen176c9652016-04-30 16:32:17 -0500162 if (token)
163 token = strtok(NULL,".-");
164
165 rev->d[1] = (token != NULL) ? 1 : 0;
Chris Austen7303bdc2016-04-17 11:50:54 -0500166
167 free(s);
168 return 0;
169}
170
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500171ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
172 ipmi_request_t request, ipmi_response_t response,
Chris Austen6caf28b2015-10-13 12:40:40 -0500173 ipmi_data_len_t data_len, ipmi_context_t context)
174{
175 ipmi_ret_t rc = IPMI_CC_OK;
Chris Austen7303bdc2016-04-17 11:50:54 -0500176 const char *busname = "org.openbmc.Inventory";
177 const char *objname = "/org/openbmc/inventory/system/chassis/motherboard/bmc";
178 const char *iface = "org.openbmc.InventoryItem";
179 char *ver = NULL;
180 int r;
181 rev_t rev = {0};
Nan Liee0cb902016-07-11 15:38:03 +0800182 ipmi_device_id_t dev_id{};
Chris Austen6caf28b2015-10-13 12:40:40 -0500183
184 // Data length
Chris Austen7303bdc2016-04-17 11:50:54 -0500185 *data_len = sizeof(dev_id);
186
Nan Liee0cb902016-07-11 15:38:03 +0800187 // From IPMI spec, controller that have different application commands, or different
188 // definitions of OEM fields, are expected to have different Device ID values.
189 // Set to 0 now.
190
191 // Device Revision is set to 0 now.
192 // Bit7 identifies if device provide Device SDRs, obmc don't have SDR,we use ipmi to
193 // simulate SDR, hence the value:
194 dev_id.revision = 0x80;
195
196 // Firmware revision is already implemented, so get it from appropriate position.
Chris Austen7303bdc2016-04-17 11:50:54 -0500197 r = sd_bus_get_property_string(bus,busname,objname,iface,"version", NULL, &ver);
198 if ( r < 0 ) {
199 fprintf(stderr, "Failed to obtain version property: %s\n", strerror(-r));
200 } else {
201 r = convert_version(ver, &rev);
202 if( r >= 0 ) {
Nan Liee0cb902016-07-11 15:38:03 +0800203 // bit7 identifies if the device is available, 0=normal operation,
204 // 1=device firmware, SDR update or self-initialization in progress.
205 // our SDR is normal working condition, so mask:
206 dev_id.fw[0] = 0x7F & rev.major;
Adriana Kobylak0e912642016-06-22 16:54:39 -0500207
208 rev.minor = (rev.minor > 99 ? 99 : rev.minor);
Nan Liee0cb902016-07-11 15:38:03 +0800209 dev_id.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16;
210 memcpy(&dev_id.aux, rev.d, 4);
Chris Austen7303bdc2016-04-17 11:50:54 -0500211 }
212 }
Chris Austen6caf28b2015-10-13 12:40:40 -0500213
Nan Liee0cb902016-07-11 15:38:03 +0800214 // IPMI Spec verison 2.0
215 dev_id.ipmi_ver = 2;
216
217 // Additional device Support.
218 // List the 'logical device' commands and functions that the controller supports
219 // that are in addition to the mandatory IPM and Application commands.
220 // [7] Chassis Device (device functions as chassis device per ICMB spec.)
221 // [6] Bridge (device responds to Bridge NetFn commands)
222 // [5] IPMB Event Generator
223 // [4] IPMB Event Receiver
224 // [3] FRU Inventory Device
225 // [2] SEL Device
226 // [1] SDR Repository Device
227 // [0] Sensor Device
228 // We support FRU/SEL/Sensor now:
229 dev_id.addn_dev_support = 0x8D;
230
231 // This value is the IANA number assigned to "IBM Platform Firmware
232 // Division", which is also used by our service processor. We may want
233 // a different number or at least a different version?
234 dev_id.manuf_id[0] = 0x41;
235 dev_id.manuf_id[1] = 0xA7;
236 dev_id.manuf_id[2] = 0x00;
237
238 // Witherspoon's product ID is hardcoded to 4F42(ASCII 'OB').
239 // TODO: openbmc/openbmc#495
240 dev_id.prod_id[0] = 0x4F;
241 dev_id.prod_id[1] = 0x42;
242
Chris Austen6caf28b2015-10-13 12:40:40 -0500243 // Pack the actual response
Chris Austen7303bdc2016-04-17 11:50:54 -0500244 memcpy(response, &dev_id, *data_len);
Chris Austen6caf28b2015-10-13 12:40:40 -0500245 return rc;
246}
247
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500248ipmi_ret_t ipmi_app_get_device_guid(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
249 ipmi_request_t request, ipmi_response_t response,
250 ipmi_data_len_t data_len, ipmi_context_t context)
251{
252 const char *busname = "org.openbmc.control.Chassis";
253 const char *objname = "/org/openbmc/control/chassis0";
Adriana Kobylak31bccae2015-11-05 13:31:06 -0600254 const char *iface = "org.freedesktop.DBus.Properties";
255 const char *chassis_iface = "org.openbmc.control.Chassis";
vishwa1eaea4f2016-02-26 11:57:40 -0600256 sd_bus_message *reply = NULL;
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500257 sd_bus_error error = SD_BUS_ERROR_NULL;
258 int r = 0;
259 char *uuid = NULL;
260
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500261 // UUID is in RFC4122 format. Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
262 // Per IPMI Spec 2.0 need to convert to 16 hex bytes and reverse the byte order
263 // Ex: 0x2332fc2c40e66298e511f2782395a361
264
265 const int resp_size = 16; // Response is 16 hex bytes per IPMI Spec
266 uint8_t resp_uuid[resp_size]; // Array to hold the formatted response
267 int resp_loc = resp_size-1; // Point resp end of array to save in reverse order
268 int i = 0;
269 char *tokptr = NULL;
vishwa1eaea4f2016-02-26 11:57:40 -0600270 char *id_octet = NULL;
271
272 // Status code.
273 ipmi_ret_t rc = IPMI_CC_OK;
274 *data_len = 0;
275
276 printf("IPMI GET DEVICE GUID\n");
277
278 // Call Get properties method with the interface and property name
279 r = sd_bus_call_method(bus,busname,objname,iface,
280 "Get",&error, &reply, "ss",
281 chassis_iface, "uuid");
282 if (r < 0)
283 {
284 fprintf(stderr, "Failed to call Get Method: %s\n", strerror(-r));
285 rc = IPMI_CC_UNSPECIFIED_ERROR;
286 goto finish;
287 }
288
289 r = sd_bus_message_read(reply, "v", "s", &uuid);
290 if (r < 0 || uuid == NULL)
291 {
292 fprintf(stderr, "Failed to get a response: %s", strerror(-r));
293 rc = IPMI_CC_RESPONSE_ERROR;
294 goto finish;
295 }
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500296
297 // Traverse the UUID
vishwa1eaea4f2016-02-26 11:57:40 -0600298 id_octet = strtok_r(uuid, "-", &tokptr); // Get the UUID octects separated by dash
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500299
300 if (id_octet == NULL)
vishwa1eaea4f2016-02-26 11:57:40 -0600301 {
302 // Error
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500303 fprintf(stderr, "Unexpected UUID format: %s", uuid);
vishwa1eaea4f2016-02-26 11:57:40 -0600304 rc = IPMI_CC_RESPONSE_ERROR;
305 goto finish;
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500306 }
307
308 while (id_octet != NULL)
309 {
310 // Calculate the octet string size since it varies
311 // Divide it by 2 for the array size since 1 byte is built from 2 chars
312 int tmp_size = strlen(id_octet)/2;
313
314 for(i = 0; i < tmp_size; i++)
315 {
Joel Stanley38310cd2015-11-25 17:32:08 +1030316 char tmp_array[3] = {0}; // Holder of the 2 chars that will become a byte
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500317 strncpy(tmp_array, id_octet, 2); // 2 chars at a time
318
319 int resp_byte = strtoul(tmp_array, NULL, 16); // Convert to hex byte
320 memcpy((void*)&resp_uuid[resp_loc], &resp_byte, 1); // Copy end to first
321 resp_loc--;
322 id_octet+=2; // Finished with the 2 chars, advance
323 }
324 id_octet=strtok_r(NULL, "-", &tokptr); // Get next octet
325 }
326
327 // Data length
328 *data_len = resp_size;
329
330 // Pack the actual response
331 memcpy(response, &resp_uuid, *data_len);
332
vishwa1eaea4f2016-02-26 11:57:40 -0600333finish:
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500334 sd_bus_error_free(&error);
vishwa1eaea4f2016-02-26 11:57:40 -0600335 reply = sd_bus_message_unref(reply);
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500336
337 return rc;
338}
Chris Austen6caf28b2015-10-13 12:40:40 -0500339
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500340ipmi_ret_t ipmi_app_get_bt_capabilities(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
341 ipmi_request_t request, ipmi_response_t response,
vishwabmcba0bd5f2015-09-30 16:50:23 +0530342 ipmi_data_len_t data_len, ipmi_context_t context)
343{
344 printf("Handling Netfn:[0x%X], Cmd:[0x%X]\n",netfn,cmd);
345
346 // Status code.
347 ipmi_ret_t rc = IPMI_CC_OK;
348
Chris Austen6caf28b2015-10-13 12:40:40 -0500349 uint8_t str[] = {0x01, MAX_IPMI_BUFFER, MAX_IPMI_BUFFER, 0x0A, 0x01};
vishwabmcba0bd5f2015-09-30 16:50:23 +0530350
351 // Data length
352 *data_len = sizeof(str);
353
354 // Pack the actual response
355 memcpy(response, &str, *data_len);
356
357 return rc;
358}
359
Chris Austen6caf28b2015-10-13 12:40:40 -0500360
361struct set_wd_data_t {
362 uint8_t t_use;
363 uint8_t t_action;
364 uint8_t preset;
365 uint8_t flags;
366 uint8_t ls;
367 uint8_t ms;
368} __attribute__ ((packed));
369
370
371
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500372ipmi_ret_t ipmi_app_set_watchdog(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
373 ipmi_request_t request, ipmi_response_t response,
Chris Austen6caf28b2015-10-13 12:40:40 -0500374 ipmi_data_len_t data_len, ipmi_context_t context)
375{
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500376 const char *busname = "org.openbmc.watchdog.Host";
Chris Austen454acfe2015-10-29 23:03:34 -0500377 const char *objname = "/org/openbmc/watchdog/host0";
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500378 const char *iface = "org.openbmc.Watchdog";
vishwa1eaea4f2016-02-26 11:57:40 -0600379 sd_bus_message *reply = NULL;
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500380 sd_bus_error error = SD_BUS_ERROR_NULL;
381 int r = 0;
Chris Austen6caf28b2015-10-13 12:40:40 -0500382
383 set_wd_data_t *reqptr = (set_wd_data_t*) request;
384 uint16_t timer = 0;
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500385 uint32_t timer_ms = 0;
Chris Austen6caf28b2015-10-13 12:40:40 -0500386
387 *data_len = 0;
388
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500389 // Get number of 100ms intervals
Chris Austen6caf28b2015-10-13 12:40:40 -0500390 timer = (((uint16_t)reqptr->ms) << 8) + reqptr->ls;
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500391 // Get timer value in ms
392 timer_ms = timer * 100;
Chris Austen6caf28b2015-10-13 12:40:40 -0500393
394 printf("WATCHDOG SET Timer:[0x%X] 100ms intervals\n",timer);
395
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500396 // Set watchdog timer
vishwa1eaea4f2016-02-26 11:57:40 -0600397 r = sd_bus_call_method(bus, busname, objname, iface,
398 "set", &error, &reply, "i", timer_ms);
399 if(r < 0)
Adriana Kobylak0896be32015-10-22 13:27:23 -0500400 {
vishwa1eaea4f2016-02-26 11:57:40 -0600401 fprintf(stderr, "Failed to call the SET method: %s\n", strerror(-r));
402 goto finish;
Adriana Kobylak0896be32015-10-22 13:27:23 -0500403 }
404
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500405 sd_bus_error_free(&error);
vishwa1eaea4f2016-02-26 11:57:40 -0600406 reply = sd_bus_message_unref(reply);
Chris Austen6caf28b2015-10-13 12:40:40 -0500407
vishwa1eaea4f2016-02-26 11:57:40 -0600408 // Stop the current watchdog if any
409 r = sd_bus_call_method(bus, busname, objname, iface,
410 "stop", &error, &reply, NULL);
411 if(r < 0)
412 {
413 fprintf(stderr, "Failed to call the STOP method: %s\n", strerror(-r));
414 goto finish;
415 }
416
417 if (reqptr->t_use & 0x40)
418 {
419 sd_bus_error_free(&error);
420 reply = sd_bus_message_unref(reply);
421
422 // Start the watchdog if requested
423 r = sd_bus_call_method(bus, busname, objname, iface,
424 "start", &error, &reply, NULL);
425 if(r < 0)
426 {
427 fprintf(stderr, "Failed to call the START method: %s\n", strerror(-r));
428 }
429 }
430
431finish:
432 sd_bus_error_free(&error);
433 reply = sd_bus_message_unref(reply);
434
435 return (r < 0) ? -1 : IPMI_CC_OK;
Chris Austen6caf28b2015-10-13 12:40:40 -0500436}
437
438
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500439ipmi_ret_t ipmi_app_reset_watchdog(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
440 ipmi_request_t request, ipmi_response_t response,
Chris Austen6caf28b2015-10-13 12:40:40 -0500441 ipmi_data_len_t data_len, ipmi_context_t context)
442{
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500443 const char *busname = "org.openbmc.watchdog.Host";
Chris Austen454acfe2015-10-29 23:03:34 -0500444 const char *objname = "/org/openbmc/watchdog/host0";
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500445 const char *iface = "org.openbmc.Watchdog";
vishwa1eaea4f2016-02-26 11:57:40 -0600446 sd_bus_message *reply = NULL;
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500447 sd_bus_error error = SD_BUS_ERROR_NULL;
448 int r = 0;
449
Chris Austen6caf28b2015-10-13 12:40:40 -0500450 // Status code.
451 ipmi_ret_t rc = IPMI_CC_OK;
452 *data_len = 0;
453
454 printf("WATCHDOG RESET\n");
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500455
456 // Refresh watchdog
vishwa1eaea4f2016-02-26 11:57:40 -0600457 r = sd_bus_call_method(bus, busname, objname, iface,
458 "poke", &error, &reply, NULL);
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500459 if (r < 0) {
vishwa1eaea4f2016-02-26 11:57:40 -0600460 fprintf(stderr, "Failed to add reset watchdog: %s\n", strerror(-r));
461 rc = -1;
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500462 }
463
464 sd_bus_error_free(&error);
vishwa1eaea4f2016-02-26 11:57:40 -0600465 reply = sd_bus_message_unref(reply);
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500466
Chris Austen6caf28b2015-10-13 12:40:40 -0500467 return rc;
468}
469
Chris Austenc2cd29d2016-02-05 20:02:29 -0600470// ATTENTION: This ipmi function is very hardcoded on purpose
471// OpenBMC does not fully support IPMI. This command is useful
472// to have around because it enables testing of interfaces with
473// the IPMI tool.
474#define GET_CHANNEL_INFO_CHANNEL_OFFSET 0
475// IPMI Table 6-2
476#define IPMI_CHANNEL_TYPE_IPMB 1
477// IPMI Table 6-3
478#define IPMI_CHANNEL_MEDIUM_TYPE_OTHER 6
479
480ipmi_ret_t ipmi_app_channel_info(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
481 ipmi_request_t request, ipmi_response_t response,
482 ipmi_data_len_t data_len, ipmi_context_t context)
483{
484 ipmi_ret_t rc = IPMI_CC_OK;
485 uint8_t resp[] = {
486 1,
487 IPMI_CHANNEL_MEDIUM_TYPE_OTHER,
488 IPMI_CHANNEL_TYPE_IPMB,
489 1,0x41,0xA7,0x00,0,0};
490 uint8_t *p = (uint8_t*) request;
491
492 printf("IPMI APP GET CHANNEL INFO\n");
493
tomjose7ec0add2016-06-27 07:59:28 -0500494 // The supported channels numbers are 1 and 8.
495 // Channel Number E is used as way to identify the current channel
496 // that the command is being is received from.
tomjose13fb4412016-03-08 14:02:34 -0600497 if (*p == 0xe || *p == 1 || *p == 8) {
Chris Austenc2cd29d2016-02-05 20:02:29 -0600498
499 *data_len = sizeof(resp);
500 memcpy(response, resp, *data_len);
501
502 } else {
503 rc = IPMI_CC_PARM_OUT_OF_RANGE;
504 *data_len = 0;
505 }
506
507 return rc;
508}
509
Adriana Kobylakdfc8d772015-10-20 09:34:48 -0500510ipmi_ret_t ipmi_app_set_bmc_global_enables(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
511 ipmi_request_t request, ipmi_response_t response,
512 ipmi_data_len_t data_len, ipmi_context_t context)
513{
514 ipmi_ret_t rc = IPMI_CC_OK;
515 *data_len = 0;
Chris Austen6caf28b2015-10-13 12:40:40 -0500516
Adriana Kobylakdfc8d772015-10-20 09:34:48 -0500517 // Event and message logging enabled by default so return for now
518 printf("IPMI APP SET BMC GLOBAL ENABLES Ignoring for now\n");
519
520 return rc;
521}
Chris Austen6caf28b2015-10-13 12:40:40 -0500522
523
524
Adriana Kobylak3a552e12015-10-19 16:11:00 -0500525ipmi_ret_t ipmi_app_wildcard_handler(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
526 ipmi_request_t request, ipmi_response_t response,
vishwabmcba0bd5f2015-09-30 16:50:23 +0530527 ipmi_data_len_t data_len, ipmi_context_t context)
528{
529 printf("Handling WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
530
531 // Status code.
532 ipmi_ret_t rc = IPMI_CC_OK;
533
534 *data_len = strlen("THIS IS WILDCARD");
535
536 // Now pack actual response
537 memcpy(response, "THIS IS WILDCARD", *data_len);
538
539 return rc;
540}
541
Chris Austen6caf28b2015-10-13 12:40:40 -0500542void register_netfn_app_functions()
vishwabmcba0bd5f2015-09-30 16:50:23 +0530543{
544 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_CAP_BIT);
Chris Austen6caf28b2015-10-13 12:40:40 -0500545 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CAP_BIT, NULL, ipmi_app_get_bt_capabilities);
546
547 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_WILDCARD);
548 ipmi_register_callback(NETFUN_APP, IPMI_CMD_WILDCARD, NULL, ipmi_app_wildcard_handler);
549
550 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_RESET_WD);
551 ipmi_register_callback(NETFUN_APP, IPMI_CMD_RESET_WD, NULL, ipmi_app_reset_watchdog);
552
553 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_SET_WD);
554 ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_WD, NULL, ipmi_app_set_watchdog);
555
556 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_DEVICE_ID);
557 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_DEVICE_ID, NULL, ipmi_app_get_device_id);
558
Adriana Kobylakd100ee52015-10-20 17:02:37 -0500559 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_DEVICE_GUID);
560 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_DEVICE_GUID, NULL, ipmi_app_get_device_guid);
561
Chris Austen6caf28b2015-10-13 12:40:40 -0500562 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_SET_ACPI);
563 ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_ACPI, NULL, ipmi_app_set_acpi_power_state);
564
565 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_READ_EVENT);
566 ipmi_register_callback(NETFUN_APP, IPMI_CMD_READ_EVENT, NULL, ipmi_app_read_event);
Adriana Kobylakdfc8d772015-10-20 09:34:48 -0500567
568 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP,
569 IPMI_CMD_SET_BMC_GLOBAL_ENABLES);
570 ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_BMC_GLOBAL_ENABLES, NULL,
571 ipmi_app_set_bmc_global_enables);
572
vishwa36993272015-11-20 12:43:49 -0600573 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_MSG_FLAGS);
574 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_MSG_FLAGS, NULL, ipmi_app_get_msg_flags);
575
Chris Austenc2cd29d2016-02-05 20:02:29 -0600576
577 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_CHAN_INFO);
578 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHAN_INFO, NULL, ipmi_app_channel_info);
579
580
581
vishwabmcba0bd5f2015-09-30 16:50:23 +0530582 return;
583}
584
Chris Austen6caf28b2015-10-13 12:40:40 -0500585