Microsemi adapter updated
Change-Id: I841d7e1d6570fc8b8a8f59b680597d7cfa297539
diff --git a/voltha/adapters/microsemi_olt/APIProxy.py b/voltha/adapters/microsemi_olt/APIProxy.py
index ff9f466..1c92f0e 100644
--- a/voltha/adapters/microsemi_olt/APIProxy.py
+++ b/voltha/adapters/microsemi_olt/APIProxy.py
@@ -21,15 +21,19 @@
from scapy.automaton import ATMT
from voltha.adapters.microsemi_olt.BaseOltAutomaton import BaseOltAutomaton
-from voltha.adapters.microsemi_olt.PAS5211 import PAS5211MsgSendFrame, PAS5211MsgSendFrameResponse, \
- PAS5211EventFrameReceived
+from voltha.adapters.microsemi_olt.PAS5211 import PAS5211MsgSendFrame, PAS5211MsgGetOltVersionResponse, PAS5211MsgSendFrameResponse, \
+ PAS5211EventFrameReceived, PAS5211MsgHeader, PAS5211SetVlanGenConfigResponse
+
+from voltha.extensions.omci.omci_frame import OmciFrame
log = structlog.get_logger()
+
class APIProxy(BaseOltAutomaton):
proxy_address = None
msg = None
+ opcode = None
def parse_args(self, debug=0, store=0, **kwargs):
self.adaptor_agent = kwargs.pop('adapter_agent')
@@ -38,6 +42,37 @@
BaseOltAutomaton.parse_args(self, debug=debug, store=store, **kwargs)
+ def restart(self, *args, **kargs):
+ self.msg = kargs.pop('msg')
+ super(APIProxy, self).restart()
+
+ def master_filter(self, pkt):
+
+ if not super(APIProxy, self).master_filter(pkt):
+ return False
+
+ if not self.proxy_address.channel_id:
+ self.proxy_address.channel_id = 0
+
+ if not self.proxy_address.onu_id:
+ self.proxy_address.onu_id = 0
+
+ # if OmciFrame in pkt:
+ # # if pkt[OmciFrame].message_type in (16, 17):
+ # return False
+
+
+ if PAS5211MsgHeader in pkt:
+ if PAS5211MsgGetOltVersionResponse not in pkt:
+ if pkt[PAS5211MsgHeader].channel_id == self.proxy_address.channel_id:
+ if pkt[PAS5211MsgHeader].onu_id == self.proxy_address.onu_id:
+ if OmciFrame not in pkt:
+ rcv_opcode = pkt[PAS5211MsgHeader].opcode & 0xFF
+ if rcv_opcode == self.opcode:
+ return True
+
+ return False
+
"""
States
"""
@@ -53,19 +88,26 @@
@ATMT.state(error=1)
def error(self, msg):
log.error(msg)
+ raise self.end()
+
@ATMT.state(final=1)
def end(self):
- pass
+ log.debug('api-msg-end')
+ # pass
"""
Utils
"""
def px(self, pkt):
- return self.p(pkt, channel_id=self.proxy_address.channel_id,
- onu_id=self.proxy_address.onu_id,
- onu_session_id=self.proxy_address.onu_session_id)
+
+ if not self.proxy_address.channel_id:
+ self.proxy_address.channel_id = 0
+
+ return self.p(pkt, channel_id=self.proxy_address.channel_id,
+ onu_id=self.proxy_address.onu_id,
+ onu_session_id=self.proxy_address.onu_session_id)
"""
Transitions
@@ -73,21 +115,26 @@
@ATMT.condition(send_msg)
def send_api_msg(self):
+ log.debug('send-api-msg')
self.opcode = self.msg.opcode & 0xFF
self.send(self.px(self.msg))
raise self.wait_response()
# Transitions from wait_event
- @ATMT.timeout(wait_response, 3)
+ @ATMT.timeout(wait_response, 10)
def timeout_wait_response(self):
- raise self.error("No OMCI event for {}".format(self.proxy_address))
+ log.debug('api-proxy-timeout')
+ # Send empty packet...
+ self.adaptor_agent.receive_proxied_message(self.proxy_address, dict());
+ raise self.error("No API event for {}".format(self.proxy_address))
@ATMT.receive_condition(wait_response)
def wait_for_response(self, pkt):
- if PAS5211EventFrameReceived in pkt:
- rcv_opcode = pkt.opcode & 0xFF
- if rcv_opcode == self.opcode:
- # FIXME we may need to verify the transaction id
- # to make sure we have the right packet
- self.adaptor_agent.recieve_proxied_message(self.proxy_address,pkt)
- raise self.end()
+ if PAS5211MsgHeader in pkt: # and not isinstance(pkt, OmciFrame):
+ log.debug("adaptor-rcv", adaptor=self.adaptor_agent)
+ self.adaptor_agent.receive_proxied_message(self.proxy_address, pkt['PAS5211MsgHeader'])
+ raise self.end()
+
+ def __del__(self):
+ log.debug("APIProxy deleted")
+ super(APIProxy, self).__del__()
\ No newline at end of file
diff --git a/voltha/adapters/microsemi_olt/ActivationWatcher.py b/voltha/adapters/microsemi_olt/ActivationWatcher.py
index 70dd42f..47bc6e0 100644
--- a/voltha/adapters/microsemi_olt/ActivationWatcher.py
+++ b/voltha/adapters/microsemi_olt/ActivationWatcher.py
@@ -15,6 +15,9 @@
#
from struct import pack, unpack
+from twisted.internet import reactor
+from twisted.internet.defer import DeferredQueue, inlineCallbacks, returnValue
+
from scapy.automaton import ATMT
import structlog
from voltha.adapters.microsemi_olt.BaseOltAutomaton import BaseOltAutomaton
@@ -25,31 +28,44 @@
PAS5211MsgGetDbaMode, PAS5211MsgGetDbaModeResponse, PAS5211MsgSendDbaAlgorithmMsg, \
PAS5211MsgSendDbaAlgorithmMsgResponse, PAS5211EventDbaAlgorithm, PAS5211MsgSetPortIdConfig, \
PAS5211MsgSetPortIdConfigResponse, PAS5211MsgGetOnuIdByPortId, PAS5211MsgGetOnuIdByPortIdResponse, \
- PAS5211SetVlanUplinkConfiguration, PAS5211SetVlanUplinkConfigurationResponse, PAS5211MsgSetOnuAllocIdResponse
+ PAS5211SetVlanUplinkConfiguration, PAS5211SetVlanUplinkConfigurationResponse, PAS5211MsgSetOnuAllocIdResponse, \
+ PAS5211MsgHeader, PAS5211MsgGetOltVersionResponse, PAS5211EventOnuDeactivation, PAS5211EventAlarmNotification
+ #PAS5211EventAlarmNotification, PAS5211EventOnuDeactivation
from voltha.adapters.microsemi_olt.PAS5211_constants import PON_ACTIVATION_AUTH_AUTO, PON_ENABLE, PON_PORT_PON, \
PON_LOGICAL_OBJECT_TYPE_ALLOC_ID, PON_LOGICAL_OBJECT_TYPE_ONU_ID_BY_ALLOC_ID, PON_TRUE, \
PMC_OFAL_MAX_BI_DIRECTIONAL_FLOW_PER_ONU, PMC_OFAL_START_FLOW_ID_BASE, PON_DBA_MODE_RUNNING, \
PYTHAGORAS_UPDATE_AID_SLA, SLA_be_bw_gros, SLA_gr_bw_gros, SLA_gr_bw_fine, SLA_be_bw_fine, PYTHAGORAS_DBA_DATA_COS, \
PYTHAGORAS_DBA_STATUS_REPORT_NSR, PYTHAGORAS_SET_SLA_RESP_SIZE, PON_PORT_TYPE_GEM, PON_PORT_DESTINATION_CNI0, \
- PON_FALSE, PON_DISABLE
+ PON_FALSE, PON_DISABLE, PON_ALARM_LOS, PASCOMM_RETRIES, \
+ 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, PON_ALARM_AUTH_FAILED_IN_REGISTRATION_ID_MODE, PON_ALARM_SUFI
from voltha.extensions.omci.omci_entities import CircuitPack
from voltha.extensions.omci.omci_frame import OmciFrame
from voltha.extensions.omci.omci_messages import OmciGet, OmciGetResponse
+from twisted.internet import reactor
+
+from voltha.protos.events_pb2 import AlarmEvent, AlarmEventType, \
+ AlarmEventSeverity, AlarmEventState, AlarmEventCategory, AlarmEventCategory
+
log = structlog.get_logger()
_verbose = False
ALLOC_ID = 1000
+
def alloc_id(onu_id):
for i in range(0, PMC_OFAL_MAX_BI_DIRECTIONAL_FLOW_PER_ONU):
alloc_id = PMC_OFAL_START_FLOW_ID_BASE + \
- (onu_id * PMC_OFAL_MAX_BI_DIRECTIONAL_FLOW_PER_ONU) + i
+ (onu_id * PMC_OFAL_MAX_BI_DIRECTIONAL_FLOW_PER_ONU) + i
yield alloc_id
+
def hexstring(string):
return ":".join("{:02x}".format(ord(c)) for c in string)
+
class ActivationManager(BaseOltAutomaton):
onu_id = None
@@ -59,14 +75,17 @@
channel_id = None
alloc_id = None
vendor = None
+ olt_adapter = None
- def parse_args(self, debug=0, store=0, **kwargs):
+ def parse_args(self, debug=0, store=0,**kwargs):
self.onu_id = kwargs.pop('onu_id')
self.serial_number = kwargs.pop('serial_number')
self.onu_session_id = kwargs.pop('onu_session_id')
self.port_id = self.onu_id
self.channel_id = kwargs.pop('channel_id')
self.alloc_id = alloc_id(self.onu_id)
+ self.activation_watcher = kwargs.pop('activation_watcher')
+ self.olt_adapter = kwargs.pop('olt_adapter')
if self.onu_id is None or self.serial_number is None or \
self.onu_session_id is None or self.channel_id is None:
@@ -75,6 +94,37 @@
BaseOltAutomaton.parse_args(self, debug=debug, store=store, **kwargs)
"""
+ Master filter: Do not allow PAS5211MsgGetOltVersionResponse
+ """
+
+ def master_filter(self, pkt):
+
+ if not super(ActivationManager, self).master_filter(pkt):
+ return False
+
+
+ if OmciFrame in pkt:
+ if pkt[OmciFrame].message_type in (16, 17):
+ return False
+
+ if PAS5211MsgGetOltVersionResponse not in pkt:
+ if PAS5211MsgHeader in pkt:
+ if pkt[PAS5211MsgHeader].channel_id == self.channel_id:
+ return True
+
+ return False
+
+ def create_default_data_flow_olt_config(self):
+ # PAS_set_onu_alloc_id
+ # PYTHAGORAS_set_SLA
+ # PAS_map_port_id_to_alloc_id
+ # PAS_set_vlan_uplink_configuration
+ pass
+
+ # def register_activation_watcher(self, activation_watcher):
+ # self.activation_watcher = activation_watcher
+
+ """
States
"""
@@ -118,33 +168,16 @@
def wait_dba_mode(self):
pass
- @ATMT.state()
- def wait_send_dba_alg_msg(self):
- pass
-
- @ATMT.state()
- def wait_dba_alg_event(self):
- pass
-
- @ATMT.state()
- def wait_set_port_id_config(self):
- pass
-
- @ATMT.state()
- def wait_get_onu_id_by_port_id(self):
- pass
-
- @ATMT.state()
- def wait_set_vlan_uplink_config(self):
- pass
-
@ATMT.state(final=1)
def end(self):
- pass
+ log.debug("activation-manager-end")
+ self.activation_watcher.next_activation()
+
@ATMT.state(error=1)
def error(self, msg):
log.error(msg)
+ raise self.end()
"""
Utility Methods
@@ -155,17 +188,25 @@
onu_id=self.onu_id, onu_session_id=self.onu_session_id)
def detect_onu(self):
- log.info("Activated {} ONT".format(self.vendor))
try:
+ log.info("Activated {} ONT, channel_id={}, onu_id={}, session_id={}, serial={} ".format(
+ self.vendor, self.channel_id, self.onu_id, self.onu_session_id, hexstring(self.serial_number)))
+
+ parent_port = self.channel_id * 32 + (self.onu_id + 1)
+ self.olt_adapter.add_onu_info(parent_port, self.onu_id, self.onu_session_id)
+
self.device.onu_detected(
- parent_port_no=self.channel_id,
+ parent_port_no=parent_port,
child_device_type='%s_onu' % self.vendor.lower(),
onu_id=self.onu_id,
serial_number=hexstring(self.serial_number),
- onu_session_id=self.onu_session_id
+ onu_session_id=self.onu_session_id,
+ channel_id=self.channel_id
)
+
except Exception as e:
- print e
+ log.exception('failed', e=e)
+ raise e
"""
Transitions
@@ -174,31 +215,38 @@
# Transition from got_activation_event
@ATMT.condition(got_activation_event)
def send_get_activation_auth_mode(self):
+ log.debug('PAS5211MsgGetActivationAuthMode, channel_id={}'.format(self.channel_id))
auth_mode = PAS5211MsgGetActivationAuthMode()
- self.send(self.p(auth_mode))
+ self.send(self.p(auth_mode, channel_id=self.channel_id))
raise self.wait_get_auth_mode()
# Transitions from wait_get_auth_mode
@ATMT.timeout(wait_get_auth_mode, 3)
def timeout_get_auth_mode(self):
raise self.error('Could not get auth mode for OLT {}; dropping activation event for {}'
- .format(self.target, hexstring(self.serial_number)))
+ .format(self.target, hexstring(self.serial_number)))
@ATMT.receive_condition(wait_get_auth_mode)
def wait_for_get_auth_mode(self, pkt):
+ log.debug('wait_for_get_auth_mode')
if PAS5211MsgGetActivationAuthModeResponse in pkt:
+ log.debug('PAS5211MsgGetActivationAuthModeResponse')
+ pkt = pkt[PAS5211MsgGetActivationAuthModeResponse]
if pkt.mode == PON_ACTIVATION_AUTH_AUTO:
raise self.got_auth_mode()
else:
# TODO There may be something that can be done here.
# See line 2497 of PAS_onu_mode_change_thread.c
- log.error('Got unknown auth mode {}; dropping activation event'.format(pkt.mode))
+ log.error(
+ 'Got unknown auth mode {}; dropping activation event'.format(pkt.mode))
raise self.end()
# Transitions from got auth_mode
@ATMT.condition(got_auth_mode)
def send_omci_port_id(self):
- omci_port_id = PAS5211MsgSetOnuOmciPortId(port_id=self.port_id, activate=PON_ENABLE)
+ log.debug('send_omci_port_id')
+ omci_port_id = PAS5211MsgSetOnuOmciPortId(
+ port_id=self.port_id, activate=PON_ENABLE)
self.send(self.px(omci_port_id))
raise self.wait_omci_port_id()
@@ -206,34 +254,32 @@
@ATMT.timeout(wait_omci_port_id, 3)
def timeout_omci_port_id(self):
raise self.error('Could not set omci port id for OLT {}; dropping activation event for {}'
- .format(self.target, hexstring(self.serial_number)))
+ .format(self.target, hexstring(self.serial_number)))
@ATMT.receive_condition(wait_omci_port_id)
def wait_for_omci_port_id(self, pkt):
- if pkt.opcode == PAS5211MsgSetOnuOmciPortIdResponse.opcode and \
- pkt.onu_id == self.onu_id and pkt.onu_session_id == self.onu_session_id and \
- pkt.channel_id == self.channel_id:
- raise self.got_omci_port_id()
+ log.debug('wait_for_omci_port_id')
+ if PAS5211MsgSetOnuOmciPortIdResponse in pkt:
+ log.debug('PAS5211MsgSetOnuOmciPortIdResponse')
+ msg_header = pkt[PAS5211MsgHeader]
+ if msg_header.opcode == PAS5211MsgSetOnuOmciPortIdResponse.opcode and \
+ msg_header.onu_id == self.onu_id and msg_header.onu_session_id == self.onu_session_id and \
+ msg_header.channel_id == self.channel_id:
+ raise self.got_omci_port_id()
# Transitions from got_omci_port_id
@ATMT.condition(got_omci_port_id)
def send_omci_identity_frame(self):
- # attr_mask |= OMCI_ATTR_BIT(OMCI_CIRCUIT_PACK_ATTR_VENDOR_ID);
- #message.attributes_mask = 2048
+ log.debug('send_omci_identity_frame')
- # Entity_id
- # equip_ind = OMCI_CIRCUIT_PACK_INTEGRATED_EQUIPMENT;
- # slot_id = 257;
- # entity_instance = ((equip_ind<<8) | slot_id
- message = OmciGet(entity_class=CircuitPack.class_id, entity_id = 257,
+ message = OmciGet(entity_class=CircuitPack.class_id, entity_id=257,
attributes_mask=2048)
- #TODO fix transaction id
+ # TODO fix transaction id
frame = OmciFrame(transaction_id=0, message_type=OmciGet.message_id,
omci_message=message)
omci_frame = PAS5211MsgSendFrame(port_type=PON_PORT_PON, port_id=self.port_id,
management_frame=PON_ENABLE, frame=frame)
-
self.send(self.px(omci_frame))
raise self.wait_send_frame()
@@ -242,195 +288,183 @@
@ATMT.timeout(wait_send_frame, 3)
def timeout_send_frame(self):
raise self.error('Could not send omci to OLT {}; dropping activation event for {}'
- .format(self.target, hexstring(self.serial_number)))
+ .format(self.target, hexstring(self.serial_number)))
@ATMT.receive_condition(wait_send_frame)
def wait_for_send_frame(self, pkt):
+ log.debug('wait_for_send_frame')
if PAS5211MsgSendFrameResponse in pkt:
+ log.debug('PAS5211MsgSendFrameResponse')
raise self.wait_omci_get()
# Transitions from wait_omci_get
@ATMT.timeout(wait_omci_get, 3)
- def timeout_send_frame(self):
+ def timeout_omci_get(self):
raise self.error('Did not receive omci get event from OLT {}; dropping activation event for {}'
- .format(self.target, hexstring(self.serial_number)))
+ .format(self.target, hexstring(self.serial_number)))
@ATMT.receive_condition(wait_omci_get)
def wait_for_omci_get(self, pkt):
+ log.debug('wait_for_omci_get')
if OmciGetResponse in pkt:
+ log.debug('OmciGetResponse')
self.allocId = self.alloc_id.next()
- self.vendor = pkt['OmciGetResponse'].data['vendor_id']
+ #self.vendor = pkt['OmciGetResponse'].data['vendor_id']
+ self.vendor = pkt[OmciGetResponse].data['vendor_id']
+ log.debug('wait_for_omci_get vendor_id:' + self.vendor)
l_obj_status = PAS5211MsgGetLogicalObjectStatus(
- type=PON_LOGICAL_OBJECT_TYPE_ALLOC_ID,
- value=self.allocId)
- self.send(self.px(l_obj_status))
+ type=PON_LOGICAL_OBJECT_TYPE_ALLOC_ID,
+ value=self.allocId)
+ self.send(self.p(l_obj_status, channel_id=self.channel_id))
raise self.wait_logical_object_status()
# Transitions from wait_logical_object_status
@ATMT.timeout(wait_logical_object_status, 3)
def timeout_logical_object_status(self):
raise self.error('Did not receive info about alloc id status for {}; dropping activation event for {}'
- .format(self.target, hexstring(self.serial_number)))
+ .format(self.target, hexstring(self.serial_number)))
@ATMT.receive_condition(wait_logical_object_status)
def wait_for_logical_object_status(self, pkt):
+ log.debug('wait_for_logical_object_status')
if PAS5211MsgGetLogicalObjectStatusResponse in pkt:
- if pkt.type == PON_LOGICAL_OBJECT_TYPE_ALLOC_ID:
+ pkt = pkt[PAS5211MsgGetLogicalObjectStatusResponse]
+ log.debug('PAS5211MsgGetLogicalObjectStatusResponse pkt.type=' + str(pkt.type) + ' pkt.return_value=' + str(
+ pkt.return_value))
+ if pkt.type == PON_LOGICAL_OBJECT_TYPE_ALLOC_ID: # PASCOMM_GPON_api_parser.c line:11994
if pkt.return_value == 0:
+ log.debug(
+ 'PAS5211MsgGetLogicalObjectStatusResponse (pkt.return_value == 0)')
# alloc-id not set
set_alloc_id = PAS5211MsgSetOnuAllocId(
- alloc_id=self.allocId,
- allocate=PON_ENABLE
- )
- self.onu_id = -1
+ alloc_id=self.allocId,
+ allocate=PON_ENABLE
+ )
+ # self.onu_id = -1
self.port_id = self.allocId
self.send(self.px(set_alloc_id))
raise self.wait_set_alloc_id()
else:
+ log.debug(
+ 'PAS5211MsgGetLogicalObjectStatusResponse (pkt.return_value != 0)')
l_obj_status = PAS5211MsgGetLogicalObjectStatus(
type=PON_LOGICAL_OBJECT_TYPE_ONU_ID_BY_ALLOC_ID,
value=self.allocId)
self.send(self.px(l_obj_status))
raise self.wait_logical_object_status()
elif pkt.type == PON_LOGICAL_OBJECT_TYPE_ONU_ID_BY_ALLOC_ID:
+ log.debug(
+ 'PAS5211MsgGetLogicalObjectStatusResponse (pkt.type == PON_LOGICAL_OBJECT_TYPE_ALLOC_ID)')
# That's your onu id.
self.onu_id = pkt.return_value
# FIXME Need to iterate to get the port id as
# in PMC_OFAL_flow_db.c line 656
- # UPDATE PORT_ID
set_alloc_id = PAS5211MsgSetOnuAllocId(
alloc_id=self.allocId,
allocate=PON_ENABLE
)
self.send(self.px(set_alloc_id))
- raise self.wait_for_set_alloc_id() #FIXME are we done? probably not but check
+ raise self.wait_set_alloc_id() # are we done? probably not but check
# Transitions from wait_set_alloc_id
@ATMT.timeout(wait_set_alloc_id, 3)
def timeout_set_alloc_id(self):
raise self.error('Was not able to set alloc id for {}; dropping activation event for {}'
- .format(self.target, hexstring(self.serial_number)))
+ .format(self.target, hexstring(self.serial_number)))
@ATMT.receive_condition(wait_set_alloc_id)
def wait_for_set_alloc_id(self, pkt):
+ log.debug('wait_for_set_alloc_id')
if PAS5211MsgSetOnuAllocIdResponse in pkt:
- self.send(self.px(PAS5211MsgGetDbaMode()))
+ self.send(self.p(PAS5211MsgGetDbaMode(),
+ channel_id=self.channel_id))
raise self.wait_dba_mode()
- # Transitions from wait for dba mode (See Pythagoras_api.c line 344 & PMC_OFAL.c 2062)
+ # Transitions from wait for dba mode (See Pythagoras_api.c line 344 &
+ # PMC_OFAL.c 2062)
@ATMT.timeout(wait_dba_mode, 3)
def timeout_wait_dba_mode(self):
raise self.error('Did not get DBA mode for {}; dropping activation event for {}'
- .format(self.target, hexstring(self.serial_number)))
-
+ .format(self.target, hexstring(self.serial_number)))
@ATMT.receive_condition(wait_dba_mode)
def wait_for_dba_mode(self, pkt):
if PAS5211MsgGetDbaModeResponse in pkt:
+ pkt = pkt[PAS5211MsgGetDbaModeResponse]
if pkt.dba_mode != PON_DBA_MODE_RUNNING:
raise self.error('DBA is not running; dropping activation event for {}'
- .format(hexstring(self.serial_number)))
-
- data = pack('<LLHHBBBB', PYTHAGORAS_UPDATE_AID_SLA,
- self.allocId, SLA_gr_bw_gros, SLA_be_bw_gros,
- SLA_gr_bw_fine, SLA_be_bw_fine, PYTHAGORAS_DBA_DATA_COS,
- PYTHAGORAS_DBA_STATUS_REPORT_NSR)
-
- send_dba_alg = PAS5211MsgSendDbaAlgorithmMsg(data=data)
- self.send(self.px(send_dba_alg))
- raise self.wait_send_dba_alg_msg()
-
- # Transitions from wait_send_dba_alg_msg
- @ATMT.timeout(wait_send_dba_alg_msg, 3)
- def timeout_wait_for_send_dba_alg_msg(self):
- raise self.error('Unable to set dba alg params for {}; dropping activation event for {}'
- .format(self.target, hexstring(self.serial_number)))
-
- @ATMT.receive_condition(wait_send_dba_alg_msg)
- def wait_for_send_dba_alg_msg(self, pkt):
- if PAS5211MsgSendDbaAlgorithmMsgResponse in pkt:
- raise self.wait_dba_alg_event()
-
- # Transitions from wait_dba_alg_event
- @ATMT.timeout(wait_dba_alg_event, 3)
- def timeout_wait_for_send_dba_alg_event(self):
- raise self.error('DBA params ont set for {}; dropping activation event for {}'
- .format(self.target, hexstring(self.serial_number)))
-
- @ATMT.receive_condition(wait_dba_alg_event)
- def wait_for_send_dba_alg_event(self, pkt):
- if PAS5211EventDbaAlgorithm in pkt:
- if pkt.size < PYTHAGORAS_SET_SLA_RESP_SIZE:
- raise self.error('DBA Event message too small for {}, dropping activation event for {}'
- .format(self.target, hexstring(self.serial_number)))
-
- (_, aid, _) = unpack('<LLH',pkt.data)
- if aid == self.allocId:
- # All is well moving on.
- # There is some more shit at PYTHAGORAS.c line 395 but fuck it.
- set_port_id_config = PAS5211MsgSetPortIdConfig(
- port_id=self.port_id,
- activate=PON_ENABLE,
- alloc_id=self.allocId,
- type=PON_PORT_TYPE_GEM,
- destination=PON_PORT_DESTINATION_CNI0
- )
- self.send(self.px(set_port_id_config))
- raise self.wait_set_port_id_config()
-
- # Transitions from wait_set_port_id_config
- @ATMT.timeout(wait_set_port_id_config, 3)
- def timeout_wait_set_port_id_config(self):
- raise self.error('Could not set port id config for {}; dropping activation event for {}'
- .format(self.target, hexstring(self.serial_number)))
-
- @ATMT.receive_condition(wait_set_port_id_config)
- def wait_for_set_port_id_config(self, pkt):
- if PAS5211MsgSetPortIdConfigResponse in pkt:
- get_onu_id = PAS5211MsgGetOnuIdByPortId(
- port_id=self.port_id
- )
- self.send(self.px(get_onu_id))
- raise self.wait_get_onu_id_by_port_id()
-
- # Transistions from wait_get_onu_id_by_port_id
- @ATMT.timeout(wait_get_onu_id_by_port_id, 3)
- def timeout_wait_get_onu_id_by_port_id(self):
- raise self.error('Could not get onu id for {}; dropping activation event for {}'
- .format(self.target, hexstring(self.serial_number)))
-
- @ATMT.receive_condition(wait_get_onu_id_by_port_id)
- def wait_for_get_onu_id_by_port_id(self, pkt):
- if PAS5211MsgGetOnuIdByPortIdResponse in pkt:
- self.onu_id = pkt['PAS5211MsgGetOnuIdByPortIdResponse'].onu_id
- # There may be more things to do here. but traces indicate that no.
- # see PAS.c line 977 and onwards.
- set_vlan_uplink_config = PAS5211SetVlanUplinkConfiguration(
- port_id=self.port_id,
- pvid_config_enabled=PON_FALSE,
- min_cos=0,
- max_cos=7,
- de_bit=PON_DISABLE
- )
- self.send(self.px(set_vlan_uplink_config))
- raise self.wait_set_vlan_uplink_config()
-
- # Transitions from wait_set_vlan_uplink_config
- @ATMT.timeout(wait_set_vlan_uplink_config, 3)
- def timeout_wait_set_vlan_uplink_config(self):
- raise self.error('Could not set vlan uplink config for {}; dropping activation event for {}'
- .format(self.target, hexstring(self.serial_number)))
-
- @ATMT.receive_condition(wait_set_vlan_uplink_config)
- def wait_for_set_vlan_uplink_config(self, pkt):
- if PAS5211SetVlanUplinkConfigurationResponse in pkt:
- # YAY we made it.
- # TODO update OLT with CNI port
+ .format(hexstring(self.serial_number)))
self.detect_onu()
raise self.end()
-
+
class ActivationWatcher(BaseOltAutomaton):
+ """
+ Master filter: Do not allow PAS5211MsgGetOltVersionResponse
+ """
+
+ pending_activation_events = []
+ activation_lock = False
+ olt_adapter = None
+
+ def master_filter(self, pkt):
+ if not super(ActivationWatcher, self).master_filter(pkt):
+ return False
+
+ if PAS5211EventOnuActivation in pkt:
+ return True
+
+ elif PAS5211EventOnuDeactivation in pkt:
+ return True
+
+ elif PAS5211EventAlarmNotification in pkt:
+ return True
+
+ return False
+
+
+ # Callback from activation manager
+ def next_activation(self):
+ log.debug("next-activation")
+ if self.pending_activation_events:
+ self.activation_lock=True
+ # Retrieve last element from list
+ pkt = self.pending_activation_events.pop()
+ self.activate_onu(pkt)
+ else:
+ self.activation_lock = False
+
+ def parse_args(self, debug=0, store=0,**kwargs):
+ self.olt_adapter = kwargs.pop('olt_adapter')
+ BaseOltAutomaton.parse_args(self, **kwargs)
+
+ def activate_onu(self, pkt):
+ log.debug("activate-onu")
+ msg_header = pkt[PAS5211MsgHeader]
+ msg = pkt[PAS5211EventOnuActivation]
+ log.debug('{} activated'.format(hexstring(msg.serial_number)))
+ onu_activation = ActivationManager(iface=self.iface, target=self.target, comm=self.comm,
+ onu_id=msg_header.onu_id, serial_number=msg.serial_number,
+ onu_session_id=msg_header.onu_session_id,
+ channel_id=msg_header.channel_id, device=self.device, activation_watcher=self, olt_adapter=self.olt_adapter)
+
+ onu_activation.runbg()
+
+ def deactivate_onu(self, pkt):
+ log.debug("deactivate-onu")
+ msg_header = pkt[PAS5211MsgHeader]
+ try:
+ log.debug("Deactivating ONT, channel_id={}, onu_id={}, session_id={},".format(
+ msg_header.channel_id, msg_header.onu_id, msg_header.onu_session_id))
+
+ self.device.deactivate_onu(channel_id=msg_header.channel_id,
+ onu_id=msg_header.onu_id,
+ onu_session_id=msg_header.onu_session_id)
+
+ log.debug("Deactivated ONT, channel_id={}, onu_id={}, session_id={} ".format(
+ msg_header.channel_id, msg_header.onu_id, msg_header.onu_session_id))
+ except Exception as e:
+ log.exception('deactivate-onu failed', e=e)
"""
States
@@ -448,10 +482,97 @@
@ATMT.receive_condition(wait_onu_activation_event)
def wait_for_onu_activation_event(self, pkt):
if PAS5211EventOnuActivation in pkt:
- log.info('{} activated'.format(hexstring(pkt.serial_number)))
- onu_activation = ActivationManager(iface=self.iface, target=self.target, comm=self.comm,
- onu_id=pkt.onu_id, serial_number=pkt.serial_number,
- onu_session_id=pkt.onu_session_id,
- channel_id=pkt.channel_id, device=self.device)
- onu_activation.runbg()
- raise self.wait_onu_activation_event()
+ log.debug('PAS5211EventOnuActivation Received')
+
+ self.pending_activation_events.append(pkt)
+
+ if not self.activation_lock:
+ self.next_activation()
+
+ elif PAS5211EventOnuDeactivation in pkt:
+ log.debug('PAS5211EventOnuDeactivation Received')
+ self.deactivate_onu(pkt)
+
+ elif PAS5211EventAlarmNotification in pkt:
+ log.debug('PAS5211EventAlarmNotification Received')
+ msg = pkt[PAS5211EventAlarmNotification]
+ log.debug('alarm:info - code: {} '.format(msg.code))
+ log.debug(' alarm:info - parameter1: {}'.format(msg.parameter1))
+ log.debug(' alarm:info - parameter2 {}'.format(msg.parameter2))
+ log.debug(' alarm:info - parameter3 {}'.format(msg.parameter3))
+ log.debug(' alarm:info - parameter4 {}'.format(msg.parameter4))
+ try:
+ self.process_alarm(pkt)
+ except Exception as e:
+ log.exception('Error at process_alarm', e=e)
+ else:
+ pass
+
+ raise self.wait_onu_activation_event()
+
+
+ #Method to parse alarm and send it to DeviceManager
+ def process_alarm(self, pkt):
+ log.debug('[Process_alarm] Starting')
+ msg_header = pkt[PAS5211MsgHeader]
+ msg = pkt[PAS5211EventAlarmNotification]
+ code = msg.code
+ ctx = {
+ 'alarm_code': str(code),
+ }
+
+ ctx = {}
+
+ #Define common alarm parameters
+ alarm = dict(
+ #id=None,
+ resource_id='voltha.olt-onuid('+str(msg_header.onu_id)+')',
+ id='voltha.olt',
+ raised_ts=None,
+ changed_ts=None,
+ type=AlarmEventType.EQUIPMENT,
+ # category=AlarmEventCategory.OLT,
+ # severity=AlarmEventSeverity.INDETERMINATE,
+ # state=AlarmEventState.RAISED,
+ context=ctx
+ )
+
+ #Define especific alarm parameters
+ if code == PON_ALARM_LOS:
+ alarm['description'] = 'Loss of signal: OLT does not receive transmissions in the upstream'
+ elif code == PON_ALARM_LOSI:
+ alarm['description'] = 'Loss of signal for ONUi: no signal from the ONU when expected'
+ elif code == PON_ALARM_DOWI:
+ alarm['description'] = 'Loss of signal for ONUi: no signal from the ONU when expected'
+ elif code == PON_ALARM_LOFI:
+ alarm['description'] = 'Loss of frame of ONUi: no valid optical signal is received from the ONU'
+ elif code == PON_ALARM_RDII:
+ alarm['description'] = 'Remote Defect Indication of ONUi: OLT transmissions is received with defect at the ONUi'
+ elif code == PON_ALARM_LOAMI:
+ alarm['description'] = 'Loss of PLOAM for ONUi: 3 messages of ONU are missing after OLT sends PLOAMu request'
+ elif code == PON_ALARM_LCDGI:
+ alarm['description'] = 'Loss of GEM channel delineation: GEM fragment delineation of ONUi is lost'
+ elif code == PON_ALARM_LOAI:
+ alarm['description'] = 'Loss of acknowledge with ONUi: OLT does not receive ack from ONUi'
+ elif code == PON_ALARM_SDI:
+ alarm['description'] = 'Signal Degraded of ONUi: raised when the upstream BER of ONUi goes below certain level'
+ elif code == PON_ALARM_SFI:
+ alarm['description'] = 'Signal Fail of ONUi: raised when the upstream of ONUi becomes greater than some level'
+ elif code == PON_ALARM_PEE:
+ alarm['description'] = 'Physical Equipment Error of ONUi: raised when the OLT receives a PEE message from the ONU'
+ elif code == PON_ALARM_DGI:
+ alarm['description'] = 'Dying Gasp of ONUi: raised when the OLT receives DG message from ONUi'
+ elif code == PON_ALARM_LOKI:
+ alarm['description'] = 'Loss of key synch with ONUi: Key transmission from ONU fails 3 times'
+ elif code == PON_ALARM_TIWI:
+ alarm['description'] = 'Transmission interference warning: raised when the drift of ONU transmissions exceeds specified threshold'
+ elif code == PON_ALARM_TIA:
+ alarm['description'] = 'Transmission Interference Alarm: an ONU turns on its laser at another ONUs time'
+ else:
+ log.error('Error, unsupported OLT Alarm {} received from OLT device'.format(code, self.device))
+ alarm['description'] = ''
+
+ log.debug('[Process_alarm] Send alarm to DeviceManager')
+ log.warn('Alarm: '+alarm['description']+' from '+alarm['id'])
+
+ self.device.publish_alarm(alarm)
diff --git a/voltha/adapters/microsemi_olt/DeviceManager.py b/voltha/adapters/microsemi_olt/DeviceManager.py
index d9499d5..c11119b 100644
--- a/voltha/adapters/microsemi_olt/DeviceManager.py
+++ b/voltha/adapters/microsemi_olt/DeviceManager.py
@@ -16,7 +16,7 @@
from uuid import uuid4
import structlog
-from voltha.adapters.microsemi_olt.PAS5211 import CHANNELS
+from voltha.adapters.microsemi_olt.PAS5211 import CHANNELS, PORTS
from voltha.protos.common_pb2 import ConnectStatus, OperStatus, AdminState
from voltha.protos.device_pb2 import Device, Port, Image
from voltha.protos.logical_device_pb2 import LogicalDevice, LogicalPort
@@ -25,6 +25,7 @@
log = structlog.get_logger()
+
def mac_str_to_tuple(mac):
"""
Convert 'xx:xx:xx:xx:xx:xx' MAC address string to a tuple of integers.
@@ -32,6 +33,7 @@
"""
return tuple(int(d, 16) for d in mac.split(':'))
+
class DeviceManager(object):
def __init__(self, device, adapter_agent):
@@ -55,13 +57,13 @@
# active, standby etc. Choose the active or running software
# below. See simulated_olt for example implementation
self.device.images.image.extend([
- Image(version="0.0.1")
- ])
+ Image(version="0.0.1")
+ ])
self.device.serial_number = self.device.mac_address
self.device.oper_status = ConnectStatus.REACHABLE
- self.adapter_agent.update_device(self.device)
+ # self.adapter_agent.update_device(self.device)
- for i in CHANNELS:
+ for i in PORTS:
self.adapter_agent.add_port(self.device.id, Port(
port_no=i,
label='PON port',
@@ -70,8 +72,15 @@
oper_status=OperStatus.ACTIVE
))
+ self.create_logical_device()
+ self.add_upstream_port(129)
+ self.add_logical_upstream_port(129)
+
+ self.device.parent_id = self.logical_device.id
+ self.adapter_agent.update_device(self.device)
+
def create_logical_device(self):
- log.info('create-logical-device')
+ log.debug('create-logical-device')
# then shortly after we create the logical device with one port
# that will correspond to the NNI port
ld = LogicalDevice(
@@ -94,7 +103,41 @@
root_device_id=self.device.id
)
- self.logical_device = self.adapter_agent.create_logical_device(ld)
+ self.logical_device = self.adapter_agent.create_logical_device(ld, dpid=self.device.mac_address)
+
+ def add_upstream_port(self, port):
+ nni_port = Port(
+ port_no=port,
+ label='NNI',
+ type=Port.ETHERNET_NNI,
+ admin_state=AdminState.ENABLED,
+ oper_status=OperStatus.ACTIVE
+ )
+ self.adapter_agent.add_port(self.device.id, nni_port)
+
+ def add_logical_upstream_port(self, port):
+
+ cap = OFPPF_10GB_FD | OFPPF_FIBER
+
+ self.adapter_agent.add_logical_port(self.logical_device.id, LogicalPort(
+ id='nni',
+ ofp_port=ofp_port(
+ port_no=port,
+ # hw_addr=mac_str_to_tuple(self.device.serial_number)[2:8],
+ hw_addr=mac_str_to_tuple('00:00:00:00:00:%02x' % port),
+ name='nni',
+ config=0,
+ state=OFPPS_LIVE,
+ curr=cap,
+ advertised=cap,
+ peer=cap,
+ curr_speed=OFPPF_10GB_FD,
+ max_speed=OFPPF_10GB_FD
+ ),
+ device_id=self.device.id,
+ device_port_no=port,
+ root_port=True
+ ))
def add_port(self, port):
self.adapter_agent.add_port(self.device.id, port)
@@ -119,27 +162,62 @@
logical_port)
def onu_detected(self, parent_port_no=None,
- child_device_type=None,
- onu_id=None,
- serial_number=None,
- onu_session_id=None):
- self.adapter_agent.child_device_detected(
- parent_device_id=self.device.id,
- parent_port_no=parent_port_no,
- child_device_type=child_device_type,
- serial_number=serial_number,
- proxy_address=Device.ProxyAddress(
+ child_device_type=None,
+ onu_id=None,
+ serial_number=None,
+ onu_session_id=None,
+ channel_id=None):
+ log.debug('onu-detected')
+ try:
+ self.adapter_agent.child_device_detected(
+ parent_device_id=self.device.id,
+ parent_port_no=parent_port_no,
+ child_device_type=child_device_type,
+ serial_number=serial_number,
+ proxy_address=Device.ProxyAddress(
+ device_id=self.device.id,
+ channel_id=channel_id, # happens to be the channel id as well
+ onu_id=onu_id,
+ onu_session_id=onu_session_id
+ ),
+ admin_state=AdminState.ENABLED,
+ vlan=0)
+ except Exception as e:
+ log.exception('onu-detected-failed', e=e)
+ raise e
+
+ def deactivate_onu(self, onu_id=None, channel_id=None, onu_session_id=None):
+ try:
+ child_device = self.adapter_agent.get_child_device_with_proxy_address(Device.ProxyAddress(
device_id=self.device.id,
- channel_id=parent_port_no, # happens to be the channel id as well
+ channel_id=channel_id,
onu_id=onu_id,
onu_session_id=onu_session_id
- ),
- admin_state=AdminState.ENABLED,
- vlan=0
- )
+ ))
+ if child_device:
+ # self.adapter_agent.update_child_device_state(child_device, admin_state=AdminState.DISABLED)
+ child_device.admin_state=AdminState.DISABLED
+ self.adapter_agent.update_device(child_device)
+ except KeyError:
+ log.debug("ONU {} cannot be deactivated".format(onu_id))
def activate(self):
- self.device = self.adapter_agent.get_device(self.device.id)
- self.device.parent_id = self.logical_device.id
+ # self.device = self.adapter_agent.get_device(self.device.id)
+ # self.device.parent_id = self.logical_device.id
self.device.oper_status = OperStatus.ACTIVE
self.adapter_agent.update_device(self.device)
+
+
+ def publish_alarm(self, alarm):
+ new_alarm = self.adapter_agent.create_alarm(
+ # id = alarm["id"],
+ resource_id = alarm["resource_id"],
+ description = alarm["description"],
+ type = alarm["type"],
+ # category = alarm["category"],
+ # severity = alarm["severity"],
+ # state = alarm["state"],
+ context = alarm["context"]
+ )
+ self.adapter_agent.submit_alarm(self.device.id, new_alarm)
+ log.debug("[publish_alarm]")
\ No newline at end of file
diff --git a/voltha/adapters/microsemi_olt/OMCIProxy.py b/voltha/adapters/microsemi_olt/OMCIProxy.py
index 58efaf6..670b247 100644
--- a/voltha/adapters/microsemi_olt/OMCIProxy.py
+++ b/voltha/adapters/microsemi_olt/OMCIProxy.py
@@ -26,6 +26,14 @@
from voltha.adapters.microsemi_olt.PAS5211_constants import PON_ENABLE, PON_TRUE
from voltha.adapters.microsemi_olt.PAS5211_constants import PON_PORT_PON
+from voltha.adapters.microsemi_olt.PAS5211 import PAS5211MsgHeader, PAS5211MsgGetOltVersionResponse, PAS5211MsgGetOltVersionResponse
+
+from voltha.extensions.omci.omci_messages import OmciMibResetResponse
+
+from voltha.extensions.omci.omci_frame import OmciFrame
+
+import sys, gc
+
log = structlog.get_logger()
@@ -40,6 +48,34 @@
self.msg = kwargs.pop('msg')
BaseOltAutomaton.parse_args(self, debug=debug, store=store, **kwargs)
+
+ def restart(self, *args, **kargs):
+ self.msg = kargs.pop('msg')
+ super(OMCIProxy, self).restart()
+
+
+ def master_filter(self, pkt):
+ if not super(OMCIProxy, self).master_filter(pkt):
+ return False
+
+ if not self.proxy_address.channel_id:
+ self.proxy_address.channel_id = 0
+
+ if not self.proxy_address.onu_id:
+ self.proxy_address.onu_id = 0
+
+ if PAS5211MsgHeader in pkt:
+ if PAS5211MsgGetOltVersionResponse not in pkt:
+ if pkt[PAS5211MsgHeader].channel_id == self.proxy_address.channel_id:
+ if pkt[PAS5211MsgHeader].onu_id == self.proxy_address.onu_id:
+ # OMCI response
+ if OmciFrame in pkt:
+ if pkt[OmciFrame].message_type not in (16, 17):
+ return True
+ # # SendFrameResponse corresponding to OMCI PAS request
+ elif PAS5211MsgSendFrameResponse in pkt:
+ return True
+ return False
"""
States
@@ -60,10 +96,12 @@
@ATMT.state(error=1)
def error(self, msg):
log.error(msg)
+ raise self.end()
@ATMT.state(final=1)
def end(self):
- pass
+ log.debug('omci-msg-end')
+ # pass
"""
Utils
@@ -80,17 +118,19 @@
@ATMT.condition(got_omci_msg)
def send_omci_msg(self):
- log.debug('send-omci-msg')
+ log.debug('send-omci-msg', proxy_address=self.proxy_address)
send_frame = PAS5211MsgSendFrame(port_type=PON_PORT_PON, port_id=self.proxy_address.onu_id,
management_frame=PON_TRUE, frame=self.msg)
to_send = self.px(send_frame)
- to_send.show()
self.send(to_send)
raise self.wait_send_response()
# Transitions from wait_send_response
- @ATMT.timeout(wait_send_response, 3)
+ @ATMT.timeout(wait_send_response, 10)
def timeout_wait_send_response(self):
+ log.debug('omci-proxy-timeout')
+ # Send back empty packet...
+ self.adaptor_agent.receive_proxied_message(self.proxy_address, dict())
raise self.error("No ack for OMCI for {}".format(self.proxy_address))
@ATMT.receive_condition(wait_send_response)
@@ -99,15 +139,25 @@
raise self.wait_event()
# Transitions from wait_event
- @ATMT.timeout(wait_event, 3)
+ @ATMT.timeout(wait_event, 20)
def timeout_wait_event(self):
+ log.debug('omci-proxy-timeout')
+ # Send back empty packet...
+ self.adaptor_agent.receive_proxied_message(self.proxy_address, dict())
raise self.error("No OMCI event for {}".format(self.proxy_address))
@ATMT.receive_condition(wait_event)
def wait_for_event(self, pkt):
if PAS5211EventFrameReceived in pkt:
+ log.debug("PAS5211EventFrameReceived")
# FIXME we may need to verify the transaction id
# to make sure we have the right packet
- self.adaptor_agent.recieve_proxied_message(self.proxy_address,
- pkt['PAS5211EventFrameReceived'])
+ # pkt.show()
+ # pkt['PAS5211EventFrameReceived'].show()
+ log.debug("rcv-omci-msg", proxy_address=self.proxy_address)
+ self.adaptor_agent.receive_proxied_message(self.proxy_address, pkt)
raise self.end()
+
+ def __del__(self):
+ log.debug("OMCIProxy deleted")
+ super(OMCIProxy, self).__del__()
diff --git a/voltha/adapters/microsemi_olt/OltInstallFlowStateMachine.py b/voltha/adapters/microsemi_olt/OltInstallFlowStateMachine.py
new file mode 100644
index 0000000..c5a945b
--- /dev/null
+++ b/voltha/adapters/microsemi_olt/OltInstallFlowStateMachine.py
@@ -0,0 +1,658 @@
+#
+# Copyright 2017 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.
+#
+
+"""
+Handles sequence of messages that are used to send OMCI to the ONU
+"""
+import structlog
+from scapy.automaton import ATMT
+
+from voltha.adapters.microsemi_olt.BaseOltAutomaton import BaseOltAutomaton
+from voltha.adapters.microsemi_olt.PAS5211 import PAS5211MsgSendFrame, PAS5211MsgGetOltVersionResponse, PAS5211MsgSendFrameResponse, \
+ PAS5211EventFrameReceived, PAS5211MsgHeader, PAS5211SetVlanGenConfigResponse
+
+from voltha.extensions.omci.omci_frame import OmciFrame
+
+from voltha.adapters.microsemi_olt.PAS5211 import PAS5211GetOnuAllocs, PAS5211GetOnuAllocsResponse, PAS5211GetSnInfo, \
+ PAS5211GetSnInfoResponse, PAS5211GetOnusRange, PAS5211GetOnusRangeResponse, PAS5211MsgSetOnuOmciPortId, \
+ PAS5211MsgSetOnuOmciPortIdResponse, PAS5211MsgSetOnuAllocId, PAS5211MsgSetOnuAllocIdResponse, \
+ PAS5211SetSVlanAtConfig, PAS5211SetSVlanAtConfigResponse, PAS5211SetVlanDownConfig, \
+ PAS5211SetVlanDownConfigResponse, PAS5211SetDownVlanHandl, PAS5211SetDownVlanHandlResponse, \
+ PAS5211SetUplinkVlanHandl, PAS5211SetDownstreamPolicingConfigResponse, PAS5211SetDownstreamPolicingConfig, \
+ PAS5211SetPortIdPolicingConfig, PAS5211UnsetPortIdPolicingConfig, \
+ PAS5211MsgSendDbaAlgorithmMsg, PAS5211MsgSendDbaAlgorithmMsgResponse, \
+ PAS5211SetUpstreamPolicingConfigResponse, PAS5211SetUpstreamPolicingConfig, \
+ PAS5211MsgSetPortIdConfig, PAS5211MsgSetPortIdConfigResponse, \
+ PAS5211MsgGetOnuIdByPortId, PAS5211MsgGetOnuIdByPortIdResponse, \
+ PAS5211SetVlanUplinkConfiguration, PAS5211SetVlanUplinkConfigurationResponse, PAS5211SetUplinkVlanHandlResponse, PAS5211SetVlanGenConfig, PAS5211SetVlanGenConfigResponse, \
+ PAS5211GetPortIdDownstreamPolicingConfig, PAS5211GetPortIdDownstreamPolicingConfigResponse, PAS5211RemoveDownstreamPolicingConfig, \
+ PAS5211MsgHeader, PAS5211UnsetPortIdPolicingConfigResponse, PAS5211RemoveDownstreamPolicingConfigResponse, \
+ PAS5211SetPortIdPolicingConfigResponse
+from voltha.adapters.microsemi_olt.PAS5211_constants import OMCI_GEM_IWTP_IW_OPT_8021P_MAPPER, PON_FALSE, \
+ PON_1_TO_1_VLAN_MODE, PON_TRUE, PON_VLAN_UNUSED_TAG, PON_VLAN_UNUSED_PRIORITY, PON_VLAN_REPLACE_PRIORITY, \
+ PON_OUTPUT_VLAN_PRIO_HANDLE_INCOMING_VLAN, PON_VLAN_UNCHANGED_PRIORITY, PON_OUTPUT_VLAN_PRIO_HANDLE_DONT_CHANGE, \
+ PON_OUTPUT_VLAN_PRIO_HANDLE_DL_VLAN_TABLE, PON_DL_VLAN_SVLAN_REMOVE, PON_DL_VLAN_CVLAN_NO_CHANGE, \
+ PON_VLAN_DEST_DATAPATH, GEM_DIR_BIDIRECT, OMCI_MAC_BRIDGE_PCD_LANFCS_FORWARDED, \
+ OMCI_MAC_BRIDGE_PCD_ENCAP_METHOD_LLC, OMCI_8021P_MSP_UNMARKED_FRAME_TAG_FRAME, OMCI_8021P_MSP_TP_TYPE_NULL, \
+ OMCI_EX_VLAN_TAG_OCD_ASSOCIATION_TYPE_PPTP_ETH_UNI, OMCI_EX_VLAN_TAG_OCD_DS_MODE_US_INVERSE, PMC_UPSTREAM_PORT, \
+ PON_DISABLE, PON_VLAN_CHANGE_TAG, PON_VLAN_DONT_CHANGE_TAG, PON_PORT_TYPE_GEM, PON_PORT_DESTINATION_CNI0, PON_ENABLE, SLA_gr_bw_gros, PYTHAGORAS_UPDATE_AID_SLA, \
+ SLA_gr_bw_gros, SLA_be_bw_gros, SLA_gr_bw_fine, SLA_be_bw_fine, PYTHAGORAS_DBA_DATA_COS, PYTHAGORAS_DBA_STATUS_REPORT_NSR, \
+ PMC_OFAL_NO_POLICY, UPSTREAM, DOWNSTREAM
+
+from struct import pack, unpack
+
+log = structlog.get_logger()
+
+
+class OltInstallFlowStateMachine(BaseOltAutomaton):
+
+ onu_id = None
+ channel_id = None
+ port_id = None
+ onu_session_id = None
+ alloc_id = None
+ policy_id = None
+
+ def parse_args(self, debug=0, store=0, **kwargs):
+
+ self.onu_id = kwargs.pop('onu_id')
+ self.channel_id = kwargs.pop('channel_id')
+ self.port_id = kwargs.pop('port_id')
+ self.onu_session_id = kwargs.pop('onu_session_id')
+ self.alloc_id = kwargs.pop('alloc_id')
+ self.svlan_id = kwargs.pop('svlan_id')
+ self.cvlan_id = kwargs.pop('cvlan_id')
+ self.uplink_bandwidth = kwargs.pop('uplink_bandwidth')
+ self.downlink_bandwidth = kwargs.pop('downlink_bandwidth')
+
+
+ BaseOltAutomaton.parse_args(self, debug=debug, store=store, **kwargs)
+
+ def master_filter(self, pkt):
+
+ if not super(OltInstallFlowStateMachine, self).master_filter(pkt):
+ return False
+
+ if PAS5211MsgHeader in pkt:
+ if PAS5211MsgGetOltVersionResponse not in pkt:
+ if pkt[PAS5211MsgHeader].channel_id == self.channel_id:
+ if pkt[PAS5211MsgHeader].onu_id == self.onu_id:
+ if OmciFrame not in pkt:
+ if PAS5211MsgSendFrameResponse not in pkt:
+ return True
+
+ return False
+
+ """
+ States
+ """
+
+ # Uplink states...
+ @ATMT.state(initial=1)
+ def send_msg(self):
+ log.debug('olt-flow-state-machine-start')
+
+ @ATMT.state()
+ def wait_set_gen_vlan_uplink_configuration_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_set_port_id_configuration_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_get_onu_id_by_port_id_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_send_dba_algorithm_msg_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_set_svlan_at_configuration_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_set_vlan_uplink_configuration_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_set_uplink_vlan_handling_response(self):
+ pass
+
+ # Downlink states...
+ @ATMT.state()
+ def wait_set_gen_vlan_downlink_configuration_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_set_vlan_downlink_configuration_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_set_downlink_vlan_handling_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_get_port_id_downlink_policing_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_unset_port_id_downlink_policing_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_remove_downlink_policing_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_set_downlink_policing_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_set_port_id_policing_response(self):
+ pass
+
+
+ @ATMT.state(error=1)
+ def error(self, msg):
+ log.error(msg)
+ raise self.end()
+
+
+ @ATMT.state(final=1)
+ def end(self):
+ log.debug('olt-flow-state-machine-end')
+ # pass
+
+ """
+ Utils
+ """
+
+ def px(self, pkt):
+ return self.p(pkt, channel_id=self.channel_id,
+ onu_id=self.onu_id,
+ onu_session_id=self.onu_session_id)
+
+ """
+ Transitions
+ """
+
+ @ATMT.condition(send_msg)
+ def install_flow(self):
+ log.debug("install-flow")
+ self.send_set_gen_vlan_uplink_configuration(self.device.device)
+ raise self.wait_set_gen_vlan_uplink_configuration_response()
+
+ @ATMT.timeout(wait_set_gen_vlan_uplink_configuration_response, 10)
+ def timeout_wait_gen_vlan_uplink_configuration_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211SetVlanGenConfigResponse")
+
+ @ATMT.receive_condition(wait_set_gen_vlan_uplink_configuration_response)
+ def wait_for_set_gen_vlan_uplink_configuration_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211SetVlanGenConfigResponse in pkt:
+ log.debug('[RESPONSE] PAS5211SetVlanGenConfigResponse')
+ self.send_set_port_id_configuration(self.device.device, PON_ENABLE, self.port_id, self.alloc_id)
+ raise self.wait_set_port_id_configuration_response()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ @ATMT.timeout(wait_set_port_id_configuration_response, 10)
+ def timeout_wait_set_port_id_configuration_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211MsgSetPortIdConfigResponse")
+
+ @ATMT.receive_condition(wait_set_port_id_configuration_response)
+ def wait_for_set_port_id_configuration_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211MsgSetPortIdConfigResponse in pkt:
+ log.debug('[RESPONSE] PAS5211MsgSetPortIdConfigResponse')
+ self.send_get_onu_id_by_port_id(self.device.device, self.port_id)
+ raise self.wait_get_onu_id_by_port_id_response()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ @ATMT.timeout(wait_get_onu_id_by_port_id_response, 10)
+ def timeout_wait_get_onu_id_by_port_id_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211MsgGetOnuIdByPortIdResponse")
+
+ @ATMT.receive_condition(wait_get_onu_id_by_port_id_response)
+ def wait_for_get_onu_id_by_port_id_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211MsgGetOnuIdByPortIdResponse in pkt:
+ log.debug('[RESPONSE] PAS5211MsgGetOnuIdByPortIdResponse')
+ self.send_send_dba_algorithm_msg(self.device.device, self.port_id, self.uplink_bandwidth)
+ raise self.wait_send_dba_algorithm_msg_response()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ @ATMT.timeout(wait_send_dba_algorithm_msg_response, 10)
+ def timeout_wait_send_dba_algorithm_msg_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211MsgSendDbaAlgorithmMsgResponse")
+
+ @ATMT.receive_condition(wait_send_dba_algorithm_msg_response)
+ def wait_for_send_dba_algorithm_msg_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211MsgSendDbaAlgorithmMsgResponse in pkt:
+ log.debug('[RESPONSE] PAS5211MsgSendDbaAlgorithmMsgResponse')
+ self.send_set_svlan_at_configuration(self.device.device, self.svlan_id)
+ raise self.wait_set_svlan_at_configuration_response()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ @ATMT.timeout(wait_set_svlan_at_configuration_response, 10)
+ def timeout_wait_set_svlan_at_configuration_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211SetSVlanAtConfigResponse")
+
+ @ATMT.receive_condition(wait_set_svlan_at_configuration_response)
+ def wait_for_set_svlan_at_configuration_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211SetSVlanAtConfigResponse in pkt:
+ log.debug('[RESPONSE] PAS5211SetSVlanAtConfigResponse')
+ self.send_set_vlan_uplink_configuration(self.device.device, self.port_id)
+ raise self.wait_set_vlan_uplink_configuration_response()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ @ATMT.timeout(wait_set_vlan_uplink_configuration_response, 10)
+ def timeout_wait_set_vlan_uplink_configuration_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211SetVlanUplinkConfigurationResponse")
+
+ @ATMT.receive_condition(wait_set_vlan_uplink_configuration_response)
+ def wait_for_set_vlan_uplink_configuration_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211SetVlanUplinkConfigurationResponse in pkt:
+ log.debug('[RESPONSE] PAS5211SetVlanUplinkConfigurationResponse')
+ self.send_set_uplink_vlan_handling(self.device.device, self.port_id, self.cvlan_id, self.svlan_id)
+ raise self.wait_set_uplink_vlan_handling_response()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+
+ @ATMT.timeout(wait_set_uplink_vlan_handling_response, 10)
+ def timeout_wait_set_uplink_vlan_handling_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211SetUplinkVlanHandlResponse")
+
+ @ATMT.receive_condition(wait_set_uplink_vlan_handling_response)
+ def wait_for_set_uplink_vlan_handling_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211SetUplinkVlanHandlResponse in pkt:
+ log.debug('[RESPONSE] PAS5211SetUplinkVlanHandlResponse')
+ self.send_set_gen_vlan_downlink_configuration(self.device.device)
+ raise self.wait_set_gen_vlan_downlink_configuration_response()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ @ATMT.timeout(wait_set_gen_vlan_downlink_configuration_response, 10)
+ def timeout_wait_set_gen_vlan_downlink_configuration_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211SetVlanGenConfigResponse")
+
+ @ATMT.receive_condition(wait_set_gen_vlan_downlink_configuration_response)
+ def wait_for_set_gen_vlan_downlink_configuration_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211SetVlanGenConfigResponse in pkt:
+ log.debug('[RESPONSE] PAS5211SetVlanGenConfigResponse')
+ self.send_set_vlan_downlink_configuration(self.device.device, self.svlan_id)
+ raise self.wait_set_vlan_downlink_configuration_response()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ @ATMT.timeout(wait_set_vlan_downlink_configuration_response, 10)
+ def timeout_wait_set_vlan_downlink_configuration_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211SetVlanDownConfigResponse")
+
+ @ATMT.receive_condition(wait_set_vlan_downlink_configuration_response)
+ def wait_for_set_vlan_downlink_configuration_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211SetVlanDownConfigResponse in pkt:
+ log.debug('[RESPONSE] PAS5211SetVlanDownConfigResponse')
+ self.send_set_downlink_vlan_handling(self.device.device, self.cvlan_id, self.svlan_id, self.port_id)
+ raise self.wait_set_downlink_vlan_handling_response()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ @ATMT.timeout(wait_set_downlink_vlan_handling_response, 10)
+ def timeout_wait_set_downlink_vlan_handling_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211SetDownVlanHandlResponse")
+
+ @ATMT.receive_condition(wait_set_downlink_vlan_handling_response)
+ def wait_for_set_downlink_vlan_handling_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211SetDownVlanHandlResponse in pkt:
+ log.debug('[RESPONSE] PAS5211SetDownVlanHandlResponse')
+ self.send_get_port_id_downlink_policing(self.device.device, self.port_id)
+ raise self.wait_get_port_id_downlink_policing_response()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ @ATMT.timeout(wait_get_port_id_downlink_policing_response, 10)
+ def timeout_wait_get_port_id_downlink_policing_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211GetPortIdDownstreamPolicingConfigResponse")
+
+ @ATMT.receive_condition(wait_get_port_id_downlink_policing_response)
+ def wait_for_get_port_id_downlink_policing_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211GetPortIdDownstreamPolicingConfigResponse in pkt:
+ log.debug('[RESPONSE] PAS5211GetPortIdDownstreamPolicingConfigResponse')
+ if pkt[PAS5211GetPortIdDownstreamPolicingConfigResponse].ds_policing_config_id != PMC_OFAL_NO_POLICY:
+ self.policy_id = pkt[PAS5211GetPortIdDownstreamPolicingConfigResponse].ds_policing_config_id
+ self.send_unset_port_id_downlink_policing(self.device.device, 1, self.port_id)
+ raise self.wait_unset_port_id_downlink_policing_response()
+ else:
+ self.send_set_downlink_policing(self.device.device,self.downlink_bandwidth)
+ raise self.wait_set_downlink_policing_response()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ @ATMT.timeout(wait_unset_port_id_downlink_policing_response, 10)
+ def timeout_wait_unset_port_id_downlink_policing_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211UnsetPortIdPolicingConfigResponse")
+
+ @ATMT.receive_condition(wait_unset_port_id_downlink_policing_response)
+ def wait_for_unset_port_id_downlink_policing_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211UnsetPortIdPolicingConfigResponse in pkt:
+ log.debug('[RESPONSE] PAS5211UnsetPortIdPolicingConfigResponse')
+ self.send_remove_downlink_policing(self.device.device, self.policy_id)
+ raise self.wait_remove_downlink_policing_response()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ @ATMT.timeout(wait_remove_downlink_policing_response, 10)
+ def timeout_wait_remove_downlink_policing_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211RemoveDownstreamPolicingConfigResponse")
+
+ @ATMT.receive_condition(wait_remove_downlink_policing_response)
+ def wait_for_remove_downlink_policing_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211RemoveDownstreamPolicingConfigResponse in pkt:
+ log.debug('[RESPONSE] PAS5211RemoveDownstreamPolicingConfigResponse')
+ self.send_set_downlink_policing(self.device.device, self.downlink_bandwidth)
+ raise self.wait_set_downlink_policing_response()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ @ATMT.timeout(wait_set_downlink_policing_response, 10)
+ def timeout_wait_set_downlink_policing_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211SetDownstreamPolicingConfigResponse")
+
+ @ATMT.receive_condition(wait_set_downlink_policing_response)
+ def wait_for_set_downlink_policing_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211SetDownstreamPolicingConfigResponse in pkt:
+ log.debug('[RESPONSE] PAS5211SetDownstreamPolicingConfigResponse')
+ if pkt[PAS5211SetDownstreamPolicingConfigResponse].policing_config_id:
+ self.policy_id = pkt[PAS5211SetDownstreamPolicingConfigResponse].policing_config_id
+ self.send_set_port_id_policing(self.device.device, 1, self.port_id, self.policy_id)
+ raise self.wait_set_port_id_policing_response()
+ else:
+ raise self.error("Error setting downling policy")
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ @ATMT.timeout(wait_set_port_id_policing_response, 10)
+ def timeout_wait_set_port_id_policing_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211SetPortIdPolicingConfigResponse")
+
+ @ATMT.receive_condition(wait_set_port_id_policing_response)
+ def wait_for_set_port_id_policing_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211SetPortIdPolicingConfigResponse in pkt:
+ log.debug('[RESPONSE] PAS5211SetPortIdPolicingConfigResponse')
+ raise self.end()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ def send_set_port_id_configuration(self, device, activate, port_id, alloc_id):
+ msg = PAS5211MsgSetPortIdConfig(
+ # port_id=1000 + device.proxy_address.onu_id,
+ port_id=port_id,
+ activate=activate,
+ alloc_id=alloc_id,
+ type=PON_PORT_TYPE_GEM,
+ destination=PON_PORT_DESTINATION_CNI0
+ )
+ self.send(self.px(msg))
+ log.debug("[SENT] PASS_set_port_id_configuration")
+
+ def send_get_onu_id_by_port_id(self, device, port_id):
+ msg = PAS5211MsgGetOnuIdByPortId(
+ # port_id=1000 + device.proxy_address.onu_id
+ port_id=port_id
+
+ )
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211MsgGetOnuIdByPortId")
+
+ def send_set_gen_vlan_uplink_configuration(self, device):
+ # transmit "vlan uplink configuration port-id 1001 min-cos 0 max-cos 7
+ # de-bit disable primary-tag-handling true"
+
+ msg = PAS5211SetVlanGenConfig(
+ direction=0,
+ extended_svlan_type=33024,
+ insertion_svlan_ethertype=33024,
+ extended_cvlan_type=33024,
+ insertion_cvlan_ethertype=33024,
+ pon_pcp_code=3,
+ cni_pcp_code=3,
+ reserved=0,
+ )
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211SetVlanGenConfig")
+
+ def send_set_gen_vlan_downlink_configuration(self, device):
+ # transmit "vlan uplink configuration port-id 1001 min-cos 0 max-cos 7
+ # de-bit disable primary-tag-handling true"
+
+ msg = PAS5211SetVlanGenConfig(
+ direction=1,
+ extended_svlan_type=33024,
+ insertion_svlan_ethertype=33024,
+ extended_cvlan_type=33024,
+ insertion_cvlan_ethertype=33024,
+ pon_pcp_code=3,
+ cni_pcp_code=3,
+ reserved=0,
+ )
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211SetVlanGenConfig")
+
+ def send_set_vlan_uplink_configuration(self, device, port_id):
+ # transmit "vlan uplink configuration port-id 1001 min-cos 0 max-cos 7
+ # de-bit disable primary-tag-handling true"
+
+ msg = PAS5211SetVlanUplinkConfiguration(
+ # port_id=(1000 + device.proxy_address.onu_id),
+ port_id = port_id,
+ pvid_config_enabled=PON_TRUE,
+ # Enables handling of primary tag in addition to the port-id at
+ # uplink frames
+ min_cos=0, # The lower limit of the priority uplink frame from the specific Port Id can get
+ max_cos=7, # The upper limit of the priority uplink frame from the specific Port Id can get
+ de_bit=PON_DISABLE # Discard Eligibility (DE) enabled
+ )
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211SetVlanUplinkConfiguration")
+
+ def send_set_uplink_vlan_handling(self, device, port_id, cvlan_id, svlan_id):
+
+ # if (ul_vlan_key->primary_vid == PON_VLAN_UNUSED_TAG)
+ # set_uplink_vlan_handling_msg.pvid_config_enabled = PON_FALSE;
+ # else
+ # {
+ # set_uplink_vlan_handling_msg.pvid_config_enabled = PON_TRUE;
+ # set_uplink_vlan_handling_msg.primary_vid = ul_vlan_key->primary_vid;
+ # }
+ primary_vid = 0 # TODO change
+ # self.port_id = (1000 + device.proxy_address.onu_id) # TODO change
+ if cvlan_id == PON_VLAN_UNUSED_TAG:
+ pvid_config_enabled = PON_FALSE
+ else:
+ pvid_config_enabled = PON_TRUE
+ primary_vid = cvlan_id
+
+ msg = PAS5211SetUplinkVlanHandl(
+ source_port_id=port_id,
+ primary_vid=primary_vid, # The primary VLAN tag of the uplink frame
+ pvid_config_enabled=pvid_config_enabled,
+ svlan_tag_operation=PON_VLAN_CHANGE_TAG,
+ cvlan_tag_operation=PON_VLAN_DONT_CHANGE_TAG, # Customer tag = new C-VLAN tag
+ new_svlan_tag=svlan_id, # Service tag to be added or replace, not relevant
+ new_cvlan_tag=0, # Customer tag to be added or replace, not relevant
+ destination=PON_VLAN_DEST_DATAPATH # Frames go to the CNI
+ )
+
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211SetUplinkVlanHandl")
+
+ def send_set_svlan_at_configuration(self, device, svlan_id):
+
+ msg = PAS5211SetSVlanAtConfig(
+ svlan_id=svlan_id, # 9
+ # 1 1:1 VLAN mode is used, no address table
+ forwarding_mode=PON_1_TO_1_VLAN_MODE,
+ use_svlan=PON_FALSE, # Use S-VLAN as part of the address table key
+ use_cvlan=PON_FALSE, # Use C-VLAN as part of the address table key
+ use_pbits=PON_FALSE, # Use priority bits as part of the address table key
+ discard_unknown=PON_FALSE # Forward frames
+ )
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211SetSVlanAtConfig")
+
+ def send_set_vlan_downlink_configuration(self, device, svlan_id):
+ msg = PAS5211SetVlanDownConfig(
+ svlan_id=svlan_id, # 9
+ double_tag_handling=PON_TRUE, # Enable handling according to double tag
+ vlan_priority_handling=PON_TRUE # Use VLAN priority at the downlink VLAN table key
+ )
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211SetVlanDownConfig")
+
+ def send_get_port_id_downlink_policing(self, device, port_id):
+ msg = PAS5211GetPortIdDownstreamPolicingConfig(port_id=port_id)
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211GetPortIdDownstreamPolicingConfig")
+
+ def send_remove_downlink_policing(self, device, policy_id):
+ msg = PAS5211RemoveDownstreamPolicingConfig(
+ policing_config_id=policy_id,
+ reserved=0)
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211RemoveDownstreamPolicingConfig")
+
+ def send_unset_port_id_downlink_policing(self, device, dir, port_id):
+ msg = PAS5211UnsetPortIdPolicingConfig(direction=dir, port_id=port_id)
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211UnsetPortIdPolicingConfig")
+
+ def send_set_downlink_policing(self, device, bandwidth):
+ msg = PAS5211SetDownstreamPolicingConfig(
+ committed_bandwidth = SLA_gr_bw_gros*1024,
+ excessive_bandwidth = (bandwidth - SLA_gr_bw_gros)*1024,
+ committed_burst_limit = 256,
+ excessive_burst_limit = 256)
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211SetDownstreamPolicingConfig")
+
+ def send_set_port_id_policing(self, device, dir, port_id, policy_id):
+ msg = PAS5211SetPortIdPolicingConfig(
+ direction=dir,
+ port_id=port_id,
+ policing_config_id=policy_id,
+ reserved=0)
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211SetPortIdPolicingConfig")
+
+ def send_send_dba_algorithm_msg(self, device, port_id, bandwidth):
+ alloc_id = []
+ mx_bw = []
+ gr_bw = []
+
+ data = pack('<LLHHBBBB', PYTHAGORAS_UPDATE_AID_SLA,
+ port_id, SLA_gr_bw_gros, bandwidth,
+ SLA_gr_bw_fine, SLA_be_bw_fine, PYTHAGORAS_DBA_DATA_COS,
+ PYTHAGORAS_DBA_STATUS_REPORT_NSR)
+
+ msg = PAS5211MsgSendDbaAlgorithmMsg(data= data)
+
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211MsgSendDbaAlgorithmMsg")
+
+ def send_set_downlink_vlan_handling(self, device, cvlan_id, svlan_id, port_id):
+ cvlan_tag = 0
+ svlan_tag = svlan_id
+ if cvlan_id == PON_VLAN_UNUSED_TAG:
+ double_tag_handling = PON_FALSE
+ else:
+ double_tag_handling = PON_TRUE
+ cvlan_tag = cvlan_id
+
+ input_priority = 0 # TODO: Extract value from somewhere
+
+ if input_priority == PON_VLAN_UNUSED_PRIORITY:
+ priority_handling = PON_FALSE
+ else:
+ priority_handling = PON_TRUE
+
+ output_priority = 0 # TODO: Extract value from somewhere
+
+ if output_priority == PON_VLAN_REPLACE_PRIORITY:
+ output_vlan_prio_handle = PON_OUTPUT_VLAN_PRIO_HANDLE_INCOMING_VLAN
+ output_priority = 0
+ elif output_priority == PON_VLAN_UNCHANGED_PRIORITY:
+ output_vlan_prio_handle = PON_OUTPUT_VLAN_PRIO_HANDLE_DONT_CHANGE
+ output_priority = 0
+ else:
+ output_vlan_prio_handle = PON_OUTPUT_VLAN_PRIO_HANDLE_DL_VLAN_TABLE
+
+ msg = PAS5211SetDownVlanHandl(
+ svlan_tag=svlan_tag,
+ cvlan_tag=cvlan_tag, # Original downlink frame with this C-tag ID
+ double_tag_handling=PON_TRUE,
+ priority_handling=PON_FALSE,
+ input_priority=1, # From traces # S-VLAN priority field
+ # Don't change original frame service tag
+ svlan_tag_operation=PON_DL_VLAN_SVLAN_REMOVE,
+ cvlan_tag_operation=PON_DL_VLAN_CVLAN_NO_CHANGE, # Customer tag = new C-VLAN tag
+ # port_id=(1000 + device.proxy_address.onu_id),
+ port_id=port_id,
+ # GEM port-id destination of the downlink frame. It is used when
+ # the MAC destination address (DA) is a broadcast address
+ new_cvlan_tag=cvlan_tag, # Same as cvlan_tag
+ # From traces PON_VLAN_DEST_DATAPATH, # Frames go to the PON
+ destination=PON_VLAN_DEST_DATAPATH,
+ output_vlan_prio_handle=PON_OUTPUT_VLAN_PRIO_HANDLE_DONT_CHANGE,
+ output_priority=1 # New VLAN priority value
+ )
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211SetDownVlanHandl")
+
\ No newline at end of file
diff --git a/voltha/adapters/microsemi_olt/OltReinstallFlowStateMachine.py b/voltha/adapters/microsemi_olt/OltReinstallFlowStateMachine.py
new file mode 100644
index 0000000..dfc5601
--- /dev/null
+++ b/voltha/adapters/microsemi_olt/OltReinstallFlowStateMachine.py
@@ -0,0 +1,78 @@
+#
+# Copyright 2017 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.
+#
+
+"""
+Handles sequence of messages that are used to send OMCI to the ONU
+"""
+import structlog
+from scapy.automaton import ATMT
+
+from voltha.adapters.microsemi_olt.BaseOltAutomaton import BaseOltAutomaton
+from voltha.adapters.microsemi_olt.PAS5211 import PAS5211MsgSendFrame, PAS5211MsgGetOltVersionResponse, PAS5211MsgSendFrameResponse, \
+ PAS5211EventFrameReceived, PAS5211MsgHeader, PAS5211SetVlanGenConfigResponse
+
+from voltha.extensions.omci.omci_frame import OmciFrame
+
+from voltha.adapters.microsemi_olt.OltInstallFlowStateMachine import OltInstallFlowStateMachine
+from voltha.adapters.microsemi_olt.OltRemoveFlowStateMachine import OltRemoveFlowStateMachine
+
+from voltha.adapters.microsemi_olt.PAS5211 import PAS5211GetOnuAllocs, PAS5211GetOnuAllocsResponse, PAS5211GetSnInfo, \
+ PAS5211GetSnInfoResponse, PAS5211GetOnusRange, PAS5211GetOnusRangeResponse, PAS5211MsgSetOnuOmciPortId, \
+ PAS5211MsgSetOnuOmciPortIdResponse, PAS5211MsgSetOnuAllocId, PAS5211MsgSetOnuAllocIdResponse, \
+ PAS5211SetSVlanAtConfig, PAS5211SetSVlanAtConfigResponse, PAS5211SetVlanDownConfig, \
+ PAS5211SetVlanDownConfigResponse, PAS5211SetDownVlanHandl, PAS5211SetDownVlanHandlResponse, \
+ PAS5211SetUplinkVlanHandl, PAS5211SetDownstreamPolicingConfigResponse, PAS5211SetDownstreamPolicingConfig, \
+ PAS5211SetPortIdPolicingConfig, PAS5211UnsetPortIdPolicingConfig, \
+ PAS5211MsgSendDbaAlgorithmMsg, PAS5211MsgSendDbaAlgorithmMsgResponse, \
+ PAS5211SetUpstreamPolicingConfigResponse, PAS5211SetUpstreamPolicingConfig, \
+ PAS5211MsgSetPortIdConfig, PAS5211MsgSetPortIdConfigResponse, \
+ PAS5211MsgGetOnuIdByPortId, PAS5211MsgGetOnuIdByPortIdResponse, \
+ PAS5211SetVlanUplinkConfiguration, PAS5211SetVlanUplinkConfigurationResponse, PAS5211SetUplinkVlanHandlResponse, PAS5211SetVlanGenConfig, PAS5211SetVlanGenConfigResponse, \
+ PAS5211GetPortIdDownstreamPolicingConfig, PAS5211GetPortIdDownstreamPolicingConfigResponse, PAS5211RemoveDownstreamPolicingConfig, \
+ PAS5211MsgHeader, PAS5211UnsetPortIdPolicingConfigResponse, PAS5211RemoveDownstreamPolicingConfigResponse, \
+ PAS5211SetPortIdPolicingConfigResponse
+from voltha.adapters.microsemi_olt.PAS5211_constants import OMCI_GEM_IWTP_IW_OPT_8021P_MAPPER, PON_FALSE, \
+ PON_1_TO_1_VLAN_MODE, PON_TRUE, PON_VLAN_UNUSED_TAG, PON_VLAN_UNUSED_PRIORITY, PON_VLAN_REPLACE_PRIORITY, \
+ PON_OUTPUT_VLAN_PRIO_HANDLE_INCOMING_VLAN, PON_VLAN_UNCHANGED_PRIORITY, PON_OUTPUT_VLAN_PRIO_HANDLE_DONT_CHANGE, \
+ PON_OUTPUT_VLAN_PRIO_HANDLE_DL_VLAN_TABLE, PON_DL_VLAN_SVLAN_REMOVE, PON_DL_VLAN_CVLAN_NO_CHANGE, \
+ PON_VLAN_DEST_DATAPATH, GEM_DIR_BIDIRECT, OMCI_MAC_BRIDGE_PCD_LANFCS_FORWARDED, \
+ OMCI_MAC_BRIDGE_PCD_ENCAP_METHOD_LLC, OMCI_8021P_MSP_UNMARKED_FRAME_TAG_FRAME, OMCI_8021P_MSP_TP_TYPE_NULL, \
+ OMCI_EX_VLAN_TAG_OCD_ASSOCIATION_TYPE_PPTP_ETH_UNI, OMCI_EX_VLAN_TAG_OCD_DS_MODE_US_INVERSE, PMC_UPSTREAM_PORT, \
+ PON_DISABLE, PON_VLAN_CHANGE_TAG, PON_VLAN_DONT_CHANGE_TAG, PON_PORT_TYPE_GEM, PON_PORT_DESTINATION_CNI0, PON_ENABLE, SLA_gr_bw_gros, PYTHAGORAS_UPDATE_AID_SLA, \
+ SLA_gr_bw_gros, SLA_be_bw_gros, SLA_gr_bw_fine, SLA_be_bw_fine, PYTHAGORAS_DBA_DATA_COS, PYTHAGORAS_DBA_STATUS_REPORT_NSR, \
+ PMC_OFAL_NO_POLICY, UPSTREAM, DOWNSTREAM
+
+log = structlog.get_logger()
+
+
+class OltReinstallFlowStateMachine(OltInstallFlowStateMachine):
+
+ @ATMT.state()
+ def wait_set_port_id_configuration_response(self):
+ pass
+
+ @ATMT.receive_condition(wait_set_port_id_configuration_response)
+ def wait_for_set_port_id_configuration_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211MsgSetPortIdConfigResponse in pkt:
+ log.debug('[RESPONSE] PAS5211MsgSetPortIdConfigResponse')
+ olt = OltInstallFlowStateMachine(iface=self.iface, comm=self.comm,
+ target=self.target, device=self.device, onu_id=self.onu_id,
+ channel_id=self.channel_id, port_id=self.port_id, onu_session_id=self.onu_session_id,
+ alloc_id=self.alloc_id, svlan_id= self.svlan_id, cvlan_id=self.cvlan_id)
+ olt.runbg()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
diff --git a/voltha/adapters/microsemi_olt/OltRemoveFlowStateMachine.py b/voltha/adapters/microsemi_olt/OltRemoveFlowStateMachine.py
new file mode 100644
index 0000000..44bbe96
--- /dev/null
+++ b/voltha/adapters/microsemi_olt/OltRemoveFlowStateMachine.py
@@ -0,0 +1,222 @@
+#
+# Copyright 2017 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.
+#
+
+"""
+Handles sequence of messages that are used to send OMCI to the ONU
+"""
+import structlog
+from scapy.automaton import ATMT
+
+from voltha.adapters.microsemi_olt.BaseOltAutomaton import BaseOltAutomaton
+from voltha.adapters.microsemi_olt.PAS5211 import PAS5211MsgSendFrame, PAS5211MsgGetOltVersionResponse, PAS5211MsgSendFrameResponse, \
+ PAS5211EventFrameReceived, PAS5211MsgHeader, PAS5211SetVlanGenConfigResponse
+
+from voltha.extensions.omci.omci_frame import OmciFrame
+
+from voltha.adapters.microsemi_olt.PAS5211 import PAS5211GetOnuAllocs, PAS5211GetOnuAllocsResponse, PAS5211GetSnInfo, \
+ PAS5211GetSnInfoResponse, PAS5211GetOnusRange, PAS5211GetOnusRangeResponse, PAS5211MsgSetOnuOmciPortId, \
+ PAS5211MsgSetOnuOmciPortIdResponse, PAS5211MsgSetOnuAllocId, PAS5211MsgSetOnuAllocIdResponse, \
+ PAS5211SetSVlanAtConfig, PAS5211SetSVlanAtConfigResponse, PAS5211SetVlanDownConfig, \
+ PAS5211SetVlanDownConfigResponse, PAS5211SetDownVlanHandl, PAS5211SetDownVlanHandlResponse, \
+ PAS5211SetUplinkVlanHandl, PAS5211SetDownstreamPolicingConfigResponse, PAS5211SetDownstreamPolicingConfig, \
+ PAS5211SetPortIdPolicingConfig, PAS5211UnsetPortIdPolicingConfig, \
+ PAS5211MsgSendDbaAlgorithmMsg, PAS5211MsgSendDbaAlgorithmMsgResponse, \
+ PAS5211SetUpstreamPolicingConfigResponse, PAS5211SetUpstreamPolicingConfig, \
+ PAS5211MsgSetPortIdConfig, PAS5211MsgSetPortIdConfigResponse, \
+ PAS5211MsgGetOnuIdByPortId, PAS5211MsgGetOnuIdByPortIdResponse, \
+ PAS5211SetVlanUplinkConfiguration, PAS5211SetVlanUplinkConfigurationResponse, PAS5211SetUplinkVlanHandlResponse, PAS5211SetVlanGenConfig, PAS5211SetVlanGenConfigResponse, \
+ PAS5211GetPortIdDownstreamPolicingConfig, PAS5211GetPortIdDownstreamPolicingConfigResponse, PAS5211RemoveDownstreamPolicingConfig, \
+ PAS5211MsgHeader, PAS5211UnsetPortIdPolicingConfigResponse, PAS5211RemoveDownstreamPolicingConfigResponse, \
+ PAS5211SetPortIdPolicingConfigResponse
+from voltha.adapters.microsemi_olt.PAS5211_constants import OMCI_GEM_IWTP_IW_OPT_8021P_MAPPER, PON_FALSE, \
+ PON_1_TO_1_VLAN_MODE, PON_TRUE, PON_VLAN_UNUSED_TAG, PON_VLAN_UNUSED_PRIORITY, PON_VLAN_REPLACE_PRIORITY, \
+ PON_OUTPUT_VLAN_PRIO_HANDLE_INCOMING_VLAN, PON_VLAN_UNCHANGED_PRIORITY, PON_OUTPUT_VLAN_PRIO_HANDLE_DONT_CHANGE, \
+ PON_OUTPUT_VLAN_PRIO_HANDLE_DL_VLAN_TABLE, PON_DL_VLAN_SVLAN_REMOVE, PON_DL_VLAN_CVLAN_NO_CHANGE, \
+ PON_VLAN_DEST_DATAPATH, GEM_DIR_BIDIRECT, OMCI_MAC_BRIDGE_PCD_LANFCS_FORWARDED, \
+ OMCI_MAC_BRIDGE_PCD_ENCAP_METHOD_LLC, OMCI_8021P_MSP_UNMARKED_FRAME_TAG_FRAME, OMCI_8021P_MSP_TP_TYPE_NULL, \
+ OMCI_EX_VLAN_TAG_OCD_ASSOCIATION_TYPE_PPTP_ETH_UNI, OMCI_EX_VLAN_TAG_OCD_DS_MODE_US_INVERSE, PMC_UPSTREAM_PORT, \
+ PON_DISABLE, PON_VLAN_CHANGE_TAG, PON_VLAN_DONT_CHANGE_TAG, PON_PORT_TYPE_GEM, PON_PORT_DESTINATION_CNI0, PON_ENABLE, SLA_gr_bw_gros, PYTHAGORAS_UPDATE_AID_SLA, \
+ SLA_gr_bw_gros, SLA_be_bw_gros, SLA_gr_bw_fine, SLA_be_bw_fine, PYTHAGORAS_DBA_DATA_COS, PYTHAGORAS_DBA_STATUS_REPORT_NSR, \
+ PMC_OFAL_NO_POLICY, UPSTREAM, DOWNSTREAM
+
+log = structlog.get_logger()
+
+
+class OltRemoveFlowStateMachine(BaseOltAutomaton):
+
+ onu_id = None
+ channel_id = None
+ port_id = None
+ onu_session_id = None
+ alloc_id = None
+ policy_id = None
+
+ def parse_args(self, debug=0, store=0, **kwargs):
+
+ self.onu_id = kwargs.pop('onu_id')
+ self.channel_id = kwargs.pop('channel_id')
+ self.port_id = kwargs.pop('port_id')
+ self.onu_session_id = kwargs.pop('onu_session_id')
+ self.alloc_id = kwargs.pop('alloc_id')
+
+ BaseOltAutomaton.parse_args(self, debug=debug, store=store, **kwargs)
+
+
+ def master_filter(self, pkt):
+
+ if not super(OltRemoveFlowStateMachine, self).master_filter(pkt):
+ return False
+
+ if PAS5211MsgHeader in pkt:
+ if PAS5211MsgGetOltVersionResponse not in pkt:
+ if pkt[PAS5211MsgHeader].channel_id == self.channel_id:
+ if pkt[PAS5211MsgHeader].onu_id == self.onu_id:
+ if OmciFrame not in pkt:
+ if PAS5211MsgSendFrameResponse not in pkt:
+ return True
+
+ return False
+
+ """
+ States
+ """
+
+ # Uplink states...
+ @ATMT.state(initial=1)
+ def send_msg(self):
+ log.debug('olt-flow-state-machine-start')
+
+ @ATMT.state()
+ def wait_set_port_id_configuration_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_get_onu_id_by_port_id_response(self):
+ pass
+
+ @ATMT.state()
+ def wait_unset_port_id_downlink_policing_response(self):
+ pass
+
+
+ @ATMT.state(error=1)
+ def error(self, msg):
+ log.error(msg)
+ raise self.end()
+
+
+ @ATMT.state(final=1)
+ def end(self):
+ log.debug('olt-flow-state-machine-end')
+ # pass
+
+ """
+ Utils
+ """
+
+ def px(self, pkt):
+ return self.p(pkt, channel_id=self.channel_id,
+ onu_id=self.onu_id,
+ onu_session_id=self.onu_session_id)
+
+ """
+ Transitions
+ """
+
+ @ATMT.condition(send_msg)
+ def remove_flow(self):
+ self.send_get_onu_id_by_port_id(self.device.device, self.port_id)
+ raise self.wait_get_onu_id_by_port_id_response()
+
+
+ @ATMT.timeout(wait_get_onu_id_by_port_id_response, 10)
+ def timeout_wait_get_onu_id_by_port_id_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211MsgGetOnuIdByPortIdResponse")
+
+ @ATMT.receive_condition(wait_get_onu_id_by_port_id_response)
+ def wait_for_get_onu_id_by_port_id_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211MsgGetOnuIdByPortIdResponse in pkt:
+ log.debug('[RESPONSE] PAS5211MsgGetOnuIdByPortIdResponse')
+ self.send_unset_port_id_downlink_policing(self.device.device, 1, self.port_id)
+ raise self.wait_unset_port_id_downlink_policing_response()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ @ATMT.timeout(wait_unset_port_id_downlink_policing_response, 10)
+ def timeout_wait_unset_port_id_downlink_policing_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211UnsetPortIdPolicingConfigResponse")
+
+ @ATMT.receive_condition(wait_unset_port_id_downlink_policing_response)
+ def wait_for_unset_port_id_downlink_policing_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211UnsetPortIdPolicingConfigResponse in pkt:
+ log.debug('[RESPONSE] PAS5211UnsetPortIdPolicingConfigResponse')
+ self.send_set_port_id_configuration(self.device.device, PON_DISABLE, self.port_id, self.alloc_id)
+ raise self.wait_set_port_id_configuration_response()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+ @ATMT.timeout(wait_set_port_id_configuration_response, 10)
+ def timeout_wait_set_port_id_configuration_response(self):
+ #log.debug('api-proxy-timeout')
+ raise self.error("Timeout for message PAS5211MsgSetPortIdConfigResponse")
+
+ @ATMT.receive_condition(wait_set_port_id_configuration_response)
+ def wait_for_set_port_id_configuration_response(self, pkt):
+ #log.debug('api-proxy-response')
+ if PAS5211MsgSetPortIdConfigResponse in pkt:
+ log.debug('[RESPONSE] PAS5211MsgSetPortIdConfigResponse')
+ self.end()
+ else:
+ log.debug('Unexpected pkt {}'.format(pkt.summary()))
+
+
+
+ """ - - - - - - - create_double_vlan_flow_olt_config - - - - - - - """
+
+
+ def send_set_port_id_configuration(self, device, activate, port_id, alloc_id):
+ msg = PAS5211MsgSetPortIdConfig(
+ # port_id=1000 + device.proxy_address.onu_id,
+ port_id=port_id,
+ activate=activate,
+ alloc_id=alloc_id,
+ type=PON_PORT_TYPE_GEM,
+ destination=PON_PORT_DESTINATION_CNI0
+ )
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211MsgSetPortIdConfig")
+
+ def send_get_onu_id_by_port_id(self, device, port_id):
+ msg = PAS5211MsgGetOnuIdByPortId(
+ # port_id=1000 + device.proxy_address.onu_id
+ port_id=port_id
+
+ )
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211MsgGetOnuIdByPortId")
+
+
+ def send_unset_port_id_downlink_policing(self, device, dir, port_id):
+ msg = PAS5211UnsetPortIdPolicingConfig(direction=dir, port_id=port_id)
+ self.send(self.px(msg))
+ log.debug("[SENT] PAS5211UnsetPortIdPolicingConfig")
+
+
+ """ - - - - - - - END create_double_vlan_flow_olt_config - - - - - - - """
diff --git a/voltha/adapters/microsemi_olt/OltStateMachine.py b/voltha/adapters/microsemi_olt/OltStateMachine.py
index 4a43332..57a2d57 100644
--- a/voltha/adapters/microsemi_olt/OltStateMachine.py
+++ b/voltha/adapters/microsemi_olt/OltStateMachine.py
@@ -19,17 +19,19 @@
from voltha.adapters.microsemi_olt.PAS5211 import PAS5211MsgGetProtocolVersion, PAS5211MsgGetOltVersion, \
PAS5211MsgGetOltVersionResponse, PAS5211MsgGetProtocolVersionResponse, \
SnrBurstDelay, RngBurstDelay, GeneralOpticsParams, ResetValues, ResetTimingCtrl, PreambleParams, \
- PAS5211MsgSetOltOpticsResponse, CHANNELS, PAS5211MsgSetOpticsIoControlResponse, PAS5211MsgGetGeneralParamResponse, PAS5211MsgAddOltChannel, \
+ PAS5211MsgSetOltOpticsResponse, CHANNELS, PAS5211MsgSetOpticsIoControlResponse, PAS5211MsgGetGeneralParamResponse, \
+ PAS5211MsgAddOltChannel, \
PAS5211MsgAddOltChannelResponse, PAS5211MsgSetAlarmConfigResponse, PAS5211MsgGetDbaMode, \
PAS5211MsgGetDbaModeResponse, PAS5211MsgStartDbaAlgorithm, \
- PAS5211MsgStartDbaAlgorithmResponse, PAS5211MsgSetOltChannelActivationPeriod, \
- PAS5211MsgSetOltChannelActivationPeriodResponse
-from voltha.adapters.microsemi_olt.PAS5211_constants import PON_OPTICS_VOLTAGE_IF_LVPECL, PON_ENABLE, PON_POLARITY_ACTIVE_HIGH, \
+ PAS5211MsgStartDbaAlgorithmResponse, PAS5211MsgSetOltChannelActivationPeriod, \
+ PAS5211MsgSetOltChannelActivationPeriodResponse, PAS5211MsgHeader, PAS5211Event, PAS5211EventAlarmNotification
+from voltha.adapters.microsemi_olt.PAS5211_constants import PON_OPTICS_VOLTAGE_IF_LVPECL, PON_ENABLE, \
+ PON_POLARITY_ACTIVE_HIGH, PASCOMM_RETRIES, \
PON_SD_SOURCE_LASER_SD, PON_RESET_TYPE_DELAY_BASED, PON_DISABLE, PON_RESET_TYPE_NORMAL_START_BURST_BASED, \
- PON_TX_ENABLE_DEFAULT, PON_ALARM_LOS, PON_DBA_MODE_LOADED_NOT_RUNNING, PON_DBA_MODE_RUNNING
+ PON_TX_ENABLE_DEFAULT, PON_ALARM_LOS, PON_DBA_MODE_LOADED_NOT_RUNNING, PON_DBA_MODE_RUNNING
from voltha.adapters.microsemi_olt.PAS5211_utils import general_param, olt_optics_pkt, burst_timing, io_ctrl_optics, \
alarm_config
-
+from voltha.extensions.omci.omci_frame import OmciFrame
import structlog
from voltha.protos.common_pb2 import ConnectStatus
@@ -38,17 +40,34 @@
class OltStateMachine(BaseOltAutomaton):
-
send_state = []
dba_needs_start = False
+ retry = 10
def check_channel_state(self):
for i in CHANNELS:
- if not self.send_state[i]:
- return False
+ if not self.send_state[i]:
+ return False
self.send_state = []
return True
+ def master_filter(self, pkt):
+
+ if not super(OltStateMachine, self).master_filter(pkt):
+ return False
+
+ if OmciFrame in pkt:
+ log.debug("OMCI-message-type: {}".format(pkt[OmciFrame].message_type))
+ return False
+
+ if PAS5211Event in pkt:
+ return False
+
+ if PAS5211EventAlarmNotification in pkt:
+ return False
+
+ return True
+
"""
States
"""
@@ -133,17 +152,18 @@
def wait_activation(self):
pass
- @ATMT.state()
- def initialized(self):
- pass
-
- @ATMT.state()
- def wait_keepalive(self):
- pass
+ @ATMT.state(final=1)
+ def end(self):
+ log.debug('OLT state machine ended')
+ #
+ # @ATMT.state()
+ # def wait_keepalive(self):
+ # pass
@ATMT.state(error=1)
- def ERROR(self):
- pass
+ def error(self):
+ raise self.end()
+ # pass
"""
Transitions
@@ -156,13 +176,13 @@
raise self.wait_for_proto_version()
# Transitions from wait_for_proto_version
- @ATMT.timeout(wait_for_proto_version, 1)
+ @ATMT.timeout(wait_for_proto_version, 3)
def timeout_proto(self):
- log.info("Timed out waiting for proto version")
+ log.debug("Timed out waiting for proto version")
self.retry -= 1
if self.retry < 0:
- log.debug("Too many retries, aborting.")
- raise self.ERROR()
+ log.error("Too many retries, aborting.")
+ raise self.error()
raise self.disconnected()
@ATMT.receive_condition(wait_for_proto_version)
@@ -171,35 +191,41 @@
if PAS5211MsgGetProtocolVersionResponse in pkt:
raise self.got_proto_version()
else:
- log.error("Got garbage packet {}".format(pkt))
- raise self.ERROR()
+ log.error("Got garbage packet: {}".format(pkt.summary()))
+ self.retry -= 1
+ if self.retry < 0:
+ log.error("Too many retries, aborting.")
+ raise self.error()
+ else:
+ raise self.wait_for_proto_version()
# Transitions from got_proto_version
@ATMT.condition(got_proto_version)
def send_olt_version(self):
self.send(self.p(PAS5211MsgGetOltVersion()))
+ log.debug("[SENT] PAS5211MsgGetOltVersion")
raise self.wait_for_olt_version()
# Transitions from waiting for olt version
- @ATMT.timeout(wait_for_olt_version, 1)
+ @ATMT.timeout(wait_for_olt_version, 3)
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()
+ log.error("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")
if PAS5211MsgGetOltVersionResponse in pkt:
- log.info("updating device")
+ log.debug("[RESPONSE] PAS5211MsgGetOltVersion")
self.device.update_device_info_from_pkt(pkt)
raise self.got_olt_version()
else:
log.error("Got garbage packet {}".format(pkt))
- raise self.ERROR()
+ raise self.error()
# Transitions from got_olt_version
@ATMT.condition(got_olt_version)
@@ -212,7 +238,8 @@
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,
+ 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)
@@ -221,21 +248,21 @@
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),
+ 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),
+ 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),
+ 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))
+ 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,
@@ -245,15 +272,16 @@
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)
+ 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))
+ log.debug("[SENT] PAS5211MsgSetOltOptics")
raise self.wait_olt_optics()
@@ -261,11 +289,12 @@
@ATMT.timeout(wait_olt_optics, 3)
def olt_optics_timeout(self):
log.error("Setting olt optics failed; disconnecting")
- raise self.ERROR()
+ raise self.error()
@ATMT.receive_condition(wait_olt_optics)
def receive_set_optics_response(self, pkt):
if PAS5211MsgSetOltOpticsResponse in pkt:
+ log.debug("[RESPONSE] PAS5211MsgSetOltOptics")
self.send_state[pkt.channel_id] = True
if self.check_channel_state():
raise self.got_olt_optics()
@@ -278,18 +307,22 @@
pkt = io_ctrl_optics(1, 0, 6, 14)
self.send_state.append(False)
self.send(self.p(pkt, channel_id=0))
+ log.debug("[SENT] PAS5211MsgSetOpticsIoControl")
pkt = io_ctrl_optics(3, 2, 7, 15)
self.send_state.append(False)
self.send(self.p(pkt, channel_id=1))
+ log.debug("[SENT] PAS5211MsgSetOpticsIoControl")
pkt = io_ctrl_optics(11, 10, 8, 16)
self.send_state.append(False)
self.send(self.p(pkt, channel_id=2))
+ log.debug("[SENT] PAS5211MsgSetOpticsIoControl")
pkt = io_ctrl_optics(13, 12, 9, 17)
self.send_state.append(False)
self.send(self.p(pkt, channel_id=3))
+ log.debug("[SENT] PAS5211MsgSetOpticsIoControl")
raise self.wait_olt_io_optics()
@@ -297,11 +330,12 @@
@ATMT.timeout(wait_olt_io_optics, 3)
def olt_io_optics_timeout(self):
log.error("Setting olt io optics failed; disconnecting")
- raise self.ERROR()
+ raise self.error()
@ATMT.receive_condition(wait_olt_io_optics)
def receive_io_optics_response(self, pkt):
if PAS5211MsgSetOpticsIoControlResponse in pkt:
+ log.debug("[RESPONSE] PAS5211MsgSetOpticsIoControl")
self.send_state[pkt.channel_id] = True
if self.check_channel_state():
raise self.got_olt_io_optics()
@@ -314,6 +348,7 @@
for id in CHANNELS:
self.send_state.append(False)
self.send(self.p(query, channel_id=id))
+ log.debug("[SENT] PAS5211MsgGetGeneralParam")
raise self.wait_query_response()
@@ -321,11 +356,12 @@
@ATMT.timeout(wait_query_response, 3)
def query_timeout(self):
log.error("Our queries have gone unanswered; disconnecting")
- raise self.ERROR()
+ raise self.error()
@ATMT.receive_condition(wait_query_response)
def check_pon_tx_state(self, pkt):
if PAS5211MsgGetGeneralParamResponse in pkt:
+ log.debug("[RESPONSE] PAS5211MsgGetGeneralParam")
self.send_state[pkt.channel_id] = True
if pkt.value == PON_ENABLE:
# TODO: we may want to do something here.
@@ -335,7 +371,7 @@
raise self.wait_query_response()
else:
log.error("TX downstream is not enabled")
- raise self.ERROR()
+ raise self.error()
# Transitions from got_query_response
@ATMT.condition(wait_query_response)
@@ -344,17 +380,19 @@
for id in CHANNELS:
self.send_state.append(False)
self.send(self.p(olt_add, channel_id=id))
+ log.debug("[SENT] PAS5211MsgAddOltChannel")
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()
+ raise self.error()
@ATMT.receive_condition(wait_olt_add)
def wait_for_olt_add(self, pkt):
if PAS5211MsgAddOltChannelResponse in pkt:
+ log.debug("[RESPONSE] PAS5211MsgAddOltChannel")
self.send_state[pkt.channel_id] = True
if self.check_channel_state():
raise self.got_olt_add()
@@ -367,17 +405,19 @@
for id in CHANNELS:
self.send_state.append(False)
self.send(self.p(alarm_msg, channel_id=id))
+ log.debug("[SENT] PAS5211MsgSetAlarmConfig")
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()
+ raise self.error()
@ATMT.receive_condition(wait_alarm_set)
def wait_for_alarm_set(self, pkt):
if PAS5211MsgSetAlarmConfigResponse in pkt:
+ log.debug("[RESPONSE] PAS5211MsgSetAlarmConfig")
self.send_state[pkt.channel_id] = True
if self.check_channel_state():
raise self.got_alarm_set()
@@ -390,19 +430,21 @@
for id in CHANNELS:
self.send_state.append(False)
self.send(self.p(get_dba_mode, channel_id=id))
+ log.debug("[SENT] PAS5211MsgGetDbaMode")
+
raise self.wait_dba_mode()
# Transitions from wait_dba_mode
@ATMT.timeout(wait_dba_mode, 3)
def dba_timeout(self):
log.error("No DBA information returned; disconnecting")
- raise self.ERROR()
-
+ raise self.error()
@ATMT.receive_condition(wait_dba_mode)
def wait_for_dba_mode(self, pkt):
if PAS5211MsgGetDbaModeResponse in pkt:
+ log.debug("[RESPONSE] PAS5211MsgGetDbaMode")
# TODO: What do we do in case the DBA is not loaded.
if pkt.dba_mode == PON_DBA_MODE_LOADED_NOT_RUNNING:
self.send_state[pkt.channel_id] = True
@@ -419,21 +461,24 @@
# Transition from got_dba_mode
@ATMT.condition(got_dba_mode)
def send_start_dba(self):
- dba_start = PAS5211MsgStartDbaAlgorithm(size=0, initialization_data=None)
+ dba_start = PAS5211MsgStartDbaAlgorithm(
+ size=0, initialization_data=None)
for id in CHANNELS:
self.send_state.append(False)
self.send(self.p(dba_start, channel_id=id))
+ log.debug("[SENT] PAS5211MsgStartDbaAlgorithm")
raise self.wait_dba_start()
# Transitions from wait_dba_start
@ATMT.timeout(wait_dba_start, 3)
- def dba_timeout(self):
+ def dba_start_timeout(self):
log.error("DBA has not started; disconnecting")
- raise self.ERROR()
+ raise self.error()
@ATMT.receive_condition(wait_dba_start)
def wait_for_dba_start(self, pkt):
if PAS5211MsgStartDbaAlgorithmResponse in pkt:
+ log.debug("[RESPONSE] PAS5211MsgStartDbaAlgorithm")
self.send_state[pkt.channel_id] = True
if self.check_channel_state():
raise self.got_dba_start()
@@ -442,45 +487,91 @@
# Transitions from got_dba_start
@ATMT.condition(got_dba_start)
def send_activation_period(self):
- activation = PAS5211MsgSetOltChannelActivationPeriod(activation_period=1000)
+ activation = PAS5211MsgSetOltChannelActivationPeriod(
+ activation_period=1000)
for id in CHANNELS:
self.send_state.append(False)
self.send(self.p(activation, channel_id=id))
+ log.debug("[SENT] PAS5211MsgSetOltChannelActivationPeriod")
+
raise self.wait_activation()
# Transitions for wait_for_activation
@ATMT.timeout(wait_activation, 3)
def timeout_activation(self):
log.error("No activation; disconnect")
- raise self.ERROR()
+ raise self.error()
@ATMT.receive_condition(wait_activation)
def wait_for_activation(self, pkt):
if PAS5211MsgSetOltChannelActivationPeriodResponse in pkt:
+ log.debug("[RESPONSE] PAS5211MsgSetOltChannelActivationPeriod")
self.send_state[pkt.channel_id] = True
if self.check_channel_state():
log.info("Ruby OLT at {} initialised".format(self.target))
- self.device.create_logical_device()
+ # self.device.create_logical_device()
self.device.activate()
- raise self.initialized()
+ # self.device.add_upstream_port(129)
+ # self.device.add_logical_upstream_port(129)
+ # keep_alive = KeepAlive(
+ # iface=self.interface, comm=self.comm, target=self.target, device=self.device)
+ # keep_alive.run()
+ raise self.end()
raise self.wait_activation()
- # Keep alive loop
- @ATMT.timeout(initialized, 1)
+
+class KeepAlive(BaseOltAutomaton):
+ """
+ Master filter: Only allow PAS5211MsgGetOltVersionResponse
+ """
+
+ def master_filter(self, pkt):
+ if not super(KeepAlive, self).master_filter(pkt):
+ return False
+
+ if PAS5211MsgGetOltVersionResponse in pkt:
+ return True
+
+ return False
+
+ """
+ States
+ """
+
+ @ATMT.state(initial=1)
+ def init_keepalive(self):
+ log.debug('init-keepalive')
+
+ @ATMT.state()
+ def wait_keepalive(self):
+ pass
+
+ @ATMT.state(error=1)
+ def error(self):
+ raise self.end()
+
+ @ATMT.state(final=1)
+ def end(self):
+ log.debug('init-keepalive-end')
+
+ """
+ Transitions
+ """
+
+ # Send Keep Alive
+ @ATMT.condition(init_keepalive)
def send_keepalive(self):
self.send(self.p(PAS5211MsgGetOltVersion()))
- raise self.wait_keepalive()
+ raise self.got_keepalive()
- # Transitions from wait_keepalive
+ # Timeout
@ATMT.timeout(wait_keepalive, 1)
def timeout_keepalive(self):
log.error("OLT not responding to keep alive; disconnecting")
- raise self.ERROR()
+ raise self.error()
+ # Received Keep Alive
@ATMT.receive_condition(wait_keepalive)
- def wait_for_keepalive(self, pkt):
- if PAS5211MsgGetOltVersionResponse in pkt:
- raise self.initialized()
-
-
-
+ def got_keepalive(self, pkt):
+ log.debug('keepalive-received')
+ raise self.send_keepalive()
diff --git a/voltha/adapters/microsemi_olt/PAS5211.py b/voltha/adapters/microsemi_olt/PAS5211.py
index 947745b..3f642cf 100644
--- a/voltha/adapters/microsemi_olt/PAS5211.py
+++ b/voltha/adapters/microsemi_olt/PAS5211.py
@@ -20,7 +20,6 @@
"""
import struct
-
from scapy.fields import LEShortField, Field, LEIntField, LESignedIntField, FieldLenField, FieldListField, PacketField, \
ByteField, StrFixedLenField, ConditionalField, StrField, MACField, LELongField, LenField, StrLenField
from scapy.layers.l2 import DestMACField, ETHER_ANY, Ether
@@ -35,15 +34,18 @@
"""
PAS5211 Constants
"""
-#TODO get range from olt_version message
-CHANNELS=range(0,4)
+# TODO get range from olt_version message
+CHANNELS = range(0, 4)
+PORTS = range(1, 129)
class XLESignedIntField(Field):
def __init__(self, name, default):
Field.__init__(self, name, default, "<i")
+
def randval(self):
return RandSInt()
+
def i2repr(self, pkt, x):
return lhex(self.i2h(pkt, x))
@@ -83,7 +85,7 @@
class PAS5211MsgGetProtocolVersion(PAS5211Msg):
opcode = 2
name = "PAS5211MsgGetProtocolVersion"
- fields_desc = [ ]
+ fields_desc = []
class PAS5211MsgGetProtocolVersionResponse(PAS5211Msg):
@@ -99,7 +101,7 @@
class PAS5211MsgGetOltVersion(PAS5211Msg):
opcode = 3
name = "PAS5211MsgGetOltVersion"
- fields_desc = [ ]
+ fields_desc = []
class PAS5211MsgGetOltVersionResponse(PAS5211Msg):
@@ -127,7 +129,7 @@
class SnrBurstDelay(Packet):
name = "SnrBurstDelay"
- fields_desc= [
+ fields_desc = [
LEShortField("timer_delay", None),
LEShortField("preamble_delay", None),
LEShortField("delimiter_delay", None),
@@ -137,9 +139,10 @@
def extract_padding(self, p):
return "", p
+
class RngBurstDelay(Packet):
name = "SnrBurstDelay"
- fields_desc= [
+ fields_desc = [
LEShortField("timer_delay", None),
LEShortField("preamble_delay", None),
LEShortField("delimiter_delay", None)
@@ -165,7 +168,7 @@
class GeneralOpticsParams(Packet):
name = "GeneralOpticsParams"
- fields_desc= [
+ fields_desc = [
ByteField("laser_reset_polarity", None),
ByteField("laser_sd_polarity", None),
ByteField("sd_source", None),
@@ -278,7 +281,7 @@
class PAS5211MsgSetOpticsIoControlResponse(PAS5211Msg):
name = "PAS5211MsgSetOpticsIoControlResponse"
- fields_desc = [ ]
+ fields_desc = []
def extract_padding(self, p):
return "", p
@@ -338,15 +341,13 @@
fields_desc = []
-class PAS5211MsgGetDbaModeResponse(PAS5211Msg):
+class PAS5211MsgGetDbaModeResponse(PAS5211Msg):
name = "PAS5211MsgGetDbaModeResponse"
fields_desc = [
LEIntField("dba_mode", None),
]
-
-
class PAS5211MsgAddOltChannel(PAS5211Msg):
opcode = 4
name = "PAS5211MsgAddOltChannel"
@@ -374,7 +375,6 @@
LEIntField("parameter4", None)
]
-
class PAS5211MsgSetOltChannelActivationPeriod(PAS5211Msg):
opcode = 11
name = "PAS5211MsgSetOltChannelActivationPeriod"
@@ -382,17 +382,14 @@
LEIntField("activation_period", None)
]
-
class PAS5211MsgSetOltChannelActivationPeriodResponse(PAS5211Msg):
name = "PAS5211MsgSetOltChannelActivationPeriodResponse"
fields_desc = []
-
class PAS5211MsgSetAlarmConfigResponse(PAS5211Msg):
name = "PAS5211MsgSetAlarmConfigResponse"
fields_desc = []
-
class PAS5211MsgSendCliCommand(PAS5211Msg):
opcode = 15
name = "PAS5211MsgSendCliCommand"
@@ -401,7 +398,6 @@
StrField("command", "")
]
-
class PAS5211MsgSwitchToInboundMode(PAS5211Msg):
opcode = 0xec
name = "PAS5211MsgSwitchToInboundMode"
@@ -414,9 +410,10 @@
opcode = 145
name = "PAS5211MsgGetActivationAuthMode"
fields_desc = [
- LEShortField("nothing", 0) # no idea why this is here
+ LEShortField("nothing", 0) # no idea why this is here
]
+
class PAS5211MsgGetActivationAuthModeResponse(PAS5211Msg):
opcode = 10385
name = "PAS5211MsgGetActivationAuthModeResponse"
@@ -425,6 +422,7 @@
LEShortField("reserved", 0),
]
+
class PAS5211MsgSetOnuOmciPortId(PAS5211Msg):
opcode = 41
name = "PAS5211MsgSetOnuOmciPortId"
@@ -470,14 +468,13 @@
name = "PAS5211MsgSetOnuAllocIdResponse"
fields_desc = []
-
class PAS5211MsgSendDbaAlgorithmMsg(PAS5211Msg):
opcode = 47
name = "PAS5211MsgSendDbaAlgorithmMsg"
fields_desc = [
- #LEShortField("id", None),
+ # LEShortField("id", None),
FieldLenField("size", None, fmt="<H", length_of="data"),
- StrLenField("data", "", length_from=lambda x:x.size)
+ StrLenField("data", "", length_from=lambda x: x.size)
]
class PAS5211MsgSendDbaAlgorithmMsgResponse(PAS5211Msg):
@@ -494,7 +491,7 @@
LEShortField("alloc_id", None),
LEIntField("type", None),
LEIntField("destination", None), # Is this the CNI port
- # if yes then values are 0-11 (for ruby)
+ # if yes then values are 0-11 (for ruby)
LEShortField("reserved", None)
]
@@ -503,7 +500,6 @@
name = "PAS5211MsgSetPortIdConfigResponse"
fields_desc = []
-
class PAS5211MsgGetOnuIdByPortId(PAS5211Msg):
opcode = 196
name = "PAS5211MsgGetOnuIdByPortId"
@@ -512,7 +508,6 @@
LEShortField("reserved", 0)
]
-
class PAS5211MsgGetOnuIdByPortIdResponse(PAS5211Msg):
opcode = 196
name = "PAS5211MsgGetOnuIdByPortIdResponse"
@@ -521,7 +516,6 @@
LEShortField("onu_id", None)
]
-
class PAS5211SetVlanUplinkConfiguration(PAS5211Msg):
opcode = 39
name = "PAS5211SetVlanUplinkConfiguration"
@@ -534,21 +528,18 @@
LEShortField("reserved", 0)
]
-
class PAS5211SetVlanUplinkConfigurationResponse(PAS5211Msg):
opcode = 10279
name = "PAS5211SetVlanUplinkConfigurationResponse"
fields_desc = []
-
class PAS5211GetOnuAllocs(PAS5211Msg):
opcode = 9
name = "PAS5211GetOnuAllocs"
fields_desc = [
- LEShortField("nothing", None) # It's in the PMC code... so yeah.
+ LEShortField("nothing", None) # It's in the PMC code... so yeah.
]
-
class PAS5211GetOnuAllocsResponse(PAS5211Msg):
opcode = 9
name = "PAS5211GetOnuAllocsResponse"
@@ -557,7 +548,6 @@
FieldListField("alloc_ids", None, LEShortField("alloc_id", None))
]
-
class PAS5211GetSnInfo(PAS5211Msg):
opcode = 7
name = "PAS5211GetSnInfo"
@@ -565,7 +555,6 @@
StrFixedLenField("serial_number", None, 8)
]
-
class PAS5211GetSnInfoResponse(PAS5211Msg):
opcode = 7
name = "PAS5211GetSnInfoResponse"
@@ -578,7 +567,6 @@
LEShortField("reserved", None)
]
-
class PAS5211GetOnusRange(PAS5211Msg):
opcode = 116
name = "PAS5211GetOnusRange"
@@ -586,7 +574,6 @@
LEShortField("nothing", None)
]
-
class PAS5211GetOnusRangeResponse(PAS5211Msg):
opcode = 116
name = "PAS5211GetOnusRangeResponse"
@@ -605,7 +592,6 @@
LEShortField("reserved", None)
]
-
class PAS5211GetPortIdConfigResponse(PAS5211Msg):
opcode = 19
name = "PAS5211GetPortIdConfigResponse"
@@ -618,15 +604,6 @@
LEShortField("reserved", None),
]
-# typedef struct
-# {
-# short int svlan_id;
-# PON_true_false_t forwarding_mode;
-# PON_true_false_t use_svlan;
-# PON_true_false_t use_cvlan;
-# PON_true_false_t use_pbits;
-# PON_true_false_t discard_unknown;
-# } PASCOMM_msg_set_svlan_at_configuration_t;
class PAS5211SetSVlanAtConfig(PAS5211Msg):
opcode = 63
name = "PAS5211SetSVlanAtConfig"
@@ -639,23 +616,11 @@
LEShortField("discard_unknown", None),
]
-
class PAS5211SetSVlanAtConfigResponse(PAS5211Msg):
opcode = 63
name = "PAS5211SetSVlanAtConfigResponse"
fields_desc = []
-# typedef struct
-# {
-# PON_port_id_t source_port_id;
-# PON_vlan_tag_t primary_vid;
-# PON_true_false_t pvid_config_enabled; /* use_pvid */
-# PON_vlan_tag_operation_t svlan_tag_operation;
-# PON_vlan_tag_operation_t cvlan_tag_operation;
-# PON_vlan_tag_t new_svlan_tag;
-# PON_vlan_tag_t new_cvlan_tag;
-# PON_vlan_destination_t destination;
-# } PASCOMM_msg_set_uplink_vlan_handling_t;
class PAS5211SetUplinkVlanHandl(PAS5211Msg):
opcode = 34
@@ -676,17 +641,6 @@
name = "PAS5211SetUplinkVlanHandlResponse"
fields_desc = []
-# typedef struct
-# {
-# PON_pon_network_traffic_direction_t direction;
-# unsigned short extended_svlan_type;
-# unsigned short insertion_svlan_ethertype;
-# unsigned short extended_cvlan_type;
-# unsigned short insertion_cvlan_ethertype;
-# PON_pcp_scheme_t pon_pcp_code;
-# PON_pcp_scheme_t cni_pcp_code;
-# unsigned short reserved;
-# } PASCOMM_msg_set_vlan_general_configuration_t;
class PAS5211SetVlanGenConfig(PAS5211Msg):
opcode = 43
name = "PAS5211SetVlanGenConfig"
@@ -701,16 +655,52 @@
LEShortField("reserved", None)
]
-
class PAS5211SetVlanGenConfigResponse(PAS5211Msg):
opcode = 43
name = "PAS5211SetVlanGenConfigResponse"
fields_desc = []
+
+class PAS5211SetVlanDownConfig(PAS5211Msg):
+ opcode = 32
+ name = "PAS5211SetVlanDownConfig"
+ fields_desc = [
+ LEShortField("svlan_id", None),
+ LEShortField("double_tag_handling", None),
+ LEShortField("vlan_priority_handling", None)
+ ]
+
+class PAS5211SetVlanDownConfigResponse(PAS5211Msg):
+ opcode = 32
+ name = "PAS5211SetVlanDownConfigResponse"
+ fields_desc = []
+
+class PAS5211SetDownVlanHandl(PAS5211Msg):
+ opcode = 27
+ name = "PAS5211SetDownVlanHandl"
+ fields_desc = [
+ LEShortField("svlan_tag", None),
+ LEShortField("cvlan_tag", None),
+ LEShortField("double_tag_handling", None),
+ LEShortField("priority_handling", None),
+ LEShortField("input_priority", None),
+ LEShortField("svlan_tag_operation", None),
+ LEShortField("cvlan_tag_operation", None),
+ LEShortField("port_id", None),
+ LEShortField("new_cvlan_tag", None),
+ LEShortField("destination", None),
+ LEShortField("output_vlan_prio_handle", None),
+ LEShortField("output_priority", None)
+ ]
+
+class PAS5211SetDownVlanHandlResponse(PAS5211Msg):
+ opcode = 27
+ name = "PAS5211SetDownVlanHandlResponse"
+ fields_desc = []
+
class Frame(Packet):
pass
-
class PAS5211MsgSendFrame(PAS5211Msg):
opcode = 42
name = "PAS5211MsgSendFrame"
@@ -719,23 +709,20 @@
LEShortField("port_type", PON_PORT_PON),
LEShortField("port_id", 0),
LEShortField("management_frame", PON_FALSE),
- ConditionalField(PacketField("frame", None, Packet), lambda pkt: pkt.management_frame==PON_FALSE),
- ConditionalField(PacketField("frame", None, OmciFrame), lambda pkt: pkt.management_frame==PON_TRUE)
+ ConditionalField(PacketField("frame", None, Packet), lambda pkt: pkt.management_frame == PON_FALSE),
+ ConditionalField(PacketField("frame", None, OmciFrame), lambda pkt: pkt.management_frame == PON_TRUE)
]
def extract_padding(self, p):
return "", p
-
class PAS5211MsgSendFrameResponse(PAS5211Msg):
name = "PAS5211MsgSendFrameResponse"
fields_desc = []
-
class PAS5211Event(PAS5211Msg):
opcode = 12
-
class PAS5211EventFrameReceived(PAS5211Event):
name = "PAS5211EventFrameReceived"
fields_desc = [
@@ -746,9 +733,9 @@
LEShortField("classification_entity", None),
LEShortField("l3_offset", None),
LEShortField("l4_offset", None),
- LEShortField("ignored", 0), # TODO these do receive values, but there is no code in PMC using it
- ConditionalField(PacketField("frame", None, Packet), lambda pkt: pkt.management_frame==PON_FALSE),
- ConditionalField(PacketField("frame", None, OmciFrame), lambda pkt: pkt.management_frame==PON_TRUE)
+ LEShortField("ignored", 0), # TODO these do receive values, but there is no code in PMC using it
+ ConditionalField(PacketField("frame", None, Packet), lambda pkt: pkt.management_frame == PON_FALSE),
+ ConditionalField(PacketField("frame", None, OmciFrame), lambda pkt: pkt.management_frame == PON_TRUE)
]
class PAS5211EventDbaAlgorithm(PAS5211Event):
@@ -758,20 +745,265 @@
StrLenField("data", "", length_from=lambda x: x.size)
]
-
class PAS5211EventOnuActivation(PAS5211Event):
name = "PAS5211EventOnuActivation"
+ event_type = 1
fields_desc = [
StrFixedLenField("serial_number", None, length=8),
LEIntField("equalization_period", None)
]
+class PAS5211EventOnuDeactivation(PAS5211Event):
+ name = "PAS5211EventOnuDeactivation"
+ event_type = 2
+ fields_desc = [
+ LEShortField("code", None)
+ ]
+
+class PAS5211EventLogMsg(PAS5211Event):
+ name = "PAS5211EventLogMsg"
+ event_type = 3
+ fields_desc = []
+
+class PAS5211EventFWGeneralPrint(PAS5211Event):
+ name = "PAS5211EventFWGeneralPrint"
+ event_type = 4
+ fields_desc = []
+
+class PAS5211EventFWTracePrint(PAS5211Event):
+ name = "PAS5211EventFWTracePrint"
+ event_type = 5
+ fields_desc = []
+
+class PAS5211EventStartEncryption(PAS5211Event):
+ name = "PAS5211EventStartEncryption"
+ event_type = 6
+ fields_desc = []
+
+class PAS5211EventStopEncryption(PAS5211Event):
+ name = "PAS5211EventStopEncryption"
+ event_type = 7
+ fields_desc = []
+
+class PAS5211EventUpdateEncryption(PAS5211Event):
+ name = "PAS5211EventUpdateEncryption"
+ event_type = 8
+ fields_desc = []
+
+class PAS5211EventAlarmNotification(PAS5211Event):
+ name = "PAS5211EventAlarmNotification"
+ event_type = 9
+ fields_desc = [
+ LEShortField("code", None),
+ LEIntField("parameter1", None),
+ LEIntField("parameter2", None),
+ LEIntField("parameter3", None),
+ LEIntField("parameter4", None)
+ ]
+
+class PAS5211EventDBAAlgorithmEvent(PAS5211Event):
+ name = "PAS5211EventDBAAlgorithmEvent"
+ event_type = 11
+ fields_desc = []
+
+class PAS5211EventOLTReset(PAS5211Event):
+ name = "PAS5211EventOLTReset"
+ event_type = 12
+ fields_desc = []
+
+class PAS5211EventOnuSleepMode(PAS5211Event):
+ name = "PAS5211EventOnuSleepMode"
+ event_type = 13
+ fields_desc = []
+
+class PAS5211EventAssignAllocId(PAS5211Event):
+ name = "PAS5211EventAssignAllocId"
+ event_type = 14
+ fields_desc = []
+
+class PAS5211EventConfigOMCIPort(PAS5211Event):
+ name = "PAS5211EventConfigOMCIPort"
+ event_type = 15
+ fields_desc = []
+
+class PAS5211EventPloamMessageReceived(PAS5211Event):
+ name = "PAS5211EventPloamMessageReceived"
+ event_type = 17
+ fields_desc = []
+
+class PAS5211EventLoadOLTBinaryCompleted(PAS5211Event):
+ name = "PAS5211EventLoadOLTBinaryCompleted"
+ event_type = 18
+ fields_desc = []
+
+class PAS5211EventMasterOLTFail(PAS5211Event):
+ name = "PAS5211EventMasterOLTFail"
+ event_type = 19
+ fields_desc = []
+
+class PAS5211EventRedundantSwitchOverStatus(PAS5211Event):
+ name = "PAS5211EventRedundantSwitchOverStatus"
+ event_type = 20
+ fields_desc = []
+
+class PAS5211EventSyncOLTData(PAS5211Event):
+ name = "PAS5211EventSyncOLTData"
+ event_type = 21
+ fields_desc = []
+
+class PAS5211EventEQDChange(PAS5211Event):
+ name = "PAS5211EventEQDChange"
+ event_type = 22
+ fields_desc = []
+
+class PAS5211EventXAUIStatusNotification(PAS5211Event):
+ name = "PAS5211EventXAUIStatusNotification"
+ event_type = 23
+ fields_desc = []
+
+class PAS5211EventUnauthenticatedONU(PAS5211Event):
+ name = "PAS5211EventUnauthenticatedONU"
+ event_type = 24
+ fields_desc = []
+
+class PAS5211EventFalseQFullReported(PAS5211Event):
+ name = "PAS5211EventFalseQFullReported"
+ event_type = 25
+ fields_desc = []
+
+class PAS5211EventOpticalModuleIndication(PAS5211Event):
+ name = "PAS5211EventOpticalModuleIndication"
+ event_type = 27
+ fields_desc = []
+
+class PAS5211EventActivationFailure(PAS5211Event):
+ name = "PAS5211EventActivationFailure"
+ event_type = 28
+ fields_desc = []
+
+class PAS5211EventBipError(PAS5211Event):
+ name = "PAS5211EventBipError"
+ event_type = 29
+ fields_desc = []
+
+class PAS5211EventREIError(PAS5211Event):
+ name = "PAS5211EventREIError"
+ event_type = 30
+ fields_desc = []
+
+class PAS5211EventRDNMultiONUFailure(PAS5211Event):
+ name = "PAS5211EventRDNMultiONUFailure"
+ event_type = 31
+ fields_desc = []
+
+class PAS5211EventUnexpectedSN(PAS5211Event):
+ name = "PAS5211EventUnexpectedSN"
+ event_type = 32
+ fields_desc = []
+
+class PAS5211EventRDNSwitchOverONUResult(PAS5211Event):
+ name = "PAS5211EventRDNSwitchOverONUResult"
+ event_type = 33
+ fields_desc = []
+
+class PAS5211EventGMacMalfucntionSuspected(PAS5211Event):
+ name = "PAS5211EventGMacMalfucntionSuspected"
+ event_type = 34
+ fields_desc = []
+
+
+class PAS5211GetPortIdDownstreamPolicingConfig(PAS5211Msg):
+ opcode = 82
+ name = "PAS5211GetPortIdDownstreamPolicingConfig"
+ fields_desc = [
+ LEShortField("port_id", None),
+ LEShortField("reserved", None)]
+
+class PAS5211GetPortIdDownstreamPolicingConfigResponse(PAS5211Msg):
+ opcode = 82
+ name = "PAS5211GetPortIdDownstreamPolicingConfigResponse"
+ fields_desc = [
+ LEIntField("committed_bandwidth", None),
+ LEIntField("excessive_bandwidth", None),
+ LEShortField("committed_burst_limit", None),
+ LEShortField("excessive_burst_limit", None),
+ LEShortField("ds_policing_config_id", None),
+ LEShortField("reserved", None)]
+
+class PAS5211RemoveDownstreamPolicingConfig(PAS5211Msg):
+ opcode = 76
+ name = "PAS5211RemoveDownstreamPolicingConfig"
+ fields_desc = [
+ LEShortField("policing_config_id", None),
+ LEShortField("reserved", None)]
+
+class PAS5211RemoveDownstreamPolicingConfigResponse(PAS5211Msg):
+ opcode = 76
+ name = "PAS5211RemoveDownstreamPolicingConfigResponse"
+ fields_desc = []
+
+class PAS5211SetPortIdPolicingConfig(PAS5211Msg):
+ opcode = 80
+ name = "PAS5211SetPortIdPolicingConfig"
+ fields_desc = [
+ LEShortField("direction", None),
+ LEShortField("port_id", None),
+ LEShortField("policing_config_id", None),
+ LEShortField("reserved", None)]
+
+class PAS5211SetPortIdPolicingConfigResponse(PAS5211Msg):
+ opcode = 80
+ name = "PAS5211SetPortIdPolicingConfigResponse"
+ fields_desc = []
+
+class PAS5211UnsetPortIdPolicingConfig(PAS5211Msg):
+ opcode = 81
+ name = "PAS5211UnsetSetPortIdPolicingConfig"
+ fields_desc = [
+ LEShortField("direction", None),
+ LEShortField("port_id", None)]
+
+class PAS5211UnsetPortIdPolicingConfigResponse(PAS5211Msg):
+ opcode = 81
+ name = "PAS5211UnsetSetPortIdPolicingConfigResponse"
+ fields_desc = []
+
+class PAS5211SetDownstreamPolicingConfig(PAS5211Msg):
+ opcode = 74
+ name = "PAS5211SetDownstreamPolicingConfig"
+ fields_desc = [
+ LEIntField("committed_bandwidth", None),
+ LEIntField("excessive_bandwidth", None),
+ LEShortField("committed_burst_limit", None),
+ LEShortField("excessive_burst_limit", None)]
+
+class PAS5211SetDownstreamPolicingConfigResponse(PAS5211Msg):
+ opcode = 74
+ name = "PAS5211SetDownstreamPolicingConfigResponse"
+ fields_desc = [
+ LEShortField("policing_config_id", None),
+ LEShortField("reserved", None)]
+
+class PAS5211SetUpstreamPolicingConfig(PAS5211Msg):
+ opcode = 77
+ name = "PAS5211SetUpstreamPolicingConfig"
+ fields_desc = [
+ LEIntField("bandwidth", None),
+ LEShortField("burst_limit", None),
+ LEShortField("reserved", None)]
+
+class PAS5211SetUpstreamPolicingConfigResponse(PAS5211Msg):
+ opcode = 77
+ name = "PAS5211SetDownstreamPolicingResponse"
+ fields_desc = [
+ LEShortField("policing_config_id", None),
+ LEShortField("reserved", None)]
class PAS5211Dot3(Packet):
name = "PAS5211Dot3"
- fields_desc = [ DestMACField("dst"),
- MACField("src", ETHER_ANY),
- LenField("len", None, "H") ]
+ fields_desc = [DestMACField("dst"),
+ MACField("src", ETHER_ANY),
+ LenField("len", None, "H")]
MIN_FRAME_SIZE = 60
@@ -789,6 +1021,7 @@
This is needed in order to force scapy to use PAS5211Dot3
instead of the default Dot3 that the Ether class uses.
'''
+
@classmethod
def PAS_dispatch_hook(cls, _pkt=None, *args, **kargs):
if _pkt and len(_pkt) >= 14:
@@ -799,7 +1032,6 @@
Ether.dispatch_hook = PAS_dispatch_hook
# bindings for messages received
-
# fix for v2 of Microsemi OLT.
bind_layers(Ether, PAS5211FrameHeader, type=0x0a00)
@@ -887,10 +1119,37 @@
bind_layers(PAS5211MsgHeader, PAS5211SetVlanGenConfig, opcode=0x3000 | 43)
bind_layers(PAS5211MsgHeader, PAS5211SetVlanGenConfigResponse, opcode=0x2800 | 43)
+bind_layers(PAS5211MsgHeader, PAS5211SetVlanDownConfig, opcode=0x3000 | 32)
+bind_layers(PAS5211MsgHeader, PAS5211SetVlanDownConfigResponse, opcode=0x2800 | 32)
+
+bind_layers(PAS5211MsgHeader, PAS5211SetDownVlanHandl, opcode=0x3000 | 27)
+bind_layers(PAS5211MsgHeader, PAS5211SetDownVlanHandlResponse, opcode=0x2800 | 27)
+
+bind_layers(PAS5211MsgHeader, PAS5211SetDownstreamPolicingConfig, opcode=0x3000 | 74)
+bind_layers(PAS5211MsgHeader, PAS5211SetDownstreamPolicingConfigResponse, opcode=0x2800 | 74)
+
+bind_layers(PAS5211MsgHeader, PAS5211SetUpstreamPolicingConfig, opcode=0x3000 | 77)
+bind_layers(PAS5211MsgHeader, PAS5211SetUpstreamPolicingConfigResponse, opcode=0x2800 | 77)
+
+bind_layers(PAS5211MsgHeader, PAS5211SetPortIdPolicingConfig, opcode=0x3000 | 80)
+bind_layers(PAS5211MsgHeader, PAS5211SetPortIdPolicingConfigResponse, opcode=0x2800 | 80)
+
+bind_layers(PAS5211MsgHeader, PAS5211UnsetPortIdPolicingConfig, opcode=0x3000 | 81)
+bind_layers(PAS5211MsgHeader, PAS5211UnsetPortIdPolicingConfigResponse, opcode=0x2800 | 81)
+
+bind_layers(PAS5211MsgHeader, PAS5211GetPortIdDownstreamPolicingConfig, opcode=0x3000 | 82)
+bind_layers(PAS5211MsgHeader, PAS5211GetPortIdDownstreamPolicingConfigResponse, opcode=0x2800 | 82)
+
+bind_layers(PAS5211MsgHeader, PAS5211RemoveDownstreamPolicingConfig, opcode=0x3000 | 76)
+bind_layers(PAS5211MsgHeader, PAS5211RemoveDownstreamPolicingConfigResponse, opcode=0x2800 | 76)
+
+
# bindings for events received
bind_layers(PAS5211MsgHeader, PAS5211EventOnuActivation, opcode=0x2800 | 12, event_type=1)
+bind_layers(PAS5211MsgHeader, PAS5211EventOnuDeactivation, opcode=0x2800 | 12, event_type=2)
bind_layers(PAS5211MsgHeader, PAS5211EventFrameReceived, opcode=0x2800 | 12, event_type=10)
bind_layers(PAS5211MsgHeader, PAS5211EventDbaAlgorithm, opcode=0x2800 | 12, event_type=11)
+bind_layers(PAS5211MsgHeader, PAS5211EventAlarmNotification, opcode=0x2800 | 12, event_type=9)
bind_layers(PAS5211MsgHeader, PAS5211Event, opcode=0x2800 | 12)
@@ -918,10 +1177,21 @@
from scapy.utils import rdpcap
import sys
import code
+
packets = rdpcap(sys.argv[1])
p = Display(packets)
- def walk(index=0):
- p.walk(index=index)
+ def walk(index=0, interactive=True, channel=-1):
+ if interactive is not True:
+ for packet in packets:
+ if PAS5211MsgHeader in packet:
+ if PAS5211MsgGetOltVersion not in packet and PAS5211MsgGetOltVersionResponse not in packet:
+ if channel is not -1:
+ if packet[PAS5211MsgHeader].channel_id == channel:
+ packet.show()
+ else:
+ packet.show()
+ else:
+ p.walk(index=index)
- code.interact(local=locals())
\ No newline at end of file
+ code.interact(local=locals())
diff --git a/voltha/adapters/microsemi_olt/PAS5211_comm.py b/voltha/adapters/microsemi_olt/PAS5211_comm.py
index e7cc36d..bd9c8c0 100644
--- a/voltha/adapters/microsemi_olt/PAS5211_comm.py
+++ b/voltha/adapters/microsemi_olt/PAS5211_comm.py
@@ -20,7 +20,6 @@
log = structlog.get_logger()
-
def constructPAS5211Frames(msg, seq, src_mac, dst_mac, channel_id=-1,
onu_id=-1, onu_session_id=-1):
@@ -41,26 +40,23 @@
return frame
-
def sequence_generator(init):
num = init
while True:
yield num
num += 1
-
def determine_src_mac(iface):
if iface in netifaces.interfaces():
return netifaces.ifaddresses(iface)[netifaces.AF_LINK][0]['addr']
return None
-
class PAS5211Communication(object):
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.seqgen = sequence_generator(init)
def frame(self, msg, channel_id=-1, onu_id=-1, onu_session_id=-1):
return constructPAS5211Frames(msg, self.seqgen.next(), self.src_mac,
diff --git a/voltha/adapters/microsemi_olt/PAS5211_constants.py b/voltha/adapters/microsemi_olt/PAS5211_constants.py
index e70db40..9f7718f 100644
--- a/voltha/adapters/microsemi_olt/PAS5211_constants.py
+++ b/voltha/adapters/microsemi_olt/PAS5211_constants.py
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+from enum import Enum
"""
PAS5211 Constants
@@ -60,7 +61,6 @@
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
@@ -77,70 +77,72 @@
PON_ALARM_LOKI = 13
PON_ALARM_TIWI = 14
PON_ALARM_TIA = 15
+PON_ALARM_AUTH_FAILED_IN_REGISTRATION_ID_MODE = 20
+PON_ALARM_SUFI = 21
+
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
+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
+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
+PON_ENABLE_CLEAR_ALARM = 1004
# Enable or disabl send assign alloc id ploam. 0 - disable, 1 - enable
-PON_ASSIGN_ALLOC_ID_PLOAM = 1005
+PON_ASSIGN_ALLOC_ID_PLOAM = 1005
# BIP error polling period, 200 - 65000, 0 - Disabled, Recommended: 5000
# (default)
-PON_BIP_ERR_POLLING_PERIOD_MS = 1006
+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
+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
+PON_ONU_PRE_ASSIGNED_DELAY = 1008
# Enable or disable DS fragmentation, 0 disable, 1 enable
-PON_DS_FRAGMENTATION = 1009
+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
+PON_REI_ERRORS_REPORT_ALL = 1010
# Set if igonre sfi deactivation, 0 disable (default), 1 enable
-PON_IGNORE_SFI_DEACTIVATION = 1011
+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
+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
+PON_OPTICS_TIMELINE_OFFSET = 1013
# Last general meter
-PON_LAST_GENERAL_PARAMETER = PON_OPTICS_TIMELINE_OFFSET
+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
+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
@@ -157,86 +159,139 @@
# 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
+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
-PON_ACTIVATION_AUTH_AUTO = 0
+PON_ACTIVATION_AUTH_AUTO = 0
PON_ACTIVATION_AUTH_HOST_CONTROLLED_SEPARATE_EVENTS = 1 # Host controlled: Separate events
-PON_ACTIVATION_AUTH_HOST_CONTROLLED_LUMPED_SN = 2 # Host controlled: Lumped-SN-Response
-PON_ACTIVATION_AUTH_REGISTRATION_ID_RAW = 3 # Registration-ID Raw
-PON_ACTIVATION_AUTH_REGISTRATION_ID_LEARN = 4 # Registration-ID Learn
+PON_ACTIVATION_AUTH_HOST_CONTROLLED_LUMPED_SN = 2 # Host controlled: Lumped-SN-Response
+PON_ACTIVATION_AUTH_REGISTRATION_ID_RAW = 3 # Registration-ID Raw
+PON_ACTIVATION_AUTH_REGISTRATION_ID_LEARN = 4 # Registration-ID Learn
-PON_LOGICAL_OBJECT_TYPE_ALLOC_ID = 0
+PON_LOGICAL_OBJECT_TYPE_ALLOC_ID = 0
PON_LOGICAL_OBJECT_TYPE_ONU_ID_BY_ALLOC_ID = 1
-PON_LOGICAL_OBJECT_TYPE_MAX = PON_LOGICAL_OBJECT_TYPE_ONU_ID_BY_ALLOC_ID
+PON_LOGICAL_OBJECT_TYPE_MAX = PON_LOGICAL_OBJECT_TYPE_ONU_ID_BY_ALLOC_ID
+PMC_OFAL_MAX_BI_DIRECTIONAL_FLOW_PER_ONU = 16
+PMC_OFAL_START_FLOW_ID_BASE = 1000
-PMC_OFAL_MAX_BI_DIRECTIONAL_FLOW_PER_ONU = 16
-PMC_OFAL_START_FLOW_ID_BASE = 1000
+PON_DL_VLAN_SVLAN_REMOVE = 3
+PON_DL_VLAN_CVLAN_NO_CHANGE = 0
+
+PON_VLAN_DONT_CHANGE_TAG = 0
+PON_VLAN_CHANGE_TAG = 1
+PON_VLAN_CHANGE_OTHER_TAG = 2
+PON_VLAN_CHANGE_REMOVE_TAG = 3
+
+PON_VLAN_UNUSED_TAG = -1
+PON_VLAN_DEST_DATAPATH = 1
+PON_VLAN_UNCHANGED_PRIORITY = -1
+PON_VLAN_REPLACE_PRIORITY = -2
+PON_VLAN_UNUSED_PRIORITY = -1
+
+PON_OUTPUT_VLAN_PRIO_HANDLE_DONT_CHANGE = 0
+PON_OUTPUT_VLAN_PRIO_HANDLE_INCOMING_VLAN = 1
+PON_OUTPUT_VLAN_PRIO_HANDLE_DL_VLAN_TABLE = 2
+
+PON_N_TO_1_VLAN_MODE = 0
+PON_1_TO_1_VLAN_MODE = 1
# OMCI
OMCI_8021P_MSP_UNMARKED_FRAME_TAG_FRAME = 1
-OMCI_8021P_MSP_TP_TYPE_NULL = 0
+OMCI_8021P_MSP_TP_TYPE_NULL = 0
# GEM interworking option for MAC Bridge LAN
-OMCI_GEM_IWTP_IW_OPT_8021P_MAPPER = 5
+OMCI_GEM_IWTP_IW_OPT_8021P_MAPPER = 5
#LLC frame encapsulation method
-OMCI_MAC_BRIDGE_PCD_ENCAP_METHOD_LLC = 1
+OMCI_MAC_BRIDGE_PCD_ENCAP_METHOD_LLC = 1
# Frame Check Sequence will forward
-OMCI_MAC_BRIDGE_PCD_LANFCS_FORWARDED = 0
+OMCI_MAC_BRIDGE_PCD_LANFCS_FORWARDED = 0
# in DS, perform the inverse of US operation
-OMCI_EX_VLAN_TAG_OCD_DS_MODE_US_INVERSE = 0
+OMCI_EX_VLAN_TAG_OCD_DS_MODE_US_INVERSE = 0
# Physical path termination point Ethernet UNI
-OMCI_EX_VLAN_TAG_OCD_ASSOCIATION_TYPE_PPTP_ETH_UNI = 2
+OMCI_EX_VLAN_TAG_OCD_ASSOCIATION_TYPE_PPTP_ETH_UNI = 2
# GEM Port Network CTP
# Direction definitions
-GEM_DIR_BIDIRECT = 3 # bi-directional
+GEM_DIR_BIDIRECT = 3 # bi-directional
+# PMC
+PMC_UPSTREAM_PORT = 129
# SLA
-PYTHAGORAS_UPDATE_AID_SLA = 21
-
-PYTHAGORAS_DBA_DATA_COS = 0
-PYTHAGORAS_DBA_STATUS_REPORT_NSR = 0
-
-PYTHAGORAS_SET_SLA_RESP_SIZE = 10
+PYTHAGORAS_UPDATE_AID_SLA = 21
+PYTHAGORAS_DBA_DATA_COS = 0
+PYTHAGORAS_DBA_STATUS_REPORT_NSR = 0
+PYTHAGORAS_SET_SLA_RESP_SIZE = 10
# Random values found in PMC code
-SLA_gr_bw_gros = 1;
-SLA_be_bw_gros = 10;
-SLA_gr_bw_fine = 0;
+SLA_gr_bw_gros = 30
+SLA_be_bw_gros = 300
+SLA_gr_bw_fine = 0
SLA_be_bw_fine = 0
+PON_MAX_DS_POLICING_CONFIGURATION_INDEX = 255
+PMC_OFAL_NO_POLICY = PON_MAX_DS_POLICING_CONFIGURATION_INDEX+1
+
+#Enum classes to set alarm parameters
+
+class AlarmEventType(Enum):
+ COMMUNICATION = 0
+ ENVIRONMENT = 1
+ EQUIPTMENT = 2
+ SERVICE = 3
+ PROCESSING = 4
+ SECURITY = 5
+
+class AlarmEventCategory(Enum):
+ PON = 0
+
+class AlarmEventState(Enum):
+ RAISED = 1
+ CLEARED = 0
+
+class AlarmEventSeverity(Enum):
+ INDETERMINATE = 0
+ WARNING = 1
+ MINOR = 2
+ MAJOR = 3
+ CRITICAL = 4
+
+AlarmEventStateDefault = 1
+
+UPSTREAM = 1
+DOWNSTREAM = 2
+
+PASCOMM_RETRIES = 5
diff --git a/voltha/adapters/microsemi_olt/microsemi_olt.py b/voltha/adapters/microsemi_olt/microsemi_olt.py
index cf30317..b37b0b6 100644
--- a/voltha/adapters/microsemi_olt/microsemi_olt.py
+++ b/voltha/adapters/microsemi_olt/microsemi_olt.py
@@ -25,7 +25,10 @@
from voltha.adapters.microsemi_olt.ActivationWatcher import ActivationWatcher
from voltha.adapters.microsemi_olt.DeviceManager import DeviceManager
from voltha.adapters.microsemi_olt.OMCIProxy import OMCIProxy
-from voltha.adapters.microsemi_olt.OltStateMachine import OltStateMachine
+from voltha.adapters.microsemi_olt.OltStateMachine import OltStateMachine
+from voltha.adapters.microsemi_olt.OltInstallFlowStateMachine import OltInstallFlowStateMachine
+from voltha.adapters.microsemi_olt.OltRemoveFlowStateMachine import OltRemoveFlowStateMachine
+from voltha.adapters.microsemi_olt.OltReinstallFlowStateMachine import OltReinstallFlowStateMachine
from voltha.adapters.microsemi_olt.PAS5211_comm import PAS5211Communication
from voltha.extensions.omci.omci_frame import OmciFrame
from voltha.extensions.omci.omci_messages import OmciMessage
@@ -35,9 +38,43 @@
from voltha.protos.device_pb2 import DeviceTypes, DeviceType
from voltha.protos.health_pb2 import HealthStatus
from voltha.registry import registry
-
from zope.interface import implementer
+import voltha.core.flow_decomposer as fd
+
+from voltha.protos.openflow_13_pb2 import OFPPF_1GB_FD, OFPPF_FIBER, ofp_port, OFPPS_LIVE, OFPXMC_OPENFLOW_BASIC
+
+from voltha.protos.openflow_13_pb2 import Flows, FlowGroups
+
+from voltha.adapters.microsemi_olt.PAS5211 import PAS5211GetOnuAllocs, PAS5211GetOnuAllocsResponse, PAS5211GetSnInfo, \
+ PAS5211GetSnInfoResponse, PAS5211GetOnusRange, PAS5211GetOnusRangeResponse, PAS5211MsgSetOnuOmciPortId, \
+ PAS5211MsgSetOnuOmciPortIdResponse, PAS5211MsgSetOnuAllocId, PAS5211MsgSetOnuAllocIdResponse, \
+ PAS5211SetSVlanAtConfig, PAS5211SetSVlanAtConfigResponse, PAS5211SetVlanDownConfig, \
+ PAS5211SetVlanDownConfigResponse, PAS5211SetDownVlanHandl, PAS5211SetDownVlanHandlResponse, \
+ PAS5211SetUplinkVlanHandl, PAS5211SetDownstreamPolicingConfigResponse, PAS5211SetDownstreamPolicingConfig, \
+ PAS5211SetPortIdPolicingConfig, PAS5211UnsetPortIdPolicingConfig, \
+ PAS5211MsgSendDbaAlgorithmMsg, PAS5211MsgSendDbaAlgorithmMsgResponse, \
+ PAS5211SetUpstreamPolicingConfigResponse, PAS5211SetUpstreamPolicingConfig, \
+ PAS5211MsgSetPortIdConfig, PAS5211MsgSetPortIdConfigResponse, \
+ PAS5211MsgGetOnuIdByPortId, PAS5211MsgGetOnuIdByPortIdResponse, \
+ PAS5211SetVlanUplinkConfiguration, PAS5211SetVlanUplinkConfigurationResponse, PAS5211SetUplinkVlanHandlResponse, PAS5211SetVlanGenConfig, PAS5211SetVlanGenConfigResponse, \
+ PAS5211GetPortIdDownstreamPolicingConfig, PAS5211GetPortIdDownstreamPolicingConfigResponse, PAS5211RemoveDownstreamPolicingConfig, \
+ PAS5211MsgHeader, PAS5211UnsetPortIdPolicingConfigResponse, PAS5211RemoveDownstreamPolicingConfigResponse, \
+ PAS5211SetPortIdPolicingConfigResponse
+from voltha.adapters.microsemi_olt.PAS5211_constants import OMCI_GEM_IWTP_IW_OPT_8021P_MAPPER, PON_FALSE, \
+ PON_1_TO_1_VLAN_MODE, PON_TRUE, PON_VLAN_UNUSED_TAG, PON_VLAN_UNUSED_PRIORITY, PON_VLAN_REPLACE_PRIORITY, \
+ PON_OUTPUT_VLAN_PRIO_HANDLE_INCOMING_VLAN, PON_VLAN_UNCHANGED_PRIORITY, PON_OUTPUT_VLAN_PRIO_HANDLE_DONT_CHANGE, \
+ PON_OUTPUT_VLAN_PRIO_HANDLE_DL_VLAN_TABLE, PON_DL_VLAN_SVLAN_REMOVE, PON_DL_VLAN_CVLAN_NO_CHANGE, \
+ PON_VLAN_DEST_DATAPATH, GEM_DIR_BIDIRECT, OMCI_MAC_BRIDGE_PCD_LANFCS_FORWARDED, \
+ OMCI_MAC_BRIDGE_PCD_ENCAP_METHOD_LLC, OMCI_8021P_MSP_UNMARKED_FRAME_TAG_FRAME, OMCI_8021P_MSP_TP_TYPE_NULL, \
+ OMCI_EX_VLAN_TAG_OCD_ASSOCIATION_TYPE_PPTP_ETH_UNI, OMCI_EX_VLAN_TAG_OCD_DS_MODE_US_INVERSE, PMC_UPSTREAM_PORT, \
+ PON_DISABLE, PON_VLAN_CHANGE_TAG, PON_VLAN_DONT_CHANGE_TAG, PON_PORT_TYPE_GEM, PON_PORT_DESTINATION_CNI0, PON_ENABLE, SLA_gr_bw_gros, PYTHAGORAS_UPDATE_AID_SLA, \
+ SLA_gr_bw_gros, SLA_be_bw_gros, SLA_gr_bw_fine, SLA_be_bw_fine, PYTHAGORAS_DBA_DATA_COS, PYTHAGORAS_DBA_STATUS_REPORT_NSR, \
+ PMC_OFAL_NO_POLICY, UPSTREAM, DOWNSTREAM
+
+from twisted.internet import reactor
+from twisted.internet.defer import DeferredQueue, inlineCallbacks, returnValue
+
log = structlog.get_logger()
_ = third_party
@@ -58,25 +95,23 @@
def __init__(self, adaptor_agent, config):
self.adaptor_agent = adaptor_agent
self.config = config
- self.olts = {}
+ self.device_handlers = dict()
self.descriptor = Adapter(
id=self.name,
vendor='Microsemi / Celestica',
- version='0.1',
+ version='0.2',
config=AdapterConfig(log_level=LogLevel.INFO)
)
- self.interface = registry('main').get_args().interface
-
def start(self):
- log.info('starting')
+ log.debug('starting')
log.info('started')
return self
def stop(self):
log.debug('stopping')
- for target in self.olts.keys():
- self._abandon(target)
+ for handler in self.device_handlers:
+ handler.stop()
log.info('stopped')
return self
@@ -93,23 +128,15 @@
raise NotImplementedError()
def adopt_device(self, device):
- device_manager = DeviceManager(device, self.adaptor_agent)
- target = device.mac_address
- comm = PAS5211Communication(dst_mac=target, iface=self.interface)
- olt = OltStateMachine(iface=self.interface, comm=comm,
- target=target, device=device_manager)
- activation = ActivationWatcher(iface=self.interface, comm=comm,
- target=target, device=device_manager)
- reactor.callLater(0, self._init_olt, olt, activation)
-
- log.info('adopted-device', device=device)
- self.olts[target] = (olt, activation, comm)
+ log.debug('adopt-device', device=device)
+ self.device_handlers[device.id] = RubyAdapterHandler(self.adaptor_agent, self.config, self.descriptor)
+ reactor.callLater(0, self.device_handlers[device.id].activate, device)
def reconcile_device(self, device):
raise NotImplementedError()
def abandon_device(self, device):
- self._abandon(device.mac_address)
+ self.stop()
def disable_device(self, device):
raise NotImplementedError()
@@ -123,52 +150,6 @@
def reboot_device(self, device):
raise NotImplementedError()
- def download_image(self, device, request):
- raise NotImplementedError()
-
- def get_image_download_status(self, device, request):
- raise NotImplementedError()
-
- def cancel_image_download(self, device, request):
- raise NotImplementedError()
-
- def activate_image_update(self, device, request):
- raise NotImplementedError()
-
- def revert_image_update(self, device, request):
- raise NotImplementedError()
-
- def self_test_device(self, device):
- """
- This is called to Self a device based on a NBI call.
- :param device: A Voltha.Device object.
- :return: Will return result of self test
- """
- log.info('self-test-device', device=device.id)
- raise NotImplementedError()
-
- def delete_device(self, device):
- raise NotImplementedError()
-
- def get_device_details(self, device):
- raise NotImplementedError()
-
- def update_flows_bulk(self, device, flows, groups):
- log.debug('bulk-flow-update', device_id=device.id,
- flows=flows, groups=groups)
-
- def create_interface(self, device, data):
- raise NotImplementedError()
-
- def update_interface(self, device, data):
- raise NotImplementedError()
-
- def remove_interface(self, device, data):
- raise NotImplementedError()
-
- def receive_onu_detect_state(self, device_id, state):
- raise NotImplementedError()
-
def create_tcont(self, device, tcont_data, traffic_descriptor_data):
raise NotImplementedError()
@@ -205,39 +186,72 @@
def remove_multicast_distribution_set(self, device, data):
raise NotImplementedError()
+ def download_image(self, device, request):
+ raise NotImplementedError()
+
+ def get_image_download_status(self, device, request):
+ raise NotImplementedError()
+
+ def cancel_image_download(self, device, request):
+ raise NotImplementedError()
+
+ def activate_image_update(self, device, request):
+ raise NotImplementedError()
+
+ def revert_image_update(self, device, request):
+ raise NotImplementedError()
+
+ def self_test_device(self, device):
+ log.debug('self-test-device', device=device.id)
+ raise NotImplementedError()
+
+ def delete_device(self, device):
+ raise NotImplementedError()
+
+ def get_device_details(self, device):
+ raise NotImplementedError()
+
+ def update_flows_bulk(self, device, flows, groups):
+ try:
+ log.debug('olt-bulk-flow-update', device_id=device.id,
+ flows=flows, groups=groups)
+
+ handler = self.device_handlers[device.id]
+ if handler:
+ handler.update_flow_table(device, flows)
+ else:
+ log.debug("No handler found for device {}".format(device.id))
+
+ except Exception as e:
+ log.exception('failed-olt-bulk-flow-update', e=e)
+
+
+ def create_interface(self, device, data):
+ raise NotImplementedError()
+
+ def update_interface(self, device, data):
+ raise NotImplementedError()
+
+ def remove_interface(self, device, data):
+ raise NotImplementedError()
+
+ def receive_onu_detect_state(self, device_id, state):
+ raise NotImplementedError()
+
def send_proxied_message(self, proxy_address, msg):
+ log.debug("send-proxied-message-olt", proxy_address=proxy_address)
device = self.adaptor_agent.get_device(proxy_address.device_id)
- _, _, comm = self.olts[device.mac_address]
- if isinstance(msg, OmciFrame):
- log.info('send-omci-proxied-message', proxy_address=proxy_address, device=device)
- # TODO make this more efficient
- omci_proxy = OMCIProxy(proxy_address=proxy_address,
- msg=msg,
- adapter_agent=self.adaptor_agent,
- target=device.mac_address,
- comm=comm,
- iface=self.interface)
- omci_proxy.runbg()
-
-
- else:
- log.info('send-proxied-message', proxy_address=proxy_address)
- api_proxy = APIProxy(proxy_address=proxy_address,
- msg=msg,
- adapter_agent=self.adaptor_agent,
- target=device.mac_address,
- comm=comm,
- iface=self.interface)
- api_proxy.runbg()
+ self.device_handlers[device.id].send_proxied_message(proxy_address, msg)
def receive_proxied_message(self, proxy_address, msg):
+ log.debug("receive-proxied-message-olt-handler", proxy_address=proxy_address)
raise NotImplementedError()
def update_flows_incrementally(self, device, flow_changes, group_changes):
raise NotImplementedError()
def receive_packet_out(self, logical_device_id, egress_port_no, msg):
- log.info('packet-out', logical_device_id=logical_device_id,
+ log.debug('packet-out', logical_device_id=logical_device_id,
egress_port_no=egress_port_no, msg_len=len(msg))
def receive_inter_adapter_message(self, msg):
@@ -249,21 +263,289 @@
def unsuppress_alarm(self, filter):
raise NotImplementedError()
- ##
- # Private methods
- ##
- def _init_olt(self, olt, activation_watch):
+class RubyAdapterHandler(object):
+
+ name = "microsemi_olt"
+
+ supported_device_types = [
+ DeviceType(
+ id=name,
+ adapter=name,
+ accepts_bulk_flow_update=True
+ )
+ ]
+
+ def __init__(self, adaptor_agent, config, descriptor):
+ self.adaptor_agent = adaptor_agent
+ self.config = config
+ self.descriptor = descriptor
+ self.device = None
+ self.device_manager = None
+ self.comm = None
+ self.activation = None
+ self.olt = None
+ self.ports = dict()
+ self.last_iteration_ports = []
+ self.interface = registry('main').get_args().interface
+
+ def stop(self):
+ log.debug('stopping')
+ self._abandon(self.target)
+ log.info('stopped')
+ return self
+
+ def activate(self, device):
+ log.debug('activate-device', device=device)
+ self.device = device
+ self.device_manager = DeviceManager(device, self.adaptor_agent)
+ self.target = device.mac_address
+ self.comm = PAS5211Communication(dst_mac=self.target, iface=self.interface)
+
+ olt = OltStateMachine(iface=self.interface, comm=self.comm,
+ target=self.target, device=self.device_manager)
+ activation = ActivationWatcher(iface=self.interface, comm=self.comm,
+ target=self.target, device=self.device_manager, olt_adapter=self)
olt.runbg()
- activation_watch.runbg()
+ activation.runbg()
+
+ self.olt = olt
+
+ def abandon_device(self, device):
+ self._abandon(self.target)
+
+ def get_port_list(self, flows):
+ port_list = []
+ for flow in flows:
+ _in_port = fd.get_in_port(flow)
+ if _in_port not in (0, PMC_UPSTREAM_PORT):
+ if _in_port not in port_list:
+ port_list.append(_in_port)
+ log.debug('field-type-in-port', in_port=_in_port, port_list=port_list)
+ return port_list
+
+ def get_svlan(self, port, flows):
+ svlan_id = None
+ for flow in flows:
+ _in_port = fd.get_in_port(flow)
+ if _in_port == PMC_UPSTREAM_PORT:
+ log.debug('svlan-port-match')
+ metadata = fd.get_metadata(flow)
+ if metadata:
+ if metadata == port:
+ svlan_id = self.get_vlan(flow) & 0xfff
+ log.debug('SVLAN found:{}'.format(svlan_id))
+
+ return svlan_id
+
+ def get_cvlan(self, svlan_id, port, flows):
+ cvlan_id = None
+ # Look for cvlan ...
+ for flow in flows:
+ _in_port = fd.get_in_port(flow)
+ if _in_port == port:
+ log.debug('cvlan-port-match')
+ for action in fd.get_actions(flow):
+ if action.type == fd.SET_FIELD:
+ vlan = action.set_field.field.ofb_field.vlan_vid & 0xfff
+ if vlan == svlan_id:
+ cvlan_id = self.get_vlan(flow) & 0xfff
+ log.debug('CVLAN found:{}'.format(cvlan_id))
+ return cvlan_id
+
+ def get_uplink_bandwidth(self, cvlan_id, svlan_id, port, flows):
+ bandwidth = None
+ # Look for cvlan ...
+ for flow in flows:
+ _in_port = fd.get_in_port(flow)
+ if _in_port == port:
+ log.debug('uplink-bandwidth-port-match')
+ for action in fd.get_actions(flow):
+ if action.type == fd.SET_FIELD:
+ vlan = action.set_field.field.ofb_field.vlan_vid & 0xfff
+ if vlan == svlan_id:
+ bandwidth = fd.get_metadata(flow)
+ if bandwidth:
+ log.debug('Bandwidth found:{}'.format(bandwidth))
+ return bandwidth
+
+ def get_downlink_bandwidth(self, cvlan_id, svlan_id, port, flows):
+ bandwidth = None
+ for flow in flows:
+ _in_port = fd.get_in_port(flow)
+ if _in_port == PMC_UPSTREAM_PORT:
+ log.debug('downlink-bandwidth-port-match')
+ if flow.table_id == 1:
+ metadata = fd.get_metadata(flow)
+ if metadata:
+ if metadata == port:
+ vlan = self.get_vlan(flow) & 0xfff
+ if vlan == cvlan_id:
+ bandwidth = fd.get_metadata(flow)
+ log.debug('Bandwidth found:{}'.format(bandwidth))
+ return bandwidth
+
+ def update_flow_table(self, device, flows):
+ try:
+ cvlan_id = None
+ svlan_id = None
+
+ log.debug('olt-update-flow-table', device_id=device.id, flows=flows)
+ # Look for in ports mentioned in flows received ...
+ port_list = self.get_port_list(flows.items)
+
+ new_ports = set(port_list)-set(self.last_iteration_ports)
+ log.debug("new-ports", new_ports=new_ports)
+
+ disconnected_ports = set(self.last_iteration_ports)-set(port_list)
+ log.debug("disconnected-ports", disconnected_ports=disconnected_ports)
+
+ # For those new ports, check if we can proceed with flow installation...
+ for port in new_ports:
+ # Got svlan for that port ...
+ svlan_id = self.get_svlan(port, flows.items)
+
+ # ... look for the corresponding cvlan...
+ if svlan_id:
+ cvlan_id = self.get_cvlan(svlan_id, port, flows.items)
+
+ # Both vlan found!
+ if svlan_id and cvlan_id:
+
+ # Get bandwidths from flow info...
+ uplink_bandwidth = self.get_uplink_bandwidth(cvlan_id, svlan_id, port, flows.items)
+ if uplink_bandwidth == None:
+ uplink_bandwidth = SLA_be_bw_gros
+
+ downlink_bandwidth = self.get_downlink_bandwidth(cvlan_id, svlan_id, port, flows.items)
+ if downlink_bandwidth == None:
+ downlink_bandwidth = SLA_be_bw_gros
+
+ onu_id = self.ports[port]['onu_id']
+ onu_session_id = self.ports[port]['onu_session_id']
+ port_id = 1000 + 16 * onu_id
+ alloc_id = port_id
+ channel_id= port / 32
+
+ # Check if flow is already installed, if so, continue with next port
+ if self.ports[port].get('cvlan') and self.ports[port].get('svlan'):
+ if self.ports[port].get('svlan') == svlan_id:
+ # Flow already installed
+ if self.ports[port].get('cvlan') == cvlan_id:
+ continue
+ # We have new VLANs so we reinstall!
+ else:
+ self.reinstall_flows_sequence(device, onu_id, svlan_id, cvlan_id, port_id,
+ alloc_id, onu_session_id, channel_id, uplink_bandwidth, downlink_bandwidth)
+ else:
+ # New installation...
+ self.install_flows_sequence(device, onu_id, svlan_id, cvlan_id, port_id,
+ alloc_id, onu_session_id, channel_id, uplink_bandwidth, downlink_bandwidth)
+ else:
+ # New installation...
+ self.install_flows_sequence(device, onu_id, svlan_id, cvlan_id, port_id,
+ alloc_id, onu_session_id, channel_id, uplink_bandwidth, downlink_bandwidth)
+
+ self.ports[port]['svlan'] = svlan_id
+ self.ports[port]['cvlan'] = cvlan_id
+
+ else:
+ # Finally, it is an incomplete port, so we remove from port list
+ port_list.remove(port)
+
+ # For those ports without flows, uninstall them
+ for port in disconnected_ports:
+
+ onu_id = self.ports[port]['onu_id']
+ onu_session_id = self.ports[port]['onu_session_id']
+ port_id = 1000 + 16 * onu_id
+ alloc_id = port_id
+ channel_id= port / 32
+
+ if self.ports[port].get('cvlan') and self.ports[port].get('svlan'):
+ self.uninstall_flows_sequence(device, onu_id, port_id, alloc_id, onu_session_id,
+ channel_id)
+ self.ports[port]['svlan'] = None
+ self.ports[port]['cvlan'] = None
+
+ self.last_iteration_ports = port_list
+
+ except Exception as e:
+ log.exception('failed-to-olt-update-flow-table', e=e)
+
+ def get_vlan(self, flow):
+ for field in fd.get_ofb_fields(flow):
+ if field.type == fd.VLAN_VID:
+ return field.vlan_vid
+ return None
+
+ def reinstall_flows_sequence(self, device, onu_id, svlan, cvlan, port_id,
+ alloc_id, onu_session_id, channel_id, uplink_bandwidth, downlink_bandwidth):
+ log.debug('init-flow-reinstallaton')
+ try:
+ olt = OltReinstallFlowStateMachine(iface=self.interface, comm=self.comm,
+ target=self.target, device=self.device_manager, onu_id=onu_id,
+ channel_id=channel_id, port_id=port_id, onu_session_id=onu_session_id,
+ alloc_id=alloc_id, svlan_id=svlan, cvlan_id=cvlan,
+ uplink_bandwidth=uplink_bandwidth, downlink_bandwidth=downlink_bandwidth)
+ olt.runbg()
+ except Exception as e:
+ log.exception('failed-to-launch-reinstall-flow', e=e)
+
+ def install_flows_sequence(self, device, onu_id, svlan, cvlan, port_id,
+ alloc_id, onu_session_id, channel_id, uplink_bandwidth, downlink_bandwidth):
+ log.debug('init-flow-installaton')
+ try:
+ olt = OltInstallFlowStateMachine(iface=self.interface, comm=self.comm,
+ target=self.target, device=self.device_manager, onu_id=onu_id,
+ channel_id=channel_id, port_id=port_id, onu_session_id=onu_session_id,
+ alloc_id=alloc_id, svlan_id=svlan, cvlan_id=cvlan,
+ uplink_bandwidth=uplink_bandwidth, downlink_bandwidth=downlink_bandwidth)
+ olt.runbg()
+ except Exception as e:
+ log.exception('failed-to-launch-install-flow', e=e)
+
+ def uninstall_flows_sequence(self, device, onu_id, port_id, alloc_id, onu_session_id,
+ channel_id):
+ log.debug('init-flow-deinstallaton')
+ try:
+ olt = OltRemoveFlowStateMachine(iface=self.interface, comm=self.comm,
+ target=self.target, device=self.device_manager, onu_id=onu_id,
+ channel_id=channel_id, port_id=port_id, onu_session_id=onu_session_id,
+ alloc_id=alloc_id)
+ olt.runbg()
+ except Exception as e:
+ log.exception('failed-to-launch-deinstallaton-flow', e=e)
def _abandon(self, target):
- olt, activation, _ = self.olts[target]
- olt.stop()
- activation.stop()
- del self.olts[target]
+ self.olt.stop()
+ self.activation.stop()
+ # Method exposed to Activation Watcher to get onu info from Activation
+ def add_onu_info(self, port, onu_id, onu_session_id):
+ existing_port = self.ports.get(port)
+ if existing_port:
+ existing_port['onu_id'] = onu_id
+ existing_port['onu_session_id'] = onu_session_id
+ else:
+ self.ports[port] = {'onu_id': onu_id, 'onu_session_id': onu_session_id}
+ def send_proxied_message(self, proxy_address, msg):
+ log.debug("send-proxied-message-olt-handler", proxy_address=proxy_address)
+ if isinstance(msg, OmciFrame):
+ omci_proxy = OMCIProxy(proxy_address=proxy_address,
+ msg=msg,
+ adapter_agent=self.adaptor_agent,
+ target=self.device.mac_address,
+ comm=self.comm,
+ iface=self.interface)
+ omci_proxy.runbg()
-
-
+ else:
+ api_proxy = APIProxy(proxy_address=proxy_address,
+ msg=msg,
+ adapter_agent=self.adaptor_agent,
+ target=self.device.mac_address,
+ comm=self.comm,
+ iface=self.interface)
+ api_proxy.runbg()
\ No newline at end of file