blob: b101016b118a4578efec4f1f606eca7411df34de [file] [log] [blame]
Tom9e5232e2016-11-07 12:14:51 +05301#include "systemintfcmds.h"
2#include "host-ipmid/ipmid-api.h"
Vishwanatha Subbannab891a572017-03-31 11:34:48 +05303#include "config.h"
Andrew Geissler12866372017-03-21 22:58:28 -05004#include "host-interface.hpp"
Tom9e5232e2016-11-07 12:14:51 +05305
6#include <stdio.h>
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05307#include <mapper.h>
Tom9e5232e2016-11-07 12:14:51 +05308
9void register_netfn_app_functions() __attribute__((constructor));
10
Andrew Geissler12866372017-03-21 22:58:28 -050011using namespace sdbusplus::xyz::openbmc_project::Control::server;
12
13// Internal function to get next host command
14Host::Command getNextHostCmd();
15
16// Notify SofPowerOff application that host is responding to command
17void notifySoftOff()
Tom9e5232e2016-11-07 12:14:51 +053018{
Tom9e5232e2016-11-07 12:14:51 +053019
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +053020 constexpr auto iface = "org.freedesktop.DBus.Properties";
21 constexpr auto soft_off_iface = "xyz.openbmc_project.Ipmi.Internal."
22 "SoftPowerOff";
23
24 constexpr auto property = "ResponseReceived";
25 constexpr auto value = "xyz.openbmc_project.Ipmi.Internal."
26 "SoftPowerOff.HostResponse.SoftOffReceived";
27 char *busname = nullptr;
28
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +053029 // Get the system bus where most system services are provided.
30 auto bus = ipmid_get_sd_bus_connection();
31
32 // Nudge the SoftPowerOff application that it needs to stop the
33 // initial watchdog timer. If we have some errors talking to Soft Off
34 // object, get going and do our regular job
Vishwanatha Subbannab891a572017-03-31 11:34:48 +053035 mapper_get_service(bus, SOFTOFF_OBJPATH, &busname);
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +053036 if (busname)
37 {
38 // No error object or reply expected.
Vishwanatha Subbannab891a572017-03-31 11:34:48 +053039 auto r = sd_bus_call_method(bus, busname, SOFTOFF_OBJPATH, iface,
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +053040 "Set", nullptr, nullptr, "ssv",
41 soft_off_iface, property, "s", value);
42 if (r < 0)
43 {
44 fprintf(stderr, "Failed to set property in SoftPowerOff object: %s\n",
45 strerror(-r));
46 }
47 free (busname);
48 }
49 else
50 {
Andrew Geissler12866372017-03-21 22:58:28 -050051 printf("Soft Power Off object is not available. Ignoring watchdog \
52 refresh");
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +053053 }
Andrew Geissler12866372017-03-21 22:58:28 -050054}
55
56//-------------------------------------------------------------------
57// Called by Host post response from Get_Message_Flags
58//-------------------------------------------------------------------
59ipmi_ret_t ipmi_app_read_event(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
60 ipmi_request_t request, ipmi_response_t response,
61 ipmi_data_len_t data_len, ipmi_context_t context)
62{
63 ipmi_ret_t rc = IPMI_CC_OK;
64
65 printf("IPMI APP READ EVENT command received\n");
66
67 struct oem_sel_timestamped oem_sel = {0};
68 *data_len = sizeof(struct oem_sel_timestamped);
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +053069
Tom9e5232e2016-11-07 12:14:51 +053070 // either id[0] -or- id[1] can be filled in. We will use id[0]
Andrew Geissler12866372017-03-21 22:58:28 -050071 oem_sel.id[0] = SEL_OEM_ID_0;
72 oem_sel.id[1] = SEL_OEM_ID_0;
73 oem_sel.type = SEL_RECORD_TYPE_OEM;
Tom9e5232e2016-11-07 12:14:51 +053074
75 // Following 3 bytes are from IANA Manufactre_Id field. See below
Andrew Geissler12866372017-03-21 22:58:28 -050076 oem_sel.manuf_id[0]= 0x41;
77 oem_sel.manuf_id[1]= 0xA7;
78 oem_sel.manuf_id[2]= 0x00;
Tom9e5232e2016-11-07 12:14:51 +053079
80 // per IPMI spec NetFuntion for OEM
Andrew Geissler12866372017-03-21 22:58:28 -050081 oem_sel.netfun = 0x3A;
Tom9e5232e2016-11-07 12:14:51 +053082
Andrew Geissler12866372017-03-21 22:58:28 -050083 // Read from the queue to see what our response is here
84 Host::Command hCmd = getNextHostCmd();
85 switch (hCmd)
86 {
87 case Host::Command::SoftOff:
88 notifySoftOff();
89 oem_sel.cmd = CMD_POWER;
90 oem_sel.data[0] = SOFT_OFF;
91 break;
92 case Host::Command::Heartbeat:
93 oem_sel.cmd = CMD_HEARTBEAT;
94 oem_sel.data[0] = 0x00;
95 break;
96 }
Tom9e5232e2016-11-07 12:14:51 +053097
98 // All '0xFF' since unused.
Andrew Geissler12866372017-03-21 22:58:28 -050099 memset(&oem_sel.data[1], 0xFF, 3);
Tom9e5232e2016-11-07 12:14:51 +0530100
101 // Pack the actual response
Andrew Geissler12866372017-03-21 22:58:28 -0500102 memcpy(response, &oem_sel, *data_len);
Tom9e5232e2016-11-07 12:14:51 +0530103 return rc;
104}
105
106//---------------------------------------------------------------------
107// Called by Host on seeing a SMS_ATN bit set. Return a hardcoded
108// value of 0x2 indicating we need Host read some data.
109//-------------------------------------------------------------------
110ipmi_ret_t ipmi_app_get_msg_flags(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
111 ipmi_request_t request, ipmi_response_t response,
112 ipmi_data_len_t data_len, ipmi_context_t context)
113{
114 // Generic return from IPMI commands.
115 ipmi_ret_t rc = IPMI_CC_OK;
116
117 printf("IPMI APP GET MSG FLAGS returning with [bit:2] set\n");
118
119 // From IPMI spec V2.0 for Get Message Flags Command :
120 // bit:[1] from LSB : 1b = Event Message Buffer Full.
121 // Return as 0 if Event Message Buffer is not supported,
122 // or when the Event Message buffer is disabled.
123 // TODO. For now. assume its not disabled and send "0x2" anyway:
124
125 uint8_t set_event_msg_buffer_full = 0x2;
126 *data_len = sizeof(set_event_msg_buffer_full);
127
128 // Pack the actual response
129 memcpy(response, &set_event_msg_buffer_full, *data_len);
130
131 return rc;
132}
133
134ipmi_ret_t ipmi_app_set_bmc_global_enables(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
135 ipmi_request_t request, ipmi_response_t response,
136 ipmi_data_len_t data_len, ipmi_context_t context)
137{
138 ipmi_ret_t rc = IPMI_CC_OK;
139 *data_len = 0;
140
141 // Event and message logging enabled by default so return for now
142 printf("IPMI APP SET BMC GLOBAL ENABLES Ignoring for now\n");
143
144 return rc;
145}
146
Lei YU12c2db72017-05-15 11:24:04 +0800147namespace {
148// Static storage to keep the object alive during process life
149std::unique_ptr<sdbusplus::bus::bus> sdbus __attribute__((init_priority(101)));
150std::unique_ptr<phosphor::host::Host> host __attribute__((init_priority(101)));
151}
Andrew Geissler12866372017-03-21 22:58:28 -0500152
153#include <unistd.h>
Tom9e5232e2016-11-07 12:14:51 +0530154void register_netfn_app_functions()
155{
156
157 // <Read Event Message Buffer>
158 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_READ_EVENT);
Tom05732372016-09-06 17:21:23 +0530159 ipmi_register_callback(NETFUN_APP, IPMI_CMD_READ_EVENT, NULL, ipmi_app_read_event,
160 SYSTEM_INTERFACE);
Tom9e5232e2016-11-07 12:14:51 +0530161
162 // <Set BMC Global Enables>
163 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP,
164 IPMI_CMD_SET_BMC_GLOBAL_ENABLES);
165 ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_BMC_GLOBAL_ENABLES, NULL,
Tom05732372016-09-06 17:21:23 +0530166 ipmi_app_set_bmc_global_enables, SYSTEM_INTERFACE);
Tom9e5232e2016-11-07 12:14:51 +0530167
168 // <Get Message Flags>
169 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_MSG_FLAGS);
Tom05732372016-09-06 17:21:23 +0530170 ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_MSG_FLAGS, NULL, ipmi_app_get_msg_flags,
171 SYSTEM_INTERFACE);
Tom9e5232e2016-11-07 12:14:51 +0530172
Andrew Geissler12866372017-03-21 22:58:28 -0500173 // Gets a hook onto SYSTEM bus used by host-ipmid
174 sd_bus *bus = ipmid_get_sd_bus_connection();
175
176 sdbus = std::make_unique<sdbusplus::bus::bus>(bus);
177
178 // Create new xyz.openbmc_project.host object on the bus
179 auto objPathInst = std::string{CONTROL_HOST_OBJPATH} + '0';
180
181 // Add sdbusplus ObjectManager.
182 sdbusplus::server::manager::manager objManager(*sdbus,
183 objPathInst.c_str());
184
Andrew Geissler83159702017-04-03 13:31:13 -0500185 // Get the sd_events pointer
186 auto events = ipmid_get_sd_event_connection();
187
Lei YU12c2db72017-05-15 11:24:04 +0800188 host = std::make_unique<phosphor::host::Host>(*sdbus,
189 objPathInst.c_str(),
190 events);
Andrew Geissler12866372017-03-21 22:58:28 -0500191
192 sdbus->request_name(CONTROL_HOST_BUSNAME);
193
Tom9e5232e2016-11-07 12:14:51 +0530194 return;
195}
Andrew Geissler12866372017-03-21 22:58:28 -0500196
197Host::Command getNextHostCmd()
198{
199 return(host->getNextCommand());
200}