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 22class ChassisControlObject(DbusProperties,DbusObjectManager): 23 def getUuid(self): 24 uuid = ""; 25 try: 26 with open(MACHINE_ID) as f: 27 data = f.readline().rstrip('\n') 28 if (len(data) == 32): 29 uuid = data 30 else: 31 print "ERROR: UUID is not formatted correctly: "+data 32 except: 33 print "ERROR: Unable to open uuid file: "+MACHINE_ID 34 35 return uuid 36 37 def __init__(self,bus,name): 38 self.dbus_objects = { } 39 DbusProperties.__init__(self) 40 DbusObjectManager.__init__(self) 41 dbus.service.Object.__init__(self,bus,name) 42 ## load utilized objects 43 self.dbus_objects = { 44 'power_control' : { 45 'bus_name' : 'org.openbmc.control.Power', 46 'object_name' : '/org/openbmc/control/power0', 47 'interface_name' : 'org.openbmc.control.Power' 48 }, 49 'identify_led' : { 50 'bus_name' : 'org.openbmc.control.led', 51 'object_name' : '/org/openbmc/control/led/identify', 52 'interface_name' : 'org.openbmc.Led' 53 }, 54 'watchdog' : { 55 'bus_name' : 'org.openbmc.watchdog.Host', 56 'object_name' : '/org/openbmc/watchdog/host0', 57 'interface_name' : 'org.openbmc.Watchdog' 58 }, 59 'host_services' : { 60 'bus_name' : 'org.openbmc.HostServices', 61 'object_name' : '/org/openbmc/HostServices', 62 'interface_name' : 'org.openbmc.HostServices' 63 }, 64 'settings' : { 65 'bus_name' : 'org.openbmc.settings.Host', 66 'object_name' : '/org/openbmc/settings/host0', 67 'interface_name' : 'org.freedesktop.DBus.Properties' 68 }, 69 } 70 71 #uuid 72 self.Set(DBUS_NAME,"uuid",self.getUuid()) 73 self.Set(DBUS_NAME,"reboot",0) 74 75 bus.add_signal_receiver(self.power_button_signal_handler, 76 dbus_interface = "org.openbmc.Button", signal_name = "Released", 77 path="/org/openbmc/buttons/power0" ) 78 bus.add_signal_receiver(self.reset_button_signal_handler, 79 dbus_interface = "org.openbmc.Button", signal_name = "PressedLong", 80 path="/org/openbmc/buttons/power0" ) 81 bus.add_signal_receiver(self.softreset_button_signal_handler, 82 dbus_interface = "org.openbmc.Button", signal_name = "Released", 83 path="/org/openbmc/buttons/reset0" ) 84 85 bus.add_signal_receiver(self.host_watchdog_signal_handler, 86 dbus_interface = "org.openbmc.Watchdog", signal_name = "WatchdogError") 87 88 bus.add_signal_receiver(self.emergency_shutdown_signal_handler, 89 dbus_interface = "org.openbmc.SensorThresholds", signal_name = "Emergency") 90 91 bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState") 92 self.InterfacesAdded(name,self.properties) 93 94 95 def getInterface(self,name): 96 o = self.dbus_objects[name] 97 obj = bus.get_object(o['bus_name'],o['object_name'],introspect=False) 98 return dbus.Interface(obj,o['interface_name']) 99 100 101 @dbus.service.method(DBUS_NAME, 102 in_signature='', out_signature='') 103 def setIdentify(self): 104 print "Turn on identify" 105 intf = self.getInterface('identify_led') 106 intf.setOn() 107 return None 108 109 @dbus.service.method(DBUS_NAME, 110 in_signature='', out_signature='') 111 def clearIdentify(self): 112 print "Turn on identify" 113 intf = self.getInterface('identify_led') 114 intf.setOff() 115 return None 116 117 @dbus.service.method(DBUS_NAME, 118 in_signature='', out_signature='') 119 def powerOn(self): 120 print "Turn on power and boot" 121 self.Set(DBUS_NAME,"reboot",0) 122 if (self.getPowerState()==0): 123 intf = self.getInterface('power_control') 124 intf.setPowerState(POWER_ON) 125 intfwatchdog = self.getInterface('watchdog') 126 #Start watchdog with 30s timeout per the OpenPower Host IPMI Spec 127 #Once the host starts booting, it'll reset and refresh the timer 128 intfwatchdog.set(30000) 129 intfwatchdog.start() 130 return None 131 132 @dbus.service.method(DBUS_NAME, 133 in_signature='', out_signature='') 134 def powerOff(self): 135 print "Turn off power" 136 intfwatchdog = self.getInterface('watchdog') 137 intfwatchdog.stop() 138 intf = self.getInterface('power_control') 139 intf.setPowerState(POWER_OFF) 140 return None 141 142 @dbus.service.method(DBUS_NAME, 143 in_signature='', out_signature='') 144 def softPowerOff(self): 145 print "Soft off power" 146 intf = self.getInterface('host_services') 147 ## host services will call power off when ready 148 intf.SoftPowerOff() 149 return None 150 151 @dbus.service.method(DBUS_NAME, 152 in_signature='', out_signature='') 153 def reboot(self): 154 print "Rebooting" 155 if self.getPowerState() == POWER_OFF: 156 self.powerOn(); 157 else: 158 self.Set(DBUS_NAME,"reboot",1) 159 self.powerOff() 160 return None 161 162 @dbus.service.method(DBUS_NAME, 163 in_signature='', out_signature='') 164 def softReboot(self): 165 print "Soft Rebooting" 166 if self.getPowerState() == POWER_OFF: 167 self.powerOn(); 168 else: 169 self.Set(DBUS_NAME,"reboot",1) 170 self.softPowerOff() 171 return None 172 173 @dbus.service.method(DBUS_NAME, 174 in_signature='', out_signature='i') 175 def getPowerState(self): 176 intf = self.getInterface('power_control') 177 return intf.getPowerState() 178 179 ## Signal handler 180 181 def SystemStateHandler(self,state_name): 182 if (state_name == "HOST_POWERED_OFF" or state_name == "HOST_POWERED_ON"): 183 intf = self.getInterface('settings') 184 intf.Set("org.openbmc.settings.Host","system_state",state_name) 185 186 if (state_name == "HOST_POWERED_OFF" and self.Get(DBUS_NAME,"reboot")==1): 187 self.powerOn() 188 189 def power_button_signal_handler(self): 190 # toggle power 191 state = self.getPowerState() 192 if state == POWER_OFF: 193 self.powerOn() 194 elif state == POWER_ON: 195 self.powerOff(); 196 197 def reset_button_signal_handler(self): 198 self.reboot(); 199 200 def softreset_button_signal_handler(self): 201 self.softReboot(); 202 203 def host_watchdog_signal_handler(self): 204 print "Watchdog Error, Hard Rebooting" 205 self.Set(DBUS_NAME,"reboot",1) 206 self.powerOff() 207 208 def emergency_shutdown_signal_handler(self): 209 print "Emergency Shutdown!" 210 self.powerOff() 211 212 213 214if __name__ == '__main__': 215 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 216 217 bus = get_dbus() 218 name = dbus.service.BusName(DBUS_NAME, bus) 219 obj = ChassisControlObject(bus, OBJ_NAME) 220 mainloop = gobject.MainLoop() 221 222 print "Running ChassisControlService" 223 mainloop.run() 224 225