blob: 9497bf4c27697de2f09ee30c61315798aae8356c [file] [log] [blame]
slowr13fa5b02017-08-08 16:32:31 -07001/*
2 * Copyright 2015-present Open Networking Laboratory
3 *
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;
23import org.apache.felix.scr.annotations.*;
24import org.onosproject.core.ApplicationId;
25import org.onosproject.core.CoreService;
26import org.onosproject.net.config.*;
27import org.onosproject.net.config.basics.SubjectFactories;
28import org.onosproject.net.device.DeviceEvent;
29import org.onosproject.net.device.DeviceListener;
30import org.onosproject.net.device.DeviceService;
31import org.onosproject.net.host.HostEvent;
32import org.onosproject.net.host.HostListener;
33import org.onosproject.net.host.HostService;
34import org.onosproject.xran.XranStore;
35import org.onosproject.xran.codecs.api.*;
slowrc153ad92017-08-16 19:47:52 -070036import org.onosproject.xran.codecs.ber.types.BerInteger;
slowr13fa5b02017-08-08 16:32:31 -070037import org.onosproject.xran.codecs.pdu.*;
38import org.onosproject.xran.entities.RnibCell;
39import org.onosproject.xran.entities.RnibLink;
40import org.onosproject.xran.entities.RnibUe;
41import org.onosproject.xran.identifiers.LinkId;
42import org.onosproject.xran.impl.XranConfig;
43import org.onosproject.xran.providers.XranDeviceListener;
44import org.onosproject.xran.providers.XranHostListener;
slowr13fa5b02017-08-08 16:32:31 -070045import org.onosproject.xran.wrapper.CellMap;
46import org.onosproject.xran.wrapper.LinkMap;
47import org.onosproject.xran.wrapper.UeMap;
slowr13fa5b02017-08-08 16:32:31 -070048import org.slf4j.Logger;
49import org.slf4j.LoggerFactory;
50
51import java.io.IOException;
52import java.util.*;
slowr8ddc2b12017-08-14 14:13:38 -070053import java.util.concurrent.ConcurrentHashMap;
54import java.util.concurrent.ConcurrentMap;
55import java.util.concurrent.CopyOnWriteArraySet;
56import java.util.concurrent.SynchronousQueue;
slowr13fa5b02017-08-08 16:32:31 -070057import java.util.stream.Collectors;
58
59import static org.onosproject.net.DeviceId.deviceId;
slowr67d05e42017-08-11 20:37:22 -070060import static org.onosproject.xran.controller.XranChannelHandler.getSctpMessage;
slowr13fa5b02017-08-08 16:32:31 -070061import static org.onosproject.xran.entities.RnibCell.decodeDeviceId;
62import static org.onosproject.xran.entities.RnibCell.uri;
slowr13fa5b02017-08-08 16:32:31 -070063import static org.onosproject.xran.entities.RnibUe.hostIdtoMME;
64
65/**
66 * Created by dimitris on 7/20/17.
67 */
68@Component(immediate = true)
69@Service
70public class XranControllerImpl implements XranController {
71 private static final String XRAN_APP_ID = "org.onosproject.xran";
72 private static final Class<XranConfig> CONFIG_CLASS = XranConfig.class;
73
74 private static final Logger log =
75 LoggerFactory.getLogger(XranControllerImpl.class);
76 /* CONFIG */
77 private final InternalNetworkConfigListener configListener =
78 new InternalNetworkConfigListener();
79 /* VARIABLES */
80 private final Controller controller = new Controller();
81 private XranConfig xranConfig;
82 private ApplicationId appId;
slowrd337c932017-08-18 13:54:02 -070083 public int northbound_timeout;
slowr13fa5b02017-08-08 16:32:31 -070084 /* Services */
85 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
86 private DeviceService deviceService;
87 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
88 private HostService hostService;
89 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
90 private NetworkConfigRegistry registry;
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
92 private NetworkConfigService configService;
93 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 private CoreService coreService;
95 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
96 private XranStore xranStore;
97 private ConfigFactory<ApplicationId, XranConfig> xranConfigFactory =
98 new ConfigFactory<ApplicationId, XranConfig>(
99 SubjectFactories.APP_SUBJECT_FACTORY, CONFIG_CLASS, "xran") {
100 @Override
101 public XranConfig createConfig() {
102 return new XranConfig();
103 }
104 };
105 /* WRAPPERS */
106 private CellMap cellMap;
107 private UeMap ueMap;
108 private LinkMap linkMap;
109 /* MAPS */
110 private ConcurrentMap<String, ECGI> legitCells = new ConcurrentHashMap<>();
slowr73b4eae2017-08-17 16:09:09 -0700111 private ConcurrentMap<ECGI, SynchronousQueue<String>> hoQueue = new ConcurrentHashMap<>();
slowr89c2ac12017-08-15 16:20:06 -0700112 private ConcurrentMap<ECGI, SynchronousQueue<String>> RRMCellQueue = new ConcurrentHashMap<>();
113 private ConcurrentMap<CRNTI, SynchronousQueue<String>> scellAddQueue = new ConcurrentHashMap<>();
slowr13fa5b02017-08-08 16:32:31 -0700114 /* AGENTS */
115 private InternalXranDeviceAgent deviceAgent = new InternalXranDeviceAgent();
116 private InternalXranHostAgent hostAgent = new InternalXranHostAgent();
117 private InternalXranPacketAgent packetAgent = new InternalXranPacketAgent();
118 /* LISTENERS */
119 private Set<XranDeviceListener> xranDeviceListeners = new CopyOnWriteArraySet<>();
120 private Set<XranHostListener> xranHostListeners = new CopyOnWriteArraySet<>();
121 private InternalDeviceListener device_listener = new InternalDeviceListener();
122 private InternalHostListener host_listener = new InternalHostListener();
123
124 @Activate
125 public void activate() {
126 appId = coreService.registerApplication(XRAN_APP_ID);
127
128 configService.addListener(configListener);
129 registry.registerConfigFactory(xranConfigFactory);
130 deviceService.addListener(device_listener);
131 hostService.addListener(host_listener);
132
133 cellMap = new CellMap(xranStore);
134 ueMap = new UeMap(xranStore);
slowrd337c932017-08-18 13:54:02 -0700135 linkMap = new LinkMap(xranStore, ueMap);
slowr13fa5b02017-08-08 16:32:31 -0700136
137 xranStore.setController(this);
138
139 log.info("XRAN Controller Started");
140 }
141
142 @Deactivate
143 public void deactivate() {
144 controller.stop();
145
146 deviceService.removeListener(device_listener);
147 hostService.removeListener(host_listener);
148
149 legitCells.clear();
150
151 configService.removeListener(configListener);
152 registry.unregisterConfigFactory(xranConfigFactory);
153
154 log.info("XRAN Controller Stopped");
155 }
156
157 @Override
slowr73b4eae2017-08-17 16:09:09 -0700158 public SynchronousQueue<String> sendHORequest(RnibLink link_t, RnibLink link_s) {
159 ECGI ecgi_t = link_t.getLinkId().getEcgi(),
160 ecgi_s = link_s.getLinkId().getEcgi();
161
162 CRNTI crnti = linkMap.getCrnti(link_t.getLinkId().getMmeues1apid());
163 ChannelHandlerContext ctx_t = cellMap.getCtx(ecgi_t),
164 ctx_s = cellMap.getCtx(ecgi_s);
slowr67d05e42017-08-11 20:37:22 -0700165
166 try {
slowr73b4eae2017-08-17 16:09:09 -0700167 XrancPdu xrancPdu = HORequest.constructPacket(crnti, ecgi_s, ecgi_t);
168 ctx_t.writeAndFlush(getSctpMessage(xrancPdu));
169 ctx_s.writeAndFlush(getSctpMessage(xrancPdu));
slowr67d05e42017-08-11 20:37:22 -0700170 } catch (IOException e) {
171 e.printStackTrace();
172 }
173
174 SynchronousQueue<String> queue = new SynchronousQueue<>();
slowr73b4eae2017-08-17 16:09:09 -0700175 hoQueue.put(ecgi_s, queue);
slowr67d05e42017-08-11 20:37:22 -0700176
177 return queue;
178 }
179
180 @Override
slowr13fa5b02017-08-08 16:32:31 -0700181 public void addListener(XranDeviceListener listener) {
182 xranDeviceListeners.add(listener);
183 }
184
185 @Override
186 public void addListener(XranHostListener listener) {
187 xranHostListeners.add(listener);
188 }
189
190 @Override
191 public void removeListener(XranDeviceListener listener) {
192 xranDeviceListeners.remove(listener);
193 }
194
195 @Override
196 public void removeListener(XranHostListener listener) {
197 xranHostListeners.remove(listener);
198 }
199
slowr67d05e42017-08-11 20:37:22 -0700200 @Override
slowr8ddc2b12017-08-14 14:13:38 -0700201 public SynchronousQueue<String> sendModifiedRRMConf(RRMConfig rrmConfig, boolean xICIC) {
202 ECGI ecgi = rrmConfig.getEcgi();
slowr67d05e42017-08-11 20:37:22 -0700203 ChannelHandlerContext ctx = cellMap.getCtx(ecgi);
204 try {
slowr73b4eae2017-08-17 16:09:09 -0700205 XrancPdu pdu = null;
206
slowr8ddc2b12017-08-14 14:13:38 -0700207 if (xICIC) {
slowr73b4eae2017-08-17 16:09:09 -0700208 CellConfigReport cellConfigReport = cellMap.get(ecgi).getConf();
209 if (cellConfigReport != null) {
210 pdu = XICICConfig.constructPacket(rrmConfig, cellConfigReport);
211 ctx.writeAndFlush(getSctpMessage(pdu));
212 }
slowr8ddc2b12017-08-14 14:13:38 -0700213 } else {
214 pdu = RRMConfig.constructPacket(rrmConfig);
slowr73b4eae2017-08-17 16:09:09 -0700215 ctx.writeAndFlush(getSctpMessage(pdu));
216 SynchronousQueue<String> queue = new SynchronousQueue<>();
217 RRMCellQueue.put(ecgi, queue);
218 return queue;
slowr8ddc2b12017-08-14 14:13:38 -0700219 }
slowr67d05e42017-08-11 20:37:22 -0700220 } catch (IOException e) {
221 e.printStackTrace();
222 }
slowr67d05e42017-08-11 20:37:22 -0700223
slowr73b4eae2017-08-17 16:09:09 -0700224 return null;
slowr67d05e42017-08-11 20:37:22 -0700225 }
226
slowr89c2ac12017-08-15 16:20:06 -0700227 @Override
228 public SynchronousQueue<String> sendScellAdd(RnibLink link) {
229 RnibCell secondaryCell = link.getLinkId().getCell(),
230 primaryCell = linkMap.getPrimaryCell(link.getLinkId().getUe());
231 ECGI primaryEcgi = primaryCell.getEcgi();
232 ChannelHandlerContext ctx = cellMap.getCtx(primaryEcgi);
233
234 CRNTI crnti = linkMap.getCrnti(link.getLinkId().getMmeues1apid());
235
236 CellConfigReport cellReport = secondaryCell.getConf();
237
238 if (cellReport != null) {
239 PCIARFCN pciarfcn = new PCIARFCN();
240 pciarfcn.setPci(cellReport.getPci());
241 pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());
242
243 PropScell propScell = new PropScell();
244 propScell.setPciArfcn(pciarfcn);
245
246 XrancPdu pdu = ScellAdd.constructPacket(primaryEcgi, crnti, propScell);
247 try {
248 ctx.writeAndFlush(getSctpMessage(pdu));
249 SynchronousQueue<String> queue = new SynchronousQueue<>();
250 scellAddQueue.put(crnti, queue);
251
252 return queue;
253 } catch (IOException e) {
254 log.error(ExceptionUtils.getFullStackTrace(e));
255 e.printStackTrace();
256 }
257 }
258 return null;
259 }
260
261 @Override
262 public boolean sendScellDelete(RnibLink link) {
263 RnibCell secondaryCell = link.getLinkId().getCell(),
264 primaryCell = linkMap.getPrimaryCell(link.getLinkId().getUe());
265 ECGI primaryEcgi = primaryCell.getEcgi();
266 ChannelHandlerContext ctx = cellMap.getCtx(primaryEcgi);
267
268 CRNTI crnti = linkMap.getCrnti(link.getLinkId().getMmeues1apid());
269
270 CellConfigReport cellReport = secondaryCell.getConf();
271
272 if (cellReport != null) {
273 PCIARFCN pciarfcn = new PCIARFCN();
274 pciarfcn.setPci(cellReport.getPci());
275 pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());
276
277 XrancPdu pdu = ScellDelete.constructPacket(primaryEcgi, crnti, pciarfcn);
278
279 try {
280 ctx.writeAndFlush(getSctpMessage(pdu));
281 link.setType(RnibLink.Type.NON_SERVING);
282 return true;
283 } catch (IOException e) {
284 log.error(ExceptionUtils.getFullStackTrace(e));
285 e.printStackTrace();
286 }
287 }
288 return false;
289 }
290
slowr13fa5b02017-08-08 16:32:31 -0700291 private void restartTimer(RnibUe ue) {
292 Timer timer = new Timer();
293 ue.setTimer(timer);
slowr13fa5b02017-08-08 16:32:31 -0700294 timer.schedule(new TimerTask() {
295 @Override
296 public void run() {
slowr67d05e42017-08-11 20:37:22 -0700297 if (ue.getState() == RnibUe.State.IDLE) {
slowr13fa5b02017-08-08 16:32:31 -0700298 hostAgent.removeConnectedHost(ue);
299 log.info("UE is removed after 10 seconds of IDLE");
300 } else {
301 log.info("UE not removed cause its ACTIVE");
302 }
303 }
slowrd337c932017-08-18 13:54:02 -0700304 }, xranConfig.getIdleUeRemoval());
slowr13fa5b02017-08-08 16:32:31 -0700305 }
306
307 private void restartTimer(RnibLink link) {
308 Timer timer = new Timer();
309 link.setTimer(timer);
slowr13fa5b02017-08-08 16:32:31 -0700310 timer.schedule(new TimerTask() {
311 @Override
312 public void run() {
313 LinkId linkId = link.getLinkId();
314 xranStore.removeLink(linkId);
315 log.info("Link is removed after not receiving Meas Reports for 10 seconds");
316 }
slowrd337c932017-08-18 13:54:02 -0700317 }, xranConfig.getNoMeasLinkRemoval());
slowr13fa5b02017-08-08 16:32:31 -0700318
319 }
320
321 class InternalDeviceListener implements DeviceListener {
322
323 @Override
324 public void event(DeviceEvent event) {
325 log.info("Device Event {}", event);
326 switch (event.type()) {
327 case DEVICE_ADDED: {
328 try {
329 ECGI ecgi = decodeDeviceId(event.subject().id());
330 RnibCell cell = cellMap.get(ecgi);
331 if (cell != null) {
332 Timer timer = new Timer();
333 timer.scheduleAtFixedRate(
334 new TimerTask() {
335 @Override
336 public void run() {
337 CellConfigReport conf = cell.getConf();
338 if (conf == null) {
339 try {
340 ChannelHandlerContext ctx = cellMap.getCtx(ecgi);
slowr8ddc2b12017-08-14 14:13:38 -0700341 XrancPdu xrancPdu = CellConfigRequest.constructPacket(ecgi);
slowr67d05e42017-08-11 20:37:22 -0700342 ctx.writeAndFlush(getSctpMessage(xrancPdu));
slowr13fa5b02017-08-08 16:32:31 -0700343 } catch (IOException e) {
344 log.error(ExceptionUtils.getFullStackTrace(e));
345 e.printStackTrace();
346 }
347 } else {
slowrd337c932017-08-18 13:54:02 -0700348 List<Object> ueNodes = xranStore.getUeNodes();
349 ueNodes.forEach(object -> {
350 RnibUe ue = (RnibUe) object;
351 try {
352 ECGI primary_ecgi = linkMap.getPrimaryCell(ue).getEcgi();
353 ChannelHandlerContext ctx = cellMap.getCtx(primary_ecgi);
354 RXSigMeasConfig.MeasCells measCells = new RXSigMeasConfig.MeasCells();
355 xranStore.getCellNodes().forEach(cell -> {
356 CellConfigReport cellReport = ((RnibCell) cell).getConf();
357 if (cellReport != null) {
358 PCIARFCN pciarfcn = new PCIARFCN();
359 pciarfcn.setPci(cellReport.getPci());
360 pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());
361 measCells.setPCIARFCN(pciarfcn);
362 }
363 });
364 XrancPdu xrancPdu = RXSigMeasConfig.constructPacket(
365 primary_ecgi,
366 ue.getRanId(),
367 measCells,
368 xranConfig.getRxSignalInterval()
369 );
370 ue.setMeasConfig(xrancPdu.getBody().getRXSigMeasConfig());
371 ctx.writeAndFlush(getSctpMessage(xrancPdu));
372 } catch (IOException e) {
373 log.warn(ExceptionUtils.getFullStackTrace(e));
374 e.printStackTrace();
375 }
376 });
377
slowr13fa5b02017-08-08 16:32:31 -0700378 try {
slowrd337c932017-08-18 13:54:02 -0700379 ChannelHandlerContext ctx = cellMap.getCtx(ecgi);
slowr8ddc2b12017-08-14 14:13:38 -0700380 XrancPdu xrancPdu = L2MeasConfig.constructPacket(ecgi, xranConfig.getL2MeasInterval());
slowr13fa5b02017-08-08 16:32:31 -0700381 cell.setMeasConfig(xrancPdu.getBody().getL2MeasConfig());
slowr67d05e42017-08-11 20:37:22 -0700382 SctpMessage sctpMessage = getSctpMessage(xrancPdu);
slowr13fa5b02017-08-08 16:32:31 -0700383 ctx.writeAndFlush(sctpMessage);
384 } catch (IOException e) {
385 log.error(ExceptionUtils.getFullStackTrace(e));
386 e.printStackTrace();
387 }
388 timer.cancel();
389 timer.purge();
390 }
391 }
392 },
393 0,
394 xranConfig.getConfigRequestInterval() * 1000
395 );
396 }
397 } catch (IOException e) {
398 log.error(ExceptionUtils.getFullStackTrace(e));
399 e.printStackTrace();
400 }
401 break;
402 }
403 default: {
404 break;
405 }
406 }
407 }
408 }
409
410 class InternalHostListener implements HostListener {
411
412 @Override
413 public void event(HostEvent event) {
414 log.info("Host Event {}", event);
415 switch (event.type()) {
416 case HOST_ADDED:
417 case HOST_MOVED: {
418 RnibUe ue = ueMap.get(hostIdtoMME(event.subject().id()));
419 if (ue != null) {
slowr89c2ac12017-08-15 16:20:06 -0700420 ECGI ecgi_primary = linkMap.getPrimaryCell(ue).getEcgi();
slowr13fa5b02017-08-08 16:32:31 -0700421 RnibCell primary = cellMap.get(ecgi_primary);
422 ue.setMeasConfig(null);
423 if (primary != null) {
424 Timer timer = new Timer();
425 timer.scheduleAtFixedRate(
426 new TimerTask() {
427 @Override
428 public void run() {
slowred74ec72017-08-17 11:25:01 -0700429 if (ue.getCapability() == null && primary.getVersion() >= 3) {
slowr13fa5b02017-08-08 16:32:31 -0700430 try {
431 ChannelHandlerContext ctx = cellMap.getCtx(primary.getEcgi());
slowr8ddc2b12017-08-14 14:13:38 -0700432 XrancPdu xrancPdu = UECapabilityEnquiry.constructPacket(
slowr67d05e42017-08-11 20:37:22 -0700433 primary.getEcgi(),
434 ue.getRanId());
435 ctx.writeAndFlush(getSctpMessage(xrancPdu));
slowr13fa5b02017-08-08 16:32:31 -0700436 } catch (IOException e) {
437 log.warn(ExceptionUtils.getFullStackTrace(e));
438 e.printStackTrace();
439 }
440 } else {
slowr13fa5b02017-08-08 16:32:31 -0700441 timer.cancel();
442 timer.purge();
443 }
444 }
445 },
446 0,
447 xranConfig.getConfigRequestInterval() * 1000
448 );
slowred74ec72017-08-17 11:25:01 -0700449 if (ue.getMeasConfig() == null) {
450 try {
451 ChannelHandlerContext ctx = cellMap.getCtx(primary.getEcgi());
452 RXSigMeasConfig.MeasCells measCells = new RXSigMeasConfig.MeasCells();
453 xranStore.getCellNodes().forEach(cell -> {
454 CellConfigReport cellReport = ((RnibCell) cell).getConf();
455 if (cellReport != null) {
456 PCIARFCN pciarfcn = new PCIARFCN();
457 pciarfcn.setPci(cellReport.getPci());
458 pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());
459 measCells.setPCIARFCN(pciarfcn);
460 }
461 });
462 XrancPdu xrancPdu = RXSigMeasConfig.constructPacket(
463 primary.getEcgi(),
464 ue.getRanId(),
465 measCells,
slowrd337c932017-08-18 13:54:02 -0700466 xranConfig.getRxSignalInterval()
slowred74ec72017-08-17 11:25:01 -0700467 );
468 ue.setMeasConfig(xrancPdu.getBody().getRXSigMeasConfig());
469 ctx.writeAndFlush(getSctpMessage(xrancPdu));
470 } catch (IOException e) {
471 log.warn(ExceptionUtils.getFullStackTrace(e));
472 e.printStackTrace();
473 }
474 }
slowr13fa5b02017-08-08 16:32:31 -0700475 }
476 }
477 break;
478 }
479 default: {
480 break;
481 }
482 }
483 }
484 }
485
486 public class InternalXranDeviceAgent implements XranDeviceAgent {
487
488 private final Logger log = LoggerFactory.getLogger(InternalXranDeviceAgent.class);
489
490 @Override
491 public boolean addConnectedCell(String host, ChannelHandlerContext ctx) {
492 ECGI ecgi = legitCells.get(host);
493
494 if (ecgi == null) {
495 log.error("Device is not a legit source; ignoring...");
496 } else {
497 log.info("Device exists in configuration; registering...");
498 RnibCell storeCell = cellMap.get(ecgi);
499 if (storeCell == null) {
500 storeCell = new RnibCell();
501 storeCell.setEcgi(ecgi);
502 cellMap.put(storeCell, ctx);
503
504 for (XranDeviceListener l : xranDeviceListeners) {
505 l.deviceAdded(storeCell);
506 }
507 return true;
508 } else {
509 log.error("Device already registered; ignoring...");
510 }
511 }
512 ctx.close();
513 return false;
514 }
515
516 @Override
517 public boolean removeConnectedCell(String host) {
518 ECGI ecgi = legitCells.get(host);
519 List<RnibLink> linksByECGI = xranStore.getLinksByECGI(ecgi);
520
521 linksByECGI.forEach(rnibLink -> xranStore.removeLink(rnibLink.getLinkId()));
522
523 if (cellMap.remove(ecgi)) {
524 for (XranDeviceListener l : xranDeviceListeners) {
525 l.deviceRemoved(deviceId(uri(ecgi)));
526 }
527 return true;
528 }
529 return false;
530 }
531 }
532
533 public class InternalXranHostAgent implements XranHostAgent {
534
535 @Override
536 public boolean addConnectedHost(RnibUe ue, RnibCell cell, ChannelHandlerContext ctx) {
537
538 if (ueMap.get(ue.getMmeS1apId()) != null) {
539 linkMap.putPrimaryLink(cell, ue);
540
541 Set<ECGI> ecgiSet = xranStore.getLinksByUeId(ue.getMmeS1apId().longValue())
542 .stream()
slowr8ddc2b12017-08-14 14:13:38 -0700543 .map(l -> l.getLinkId().getEcgi())
slowr13fa5b02017-08-08 16:32:31 -0700544 .collect(Collectors.toSet());
545
546 for (XranHostListener l : xranHostListeners) {
547 l.hostAdded(ue, ecgiSet);
548 }
549 return true;
550 } else {
slowrd337c932017-08-18 13:54:02 -0700551 ueMap.put(cell, ue);
slowr13fa5b02017-08-08 16:32:31 -0700552 linkMap.putPrimaryLink(cell, ue);
553
554 Set<ECGI> ecgiSet = Sets.newConcurrentHashSet();
555 ecgiSet.add(cell.getEcgi());
556 for (XranHostListener l : xranHostListeners) {
557 l.hostAdded(ue, ecgiSet);
558 }
559 return true;
560 }
561
562 }
563
564 @Override
565 public boolean removeConnectedHost(RnibUe ue) {
566 List<RnibLink> links = xranStore.getLinksByUeId(ue.getMmeS1apId().longValue());
567 links.forEach(rnibLink -> xranStore.removeLink(rnibLink.getLinkId()));
568 if (ueMap.remove(ue.getMmeS1apId())) {
569 for (XranHostListener l : xranHostListeners) {
570 l.hostRemoved(ue.getHostId());
571 }
572 return true;
573 }
574 return false;
575 }
576 }
577
578 public class InternalXranPacketAgent implements XranPacketProcessor {
579 @Override
580 public void handlePacket(XrancPdu recv_pdu, ChannelHandlerContext ctx) throws IOException {
581 XrancPdu send_pdu;
582
583 int apiID = recv_pdu.getHdr().getApiId().intValue();
584 log.debug("Received message: {}", recv_pdu);
585 switch (apiID) {
586 case 1: {
587 // Decode Cell config report.
588 CellConfigReport report = recv_pdu.getBody().getCellConfigReport();
589
590 ECGI ecgi = report.getEcgi();
591
592 RnibCell cell = xranStore.getCell(ecgi);
slowr8ddc2b12017-08-14 14:13:38 -0700593 cell.setVersion(recv_pdu.getHdr().getVer().toString());
slowr13fa5b02017-08-08 16:32:31 -0700594 cell.setConf(report);
slowr507a0822017-08-17 20:54:18 -0700595 cellMap.putPciArfcn(cell);
slowr13fa5b02017-08-08 16:32:31 -0700596 break;
597 }
598 case 2: {
599 // Decode UE Admission Request.
600 UEAdmissionRequest ueAdmissionRequest = recv_pdu.getBody().getUEAdmissionRequest();
601
602 ECGI ecgi = ueAdmissionRequest.getEcgi();
603 if (xranStore.getCell(ecgi) != null) {
604 CRNTI crnti = ueAdmissionRequest.getCrnti();
slowr8ddc2b12017-08-14 14:13:38 -0700605 send_pdu = UEAdmissionResponse.constructPacket(ecgi, crnti, xranConfig.admissionFlag());
slowr67d05e42017-08-11 20:37:22 -0700606 ctx.writeAndFlush(getSctpMessage(send_pdu));
slowr13fa5b02017-08-08 16:32:31 -0700607 } else {
608 log.warn("Could not find ECGI in registered cells: {}", ecgi);
609 }
610 break;
611 }
612 case 4: {
613 // Decode UE Admission Status.
614 UEAdmissionStatus ueAdmissionStatus = recv_pdu.getBody().getUEAdmissionStatus();
615
slowrd337c932017-08-18 13:54:02 -0700616 RnibUe ue = ueMap.get(ueAdmissionStatus.getEcgi(), ueAdmissionStatus.getCrnti());
slowr13fa5b02017-08-08 16:32:31 -0700617 if (ue != null) {
618 if (ueAdmissionStatus.getAdmEstStatus().value.intValue() == 0) {
slowr67d05e42017-08-11 20:37:22 -0700619 ue.setState(RnibUe.State.ACTIVE);
slowr13fa5b02017-08-08 16:32:31 -0700620 } else {
slowr67d05e42017-08-11 20:37:22 -0700621 ue.setState(RnibUe.State.IDLE);
slowr13fa5b02017-08-08 16:32:31 -0700622 }
623 }
624 break;
625 }
626 case 5: {
627 // Decode UE Admission Context Update.
slowr8ddc2b12017-08-14 14:13:38 -0700628 UEContextUpdate ueContextUpdate = recv_pdu.getBody().getUEContextUpdate();
slowr13fa5b02017-08-08 16:32:31 -0700629
slowr8ddc2b12017-08-14 14:13:38 -0700630 RnibUe ue = ueMap.get(ueContextUpdate.getMMEUES1APID());
slowr73b4eae2017-08-17 16:09:09 -0700631 RnibCell cell = xranStore.getCell(ueContextUpdate.getEcgi());
632 if (ue == null) {
633 ue = new RnibUe();
slowr13fa5b02017-08-08 16:32:31 -0700634 }
slowr73b4eae2017-08-17 16:09:09 -0700635
636 ue.setMmeS1apId(ueContextUpdate.getMMEUES1APID());
637 ue.setEnbS1apId(ueContextUpdate.getENBUES1APID());
638 ue.setRanId(ueContextUpdate.getCrnti());
639
640 hostAgent.addConnectedHost(ue, cell, ctx);
641
slowr13fa5b02017-08-08 16:32:31 -0700642 break;
643 }
644 case 6: {
645 // Decode UE Reconfig_Ind.
646 UEReconfigInd ueReconfigInd = recv_pdu.getBody().getUEReconfigInd();
slowrd337c932017-08-18 13:54:02 -0700647 RnibUe ue = ueMap.get(ueReconfigInd.getEcgi(), ueReconfigInd.getCrntiOld());
slowr13fa5b02017-08-08 16:32:31 -0700648
649 if (ue != null) {
650 ue.setRanId(ueReconfigInd.getCrntiNew());
651 } else {
652 log.warn("Could not find UE with this CRNTI: {}", ueReconfigInd.getCrntiOld());
653 }
654 break;
655 }
656 case 7: {
657 // If xRANc wants to deactivate UE, we pass UEReleaseInd from xRANc to eNB.
658 // Decode UE Release_Ind.
659 UEReleaseInd ueReleaseInd = recv_pdu.getBody().getUEReleaseInd();
slowrd337c932017-08-18 13:54:02 -0700660 RnibUe ue = ueMap.get(ueReleaseInd.getEcgi(), ueReleaseInd.getCrnti());
slowr13fa5b02017-08-08 16:32:31 -0700661 if (ue != null) {
slowr67d05e42017-08-11 20:37:22 -0700662 ue.setState(RnibUe.State.IDLE);
slowr13fa5b02017-08-08 16:32:31 -0700663 restartTimer(ue);
664 }
665 break;
666 }
667 case 8: {
668 // Decode Bearer Adm Request
669 BearerAdmissionRequest bearerAdmissionRequest = recv_pdu.getBody().getBearerAdmissionRequest();
670
671 ECGI ecgi = bearerAdmissionRequest.getEcgi();
672 CRNTI crnti = bearerAdmissionRequest.getCrnti();
673 ERABParams erabParams = bearerAdmissionRequest.getErabParams();
674 RnibLink link = linkMap.get(ecgi, crnti);
675 if (link != null) {
676 link.setBearerParameters(erabParams);
677 } else {
678 log.warn("Could not find link between {}-{}", ecgi, crnti);
679 }
680
681 BerInteger numErabs = bearerAdmissionRequest.getNumErabs();
slowr8ddc2b12017-08-14 14:13:38 -0700682 // Encode and send Bearer Admission Response
683 send_pdu = BearerAdmissionResponse.constructPacket(ecgi, crnti, erabParams, numErabs, xranConfig.bearerFlag());
slowr67d05e42017-08-11 20:37:22 -0700684 ctx.writeAndFlush(getSctpMessage(send_pdu));
slowr13fa5b02017-08-08 16:32:31 -0700685 break;
686 }
687 case 10: {
688 //Decode Bearer Admission Status
689 BearerAdmissionStatus bearerAdmissionStatus = recv_pdu.getBody().getBearerAdmissionStatus();
slowr8ddc2b12017-08-14 14:13:38 -0700690 break;
slowr13fa5b02017-08-08 16:32:31 -0700691// ECGI ecgi = bearerAdmissionStatus.getEcgi();
692// CRNTI crnti = bearerAdmissionStatus.getCrnti();
693//
694// RnibLink link = linkMap.get(ecgi, crnti);
slowr13fa5b02017-08-08 16:32:31 -0700695 }
696 case 11: {
697 //Decode Bearer Release Ind
698 BearerReleaseInd bearerReleaseInd = recv_pdu.getBody().getBearerReleaseInd();
699
700 ECGI ecgi = bearerReleaseInd.getEcgi();
701 CRNTI crnti = bearerReleaseInd.getCrnti();
702 RnibLink link = linkMap.get(ecgi, crnti);
703
704 List<ERABID> erabidsRelease = bearerReleaseInd.getErabIds().getERABID();
705 List<ERABParamsItem> erabParamsItem = link.getBearerParameters().getERABParamsItem();
706
707 List<ERABParamsItem> unreleased = erabParamsItem
708 .stream()
709 .filter(item -> {
710 Optional<ERABID> any = erabidsRelease.stream().filter(id -> id.equals(item.getId())).findAny();
711 return !any.isPresent();
712 }).collect(Collectors.toList());
713
714 link.getBearerParameters().setERABParamsItem(new ArrayList<>(unreleased));
slowr13fa5b02017-08-08 16:32:31 -0700715 break;
716 }
717 case 13: {
slowr67d05e42017-08-11 20:37:22 -0700718 HOFailure hoFailure = recv_pdu.getBody().getHOFailure();
719
720 try {
slowr73b4eae2017-08-17 16:09:09 -0700721 hoQueue.get(hoFailure.getEcgi())
slowr67d05e42017-08-11 20:37:22 -0700722 .put("Hand Over Failed with cause: " + hoFailure.getCause());
723 } catch (InterruptedException e) {
724 log.error(ExceptionUtils.getFullStackTrace(e));
725 e.printStackTrace();
726 } finally {
slowr73b4eae2017-08-17 16:09:09 -0700727 hoQueue.remove(hoFailure.getEcgi());
slowr67d05e42017-08-11 20:37:22 -0700728 }
729 break;
slowr8ddc2b12017-08-14 14:13:38 -0700730
slowr67d05e42017-08-11 20:37:22 -0700731 }
slowr8ddc2b12017-08-14 14:13:38 -0700732 case 14: {
slowr67d05e42017-08-11 20:37:22 -0700733 HOComplete hoComplete = recv_pdu.getBody().getHOComplete();
734
slowr67d05e42017-08-11 20:37:22 -0700735 try {
slowr73b4eae2017-08-17 16:09:09 -0700736 hoQueue.get(hoComplete.getEcgiS())
slowr67d05e42017-08-11 20:37:22 -0700737 .put("Hand Over Completed");
738 } catch (InterruptedException e) {
739 log.error(ExceptionUtils.getFullStackTrace(e));
740 e.printStackTrace();
741 } finally {
slowr73b4eae2017-08-17 16:09:09 -0700742 hoQueue.remove(hoComplete.getEcgiS());
slowr67d05e42017-08-11 20:37:22 -0700743 }
744 break;
745 }
slowr8ddc2b12017-08-14 14:13:38 -0700746
747 case 16: {
slowr13fa5b02017-08-08 16:32:31 -0700748 // Decode RX Sig Meas Report.
749 RXSigMeasReport rxSigMeasReport = recv_pdu.getBody().getRXSigMeasReport();
750 List<RXSigReport> rxSigReportList = rxSigMeasReport.getCellMeasReports().getRXSigReport();
751
752 if (!rxSigReportList.isEmpty()) {
753 rxSigReportList.forEach(rxSigReport -> {
754 RnibCell cell = cellMap.get(rxSigReport.getPciArfcn());
755 if (cell != null) {
756 ECGI ecgi = cell.getEcgi();
757 RnibLink link = linkMap.get(ecgi, rxSigMeasReport.getCrnti());
758 if (link == null) {
759 log.warn("Could not find link between: {}-{} | Creating non-serving link..", ecgi, rxSigMeasReport.getCrnti());
760 link = linkMap.putNonServingLink(cell, rxSigMeasReport.getCrnti());
slowr13fa5b02017-08-08 16:32:31 -0700761 }
762
763 if (link != null) {
slowrda15d9a2017-08-18 10:33:31 -0700764 if (link.getType().equals(RnibLink.Type.NON_SERVING)) {
765 restartTimer(link);
766 }
767
slowr13fa5b02017-08-08 16:32:31 -0700768 RSRQRange rsrq = rxSigReport.getRsrq();
769 RSRPRange rsrp = rxSigReport.getRsrp();
770
771 RnibLink.LinkQuality quality = link.getQuality();
slowrc153ad92017-08-16 19:47:52 -0700772 quality.setRX(new RnibLink.LinkQuality.RX(
773 rsrp.value.intValue() - 140,
774 (rsrq.value.intValue() * 0.5) - 19.5
775 ));
slowr13fa5b02017-08-08 16:32:31 -0700776 }
777 } else {
slowr507a0822017-08-17 20:54:18 -0700778 log.warn("case 16: Could not find cell with PCI-ARFCN: {}", rxSigReport.getPciArfcn());
slowr13fa5b02017-08-08 16:32:31 -0700779 }
780 });
781 }
782 break;
783 }
slowr8ddc2b12017-08-14 14:13:38 -0700784 case 18: {
slowr13fa5b02017-08-08 16:32:31 -0700785 RadioMeasReportPerUE radioMeasReportPerUE = recv_pdu.getBody().getRadioMeasReportPerUE();
786
787 List<RadioRepPerServCell> servCells = radioMeasReportPerUE.getRadioReportServCells().getRadioRepPerServCell();
788
789 servCells.forEach(servCell -> {
790 RnibCell cell = cellMap.get(servCell.getPciArfcn());
791 if (cell != null) {
792 RnibLink link = linkMap.get(cell.getEcgi(), radioMeasReportPerUE.getCrnti());
793 if (link != null) {
794 RadioRepPerServCell.CqiHist cqiHist = servCell.getCqiHist();
795 RnibLink.LinkQuality quality = link.getQuality();
slowr13fa5b02017-08-08 16:32:31 -0700796
797 final double[] values = {0, 0, 0};
slowrd3d7b412017-08-17 11:15:44 -0700798 final int[] i = {1};
slowr13fa5b02017-08-08 16:32:31 -0700799 cqiHist.getBerInteger().forEach(value -> {
800 values[0] = Math.max(values[0], value.intValue());
slowrd3d7b412017-08-17 11:15:44 -0700801 values[1] += i[0] * value.intValue();
slowr13fa5b02017-08-08 16:32:31 -0700802 values[2] += value.intValue();
slowrd3d7b412017-08-17 11:15:44 -0700803 i[0]++;
slowr13fa5b02017-08-08 16:32:31 -0700804 });
805
slowrc153ad92017-08-16 19:47:52 -0700806 quality.setCQI(new RnibLink.LinkQuality.CQI(
807 cqiHist,
808 values[0],
809 values[1] / values[0]
810 ));
slowr13fa5b02017-08-08 16:32:31 -0700811
812 } else {
813 log.warn("Could not find link between: {}-{}", cell.getEcgi(), radioMeasReportPerUE.getCrnti());
814 }
815 } else {
slowr507a0822017-08-17 20:54:18 -0700816 log.warn("case 18: Could not find cell with PCI-ARFCN: {}", servCell.getPciArfcn());
slowr13fa5b02017-08-08 16:32:31 -0700817 }
818 });
slowr67d05e42017-08-11 20:37:22 -0700819 break;
slowr13fa5b02017-08-08 16:32:31 -0700820 }
slowr8ddc2b12017-08-14 14:13:38 -0700821 case 19: {
slowr13fa5b02017-08-08 16:32:31 -0700822 RadioMeasReportPerCell radioMeasReportPerCell = recv_pdu.getBody().getRadioMeasReportPerCell();
823 break;
824 }
slowr8ddc2b12017-08-14 14:13:38 -0700825 case 20: {
slowr13fa5b02017-08-08 16:32:31 -0700826 SchedMeasReportPerUE schedMeasReportPerUE = recv_pdu.getBody().getSchedMeasReportPerUE();
slowr8ddc2b12017-08-14 14:13:38 -0700827 List<SchedMeasRepPerServCell> servCells = schedMeasReportPerUE.getSchedReportServCells()
828 .getSchedMeasRepPerServCell();
slowr13fa5b02017-08-08 16:32:31 -0700829
830 servCells.forEach(servCell -> {
831 RnibCell cell = cellMap.get(servCell.getPciArfcn());
832 if (cell != null) {
833 RnibLink link = linkMap.get(cell.getEcgi(), schedMeasReportPerUE.getCrnti());
834 if (link != null) {
slowrc153ad92017-08-16 19:47:52 -0700835 link.getQuality().setMCS(new RnibLink.LinkQuality.MCS(
836 servCell.getMcsDl(),
837 servCell.getMcsUl()
838 ));
slowr13fa5b02017-08-08 16:32:31 -0700839
slowrc153ad92017-08-16 19:47:52 -0700840 link.setResourceUsage(new RnibLink.ResourceUsage(
841 servCell.getPrbUsage().getPrbUsageDl(),
842 servCell.getPrbUsage().getPrbUsageUl()
843 ));
slowr13fa5b02017-08-08 16:32:31 -0700844 } else {
slowr8ddc2b12017-08-14 14:13:38 -0700845 log.warn("Could not find link between: {}-{}", cell.getEcgi(),
846 schedMeasReportPerUE.getCrnti());
slowr13fa5b02017-08-08 16:32:31 -0700847 }
848 } else {
slowr507a0822017-08-17 20:54:18 -0700849 log.warn("case 20: Could not find cell with PCI-ARFCN: {}", servCell.getPciArfcn());
slowr13fa5b02017-08-08 16:32:31 -0700850 }
851 });
852 break;
853 }
slowr8ddc2b12017-08-14 14:13:38 -0700854 case 21: {
slowr13fa5b02017-08-08 16:32:31 -0700855 SchedMeasReportPerCell schedMeasReportPerCell = recv_pdu.getBody().getSchedMeasReportPerCell();
slowr13fa5b02017-08-08 16:32:31 -0700856 RnibCell cell = cellMap.get(schedMeasReportPerCell.getEcgi());
857 if (cell != null) {
slowrc153ad92017-08-16 19:47:52 -0700858 cell.setPrbUsage(new RnibCell.PrbUsageContainer(
859 schedMeasReportPerCell.getPrbUsagePcell(),
860 schedMeasReportPerCell.getPrbUsageScell()
861 ));
862
slowr13fa5b02017-08-08 16:32:31 -0700863 cell.setQci(schedMeasReportPerCell.getQciVals());
864 } else {
865 log.warn("Could not find cell with ECGI: {}", schedMeasReportPerCell.getEcgi());
866 }
867 break;
868 }
slowr8ddc2b12017-08-14 14:13:38 -0700869 case 22: {
slowr13fa5b02017-08-08 16:32:31 -0700870 PDCPMeasReportPerUe pdcpMeasReportPerUe = recv_pdu.getBody().getPDCPMeasReportPerUe();
871
872 RnibLink link = linkMap.get(pdcpMeasReportPerUe.getEcgi(), pdcpMeasReportPerUe.getCrnti());
873 if (link != null) {
slowrc153ad92017-08-16 19:47:52 -0700874 link.setPdcpThroughput(new RnibLink.PDCPThroughput(
875 pdcpMeasReportPerUe.getThroughputDl(),
876 pdcpMeasReportPerUe.getThroughputUl()
877 ));
878
879 link.setPdcpPackDelay(new RnibLink.PDCPPacketDelay(
880 pdcpMeasReportPerUe.getPktDelayDl(),
881 pdcpMeasReportPerUe.getPktDelayUl()
882 ));
slowr13fa5b02017-08-08 16:32:31 -0700883 } else {
slowr8ddc2b12017-08-14 14:13:38 -0700884 log.warn("Could not find link between: {}-{}", pdcpMeasReportPerUe.getEcgi(),
885 pdcpMeasReportPerUe.getCrnti());
slowr13fa5b02017-08-08 16:32:31 -0700886 }
887 break;
888 }
slowr8ddc2b12017-08-14 14:13:38 -0700889 case 24: {
890 // Decode UE Capability Info
891 UECapabilityInfo capabilityInfo = recv_pdu.getBody().getUECapabilityInfo();
892
slowrd337c932017-08-18 13:54:02 -0700893 RnibUe ue = ueMap.get(capabilityInfo.getEcgi(), capabilityInfo.getCrnti());
slowr8ddc2b12017-08-14 14:13:38 -0700894 if (ue != null) {
895 ue.setCapability(capabilityInfo);
896 } else {
897 log.warn("Could not find UE with this CRNTI: {}", capabilityInfo.getCrnti());
898 }
899 break;
900 }
901 case 25: {
902 // Don't know what will invoke sending UE CAPABILITY ENQUIRY
903 // Encode and send UE CAPABILITY ENQUIRY
904 UECapabilityEnquiry ueCapabilityEnquiry = recv_pdu.getBody().getUECapabilityEnquiry();
905 XrancPdu xrancPdu = UECapabilityEnquiry.constructPacket(ueCapabilityEnquiry.getEcgi(), ueCapabilityEnquiry.getCrnti());
906 ctx.writeAndFlush(getSctpMessage(xrancPdu));
907 break;
908 }
slowr89c2ac12017-08-15 16:20:06 -0700909 case 27: {
910 //Decode ScellAddStatus
911 ScellAddStatus scellAddStatus = recv_pdu.getBody().getScellAddStatus();
912 try {
913 scellAddQueue.get(scellAddStatus.getCrnti()).put("Scell's status: " + scellAddStatus.getStatus());
914 if (scellAddStatus.getStatus().getBerEnum().get(0).value.intValue() == 0) {
915
916 scellAddStatus.getScellsInd().getPCIARFCN().forEach(
917 pciarfcn -> {
918 RnibCell cell = cellMap.get(pciarfcn);
919 RnibLink link = linkMap.get(cell.getEcgi(), scellAddStatus.getCrnti());
920 link.setType(RnibLink.Type.SERVING_SECONDARY_CA);
921 }
922 );
923 } else {
924 log.error("Scell addition failed.");
925 }
926 } catch (InterruptedException e) {
927 log.error(ExceptionUtils.getFullStackTrace(e));
928 e.printStackTrace();
929 } finally {
930 scellAddQueue.remove(scellAddStatus.getCrnti());
931 }
932 break;
933 }
934 // TODO: 28: ScellDelete
slowr8ddc2b12017-08-14 14:13:38 -0700935
936 case 30: {
937 // Decode RRMConfig Status
slowr67d05e42017-08-11 20:37:22 -0700938 RRMConfigStatus rrmConfigStatus = recv_pdu.getBody().getRRMConfigStatus();
939 try {
940 RRMCellQueue.get(rrmConfigStatus.getEcgi())
941 .put("RRM Config's status: " + rrmConfigStatus.getStatus());
942 } catch (InterruptedException e) {
943 log.error(ExceptionUtils.getFullStackTrace(e));
944 e.printStackTrace();
945 } finally {
946 RRMCellQueue.remove(rrmConfigStatus.getEcgi());
947 }
948 break;
949 }
slowr8ddc2b12017-08-14 14:13:38 -0700950 //TODO Case 31: SeNBAdd 32: SeNBAddStatus 33: SeNBDelete
slowr13fa5b02017-08-08 16:32:31 -0700951 case 34: {
952 TrafficSplitConfig trafficSplitConfig = recv_pdu.getBody().getTrafficSplitConfig();
953
954 List<TrafficSplitPercentage> splitPercentages = trafficSplitConfig.getTrafficSplitPercent().getTrafficSplitPercentage();
955
956 splitPercentages.forEach(trafficSplitPercentage -> {
957 RnibCell cell = cellMap.get(trafficSplitPercentage.getEcgi());
958 if (cell != null) {
959 RnibLink link = linkMap.get(cell.getEcgi(), trafficSplitConfig.getCrnti());
960 if (link != null) {
961 link.setTrafficPercent(trafficSplitPercentage);
962 } else {
963 log.warn("Could not find link between: {}-{}", cell.getEcgi(), trafficSplitConfig.getCrnti());
964 }
965 } else {
966 log.warn("Could not find cell with ECGI: {}", trafficSplitConfig.getEcgi());
967 }
968 });
slowr67d05e42017-08-11 20:37:22 -0700969 break;
slowr13fa5b02017-08-08 16:32:31 -0700970 }
971 default: {
slowr60d4d102017-08-16 18:33:58 -0700972 log.warn("Wrong API ID: {}", recv_pdu);
slowr67d05e42017-08-11 20:37:22 -0700973 break;
slowr13fa5b02017-08-08 16:32:31 -0700974 }
975 }
976
977 }
978 }
979
980 class InternalNetworkConfigListener implements NetworkConfigListener {
981
982 @Override
983 public void event(NetworkConfigEvent event) {
984 switch (event.type()) {
985 case CONFIG_REGISTERED:
986 break;
987 case CONFIG_UNREGISTERED:
988 break;
989 case CONFIG_ADDED:
990 case CONFIG_UPDATED:
991 if (event.configClass() == CONFIG_CLASS) {
992 handleConfigEvent(event.config());
993 }
994 break;
995 case CONFIG_REMOVED:
996 break;
997 default:
998 break;
999 }
1000 }
1001
1002 private void handleConfigEvent(Optional<Config> config) {
1003 if (!config.isPresent()) {
1004 return;
1005 }
1006
1007 xranConfig = (XranConfig) config.get();
1008
slowrd337c932017-08-18 13:54:02 -07001009 northbound_timeout = xranConfig.getNorthBoundTimeout();
1010
slowr13fa5b02017-08-08 16:32:31 -07001011 legitCells.putAll(xranConfig.activeCellSet());
1012
1013 controller.start(deviceAgent, hostAgent, packetAgent, xranConfig.getXrancPort());
1014 }
1015 }
1016}