Merge "MIB periodicity fix Jira ID : ODUHIGH-183"
[o-du/l2.git] / src / du_app / du_ue_mgr.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  /* This file contains UE management handling functionality for DU APP */
19 #include "du_ue_mgr.h"
20
21 #ifdef EGTP_TEST
22 U32 sduId = 0;
23 #endif
24
25 DuMacDlCcchInd packMacDlCcchIndOpts[] =
26 {
27    packMacDlCcchInd,   /* Loose coupling */
28    MacHdlDlCcchInd,    /* TIght coupling */
29    packMacDlCcchInd    /* Light weight-loose coupling */
30 };
31
32 /******************************************************************
33  *
34  * @brief Send UE configuration to RLC
35  *
36  * @details
37  *
38  *    Function : duSendUeCreateReqToRlc
39  *
40  *    Functionality: Send UeCreateReqToRlc
41  *
42  * @return ROK     - success
43  *         RFAILED - failure
44  *
45  * ****************************************************************/
46 S16 duSendUeCreateReqToRlc()
47 {
48    U8  idx;
49    Pst pst;
50    CkwCfgInfo *ueCfg;
51    
52    DU_SET_ZERO(&ueCfg, sizeof(ueCfg));
53    DU_SET_ZERO(&pst, sizeof(Pst));
54
55    DU_ALLOC(ueCfg, sizeof(CkwCfgInfo));
56
57 #ifdef EGTP_TEST
58    ueCfg->ueId = UE_ID;
59 #endif
60    ueCfg->cellId = NR_CELL_ID;
61    ueCfg->numEnt = 1;
62    
63    for(idx = 0; idx < ueCfg->numEnt; idx++)
64    {
65 #ifdef EGTP_TEST
66       ueCfg->entCfg[idx].rbId           = RB_ID;
67       ueCfg->entCfg[idx].rbType         = CM_LTE_DRB;
68       ueCfg->entCfg[idx].lCh[0].lChId   = LC_ID;
69       ueCfg->entCfg[idx].lCh[0].type    = CM_LTE_LCH_DTCH;
70 #endif
71       ueCfg->entCfg[idx].entMode        = CM_LTE_MODE_UM;
72       ueCfg->entCfg[idx].dir            = CKW_CFG_DIR_BOTH;
73       switch(ueCfg->entCfg[idx].entMode)
74       {
75          case CM_LTE_MODE_TM:
76          {
77             break;
78          }
79
80          case CM_LTE_MODE_UM:
81          {
82             ueCfg->entCfg[idx].m.umInfo.dl.snLen = 1;      /* For 12 bit SN */
83             ueCfg->entCfg[idx].m.umInfo.ul.snLen = 1;      /* For 12 bit SN */
84             ueCfg->entCfg[idx].m.umInfo.ul.reOrdTmr = 10;  /* in msec */
85             break;
86          }
87
88          case CM_LTE_MODE_AM:
89          {
90             break;
91          }
92          
93          default:
94             break;
95       } /* End of switch(entMode) */
96    } /* End of entity configuration for loop */
97
98    /* Fill Pst */
99    pst.selector  = DU_SELECTOR_LWLC;
100    pst.srcEnt    = ENTDUAPP;
101    pst.dstEnt    = ENTKW;
102    pst.dstInst   = RLC_UL_INST;
103    pst.dstProcId = DU_PROC;
104    pst.srcProcId = DU_PROC;
105    pst.region    = duCb.init.region;
106
107    /* Sending to RLC */
108    packUeCreateReq(&pst, ueCfg);
109
110    RETVALUE(ROK); 
111 } /* End of duSendUeCreateReqToRlc */
112
113 /*******************************************************************
114  *
115  * @brief Handles EGTP data from CU 
116  *
117  * @details
118  *
119  *    Function : duHdlEgtpData
120  *
121  *    Functionality: 
122  *      Processes EGTP header and sends data to RLC
123  *
124  * @params[in]  Pointer to EGTP Message 
125  * @return ROK     - success
126  *         RFAILED - failure
127  *
128  * ****************************************************************/
129 S16 duHdlEgtpDlData(EgtpMsg  *egtpMsg)
130 {
131    /* TODO : Extract RbId/UeID/CellID/SduId from database
132       using tunnel id in egtp header */
133    
134    DU_LOG("\nDU_APP : Processing DL data");
135    
136    Pst pst;
137    KwuDatReqInfo datReqInfo;
138
139 #ifdef EGTP_TEST
140    datReqInfo.rlcId.rbId = RB_ID;
141    datReqInfo.rlcId.rbType = CM_LTE_DRB;
142    datReqInfo.rlcId.ueId = UE_ID;
143    datReqInfo.rlcId.cellId = NR_CELL_ID;
144    
145    datReqInfo.sduId = ++sduId;
146    datReqInfo.lcType = CM_LTE_LCH_DTCH;
147 #endif
148    /* Filling pst and Sending to RLC DL */
149    pst.selector  = DU_SELECTOR_LWLC;
150    pst.srcEnt    = ENTDUAPP;
151    pst.dstEnt    = ENTKW;
152    pst.dstInst   = RLC_DL_INST;
153    pst.dstProcId = DU_PROC;
154    pst.srcProcId = DU_PROC;
155    pst.region    = duCb.init.region;
156
157    cmPkKwuDatReq(&pst, &datReqInfo, egtpMsg->msg);
158    return ROK;
159 }
160
161 /*******************************************************************
162  *
163  * @brief Handles UL data and send to CU
164  *
165  * @details
166  *
167  *    Function : duHdlRlcUlData
168  *
169  *    Functionality: 
170  *     Processes UL Data from RLC and sends to CU
171  * 
172  *  @params[in]  Pointer to EGTP Message 
173  *  @return ROK     - success
174  *          RFAILED - failure
175  * 
176  *****************************************************************/
177
178 PUBLIC S16 duHdlRlcUlData(Pst *pst, KwuDatIndInfo* datInd, Buffer *mBuf)
179 {
180    DU_LOG("\nDU_APP : Received UL Data at DU_APP");
181  
182    /* Send UL data to CU via EGTP */
183    duSendEgtpDatInd(mBuf);
184    SPutMsg(mBuf);
185
186    return ROK;
187 }
188
189 /******************************************************************
190 *
191 * @brief Builds and Sends DL CCCH Ind to MAC
192 *
193 * @details
194 *
195 *    Function : duBuildAndSendDlCcchInd 
196 *
197 *    Functionality: Builds and sends DL CCCH Ind Msg to MAC
198 *
199 * @params[in] dlCcchMsg - uint8_t*
200 * @return ROK     - success
201 *         RFAILED - failure
202 *
203 * ****************************************************************/
204 uint8_t duBuildAndSendDlCcchInd(uint16_t cellId, uint16_t crnti, \
205   DlCcchMsgType msgType, uint8_t *dlCcchMsg, uint16_t dlCcchMsgSize)
206 {
207         uint8_t ret                  = ROK;
208         uint16_t idx2;
209    DlCcchIndInfo *dlCcchIndInfo = NULLP;
210    Pst pst;
211    
212         memset(&pst, 0, sizeof(Pst));
213    DU_LOG("\nDU APP : Building and Sending DL CCCH Ind to MAC");
214
215         DU_ALLOC_SHRABL_BUF(dlCcchIndInfo, sizeof(DlCcchIndInfo));
216
217    if(!dlCcchIndInfo)
218    {
219                 DU_LOG("\nDU APP : Memory alloc failed while building DL CCCH Ind");
220                 return RFAILED;
221         }
222
223         dlCcchIndInfo->cellId = cellId;
224         dlCcchIndInfo->crnti = crnti;
225         dlCcchIndInfo->msgType = msgType;
226         dlCcchIndInfo->dlCcchMsgLen = dlCcchMsgSize;
227
228         DU_ALLOC_SHRABL_BUF(dlCcchIndInfo->dlCcchMsg, dlCcchIndInfo->dlCcchMsgLen);
229         if(!dlCcchIndInfo->dlCcchMsg)
230    {
231                 DU_LOG("\nDU APP : Memory alloc failed while building DL CCCH Ind");
232                 DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, dlCcchIndInfo, sizeof(DlCcchIndInfo));
233                 return RFAILED;
234         }
235         for(idx2 = 0; idx2 < dlCcchIndInfo->dlCcchMsgLen; idx2++)
236         {
237            dlCcchIndInfo->dlCcchMsg[idx2] = dlCcchMsg[idx2];
238         }
239         DU_FREE(dlCcchMsg, dlCcchMsgSize);
240
241         /* Fill Pst */
242         pst.selector  = DU_MAC_LWLC;
243         pst.srcEnt    = ENTDUAPP;
244         pst.dstEnt    = ENTRG;
245         pst.dstInst   = 0;
246         pst.srcInst   = 0;
247         pst.dstProcId = DU_PROC;
248         pst.srcProcId = DU_PROC;
249         pst.region    = DU_APP_MEM_REGION;
250         pst.pool      = DU_POOL;
251         pst.event     = EVENT_MAC_DL_CCCH_IND;
252
253    ret = (*packMacDlCcchIndOpts[pst.selector])(&pst, dlCcchIndInfo);
254         if(ret != ROK)
255         {
256       DU_LOG("\nDU_APP : Failure in sending DL CCCH to MAC");
257                 DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, dlCcchIndInfo->dlCcchMsg,\
258                   dlCcchIndInfo->dlCcchMsgLen);
259                 DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, dlCcchIndInfo, \
260                   sizeof(DlCcchIndInfo));
261       ret = RFAILED; 
262         }
263
264         return ret;
265
266 }
267
268 /******************************************************************
269 *
270 * @brief Processes DL RRC Message Transfer  sent by CU
271 *
272 * @details
273 *
274 *    Function : procDlRrcMsgTrans 
275 *
276 *    Functionality: Processes DL RRC Message Transfer sent by CU
277 *
278 * @params[in] F1AP_PDU_t ASN decoded F1AP message
279 * @return ROK     - success
280 *         RFAILED - failure
281 *
282 * ****************************************************************/
283 uint8_t procDlRrcMsgTrans(F1AP_PDU_t *f1apMsg)
284 {
285         DLRRCMessageTransfer_t *dlRrcMsg = NULLP;
286         uint8_t                *dlCcchMsg = NULLP;
287         uint8_t                idx, ret, srbId;
288         uint16_t               idx2, crnti, cellId, dlCcchMsgSize;
289         uint32_t               gnbCuUeF1apId, gnbDuUeF1apId;
290
291
292         DU_LOG("\nDU_APP : DL RRC message transfer Recevied");
293         dlRrcMsg = &f1apMsg->choice.initiatingMessage->value.choice.DLRRCMessageTransfer;
294
295         ret = ROK;
296
297         for(idx=0; idx<dlRrcMsg->protocolIEs.list.count; idx++)
298         {
299                 switch(dlRrcMsg->protocolIEs.list.array[idx]->id)
300                 {
301                         case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
302                                 {
303                                         gnbCuUeF1apId = dlRrcMsg->protocolIEs.list.array[idx]->value.choice.GNB_CU_UE_F1AP_ID;
304                                         UNUSED(gnbCuUeF1apId); //This is currently not used
305                                         break;
306                                 }
307                         case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
308                                 {
309                                         gnbDuUeF1apId = dlRrcMsg->protocolIEs.list.array[idx]->value.choice.GNB_DU_UE_F1AP_ID;
310                                         break;
311                                 }
312                         case ProtocolIE_ID_id_SRBID:
313                                 {
314                                         srbId = dlRrcMsg->protocolIEs.list.array[idx]->value.choice.SRBID;
315                                         break;
316                                 }
317         case ProtocolIE_ID_id_ExecuteDuplication:
318                                         break;
319
320                         case ProtocolIE_ID_id_RRCContainer:
321                                 {
322                                    if(dlRrcMsg->protocolIEs.list.array[idx]->value.choice.RRCContainer.size > 0)
323                                         {
324                                       dlCcchMsgSize = dlRrcMsg->protocolIEs.list.array[idx]->value.choice.RRCContainer.size;
325                                       DU_ALLOC(dlCcchMsg, dlCcchMsgSize);
326                                            for(idx2 = 0; idx2 < dlCcchMsgSize; idx2++)
327                                            {
328                                               dlCcchMsg[idx2] = \
329                                                  dlRrcMsg->protocolIEs.list.array[idx]->value.choice.RRCContainer.buf[idx2];
330                                            }
331                                         }
332                                         else
333                                         {
334                                       DU_LOG("\nDU_APP : RRC Container Size is invalid:%d",\
335                                                  dlRrcMsg->protocolIEs.list.array[idx]->value.choice.RRCContainer.size);
336                                         }
337                                         break;
338                                 }
339
340                         default:
341                                 DU_LOG("\nDU_APP : Invalid IE received in DL RRC Msg Transfer:%ld",
342                                                 dlRrcMsg->protocolIEs.list.array[idx]->id);
343                 }
344         }
345    
346    for(idx=0; idx<duCb.numUe; idx++)
347         {
348       if(gnbDuUeF1apId == duCb.ueCcchCtxt[idx].gnbDuUeF1apId)
349                 {
350                    crnti  = duCb.ueCcchCtxt[idx].crnti;
351                         cellId = duCb.ueCcchCtxt[idx].cellId;
352                 }
353         }
354         if(srbId == SRB_ID_1) //RRC connection setup
355         {
356                 ret = duBuildAndSendDlCcchInd(cellId, crnti, RRC_SETUP, dlCcchMsg, dlCcchMsgSize);
357         }
358         return ret;
359 }
360
361 /******************************************************************
362  *
363  * @brief Generates GNB DU Ue F1AP ID
364  *
365  * @details
366  *
367  *    Function : genGnbDuUeF1apId
368  *
369  *    Functionality: Generates GNB DU Ue F1AP ID
370  *
371  * @params[in] void
372  * @return gnbDuF1apId
373  *
374  * ****************************************************************/
375 uint32_t genGnbDuUeF1apId()
376 {
377         static uint32_t gnbDuUeF1apId = 0;
378
379         return ++gnbDuUeF1apId;
380 }
381 /******************************************************************
382  *
383  * @brief Processes UL CCCH Ind recvd from MAC
384  *
385  * @details
386  *
387  *    Function : duProcUlCcchInd
388  *
389  *    Functionality: Processes UL CCCH Ind recvd from MAC
390  *
391  * @params[in] UlCcchIndInfo *ulCcchIndInfo
392  * @return ROK     - success
393  *         RFAILED - failure
394  *
395  * ****************************************************************/
396 uint8_t duProcUlCcchInd(UlCcchIndInfo *ulCcchIndInfo)
397 {
398
399    uint8_t ret = ROK;
400         uint32_t gnbDuUeF1apId = 0;
401
402         gnbDuUeF1apId = genGnbDuUeF1apId();
403
404         /* Store Ue mapping */
405         duCb.ueCcchCtxt[duCb.numUe].gnbDuUeF1apId = gnbDuUeF1apId;
406         duCb.ueCcchCtxt[duCb.numUe].crnti         = ulCcchIndInfo->crnti;
407         duCb.ueCcchCtxt[duCb.numUe].cellId        = ulCcchIndInfo->cellId;
408
409         duCb.numUe++;
410
411    ret = (BuildAndSendInitialRrcMsgTransfer(gnbDuUeF1apId, ulCcchIndInfo->crnti,
412                                 ulCcchIndInfo->ulCcchMsg));
413         if(ret != ROK)
414         {
415       DU_LOG("\nDU_APP : BuildAndSendInitialRrcMsgTransfer failed");
416         }
417
418    DU_FREE_SHRABL_BUF(MAC_MEM_REGION, RG_POOL, ulCcchIndInfo->ulCcchMsg, strlen((const char*)ulCcchIndInfo->ulCcchMsg));
419    DU_FREE_SHRABL_BUF(MAC_MEM_REGION, RG_POOL, ulCcchIndInfo, sizeof(UlCcchIndInfo));
420
421         return ret;
422
423 }
424
425
426 /**********************************************************************
427          End of file
428 ***********************************************************************/