blob: b0fe3d807044fa55ab3bfd772076d560998cfa17 [file] [log] [blame]
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -05001#
2# Copyright 2018 the original author or authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050016from twisted.internet import reactor
17from twisted.internet.defer import inlineCallbacks, returnValue, TimeoutError, failure
Matt Jeanneret2e3cb8d2019-11-16 09:22:41 -050018from pyvoltha.adapters.extensions.omci.omci_me import PptpEthernetUniFrame, GalEthernetProfileFrame, \
19 MacBridgePortConfigurationDataFrame, MacBridgeServiceProfileFrame, Ieee8021pMapperServiceProfileFrame, \
20 VeipUniFrame, ExtendedVlanTaggingOperationConfigurationDataFrame
Matt Jeanneret72f96fc2019-02-11 10:53:05 -050021from pyvoltha.adapters.extensions.omci.tasks.task import Task
Matt Jeanneret2e3cb8d2019-11-16 09:22:41 -050022from pyvoltha.adapters.extensions.omci.omci_defs import EntityOperations, ReasonCodes
23from uni_port import UniType
24from pon_port \
Matt Jeanneret810148b2019-09-29 12:44:01 -040025 import TASK_PRIORITY, DEFAULT_TPID, DEFAULT_GEM_PAYLOAD
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050026
27OP = EntityOperations
28RC = ReasonCodes
29
30
31class MibDownloadFailure(Exception):
32 """
33 This error is raised by default when the download fails
34 """
35
36
37class MibResourcesFailure(Exception):
38 """
39 This error is raised by when one or more resources required is not available
40 """
41
42
43class BrcmMibDownloadTask(Task):
44 """
Matt Jeanneret810148b2019-09-29 12:44:01 -040045 OpenOMCI MIB Download Bridge Setup Task
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050046
47 This task takes the legacy OMCI 'script' for provisioning the Broadcom ONU
48 and converts it to run as a Task on the OpenOMCI Task runner. This is
49 in order to begin to decompose service instantiation in preparation for
50 Technology Profile work.
51
52 Once technology profiles are ready, some of this task may hang around or
53 be moved into OpenOMCI if there are any very common settings/configs to do
54 for any profile that may be provided in the v2.0 release
55
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050056 """
57
Matt Jeanneret810148b2019-09-29 12:44:01 -040058 name = "Broadcom MIB Download Bridge Setup Task"
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050059
60 def __init__(self, omci_agent, handler):
61 """
62 Class initialization
63
64 :param omci_agent: (OmciAdapterAgent) OMCI Adapter agent
65 :param device_id: (str) ONU Device ID
66 """
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050067 super(BrcmMibDownloadTask, self).__init__(BrcmMibDownloadTask.name,
68 omci_agent,
69 handler.device_id,
70 priority=TASK_PRIORITY)
71 self._handler = handler
72 self._onu_device = omci_agent.get_device(handler.device_id)
73 self._local_deferred = None
74
75 # Frame size
76 self._max_gem_payload = DEFAULT_GEM_PAYLOAD
77
78 self._pon = handler.pon_port
79
80 # Defaults
81 self._input_tpid = DEFAULT_TPID
82 self._output_tpid = DEFAULT_TPID
83
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050084 # Entity IDs. IDs with values can probably be most anything for most ONUs,
85 # IDs set to None are discovered/set
86
87 self._mac_bridge_service_profile_entity_id = \
88 self._handler.mac_bridge_service_profile_entity_id
89 self._ieee_mapper_service_profile_entity_id = \
90 self._pon.ieee_mapper_service_profile_entity_id
91 self._mac_bridge_port_ani_entity_id = \
92 self._pon.mac_bridge_port_ani_entity_id
93 self._gal_enet_profile_entity_id = \
94 self._handler.gal_enet_profile_entity_id
95
96 self._free_ul_prior_q_entity_ids = set()
97 self._free_dl_prior_q_entity_ids = set()
98
99 def cancel_deferred(self):
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500100 super(BrcmMibDownloadTask, self).cancel_deferred()
101
102 d, self._local_deferred = self._local_deferred, None
103 try:
104 if d is not None and not d.called:
105 d.cancel()
106 except:
107 pass
108
109 def start(self):
110 """
111 Start the MIB Download
112 """
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500113 super(BrcmMibDownloadTask, self).start()
114 self._local_deferred = reactor.callLater(0, self.perform_mib_download)
115
116 def stop(self):
117 """
118 Shutdown MIB Synchronization tasks
119 """
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500120 self.cancel_deferred()
121 super(BrcmMibDownloadTask, self).stop()
122
123 def check_status_and_state(self, results, operation=''):
124 """
125 Check the results of an OMCI response. An exception is thrown
126 if the task was cancelled or an error was detected.
127
128 :param results: (OmciFrame) OMCI Response frame
129 :param operation: (str) what operation was being performed
130 :return: True if successful, False if the entity existed (already created)
131 """
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500132
133 omci_msg = results.fields['omci_message'].fields
134 status = omci_msg['success_code']
135 error_mask = omci_msg.get('parameter_error_attributes_mask', 'n/a')
136 failed_mask = omci_msg.get('failed_attributes_mask', 'n/a')
137 unsupported_mask = omci_msg.get('unsupported_attributes_mask', 'n/a')
138
Matt Jeannerete8fc53e2019-04-13 15:58:33 -0400139 self.log.debug("OMCI Result", operation=operation,
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500140 omci_msg=omci_msg, status=status,
141 error_mask=error_mask, failed_mask=failed_mask,
142 unsupported_mask=unsupported_mask)
143
144 if status == RC.Success:
145 self.strobe_watchdog()
146 return True
147
148 elif status == RC.InstanceExists:
149 return False
150
151 raise MibDownloadFailure('{} failed with a status of {}, error_mask: {}, failed_mask: {}, unsupported_mask: {}'
152 .format(operation, status, error_mask, failed_mask, unsupported_mask))
153
154 @inlineCallbacks
155 def perform_mib_download(self):
156 """
157 Send the commands to minimally configure the PON, Bridge, and
158 UNI ports for this device. The application of any service flows
159 and other characteristics are done as needed.
160 """
161 try:
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500162 self.log.info('perform-download')
163
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500164 if self._handler.enabled and len(self._handler.uni_ports) > 0:
Mahir Gunyel0e6882a2019-10-16 17:02:39 -0700165 yield self._handler.core_proxy.device_reason_update(self.device_id, 'performing-initial-mib-download')
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500166
167 try:
168 # Lock the UNI ports to prevent any alarms during initial configuration
169 # of the ONU
170 self.strobe_watchdog()
171
172 # Provision the initial bridge configuration
173 yield self.perform_initial_bridge_setup()
174
175 for uni_port in self._handler.uni_ports:
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500176 # Provision the initial bridge configuration
177 yield self.perform_uni_initial_bridge_setup(uni_port)
178
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500179 self.deferred.callback('initial-download-success')
180
181 except TimeoutError as e:
182 self.log.error('initial-download-failure', e=e)
183 self.deferred.errback(failure.Failure(e))
184
185 except Exception as e:
186 self.log.exception('initial-download-failure', e=e)
187 self.deferred.errback(failure.Failure(e))
188
189 else:
190 e = MibResourcesFailure('Required resources are not available',
191 len(self._handler.uni_ports))
192 self.deferred.errback(failure.Failure(e))
193 except BaseException as e:
Matt Jeanneret810148b2019-09-29 12:44:01 -0400194 self.log.debug('cannot-start-mib-download', exception=e)
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500195
196 @inlineCallbacks
197 def perform_initial_bridge_setup(self):
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500198
199 omci_cc = self._onu_device.omci_cc
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500200 try:
201 ########################################################################################
202 # Create GalEthernetProfile - Once per ONU/PON interface
203 #
204 # EntityID will be referenced by:
205 # - GemInterworkingTp
206 # References:
207 # - Nothing
208
209 msg = GalEthernetProfileFrame(
210 self._gal_enet_profile_entity_id,
211 max_gem_payload_size=self._max_gem_payload
212 )
213 frame = msg.create()
214 self.log.debug('openomci-msg', omci_msg=msg)
215 results = yield omci_cc.send(frame)
216 self.check_status_and_state(results, 'create-gal-ethernet-profile')
217
218 except TimeoutError as e:
Matt Jeanneret810148b2019-09-29 12:44:01 -0400219 self.log.warn('rx-timeout-initial-gal-profile', e=e)
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500220 raise
221
222 except Exception as e:
Matt Jeanneret810148b2019-09-29 12:44:01 -0400223 self.log.exception('omci-setup-initial-gal-profile', e=e)
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500224 raise
225
226 returnValue(None)
227
228 @inlineCallbacks
229 def perform_uni_initial_bridge_setup(self, uni_port):
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500230 omci_cc = self._onu_device.omci_cc
231 frame = None
232 try:
233 ################################################################################
234 # Common - PON and/or UNI #
235 ################################################################################
236 # MAC Bridge Service Profile
237 #
238 # EntityID will be referenced by:
239 # - MAC Bridge Port Configuration Data (PON & UNI)
240 # References:
241 # - Nothing
242
243 # TODO: magic. event if static, assign to a meaningful variable name
244 attributes = {
245 'spanning_tree_ind': False,
246 'learning_ind': True,
247 'priority': 0x8000,
248 'max_age': 20 * 256,
249 'hello_time': 2 * 256,
250 'forward_delay': 15 * 256,
251 'unknown_mac_address_discard': True
252 }
253 msg = MacBridgeServiceProfileFrame(
254 self._mac_bridge_service_profile_entity_id + uni_port.mac_bridge_port_num,
255 attributes
256 )
257 frame = msg.create()
258 self.log.debug('openomci-msg', omci_msg=msg)
259 results = yield omci_cc.send(frame)
260 self.check_status_and_state(results, 'create-mac-bridge-service-profile')
261
262 ################################################################################
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500263 # UNI Specific #
264 ################################################################################
265 # MAC Bridge Port config
266 # This configuration is for Ethernet UNI
267 #
268 # EntityID will be referenced by:
269 # - Nothing
270 # References:
271 # - MAC Bridge Service Profile (the bridge)
272 # - PPTP Ethernet or VEIP UNI
273
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500274 # default to PPTP
Matt Jeanneret31509ec2019-12-20 14:57:53 -0500275 tp_type = 1
Matt Jeanneretaf7cd6b2019-04-05 15:37:34 -0400276 if uni_port.type.value == UniType.VEIP.value:
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500277 tp_type = 11
Matt Jeanneretaf7cd6b2019-04-05 15:37:34 -0400278 elif uni_port.type.value == UniType.PPTP.value:
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500279 tp_type = 1
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500280
281 msg = MacBridgePortConfigurationDataFrame(
Matt Jeanneret2e5c6f12019-12-13 07:06:06 -0500282 self._mac_bridge_port_ani_entity_id + uni_port.entity_id, # Entity ID
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500283 bridge_id_pointer=self._mac_bridge_service_profile_entity_id + uni_port.mac_bridge_port_num, # Bridge Entity ID
284 port_num=uni_port.mac_bridge_port_num, # Port ID
285 tp_type=tp_type, # PPTP Ethernet or VEIP UNI
286 tp_pointer=uni_port.entity_id # Ethernet UNI ID
287 )
288 frame = msg.create()
289 self.log.debug('openomci-msg', omci_msg=msg)
290 results = yield omci_cc.send(frame)
Matt Jeanneret810148b2019-09-29 12:44:01 -0400291 self.check_status_and_state(results, 'create-mac-bridge-port-configuration-data-uni-port')
292
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500293 except TimeoutError as e:
Matt Jeanneret810148b2019-09-29 12:44:01 -0400294 self.log.warn('rx-timeout-inital-per-uni-setup', e=e)
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500295 raise
296
297 except Exception as e:
Matt Jeanneret810148b2019-09-29 12:44:01 -0400298 self.log.exception('omci-setup-initial-per-uni-setup', e=e)
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500299 raise
300
301 returnValue(None)