Skip to content

Commit

Permalink
Merge pull request #42 from Raguideau/test3
Browse files Browse the repository at this point in the history
add pdu session release command test
  • Loading branch information
linouxis9 authored Dec 8, 2023
2 parents a80a90b + 1f775db commit 767ce0a
Show file tree
Hide file tree
Showing 15 changed files with 262 additions and 41 deletions.
1 change: 1 addition & 0 deletions test/aio5gc/context/amf.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ func (c *AMFContext) NewUE(ueRanNgapId int64) *UEContext {
newUE.SetRanNgapId(ueRanNgapId)
newUE.SetAmfNgapId(c.getAmfUeId())
newUE.SecurityContextAvailable = false
newUE.smContexts = make(map[int32]*SmContext)
ueMutex.Lock()
c.ues = append(c.ues, &newUE)
ueMutex.Unlock()
Expand Down
4 changes: 2 additions & 2 deletions test/aio5gc/context/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (s *SessionContext) NewSessionContext() {
}}

s.lastAllocatedIP = net.ParseIP("10.0.0.1")
s.n3 = net.ParseIP("127.0.0.1")
s.n3 = net.ParseIP("127.0.0.1").To4()
}

func (s *SessionContext) GetN3() net.IP {
Expand Down Expand Up @@ -96,6 +96,6 @@ func (s *SessionContext) GetUnallocatedIP() net.IP {
log.Fatal("[5GC][NAS] Error while allocating ip for PDU session: " + err.Error())
}

s.lastAllocatedIP = net.ParseIP(ip)
s.lastAllocatedIP = net.ParseIP(ip).To4()
return s.lastAllocatedIP
}
4 changes: 4 additions & 0 deletions test/aio5gc/context/sessionManagement.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,7 @@ func CreatePDUSession(sessionRequest *nasMessage.PDUSessionEstablishmentRequest,
log.Infof("[5GC] Create smContext[pduSessionID: %d] Success", pduSessionID)
return newSmContext, nil
}

func ReleasePDUSession(ue *UEContext, pduSessionID int32) (SmContext, error) {
return ue.DeleteSmContext(pduSessionID)
}
24 changes: 19 additions & 5 deletions test/aio5gc/context/ue.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,21 +115,35 @@ func (ue *UEContext) GetSecurityContext() *SecurityContext {
func (ue *UEContext) AddSmContext(newContext *SmContext) error {
ue.SmContextMtx.Lock()
defer ue.SmContextMtx.Unlock()

sessionId := newContext.GetPduSessionId()
if ue.smContexts == nil {
ue.smContexts = make(map[int32]*SmContext)
}
_, hasKey := ue.smContexts[sessionId]
if hasKey {
id := strconv.Itoa(int(sessionId))
return errors.New("[5GC] UE" + ue.guti + " already have a PDU Sessions with Id" + id)
return errors.New("[5GC] Could not create PDU Session " + id + " for UE " + ue.guti + ": already exist")
} else {
ue.smContexts[sessionId] = newContext
}
return nil
}

func (ue *UEContext) DeleteSmContext(sessionId int32) (SmContext, error) {
ue.SmContextMtx.Lock()
defer ue.SmContextMtx.Unlock()

var smContext SmContext
_, hasKey := ue.smContexts[sessionId]
if hasKey {
smContext = *ue.smContexts[sessionId]
delete(ue.smContexts, sessionId)
} else {
id := strconv.Itoa(int(sessionId))
return SmContext{}, errors.New("[5GC] Could not delete PDU Session " + id + " for UE " + ue.guti + ": not found")
}

return smContext, nil
}

// Kamf Derivation function defined in TS 33.501 Annex A.7
func (ue *UEContext) DerivateKamf() {
supiRegexp, err := regexp.Compile("(?:imsi|supi)-([0-9]{5,15})")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func PDUSessionEstablishmentAccept(ue *context.UEContext, smContext *context.SmC
if err != nil {
return nil, err
}
nasMsg, err = buildDLNASTransport(ue, nasPdu, 1)
nasMsg, err = buildDLNASTransport(ue, nasPdu, uint8(smContext.GetPduSessionId()))
if err != nil {
return nil, err
}
Expand Down
44 changes: 44 additions & 0 deletions test/aio5gc/msg/nas/builder/pduSessionReleaseCommand.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* SPDX-License-Identifier: Apache-2.0
* © Copyright 2023 Hewlett Packard Enterprise Development LP
*/
package builder

import (
"my5G-RANTester/test/aio5gc/context"
"my5G-RANTester/test/aio5gc/lib/tools"

"github.com/free5gc/nas"
"github.com/free5gc/nas/nasMessage"
)

func PDUSessionReleaseCommand(ue *context.UEContext, smContext context.SmContext, cause uint8) (msg []byte, err error) {
nasMsg := buildPDUSessionReleaseCommand(ue, smContext, cause)
nasPdu, err := nasMsg.PlainNasEncode()
if err != nil {
return nil, err
}
nasMsg, err = buildDLNASTransport(ue, nasPdu, uint8(smContext.GetPduSessionId()))
if err != nil {
return nil, err
}
return tools.Encode(ue, nasMsg)
}

func buildPDUSessionReleaseCommand(ue *context.UEContext, smContext context.SmContext, cause uint8) *nas.Message {
m := nas.NewMessage()
m.GsmMessage = nas.NewGsmMessage()
m.GsmHeader.SetMessageType(nas.MsgTypePDUSessionReleaseCommand)
m.GsmHeader.SetExtendedProtocolDiscriminator(nasMessage.Epd5GSSessionManagementMessage)
m.PDUSessionReleaseCommand = nasMessage.NewPDUSessionReleaseCommand(0x0)
pDUSessionReleaseCommand := m.PDUSessionReleaseCommand

pDUSessionReleaseCommand.SetMessageType(nas.MsgTypePDUSessionReleaseCommand)
pDUSessionReleaseCommand.SetExtendedProtocolDiscriminator(nasMessage.Epd5GSSessionManagementMessage)
pDUSessionReleaseCommand.SetPDUSessionID(uint8(smContext.GetPduSessionId()))

pDUSessionReleaseCommand.SetPTI(smContext.GetPti())
pDUSessionReleaseCommand.SetCauseValue(cause)

return m
}
78 changes: 52 additions & 26 deletions test/aio5gc/msg/nas/handler/ulNasTransport.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,59 +39,85 @@ func UlNasTransport(nasReq *nas.Message, gnb *context.GNBContext, ue *context.UE

func transport5GSMMessage(ue *context.UEContext, ulNasTransport *nasMessage.ULNASTransport, session *context.SessionContext, gnb *context.GNBContext) error {
requestType := ulNasTransport.RequestType
smMessage := ulNasTransport.PayloadContainer.GetPayloadContainerContents()
n1smContent := ulNasTransport.PayloadContainer.GetPayloadContainerContents()
var pduSessionID int32

if requestType == nil {
return errors.New("[5GC][NAS] ulNasTransport Request type is nil")
}

if id := ulNasTransport.PduSessionID2Value; id != nil {
pduSessionID = int32(id.GetPduSessionID2Value())
} else {
return errors.New("[5GC][NAS] PDU Session ID is nil")
}

switch requestType.GetRequestTypeValue() {
// case iii) if the AMF does not have a PDU session routing context for the PDU session ID and the UE
// and the Request type IE is included and is set to "initial request"
case nasMessage.ULNASTransportRequestTypeInitialRequest:
return ulNASTransportRequestTypeInitialRequest(ulNasTransport, ue, session, pduSessionID, smMessage, gnb)
default:
return errors.New("[5GC][NAS] Unimplemented ulNasTransport Request type")
if requestType == nil {
n1smContent := ulNasTransport.PayloadContainer.GetPayloadContainerContents()
return handleUnspecifiedRequest(n1smContent, ue, pduSessionID, gnb)
}
}

func ulNASTransportRequestTypeInitialRequest(initialRequest *nasMessage.ULNASTransport,
ue *context.UEContext,
session *context.SessionContext,
pduSessionID int32,
smMessage []uint8,
gnb *context.GNBContext) error {

var (
snssai models.Snssai
dnn string
)
// If the S-NSSAI IE is not included, select a default snssai
if initialRequest.SNSSAI != nil {
snssai = nasConvert.SnssaiToModels(initialRequest.SNSSAI)
if ulNasTransport.SNSSAI != nil {
snssai = nasConvert.SnssaiToModels(ulNasTransport.SNSSAI)
} else {
snssai = ue.GetNssai()
}

dnnList := session.GetDnnList()
if initialRequest.DNN != nil {
if !slices.Contains(dnnList, initialRequest.DNN.GetDNN()) {
if ulNasTransport.DNN != nil {
if !slices.Contains(dnnList, ulNasTransport.DNN.GetDNN()) {
return errors.New("[5GC] Unknown DNN requested")
}
dnn = initialRequest.DNN.GetDNN()
dnn = ulNasTransport.DNN.GetDNN()

} else {
dnn = dnnList[0]
}

n1smContent := initialRequest.PayloadContainer.GetPayloadContainerContents()
switch requestType.GetRequestTypeValue() {
// case iii) if the AMF does not have a PDU session routing context for the PDU session ID and the UE
// and the Request type IE is included and is set to "initial request"
case nasMessage.ULNASTransportRequestTypeInitialRequest:
return handleInitialRequest(n1smContent, ue, session, pduSessionID, snssai, dnn, gnb)

default:
return errors.New("[5GC][NAS] Unimplemented ulNasTransport Request type")
}
}

func handleUnspecifiedRequest(n1smContent []uint8,
ue *context.UEContext,
pduSessionID int32,
gnb *context.GNBContext) error {

m := nas.NewMessage()
err := m.GsmMessageDecode(&n1smContent)
if err != nil {
return errors.New("[5GC][NAS] GsmMessageDecode Error: " + err.Error())
}
switch m.GsmHeader.GetMessageType() {
case nas.MsgTypePDUSessionReleaseRequest:
smContext, err := context.ReleasePDUSession(ue, pduSessionID)
if err != nil {
return err
}
msg.SendPDUSessionReleaseCommand(gnb, ue, smContext, nasMessage.Cause5GSMRegularDeactivation)

default:
return errors.New("[5GC][NAS] Unimplemented ulNasTransport Request type")
}
return nil
}

func handleInitialRequest(n1smContent []uint8,
ue *context.UEContext,
session *context.SessionContext,
pduSessionID int32,
snssai models.Snssai,
dnn string,
gnb *context.GNBContext) error {

m := nas.NewMessage()
err := m.GsmMessageDecode(&n1smContent)
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions test/aio5gc/msg/nas/nasDispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ func Dispatch(nasPDU *ngapType.NASPDU, ueContext *context.UEContext, fgc *contex
case nas.MsgTypeConfigurationUpdateComplete:
log.Info("[5GC][NAS] Received Configuration Update Complete")

case nas.MsgTypeDeregistrationRequestUEOriginatingDeregistration:
log.Info("[5GC][NAS] Received Deregistration Request: UE Originating Deregistration (not handled yet)")

default:
err = errors.New("[5GC][NAS] unrecognised nas message type: " + strconv.Itoa(int(msg.GmmHeader.GetMessageType())))
}
Expand Down
4 changes: 2 additions & 2 deletions test/aio5gc/msg/ngap/builder/downlinkNASTransport.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ import (

func DownlinkNASTransport(nasPdu []byte, ue *context.UEContext) ([]byte, error) {

message, err := BuildDownlinkNASTransport(nasPdu, *ue)
message, err := BuildDownlinkNASTransport(nasPdu, ue)
if err != nil {
return []byte{}, err
}
return ngap.Encoder(message)
}

func BuildDownlinkNASTransport(nasPdu []byte, ue context.UEContext) (pdu ngapType.NGAPPDU, err error) {
func BuildDownlinkNASTransport(nasPdu []byte, ue *context.UEContext) (pdu ngapType.NGAPPDU, err error) {

pdu.Present = ngapType.NGAPPDUPresentInitiatingMessage
pdu.InitiatingMessage = new(ngapType.InitiatingMessage)
Expand Down
4 changes: 2 additions & 2 deletions test/aio5gc/msg/ngap/builder/initialContextSetupRequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ import (
)

func InitialContextSetupRequest(nasPdu []byte, ue *context.UEContext, amf context.AMFContext) ([]byte, error) {
message, err := buildInitialContextSetupRequest(nasPdu, *ue, amf)
message, err := buildInitialContextSetupRequest(nasPdu, ue, amf)
if err != nil {
return []byte{}, err
}
return ngap.Encoder(message)
}

func buildInitialContextSetupRequest(nasPdu []byte, ue context.UEContext, amf context.AMFContext) (ngapType.NGAPPDU, error) {
func buildInitialContextSetupRequest(nasPdu []byte, ue *context.UEContext, amf context.AMFContext) (ngapType.NGAPPDU, error) {
var pdu ngapType.NGAPPDU

pdu.Present = ngapType.NGAPPDUPresentInitiatingMessage
Expand Down
2 changes: 1 addition & 1 deletion test/aio5gc/msg/ngap/builder/pduSessionResourceSetup.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
func PDUSessionResourceSetup(nasPdu []byte, smContext context.SmContext, ue *context.UEContext, session *context.SessionContext) ([]byte, error) {
message, err := buildPDUSessionResourceSetupRequest(ue, smContext, nasPdu, session.GetN3())
if err != nil {
return []byte{}, err
return nil, err
}
return ngap.Encoder(message)
}
Expand Down
99 changes: 99 additions & 0 deletions test/aio5gc/msg/ngap/builder/pduSessionRessourceRelease.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/**
* SPDX-License-Identifier: Apache-2.0
* © Copyright 2023 Hewlett Packard Enterprise Development LP
*/
package builder

import (
"my5G-RANTester/lib/aper"
"my5G-RANTester/lib/ngap"
"my5G-RANTester/lib/ngap/ngapType"
"my5G-RANTester/test/aio5gc/context"
)

func PDUSessionResourceRelease(nasPdu []byte, ue *context.UEContext, sessionId int32) ([]byte, error) {
message, err := buildPDUSessionResourceRelease(nasPdu, ue, sessionId)
if err != nil {
return nil, err
}
return ngap.Encoder(message)
}

func buildPDUSessionResourceRelease(nasPdu []byte, ue *context.UEContext, sessionId int32) (ngapType.NGAPPDU, error) {
var pdu ngapType.NGAPPDU
pdu.Present = ngapType.NGAPPDUPresentInitiatingMessage
pdu.InitiatingMessage = new(ngapType.InitiatingMessage)

initiatingMessage := pdu.InitiatingMessage
initiatingMessage.ProcedureCode.Value = ngapType.ProcedureCodePDUSessionResourceRelease
initiatingMessage.Criticality.Value = ngapType.CriticalityPresentReject
initiatingMessage.Value.Present = ngapType.InitiatingMessagePresentPDUSessionResourceReleaseCommand
initiatingMessage.Value.PDUSessionResourceReleaseCommand = new(ngapType.PDUSessionResourceReleaseCommand)

pDUSessionResourceReleaseCommand := initiatingMessage.Value.PDUSessionResourceReleaseCommand
PDUSessionResourceReleaseCommandIEs := &pDUSessionResourceReleaseCommand.ProtocolIEs

// AMFUENGAPID
ie := ngapType.PDUSessionResourceReleaseCommandIEs{}
ie.Id.Value = ngapType.ProtocolIEIDAMFUENGAPID
ie.Criticality.Value = ngapType.CriticalityPresentReject
ie.Value.Present = ngapType.PDUSessionResourceReleaseCommandIEsPresentAMFUENGAPID
ie.Value.AMFUENGAPID = new(ngapType.AMFUENGAPID)

aMFUENGAPID := ie.Value.AMFUENGAPID
aMFUENGAPID.Value = ue.GetAmfNgapId()

PDUSessionResourceReleaseCommandIEs.List = append(PDUSessionResourceReleaseCommandIEs.List, ie)

// RANUENGAPID
ie = ngapType.PDUSessionResourceReleaseCommandIEs{}
ie.Id.Value = ngapType.ProtocolIEIDRANUENGAPID
ie.Criticality.Value = ngapType.CriticalityPresentReject
ie.Value.Present = ngapType.PDUSessionResourceReleaseCommandIEsPresentRANUENGAPID
ie.Value.RANUENGAPID = new(ngapType.RANUENGAPID)

rANUENGAPID := ie.Value.RANUENGAPID
rANUENGAPID.Value = ue.GetRanNgapId()

PDUSessionResourceReleaseCommandIEs.List = append(PDUSessionResourceReleaseCommandIEs.List, ie)

ie = ngapType.PDUSessionResourceReleaseCommandIEs{}
ie.Id.Value = ngapType.ProtocolIEIDNASPDU
ie.Criticality.Value = ngapType.CriticalityPresentIgnore
ie.Value.Present = ngapType.PDUSessionResourceReleaseCommandIEsPresentNASPDU
ie.Value.NASPDU = new(ngapType.NASPDU)

ie.Value.NASPDU.Value = nasPdu

PDUSessionResourceReleaseCommandIEs.List = append(PDUSessionResourceReleaseCommandIEs.List, ie)

// PDUSessionResourceToReleaseListRelCmd
ie = ngapType.PDUSessionResourceReleaseCommandIEs{}
ie.Id.Value = ngapType.ProtocolIEIDPDUSessionResourceToReleaseListRelCmd
ie.Criticality.Value = ngapType.CriticalityPresentReject
ie.Value.Present = ngapType.PDUSessionResourceReleaseCommandIEsPresentPDUSessionResourceToReleaseListRelCmd

pduSessionResourceReleasedList := ngapType.PDUSessionResourceToReleaseListRelCmd{}
var item ngapType.PDUSessionResourceToReleaseItemRelCmd
item.PDUSessionID.Value = int64(sessionId)

pduSessionResourceReleaseCommandTransfer := ngapType.PDUSessionResourceReleaseCommandTransfer{
Cause: ngapType.Cause{
Present: ngapType.CausePresentNas,
Nas: &ngapType.CauseNas{
Value: ngapType.CauseNasPresentNormalRelease,
},
},
}
buf, err := aper.MarshalWithParams(pduSessionResourceReleaseCommandTransfer, "valueExt")
if err != nil {
return ngapType.NGAPPDU{}, err
}
item.PDUSessionResourceReleaseCommandTransfer = buf
pduSessionResourceReleasedList.List = append(pduSessionResourceReleasedList.List, item)

ie.Value.PDUSessionResourceToReleaseListRelCmd = &pduSessionResourceReleasedList
PDUSessionResourceReleaseCommandIEs.List = append(PDUSessionResourceReleaseCommandIEs.List, ie)

return pdu, nil
}
Loading

0 comments on commit 767ce0a

Please sign in to comment.