1de6ed120SBrad Bishop#!/usr/bin/env python 240a360c2SBrad Bishop 340a360c2SBrad Bishopimport gobject 440a360c2SBrad Bishopimport dbus 540a360c2SBrad Bishopimport dbus.service 640a360c2SBrad Bishopimport dbus.mainloop.glib 740a360c2SBrad Bishopimport os 840a360c2SBrad Bishopimport obmc.dbuslib.propertycacher as PropertyCacher 940a360c2SBrad Bishopfrom obmc.dbuslib.bindings import DbusProperties, DbusObjectManager, get_dbus 1040a360c2SBrad Bishopimport obmc.enums 110b380f7bSBrad Bishopimport obmc_system_config as System 126173a896SBrad Bishopimport obmc.mapper.utils 137e5ec46dSBrad Bishopimport obmc.inventory 14a7ac805bSBrad Bishopimport obmc.system 1540a360c2SBrad Bishop 1640a360c2SBrad BishopDBUS_NAME = 'org.openbmc.managers.System' 1740a360c2SBrad BishopOBJ_NAME = '/org/openbmc/managers/System' 1840a360c2SBrad BishopINTF_SENSOR = 'org.openbmc.SensorValue' 1940a360c2SBrad BishopINTF_ITEM = 'org.openbmc.InventoryItem' 2040a360c2SBrad Bishop 21*520f8b05SRatan GuptaSYS_STATE_FILE = '/var/lib/obmc/last-system-state' 22*520f8b05SRatan GuptaPOWER_OFF = "0" 23*520f8b05SRatan Gupta 2440a360c2SBrad Bishop 2540a360c2SBrad Bishopclass SystemManager(DbusProperties, DbusObjectManager): 2640a360c2SBrad Bishop def __init__(self, bus, obj_name): 27f47f5faaSBrad Bishop super(SystemManager, self).__init__( 28f47f5faaSBrad Bishop conn=bus, 29f47f5faaSBrad Bishop object_path=obj_name) 30fa736499SBrad Bishop self.bus = bus 3140a360c2SBrad Bishop 32fa736499SBrad Bishop bus.add_signal_receiver( 33416539dfSBrad Bishop self.NewObjectHandler, 3440a360c2SBrad Bishop signal_name="InterfacesAdded", sender_keyword='bus_name') 35416539dfSBrad Bishop bus.add_signal_receiver( 36416539dfSBrad Bishop self.SystemStateHandler, signal_name="GotoSystemState") 3740a360c2SBrad Bishop 38*520f8b05SRatan Gupta bus.add_signal_receiver( 39*520f8b05SRatan Gupta self.chassisPowerStateHandler, 40*520f8b05SRatan Gupta dbus_interface="org.freedesktop.DBus.Properties", 41*520f8b05SRatan Gupta signal_name="PropertiesChanged", 42*520f8b05SRatan Gupta path="/org/openbmc/control/power0") 4340a360c2SBrad Bishop 44*520f8b05SRatan Gupta self.Set(DBUS_NAME, "current_state", "") 45*520f8b05SRatan Gupta self.Set(DBUS_NAME, "system_last_state", POWER_OFF) 46*520f8b05SRatan Gupta self.import_system_state_from_disk() 47*520f8b05SRatan Gupta # replace symbolic path in ID_LOOKUP 4840a360c2SBrad Bishop for category in System.ID_LOOKUP: 4940a360c2SBrad Bishop for key in System.ID_LOOKUP[category]: 5040a360c2SBrad Bishop val = System.ID_LOOKUP[category][key] 51416539dfSBrad Bishop new_val = val.replace( 527e5ec46dSBrad Bishop "<inventory_root>", obmc.inventory.INVENTORY_ROOT) 5340a360c2SBrad Bishop System.ID_LOOKUP[category][key] = new_val 5440a360c2SBrad Bishop 5540a360c2SBrad Bishop self.SystemStateHandler(System.SYSTEM_STATES[0]) 5640a360c2SBrad Bishop 5740a360c2SBrad Bishop print "SystemManager Init Done" 5840a360c2SBrad Bishop 59*520f8b05SRatan Gupta def chassisPowerStateHandler(self, interface_name, changed_properties, 60*520f8b05SRatan Gupta invalidated_properties): 61*520f8b05SRatan Gupta value = changed_properties.get('state') 62*520f8b05SRatan Gupta if value is not None: 63*520f8b05SRatan Gupta self.write_to_disk_and_update(str(value)) 64*520f8b05SRatan Gupta 6540a360c2SBrad Bishop def SystemStateHandler(self, state_name): 6640a360c2SBrad Bishop print "Running System State: "+state_name 6740a360c2SBrad Bishop 6840a360c2SBrad Bishop self.Set(DBUS_NAME, "current_state", state_name) 6940a360c2SBrad Bishop 706173a896SBrad Bishop waitlist = System.EXIT_STATE_DEPEND.get(state_name, {}).keys() 716173a896SBrad Bishop if waitlist: 726173a896SBrad Bishop self.waiter = obmc.mapper.utils.Wait( 736173a896SBrad Bishop self.bus, waitlist, 746173a896SBrad Bishop callback=self.gotoNextState) 756173a896SBrad Bishop 7640a360c2SBrad Bishop def gotoNextState(self): 7740a360c2SBrad Bishop s = 0 7840a360c2SBrad Bishop current_state = self.Get(DBUS_NAME, "current_state") 7940a360c2SBrad Bishop for i in range(len(System.SYSTEM_STATES)): 8040a360c2SBrad Bishop if (System.SYSTEM_STATES[i] == current_state): 8140a360c2SBrad Bishop s = i+1 8240a360c2SBrad Bishop 8340a360c2SBrad Bishop if (s == len(System.SYSTEM_STATES)): 8440a360c2SBrad Bishop print "ERROR SystemManager: No more system states" 8540a360c2SBrad Bishop else: 8640a360c2SBrad Bishop new_state_name = System.SYSTEM_STATES[s] 8740a360c2SBrad Bishop print "SystemManager Goto System State: "+new_state_name 8840a360c2SBrad Bishop self.SystemStateHandler(new_state_name) 8940a360c2SBrad Bishop 90*520f8b05SRatan Gupta def import_system_state_from_disk(self): 91*520f8b05SRatan Gupta state = str(POWER_OFF) 92*520f8b05SRatan Gupta try: 93*520f8b05SRatan Gupta with open(SYS_STATE_FILE, 'r+') as f: 94*520f8b05SRatan Gupta state = f.readline().rstrip('\n') 95*520f8b05SRatan Gupta except IOError: 96*520f8b05SRatan Gupta pass 97*520f8b05SRatan Gupta self.Set(DBUS_NAME, "system_last_state", state) 98*520f8b05SRatan Gupta return state 99*520f8b05SRatan Gupta 100*520f8b05SRatan Gupta def write_to_disk_and_update(self, state): 101*520f8b05SRatan Gupta try: 102*520f8b05SRatan Gupta with open(SYS_STATE_FILE, 'w+') as f: 103*520f8b05SRatan Gupta f.write(str(state)) 104*520f8b05SRatan Gupta self.Set(DBUS_NAME, "system_last_state", state) 105*520f8b05SRatan Gupta except IOError: 106*520f8b05SRatan Gupta pass 107*520f8b05SRatan Gupta 108416539dfSBrad Bishop @dbus.service.method(DBUS_NAME, in_signature='', out_signature='s') 10940a360c2SBrad Bishop def getSystemState(self): 11040a360c2SBrad Bishop return self.Get(DBUS_NAME, "current_state") 11140a360c2SBrad Bishop 11240a360c2SBrad Bishop def doObjectLookup(self, category, key): 11340a360c2SBrad Bishop obj_path = "" 11440a360c2SBrad Bishop intf_name = INTF_ITEM 11540a360c2SBrad Bishop try: 11640a360c2SBrad Bishop obj_path = System.ID_LOOKUP[category][key] 11740a360c2SBrad Bishop parts = obj_path.split('/') 11840a360c2SBrad Bishop if (parts[3] == 'sensors'): 11940a360c2SBrad Bishop intf_name = INTF_SENSOR 12040a360c2SBrad Bishop except Exception as e: 12140a360c2SBrad Bishop print "ERROR SystemManager: "+str(e)+" not found in lookup" 12240a360c2SBrad Bishop 123fc38a575SBrad Bishop return [obj_path, intf_name] 12440a360c2SBrad Bishop 125fc38a575SBrad Bishop @dbus.service.method(DBUS_NAME, in_signature='ss', out_signature='(ss)') 12640a360c2SBrad Bishop def getObjectFromId(self, category, key): 12740a360c2SBrad Bishop return self.doObjectLookup(category, key) 12840a360c2SBrad Bishop 129fc38a575SBrad Bishop @dbus.service.method(DBUS_NAME, in_signature='sy', out_signature='(ss)') 13040a360c2SBrad Bishop def getObjectFromByteId(self, category, key): 13140a360c2SBrad Bishop byte = int(key) 13240a360c2SBrad Bishop return self.doObjectLookup(category, byte) 13340a360c2SBrad Bishop 13440a360c2SBrad Bishop # Get the FRU area names defined in ID_LOOKUP table given a fru_id. 13540a360c2SBrad Bishop # If serval areas are defined for a fru_id, the areas are returned 13640a360c2SBrad Bishop # together as a string with each area name seperated with ','. 13740a360c2SBrad Bishop # If no fru area defined in ID_LOOKUP, an empty string will be returned. 138416539dfSBrad Bishop @dbus.service.method(DBUS_NAME, in_signature='y', out_signature='s') 13940a360c2SBrad Bishop def getFRUArea(self, fru_id): 14040a360c2SBrad Bishop ret_str = '' 14140a360c2SBrad Bishop fru_id = '_' + str(fru_id) 142416539dfSBrad Bishop area_list = [ 143416539dfSBrad Bishop area for area in System.ID_LOOKUP['FRU_STR'].keys() 14440a360c2SBrad Bishop if area.endswith(fru_id)] 14540a360c2SBrad Bishop for area in area_list: 14640a360c2SBrad Bishop ret_str = area + ',' + ret_str 14740a360c2SBrad Bishop # remove the last ',' 14840a360c2SBrad Bishop return ret_str[:-1] 14940a360c2SBrad Bishop 15040a360c2SBrad Bishop def NewObjectHandler(self, obj_path, iprops, bus_name=None): 15140a360c2SBrad Bishop current_state = self.Get(DBUS_NAME, "current_state") 1524de42643SBrad Bishop if current_state not in System.EXIT_STATE_DEPEND: 1534de42643SBrad Bishop return 15440a360c2SBrad Bishop 1554de42643SBrad Bishop if obj_path in System.EXIT_STATE_DEPEND[current_state]: 1564de42643SBrad Bishop print "New object: "+obj_path+" ("+bus_name+")" 15740a360c2SBrad Bishop 158416539dfSBrad Bishop @dbus.service.method(DBUS_NAME, in_signature='s', out_signature='sis') 15940a360c2SBrad Bishop def gpioInit(self, name): 16040a360c2SBrad Bishop gpio_path = '' 16140a360c2SBrad Bishop gpio_num = -1 16240a360c2SBrad Bishop r = ['', gpio_num, ''] 163416539dfSBrad Bishop if name not in System.GPIO_CONFIG: 16440a360c2SBrad Bishop # TODO: Error handling 16540a360c2SBrad Bishop print "ERROR: "+name+" not found in GPIO config table" 16640a360c2SBrad Bishop else: 16740a360c2SBrad Bishop 16840a360c2SBrad Bishop gpio_num = -1 16940a360c2SBrad Bishop gpio = System.GPIO_CONFIG[name] 170416539dfSBrad Bishop if 'gpio_num' in System.GPIO_CONFIG[name]: 17140a360c2SBrad Bishop gpio_num = gpio['gpio_num'] 17240a360c2SBrad Bishop else: 173416539dfSBrad Bishop if 'gpio_pin' in System.GPIO_CONFIG[name]: 174a7ac805bSBrad Bishop gpio_num = obmc.system.convertGpio(gpio['gpio_pin']) 17540a360c2SBrad Bishop else: 17640a360c2SBrad Bishop print "ERROR: SystemManager - GPIO lookup failed for "+name 17740a360c2SBrad Bishop 17840a360c2SBrad Bishop if (gpio_num != -1): 17940a360c2SBrad Bishop r = [obmc.enums.GPIO_DEV, gpio_num, gpio['direction']] 18040a360c2SBrad Bishop return r 18140a360c2SBrad Bishop 18240a360c2SBrad Bishop 18340a360c2SBrad Bishopif __name__ == '__main__': 18440a360c2SBrad Bishop dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 18540a360c2SBrad Bishop bus = get_dbus() 18640a360c2SBrad Bishop obj = SystemManager(bus, OBJ_NAME) 18740a360c2SBrad Bishop mainloop = gobject.MainLoop() 188f0f3efe1SBrad Bishop obj.unmask_signals() 18970852a38SBrad Bishop name = dbus.service.BusName(DBUS_NAME, bus) 19040a360c2SBrad Bishop 19140a360c2SBrad Bishop print "Running SystemManager" 19240a360c2SBrad Bishop mainloop.run() 19353066750SBrad Bishop 19453066750SBrad Bishop# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 195