1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
19 /* header include files (.h) */
20 #include "common_def.h"
21 #include "rgu.h" /* RGU interface includes*/
22 #include "lkw.h" /* LKW defines */
23 #include "ckw.h" /* CKW defines */
24 #include "kwu.h" /* KWU defines */
25 #include "kw_env.h" /* RLC environment options */
26 #include "kw.h" /* RLC defines */
31 /* header/extern include files (.x) */
33 #include "lkw.x" /* LKW */
34 #include "ckw.x" /* CKW */
35 #include "kwu.x" /* KWU */
42 #include "rlc_mac_inf.h"
43 #include "du_app_rlc_inf.h"
44 #include "rlc_utils.h"
45 #include "rlc_upr_inf_api.h"
46 /*******************************************************************
48 * @brief Fills RLC UL UE Cfg Rsp from RlcCRsp
52 * Function : fillRlcUlUeCfgRsp
55 * Fills RLC UL UE Cfg Rsp from RlcCRsp
57 * @params[in] Pointer to RlcCfgCfm
58 * Pointer to RlcUeCfgRsp
62 *****************************************************************/
64 void fillRlcUlUeCfgRsp(RlcUeCfgRsp *rlcCfgRsp, RlcCfgCfmInfo *rlcCRsp)
68 rlcCfgRsp->cellId = rlcCRsp->cellId;
69 rlcCfgRsp->ueIdx = rlcCRsp->ueId;
70 for(idx = 0; idx < rlcCRsp->numEnt; idx++)
72 if(rlcCRsp->entCfgCfm[idx].status.status == CKW_CFG_CFM_OK)
74 rlcCfgRsp->result = RLC_DU_APP_RSP_OK;
75 rlcCfgRsp->reason = rlcCRsp->entCfgCfm[idx].status.reason;
79 rlcCfgRsp->result = RLC_DU_APP_RSP_NOK;
80 rlcCfgRsp->reason = rlcCRsp->entCfgCfm[idx].status.reason;
85 /*******************************************************************
87 * @brief Fills the entity mode and direction compiling to seed code
91 * Function : fillEntModeAndDir
94 * Fills the entity mode and direction compiling to seed code
96 * @params[in] Pointer to entMode
97 * Pointer to direction
100 * ****************************************************************/
102 void fillEntModeAndDir(uint8_t *entMode, uint8_t *direction, RlcMode rlcMode)
107 *entMode = CM_LTE_MODE_AM;
108 *direction = RLC_CFG_DIR_BOTH;
110 case RLC_UM_BI_DIRECTIONAL:
111 *entMode = CM_LTE_MODE_UM;
112 *direction = RLC_CFG_DIR_BOTH;
114 case RLC_UM_UNI_DIRECTIONAL_UL:
115 *entMode = CM_LTE_MODE_UM;
116 *direction = RLC_CFG_DIR_UL;
118 case RLC_UM_UNI_DIRECTIONAL_DL:
119 *entMode = CM_LTE_MODE_UM;
120 *direction = RLC_CFG_DIR_DL;
123 DU_LOG("\nRLC: Rlc Mode invalid %d", rlcMode);
127 /*******************************************************************
129 * @brief Handles Ue Create Request from DU APP
133 * Function : RlcUlProcUeCreateReq
136 * Handles Ue create Request from DU APP
138 * @params[in] Post structure pointer
140 * @return ROK - success
143 * ****************************************************************/
144 uint8_t RlcUlProcUeCreateReq(Pst *pst, RlcUeCfg *ueCfg)
149 RlcCfgInfo *rlcUeCfg = NULLP;
151 RlcCb *rlcUeCb = NULLP;
152 rlcUeCb = RLC_GET_RLCCB(pst->dstInst);
153 RLC_ALLOC(rlcUeCb, rlcUeCfg, sizeof(RlcCfgInfo));
156 memset(rlcUeCfg, 0, sizeof(RlcCfgInfo));
158 rlcUeCfg->ueId = ueCfg->ueIdx;
159 rlcUeCfg->cellId = ueCfg->cellId;
160 rlcUeCfg->numEnt = ueCfg->numLcs;
161 rlcUeCfg->transId = getTransId();
163 for(idx = 0; idx < ueCfg->numLcs; idx++)
166 rlcUeCfg->entCfg[idx].rbId = ueCfg->rlcBearerCfg[idx].rbId;
167 rlcUeCfg->entCfg[idx].rbType = ueCfg->rlcBearerCfg[idx].rbType; // SRB or DRB
168 rlcUeCfg->entCfg[idx].lCh[lChRbIdx].lChId = ueCfg->rlcBearerCfg[idx].lcId;
169 rlcUeCfg->entCfg[idx].lCh[lChRbIdx].type = ueCfg->rlcBearerCfg[idx].lcType;
170 fillEntModeAndDir(&rlcUeCfg->entCfg[idx].entMode, &rlcUeCfg->entCfg[idx].dir,\
171 ueCfg->rlcBearerCfg[idx].rlcMode);
172 rlcUeCfg->entCfg[idx].cfgType = CKW_CFG_ADD;
173 switch(rlcUeCfg->entCfg[idx].entMode)
179 rlcUeCfg->entCfg[idx].m.amInfo.dl.snLen = ueCfg->rlcBearerCfg[idx].u.amCfg.dlAmCfg.snLenDl;
180 rlcUeCfg->entCfg[idx].m.amInfo.dl.pollRetxTmr = ueCfg->rlcBearerCfg[idx].u.amCfg.dlAmCfg.pollRetxTmr;
181 rlcUeCfg->entCfg[idx].m.amInfo.dl.pollPdu = ueCfg->rlcBearerCfg[idx].u.amCfg.dlAmCfg.pollPdu;
182 rlcUeCfg->entCfg[idx].m.amInfo.dl.pollByte = ueCfg->rlcBearerCfg[idx].u.amCfg.dlAmCfg.pollByte;
183 rlcUeCfg->entCfg[idx].m.amInfo.dl.maxRetx = ueCfg->rlcBearerCfg[idx].u.amCfg.dlAmCfg.maxRetxTh;
186 lChRbIdx++; //lChRbIdx = 1, indicates UL AM
187 rlcUeCfg->entCfg[idx].lCh[lChRbIdx].lChId = ueCfg->rlcBearerCfg[idx].lcId;
188 rlcUeCfg->entCfg[idx].lCh[lChRbIdx].type = ueCfg->rlcBearerCfg[idx].lcType;
189 rlcUeCfg->entCfg[idx].m.amInfo.ul.snLen = ueCfg->rlcBearerCfg[idx].u.amCfg.ulAmCfg.snLenUl;
190 rlcUeCfg->entCfg[idx].m.amInfo.ul.staProhTmr = ueCfg->rlcBearerCfg[idx].u.amCfg.ulAmCfg.statProhTmr;
191 rlcUeCfg->entCfg[idx].m.amInfo.ul.reOrdTmr = ueCfg->rlcBearerCfg[idx].u.amCfg.ulAmCfg.reAssemTmr;
197 rlcUeCfg->entCfg[idx].m.umInfo.ul.snLen = ueCfg->rlcBearerCfg[idx].u.umBiDirCfg.ulUmCfg.snLenUlUm;
198 rlcUeCfg->entCfg[idx].m.umInfo.ul.reOrdTmr = ueCfg->rlcBearerCfg[idx].u.umBiDirCfg.ulUmCfg.reAssemTmr;
201 rlcUeCfg->entCfg[idx].m.umInfo.dl.snLen = ueCfg->rlcBearerCfg[idx].u.umBiDirCfg.dlUmCfg.snLenDlUm;
206 }/* End of switch(entMode) */
208 ret = RlcProcCfgReq(pst, rlcUeCfg);
212 DU_LOG("\nRLC: Failed to allocate memory ");
215 RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ueCfg, sizeof(RlcUeCfg));
218 /*******************************************************************
220 * @brief filling the structure of rrc delivery msg info
224 * Function : BuildAndSendRrcDeliveryReportToDu
226 * Functionality: filling the structure of rrc delivery msg info
228 * @return ROK - success
231 * ****************************************************************/
232 uint8_t BuildAndSendRrcDeliveryReportToDu( RlcDlRrcMsgInfo *dlRrcMsgInfo )
235 RrcDeliveryReport *rrcDelivery;
237 DU_LOG("\nRLC : Filling the RRC Delivery Report");
238 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, rrcDelivery, sizeof(RrcDeliveryReport));
242 rrcDelivery->cellId = dlRrcMsgInfo->cellId;
243 rrcDelivery->ueIdx = dlRrcMsgInfo->ueIdx;
244 rrcDelivery->srbId = dlRrcMsgInfo->lcId ;
245 rrcDelivery->rrcDeliveryStatus.deliveryStatus = PDCP_SN;
246 rrcDelivery->rrcDeliveryStatus.triggeringMessage = PDCP_SN;
248 /* Sending UL RRC Message transfeer to DU APP */
249 memset(&pst, 0, sizeof(Pst));
250 FILL_PST_RLC_TO_DUAPP(pst, RLC_UL_INST, EVENT_RRC_DELIVERY_MSG_TRANS_TO_DU);
251 rlcSendRrcDeliveryReportToDu(&pst, rrcDelivery);
255 DU_LOG("\nRLC : Memory allocation failed");
260 /* ****************************************************************
262 * @brief Process the DL RRC Message from DU APP
266 * Function : RlcProcDlRrcMsgTransfer
268 * Functionality: Process the DL RRC Message from DU APP
270 * @params[in] Post structure
271 * DL RRC Message info
272 * @return ROK - success
275 * ****************************************************************/
276 uint8_t RlcProcDlRrcMsgTransfer(Pst *pst, RlcDlRrcMsgInfo *dlRrcMsgInfo)
279 KwuDatReqInfo *datReqInfo;
281 RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(KwuDatReqInfo));
284 DU_LOG("\nRLC : Memory allocation failed in RlcProcDlRrcMsgTransfer");
285 RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo->rrcMsg, dlRrcMsgInfo->msgLen);
286 RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo, sizeof(RlcDlRrcMsgInfo));
290 datReqInfo->rlcId.rbType = dlRrcMsgInfo->rbType;
291 datReqInfo->rlcId.rbId = dlRrcMsgInfo->rbId;
292 datReqInfo->rlcId.ueId = dlRrcMsgInfo->ueIdx;
293 datReqInfo->rlcId.cellId = dlRrcMsgInfo->cellId;
294 datReqInfo->lcType = dlRrcMsgInfo->lcType;
295 datReqInfo->sduId = ++(rlcCb[pst->dstInst]->dlSduId);
297 /* Copy fixed buffer to message */
298 if(ODU_GET_MSG_BUF(RLC_MEM_REGION_UL, RLC_POOL, &mBuf) != ROK)
300 DU_LOG("\nRLC : Memory allocation failed at RlcMacProcUlData");
301 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(KwuDatReqInfo));
302 RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo->rrcMsg, dlRrcMsgInfo->msgLen);
303 RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo, sizeof(RlcDlRrcMsgInfo));
306 oduCpyFixBufToMsg(dlRrcMsgInfo->rrcMsg, mBuf, dlRrcMsgInfo->msgLen);
308 rlcProcDlData(pst, datReqInfo, mBuf);
310 /* RRC Delivery report is only send when RRC Delivery status report is true in DL RRC Message */
311 if(dlRrcMsgInfo->deliveryStaRpt)
313 BuildAndSendRrcDeliveryReportToDu(dlRrcMsgInfo);
316 /* Free memory allocated by du app */
317 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(KwuDatReqInfo));
318 RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo->rrcMsg, dlRrcMsgInfo->msgLen);
319 RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo, sizeof(RlcDlRrcMsgInfo));
323 /*******************************************************************
325 * @brief Process UL data from UE
329 * Function : RlcProcUlData
332 * This function receives the PDU from MAC.
333 * seggregates common and dedicated logical channel
334 * PDU and call respective handler.
337 * @return ROK - success
340 * ****************************************************************/
341 uint8_t RlcProcUlData(Pst *pst, RlcData *ulData)
345 uint8_t lcId; /* Logical Channel */
346 uint8_t numDLch = 0; /* Number of dedicated logical channel */
347 bool dLchPduPres; /* PDU received on dedicated logical channel */
348 RguLchDatInd dLchData[MAX_NUM_LC]; /* PDU info on dedicated logical channel */
349 RguDDatIndInfo *dLchUlDat; /* UL data on dedicated logical channel */
350 RguCDatIndInfo *cLchUlDat; /* UL data on common logical channel */
352 /* Initializing dedicated logical channel Database */
353 for(idx = 0; idx < MAX_NUM_LC; idx++)
355 dLchData[idx].lcId = idx;
356 dLchData[idx].pdu.numPdu = 0;
360 /* Seggregate PDUs received on common and dedicated channels
361 * and call common channel's handler */
362 for(idx = 0; idx< ulData->numPdu; idx++)
364 if(ulData->pduInfo[idx].commCh)
366 RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_UL, RLC_POOL, cLchUlDat, \
367 sizeof(RguCDatIndInfo));
370 DU_LOG("\nRLC : Memory allocation failed at RlcProcUlData");
374 memset(cLchUlDat, 0, sizeof(RguCDatIndInfo));
376 cLchUlDat->cellId = ulData->cellId;
377 GET_UE_IDX(ulData->rnti, cLchUlDat->rnti);
378 cLchUlDat->lcId = ulData->pduInfo[idx].lcId;
380 /* Copy fixed buffer to message */
381 if(ODU_GET_MSG_BUF(RLC_MEM_REGION_UL, RLC_POOL, &cLchUlDat->pdu) != ROK)
383 DU_LOG("\nRLC : Memory allocation failed at RlcProcUlData");
384 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, cLchUlDat, \
385 sizeof(RguCDatIndInfo));
389 oduCpyFixBufToMsg(ulData->pduInfo[idx].pduBuf, cLchUlDat->pdu, \
390 ulData->pduInfo[idx].pduLen);
392 rlcProcCommLcUlData(pst, 0, cLchUlDat);
398 RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_UL, RLC_POOL, dLchUlDat, \
399 sizeof(RguDDatIndInfo));
402 DU_LOG("\nRLC : Memory allocation failed at RlcMacProcUlData");
409 /* Copy fixed buffer to message */
410 lcId = ulData->pduInfo[idx].lcId;
411 if(ODU_GET_MSG_BUF(RLC_MEM_REGION_UL, RLC_POOL, \
412 &dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu]) != ROK)
414 DU_LOG("\nRLC : Memory allocation failed at RlcMacProcUlData");
415 for(pduIdx=0; pduIdx < dLchData[lcId].pdu.numPdu; pduIdx++)
417 ODU_PUT_MSG_BUF(dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu]);
419 RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, dLchUlDat, \
420 sizeof(RguDDatIndInfo));
424 oduCpyFixBufToMsg(ulData->pduInfo[idx].pduBuf, \
425 dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu],\
426 ulData->pduInfo[idx].pduLen);
428 dLchData[lcId].pdu.numPdu++;
432 /* If any PDU received on dedicated logical channel, copy into RguDDatIndInfo
433 * and call its handler */
438 dLchUlDat->cellId = ulData->cellId;
439 dLchUlDat->rnti = ulData->rnti;
441 for(idx = 0; idx < MAX_NUM_LC; idx++)
443 if(dLchData[idx].pdu.numPdu)
445 memcpy(&dLchUlDat->lchData[numDLch], &dLchData[idx], sizeof(RguLchDatInd));
449 dLchUlDat->numLch = numDLch;
450 rlcProcDedLcUlData(pst, 0, dLchUlDat);
454 for(pduIdx = 0; pduIdx < ulData->numPdu; idx++)
456 RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ulData->pduInfo[pduIdx].pduBuf, \
457 ulData->pduInfo[pduIdx].pduLen);
459 RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ulData, sizeof(RlcData));
462 }/* End of RlcProcUlData */
464 /*******************************************************************
466 * @brief Handler for extracting common and dedicated channel
467 * Scheduling result report.
471 * Function : RlcProcSchedResultRpt
474 * Handler for extracting common and dedicated channel
475 * Scheduling result report
478 * @return ROK - success
481 * ****************************************************************/
482 uint8_t RlcProcSchedResultRpt(Pst *pst, RlcSchedResultRpt *schRep)
485 uint8_t idx; /* Iterator */
486 uint8_t nmbDLch = 0; /* Number of dedicated logical channles */
487 RguCStaIndInfo *cLchSchInfo; /* Common logical channel scheduling result */
488 RguDStaIndInfo *dLchSchInfo; /* Dedicated logical channel scheduling result */
490 DU_LOG("\nRLC : Received scheduling report from MAC");
492 for(idx=0; idx < schRep->numLc; idx++)
494 /* If it is common channel, fill status indication information
495 * and trigger the handler for each common lch separately */
496 if(schRep->lcSch[idx].commCh)
498 RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, cLchSchInfo, \
499 sizeof(RguCStaIndInfo));
502 DU_LOG("\nRLC: RlcProcSchedResultRpt: Memory allocation failed for cLchSchInfo");
506 memset(cLchSchInfo, 0, sizeof(RguCStaIndInfo));
508 cLchSchInfo->cellId = schRep->cellId;
509 cLchSchInfo->lcId = schRep->lcSch[idx].lcId;
510 cLchSchInfo->transId = schRep->slotInfo.sfn;
511 cLchSchInfo->transId = (cLchSchInfo->transId << 16) | schRep->slotInfo.slot;
512 cLchSchInfo->rnti = schRep->rnti;
513 rlcProcCommLcSchedRpt(pst, 0, cLchSchInfo);
518 /* Fill status info structure if at least one dedicated channel
519 * scheduling report is received */
522 RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, dLchSchInfo, \
523 sizeof(RguDStaIndInfo));
526 DU_LOG("\nRLC: RlcProcSchedResultRpt: Memory allocation failed for dLchSchInfo");
531 dLchSchInfo->cellId = schRep->cellId;
532 dLchSchInfo->nmbOfUeGrantPerTti = 1;
533 /* MAC sends Scheduling report for one UE at a time. Hence filling
534 only the 0th index of staInd */
535 dLchSchInfo->staInd[0].rnti = schRep->rnti;
537 /* Storing sfn/slot into a single 32-bit variable to be used later*/
538 dLchSchInfo->staInd[0].transId = schRep->slotInfo.sfn;
539 dLchSchInfo->staInd[0].transId = \
540 (dLchSchInfo->staInd[0].transId << 16) | schRep->slotInfo.slot;
541 dLchSchInfo->staInd[0].nmbOfTbs = 1;
542 dLchSchInfo->staInd[0].fillCtrlPdu = true;
545 /* Fill logical channel scheduling info */
546 dLchSchInfo->staInd[0].staIndTb[0].lchStaInd[nmbDLch].lcId = \
547 schRep->lcSch[idx].lcId;
548 dLchSchInfo->staInd[0].staIndTb[0].lchStaInd[nmbDLch].totBufSize = \
549 schRep->lcSch[idx].bufSize;
554 /* Calling handler for all dedicated channels scheduling*/
559 dLchSchInfo->staInd[0].staIndTb[0].nmbLch = nmbDLch;
560 rlcProcDedLcSchedRpt(pst, 0, dLchSchInfo);
564 RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, schRep, sizeof(RlcSchedResultRpt));
568 /**********************************************************************
570 **********************************************************************/