Merge "Restructure O1 module to run as a thread in O-DU High binary [Issue-Id: ODUHIG...
[o-du/l2.git] / src / 5gnrmac / rg_lmm.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 Layer Manager Interface Module 
26   
27      File:     rg_lmm.c 
28   
29 **********************************************************************/
30
31 /** @file rg_lmm.c
32 @brief This file contains the Layer Management interface module implementation.
33        The functions for the configuration, control, status and statistics 
34        request primitives are defined here.
35 */
36
37 /* header include files (.h) */
38 #include "common_def.h"
39 #include "rg_env.h"        /* MAC Environment Defines */
40 #include "crg.h"           /* CRG Interface defines */
41 #include "rgu.h"           /* RGU Interface defines */
42 #include "tfu.h"           /* RGU Interface defines */
43 #include "rg_sch_inf.h"    /* RGR Interface defines */
44 #include "lrg.h"           /* LRG Interface defines */
45 #include "rgr.h"           /* LRG Interface defines */
46 #include "rg.h"            /* MAC defines */
47 #include "rg_err.h"        /* MAC error defines */
48
49 /* header/extern include files (.x) */
50 #include "crg.x"           /* CRG Interface includes */
51 #include "rgu.x"           /* RGU Interface includes */
52 #include "tfu.x"           /* RGU Interface includes */
53 #include "rg_sch_inf.x"    /* SCH Interface includes */
54 #include "rg_prg.x"    /* PRG Interface includes */
55 #include "lrg.x"           /* LRG Interface includes */
56 #include "rgr.x"           /* LRG Interface includes */
57 #include "du_app_mac_inf.h"
58 #include "rg.x"            /* MAC includes */
59 #ifdef SS_DIAG
60 #include "ss_diag.h"        /* Common log file */
61 #endif
62 #include "ss_rbuf.h"
63 #include "ss_rbuf.x"
64 #include "mac_sch_interface.h"
65 #include "lwr_mac_upr_inf.h"
66 #include "mac.h"
67 #include "lwr_mac_fsm.h"
68 #include "lwr_mac_phy.h"
69
70 #ifdef __cplusplus
71 extern "C" {
72 #endif /* __cplusplus */
73 Void rgGetSId ARGS((SystemId *s));
74 #ifdef __cplusplus
75 }
76 #endif /* __cplusplus */
77
78 /* Public variable declaration */
79 MacCb  macCb;
80
81 /* forward references */
82 static uint16_t rgLMMGenCfg ARGS((
83    Inst           inst,
84    RgCfg          *cfg           
85 ));
86
87 static uint16_t rgLMMSapCfg ARGS((
88    Inst           inst,
89    RgCfg          *cfg,
90    Elmnt          sapType
91 ));
92
93 static Void rgLMMShutdown ARGS((
94    Inst           inst
95 ));
96
97 static Void rgLMMFillCfmPst ARGS((
98    Pst           *reqPst,
99    Pst           *cfmPst,
100    RgMngmt       *cfm
101 ));
102
103 static Void rgLMMGenCntrl ARGS((
104 RgMngmt       *cntrl,
105 RgMngmt       *cfm,
106 Pst           *cfmPst
107 ));
108
109 static Void rgLMMSapCntrl ARGS((
110 RgMngmt       *cntrl,
111 RgMngmt       *cfm,
112 Pst           *cfmPst
113 ));
114
115 \f
116 /**
117  * @brief Task Initiation callback function. 
118  *
119  * @details
120  *
121  *     Function : rgActvInit
122  *     
123  *     This function is supplied as one of parameters during MAC's 
124  *     task registration. SSI will invoke this function once, after
125  *     it creates and attaches this TAPA Task to a system task.
126  *     
127  *  @param[in]  Ent entity, the entity ID of this task.     
128  *  @param[in]  Inst inst, the instance ID of this task.
129  *  @param[in]  Region region, the region ID registered for memory 
130  *              usage of this task.
131  *  @param[in]  Reason reason.
132  *  @return  S16
133  *      -# ROK
134  **/
135 S16 rgActvInit
136 (
137 Ent entity,            /* entity */
138 Inst inst,             /* instance */
139 Region region,         /* region */
140 Reason reason          /* reason */
141 )
142 {
143    Inst macInst ;
144
145    RG_IS_INST_VALID(inst);
146
147    macInst = inst - RG_INST_START;
148    /* Initialize the MAC TskInit structure to zero */
149    memset (&rgCb[macInst], 0, sizeof(RgCb));
150
151    /* Initialize the MAC TskInit with received values */
152    rgCb[macInst].rgInit.ent = entity;
153    rgCb[macInst].rgInit.inst = inst;
154    rgCb[macInst].rgInit.region = region;
155    rgCb[macInst].rgInit.pool = 0;
156    rgCb[macInst].rgInit.reason = reason;
157    rgCb[macInst].rgInit.cfgDone = FALSE;
158    rgCb[macInst].rgInit.acnt = FALSE;
159    rgCb[macInst].rgInit.usta = FALSE;
160    rgCb[macInst].rgInit.trc = FALSE;
161    rgCb[macInst].trcLen = 0; 
162 #ifdef DEBUGP
163 #ifdef RG_DEBUG
164    /* disabling debugs by default */
165    rgCb[macInst].rgInit.dbgMask = 0xffffffff; 
166 #endif
167 #endif /* DEBUGP */
168 #ifdef SS_DIAG
169    rgCb[macInst].rgInit.logMask = 0x0;
170 #endif
171    rgCb[macInst].rgInit.procId = SFndProcId();
172    rgCb[macInst].tfuSap.numBndRetries = 0;
173
174    /* Initialize Sap state */
175    rgCb[macInst].tfuSap.sapSta.sapState = LRG_NOT_CFG;
176    rgCb[macInst].crgSap.sapSta.sapState = LRG_NOT_CFG;
177    rgCb[macInst].rguSap = NULLP;
178    rgCb[macInst].crgSap.sapSta.sapState = LRG_NOT_CFG;
179
180    rgCb[macInst].inactiveCell = NULLP;
181    rgCb[macInst].cell         = NULLP;
182 #ifdef SS_RBUF
183    SAttachSRngBuf(SS_RNG_BUF_ULMAC_TO_ULRLC, SS_RBUF_ENT_ULMAC,SS_RNG_TX);
184    SAttachSRngBuf(SS_RNG_BUF_ULMAC_TO_ULRLC, SS_RBUF_ENT_ULRLC,SS_RNG_RX);
185 #endif
186
187    /* Initialize Scheduler as well */
188    schActvInit(ENTMAC, (DEFAULT_CELLS + SCH_INST_START), DFLT_REGION, PWR_UP);
189
190    /* Initialize lower mac */
191    lwrMacLayerInit(region, 0);
192
193    return ROK;
194
195 } /* rgActvInit */
196 \f
197 /**
198  * @brief Layer Manager Configuration request handler. 
199  *
200  * @details
201  *
202  *     Function : RgMiLrgCfgReq
203  *     
204  *     This function handles the configuration
205  *     request received from the Layer Manager.
206  *     -# Based on the cfg->hdr.elmId.elmnt value it invokes one of the
207  *        functions rgHdlGenCfg() or rgHdlSapCfg().
208  *     -# Invokes RgMiLrgCfgCfm() to send back the confirmation to the LM.
209  *     
210  *  @param[in]  Pst *pst, the post structure     
211  *  @param[in]  RgMngmt *cfg, the configuration parameter's structure
212  *  @return  S16
213  *      -# ROK
214  **/
215 S16 RgMiLrgCfgReq
216 (
217 Pst      *pst,    /* post structure  */
218 RgMngmt  *cfg     /* config structure  */
219 )
220 {
221    uint16_t  ret = LCM_PRIM_OK;
222    uint16_t  reason = LCM_REASON_NOT_APPL;
223    RgMngmt   cfm;
224    Pst       cfmPst;
225    Inst      inst;
226
227
228
229    DU_LOG("\nINFO  -->  MAC : Received CfgReq for MAC layer, Entity = %d, Instance = %d", pst->srcEnt, pst->srcInst);
230
231    RG_IS_INST_VALID(pst->dstInst);
232    inst = pst->dstInst - RG_INST_START;
233
234    /* Fill the post structure for sending the confirmation */
235    rgLMMFillCfmPst(pst, &cfmPst, cfg);
236
237    memset(&cfm, 0, sizeof(RgMngmt));
238
239 #ifdef LMINT3
240    cfm.hdr.transId = cfg->hdr.transId;
241 #endif
242
243
244    cfm.hdr.elmId.elmnt = cfg->hdr.elmId.elmnt;
245    switch(cfg->hdr.elmId.elmnt)
246    {
247       case STGEN:
248 #ifdef INTEL_WLS_MEM
249          /* Start WLS message receiver thread */
250          LwrMacStartWlsRcvr();
251 #endif
252          reason = rgLMMGenCfg(inst,&cfg->t.cfg); 
253          break;
254       case STRGUSAP:
255       case STCRGSAP:
256       case STTFUSAP:
257          reason = rgLMMSapCfg(inst,&cfg->t.cfg, cfg->hdr.elmId.elmnt);
258          break;
259       default:
260          ret = LCM_PRIM_NOK;
261          reason = LCM_REASON_INVALID_ELMNT;
262          DU_LOG("\nERROR  -->  MAC : Invalid Elmnt=%d",
263                cfg->hdr.elmId.elmnt);
264          break;
265    }
266
267    if (reason != LCM_REASON_NOT_APPL)
268    {
269       ret = LCM_PRIM_NOK;
270    }
271
272    cfm.cfm.status = ret;
273    cfm.cfm.reason = reason;
274
275    RgMiLrgCfgCfm(&cfmPst, &cfm);
276
277    return ROK;
278 }/*-- RgMiLrgCfgReq --*/
279
280 \f
281 /**
282  * @brief Layer Manager Statistics request handler. 
283  *
284  * @details
285  *
286  *     Function : RgMiLrgStsReq
287  *     
288  *     This function handles the statistics
289  *     request received from the Layer Manager.
290  *      -# Based on sts->hdr.elmId.elmnt, it retrieves either general or SAP
291  *      statistics from the rgCb global control block.
292  *      -# If action=ARST, it will reset the statistics parameters in rgCb to 0.
293  *      -# Invokes the RgMiLrgStsCfm to send back the confirmation to LM.
294  *     
295  *  @param[in]  Pst *pst, the post structure     
296  *  @param[in]  RgMngmt *sts, the statistics parameter's structure
297  *  @return  S16
298  *      -# ROK
299  **/
300 S16 RgMiLrgStsReq
301 (
302 Pst      *pst,    /* post structure  */
303 RgMngmt  *sts     /* statistics structure  */
304 )
305 {
306    Pst       cfmPst;
307    RgMngmt   cfm;
308    Inst      inst;
309
310    RG_IS_INST_VALID(pst->dstInst);
311    inst = pst->dstInst - RG_INST_START;
312    /* Fill the post structure for sending the confirmation */
313    rgLMMFillCfmPst(pst, &cfmPst, sts);
314
315    memset(&cfm, 0, sizeof(RgMngmt));
316
317 #ifdef LMINT3
318    cfm.hdr.transId = sts->hdr.transId;
319 #endif
320    SGetDateTime(&cfm.t.sts.dt);
321    cfm.cfm.status = LCM_PRIM_OK;
322    cfm.cfm.reason = LCM_REASON_NOT_APPL;
323    cfm.hdr.elmId.elmnt = sts->hdr.elmId.elmnt;
324    cfm.t.sts.action = sts->t.sts.action;
325
326    /* Check if General Config Done */
327    if(rgCb[inst].rgInit.cfgDone != TRUE) 
328    {
329       cfm.cfm.status = LCM_PRIM_NOK;
330       cfm.cfm.reason = LCM_REASON_GENCFG_NOT_DONE;
331       RgMiLrgStsCfm(&cfmPst,&cfm);
332       DU_LOG("\nERROR  -->  MAC : Gen Cfg not done");
333       return ROK;
334    }
335
336    switch(sts->hdr.elmId.elmnt)
337    {
338       case STGEN:
339          {
340             memcpy(&(cfm.t.sts.s.genSts), &rgCb[inst].genSts,
341                   sizeof(RgGenSts));
342             /* check if action is read and reset */
343             if(sts->t.sts.action == ARST)
344             {
345                rgCb[inst].genSts.numHarqFail = 0;
346             }
347             /* L2 statistics */
348 #ifdef MAC_SCH_STATS
349             {
350                RgGenSts *genSts = &(cfm.t.sts.s.genSts);
351                uint8_t       cqi = 0;
352                for(cqi=0; cqi <= 14; cqi++)
353                {
354                   /* Filling DL ACK/NACK stats */
355                   genSts->nackAckStats.dlCqiStat[cqi].mcs = \
356                      hqFailStats.dlCqiStat[cqi].mcs;
357                   genSts->nackAckStats.dlCqiStat[cqi].numOfNacks = \
358                      hqFailStats.dlCqiStat[cqi].numOfNacks;
359                   genSts->nackAckStats.dlCqiStat[cqi].numOfAcks = 
360                      hqFailStats.dlCqiStat[cqi].numOfAcks;
361
362                   /* Filling UL ACK/NACK stats */
363                   genSts->nackAckStats.ulCqiStat[cqi].mcs = \
364                      hqFailStats.ulCqiStat[cqi].mcs;
365                   genSts->nackAckStats.ulCqiStat[cqi].numOfNacks = \
366                      hqFailStats.ulCqiStat[cqi].numOfNacks;
367                   genSts->nackAckStats.ulCqiStat[cqi].numOfAcks = \
368                      hqFailStats.ulCqiStat[cqi].numOfAcks;
369
370                   /* Filling DL HQ Retx stats */
371                   genSts->hqRetxStats.dlCqiStat[cqi].mcs = \
372                      hqRetxStats.dlCqiStat[cqi].mcs;
373                   genSts->hqRetxStats.dlCqiStat[cqi].numOfHQ_1 = \
374                      hqRetxStats.dlCqiStat[cqi].numOfHQ_1;
375                   genSts->hqRetxStats.dlCqiStat[cqi].numOfHQ_2 = \
376                      hqRetxStats.dlCqiStat[cqi].numOfHQ_2;
377                   genSts->hqRetxStats.dlCqiStat[cqi].numOfHQ_3 = \
378                      hqRetxStats.dlCqiStat[cqi].numOfHQ_3;
379                   genSts->hqRetxStats.dlCqiStat[cqi].numOfHQ_4 = \
380                      hqRetxStats.dlCqiStat[cqi].numOfHQ_4;
381                   genSts->hqRetxStats.dlCqiStat[cqi].totalTx = \
382                      hqRetxStats.dlCqiStat[cqi].totalTx;
383
384                   /* Filling UL HQ Retx stats */
385                   genSts->hqRetxStats.ulCqiStat[cqi].mcs = \
386                      hqRetxStats.ulCqiStat[cqi].mcs;
387                   genSts->hqRetxStats.ulCqiStat[cqi].numOfHQ_1 = \
388                      hqRetxStats.ulCqiStat[cqi].numOfHQ_1;
389                   genSts->hqRetxStats.ulCqiStat[cqi].numOfHQ_2 = \
390                      hqRetxStats.ulCqiStat[cqi].numOfHQ_2;
391                   genSts->hqRetxStats.ulCqiStat[cqi].numOfHQ_3 = \
392                      hqRetxStats.ulCqiStat[cqi].numOfHQ_3;
393                   genSts->hqRetxStats.ulCqiStat[cqi].numOfHQ_4 = \
394                      hqRetxStats.ulCqiStat[cqi].numOfHQ_4;
395                   genSts->hqRetxStats.ulCqiStat[cqi].totalTx = \
396                      hqRetxStats.ulCqiStat[cqi].totalTx;
397                }
398                /* Reset statistics */
399                if(sts->t.sts.action == ZEROSTS)
400                {
401                   memset(&hqRetxStats, 0, \
402                         sizeof(RgSchHqRetxStats));
403                   memset(&hqFailStats, 0, \
404                         sizeof(RgSchNackAckStats));
405                }
406             }
407 #endif /* MAC_SCH_STATS*/
408          }
409          break;
410       case STRGUSAP:
411          memcpy(&(cfm.t.sts.s.rguSts), &rgCb[inst].rguSap[sts->t.sts.sapInst].sapSts,
412                   sizeof(RgSapSts));
413
414          /* check if action is read and reset */
415          if(sts->t.sts.action == ARST)
416             memset(&rgCb[inst].rguSap[sts->t.sts.sapInst].sapSts, 0, sizeof(RgSapSts));
417
418          break;
419       case STCRGSAP:
420          memcpy(&(cfm.t.sts.s.crgSts), &rgCb[inst].crgSap.sapSts,
421                   sizeof(RgSapSts));
422
423          /* check if action is read and reset */
424          if(sts->t.sts.action == ARST)
425             memset(&rgCb[inst].crgSap.sapSts, 0, sizeof(RgSapSts));
426
427          break;
428       case STTFUSAP:
429          memcpy(&(cfm.t.sts.s.tfuSts), &rgCb[inst].tfuSap.sapSts,
430                   sizeof(RgSapSts));
431
432          /* check if action is read and reset */
433          if(sts->t.sts.action == ARST)
434             memset(&rgCb[inst].tfuSap.sapSts, 0, sizeof(RgSapSts));
435
436          break;
437       default:
438          cfm.cfm.status = LCM_PRIM_NOK;
439          cfm.cfm.reason = LCM_REASON_INVALID_ELMNT;
440          DU_LOG("\nERROR  -->  MAC : Invalid Elmnt = %d",sts->hdr.elmId.elmnt);
441          break;     
442    }
443    RgMiLrgStsCfm(&cfmPst,&cfm);
444    return ROK;
445 }/*-- RgMiLrgStsReq --*/
446
447 \f
448 /**
449  * @brief Layer Manager Status request handler. 
450  *
451  * @details
452  *
453  *     Function : RgMiLrgStaReq
454  *     
455  *     This function handles the solicited status
456  *     request received from the Layer Manager.
457  *      -# Based on sta->hdr.elmId.elmnt, it retrieves the status of a
458  *      particular SAP from the rgCb global control block.
459  *      -# Invokes the RgMiLrgStaCfm to send back the confirmation to LM.
460  *     
461  *  @param[in]  Pst *pst, the post structure     
462  *  @param[in]  RgMngmt *sta, the status parameter's structure
463  *  @return  S16
464  *      -# ROK
465  **/
466 S16 RgMiLrgStaReq
467 (
468 Pst      *pst,    /* post structure  */
469 RgMngmt  *sta     /* status structure  */
470 )
471 {
472    Pst       cfmPst;
473    RgMngmt   cfm;
474    Inst      inst ;
475
476
477    RG_IS_INST_VALID(pst->dstInst);
478    inst = pst->dstInst - RG_INST_START;
479
480
481    /* Fill the post structure for sending the confirmation */
482    rgLMMFillCfmPst(pst, &cfmPst, sta);
483
484    if (sta->t.ssta.s.sysId.ptNmb != NULLP)
485    {
486       SPutSBuf(pst->region, pst->pool, (Data *)sta->t.ssta.s.sysId.ptNmb, LRG_MAX_PT_NUM_SIZE);
487    }
488    
489    memset(&cfm, 0, sizeof(RgMngmt));
490    cfm.hdr.elmId.elmnt = sta->hdr.elmId.elmnt;
491
492 #ifdef LMINT3
493    cfm.hdr.transId = sta->hdr.transId;
494 #endif
495    /* Check if General Config Done */
496    if(rgCb[inst].rgInit.cfgDone != TRUE) 
497    {
498       SGetDateTime(&cfm.t.ssta.dt);
499       if (SGetSBuf(cfmPst.region, cfmPst.pool, 
500                (Data **)&(cfm.t.ssta.s.sysId.ptNmb), LRG_MAX_PT_NUM_SIZE)
501             != ROK)
502       {
503          DU_LOG("\nERROR  -->  MAC : Memory Unavailable for Confirmation");
504          return ROK;
505       } 
506       memset((cfm.t.ssta.s.sysId.ptNmb), 0, LRG_MAX_PT_NUM_SIZE);
507       rgGetSId(&cfm.t.ssta.s.sysId);
508       cfm.cfm.status = LCM_PRIM_NOK;
509       cfm.cfm.reason = LCM_REASON_GENCFG_NOT_DONE;
510       cfm.hdr.elmId.elmnt = sta->hdr.elmId.elmnt;
511       RgMiLrgStaCfm(&cfmPst, &cfm);
512       DU_LOG("\nERROR  -->  MAC : Gen Cfg not done");
513       return ROK;
514    }
515
516    switch(sta->hdr.elmId.elmnt)
517    {
518       case STGEN:
519          SGetDateTime(&cfm.t.ssta.dt);
520          if (SGetSBuf(cfmPst.region, cfmPst.pool, 
521              (Data **)&(cfm.t.ssta.s.sysId.ptNmb), LRG_MAX_PT_NUM_SIZE)
522             != ROK)
523          {
524             DU_LOG("\nERROR  -->  MAC : Memory Unavailable for Confirmation");
525             return ROK;
526          } 
527          memset((cfm.t.ssta.s.sysId.ptNmb), 0, LRG_MAX_PT_NUM_SIZE);
528          rgGetSId(&cfm.t.ssta.s.sysId);
529          cfm.cfm.status = LCM_PRIM_OK;
530          cfm.cfm.reason = LCM_REASON_NOT_APPL;
531          RgMiLrgStaCfm(&cfmPst, &cfm);
532          break;
533       case STRGUSAP:
534          cfm.cfm.status = LCM_PRIM_OK;
535          cfm.cfm.reason = LCM_REASON_NOT_APPL;
536          SGetDateTime(&cfm.t.ssta.dt);
537          memcpy(&(cfm.t.ssta.s.rguSapSta), 
538                                 &rgCb[inst].rguSap[sta->t.ssta.sapInst].sapSta,
539             sizeof(RgSapSta));
540          RgMiLrgStaCfm(&cfmPst, &cfm);
541          break;
542       case STCRGSAP:
543          cfm.cfm.status = LCM_PRIM_OK;
544          cfm.cfm.reason = LCM_REASON_NOT_APPL;
545          SGetDateTime(&cfm.t.ssta.dt);
546          memcpy(&(cfm.t.ssta.s.crgSapSta), &rgCb[inst].crgSap.sapSta,
547          sizeof(RgSapSta));
548          RgMiLrgStaCfm(&cfmPst, &cfm);
549          break;
550       case STTFUSAP:
551          cfm.cfm.status = LCM_PRIM_OK;
552          cfm.cfm.reason = LCM_REASON_NOT_APPL;
553          SGetDateTime(&cfm.t.ssta.dt);
554          memcpy(&(cfm.t.ssta.s.tfuSapSta), &rgCb[inst].tfuSap.sapSta,
555          sizeof(RgSapSta));
556          RgMiLrgStaCfm(&cfmPst, &cfm);
557          break;
558       default:
559          cfm.cfm.status = LCM_PRIM_NOK;
560          cfm.cfm.reason = LCM_REASON_INVALID_ELMNT;
561          RgMiLrgStaCfm(&cfmPst, &cfm);
562          DU_LOG("\nERROR  -->  MAC : Invalid elmnt=%d",sta->hdr.elmId.elmnt);
563          break;     
564    }
565    return ROK;
566 }/*-- RgMiLrgStaReq --*/
567
568 \f
569 /**
570  * @brief Layer Manager Control request handler. 
571  *
572  * @details
573  *
574  *     Function : RgMiLrgCntrlReq
575  *     
576  *     This function handles the control
577  *     request received from the Layer Manager.
578  *      -# Based on cntrl->hdr.elmId.elmnt, cntrl->t.cntrl.action
579  *      and cntrl->t.cntrl.subAction, it performs the appropriate control action
580  *      of SAP (enable/disable), Debug (enable/disable), Trace (enable/disable)
581  *      and layer shutdown.
582  *      -# Invokes the RgMiLrgCntrlCfm to send back the confirmation to LM.
583  *     
584  *  @param[in]  Pst *pst, the post structure     
585  *  @param[in]  RgMngmt *cntrl, the control parameter's structure
586  *  @return  S16
587  *      -# ROK
588  **/
589 S16 RgMiLrgCntrlReq
590 (
591 Pst      *pst,    /* post structure  */
592 RgMngmt  *cntrl   /* control structure  */
593 )
594 {
595    S16       ret = ROK;            /* return value */
596    Pst       cfmPst;
597    RgMngmt   cfm;
598    Inst      inst;
599    /* Fill the post structure for sending the confirmation */
600
601    RG_IS_INST_VALID(pst->dstInst);
602    inst = pst->dstInst - RG_INST_START;
603
604    rgLMMFillCfmPst(pst, &cfmPst, cntrl);
605
606    memset(&cfm, 0, sizeof(RgMngmt));
607 #ifdef LMINT3
608    cfm.hdr.transId = cntrl->hdr.transId;
609 #endif
610    cfm.hdr.elmId.elmnt = cntrl->hdr.elmId.elmnt;
611    cfm.t.cntrl.action = cntrl->t.cntrl.action;
612    cfm.t.cntrl.subAction = cntrl->t.cntrl.subAction;
613
614    /* Check if General Config Done*/
615    if(rgCb[inst].rgInit.cfgDone != TRUE)
616    {
617       cfm.cfm.status = LCM_PRIM_NOK;
618       cfm.cfm.reason = LCM_REASON_GENCFG_NOT_DONE;
619       cfm.hdr.elmId.elmnt = cntrl->hdr.elmId.elmnt;
620       RgMiLrgCntrlCfm(&cfmPst, &cfm);
621       DU_LOG("\nERROR  -->  MAC : Gen Cfg not done");
622       return ROK;
623    }
624
625    /* General Config done, process the Control request */   
626    switch(cntrl->hdr.elmId.elmnt)
627    {
628       case STGEN:
629          rgLMMGenCntrl(cntrl, &cfm, &cfmPst);
630          break;
631       case STTFUSAP:
632       case STRGUSAP:
633       case STCRGSAP:
634          rgLMMSapCntrl(cntrl, &cfm, &cfmPst);
635          break;
636       default:
637          cfm.cfm.status = LCM_PRIM_NOK;
638          cfm.cfm.reason = LCM_REASON_INVALID_PAR_VAL;
639          RgMiLrgCntrlCfm(&cfmPst, &cfm);
640          DU_LOG("\nERROR  -->  MAC : invalid elmnt=%d",cntrl->hdr.elmId.elmnt);
641          break;
642    }
643    return (ret);
644 }/*-- RgMiLrgCntrlReq --*/
645
646 \f
647 /**
648  * @brief SAP Configuration Handler. 
649  *
650  * @details
651  *
652  *     Function : rgLMMSapCfg
653  *     
654  *     This function in called by RgMiLrgCfgReq(). It handles the
655  *     interface SAP configuration of the LTE MAC layer. It 
656  *     initializes the sapState to LRG_UNBND. Returns
657  *     reason for success/failure of this function.
658  *     
659  *  @param[in]  Inst        inst
660  *  @param[in]  RgCfg *cfg, the Configuaration information 
661  *  @return  uint16_t
662  *      -# LCM_REASON_GENCFG_NOT_DONE
663  *      -# LCM_REASON_INVALID_SAP
664  *      -# LCM_REASON_NOT_APPL
665  **/
666 static uint16_t rgLMMSapCfg
667 (
668 Inst  inst,
669 RgCfg *cfg,            /* Configuaration information */
670 Elmnt sapType             /* Sap Type */
671 )
672 {
673    uint16_t          ret = LCM_REASON_NOT_APPL;
674    RgLowSapCfgInfo   *lowSapCfg = NULLP;
675    RgUpSapCfgInfo    *upSapCfg = NULLP;
676    RgUpSapCb         *upSapCb  = NULLP;
677
678
679       /* Check if Gen Config has been done */
680    if(rgCb[inst].rgInit.cfgDone != TRUE)
681          return (LCM_REASON_GENCFG_NOT_DONE);
682
683    switch(sapType)
684    {   
685       case STRGUSAP:
686          if ((cfg->s.rguSap.spId > LRG_MAX_RGU_SAPS) &&
687                (cfg->s.rguSap.selector != ODU_SELECTOR_TC) &&
688                (cfg->s.rguSap.selector != ODU_SELECTOR_LC))
689          {
690             ret = LCM_REASON_INVALID_PAR_VAL;
691             DU_LOG("\nERROR  -->  MAC : unsupported Selector value for RGU");
692             break;
693          }
694          upSapCb = &(rgCb[inst].rguSap[cfg->s.rguSap.spId]);
695          if(upSapCb->sapSta.sapState == LRG_NOT_CFG)
696          { 
697             upSapCb->sapSta.sapState = LRG_UNBND;
698          }
699          upSapCfg = &(upSapCb->sapCfg);
700          upSapCfg->sapPst.dstEnt = cfg->s.rguSap.ent;
701          upSapCfg->sapPst.dstInst = cfg->s.rguSap.inst;
702          upSapCfg->sapPst.dstProcId = cfg->s.rguSap.procId;
703          upSapCfg->sapPst.srcEnt = rgCb[inst].rgInit.ent;
704          upSapCfg->sapPst.srcInst = rgCb[inst].rgInit.inst;
705          upSapCfg->sapPst.srcProcId = rgCb[inst].rgInit.procId;
706          upSapCfg->sapPst.region = cfg->s.rguSap.mem.region;
707          upSapCfg->sapPst.pool = cfg->s.rguSap.mem.pool;
708          upSapCfg->sapPst.selector = cfg->s.rguSap.selector;
709          upSapCfg->sapPst.route = cfg->s.rguSap.route;
710          upSapCfg->sapPst.intfVer = 0; 
711          upSapCfg->sapPst.prior = cfg->s.rguSap.prior;
712          upSapCfg->suId = cfg->s.rguSap.suId;
713          upSapCfg->spId = cfg->s.rguSap.spId;
714          /*T2K uses 2 saps, T3K uses 1 sap. change the rgRguDlSap to 1 only if
715           * there is cfg request with sap is 1*/
716          break;
717       case STCRGSAP:
718          if ((cfg->s.crgSap.selector != ODU_SELECTOR_TC) &&
719                (cfg->s.crgSap.selector != ODU_SELECTOR_LC))
720          {
721             ret = LCM_REASON_INVALID_PAR_VAL;
722             DU_LOG("\nERROR  -->  MAC : unsupported Selector value for CRG");
723             break;
724          }
725          if(rgCb[inst].crgSap.sapSta.sapState == LRG_NOT_CFG)
726          { 
727             rgCb[inst].crgSap.sapSta.sapState = LRG_UNBND;
728          }
729          upSapCfg = &rgCb[inst].crgSap.sapCfg;
730
731          upSapCfg->sapPst.dstEnt = cfg->s.crgSap.ent;
732          upSapCfg->sapPst.dstInst = cfg->s.crgSap.inst;
733          upSapCfg->sapPst.dstProcId = cfg->s.crgSap.procId;
734          upSapCfg->sapPst.srcEnt = rgCb[inst].rgInit.ent;
735          upSapCfg->sapPst.srcInst = rgCb[inst].rgInit.inst;
736          upSapCfg->sapPst.srcProcId = rgCb[inst].rgInit.procId;
737          upSapCfg->sapPst.region = cfg->s.crgSap.mem.region;
738          upSapCfg->sapPst.pool = cfg->s.crgSap.mem.pool;
739          upSapCfg->sapPst.selector = cfg->s.crgSap.selector;
740          upSapCfg->sapPst.route = cfg->s.crgSap.route;
741          upSapCfg->sapPst.intfVer = 0; 
742          upSapCfg->sapPst.prior = cfg->s.crgSap.prior;
743          upSapCfg->suId = cfg->s.crgSap.suId;
744          upSapCfg->spId = cfg->s.crgSap.spId;
745          break;
746       case STTFUSAP:
747 #ifndef CL_MAC_LWLC 
748          if ((cfg->s.tfuSap.selector != ODU_SELECTOR_TC) &&
749                (cfg->s.tfuSap.selector != ODU_SELECTOR_LC))
750          {
751             ret = LCM_REASON_INVALID_PAR_VAL;
752             DU_LOG("\nERROR  -->  MAC : unsupported Selector value for TFU");
753             break;
754          }
755 #endif
756          if (rgCb[inst].tfuSap.sapSta.sapState == LRG_NOT_CFG) 
757          { 
758             rgCb[inst].tfuSap.sapSta.sapState = LRG_UNBND;
759          }
760          lowSapCfg = &rgCb[inst].tfuSap.sapCfg;
761
762          lowSapCfg->sapPst.dstEnt = cfg->s.tfuSap.ent;
763          lowSapCfg->sapPst.dstInst = cfg->s.tfuSap.inst;
764          lowSapCfg->sapPst.dstProcId = rgCb[inst].rgInit.procId;
765          lowSapCfg->sapPst.srcEnt = rgCb[inst].rgInit.ent;
766          lowSapCfg->sapPst.srcInst = rgCb[inst].rgInit.inst;
767          lowSapCfg->sapPst.srcProcId = rgCb[inst].rgInit.procId;
768          lowSapCfg->sapPst.region = cfg->s.tfuSap.mem.region;
769          lowSapCfg->sapPst.pool = cfg->s.tfuSap.mem.pool;
770          lowSapCfg->sapPst.selector = cfg->s.tfuSap.selector;
771          lowSapCfg->sapPst.route = cfg->s.tfuSap.route;
772          lowSapCfg->sapPst.intfVer = 0; 
773          lowSapCfg->sapPst.prior = cfg->s.tfuSap.prior;
774          lowSapCfg->suId = cfg->s.tfuSap.suId;
775          lowSapCfg->spId = cfg->s.tfuSap.spId;
776          memcpy(&lowSapCfg->bndTmr, &cfg->s.tfuSap.bndTmr,
777                    sizeof(TmrCfg));
778          break;
779       default:
780          /* would never reach here */
781          break;
782    }
783    return (ret);
784 }
785
786 \f
787 /**
788  * @brief General Configuration Handler. 
789  *
790  * @details
791  *
792  *     Function : rgLMMGenCfg
793  *     
794  *     This function in called by RgMiLrgCfgReq(). It handles the
795  *     general configuration of the LTE MAC layer. It initializes 
796  *     the hash lists of RgCb. Returns
797  *     reason for success/failure of this function.
798  *     
799  *  @param[in]  Inst        inst
800  *  @param[in]  RgCfg *cfg, the Configuaration information 
801  *  @return  uint16_t
802  *      -# LCM_REASON_NOT_APPL 
803  *      -# LCM_REASON_INVALID_MSGTYPE
804  *      -# LCM_REASON_MEM_NOAVAIL
805  **/
806 static uint16_t rgLMMGenCfg
807 (
808 Inst inst,
809 RgCfg *cfg            /* Configuaration information */
810 )
811 {
812    uint16_t    ret = LCM_REASON_NOT_APPL;
813
814
815    /* Check if General Configuration is done already */
816    if (rgCb[inst].rgInit.cfgDone == TRUE)
817    {
818       return (LCM_REASON_INVALID_MSGTYPE);
819    }
820    if ((cfg->s.genCfg.lmPst.selector != ODU_SELECTOR_TC) &&
821          (cfg->s.genCfg.lmPst.selector != ODU_SELECTOR_LC))
822    {
823       DU_LOG("\nERROR  -->  MAC : unsupported Selector value for RGU");
824       return (LCM_REASON_INVALID_PAR_VAL);
825    }
826    /* Update the Pst structure for LM interface */
827    memcpy(&rgCb[inst].rgInit.lmPst, &cfg->s.genCfg.lmPst,
828              sizeof(Pst));
829
830    rgCb[inst].rgInit.lmPst.srcProcId = rgCb[inst].rgInit.procId;
831    rgCb[inst].rgInit.lmPst.srcEnt = rgCb[inst].rgInit.ent;
832    rgCb[inst].rgInit.lmPst.srcInst = rgCb[inst].rgInit.inst;
833    rgCb[inst].rgInit.lmPst.event = EVTNONE;
834
835    rgCb[inst].rgInit.region = cfg->s.genCfg.mem.region;
836    rgCb[inst].rgInit.pool = cfg->s.genCfg.mem.pool;
837    rgCb[inst].genCfg.tmrRes = cfg->s.genCfg.tmrRes;
838
839    macCb.tmrRes = cfg->s.genCfg.tmrRes;
840    macCb.macInst = rgCb[inst].rgInit.inst;
841    macCb.procId = rgCb[inst].rgInit.procId;
842
843    /* Initialize SAP States */
844    rgCb[inst].crgSap.sapSta.sapState = LRG_NOT_CFG;
845
846    if(cfg->s.genCfg.numRguSaps == 0)
847    {
848       DU_LOG("\nERROR  -->  MAC : rgGenCfg(): Invalid numRguSap.\n");
849       return RFAILED;
850    }
851
852    /* allocate RGR saps */
853    if (SGetSBuf(rgCb[inst].rgInit.region,
854             rgCb[inst].rgInit.pool,
855             (Data **)&rgCb[inst].rguSap,
856             (sizeof(RgUpSapCb) * cfg->s.genCfg.numRguSaps)) != ROK)
857    {
858       DU_LOG("\nERROR  -->  MAC : rgGenCfg(): Failed to allocate mem for RGU SAP's.\n");
859       return RFAILED;
860    }
861    rgCb[inst].numRguSaps = cfg->s.genCfg.numRguSaps;
862
863    for (int idx = 0; idx < rgCb[inst].numRguSaps; idx++)
864    {
865       rgCb[inst].rguSap[idx].sapSta.sapState = LRG_NOT_CFG;
866       memset(&rgCb[inst].rguSap[idx], 0, sizeof(RgUpSapCb));
867    }
868    rgCb[inst].tfuSap.sapSta.sapState = LRG_NOT_CFG;
869    /* Initialize the timer blocks */
870    cmInitTimers(macCb.tmrBlk, MAX_NUM_TIMER);
871    /* Initialzie the timer queue */   
872    memset(&macCb.tmrTq, 0, sizeof(CmTqType) * MAC_TQ_SIZE);
873    /* Initialize the timer control point */
874    memset(&macCb.tmrTqCp, 0, sizeof(CmTqCp));
875    macCb.tmrTqCp.tmrLen = MAC_TQ_SIZE;
876
877    /* Timer Registration request to SSI */
878    if(ODU_REG_TMR_MT(ENTMAC, macCb.macInst, macCb.tmrRes, macActvTmr) != ROK)
879    {
880
881       DU_LOG("\nERROR  -->  MAC : Failed to register timer");
882
883       SPutSBuf(rgCb[inst].rgInit.region,
884             rgCb[inst].rgInit.pool,
885             (Data *)rgCb[inst].rguSap,
886             (sizeof(RgUpSapCb) * cfg->s.genCfg.numRguSaps));
887
888       return (LCM_REASON_MEM_NOAVAIL);
889    }
890
891    /* Set Config done in TskInit */
892    rgCb[inst].rgInit.cfgDone = TRUE;
893
894    return (ret);
895 }
896
897 \f
898 /***********************************************************
899  *
900  *     Func : rgLMMShutdown
901  *        
902  *
903  *     Desc : Handles the MAC layer shutdown request. Calls 
904  *     rgCFGFreeCellCb(RgCellCb*) to handle each cellCb deallocation.
905  *            
906  *
907  *     Ret  : Void
908  *
909  *     Notes: 
910  *
911  *     File : rg_lmm.c 
912  *
913  **********************************************************/
914 static Void rgLMMShutdown(Inst inst)
915 {
916    RgCellCb   *cell = rgCb[inst].cell;
917    uint8_t    idx;
918
919
920     /* Unbind the TFU Sap */
921    if(rgCb[inst].tfuSap.sapSta.sapState == LRG_WAIT_BNDCFM)
922    {
923       //rgLIMTfuUbndReq(inst,rgCb[inst].tfuSap.sapCfg.spId, LRG_UNBND);
924       if (rgCb[inst].tfuSap.sapCfg.bndTmr.enb == TRUE)
925       {
926          rgLMMStopTmr(inst,RG_BNDREQ_TMR, (PTR)&rgCb[inst].tfuSap); 
927       } 
928       rgCb[inst].tfuSap.sapSta.sapState = LRG_UNBND;
929    }
930    if(rgCb[inst].tfuSap.sapSta.sapState == LRG_BND)
931    {
932       //rgLIMTfuUbndReq(inst,rgCb[inst].tfuSap.sapCfg.spId, LRG_UNBND);
933       rgCb[inst].tfuSap.sapSta.sapState = LRG_UNBND;
934    }
935
936
937    if(cell != NULLP)
938    {
939       for(idx=0;idx < RG_NUM_SUB_FRAMES; idx++)
940       {
941          rgTOMRlsSf(inst,&cell->subFrms[idx]);
942       }
943
944       rgCFGFreeCellCb(cell);
945    }
946
947    /* Deleting the RGU SAPs */
948    SPutSBuf(rgCb[inst].rgInit.region,
949          rgCb[inst].rgInit.pool,
950          (Data *)rgCb[inst].rguSap,
951          (sizeof(RgUpSapCb) * rgCb[inst].numRguSaps));
952    rgCb[inst].rguSap = NULLP;
953
954    rgCb[inst].inactiveCell = NULLP;
955    rgCb[inst].cell         = NULLP;
956
957    /* De-register the Timer Service */
958    (Void) SDeregTmrMt(rgCb[inst].rgInit.ent, rgCb[inst].rgInit.inst,
959          (S16)rgCb[inst].genCfg.tmrRes, macActvTmr); 
960
961    /* call back the task initialization function to intialize
962     * the global RgCb Struct */
963    rgActvInit(rgCb[inst].rgInit.ent, rgCb[inst].rgInit.inst, rgCb[inst].rgInit.region, 
964          rgCb[inst].rgInit.reason);
965
966    return;
967 }
968
969 \f
970 /***********************************************************
971  *
972  *     Func : rgLMMGenCntrl 
973  *        
974  *
975  *     Desc : Processes the LM control request for STGEN elmnt.
976  *            
977  *
978  *     Ret  : Void
979  *
980  *     Notes: 
981  *
982  *     File : rg_lmm.c 
983  *
984  **********************************************************/
985 static Void rgLMMGenCntrl 
986 (
987 RgMngmt       *cntrl,
988 RgMngmt       *cfm,
989 Pst           *cfmPst
990 )
991 {
992    Inst      inst = (cfmPst->srcInst - RG_INST_START);
993
994    cfm->cfm.status = LCM_PRIM_OK;
995    cfm->cfm.reason = LCM_REASON_NOT_APPL;
996
997
998    switch(cntrl->t.cntrl.action)
999    {
1000       case AENA:
1001          /* Action is Enable */
1002          switch(cntrl->t.cntrl.subAction)
1003          {
1004             case SATRC:
1005             /* Enable Traces */
1006                rgCb[inst].rgInit.trc = TRUE;
1007                rgCb[inst].trcLen = cntrl->t.cntrl.s.trcLen;
1008                /*Store the response and TransId for sending the Traces */
1009                memcpy(&rgCb[inst].genCfg.trcResp.response, 
1010                &cntrl->hdr.response, sizeof(Resp));
1011                rgCb[inst].genCfg.trcResp.transId = cntrl->hdr.transId;
1012                
1013                break;
1014             case SAUSTA:   
1015             /* Enable Unsolicited Status (alarms) */
1016                rgCb[inst].rgInit.usta = TRUE;
1017                /*Store the response and TransId for sending the Alarms */
1018                memcpy(&rgCb[inst].genCfg.ustaResp.response, 
1019                &cntrl->hdr.response, sizeof(Resp));
1020                rgCb[inst].genCfg.ustaResp.transId = cntrl->hdr.transId;
1021                break;
1022             case SADBG:
1023             /* Enable Debug Printing */
1024 #ifdef DEBUGP
1025                rgCb[inst].rgInit.dbgMask |= cntrl->t.cntrl.s.rgDbgCntrl.dbgMask;
1026 #endif
1027                break;
1028 #ifdef SS_DIAG
1029             case SALOG:
1030                rgCb[inst].rgInit.logMask = cntrl->t.cntrl.s.logMask;
1031                break;
1032 #endif
1033
1034             default:
1035                cfm->cfm.status = LCM_PRIM_NOK;
1036                cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
1037                DU_LOG("\nERROR  -->  MAC : invalid subaction=%d",cntrl->t.cntrl.subAction);
1038                break;
1039          }
1040          break;
1041       case ADISIMM:
1042          /* Action is Diable immidiately */
1043          switch(cntrl->t.cntrl.subAction)
1044          {
1045             case SATRC:
1046                /* Disable Traces */
1047                rgCb[inst].rgInit.trc = FALSE;
1048                break;
1049             case SAUSTA:
1050                /* Disable Unsolicited Status (alarms) */
1051                rgCb[inst].rgInit.usta = FALSE;
1052                break;
1053             case SADBG:
1054                /* Disable Debug Printing */
1055 #ifdef DEBUGP
1056                rgCb[inst].rgInit.dbgMask &=~cntrl->t.cntrl.s.rgDbgCntrl.dbgMask;
1057 #endif
1058                break;
1059 #ifdef SS_DIAG
1060             case SALOG:
1061                rgCb[inst].rgInit.logMask = cntrl->t.cntrl.s.logMask;
1062                break;
1063 #endif
1064
1065             default:
1066                cfm->cfm.status = LCM_PRIM_NOK;
1067                cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
1068                DU_LOG("\nERROR  -->  MAC : invalid subaction=%d",cntrl->t.cntrl.subAction);
1069                break;
1070          }
1071          break;
1072       case ASHUTDOWN:
1073          /* Free all the memory dynamically allocated by MAC */
1074          rgLMMShutdown(inst);
1075          break;
1076       default:
1077          cfm->cfm.status = LCM_PRIM_NOK;
1078          cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
1079          DU_LOG("\nERROR  -->  MAC : invalid action=%d",cntrl->t.cntrl.action);
1080          break;
1081    }
1082    RgMiLrgCntrlCfm(cfmPst, cfm);
1083    return;
1084 }
1085
1086 \f
1087 /***********************************************************
1088  *
1089  *     Func : rgLMMSapCntrl 
1090  *        
1091  *
1092  *     Desc : Processes the LM control request for STxxxSAP elmnt.
1093  *            
1094  *
1095  *     Ret  : Void
1096  *
1097  *     Notes: 
1098  *
1099  *     File : rg_lmm.c 
1100  *
1101  **********************************************************/
1102 static Void rgLMMSapCntrl 
1103 (
1104 RgMngmt       *cntrl,
1105 RgMngmt       *cfm,
1106 Pst           *cfmPst
1107 )
1108 {
1109    Inst      inst = cfmPst->srcInst - RG_INST_START;
1110
1111    /* Only TFU Sap can be controlled by LM */
1112    switch(cntrl->hdr.elmId.elmnt)
1113    {
1114       case STTFUSAP:
1115          switch(cntrl->t.cntrl.action)
1116          {
1117             case ABND:
1118             /* Bind Enable Request */
1119                if ((rgCb[inst].tfuSap.sapSta.sapState == LRG_NOT_CFG) ||
1120                    (rgCb[inst].tfuSap.sapSta.sapState == LRG_BND))
1121                {
1122                   cfm->cfm.status = LCM_PRIM_NOK;
1123                   cfm->cfm.reason = LCM_REASON_INVALID_SAP;
1124                }
1125                else
1126                {
1127                   if (rgCb[inst].tfuSap.sapCfg.bndTmr.enb == TRUE)
1128                   {
1129                      rgLMMStartTmr(inst,RG_BNDREQ_TMR, rgCb[inst].tfuSap.sapCfg.bndTmr.val, 
1130                      (PTR)&rgCb[inst].tfuSap);
1131                   }
1132                   /* Change SAP state */
1133                   rgCb[inst].tfuSap.sapSta.sapState = LRG_WAIT_BNDCFM;
1134                   rgCb[inst].tfuSap.numBndRetries++;
1135                   /* Store the response and TransId for sending 
1136                    * the Control confirm */
1137                   memcpy(&rgCb[inst].genCfg.bndCfmResp.response,
1138                            &cntrl->hdr.response, sizeof(Resp));
1139                   rgCb[inst].genCfg.bndCfmResp.transId = cntrl->hdr.transId;
1140
1141                   /* Sending Status Indication to Layer Manager */
1142                   cfm->cfm.status = LCM_PRIM_OK_NDONE;
1143                   cfm->cfm.reason = LCM_REASON_NOT_APPL;
1144                   RgMiLrgCntrlCfm(cfmPst, cfm);
1145
1146                   //rgLIMTfuBndReq(inst,rgCb[inst].tfuSap.sapCfg.suId,
1147                                       //rgCb[inst].tfuSap.sapCfg.spId);
1148                   RETVOID;
1149                }
1150                break;
1151             case AUBND:
1152             /* Unbind request */
1153
1154                /* Check if the SAP is configured */
1155                if( (rgCb[inst].tfuSap.sapSta.sapState == LRG_NOT_CFG) ||
1156                      (rgCb[inst].tfuSap.sapSta.sapState == LRG_UNBND))
1157                {
1158                   cfm->cfm.status = LCM_PRIM_NOK;
1159                   cfm->cfm.reason = LCM_REASON_INVALID_MSGTYPE;
1160                }
1161                else
1162                {
1163                   //rgLIMTfuUbndReq(inst,rgCb[inst].tfuSap.sapCfg.spId, TFU_UBNDREQ_MNGMT);
1164                   if (rgCb[inst].tfuSap.sapCfg.bndTmr.enb == TRUE)
1165                   {
1166                      rgLMMStopTmr(inst,RG_BNDREQ_TMR, (PTR)&rgCb[inst].tfuSap);
1167                   }
1168                   /* Change SAP state */
1169                   rgCb[inst].tfuSap.sapSta.sapState = LRG_UNBND;
1170                   cfm->cfm.status = LCM_PRIM_OK;
1171                   cfm->cfm.reason = LCM_REASON_NOT_APPL;
1172                }
1173                break;
1174             case ADEL:
1175                /* Delete SAP, does initialization of SAP */
1176                if ((rgCb[inst].tfuSap.sapSta.sapState == LRG_WAIT_BNDCFM) ||
1177                    (rgCb[inst].tfuSap.sapSta.sapState == LRG_BND))
1178                {
1179                   //rgLIMTfuUbndReq(inst,rgCb[inst].tfuSap.sapCfg.spId, TFU_UBNDREQ_MNGMT);
1180                   if (rgCb[inst].tfuSap.sapCfg.bndTmr.enb == TRUE)
1181                   {
1182                      rgLMMStopTmr(inst,RG_BNDREQ_TMR, (PTR)&rgCb[inst].tfuSap);
1183                   }
1184                }
1185                memset(&rgCb[inst].tfuSap, 0, sizeof(RgLowSapCb));
1186                rgCb[inst].tfuSap.sapSta.sapState = LRG_NOT_CFG;
1187                cfm->cfm.status = LCM_PRIM_OK;
1188                cfm->cfm.reason = LCM_REASON_NOT_APPL;
1189                break;
1190             default:
1191                cfm->cfm.status = LCM_PRIM_NOK;
1192                cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
1193                DU_LOG("\nERROR  -->  MAC : rgLMMSapCntrl(): invalid action=%d",
1194                cntrl->t.cntrl.action);
1195                break;
1196          }
1197          break;
1198       case STRGUSAP:
1199          switch(cntrl->t.cntrl.action)
1200          {
1201             case ADEL:
1202                memset(&rgCb[inst].rguSap[cntrl->t.cntrl.instId], 0, sizeof(RgUpSapCb));
1203                rgCb[inst].rguSap[cntrl->t.cntrl.instId].sapSta.sapState = LRG_NOT_CFG;
1204                cfm->cfm.status = LCM_PRIM_OK;
1205                cfm->cfm.reason = LCM_REASON_NOT_APPL;
1206                break;
1207             default:
1208                cfm->cfm.status = LCM_PRIM_NOK;
1209                cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
1210                DU_LOG("\nERROR  -->  MAC : rgLMMSapCntrl(): invalid action=%d",
1211                cntrl->t.cntrl.action);
1212                break;
1213          }
1214          break;
1215       case STCRGSAP:
1216          switch(cntrl->t.cntrl.action)
1217          {
1218             case ADEL:
1219                memset(&rgCb[inst].crgSap, 0, sizeof(RgUpSapCb));
1220                rgCb[inst].crgSap.sapSta.sapState = LRG_NOT_CFG;
1221                cfm->cfm.status = LCM_PRIM_OK;
1222                cfm->cfm.reason = LCM_REASON_NOT_APPL;
1223                break;
1224             default:
1225                cfm->cfm.status = LCM_PRIM_NOK;
1226                cfm->cfm.reason = LCM_REASON_INVALID_PAR_VAL;
1227                DU_LOG("\nERROR  -->  MAC : invalid action=%d",cntrl->t.cntrl.action);
1228                
1229                break;
1230          }
1231          break;
1232       default:
1233          /* Would never here. */
1234          RETVOID;
1235    }
1236    RgMiLrgCntrlCfm(cfmPst, cfm);
1237    return;
1238 }
1239
1240 \f
1241 /***********************************************************
1242  *
1243  *     Func : rgLMMFillCfmPst 
1244  *        
1245  *
1246  *     Desc : Fills the Confirmation Post Structure cfmPst using the reqPst 
1247  *            and the cfm->hdr.response.
1248  *            
1249  *
1250  *     Ret  : Void
1251  *
1252  *     Notes: 
1253  *
1254  *     File : rg_lmm.c 
1255  *
1256  **********************************************************/
1257 static Void rgLMMFillCfmPst
1258 (
1259 Pst           *reqPst,
1260 Pst           *cfmPst,
1261 RgMngmt       *cfm
1262 )
1263 {
1264    Inst inst;
1265    inst = (reqPst->dstInst - RG_INST_START);
1266
1267    cfmPst->srcEnt    = rgCb[inst].rgInit.ent;
1268    cfmPst->srcInst   = rgCb[inst].rgInit.inst;
1269    cfmPst->srcProcId = rgCb[inst].rgInit.procId;
1270    cfmPst->dstEnt    = reqPst->srcEnt;
1271    cfmPst->dstInst   = reqPst->srcInst;
1272    cfmPst->dstProcId = reqPst->srcProcId;
1273
1274    cfmPst->selector  = cfm->hdr.response.selector;
1275    cfmPst->prior     = cfm->hdr.response.prior;
1276    cfmPst->route     = cfm->hdr.response.route;
1277    cfmPst->region    = cfm->hdr.response.mem.region;
1278    cfmPst->pool      = cfm->hdr.response.mem.pool;
1279
1280    return;
1281 }
1282
1283 \f
1284 /**
1285  * @brief Timer start handler. 
1286  *
1287  * @details
1288  *
1289  *     Function : rgLMMStartTmr
1290  *     
1291  *     This function based on the input parameters starts the timer for 
1292  *     "tmrVal" duration. As of now MAC uses the timer functionality for 
1293  *     BndReq only. Hence there is no conditional code based on "tmrEvnt".
1294  *     
1295  *  @param[in]  Inst        inst
1296  *  @param[in]  S16   tmrEvnt, the Timer Event    
1297  *  @param[in]  uint32_t   tmrVal,  the Wait Time
1298  *  @param[in]  PTR   cb,  Entry for which Timer expired
1299  *  @return  S16
1300  *      -# ROK
1301  **/
1302 S16 rgLMMStartTmr
1303 (
1304 Inst               inst,
1305 S16                tmrEvnt,            /* Timer Event */
1306 uint32_t           tmrVal,             /* Wait Time */
1307 PTR                cb                  /* Entry for which Timer Expired */
1308 )
1309 {
1310    CmTmrArg    arg;
1311
1312
1313       UNUSED(tmrEvnt);
1314
1315    /* Initialize the arg structure */
1316    memset(&arg, 0, sizeof(CmTmrArg));
1317
1318    arg.tqCp = &rgCb[inst].tmrTqCp;
1319    arg.tq = rgCb[inst].tmrTq;
1320    arg.timers = rgCb[inst].tmrBlk;
1321    arg.cb = cb;
1322    arg.tNum = 0;
1323    arg.max = RG_MAX_TIMER;
1324    arg.evnt = RG_BNDREQ_TMR;
1325    arg.wait = tmrVal;      
1326    cmPlcCbTq(&arg);
1327
1328    return ROK;
1329 }
1330
1331 \f
1332 /**
1333  * @brief Timer stop handler. 
1334  *
1335  * @details
1336  *
1337  *     Function : rgLMMStopTmr
1338  *     
1339  *     This function based on the input parameters stops the timer for 
1340  *     "tmrEvnt". As of now MAC uses the timer functionality for 
1341  *     BndReq only. Hence there is no conditional code based on "tmrEvnt".
1342  *     Once the bind happens and this timer is stopped, the timer functionality
1343  *     is deregistered with SSI. As there is no further use of timer processing.
1344  *     
1345  *  @param[in]  Inst        inst
1346  *  @param[in]  S16   tmrEvnt, the Timer Event    
1347  *  @param[in]  PTR   cb,  Entry for which Timer expired
1348  *  @return  S16
1349  *      -# ROK
1350  *      -# RFAILED
1351  **/
1352 S16 rgLMMStopTmr
1353 (
1354 Inst               inst,             /* Scheduler instance */
1355 S16                tmrEvnt,            /* Timer Event */
1356 PTR                cb                  /* Entry for which Timer Expired */
1357 )
1358 {
1359    CmTmrArg   arg;
1360    uint8_t      i;
1361    S16        ret; 
1362
1363
1364    ret = RFAILED;
1365
1366    for(i=0;i<RG_MAX_TIMER;i++)
1367    {
1368       /* Search for the Timer Blocks */
1369       if(rgCb[inst].tmrBlk[i].tmrEvnt == tmrEvnt)
1370       {
1371          /* Initialize the arg structure */
1372          memset(&arg, 0, sizeof(CmTmrArg));
1373
1374          arg.tqCp = &rgCb[inst].tmrTqCp;
1375          arg.tq = rgCb[inst].tmrTq;
1376          arg.timers = rgCb[inst].tmrBlk;
1377          arg.cb = cb;
1378          arg.max = RG_MAX_TIMER;
1379          arg.evnt = NOTUSED;
1380          arg.wait = NOTUSED;
1381
1382          arg.tNum = i;   
1383          cmRmvCbTq(&arg);
1384          ret = ROK;
1385          break;
1386       }
1387
1388    }
1389
1390
1391    return (ret);
1392 }
1393
1394 \f
1395 /**
1396  * @brief Timer Expiry handler. 
1397  *
1398  * @details
1399  *
1400  *     Function : rgLMMTmrExpiry
1401  *     
1402  *     This is a callback function used as an input parameter to cmPrcTmr()
1403  *     to check expiry of any timer. In this function, the only concern is
1404  *     about tmrEvnt=Bind timer.
1405  *     
1406  *  @param[in]  PTR   cb,  Entry for which Timer expired
1407  *  @param[in]  S16   tmrEvnt, the Timer Event    
1408  *  @return  S16
1409  *      -# ROK
1410  **/
1411 S16 rgLMMTmrExpiry
1412 (
1413 PTR cb,               /* Pointer to timer control block */
1414 S16 tmrEvnt           /* Timer Event */
1415 )
1416 {
1417    S16        ret = ROK;
1418    RgLowSapCb *tfuSap = (RgLowSapCb *)cb;
1419    Inst          inst = tfuSap->sapCfg.sapPst.srcInst - RG_INST_START;
1420
1421    switch(tmrEvnt)
1422    {
1423       case RG_BNDREQ_TMR:
1424          tfuSap->numBndRetries++;
1425          if(tfuSap->numBndRetries > RG_MAX_BNDRETRY)
1426          {
1427             rgLMMStaInd(inst,LCM_CATEGORY_INTERFACE, LCM_EVENT_BND_FAIL,
1428                         LCM_CAUSE_TMR_EXPIRED, NULLP);
1429          }
1430          else
1431          {
1432             /* Restart the bind timer */
1433             if (tfuSap->sapCfg.bndTmr.enb == TRUE)
1434             {
1435                ret = rgLMMStartTmr(inst,RG_BNDREQ_TMR, tfuSap->sapCfg.bndTmr.val,
1436                cb);
1437             }
1438
1439             /* Send bind request */
1440             //rgLIMTfuBndReq(inst,rgCb[inst].tfuSap.sapCfg.suId,
1441                                 //rgCb[inst].tfuSap.sapCfg.spId);
1442          }
1443          break;
1444       default:
1445          DU_LOG("\nERROR  -->  MAC : Invalid tmrEvnt=%d",tmrEvnt);
1446          ret = RFAILED;
1447          break;
1448    }
1449    return (ret);
1450 }
1451
1452
1453 \f
1454 /**
1455  * @brief Layer Manager Unsolicited Status Indication generation. 
1456  *
1457  * @details
1458  *
1459  *     Function : rgLMMStaInd 
1460  *     
1461  *     This API is used by the other modules of MAC to send a unsolicited
1462  *     status indication to the Layer Manager.
1463  *     
1464  *  @param[in]  Inst        inst
1465  *  @param[in]  uint16_t category, the Alarm category
1466  *  @param[in]  uint16_t event, the Alarm event
1467  *  @param[in]  uint16_t cause, the cause of the Alarm
1468  *  @param[in]  RgUstaDgn *dgn, Alarm Diagonostics
1469  *  @return  S16
1470  *      -# ROK
1471  **/
1472 S16 rgLMMStaInd
1473 (
1474 Inst inst,
1475 uint16_t category,
1476 uint16_t event,
1477 uint16_t cause,
1478 RgUstaDgn *dgn
1479 )
1480 {
1481    RgMngmt    usta;
1482    if(rgCb[inst].rgInit.usta == FALSE)
1483    {
1484       return ROK;
1485    }
1486
1487    memset(&usta, 0, sizeof(RgMngmt));
1488
1489    SGetDateTime(&usta.t.usta.cmAlarm.dt);
1490    usta.t.usta.cmAlarm.category = category;
1491    usta.t.usta.cmAlarm.event = event;
1492    usta.t.usta.cmAlarm.cause = cause;
1493    if (dgn != NULLP)
1494    {
1495       memcpy(&usta.t.usta.dgn, dgn, sizeof(RgUstaDgn));
1496    }
1497
1498    rgCb[inst].rgInit.lmPst.selector = rgCb[inst].genCfg.ustaResp.response.selector;
1499    rgCb[inst].rgInit.lmPst.prior = rgCb[inst].genCfg.ustaResp.response.prior;
1500    rgCb[inst].rgInit.lmPst.route = rgCb[inst].genCfg.ustaResp.response.route;
1501    rgCb[inst].rgInit.lmPst.region = rgCb[inst].genCfg.ustaResp.response.mem.region;
1502    rgCb[inst].rgInit.lmPst.pool = rgCb[inst].genCfg.ustaResp.response.mem.pool;
1503    usta.hdr.transId = rgCb[inst].genCfg.ustaResp.transId;
1504
1505    return (RgMiLrgStaInd(&rgCb[inst].rgInit.lmPst, &usta));
1506 }
1507
1508 \f
1509 /**
1510  * @brief Layer Manager Trace Indication generation. 
1511  *
1512  * @details
1513  *
1514  *     Function : rgLMMTrcInd 
1515  *     
1516  *     This API is used by the other modules of MAC to send a 
1517  *     Trace indication to the Layer Manager.
1518  *     
1519  *  @param[in]  Inst        inst
1520  *  @param[in]   Buffer *srcMbuf, the Message Buffer .
1521  *  @param[in]   uint8_t event, the trace event.
1522  *  @return Void 
1523  **/
1524 Void rgLMMTrcInd
1525 (
1526 Inst   inst,
1527 Buffer *srcMbuf,    /* Message Buffer */
1528 uint8_t event            /* event */
1529 )
1530 {
1531    Buffer   *dstMbuf = NULLP;   
1532    MsgLen   bufLen  = 0;
1533    Data     *tempBuf;
1534    MsgLen   tempCnt;
1535    RgMngmt  trc;
1536    Pst      pst;
1537
1538
1539
1540    if ((rgCb[inst].trcLen == LRG_NO_TRACE) || (srcMbuf == NULLP))
1541    {
1542       DU_LOG("\nERROR  -->  MAC : Trace Disabled.");
1543       return;
1544    }
1545    
1546    memset(&trc, 0, sizeof(RgMngmt));
1547
1548    pst = rgCb[inst].rgInit.lmPst;
1549    pst.selector = rgCb[inst].genCfg.trcResp.response.selector;
1550    pst.prior = rgCb[inst].genCfg.trcResp.response.prior;
1551    pst.route = rgCb[inst].genCfg.trcResp.response.route;
1552    pst.region = rgCb[inst].genCfg.trcResp.response.mem.region;
1553    pst.pool = rgCb[inst].genCfg.trcResp.response.mem.pool;
1554
1555    trc.hdr.transId = rgCb[inst].genCfg.trcResp.transId;
1556
1557    SGetDateTime(&trc.t.trc.dt);
1558
1559    /* Check if the whole buffer is to be sent in Trace indication */
1560    if(rgCb[inst].trcLen == LRG_FULL_TRACE)
1561    {
1562       if (SCpyMsgMsg(srcMbuf, pst.region, pst.pool, &dstMbuf)
1563             != ROK)
1564       {
1565          DU_LOG("\nERROR  -->  MAC : SCpyMsgMsg Failed.");
1566          return;
1567       }
1568       trc.cfm.status = LCM_PRIM_OK;
1569       trc.cfm.reason = LCM_REASON_NOT_APPL;
1570       trc.t.trc.evnt = event;
1571
1572       /* Send Trace Indication to Layer manager */
1573       RgMiLrgTrcInd(&pst, &trc, dstMbuf);
1574    }
1575    /* check if only a specified number of bytes are to be sent */
1576    else if(rgCb[inst].trcLen > 0)
1577    {
1578       /* Get the length of the recvd message buffer */
1579       if (SFndLenMsg(srcMbuf, &bufLen) != ROK)
1580       {
1581          DU_LOG("\nERROR  -->  MAC : SFndLenMsg Failed.");
1582          return;
1583       }
1584       /* Check if the recvd buffer size is less than request trace len */
1585       if(bufLen < rgCb[inst].trcLen)
1586       {
1587          /* Copy the whole of the recvd buffer in trace indication */
1588
1589          if (SCpyMsgMsg(srcMbuf, pst.region, pst.pool, &dstMbuf)
1590                != ROK)
1591          {
1592             DU_LOG("\nERROR  -->  MAC : SCpyMsgMsg Failed.");
1593             return;
1594          }
1595
1596          trc.cfm.status = LCM_PRIM_OK;
1597          trc.cfm.reason = LCM_REASON_NOT_APPL;
1598          trc.t.trc.evnt = event;
1599
1600          /* Send Trace Indication to Layer manager */
1601          RgMiLrgTrcInd(&pst, &trc, dstMbuf);
1602       }
1603       /* if the recvd buffer size is greater than request trace len */
1604       if(bufLen >= rgCb[inst].trcLen)
1605       {
1606          /* Get a temporary buffer to store the msg */
1607          if (rgAllocSBuf(inst,&tempBuf, rgCb[inst].trcLen) != ROK)
1608          {
1609             DU_LOG("\nERROR  -->  MAC : rgAllocSBuf Failed.");
1610             return;
1611          }
1612
1613          /* Copy trcLen nos of bytes from the recvd message */
1614          if (SCpyMsgFix(srcMbuf,0,rgCb[inst].trcLen,tempBuf,&tempCnt) != ROK)   
1615          {
1616             DU_LOG("\nERROR  -->  MAC : SCpyMsgFix Failed.");
1617             return;
1618          }
1619
1620          if (SGetMsg(pst.region, pst.pool, &dstMbuf) != ROK)
1621          {
1622             DU_LOG("\nERROR  -->  MAC : dstMbuf Allocation Failed");
1623             return;
1624          }
1625          /* Copy the tempBuf data to dst mBuf */
1626          if (SCpyFixMsg(tempBuf,dstMbuf,0,rgCb[inst].trcLen,&tempCnt) != ROK)
1627          {
1628             DU_LOG("\nERROR  -->  MAC : SCpyFixMsg Failed.");
1629             return;
1630          }
1631
1632          /*ccpu00117052 - MOD - Passing double pointer for proper NULLP 
1633            assignment */
1634          /* Free the memory allocated for tempBuf */
1635          rgFreeSBuf(inst,&tempBuf, rgCb[inst].trcLen);
1636
1637          trc.cfm.status = LCM_PRIM_OK;
1638          trc.cfm.reason = LCM_REASON_NOT_APPL;
1639          trc.t.trc.evnt = event;
1640
1641          /* Send Trace Indication to Layer manager */
1642          RgMiLrgTrcInd(&pst, &trc, dstMbuf);
1643       }
1644    }
1645    return;
1646 }
1647
1648 \f
1649 /**
1650  * @brief Layer Manager Control Confirm generation handler
1651  *        for Bind Confirm reception at TFU interface.
1652  *        RgLiTfuBndCfm() forwards the confirmation to this 
1653  *        function. All SAP state related handling is restricted
1654  *        to LMM modules, hence the cfm forwarding.
1655  *
1656  * @details
1657  *
1658  *     Function : rgLMMBndCfm 
1659  *     
1660  *     This API is used by the LIM module of MAC to forward
1661  *     the Bind Confirm it receives over the TFU interface.
1662  *     
1663  *  @param[in]   Pst *pst, Post Structure
1664  *  @param[in]   SuId suId, Service user ID
1665  *  @param[in]   uint8_t status, Status
1666  *  @return  S16
1667  *      -# ROK
1668  **/
1669 S16 rgLMMBndCfm
1670 (
1671 Pst *pst,               /* Post Structure */
1672 SuId suId,              /* Service user ID */
1673 uint8_t status               /* Status */
1674 )
1675 {
1676    Inst      inst = pst->dstInst - RG_INST_START;
1677    S16       ret = ROK;
1678    RgMngmt   cntrlCfm;
1679    Pst       cfmPst;
1680
1681
1682    UNUSED(pst);
1683
1684    /* Check if the suId is valid */
1685    if(rgCb[inst].tfuSap.sapCfg.suId != suId)
1686    {
1687       DU_LOG("\nERROR  -->  MAC : Invalid SuId");
1688       return RFAILED;
1689    }
1690
1691    /* check the Sap State */
1692    switch(rgCb[inst].tfuSap.sapSta.sapState)
1693    {
1694       case LRG_WAIT_BNDCFM:
1695          break;
1696       case LRG_BND:
1697          /* SAP is already bound */
1698          return ROK;
1699       default:
1700          return RFAILED;
1701    }
1702
1703    cfmPst = rgCb[inst].rgInit.lmPst;
1704    cfmPst.selector = rgCb[inst].genCfg.bndCfmResp.response.selector;
1705    cfmPst.prior = rgCb[inst].genCfg.bndCfmResp.response.prior;
1706    cfmPst.route = rgCb[inst].genCfg.bndCfmResp.response.route;
1707    cfmPst.region = rgCb[inst].genCfg.bndCfmResp.response.mem.region;
1708    cfmPst.pool = rgCb[inst].genCfg.bndCfmResp.response.mem.pool;
1709    
1710    memset(&cntrlCfm, 0, sizeof(RgMngmt));
1711
1712    switch(status)
1713    {
1714       case CM_BND_OK: /* status is OK */
1715          /* Change SAP state to Bound */
1716          rgCb[inst].tfuSap.sapSta.sapState = LRG_BND;
1717          if (rgCb[inst].tfuSap.sapCfg.bndTmr.enb == TRUE)
1718          {
1719             ret = rgLMMStopTmr(inst,RG_BNDREQ_TMR, (PTR)&rgCb[inst].tfuSap);
1720          }
1721          /* Send Control Confirm with status as OK to Layer Manager */
1722          cntrlCfm.cfm.status = LCM_PRIM_OK;
1723          cntrlCfm.cfm.reason = LCM_REASON_NOT_APPL;
1724          break;
1725
1726       default:
1727          /* Change SAP state to UnBound */
1728          rgCb[inst].tfuSap.sapSta.sapState = LRG_UNBND;
1729          if (rgCb[inst].tfuSap.sapCfg.bndTmr.enb == TRUE)
1730          {
1731             ret = rgLMMStopTmr(inst,RG_BNDREQ_TMR, (PTR)&rgCb[inst].tfuSap);
1732          }
1733          /* Send Control Confirm with status as NOK to Layer Manager */
1734          cntrlCfm.cfm.status = LCM_PRIM_NOK;
1735          cntrlCfm.cfm.reason = LCM_REASON_NEG_CFM;
1736          break;
1737    }
1738    rgCb[inst].tfuSap.numBndRetries = 0;
1739    cntrlCfm.hdr.elmId.elmnt = STTFUSAP;
1740    cntrlCfm.hdr.transId = rgCb[inst].genCfg.bndCfmResp.transId;
1741
1742    ret = RgMiLrgCntrlCfm(&cfmPst, &cntrlCfm);
1743
1744    return (ret);
1745 }
1746
1747 /**********************************************************************
1748
1749   End of file
1750  **********************************************************************/