xref: /openbmc/skeleton/pyipmitest/ipmi_debug.py (revision 7e5ec46d)
1#!/usr/bin/env python
2
3import sys
4import subprocess
5import dbus
6import string
7import os
8import fcntl
9import glib
10import gobject
11import dbus.service
12import dbus.mainloop.glib
13
14DBUS_NAME = 'org.openbmc.HostIpmi'
15OBJ_NAME = '/org/openbmc/HostIpmi/1'
16
17def header(seq, netfn, lun, cmd):
18    return (
19        'seq:   0x%02x\nnetfn: 0x%02x\n\nlun: 0x%02d\ncmd:   0x%02x\n') % (
20            seq, netfn, lun, cmd)
21
22
23def print_request(seq, netfn, lun, cmd, data):
24    str = header(seq, netfn, lun, cmd)
25    str += 'data:  [%s]' % ', '.join(['0x%02x' % x for x in data])
26    print str
27
28def print_response(seq, netfn, lun, cmd, cc, data):
29    str = header(seq, netfn, lun, cmd)
30    str += 'cc:    0x%02x\ndata:  [%s]' % (
31                cc, ', '.join(['0x%02x' % x for x in data])
32            )
33    print str
34
35class IpmiDebug(dbus.service.Object):
36    def __init__(self,bus,name):
37        dbus.service.Object.__init__(self,bus,name)
38
39    @dbus.service.signal(DBUS_NAME, "yyyyay")
40    def ReceivedMessage(self, seq, netfn, lun, cmd, data):
41        print "IPMI packet from host:"
42        print_request(seq, netfn, lun, cmd, data)
43
44    @dbus.service.method(DBUS_NAME, "yyyyyay", "x")
45    def sendMessage(self, seq, netfn, lun, cmd, ccode, data):
46        print "IPMI packet sent to host:"
47        print_response(seq, netfn, lun, cmd, ccode, data)
48        return 0
49
50    @dbus.service.method(DBUS_NAME)
51    def setAttention(self):
52        print "IPMI SMS_ATN set"
53
54class ConsoleReader(object):
55    def __init__(self, ipmi_obj):
56        self.buffer = ''
57        self.seq = 0
58        self.ipmi_obj = ipmi_obj
59        flags = fcntl.fcntl(sys.stdin.fileno(), fcntl.F_GETFL)
60        flags |= os.O_NONBLOCK
61        fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, flags)
62        glib.io_add_watch(sys.stdin, glib.IO_IN, self.io_callback)
63
64    def io_callback(self, fd, condition):
65        chunk = fd.read()
66        for char in chunk:
67            self.buffer += char
68            if char == '\n':
69                self.line(self.buffer)
70                self.buffer = ''
71
72        return True
73
74    def line(self, data):
75        s = data.split(' ')
76        if len(s) < 2:
77            print "Not enough bytes to form a valid IPMI packet"
78            return
79        try:
80            data = [int(c, 16) for c in s]
81        except ValueError:
82            return
83        self.seq += 1
84        self.ipmi_obj.ReceivedMessage(self.seq, data[0], 0, data[1], data[2:])
85
86def main():
87    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
88    bus = dbus.SystemBus()
89    obj = IpmiDebug(bus, OBJ_NAME)
90    mainloop = gobject.MainLoop()
91    r = ConsoleReader(obj)
92
93    obj.unmask_signals()
94    name = dbus.service.BusName(DBUS_NAME, bus)
95
96    print ("Enter IPMI packet as hex values. First three bytes will be used"
97            "as netfn and cmd.\nlun will be zero.")
98    mainloop.run()
99
100if __name__ == '__main__':
101    sys.exit(main())
102
103# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
104