BearerManagement.h Source File

Simu5G: BearerManagement.h Source File
Simu5G
BearerManagement.h
1//
2// Simu5G
3//
4// Authors: Andras Varga (OpenSim Ltd)
5//
6// This file is part of a software released under the license included in file
7// "license.pdf". Please read LICENSE and README files before using it.
8// The above files and the present reference are part of the software itself,
9// and cannot be removed from it.
10//
11
12#ifndef _BEARER_MANAGEMENT_H_
13#define _BEARER_MANAGEMENT_H_
14
15#include "simu5g/common/LteDefs.h"
16#include "simu5g/common/LteControlInfo.h"
17#include "simu5g/stack/rrc/DrbTable.h"
18#include <inet/common/ModuleRefByPar.h>
19#include <set>
20#include <utility>
21
22using namespace omnetpp;
23
24namespace simu5g {
25
26class LteMacBase;
27class RlcMux;
28class RlcTxEntityBase;
29class RlcRxEntityBase;
31class PdcpMux;
32class DcMux;
35class Registration;
36class Binder;
38class NrSdap;
40class QfiRuleSet;
41class Ip2Nic;
42class HandoverPacketHolderUe;
43
48class BearerManagement : public cSimpleModule
49{
50 protected:
51 Registration *registration_ = nullptr;
52
53 // PDCP entity types (resolved from NED params): the full PDCP entity is a compound
54 // (LtePdcpEntity/NrPdcpEntity, TX+RX); at a DC secondary an PdcpRelayEntity stands in for it.
55 cModuleType *pdcpEntityModuleType_ = nullptr;
56 cModuleType *pdcpRelayEntityModuleType_ = nullptr;
57 cModule *nicModule_ = nullptr; // containing NIC module (parent of all submodules and entities)
58
59 // RLC entity types (compound modules; resolved from NED params):
60 // lteRlc* = LTE-FI bearers (TS 36.322), nrRlc* = NR bearers (SI/SO, TS 38.322)
61 cModuleType *rlcTmEntityModuleType_ = nullptr;
62 cModuleType *lteRlcUmEntityModuleType_ = nullptr;
63 cModuleType *lteRlcAmEntityModuleType_ = nullptr;
64 cModuleType *nrRlcUmEntityModuleType_ = nullptr;
65 cModuleType *nrRlcAmEntityModuleType_ = nullptr;
66
67 inet::ModuleRefByPar<RlcMux> rlcMuxModule;
68 inet::ModuleRefByPar<RlcMux> nrRlcMuxModule;
69 inet::ModuleRefByPar<LteMacBase> macModule;
70 inet::ModuleRefByPar<LteMacBase> nrMacModule;
71 inet::ModuleRefByPar<Binder> binderModule; // DC master/secondary topology lookups; peer BearerManagement on RLF
72 inet::ModuleRefByPar<ConnectionControlBase> connectionControlModule; // the node's control-plane entry point, which a torn-down bearer's DRB identity goes back through
73 inet::ModuleRefByPar<DrbTable> drbTableModule; // the bearer configuration this module authors
74 inet::ModuleRefByPar<NrSdap> sdapModule; // configuration push target; null when the NIC has no SDAP
75 inet::ModuleRefByPar<QosFlowClassifier> qosFlowClassifierModule; // uplink QFI rule push target; null unless a UE stack with SDAP
76 Ip2Nic *ip2nicModule_ = nullptr; // configuration/notification push target
77
78 // Tell the user-plane modules that a bearer came up or went away, so they never have
79 // to inspect another layer to find out. Called exactly where this module mutates
80 // PdcpMux's TX-entity registry, so their view of which bearers exist is identical
81 // to that registry by construction.
82 virtual void notifyBearerEstablished(DrbKey key);
83 virtual void notifyBearerReleased(DrbKey key);
84
85 // Give a torn-down bearer's DRB identity back to the pool it came from, through
86 // the node's control-plane entry point (see ConnectionControlBase::bearerReleased()).
87 virtual void releaseDrbIdOf(DrbKey bearer);
88
89 // Entity registries (CP owns the lifecycle of all entities)
90 // One PDCP entity module (compound: TX+RX, see PdcpEntityBase) per bearer, keyed by (peer
91 // node, DRB id); the tx/rx submodule pointers below index into it for per-side lookups.
92 std::map<DrbKey, cModule *> pdcpEntities_;
93 std::map<DrbKey, PdcpTxEntityBase *> pdcpTxEntities_;
94 std::map<DrbKey, PdcpRxEntityBase *> pdcpRxEntities_;
95 // One PdcpRelayEntity compound per DC-secondary bearer (both directions), keyed by (UE, DRB id)
96 std::map<DrbKey, cModule *> pdcpRelayEntities_;
97 // One RLC entity module (compound: TX+RX sides, see RlcTm/Um/AmEntity) per
98 // bearer, keyed by (peer node, DRB id); one map per leg (LTE / NR)
99 std::map<DrbKey, cModule *> rlcEntities_;
100 std::map<DrbKey, cModule *> nrRlcEntities_;
101
102 // Radio Link Failure: teardown is deferred to a safe execution context via a
103 // self-message, so we never delete entity modules from inside RLC/PDCP processing.
104 cMessage *rlfTrigger_ = nullptr;
105 std::set<std::pair<MacNodeId, bool>> pendingRlf_; // (peer nodeId, nrStack)
106 virtual void handleRadioLinkFailure(MacNodeId nodeId, bool nrStack);
107
108 // RRC re-establishment (TS 38.331 5.3.7), modeled by its timers. On RLF the peer's link
109 // is released (Ip2Nic drops its traffic); T311 (cell selection) then T301 (request ->
110 // complete) run, after which the peer is un-released (Ip2Nic::resumeUe) and its bearer
111 // re-establishes on demand. t311_ = 0 => release-to-IDLE (no reconnect attempt).
112 simtime_t t311_;
113 simtime_t t301_;
114 std::map<cMessage *, MacNodeId> t311Timers_; // pending cell-selection timers -> peer
115 std::map<cMessage *, MacNodeId> t301Timers_; // pending request->complete timers -> peer
116
117 // NR dual connectivity on this NIC: infrastructure bearers get two legs (see
118 // findOrCreatePdcpEntity)
119 bool dualConnectivityEnabled_ = false;
120
121 /*
122 * The serving node of each of this UE's stacks, as RRC knows
123 * it: updated the instant a handover, attachment or detachment BEGINS (see
124 * ConnectionControlUe::triggerHandover()), which is ahead of the Binder -- that
125 * learns only when the handover executes. Within that window this is the answer
126 * that matches what the stack is actually doing; the Binder's stale one would make
127 * the UE abandon a stack that is attached, or about to be. Seeded from the Binder
128 * at initialization, which is still too early to see the result of dynamic cell
129 * association. UE only: a base station learns of its UEs' handovers by signaling
130 * and has no earlier local knowledge (its bearer legs consult the Binder).
131 *
132 * Delivery is push only: every change is fanned out to the modules that steer by
133 * it (see pushServingNodeIds()), which keep mirrors and never call back into
134 * RRC on the data path.
135 */
136 MacNodeId servingNodeId_ = NODEID_NONE; // the LTE stack's serving node
137 MacNodeId nrServingNodeId_ = NODEID_NONE; // the NR stack's serving node
138
139 // push target of the attachment ledger (UE only; see pushServingNodeIds())
140 HandoverPacketHolderUe *handoverPacketHolderModule_ = nullptr;
141
142 // The configuration entry for the bearer of an infrastructure unicast flow, as
143 // delivered by configureDrb(), or nullptr. peerId is the flow's remote end; on the
144 // UE side entries are keyed by NODEID_NONE instead.
145 virtual const DrbDesc *lookupConfiguredDrb(const FlowId& flow, MacNodeId peerId);
146
147 // Checks req.rlcMode before any use of it (entity type selection, materializeDrb),
148 // called once at the top of each establishment entry point. The delivered configuration
149 // wins (a conflicting explicit request throws). The bearer configurator resolves
150 // every request before it reaches RRC (from the bearer's definition entry, or the fixed D2D/multicast
151 // configuration), so an rlcMode still UNKNOWN_RLC_MODE here is a requester bug and
152 // throws.
153 virtual BearerRequest resolveBearerRequest(const BearerRequest& req, const FlowId& flow, MacNodeId peerId);
154
155 virtual void setRlcEntityParams(cModule *entity, bool isNr);
156 virtual void setEntityDisplayPosition(cModule *entity, bool isPdcpEntity, cModule *rlcMux, int bearerIndex);
157 virtual cModule *lookupRlcEntityModule(DrbKey id, bool isNr);
158 virtual cModule *findOrCreateRlcEntity(DrbKey id, RlcMode rlcMode, const FlowId& flow, RlcMux *rlcMux, bool isNr);
159 virtual RlcTxEntityBase *installRlcTxSide(DrbKey id, const FlowId& flow, const BearerRequest& req, RlcMux *rlcMux, bool isNr);
160 virtual RlcRxEntityBase *installRlcRxSide(DrbKey id, const FlowId& flow, const BearerRequest& req, RlcMux *rlcMux, bool isNr);
161 virtual cModule *findOrCreatePdcpEntity(DrbKey id, const FlowId& flow, RlcMode rlcMode, RlcMux *rlcMux);
162 virtual void installPdcpTxSide(DrbKey id, const FlowId& flow, RlcMode rlcMode, RlcMux *rlcMux, bool isNr);
163 virtual void installPdcpRxSide(DrbKey id, const FlowId& flow, RlcMode rlcMode, RlcMux *rlcMux, bool isNr);
164 virtual cModule *findOrCreatePdcpRelayEntity(DrbKey id, RlcMux *rlcMux);
165
166 // The layout of a bearer over the node's stack legs. getNumLegs() gives the number of legs
167 // the bearer's PDCP entity is built with, legCellGroups() the cell group of each leg
168 // (authored, or derived: two legs = an MCG+SCG split bearer, one = MCG), and
169 // selectPdcpLeg() the leg an establishment call attaches to (and, for a leg of a
170 // bearer anchored elsewhere, the anchor bearer's key).
171 virtual int getNumLegs(DrbKey id, const FlowId& flow);
172 virtual std::vector<CellGroup> legCellGroups(DrbKey id, const FlowId& flow, int numLegs);
173 virtual int selectPdcpLeg(MacNodeId peerId, const FlowId& flow, DrbKey& compoundId /*inout*/);
174
175 // True when this node terminates the bearer's PDCP without carrying an RLC leg of it:
176 // a DC master whose bearer states legs without an MCG leg (an SCG bearer, TS 37.340).
177 // The core network still delivers to the master, so its PDCP legs are wired to the
178 // X2 path and no local RLC/MAC state exists. peerId keys the configuration lookup.
179 virtual bool isPdcpAnchorOnly(const FlowId& flow, MacNodeId peerId);
180
181 // This node's own MacNodeId. A base station holds it under the technology it is, so a
182 // gNB has no LTE id to ask for; a dual-stack UE has both, and its LTE id is its
183 // identity (see Registration).
184 virtual MacNodeId getOwnNodeId() const;
185
186 // Is this one of the node's own ids? Spelling the question out as "the LTE id or the
187 // NR id" is what breaks at a node whose stacks are not that pair.
188 virtual bool isLocalNodeId(MacNodeId nodeId) const;
189
190 // Whether this base station serves only a non-anchor leg of the given UE's bearers:
191 // it is a secondary node and the UE is also attached to its master, where the
192 // bearers' PDCP (and any SDAP) terminates. NODEB only; see configureDrb().
193 virtual bool servesNonAnchorLegOnly(MacNodeId ueId);
194
195 // Records the configuration of the bearer this establishment call sets up, from
196 // exactly the derivations the entities are built from. Runs after the RLC entity
197 // exists: the wire format and the SN field length are properties of the entity that
198 // implements the bearer, and are read off it. Returns the descriptor so callers can
199 // push it into MAC without a re-lookup.
200 virtual const DrbDesc& materializeDrb(const FlowId& flow, const BearerRequest& req, MacNodeId peerId, DrbKey rlcId, bool isNr);
201
202 protected:
203 void initialize(int stage) override;
204 int numInitStages() const override { return inet::NUM_INIT_STAGES; }
205 void handleMessage(cMessage *msg) override;
206
207 public:
208 ~BearerManagement() override;
209 // Take delivery of one bearer's configuration from the serving base station's
210 // control plane (see ConnectionControlEnb::pushDrbToRrcs()), through this
211 // node's entry point. RRC never fetches this itself.
212 virtual void configureDrb(const DrbDesc& drb);
213
214 // The bearer configuration delivered for the given peer (at a base station: a UE
215 // leg), as configureDrb() recorded it
216 virtual std::vector<DrbDesc> getConfiguredDrbs(MacNodeId peerId);
217 // Take delivery of this UE's uplink QFI-assignment rules from the core network
218 // (see CoreControl::deliverQfiRules()) and push them into the
219 // QoS-flow classifier, which never authors rules of its own. UE with SDAP only.
220 virtual void setUplinkQfiRules(QfiRuleSet&& rules);
221 // Record that one of this UE's stacks is changing its serving node -- called by the
222 // UE's connection control the instant a handover, attachment or detachment begins,
223 // ahead of its execution. NODEID_NONE = the stack is detaching. Each updates the
224 // ledger and pushes it to every consumer (see servingNodeId_). UE only.
225 virtual void setServingNodeId(MacNodeId servingNodeId);
226 virtual void setNrServingNodeId(MacNodeId servingNodeId);
227 // Deliver the attachment ledger to everything that steers by it -- ~Ip2Nic, the
228 // ~HandoverPacketHolderUe, and each bearer's leg splitter. Consumers keep pushed
229 // mirrors; nothing pulls. A splitter created later gets its initial push at
230 // creation (see findOrCreatePdcpEntity()).
231 virtual void pushServingNodeIds();
232 // Schedule an RLC-detected radio link failure teardown for a peer node, deferred
233 // to a safe execution context. nrStack selects the failing leg (LTE vs NR).
234 virtual void scheduleRadioLinkFailure(MacNodeId nodeId, bool nrStack);
235 // Release + tear down the link to a peer (both legs, MAC/RLC/PDCP + Ip2Nic drop). Public
236 // so the failing node can drive the symmetric teardown on the peer via the binder.
237 virtual void releaseLink(MacNodeId peerId);
238 virtual void createIncomingConnection(const FlowId& flow, const BearerRequest& req, bool withPdcp=true);
239 virtual void createOutgoingConnection(const FlowId& flow, const BearerRequest& req, bool withPdcp=true);
240 virtual RlcTxEntityBase *createRlcTxBuffer(DrbKey id, const FlowId& flow, const BearerRequest& req);
241 virtual RlcRxEntityBase *createRlcRxBuffer(DrbKey id, const FlowId& flow, const BearerRequest& req);
242 virtual PdcpTxEntityBase *lookupPdcpTxEntity(DrbKey id);
243 virtual cModule *lookupPdcpEntityModule(DrbKey id); // the per-bearer PdcpEntityBase compound (DcMux leg dispatch)
244 virtual cModule *lookupPdcpRelayEntityModule(DrbKey id); // the per-bearer PdcpRelayEntity compound (DcMux DL dispatch)
245 virtual void deleteLocalPdcpEntities(MacNodeId nodeId);
246 virtual void deleteLocalRlcQueues(MacNodeId nodeId, bool nrStack=false);
247 virtual void pdcpActiveUeUL(std::set<MacNodeId> *ueSet);
248};
249
250} // namespace simu5g
251
252#endif
RRC Bearer Management — creates and tears down PDCP, RLC and MAC entities for data radio bearers.
Definition BearerManagement.h:49
Definition Binder.h:48
Definition ConnectionControlBase.h:42
Dual Connectivity mux.
Definition DcMux.h:34
Definition LteTypes.h:191
MAC Layer.
Definition LteMacBase.h:80
Definition NrSdap.h:45
Upper-layer PDCP packet dispatcher.
Definition PdcpMux.h:35
Abstract base class for all RX PDCP entities.
Definition PdcpRxEntityBase.h:29
Abstract base class for all TX PDCP entities.
Definition PdcpTxEntityBase.h:29
An ordered set of QFI-assignment rules, shared by every module that classifies packets to QoS flows.
Definition QfiRuleSet.h:57
Classifies a UE's uplink packets to QoS flows (see QosFlowClassifier.ned).
Definition QosFlowClassifier.h:35
RRC Registration — registers the node with the Binder, sets up the network interface,...
Definition Registration.h:29
Lower-layer RLC packet dispatcher.
Definition RlcMux.h:37
Abstract base class for all RLC RX entities (UM, TM, AM).
Definition RlcRxEntityBase.h:29
Abstract base class for all RLC TX entities (UM, TM, AM).
Definition RlcTxEntityBase.h:29
Common shell of the RLC UM transmission entity.
Definition RlcUmTxEntityBase.h:40
Definition AlertReceiver.h:24
constexpr MacNodeId NODEID_NONE
MAC node ID.
Definition LteTypes.h:54