Skip to content

Commit

Permalink
Reduce the number of fatal assertions and add timeBeforeReconnecting
Browse files Browse the repository at this point in the history
Signed-off-by: Valentin <[email protected]>
  • Loading branch information
linouxis9 committed Mar 25, 2024
1 parent 2c00658 commit 1d88b76
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 13 deletions.
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
1 change: 1 addition & 0 deletions internal/control_test_engine/procedures/UeTesterMessage.go
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

0 comments on commit 1d88b76

Please sign in to comment.