Skip to content

Commit

Permalink
UE MM state management improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
aligungr committed Aug 31, 2020
1 parent 998da60 commit fe4b5f4
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public IEGprsTimer2(Octet value) {
this.value = value;
}

public IEGprsTimer2(int value) {
this(new Octet(value));
}

public boolean hasValue() {
return value.intValue() != 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@

public class UserEquipment {

public static boolean AUTO = false;

public static void sendNas(UeSimContext ctx, NasMessage message) {
Debugging.assertThread(ctx);

Expand Down Expand Up @@ -93,6 +95,7 @@ public static void receiveNas(UeSimContext ctx, NasMessage message) {

public static void cycle(UeSimContext ctx) {
ctx.ueTimers.performTick(ctx);
MobilityManagement.cycle(ctx);

var event = ctx.popEvent();
if (event instanceof UeCommandEvent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@
package tr.havelsan.ueransim.app.api.ue.mm;

import tr.havelsan.ueransim.app.core.UeSimContext;
import tr.havelsan.ueransim.app.enums.EMmState;
import tr.havelsan.ueransim.app.enums.EMmSubState;
import tr.havelsan.ueransim.app.enums.ERmState;
import tr.havelsan.ueransim.core.exceptions.NotImplementedException;
import tr.havelsan.ueransim.nas.eap.Eap;
import tr.havelsan.ueransim.nas.impl.enums.*;
import tr.havelsan.ueransim.nas.impl.ies.*;
Expand All @@ -44,6 +47,8 @@ public static void sendRegistration(UeSimContext ctx, ERegistrationType registra

Logging.funcIn("Starting: Registration procedure (%s)", registrationType);

MobilityManagement.switchState(ctx, EMmState.MM_REGISTERED_INITIATED, EMmSubState.MM_REGISTERED_INITIATED__NA);

var ngKsi = new IENasKeySetIdentifier(ETypeOfSecurityContext.NATIVE_SECURITY_CONTEXT, IENasKeySetIdentifier.NOT_AVAILABLE_OR_RESERVED);
if (ctx.currentNsCtx != null && ctx.currentNsCtx.ngKsi != null) {
ngKsi = ctx.currentNsCtx.ngKsi;
Expand Down Expand Up @@ -122,8 +127,8 @@ public static void receiveRegistrationAccept(UeSimContext ctx, RegistrationAccep
MobilityManagement.sendMm(ctx, new RegistrationComplete());
}

Logging.info(Tag.STATE, "UE enters RM_REGISTERED state");
ctx.mmCtx.rmState = ERmState.RM_REGISTERED;
MobilityManagement.switchState(ctx, ERmState.RM_REGISTERED);
MobilityManagement.switchState(ctx, EMmState.MM_REGISTERED, EMmSubState.MM_REGISTERED__NORMAL_SERVICE);

Logging.success(Tag.PROCEDURE_RESULT, "Registration is successful");
Logging.funcOut();
Expand Down Expand Up @@ -154,67 +159,89 @@ public static void receiveRegistrationReject(UeSimContext ctx, RegistrationRejec
ctx.mmCtx.taiList = null;
ctx.currentNsCtx = null;
ctx.nonCurrentNsCtx = null;
MobilityManagement.switchState(ctx, EMmState.MM_DEREGISTERED, EMmSubState.MM_DEREGISTERED__PLMN_SEARCH);
} else if (cause.equals(EMmCause.FIVEG_SERVICES_NOT_ALLOWED)) {
ctx.mmCtx.storedGuti = null;
ctx.mmCtx.lastVisitedRegisteredTai = null;
ctx.mmCtx.taiList = null;
ctx.currentNsCtx = null;
ctx.nonCurrentNsCtx = null;
MobilityManagement.switchState(ctx, EMmState.MM_DEREGISTERED, EMmSubState.MM_DEREGISTERED__PLMN_SEARCH);
} else if (cause.equals(EMmCause.PLMN_NOT_ALLOWED)) {
ctx.mmCtx.storedGuti = null;
ctx.mmCtx.lastVisitedRegisteredTai = null;
ctx.mmCtx.taiList = null;
ctx.currentNsCtx = null;
ctx.nonCurrentNsCtx = null;
MobilityManagement.switchState(ctx, EMmState.MM_DEREGISTERED, EMmSubState.MM_DEREGISTERED__PLMN_SEARCH);
} else if (cause.equals(EMmCause.TA_NOT_ALLOWED)) {
ctx.mmCtx.storedGuti = null;
ctx.mmCtx.lastVisitedRegisteredTai = null;
ctx.mmCtx.taiList = null;
ctx.currentNsCtx = null;
ctx.nonCurrentNsCtx = null;
MobilityManagement.switchState(ctx, EMmState.MM_DEREGISTERED, EMmSubState.MM_DEREGISTERED__LIMITED_SERVICE);
} else if (cause.equals(EMmCause.ROAMING_NOT_ALLOWED_IN_TA)) {
ctx.mmCtx.storedGuti = null;
ctx.mmCtx.lastVisitedRegisteredTai = null;
ctx.mmCtx.taiList = null;
ctx.currentNsCtx = null;
ctx.nonCurrentNsCtx = null;
MobilityManagement.switchState(ctx, EMmState.MM_DEREGISTERED, EMmSubState.MM_DEREGISTERED__LIMITED_SERVICE);
} else if (cause.equals(EMmCause.NO_SUITIBLE_CELLS_IN_TA)) {
ctx.mmCtx.storedGuti = null;
ctx.mmCtx.lastVisitedRegisteredTai = null;
ctx.mmCtx.taiList = null;
ctx.currentNsCtx = null;
ctx.nonCurrentNsCtx = null;
MobilityManagement.switchState(ctx, EMmState.MM_DEREGISTERED, EMmSubState.MM_DEREGISTERED__LIMITED_SERVICE);
} else if (cause.equals(EMmCause.CONGESTION)) {
if (message.t3346value != null && message.t3346value.hasValue()) {

MobilityManagement.switchState(ctx, EMmState.MM_DEREGISTERED, EMmSubState.MM_DEREGISTERED__ATTEMPTING_REGISTRATION);
ctx.ueTimers.t3346.stop();

if (message.securityHeaderType.isIntegrityProtected()) {
ctx.ueTimers.t3346.start(message.t3346value);
} else {
// todo
ctx.ueTimers.t3346.start(new IEGprsTimer2(5));
}

} else {
// todo
// todo abnormal case see 5.5.1.2.7.
throw new NotImplementedException("");
}
} else if (cause.equals(EMmCause.N1_MODE_NOT_ALLOWED)) {
// todo
ctx.mmCtx.storedGuti = null;
ctx.mmCtx.lastVisitedRegisteredTai = null;
ctx.mmCtx.taiList = null;
ctx.currentNsCtx = null;
ctx.nonCurrentNsCtx = null;
MobilityManagement.switchState(ctx, EMmState.MM_NULL, EMmSubState.MM_NULL__NA);
} else if (cause.equals(EMmCause.NON_3GPP_ACCESS_TO_CN_NOT_ALLOWED)) {
// todo
throw new NotImplementedException("");
} else if (cause.equals(EMmCause.SERVING_NETWORK_NOT_AUTHORIZED)) {
// todo
throw new NotImplementedException("");
} else {
// todo
throw new NotImplementedException("");
}
} else if (regType.equals(ERegistrationType.EMERGENCY_REGISTRATION)) {
if (cause.equals(EMmCause.PEI_NOT_ACCEPTED)) {
// todo
throw new NotImplementedException("");
} else {
// todo: abnormal case
throw new NotImplementedException("");
}
} else {
// todo
throw new NotImplementedException("");
}

Logging.info(Tag.STATE, "UE enters RM_DEREGISTERED state");
ctx.mmCtx.rmState = ERmState.RM_DEREGISTERED;
MobilityManagement.switchState(ctx, ERmState.RM_DEREGISTERED);

Logging.funcOut();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@
import tr.havelsan.ueransim.app.api.nas.NasTimer;
import tr.havelsan.ueransim.app.api.ue.UserEquipment;
import tr.havelsan.ueransim.app.core.UeSimContext;
import tr.havelsan.ueransim.app.enums.EMmState;
import tr.havelsan.ueransim.app.enums.EMmSubState;
import tr.havelsan.ueransim.app.enums.ERmState;
import tr.havelsan.ueransim.app.testing.TestCommand;
import tr.havelsan.ueransim.app.testing.TestCommand_Deregistration;
import tr.havelsan.ueransim.app.testing.TestCommand_InitialRegistration;
import tr.havelsan.ueransim.app.testing.TestCommand_PeriodicRegistration;
import tr.havelsan.ueransim.app.utils.Debugging;
import tr.havelsan.ueransim.core.exceptions.NotImplementedException;
import tr.havelsan.ueransim.nas.core.messages.PlainMmMessage;
import tr.havelsan.ueransim.nas.impl.enums.ERegistrationType;
import tr.havelsan.ueransim.nas.impl.ies.IEDeRegistrationType;
Expand Down Expand Up @@ -85,7 +89,15 @@ public static void receiveTimerExpire(UeSimContext ctx, NasTimer timer) {
Debugging.assertThread(ctx);

if (timer.timerCode == 3512) {
MmRegistration.sendRegistration(ctx, ERegistrationType.PERIODIC_REGISTRATION_UPDATING);
if (UserEquipment.AUTO && ctx.mmCtx.mmState == EMmState.MM_REGISTERED) {
MmRegistration.sendRegistration(ctx, ERegistrationType.PERIODIC_REGISTRATION_UPDATING);
}
}

if (timer.timerCode == 3346) {
if (UserEquipment.AUTO && ctx.mmCtx.mmSubState == EMmSubState.MM_DEREGISTERED__NORMAL_SERVICE) {
MmRegistration.sendRegistration(ctx, ERegistrationType.INITIAL_REGISTRATION);
}
}
}

Expand All @@ -106,4 +118,53 @@ public static boolean executeCommand(UeSimContext ctx, TestCommand cmd) {

return false;
}

public static void switchState(UeSimContext ctx, EMmState state, EMmSubState subState) {
Debugging.assertThread(ctx);

ctx.mmCtx.mmState = state;
ctx.mmCtx.mmSubState = subState;

Logging.info(Tag.STATE, "UE switches to state: %s/%s", state, subState);
}

public static void switchState(UeSimContext ctx, ERmState state) {
Debugging.assertThread(ctx);

ctx.mmCtx.rmState = state;
Logging.info(Tag.STATE, "UE switches to state: %s", state);
}

public static void cycle(UeSimContext ctx) {
Debugging.assertThread(ctx);

if (ctx.mmCtx.mmState == EMmState.MM_NULL) {
switchState(ctx, EMmState.MM_DEREGISTERED, EMmSubState.MM_DEREGISTERED__PLMN_SEARCH);
return;
}

if (ctx.mmCtx.mmSubState == EMmSubState.MM_DEREGISTERED__PLMN_SEARCH) {
switchState(ctx, EMmState.MM_DEREGISTERED, EMmSubState.MM_DEREGISTERED__NORMAL_SERVICE);
return;
}

if (ctx.mmCtx.mmSubState == EMmSubState.MM_DEREGISTERED__NORMAL_SERVICE) {
if (UserEquipment.AUTO && !ctx.ueTimers.t3346.isRunning()) {
MmRegistration.sendRegistration(ctx, ERegistrationType.INITIAL_REGISTRATION);
}
return;
}

if (ctx.mmCtx.mmState == EMmState.MM_REGISTERED_INITIATED) {
return;
}

if (ctx.mmCtx.mmSubState == EMmSubState.MM_REGISTERED__NORMAL_SERVICE) {
return;
}

if (UserEquipment.AUTO) {
throw new NotImplementedException("unhandled UE MM state");
}
}
}

0 comments on commit fe4b5f4

Please sign in to comment.