blob: 14903ae5b64275226ca3372fe9b89ddd11cad650 [file] [log] [blame]
#
# Copyright 2019 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import structlog
import socket
from voltha.adapters.openolt.openolt_utils import OpenoltUtils
from voltha.protos.device_pb2 import Port
from voltha.protos.openflow_13_pb2 import OFPPS_LIVE, OFPPF_FIBER, \
OFPPS_LINK_DOWN, OFPPF_1GB_FD, OFPC_PORT_STATS, OFPC_TABLE_STATS, \
OFPC_FLOW_STATS, OFPC_GROUP_STATS, ofp_port, ofp_port_stats, ofp_desc, \
ofp_switch_features
from voltha.core.logical_device_agent import mac_str_to_tuple
from voltha.protos.logical_device_pb2 import LogicalPort
from voltha.protos.common_pb2 import OperStatus, ConnectStatus
from voltha.protos.logical_device_pb2 import LogicalDevice
from voltha.registry import registry
class OpenOltDataModel(object):
log = structlog.get_logger()
def __init__(self, adapter_agent):
self.adapter_agent = adapter_agent
self.log = structlog.get_logger()
def create_logical_device(self, device_id, device_info):
dpid = device_info.device_id
serial_number = device_info.device_serial_number
device = self.adapter_agent.get_device(device_id)
host_and_port = device.host_and_port
if dpid is None or dpid == '':
uri = host_and_port.split(":")[0]
try:
socket.inet_pton(socket.AF_INET, uri)
dpid = '00:00:' + OpenoltUtils.ip_hex(uri)
except socket.error:
# this is not an IP
dpid = OpenoltUtils.str_to_mac(uri)
self.log.info('creating-openolt-logical-device', dp_id=dpid,
serial_number=serial_number)
hw_desc = device_info.model
if device_info.hardware_version:
hw_desc += '-' + device_info.hardware_version
# Create logical OF device
ld = LogicalDevice(
root_device_id=device_id,
switch_features=ofp_switch_features(
n_buffers=256, # TODO fake for now
n_tables=2, # TODO ditto
capabilities=( # TODO and ditto
OFPC_FLOW_STATS
| OFPC_TABLE_STATS
| OFPC_PORT_STATS
| OFPC_GROUP_STATS
)
),
desc=ofp_desc(
serial_num=serial_number
)
)
ld_init = self.adapter_agent.create_logical_device(ld,
dpid=dpid)
device = self.adapter_agent.get_device(device_id)
device.serial_number = serial_number
self.adapter_agent.update_device(device)
self.log.info('created-openolt-logical-device',
logical_device_id=ld_init.id)
return ld_init.id
def disable_logical_device(self, device_id):
oper_state = OperStatus.UNKNOWN
connect_state = ConnectStatus.UNREACHABLE
device = self.adapter_agent.get_device(device_id)
logical_device_id = device.parent_id
child_devices = self.adapter_agent.get_child_devices(device_id)
for onu_device in child_devices:
onu_adapter_agent = \
registry('adapter_loader').get_agent(onu_device.adapter)
onu_adapter_agent.update_interface(onu_device,
{'oper_state': 'down'})
self.onu_ports_down(onu_device, oper_state)
# Children devices
self.adapter_agent.update_child_devices_state(
device_id, oper_status=oper_state,
connect_status=connect_state)
# Device Ports
device_ports = self.adapter_agent.get_ports(device_id,
Port.ETHERNET_NNI)
logical_ports_ids = [port.label for port in device_ports]
device_ports += self.adapter_agent.get_ports(device_id,
Port.PON_OLT)
for port in device_ports:
port.oper_status = oper_state
self.adapter_agent.add_port(device_id, port)
# Device logical port
for logical_port_id in logical_ports_ids:
logical_port = self.adapter_agent.get_logical_port(
logical_device_id, logical_port_id)
logical_port.ofp_port.state = OFPPS_LINK_DOWN
self.adapter_agent.update_logical_port(self.logical_device_id,
logical_port)
device.oper_status = oper_state
device.connect_status = connect_state
self.adapter_agent.update_device(device)
def add_logical_port(self, logical_device_id, device_id, port_no, intf_id,
oper_state):
self.log.info('adding-logical-port', port_no=port_no)
label = OpenoltUtils.port_name(port_no, Port.ETHERNET_NNI)
cap = OFPPF_1GB_FD | OFPPF_FIBER
curr_speed = OFPPF_1GB_FD
max_speed = OFPPF_1GB_FD
if oper_state == OperStatus.ACTIVE:
of_oper_state = OFPPS_LIVE
else:
of_oper_state = OFPPS_LINK_DOWN
ofp = ofp_port(
port_no=port_no,
hw_addr=mac_str_to_tuple(
OpenoltUtils.make_mac_from_port_no(port_no)),
name=label, config=0, state=of_oper_state, curr=cap,
advertised=cap, peer=cap, curr_speed=curr_speed,
max_speed=max_speed)
ofp_stats = ofp_port_stats(port_no=port_no)
logical_port = LogicalPort(
id=label, ofp_port=ofp, device_id=device_id,
device_port_no=port_no, root_port=True,
ofp_port_stats=ofp_stats)
self.adapter_agent.add_logical_port(logical_device_id, logical_port)