diff --git a/build_debian.sh b/build_debian.sh index 767dd7b83b7..bc79cd0bd8b 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -225,6 +225,8 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in screen \ hping3 \ python-scapy \ + python-ptyprocess \ + python-pexpect \ tcptraceroute \ mtr-tiny diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py new file mode 100755 index 00000000000..54107bb0461 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/eeprom.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess + import re + import pexpect + import cPickle as pickle + +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + bf_commands = ["ucli", "..", "..", "bf_pltfm", "cp2112"] + BFCMD="do_bfshell.py -c ucli \ + -c .. -c .. -c bf_pltfm -c cp2112 -c" + cache = "" + DATA = {'last_poll':0, 'raw': ""} + CHECK_INTV = 5 #in seconds + + def __init__(self, name, path, cpld_root, ro): + self.cache = "/tmp/.%s.cache" % os.path.basename(sys.argv[0]) + super(board, self).__init__("", 0, '', True) + + def eeprom_up2date(self): + if os.path.exists(self.cache): + self.DATA = pickle.load(open(self.cache, "rb")) + last_poll = self.DATA['last_poll'] + + #check interval + now = time.time() + if now < (last_poll + self.CHECK_INTV): + return True + else: + return False + + def interact_with_bfshell(self, cmds, timeout=20): + bfshell_path = 'docker exec -it syncd /opt/bfn/install/bin/bfshell' + bfshell_cmd = [ bfshell_path ] + + prompt_list = ['bfshell> $', 'bf-sde\.*.*> $', 'pd-switch:\d+> $', pexpect.EOF] + child = pexpect.spawn(' '.join(bfshell_cmd)) + child.expect(prompt_list) + lines = [] + for cmd in cmds: + child.sendline(cmd) + child.expect(prompt_list) + for line in child.before.splitlines(): + if line.strip() and line != cmd: + lines.append(line) + + return lines + + + def read_eeprom_bytes(self, byteCount, offset=0): + if self.eeprom_up2date() == True: + str = self.DATA['raw'] + else: + subcmd = "write 1 0xe8 1 0x40; write 1 0xa0 2 0 0; read 1 0xa0 ff" + cmd = self.BFCMD + "\'" + subcmd + "\'" + cmds = self.bf_commands + cmds.append(subcmd) + #lines = os.popen(cmd).readlines() + lines = self.interact_with_bfshell(cmds) + + last = lines[-1].strip() + raw = last.split() + hex = [] + for byte in raw: + hex.append(chr(int(byte,16))) + str = ''.join(hex) + if len(str) < offset+byteCount: + raise RuntimeError("expected to read %d bytes from %s, " \ + %(byteCount, "bfshell") + + "but only read %d" %(len(str))) + self.DATA['raw'] = str + self.DATA['last_poll'] = time.time() + pickle.dump(self.DATA, open(self.cache, "wb")) + + return str[offset:offset+byteCount] + diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/psuutil.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/psuutil.py new file mode 100755 index 00000000000..4ddc4a86138 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/psuutil.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python + +############################################################################# +# Accton +# +# Module contains an implementation of SONiC PSU Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# +import sys +import commands +import time +import os.path +import re +import pexpect +import cPickle as pickle + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + BF_INTV = 10 # in seconds + cache = "" + DATA = {1: {'last_poll':0, + 'status':False, + 'presence':False}, + 2: {'status':False, + 'presence':False} + } + bf_commands = ["ucli", "..", "..", "bf_pltfm", "chss_mgmt"] + + def __init__(self): + PsuBase.__init__(self) + self.cache = "/tmp/.%s.cache" % os.path.basename(sys.argv[0]) + + def get_num_psus(self): + return len(self.DATA) + + def interact_with_bfshell(self, cmds, timeout=20): + bfshell_path = 'docker exec -it syncd /opt/bfn/install/bin/bfshell' + bfshell_cmd = [ bfshell_path ] + + prompt_list = ['bfshell> $', 'bf-sde\.*.*> $', 'pd-switch:\d+> $', pexpect.EOF] + child = pexpect.spawn(' '.join(bfshell_cmd)) + child.expect(prompt_list) + lines = [] + for cmd in cmds: + child.sendline(cmd) + child.expect(prompt_list) + for line in child.before.splitlines(): + if line.strip() and line != cmd: + lines.append(line) + + return lines + + def bf_poll_psu(self): + if os.path.exists(self.cache): + self.DATA = pickle.load(open(self.cache, "rb")) + last_poll = self.DATA[1]['last_poll'] + now = time.time() + if now < (last_poll + self.BF_INTV): + return True + + for d in self.DATA: + index = d + subcmd = "ps_show %d" % index + cmds = list(self.bf_commands) + cmds.append(subcmd) + lines = self.interact_with_bfshell(cmds) + log = "".join(lines) + mt = re.search("error:", log, re.I) + if mt != None: + self.DATA[d]['presence'] = False + return False + + + buf = log.replace("\r", "") + buf = buf.replace("\n", "") + mt = re.search("Presence\s+true", buf) + if mt == None: + self.DATA[d]['presence'] = False + else: + self.DATA[d]['presence'] = True + pw = re.sub(r"(.*Power output\s+)(\d+)(.*)", r"\2", buf) + pw = int(pw) + if pw <= 100: #for output power < 100mW, it'd off + self.DATA[d]['status'] = False + else: + self.DATA[d]['status'] = True + + + self.DATA[1]['last_poll'] = time.time() + pickle.dump(self.DATA, open(self.cache, "wb")) + return True + + def get_psu_status(self, index): + if index is None: + return False + + self.bf_poll_psu() + d = self.DATA[index] + return d['status'] + + def get_psu_presence(self, index): + if index is None: + return False + + self.bf_poll_psu() + d = self.DATA[index] + return d['presence'] +