DcPdcpLegSplitter.h Source File

Simu5G: DcPdcpLegSplitter.h Source File
Simu5G
DcPdcpLegSplitter.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 _DC_PDCP_LEG_SPLITTER_H_
13#define _DC_PDCP_LEG_SPLITTER_H_
14
15#include <inet/common/ModuleRefByPar.h>
16#include "simu5g/common/LteCommon.h"
17#include "simu5g/common/LteControlInfo.h"
18#include "simu5g/common/binder/Binder.h"
19#include "simu5g/stack/rrc/DrbDesc.h" // SPLIT_THRESHOLD_INFINITY
20
21namespace simu5g {
22
23class RlcTxEntityBase;
24
32class DcPdcpLegSplitter : public omnetpp::cSimpleModule
33{
34 protected:
35 // Variable bindings for the legSelection override expression
36 class PolicyResolver : public omnetpp::cDynamicExpression::IResolver {
37 DcPdcpLegSplitter *module_;
38 public:
39 PolicyResolver(DcPdcpLegSplitter *module) : module_(module) {}
40 IResolver *dup() const override { return new PolicyResolver(module_); }
41 omnetpp::cValue readVariable(omnetpp::cExpression::Context *context, const char *name) override;
42 };
43
44 static omnetpp::simsignal_t sentPacketToLowerLayerSignal_;
45 static omnetpp::simsignal_t pdcpSduSentSignal_;
46 static omnetpp::simsignal_t pdcpSduSentNrSignal_;
47
48 inet::ModuleRefByPar<Binder> binder_;
49
50 int numLegs_ = 1;
51 std::vector<CellGroup> legGroups_; // cell group of each leg, in leg-index order (the legs parameter)
52 bool isUe_ = false; // selects the SCG leg's id mapping: UE's secondary stack vs a master's X2 leg
53
54 MacNodeId nodeId_ = NODEID_NONE; // this node's (LTE/base) id
55 MacNodeId nrNodeId_ = NODEID_NONE; // this UE's NR-leg id (UEs only)
56
57 // UEs only: mirror of RRC's stack attachment ledger, pushed at creation and on
58 // every handover event (see setServingNodeIds()); NODEID_NONE = not attached
59 MacNodeId servingNodeId_ = NODEID_NONE; // the LTE stack's serving node
60 MacNodeId nrServingNodeId_ = NODEID_NONE; // the NR stack's serving node
61
62 // The split policy (TS 38.331 PDCP-Config), pushed by RRC (see setSplitConfig()):
63 // the bearer rides primaryPath_ until the pending data volume reaches splitThreshold_.
64 CellGroup primaryPath_ = MCG;
65 int64_t splitThreshold_ = SPLIT_THRESHOLD_INFINITY;
66
67 // The TX RLC entity of each leg the splitter can weigh, in leg-index order; nullptr
68 // where the leg has no local RLC (a DC master's secondary leg, whose queue is across
69 // X2). Pushed at establishment (see setLegRlc()).
70 std::vector<RlcTxEntityBase *> legRlc_;
71
72 // This splitter's direction-appropriate leg-selection expression (ulLegSelection at a
73 // UE, dlLegSelection at a base station; RRC pushes the matching one, see setLegSelection).
74 // nullptr = none: uplink falls back to the least-occupied leg, downlink to the primary.
75 omnetpp::cDynamicExpression *legSelection_ = nullptr;
76
77 // Evaluation context of the override expression, set before each evaluation
78 int currentPacketOrdinal_ = 0;
79
80 // PDUs this bearer has steered by the override; the "packetOrdinal" variable
81 int packetsSteered_ = 0;
82
83 void initialize(int stage) override;
84 int numInitStages() const override { return inet::NUM_INIT_STAGES; }
85 void handleMessage(omnetpp::cMessage *msg) override;
86
87 // Which leg carries this PDU. A leg whose peer is not attached is not offered to the
88 // policy: with one leg live the choice is made for us, and the policy only decides
89 // between legs that can actually carry the PDU.
90 virtual int selectLeg(const FlowControlInfo *lteInfo);
91 virtual bool isLegLive(int leg, const FlowControlInfo *lteInfo);
92
93 // Evaluate the legSelection expression to a live leg index (throws otherwise).
94 virtual int applyLegSelection(const std::vector<bool>& live);
95
96 // The leg index whose cell group is the primary path.
97 virtual int primaryLeg() const;
98
99 public:
100 // Configuration push from RRC (see BearerManagement): the bearer's split policy --
101 // the primary path cell group and the ul-DataSplitThreshold in bytes.
102 virtual void setSplitConfig(CellGroup primaryPath, int64_t ulDataSplitThreshold);
103
104 // Configuration push from RRC: this bearer's leg-selection expression for this
105 // splitter's direction (RRC passes ulLegSelection to a UE, dlLegSelection to a base
106 // station), as an "expr(...)" source string. Compiled here, so errors throw at
107 // establishment.
108 virtual void setLegSelection(const char *spec);
109
110 // Configuration push from RRC: the TX RLC entity a leg was wired to, so the splitter
111 // can read its pending data volume for the split decision. UE legs and a master's
112 // local leg only; a master's secondary leg has none.
113 virtual void setLegRlc(int leg, RlcTxEntityBase *txEntity);
114
115 // RRC's push of the stacks' attachment (see BearerManagement::pushServingNodeIds()):
116 // the serving node of the UE's LTE and NR stack, current as of handover start.
117 // UEs only; a base station's splitter steers by the Binder.
118 virtual void setServingNodeIds(MacNodeId servingNodeId, MacNodeId nrServingNodeId);
119
120 ~DcPdcpLegSplitter() override;
121};
122
123} // namespace simu5g
124
125#endif
TX-side leg dispatcher for a dual-connectivity split bearer.
Definition DcPdcpLegSplitter.h:33
Abstract base class for all RLC TX entities (UM, TM, AM).
Definition RlcTxEntityBase.h:29
Definition AlertReceiver.h:24
constexpr MacNodeId NODEID_NONE
MAC node ID.
Definition LteTypes.h:54