1#!/usr/bin/python -u 2 3import sys 4import subprocess 5import gobject 6import dbus 7import dbus.service 8import dbus.mainloop.glib 9import os 10import obmc.dbuslib.propertycacher as PropertyCacher 11from obmc.dbuslib.bindings import DbusProperties, DbusObjectManager, get_dbus 12import obmc.enums 13import obmc_system_config as System 14import obmc.dbuslib.introspection 15import obmc.utils.misc 16import obmc.mapper.utils 17 18DBUS_NAME = 'org.openbmc.managers.System' 19OBJ_NAME = '/org/openbmc/managers/System' 20INTF_SENSOR = 'org.openbmc.SensorValue' 21INTF_ITEM = 'org.openbmc.InventoryItem' 22INTF_CONTROL = 'org.openbmc.Control' 23 24 25class SystemManager(DbusProperties, DbusObjectManager): 26 def __init__(self, bus, obj_name): 27 DbusProperties.__init__(self) 28 DbusObjectManager.__init__(self) 29 dbus.service.Object.__init__(self, bus, 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 self.Set(DBUS_NAME, "current_state", "") 39 self.system_states = {} 40 self.bin_path = os.path.dirname(os.path.realpath(sys.argv[0])) 41 42 for name in System.APPS.keys(): 43 sys_state = System.APPS[name]['system_state'] 44 if sys_state not in self.system_states: 45 self.system_states[sys_state] = [] 46 self.system_states[sys_state].append(name) 47 48 ## replace symbolic path in ID_LOOKUP 49 for category in System.ID_LOOKUP: 50 for key in System.ID_LOOKUP[category]: 51 val = System.ID_LOOKUP[category][key] 52 new_val = val.replace( 53 "<inventory_root>", System.INVENTORY_ROOT) 54 System.ID_LOOKUP[category][key] = new_val 55 56 self.SystemStateHandler(System.SYSTEM_STATES[0]) 57 58 print "SystemManager Init Done" 59 60 def SystemStateHandler(self, state_name): 61 print "Running System State: "+state_name 62 if state_name in self.system_states: 63 for name in self.system_states[state_name]: 64 self.start_process(name) 65 66 try: 67 cb = System.ENTER_STATE_CALLBACK[state_name] 68 for methd in cb.keys(): 69 obj = bus.get_object( 70 cb[methd]['bus_name'], 71 cb[methd]['obj_name'], 72 introspect=False) 73 method = obj.get_dbus_method( 74 methd, cb[methd]['interface_name']) 75 method() 76 except: 77 pass 78 79 self.Set(DBUS_NAME, "current_state", state_name) 80 81 waitlist = System.EXIT_STATE_DEPEND.get(state_name, {}).keys() 82 if waitlist: 83 self.waiter = obmc.mapper.utils.Wait( 84 self.bus, waitlist, 85 callback=self.gotoNextState) 86 87 def gotoNextState(self): 88 s = 0 89 current_state = self.Get(DBUS_NAME, "current_state") 90 for i in range(len(System.SYSTEM_STATES)): 91 if (System.SYSTEM_STATES[i] == current_state): 92 s = i+1 93 94 if (s == len(System.SYSTEM_STATES)): 95 print "ERROR SystemManager: No more system states" 96 else: 97 new_state_name = System.SYSTEM_STATES[s] 98 print "SystemManager Goto System State: "+new_state_name 99 self.SystemStateHandler(new_state_name) 100 101 @dbus.service.method(DBUS_NAME, in_signature='', out_signature='s') 102 def getSystemState(self): 103 return self.Get(DBUS_NAME, "current_state") 104 105 def doObjectLookup(self, category, key): 106 obj_path = "" 107 intf_name = INTF_ITEM 108 try: 109 obj_path = System.ID_LOOKUP[category][key] 110 parts = obj_path.split('/') 111 if (parts[3] == 'sensors'): 112 intf_name = INTF_SENSOR 113 except Exception as e: 114 print "ERROR SystemManager: "+str(e)+" not found in lookup" 115 116 return [obj_path, intf_name] 117 118 @dbus.service.method(DBUS_NAME, in_signature='ss', out_signature='(ss)') 119 def getObjectFromId(self, category, key): 120 return self.doObjectLookup(category, key) 121 122 @dbus.service.method(DBUS_NAME, in_signature='sy', out_signature='(ss)') 123 def getObjectFromByteId(self, category, key): 124 byte = int(key) 125 return self.doObjectLookup(category, byte) 126 127 # Get the FRU area names defined in ID_LOOKUP table given a fru_id. 128 # If serval areas are defined for a fru_id, the areas are returned 129 # together as a string with each area name seperated with ','. 130 # If no fru area defined in ID_LOOKUP, an empty string will be returned. 131 @dbus.service.method(DBUS_NAME, in_signature='y', out_signature='s') 132 def getFRUArea(self, fru_id): 133 ret_str = '' 134 fru_id = '_' + str(fru_id) 135 area_list = [ 136 area for area in System.ID_LOOKUP['FRU_STR'].keys() 137 if area.endswith(fru_id)] 138 for area in area_list: 139 ret_str = area + ',' + ret_str 140 # remove the last ',' 141 return ret_str[:-1] 142 143 def start_process(self, name): 144 if System.APPS[name]['start_process']: 145 app = System.APPS[name] 146 process_name = self.bin_path+"/"+app['process_name'] 147 cmdline = [] 148 cmdline.append(process_name) 149 if 'args' in app: 150 for a in app['args']: 151 cmdline.append(a) 152 try: 153 print "Starting process: "+" ".join(cmdline)+": "+name 154 if app['monitor_process']: 155 app['popen'] = subprocess.Popen(cmdline) 156 else: 157 subprocess.Popen(cmdline) 158 159 except Exception as e: 160 ## TODO: error 161 print "ERROR: starting process: "+" ".join(cmdline) 162 163 def NewObjectHandler(self, obj_path, iprops, bus_name=None): 164 current_state = self.Get(DBUS_NAME, "current_state") 165 if current_state not in System.EXIT_STATE_DEPEND: 166 return 167 168 if obj_path in System.EXIT_STATE_DEPEND[current_state]: 169 print "New object: "+obj_path+" ("+bus_name+")" 170 171 @dbus.service.method(DBUS_NAME, in_signature='s', out_signature='sis') 172 def gpioInit(self, name): 173 gpio_path = '' 174 gpio_num = -1 175 r = ['', gpio_num, ''] 176 if name not in System.GPIO_CONFIG: 177 # TODO: Error handling 178 print "ERROR: "+name+" not found in GPIO config table" 179 else: 180 181 gpio_num = -1 182 gpio = System.GPIO_CONFIG[name] 183 if 'gpio_num' in System.GPIO_CONFIG[name]: 184 gpio_num = gpio['gpio_num'] 185 else: 186 if 'gpio_pin' in System.GPIO_CONFIG[name]: 187 gpio_num = System.convertGpio(gpio['gpio_pin']) 188 else: 189 print "ERROR: SystemManager - GPIO lookup failed for "+name 190 191 if (gpio_num != -1): 192 r = [obmc.enums.GPIO_DEV, gpio_num, gpio['direction']] 193 return r 194 195 196if __name__ == '__main__': 197 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 198 bus = get_dbus() 199 obj = SystemManager(bus, OBJ_NAME) 200 mainloop = gobject.MainLoop() 201 obj.unmask_signals() 202 name = dbus.service.BusName(DBUS_NAME, bus) 203 204 print "Running SystemManager" 205 mainloop.run() 206