@@ -112,7 +112,24 @@ func sendServiceAccept(
112112
113113// TS 24501 5.6.1
114114func handleServiceRequest (ctx context.Context , amfInstance * amf.AMF , ue * amf.AmfUe , msg * nasMessage.ServiceRequest ) error {
115- if ue .GetState () != amf .Deregistered && ue .GetState () != amf .Registered {
115+ // TS 24.501 5.6.1.1: reject service request from deregistered UE
116+ if ue .GetState () == amf .Deregistered {
117+ err := message .SendServiceReject (ctx , ue .RanUe (), nasMessage .Cause5GMMUEIdentityCannotBeDerivedByTheNetwork )
118+ if err != nil {
119+ return fmt .Errorf ("error sending service reject: %v" , err )
120+ }
121+
122+ ue .RanUe ().ReleaseAction = amf .UeContextN2NormalRelease
123+
124+ err = ue .RanUe ().SendUEContextReleaseCommand (ctx , ngapType .CausePresentNas , ngapType .CauseNasPresentNormalRelease )
125+ if err != nil {
126+ return fmt .Errorf ("error sending ue context release command: %v" , err )
127+ }
128+
129+ return nil
130+ }
131+
132+ if ue .GetState () != amf .Registered {
116133 return fmt .Errorf ("state mismatch: receive Service Request message in state %s" , ue .GetState ())
117134 }
118135
@@ -165,8 +182,8 @@ func handleServiceRequest(ctx context.Context, amfInstance *amf.AMF, ue *amf.Amf
165182 ue .RetransmissionOfInitialNASMsg = ue .MacFailed
166183 }
167184
168- // Service Reject if the SecurityContext is invalid or the UE is Deregistered
169- if ! ue .SecurityContextIsValid () || ue . GetState () == amf . Deregistered {
185+ // Service Reject if the SecurityContext is invalid
186+ if ! ue .SecurityContextIsValid () {
170187 ue .Log .Warn ("No security context" , logger .SUPI (ue .Supi .String ()))
171188 ue .SecurityContextAvailable = false
172189
@@ -221,12 +238,21 @@ func handleServiceRequest(ctx context.Context, amfInstance *amf.AMF, ue *amf.Amf
221238 }
222239 }
223240
241+ // Copy SmContextList under lock for safe concurrent iteration.
242+ ue .Mutex .Lock ()
243+
244+ smContextSnapshot := make (map [uint8 ]* amf.SmContext , len (ue .SmContextList ))
245+ for id , sc := range ue .SmContextList {
246+ smContextSnapshot [id ] = sc
247+ }
248+ ue .Mutex .Unlock ()
249+
224250 // If the UE has uplink data pending for some PDU sessions, we need to activate them
225251 if msg .UplinkDataStatus != nil {
226252 uplinkDataPsi := nasConvert .PSIToBooleanArray (msg .UplinkDataStatus .Buffer )
227253 reactivationResult = new ([16 ]bool )
228254
229- for pduSessionID , smContext := range ue . SmContextList {
255+ for pduSessionID , smContext := range smContextSnapshot {
230256 if int (pduSessionID ) >= len (uplinkDataPsi ) {
231257 ue .Log .Warn ("Ignoring out-of-range PDU session ID in UplinkDataStatus processing" , zap .Uint8 ("pduSessionID" , pduSessionID ))
232258 continue
@@ -255,7 +281,7 @@ func handleServiceRequest(ctx context.Context, amfInstance *amf.AMF, ue *amf.Amf
255281 acceptPduSessionPsi = new ([16 ]bool )
256282
257283 psiArray := nasConvert .PSIToBooleanArray (msg .PDUSessionStatus .Buffer )
258- for pduSessionID , smContext := range ue . SmContextList {
284+ for pduSessionID , smContext := range smContextSnapshot {
259285 if int (pduSessionID ) >= len (psiArray ) {
260286 ue .Log .Warn ("Ignoring out-of-range PDU session ID in PDUSessionStatus processing" , zap .Uint8 ("pduSessionID" , pduSessionID ))
261287 continue
0 commit comments