Jimmy
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    [TOC] # Capture packets ## Information in wireshark ### RAND value ### AUTN value # GO language * 看要不要獨立一篇出來 * chatgpt之前問的問題要紀錄下來 ## main.go / init.go ![image](https://hackmd.io/_uploads/SkowVgeLC.png) ![image](https://hackmd.io/_uploads/HJr_Elx8A.png) ![image](https://hackmd.io/_uploads/BJ-YVxxLA.png) ### Example in Free5GC * You can find that there are some building logs when you run the run.sh, and they are really start from run.sh. ![image](https://hackmd.io/_uploads/HJwsDxg80.png) * After it do something, start UPF and MongoDB, it will run every NF in ~/bin/NF and read the config of them. ![image](https://hackmd.io/_uploads/B1z1uxxUC.png) ![image](https://hackmd.io/_uploads/rJBxdleLC.png) * If you see the log in detail, you can find some descreption of each NF, and it is not from run.sh because run.sh is done. ![image](https://hackmd.io/_uploads/SkbF8xeU0.png) * About the files in bin folder, we can not read it because of the garbled characters. ![image](https://hackmd.io/_uploads/HyJH5ggIC.png) ![image](https://hackmd.io/_uploads/H1Z4cggI0.png) * About the explanation of these files. ![image](https://hackmd.io/_uploads/HJog9gx8C.png) ![image](https://hackmd.io/_uploads/Sy2K5xxIC.png) * So after bin file is executed, system will enter main.go and it will call init.go, then in this process, you can the logs is printed from here. ![image](https://hackmd.io/_uploads/rJk6jxeUC.png) ![image](https://hackmd.io/_uploads/SJYTogxU0.png) * In init.go, you can see it imports a lot of service ![image](https://hackmd.io/_uploads/S1Kl2egUC.png) * And call some functions which will print out the logs. ![image](https://hackmd.io/_uploads/HyS-hggUA.png) ![image](https://hackmd.io/_uploads/BkLQ2geUA.png) ![image](https://hackmd.io/_uploads/rkxN3lxUR.png) ![image](https://hackmd.io/_uploads/HyjN3lxLR.png) ![image](https://hackmd.io/_uploads/rJF8nle8C.png) ## Go module :::warning ### Example before * [Link](https://hackmd.io/fH1eBOchRbGLQA3qb202PQ?view#Test) * Compared to my [study](https://hackmd.io/AMzUH2F7TzOxIo5o3H3CyA?both#import-method) on Terry's method. ::: :::success ### go.mod * I want to clearify the usage of this, because this is one of the point in the newer version(>1.11) of Go language, most of the import methods don't rely on GOPATH. * When I was browsing my past method and Terry's, I found that there is no a direct URL calling the Network Function in each go.mod, but it exists on the first line. ![image](https://hackmd.io/_uploads/BkakPINVR.png) * For ex, there is no 1 and 2 in go.mod, but for 3 there are in go.mod, which means I can directly import the things in the same amf folder. ![image](https://hackmd.io/_uploads/H1pTUUN4C.png) ### Answar ![image](https://hackmd.io/_uploads/SyZ0DU4NC.png) ![image](https://hackmd.io/_uploads/rJJ4_UEV0.png) ![image](https://hackmd.io/_uploads/S1eLuUNNR.png) ![image](https://hackmd.io/_uploads/S1TLOLEEC.png) ```go= go mod init github.com/yourusername/yourproject ``` ![image](https://hackmd.io/_uploads/H1wudI4N0.png) ![image](https://hackmd.io/_uploads/By4qOUN40.png) ![image](https://hackmd.io/_uploads/H1NdYUVER.png) ![image](https://hackmd.io/_uploads/BJ-tKL44R.png) ![image](https://hackmd.io/_uploads/HkfcY8440.png) ![image](https://hackmd.io/_uploads/BJFjF84NA.png) #### Test ![image](https://hackmd.io/_uploads/ryq6MekH0.png) ![image](https://hackmd.io/_uploads/BkNCMg1S0.png) ![image](https://hackmd.io/_uploads/r1nOKx1SA.png) ### replace * Before I know how Terry use the import, I dont understand why he doesnt use replace in go.mod to redirect the URL but he can import his own local folder. * Here is some concept of replace. ![image](https://hackmd.io/_uploads/SkXBkIEEA.png) ![image](https://hackmd.io/_uploads/SJUUJLNVR.png) ![image](https://hackmd.io/_uploads/B1vFkUVEC.png) ![image](https://hackmd.io/_uploads/HJ1T1UENA.png) ![image](https://hackmd.io/_uploads/Sy1RJ8EE0.png) * So the point is that **there has already a UR**L which calls the resouce from github, and **we use "replace" to cut the link with github, rebuild a link with local folder/file** if we want to do a test in local environment. * Then what I had done using replace may be **an unnecessory move**, because the OG URL has already call the folder I want to use, and replace just add one more command to call the local path. ![image](https://hackmd.io/_uploads/ryoFbIENA.png) #### The environment path check ![image](https://hackmd.io/_uploads/Bk29mLNEC.png) #### Some other possibility ![image](https://hackmd.io/_uploads/rkv6XUENR.png) ```go= go env GOPATH //This command is also useful for check the location. ``` ![image](https://hackmd.io/_uploads/HJ2ZEI4EC.png) ```go= go list -m all ``` ![image](https://hackmd.io/_uploads/SyfuV8V4A.png) ![image](https://hackmd.io/_uploads/HJi_E8V40.png) ![image](https://hackmd.io/_uploads/BJLKVLV4A.png) ![image](https://hackmd.io/_uploads/H1b9VL44A.png) > ### import ### import( github.com/... ) * When I was modifying the UDM/UDR part in AUSF improvement, I found that there is no this imported address in the local free5gc folder (free5gc/util/...). ![image](https://hackmd.io/_uploads/BkYCOHNVA.png) * But it is indeed in the go.mod in UDR. ![image](https://hackmd.io/_uploads/HkjOKrNNA.png) * **The answar is in the [repository](https://github.com/orgs/free5gc/repositories)** on free5GC official github, the URL will be the same as what you import when you click into one of the repo. ![image](https://hackmd.io/_uploads/BJAwcBVER.png) ::: ### Use code from github :::spoiler reference https://blog.csdn.net/yeshang_lady/article/details/134272955 https://home.gamer.com.tw/artwork.php?sn=5463024 ![image](https://hackmd.io/_uploads/rygEaz996.png) ::: #### Code * In smf, take sm_context.go in package context as example, below are the functions it import, some are the functions from the official go language, the other imported lines including "github.com/..." are from the github of free5gc. ![image](https://hackmd.io/_uploads/Bk--2McqT.png) ![image](https://hackmd.io/_uploads/Sy6Pjvqq6.png) * You can see the reference about how you can add the frepository into your code, in free5gc's NFs, every NF has a file called go.mod, recording the url it imports. ![image](https://hackmd.io/_uploads/HybUKPqqa.png) * Until here, Im curious about if the free5gc works without internet, because the modules from github are imported, not copied to local host, so I do a test closing the network interface and running the 5gc. The result is that it needs addresses binded for using http service, but it doesnt explan whether the github module affect the program. ![image](https://hackmd.io/_uploads/rkqFuw9qa.png) ### Use code from local place :::spoiler reference https://calvertyang.github.io/2019/11/12/a-beginners-guide-to-packages-in-golang/ ::: #### Package context ![image](https://hackmd.io/_uploads/HJQuCx65T.png) ![image](https://hackmd.io/_uploads/HyDtAeTca.png) ![image](https://hackmd.io/_uploads/Sk8qCxaq6.png) #### Package ![image](https://hackmd.io/_uploads/SJ3lyWaqa.png) ![image](https://hackmd.io/_uploads/SkBMJb65p.png) ![image](https://hackmd.io/_uploads/rJSQkZT9T.png) ### GOPATH * Check the path in your environment, it will be void if you havent set GOPATH. * The default path will be $HOME/go if your version >= Go 1.11 ```shell= echo $GOPATH ``` * Set the path. * It will not affect other path directly, GOPATH is used for store 3rd party packages or items, and dealing with the improting relation in Go, it will tell compiler where to find and check the library. * Other package provided by Go standard library exist when installing Go, and can be accessed everywhere. ```shell= export GOPATH=/home/ubuntu/free5gc_AUSF_v2.0 ``` ## make ![image](https://hackmd.io/_uploads/H1_hh7_SA.png) :::danger ![image](https://hackmd.io/_uploads/S1xWeT7uBA.png) ::: :::success ![image](https://hackmd.io/_uploads/r1EX6XOHC.png) ::: ## Run .go in VScode ![image](https://hackmd.io/_uploads/Hkcvmuh7R.png) ![image](https://hackmd.io/_uploads/Bk5tmO27A.png) ```go= package main import ( "fmt" "strings" ) func main() { suci := "suci-0-208-93-0000-0-0-0000000003" parts := strings.Split(suci, "-") lastPart := parts[len(parts)-1] supi := "imsi-20893" + lastPart fmt.Println(supi) // 輸出: imsi-208930000000003 } ``` ![image](https://hackmd.io/_uploads/rJfpXO2QR.png) ```shell= go mod init example.com/myapp ``` ![image](https://hackmd.io/_uploads/Sk7RQ_2mC.png) ```shell= go run main.go ``` ![image](https://hackmd.io/_uploads/BJBCkq3mC.png) ### Set the environment PATH for Go :::danger * Error when I want to go run. ``` go : 無法辨識 'go' 詞彙是否為 Cmdlet、函數、指令檔或可執行程式的名稱。請檢查名稱拼字是否正確,如果包含路徑的話,請確認路徑是否正 確,然後再試一次。 位於 線路:1 字元:1 + go run main.go + ~~ + CategoryInfo : ObjectNotFound: (go:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException ``` ::: :::success * Usually after the installation, the PATH of Go will be added automatically, like the pic below, I added it repeatly. ![image](https://hackmd.io/_uploads/HkYHTK37C.png) * The reason why this error popped up is that I need to **restart the VScode** after installing Go, after restart : ![image](https://hackmd.io/_uploads/SyMURFnQR.png) ![image](https://hackmd.io/_uploads/BJKwJqhXR.png) ::: ![image](https://hackmd.io/_uploads/S1WCEdhmR.png) ![image](https://hackmd.io/_uploads/HJh0VOnmR.png) ```shell= go version ``` ![image](https://hackmd.io/_uploads/HkwlB_nXA.png) ![image](https://hackmd.io/_uploads/ByXanY3XR.png) ## const ```go= // suci-0(SUPI type: IMSI)-mcc-mnc-routingIndicator-protectionScheme-homeNetworkPublicKeyID-schemeOutput. // TODO: // suci-1(SUPI type: NAI)-homeNetworkID-routingIndicator-protectionScheme-homeNetworkPublicKeyID-schemeOutput. const ( PrefixPlace = iota SupiTypePlace MccPlace MncPlace RoutingIndicatorPlace SchemePlace HNPublicKeyIDPlace SchemeOuputPlace MaxPlace ) const ( PrefixIMSI = "imsi-" PrefixSUCI = "suci" SupiTypeIMSI = "0" NullScheme = "0" ProfileAScheme = "1" ProfileBScheme = "2" ) func ToSupi(suci string, suciProfiles []SuciProfile) (string, error) { suciPart := strings.Split(suci, "-") logger.SuciLog.Infof("suciPart: %+v", suciPart) suciPrefix := suciPart[0] if suciPrefix == "imsi" || suciPrefix == "nai" { logger.SuciLog.Infof("Got supi\n") return suci, nil } else if suciPrefix == PrefixSUCI { if len(suciPart) < 6 { return "", fmt.Errorf("Suci with wrong format\n") } } else { return "", fmt.Errorf("Unknown suciPrefix [%s]", suciPrefix) } logger.SuciLog.Infof("scheme %s\n", suciPart[SchemePlace]) scheme := suciPart[SchemePlace] mccMnc := suciPart[MccPlace] + suciPart[MncPlace] supiPrefix := PrefixIMSI if suciPrefix == PrefixSUCI && suciPart[SupiTypePlace] == SupiTypeIMSI { logger.SuciLog.Infof("SUPI type is IMSI\n") } if scheme == NullScheme { // NULL scheme return supiPrefix + mccMnc + suciPart[len(suciPart)-1], nil } . . . ``` :::danger * How ToSupi can use the variable MccPlace or MncPlace without calling ? ::: :::success ![image](https://hackmd.io/_uploads/BkbGdnp7C.png) ![image](https://hackmd.io/_uploads/Hygvu367C.png) ![image](https://hackmd.io/_uploads/S1nvu2p7R.png) ::: ![image](https://hackmd.io/_uploads/rJ83uh6XA.png) ![image](https://hackmd.io/_uploads/SkkCd3TmA.png) ![image](https://hackmd.io/_uploads/HJKJF36m0.png) ## P0 := []byte(snName) ![image](https://hackmd.io/_uploads/BJiql7j7C.png) ```go= package main import "fmt" func main() { snName := "Hello, Go!" P0 := []byte(snName) fmt.Println("Original string:", snName) fmt.Println("Byte slice:", P0) } ``` ![image](https://hackmd.io/_uploads/ByY3emoQC.png) ## Return ### return "" & return nil ![image](https://hackmd.io/_uploads/ryktGmjQC.png) ```go= package main import "fmt" func getEmptyString() string { return "" } func main() { result := getEmptyString() fmt.Println(result) // 輸出一個空行,因為 result 是一個空字符串 } ``` ![image](https://hackmd.io/_uploads/SJihf7o70.png) ![image](https://hackmd.io/_uploads/Hyvpz7s70.png) ![image](https://hackmd.io/_uploads/HJ90GmsQC.png) ```go= package main import "fmt" // 返回空字符串 func getEmptyString() string { return "" } // 返回空指針 func getNilPointer() *int { return nil } // 返回空切片 func getNilSlice() []int { return nil } // 返回空映射 func getNilMap() map[string]int { return nil } // 返回空通道 func getNilChannel() chan int { return nil } // 返回空接口 func getNilInterface() interface{} { return nil } func main() { fmt.Println("Empty String:", getEmptyString()) fmt.Println("Nil Pointer:", getNilPointer()) fmt.Println("Nil Slice:", getNilSlice()) fmt.Println("Nil Map:", getNilMap()) fmt.Println("Nil Channel:", getNilChannel()) fmt.Println("Nil Interface:", getNilInterface()) } ``` ![image](https://hackmd.io/_uploads/Hy_lQXomC.png) ## API link ![image](https://hackmd.io/_uploads/SyS63EiQ0.png) ```go= package models type LinksValueSchema struct { Href string `json:"href"` } ``` ![image](https://hackmd.io/_uploads/HJa0nNjX0.png) --- ![image](https://hackmd.io/_uploads/SkYF6Ej7C.png) ```go= linksValue := models.LinksValueSchema{Href: putLink} responseBody.Links = make(map[string]models.LinksValueSchema) responseBody.Links["5g-aka"] = linksValue ``` * make function doesnt need to import module. ![image](https://hackmd.io/_uploads/r1AbpNo7A.png) ![image](https://hackmd.io/_uploads/rk3M6EomR.png) ![image](https://hackmd.io/_uploads/HkDmaEsm0.png) ```go= //You can use this example to print the result, and see the structure. package main import ( "fmt" "models" ) func main() { // 假設 putLink 是一個有效的 URL 字串 putLink := "https://example.com/5g-aka" // 創建 LinksValueSchema 實例 linksValue := models.LinksValueSchema{Href: putLink} // 初始化 responseBody 的 Links 映射 var responseBody models.ResponseBody responseBody.Links = make(map[string]models.LinksValueSchema) // 將 linksValue 添加到映射中,鍵為 "5g-aka" responseBody.Links["5g-aka"] = linksValue // 打印結果 fmt.Println(responseBody) } ``` ## strictHex() ![image](https://hackmd.io/_uploads/rkxbvYNN0.png) ```go= func strictHex(s string, n int) string { l := len(s) if l < n { return fmt.Sprintf(strings.Repeat("0", n-l) + s) } else { return s[l-n : l] } } ``` ![image](https://hackmd.io/_uploads/rJhGwYN40.png) ```go= package main import ( "fmt" "strings" ) func strictHex(s string, n int) string { l := len(s) if l < n { return fmt.Sprintf(strings.Repeat("0", n-l) + s) } else { return s[l-n : l] } } func main() { authSubsSequenceNumber := "12345" sqnStr := strictHex(authSubsSequenceNumber, 12) fmt.Println(sqnStr) // 輸出 "0000000012345" authSubsSequenceNumber = "1234567890ABCDEF" sqnStr = strictHex(authSubsSequenceNumber, 12) fmt.Println(sqnStr) // 輸出 "7890ABCDEF" } ``` ![image](https://hackmd.io/_uploads/rySNvFNVA.png) ## Some computation ### big/SetString ![image](https://hackmd.io/_uploads/BJMXz1vrR.png) ```go= package main import ( "fmt" "math/big" ) func main() { sqnStr := "123ABC" bigSQN := new(big.Int) bigSQN, success := bigSQN.SetString(sqnStr, 16) if !success { fmt.Println("轉換失敗") } else { fmt.Println("轉換成功:", bigSQN) } } ``` ![image](https://hackmd.io/_uploads/SylrzJDS0.png) ```go= // 假設 authSubs.SequenceNumber 是一個十六進制字符串 sqnStr := "16f3b3f70ff2" bigSQN := new(big.Int) bigSQN, success := bigSQN.SetString(sqnStr, 16) if !success { logger.GmmLog.Infof("轉換失敗") return nil, fmt.Errorf("無法轉換序列號") } // 進行大數運算,例如增加序列號 bigInc := big.NewInt(1) bigSQN.Add(bigSQN, bigInc) // 將結果轉換回十六進制字符串 newSqnStr := fmt.Sprintf("%x", bigSQN) logger.GmmLog.Infof("新的序列號: %s", newSqnStr) ``` ### NewInt/Add/Mod ![image](https://hackmd.io/_uploads/rkcSHkDBC.png) ![image](https://hackmd.io/_uploads/Sy7UHyvB0.png) ```go= package main import ( "fmt" "math/big" ) func main() { // 定義常數和初始值 SqnMAx := int64(0xFFFFFFFFFFFF) sqnStr := "16f3b3f70ff2" // 將 sqnStr 轉換為大數 bigSQN := new(big.Int) bigSQN, success := bigSQN.SetString(sqnStr, 16) if !success { fmt.Println("轉換失敗") return } // 定義增量和最大值 bigInc := big.NewInt(1) bigP := big.NewInt(SqnMAx) // 增加序列號並進行模運算 bigSQN.Add(bigSQN, bigInc) bigSQN.Mod(bigSQN, bigP) // 將結果轉換回十六進制字符串 newSqnStr := fmt.Sprintf("%x", bigSQN) fmt.Println("新的序列號:", newSqnStr) } ``` ## Declaration & :=, =, == ![image](https://hackmd.io/_uploads/SyrULzdrC.png) ```go= package main import "fmt" // 全域變數宣告 var globalVar int = 100 func main() { // 宣告並初始化變數 var a int = 10 var b = 20 // 類型推斷 var c int // 宣告但不初始化,默認值為 0 fmt.Println(a, b, c) fmt.Println(globalVar) } ``` ![image](https://hackmd.io/_uploads/rJtF8MdSR.png) ![image](https://hackmd.io/_uploads/Skv9UMdSA.png) ```go= package main import "fmt" func main() { var ( a int = 10 b string = "hello" c float64 = 3.14 ) fmt.Println(a, b, c) } ``` ![image](https://hackmd.io/_uploads/BJeh8MOSC.png) ```go= package main import "fmt" func main() { const pi = 3.14159 const hello = "Hello, World!" fmt.Println(pi) fmt.Println(hello) } ``` ![image](https://hackmd.io/_uploads/ByYTUzOSC.png) ```go= package main import "fmt" func add(a int, b int) int { return a + b } func main() { result := add(3, 4) fmt.Println(result) // 輸出: 7 } ``` ![image](https://hackmd.io/_uploads/rJwALGdSR.png) ```go= package main import "fmt" func swap(a, b int) (int, int) { return b, a } func main() { x, y := swap(3, 4) fmt.Println(x, y) // 輸出: 4 3 } ``` ![image](https://hackmd.io/_uploads/Sy41wfdr0.png) ```go= package main import "fmt" func divide(a, b int) (result int, err error) { if b == 0 { err = fmt.Errorf("division by zero") return } result = a / b return } func main() { result, err := divide(10, 2) if err != nil { fmt.Println("Error:", err) } else { fmt.Println("Result:", result) // 輸出: Result: 5 } } ``` ![image](https://hackmd.io/_uploads/BJlgPMdBR.png) ![image](https://hackmd.io/_uploads/SkWtrMOHA.png) ```go= package main import "fmt" func main() { // 使用 := 進行變數宣告和賦值 a := 5 // a 是 int 型別,值為 5 b := "hello" // b 是 string 型別,值為 "hello" c := 3.14 // c 是 float64 型別,值為 3.14 // 打印變數的值 fmt.Println(a) // 輸出: 5 fmt.Println(b) // 輸出: hello fmt.Println(c) // 輸出: 3.14 } ``` ![image](https://hackmd.io/_uploads/rJrcHGOHR.png) ```go= package main import "fmt" func main() { // 使用 := 宣告並初始化變數 x := 10 fmt.Println(x) // 輸出: 10 // 使用 = 賦值給已宣告的變數 x = 20 fmt.Println(x) // 輸出: 20 } ``` ![image](https://hackmd.io/_uploads/HJjsHzdrC.png) ```go= package main import "fmt" func main() { a := 5 b := 5 c := 10 // 使用 == 比較變數的值 fmt.Println(a == b) // 輸出: true fmt.Println(a == c) // 輸出: false } ``` ![image](https://hackmd.io/_uploads/HkHaBGuSC.png) ## recover() ![image](https://hackmd.io/_uploads/HkIuqQuS0.png) ```go= func main() { defer func() { if r := recover(); r != nil { fmt.Println("Recovered from panic:", r) } }() mightPanic() fmt.Println("This will not be printed if panic is not recovered") } func mightPanic() { panic("Something went wrong!") } ``` ![image](https://hackmd.io/_uploads/HyCFqQdBC.png) ```go= package main import ( "fmt" ) func main() { safeFunction() fmt.Println("Program continues to run...") } func safeFunction() { defer func() { if r := recover(); r != nil { fmt.Println("Recovered in safeFunction:", r) } }() panicFunction() } func panicFunction() { panic("A severe error occurred!") } ``` ![image](https://hackmd.io/_uploads/HyEs5X_SA.png) ## map[string]interface {} ![image](https://hackmd.io/_uploads/HkqULqFrC.png) ```go= package main import ( "fmt" ) func main() { // 定義一個 map[string]interface{} data := make(map[string]interface{}) // 向 map 中添加不同類型的數據 data["name"] = "Alice" data["age"] = 30 data["isStudent"] = false data["grades"] = []int{85, 90, 92} // 訪問 map 中的數據 fmt.Println("Name:", data["name"]) fmt.Println("Age:", data["age"]) fmt.Println("Is Student:", data["isStudent"]) fmt.Println("Grades:", data["grades"]) } ``` ![image](https://hackmd.io/_uploads/rJkuU5tr0.png) ```go= package main import ( "encoding/json" "fmt" ) func main() { jsonString := `{ "name": "Bob", "age": 25, "isStudent": true, "grades": [88, 76, 93] }` var data map[string]interface{} // 將 JSON 字符串解析為 map[string]interface{} err := json.Unmarshal([]byte(jsonString), &data) if err != nil { fmt.Println("Error:", err) return } // 訪問解析後的數據 fmt.Println("Name:", data["name"]) fmt.Println("Age:", data["age"]) fmt.Println("Is Student:", data["isStudent"]) fmt.Println("Grades:", data["grades"]) } ``` ![image](https://hackmd.io/_uploads/BJ_FI9FHA.png) ```go= func main() { data := map[string]interface{}{ "name": "Alice", "age": 30, "isStudent": false, "grades": []int{85, 90, 92}, } // 類型斷言 name, ok := data["name"].(string) if !ok { fmt.Println("Name is not a string") } else { fmt.Println("Name:", name) } age, ok := data["age"].(int) if !ok { fmt.Println("Age is not an int") } else { fmt.Println("Age:", age) } isStudent, ok := data["isStudent"].(bool) if !ok { fmt.Println("isStudent is not a bool") } else { fmt.Println("Is Student:", isStudent) } grades, ok := data["grades"].([]int) if !ok { fmt.Println("Grades is not a []int") } else { fmt.Println("Grades:", grades) } } ``` ![image](https://hackmd.io/_uploads/Skfo8qKBA.png) ### The reason MongoDB use this format ![image](https://hackmd.io/_uploads/HyiaI5Kr0.png) ```shell= go get go.mongodb.org/mongo-driver/mongo ``` ![image](https://hackmd.io/_uploads/S1xkPqKSA.png) ```go= package main import ( "context" "fmt" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/bson" "log" "time" ) func main() { // 設置 MongoDB 連接選項 clientOptions := options.Client().ApplyURI("mongodb://localhost:27017") // 連接到 MongoDB client, err := mongo.Connect(context.TODO(), clientOptions) if err != nil { log.Fatal(err) } // 檢查連接是否成功 err = client.Ping(context.TODO(), nil) if err != nil { log.Fatal(err) } fmt.Println("Connected to MongoDB!") // 指定數據庫和集合 collection := client.Database("testdb").Collection("testcollection") // 查詢一個文檔 var result bson.M filter := bson.M{"name": "Alice"} err = collection.FindOne(context.TODO(), filter).Decode(&result) if err != nil { log.Fatal(err) } // 打印結果 fmt.Println("Result:", result) // 關閉連接 err = client.Disconnect(context.TODO()) if err != nil { log.Fatal(err) } fmt.Println("Connection to MongoDB closed.") } ``` ![image](https://hackmd.io/_uploads/H1vlD5KHA.png) ```go= // 假設 result 已經包含從 MongoDB 查詢到的數據 name, ok := result["name"].(string) if ok { fmt.Println("Name:", name) } age, ok := result["age"].(int32) if ok { fmt.Println("Age:", age) } ``` ### Why don't we access the content of this format in free5GC directly, but use structure to replace ? ![image](https://hackmd.io/_uploads/ByjTwcYSR.png) ```go= authSubs := map[string]interface{}{ "authenticationMethod": "5G_AKA", "permanentKey": map[string]interface{}{ "permanentKeyValue": "8baf473f2f8fd09487cccbd7097c6862", "encryptionAlgorithm": "0", "encryptionKey": "0", }, "sequenceNumber": "000000000034", "authenticationManagementField": "8000", "milenage": map[string]interface{}{ "op": map[string]interface{}{ "opValue": "8e27b6af0e692e750f32667a3b14605d", "encryptionAlgorithm": "0", "encryptionKey": "0", }, "opc": map[string]interface{}{ "opcValue": "", "encryptionAlgorithm": "0", "encryptionKey": "0", }, }, "ueId": "imsi-208930000000003", } ``` ![image](https://hackmd.io/_uploads/HJ7yuqFBC.png) ```go= // 先從 map 中取出 permanentKey permanentKey, ok := authSubs["permanentKey"].(map[string]interface{}) if !ok { // 處理錯誤,例如 permanentKey 字段不存在或類型不匹配 log.Fatalf("permanentKey not found or not a map[string]interface{}") } // 從 permanentKey 中取出 permanentKeyValue permanentKeyValue, ok := permanentKey["permanentKeyValue"].(string) if !ok { // 處理錯誤,例如 permanentKeyValue 字段不存在或類型不匹配 log.Fatalf("permanentKeyValue not found or not a string") } fmt.Println("PermanentKeyValue:", permanentKeyValue) ``` ![image](https://hackmd.io/_uploads/SJvxOctrR.png) ```go= 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"` Opc struct { OpcValue string `json:"opcValue"` EncryptionAlgorithm string `json:"encryptionAlgorithm"` EncryptionKey string `json:"encryptionKey"` } `json:"opc"` } type AuthSubs struct { AuthenticationMethod string `json:"authenticationMethod"` PermanentKey *PermanentKey `json:"permanentKey"` SequenceNumber string `json:"sequenceNumber"` AuthenticationManagementField string `json:"authenticationManagementField"` Milenage *Milenage `json:"milenage"` UeId string `json:"ueId"` } func main() { var authSubs AuthSubs // 假設從數據庫中獲取數據並反序列化為 authSubs 結構體 // ... // 直接訪問 PermanentKeyValue 字段 fmt.Println("PermanentKeyValue:", authSubs.PermanentKey.PermanentKeyValue) } ``` ![image](https://hackmd.io/_uploads/r1lf_5KHC.png) ## int32() ![image](https://hackmd.io/_uploads/SJPo9_aHR.png) ![image](https://hackmd.io/_uploads/SJG_9u6SA.png) ```go= package main import ( "fmt" ) type ProblemDetails struct { Status int32 Detail string // 假設有其他欄位 } func main() { // 假設 rsp 是一個 HTTP 回應物件,StatusCode 是其狀態碼 rsp := struct { StatusCode int }{ StatusCode: 404, // 假設狀態碼為 404 } var problemDetails ProblemDetails // 將 rsp.StatusCode 轉換為 int32,並賦值給 problemDetails.Status problemDetails.Status = int32(rsp.StatusCode) fmt.Printf("ProblemDetails 的狀態碼為: %d\n", problemDetails.Status) } ``` ![image](https://hackmd.io/_uploads/SJiKqOaHR.png) ## %x ![image](https://hackmd.io/_uploads/B1Me4RfIC.png) ```go= package main import ( "fmt" ) func main() { num := 255 fmt.Printf("%x\n", num) // 輸出:ff } ``` ![image](https://hackmd.io/_uploads/rJtbECf80.png) ```go= package main import ( "fmt" ) func main() { str := "hello" fmt.Printf("%x\n", str) // 輸出:68656c6c6f } ``` ![image](https://hackmd.io/_uploads/HJxVERzL0.png) ```go= package main import ( "fmt" ) func main() { data := []byte{0, 1, 2, 10, 15, 255} fmt.Printf("%x\n", data) // 輸出:0001020a0fff } ``` ![image](https://hackmd.io/_uploads/HJVS4Az8C.png) ```go= package main import ( "fmt" ) func main() { data := []byte{0, 1, 2, 10, 15, 255} fmt.Printf("% x\n", data) // 輸出:00 01 02 0a 0f ff } ``` ![image](https://hackmd.io/_uploads/BJxPNRzUR.png) ```go= package main import ( "fmt" ) func main() { num := 255 str := "hello" data := []byte{0, 1, 2, 10, 15, 255} fmt.Printf("Number in hex: %x\n", num) // Number in hex: ff fmt.Printf("String in hex: %x\n", str) // String in hex: 68656c6c6f fmt.Printf("Bytes in hex: %x\n", data) // Bytes in hex: 0001020a0fff fmt.Printf("Bytes with space: % x\n", data) // Bytes with space: 00 01 02 0a 0f ff } ``` ## Function declaration ![image](https://hackmd.io/_uploads/HyOsBAzL0.png) ![image](https://hackmd.io/_uploads/r1OhSRGLR.png) ## Structure printing ![image](https://hackmd.io/_uploads/rJOVoELuR.png) ```go= package main import ( "fmt" ) type Person struct { Name string Age int Email string } func main() { p := Person{ Name: "Alice", Age: 30, Email: "alice@example.com", } // 使用%v打印 struct fmt.Printf("%v\n", p) // {Alice 30 alice@example.com} // 使用%+v打印 struct,包括字段名 fmt.Printf("%+v\n", p) // {Name:Alice Age:30 Email:alice@example.com} // 使用%#v打印 struct,顯示詳細信息 fmt.Printf("%#v\n", p) // main.Person{Name:"Alice", Age:30, Email:"alice@example.com"} // 使用%T打印 struct 的類型 fmt.Printf("%T\n", p) // main.Person // 打印 struct 的字段值,分別用不同格式 fmt.Printf("Name: %s, Age: %d (bin: %b, hex: %x), Email: %s\n", p.Name, p.Age, p.Age, p.Age, p.Email) } ``` ```shell= {Alice 30 alice@example.com} {Name:Alice Age:30 Email:alice@example.com} main.Person{Name:"Alice", Age:30, Email:"alice@example.com"} main.Person Name: Alice, Age: 30 (bin: 11110, hex: 1e), Email: alice@example.com ``` ## MongoDB * About the explanation of Go language executing sequence -> [Link](https://hackmd.io/DETj57LjQFimKBIOaD6csQ?view#maingo--initgo) ### Connection * At first I thought these logs represent that 5GC has connected to MongoDB. ![image](https://hackmd.io/_uploads/SyT-xWl8C.png) * But no, because the modification in AMF still can not connect to DB, but original UDR can, and the logs are just print after UPF start from run.sh, I dont know what it is for. ![image](https://hackmd.io/_uploads/r1dilbeLA.png) * The thing turned to my mind is that [Terry manually set](https://hackmd.io/AMzUH2F7TzOxIo5o3H3CyA#Connection-building) the connection in the init.go in AMF, which means it is necessary to do this before get the data. * So I go to search the name of **func SetMongoDB** to see where it is used, it must be in UDR but we can only find **func getDataFromDB** use **mongoapi.RestfulAPIGetOne**. ![image](https://hackmd.io/_uploads/HkkSMZg8C.png) * You can see it is called here to build the connection when start UDR in init.go. ![image](https://hackmd.io/_uploads/r1xsG-x8A.png) ![image](https://hackmd.io/_uploads/HyNKz-eIC.png) ## go.work ![image](https://hackmd.io/_uploads/Hyn9lJY5R.png) ![image](https://hackmd.io/_uploads/H1BsgyKqR.png) ![image](https://hackmd.io/_uploads/H1RsektcA.png) ![image](https://hackmd.io/_uploads/Bku3gytqA.png) ![image](https://hackmd.io/_uploads/Byf6g1Y9A.png) ![image](https://hackmd.io/_uploads/SkWAgyYqC.png) ![image](https://hackmd.io/_uploads/BkKCgkF5R.png) ![image](https://hackmd.io/_uploads/ByGy-JF90.png) ![image](https://hackmd.io/_uploads/H1YybJtc0.png) ![image](https://hackmd.io/_uploads/B1zlWJKcR.png) :::success ![image](https://hackmd.io/_uploads/HkAg-kYcA.png) ![image](https://hackmd.io/_uploads/HJPbWktq0.png) ![image](https://hackmd.io/_uploads/SJNzbJF9C.png) ![image](https://hackmd.io/_uploads/r11mZkY5R.png) ![image](https://hackmd.io/_uploads/HkEHZJFq0.png) ::: :::success ![image](https://hackmd.io/_uploads/rJELWJKc0.png) ![image](https://hackmd.io/_uploads/rkRYbJYqR.png) ![image](https://hackmd.io/_uploads/r1g8cbytc0.png) ![image](https://hackmd.io/_uploads/S1yoWkKcR.png) ::: ## PCF context problem ### go.mod replace ![image](https://hackmd.io/_uploads/HJWKJKloR.png) ![image](https://hackmd.io/_uploads/HJY91FxjA.png) ![image](https://hackmd.io/_uploads/rkwjyYeiC.png) ![image](https://hackmd.io/_uploads/Bkrn1Kxs0.png) ![image](https://hackmd.io/_uploads/SyU6yKgj0.png) ![image](https://hackmd.io/_uploads/S1TRJKes0.png) ![image](https://hackmd.io/_uploads/H1q1gFljA.png) ![image](https://hackmd.io/_uploads/SyNExYli0.png) ![image](https://hackmd.io/_uploads/HJKNeYxjA.png) --- ![image](https://hackmd.io/_uploads/Hy6BeYes0.png) ![image](https://hackmd.io/_uploads/SJ8wlteoR.png) ![image](https://hackmd.io/_uploads/By0_eFls0.png) ![image](https://hackmd.io/_uploads/B1EqgFgsC.png) ![image](https://hackmd.io/_uploads/Bk6cxtljA.png) ![image](https://hackmd.io/_uploads/S1HnxYeiC.png) ![image](https://hackmd.io/_uploads/B1FnlKliA.png) ![image](https://hackmd.io/_uploads/HJATxKxiA.png) --- ### internal in golang ![image](https://hackmd.io/_uploads/ByoRxKeoC.png) ![image](https://hackmd.io/_uploads/SJKk-KejC.png) ![image](https://hackmd.io/_uploads/BkGlbYxj0.png) ### Combine two go.mod ![image](https://hackmd.io/_uploads/rJPFWtxsR.png) ![image](https://hackmd.io/_uploads/rybq-FgoA.png) ![image](https://hackmd.io/_uploads/BJu9ZYeiR.png) ![image](https://hackmd.io/_uploads/ByRcWYgoR.png) ![image](https://hackmd.io/_uploads/HyQ2ZKeiA.png) ### go.work ![image](https://hackmd.io/_uploads/SkogfFxjC.png) ![image](https://hackmd.io/_uploads/H1fZGFxi0.png) ![image](https://hackmd.io/_uploads/S1oZMFxoA.png) ![image](https://hackmd.io/_uploads/r1XGfKgjC.png) ![image](https://hackmd.io/_uploads/HJ0GGYgoR.png) ![image](https://hackmd.io/_uploads/SyDmMteoR.png) ![image](https://hackmd.io/_uploads/SkZ4fYes0.png) ![image](https://hackmd.io/_uploads/HkCVMKgsA.png) ![image](https://hackmd.io/_uploads/SyKrfteoR.png) ![image](https://hackmd.io/_uploads/H1a8ftesC.png) ![image](https://hackmd.io/_uploads/SJLOGKgsC.png) ### internal bigger than go.work ![image](https://hackmd.io/_uploads/BkSRGFxoR.png) ![image](https://hackmd.io/_uploads/BJv1XFxoR.png) ![image](https://hackmd.io/_uploads/HyxxQKliA.png) ![image](https://hackmd.io/_uploads/BJDlQYesA.png) ![image](https://hackmd.io/_uploads/HyZZ7FejR.png) ![image](https://hackmd.io/_uploads/r1t-7YesR.png) ![image](https://hackmd.io/_uploads/ByrzQFeo0.png) ![image](https://hackmd.io/_uploads/S1JX7FliR.png) ![image](https://hackmd.io/_uploads/H1vX7YgoR.png) --- ### Move outside internal ![image](https://hackmd.io/_uploads/Bkow7Ylj0.png) ![image](https://hackmd.io/_uploads/SJW_QFxsA.png) ![image](https://hackmd.io/_uploads/S1s_mFgsA.png) #### can not still use shared go.mod ![image](https://hackmd.io/_uploads/rk6jXYgsC.png) ![image](https://hackmd.io/_uploads/rk73QYgsC.png) ![image](https://hackmd.io/_uploads/Hkc3mKljR.png) ![image](https://hackmd.io/_uploads/S1MpQYxj0.png) ![image](https://hackmd.io/_uploads/HJ3CQFxjR.png) ![image](https://hackmd.io/_uploads/ryY1EKljC.png) ![image](https://hackmd.io/_uploads/S1NxEFxjR.png) ![image](https://hackmd.io/_uploads/r1cgEYgoR.png) #### The reason ![image](https://hackmd.io/_uploads/rkjGVtliA.png) ![image](https://hackmd.io/_uploads/SJyVNFljR.png) ![image](https://hackmd.io/_uploads/rkj4EFxjR.png) #### The result ![image](https://hackmd.io/_uploads/ByE78KgsC.png) ![image](https://hackmd.io/_uploads/SJgVIteoA.png) ![image](https://hackmd.io/_uploads/SkmBLYljA.png) ![image](https://hackmd.io/_uploads/SkOIUYgiC.png) :::danger * Then is the same problem so ask more detailed (The screenshots see the improvement note). ![image](https://hackmd.io/_uploads/BJX0UFxiC.png) ![image](https://hackmd.io/_uploads/S10AUYxjA.png) ![image](https://hackmd.io/_uploads/rkcpOFxjC.png) ![image](https://hackmd.io/_uploads/S1OkKtljC.png) ![image](https://hackmd.io/_uploads/SyNeYtgj0.png) ![image](https://hackmd.io/_uploads/ByCeFKxsC.png) ![image](https://hackmd.io/_uploads/HJ0-YYgi0.png) ![image](https://hackmd.io/_uploads/SkiGFFgs0.png) ![image](https://hackmd.io/_uploads/ryt7KFxjA.png) ![image](https://hackmd.io/_uploads/rkxEttgi0.png) * Then is to ask the method how to solve, so no take screenshots here, just see the results in improvement note. ::: --- ### The method of two go routine ![image](https://hackmd.io/_uploads/B1Lmm9xoA.png) ![image](https://hackmd.io/_uploads/H1ZNm9giR.png) ![image](https://hackmd.io/_uploads/B1nIQcls0.png) ![image](https://hackmd.io/_uploads/SJLdmqeiA.png) ![image](https://hackmd.io/_uploads/Bk-KQ9gjR.png) ![image](https://hackmd.io/_uploads/H1uKQ9loR.png) ![image](https://hackmd.io/_uploads/ryRKXqxsC.png) ![image](https://hackmd.io/_uploads/BkQkE9gsA.png) ![image](https://hackmd.io/_uploads/S10JEqxoC.png) ![image](https://hackmd.io/_uploads/SySeE5esA.png) ![image](https://hackmd.io/_uploads/BysxNqxj0.png) ![image](https://hackmd.io/_uploads/HkX-E5eo0.png) ![image](https://hackmd.io/_uploads/BJsWN5ls0.png) # OpenAPI ## Use SMF--PCF as example * Consumer means the http client, and producer means the http server in the communication between NFs * Sbi is the service based interface related folder, storing the api files in each NF. ![image](https://hackmd.io/_uploads/ryUv49vc6.png) ### Architecture ![Openapi(SMF--PCF)](https://hackmd.io/_uploads/SyLhsM69a.png) ### Tracing * How can sm_policy.go use the parameter smContext to call the function on github? 1. First, this parameter is passed from pdu_session.go ![image](https://hackmd.io/_uploads/B1EWTMp9T.png) V ![image](https://hackmd.io/_uploads/SkJITMpqp.png) 2. And the parameter is declared by the function in smf_context, ![image](https://hackmd.io/_uploads/SJk3Tf69a.png) which is imported from the the other package "context" ![image](https://hackmd.io/_uploads/HywBCzp9p.png) 3. Let's saerch the calling function directly, we can see two context folder, but the one in smf is correct. ![image](https://hackmd.io/_uploads/r1d1kXaca.png) ![image](https://hackmd.io/_uploads/H1CZ-Qp9p.png) 4. Final, the func NewSMContext create a new smContext using a defined structure SMContxt, we can find the structure up there, ![image](https://hackmd.io/_uploads/B1YqWQT5a.png) then when we look back to the parameter "SMPolicyClient" the sm_policy.go use, ![image](https://hackmd.io/_uploads/B1dbz7pqa.png) we can find it is in the structure. ![image](https://hackmd.io/_uploads/BkX8GQp9p.png) 5. So the result is that "SMPolicyClient" in the structure is declared as a APIClient reference of the package "Npcf_SMPolicyControl". ![image](https://hackmd.io/_uploads/By86MXa9p.png) 6. If we see into github, we can find this function which including "DefaultApi", ![image](https://hackmd.io/_uploads/rkkgVXac6.png) ![image](https://hackmd.io/_uploads/HkCl47acp.png) then the DefaultApi can call "SmPloiciesPost" (dont know how it can, maybe it can use DefaultApi to call the function in the same folder?) which call the routers.go in PCF, ![image](https://hackmd.io/_uploads/rkY1Smaqp.png) ![image](https://hackmd.io/_uploads/Hk0AEXp5T.png) # Core modules/Network functions ## AMF ### Security mode * Procedure defined in 3GPP **TS 33.501** version 15.2.0 Release 15 * Header type defined in 3GPP **TS 24.501** version 15.3.0 Release 15 * The conclusion made by chatGPT : ![image](https://hackmd.io/_uploads/rJ3GbkOUR.png) ![image](https://hackmd.io/_uploads/BkBXZJdLR.png) ## AUSF [Authentication Server Services / ETSI TS 129 509 V16.7.0 (2021-04)](https://www.etsi.org/deliver/etsi_ts/129500_129599/129509/16.07.00_60/ts_129509v160700p.pdf) [Security architecture and procedures for 5G System / ETSI TS 133 501 V15.2.0 (2018-10)](https://www.etsi.org/deliver/etsi_ts/133500_133599/133501/15.02.00_60/ts_133501v150200p.pdf) ### Functionalities - Authenticate the UE for the requester NF, - Provide keying material to the requester NF, - Protect the Steering Information List for the requester NF. - Protect the UE Parameter Update Data for the requester NF. ### Service-based architecture ![image](https://hackmd.io/_uploads/SJTel7Q3a.png) * SEAF(SEcurity Anchor Function)(安全錨功能) : The function that serves in the serving network as the anchor for security in 5G, provides the authentication functionality via the AMF in the serving network. The SEAF shall support primary authentication using SUCI. * ![image](https://hackmd.io/_uploads/SyulUtN26.png) * SEAF function is collocated(搭配) with the AMF. * PLMN * Public Land Mobile Network is hosted by government or the permitted operator, provides mobile communication technology to public. * PLMN=mcc+mnc. * Home PLMN(歸屬PLMN) : the PLMN in IMSI of the user SIM card is identical with HPLMN. * Visited PLMN(訪問PLMN) : The PLMN of SIM is not completely same as VPLMN. :::warning #### Serving network & Home network * In 5G, serving network include the component which provide the service, like AMF, and home network includes the components which store the register info. ![image](https://hackmd.io/_uploads/rJZvRd9kA.png) ![image](https://hackmd.io/_uploads/S1zx1tcJC.png) * For example, if you are roaming, you will be changed to different serving network, but go to the same home network for getting your subscriber data. ![image](https://hackmd.io/_uploads/rkNqkKqJA.png) ::: ### Provided services - Nausf_UEAuthentication - Nausf_SoRProtection - Nausf_UPUProtection ![image](https://hackmd.io/_uploads/B12mjYN3T.png) #### Nausf_UEAuthentication ![image](https://hackmd.io/_uploads/rkdL-Tthp.png) [Ref](https://blog.csdn.net/zhonglinzhang/article/details/109749426) #### 5G-AKA ![image](https://hackmd.io/_uploads/ByGHcg526.png) * UE's identifier like IMSI, SUCI(Subscription Concealed Identifier) will not be transmitted in plaintext in 5G, it's different from 4G. * SNN(Service Network Name) can be used for authenticaion of SEAF in AUSF * SIDF(Subscriber Identity De-concealing Function) can decrypt the SUCI into SUPI if AUSF provides to UDM, and the SUPI can be used for choosing the authenticating method. * AV : Authentication Vector [Ref](https://nccnews.com.tw/202010/ch4.html) :::warning #### 5G-AKA v.s. EAP-AKA' * In free5GC, AUSF will search the authentication method in UDM ([Ref](https://blog.csdn.net/zhonglinzhang/article/details/108636015)), UDM will check the contract content to see which method it use. * Normally, the authentication method is decided by the operator, which is pre-assigned to the 5GC. - 5G-AKA (Authentication and Key Agreement) - Specifically Designed for 5G. - Based on SIM and AuC (Authentication Center). - 5G-AKA is integrated into the 5G standards and is widely used as the primary authentication mechanism in 5G networks. - It provides robust security features to protect user identities and ensure the confidentiality and integrity of communications. - 5G AKA involves multiple stages, including a series of challenges and responses, to ensure secure communication between the user and the network. - EAP-AKA' (Extensible Authentication Protocol - AKA Prime): - EAP-AKA' is an extension of the Extensible Authentication Protocol (EAP) that encapsulates the AKA (Authentication and Key Agreement) protocol - EAP is a more general authentication protocol used not only in 5G networks but also widely in other wireless networks such as Wi-Fi. - In the 5GC, EAP is typically used in conjunction with EAP-AKA' (a version encapsulating 5G AKA) to provide greater flexibility and interoperability. - EAP-AKA' allows for compatibility with existing authentication infrastructures and protocols, making it suitable for integration into heterogeneous networks. - EAP requires more infrastructure support and is typically more complex than 5G AKA, but it offers greater flexibility and scalability. - It offers greater flexibility in authentication methods and protocols, allowing operators to leverage various authentication mechanisms beyond 5G-AKA. - EAP-AKA' enhances interoperability between different network types and facilitates seamless roaming across networks. ::: :::warning #### Auth parameters generating * ![image](https://hackmd.io/_uploads/rk83uFc1C.png) ![image](https://hackmd.io/_uploads/rk7TOYcyC.png) ![image](https://hackmd.io/_uploads/rJJRdY51R.png) ![image](https://hackmd.io/_uploads/r1q0_Fqk0.png) [Ref](https://1drv.ms/p/s!AndI1JV-h1Q5jeI3KMCmpMuBShSd2A?e=GlVTJ8) ::: #### Nausf_SoRProtection & Nausf_UPUProtection ![image](https://hackmd.io/_uploads/rkthKzuC6.png) * Left is in the free5gc, right is in the AUSF services spec. * Until now, it dosent affect the main UEauthentication part, so I didnt do any detailed investigation on it. ## NSSF ### Definition * [Ref](https://free5gc.org/blog/20230726/network_slice/) * NS allows for the creation of multiple logical, isolated, and independent virtual networks that can coexist within a shared physical infrastructure. * Each network slice provides dedicated and customized network resources to meet the specific requirements of different services * The main elements of a network slice include: * Virtualized Network Functions (VNFs) * Isolation and Resource Allocation * Orchestration and Management ![image](https://hackmd.io/_uploads/Skel0vCwR.png) * MANO is a NFV based architecture. ![image](https://hackmd.io/_uploads/BJI5Av0vA.png) * [MANO 5GC](https://www.google.com/search?q=mano+5gc&rlz=1C1GCEA_enTW807TW810&oq=mano+&gs_lcrp=EgZjaHJvbWUqBggBEEUYOzIGCAAQRRg5MgYIARBFGDvSAQgyOTUzajBqN6gCALACAA&sourceid=chrome&ie=UTF-8) ### Network Slicing Identifier * [Ref](https://free5gc.org/blog/20230726/network_slice/) * NSSAI (Network Slice Selection Assistance Information) is a set of S-NSSAI, can be classified into 5. ![image](https://hackmd.io/_uploads/SyuT7ORP0.png) * The deifnition in 5GC. ![image](https://hackmd.io/_uploads/Bko0-F0PA.png) * The NFs join the NS function, and the NSSAI they have. (From On the Rollout of Network Slicing in Carrier Networks: A Technology Radar) ![image](https://hackmd.io/_uploads/ByzV74zdR.png) - From the release of 3GPP R15, the NS is mentioned, and it needs the support from not only NG-RAN but also CN, so 5G system use S-NSSAI(Single-NSSAI) and NSSAI to do slice management. - S-NSSAI is combined from two fields. - SST (Slice/Service Type) : Different SST implies different applied scene, like 1 for eMBB, 2 for uRLLC, 3 for mIoT, 4 for V2V and 5 for HMTC(High-Performance Machine-Type Communications). - SD (Slice Differentiator) : Subdivide functions in the same scenario, including mobile network or fixed wireless access network, charging, slice priority, tenancy. ### Info in SPEC * [Ref](https://1drv.ms/b/s!AndI1JV-h1Q5kYZeG2Sr2dIbSdACRA?e=JjRZBp) ![image](https://hackmd.io/_uploads/BJJwX6fDR.png) * [Ref](https://1drv.ms/b/s!AndI1JV-h1Q5kYsPCXpzC6mA3SW7Dw?e=ji9tew) ![image](https://hackmd.io/_uploads/r1AgNMTP0.png) ![image](https://hackmd.io/_uploads/Bkfm4GaDC.png) * [Ref](https://1drv.ms/b/s!AndI1JV-h1Q5kYsQilw4YRQwvQS-yA?e=copnMw) ![image](https://hackmd.io/_uploads/rJHtBGTPA.png) #### Nnssf_NSSelection * [Ref](https://blog.csdn.net/zhonglinzhang/article/details/108166165) * Comsumer in other PLMN (AMF, NSSF) search (**GET**) the info about network slice in roaming or not in roaming. * Comsumer find NSSF based on local configuration, or find NSSF in different PLMN based on its own FQDN. * NSSF use it to provide **Allowed NSSAI** and **Configured NSSAI** of served PLMN to AMF. * Applied Scenes ![image](https://hackmd.io/_uploads/BJqEcw0vC.png) * ![image](https://hackmd.io/_uploads/H1KKcDRwA.png) ![image](https://hackmd.io/_uploads/SyVt5vCv0.png) ![image](https://hackmd.io/_uploads/ryXacv0w0.png) #### Nnssf_NSSAIAvailability * Comsumer (AMF) update the **Supported S-NSSAI** on every [Tracking Area](https://xdxdd.blogspot.com/2012/08/lte-tracking-area-tai-tau-tac.html) of NSSF * Subscribe or unsubscribe the change notification of * NSSAI Availability info on each TA. * Resricted S-NSSAI in every PLMN in the TA of UE served PLMN. ![image](https://hackmd.io/_uploads/SJMjnvCP0.png) ### Info from Terry * There are some slicing method, one is using multiple UPF, one is using one UPF only. * The test ref from Terry : [Link](https://1drv.ms/f/s!AndI1JV-h1Q5kYwVSWzGBETacpiY3A?e=uJghQO) * Ther conclusion for this test is that we can not see the influence of slice seperate by using only one UPF, because different UE can ping each other in different slice. * UPF is like a router, can assign different sub-domain and set the router to make them able to communication with each other. #### UCLC ![image](https://hackmd.io/_uploads/BytIvDBuR.png) * Ref : [Link](https://free5gc.org/guide/Smf/design/#description), [Link](https://free5gc.org/guide/SMF-Config/#userplane-information), [Link](https://github.com/s5uishida/free5gc_ueransim_ulcl_sample_config) ## PCF ### Study from our content * The code tracing I done before : [Link](https://hackmd.io/IUW_ewqoTSy3djiAgi7Btg?view#4-Remove-PCF) * The AMF policy part is useless because it is all about commenting out the error, but didnt solve the panic error. * The SMF part may be useful, because there are some record of the process of SMF policy creating. * Note from Rifqi : [Link](https://hackmd.io/@arifadh2003/rkdMlftUA#Understanding-PCF) * Thers are some info from SPEC, and his own code tracing, but it is not finished. ### Study on SPEC/Background * AMF policy : [Link](https://blog.csdn.net/zhonglinzhang/article/details/107881343), [R16](https://www.etsi.org/deliver/etsi_ts/129500_129599/129507/16.06.00_60/ts_129507v160600p.pdf) * SMF policy : [Link](https://blog.csdn.net/zhonglinzhang/article/details/107882933), [R16](https://www.etsi.org/deliver/etsi_ts/129500_129599/129512/16.08.00_60/ts_129512v160800p.pdf) * PCF : [Series](https://blog.csdn.net/yifei800327/category_12415665.html), [R15](https://www.etsi.org/deliver/etsi_ts/129500_129599/129513/15.03.00_60/ts_129513v150300p.pdf), [R16](https://www.etsi.org/deliver/etsi_ts/129500_129599/129513/16.06.00_60/ts_129513v160600p.pdf), [Framework R15](https://www.etsi.org/deliver/etsi_ts/123500_123599/123503/15.02.00_60/ts_123503v150200p.pdf), [Brief intro 1](https://blog.51cto.com/u_14758357/4725777), [Brief intro 2](https://blog.csdn.net/zhonglinzhang/article/details/107877819) ### BSF * The function related to PCF. * [Ref](https://techjunction.co/tech-question/binding-support-function-bsf-in-5g/) ## UDM/UDR ### UDM * Authentication part has been introduced in AUSF. * Here just introduces some SDM functions which will be part of the modification in UDM/UDR. #### UeCmRegistration ![image](https://hackmd.io/_uploads/Syq33UP90.png) #### SdmSubscriptions ![image](https://hackmd.io/_uploads/rJxT-_Dq0.png) ### UDR * You can see it as an **API** between NFs and MongoDB. * UDM (AUSF) will call it to manage UE auth info. * PCF will call it to manage policy data. * AMF will do SDM by calling UDM to call it. * SMF will get context from UDM calling it. * ... ## SMF ### IP allocation [Ref](https://www.sharetechnote.com/html/5G/5G_IP_Allocation.html) [Ref](https://www.tech-invite.com/3m23/toc/tinv-3gpp-23-501_ze.html) * I think the IP allocation in CN has many probability, from SMF, UPF, or the DHCP server outside, but in usual E2E test with UERANSIM is from SMF. ![unnamed](https://hackmd.io/_uploads/ryxSVIDjtC.png) # Protocols NGAP # Lightweight core ## Before & After * [Ref](https://1drv.ms/w/s!AndI1JV-h1Q5sGh3kUKtfyAhbWGH?e=vCy3RB) ### Module ![image](https://hackmd.io/_uploads/HykO3_ot0.png) ![image](https://hackmd.io/_uploads/SyfS3dsK0.png) ![image](https://hackmd.io/_uploads/rJCQn_sKC.png) ### Call flow * Original ![image](https://hackmd.io/_uploads/BysVTUoYR.png) ![image](https://hackmd.io/_uploads/BJwIp8sY0.png) ![image](https://hackmd.io/_uploads/HJkdT8jFC.png) ![image](https://hackmd.io/_uploads/Sk52TUjYA.png) * Lightweight ![image](https://hackmd.io/_uploads/ryK068jKR.png) ![image](https://hackmd.io/_uploads/rJzlCIot0.png) ![image](https://hackmd.io/_uploads/BJgQ0IoYC.png) ![image](https://hackmd.io/_uploads/HkK4C8otR.png) ## Fix the parameter ## Authen. context ## Remove AUSF ### What happen? ### How to repair? ## Remove NSSF ## Remove PCF

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully