blob: ff70e5088e405fbb4010eb094a7f62945fa6a27b [file] [log] [blame]
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -05001#
2# Copyright 2017 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#
16
17"""
18Broadcom OpenOMCI OLT/ONU adapter.
19
20This adapter does NOT support XPON
21"""
22
23from twisted.internet import reactor, task
William Kurkian3a206332019-04-29 11:05:47 -040024from twisted.internet.defer import inlineCallbacks
25
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050026from zope.interface import implementer
27
Matt Jeanneret72f96fc2019-02-11 10:53:05 -050028from pyvoltha.adapters.interface import IAdapterInterface
Matt Jeanneret21363202019-02-13 16:21:48 -050029from pyvoltha.adapters.iadapter import OnuAdapter
William Kurkian8235c1e2019-03-05 12:58:28 -050030from voltha_protos.adapter_pb2 import Adapter
31from voltha_protos.adapter_pb2 import AdapterConfig
32from voltha_protos.common_pb2 import LogLevel
33from voltha_protos.device_pb2 import DeviceType, DeviceTypes, Port, Image
34from voltha_protos.health_pb2 import HealthStatus
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050035
Matt Jeanneret72f96fc2019-02-11 10:53:05 -050036from pyvoltha.adapters.common.frameio.frameio import hexify
37from pyvoltha.adapters.extensions.omci.openomci_agent import OpenOMCIAgent, OpenOmciAgentDefaults
38from pyvoltha.adapters.extensions.omci.omci_me import *
39
40from brcm_openomci_onu_handler import BrcmOpenomciOnuHandler
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050041from omci.brcm_capabilities_task import BrcmCapabilitiesTask
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050042from omci.brcm_mib_sync import BrcmMibSynchronizer
43from copy import deepcopy
44
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050045log = structlog.get_logger()
46
47
48@implementer(IAdapterInterface)
49class BrcmOpenomciOnuAdapter(object):
50
51 name = 'brcm_openomci_onu'
52
53 supported_device_types = [
54 DeviceType(
55 id=name,
56 vendor_ids=['OPEN', 'ALCL', 'BRCM', 'TWSH', 'ALPH', 'ISKT', 'SFAA', 'BBSM'],
57 adapter=name,
58 accepts_bulk_flow_update=True
59 )
60 ]
61
Matt Jeanneret21363202019-02-13 16:21:48 -050062 def __init__(self, core_proxy, adapter_proxy, config):
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050063 log.debug('function-entry', config=config)
Matt Jeannereta32441c2019-03-07 05:16:37 -050064 self.core_proxy = core_proxy
Matt Jeanneret0bd63c82019-02-15 05:40:44 -050065 self.adapter_proxy = adapter_proxy
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050066 self.config = config
67 self.descriptor = Adapter(
68 id=self.name,
69 vendor='Voltha project',
Matt Jeanneret21363202019-02-13 16:21:48 -050070 version='2.0',
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050071 config=AdapterConfig(log_level=LogLevel.INFO)
72 )
73 self.devices_handlers = dict()
Matt Jeanneret21363202019-02-13 16:21:48 -050074 self.device_handler_class = BrcmOpenomciOnuHandler
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050075
76 # Customize OpenOMCI for Broadcom ONUs
77 self.broadcom_omci = deepcopy(OpenOmciAgentDefaults)
78
79 self.broadcom_omci['mib-synchronizer']['state-machine'] = BrcmMibSynchronizer
80 self.broadcom_omci['omci-capabilities']['tasks']['get-capabilities'] = BrcmCapabilitiesTask
81
82 # Defer creation of omci agent to a lazy init that allows subclasses to override support classes
83
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050084 def custom_me_entities(self):
85 return None
86
87 @property
88 def omci_agent(self):
89 if not hasattr(self, '_omci_agent') or self._omci_agent is None:
90 log.debug('creating-omci-agent')
Matt Jeannereta32441c2019-03-07 05:16:37 -050091 self._omci_agent = OpenOMCIAgent(self.core_proxy,
92 self.adapter_proxy,
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050093 support_classes=self.broadcom_omci)
94 return self._omci_agent
95
96 def start(self):
97 log.debug('starting')
98 self.omci_agent.start()
99 log.info('started')
100
101 def stop(self):
102 log.debug('stopping')
103
104 omci, self._omci_agent = self._omci_agent, None
105 if omci is not None:
106 self._omci_agent.stop()
107
108 log.info('stopped')
109
110 def adapter_descriptor(self):
111 return self.descriptor
112
113 def device_types(self):
114 return DeviceTypes(items=self.supported_device_types)
115
116 def health(self):
117 return HealthStatus(state=HealthStatus.HealthState.HEALTHY)
118
119 def change_master_state(self, master):
120 raise NotImplementedError()
121
122 def adopt_device(self, device):
123 log.info('adopt_device', device_id=device.id)
124 self.devices_handlers[device.id] = BrcmOpenomciOnuHandler(self, device.id)
125 reactor.callLater(0, self.devices_handlers[device.id].activate, device)
126 return device
127
128 def reconcile_device(self, device):
129 log.info('reconcile-device', device_id=device.id)
130 self.devices_handlers[device.id] = BrcmOpenomciOnuHandler(self, device.id)
131 reactor.callLater(0, self.devices_handlers[device.id].reconcile, device)
132
133 def abandon_device(self, device):
134 raise NotImplementedError()
135
136 def disable_device(self, device):
137 log.info('disable-onu-device', device_id=device.id)
138 if device.id in self.devices_handlers:
139 handler = self.devices_handlers[device.id]
140 if handler is not None:
141 handler.disable(device)
142
143 def reenable_device(self, device):
144 log.info('reenable-onu-device', device_id=device.id)
145 if device.id in self.devices_handlers:
146 handler = self.devices_handlers[device.id]
147 if handler is not None:
148 handler.reenable(device)
149
150 def reboot_device(self, device):
151 log.info('reboot-device', device_id=device.id)
152 if device.id in self.devices_handlers:
153 handler = self.devices_handlers[device.id]
154 if handler is not None:
155 handler.reboot()
156
157 def download_image(self, device, request):
158 raise NotImplementedError()
159
160 def get_image_download_status(self, device, request):
161 raise NotImplementedError()
162
163 def cancel_image_download(self, device, request):
164 raise NotImplementedError()
165
166 def activate_image_update(self, device, request):
167 raise NotImplementedError()
168
169 def revert_image_update(self, device, request):
170 raise NotImplementedError()
171
172 def self_test_device(self, device):
173 """
174 This is called to Self a device based on a NBI call.
175 :param device: A Voltha.Device object.
176 :return: Will return result of self test
177 """
178 log.info('self-test-device - Not implemented yet', device=device.id)
179 raise NotImplementedError()
180
181 def delete_device(self, device):
182 log.info('delete-device', device_id=device.id)
183 if device.id in self.devices_handlers:
184 handler = self.devices_handlers[device.id]
185 if handler is not None:
186 handler.delete(device)
187 del self.devices_handlers[device.id]
188 return
189
190 def get_device_details(self, device):
191 raise NotImplementedError()
192
193 # TODO(smbaker): When BrcmOpenomciOnuAdapter is updated to inherit from OnuAdapter, this function can be deleted
194 def update_pm_config(self, device, pm_config):
195 log.info("adapter-update-pm-config", device=device,
196 pm_config=pm_config)
197 handler = self.devices_handlers[device.id]
198 handler.update_pm_config(device, pm_config)
199
200 def update_flows_bulk(self, device, flows, groups):
201 '''
202 log.info('bulk-flow-update', device_id=device.id,
203 flows=flows, groups=groups)
204 '''
205 assert len(groups.items) == 0
206 handler = self.devices_handlers[device.id]
207 return handler.update_flow_table(device, flows.items)
208
209 def update_flows_incrementally(self, device, flow_changes, group_changes):
210 raise NotImplementedError()
211
212 def send_proxied_message(self, proxy_address, msg):
213 log.debug('send-proxied-message', proxy_address=proxy_address, msg=msg)
214
William Kurkian3a206332019-04-29 11:05:47 -0400215 @inlineCallbacks
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500216 def receive_proxied_message(self, proxy_address, msg):
217 log.debug('receive-proxied-message', proxy_address=proxy_address,
218 device_id=proxy_address.device_id, msg=hexify(msg))
219 # Device_id from the proxy_address is the olt device id. We need to
220 # get the onu device id using the port number in the proxy_address
William Kurkian3a206332019-04-29 11:05:47 -0400221 device = self.core_proxy. \
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500222 get_child_device_with_proxy_address(proxy_address)
223 if device:
224 handler = self.devices_handlers[device.id]
225 handler.receive_message(msg)
226
227 def receive_packet_out(self, logical_device_id, egress_port_no, msg):
228 log.info('packet-out', logical_device_id=logical_device_id,
229 egress_port_no=egress_port_no, msg_len=len(msg))
230
William Kurkian3a206332019-04-29 11:05:47 -0400231 @inlineCallbacks
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500232 def receive_inter_adapter_message(self, msg):
233 log.debug('receive_inter_adapter_message', msg=msg)
234 proxy_address = msg['proxy_address']
235 assert proxy_address is not None
236 # Device_id from the proxy_address is the olt device id. We need to
237 # get the onu device id using the port number in the proxy_address
William Kurkian3a206332019-04-29 11:05:47 -0400238 device = self.core_proxy. \
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500239 get_child_device_with_proxy_address(proxy_address)
240 if device:
241 handler = self.devices_handlers[device.id]
242 handler.event_messages.put(msg)
243 else:
244 log.error("device-not-found")
245
Matt Jeanneretc083f462019-03-11 15:02:01 -0400246 def get_ofp_port_info(self, device, port_no):
247 ofp_port_info = self.devices_handlers[device.id].get_ofp_port_info(device, port_no)
248 log.debug('get_ofp_port_info', device_id=device.id, ofp_port_info=ofp_port_info)
249 return ofp_port_info
250
Matt Jeannereta32441c2019-03-07 05:16:37 -0500251 def process_inter_adapter_message(self, msg):
252 log.debug('process-inter-adapter-message', msg=msg)
253 # Unpack the header to know which device needs to handle this message
254 if msg.header:
255 handler = self.devices_handlers[msg.header.to_device_id]
256 handler.process_inter_adapter_message(msg)
257
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500258 def create_interface(self, device, data):
259 log.debug('create-interface', device_id=device.id)
260 if device.id in self.devices_handlers:
261 handler = self.devices_handlers[device.id]
262 if handler is not None:
263 handler.create_interface(data)
264
265 def update_interface(self, device, data):
266 log.debug('update-interface', device_id=device.id)
267 if device.id in self.devices_handlers:
268 handler = self.devices_handlers[device.id]
269 if handler is not None:
270 handler.update_interface(data)
271
272 def remove_interface(self, device, data):
273 log.debug('remove-interface', device_id=device.id)
274 if device.id in self.devices_handlers:
275 handler = self.devices_handlers[device.id]
276 if handler is not None:
277 handler.remove_interface(data)
278
279 def receive_onu_detect_state(self, device_id, state):
280 raise NotImplementedError()
281
282 def create_tcont(self, device, tcont_data, traffic_descriptor_data):
283 log.debug('create-tcont', device_id=device.id)
284 if device.id in self.devices_handlers:
285 handler = self.devices_handlers[device.id]
286 if handler is not None:
287 handler.create_tcont(tcont_data, traffic_descriptor_data)
288
289 def update_tcont(self, device, tcont_data, traffic_descriptor_data):
290 raise NotImplementedError()
291
292 def remove_tcont(self, device, tcont_data, traffic_descriptor_data):
293 log.debug('remove-tcont', device_id=device.id)
294 if device.id in self.devices_handlers:
295 handler = self.devices_handlers[device.id]
296 if handler is not None:
297 handler.remove_tcont(tcont_data, traffic_descriptor_data)
298
299 def create_gemport(self, device, data):
300 log.debug('create-gemport', device_id=device.id)
301 if device.id in self.devices_handlers:
302 handler = self.devices_handlers[device.id]
303 if handler is not None:
304 handler.create_gemport(data)
305
306 def update_gemport(self, device, data):
307 raise NotImplementedError()
308
309 def remove_gemport(self, device, data):
310 log.debug('remove-gemport', device_id=device.id)
311 if device.id in self.devices_handlers:
312 handler = self.devices_handlers[device.id]
313 if handler is not None:
314 handler.remove_gemport(data)
315
316 def create_multicast_gemport(self, device, data):
317 log.debug('create-multicast-gemport', device_id=device.id)
318 if device.id in self.devices_handlers:
319 handler = self.devices_handlers[device.id]
320 if handler is not None:
321 handler.create_multicast_gemport(data)
322
323 def update_multicast_gemport(self, device, data):
324 raise NotImplementedError()
325
326 def remove_multicast_gemport(self, device, data):
327 raise NotImplementedError()
328
329 def create_multicast_distribution_set(self, device, data):
330 raise NotImplementedError()
331
332 def update_multicast_distribution_set(self, device, data):
333 raise NotImplementedError()
334
335 def remove_multicast_distribution_set(self, device, data):
336 raise NotImplementedError()
337
338 def suppress_alarm(self, filter):
339 raise NotImplementedError()
340
341 def unsuppress_alarm(self, filter):
342 raise NotImplementedError()
343
344