[JIRA ID: ODUHIGH-232]: RB config for MAC and SCH
[o-du/l2.git] / src / 5gnrsch / sch_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 SCH */
19
20 #include "common_def.h"
21 #include "tfu.h"
22 #include "lrg.h"
23
24 #include "tfu.x"
25 #include "lrg.x"
26 #include "du_log.h"
27 #include "du_app_mac_inf.h"
28 #include "mac_sch_interface.h"
29 #include "sch.h"
30 #include "sch_utils.h"
31
32 /* local defines */
33 SchUeCfgRspFunc SchUeCfgRspOpts[] =
34 {
35    packSchUeCfgRsp,      /* LC */
36    MacProcSchUeCfgRsp,   /* TC */
37    packSchUeCfgRsp       /* LWLC */
38 };
39
40
41 /*******************************************************************
42  *
43  * @brief Fill and send UE cfg response to MAC
44  *
45  * @details
46  *
47  *    Function : SchSendUeCfgRspToMac
48  *
49  *    Functionality: Fill and send UE cfg response to MAC
50  *
51  * @params[in] 
52  * @return ROK     - success
53  *         RFAILED - failure
54  *
55  * ****************************************************************/
56 void SchSendUeCfgRspToMac(uint16_t event, SchUeCfg *ueCfg, Inst inst,\
57       SchMacRsp result, SchUeCfgRsp *cfgRsp)
58 {
59    Pst rspPst;
60
61    DU_LOG("\nSCH: Sending UE Create response to MAC");
62
63    cfgRsp->cellId = ueCfg->cellId;
64    cfgRsp->crnti = ueCfg->crnti;
65    GET_UE_IDX(ueCfg->crnti, cfgRsp->ueIdx);
66    cfgRsp->rsp = result;   
67
68    /* Filling response post */
69    memset(&rspPst, 0, sizeof(Pst));
70    FILL_PST_SCH_TO_MAC(rspPst, inst);
71    if(event == EVENT_UE_CREATE_REQ_TO_SCH)
72    {
73       rspPst.event = EVENT_UE_CREATE_RSP_TO_MAC;
74    }
75    else if(event == EVENT_UE_RECONFIG_REQ_TO_SCH)
76    {
77       rspPst.event = EVENT_UE_RECONFIG_RSP_TO_MAC;
78    }
79    SchUeCfgRspOpts[rspPst.selector](&rspPst, cfgRsp);
80 }
81
82 /*******************************************************************
83  *
84  * @brief Function to fill Dl Lc Context in SCH Ue Cb
85  *
86  * @details
87  *
88  *    Function : fillSchDlLcCtxt
89  *
90  *    Functionality: Function to fill Dl Lc Context in SCH Ue Cb
91  *
92  * @params[in] SchDlLcCtxt pointer,
93  *             SchLcCfg pointer
94  * @return void
95  *
96  * ****************************************************************/
97
98 void fillSchDlLcCtxt(SchDlLcCtxt *ueCbLcCfg, SchLcCfg *lcCfg)
99 {
100    ueCbLcCfg->lcId = lcCfg->lcId;
101    ueCbLcCfg->lcp = lcCfg->dlLcCfg.lcp;
102    ueCbLcCfg->lcState = SCH_LC_STATE_ACTIVE;
103    ueCbLcCfg->bo = 0;
104 }
105
106 /*******************************************************************
107  *
108  * @brief Function to fill Ul Lc Context in SCH Ue Cb
109  *
110  * @details
111  *
112  *    Function : fillSchUlLcCtxt
113  *
114  *    Functionality: Function to fill Ul Lc Context in SCH Ue Cb
115  *
116  * @params[in] SchUlLcCtxt pointer,
117  *             SchLcCfg pointer
118  * @return void
119  *
120  * ****************************************************************/
121
122 void fillSchUlLcCtxt(SchUlLcCtxt *ueCbLcCfg, SchLcCfg *lcCfg)
123 {
124    ueCbLcCfg->lcId = lcCfg->lcId;
125    ueCbLcCfg->lcState = SCH_LC_STATE_ACTIVE;
126    ueCbLcCfg->priority = lcCfg->ulLcCfg.priority;
127    ueCbLcCfg->lcGroup = lcCfg->ulLcCfg.lcGroup;
128    ueCbLcCfg->schReqId = lcCfg->ulLcCfg.schReqId;
129    ueCbLcCfg->pbr     = lcCfg->ulLcCfg.pbr;
130    ueCbLcCfg->bsd     = lcCfg->ulLcCfg.bsd;
131
132 }
133
134 /*******************************************************************
135  *
136  * @brief Function to update Sch Ul Lc Cb
137  *
138  * @details
139  *
140  *    Function : updateSchUlCb
141  *
142  *    Functionality: Function to update SCH Ul Lc Cb
143  *
144  * @returns void
145  *
146  * ****************************************************************/
147
148 void updateSchUlCb(uint8_t delIdx, SchUlCb *ulInfo)
149 {
150    uint8_t lcIdx = 0;
151
152    for(lcIdx = delIdx; lcIdx < ulInfo->numUlLc; lcIdx++)
153    {
154       memcpy(&ulInfo->ulLcCtxt[lcIdx], &ulInfo->ulLcCtxt[lcIdx+1], sizeof(SchUlLcCtxt));
155       memset(&ulInfo->ulLcCtxt[lcIdx+1], 0, sizeof(SchUlLcCtxt));
156    }
157 }
158
159 /*******************************************************************
160  *
161  * @brief Function to update SCH Dl Lc Cb
162  *
163  * @details
164  *
165  *    Function : updateSchDlCb
166  *
167  *    Functionality: Function to update SCH DL Lc Cb
168  *
169  * @returns void
170  *
171  * ****************************************************************/
172
173 void updateSchDlCb(uint8_t delIdx, SchDlCb *dlInfo)
174 {
175    uint8_t lcIdx = 0;
176
177    for(lcIdx = delIdx; lcIdx < dlInfo->numDlLc; lcIdx++)
178    {
179       memcpy(&dlInfo->dlLcCtxt[lcIdx], &dlInfo->dlLcCtxt[lcIdx+1], sizeof(SchDlLcCtxt));
180       memset(&dlInfo->dlLcCtxt[lcIdx+1], 0, sizeof(SchDlLcCtxt));
181    }
182 }
183
184 /*******************************************************************
185  *
186  * @brief Function to fill SchUeCb
187  *
188  * @details
189  *
190  *    Function : fillSchUeCb
191  *
192  *    Functionality: Function to fill SchUeCb
193  *
194  * @params[in] SchUeCb pointer,
195  *             SchUeCfg pointer
196  * @return ROK/RFAILED
197  *
198  * ****************************************************************/
199
200 uint8_t fillSchUeCb(SchUeCb *ueCb, SchUeCfg *ueCfg)
201 {
202    uint8_t   lcIdx, ueLcIdx;
203
204    memset(&ueCb->ueCfg, 0, sizeof(SchUeCfg));
205    memcpy(&ueCb->ueCfg, ueCfg, sizeof(SchUeCfg));
206    ueCb->state = SCH_UE_STATE_ACTIVE;
207
208    for(lcIdx = 0; lcIdx < ueCfg->numLcs; lcIdx++)
209    {
210       if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_ADD)
211       {
212          fillSchUlLcCtxt(&ueCb->ulInfo.ulLcCtxt[ueCb->ulInfo.numUlLc], &ueCfg->schLcCfg[lcIdx]);
213          ueCb->ulInfo.numUlLc++;
214          fillSchDlLcCtxt(&ueCb->dlInfo.dlLcCtxt[ueCb->dlInfo.numDlLc], &ueCfg->schLcCfg[lcIdx]);
215          ueCb->dlInfo.numDlLc++;
216       }
217       else
218       {
219          for(ueLcIdx = 0; ueLcIdx < ueCb->ulInfo.numUlLc; ueLcIdx++) //searching for Lc to be Mod
220          {
221             if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].lcId == ueCfg->schLcCfg[lcIdx].lcId)
222             {
223                if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_MOD)
224                {
225                   fillSchUlLcCtxt(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], &ueCfg->schLcCfg[lcIdx]);
226                   fillSchDlLcCtxt(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], &ueCfg->schLcCfg[lcIdx]);
227                   break;
228                }
229                if(ueCfg->schLcCfg[ueLcIdx].configType == CONFIG_DEL)
230                {
231                   memset(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], 0, sizeof(SchUlLcCtxt));
232                   ueCb->ulInfo.numUlLc--;
233                   updateSchUlCb(ueLcIdx, &ueCb->ulInfo); //moving arr elements one idx ahead 
234                   memset(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], 0, sizeof(SchDlLcCtxt));
235                   ueCb->dlInfo.numDlLc--;
236                   updateSchDlCb(ueLcIdx, &ueCb->dlInfo); //moving arr elements one idx ahead
237                   break;
238                }
239             }
240          }/*End of inner for loop */
241       }
242    }/* End of outer for loop */
243    return ROK;
244 }
245
246 /*******************************************************************
247  *
248  * @brief Function to get SCH Cell Cb
249  *
250  * @details
251  *
252  *    Function : getSchCellCb
253  *
254  *    Functionality: Function to get SCH Cell Cb
255  *
256  * @params[in] event, SchUeCfg pointer 
257  * @return schUeCb pointer  - success
258  *         NULLP - failure
259  *
260  * ****************************************************************/
261
262 SchCellCb *getSchCellCb(uint16_t srcEvent, Inst inst, SchUeCfg *ueCfg)
263 {
264    uint8_t      idx;
265    SchCellCb    *cellCb = NULLP;
266    SchUeCfgRsp  cfgRsp;
267    memset(&cfgRsp, 0, sizeof(SchUeCfgRsp));
268
269    /* Search of cell cb */
270    for(idx = 0; idx < MAX_NUM_CELL; idx++)
271    {
272       cellCb = schCb[inst].cells[idx];
273       if(cellCb->cellId == ueCfg->cellId)
274          break;
275    }
276    if(idx == MAX_NUM_CELL)
277    {
278       DU_LOG("\nSCH : Ue create request failed. Invalid cell id %d", ueCfg->cellId);
279       SchSendUeCfgRspToMac(srcEvent, ueCfg, inst, RSP_NOK, &cfgRsp);
280       return NULLP;
281    }
282
283    /* Check if max number of UE configured */
284    if(cellCb->numActvUe > MAX_NUM_UE)
285    {
286       DU_LOG("SCH : Max number of UE [%d] already configured", MAX_NUM_UE);
287       SchSendUeCfgRspToMac(srcEvent, ueCfg, inst, RSP_NOK, &cfgRsp);
288       return NULLP;
289    }
290    return cellCb;
291 }
292
293
294 /*******************************************************************
295  *
296  * @brief Hanles Ue create request from MAC
297  *
298  * @details
299  *
300  *    Function : MacSchUeCreateReq
301  *
302  *    Functionality: Hanles Ue create request from MAC
303  *
304  * @params[in] 
305  * @return ROK     - success
306  *         RFAILED - failure
307  *
308  * ****************************************************************/
309 uint8_t MacSchUeCreateReq(Pst *pst, SchUeCfg *ueCfg)
310 {
311    uint8_t ueIdx, lcIdx, ret = ROK;
312    SchCellCb    *cellCb = NULLP;
313    SchUeCb      *ueCb = NULLP;
314    SchUeCfgRsp  cfgRsp;
315    Inst         inst = pst->dstInst - 1;
316    memset(&cfgRsp, 0, sizeof(SchUeCfgRsp));
317
318    if(!ueCfg)
319    {
320       DU_LOG("\nSCH : UE create request failed at MacSchUeCreateReq()");
321       return RFAILED;
322    }
323    DU_LOG("\nSCH : UE Create Request for CRNTI[%d]", ueCfg->crnti);
324    cellCb = getSchCellCb(pst->event, inst, ueCfg);
325
326    /* Search if UE already configured */
327    GET_UE_IDX(ueCfg->crnti, ueIdx);
328    ueCb = &cellCb->ueCb[ueIdx -1];
329    if(ueCb)
330    {
331       if((ueCb->crnti == ueCfg->crnti) && (ueCb->state == SCH_UE_STATE_ACTIVE))
332       {
333          DU_LOG("\n SCH : CRNTI %d already configured ", ueCfg->crnti);
334          SchSendUeCfgRspToMac(pst->event, ueCfg, inst, RSP_OK, &cfgRsp);
335          return ROK;
336       }
337    }
338    else
339    {
340       DU_LOG("\n SCH : SchUeCb not found at MacSchUeCreateReq() ");
341       SchSendUeCfgRspToMac(pst->event, ueCfg, inst, RSP_NOK, &cfgRsp);
342       return RFAILED;
343    }
344
345    /* Fill received Ue Configuration in UeCb */
346    memset(ueCb, 0, sizeof(SchUeCb));
347    GET_UE_IDX(ueCfg->crnti, ueIdx);
348    ueCb->ueIdx = ueIdx;
349    ueCb->crnti = ueCfg->crnti;
350    ueCb->state = SCH_UE_STATE_ACTIVE;
351    ret = fillSchUeCb(ueCb, ueCfg);
352    if(ret == ROK)
353    {
354       cellCb->numActvUe++;
355       SET_ONE_BIT(ueCb->ueIdx, cellCb->actvUeBitMap);
356       ueCb->cellCb = cellCb;
357       ueCb->srRcvd = false;
358       for(lcIdx=0; lcIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcIdx++)
359          ueCb->bsrInfo[lcIdx].dataVol = 0;
360
361       SchSendUeCfgRspToMac(pst->event, ueCfg, inst, RSP_OK, &cfgRsp);
362    }
363    return ret;
364 }
365
366 /*******************************************************************
367 *
368 * @brief Fills PUSCH UL allocation
369 *
370 * @details
371 *
372 *    Function : schFillPuschAlloc
373 *
374 *    Functionality: fills PUSCH info
375 *
376 * @params[in]
377 * @return ROK     - success
378 *         RFAILED - failure
379 *
380 * ****************************************************************/
381 uint8_t schFillPuschAlloc(SchUeCb *ueCb, uint16_t pdcchSlot, uint32_t dataVol, SchPuschInfo *puschInfo)
382 {
383   uint16_t puschSlot      = 0;
384   uint16_t startRb        = 0;
385   uint8_t  numRb          = 0;
386   uint8_t  mcs            = 4;
387   uint8_t  numPdschSymbols= 14;
388   uint16_t tbSize         = 0;
389   uint8_t  buffer         = 5;
390   uint8_t  idx            = 0;
391   SchCellCb *cellCb       = ueCb->cellCb;
392   SchUlSlotInfo *schUlSlotInfo = NULLP;
393   uint8_t  k2 = ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.puschCfg.timeDomRsrcAllocList[0].k2;
394   uint8_t  startSymb = ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.puschCfg.timeDomRsrcAllocList[0].startSymbol;
395   uint8_t  symbLen = ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.puschCfg.timeDomRsrcAllocList[0].symbolLength;
396
397   puschSlot = (pdcchSlot + k2) % SCH_NUM_SLOTS;
398
399   startRb = cellCb->schUlSlotInfo[puschSlot]->puschCurrentPrb;
400   tbSize  = schCalcTbSize(dataVol + buffer); /*  2 bytes header + some buffer */
401   numRb   = schCalcNumPrb(tbSize, mcs, numPdschSymbols);
402   /* increment PUSCH PRB */
403
404   cellCb->schUlSlotInfo[puschSlot]->puschCurrentPrb += numRb;
405
406   puschInfo->crnti             = ueCb->crnti; 
407   puschInfo->harqProcId        = SCH_HARQ_PROC_ID;
408   puschInfo->resAllocType      = SCH_ALLOC_TYPE_1;
409   puschInfo->fdAlloc.startPrb  = startRb;
410   puschInfo->fdAlloc.numPrb    = numRb;
411   puschInfo->tdAlloc.startSymb = startSymb;
412   puschInfo->tdAlloc.numSymb   = symbLen;
413   puschInfo->tbInfo.mcs        = mcs;
414   puschInfo->tbInfo.ndi        = 1; /* new transmission */
415   puschInfo->tbInfo.rv         = 0;
416   puschInfo->tbInfo.tbSize     = tbSize;
417   puschInfo->dmrsMappingType   = DMRS_MAP_TYPE_A;  /* Setting Type-A */
418   puschInfo->nrOfDmrsSymbols   = NUM_DMRS_SYMBOLS;
419   puschInfo->dmrsAddPos        = DMRS_ADDITIONAL_POS;
420
421   /* Update pusch in cell */
422   for(idx=startSymb; idx<symbLen; idx++)
423   {
424      cellCb->schUlSlotInfo[puschSlot]->assignedPrb[idx] = startRb + numRb;
425   }
426
427   schUlSlotInfo = cellCb->schUlSlotInfo[puschSlot];
428
429   SCH_ALLOC(schUlSlotInfo->schPuschInfo, sizeof(SchPuschInfo));
430   if(!schUlSlotInfo->schPuschInfo)
431   {
432      DU_LOG("SCH: Memory allocation failed in schAllocMsg3Pusch");
433      return RFAILED;
434   }
435   memcpy(schUlSlotInfo->schPuschInfo, puschInfo, sizeof(SchPuschInfo));
436
437   return ROK;
438 }
439
440 /*******************************************************************
441  *
442  * @brief Fills DCI for UL grant
443  *
444  * @details
445  *
446  *    Function : schFillUlDci
447  *
448  *    Functionality: fills DCI for UL grant in response to BSR
449  *
450  * @params[in]
451  * @return ROK     - success
452  *         RFAILED - failure
453  *
454  * ****************************************************************/
455 uint8_t schFillUlDci(SchUeCb *ueCb, SchPuschInfo puschInfo, DciInfo *dciInfo)
456 {
457    SchCellCb         *cellCb  = ueCb->cellCb;
458    SchControlRsrcSet coreset1 = ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdcchCfg.cRSetToAddModList[0];
459
460    dciInfo->cellId = cellCb->cellId;
461    dciInfo->crnti  = ueCb->crnti;
462
463    /* fill bwp cfg */
464    dciInfo->bwpCfg.subcarrierSpacing  = cellCb->cellCfg.sib1SchCfg.bwp.subcarrierSpacing;
465    dciInfo->bwpCfg.cyclicPrefix       = cellCb->cellCfg.sib1SchCfg.bwp.cyclicPrefix;
466    dciInfo->bwpCfg.freqAlloc.startPrb = 0;
467    dciInfo->bwpCfg.freqAlloc.numPrb   = MAX_NUM_RB; /* whole of BW */
468
469    /*fill coreset cfg */
470    //Considering number of RBs in coreset1 is same as coreset0
471    dciInfo->coresetCfg.coreSetSize      = coresetIdxTable[0][1];
472    //Considering coreset1 also starts from same symbol as coreset0
473    dciInfo->coresetCfg.startSymbolIndex = searchSpaceIdxTable[0][3];
474    dciInfo->coresetCfg.durationSymbols  = coreset1.duration;
475    memcpy(dciInfo->coresetCfg.freqDomainResource, coreset1.freqDomainRsrc, FREQ_DOM_RSRC_SIZE);
476    
477    dciInfo->coresetCfg.cceRegMappingType   = coreset1.cceRegMappingType; /* non-interleaved */
478    dciInfo->coresetCfg.regBundleSize       = 6; /* must be 6 for non-interleaved */
479    dciInfo->coresetCfg.interleaverSize     = 0; /* NA for non-interleaved */
480    dciInfo->coresetCfg.coreSetType         = 1; /* non PBCH coreset */
481    dciInfo->coresetCfg.shiftIndex          = cellCb->cellCfg.phyCellId;
482    dciInfo->coresetCfg.precoderGranularity = coreset1.precoderGranularity;
483    dciInfo->coresetCfg.cceIndex            = 0; /* 0-3 for UL and 4-7 for DL */
484    dciInfo->coresetCfg.aggregationLevel    = 4; /* same as for sib1 */
485    
486    dciInfo->formatType = FORMAT0_0;
487    
488    /* fill UL grant */
489    dciInfo->format.format0_0.resourceAllocType   = puschInfo.resAllocType;
490    dciInfo->format.format0_0.freqAlloc.startPrb  = puschInfo.fdAlloc.startPrb;
491    dciInfo->format.format0_0.freqAlloc.numPrb    = puschInfo.fdAlloc.numPrb;
492    dciInfo->format.format0_0.timeAlloc.startSymb = puschInfo.tdAlloc.startSymb;
493    dciInfo->format.format0_0.timeAlloc.numSymb   = puschInfo.tdAlloc.numSymb;
494    dciInfo->format.format0_0.rowIndex            = 0; /* row Index */
495    dciInfo->format.format0_0.mcs                 = puschInfo.tbInfo.mcs;
496    dciInfo->format.format0_0.harqProcId          = puschInfo.harqProcId;
497    dciInfo->format.format0_0.puschHopFlag        = FALSE; /* disabled */
498    dciInfo->format.format0_0.freqHopFlag         = FALSE; /* disabled */
499    dciInfo->format.format0_0.ndi                 = puschInfo.tbInfo.ndi; /* new transmission */
500    dciInfo->format.format0_0.rv                  = puschInfo.tbInfo.rv;
501    dciInfo->format.format0_0.tpcCmd              = 0; //Sphoorthi TODO: check
502    dciInfo->format.format0_0.sUlCfgd             = FALSE; /* SUL not configured */
503    
504    /* Fill DCI Structure */
505    dciInfo->dciInfo.rnti                              = ueCb->crnti;
506    dciInfo->dciInfo.scramblingId                      = cellCb->cellCfg.phyCellId;
507    dciInfo->dciInfo.scramblingRnti                    = 0;
508    dciInfo->dciInfo.cceIndex                          = 0; /* 0-3 for UL and 4-7 for DL */
509    dciInfo->dciInfo.aggregLevel                       = 4;
510    dciInfo->dciInfo.beamPdcchInfo.numPrgs             = 1;
511    dciInfo->dciInfo.beamPdcchInfo.prgSize             = 1;
512    dciInfo->dciInfo.beamPdcchInfo.digBfInterfaces     = 0;
513    dciInfo->dciInfo.beamPdcchInfo.prg[0].pmIdx        = 0;
514    dciInfo->dciInfo.beamPdcchInfo.prg[0].beamIdx[0]   = 0;
515    dciInfo->dciInfo.txPdcchPower.powerValue           = 0;
516    dciInfo->dciInfo.txPdcchPower.powerControlOffsetSS = 0;
517    dciInfo->dciInfo.pdschCfg                          = NULLP; /* No DL data being sent */
518
519    return ROK;
520 }
521
522 /*******************************************************************
523  *
524  * @brief Hanles Ue Reconfig request from MAC
525  *
526  * @details
527  *
528  *    Function : MacSchUeReconfigReq
529  *
530  *    Functionality: Hanles Ue Reconfig request from MAC
531  *
532  * @params[in] 
533  * @return ROK     - success
534  *         RFAILED - failure
535  *
536  * ****************************************************************/
537 uint8_t MacSchUeReconfigReq(Pst *pst, SchUeCfg *ueCfg)
538 {
539    uint8_t ueIdx, lcIdx, ret = ROK;
540    SchCellCb    *cellCb = NULLP;
541    SchUeCb      *ueCb = NULLP;
542    SchUeCfgRsp  cfgRsp;
543    Inst         inst = pst->dstInst - 1;
544    memset(&cfgRsp, 0, sizeof(SchUeCfgRsp));
545
546    if(!ueCfg)
547    {
548       DU_LOG("\nSCH : Reconfig request failed at MacSchUeReconfigReq()");
549       return RFAILED;
550    }
551    DU_LOG("\nSCH : Reconfig Request for CRNTI[%d]", ueCfg->crnti);
552    cellCb = getSchCellCb(pst->event, inst, ueCfg);
553
554    /* Search if UE already configured */
555    GET_UE_IDX(ueCfg->crnti, ueIdx);
556    ueCb = &cellCb->ueCb[ueIdx -1];
557    
558    if(!ueCb)
559    {
560       DU_LOG("\n SCH : SchUeCb not found at MacSchUeReconfigReq() ");
561       SchSendUeCfgRspToMac(pst->event, ueCfg, inst, RSP_NOK, &cfgRsp);
562       return RFAILED;
563    }
564    if((ueCb->crnti == ueCfg->crnti) && (ueCb->state == SCH_UE_STATE_ACTIVE))
565    {
566       /* Found the UeCb to Reconfig */
567       ret = fillSchUeCb(ueCb, ueCfg);
568       if(ret == ROK)
569       {
570          ueCb->cellCb = cellCb;
571          ueCb->srRcvd = false;
572          for(lcIdx=0; lcIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcIdx++)
573             ueCb->bsrInfo[lcIdx].dataVol = 0;
574
575          SchSendUeCfgRspToMac(pst->event, ueCfg, inst, RSP_OK, &cfgRsp);
576       }
577    }
578    return ret;
579 }
580
581 /**********************************************************************
582   End of file
583  **********************************************************************/