blob: 84e8426c9f12c7bc0d1d1d3c6647fa996434133d [file] [log] [blame]
Patrick Venture5e6ac712017-10-25 12:16:19 -07001#include "watchdog.hpp"
Patrick Venture894571d2017-11-09 14:46:54 -08002#include "utils.hpp"
Patrick Venture5e6ac712017-10-25 12:16:19 -07003
4#include <systemd/sd-bus.h>
Patrick Venture894571d2017-11-09 14:46:54 -08005
Patrick Venture5e6ac712017-10-25 12:16:19 -07006#include <mapper.h>
Patrick Venture894571d2017-11-09 14:46:54 -08007#include <sdbusplus/bus.hpp>
Patrick Venture5e6ac712017-10-25 12:16:19 -07008
9extern sd_bus *bus;
10
11struct set_wd_data_t {
Patrick Venture894571d2017-11-09 14:46:54 -080012 uint8_t timer_use;
13 uint8_t timer_action;
Patrick Venture5e6ac712017-10-25 12:16:19 -070014 uint8_t preset;
15 uint8_t flags;
16 uint8_t ls;
17 uint8_t ms;
18} __attribute__ ((packed));
19
Patrick Venture894571d2017-11-09 14:46:54 -080020static constexpr auto objname = "/xyz/openbmc_project/watchdog/host0";
21static constexpr auto iface = "xyz.openbmc_project.State.Watchdog";
22static constexpr auto property_iface = "org.freedesktop.DBus.Properties";
Patrick Venture5e6ac712017-10-25 12:16:19 -070023
Patrick Venture894571d2017-11-09 14:46:54 -080024ipmi_ret_t ipmi_app_set_watchdog(
25 ipmi_netfn_t netfn,
26 ipmi_cmd_t cmd,
27 ipmi_request_t request,
28 ipmi_response_t response,
29 ipmi_data_len_t data_len,
30 ipmi_context_t context)
Patrick Venture5e6ac712017-10-25 12:16:19 -070031{
Patrick Venture5e6ac712017-10-25 12:16:19 -070032 sd_bus_message *reply = NULL;
33 sd_bus_error error = SD_BUS_ERROR_NULL;
34 int r = 0;
35
36 set_wd_data_t *reqptr = (set_wd_data_t*) request;
Patrick Venture894571d2017-11-09 14:46:54 -080037
Patrick Venture5e6ac712017-10-25 12:16:19 -070038 uint16_t timer = 0;
39
40 // Making this uint64_t to match with provider
41 uint64_t timer_ms = 0;
42 char *busname = NULL;
43 *data_len = 0;
44
45 // Get number of 100ms intervals
46 timer = (((uint16_t)reqptr->ms) << 8) + reqptr->ls;
47 // Get timer value in ms
48 timer_ms = timer * 100;
49
50 printf("WATCHDOG SET Timer:[0x%X] 100ms intervals\n",timer);
51
52 // Get bus name
53 r = mapper_get_service(bus, objname, &busname);
54 if (r < 0) {
55 fprintf(stderr, "Failed to get %s bus name: %s\n",
56 objname, strerror(-r));
57 goto finish;
58 }
59
60 // Disable watchdog if running
61 r = sd_bus_call_method(bus, busname, objname, property_iface,
62 "Set", &error, &reply, "ssv",
63 iface, "Enabled", "b", false);
64 if(r < 0) {
65 fprintf(stderr, "Failed to disable Watchdog: %s\n",
66 strerror(-r));
67 goto finish;
68 }
69
70 /*
71 * If the action is 0, it means, do nothing. Multiple actions on timer
72 * expiration aren't supported by phosphor-watchdog yet, so when the
73 * action set is "none", we should just leave the timer disabled.
74 */
Patrick Venture894571d2017-11-09 14:46:54 -080075 if (0 == reqptr->timer_action)
Patrick Venture5e6ac712017-10-25 12:16:19 -070076 {
77 goto finish;
78 }
79
Patrick Venture894571d2017-11-09 14:46:54 -080080 if (reqptr->timer_use & 0x40)
Patrick Venture5e6ac712017-10-25 12:16:19 -070081 {
82 sd_bus_error_free(&error);
83 reply = sd_bus_message_unref(reply);
84
85 // Set the Interval for the Watchdog
86 r = sd_bus_call_method(bus, busname, objname, property_iface,
87 "Set", &error, &reply, "ssv",
88 iface, "Interval", "t", timer_ms);
89 if(r < 0) {
90 fprintf(stderr, "Failed to set new expiration time: %s\n",
91 strerror(-r));
92 goto finish;
93 }
94
95 // Now Enable Watchdog
96 r = sd_bus_call_method(bus, busname, objname, property_iface,
97 "Set", &error, &reply, "ssv",
98 iface, "Enabled", "b", true);
99 if(r < 0) {
100 fprintf(stderr, "Failed to Enable Watchdog: %s\n",
101 strerror(-r));
102 goto finish;
103 }
104 }
105
106finish:
107 sd_bus_error_free(&error);
108 reply = sd_bus_message_unref(reply);
109 free(busname);
110
111 return (r < 0) ? -1 : IPMI_CC_OK;
112}
113
Patrick Venture894571d2017-11-09 14:46:54 -0800114ipmi_ret_t ipmi_app_reset_watchdog(
115 ipmi_netfn_t netfn,
116 ipmi_cmd_t cmd,
117 ipmi_request_t request,
118 ipmi_response_t response,
119 ipmi_data_len_t data_len,
120 ipmi_context_t context)
Patrick Venture5e6ac712017-10-25 12:16:19 -0700121{
Patrick Venture5e6ac712017-10-25 12:16:19 -0700122 sd_bus_message *reply = NULL;
123 sd_bus_error error = SD_BUS_ERROR_NULL;
124 int r = 0;
125 char *busname = NULL;
126
127 // Current time interval that is set in watchdog.
128 uint64_t interval = 0;
129
130 // Status code.
131 ipmi_ret_t rc = IPMI_CC_OK;
132 *data_len = 0;
133
134 printf("WATCHDOG RESET\n");
135 // Get bus name
136 r = mapper_get_service(bus, objname, &busname);
137 if (r < 0) {
138 fprintf(stderr, "Failed to get %s bus name: %s\n",
139 objname, strerror(-r));
140 goto finish;
141 }
142
143 // Get the current interval and set it back.
144 r = sd_bus_call_method(bus, busname, objname, property_iface,
145 "Get", &error, &reply, "ss",
146 iface, "Interval");
147
148 if(r < 0) {
149 fprintf(stderr, "Failed to get current Interval msg: %s\n",
150 strerror(-r));
151 goto finish;
152 }
153
154 // Now extract the value
155 r = sd_bus_message_read(reply, "v", "t", &interval);
156 if (r < 0) {
157 fprintf(stderr, "Failed to read current interval: %s\n",
158 strerror(-r));
159 goto finish;
160 }
161
162 sd_bus_error_free(&error);
163 reply = sd_bus_message_unref(reply);
164
165 // Set watchdog timer
166 r = sd_bus_call_method(bus, busname, objname, property_iface,
167 "Set", &error, &reply, "ssv",
168 iface, "TimeRemaining", "t", interval);
169 if(r < 0) {
170 fprintf(stderr, "Failed to refresh the timer: %s\n",
171 strerror(-r));
172 goto finish;
173 }
174
175finish:
176 sd_bus_error_free(&error);
177 reply = sd_bus_message_unref(reply);
178 free(busname);
179
180 return rc;
181}