Skip to content

Commit

Permalink
Allow registration to PLMNID other than 208-93
Browse files Browse the repository at this point in the history
  • Loading branch information
yoursunny committed Jan 24, 2024
1 parent 44f09be commit ad6ee56
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 36 deletions.
87 changes: 87 additions & 0 deletions gnodeb/ngap/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
package ngap

import (
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"strconv"

"github.com/omec-project/aper"
gnbctx "github.com/omec-project/gnbsim/gnodeb/context"
"github.com/omec-project/gnbsim/util/ngapTestpacket"

Expand Down Expand Up @@ -65,6 +69,36 @@ func GetNGSetupRequest(gnb *gnbctx.GNodeB) ([]byte, error) {
return ngap.Encoder(message)
}

// GetInitialUEMessage encodes NGAP InitialUEMessage for the given UE.
//
// gnbue: gNB-UE context.
// nasPdu: value of id-NAS-PDU from the UE.
func GetInitialUEMessage(gnbue *gnbctx.GnbCpUe, nasPdu []byte) ([]byte, error) {
message := ngapTestpacket.BuildInitialUEMessage(gnbue.GnbUeNgapId, nasPdu, "")
ies := message.InitiatingMessage.Value.InitialUEMessage.ProtocolIEs.List

if e := updateUserLocationInformation(gnbue.Gnb, ies[2].Value.UserLocationInformation); e != nil {
return nil, e
}

return ngap.Encoder(message)
}

// GetUplinkNASTransport encodes NGAP UplinkNASTransport for the given UE.
//
// gnbue: gNB-UE context.
// nasPdu: value of id-NAS-PDU from the UE.
func GetUplinkNASTransport(gnbue *gnbctx.GnbCpUe, nasPdu []byte) ([]byte, error) {
message := ngapTestpacket.BuildUplinkNasTransport(gnbue.AmfUeNgapId, gnbue.GnbUeNgapId, nasPdu)
ies := message.InitiatingMessage.Value.UplinkNASTransport.ProtocolIEs.List

if e := updateUserLocationInformation(gnbue.Gnb, ies[3].Value.UserLocationInformation); e != nil {
return nil, e
}

return ngap.Encoder(message)
}

func GetUEContextReleaseRequest(gnbue *gnbctx.GnbCpUe) ([]byte, error) {
var pduSessIds []int64
f := func(k interface{}, v interface{}) bool {
Expand All @@ -85,3 +119,56 @@ func GetUEContextReleaseRequest(gnbue *gnbctx.GnbCpUe) ([]byte, error) {

return ngap.Encoder(message)
}

// GetUplinkNASTransport encodes NGAP UEContextReleaseComplete for the given UE.
//
// gnbue: gNB-UE context.
// nasPdu: value of id-NAS-PDU from the UE.
func GetUEContextReleaseComplete(gnbue *gnbctx.GnbCpUe) ([]byte, error) {
var pduSessIds []int64
gnbue.GnbUpUes.Range(func(k interface{}, v interface{}) bool {
pduSessIds = append(pduSessIds, k.(int64))
return true
})

message := ngapTestpacket.BuildUEContextReleaseComplete(gnbue.AmfUeNgapId, gnbue.GnbUeNgapId, pduSessIds)
ies := message.SuccessfulOutcome.Value.UEContextReleaseComplete.ProtocolIEs.List

if e := updateUserLocationInformation(gnbue.Gnb, ies[2].Value.UserLocationInformation); e != nil {
return nil, e
}

return ngap.Encoder(message)
}

// updateUserLocationInformation updates UserLocationInformation element to match gNB information.
//
// gnb: gNB context.
// uli: UserLocationInformation prepared by ngapTestpacket package.
func updateUserLocationInformation(gnb *gnbctx.GNodeB, uli *ngapType.UserLocationInformation) error {
nr := uli.UserLocationInformationNR

nr.NRCGI.PLMNIdentity = ngapConvert.PlmnIdToNgap(*gnb.RanId.PlmnId)
nr.TAI.PLMNIdentity = nr.NRCGI.PLMNIdentity

gnbID, e := strconv.ParseUint(gnb.RanId.GNbId.GNBValue, 16, 64)
if e != nil {
return fmt.Errorf("invalid GNB ID: %w", e)
}
// NRCI contains gnbID and cellID, here we assume cellID is zero
nrci := gnbID << uint64(36-gnb.RanId.GNbId.BitLength)
nrciBuf := [8]byte{}
binary.BigEndian.PutUint64(nrciBuf[:], nrci)
nr.NRCGI.NRCellIdentity.Value.Bytes = nrciBuf[3:]

if len(gnb.SupportedTaList) < 1 {
return errors.New("unexpected empty SupportedTaList")
}
tac, e := hex.DecodeString(gnb.SupportedTaList[0].Tac)
if e != nil {
return fmt.Errorf("invalid TAC: %w", e)
}
nr.TAI.TAC.Value = aper.OctetString(tac)

return nil
}
14 changes: 3 additions & 11 deletions gnodeb/worker/gnbcpueworker/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func HandleInitialUEMessage(gnbue *gnbctx.GnbCpUe,
}
gnbue.Log.Traceln("Sent Uplink NAS Message to AMF")
} else {
sendMsg, err := test.GetInitialUEMessage(gnbue.GnbUeNgapId, msg.NasPdus[0], "")
sendMsg, err := ngap.GetInitialUEMessage(gnbue, msg.NasPdus[0])
if err != nil {
gnbue.Log.Errorln("GetInitialUEMessage failed:", err)
return
Expand Down Expand Up @@ -113,7 +113,7 @@ func HandleUlInfoTransfer(gnbue *gnbctx.GnbCpUe,

msg := intfcMsg.(*common.UuMessage)
gnbue.Log.Traceln("Creating Uplink NAS Transport Message")
sendMsg, err := test.GetUplinkNASTransport(gnbue.AmfUeNgapId, gnbue.GnbUeNgapId, msg.NasPdus[0])
sendMsg, err := ngap.GetUplinkNASTransport(gnbue, msg.NasPdus[0])
if err != nil {
gnbue.Log.Errorln("GetUplinkNASTransport failed:", err)
return
Expand Down Expand Up @@ -427,15 +427,7 @@ func HandleUeCtxReleaseCommand(gnbue *gnbctx.GnbCpUe,
}
}

var pduSessIds []int64
f := func(k interface{}, v interface{}) bool {
pduSessIds = append(pduSessIds, k.(int64))
return true
}
gnbue.GnbUpUes.Range(f)

ngapPdu, err := test.GetUEContextReleaseComplete(gnbue.AmfUeNgapId,
gnbue.GnbUeNgapId, pduSessIds)
ngapPdu, err := ngap.GetUEContextReleaseComplete(gnbue)
if err != nil {
fmt.Println("Failed to create UE Context Release Complete message")
return
Expand Down
13 changes: 10 additions & 3 deletions profile/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"fmt"
"log"
"strconv"
"strings"
"sync"

"github.com/omec-project/gnbsim/common"
Expand Down Expand Up @@ -62,12 +63,18 @@ func InitProfile(profile *profctx.Profile, summaryChan chan common.InterfaceMess
}

for count := 1; count <= profile.UeCount; count++ {
imsiStr := IMSI_PREFIX + strconv.Itoa(startImsi)
imsiStr := makeImsiStr(profile, startImsi)
initImsi(profile, gnb, imsiStr)
startImsi++
}
}

// makeImsiStr constructs IMSI string with specified integer value and proper length.
func makeImsiStr(profile *profctx.Profile, imsi int) string {
s := strconv.Itoa(imsi)
return IMSI_PREFIX + strings.Repeat("0", max(0, len(profile.StartImsi)-len(s))) + s
}

func initImsi(profile *profctx.Profile, gnb *gnbctx.GNodeB, imsiStr string) {
readChan := make(chan *common.ProfileMessage)
c := simue.InitUE(imsiStr, gnb, profile, readChan)
Expand Down Expand Up @@ -127,7 +134,7 @@ func ExecuteProfile(profile *profctx.Profile, summaryChan chan common.InterfaceM
plock.Lock()
profile.UeCount = profile.UeCount + 1
imsi := profile.Imsi + profile.UeCount
imsiStr := IMSI_PREFIX + strconv.Itoa(imsi)
imsiStr := makeImsiStr(profile, imsi)
initImsi(profile, gnb, imsiStr)
pCtx := profile.PSimUe[imsiStr]
profile.Log.Infoln("pCtx ", pCtx)
Expand All @@ -151,7 +158,7 @@ func ExecuteProfile(profile *profctx.Profile, summaryChan chan common.InterfaceM
}()
imsi := profile.Imsi
for count := 1; count <= profile.UeCount; count++ {
imsiStr := IMSI_PREFIX + strconv.Itoa(imsi)
imsiStr := makeImsiStr(profile, imsi)
imsi++
wg.Add(1)
pCtx := profile.PSimUe[imsiStr]
Expand Down
12 changes: 8 additions & 4 deletions realue/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package realue
import (
"fmt"
"net"
"strconv"

"github.com/omec-project/gnbsim/common"
realuectx "github.com/omec-project/gnbsim/realue/context"
Expand All @@ -25,9 +26,8 @@ import (

// TODO Remove the hardcoding
const (
SN_NAME string = "5G:mnc093.mcc208.3gppnetwork.org"
SWITCH_OFF uint8 = 0
REQUEST_TYPE_EXISTING_PDU_SESS uint8 = 0x02
SWITCH_OFF uint8 = 0
REQUEST_TYPE_EXISTING_PDU_SESS uint8 = 0x02
)

func HandleRegRequestEvent(ue *realuectx.RealUe,
Expand Down Expand Up @@ -64,9 +64,13 @@ func HandleAuthResponseEvent(ue *realuectx.RealUe,

ue.NgKsi = nasConvert.SpareHalfOctetAndNgksiToModels(authReq.SpareHalfOctetAndNgksi)

mcc, _ := strconv.Atoi(ue.Plmn.Mcc)
mnc, _ := strconv.Atoi(ue.Plmn.Mnc)
snName := fmt.Sprintf("5G:mnc%03d.mcc%03d.3gppnetwork.org", mnc, mcc)

rand := authReq.GetRANDValue()
autn := authReq.GetAUTN()
resStat := ue.DeriveRESstarAndSetKey(autn[:], rand[:], SN_NAME)
resStat := ue.DeriveRESstarAndSetKey(autn[:], rand[:], snName)

// TODO: Parse Auth Request IEs and update the RealUE Context

Expand Down
23 changes: 5 additions & 18 deletions realue/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,12 @@ const (
var ROUTING_INDICATOR []uint8 = []uint8{0xf0, 0xff}

func SupiToSuci(supi string, plmnid *models.PlmnId) ([]byte, error) {
index := strings.Index(supi, "-")
if index < 0 {
return nil, fmt.Errorf(`invalid supi format, should start with "imsi-"`)
supiExpectedPrefix := "imsi-" + plmnid.Mcc + plmnid.Mnc
if !strings.HasPrefix(supi, supiExpectedPrefix) {
return nil, fmt.Errorf(`invalid supi format, should start with "imsi-" + MCC + MNC`)
}

// extracting imsi part after "imsi-"
imsi := supi[(index + 1):]

if !strings.Contains(imsi, plmnid.Mcc) {
return nil, fmt.Errorf("mcc not found in imsi")
}

index = strings.Index(imsi, plmnid.Mnc)
if index < 0 {
return nil, fmt.Errorf("mnc not found in imsi")
}
index += len(plmnid.Mnc)
// extracting msin from imsi
msin := imsi[index:]
// extracting msin from supi
msin := supi[len(supiExpectedPrefix):]

suci := make([]uint8, 0, SUCI_LEN)
// creating octet 4 of 5GS mobile identity info
Expand Down

0 comments on commit ad6ee56

Please sign in to comment.