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 } 71 72 # uuid 73 self.Set(DBUS_NAME, "uuid", self.getUuid()) 74 self.Set(DBUS_NAME, "reboot", 0) 75 76 bus.add_signal_receiver(self.power_button_signal_handler, 77 dbus_interface="org.openbmc.Button", 78 signal_name="Released", 79 path="/org/openbmc/buttons/power0") 80 bus.add_signal_receiver(self.reset_button_signal_handler, 81 dbus_interface="org.openbmc.Button", 82 signal_name="PressedLong", 83 path="/org/openbmc/buttons/power0") 84 bus.add_signal_receiver(self.softreset_button_signal_handler, 85 dbus_interface="org.openbmc.Button", 86 signal_name="Released", 87 path="/org/openbmc/buttons/reset0") 88 89 bus.add_signal_receiver(self.host_watchdog_signal_handler, 90 dbus_interface="org.openbmc.Watchdog", 91 signal_name="WatchdogError") 92 93 bus.add_signal_receiver(self.emergency_shutdown_signal_handler, 94 dbus_interface="org.openbmc.SensorThresholds", 95 signal_name="Emergency") 96 97 bus.add_signal_receiver(self.SystemStateHandler, 98 signal_name="GotoSystemState") 99 self.InterfacesAdded(name, self.properties) 100 101 102 def getInterface(self, name): 103 o = self.dbus_objects[name] 104 obj = bus.get_object(o['bus_name'], o['object_name'], introspect=False) 105 return dbus.Interface(obj, o['interface_name']) 106 107 108 @dbus.service.method(DBUS_NAME, 109 in_signature='', out_signature='') 110 def setIdentify(self): 111 print "Turn on identify" 112 intf = self.getInterface('identify_led') 113 intf.setOn() 114 return None 115 116 @dbus.service.method(DBUS_NAME, 117 in_signature='', out_signature='') 118 def clearIdentify(self): 119 print "Turn on identify" 120 intf = self.getInterface('identify_led') 121 intf.setOff() 122 return None 123 124 @dbus.service.method(DBUS_NAME, 125 in_signature='', out_signature='') 126 def powerOn(self): 127 print "Turn on power and boot" 128 self.Set(DBUS_NAME, "reboot", 0) 129 if (self.getPowerState() == 0): 130 intf = self.getInterface('power_control') 131 intf.setPowerState(POWER_ON) 132 intfwatchdog = self.getInterface('watchdog') 133 # Start watchdog with 30s timeout per the OpenPower Host IPMI Spec 134 #Once the host starts booting, it'll reset and refresh the timer 135 intfwatchdog.set(30000) 136 intfwatchdog.start() 137 return None 138 139 @dbus.service.method(DBUS_NAME, 140 in_signature='', out_signature='') 141 def powerOff(self): 142 print "Turn off power" 143 intfwatchdog = self.getInterface('watchdog') 144 intfwatchdog.stop() 145 intf = self.getInterface('power_control') 146 intf.setPowerState(POWER_OFF) 147 return None 148 149 @dbus.service.method(DBUS_NAME, 150 in_signature='', out_signature='') 151 def softPowerOff(self): 152 print "Soft off power" 153 intf = self.getInterface('host_services') 154 ## host services will call power off when ready 155 intf.SoftPowerOff() 156 return None 157 158 @dbus.service.method(DBUS_NAME, 159 in_signature='', out_signature='') 160 def reboot(self): 161 print "Rebooting" 162 if self.getPowerState() == POWER_OFF: 163 self.powerOn(); 164 else: 165 self.Set(DBUS_NAME, "reboot", 1) 166 self.powerOff() 167 return None 168 169 @dbus.service.method(DBUS_NAME, 170 in_signature='', out_signature='') 171 def softReboot(self): 172 print "Soft Rebooting" 173 if self.getPowerState() == POWER_OFF: 174 self.powerOn(); 175 else: 176 self.Set(DBUS_NAME, "reboot", 1) 177 self.softPowerOff() 178 return None 179 180 @dbus.service.method(DBUS_NAME, 181 in_signature='', out_signature='i') 182 def getPowerState(self): 183 intf = self.getInterface('power_control') 184 return intf.getPowerState() 185 186 ## Signal handler 187 188 def SystemStateHandler(self, state_name): 189 if ( 190 state_name == "HOST_POWERED_OFF" or state_name == "HOST_POWERED_ON"): 191 intf = self.getInterface('settings') 192 intf.Set("org.openbmc.settings.Host", "system_state", state_name) 193 194 if (state_name == "HOST_POWERED_OFF" and self.Get(DBUS_NAME, 195 "reboot") == 1): 196 self.powerOn() 197 198 def power_button_signal_handler(self): 199 # toggle power 200 state = self.getPowerState() 201 if state == POWER_OFF: 202 self.powerOn() 203 elif state == POWER_ON: 204 self.powerOff(); 205 206 def reset_button_signal_handler(self): 207 self.reboot(); 208 209 def softreset_button_signal_handler(self): 210 self.softReboot(); 211 212 def host_watchdog_signal_handler(self): 213 print "Watchdog Error, Hard Rebooting" 214 self.Set(DBUS_NAME, "reboot", 1) 215 self.powerOff() 216 217 def emergency_shutdown_signal_handler(self): 218 print "Emergency Shutdown!" 219 self.powerOff() 220 221 222if __name__ == '__main__': 223 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 224 225 bus = get_dbus() 226 name = dbus.service.BusName(DBUS_NAME, bus) 227 obj = ChassisControlObject(bus, OBJ_NAME) 228 mainloop = gobject.MainLoop() 229 230 print "Running ChassisControlService" 231 mainloop.run() 232 233