EPIC ID: RICAPP-200 Upgrading rc version to 1.0.3 and fixing E2SM RC control structure
[ric-app/rc.git] / control / rcControl.go
1 package control\r
2 \r
3 import (\r
4         "errors"\r
5         "fmt"\r
6         "log"\r
7         "os"\r
8         "strconv"\r
9         "sync"\r
10         "time"\r
11         //"encoding/hex"\r
12         "gerrit.o-ran-sc.org/r/ric-app/rc/protocol/grpc/ricmsgcommrpc/rc"\r
13         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"\r
14 )\r
15 \r
16 var (\r
17         gControlData               *Control\r
18         gChan_RicControlReq_handle = make(chan *rc.RicControlGrpcReq, 2000) //Make it configurable\r
19 )\r
20 \r
21 func NewControl() Control {\r
22 \r
23         file := "/opt/rc.log"\r
24         logFile, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766)\r
25         if err != nil {\r
26                 panic(err)\r
27         }\r
28         log.SetOutput(logFile)\r
29         log.SetPrefix("[qSkipTool]")\r
30         log.SetFlags(log.LstdFlags | log.Lshortfile | log.LUTC)\r
31         logLevel := xapp.Config.GetInt("controls.logLevel")\r
32         xapp.Logger.SetLevel(logLevel)\r
33 \r
34         xapp.Logger.Debug("GRPC Server Port = %v ", xapp.Config.GetString("controls.ricHOControlgRpcServerPort"))\r
35         xapp.Logger.Debug("Log Level = %d ", xapp.Config.GetInt("controls.logLevel"))\r
36 \r
37         go StartgRPCRCControlCommServerRoutine()\r
38         xapp.Logger.Debug("StartgRPCRCControlCommServerRoutine done")\r
39 \r
40         //To Handle RIC Control Message\r
41         go StartHandleControlReqRoutine()\r
42 \r
43         return Control{5,\r
44                 make(chan *xapp.RMRParams, 1000), //Make it configurable\r
45                 make(map[int]bool),\r
46                 &sync.Mutex{},\r
47                 0}\r
48 }\r
49 \r
50 func ReadyCB(i interface{}) {\r
51         gControlData = i.(*Control)\r
52         go controlLoop()\r
53 }\r
54 \r
55 func (aControlData *Control) Run() {\r
56         xapp.SetReadyCB(ReadyCB, aControlData)\r
57         xapp.Run(aControlData)\r
58 }\r
59 \r
60 func (aControlData *Control) Consume(rp *xapp.RMRParams) (err error) {\r
61         gControlData.rcChan <- rp\r
62         return\r
63 }\r
64 \r
65 func (aControlData *Control) rmrSend(params *xapp.RMRParams) (err error) {\r
66         if !xapp.Rmr.Send(params, false) {\r
67                 err = errors.New("rmr.Send() failed")\r
68                 xapp.Logger.Info("Failed to rmrSend to %v", err)\r
69                 log.Printf("Failed to rmrSend to %v", err)\r
70         }\r
71         return\r
72 }\r
73 \r
74 func (aControlData *Control) rmrReplyToSender(params *xapp.RMRParams) (err error) {\r
75         if !xapp.Rmr.Send(params, true) {\r
76                 err = errors.New("rmr.Send() failed")\r
77                 xapp.Logger.Error("Failed to rmrReplyToSender to %v", err)\r
78                 log.Printf("Failed to rmrReplyToSender to %v", err)\r
79         }\r
80         return\r
81 }\r
82 \r
83 func controlLoop() {\r
84         for {\r
85                 msg := <-gControlData.rcChan\r
86                 xapp.Logger.Debug("Received message type: %d", msg.Mtype)\r
87                 log.Printf("Received message type: %d", msg.Mtype)\r
88                 switch msg.Mtype {\r
89                 case 12041:\r
90                         go HandleControlResponse(msg)\r
91                 case 12042:\r
92                         go HandleControlFailure(msg)\r
93                 default:\r
94                         err := errors.New("Message Type " + strconv.Itoa(msg.Mtype) + " is discarded")\r
95                         xapp.Logger.Error("Unknown message type: %v", err)\r
96                         log.Printf("Unknown message type: %v", err)\r
97                 }\r
98         }\r
99 }\r
100 \r
101 func StartHandleControlReqRoutine() {\r
102 \r
103         log.Printf("Starting Go Routine for Handling GRPC RIC Control msg ")\r
104         xapp.Logger.Info("Starting Go Routine for Handling GRPC RIC Control msg ")\r
105         for {\r
106                 HandlegRPCRICControlMsgReq(<-gChan_RicControlReq_handle)\r
107         }\r
108         xapp.Logger.Debug("StartHandleControlReqRoutine Done")\r
109 }\r
110 \r
111 func HandlegRPCRICControlMsgReq(aPtrRicControlGrpcReq *rc.RicControlGrpcReq) {\r
112 \r
113         xapp.Logger.Debug("HandlegRPCRICControlMsgReq :%v", *aPtrRicControlGrpcReq)\r
114         lRicHoControlMsg := RicHoControlMsg{}\r
115         lRicHoControlMsg.RicControlGrpcReqPtr = aPtrRicControlGrpcReq\r
116 \r
117         lUEID := lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID\r
118         xapp.Logger.Debug("HandlegRPCRICControlMsgReq UEID = %v ", lUEID)\r
119         //Mandatory parameters validation\r
120         if lRicHoControlMsg.RicControlGrpcReqPtr.E2NodeID == "" ||\r
121                 lRicHoControlMsg.RicControlGrpcReqPtr.RICControlMessageData.TargetCellID == "" ||\r
122                 lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID.GnbUEID.AmfUENGAPID < 0 ||\r
123                 lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID.GnbUEID.Guami.PLMNIdentity == "" ||\r
124                 lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID.GnbUEID.Guami.AMFRegionID == "" ||\r
125                 lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID.GnbUEID.Guami.AMFSetID == "" ||\r
126                 lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID.GnbUEID.Guami.AMFPointer == "" ||\r
127                 len(lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID.GnbUEID.GNBCUUEF1APID) == 0 ||\r
128                 len(lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID.GnbUEID.GNBCUCPUEE1APID) == 0 ||\r
129                 lRicHoControlMsg.RicControlGrpcReqPtr.PlmnID == "" ||\r
130                 lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.ControlActionId < 0 ||\r
131                 lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.ControlStyle < 0 ||\r
132                 lRicHoControlMsg.RicControlGrpcReqPtr.RICControlMessageData.RICControlCellTypeVal < 0 ||\r
133                 lRicHoControlMsg.RicControlGrpcReqPtr.RICE2APHeaderData.RICRequestorID < 0 ||\r
134                 lRicHoControlMsg.RicControlGrpcReqPtr.RICE2APHeaderData.RanFuncId < 0 {\r
135                 xapp.Logger.Error("Mandaroty parameters missing, dont send control request ")\r
136                 return\r
137         }\r
138 \r
139         lRicHoControlMsg.GetSequenceNumber()\r
140 \r
141         go lRicHoControlMsg.SendRicControlRequest(lRicHoControlMsg.GetSequenceNumber())\r
142 \r
143         return\r
144 }\r
145 \r
146 func (aRicHoControlMsg *RicHoControlMsg) GetSequenceNumber() int {\r
147 \r
148         //Incrementing the RIC Requestor Instance Id to make the request unique and traceable.\r
149         gControlData.eventRicControlReqExpiredMu.Lock()\r
150         gControlData.ricRequestInstanceID = gControlData.ricRequestInstanceID + 1\r
151         gControlData.eventRicControlReqExpiredMu.Unlock()\r
152 \r
153         return gControlData.ricRequestInstanceID\r
154 }\r
155 \r
156 func (aRicHoControlMsg *RicHoControlMsg) setEventRicControlCreateExpiredTimer(aSeqNum int) {\r
157 \r
158         gControlData.eventRicControlReqExpiredMu.Lock()\r
159         gControlData.eventRicControlReqExpiredMap[aSeqNum] = false\r
160         gControlData.eventRicControlReqExpiredMu.Unlock()\r
161         controlAckTimer := xapp.Config.GetInt("controls.controlAckTimer")\r
162         xapp.Logger.Debug("configured controlAckTimer = %d and controlAckTimer = %d ", xapp.Config.GetInt("controls.controlAckTimer"),controlAckTimer)\r
163 \r
164         timer := time.NewTimer(time.Duration(controlAckTimer) * time.Second)\r
165         go func(t *time.Timer) {\r
166                 defer t.Stop()\r
167                 xapp.Logger.Debug("RIC_CONTROL_REQ[%s]: Waiting for RIC_CONTROL_RESP...", aSeqNum)\r
168                 log.Printf("RIC_CONTROL_REQ[%s]: Waiting for RIC_CONTROL_RESP...", aSeqNum)\r
169                 for {\r
170                         select {\r
171                         case <-t.C:\r
172                                 gControlData.eventRicControlReqExpiredMu.Lock()\r
173                                 isResponsed := gControlData.eventRicControlReqExpiredMap[aSeqNum]\r
174                                 delete(gControlData.eventRicControlReqExpiredMap, aSeqNum)\r
175                                 gControlData.eventRicControlReqExpiredMu.Unlock()\r
176                                 if !isResponsed {\r
177                                         xapp.Logger.Debug("RIC_CONTROL_REQ[%s]: RIC Event Create Timer experied!", aSeqNum)\r
178                                         log.Printf("RIC_CONTROL_REQ[%s]: RIC Event Create Timer experied!", aSeqNum)\r
179                                         //Send ErrorIndication message on Timeout\r
180                                         return\r
181                                 }\r
182                         default:\r
183                                 gControlData.eventRicControlReqExpiredMu.Lock()\r
184                                 flag := gControlData.eventRicControlReqExpiredMap[aSeqNum]\r
185                                 if flag {\r
186                                         delete(gControlData.eventRicControlReqExpiredMap, aSeqNum)\r
187                                         gControlData.eventRicControlReqExpiredMu.Unlock()\r
188                                         xapp.Logger.Debug("RIC_CONTROL_REQ[%s]: RIC Event Create Timer canceled!", aSeqNum)\r
189                                         log.Printf("RIC_CONTROL_REQ[%s]: RIC Event Create Timer canceled!", aSeqNum)\r
190                                         return\r
191                                 } else {\r
192                                         gControlData.eventRicControlReqExpiredMu.Unlock()\r
193                                 }\r
194                         }\r
195                         time.Sleep(100 * time.Millisecond)\r
196                 }\r
197         }(timer)\r
198 }\r
199 func (aRicHoControlMsg *RicHoControlMsg) SendRicControlRequest(aRequestSN int) (err error) {\r
200         var e2ap *E2ap\r
201         var e2sm *E2sm\r
202 \r
203         xapp.Logger.Info("SendRicControlRequest Enter for RanName = %s", aRicHoControlMsg.RicControlGrpcReqPtr.RanName)\r
204 \r
205         if aRicHoControlMsg.RicControlGrpcReqPtr == nil {\r
206                 return err\r
207         }\r
208 \r
209         var lRicControlStyleType int64 = aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.ControlStyle\r
210         var lRicControlActionID int64 = aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.ControlActionId\r
211         lUEID := aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID\r
212 \r
213         var ueId_data UEid\r
214 \r
215         xapp.Logger.Debug("UEID:%v, ueId_data strct :%v", aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID,\r
216                 ueId_data)\r
217         ueId_data.amf_UE_NGAP_Id = lUEID.GnbUEID.AmfUENGAPID\r
218         ueId_data.pLMNIdentitybuf = lUEID.GnbUEID.Guami.PLMNIdentity\r
219         ueId_data.aMFRegionIDbuf = lUEID.GnbUEID.Guami.AMFRegionID\r
220         ueId_data.aMFSetIDbuf = lUEID.GnbUEID.Guami.AMFSetID\r
221         ueId_data.aMFPointerbuf = lUEID.GnbUEID.Guami.AMFPointer\r
222         ueId_data.F1AP_id = lUEID.GnbUEID.GNBCUUEF1APID\r
223         ueId_data.E1AP_id = lUEID.GnbUEID.GNBCUCPUEE1APID\r
224 \r
225         var lRicControlHeader []byte = make([]byte, 1024) //Check the Size\r
226         lRicControlHeaderEncoded, err := e2sm.SetRicControlHeader(lRicControlHeader, &ueId_data, lRicControlStyleType, lRicControlActionID)\r
227         if err != nil {\r
228                 xapp.Logger.Error("SetRicControlHeader Failed: %v, UEID:%v", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)\r
229                 log.Printf("SetRicControlHeader Failed: %v, UEID:%v", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)\r
230                 return err\r
231         } else {\r
232                 xapp.Logger.Info("SetRicControlHeader is success: %x", lRicControlHeaderEncoded)\r
233                 fmt.Fprintf(os.Stderr, "Encoded RIC Control Header PDU:\n")\r
234                 for i := 0; i < len(lRicControlHeaderEncoded); i++ {\r
235                         fmt.Fprintf(os.Stderr, " %02x", lRicControlHeaderEncoded[i])\r
236                 }\r
237                 fmt.Fprintf(os.Stderr, "\n")\r
238         }\r
239         var lTargetPrimaryCell int64 = RIC_CONTROL_TARGET_PRIMARY_CELL\r
240         var lTargetCell int64 = RIC_CONTROL_TARGET_CELL\r
241         var lNrCGIOrECGI int64 = RIC_CONTROL_CGI_TYPE\r
242 \r
243         lNrOrEUtraCellType := aRicHoControlMsg.RicControlGrpcReqPtr.RICControlMessageData.RICControlCellTypeVal\r
244         lTargetCellVal := aRicHoControlMsg.RicControlGrpcReqPtr.RICControlMessageData.TargetCellID\r
245         //lTargetCellValBuf, _:= hex.DecodeString(lTargetCellVal)\r
246         lTargetCellValBuf := []byte(lTargetCellVal)\r
247         //lNRPlmnId := []byte(aRicHoControlMsg.RicControlGrpcReqPtr.RICControlMessageData.TargetCellID.PlmnID)\r
248         //lNRCellId := aRicHoControlMsg.RicControlGrpcReqPtr.RICControlMessageData.TargetCellID.NRCellID\r
249 \r
250 \r
251         var lRicControlMessage []byte = make([]byte, 1024)\r
252         lRicControlMessageEncoded, err := e2sm.SetRicControlMessage(lRicControlMessage, lTargetPrimaryCell, lTargetCell, lNrCGIOrECGI, int64(lNrOrEUtraCellType), ueId_data.pLMNIdentitybuf, lTargetCellValBuf)\r
253         if err != nil {\r
254                 xapp.Logger.Error("SetRicControlMessage Failed: %v, UEID:%v", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)\r
255                 log.Printf("SetRicControlMessage Failed: %v, UEID:%v", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)\r
256                 return err\r
257         } else {\r
258                 xapp.Logger.Debug("SetRicControlMessage is success: %x", lRicControlMessageEncoded)\r
259                 fmt.Fprintf(os.Stderr, "Encoded RIC Control Message PDU:\n")\r
260                 for i := 0; i < len(lRicControlMessageEncoded); i++ {\r
261                         fmt.Fprintf(os.Stderr, " %02x", lRicControlMessageEncoded[i])\r
262                 }\r
263                 fmt.Fprintf(os.Stderr, "\n")\r
264         }\r
265 \r
266         lParams := &xapp.RMRParams{}\r
267         lParams.Mtype = 12040 //RIC_CONTROL_REQ\r
268         lParams.SubId = -1\r
269 \r
270         var lRequestorId uint16 = uint16(aRicHoControlMsg.RicControlGrpcReqPtr.RICE2APHeaderData.RICRequestorID)\r
271         var lFuncId uint16 = uint16(aRicHoControlMsg.RicControlGrpcReqPtr.RICE2APHeaderData.RanFuncId)\r
272 \r
273         lParams.Payload = make([]byte, 2048)\r
274         lParams.Payload, err = e2ap.SetRicControlRequestPayload(lParams.Payload, lRequestorId, uint16(aRequestSN), lFuncId,\r
275                 lRicControlHeaderEncoded, lRicControlMessageEncoded)\r
276         if err != nil {\r
277                 xapp.Logger.Error("SetRicControlRequestPayload Failed: %v, UEID:%v", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)\r
278                 log.Printf("SetRicControlRequestPayload Failed: %v, UEID:%v", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)\r
279                 return err\r
280         } else {\r
281 \r
282                 xapp.Logger.Debug("Encoding RicControlRequestPayload is success. UEID: %v, Payload: %x", lUEID, lParams.Payload)\r
283                 fmt.Fprintf(os.Stderr, "Encoded RIC Control Req PDU:\n")\r
284                 for i := 0; i < len(lParams.Payload); i++ {\r
285                         fmt.Fprintf(os.Stderr, " %02x", lParams.Payload[i])\r
286                 }\r
287                 fmt.Fprintf(os.Stderr, "\n")\r
288         }\r
289         lParams.PayloadLen = len(lParams.Payload)\r
290         valEnbId := aRicHoControlMsg.RicControlGrpcReqPtr.E2NodeID\r
291         valRanName := aRicHoControlMsg.RicControlGrpcReqPtr.RanName\r
292         valPlmnId := aRicHoControlMsg.RicControlGrpcReqPtr.PlmnID\r
293         lParams.Meid = &xapp.RMRMeid{PlmnID: valPlmnId, EnbID: valEnbId, RanName: valRanName}\r
294 \r
295         xapp.Logger.Debug("The RIC Control RMR message to be sent is with MsgType:%d  SubId=%d, lParams.Meid: %v, UEID: %v", lParams.Mtype, lParams.SubId, lParams.Meid, lUEID)\r
296 \r
297         xapp.Logger.Debug("Sending RIC Control message to RanName: %s, UEID: %v  ", aRicHoControlMsg.RicControlGrpcReqPtr.RanName, lUEID)\r
298         \r
299         xapp.Logger.Info("lParams %v ",lParams)\r
300         err = gControlData.rmrSend(lParams)\r
301         if err != nil {\r
302                 xapp.Logger.Error("Failed to send RIC_CONTROL_REQ: %v", err)\r
303                 log.Printf("Failed to send RIC_CONTROL_REQ: %v", err)\r
304                 xapp.Logger.Info("Failed to send RIC_CONTROL_REQ: %v", err)\r
305                 return err\r
306         }\r
307 \r
308         xapp.Logger.Info("Sending RIC Control message to RanName: %s, UEID: %v  Success", aRicHoControlMsg.RicControlGrpcReqPtr.RanName, lUEID)\r
309         //Start Timer Operation.\r
310         aRicHoControlMsg.setEventRicControlCreateExpiredTimer(aRequestSN) //TODO check if this is required as we are not expecting Control ACK\r
311 \r
312         return nil\r
313 }\r
314 \r
315 func HandleControlResponse(params *xapp.RMRParams) (err error) {\r
316 \r
317         var e2ap *E2ap\r
318         var e2sm *E2sm\r
319         xapp.Logger.Debug("The SubId in RIC_CONTROL_RESP is %d", params.SubId)\r
320         log.Printf("The SubId in RIC_CONTROL_RESP is %d", params.SubId)\r
321 \r
322 \r
323 \r
324         //Decode the RIC Control Ack message\r
325         controlAck, err := e2ap.GetControlAckMsg(params.Payload)\r
326         if err != nil {\r
327                 xapp.Logger.Error("Failed to decode RIC Control Ack: %v", err)\r
328                 log.Println("Failed to decode RIC Control Ack: %v", err)\r
329                 return\r
330         }\r
331         log.Println("E2ap RIC RIC Control Ack message decoded \n")\r
332         xapp.Logger.Info("E2ap RIC RIC Control Ack message decoded \n")\r
333         gControlData.eventRicControlReqExpiredMu.Lock()\r
334         _,ok := gControlData.eventRicControlReqExpiredMap[int(controlAck.InstanceId)]\r
335         if !ok {\r
336                 gControlData.eventRicControlReqExpiredMu.Unlock()\r
337                 xapp.Logger.Debug("RIC_CONTROL_REQ has been deleted!")\r
338                 log.Printf("RIC_CONTROL_REQ has been deleted!")\r
339                 return nil\r
340         } else {\r
341                 gControlData.eventRicControlReqExpiredMap[int(controlAck.InstanceId)] = true\r
342                 gControlData.eventRicControlReqExpiredMu.Unlock()\r
343         }\r
344 \r
345         controlOutcome, err := e2sm.GetControlOutcome(controlAck.ControlOutcome)\r
346         if err != nil {\r
347                 xapp.Logger.Error("Failed to decode RIC Control Outcome: %v", err)\r
348                 log.Println("Failed to decode RIC Control Outcome: %v", err)\r
349                 return\r
350         }\r
351         log.Println("E2SM-RC RIC Control Outcome  decoded \n",controlOutcome)\r
352         xapp.Logger.Info("E2SM-RC RIC Control Outcome  decoded \n",controlOutcome)\r
353 \r
354 \r
355 \r
356         return nil\r
357 }\r
358 \r
359 func HandleControlFailure(params *xapp.RMRParams) (err error) {\r
360 \r
361         var e2ap *E2ap\r
362 \r
363         xapp.Logger.Debug("The SubId in RIC_CONTROL_FAILURE is %d", params.SubId)\r
364         log.Printf("The SubId in RIC_CONTROL_FAILURE is %d", params.SubId)\r
365 \r
366         controlAck, err := e2ap.GetControlFailureMsg(params.Payload)\r
367         if err != nil {\r
368                 xapp.Logger.Debug("Failed to decode RIC Control message: %v", err)\r
369                 log.Println("Failed to decode RIC Control Ack: %v", err)\r
370                 return\r
371         }\r
372         log.Println("E2ap RIC  Control Ack message decoded \n")\r
373         xapp.Logger.Debug("E2ap RIC Control Ack message decoded \n")\r
374 \r
375         gControlData.eventRicControlReqExpiredMu.Lock()\r
376         _, ok := gControlData.eventRicControlReqExpiredMap[int(controlAck.InstanceId)]\r
377         if !ok {\r
378                 gControlData.eventRicControlReqExpiredMu.Unlock()\r
379                 xapp.Logger.Debug("RIC_CONTROL_REQ has been deleted!")\r
380                 log.Printf("RIC_CONTROL_REQ has been deleted!")\r
381                 return nil\r
382         } else {\r
383                 gControlData.eventRicControlReqExpiredMap[int(controlAck.InstanceId)] = true\r
384                 gControlData.eventRicControlReqExpiredMu.Unlock()\r
385         }\r
386         return nil\r
387 }\r