/*
 * Copyright 2015-present Open Networking Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.onosproject.xran.controller;

import com.google.common.collect.Sets;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.sctp.SctpMessage;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.config.basics.SubjectFactories;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
import org.onosproject.net.host.HostService;
import org.onosproject.xran.XranStore;
import org.onosproject.xran.codecs.api.CRNTI;
import org.onosproject.xran.codecs.api.ECGI;
import org.onosproject.xran.codecs.api.ERABID;
import org.onosproject.xran.codecs.api.ERABParams;
import org.onosproject.xran.codecs.api.ERABParamsItem;
import org.onosproject.xran.codecs.api.PCIARFCN;
import org.onosproject.xran.codecs.api.PropScell;
import org.onosproject.xran.codecs.api.RSRPRange;
import org.onosproject.xran.codecs.api.RSRQRange;
import org.onosproject.xran.codecs.api.RXSigReport;
import org.onosproject.xran.codecs.api.RadioRepPerServCell;
import org.onosproject.xran.codecs.api.SchedMeasRepPerServCell;
import org.onosproject.xran.codecs.api.TrafficSplitPercentage;
import org.onosproject.xran.codecs.ber.types.BerInteger;
import org.onosproject.xran.codecs.pdu.BearerAdmissionRequest;
import org.onosproject.xran.codecs.pdu.BearerAdmissionResponse;
import org.onosproject.xran.codecs.pdu.BearerAdmissionStatus;
import org.onosproject.xran.codecs.pdu.BearerReleaseInd;
import org.onosproject.xran.codecs.pdu.CellConfigReport;
import org.onosproject.xran.codecs.pdu.CellConfigRequest;
import org.onosproject.xran.codecs.pdu.HOComplete;
import org.onosproject.xran.codecs.pdu.HOFailure;
import org.onosproject.xran.codecs.pdu.HORequest;
import org.onosproject.xran.codecs.pdu.L2MeasConfig;
import org.onosproject.xran.codecs.pdu.PDCPMeasReportPerUe;
import org.onosproject.xran.codecs.pdu.RRMConfig;
import org.onosproject.xran.codecs.pdu.RRMConfigStatus;
import org.onosproject.xran.codecs.pdu.RXSigMeasConfig;
import org.onosproject.xran.codecs.pdu.RXSigMeasReport;
import org.onosproject.xran.codecs.pdu.RadioMeasReportPerCell;
import org.onosproject.xran.codecs.pdu.RadioMeasReportPerUE;
import org.onosproject.xran.codecs.pdu.ScellAdd;
import org.onosproject.xran.codecs.pdu.ScellAddStatus;
import org.onosproject.xran.codecs.pdu.ScellDelete;
import org.onosproject.xran.codecs.pdu.SchedMeasReportPerCell;
import org.onosproject.xran.codecs.pdu.SchedMeasReportPerUE;
import org.onosproject.xran.codecs.pdu.TrafficSplitConfig;
import org.onosproject.xran.codecs.pdu.UEAdmissionRequest;
import org.onosproject.xran.codecs.pdu.UEAdmissionResponse;
import org.onosproject.xran.codecs.pdu.UEAdmissionStatus;
import org.onosproject.xran.codecs.pdu.UECapabilityEnquiry;
import org.onosproject.xran.codecs.pdu.UECapabilityInfo;
import org.onosproject.xran.codecs.pdu.UEContextUpdate;
import org.onosproject.xran.codecs.pdu.UEReconfigInd;
import org.onosproject.xran.codecs.pdu.UEReleaseInd;
import org.onosproject.xran.codecs.pdu.XICICConfig;
import org.onosproject.xran.codecs.pdu.XrancPdu;
import org.onosproject.xran.entities.RnibCell;
import org.onosproject.xran.entities.RnibLink;
import org.onosproject.xran.entities.RnibUe;
import org.onosproject.xran.identifiers.ContextUpdateHandler;
import org.onosproject.xran.identifiers.EcgiCrntiPair;
import org.onosproject.xran.identifiers.LinkId;
import org.onosproject.xran.impl.XranConfig;
import org.onosproject.xran.providers.XranDeviceListener;
import org.onosproject.xran.providers.XranHostListener;
import org.onosproject.xran.wrapper.CellMap;
import org.onosproject.xran.wrapper.LinkMap;
import org.onosproject.xran.wrapper.UeMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.stream.Collectors;

import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.xran.controller.XranChannelHandler.getSctpMessage;
import static org.onosproject.xran.entities.RnibCell.decodeDeviceId;
import static org.onosproject.xran.entities.RnibCell.uri;
import static org.onosproject.xran.entities.RnibUe.hostIdtoUEId;

/**
 * Created by dimitris on 7/20/17.
 */
@Component(immediate = true)
@Service
public class XranControllerImpl implements XranController {
    private static final String XRAN_APP_ID = "org.onosproject.xran";
    private static final Class<XranConfig> CONFIG_CLASS = XranConfig.class;

    private static final Logger log =
            LoggerFactory.getLogger(XranControllerImpl.class);
    /* CONFIG */
    private final InternalNetworkConfigListener configListener =
            new InternalNetworkConfigListener();
    /* VARIABLES */
    private final Controller controller = new Controller();
    private XranConfig xranConfig;
    private ApplicationId appId;
    private int northboundTimeout;
    /* Services */
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    private DeviceService deviceService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    private HostService hostService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    private NetworkConfigRegistry registry;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    private NetworkConfigService configService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    private CoreService coreService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    private XranStore xranStore;
    private ConfigFactory<ApplicationId, XranConfig> xranConfigFactory =
            new ConfigFactory<ApplicationId, XranConfig>(
                    SubjectFactories.APP_SUBJECT_FACTORY, CONFIG_CLASS, "xran") {
                @Override
                public XranConfig createConfig() {
                    return new XranConfig();
                }
            };
    /* WRAPPERS */
    private CellMap cellMap;
    private UeMap ueMap;
    private LinkMap linkMap;
    /* MAPS */
    private ConcurrentMap<IpAddress, ECGI> legitCells = new ConcurrentHashMap<>();
    private ConcurrentMap<ECGI, SynchronousQueue<String>> hoMap = new ConcurrentHashMap<>();
    private ConcurrentMap<ECGI, SynchronousQueue<String>> rrmcellMap = new ConcurrentHashMap<>();
    private ConcurrentMap<CRNTI, SynchronousQueue<String>> scellAddMap = new ConcurrentHashMap<>();
    // Map used to keep messages in pairs (HO Complete - CTX Update, Adm Status - CTX Update)
    private ConcurrentMap<EcgiCrntiPair, ContextUpdateHandler> contextUpdateMap = new ConcurrentHashMap<>();
    /* QUEUE */
    private BlockingQueue<Long> ueIdQueue = new LinkedBlockingQueue<>();
    /* AGENTS */
    private InternalXranDeviceAgent deviceAgent = new InternalXranDeviceAgent();
    private InternalXranHostAgent hostAgent = new InternalXranHostAgent();
    private InternalXranPacketAgent packetAgent = new InternalXranPacketAgent();
    /* LISTENERS */
    private Set<XranDeviceListener> xranDeviceListeners = new CopyOnWriteArraySet<>();
    private Set<XranHostListener> xranHostListeners = new CopyOnWriteArraySet<>();
    private InternalDeviceListener deviceListener = new InternalDeviceListener();
    private InternalHostListener hostListener = new InternalHostListener();

    @Activate
    public void activate() {
        appId = coreService.registerApplication(XRAN_APP_ID);

        configService.addListener(configListener);
        registry.registerConfigFactory(xranConfigFactory);
        deviceService.addListener(deviceListener);
        hostService.addListener(hostListener);

        cellMap = new CellMap(xranStore);
        ueMap = new UeMap(xranStore);
        linkMap = new LinkMap(xranStore, ueMap);

        xranStore.setController(this);

        log.info("XRAN Controller Started");
    }

    @Deactivate
    public void deactivate() {
        deviceService.removeListener(deviceListener);
        hostService.removeListener(hostListener);
        configService.removeListener(configListener);
        registry.unregisterConfigFactory(xranConfigFactory);

        cleanup();

        log.info("XRAN Controller Stopped");
    }

    private void cleanup() {
        xranStore.getuenodes().forEach(ue -> {
            for (XranHostListener l : xranHostListeners) {
                l.hostRemoved(((RnibUe) ue).getHostId());
            }
        });

        xranStore.getcellnodes().forEach(cell -> {
            for (XranDeviceListener l : xranDeviceListeners) {
                l.deviceRemoved(deviceId(uri(((RnibCell) cell).getEcgi())));
            }
        });

        controller.stop();

        legitCells.clear();
        hoMap.clear();
        rrmcellMap.clear();
        scellAddMap.clear();
        contextUpdateMap.clear();
        ueIdQueue.clear();
        xranDeviceListeners.clear();
        xranHostListeners.clear();

        cellMap = null;
        ueMap = null;
        linkMap = null;
    }

    @Override
    public SynchronousQueue<String> sendHORequest(RnibLink linkT, RnibLink linkS) throws InterruptedException {
        ECGI ecgiT = linkT.getLinkId().getEcgi(),
                ecgiS = linkS.getLinkId().getEcgi();

        CRNTI crnti = linkMap.getCrnti(linkT.getLinkId().getUeId());
        ChannelHandlerContext ctxT = cellMap.getCtx(ecgiT),
                ctxS = cellMap.getCtx(ecgiS);

        SynchronousQueue<String> queue = new SynchronousQueue<>();
        try {
            XrancPdu xrancPdu = HORequest.constructPacket(crnti, ecgiS, ecgiT);

            // temporary map that has ECGI source of a handoff to a queue waiting for REST response.
            hoMap.put(ecgiS, queue);

            ctxT.writeAndFlush(getSctpMessage(xrancPdu));
            ctxS.writeAndFlush(getSctpMessage(xrancPdu));

            // FIXME: only works for one HO at a time.
            ueIdQueue.put(linkT.getLinkId().getUeId());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return queue;
    }

    @Override
    public void addListener(XranDeviceListener listener) {
        xranDeviceListeners.add(listener);
    }

    @Override
    public void addListener(XranHostListener listener) {
        xranHostListeners.add(listener);
    }

    @Override
    public void removeListener(XranDeviceListener listener) {
        xranDeviceListeners.remove(listener);
    }

    @Override
    public void removeListener(XranHostListener listener) {
        xranHostListeners.remove(listener);
    }

    @Override
    public int getNorthboundTimeout() {
        return northboundTimeout;
    }

    @Override
    public SynchronousQueue<String> sendmodifiedrrmconf(RRMConfig rrmConfig, boolean xicic) {
        ECGI ecgi = rrmConfig.getEcgi();
        ChannelHandlerContext ctx = cellMap.getCtx(ecgi);
        try {
            XrancPdu pdu;

            if (xicic) {
                CellConfigReport cellConfigReport = cellMap.get(ecgi).getConf();
                if (cellConfigReport != null) {
                    pdu = XICICConfig.constructPacket(rrmConfig, cellConfigReport);
                    ctx.writeAndFlush(getSctpMessage(pdu));
                }
            } else {
                pdu = RRMConfig.constructPacket(rrmConfig);
                ctx.writeAndFlush(getSctpMessage(pdu));
                SynchronousQueue<String> queue = new SynchronousQueue<>();
                rrmcellMap.put(ecgi, queue);
                return queue;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public SynchronousQueue<String> sendScellAdd(RnibLink link) {
        RnibCell secondaryCell = link.getLinkId().getCell(),
                primaryCell = linkMap.getPrimaryCell(link.getLinkId().getUe());
        ECGI primaryEcgi = primaryCell.getEcgi();
        ChannelHandlerContext ctx = cellMap.getCtx(primaryEcgi);

        CRNTI crnti = linkMap.getCrnti(link.getLinkId().getUeId());

        CellConfigReport cellReport = secondaryCell.getConf();

        if (cellReport != null) {
            PCIARFCN pciarfcn = new PCIARFCN();
            pciarfcn.setPci(cellReport.getPci());
            pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());

            PropScell propScell = new PropScell();
            propScell.setPciArfcn(pciarfcn);

            XrancPdu pdu = ScellAdd.constructPacket(primaryEcgi, crnti, propScell);
            try {
                ctx.writeAndFlush(getSctpMessage(pdu));
                SynchronousQueue<String> queue = new SynchronousQueue<>();
                scellAddMap.put(crnti, queue);

                return queue;
            } catch (IOException e) {
                log.error(ExceptionUtils.getFullStackTrace(e));
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public boolean sendScellDelete(RnibLink link) {
        RnibCell secondaryCell = link.getLinkId().getCell(),
                primaryCell = linkMap.getPrimaryCell(link.getLinkId().getUe());
        ECGI primaryEcgi = primaryCell.getEcgi();
        ChannelHandlerContext ctx = cellMap.getCtx(primaryEcgi);

        CRNTI crnti = linkMap.getCrnti(link.getLinkId().getUeId());

        CellConfigReport cellReport = secondaryCell.getConf();

        if (cellReport != null) {
            PCIARFCN pciarfcn = new PCIARFCN();
            pciarfcn.setPci(cellReport.getPci());
            pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());

            XrancPdu pdu = ScellDelete.constructPacket(primaryEcgi, crnti, pciarfcn);

            try {
                ctx.writeAndFlush(getSctpMessage(pdu));
                link.setType(RnibLink.Type.NON_SERVING);
                return true;
            } catch (IOException e) {
                log.error(ExceptionUtils.getFullStackTrace(e));
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * Timer to delete UE after being IDLE.
     *
     * @param ue UE entity
     */
    private void restartTimer(RnibUe ue) {
        Timer timer = new Timer();
        ue.setTimer(timer);
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (ue.getState() == RnibUe.State.IDLE) {
                    hostAgent.removeConnectedHost(ue);
                    log.info("UE is removed after {} ms of IDLE", xranConfig.getIdleUeRemoval());
                } else {
                    log.info("UE not removed cause its ACTIVE");
                }
            }
        }, xranConfig.getIdleUeRemoval());
    }

    /**
     * Timer to delete LINK after not receiving measurements.
     *
     * @param link LINK entity
     */
    private void restartTimer(RnibLink link) {
        Timer timer = new Timer();
        link.setTimer(timer);
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                LinkId linkId = link.getLinkId();
                xranStore.removeLink(linkId);
                log.info("Link is removed after not receiving Meas Reports for {} ms",
                        xranConfig.getNoMeasLinkRemoval());
            }
        }, xranConfig.getNoMeasLinkRemoval());

    }

    /**
     * Request measurement configuration field of specified UE.
     *
     * @param primary primary CELL
     * @param ue      UE entity
     */
    private void populateMeasConfig(RnibCell primary, RnibUe ue) {
        try {
            ChannelHandlerContext ctx = cellMap.getCtx(primary.getEcgi());
            RXSigMeasConfig.MeasCells measCells = new RXSigMeasConfig.MeasCells();
            xranStore.getcellnodes().forEach(cell -> {
                CellConfigReport cellReport = ((RnibCell) cell).getConf();
                if (cellReport != null) {
                    PCIARFCN pciarfcn = new PCIARFCN();
                    pciarfcn.setPci(cellReport.getPci());
                    pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());
                    measCells.setPCIARFCN(pciarfcn);
                }
            });
            XrancPdu xrancPdu = RXSigMeasConfig.constructPacket(
                    primary.getEcgi(),
                    ue.getCrnti(),
                    measCells,
                    xranConfig.getRxSignalInterval()
            );
            ue.setMeasConfig(xrancPdu.getBody().getRXSigMeasConfig());
            ctx.writeAndFlush(getSctpMessage(xrancPdu));
        } catch (IOException e) {
            log.warn(ExceptionUtils.getFullStackTrace(e));
            e.printStackTrace();
        }
    }

    /**
     * Internal device listener.
     */
    class InternalDeviceListener implements DeviceListener {

        @Override
        public void event(DeviceEvent event) {
            log.info("Device Event {}", event);
            switch (event.type()) {
                case DEVICE_ADDED: {
                    try {
                        ECGI ecgi = decodeDeviceId(event.subject().id());
                        RnibCell cell = cellMap.get(ecgi);
                        if (cell != null) {
                            Timer timer = new Timer();
                            timer.scheduleAtFixedRate(
                                    new TimerTask() {
                                        @Override
                                        public void run() {
                                            CellConfigReport conf = cell.getConf();
                                            if (conf == null) {
                                                try {
                                                    ChannelHandlerContext ctx = cellMap.getCtx(ecgi);
                                                    XrancPdu xrancPdu = CellConfigRequest.constructPacket(ecgi);
                                                    ctx.writeAndFlush(getSctpMessage(xrancPdu));
                                                } catch (IOException e) {
                                                    log.error(ExceptionUtils.getFullStackTrace(e));
                                                    e.printStackTrace();
                                                }
                                            } else {
                                                List<Object> ueNodes = xranStore.getuenodes();
                                                ueNodes.forEach(object -> {
                                                    RnibUe ue = (RnibUe) object;
                                                    try {
                                                        ECGI primaryEcgi = linkMap.getPrimaryCell(ue).getEcgi();
                                                        ChannelHandlerContext ctx = cellMap.getCtx(primaryEcgi);
                                                        RXSigMeasConfig.MeasCells measCells =
                                                                new RXSigMeasConfig.MeasCells();
                                                        xranStore.getcellnodes().forEach(cell -> {
                                                            CellConfigReport cellReport = ((RnibCell) cell).getConf();
                                                            if (cellReport != null) {
                                                                PCIARFCN pciarfcn = new PCIARFCN();
                                                                pciarfcn.setPci(cellReport.getPci());
                                                                pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());
                                                                measCells.setPCIARFCN(pciarfcn);
                                                            }
                                                        });
                                                        XrancPdu xrancPdu = RXSigMeasConfig.constructPacket(
                                                                primaryEcgi,
                                                                ue.getCrnti(),
                                                                measCells,
                                                                xranConfig.getRxSignalInterval()
                                                        );
                                                        ue.setMeasConfig(xrancPdu.getBody().getRXSigMeasConfig());
                                                        ctx.writeAndFlush(getSctpMessage(xrancPdu));
                                                    } catch (IOException e) {
                                                        log.warn(ExceptionUtils.getFullStackTrace(e));
                                                        e.printStackTrace();
                                                    }
                                                });

                                                try {
                                                    ChannelHandlerContext ctx = cellMap.getCtx(ecgi);
                                                    XrancPdu xrancPdu = L2MeasConfig
                                                            .constructPacket(ecgi, xranConfig.getL2MeasInterval());
                                                    cell.setMeasConfig(xrancPdu.getBody().getL2MeasConfig());
                                                    SctpMessage sctpMessage = getSctpMessage(xrancPdu);
                                                    ctx.writeAndFlush(sctpMessage);
                                                } catch (IOException e) {
                                                    log.error(ExceptionUtils.getFullStackTrace(e));
                                                    e.printStackTrace();
                                                }
                                                timer.cancel();
                                                timer.purge();
                                            }
                                        }
                                    },
                                    0,
                                    xranConfig.getConfigRequestInterval() * 1000
                            );
                        }
                    } catch (IOException e) {
                        log.error(ExceptionUtils.getFullStackTrace(e));
                        e.printStackTrace();
                    }
                    break;
                }
                default: {
                    break;
                }
            }
        }
    }

    /**
     * Internal host listener.
     */
    class InternalHostListener implements HostListener {

        @Override
        public void event(HostEvent event) {
            log.info("Host Event {}", event);
            switch (event.type()) {
                case HOST_ADDED:
                case HOST_MOVED: {
                    RnibUe ue = ueMap.get(hostIdtoUEId(event.subject().id()));
                    if (ue != null) {
                        ECGI ecgiPrimary = linkMap.getPrimaryCell(ue).getEcgi();
                        RnibCell primary = cellMap.get(ecgiPrimary);
                        ue.setMeasConfig(null);
                        if (primary != null) {
                            Timer timer = new Timer();
                            timer.scheduleAtFixedRate(
                                    new TimerTask() {
                                        @Override
                                        public void run() {
                                            if (ue.getCapability() == null && primary.getVersion() >= 3) {
                                                try {
                                                    ChannelHandlerContext ctx = cellMap.getCtx(primary.getEcgi());
                                                    XrancPdu xrancPdu = UECapabilityEnquiry.constructPacket(
                                                            primary.getEcgi(),
                                                            ue.getCrnti());
                                                    ctx.writeAndFlush(getSctpMessage(xrancPdu));
                                                } catch (IOException e) {
                                                    log.warn(ExceptionUtils.getFullStackTrace(e));
                                                    e.printStackTrace();
                                                }
                                            } else {
                                                timer.cancel();
                                                timer.purge();
                                            }
                                        }
                                    },
                                    0,
                                    xranConfig.getConfigRequestInterval() * 1000
                            );
                            if (ue.getMeasConfig() == null) {
                                populateMeasConfig(primary, ue);
                            }
                        }
                    }
                    break;
                }
                default: {
                    break;
                }
            }
        }
    }

    /**
     * Internal xran device agent.
     */
    public class InternalXranDeviceAgent implements XranDeviceAgent {

        private final Logger log = LoggerFactory.getLogger(InternalXranDeviceAgent.class);

        @Override
        public boolean addConnectedCell(String host, ChannelHandlerContext ctx) {
            ECGI ecgi = legitCells.get(IpAddress.valueOf(host));

            if (ecgi == null) {
                log.error("Device is not a legit source; ignoring...");
            } else {
                log.info("Device exists in configuration; registering...");
                RnibCell storeCell = cellMap.get(ecgi);
                if (storeCell == null) {
                    storeCell = new RnibCell();
                    storeCell.setEcgi(ecgi);
                    cellMap.put(storeCell, ctx);

                    for (XranDeviceListener l : xranDeviceListeners) {
                        l.deviceAdded(storeCell);
                    }
                    return true;
                } else {
                    log.error("Device already registered; ignoring...");
                }
            }
            ctx.close();
            return false;
        }

        @Override
        public boolean removeConnectedCell(String host) {
            ECGI ecgi = legitCells.get(IpAddress.valueOf(host));
            List<RnibLink> linksbyecgi = xranStore.getlinksbyecgi(ecgi);

            linksbyecgi.forEach(rnibLink -> xranStore.removeLink(rnibLink.getLinkId()));

            if (cellMap.remove(ecgi)) {
                for (XranDeviceListener l : xranDeviceListeners) {
                    l.deviceRemoved(deviceId(uri(ecgi)));
                }
                return true;
            }
            return false;
        }
    }

    /**
     * Internal xran host agent.
     */
    public class InternalXranHostAgent implements XranHostAgent {

        @Override
        public boolean addConnectedHost(RnibUe ue, RnibCell cell, ChannelHandlerContext ctx) {

            if (ue.getId() != null && ueMap.get(ue.getId()) != null) {
                linkMap.putPrimaryLink(cell, ue);

                Set<ECGI> ecgiSet = Sets.newConcurrentHashSet();

                xranStore.getlinksbyueid(ue.getId())
                        .stream()
                        .filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY))
                        .findFirst()
                        .ifPresent(l -> ecgiSet.add(l.getLinkId().getEcgi()));

                for (XranHostListener l : xranHostListeners) {
                    l.hostAdded(ue, ecgiSet);
                }
                return true;
            } else {
                ueMap.put(cell, ue);
                linkMap.putPrimaryLink(cell, ue);

                Set<ECGI> ecgiSet = Sets.newConcurrentHashSet();
                ecgiSet.add(cell.getEcgi());
                for (XranHostListener l : xranHostListeners) {
                    l.hostAdded(ue, ecgiSet);
                }
                return true;
            }

        }

        @Override
        public boolean removeConnectedHost(RnibUe ue) {
            List<RnibLink> links = xranStore.getlinksbyueid(ue.getId());
            links.forEach(rnibLink -> xranStore.removeLink(rnibLink.getLinkId()));
            if (ueMap.remove(ue.getId())) {
                for (XranHostListener l : xranHostListeners) {
                    l.hostRemoved(ue.getHostId());
                }
                return true;
            }
            return false;
        }
    }

    public class InternalXranPacketAgent implements XranPacketProcessor {
        @Override
        public void handlePacket(XrancPdu recvPdu, ChannelHandlerContext ctx)
                throws IOException, InterruptedException {
            XrancPdu sendPdu;

            int apiID = recvPdu.getHdr().getApiId().intValue();
            log.debug("Received message: {}", recvPdu);
            switch (apiID) {
                case 1: {
                    // Decode Cell config report.
                    CellConfigReport report = recvPdu.getBody().getCellConfigReport();
                    handleCellconfigreport(report, recvPdu.getHdr().getVer().toString());
                    break;
                }
                case 2: {
                    // Decode UE Admission Request.
                    UEAdmissionRequest ueAdmissionRequest = recvPdu.getBody().getUEAdmissionRequest();
                    handleUeadmissionrequest(ueAdmissionRequest, ctx);
                    break;
                }
                case 4: {
                    // Decode UE Admission Status.
                    UEAdmissionStatus ueAdmissionStatus = recvPdu.getBody().getUEAdmissionStatus();
                    handleAdmissionstatus(ueAdmissionStatus, ctx);
                    break;
                }
                case 5: {
                    // Decode UE Context Update.
                    UEContextUpdate ueContextUpdate = recvPdu.getBody().getUEContextUpdate();
                    handleUecontextupdate(ueContextUpdate, ctx);

                    break;
                }
                case 6: {
                    // Decode UE Reconfig_Ind.
                    UEReconfigInd ueReconfigInd = recvPdu.getBody().getUEReconfigInd();
                    handleUereconfigind(ueReconfigInd);
                    break;
                }
                case 7: {
                    // If xRANc wants to deactivate UE, we pass UEReleaseInd from xRANc to eNB.
                    // Decode UE Release_Ind.
                    UEReleaseInd ueReleaseInd = recvPdu.getBody().getUEReleaseInd();
                    handleUereleaseind(ueReleaseInd);
                    break;
                }
                case 8: {
                    // Decode Bearer Adm Request
                    BearerAdmissionRequest bearerAdmissionRequest = recvPdu.getBody().getBearerAdmissionRequest();
                    handleBeareradmissionrequest(bearerAdmissionRequest, ctx);
                    break;
                }
                case 10: {
                    //Decode Bearer Admission Status
                    BearerAdmissionStatus bearerAdmissionStatus = recvPdu.getBody().getBearerAdmissionStatus();
                    break;
                }
                case 11: {
                    //Decode Bearer Release Ind
                    BearerReleaseInd bearerReleaseInd = recvPdu.getBody().getBearerReleaseInd();
                    handleBearerreleaseind(bearerReleaseInd);
                    break;
                }
                case 13: {
                    HOFailure hoFailure = recvPdu.getBody().getHOFailure();
                    handleHofailure(hoFailure);
                    break;

                }
                case 14: {
                    HOComplete hoComplete = recvPdu.getBody().getHOComplete();
                    handleHocomplete(hoComplete, ctx);
                    break;
                }

                case 16: {
                    // Decode Rx Sig Meas Report.
                    RXSigMeasReport rxSigMeasReport = recvPdu.getBody().getRXSigMeasReport();
                    handleRxsigmeasreport(rxSigMeasReport);
                    break;
                }
                case 18: {
                    RadioMeasReportPerUE radioMeasReportPerUE = recvPdu.getBody().getRadioMeasReportPerUE();
                    handleRadionmeasreportperue(radioMeasReportPerUE);
                    break;
                }
                case 19: {
                    RadioMeasReportPerCell radioMeasReportPerCell = recvPdu.getBody().getRadioMeasReportPerCell();
                    break;
                }
                case 20: {
                    SchedMeasReportPerUE schedMeasReportPerUE = recvPdu.getBody().getSchedMeasReportPerUE();
                    handleSchedmeasreportperue(schedMeasReportPerUE);
                    break;
                }
                case 21: {
                    SchedMeasReportPerCell schedMeasReportPerCell = recvPdu.getBody().getSchedMeasReportPerCell();
                    handleSchedmeasreportpercell(schedMeasReportPerCell);
                    break;
                }
                case 22: {
                    PDCPMeasReportPerUe pdcpMeasReportPerUe = recvPdu.getBody().getPDCPMeasReportPerUe();
                    handlePdcpmeasreportperue(pdcpMeasReportPerUe);
                    break;
                }
                case 24: {
                    // Decode UE Capability Info
                    UECapabilityInfo capabilityInfo = recvPdu.getBody().getUECapabilityInfo();
                    handleCapabilityinfo(capabilityInfo);
                    break;
                }
                case 25: {
                    // Don't know what will invoke sending UE CAPABILITY ENQUIRY
                    // Encode and send UE CAPABILITY ENQUIRY
                    UECapabilityEnquiry ueCapabilityEnquiry = recvPdu.getBody().getUECapabilityEnquiry();
                    handleUecapabilityenquiry(ueCapabilityEnquiry, ctx);
                    break;
                }
                case 27: {
                    //Decode ScellAddStatus
                    ScellAddStatus scellAddStatus = recvPdu.getBody().getScellAddStatus();
                    handleScelladdstatus(scellAddStatus);
                    break;
                }
                case 30: {
                    // Decode RRMConfig Status
                    RRMConfigStatus rrmConfigStatus = recvPdu.getBody().getRRMConfigStatus();
                    handleRrmconfigstatus(rrmConfigStatus);
                    break;
                }
                //TODO Case 31: SeNBAdd 32: SeNBAddStatus 33: SeNBDelete
                case 34: {
                    TrafficSplitConfig trafficSplitConfig = recvPdu.getBody().getTrafficSplitConfig();
                    handleTrafficSplitConfig(trafficSplitConfig);
                    break;
                }
                default: {
                    log.warn("Wrong API ID: {}", recvPdu);
                    break;
                }
            }

        }

        /**
         * Handle Cellconfigreport.
         *
         * @param report  CellConfigReport
         * @param version String version ID
         */
        private void handleCellconfigreport(CellConfigReport report, String version) {
            ECGI ecgi = report.getEcgi();

            RnibCell cell = xranStore.getCell(ecgi);
            cell.setVersion(version);
            cell.setConf(report);
            cellMap.putPciArfcn(cell);
        }

        /**
         * Handle Ueadmissionrequest.
         *
         * @param ueAdmissionRequest UEAdmissionRequest
         * @param ctx                ChannelHandlerContext
         * @throws IOException IO Exception
         */
        private void handleUeadmissionrequest(UEAdmissionRequest ueAdmissionRequest, ChannelHandlerContext ctx)
                throws IOException {
            ECGI ecgi = ueAdmissionRequest.getEcgi();
            if (xranStore.getCell(ecgi) != null) {
                CRNTI crnti = ueAdmissionRequest.getCrnti();
                XrancPdu sendPdu = UEAdmissionResponse.constructPacket(ecgi, crnti, xranConfig.admissionFlag());
                ctx.writeAndFlush(getSctpMessage(sendPdu));
            } else {
                log.warn("Could not find ECGI in registered cells: {}", ecgi);
            }
        }

        /**
         * Handle UEAdmissionStatus.
         *
         * @param ueAdmissionStatus UEAdmissionStatus
         * @param ctx               ChannelHandlerContext
         */
        private void handleAdmissionstatus(UEAdmissionStatus ueAdmissionStatus, ChannelHandlerContext ctx) {
            RnibUe ue = ueMap.get(ueAdmissionStatus.getEcgi(), ueAdmissionStatus.getCrnti());
            if (ue != null) {
                if (ueAdmissionStatus.getAdmEstStatus().value.intValue() == 0) {
                    ue.setState(RnibUe.State.ACTIVE);
                } else {
                    ue.setState(RnibUe.State.IDLE);
                }
            }

            if (ueAdmissionStatus.getAdmEstStatus().value.intValue() == 0) {
                EcgiCrntiPair ecgiCrntiPair = EcgiCrntiPair
                        .valueOf(ueAdmissionStatus.getEcgi(), ueAdmissionStatus.getCrnti());
                contextUpdateMap.compute(ecgiCrntiPair, (k, v) -> {
                    if (v == null) {
                        v = new ContextUpdateHandler();
                    }
                    if (v.setAdmissionStatus(ueAdmissionStatus)) {
                        handlePairedPackets(v.getContextUpdate(), ctx, false);
                        v.reset();
                    }
                    return v;
                });
            }
        }

        /**
         * Handle UEContextUpdate.
         *
         * @param ueContextUpdate UEContextUpdate
         * @param ctx             ChannelHandlerContext
         */
        private void handleUecontextupdate(UEContextUpdate ueContextUpdate, ChannelHandlerContext ctx) {
            EcgiCrntiPair ecgiCrntiPair = EcgiCrntiPair
                    .valueOf(ueContextUpdate.getEcgi(), ueContextUpdate.getCrnti());

            contextUpdateMap.compute(ecgiCrntiPair, (k, v) -> {
                if (v == null) {
                    v = new ContextUpdateHandler();
                }
                if (v.setContextUpdate(ueContextUpdate)) {
                    HOComplete hoComplete = v.getHoComplete();
                    handlePairedPackets(ueContextUpdate, ctx, hoComplete != null);
                    if (hoComplete != null) {
                        try {
                            hoMap.get(hoComplete.getEcgiS()).put("Hand Over Completed");
                        } catch (InterruptedException e) {
                            log.error(ExceptionUtils.getFullStackTrace(e));
                            e.printStackTrace();
                        } finally {
                            hoMap.remove(hoComplete.getEcgiS());
                        }
                    }
                    v.reset();
                }
                return v;
            });
        }

        /**
         * Handle UEReconfigInd.
         *
         * @param ueReconfigInd UEReconfigInd
         */
        private void handleUereconfigind(UEReconfigInd ueReconfigInd) {
            RnibUe ue = ueMap.get(ueReconfigInd.getEcgi(), ueReconfigInd.getCrntiOld());
            RnibCell cell = cellMap.get(ueReconfigInd.getEcgi());

            if (ue != null && cell != null) {
                ue.setCrnti(ueReconfigInd.getCrntiNew());
                ueMap.putCrnti(cell, ue);
            } else {
                log.warn("Could not find UE with this CRNTI: {}", ueReconfigInd.getCrntiOld());
            }
        }

        /**
         * Handle UEReleaseInd.
         *
         * @param ueReleaseInd UEReleaseInd
         */
        private void handleUereleaseind(UEReleaseInd ueReleaseInd) {
            ECGI ecgi = ueReleaseInd.getEcgi();
            CRNTI crnti = ueReleaseInd.getCrnti();
            RnibUe ue = ueMap.get(ecgi, crnti);

            // Check if there is an ongoing handoff and only remove if ue is not part of the handoff.
            Long peek = ueIdQueue.peek();
            if (peek != null) {
                EcgiCrntiPair ecgiCrntiPair = ueMap.getCrntUe().inverse().get(peek);
                if (ecgiCrntiPair != null && ecgiCrntiPair.equals(EcgiCrntiPair.valueOf(ecgi, crnti))) {
                    return;
                }
            }

            if (ue != null) {
                ue.setState(RnibUe.State.IDLE);
                restartTimer(ue);
            } else {
                log.warn("Cannot release UE from non primary link.");
            }
        }

        /**
         * Handle BearerAdmissionRequest.
         *
         * @param bearerAdmissionRequest BearerAdmissionRequest
         * @param ctx                    ChannelHandlerContext
         * @throws IOException IO Exception
         */
        private void handleBeareradmissionrequest(BearerAdmissionRequest bearerAdmissionRequest,
                                                  ChannelHandlerContext ctx) throws IOException {
            ECGI ecgi = bearerAdmissionRequest.getEcgi();
            CRNTI crnti = bearerAdmissionRequest.getCrnti();
            ERABParams erabParams = bearerAdmissionRequest.getErabParams();
            RnibLink link = linkMap.get(ecgi, crnti);
            if (link != null) {
                link.setBearerParameters(erabParams);
            } else {
                log.warn("Could not find link between {}-{}", ecgi, crnti);
            }

            BerInteger numErabs = bearerAdmissionRequest.getNumErabs();
            // Encode and send Bearer Admission Response
            XrancPdu sendPdu = BearerAdmissionResponse
                    .constructPacket(ecgi, crnti, erabParams, numErabs, xranConfig.bearerFlag());
            ctx.writeAndFlush(getSctpMessage(sendPdu));
        }

        /**
         * Handle BearerReleaseInd.
         *
         * @param bearerReleaseInd
         */
        private void handleBearerreleaseind(BearerReleaseInd bearerReleaseInd) {
            ECGI ecgi = bearerReleaseInd.getEcgi();
            CRNTI crnti = bearerReleaseInd.getCrnti();
            RnibLink link = linkMap.get(ecgi, crnti);

            List<ERABID> erabidsRelease = bearerReleaseInd.getErabIds().getERABID();
            List<ERABParamsItem> erabParamsItem = link.getBearerParameters().getERABParamsItem();

            List<ERABParamsItem> unreleased = erabParamsItem
                    .stream()
                    .filter(item -> {
                        Optional<ERABID> any = erabidsRelease.stream()
                                .filter(id -> id.equals(item.getId())).findAny();
                        return !any.isPresent();
                    }).collect(Collectors.toList());

            link.getBearerParameters().setERABParamsItem(new ArrayList<>(unreleased));
        }

        /**
         * Handle HOFailure.
         *
         * @param hoFailure HOFailure
         * @throws InterruptedException ueIdQueue interruption
         */
        private void handleHofailure(HOFailure hoFailure) throws InterruptedException {
            try {
                hoMap.get(hoFailure.getEcgi())
                        .put("Hand Over Failed with cause: " + hoFailure.getCause());
            } catch (InterruptedException e) {
                log.error(ExceptionUtils.getFullStackTrace(e));
                e.printStackTrace();
            } finally {
                hoMap.remove(hoFailure.getEcgi());
                ueIdQueue.take();
            }
        }

        /**
         * Handle HOComplete.
         *
         * @param hoComplete HOComplete
         * @param ctx        ChannelHandlerContext
         */
        private void handleHocomplete(HOComplete hoComplete, ChannelHandlerContext ctx) {
            EcgiCrntiPair ecgiCrntiPair = EcgiCrntiPair.valueOf(hoComplete.getEcgiT(),
                    hoComplete.getCrntiNew());
            contextUpdateMap.compute(ecgiCrntiPair, (k, v) -> {
                if (v == null) {
                    v = new ContextUpdateHandler();
                }
                if (v.setHoComplete(hoComplete)) {
                    handlePairedPackets(v.getContextUpdate(), ctx, true);

                    try {
                        hoMap.get(hoComplete.getEcgiS()).put("Hand Over Completed");
                    } catch (InterruptedException e) {
                        log.error(ExceptionUtils.getFullStackTrace(e));
                        e.printStackTrace();
                    } finally {
                        hoMap.remove(hoComplete.getEcgiS());
                    }
                    v.reset();
                }
                return v;
            });
        }

        /**
         * Handle RXSigMeasReport.
         *
         * @param rxSigMeasReport RXSigMeasReport
         */
        private void handleRxsigmeasreport(RXSigMeasReport rxSigMeasReport) {
            List<RXSigReport> rxSigReportList = rxSigMeasReport.getCellMeasReports().getRXSigReport();

            RnibUe ue = ueMap.get(rxSigMeasReport.getEcgi(), rxSigMeasReport.getCrnti());
            if (ue != null) {
                Long ueId = ue.getId();

                if (!rxSigReportList.isEmpty()) {
                    rxSigReportList.forEach(rxSigReport -> {
                        RnibCell cell = cellMap.get(rxSigReport.getPciArfcn());
                        if (cell != null) {
                            ECGI ecgi = cell.getEcgi();

                            RnibLink link = linkMap.get(ecgi, ueId);
                            if (link == null) {
                                log.warn("Could not find link between: {}-{} | Creating non-serving link..",
                                        ecgi, ueId);
                                link = linkMap.putNonServingLink(cell, ueId);
                            }

                            if (link != null) {
                                if (link.getType().equals(RnibLink.Type.NON_SERVING)) {
                                    restartTimer(link);
                                }

                                RSRQRange rsrq = rxSigReport.getRsrq();
                                RSRPRange rsrp = rxSigReport.getRsrp();

                                RnibLink.LinkQuality quality = link.getQuality();
                                quality.setRx(new RnibLink.LinkQuality.Rx(
                                        rsrp.value.intValue() - 140,
                                        (rsrq.value.intValue() * 0.5) - 19.5
                                ));
                            }
                        } else {
                            log.warn("case 16: Could not find cell with PCI-ARFCN: {}",
                                    rxSigReport.getPciArfcn());
                        }
                    });
                }
            }
        }

        /**
         * Handle RadioMeasReportPerUE.
         *
         * @param radioMeasReportPerUE RadioMeasReportPerUE
         */
        private void handleRadionmeasreportperue(RadioMeasReportPerUE radioMeasReportPerUE) {
            RnibUe ue = ueMap.get(radioMeasReportPerUE.getEcgi(), radioMeasReportPerUE.getCrnti());
            if (ue != null) {
                Long ueId = ue.getId();
                List<RadioRepPerServCell> servCells = radioMeasReportPerUE.getRadioReportServCells()
                        .getRadioRepPerServCell();

                servCells.forEach(servCell -> {
                    RnibCell cell = cellMap.get(servCell.getPciArfcn());
                    if (cell != null) {
                        RnibLink link = linkMap.get(cell.getEcgi(), ueId);
                        if (link != null) {
                            RadioRepPerServCell.CqiHist cqiHist = servCell.getCqiHist();
                            RnibLink.LinkQuality quality = link.getQuality();

                            final double[] values = {0, 0, 0};
                            final int[] i = {1};
                            cqiHist.getBerInteger().forEach(value -> {
                                values[0] = Math.max(values[0], value.intValue());
                                values[1] += i[0] * value.intValue();
                                values[2] += value.intValue();
                                i[0]++;
                            });

                            quality.setCqi(new RnibLink.LinkQuality.Cqi(
                                    cqiHist,
                                    values[0],
                                    values[1] / values[0]
                            ));

                        } else {
                            log.warn("Could not find link between: {}-{}", cell.getEcgi(), ueId);
                        }
                    } else {
                        log.warn("case 18: Could not find cell with PCI-ARFCN: {}", servCell.getPciArfcn());
                    }
                });
            }
        }

        /**
         * Handle SchedMeasReportPerUE.
         *
         * @param schedMeasReportPerUE SchedMeasReportPerUE
         */
        private void handleSchedmeasreportperue(SchedMeasReportPerUE schedMeasReportPerUE) {
            RnibUe ue = ueMap.get(schedMeasReportPerUE.getEcgi(), schedMeasReportPerUE.getCrnti());
            if (ue != null) {
                Long ueId = ue.getId();

                List<SchedMeasRepPerServCell> servCells = schedMeasReportPerUE.getSchedReportServCells()
                        .getSchedMeasRepPerServCell();

                servCells.forEach(servCell -> {
                    RnibCell cell = cellMap.get(servCell.getPciArfcn());
                    if (cell != null) {
                        RnibLink link = linkMap.get(cell.getEcgi(), ueId);
                        if (link != null) {
                            link.getQuality().setMcs(new RnibLink.LinkQuality.Mcs(
                                    servCell.getMcsDl(),
                                    servCell.getMcsUl()
                            ));

                            link.setResourceUsage(new RnibLink.ResourceUsage(
                                    servCell.getPrbUsage().getPrbUsageDl(),
                                    servCell.getPrbUsage().getPrbUsageUl()
                            ));
                        } else {
                            log.warn("Could not find link between: {}-{}", cell.getEcgi(), ueId);
                        }
                    } else {
                        log.warn("case 20: Could not find cell with PCI-ARFCN: {}", servCell.getPciArfcn());
                    }
                });
            }
        }

        /**
         * Handle SchedMeasReportPerCell.
         *
         * @param schedMeasReportPerCell SchedMeasReportPerCell
         */
        private void handleSchedmeasreportpercell(SchedMeasReportPerCell schedMeasReportPerCell) {
            RnibCell cell = cellMap.get(schedMeasReportPerCell.getEcgi());
            if (cell != null) {
                cell.setPrbUsage(new RnibCell.PrbUsageContainer(
                        schedMeasReportPerCell.getPrbUsagePcell(),
                        schedMeasReportPerCell.getPrbUsageScell()
                ));

                cell.setQci(schedMeasReportPerCell.getQciVals());
            } else {
                log.warn("Could not find cell with ECGI: {}", schedMeasReportPerCell.getEcgi());
            }
        }

        /**
         * Handle PDCPMeasReportPerUe.
         *
         * @param pdcpMeasReportPerUe PDCPMeasReportPerUe
         */
        private void handlePdcpmeasreportperue(PDCPMeasReportPerUe pdcpMeasReportPerUe) {
            RnibUe ue = ueMap.get(pdcpMeasReportPerUe.getEcgi(), pdcpMeasReportPerUe.getCrnti());
            if (ue != null) {
                Long ueId = ue.getId();
                RnibLink link = linkMap.get(pdcpMeasReportPerUe.getEcgi(), ueId);
                if (link != null) {
                    link.setPdcpThroughput(new RnibLink.PdcpThroughput(
                            pdcpMeasReportPerUe.getThroughputDl(),
                            pdcpMeasReportPerUe.getThroughputUl()
                    ));

                    link.setPdcpPackDelay(new RnibLink.PdcpPacketdelay(
                            pdcpMeasReportPerUe.getPktDelayDl(),
                            pdcpMeasReportPerUe.getPktDelayUl()
                    ));
                } else {
                    log.warn("Could not find link between: {}-{}", pdcpMeasReportPerUe.getEcgi(), ueId);
                }
            }
        }

        /**
         * Handle UECapabilityInfo.
         *
         * @param capabilityInfo UECapabilityInfo
         */
        private void handleCapabilityinfo(UECapabilityInfo capabilityInfo) {
            RnibUe ue = ueMap.get(capabilityInfo.getEcgi(), capabilityInfo.getCrnti());
            if (ue != null) {
                ue.setCapability(capabilityInfo);
            } else {
                log.warn("Could not find UE with this CRNTI: {}", capabilityInfo.getCrnti());
            }
        }

        /**
         * Handle UECapabilityEnquiry.
         *
         * @param ueCapabilityEnquiry UECapabilityEnquiry
         * @param ctx                 ChannelHandlerContext
         * @throws IOException IO Exception
         */
        private void handleUecapabilityenquiry(UECapabilityEnquiry ueCapabilityEnquiry, ChannelHandlerContext ctx)
                throws IOException {
            XrancPdu xrancPdu = UECapabilityEnquiry.constructPacket(ueCapabilityEnquiry.getEcgi(),
                    ueCapabilityEnquiry.getCrnti());
            ctx.writeAndFlush(getSctpMessage(xrancPdu));
        }

        /**
         * Handle ScellAddStatus.
         *
         * @param scellAddStatus ScellAddStatus
         */
        private void handleScelladdstatus(ScellAddStatus scellAddStatus) {
            RnibUe ue = ueMap.get(scellAddStatus.getEcgi(), scellAddStatus.getCrnti());
            if (ue != null) {
                Long ueId = ue.getId();
                try {
                    scellAddMap.get(scellAddStatus.getCrnti()).put("Scell's status: " +
                            scellAddStatus.getStatus());
                    final int[] i = {0};
                    scellAddStatus.getScellsInd().getPCIARFCN().forEach(
                            pciarfcn -> {
                                if (scellAddStatus.getStatus().getBerEnum().get(i[0]).value.intValue() == 0) {
                                    RnibCell cell = cellMap.get(pciarfcn);
                                    RnibLink link = linkMap.get(cell.getEcgi(), ueId);
                                    link.setType(RnibLink.Type.SERVING_SECONDARY_CA);
                                }
                                i[0]++;
                            }
                    );

                } catch (InterruptedException e) {
                    log.error(ExceptionUtils.getFullStackTrace(e));
                    e.printStackTrace();
                } finally {
                    scellAddMap.remove(scellAddStatus.getCrnti());
                }
            }
        }

        /**
         * Handle RRMConfigStatus.
         *
         * @param rrmConfigStatus RRMConfigStatus
         */
        private void handleRrmconfigstatus(RRMConfigStatus rrmConfigStatus) {
            try {
                rrmcellMap.get(rrmConfigStatus.getEcgi())
                        .put("RRM Config's status: " + rrmConfigStatus.getStatus());
            } catch (InterruptedException e) {
                log.error(ExceptionUtils.getFullStackTrace(e));
                e.printStackTrace();
            } finally {
                rrmcellMap.remove(rrmConfigStatus.getEcgi());
            }
        }

        /**
         * Handle TrafficSplitConfig.
         *
         * @param trafficSplitConfig TrafficSplitConfig
         */
        private void handleTrafficSplitConfig(TrafficSplitConfig trafficSplitConfig) {
            RnibUe ue = ueMap.get(trafficSplitConfig.getEcgi(), trafficSplitConfig.getCrnti());
            if (ue != null) {
                Long ueId = ue.getId();
                List<TrafficSplitPercentage> splitPercentages = trafficSplitConfig
                        .getTrafficSplitPercent().getTrafficSplitPercentage();

                splitPercentages.forEach(trafficSplitPercentage -> {
                    RnibCell cell = cellMap.get(trafficSplitPercentage.getEcgi());
                    if (cell != null) {
                        RnibLink link = linkMap.get(cell.getEcgi(), ueId);
                        if (link != null) {
                            link.setTrafficPercent(trafficSplitPercentage);
                        } else {
                            log.warn("Could not find link between: {}-{}", cell.getEcgi(), ueId);
                        }
                    } else {
                        log.warn("Could not find cell with ECGI: {}", trafficSplitConfig.getEcgi());
                    }
                });
            }
        }

        /**
         * Handle context update depending if its handoff or not.
         *
         * @param contextUpdate context update packet
         * @param ctx           channel context for the CELL
         * @param handoff       true if we handle a Hand Off
         */
        private void handlePairedPackets(UEContextUpdate contextUpdate, ChannelHandlerContext ctx, boolean handoff) {
            RnibUe ue;
            RnibCell cell = xranStore.getCell(contextUpdate.getEcgi());

            if (handoff) {
                try {
                    ue = ueMap.get(ueIdQueue.take());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    log.error(ExceptionUtils.getFullStackTrace(e));
                    ue = new RnibUe();
                }
            } else {
                ue = new RnibUe();
            }

            ue.setMmeS1apId(contextUpdate.getMMEUES1APID());
            ue.setEnbS1apId(contextUpdate.getENBUES1APID());
            ue.setCrnti(contextUpdate.getCrnti());

            hostAgent.addConnectedHost(ue, cell, ctx);
        }
    }

    /**
     * Internal class for NetworkConfigListener.
     */
    class InternalNetworkConfigListener implements NetworkConfigListener {

        @Override
        public void event(NetworkConfigEvent event) {
            switch (event.type()) {
                case CONFIG_REGISTERED:
                    break;
                case CONFIG_UNREGISTERED:
                    break;
                case CONFIG_ADDED:
                case CONFIG_UPDATED:
                    if (event.configClass() == CONFIG_CLASS) {
                        handleConfigEvent(event.config());
                    }
                    break;
                case CONFIG_REMOVED:
                    break;
                default:
                    break;
            }
        }

        /**
         * Handle config event.
         *
         * @param config
         */
        private void handleConfigEvent(Optional<Config> config) {
            if (!config.isPresent()) {
                return;
            }

            xranConfig = (XranConfig) config.get();

            northboundTimeout = xranConfig.getNorthBoundTimeout();

            legitCells.putAll(xranConfig.activeCellSet());

            controller.start(deviceAgent, hostAgent, packetAgent, xranConfig.getXrancIp(), xranConfig.getXrancPort());
        }
    }
}
