450 lines
14 KiB
Python
450 lines
14 KiB
Python
|
#!/usr/bin/python3
|
||
|
import binascii
|
||
|
|
||
|
|
||
|
class OnietlvException(Exception):
|
||
|
def __init__(self, message='onietlverror', code=-100):
|
||
|
err = 'errcode: {0} message:{1}'.format(code, message)
|
||
|
Exception.__init__(self, err)
|
||
|
self.code = code
|
||
|
self.message = message
|
||
|
|
||
|
|
||
|
class onie_tlv(object):
|
||
|
TLV_INFO_ID_STRING = "TlvInfo\x00"
|
||
|
TLV_INFO_INIA_ID = "\x00\x00\x13\x11"
|
||
|
TLV_INFO_VERSION = 0x01
|
||
|
TLV_INFO_LENGTH = 0x00
|
||
|
TLV_INFO_LENGTH_VALUE = 0xba
|
||
|
|
||
|
TLV_CODE_PRODUCT_NAME = 0x21
|
||
|
TLV_CODE_PART_NUMBER = 0x22
|
||
|
TLV_CODE_SERIAL_NUMBER = 0x23
|
||
|
TLV_CODE_MAC_BASE = 0x24
|
||
|
TLV_CODE_MANUF_DATE = 0x25
|
||
|
TLV_CODE_DEVICE_VERSION = 0x26
|
||
|
TLV_CODE_LABEL_REVISION = 0x27
|
||
|
TLV_CODE_PLATFORM_NAME = 0x28
|
||
|
TLV_CODE_ONIE_VERSION = 0x29
|
||
|
TLV_CODE_MAC_SIZE = 0x2A
|
||
|
TLV_CODE_MANUF_NAME = 0x2B
|
||
|
TLV_CODE_MANUF_COUNTRY = 0x2C
|
||
|
TLV_CODE_VENDOR_NAME = 0x2D
|
||
|
TLV_CODE_DIAG_VERSION = 0x2E
|
||
|
TLV_CODE_SERVICE_TAG = 0x2F
|
||
|
TLV_CODE_VENDOR_EXT = 0xFD
|
||
|
TLV_CODE_CRC_32 = 0xFE
|
||
|
_TLV_DISPLAY_VENDOR_EXT = 1
|
||
|
TLV_CODE_RJ_CARID = 0x01
|
||
|
_TLV_INFO_HDR_LEN = 11
|
||
|
TLV_CODE_PRODUCT_ID = 0x40
|
||
|
TLV_CODE_HW_VERSION = 0x41
|
||
|
TLV_CODE_MAIN_FILENAME = 0x42
|
||
|
TLV_CODE_DTS_FINENAME = 0x43
|
||
|
TLV_CODE_SY_SERIAL0 = 0x44
|
||
|
TLV_CODE_SY_SERIAL1 = 0x45
|
||
|
TLV_CODE_SY_SERIAL2 = 0x46
|
||
|
TLV_CODE_SY_SERIAL3 = 0x47
|
||
|
TLV_CODE_PROJECT_ID = 0x48
|
||
|
TLV_CODE_SETMAC_VERSION = 0x49
|
||
|
TLV_CODE_EEPROM_TYPE = 0x4A
|
||
|
|
||
|
@property
|
||
|
def dstatus(self):
|
||
|
return self._dstatus
|
||
|
|
||
|
@property
|
||
|
def cardid(self):
|
||
|
return self._cardid
|
||
|
|
||
|
@property
|
||
|
def productname(self):
|
||
|
return self._productname
|
||
|
|
||
|
@property
|
||
|
def partnum(self):
|
||
|
return self._partnum
|
||
|
|
||
|
@property
|
||
|
def serialnum(self):
|
||
|
return self._serialnum
|
||
|
|
||
|
@property
|
||
|
def macbase(self):
|
||
|
return self._macbase
|
||
|
|
||
|
@property
|
||
|
def manufdate(self):
|
||
|
return self._manufdate
|
||
|
|
||
|
@property
|
||
|
def deviceversion(self):
|
||
|
return self._deviceversion
|
||
|
|
||
|
@property
|
||
|
def labelrevision(self):
|
||
|
return self._labelrevision
|
||
|
|
||
|
@property
|
||
|
def platformname(self):
|
||
|
return self._platformname
|
||
|
|
||
|
@property
|
||
|
def onieversion(self):
|
||
|
return self._onieversion
|
||
|
|
||
|
@property
|
||
|
def macsize(self):
|
||
|
return self._macsize
|
||
|
|
||
|
@property
|
||
|
def manufname(self):
|
||
|
return self._manufname
|
||
|
|
||
|
@property
|
||
|
def manufcountry(self):
|
||
|
return self._manufcountry
|
||
|
|
||
|
@property
|
||
|
def vendorname(self):
|
||
|
return self._vendorname
|
||
|
|
||
|
@property
|
||
|
def diagname(self):
|
||
|
return self._diagname
|
||
|
|
||
|
@property
|
||
|
def servicetag(self):
|
||
|
return self._servicetag
|
||
|
|
||
|
@property
|
||
|
def vendorext(self):
|
||
|
return self._vendorext
|
||
|
|
||
|
@property
|
||
|
def fanbus(self):
|
||
|
return self._fanbus
|
||
|
|
||
|
@property
|
||
|
def fanloc(self):
|
||
|
return self._fanloc
|
||
|
|
||
|
def __init__(self):
|
||
|
self._cardid = ""
|
||
|
self._productname = ""
|
||
|
self._partnum = ""
|
||
|
self._serialnum = ""
|
||
|
self._macbase = ""
|
||
|
self._manufdate = ""
|
||
|
self._deviceversion = ""
|
||
|
self._labelrevision = ""
|
||
|
self._platformname = ""
|
||
|
self._onieversion = ""
|
||
|
self._macsize = ""
|
||
|
self._manufname = ""
|
||
|
self._manufcountry = ""
|
||
|
self._vendorname = ""
|
||
|
self._diagname = ""
|
||
|
self._servicetag = ""
|
||
|
self._vendorext = ""
|
||
|
self._productid = ""
|
||
|
self._hwversion = ""
|
||
|
self._mainfilename = ""
|
||
|
self._dtsfilename = ""
|
||
|
self._syserial0 = ""
|
||
|
self._syserial1 = ""
|
||
|
self._syserial2 = ""
|
||
|
self._syserial3 = ""
|
||
|
self._projectid = ""
|
||
|
self._setmacversion = ""
|
||
|
self._eepromtype = ""
|
||
|
self._crc32 = ""
|
||
|
self._dstatus = 0
|
||
|
|
||
|
def oniecrc32(self, v):
|
||
|
data_array = bytearray()
|
||
|
for x in v:
|
||
|
data_array.append(ord(x))
|
||
|
return '0x%08x' % (binascii.crc32(bytes(data_array)) & 0xffffffff)
|
||
|
|
||
|
def getTLV_BODY(self, type, value):
|
||
|
x = []
|
||
|
temp_t = ""
|
||
|
if type == self.TLV_CODE_MAC_BASE:
|
||
|
arr = value.split(':')
|
||
|
for tt in arr:
|
||
|
temp_t += chr(int(tt, 16))
|
||
|
elif type == self.TLV_CODE_DEVICE_VERSION:
|
||
|
temp_t = chr(value)
|
||
|
elif type == self.TLV_CODE_MAC_SIZE:
|
||
|
temp_t = chr(value >> 8) + chr(value & 0x00ff)
|
||
|
else:
|
||
|
temp_t = value
|
||
|
x.append(chr(type))
|
||
|
x.append(chr(len(temp_t)))
|
||
|
for i in temp_t:
|
||
|
x.append(i)
|
||
|
return x
|
||
|
|
||
|
def generate_ext(self, cardid):
|
||
|
s = "%08x" % cardid
|
||
|
ret = ""
|
||
|
for t in range(0, 4):
|
||
|
ret += chr(int(s[2 * t:2 * t + 2], 16))
|
||
|
ret = chr(0x01) + chr(len(ret)) + ret
|
||
|
return ret
|
||
|
|
||
|
def generate_value(self, _t):
|
||
|
ret = []
|
||
|
for i in self.TLV_INFO_ID_STRING:
|
||
|
ret.append(i)
|
||
|
ret.append(chr(self.TLV_INFO_VERSION))
|
||
|
ret.append(chr(self.TLV_INFO_LENGTH))
|
||
|
ret.append(chr(self.TLV_INFO_LENGTH_VALUE))
|
||
|
|
||
|
total_len = 0
|
||
|
for key in _t:
|
||
|
x = self.getTLV_BODY(key, _t[key])
|
||
|
ret += x
|
||
|
total_len += len(x)
|
||
|
ret[10] = chr(total_len + 6)
|
||
|
|
||
|
ret.append(chr(0xFE))
|
||
|
ret.append(chr(0x04))
|
||
|
s = self.oniecrc32(''.join(ret))
|
||
|
for t in range(0, 4):
|
||
|
ret.append(chr(int(s[2 * t + 2:2 * t + 4], 16)))
|
||
|
totallen = len(ret)
|
||
|
if (totallen < 256):
|
||
|
for left_t in range(0, 256 - totallen):
|
||
|
ret.append(chr(0x00))
|
||
|
return (ret, True)
|
||
|
|
||
|
def decode_tlv(self, e):
|
||
|
tlv_index = 0
|
||
|
tlv_end = len(e)
|
||
|
ret = []
|
||
|
while tlv_index < tlv_end and (tlv_index + 2 + ord(e[tlv_index + 1])) <= len(e):
|
||
|
rt = self.decoder(e[tlv_index:tlv_index + 2 + ord(e[tlv_index + 1])])
|
||
|
ret.append(rt)
|
||
|
if ord(e[tlv_index]) == self.TLV_CODE_CRC_32:
|
||
|
break
|
||
|
tlv_index += ord(e[tlv_index + 1]) + 2
|
||
|
return ret
|
||
|
|
||
|
def decode(self, e):
|
||
|
if e[0:8] != self.TLV_INFO_ID_STRING:
|
||
|
raise OnietlvException("ONIE tlv head info error,not onie tlv type", -1)
|
||
|
total_len = (ord(e[9]) << 8) | ord(e[10])
|
||
|
tlv_index = self._TLV_INFO_HDR_LEN
|
||
|
tlv_end = self._TLV_INFO_HDR_LEN + total_len
|
||
|
if tlv_end > len(e):
|
||
|
raise OnietlvException("ONIE tlv length error", -2)
|
||
|
ret = []
|
||
|
ret = self.decode_tlv(e[tlv_index:tlv_end])
|
||
|
for item in ret:
|
||
|
if item['code'] == self.TLV_CODE_VENDOR_EXT:
|
||
|
if item["value"][0:4] == self.TLV_INFO_INIA_ID:
|
||
|
rt = self.decode_tlv(item["value"][4:])
|
||
|
else:
|
||
|
rt = self.decode_tlv(item["value"][0:])
|
||
|
ret.extend(rt)
|
||
|
return ret
|
||
|
|
||
|
def decoder(self, t):
|
||
|
if ord(t[0]) == self.TLV_CODE_PRODUCT_NAME:
|
||
|
name = "Product Name"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._productname = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_PART_NUMBER:
|
||
|
name = "Part Number"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._partnum = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_SERIAL_NUMBER:
|
||
|
name = "Serial Number"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._serialnum = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_MAC_BASE:
|
||
|
name = "Base MAC Address"
|
||
|
_len = ord(t[1])
|
||
|
value = ":".join(['%02X' % ord(T) for T in t[2:8]]).upper()
|
||
|
self._macbase = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_MANUF_DATE:
|
||
|
name = "Manufacture Date"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._manufdate = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_DEVICE_VERSION:
|
||
|
name = "Device Version"
|
||
|
_len = ord(t[1])
|
||
|
value = ord(t[2])
|
||
|
self._deviceversion = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_LABEL_REVISION:
|
||
|
name = "Label Revision"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._labelrevision = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_PLATFORM_NAME:
|
||
|
name = "Platform Name"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._platformname = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_ONIE_VERSION:
|
||
|
name = "ONIE Version"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._onieversion = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_MAC_SIZE:
|
||
|
name = "MAC Addresses"
|
||
|
_len = ord(t[1])
|
||
|
value = str((ord(t[2]) << 8) | ord(t[3]))
|
||
|
self._macsize = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_MANUF_NAME:
|
||
|
name = "Manufacturer"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._manufname = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_MANUF_COUNTRY:
|
||
|
name = "Manufacture Country"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._manufcountry = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_VENDOR_NAME:
|
||
|
name = "Vendor Name"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._vendorname = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_DIAG_VERSION:
|
||
|
name = "Diag Version"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._diagname = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_SERVICE_TAG:
|
||
|
name = "Service Tag"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._servicetag = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_VENDOR_EXT:
|
||
|
name = "Vendor Extension"
|
||
|
_len = ord(t[1])
|
||
|
value = ""
|
||
|
if self._TLV_DISPLAY_VENDOR_EXT:
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._vendorext = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_CRC_32 and len(t) == 6:
|
||
|
name = "CRC-32"
|
||
|
_len = ord(t[1])
|
||
|
value = "0x%08X" % (((ord(t[2]) << 24) | (
|
||
|
ord(t[3]) << 16) | (ord(t[4]) << 8) | ord(t[5])),)
|
||
|
self._crc32 = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_RJ_CARID:
|
||
|
name = "Card id"
|
||
|
_len = ord(t[1])
|
||
|
value = ""
|
||
|
for c in t[2:2 + ord(t[1])]:
|
||
|
value += "%02X" % (ord(c),)
|
||
|
self._cardid = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_PRODUCT_ID:
|
||
|
name = "Product id"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._productid = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_HW_VERSION:
|
||
|
name = "Hardware Version"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._hwversion = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_MAIN_FILENAME:
|
||
|
name = "Main File Name"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._mainfilename = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_DTS_FINENAME:
|
||
|
name = "DTS File Name"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._dtsfilename = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_SY_SERIAL0:
|
||
|
name = "SY Serial 0"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._syserial0 = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_SY_SERIAL1:
|
||
|
name = "SY Serial 1"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._syserial1 = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_SY_SERIAL2:
|
||
|
name = "SY Serial 2"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._syserial2 = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_SY_SERIAL3:
|
||
|
name = "SY Serial 3"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._syserial3 = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_PROJECT_ID:
|
||
|
name = "Project id"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._projectid = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_SETMAC_VERSION:
|
||
|
name = "Setmac Version"
|
||
|
_len = ord(t[1])
|
||
|
value = t[2:2 + ord(t[1])]
|
||
|
self._setmacversion = value
|
||
|
elif ord(t[0]) == self.TLV_CODE_EEPROM_TYPE:
|
||
|
name = "EEPROM Type"
|
||
|
_len = ord(t[1])
|
||
|
value = ""
|
||
|
for c in t[2:2 + ord(t[1])]:
|
||
|
value += "%02X" % (ord(c),)
|
||
|
self._eepromtype = value
|
||
|
else:
|
||
|
name = "Unknown"
|
||
|
_len = ord(t[1])
|
||
|
value = ""
|
||
|
for c in t[2:2 + ord(t[1])]:
|
||
|
value += "0x%02X " % (ord(c),)
|
||
|
return {"name": name, "code": ord(t[0]), "value": value, "lens": _len}
|
||
|
|
||
|
def __str__(self):
|
||
|
formatstr = "Card id : %s \n" \
|
||
|
"Product Name : %s \n" \
|
||
|
"Part Number : %s \n" \
|
||
|
"Serial Number : %s \n" \
|
||
|
"Base MAC Address : %s \n" \
|
||
|
"Manufacture Date : %s \n" \
|
||
|
"Device Version : %s \n" \
|
||
|
"Label Revision : %s \n" \
|
||
|
"Platform Name : %s \n" \
|
||
|
"ONIE Version : %s \n" \
|
||
|
"MAC Addresses : %s \n" \
|
||
|
"Manufacturer : %s \n" \
|
||
|
"Manufacture Country : %s \n" \
|
||
|
"Vendor Name : %s \n" \
|
||
|
"Diag Version : %s \n" \
|
||
|
"Service Tag : %s \n" \
|
||
|
"CRC-32 : %s \n"
|
||
|
return formatstr % (self._cardid,
|
||
|
self._productname,
|
||
|
self._partnum,
|
||
|
self._serialnum,
|
||
|
self._macbase,
|
||
|
self._manufdate,
|
||
|
self._deviceversion,
|
||
|
self._labelrevision,
|
||
|
self._platformname,
|
||
|
self._onieversion,
|
||
|
self._macsize,
|
||
|
self._manufname,
|
||
|
self._manufcountry,
|
||
|
self._vendorname,
|
||
|
self._diagname,
|
||
|
self._servicetag,
|
||
|
self._crc32)
|