140a360c2SBrad Bishop#!/usr/bin/env python 240a360c2SBrad Bishop 340a360c2SBrad Bishopimport sys 440a360c2SBrad Bishopimport subprocess 540a360c2SBrad Bishopimport dbus 640a360c2SBrad Bishopimport string 740a360c2SBrad Bishopimport os 840a360c2SBrad Bishopimport fcntl 940a360c2SBrad Bishopimport glib 1040a360c2SBrad Bishopimport gobject 1140a360c2SBrad Bishopimport dbus.service 1240a360c2SBrad Bishopimport dbus.mainloop.glib 1340a360c2SBrad Bishop 14*75fe8cc4SPatrick WilliamsDBUS_NAME = "org.openbmc.HostIpmi" 15*75fe8cc4SPatrick WilliamsOBJ_NAME = "/org/openbmc/HostIpmi/1" 1640a360c2SBrad Bishop 1724341f9dSAdriana Kobylak 1840a360c2SBrad Bishopdef header(seq, netfn, lun, cmd): 19*75fe8cc4SPatrick Williams return ("seq: 0x%02x\nnetfn: 0x%02x\n\nlun: 0x%02d\ncmd: 0x%02x\n") % ( 20*75fe8cc4SPatrick Williams seq, 21*75fe8cc4SPatrick Williams netfn, 22*75fe8cc4SPatrick Williams lun, 23*75fe8cc4SPatrick Williams cmd, 24*75fe8cc4SPatrick Williams ) 2540a360c2SBrad Bishop 2640a360c2SBrad Bishop 2740a360c2SBrad Bishopdef print_request(seq, netfn, lun, cmd, data): 2840a360c2SBrad Bishop str = header(seq, netfn, lun, cmd) 29*75fe8cc4SPatrick Williams str += "data: [%s]" % ", ".join(["0x%02x" % x for x in data]) 30*75fe8cc4SPatrick Williams print(str) 3140a360c2SBrad Bishop 3224341f9dSAdriana Kobylak 3340a360c2SBrad Bishopdef print_response(seq, netfn, lun, cmd, cc, data): 3440a360c2SBrad Bishop str = header(seq, netfn, lun, cmd) 35*75fe8cc4SPatrick Williams str += "cc: 0x%02x\ndata: [%s]" % ( 36*75fe8cc4SPatrick Williams cc, 37*75fe8cc4SPatrick Williams ", ".join(["0x%02x" % x for x in data]), 3840a360c2SBrad Bishop ) 39*75fe8cc4SPatrick Williams print(str) 4040a360c2SBrad Bishop 4124341f9dSAdriana Kobylak 4240a360c2SBrad Bishopclass IpmiDebug(dbus.service.Object): 4340a360c2SBrad Bishop def __init__(self, bus, name): 4440a360c2SBrad Bishop dbus.service.Object.__init__(self, bus, name) 4540a360c2SBrad Bishop 4640a360c2SBrad Bishop @dbus.service.signal(DBUS_NAME, "yyyyay") 4740a360c2SBrad Bishop def ReceivedMessage(self, seq, netfn, lun, cmd, data): 48*75fe8cc4SPatrick Williams print("IPMI packet from host:") 4940a360c2SBrad Bishop print_request(seq, netfn, lun, cmd, data) 5040a360c2SBrad Bishop 5140a360c2SBrad Bishop @dbus.service.method(DBUS_NAME, "yyyyyay", "x") 5240a360c2SBrad Bishop def sendMessage(self, seq, netfn, lun, cmd, ccode, data): 53*75fe8cc4SPatrick Williams print("IPMI packet sent to host:") 5440a360c2SBrad Bishop print_response(seq, netfn, lun, cmd, ccode, data) 5540a360c2SBrad Bishop return 0 5640a360c2SBrad Bishop 5740a360c2SBrad Bishop @dbus.service.method(DBUS_NAME) 5840a360c2SBrad Bishop def setAttention(self): 59*75fe8cc4SPatrick Williams print("IPMI SMS_ATN set") 6040a360c2SBrad Bishop 6124341f9dSAdriana Kobylak 6240a360c2SBrad Bishopclass ConsoleReader(object): 6340a360c2SBrad Bishop def __init__(self, ipmi_obj): 64*75fe8cc4SPatrick Williams self.buffer = "" 6540a360c2SBrad Bishop self.seq = 0 6640a360c2SBrad Bishop self.ipmi_obj = ipmi_obj 6740a360c2SBrad Bishop flags = fcntl.fcntl(sys.stdin.fileno(), fcntl.F_GETFL) 6840a360c2SBrad Bishop flags |= os.O_NONBLOCK 6940a360c2SBrad Bishop fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, flags) 7040a360c2SBrad Bishop glib.io_add_watch(sys.stdin, glib.IO_IN, self.io_callback) 7140a360c2SBrad Bishop 7240a360c2SBrad Bishop def io_callback(self, fd, condition): 7340a360c2SBrad Bishop chunk = fd.read() 7440a360c2SBrad Bishop for char in chunk: 7540a360c2SBrad Bishop self.buffer += char 76*75fe8cc4SPatrick Williams if char == "\n": 7740a360c2SBrad Bishop self.line(self.buffer) 78*75fe8cc4SPatrick Williams self.buffer = "" 7940a360c2SBrad Bishop 8040a360c2SBrad Bishop return True 8140a360c2SBrad Bishop 8240a360c2SBrad Bishop def line(self, data): 83*75fe8cc4SPatrick Williams s = data.split(" ") 8440a360c2SBrad Bishop if len(s) < 2: 85*75fe8cc4SPatrick Williams print("Not enough bytes to form a valid IPMI packet") 8640a360c2SBrad Bishop return 8740a360c2SBrad Bishop try: 8840a360c2SBrad Bishop data = [int(c, 16) for c in s] 8940a360c2SBrad Bishop except ValueError: 9040a360c2SBrad Bishop return 9140a360c2SBrad Bishop self.seq += 1 9240a360c2SBrad Bishop self.ipmi_obj.ReceivedMessage(self.seq, data[0], 0, data[1], data[2:]) 9340a360c2SBrad Bishop 9424341f9dSAdriana Kobylak 9540a360c2SBrad Bishopdef main(): 9640a360c2SBrad Bishop dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 9740a360c2SBrad Bishop bus = dbus.SystemBus() 9840a360c2SBrad Bishop obj = IpmiDebug(bus, OBJ_NAME) 9940a360c2SBrad Bishop mainloop = gobject.MainLoop() 10040a360c2SBrad Bishop r = ConsoleReader(obj) 101f0f3efe1SBrad Bishop 102f0f3efe1SBrad Bishop obj.unmask_signals() 10370852a38SBrad Bishop name = dbus.service.BusName(DBUS_NAME, bus) 10440a360c2SBrad Bishop 105*75fe8cc4SPatrick Williams print( 106*75fe8cc4SPatrick Williams "Enter IPMI packet as hex values. First three bytes will be used" 107*75fe8cc4SPatrick Williams "as netfn and cmd.\nlun will be zero." 108*75fe8cc4SPatrick Williams ) 10940a360c2SBrad Bishop mainloop.run() 11040a360c2SBrad Bishop 11124341f9dSAdriana Kobylak 112*75fe8cc4SPatrick Williamsif __name__ == "__main__": 11340a360c2SBrad Bishop sys.exit(main()) 114