blob: 6dde34a0fcee8b7d99f6202a4e656087477d4a3d [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
29from voltha.protos.device_pb2 import DeviceType, DeviceTypes
Shad Ansari2825d012018-02-22 23:57:46 +000030from voltha.registry import registry
31
32_ = third_party
33log = structlog.get_logger()
34
Shad Ansarif9d2d102018-06-13 02:15:26 +000035
Shad Ansari2825d012018-02-22 23:57:46 +000036@implementer(IAdapterInterface)
37class OpenoltAdapter(object):
38 name = 'openolt'
39
40 supported_device_types = [
41 DeviceType(
42 id=name,
43 adapter=name,
Nicolas Palpacuer0c7c3162018-08-08 11:27:57 -040044 accepts_bulk_flow_update=True,
45 accepts_direct_logical_flows_update=True
Shad Ansari2825d012018-02-22 23:57:46 +000046 )
47 ]
48
49 def __init__(self, adapter_agent, config):
50 self.adapter_agent = adapter_agent
51 self.config = config
52 self.descriptor = Adapter(
53 id=self.name,
54 vendor='OLT white box vendor',
55 version='0.1',
56 config=AdapterConfig(log_level=LogLevel.INFO)
57 )
58 log.debug('openolt.__init__', adapter_agent=adapter_agent)
59 self.devices = dict() # device_id -> OpenoltDevice()
60 self.interface = registry('main').get_args().interface
61 self.logical_device_id_to_root_device_id = dict()
Shad Ansari5dbc9c82018-05-10 03:29:31 +000062 self.num_devices = 0
Shad Ansari2825d012018-02-22 23:57:46 +000063
64 def start(self):
65 log.info('started', interface=self.interface)
66
67 def stop(self):
68 log.info('stopped', interface=self.interface)
69
70 def adapter_descriptor(self):
71 log.debug('get descriptor', interface=self.interface)
72 return self.descriptor
73
74 def device_types(self):
Shad Ansarif9d2d102018-06-13 02:15:26 +000075 log.debug('get device_types', interface=self.interface,
76 items=self.supported_device_types)
Shad Ansari2825d012018-02-22 23:57:46 +000077 return DeviceTypes(items=self.supported_device_types)
78
79 def health(self):
80 log.debug('get health', interface=self.interface)
81 raise NotImplementedError()
82
83 def change_master_state(self, master):
Shad Ansarif9d2d102018-06-13 02:15:26 +000084 log.debug('change_master_state', interface=self.interface,
85 master=master)
Shad Ansari2825d012018-02-22 23:57:46 +000086 raise NotImplementedError()
87
88 def adopt_device(self, device):
89 log.info('adopt-device', device=device)
90 kwargs = {
91 'adapter_agent': self.adapter_agent,
Shad Ansari5dbc9c82018-05-10 03:29:31 +000092 'device': device,
93 'device_num': self.num_devices + 1
Shad Ansari2825d012018-02-22 23:57:46 +000094 }
95 try:
96 self.devices[device.id] = OpenoltDevice(**kwargs)
97 except Exception as e:
98 log.error('Failed to adopt OpenOLT device', error=e)
99 del self.devices[device.id]
100 raise
Shad Ansari5dbc9c82018-05-10 03:29:31 +0000101 else:
102 self.num_devices += 1
Shad Ansari2825d012018-02-22 23:57:46 +0000103
104 def reconcile_device(self, device):
105 log.info('reconcile-device', device=device)
Nicolas Palpacuer253461f2018-06-01 12:01:45 -0400106 kwargs = {
107 'adapter_agent': self.adapter_agent,
108 'device': device,
109 'device_num': self.num_devices + 1,
110 'reconciliation': True
111 }
112 try:
113 reconciled_device = OpenoltDevice(**kwargs)
Shad Ansarif9d2d102018-06-13 02:15:26 +0000114 log.debug('reconciled-device-recreated',
115 device_id=reconciled_device.device_id)
Nicolas Palpacuer253461f2018-06-01 12:01:45 -0400116 self.devices[device.id] = reconciled_device
117 except Exception as e:
Shad Ansarif9d2d102018-06-13 02:15:26 +0000118 log.error('Failed to reconcile OpenOLT device', error=e,
119 exception_type=type(e).__name__)
Nicolas Palpacuer253461f2018-06-01 12:01:45 -0400120 del self.devices[device.id]
121 raise
122 else:
123 self.num_devices += 1
124 # Invoke the children reconciliation which would setup the
125 # basic children data structures
126 self.adapter_agent.reconcile_child_devices(device.id)
127 return device
Shad Ansari2825d012018-02-22 23:57:46 +0000128
129 def abandon_device(self, device):
130 log.info('abandon-device', device=device)
131 raise NotImplementedError()
132
133 def disable_device(self, device):
134 log.info('disable-device', device=device)
Jonathan Davis0f917a22018-05-30 14:39:45 -0400135 handler = self.devices[device.id]
136 handler.disable()
Shad Ansari2825d012018-02-22 23:57:46 +0000137
138 def reenable_device(self, device):
139 log.info('reenable-device', device=device)
Jonathan Davis0f917a22018-05-30 14:39:45 -0400140 handler = self.devices[device.id]
141 handler.reenable()
Shad Ansari2825d012018-02-22 23:57:46 +0000142
143 def reboot_device(self, device):
144 log.info('reboot_device', device=device)
Nicolas Palpacuerfd365ac2018-08-02 11:37:37 -0400145 handler = self.devices[device.id]
146 handler.reboot()
Shad Ansari2825d012018-02-22 23:57:46 +0000147
148 def download_image(self, device, request):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400149 log.info('image_download - Not implemented yet', device=device,
150 request=request)
Shad Ansari2825d012018-02-22 23:57:46 +0000151 raise NotImplementedError()
152
153 def get_image_download_status(self, device, request):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400154 log.info('get_image_download - Not implemented yet', device=device,
155 request=request)
Shad Ansari2825d012018-02-22 23:57:46 +0000156 raise NotImplementedError()
157
158 def cancel_image_download(self, device, request):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400159 log.info('cancel_image_download - Not implemented yet', device=device)
Shad Ansari2825d012018-02-22 23:57:46 +0000160 raise NotImplementedError()
161
162 def activate_image_update(self, device, request):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400163 log.info('activate_image_update - Not implemented yet',
164 device=device, request=request)
Shad Ansari2825d012018-02-22 23:57:46 +0000165 raise NotImplementedError()
166
167 def revert_image_update(self, device, request):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400168 log.info('revert_image_update - Not implemented yet',
169 device=device, request=request)
Shad Ansari2825d012018-02-22 23:57:46 +0000170 raise NotImplementedError()
171
172 def self_test_device(self, device):
Shad Ansarif9d2d102018-06-13 02:15:26 +0000173 # from voltha.protos.voltha_pb2 import SelfTestResponse
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400174 log.info('Not implemented yet')
Shad Ansari2825d012018-02-22 23:57:46 +0000175 raise NotImplementedError()
176
177 def delete_device(self, device):
178 log.info('delete-device', device=device)
Jonathan Davis0f917a22018-05-30 14:39:45 -0400179 handler = self.devices[device.id]
180 handler.delete()
181 del self.devices[device.id]
Nicolas Palpacuer0d44e682018-08-06 10:30:26 -0400182 return device
Shad Ansari2825d012018-02-22 23:57:46 +0000183
184 def get_device_details(self, device):
185 log.debug('get_device_details', device=device)
186 raise NotImplementedError()
187
188 def update_flows_bulk(self, device, flows, groups):
189 log.info('bulk-flow-update', device_id=device.id,
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400190 number_of_flows=len(flows.items), number_of_groups=len(
191 groups.items))
192 log.debug('flows and grousp details', flows=flows, groups=groups)
Shad Ansari2825d012018-02-22 23:57:46 +0000193 assert len(groups.items) == 0, "Cannot yet deal with groups"
194 handler = self.devices[device.id]
195 return handler.update_flow_table(flows.items)
196
197 def update_flows_incrementally(self, device, flow_changes, group_changes):
Shad Ansarif9d2d102018-06-13 02:15:26 +0000198 log.debug('update_flows_incrementally', device=device,
199 flow_changes=flow_changes, group_changes=group_changes)
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400200 log.info('This device does not allow this, therefore it is Not '
201 'implemented')
Shad Ansari2825d012018-02-22 23:57:46 +0000202 raise NotImplementedError()
203
Nicolas Palpacuer0c7c3162018-08-08 11:27:57 -0400204 def update_logical_flows(self, device_id, flows_to_add, flows_to_remove,
205 groups, device_rules_map):
206
207 log.info('logical-flows-update', flows_to_add=len(flows_to_add),
208 flows_to_remove = len(flows_to_remove))
209 log.debug('logical-flows-details', flows_to_add=flows_to_add,
210 flows_to_remove=flows_to_remove)
211 assert len(groups) == 0, "Cannot yet deal with groups"
212 handler = self.devices[device_id]
213 handler.update_logical_flows(flows_to_add, flows_to_remove,
214 device_rules_map)
215
Shad Ansari2825d012018-02-22 23:57:46 +0000216 def update_pm_config(self, device, pm_configs):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400217 log.info('update_pm_config - Not implemented yet', device=device,
218 pm_configs=pm_configs)
Shad Ansari2825d012018-02-22 23:57:46 +0000219 raise NotImplementedError()
220
221 def send_proxied_message(self, proxy_address, msg):
222 log.debug('send-proxied-message', proxy_address=proxy_address, msg=msg)
223 handler = self.devices[proxy_address.device_id]
224 handler.send_proxied_message(proxy_address, msg)
225
226 def receive_proxied_message(self, proxy_address, msg):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400227 log.debug('receive_proxied_message - Not implemented',
228 proxy_address=proxy_address,
Shad Ansarif9d2d102018-06-13 02:15:26 +0000229 msg=msg)
Shad Ansari2825d012018-02-22 23:57:46 +0000230 raise NotImplementedError()
231
232 def receive_packet_out(self, logical_device_id, egress_port_no, msg):
233 log.debug('packet-out', logical_device_id=logical_device_id,
234 egress_port_no=egress_port_no, msg_len=len(msg))
Shad Ansarif9d2d102018-06-13 02:15:26 +0000235
Shad Ansari42db7342018-04-25 21:39:46 +0000236 def ldi_to_di(ldi):
237 di = self.logical_device_id_to_root_device_id.get(ldi)
238 if di is None:
239 logical_device = self.adapter_agent.get_logical_device(ldi)
240 di = logical_device.root_device_id
241 self.logical_device_id_to_root_device_id[ldi] = di
242 return di
243
244 device_id = ldi_to_di(logical_device_id)
245 handler = self.devices[device_id]
246 handler.packet_out(egress_port_no, msg)
Shad Ansari2825d012018-02-22 23:57:46 +0000247
248 def receive_inter_adapter_message(self, msg):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400249 log.info('rx_inter_adapter_msg - Not implemented')
Shad Ansari2825d012018-02-22 23:57:46 +0000250 raise NotImplementedError()
251
252 def suppress_alarm(self, filter):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400253 log.info('suppress_alarm - Not implemented yet', filter=filter)
Shad Ansari2825d012018-02-22 23:57:46 +0000254 raise NotImplementedError()
255
256 def unsuppress_alarm(self, filter):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400257 log.info('unsuppress_alarm - Not implemented yet', filter=filter)
Shad Ansari2825d012018-02-22 23:57:46 +0000258 raise NotImplementedError()
259
260 # PON Mgnt APIs #
261 def create_interface(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400262 log.debug('create-interface - Not implemented - We do not use this',
263 data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000264 raise NotImplementedError()
265
266 def update_interface(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400267 log.debug('update-interface - Not implemented - We do not use this',
268 data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000269 raise NotImplementedError()
270
271 def remove_interface(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400272 log.debug('remove-interface - Not implemented - We do not use this',
273 data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000274 raise NotImplementedError()
275
276 def receive_onu_detect_state(self, proxy_address, state):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400277 log.debug('receive-onu-detect-state - Not implemented - We do not '
278 'use this', proxy_address=proxy_address,
Shad Ansarif9d2d102018-06-13 02:15:26 +0000279 state=state)
Shad Ansari2825d012018-02-22 23:57:46 +0000280 raise NotImplementedError()
281
282 def create_tcont(self, device, tcont_data, traffic_descriptor_data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400283 log.info('create-tcont - Not implemented - We do not use this',
284 tcont_data=tcont_data,
Shad Ansari2825d012018-02-22 23:57:46 +0000285 traffic_descriptor_data=traffic_descriptor_data)
286 raise NotImplementedError()
287
288 def update_tcont(self, device, tcont_data, traffic_descriptor_data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400289 log.info('update-tcont - Not implemented - We do not use this',
290 tcont_data=tcont_data,
Shad Ansari2825d012018-02-22 23:57:46 +0000291 traffic_descriptor_data=traffic_descriptor_data)
292 raise NotImplementedError()
293
294 def remove_tcont(self, device, tcont_data, traffic_descriptor_data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400295 log.info('remove-tcont - Not implemented - We do not use this',
296 tcont_data=tcont_data,
Shad Ansari2825d012018-02-22 23:57:46 +0000297 traffic_descriptor_data=traffic_descriptor_data)
298 raise NotImplementedError()
299
300 def create_gemport(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400301 log.info('create-gemport - Not implemented - We do not use this',
302 data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000303 raise NotImplementedError()
304
305 def update_gemport(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400306 log.info('update-gemport - Not implemented - We do not use this',
307 data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000308 raise NotImplementedError()
309
310 def remove_gemport(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400311 log.info('remove-gemport - Not implemented - We do not use this',
312 data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000313 raise NotImplementedError()
314
315 def create_multicast_gemport(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400316 log.info('create-mcast-gemport - Not implemented - We do not use '
317 'this', data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000318 raise NotImplementedError()
319
320 def update_multicast_gemport(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400321 log.info('update-mcast-gemport - Not implemented - We do not use '
322 'this', data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000323 raise NotImplementedError()
324
325 def remove_multicast_gemport(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400326 log.info('remove-mcast-gemport - Not implemented - We do not use '
327 'this', data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000328 raise NotImplementedError()
329
330 def create_multicast_distribution_set(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400331 log.info('create-mcast-distribution-set - Not implemented - We do '
332 'not use this', data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000333 raise NotImplementedError()
334
335 def update_multicast_distribution_set(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400336 log.info('update-mcast-distribution-set - Not implemented - We do '
337 'not use this', data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000338 raise NotImplementedError()
339
340 def remove_multicast_distribution_set(self, device, data):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400341 log.info('remove-mcast-distribution-set - Not implemented - We do '
342 'not use this', data=data)
Shad Ansari2825d012018-02-22 23:57:46 +0000343 raise NotImplementedError()
Jonathan Davisb45bb372018-07-19 15:05:15 -0400344
Jonathan Davisb45bb372018-07-19 15:05:15 -0400345 def delete_child_device(self, parent_device_id, child_device):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400346 log.info('delete-child_device', parent_device_id=parent_device_id,
347 child_device=child_device)
Jonathan Davisb45bb372018-07-19 15:05:15 -0400348 handler = self.devices[parent_device_id]
Nicolas Palpacuer131790b2018-08-20 09:59:34 -0400349 if handler is not None:
350 handler.delete_child_device(child_device)
351 else:
352 log.error('Could not find matching handler',
353 looking_for_device_id =parent_device_id,
354 available_handlers=self.devices.keys())
Nicolas Palpacuer30027f42018-09-06 15:55:54 -0400355
356 # This is currently not part of the Iadapter interface
357 def collect_stats(self, device_id):
358 log.info('collect_stats', device_id=device_id)
359 handler= self.devices[device_id]
360 if handler is not None:
361 handler.trigger_statistics_collection()
362 else:
363 log.error('Could not find matching handler',
364 looking_for_device_id=device_id,
365 available_handlers=self.devices.keys())