@@ -33,10 +33,10 @@ void NrSdap::initialize()
3333 // Load QFI-to-DRB mapping from drbConfig parameter
3434 const cValueArray *arr = check_and_cast_nullable<const cValueArray *>(par (" drbConfig" ).objectValue ());
3535 if (arr && arr->size () > 0 ) {
36- qfiContextManager_ .loadFromJson (arr);
37- EV << " NrSdap: Loaded " << qfiContextManager_ .getDrbMap ().size () << " DRB entries from drbConfig" << endl;
38- for (const auto & [drb , ctx] : qfiContextManager_ .getDrbMap ())
39- EV << " DRB " << drb << " : " << ctx << endl;
36+ drbTable_ .loadFromJson (arr);
37+ EV << " NrSdap: Loaded " << drbTable_ .getDrbMap ().size () << " DRB entries from drbConfig" << endl;
38+ for (const auto & [key , ctx] : drbTable_ .getDrbMap ())
39+ EV << " " << key << " : " << ctx << endl;
4040 }
4141
4242 // Get pointer to reflective QoS table
@@ -49,7 +49,7 @@ void NrSdap::initialize()
4949 throw cRuntimeError (" Only UE may use a reflective QoS table" );
5050}
5151
52- bool NrSdap::requiresSdapHeader (int drbIndex )
52+ bool NrSdap::requiresSdapHeader (const DrbConfig *drb )
5353{
5454 return par (" addSdapHeader" ).boolValue (); // for now -- should come from RRC config
5555}
@@ -59,7 +59,7 @@ bool NrSdap::shouldEnableReflectiveQos(int qfi)
5959 return par (" useReflectiveQos" ).boolValue (); // for now -- should come from RRC config
6060}
6161
62- const inet::Protocol *NrSdap::getUpperProtocol (const DrbContext *ctx)
62+ const inet::Protocol *NrSdap::getUpperProtocol (const DrbConfig *ctx)
6363{
6464 // If an explicit upperProtocol is configured on this DRB, use it
6565 if (ctx && !ctx->upperProtocol .empty ()) {
@@ -138,44 +138,28 @@ void NrSdap::handleUpperPacket(inet::Packet *pkt)
138138 EV_WARN << " SDAP TX: QfiReq not found on gNB path, defaulting QFI to 0\n " ;
139139 }
140140
141- // Lookup DRB index
142- int drbIndex = 0 ;
143-
144- if (isUe) {
145- // UE side: simple QFI -> drbIndex lookup
146- int idx = qfiContextManager_.getDrbIndexForQfi (qfi);
147- if (idx >= 0 )
148- drbIndex = idx;
149- else
150- EV_WARN << " SDAP TX: No DRB mapping for QFI=" << (int )qfi << " on UE, using DRB 0\n " ;
151- } else {
152- // gNB side: need dest UE nodeId + QFI -> drbIndex
153- MacNodeId destUeId = pkt->getTag <FlowControlInfo>()->getDestId ();
154- if (destUeId == NODEID_NONE)
155- EV_WARN << " SDAP TX: destId not set in FlowControlInfo, using DRB 0\n " ;
156- else {
157- int idx = qfiContextManager_.getDrbIndex (destUeId, qfi);
158- if (idx >= 0 )
159- drbIndex = idx;
160- else {
161- // Fallback: use first DRB configured for this UE
162- int fallback = qfiContextManager_.getFirstDrbForUe (destUeId);
163- if (fallback >= 0 ) {
164- drbIndex = fallback;
165- EV_WARN << " SDAP TX: No DRB mapping for ueNodeId=" << destUeId << " QFI=" << (int )qfi
166- << " , falling back to first DRB " << drbIndex << " for this UE\n " ;
167- } else {
168- EV_WARN << " SDAP TX: No DRB mapping for ueNodeId=" << destUeId << " QFI=" << (int )qfi
169- << " , no DRBs configured for this UE, using DRB 0\n " ;
170- }
171- }
172- }
141+ // Lookup DRB context: nodeId is NODEID_NONE on UE, destUeId on gNB
142+ MacNodeId nodeId = NODEID_NONE;
143+ if (!isUe) {
144+ nodeId = pkt->getTag <FlowControlInfo>()->getDestId ();
145+ if (nodeId == NODEID_NONE)
146+ EV_WARN << " SDAP TX: destId not set in FlowControlInfo\n " ;
147+ }
148+
149+ const DrbConfig *drb = drbTable_.getDrbForQfi (nodeId, qfi);
150+ if (!drb) {
151+ drb = drbTable_.getDefaultDrb (nodeId);
152+ if (drb)
153+ EV_WARN << " SDAP TX: No DRB mapping for nodeId=" << nodeId << " QFI=" << (int )qfi
154+ << " , falling back to default DRB " << drb->drbId << " \n " ;
173155 }
156+ if (!drb)
157+ throw cRuntimeError (" SDAP TX: No DRB available for nodeId=%d" , (int )num (nodeId));
174158
175- EV_INFO << " SDAP TX: Selected DRB=" << drbIndex << " for QFI=" << (int )qfi << " \n " ;
159+ EV_INFO << " SDAP TX: Selected DRB=" << drb-> drbId << " for QFI=" << (int )qfi << " \n " ;
176160
177161 // Check if SDAP header is required for this DRB
178- if (requiresSdapHeader (drbIndex )) {
162+ if (requiresSdapHeader (drb )) {
179163 // Build SDAP header according to 3GPP TS 37.324
180164 auto sdapHeader = makeShared<NrSdapHeader>();
181165 sdapHeader->setQfi (qfi);
@@ -189,38 +173,38 @@ void NrSdap::handleUpperPacket(inet::Packet *pkt)
189173 << " , reflectiveQoS = " << (enableReflectiveQos ? " true" : " false" ) << " \n " ;
190174 }
191175 else {
192- EV_INFO << " SDAP TX: No SDAP header required for DRB " << drbIndex << " \n " ;
176+ EV_INFO << " SDAP TX: No SDAP header required for DRB " << drb-> drbId << " \n " ;
193177 }
194178
195179 // Set DRB ID and RLC type on FlowControlInfo for PDCP/RLC entity creation and routing
196180 auto lteInfo = pkt->getTagForUpdate <FlowControlInfo>();
197- lteInfo->setDrbId (DrbId (drbIndex));
198- const DrbContext *ctx = qfiContextManager_.getDrbContext (drbIndex);
199- if (ctx)
200- lteInfo->setRlcType (ctx->rlcType );
181+ lteInfo->setDrbId (drb->drbId );
182+ lteInfo->setRlcType (drb->rlcType );
201183
202184 // Establish connection if not yet done for this (drbId, destId) pair
203- if (establishedConnections_.insert ({DrbId (drbIndex) , lteInfo->getDestId ()}).second )
185+ if (establishedConnections_.insert ({drb-> drbId , lteInfo->getDestId ()}).second )
204186 binder_->establishUnidirectionalDataConnection (lteInfo.get ());
205187
206188 // Set protocol tag for outgoing frame to PDCP layer
207189 pkt->addTagIfAbsent <PacketProtocolTag>()->setProtocol (&LteProtocol::sdap);
208190
209- EV_INFO << " SDAP TX: Forwarding to DRB " << drbIndex << " \n " ;
191+ EV_INFO << " SDAP TX: Forwarding to DRB " << drb-> drbId << " \n " ;
210192 send (pkt, " pdcpOut" );
211193}
212194
213195void NrSdap::handleLowerPacket (inet::Packet *pkt)
214196{
215197 auto lteInfo = pkt->findTag <FlowControlInfo>();
216- int drbIndex = lteInfo ? num (lteInfo->getDrbId ()) : -1 ;
198+ DrbId drbId = lteInfo ? lteInfo->getDrbId () : DRBID_NONE;
199+ MacNodeId ueId = (!isUe && lteInfo) ? lteInfo->getSourceId () : NODEID_NONE;
200+ const DrbConfig *drb = (drbId != DRBID_NONE) ? drbTable_.getDrb (DrbKey (ueId, drbId)) : nullptr ;
217201
218- EV_INFO << " SDAP RX: Received packet from DRB " << drbIndex << " : " << pkt->peekAtFront () << " \n " ;
202+ EV_INFO << " SDAP RX: Received packet from DRB " << drbId << " : " << pkt->peekAtFront () << " \n " ;
219203
220204 int qfi = 0 ;
221205
222206 // Check if packet has SDAP header (should be at the front according to 3GPP TS 37.324)
223- if (requiresSdapHeader (drbIndex )) {
207+ if (requiresSdapHeader (drb )) {
224208 // Extract SDAP header from the front of the packet
225209 auto sdapHeader = pkt->removeAtFront <NrSdapHeader>();
226210 qfi = sdapHeader->getQfi ();
@@ -242,30 +226,27 @@ void NrSdap::handleLowerPacket(inet::Packet *pkt)
242226 }
243227 }
244228 else {
245- EV_INFO << " SDAP RX: No SDAP header expected for DRB " << drbIndex << " \n " ;
229+ EV_INFO << " SDAP RX: No SDAP header expected for DRB " << drbId << " \n " ;
246230
247231 // For DRBs without SDAP header, derive QFI from DRB context (use first QFI in the list)
248- const DrbContext* ctx = qfiContextManager_.getDrbContext (drbIndex);
249- if (ctx && !ctx->qfiList .empty ()) {
250- qfi = ctx->qfiList [0 ];
232+ if (drb && !drb->qfiList .empty ()) {
233+ qfi = drb->qfiList [0 ];
251234 EV_INFO << " SDAP RX: Using QFI " << qfi << " from DRB context\n " ;
252235 }
253236 }
254237
255238 // Validate QFI ↔ DRB consistency
256- const DrbContext* ctxValidate = qfiContextManager_.getDrbContext (drbIndex);
257- if (ctxValidate) {
258- if (!contains (ctxValidate->qfiList , (int )qfi))
259- EV_WARN << " SDAP RX: DRB/QFI mismatch! Received on DRB=" << drbIndex << " , QFI=" << qfi << " not in qfiList\n " ;
239+ if (drb) {
240+ if (!contains (drb->qfiList , (int )qfi))
241+ EV_WARN << " SDAP RX: DRB/QFI mismatch! Received on DRB=" << drbId << " , QFI=" << qfi << " not in qfiList\n " ;
260242 }
261243
262244 // Add QoS indication tag for upper layers
263245 auto qosIndTag = pkt->addTagIfAbsent <QfiInd>();
264246 qosIndTag->setQfi (qfi);
265247
266248 // Set protocol tag for upper layer based on PDU session type
267- const DrbContext* ctxProto = qfiContextManager_.getDrbContext (drbIndex);
268- const inet::Protocol *upperProto = getUpperProtocol (ctxProto);
249+ const inet::Protocol *upperProto = getUpperProtocol (drb);
269250 pkt->addTagIfAbsent <PacketProtocolTag>()->setProtocol (upperProto);
270251
271252 EV_INFO << " SDAP RX: Forwarding packet with QFI " << qfi << " to upper layer (protocol: " << upperProto->getName () << " )\n " ;
0 commit comments