Modify the packet parameters with “Security Mode Command”
Modify the packet parameters with “Initial Context Setup Request”
func BuildAuthenticationRequest(ue *context.AmfUe) ([]byte, error) {
m := nas.NewMessage()
m.GmmMessage = nas.NewGmmMessage()
m.GmmHeader.SetMessageType(nas.MsgTypeAuthenticationRequest)
authenticationRequest := nasMessage.NewAuthenticationRequest(0)
authenticationRequest.SetExtendedProtocolDiscriminator(nasMessage.Epd5GSMobilityManagementMessage)
authenticationRequest.SpareHalfOctetAndSecurityHeaderType.SetSecurityHeaderType(nas.SecurityHeaderTypePlainNas)
authenticationRequest.SpareHalfOctetAndSecurityHeaderType.SetSpareHalfOctet(0)
authenticationRequest.AuthenticationRequestMessageIdentity.SetMessageType(nas.MsgTypeAuthenticationRequest)
authenticationRequest.SpareHalfOctetAndNgksi = nasConvert.SpareHalfOctetAndNgksiToNas(ue.NgKsi)
authenticationRequest.ABBA.SetLen(uint8(len(ue.ABBA)))
authenticationRequest.ABBA.SetABBAContents(ue.ABBA)
switch ue.AuthenticationCtx.AuthType {
case models.AuthType__5_G_AKA:
var tmpArray [16]byte
var av5gAka models.Av5gAka
if err := mapstructure.Decode(ue.AuthenticationCtx.Var5gAuthData, &av5gAka); err != nil {
logger.GmmLog.Error("Var5gAuthData Convert Type Error")
return nil, err
}
rand, err := hex.DecodeString(av5gAka.Rand)
if err != nil {
return nil, err
}
authenticationRequest.AuthenticationParameterRAND = nasType.
NewAuthenticationParameterRAND(nasMessage.AuthenticationRequestAuthenticationParameterRANDType)
copy(tmpArray[:], rand[0:16])
authenticationRequest.AuthenticationParameterRAND.SetRANDValue(tmpArray)
autn, err := hex.DecodeString(av5gAka.Autn)
if err != nil {
return nil, err
}
authenticationRequest.AuthenticationParameterAUTN = nasType.
NewAuthenticationParameterAUTN(nasMessage.AuthenticationRequestAuthenticationParameterAUTNType)
authenticationRequest.AuthenticationParameterAUTN.SetLen(uint8(len(autn)))
copy(tmpArray[:], autn[0:16])
authenticationRequest.AuthenticationParameterAUTN.SetAUTN(tmpArray)
case models.AuthType_EAP_AKA_PRIME:
eapMsg := ue.AuthenticationCtx.Var5gAuthData.(string)
rawEapMsg, err := base64.StdEncoding.DecodeString(eapMsg)
if err != nil {
return nil, err
}
authenticationRequest.EAPMessage = nasType.NewEAPMessage(nasMessage.AuthenticationRequestEAPMessageType)
authenticationRequest.EAPMessage.SetLen(uint16(len(rawEapMsg)))
authenticationRequest.EAPMessage.SetEAPMessage(rawEapMsg)
}
m.GmmMessage.AuthenticationRequest = authenticationRequest
return m.PlainNasEncode()
}
func BuildAuthenticationRequest(ue *context.AmfUe) ([]byte, error) {
m := nas.NewMessage()
m.GmmMessage = nas.NewGmmMessage()
m.GmmHeader.SetMessageType(nas.MsgTypeAuthenticationRequest)
authenticationRequest := nasMessage.NewAuthenticationRequest(0)
authenticationRequest.SetExtendedProtocolDiscriminator(nasMessage.Epd5GSMobilityManagementMessage)
authenticationRequest.SpareHalfOctetAndSecurityHeaderType.SetSecurityHeaderType(nas.SecurityHeaderTypePlainNas)
authenticationRequest.SpareHalfOctetAndSecurityHeaderType.SetSpareHalfOctet(0)
authenticationRequest.AuthenticationRequestMessageIdentity.SetMessageType(nas.MsgTypeAuthenticationRequest)
authenticationRequest.SpareHalfOctetAndNgksi = nasConvert.SpareHalfOctetAndNgksiToNas(ue.NgKsi)
authenticationRequest.ABBA.SetLen(uint8(len(ue.ABBA)))
authenticationRequest.ABBA.SetABBAContents(ue.ABBA)
authenticationRequest.AuthenticationParameterRAND =
nasType.NewAuthenticationParameterRAND(nasMessage.AuthenticationRequestAuthenticationParameterRANDType)
//copy(tmpArray[:], "f63d9c08cfc5d42f26f20419de208bde")
var av5gAka models.Av5gAka
av5gAka.Autn = "e6ab5a8dfdee8000ec9fd483d54cb7d8"
var tmpArray string = "568c804753fe5ebd1f6707ec044f2c2c"
b, err := hex.DecodeString(tmpArray)
if err != nil {
panic(err)
}
var a [16]uint8
copy(a[:], b)
authenticationRequest.AuthenticationParameterRAND.SetRANDValue(a)
//av5gAka.Rand = strconv.Itoa(uint8(a))
authenticationRequest.AuthenticationParameterAUTN =
nasType.NewAuthenticationParameterAUTN(nasMessage.AuthenticationRequestAuthenticationParameterAUTNType)
var autn string = "e6ab5a8dfdee8000ec9fd483d54cb7d8"
c, err := hex.DecodeString(autn)
if err != nil {
panic(err)
}
var d [16]uint8
copy(d[:], c)
authenticationRequest.AuthenticationParameterAUTN.SetLen(uint8(len(d)))
authenticationRequest.AuthenticationParameterAUTN.SetAUTN(d)
fmt.Printf("Authentication Request paramenter - ExtendedProtocolDiscriminator: %s\n", authenticationRequest.ExtendedProtocolDiscriminator)
fmt.Printf("Authentication Request paramenter - SpareHalfOctetAndSecurityHeaderType: %s\n", authenticationRequest.SpareHalfOctetAndSecurityHeaderType)
fmt.Printf("Authentication Request paramenter - AuthenticationParameterAUTN: %s\n", authenticationRequest.AuthenticationParameterAUTN)
fmt.Printf("Authentication Request paramenter - AuthenticationParameterRAND: %s\n", authenticationRequest.AuthenticationParameterRAND)
fmt.Printf("Authentication Request paramenter - SpareHalfOctetAndNgksi: %s\n", authenticationRequest.SpareHalfOctetAndNgksi)
fmt.Printf("Authentication Request paramenter - SpareHalfOctetAndNgksi: %s\n", authenticationRequest.SpareHalfOctetAndNgksi)
fmt.Printf("Authentication Request paramenter - ABBA: %s\n", authenticationRequest.ABBA)
fmt.Printf("Authentication Request paramenter - AuthenticationRequestMessageIdentity: %s\n", authenticationRequest.AuthenticationRequestMessageIdentity)
//ue.Kseaf = "0fa8ed5965d42132289e6aa1e271642d1e883f8d8ef9775cde0b254b3fc2ea66"
//ue.Kamf = "a01d61546ea6bd1d82b46dab5c6887aea945af6f700bece1532e50e4a68df4ad"
//ue.DerivateKamf()
//switch ue.AuthenticationCtx.AuthType {
//case models.AuthType__5_G_AKA:
// var tmpArray [16]byte
// var av5gAka models.Av5gAka
//
// if err := mapstructure.Decode(ue.AuthenticationCtx.Var5gAuthData, &av5gAka); err != nil {
// logger.GmmLog.Error("Var5gAuthData Convert Type Error")
// return nil, err
// }
//
// rand, err := hex.DecodeString(av5gAka.Rand)
// if err != nil {
// return nil, err
// }
// authenticationRequest.AuthenticationParameterRAND =
// nasType.NewAuthenticationParameterRAND(nasMessage.AuthenticationRequestAuthenticationParameterRANDType)
// copy(tmpArray[:], rand[0:16])
// authenticationRequest.AuthenticationParameterRAND.SetRANDValue(tmpArray)
//
// autn, err := hex.DecodeString(av5gAka.Autn)
// if err != nil {
// return nil, err
// }
// authenticationRequest.AuthenticationParameterAUTN =
// nasType.NewAuthenticationParameterAUTN(nasMessage.AuthenticationRequestAuthenticationParameterAUTNType)
// authenticationRequest.AuthenticationParameterAUTN.SetLen(uint8(len(autn)))
// copy(tmpArray[:], autn[0:16])
// authenticationRequest.AuthenticationParameterAUTN.SetAUTN(tmpArray)
//case models.AuthType_EAP_AKA_PRIME:
// eapMsg := ue.AuthenticationCtx.Var5gAuthData.(string)
// rawEapMsg, err := base64.StdEncoding.DecodeString(eapMsg)
// if err != nil {
// return nil, err
// }
// authenticationRequest.EAPMessage = nasType.NewEAPMessage(nasMessage.AuthenticationRequestEAPMessageType)
// authenticationRequest.EAPMessage.SetLen(uint16(len(rawEapMsg)))
// authenticationRequest.EAPMessage.SetEAPMessage(rawEapMsg)
//}
m.GmmMessage.AuthenticationRequest = authenticationRequest
return m.PlainNasEncode()
}
// TS 24.501 5.4.1
func HandleAuthenticationResponse(ue *context.AmfUe, accessType models.AccessType,
authenticationResponse *nasMessage.AuthenticationResponse,
) error {
ue.GmmLog.Info("Handle Authentication Response")
ue.StopT3560()
if ue.AuthenticationCtx == nil {
return fmt.Errorf("Ue Authentication Context is nil")
}
switch ue.AuthenticationCtx.AuthType {
case models.AuthType__5_G_AKA:
var av5gAka models.Av5gAka
if err := mapstructure.Decode(ue.AuthenticationCtx.Var5gAuthData, &av5gAka); err != nil {
return fmt.Errorf("Var5gAuthData Convert Type Error")
}
if authenticationResponse.AuthenticationResponseParameter == nil {
return fmt.Errorf("AuthenticationResponseParamete is nil")
}
resStar := authenticationResponse.AuthenticationResponseParameter.GetRES()
// Calculate HRES* (TS 33.501 Annex A.5)
p0, err := hex.DecodeString(av5gAka.Rand)
if err != nil {
return err
}
p1 := resStar[:]
concat := append(p0, p1...)
hResStarBytes := sha256.Sum256(concat)
hResStar := hex.EncodeToString(hResStarBytes[16:])
if hResStar != av5gAka.HxresStar {
ue.GmmLog.Errorf("HRES* Validation Failure (received: %s, expected: %s)", hResStar, av5gAka.HxresStar)
if ue.IdentityTypeUsedForRegistration == nasMessage.MobileIdentity5GSType5gGuti && ue.IdentityRequestSendTimes == 0 {
ue.IdentityRequestSendTimes++
gmm_message.SendIdentityRequest(ue.RanUe[accessType], accessType, nasMessage.MobileIdentity5GSTypeSuci)
return nil
} else {
gmm_message.SendAuthenticationReject(ue.RanUe[accessType], "")
return GmmFSM.SendEvent(ue.State[accessType], AuthFailEvent, fsm.ArgsType{
ArgAmfUe: ue,
ArgAccessType: accessType,
}, logger.GmmLog)
}
}
response, problemDetails, err := consumer.SendAuth5gAkaConfirmRequest(ue, hex.EncodeToString(resStar[:]))
if err != nil {
return err
} else if problemDetails != nil {
ue.GmmLog.Debugf("Auth5gAkaConfirm Error[Problem Detail: %+v]", problemDetails)
return nil
}
switch response.AuthResult {
case models.AuthResult_SUCCESS:
ue.UnauthenticatedSupi = false
ue.Kseaf = response.Kseaf
ue.Supi = response.Supi
ue.DerivateKamf()
ue.GmmLog.Debugln("ue.DerivateKamf()", ue.Kamf)
return GmmFSM.SendEvent(ue.State[accessType], AuthSuccessEvent, fsm.ArgsType{
ArgAmfUe: ue,
ArgAccessType: accessType,
ArgEAPSuccess: false,
ArgEAPMessage: "",
}, logger.GmmLog)
case models.AuthResult_FAILURE:
if ue.IdentityTypeUsedForRegistration == nasMessage.MobileIdentity5GSType5gGuti && ue.IdentityRequestSendTimes == 0 {
ue.IdentityRequestSendTimes++
gmm_message.SendIdentityRequest(ue.RanUe[accessType], accessType, nasMessage.MobileIdentity5GSTypeSuci)
return nil
} else {
gmm_message.SendAuthenticationReject(ue.RanUe[accessType], "")
return GmmFSM.SendEvent(ue.State[accessType], AuthFailEvent, fsm.ArgsType{
ArgAmfUe: ue,
ArgAccessType: accessType,
}, logger.GmmLog)
}
}
case models.AuthType_EAP_AKA_PRIME:
response, problemDetails, err := consumer.SendEapAuthConfirmRequest(ue, *authenticationResponse.EAPMessage)
if err != nil {
return err
} else if problemDetails != nil {
ue.GmmLog.Debugf("EapAuthConfirm Error[Problem Detail: %+v]", problemDetails)
return nil
}
switch response.AuthResult {
case models.AuthResult_SUCCESS:
ue.UnauthenticatedSupi = false
ue.Kseaf = response.KSeaf
ue.Supi = response.Supi
ue.DerivateKamf()
// TODO: select enc/int algorithm based on ue security capability & amf's policy,
// then generate KnasEnc, KnasInt
return GmmFSM.SendEvent(ue.State[accessType], AuthSuccessEvent, fsm.ArgsType{
ArgAmfUe: ue,
ArgAccessType: accessType,
ArgEAPSuccess: true,
ArgEAPMessage: response.EapPayload,
}, logger.GmmLog)
case models.AuthResult_FAILURE:
if ue.IdentityTypeUsedForRegistration == nasMessage.MobileIdentity5GSType5gGuti && ue.IdentityRequestSendTimes == 0 {
ue.IdentityRequestSendTimes++
gmm_message.SendAuthenticationResult(ue.RanUe[accessType], false, response.EapPayload)
gmm_message.SendIdentityRequest(ue.RanUe[accessType], accessType, nasMessage.MobileIdentity5GSTypeSuci)
return nil
} else {
gmm_message.SendAuthenticationReject(ue.RanUe[accessType], response.EapPayload)
return GmmFSM.SendEvent(ue.State[accessType], AuthFailEvent, fsm.ArgsType{
ArgAmfUe: ue,
ArgAccessType: accessType,
}, logger.GmmLog)
}
case models.AuthResult_ONGOING:
ue.AuthenticationCtx.Var5gAuthData = response.EapPayload
if _, exists := response.Links["eap-session"]; exists {
ue.AuthenticationCtx.Links = response.Links
}
gmm_message.SendAuthenticationRequest(ue.RanUe[accessType])
}
}
return nil
}
// TS 24.501 5.4.1
func HandleAuthenticationResponse(ue *context.AmfUe, accessType models.AccessType,
authenticationResponse *nasMessage.AuthenticationResponse,
) error {
ue.GmmLog.Info("Handle Authentication Response")
if ue.T3560 != nil {
ue.T3560.Stop()
ue.T3560 = nil // clear the timer
}
// ue.StopT3560()
//
// if ue.AuthenticationCtx == nil {
// return fmt.Errorf("Ue Authentication Context is nil")
// }
//
// switch ue.AuthenticationCtx.AuthType {
// case models.AuthType__5_G_AKA:
// var av5gAka models.Av5gAka
// if err := mapstructure.Decode(ue.AuthenticationCtx.Var5gAuthData, &av5gAka); err != nil {
// return fmt.Errorf("Var5gAuthData Convert Type Error")
// }
// if authenticationResponse.AuthenticationResponseParameter == nil {
// return fmt.Errorf("AuthenticationResponseParamete is nil")
// }
// resStar := authenticationResponse.AuthenticationResponseParameter.GetRES()
//
// // Calculate HRES* (TS 33.501 Annex A.5)
// p0, err := hex.DecodeString(av5gAka.Rand)
// if err != nil {
// return err
// }
// p1 := resStar[:]
// concat := append(p0, p1...)
// hResStarBytes := sha256.Sum256(concat)
// hResStar := hex.EncodeToString(hResStarBytes[16:])
//
// if hResStar != av5gAka.HxresStar {
// ue.GmmLog.Errorf("HRES* Validation Failure (received: %s, expected: %s)", hResStar, av5gAka.HxresStar)
//
// if ue.IdentityTypeUsedForRegistration == nasMessage.MobileIdentity5GSType5gGuti && ue.IdentityRequestSendTimes == 0 {
// ue.IdentityRequestSendTimes++
// gmm_message.SendIdentityRequest(ue.RanUe[accessType], accessType, nasMessage.MobileIdentity5GSTypeSuci)
// return nil
// } else {
// gmm_message.SendAuthenticationReject(ue.RanUe[accessType], "")
// return GmmFSM.SendEvent(ue.State[accessType], AuthFailEvent, fsm.ArgsType{
// ArgAmfUe: ue,
// ArgAccessType: accessType,
// }, logger.GmmLog)
// }
// }
//
// response, problemDetails, err := consumer.SendAuth5gAkaConfirmRequest(ue, hex.EncodeToString(resStar[:]))
// if err != nil {
// return err
// } else if problemDetails != nil {
// ue.GmmLog.Debugf("Auth5gAkaConfirm Error[Problem Detail: %+v]", problemDetails)
// return nil
// }
// switch response.AuthResult {
// case models.AuthResult_SUCCESS:
// ue.UnauthenticatedSupi = false
// ue.Kseaf = response.Kseaf
// ue.Supi = response.Supi
// ue.DerivateKamf()
// ue.GmmLog.Debugln("ue.DerivateKamf()", ue.Kamf)
// return GmmFSM.SendEvent(ue.State[accessType], AuthSuccessEvent, fsm.ArgsType{
// ArgAmfUe: ue,
// ArgAccessType: accessType,
// ArgEAPSuccess: false,
// ArgEAPMessage: "",
// }, logger.GmmLog)
// case models.AuthResult_FAILURE:
// if ue.IdentityTypeUsedForRegistration == nasMessage.MobileIdentity5GSType5gGuti && ue.IdentityRequestSendTimes == 0 {
// ue.IdentityRequestSendTimes++
// gmm_message.SendIdentityRequest(ue.RanUe[accessType], accessType, nasMessage.MobileIdentity5GSTypeSuci)
// return nil
// } else {
// gmm_message.SendAuthenticationReject(ue.RanUe[accessType], "")
// return GmmFSM.SendEvent(ue.State[accessType], AuthFailEvent, fsm.ArgsType{
// ArgAmfUe: ue,
// ArgAccessType: accessType,
// }, logger.GmmLog)
// }
// }
// case models.AuthType_EAP_AKA_PRIME:
// response, problemDetails, err := consumer.SendEapAuthConfirmRequest(ue, *authenticationResponse.EAPMessage)
// if err != nil {
// return err
// } else if problemDetails != nil {
// ue.GmmLog.Debugf("EapAuthConfirm Error[Problem Detail: %+v]", problemDetails)
// return nil
// }
//
// switch response.AuthResult {
// case models.AuthResult_SUCCESS:
// ue.UnauthenticatedSupi = false
// ue.Kseaf = response.KSeaf
// ue.Supi = response.Supi
// ue.DerivateKamf()
// // TODO: select enc/int algorithm based on ue security capability & amf's policy,
// // then generate KnasEnc, KnasInt
// return GmmFSM.SendEvent(ue.State[accessType], AuthSuccessEvent, fsm.ArgsType{
// ArgAmfUe: ue,
// ArgAccessType: accessType,
// ArgEAPSuccess: true,
// ArgEAPMessage: response.EapPayload,
// }, logger.GmmLog)
// case models.AuthResult_FAILURE:
// if ue.IdentityTypeUsedForRegistration == nasMessage.MobileIdentity5GSType5gGuti && ue.IdentityRequestSendTimes == 0 {
// ue.IdentityRequestSendTimes++
// gmm_message.SendAuthenticationResult(ue.RanUe[accessType], false, response.EapPayload)
// gmm_message.SendIdentityRequest(ue.RanUe[accessType], accessType, nasMessage.MobileIdentity5GSTypeSuci)
// return nil
// } else {
// gmm_message.SendAuthenticationReject(ue.RanUe[accessType], response.EapPayload)
// return GmmFSM.SendEvent(ue.State[accessType], AuthFailEvent, fsm.ArgsType{
// ArgAmfUe: ue,
// ArgAccessType: accessType,
// }, logger.GmmLog)
// }
// case models.AuthResult_ONGOING:
// ue.AuthenticationCtx.Var5gAuthData = response.EapPayload
// if _, exists := response.Links["eap-session"]; exists {
// ue.AuthenticationCtx.Links = response.Links
// }
// gmm_message.SendAuthenticationRequest(ue.RanUe[accessType])
// }
// }
ue.UnauthenticatedSupi = false
ue.Kseaf = "ae43b27609029323b992bd71a7e8351b87b655ae2b13330117cd3e4870bcd79c"
ue.Kamf = "4770a89cf767fa0270325dd799ed2ca187c8960b905e38f9bdae02025c64ec5d"
ue.Supi = "imsi-208930000000003"
ue.DerivateKamf()
ue.GmmLog.Debugln("ue.DerivateKamf()", ue.Kamf)
return GmmFSM.SendEvent(ue.State[accessType], AuthSuccessEvent, fsm.ArgsType{
ArgAmfUe: ue,
ArgAccessType: accessType,
ArgEAPSuccess: false,
ArgEAPMessage: "",
}, logger.GmmLog)
return nil
}
func AuthenticationProcedure(ue *context.AmfUe, accessType models.AccessType) (bool, error) {
ue.GmmLog.Info("Authentication procedure")
// Check whether UE has SUCI and SUPI
if IdentityVerification(ue) {
ue.GmmLog.Debugln("UE has SUCI / SUPI")
if ue.SecurityContextIsValid() {
ue.GmmLog.Debugln("UE has a valid security context - skip the authentication procedure")
return true, nil
}
} else {
// Request UE's SUCI by sending identity request
ue.IdentityRequestSendTimes++
gmm_message.SendIdentityRequest(ue.RanUe[accessType], accessType, nasMessage.MobileIdentity5GSTypeSuci)
return false, nil
}
amfSelf := context.GetSelf()
// TODO: consider ausf group id, Routing ID part of SUCI
param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{}
resp, err := consumer.SendSearchNFInstances(amfSelf.NrfUri, models.NfType_AUSF, models.NfType_AMF, ¶m)
if err != nil {
ue.GmmLog.Error("AMF can not select an AUSF by NRF")
gmm_message.SendRegistrationReject(ue.RanUe[accessType], nasMessage.Cause5GMMCongestion, "")
return false, err
}
// select the first AUSF, TODO: select base on other info
var ausfUri string
for _, nfProfile := range resp.NfInstances {
ue.AusfId = nfProfile.NfInstanceId
ausfUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NAUSF_AUTH, models.NfServiceStatus_REGISTERED)
if ausfUri != "" {
break
}
}
if ausfUri == "" {
err = fmt.Errorf("AMF can not select an AUSF by NRF")
ue.GmmLog.Errorf(err.Error())
gmm_message.SendRegistrationReject(ue.RanUe[accessType], nasMessage.Cause5GMMCongestion, "")
return false, err
}
ue.AusfUri = ausfUri
response, problemDetails, err := consumer.SendUEAuthenticationAuthenticateRequest(ue, nil)
if err != nil {
ue.GmmLog.Errorf("Nausf_UEAU Authenticate Request Error: %+v", err)
gmm_message.SendRegistrationReject(ue.RanUe[accessType], nasMessage.Cause5GMMCongestion, "")
err = fmt.Errorf("Authentication procedure failed")
ue.GmmLog.Errorf(err.Error())
return false, err
} else if problemDetails != nil {
ue.GmmLog.Warnf("Nausf_UEAU Authenticate Request Failed: %+v", problemDetails)
var cause uint8
switch problemDetails.Status {
case http.StatusForbidden, http.StatusNotFound:
cause = nasMessage.Cause5GMMIllegalUE
default:
cause = nasMessage.Cause5GMMCongestion
}
gmm_message.SendRegistrationReject(ue.RanUe[accessType], cause, "")
err = fmt.Errorf("Authentication procedure failed")
ue.GmmLog.Warnf(err.Error())
return false, err
}
ue.AuthenticationCtx = response
ue.ABBA = []uint8{0x00, 0x00} // set ABBA value as described at TS 33.501 Annex A.7.1
gmm_message.SendAuthenticationRequest(ue.RanUe[accessType])
return false, nil
}
package gmm
import (
"bytes"
// "crypto/sha256"
"encoding/hex"
"fmt"
// "net/http"
.
.
.
func HandleConfigurationUpdateComplete(ue *context.AmfUe,
configurationUpdateComplete *nasMessage.ConfigurationUpdateComplete,
) error {
ue.GmmLog.Info("Handle Configuration Update Complete")
if ue.MacFailed {
return fmt.Errorf("NAS message integrity check failed")
}
// TODO: Stop timer T3555 in TS 24.501 Figure 5.4.4.1.1 in handler
// TODO: Send acknowledgment by Nudm_SMD_Info_Service to UDM in handler
// import "github.com/free5gc/openapi/Nudm_SubscriberDataManagement" client.Info
return nil
}
func AuthenticationProcedure(ue *context.AmfUe, accessType models.AccessType) (bool, error) {
ue.GmmLog.Info("Authentication procedure")
// Check whether UE has SUCI and SUPI
if IdentityVerification(ue) {
ue.GmmLog.Debugln("UE has SUCI / SUPI")
if ue.SecurityContextIsValid() {
ue.GmmLog.Debugln("UE has a valid security context - skip the authentication procedure")
return true, nil
}
} else {
// Request UE's SUCI by sending identity request
ue.IdentityRequestSendTimes++
gmm_message.SendIdentityRequest(ue.RanUe[accessType], accessType, nasMessage.MobileIdentity5GSTypeSuci)
return false, nil
}
// amfSelf := context.GetSelf()
//
// // TODO: consider ausf group id, Routing ID part of SUCI
// param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{}
// resp, err := consumer.SendSearchNFInstances(amfSelf.NrfUri, models.NfType_AUSF, models.NfType_AMF, ¶m)
// if err != nil {
// ue.GmmLog.Error("AMF can not select an AUSF by NRF")
// ue.GmmLog.Error("1111111111")
// gmm_message.SendRegistrationReject(ue.RanUe[accessType], nasMessage.Cause5GMMCongestion, "")
// return false, err
// }
//
// // select the first AUSF, TODO: select base on other info
// var ausfUri string
// for _, nfProfile := range resp.NfInstances {
// ue.AusfId = nfProfile.NfInstanceId
// ausfUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NAUSF_AUTH, models.NfServiceStatus_REGISTERED)
// if ausfUri != "" {
// break
// }
// }
// if ausfUri == "" {
// err = fmt.Errorf("AMF can not select an AUSF by NRF")
// err = fmt.Errorf("22222222")
// ue.GmmLog.Errorf(err.Error())
// //gmm_message.SendRegistrationReject(ue.RanUe[accessType], nasMessage.Cause5GMMCongestion, "")
// return false, err
// }
// ue.AusfUri = ausfUri
//
// response, problemDetails, err := consumer.SendUEAuthenticationAuthenticateRequest(ue, nil)
// if err != nil {
// ue.GmmLog.Errorf("Nausf_UEAU Authenticate Request Error: %+v", err)
// gmm_message.SendRegistrationReject(ue.RanUe[accessType], nasMessage.Cause5GMMCongestion, "")
// err = fmt.Errorf("Authentication procedure failed")
// ue.GmmLog.Errorf(err.Error())
// return false, err
// } else if problemDetails != nil {
// ue.GmmLog.Warnf("Nausf_UEAU Authenticate Request Failed: %+v", problemDetails)
// var cause uint8
// switch problemDetails.Status {
// case http.StatusForbidden, http.StatusNotFound:
// cause = nasMessage.Cause5GMMIllegalUE
// default:
// cause = nasMessage.Cause5GMMCongestion
// }
// gmm_message.SendRegistrationReject(ue.RanUe[accessType], cause, "")
// err = fmt.Errorf("Authentication procedure failed")
// ue.GmmLog.Warnf(err.Error())
// return false, err
// }
// ue.AuthenticationCtx = response
ue.ABBA = []uint8{0x00, 0x00} // set ABBA value as described at TS 33.501 Annex A.7.1
gmm_message.SendAuthenticationRequest(ue.RanUe[accessType])
return false, nil
}
func SendAuthenticationRequest(ue *context.RanUe) {
if ue == nil {
logger.GmmLog.Error("SendAuthenticationRequest: RanUe is nil")
return
}
if ue.AmfUe == nil {
logger.GmmLog.Error("SendAuthenticationRequest: AmfUe is nil")
return
}
amfUe := ue.AmfUe
amfUe.GmmLog.Infof("Send Authentication Request")
if amfUe.AuthenticationCtx == nil {
amfUe.GmmLog.Error("Authentication Context of UE is nil")
return
}
nasMsg, err := BuildAuthenticationRequest(amfUe)
if err != nil {
amfUe.GmmLog.Error(err.Error())
return
}
ngap_message.SendDownlinkNasTransport(ue, nasMsg, nil)
if context.GetSelf().T3560Cfg.Enable {
cfg := context.GetSelf().T3560Cfg
amfUe.GmmLog.Infof("Start T3560 timer")
amfUe.T3560 = context.NewTimer(cfg.ExpireTime, cfg.MaxRetryTimes, func(expireTimes int32) {
amfUe.GmmLog.Warnf("T3560 expires, retransmit Authentication Request (retry: %d)", expireTimes)
ngap_message.SendDownlinkNasTransport(ue, nasMsg, nil)
}, func() {
amfUe.Lock.Lock()
defer amfUe.Lock.Unlock()
amfUe.GmmLog.Warnf("T3560 Expires %d times, abort authentication procedure & ongoing 5GMM procedure",
cfg.MaxRetryTimes)
amfUe.T3560 = nil
gmm_common.RemoveAmfUe(amfUe, false)
})
}
}
func SendAuthenticationRequest(ue *context.RanUe) {
if ue == nil {
logger.GmmLog.Error("SendAuthenticationRequest: RanUe is nil")
return
}
if ue.AmfUe == nil {
logger.GmmLog.Error("SendAuthenticationRequest: AmfUe is nil")
return
}
amfUe := ue.AmfUe
amfUe.GmmLog.Infof("Send Authentication Request")
// if amfUe.AuthenticationCtx == nil {
// amfUe.GmmLog.Error("Authentication Context of UE is nil")
// return
// }
nasMsg, err := BuildAuthenticationRequest(amfUe)
if err != nil {
amfUe.GmmLog.Error(err.Error())
return
}
ngap_message.SendDownlinkNasTransport(ue, nasMsg, nil)
if context.GetSelf().T3560Cfg.Enable {
cfg := context.GetSelf().T3560Cfg
amfUe.GmmLog.Infof("Start T3560 timer")
amfUe.T3560 = context.NewTimer(cfg.ExpireTime, cfg.MaxRetryTimes, func(expireTimes int32) {
amfUe.GmmLog.Warnf("T3560 expires, retransmit Authentication Request (retry: %d)", expireTimes)
ngap_message.SendDownlinkNasTransport(ue, nasMsg, nil)
}, func() {
amfUe.Lock.Lock()
defer amfUe.Lock.Unlock()
amfUe.GmmLog.Warnf("T3560 Expires %d times, abort authentication procedure & ongoing 5GMM procedure",
cfg.MaxRetryTimes)
amfUe.T3560 = nil
gmm_common.RemoveAmfUe(amfUe, false)
})
}
}
func CreatePDUSession(ulNasTransport *nasMessage.ULNASTransport,
ue *context.AmfUe,
anType models.AccessType,
pduSessionID int32,
smMessage []uint8,
) (setNewSmContext bool, err error) {
var (
snssai models.Snssai
dnn string
)
// A) AMF shall select an SMF
// If the S-NSSAI IE is not included and the user's subscription context obtained from UDM. AMF shall
// select a default snssai
if ulNasTransport.SNSSAI != nil {
snssai = nasConvert.SnssaiToModels(ulNasTransport.SNSSAI)
} else {
if allowedNssai, ok := ue.AllowedNssai[anType]; ok {
snssai = *allowedNssai[0].AllowedSnssai
} else {
return false, errors.New("Ue doesn't have allowedNssai")
}
}
if ulNasTransport.DNN != nil {
dnn = ulNasTransport.DNN.GetDNN()
} else {
// if user's subscription context obtained from UDM does not contain the default DNN for the,
// S-NSSAI, the AMF shall use a locally configured DNN as the DNN
dnn = ue.ServingAMF().SupportDnnLists[0]
if ue.SmfSelectionData != nil {
snssaiStr := util.SnssaiModelsToHex(snssai)
if snssaiInfo, ok := ue.SmfSelectionData.SubscribedSnssaiInfos[snssaiStr]; ok {
for _, dnnInfo := range snssaiInfo.DnnInfos {
if dnnInfo.DefaultDnnIndicator {
dnn = dnnInfo.Dnn
}
}
}
}
}
if newSmContext, cause, err := consumer.SelectSmf(ue, anType, pduSessionID, snssai, dnn); err != nil {
ue.GmmLog.Errorf("Select SMF failed: %+v", err)
ue.GmmLog.Errorf("%+v", err)
gmm_message.SendDLNASTransport(ue.RanUe[anType], nasMessage.PayloadContainerTypeN1SMInfo,
smMessage, pduSessionID, cause, nil, 0)
} else {
_, smContextRef, errResponse, problemDetail, err := consumer.SendCreateSmContextRequest(
ue, newSmContext, nil, smMessage)
if err != nil {
ue.GmmLog.Errorf("CreateSmContextRequest Error: %+v", err)
return false, nil
} else if problemDetail != nil {
// TODO: error handling
return false, fmt.Errorf("Failed to Create smContext[pduSessionID: %d], Error[%v]", pduSessionID, problemDetail)
} else if errResponse != nil {
ue.GmmLog.Warnf("PDU Session Establishment Request is rejected by SMF[pduSessionId:%d]",
pduSessionID)
gmm_message.SendDLNASTransport(ue.RanUe[anType], nasMessage.PayloadContainerTypeN1SMInfo,
errResponse.BinaryDataN1SmMessage, pduSessionID, 0, nil, 0)
} else {
newSmContext.SetSmContextRef(smContextRef)
newSmContext.SetUserLocation(deepcopy.Copy(ue.Location).(models.UserLocation))
ue.StoreSmContext(pduSessionID, newSmContext)
ue.GmmLog.Infof("create smContext[pduSessionID: %d] Success", pduSessionID)
// TODO: handle response(response N2SmInfo to RAN if exists)
return true, nil
}
}
return false, nil
}
func SelectSmf(
ue *amf_context.AmfUe,
anType models.AccessType,
pduSessionID int32,
snssai models.Snssai,
dnn string,
) (*amf_context.SmContext, uint8, error) {
var (
smfID string
smfUri string
)
ue.GmmLog.Infof("Select SMF [snssai: %+v, dnn: %+v]", snssai, dnn)
nrfUri := ue.ServingAMF().NrfUri // default NRF URI is pre-configured by AMF
nsiInformation := ue.GetNsiInformationFromSnssai(anType, snssai)
if nsiInformation == nil {
if ue.NssfUri == "" {
// TODO: Set a timeout of NSSF Selection or will starvation here
for {
if err := SearchNssfNSSelectionInstance(ue, nrfUri, models.NfType_NSSF,
models.NfType_AMF, nil); err != nil {
ue.GmmLog.Errorf("AMF can not select an NSSF Instance by NRF[Error: %+v]", err)
time.Sleep(2 * time.Second)
} else {
break
}
}
}
response, problemDetails, err := NSSelectionGetForPduSession(ue, snssai)
if err != nil {
err = fmt.Errorf("NSSelection Get Error[%+v]", err)
return nil, nasMessage.Cause5GMMPayloadWasNotForwarded, err
} else if problemDetails != nil {
err = fmt.Errorf("NSSelection Get Failed Problem[%+v]", problemDetails)
return nil, nasMessage.Cause5GMMPayloadWasNotForwarded, err
}
nsiInformation = response.NsiInformation
}
smContext := amf_context.NewSmContext(pduSessionID)
smContext.SetSnssai(snssai)
smContext.SetDnn(dnn)
smContext.SetAccessType(anType)
if nsiInformation == nil {
ue.GmmLog.Warnf("nsiInformation is still nil, use default NRF[%s]", nrfUri)
} else {
smContext.SetNsInstance(nsiInformation.NsiId)
nrfApiUri, err := url.Parse(nsiInformation.NrfId)
if err != nil {
ue.GmmLog.Errorf("Parse NRF URI error, use default NRF[%s]", nrfUri)
} else {
nrfUri = fmt.Sprintf("%s://%s", nrfApiUri.Scheme, nrfApiUri.Host)
}
}
param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{
ServiceNames: optional.NewInterface([]models.ServiceName{models.ServiceName_NSMF_PDUSESSION}),
Dnn: optional.NewString(dnn),
Snssais: optional.NewInterface(openapi.MarshToJsonString([]models.Snssai{snssai})),
}
if ue.PlmnId.Mcc != "" {
param.TargetPlmnList = optional.NewInterface(openapi.MarshToJsonString(ue.PlmnId))
}
if amf_context.GetSelf().Locality != "" {
param.PreferredLocality = optional.NewString(amf_context.GetSelf().Locality)
}
ue.GmmLog.Debugf("Search SMF from NRF[%s]", nrfUri)
result, err := SendSearchNFInstances(nrfUri, models.NfType_SMF, models.NfType_AMF, ¶m)
if err != nil {
return nil, nasMessage.Cause5GMMPayloadWasNotForwarded, err
}
if len(result.NfInstances) == 0 {
err = fmt.Errorf("DNN[%s] is not supported or not subscribed in the slice[Snssai: %+v]", dnn, snssai)
return nil, nasMessage.Cause5GMMDNNNotSupportedOrNotSubscribedInTheSlice, err
}
// select the first SMF, TODO: select base on other info
for _, nfProfile := range result.NfInstances {
smfUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NSMF_PDUSESSION, models.NfServiceStatus_REGISTERED)
if smfUri != "" {
break
}
}
smContext.SetSmfID(smfID)
smContext.SetSmfUri(smfUri)
return smContext, 0, nil
}
func SelectSmf(
ue *amf_context.AmfUe,
anType models.AccessType,
pduSessionID int32,
snssai models.Snssai,
dnn string,
) (*amf_context.SmContext, uint8, error) {
var (
smfID string
smfUri string
)
ue.GmmLog.Infof("Select SMF [snssai: %+v, dnn: %+v]", snssai, dnn)
nrfUri := ue.ServingAMF().NrfUri // default NRF URI is pre-configured by AMF
ue.GmmLog.Errorf("/////////////////TEST01////////////////")
nsiInformation := ue.GetNsiInformationFromSnssai(anType, snssai)
ue.GmmLog.Errorf("/////////////////TEST02////////////////")
// if nsiInformation == nil {
// if ue.NssfUri == "" {
// // TODO: Set a timeout of NSSF Selection or will starvation here
// for {
//
// ue.GmmLog.Errorf("/////////////////TEST03////////////////")
//
// if err := SearchNssfNSSelectionInstance(ue, nrfUri, models.NfType_NSSF,
// models.NfType_AMF, nil); err != nil {
//
// ue.GmmLog.Errorf("/////////////////TEST04////////////////")
//
// //ue.GmmLog.Errorf("AMF can not select an NSSF Instance by NRF[Error: %+v]", err)
// //time.Sleep(2 * time.Second)
//
// break
//
// } else {
// break
// }
// }
// }
//
// response, problemDetails, err := NSSelectionGetForPduSession(ue, snssai)
// if err != nil {
// //err = fmt.Errorf("NSSelection Get Error[%+v]", err)
// err_1 = nil
// ue.GmmLog.Errorf("////return01////")
// return nil, nasMessage.Cause5GMMPayloadWasNotForwarded, err_1
// } else if problemDetails != nil {
// err = fmt.Errorf("NSSelection Get Failed Problem[%+v]", problemDetails)
// ue.GmmLog.Errorf("////return02////")
// return nil, nasMessage.Cause5GMMPayloadWasNotForwarded, err
// }
// nsiInformation = response.NsiInformation
// }
smContext := amf_context.NewSmContext(pduSessionID)
smContext.SetSnssai(snssai)
smContext.SetDnn(dnn)
smContext.SetAccessType(anType)
if nsiInformation == nil {
ue.GmmLog.Warnf("nsiInformation is still nil, use default NRF[%s]", nrfUri)
} else {
smContext.SetNsInstance(nsiInformation.NsiId)
nrfApiUri, err := url.Parse(nsiInformation.NrfId)
if err != nil {
ue.GmmLog.Errorf("Parse NRF URI error, use default NRF[%s]", nrfUri)
} else {
nrfUri = fmt.Sprintf("%s://%s", nrfApiUri.Scheme, nrfApiUri.Host)
}
}
param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{
ServiceNames: optional.NewInterface([]models.ServiceName{models.ServiceName_NSMF_PDUSESSION}),
Dnn: optional.NewString(dnn),
Snssais: optional.NewInterface(openapi.MarshToJsonString([]models.Snssai{snssai})),
}
if ue.PlmnId.Mcc != "" {
param.TargetPlmnList = optional.NewInterface(openapi.MarshToJsonString(ue.PlmnId))
}
if amf_context.GetSelf().Locality != "" {
param.PreferredLocality = optional.NewString(amf_context.GetSelf().Locality)
}
ue.GmmLog.Debugf("Search SMF from NRF[%s]", nrfUri)
result, err := SendSearchNFInstances(nrfUri, models.NfType_SMF, models.NfType_AMF, ¶m)
if err != nil {
ue.GmmLog.Errorf("////return03////")
return nil, nasMessage.Cause5GMMPayloadWasNotForwarded, err
}
if len(result.NfInstances) == 0 {
err = fmt.Errorf("DNN[%s] is not supported or not subscribed in the slice[Snssai: %+v]", dnn, snssai)
ue.GmmLog.Errorf("////return04////")
return nil, nasMessage.Cause5GMMDNNNotSupportedOrNotSubscribedInTheSlice, err
}
// select the first SMF, TODO: select base on other info
for _, nfProfile := range result.NfInstances {
smfUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NSMF_PDUSESSION, models.NfServiceStatus_REGISTERED)
if smfUri != "" {
break
}
}
smContext.SetSmfID(smfID)
smContext.SetSmfUri(smfUri)
ue.GmmLog.Errorf("////return05////")
return smContext, 0, nil
}
func NSSelectionGetForPduSession(ue *amf_context.AmfUe, snssai models.Snssai) (
*models.AuthorizedNetworkSliceInfo, *models.ProblemDetails, error,
) {
configuration := Nnssf_NSSelection.NewConfiguration()
configuration.SetBasePath(ue.NssfUri)
client := Nnssf_NSSelection.NewAPIClient(configuration)
amfSelf := amf_context.GetSelf()
sliceInfoForPduSession := models.SliceInfoForPduSession{
SNssai: &snssai,
RoamingIndication: models.RoamingIndication_NON_ROAMING, // not support roaming
}
e, err := json.Marshal(sliceInfoForPduSession)
if err != nil {
logger.ConsumerLog.Warnf("json marshal failed: %+v", err)
}
paramOpt := Nnssf_NSSelection.NSSelectionGetParamOpts{
SliceInfoRequestForPduSession: optional.NewInterface(string(e)),
}
res, httpResp, localErr := client.NetworkSliceInformationDocumentApi.NSSelectionGet(context.Background(),
models.NfType_AMF, amfSelf.NfId, ¶mOpt)
defer func() {
if httpResp != nil {
if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil {
logger.ConsumerLog.Errorf("NSSelectionGet response body cannot close: %+v",
rspCloseErr)
}
}
}()
if localErr == nil {
return &res, nil, nil
} else if httpResp != nil {
if httpResp.Status != localErr.Error() {
return nil, nil, localErr
}
problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails)
return nil, &problem, nil
} else {
return nil, nil, openapi.ReportError("NSSF No Response")
}
}
1 -> 2
func SearchNssfNSSelectionInstance(ue *amf_context.AmfUe, nrfUri string, targetNfType, requestNfType models.NfType,
param *Nnrf_NFDiscovery.SearchNFInstancesParamOpts,
) error {
resp, localErr := SendSearchNFInstances(nrfUri, targetNfType, requestNfType, param)
if localErr != nil {
return localErr
}
// select the first NSSF, TODO: select base on other info
var nssfUri string
for _, nfProfile := range resp.NfInstances {
ue.NssfId = nfProfile.NfInstanceId
nssfUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NNSSF_NSSELECTION, models.NfServiceStatus_REGISTERED)
if nssfUri != "" {
break
}
}
ue.NssfUri = nssfUri
if ue.NssfUri == "" {
return fmt.Errorf("AMF can not select an NSSF by NRF")
}
return nil
}
func SendSearchNFInstances(nrfUri string, targetNfType, requestNfType models.NfType,
param *Nnrf_NFDiscovery.SearchNFInstancesParamOpts,
) (models.SearchResult, error) {
// Set client and set url
configuration := Nnrf_NFDiscovery.NewConfiguration()
configuration.SetBasePath(nrfUri)
client := Nnrf_NFDiscovery.NewAPIClient(configuration)
result, res, err := client.NFInstancesStoreApi.SearchNFInstances(context.TODO(), targetNfType, requestNfType, param)
if res != nil && res.StatusCode == http.StatusTemporaryRedirect {
err = fmt.Errorf("Temporary Redirect For Non NRF Consumer")
}
if res == nil || res.Body == nil {
return result, err
}
defer func() {
if res != nil {
if bodyCloseErr := res.Body.Close(); bodyCloseErr != nil {
err = fmt.Errorf("SearchNFInstances' response body cannot close: %+w", bodyCloseErr)
}
}
}()
return result, err
}
func SendSearchNFInstances(nrfUri string, targetNfType, requestNfType models.NfType,
param *Nnrf_NFDiscovery.SearchNFInstancesParamOpts,
) (models.SearchResult, error) {
// Set client and set url
fmt.Println("////TEST A////")
configuration := Nnrf_NFDiscovery.NewConfiguration()
fmt.Println("////TEST B////")
configuration.SetBasePath(nrfUri)
client := Nnrf_NFDiscovery.NewAPIClient(configuration)
fmt.Println("////TEST C////")
result, res, err := client.NFInstancesStoreApi.SearchNFInstances(context.TODO(), targetNfType, requestNfType, param)
// 從這行印出 Handle NFDiscoveryRequest 和 200 GET,然後就到下面return回去了。
fmt.Println("////TEST D////")
if res != nil && res.StatusCode == http.StatusTemporaryRedirect {
err = fmt.Errorf("Temporary Redirect For Non NRF Consumer")
}
if res == nil || res.Body == nil {
return result, err
}
defer func() {
if res != nil {
if bodyCloseErr := res.Body.Close(); bodyCloseErr != nil {
err = fmt.Errorf("SearchNFInstances' response body cannot close: %+w", bodyCloseErr)
}
}
}()
return result, err
}
.
.
.
suci := amfUe.Suci
parts := strings.Split(suci, "-")
lastPart := parts[len(parts)-1]
Supi := "imsi-20893" + lastPart
fmt.Println("Last part:", Supi)
if !(uestatus.CheckUEStatus(Supi)) {
// UE is in initial Context Set up procedure
newUe := uestatus.NewAmfUe(Supi, true)
uestatus.StoreAmfUe(newUe)
//return
} else {
return
}
nasMessageBytes := []byte{}
originalOctetForAuth := []byte{0x7e, 0x00, 0x56, 0x01, 0x02, 0x00, 0x00}
//nasMessageBytes = append(nasMessageBytes, nasMsg...)
nasMessageBytes = append(nasMessageBytes, originalOctetForAuth...)
for i := 0; i <= 9; i++ {
av, err := XAppAKAGenerateAUTH(Supi)
if err != nil {
amfUe.GmmLog.Error(err.Error())
return
}
//fmt.Println("AV-AUTN:", av.Autn)
//fmt.Println("AV-RAND:", av.Rand)
.
.
.
package uestatus
import (
Mongoconteext "context"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"golang.org/x/net/context"
"log"
)
var client *mongo.Client
type PermanentKey struct {
EncryptionKey float64 `bson:"encryptionKey"`
PermanentKeyValue string `bson:"permanentKeyValue"`
EncryptionAlgorithm float64 `bson:"encryptionAlgorithm"`
}
type Milenage struct {
Op struct {
EncryptionAlgorithm float64 `bson:"encryptionAlgorithm"`
EncryptionKey float64 `bson:"encryptionKey"`
OpValue string `bson:"opValue"`
} `bson:"op"`
}
type Opc struct {
EncryptionAlgorithm float64 `bson:"encryptionAlgorithm"`
EncryptionKey float64 `bson:"encryptionKey"`
OpcValue string `bson:"opcValue"`
}
type AuthenticationSubscription struct {
ID primitive.ObjectID `bson:"_id"`
AuthenticationMethod string `bson:"authenticationMethod"`
PermanentKey PermanentKey `bson:"permanentKey"`
SequenceNumber string `bson:"sequenceNumber"`
AuthenticationManagementField string `bson:"authenticationManagementField"`
Milenage Milenage `bson:"milenage"`
Opc Opc `bson:"opc"`
UeID string `bson:"ueId"`
}
func ConnectToMongoDB() {
// Set MongoDB connection options
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
// Connect to MongoDB
var err error
client, err = mongo.Connect(Mongoconteext.Background(), clientOptions)
if err != nil {
log.Fatal(err)
}
// Ping the MongoDB server to verify that the connection is established
err = client.Ping(Mongoconteext.Background(), nil)
if err != nil {
log.Fatal("Failed to ping MongoDB:", err)
}
fmt.Println("Connected to MongoDB!")
}
func GetMongoData(ueId string) AuthenticationSubscription {
// Access the MongoDB client and perform operations
// For example, you can retrieve data from a collection here
// This function can be called from other files in the package
// to interact with MongoDB
// Get a handle for the "test" database
database := client.Database("free5gc")
collection := database.Collection("subscriptionData.authenticationData.authenticationSubscription")
ueid := ueId
filter := bson.M{"ueId": ueid}
var result AuthenticationSubscription
err := collection.FindOne(context.Background(), filter).Decode(&result)
if err != nil {
log.Fatal(err)
}
return result
}
func DisconnectToMongoDB() {
// Disconnect from MongoDB when done
err := client.Disconnect(Mongoconteext.Background())
if err != nil {
log.Fatal("Failed to disconnect from MongoDB:", err)
}
fmt.Println("Disconnected from MongoDB!")
}
package models
type PermanentKey struct {
PermanentKeyValue string `json:"permanentKeyValue"`
EncryptionAlgorithm string `json:"encryptionAlgorithm"`
EncryptionKey string `json:"encryptionKey"`
}
type Milenage struct {
Op struct {
OpValue string `json:"opValue"`
EncryptionAlgorithm string `json:"encryptionAlgorithm"`
EncryptionKey string `json:"encryptionKey"`
} `json:"op"`
}
type Opc struct {
OpcValue string `json:"opcValue"`
EncryptionAlgorithm string `json:"encryptionAlgorithm"`
EncryptionKey string `json:"encryptionKey"`
}
type AuthSubs struct {
AuthenticationMethod string `json:"authenticationMethod"`
PermanentKey *PermanentKey `json:"permanentKey"`
SequenceNumber string `json:"sequenceNumber"`
AuthenticationManagementField string `json:"authenticationManagementField"`
Milenage *Milenage `json:"milenage"`
Opc *Opc `json:"opc"`
UeId string `json:"ueId"`
}
func QueryAuthSubsDataProcedure(collName string, ueId string) (*models.AuthSubs, *models.ProblemDetails) {
filter := bson.M{"ueId": ueId}
data, pd := getDataFromDB(collName, filter)
if pd != nil {
if pd.Status == http.StatusNotFound {
logger.DataRepoLog.Warnf("QueryAuthSubsDataProcedure err: %s", pd.Title)
} else {
logger.DataRepoLog.Errorf("QueryAuthSubsDataProcedure err: %s", pd.Detail)
}
return nil, pd
}
// 將 map[string]interface{} 轉換為 AuthSubs 結構體
var authSubs models.AuthSubs
jsonData, err := json.Marshal(data)
if err != nil {
logger.DataRepoLog.Errorf("Error marshaling data: %s", err)
return nil, &models.ProblemDetails{
Status: http.StatusInternalServerError,
Cause: "MarshalingError",
Detail: err.Error(),
}
}
err = json.Unmarshal(jsonData, &authSubs)
if err != nil {
logger.DataRepoLog.Errorf("Error unmarshaling data: %s", err)
return nil, &models.ProblemDetails{
Status: http.StatusInternalServerError,
Cause: "UnmarshalingError",
Detail: err.Error(),
}
}
return &authSubs, nil
}
type PermanentKey struct {
EncryptionKey float64 `bson:"encryptionKey"`
PermanentKeyValue string `bson:"permanentKeyValue"`
EncryptionAlgorithm float64 `bson:"encryptionAlgorithm"`
}
type Milenage struct {
Op struct {
EncryptionAlgorithm float64 `bson:"encryptionAlgorithm"`
EncryptionKey float64 `bson:"encryptionKey"`
OpValue string `bson:"opValue"`
} `bson:"op"`
}
type Opc struct {
EncryptionAlgorithm float64 `bson:"encryptionAlgorithm"`
EncryptionKey float64 `bson:"encryptionKey"`
OpcValue string `bson:"opcValue"`
}
type AuthenticationSubscription struct {
ID primitive.ObjectID `bson:"_id"`
AuthenticationMethod string `bson:"authenticationMethod"`
PermanentKey PermanentKey `bson:"permanentKey"`
SequenceNumber string `bson:"sequenceNumber"`
AuthenticationManagementField string `bson:"authenticationManagementField"`
Milenage Milenage `bson:"milenage"`
Opc Opc `bson:"opc"`
UeID string `bson:"ueId"`
}
func GetMongoData(ueId string) AuthenticationSubscription {
// Access the MongoDB client and perform operations
// For example, you can retrieve data from a collection here
// This function can be called from other files in the package
// to interact with MongoDB
// Get a handle for the "test" database
database := client.Database("free5gc")
collection := database.Collection("subscriptionData.authenticationData.authenticationSubscription")
ueid := ueId
filter := bson.M{"ueId": ueid}
var result AuthenticationSubscription
err := collection.FindOne(context.Background(), filter).Decode(&result)
if err != nil {
log.Fatal(err)
}
return result
}