2021-05-01 12:37:07 -05:00
|
|
|
#!/usr/bin/env python
|
2020-08-06 05:16:11 -05:00
|
|
|
#
|
|
|
|
# led_control.py
|
|
|
|
#
|
|
|
|
# Platform-specific LED control functionality for SONiC
|
|
|
|
#
|
|
|
|
|
|
|
|
try:
|
2021-05-01 12:37:07 -05:00
|
|
|
import os
|
|
|
|
import re
|
2020-08-06 05:16:11 -05:00
|
|
|
import syslog
|
2021-05-01 12:37:07 -05:00
|
|
|
import collections
|
|
|
|
from sonic_led.led_control_base import LedControlBase
|
|
|
|
from sonic_py_common import device_info
|
2020-11-25 12:28:36 -06:00
|
|
|
except ImportError as e:
|
2020-08-06 05:16:11 -05:00
|
|
|
raise ImportError(str(e) + " - required module not found")
|
|
|
|
|
2021-05-01 12:37:07 -05:00
|
|
|
USR_SHARE_SONIC_PATH = "/usr/share/sonic"
|
|
|
|
HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device"
|
|
|
|
CONTAINER_PLATFORM_PATH = USR_SHARE_SONIC_PATH + "/platform"
|
2020-08-06 05:16:11 -05:00
|
|
|
|
|
|
|
def DBG_PRINT(str):
|
|
|
|
syslog.openlog("centec-led")
|
|
|
|
syslog.syslog(syslog.LOG_INFO, str)
|
|
|
|
syslog.closelog()
|
|
|
|
|
|
|
|
class LedControl(LedControlBase):
|
|
|
|
"""Platform specific LED control class"""
|
|
|
|
|
2021-05-01 12:37:07 -05:00
|
|
|
# Constructor
|
|
|
|
def __init__(self):
|
|
|
|
|
|
|
|
self.mac_to_led = {
|
|
|
|
0: 1,
|
|
|
|
1: 2,
|
|
|
|
2: 3,
|
|
|
|
3: 4,
|
|
|
|
8: 5,
|
|
|
|
9: 6,
|
|
|
|
10: 7,
|
|
|
|
11: 8,
|
|
|
|
20: 9,
|
|
|
|
21:10,
|
|
|
|
22:11,
|
|
|
|
23:12,
|
|
|
|
12:13,
|
|
|
|
13:14,
|
|
|
|
14:15,
|
|
|
|
15:16,
|
|
|
|
24:17,
|
|
|
|
25:18,
|
|
|
|
26:19,
|
|
|
|
27:20,
|
|
|
|
28:21,
|
|
|
|
29:22,
|
|
|
|
30:23,
|
|
|
|
31:24,
|
|
|
|
61:-1,
|
|
|
|
60:25,
|
|
|
|
63:-1,
|
|
|
|
62:-1,
|
|
|
|
45:-1,
|
|
|
|
44:26,
|
|
|
|
47:-1,
|
|
|
|
46:-1,
|
|
|
|
}
|
|
|
|
|
|
|
|
if os.path.isdir(CONTAINER_PLATFORM_PATH):
|
|
|
|
platform_path = CONTAINER_PLATFORM_PATH
|
|
|
|
else:
|
|
|
|
platform = device_info.get_platform()
|
|
|
|
if platform is None:
|
|
|
|
raise
|
|
|
|
platform_path = os.path.join(HOST_DEVICE_PATH, platform)
|
|
|
|
|
|
|
|
port_config_file = "/".join([platform_path, "E530-24x2c", "port_config.ini"])
|
|
|
|
try:
|
|
|
|
f = open(port_config_file)
|
|
|
|
except:
|
|
|
|
raise
|
|
|
|
for line in f:
|
|
|
|
line.strip()
|
|
|
|
if re.search('^#', line) is not None:
|
|
|
|
Port_cfg = collections.namedtuple('Port_cfg', line.split()[1:])
|
|
|
|
break
|
|
|
|
f.close()
|
|
|
|
f = open(port_config_file)
|
|
|
|
self._port_cfgs = [Port_cfg(*tuple((line.strip().split())))
|
|
|
|
for line in f if re.search('^#', line) is None]
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
self.LED_MODE_UP = [11, 11]
|
|
|
|
self.LED_MODE_DOWN = [7, 7]
|
|
|
|
self.f_led = "/sys/class/leds/{}/brightness"
|
|
|
|
self._initDefaultConfig()
|
|
|
|
|
2020-08-06 05:16:11 -05:00
|
|
|
# Helper method to map SONiC port name to index
|
|
|
|
def _port_name_to_index(self, port_name):
|
2021-05-01 12:37:07 -05:00
|
|
|
for port_cfg in self._port_cfgs:
|
|
|
|
if port_name == port_cfg.name:
|
|
|
|
macs = [int(x) for x in (port_cfg.lanes.split(','))]
|
|
|
|
led = self.mac_to_led[min(macs)]
|
|
|
|
if led < 0:
|
|
|
|
return None
|
|
|
|
return led
|
|
|
|
return None
|
2020-08-06 05:16:11 -05:00
|
|
|
|
|
|
|
def _port_state_to_mode(self, port_idx, state):
|
|
|
|
if state == "up":
|
2021-05-01 12:37:07 -05:00
|
|
|
return self.LED_MODE_UP[1] if port_idx == 25 or port_idx == 26 else self.LED_MODE_UP[0]
|
2020-08-06 05:16:11 -05:00
|
|
|
else:
|
2021-05-01 12:37:07 -05:00
|
|
|
return self.LED_MODE_DOWN[1] if port_idx == 25 or port_idx == 26 else self.LED_MODE_DOWN[0]
|
2020-08-06 05:16:11 -05:00
|
|
|
|
|
|
|
def _port_led_mode_update(self, port_idx, ledMode):
|
|
|
|
with open(self.f_led.format("port{}".format(port_idx)), 'w') as led_file:
|
|
|
|
led_file.write(str(ledMode))
|
|
|
|
|
|
|
|
def _initSystemLed(self):
|
|
|
|
try:
|
|
|
|
with open(self.f_led.format("system"), 'w') as led_file:
|
|
|
|
led_file.write("1")
|
|
|
|
DBG_PRINT("init system led to normal")
|
|
|
|
with open(self.f_led.format("idn"), 'w') as led_file:
|
|
|
|
led_file.write("1")
|
|
|
|
DBG_PRINT("init idn led to off")
|
|
|
|
except IOError as e:
|
|
|
|
DBG_PRINT(str(e))
|
|
|
|
|
|
|
|
def _initPanelLed(self):
|
|
|
|
with open(self.f_led.format("port1"), 'r') as led_file:
|
|
|
|
shouldInit = (int(led_file.read()) == 0)
|
|
|
|
|
|
|
|
if shouldInit == True:
|
2021-05-01 12:37:07 -05:00
|
|
|
for port_cfg in self._port_cfgs:
|
|
|
|
macs = [int(x) for x in (port_cfg.lanes.split(','))]
|
|
|
|
led = self.mac_to_led[min(macs)]
|
|
|
|
if led < 0:
|
|
|
|
continue
|
|
|
|
defmode = self._port_state_to_mode(led, "down")
|
|
|
|
with open(self.f_led.format("port{}".format(led)), 'w') as led_file:
|
2020-08-06 05:16:11 -05:00
|
|
|
led_file.write(str(defmode))
|
2021-05-01 12:37:07 -05:00
|
|
|
DBG_PRINT("init port{} led to mode={}".format(led, defmode))
|
2020-08-06 05:16:11 -05:00
|
|
|
|
|
|
|
def _initDefaultConfig(self):
|
|
|
|
DBG_PRINT("start init led")
|
|
|
|
|
|
|
|
self._initSystemLed()
|
|
|
|
self._initPanelLed()
|
|
|
|
|
|
|
|
DBG_PRINT("init led done")
|
|
|
|
|
|
|
|
# Concrete implementation of port_link_state_change() method
|
|
|
|
def port_link_state_change(self, portname, state):
|
|
|
|
port_idx = self._port_name_to_index(portname)
|
2021-05-01 12:37:07 -05:00
|
|
|
if port_idx is None:
|
|
|
|
return
|
2020-08-06 05:16:11 -05:00
|
|
|
ledMode = self._port_state_to_mode(port_idx, state)
|
|
|
|
with open(self.f_led.format("port{}".format(port_idx)), 'r') as led_file:
|
|
|
|
saveMode = int(led_file.read())
|
|
|
|
|
|
|
|
if ledMode == saveMode:
|
|
|
|
return
|
|
|
|
|
|
|
|
self._port_led_mode_update(port_idx, ledMode)
|
|
|
|
DBG_PRINT("update {} led mode from {} to {}".format(portname, saveMode, ledMode))
|