diff --git a/common/events.go b/common/events.go index 5c4ae559..6547f13e 100644 --- a/common/events.go +++ b/common/events.go @@ -58,6 +58,7 @@ const ( // For setting up channels between UE and GNB to exchange user data DATA_BEARER_SETUP_REQUEST_EVENT DATA_BEARER_SETUP_RESPONSE_EVENT + DATA_BEARER_RELEASE_REQUEST_EVENT // gNB acknowledges simue for releasing UE context using this event CTX_RELEASE_ACKNOWLEDGEMENT_EVENT @@ -141,6 +142,7 @@ const ( DOWNLINK_NAS_TRANSPORT_EVENT EventType = N2_EVENT + 1 + iota INITIAL_CTX_SETUP_REQUEST_EVENT PDU_SESS_RESOURCE_SETUP_REQUEST_EVENT + PDU_SESS_RESOURCE_RELEASE_COMMAND_EVENT UE_CTX_RELEASE_COMMAND_EVENT ) @@ -150,79 +152,81 @@ const ( ) var evtStrMap map[EventType]string = map[EventType]string{ - INIT_EVENT: "INIT-EVENT", - QUIT_EVENT: "QUIT-EVENT", - ERROR_EVENT: "ERROR-EVENT", - PROFILE_START_EVENT: "PROFILE-START-EVENT", - PROFILE_PASS_EVENT: "PROFILE-PASS-EVENT", - PROFILE_FAIL_EVENT: "PROFILE-FAIL-EVENT", - DATA_PKT_GEN_REQUEST_EVENT: "DATA-PACKET-GENERATION-REQUEST-EVENT", - DATA_PKT_GEN_SUCCESS_EVENT: "DATA-PACKET-SUCCESS-EVENT", - DATA_PKT_GEN_FAILURE_EVENT: "DATA-PACKET-FAILURE-EVENT", - CONNECTION_REQUEST_EVENT: "CONNECTION-REQUEST-EVENT", - CONNECTION_RELEASE_REQUEST_EVENT: "CONNECTION-RELEASE-REQUEST-EVENT", - UL_INFO_TRANSFER_EVENT: "UL-INFO-TRANSFER-EVENT", - DL_INFO_TRANSFER_EVENT: "DL-INFO-TRANSFER-EVENT", - UL_UE_DATA_TRANSFER_EVENT: "UL-UE-DATA-TRANSFER-EVENT", - DL_UE_DATA_TRANSFER_EVENT: "DL-UE-DATA-TRANSFER-EVENT", - LAST_DATA_PKT_EVENT: "LAST-DATA-PACKET-EVENT", - DATA_BEARER_SETUP_REQUEST_EVENT: "DATA-BEARER-SETUP-REQUEST-EVENT", - DATA_BEARER_SETUP_RESPONSE_EVENT: "DATA-BEARER-SETUP-RESPONSE-EVENT", - CTX_RELEASE_ACKNOWLEDGEMENT_EVENT: "CONTEXT-RELEASE-ACKNOWLEDGEMENT-EVENT", - TRIGGER_AN_RELEASE_EVENT: "TRIGGER-AN-RELEASE-EVENT", - REG_REQUEST_EVENT: "REGESTRATION-REQUEST-EVENT", - REG_ACCEPT_EVENT: "REGESTRATION-ACCEPT-EVENT", - REG_COMPLETE_EVENT: "REGESTRATION-COMPLETE-EVENT", - REG_REJECT_EVENT: "REGESTRATION-REJECT-EVENT", - DEREG_REQUEST_UE_ORIG_EVENT: "DEREGISTRATION-REQUEST-UE-ORIG-EVENT", - DEREG_ACCEPT_UE_ORIG_EVENT: "DEREGISTRATION-ACCEPT-UE-ORIG-EVENT", - DEREG_REQUEST_UE_TERM_EVENT: "DEREGISTRATION-REQUEST-UE-TERM-EVENT", - DEREG_ACCEPT_UE_TERM_EVENT: "DEREGISTRATION-ACCEPT-UE-TERM-EVENT", - SERVICE_REQUEST_EVENT: "SERVICE-REQUEST-EVENT", - SERVICE_REJECT_EVENT: "SERVICE-REJECT-EVENT", - SERVICE_ACCEPT_EVENT: "SERVICE-ACCEPT-EVENT", - AUTH_REQUEST_EVENT: "AUTHENTICATION-REQUEST-EVENT", - AUTH_RESPONSE_EVENT: "AUTHENTICATION-RESPONSE-EVENT", - AUTH_REJECT_EVENT: "AUTHENTICATION-REJECT-EVENT", - AUTH_FAILURE_EVENT: "AUTHENTICATION-FAILURE-EVENT", - AUTH_RESULT_EVENT: "AUTHENTICATION-RESULT-EVENT", - ID_REQUEST_EVENT: "ID-REQUEST-EVENT", - ID_RESPONSE_EVENT: "ID-RESPONSE-EVENT", - SEC_MOD_COMMAND_EVENT: "SECURITY-MODE-COMMAND-EVENT", - SEC_MOD_COMPLETE_EVENT: "SECURITY-MODE-COMPLETE-EVENT", - SEC_MOD_REJECT_EVENT: "SECURITY-MODE-REJECT-EVENT", - FIVE_GMM_STATUS_EVENT: "FIVE-GMM-STATUS-EVENT", - NOTIFICATION_EVENT: "NOTIFICATION-EVENT", - NOTIFICATION_RESPONSE_EVENT: "NOTIFICATION-RESPONSE-EVENT", - UL_NAS_TRANSPORT_EVENT: "UL-NAS-TRANSPORT-EVENT", - DL_NAS_TRANSPORT_EVENT: "DL-NAS-TRANSPORT-EVENT", - PDU_SESS_EST_REQUEST_EVENT: "PDU-SESSION-ESTABLISHMENT-REQUEST-EVENT", - PDU_SESS_EST_ACCEPT_EVENT: "PDU-SESSION-ESTABLISHMENT-ACCEPT-EVENT", - PDU_SESS_EST_REJECT_EVENT: "PDU-SESSION-ESTABLISHMENT-REJECT-EVENT", - PDU_SESS_AUTH_COMMAND_EVENT: "PDU-SESSION-AUTHENTICATION-COMMAND-EVENT", - PDU_SESS_AUTH_COMPLETE_EVENT: "PDU-SESSION-AUTHENTICATION-COMPLETE-EVENT", - PDU_SESS_AUTH_RESULT_EVENT: "PDU-SESSION-AUTHENTICATION-RESULT-EVENT", - PDU_SESS_MOD_REQUEST_EVENT: "PDU-SESSION-MODIFICATION-REQUEST-EVENT", - PDU_SESS_MOD_REJECT_EVENT: "PDU-SESSION-MODIFICATION-REJECT-EVENT", - PDU_SESS_MOD_COMMAND_EVENT: "PDU-SESSION-MODIFICATION-COMMAND-EVENT", - PDU_SESS_MOD_COMPLETE_EVENT: "PDU-SESSION-MODIFICATION-COMPLETE-EVENT", - PDU_SESS_MOD_CMD_REJECT_EVENT: "PDU-SESSION-MODIFICATION-COMMAND-REJECT-EVENT", - PDU_SESS_REL_REQUEST_EVENT: "PDU-SESSION-RELEASE-REQUEST-EVENT", - PDU_SESS_REL_REJECT_EVENT: "PDU-SESSION-RELEASE-REJECT-EVENT", - PDU_SESS_REL_COMMAND_EVENT: "PDU-SESSION-RELEASE-COMMAND-EVENT", - PDU_SESS_REL_COMPLETE_EVENT: "PDU-SESSION-RELEASE-COMPLETE-EVENT", - FIVEGSM_STATUS_EVENT: "FIVEGSM-STATUS-EVENT", - DOWNLINK_NAS_TRANSPORT_EVENT: "DOWNLINK-NAS-TRANSPORT-EVENT", - INITIAL_CTX_SETUP_REQUEST_EVENT: "INITIAL-CONTEXT-SETUP-REQUEST-EVENT", - PDU_SESS_RESOURCE_SETUP_REQUEST_EVENT: "PDU-SESSION-RESOURCE-SETUP-REQUEST-EVENT", - UE_CTX_RELEASE_COMMAND_EVENT: "UE-CONTEXT-RELEASE-COMMAND-EVENT", - DL_UE_DATA_TRANSPORT_EVENT: "DL-UE-DATA-TRANSPORT-EVENT", + INIT_EVENT: "INIT-EVENT", + QUIT_EVENT: "QUIT-EVENT", + ERROR_EVENT: "ERROR-EVENT", + PROFILE_START_EVENT: "PROFILE-START-EVENT", + PROFILE_PASS_EVENT: "PROFILE-PASS-EVENT", + PROFILE_FAIL_EVENT: "PROFILE-FAIL-EVENT", + DATA_PKT_GEN_REQUEST_EVENT: "DATA-PACKET-GENERATION-REQUEST-EVENT", + DATA_PKT_GEN_SUCCESS_EVENT: "DATA-PACKET-SUCCESS-EVENT", + DATA_PKT_GEN_FAILURE_EVENT: "DATA-PACKET-FAILURE-EVENT", + CONNECTION_REQUEST_EVENT: "CONNECTION-REQUEST-EVENT", + CONNECTION_RELEASE_REQUEST_EVENT: "CONNECTION-RELEASE-REQUEST-EVENT", + UL_INFO_TRANSFER_EVENT: "UL-INFO-TRANSFER-EVENT", + DL_INFO_TRANSFER_EVENT: "DL-INFO-TRANSFER-EVENT", + UL_UE_DATA_TRANSFER_EVENT: "UL-UE-DATA-TRANSFER-EVENT", + DL_UE_DATA_TRANSFER_EVENT: "DL-UE-DATA-TRANSFER-EVENT", + LAST_DATA_PKT_EVENT: "LAST-DATA-PACKET-EVENT", + DATA_BEARER_SETUP_REQUEST_EVENT: "DATA-BEARER-SETUP-REQUEST-EVENT", + DATA_BEARER_SETUP_RESPONSE_EVENT: "DATA-BEARER-SETUP-RESPONSE-EVENT", + DATA_BEARER_RELEASE_REQUEST_EVENT: "DATA-BEARER-RELEASE-REQUEST-EVENT", + CTX_RELEASE_ACKNOWLEDGEMENT_EVENT: "CONTEXT-RELEASE-ACKNOWLEDGEMENT-EVENT", + TRIGGER_AN_RELEASE_EVENT: "TRIGGER-AN-RELEASE-EVENT", + REG_REQUEST_EVENT: "REGESTRATION-REQUEST-EVENT", + REG_ACCEPT_EVENT: "REGESTRATION-ACCEPT-EVENT", + REG_COMPLETE_EVENT: "REGESTRATION-COMPLETE-EVENT", + REG_REJECT_EVENT: "REGESTRATION-REJECT-EVENT", + DEREG_REQUEST_UE_ORIG_EVENT: "DEREGISTRATION-REQUEST-UE-ORIG-EVENT", + DEREG_ACCEPT_UE_ORIG_EVENT: "DEREGISTRATION-ACCEPT-UE-ORIG-EVENT", + DEREG_REQUEST_UE_TERM_EVENT: "DEREGISTRATION-REQUEST-UE-TERM-EVENT", + DEREG_ACCEPT_UE_TERM_EVENT: "DEREGISTRATION-ACCEPT-UE-TERM-EVENT", + SERVICE_REQUEST_EVENT: "SERVICE-REQUEST-EVENT", + SERVICE_REJECT_EVENT: "SERVICE-REJECT-EVENT", + SERVICE_ACCEPT_EVENT: "SERVICE-ACCEPT-EVENT", + AUTH_REQUEST_EVENT: "AUTHENTICATION-REQUEST-EVENT", + AUTH_RESPONSE_EVENT: "AUTHENTICATION-RESPONSE-EVENT", + AUTH_REJECT_EVENT: "AUTHENTICATION-REJECT-EVENT", + AUTH_FAILURE_EVENT: "AUTHENTICATION-FAILURE-EVENT", + AUTH_RESULT_EVENT: "AUTHENTICATION-RESULT-EVENT", + ID_REQUEST_EVENT: "ID-REQUEST-EVENT", + ID_RESPONSE_EVENT: "ID-RESPONSE-EVENT", + SEC_MOD_COMMAND_EVENT: "SECURITY-MODE-COMMAND-EVENT", + SEC_MOD_COMPLETE_EVENT: "SECURITY-MODE-COMPLETE-EVENT", + SEC_MOD_REJECT_EVENT: "SECURITY-MODE-REJECT-EVENT", + FIVE_GMM_STATUS_EVENT: "FIVE-GMM-STATUS-EVENT", + NOTIFICATION_EVENT: "NOTIFICATION-EVENT", + NOTIFICATION_RESPONSE_EVENT: "NOTIFICATION-RESPONSE-EVENT", + UL_NAS_TRANSPORT_EVENT: "UL-NAS-TRANSPORT-EVENT", + DL_NAS_TRANSPORT_EVENT: "DL-NAS-TRANSPORT-EVENT", + PDU_SESS_EST_REQUEST_EVENT: "PDU-SESSION-ESTABLISHMENT-REQUEST-EVENT", + PDU_SESS_EST_ACCEPT_EVENT: "PDU-SESSION-ESTABLISHMENT-ACCEPT-EVENT", + PDU_SESS_EST_REJECT_EVENT: "PDU-SESSION-ESTABLISHMENT-REJECT-EVENT", + PDU_SESS_AUTH_COMMAND_EVENT: "PDU-SESSION-AUTHENTICATION-COMMAND-EVENT", + PDU_SESS_AUTH_COMPLETE_EVENT: "PDU-SESSION-AUTHENTICATION-COMPLETE-EVENT", + PDU_SESS_AUTH_RESULT_EVENT: "PDU-SESSION-AUTHENTICATION-RESULT-EVENT", + PDU_SESS_MOD_REQUEST_EVENT: "PDU-SESSION-MODIFICATION-REQUEST-EVENT", + PDU_SESS_MOD_REJECT_EVENT: "PDU-SESSION-MODIFICATION-REJECT-EVENT", + PDU_SESS_MOD_COMMAND_EVENT: "PDU-SESSION-MODIFICATION-COMMAND-EVENT", + PDU_SESS_MOD_COMPLETE_EVENT: "PDU-SESSION-MODIFICATION-COMPLETE-EVENT", + PDU_SESS_MOD_CMD_REJECT_EVENT: "PDU-SESSION-MODIFICATION-COMMAND-REJECT-EVENT", + PDU_SESS_REL_REQUEST_EVENT: "PDU-SESSION-RELEASE-REQUEST-EVENT", + PDU_SESS_REL_REJECT_EVENT: "PDU-SESSION-RELEASE-REJECT-EVENT", + PDU_SESS_REL_COMMAND_EVENT: "PDU-SESSION-RELEASE-COMMAND-EVENT", + PDU_SESS_REL_COMPLETE_EVENT: "PDU-SESSION-RELEASE-COMPLETE-EVENT", + PDU_SESS_RESOURCE_RELEASE_COMMAND_EVENT: "PDU-SESSION-RESOURCE-RELEASE-COMMAND-EVENT", + FIVEGSM_STATUS_EVENT: "FIVEGSM-STATUS-EVENT", + DOWNLINK_NAS_TRANSPORT_EVENT: "DOWNLINK-NAS-TRANSPORT-EVENT", + INITIAL_CTX_SETUP_REQUEST_EVENT: "INITIAL-CONTEXT-SETUP-REQUEST-EVENT", + PDU_SESS_RESOURCE_SETUP_REQUEST_EVENT: "PDU-SESSION-RESOURCE-SETUP-REQUEST-EVENT", + UE_CTX_RELEASE_COMMAND_EVENT: "UE-CONTEXT-RELEASE-COMMAND-EVENT", + DL_UE_DATA_TRANSPORT_EVENT: "DL-UE-DATA-TRANSPORT-EVENT", } func (id EventType) String() string { evtStr, ok := evtStrMap[id] if !ok { - logger.AppLog.Fatalln("Invaid Event ID:", id) + logger.AppLog.Fatalf("Invalid Event ID: %#v", id) } return evtStr } diff --git a/common/procedures.go b/common/procedures.go index 9051c5e0..8e718e86 100644 --- a/common/procedures.go +++ b/common/procedures.go @@ -11,6 +11,7 @@ type ProcedureType uint8 const ( REGISTRATION_PROCEDURE ProcedureType = 1 + iota PDU_SESSION_ESTABLISHMENT_PROCEDURE + UE_REQUESTED_PDU_SESSION_RELEASE_PROCEDURE USER_DATA_PKT_GENERATION_PROCEDURE UE_INITIATED_DEREGISTRATION_PROCEDURE AN_RELEASE_PROCEDURE @@ -20,20 +21,21 @@ const ( ) var procStrMap = map[ProcedureType]string{ - REGISTRATION_PROCEDURE: "REGISTRATION-PROCEDURE", - PDU_SESSION_ESTABLISHMENT_PROCEDURE: "PDU-SESSION-ESTABLISHMENT-PROCEDURE", - USER_DATA_PKT_GENERATION_PROCEDURE: "USER-DATA-PACKET-GENERATION-PROCEDURE", - UE_INITIATED_DEREGISTRATION_PROCEDURE: "UE-INITIATED-DEREGISTRATION-PROCEDURE", - AN_RELEASE_PROCEDURE: "AN-RELEASE-PROCEDURE", - UE_TRIGGERED_SERVICE_REQUEST_PROCEDURE: "UE-TRIGGERED-SERVICE-REQUEST-PROCEDURE", - NW_TRIGGERED_UE_DEREGISTRATION_PROCEDURE: "NW-TRIGGERED-UE-DEREGISTRATION-PROCEDURE", - AMF_RELEASE_PROCEDURE: "AMF_RELEASE_PROCEDURE", + REGISTRATION_PROCEDURE: "REGISTRATION-PROCEDURE", + PDU_SESSION_ESTABLISHMENT_PROCEDURE: "PDU-SESSION-ESTABLISHMENT-PROCEDURE", + USER_DATA_PKT_GENERATION_PROCEDURE: "USER-DATA-PACKET-GENERATION-PROCEDURE", + UE_INITIATED_DEREGISTRATION_PROCEDURE: "UE-INITIATED-DEREGISTRATION-PROCEDURE", + AN_RELEASE_PROCEDURE: "AN-RELEASE-PROCEDURE", + UE_TRIGGERED_SERVICE_REQUEST_PROCEDURE: "UE-TRIGGERED-SERVICE-REQUEST-PROCEDURE", + NW_TRIGGERED_UE_DEREGISTRATION_PROCEDURE: "NW-TRIGGERED-UE-DEREGISTRATION-PROCEDURE", + AMF_RELEASE_PROCEDURE: "AMF-RELEASE-PROCEDURE", + UE_REQUESTED_PDU_SESSION_RELEASE_PROCEDURE: "UE-REQUESTED-PDU-SESSION-RELEASE-PROCEDURE", } func (id ProcedureType) String() string { procStr, ok := procStrMap[id] if !ok { - logger.AppLog.Fatalln("Invalid Procedure ID:", id) + logger.AppLog.Fatalf("Invalid Procedure ID: %#v", id) } return procStr } diff --git a/config/gnbsim.yaml b/config/gnbsim.yaml index e1d58499..bdaf0ab5 100644 --- a/config/gnbsim.yaml +++ b/config/gnbsim.yaml @@ -93,6 +93,15 @@ configuration: plmnId: # Public Land Mobile Network ID, = . Should match startImsi mcc: 208 # Mobile Country Code (3 digits string, digit: 0~9) mnc: 93 # Mobile Network Code (2 or 3 digits string, digit: 0~9) + - profileType: uereqpdusessrelease # profile type + profileName: profile7 # uniqely identifies a profile within application + enable: false # Set true to execute the profile, false otherwise. + gnbName: gnb1 # gNB to be used for this profile + startImsi: 208930100007497 # First IMSI. Subsequent values will be used if ueCount is more than 1 + ueCount: 5 # Number of UEs for for which the profile will be executed + plmnId: # Public Land Mobile Network ID, = . Should match startImsi + mcc: 208 # Mobile Country Code (3 digits string, digit: 0~9) + mnc: 93 # Mobile Network Code (2 or 3 digits string, digit: 0~9) logger: logLevel: info # how detailed the log will be, values: trace, debug, info, warn, error, fatal, panic diff --git a/gnodeb/context/gnbcpue.go b/gnodeb/context/gnbcpue.go index d711832d..5609a36a 100644 --- a/gnodeb/context/gnbcpue.go +++ b/gnodeb/context/gnbcpue.go @@ -5,6 +5,7 @@ package context import ( + "fmt" "sync" "github.com/omec-project/gnbsim/common" @@ -48,14 +49,13 @@ func NewGnbCpUe(ngapId int64, gnb *GNodeB, amf *GnbAmf) *GnbCpUe { } // GetGnbUpUe returns the GnbUpUe instance corresponding to provided PDU Sess ID -func (ctx *GnbCpUe) GetGnbUpUe(pduSessId int64) *GnbUpUe { +func (ctx *GnbCpUe) GetGnbUpUe(pduSessId int64) (*GnbUpUe, error) { ctx.Log.Infoln("Fetching GnbUpUe for pduSessId:", pduSessId) val, ok := ctx.GnbUpUes.Load(pduSessId) if ok { - return val.(*GnbUpUe) + return val.(*GnbUpUe), nil } else { - ctx.Log.Errorln("key not present:", pduSessId) - return nil + return nil, fmt.Errorf("key not present: %v", pduSessId) } } diff --git a/gnodeb/gnodeb.go b/gnodeb/gnodeb.go index ec4b7297..727c4885 100644 --- a/gnodeb/gnodeb.go +++ b/gnodeb/gnodeb.go @@ -130,7 +130,10 @@ func RequestConnection(gnb *gnbctx.GNodeB, uemsg *common.UuMessage) (chan common // TODO: Launching a GO Routine for gNB and handling the waitgroup var wg sync.WaitGroup wg.Add(1) - go gnbcpueworker.Init(gnbUe, &wg) + go func() { + defer wg.Done() + gnbcpueworker.Init(gnbUe) + }() //Channel on which UE can write message to GnbUe and from which GnbUe will //be reading. ch := gnbUe.ReadChan diff --git a/gnodeb/transport/cptransport.go b/gnodeb/transport/cptransport.go index e596e4c6..60e54ccb 100644 --- a/gnodeb/transport/cptransport.go +++ b/gnodeb/transport/cptransport.go @@ -164,7 +164,7 @@ func (cpTprt *GnbCpTransport) ReceiveFromPeer(peer transportcommon.TransportPeer } } - cpTprt.Log.Infof("Read %v bytes from %v\n", n, conn) + cpTprt.Log.Infof("Read %v bytes from %v\n", n, amf.GetIpAddr()) //TODO Post to gnbamfworker channel gnbamfworker.HandleMessage(cpTprt.GnbInstance, amf, recvMsg[:n]) } diff --git a/gnodeb/worker/gnbamfworker/handler.go b/gnodeb/worker/gnbamfworker/handler.go index e546bc58..090eedd6 100644 --- a/gnodeb/worker/gnbamfworker/handler.go +++ b/gnodeb/worker/gnbamfworker/handler.go @@ -191,6 +191,7 @@ func HandleNgSetupFailure(amf *gnbctx.GnbAmf, pdu *ngapType.NGAPPDU) { amf.Log.Errorln("Cause is nil") return } + break } // TODO handle TimeToWait IE } @@ -216,7 +217,7 @@ func HandleDownlinkNasTransport(gnb *gnbctx.GNodeB, amf *gnbctx.GnbAmf, return } if gnb == nil { - amf.Log.Errorln("GNodeB Message is nil") + amf.Log.Errorln("gNodeB context is nil") return } initiatingMessage := pdu.InitiatingMessage @@ -240,6 +241,7 @@ func HandleDownlinkNasTransport(gnb *gnbctx.GNodeB, amf *gnbctx.GnbAmf, amf.Log.Errorln("RANUENGAPID is nil") return } + break } } ngapId := gnbUeNgapId.Value @@ -267,7 +269,7 @@ func HandleInitialContextSetupRequest(gnb *gnbctx.GNodeB, amf *gnbctx.GnbAmf, return } if gnb == nil { - amf.Log.Errorln("GNodeB Message is nil") + amf.Log.Errorln("gNodeB context is nil") return } initiatingMessage := pdu.InitiatingMessage @@ -290,6 +292,7 @@ func HandleInitialContextSetupRequest(gnb *gnbctx.GNodeB, amf *gnbctx.GnbAmf, amf.Log.Errorln("RANUENGAPID is nil") return } + break } } ngapId := gnbUeNgapId.Value @@ -317,7 +320,7 @@ func HandlePduSessResourceSetupRequest(gnb *gnbctx.GNodeB, amf *gnbctx.GnbAmf, return } if gnb == nil { - amf.Log.Errorln("GNodeB Message is nil") + amf.Log.Errorln("gNodeB context is nil") return } initiatingMessage := pdu.InitiatingMessage @@ -327,11 +330,10 @@ func HandlePduSessResourceSetupRequest(gnb *gnbctx.GNodeB, amf *gnbctx.GnbAmf, } pduSessResourceSetupReq := initiatingMessage.Value.PDUSessionResourceSetupRequest if pduSessResourceSetupReq == nil { - amf.Log.Errorln("InitialContextSetupRequest is nil") + amf.Log.Errorln("PDUSessionResourceSetupRequest is nil") return } - amf.Log.Traceln("InitialContextSetupRequest") for _, ie := range pduSessResourceSetupReq.ProtocolIEs.List { if ie.Id.Value == ngapType.ProtocolIEIDRANUENGAPID { gnbUeNgapId = ie.Value.RANUENGAPID @@ -340,6 +342,7 @@ func HandlePduSessResourceSetupRequest(gnb *gnbctx.GNodeB, amf *gnbctx.GnbAmf, amf.Log.Errorln("RANUENGAPID is nil") return } + break } } ngapId := gnbUeNgapId.Value @@ -352,6 +355,55 @@ func HandlePduSessResourceSetupRequest(gnb *gnbctx.GNodeB, amf *gnbctx.GnbAmf, SendToGnbUe(gnbue, common.PDU_SESS_RESOURCE_SETUP_REQUEST_EVENT, pdu) } +func HandlePduSessResourceReleaseCommand(gnb *gnbctx.GNodeB, amf *gnbctx.GnbAmf, + pdu *ngapType.NGAPPDU) { + amf.Log.Traceln("Processing Pdu Session Resource Release Command") + var gnbUeNgapId *ngapType.RANUENGAPID + + if amf == nil { + amf.Log.Errorln("ran is nil") + return + } + if pdu == nil { + amf.Log.Errorln("NGAP Message is nil") + return + } + if gnb == nil { + amf.Log.Errorln("gNodeB context is nil") + return + } + initiatingMessage := pdu.InitiatingMessage + if initiatingMessage == nil { + amf.Log.Errorln("Initiating Message is nil") + return + } + pduSessResourceReleaseCmd := initiatingMessage.Value.PDUSessionResourceReleaseCommand + if pduSessResourceReleaseCmd == nil { + amf.Log.Errorln("PDUSessionResourceReleaseCommand is nil") + return + } + + for _, ie := range pduSessResourceReleaseCmd.ProtocolIEs.List { + if ie.Id.Value == ngapType.ProtocolIEIDRANUENGAPID { + gnbUeNgapId = ie.Value.RANUENGAPID + amf.Log.Traceln("Decode IE RANUENGAPID") + if gnbUeNgapId == nil { + amf.Log.Errorln("RANUENGAPID is nil") + return + } + break + } + } + ngapId := gnbUeNgapId.Value + gnbue := gnb.GnbUes.GetGnbCpUe(ngapId) + if gnbue == nil { + amf.Log.Errorln("No GnbUe found corresponding to RANUENGAPID:") + return + } + + SendToGnbUe(gnbue, common.PDU_SESS_RESOURCE_RELEASE_COMMAND_EVENT, pdu) +} + func HandleUeCtxReleaseCommand(gnb *gnbctx.GNodeB, amf *gnbctx.GnbAmf, pdu *ngapType.NGAPPDU) { @@ -365,7 +417,7 @@ func HandleUeCtxReleaseCommand(gnb *gnbctx.GNodeB, amf *gnbctx.GnbAmf, return } if gnb == nil { - amf.Log.Errorln("GNodeB Message is nil") + amf.Log.Errorln("gNodeB context is nil") return } @@ -392,6 +444,7 @@ func HandleUeCtxReleaseCommand(gnb *gnbctx.GNodeB, amf *gnbctx.GnbAmf, amf.Log.Errorln("UENGAPIDs is nil") return } + break } } diff --git a/gnodeb/worker/gnbamfworker/worker.go b/gnodeb/worker/gnbamfworker/worker.go index 8728d326..31812d99 100644 --- a/gnodeb/worker/gnbamfworker/worker.go +++ b/gnodeb/worker/gnbamfworker/worker.go @@ -38,6 +38,8 @@ func HandleMessage(gnb *gnbctx.GNodeB, amf *gnbctx.GnbAmf, pkt []byte) error { HandleInitialContextSetupRequest(gnb, amf, pdu) case ngapType.ProcedureCodePDUSessionResourceSetup: HandlePduSessResourceSetupRequest(gnb, amf, pdu) + case ngapType.ProcedureCodePDUSessionResourceRelease: + HandlePduSessResourceReleaseCommand(gnb, amf, pdu) case ngapType.ProcedureCodeUEContextRelease: HandleUeCtxReleaseCommand(gnb, amf, pdu) } diff --git a/gnodeb/worker/gnbcpueworker/handler.go b/gnodeb/worker/gnbcpueworker/handler.go index eeed5fac..551c9962 100644 --- a/gnodeb/worker/gnbcpueworker/handler.go +++ b/gnodeb/worker/gnbcpueworker/handler.go @@ -234,6 +234,91 @@ func HandlePduSessResourceSetupRequest(gnbue *gnbctx.GnbCpUe, common.PDU_SESS_RESOURCE_SETUP_REQUEST_EVENT) } +// TODO: Error handling +func HandlePduSessResourceReleaseCommand(gnbue *gnbctx.GnbCpUe, + intfcMsg common.InterfaceMessage) { + + msg := intfcMsg.(*common.N2Message) + var amfUeNgapId *ngapType.AMFUENGAPID + var pduSessResourceToReleaseList *ngapType.PDUSessionResourceToReleaseListRelCmd + var nasPdu *ngapType.NASPDU + + pdu := msg.NgapPdu + + initiatingMessage := pdu.InitiatingMessage + pduSessResourceReleaseCmd := initiatingMessage.Value.PDUSessionResourceReleaseCommand + + for _, ie := range pduSessResourceReleaseCmd.ProtocolIEs.List { + switch ie.Id.Value { + case ngapType.ProtocolIEIDAMFUENGAPID: + amfUeNgapId = ie.Value.AMFUENGAPID + if amfUeNgapId == nil { + gnbue.Log.Errorln("AMFUENGAPID is nil") + return + } + case ngapType.ProtocolIEIDPDUSessionResourceToReleaseListRelCmd: + pduSessResourceToReleaseList = ie.Value.PDUSessionResourceToReleaseListRelCmd + if pduSessResourceToReleaseList == nil || len(pduSessResourceToReleaseList.List) == 0 { + gnbue.Log.Errorln("PDUSessionResourceToReleaseListRelCmd is empty") + return + } + case ngapType.ProtocolIEIDNASPDU: + nasPdu = ie.Value.NASPDU + if nasPdu == nil { + gnbue.Log.Errorln("NASPDU is nil") + return + } + } + } + + for _, item := range pduSessResourceToReleaseList.List { + resourceReleaseCmdTransfer := ngapType.PDUSessionResourceReleaseCommandTransfer{} + err := aper.UnmarshalWithParams(item.PDUSessionResourceReleaseCommandTransfer, + &resourceReleaseCmdTransfer, "valueExt") + if err != nil { + gnbue.Log.Errorln("UnmarshalWithParams returned:", err) + return + } + + pduSessId := item.PDUSessionID.Value + _, cause := test.PrintAndGetCause(&resourceReleaseCmdTransfer.Cause) + gnbue.Log.Infoln("PDU Session Resource Release Command PDU Session ID:", + pduSessId) + gnbue.Log.Infoln("PDU Session Resource Release Command Cause:", cause) + + upCtx, err := gnbue.GetGnbUpUe(pduSessId) + if err != nil { + gnbue.Log.Errorln("Failed to fetch PDU session context:", err) + return + } + terminateUpUeContext(upCtx) + gnbue.RemoveGnbUpUe(pduSessId) + } + + if nasPdu.Value != nil { + var pdus common.NasPduList + pdus = append(pdus, nasPdu.Value) + SendToUe(gnbue, common.DL_INFO_TRANSFER_EVENT, pdus) + gnbue.Log.Traceln("Sent DL Information Transfer Event to UE") + } + + ngapPdu, err := test.GetPDUSessionResourceReleaseResponse(gnbue.AmfUeNgapId, + gnbue.GnbUeNgapId) + if err != nil { + gnbue.Log.Errorln("Failed to create PDU Session Resource Release Response:", err) + return + } + + err = gnbue.Gnb.CpTransport.SendToPeer(gnbue.Amf, ngapPdu) + if err != nil { + gnbue.Log.Errorln("SendToPeer failed:", err) + return + } + gnbue.Log.Traceln("Sent PDU Session Resource Setup Response Message to AMF") + + SendToUe(gnbue, common.DATA_BEARER_RELEASE_REQUEST_EVENT, nil) +} + func HandleDataBearerSetupResponse(gnbue *gnbctx.GnbCpUe, intfcMsg common.InterfaceMessage) { @@ -244,14 +329,20 @@ func HandleDataBearerSetupResponse(gnbue *gnbctx.GnbCpUe, if !pduSess.Success { gnbue.RemoveGnbUpUe(pduSess.PduSessId) } else { - gnbUpUe := gnbue.GetGnbUpUe(pduSess.PduSessId) + gnbUpUe, err := gnbue.GetGnbUpUe(pduSess.PduSessId) + if err != nil { + gnbue.Log.Errorln("Failed to fetch PDU session context:", err) + } // TODO: Addition to this map should only be through GnbUpfWorker // routine. This will help in replacing sync map with normal map // Thus will help avoid lock unlock operation on per downlink message gnbUpUe.Upf.GnbUpUes.AddGnbUpUe(gnbUpUe.DlTeid, true, gnbUpUe) gnbUpUe.WriteUeChan = item.CommChan gnbue.WaitGrp.Add(1) - go gnbupueworker.Init(gnbUpUe, &gnbue.WaitGrp) + go func() { + defer gnbue.WaitGrp.Done() + gnbupueworker.Init(gnbUpUe) + }() } pduSessions = append(pduSessions, pduSess) } @@ -510,21 +601,24 @@ func ProcessPduSessResourceSetupList(gnbue *gnbctx.GnbCpUe, } func HandleQuitEvent(gnbue *gnbctx.GnbCpUe, intfcMsg common.InterfaceMessage) { - releaseUpUeContexts(gnbue) + terminateUpUeContexts(gnbue) gnbue.Gnb.RanUeNGAPIDGenerator.FreeID(gnbue.GnbUeNgapId) gnbue.WaitGrp.Wait() gnbue.Log.Infoln("gNB Control-Plane UE context terminated") } -func releaseUpUeContexts(gnbue *gnbctx.GnbCpUe) { +func terminateUpUeContexts(gnbue *gnbctx.GnbCpUe) { f := func(key, value interface{}) bool { - ctx := value.(*gnbctx.GnbUpUe) - msg := &common.DefaultMessage{} - msg.Event = common.QUIT_EVENT - ctx.ReadCmdChan <- msg - ctx.Upf.GnbUpUes.RemoveGnbUpUe(ctx.DlTeid, true) + terminateUpUeContext(value.(*gnbctx.GnbUpUe)) return true } gnbue.GnbUpUes.Range(f) gnbue.GnbUpUes = sync.Map{} } + +func terminateUpUeContext(upCtx *gnbctx.GnbUpUe) { + msg := &common.DefaultMessage{} + msg.Event = common.QUIT_EVENT + upCtx.ReadCmdChan <- msg + upCtx.Upf.GnbUpUes.RemoveGnbUpUe(upCtx.DlTeid, true) +} diff --git a/gnodeb/worker/gnbcpueworker/worker.go b/gnodeb/worker/gnbcpueworker/worker.go index 37fb32e5..239d8da2 100644 --- a/gnodeb/worker/gnbcpueworker/worker.go +++ b/gnodeb/worker/gnbcpueworker/worker.go @@ -5,15 +5,12 @@ package gnbcpueworker import ( - "sync" - "github.com/omec-project/gnbsim/common" gnbctx "github.com/omec-project/gnbsim/gnodeb/context" ) -func Init(gnbue *gnbctx.GnbCpUe, wg *sync.WaitGroup) { +func Init(gnbue *gnbctx.GnbCpUe) { HandleEvents(gnbue) - wg.Done() } func HandleEvents(gnbue *gnbctx.GnbCpUe) (err error) { @@ -37,6 +34,8 @@ func HandleEvents(gnbue *gnbctx.GnbCpUe) (err error) { HandleInitialContextSetupRequest(gnbue, msg) case common.PDU_SESS_RESOURCE_SETUP_REQUEST_EVENT: HandlePduSessResourceSetupRequest(gnbue, msg) + case common.PDU_SESS_RESOURCE_RELEASE_COMMAND_EVENT: + HandlePduSessResourceReleaseCommand(gnbue, msg) case common.UE_CTX_RELEASE_COMMAND_EVENT: HandleUeCtxReleaseCommand(gnbue, msg) case common.TRIGGER_AN_RELEASE_EVENT: diff --git a/gnodeb/worker/gnbupueworker/worker.go b/gnodeb/worker/gnbupueworker/worker.go index 91052ad9..3d9b538d 100644 --- a/gnodeb/worker/gnbupueworker/worker.go +++ b/gnodeb/worker/gnbupueworker/worker.go @@ -5,15 +5,12 @@ package gnbupueworker import ( - "sync" - "github.com/omec-project/gnbsim/common" gnbctx "github.com/omec-project/gnbsim/gnodeb/context" ) -func Init(gnbue *gnbctx.GnbUpUe, wg *sync.WaitGroup) { +func Init(gnbue *gnbctx.GnbUpUe) { HandleEvents(gnbue) - wg.Done() } func HandleEvents(gnbue *gnbctx.GnbUpUe) { diff --git a/profile/profile.go b/profile/profile.go index 5d0eea74..f3ae3dd9 100644 --- a/profile/profile.go +++ b/profile/profile.go @@ -6,15 +6,16 @@ package profile import ( "fmt" + "strconv" + "sync" + "time" + "github.com/omec-project/gnbsim/common" "github.com/omec-project/gnbsim/factory" profctx "github.com/omec-project/gnbsim/profile/context" "github.com/omec-project/gnbsim/profile/util" "github.com/omec-project/gnbsim/simue" simuectx "github.com/omec-project/gnbsim/simue/context" - "strconv" - "sync" - "time" ) //profile names @@ -25,6 +26,7 @@ const ( AN_RELEASE string = "anrelease" UE_TRIGG_SERVICE_REQ string = "uetriggservicereq" NW_TRIGG_UE_DEREG_REQ string = "nwtriggeruedereg" + UE_REQ_PDU_SESS_REL string = "uereqpdusessrelease" ) func InitializeAllProfiles() { @@ -120,6 +122,18 @@ func initEventMap(profile *profctx.Profile) { common.PDU_SESS_EST_ACCEPT_EVENT: common.PDU_SESS_EST_ACCEPT_EVENT, common.PROFILE_PASS_EVENT: common.QUIT_EVENT, } + case UE_REQ_PDU_SESS_REL: + profile.Events = map[common.EventType]common.EventType{ + common.REG_REQUEST_EVENT: common.AUTH_REQUEST_EVENT, + common.AUTH_REQUEST_EVENT: common.AUTH_RESPONSE_EVENT, + common.SEC_MOD_COMMAND_EVENT: common.SEC_MOD_COMPLETE_EVENT, + common.REG_ACCEPT_EVENT: common.REG_COMPLETE_EVENT, + common.PDU_SESS_EST_REQUEST_EVENT: common.PDU_SESS_EST_ACCEPT_EVENT, + common.PDU_SESS_EST_ACCEPT_EVENT: common.PDU_SESS_EST_ACCEPT_EVENT, + common.PDU_SESS_REL_REQUEST_EVENT: common.PDU_SESS_REL_COMMAND_EVENT, + common.PDU_SESS_REL_COMMAND_EVENT: common.PDU_SESS_REL_COMPLETE_EVENT, + common.PROFILE_PASS_EVENT: common.QUIT_EVENT, + } case DEREGISTER: profile.Events = map[common.EventType]common.EventType{ common.REG_REQUEST_EVENT: common.AUTH_REQUEST_EVENT, @@ -208,7 +222,13 @@ func initProcedureList(profile *profctx.Profile) { common.PDU_SESSION_ESTABLISHMENT_PROCEDURE, common.USER_DATA_PKT_GENERATION_PROCEDURE, common.NW_TRIGGERED_UE_DEREGISTRATION_PROCEDURE, - common.AMF_RELEASE_PROCEDURE, + } + case UE_REQ_PDU_SESS_REL: + profile.Procedures = []common.ProcedureType{ + common.REGISTRATION_PROCEDURE, + common.PDU_SESSION_ESTABLISHMENT_PROCEDURE, + common.USER_DATA_PKT_GENERATION_PROCEDURE, + common.UE_REQUESTED_PDU_SESSION_RELEASE_PROCEDURE, } } } diff --git a/realue/context/pdusession.go b/realue/context/pdusession.go index d3538cf2..1bbf6186 100644 --- a/realue/context/pdusession.go +++ b/realue/context/pdusession.go @@ -22,7 +22,7 @@ type PduSession struct { /* Number of UL data packets to be transmitted as requested by Sim UE*/ SscMode uint8 PktCount int - PduSessId uint64 + PduSessId int64 Snssai models.Snssai PduSessType models.PduSessionType PduAddress net.IP @@ -49,7 +49,7 @@ type PduSession struct { Log *logrus.Entry } -func NewPduSession(realUe *RealUe, pduSessId uint64) *PduSession { +func NewPduSession(realUe *RealUe, pduSessId int64) *PduSession { pduSess := PduSession{} pduSess.PduSessId = pduSessId pduSess.ReadDlChan = make(chan common.InterfaceMessage, 10) diff --git a/realue/context/realue.go b/realue/context/realue.go index 70f67713..d0f10936 100644 --- a/realue/context/realue.go +++ b/realue/context/realue.go @@ -7,6 +7,7 @@ package context import ( "encoding/hex" + "fmt" "regexp" "sync" @@ -234,14 +235,13 @@ func (ue *RealUe) Get5GMMCapability() (capability5GMM *nasType.Capability5GMM) { } // GetPduSession returns the PduSession instance corresponding to provided PDU Sess ID -func (ctx *RealUe) GetPduSession(pduSessId int64) *PduSession { +func (ctx *RealUe) GetPduSession(pduSessId int64) (*PduSession, error) { ctx.Log.Infoln("Fetching PDU Session for pduSessId:", pduSessId) val, ok := ctx.PduSessions[pduSessId] if ok { - return val + return val, nil } else { - ctx.Log.Errorln("key not present:", pduSessId) - return nil + return nil, fmt.Errorf("key not present: %v", pduSessId) } } diff --git a/realue/handler.go b/realue/handler.go index b975b961..8c32debb 100644 --- a/realue/handler.go +++ b/realue/handler.go @@ -25,8 +25,9 @@ import ( //TODO Remove the hardcoding const ( - SN_NAME string = "5G:mnc093.mcc208.3gppnetwork.org" - SWITCH_OFF uint8 = 0 + SN_NAME string = "5G:mnc093.mcc208.3gppnetwork.org" + SWITCH_OFF uint8 = 0 + REQUEST_TYPE_EXISTING_PDU_SESS uint8 = 0x02 ) func HandleRegRequestEvent(ue *realuectx.RealUe, @@ -205,7 +206,7 @@ func HandlePduSessEstAcceptEvent(ue *realuectx.RealUe, pduAddr = net.IPv4(ip[0], ip[1], ip[2], ip[3]) } - pduSess := realuectx.NewPduSession(ue, uint64(nasMsg.PDUSessionID.Octet)) + pduSess := realuectx.NewPduSession(ue, int64(nasMsg.PDUSessionID.Octet)) pduSess.PduSessType = pduSessType pduSess.SscMode = nasMsg.GetSSCMode() pduSess.PduAddress = pduAddr @@ -219,6 +220,60 @@ func HandlePduSessEstAcceptEvent(ue *realuectx.RealUe, return nil } +func HandlePduSessReleaseRequestEvent(ue *realuectx.RealUe, + msg common.InterfaceMessage) (err error) { + + nasPdu := nasTestpacket.GetUlNasTransport_PduSessionReleaseRequest(10) + + nasPdu, err = realue_nas.EncodeNasPduWithSecurity(ue, nasPdu, + nas.SecurityHeaderTypeIntegrityProtectedAndCiphered, true) + if err != nil { + fmt.Println("Failed to encrypt PDU Session Release Request Message", err) + return + } + + m := formUuMessage(common.PDU_SESS_REL_REQUEST_EVENT, nasPdu) + SendToSimUe(ue, m) + return nil +} + +func HandlePduSessReleaseCompleteEvent(ue *realuectx.RealUe, + intfcMsg common.InterfaceMessage) (err error) { + + msg := intfcMsg.(*common.UeMessage) + nasMsg := msg.NasMsg.PDUSessionReleaseCommand + if nasMsg == nil { + ue.Log.Errorln("PDUSessionReleaseCommand is nil") + return fmt.Errorf("invalid NAS Message") + } + + pduSessId := nasMsg.PDUSessionID.Octet + ue.Log.Infoln("PDU Session Release Command, PDU Session ID:", pduSessId) + + pduSess, err := ue.GetPduSession(int64(pduSessId)) + if err != nil { + return fmt.Errorf("failed to fetch PDU session:%v", err) + } + + quitMsg := &common.UeMessage{} + quitMsg.Event = common.QUIT_EVENT + pduSess.ReadCmdChan <- quitMsg + + nasPdu := nasTestpacket.GetUlNasTransport_PduSessionReleaseComplete(pduSessId, + REQUEST_TYPE_EXISTING_PDU_SESS, "", nil) + + nasPdu, err = realue_nas.EncodeNasPduWithSecurity(ue, nasPdu, + nas.SecurityHeaderTypeIntegrityProtectedAndCiphered, true) + if err != nil { + fmt.Println("Failed to encrypt PDU Session Release Request Message", err) + return + } + + m := formUuMessage(common.PDU_SESS_REL_COMPLETE_EVENT, nasPdu) + SendToSimUe(ue, m) + return nil +} + func HandleDataBearerSetupRequestEvent(ue *realuectx.RealUe, intfcMsg common.InterfaceMessage) (err error) { @@ -231,8 +286,9 @@ func HandleDataBearerSetupRequestEvent(ue *realuectx.RealUe, PDUSession Resource Setup/Failed To Setup Response list */ if item.PduSess.Success { - pduSess := ue.GetPduSession(item.PduSess.PduSessId) - if pduSess == nil { + pduSess, err := ue.GetPduSession(item.PduSess.PduSessId) + if err != nil { + ue.Log.Warnln("Failed to fetch PDU Session:", err) item.PduSess.Success = false continue } @@ -358,14 +414,14 @@ func HandleServiceRequestEvent(ue *realuectx.RealUe, nasPdu, err := realue_nas.GetServiceRequest(ue) if err != nil { - return fmt.Errorf("failed to handle service request event:", err) + return fmt.Errorf("failed to handle service request event: %v", err) } // TS 24.501 Section 4.4.6 - Protection of Initial NAS signalling messages nasPdu, err = realue_nas.EncodeNasPduWithSecurity(ue, nasPdu, nas.SecurityHeaderTypeIntegrityProtected, true) if err != nil { - return fmt.Errorf("failed to encode with security:", err) + return fmt.Errorf("failed to encode with security: %v", err) } m := formUuMessage(common.SERVICE_REQUEST_EVENT, nasPdu) @@ -373,7 +429,7 @@ func HandleServiceRequestEvent(ue *realuectx.RealUe, return nil } -func HandleDeregAcceptEvent(ue *realuectx.RealUe, msg common.InterfaceMessage) (err error) { +func HandleNwDeregAcceptEvent(ue *realuectx.RealUe, msg common.InterfaceMessage) (err error) { ue.Log.Traceln("Generating Dereg Accept Message") nasPdu := nasTestpacket.GetDeregistrationAccept() diff --git a/realue/realue.go b/realue/realue.go index 959e3a99..a43fa1c5 100644 --- a/realue/realue.go +++ b/realue/realue.go @@ -42,6 +42,10 @@ func HandleEvents(ue *realuectx.RealUe) (err error) { err = HandleDlInfoTransferEvent(ue, msg) case common.PDU_SESS_EST_REQUEST_EVENT: err = HandlePduSessEstRequestEvent(ue, msg) + case common.PDU_SESS_REL_REQUEST_EVENT: + err = HandlePduSessReleaseRequestEvent(ue, msg) + case common.PDU_SESS_REL_COMPLETE_EVENT: + err = HandlePduSessReleaseCompleteEvent(ue, msg) case common.PDU_SESS_EST_ACCEPT_EVENT: err = HandlePduSessEstAcceptEvent(ue, msg) case common.DATA_BEARER_SETUP_REQUEST_EVENT: @@ -55,7 +59,7 @@ func HandleEvents(ue *realuectx.RealUe) (err error) { case common.CONNECTION_RELEASE_REQUEST_EVENT: err = HandleConnectionReleaseRequestEvent(ue, msg) case common.DEREG_ACCEPT_UE_TERM_EVENT: - err = HandleDeregAcceptEvent(ue, msg) + err = HandleNwDeregAcceptEvent(ue, msg) case common.ERROR_EVENT: HandleErrorEvent(ue, msg) case common.QUIT_EVENT: diff --git a/simue/handler.go b/simue/handler.go index ef5d55b8..f7794585 100644 --- a/simue/handler.go +++ b/simue/handler.go @@ -208,6 +208,44 @@ func HandlePduSessEstRejectEvent(ue *simuectx.SimUe, return nil } +func HandlePduSessReleaseRequestEvent(ue *simuectx.SimUe, + intfcMsg common.InterfaceMessage) (err error) { + + msg := intfcMsg.(*common.UuMessage) + msg.Event = common.UL_INFO_TRANSFER_EVENT + SendToGnbUe(ue, msg) + return nil +} + +func HandlePduSessReleaseCommandEvent(ue *simuectx.SimUe, + intfcMsg common.InterfaceMessage) (err error) { + + msg := intfcMsg.(*common.UeMessage) + err = ue.ProfileCtx.CheckCurrentEvent(common.PDU_SESS_REL_REQUEST_EVENT, msg.Event) + if err != nil { + ue.Log.Errorln("CheckCurrentEvent returned:", err) + return err + } + nextEvent, err := ue.ProfileCtx.GetNextEvent(msg.Event) + if err != nil { + ue.Log.Errorln("GetNextEvent returned:", err) + return err + } + ue.Log.Infoln("Next Event:", nextEvent) + msg.Event = nextEvent + SendToRealUe(ue, msg) + return nil +} + +func HandlePduSessReleaseCompleteEvent(ue *simuectx.SimUe, + intfcMsg common.InterfaceMessage) (err error) { + + msg := intfcMsg.(*common.UuMessage) + msg.Event = common.UL_INFO_TRANSFER_EVENT + SendToGnbUe(ue, msg) + return nil +} + func HandleDlInfoTransferEvent(ue *simuectx.SimUe, msg common.InterfaceMessage) (err error) { @@ -231,6 +269,17 @@ func HandleDataBearerSetupResponseEvent(ue *simuectx.SimUe, return nil } +func HandleDataBearerReleaseRequestEvent(ue *simuectx.SimUe, + msg common.InterfaceMessage) (err error) { + // This event is sent by gNB component after it has sent + // PDU Session Resource Release Complete over N2, However the PDU Sesson + // routines in the RealUE will be terminated while processing PDU Session + // Release Complete which will also release the communication links + // (go channels) with the gNB + ChangeProcedure(ue) + return nil +} + func HandleDataPktGenSuccessEvent(ue *simuectx.SimUe, intfcMsg common.InterfaceMessage) (err error) { @@ -250,7 +299,7 @@ func HandleServiceRequestEvent(ue *simuectx.SimUe, err = ConnectToGnb(ue) if err != nil { - return fmt.Errorf("failed to connect gnb:", err) + return fmt.Errorf("failed to connect gnb %v:", err) } SendToGnbUe(ue, intfcMsg) @@ -287,7 +336,7 @@ func HandleConnectionReleaseRequestEvent(ue *simuectx.SimUe, ue.WriteGnbUeChan = nil if msg.TriggeringEvent == common.DEREG_REQUEST_UE_ORIG_EVENT { - msg := &common.UuMessage{} + msg := &common.UeMessage{} msg.Event = common.QUIT_EVENT ue.ReadChan <- msg // Once UE is deregistered, Sim UE is not expecting any further @@ -333,7 +382,6 @@ func HandleNwDeregAcceptEvent(ue *simuectx.SimUe, intfcMsg common.InterfaceMessa msg.Event = common.UL_INFO_TRANSFER_EVENT SendToGnbUe(ue, msg) ue.Log.Traceln("Sent Dereg Accept to the network") - ChangeProcedure(ue) return nil } @@ -393,6 +441,11 @@ func HandleProcedure(ue *simuectx.SimUe) { msg := &common.UeMessage{} msg.Event = common.PDU_SESS_EST_REQUEST_EVENT SendToRealUe(ue, msg) + case common.UE_REQUESTED_PDU_SESSION_RELEASE_PROCEDURE: + ue.Log.Infoln("Initiating UE Requested PDU Session Release Procedure") + msg := &common.UeMessage{} + msg.Event = common.PDU_SESS_REL_REQUEST_EVENT + SendToRealUe(ue, msg) case common.USER_DATA_PKT_GENERATION_PROCEDURE: ue.Log.Infoln("Initiating User Data Packet Generation Procedure") msg := &common.UeMessage{} diff --git a/simue/simue.go b/simue/simue.go index 35bc4007..ad31e0e1 100644 --- a/simue/simue.go +++ b/simue/simue.go @@ -17,7 +17,7 @@ func Init(simUe *simuectx.SimUe) { err := ConnectToGnb(simUe) if err != nil { - err = fmt.Errorf("failed to connect to gnodeb:", err) + err = fmt.Errorf("failed to connect to gnodeb: %v", err) SendToProfile(simUe, common.PROFILE_FAIL_EVENT, err) simUe.Log.Infoln("Sent Profile Fail Event to Profile routine") return @@ -80,16 +80,24 @@ func HandleEvents(ue *simuectx.SimUe) { err = HandleDeregAcceptEvent(ue, msg) case common.PDU_SESS_EST_REQUEST_EVENT: err = HandlePduSessEstRequestEvent(ue, msg) + case common.PDU_SESS_REL_REQUEST_EVENT: + err = HandlePduSessReleaseRequestEvent(ue, msg) + case common.PDU_SESS_REL_COMMAND_EVENT: + err = HandlePduSessReleaseCommandEvent(ue, msg) case common.PDU_SESS_EST_ACCEPT_EVENT: err = HandlePduSessEstAcceptEvent(ue, msg) case common.PDU_SESS_EST_REJECT_EVENT: err = HandlePduSessEstRejectEvent(ue, msg) + case common.PDU_SESS_REL_COMPLETE_EVENT: + err = HandlePduSessReleaseCompleteEvent(ue, msg) case common.DL_INFO_TRANSFER_EVENT: err = HandleDlInfoTransferEvent(ue, msg) case common.DATA_BEARER_SETUP_REQUEST_EVENT: err = HandleDataBearerSetupRequestEvent(ue, msg) case common.DATA_BEARER_SETUP_RESPONSE_EVENT: err = HandleDataBearerSetupResponseEvent(ue, msg) + case common.DATA_BEARER_RELEASE_REQUEST_EVENT: + err = HandleDataBearerReleaseRequestEvent(ue, msg) case common.DATA_PKT_GEN_SUCCESS_EVENT: err = HandleDataPktGenSuccessEvent(ue, msg) case common.DATA_PKT_GEN_FAILURE_EVENT: @@ -113,7 +121,7 @@ func HandleEvents(ue *simuectx.SimUe) { HandleQuitEvent(ue, msg) return default: - ue.Log.Infoln("Event:", event, "is not supported") + ue.Log.Warnln("Event:", event, "is not supported") } if err != nil {