Epic-ID: ODUHIGH-463][Task-ID: ODUHIGH-504]Dummy Handover Request/Response and UE...
[o-du/l2.git] / src / cu_stub / cu_xnap_msg_hdl.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17 *******************************************************************************/
18
19 /* This file contains F1AP message handler functions */
20 #include "common_def.h"
21 #include "cu_stub_sctp.h"
22 #include "cu_stub_egtp.h"
23 #include "OCTET_STRING.h"
24 #include "F1AP-PDU.h"
25 #include "cu_f1ap_msg_hdl.h"
26 #include "cu_stub.h"
27
28 /*******************************************************************
29  *
30  * @brief Build And send dummy Xn Setup request
31  *
32  * @details
33  *
34  *    Function : BuildAndSendXnSetupReq
35  *
36  *    Functionality:
37  *       Build And send dummy Xn Setup request
38  *
39  * @params[in]
40  * @return void
41  *
42  ******************************************************************/
43 void BuildAndSendXnSetupReq()
44 {
45    uint8_t assocIdx = 0;
46    Buffer *mBuf = NULLP;
47    CuSctpAssocCb *assocCb = NULLP;
48
49    for(assocIdx = 0; assocIdx < sctpCb.numAssoc; assocIdx++)
50    {
51       assocCb = &sctpCb.assocCb[assocIdx];
52       if(assocCb->connUp && assocCb->intf == XN_INTERFACE && assocCb->destId == 0)
53       {
54          if(ODU_GET_MSG_BUF(1, 1, &mBuf) == ROK)
55          {
56             CMCHKPK(oduUnpackUInt8,(Data *)CU_ID, mBuf);
57             CMCHKPK(oduUnpackUInt8,XN_SETUP_REQ, mBuf);
58             ODU_PRINT_MSG(mBuf, 0,0);
59             if(sendOnSctpAssoc(assocCb, mBuf) != ROK)
60             {
61                DU_LOG("\nERROR  -->  CU_STUB: Failed to send XN setup request to peer CU");
62             }
63          }
64          break;
65       }
66    }
67 }
68
69 /*******************************************************************
70  *
71  * @brief Process received Xn Setup request
72  *
73  * @details
74  *
75  *    Function : XNAPProcXnSetupReq
76  *
77  *    Functionality:
78  *       Fetch peer CU ID and store in assocCb
79  *
80  * @params[in] Pointer to destination Id
81  *             Pointer to message buffer
82  * @return void
83  *
84  ******************************************************************/
85 void XNAPProcXnSetupReq(uint32_t *destId, Buffer *mBuf)
86 {
87    uint8_t cuId;
88
89    DU_LOG("\nINFO  -->  CU STUB : Received XN Setup Request");
90    CMCHKUNPK(oduPackUInt8, &(cuId), mBuf)
91    *destId = cuId;
92
93    BuildAndSendXnSetupRsp(*destId);
94 }
95
96 /*******************************************************************
97  *
98  * @brief Build And send dummy Xn Setup response
99  *
100  * @details
101  *
102  *    Function : BuildAndSendXnSetupRsp
103  *
104  *    Functionality:
105  *       Build And send dummy Xn Setup response
106  *
107  * @params[in]
108  * @return void
109  *
110  ******************************************************************/
111 void BuildAndSendXnSetupRsp(uint32_t destId)
112 {
113    Buffer *mBuf = NULLP;
114
115    if(ODU_GET_MSG_BUF(1, 1, &mBuf) == ROK)
116    {
117       CMCHKPK(oduUnpackUInt8, CU_ID, mBuf);
118       CMCHKPK(oduUnpackUInt8, XN_SETUP_RSP, mBuf);
119       if(sctpSend(XN_INTERFACE, destId, mBuf))
120       {
121          DU_LOG("\nERROR  -->  CU_STUB: Failed to send XN setup response to peer CU");
122       }   
123    }   
124 }
125
126 /*******************************************************************
127  *
128  * @brief Process received Xn Setup response
129  *
130  * @details
131  *
132  *    Function : XNAPProcXnSetupRsp
133  *
134  *    Functionality:
135  *       Fetch peer CU ID and store in assocCb
136  *
137  * @params[in] Pointer to destination Id
138  *             Pointer to message buffer
139  * @return void
140  *
141  ******************************************************************/
142 void XNAPProcXnSetupRsp(uint32_t *destId, Buffer *mBuf)
143 {
144    uint8_t cuId;
145
146    DU_LOG("\nINFO  -->  CU STUB : Received XN Setup Response");
147    CMCHKUNPK(oduPackUInt8, &(cuId), mBuf)
148    *destId = cuId;
149 }
150
151 /*******************************************************************
152  *
153  * @brief Build And send dummy Handover request to Peer CU
154  *
155  * @details
156  *
157  *    Function : BuildAndSendHOReq
158  *
159  *    Functionality:
160  *       Build And send dummy Handover request to Peer CU
161  *
162  * @params[in] Pointer to UE Cb
163  *             Event type
164  *             Message to be sent
165  *             Message Length
166  * @return void
167  *
168  ******************************************************************/
169 void BuildAndSendHOReq(CuUeCb *ueCb, char *xnMsg, MsgLen xnMsgLen)
170 {
171    Buffer *mBuf = NULLP;
172
173    if(ODU_GET_MSG_BUF(1, 1, &mBuf) == ROK)
174    {
175       if(ODU_ADD_POST_MSG_MULT((Data *)xnMsg, xnMsgLen, mBuf) == ROK)
176       {  
177          CMCHKPK(oduUnpackUInt8, ueCb->hoInfo.cuUeF1apIdSrc, mBuf);
178          CMCHKPK(oduUnpackUInt32, ueCb->hoInfo.tgtCellId, mBuf);
179          CMCHKPK(oduUnpackUInt8, HO_REQ, mBuf);
180          if(sctpSend(XN_INTERFACE, ueCb->hoInfo.tgtNodeId, mBuf) != ROK)
181          {
182             DU_LOG("\nERROR  -->  CU_STUB: Failed to send handover request to peer CU");
183             ueCb->state = UE_ACTIVE;
184             memset(&ueCb->hoInfo, 0, sizeof(HandoverInfo));
185          }
186       }     
187    }
188 }
189
190 /*******************************************************************
191  *
192  * @brief Process received Handover Request
193  *
194  * @details
195  *
196  *    Function : XNAPProcHandoverReq
197  *
198  *    Functionality:
199  *       1. Unpack Cell Id from msg and find DU to which it belongs
200  *       2. Create UE context for UE in handover and store in DU DB
201  *       3. Decode the F1AP UE context modification msg received in 
202  *          XNAP message buffer and extract UE configurations
203  *       4. Send UE context setup request to DU with these configs 
204  *
205  * @params[in] Pointer to destination Id
206  *             Pointer to message buffer
207  * @return void
208  *
209  ******************************************************************/
210 void XNAPProcHandoverReq(uint32_t destId, Buffer *mBuf)
211 {
212    uint8_t duIdx, cellIdx;
213    uint8_t cuUeF1apIdSrc;
214    uint32_t cellId;
215    DuDb *duDb;
216    CuCellCb *cellCb;
217
218    DU_LOG("\nINFO  -->  CU STUB : Received Handover Request");
219    
220    /* Find DU Db and Cell Cb from cellId */
221    CMCHKUNPK(oduPackUInt32, &(cellId), mBuf);
222    for(duIdx = 0; duIdx < cuCb.numDu; duIdx++)
223    {
224       duDb = &cuCb.duInfo[duIdx];
225       SEARCH_CELL_DB(cellIdx, duDb, cellId, cellCb)
226       if(cellCb)
227          break;
228    }
229    if(!cellCb)
230    {
231       DU_LOG("\nERROR  -->  CU_STUB: Failed to find Cell Id [%d] received in HO Request", cellId);
232       return;
233    }
234
235    /* Fetch CU UE F1AP ID of UE in handover assigned by source CU */
236    CMCHKUNPK(oduPackUInt8, &(cuUeF1apIdSrc), mBuf);
237
238    /* Filling temporary UE context which will be used to create actual UE context at
239     * CU later */
240    CU_ALLOC(duDb->tempUeCtxtInHo, sizeof(CuUeCb));
241    if(!duDb->tempUeCtxtInHo)
242    {
243       DU_LOG("\nERROR  -->  XNAP : Failed to allocate memory to temporary UE context for UE in handover");
244       return;
245    }
246    memset(duDb->tempUeCtxtInHo, 0, sizeof(CuUeCb));
247    duDb->tempUeCtxtInHo->cellCb = cellCb;
248    duDb->tempUeCtxtInHo->gnbCuUeF1apId = ++cuCb.gnbCuUeF1apIdGenerator;
249    duDb->tempUeCtxtInHo->state = UE_HANDOVER_IN_PROGRESS;
250    duDb->tempUeCtxtInHo->hoInfo.HOType = Xn_Based_Inter_CU_HO;
251    duDb->tempUeCtxtInHo->hoInfo.srcNodeId = destId;
252    duDb->tempUeCtxtInHo->hoInfo.tgtNodeId = cuCb.cuCfgParams.cuId;
253    duDb->tempUeCtxtInHo->hoInfo.tgtCellId = cellId;
254    duDb->tempUeCtxtInHo->hoInfo.cuUeF1apIdSrc = cuUeF1apIdSrc;
255    duDb->tempUeCtxtInHo->hoInfo.cuUeF1apIdTgt = duDb->tempUeCtxtInHo->gnbCuUeF1apId;
256
257    /* Decode UE context modification response msg received in Xn Msg */
258    char *recvBuf;
259    MsgLen recvBufLen, copyLen;
260    F1AP_PDU_t *f1apMsg = NULLP;
261    F1AP_PDU_t f1apasnmsg ;
262
263    f1apMsg = &f1apasnmsg;
264    memset(f1apMsg, 0, sizeof(F1AP_PDU_t));
265    if(F1APDecodeMsg(f1apMsg, mBuf, &recvBuf, &recvBufLen) != ROK)
266    {
267       DU_LOG("\nERROR  -->  F1AP : F1AP PDU decode failed");
268       return;
269    }
270    CU_FREE(recvBuf, recvBufLen);
271    procUeContextModificationResponse(duDb->duId, f1apMsg, NULL, 0);
272 }
273
274 /*******************************************************************
275  *
276  * @brief Build And send dummy Handover request ack to Peer CU
277  *
278  * @details
279  *
280  *    Function : BuildAndSendHOReqAck
281  *
282  *    Functionality:
283  *       Build And send dummy Handover request ack to Peer CU
284  *
285  * @params[in] Pointer to UE Cb
286  *             Message to be sent
287  *             Message Length
288  * @return void
289  *
290  ******************************************************************/
291 void BuildAndSendHOReqAck(CuUeCb *ueCb, char *xnMsg, MsgLen xnMsgLen)
292 {
293    Buffer *mBuf = NULLP;
294
295    if(ODU_GET_MSG_BUF(1, 1, &mBuf) == ROK)
296    {   
297       if(ODU_ADD_POST_MSG_MULT((Data *)xnMsg, xnMsgLen, mBuf) == ROK)
298       {   
299          CMCHKPK(oduUnpackUInt8, ueCb->gnbCuUeF1apId, mBuf);
300          CMCHKPK(oduUnpackUInt8, ueCb->hoInfo.cuUeF1apIdSrc, mBuf);
301          CMCHKPK(oduUnpackUInt8, HO_REQ_ACK, mBuf);
302          if(sctpSend(XN_INTERFACE, ueCb->hoInfo.srcNodeId, mBuf) != ROK)
303          {
304             DU_LOG("\nERROR  -->  CU_STUB: Failed to send handover request ack to peer CU");
305          }
306       }
307    }
308 }
309
310 /*******************************************************************
311  *
312  * @brief Process received Handover Request Ack
313  *
314  * @details
315  *
316  *    Function : XNAPProcHandoverReqAck
317  *
318  *    Functionality:
319  *       1. Unpack CU UE F1AP ID (by SCU) and search for UE CB and
320  *          the corresponding DU DB (SDU)
321  *       2. Unpack CU UE F1AP ID (by TCU) and fill in UEcb->hoInfo
322  *       3. Decode the F1AP UE context setup response msg received in 
323  *          XNAP message buffer and extract UE configurations
324  *       4. Create RRC reconfig msg with these configurations
325  *       5. Send RRC Reconfig msg and Transmission Action = DO NOT TRANSMIT
326  *          in UE context modification request to S DU
327  *
328  * @params[in] Pointer to destination Id
329  *             Pointer to message buffer
330  * @return void
331  *
332  ******************************************************************/
333 void XNAPProcHandoverReqAck(uint32_t destId, Buffer *mBuf)
334 {
335    DU_LOG("\nINFO  -->  CU STUB : Received Handover Request Acknowledgement");
336 }
337
338 /*******************************************************************
339  *
340  * @brief Handle incoming messages at Xn interface
341  *
342  * @details
343  *
344  *    Function : XNAPMsgHdlr
345  *
346  *    Functionality:
347  *       Fetch event type from message buffer and call appropriate
348  *       handler
349  *
350  * @params[in] Pointer to destination Id
351  *             Pointer to message buffer
352  * @return void
353  *
354  ******************************************************************/
355 void XNAPMsgHdlr(uint32_t *destId, Buffer *mBuf)
356 {
357    XnEventType event;
358
359    CMCHKUNPK(oduPackUInt8, &event, mBuf);
360
361    switch(event)
362    {
363       case XN_SETUP_REQ:
364          {
365              XNAPProcXnSetupReq(destId, mBuf);
366              break;
367          }
368
369     case XN_SETUP_RSP:
370          {
371              XNAPProcXnSetupRsp(destId, mBuf);
372              break;
373          }
374
375       case HO_REQ:
376          {
377             XNAPProcHandoverReq(*destId, mBuf);
378             break;
379          }
380       
381       case HO_REQ_ACK:
382          {
383             XNAPProcHandoverReqAck(*destId, mBuf);
384             break;
385          }
386       default:
387          DU_LOG("\nERROR  --> CU_STUB : Invalid event [%d] received at XN interface", event);
388          break;
389    }
390 }
391
392 /**********************************************************************
393   End of file
394  **********************************************************************/