blob: bb5b5338eaf4a930f8912052d479babebcdb4924 [file] [log] [blame]
Zsolt Haraszti656ecc62016-12-28 15:08:23 -08001#
Zsolt Haraszti3eb27a52017-01-03 21:56:48 -08002# Copyright 2017 the original author or authors.
Zsolt Haraszti656ecc62016-12-28 15:08:23 -08003#
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#
16
17"""
18Fully simulated OLT/ONU adapter.
19"""
Nikolay Titov176f1db2017-08-10 12:38:43 -040020import sys
Zsolt Haraszti656ecc62016-12-28 15:08:23 -080021from uuid import uuid4
22
Sergio Slobodrian98eff412017-03-15 14:46:30 -040023import arrow
Zsolt Haraszti656ecc62016-12-28 15:08:23 -080024import grpc
Stephane Barbarie4475a252017-03-31 13:49:20 -040025import json
Zsolt Haraszti656ecc62016-12-28 15:08:23 -080026import structlog
27from scapy.layers.l2 import Ether, Dot1Q
Stephane Barbarie4475a252017-03-31 13:49:20 -040028from scapy.layers.inet import Raw
Khen Nursimulud068d812017-03-06 11:44:18 -050029from twisted.internet.defer import inlineCallbacks
Zsolt Haraszti656ecc62016-12-28 15:08:23 -080030
31from common.frameio.frameio import BpfProgramFilter, hexify
Khen Nursimulud068d812017-03-06 11:44:18 -050032from common.utils.asleep import asleep
Sergio Slobodrian98eff412017-03-15 14:46:30 -040033from twisted.internet.task import LoopingCall
Shad Ansarid1aa9e72017-06-23 21:34:25 -070034from voltha.adapters.iadapter import OltAdapter
Zsolt Haraszti656ecc62016-12-28 15:08:23 -080035from voltha.core.logical_device_agent import mac_str_to_tuple
36from voltha.protos import third_party
37from voltha.protos import ponsim_pb2
Shad Ansari14bcd992017-06-13 14:27:20 -070038from voltha.protos.common_pb2 import OperStatus, ConnectStatus, AdminState
39from voltha.protos.device_pb2 import Port, Device, PmConfig, PmConfigs
Sergio Slobodrian98eff412017-03-15 14:46:30 -040040from voltha.protos.events_pb2 import KpiEvent, KpiEventType, MetricValuePairs
Zsolt Haraszti656ecc62016-12-28 15:08:23 -080041from google.protobuf.empty_pb2 import Empty
42
43from voltha.protos.logical_device_pb2 import LogicalPort, LogicalDevice
Stephane Barbarie5253c652017-03-22 16:29:46 -040044from voltha.protos.openflow_13_pb2 import OFPPS_LIVE, OFPPF_FIBER, \
45 OFPPF_1GB_FD, \
Zsolt Haraszti656ecc62016-12-28 15:08:23 -080046 OFPC_GROUP_STATS, OFPC_PORT_STATS, OFPC_TABLE_STATS, OFPC_FLOW_STATS, \
47 ofp_switch_features, ofp_desc
48from voltha.protos.openflow_13_pb2 import ofp_port
49from voltha.protos.ponsim_pb2 import FlowTable
50from voltha.registry import registry
51
Nikolay Titov89004ec2017-06-19 18:22:42 -040052from voltha.protos.bbf_fiber_base_pb2 import \
Nikolay Titov176f1db2017-08-10 12:38:43 -040053 ChannelgroupConfig, ChannelpartitionConfig, ChannelpairConfig,\
54 ChannelterminationConfig, OntaniConfig, VOntaniConfig, VEnetConfig
55from voltha.protos.bbf_fiber_traffic_descriptor_profile_body_pb2 import \
56 TrafficDescriptorProfileData
57from voltha.protos.bbf_fiber_tcont_body_pb2 import TcontsConfigData
58from voltha.protos.bbf_fiber_gemport_body_pb2 import GemportsConfigData
59from voltha.protos.bbf_fiber_multicast_gemport_body_pb2 import \
60 MulticastGemportsConfigData
61from voltha.protos.bbf_fiber_multicast_distribution_set_body_pb2 import \
62 MulticastDistributionSetData
Nikolay Titov89004ec2017-06-19 18:22:42 -040063
Nikolay Titov176f1db2017-08-10 12:38:43 -040064from voltha.protos.ponsim_pb2 import InterfaceConfig, TcontInterfaceConfig
Nikolay Titov89004ec2017-06-19 18:22:42 -040065
Zsolt Haraszti656ecc62016-12-28 15:08:23 -080066_ = third_party
67log = structlog.get_logger()
68
Zsolt Haraszti656ecc62016-12-28 15:08:23 -080069PACKET_IN_VLAN = 4000
70is_inband_frame = BpfProgramFilter('(ether[14:2] & 0xfff) = 0x{:03x}'.format(
71 PACKET_IN_VLAN))
72
Stephane Barbarie5253c652017-03-22 16:29:46 -040073
Sergio Slobodrian98eff412017-03-15 14:46:30 -040074class AdapterPmMetrics:
Stephane Barbarie5253c652017-03-22 16:29:46 -040075 def __init__(self, device):
Sergio Slobodrianec6e3912017-04-02 11:46:55 -040076 self.pm_names = {'tx_64_pkts', 'tx_65_127_pkts', 'tx_128_255_pkts',
77 'tx_256_511_pkts', 'tx_512_1023_pkts',
78 'tx_1024_1518_pkts', 'tx_1519_9k_pkts',
79 'rx_64_pkts', 'rx_65_127_pkts',
80 'rx_128_255_pkts', 'rx_256_511_pkts',
81 'rx_512_1023_pkts', 'rx_1024_1518_pkts',
82 'rx_1519_9k_pkts'}
Sergio Slobodrian98eff412017-03-15 14:46:30 -040083 self.device = device
84 self.id = device.id
85 self.name = 'ponsim_olt'
Stephane Barbarie5253c652017-03-22 16:29:46 -040086 # self.id = "abc"
Sergio Slobodrian98eff412017-03-15 14:46:30 -040087 self.default_freq = 150
88 self.grouped = False
89 self.freq_override = False
90 self.pon_metrics_config = dict()
91 self.nni_metrics_config = dict()
92 self.lc = None
93 for m in self.pm_names:
94 self.pon_metrics_config[m] = PmConfig(name=m,
95 type=PmConfig.COUNTER,
96 enabled=True)
97 self.nni_metrics_config[m] = PmConfig(name=m,
98 type=PmConfig.COUNTER,
99 enabled=True)
100
101 def update(self, pm_config):
102 if self.default_freq != pm_config.default_freq:
103 # Update the callback to the new frequency.
104 self.default_freq = pm_config.default_freq
105 self.lc.stop()
Stephane Barbarie5253c652017-03-22 16:29:46 -0400106 self.lc.start(interval=self.default_freq / 10)
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400107 for m in pm_config.metrics:
108 self.pon_metrics_config[m.name].enabled = m.enabled
109 self.nni_metrics_config[m.name].enabled = m.enabled
110
111 def make_proto(self):
112 pm_config = PmConfigs(
113 id=self.id,
114 default_freq=self.default_freq,
Stephane Barbarie5253c652017-03-22 16:29:46 -0400115 grouped=False,
116 freq_override=False)
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400117 for m in sorted(self.pon_metrics_config):
Stephane Barbarie5253c652017-03-22 16:29:46 -0400118 pm = self.pon_metrics_config[m] # Either will do they're the same
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400119 pm_config.metrics.extend([PmConfig(name=pm.name,
120 type=pm.type,
121 enabled=pm.enabled)])
122 return pm_config
123
124 def collect_port_metrics(self, channel):
125 rtrn_port_metrics = dict()
126 stub = ponsim_pb2.PonSimStub(channel)
127 stats = stub.GetStats(Empty())
128 rtrn_port_metrics['pon'] = self.extract_pon_metrics(stats)
129 rtrn_port_metrics['nni'] = self.extract_nni_metrics(stats)
130 return rtrn_port_metrics
131
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400132 def extract_pon_metrics(self, stats):
133 rtrn_pon_metrics = dict()
134 for m in stats.metrics:
135 if m.port_name == "pon":
136 for p in m.packets:
137 if self.pon_metrics_config[p.name].enabled:
138 rtrn_pon_metrics[p.name] = p.value
139 return rtrn_pon_metrics
140
141 def extract_nni_metrics(self, stats):
142 rtrn_pon_metrics = dict()
143 for m in stats.metrics:
144 if m.port_name == "nni":
145 for p in m.packets:
146 if self.pon_metrics_config[p.name].enabled:
147 rtrn_pon_metrics[p.name] = p.value
148 return rtrn_pon_metrics
149
150 def start_collector(self, callback):
151 log.info("starting-pm-collection", device_name=self.name,
152 device_id=self.device.id)
153 prefix = 'voltha.{}.{}'.format(self.name, self.device.id)
154 self.lc = LoopingCall(callback, self.device.id, prefix)
Stephane Barbarie5253c652017-03-22 16:29:46 -0400155 self.lc.start(interval=self.default_freq / 10)
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400156
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800157
Stephane Barbarie4475a252017-03-31 13:49:20 -0400158class AdapterAlarms:
159 def __init__(self, adapter, device):
160 self.adapter = adapter
161 self.device = device
162 self.lc = None
163
164 def send_alarm(self, context_data, alarm_data):
165 try:
166 current_context = {}
167 for key, value in context_data.__dict__.items():
168 current_context[key] = str(value)
169
170 alarm_event = self.adapter.adapter_agent.create_alarm(
171 resource_id=self.device.id,
khenaidoo032d3302017-06-09 14:50:04 -0400172 description="{}.{} - {}".format(self.adapter.name,
173 self.device.id,
174 alarm_data[
175 'description']) if 'description' in alarm_data else None,
Stephane Barbarie4475a252017-03-31 13:49:20 -0400176 type=alarm_data['type'] if 'type' in alarm_data else None,
khenaidoo032d3302017-06-09 14:50:04 -0400177 category=alarm_data[
178 'category'] if 'category' in alarm_data else None,
179 severity=alarm_data[
180 'severity'] if 'severity' in alarm_data else None,
Stephane Barbarie4475a252017-03-31 13:49:20 -0400181 state=alarm_data['state'] if 'state' in alarm_data else None,
182 raised_ts=alarm_data['ts'] if 'ts' in alarm_data else 0,
183 context=current_context
184 )
185
khenaidoo032d3302017-06-09 14:50:04 -0400186 self.adapter.adapter_agent.submit_alarm(self.device.id,
187 alarm_event)
Stephane Barbarie4475a252017-03-31 13:49:20 -0400188
189 except Exception as e:
190 log.exception('failed-to-send-alarm', e=e)
191
Shad Ansarid1aa9e72017-06-23 21:34:25 -0700192class PonSimOltAdapter(OltAdapter):
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800193 def __init__(self, adapter_agent, config):
Shad Ansari14bcd992017-06-13 14:27:20 -0700194 super(PonSimOltAdapter, self).__init__(adapter_agent=adapter_agent,
195 config=config,
Shad Ansari96f817b2017-06-18 23:17:44 -0700196 device_handler_class=PonSimOltHandler,
Shad Ansari14bcd992017-06-13 14:27:20 -0700197 name='ponsim_olt',
198 vendor='Voltha project',
Nikolay Titov89004ec2017-06-19 18:22:42 -0400199 version='0.4',
200 device_type='ponsim_olt')
Shad Ansari96f817b2017-06-18 23:17:44 -0700201
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400202 def update_pm_config(self, device, pm_config):
Stephane Barbarie5253c652017-03-22 16:29:46 -0400203 log.info("adapter-update-pm-config", device=device,
204 pm_config=pm_config)
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400205 handler = self.devices_handlers[device.id]
206 handler.update_pm_config(device, pm_config)
Sergio Slobodrianec864c62017-03-09 11:41:43 -0500207
Nikolay Titov89004ec2017-06-19 18:22:42 -0400208 def create_interface(self, device, data):
Nikolay Titov4e1c3702017-08-23 12:41:57 -0400209 if super(PonSimOltAdapter, self)._get_handler(device):
210 log.info('create-interface', device_id=device.id)
211 self.devices_handlers[device.id].create_interface(data)
Nikolay Titov89004ec2017-06-19 18:22:42 -0400212
213 def update_interface(self, device, data):
Nikolay Titov4e1c3702017-08-23 12:41:57 -0400214 if super(PonSimOltAdapter, self)._get_handler(device):
215 log.info('update-interface', device_id=device.id)
216 self.devices_handlers[device.id].update_interface(data)
Nikolay Titov89004ec2017-06-19 18:22:42 -0400217
218 def remove_interface(self, device, data):
Nikolay Titov4e1c3702017-08-23 12:41:57 -0400219 if super(PonSimOltAdapter, self)._get_handler(device):
220 log.info('remove-interface', device_id=device.id)
221 self.devices_handlers[device.id].remove_interface(data)
Nikolay Titov89004ec2017-06-19 18:22:42 -0400222
Nikolay Titov176f1db2017-08-10 12:38:43 -0400223 def create_tcont(self, device, tcont_data, traffic_descriptor_data):
Nikolay Titov4e1c3702017-08-23 12:41:57 -0400224 if super(PonSimOltAdapter, self)._get_handler(device):
225 log.info('create-tcont', device_id=device.id)
226 self.devices_handlers[device.id].create_tcont(
227 tcont_data, traffic_descriptor_data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400228
229 def update_tcont(self, device, tcont_data, traffic_descriptor_data):
Nikolay Titov4e1c3702017-08-23 12:41:57 -0400230 if super(PonSimOltAdapter, self)._get_handler(device):
231 log.info('update-tcont', device_id=device.id)
232 self.devices_handlers[device.id].update_tcont(
233 tcont_data, traffic_descriptor_data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400234
235 def remove_tcont(self, device, tcont_data, traffic_descriptor_data):
Nikolay Titov4e1c3702017-08-23 12:41:57 -0400236 if super(PonSimOltAdapter, self)._get_handler(device):
237 log.info('remove-tcont', device_id=device.id)
238 self.devices_handlers[device.id].remove_tcont(
239 tcont_data, traffic_descriptor_data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400240
241 def create_gemport(self, device, data):
Nikolay Titov4e1c3702017-08-23 12:41:57 -0400242 if super(PonSimOltAdapter, self)._get_handler(device):
243 log.info('create-gemport', device_id=device.id)
244 self.devices_handlers[device.id].create_gemport(data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400245
246 def update_gemport(self, device, data):
Nikolay Titov4e1c3702017-08-23 12:41:57 -0400247 if super(PonSimOltAdapter, self)._get_handler(device):
248 log.info('update-gemport', device_id=device.id)
249 self.devices_handlers[device.id].update_gemport(data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400250
251 def remove_gemport(self, device, data):
Nikolay Titov4e1c3702017-08-23 12:41:57 -0400252 if super(PonSimOltAdapter, self)._get_handler(device):
253 log.info('remove-gemport', device_id=device.id)
254 self.devices_handlers[device.id].remove_gemport(data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400255
256 def create_multicast_gemport(self, device, data):
Nikolay Titov4e1c3702017-08-23 12:41:57 -0400257 if super(PonSimOltAdapter, self)._get_handler(device):
258 log.info('create-multicast-gemport', device_id=device.id)
259 self.devices_handlers[device.id].create_multicast_gemport(data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400260
261 def update_multicast_gemport(self, device, data):
Nikolay Titov4e1c3702017-08-23 12:41:57 -0400262 if super(PonSimOltAdapter, self)._get_handler(device):
263 log.info('update-multicast-gemport', device_id=device.id)
264 self.devices_handlers[device.id].update_multicast_gemport(data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400265
266 def remove_multicast_gemport(self, device, data):
Nikolay Titov4e1c3702017-08-23 12:41:57 -0400267 if super(PonSimOltAdapter, self)._get_handler(device):
268 log.info('remove-multicast-gemport', device_id=device.id)
269 self.devices_handlers[device.id].remove_multicast_gemport(data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400270
271 def create_multicast_distribution_set(self, device, data):
Nikolay Titov4e1c3702017-08-23 12:41:57 -0400272 if super(PonSimOltAdapter, self)._get_handler(device):
273 log.info('create-multicast-distribution-set', device_id=device.id)
274 self.devices_handlers[device.id].create_multicast_distribution_set(
275 data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400276
277 def update_multicast_distribution_set(self, device, data):
Nikolay Titov4e1c3702017-08-23 12:41:57 -0400278 if super(PonSimOltAdapter, self)._get_handler(device):
279 log.info('update-multicast-distribution-set', device_id=device.id)
280 self.devices_handlers[device.id].update_multicast_distribution_set(
281 data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400282
283 def remove_multicast_distribution_set(self, device, data):
Nikolay Titov4e1c3702017-08-23 12:41:57 -0400284 if super(PonSimOltAdapter, self)._get_handler(device):
285 log.info('remove-multicast-distribution-set', device_id=device.id)
286 self.devices_handlers[device.id].remove_multicast_distribution_set(
287 data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400288
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800289class PonSimOltHandler(object):
Nikolay Titov176f1db2017-08-10 12:38:43 -0400290 xpon_ponsim_olt_itfs = {
291 'create_interface': {
292 'method_name': 'CreateInterface',
293 'log': 'create-interface'},
294 'update_interface': {
295 'method_name': 'UpdateInterface',
296 'log': 'update-interface'},
297 'remove_interface': {
298 'method_name': 'RemoveInterface',
299 'log': 'remove-interface'},
300 'create_tcont': {
301 'method_name': 'CreateTcont',
302 'log': 'create-tconts-config-data'},
303 'update_tcont': {
304 'method_name': 'UpdateTcont',
305 'log': 'update-tconts-config-data'},
306 'remove_tcont': {
307 'method_name': 'RemoveTcont',
308 'log': 'remove-tconts-config-data'},
309 'create_gemport': {
310 'method_name': 'CreateGemport',
311 'log': 'create-gemports-config-data'},
312 'update_gemport': {
313 'method_name': 'UpdateGemport',
314 'log': 'update-gemports-config-data'},
315 'remove_gemport': {
316 'method_name': 'RemoveGemport',
317 'log': 'remove-gemports-config-data'},
318 'create_multicast_gemport': {
319 'method_name': 'CreateMulticastGemport',
320 'log': 'create-multicast-gemports-config-data'},
321 'update_multicast_gemport': {
322 'method_name': 'UpdateMulticastGemport',
323 'log': 'update-multicast-gemports-config-data'},
324 'remove_multicast_gemport': {
325 'method_name': 'RemoveMulticastGemport',
326 'log': 'remove-multicast-gemports-config-data'},
327 'create_multicast_distribution_set': {
328 'method_name': 'CreateMulticastDistributionSet',
329 'log': 'create-multicast-distribution-set-data'},
330 'update_multicast_distribution_set': {
331 'method_name': 'UpdateMulticastDistributionSet',
332 'log': 'update-multicast-distribution-set-data'},
333 'remove_multicast_distribution_set': {
334 'method_name': 'RemoveMulticastDistributionSet',
335 'log': 'remove-multicast-distribution-set-data'},
336 }
337
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800338 def __init__(self, adapter, device_id):
339 self.adapter = adapter
340 self.adapter_agent = adapter.adapter_agent
341 self.device_id = device_id
342 self.log = structlog.get_logger(device_id=device_id)
343 self.channel = None
344 self.io_port = None
345 self.logical_device_id = None
Khen Nursimulud068d812017-03-06 11:44:18 -0500346 self.nni_port = None
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400347 self.ofp_port_no = None
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800348 self.interface = registry('main').get_args().interface
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400349 self.pm_metrics = None
Stephane Barbarie4475a252017-03-31 13:49:20 -0400350 self.alarms = None
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800351
352 def __del__(self):
353 if self.io_port is not None:
Zsolt Haraszti3e6f0892017-01-19 11:51:40 -0800354 registry('frameio').close_port(self.io_port)
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800355
356 def get_channel(self):
357 if self.channel is None:
358 device = self.adapter_agent.get_device(self.device_id)
schowdhury9e247752017-07-14 06:56:20 -0700359
360 # read in certificate
361 try:
362 with open('/voltha/pki/voltha-CA.pem') as f:
363 trusted_certs = f.read()
364
365 with open('/voltha/pki/voltha.crt') as f:
366 client_cert = f.read()
367
368 with open('/voltha/pki/voltha.key') as f:
369 client_key = f.read()
370 except Exception as e:
371 log.error('failed-to-read-cert-keys', reason=e)
372
373 # create credentials
374 credentials = grpc.ssl_channel_credentials( root_certificates=trusted_certs, private_key=client_key, certificate_chain=client_cert)
375
376 # create channel using ssl credentials
377 my_server_host_override_string = "ABCD" # Server's CN Name, Ugly but no other Choice.
378 self.channel = grpc.secure_channel(device.host_and_port, credentials, options=(('grpc.ssl_target_name_override', my_server_host_override_string,),))
379
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800380 return self.channel
381
khenaidoo032d3302017-06-09 14:50:04 -0400382 def _get_nni_port(self):
383 ports = self.adapter_agent.get_ports(self.device_id, Port.ETHERNET_NNI)
384 if ports:
385 # For now, we use on one NNI port
386 return ports[0]
387
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800388 def activate(self, device):
389 self.log.info('activating')
390
391 if not device.host_and_port:
392 device.oper_status = OperStatus.FAILED
393 device.reason = 'No host_and_port field provided'
394 self.adapter_agent.update_device(device)
395 return
396
397 stub = ponsim_pb2.PonSimStub(self.get_channel())
398 info = stub.GetDeviceInfo(Empty())
399 log.info('got-info', info=info)
400
401 device.root = True
402 device.vendor = 'ponsim'
Stephane Barbarie5253c652017-03-22 16:29:46 -0400403 device.model = 'n/a'
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800404 device.serial_number = device.host_and_port
405 device.connect_status = ConnectStatus.REACHABLE
406 self.adapter_agent.update_device(device)
407
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400408 # Now set the initial PM configuration for this device
Stephane Barbarie5253c652017-03-22 16:29:46 -0400409 self.pm_metrics = AdapterPmMetrics(device)
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400410 pm_config = self.pm_metrics.make_proto()
411 log.info("initial-pm-config", pm_config=pm_config)
Stephane Barbarie5253c652017-03-22 16:29:46 -0400412 self.adapter_agent.update_device_pm_config(pm_config, init=True)
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400413
Stephane Barbarie4475a252017-03-31 13:49:20 -0400414 # Setup alarm handler
415 self.alarms = AdapterAlarms(self.adapter, device)
416
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800417 nni_port = Port(
418 port_no=2,
419 label='NNI facing Ethernet port',
420 type=Port.ETHERNET_NNI,
421 admin_state=AdminState.ENABLED,
422 oper_status=OperStatus.ACTIVE
423 )
Khen Nursimulud068d812017-03-06 11:44:18 -0500424 self.nni_port = nni_port
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800425 self.adapter_agent.add_port(device.id, nni_port)
426 self.adapter_agent.add_port(device.id, Port(
427 port_no=1,
428 label='PON port',
429 type=Port.PON_OLT,
430 admin_state=AdminState.ENABLED,
431 oper_status=OperStatus.ACTIVE
432 ))
433
434 ld = LogicalDevice(
khenaidoo507d9222017-10-10 16:23:49 -0400435 # not setting id and datapath_id. Adapter agent will pick the id
436 # and will pick the datapath_id is it is not provided
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800437 desc=ofp_desc(
438 mfr_desc='cord porject',
439 hw_desc='simualted pon',
440 sw_desc='simualted pon',
441 serial_num=uuid4().hex,
442 dp_desc='n/a'
443 ),
444 switch_features=ofp_switch_features(
445 n_buffers=256, # TODO fake for now
446 n_tables=2, # TODO ditto
447 capabilities=( # TODO and ditto
448 OFPC_FLOW_STATS
449 | OFPC_TABLE_STATS
450 | OFPC_PORT_STATS
451 | OFPC_GROUP_STATS
452 )
453 ),
454 root_device_id=device.id
455 )
khenaidoo507d9222017-10-10 16:23:49 -0400456 mac_address = "AA:BB:CC:DD:EE:FF"
457 ld_initialized = self.adapter_agent.create_logical_device(ld,
458 dpid=mac_address)
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800459 cap = OFPPF_1GB_FD | OFPPF_FIBER
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400460 self.ofp_port_no = info.nni_port
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800461 self.adapter_agent.add_logical_port(ld_initialized.id, LogicalPort(
462 id='nni',
463 ofp_port=ofp_port(
464 port_no=info.nni_port,
Stephane Barbarie5253c652017-03-22 16:29:46 -0400465 hw_addr=mac_str_to_tuple(
466 '00:00:00:00:00:%02x' % info.nni_port),
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800467 name='nni',
468 config=0,
469 state=OFPPS_LIVE,
470 curr=cap,
471 advertised=cap,
472 peer=cap,
473 curr_speed=OFPPF_1GB_FD,
474 max_speed=OFPPF_1GB_FD
475 ),
476 device_id=device.id,
477 device_port_no=nni_port.port_no,
478 root_port=True
479 ))
480
481 device = self.adapter_agent.get_device(device.id)
482 device.parent_id = ld_initialized.id
483 device.oper_status = OperStatus.ACTIVE
484 self.adapter_agent.update_device(device)
485 self.logical_device_id = ld_initialized.id
486
487 # register ONUS per uni port
488 for port_no in info.uni_ports:
489 vlan_id = port_no
490 self.adapter_agent.child_device_detected(
491 parent_device_id=device.id,
492 parent_port_no=1,
Niren R Chidrawarefcebcd2017-07-19 20:03:39 -0400493 child_device_type='ponsim_onu',
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800494 proxy_address=Device.ProxyAddress(
495 device_id=device.id,
496 channel_id=vlan_id
497 ),
Nikolay Titov89004ec2017-06-19 18:22:42 -0400498 admin_state=AdminState.ENABLED,
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800499 vlan=vlan_id
500 )
501
502 # finally, open the frameio port to receive in-band packet_in messages
503 self.log.info('registering-frameio')
Zsolt Haraszti3e6f0892017-01-19 11:51:40 -0800504 self.io_port = registry('frameio').open_port(
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800505 self.interface, self.rcv_io, is_inband_frame)
506 self.log.info('registered-frameio')
507
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400508 # Start collecting stats from the device after a brief pause
509 self.start_kpi_collection(device.id)
510
khenaidoo032d3302017-06-09 14:50:04 -0400511 def reconcile(self, device):
512 self.log.info('reconciling-OLT-device-starts')
513
514 if not device.host_and_port:
515 device.oper_status = OperStatus.FAILED
516 device.reason = 'No host_and_port field provided'
517 self.adapter_agent.update_device(device)
518 return
519
520 try:
521 stub = ponsim_pb2.PonSimStub(self.get_channel())
522 info = stub.GetDeviceInfo(Empty())
523 log.info('got-info', info=info)
524 # TODO: Verify we are connected to the same device we are
525 # reconciling - not much data in ponsim to differentiate at the
526 # time
527 device.oper_status = OperStatus.ACTIVE
528 self.adapter_agent.update_device(device)
529 self.ofp_port_no = info.nni_port
530 self.nni_port = self._get_nni_port()
531 except Exception, e:
532 log.exception('device-unreachable', e=e)
533 device.connect_status = ConnectStatus.UNREACHABLE
534 device.oper_status = OperStatus.UNKNOWN
535 self.adapter_agent.update_device(device)
536 return
537
538 # Now set the initial PM configuration for this device
539 self.pm_metrics = AdapterPmMetrics(device)
540 pm_config = self.pm_metrics.make_proto()
541 log.info("initial-pm-config", pm_config=pm_config)
542 self.adapter_agent.update_device_pm_config(pm_config, init=True)
543
544 # Setup alarm handler
545 self.alarms = AdapterAlarms(self.adapter, device)
546
547 # TODO: Is there anything required to verify nni and PON ports
548
549 # Set the logical device id
550 device = self.adapter_agent.get_device(device.id)
551 if device.parent_id:
552 self.logical_device_id = device.parent_id
553 self.adapter_agent.reconcile_logical_device(device.parent_id)
554 else:
555 self.log.info('no-logical-device-set')
556
557 # Reconcile child devices
558 self.adapter_agent.reconcile_child_devices(device.id)
559
560 # finally, open the frameio port to receive in-band packet_in messages
561 self.io_port = registry('frameio').open_port(
562 self.interface, self.rcv_io, is_inband_frame)
563
564 # Start collecting stats from the device after a brief pause
565 self.start_kpi_collection(device.id)
566
567 self.log.info('reconciling-OLT-device-ends')
568
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800569 def rcv_io(self, port, frame):
khenaidoo032d3302017-06-09 14:50:04 -0400570 self.log.info('received', iface_name=port.iface_name,
Stephane Barbarie5253c652017-03-22 16:29:46 -0400571 frame_len=len(frame))
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800572 pkt = Ether(frame)
573 if pkt.haslayer(Dot1Q):
574 outer_shim = pkt.getlayer(Dot1Q)
575 if isinstance(outer_shim.payload, Dot1Q):
576 inner_shim = outer_shim.payload
577 cvid = inner_shim.vlan
578 logical_port = cvid
579 popped_frame = (
580 Ether(src=pkt.src, dst=pkt.dst, type=inner_shim.type) /
581 inner_shim.payload
582 )
583 kw = dict(
584 logical_device_id=self.logical_device_id,
585 logical_port_no=logical_port,
586 )
587 self.log.info('sending-packet-in', **kw)
588 self.adapter_agent.send_packet_in(
589 packet=str(popped_frame), **kw)
Stephane Barbarie4475a252017-03-31 13:49:20 -0400590 elif pkt.haslayer(Raw):
591 raw_data = json.loads(pkt.getlayer(Raw).load)
592 self.alarms.send_alarm(self, raw_data)
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800593
594 def update_flow_table(self, flows):
595 stub = ponsim_pb2.PonSimStub(self.get_channel())
596 self.log.info('pushing-olt-flow-table')
597 stub.UpdateFlowTable(FlowTable(
598 port=0,
599 flows=flows
600 ))
601 self.log.info('success')
602
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400603 def update_pm_config(self, device, pm_config):
Stephane Barbarie5253c652017-03-22 16:29:46 -0400604 log.info("handler-update-pm-config", device=device,
605 pm_config=pm_config)
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400606 self.pm_metrics.update(pm_config)
607
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800608 def send_proxied_message(self, proxy_address, msg):
609 self.log.info('sending-proxied-message')
610 if isinstance(msg, FlowTable):
611 stub = ponsim_pb2.PonSimStub(self.get_channel())
612 self.log.info('pushing-onu-flow-table', port=msg.port)
613 res = stub.UpdateFlowTable(msg)
614 self.adapter_agent.receive_proxied_message(proxy_address, res)
615
616 def packet_out(self, egress_port, msg):
617 self.log.info('sending-packet-out', egress_port=egress_port,
618 msg=hexify(msg))
619 pkt = Ether(msg)
620 out_pkt = (
621 Ether(src=pkt.src, dst=pkt.dst) /
622 Dot1Q(vlan=4000) /
623 Dot1Q(vlan=egress_port, type=pkt.type) /
624 pkt.payload
625 )
626 self.io_port.send(str(out_pkt))
Khen Nursimulud068d812017-03-06 11:44:18 -0500627
628 @inlineCallbacks
629 def reboot(self):
630 self.log.info('rebooting', device_id=self.device_id)
631
632 # Update the operational status to ACTIVATING and connect status to
633 # UNREACHABLE
634 device = self.adapter_agent.get_device(self.device_id)
635 previous_oper_status = device.oper_status
636 previous_conn_status = device.connect_status
637 device.oper_status = OperStatus.ACTIVATING
638 device.connect_status = ConnectStatus.UNREACHABLE
639 self.adapter_agent.update_device(device)
640
khenaidoo71d0a6c2017-03-22 21:46:04 -0400641 # Update the child devices connect state to UNREACHABLE
khenaidoo2d7af132017-03-23 15:45:51 -0400642 self.adapter_agent.update_child_devices_state(self.device_id,
Stephane Barbarie4475a252017-03-31 13:49:20 -0400643 connect_status=ConnectStatus.UNREACHABLE)
khenaidoo71d0a6c2017-03-22 21:46:04 -0400644
Khen Nursimulud068d812017-03-06 11:44:18 -0500645 # Sleep 10 secs, simulating a reboot
Stephane Barbarie5253c652017-03-22 16:29:46 -0400646 # TODO: send alert and clear alert after the reboot
Khen Nursimulud068d812017-03-06 11:44:18 -0500647 yield asleep(10)
648
649 # Change the operational status back to its previous state. With a
650 # real OLT the operational state should be the state the device is
651 # after a reboot.
652 # Get the latest device reference
653 device = self.adapter_agent.get_device(self.device_id)
654 device.oper_status = previous_oper_status
655 device.connect_status = previous_conn_status
656 self.adapter_agent.update_device(device)
khenaidoo71d0a6c2017-03-22 21:46:04 -0400657
658 # Update the child devices connect state to REACHABLE
khenaidoo2d7af132017-03-23 15:45:51 -0400659 self.adapter_agent.update_child_devices_state(self.device_id,
Stephane Barbarie4475a252017-03-31 13:49:20 -0400660 connect_status=ConnectStatus.REACHABLE)
khenaidoo71d0a6c2017-03-22 21:46:04 -0400661
Khen Nursimulud068d812017-03-06 11:44:18 -0500662 self.log.info('rebooted', device_id=self.device_id)
663
sathishg5ae86222017-06-28 15:16:29 +0530664 def self_test_device(self, device):
665 """
666 This is called to Self a device based on a NBI call.
667 :param device: A Voltha.Device object.
668 :return: Will return result of self test
669 """
670 log.info('self-test-device', device=device.id)
671 raise NotImplementedError()
672
Khen Nursimulud068d812017-03-06 11:44:18 -0500673 def disable(self):
674 self.log.info('disabling', device_id=self.device_id)
675
676 # Get the latest device reference
677 device = self.adapter_agent.get_device(self.device_id)
678
679 # Update the operational status to UNKNOWN
680 device.oper_status = OperStatus.UNKNOWN
681 device.connect_status = ConnectStatus.UNREACHABLE
682 self.adapter_agent.update_device(device)
683
684 # Remove the logical device
685 logical_device = self.adapter_agent.get_logical_device(
Stephane Barbarie5253c652017-03-22 16:29:46 -0400686 self.logical_device_id)
Khen Nursimulud068d812017-03-06 11:44:18 -0500687 self.adapter_agent.delete_logical_device(logical_device)
688
689 # Disable all child devices first
khenaidoo2d7af132017-03-23 15:45:51 -0400690 self.adapter_agent.update_child_devices_state(self.device_id,
Stephane Barbarie4475a252017-03-31 13:49:20 -0400691 admin_state=AdminState.DISABLED)
Khen Nursimulud068d812017-03-06 11:44:18 -0500692
Khen Nursimulud068d812017-03-06 11:44:18 -0500693 # Remove the peer references from this device
694 self.adapter_agent.delete_all_peer_references(self.device_id)
695
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400696 # Set all ports to disabled
697 self.adapter_agent.disable_all_ports(self.device_id)
698
Khen Nursimulud068d812017-03-06 11:44:18 -0500699 # close the frameio port
700 registry('frameio').close_port(self.io_port)
701
khenaidoo032d3302017-06-09 14:50:04 -0400702 # Update the logice device mapping
703 if self.logical_device_id in \
704 self.adapter.logical_device_id_to_root_device_id:
705 del self.adapter.logical_device_id_to_root_device_id[
706 self.logical_device_id]
707
Khen Nursimulud068d812017-03-06 11:44:18 -0500708 # TODO:
709 # 1) Remove all flows from the device
710 # 2) Remove the device from ponsim
711
712 self.log.info('disabled', device_id=device.id)
713
Khen Nursimulud068d812017-03-06 11:44:18 -0500714 def reenable(self):
715 self.log.info('re-enabling', device_id=self.device_id)
716
717 # Get the latest device reference
718 device = self.adapter_agent.get_device(self.device_id)
719
khenaidoo032d3302017-06-09 14:50:04 -0400720 # Set the ofp_port_no and nni_port in case we bypassed the reconcile
721 # process if the device was in DISABLED state on voltha restart
722 if not self.ofp_port_no and not self.nni_port:
723 stub = ponsim_pb2.PonSimStub(self.get_channel())
724 info = stub.GetDeviceInfo(Empty())
725 log.info('got-info', info=info)
726 self.ofp_port_no = info.nni_port
727 self.nni_port = self._get_nni_port()
728
Khen Nursimulud068d812017-03-06 11:44:18 -0500729 # Update the connect status to REACHABLE
730 device.connect_status = ConnectStatus.REACHABLE
731 self.adapter_agent.update_device(device)
732
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400733 # Set all ports to enabled
734 self.adapter_agent.enable_all_ports(self.device_id)
735
Khen Nursimulud068d812017-03-06 11:44:18 -0500736 ld = LogicalDevice(
737 # not setting id and datapth_id will let the adapter agent pick id
738 desc=ofp_desc(
739 mfr_desc='cord porject',
740 hw_desc='simulated pon',
741 sw_desc='simulated pon',
742 serial_num=uuid4().hex,
743 dp_desc='n/a'
744 ),
745 switch_features=ofp_switch_features(
746 n_buffers=256, # TODO fake for now
747 n_tables=2, # TODO ditto
748 capabilities=( # TODO and ditto
749 OFPC_FLOW_STATS
750 | OFPC_TABLE_STATS
751 | OFPC_PORT_STATS
752 | OFPC_GROUP_STATS
753 )
754 ),
755 root_device_id=device.id
756 )
khenaidoo507d9222017-10-10 16:23:49 -0400757 mac_address = "AA:BB:CC:DD:EE:FF"
758 ld_initialized = self.adapter_agent.create_logical_device(ld,
759 dpid=mac_address)
Khen Nursimulud068d812017-03-06 11:44:18 -0500760 cap = OFPPF_1GB_FD | OFPPF_FIBER
761 self.adapter_agent.add_logical_port(ld_initialized.id, LogicalPort(
762 id='nni',
763 ofp_port=ofp_port(
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400764 port_no=self.ofp_port_no,
Khen Nursimulud068d812017-03-06 11:44:18 -0500765 hw_addr=mac_str_to_tuple(
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400766 '00:00:00:00:00:%02x' % self.ofp_port_no),
Khen Nursimulud068d812017-03-06 11:44:18 -0500767 name='nni',
768 config=0,
769 state=OFPPS_LIVE,
770 curr=cap,
771 advertised=cap,
772 peer=cap,
773 curr_speed=OFPPF_1GB_FD,
774 max_speed=OFPPF_1GB_FD
775 ),
776 device_id=device.id,
777 device_port_no=self.nni_port.port_no,
778 root_port=True
779 ))
780
781 device = self.adapter_agent.get_device(device.id)
782 device.parent_id = ld_initialized.id
783 device.oper_status = OperStatus.ACTIVE
784 self.adapter_agent.update_device(device)
785 self.logical_device_id = ld_initialized.id
786
787 # Reenable all child devices
khenaidoo2d7af132017-03-23 15:45:51 -0400788 self.adapter_agent.update_child_devices_state(device.id,
Stephane Barbarie4475a252017-03-31 13:49:20 -0400789 admin_state=AdminState.ENABLED)
Khen Nursimulud068d812017-03-06 11:44:18 -0500790
Khen Nursimulud068d812017-03-06 11:44:18 -0500791 # finally, open the frameio port to receive in-band packet_in messages
Khen Nursimulud068d812017-03-06 11:44:18 -0500792 self.io_port = registry('frameio').open_port(
793 self.interface, self.rcv_io, is_inband_frame)
Khen Nursimulud068d812017-03-06 11:44:18 -0500794
795 self.log.info('re-enabled', device_id=device.id)
796
Khen Nursimulud068d812017-03-06 11:44:18 -0500797 def delete(self):
798 self.log.info('deleting', device_id=self.device_id)
799
800 # Remove all child devices
801 self.adapter_agent.delete_all_child_devices(self.device_id)
802
803 # TODO:
804 # 1) Remove all flows from the device
805 # 2) Remove the device from ponsim
806
807 self.log.info('deleted', device_id=self.device_id)
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400808
809 def start_kpi_collection(self, device_id):
810
811 def _collect(device_id, prefix):
812
813 try:
814 # Step 1: gather metrics from device
815 port_metrics = \
Stephane Barbarie5253c652017-03-22 16:29:46 -0400816 self.pm_metrics.collect_port_metrics(self.get_channel())
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400817
818 # Step 2: prepare the KpiEvent for submission
819 # we can time-stamp them here (or could use time derived from OLT
820 ts = arrow.utcnow().timestamp
821 kpi_event = KpiEvent(
822 type=KpiEventType.slice,
823 ts=ts,
824 prefixes={
825 # OLT NNI port
826 prefix + '.nni': MetricValuePairs(
827 metrics=port_metrics['nni']),
828 # OLT PON port
829 prefix + '.pon': MetricValuePairs(
830 metrics=port_metrics['pon'])
831 }
832 )
833
834 # Step 3: submit
835 self.adapter_agent.submit_kpis(kpi_event)
836
837 except Exception as e:
838 log.exception('failed-to-submit-kpis', e=e)
Stephane Barbarie5253c652017-03-22 16:29:46 -0400839
Sergio Slobodrian98eff412017-03-15 14:46:30 -0400840 self.pm_metrics.start_collector(_collect)
Nikolay Titov89004ec2017-06-19 18:22:42 -0400841
842 def get_interface_config(self, data):
843 interfaceConfig = InterfaceConfig()
844 if isinstance(data, ChannelgroupConfig):
845 interfaceConfig.channel_group_config.CopyFrom(data)
846 elif isinstance(data, ChannelpartitionConfig):
847 interfaceConfig.channel_partition_config.CopyFrom(data)
848 elif isinstance(data, ChannelpairConfig):
849 interfaceConfig.channel_pair_config.CopyFrom(data)
850 elif isinstance(data, ChannelterminationConfig):
851 interfaceConfig.channel_termination_config.CopyFrom(data)
852 elif isinstance(data, OntaniConfig):
853 interfaceConfig.ont_ani_config.CopyFrom(data)
854 elif isinstance(data, VOntaniConfig):
855 interfaceConfig.vont_ani_config.CopyFrom(data)
856 elif isinstance(data, VEnetConfig):
857 interfaceConfig.venet_config.CopyFrom(data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400858 elif isinstance(data, TrafficDescriptorProfileData):
859 interfaceConfig.traffic_descriptor_profile_config_data.CopyFrom(
860 data)
861 elif isinstance(data, TcontsConfigData):
862 interfaceConfig.tconts_config_data.CopyFrom(data)
863 elif isinstance(data, GemportsConfigData):
864 interfaceConfig.gemports_config_data.CopyFrom(data)
865 elif isinstance(data, MulticastGemportsConfigData):
866 interfaceConfig.multicast_gemports_config_data.CopyFrom(data)
867 elif isinstance(data, MulticastDistributionSetData):
868 interfaceConfig.multicast_distribution_set_data.CopyFrom(data)
Nikolay Titov89004ec2017-06-19 18:22:42 -0400869 else:
870 return None
871 return interfaceConfig
872
Nikolay Titov176f1db2017-08-10 12:38:43 -0400873 def xpon_ponsim_olt_interface(self, method_name, data, data2=None):
Nikolay Titov89004ec2017-06-19 18:22:42 -0400874 interfaceConfig = self.get_interface_config(data)
875 if interfaceConfig is not None:
Nikolay Titov176f1db2017-08-10 12:38:43 -0400876 self.log.info(
877 'forwarding-{}-request-to-olt-for-interface-type'
878 .format(self.xpon_ponsim_olt_itfs[method_name]['log']),
879 interface_type=type(data))
Nikolay Titov89004ec2017-06-19 18:22:42 -0400880 stub = ponsim_pb2.XPonSimStub(self.get_channel())
Nikolay Titov176f1db2017-08-10 12:38:43 -0400881 _method = getattr(
882 stub, self.xpon_ponsim_olt_itfs[method_name]['method_name'])
883 if isinstance(data, TcontsConfigData):
884 tcont_config = TcontInterfaceConfig()
885 tcont_config.tconts_config_data.CopyFrom(data)
886 tcont_config.traffic_descriptor_profile_config_data.CopyFrom(
887 data2)
888 _method(tcont_config)
889 else:
890 _method(interfaceConfig)
Nikolay Titov89004ec2017-06-19 18:22:42 -0400891 self.log.info('success')
892
Nikolay Titov176f1db2017-08-10 12:38:43 -0400893 def create_interface(self, data):
894 _method_name = sys._getframe().f_code.co_name
895 self.xpon_ponsim_olt_interface(_method_name, data);
896
Nikolay Titov89004ec2017-06-19 18:22:42 -0400897 def update_interface(self, data):
Nikolay Titov176f1db2017-08-10 12:38:43 -0400898 _method_name = sys._getframe().f_code.co_name
899 self.xpon_ponsim_olt_interface(_method_name, data);
Nikolay Titov89004ec2017-06-19 18:22:42 -0400900
901 def remove_interface(self, data):
Nikolay Titov176f1db2017-08-10 12:38:43 -0400902 _method_name = sys._getframe().f_code.co_name
903 self.xpon_ponsim_olt_interface(_method_name, data);
904
905 def create_tcont(self, tcont_data, traffic_descriptor_data):
906 _method_name = sys._getframe().f_code.co_name
907 self.xpon_ponsim_olt_interface(_method_name, tcont_data,
908 traffic_descriptor_data);
909
910 def update_tcont(self, tcont_data, traffic_descriptor_data):
911 _method_name = sys._getframe().f_code.co_name
912 self.xpon_ponsim_olt_interface(_method_name, tcont_data,
913 traffic_descriptor_data);
914
915 def remove_tcont(self, tcont_data, traffic_descriptor_data):
916 _method_name = sys._getframe().f_code.co_name
917 self.xpon_ponsim_olt_interface(_method_name, tcont_data,
918 traffic_descriptor_data);
919
920 def create_gemport(self, data):
921 _method_name = sys._getframe().f_code.co_name
922 self.xpon_ponsim_olt_interface(_method_name, data);
923
924 def update_gemport(self, data):
925 _method_name = sys._getframe().f_code.co_name
926 self.xpon_ponsim_olt_interface(_method_name, data);
927
928 def remove_gemport(self, data):
929 _method_name = sys._getframe().f_code.co_name
930 self.xpon_ponsim_olt_interface(_method_name, data);
931
932 def create_multicast_gemport(self, data):
933 _method_name = sys._getframe().f_code.co_name
934 self.xpon_ponsim_olt_interface(_method_name, data);
935
936 def update_multicast_gemport(self, data):
937 _method_name = sys._getframe().f_code.co_name
938 self.xpon_ponsim_olt_interface(_method_name, data);
939
940 def remove_multicast_gemport(self, data):
941 _method_name = sys._getframe().f_code.co_name
942 self.xpon_ponsim_olt_interface(_method_name, data);
943
944 def create_multicast_distribution_set(self, data):
945 _method_name = sys._getframe().f_code.co_name
946 self.xpon_ponsim_olt_interface(_method_name, data);
947
948 def update_multicast_distribution_set(self, data):
949 _method_name = sys._getframe().f_code.co_name
950 self.xpon_ponsim_olt_interface(_method_name, data);
951
952 def remove_multicast_distribution_set(self, data):
953 _method_name = sys._getframe().f_code.co_name
954 self.xpon_ponsim_olt_interface(_method_name, data);