Skip to content

Commit

Permalink
fru: add decode of VITA fru records
Browse files Browse the repository at this point in the history
- FruVitaChassisIpmbDescriptionRecord
- FruVitaChassisAddressTableRecord

Signed-off-by: Heiko Thiery <[email protected]>
  • Loading branch information
hthiery committed Mar 5, 2024
1 parent fe0c186 commit d10f062
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 5 deletions.
82 changes: 77 additions & 5 deletions pyipmi/fru.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ def _from_data(self, data):


class FruDataMultiRecord(FruData):
MANUFACTURER_ID_PICMG = 0x315A
MANUFACTURER_ID_VITA = 0x81AC
TYPE_POWER_SUPPLY_INFORMATION = 0
TYPE_DC_OUTPUT = 1
TYPE_DC_LOAD = 2
Expand Down Expand Up @@ -333,9 +335,19 @@ def _from_data(self, data):

@staticmethod
def create_from_record_id(data):
if data[0] == FruDataMultiRecord.TYPE_OEM_PICMG:
return FruPicmgRecord.create_from_record_id(data)
else:

if data[0] != 0xc0:
return FruDataUnknown(data)

try:
manufacturer_id = data[5] | data[6] << 8 | data[7] << 16
cls = {
FruDataMultiRecord.MANUFACTURER_ID_PICMG: FruPicmgRecord,
FruDataMultiRecord.MANUFACTURER_ID_VITA: FruVitaRecord,
}[manufacturer_id]

return cls.create_from_record_id(data)
except IndexError:
return FruDataUnknown(data)


Expand All @@ -345,6 +357,66 @@ class FruDataUnknown(FruDataMultiRecord):
pass


class FruVitaRecord(FruDataMultiRecord):
VITA_RECORD_ID_CHASSIS_ADDRESS_TABLE = 0x10
VITA_RECORD_ID_CHASSIS_MANAGER_IP_CONNECTION = 0x13
VITA_RECORD_ID_RADIAL_SYSTEM_IPMB_LINK_MAP = 0x15
VITA_RECORD_ID_CHASSIS_FAN_GEOGRAPHY = 0x1b
VITA_RECORD_ID_LED_DESCRIPTION = 0x2f
VITA_RECORD_ID_CHASSIS_IPMB_DESCRIPTION = 0x30

def __init__(self, data):
FruDataMultiRecord.__init__(self, data)

@staticmethod
def create_from_record_id(data):
record = FruVitaRecord(data)

if record.record_id ==\
FruVitaRecord.VITA_RECORD_ID_CHASSIS_IPMB_DESCRIPTION:
return FruVitaChassisIpmbDescriptionRecord(data)
elif record.record_id ==\
FruVitaRecord.VITA_RECORD_ID_CHASSIS_ADDRESS_TABLE:
return FruVitaChassisAddressTableRecord(data)

return FruPicmgRecord(data)

def _from_data(self, data):
if len(data) < 10:
raise DecodingError('data too short')
data = array.array('B', data)
FruDataMultiRecord._from_data(self, data)
self.manufacturer_id = \
data[5] | data[6] << 8 | data[7] << 16
self.record_id = data[8]
self.format_version = data[9]


class FruVitaChassisAddressTableRecord(FruVitaRecord):
def _from_data(self, data):
if len(data) < 11:
raise DecodingError('data too short')
FruVitaRecord._from_data(self, data)

self.identifier = FruTypeLengthString(data[10:31])
self.entry_count = data[31]
self.table = list()
for idx in range(0, self.entry_count):
entry = (data[32+(idx*3)], data[32+(idx*3)+1], data[32+(idx*3) + 2])
self.table.append(entry)


class FruVitaChassisIpmbDescriptionRecord(FruVitaRecord):
def _from_data(self, data):
if len(data) < 11:
raise DecodingError('data too short')
FruVitaRecord._from_data(self, data)
self.ipmb_a_supported = True if data[10] & 0x1 else False
self.ipmb_b_supported = True if data[10] & 0x2 else False
self.ipmb_a_max_freq = (data[10] & 0x0c) >> 2
self.ipmb_b_max_freq = (data[10] & 0x30) >> 4


class FruPicmgRecord(FruDataMultiRecord):
PICMG_RECORD_ID_BACKPLANE_PTP_CONNECTIVITY = 0x04
PICMG_RECORD_ID_ADDRESS_TABLE = 0x10
Expand Down Expand Up @@ -380,7 +452,7 @@ def __init__(self, data):
@staticmethod
def create_from_record_id(data):
picmg_record = FruPicmgRecord(data)
if picmg_record.picmg_record_type_id ==\
if picmg_record.record_id ==\
FruPicmgRecord.PICMG_RECORD_ID_MTCA_POWER_MODULE_CAPABILITY:
return FruPicmgPowerModuleCapabilityRecord(data)

Expand All @@ -393,7 +465,7 @@ def _from_data(self, data):
FruDataMultiRecord._from_data(self, data)
self.manufacturer_id = \
data[5] | data[6] << 8 | data[7] << 16
self.picmg_record_type_id = data[8]
self.record_id = data[8]
self.format_version = data[9]


Expand Down
40 changes: 40 additions & 0 deletions tests/test_fru.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from pyipmi.fru import (FruData, FruPicmgPowerModuleCapabilityRecord,
InventoryCommonHeader, InventoryBoardInfoArea,
FruVitaRecord, FruVitaChassisIpmbDescriptionRecord,
FruVitaChassisAddressTableRecord,
get_fru_inventory_from_file)


Expand Down Expand Up @@ -72,3 +74,41 @@ def test_BoardInfoArea():
assert area.product_name.string == 'PowerEdge R515 '
assert area.serial_number.string == 'CN717033AI0058'
assert area.part_number.string == '0RMRF7A05'


def test_FruVitaChassisIpmbDescription():
record = FruVitaRecord.create_from_record_id(b'\xc0\x82\x06\x8c\x2c\xac\x81\x00\x30\x00\x17')
assert record.ipmb_a_supported == True
assert record.ipmb_b_supported == True
assert record.ipmb_a_max_freq == 1
assert record.ipmb_b_max_freq == 1

record = FruVitaChassisIpmbDescriptionRecord(b'\xc0\x82\x06\x8c\x2c\xac\x81\x00\x30\x00\x17')
assert record.ipmb_a_supported == True
assert record.ipmb_b_supported == True
assert record.ipmb_a_max_freq == 1
assert record.ipmb_b_max_freq == 1


def test_FruVitaChassisAddressTableRecord():
record = FruVitaRecord.create_from_record_id(b'\xc0\x02\x30\x70\x9e\xac\x81\x00\x10\x00\xce\x56\x50\x58\x43\x68\x61\x73\x73\x69\x73\x30\x30\x30\x30\xff\xff\xff\xff\xff\xff\x07\x41\x01\x00\x42\x02\x00\x43\x03\x00\x44\x04\x00\x45\x05\x00\x46\x06\x00\x47\x07\x00')
assert str(record.identifier) == 'VPXChassis0000'
assert record.entry_count == 7
assert record.table[0] == (0x41, 1, 0)
assert record.table[1] == (0x42, 2, 0)
assert record.table[2] == (0x43, 3, 0)
assert record.table[3] == (0x44, 4, 0)
assert record.table[4] == (0x45, 5, 0)
assert record.table[5] == (0x46, 6, 0)
assert record.table[6] == (0x47, 7, 0)

record = FruVitaChassisAddressTableRecord(b'\xc0\x02\x30\x70\x9e\xac\x81\x00\x10\x00\xce\x56\x50\x58\x43\x68\x61\x73\x73\x69\x73\x30\x30\x30\x30\xff\xff\xff\xff\xff\xff\x07\x41\x01\x00\x42\x02\x00\x43\x03\x00\x44\x04\x00\x45\x05\x00\x46\x06\x00\x47\x07\x00')
assert str(record.identifier) == 'VPXChassis0000'
assert record.entry_count == 7
assert record.table[0] == (0x41, 1, 0)
assert record.table[1] == (0x42, 2, 0)
assert record.table[2] == (0x43, 3, 0)
assert record.table[3] == (0x44, 4, 0)
assert record.table[4] == (0x45, 5, 0)
assert record.table[5] == (0x46, 6, 0)
assert record.table[6] == (0x47, 7, 0)

0 comments on commit d10f062

Please sign in to comment.