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-PDCP Layer - Lower Interface Functions
25 Desc: Source code for PDCP Lower Interface Module.
26 This file contains following functions
34 **********************************************************************/
36 static const char* RLOG_MODULE_NAME="PDCP";
37 static int RLOG_MODULE_ID=1024;
38 static int RLOG_FILE_ID=219;
40 @brief PDCP Lower Interface Module
44 /* header (.h) include files */
45 #include "envopt.h" /* environment options */
46 #include "envdep.h" /* environment dependent */
47 #include "envind.h" /* environment independent */
49 #include "gen.h" /* general */
50 #include "ssi.h" /* system services interface */
51 #include "cm5.h" /* Timer Functions */
52 #include "cm_lte.h" /* common LTE header file */
53 #include "cm_hash.h" /* common hash module file */
54 #include "cm_llist.h" /* common list header file */
55 #include "cpj.h" /* RRC layer */
57 #include "pju.h" /* PDCP service user */
58 #include "lpj.h" /* RRC layer */
59 #include "pj_env.h" /* RLC environment options */
60 #include "pj.h" /* RLC layer */
63 /* header/extern include files (.x) */
65 #include "gen.x" /* general */
66 #include "ssi.x" /* system services interface */
67 #include "cm_lib.x" /* common library */
68 #include "cm5.x" /* Timer Functions */
69 #include "cm_hash.x" /* common hash module */
70 #include "cm_lte.x" /* common LTE file */
71 #include "cm_llist.x" /* common list header file */
73 #include "cpj.x" /* RRC layer */
74 #include "pju.x" /* PDCP service user */
75 #include "lpj.x" /* LM Interface */
76 #include "pj.x" /* RLC layer */
84 #endif /* __cplusplus */
85 PRIVATE S16 pjLimDiscSduCfm ARGS((PjCb *gCb,
87 KwuDiscSduInfo *discSduCfm));
91 * @brief Handler for Sending sdu to Rlc.
97 * @param[in] pjRbCb PDCP control block.
98 * @param[in] sduId PDCP SDU id.
99 * @param[in] mBuf Pointer to PDCP Sdu
108 PUBLIC S16 pjDlmSendDatReq
116 PUBLIC S16 pjDlmSendDatReq(gCb,pjRbCb,sduId, mBuf)
124 KwuDatReqInfo datReq;
125 TRC2(pjDlmSendDatReq);
127 pjSapCb = gCb->u.dlCb->kwuSap;
128 datReq.rlcId.rbId = pjRbCb->rbId;
129 datReq.rlcId.rbType = pjRbCb->rbType;
130 datReq.rlcId.ueId = pjRbCb->ueCb->key.ueId;
131 datReq.rlcId.cellId = pjRbCb->ueCb->key.cellId;
133 datReq.lcType = (U8)((pjRbCb->rbType == CM_LTE_SRB) ?
134 CM_LTE_LCH_DCCH : CM_LTE_LCH_DTCH); /*KW_FIX*/
137 datReq.sduId = sduId;
139 RETVALUE(PjLiKwuDatReq(&(pjSapCb->pst),pjSapCb->spId, &datReq, mBuf));
144 * @brief Handler for Discarding SDU to Rlc.
150 * @param[in] pjRbCb PDCP control block.
151 * @param[in] sduId PDCP SDU id.
160 PUBLIC S16 pjDlmSendDiscSdu
167 PUBLIC S16 pjDlmSendDiscSdu(gCb,pjRbCb,sduId)
173 KwuDiscSduInfo *discSdu;
175 TRC2(pjDlmSendDiscSdu);
177 pjSapCb = gCb->u.dlCb->kwuSap;
178 KwuDiscSduInfo discSduTmp;
179 discSdu = &discSduTmp;
181 discSdu->rlcId.rbId = pjRbCb->rbId;
182 discSdu->rlcId.rbType = pjRbCb->rbType;
183 discSdu->rlcId.ueId = pjRbCb->ueCb->key.ueId;
184 discSdu->rlcId.cellId = pjRbCb->ueCb->key.cellId;
186 discSdu->sduIds[0] = sduId;
187 discSdu->numSduIds = 1;
189 PjLiKwuDiscSduReq(&(pjSapCb->pst),pjSapCb->spId, discSdu);
196 /*****************************************************************************
197 * PDCP LOWER INTERFACE
198 ****************************************************************************/
203 * Handler for getting the BndCfm from RLC.
207 * This function receives the PDU from RLC
208 * and invokes the handler for processing the PDU.
210 * @param[in] pjRbCb - PDCP RB Control Block
211 * @param[in] mBuf - PDU
219 PUBLIC S16 PjLiKwuBndCfm
222 SuId suId, /* Service User Id */
223 U8 status /* Status */
226 PUBLIC Void PjLiKwuBndCfm (pst, suId, datCfm)
228 SuId suId; /* Service User Id */
229 U8 status; /* Status */
232 U16 event; /* Event */
233 U16 cause; /* Cause */
234 PjKwuSapCb *kwuSap; /* RGU SAP Control Block */
239 if (pst->dstInst >= PJ_MAX_PDCP_INSTANCES) /* KW_FIX */
243 tPjCb = PJ_GET_PJCB(pst->dstInst);
245 RLOG2(L_DEBUG, "PjLiKwuBndCfm(SuId (%d), status (%d) ",suId, status);
248 #if (ERRCLASS & ERRCLS_INT_PAR)
249 if (!(tPjCb->init.cfgDone & PJ_LMM_GENCFG_DONE))
251 /* INNC: ERROR CLASS */
252 RLOG0(L_FATAL, "General configuration not done");
253 /*PJ_SEND_SAPID_ALARM(tPjCb,suId, LPJ_EVENT_LI_BND_CFM, LPJ_CAUSE_INV_STATE);*/
260 /* INNC: ERROR CLASS */
261 RLOG0(L_ERROR, "Invalid suId");
262 /*PJ_SEND_SAPID_ALARM(tPjCb,suId, LPJ_EVENT_LI_BND_CFM, LPJ_CAUSE_INV_SUID);*/
266 #endif /* ERRCLASS & ERRCLS_INT_PAR */
268 if (tPjCb->pjGenCfg.mode == LPJ_MODE_PDCP_UL)
270 kwuSap = tPjCb->u.ulCb->kwuSap;
274 kwuSap = tPjCb->u.dlCb->kwuSap;
278 RLOG1(L_DEBUG, "PjLiKwuBndCfm: For KWU SAP state=%d",
282 /* Check rguSap state */
283 switch (kwuSap->state)
287 pjStopTmr (tPjCb, (PTR)kwuSap, PJ_EVT_WAIT_KWU_BNDCFM);
289 kwuSap->retryCnt = 0;
291 if (status == CM_BND_OK)
293 kwuSap->state = PJ_SAP_BND;
294 event = LCM_EVENT_BND_OK;
295 cause = LPJ_CAUSE_SAP_BNDENB;
299 kwuSap->state = PJ_SAP_CFG;
300 event = LCM_EVENT_BND_FAIL;
301 cause = LPJ_CAUSE_UNKNOWN;
306 event = LPJ_EVENT_RGU_BND_CFM;
307 cause = LCM_CAUSE_INV_STATE;
311 /* Send an alarm with proper event and cause */
312 /* PJ_SEND_SAPID_ALARM(tPjCb, suId, event, cause);*/
314 pjLmmSendAlarm(tPjCb,LCM_CATEGORY_INTERFACE, event, cause, suId, 0,0);
316 pjLmmSendAlarm(tPjCb,LCM_CATEGORY_INTERFACE, event, cause, suId, 0);
326 * Handler for getting the PDU from RLC.
330 * This function receives the PDU from RLC
331 * and invokes the handler for processing the PDU.
333 * @param[in] pjRbCb - PDCP RB Control Block
334 * @param[in] mBuf - PDU
342 PUBLIC S16 PjLiKwuDatInd
345 SuId suId, /* Service User Id */
346 KwuDatIndInfo *datInd, /* Data Indication Info */
347 Buffer *mBuf /* Buffer */
350 PUBLIC Void PjLiKwuDatInd(pst, suId, datInd, mBuf)
352 SuId suId; /* Service User Id */
353 KwuDatIndInfo *datInd; /* Data Indication Info */
354 Buffer *mBuf; /* Buffer */
357 S16 ret; /* Return Value */
363 if (pst->dstInst >= PJ_MAX_PDCP_INSTANCES) /* KW_FIX*/
367 tPjCb = PJ_GET_PJCB(pst->dstInst);
369 ret = pjDbmFetchUlRbCb (tPjCb,datInd->rlcId,&pjRbCb);
372 RLOG_ARG2(L_ERROR, DBG_UEID,datInd->rlcId.ueId, "CellId[%u]:UL RbId[%d] not found",
373 datInd->rlcId.cellId, datInd->rlcId.rbId);
378 pjLimDatInd(tPjCb, pjRbCb, mBuf, datInd->isOutOfSeq);
384 PUBLIC int pdcpDatCfmsReceived = 0;
389 * Handler for getting the datCfm from RLC.
393 * This function receives the PDU from RLC
394 * and invokes the handler for processing the PDU.
396 * @param[in] pjRbCb - PDCP RB Control Block
397 * @param[in] mBuf - PDU
405 PUBLIC S16 PjLiKwuDatCfm
408 SuId suId, /* Service User Id */
409 KwuDatCfmInfo *datCfm /* Data Confirm Info */
412 PUBLIC Void PjLiKwuDatCfm(pst, suId, datCfm)
414 SuId suId; /* Service User Id */
415 KwuDatCfmInfo *datCfm; /* Data Confirm Info */
418 S16 ret; /* Return Value */
425 if (pst->dstInst >= PJ_MAX_PDCP_INSTANCES) /* KW_FIX */
430 tPjCb = PJ_GET_PJCB(pst->dstInst);
432 RLOG2(L_DEBUG, "PjLiKwuDatCfm(rbId(%d),rbType (%d), mBuf)",
433 datCfm->rlcId.rbId,datCfm->rlcId.rbType);
435 ret = pjDbmFetchDlRbCb (tPjCb,datCfm->rlcId,&pjRbCb);
438 RLOG_ARG2(L_ERROR, DBG_UEID,datCfm->rlcId.ueId, "CellId[%u]:DL RbId[%d] not found",
439 datCfm->rlcId.cellId, datCfm->rlcId.rbId);
440 PJ_FREE_SHRABL_BUF_PST(pst->region, pst->pool, datCfm, sizeof(KwuDatCfmInfo));
444 pdcpDatCfmsReceived++;
446 pjCfm.rlcId = datCfm->rlcId;
447 pjCfm.numSdu = (U16)(datCfm->numSduIds); /*KW_FIX*/
448 cmMemcpy((U8*)pjCfm.sduId, (U8*)datCfm->sduIds, sizeof(U32)*datCfm->numSduIds);
449 pjLimDatCfm (tPjCb, pjRbCb, &pjCfm);
451 PJ_FREE_SHRABL_BUF_PST(pst->region, pst->pool, datCfm, sizeof(KwuDatCfmInfo));
459 * Handler for flow control indication from RLC.
465 * @param[in] pst - Pointer to post structure
466 * @param[in] suId - Service user Id
467 * @param[in] flowCntrlInfo - Flow control information
475 PUBLIC S16 PjLiKwuFlowCntrlInd
479 KwuFlowCntrlIndInfo *flowCntrlInfo
482 PUBLIC Void PjLiKwuFlowCntrlInd(pst, suId, flowCntrlInfo)
485 KwuFlowCntrlIndInfo *flowCntrlInfo;
492 TRC1(PjLiKwuFlowCntrlInd);
494 if (pst->dstInst >= PJ_MAX_PDCP_INSTANCES)
499 tPjCb = PJ_GET_PJCB(pst->dstInst);
501 RLOG2(L_DEBUG, "PjLiKwuFlowCntrlInd(rbId(%d),rbType (%d), mBuf)",
502 flowCntrlInfo->rlcId.rbId,flowCntrlInfo->rlcId.rbType);
504 ret = pjDbmFetchDlRbCb (tPjCb,flowCntrlInfo->rlcId,&pjRbCb);
507 RLOG_ARG2(L_ERROR, DBG_UEID,flowCntrlInfo->rlcId.ueId, "CellId[%u]:DL RbId[%d] not found",
508 flowCntrlInfo->rlcId.cellId, flowCntrlInfo->rlcId.rbId);
509 PJ_FREE_SHRABL_BUF_PST(pst->region, pst->pool, flowCntrlInfo, sizeof(KwuFlowCntrlIndInfo));
513 /* if RLC is requesting to stop the flow means RB is overloaded */
514 if (flowCntrlInfo->pktAdmitCnt)
516 if (pjRbCb->mode == PJ_DRB_AM)
518 pjRbCb->dropOnlyOne = 1;
519 pjRbCb->pktAdmitCnt= 0;
523 pjRbCb->dropOnlyOne = 0;
524 pjRbCb->pktAdmitCnt = flowCntrlInfo->pktAdmitCnt;
529 /* flowCntrlInfo->pktAdmitCnt = 0 indicates PDB Recovered and no FC required
531 pjRbCb->dropOnlyOne = 0;
532 pjRbCb->pktAdmitCnt = 0;
536 PJ_FREE_SHRABL_BUF_PST(pst->region, pst->pool, flowCntrlInfo, sizeof(KwuFlowCntrlIndInfo));
538 } /* PjLiKwuFlowCntrlInd */
543 * Handler for getting the Status Ind from RLC.
547 * This function receives the PDU from RLC
548 * and invokes the handler for processing the PDU.
550 * @param[in] pjRbCb - PDCP RB Control Block
551 * @param[in] mBuf - PDU
559 PUBLIC S16 PjLiKwuStaInd
562 SuId suId, /* Service User Id */
563 KwuStaIndInfo *staInd /* StatusIndication Info */
566 PUBLIC Void PjLiKwuStaInd(pst, suId, datCfm)
568 SuId suId; /* Service User Id */
569 KwuStaIndInfo *staInd; /* Status Indication Info */
572 S16 ret; /* Return Value */
579 tPjCb = PJ_GET_PJCB(pst->dstInst);
580 if ((pst->dstInst >= PJ_MAX_PDCP_INSTANCES) || (tPjCb->init.cfgDone == FALSE))
582 PJ_FREE_SHRABL_BUF_PST(pst->region, pst->pool, staInd, sizeof(KwuStaIndInfo));
587 RLOG2(L_DEBUG, "PjLiKwuStaInd(rbId(%d),rbType (%d), mBuf)",
588 staInd->rlcId.rbId,staInd->rlcId.rbType);
590 ret = pjDbmFetchDlRbCb (tPjCb,staInd->rlcId,&pjRbCb);
593 RLOG_ARG2(L_ERROR, DBG_UEID,staInd->rlcId.ueId, "CellId[%u]:DL RbId[%d] not found",
594 staInd->rlcId.cellId, staInd->rlcId.rbId);
595 /* To confirm :: BRDCM team */
596 PJ_FREE_SHRABL_BUF_PST(pst->region, pst->pool, staInd, sizeof(KwuStaIndInfo));
599 minSduCnt = (KWU_MAX_STA_IND_SDU < PJ_MAX_DAT_CFM)?KWU_MAX_STA_IND_SDU:PJ_MAX_DAT_CFM;
600 if(staInd->numSdu > minSduCnt)
602 staInd->numSdu = (U16)minSduCnt; /*KW_FIX*/
603 RLOG_ARG2(L_ERROR, DBG_RBID , pjRbCb->rbId , "numSdu [%u] in StaInd is more than acceptable limit [%lu]",
604 staInd->numSdu , minSduCnt);
606 pjLimStaInd(tPjCb, pjRbCb, (PjDatCfm *) staInd);
607 /* To confirm :: BRDCM team */
608 PJ_FREE_SHRABL_BUF_PST(pst->region, pst->pool, staInd, sizeof(KwuStaIndInfo));
610 } /* pjLimKwuStaInd */
618 * Handler for getting the ReEstablish Ind from RLC.
622 * This function receives the PDU from RLC
623 * and invokes the handler for processing the PDU.
625 * @param[in] pjRbCb - PDCP RB Control Block
626 * @param[in] mBuf - PDU
634 PUBLIC S16 PjLiKwuReEstCmpInd
637 SuId suId, /* Service User Id */
638 CmLteRlcId rlcId /* RlcId */
641 PUBLIC Void PjLiKwuReEstCmpInd(pst, suId, rlcId)
643 SuId suId; /* Service User Id */
644 CmLteRlcId rlcId; /* RlcId */
647 S16 ret; /* Return Value */
651 TRC1(PjLiKwuReEstCmpInd);
653 tPjCb = PJ_GET_PJCB(pst->dstInst);
654 if ((pst->dstInst >= PJ_MAX_PDCP_INSTANCES) || (tPjCb->init.cfgDone == FALSE))
660 RLOG2(L_DEBUG, "PjLiKwuReEstCmpInd(rbId(%d),rbType (%d), mBuf)",
661 rlcId.rbId,rlcId.rbType);
663 ret = pjDbmFetchUlRbCb (tPjCb,rlcId,&ulRbCb);
666 RLOG_ARG2(L_ERROR, DBG_UEID,rlcId.ueId, "CellId[%u]:UL RbId[%d] not found",
667 rlcId.cellId, rlcId.rbId);
670 pjUlmReEstCmpInd(tPjCb,ulRbCb);
680 * Handler for getting the Ack Ind from RLC.
684 * This function receives the PDU from RLC
685 * and invokes the handler for processing the PDU.
687 * @param[in] pjRbCb - PDCP RB Control Block
688 * @param[in] mBuf - PDU
696 PUBLIC S16 PjLiKwuDatAckInd
699 SuId suId, /* Service User Id */
700 KwuDatAckInfo *ackInfo /* Data Ack Info */
703 PUBLIC Void PjLiKwuDatAckInd(pst, suId, datCfm)
705 SuId suId; /* Service User Id */
706 KwuDatAckInfo *ackInfo; /* Data Ack Info */
717 * Handler for getting the DiscSdu Cfm from RLC.
721 * This function receives the PDU from RLC
722 * and invokes the handler for processing the PDU.
724 * @param[in] pjRbCb - PDCP RB Control Block
725 * @param[in] mBuf - PDU
733 PUBLIC S16 PjLiKwuDiscSduCfm
736 SuId suId, /* Service User Id */
737 KwuDiscSduInfo *discInfo /* Data Ack Info */
740 PUBLIC Void PjLiKwuDiscSduCfm(pst, suId, discInfo)
742 SuId suId; /* Service User Id */
743 KwuDiscSduInfo *discInfo; /* Data Ack Info */
746 S16 ret; /* Return Value */
750 TRC1(PjLiKwuDiscSduCfm);
751 tPjCb = PJ_GET_PJCB(pst->dstInst);
754 RLOG2(L_DEBUG, "PjLiKwuDiscSduCfm (rbId(%d),rbType (%d), mBuf)",
755 discInfo->rlcId.rbId,discInfo->rlcId.rbType);
757 ret = pjDbmFetchDlRbCb (tPjCb,discInfo->rlcId,&pjRbCb);
760 RLOG_ARG2(L_ERROR, DBG_UEID,discInfo->rlcId.ueId, "CellId[%u]:DL RbId[%d] not found",
761 discInfo->rlcId.cellId, discInfo->rlcId.rbId);
762 PJ_FREE_SHRABL_BUF_PST(pst->region, pst->pool, discInfo, sizeof(KwuDiscSduInfo));
766 pjLimDiscSduCfm(tPjCb, pjRbCb, discInfo);
768 PJ_FREE_SHRABL_BUF_PST(pst->region, pst->pool, discInfo, sizeof(KwuDiscSduInfo));
777 * Handler for getting the PDU from RLC.
781 * This function receives the PDU from RLC
782 * and invokes the handler for processing the PDU.
784 * @param[in] pjRbCb - PDCP RB Control Block
785 * @param[in] mBuf - PDU
793 PUBLIC Void pjLimDatInd
796 PjUlRbCb *pjRbCb, /* RB Control Block */
797 Buffer *mBuf, /* RLC PDU */
801 PUBLIC Void pjLimDatInd(gCb, pjRbCb, mBuf, isOutOfSeq)
803 PjUlRbCb *pjRbCb; /* RB Control Block */
804 Buffer *mBuf; /* RLC PDU */
808 #if (ERRCLASS & ERRCLS_DEBUG)
809 S16 ret; /* Return Value */
814 PJ_STS_INC_GEN_CNT(gCb, rxPdus);
816 /* Extract the header */
817 if(pjRbCb->rbType == PJ_SRB)
819 if((pjRbCb->rbId == 1) || (pjRbCb->ueCb->libInfo.state == PJ_STATE_NORMAL))
821 #if (ERRCLASS & ERRCLS_DEBUG)
822 ret = pjUlmHdlSrbPkt(gCb, pjRbCb, mBuf);
824 pjUlmHdlSrbPkt(gCb, pjRbCb, mBuf);
829 /* in reestablishment state */
833 else if(pjRbCb->rbType == PJ_DRB)
835 #if (ERRCLASS & ERRCLS_DEBUG)
836 ret = pjUlmHdlDrbPkt(gCb, pjRbCb, mBuf, isOutOfSeq);
838 pjUlmHdlDrbPkt(gCb, pjRbCb, mBuf, isOutOfSeq);
842 #if (ERRCLASS & ERRCLS_DEBUG)
845 RLOG_ARG0(L_ERROR, DBG_RBID,pjRbCb->rbId, "pjLimDatInd: pjHdlProcessPdu Failed");
857 * Handler for getting the Data Cfm from RLC.
861 * This function receives the Data Cfm from RLC
862 * and invokes the handler for processing it.
864 * @param[in] pjRbCb - PDCP RB Control Block
865 * @param[in] datCfm - Data Confirmation Information
873 PUBLIC Void pjLimDatCfm
876 PjDlRbCb *pjRbCb, /* RB Control Block */
877 PjDatCfm *datCfm /* Data Confirmation Information */
880 PUBLIC Void pjLimDatCfm(gCb, pjRbCb, datCfm)
882 PjDlRbCb *pjRbCb; /* RB Control Block */
883 PjDatCfm *datCfm; /* Data Confirmation Information */
886 #if (ERRCLASS & ERRCLS_DEBUG)
887 S16 ret = ROK; /* Return Value */
893 /* Process the PDU */
894 #if (ERRCLASS & ERRCLS_DEBUG)
895 ret = pjDlmProcessCfm(gCb, pjRbCb, datCfm, PJ_CFM_OK);
898 RLOG_ARG0(L_ERROR, DBG_RBID,pjRbCb->rbId, "pjLimDatCfm: pjDlmProcessCfm Failed");
901 pjDlmProcessCfm(gCb, pjRbCb, datCfm, PJ_CFM_OK);
903 /* pj002.201 : Removed freeing and allocation of datCfm */
912 * Handler for trigerring the error indication when RLC times out
913 * for sending AM data.
917 * This function receives the pduIds of the PDU that were not
918 * successfully sent to the layer.
920 * @param[in] pjRbCb - PDCP RB Control Block
921 * @param[in] staInd - Status Indication Information.
929 PUBLIC Void pjLimStaInd
932 PjDlRbCb *pjRbCb, /* PDCP RB Control Block */
933 PjDatCfm *staInd /* Status Indication Information */
936 PUBLIC Void pjLimStaInd(gCb, pjRbCb, staInd)
938 PjDlRbCb *pjRbCb; /* PDCP RB control Block */
939 PjDatCfm *staInd; /* Status Indication Information */
942 #if (ERRCLASS & ERRCLS_DEBUG)
943 S16 ret = ROK; /* Return Value */
948 if (gCb->init.cfgDone == FALSE)
952 RLOG1(L_DEBUG, "pjLimStaInd(pjRbCb(%d), staInd)", pjRbCb->rbId);
954 /* Call the confirm code */
955 #if (ERRCLASS & ERRCLS_DEBUG)
956 ret = pjDlmProcessCfm(gCb, pjRbCb, staInd, PJ_CFM_NOK);
959 RLOG_ARG0(L_ERROR, DBG_RBID,pjRbCb->rbId, "pjLimStaInd: pjDlmProcessCfm Failed");
962 pjDlmProcessCfm(gCb, pjRbCb, staInd, PJ_CFM_NOK);
964 /* pj002.201 : Removed freeing and allocation of staInd */
973 * Handler for informing the PDCP that RLC has successfully discarded
978 * This function receives the pointer to the PDCP control block of the
979 * RB that has finished transmitting its data to PDCP.
981 * @param[in] pjRbCb - PDCP RB Control Block
982 * @param[in] discSduCfm - Info about the discarded SDUs
990 PRIVATE S16 pjLimDiscSduCfm
993 PjDlRbCb *pjRbCb, /* PDCP RB Control Block */
994 KwuDiscSduInfo *discSduCfm /* Info about the discarded SDUs*/
997 PRIVATE S16 pjLimDiscSduCfm(gCb, pjRbCb, count)
999 PjDlRbCb *pjRbCb; /* PDCP RB control Block */
1000 KwuDiscSduInfo *discSduCfm; /* Info about the discarded SDUs*/
1003 PjuDatCfmInfo datCfm; /* DatCfm structure */
1004 CmLtePdcpId pdcpId; /* PDCP ID */
1005 PjTxEnt *txEnt; /* Transmission Entity */
1007 U16 cfmsToUpperLayer = 0; /*KW_FIX*/
1009 TRC3(pjLimDiscSduCfm);
1011 RLOG1(L_DEBUG, "pjLimDiscSduCfm(pjRbCb(%d))", pjRbCb->rbId);
1013 if((gCb->init.cfgDone == FALSE) || (discSduCfm->numSduIds == 0))
1018 while(count < discSduCfm->numSduIds)
1020 txEnt = pjDbmGetTxEnt(gCb, &(pjRbCb->dlCb.txBuf), discSduCfm->sduIds[count]);
1024 if( pjRbCb->dlCb.cfmReqd)
1026 datCfm.cfmSta[cfmsToUpperLayer].sduId = txEnt->sduId;
1027 datCfm.cfmSta[cfmsToUpperLayer++].status = PJU_DISCARD_TMR_EXP;
1030 if( txEnt->pdu == txEnt->sdu )
1035 /* if the PDU being discarded was a one for which confirm was expected
1036 then we need to set the confirm expectation correctly */
1038 if(pjRbCb->dlCb.cfmExp < txEnt->count)
1040 /* need to check if count should be just incremented by one or should the txHfn
1041 also need to be considered */
1042 pjRbCb->dlCb.cfmExp = txEnt->count + 1;
1045 pjDbmDelTxEnt(gCb, &(pjRbCb->dlCb.txBuf), txEnt->count);
1048 PJ_UPD_L2_DLDISC_STS(gCb,pjRbCb);
1055 if(pjRbCb->dlCb.cfmReqd)
1057 PjPjuSapCb *pjuSap; /* PJU SAP */
1059 datCfm.numSdus = cfmsToUpperLayer;
1061 pdcpId.rbId = pjRbCb->rbId;
1062 pdcpId.rbType = pjRbCb->rbType;
1063 pdcpId.ueId = pjRbCb->ueCb->key.ueId;
1064 pdcpId.cellId = pjRbCb->ueCb->key.cellId;
1066 if (pjRbCb->rbType == PJ_SRB)
1068 pjuSap = &(gCb->u.dlCb->pjuSap[PJ_SRB_SAP]);
1072 pjuSap = &(gCb->u.dlCb->pjuSap[PJ_DRB_SAP]);
1075 /* If trace flag is enabled send the trace indication */
1076 if(gCb->init.trc == TRUE)
1078 /* Populate the trace params */
1079 pjLmmSendTrc(gCb, EVTPJUDATCFM, NULLP);
1082 PjUiPjuDatCfm(&pjuSap->pst, pjuSap->suId, &pdcpId, &datCfm);
1087 } /* pjLimDiscSduCfm */
1090 #endif /* __cplusplus */
1092 /********************************************************************30**
1094 **********************************************************************/