Skip to content

Commit

Permalink
fields: add support for 6bitascii string fields
Browse files Browse the repository at this point in the history
Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>
  • Loading branch information
hthiery committed Jul 12, 2023
1 parent e8f7380 commit 2f8cb4a
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 5 deletions.
18 changes: 15 additions & 3 deletions pyipmi/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ def version_to_string(self):
return ''.join("%s.%s" % (self.major, self.minor))


def _unpack6bitascii(data):
"""Unpack the 6bit ascii encoded string."""
string = ''
for i in range(0, len(data), 3):
d = data[i:i+3]
string += chr(0x20 + (d[0] & 0x3f))
string += chr(0x20 + (((d[0] & 0xc0) >> 6) | ((d[1] & 0xf) << 2)))
string += chr(0x20 + (((d[1] & 0xf0) >> 4) | ((d[2] & 0x3) << 4)))
string += chr(0x20 + ((d[2] & 0xfc) >> 2))
return string


class TypeLengthString(object):
"""
This is the TYPE/LENGTH BYTE FORMAT field represenation according the
Expand Down Expand Up @@ -82,12 +94,12 @@ def _from_data(self, data, offset=0, force_lang_eng=False):

self.raw = data[offset+1:offset+1+self.length]

chr_data = ''.join([chr(c) for c in self.raw])
if self.field_type == self.TYPE_BCD_PLUS:
self.string = chr_data.decode('bcd+')
self.string = self.raw.decode('bcd+')
elif self.field_type == self.TYPE_6BIT_ASCII:
self.string = chr_data.decode('6bitascii')
self.string = _unpack6bitascii(self.raw)
else:
chr_data = ''.join([chr(c) for c in self.raw])
self.string = chr_data


Expand Down
7 changes: 6 additions & 1 deletion tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import pytest

from pyipmi.fields import VersionField
from pyipmi.fields import (VersionField, FruTypeLengthString)
from pyipmi.errors import DecodingError


Expand All @@ -26,3 +26,8 @@ def test_versionfield_invalid():
def test_versionfield_decoding_error():
with pytest.raises(DecodingError):
version = VersionField('\x00\x9a') # noqa:F841


def test_FruTypeLengthString_6bitascii():
f = FruTypeLengthString(b'\x83d\xc9\xb2\xde', 0)
assert f.string == 'DELL'
11 changes: 10 additions & 1 deletion tests/test_fru.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import os

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


def test_frudata_object():
Expand Down Expand Up @@ -63,3 +64,11 @@ def test_multirecord_with_power_module_capability_record():
record = fru.multirecord_area.records[0]
assert isinstance(record, FruPicmgPowerModuleCapabilityRecord)
assert record.maximum_current_output == 42.0


def test_BoardInfoArea():
area = InventoryBoardInfoArea(b'\x01\t\x00\x00\x00\x00\x83d\xc9\xb2\xdePowerEdge R515 \xceCN717033AI0058\xc90RMRF7A05A\x03\xc1\x00\x00*')
assert area.manufacturer.string == 'DELL'
assert area.product_name.string == 'PowerEdge R515 '
assert area.serial_number.string == 'CN717033AI0058'
assert area.part_number.string == '0RMRF7A05'

0 comments on commit 2f8cb4a

Please sign in to comment.