diff --git a/pyghmi/ipmi/oem/lenovo/firmware.py b/pyghmi/ipmi/oem/lenovo/firmware.py index cab717e5..35854ffd 100644 --- a/pyghmi/ipmi/oem/lenovo/firmware.py +++ b/pyghmi/ipmi/oem/lenovo/firmware.py @@ -34,13 +34,23 @@ firmware_fields = ( inventory.EntryField("DIAG", "16s")) -def parse_firmware_info(raw): +def parse_firmware_info(raw, bios_versions=None): bytes_read, data = inventory.parse_inventory_category_entry( raw, firmware_fields) del data['Revision'] for key in data: yield key, {'version': data[key]} + if bios_versions is not None: + yield ("Bios_bundle_ver", + {'version': bios_versions['new_img_version']}) + yield ("Bios_current_ver", + {'version': bios_versions['cur_img_version']}) + + +def parse_bios_number(raw): + return inventory.parse_bios_number_entry(raw) + def get_categories(): return { @@ -52,5 +62,15 @@ def get_categories(): "command": 0x59, "data": (0x00, 0xc7, 0x00, 0x00) } + }, + "bios_version": { + "idstr": "Bios Version", + "parser": parse_bios_number, + "command": { + "netfn": 0x32, + "command": 0xE8, + "data": (0x01, 0x01, 0x02) + } + } } diff --git a/pyghmi/ipmi/oem/lenovo/handler.py b/pyghmi/ipmi/oem/lenovo/handler.py index 480b8c26..65114e49 100755 --- a/pyghmi/ipmi/oem/lenovo/handler.py +++ b/pyghmi/ipmi/oem/lenovo/handler.py @@ -656,7 +656,17 @@ class OEMHandler(generic.OEMHandler): if self.has_tsm: command = firmware.get_categories()["firmware"] rsp = self.ipmicmd.xraw_command(**command["command"]) - return command["parser"](rsp["data"]) + # the newest Lenovo ThinkServer versions are returning Bios version + # numbers through another command + bios_versions = None + if self.has_tsm: + bios_command = firmware.get_categories()["bios_version"] + bios_rsp = self.ipmicmd.xraw_command(**bios_command["command"]) + bios_versions = bios_command["parser"](bios_rsp["data"]) + + # pass bios versions to firmware parser + return command["parser"](rsp["data"], bios_versions) + elif self.has_imm: return self.immhandler.get_firmware_inventory(bmcver, components) elif self.is_fpc: diff --git a/pyghmi/ipmi/oem/lenovo/inventory.py b/pyghmi/ipmi/oem/lenovo/inventory.py index 248b0e60..11982119 100755 --- a/pyghmi/ipmi/oem/lenovo/inventory.py +++ b/pyghmi/ipmi/oem/lenovo/inventory.py @@ -142,3 +142,33 @@ def parse_inventory_category_entry(raw, fields): if discard: obj = None return bytes_read, obj + + +def parse_bios_number_entry(raw): + """Parses the Bios number given a raw data. + + :param raw: the raw data to the entry. + + :returns: dict -- structure with read current and newest versions + """ + new_major_version = struct.unpack_from("1B", raw, 25)[0] + new_minor_version = struct.unpack_from("1B", raw, 26)[0] + new_aux = struct.unpack_from("I", raw, 27)[0] + + cur_major_version = struct.unpack_from("1B", raw, 31)[0] + cur_minor_version = struct.unpack_from("1B", raw, 32)[0] + cur_aux = struct.unpack_from("I", raw, 33)[0] + + new_image_version = "%s.%s.%s" % ( + str(new_major_version), + str(new_minor_version), + str(new_aux)) + cur_image_version = "%s.%s.%s" % ( + str(cur_major_version), + str(cur_minor_version), + str(cur_aux)) + + return { + 'new_img_version': new_image_version, + 'cur_img_version': cur_image_version + }