blob: 7b75590a70d83a809924d2f4ff96922143ff9988 [file] [log] [blame]
Andrea Campanellad8d92db2016-01-14 16:24:41 -08001/*
Ray Milkey85267002016-11-16 11:06:35 -08002 * Copyright 2016-present Open Networking Laboratory
Andrea Campanellad8d92db2016-01-14 16:24:41 -08003 *
Ray Milkey85267002016-11-16 11:06:35 -08004 * 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
Andrea Campanellad8d92db2016-01-14 16:24:41 -08007 *
Ray Milkey85267002016-11-16 11:06:35 -08008 * 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.
Andrea Campanellad8d92db2016-01-14 16:24:41 -080015 */
Andrea Campanella238d96e2016-01-20 11:52:02 -080016package org.onosproject.drivers.ciena;
Andrea Campanellad8d92db2016-01-14 16:24:41 -080017
Andrea Campanella6c71a052016-04-22 11:56:31 -070018import com.google.common.collect.ImmutableList;
Andrea Campanellad8d92db2016-01-14 16:24:41 -080019import com.google.common.collect.Lists;
20import org.apache.commons.configuration.HierarchicalConfiguration;
Andrea Campanella238d96e2016-01-20 11:52:02 -080021import org.onosproject.drivers.utilities.XmlConfigParser;
Andrea Campanellad8d92db2016-01-14 16:24:41 -080022import org.onosproject.net.AnnotationKeys;
HIGUCHI Yuta9605c782016-05-16 14:34:05 -070023import org.onosproject.net.ChannelSpacing;
Andrea Campanellad8d92db2016-01-14 16:24:41 -080024import org.onosproject.net.CltSignalType;
25import org.onosproject.net.DefaultAnnotations;
26import org.onosproject.net.DeviceId;
HIGUCHI Yuta9605c782016-05-16 14:34:05 -070027import org.onosproject.net.GridType;
28import org.onosproject.net.OchSignal;
29import org.onosproject.net.OduSignalType;
Andrea Campanellad8d92db2016-01-14 16:24:41 -080030import org.onosproject.net.PortNumber;
HIGUCHI Yuta9605c782016-05-16 14:34:05 -070031import org.onosproject.net.SparseAnnotations;
Andrea Campanella6c71a052016-04-22 11:56:31 -070032import org.onosproject.net.device.DeviceDescription;
33import org.onosproject.net.device.DeviceDescriptionDiscovery;
Andrea Campanellad8d92db2016-01-14 16:24:41 -080034import org.onosproject.net.device.PortDescription;
35import org.onosproject.net.driver.AbstractHandlerBehaviour;
36import org.onosproject.net.driver.DriverHandler;
37import org.onosproject.protocol.rest.RestSBController;
Andrea Campanella6c71a052016-04-22 11:56:31 -070038import org.slf4j.Logger;
Andrea Campanellad8d92db2016-01-14 16:24:41 -080039
40import java.util.ArrayList;
41import java.util.List;
42
43import static com.google.common.base.Preconditions.checkNotNull;
HIGUCHI Yuta9605c782016-05-16 14:34:05 -070044import static org.onosproject.net.optical.device.OchPortHelper.ochPortDescription;
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -070045import static org.onosproject.net.optical.device.OduCltPortHelper.oduCltPortDescription;
Andrea Campanella6c71a052016-04-22 11:56:31 -070046import static org.slf4j.LoggerFactory.getLogger;
Andrea Campanellad8d92db2016-01-14 16:24:41 -080047
48/**
49 * Discovers the ports from a Ciena WaveServer Rest device.
50 */
Andrea Campanella6c71a052016-04-22 11:56:31 -070051public class CienaWaveserverDeviceDescription extends AbstractHandlerBehaviour
52 implements DeviceDescriptionDiscovery {
53
54 private final Logger log = getLogger(getClass());
Andrea Campanellad8d92db2016-01-14 16:24:41 -080055
56 private static final String SPEED = "speed";
57 private static final String GBPS = "Gbps";
58 private static final String PORT_ID = "port-id";
59 private static final String XML = "xml";
60 private static final String ENABLED = "enabled";
61 private static final String EMPTY_STRING = "";
62 private static final String NAME = "name";
63 private static final String ADMIN_STATE = "admin-state";
64
Andrea Campanella2947e622016-01-27 09:23:46 -080065 private static final ArrayList<String> LINESIDE_PORT_ID = Lists.newArrayList(
66 "4", "48");
Andrea Campanellad8d92db2016-01-14 16:24:41 -080067
68 private static final String GENERAL_PORT_REQUEST =
Andrea Campanella2947e622016-01-27 09:23:46 -080069 "ws-ports?config=true&format=xml&depth=unbounded";
70 private static final String SPECIFIC_PORT_PATH = "ws-ptps/ptp/";
Andrea Campanellad8d92db2016-01-14 16:24:41 -080071 private static final String SPECIFIC_PORT_CONFIG =
72 "/ptp-config?config=true&format=xml&depth=unbounded";
Andrea Campanella2947e622016-01-27 09:23:46 -080073 //HTTP strings
74// private static final String GENERAL_PORT_REQUEST =
75// "/yang-api/datastore/ws-ports?config=true&format=xml&depth=unbounded";
76// private static final String SPECIFIC_PORT_PATH = "/yang-api/datastore/ws-ptps/ptp/";
77// private static final String SPECIFIC_PORT_CONFIG =
78// "/ptp-config?config=true&format=xml&depth=unbounded";
Andrea Campanellad8d92db2016-01-14 16:24:41 -080079
Andrea Campanella6c71a052016-04-22 11:56:31 -070080 @Override
81 public DeviceDescription discoverDeviceDetails() {
82 log.info("No description to be added for device");
83 //TODO to be implemented if needed.
84 return null;
85 }
Andrea Campanellad8d92db2016-01-14 16:24:41 -080086
87 @Override
Andrea Campanella6c71a052016-04-22 11:56:31 -070088 public List<PortDescription> discoverPortDetails() {
89 return getPorts();
90 }
91
92 private List<PortDescription> getPorts() {
Andrea Campanellad8d92db2016-01-14 16:24:41 -080093 List<PortDescription> ports = Lists.newArrayList();
94 DriverHandler handler = handler();
95 RestSBController controller = checkNotNull(handler.get(RestSBController.class));
96 DeviceId deviceId = handler.data().deviceId();
97
98
99 HierarchicalConfiguration config = XmlConfigParser.
100 loadXml(controller.get(deviceId, GENERAL_PORT_REQUEST, XML));
101 List<HierarchicalConfiguration> portsConfig =
HIGUCHI Yuta9605c782016-05-16 14:34:05 -0700102 parseWaveServerCienaPorts(config);
Sho SHIMIZUa09e1bb2016-08-01 14:25:25 -0700103 portsConfig.forEach(sub -> {
Andrea Campanella2947e622016-01-27 09:23:46 -0800104 String portId = sub.getString(PORT_ID);
Andrea Campanellad8d92db2016-01-14 16:24:41 -0800105 String name = sub.getString(NAME);
Andrea Campanella2947e622016-01-27 09:23:46 -0800106 if (LINESIDE_PORT_ID.contains(portId)) {
Andrea Campanella3afcfd12016-02-26 11:05:57 -0800107 String txName = name + " Tx";
108 DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
109 .set(AnnotationKeys.PORT_NAME, txName);
Andrea Campanella2947e622016-01-27 09:23:46 -0800110 String wsportInfoRequest = SPECIFIC_PORT_PATH + portId +
Andrea Campanellad8d92db2016-01-14 16:24:41 -0800111 SPECIFIC_PORT_CONFIG;
HIGUCHI Yuta9605c782016-05-16 14:34:05 -0700112 ports.add(parseWaveServerCienaOchPorts(
Andrea Campanellad8d92db2016-01-14 16:24:41 -0800113 sub.getLong(PORT_ID),
Andrea Campanella2947e622016-01-27 09:23:46 -0800114 toGbps(Long.parseLong(sub.getString(SPEED).replace(GBPS, EMPTY_STRING)
115 .replace(" ", EMPTY_STRING))),
Andrea Campanellad8d92db2016-01-14 16:24:41 -0800116 XmlConfigParser.loadXml(controller.get(deviceId, wsportInfoRequest, XML)),
Andrea Campanella784ee0f2016-02-17 15:50:59 -0800117 annotations.build()));
Andrea Campanella2947e622016-01-27 09:23:46 -0800118 //adding corresponding opposite side port
Andrea Campanella3afcfd12016-02-26 11:05:57 -0800119 String rxName = name.replace(".1", ".2") + " Rx";
HIGUCHI Yuta9605c782016-05-16 14:34:05 -0700120 ports.add(parseWaveServerCienaOchPorts(
Andrea Campanella2947e622016-01-27 09:23:46 -0800121 sub.getLong(PORT_ID) + 1,
122 toGbps(Long.parseLong(sub.getString(SPEED).replace(GBPS, EMPTY_STRING)
123 .replace(" ", EMPTY_STRING))),
124 XmlConfigParser.loadXml(controller.get(deviceId, wsportInfoRequest, XML)),
Andrea Campanella3afcfd12016-02-26 11:05:57 -0800125 annotations.set(AnnotationKeys.PORT_NAME, rxName)
Andrea Campanella2947e622016-01-27 09:23:46 -0800126 .build()));
127 } else if (!portId.equals("5") && !portId.equals("49")) {
Andrea Campanella3afcfd12016-02-26 11:05:57 -0800128 DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
129 .set(AnnotationKeys.PORT_NAME, name);
Andrea Campanellad8d92db2016-01-14 16:24:41 -0800130 //FIXME change when all optical types have two way information methods, see jira tickets
131 final int speed100GbpsinMbps = 100000;
132 CltSignalType cltType = toGbps(Long.parseLong(
Andrea Campanella2947e622016-01-27 09:23:46 -0800133 sub.getString(SPEED).replace(GBPS, EMPTY_STRING)
134 .replace(" ", EMPTY_STRING))) == speed100GbpsinMbps ?
Andrea Campanellad8d92db2016-01-14 16:24:41 -0800135 CltSignalType.CLT_100GBE : null;
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700136 ports.add(oduCltPortDescription(PortNumber.portNumber(sub.getLong(PORT_ID)),
Andrea Campanella6c71a052016-04-22 11:56:31 -0700137 sub.getString(ADMIN_STATE).equals(ENABLED),
138 cltType, annotations.build()));
Andrea Campanellad8d92db2016-01-14 16:24:41 -0800139 }
140 });
Andrea Campanella6c71a052016-04-22 11:56:31 -0700141 return ImmutableList.copyOf(ports);
Andrea Campanellad8d92db2016-01-14 16:24:41 -0800142 }
143
HIGUCHI Yuta9605c782016-05-16 14:34:05 -0700144 public static List<HierarchicalConfiguration> parseWaveServerCienaPorts(HierarchicalConfiguration cfg) {
145 return cfg.configurationsAt("ws-ports.port-interface");
146 }
147
148 public static PortDescription parseWaveServerCienaOchPorts(long portNumber, long oduPortSpeed,
149 HierarchicalConfiguration config,
150 SparseAnnotations annotations) {
151 final List<String> tunableType = Lists.newArrayList("Performance-Optimized", "Accelerated");
152 final String transmitterPath = "ptp-config.transmitter-state";
153 final String tunablePath = "ptp-config.adv-config.tx-tuning-mode";
154 final String gridTypePath = "ptp-config.adv-config.wl-spacing";
155 final String frequencyPath = "ptp-config.adv-config.frequency";
156
157 boolean isEnabled = config.getString(transmitterPath).equals("enabled");
158 boolean isTunable = tunableType.contains(config.getString(tunablePath));
159
160 //FIXME change when all optical types have two way information methods, see jira tickets
161 final int speed100GbpsinMbps = 100000;
162 OduSignalType oduSignalType = oduPortSpeed == speed100GbpsinMbps ? OduSignalType.ODU4 : null;
163 GridType gridType = config.getString(gridTypePath).equals("FlexGrid") ? GridType.FLEX : null;
164 ChannelSpacing chSpacing = gridType == GridType.FLEX ? ChannelSpacing.CHL_6P25GHZ : null;
165
166 //Working in Ghz //(Nominal central frequency - 193.1)/channelSpacing = spacingMultiplier
167 final int baseFrequency = 193100;
168 int spacingMult = (int) (toGbps((Integer.parseInt(config.getString(frequencyPath)) -
169 baseFrequency)) / toGbpsFromHz(chSpacing.frequency().asHz())); //FIXME is there a better way ?
170
171 return ochPortDescription(PortNumber.portNumber(portNumber), isEnabled, oduSignalType, isTunable,
Andrea Campanella6c71a052016-04-22 11:56:31 -0700172 new OchSignal(gridType, chSpacing, spacingMult, 1), annotations);
HIGUCHI Yuta9605c782016-05-16 14:34:05 -0700173 }
174
Andrea Campanellad8d92db2016-01-14 16:24:41 -0800175 //FIXME remove when all optical types have two way information methods, see jira tickets
HIGUCHI Yuta9605c782016-05-16 14:34:05 -0700176 private static long toGbps(long speed) {
Andrea Campanellad8d92db2016-01-14 16:24:41 -0800177 return speed * 1000;
178 }
Andrea Campanella2947e622016-01-27 09:23:46 -0800179
HIGUCHI Yuta9605c782016-05-16 14:34:05 -0700180 private static long toGbpsFromHz(long speed) {
181 return speed / 1000;
182 }
Andrea Campanellad8d92db2016-01-14 16:24:41 -0800183}
184