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 /********************************************************************20**
21 Name: LTE-RLC Layer - Lower Interface Functions
25 Desc: Source code for RLC Lower Interface Module.
26 This file contains following functions
37 **********************************************************************/
38 static const char* RLOG_MODULE_NAME="LIM";
39 static int RLOG_MODULE_ID=2048;
40 static int RLOG_FILE_ID=196;
44 * @brief RLC Lower Interface module
47 #define KW_MODULE KW_DBGMASK_INF
50 /* header (.h) include files */
51 #include "envopt.h" /* environment options */
52 #include "envdep.h" /* environment dependent */
53 #include "envind.h" /* environment independent */
55 #include "gen.h" /* general */
56 #include "ssi.h" /* system services */
57 #include "cm5.h" /* common timer defines */
58 #include "cm_tkns.h" /* common tokens defines */
59 #include "cm_mblk.h" /* common memory allocation library defines */
60 #include "cm_llist.h" /* common link list defines */
61 #include "cm_hash.h" /* common hash list defines */
62 #include "cm_lte.h" /* common LTE defines */
63 #include "lkw.h" /* LKW defines */
64 #include "ckw.h" /* CKW defines */
65 #include "kwu.h" /* KWU defines */
66 #include "rgu.h" /* RGU defines */
68 #include "kw_env.h" /* RLC environment options */
70 #include "kw.h" /* RLC defines */
75 /* extern (.x) include files */
76 #include "gen.x" /* general */
77 #include "ssi.x" /* system services */
79 #include "cm5.x" /* common timer library */
80 #include "cm_tkns.x" /* common tokens */
81 #include "cm_mblk.x" /* common memory allocation */
82 #include "cm_llist.x" /* common link list */
83 #include "cm_hash.x" /* common hash list */
84 #include "cm_lte.x" /* common LTE includes */
85 #include "cm_lib.x" /* common memory allocation library */
86 #include "lkw.x" /* LKW */
87 #include "ckw.x" /* CKW */
88 #include "kwu.x" /* KWU */
89 #include "rgu.x" /* RGU */
98 #endif /* __cplusplus */
101 /*****************************************************************************
103 ****************************************************************************/
105 * @brief Handler for bind confirmation from MAC.
108 * This function handles the bind confirmation received from MAC. If the
109 * bind was successful changes the state of the SAP to KW_SAP_BND
110 * else KW_SAP_CFG. Sends an alarm to LM in any case
112 * @param[in] pst Post structure
113 * @param[in] suId Service User ID
114 * @param[in] status Status whether the bind was successful or not
122 PUBLIC S16 KwLiRguBndCfm
129 PUBLIC S16 KwLiRguBndCfm (pst, suId, status)
135 U16 event; /* Event */
136 U16 cause; /* Cause */
137 KwRguSapCb *rguSap; /* RGU SAP Control Block */
142 #if (ERRCLASS & ERRCLS_INT_PAR)
143 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
148 tKwCb = KW_GET_KWCB(pst->dstInst);
150 RLOG2(L_DEBUG,"KwLiRguBndCfm(suId(%d), status(%d)", suId, status);
152 #if (ERRCLASS & ERRCLS_INT_PAR)
153 if (tKwCb->init.cfgDone != TRUE)
155 RLOG0(L_FATAL,"General configuration not done");
157 KW_SEND_SAPID_ALARM(tKwCb,suId,LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_STATE);
162 if ((suId >= tKwCb->genCfg.maxRguSaps) || (suId < 0))
164 RLOG0(L_ERROR, "Invalid suId");
166 KW_SEND_SAPID_ALARM(tKwCb,suId, LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_SUID);
170 #endif /* ERRCLASS & ERRCLS_INT_PAR */
172 rguSap = (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
173 &(tKwCb->u.dlCb->rguDlSap[suId]) : &(tKwCb->u.ulCb->rguUlSap[suId]);
175 RLOG1(L_DEBUG, "KwLiRguBndCfm: For RGU SAP state=%d", rguSap->state)
177 switch (rguSap->state)
181 kwStopTmr (tKwCb,(PTR)rguSap, KW_EVT_WAIT_BNDCFM);
183 rguSap->retryCnt = 0;
185 if (status == CM_BND_OK)
187 rguSap->state = KW_SAP_BND;
188 event = LCM_EVENT_BND_OK;
189 cause = LKW_CAUSE_SAP_BNDENB;
193 rguSap->state = KW_SAP_CFG;
194 event = LCM_EVENT_BND_FAIL;
195 cause = LKW_CAUSE_UNKNOWN;
201 event = LKW_EVENT_RGU_BND_CFM;
202 cause = LCM_CAUSE_INV_STATE;
206 /* Send an alarm with proper event and cause */
207 KW_SEND_SAPID_ALARM(tKwCb, suId, event, cause);
210 } /* KwLiRguBndCfm */
213 * @brief Handler to process PDU received from MAC
216 * This function receives the PDU from MAC.
217 * seggregates common and dedicated logical channel
218 * PDU and call respective handler.
220 * @param[in] pst Post structure
221 * @param[in] suId Service User ID
222 * @param[in] datInd Data Indication Information
230 PUBLIC S16 RlcMacProcUlData(Pst *pst, SuId suId, RlcMacData *ulData)
233 U8 lcId; /* Logical Channel */
234 U8 numDLch = 0; /* Number of dedicated logical channel */
235 Bool dLchPduPres; /* PDU received on dedicated logical channel */
236 RguLchDatInd dLchData[RGU_MAX_LC]; /* PDU info on dedicated logical channel */
237 RguDDatIndInfo *dLchUlDat; /* UL data on dedicated logical channel */
238 RguCDatIndInfo *cLchUlDat; /* UL data on common logical channel */
240 /* Initializing dedicated logical channel Database */
241 for(idx = 0; idx < RGU_MAX_LC; idx++)
243 dLchData[idx].lcId = idx;
244 dLchData[idx].pdu.numPdu = 0;
249 /* Seggregate PDUs received on common and dedicated channels
250 * and call common channel's handler */
251 for(idx = 0; idx< ulData->nmbPdu; idx++)
253 if(ulData->pduInfo[idx].commCh)
255 KW_SHRABL_STATIC_BUF_ALLOC(pst->region, pst->pool, cLchUlDat, sizeof(RguCDatIndInfo));
256 cmMemset((U8*)cLchUlDat, (U8)0, sizeof(RguCDatIndInfo));
258 cLchUlDat->cellId = ulData->cellId;
259 cLchUlDat->rnti = ulData->rnti;
260 cLchUlDat->lcId = ulData->pduInfo[idx].lcId;
261 cLchUlDat->pdu = ulData->pduInfo[idx].pduBuf;
263 KwLiRguCDatInd(pst, suId, cLchUlDat);
269 KW_SHRABL_STATIC_BUF_ALLOC(pst->region, pst->pool, dLchUlDat, sizeof(RguDDatIndInfo));
273 lcId = ulData->pduInfo[idx].lcId;
274 dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu] = ulData->pduInfo[idx].pduBuf;
275 dLchData[lcId].pdu.numPdu++;
279 /* If any PDU received on dedicated logical channel, copy into RguDDatIndInfo
280 * and call its handler */
283 dLchUlDat->cellId = ulData->cellId;
284 dLchUlDat->rnti = ulData->rnti;
286 for(idx = 0; idx < RGU_MAX_LC; idx++)
288 if(dLchData[idx].pdu.numPdu)
290 cmMemcpy((U8 *)&dLchUlDat->lchData[numDLch], (U8 *)&dLchData[idx], sizeof(RguLchDatInd));
294 dLchUlDat->numLch = numDLch;
295 KwLiRguDDatInd(pst, suId, dLchUlDat);
299 KW_FREE_SHRABL_BUF(pst->region, pst->pool, ulData, sizeof(RlcMacData));
302 }/* End of RlcMacProcUlData */
304 PUBLIC int rlcDDatIndRcvd;
305 PUBLIC int rlcCDatIndRcvd;
307 * @brief Handler to process PDU received from MAC for common logical channels.
310 * This function receives the PDU from MAC for common logical channels
311 * does checks before handing over the PDU to the TM module
313 * @param[in] pst Post structure
314 * @param[in] suId Service User ID
315 * @param[in] datInd Data Indication Information
323 PUBLIC S16 KwLiRguCDatInd
327 RguCDatIndInfo *datInd
330 PUBLIC S16 KwLiRguCDatInd(pst,suId,datInd)
333 RguCDatIndInfo *datInd;
342 #if (ERRCLASS & ERRCLS_INT_PAR)
343 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
345 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
350 tKwCb = KW_GET_KWCB(pst->dstInst);
353 #if (ERRCLASS & ERRCLS_DEBUG)
354 if (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL)
356 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
361 /* kw006.201 ccpu00120058, Added array boundary condition check */
362 #if (ERRCLASS & ERRCLS_DEBUG)
363 if(KW_MAX_LCH_PER_CELL <= datInd->lcId)
365 RLOG_ARG1(L_ERROR,DBG_LCID,datInd->lcId, "Invalid LcId, Max is [%d]",
366 KW_MAX_LCH_PER_CELL);
367 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
370 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
372 /* Fetch RbCb from lcId */
373 kwDbmFetchUlRbCbFromLchId(tKwCb, 0, datInd->cellId, datInd->lcId, &rbCb);
376 RLOG_ARG1(L_ERROR, DBG_CELLID,datInd->cellId, "LcId [%d] not found",
378 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
382 /* Dispatch to TM Module */
384 kwTmmRcvFrmLi(tKwCb, rbCb, datInd->rnti, datInd->pdu);
386 kwTmmRcvFrmLi(tKwCb, rbCb, datInd->pdu);
387 #endif /* CCPU_OPT */
389 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguCDatIndInfo));
392 } /* KwLiRguCDatInd */
395 * @brief Handler to process PDU received from MAC for
396 * dedicated logical channels.
399 * This function receives the PDU from MAC for one or more dedicated
400 * logical channels and passes it to the UTL module for further processing
402 * @param[in] pst Post structure
403 * @param[in] suId Service User ID
404 * @param[in] datInd Data Indication Information
413 PUBLIC S16 KwLiRguDDatInd
417 RguDDatIndInfo *datInd
420 PUBLIC S16 KwLiRguDDatInd(pst, suId, datInd)
423 RguDDatIndInfo *datInd;
429 #if (ERRCLASS & ERRCLS_INT_PAR)
430 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
432 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
437 #if (ERRCLASS & ERRCLS_DEBUG)
438 if (((KwCb*)KW_GET_KWCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_DL)
440 RLOG1(L_DEBUG,"KwLiRguDDatInd(pst, suId(%d))recieved in DL Inst",suId);
441 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
445 kwUtlRcvFrmLi(KW_GET_KWCB(pst->dstInst),datInd);
447 #ifdef SS_LOCKLESS_MEMORY
448 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
450 KW_PST_FREE(pst->region, pst->pool, datInd, sizeof(RguDDatIndInfo));
455 } /* KwLiRguDDatInd */
458 /*******************************************************************
460 * @brief Handler for extracting common and dedicated channel
461 * Scheduling result report.
465 * Function : RlcMacProcSchedRep
468 * Handler for extracting common and dedicated channel
469 * Scheduling result report
472 * @return ROK - success
475 * ****************************************************************/
476 PUBLIC S16 RlcMacProcSchedRep(Pst *pst, SuId suId, RlcMacSchedRep *schRep)
478 U8 idx; /* Iterator */
479 U8 nmbDLch = 0; /* Number of dedicated logical channles */
480 RguCStaIndInfo *cLchSchInfo; /* Common logical channel scheduling result */
481 RguDStaIndInfo *dLchSchInfo; /* Dedicated logical channel scheduling result */
483 DU_LOG("\nRLC : Received scheduling report from MAC");
485 for(idx=0; idx < schRep->nmbLch; idx++)
487 /* If it is common channel, fill status indication information
488 * and trigger the handler for each common lch separately */
489 if(schRep->lchSta[idx].commCh)
491 KW_SHRABL_STATIC_BUF_ALLOC(pst->region, pst->pool, cLchSchInfo, sizeof(RguCStaIndInfo));
492 cmMemset((U8*)cLchSchInfo, (U8)0, sizeof(RguCStaIndInfo));
494 cLchSchInfo->cellId = schRep->cellId;
495 cLchSchInfo->lcId = schRep->lchSta[idx].lchStaInd.lcId;
496 //cLchSchInfo->transId = schRep->timeToTx; /* TODO : fill transId suing timeToTx */
497 cLchSchInfo->rnti = schRep->rnti;
499 KwLiRguCStaInd(pst, suId, cLchSchInfo);
504 /* Fill status info structure if at least one dedicated channel
505 * scheduling report is received */
508 KW_SHRABL_STATIC_BUF_ALLOC(pst->region, pst->pool, dLchSchInfo, sizeof(RguDStaIndInfo));
510 dLchSchInfo->cellId = schRep->cellId;
511 dLchSchInfo->nmbOfUeGrantPerTti = 1;
512 dLchSchInfo->staInd[0].rnti = schRep->rnti;
513 //dLchSchInfo->staInd[0].transId = schRep->timeToTx; /* TODO : fill transId suing timeToTx */
514 dLchSchInfo->staInd[0].nmbOfTbs = 1;
515 //dLchSchInfo->staInd[0].fillCrlPdu = /* TODO : Check the value needed to be filled */
518 /* Fill logical channel scheduling info */
519 cmMemcpy((U8 *)&dLchSchInfo->staInd[0].staIndTb[0].lchStaInd[nmbDLch], (U8 *)&schRep->lchSta[idx].lchStaInd, sizeof(RguLchStaInd));
526 /* Calling handler for all dedicated channels scheduling*/
529 dLchSchInfo->staInd[0].staIndTb[0].nmbLch = nmbDLch;
530 KwLiRguDStaInd(pst, suId, dLchSchInfo);
533 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, schRep, sizeof(RlcMacSchedRep));
539 * @brief Handler for trigerring the data transfer from RLC to MAC
540 * for common logical channels.
543 * This function receives the size of the PDU to be transmitted
544 * and acts as a trigger for forming PDU and sending it to MAC.
546 * @param[in] pst Post structure
547 * @param[in] suId Service User ID
548 * @param[in] staInd Status Indication Information for Common Logical
557 PUBLIC S16 KwLiRguCStaInd
561 RguCStaIndInfo *staInd
564 PUBLIC S16 KwLiRguCStaInd(pst,suId,staInd)
567 RguCStaIndInfo *staInd;
575 #if (ERRCLASS & ERRCLS_INT_PAR)
576 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
578 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
583 tKwCb = KW_GET_KWCB(pst->dstInst);
586 #if (ERRCLASS & ERRCLS_INT_PAR)
587 if ((suId >= tKwCb->genCfg.maxRguSaps) || (suId < 0))
593 "KwLiRguCStaInd: Invalid RGU suId\n");
596 if (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_UL)
598 RLOG_ARG1(L_ERROR,DBG_LCID,staInd->lcId,
599 "Received in RLC UL CELLID:%d",
601 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
608 /* kw006.201 ccpu00120058, added boundary condition check */
609 #if (ERRCLASS & ERRCLS_DEBUG)
610 if(KW_MAX_LCH_PER_CELL < staInd->lcId)
612 RLOG_ARG2(L_ERROR,DBG_LCID,staInd->lcId,
613 "Invalid LcId, Max is [%d] CELLID:%d",
616 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
619 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
620 /* Fertch RbCb from lcId */
621 kwDbmFetchDlRbCbFromLchId(tKwCb,0, staInd->cellId, staInd->lcId, &rbCb);
624 RLOG_ARG1(L_ERROR, DBG_CELLID,staInd->cellId,
625 "LcId [%d] not found CELLID:%d",
627 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
631 /* Dispatch to TM Module */
632 rbCb->transId = staInd->transId;
634 /* If trace flag is enabled send the trace indication */
635 if(tKwCb->init.trc == TRUE)
637 /* Populate the trace params */
638 kwLmmSendTrc(tKwCb,EVTRGUCSTAIND, NULLP);
640 kwTmmSndToLi(tKwCb, suId, rbCb, staInd);
642 #ifdef SS_LOCKLESS_MEMORY
643 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
645 KW_PST_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
648 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguCStaIndInfo));
651 } /* KwLiRguCStaInd */
654 * @brief Handler for trigerring the data transfer from RLC to MAC
655 * for dedicated logical channels.
658 * This function receives the size of the PDUs to be transmitted to
659 * MAC via one or more dedicated logical channels and acts as a trigger
660 * for forming PDUs and sending them to MAC.
662 * @param[in] pst Post structure
663 * @param[in] suId Service User ID
664 * @param[in] staInd Status Indication Information for Dedicated Logical
673 PUBLIC S16 KwLiRguDStaInd
677 RguDStaIndInfo *staInd
680 PUBLIC S16 KwLiRguDStaInd(pst, suId, staInd)
683 RguDStaIndInfo *staInd;
689 #if (ERRCLASS & ERRCLS_INT_PAR)
690 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
692 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo));
697 gCb = KW_GET_KWCB(pst->dstInst);
699 #if (ERRCLASS & ERRCLS_INT_PAR)
700 if (((KwCb*)KW_GET_KWCB(pst->dstInst))->genCfg.rlcMode == LKW_RLC_MODE_UL)
702 RLOG_ARG0(L_ERROR,DBG_CELLID,staInd->cellId,"Received in RLC UL ");
703 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo));
706 if ((suId >= gCb->genCfg.maxRguSaps) || (suId < 0))
712 "KwLiRguDStaInd: Invalid RGU suId\n");
716 kwUtlSndToLi(gCb, suId, staInd);
718 /* kw002.201 :Freeing from proper region */
719 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, staInd, sizeof(RguDStaIndInfo));
721 } /* KwLiRguDStaInd */
724 * @brief Handler for handling the flow cntrl Ind from MAC
728 * This function receives the flow control indication from
729 * MAC and calls kwUtlTrigPdbFlowCntrl
731 * @param[in] pst Post structure
732 * @param[in] suId Service User ID
733 * @param[in] flowCntrlInd flow control Indication Information
742 PUBLIC S16 KwLiRguFlowCntrlInd
746 RguFlowCntrlInd *flowCntrlInd
749 PUBLIC S16 KwLiRguFlowCntrlInd(pst, suId, flowCntrlInd)
752 RguFlowCntrlInd *flowCntrlInd;
756 KwDlRbCb *rbCb = NULLP;
760 tKwCb = KW_GET_KWCB(pst->dstInst);
761 for (idx = 0; idx < flowCntrlInd->numUes; idx++)
763 for (lcIdx = 0; lcIdx < flowCntrlInd->ueFlowCntrlInfo[idx].numLcs; lcIdx++)
765 RguLcFlowCntrlInfo *lcInfo = &(flowCntrlInd->ueFlowCntrlInfo[idx].lcInfo[lcIdx]);
766 kwDbmFetchDlRbCbFromLchId(tKwCb, flowCntrlInd->ueFlowCntrlInfo[idx].ueId, flowCntrlInd->cellId, lcInfo->lcId, &rbCb);
770 if (lcInfo->pktAdmitCnt == 0) /* Special case */
772 kwUtlTrigPdbFlowCntrl(tKwCb, rbCb, lcInfo->pktAdmitCnt);
775 if (rbCb->mode == CM_LTE_MODE_AM)
777 if ((rbCb->m.amDl.retxLst.count != 0) ||
778 ((rbCb->m.amDl.bo == 0) ||
779 (rbCb->m.amDl.bo < lcInfo->maxBo4FlowCtrl)))
786 if ((rbCb->m.umDl.bo == 0) ||
787 (rbCb->m.umDl.bo < lcInfo->maxBo4FlowCtrl))
792 kwUtlTrigPdbFlowCntrl(tKwCb, rbCb, lcInfo->pktAdmitCnt);
798 /* kw005.201 added support for L2 Measurement */
805 * Handler for indicating the Harq Status of the data sent.
809 * This function receives the harq status of the data sent to MAC.
810 * This information is used for two things.
811 * 1. Computing the UuLoss of UM
812 * 2. Computing the DL Delay for UM and AM.
814 * @param[in] pst - Post structure
815 * @param[in] suId - Service User ID
816 * @param[in] staInd - Harq Status Indication Information.
824 PUBLIC S16 KwLiRguHqStaInd
828 RguHarqStatusInd *staInd
831 PUBLIC S16 KwLiRguHqStaInd(pst,suId,staInd)
834 RguHarqStatusInd *staInd;
844 TRC3(KwLiRguHqStaInd)
846 tKwCb = KW_GET_KWCB(pst->dstInst);
847 ueKey.cellId = staInd->cellId;
848 ueKey.ueId = staInd->ueId;
850 ret = kwDbmFetchDlUeCb(tKwCb, ueKey.ueId, ueKey.cellId, &ueCb);
856 /*Call kwUtlProcHarqInd as many times as number of Tbs present*/
857 for ( tbIdx = 0; tbIdx < staInd->numTbs; tbIdx++)
859 kwUtlProcHarqInd(tKwCb, staInd, ueCb, tbIdx);
863 } /* KwLiRguHqStaInd */
864 #endif /* LTE_L2_MEAS */
868 #endif /* __cplusplus */
870 /********************************************************************30**
872 **********************************************************************/