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

SDCORE-432: Adding event generation logic in sim UE for Registration … #10

Merged
merged 1 commit into from
Sep 3, 2021
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
63 changes: 63 additions & 0 deletions common/events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-FileCopyrightText: 2021 Open Networking Foundation <info@opennetworking.org>
//
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0

package common

type EventType uint8

// Events between Profile and SimUe
const (
PROFILE_START_EVENT EventType = 1 + iota
PROFILE_PASS_EVENT
PROFILE_FAIL_EVENT
)

// Events between UE and GNodeB (UU)
const (
CONNECT_REQUEST_EVENT EventType = 1 + iota
UL_INFO_TRANSFER_EVENT
DL_INFO_TRANSFER_EVENT
)

// Events betweem UE and AMF (N1)

// Following events are numbered same as the NAS Message types in section 9.7 of
// 3GPP TS 24.501

// 5GS Mobility Management events.
const UE_5GS_MOBILITY_MANAGEMENT_EVENTS EventType = 64
const (
_ EventType = UE_5GS_MOBILITY_MANAGEMENT_EVENTS + iota

REG_REQUEST_EVENT //65
REG_ACCEPT_EVENT
REG_COMPLETE_EVENT
REG_REJECT_EVENT
DEREG_REQUEST_UE_ORIG_EVENT
DEREG_ACCEPT_UE_ORIG_EVENT
DEREG_REQUEST_UE_TERM_EVENT
DEREG_ACCEPT_UE_TERM_EVENT //72

SERVICE_REQUEST_EVENT = UE_5GS_MOBILITY_MANAGEMENT_EVENTS + 3 + iota //76
SERVICE_REJECT_EVENT
SERVICE_ACCEPT_EVENT //78

AUTH_REQUEST_EVENT = UE_5GS_MOBILITY_MANAGEMENT_EVENTS + 10 + iota //86
AUTH_RESPONSE_EVENT
AUTH_REJECT_EVENT
AUTH_FAILURE_EVENT
AUTH_RESULT_EVENT
ID_REQUEST_EVENT
ID_RESPONSE_EVENT
SEC_MOD_COMMAND_EVENT
SEC_MOD_COMPLETE_EVENT
SEC_MOD_REJECT_EVENT //95
)

// Events between GNodeB and AMF (N2)
const (
DOWNLINK_NAS_TRANSPORT_EVENT EventType = 1 + iota
INITIAL_CONTEXT_SETUP_REQUEST_EVENT
)
11 changes: 7 additions & 4 deletions interfacecommon/interfacetype.go → common/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0

package interfacecommon
package common

type InterfaceType uint8

// Interface types
const (
UU_INTERFACE InterfaceType = iota
N2_INTERFACE InterfaceType = iota
// Application defined interfaces
PROFILE_SIMUE_INTERFACE InterfaceType = 1 + iota

// Network interfaces
UU_INTERFACE
N2_INTERFACE
)
68 changes: 68 additions & 0 deletions common/messages.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-FileCopyrightText: 2021 Open Networking Foundation <info@opennetworking.org>
//
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0

package common

import (
"github.com/free5gc/ngap/ngapType"
"github.com/omec-project/nas"
)

type InterfaceMessage interface {
GetEventType() EventType
GetInterfaceType() InterfaceType
}

type DefaultMessage struct {
Event EventType
Interface InterfaceType
}

func (msg *DefaultMessage) GetEventType() EventType {
return msg.Event
}

func (msg *DefaultMessage) GetInterfaceType() InterfaceType {
return msg.Interface
}

// N2Message is used to transfer information gnodeb the GNodeB components
type N2Message struct {
DefaultMessage
NgapPdu *ngapType.NGAPPDU
}

// UuMessage is used to transfer information between the UE and GNodeB
type UuMessage struct {
DefaultMessage
Supi string
// Encoded NAS message
NasPdu []byte
Extras EventData
// Channel to communicate with UE
UeChan chan InterfaceMessage
}

// UuMessage is used to transfer information between the UE and GNodeB
type ProfileMessage struct {
DefaultMessage
Supi string
Proc ProcedureType
ErrorMsg error
}

func (msg *ProfileMessage) GetEventType() EventType {
return msg.Event
}

func (msg *ProfileMessage) GetInterfaceType() InterfaceType {
return msg.Interface
}

type EventData struct {
Cause uint8
// Decoded NAS message
NasMsg *nas.Message
}
12 changes: 12 additions & 0 deletions common/procedures.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-FileCopyrightText: 2021 Open Networking Foundation <info@opennetworking.org>
//
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0

package common

type ProcedureType uint8

const (
REGISTRATION_PROCEDURE ProcedureType = 1 + iota
)
20 changes: 5 additions & 15 deletions gnbsim.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"fmt"
"gnbsim/gnodeb/dao"
"gnbsim/loadsub"
"gnbsim/profile/context"
"gnbsim/profile/ngsetup"
"gnbsim/profile/register"
"os"
Expand Down Expand Up @@ -39,18 +40,6 @@ func main() {
return
}

/*addrs, err := net.LookupHost("upf")
if err != nil {
fmt.Println("Failed to resolve upf")
return
}
upfIpAddr := addrs[0]
fmt.Println("UPF address - ", upfIpAddr)*/

upfIpAddr := "192.168.252.3"
fmt.Println("UPF address - ", upfIpAddr)
ranUIpAddr := "192.168.251.5"

switch testcase {
case "ngsetup":
{
Expand All @@ -62,9 +51,10 @@ func main() {
case "register":
{
fmt.Println("test register")
// TODO which gnb to use should be parsed from the config file
gnb := gnbDao.GetGNodeB("gnodeb1")
register.Register_test(ranUIpAddr, upfIpAddr, gnb)
// TODO parse profile from config file
profileCtx := context.NewProfile("register")
gnb := gnbDao.GetGNodeB(profileCtx.GnbName)
register.Register_test(profileCtx, gnb)
}
case "deregister":
{
Expand Down
17 changes: 13 additions & 4 deletions gnodeb/context/gnbue.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
package context

import (
intfc "gnbsim/interfacecommon"
"gnbsim/common"
"gnbsim/logger"

"github.com/sirupsen/logrus"
)

type GnbUe struct {
Expand All @@ -19,17 +22,23 @@ type GnbUe struct {
// TODO MME details

// GnbUe writes messages to UE on this channel
WriteUeChan chan *intfc.UuMessage
WriteUeChan chan common.InterfaceMessage

// GnbUe reads messages from all other workers and UE on this channel
ReadChan chan intfc.InterfaceMessage
ReadChan chan common.InterfaceMessage

/* logger */
Log *logrus.Entry
}

func NewGnbUe(ngapId int64, gnb *GNodeB, amf *GnbAmf) *GnbUe {
gnbue := GnbUe{}
gnbue.GnbUeNgapId = ngapId
gnbue.Amf = amf
gnbue.Gnb = gnb
gnbue.ReadChan = make(chan intfc.InterfaceMessage)
gnbue.ReadChan = make(chan common.InterfaceMessage)
gnbue.Log = logger.GNodeBLog.WithFields(logrus.Fields{"subcategory": "GnbUE",
logger.FieldGnbUeNgapId: ngapId})
gnbue.Log.Traceln("Context Created")
return &gnbue
}
5 changes: 5 additions & 0 deletions gnodeb/context/gnodeb.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ package context

import (
transport "gnbsim/transportcommon"

"github.com/sirupsen/logrus"
)

// GNodeB holds the context for a gNodeB. It manages the control plane and
Expand All @@ -28,6 +30,9 @@ type GNodeB struct {

/* Control Plane transport */
CpTransport transport.Transport

/* logger */
Log *logrus.Entry
}

func (gnb *GNodeB) GetDefaultAmf() *GnbAmf {
Expand Down
2 changes: 2 additions & 0 deletions gnodeb/dao/gnbdao.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package dao
import (
"gnbsim/gnodeb"
"gnbsim/gnodeb/context"
"gnbsim/logger"
"log"
"net"
"os"
Expand Down Expand Up @@ -48,6 +49,7 @@ func (gnbdao *GnbDao) ParseGnbConfig() error {
PlmnSupportList: context.NewPlmnSupportList(),
},
Tac: []byte("\x00\x00\x01"),
Log: logger.GNodeBLog.WithField(logger.FieldGnb, "gnodeb1"),
}

gnbdao.gnbMap["gnodeb1"] = &gnb
Expand Down
35 changes: 19 additions & 16 deletions gnodeb/gnodeb.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,35 @@
package gnodeb

import (
"fmt"
"gnbsim/common"
"gnbsim/gnodeb/context"
"gnbsim/gnodeb/transport"
"gnbsim/gnodeb/worker/gnbamfworker"
"gnbsim/gnodeb/worker/gnbueworker"
"gnbsim/util/test"
"log"

intfc "gnbsim/interfacecommon"
)

// Init initializes the GNodeB struct var and connects to the default AMF
func Init(gnb *context.GNodeB) error {
fmt.Printf("Default gNodeB configuration : %#v\n", *gnb)
gnb.Log.Traceln("Inititializing GNodeB")
gnb.Log.Infoln("GNodeB IP:", gnb.GnbIp, "GNodeB Port:", gnb.GnbPort)
gnb.CpTransport = &transport.GnbCTransport{GnbInstance: gnb}
gnb.GnbUes = &context.GnbUeDao{}

if gnb.DefaultAmf == nil {
log.Println("Default AMF not configured, continuing ...")
gnb.Log.Traceln("Default AMF not configured, continuing ...")
return nil
}

err := ConnectToAmf(gnb, gnb.DefaultAmf)
if err != nil {
log.Println("failed to connect to amf : ", err)
gnb.Log.Errorln("failed to connect to amf : ", err)
return err
}
successfulOutcome, err := PerformNgSetup(gnb, gnb.DefaultAmf)
if !successfulOutcome || err != nil {
log.Println("failed to perform NG Setup procedure : ", err)
gnb.Log.Errorln("failed to perform ng setup procedure : ", err)
return err
}

Expand All @@ -54,49 +53,53 @@ func QuitGnb(gnb *context.GNodeB) {
// ConnectToAmf establishes SCTP connection with the AMF and initiates NG Setup
// Procedure.
func ConnectToAmf(gnb *context.GNodeB, amf *context.GnbAmf) (err error) {
log.Println("gnodeb : ConnectToAmf called, AMF details :", *amf)
amf.Conn, err = test.ConnectToAmf(amf.AmfIp, gnb.GnbIp, int(amf.AmfPort), int(gnb.GnbPort))
gnb.Log.Traceln("Connecting to AMF")
amf.Conn, err = test.ConnectToAmf(amf.AmfIp, gnb.GnbIp, int(amf.AmfPort),
int(gnb.GnbPort))
if err != nil {
log.Println("Failed to connect to AMF ", *amf)
gnb.Log.Errorln("failed to connect to AMF, AMF IP:", amf.AmfIp, "Error:", err)
return
}
log.Println("Success - connected to AMF ", *amf)
gnb.Log.Infoln("Connected to AMF, AMF IP:", amf.AmfIp, "AMF Port:", amf.AmfPort)
return
}

// PerformNGSetup sends the NGSetupRequest to the provided GnbAmf.
// It waits for the response, process the response and informs whether it was
// SuccessfulOutcome or UnsuccessfulOutcome
func PerformNgSetup(gnb *context.GNodeB, amf *context.GnbAmf) (status bool, err error) {
gnb.Log.Traceln("Performing NG Setup Procedure")

// Forming NGSetupRequest with configured parameters
ngSetupReq, err := test.GetNGSetupRequest(gnb.Tac, gnb.GnbId, 24, gnb.GnbName)
if err != nil {
log.Println("failed to create setupRequest message")
gnb.Log.Errorln("failed to create setupRequest message")
return
}

// Sending NGSetupRequest to AMF
gnb.Log.Traceln("Sending NG Setup Request")
ngSetupResp, err := gnb.CpTransport.SendToPeerBlock(amf, ngSetupReq)
if err != nil {
log.Println("failed to send NGSetupRequest to AMF, error:", err)
gnb.Log.Errorln("SendToPeerBlock Failed:", err)
return
}
gnb.Log.Traceln("Received NG Setup Response")
err = gnbamfworker.HandleMessage(gnb, amf, ngSetupResp)
if err != nil {
log.Println("Unexpected erro in NGSetupResponse")
gnb.Log.Errorln("HandleMessage Failed:", err)
return
}

return amf.GetNgSetupStatus(), nil
}

// RequestConnection should be called by UE that is willing to connect to this GNodeB
func RequestConnection(gnb *context.GNodeB, uemsg *intfc.UuMessage) chan intfc.InterfaceMessage {
func RequestConnection(gnb *context.GNodeB, uemsg *common.UuMessage) chan common.InterfaceMessage {
// TODO Get NGAP Id from NGAP ID Pool
gnbUe := gnb.GnbUes.GetGnbUe(1)
if gnbUe != nil {
fmt.Printf("Error: Cannot process Register Request. GnbUe context already exists.")
gnb.Log.Errorln("GnbUe context already exists")
return nil
}
gnbUe = context.NewGnbUe(1, gnb, gnb.DefaultAmf)
Expand Down
Loading