OLT Initialization state machine
This statemachine takes a disconnected OLT to an init
state. It follows the scapy automata design pattern.
It allows for state transitions to be actuated from
a command or the reception of a packet.
Change-Id: I8dc78c977099b67f76795dcb6ea2eeb458dd55a6
diff --git a/voltha/adapters/microsemi/OltStateMachine.py b/voltha/adapters/microsemi/OltStateMachine.py
new file mode 100644
index 0000000..a2db517
--- /dev/null
+++ b/voltha/adapters/microsemi/OltStateMachine.py
@@ -0,0 +1,387 @@
+#
+# Copyright 2016 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+from scapy.automaton import ATMT, Automaton
+from scapy.layers.l2 import sendp
+import structlog
+from voltha.adapters.microsemi.PAS5211 import PAS5211MsgGetProtocolVersion, PAS5211MsgGetOltVersion, \
+ PAS5211MsgGetOltVersionResponse, PAS5211MsgGetProtocolVersionResponse, PAS5211MsgSetOltOptics, BurstTimingCtrl, \
+ SnrBurstDelay, RngBurstDelay, GeneralOpticsParams, ResetValues, ResetTimingCtrl, PreambleParams, \
+ PAS5211MsgSetOltOpticsResponse, CHANNELS, PON_OPTICS_VOLTAGE_IF_LVPECL, PON_ENABLE, PON_POLARITY_ACTIVE_HIGH, \
+ PON_SD_SOURCE_LASER_SD, PON_RESET_TYPE_DELAY_BASED, PON_DISABLE, PON_RESET_TYPE_NORMAL_START_BURST_BASED, \
+ PAS5211MsgSetOpticsIoControl, PON_POLARITY_ACTIVE_LOW, PAS5211MsgSetOpticsIoControlResponse, \
+ PAS5211MsgGetGeneralParam, PON_TX_ENABLE_DEFAULT, PAS5211MsgGetGeneralParamResponse, PAS5211MsgAddOltChannel, \
+ PAS5211MsgAddOltChannelResponse, PON_ALARM_LOS, PAS5211MsgSetAlarmConfigResponse
+from voltha.adapters.microsemi.PAS5211_utils import general_param, olt_optics_pkt, burst_timing, io_ctrl_optics, \
+ alarm_config
+
+log = structlog.get_logger()
+_verbose = False
+
+
+
+class OltStateMachine(Automaton):
+
+ comm = None
+ retry = 3
+ iface = None
+ target = None
+ verbose = None
+
+ send_state = []
+
+ def parse_args(self, debug=0, store=0, **kwargs):
+ self.comm = kwargs.pop('comm', None)
+ self.target = kwargs.pop('target', None)
+ Automaton.parse_args(self, debug=debug, store=store, **kwargs)
+ self.verbose = kwargs.get('verbose', _verbose)
+ self.iface = kwargs.get('iface', "eth0")
+
+ if self.comm is None or self.target is None:
+ raise ValueError("Missing comm or target")
+
+ def my_send(self, pkt):
+ sendp(pkt, iface=self.iface, verbose=self.verbose)
+
+ def master_filter(self, pkt):
+ """
+ Anything coming from the OLT is for us
+ :param pkt: incoming packet
+ :return: True if it came from the olt
+ """
+ return pkt.src == self.target
+
+ def debug(self, lvl, msg):
+ if self.debug_level >= lvl:
+ log.info(msg)
+
+ def p(self, pkt, channel_id=-1):
+ return self.comm.frame(pkt, channel_id=channel_id)
+
+ def check_channel_state(self):
+ for i in CHANNELS:
+ if not self.send_state[i]:
+ return False
+ self.send_state = []
+ return True
+
+ @ATMT.state(initial=1)
+ def disconnected(self):
+ pass
+
+ @ATMT.state()
+ def wait_for_proto_version(self):
+ pass
+
+ @ATMT.state()
+ def got_proto_version(self):
+ pass
+
+ @ATMT.state()
+ def wait_for_olt_version(self):
+ pass
+
+ @ATMT.state()
+ def got_olt_version(self):
+ pass
+
+ @ATMT.state()
+ def wait_olt_optics(self):
+ pass
+
+ @ATMT.state()
+ def got_olt_optics(self):
+ pass
+
+ @ATMT.state()
+ def wait_olt_io_optics(self):
+ pass
+
+ @ATMT.state()
+ def got_olt_io_optics(self):
+ pass
+
+ @ATMT.state()
+ def wait_query_response(self):
+ pass
+
+ @ATMT.state()
+ def got_query_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_olt_add(self):
+ pass
+
+ @ATMT.state()
+ def got_olt_add(self):
+ pass
+
+ @ATMT.state()
+ def wait_alarm_set(self):
+ pass
+
+ @ATMT.state()
+ def got_alarm_set(self):
+ pass
+
+ @ATMT.state(final=1)
+ def initialized(self):
+ pass
+
+ @ATMT.state(error=1)
+ def ERROR(self):
+ pass
+
+
+
+ #Transitions from disconnected state
+ @ATMT.condition(disconnected)
+ def send_proto_request(self):
+ self.send(self.p(PAS5211MsgGetProtocolVersion()))
+ raise self.wait_for_proto_version()
+
+ #Transitions from wait_for_proto_version
+ @ATMT.timeout(wait_for_proto_version, 1)
+ def timeout_proto(self):
+ log.info("Timed out waiting for proto version")
+ self.retry -= 1
+ if self.retry < 0:
+ log.debug("Too many retries, aborting.")
+ raise self.ERROR()
+ raise self.disconnected()
+
+ @ATMT.receive_condition(wait_for_proto_version)
+ def receive_proto_version(self, pkt):
+ log.debug("Received proto version {}".format(type(pkt)))
+ if PAS5211MsgGetProtocolVersionResponse in pkt:
+ raise self.got_proto_version()
+ else:
+ log.error("Got garbage packet {}".format(pkt))
+ raise self.ERROR()
+
+ # Transitions from got_proto_version
+ @ATMT.condition(got_proto_version)
+ def send_olt_version(self):
+ self.send(self.p(PAS5211MsgGetOltVersion()))
+ raise self.wait_for_olt_version()
+
+ # Transitions from waiting for olt version
+ @ATMT.timeout(wait_for_olt_version, 1)
+ def timeout_olt(self):
+ log.debug("Timed out waiting for olt version")
+ self.retry -= 1
+ if self.retry < 0:
+ log.debug("Too many retries, aborting.")
+ raise self.ERROR()
+ raise self.disconnected()
+
+ @ATMT.receive_condition(wait_for_olt_version)
+ def receive_olt_version(self, pkt):
+ log.debug("Received proto version {}".format(pkt))
+ if PAS5211MsgGetOltVersionResponse in pkt:
+ raise self.got_olt_version()
+ else:
+ log.error("Got garbage packet {}".format(pkt))
+ raise self.ERROR()
+
+ # Transitions from got_olt_version
+ @ATMT.condition(got_olt_version)
+ def send_olt_optics(self):
+ snr_burst_delay = SnrBurstDelay(timer_delay=8, preamble_delay=32,
+ delimiter_delay=128, burst_delay=128)
+ rng_burst_delay = RngBurstDelay(timer_delay=8, preamble_delay=32,
+ delimiter_delay=128)
+
+ general_optics_param = GeneralOpticsParams(laser_reset_polarity=PON_POLARITY_ACTIVE_HIGH,
+ laser_sd_polarity=PON_POLARITY_ACTIVE_HIGH,
+ sd_source=PON_SD_SOURCE_LASER_SD, sd_hold_snr_ranging=PON_DISABLE,
+ sd_hold_normal=PON_DISABLE, reset_type_snr_ranging=PON_RESET_TYPE_DELAY_BASED,
+ reset_type_normal=PON_RESET_TYPE_NORMAL_START_BURST_BASED,
+ laser_reset_enable=PON_ENABLE)
+
+ reset = ResetTimingCtrl(reset_data_burst=ResetValues(bcdr_reset_d2=1,
+ bcdr_reset_d1=11,
+ laser_reset_d2=2,
+ laser_reset_d1=5),
+ reset_snr_burst=ResetValues(bcdr_reset_d2=2,
+ bcdr_reset_d1=9,
+ laser_reset_d2=2,
+ laser_reset_d1=1),
+ reset_rng_burst=ResetValues(bcdr_reset_d2=2,
+ bcdr_reset_d1=9,
+ laser_reset_d2=2,
+ laser_reset_d1=1),
+ single_reset=ResetValues(bcdr_reset_d2=1,
+ bcdr_reset_d1=1,
+ laser_reset_d2=1,
+ laser_reset_d1=1),
+ double_reset=ResetValues(bcdr_reset_d2=1,
+ bcdr_reset_d1=1,
+ laser_reset_d2=1,
+ laser_reset_d1=1))
+
+ preamble = PreambleParams(correlation_preamble_length=8, preamble_length_snr_rng=119,
+ guard_time_data_mode=32, type1_size_data=0,
+ type2_size_data=0, type3_size_data=5,
+ type3_pattern=170, delimiter_size=20,
+ delimiter_byte1=171, delimiter_byte2=89,
+ delimiter_byte3=131)
+
+ olt_optics = olt_optics_pkt(PON_OPTICS_VOLTAGE_IF_LVPECL, burst=burst_timing(1, 1,
+ snr_burst=snr_burst_delay,
+ rng_burst=rng_burst_delay),
+ general=general_optics_param,
+ reset=reset,
+ preamble=preamble)
+
+ for id in CHANNELS:
+ self.send_state.append(False)
+ self.send(self.p(olt_optics, channel_id=id))
+
+ raise self.wait_olt_optics()
+
+ #Transitions from wait_olt_optics
+ @ATMT.timeout(wait_olt_optics, 3)
+ def olt_optics_timeout(self):
+ log.error("Setting olt optics failed; disconnecting")
+ raise self.ERROR()
+
+ @ATMT.receive_condition(wait_olt_optics)
+ def receive_set_optics_response(self, pkt):
+ if pkt.opcode == PAS5211MsgSetOltOpticsResponse.opcode:
+ self.send_state[pkt.channel_id] = True
+ if self.check_channel_state():
+ raise self.got_olt_optics()
+ raise self.wait_olt_optics()
+
+ #Transitions from got_olt_optics
+ @ATMT.condition(got_olt_optics)
+ def send_olt_io_optics(self):
+
+ pkt = io_ctrl_optics(1, 0, 6, 14)
+ self.send_state.append(False)
+ self.send(self.p(pkt, channel_id=0))
+
+ pkt = io_ctrl_optics(3, 2, 7, 15)
+ self.send_state.append(False)
+ self.send(self.p(pkt, channel_id=1))
+
+ pkt = io_ctrl_optics(11, 10, 8, 16)
+ self.send_state.append(False)
+ self.send(self.p(pkt, channel_id=2))
+
+ pkt = io_ctrl_optics(13, 12, 9, 17)
+ self.send_state.append(False)
+ self.send(self.p(pkt, channel_id=3))
+
+ raise self.wait_olt_io_optics()
+
+ #Transitions from wait olt io optics
+ @ATMT.timeout(wait_olt_io_optics, 3)
+ def olt_io_optics_timeout(self):
+ log.error("Setting olt io optics failed; disconnecting")
+ raise self.ERROR()
+
+ @ATMT.receive_condition(wait_olt_io_optics)
+ def receive_io_optics_response(self, pkt):
+ if pkt.opcode == PAS5211MsgSetOpticsIoControlResponse.opcode:
+ self.send_state[pkt.channel_id] = True
+ if self.check_channel_state():
+ raise self.got_olt_io_optics()
+ raise self.wait_olt_io_optics()
+
+ # Transitions got olt io optics
+ @ATMT.condition(got_olt_io_optics)
+ def check_downstream_pon_tx(self):
+ query = general_param(PON_TX_ENABLE_DEFAULT)
+ for id in CHANNELS:
+ self.send_state.append(False)
+ self.send(self.p(query, channel_id=id))
+
+ raise self.wait_query_response()
+
+ # Transitions from wait query response
+ @ATMT.timeout(wait_query_response, 3)
+ def query_timeout(self):
+ log.error("Our queries have gone unanswered; disconnecting")
+ raise self.ERROR()
+
+ @ATMT.receive_condition(wait_query_response)
+ def check_pon_tx_state(self, pkt):
+ if PAS5211MsgGetGeneralParamResponse in pkt:
+ self.send_state[pkt.channel_id] = True
+ if pkt.value == PON_ENABLE:
+ # we may want to do something here.
+ if self.check_channel_state():
+ raise self.got_query_response()
+ else:
+ raise self.wait_query_response()
+ else:
+ log.error("TX downstream is not enabled")
+ raise self.ERROR()
+
+ # Transitions from got_query_response
+ @ATMT.condition(wait_query_response)
+ def send_add_olt(self):
+ olt_add = PAS5211MsgAddOltChannel()
+ for id in CHANNELS:
+ self.send_state.append(False)
+ self.send(self.p(olt_add, channel_id=id))
+ raise self.wait_olt_add()
+
+ # Transitions from wait_olt_add
+ @ATMT.timeout(wait_olt_add, 3)
+ def olt_add_timeout(self):
+ log.error("Cannot add olts; disconnecting")
+ raise self.ERROR()
+
+ @ATMT.receive_condition(wait_olt_add)
+ def wait_for_olt_add(self, pkt):
+ if pkt.opcode == PAS5211MsgAddOltChannelResponse.opcode:
+ self.send_state[pkt.channel_id] = True
+ if self.check_channel_state():
+ raise self.got_olt_add()
+ raise self.wait_olt_add()
+
+ # Transitions from got_olt_add
+ @ATMT.condition(got_olt_add)
+ def send_alarm_config(self):
+ alarm_msg = alarm_config(PON_ALARM_LOS, PON_ENABLE)
+ for id in CHANNELS:
+ self.send_state.append(False)
+ self.send(self.p(alarm_msg, channel_id=id))
+ raise self.wait_alarm_set()
+
+ # Transitions for wait_alarm_set
+ @ATMT.timeout(wait_alarm_set, 3)
+ def alarm_timeout(self):
+ log.error("Couldn't set alarms; disconnecting")
+ raise self.ERROR()
+
+ @ATMT.receive_condition(wait_alarm_set)
+ def wait_for_alarm_set(self, pkt):
+ if pkt.opcode == PAS5211MsgSetAlarmConfigResponse.opcode:
+ self.send_state[pkt.channel_id] = True
+ if self.check_channel_state():
+ raise self.got_alarm_set()
+ raise self.wait_alarm_set()
+
+ @ATMT.timeout(got_alarm_set, 1)
+ def send_keepalive(self):
+ self.send(self.p(PAS5211MsgGetOltVersion()))
+ raise self.got_alarm_set()
+
+
diff --git a/voltha/adapters/microsemi/PAS5211.py b/voltha/adapters/microsemi/PAS5211.py
index ec9e8b8..f24af17 100644
--- a/voltha/adapters/microsemi/PAS5211.py
+++ b/voltha/adapters/microsemi/PAS5211.py
@@ -18,14 +18,202 @@
"""
PAS5211 scapy structs used for interaction with Ruby
"""
-from scapy.fields import LEShortField, Field, LEIntField, LESignedIntField, FieldLenField, FieldListField
+from scapy.fields import LEShortField, Field, LEIntField, LESignedIntField, FieldLenField, FieldListField, PacketField, \
+ ByteField
from scapy.layers.l2 import Dot3, LLC
+from scapy.layers.inet import ARP
from scapy.packet import Packet, bind_layers, split_layers
from scapy.utils import lhex
from scapy.volatile import RandSInt
from scapy.layers.ntp import XLEShortField
"""
+PAS5211 Constants
+"""
+CHANNELS=range(0,4)
+
+# from enum PON_true_false_t
+PON_FALSE = 0
+PON_TRUE = 1
+
+# from enum PON_enable_disable_t
+PON_DISABLE = 0
+PON_ENABLE = 1
+
+# from enym PON_mac_t
+PON_MII = 0
+PON_GMII = 1
+PON_TBI = 2
+
+PON_POLARITY_ACTIVE_LOW = 0
+PON_POLARITY_ACTIVE_HIGH = 1
+
+PON_OPTICS_VOLTAGE_IF_UNDEFINED = 0
+PON_OPTICS_VOLTAGE_IF_CML = 1
+PON_OPTICS_VOLTAGE_IF_LVPECL = 2
+
+PON_SD_SOURCE_LASER_SD = 0
+PON_SD_SOURCE_BCDR_LOCK = 1
+PON_SD_SOURCE_BCDR_SD = 2
+
+PON_RESET_TYPE_DELAY_BASED = 0
+PON_RESET_TYPE_SINGLE_RESET = 1
+PON_RESET_TYPE_DOUBLE_RESET = 2
+
+PON_RESET_TYPE_NORMAL_START_BURST_BASED = 0
+PON_RESET_TYPE_NORMAL_END_BURST_BASED = 1
+
+#from PON_general_parameters_type_t
+PON_COMBINED_LOSI_LOFI = 1000,
+PON_TX_ENABLE_DEFAULT = 1001,
+PON_FALSE_Q_FULL_EVENT_MODE = 1002, #Enable or disable False queue full event from DBA
+PON_PID_AID_MISMATCH_MIN_SILENCE_PERIOD = 1003, #Set PID_AID_MISMATCH min silence period. 0 - disable, Else - period in secs
+PON_ENABLE_CLEAR_ALARM = 1004, #Set if FW generate clear alarm. 0 - generate clear alarm, Else - don't generate clear alarm
+PON_ASSIGN_ALLOC_ID_PLOAM = 1005, #Enable or disabl send assign alloc id ploam. 0 - disable, 1 - enable
+PON_BIP_ERR_POLLING_PERIOD_MS = 1006, #BIP error polling period, 200 - 65000, 0 - Disabled, Recommended: 5000 (default)
+PON_IGNORE_SN_WHEN_ACTIVE = 1007, #Ignore SN when decatived 0 - consider SN (deactivate the onu if received same SN when activated (default) 1 - Ignore
+PON_ONU_PRE_ASSIGNED_DELAY = 1008, #0xffffffff - Disabled (default). Any other value (0 - 0xfffe) indicates that PA delay is enabled, with the specified delay value and included in the US_OVERHEAD PLOAM.
+PON_DS_FRAGMENTATION = 1009, #Enable or disable DS fragmentation, 0 disable, 1 enable
+PON_REI_ERRORS_REPORT_ALL = 1010, #Set if fw report rei alarm when errors is 0, 0 disable (default), 1 enable
+PON_IGNORE_SFI_DEACTIVATION = 1011, #Set if igonre sfi deactivation, 0 disable (default), 1 enable
+PON_OVERRIDE_ALLOCATION_OVERHEAD = 1012, #Allows to override the allocation overhead set by optic-params configuration. This configuration is only allowed when the the pon channel is disabled.
+PON_OPTICS_TIMELINE_OFFSET = 1013, #Optics timeline offset, -128-127, : this parameter is very sensitive and requires coordination with PMC
+PON_LAST_GENERAL_PARAMETER = PON_OPTICS_TIMELINE_OFFSET #Last general meter
+
+
+
+PON_GPIO_LINE_0 = 0
+PON_GPIO_LINE_1 = 1
+PON_GPIO_LINE_2 = 2
+PON_GPIO_LINE_3 = 3
+PON_GPIO_LINE_4 = 4
+PON_GPIO_LINE_5 = 5
+PON_GPIO_LINE_6 = 6
+PON_GPIO_LINE_7 = 7
+def PON_EXT_GPIO_LINE(line):
+ return line + 8
+
+# from enum PON_alarm_t
+PON_ALARM_SOFTWARE_ERROR = 0
+PON_ALARM_LOS = 1
+PON_ALARM_LOSI = 2
+PON_ALARM_DOWI = 3
+PON_ALARM_LOFI = 4
+PON_ALARM_RDII = 5
+PON_ALARM_LOAMI = 6
+PON_ALARM_LCDGI = 7
+PON_ALARM_LOAI = 8
+PON_ALARM_SDI = 9
+PON_ALARM_SFI = 10
+PON_ALARM_PEE = 11
+PON_ALARM_DGI = 12
+PON_ALARM_LOKI = 13
+PON_ALARM_TIWI = 14
+PON_ALARM_TIA = 15
+PON_ALARM_VIRTUAL_SCOPE_ONU_LASER_ALWAYS_ON = 16
+PON_ALARM_VIRTUAL_SCOPE_ONU_SIGNAL_DEGRADATION = 17
+PON_ALARM_VIRTUAL_SCOPE_ONU_EOL = 18
+PON_ALARM_VIRTUAL_SCOPE_ONU_EOL_DATABASE_IS_FULL = 19
+PON_ALARM_AUTH_FAILED_IN_REGISTRATION_ID_MODE = 20
+PON_ALARM_SUFI = 21
+PON_ALARM_LAST_ALARM = 22
+
+# from enum PON_general_parameters_type_t
+PON_COMBINED_LOSI_LOFI = 1000
+PON_TX_ENABLE_DEFAULT = 1001
+
+# Enable or disable False queue full event from DBA
+PON_FALSE_Q_FULL_EVENT_MODE = 1002
+
+# Set PID_AID_MISMATCH min silence period. 0 - disable, Else - period in secs
+PON_PID_AID_MISMATCH_MIN_SILENCE_PERIOD = 1003
+
+# Set if FW generate clear alarm. 0 - generate clear alarm, Else - don't
+# generate clear alarm
+PON_ENABLE_CLEAR_ALARM = 1004
+
+# Enable or disabl send assign alloc id ploam. 0 - disable, 1 - enable
+PON_ASSIGN_ALLOC_ID_PLOAM = 1005
+
+# BIP error polling period, 200 - 65000, 0 - Disabled, Recommended: 5000
+# (default)
+PON_BIP_ERR_POLLING_PERIOD_MS = 1006
+
+# Ignore SN when decatived 0 - consider SN (deactivate the onu if received
+# same SN when activated (default) 1 - Ignore
+PON_IGNORE_SN_WHEN_ACTIVE = 1007
+
+# 0xffffffff - Disabled (default). Any other value (0 - 0xfffe) indicates
+# that PA delay is enabled, with the specified delay value and included in
+# the US_OVERHEAD PLOAM
+PON_ONU_PRE_ASSIGNED_DELAY = 1008
+
+# Enable or disable DS fragmentation, 0 disable, 1 enable
+PON_DS_FRAGMENTATION = 1009
+
+# Set if fw report rei alarm when errors is 0, 0 disable (default), 1 enable
+PON_REI_ERRORS_REPORT_ALL = 1010
+
+# Set if igonre sfi deactivation, 0 disable (default), 1 enable
+PON_IGNORE_SFI_DEACTIVATION = 1011
+
+# Allows to override the allocation overhead set by optic-params
+# configuration. This configuration is only allowed when the the pon channel
+# is disabled
+PON_OVERRIDE_ALLOCATION_OVERHEAD = 1012
+
+# Optics timeline offset, -128-127, : this parameter is very sensitive and
+# requires coordination with PMC
+PON_OPTICS_TIMELINE_OFFSET = 1013
+
+# Last general meter
+PON_LAST_GENERAL_PARAMETER = PON_OPTICS_TIMELINE_OFFSET
+
+# from enum PON_dba_mode_t
+PON_DBA_MODE_NOT_LOADED = 0
+PON_DBA_MODE_LOADED_NOT_RUNNING = 1
+PON_DBA_MODE_RUNNING = 2
+PON_DBA_MODE_LAST = 3
+
+# from enum type typedef enum PON_port_frame_destination_t
+PON_PORT_PON = 0
+PON_PORT_SYSTEM = 1
+
+# from enum PON_olt_hw_classification_t
+
+PON_OLT_HW_CLASSIFICATION_PAUSE = 0
+PON_OLT_HW_CLASSIFICATION_LINK_CONSTRAINT = 1
+PON_OLT_HW_CLASSIFICATION_IGMP = 2
+PON_OLT_HW_CLASSIFICATION_MPCP = 3
+PON_OLT_HW_CLASSIFICATION_OAM = 4
+PON_OLT_HW_CLASSIFICATION_802_1X = 5
+PON_OLT_HW_CLASSIFICATION_PPPOE_DISCOVERY = 6
+PON_OLT_HW_CLASSIFICATION_PPPOE_SESSION = 7
+PON_OLT_HW_CLASSIFICATION_DHCP_V4 = 8
+PON_OLT_HW_CLASSIFICATION_PIM = 9
+PON_OLT_HW_CLASSIFICATION_DHCP_V6 = 10
+PON_OLT_HW_CLASSIFICATION_ICMP_V4 = 11
+PON_OLT_HW_CLASSIFICATION_MLD = 12
+PON_OLT_HW_CLASSIFICATION_ARP = 13
+PON_OLT_HW_CLASSIFICATION_CONF_DA = 14
+PON_OLT_HW_CLASSIFICATION_CONF_RULE = 15
+PON_OLT_HW_CLASSIFICATION_DA_EQ_SA = 16
+PON_OLT_HW_CLASSIFICATION_DA_EQ_MAC = 17
+PON_OLT_HW_CLASSIFICATION_DA_EQ_SEC_MAC = 18
+PON_OLT_HW_CLASSIFICATION_SA_EQ_MAC = 19
+PON_OLT_HW_CLASSIFICATION_SA_EQ_SEC_MAC = 20
+PON_OLT_HW_CLASSIFICATION_ETHERNET_MANAGEMENT = 100
+PON_OLT_HW_CLASSIFICATION_IPV4_LOCAL_MULTICAST = 101
+PON_OLT_HW_CLASSIFICATION_IPV4_MANAGEMENT = 102
+PON_OLT_HW_CLASSIFICATION_ALL_IPV4_MULTICAST = 103
+PON_OLT_HW_CLASSIFICATION_IPV6_LOCAL_MULTICAST = 104
+PON_OLT_HW_CLASSIFICATION_IPV6_MANAGEMENT = 105
+PON_OLT_HW_CLASSIFICATION_ALL_IPV6_MULTICAST = 106
+PON_OLT_HW_CLASSIFICATION_OTHER = 107
+PON_OLT_HW_CLASSIFICATION_LAST_RULE = 108
+
+
+"""
Extra field structs
"""
@@ -124,6 +312,229 @@
def answers(self, other):
return other.name == "PAS5211MsgGetOltVersion"
+
+class SnrBurstDelay(Packet):
+ name = "SnrBurstDelay"
+ fields_desc= [
+ LEShortField("timer_delay", None),
+ LEShortField("preamble_delay", None),
+ LEShortField("delimiter_delay", None),
+ LEShortField("burst_delay", None)
+ ]
+
+ def extract_padding(self, p):
+ return "", p
+
+class RngBurstDelay(Packet):
+ name = "SnrBurstDelay"
+ fields_desc= [
+ LEShortField("timer_delay", None),
+ LEShortField("preamble_delay", None),
+ LEShortField("delimiter_delay", None)
+ ]
+
+
+ def extract_padding(self, p):
+ return "", p
+
+
+class BurstTimingCtrl(Packet):
+ name = "BurstTimingCtrl"
+ fields_desc = [
+ PacketField("snr_burst_delay", None, SnrBurstDelay),
+ PacketField("rng_burst_delay", None, RngBurstDelay),
+ LEShortField("burst_delay_single", None),
+ LEShortField("burst_delay_double", None)
+
+ ]
+
+ def extract_padding(self, p):
+ return "", p
+
+
+class GeneralOpticsParams(Packet):
+ name = "GeneralOpticsParams"
+ fields_desc= [
+ ByteField("laser_reset_polarity", None),
+ ByteField("laser_sd_polarity", None),
+ ByteField("sd_source", None),
+ ByteField("sd_hold_snr_ranging", None),
+ ByteField("sd_hold_normal", None),
+ ByteField("reset_type_snr_ranging", None),
+ ByteField("reset_type_normal", None),
+ ByteField("laser_reset_enable", None),
+ ]
+
+ def extract_padding(self, p):
+ return "", p
+
+
+class ResetValues(Packet):
+ name = "ResetDataBurst"
+ fields_desc = [
+ ByteField("bcdr_reset_d2", None),
+ ByteField("bcdr_reset_d1", None),
+ ByteField("laser_reset_d2", None),
+ ByteField("laser_reset_d1", None)
+ ]
+
+ def extract_padding(self, p):
+ return "", p
+
+
+class DoubleResetValues(Packet):
+ name = "ResetDataBurst"
+ fields_desc = [
+ ByteField("bcdr_reset_d4", None),
+ ByteField("bcdr_reset_d3", None),
+ ByteField("laser_reset_d4", None),
+ ByteField("laser_reset_d3", None)
+ ]
+
+ def extract_padding(self, p):
+ return "", p
+
+
+class ResetTimingCtrl(Packet):
+ name = "ResetTimingCtrl"
+ fields_desc = [
+ PacketField("reset_data_burst", None, ResetValues),
+ PacketField("reset_snr_burst", None, ResetValues),
+ PacketField("reset_rng_burst", None, ResetValues),
+ PacketField("single_reset", None, ResetValues),
+ PacketField("double_reset", None, DoubleResetValues),
+ ]
+
+ def extract_padding(self, p):
+ return "", p
+
+
+class PreambleParams(Packet):
+ name = "PreambleParams"
+ fields_desc = [
+ ByteField("correlation_preamble_length", None),
+ ByteField("preamble_length_snr_rng", None),
+ ByteField("guard_time_data_mode", None),
+ ByteField("type1_size_data", None),
+ ByteField("type2_size_data", None),
+ ByteField("type3_size_data", None),
+ ByteField("type3_pattern", None),
+ ByteField("delimiter_size", None),
+ ByteField("delimiter_byte1", None),
+ ByteField("delimiter_byte2", None),
+ ByteField("delimiter_byte3", None)
+ ]
+
+ def extract_padding(self, p):
+ return "", p
+
+class PAS5211MsgSetOltOptics(PAS5211Msg):
+
+ opcode = 106
+ name = "PAS5211MsgSetOltOptics"
+
+ fields_desc = [
+ PacketField("burst_timing_ctrl", None, BurstTimingCtrl),
+ PacketField("general_optics_params", None, GeneralOpticsParams),
+ ByteField("reserved1", 0),
+ ByteField("reserved2", 0),
+ ByteField("reserved3", 0),
+ PacketField("reset_timing_ctrl", None, ResetTimingCtrl),
+ ByteField("voltage_if_mode", None),
+ PacketField("preamble_params", None, PreambleParams),
+ ByteField("reserved4", 0),
+ ByteField("reserved5", 0),
+ ByteField("reserved6", 0)
+ ]
+
+class PAS5211MsgSetOltOpticsResponse(PAS5211Msg):
+ opcode = 10346
+ name = "PAS5211MsgSetOltOpticsResponse"
+ fields_desc = []
+
+
+class PAS5211MsgSetOpticsIoControl(PAS5211Msg):
+ opcode = 108
+ name = "PAS5211MsgSetOpticsIoControl"
+ fields_desc = [
+ ByteField("i2c_clk", None),
+ ByteField("i2c_data", None),
+ ByteField("tx_enable", None),
+ ByteField("tx_fault", None),
+ ByteField("tx_enable_polarity", None),
+ ByteField("tx_fault_polarity", None),
+ ]
+
+
+class PAS5211MsgSetOpticsIoControlResponse(PAS5211Msg):
+ opcode = 10348
+ name = "PAS5211MsgSetOpticsIoControlResponse"
+ fields_desc = [ ]
+
+
+class PAS5211MsgAddOltChannel(PAS5211Msg):
+ opcode = 4
+ name = "PAS5211MsgAddOltChannel"
+ fields_desc = [
+
+ ]
+
+
+class PAS5211MsgAddOltChannelResponse(PAS5211Msg):
+ opcode = 10244
+ name = "PAS5211MsgAddOltChannelResponse"
+ fields_desc = [
+
+ ]
+
+class PAS5211MsgGetGeneralParam(PAS5211Msg):
+ opcode = 165
+ name = "PAS5211MsgGetGeneralParam"
+ fields_desc = [
+ LEIntField("parameter", None),
+ LEIntField("reserved", 0),
+ ]
+
+
+class PAS5211MsgGetGeneralParamResponse(PAS5211Msg):
+ name = "PAS5211MsgGetGeneralParamResponse"
+ fields_desc = [
+ LEIntField("parameter", None),
+ LEIntField("reserved", 0),
+ LEIntField("value", None)
+ ]
+
+class PAS5211MsgSetAlarmConfig(PAS5211Msg):
+ opcode = 48
+ name = "PAS5211MsgSetAlarmConfig"
+ fields_desc = [
+ LEShortField("type", None),
+ LEShortField("activate", None),
+ LEIntField("parameter1", None),
+ LEIntField("parameter2", None),
+ LEIntField("parameter3", None),
+ LEIntField("parameter4", None)
+ ]
+
+
+class PAS5211MsgSetOltChannelActivationPeriod(PAS5211Msg):
+ opcode = 11
+ name = "PAS5211MsgSetOltChannelActivationPeriod"
+ fields_desc = [
+ LEIntField("activation_period", None)
+ ]
+
+
+class PAS5211MsgSetOltChannelActivationPeriodResponse(PAS5211Msg):
+ name = "PAS5211MsgSetOltChannelActivationPeriodResponse"
+ fields_desc = []
+
+
+class PAS5211MsgSetAlarmConfigResponse(PAS5211Msg):
+ opcode = 10288
+ name = "PAS5211MsgSetAlarmConfigResponse"
+ fields_desc = []
+
"""
Bindings used for message processing
"""
@@ -132,4 +543,6 @@
bind_layers(Dot3,PAS5211FrameHeader)
bind_layers(PAS5211FrameHeader, PAS5211MsgHeader)
bind_layers(PAS5211MsgHeader, PAS5211MsgGetOltVersionResponse, opcode=0x3800 | 3)
-bind_layers(PAS5211MsgHeader, PAS5211MsgGetProtocolVersionResponse, opcode=0x2800 | 2)
\ No newline at end of file
+bind_layers(PAS5211MsgHeader, PAS5211MsgGetProtocolVersionResponse, opcode=0x2800 | 2)
+bind_layers(PAS5211MsgHeader, PAS5211MsgGetGeneralParamResponse, opcode=0x2800 | 165)
+bind_layers(PAS5211MsgHeader, PAS5211MsgSetAlarmConfigResponse, opcode=0x2800 | 48)
diff --git a/voltha/adapters/microsemi/PAS5211_comm.py b/voltha/adapters/microsemi/PAS5211_comm.py
index d604077..863cfbb 100644
--- a/voltha/adapters/microsemi/PAS5211_comm.py
+++ b/voltha/adapters/microsemi/PAS5211_comm.py
@@ -58,25 +58,13 @@
class PAS5211Communication(object):
- def __init__(self, dst_mac, channel_id = -1, init=0, iface = None):
+ def __init__(self, dst_mac, init=0, iface = None):
self.iface = iface
self.dst_mac = dst_mac
self.seqgen = sequence_generator(init)
self.src_mac = determine_src_mac(self.iface)
- self.channel_id = channel_id
- def communicate(self, msg, timeout=1, **kwargs):
- if self.src_mac is not None:
- frame = constructPAS5211Frames(msg, self.seqgen.next(), self.src_mac,
- self.dst_mac, channel_id=self.channel_id,
- **kwargs)
- try:
- return srp1(frame, timeout=timeout, iface=self.iface)
- except IOError as exc:
- log.info('Can not communicate to ruby on mac {} because {}'
- .format(self.dst_mac, exc.message))
- except select.error as exc:
- log.info('Can not communicate to ruby on mac {} because {}'
- .format(self.dst_mac, exc))
- else:
- log.info('Unknown src mac for {}'.format(self.iface))
+ def frame(self, msg, channel_id=-1):
+ return constructPAS5211Frames(msg, self.seqgen.next(), self.src_mac,
+ self.dst_mac, channel_id=channel_id)
+
diff --git a/voltha/adapters/microsemi/PAS5211_hardware.py b/voltha/adapters/microsemi/PAS5211_hardware.py
new file mode 100644
index 0000000..c3a5f46
--- /dev/null
+++ b/voltha/adapters/microsemi/PAS5211_hardware.py
@@ -0,0 +1,33 @@
+#
+# Copyright 2016 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+PON_ALARM_CODE_LOS = 0
+PON_ALARM_CODE_LOSI = 1
+PON_ALARM_CODE_DOWI = 2
+PON_ALARM_CODE_LOFI = 3
+PON_ALARM_CODE_RDII = 4
+PON_ALARM_CODE_LOAMI = 5
+PON_ALARM_CODE_LCDGI = 6
+PON_ALARM_CODE_LOAI = 7
+PON_ALARM_CODE_SDI = 8
+PON_ALARM_CODE_SFI = 9
+PON_ALARM_CODE_PEE = 10
+PON_ALARM_CODE_DGI = 11
+PON_ALARM_CODE_LOKI = 12
+PON_ALARM_CODE_TIWI = 13
+PON_ALARM_CODE_TIA = 14
+PON_ALARM_CODE_LAST_ALARM = 15
\ No newline at end of file
diff --git a/voltha/adapters/microsemi/PAS5211_utils.py b/voltha/adapters/microsemi/PAS5211_utils.py
new file mode 100644
index 0000000..e923a8c
--- /dev/null
+++ b/voltha/adapters/microsemi/PAS5211_utils.py
@@ -0,0 +1,91 @@
+#
+# Copyright 2016 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+from voltha.adapters.microsemi.PAS5211 import PAS5211MsgGetGeneralParam, PON_POLARITY_ACTIVE_LOW, \
+ PON_POLARITY_ACTIVE_HIGH, PAS5211MsgSetOpticsIoControl, BurstTimingCtrl, PAS5211MsgSetOltOptics, PON_ALARM_LOS, \
+ PON_ALARM_LOSI, PON_ALARM_DOWI, PON_ALARM_LOFI, PON_ALARM_RDII, PON_ALARM_LOAMI, PON_ALARM_LCDGI, PON_ALARM_LOAI, \
+ PON_ALARM_SDI, PON_ALARM_SFI, PON_ALARM_PEE, PON_ALARM_DGI, PON_ALARM_LOKI, PON_ALARM_TIWI, PON_ALARM_TIA, \
+ PAS5211MsgSetAlarmConfig
+from voltha.adapters.microsemi.PAS5211_hardware import PON_ALARM_CODE_LOS, PON_ALARM_CODE_LOSI, PON_ALARM_CODE_DOWI, \
+ PON_ALARM_CODE_LOFI, PON_ALARM_CODE_RDII, PON_ALARM_CODE_LOAMI, PON_ALARM_CODE_LCDGI, PON_ALARM_CODE_LOAI, \
+ PON_ALARM_CODE_SDI, PON_ALARM_CODE_SFI, PON_ALARM_CODE_PEE, PON_ALARM_CODE_DGI, PON_ALARM_CODE_LOKI, \
+ PON_ALARM_CODE_TIWI, PON_ALARM_CODE_TIA, PON_ALARM_CODE_LAST_ALARM
+
+
+def general_param(parameter):
+ return PAS5211MsgGetGeneralParam(parameter=parameter)
+
+
+def io_ctrl_optics(i2c_clk, i2c_data, tx_enable, tx_fault,
+ tx_enable_polarity = PON_POLARITY_ACTIVE_LOW,
+ tx_fault_polarity= PON_POLARITY_ACTIVE_HIGH):
+ channel_optic_ctrl_if = PAS5211MsgSetOpticsIoControl()
+
+ channel_optic_ctrl_if.i2c_clk = i2c_clk
+ channel_optic_ctrl_if.i2c_data = i2c_data
+ channel_optic_ctrl_if.tx_enable = tx_enable
+ channel_optic_ctrl_if.tx_fault = tx_fault
+ channel_optic_ctrl_if.tx_enable_polarity = tx_enable_polarity
+ channel_optic_ctrl_if.tx_fault_polarity = tx_fault_polarity
+
+ return channel_optic_ctrl_if
+
+
+def burst_timing(single, double, snr_burst=None, rng_burst=None):
+ return BurstTimingCtrl(snr_burst_delay=snr_burst, rng_burst_delay=rng_burst,
+ burst_delay_single=single, burst_delay_double=double)
+
+
+def olt_optics_pkt(voltage, burst=None, general=None, reset=None, preamble=None):
+ return PAS5211MsgSetOltOptics(burst_timing_ctrl=burst,
+ general_optics_params=general,
+ voltage_if_mode=voltage,
+ reset_timing_ctrl=reset,
+ preamble_params=preamble)
+
+def alarm_config(type, activate, parameters=[None, None, None, None]):
+ while len(parameters) != 4:
+ parameters.append(None)
+ return PAS5211MsgSetAlarmConfig(type=get_alarm_code_for_type(type),
+ activate=activate,
+ parameter1=parameters[0],
+ parameter2=parameters[1],
+ parameter3=parameters[2],
+ parameter4=parameters[3])
+
+
+def get_alarm_code_for_type(type):
+ try:
+ return {
+ PON_ALARM_LOS : PON_ALARM_CODE_LOS,
+ PON_ALARM_LOSI : PON_ALARM_CODE_LOSI,
+ PON_ALARM_DOWI : PON_ALARM_CODE_DOWI,
+ PON_ALARM_LOFI : PON_ALARM_CODE_LOFI,
+ PON_ALARM_RDII : PON_ALARM_CODE_RDII,
+ PON_ALARM_LOAMI: PON_ALARM_CODE_LOAMI,
+ PON_ALARM_LCDGI: PON_ALARM_CODE_LCDGI,
+ PON_ALARM_LOAI : PON_ALARM_CODE_LOAI,
+ PON_ALARM_SDI : PON_ALARM_CODE_SDI,
+ PON_ALARM_SFI : PON_ALARM_CODE_SFI,
+ PON_ALARM_PEE : PON_ALARM_CODE_PEE,
+ PON_ALARM_DGI : PON_ALARM_CODE_DGI,
+ PON_ALARM_LOKI : PON_ALARM_CODE_LOKI,
+ PON_ALARM_TIWI : PON_ALARM_CODE_TIWI,
+ PON_ALARM_TIA : PON_ALARM_CODE_TIA
+ }[type]
+ except KeyError, e:
+ return PON_ALARM_CODE_LAST_ALARM
+
diff --git a/voltha/adapters/microsemi/RubyAdapter.py b/voltha/adapters/microsemi/RubyAdapter.py
index 086bd33..0d57a65 100644
--- a/voltha/adapters/microsemi/RubyAdapter.py
+++ b/voltha/adapters/microsemi/RubyAdapter.py
@@ -20,13 +20,10 @@
import structlog
from twisted.internet import reactor
from voltha.adapters.interface import IAdapterInterface
-from voltha.adapters.microsemi.PAS5211 import PAS5211MsgGetOltVersion, PAS5211MsgGetOltVersionResponse
+from voltha.adapters.microsemi.OltStateMachine import OltStateMachine
from voltha.adapters.microsemi.PAS5211_comm import PAS5211Communication
-from voltha.adapters.microsemi.StateMachine import Disconnected, States
from voltha.protos import third_party
-from voltha.protos.adapter_pb2 import Adapter, AdapterConfig, DeviceTypes
-from voltha.protos.health_pb2 import HealthStatus
from zope.interface import implementer
@@ -45,7 +42,10 @@
self.descriptor = None
self.comm = comm = PAS5211Communication(dst_mac=olt_conf['olts']['mac'],
iface=olt_conf['iface'])
- self.olt = Disconnected(comm)
+ self.olt = OltStateMachine(iface=olt_conf['iface'],
+ comm=comm,
+ target=olt_conf['olts']['mac'])
+
def start(self):
log.info('starting')
@@ -55,7 +55,7 @@
def stop(self):
log.debug('stopping')
- self.olt.disconnect()
+ self.olt.stop()
log.info('stopped')
return self
@@ -65,12 +65,14 @@
return self.descriptor
def device_types(self):
- return DeviceTypes(
- items=[] # TODO
- )
+ pass
+ #return DeviceTypes(
+ # items=[] # TODO
+ #)
def health(self):
- return HealthStatus(state=HealthStatus.HealthState.HEALTHY)
+ pass
+ #return HealthStatus(state=HealthStatus.HealthState.HEALTHY)
def change_master_state(self, master):
raise NotImplementedError()
@@ -89,28 +91,8 @@
##
def __init_olt(self):
- olt = self.olt
- while not olt.abandon():
- if olt.state() == States.DISCONNECTED or olt.state() == States.FETCH_VERSION:
- olt.run()
- olt = olt.transition()
- elif olt.state() == States.CONNECTED:
- olt.run()
- break
- if olt.abandon():
- #TODO Add more info here
- log.info('Disconnecting this OLT')
- self.stop()
- self.olt = olt
+ self.olt.run()
- def __obtain_descriptor(self):
- layer = PAS5211MsgGetOltVersionResponse.name
- pkt = self.olt.send_msg(PAS5211MsgGetOltVersion())
- return Adapter(
- id='ruby-{}'.format(olt_conf['olts']['id']),
- vendor='Celestica',
- version='{}.{}.{}'.format(pkt[layer].major_firmware_version,
- pkt[layer].minor_firmware_version,
- pkt[layer].build_firmware_version))
+
diff --git a/voltha/adapters/microsemi/StateMachine.py b/voltha/adapters/microsemi/StateMachine.py
deleted file mode 100644
index 91d85bf..0000000
--- a/voltha/adapters/microsemi/StateMachine.py
+++ /dev/null
@@ -1,214 +0,0 @@
-#
-# Copyright 2016 the original author or authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""
-Base OLT State machine class
-"""
-import time
-
-from structlog import get_logger
-from twisted.internet import reactor, task
-from voltha.adapters.microsemi.PAS5211 import PAS5211MsgGetProtocolVersion, PAS5211MsgGetOltVersion
-
-log = get_logger()
-
-class States(object):
- DISCONNECTED = 0
- FETCH_VERSION = 1
- CONNECTED = 2
-
-# TODO convert to scapy automata
-class State(object):
-
- def __init__(self):
- pass
-
- """
- Attempt an operation towards the OLT
- """
- def run(self):
- raise NotImplementedError()
-
- """
- Dictates which state to transtion to.
- Predicated on the run operation to be successful.
- """
- def transition(self):
- raise NotImplementedError()
-
- """
- Returns the current state name
- """
- def state(self):
- raise NotImplementedError()
-
- """
- Returns any useful information for the given State
- """
- def value(self):
- raise NotImplementedError()
-
- """
- Sends a message to this olt
- """
- def send_msg(self, msg):
- raise NotImplementedError()
-
- """
- Disconnected an OLT.
- """
- def disconnect(self):
- raise NotImplementedError()
-
- """
- Indicates whether to abandon trying to connect.
- """
- def abandon(self):
- raise NotImplementedError()
-
-"""
-Represents an OLT in disconnected or pre init state.
-"""
-class Disconnected(State):
-
- def __init__(self, pas_comm, retry=3):
- self.comm = pas_comm
- self.completed = False
- self.packet = None
- self.retry = retry
- self.attempt = 1
-
- def run(self):
- self.packet = self.comm.communicate(PAS5211MsgGetProtocolVersion())
- if self.packet is not None:
- self.packet.show()
- self.completed = True
- else:
- if self.attempt <= self.retry:
- time.sleep(self.attempt)
- self.attempt += 1
- return self.completed
-
- def transition(self):
- if self.completed:
- return Fetch_Version(self.comm)
- else:
- return self
-
- def state(self):
- return States.DISCONNECTED
-
- def value(self):
- # TODO return a nicer value than the packet.
- return self.packet
-
- def send_msg(self, msg):
- raise NotImplementedError()
-
- def disconnect(self):
- pass
-
- def abandon(self):
- return self.attempt > self.retry
-
-"""
-Fetches the OLT version
-"""
-class Fetch_Version(State):
- def __init__(self, pas_comm):
- self.comm = pas_comm
- self.completed = False
- self.packet = None
-
- def run(self):
- self.packet = self.comm.communicate(PAS5211MsgGetOltVersion())
- if self.packet is not None:
- self.packet.show()
- self.completed = True
- return self.completed
-
- def transition(self):
- if self.completed:
- return Connected(self.comm)
- else:
- return self
-
- def state(self):
- return States.FETCH_VERSION
-
- def value(self):
- # TODO return a nicer value than the packet.
- return self.packet
-
- def send_msg(self, msg):
- raise NotImplementedError()
-
- def disconnect(self):
- raise NotImplementedError()
-
- def abandon(self):
- return False
-
-
-"""
-OLT is in connected State
-"""
-class Connected(State):
- def __init__(self, pas_comm):
- self.comm = pas_comm
- self.completed = False
- self.packet = None
- self.scheduled = False
- self.scheduledTask = task.LoopingCall(self.keepalive)
-
- def run(self):
- if not self.scheduled:
- self.scheduled = True
- self.scheduledTask.start(1.0)
-
- def transition(self):
- if self.completed:
- return Disconnected(self.comm)
- else:
- return self
-
- def state(self):
- return States.CONNECTED
-
- def value(self):
- # TODO return a nicer value than the packet.
- return self.packet
-
- def send_msg(self, msg):
- return self.comm.communicate(msg)
-
- def keepalive(self):
- if self.completed:
- log.info('OLT has been disconnected')
- return
- self.packet = self.comm.communicate(PAS5211MsgGetOltVersion())
- if self.packet is None:
- self.completed = True
-
- def disconnect(self):
- print "Disconnecting OLT"
- if self.scheduled:
- self.completed = True
- self.scheduledTask.stop()
- return self.transition()
-
- def abandon(self):
- return False
\ No newline at end of file
diff --git a/voltha/adapters/microsemi/chat.py b/voltha/adapters/microsemi/chat.py
index cc69731..f4902ed 100755
--- a/voltha/adapters/microsemi/chat.py
+++ b/voltha/adapters/microsemi/chat.py
@@ -629,7 +629,7 @@
self.finished = False
def start(self):
- self.sock = s = conf.L2listen( type=ETH_P_ALL, iface=self.iface, filter='inbound')
+ self.sock = s = conf.L2listen(type=ETH_P_ALL, iface=self.iface, filter='inbound')
while not self.finished:
try:
sniffed = sniff(1, iface=self.iface, timeout=1, opened_socket=s)
diff --git a/voltha/adapters/microsemi/sniff.py b/voltha/adapters/microsemi/sniff.py
index 7ebf950..23cb7ee 100755
--- a/voltha/adapters/microsemi/sniff.py
+++ b/voltha/adapters/microsemi/sniff.py
@@ -420,7 +420,7 @@
class PAS5211MsgSetOltOpticsResponse(PAS5211Msg):
name = "PAS5211MsgSetOltOpticsResponse"
- fields_desc = [ ]
+ fields_desc = []
class PAS5211MsgSetOpticsIoControl(PAS5211Msg):
@@ -440,6 +440,8 @@
name = "PAS5211MsgSetOpticsIoControlResponse"
fields_desc = [ ]
+ def extract_padding(self, p):
+ return "", p
class PAS5211MsgSetGeneralParam(PAS5211Msg):
opcode = 164