blob: 0aac2913008f58610d98a4b8fa763a387b921935 [file] [log] [blame]
slowr13fa5b02017-08-08 16:32:31 -07001/*
slowr577f3222017-08-28 10:49:08 -07002 * Copyright 2015-present Open Networking Foundation
slowr13fa5b02017-08-08 16:32:31 -07003 *
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
17package org.onosproject.xran.controller;
18
19import com.google.common.collect.Sets;
20import io.netty.channel.ChannelHandlerContext;
21import io.netty.channel.sctp.SctpMessage;
22import org.apache.commons.lang.exception.ExceptionUtils;
slowr577f3222017-08-28 10:49:08 -070023import org.apache.felix.scr.annotations.Activate;
24import org.apache.felix.scr.annotations.Component;
25import org.apache.felix.scr.annotations.Deactivate;
26import org.apache.felix.scr.annotations.Reference;
27import org.apache.felix.scr.annotations.ReferenceCardinality;
28import org.apache.felix.scr.annotations.Service;
29import org.onlab.packet.IpAddress;
slowr13fa5b02017-08-08 16:32:31 -070030import org.onosproject.core.ApplicationId;
31import org.onosproject.core.CoreService;
slowr577f3222017-08-28 10:49:08 -070032import org.onosproject.net.config.Config;
33import org.onosproject.net.config.ConfigFactory;
34import org.onosproject.net.config.NetworkConfigEvent;
35import org.onosproject.net.config.NetworkConfigListener;
36import org.onosproject.net.config.NetworkConfigRegistry;
37import org.onosproject.net.config.NetworkConfigService;
slowr13fa5b02017-08-08 16:32:31 -070038import org.onosproject.net.config.basics.SubjectFactories;
39import org.onosproject.net.device.DeviceEvent;
40import org.onosproject.net.device.DeviceListener;
41import org.onosproject.net.device.DeviceService;
42import org.onosproject.net.host.HostEvent;
43import org.onosproject.net.host.HostListener;
44import org.onosproject.net.host.HostService;
45import org.onosproject.xran.XranStore;
slowr577f3222017-08-28 10:49:08 -070046import org.onosproject.xran.codecs.api.CRNTI;
47import org.onosproject.xran.codecs.api.ECGI;
48import org.onosproject.xran.codecs.api.ERABID;
49import org.onosproject.xran.codecs.api.ERABParams;
50import org.onosproject.xran.codecs.api.ERABParamsItem;
51import org.onosproject.xran.codecs.api.PCIARFCN;
52import org.onosproject.xran.codecs.api.PropScell;
53import org.onosproject.xran.codecs.api.RSRPRange;
54import org.onosproject.xran.codecs.api.RSRQRange;
55import org.onosproject.xran.codecs.api.RXSigReport;
56import org.onosproject.xran.codecs.api.RadioRepPerServCell;
57import org.onosproject.xran.codecs.api.SchedMeasRepPerServCell;
58import org.onosproject.xran.codecs.api.TrafficSplitPercentage;
slowrc153ad92017-08-16 19:47:52 -070059import org.onosproject.xran.codecs.ber.types.BerInteger;
slowr577f3222017-08-28 10:49:08 -070060import org.onosproject.xran.codecs.pdu.BearerAdmissionRequest;
61import org.onosproject.xran.codecs.pdu.BearerAdmissionResponse;
62import org.onosproject.xran.codecs.pdu.BearerAdmissionStatus;
63import org.onosproject.xran.codecs.pdu.BearerReleaseInd;
64import org.onosproject.xran.codecs.pdu.CellConfigReport;
65import org.onosproject.xran.codecs.pdu.CellConfigRequest;
66import org.onosproject.xran.codecs.pdu.HOComplete;
67import org.onosproject.xran.codecs.pdu.HOFailure;
68import org.onosproject.xran.codecs.pdu.HORequest;
69import org.onosproject.xran.codecs.pdu.L2MeasConfig;
70import org.onosproject.xran.codecs.pdu.PDCPMeasReportPerUe;
71import org.onosproject.xran.codecs.pdu.RRMConfig;
72import org.onosproject.xran.codecs.pdu.RRMConfigStatus;
73import org.onosproject.xran.codecs.pdu.RXSigMeasConfig;
74import org.onosproject.xran.codecs.pdu.RXSigMeasReport;
75import org.onosproject.xran.codecs.pdu.RadioMeasReportPerCell;
76import org.onosproject.xran.codecs.pdu.RadioMeasReportPerUE;
77import org.onosproject.xran.codecs.pdu.ScellAdd;
78import org.onosproject.xran.codecs.pdu.ScellAddStatus;
79import org.onosproject.xran.codecs.pdu.ScellDelete;
80import org.onosproject.xran.codecs.pdu.SchedMeasReportPerCell;
81import org.onosproject.xran.codecs.pdu.SchedMeasReportPerUE;
82import org.onosproject.xran.codecs.pdu.TrafficSplitConfig;
83import org.onosproject.xran.codecs.pdu.UEAdmissionRequest;
84import org.onosproject.xran.codecs.pdu.UEAdmissionResponse;
85import org.onosproject.xran.codecs.pdu.UEAdmissionStatus;
86import org.onosproject.xran.codecs.pdu.UECapabilityEnquiry;
87import org.onosproject.xran.codecs.pdu.UECapabilityInfo;
88import org.onosproject.xran.codecs.pdu.UEContextUpdate;
89import org.onosproject.xran.codecs.pdu.UEReconfigInd;
90import org.onosproject.xran.codecs.pdu.UEReleaseInd;
91import org.onosproject.xran.codecs.pdu.XICICConfig;
92import org.onosproject.xran.codecs.pdu.XrancPdu;
slowr13fa5b02017-08-08 16:32:31 -070093import org.onosproject.xran.entities.RnibCell;
94import org.onosproject.xran.entities.RnibLink;
95import org.onosproject.xran.entities.RnibUe;
slowr577f3222017-08-28 10:49:08 -070096import org.onosproject.xran.identifiers.ContextUpdateHandler;
slowrc86750e2017-08-22 17:26:47 -070097import org.onosproject.xran.identifiers.EcgiCrntiPair;
slowr13fa5b02017-08-08 16:32:31 -070098import org.onosproject.xran.identifiers.LinkId;
99import org.onosproject.xran.impl.XranConfig;
100import org.onosproject.xran.providers.XranDeviceListener;
101import org.onosproject.xran.providers.XranHostListener;
slowr13fa5b02017-08-08 16:32:31 -0700102import org.onosproject.xran.wrapper.CellMap;
103import org.onosproject.xran.wrapper.LinkMap;
104import org.onosproject.xran.wrapper.UeMap;
slowr13fa5b02017-08-08 16:32:31 -0700105import org.slf4j.Logger;
106import org.slf4j.LoggerFactory;
107
108import java.io.IOException;
slowr577f3222017-08-28 10:49:08 -0700109import java.util.ArrayList;
110import java.util.List;
111import java.util.Optional;
112import java.util.Set;
113import java.util.Timer;
114import java.util.TimerTask;
115import java.util.concurrent.BlockingQueue;
116import java.util.concurrent.ConcurrentHashMap;
117import java.util.concurrent.ConcurrentMap;
118import java.util.concurrent.CopyOnWriteArraySet;
119import java.util.concurrent.LinkedBlockingQueue;
120import java.util.concurrent.SynchronousQueue;
slowr13fa5b02017-08-08 16:32:31 -0700121import java.util.stream.Collectors;
122
123import static org.onosproject.net.DeviceId.deviceId;
slowr67d05e42017-08-11 20:37:22 -0700124import static org.onosproject.xran.controller.XranChannelHandler.getSctpMessage;
slowr13fa5b02017-08-08 16:32:31 -0700125import static org.onosproject.xran.entities.RnibCell.decodeDeviceId;
126import static org.onosproject.xran.entities.RnibCell.uri;
slowrc86750e2017-08-22 17:26:47 -0700127import static org.onosproject.xran.entities.RnibUe.hostIdtoUEId;
slowr13fa5b02017-08-08 16:32:31 -0700128
129/**
130 * Created by dimitris on 7/20/17.
131 */
132@Component(immediate = true)
133@Service
134public class XranControllerImpl implements XranController {
135 private static final String XRAN_APP_ID = "org.onosproject.xran";
136 private static final Class<XranConfig> CONFIG_CLASS = XranConfig.class;
137
138 private static final Logger log =
139 LoggerFactory.getLogger(XranControllerImpl.class);
140 /* CONFIG */
141 private final InternalNetworkConfigListener configListener =
142 new InternalNetworkConfigListener();
143 /* VARIABLES */
144 private final Controller controller = new Controller();
145 private XranConfig xranConfig;
146 private ApplicationId appId;
slowr577f3222017-08-28 10:49:08 -0700147 private int northboundTimeout;
slowr13fa5b02017-08-08 16:32:31 -0700148 /* Services */
149 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
150 private DeviceService deviceService;
151 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
152 private HostService hostService;
153 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
154 private NetworkConfigRegistry registry;
155 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
156 private NetworkConfigService configService;
157 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
158 private CoreService coreService;
159 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
160 private XranStore xranStore;
161 private ConfigFactory<ApplicationId, XranConfig> xranConfigFactory =
162 new ConfigFactory<ApplicationId, XranConfig>(
163 SubjectFactories.APP_SUBJECT_FACTORY, CONFIG_CLASS, "xran") {
164 @Override
165 public XranConfig createConfig() {
166 return new XranConfig();
167 }
168 };
169 /* WRAPPERS */
170 private CellMap cellMap;
171 private UeMap ueMap;
172 private LinkMap linkMap;
173 /* MAPS */
slowr577f3222017-08-28 10:49:08 -0700174 private ConcurrentMap<IpAddress, ECGI> legitCells = new ConcurrentHashMap<>();
slowrc86750e2017-08-22 17:26:47 -0700175 private ConcurrentMap<ECGI, SynchronousQueue<String>> hoMap = new ConcurrentHashMap<>();
slowr577f3222017-08-28 10:49:08 -0700176 private ConcurrentMap<ECGI, SynchronousQueue<String>> rrmcellMap = new ConcurrentHashMap<>();
slowrc86750e2017-08-22 17:26:47 -0700177 private ConcurrentMap<CRNTI, SynchronousQueue<String>> scellAddMap = new ConcurrentHashMap<>();
slowrab685ef2017-08-31 17:17:35 -0700178 // Map used to keep messages in pairs (HO Complete - CTX Update, Adm Status - CTX Update)
slowr577f3222017-08-28 10:49:08 -0700179 private ConcurrentMap<EcgiCrntiPair, ContextUpdateHandler> contextUpdateMap = new ConcurrentHashMap<>();
slowrc86750e2017-08-22 17:26:47 -0700180 /* QUEUE */
181 private BlockingQueue<Long> ueIdQueue = new LinkedBlockingQueue<>();
slowr13fa5b02017-08-08 16:32:31 -0700182 /* AGENTS */
183 private InternalXranDeviceAgent deviceAgent = new InternalXranDeviceAgent();
184 private InternalXranHostAgent hostAgent = new InternalXranHostAgent();
185 private InternalXranPacketAgent packetAgent = new InternalXranPacketAgent();
186 /* LISTENERS */
187 private Set<XranDeviceListener> xranDeviceListeners = new CopyOnWriteArraySet<>();
188 private Set<XranHostListener> xranHostListeners = new CopyOnWriteArraySet<>();
slowr577f3222017-08-28 10:49:08 -0700189 private InternalDeviceListener deviceListener = new InternalDeviceListener();
190 private InternalHostListener hostListener = new InternalHostListener();
slowr13fa5b02017-08-08 16:32:31 -0700191
192 @Activate
193 public void activate() {
194 appId = coreService.registerApplication(XRAN_APP_ID);
195
196 configService.addListener(configListener);
197 registry.registerConfigFactory(xranConfigFactory);
slowr577f3222017-08-28 10:49:08 -0700198 deviceService.addListener(deviceListener);
199 hostService.addListener(hostListener);
slowr13fa5b02017-08-08 16:32:31 -0700200
201 cellMap = new CellMap(xranStore);
202 ueMap = new UeMap(xranStore);
slowrd337c932017-08-18 13:54:02 -0700203 linkMap = new LinkMap(xranStore, ueMap);
slowr13fa5b02017-08-08 16:32:31 -0700204
205 xranStore.setController(this);
206
207 log.info("XRAN Controller Started");
208 }
209
210 @Deactivate
211 public void deactivate() {
slowr577f3222017-08-28 10:49:08 -0700212 deviceService.removeListener(deviceListener);
213 hostService.removeListener(hostListener);
slowr13fa5b02017-08-08 16:32:31 -0700214 configService.removeListener(configListener);
215 registry.unregisterConfigFactory(xranConfigFactory);
216
slowr23a93e12017-09-01 13:26:18 -0700217 cleanup();
218
slowr13fa5b02017-08-08 16:32:31 -0700219 log.info("XRAN Controller Stopped");
220 }
221
slowr23a93e12017-09-01 13:26:18 -0700222 private void cleanup() {
223 xranStore.getuenodes().forEach(ue -> {
224 for (XranHostListener l : xranHostListeners) {
225 l.hostRemoved(((RnibUe) ue).getHostId());
226 }
227 });
228
229 xranStore.getcellnodes().forEach(cell -> {
230 for (XranDeviceListener l : xranDeviceListeners) {
231 l.deviceRemoved(deviceId(uri(((RnibCell) cell).getEcgi())));
232 }
233 });
234
235 controller.stop();
236
237 legitCells.clear();
238 hoMap.clear();
239 rrmcellMap.clear();
240 scellAddMap.clear();
241 contextUpdateMap.clear();
242 ueIdQueue.clear();
243 xranDeviceListeners.clear();
244 xranHostListeners.clear();
245
246 cellMap = null;
247 ueMap = null;
248 linkMap = null;
249 }
250
slowr13fa5b02017-08-08 16:32:31 -0700251 @Override
slowr577f3222017-08-28 10:49:08 -0700252 public SynchronousQueue<String> sendHORequest(RnibLink linkT, RnibLink linkS) throws InterruptedException {
253 ECGI ecgiT = linkT.getLinkId().getEcgi(),
254 ecgiS = linkS.getLinkId().getEcgi();
slowr73b4eae2017-08-17 16:09:09 -0700255
slowr577f3222017-08-28 10:49:08 -0700256 CRNTI crnti = linkMap.getCrnti(linkT.getLinkId().getUeId());
257 ChannelHandlerContext ctxT = cellMap.getCtx(ecgiT),
258 ctxS = cellMap.getCtx(ecgiS);
slowrc86750e2017-08-22 17:26:47 -0700259
260 SynchronousQueue<String> queue = new SynchronousQueue<>();
slowr67d05e42017-08-11 20:37:22 -0700261 try {
slowr577f3222017-08-28 10:49:08 -0700262 XrancPdu xrancPdu = HORequest.constructPacket(crnti, ecgiS, ecgiT);
slowrc86750e2017-08-22 17:26:47 -0700263
slowr577f3222017-08-28 10:49:08 -0700264 // temporary map that has ECGI source of a handoff to a queue waiting for REST response.
265 hoMap.put(ecgiS, queue);
slowrc86750e2017-08-22 17:26:47 -0700266
slowr577f3222017-08-28 10:49:08 -0700267 ctxT.writeAndFlush(getSctpMessage(xrancPdu));
268 ctxS.writeAndFlush(getSctpMessage(xrancPdu));
269
270 // FIXME: only works for one HO at a time.
271 ueIdQueue.put(linkT.getLinkId().getUeId());
slowr67d05e42017-08-11 20:37:22 -0700272 } catch (IOException e) {
273 e.printStackTrace();
274 }
275
slowr67d05e42017-08-11 20:37:22 -0700276 return queue;
277 }
278
279 @Override
slowr13fa5b02017-08-08 16:32:31 -0700280 public void addListener(XranDeviceListener listener) {
281 xranDeviceListeners.add(listener);
282 }
283
284 @Override
285 public void addListener(XranHostListener listener) {
286 xranHostListeners.add(listener);
287 }
288
289 @Override
290 public void removeListener(XranDeviceListener listener) {
291 xranDeviceListeners.remove(listener);
292 }
293
294 @Override
295 public void removeListener(XranHostListener listener) {
296 xranHostListeners.remove(listener);
297 }
298
slowr67d05e42017-08-11 20:37:22 -0700299 @Override
slowr577f3222017-08-28 10:49:08 -0700300 public int getNorthboundTimeout() {
301 return northboundTimeout;
slowrc86750e2017-08-22 17:26:47 -0700302 }
303
304 @Override
slowr577f3222017-08-28 10:49:08 -0700305 public SynchronousQueue<String> sendmodifiedrrmconf(RRMConfig rrmConfig, boolean xicic) {
slowr8ddc2b12017-08-14 14:13:38 -0700306 ECGI ecgi = rrmConfig.getEcgi();
slowr67d05e42017-08-11 20:37:22 -0700307 ChannelHandlerContext ctx = cellMap.getCtx(ecgi);
308 try {
slowrc86750e2017-08-22 17:26:47 -0700309 XrancPdu pdu;
slowr73b4eae2017-08-17 16:09:09 -0700310
slowr577f3222017-08-28 10:49:08 -0700311 if (xicic) {
slowr73b4eae2017-08-17 16:09:09 -0700312 CellConfigReport cellConfigReport = cellMap.get(ecgi).getConf();
313 if (cellConfigReport != null) {
314 pdu = XICICConfig.constructPacket(rrmConfig, cellConfigReport);
315 ctx.writeAndFlush(getSctpMessage(pdu));
316 }
slowr8ddc2b12017-08-14 14:13:38 -0700317 } else {
318 pdu = RRMConfig.constructPacket(rrmConfig);
slowr73b4eae2017-08-17 16:09:09 -0700319 ctx.writeAndFlush(getSctpMessage(pdu));
320 SynchronousQueue<String> queue = new SynchronousQueue<>();
slowr577f3222017-08-28 10:49:08 -0700321 rrmcellMap.put(ecgi, queue);
slowr73b4eae2017-08-17 16:09:09 -0700322 return queue;
slowr8ddc2b12017-08-14 14:13:38 -0700323 }
slowr67d05e42017-08-11 20:37:22 -0700324 } catch (IOException e) {
325 e.printStackTrace();
326 }
slowr67d05e42017-08-11 20:37:22 -0700327
slowr73b4eae2017-08-17 16:09:09 -0700328 return null;
slowr67d05e42017-08-11 20:37:22 -0700329 }
330
slowr89c2ac12017-08-15 16:20:06 -0700331 @Override
332 public SynchronousQueue<String> sendScellAdd(RnibLink link) {
333 RnibCell secondaryCell = link.getLinkId().getCell(),
334 primaryCell = linkMap.getPrimaryCell(link.getLinkId().getUe());
335 ECGI primaryEcgi = primaryCell.getEcgi();
336 ChannelHandlerContext ctx = cellMap.getCtx(primaryEcgi);
337
slowrc86750e2017-08-22 17:26:47 -0700338 CRNTI crnti = linkMap.getCrnti(link.getLinkId().getUeId());
slowr89c2ac12017-08-15 16:20:06 -0700339
340 CellConfigReport cellReport = secondaryCell.getConf();
341
342 if (cellReport != null) {
343 PCIARFCN pciarfcn = new PCIARFCN();
344 pciarfcn.setPci(cellReport.getPci());
345 pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());
346
347 PropScell propScell = new PropScell();
348 propScell.setPciArfcn(pciarfcn);
349
350 XrancPdu pdu = ScellAdd.constructPacket(primaryEcgi, crnti, propScell);
351 try {
352 ctx.writeAndFlush(getSctpMessage(pdu));
353 SynchronousQueue<String> queue = new SynchronousQueue<>();
slowrc86750e2017-08-22 17:26:47 -0700354 scellAddMap.put(crnti, queue);
slowr89c2ac12017-08-15 16:20:06 -0700355
356 return queue;
357 } catch (IOException e) {
358 log.error(ExceptionUtils.getFullStackTrace(e));
359 e.printStackTrace();
360 }
361 }
362 return null;
363 }
364
365 @Override
366 public boolean sendScellDelete(RnibLink link) {
367 RnibCell secondaryCell = link.getLinkId().getCell(),
368 primaryCell = linkMap.getPrimaryCell(link.getLinkId().getUe());
369 ECGI primaryEcgi = primaryCell.getEcgi();
370 ChannelHandlerContext ctx = cellMap.getCtx(primaryEcgi);
371
slowrc86750e2017-08-22 17:26:47 -0700372 CRNTI crnti = linkMap.getCrnti(link.getLinkId().getUeId());
slowr89c2ac12017-08-15 16:20:06 -0700373
374 CellConfigReport cellReport = secondaryCell.getConf();
375
376 if (cellReport != null) {
377 PCIARFCN pciarfcn = new PCIARFCN();
378 pciarfcn.setPci(cellReport.getPci());
379 pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());
380
381 XrancPdu pdu = ScellDelete.constructPacket(primaryEcgi, crnti, pciarfcn);
382
383 try {
384 ctx.writeAndFlush(getSctpMessage(pdu));
385 link.setType(RnibLink.Type.NON_SERVING);
386 return true;
387 } catch (IOException e) {
388 log.error(ExceptionUtils.getFullStackTrace(e));
389 e.printStackTrace();
390 }
391 }
392 return false;
393 }
394
slowr577f3222017-08-28 10:49:08 -0700395 /**
396 * Timer to delete UE after being IDLE.
397 *
398 * @param ue UE entity
399 */
slowr13fa5b02017-08-08 16:32:31 -0700400 private void restartTimer(RnibUe ue) {
401 Timer timer = new Timer();
402 ue.setTimer(timer);
slowr13fa5b02017-08-08 16:32:31 -0700403 timer.schedule(new TimerTask() {
404 @Override
405 public void run() {
slowr67d05e42017-08-11 20:37:22 -0700406 if (ue.getState() == RnibUe.State.IDLE) {
slowr13fa5b02017-08-08 16:32:31 -0700407 hostAgent.removeConnectedHost(ue);
slowrc86750e2017-08-22 17:26:47 -0700408 log.info("UE is removed after {} ms of IDLE", xranConfig.getIdleUeRemoval());
slowr13fa5b02017-08-08 16:32:31 -0700409 } else {
410 log.info("UE not removed cause its ACTIVE");
411 }
412 }
slowrd337c932017-08-18 13:54:02 -0700413 }, xranConfig.getIdleUeRemoval());
slowr13fa5b02017-08-08 16:32:31 -0700414 }
415
slowr577f3222017-08-28 10:49:08 -0700416 /**
417 * Timer to delete LINK after not receiving measurements.
418 *
419 * @param link LINK entity
420 */
slowr13fa5b02017-08-08 16:32:31 -0700421 private void restartTimer(RnibLink link) {
422 Timer timer = new Timer();
423 link.setTimer(timer);
slowr13fa5b02017-08-08 16:32:31 -0700424 timer.schedule(new TimerTask() {
425 @Override
426 public void run() {
427 LinkId linkId = link.getLinkId();
428 xranStore.removeLink(linkId);
slowr577f3222017-08-28 10:49:08 -0700429 log.info("Link is removed after not receiving Meas Reports for {} ms",
430 xranConfig.getNoMeasLinkRemoval());
slowr13fa5b02017-08-08 16:32:31 -0700431 }
slowrd337c932017-08-18 13:54:02 -0700432 }, xranConfig.getNoMeasLinkRemoval());
slowr13fa5b02017-08-08 16:32:31 -0700433
434 }
435
slowr577f3222017-08-28 10:49:08 -0700436 /**
437 * Request measurement configuration field of specified UE.
438 *
439 * @param primary primary CELL
440 * @param ue UE entity
441 */
442 private void populateMeasConfig(RnibCell primary, RnibUe ue) {
443 try {
444 ChannelHandlerContext ctx = cellMap.getCtx(primary.getEcgi());
445 RXSigMeasConfig.MeasCells measCells = new RXSigMeasConfig.MeasCells();
446 xranStore.getcellnodes().forEach(cell -> {
447 CellConfigReport cellReport = ((RnibCell) cell).getConf();
448 if (cellReport != null) {
449 PCIARFCN pciarfcn = new PCIARFCN();
450 pciarfcn.setPci(cellReport.getPci());
451 pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());
452 measCells.setPCIARFCN(pciarfcn);
453 }
454 });
455 XrancPdu xrancPdu = RXSigMeasConfig.constructPacket(
456 primary.getEcgi(),
457 ue.getCrnti(),
458 measCells,
459 xranConfig.getRxSignalInterval()
460 );
461 ue.setMeasConfig(xrancPdu.getBody().getRXSigMeasConfig());
462 ctx.writeAndFlush(getSctpMessage(xrancPdu));
463 } catch (IOException e) {
464 log.warn(ExceptionUtils.getFullStackTrace(e));
465 e.printStackTrace();
466 }
467 }
468
469 /**
470 * Internal device listener.
471 */
slowr13fa5b02017-08-08 16:32:31 -0700472 class InternalDeviceListener implements DeviceListener {
473
474 @Override
475 public void event(DeviceEvent event) {
476 log.info("Device Event {}", event);
477 switch (event.type()) {
478 case DEVICE_ADDED: {
479 try {
480 ECGI ecgi = decodeDeviceId(event.subject().id());
481 RnibCell cell = cellMap.get(ecgi);
482 if (cell != null) {
483 Timer timer = new Timer();
484 timer.scheduleAtFixedRate(
485 new TimerTask() {
486 @Override
487 public void run() {
488 CellConfigReport conf = cell.getConf();
489 if (conf == null) {
490 try {
491 ChannelHandlerContext ctx = cellMap.getCtx(ecgi);
slowr8ddc2b12017-08-14 14:13:38 -0700492 XrancPdu xrancPdu = CellConfigRequest.constructPacket(ecgi);
slowr67d05e42017-08-11 20:37:22 -0700493 ctx.writeAndFlush(getSctpMessage(xrancPdu));
slowr13fa5b02017-08-08 16:32:31 -0700494 } catch (IOException e) {
495 log.error(ExceptionUtils.getFullStackTrace(e));
496 e.printStackTrace();
497 }
498 } else {
slowr577f3222017-08-28 10:49:08 -0700499 List<Object> ueNodes = xranStore.getuenodes();
slowrd337c932017-08-18 13:54:02 -0700500 ueNodes.forEach(object -> {
501 RnibUe ue = (RnibUe) object;
502 try {
slowr577f3222017-08-28 10:49:08 -0700503 ECGI primaryEcgi = linkMap.getPrimaryCell(ue).getEcgi();
504 ChannelHandlerContext ctx = cellMap.getCtx(primaryEcgi);
505 RXSigMeasConfig.MeasCells measCells =
506 new RXSigMeasConfig.MeasCells();
507 xranStore.getcellnodes().forEach(cell -> {
slowrd337c932017-08-18 13:54:02 -0700508 CellConfigReport cellReport = ((RnibCell) cell).getConf();
509 if (cellReport != null) {
510 PCIARFCN pciarfcn = new PCIARFCN();
511 pciarfcn.setPci(cellReport.getPci());
512 pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());
513 measCells.setPCIARFCN(pciarfcn);
514 }
515 });
516 XrancPdu xrancPdu = RXSigMeasConfig.constructPacket(
slowr577f3222017-08-28 10:49:08 -0700517 primaryEcgi,
slowrc86750e2017-08-22 17:26:47 -0700518 ue.getCrnti(),
slowrd337c932017-08-18 13:54:02 -0700519 measCells,
520 xranConfig.getRxSignalInterval()
521 );
522 ue.setMeasConfig(xrancPdu.getBody().getRXSigMeasConfig());
523 ctx.writeAndFlush(getSctpMessage(xrancPdu));
524 } catch (IOException e) {
525 log.warn(ExceptionUtils.getFullStackTrace(e));
526 e.printStackTrace();
527 }
528 });
529
slowr13fa5b02017-08-08 16:32:31 -0700530 try {
slowrd337c932017-08-18 13:54:02 -0700531 ChannelHandlerContext ctx = cellMap.getCtx(ecgi);
slowr577f3222017-08-28 10:49:08 -0700532 XrancPdu xrancPdu = L2MeasConfig
533 .constructPacket(ecgi, xranConfig.getL2MeasInterval());
slowr13fa5b02017-08-08 16:32:31 -0700534 cell.setMeasConfig(xrancPdu.getBody().getL2MeasConfig());
slowr67d05e42017-08-11 20:37:22 -0700535 SctpMessage sctpMessage = getSctpMessage(xrancPdu);
slowr13fa5b02017-08-08 16:32:31 -0700536 ctx.writeAndFlush(sctpMessage);
537 } catch (IOException e) {
538 log.error(ExceptionUtils.getFullStackTrace(e));
539 e.printStackTrace();
540 }
541 timer.cancel();
542 timer.purge();
543 }
544 }
545 },
546 0,
547 xranConfig.getConfigRequestInterval() * 1000
548 );
549 }
550 } catch (IOException e) {
551 log.error(ExceptionUtils.getFullStackTrace(e));
552 e.printStackTrace();
553 }
554 break;
555 }
556 default: {
557 break;
558 }
559 }
560 }
561 }
562
slowr577f3222017-08-28 10:49:08 -0700563 /**
564 * Internal host listener.
565 */
slowr13fa5b02017-08-08 16:32:31 -0700566 class InternalHostListener implements HostListener {
567
568 @Override
569 public void event(HostEvent event) {
570 log.info("Host Event {}", event);
571 switch (event.type()) {
572 case HOST_ADDED:
573 case HOST_MOVED: {
slowrc86750e2017-08-22 17:26:47 -0700574 RnibUe ue = ueMap.get(hostIdtoUEId(event.subject().id()));
slowr13fa5b02017-08-08 16:32:31 -0700575 if (ue != null) {
slowr577f3222017-08-28 10:49:08 -0700576 ECGI ecgiPrimary = linkMap.getPrimaryCell(ue).getEcgi();
577 RnibCell primary = cellMap.get(ecgiPrimary);
slowr13fa5b02017-08-08 16:32:31 -0700578 ue.setMeasConfig(null);
579 if (primary != null) {
580 Timer timer = new Timer();
581 timer.scheduleAtFixedRate(
582 new TimerTask() {
583 @Override
584 public void run() {
slowred74ec72017-08-17 11:25:01 -0700585 if (ue.getCapability() == null && primary.getVersion() >= 3) {
slowr13fa5b02017-08-08 16:32:31 -0700586 try {
587 ChannelHandlerContext ctx = cellMap.getCtx(primary.getEcgi());
slowr8ddc2b12017-08-14 14:13:38 -0700588 XrancPdu xrancPdu = UECapabilityEnquiry.constructPacket(
slowr67d05e42017-08-11 20:37:22 -0700589 primary.getEcgi(),
slowrc86750e2017-08-22 17:26:47 -0700590 ue.getCrnti());
slowr67d05e42017-08-11 20:37:22 -0700591 ctx.writeAndFlush(getSctpMessage(xrancPdu));
slowr13fa5b02017-08-08 16:32:31 -0700592 } catch (IOException e) {
593 log.warn(ExceptionUtils.getFullStackTrace(e));
594 e.printStackTrace();
595 }
596 } else {
slowr13fa5b02017-08-08 16:32:31 -0700597 timer.cancel();
598 timer.purge();
599 }
600 }
601 },
602 0,
603 xranConfig.getConfigRequestInterval() * 1000
604 );
slowred74ec72017-08-17 11:25:01 -0700605 if (ue.getMeasConfig() == null) {
slowr577f3222017-08-28 10:49:08 -0700606 populateMeasConfig(primary, ue);
slowred74ec72017-08-17 11:25:01 -0700607 }
slowr13fa5b02017-08-08 16:32:31 -0700608 }
609 }
610 break;
611 }
612 default: {
613 break;
614 }
615 }
616 }
617 }
618
slowr577f3222017-08-28 10:49:08 -0700619 /**
620 * Internal xran device agent.
621 */
slowr13fa5b02017-08-08 16:32:31 -0700622 public class InternalXranDeviceAgent implements XranDeviceAgent {
623
624 private final Logger log = LoggerFactory.getLogger(InternalXranDeviceAgent.class);
625
626 @Override
627 public boolean addConnectedCell(String host, ChannelHandlerContext ctx) {
slowr577f3222017-08-28 10:49:08 -0700628 ECGI ecgi = legitCells.get(IpAddress.valueOf(host));
slowr13fa5b02017-08-08 16:32:31 -0700629
630 if (ecgi == null) {
631 log.error("Device is not a legit source; ignoring...");
632 } else {
633 log.info("Device exists in configuration; registering...");
634 RnibCell storeCell = cellMap.get(ecgi);
635 if (storeCell == null) {
636 storeCell = new RnibCell();
637 storeCell.setEcgi(ecgi);
638 cellMap.put(storeCell, ctx);
639
640 for (XranDeviceListener l : xranDeviceListeners) {
641 l.deviceAdded(storeCell);
642 }
643 return true;
644 } else {
645 log.error("Device already registered; ignoring...");
646 }
647 }
648 ctx.close();
649 return false;
650 }
651
652 @Override
653 public boolean removeConnectedCell(String host) {
slowr577f3222017-08-28 10:49:08 -0700654 ECGI ecgi = legitCells.get(IpAddress.valueOf(host));
655 List<RnibLink> linksbyecgi = xranStore.getlinksbyecgi(ecgi);
slowr13fa5b02017-08-08 16:32:31 -0700656
slowr577f3222017-08-28 10:49:08 -0700657 linksbyecgi.forEach(rnibLink -> xranStore.removeLink(rnibLink.getLinkId()));
slowr13fa5b02017-08-08 16:32:31 -0700658
659 if (cellMap.remove(ecgi)) {
660 for (XranDeviceListener l : xranDeviceListeners) {
661 l.deviceRemoved(deviceId(uri(ecgi)));
662 }
663 return true;
664 }
665 return false;
666 }
667 }
668
slowr577f3222017-08-28 10:49:08 -0700669 /**
670 * Internal xran host agent.
671 */
slowr13fa5b02017-08-08 16:32:31 -0700672 public class InternalXranHostAgent implements XranHostAgent {
673
674 @Override
675 public boolean addConnectedHost(RnibUe ue, RnibCell cell, ChannelHandlerContext ctx) {
676
slowrc86750e2017-08-22 17:26:47 -0700677 if (ue.getId() != null && ueMap.get(ue.getId()) != null) {
slowr13fa5b02017-08-08 16:32:31 -0700678 linkMap.putPrimaryLink(cell, ue);
679
slowrc86750e2017-08-22 17:26:47 -0700680 Set<ECGI> ecgiSet = Sets.newConcurrentHashSet();
681
slowr577f3222017-08-28 10:49:08 -0700682 xranStore.getlinksbyueid(ue.getId())
slowr13fa5b02017-08-08 16:32:31 -0700683 .stream()
slowrc86750e2017-08-22 17:26:47 -0700684 .filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY))
slowr577f3222017-08-28 10:49:08 -0700685 .findFirst()
686 .ifPresent(l -> ecgiSet.add(l.getLinkId().getEcgi()));
slowr13fa5b02017-08-08 16:32:31 -0700687
688 for (XranHostListener l : xranHostListeners) {
689 l.hostAdded(ue, ecgiSet);
690 }
691 return true;
692 } else {
slowrd337c932017-08-18 13:54:02 -0700693 ueMap.put(cell, ue);
slowr13fa5b02017-08-08 16:32:31 -0700694 linkMap.putPrimaryLink(cell, ue);
695
696 Set<ECGI> ecgiSet = Sets.newConcurrentHashSet();
697 ecgiSet.add(cell.getEcgi());
698 for (XranHostListener l : xranHostListeners) {
699 l.hostAdded(ue, ecgiSet);
700 }
701 return true;
702 }
703
704 }
705
706 @Override
707 public boolean removeConnectedHost(RnibUe ue) {
slowr577f3222017-08-28 10:49:08 -0700708 List<RnibLink> links = xranStore.getlinksbyueid(ue.getId());
slowr13fa5b02017-08-08 16:32:31 -0700709 links.forEach(rnibLink -> xranStore.removeLink(rnibLink.getLinkId()));
slowrc86750e2017-08-22 17:26:47 -0700710 if (ueMap.remove(ue.getId())) {
slowr13fa5b02017-08-08 16:32:31 -0700711 for (XranHostListener l : xranHostListeners) {
712 l.hostRemoved(ue.getHostId());
713 }
714 return true;
715 }
716 return false;
717 }
718 }
719
720 public class InternalXranPacketAgent implements XranPacketProcessor {
721 @Override
slowr577f3222017-08-28 10:49:08 -0700722 public void handlePacket(XrancPdu recvPdu, ChannelHandlerContext ctx)
723 throws IOException, InterruptedException {
724 XrancPdu sendPdu;
slowr13fa5b02017-08-08 16:32:31 -0700725
slowr577f3222017-08-28 10:49:08 -0700726 int apiID = recvPdu.getHdr().getApiId().intValue();
727 log.debug("Received message: {}", recvPdu);
slowr13fa5b02017-08-08 16:32:31 -0700728 switch (apiID) {
729 case 1: {
730 // Decode Cell config report.
slowr577f3222017-08-28 10:49:08 -0700731 CellConfigReport report = recvPdu.getBody().getCellConfigReport();
732 handleCellconfigreport(report, recvPdu.getHdr().getVer().toString());
slowr13fa5b02017-08-08 16:32:31 -0700733 break;
734 }
735 case 2: {
736 // Decode UE Admission Request.
slowr577f3222017-08-28 10:49:08 -0700737 UEAdmissionRequest ueAdmissionRequest = recvPdu.getBody().getUEAdmissionRequest();
738 handleUeadmissionrequest(ueAdmissionRequest, ctx);
slowr13fa5b02017-08-08 16:32:31 -0700739 break;
740 }
741 case 4: {
742 // Decode UE Admission Status.
slowr577f3222017-08-28 10:49:08 -0700743 UEAdmissionStatus ueAdmissionStatus = recvPdu.getBody().getUEAdmissionStatus();
744 handleAdmissionstatus(ueAdmissionStatus, ctx);
slowr13fa5b02017-08-08 16:32:31 -0700745 break;
746 }
747 case 5: {
slowrc86750e2017-08-22 17:26:47 -0700748 // Decode UE Context Update.
slowr577f3222017-08-28 10:49:08 -0700749 UEContextUpdate ueContextUpdate = recvPdu.getBody().getUEContextUpdate();
750 handleUecontextupdate(ueContextUpdate, ctx);
slowr73b4eae2017-08-17 16:09:09 -0700751
slowr13fa5b02017-08-08 16:32:31 -0700752 break;
753 }
754 case 6: {
755 // Decode UE Reconfig_Ind.
slowr577f3222017-08-28 10:49:08 -0700756 UEReconfigInd ueReconfigInd = recvPdu.getBody().getUEReconfigInd();
757 handleUereconfigind(ueReconfigInd);
slowr13fa5b02017-08-08 16:32:31 -0700758 break;
759 }
760 case 7: {
761 // If xRANc wants to deactivate UE, we pass UEReleaseInd from xRANc to eNB.
762 // Decode UE Release_Ind.
slowr577f3222017-08-28 10:49:08 -0700763 UEReleaseInd ueReleaseInd = recvPdu.getBody().getUEReleaseInd();
764 handleUereleaseind(ueReleaseInd);
slowr13fa5b02017-08-08 16:32:31 -0700765 break;
766 }
767 case 8: {
768 // Decode Bearer Adm Request
slowr577f3222017-08-28 10:49:08 -0700769 BearerAdmissionRequest bearerAdmissionRequest = recvPdu.getBody().getBearerAdmissionRequest();
770 handleBeareradmissionrequest(bearerAdmissionRequest, ctx);
slowr13fa5b02017-08-08 16:32:31 -0700771 break;
772 }
773 case 10: {
774 //Decode Bearer Admission Status
slowr577f3222017-08-28 10:49:08 -0700775 BearerAdmissionStatus bearerAdmissionStatus = recvPdu.getBody().getBearerAdmissionStatus();
slowr8ddc2b12017-08-14 14:13:38 -0700776 break;
slowr13fa5b02017-08-08 16:32:31 -0700777 }
778 case 11: {
779 //Decode Bearer Release Ind
slowr577f3222017-08-28 10:49:08 -0700780 BearerReleaseInd bearerReleaseInd = recvPdu.getBody().getBearerReleaseInd();
781 handleBearerreleaseind(bearerReleaseInd);
slowr13fa5b02017-08-08 16:32:31 -0700782 break;
783 }
784 case 13: {
slowr577f3222017-08-28 10:49:08 -0700785 HOFailure hoFailure = recvPdu.getBody().getHOFailure();
786 handleHofailure(hoFailure);
slowr67d05e42017-08-11 20:37:22 -0700787 break;
slowr8ddc2b12017-08-14 14:13:38 -0700788
slowr67d05e42017-08-11 20:37:22 -0700789 }
slowr8ddc2b12017-08-14 14:13:38 -0700790 case 14: {
slowr577f3222017-08-28 10:49:08 -0700791 HOComplete hoComplete = recvPdu.getBody().getHOComplete();
792 handleHocomplete(hoComplete, ctx);
slowr67d05e42017-08-11 20:37:22 -0700793 break;
794 }
slowr8ddc2b12017-08-14 14:13:38 -0700795
796 case 16: {
slowr577f3222017-08-28 10:49:08 -0700797 // Decode Rx Sig Meas Report.
798 RXSigMeasReport rxSigMeasReport = recvPdu.getBody().getRXSigMeasReport();
799 handleRxsigmeasreport(rxSigMeasReport);
slowr13fa5b02017-08-08 16:32:31 -0700800 break;
801 }
slowr8ddc2b12017-08-14 14:13:38 -0700802 case 18: {
slowr577f3222017-08-28 10:49:08 -0700803 RadioMeasReportPerUE radioMeasReportPerUE = recvPdu.getBody().getRadioMeasReportPerUE();
804 handleRadionmeasreportperue(radioMeasReportPerUE);
slowr67d05e42017-08-11 20:37:22 -0700805 break;
slowr13fa5b02017-08-08 16:32:31 -0700806 }
slowr8ddc2b12017-08-14 14:13:38 -0700807 case 19: {
slowr577f3222017-08-28 10:49:08 -0700808 RadioMeasReportPerCell radioMeasReportPerCell = recvPdu.getBody().getRadioMeasReportPerCell();
slowr13fa5b02017-08-08 16:32:31 -0700809 break;
810 }
slowr8ddc2b12017-08-14 14:13:38 -0700811 case 20: {
slowr577f3222017-08-28 10:49:08 -0700812 SchedMeasReportPerUE schedMeasReportPerUE = recvPdu.getBody().getSchedMeasReportPerUE();
813 handleSchedmeasreportperue(schedMeasReportPerUE);
slowr13fa5b02017-08-08 16:32:31 -0700814 break;
815 }
slowr8ddc2b12017-08-14 14:13:38 -0700816 case 21: {
slowr577f3222017-08-28 10:49:08 -0700817 SchedMeasReportPerCell schedMeasReportPerCell = recvPdu.getBody().getSchedMeasReportPerCell();
818 handleSchedmeasreportpercell(schedMeasReportPerCell);
slowr13fa5b02017-08-08 16:32:31 -0700819 break;
820 }
slowr8ddc2b12017-08-14 14:13:38 -0700821 case 22: {
slowr577f3222017-08-28 10:49:08 -0700822 PDCPMeasReportPerUe pdcpMeasReportPerUe = recvPdu.getBody().getPDCPMeasReportPerUe();
823 handlePdcpmeasreportperue(pdcpMeasReportPerUe);
slowr13fa5b02017-08-08 16:32:31 -0700824 break;
825 }
slowr8ddc2b12017-08-14 14:13:38 -0700826 case 24: {
827 // Decode UE Capability Info
slowr577f3222017-08-28 10:49:08 -0700828 UECapabilityInfo capabilityInfo = recvPdu.getBody().getUECapabilityInfo();
829 handleCapabilityinfo(capabilityInfo);
slowr8ddc2b12017-08-14 14:13:38 -0700830 break;
831 }
832 case 25: {
833 // Don't know what will invoke sending UE CAPABILITY ENQUIRY
834 // Encode and send UE CAPABILITY ENQUIRY
slowr577f3222017-08-28 10:49:08 -0700835 UECapabilityEnquiry ueCapabilityEnquiry = recvPdu.getBody().getUECapabilityEnquiry();
836 handleUecapabilityenquiry(ueCapabilityEnquiry, ctx);
slowr8ddc2b12017-08-14 14:13:38 -0700837 break;
838 }
slowr89c2ac12017-08-15 16:20:06 -0700839 case 27: {
840 //Decode ScellAddStatus
slowr577f3222017-08-28 10:49:08 -0700841 ScellAddStatus scellAddStatus = recvPdu.getBody().getScellAddStatus();
842 handleScelladdstatus(scellAddStatus);
slowr89c2ac12017-08-15 16:20:06 -0700843 break;
844 }
slowr8ddc2b12017-08-14 14:13:38 -0700845 case 30: {
846 // Decode RRMConfig Status
slowr577f3222017-08-28 10:49:08 -0700847 RRMConfigStatus rrmConfigStatus = recvPdu.getBody().getRRMConfigStatus();
848 handleRrmconfigstatus(rrmConfigStatus);
slowr67d05e42017-08-11 20:37:22 -0700849 break;
850 }
slowr8ddc2b12017-08-14 14:13:38 -0700851 //TODO Case 31: SeNBAdd 32: SeNBAddStatus 33: SeNBDelete
slowr13fa5b02017-08-08 16:32:31 -0700852 case 34: {
slowr577f3222017-08-28 10:49:08 -0700853 TrafficSplitConfig trafficSplitConfig = recvPdu.getBody().getTrafficSplitConfig();
854 handleTrafficSplitConfig(trafficSplitConfig);
slowr67d05e42017-08-11 20:37:22 -0700855 break;
slowr13fa5b02017-08-08 16:32:31 -0700856 }
857 default: {
slowr577f3222017-08-28 10:49:08 -0700858 log.warn("Wrong API ID: {}", recvPdu);
slowr67d05e42017-08-11 20:37:22 -0700859 break;
slowr13fa5b02017-08-08 16:32:31 -0700860 }
861 }
862
863 }
slowrc86750e2017-08-22 17:26:47 -0700864
slowr577f3222017-08-28 10:49:08 -0700865 /**
866 * Handle Cellconfigreport.
slowr23a93e12017-09-01 13:26:18 -0700867 *
868 * @param report CellConfigReport
slowr577f3222017-08-28 10:49:08 -0700869 * @param version String version ID
870 */
871 private void handleCellconfigreport(CellConfigReport report, String version) {
872 ECGI ecgi = report.getEcgi();
873
874 RnibCell cell = xranStore.getCell(ecgi);
875 cell.setVersion(version);
876 cell.setConf(report);
877 cellMap.putPciArfcn(cell);
878 }
879
880 /**
881 * Handle Ueadmissionrequest.
slowr23a93e12017-09-01 13:26:18 -0700882 *
slowr577f3222017-08-28 10:49:08 -0700883 * @param ueAdmissionRequest UEAdmissionRequest
slowr23a93e12017-09-01 13:26:18 -0700884 * @param ctx ChannelHandlerContext
slowr577f3222017-08-28 10:49:08 -0700885 * @throws IOException IO Exception
886 */
887 private void handleUeadmissionrequest(UEAdmissionRequest ueAdmissionRequest, ChannelHandlerContext ctx)
888 throws IOException {
889 ECGI ecgi = ueAdmissionRequest.getEcgi();
890 if (xranStore.getCell(ecgi) != null) {
891 CRNTI crnti = ueAdmissionRequest.getCrnti();
892 XrancPdu sendPdu = UEAdmissionResponse.constructPacket(ecgi, crnti, xranConfig.admissionFlag());
893 ctx.writeAndFlush(getSctpMessage(sendPdu));
894 } else {
895 log.warn("Could not find ECGI in registered cells: {}", ecgi);
896 }
897 }
898
899 /**
900 * Handle UEAdmissionStatus.
slowr23a93e12017-09-01 13:26:18 -0700901 *
slowr577f3222017-08-28 10:49:08 -0700902 * @param ueAdmissionStatus UEAdmissionStatus
slowr23a93e12017-09-01 13:26:18 -0700903 * @param ctx ChannelHandlerContext
slowr577f3222017-08-28 10:49:08 -0700904 */
905 private void handleAdmissionstatus(UEAdmissionStatus ueAdmissionStatus, ChannelHandlerContext ctx) {
906 RnibUe ue = ueMap.get(ueAdmissionStatus.getEcgi(), ueAdmissionStatus.getCrnti());
907 if (ue != null) {
908 if (ueAdmissionStatus.getAdmEstStatus().value.intValue() == 0) {
909 ue.setState(RnibUe.State.ACTIVE);
910 } else {
911 ue.setState(RnibUe.State.IDLE);
912 }
913 }
914
915 if (ueAdmissionStatus.getAdmEstStatus().value.intValue() == 0) {
916 EcgiCrntiPair ecgiCrntiPair = EcgiCrntiPair
917 .valueOf(ueAdmissionStatus.getEcgi(), ueAdmissionStatus.getCrnti());
918 contextUpdateMap.compute(ecgiCrntiPair, (k, v) -> {
919 if (v == null) {
920 v = new ContextUpdateHandler();
921 }
922 if (v.setAdmissionStatus(ueAdmissionStatus)) {
slowrab685ef2017-08-31 17:17:35 -0700923 handlePairedPackets(v.getContextUpdate(), ctx, false);
924 v.reset();
slowr577f3222017-08-28 10:49:08 -0700925 }
926 return v;
927 });
928 }
929 }
930
931 /**
932 * Handle UEContextUpdate.
slowr23a93e12017-09-01 13:26:18 -0700933 *
slowr577f3222017-08-28 10:49:08 -0700934 * @param ueContextUpdate UEContextUpdate
slowr23a93e12017-09-01 13:26:18 -0700935 * @param ctx ChannelHandlerContext
slowr577f3222017-08-28 10:49:08 -0700936 */
937 private void handleUecontextupdate(UEContextUpdate ueContextUpdate, ChannelHandlerContext ctx) {
938 EcgiCrntiPair ecgiCrntiPair = EcgiCrntiPair
939 .valueOf(ueContextUpdate.getEcgi(), ueContextUpdate.getCrnti());
940
941 contextUpdateMap.compute(ecgiCrntiPair, (k, v) -> {
942 if (v == null) {
943 v = new ContextUpdateHandler();
944 }
945 if (v.setContextUpdate(ueContextUpdate)) {
946 HOComplete hoComplete = v.getHoComplete();
slowrab685ef2017-08-31 17:17:35 -0700947 handlePairedPackets(ueContextUpdate, ctx, hoComplete != null);
slowr577f3222017-08-28 10:49:08 -0700948 if (hoComplete != null) {
949 try {
950 hoMap.get(hoComplete.getEcgiS()).put("Hand Over Completed");
951 } catch (InterruptedException e) {
952 log.error(ExceptionUtils.getFullStackTrace(e));
953 e.printStackTrace();
954 } finally {
955 hoMap.remove(hoComplete.getEcgiS());
956 }
957 }
slowrab685ef2017-08-31 17:17:35 -0700958 v.reset();
slowr577f3222017-08-28 10:49:08 -0700959 }
960 return v;
961 });
962 }
963
964 /**
965 * Handle UEReconfigInd.
slowr23a93e12017-09-01 13:26:18 -0700966 *
slowr577f3222017-08-28 10:49:08 -0700967 * @param ueReconfigInd UEReconfigInd
968 */
969 private void handleUereconfigind(UEReconfigInd ueReconfigInd) {
970 RnibUe ue = ueMap.get(ueReconfigInd.getEcgi(), ueReconfigInd.getCrntiOld());
971 RnibCell cell = cellMap.get(ueReconfigInd.getEcgi());
972
973 if (ue != null && cell != null) {
974 ue.setCrnti(ueReconfigInd.getCrntiNew());
975 ueMap.putCrnti(cell, ue);
976 } else {
977 log.warn("Could not find UE with this CRNTI: {}", ueReconfigInd.getCrntiOld());
978 }
979 }
980
981 /**
982 * Handle UEReleaseInd.
slowr23a93e12017-09-01 13:26:18 -0700983 *
slowr577f3222017-08-28 10:49:08 -0700984 * @param ueReleaseInd UEReleaseInd
985 */
986 private void handleUereleaseind(UEReleaseInd ueReleaseInd) {
987 ECGI ecgi = ueReleaseInd.getEcgi();
988 CRNTI crnti = ueReleaseInd.getCrnti();
989 RnibUe ue = ueMap.get(ecgi, crnti);
990
991 // Check if there is an ongoing handoff and only remove if ue is not part of the handoff.
992 Long peek = ueIdQueue.peek();
993 if (peek != null) {
994 EcgiCrntiPair ecgiCrntiPair = ueMap.getCrntUe().inverse().get(peek);
995 if (ecgiCrntiPair != null && ecgiCrntiPair.equals(EcgiCrntiPair.valueOf(ecgi, crnti))) {
996 return;
997 }
998 }
999
1000 if (ue != null) {
1001 ue.setState(RnibUe.State.IDLE);
1002 restartTimer(ue);
1003 } else {
1004 log.warn("Cannot release UE from non primary link.");
1005 }
1006 }
1007
1008 /**
1009 * Handle BearerAdmissionRequest.
slowr23a93e12017-09-01 13:26:18 -07001010 *
slowr577f3222017-08-28 10:49:08 -07001011 * @param bearerAdmissionRequest BearerAdmissionRequest
slowr23a93e12017-09-01 13:26:18 -07001012 * @param ctx ChannelHandlerContext
slowr577f3222017-08-28 10:49:08 -07001013 * @throws IOException IO Exception
1014 */
1015 private void handleBeareradmissionrequest(BearerAdmissionRequest bearerAdmissionRequest,
1016 ChannelHandlerContext ctx) throws IOException {
1017 ECGI ecgi = bearerAdmissionRequest.getEcgi();
1018 CRNTI crnti = bearerAdmissionRequest.getCrnti();
1019 ERABParams erabParams = bearerAdmissionRequest.getErabParams();
1020 RnibLink link = linkMap.get(ecgi, crnti);
1021 if (link != null) {
1022 link.setBearerParameters(erabParams);
1023 } else {
1024 log.warn("Could not find link between {}-{}", ecgi, crnti);
1025 }
1026
1027 BerInteger numErabs = bearerAdmissionRequest.getNumErabs();
1028 // Encode and send Bearer Admission Response
1029 XrancPdu sendPdu = BearerAdmissionResponse
1030 .constructPacket(ecgi, crnti, erabParams, numErabs, xranConfig.bearerFlag());
1031 ctx.writeAndFlush(getSctpMessage(sendPdu));
1032 }
1033
1034 /**
1035 * Handle BearerReleaseInd.
slowr23a93e12017-09-01 13:26:18 -07001036 *
slowr577f3222017-08-28 10:49:08 -07001037 * @param bearerReleaseInd
1038 */
1039 private void handleBearerreleaseind(BearerReleaseInd bearerReleaseInd) {
1040 ECGI ecgi = bearerReleaseInd.getEcgi();
1041 CRNTI crnti = bearerReleaseInd.getCrnti();
1042 RnibLink link = linkMap.get(ecgi, crnti);
1043
1044 List<ERABID> erabidsRelease = bearerReleaseInd.getErabIds().getERABID();
1045 List<ERABParamsItem> erabParamsItem = link.getBearerParameters().getERABParamsItem();
1046
1047 List<ERABParamsItem> unreleased = erabParamsItem
1048 .stream()
1049 .filter(item -> {
1050 Optional<ERABID> any = erabidsRelease.stream()
1051 .filter(id -> id.equals(item.getId())).findAny();
1052 return !any.isPresent();
1053 }).collect(Collectors.toList());
1054
1055 link.getBearerParameters().setERABParamsItem(new ArrayList<>(unreleased));
1056 }
1057
1058 /**
1059 * Handle HOFailure.
slowr23a93e12017-09-01 13:26:18 -07001060 *
slowr577f3222017-08-28 10:49:08 -07001061 * @param hoFailure HOFailure
1062 * @throws InterruptedException ueIdQueue interruption
1063 */
1064 private void handleHofailure(HOFailure hoFailure) throws InterruptedException {
1065 try {
1066 hoMap.get(hoFailure.getEcgi())
1067 .put("Hand Over Failed with cause: " + hoFailure.getCause());
1068 } catch (InterruptedException e) {
1069 log.error(ExceptionUtils.getFullStackTrace(e));
1070 e.printStackTrace();
1071 } finally {
1072 hoMap.remove(hoFailure.getEcgi());
1073 ueIdQueue.take();
1074 }
1075 }
1076
1077 /**
1078 * Handle HOComplete.
slowr23a93e12017-09-01 13:26:18 -07001079 *
slowr577f3222017-08-28 10:49:08 -07001080 * @param hoComplete HOComplete
slowr23a93e12017-09-01 13:26:18 -07001081 * @param ctx ChannelHandlerContext
slowr577f3222017-08-28 10:49:08 -07001082 */
1083 private void handleHocomplete(HOComplete hoComplete, ChannelHandlerContext ctx) {
1084 EcgiCrntiPair ecgiCrntiPair = EcgiCrntiPair.valueOf(hoComplete.getEcgiT(),
1085 hoComplete.getCrntiNew());
1086 contextUpdateMap.compute(ecgiCrntiPair, (k, v) -> {
1087 if (v == null) {
1088 v = new ContextUpdateHandler();
1089 }
1090 if (v.setHoComplete(hoComplete)) {
slowrab685ef2017-08-31 17:17:35 -07001091 handlePairedPackets(v.getContextUpdate(), ctx, true);
slowr577f3222017-08-28 10:49:08 -07001092
1093 try {
1094 hoMap.get(hoComplete.getEcgiS()).put("Hand Over Completed");
1095 } catch (InterruptedException e) {
1096 log.error(ExceptionUtils.getFullStackTrace(e));
1097 e.printStackTrace();
1098 } finally {
1099 hoMap.remove(hoComplete.getEcgiS());
1100 }
slowrab685ef2017-08-31 17:17:35 -07001101 v.reset();
slowr577f3222017-08-28 10:49:08 -07001102 }
1103 return v;
1104 });
1105 }
1106
1107 /**
1108 * Handle RXSigMeasReport.
slowr23a93e12017-09-01 13:26:18 -07001109 *
slowr577f3222017-08-28 10:49:08 -07001110 * @param rxSigMeasReport RXSigMeasReport
1111 */
1112 private void handleRxsigmeasreport(RXSigMeasReport rxSigMeasReport) {
1113 List<RXSigReport> rxSigReportList = rxSigMeasReport.getCellMeasReports().getRXSigReport();
1114
1115 RnibUe ue = ueMap.get(rxSigMeasReport.getEcgi(), rxSigMeasReport.getCrnti());
1116 if (ue != null) {
1117 Long ueId = ue.getId();
1118
1119 if (!rxSigReportList.isEmpty()) {
1120 rxSigReportList.forEach(rxSigReport -> {
1121 RnibCell cell = cellMap.get(rxSigReport.getPciArfcn());
1122 if (cell != null) {
1123 ECGI ecgi = cell.getEcgi();
1124
1125 RnibLink link = linkMap.get(ecgi, ueId);
1126 if (link == null) {
1127 log.warn("Could not find link between: {}-{} | Creating non-serving link..",
1128 ecgi, ueId);
1129 link = linkMap.putNonServingLink(cell, ueId);
1130 }
1131
1132 if (link != null) {
1133 if (link.getType().equals(RnibLink.Type.NON_SERVING)) {
1134 restartTimer(link);
1135 }
1136
1137 RSRQRange rsrq = rxSigReport.getRsrq();
1138 RSRPRange rsrp = rxSigReport.getRsrp();
1139
1140 RnibLink.LinkQuality quality = link.getQuality();
1141 quality.setRx(new RnibLink.LinkQuality.Rx(
1142 rsrp.value.intValue() - 140,
1143 (rsrq.value.intValue() * 0.5) - 19.5
1144 ));
1145 }
1146 } else {
1147 log.warn("case 16: Could not find cell with PCI-ARFCN: {}",
1148 rxSigReport.getPciArfcn());
1149 }
1150 });
1151 }
1152 }
1153 }
1154
1155 /**
1156 * Handle RadioMeasReportPerUE.
slowr23a93e12017-09-01 13:26:18 -07001157 *
slowr577f3222017-08-28 10:49:08 -07001158 * @param radioMeasReportPerUE RadioMeasReportPerUE
1159 */
1160 private void handleRadionmeasreportperue(RadioMeasReportPerUE radioMeasReportPerUE) {
1161 RnibUe ue = ueMap.get(radioMeasReportPerUE.getEcgi(), radioMeasReportPerUE.getCrnti());
1162 if (ue != null) {
1163 Long ueId = ue.getId();
1164 List<RadioRepPerServCell> servCells = radioMeasReportPerUE.getRadioReportServCells()
1165 .getRadioRepPerServCell();
1166
1167 servCells.forEach(servCell -> {
1168 RnibCell cell = cellMap.get(servCell.getPciArfcn());
1169 if (cell != null) {
1170 RnibLink link = linkMap.get(cell.getEcgi(), ueId);
1171 if (link != null) {
1172 RadioRepPerServCell.CqiHist cqiHist = servCell.getCqiHist();
1173 RnibLink.LinkQuality quality = link.getQuality();
1174
1175 final double[] values = {0, 0, 0};
1176 final int[] i = {1};
1177 cqiHist.getBerInteger().forEach(value -> {
1178 values[0] = Math.max(values[0], value.intValue());
1179 values[1] += i[0] * value.intValue();
1180 values[2] += value.intValue();
1181 i[0]++;
1182 });
1183
1184 quality.setCqi(new RnibLink.LinkQuality.Cqi(
1185 cqiHist,
1186 values[0],
1187 values[1] / values[0]
1188 ));
1189
1190 } else {
1191 log.warn("Could not find link between: {}-{}", cell.getEcgi(), ueId);
1192 }
1193 } else {
1194 log.warn("case 18: Could not find cell with PCI-ARFCN: {}", servCell.getPciArfcn());
1195 }
1196 });
1197 }
1198 }
1199
1200 /**
1201 * Handle SchedMeasReportPerUE.
slowr23a93e12017-09-01 13:26:18 -07001202 *
slowr577f3222017-08-28 10:49:08 -07001203 * @param schedMeasReportPerUE SchedMeasReportPerUE
1204 */
1205 private void handleSchedmeasreportperue(SchedMeasReportPerUE schedMeasReportPerUE) {
1206 RnibUe ue = ueMap.get(schedMeasReportPerUE.getEcgi(), schedMeasReportPerUE.getCrnti());
1207 if (ue != null) {
1208 Long ueId = ue.getId();
1209
1210 List<SchedMeasRepPerServCell> servCells = schedMeasReportPerUE.getSchedReportServCells()
1211 .getSchedMeasRepPerServCell();
1212
1213 servCells.forEach(servCell -> {
1214 RnibCell cell = cellMap.get(servCell.getPciArfcn());
1215 if (cell != null) {
1216 RnibLink link = linkMap.get(cell.getEcgi(), ueId);
1217 if (link != null) {
1218 link.getQuality().setMcs(new RnibLink.LinkQuality.Mcs(
1219 servCell.getMcsDl(),
1220 servCell.getMcsUl()
1221 ));
1222
1223 link.setResourceUsage(new RnibLink.ResourceUsage(
1224 servCell.getPrbUsage().getPrbUsageDl(),
1225 servCell.getPrbUsage().getPrbUsageUl()
1226 ));
1227 } else {
1228 log.warn("Could not find link between: {}-{}", cell.getEcgi(), ueId);
1229 }
1230 } else {
1231 log.warn("case 20: Could not find cell with PCI-ARFCN: {}", servCell.getPciArfcn());
1232 }
1233 });
1234 }
1235 }
1236
1237 /**
1238 * Handle SchedMeasReportPerCell.
slowr23a93e12017-09-01 13:26:18 -07001239 *
slowr577f3222017-08-28 10:49:08 -07001240 * @param schedMeasReportPerCell SchedMeasReportPerCell
1241 */
1242 private void handleSchedmeasreportpercell(SchedMeasReportPerCell schedMeasReportPerCell) {
1243 RnibCell cell = cellMap.get(schedMeasReportPerCell.getEcgi());
1244 if (cell != null) {
1245 cell.setPrbUsage(new RnibCell.PrbUsageContainer(
1246 schedMeasReportPerCell.getPrbUsagePcell(),
1247 schedMeasReportPerCell.getPrbUsageScell()
1248 ));
1249
1250 cell.setQci(schedMeasReportPerCell.getQciVals());
1251 } else {
1252 log.warn("Could not find cell with ECGI: {}", schedMeasReportPerCell.getEcgi());
1253 }
1254 }
1255
1256 /**
1257 * Handle PDCPMeasReportPerUe.
slowr23a93e12017-09-01 13:26:18 -07001258 *
slowr577f3222017-08-28 10:49:08 -07001259 * @param pdcpMeasReportPerUe PDCPMeasReportPerUe
1260 */
1261 private void handlePdcpmeasreportperue(PDCPMeasReportPerUe pdcpMeasReportPerUe) {
1262 RnibUe ue = ueMap.get(pdcpMeasReportPerUe.getEcgi(), pdcpMeasReportPerUe.getCrnti());
1263 if (ue != null) {
1264 Long ueId = ue.getId();
1265 RnibLink link = linkMap.get(pdcpMeasReportPerUe.getEcgi(), ueId);
1266 if (link != null) {
1267 link.setPdcpThroughput(new RnibLink.PdcpThroughput(
1268 pdcpMeasReportPerUe.getThroughputDl(),
1269 pdcpMeasReportPerUe.getThroughputUl()
1270 ));
1271
1272 link.setPdcpPackDelay(new RnibLink.PdcpPacketdelay(
1273 pdcpMeasReportPerUe.getPktDelayDl(),
1274 pdcpMeasReportPerUe.getPktDelayUl()
1275 ));
1276 } else {
1277 log.warn("Could not find link between: {}-{}", pdcpMeasReportPerUe.getEcgi(), ueId);
1278 }
1279 }
1280 }
1281
1282 /**
1283 * Handle UECapabilityInfo.
slowr23a93e12017-09-01 13:26:18 -07001284 *
slowr577f3222017-08-28 10:49:08 -07001285 * @param capabilityInfo UECapabilityInfo
1286 */
1287 private void handleCapabilityinfo(UECapabilityInfo capabilityInfo) {
1288 RnibUe ue = ueMap.get(capabilityInfo.getEcgi(), capabilityInfo.getCrnti());
1289 if (ue != null) {
1290 ue.setCapability(capabilityInfo);
1291 } else {
1292 log.warn("Could not find UE with this CRNTI: {}", capabilityInfo.getCrnti());
1293 }
1294 }
1295
1296 /**
1297 * Handle UECapabilityEnquiry.
slowr23a93e12017-09-01 13:26:18 -07001298 *
slowr577f3222017-08-28 10:49:08 -07001299 * @param ueCapabilityEnquiry UECapabilityEnquiry
slowr23a93e12017-09-01 13:26:18 -07001300 * @param ctx ChannelHandlerContext
slowr577f3222017-08-28 10:49:08 -07001301 * @throws IOException IO Exception
1302 */
1303 private void handleUecapabilityenquiry(UECapabilityEnquiry ueCapabilityEnquiry, ChannelHandlerContext ctx)
1304 throws IOException {
1305 XrancPdu xrancPdu = UECapabilityEnquiry.constructPacket(ueCapabilityEnquiry.getEcgi(),
1306 ueCapabilityEnquiry.getCrnti());
1307 ctx.writeAndFlush(getSctpMessage(xrancPdu));
1308 }
1309
1310 /**
1311 * Handle ScellAddStatus.
slowr23a93e12017-09-01 13:26:18 -07001312 *
slowr577f3222017-08-28 10:49:08 -07001313 * @param scellAddStatus ScellAddStatus
1314 */
1315 private void handleScelladdstatus(ScellAddStatus scellAddStatus) {
1316 RnibUe ue = ueMap.get(scellAddStatus.getEcgi(), scellAddStatus.getCrnti());
1317 if (ue != null) {
1318 Long ueId = ue.getId();
1319 try {
1320 scellAddMap.get(scellAddStatus.getCrnti()).put("Scell's status: " +
1321 scellAddStatus.getStatus());
1322 final int[] i = {0};
1323 scellAddStatus.getScellsInd().getPCIARFCN().forEach(
1324 pciarfcn -> {
1325 if (scellAddStatus.getStatus().getBerEnum().get(i[0]).value.intValue() == 0) {
1326 RnibCell cell = cellMap.get(pciarfcn);
1327 RnibLink link = linkMap.get(cell.getEcgi(), ueId);
1328 link.setType(RnibLink.Type.SERVING_SECONDARY_CA);
1329 }
1330 i[0]++;
1331 }
1332 );
1333
1334 } catch (InterruptedException e) {
1335 log.error(ExceptionUtils.getFullStackTrace(e));
1336 e.printStackTrace();
1337 } finally {
1338 scellAddMap.remove(scellAddStatus.getCrnti());
1339 }
1340 }
1341 }
1342
1343 /**
1344 * Handle RRMConfigStatus.
slowr23a93e12017-09-01 13:26:18 -07001345 *
slowr577f3222017-08-28 10:49:08 -07001346 * @param rrmConfigStatus RRMConfigStatus
1347 */
1348 private void handleRrmconfigstatus(RRMConfigStatus rrmConfigStatus) {
1349 try {
1350 rrmcellMap.get(rrmConfigStatus.getEcgi())
1351 .put("RRM Config's status: " + rrmConfigStatus.getStatus());
1352 } catch (InterruptedException e) {
1353 log.error(ExceptionUtils.getFullStackTrace(e));
1354 e.printStackTrace();
1355 } finally {
1356 rrmcellMap.remove(rrmConfigStatus.getEcgi());
1357 }
1358 }
1359
1360 /**
1361 * Handle TrafficSplitConfig.
slowr23a93e12017-09-01 13:26:18 -07001362 *
slowr577f3222017-08-28 10:49:08 -07001363 * @param trafficSplitConfig TrafficSplitConfig
1364 */
1365 private void handleTrafficSplitConfig(TrafficSplitConfig trafficSplitConfig) {
1366 RnibUe ue = ueMap.get(trafficSplitConfig.getEcgi(), trafficSplitConfig.getCrnti());
1367 if (ue != null) {
1368 Long ueId = ue.getId();
1369 List<TrafficSplitPercentage> splitPercentages = trafficSplitConfig
1370 .getTrafficSplitPercent().getTrafficSplitPercentage();
1371
1372 splitPercentages.forEach(trafficSplitPercentage -> {
1373 RnibCell cell = cellMap.get(trafficSplitPercentage.getEcgi());
1374 if (cell != null) {
1375 RnibLink link = linkMap.get(cell.getEcgi(), ueId);
1376 if (link != null) {
1377 link.setTrafficPercent(trafficSplitPercentage);
1378 } else {
1379 log.warn("Could not find link between: {}-{}", cell.getEcgi(), ueId);
1380 }
1381 } else {
1382 log.warn("Could not find cell with ECGI: {}", trafficSplitConfig.getEcgi());
1383 }
1384 });
1385 }
1386 }
1387
1388 /**
1389 * Handle context update depending if its handoff or not.
1390 *
1391 * @param contextUpdate context update packet
1392 * @param ctx channel context for the CELL
1393 * @param handoff true if we handle a Hand Off
1394 */
slowrab685ef2017-08-31 17:17:35 -07001395 private void handlePairedPackets(UEContextUpdate contextUpdate, ChannelHandlerContext ctx, boolean handoff) {
slowrc86750e2017-08-22 17:26:47 -07001396 RnibUe ue;
1397 RnibCell cell = xranStore.getCell(contextUpdate.getEcgi());
1398
1399 if (handoff) {
1400 try {
1401 ue = ueMap.get(ueIdQueue.take());
1402 } catch (InterruptedException e) {
1403 e.printStackTrace();
1404 log.error(ExceptionUtils.getFullStackTrace(e));
1405 ue = new RnibUe();
1406 }
1407 } else {
1408 ue = new RnibUe();
1409 }
1410
1411 ue.setMmeS1apId(contextUpdate.getMMEUES1APID());
1412 ue.setEnbS1apId(contextUpdate.getENBUES1APID());
1413 ue.setCrnti(contextUpdate.getCrnti());
1414
1415 hostAgent.addConnectedHost(ue, cell, ctx);
1416 }
slowr13fa5b02017-08-08 16:32:31 -07001417 }
1418
slowr577f3222017-08-28 10:49:08 -07001419 /**
1420 * Internal class for NetworkConfigListener.
1421 */
slowr13fa5b02017-08-08 16:32:31 -07001422 class InternalNetworkConfigListener implements NetworkConfigListener {
1423
1424 @Override
1425 public void event(NetworkConfigEvent event) {
1426 switch (event.type()) {
1427 case CONFIG_REGISTERED:
1428 break;
1429 case CONFIG_UNREGISTERED:
1430 break;
1431 case CONFIG_ADDED:
1432 case CONFIG_UPDATED:
1433 if (event.configClass() == CONFIG_CLASS) {
1434 handleConfigEvent(event.config());
1435 }
1436 break;
1437 case CONFIG_REMOVED:
1438 break;
1439 default:
1440 break;
1441 }
1442 }
1443
slowr577f3222017-08-28 10:49:08 -07001444 /**
1445 * Handle config event.
1446 *
1447 * @param config
1448 */
slowr13fa5b02017-08-08 16:32:31 -07001449 private void handleConfigEvent(Optional<Config> config) {
1450 if (!config.isPresent()) {
1451 return;
1452 }
1453
1454 xranConfig = (XranConfig) config.get();
1455
slowr577f3222017-08-28 10:49:08 -07001456 northboundTimeout = xranConfig.getNorthBoundTimeout();
slowrd337c932017-08-18 13:54:02 -07001457
slowr13fa5b02017-08-08 16:32:31 -07001458 legitCells.putAll(xranConfig.activeCellSet());
1459
slowr23a93e12017-09-01 13:26:18 -07001460 controller.start(deviceAgent, hostAgent, packetAgent, xranConfig.getXrancIp(), xranConfig.getXrancPort());
slowr13fa5b02017-08-08 16:32:31 -07001461 }
1462 }
1463}