#!/usr/bin/python import sys import dbus import json import xml.etree.ElementTree as ET def fix_byte(it, key, parent): if (isinstance(it, dbus.Array)): for i in range(0, len(it)): fix_byte(it[i], i, it) elif (isinstance(it, dict)): for key in it.keys(): fix_byte(it[key], key, it) elif (isinstance(it, dbus.Byte)): if (key != None): parent[key] = int(it) elif (isinstance(it, dbus.Double)): if (key != None): parent[key] = float(it) else: pass def merge_interfaces(objs): for op in objs: merged = {} for interface, properties in objs[op].items(): merged.update(properties) del objs[op] objs[op] = merged def printDict(name, data): if (isinstance(data, dict)): print ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" print name for p in sorted(data.keys()): printDict(p, data[p]) else: print name + " = " + str(data) def introspect(bus_name, obj_path, intf_name, method_name): obj = bus.get_object(bus_name, obj_path) introspect_iface = dbus.Interface(obj, "org.freedesktop.DBus.Introspectable") tree = ET.ElementTree(ET.fromstring(introspect_iface.Introspect())) # print method_name # print introspect_iface.Introspect() root = tree.getroot() found = False for node in root.iter('node'): for intf in node.iter('interface'): if (intf.attrib['name'] == intf_name): for method in intf.iter('method'): if (method.attrib['name'] == method_name): for ar in method.iter('arg'): if (ar.attrib['direction'] == "in"): print "\t" + ar.attrib['name'] + " (" + \ ar.attrib['type'] + ")" found = True return found dbus_objects = { 'power': { 'bus_name': 'org.openbmc.control.Power', 'object_name': '/org/openbmc/control/power0', 'interface_name': 'org.openbmc.control.Power' }, 'chassis': { 'bus_name': 'org.openbmc.control.Chassis', 'object_name': '/org/openbmc/control/chassis0', 'interface_name': 'org.openbmc.control.Chassis' }, 'poweron': { 'bus_name': 'xyz.openbmc_project.State.Host', 'object_name': '/xyz/openbmc_project/state/host0', 'interface_name': 'xyz.openbmc_project.State.Host', 'property': 'RequestedHostTransition', 'value': 'xyz.openbmc_project.State.Host.Transition.On' }, 'poweroff': { 'bus_name': 'xyz.openbmc_project.State.Host', 'object_name': '/xyz/openbmc_project/state/host0', 'interface_name': 'xyz.openbmc_project.State.Host', 'property': 'RequestedHostTransition', 'value': 'xyz.openbmc_project.State.Host.Transition.Off' }, 'bmcstate': { 'bus_name': 'xyz.openbmc_project.State.BMC', 'object_name': '/xyz/openbmc_project/state/bmc0', 'interface_name': 'xyz.openbmc_project.State.BMC', 'property': 'CurrentBMCState', }, 'chassisstate': { 'bus_name': 'xyz.openbmc_project.State.Chassis', 'object_name': '/xyz/openbmc_project/state/chassis0', 'interface_name': 'xyz.openbmc_project.State.Chassis', 'property': 'CurrentPowerState', }, 'hoststate': { 'bus_name': 'xyz.openbmc_project.State.Host', 'object_name': '/xyz/openbmc_project/state/host0', 'interface_name': 'xyz.openbmc_project.State.Host', 'property': 'CurrentHostState', }, 'bootprogress': { 'bus_name': 'org.openbmc.Sensors', 'object_name': '/org/openbmc/sensors/host/BootProgress', 'interface_name': 'org.openbmc.SensorValue' }, 'biosupdate': { 'bus_name': 'org.openbmc.control.Flash', 'object_name': '/org/openbmc/control/flash/bios', 'interface_name': 'org.openbmc.Flash', 'method': 'updateViaTftp', }, 'biosflash': { 'bus_name': 'org.openbmc.control.Flash', 'object_name': '/org/openbmc/control/flash/bios', 'interface_name': 'org.openbmc.Flash', }, 'bmcupdate': { 'bus_name': 'org.openbmc.control.BmcFlash', 'object_name': '/org/openbmc/control/flash/bmc', 'interface_name': 'org.openbmc.control.BmcFlash', 'method': 'updateViaTftp', }, 'bmcflash': { 'bus_name': 'org.openbmc.control.BmcFlash', 'object_name': '/org/openbmc/control/flash/bmc', 'interface_name': 'org.openbmc.control.BmcFlash', }, 'getinventory': { 'bus_name': 'org.openbmc.Inventory', 'object_name': '/org/openbmc/inventory', 'interface_name': 'org.freedesktop.DBus.ObjectManager', 'method': 'GetManagedObjects', 'transform': merge_interfaces }, 'getsensors': { 'bus_name': 'org.openbmc.Sensors', 'object_name': '/org/openbmc/sensors', 'interface_name': 'org.freedesktop.DBus.ObjectManager', 'method': 'GetManagedObjects', 'transform': merge_interfaces }, 'host': { 'bus_name': 'org.openbmc.control.Host', 'object_name': '/org/openbmc/control/host0', 'interface_name': 'org.openbmc.control.Host', }, 'setdebugmode': { 'bus_name': 'org.openbmc.control.Host', 'object_name': '/org/openbmc/control/host0', 'interface_name': 'org.openbmc.control.Host', 'property': 'debug_mode' }, } # Commands that need to run multiple objects above multicmd_objects = { 'state' : ['bmcstate', 'chassisstate', 'hoststate'] } bus = dbus.SystemBus() if (len(sys.argv) == 1 or sys.argv[1] == "-h" or (not(dbus_objects.has_key(sys.argv[1])) and (not(multicmd_objects.has_key(sys.argv[1]))))): print "Usage: obmcutil [command] [[method] [*args]]" print "\tIf [method] is blank, then all properties are printed\n" print "Available commands:" for name in sorted(dbus_objects.keys()): m = "" if (dbus_objects[name].has_key('method') == True): m = " (" + dbus_objects[name]['interface_name'] + "->" + \ dbus_objects[name]['method'] + ")" elif (dbus_objects[name].has_key('property') == True): m = " (" + dbus_objects[name]['interface_name'] + "->" + \ dbus_objects[name]['property'] + ")" print "\t" + name + m print "Multi-Commands:" for name in sorted(multicmd_objects.keys()): print "\t" + name + " -> " + ",".join(multicmd_objects[name]) exit(0) method_name = "" property_name = "" sys.argv.pop(0) cmd = [sys.argv.pop(0)] # Check if this is a multicmd command and update if it is if(multicmd_objects.has_key(cmd[0])): cmd = multicmd_objects[cmd[0]] for c in cmd: objinfo = dbus_objects[c] if (objinfo.has_key('method')): method_name = objinfo['method'] elif (objinfo.has_key('property')): property_name = objinfo['property'] elif (len(sys.argv) > 0): ## if command line args left and method not specified ## then next arg must be method name method_name = sys.argv.pop(0) bus_name = objinfo['bus_name'] obj_path = objinfo['object_name'] intf_name = objinfo['interface_name'] obj = bus.get_object(bus_name, obj_path) if (method_name != ""): methd = obj.get_dbus_method(method_name, intf_name) try: data = methd(*sys.argv) fix_byte(data, None, None) pydata = json.loads(json.dumps(data)) if 'transform' in objinfo: objinfo['transform'](pydata) printDict("", pydata) except Exception as e: print e r = introspect(bus_name, obj_path, intf_name, method_name) if (r == False): print "ERROR: Invalid method: " + method_name else: print "ERROR: Incorrect arguments passed to method" elif (property_name != ""): intf = dbus.Interface(obj, "org.freedesktop.DBus.Properties") if (objinfo.has_key('value')): property_value = objinfo['value'] else: if(len(sys.argv) > 0): property_value = eval(sys.argv.pop(0)) else: property_value = None if(property_value is not None): intf.Set(intf_name, property_name, property_value) else: prop = intf.Get(intf_name,property_name) print '{:<20}'.format(property_name+": ") + str(prop) else: intf = dbus.Interface(obj, "org.freedesktop.DBus.Properties") props = intf.GetAll(intf_name) for p in props: print p + " = " + str(props[p])