macCellCfg
[o-du/l2.git] / src / 5gnrmac / rg_cfg.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-MAC layer
22  
23      Type:     C source file
24  
25      Desc:     C source code for Entry point fucntions
26  
27      File:     rg_cfg.c
28  
29 **********************************************************************/
30
31 /** @file rg_cfg.c
32 @brief This module handles the configuration of MAC by RRC and RRM.
33 */
34
35 static const char* RLOG_MODULE_NAME="MAC";
36 static int RLOG_FILE_ID=180;
37 static int RLOG_MODULE_ID=4096;
38
39 /* header include files -- defines (.h) */
40 #include "envopt.h"        /* environment options */
41 #include "envdep.h"        /* environment dependent */
42 #include "envind.h"        /* environment independent */
43 #include "gen.h"           /* general layer */
44 #include "ssi.h"           /* system service interface */
45 #include "cm_hash.h"       /* common hash list */
46 #include "cm_mblk.h"       /* common memory link list library */
47 #include "cm_llist.h"      /* common linked list library */
48 #include "cm_err.h"        /* common error */
49 #include "cm_lte.h"        /* common LTE */
50 #include "lrg.h"           /* Layer manager interface includes*/
51 #include "crg.h"           /* CRG interface includes*/
52 #include "rgu.h"           /* RGU interface includes*/
53 #include "tfu.h"           /* TFU interface includes */
54 #include "rg_sch_inf.h"    /* SCH interface includes */
55 #include "rg_prg.h"       /* PRG (MAC-MAC) interface includes*/
56 #include "rg_env.h"       /* MAC environmental includes*/
57 #include "rg.h"           /* MAC includes*/
58 #include "rg_err.h"       /* MAC error includes*/
59
60 /* header/extern include files (.x) */
61 #include "gen.x"           /* general layer typedefs */
62 #include "ssi.x"           /* system services typedefs */
63 #include "cm5.x"           /* common timers */
64 #include "cm_hash.x"       /* common hash list */
65 #include "cm_lib.x"        /* common library */
66 #include "cm_llist.x"      /* common linked list */
67 #include "cm_mblk.x"       /* memory management */
68 #include "cm_tkns.x"       /* common tokens */
69 #include "cm_lte.x"       /* common tokens */
70 #include "rgu.x"           /* RGU types */
71 #include "tfu.x"           /* RGU types */
72 #include "lrg.x"           /* layer management typedefs for MAC */
73 #include "crg.x"           /* CRG interface includes */
74 #include "rg_sch_inf.x"    /* SCH interface typedefs */
75 #include "rg_prg.x"        /* PRG (MAC-MAC) Interface typedefs */
76 #include "du_mgr_mac_inf.h"
77 #include "rg.x"            /* typedefs for MAC */
78 #ifdef LTE_ADV
79 #include "rg_pom_scell.x"
80 #endif
81 /* LTE-MAC Control Block Structure */
82 PUBLIC RgCb rgCb[RG_MAX_INST];
83
84 /* local defines */
85 PRIVATE S16 rgCFGVldtCrgDedLcCfg ARGS((Inst inst,CrgLchCfg *lcCfg, RgCellCb **cell,
86          RgUeCb **ue, RgErrInfo *errInfo));
87 PRIVATE S16 rgCFGVldtCrgCmnLcCfg ARGS((Inst inst,CrgLchCfg *lcCfg, RgCellCb **cell,
88          RgErrInfo *errInfo));
89 PRIVATE S16 rgCFGCrgDedLcCfg ARGS((RgCellCb *cell, RgUeCb *ue,
90          CrgLchCfg *lcCfg, RgErrInfo *errInfo));
91 PRIVATE S16 rgCFGCrgCmnLcCfg ARGS((Inst inst,RgCellCb *cell, CrgLchCfg *lcCfg,
92          RgErrInfo *errInfo));
93
94 PRIVATE Void rgCFGFreeCmnLcLst ARGS((RgCellCb *cell));
95 PRIVATE Void rgCFGFreeUeLst ARGS((RgCellCb *cell));
96 /* Added support for SPS*/
97 #ifdef LTEMAC_SPS
98 PRIVATE Void rgCFGFreeSpsUeLst ARGS((RgCellCb *cell));
99 #endif /* LTEMAC_SPS */
100
101
102 /* local typedefs */
103  
104 /* local externs */
105  
106 /* forward references */
107
108
109
110
111 /**
112  * @brief Validates the cell configuration request from RRC to MAC.
113  *
114  * @details
115  *
116  *     Function : rgCFGVldtCrgCellCfg
117  *
118  *     Processing Steps:
119  *      - Validate the cell configuration request from RRC to MAC at CFG:
120  *        validate the value range for the configured values.
121  *      - If validated successfully,
122  *        - Return ROK.
123  *      - Else 
124  *        - Return RFAILED.
125  *
126  *  @param[in]  Inst        inst
127  *  @param[in]  CrgCellCfg  *cellCfg
128  *  @param[out] RgErrInfo   *errInfo
129  *  @return  S16
130  *      -# ROK
131  *      -# RFAILED
132  **/
133 #ifdef ANSI
134 PUBLIC S16 rgCFGVldtCrgCellCfg
135 (
136 Inst        inst,
137 CrgCellCfg  *cellCfg,
138 RgErrInfo   *errInfo
139 )
140 #else
141 PUBLIC S16 rgCFGVldtCrgCellCfg(inst,cellCfg, errInfo)
142 Inst        inst;
143 CrgCellCfg  *cellCfg;
144 RgErrInfo   *errInfo;
145 #endif
146 {
147    TRC2(rgCFGVldtCrgCellCfg);
148
149    errInfo->errCause = RGERR_CFG_INVALID_CRG_CELL_CFG;
150    if ((rgCb[inst].cell != NULLP)
151          || rgCb[inst].inactiveCell != NULLP)
152    {
153       RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Cell already exists");
154       RETVALUE(RFAILED);
155    }
156    if ((cellCfg->bwCfg.dlTotalBw < RG_MIN_DL_BW
157             || cellCfg->bwCfg.dlTotalBw > RG_MAX_DL_BW)
158          || (cellCfg->bwCfg.ulTotalBw < RG_MIN_UL_BW
159             || cellCfg->bwCfg.ulTotalBw > RG_MAX_UL_BW))
160    {
161       RLOG_ARG2(L_ERROR,DBG_CELLID,cellCfg->cellId, 
162             "Invalid Bandwidth configuration: ul %d dl %d",
163             cellCfg->bwCfg.ulTotalBw, cellCfg->bwCfg.dlTotalBw);
164       RETVALUE(RFAILED);
165    }
166    if (cellCfg->rachCfg.maxMsg3Tx < RG_MIN_HQ_TX)
167    {
168       RLOG_ARG1(L_ERROR,DBG_CELLID,cellCfg->cellId,
169                 "Invalid RACH configuration: maxMsg3Tx %d",cellCfg->rachCfg.maxMsg3Tx);
170       RETVALUE(RFAILED);
171    }
172 #ifdef TENB_MULT_CELL_SUPPRT
173    if((cellCfg->rguDlSapId > rgCb[inst].numRguSaps) ||
174       (cellCfg->rguUlSapId > rgCb[inst].numRguSaps))
175    {
176       RGDBGERRNEW(inst,(rgPBuf(inst), "Invald Sap Id: DL %d UL %d for CellId %d failed\n",
177                cellCfg->rguDlSapId,
178                cellCfg->rguUlSapId,
179                cellCfg->cellId));
180       RETVALUE(RFAILED);
181    }
182 #endif
183    errInfo->errCause = RGERR_NONE;
184    RETVALUE(ROK);
185 }  /* rgCFGVldtCrgCellCfg */
186
187
188 /**
189  * @brief Validates the UE configuration request from RRC to MAC.
190  *
191  * @details
192  *
193  *     Function : rgCFGVldtCrgUeCfg
194  *
195  *     Processing Steps:
196  *      - Validate the UE configuration request from RRC to MAC at CFG:
197  *        validate the value range for the configured values.
198  *      - If validated successfully,
199  *        - Return ROK and pointer to the cell of UE.
200  *      - Else 
201  *        - Return RFAILED.
202  *
203  *  @param[in]  Inst        inst
204  *  @param[in]  CrgUeCfg  *ueCfg
205  *  @param[out] RgCellCb  **cell
206  *  @param[out] RgErrInfo *errInfo
207  *  @return  S16
208  *      -# ROK
209  *      -# RFAILED
210  **/
211 #ifdef ANSI
212 PUBLIC S16 rgCFGVldtCrgUeCfg
213 (
214 Inst      inst,
215 CrgUeCfg  *ueCfg,
216 RgCellCb  **cell,
217 RgErrInfo *errInfo
218 )
219 #else
220 PUBLIC S16 rgCFGVldtCrgUeCfg(inst,ueCfg, cell, errInfo)
221 Inst      inst;
222 CrgUeCfg  *ueCfg;
223 RgCellCb  **cell;
224 RgErrInfo *errInfo;
225 #endif
226 {
227    TRC2(rgCFGVldtCrgUeCfg);
228
229    errInfo->errCause = RGERR_CFG_INVALID_CRG_UE_CFG;
230    if ((ueCfg->txMode.pres == PRSNT_NODEF) && 
231        (ueCfg->txMode.tm == CRG_UE_TM_5))
232    {
233       RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti,"Transmission Mode=%d not supported",
234             ueCfg->txMode.tm);
235       RETVALUE(RFAILED);
236    }
237    
238    /* Fetch the Active cell */
239    if(((*cell = rgCb[inst].cell) == NULLP) ||
240        ((*cell)->cellId != ueCfg->cellId))
241    {
242       RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti,"Active Cell does not exist for cellId%d",
243             ueCfg->cellId);
244       RETVALUE(RFAILED);
245    }
246    /* Check if Ue already configured */
247    if (rgDBMGetUeCb(*cell, ueCfg->crnti) != NULLP)
248    {
249       RLOG_ARG0(L_ERROR,DBG_CRNTI,ueCfg->crnti,"Ue already exists");
250       RETVALUE(RFAILED);
251    }
252
253    if (ueCfg->ueUlHqCfg.maxUlHqTx < RG_MIN_HQ_TX)
254    {
255       RLOG_ARG1(L_ERROR,DBG_CRNTI,ueCfg->crnti, "Invalid Uplink HARQ config %d ",
256             ueCfg->ueUlHqCfg.maxUlHqTx);
257       RETVALUE(RFAILED);
258    }
259 #ifdef TENB_MULT_CELL_SUPPRT
260    if((ueCfg->rguDlSapId > rgCb[inst].numRguSaps) ||
261       (ueCfg->rguUlSapId > rgCb[inst].numRguSaps))
262    {
263       RGDBGERRNEW(inst,(rgPBuf(inst), "Invald Sap Id: DL %d UL %d for ueId %d failed\n",
264                ueCfg->rguDlSapId,
265                ueCfg->rguUlSapId,
266                ueCfg->crnti));
267       RETVALUE(RFAILED);
268    }
269 #endif
270
271    errInfo->errCause = RGERR_NONE;
272    RETVALUE(ROK);
273 }  /* rgCFGVldtCrgUeCfg */
274
275
276 /**
277  * @brief Validates the logical channel configuration request from RRC to MAC.
278  *
279  * @details
280  *
281  *     Function : rgCFGVldtCrgLcCfg
282  *
283  *     Processing Steps:
284  *      - Validate the logical channel configuration request from RRC to
285  *        MAC at CFG: validate if configured values are within the range.
286  *      - If validated successfully,
287  *        - Return ROK and pointer to the cell for common channels. Return
288  *          pointer to cell and UE for dedicated logical channels.
289  *      - Else 
290  *        - Return RFAILED.
291  *
292  *  @param[in]  CrgLchCfg  *lcCfg
293  *  @param[in]  Inst        inst
294  *  @param[out] RgCellCb   **cell
295  *  @param[out] RgUeCb     **ue
296  *  @param[out] RgErrInfo  *errInfo
297  *  @return  S16
298  *      -# ROK
299  *      -# RFAILED
300  **/
301 #ifdef ANSI
302 PUBLIC S16 rgCFGVldtCrgLcCfg
303 (
304 Inst       inst, 
305 CrgLchCfg  *lcCfg,
306 RgCellCb   **cell,
307 RgUeCb     **ue,
308 RgErrInfo  *errInfo
309 )
310 #else
311 PUBLIC S16 rgCFGVldtCrgLcCfg(inst,lcCfg, cell, ue, errInfo)
312 Inst       inst;
313 CrgLchCfg  *lcCfg;
314 RgCellCb   **cell;
315 RgUeCb     **ue;
316 RgErrInfo  *errInfo;
317 #endif
318 {
319
320    TRC2(rgCFGVldtCrgLcCfg);
321
322    if (lcCfg->lcType == CM_LTE_LCH_DTCH || lcCfg->lcType == CM_LTE_LCH_DCCH)
323    {
324       /* Dedicated logical channels */
325       if ((rgCFGVldtCrgDedLcCfg(inst,lcCfg, cell, ue, errInfo)) != ROK)
326       {
327          RLOG_ARG0(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Validation for dedicated LC failed");
328          RETVALUE(RFAILED);
329       }
330    }
331    else if (lcCfg->lcType == CM_LTE_LCH_BCCH
332          || lcCfg->lcType == CM_LTE_LCH_PCCH
333          || lcCfg->lcType == CM_LTE_LCH_CCCH)
334    {
335       if ((rgCFGVldtCrgCmnLcCfg(inst,lcCfg, cell, errInfo)) != ROK)
336       {
337          RLOG_ARG0(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Validation for common logical channels failed");
338          RETVALUE(RFAILED);
339       }
340    }
341    else
342    {
343       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Invalid logical channel type %d",
344                 lcCfg->lcType);
345       RETVALUE(RFAILED);
346    }
347 #ifdef LTE_L2_MEAS
348    if ( lcCfg->qci <  RG_QCI_MIN ||
349         lcCfg->qci >  RG_QCI_MAX
350       )
351    {
352       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Invalid qci %x",lcCfg->qci);
353       RETVALUE(RFAILED);
354    }
355    /*validate qci */
356 #endif /*LTE_L2_MEAS */
357
358    errInfo->errCause = RGERR_NONE;
359    RETVALUE(ROK);
360 }  /* rgCFGVldtCrgLcCfg */
361
362
363 /**
364  * @brief Validates the cell re-configuration request from RRC to MAC.
365  *
366  * @details
367  *
368  *     Function : rgCFGVldtCrgCellRecfg
369  *
370  *     Processing Steps:
371  *      - Retrieve the cell control block.
372  *      - If successful,
373  *        - Validate the range of re-configured values recieved in
374  *          re-configuration request.
375  *        - If validated successfully,
376  *          - Return ROK and pointer to the cell.
377  *        - Else 
378  *          - Return RFAILED.
379  *      - Else return RFAILED.
380  *
381  *  @param[in]  Inst        inst
382  *  @param[in]  CrgCellRecfg  *cellRecfg
383  *  @param[out] RgCellCb      **cell
384  *  @param[out] RgErrInfo     *errInfo
385  *  @return  S16
386  *      -# ROK
387  *      -# RFAILED
388  **/
389 #ifdef ANSI
390 PUBLIC S16 rgCFGVldtCrgCellRecfg
391 (
392 Inst          inst,
393 CrgCellRecfg  *cellRecfg,
394 RgCellCb      **cell,
395 RgErrInfo     *errInfo
396 )
397 #else
398 PUBLIC S16 rgCFGVldtCrgCellRecfg(inst,cellRecfg, cell, errInfo)
399 Inst          inst;
400 CrgCellRecfg  *cellRecfg;
401 RgCellCb      **cell;
402 RgErrInfo     *errInfo;
403 #endif
404 {
405    TRC2(rgCFGVldtCrgCellRecfg);
406
407    errInfo->errCause = RGERR_CFG_INVALID_CRG_CELL_RECFG;
408    
409    if (((*cell = rgCb[inst].cell) == NULLP)
410          && ((*cell = rgCb[inst].inactiveCell) == NULLP))
411    {
412       RLOG_ARG0(L_ERROR,DBG_CELLID,cellRecfg->cellId,"Cell does not exist");
413       RETVALUE(RFAILED);
414    }
415
416    if((*cell)->cellId != cellRecfg->cellId)
417    {
418       RLOG_ARG1(L_ERROR,DBG_CELLID,cellRecfg->cellId, "Cell does not exist %d\n",cellRecfg->cellId);
419       RETVALUE(RFAILED);
420    }
421    if (cellRecfg->rachRecfg.maxMsg3Tx < RG_MIN_HQ_TX)
422    {
423       RLOG_ARG1(L_ERROR,DBG_CELLID,cellRecfg->cellId,
424                 "Invalid RACH configuration: maxMsg3Tx %d",cellRecfg->rachRecfg.maxMsg3Tx);
425       RETVALUE(RFAILED);
426    }
427    errInfo->errCause = RGERR_NONE;
428    RETVALUE(ROK);
429 }  /* rgCFGVldtCrgCellRecfg */
430
431
432 /**
433  * @brief Validates the UE re-configuration request from RRC to MAC.
434  *
435  * @details
436  *
437  *     Function : rgCFGVldtCrgUeRecfg
438  *
439  *     Processing Steps:
440  *      - Retrieve the UE control block.
441  *      - If successful,
442  *        - Validate the range of re-configured values recieved in
443  *          re-configuration request.
444  *        - If validated successfully,
445  *          - Return ROK and pointer to the cell and ue.
446  *        - Else 
447  *          - Return RFAILED.
448  *      - Else return RFAILED.
449  *
450  *  @param[in]  Inst        inst
451  *  @param[in]  CrgUeRecfg *ueRecfg
452  *  @param[out] RgCellCb   **cell
453  *  @param[out] RgUeCb     **ue
454  *  @param[out] RgErrInfo *errInfo
455  *  @return  S16
456  *      -# ROK
457  *      -# RFAILED
458  **/
459 #ifdef ANSI
460 PUBLIC S16 rgCFGVldtCrgUeRecfg
461 (
462 Inst        inst,
463 CrgUeRecfg  *ueRecfg,
464 RgCellCb    **cell,
465 RgUeCb      **ue,
466 RgErrInfo   *errInfo
467 )
468 #else
469 PUBLIC S16 rgCFGVldtCrgUeRecfg(inst,ueRecfg, cell, ue, errInfo)
470 Inst        inst;
471 CrgUeRecfg  *ueRecfg;
472 RgCellCb    **cell;
473 RgUeCb      **ue;
474 RgErrInfo   *errInfo;
475 #endif
476 {
477    TRC2(rgCFGVldtCrgUeRecfg);
478
479    errInfo->errCause = RGERR_CFG_INVALID_CRG_UE_RECFG;
480    
481    if ((ueRecfg->txMode.pres == PRSNT_NODEF) && 
482        (ueRecfg->txMode.tm == CRG_UE_TM_5))
483    {
484       RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Transmission Mode=%d not supported",
485                 ueRecfg->txMode.tm);
486       RETVALUE(RFAILED);
487    }
488
489     /* Fetch the Active cell */
490    if (((*cell = rgCb[inst].cell) == NULLP) 
491         || ((*cell)->cellId != ueRecfg->cellId))
492    {
493       RLOG_ARG0(L_ERROR,DBG_CELLID,ueRecfg->cellId, "Active Cell does not exist\n");
494       RETVALUE(RFAILED);
495    }
496  
497    /* Fix : syed UE ID change at MAC will now be controlled
498     * by SCH. */
499    if ((*ue = rgDBMGetUeCb(*cell, ueRecfg->oldCrnti)) == NULLP)
500    {
501       RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"[%d]Old Ue does not exist", ueRecfg->oldCrnti);
502       RETVALUE(RFAILED);
503    }
504    if (ueRecfg->ueUlHqRecfg.maxUlHqTx < RG_MIN_HQ_TX)
505    {
506       RLOG_ARG1(L_ERROR,DBG_CELLID,ueRecfg->cellId,"Invalid Uplink HARQ config for UE %d",
507             ueRecfg->ueUlHqRecfg.maxUlHqTx);
508       RETVALUE(RFAILED);
509    }
510    errInfo->errCause = RGERR_NONE;
511    RETVALUE(ROK);
512 }  /* rgCFGVldtCrgUeRecfg */
513
514
515 /**
516  * @brief Validates the logical channel re-configuration request from
517  * RRC to MAC.
518  *
519  * @details
520  *
521  *     Function : rgCFGVldtCrgLcRecfg
522  *
523  *     Processing Steps:
524  *      - Retrieve the uplink and downlink logical channel control block.
525  *      - If successful,
526  *        - Validate the range of re-configured values recieved in
527  *          re-configuration request.
528  *        - If validated successfully,
529  *          - Return ROK and pointer to the cell, UE and logical channel.
530  *        - Else 
531  *          - Return RFAILED.
532  *      - Else return RFAILED.
533  *
534  *  @param[in]  Inst        inst
535  *  @param[in]  CrgLchRecfg  *lcRecfg
536  *  @param[out] RgCellCb     **cell
537  *  @param[out] RgUeCb       **ue
538  *  @param[out] RgUlLcCb     **ulLc
539  *  @param[out] RgDlLcCb     **dlLc
540  *  @param[out] RgErrInfo    *errInfo
541  *  @return  S16
542  *      -# ROK
543  *      -# RFAILED
544  **/
545 #ifdef ANSI
546 PUBLIC S16 rgCFGVldtCrgLcRecfg
547 (
548 Inst        inst,
549 CrgLchRecfg *lcRecfg,
550 RgCellCb    **cell,
551 RgUeCb      **ue,
552 RgUlLcCb    **ulLc,
553 RgErrInfo   *errInfo
554 )
555 #else
556 PUBLIC S16 rgCFGVldtCrgLcRecfg(inst,lcRecfg, cell, ue, ulLc, errInfo)
557 Inst        inst;
558 CrgLchRecfg  *lcRecfg;
559 RgCellCb     **cell;
560 RgUeCb       **ue;
561 RgUlLcCb     **ulLc;
562 RgErrInfo    *errInfo;
563 #endif
564 {
565    TRC2(rgCFGVldtCrgLcRecfg);
566
567    errInfo->errCause = RGERR_CFG_INVALID_CRG_LC_RECFG;
568
569    /* Fetch the cell */
570    if ((((*cell = rgCb[inst].cell)) == NULLP)
571       || ((*cell)->cellId != lcRecfg->cellId))
572    {
573       RLOG_ARG2(L_ERROR,DBG_CRNTI,lcRecfg->crnti,"Active Cell %u does not exist for UE %u", lcRecfg->cellId, lcRecfg->crnti);
574       RETVALUE(RFAILED);
575    }
576    /* Fetch the Ue for dedicated channels */
577    if ((*ue = rgDBMGetUeCb(*cell, lcRecfg->crnti)) == NULLP)
578    {
579       RLOG_ARG0(L_ERROR,DBG_CRNTI,lcRecfg->crnti,"Ue does not exist for dedicated logical channel");
580       RETVALUE(RFAILED);
581    }
582
583    if ((*ulLc = rgDBMGetUlDedLcCb((*ue), lcRecfg->lcId)) == NULLP)
584    {
585       RLOG_ARG1(L_ERROR, DBG_CRNTI,lcRecfg->crnti,"Dedicated UL LC does not exist %d",lcRecfg->lcId);
586       RETVALUE(RFAILED);
587    }
588
589    if (lcRecfg->ulRecfg.lcgId > (RG_MAX_LCG_PER_UE - 1))
590    {
591       RLOG_ARG2(L_ERROR,DBG_CRNTI,lcRecfg->crnti,"Invalid lcgId for uplink logical channel lcg %d lc %d",
592                 lcRecfg->ulRecfg.lcgId, lcRecfg->lcId);
593       RETVALUE(RFAILED);
594    }
595
596    errInfo->errCause = RGERR_NONE;
597    RETVALUE(ROK);
598 }  /* rgCFGVldtCrgLcRecfg */
599
600 /* Start: LTEMAC_2.1_DEV_CFG */
601 /**
602  * @brief Validates the UE Reset request from RRC to MAC.
603  *
604  * @details
605  *
606  *     Function : rgCFGVldtCrgUeReset
607  *
608  *     Processing Steps:
609  *      - Retrieve the CELL control block.
610  *      - If Failue,
611  *          - Return RFAILED.
612  *      - Retrieve the UE control block.
613  *      - If Failue,
614  *          - Return RFAILED.
615  *
616  *  @param[in]  Inst        inst
617  *  @param[in]  CrgRst     *reset,
618  *  @param[out] RgCellCb   **cell
619  *  @param[out] RgUeCb     **ue
620  *  @param[out] RgErrInfo *errInfo
621  *  @return  S16
622  *      -# ROK
623  *      -# RFAILED
624  **/
625 #ifdef ANSI
626 PUBLIC S16 rgCFGVldtCrgUeReset
627 (
628 Inst       inst,
629 CrgRst     *reset,
630 RgCellCb    **cell,
631 RgUeCb      **ue,
632 RgErrInfo   *errInfo
633 )
634 #else
635 PUBLIC S16 rgCFGVldtCrgUeReset(inst,reset, cell, ue, errInfo)
636 Inst       inst;
637 CrgRst     *reset;
638 RgCellCb    **cell;
639 RgUeCb      **ue;
640 RgErrInfo   *errInfo;
641 #endif
642 {
643    TRC2(rgCFGVldtCrgUeReset);
644
645    errInfo->errCause = RGERR_CFG_INVALID_CRG_UE_RESET;
646    
647    /* Fetch the Active cell */
648    if (((*cell = rgCb[inst].cell) == NULLP)
649       || ((*cell)->cellId != reset->cellId))
650    {
651       RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]Active Cell does not exist %d\n",reset->crnti, reset->cellId));
652       RLOG_ARG1(L_ERROR,DBG_CRNTI,reset->crnti,"Active Cell does not exist %d",reset->cellId);
653       RETVALUE(RFAILED);
654    }
655
656    /* Fetch the Ue */
657    if ((*ue = rgDBMGetUeCb(*cell, reset->crnti)) == NULLP)
658    {
659       RLOG_ARG0(L_ERROR,DBG_CRNTI,reset->crnti,"UE does not exist");
660       RETVALUE(RFAILED);
661    }
662
663    errInfo->errCause = RGERR_NONE;
664    RETVALUE(ROK);
665 }  /* rgCFGVldtCrgUeReset*/
666 /* End: LTEMAC_2.1_DEV_CFG */
667
668
669
670 /**
671  * @brief Handler for the cell configuration request from RRC to MAC.
672  *
673  * @details
674  *
675  *     Function : rgCFGCrgCellCfg
676  *
677  *     Processing Steps:
678  *      - Allocate and create cell control block.
679  *      - Update cell control block with the values recieved in the
680  *        configuration.
681  *      - Add the control block to hash list of cells.
682  *      - Update the statistics.
683  *      - If successful, return ROK else return RFAILED.
684  *
685  *  @param[in]  Inst        inst
686  *  @param[in]  CrgCellCfg  *cellCfg
687  *  @param[out] RgErrInfo   *errInfo
688  *  @return  S16
689  *      -# ROK
690  *      -# RFAILED
691  **/
692 #ifdef ANSI
693 PUBLIC S16 rgCFGCrgCellCfg
694 (
695 Inst        inst,
696 CrgCellCfg  *cellCfg,
697 RgErrInfo   *errInfo
698 )
699 #else
700 PUBLIC S16 rgCFGCrgCellCfg(inst,cellCfg, errInfo)
701 Inst        inst;
702 CrgCellCfg  *cellCfg;
703 RgErrInfo   *errInfo;
704 #endif
705 {
706    S16        ret;
707    RgCellCb   *cell = NULLP;
708    U8         idx;
709    SuId       rguUlSapId = 0;
710    SuId       rguDlSapId = 0;
711    /* RLC SAP to allocate flowCntrlInd buffer*/
712    Pst        *pst ;
713
714    TRC2(rgCFGCrgCellCfg);
715
716    errInfo->errCause = RGERR_CFG_CRG_CELL_CFG;
717    
718    /* Allocate the cell control block */
719    if((ret = rgAllocSBuf(inst,(Data**)&cell, sizeof(RgCellCb))) != ROK)
720    {
721       RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"Memory allocation FAILED for cell");
722       RETVALUE(RFAILED);
723    }
724    if (cell == NULLP)
725    {
726       RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId, "Memory allocation FAILED for cell");
727       RETVALUE(RFAILED);
728    }
729
730    /* Initialize the cell */
731    cell->cellId  = cellCfg->cellId;
732    cell->rachCfg = cellCfg->rachCfg;
733    cell->bwCfg   = cellCfg->bwCfg;
734 #ifdef EMTC_ENABLE
735    if(cellCfg->emtcEnable)
736     {  
737      cell->emtcEnable = cellCfg->emtcEnable;
738     }
739 #endif
740    /* Initialize UL and DL CCCH logical channels */
741    cell->ulCcchId = RG_INVALID_LC_ID;
742    cell->dlCcchId = RG_INVALID_LC_ID;
743
744    
745    /* Initialize the lists of the cell */
746    ret = rgDBMInitCell(cell);
747    if (ret != ROK)
748    {
749       RLOG_ARG0(L_ERROR,DBG_CELLID,cellCfg->cellId,"DBM initialization for cell failed");
750       rgCFGFreeInactvCellCb(cell);
751       RETVALUE(RFAILED);
752    }
753
754 #ifdef LTE_ADV
755    if (RFAILED == RgLaaCellCbInit(cell))
756    {
757       rgCFGFreeInactvCellCb(cell);
758       RETVALUE(RFAILED);
759    }
760 #endif
761
762    for(idx=0;idx < RG_NUM_SUB_FRAMES; idx++)
763    {
764       cell->subFrms[idx].txDone = TRUE;
765    }
766   
767    cell->macInst           = inst + RG_INST_START; 
768    /* Insert cell in the incative cell list */
769    rgCb[inst].inactiveCell = cell;
770    rgCb[inst].cell         = NULLP;
771 #ifdef TENB_MULT_CELL_SUPPRT
772    rguDlSapId              = cellCfg->rguDlSapId;
773    rguUlSapId              = cellCfg->rguUlSapId;
774 #else
775    if(rgCb[inst].numRguSaps > 1)
776    {
777       rguDlSapId              = 1;
778    }
779 #endif
780    cell->rguDlSap          = &(rgCb[inst].rguSap[rguDlSapId]);
781    cell->rguUlSap          = &(rgCb[inst].rguSap[rguUlSapId]);
782
783
784 #ifdef LTE_L2_MEAS
785    cmLListInit(&cell->l2mList);
786    for(idx = 0; idx < RG_NUM_UL_SUB_FRAMES; idx++)
787    {
788       cmMemset((U8 *)&cell->ulSf[idx], 0, sizeof(RgUlSf));
789    }
790
791    cell->ttiCycle = (U32)RG_TTI_CYCLE_INVLD;   
792 #endif
793    /* Update Statistics */
794    rgUpdtCellCnt(inst,RG_CFG_ADD);
795    errInfo->errCause = RGERR_NONE;
796   
797    pst = &rgCb[inst].rguSap[rguDlSapId].sapCfg.sapPst;
798    /* Allocate a buffer for flowCntrlInd.*/
799    SGetSBuf(pst->region, pst->pool, (Data **)&cell->flowCntrlInd, 
800               sizeof(RguFlowCntrlInd));
801    RETVALUE(ROK);
802 }  /* rgCFGCrgCellCfg */
803
804 #ifdef LTE_ADV
805 /**
806  * @brief Add SCell Cfg recvd from primary MAC instance.
807  *
808  * @details
809  *
810  *     Function : rgCfgAddUeSCellCfg
811  *
812  *     Processing Steps:
813  *      - Allocate and create UE control block.
814  *      - Update UE control block with the values recieved in the
815  *        configuration.
816  *      - If successful, add the control block to hash list of UEs for the cell
817  *        else Rollback and FAIL.
818  *
819  *  @param[in]  Inst                 dstMacInst
820  *  @param[in]  RgPrgUeSCellCfgInfo  *ueSCellCb
821  *  @param[in]  RgCellCb              cell
822
823  *  @return  S16
824  *      -# ROK
825  *      -# RFAILED
826  **/
827 #ifdef ANSI
828 PUBLIC S16 rgCfgAddUeSCellCfg
829 (
830 Inst        dstMacInst,    
831 RgPrgUeSCellCfgInfo *ueSCellCb,
832 RgCellCb    *cell
833 )
834 #else
835 PUBLIC S16 rgCfgAddUeSCellCfg(dstMacInst, ueSCellCb, cell)
836 Inst        dstMacInst;    
837 RgPrgUeSCellCfgInfo *ueSCellCb;
838 RgCellCb    *cell;
839 #endif
840 {
841    RgUeCb     *ueCb = NULLP;
842    SuId       rguUlSapId = 0;
843    SuId       rguDlSapId = 0;
844    U8        idx;
845    RgErrInfo  errInfo;
846
847    TRC2(rgCfgAddUeSCellCfg);
848    
849 #ifdef LTE_ADV
850    rguDlSapId              = ueSCellCb->rguDlSapId;
851    rguUlSapId              = ueSCellCb->rguUlSapId;
852 #endif
853 #ifndef TENB_MULT_CELL_SUPPRT
854    if(rgCb[dstMacInst].numRguSaps > 1)
855    {
856       rguDlSapId              = 1;
857    }
858 #endif
859
860    if ((ueCb = rgDBMGetUeCb(cell, ueSCellCb->ueId)) != NULLP)
861    {
862       RGDBGERRNEW(dstMacInst,(rgPBuf(dstMacInst), 
863                "[%d]Ue already exist in scell %d during scell addition\n", 
864                ueSCellCb->ueId,
865                cell->cellId));
866       RETVALUE(RFAILED);
867    }
868
869    /* Create UeCb */
870    if((ueCb = rgRAMCreateUeCb(cell, ueSCellCb->ueId,
871                FALSE, &errInfo)) == NULLP)
872    {
873       RGDBGERRNEW(dstMacInst, (rgPBuf(dstMacInst),
874                "[%d]UeCb creation failed\n", ueSCellCb->ueId));
875       RETVALUE(RFAILED);
876    }
877
878    if(rgDHMHqEntInit(dstMacInst, &ueCb->dl.hqEnt, 
879             (rgCb[dstMacInst].cell)->maxDlHqProcPerUe) != ROK)
880    {
881       RGDBGERRNEW(dstMacInst,(rgPBuf(dstMacInst), 
882                "[%d]UeCb Harq Entity Initialization failed\n", ueSCellCb->ueId));
883       RETVALUE(RFAILED);
884    }
885    rgDBMInsUeCb(cell, ueCb);
886
887
888    ueCb->rguDlSap          = &(rgCb[dstMacInst].rguSap[rguDlSapId]);
889    ueCb->rguUlSap          = &(rgCb[dstMacInst].rguSap[rguUlSapId]);
890
891    /* Update satistics */
892    rgUpdtUeCnt(dstMacInst, RG_CFG_ADD);
893    /*Commit Added SCell info to UeCb */
894    /*
895    ueCb->sCelAddInfo[idx].isSCellAdded = TRUE;
896    ueCb->sCelAddInfo[idx].macInst = dstMacInst;
897    ueCb->sCelAddInfo[idx].sCellId = ueSCellCb->cellId;
898    */
899
900    ueCb->txMode = ueSCellCb->txMode;
901    ueCb->ul.hqEnt.maxHqRetx = ueSCellCb->maxUlHqRetx;
902
903    for (idx =0; idx <RG_MAX_LC_PER_UE; idx++)
904    {
905       ueCb->ul.lcCb[idx] = ueSCellCb->ulLcInfo[idx];
906       ueCb->dl.lcCb[idx] = ueSCellCb->dlLcInfo[idx];
907    }
908
909    for (idx =0; idx < RG_MAX_LCG_PER_UE; idx++)
910    {
911       ueCb->ul.lcgArr[idx].lcgId = ueSCellCb->lcgInfo[idx].lcgId;
912       ueCb->ul.lcgArr[idx].lcCount = ueSCellCb->lcgInfo[idx].lcCount;
913       ueCb->ul.lcgArr[idx].isGbr = ueSCellCb->lcgInfo[idx].isGbr;
914    }
915    RETVALUE(ROK);
916 }/* rgCfgAddUeSCellCfg */
917
918 /**
919  * @brief SCell Config Filling for added cell from RRC to MAC.
920  *
921  * @details
922  *
923  *     Function : rgFillAndAddSCellCfg 
924  *
925  *     Processing Steps:
926  *      - Update UE control block with the values recieved in the
927  *        configuration.
928  *      - Update UE control block with the values present in the
929  *        CellCb
930  *      - If successful, add the control block to hash list of UEs for the cell
931  *        else Rollback and FAIL.
932  *
933  *  @param[in]  Inst          inst
934  *  @param[in]  RgCellCb      *cell
935  *  @param[in]  CrgUeCfg      *ueCfg
936  *  @param[in]  CrgCfgTransId transId
937  *  @return  S16
938  *      -# ROK
939  *      -# RFAILED
940  **/
941 #ifdef ANSI
942 PUBLIC S16 rgFillAndAddSCellCfg
943 (
944 Inst            inst,
945 RgCellCb        *cell,
946 CrgUeRecfg      *ueRecfg,
947 CrgCfgTransId   transId,
948 Bool            *isCfmRqrd
949 )
950 #else
951 PUBLIC S16 rgFillAndAddSCellCfg(inst, cell, ueRecfg, transId, isCfmRqrd)
952 Inst            inst;
953 RgCellCb        *cell;
954 CrgUeRecfg      *ueRecfg;
955 CrgCfgTransId   transId;
956 Bool            *isCfmRqrd;
957 #endif
958 {
959    RgUeCb     *ue = NULLP;
960    U8          idx = 0;
961    Inst        dstMacInst;
962    RgPrgUeSCellCfgInfo ueSCellCb;
963    Pst          dstInstPst;
964
965    TRC2(rgFillAndAddSCellCfg);
966   
967   /* Fetch the Active cell */
968    if(((cell = rgCb[inst].cell) == NULLP) ||
969        (cell->cellId != ueRecfg->cellId))
970    {
971       RGDBGERRNEW(inst,(rgPBuf(inst), 
972                        "[%d]Active Cell does not exist %d\n",
973                                   ueRecfg->oldCrnti, ueRecfg->cellId));
974       RETVALUE(RFAILED);
975    }
976
977    RGDBGPRM(inst,(rgPBuf(inst), 
978             "Filling SCell Config : cellId %d ueId %d\n",
979             cell->cellId, cell->ueId));
980
981    if ((ue = rgDBMGetUeCb(cell, ueRecfg->oldCrnti)) == NULLP)
982    {
983       RGDBGERRNEW(inst,(rgPBuf(inst), 
984                "[%d]Ue does not exist\n", ueRecfg->oldCrnti));
985       RETVALUE(RFAILED);
986    }
987
988    /* Initialize cfgCfmInfo in the ueCb. This is used while processing SCellAdd
989     *confirmation*/
990    ue->cfgCfmInfo.numSCells = ueRecfg->crgSCellCfg.numSCells;
991    ue->cfgCfmInfo.cfgCfgCount = 0;
992    ue->cfgCfmInfo.mask = 0x0;
993
994    cmMemcpy( (U8*)&(ue->cfgCfmInfo.transId), (U8*)&transId,
995          sizeof(CrgCfgTransId));
996    ueSCellCb.ueId = ueRecfg->oldCrnti;
997    ueSCellCb.txMode = ue->txMode;
998    ueSCellCb.maxUlHqRetx = ue->ul.hqEnt.maxHqRetx;
999    cmMemcpy((U8 *)ueSCellCb.ulLcInfo, (U8 *)ue->ul.lcCb, sizeof(ue->ul.lcCb));
1000    cmMemcpy((U8 *)ueSCellCb.dlLcInfo, (U8 *)ue->dl.lcCb, sizeof(ue->dl.lcCb));
1001    for (idx =0; idx < RG_MAX_LCG_PER_UE; idx++)
1002    {
1003       ueSCellCb.lcgInfo[idx].lcgId = ue->ul.lcgArr[idx].lcgId;
1004       ueSCellCb.lcgInfo[idx].lcCount = ue->ul.lcgArr[idx].lcCount;
1005       ueSCellCb.lcgInfo[idx].isGbr = ue->ul.lcgArr[idx].isGbr;
1006    }
1007
1008    for(idx = 0; 
1009          idx < ueRecfg->crgSCellCfg.numSCells; idx++)
1010    {
1011       dstMacInst = ueRecfg->crgSCellCfg.ueSCellCfg[idx].macInst - RG_INST_START;
1012       ueSCellCb.cellId = ueRecfg->crgSCellCfg.ueSCellCfg[idx].sCellId;
1013       ueSCellCb.rguDlSapId = ueRecfg->crgSCellCfg.ueSCellCfg[idx].rguDlSapId;
1014       ueSCellCb.rguUlSapId = ueRecfg->crgSCellCfg.ueSCellCfg[idx].rguUlSapId;
1015
1016       /* Get post structure of the cell to whom ueSCellCb needs to be sent
1017        * And then send the sCell Add based on Mac instances */
1018       rgGetPstToInst(&dstInstPst, inst, dstMacInst);
1019       RgPrgPMacSMacUeSCellCfg(&dstInstPst, &ueSCellCb);
1020
1021       /*Commit Added SCell info to UeCb is moved to config confirm*/
1022    } /*end of for loop */
1023    *isCfmRqrd = FALSE;
1024
1025    RETVALUE(ROK);
1026 }  /* rgFillAndAddSCellCfg */
1027 #endif /* LTE_ADV */
1028
1029 /**
1030  * @brief Handler for the UE configuration request from RRC to MAC.
1031  *
1032  * @details
1033  *
1034  *     Function : rgCFGCrgUeCfg
1035  *
1036  *     Processing Steps:
1037  *      - Allocate and create UE control block.
1038  *      - Update UE control block with the values recieved in the
1039  *        configuration.
1040  *      - Invoke RAM, SCH, UHM and DHM with created UE control block, to
1041  *        update random access, scheduler, uplink harq and downlink harq
1042  *        specific information respectively.
1043  *      - If successful, add the control block to hash list of UEs for the cell
1044  *        else Rollback and FAIL.
1045  *
1046  *  @param[in]  Inst        inst
1047  *  @param[in]  RgCellCb  *cell
1048  *  @param[in]  CrgUeCfg  *ueCfg
1049  *  @param[out] RgErrInfo *errInfo
1050  *  @return  S16
1051  *      -# ROK
1052  *      -# RFAILED
1053  **/
1054 #ifdef ANSI
1055 PUBLIC S16 rgCFGCrgUeCfg
1056 (
1057 Inst      inst,
1058 RgCellCb  *cell,
1059 CrgUeCfg  *ueCfg,
1060 RgErrInfo *errInfo
1061 )
1062 #else
1063 PUBLIC S16 rgCFGCrgUeCfg(inst,cell, ueCfg, errInfo)
1064 Inst      inst;
1065 RgCellCb  *cell;
1066 CrgUeCfg  *ueCfg;
1067 RgErrInfo *errInfo;
1068 #endif
1069 {
1070    RgUeCb    *ue = NULLP;
1071    Bool      handover = FALSE;
1072    SuId       rguUlSapId = 0;
1073    SuId       rguDlSapId = 0;
1074
1075    TRC2(rgCFGCrgUeCfg);
1076
1077    errInfo->errCause = RGERR_CFG_CRG_UE_CFG;
1078
1079 /* Start: LTEMAC_2.1_DEV_CFG */
1080    if ((ue = rgDBMGetUeCbFromRachLst(cell, ueCfg->crnti)) == NULLP)
1081    {
1082       /* Create UeCb and Insert in Rach List */
1083       if((ue=rgRAMCreateUeCb(cell, ueCfg->crnti, FALSE, errInfo)) == NULLP)
1084       {
1085          RLOG_ARG0(L_ERROR,DBG_CRNTI,ueCfg->crnti,"UeCb creation failed");
1086          RETVALUE(RFAILED);
1087       }
1088       if(rgDHMHqEntInit(inst,&ue->dl.hqEnt, cell->maxDlHqProcPerUe) != ROK)
1089       {
1090          RLOG_ARG0(L_ERROR,DBG_CRNTI,ueCfg->crnti,"UeCb Harq Entity Initialization failed");
1091          RETVALUE(RFAILED);
1092       }
1093       handover = TRUE;
1094    }
1095 /* End: LTEMAC_2.1_DEV_CFG */
1096
1097    if(handover == FALSE)
1098    {
1099       /* Remove from the rachLst */
1100       rgDBMDelUeCbFromRachLst(cell, ue);
1101    }
1102
1103
1104    /* Initialize uplink HARQ related information for UE */
1105    rgUHMCrgUeCfg(cell, ue, ueCfg);
1106
1107    rgDBMInsUeCb(cell, ue);
1108
1109 #ifdef TENB_MULT_CELL_SUPPRT
1110    rguDlSapId              = ueCfg->rguDlSapId;
1111    rguUlSapId              = ueCfg->rguUlSapId;
1112 #else
1113    if(rgCb[inst].numRguSaps > 1)
1114    {
1115       rguDlSapId              = 1;
1116    }
1117 #endif
1118
1119    ue->rguDlSap          = &(rgCb[inst].rguSap[rguDlSapId]);
1120    ue->rguUlSap          = &(rgCb[inst].rguSap[rguUlSapId]);
1121
1122
1123    /* Update satistics */
1124    rgUpdtUeCnt(inst,RG_CFG_ADD);
1125    errInfo->errCause = RGERR_NONE;
1126    RETVALUE(ROK);
1127 }  /* rgCFGCrgUeCfg */
1128
1129
1130 /**
1131  * @brief Handler for the logical channel configuration request from
1132  * RRC to MAC.
1133  *
1134  * @details
1135  *
1136  *     Function : rgCFGCrgLcCfg
1137  *
1138  *     Processing Steps:
1139  *      - Check if the configuration is for dedicated or common logical channel.
1140  *      - For Dedicated logical channels:
1141  *        - Update the dedicated logical channel Cb with the configured values.
1142  *        - Invoke SCH will cell, UE and logical channel Cb to update scheduler
1143  *          specific information.
1144  *      - For Common logical channels:
1145  *        - Update the common logical channel Cb with the configured values.
1146  *        - Move cell to active list of cells if cell becomes ACTIVE.
1147  *      - If successful, return ROK else RFAILED.
1148  *
1149  *  @param[in]  Inst        inst
1150  *  @param[in]  RgCellCb    *cell
1151  *  @param[in]  RgUeCb      *ue
1152  *  @param[in]  CrgLchCfg   *lcCfg
1153  *  @param[out] RgErrInfo   *errInfo
1154  *  @param[in]  Bool        *isCfmRqrd
1155  *  @return  S16
1156  *      -# ROK
1157  *      -# RFAILED
1158  **/
1159 #ifdef ANSI
1160 PUBLIC S16 rgCFGCrgLcCfg
1161 (
1162 Inst            inst,
1163 RgCellCb        *cell,
1164 RgUeCb          *ue,
1165 CrgLchCfg       *lcCfg,
1166 RgErrInfo       *errInfo,
1167 Bool            *isCfmRqrd,
1168 CrgCfgTransId   transId
1169 )
1170 #else
1171 PUBLIC S16 rgCFGCrgLcCfg(inst,cell, ue, lcCfg, errInfo, isCfmRqrd,transId)
1172 Inst        inst;
1173 RgCellCb    *cell;
1174 RgUeCb      *ue;
1175 CrgLchCfg   *lcCfg;
1176 RgErrInfo   *errInfo;
1177 Bool        *isCfmRqrd;
1178 CrgCfgTransId   transId;
1179 #endif
1180 {
1181
1182    TRC2(rgCFGCrgLcCfg);
1183    
1184    /* Handle Config for dedicated/common logical channels */
1185    if (lcCfg->lcType == CM_LTE_LCH_DTCH || lcCfg->lcType == CM_LTE_LCH_DCCH)
1186    {
1187
1188       if ((rgCFGCrgDedLcCfg(cell, ue, lcCfg, errInfo)) != ROK)
1189       {
1190          RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,
1191                "Dedicated logical channel configuration failed %d",lcCfg->lcId);
1192          RETVALUE(RFAILED);
1193       }
1194 #ifdef LTE_ADV
1195       /*ERAB Multl Cell fix*/
1196        cmMemcpy( (U8*)&(ue->cfgCfmInfo.transId), (U8*)&transId,
1197             sizeof(CrgCfgTransId));
1198        rgPomSndUeSCellLchAddToSmac(inst, cell, ue, lcCfg,isCfmRqrd);
1199 #endif
1200    }
1201    else
1202    {
1203       if ((rgCFGCrgCmnLcCfg(inst,cell, lcCfg, errInfo)) != ROK)
1204       {
1205          RLOG_ARG1(L_ERROR, DBG_CRNTI, lcCfg->crnti, "Common logical channel configuration"
1206                   "failed %d\n", lcCfg->lcId);
1207          RETVALUE(RFAILED);
1208       }
1209    }
1210
1211    errInfo->errCause = RGERR_NONE;
1212    RLOG_ARG1(L_INFO, DBG_CRNTI,lcCfg->crnti, "CRG LC config done for UE: lcId %d\n", lcCfg->lcId);
1213    RETVALUE(ROK);
1214 }  /* rgCFGCrgLcCfg */
1215
1216
1217 /**
1218  * @brief Handler for the cell re-configuration request from RRC to MAC.
1219  *
1220  * @details
1221  *
1222  *     Function : rgCFGCrgCellRecfg
1223  *
1224  *     Processing Steps:
1225  *      - Invoke SCH with updated Cell Cb to update scheduler specific
1226  *        parameters.
1227  *      - Update the cell Cb with the reconfigured values.
1228  *      - If successful, return ROK else RFAILED.
1229  *
1230  *  @param[in]  Inst        inst
1231  *  @param[in]  RgCellCb      *cell
1232  *  @param[in]  CrgCellRecfg  *cellRecfg
1233  *  @param[out] RgErrInfo     *errInfo
1234  *  @return  S16
1235  *      -# ROK
1236  *      -# RFAILED
1237  **/
1238 #ifdef ANSI
1239 PUBLIC S16 rgCFGCrgCellRecfg
1240 (
1241 Inst          inst,
1242 RgCellCb      *cell,
1243 CrgCellRecfg  *cellRecfg,
1244 RgErrInfo     *errInfo
1245 )
1246 #else
1247 PUBLIC S16 rgCFGCrgCellRecfg(inst,cell, cellRecfg, errInfo)
1248 Inst          inst;
1249 RgCellCb      *cell;
1250 CrgCellRecfg  *cellRecfg;
1251 RgErrInfo     *errInfo;
1252 #endif
1253 {
1254    TRC2(rgCFGCrgCellRecfg);
1255
1256    /* Store the given rachCfg */
1257    cell->rachCfg = cellRecfg->rachRecfg;
1258
1259    errInfo->errCause = RGERR_NONE;
1260    RETVALUE(ROK);
1261 }  /* rgCFGCrgCellRecfg */
1262
1263
1264 /**
1265  * @brief Handler for the UE re-configuration request from RRC to MAC.
1266  *
1267  * @details
1268  *
1269  *     Function : rgCFGCrgUeRecfg
1270  *
1271  *     Processing Steps:
1272  *      - If rnti changes,
1273  *        - Invoke RAM for UE reconfiguration.
1274  *        - Delete old UE from the list.
1275  *        - Update the new rnti and re-insert the UE in the list.
1276  *      - Update the UE control block with the reconfigured values.
1277  *      - Invoke SCH, UHM and DHM with updated UE control block to 
1278  *        update scheduler, uplink HARQ and downlink HARQ specific
1279  *        parameters.
1280  *      - If successful, return ROK else RFAILED.
1281  *
1282  *  @param[in]  Inst        inst
1283  *  @param[in]  RgCellCb    *cell
1284  *  @param[in]  RgUeCb      *ue
1285  *  @param[in]  CrgUeRecfg  *ueRecfg
1286  *  @param[out] RgErrInfo   *errInfo
1287  *  @return  S16
1288  *      -# ROK
1289  *      -# RFAILED
1290  **/
1291 #ifdef ANSI
1292 PUBLIC S16 rgCFGCrgUeRecfg
1293 (
1294 Inst        inst,
1295 RgCellCb    *cell,
1296 RgUeCb      *ue,
1297 CrgUeRecfg  *ueRecfg,
1298 RgErrInfo   *errInfo
1299 )
1300 #else
1301 PUBLIC S16 rgCFGCrgUeRecfg(inst,cell, ue, ueRecfg, errInfo)
1302 Inst        inst;
1303 RgCellCb    *cell;
1304 RgUeCb      *ue;
1305 CrgUeRecfg  *ueRecfg;
1306 RgErrInfo   *errInfo;
1307 #endif
1308 {
1309    TRC2(rgCFGCrgUeRecfg);
1310
1311    errInfo->errCause = RGERR_CFG_CRG_UE_RECFG;
1312
1313    /* Fix : syed UE ID change at MAC will now be controlled
1314     * by SCH. */
1315
1316    /* Update uplink HARQ related information for UE */
1317    rgUHMCrgUeRecfg(cell, ue, ueRecfg);
1318
1319    errInfo->errCause = RGERR_NONE;
1320    RETVALUE(ROK);
1321 }  /* rgCFGCrgUeRecfg */
1322
1323
1324 /**
1325  * @brief Handler for the logical channel re-configuration request from
1326  * RRC to MAC.
1327  *
1328  * @details
1329  *
1330  *     Function : rgCFGCrgLcRecfg
1331  *
1332  *     Processing Steps:
1333  *      - Invoke scheduler to update scheduler specific information.
1334  *      - Update the dedicated logical channel Cb with the re-configured
1335  *        values.
1336  *      - If successful, return ROK else RFAILED.
1337  *
1338  *  @param[in]  Inst        inst
1339  *  @param[in]  RgUlCellCb  *cell
1340  *  @param[in]  RgUlUeCb    *ue
1341  *  @param[in]  RgUlLcCb    *ulLc
1342  *  @param[in]  RgDlLcCb    *dlLc
1343  *  @param[in]  CrgLchRecfg *lcRecfg
1344  *  @param[out] RgErrInfo   *errInfo
1345  *  @return  S16
1346  *      -# ROK
1347  *      -# RFAILED
1348  **/
1349 #ifdef ANSI
1350 PUBLIC S16 rgCFGCrgLcRecfg
1351 (
1352 Inst        inst,
1353 RgCellCb    *cell,
1354 RgUeCb      *ue,
1355 RgUlLcCb    *ulLc,
1356 CrgLchRecfg *lcRecfg,
1357 RgErrInfo   *errInfo,
1358 Bool        *isCfmRqrd
1359 )
1360 #else
1361 PUBLIC S16 rgCFGCrgLcRecfg(inst,cell, ue, ulLc, lcRecfg, errInfo, isCfmRqrd)
1362 Inst        inst;
1363 RgCellCb    *cell;
1364 RgUeCb      *ue;
1365 RgUlLcCb    *ulLc;
1366 CrgLchRecfg *lcRecfg;
1367 RgErrInfo   *errInfo;
1368 Bool        *isCfmRqrd;
1369 #endif
1370 {
1371    TRC2(rgCFGCrgLcRecfg);
1372
1373    if (ulLc->lcgId != lcRecfg->ulRecfg.lcgId)
1374    {
1375       rgDBMUpdUlDedLcCb(ue, ulLc, lcRecfg->ulRecfg.lcgId);
1376 #ifdef LTE_ADV
1377       rgPomSndUeSCellLchModToSmac(inst, cell, ue,  lcRecfg,isCfmRqrd);
1378 #endif
1379    }
1380
1381    errInfo->errCause = RGERR_NONE;
1382    RETVALUE(ROK);
1383 }  /* rgCFGCrgLcRecfg */
1384
1385 /* Start: LTEMAC_2.1_DEV_CFG */
1386 /**
1387  * @brief Handler for the logical channel re-configuration request from
1388  * RRC to MAC.
1389  *
1390  * @details
1391  *
1392  *     Function : rgCFGCrgUeReset
1393  *
1394  *     Processing Steps:
1395  *
1396  *  @param[in]  RgUlCellCb  *cell
1397  *  @param[in]  RgUlUeCb    *ue
1398  *  @param[in]  CrgRst     *reset
1399  *  @param[out] RgErrInfo   *errInfo
1400  *  @return  S16
1401  *      -# ROK
1402  *      -# RFAILED
1403  **/
1404 #ifdef ANSI
1405 PUBLIC S16 rgCFGCrgUeReset
1406 (
1407 RgCellCb    *cell,
1408 RgUeCb      *ue,
1409 CrgRst     *reset,
1410 RgErrInfo   *errInfo
1411 )
1412 #else
1413 PUBLIC S16 rgCFGCrgUeReset(cell, ue, reset, errInfo)
1414 RgCellCb    *cell;
1415 RgUeCb      *ue;
1416 CrgRst     *reset;
1417 RgErrInfo   *errInfo;
1418 #endif
1419 {
1420    TRC2(rgCFGCrgUeReset);
1421
1422    RLOG_ARG1(L_DEBUG, DBG_CRNTI, ue->ueId, "UE: of cell %d Reset\n", cell->cellId);
1423    rgDHMUeReset(cell, &ue->dl.hqEnt);
1424
1425    errInfo->errCause = RGERR_NONE;
1426
1427    RETVALUE(ROK);
1428 }  /* rgCFGCrgUeReset */
1429 /* End: LTEMAC_2.1_DEV_CFG */
1430
1431 /**
1432  * @brief Handler for the cell delete request from RRC to MAC.
1433  *
1434  * @details
1435  *
1436  *     Function : rgCFGCrgCellDel
1437  *
1438  *     Processing Steps:
1439  *      - Fetch the cell control block.
1440  *      - Remove the cell control block from the hash list of cells.
1441  *      - Free the cell control block.
1442  *      - If successful, return ROK else return RFAILED.
1443  *
1444  *  @param[in]  Inst        inst
1445  *  @param[in]  CrgDel      *cellDelInfo
1446  *  @param[out] RgErrInfo   *errInfo
1447  *  @return  S16
1448  *      -# ROK
1449  *      -# RFAILED
1450  **/
1451 #ifdef ANSI
1452 PUBLIC S16 rgCFGCrgCellDel
1453 (
1454 Inst        inst,
1455 CrgDel      *cellDelInfo,
1456 RgErrInfo   *errInfo
1457 )
1458 #else
1459 PUBLIC S16 rgCFGCrgCellDel(inst,cellDelInfo, errInfo)
1460 Inst        inst,
1461 CrgDel      *cellDelInfo;
1462 RgErrInfo   *errInfo;
1463 #endif
1464 {
1465    RgCellCb      *cell;
1466    U8 idx;
1467
1468    TRC2(rgCFGCrgCellDel);
1469
1470    errInfo->errCause = RGERR_CFG_CRG_CELL_DEL;
1471    if (((cell = rgCb[inst].cell) == NULLP)
1472        ||(cell->cellId != cellDelInfo->u.cellDel.cellId))  
1473    {
1474       if(((cell = rgCb[inst].inactiveCell) == NULLP)
1475           ||(cell->cellId != cellDelInfo->u.cellDel.cellId))  
1476       {
1477
1478          
1479          RLOG_ARG0(L_ERROR,DBG_CELLID,cellDelInfo->u.cellDel.cellId,"Cell does not exist");
1480          RETVALUE(RFAILED);
1481       }
1482
1483       /* Delete cell from inactive list */
1484       rgCb[inst].inactiveCell = NULLP ;
1485
1486       /* Free the inactive cell */
1487       rgCFGFreeInactvCellCb(cell);
1488
1489       errInfo->errCause = RGERR_NONE;
1490       RETVALUE(ROK);
1491    }
1492
1493    /* Delete from the cell list */
1494    //rgDBMDelCellCb(cell);
1495    for(idx=0;idx < RG_NUM_SUB_FRAMES; idx++)
1496    {
1497       rgTOMRlsSf(inst,&cell->subFrms[idx]);
1498    }
1499
1500    /* Free the active cell */
1501    rgCFGFreeCellCb(cell);
1502
1503    rgCb[inst].cell = NULLP;
1504
1505    errInfo->errCause    = RGERR_NONE;
1506    RGDBGINFO(inst,(rgPBuf(inst), "Cell %d deleted\n", cellDelInfo->u.cellDel.cellId));
1507    RETVALUE(ROK);
1508 }  /* rgCFGCrgCellDel */
1509
1510
1511 /**
1512  * @brief Handler for the UE delete request from RRC to MAC.
1513  *
1514  * @details
1515  *
1516  *     Function : rgCFGCrgUeDel
1517  *
1518  *     Processing Steps:
1519  *      - Fetch the UE control block.
1520  *      - Remove the UE control block from the hash list of UEs for the cell.
1521  *      - Free the UE control block.
1522  *      - If successful, return ROK else return RFAILED.
1523  *
1524  *  @param[in]  Inst        inst
1525  *  @param[in]  CrgDel      *ueDelInfo
1526  *  @param[out] RgErrInfo   *errInfo
1527  *  @return  S16
1528  *      -# ROK
1529  *      -# RFAILED
1530  **/
1531 #ifdef ANSI
1532 PUBLIC S16 rgCFGCrgUeDel
1533 (
1534 Inst        inst,
1535 CrgDel      *ueDelInfo,
1536 RgErrInfo   *errInfo
1537 )
1538 #else
1539 PUBLIC S16 rgCFGCrgUeDel(inst,ueDelInfo, errInfo)
1540 Inst        inst;
1541 CrgDel      *ueDelInfo;
1542 RgErrInfo   *errInfo;
1543 #endif
1544 {
1545    TRC2(rgCFGCrgUeDel);
1546
1547    errInfo->errCause = RGERR_CFG_CRG_UE_DEL;
1548
1549    RLOG_ARG1(L_DEBUG, DBG_CRNTI, ueDelInfo->u.ueDel.crnti, "UE %d Deletion Req at MAC\n", \
1550             ueDelInfo->u.ueDel.crnti);
1551    if ((rgCb[inst].cell == NULLP)
1552        || (rgCb[inst].cell->cellId != ueDelInfo->u.ueDel.cellId))
1553    {
1554       RLOG_ARG1(L_ERROR,DBG_CRNTI,ueDelInfo->u.ueDel.crnti,"Cell does not exist %d",
1555                 ueDelInfo->u.ueDel.cellId);
1556       RETVALUE(RFAILED);
1557    }
1558
1559    errInfo->errCause = RGERR_NONE;
1560    /* Fix: syed Context Deletion is relied upon SCH indication */
1561    RETVALUE(ROK);
1562 }  /* rgCFGCrgUeDel */
1563
1564
1565 /**
1566  * @brief Handler for the logical channel delete request from
1567  * RRC to MAC.
1568  *
1569  * @details
1570  *
1571  *     Function : rgCFGCrgLcDel
1572  *
1573  *     Processing Steps:
1574  *      - Fetch the logical channel control block.
1575  *      - Free the logical channel control block.
1576  *      - If successful, return ROK else return RFAILED.
1577  *
1578  *  @param[in]  Inst        inst
1579  *  @param[in]  CrgDel      *lcDelInfo
1580  *  @param[out] RgErrInfo   *errInfo
1581  *  @return  S16
1582  *      -# ROK
1583  *      -# RFAILED
1584  **/
1585 #ifdef ANSI
1586 PUBLIC S16 rgCFGCrgLcDel
1587 (
1588 Inst        inst,
1589 CrgDel      *lcDelInfo,
1590 RgErrInfo   *errInfo,
1591 Bool        *isCfmRqrd,
1592 CrgCfgTransId transId
1593 )
1594 #else
1595 PUBLIC S16 rgCFGCrgLcDel(inst,lcDelInfo, errInfo,isCfmRqrd,transId)
1596 Inst        inst;
1597 CrgDel      *lcDelInfo;
1598 RgErrInfo   *errInfo;
1599 CrgCfgTransId transId;
1600 #endif
1601 {
1602    Bool      dirVld = FALSE;
1603    RgCellCb  *cell;
1604    RgUeCb    *ue;
1605    RgUlLcCb  *ulLc;
1606    RgDlLcCb  *dlLc;
1607
1608    TRC2(rgCFGCrgLcDel);
1609
1610    errInfo->errCause = RGERR_CFG_CRG_LC_DEL;
1611
1612    /* Fetch the Active cell */
1613    if (((cell = rgCb[inst].cell) == NULLP) ||
1614        (rgCb[inst].cell->cellId != lcDelInfo->u.lchDel.cellId))
1615    {
1616       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcDelInfo->u.lchDel.crnti,"Cell does not exist %d",
1617                 lcDelInfo->u.lchDel.cellId);
1618       RETVALUE(RFAILED);
1619    }
1620
1621    /* Fetch the Ue */
1622    if ((ue = rgDBMGetUeCb(cell, lcDelInfo->u.lchDel.crnti)) == NULLP)
1623    {
1624       RLOG_ARG0(L_ERROR,DBG_CRNTI,lcDelInfo->u.lchDel.crnti,
1625                 "UE does not exist for dedicated logical channel");
1626       RETVALUE(RFAILED);
1627    }
1628
1629    /* Validate downlink info */
1630    if (lcDelInfo->u.lchDel.dir & CRG_DIR_TX)
1631    {
1632       if ((dlLc = rgDBMGetDlDedLcCb(ue, lcDelInfo->u.lchDel.lcId))
1633             == NULLP)
1634       {
1635          RLOG_ARG1(L_ERROR,DBG_CRNTI,lcDelInfo->u.lchDel.crnti,"DL LC %d does not exist",
1636                    lcDelInfo->u.lchDel.lcId);
1637          RETVALUE(RFAILED);
1638       }
1639       rgDBMDelDlDedLcCb(ue, dlLc);
1640       dirVld = TRUE;
1641    }
1642
1643    /* Validate uplink info */
1644    if (lcDelInfo->u.lchDel.dir & CRG_DIR_RX)
1645    {
1646       if ((ulLc = rgDBMGetUlDedLcCb(ue, lcDelInfo->u.lchDel.lcId))
1647             == NULLP)
1648       {
1649          RLOG_ARG1(L_ERROR,DBG_CRNTI,lcDelInfo->u.lchDel.crnti,"UL LC %d does not exist",
1650                    lcDelInfo->u.lchDel.lcId);
1651          RETVALUE(RFAILED);
1652       }
1653       rgDBMDelUlDedLcCb(ue, ulLc);
1654       dirVld = TRUE;
1655    }
1656
1657    if (!dirVld)
1658    {
1659       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcDelInfo->u.lchDel.crnti,"Invalid direction %d for LC Delete",
1660             lcDelInfo->u.lchDel.dir);
1661       RETVALUE(RFAILED);
1662    }
1663 #ifdef LTE_ADV
1664    /*ERAB - multicell fix*/
1665    cmMemcpy( (U8*)&(ue->cfgCfmInfo.transId), (U8*)&transId,
1666          sizeof(CrgCfgTransId));
1667    rgPomSndUeSCellLchDelToSmac(inst, lcDelInfo, isCfmRqrd);
1668 #endif
1669    errInfo->errCause = RGERR_NONE;
1670    RETVALUE(ROK);
1671 }  /* rgCFGCrgLcDel */
1672
1673 /***********************************************************
1674  *
1675  *     Func : rgCFGVldtCrgDedLcCfg
1676  *
1677  *
1678  *     Desc : Validates dedicated logical channel configuration recieved from RRC.
1679  *
1680  *     Ret  : S16
1681  *            ROK - Success
1682  *            RFAILED - Failed
1683  *
1684  *     Notes:
1685  *
1686  *     File :
1687  *
1688  **********************************************************/
1689 #ifdef ANSI
1690 PRIVATE S16 rgCFGVldtCrgDedLcCfg
1691 (
1692 Inst          inst, 
1693 CrgLchCfg     *lcCfg,
1694 RgCellCb      **cell,
1695 RgUeCb        **ue,
1696 RgErrInfo     *errInfo
1697 )
1698 #else
1699 PRIVATE S16 rgCFGVldtCrgDedLcCfg(inst,lcCfg, cell, ue, errInfo)
1700 Inst          inst;
1701 CrgLchCfg     *lcCfg;
1702 RgCellCb      **cell;
1703 RgUeCb        **ue;
1704 RgErrInfo     *errInfo;
1705 #endif
1706 {
1707    U8         dirVld   = FALSE;
1708    TRC2(rgCFGVldtCrgDedLcCfg);
1709
1710    errInfo->errCause = RGERR_CFG_INVALID_CRG_DED_LC_CFG;
1711
1712    /* Fetch the Active cell */
1713    if (((*cell = rgCb[inst].cell) == NULLP)
1714       || ((*cell)->cellId != lcCfg->cellId))
1715    {
1716       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Active Cell does not exist: Cell %d",
1717                 lcCfg->cellId);
1718       RETVALUE(RFAILED);
1719    }
1720
1721    /* Fetch the Ue */
1722    if ((*ue = rgDBMGetUeCb(*cell, lcCfg->crnti)) == NULLP)
1723    {
1724       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"UE  does not exist for dedicated logical channel %d",
1725                 lcCfg->lcId);
1726       RETVALUE(RFAILED);
1727    }
1728
1729    /* Validate logical channel Id */
1730    if ((lcCfg->lcId < RG_DEDLC_MIN_LCID)
1731             ||(lcCfg->lcId > RG_DEDLC_MAX_LCID))
1732    {
1733       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Invalid logical channel Id %d",
1734                 lcCfg->lcId);
1735       RETVALUE(RFAILED);
1736    }
1737
1738    /* Validate downlink info */
1739    if (lcCfg->dir & CRG_DIR_TX)
1740    {
1741       if (rgDBMGetDlDedLcCb((*ue), lcCfg->lcId) != NULLP)
1742       {
1743          RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"UE: Dedicated DL LC %d already configured",
1744                     lcCfg->lcId);
1745          RETVALUE(RFAILED);
1746       }
1747       dirVld = TRUE;
1748    }
1749
1750    /* Validate uplink info */
1751    if (lcCfg->dir & CRG_DIR_RX)
1752    {
1753       if (lcCfg->ulInfo.lcgId > (RG_MAX_LCG_PER_UE - 1))
1754       {
1755          RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"UE: Invalid lcgId for uplink logical channel %d",
1756                    lcCfg->ulInfo.lcgId);
1757          RETVALUE(RFAILED);
1758       }
1759       if (rgDBMGetUlDedLcCb((*ue), lcCfg->lcId) != NULLP)
1760       {
1761          RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"UE: Dedicated UL LC %d already configured",
1762                    lcCfg->lcId);
1763          RETVALUE(RFAILED);
1764       }
1765       dirVld = TRUE;
1766    }
1767
1768    if (!dirVld)
1769    {
1770       RLOG_ARG1(L_ERROR,DBG_CRNTI,lcCfg->crnti,"Invalid Direction %d",
1771                lcCfg->dir);
1772       RETVALUE(RFAILED);
1773    }
1774
1775    RETVALUE(ROK);
1776 }  /* rgCFGVldtCrgDedLcCfg */
1777
1778
1779 /***********************************************************
1780  *
1781  *     Func : rgCFGVldtCrgCmnLcCfg
1782  *
1783  *
1784  *     Desc : Validates common logical channel configuration recieved from RRC.
1785  *
1786  *     Ret  : S16
1787  *            ROK - Success
1788  *            RFAILED - Failed
1789  *
1790  *     Notes:
1791  *
1792  *     File :
1793  *
1794  **********************************************************/
1795 #ifdef ANSI
1796 PRIVATE S16 rgCFGVldtCrgCmnLcCfg
1797 (
1798 Inst          inst,
1799 CrgLchCfg     *lcCfg,
1800 RgCellCb      **cell,
1801 RgErrInfo     *errInfo
1802 )
1803 #else
1804 PRIVATE S16 rgCFGVldtCrgCmnLcCfg(inst,lcCfg, cell, errInfo)
1805 Inst          inst;
1806 CrgLchCfg     *lcCfg;
1807 RgCellCb      **cell;
1808 RgErrInfo     *errInfo;
1809 #endif
1810 {
1811    U8         dirVld  = FALSE;
1812
1813    TRC2(rgCFGVldtCrgCmnLcCfg);
1814
1815    errInfo->errCause = RGERR_CFG_INVALID_CRG_CMN_LC_CFG;
1816
1817    /* Ensure cell is not in the active list */
1818    if (((*cell = rgCb[inst].cell) != NULLP)
1819       && ((*cell)->cellId != lcCfg->cellId))
1820    {
1821       RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"Active Cell exists for common channels");
1822       RETVALUE(RFAILED);
1823    }
1824
1825    /* Fetch the inactive cell for common logical channels */
1826    if (((*cell = rgCb[inst].inactiveCell) == NULLP)
1827         || ((*cell)->cellId != lcCfg->cellId))
1828    {
1829       
1830       RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"Inactive Cell does not exist for common channels");
1831       RETVALUE(RFAILED);
1832    }
1833    /* Validate downlink info */
1834    if (lcCfg->dir & CRG_DIR_TX)
1835    {
1836       if (lcCfg->lcType == CM_LTE_LCH_BCCH)
1837       {
1838          if (lcCfg->dlInfo.dlTrchType == CM_LTE_TRCH_DL_SCH)
1839          {
1840             if (rgDBMGetBcchOnDlsch(*cell,lcCfg->lcId) != NULLP)
1841             {
1842                RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"BCCH on DLSCH already configured for cell");
1843                RETVALUE(RFAILED);
1844             }
1845          }
1846          else if (lcCfg->dlInfo.dlTrchType == CM_LTE_TRCH_BCH)
1847          {
1848             if (rgDBMGetBcchOnBch(*cell) != NULLP)
1849             {
1850                RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"BCCH on BCH already configured for cell %d");
1851                RETVALUE(RFAILED);
1852             }
1853          }
1854          else
1855          {
1856             RLOG_ARG1(L_ERROR,DBG_CELLID,lcCfg->cellId,"Invalid transport channel %d for cell",
1857                   lcCfg->dlInfo.dlTrchType);
1858             RETVALUE(RFAILED);
1859          }
1860       }
1861       else if (lcCfg->lcType == CM_LTE_LCH_PCCH)
1862       {
1863          if (rgDBMGetPcch(*cell) != NULLP)
1864          {
1865             RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"PCCH already configured for cell");
1866             RETVALUE(RFAILED);
1867          }
1868       }
1869       else if (RG_DLCCCH_ISCFGD(*cell))
1870       {
1871          RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"DL CCCH already configured for cell %d");
1872          RETVALUE(RFAILED);
1873       }
1874       dirVld = TRUE;
1875    }
1876
1877    /* Validate uplink info */
1878    if (lcCfg->dir & CRG_DIR_RX)
1879    {
1880       /* Uplink CCCH */
1881       if (lcCfg->lcType != CM_LTE_LCH_CCCH)
1882       {
1883          RLOG_ARG1(L_ERROR,DBG_CELLID,lcCfg->cellId,"Invalid UL common lcType %d for cell ",
1884                   lcCfg->lcType);
1885          RETVALUE(RFAILED);
1886       }
1887       if (RG_ULCCCH_ISCFGD(*cell))
1888       {
1889          RLOG_ARG0(L_ERROR,DBG_CELLID,lcCfg->cellId,"UL CCCH already configured for cell ");
1890          RETVALUE(RFAILED);
1891       }
1892       dirVld = TRUE;
1893    }
1894
1895    /* Invalid direction */
1896    if (!dirVld)
1897    {
1898       RLOG_ARG1(L_ERROR,DBG_CELLID,lcCfg->cellId,"Invalid Direction %d", lcCfg->dir);
1899       RETVALUE(RFAILED);
1900    }
1901
1902    RETVALUE(ROK);
1903 }  /* rgCFGVldtCrgCmnLcCfg */
1904
1905 /***********************************************************
1906  *
1907  *     Func : rgCFGCrgDedLcCfg
1908  *
1909  *
1910  *     Desc : Handles dedicated logical channel configuration 
1911  *     recieved from RRC.
1912  *
1913  *     Ret  : S16
1914  *            ROK - Success
1915  *            RFAILED - Failed
1916  *
1917  *     Notes:
1918  *
1919  *     File :
1920  *
1921  **********************************************************/
1922 #ifdef ANSI
1923 PRIVATE S16 rgCFGCrgDedLcCfg
1924 (
1925 RgCellCb      *cell,
1926 RgUeCb        *ue,
1927 CrgLchCfg     *lcCfg,
1928 RgErrInfo     *errInfo
1929 )
1930 #else
1931 PRIVATE S16 rgCFGCrgDedLcCfg(cell, ue, lcCfg, errInfo)
1932 RgCellCb      *cell;
1933 RgUeCb        *ue;
1934 CrgLchCfg     *lcCfg;
1935 RgErrInfo     *errInfo;
1936 #endif
1937 {
1938    //Inst     inst = cell->macInst - RG_INST_START;
1939    TRC2(rgCFGCrgDedLcCfg);
1940
1941    errInfo->errCause = RGERR_CFG_CRG_DED_LC_CFG;
1942
1943    /* Uplink/Bi-directional logical channel */
1944    if (lcCfg->dir & CRG_DIR_RX)
1945    {
1946 #ifdef LTE_L2_MEAS
1947       rgDBMInsUlDedLcCb(ue, lcCfg->lcId, lcCfg->ulInfo.lcgId, lcCfg->qci);
1948       cell->qciArray[lcCfg->qci].qci = lcCfg->qci;
1949       if(lcCfg->lcType == CM_LTE_LCH_DTCH)
1950       {
1951         rgAddToL2MeasPerQci(cell,lcCfg->qci);/*LTE_L2_MEAS_PHASE2*/ 
1952       }
1953 #else
1954       rgDBMInsUlDedLcCb(ue, lcCfg->lcId, lcCfg->ulInfo.lcgId);
1955 #endif
1956    }
1957
1958    /* Downlink/Bi-directional logical channel */
1959    if (lcCfg->dir & CRG_DIR_TX)
1960    {
1961       rgDBMInsDlDedLcCb(ue, lcCfg->lcId);
1962    }
1963    RETVALUE(ROK);
1964 }  /* rgCFGCrgDedLcCfg */
1965
1966
1967 /***********************************************************
1968  *
1969  *     Func : rgCFGCrgCmnLcCfg
1970  *
1971  *
1972  *     Desc : Handles dedicated logical channel configuration 
1973  *     recieved from RRC.
1974  *
1975  *     Ret  : S16
1976  *            ROK - Success
1977  *            RFAILED - Failed
1978  *
1979  *     Notes:
1980  *
1981  *     File :
1982  *
1983  **********************************************************/
1984 #ifdef ANSI
1985 PRIVATE S16 rgCFGCrgCmnLcCfg
1986 (
1987 Inst          inst,
1988 RgCellCb      *cell,
1989 CrgLchCfg     *lcCfg,
1990 RgErrInfo     *errInfo
1991 )
1992 #else
1993 PRIVATE S16 rgCFGCrgCmnLcCfg(inst,cell, lcCfg, errInfo)
1994 Inst          inst;
1995 RgCellCb      *cell;
1996 CrgLchCfg     *lcCfg;
1997 RgErrInfo     *errInfo;
1998 #endif
1999 {
2000    TRC2(rgCFGCrgCmnLcCfg);
2001
2002    errInfo->errCause = RGERR_CFG_CRG_CMN_LC_CFG;
2003
2004    /* Handle configuration for CCCH/BCCH/PCCH */
2005    if (lcCfg->lcType == CM_LTE_LCH_CCCH)
2006    {
2007       /* UL and DL CCCH configuration */
2008       if (lcCfg->dir & CRG_DIR_TX)
2009       {
2010          cell->dlCcchId = lcCfg->lcId;
2011          cell->cellActvState |= RG_DL_CCCH_CFG_DONE;
2012       }
2013
2014       if (lcCfg->dir & CRG_DIR_RX)
2015       {
2016          cell->ulCcchId = lcCfg->lcId;
2017          cell->cellActvState |= RG_UL_CCCH_CFG_DONE;
2018       }
2019    }
2020    else
2021    {
2022       if (lcCfg->lcType == CM_LTE_LCH_BCCH)
2023       {
2024          /* BCCH on BCH and DLSCH configuration */
2025          if (lcCfg->dlInfo.dlTrchType == CM_LTE_TRCH_DL_SCH)
2026          {
2027             rgDBMInsBcchOnDlsch(cell, lcCfg->lcId);
2028             
2029             if(cell->cellActvState & RG_BCCH_DLSCH_CFG1_DONE)
2030             {
2031                cell->cellActvState |= RG_BCCH_DLSCH_CFG2_DONE;
2032             }
2033             else
2034             {
2035                cell->cellActvState |= RG_BCCH_DLSCH_CFG1_DONE;
2036             }
2037          }
2038          else
2039          {
2040             rgDBMInsBcchOnBch(cell, lcCfg->lcId);
2041             cell->cellActvState |= RG_BCCH_BCH_CFG_DONE;
2042          }
2043       }
2044       else  /* PCCH configuration */
2045       {
2046          rgDBMInsPcch(cell, lcCfg->lcId);
2047          cell->cellActvState |= RG_PCCH_CFG_DONE;
2048       }
2049    }
2050
2051    /* Add to active cell list if cell is active */
2052    if (cell->cellActvState == RG_CELL_ACTIVE)
2053    {
2054       rgCb[inst].cell = cell;
2055       rgCb[inst].inactiveCell = NULLP;
2056       RLOG_ARG1(L_DEBUG, DBG_CELLID, cell->cellId, "Cell %d added to active list after common LC %d\
2057                config\n", lcCfg->lcId);
2058    }
2059
2060    RETVALUE(ROK);
2061 }  /* rgCFGCrgCmnLcCfg */
2062 #ifdef LTE_L2_MEAS
2063 /***********************************************************
2064  *
2065  *     Func : rgCFGFreeUeUlAlloc 
2066  *
2067  *
2068  *     Desc :
2069  *     - Processing Steps:
2070  *        - Frees cell control block.
2071  *
2072  *     Ret  : Void
2073  *
2074  *     Notes:
2075  *
2076  *     File :
2077  *
2078  **********************************************************/
2079 #ifdef ANSI
2080 PRIVATE Void rgCFGFreeUeUlAlloc
2081 (
2082 RgCellCb      *cell
2083 )
2084 #else
2085 PRIVATE Void rgCFGFreeUeUlAlloc(cell)
2086 RgCellCb      *cell;
2087 #endif
2088 {
2089    U8    sfIdx;
2090    Inst inst = cell->macInst - RG_INST_START;
2091    
2092    TRC2(rgCFGFreeUeUlAlloc);
2093
2094    for(sfIdx = 0; sfIdx < RG_NUM_UL_SUB_FRAMES; sfIdx++)
2095    {
2096       if(cell->ulSf[sfIdx].ueUlAllocInfo != NULLP)
2097       {
2098          /*ccpu00117052 - MOD- Passing double pointer for proper
2099           *                    NULLP assignment */
2100          rgFreeSBuf(inst,(Data **)&(cell->ulSf[sfIdx].ueUlAllocInfo), 
2101                (cell->ulSf[sfIdx].numUe * sizeof(RgUeUlAlloc)));
2102       }
2103    }
2104 }/* rgCFGFreeUeUlAlloc */
2105 #endif
2106 /***********************************************************
2107  *
2108  *     Func : rgCFGFreeCellCb
2109  *
2110  *
2111  *     Desc :
2112  *     - Processing Steps:
2113  *        - Frees cell control block.
2114  *
2115  *     Ret  : Void
2116  *
2117  *     Notes:
2118  *
2119  *     File :
2120  *
2121  **********************************************************/
2122 #ifdef ANSI
2123 PUBLIC Void rgCFGFreeCellCb
2124 (
2125 RgCellCb      *cell
2126 )
2127 #else
2128 PUBLIC Void rgCFGFreeCellCb(cell)
2129 RgCellCb      *cell;
2130 #endif
2131 {
2132    Inst inst = cell->macInst - RG_INST_START;
2133    TRC2(rgCFGFreeCellCb);
2134
2135 #ifdef LTE_ADV
2136    RgLaaCellCbDeInit(cell);
2137 #endif
2138    /* Free lists of the cell */
2139 #ifdef LTEMAC_SPS
2140    rgCFGFreeSpsUeLst(cell);
2141 #endif /* LTEMAC_SPS */
2142    rgCFGFreeUeLst(cell);
2143    rgRAMFreeCell(cell);
2144    rgCFGFreeCmnLcLst(cell);
2145 #ifdef LTE_L2_MEAS
2146    rgCFGFreeUeUlAlloc(cell);
2147 #endif
2148    /* ccpu00117052 - MOD - Passing double pointer for proper NULLP 
2149                            assignment */
2150    /* Update satistics */
2151    rgUpdtCellCnt(inst,RG_CFG_DEL);
2152    rgDHMFreeAllTbBufs(inst);
2153
2154    rgFreeSBuf(inst,(Data **)&cell->flowCntrlInd, sizeof(RguFlowCntrlInd));
2155
2156    /* De-allocate the Cell */
2157    rgFreeSBuf(inst,(Data **)&cell, sizeof(*cell));
2158  
2159
2160    RGDBGINFO(inst,(rgPBuf(inst), "Cell freed\n"));
2161
2162   /* Stack Crash Problem for TRACE5 Changes. Added return below */
2163   RETVOID; 
2164 }  /* rgCFGFreeCellCb */
2165
2166
2167 /***********************************************************
2168  *
2169  *     Func : rgCFGFreeInactvCellCb
2170  *
2171  *
2172  *     Desc :
2173  *     - Processing Steps:
2174  *        - Frees inactive cell control block.
2175  *
2176  *     Ret  : Void
2177  *
2178  *     Notes:
2179  *
2180  *     File :
2181  *
2182  **********************************************************/
2183 #ifdef ANSI
2184 PUBLIC Void rgCFGFreeInactvCellCb
2185 (
2186 RgCellCb      *cell
2187 )
2188 #else
2189 PUBLIC Void rgCFGFreeInactvCellCb(cell)
2190 RgCellCb      *cell;
2191 #endif
2192 {
2193    Inst      inst = cell->macInst - RG_INST_START;
2194    TRC2(rgCFGFreeInactvCellCb);
2195    
2196    /* De-initialize the Ue list */
2197    rgDBMDeInitUeCbLst(cell);
2198 #ifdef LTEMAC_SPS
2199    rgDBMDeInitSpsUeCbLst(cell);
2200 #endif
2201
2202    rgCFGFreeCmnLcLst(cell);
2203
2204    rgFreeSBuf(inst, (Data **)&cell->flowCntrlInd, sizeof(RguFlowCntrlInd));
2205    /*ccpu00117052 - MOD- Passing double pointer for proper
2206                         NULLP assignment */
2207    /* De-allocate the Cell */
2208    rgFreeSBuf(inst,(Data **)&cell, sizeof(*cell));
2209
2210    /* Update satistics */
2211    rgUpdtCellCnt(inst,RG_CFG_DEL);
2212
2213
2214   /* Stack Crash Problem for TRACE5 Changes. Added return below */
2215   RETVOID; 
2216 }  /* rgCFGFreeInactvCellCb */
2217
2218
2219 /***********************************************************
2220  *
2221  *     Func : rgCFGFreeUeCb
2222  *
2223  *
2224  *     Desc :
2225  *     - Processing Steps:
2226  *        - Frees UE control block.
2227  *
2228  *     Ret  : Void
2229  *
2230  *     Notes:
2231  *
2232  *     File :
2233  *
2234  **********************************************************/
2235 #ifdef ANSI
2236 PUBLIC Void rgCFGFreeUeCb
2237 (
2238 RgCellCb    *cell,
2239 RgUeCb      *ue
2240 )
2241 #else
2242 PUBLIC Void rgCFGFreeUeCb(cell, ue)
2243 RgCellCb    *cell;
2244 RgUeCb      *ue;
2245 #endif
2246 {
2247    Inst inst = cell->macInst - RG_INST_START;
2248
2249    TRC2(rgCFGFreeUeCb);
2250
2251    rgDHMFreeUe(inst,&ue->dl.hqEnt);
2252
2253    /* ccpu00117052 - MOD - Passing double pointer for proper NULLP
2254                           assignment */
2255    /* De-allocate the Ue */
2256    rgFreeSBuf(inst,(Data **)&ue, sizeof(*ue));
2257
2258    /* Update Statistics */
2259    rgUpdtUeCnt(inst,RG_CFG_DEL);
2260
2261
2262   /* Stack Crash Problem for TRACE5 Changes. Added return below */
2263   RETVOID; 
2264 }  /* rgCFGFreeUeCb */
2265
2266 /***********************************************************
2267  *
2268  *     Func : rgCFGFreeCmnLcLst
2269  *
2270  *
2271  *     Desc :
2272  *     - Processing Steps:
2273  *        - Frees common logical channels in cell control block.
2274  *
2275  *     Ret  : Void
2276  *
2277  *     Notes:
2278  *
2279  *     File :
2280  *
2281  **********************************************************/
2282 #ifdef ANSI
2283 PRIVATE Void rgCFGFreeCmnLcLst
2284 (
2285 RgCellCb      *cell
2286 )
2287 #else
2288 PRIVATE Void rgCFGFreeCmnLcLst(cell)
2289 RgCellCb      *cell;
2290 #endif
2291 {
2292    TRC2(rgCFGFreeCmnLcLst);
2293
2294    rgDBMFreeCmnLcLst(cell);
2295
2296
2297   /* Stack Crash Problem for TRACE5 Changes. Added return below */
2298   RETVOID; 
2299 }  /* rgCFGFreeCmnLcLst */
2300
2301
2302 /***********************************************************
2303  *
2304  *     Func : rgCFGFreeUeLst
2305  *
2306  *
2307  *     Desc :
2308  *     - Processing Steps:
2309  *        - Frees UE list in cell control block.
2310  *
2311  *     Ret  : Void
2312  *
2313  *     Notes:
2314  *
2315  *     File :
2316  *
2317  **********************************************************/
2318 #ifdef ANSI
2319 PRIVATE Void rgCFGFreeUeLst
2320 (
2321 RgCellCb      *cell
2322 )
2323 #else
2324 PRIVATE Void rgCFGFreeUeLst(cell)
2325 RgCellCb      *cell;
2326 #endif
2327 {
2328    RgUeCb     *ue;
2329
2330    TRC2(rgCFGFreeUeLst);
2331
2332    /* Free Ues in the list */
2333    while ((ue = rgDBMGetNextUeCb(cell, NULLP)) != NULLP)
2334    {
2335 #ifdef LTE_ADV
2336       rgDelUeFrmAllSCell(cell,ue);
2337 #endif
2338       rgDBMDelUeCb(cell, ue);
2339       rgCFGFreeUeCb(cell, ue);
2340    }
2341
2342    /* De-initialize the Ue list */
2343    rgDBMDeInitUeCbLst(cell);
2344
2345
2346   /* Stack Crash Problem for TRACE5 Changes. Added return below */
2347   RETVOID; 
2348 }  /* rgCFGFreeUeLst */
2349
2350 #ifdef LTEMAC_SPS
2351 /***********************************************************
2352  *
2353  *     Func : rgCFGFreeSpsUeLst
2354  *
2355  *
2356  *     Desc :
2357  *     - Processing Steps:
2358  *        - Frees Sps UE list in cell control block.
2359  *
2360  *     Ret  : Void
2361  *
2362  *     Notes:
2363  *
2364  *     File :
2365  *
2366  **********************************************************/
2367 #ifdef ANSI
2368 PRIVATE Void rgCFGFreeSpsUeLst
2369 (
2370 RgCellCb      *cell
2371 )
2372 #else
2373 PRIVATE Void rgCFGFreeSpsUeLst(cell)
2374 RgCellCb      *cell;
2375 #endif
2376 {
2377    RgUeCb     *ue;
2378
2379    TRC2(rgCFGFreeSpsUeLst);
2380
2381    /* Free Ues in the list */
2382    while ((ue = rgDBMGetNextSpsUeCb(cell, NULLP)))
2383    {
2384       rgDBMDelSpsUeCb(cell, ue);
2385    }
2386
2387    /* De-initialize the Ue list */
2388    rgDBMDeInitSpsUeCbLst(cell);
2389
2390 }  /* rgCFGFreeSpsUeLst */
2391
2392 #endif /* LTEMAC_SPS */
2393
2394 /**
2395  * @brief Function for registering cell- scheduler instance mapping
2396  *
2397  * @details
2398  *
2399  *     Function : RgSchMacCellRegReq
2400  *     
2401  *     This function shall be invoked whenever scheduler is done with the
2402  *     cell configuration successfully.
2403  *     This shall create a mapping of the cell, scheduler instance that
2404  *     is serving the cell and the unique identifier of the cell on the 
2405  *     scheduler at MAC. This mapping shall be used for further 
2406  *     communication to the scheduler instance for this cell.
2407  *     
2408  *           
2409  *  @param[in] Pst*                pst,
2410  *  @param[in] CmLteCellId         cellId,
2411  *  @param[in] RaRespReqInfo       raRespReq
2412  *  @return  S16
2413  *      -# ROK 
2414  **/
2415 #ifdef ANSI
2416 PUBLIC S16 RgSchMacCellRegReq
2417 (
2418 Pst*                pst,
2419 RgInfCellReg*       regReq 
2420 )
2421 #else
2422 PUBLIC S16 RgSchMacCellRegReq(pst, regReq)
2423 Pst*                pst;
2424 RgInfCellReg*       regReq;
2425 #endif
2426 {
2427    Inst      inst;
2428    RgCellCb *cell = NULLP;
2429
2430    TRC3(RgSchMacCellRegReq)
2431
2432    RG_IS_INST_VALID(pst->dstInst);
2433    inst = pst->dstInst - RG_INST_START;
2434    cell = rgCb[inst].cell;
2435
2436    if(NULLP == regReq)
2437    {
2438       RETVALUE(RFAILED);
2439    }
2440       
2441    if((cell  == NULLP) || (cell->cellId != regReq->cellId))
2442    {
2443       RETVALUE(RFAILED);
2444    }
2445    if(regReq->maxDlHqProcPerUe > RG_MAX_DL_HARQ_NUM) 
2446    {
2447       RETVALUE(RFAILED);
2448    }
2449    /* Initialize */
2450    cell->schInstMap.cellSapId = regReq->cellSapId;
2451    cell->schInstMap.schInst   = pst->srcInst;
2452    cell->maxDlHqProcPerUe = regReq->maxDlHqProcPerUe;
2453
2454    RETVALUE(ROK);
2455
2456 } /* end of RgSchMacCellRegReq */
2457
2458 /*Added Ue for Onging L2 Meas*/
2459 #ifdef LTE_L2_MEAS
2460 /*LTE_L2_MEAS_PHASE2*/
2461 PUBLIC S16 rgAddToL2MeasPerQci(RgCellCb  *cell,U8 qci)
2462 {
2463  S16      ret = ROK;    
2464  CmLList   *lnk;
2465  RgL2MeasCb  *measCb;
2466  U16          idx;
2467  
2468  lnk = cell->l2mList.first;
2469   while(lnk != NULLP )
2470    {
2471       measCb = (RgL2MeasCb *)lnk->node;
2472       if(measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL)
2473       {
2474               for(idx = 0;idx< measCb->measReq.t.prbReq.numQci;idx++)
2475               {
2476                       if(measCb->measReq.t.prbReq.qci[idx] == qci)
2477                       {
2478                               break; /*exit from for loop*/
2479                       } 
2480               } 
2481               if(idx == measCb->measReq.t.prbReq.numQci)
2482               {
2483                       cell->qciArray[qci].mask = TRUE; 
2484                       measCb->measReq.t.prbReq.qci[measCb->measReq.t.prbReq.numQci++] = qci;
2485               }         
2486       }           
2487       lnk = lnk->next;
2488    }  /* End of While*/
2489  
2490                  
2491        
2492  RETVALUE(ret);
2493 }
2494
2495
2496 #endif
2497
2498 /**********************************************************************
2499  
2500          End of file
2501 **********************************************************************/