1#!/usr/bin/env python 2 3import gobject 4import dbus 5import dbus.service 6import dbus.mainloop.glib 7import os 8import obmc.dbuslib.propertycacher as PropertyCacher 9from obmc.dbuslib.bindings import DbusProperties, DbusObjectManager, get_dbus 10import obmc.enums 11import obmc_system_config as System 12import obmc.mapper.utils 13import obmc.inventory 14import obmc.system 15 16DBUS_NAME = 'org.openbmc.managers.System' 17OBJ_NAME = '/org/openbmc/managers/System' 18INTF_SENSOR = 'org.openbmc.SensorValue' 19INTF_ITEM = 'org.openbmc.InventoryItem' 20 21SYS_STATE_FILE = '/var/lib/obmc/last-system-state' 22POWER_OFF = "0" 23 24 25class SystemManager(DbusProperties, DbusObjectManager): 26 def __init__(self, bus, obj_name): 27 super(SystemManager, self).__init__( 28 conn=bus, 29 object_path=obj_name) 30 self.bus = bus 31 32 bus.add_signal_receiver( 33 self.NewObjectHandler, 34 signal_name="InterfacesAdded", sender_keyword='bus_name') 35 bus.add_signal_receiver( 36 self.SystemStateHandler, signal_name="GotoSystemState") 37 38 bus.add_signal_receiver( 39 self.chassisPowerStateHandler, 40 dbus_interface="org.freedesktop.DBus.Properties", 41 signal_name="PropertiesChanged", 42 path="/org/openbmc/control/power0") 43 44 self.Set(DBUS_NAME, "current_state", "") 45 self.Set(DBUS_NAME, "system_last_state", POWER_OFF) 46 self.import_system_state_from_disk() 47 # replace symbolic path in ID_LOOKUP 48 for category in System.ID_LOOKUP: 49 for key in System.ID_LOOKUP[category]: 50 val = System.ID_LOOKUP[category][key] 51 new_val = val.replace( 52 "<inventory_root>", obmc.inventory.INVENTORY_ROOT) 53 System.ID_LOOKUP[category][key] = new_val 54 55 self.SystemStateHandler(System.SYSTEM_STATES[0]) 56 57 print "SystemManager Init Done" 58 59 def chassisPowerStateHandler(self, interface_name, changed_properties, 60 invalidated_properties): 61 value = changed_properties.get('state') 62 if value is not None: 63 self.write_to_disk_and_update(str(value)) 64 65 def SystemStateHandler(self, state_name): 66 print "Running System State: "+state_name 67 68 self.Set(DBUS_NAME, "current_state", state_name) 69 70 waitlist = System.EXIT_STATE_DEPEND.get(state_name, {}).keys() 71 if waitlist: 72 self.waiter = obmc.mapper.utils.Wait( 73 self.bus, waitlist, 74 callback=self.gotoNextState) 75 76 def gotoNextState(self): 77 s = 0 78 current_state = self.Get(DBUS_NAME, "current_state") 79 for i in range(len(System.SYSTEM_STATES)): 80 if (System.SYSTEM_STATES[i] == current_state): 81 s = i+1 82 83 if (s == len(System.SYSTEM_STATES)): 84 print "ERROR SystemManager: No more system states" 85 else: 86 new_state_name = System.SYSTEM_STATES[s] 87 print "SystemManager Goto System State: "+new_state_name 88 self.SystemStateHandler(new_state_name) 89 90 def import_system_state_from_disk(self): 91 state = str(POWER_OFF) 92 try: 93 with open(SYS_STATE_FILE, 'r+') as f: 94 state = f.readline().rstrip('\n') 95 except IOError: 96 pass 97 self.Set(DBUS_NAME, "system_last_state", state) 98 return state 99 100 def write_to_disk_and_update(self, state): 101 try: 102 with open(SYS_STATE_FILE, 'w+') as f: 103 f.write(str(state)) 104 self.Set(DBUS_NAME, "system_last_state", state) 105 except IOError: 106 pass 107 108 @dbus.service.method(DBUS_NAME, in_signature='', out_signature='s') 109 def getSystemState(self): 110 return self.Get(DBUS_NAME, "current_state") 111 112 def doObjectLookup(self, category, key): 113 obj_path = "" 114 intf_name = INTF_ITEM 115 try: 116 obj_path = System.ID_LOOKUP[category][key] 117 parts = obj_path.split('/') 118 if (parts[3] == 'sensors'): 119 intf_name = INTF_SENSOR 120 except Exception as e: 121 print "ERROR SystemManager: "+str(e)+" not found in lookup" 122 123 return [obj_path, intf_name] 124 125 @dbus.service.method(DBUS_NAME, in_signature='ss', out_signature='(ss)') 126 def getObjectFromId(self, category, key): 127 return self.doObjectLookup(category, key) 128 129 @dbus.service.method(DBUS_NAME, in_signature='sy', out_signature='(ss)') 130 def getObjectFromByteId(self, category, key): 131 byte = int(key) 132 return self.doObjectLookup(category, byte) 133 134 # Get the FRU area names defined in ID_LOOKUP table given a fru_id. 135 # If serval areas are defined for a fru_id, the areas are returned 136 # together as a string with each area name seperated with ','. 137 # If no fru area defined in ID_LOOKUP, an empty string will be returned. 138 @dbus.service.method(DBUS_NAME, in_signature='y', out_signature='s') 139 def getFRUArea(self, fru_id): 140 ret_str = '' 141 fru_id = '_' + str(fru_id) 142 area_list = [ 143 area for area in System.ID_LOOKUP['FRU_STR'].keys() 144 if area.endswith(fru_id)] 145 for area in area_list: 146 ret_str = area + ',' + ret_str 147 # remove the last ',' 148 return ret_str[:-1] 149 150 def NewObjectHandler(self, obj_path, iprops, bus_name=None): 151 current_state = self.Get(DBUS_NAME, "current_state") 152 if current_state not in System.EXIT_STATE_DEPEND: 153 return 154 155 if obj_path in System.EXIT_STATE_DEPEND[current_state]: 156 print "New object: "+obj_path+" ("+bus_name+")" 157 158 @dbus.service.method(DBUS_NAME, in_signature='s', out_signature='sis') 159 def gpioInit(self, name): 160 gpio_path = '' 161 gpio_num = -1 162 r = ['', gpio_num, ''] 163 if name not in System.GPIO_CONFIG: 164 # TODO: Better error handling 165 msg = "ERROR: "+name+" not found in GPIO config table" 166 print msg 167 raise Exception(msg) 168 else: 169 170 gpio_num = -1 171 gpio = System.GPIO_CONFIG[name] 172 if 'gpio_num' in System.GPIO_CONFIG[name]: 173 gpio_num = gpio['gpio_num'] 174 else: 175 if 'gpio_pin' in System.GPIO_CONFIG[name]: 176 gpio_num = obmc.system.convertGpio(gpio['gpio_pin']) 177 else: 178 msg = "ERROR: SystemManager - GPIO lookup failed for "+name 179 print msg 180 raise Exception(msg) 181 182 if (gpio_num != -1): 183 r = [obmc.enums.GPIO_DEV, gpio_num, gpio['direction']] 184 return r 185 186 @dbus.service.method(DBUS_NAME, in_signature='', 187 out_signature='ssa(sb)a(sb)') 188 def getPowerConfiguration(self): 189 power_good_in = System.POWER_CONFIG.get('power_good_in', '') 190 latch_out = System.POWER_CONFIG.get('latch_out', '') 191 power_up_outs = System.POWER_CONFIG.get('power_up_outs', []) 192 reset_outs = System.POWER_CONFIG.get('reset_outs', []) 193 r = [power_good_in, latch_out, power_up_outs, reset_outs] 194 print "Power GPIO config: " + str(r) 195 return r 196 197 198if __name__ == '__main__': 199 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 200 bus = get_dbus() 201 obj = SystemManager(bus, OBJ_NAME) 202 mainloop = gobject.MainLoop() 203 obj.unmask_signals() 204 name = dbus.service.BusName(DBUS_NAME, bus) 205 206 print "Running SystemManager" 207 mainloop.run() 208 209# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 210