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