blob: b0b12aefc5fc24f08336aa77d8d78ab56cda0135 [file] [log] [blame]
vishwa36993272015-11-20 12:43:49 -06001#include <stdio.h>
2#include <stdlib.h>
3#include <errno.h>
4#include <systemd/sd-bus.h>
Sergey Solomineb9b8142016-08-23 09:07:28 -05005#include <mapper.h>
Patrick Williams37af7332016-09-02 21:21:42 -05006#include "host-ipmid/ipmid-api.h"
Joel Stanley43776832015-11-25 17:28:33 +10307
vishwab9f559a2016-01-13 01:53:08 -06008void register_host_services() __attribute__((constructor));
9
vishwa36993272015-11-20 12:43:49 -060010// OpenBMC Host IPMI dbus framework
vishwa36993272015-11-20 12:43:49 -060011const char *object_name = "/org/openbmc/HostIpmi/1";
12const char *intf_name = "org.openbmc.HostIpmi";
13
14//-------------------------------------------------------------------
15// Gets called by PowerOff handler when a Soft Power off is requested
16//-------------------------------------------------------------------
vishwab9f559a2016-01-13 01:53:08 -060017static int soft_power_off(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
vishwa36993272015-11-20 12:43:49 -060018{
vishwab9f559a2016-01-13 01:53:08 -060019 int64_t bt_resp = -1;
20 int rc = 0;
Sergey Solomineb9b8142016-08-23 09:07:28 -050021 char *bus_name = NULL;
vishwa36993272015-11-20 12:43:49 -060022
vishwab9f559a2016-01-13 01:53:08 -060023 // Steps to be taken when we get this.
24 // 1: Send a SMS_ATN to the Host
25 // 2: Host receives it and sends a GetMsgFlags IPMI command
26 // 3: IPMID app handler will respond to that with a MSgFlag with bit:0x2
27 // set indicating we have a message for Host
28 // 4: Host sends a GetMsgBuffer command and app handler will respond to
29 // that with a OEM-SEL with certain fields packed indicating to the
30 // host that it do a shutdown of the partitions.
31 // 5: Host does the partition shutdown and calls Chassis Power off command
32 // 6: App handler handles the command by making a call to ChassisManager
33 // Dbus
34
35 // Now the job is to send the SMS_ATTN.
36
vishwa36993272015-11-20 12:43:49 -060037 // Req message contains the specifics about which method etc that we want to
38 // access on which bus, object
39 sd_bus_message *response = NULL;
40
vishwab9f559a2016-01-13 01:53:08 -060041 // Error return mechanism
vishwa36993272015-11-20 12:43:49 -060042 sd_bus_error bus_error = SD_BUS_ERROR_NULL;
43
vishwab9f559a2016-01-13 01:53:08 -060044 // Gets a hook onto either a SYSTEM or SESSION bus
45 sd_bus *bus = ipmid_get_sd_bus_connection();
Sergey Solomineb9b8142016-08-23 09:07:28 -050046 rc = mapper_get_service(bus, object_name, &bus_name);
47 if (rc < 0) {
Brad Bishop819ddd42016-10-05 21:19:19 -040048 fprintf(stderr, "Failed to get %s bus name: %s\n",
49 object_name, strerror(-rc));
Sergey Solomineb9b8142016-08-23 09:07:28 -050050 goto finish;
51 }
vishwab9f559a2016-01-13 01:53:08 -060052 rc = sd_bus_call_method(bus, // In the System Bus
53 bus_name, // Service to contact
54 object_name, // Object path
55 intf_name, // Interface name
56 "setAttention", // Method to be called
57 &bus_error, // object to return error
58 &response, // Response buffer if any
59 NULL); // No input arguments
60 if(rc < 0)
61 {
62 fprintf(stderr,"ERROR initiating Power Off:[%s]\n",bus_error.message);
63 goto finish;
64 }
vishwa36993272015-11-20 12:43:49 -060065
vishwab9f559a2016-01-13 01:53:08 -060066 // See if we were able to successfully raise SMS_ATN
vishwa36993272015-11-20 12:43:49 -060067 rc = sd_bus_message_read(response, "x", &bt_resp);
vishwab9f559a2016-01-13 01:53:08 -060068 if (rc < 0)
69 {
70 fprintf(stderr, "Failed to get a rc from BT for SMS_ATN: %s\n", strerror(-rc));
71 goto finish;
vishwa36993272015-11-20 12:43:49 -060072 }
73
74finish:
75 sd_bus_error_free(&bus_error);
vishwa1eaea4f2016-02-26 11:57:40 -060076 response = sd_bus_message_unref(response);
Sergey Solomineb9b8142016-08-23 09:07:28 -050077 free(bus_name);
vishwa36993272015-11-20 12:43:49 -060078
vishwab9f559a2016-01-13 01:53:08 -060079 if(rc < 0)
80 {
81 return sd_bus_reply_method_return(m, "x", rc);
82 }
83 else
84 {
85 return sd_bus_reply_method_return(m, "x", bt_resp);
86 }
vishwa36993272015-11-20 12:43:49 -060087}
88
89//-------------------------------------------
90// Function pointer of APIs exposed via Dbus
91//-------------------------------------------
92static const sd_bus_vtable host_services_vtable[] =
93{
vishwab9f559a2016-01-13 01:53:08 -060094 SD_BUS_VTABLE_START(0),
95 // Takes No("") arguments -but- returns a value of type 64 bit integer("x")
96 SD_BUS_METHOD("SoftPowerOff", "", "x", &soft_power_off, SD_BUS_VTABLE_UNPRIVILEGED),
97 SD_BUS_VTABLE_END,
vishwa36993272015-11-20 12:43:49 -060098};
99
100//------------------------------------------------------
101// Called by IPMID as part of the start up
102// -----------------------------------------------------
103int start_host_service(sd_bus *bus, sd_bus_slot *slot)
104{
vishwab9f559a2016-01-13 01:53:08 -0600105 int rc = 0;
vishwa36993272015-11-20 12:43:49 -0600106
vishwab9f559a2016-01-13 01:53:08 -0600107 /* Install the object */
108 rc = sd_bus_add_object_vtable(bus,
109 &slot,
110 "/org/openbmc/HostServices", /* object path */
111 "org.openbmc.HostServices", /* interface name */
112 host_services_vtable,
113 NULL);
114 if (rc < 0)
115 {
116 fprintf(stderr, "Failed to issue method call: %s\n", strerror(-rc));
117 }
118 else
119 {
120 /* Take one in OpenBmc */
121 rc = sd_bus_request_name(bus, "org.openbmc.HostServices", 0);
122 if (rc < 0)
123 {
124 fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-rc));
125 }
126 }
vishwa36993272015-11-20 12:43:49 -0600127
vishwab9f559a2016-01-13 01:53:08 -0600128 return rc < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
129}
130
131//------------------------------------------------------
132// Callback register function
133// -----------------------------------------------------
134void register_host_services()
135{
136 // Gets a hook onto SYSTEM bus used by host-ipmid
137 sd_bus *bus = ipmid_get_sd_bus_connection();
138
139 // Gets a hook onto SYSTEM bus slot used by host-ipmid
140 sd_bus_slot *ipmid_slot = ipmid_get_sd_bus_slot();
141
142 //start_host_service(bus, ipmid_slot);
143 start_host_service(bus, ipmid_slot);
vishwa36993272015-11-20 12:43:49 -0600144}