#!/usr/bin/python3 # -*- coding: utf-8 -*- class FantlvException(Exception): def __init__(self, message='fantlverror', code=-100): err = 'errcode: {0} message:{1}'.format(code, message) Exception.__init__(self, err) self.code = code self.message = message class fan_tlv(object): HEAD_INFO = "\x01\x7e\x01\xf1" VERSION = 0x01 # E2PROM file init version is 0x01 FLAG = 0x7E #new version E2PROM mark as 0x7E HW_VER = 0X01 # consists of master version and revised version TYPE = 0xf1 # hardware type define TLV_LEN = 00 # vaild data length(16bit) _FAN_TLV_HDR_LEN = 6 _FAN_TLV_CRC_LEN = 2 _FAN_TLV_TYPE_NAME = 0x02 _FAN_TLV_TYPE_SN = 0x03 _FAN_TLV_TYPE_HW_INFO = 0x05 _FAN_TLV_TYPE_DEV_TYPE = 0x06 _fandecodetime = 0 @property def dstatus(self): return self._dstatus @property def typename(self): return self._typename @property def typesn(self): return self._typesn @property def typehwinfo(self): return self._typehwinfo @property def typedevtype(self): return self._typedevtype @property def fanbus(self): return self._fanbus @property def fanloc(self): return self._fanloc @property def fandecodetime(self): return self._fandecodetime def __init__(self): self._typename = "" self._typesn = "" self._typehwinfo = "" self._typedevtype = "" self._dstatus = 0 def strtoarr(self, str): s = [] if str is not None: for index in range(len(str)): s.append(str[index]) return s def str_to_hex(self,rest_v): value = 0 for index in range(len(rest_v)): value |= ord(rest_v[index]) << ((len(rest_v) - index - 1) * 8) return value def hex_to_str(self,s): len_t = len(s) if len_t % 2 != 0: return 0 ret = "" for t in range(0, int(len_t / 2)): ret += chr(int(s[2 * t:2 * t + 2], 16)) return ret def generate_fan_value(self): bin_buffer = [chr(0xff)] * 256 bin_buffer[0] = chr(self.VERSION) bin_buffer[1] = chr(self.FLAG) bin_buffer[2] = chr(self.HW_VER) bin_buffer[3] = chr(self.TYPE) temp_t = "%08x" % self.typedevtype # handle devtype first typedevtype_t = self.hex_to_str(temp_t) total_len = len(self.typename) + len(self.typesn) + \ len(self.typehwinfo) + len(typedevtype_t) + 8 bin_buffer[4] = chr(total_len >> 8) bin_buffer[5] = chr(total_len & 0x00FF) index_start = 6 bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_NAME) bin_buffer[index_start + 1] = chr(len(self.typename)) bin_buffer[index_start + 2: index_start + 2 + len(self.typename)] = self.strtoarr(self.typename) index_start = index_start + 2 + len(self.typename) bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_SN) bin_buffer[index_start + 1] = chr(len(self.typesn)) bin_buffer[index_start + 2:index_start + 2 + len(self.typesn)] = self.strtoarr(self.typesn) index_start = index_start + 2 + len(self.typesn) bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_HW_INFO) bin_buffer[index_start + 1] = chr(len(self.typehwinfo)) bin_buffer[index_start + 2:index_start + 2 + len(self.typehwinfo)] = self.strtoarr(self.typehwinfo) index_start = index_start + 2 + len(self.typehwinfo) bin_buffer[index_start] = chr(self._FAN_TLV_TYPE_DEV_TYPE) bin_buffer[index_start + 1] = chr(len(typedevtype_t)) bin_buffer[index_start + 2:index_start + 2 + len(typedevtype_t)] = self.strtoarr(typedevtype_t) index_start = index_start + 2 + len(typedevtype_t) crcs = fan_tlv.fancrc(''.join(bin_buffer[0:index_start])) # 2bytes checking bin_buffer[index_start] = chr(crcs >> 8) bin_buffer[index_start + 1] = chr(crcs & 0x00ff) # printvalue(bin_buffer) return bin_buffer def decode(self, e2): if e2[0:4] != self.HEAD_INFO: raise FantlvException("Fan tlv head info error,not fan tlv type", -10) ret = [] self.VERSION = ord(e2[0]) self.FLAG = ord(e2[1]) self.HW_VER = ord(e2[2]) self.TYPE = ord(e2[3]) self.TLV_LEN = (ord(e2[4]) << 8) | ord(e2[5]) tlv_index = self._FAN_TLV_HDR_LEN tlv_end = self._FAN_TLV_HDR_LEN + self.TLV_LEN # check sum if len(e2) < self._FAN_TLV_HDR_LEN + self.TLV_LEN + 2: raise FantlvException("Fan tlv eeprom len error!", -2) sumcrc = fan_tlv.fancrc(e2[0:self._FAN_TLV_HDR_LEN + self.TLV_LEN]) readcrc = ord(e2[self._FAN_TLV_HDR_LEN + self.TLV_LEN] ) << 8 | ord(e2[self._FAN_TLV_HDR_LEN + self.TLV_LEN + 1]) if sumcrc != readcrc: raise FantlvException("Fan tlv eeprom checksum error!", -1) else: self._dstatus = 0 while (tlv_index + 2) < len(e2) and tlv_index < tlv_end: s = self.decoder( e2[tlv_index:tlv_index + 2 + ord(e2[tlv_index + 1])]) tlv_index += ord(e2[tlv_index + 1]) + 2 ret.append(s) return ret @staticmethod def fancrc(t): sum = 0 for index in range(len(t)): sum += ord(t[index]) return sum def decoder(self, t): try: name = "" value = "" if ord(t[0]) == self._FAN_TLV_TYPE_NAME: name = "Product Name" _len = ord(t[1]) value = t[2:2 + ord(t[1])] self._typename = value elif ord(t[0]) == self._FAN_TLV_TYPE_SN: name = "serial Number" _len = ord(t[1]) value = t[2:2 + ord(t[1])] self._typesn = value elif ord(t[0]) == self._FAN_TLV_TYPE_HW_INFO: name = "hardware info" _len = ord(t[1]) value = t[2:2 + ord(t[1])] self._typehwinfo = value elif ord(t[0]) == self._FAN_TLV_TYPE_DEV_TYPE: name = "dev type" _len = ord(t[1]) value = "0x" for c in t[2:2 + ord(t[1])]: value += "%02X" % (ord(c),) self._typedevtype = int(value,16) except Exception as e: print(e) return {"name": name, "code": ord(t[0]), "value": value,"lens": _len} def __str__(self): formatstr = "VERSION : 0x%02x \n" \ " FLAG : 0x%02x \n" \ " HW_VER : 0x%02x \n" \ " TYPE : 0x%02x \n" \ "typename : %s \n" \ "typesn : %s \n" \ "typehwinfo : %s \n" return formatstr % (self.VERSION, self.FLAG, self.HW_VER, self.TYPE, self.typename, self.typesn, self.typehwinfo)