Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce the number of fatal assertions and add timeBeforeReconnecting #95

Merged
merged 1 commit into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cmd/packetrusher.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func main() {
&cli.IntFlag{Name: "timeBeforeNgapHandover", Value: 0, Aliases: []string{"ngh"}, Usage: "The time in ms, before triggering a UE handover using NGAP Handover. 0 to disable handover. This requires at least two gNodeB, eg: two N2/N3 IPs."},
&cli.IntFlag{Name: "timeBeforeXnHandover", Value: 0, Aliases: []string{"xnh"}, Usage: "The time in ms, before triggering a UE handover using Xn Handover. 0 to disable handover. This requires at least two gNodeB, eg: two N2/N3 IPs."},
&cli.IntFlag{Name: "timeBeforeIdle", Value: 0, Aliases: []string{"idl"}, Usage: "The time in ms, before switching UE to Idle. 0 to disable Idling."},
&cli.IntFlag{Name: "timeBeforeReconnecting", Value: 1000, Aliases: []string{"tbr"}, Usage: "The time in ms, before reconnecting to gNodeB after switching to Idle state. Default is 1000 ms. Only work in conjunction with timeBeforeIdle."},
&cli.IntFlag{Name: "numPduSessions", Value: 1, Aliases: []string{"nPdu"}, Usage: "The number of PDU Sessions to create"},
&cli.BoolFlag{Name: "loop", Aliases: []string{"l"}, Usage: "Register UEs in a loop."},
&cli.BoolFlag{Name: "tunnel", Aliases: []string{"t"}, Usage: "Enable the creation of the GTP-U tunnel interface."},
Expand Down Expand Up @@ -131,7 +132,7 @@ func main() {
tunnelMode = config.TunnelTun
}
}
templates.TestMultiUesInQueue(numUes, tunnelMode, c.Bool("dedicatedGnb"), c.Bool("loop"), c.Int("timeBetweenRegistration"), c.Int("timeBeforeDeregistration"), c.Int("timeBeforeNgapHandover"), c.Int("timeBeforeXnHandover"), c.Int("timeBeforeIdle"), c.Int("numPduSessions"))
templates.TestMultiUesInQueue(numUes, tunnelMode, c.Bool("dedicatedGnb"), c.Bool("loop"), c.Int("timeBetweenRegistration"), c.Int("timeBeforeDeregistration"), c.Int("timeBeforeNgapHandover"), c.Int("timeBeforeXnHandover"), c.Int("timeBeforeIdle"), c.Int("timeBeforeReconnecting"), c.Int("numPduSessions"))

return nil
},
Expand Down
10 changes: 10 additions & 0 deletions internal/common/tools/tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ type UESimulationConfig struct {
TimeBeforeNgapHandover int
TimeBeforeXnHandover int
TimeBeforeIdle int
TimeBeforeReconnecting int
NumPduSessions int
}

Expand Down Expand Up @@ -148,6 +149,7 @@ func SimulateSingleUE(simConfig UESimulationConfig, wg *sync.WaitGroup) {
}

var idleChannel <-chan time.Time = nil
var reconnectChannel <-chan time.Time = nil
if simConfig.TimeBeforeIdle != 0 {
idleChannel = time.After(time.Duration(simConfig.TimeBeforeIdle) * time.Millisecond)
}
Expand All @@ -171,6 +173,14 @@ func SimulateSingleUE(simConfig UESimulationConfig, wg *sync.WaitGroup) {
case <-idleChannel:
if ueRx != nil {
ueRx <- procedures.UeTesterMessage{Type: procedures.Idle}
// Channel creation to be transformed into a task ;-)
if simConfig.TimeBeforeReconnecting != 0 {
reconnectChannel = time.After(time.Duration(simConfig.TimeBeforeReconnecting) * time.Millisecond)
}
}
case <-reconnectChannel:
if ueRx != nil {
ueRx <- procedures.UeTesterMessage{Type: procedures.ServiceRequest}
}
case msg := <-scenarioChan:
if ueRx != nil {
Expand Down
7 changes: 6 additions & 1 deletion internal/control_test_engine/gnb/ngap/dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,15 @@ func Dispatch(amf *context.GNBAmf, gnb *context.GNBContext, message []byte) {
handler.HandlerAmfConfigurationUpdate(amf, gnb, ngapMsg)

case ngapType.ProcedureCodeHandoverResourceAllocation:
// handler NGAP Handover REquest
// handler NGAP Handover Request
log.Info("[GNB][NGAP] Receive Handover Request")
handler.HandlerHandoverRequest(amf, gnb, ngapMsg)

case ngapType.ProcedureCodePaging:
// handler NGAP Paging
log.Info("[GNB][NGAP] Receive Paging")
handler.HandlerPaging(gnb, ngapMsg)

case ngapType.ProcedureCodeErrorIndication:
// handler Error Indicator
log.Error("[GNB][NGAP] Receive Error Indication")
Expand Down
68 changes: 61 additions & 7 deletions internal/control_test_engine/gnb/ngap/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ func HandlerDownlinkNasTransport(gnb *context.GNBContext, message *ngapType.NGAP
}

ue := getUeFromContext(gnb, ranUeId, amfUeId)
if ue == nil {
log.Errorf("[GNB][NGAP] Cannot send DownlinkNASTransport message to UE with RANUEID %d as it does not know this UE", ranUeId)
return
}

// send NAS message to UE.
sender.SendToUe(ue, messageNas)
Expand Down Expand Up @@ -177,7 +181,10 @@ func HandlerInitialContextSetupRequest(gnb *context.GNBContext, message *ngapTyp
}

ue := getUeFromContext(gnb, ranUeId, amfUeId)

if ue == nil {
log.Errorf("[GNB][NGAP] Cannot setup context for unknown UE with RANUEID %d", ranUeId)
return
}
// create UE context.
ue.CreateUeContext(mobilityRestrict, maskedImeisv, sst, sd, ueSecurityCapabilities)

Expand Down Expand Up @@ -284,6 +291,10 @@ func HandlerPduSessionResourceSetupRequest(gnb *context.GNBContext, message *nga
}

ue := getUeFromContext(gnb, ranUeId, amfUeId)
if ue == nil {
log.Errorf("[GNB][NGAP] Cannot setup PDU Session for unknown UE With RANUEID %d", ranUeId)
return
}

var configuredPduSessions []*context.GnbPDUSession
for _, item := range pDUSessionResourceSetupList.List {
Expand Down Expand Up @@ -445,6 +456,10 @@ func HandlerPduSessionReleaseCommand(gnb *context.GNBContext, message *ngapType.
}

ue := getUeFromContext(gnb, ranUeId, amfUeId)
if ue == nil {
log.Errorf("[GNB][NGAP] Cannot release PDU Session for unknown UE With RANUEID %d", ranUeId)
return
}

for _, pduSessionId := range pduSessionIds {
pduSession, err := ue.GetPduSession(pduSessionId.Value)
Expand Down Expand Up @@ -703,6 +718,10 @@ func HandlerPathSwitchRequestAcknowledge(gnb *context.GNBContext, message *ngapT

}
ue := getUeFromContext(gnb, ranUeId, amfUeId)
if ue == nil {
log.Errorf("[GNB][NGAP] Cannot Xn Handover unknown UE With RANUEID %d", ranUeId)
return
}

if pduSessionResourceSwitchedList == nil || len(pduSessionResourceSwitchedList.List) == 0 {
log.Warn("[GNB] No PDU Sessions to be switched")
Expand Down Expand Up @@ -911,6 +930,10 @@ func HandlerHandoverCommand(amf *context.GNBAmf, gnb *context.GNBContext, messag

}
ue := getUeFromContext(gnb, ranUeId, amfUeId)
if ue == nil {
log.Errorf("[GNB][NGAP] Cannot NGAP Handover unknown UE With RANUEID %d", ranUeId)
return
}
newGnb := ue.GetHandoverGnodeB()
if newGnb == nil {
log.Error("[GNB] AMF is sending a Handover Command for an UE we did not send a Handover Required message")
Expand All @@ -927,6 +950,41 @@ func HandlerHandoverCommand(amf *context.GNBAmf, gnb *context.GNBContext, messag
sender.SendMessageToUe(ue, msg)
}

func HandlerPaging(gnb *context.GNBContext, message *ngapType.NGAPPDU) {

valueMessage := message.InitiatingMessage.Value.Paging

var uEPagingIdentity *ngapType.UEPagingIdentity
var tAIListForPaging *ngapType.TAIListForPaging

for _, ies := range valueMessage.ProtocolIEs.List {
switch ies.Id.Value {

case ngapType.ProtocolIEIDUEPagingIdentity:

if ies.Value.UEPagingIdentity == nil {
log.Fatal("[GNB][NGAP] UE Paging Identity is missing")
}
uEPagingIdentity = ies.Value.UEPagingIdentity

case ngapType.ProtocolIEIDTAIListForPaging:

if ies.Value.TAIListForPaging == nil {
log.Fatal("[GNB][NGAP] TAI List For Paging is missing")
}
tAIListForPaging = ies.Value.TAIListForPaging
}
}
_ = uEPagingIdentity
_ = tAIListForPaging
// TODO: Implement Paging
// Upon reception of the Paging with its TMSI, the UE must send a Service Request
// as in UE-initiated Service Request
// But: we need to figure out how the gNodeB may contact the UE when it's not in its context
// While avoiding adding a new channel, deadlock / sending to closed channels, having to jungle too much between channels when doing handover
log.Warnf("[GNB][AMF] UE Paging is not implemented, please manually reconnect UE with --timeBeforeReconnecting")
}

func HandlerErrorIndication(gnb *context.GNBContext, message *ngapType.NGAPPDU) {

valueMessage := message.InitiatingMessage.Value.ErrorIndication
Expand Down Expand Up @@ -960,7 +1018,8 @@ func getUeFromContext(gnb *context.GNBContext, ranUeId int64, amfUeId int64) *co
// check RanUeId and get UE.
ue, err := gnb.GetGnbUe(ranUeId)
if err != nil || ue == nil {
log.Fatal("[GNB][NGAP] RAN UE NGAP ID is incorrect, found: ", ranUeId)
log.Error("[GNB][NGAP] RAN UE NGAP ID is incorrect, found: ", ranUeId)
return nil
// TODO SEND ERROR INDICATION
}

Expand All @@ -974,19 +1033,14 @@ func causeToString(cause *ngapType.Cause) string {
switch cause.Present {
case ngapType.CausePresentRadioNetwork:
return "radioNetwork: " + causeRadioNetworkToString(cause.RadioNetwork)
break
case ngapType.CausePresentTransport:
return "transport: " + causeTransportToString(cause.Transport)
break
case ngapType.CausePresentNas:
return "nas: " + causeNasToString(cause.Nas)
break
case ngapType.CausePresentProtocol:
return "protocol: " + causeProtocolToString(cause.Protocol)
break
case ngapType.CausePresentMisc:
return "misc: " + causeMiscToString(cause.Misc)
break
}
}
return "Cause not found"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const (
Terminate UeTesterMessageType = 4
Kill UeTesterMessageType = 5
Idle UeTesterMessageType = 6
ServiceRequest UeTesterMessageType = 7
)

type UeTesterMessage struct {
Expand Down
3 changes: 1 addition & 2 deletions internal/control_test_engine/ue/ue.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,7 @@ func ueMgrHandler(msg procedures.UeTesterMessage, ue *context.UEContext) bool {
// We switch UE to IDLE
ue.SetStateMM_IDLE()
trigger.SwitchToIdle(ue)

time.Sleep(1 * time.Second)
case procedures.ServiceRequest:
// Since gNodeB stopped communication after switching to Idle, we need to connect back to gNodeB
service.InitConn(ue, ue.GetGnbInboundChannel())
if ue.Get5gGuti() != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/templates/test-attach-ue-with-configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ func TestAttachUeWithConfiguration(tunnelEnabled bool) {
if tunnelEnabled {
tunnelMode = config.TunnelVrf
}
TestMultiUesInQueue(1, tunnelMode, true, false, 500, 0, 0, 0, 0, 1)
TestMultiUesInQueue(1, tunnelMode, true, false, 500, 0, 0, 0, 0, 0, 1)
}
3 changes: 2 additions & 1 deletion internal/templates/test-multi-ues-in-queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
log "github.com/sirupsen/logrus"
)

func TestMultiUesInQueue(numUes int, tunnelMode config.TunnelMode, dedicatedGnb bool, loop bool, timeBetweenRegistration int, timeBeforeDeregistration int, timeBeforeNgapHandover int, timeBeforeXnHandover int, timeBeforeIdle int, numPduSessions int) {
func TestMultiUesInQueue(numUes int, tunnelMode config.TunnelMode, dedicatedGnb bool, loop bool, timeBetweenRegistration int, timeBeforeDeregistration int, timeBeforeNgapHandover int, timeBeforeXnHandover int, timeBeforeIdle int, timeBeforeReconnecting int, numPduSessions int) {
if tunnelMode != config.TunnelDisabled {
if !dedicatedGnb {
log.Fatal("You cannot use the --tunnel option, without using the --dedicatedGnb option")
Expand Down Expand Up @@ -64,6 +64,7 @@ func TestMultiUesInQueue(numUes int, tunnelMode config.TunnelMode, dedicatedGnb
TimeBeforeNgapHandover: timeBeforeNgapHandover,
TimeBeforeXnHandover: timeBeforeXnHandover,
TimeBeforeIdle: timeBeforeIdle,
TimeBeforeReconnecting: timeBeforeReconnecting,
NumPduSessions: numPduSessions,
}

Expand Down