blob: 7ccec652b6879888d32ca8e21538438cc51a6708 [file] [log] [blame]
Shad Ansari2825d012018-02-22 23:57:46 +00001#
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#
16
17"""
18Openolt adapter.
19"""
Shad Ansari2825d012018-02-22 23:57:46 +000020from zope.interface import implementer
Shad Ansarif9d2d102018-06-13 02:15:26 +000021import structlog
Shad Ansari2825d012018-02-22 23:57:46 +000022
23from openolt_device import OpenoltDevice
24from voltha.adapters.interface import IAdapterInterface
25from voltha.protos import third_party
26from voltha.protos.adapter_pb2 import Adapter
27from voltha.protos.adapter_pb2 import AdapterConfig
28from voltha.protos.common_pb2 import LogLevel
Scott Bakerd3190952018-09-04 15:47:28 -070029from voltha.protos.common_pb2 import OperationResp
Shad Ansari2825d012018-02-22 23:57:46 +000030from voltha.protos.device_pb2 import DeviceType, DeviceTypes
Shad Ansari2825d012018-02-22 23:57:46 +000031from voltha.registry import registry
Shad Ansaricd20a6d2018-10-02 14:36:33 +000032from voltha.adapters.openolt.openolt_flow_mgr import OpenOltFlowMgr
33from voltha.adapters.openolt.openolt_alarms import OpenOltAlarmMgr
34from voltha.adapters.openolt.openolt_statistics import OpenOltStatisticsMgr
35from voltha.adapters.openolt.openolt_bw import OpenOltBW
36from voltha.adapters.openolt.openolt_platform import OpenOltPlatform
Shad Ansari2825d012018-02-22 23:57:46 +000037
38_ = third_party
39log = structlog.get_logger()
40
Shad Ansarif9d2d102018-06-13 02:15:26 +000041
Shad Ansaricd20a6d2018-10-02 14:36:33 +000042OpenOltDefaults = {
43 'support_classes': {
44 'platform': OpenOltPlatform,
45 'flow_mgr': OpenOltFlowMgr,
46 'alarm_mgr': OpenOltAlarmMgr,
47 'stats_mgr': OpenOltStatisticsMgr,
48 'bw_mgr': OpenOltBW
49 }
50}
51
Shad Ansari2825d012018-02-22 23:57:46 +000052@implementer(IAdapterInterface)
53class OpenoltAdapter(object):
54 name = 'openolt'
55
56 supported_device_types = [
57 DeviceType(
58 id=name,
59 adapter=name,
Nicolas Palpacuer0c7c3162018-08-08 11:27:57 -040060 accepts_bulk_flow_update=True,
61 accepts_direct_logical_flows_update=True
Shad Ansari2825d012018-02-22 23:57:46 +000062 )
63 ]
64
65 def __init__(self, adapter_agent, config):
66 self.adapter_agent = adapter_agent
67 self.config = config
68 self.descriptor = Adapter(
69 id=self.name,
70 vendor='OLT white box vendor',
71 version='0.1',
72 config=AdapterConfig(log_level=LogLevel.INFO)
73 )
74 log.debug('openolt.__init__', adapter_agent=adapter_agent)
75 self.devices = dict() # device_id -> OpenoltDevice()
76 self.interface = registry('main').get_args().interface
77 self.logical_device_id_to_root_device_id = dict()
Shad Ansari5dbc9c82018-05-10 03:29:31 +000078 self.num_devices = 0
Shad Ansari2825d012018-02-22 23:57:46 +000079
80 def start(self):
81 log.info('started', interface=self.interface)
82
83 def stop(self):
84 log.info('stopped', interface=self.interface)
85
86 def adapter_descriptor(self):
87 log.debug('get descriptor', interface=self.interface)
88 return self.descriptor
89
90 def device_types(self):
Shad Ansarif9d2d102018-06-13 02:15:26 +000091 log.debug('get device_types', interface=self.interface,
92 items=self.supported_device_types)
Shad Ansari2825d012018-02-22 23:57:46 +000093 return DeviceTypes(items=self.supported_device_types)
94
95 def health(self):
96 log.debug('get health', interface=self.interface)
97 raise NotImplementedError()
98
99 def change_master_state(self, master):
Shad Ansarif9d2d102018-06-13 02:15:26 +0000100 log.debug('change_master_state', interface=self.interface,
101 master=master)
Shad Ansari2825d012018-02-22 23:57:46 +0000102 raise NotImplementedError()
103
104 def adopt_device(self, device):
105 log.info('adopt-device', device=device)
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000106
Shad Ansari2825d012018-02-22 23:57:46 +0000107 kwargs = {
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000108 'support_classes': OpenOltDefaults['support_classes'],
Shad Ansari2825d012018-02-22 23:57:46 +0000109 'adapter_agent': self.adapter_agent,
Shad Ansari5dbc9c82018-05-10 03:29:31 +0000110 'device': device,
111 'device_num': self.num_devices + 1
Shad Ansari2825d012018-02-22 23:57:46 +0000112 }
113 try:
114 self.devices[device.id] = OpenoltDevice(**kwargs)
115 except Exception as e:
116 log.error('Failed to adopt OpenOLT device', error=e)
117 del self.devices[device.id]
118 raise
Shad Ansari5dbc9c82018-05-10 03:29:31 +0000119 else:
120 self.num_devices += 1
Shad Ansari2825d012018-02-22 23:57:46 +0000121
122 def reconcile_device(self, device):
123 log.info('reconcile-device', device=device)
Nicolas Palpacuer253461f2018-06-01 12:01:45 -0400124 kwargs = {
125 'adapter_agent': self.adapter_agent,
126 'device': device,
127 'device_num': self.num_devices + 1,
128 'reconciliation': True
129 }
130 try:
131 reconciled_device = OpenoltDevice(**kwargs)
Shad Ansarif9d2d102018-06-13 02:15:26 +0000132 log.debug('reconciled-device-recreated',
133 device_id=reconciled_device.device_id)
Nicolas Palpacuer253461f2018-06-01 12:01:45 -0400134 self.devices[device.id] = reconciled_device
135 except Exception as e:
Shad Ansarif9d2d102018-06-13 02:15:26 +0000136 log.error('Failed to reconcile OpenOLT device', error=e,
137 exception_type=type(e).__name__)
Nicolas Palpacuer253461f2018-06-01 12:01:45 -0400138 del self.devices[device.id]
139 raise
140 else:
141 self.num_devices += 1
142 # Invoke the children reconciliation which would setup the
143 # basic children data structures
144 self.adapter_agent.reconcile_child_devices(device.id)
145 return device
Shad Ansari2825d012018-02-22 23:57:46 +0000146
147 def abandon_device(self, device):
148 log.info('abandon-device', device=device)
149 raise NotImplementedError()
150
151 def disable_device(self, device):
152 log.info('disable-device', device=device)
Jonathan Davis0f917a22018-05-30 14:39:45 -0400153 handler = self.devices[device.id]
154 handler.disable()
Shad Ansari2825d012018-02-22 23:57:46 +0000155
156 def reenable_device(self, device):
157 log.info('reenable-device', device=device)
Jonathan Davis0f917a22018-05-30 14:39:45 -0400158 handler = self.devices[device.id]
159 handler.reenable()
Shad Ansari2825d012018-02-22 23:57:46 +0000160
161 def reboot_device(self, device):
162 log.info('reboot_device', device=device)
Nicolas Palpacuerfd365ac2018-08-02 11:37:37 -0400163 handler = self.devices[device.id]
164 handler.reboot()
Shad Ansari2825d012018-02-22 23:57:46 +0000165
166 def download_image(self, device, request):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400167 log.info('image_download - Not implemented yet', device=device,
168 request=request)
Shad Ansari2825d012018-02-22 23:57:46 +0000169 raise NotImplementedError()
170
171 def get_image_download_status(self, device, request):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400172 log.info('get_image_download - Not implemented yet', device=device,
173 request=request)
Shad Ansari2825d012018-02-22 23:57:46 +0000174 raise NotImplementedError()
175
176 def cancel_image_download(self, device, request):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400177 log.info('cancel_image_download - Not implemented yet', device=device)
Shad Ansari2825d012018-02-22 23:57:46 +0000178 raise NotImplementedError()
179
180 def activate_image_update(self, device, request):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400181 log.info('activate_image_update - Not implemented yet',
182 device=device, request=request)
Shad Ansari2825d012018-02-22 23:57:46 +0000183 raise NotImplementedError()
184
185 def revert_image_update(self, device, request):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400186 log.info('revert_image_update - Not implemented yet',
187 device=device, request=request)
Shad Ansari2825d012018-02-22 23:57:46 +0000188 raise NotImplementedError()
189
190 def self_test_device(self, device):
Shad Ansarif9d2d102018-06-13 02:15:26 +0000191 # from voltha.protos.voltha_pb2 import SelfTestResponse
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400192 log.info('Not implemented yet')
Shad Ansari2825d012018-02-22 23:57:46 +0000193 raise NotImplementedError()
194
195 def delete_device(self, device):
196 log.info('delete-device', device=device)
Jonathan Davis0f917a22018-05-30 14:39:45 -0400197 handler = self.devices[device.id]
198 handler.delete()
199 del self.devices[device.id]
Matteo Scandoloa171b6e2018-09-14 16:48:24 -0700200 del self.logical_device_id_to_root_device_id[device.parent_id]
Nicolas Palpacuer0d44e682018-08-06 10:30:26 -0400201 return device
Shad Ansari2825d012018-02-22 23:57:46 +0000202
203 def get_device_details(self, device):
204 log.debug('get_device_details', device=device)
205 raise NotImplementedError()
206
207 def update_flows_bulk(self, device, flows, groups):
208 log.info('bulk-flow-update', device_id=device.id,
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400209 number_of_flows=len(flows.items), number_of_groups=len(
210 groups.items))
211 log.debug('flows and grousp details', flows=flows, groups=groups)
Shad Ansari2825d012018-02-22 23:57:46 +0000212 assert len(groups.items) == 0, "Cannot yet deal with groups"
213 handler = self.devices[device.id]
214 return handler.update_flow_table(flows.items)
215
216 def update_flows_incrementally(self, device, flow_changes, group_changes):
Shad Ansarif9d2d102018-06-13 02:15:26 +0000217 log.debug('update_flows_incrementally', device=device,
218 flow_changes=flow_changes, group_changes=group_changes)
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400219 log.info('This device does not allow this, therefore it is Not '
220 'implemented')
Shad Ansari2825d012018-02-22 23:57:46 +0000221 raise NotImplementedError()
222
Nicolas Palpacuer0c7c3162018-08-08 11:27:57 -0400223 def update_logical_flows(self, device_id, flows_to_add, flows_to_remove,
224 groups, device_rules_map):
225
226 log.info('logical-flows-update', flows_to_add=len(flows_to_add),
227 flows_to_remove = len(flows_to_remove))
228 log.debug('logical-flows-details', flows_to_add=flows_to_add,
229 flows_to_remove=flows_to_remove)
230 assert len(groups) == 0, "Cannot yet deal with groups"
231 handler = self.devices[device_id]
232 handler.update_logical_flows(flows_to_add, flows_to_remove,
233 device_rules_map)
234
Shad Ansari2825d012018-02-22 23:57:46 +0000235 def update_pm_config(self, device, pm_configs):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400236 log.info('update_pm_config - Not implemented yet', device=device,
237 pm_configs=pm_configs)
Shad Ansari2825d012018-02-22 23:57:46 +0000238 raise NotImplementedError()
239
240 def send_proxied_message(self, proxy_address, msg):
241 log.debug('send-proxied-message', proxy_address=proxy_address, msg=msg)
242 handler = self.devices[proxy_address.device_id]
243 handler.send_proxied_message(proxy_address, msg)
244
245 def receive_proxied_message(self, proxy_address, msg):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400246 log.debug('receive_proxied_message - Not implemented',
247 proxy_address=proxy_address,
Shad Ansarif9d2d102018-06-13 02:15:26 +0000248 msg=msg)
Shad Ansari2825d012018-02-22 23:57:46 +0000249 raise NotImplementedError()
250
251 def receive_packet_out(self, logical_device_id, egress_port_no, msg):
252 log.debug('packet-out', logical_device_id=logical_device_id,
253 egress_port_no=egress_port_no, msg_len=len(msg))
Shad Ansarif9d2d102018-06-13 02:15:26 +0000254
Shad Ansari42db7342018-04-25 21:39:46 +0000255 def ldi_to_di(ldi):
256 di = self.logical_device_id_to_root_device_id.get(ldi)
257 if di is None:
258 logical_device = self.adapter_agent.get_logical_device(ldi)
259 di = logical_device.root_device_id
260 self.logical_device_id_to_root_device_id[ldi] = di
261 return di
262
Matteo Scandoloa171b6e2018-09-14 16:48:24 -0700263 try:
264 device_id = ldi_to_di(logical_device_id)
265 handler = self.devices[device_id]
266 handler.packet_out(egress_port_no, msg)
267 except Exception as e:
268 log.error('packet-out:exception', e=e.message)
Shad Ansari2825d012018-02-22 23:57:46 +0000269
270 def receive_inter_adapter_message(self, msg):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400271 log.info('rx_inter_adapter_msg - Not implemented')
Shad Ansari2825d012018-02-22 23:57:46 +0000272 raise NotImplementedError()
273
274 def suppress_alarm(self, filter):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400275 log.info('suppress_alarm - Not implemented yet', filter=filter)
Shad Ansari2825d012018-02-22 23:57:46 +0000276 raise NotImplementedError()
277
278 def unsuppress_alarm(self, filter):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400279 log.info('unsuppress_alarm - Not implemented yet', filter=filter)
Shad Ansari2825d012018-02-22 23:57:46 +0000280 raise NotImplementedError()
281
282 # PON Mgnt APIs #
283 def create_interface(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400284 log.debug('create-interface - Not implemented - We do not use this',
285 data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000286 raise NotImplementedError()
287
288 def update_interface(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400289 log.debug('update-interface - Not implemented - We do not use this',
290 data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000291 raise NotImplementedError()
292
293 def remove_interface(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400294 log.debug('remove-interface - Not implemented - We do not use this',
295 data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000296 raise NotImplementedError()
297
298 def receive_onu_detect_state(self, proxy_address, state):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400299 log.debug('receive-onu-detect-state - Not implemented - We do not '
300 'use this', proxy_address=proxy_address,
Shad Ansarif9d2d102018-06-13 02:15:26 +0000301 state=state)
Shad Ansari2825d012018-02-22 23:57:46 +0000302 raise NotImplementedError()
303
304 def create_tcont(self, device, tcont_data, traffic_descriptor_data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400305 log.info('create-tcont - Not implemented - We do not use this',
306 tcont_data=tcont_data,
Shad Ansari2825d012018-02-22 23:57:46 +0000307 traffic_descriptor_data=traffic_descriptor_data)
308 raise NotImplementedError()
309
310 def update_tcont(self, device, tcont_data, traffic_descriptor_data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400311 log.info('update-tcont - Not implemented - We do not use this',
312 tcont_data=tcont_data,
Shad Ansari2825d012018-02-22 23:57:46 +0000313 traffic_descriptor_data=traffic_descriptor_data)
314 raise NotImplementedError()
315
316 def remove_tcont(self, device, tcont_data, traffic_descriptor_data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400317 log.info('remove-tcont - Not implemented - We do not use this',
318 tcont_data=tcont_data,
Shad Ansari2825d012018-02-22 23:57:46 +0000319 traffic_descriptor_data=traffic_descriptor_data)
320 raise NotImplementedError()
321
322 def create_gemport(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400323 log.info('create-gemport - Not implemented - We do not use this',
324 data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000325 raise NotImplementedError()
326
327 def update_gemport(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400328 log.info('update-gemport - Not implemented - We do not use this',
329 data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000330 raise NotImplementedError()
331
332 def remove_gemport(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400333 log.info('remove-gemport - Not implemented - We do not use this',
334 data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000335 raise NotImplementedError()
336
337 def create_multicast_gemport(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400338 log.info('create-mcast-gemport - Not implemented - We do not use '
339 'this', data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000340 raise NotImplementedError()
341
342 def update_multicast_gemport(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400343 log.info('update-mcast-gemport - Not implemented - We do not use '
344 'this', data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000345 raise NotImplementedError()
346
347 def remove_multicast_gemport(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400348 log.info('remove-mcast-gemport - Not implemented - We do not use '
349 'this', data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000350 raise NotImplementedError()
351
352 def create_multicast_distribution_set(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400353 log.info('create-mcast-distribution-set - Not implemented - We do '
354 'not use this', data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000355 raise NotImplementedError()
356
357 def update_multicast_distribution_set(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400358 log.info('update-mcast-distribution-set - Not implemented - We do '
359 'not use this', data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000360 raise NotImplementedError()
361
362 def remove_multicast_distribution_set(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400363 log.info('remove-mcast-distribution-set - Not implemented - We do '
364 'not use this', data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000365 raise NotImplementedError()
Jonathan Davisb45bb372018-07-19 15:05:15 -0400366
Jonathan Davisb45bb372018-07-19 15:05:15 -0400367 def delete_child_device(self, parent_device_id, child_device):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400368 log.info('delete-child_device', parent_device_id=parent_device_id,
369 child_device=child_device)
Jonathan Davisb45bb372018-07-19 15:05:15 -0400370 handler = self.devices[parent_device_id]
Nicolas Palpacuer131790b2018-08-20 09:59:34 -0400371 if handler is not None:
372 handler.delete_child_device(child_device)
373 else:
374 log.error('Could not find matching handler',
375 looking_for_device_id =parent_device_id,
376 available_handlers=self.devices.keys())
Nicolas Palpacuer30027f42018-09-06 15:55:54 -0400377
378 # This is currently not part of the Iadapter interface
379 def collect_stats(self, device_id):
380 log.info('collect_stats', device_id=device_id)
381 handler= self.devices[device_id]
382 if handler is not None:
383 handler.trigger_statistics_collection()
384 else:
385 log.error('Could not find matching handler',
386 looking_for_device_id=device_id,
387 available_handlers=self.devices.keys())
Scott Bakerd3190952018-09-04 15:47:28 -0700388
389 def simulate_alarm(self, device, request):
390 log.info('simulate_alarm', device=device, request=request)
391
392 if device.id not in self.devices:
393 log.error("Device does not exist", device_id=device.id)
394 return OperationResp(code=OperationResp.OPERATION_FAILURE,
395 additional_info="Device %s does not exist" % device.id)
396
397 handler = self.devices[device.id]
398
399 handler.simulate_alarm(request)
400
401 return OperationResp(code=OperationResp.OPERATION_SUCCESS)