blob: 7bab7cac06e7552fab32d12faa2f8a6253c523aa [file] [log] [blame]
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -05001#
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
Matt Jeanneret2e3cb8d2019-11-16 09:22:41 -050016from __future__ import absolute_import
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050017import structlog
18from enum import Enum
Girish Gowdra5b499342020-06-16 14:45:51 -070019from pyvoltha.common.utils.nethelpers import mac_str_to_tuple
William Kurkian8235c1e2019-03-05 12:58:28 -050020from voltha_protos.common_pb2 import OperStatus, AdminState
21from voltha_protos.device_pb2 import Port
Girish Gowdra5b499342020-06-16 14:45:51 -070022from voltha_protos.openflow_13_pb2 import OFPPF_1GB_FD, OFPPF_FIBER, OFPPS_LINK_DOWN, OFPPS_LIVE, ofp_port
23
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050024
25class UniType(Enum):
26 """
27 UNI Types Defined in G.988
28 """
29 PPTP = 'PhysicalPathTerminationPointEthernet'
30 VEIP = 'VirtualEthernetInterfacePoint'
31 # TODO: Add others as they become supported
32
Girish Gowdra5b499342020-06-16 14:45:51 -070033
Andrea Campanellacf916ea2020-02-14 10:03:58 +010034# ReservedVlan Transparent Vlan (Masked Vlan, VLAN_ANY in ONOS Flows)
35
36RESERVED_TRANSPARENT_VLAN = 4096
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050037
Girish Gowdra5b499342020-06-16 14:45:51 -070038
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050039class UniPort(object):
40 """Wraps southbound-port(s) support for ONU"""
41
42 def __init__(self, handler, name, uni_id, port_no, ofp_port_no,
Girish Gowdra5b499342020-06-16 14:45:51 -070043 parent_port_no, device_serial_number,
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050044 type=UniType.PPTP):
45 self.log = structlog.get_logger(device_id=handler.device_id,
46 port_no=port_no)
47 self._enabled = False
48 self._handler = handler
49 self._name = name
50 self._port = None
51 self._port_number = port_no
52 self._ofp_port_no = ofp_port_no
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050053 self._entity_id = None
54 self._mac_bridge_port_num = 0
55 self._type = type
56 self._uni_id = uni_id
Girish Gowdra5b499342020-06-16 14:45:51 -070057 self._parent_port_no = parent_port_no
58 self._serial_num = device_serial_number
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050059
Matt Jeanneretf4113222019-08-14 19:44:34 -040060 self._admin_state = AdminState.DISABLED
61 self._oper_status = OperStatus.DISCOVERED
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050062
63 def __str__(self):
Matt Jeanneretf4113222019-08-14 19:44:34 -040064 return "UniPort - name: {}, port_number: {}, admin_state: {}, oper_state: {}, entity_id: {}, " \
Girish Gowdra5b499342020-06-16 14:45:51 -070065 "mac_bridge_port_num: {}, type: {}, ofp_port: {}" \
Matt Jeanneretf4113222019-08-14 19:44:34 -040066 .format(self.name, self.port_number, self.adminstate, self.operstatus, self.entity_id,
67 self._mac_bridge_port_num, self.type, self._ofp_port_no)
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050068
69 def __repr__(self):
70 return str(self)
71
72 @staticmethod
Girish Gowdra5b499342020-06-16 14:45:51 -070073 def create(handler, name, uni_id, port_no, ofp_port_no,
74 parent_port_no, device_serial_number, type):
75 port = UniPort(handler, name, uni_id, port_no, ofp_port_no,
76 parent_port_no, device_serial_number, type)
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050077 return port
78
79 def _start(self):
80 self._cancel_deferred()
81 self._admin_state = AdminState.ENABLED
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050082
83 def _stop(self):
84 self._cancel_deferred()
85 self._admin_state = AdminState.DISABLED
86 self._oper_status = OperStatus.UNKNOWN
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -050087
88 def delete(self):
89 self.enabled = False
90 self._handler = None
91
92 def _cancel_deferred(self):
93 pass
94
95 @property
Matt Jeanneretf4113222019-08-14 19:44:34 -040096 def adminstate(self):
97 return self._admin_state
98
99 @adminstate.setter
100 def adminstate(self, value):
101 self._admin_state = value
102
103 @property
104 def operstatus(self):
105 return self._oper_status
106
107 @operstatus.setter
108 def operstatus(self, value):
109 self._oper_status = value
110
111 @property
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500112 def name(self):
113 return self._name
114
115 @property
116 def enabled(self):
117 return self._enabled
118
119 @enabled.setter
120 def enabled(self, value):
121 if self._enabled != value:
122 self._enabled = value
123
124 if value:
125 self._start()
126 else:
127 self._stop()
128
129 @property
130 def uni_id(self):
131 """
132 Physical prt index on ONU 0 - N
133 :return: (int) uni id
134 """
135 return self._uni_id
136
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500137 @property
138 def mac_bridge_port_num(self):
139 """
140 Port number used when creating MacBridgePortConfigurationDataFrame port number
141 :return: (int) port number
142 """
143 return self._mac_bridge_port_num
144
145 @mac_bridge_port_num.setter
146 def mac_bridge_port_num(self, value):
147 self._mac_bridge_port_num = value
148
149 @property
150 def port_number(self):
151 """
152 Physical device port number
153 :return: (int) port number
154 """
155 return self._port_number
156
157 @property
158 def entity_id(self):
159 """
160 OMCI UNI_G entity ID for port
161 """
162 return self._entity_id
163
164 @entity_id.setter
165 def entity_id(self, value):
166 assert self._entity_id is None, 'Cannot reset the Entity ID'
167 self._entity_id = value
168
169 @property
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500170 def type(self):
171 """
172 UNI Type used in OMCI messaging
173 :return: (UniType) One of the enumerated types
174 """
175 return self._type
176
Girish Gowdra5b499342020-06-16 14:45:51 -0700177 @property
178 def parent_port_no(self):
179 """
180 Parent port number for this ONU - will be the PON port of the OLT
181 where this ONU is connected
182 """
183 return self._parent_port_no
184
185 @property
186 def serial_number(self):
187 """
188 Serial number of the ONU
189 """
190 return self._serial_num
191
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500192 def get_port(self):
193 """
194 Get the VOLTHA PORT object for this port
195 :return: VOLTHA Port object
196 """
Girish Gowdra5b499342020-06-16 14:45:51 -0700197
198 cap = OFPPF_1GB_FD | OFPPF_FIBER
199
200 hw_addr = mac_str_to_tuple('08:%02x:%02x:%02x:%02x:%02x' %
201 ((self.parent_port_no >> 8 & 0xff),
202 self.parent_port_no & 0xff,
203 (self.port_number >> 16) & 0xff,
204 (self.port_number >> 8) & 0xff,
205 self.port_number & 0xff))
206
207 name = self.serial_number + '-' + str(self.mac_bridge_port_num)
208
209 ofstate = OFPPS_LINK_DOWN
210 if self.operstatus is OperStatus.ACTIVE:
211 ofstate = OFPPS_LIVE
212
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500213 self._port = Port(port_no=self.port_number,
214 label=self.port_id_name(),
215 type=Port.ETHERNET_UNI,
216 admin_state=self._admin_state,
Girish Gowdra5b499342020-06-16 14:45:51 -0700217 oper_status=self._oper_status,
218 ofp_port=ofp_port(
219 name=name,
220 hw_addr=hw_addr,
221 config=0,
222 state=ofstate,
223 curr=cap,
224 advertised=cap,
225 peer=cap,
226 curr_speed=OFPPF_1GB_FD,
227 max_speed=OFPPF_1GB_FD
228 ))
Matt Jeanneretf1e9c5d2019-02-08 07:41:29 -0500229 return self._port
230
231 def port_id_name(self):
232 return 'uni-{}'.format(self._port_number)