# Project 2: UE-RM Monitoring Service ## 課程目標 在上一次的 Project 中,我們藉由模擬 FAE 的日常對 5GS 的運作有了一定的掌握。在這次的作業中,你需要扮演 RD 的日常,根據 3GPP 定義的 Technical Specification 來實作對應的服務。 - [ ] 學習閱讀 3GPP TS 文件 - [ ] 學習 SBI 服務開發 - [ ] 了解網路元件如何互動 - [ ] 利用設計模式設計出簡潔有效的程式碼 ## 作業說明 使用以下命令取得此次作業的提交樣板: ```sh $ git clone https://github.com/NYCU-CNDI/amf-rms.git ``` 在這次的作業中,你需要按照 [Requirements](#Requirements) 提供的規格書為 AMF 實作一個新的 SBI service。並且在適當的時機通知該 SBI service 的 service consumer。 - 請將修改完的程式碼包含 `.git` 紀錄一起打包,提交至 E3 作業區 - 會有隱藏測資,請確保所有行為符合規格書規範,以及考慮多用戶請求併發的情況 ## Requirements 請根據規格書實作 UE-RM Monitoring Service: - [UE-RM Monitoring Service 規格書](https://hackmd.io/@cndi2025/SyhOHt0sxx) :::info 補充: 如果對 SBI 仍不熟悉,請參考 https://github.com/free5gc/free5GLabs/blob/master/lab4/README.md 。 ::: ```mermaid flowchart TD A[AF 發送 POST /subscriptions] --> B[AMF Namf-RMMonitoring<br/>接收訂閱請求] B --> C[AMF Subscription Table<br/>儲存 Subscription<br/>UE ID、Callback URI、Event] C --> D[回傳 201 Created<br/>+ SubscriptionID 給 AF] %% UE 狀態改變事件 E[UE 狀態改變<br/>AMF UE Context / FSM] --> F[AMF Event Handler Hook] F --> G[查找對應 UE 的<br/>Subscription Table] G -->|符合事件| H[組成通知 JSON Payload] H --> I[HTTP POST 通知至 AF Callback URI] I --> J[AF 收到通知<br/>處理 UE 狀態改變] %% 流程關聯 subgraph AMF B C F G H I end ``` ### 1. AMF 實作 RM Subscription service RM Subscription service 是 AMF 提供的功能,Service AMF 所實作的 RM Subscription service 需要提供 GET/POST/PUT/DELETION 四種方式供 Service Consumer 使用。 #### GET Operation 回傳目前已經存在的 UE-RM subscription。 #### POST Operation 新增一個 UE-RM subscription,相關 schema 如下: ```go type Subscription struct { SubId string `json:"subId"` // 由 AMF 產生的 subs id UeId string `json:"ueId"` // UE SUPI NotifyUri string `json:"notifyUri"` // 由 service consumer 填入,當訂閱的 UE 的 FSM 發生轉變,會透過 URI 通知 service consumer。 } ``` 根據規格書的定義,呼叫 POST API 時需帶入 subscriptionID,請修改 API handler 的行為,使 AMF 能夠: - 為 Service consumer 請求的 Subscription 分配 SubscriptionID #### PUT Operation 新增或覆蓋一個 UE-RM subscription,相關 schema 同 **POST Operation**。 #### DELETE Operation 刪除已存在的 UE-RM subscription。 #### Error Handling 對於不合法的 Case,一率回應 Status code 404。 #### 實作說明 SBI server 會在初始化時根據不同的 API group 逐一初始化對應的 http handler,請根據此次作業的規格書提供的內容修改 `getRMSRoutes()` 以滿足作業需求: ```go func (s *Server) getRMSRoutes() []Route { return []Route{ { Name: "root", Method: http.MethodGet, Pattern: "/", APIFunc: func(c *gin.Context) { c.String(http.StatusOK, "Hello World!") }, }, // add more Route based on provided spec } } ``` ### 2. 實作 FSM plugin #### 實作說明 請實作一個 RSM service,滿足以下介面: ```go type RMS interface { HandleEvent(*State, EventType, ArgsType, Transition) } ``` 並且在適當的地方呼叫 `AttachRSM()` 將你實作的 RMS 加載至 `GmmFSM`: ```go func AttachRSM(rms fsm.RMS) { GmmFSM.WithRSM(rms) } ``` RMS 請實作在 `amf/internal/rms/rms.go`。 此外,當 AMF 的 RMS service 需要通知 service consumer 時,請使用 `http.DefaultClient` 發出 POST 請求,並且使用下列 schema 作為 request body: ```go type UeRMNotif struct { SubId string `json:"subId"` UeId string `json:"ueId"` PrevState string `json:"from"` CurrState string `json:"to"` } ```