Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | from BaseHTTPServer import BaseHTTPRequestHandler |
| 4 | import urlparse |
| 5 | import dbus |
| 6 | import json |
| 7 | import re |
| 8 | import xml.etree.ElementTree as ET |
| 9 | |
| 10 | def parseIntrospection(obj,interface,method=None): |
| 11 | introspect_iface = dbus.Interface(obj,"org.freedesktop.DBus.Introspectable") |
| 12 | tree = ET.ElementTree(ET.fromstring(introspect_iface.Introspect())) |
| 13 | root = tree.getroot() |
| 14 | r = [] |
| 15 | for intf in root.iter('interface'): |
| 16 | if (intf.attrib['name'] == interface): |
| 17 | for methd in intf.iter('method'): |
| 18 | if (method == None): |
| 19 | r.append(methd.attrib['name']) |
| 20 | elif (method == methd.attrib['name']): |
| 21 | for arg in methd.iter('arg'): |
| 22 | a = [arg.attrib['name'],arg.attrib['type'],arg.attrib['direction']] |
| 23 | r.append(a) |
| 24 | return r |
| 25 | |
| 26 | def getArgFromSignature(args,signature): |
| 27 | if (signature == 'i'): |
| 28 | return int(args[0]) |
| 29 | elif (signature == 's'): |
| 30 | return args[0]; |
| 31 | |
| 32 | raise Exception("Inavlid signature: "+signature) |
| 33 | |
| 34 | |
| 35 | class GetHandler(BaseHTTPRequestHandler): |
| 36 | def do_GET(self): |
| 37 | url_data = urlparse.urlparse(self.path) |
| 38 | parms = urlparse.parse_qs(url_data.query) |
| 39 | self.objmap = { |
| 40 | 'chassis' : ['org.openbmc.ChassisControl','/org/openbmc/ChassisControl','org.openbmc.ChassisControl'], |
| 41 | 'flash' : ['org.openbmc.Flash.BIOS','/org/openbmc/Flash/BIOS/0','org.openbmc.Flash'], |
| 42 | 'power' : ['org.openbmc.PowerControl','/org/openbmc/PowerControl/0','org.openbmc.PowerControl'] |
| 43 | } |
| 44 | self.sensors = { |
| 45 | '/org/openbmc/Sensors/HostStatus/0' : ['org.openbmc.Sensors.HostStatus','org.openbmc.SensorIntegerSettable',0,""], |
| 46 | '/org/openbmc/Sensors/Temperature/Ambient/0': ['org.openbmc.Sensors.Temperature.Ambient','org.openbmc.SensorInteger',0,""] |
| 47 | } |
| 48 | |
| 49 | |
| 50 | parts = url_data.path.split('/'); |
| 51 | item = parts[1] |
| 52 | |
| 53 | method = '' |
| 54 | if (len(parts) > 2): |
| 55 | method = parts[2] |
| 56 | |
| 57 | code = 403 |
| 58 | payload = {'status': 'error'} |
| 59 | bus = dbus.SessionBus() |
| 60 | |
| 61 | if (item == 'sensors'): |
| 62 | try: |
| 63 | for s in self.sensors.keys(): |
| 64 | obj = bus.get_object(self.sensors[s][0],s) |
| 65 | iface = dbus.Interface(obj,self.sensors[s][1]) |
| 66 | self.sensors[s][2] = iface.getValue() |
| 67 | self.sensors[s][3] = iface.getUnits() |
| 68 | |
| 69 | payload['status'] = 'ok' |
| 70 | payload['sensors'] = self.sensors |
| 71 | code = 200 |
| 72 | except dbus.exceptions.DBusException as e: |
| 73 | payload['error-message'] = e.get_dbus_name() |
| 74 | |
| 75 | elif (self.objmap.has_key(item)): |
| 76 | bus_name = self.objmap[item][0] |
| 77 | obj_name = self.objmap[item][1] |
| 78 | interface = self.objmap[item][2] |
| 79 | try: |
| 80 | obj = bus.get_object(bus_name,obj_name) |
| 81 | |
| 82 | if (method == ''): |
| 83 | payload['available-methods'] = parseIntrospection(obj,interface) |
| 84 | else: |
| 85 | args = parseIntrospection(obj,interface,method) |
| 86 | arg_array = [] |
| 87 | signature_in = '' |
| 88 | signature_out = '' |
| 89 | for a in args: |
| 90 | if (a[2] == 'in'): |
| 91 | if (parms.has_key(a[0]) == False): |
| 92 | raise Exception("Method '"+method+"' requires argument '"+a[0]+"'") |
| 93 | arg_array.append(getArgFromSignature(parms[a[0]],a[1])) |
| 94 | signature_in = signature_in + a[1] |
| 95 | else: |
| 96 | signature_out = a[1] |
| 97 | |
| 98 | rtn = bus.call_blocking(bus_name,obj_name,interface,method,signature_in,arg_array) |
| 99 | |
| 100 | code = 200 |
| 101 | payload['status'] = 'ok' |
| 102 | |
| 103 | except dbus.exceptions.DBusException as e: |
| 104 | payload['error-message'] = str(e) |
| 105 | except Exception as ex: |
| 106 | payload['error-message'] = str(ex) |
| 107 | |
| 108 | else: |
| 109 | payload['status'] = 'ok' |
| 110 | payload['available-commands'] = self.objmap.keys() |
| 111 | |
| 112 | self.send_response(code) |
| 113 | self.send_header('Content-Type', 'application/json') |
| 114 | self.end_headers() |
| 115 | self.wfile.write(json.dumps(payload)) |
| 116 | return |
| 117 | |
| 118 | if __name__ == '__main__': |
| 119 | from BaseHTTPServer import HTTPServer |
| 120 | server = HTTPServer(('', 3000), GetHandler) |
| 121 | print 'Starting server, use <Ctrl-C> to stop' |
| 122 | server.serve_forever() |
| 123 | |