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