JIRA-ID ODUHIGH-275 classification of logs of RLC part -3
[o-du/l2.git] / src / 5gnrrlc / kw_tmm_dl.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 /**********************************************************************
20
21      Name:     LTE-RLC Layer 
22   
23      Type:     C file
24   
25      Desc:     Source code for RLC Transparent mode assembly and
26                reassembly.This file contains following functions
27                 
28                   --rlcTmmQSdu
29                   --rlcTmmSendToMac
30                   --rlcTmmRcvFrmMac
31                   --kwTmmReEstablish 
32
33      File:     kw_tmm_dl.c
34
35 **********************************************************************/
36 /** 
37  * @file kw_tmm_dl.c
38  * @brief RLC Transparent Mode module
39 */
40 \f
41 /* header (.h) include files */
42 #include "common_def.h"
43 #include "lkw.h"           /* LKW defines */
44 #include "ckw.h"           /* CKW defines */
45 #include "kwu.h"           /* KWU defines */
46 #include "rgu.h"           /* RGU defines */
47 #include "kw_env.h"        /* RLC environment options */
48
49 #include "kw.h"            /* RLC defines */
50 #include "kw_err.h"            /* RLC defines */
51 #include "kw_udx.h"
52 #include "kw_dl.h"
53
54 /* extern (.x) include files */
55 #include "lkw.x"           /* LKW */
56 #include "ckw.x"           /* CKW */
57 #include "kwu.x"           /* KWU */
58 #include "rgu.x"           /* RGU */
59
60 #include "kw.x"
61 #include "kw_udx.x"
62 #include "kw_dl.x"
63 #include "rlc_utils.h"
64 #include "rlc_mac_inf.h"
65 #include "rlc_lwr_inf_api.h"
66
67 #define RLC_MODULE (RLC_DBGMASK_TM | RLC_DBGMASK_DL)
68
69 static Void rlcTmmSendBoSta ARGS((RlcCb *gCb, RlcDlRbCb *rbCb, 
70                                  MsgLen bo, KwuDatReqInfo *datReqInfo));
71 uint32_t rgMacGT ;  
72 /** @addtogroup tmmode */
73 /*@{*/
74
75 /**
76  * @brief 
77  *    Handler to queue the SDU in the SDU queue and update BO and report it to
78  *    the lower layer.
79  *
80  * @details 
81  *    This function is used to queue the received SDU in the SDU queue 
82  *    maintained in the radio bearer control block. After queuing the SDU, BO 
83  *    is updated and is reported to the lower layer. 
84  *            
85  *  @param[in] rbCb         RB control block. 
86  *  @param[in] datReqInfo   Data Request Information.
87  *  @param[in] mBuf         SDU Buffer.
88  *
89  *  @return  S16
90  *      -# ROK 
91  *      -# RFAILED 
92  */
93 Void rlcTmmQSdu
94 (
95 RlcCb            *gCb,
96 RlcDlRbCb        *rbCb,      
97 KwuDatReqInfo   *datReqInfo, 
98 Buffer          *mBuf       
99 )
100 {
101    RlcSdu   *sdu;              
102  
103    RLC_ALLOC(gCb,sdu,sizeof(RlcSdu));
104 #if (ERRCLASS & ERRCLS_ADD_RES)
105    if ( sdu == NULLP )
106    {
107       RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId,
108             "Memory Allocation failed UEID:%d CELLID:%d",   
109             rbCb->rlcId.ueId,
110             rbCb->rlcId.cellId);   
111       return;
112    }
113 #endif /* ERRCLASS & ERRCLS_ADD_RES */
114 #ifdef CCPU_OPT   
115    if ( rbCb->lch.lChType == CM_LTE_LCH_BCCH || 
116         rbCb->lch.lChType == CM_LTE_LCH_PCCH )
117    {
118       sdu->mode.tm.sfn = datReqInfo->tm.tmg.sfn;
119       sdu->mode.tm.slot = datReqInfo->tm.tmg.slot;
120 #ifdef EMTC_ENABLE
121      if(rbCb->lch.lChType == CM_LTE_LCH_PCCH)
122      {
123         sdu->mode.tm.pnb = datReqInfo->pnb;
124      }
125 #endif
126    }
127    else
128    {
129       sdu->mode.tm.rnti = datReqInfo->tm.rnti;
130    }
131 #endif
132    sdu->arrTime = rgMacGT;
133    SFndLenMsg(mBuf,&sdu->sduSz); 
134    sdu->mBuf = mBuf;
135    
136    cmLListAdd2Tail(&(rbCb->m.tm.sduQ), &(sdu->lstEnt));  
137    sdu->lstEnt.node = (PTR)sdu; 
138
139    rlcTmmSendBoSta(gCb, rbCb, sdu->sduSz, datReqInfo); 
140    return;
141 }
142
143 /**
144 * @brief 
145 *    Handler to form a pdu and send it to the lower layer.
146
147 * @details 
148 *    This function forms one pdu from the first SDU in the SDU queue and sends 
149 *    it to the lower layer.
150 *             
151 * @param[in] gCb     RLC Instance Control Block
152 * @param[in] rbCb    RB control block. 
153 * @param[in] staInd  Status Indication of common logical channel 
154 *
155 * @return  S16
156 *    -# ROK 
157 *    -# RFAILED         
158 */
159 void rlcTmmSendToMac(RlcCb *gCb, SuId suId, RlcDlRbCb *rbCb, RguCStaIndInfo *staInd)
160 {
161    Pst              pst;
162    CmLList          *node;          /* Current Link List Node */
163    RlcSdu           *sdu;           /* SDU */
164    RlcData          *dlData;
165    uint16_t         pduLen;
166    uint16_t         copyLen;
167    int16_t          timeDiff = 0;
168    Ticks            curTime  = 0;
169
170    CM_LLIST_FIRST_NODE(&(rbCb->m.tm.sduQ), 
171                        node);
172
173    /* (Sfn,slot) at which the message should be transmitted is 
174     * validated with alloted (sfn,slot)in the MAC layer */
175    while (node != NULLP)
176    {
177       sdu = (RlcSdu *)(node->node);
178       if ( rbCb->lch.lChType == CM_LTE_LCH_BCCH ||
179             rbCb->lch.lChType == CM_LTE_LCH_PCCH )
180       {
181          uint16_t sfn, slot;
182          /* MS_FIX: syed sfn is of 10 bytes rather than 8 */
183 #ifdef EMTC_ENABLE
184          /* As part of CATM feature cross slot scheduling is implemented , so there is some delta(currently 2)
185             between MPDCCH and PDSCH,RLC expects cell crntTime of transmission of control dlsf, so one extra 
186             information is provided in staInd, so that sfn,slot should calculate from paging Timing information 
187             in case of EMTC paging, instead of transId */
188          if(staInd->isEmtcPaging)
189          {
190             sfn      = staInd->pagingTimingInfo.sfn;
191             slot = staInd->pagingTimingInfo.slot;
192          }
193          else
194 #endif
195          {
196             sfn = (staInd->transId >> 8) & 0x3FF;
197             slot = staInd->transId & 0xFF;
198          }
199
200          /* Table
201           * tm.slot - current slot 
202           * 0,sfn        7,sfn-1
203           * 4,sfn        1,sfn
204           * 5,sfn        2,sfn
205           * 9,sfn        6,sfn
206           */
207          /* MS_FIX: syed Incorrect sfn determination. 
208           * Take care of SFN wraparound. TODO: It is better for RLC
209           * not to be aware of SCH DELTAs. So we should look for 
210           * sending actual transmission time to RLC. */
211          if ((slot + TFU_DELTA) >= 10)
212          {
213             sfn = (sfn + 1)%1024;
214          }
215
216          if ((sdu->mode.tm.sfn != sfn) ||
217                (sdu->mode.tm.slot != ((slot+TFU_DELTA)%10)))
218          {
219             node = node->next;
220             DU_LOG("\nRLC: rlcTmmSendToMac: Releasing SDU of RNTI = %d for RNTI = %d \
221                UEID:%d CELLID:%d", sdu->mode.tm.rnti, staInd->rnti, rbCb->rlcId.ueId,
222                rbCb->rlcId.cellId);   
223             DU_LOG("\nRLC: rlcTmmSendToMac: sfn %d slot %d  UEID:%d CELLID:%d",
224                   sfn, slot, rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
225             cmLListDelFrm(&(rbCb->m.tm.sduQ), &sdu->lstEnt);
226             ODU_PUT_MSG_BUF(sdu->mBuf);
227             RLC_FREE(gCb, sdu, sizeof(RlcSdu));
228          }
229          else
230          {
231             break;
232          }
233       }
234       else
235       {
236          curTime = rgMacGT;
237          if (curTime < sdu->arrTime)
238          {
239             timeDiff = (10240 - sdu->arrTime) + curTime;
240          }
241          else
242          {
243             timeDiff = curTime - sdu->arrTime;
244          }
245          DU_LOG("\nRLC: rlcTmmSendToMac: TMM: TmSdu Sta Indication received \
246             for Rnti %d Sdu Rnti %d UEID:%d CELLID:%d", staInd->rnti, 
247             sdu->mode.tm.rnti, rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
248          DU_LOG("\nRLC: rlcTmmSendToMac: TMM: TmSdu Sta Indication received : \
249             timeDiff %d SduQCnt %d UEID:%d CELLID:%d", timeDiff, rbCb->m.tm.sduQ.count,
250             rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
251          if (timeDiff > 40)
252          {
253             /* Memory leak needs to be fixed */
254             node = node->next;
255             DU_LOG("\nRLC: rlcTmmSendToMac: timeDiff greater than 40, so deleting\
256                the Sdu %u UEID:%d CELLID:%d", sdu->mode.tm.rnti, rbCb->rlcId.ueId,
257                rbCb->rlcId.cellId);   
258             cmLListDelFrm(&(rbCb->m.tm.sduQ), &sdu->lstEnt);
259             ODU_PUT_MSG_BUF(sdu->mBuf);
260             RLC_FREE(gCb, sdu, sizeof(RlcSdu));
261             continue;
262          }
263
264          if (sdu->mode.tm.rnti != staInd->rnti)
265          {
266             /* Memory leak needs to be fixed */
267             node = node->next;
268             DU_LOG("\nRLC: rlcTmmSendToMac: TMM: Searching for Rnti %d Skipping \
269                Sdu for Rnti %d UEID:%d CELLID:%d", staInd->rnti, sdu->mode.tm.rnti, 
270                rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
271             DU_LOG("\nRLC: rlcTmmSendToMac: timeDiff %d sdu->arrTime %d UEID:%d CELLID:%d", 
272                 timeDiff, sdu->arrTime, rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
273             DU_LOG("\nRLC: rlcTmmSendToMac: curTime %d SduQCnt %d and continuing"
274                " UEID:%d CELLID:%d", curTime, rbCb->m.tm.sduQ.count, rbCb->rlcId.ueId,
275                rbCb->rlcId.cellId);   
276             continue;
277          }
278          else
279          {
280             DU_LOG("\nRLC: rlcTmmSendToMac: TMM: TmSdu found %u UEID:%d CELLID:%d",
281                sdu->mode.tm.rnti, rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
282             break;
283          }
284       }
285
286    }
287    if ( node == NULLP )
288    {
289       DU_LOG("\nRLC: rlcTmmSendToMac: SDU not found TM Queue is empty UEID:%d CELLID:%d",
290          rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
291       return;
292    }
293    sdu = (RlcSdu *)node->node;
294
295     RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
296                         dlData,(Size)sizeof(RlcData));
297 #if (ERRCLASS & ERRCLS_ADD_RES)
298    if ( dlData == NULLP )
299    {
300       DU_LOG("\nRLC: rlcTmmSendToMac: Memory Allocation failed UEID:%d CELLID:%d",   
301          rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
302       return; 
303    }
304 #endif /* ERRCLASS & ERRCLS_ADD_RES */
305
306    dlData->slotInfo.sfn = sdu->mode.tm.sfn;
307    dlData->slotInfo.slot = sdu->mode.tm.slot;
308    dlData->cellId = rbCb->rlcId.cellId;
309    dlData->rnti = sdu->mode.tm.rnti;
310    dlData->numPdu = 1;
311    dlData->pduInfo[0].commCh = TRUE;
312    dlData->pduInfo[0].lcId = rbCb->lch.lChId;
313
314    /* Copy Message to fixed buffer to send */
315    ODU_GET_MSG_LEN(sdu->mBuf, (MsgLen *)&pduLen);
316    RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
317       dlData->pduInfo[0].pduBuf, pduLen);
318    if (dlData->pduInfo[0].pduBuf == NULLP )
319    {
320       DU_LOG("Memory allocation failed");
321       return;
322    }
323    ODU_COPY_MSG_TO_FIX_BUF(sdu->mBuf, 0, pduLen, \
324       dlData->pduInfo[0].pduBuf, (MsgLen *)&copyLen);
325    dlData->pduInfo[0].pduLen = pduLen;
326
327    /* Free message */
328    ODU_PUT_MSG_BUF(sdu->mBuf);
329
330    /* kw005.201 ccpu00117318, updating the statistics */
331    gCb->genSts.bytesSent += sdu->sduSz;
332    gCb->genSts.pdusSent++;
333
334    rlcUtlIncrementKwuStsSduTx(gCb->u.dlCb->rlcKwuDlSap + rbCb->k1wuSapId);   
335
336    /* remove SDU from queue */ 
337    sdu->mBuf = NULLP;
338    cmLListDelFrm(&(rbCb->m.tm.sduQ),
339                  &sdu->lstEnt); 
340    RLC_FREE(gCb,sdu, sizeof(RlcSdu));
341
342    /* Fill Pst structure. Copying rguSap->pst to pst to avoid any
343     * changes in rguSap->pst */
344    memset(&pst, 0, sizeof(Pst));
345    FILL_PST_RLC_TO_MAC(pst, RLC_DL_INST, EVENT_DL_DATA_TO_MAC);
346
347    if(RlcSendDlDataToMac(&pst, dlData) != ROK)
348    {
349       RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData->pduInfo[0].pduBuf, \
350          dlData->pduInfo[0].pduLen);
351       RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData, sizeof(RlcData));
352    } 
353
354    return;
355 }
356
357 /**
358  *
359  * @brief 
360  *    Handler to process the re-establishment request received from the upper 
361  *    layer. 
362  *
363  * @details
364  *    This function empties the SDU queue for the RB in the downlink.
365  *            
366  * @param[in] gCb   RLC Instance Control Block 
367  * @param[in] rbCb  RB control block. 
368  *
369  * @return  S16
370  *    -# ROK 
371  */
372 Void rlcDlTmmReEstablish
373 (
374 RlcCb       *gCb,
375 RlcDlRbCb   *rbCb    
376 )
377 {
378
379 #ifdef LTE_L2_MEAS_RLC
380    rlcUtlEmptySduQ(gCb, rbCb, &rbCb->m.tm.sduQ);
381 #else
382    rlcUtlEmptySduQ(gCb,&rbCb->m.tm.sduQ);
383 #endif
384    
385    return;
386 }
387 /**
388  *
389  * @brief 
390  *    Handler to send Status Response to the lower layer.
391  *
392  * @details
393  *    This function is used to the BO to the lower layer after receiving a data
394  *    request from the upper layer. 
395  *            
396  * @param[in] gCb          RLC Instance Control Block 
397  * @param[in] rbCb         RB control block. 
398  * @param[in] bo           Buffer Occupancy 
399  * @param[in] datReqInfo   Data Request Information.
400  *
401  * @return  S16
402  *    -# ROK 
403  *    -# RFAILED 
404  */
405
406 static void rlcTmmSendBoSta(RlcCb *gCb, RlcDlRbCb *rbCb, MsgLen bo, KwuDatReqInfo *datReqInfo)
407 {
408    Pst              pst;            /* Post structure */    
409    RlcBoStatus      *boStatus;      /* Buffer occupancy status information */
410
411    RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
412                        boStatus, sizeof(RlcBoStatus));
413    if ( boStatus == NULLP )
414    {
415       DU_LOG("Memory Allocation failed UEID:%d CELLID:%d",\
416             rbCb->rlcId.ueId, rbCb->rlcId.cellId);   
417       return;
418    }
419
420    boStatus->cellId = rbCb->rlcId.cellId;
421    boStatus->ueIdx = rbCb->rlcId.ueId;
422    boStatus->commCh = TRUE;
423    boStatus->lcId = rbCb->lch.lChId;
424    boStatus->bo = bo;
425
426    /* If trace flag is enabled send the trace indication */
427    if(gCb->init.trc == TRUE)
428    {
429       /* Populate the trace params */
430       rlcLmmSendTrc(gCb, EVENT_BO_STATUS_TO_MAC, NULLP);
431    }
432
433    /* Fill Pst structure. Copying rguSap->pst to pst to avoid any
434     * changes in rguSap->pst */
435    memset(&pst, 0, sizeof(Pst));
436    FILL_PST_RLC_TO_MAC(pst, RLC_DL_INST, EVENT_DL_DATA_TO_MAC);
437
438    if(RlcSendBoStatusToMac(&pst, boStatus) != ROK)
439    {
440       RLC_FREE_SHRABL_BUF(pst.region, pst.pool, boStatus, sizeof(RlcBoStatus));
441    }
442
443    return;
444
445
446 #ifdef _cplusplus
447 }
448 #endif
449 /*@}*/
450 /********************************************************************30**
451          End of file
452 **********************************************************************/