[toc]
# AUSF improvement 1
* (2024/02/26~)
## Reason

## Method

### Full flow of 5g-aka

### Corresponded logs

## Analysis (Part 1)
### Corresponded logs of part 1
* Dark place is where I need to skip in call flow.

* [Drawio(clearer version)](https://drive.google.com/file/d/1eejyLflMXjOaQxs9qnIe1W4Nd-nn3B-0/view?usp=drive_link)

### Red framed place

:::warning
#### Foreword
* Here I just find the source file by search the log (Authentication procedure), so I dont know the source of the previous log, who triggers the authentication.
* And I started from AuthenticationProcedure, the prvious function who calls it is sm.go, you can chek how it works [here](https://hackmd.io/fH1eBOchRbGLQA3qb202PQ?view#Orange-framed-place)
:::
#### Simple process
| Seq. | File name | Function name |
|:----:|:-------------------------------------------------- |:-------------------------------------------- |
| 0 |  | func Authentication |
| 1 |  | func AuthenticationProcedure |
| 2 |  | func SendUEAuthenticationAuthenticateRequest |
| 3 | NRF -> routers.go & api_default.go in AUSF | NRF forward & OpenAPI |
| 4 |  | func HandleUeAuthPostRequest |
#### Detailed process
1. func AuthenticationProcedure
* 
* Check the ID of UE.
* 
* **Call(AUSF)**

* It is wrong, see [here](https://hackmd.io/fH1eBOchRbGLQA3qb202PQ?both#Correction)
* This one is true : 
* func SendUEAuthenticationAuthenticateRequest
* 
2. NRF forward -> OpenAPI
* NRF forwarding
* OpenAPI
* 

* 

3. func HandleUeAuthPostRequest
* 
* **Call (Function)**
* 
### Purple framed place

#### Simple process
| Seq. | File name | Function name |
|:----:|:-------------------------------------------------------------- |:---------------------------------- |
| 1 |  | func HandleUeAuthPostRequest |
| 2 |  | func UeAuthPostRequestProcedure |
| 3 | NRF -> routers.go & api_generate_auth_data.go in UDM | NRF forward & OpenAPI |
| 4 |  | func HandleGenerateAuthDataRequest |
| 5 |  | func GenerateAuthDataProcedure |
| 6 | NRF -> routers.go & api_authentication_data_document.go in UDM | NRF forward & OpenAPI |
| 7 |  | func HandleQueryAuthSubsData |
| 8 | **Return (5)** | **Return (5)** |
| 9 | NRF -> routers.go & api_authentication_data_document.go in UDM | NRF forward & OpenAPI |
| 10 |  | func HandleModifyAuthentication |
| 11 | **Return (8)** | **Return (8)** |
| 12 | **Return (2)** | **Return (2)** |
| 13 | **Return (1)** | **Return (1)** |
#### Detailed process
1. func HandleUeAuthPostRequest
* 
* **Call (Function)**
* 
2. func UeAuthPostRequestProcedure
* 
* Here it calls , because it is not quit important to the flow in the picture, I just skip recording it, and I will also do this if there is any same situation.
* **Call (UDM)**
* 
3. NRF forward -> OpenAPI
* NRF forwarding
* OpenAPI
* 
We can notice that the calling line is not in the var routes.

* 

4. func HandleGenerateAuthDataRequest
* 
* **Call (Function)**
* 
5. func GenerateAuthDataProcedure
* **Call (Function)**
* Suci transfer to Supi
* 
*  func ToSupi (Include below three Suci lines)

* 
* 
* 
* **Return**
* **Call (UDR)**
* 
6. NRF forward -> OpenAPI
* NRF forwarding
* OpenAPI
* 
* 

7. func HandleQueryAuthSubsData
* 
* **Call (Function)**
* 
* func QueryAuthSubsDataProcedure
* **Call (Function) : Get data from mongoDB.**
* 
* func getDataFromDB

* **Return : Deal some error of data not found and return sub data.**
* **Return : Deal some procedure error and return sub data.**
*  : Something about http status(Not 200 ok and also no problem).
* **Return (5) : HTTP response to UDM, it includes the 200ok and response(Getted sub data).**
8. (5) func GenerateAuthDataProcedure
* After receiving the return from UDR, it computes the hash values,

does some conditionals, and  is printed here,

* Then has a re-syncronization if needed

and SQN

* And then call the patch API (update the authentication-data),
**Call (UDR)**


9. NRF forward -> OpenAPI
* NRF forwarding
* OpenAPI
* 
* 

10. func HandleModifyAuthentication
* 
* **Call (Funcion)**
* 
* func ModifyAuthenticationProcedure
* 
* func patchDataToDBAndNotify
* Do some API work in UDR.
* **Return**
* **Return (8)**
11. (8) func GenerateAuthDataProcedure
* Generating of parameters.
* 
* 
* 
* 
* AV
* Use 5g-AKA
* 
* 
* 
* Use EAP-AKA'
* ...
* **Return to AUSF (2) : AV & SUPI**
* 
* 
* Maybe it is this API log, but not sure.
* 
12. (2) func UeAuthPostRequestProcedure
* It get the info from UDM and create the AUSF context (Need modified)).

* 
* Use 5g-AKA
* 
* 
* 
* 
* Use EAP-AKA
* 
* **Return (1) (same as 3 in red framed place.)**
13. (1) func HandleUeAuthPostRequest
* **Return HTTP to AMF. (same as 1 in red framed place)**
* 
### Orange framed place

#### Simple process
| Seq. | File name | Function name |
|:----:|:-------------------------------------------------- |:--------------------------------- |
| 1 |  | func HandleUeAuthPostRequest |
| 2 |  | func UeAuthPostRequestProcedure |
| 3 |  | func AuthenticationProcedure |
| 4 |  | func SendAuthenticationReques |
| 5 | **(3)** | **(3)** |
| 6 | **Return (0)** | **Return (0)** |
| 7 | N/A | N/A |
| 8 |  | func HandleAuthenticationResponse |
#### Detailed process
1. = 13.(Purple)
2. = 12.(Purple)
3. = [1.(Red) func AuthenticationProcedure](https://hackmd.io/fH1eBOchRbGLQA3qb202PQ?both#Red-framed-place)
* Here I find that I got it wrong, see the green part.

:::success
#### Correction
* In the red framed place, I think the first SearchNF line is the one which call AUSF, but it is not.
* The test code :


* The test logs :

* So the third one  is the real one to generate the authentication context, the red framed place need to be corrected.
* And it will call another function in AMF then call the AUSF.
* 
* And the first one and the second one in the crossed picture are just use NRF to find AUSF.
* But I dont know which one produce the NRF log.
* 
:::
* Keep in func AuthenticationProcedure
* **Call (Function)**
4. func SendAuthenticationRequest
* 
* **Call (Function)**

* func BuildAuthenticationRequest

* It use the context from AUSF's reponse to build the request sending to UE by 5G-AKA or EAP-AKA'


* **Return :** 
* **Call (Function)**

* func SendDownlinkNasTransport

* It builds nas message in ngap folder then send to RAN and UE.

* No **Return** unless error happends.
* Use timer waiting for UE and decide if it need a retransmission.

* No **Return (3)** unless error happends.
5. (3) func AuthenticationProcedure
* **Return to (0) in red framed place** after sending the request to UE.
6. (0) func Authentication
* This function receive the state, event and arg of UE, then use switch to decide the event related to authentication, and it doesnt have return value, it's like a divider.
* So we dont have clues about next step, and also serch this function name got too much results, here search the logs directly.
7. 1~3 include the interactions with UE, so I dont take time on them.

1. 
* 
* 
* 
* Dispach is too much to find the source.
2. 
* 
* 
* Same as 1.
3. 
* This one is like the start of authentication procedure, which can not be found like the [foreword](https://hackmd.io/fH1eBOchRbGLQA3qb202PQ?both#Foreword) says.
4. Next log we can get the clue.
8. func HandleAuthenticationResponse
* The source is also one case from , so like 6. says.
* 
* It stops the timer 

* It decodes the response and sends the confirm request to AUSF, so it belongs to Part 2.
## Stratagy 1
* Simplify the go.mod procedure
* Check whether we need this module or not.

* In the debug on undefined parameters process, some functions may not be used like the AUSF config & context, need to check how to reduce them.
## Modification 1
### Prerequisite
* Remove the AUSF in run.sh and Makefile
* Move the producer folder in AUSF

to the neighbor of AMF,

* 
### 1st authentication request

#### AMF side ()
:::warning
1. Stop the AUSF selecting process in func AuthenticationProcedure
* 
* 
2. In func SendUEAuthenticationAuthenticateRequest.
* Print the authinfo to see the content,


* but I dont know the meaning of this kind of parameter format,

* it seems like it doesnt need to be modified, because the receiver side has the same format (models.AuthenticationInfo) .


* And the other parameter  .
* ~~I cant find where it is from in the context folder in amf/internal.~~
* Actually it is from  .
* It is kinda complex, it is a specific method in Go language, here it can be used in API searching.
* [Link](https://garyliao-13743.medium.com/go-context-23c80159854c)
* **Modification of sender**
* Comment out parameter not using.

* Directly call the func UeAuthPostRequestProcedure

* Need to test the cooperation with the receiver's three return parameter.
* And need to add some lines dealing the error (if locationURI ... then ...) .
:::
#### AUSF side ()
:::warning
1. In func HandleUeAuthPostRequest
* Comment out the API forwarding function 
* There are another two forwarding function for confirming the 5g-aka and eap-aka', which may use in next round of request and response.
2. In func UeAuthPostRequestProcedure.
* In all of the files in producer_ausf, change the package name
* And the imported path is from github, so just reserve it, I will move the local imported files to amf and modify the path if some errors shows up.

* **Modification of receiver :**
* Stays the same, but Im not sure if the passing parameter is matched after jump through the forwarding part.
* Like the pointer parameter or some other wrapping process.

:::
#### Test
:::spoiler 1. Debug on Go module problems
1. Forget to import the path of receiver.

* ~~Just using 相對路徑導入, if these two files are in the same folder (sbi) .~~

* Actually it need to be in the same packge (need all of them using packge sbi, not packge consumer & packge producer_ausf), so it need 絕對路徑導入 (it is not flexible, need to change the path when moving to other environment.).

or

2. No set GOPATH.

* First error is because of the redudant slash before home.
* Second error is because "go build" or "go install" will find the packge under GOPATH or GOROOT, and GOROOT is the official packages path, so we need to set a GOPATH.
* [Solu](https://hackmd.io/DETj57LjQFimKBIOaD6csQ?both#GOPATH)
3. About make command.
* When I use make to compile again, the same error pops up even that I have set the GOPATH, it may related to the compiling method.

* Go build is to directly compile go language.
* Make use makefile to implimenting lots of command in one time, so maybe there is some default setting in makefile that will cover the manual set GOPATH.
* Modify part of Makefile.

* $(ROOT_PATH) represent the absolute path of Makefile, it use $(shell pwd) to get the path of current directory, then give it to $(ROOT_PATH).
4. GOPATH -> Go mudule
* After modifying the Makefile and trying many kind of solutions (set GOPATH, move producer_ausf to amf/consumer and test), the results still searchs in GOROOT only.

* Then I find a [solu](https://stackoverflow.com/questions/62760999/how-to-make-go-search-for-packages-in-gopath-while-importing-a-package) on google, but the result is like below altough I have set the GOPATH.

* Then I find that there is no go.mod in free5gc_AUSF_v2.0, but go.mod exists in MFs/amf,

and chatGPT give the answar like below :
根据提供的 `go.mod` 文件, amf的模块路径为 `github.com/free5gc/amf`。如果您的 `producer_ausf` 也是在 `github.com/free5gc` ,应该可以被正确地导入。请确保在 `producer_ausf` 模块中的代码中,导入路径应该是`github.com/free5gc/amf/internal/sbi/producer_ausf`。
* Q & A
* Q : producer_ausf是我自己建的,而非在github上
A : 由于 producer_ausf 是您自己在本地项目中创建的模块,需要正确设置 GOPATH 和 GO111MODULE。
1. 首先,确保您的 GOPATH 环境变量已经正确设置为 /home/ubuntu/free5gc_AUSF_v2.0。您之前提到已经设置了,这一步应该没问题。
2. 接下来,确保您的项目目录结构正确。producer_ausf 应该位于 /home/ubuntu/free5gc_AUSF_v2.0/NFs/amf/internal/sbi/producer_ausf。您之前提到已经建立了该路径,所以这一步也应该没问题。
3. 然后,**请确保您在 go.mod 中指定了您的项目路径。本地项目需要在 go.mod 中加 replace 指令,告诉编译器在构建时使用本地路径**。
5. 最后,请确保您在导入 producer_ausf 时使用正确的导入路径。在 amf 模块的代码中,导入路径应该是 github.com/free5gc/amf/internal/sbi/producer_ausf,而不是 NFs/amf/internal/sbi/producer_ausf。
* Q : 為何使用NFs/amf/internal/sbi/producer_ausf是不行的 就算我已經設置GOPATH
A : 问题可能出在导入路径的解析上。**在 Go 1.11 之后,当您使用 go mod 管理依赖关系时,Go 将不再依赖于 GOPATH 来解析导入路径。**
* 当您使用相对路径 NFs/amf/internal/sbi/producer_ausf 时,Go 编译器会将其解释为相对于当前目录的导入路径。由于您的项目不在 GOPATH 中,编译器无法正确地解析该路径,导致无法找到相应的模块。
* 您应该使用绝对路径或者正确的模块路径来导入模块。**正确的导入路径应该是 github.com/free5gc/amf/internal/sbi/producer_ausf。** 然后在 go.mod 文件中,使用 replace 指令将该路径映射到本地路径。
* Q : 所以在有使用go.mod的資料夾中 無法透過設置GOPATH來導入自己建立的檔案 只能透過已經啟用的go mod來管理嗎?
A : 是的,您的理解基本上是正确的。
* **在使用 go mod 管理依赖关系时,Go 编译器会优先使用模块的根目录来解析导入路径,而不是依赖于 GOPATH。** 因此,即使您设置了 GOPATH,也不会影响 go mod 项目中的导入路径解析。
* 如果您希望在 go mod 项目中引入自己的本地包或模块,通常的做法是将其放置在正确的模块路径下,并确保在 go.mod 文件中正确地指定了依赖关系。**如果您的本地包或模块并不是一个独立的模块,而只是当前项目的一部分,您可以使用 replace 指令将本地路径映射到正确的模块路径,以便在开发过程中使用。**
* Q : 為何要使用replace而非直接設置絕對路徑在go.mod中
A : 可以直接在 go.mod 文件中指定本地包或模块的绝对路径。使用 replace 的情况通常是在以下情形下:
* 开发时使用本地修改的包或模块:如果您在开发过程中对本地包或模块进行了修改,并且希望立即看到这些修改的效果。
* 依赖管理工具支持:有些依赖管理工具或持续集成工具可能会自动地将 replace 指令用于本地路径的解决方案。这可以确保在开发和构建过程中始终使用正确的依赖关系。
* Q : 如何直接設定絕對路徑
A : 添加一个 replace 指令,将您的本地路径映射到您的模块或包。
* 这将告诉 Go 编译器在构建过程中将 github.com/yourusername/yourmodule 映射到您的本地路径 /path/to/yourmodule。然后,您可以在您的代码中使用 github.com/yourusername/yourmodule,Go 编译器将会自动将其解析为您的本地路径。
* 这种方法仅适用于开发阶段,因为其他人无法访问您的本地路径。一旦您准备好将代码推送到公共存储库,您应该将 replace 指令删除,或者使用相对于 GOPATH 或者模块的路径。
* Q : 我原本就沒有設置github.com/free5gc/amf/internal/sbi/producer_ausf而想要直接使用/home/ubuntu/free5gc_AUSF_v2.0/NFs/amf/internal/sbi/producer_ausf
A : import ("home/ubuntu/free5gc_AUSF_v2.0/NFs/amf/internal/sbi/producer_ausf")
* Q : ../internal/sbi/consumer/ue_authentication.go:19:2: package home/ubuntu/free5gc_AUSF_v2.0/NFs/amf/internal/sbi/producer_ausf is not in GOROOT(/usr/local/go/src/home/ubuntu/free5gc_AUSF_v2.0/NFs/amf/internal/sbi/producer_ausf)
A : **在 Go 中,包的导入路径应该是相对于 $GOPATH/src 或者是在使用 go mod 的情况下,相对于模块的根目录。由于您想要导入的包路径不是相对于这些目录的,因此 Go 编译器无法找到该包。**
* 一种解决方法是**将您的项目作为一个模块来管理**,这样您就可以使用 go mod 来管理依赖关系,并且可以在任何地方导入该包。要将您的项目初始化为模块,可以执行以下命令:
* cd /home/ubuntu/free5gc_AUSF_v2.0
go mod init github.com/yourusername/yourprojectname
* 然后,您可以使用 go mod tidy 命令来整理并下载所需的依赖项。之后,您就可以在您的代码中导入 producer_ausf 包了。
* **但這樣子就得結合github,所以還是得嘗試使用replce**
* Q : replace放在require中還是外面
A : 
* Need to do some study about :
* Import of Go. [Link](https://www.cnblogs.com/f-ck-need-u/p/9847554.html)
* And the nameing rule of Go, what kind of function is visible in imported file, what kind of function is not. [Link](https://hackmd.io/@Aquamay/r13t064Yd)
* And also the path methods of Go, below is the example.

* [Go module & GOPATH](https://ithelp.ithome.com.tw/articles/10217414?sc=rss.iron)
:::
:::success
* The conoclution of Go module :
* Free5GC use go.mod in every NFs to manage the imported packges, so set GOPATH is useless.
* In go.mod, we have two methods to add a local path :
* Put the path outside the root folder of go.mod, and use the absolute path.
* But the local file is put in amf(which has its own go.mod), so it need to use go mod init to modulize and tidy with the github.
* This method is not clear for me, I need more study.
* Use replace for mapping the github path to local path.
* Replace method has some problem, the imported local file also imports other github path, so it need git get to get it from github.



* You can try the go get command.
* But if I go get these modules, it still uses the AUSF contents, the got package from AUSF shouldnt be existed, I have two options :
1. Move these folder from AUSF to AMF locally, and also add the path using replace.
* This method is not totally equal to go get, because it modify the path and files into local contents of AMF.
* It also need to change the path when the environment is changed.
2. Directly put the functions in the same file and use function calling.
* I think it's too complicated, maybe I will put it as the last step of improvement.
* Replace problem
* Move four folders to AMF.

* Change the path in the error file :
* 
* 
* Add new lines in go.mod.
* 
* The moved files need to change the imported path too.
* 


* 

* 

* 

* 

* 

* I dont know why these errors dont show up at the same time, so if you want to solve them asap, you can directly comment out all related lines at first.
* Remained errors

* In amf folder and go get them, but the third one didnt have a message after typing the command, but it still worked.

:::
:::spoiler 2. Debug on undefined parameter and imported not use path
* The new moved file has some parameter undefined.

* In func BuildNFInstance

* **Forgot to change the belonged packge of those moved files.**
* 

* 
* 

* 

* Some **function calling of logger are undefined** because of the changed name logger_ausf.

* And **the changed path is also not used** because of it.
* I don't know whether this error files will be used or not, because config.go is for AUSF configuration, but it may be abandoned in the future, **I just recover them for current debugging process, maybe I will comment out all of them, maybe not**.
* 
* 
* 
* 
* 
* 
* 
* 
* 
* More undefined problems.

* Same method, recover them first.
* 
* 
* 
* 
* 
* 
* 
* More.

* 
* 
* 
* 
* 
* It comes back again.

* I dont know why it is undefined, because the called function is model from openapi, it should be defined properly.
* But when I look back to the original file in AUSF, it doesnt include the "s", I don’t know when to **typed one more letter and saved the file**.

* After restoring it, there is no problem.
* More...



* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* More......




* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* The use of logger.

* The use of factory.

:::
:::success
* After changing all the parameters, they can call each other in AMF.
* Next, modify the code to fix the errors about integration test.
:::
:::spoiler 3. Debug on integrating errors
**Parameter transfering problem**

1. The original parameter is httpResponse in the 45 line, and after commenting out the api part in amf and ausf, httpResponse is not used, so I fill in the returned parameter locationURI instead, but the locationURI is originally used for producer side api handling.
* So I think I can directly comment out the URI construction process in producer side.

* Here other parameter using locationURI in 5g-AKA & EAPAKA' can be commented out, because the Links in response will be set nil as default, will not have any error.
* In Go, not initailed map will be nil.




* And the received & returned parameter number need to be modified to 2.







2. In amf side, the 66 line has got the *models.UeAuthenticationCtx but the 68 line return the address (*models.UeAuthenticationCtx) of it, so **don't need to add & before the parameter**.

* I think the reason is the original parameter used in the 45 line, implements **the openAPI transformation (httpwarpper) between AMF and AUSF which will add one more pointer (addressing) operation**.
3. Bsed on ChatGPT, responseBody and ueAuthenticationCtx have the same format *models.UeAuthenticationCtx, so they wont conflict.
4. Compile has error,

so I change the commenting out method, maybe the original one is wrong.

* But the error stays the same, then I find the function title definds the number of returned values,

so I change it.

* Another error like this.

If I change like this (the commenting out part doesnt affect).

It cause another error.

* After trying, below two kind of methods are correct way to define function.

or

**Adding a comma at the end or put in same line.**
**Bug 2**

* It call itself, so just change the parameter number

:::
:::success
* The compiling result is successful

:::
:::spoiler 4. Debug on function problems after function integrated successfully.

* This problem is about ServingNetworkAuthorized function, maybe the parameter got from amf calling is not matching after killing the openAPI.

* Here print it to compare with orginal one (Using %+v in both places).


* The result is that the values of them are the same.



* Check back to the place that it use ausf_context to call IsServingNetworkAuthorized function, and in this function it match the snName from AMF with snRegex in AUSF.


* The AUSFContext should not be created because I commented out AUSF finding process.
* So maybe the serving network check part can be commented out too.
:::
:::success
* Pause in half done status, if you want to continue simplifying, you should start here.
* And

:::
## Analysis (Part 2)
* 3/25~
* As the **ending** of my stratay, investigate remained procedure, understand them, so I can continue to Terry's stratagy.
* If the parameters(XRES*, HXRES*...) between AMF and AUSF comfirming are needed or I can ignore them and use the generating function in UDM directly.
* Maybe the stratagy and modification parts also needed to be completed and concluded.
### Corresponded logs of part 2
* Dark place is where I need to skip in call flow.


#### Simple process
| Seq. | File name | Function name |
|:----:|:-------------------------------------------------- |:------------------------------------- |
| 0 |  | func Authentication |
| 1 |  | func HandleAuthenticationResponse |
| 2 |  | func SendAuth5gAkaConfirmRequest |
| 3 | API | API |
| 4 |  | func HandleAuth5gAkaComfirmRequest |
| 5 |  | func Auth5gAkaComfirmRequestProcedure |
| 6 | **Return (2)** | **Return (2)** |
| 7 | **Return (1)** | **Return (1)** |
#### Detailed process
1. func HandleAuthenticationResponse
* After the timer start in 4(Orange framed place), 5(Orange framed place) return to sm.go, then 6(Orange framed place) waits for the uplinkNAStransport from gnb.
* After dealing the NAS in 7(Orange framed place), we can find that 8(Orange framed place) is called by searching the log.
* The 8(Orange framed place) is 1(here), actually it is called by 0, which is triggered by the NAS message.

* After it stop the T3560, it uses switch to choose 5g-aka,

then gets the res*, calculates the HRES*, compare to HXRES*



then send comfirm request to AUSF, **call(function)**.

2. func SendAuth5gAkaConfirmRequest
* It's just below func SendUEAuthenticationAuthenticateRequest, in ueauthentication.go of amf side.
* **Call (AUSF)**

3. API (No explanation)
4. func HandleAuth5gAkaComfirmRequest
* 
* **Call (function)**

5. func Auth5gAkaComfirmRequestProcedure
* Check SUPI & get SUPI & use SUPI to get info.

* Use info to compare & print  .

* **Call (UDM)** to create AuthStatus.

* func sendAuthResultToUDM


* API (No explanation) & func HandleConfirmAuthDataRequest (print) & **Call(Function)**




* func ConfirmAuthDataProcedure & **Call (UDR)**

* API (No explanation) & In UDR (print)


* **Continuous return (AUSF)**
* **Return (4) & Return (2)**

6. (2) func SendAuth5gAkaConfirmRequest
* Deal with HTTP response from AUSF

* Return (1)
7. (1) func HandleAuthenticationResponse
* In the choose of 5g-aka, switch the confirm result. & **Call(function)** & **Reutrn (0)**

* func DerivateKamf

* func SendEvent (call callback function)


* I think here is the source to print it, which **ends the event of Authentication**.

* But I dont understand why the return use call function instead of err, in sm.go it use err to receive the return value.

* And I dont understand the relation between the exit event and the N1 message from AMF to UE.
* How to end the authentication and start the next stage ?
* Maybe the start and the end are both triggered by UE ?