@@ -88,9 +88,9 @@ def read_fru_data(self, offset=None, count=None, fru_id=0):
88
88
def read_fru_data_full (self , fru_id = 0 ):
89
89
return self .read_fru_data (fru_id = fru_id )
90
90
91
- def get_fru_inventory_header (self , fru_id = 0 ):
91
+ def get_fru_inventory_header (self , fru_id = 0 , ignore_checksum = False ):
92
92
data = self .read_fru_data (offset = 0 , count = 8 , fru_id = fru_id )
93
- return InventoryCommonHeader (data )
93
+ return InventoryCommonHeader (data , ignore_checksum = ignore_checksum )
94
94
95
95
def _read_fru_area (self , offset , fru_id = 0 ):
96
96
# read the area header
@@ -99,26 +99,30 @@ def _read_fru_area(self, offset, fru_id=0):
99
99
count = data [1 ] * 8
100
100
return self .read_fru_data (offset = offset , count = count , fru_id = fru_id )
101
101
102
- def get_fru_chassis_area (self , fru_id = 0 ):
103
- header = self .get_fru_inventory_header (fru_id = fru_id )
102
+ def get_fru_chassis_area (self , fru_id = 0 , ignore_checksum = False ):
103
+ header = self .get_fru_inventory_header (fru_id = fru_id ,
104
+ ignore_checksum = ignore_checksum )
104
105
data = self ._read_fru_area (offset = header .chassis_info_area_offset ,
105
106
fru_id = fru_id )
106
- return InventoryChassisInfoArea (data )
107
+ return InventoryChassisInfoArea (data , ignore_checksum = ignore_checksum )
107
108
108
- def get_fru_board_area (self , fru_id = 0 ):
109
- header = self .get_fru_inventory_header (fru_id = fru_id )
109
+ def get_fru_board_area (self , fru_id = 0 , ignore_checksum = False ):
110
+ header = self .get_fru_inventory_header (fru_id = fru_id ,
111
+ ignore_checksum = ignore_checksum )
110
112
data = self ._read_fru_area (offset = header .board_info_area_offset ,
111
113
fru_id = fru_id )
112
- return InventoryBoardInfoArea (data )
114
+ return InventoryBoardInfoArea (data , ignore_checksum = ignore_checksum )
113
115
114
- def get_fru_product_area (self , fru_id = 0 ):
115
- header = self .get_fru_inventory_header (fru_id = fru_id )
116
+ def get_fru_product_area (self , fru_id = 0 , ignore_checksum = False ):
117
+ header = self .get_fru_inventory_header (fru_id = fru_id ,
118
+ ignore_checksum = ignore_checksum )
116
119
data = self ._read_fru_area (offset = header .product_info_area_offset ,
117
120
fru_id = fru_id )
118
- return InventoryProductInfoArea (data )
121
+ return InventoryProductInfoArea (data , ignore_checksum = ignore_checksum )
119
122
120
- def get_fru_multirecord_area (self , fru_id = 0 ):
121
- header = self .get_fru_inventory_header (fru_id = fru_id )
123
+ def get_fru_multirecord_area (self , fru_id = 0 , ignore_checksum = False ):
124
+ header = self .get_fru_inventory_header (fru_id = fru_id ,
125
+ ignore_checksum = ignore_checksum )
122
126
123
127
# we have to determine the length of the area first
124
128
offset = header .multirecord_area_offset
@@ -137,9 +141,9 @@ def get_fru_multirecord_area(self, fru_id=0):
137
141
# now read the full area
138
142
offset = header .multirecord_area_offset
139
143
data = self .read_fru_data (offset = offset , count = count )
140
- return InventoryMultiRecordArea (data )
144
+ return InventoryMultiRecordArea (data , ignore_checksum = ignore_checksum )
141
145
142
- def get_fru_inventory (self , fru_id = 0 ):
146
+ def get_fru_inventory (self , fru_id = 0 , ignore_checksum = False ):
143
147
"""
144
148
Get the full parsed FRU inventory data.
145
149
"""
@@ -161,7 +165,7 @@ def get_fru_inventory(self, fru_id=0):
161
165
return fru
162
166
163
167
164
- def get_fru_inventory_from_file (filename ):
168
+ def get_fru_inventory_from_file (filename , ignore_checksum = False ):
165
169
try :
166
170
file = open (filename , "rb" )
167
171
except IOError :
@@ -173,7 +177,7 @@ def get_fru_inventory_from_file(filename):
173
177
file_data = file .read (file_size )
174
178
data = array .array ('B' , file_data )
175
179
file .close ()
176
- return FruInventory (data )
180
+ return FruInventory (data , ignore_checksum = ignore_checksum )
177
181
178
182
179
183
CUSTOM_FIELD_END = 0xc1
@@ -190,37 +194,37 @@ def _decode_custom_fields(data):
190
194
191
195
192
196
class FruData (object ):
193
- def __init__ (self , data = None ):
197
+ def __init__ (self , data = None , ignore_checksum = False ):
194
198
if data :
195
199
if isinstance (data , str ):
196
200
data = [ord (c ) for c in data ]
197
201
self .data = data
198
202
if hasattr (self , '_from_data' ):
199
- self ._from_data (data )
203
+ self ._from_data (data , ignore_checksum = ignore_checksum )
200
204
201
205
202
206
class InventoryCommonHeader (FruData ):
203
- def _from_data (self , data ):
204
- if len (data ) != 8 :
207
+ def _from_data (self , data , ignore_checksum = False ):
208
+ if len (data ) < 8 :
205
209
raise DecodingError ('InventoryCommonHeader length != 8' )
206
210
self .format_version = data [0 ] & 0x0f
207
211
self .internal_use_area_offset = data [1 ] * 8 or None
208
212
self .chassis_info_area_offset = data [2 ] * 8 or None
209
213
self .board_info_area_offset = data [3 ] * 8 or None
210
214
self .product_info_area_offset = data [4 ] * 8 or None
211
215
self .multirecord_area_offset = data [5 ] * 8 or None
212
- if sum (data ) % 256 != 0 :
213
- raise DecodingError ('InventoryCommonHeader checksum failed' )
216
+ if sum (data [: 8 ] ) % 256 != 0 and ignore_checksum is False :
217
+ raise DecodingError (f 'InventoryCommonHeader checksum failed { sum ( data ) % 0x10 } ' )
214
218
215
219
216
220
class CommonInfoArea (FruData ):
217
- def _from_data (self , data ):
221
+ def _from_data (self , data , ignore_checksum = False ):
218
222
self .format_version = data [0 ] & 0x0f
219
223
if self .format_version != 1 :
220
224
raise DecodingError ('unsupported format version (%d)' %
221
225
self .format_version )
222
226
self .length = data [1 ] * 8
223
- if sum (data [:self .length ]) % 256 != 0 :
227
+ if sum (data [:self .length ]) % 256 != 0 and ignore_checksum is False :
224
228
raise DecodingError ('checksum failed' )
225
229
226
230
@@ -249,7 +253,7 @@ class InventoryChassisInfoArea(CommonInfoArea):
249
253
TYPE_RAID_CHASSIS = 22
250
254
TYPE_RACK_MOUNT_CHASSIS = 23
251
255
252
- def _from_data (self , data ):
256
+ def _from_data (self , data , ignore_checksum = False ):
253
257
CommonInfoArea ._from_data (self , data )
254
258
self .type = data [2 ]
255
259
offset = 3
@@ -261,8 +265,8 @@ def _from_data(self, data):
261
265
262
266
263
267
class InventoryBoardInfoArea (CommonInfoArea ):
264
- def _from_data (self , data ):
265
- CommonInfoArea ._from_data (self , data )
268
+ def _from_data (self , data , ignore_checksum = False ):
269
+ CommonInfoArea ._from_data (self , data , ignore_checksum = ignore_checksum )
266
270
self .language_code = data [2 ]
267
271
minutes = data [5 ] << 16 | data [4 ] << 8 | data [3 ]
268
272
self .mfg_date = (datetime .datetime (1996 , 1 , 1 )
@@ -282,7 +286,7 @@ def _from_data(self, data):
282
286
283
287
284
288
class InventoryProductInfoArea (CommonInfoArea ):
285
- def _from_data (self , data ):
289
+ def _from_data (self , data , ignore_checksum = False ):
286
290
CommonInfoArea ._from_data (self , data )
287
291
self .language_code = data [2 ]
288
292
offset = 3
@@ -318,17 +322,17 @@ def __str__(self):
318
322
return '%02x: %s' % (self .record_type_id ,
319
323
' ' .join ('%02x' % b for b in self .raw ))
320
324
321
- def _from_data (self , data ):
325
+ def _from_data (self , data , ignore_checksum = False ):
322
326
if len (data ) < 5 :
323
327
raise DecodingError ('data too short' )
324
328
self .record_type_id = data [0 ]
325
329
self .format_version = data [1 ] & 0x0f
326
330
self .end_of_list = bool (data [1 ] & 0x80 )
327
331
self .length = data [2 ]
328
- if sum (data [:5 ]) % 256 != 0 :
332
+ if sum (data [:5 ]) % 256 != 0 and ignore_checksum is False :
329
333
raise DecodingError ('FruDataMultiRecord header checksum failed' )
330
334
self .raw = data [5 :5 + self .length ]
331
- if (sum (self .raw ) + data [3 ]) % 256 != 0 :
335
+ if (sum (self .raw ) + data [3 ]) % 256 != 0 and ignore_checksum is False :
332
336
raise DecodingError ('FruDataMultiRecord record checksum failed' )
333
337
334
338
@staticmethod
@@ -386,19 +390,19 @@ def create_from_record_id(data):
386
390
387
391
return FruPicmgRecord (data )
388
392
389
- def _from_data (self , data ):
393
+ def _from_data (self , data , ignore_checksum = False ):
390
394
if len (data ) < 10 :
391
395
raise DecodingError ('data too short' )
392
396
data = array .array ('B' , data )
393
- FruDataMultiRecord ._from_data (self , data )
397
+ FruDataMultiRecord ._from_data (self , data , ignore_checksum = ignore_checksum )
394
398
self .manufacturer_id = \
395
399
data [5 ] | data [6 ] << 8 | data [7 ] << 16
396
400
self .picmg_record_type_id = data [8 ]
397
401
self .format_version = data [9 ]
398
402
399
403
400
404
class FruPicmgPowerModuleCapabilityRecord (FruPicmgRecord ):
401
- def _from_data (self , data ):
405
+ def _from_data (self , data , ignore_checksum = False ):
402
406
if len (data ) < 12 :
403
407
raise DecodingError ('data too short' )
404
408
FruPicmgRecord ._from_data (self , data )
@@ -407,11 +411,11 @@ def _from_data(self, data):
407
411
408
412
409
413
class InventoryMultiRecordArea (object ):
410
- def __init__ (self , data ):
414
+ def __init__ (self , data , ignore_checksum = False ):
411
415
if data :
412
416
self ._from_data (data )
413
417
414
- def _from_data (self , data ):
418
+ def _from_data (self , data , ignore_checksum = False ):
415
419
self .records = list ()
416
420
offset = 0
417
421
while True :
@@ -423,31 +427,35 @@ def _from_data(self, data):
423
427
424
428
425
429
class FruInventory (object ):
426
- def __init__ (self , data = None ):
430
+ def __init__ (self , data = None , ignore_checksum = False ):
427
431
self .chassis_info_area = None
428
432
self .board_info_area = None
429
433
self .product_info_area = None
430
434
self .multirecord_area = None
431
435
432
436
if data :
433
- self ._from_data (data )
437
+ self ._from_data (data , ignore_checksum = ignore_checksum )
434
438
435
- def _from_data (self , data ):
439
+ def _from_data (self , data , ignore_checksum = False ):
436
440
self .raw = data
437
441
self .common_header = InventoryCommonHeader (data [:8 ])
438
442
439
443
if self .common_header .chassis_info_area_offset :
440
444
self .chassis_info_area = InventoryChassisInfoArea (
441
- data [self .common_header .chassis_info_area_offset :])
445
+ data [self .common_header .chassis_info_area_offset :],
446
+ ignore_checksum = ignore_checksum )
442
447
443
448
if self .common_header .board_info_area_offset :
444
449
self .board_info_area = InventoryBoardInfoArea (
445
- data [self .common_header .board_info_area_offset :])
450
+ data [self .common_header .board_info_area_offset :],
451
+ ignore_checksum = ignore_checksum )
446
452
447
453
if self .common_header .product_info_area_offset :
448
454
self .product_info_area = InventoryProductInfoArea (
449
- data [self .common_header .product_info_area_offset :])
455
+ data [self .common_header .product_info_area_offset :],
456
+ ignore_checksum = ignore_checksum )
450
457
451
458
if self .common_header .multirecord_area_offset :
452
459
self .multirecord_area = InventoryMultiRecordArea (
453
- data [self .common_header .multirecord_area_offset :])
460
+ data [self .common_header .multirecord_area_offset :],
461
+ ignore_checksum = ignore_checksum )
0 commit comments