@@ -115,32 +115,30 @@ void NrSdap::handleUpperPacket(inet::Packet *pkt)
115115 EV_INFO << " SDAP TX: QFI = " << (int )qfi << " extracted from QfiReq\n " ;
116116 }
117117 else if (isUe) {
118- // UE UL: derive QFI from DSCP field of the IP header (DSCP = TOS >> 2)
119- // FlowControlInfo.typeOfService is the raw TOS byte set by Ip2Nic::toStackUe()
120- // Only applicable for IP PDU sessions; non-IP sessions use QfiReq or default QFI.
121- if (pkt->hasTag <FlowControlInfo>()) {
122- auto fci = pkt->getTag <FlowControlInfo>();
123- uint8_t tos = (uint8_t )fci->getTypeOfService ();
124- if (tos > 0 ) {
125- uint8_t dscp = tos >> 2 ;
126- qfi = dscp;
127- EV_INFO << " SDAP TX: QFI = " << (int )qfi << " derived from DSCP=" << (int )dscp << " \n " ;
128- }
129- }
130- // If DSCP gave no QFI, try reflective QoS
131- if (qfi == 0 && reflectiveQosTable != nullptr ) {
118+ // UE UL: try reflective QoS first (3GPP-defined mechanism)
119+ if (reflectiveQosTable != nullptr ) {
132120 uint8_t reflectiveQfi = reflectiveQosTable->lookupUplinkQfi (pkt);
133121 if (reflectiveQfi > 0 ) {
134122 qfi = reflectiveQfi;
135123 qfiFromReflectiveQos = true ;
136124 EV_INFO << " SDAP TX: QFI = " << (int )qfi << " derived from reflective QoS\n " ;
137125 }
138126 }
127+ // Optional non-standard fallback: derive QFI from DSCP field of the IP header
128+ if (qfi == 0 && par (" useDscpAsQfiFallback" ).boolValue ()) {
129+ if (pkt->hasTag <FlowControlInfo>()) {
130+ uint8_t tos = (uint8_t )pkt->getTag <FlowControlInfo>()->getTypeOfService ();
131+ if (tos > 0 ) {
132+ qfi = tos >> 2 ;
133+ EV_INFO << " SDAP TX: QFI = " << (int )qfi << " derived from DSCP (fallback)\n " ;
134+ }
135+ }
136+ }
139137 if (qfi == 0 )
140- EV_WARN << " SDAP TX: No QFI from DSCP or reflective QoS, defaulting QFI to 0 \n " ;
138+ EV_WARN << " SDAP TX: No QFI from reflective QoS or DSCP, using QFI=0 (default DRB) \n " ;
141139 }
142140 else {
143- EV_WARN << " SDAP TX: QfiReq not found on gNB path, defaulting QFI to 0 \n " ;
141+ throw cRuntimeError ( " SDAP TX: QfiReq tag missing on gNB DL path -- GtpUser should always set it " ) ;
144142 }
145143
146144 // Lookup DRB context: nodeId is NODEID_NONE on UE, destUeId on gNB
0 commit comments