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 105 106 def getInterface(self, name): 107 o = self.dbus_objects[name] 108 obj = bus.get_object(o['bus_name'], o['object_name'], introspect=False) 109 return dbus.Interface(obj, o['interface_name']) 110 111 112 @dbus.service.method(DBUS_NAME, 113 in_signature='', out_signature='') 114 def setIdentify(self): 115 print "Turn on identify" 116 intf = self.getInterface('identify_led') 117 intf.setOn() 118 return None 119 120 @dbus.service.method(DBUS_NAME, 121 in_signature='', out_signature='') 122 def clearIdentify(self): 123 print "Turn on identify" 124 intf = self.getInterface('identify_led') 125 intf.setOff() 126 return None 127 128 @dbus.service.method(DBUS_NAME, 129 in_signature='', out_signature='') 130 def powerOn(self): 131 print "Turn on power and boot" 132 self.Set(DBUS_NAME, "reboot", 0) 133 if (self.getPowerState() == 0): 134 intf = self.getInterface('power_control') 135 intf.setPowerState(POWER_ON) 136 137 # Determine if debug_mode is set. If it is then we don't 138 # want to start the watchdog since debug mode 139 intfcontrol = self.getInterface('host_control') 140 intfproperties = dbus.Interface(intfcontrol, 141 "org.freedesktop.DBus.Properties") 142 debug_mode = intfproperties.Get('org.openbmc.control.Host', 143 'debug_mode') 144 if(not debug_mode): 145 intfwatchdog = self.getInterface('watchdog') 146 # Start watchdog with 30s timeout per the OpenPower Host IPMI Spec 147 #Once the host starts booting, it'll reset and refresh the timer 148 intfwatchdog.set(30000) 149 intfwatchdog.start() 150 else: 151 print "Debug mode is on, no watchdog" 152 return None 153 154 @dbus.service.method(DBUS_NAME, 155 in_signature='', out_signature='') 156 def powerOff(self): 157 print "Turn off power" 158 intfwatchdog = self.getInterface('watchdog') 159 intfwatchdog.stop() 160 intf = self.getInterface('power_control') 161 intf.setPowerState(POWER_OFF) 162 return None 163 164 @dbus.service.method(DBUS_NAME, 165 in_signature='', out_signature='') 166 def softPowerOff(self): 167 print "Soft off power" 168 intf = self.getInterface('host_services') 169 ## host services will call power off when ready 170 intf.SoftPowerOff() 171 return None 172 173 @dbus.service.method(DBUS_NAME, 174 in_signature='', out_signature='') 175 def reboot(self): 176 print "Rebooting" 177 if self.getPowerState() == POWER_OFF: 178 self.powerOn(); 179 else: 180 self.Set(DBUS_NAME, "reboot", 1) 181 self.powerOff() 182 return None 183 184 @dbus.service.method(DBUS_NAME, 185 in_signature='', out_signature='') 186 def softReboot(self): 187 print "Soft Rebooting" 188 if self.getPowerState() == POWER_OFF: 189 self.powerOn(); 190 else: 191 self.Set(DBUS_NAME, "reboot", 1) 192 self.softPowerOff() 193 return None 194 195 @dbus.service.method(DBUS_NAME, 196 in_signature='', out_signature='i') 197 def getPowerState(self): 198 intf = self.getInterface('power_control') 199 return intf.getPowerState() 200 201 ## Signal handler 202 203 def SystemStateHandler(self, state_name): 204 if ( 205 state_name == "HOST_POWERED_OFF" or state_name == "HOST_POWERED_ON"): 206 intf = self.getInterface('settings') 207 intf.Set("org.openbmc.settings.Host", "system_state", state_name) 208 209 if (state_name == "HOST_POWERED_OFF" and self.Get(DBUS_NAME, 210 "reboot") == 1): 211 self.powerOn() 212 213 def power_button_signal_handler(self): 214 # toggle power 215 state = self.getPowerState() 216 if state == POWER_OFF: 217 self.powerOn() 218 elif state == POWER_ON: 219 self.powerOff(); 220 221 def reset_button_signal_handler(self): 222 self.reboot(); 223 224 def softreset_button_signal_handler(self): 225 self.softReboot(); 226 227 def host_watchdog_signal_handler(self): 228 print "Watchdog Error, Hard Rebooting" 229 self.Set(DBUS_NAME, "reboot", 1) 230 self.powerOff() 231 232 def emergency_shutdown_signal_handler(self): 233 print "Emergency Shutdown!" 234 self.powerOff() 235 236 237if __name__ == '__main__': 238 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 239 240 bus = get_dbus() 241 obj = ChassisControlObject(bus, OBJ_NAME) 242 mainloop = gobject.MainLoop() 243 244 obj.unmask_signals() 245 name = dbus.service.BusName(DBUS_NAME, bus) 246 247 print "Running ChassisControlService" 248 mainloop.run() 249 250