blob: 473e2f652d7e55bac07288ac5884fbe259e89161 [file] [log] [blame]
Chip Bolingf5af85d2019-02-12 15:36:17 -06001# Copyright 2017-present Adtran, Inc.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import structlog
16
17log = structlog.get_logger()
18
19
20class OltConfig(object):
21 """
22 Class to wrap decode of olt container (config) from the ADTRAN
23 gpon-olt-hw.yang YANG model
24 """
25 def __init__(self, packet):
26 self._packet = packet
27 self._pons = None
28
29 def __str__(self):
30 return "OltConfig: {}".format(self.olt_id)
31
32 @property
33 def olt_id(self):
34 """Unique OLT identifier"""
35 return self._packet.get('olt-id', '')
36
37 @property
38 def debug_output(self):
39 """least important level that will output everything"""
40 return self._packet.get('debug-output', 'warning')
41
42 @property
43 def pons(self):
44 if self._pons is None:
45 self._pons = OltConfig.Pon.decode(self._packet.get('pon', None))
46 return self._pons
47
48 class Pon(object):
49 """
50 Provides decode of PON list from within
51 """
52 def __init__(self, packet):
53 assert 'pon-id' in packet, 'pon-id not found'
54 self._packet = packet
55 self._onus = None
56
57 def __str__(self):
58 return "OltConfig.Pon: pon-id: {}".format(self.pon_id)
59
60 @staticmethod
61 def decode(pon_list):
62 pons = {}
63
64 if pon_list is not None:
65 for pon_data in pon_list:
66 pon = OltConfig.Pon(pon_data)
67 assert pon.pon_id not in pons
68 pons[pon.pon_id] = pon
69
70 return pons
71
72 @property
73 def pon_id(self):
74 """PON identifier"""
75 return self._packet['pon-id']
76
77 @property
78 def enabled(self):
79 """The desired state of the interface"""
80 return self._packet.get('enabled', False)
81
82 @property
83 def downstream_fec_enable(self):
84 """Enables downstream Forward Error Correction"""
85 return self._packet.get('downstream-fec-enable', False)
86
87 @property
88 def upstream_fec_enable(self):
89 """Enables upstream Forward Error Correction"""
90 return self._packet.get('upstream-fec-enable', False)
91
92 @property
93 def deployment_range(self):
94 """Maximum deployment distance (meters)"""
95 return self._packet.get('deployment-range', 25000)
96
97 @property
98 def onus(self):
99 if self._onus is None:
100 self._onus = OltConfig.Pon.Onu.decode(self._packet.get('onus', None))
101 return self._onus
102
103 class Onu(object):
104 """
105 Provides decode of onu list for a PON port
106 """
107 def __init__(self, packet):
108 assert 'onu-id' in packet, 'onu-id not found'
109 self._packet = packet
110 self._tconts = None
111 self._tconts_dict = None
112 self._gem_ports = None
113 self._gem_ports_dict = None
114
115 def __str__(self):
116 return "OltConfig.Pon.Onu: onu-id: {}".format(self.onu_id)
117
118 @staticmethod
119 def decode(onu_dict):
120 onus = {}
121
122 if onu_dict is not None:
123 if 'onu' in onu_dict:
124 for onu_data in onu_dict['onu']:
125 onu = OltConfig.Pon.Onu(onu_data)
126 assert onu.onu_id not in onus
127 onus[onu.onu_id] = onu
128 elif len(onu_dict) > 0 and 'onu-id' in onu_dict[0]:
129 onu = OltConfig.Pon.Onu(onu_dict[0])
130 assert onu.onu_id not in onus
131 onus[onu.onu_id] = onu
132
133 return onus
134
135 @property
136 def onu_id(self):
137 """The ID used to identify the ONU"""
138 return self._packet['onu-id']
139
140 @property
141 def serial_number_64(self):
142 """The serial number (base-64) is unique for each ONU"""
143 return self._packet.get('serial-number', '')
144
145 @property
146 def password(self):
147 """ONU Password"""
148 return self._packet.get('password', bytes(0))
149
150 @property
151 def enable(self):
152 """If true, places the ONU in service"""
153 return self._packet.get('enable', False)
154
155 @property
156 def tconts(self):
157 if self._tconts is None:
158 self._tconts = OltConfig.Pon.Onu.TCont.decode(self._packet.get('t-conts', None))
159 return self._tconts
160
161 @property
162 def tconts_dict(self): # TODO: Remove if not used
163 if self._tconts_dict is None:
164 self._tconts_dict = {tcont.alloc_id: tcont for tcont in self.tconts}
165 return self._tconts_dict
166
167 @property
168 def gem_ports(self):
169 if self._gem_ports is None:
170 self._gem_ports = OltConfig.Pon.Onu.GemPort.decode(self._packet.get('gem-ports', None))
171 return self._gem_ports
172
173 @property
174 def gem_ports_dict(self): # TODO: Remove if not used
175 if self._gem_ports_dict is None:
176 self._gem_ports_dict = {gem.gem_id: gem for gem in self.gem_ports}
177 return self._gem_ports_dict
178
179 class TCont(object):
180 """
181 Provides decode of onu list for the T-CONT container
182 """
183 def __init__(self, packet):
184 assert 'alloc-id' in packet, 'alloc-id not found'
185 self._packet = packet
186 self._traffic_descriptor = None
187 self._best_effort = None
188
189 def __str__(self):
190 return "OltConfig.Pon.Onu.TCont: alloc-id: {}".format(self.alloc_id)
191
192 @staticmethod
193 def decode(tcont_container):
194 tconts = {}
195
196 if tcont_container is not None:
197 for tcont_data in tcont_container.get('t-cont', []):
198 tcont = OltConfig.Pon.Onu.TCont(tcont_data)
199 assert tcont.alloc_id not in tconts
200 tconts[tcont.alloc_id] = tcont
201
202 return tconts
203
204 @property
205 def alloc_id(self):
206 """The ID used to identify the T-CONT"""
207 return self._packet['alloc-id']
208
209 @property
210 def traffic_descriptor(self):
211 """
212 Each Alloc-ID is provisioned with a traffic descriptor that specifies
213 the three bandwidth component parameters: fixed bandwidth, assured
214 bandwidth, and maximum bandwidth, as well as the ternary eligibility
215 indicator for additional bandwidth assignment
216 """
217 if self._traffic_descriptor is None and 'traffic-descriptor' in self._packet:
218 self._traffic_descriptor = OltConfig.Pon.Onu.TCont.\
219 TrafficDescriptor(self._packet['traffic-descriptor'])
220 return self._traffic_descriptor
221
222 class TrafficDescriptor(object):
223 def __init__(self, packet):
224 self._packet = packet
225
226 def __str__(self):
227 return "OltConfig.Pon.Onu.TCont.TrafficDescriptor: {}/{}/{}".\
228 format(self.fixed_bandwidth, self.assured_bandwidth,
229 self.maximum_bandwidth)
230
231 @property
232 def fixed_bandwidth(self):
233 try:
234 return int(self._packet.get('fixed-bandwidth', 0))
235 except:
236 return 0
237
238 @property
239 def assured_bandwidth(self):
240 try:
241 return int(self._packet.get('assured-bandwidth', 0))
242 except:
243 return 0
244
245 @property
246 def maximum_bandwidth(self):
247 try:
248 return int(self._packet.get('maximum-bandwidth', 0))
249 except:
250 return 0
251
252 @property
253 def additional_bandwidth_eligibility(self):
254 return self._packet.get('additional-bandwidth-eligibility', 'none')
255
256 @property
257 def best_effort(self):
258 if self._best_effort is None:
259 self._best_effort = OltConfig.Pon.Onu.TCont.BestEffort.decode(
260 self._packet.get('best-effort', None))
261 return self._best_effort
262
263 class BestEffort(object):
264 def __init__(self, packet):
265 self._packet = packet
266
267 def __str__(self):
268 return "OltConfig.Pon.Onu.TCont.BestEffort: {}".format(self.bandwidth)
269
270 @property
271 def bandwidth(self):
272 return self._packet['bandwidth']
273
274 @property
275 def priority(self):
276 return self._packet['priority']
277
278 @property
279 def weight(self):
280 return self._packet['weight']
281
282 class GemPort(object):
283 """
284 Provides decode of onu list for the gem-ports container
285 """
286 def __init__(self, packet):
287 assert 'port-id' in packet, 'port-id not found'
288 self._packet = packet
289
290 def __str__(self):
291 return "OltConfig.Pon.Onu.GemPort: port-id: {}/{}".\
292 format(self.port_id, self.alloc_id)
293
294 @staticmethod
295 def decode(gem_port_container):
296 gem_ports = {}
297
298 if gem_port_container is not None:
299 for gem_port_data in gem_port_container.get('gem-port', []):
300 gem_port = OltConfig.Pon.Onu.GemPort(gem_port_data)
301 assert gem_port.port_id not in gem_ports
302 gem_ports[gem_port.port_id] = gem_port
303
304 return gem_ports
305
306 @property
307 def port_id(self):
308 """The ID used to identify the GEM Port"""
309 return self._packet['port-id']
310
311 @property
312 def gem_id(self):
313 """The ID used to identify the GEM Port"""
314 return self.port_id
315
316 @property
317 def alloc_id(self):
318 """The Alloc-ID of the T-CONT to which this GEM port is mapped"""
319 return self._packet['alloc-id']
320
321 @property
322 def omci_transport(self):
323 """If true, this GEM port is used to transport the OMCI virtual connection"""
324 return self._packet.get('omci-transport', False)
325
326 @property
327 def encryption(self):
328 """If true, enable encryption using the advanced encryption standard(AES)"""
329 return self._packet.get('encryption', False)