1#!/usr/bin/python -u 2 3import sys 4import uuid 5import gobject 6import dbus 7import dbus.service 8import dbus.mainloop.glib 9from obmc.dbuslib.bindings import get_dbus, DbusProperties, DbusObjectManager 10 11DBUS_NAME = 'org.openbmc.control.Chassis' 12OBJ_NAME = '/org/openbmc/control/chassis0' 13CONTROL_INTF = 'org.openbmc.Control' 14 15MACHINE_ID = '/etc/machine-id' 16 17POWER_OFF = 0 18POWER_ON = 1 19 20BOOTED = 100 21 22 23class 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 35 36 return uuid 37 38 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 }, 70 'host_control': { 71 'bus_name': 'org.openbmc.control.Host', 72 'object_name': '/org/openbmc/control/host0', 73 'interface_name': 'org.openbmc.control.Host' 74 }, 75 } 76 77 # uuid 78 self.Set(DBUS_NAME, "uuid", self.getUuid()) 79 self.Set(DBUS_NAME, "reboot", 0) 80 81 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) 105 106 107 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']) 111 112 113 @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 120 121 @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 128 129 @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) 137 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" 153 return None 154 155 @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 164 165 @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 173 174 @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 184 185 @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 195 196 @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() 201 202 ## Signal handler 203 204 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) 209 210 if (state_name == "HOST_POWERED_OFF" and self.Get(DBUS_NAME, 211 "reboot") == 1): 212 self.powerOn() 213 214 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(); 221 222 def reset_button_signal_handler(self): 223 self.reboot(); 224 225 def softreset_button_signal_handler(self): 226 self.softReboot(); 227 228 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 237 238if __name__ == '__main__': 239 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 240 241 bus = get_dbus() 242 obj = ChassisControlObject(bus, OBJ_NAME) 243 mainloop = gobject.MainLoop() 244 name = dbus.service.BusName(DBUS_NAME, bus) 245 246 print "Running ChassisControlService" 247 mainloop.run() 248 249