Skip to content

Commit 743ac26

Browse files
committed
SDAP: Turn Qfi into strong typedef
1 parent c72e75b commit 743ac26

15 files changed

Lines changed: 71 additions & 49 deletions

File tree

src/simu5g/common/LteCommon.msg

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,19 @@ class DrbId {
8080
@fromValue(DrbId($.intValue()));
8181
};
8282

83+
/// QoS Flow Identifier (6-bit, 0-63 per 3GPP TS 24.501)
84+
class Qfi {
85+
@existingClass; // enum class Qfi : uint8_t;
86+
@descriptor(false);
87+
@primitive;
88+
@castFunction(false);
89+
@fromString(Qfi(string2int64($)));
90+
@toString(int642string(num($)));
91+
@defaultValue(QFI_NONE);
92+
@toValue((omnetpp::intval_t)(num($)));
93+
@fromValue(Qfi($.intValue()));
94+
};
95+
8396
/// Connection Identifier: <MacNodeId,LogicalCid>
8497
class MacCid {
8598
@existingClass; // class MacCid with separate nodeId and lcid fields

src/simu5g/common/LteTypes.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ SIMU5G_STRONG_TYPEDEF(LogicalCid, unsigned short)
7474
/// Data Radio Bearer Identifier (used in PDCP/RLC layers, maps 1:1 to LogicalCid)
7575
SIMU5G_STRONG_TYPEDEF(DrbId, unsigned short)
7676

77+
/// QoS Flow Identifier (6-bit, 0-63 per 3GPP TS 24.501)
78+
SIMU5G_STRONG_TYPEDEF(Qfi, uint8_t)
79+
constexpr Qfi QFI_NONE = Qfi(0);
80+
7781
/// Invalid/uninitialized LCID and DRB ID values
7882
constexpr LogicalCid LCID_NONE = LogicalCid(65535);
7983
constexpr DrbId DRBID_NONE = DrbId(65535);

src/simu5g/common/QfiTag.msg

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
//
1010
import inet.common.INETDefs;
1111
import inet.common.TagBase;
12+
import simu5g.common.LteCommon;
1213

1314
cplusplus {{
1415
using namespace inet;
@@ -27,7 +28,7 @@ namespace simu5g;
2728
// QfiInd is typically used when receiving packets upwards.
2829
//
2930
class QfiTagBase extends inet::TagBase {
30-
uint8_t qfi = 0; // QFI value (range: 0–63), defaults to 0 if not set
31+
Qfi qfi; // QFI value (range: 0–63)
3132
}
3233

3334
class QfiReq extends QfiTagBase

src/simu5g/corenetwork/gtp/GtpUser.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,9 @@ void GtpUser::handleFromTrafficFlowFilter(Packet *datagram)
146146

147147
auto tftInfo = datagram->removeTag<TftControlInfo>();
148148
TrafficFlowTemplateId flowId = tftInfo->getTft();
149-
uint8_t qfi = tftInfo->getQfi();
149+
Qfi qfi = tftInfo->getQfi();
150150

151-
EV << "GtpUser::handleFromTrafficFlowFilter - Received a tftMessage with flowId[" << flowId << "] qfi[" << (int)qfi << "]" << endl;
151+
EV << "GtpUser::handleFromTrafficFlowFilter - Received a tftMessage with flowId[" << flowId << "] qfi[" << qfi << "]" << endl;
152152

153153
if (flowId == TFT_REMOVED_DESTINATION) {
154154
// the destination has been removed from the simulation. Delete datagram
@@ -235,7 +235,7 @@ void GtpUser::handleFromUdp(Packet *pkt)
235235
originalPacket->addTagIfAbsent<PacketProtocolTag>()->setProtocol(&Protocol::ipv4);
236236

237237
// Restore QFI from GTP-U header so SDAP can use it for QFI-to-DRB mapping
238-
if (gtpUserMsg->getQfi() > 0)
238+
if (gtpUserMsg->getQfi() != QFI_NONE)
239239
originalPacket->addTagIfAbsent<QfiReq>()->setQfi(gtpUserMsg->getQfi());
240240
// remove any pending socket indications
241241
auto sockInd = pkt->removeTagIfPresent<SocketInd>();

src/simu5g/corenetwork/gtp/GtpUserMsg.msg

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111

1212
import inet.common.INETDefs;
1313
import inet.common.packet.chunk.Chunk;
14+
import simu5g.common.LteCommon;
1415

1516
namespace simu5g;
1617

1718
class GtpUserMsg extends inet::FieldsChunk {
1819
unsigned int teid;
19-
uint8_t qfi = 0; // QoS Flow Identifier (carried in PDU Session Container in real GTP-U)
20+
Qfi qfi; // QoS Flow Identifier (carried in PDU Session Container in real GTP-U)
2021
chunkLength = inet::B(1); // TODO: size 0
2122
}

src/simu5g/corenetwork/trafficFlowFilter/TftControlInfo.msg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ namespace simu5g;
1818
class TftControlInfo extends inet::TagBase
1919
{
2020
unsigned int tft;
21-
uint8_t qfi = 0; // QFI derived from IP DSCP (simplified PDR matching)
21+
Qfi qfi; // QFI derived from IP DSCP (simplified PDR matching)
2222
};

src/simu5g/corenetwork/trafficFlowFilter/TrafficFlowFilter.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,10 @@ void TrafficFlowFilter::handleMessage(cMessage *msg)
135135

136136
// Simplified QFI derivation: use IP DSCP as QFI directly.
137137
// In a real 5G UPF, this would be done via PDR/QER rules.
138-
tftInfo->setQfi(ipv4Header->getDscp());
138+
Qfi qfi = Qfi(ipv4Header->getDscp());
139+
tftInfo->setQfi(qfi);
139140

140-
EV << "TrafficFlowFilter::handleMessage - setting tft=" << tftId << " qfi=" << (int)ipv4Header->getDscp() << endl;
141+
EV << "TrafficFlowFilter::handleMessage - setting tft=" << tftId << " qfi=" << qfi << endl;
141142

142143
// send the datagram to the GTP-U module
143144
send(pkt, "gtpUserGateOut");

src/simu5g/stack/sdap/NrSdap.cc

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ bool NrSdap::requiresSdapHeader(const DrbConfig *drb)
5959
return drb->isDefault || drb->qfiList.size() > 1;
6060
}
6161

62-
bool NrSdap::shouldEnableReflectiveQos(int qfi)
62+
bool NrSdap::shouldEnableReflectiveQos(Qfi qfi)
6363
{
6464
return par("useReflectiveQos").boolValue(); // for now -- should come from RRC config
6565
}
@@ -106,35 +106,35 @@ void NrSdap::handleMessage(cMessage *msg)
106106

107107
void NrSdap::handleUpperPacket(inet::Packet *pkt)
108108
{
109-
uint8_t qfi = 0;
109+
Qfi qfi = QFI_NONE;
110110
bool qfiFromReflectiveQos = false;
111111

112112
// Extract QFI from QfiReq tag if present (set by GtpUser from GTP-U header, or by app directly)
113113
if (pkt->hasTag<QfiReq>()) {
114114
qfi = pkt->getTag<QfiReq>()->getQfi();
115-
EV_INFO << "SDAP TX: QFI = " << (int)qfi << " extracted from QfiReq\n";
115+
EV_INFO << "SDAP TX: QFI = " << qfi << " extracted from QfiReq\n";
116116
}
117117
else if (isUe) {
118118
// UE UL: try reflective QoS first (3GPP-defined mechanism)
119119
if (reflectiveQosTable != nullptr) {
120-
uint8_t reflectiveQfi = reflectiveQosTable->lookupUplinkQfi(pkt);
121-
if (reflectiveQfi > 0) {
120+
Qfi reflectiveQfi = reflectiveQosTable->lookupUplinkQfi(pkt);
121+
if (reflectiveQfi != QFI_NONE) {
122122
qfi = reflectiveQfi;
123123
qfiFromReflectiveQos = true;
124-
EV_INFO << "SDAP TX: QFI = " << (int)qfi << " derived from reflective QoS\n";
124+
EV_INFO << "SDAP TX: QFI = " << qfi << " derived from reflective QoS\n";
125125
}
126126
}
127127
// Optional non-standard fallback: derive QFI from DSCP field of the IP header
128-
if (qfi == 0 && par("useDscpAsQfiFallback").boolValue()) {
128+
if (qfi == QFI_NONE && par("useDscpAsQfiFallback").boolValue()) {
129129
if (pkt->hasTag<FlowControlInfo>()) {
130130
uint8_t tos = (uint8_t)pkt->getTag<FlowControlInfo>()->getTypeOfService();
131131
if (tos > 0) {
132-
qfi = tos >> 2;
133-
EV_INFO << "SDAP TX: QFI = " << (int)qfi << " derived from DSCP (fallback)\n";
132+
qfi = Qfi(tos >> 2);
133+
EV_INFO << "SDAP TX: QFI = " << qfi << " derived from DSCP (fallback)\n";
134134
}
135135
}
136136
}
137-
if (qfi == 0)
137+
if (qfi == QFI_NONE)
138138
EV_WARN << "SDAP TX: No QFI from reflective QoS or DSCP, using QFI=0 (default DRB)\n";
139139
}
140140
else {
@@ -153,13 +153,13 @@ void NrSdap::handleUpperPacket(inet::Packet *pkt)
153153
if (!drb) {
154154
drb = drbTable_.getDefaultDrb(nodeId);
155155
if (drb)
156-
EV_WARN << "SDAP TX: No DRB mapping for nodeId=" << nodeId << " QFI=" << (int)qfi
156+
EV_WARN << "SDAP TX: No DRB mapping for nodeId=" << nodeId << " QFI=" << qfi
157157
<< ", falling back to default DRB " << drb->drbId << "\n";
158158
}
159159
if (!drb)
160160
throw cRuntimeError("SDAP TX: No DRB available for nodeId=%d", (int)num(nodeId));
161161

162-
EV_INFO << "SDAP TX: Selected DRB=" << drb->drbId << " for QFI=" << (int)qfi << "\n";
162+
EV_INFO << "SDAP TX: Selected DRB=" << drb->drbId << " for QFI=" << qfi << "\n";
163163

164164
// Check if SDAP header is required for this DRB
165165
if (requiresSdapHeader(drb)) {
@@ -172,7 +172,7 @@ void NrSdap::handleUpperPacket(inet::Packet *pkt)
172172
sdapHeader->setReflectiveQoS(enableReflectiveQos);
173173

174174
pkt->insertAtFront(sdapHeader);
175-
EV_INFO << "SDAP TX: Inserted SDAP header with QFI = " << (int)qfi
175+
EV_INFO << "SDAP TX: Inserted SDAP header with QFI = " << qfi
176176
<< ", reflectiveQoS = " << (enableReflectiveQos ? "true" : "false") << "\n";
177177
}
178178
else {
@@ -207,7 +207,7 @@ void NrSdap::handleLowerPacket(inet::Packet *pkt)
207207

208208
EV_INFO << "SDAP RX: Received packet from DRB " << drbId << ": " << pkt->peekAtFront() << "\n";
209209

210-
int qfi = 0;
210+
Qfi qfi = QFI_NONE;
211211

212212
// Check if packet has SDAP header (should be at the front according to 3GPP TS 37.324)
213213
if (requiresSdapHeader(drb)) {
@@ -218,14 +218,14 @@ void NrSdap::handleLowerPacket(inet::Packet *pkt)
218218
EV_INFO << "SDAP RX: Extracted SDAP header with QFI = " << qfi << "\n";
219219

220220
// Validate QFI range (0-63 according to 3GPP)
221-
if (qfi > 63) {
221+
if (num(qfi) > 63) {
222222
EV_WARN << "SDAP RX: Invalid QFI value " << qfi << " (should be 0-63)\n";
223-
qfi = 0; // Use default QFI
223+
qfi = QFI_NONE;
224224
}
225225

226226
// Handle reflective QoS if UE and enabled
227227
if (sdapHeader->getReflectiveQoS()) {
228-
EV_INFO << "SDAP RX: Reflective QoS enabled for QFI " << (int)qfi << "\n";
228+
EV_INFO << "SDAP RX: Reflective QoS enabled for QFI " << qfi << "\n";
229229
if (isUe && reflectiveQosTable != nullptr) {
230230
reflectiveQosTable->handleDownlinkFlow(pkt, qfi);
231231
}
@@ -243,7 +243,7 @@ void NrSdap::handleLowerPacket(inet::Packet *pkt)
243243

244244
// Validate QFI ↔ DRB consistency
245245
if (drb) {
246-
if (!contains(drb->qfiList, (int)qfi))
246+
if (!contains(drb->qfiList, qfi))
247247
EV_WARN << "SDAP RX: DRB/QFI mismatch! Received on DRB=" << drbId << ", QFI=" << qfi << " not in qfiList\n";
248248
}
249249

@@ -255,7 +255,7 @@ void NrSdap::handleLowerPacket(inet::Packet *pkt)
255255
const inet::Protocol *upperProto = getUpperProtocol(drb);
256256
pkt->addTagIfAbsent<PacketProtocolTag>()->setProtocol(upperProto);
257257

258-
EV_INFO << "SDAP RX: Forwarding packet with QFI " << qfi << " to upper layer (protocol: " << upperProto->getName() << ")\n";
258+
EV_INFO << "SDAP RX: Forwarding packet with QFI=" << qfi << " to upper layer (protocol: " << upperProto->getName() << ")\n";
259259
send(pkt, "upperLayerOut");
260260
}
261261

src/simu5g/stack/sdap/NrSdap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class NrSdap : public cSimpleModule
5454

5555
protected:
5656
bool requiresSdapHeader(const DrbConfig *drb);
57-
bool shouldEnableReflectiveQos(int qfi);
57+
bool shouldEnableReflectiveQos(Qfi qfi);
5858
const inet::Protocol *getUpperProtocol(const DrbConfig *ctx);
5959
virtual void initialize() override;
6060
virtual void handleMessage(cMessage *msg) override;

src/simu5g/stack/sdap/common/DrbConfig.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ struct DrbConfig {
2222
DrbId drbId = DRBID_NONE; // DRB identifier (= nrPdcp[]/nrRlc[] array index)
2323
MacNodeId ueNodeId = NODEID_NONE; // NODEID_NONE = "self" (UE side); numeric MacNodeId on gNB
2424
bool isDefault = false; // true if this is the default DRB for this UE
25-
std::vector<int> qfiList; // QFIs mapped to this DRB
25+
std::vector<Qfi> qfiList; // QFIs mapped to this DRB
2626
LteRlcType rlcType = UM; // RLC mode for this DRB (AM, UM, TM)
2727
PduSessionType pduSessionType = IP_V4; // PDU session type (3GPP TS 23.501)
2828
std::string upperProtocol; // INET protocol name for upper layer dispatch (empty = derive from pduSessionType)
@@ -42,7 +42,7 @@ inline std::ostream& operator<<(std::ostream& os, const DrbConfig& ctx) {
4242
return os;
4343
}
4444

45-
inline std::ostream& operator<<(std::ostream& os, const std::pair<MacNodeId,int>& p) {
45+
inline std::ostream& operator<<(std::ostream& os, const std::pair<MacNodeId,Qfi>& p) {
4646
os << "(" << p.first << "," << p.second << ")";
4747
return os;
4848
}

0 commit comments

Comments
 (0)