blob: ef94da7bc9a734a3f4bc98216158faa5b8a686ad [file] [log] [blame]
Shad Ansari2825d012018-02-22 23:57:46 +00001#
Shad Ansarie8cbc6f2019-02-14 15:50:54 -08002# Copyright 2019 the original author or authors.
Shad Ansari2825d012018-02-22 23:57:46 +00003#
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#
Shad Ansari548f94d2019-04-24 13:42:52 -070016
Shad Ansari94250fc2018-07-04 06:52:11 +000017import binascii
Shad Ansari94250fc2018-07-04 06:52:11 +000018import structlog
Shad Ansari06019382019-02-07 22:56:16 -080019import time
Shad Ansari548f94d2019-04-24 13:42:52 -070020import subprocess
Shad Ansarid1652de2019-04-24 10:15:20 -070021import grpc
Shad Ansari0346f0d2018-04-26 06:54:09 +000022from scapy.layers.l2 import Ether, Dot1Q
Shad Ansari3cd9bf22018-07-25 19:29:39 +000023from transitions import Machine
Shad Ansari3fbf1c02019-04-11 15:12:54 -070024from twisted.internet import reactor
Shad Ansari15928d12018-04-17 02:42:13 +000025
Shad Ansari548f94d2019-04-24 13:42:52 -070026from voltha.registry import registry
Shad Ansarid5577972019-02-22 09:35:03 -080027from voltha.protos.device_pb2 import Port
Shad Ansarid1652de2019-04-24 10:15:20 -070028from voltha.adapters.openolt.protos import openolt_pb2, openolt_pb2_grpc
Shad Ansarie8cbc6f2019-02-14 15:50:54 -080029from voltha.adapters.openolt.openolt_utils import OpenoltUtils
Shad Ansarie969afc2019-04-05 15:16:41 -070030from voltha.adapters.openolt.openolt_indications import OpenoltIndications
Shad Ansari42392a72019-04-09 22:44:18 -070031from voltha.adapters.openolt.openolt_packet import OpenoltPacket
Shad Ansari995ca632019-04-08 19:43:46 -070032from voltha.adapters.openolt.openolt_kafka_admin import KAdmin
Shad Ansarif9d2d102018-06-13 02:15:26 +000033
34
Shad Ansari2825d012018-02-22 23:57:46 +000035class OpenoltDevice(object):
Shad Ansari94250fc2018-07-04 06:52:11 +000036 """
37 OpenoltDevice state machine:
Shad Ansari2825d012018-02-22 23:57:46 +000038
Shad Ansari94250fc2018-07-04 06:52:11 +000039 null ----> init ------> connected -----> up -----> down
40 ^ ^ | ^ | |
41 | | | | | |
42 | +-------------+ +---------+ |
43 | |
44 +-----------------------------------------+
45 """
46 # pylint: disable=too-many-instance-attributes
47 # pylint: disable=R0904
48 states = [
49 'state_null',
50 'state_init',
51 'state_connected',
52 'state_up',
53 'state_down']
54
Shad Ansari22efe832018-05-19 05:37:03 +000055 transitions = [
Shad Ansari0e7ad962018-09-28 01:42:26 +000056 {'trigger': 'go_state_init',
57 'source': ['state_null', 'state_connected', 'state_down'],
58 'dest': 'state_init',
59 'before': 'do_state_init',
60 'after': 'post_init'},
61 {'trigger': 'go_state_connected',
62 'source': 'state_init',
63 'dest': 'state_connected',
Shad Ansari72462c82019-04-17 01:36:01 -070064 'before': 'do_state_connected',
65 'after': 'post_connected'},
Shad Ansari0e7ad962018-09-28 01:42:26 +000066 {'trigger': 'go_state_up',
67 'source': ['state_connected', 'state_down'],
68 'dest': 'state_up',
69 'before': 'do_state_up'},
70 {'trigger': 'go_state_down',
71 'source': ['state_up'],
72 'dest': 'state_down',
73 'before': 'do_state_down',
74 'after': 'post_down'}]
Shad Ansari22efe832018-05-19 05:37:03 +000075
Shad Ansari2825d012018-02-22 23:57:46 +000076 def __init__(self, **kwargs):
77 super(OpenoltDevice, self).__init__()
78
Shad Ansari7c73c1a2019-02-04 15:39:47 -080079 self.admin_state = "up"
80
Shad Ansari8d068642019-02-28 23:09:03 -080081 adapter_agent = kwargs['adapter_agent']
Shad Ansari4f9a9732019-03-08 16:47:08 -080082 self.device_id = kwargs['device_id']
Shad Ansaricd20a6d2018-10-02 14:36:33 +000083
Shad Ansarid5577972019-02-22 09:35:03 -080084 self.data_model_class = kwargs['support_classes']['data_model']
Shad Ansaricd20a6d2018-10-02 14:36:33 +000085 self.platform_class = kwargs['support_classes']['platform']
Shad Ansarid5577972019-02-22 09:35:03 -080086 self.platform = self.platform_class()
Girish Gowdru1e77ea02018-09-24 09:10:35 -070087 self.resource_mgr_class = kwargs['support_classes']['resource_mgr']
Shad Ansaricd20a6d2018-10-02 14:36:33 +000088 self.flow_mgr_class = kwargs['support_classes']['flow_mgr']
89 self.alarm_mgr_class = kwargs['support_classes']['alarm_mgr']
90 self.stats_mgr_class = kwargs['support_classes']['stats_mgr']
Shad Ansaricd20a6d2018-10-02 14:36:33 +000091
Nicolas Palpacuer253461f2018-06-01 12:01:45 -040092 is_reconciliation = kwargs.get('reconciliation', False)
Shad Ansari4f9a9732019-03-08 16:47:08 -080093 self.host_and_port = kwargs['host_and_port']
94 self.extra_args = kwargs['extra_args']
Shad Ansari8d068642019-02-28 23:09:03 -080095 self.log = structlog.get_logger(ip=self.host_and_port)
Shad Ansari2825d012018-02-22 23:57:46 +000096
Matteo Scandolobf5ae0c2018-11-15 18:12:54 -080097 self.log.info('openolt-device-init')
98
Shad Ansari4f9a9732019-03-08 16:47:08 -080099 self.data_model = self.data_model_class(self.device_id, adapter_agent,
Shad Ansari8d068642019-02-28 23:09:03 -0800100 self.platform)
101 if is_reconciliation:
Shad Ansarid5577972019-02-22 09:35:03 -0800102 self.log.info('reconcile data model')
Shad Ansarid5577972019-02-22 09:35:03 -0800103 self.data_model.reconcile()
Nicolas Palpacuer28cc2662018-06-22 16:30:18 -0400104
Shad Ansari94250fc2018-07-04 06:52:11 +0000105 # Initialize the OLT state machine
106 self.machine = Machine(model=self, states=OpenoltDevice.states,
107 transitions=OpenoltDevice.transitions,
108 send_event=True, initial='state_null')
Shad Ansaric4085df2019-02-13 16:47:07 -0800109
110 self.device_info = None
111
Shad Ansari995ca632019-04-08 19:43:46 -0700112 self._kadmin = KAdmin()
Shad Ansaria3bcfe12019-04-13 11:46:28 -0700113 self._kadmin.delete_topics([
114 'openolt.ind-{}'.format(self.host_and_port.split(':')[0])])
Shad Ansarid1652de2019-04-24 10:15:20 -0700115
Shad Ansari548f94d2019-04-24 13:42:52 -0700116 self.broker = registry('openolt_kafka_proxy').kafka_endpoint
Shad Ansarid1652de2019-04-24 10:15:20 -0700117 channel = grpc.insecure_channel(self.host_and_port)
118 self.stub = openolt_pb2_grpc.OpenoltStub(channel)
119
Shad Ansari0cc92302019-04-03 11:34:49 -0700120 self._grpc = None
Shad Ansari94250fc2018-07-04 06:52:11 +0000121 self.go_state_init()
122
123 def do_state_init(self, event):
Shad Ansari0cc92302019-04-03 11:34:49 -0700124 self.log.debug('init')
Shad Ansarie969afc2019-04-05 15:16:41 -0700125 self._indications = OpenoltIndications(self)
126 self._indications.start()
Nicolas Palpacuer7183a3b2018-09-10 17:16:49 -0400127
128 def post_init(self, event):
129 self.log.debug('post_init')
Shad Ansari72462c82019-04-17 01:36:01 -0700130
131 # FIXME
Shad Ansarie969afc2019-04-05 15:16:41 -0700132 time.sleep(10)
Shad Ansari72462c82019-04-17 01:36:01 -0700133
Shad Ansari72462c82019-04-17 01:36:01 -0700134 reactor.callInThread(self.get_device_info)
Shad Ansari94250fc2018-07-04 06:52:11 +0000135
136 def do_state_connected(self, event):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400137 self.log.debug("do_state_connected")
138
Shad Ansarif34da592019-02-13 23:05:35 -0800139 # Check that device_info was successfully retrieved
140 assert(self.device_info is not None
141 and self.device_info.device_serial_number is not None
142 and self.device_info.device_serial_number != '')
143
Shad Ansarid5577972019-02-22 09:35:03 -0800144 self.data_model.olt_create(self.device_info)
Craig Lutgen109d4072018-12-11 17:01:16 -0600145
Shad Ansari1ed6f7d2019-05-18 00:01:54 +0000146 self._kadmin.delete_topics([
147 'voltha.pktout-{}'.format(self.data_model.logical_device_id)])
Shad Ansari1ed6f7d2019-05-18 00:01:54 +0000148
Shad Ansaria3bcfe12019-04-13 11:46:28 -0700149 self._packet = OpenoltPacket(self)
150 self._packet.start()
151
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700152 self.resource_mgr = self.resource_mgr_class(self.device_id,
Shad Ansari78de2be2018-10-12 22:13:54 +0000153 self.host_and_port,
154 self.extra_args,
Shad Ansaric4085df2019-02-13 16:47:07 -0800155 self.device_info)
Shad Ansarid1652de2019-04-24 10:15:20 -0700156 self.flow_mgr = self.flow_mgr_class(self.log, self.stub,
Shad Ansarif9b9b892019-02-27 17:10:27 -0800157 self.device_id,
Shad Ansarid5577972019-02-22 09:35:03 -0800158 self.data_model.logical_device_id,
Shad Ansarif9b9b892019-02-27 17:10:27 -0800159 self.platform, self.resource_mgr,
160 self.data_model)
Girish Gowdruab836e92018-10-25 01:17:57 -0700161
Shad Ansari8d068642019-02-28 23:09:03 -0800162 self.alarm_mgr = self.alarm_mgr_class(self.log, self.platform,
163 self.data_model)
164 self.stats_mgr = self.stats_mgr_class(self, self.log, self.platform,
165 self.data_model)
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000166
Shad Ansari72462c82019-04-17 01:36:01 -0700167 def post_connected(self, event):
Shad Ansari548f94d2019-04-24 13:42:52 -0700168 # FIXME - better way that avoids absolute paths?
169 self._grpc = subprocess.Popen(
170 ['python',
Shad Ansaria03b1332019-04-24 23:31:36 -0700171 'openolt_grpc.py',
Shad Ansari548f94d2019-04-24 13:42:52 -0700172 self.broker,
173 self.host_and_port],
Shad Ansaria03b1332019-04-24 23:31:36 -0700174 env={'PYTHONPATH': '/voltha:/voltha/voltha/protos/third_party'},
175 cwd='/voltha/voltha/adapters/openolt/grpc',
176 )
Shad Ansari72462c82019-04-17 01:36:01 -0700177
Shad Ansari94250fc2018-07-04 06:52:11 +0000178 def do_state_up(self, event):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400179 self.log.debug("do_state_up")
Shad Ansarid5577972019-02-22 09:35:03 -0800180 self.data_model.olt_oper_up()
nick47b74372018-05-25 18:22:49 -0400181
Shad Ansari94250fc2018-07-04 06:52:11 +0000182 def do_state_down(self, event):
183 self.log.debug("do_state_down")
Shad Ansarid5577972019-02-22 09:35:03 -0800184 self.data_model.olt_oper_down()
Nicolas Palpacuer41141352018-08-31 14:11:38 -0400185
Nicolas Palpacuer41141352018-08-31 14:11:38 -0400186 def post_down(self, event):
187 self.log.debug('post_down')
188 self.flow_mgr.reset_flows()
Shad Ansarifc3c4e12019-04-19 16:54:01 -0700189 self.go_state_init()
Nicolas Palpacuer41141352018-08-31 14:11:38 -0400190
Shad Ansari2825d012018-02-22 23:57:46 +0000191 def olt_indication(self, olt_indication):
Shad Ansari22efe832018-05-19 05:37:03 +0000192 if olt_indication.oper_state == "up":
Shad Ansari94250fc2018-07-04 06:52:11 +0000193 self.go_state_up()
Shad Ansari22efe832018-05-19 05:37:03 +0000194 elif olt_indication.oper_state == "down":
Shad Ansari94250fc2018-07-04 06:52:11 +0000195 self.go_state_down()
Shad Ansari2825d012018-02-22 23:57:46 +0000196
197 def intf_indication(self, intf_indication):
Nicolas Palpacuer65de6a42018-05-22 17:28:29 -0400198 self.log.debug("intf indication", intf_id=intf_indication.intf_id,
Shad Ansarif9d2d102018-06-13 02:15:26 +0000199 oper_state=intf_indication.oper_state)
Shad Ansarief2029b2019-02-25 09:45:54 -0800200 # NOTE - BAL only sends interface indications for PON ports,
201 # not for NNI ports.
202 self.data_model.olt_port_add_update(intf_indication.intf_id,
203 "pon",
204 intf_indication.oper_state)
Shad Ansari2825d012018-02-22 23:57:46 +0000205
206 def intf_oper_indication(self, intf_oper_indication):
Shad Ansarif9d2d102018-06-13 02:15:26 +0000207 self.log.debug("Received interface oper state change indication",
208 intf_id=intf_oper_indication.intf_id,
209 type=intf_oper_indication.type,
210 oper_state=intf_oper_indication.oper_state)
Shad Ansarief2029b2019-02-25 09:45:54 -0800211 self.data_model.olt_port_add_update(intf_oper_indication.intf_id,
212 intf_oper_indication.type,
213 intf_oper_indication.oper_state)
Shad Ansari2825d012018-02-22 23:57:46 +0000214
215 def onu_discovery_indication(self, onu_disc_indication):
Shad Ansari803900a2018-05-02 06:26:00 +0000216 intf_id = onu_disc_indication.intf_id
Shad Ansarif9d2d102018-06-13 02:15:26 +0000217 serial_number = onu_disc_indication.serial_number
Shad Ansarie8cbc6f2019-02-14 15:50:54 -0800218 serial_number_str = OpenoltUtils.stringify_serial_number(serial_number)
Shad Ansari803900a2018-05-02 06:26:00 +0000219
Shad Ansarif9d2d102018-06-13 02:15:26 +0000220 self.log.debug("onu discovery indication", intf_id=intf_id,
221 serial_number=serial_number_str)
Nicolas Palpacuer36a93442018-05-23 17:38:57 -0400222
Shad Ansarif9358292019-03-07 12:31:53 -0800223 try:
Shad Ansari4f9a9732019-03-08 16:47:08 -0800224 onu_id = self.data_model.onu_id(serial_number=serial_number_str)
Shad Ansarif9358292019-03-07 12:31:53 -0800225 except ValueError:
226 # FIXME - resource_mgr.get_onu_id() should raise exception
Shad Ansarid5577972019-02-22 09:35:03 -0800227 onu_id = self.resource_mgr.get_onu_id(intf_id)
228 if onu_id is None:
229 raise Exception("onu-id-unavailable")
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700230
Shad Ansari2f8a90d2019-04-19 01:44:24 -0700231 try:
232 self.data_model.onu_create(intf_id, onu_id, serial_number_str)
233 except ValueError:
234 pass
235 else:
236 self.activate_onu(intf_id, onu_id, serial_number,
237 serial_number_str)
Shad Ansari2825d012018-02-22 23:57:46 +0000238
Shad Ansari2825d012018-02-22 23:57:46 +0000239 def onu_indication(self, onu_indication):
Shad Ansaria0b37892018-06-12 21:34:30 +0000240 self.log.debug("onu indication", intf_id=onu_indication.intf_id,
Shad Ansarif9d2d102018-06-13 02:15:26 +0000241 onu_id=onu_indication.onu_id,
242 serial_number=onu_indication.serial_number,
243 oper_state=onu_indication.oper_state,
244 admin_state=onu_indication.admin_state)
Shad Ansari94250fc2018-07-04 06:52:11 +0000245
Shad Ansarif9d2d102018-06-13 02:15:26 +0000246 # Admin state
Nicolas Palpacuer65de6a42018-05-22 17:28:29 -0400247 if onu_indication.admin_state == 'down':
248 if onu_indication.oper_state != 'down':
Shad Ansarif9d2d102018-06-13 02:15:26 +0000249 self.log.error('ONU-admin-state-down-and-oper-status-not-down',
250 oper_state=onu_indication.oper_state)
251 # Forcing the oper state change code to execute
252 onu_indication.oper_state = 'down'
Nicolas Palpacuer65de6a42018-05-22 17:28:29 -0400253
Shad Ansarif9d2d102018-06-13 02:15:26 +0000254 # Port and logical port update is taken care of by oper state block
Nicolas Palpacuer65de6a42018-05-22 17:28:29 -0400255
Nicolas Palpacuer65de6a42018-05-22 17:28:29 -0400256 self.log.debug('admin-state-dealt-with')
257
Shad Ansarif9d2d102018-06-13 02:15:26 +0000258 # Operating state
Nicolas Palpacuer65de6a42018-05-22 17:28:29 -0400259 if onu_indication.oper_state == 'down':
Shad Ansarief2029b2019-02-25 09:45:54 -0800260 self.data_model.onu_oper_down(onu_indication.intf_id,
261 onu_indication.onu_id)
Matt Jeanneret12cd5d02018-08-07 15:30:19 -0400262
Nicolas Palpacuer65de6a42018-05-22 17:28:29 -0400263 elif onu_indication.oper_state == 'up':
Shad Ansarief2029b2019-02-25 09:45:54 -0800264 self.data_model.onu_oper_up(onu_indication.intf_id,
265 onu_indication.onu_id)
nick47b74372018-05-25 18:22:49 -0400266
Shad Ansari2825d012018-02-22 23:57:46 +0000267 def omci_indication(self, omci_indication):
268
269 self.log.debug("omci indication", intf_id=omci_indication.intf_id,
Shad Ansarif9d2d102018-06-13 02:15:26 +0000270 onu_id=omci_indication.onu_id)
Shad Ansari2825d012018-02-22 23:57:46 +0000271
Shad Ansari8d068642019-02-28 23:09:03 -0800272 self.data_model.onu_omci_rx(omci_indication.intf_id,
273 omci_indication.onu_id,
274 omci_indication.pkt)
Shad Ansari2825d012018-02-22 23:57:46 +0000275
Shad Ansari2825d012018-02-22 23:57:46 +0000276 def send_proxied_message(self, proxy_address, msg):
Shad Ansarif9d2d102018-06-13 02:15:26 +0000277 omci = openolt_pb2.OmciMsg(intf_id=proxy_address.channel_id,
278 onu_id=proxy_address.onu_id, pkt=str(msg))
Shad Ansarid1652de2019-04-24 10:15:20 -0700279 reactor.callInThread(self.stub.OmciMsgOut, omci)
Shad Ansari2825d012018-02-22 23:57:46 +0000280
Shad Ansari2825d012018-02-22 23:57:46 +0000281 def update_flow_table(self, flows):
Nicolas Palpacuer0c7c3162018-08-08 11:27:57 -0400282 self.log.debug('No updates here now, all is done in logical flows '
283 'update')
Shad Ansari5df91f62018-07-25 23:59:46 +0000284
Nicolas Palpacuer0c7c3162018-08-08 11:27:57 -0400285 def update_logical_flows(self, flows_to_add, flows_to_remove,
286 device_rules_map):
Nicolas Palpacuer3d0878d2018-08-17 11:29:42 -0400287 if not self.is_state_up():
288 self.log.info('The OLT is not up, we cannot update flows',
289 flows_to_add=[f.id for f in flows_to_add],
290 flows_to_remove=[f.id for f in flows_to_remove])
291 return
292
Shad Ansari4f9a9732019-03-08 16:47:08 -0800293 self.flow_mgr.update_logical_flows(flows_to_add, flows_to_remove,
294 device_rules_map)
Nicolas Palpacuer41141352018-08-31 14:11:38 -0400295
Jonathan Davis0f917a22018-05-30 14:39:45 -0400296 def disable(self):
Shad Ansari8d068642019-02-28 23:09:03 -0800297 self.log.debug('sending-deactivate-olt-message')
Jonathan Davis0f917a22018-05-30 14:39:45 -0400298
Nicolas Palpacuer62dbb9c2018-08-02 15:03:35 -0400299 try:
300 # Send grpc call
Shad Ansarid1652de2019-04-24 10:15:20 -0700301 self.stub.DisableOlt(openolt_pb2.Empty())
Shad Ansari7c73c1a2019-02-04 15:39:47 -0800302 self.admin_state = "down"
Nicolas Palpacuer62dbb9c2018-08-02 15:03:35 -0400303 self.log.info('openolt device disabled')
304 except Exception as e:
305 self.log.error('Failure to disable openolt device', error=e)
Jonathan Davis0f917a22018-05-30 14:39:45 -0400306
Jonathan Davis0f917a22018-05-30 14:39:45 -0400307 def delete(self):
Shad Ansari8d068642019-02-28 23:09:03 -0800308 self.log.info('deleting-olt')
Nicolas Palpacuer0d44e682018-08-06 10:30:26 -0400309
Shad Ansari18094d62019-04-25 10:00:34 -0700310 # Terminate the grpc subprocess
311 self._grpc.terminate()
312
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700313 # Clears up the data from the resource manager KV store
314 # for the device
315 del self.resource_mgr
316
Nicolas Palpacuer0d44e682018-08-06 10:30:26 -0400317 try:
318 # Rebooting to reset the state
319 self.reboot()
Shad Ansarief2029b2019-02-25 09:45:54 -0800320 self.data_model.olt_delete()
Nicolas Palpacuer0d44e682018-08-06 10:30:26 -0400321 except Exception as e:
322 self.log.error('Failure to delete openolt device', error=e)
323 raise e
324 else:
Shad Ansari8d068642019-02-28 23:09:03 -0800325 self.log.info('successfully-deleted-olt')
Jonathan Davis0f917a22018-05-30 14:39:45 -0400326
Jonathan Davis0f917a22018-05-30 14:39:45 -0400327 def reenable(self):
Shad Ansari8d068642019-02-28 23:09:03 -0800328 self.log.debug('reenabling-olt')
Jonathan Davis0f917a22018-05-30 14:39:45 -0400329
Nicolas Palpacuer62dbb9c2018-08-02 15:03:35 -0400330 try:
Shad Ansarid1652de2019-04-24 10:15:20 -0700331 self.stub.ReenableOlt(openolt_pb2.Empty())
Nicolas Palpacuer62dbb9c2018-08-02 15:03:35 -0400332 except Exception as e:
333 self.log.error('Failure to reenable openolt device', error=e)
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400334 else:
335 self.log.info('openolt device reenabled')
Shad Ansari7c73c1a2019-02-04 15:39:47 -0800336 self.admin_state = "up"
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400337
Nicolas Palpacuer131790b2018-08-20 09:59:34 -0400338 def activate_onu(self, intf_id, onu_id, serial_number,
Girish Gowdruab836e92018-10-25 01:17:57 -0700339 serial_number_str):
Nicolas Palpacuer131790b2018-08-20 09:59:34 -0400340 self.log.debug("activating-onu", intf_id=intf_id, onu_id=onu_id,
Shad Ansarif9521ad2018-09-08 10:46:43 +0000341 serial_number_str=serial_number_str,
Shad Ansari8d068642019-02-28 23:09:03 -0800342 serial_number=serial_number)
Nicolas Palpacuer131790b2018-08-20 09:59:34 -0400343 onu = openolt_pb2.Onu(intf_id=intf_id, onu_id=onu_id,
Shad Ansari8d068642019-02-28 23:09:03 -0800344 serial_number=serial_number)
Shad Ansari3fbf1c02019-04-11 15:12:54 -0700345
346 self.log.info('activating onu', serial_number=serial_number_str)
Shad Ansarid1652de2019-04-24 10:15:20 -0700347 reactor.callInThread(self.stub.ActivateOnu, onu)
Nicolas Palpacuer62dbb9c2018-08-02 15:03:35 -0400348
Shad Ansarief2029b2019-02-25 09:45:54 -0800349 # FIXME - instead of passing child_device around, delete_child_device
350 # needs to change to use serial_number.
Jonathan Davisb45bb372018-07-19 15:05:15 -0400351 def delete_child_device(self, child_device):
352 self.log.debug('sending-deactivate-onu',
Jonathan Davisb45bb372018-07-19 15:05:15 -0400353 onu_device=child_device,
354 onu_serial_number=child_device.serial_number)
Thiyagarajan Subramani353af122019-02-20 23:14:24 -0800355
Shad Ansarief2029b2019-02-25 09:45:54 -0800356 self.data_model.onu_delete(child_device.serial_number)
Thiyagarajan Subramani353af122019-02-20 23:14:24 -0800357
Craig Lutgenabd9c842018-11-15 23:58:27 +0000358 # TODO FIXME - For each uni.
359 # TODO FIXME - Flows are not deleted
360 uni_id = 0 # FIXME
Thiyagarajan Subramani353af122019-02-20 23:14:24 -0800361 try:
362 self.flow_mgr.delete_tech_profile_instance(
363 child_device.proxy_address.channel_id,
364 child_device.proxy_address.onu_id,
Shad Ansarief2029b2019-02-25 09:45:54 -0800365 uni_id, None)
Thiyagarajan Subramani353af122019-02-20 23:14:24 -0800366 except Exception as e:
367 self.log.exception("error-removing-tp-instance")
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700368
Thiyagarajan Subramani353af122019-02-20 23:14:24 -0800369 try:
370 pon_intf_id_onu_id = (child_device.proxy_address.channel_id,
371 child_device.proxy_address.onu_id,
372 uni_id)
373 # Free any PON resources that were reserved for the ONU
374 self.resource_mgr.free_pon_resources_for_onu(pon_intf_id_onu_id)
375 except Exception as e:
376 self.log.exception("error-removing-pon-resources-for-onu")
377
Shad Ansarief2029b2019-02-25 09:45:54 -0800378 serial_number = OpenoltUtils.destringify_serial_number(
379 child_device.serial_number)
Thiyagarajan Subramani353af122019-02-20 23:14:24 -0800380 try:
Shad Ansarid5577972019-02-22 09:35:03 -0800381 onu = openolt_pb2.Onu(
382 intf_id=child_device.proxy_address.channel_id,
383 onu_id=child_device.proxy_address.onu_id,
384 serial_number=serial_number)
Shad Ansarid1652de2019-04-24 10:15:20 -0700385 self.stub.DeleteOnu(onu)
Thiyagarajan Subramani353af122019-02-20 23:14:24 -0800386 except Exception as e:
Shad Ansari242aac62019-04-19 18:32:56 -0700387 self.log.warn("error-deleting-the-onu-on-olt-device", error=e)
Nicolas Palpacuerfd365ac2018-08-02 11:37:37 -0400388
389 def reboot(self):
Shad Ansari8d068642019-02-28 23:09:03 -0800390 self.log.debug('rebooting openolt device')
Nicolas Palpacuerfd365ac2018-08-02 11:37:37 -0400391 try:
Shad Ansarid1652de2019-04-24 10:15:20 -0700392 self.stub.Reboot(openolt_pb2.Empty())
Nicolas Palpacuerfd365ac2018-08-02 11:37:37 -0400393 except Exception as e:
394 self.log.error('something went wrong with the reboot', error=e)
395 else:
396 self.log.info('device rebooted')
397
Nicolas Palpacuer30027f42018-09-06 15:55:54 -0400398 def trigger_statistics_collection(self):
399 try:
Shad Ansarid1652de2019-04-24 10:15:20 -0700400 self.stub.CollectStatistics(openolt_pb2.Empty())
Nicolas Palpacuer30027f42018-09-06 15:55:54 -0400401 except Exception as e:
402 self.log.error('Error while triggering statistics collection',
403 error=e)
404 else:
405 self.log.info('statistics requested')
Scott Bakerd3190952018-09-04 15:47:28 -0700406
407 def simulate_alarm(self, alarm):
408 self.alarm_mgr.simulate_alarm(alarm)
Shad Ansari72462c82019-04-17 01:36:01 -0700409
410 def get_device_info(self):
411 self.log.debug('get_device_info')
412 timeout = 60*60
413 delay = 1
414 exponential_back_off = False
415 while True:
416 try:
417 self.device_info \
Shad Ansarid1652de2019-04-24 10:15:20 -0700418 = self.stub.GetDeviceInfo(openolt_pb2.Empty())
Shad Ansari72462c82019-04-17 01:36:01 -0700419 break
420 except Exception as e:
421 if delay > timeout:
422 self.log.error("openolt grpc timed out connecting to olt")
423 return
424 else:
425 self.log.warn(
426 "openolt grpc retry connecting to olt in %ds: %s"
427 % (delay, repr(e)))
428 time.sleep(delay)
429 if exponential_back_off:
430 delay += delay
431 else:
432 delay += 1
433
434 self.log.info('openolt grpc connected to olt',
435 device_info=self.device_info)
436
437 self.go_state_connected()