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