blob: 77c21e0edc3fbfb6eb965b7b7374e809a463ec22 [file] [log] [blame]
Shad Ansari134947d2019-02-14 23:45:03 -08001#
2# Copyright 2019 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#
16import structlog
17import socket
18from voltha.adapters.openolt.openolt_utils import OpenoltUtils
Shad Ansarid5577972019-02-22 09:35:03 -080019from voltha.protos.device_pb2 import Port, Device
Shad Ansari134947d2019-02-14 23:45:03 -080020from voltha.protos.openflow_13_pb2 import OFPPS_LIVE, OFPPF_FIBER, \
21 OFPPS_LINK_DOWN, OFPPF_1GB_FD, OFPC_PORT_STATS, OFPC_TABLE_STATS, \
22 OFPC_FLOW_STATS, OFPC_GROUP_STATS, ofp_port, ofp_port_stats, ofp_desc, \
23 ofp_switch_features
24from voltha.core.logical_device_agent import mac_str_to_tuple
25from voltha.protos.logical_device_pb2 import LogicalPort
Shad Ansarid5577972019-02-22 09:35:03 -080026from voltha.protos.common_pb2 import OperStatus, AdminState, ConnectStatus
Shad Ansari134947d2019-02-14 23:45:03 -080027from voltha.protos.logical_device_pb2 import LogicalDevice
28from voltha.registry import registry
29
30
31class OpenOltDataModel(object):
Shad Ansari134947d2019-02-14 23:45:03 -080032
Shad Ansarid5577972019-02-22 09:35:03 -080033 def __init__(self, device, adapter_agent, platform):
Shad Ansari134947d2019-02-14 23:45:03 -080034 self.log = structlog.get_logger()
35
Shad Ansarid5577972019-02-22 09:35:03 -080036 self.device = device
37 self.adapter_agent = adapter_agent
38 self.platform = platform
39 self.logical_device_id = None
40
41 self.device.root = True
42 self.device.connect_status = ConnectStatus.UNREACHABLE
43 self.device.oper_status = OperStatus.ACTIVATING
44
45 self.adapter_agent.update_device(device)
46
47 def reconcile(self):
48 assert self.logical_device_id is not None
49 self.adapter_agent.reconcile_logical_device(
50 self.logical_device_id)
51
52 def olt_create(self, device_info):
53 if self.logical_device_id is not None:
54 return
55
Shad Ansari134947d2019-02-14 23:45:03 -080056 dpid = device_info.device_id
57 serial_number = device_info.device_serial_number
58
Shad Ansari134947d2019-02-14 23:45:03 -080059 if dpid is None or dpid == '':
Shad Ansarid5577972019-02-22 09:35:03 -080060 uri = self.device.host_and_port.split(":")[0]
Shad Ansari134947d2019-02-14 23:45:03 -080061 try:
62 socket.inet_pton(socket.AF_INET, uri)
63 dpid = '00:00:' + OpenoltUtils.ip_hex(uri)
64 except socket.error:
65 # this is not an IP
66 dpid = OpenoltUtils.str_to_mac(uri)
67
68 self.log.info('creating-openolt-logical-device', dp_id=dpid,
69 serial_number=serial_number)
70
71 hw_desc = device_info.model
72 if device_info.hardware_version:
73 hw_desc += '-' + device_info.hardware_version
74
75 # Create logical OF device
76 ld = LogicalDevice(
Shad Ansarid5577972019-02-22 09:35:03 -080077 root_device_id=self.device.id,
Shad Ansari134947d2019-02-14 23:45:03 -080078 switch_features=ofp_switch_features(
79 n_buffers=256, # TODO fake for now
80 n_tables=2, # TODO ditto
81 capabilities=( # TODO and ditto
82 OFPC_FLOW_STATS
83 | OFPC_TABLE_STATS
84 | OFPC_PORT_STATS
85 | OFPC_GROUP_STATS
86 )
87 ),
88 desc=ofp_desc(
89 serial_num=serial_number
90 )
91 )
Shad Ansarid5577972019-02-22 09:35:03 -080092 self.logical_device_id = \
93 self.adapter_agent.create_logical_device(ld, dpid=dpid).id
Shad Ansari134947d2019-02-14 23:45:03 -080094
Shad Ansarid5577972019-02-22 09:35:03 -080095 self.device.vendor = device_info.vendor
96 self.device.model = device_info.model
97 self.device.hardware_version = device_info.hardware_version
98 self.device.firmware_version = device_info.firmware_version
99 self.device.connect_status = ConnectStatus.REACHABLE
100 self.device.serial_number = serial_number
101
102 self.adapter_agent.update_device(self.device)
Shad Ansari134947d2019-02-14 23:45:03 -0800103
104 self.log.info('created-openolt-logical-device',
Shad Ansarid5577972019-02-22 09:35:03 -0800105 logical_device_id=self.logical_device_id)
Shad Ansari134947d2019-02-14 23:45:03 -0800106
Shad Ansarid5577972019-02-22 09:35:03 -0800107 return self.logical_device_id
Shad Ansari134947d2019-02-14 23:45:03 -0800108
Shad Ansarid5577972019-02-22 09:35:03 -0800109 def disable_logical_device(self):
Shad Ansari134947d2019-02-14 23:45:03 -0800110
111 oper_state = OperStatus.UNKNOWN
112 connect_state = ConnectStatus.UNREACHABLE
113
Shad Ansarid5577972019-02-22 09:35:03 -0800114 child_devices = self.adapter_agent.get_child_devices(self.device.id)
Shad Ansari134947d2019-02-14 23:45:03 -0800115 for onu_device in child_devices:
116 onu_adapter_agent = \
117 registry('adapter_loader').get_agent(onu_device.adapter)
118 onu_adapter_agent.update_interface(onu_device,
119 {'oper_state': 'down'})
120 self.onu_ports_down(onu_device, oper_state)
121
122 # Children devices
123 self.adapter_agent.update_child_devices_state(
Shad Ansarid5577972019-02-22 09:35:03 -0800124 self.device.id, oper_status=oper_state,
Shad Ansari134947d2019-02-14 23:45:03 -0800125 connect_status=connect_state)
126 # Device Ports
Shad Ansarid5577972019-02-22 09:35:03 -0800127 device_ports = self.adapter_agent.get_ports(self.device.id,
Shad Ansari134947d2019-02-14 23:45:03 -0800128 Port.ETHERNET_NNI)
129 logical_ports_ids = [port.label for port in device_ports]
Shad Ansarid5577972019-02-22 09:35:03 -0800130 device_ports += self.adapter_agent.get_ports(self.device.id,
Shad Ansari134947d2019-02-14 23:45:03 -0800131 Port.PON_OLT)
132
133 for port in device_ports:
134 port.oper_status = oper_state
Shad Ansarid5577972019-02-22 09:35:03 -0800135 self.adapter_agent.add_port(self.device.id, port)
Shad Ansari134947d2019-02-14 23:45:03 -0800136
137 # Device logical port
138 for logical_port_id in logical_ports_ids:
139 logical_port = self.adapter_agent.get_logical_port(
Shad Ansarid5577972019-02-22 09:35:03 -0800140 self.logical_device_id, logical_port_id)
Shad Ansari134947d2019-02-14 23:45:03 -0800141 logical_port.ofp_port.state = OFPPS_LINK_DOWN
142 self.adapter_agent.update_logical_port(self.logical_device_id,
143 logical_port)
Shad Ansarid5577972019-02-22 09:35:03 -0800144 self.device.oper_status = oper_state
145 self.device.connect_status = connect_state
146 self.adapter_agent.update_device(self.device)
Shad Ansari134947d2019-02-14 23:45:03 -0800147
Shad Ansarid5577972019-02-22 09:35:03 -0800148 def add_logical_port(self, port_no, intf_id, oper_state):
Shad Ansari134947d2019-02-14 23:45:03 -0800149 self.log.info('adding-logical-port', port_no=port_no)
150
151 label = OpenoltUtils.port_name(port_no, Port.ETHERNET_NNI)
152
153 cap = OFPPF_1GB_FD | OFPPF_FIBER
154 curr_speed = OFPPF_1GB_FD
155 max_speed = OFPPF_1GB_FD
156
157 if oper_state == OperStatus.ACTIVE:
158 of_oper_state = OFPPS_LIVE
159 else:
160 of_oper_state = OFPPS_LINK_DOWN
161
162 ofp = ofp_port(
163 port_no=port_no,
164 hw_addr=mac_str_to_tuple(
165 OpenoltUtils.make_mac_from_port_no(port_no)),
166 name=label, config=0, state=of_oper_state, curr=cap,
167 advertised=cap, peer=cap, curr_speed=curr_speed,
168 max_speed=max_speed)
169
170 ofp_stats = ofp_port_stats(port_no=port_no)
171
172 logical_port = LogicalPort(
Shad Ansarid5577972019-02-22 09:35:03 -0800173 id=label, ofp_port=ofp, device_id=self.device.id,
Shad Ansari134947d2019-02-14 23:45:03 -0800174 device_port_no=port_no, root_port=True,
175 ofp_port_stats=ofp_stats)
176
Shad Ansarid5577972019-02-22 09:35:03 -0800177 self.adapter_agent.add_logical_port(self.logical_device_id,
178 logical_port)
179
180 def olt_oper_up(self):
181 self.device.parent_id = self.logical_device_id
182 self.device.oper_status = OperStatus.ACTIVE
183 self.adapter_agent.update_device(self.device)
184
185 def olt_oper_down(self):
186 self.disable_logical_device()
187
188 def onu_create(self, intf_id, onu_id, serial_number):
189
190 onu_device = self.adapter_agent.get_child_device(
191 self.device.id,
192 serial_number=serial_number)
193
194 if onu_device:
195 self.log.debug("data_model onu update", intf_id=intf_id,
196 onu_id=onu_id, serial_number=serial_number)
197 onu_device.oper_status = OperStatus.DISCOVERED
198 onu_device.connect_status = ConnectStatus.REACHABLE
199 self.adapter_agent.update_device(onu_device)
200 return
201
202 self.log.debug("data_model onu create", intf_id=intf_id,
203 onu_id=onu_id, serial_number=serial_number)
204
205 # NOTE - channel_id of onu is set to intf_id
206 proxy_address = Device.ProxyAddress(device_id=self.device.id,
207 channel_id=intf_id, onu_id=onu_id,
208 onu_session_id=onu_id)
209 port_no = self.platform.intf_id_to_port_no(intf_id, Port.PON_OLT)
210 vendor_id = serial_number[:4]
211 self.adapter_agent.add_onu_device(
212 parent_device_id=self.device.id, parent_port_no=port_no,
213 vendor_id=vendor_id, proxy_address=proxy_address,
214 root=False, serial_number=serial_number,
215 admin_state=AdminState.ENABLED,
216 connect_status=ConnectStatus.REACHABLE
217 )
218
219 def onu_id(self, serial_number):
220 onu_device = self.adapter_agent.get_child_device(
221 self.device.id,
222 serial_number=serial_number)
223
224 if onu_device:
225 return onu_device.proxy_address.onu_id
226 else:
227 return 0 # Invalid onu id