blob: 56a2116bad7077329fcbf19b0a0867ce8085d73b [file] [log] [blame]
Norman James42c1be82015-10-22 14:34:26 -05001#!/usr/bin/python -u
Norman Jamese2765102015-08-19 22:00:55 -05002
Norman James471ab592015-08-30 22:29:40 -05003import sys
Adriana Kobylak08d3bdb2015-10-20 16:59:14 -05004import uuid
Norman James6f8d0422015-09-14 18:48:00 -05005import gobject
Norman Jamese2765102015-08-19 22:00:55 -05006import dbus
7import dbus.service
8import dbus.mainloop.glib
Brad Bishop84e73b52016-05-12 15:57:52 -04009from obmc.dbuslib.bindings import get_dbus, DbusProperties, DbusObjectManager
Norman Jamese2765102015-08-19 22:00:55 -050010
Norman James3f97c5d2015-08-26 17:44:14 -050011DBUS_NAME = 'org.openbmc.control.Chassis'
Norman James8fee6f22015-10-28 12:48:43 -050012OBJ_NAME = '/org/openbmc/control/chassis0'
Norman Jamesa3e47c42015-10-18 14:43:10 -050013CONTROL_INTF = 'org.openbmc.Control'
Norman James3f97c5d2015-08-26 17:44:14 -050014
Norman Jamesad8c3d32016-02-11 15:19:01 -060015MACHINE_ID = '/etc/machine-id'
16
Norman James2a3d20b2015-08-20 07:09:33 -050017POWER_OFF = 0
18POWER_ON = 1
19
Norman James9e6acf92015-09-08 07:00:04 -050020BOOTED = 100
21
Norman James90baede2015-09-02 20:32:49 -050022
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050023class ChassisControlObject(DbusProperties, DbusObjectManager):
24 def getUuid(self):
25 uuid = "";
26 try:
27 with open(MACHINE_ID) as f:
28 data = f.readline().rstrip('\n')
29 if (len(data) == 32):
30 uuid = data
31 else:
32 print "ERROR: UUID is not formatted correctly: " + data
33 except:
34 print "ERROR: Unable to open uuid file: " + MACHINE_ID
Adriana Kobylak08d3bdb2015-10-20 16:59:14 -050035
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050036 return uuid
Norman Jamescfc2b442015-10-31 17:31:46 -050037
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050038 def __init__(self, bus, name):
39 self.dbus_objects = {}
40 DbusProperties.__init__(self)
41 DbusObjectManager.__init__(self)
42 dbus.service.Object.__init__(self, bus, name)
43 ## load utilized objects
44 self.dbus_objects = {
45 'power_control': {
46 'bus_name': 'org.openbmc.control.Power',
47 'object_name': '/org/openbmc/control/power0',
48 'interface_name': 'org.openbmc.control.Power'
49 },
50 'identify_led': {
51 'bus_name': 'org.openbmc.control.led',
52 'object_name': '/org/openbmc/control/led/identify',
53 'interface_name': 'org.openbmc.Led'
54 },
55 'watchdog': {
56 'bus_name': 'org.openbmc.watchdog.Host',
57 'object_name': '/org/openbmc/watchdog/host0',
58 'interface_name': 'org.openbmc.Watchdog'
59 },
60 'host_services': {
61 'bus_name': 'org.openbmc.HostServices',
62 'object_name': '/org/openbmc/HostServices',
63 'interface_name': 'org.openbmc.HostServices'
64 },
65 'settings': {
66 'bus_name': 'org.openbmc.settings.Host',
67 'object_name': '/org/openbmc/settings/host0',
68 'interface_name': 'org.freedesktop.DBus.Properties'
69 },
Andrew Geissler6b63e9a2016-06-30 10:45:01 -050070 'host_control': {
71 'bus_name': 'org.openbmc.control.Host',
72 'object_name': '/org/openbmc/control/host0',
73 'interface_name': 'org.openbmc.control.Host'
74 },
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050075 }
Norman James72567ba2016-01-13 16:57:48 -060076
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050077 # uuid
78 self.Set(DBUS_NAME, "uuid", self.getUuid())
79 self.Set(DBUS_NAME, "reboot", 0)
Norman James72567ba2016-01-13 16:57:48 -060080
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050081 bus.add_signal_receiver(self.power_button_signal_handler,
82 dbus_interface="org.openbmc.Button",
83 signal_name="Released",
84 path="/org/openbmc/buttons/power0")
85 bus.add_signal_receiver(self.reset_button_signal_handler,
86 dbus_interface="org.openbmc.Button",
87 signal_name="PressedLong",
88 path="/org/openbmc/buttons/power0")
89 bus.add_signal_receiver(self.softreset_button_signal_handler,
90 dbus_interface="org.openbmc.Button",
91 signal_name="Released",
92 path="/org/openbmc/buttons/reset0")
93
94 bus.add_signal_receiver(self.host_watchdog_signal_handler,
95 dbus_interface="org.openbmc.Watchdog",
96 signal_name="WatchdogError")
97
98 bus.add_signal_receiver(self.emergency_shutdown_signal_handler,
99 dbus_interface="org.openbmc.SensorThresholds",
100 signal_name="Emergency")
101
102 bus.add_signal_receiver(self.SystemStateHandler,
103 signal_name="GotoSystemState")
104 self.InterfacesAdded(name, self.properties)
Norman James471ab592015-08-30 22:29:40 -0500105
Norman James9e6acf92015-09-08 07:00:04 -0500106
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500107 def getInterface(self, name):
108 o = self.dbus_objects[name]
109 obj = bus.get_object(o['bus_name'], o['object_name'], introspect=False)
110 return dbus.Interface(obj, o['interface_name'])
Norman Jamese2765102015-08-19 22:00:55 -0500111
Norman Jamese2765102015-08-19 22:00:55 -0500112
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500113 @dbus.service.method(DBUS_NAME,
114 in_signature='', out_signature='')
115 def setIdentify(self):
116 print "Turn on identify"
117 intf = self.getInterface('identify_led')
118 intf.setOn()
119 return None
Norman Jamese2765102015-08-19 22:00:55 -0500120
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500121 @dbus.service.method(DBUS_NAME,
122 in_signature='', out_signature='')
123 def clearIdentify(self):
124 print "Turn on identify"
125 intf = self.getInterface('identify_led')
126 intf.setOff()
127 return None
Norman Jamese2765102015-08-19 22:00:55 -0500128
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500129 @dbus.service.method(DBUS_NAME,
130 in_signature='', out_signature='')
131 def powerOn(self):
132 print "Turn on power and boot"
133 self.Set(DBUS_NAME, "reboot", 0)
134 if (self.getPowerState() == 0):
135 intf = self.getInterface('power_control')
136 intf.setPowerState(POWER_ON)
Andrew Geissler6b63e9a2016-06-30 10:45:01 -0500137
138 # Determine if debug_mode is set. If it is then we don't
139 # want to start the watchdog since debug mode
140 intfcontrol = self.getInterface('host_control')
141 intfproperties = dbus.Interface(intfcontrol,
142 "org.freedesktop.DBus.Properties")
143 debug_mode = intfproperties.Get('org.openbmc.control.Host',
144 'debug_mode')
145 if(not debug_mode):
146 intfwatchdog = self.getInterface('watchdog')
147 # Start watchdog with 30s timeout per the OpenPower Host IPMI Spec
148 #Once the host starts booting, it'll reset and refresh the timer
149 intfwatchdog.set(30000)
150 intfwatchdog.start()
151 else:
152 print "Debug mode is on, no watchdog"
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500153 return None
Norman Jamese2765102015-08-19 22:00:55 -0500154
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500155 @dbus.service.method(DBUS_NAME,
156 in_signature='', out_signature='')
157 def powerOff(self):
158 print "Turn off power"
159 intfwatchdog = self.getInterface('watchdog')
160 intfwatchdog.stop()
161 intf = self.getInterface('power_control')
162 intf.setPowerState(POWER_OFF)
163 return None
Norman James362a80f2015-09-14 14:04:39 -0500164
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500165 @dbus.service.method(DBUS_NAME,
166 in_signature='', out_signature='')
167 def softPowerOff(self):
168 print "Soft off power"
169 intf = self.getInterface('host_services')
170 ## host services will call power off when ready
171 intf.SoftPowerOff()
172 return None
Norman James362a80f2015-09-14 14:04:39 -0500173
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500174 @dbus.service.method(DBUS_NAME,
175 in_signature='', out_signature='')
176 def reboot(self):
177 print "Rebooting"
178 if self.getPowerState() == POWER_OFF:
179 self.powerOn();
180 else:
181 self.Set(DBUS_NAME, "reboot", 1)
182 self.powerOff()
183 return None
Norman Jamesb4ef3182015-12-03 17:54:35 -0600184
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500185 @dbus.service.method(DBUS_NAME,
186 in_signature='', out_signature='')
187 def softReboot(self):
188 print "Soft Rebooting"
189 if self.getPowerState() == POWER_OFF:
190 self.powerOn();
191 else:
192 self.Set(DBUS_NAME, "reboot", 1)
193 self.softPowerOff()
194 return None
Norman Jamese2765102015-08-19 22:00:55 -0500195
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500196 @dbus.service.method(DBUS_NAME,
197 in_signature='', out_signature='i')
198 def getPowerState(self):
199 intf = self.getInterface('power_control')
200 return intf.getPowerState()
Norman Jamese2765102015-08-19 22:00:55 -0500201
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500202 ## Signal handler
Norman James362a80f2015-09-14 14:04:39 -0500203
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500204 def SystemStateHandler(self, state_name):
205 if (
206 state_name == "HOST_POWERED_OFF" or state_name == "HOST_POWERED_ON"):
207 intf = self.getInterface('settings')
208 intf.Set("org.openbmc.settings.Host", "system_state", state_name)
Norman Jamesf5edb9e2016-01-31 13:32:24 -0600209
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500210 if (state_name == "HOST_POWERED_OFF" and self.Get(DBUS_NAME,
211 "reboot") == 1):
212 self.powerOn()
Norman James362a80f2015-09-14 14:04:39 -0500213
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500214 def power_button_signal_handler(self):
215 # toggle power
216 state = self.getPowerState()
217 if state == POWER_OFF:
218 self.powerOn()
219 elif state == POWER_ON:
220 self.powerOff();
Norman Jamese2765102015-08-19 22:00:55 -0500221
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500222 def reset_button_signal_handler(self):
223 self.reboot();
Kenc95eccd2015-12-19 07:02:34 +0800224
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500225 def softreset_button_signal_handler(self):
226 self.softReboot();
Norman James72567ba2016-01-13 16:57:48 -0600227
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500228 def host_watchdog_signal_handler(self):
229 print "Watchdog Error, Hard Rebooting"
230 self.Set(DBUS_NAME, "reboot", 1)
231 self.powerOff()
232
233 def emergency_shutdown_signal_handler(self):
234 print "Emergency Shutdown!"
235 self.powerOff()
236
Norman Jamese2765102015-08-19 22:00:55 -0500237
238if __name__ == '__main__':
239 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
240
Brad Bishop84e73b52016-05-12 15:57:52 -0400241 bus = get_dbus()
Norman James3f97c5d2015-08-26 17:44:14 -0500242 name = dbus.service.BusName(DBUS_NAME, bus)
243 obj = ChassisControlObject(bus, OBJ_NAME)
Norman James6f8d0422015-09-14 18:48:00 -0500244 mainloop = gobject.MainLoop()
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500245
Norman Jamese2765102015-08-19 22:00:55 -0500246 print "Running ChassisControlService"
247 mainloop.run()
248