blob: eec0f2cbc0aaa0f71a045359c3e528cdd881d5fb [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 Ansari12acc9a2019-05-20 21:46:28 +0000146 # FIXME
Shad Ansari1ed6f7d2019-05-18 00:01:54 +0000147 self._kadmin.delete_topics([
148 'voltha.pktout-{}'.format(self.data_model.logical_device_id)])
Shad Ansari12acc9a2019-05-20 21:46:28 +0000149 self._kadmin.delete_topics(['openolt.pktin-{}'.format(
150 self.host_and_port.split(':')[0])])
Shad Ansari1ed6f7d2019-05-18 00:01:54 +0000151
Shad Ansaria3bcfe12019-04-13 11:46:28 -0700152 self._packet = OpenoltPacket(self)
153 self._packet.start()
154
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700155 self.resource_mgr = self.resource_mgr_class(self.device_id,
Shad Ansari78de2be2018-10-12 22:13:54 +0000156 self.host_and_port,
157 self.extra_args,
Shad Ansaric4085df2019-02-13 16:47:07 -0800158 self.device_info)
Shad Ansarid1652de2019-04-24 10:15:20 -0700159 self.flow_mgr = self.flow_mgr_class(self.log, self.stub,
Shad Ansarif9b9b892019-02-27 17:10:27 -0800160 self.device_id,
Shad Ansarid5577972019-02-22 09:35:03 -0800161 self.data_model.logical_device_id,
Shad Ansarif9b9b892019-02-27 17:10:27 -0800162 self.platform, self.resource_mgr,
163 self.data_model)
Girish Gowdruab836e92018-10-25 01:17:57 -0700164
Shad Ansari8d068642019-02-28 23:09:03 -0800165 self.alarm_mgr = self.alarm_mgr_class(self.log, self.platform,
166 self.data_model)
167 self.stats_mgr = self.stats_mgr_class(self, self.log, self.platform,
168 self.data_model)
Shad Ansaricd20a6d2018-10-02 14:36:33 +0000169
Shad Ansari72462c82019-04-17 01:36:01 -0700170 def post_connected(self, event):
Shad Ansari548f94d2019-04-24 13:42:52 -0700171 # FIXME - better way that avoids absolute paths?
172 self._grpc = subprocess.Popen(
173 ['python',
Shad Ansaria03b1332019-04-24 23:31:36 -0700174 'openolt_grpc.py',
Shad Ansari548f94d2019-04-24 13:42:52 -0700175 self.broker,
176 self.host_and_port],
Shad Ansaria03b1332019-04-24 23:31:36 -0700177 env={'PYTHONPATH': '/voltha:/voltha/voltha/protos/third_party'},
178 cwd='/voltha/voltha/adapters/openolt/grpc',
179 )
Shad Ansari72462c82019-04-17 01:36:01 -0700180
Shad Ansari94250fc2018-07-04 06:52:11 +0000181 def do_state_up(self, event):
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400182 self.log.debug("do_state_up")
Shad Ansarid5577972019-02-22 09:35:03 -0800183 self.data_model.olt_oper_up()
nick47b74372018-05-25 18:22:49 -0400184
Shad Ansari94250fc2018-07-04 06:52:11 +0000185 def do_state_down(self, event):
186 self.log.debug("do_state_down")
Shad Ansarid5577972019-02-22 09:35:03 -0800187 self.data_model.olt_oper_down()
Nicolas Palpacuer41141352018-08-31 14:11:38 -0400188
Nicolas Palpacuer41141352018-08-31 14:11:38 -0400189 def post_down(self, event):
190 self.log.debug('post_down')
191 self.flow_mgr.reset_flows()
Shad Ansarifc3c4e12019-04-19 16:54:01 -0700192 self.go_state_init()
Nicolas Palpacuer41141352018-08-31 14:11:38 -0400193
Shad Ansari2825d012018-02-22 23:57:46 +0000194 def olt_indication(self, olt_indication):
Shad Ansari22efe832018-05-19 05:37:03 +0000195 if olt_indication.oper_state == "up":
Shad Ansari94250fc2018-07-04 06:52:11 +0000196 self.go_state_up()
Shad Ansari22efe832018-05-19 05:37:03 +0000197 elif olt_indication.oper_state == "down":
Shad Ansari94250fc2018-07-04 06:52:11 +0000198 self.go_state_down()
Shad Ansari2825d012018-02-22 23:57:46 +0000199
200 def intf_indication(self, intf_indication):
Nicolas Palpacuer65de6a42018-05-22 17:28:29 -0400201 self.log.debug("intf indication", intf_id=intf_indication.intf_id,
Shad Ansarif9d2d102018-06-13 02:15:26 +0000202 oper_state=intf_indication.oper_state)
Shad Ansarief2029b2019-02-25 09:45:54 -0800203 # NOTE - BAL only sends interface indications for PON ports,
204 # not for NNI ports.
205 self.data_model.olt_port_add_update(intf_indication.intf_id,
206 "pon",
207 intf_indication.oper_state)
Shad Ansari2825d012018-02-22 23:57:46 +0000208
209 def intf_oper_indication(self, intf_oper_indication):
Shad Ansarif9d2d102018-06-13 02:15:26 +0000210 self.log.debug("Received interface oper state change indication",
211 intf_id=intf_oper_indication.intf_id,
212 type=intf_oper_indication.type,
213 oper_state=intf_oper_indication.oper_state)
Shad Ansarief2029b2019-02-25 09:45:54 -0800214 self.data_model.olt_port_add_update(intf_oper_indication.intf_id,
215 intf_oper_indication.type,
216 intf_oper_indication.oper_state)
Shad Ansari2825d012018-02-22 23:57:46 +0000217
218 def onu_discovery_indication(self, onu_disc_indication):
Shad Ansari803900a2018-05-02 06:26:00 +0000219 intf_id = onu_disc_indication.intf_id
Shad Ansarif9d2d102018-06-13 02:15:26 +0000220 serial_number = onu_disc_indication.serial_number
Shad Ansarie8cbc6f2019-02-14 15:50:54 -0800221 serial_number_str = OpenoltUtils.stringify_serial_number(serial_number)
Shad Ansari803900a2018-05-02 06:26:00 +0000222
Shad Ansarif9d2d102018-06-13 02:15:26 +0000223 self.log.debug("onu discovery indication", intf_id=intf_id,
224 serial_number=serial_number_str)
Nicolas Palpacuer36a93442018-05-23 17:38:57 -0400225
Shad Ansarif9358292019-03-07 12:31:53 -0800226 try:
Shad Ansari4f9a9732019-03-08 16:47:08 -0800227 onu_id = self.data_model.onu_id(serial_number=serial_number_str)
Shad Ansarif9358292019-03-07 12:31:53 -0800228 except ValueError:
229 # FIXME - resource_mgr.get_onu_id() should raise exception
Shad Ansarid5577972019-02-22 09:35:03 -0800230 onu_id = self.resource_mgr.get_onu_id(intf_id)
231 if onu_id is None:
232 raise Exception("onu-id-unavailable")
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700233
Shad Ansari2f8a90d2019-04-19 01:44:24 -0700234 try:
235 self.data_model.onu_create(intf_id, onu_id, serial_number_str)
236 except ValueError:
237 pass
238 else:
239 self.activate_onu(intf_id, onu_id, serial_number,
240 serial_number_str)
Shad Ansari2825d012018-02-22 23:57:46 +0000241
Shad Ansari2825d012018-02-22 23:57:46 +0000242 def onu_indication(self, onu_indication):
Shad Ansaria0b37892018-06-12 21:34:30 +0000243 self.log.debug("onu indication", intf_id=onu_indication.intf_id,
Shad Ansarif9d2d102018-06-13 02:15:26 +0000244 onu_id=onu_indication.onu_id,
245 serial_number=onu_indication.serial_number,
246 oper_state=onu_indication.oper_state,
247 admin_state=onu_indication.admin_state)
Shad Ansari94250fc2018-07-04 06:52:11 +0000248
Shad Ansarif9d2d102018-06-13 02:15:26 +0000249 # Admin state
Nicolas Palpacuer65de6a42018-05-22 17:28:29 -0400250 if onu_indication.admin_state == 'down':
251 if onu_indication.oper_state != 'down':
Shad Ansarif9d2d102018-06-13 02:15:26 +0000252 self.log.error('ONU-admin-state-down-and-oper-status-not-down',
253 oper_state=onu_indication.oper_state)
254 # Forcing the oper state change code to execute
255 onu_indication.oper_state = 'down'
Nicolas Palpacuer65de6a42018-05-22 17:28:29 -0400256
Shad Ansarif9d2d102018-06-13 02:15:26 +0000257 # Port and logical port update is taken care of by oper state block
Nicolas Palpacuer65de6a42018-05-22 17:28:29 -0400258
Nicolas Palpacuer65de6a42018-05-22 17:28:29 -0400259 self.log.debug('admin-state-dealt-with')
260
Shad Ansarif9d2d102018-06-13 02:15:26 +0000261 # Operating state
Nicolas Palpacuer65de6a42018-05-22 17:28:29 -0400262 if onu_indication.oper_state == 'down':
Shad Ansarief2029b2019-02-25 09:45:54 -0800263 self.data_model.onu_oper_down(onu_indication.intf_id,
264 onu_indication.onu_id)
Matt Jeanneret12cd5d02018-08-07 15:30:19 -0400265
Nicolas Palpacuer65de6a42018-05-22 17:28:29 -0400266 elif onu_indication.oper_state == 'up':
Shad Ansarief2029b2019-02-25 09:45:54 -0800267 self.data_model.onu_oper_up(onu_indication.intf_id,
268 onu_indication.onu_id)
nick47b74372018-05-25 18:22:49 -0400269
Shad Ansari2825d012018-02-22 23:57:46 +0000270 def omci_indication(self, omci_indication):
271
272 self.log.debug("omci indication", intf_id=omci_indication.intf_id,
Shad Ansarif9d2d102018-06-13 02:15:26 +0000273 onu_id=omci_indication.onu_id)
Shad Ansari2825d012018-02-22 23:57:46 +0000274
Shad Ansari8d068642019-02-28 23:09:03 -0800275 self.data_model.onu_omci_rx(omci_indication.intf_id,
276 omci_indication.onu_id,
277 omci_indication.pkt)
Shad Ansari2825d012018-02-22 23:57:46 +0000278
Shad Ansari2825d012018-02-22 23:57:46 +0000279 def send_proxied_message(self, proxy_address, msg):
Shad Ansarif9d2d102018-06-13 02:15:26 +0000280 omci = openolt_pb2.OmciMsg(intf_id=proxy_address.channel_id,
281 onu_id=proxy_address.onu_id, pkt=str(msg))
Shad Ansarid1652de2019-04-24 10:15:20 -0700282 reactor.callInThread(self.stub.OmciMsgOut, omci)
Shad Ansari2825d012018-02-22 23:57:46 +0000283
Shad Ansari2825d012018-02-22 23:57:46 +0000284 def update_flow_table(self, flows):
Nicolas Palpacuer0c7c3162018-08-08 11:27:57 -0400285 self.log.debug('No updates here now, all is done in logical flows '
286 'update')
Shad Ansari5df91f62018-07-25 23:59:46 +0000287
Nicolas Palpacuer0c7c3162018-08-08 11:27:57 -0400288 def update_logical_flows(self, flows_to_add, flows_to_remove,
289 device_rules_map):
Nicolas Palpacuer3d0878d2018-08-17 11:29:42 -0400290 if not self.is_state_up():
291 self.log.info('The OLT is not up, we cannot update flows',
292 flows_to_add=[f.id for f in flows_to_add],
293 flows_to_remove=[f.id for f in flows_to_remove])
294 return
295
Shad Ansari4f9a9732019-03-08 16:47:08 -0800296 self.flow_mgr.update_logical_flows(flows_to_add, flows_to_remove,
297 device_rules_map)
Nicolas Palpacuer41141352018-08-31 14:11:38 -0400298
Jonathan Davis0f917a22018-05-30 14:39:45 -0400299 def disable(self):
Shad Ansari8d068642019-02-28 23:09:03 -0800300 self.log.debug('sending-deactivate-olt-message')
Jonathan Davis0f917a22018-05-30 14:39:45 -0400301
Nicolas Palpacuer62dbb9c2018-08-02 15:03:35 -0400302 try:
303 # Send grpc call
Shad Ansarid1652de2019-04-24 10:15:20 -0700304 self.stub.DisableOlt(openolt_pb2.Empty())
Shad Ansari7c73c1a2019-02-04 15:39:47 -0800305 self.admin_state = "down"
Nicolas Palpacuer62dbb9c2018-08-02 15:03:35 -0400306 self.log.info('openolt device disabled')
307 except Exception as e:
308 self.log.error('Failure to disable openolt device', error=e)
Jonathan Davis0f917a22018-05-30 14:39:45 -0400309
Jonathan Davis0f917a22018-05-30 14:39:45 -0400310 def delete(self):
Shad Ansari8d068642019-02-28 23:09:03 -0800311 self.log.info('deleting-olt')
Nicolas Palpacuer0d44e682018-08-06 10:30:26 -0400312
Shad Ansari18094d62019-04-25 10:00:34 -0700313 # Terminate the grpc subprocess
314 self._grpc.terminate()
315
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700316 # Clears up the data from the resource manager KV store
317 # for the device
318 del self.resource_mgr
319
Nicolas Palpacuer0d44e682018-08-06 10:30:26 -0400320 try:
321 # Rebooting to reset the state
322 self.reboot()
Shad Ansarief2029b2019-02-25 09:45:54 -0800323 self.data_model.olt_delete()
Nicolas Palpacuer0d44e682018-08-06 10:30:26 -0400324 except Exception as e:
325 self.log.error('Failure to delete openolt device', error=e)
326 raise e
327 else:
Shad Ansari8d068642019-02-28 23:09:03 -0800328 self.log.info('successfully-deleted-olt')
Jonathan Davis0f917a22018-05-30 14:39:45 -0400329
Jonathan Davis0f917a22018-05-30 14:39:45 -0400330 def reenable(self):
Shad Ansari8d068642019-02-28 23:09:03 -0800331 self.log.debug('reenabling-olt')
Jonathan Davis0f917a22018-05-30 14:39:45 -0400332
Nicolas Palpacuer62dbb9c2018-08-02 15:03:35 -0400333 try:
Shad Ansarid1652de2019-04-24 10:15:20 -0700334 self.stub.ReenableOlt(openolt_pb2.Empty())
Nicolas Palpacuer62dbb9c2018-08-02 15:03:35 -0400335 except Exception as e:
336 self.log.error('Failure to reenable openolt device', error=e)
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400337 else:
338 self.log.info('openolt device reenabled')
Shad Ansari7c73c1a2019-02-04 15:39:47 -0800339 self.admin_state = "up"
Nicolas Palpacuer324dcae2018-08-02 11:12:22 -0400340
Nicolas Palpacuer131790b2018-08-20 09:59:34 -0400341 def activate_onu(self, intf_id, onu_id, serial_number,
Girish Gowdruab836e92018-10-25 01:17:57 -0700342 serial_number_str):
Nicolas Palpacuer131790b2018-08-20 09:59:34 -0400343 self.log.debug("activating-onu", intf_id=intf_id, onu_id=onu_id,
Shad Ansarif9521ad2018-09-08 10:46:43 +0000344 serial_number_str=serial_number_str,
Shad Ansari8d068642019-02-28 23:09:03 -0800345 serial_number=serial_number)
Nicolas Palpacuer131790b2018-08-20 09:59:34 -0400346 onu = openolt_pb2.Onu(intf_id=intf_id, onu_id=onu_id,
Shad Ansari8d068642019-02-28 23:09:03 -0800347 serial_number=serial_number)
Shad Ansari3fbf1c02019-04-11 15:12:54 -0700348
349 self.log.info('activating onu', serial_number=serial_number_str)
Shad Ansarid1652de2019-04-24 10:15:20 -0700350 reactor.callInThread(self.stub.ActivateOnu, onu)
Nicolas Palpacuer62dbb9c2018-08-02 15:03:35 -0400351
Shad Ansarief2029b2019-02-25 09:45:54 -0800352 # FIXME - instead of passing child_device around, delete_child_device
353 # needs to change to use serial_number.
Jonathan Davisb45bb372018-07-19 15:05:15 -0400354 def delete_child_device(self, child_device):
355 self.log.debug('sending-deactivate-onu',
Jonathan Davisb45bb372018-07-19 15:05:15 -0400356 onu_device=child_device,
357 onu_serial_number=child_device.serial_number)
Thiyagarajan Subramani353af122019-02-20 23:14:24 -0800358
Shad Ansarief2029b2019-02-25 09:45:54 -0800359 self.data_model.onu_delete(child_device.serial_number)
Thiyagarajan Subramani353af122019-02-20 23:14:24 -0800360
Craig Lutgenabd9c842018-11-15 23:58:27 +0000361 # TODO FIXME - For each uni.
362 # TODO FIXME - Flows are not deleted
363 uni_id = 0 # FIXME
Thiyagarajan Subramani353af122019-02-20 23:14:24 -0800364 try:
365 self.flow_mgr.delete_tech_profile_instance(
366 child_device.proxy_address.channel_id,
367 child_device.proxy_address.onu_id,
Shad Ansarief2029b2019-02-25 09:45:54 -0800368 uni_id, None)
Thiyagarajan Subramani353af122019-02-20 23:14:24 -0800369 except Exception as e:
370 self.log.exception("error-removing-tp-instance")
Girish Gowdru1e77ea02018-09-24 09:10:35 -0700371
Thiyagarajan Subramani353af122019-02-20 23:14:24 -0800372 try:
373 pon_intf_id_onu_id = (child_device.proxy_address.channel_id,
374 child_device.proxy_address.onu_id,
375 uni_id)
376 # Free any PON resources that were reserved for the ONU
377 self.resource_mgr.free_pon_resources_for_onu(pon_intf_id_onu_id)
378 except Exception as e:
379 self.log.exception("error-removing-pon-resources-for-onu")
380
Shad Ansarief2029b2019-02-25 09:45:54 -0800381 serial_number = OpenoltUtils.destringify_serial_number(
382 child_device.serial_number)
Thiyagarajan Subramani353af122019-02-20 23:14:24 -0800383 try:
Shad Ansarid5577972019-02-22 09:35:03 -0800384 onu = openolt_pb2.Onu(
385 intf_id=child_device.proxy_address.channel_id,
386 onu_id=child_device.proxy_address.onu_id,
387 serial_number=serial_number)
Shad Ansarid1652de2019-04-24 10:15:20 -0700388 self.stub.DeleteOnu(onu)
Thiyagarajan Subramani353af122019-02-20 23:14:24 -0800389 except Exception as e:
Shad Ansari242aac62019-04-19 18:32:56 -0700390 self.log.warn("error-deleting-the-onu-on-olt-device", error=e)
Nicolas Palpacuerfd365ac2018-08-02 11:37:37 -0400391
392 def reboot(self):
Shad Ansari8d068642019-02-28 23:09:03 -0800393 self.log.debug('rebooting openolt device')
Nicolas Palpacuerfd365ac2018-08-02 11:37:37 -0400394 try:
Shad Ansarid1652de2019-04-24 10:15:20 -0700395 self.stub.Reboot(openolt_pb2.Empty())
Nicolas Palpacuerfd365ac2018-08-02 11:37:37 -0400396 except Exception as e:
397 self.log.error('something went wrong with the reboot', error=e)
398 else:
399 self.log.info('device rebooted')
400
Nicolas Palpacuer30027f42018-09-06 15:55:54 -0400401 def trigger_statistics_collection(self):
402 try:
Shad Ansarid1652de2019-04-24 10:15:20 -0700403 self.stub.CollectStatistics(openolt_pb2.Empty())
Nicolas Palpacuer30027f42018-09-06 15:55:54 -0400404 except Exception as e:
405 self.log.error('Error while triggering statistics collection',
406 error=e)
407 else:
408 self.log.info('statistics requested')
Scott Bakerd3190952018-09-04 15:47:28 -0700409
410 def simulate_alarm(self, alarm):
411 self.alarm_mgr.simulate_alarm(alarm)
Shad Ansari72462c82019-04-17 01:36:01 -0700412
413 def get_device_info(self):
414 self.log.debug('get_device_info')
415 timeout = 60*60
416 delay = 1
417 exponential_back_off = False
418 while True:
419 try:
420 self.device_info \
Shad Ansarid1652de2019-04-24 10:15:20 -0700421 = self.stub.GetDeviceInfo(openolt_pb2.Empty())
Shad Ansari72462c82019-04-17 01:36:01 -0700422 break
423 except Exception as e:
424 if delay > timeout:
425 self.log.error("openolt grpc timed out connecting to olt")
426 return
427 else:
428 self.log.warn(
429 "openolt grpc retry connecting to olt in %ds: %s"
430 % (delay, repr(e)))
431 time.sleep(delay)
432 if exponential_back_off:
433 delay += delay
434 else:
435 delay += 1
436
437 self.log.info('openolt grpc connected to olt',
438 device_info=self.device_info)
439
440 self.go_state_connected()