Moving all common header file into common_def.h file
[o-du/l2.git] / src / 5gnrmac / rg_lim.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_lim.c 
28   
29 **********************************************************************/
30
31 /** @file rg_lim.c.
32 @brief It has APIs exposed by Lower Interface Modulue of MAC. It acts as an 
33 Interface handler for lower interface APIs.
34 */
35 static const char* RLOG_MODULE_NAME="MAC";
36 static int RLOG_FILE_ID=182;
37 static int RLOG_MODULE_ID=4096;
38 /* header include files -- defines (.h) */
39 #include "common_def.h"
40 #include "rgu.h"           /* RGU defines */
41 #include "tfu.h"           /* RGU defines */
42 #include "lrg.h"           /* layer management defines for LTE-MAC */
43 #include "crg.h"           /* layer management defines for LTE-MAC */
44 #include "rg_sch_inf.h"           /* layer management defines for LTE-MAC */
45 #include "rg_env.h"        /* customisable defines and macros for MAC */
46 #include "rg.h"            /* defines and macros for MAC */
47 #include "du_log.h"
48
49 /* header/extern include files (.x) */
50 #include "rgu.x"           /* RGU types */
51 #include "tfu.x"           /* RGU types */
52 #include "lrg.x"           /* layer management typedefs for MAC */
53 #include "crg.x"           /* layer management typedefs for MAC */
54 #include "rg_sch_inf.x"    /* SCH interface typedefs */
55 #include "rg_prg.x"    /* PRG interface typedefs */
56 #include "du_app_mac_inf.h"
57 #include "rg.x"            /* typedefs for MAC */
58
59 #include "mac_upr_inf_api.h"
60 #include "mac.h"
61
62 /* local externs */
63 #ifdef UNUSED_FUNC
64 PRIVATE S16  rgLIMValidateSap ARGS((Inst inst,SuId suId));
65 #endif
66 PRIVATE Void rgLIMUtlFreeDatIndEvnt ARGS((TfuDatIndInfo *datInd,
67                                           Bool error));
68 #ifdef RG_UNUSED
69 PRIVATE Void rgLIMUtlFreeDatReqEvnt ARGS((TfuDatReqInfo *datReq,
70                                           Bool error));
71 #endif
72 /* forward references */
73
74 /**
75  * @brief This API is invoked to send TFU SAP bind request to PHY.
76  *
77  * @details
78  *
79  *     Function : rgLIMTfuBndReq
80  *      
81  *      This API is invoked to send TFU SAP bind request to PHY. It fills in 
82  *      the Pst structure, spId and suId values and invokes bind request
83  *      primitive at TFU.
84  *           
85  *  @param[in]  Inst        inst
86  *  @param[in]  SuId            suId 
87  *  @param[in]  SpId            spId
88  *  @return  S16
89  *      -# ROK 
90  *      -# RFAILED 
91  **/
92 #ifdef ANSI
93 PUBLIC S16 rgLIMTfuBndReq
94 (
95 Inst    inst,
96 SuId    suId, 
97 SpId    spId
98 )
99 #else
100 PUBLIC S16 rgLIMTfuBndReq(inst,suId, spId)
101 Inst    inst;
102 SuId    suId; 
103 SpId    spId;
104 #endif
105 {
106    S16         ret;
107    RgLowSapCb  *tfuSap;
108    Pst         pst;
109
110    TRC2(rgLIMTfuBndReq);
111
112    /* Get the lower SAP control block from the layer control block. */
113    tfuSap = &(rgCb[inst].tfuSap);
114    (Void)cmMemcpy ((U8*)&pst, (U8*)&(tfuSap->sapCfg.sapPst), sizeof(Pst));
115    if((ret = RgLiTfuBndReq (&pst, suId, spId)) != ROK)
116    {
117       RLOG0(L_ERROR,"Call to RgLiTfuBndReq() failed");
118    }
119    RETVALUE(ret);
120 }  /* rgLIMTfuBndReq */
121
122
123 /**
124  * @brief This API is invoked to send TFU SAP unbind request to PHY.
125  *
126  * @details
127  *
128  *     Function : rgLIMTfuBndReq
129  *      
130  *      This API is invoked to send TFU SAP unbind request to PHY. It fills in 
131  *      the Pst structure and spId value and invokes unbind request
132  *      primitive at TFU.
133  *           
134  *  @param[in]  Inst        inst
135  *  @param[in]  SpId            spId
136  *  @param[in]  Reason          reason 
137  *  @return  S16
138  *      -# ROK 
139  *      -# RFAILED 
140  **/
141 #ifdef ANSI
142 PUBLIC S16 rgLIMTfuUbndReq
143 (
144 Inst    inst,
145 SpId    spId, 
146 Reason  reason
147 )
148 #else
149 PUBLIC S16 rgLIMTfuUbndReq(inst,spId, reason)
150 Inst    inst;
151 SpId    spId; 
152 Reason  reason;
153 #endif
154 {
155    S16         ret;
156    RgLowSapCb  *tfuSap;
157    Pst         pst;
158
159    TRC2(rgLIMTfuUbndReq);
160
161    /* Get the lower SAP control block from the layer control block. */
162    tfuSap = &(rgCb[inst].tfuSap);
163    cmMemcpy ((U8*)&pst, (U8*)&(tfuSap->sapCfg.sapPst), sizeof(Pst));
164    if((ret = RgLiTfuUbndReq (&pst, tfuSap->sapCfg.spId, reason)) != ROK)
165    {
166       RLOG0(L_ERROR,"Call to RgLiTfuUbndReq() failed");
167    }
168    RETVALUE(ret);
169
170 }  /* rgLIMTfuUbndReq */
171
172
173 /**
174  * @brief Bind confirm API for TFU SAP 
175  *
176  * @details
177  *
178  *     Function : RgLiTfuBndCfm
179  *      
180  *      This API is invoked by PHY to confirm TFU SAP bind. 
181  *     
182  *           
183  *  @param[in]  Pst   *pst 
184  *  @param[in]  SuId  suId 
185  *  @param[in]  U8    status
186  *  @return  S16
187  *      -# ROK 
188  *      -# RFAILED 
189  **/
190 #ifdef ANSI
191 PUBLIC S16 RgLiTfuBndCfm 
192 (
193 Pst     *pst,
194 SuId    suId, 
195 U8      status
196 )
197 #else
198 PUBLIC S16 RgLiTfuBndCfm(pst, suId, status)
199 Pst     *pst; 
200 SuId    suId; 
201 U8      status;
202 #endif
203 {
204    Inst inst;
205    S16 ret;
206    RgLowSapCb  *tfuSap;
207
208    TRC3(RgLiTfuBndCfm);
209
210
211    RG_IS_INST_VALID(pst->dstInst);
212    inst = pst->dstInst - RG_INST_START;
213    /* Lets validate suId first */
214    /* CA_Change */
215    tfuSap = &(rgCb[inst].tfuSap);
216
217    if (suId != tfuSap->sapCfg.suId)
218    {
219       RLOG2(L_ERROR,"Incorrect SuId. Configured (%d) Recieved (%d)",
220             tfuSap->sapCfg.suId, suId);
221       RETVALUE(RFAILED);
222    }
223    ret = rgLMMBndCfm (pst, suId, status);
224    RETVALUE(ret);
225 }  /* RgLiTfuBndCfm */
226
227  /** @brief This function Validates the SAP information received along with the
228   * primitive from the lower layer. 
229   * Function:
230   *   Validates SAP information.
231  *  @param[in]  Inst        inst
232   * @param  suId The SAP Id
233   * @return 
234   *   -# ROK
235   *   -# RFAILED
236   */
237 #ifdef UNUSED_FUNC
238 #ifdef ANSI
239 PRIVATE S16 rgLIMValidateSap
240 (
241  Inst    inst,
242  SuId    suId
243 )
244 #else
245 PRIVATE S16 rgLIMValidateSap(inst,suId)
246  Inst    inst;
247  SuId    suId;
248 #endif
249 {
250    RgLowSapCb  *tfuSap;
251
252    TRC2(rgLIMValidateSap)
253
254    tfuSap = &(rgCb[inst].tfuSap);
255
256    /* First lets check the suId */
257    if( suId != tfuSap->sapCfg.suId)
258    {
259       RLOG2(L_ERROR,"Incorrect SuId. Configured (%d) Recieved (%d)",
260             tfuSap->sapCfg.suId, suId);
261       RETVALUE(RFAILED);
262    }
263    if (tfuSap->sapSta.sapState != LRG_BND)
264    {
265       RLOG1(L_ERROR,"Lower SAP not enabled SuId (%d)",
266             tfuSap->sapCfg.suId);
267       RETVALUE(RFAILED);
268    }
269    RETVALUE(ROK);
270 } /* end of rgLIMValidateSap */
271 #endif
272 /** @brief This function frees up the TfuDatIndInfo structure
273  *
274  * @details
275  *
276  *     Function: rgLIMUtlFreeDatIndEvnt 
277  *       - Function frees up the TfuDatIndInfo structure, in case of error it shall
278  *       free up the buffer's present in the datIndLst.
279  *
280  *         Processing steps:
281  * @param  [in] TfuDatIndInfo *datInd
282  * @param  [in] Bool          *error
283  * @return 
284  */
285 #ifdef ANSI
286 PRIVATE Void rgLIMUtlFreeDatIndEvnt 
287 (
288  TfuDatIndInfo *datInd,
289  Bool          error
290  )
291 #else
292 PRIVATE Void rgLIMUtlFreeDatIndEvnt(datInd, error)
293  TfuDatIndInfo *datInd;
294  Bool          error;
295 #endif
296 {
297
298    TfuDatInfo     *datInfo;
299    CmLList        *node;
300
301    TRC2(rgLIMUtlFreeDatIndEvnt);
302    /* Steps of freeing up the TfuDatInd.
303     * 1. loop through the datIndLst and free up all the buffers.
304     * 2. free up the whole event
305     */
306    if ((error == TRUE) && (datInd->datIndLst.count > 0))
307    {
308       node =  datInd->datIndLst.first;
309       while (node)
310       {
311          datInfo = (TfuDatInfo*)node->node;
312          RG_FREE_MSG(datInfo->mBuf);
313          node = node->next;
314       }
315    }
316    RG_FREE_MEM(datInd);
317    RETVOID;
318 } /* end of rgLIMUtlFreeDatIndEvnt*/
319
320 /**
321  * @brief Downlink data indication from PHY.
322  *
323  * @details
324  *
325  *     Function : RgLiTfuDatInd
326  *      
327  *      This API is invoked by PHY to send data indication to MAC on 
328  *      recieving data from UEs.
329  *           
330  *  @param[in]  Pst              *pst
331  *  @param[in]  SuId             suId 
332  *  @param[in]  TfuDatIndInfo    *datInd
333  *  @return  S16
334  *      -# ROK 
335  *      -# RFAILED 
336  **/
337 #ifdef ANSI
338 PUBLIC S16 RgLiTfuDatInd
339 (
340 Pst                *pst, 
341 SuId               suId, 
342 TfuDatIndInfo    *datInd
343 )
344 #else
345 PUBLIC S16 RgLiTfuDatInd(pst, suId, datInd)
346 Pst                *pst; 
347 SuId               suId; 
348 TfuDatIndInfo    *datInd;
349 #endif
350 {
351    Inst             inst;
352    S16              ret;
353    VOLATILE U32     startTime=0;
354
355    TRC3(RgLiTfuDatInd);
356
357   // printf("5GTF:: DatindRcvd\n");
358
359    RG_IS_INST_VALID(pst->dstInst);
360    inst = pst->dstInst - RG_INST_START;
361    /*starting Task*/
362    SStartTask(&startTime, PID_MAC_TFU_DATIND);
363
364 #ifndef NO_ERRCLS 
365    if ((ret = rgLIMValidateSap (inst,suId)) != ROK)
366    {
367       RLOG_ARG0(L_ERROR,DBG_CELLID,datInd->cellId,"SAP Validation failed");
368       rgLIMUtlFreeDatIndEvnt(datInd, TRUE);
369       RETVALUE(ret);
370    }
371 #endif
372    /* Now call the TOM (Tfu ownership module) primitive to process further */
373    rgCb[inst].tfuSap.sapSts.numPduRcvd += 
374                     datInd->datIndLst.count;
375    ret = rgTOMDatInd(inst,datInd);
376    /* Fix: sriky memory corruption precautions */
377    /* Free up the memory for the request structure */
378    if (ret == ROK)
379    {
380       rgLIMUtlFreeDatIndEvnt(datInd, FALSE);
381    }
382    else
383    {
384       rgLIMUtlFreeDatIndEvnt(datInd, TRUE);
385    }
386
387    /*stoping Task*/
388    SStopTask(startTime, PID_MAC_TFU_DATIND);
389
390    RETVALUE(ret);
391 }  /* RgLiTfuDatInd*/
392
393 #ifdef RG_UNUSED
394 /** @brief This function frees up the TfuDatReqInfo structure.
395  *
396  * @details
397  *
398  *     Function: rgLIMUtlFreeDatReqEvnt
399  *       - Function frees up the TfuDatReqInfo structure, in case of error it shall
400  *       free up the buffer's present in the PDUs list.
401  *
402  *         Processing steps:
403  * @param  [in] TfuDatReqInfo *datReq
404  * @param  [in] Bool          *error
405  * @return 
406  */
407 #ifdef ANSI
408 PRIVATE Void rgLIMUtlFreeDatReqEvnt
409 (
410  TfuDatReqInfo *datReq,
411  Bool          error
412  )
413 #else
414 PRIVATE Void rgLIMUtlFreeDatReqEvnt(datReq, error)
415  TfuDatReqInfo *datReq;
416  Bool          error;
417 #endif
418 {
419
420    TfuDatReqPduInfo *datInfo;
421    CmLList          *node;
422    U8               i;
423
424    TRC2(rgLIMUtlFreeDatReqEvnt);
425    /* Steps of freeing up the TfuDatReq.
426     * 1. Free the bch buffer.
427     * 2. loop through the pdus list and free up all the buffers.
428     * 3. free up the whole event
429     */
430    if (error)
431    {
432       if (datReq->bchDat.pres == PRSNT_NODEF)
433       {
434          RG_FREE_MSG(datReq->bchDat.val);
435       }
436       if (datReq->pdus.count > 0)
437       {
438          node =  datReq->pdus.first;
439          while (node)
440          {
441             datInfo = (TfuDatReqPduInfo*)node->node;
442             for (i=0; i<datInfo->nmbOfTBs; i++)
443             {
444                if (datInfo->mBuf[i] != NULLP)
445                {
446                   RG_FREE_MSG(datInfo->mBuf[i]);
447                }
448             }
449             node = node->next;
450          }
451       }
452    }
453    RG_FREE_MEM(datReq);
454    RETVOID;
455 } /* end of rgLIMUtlFreeDatReqEvnt*/
456 #endif
457 /**
458  * @brief This API is invoked to send Data to PHY.
459  *
460  * @details
461  *
462  *     Function : rgLIMTfuDatReq
463  *      
464  *      This API is invoked to send Data to PHY. It 
465  *      fills in the Pst structure, spId value and invokes Data
466  *      request primitive at TFU.
467  *           
468  *  @param[in]  Inst        inst
469  *  @param[in]  TfuDatReqInfo *datReq
470  *  @return  S16
471  *      -# ROK 
472  *      -# RFAILED 
473  **/
474 #ifdef ANSI
475 PUBLIC S16 rgLIMTfuDatReq 
476 (
477 Inst          inst,
478 TfuDatReqInfo *datReq
479 )
480 #else
481 PUBLIC S16 rgLIMTfuDatReq(inst,datReq)
482 Inst          inst;
483 TfuDatReqInfo *datReq;
484 #endif
485 {
486    S16         ret;
487    RgLowSapCb  *tfuSap;
488
489    TRC2(rgLIMTfuDatReq)
490
491    /* Get the lower SAP control block from the layer control block. */
492    tfuSap = &(rgCb[inst].tfuSap);
493
494 #ifndef NO_ERRCLS
495    if (tfuSap->sapSta.sapState != LRG_BND)
496    {
497       RLOG_ARG1(L_ERROR,DBG_CELLID,datReq->cellId,"Lower SAP not bound (%d)",
498             tfuSap->sapSta.sapState);
499 #ifdef RG_UNUSED
500       /* This case will never be hit if sap is not bound then we dont get TTI */
501       rgLIMUtlFreeDatReqEvnt(datReq, TRUE);
502 #endif
503       RETVALUE(RFAILED);
504    }
505 #endif
506
507    tfuSap->sapSts.numPduTxmit += datReq->pdus.count; 
508
509    /* Using existing pst - for optimization */
510    if((ret = RgLiTfuDatReq (&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId, 
511                             datReq)) != ROK)
512    {
513       RLOG_ARG0(L_ERROR,DBG_CELLID,datReq->cellId,"Call to RgLiTfuDatReq() failed");
514    }
515    RETVALUE(ret);
516 }  /* rgLIMTfuDatReq*/
517
518 #ifdef L2_OPTMZ
519 /**
520  * @brief This API is invoked to send Data to PHY.
521  *
522  * @details
523  *
524  *     Function : rgLIMTfuDelDatReq
525  *      
526  *      This API is invoked to send Data to PHY. It 
527  *      fills in the Pst structure, spId value and invokes Data
528  *      request primitive at TFU.
529  *           
530  *  @param[in]  Inst        inst
531  *  @param[in]  TfuDelDatReqInfo *datReq
532  *  @return  S16
533  *      -# ROK 
534  *      -# RFAILED 
535  **/
536 #ifdef ANSI
537 PUBLIC S16 rgLIMTfuDelDatReq 
538 (
539 Inst          inst,
540 TfuDelDatReqInfo *delDatReq
541 )
542 #else
543 PUBLIC S16 rgLIMTfuDatReq(inst,delDatReq)
544 Inst          inst;
545 TfuDelDatReqInfo *delDatReq;
546 #endif
547 {
548    S16         ret;
549    RgLowSapCb  *tfuSap;
550
551    TRC2(rgLIMTfuDelDatReq)
552
553    /* Get the lower SAP control block from the layer control block. */
554    tfuSap = &(rgCb[inst].tfuSap);
555
556 #ifndef NO_ERRCLS
557    if (tfuSap->sapSta.sapState != LRG_BND)
558    {
559       RLOG_ARG1(L_ERROR,DBG_CELLID,delDatReq->cellId,"Lower SAP not bound (%d)",
560             tfuSap->sapSta.sapState);
561       RETVALUE(RFAILED);
562    }
563 #endif
564
565    if((ret = RgLiTfuDelDatReq (&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId, 
566                             delDatReq)) != ROK)
567    {
568       RLOG_ARG0(L_ERROR,DBG_CELLID,delDatReq->cellId,"Call to RgLiTfuDelDatReq() failed");
569    }
570    RETVALUE(ret);
571 }  /* rgLIMTfuDatReq*/
572 #endif /*L2_OPTMZ */
573
574 /*******************************************************************
575  *
576  * @brief Fills post structure
577  *
578  * @details
579  *
580  *    Function : fillMacToSchPst
581  *
582  *    Functionality:
583  *      Fills post structure to be used when sending msg from 
584  *      MAC to SCH
585  *
586  * @params[in] Post structure pointer 
587  * @return ROK     - success
588  *         RFAILED - failure
589  *
590  * ****************************************************************/
591 void fillMacToSchPst(Pst *pst)
592 {
593    pst->srcProcId = 0;
594    pst->dstProcId = 0;
595    pst->srcEnt = ENTRG;
596    pst->dstEnt = ENTRG;
597    pst->srcInst = 0;
598    pst->dstInst = 1;
599    pst->region = 0;
600    pst->pool =  0;
601    pst->selector = ODU_SELECTOR_TC;
602 }
603
604 /*******************************************************************
605  *
606  * @brief MAC handler for config response from PHY
607  *
608  * @details
609  *
610  *    Function : fapiMacConfigRsp
611  *
612  *    Functionality:
613  *     Processes config response from PHY and sends cell config
614  *     confirm to DU APP
615  *
616  * @params[in] 
617  * @return void
618  *
619  * ****************************************************************/
620 void fapiMacConfigRsp()
621 {
622    /* TODO : Processing of config response from PHY */
623
624    /* Send cell config cfm to DU APP */
625    MacSendCellCfgCfm(RSP_OK);
626 }
627
628 /*******************************************************************
629  *
630  * @brief Send stop indication to DU APP
631  *
632  * @details
633  *
634  *    Function : sendStopIndMacToDuApp
635  *
636  *    Functionality:
637  *       Send stop indication to DU APP
638  *
639  * @params[in] Pst info 
640  * @return ROK     - success
641  *         RFAILED - failure
642  *
643  * ****************************************************************/
644 uint8_t sendStopIndMacToDuApp()
645 {
646    Pst pst;
647    uint8_t ret = ROK;
648
649    MacCellStopInfo *cellStopId; 
650   
651    /*  Allocate sharable memory */
652    MAC_ALLOC_SHRABL_BUF(cellStopId, sizeof(MacCellStopInfo));
653    if(!cellStopId)
654    {
655       DU_LOG("\nMAC : Stop Indication memory allocation failed");
656       return RFAILED;
657    }
658    cellStopId->cellId = macCb.macCell->cellId;
659
660    /* Fill Pst */
661    pst.selector  = ODU_SELECTOR_LWLC;
662    pst.srcEnt    = ENTRG;
663    pst.dstEnt    = ENTDUAPP;
664    pst.dstInst   = 0;
665    pst.srcInst   = macCb.macInst;
666    pst.dstProcId = rgCb[pst.srcInst].rgInit.procId;
667    pst.srcProcId = rgCb[pst.srcInst].rgInit.procId;
668    pst.region = MAC_MEM_REGION;
669    pst.pool = MAC_POOL;
670    pst.event = EVENT_MAC_STOP_IND;
671    pst.route = 0;
672    pst.prior = 0;
673    pst.intfVer = 0;
674
675    ret = MacDuAppStopInd(&pst, cellStopId);
676    if(ret != ROK)
677    {
678       DU_LOG("\nMAC: Failed to send stop indication to DU APP");
679       MAC_FREE_SHRABL_BUF(MAC_MEM_REGION, MAC_POOL, cellStopId, sizeof(MacCellStopInfo));
680    }
681    return ROK;
682 }
683 #if defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
684  /**
685  * @brief Transmission of non-rt indication from CL.
686  *
687  * @details
688  *
689  *     Function : RgLiTfuNonRtInd 
690  *      
691  *      This API is invoked by CL to indicate non-rt processing indication to MAC for a cell.
692  *           
693  *  @param[in]  Pst            *pst
694  *  @param[in]  SuId           suId 
695  *  @return  S16
696  *      -# ROK 
697  *      -# RFAILED 
698  **/
699 #ifdef ANSI
700 PUBLIC S16 RgLiTfuNonRtInd
701 (
702 Pst                 *pst,
703 SuId                suId
704 )
705 #else
706 PUBLIC S16 RgLiTfuNonRtInd(pst, suId)
707 Pst                 *pst;
708 SuId                suId;
709 #endif
710 {
711    TRC3(RgLiTfuNonRtInd);
712
713 #ifdef NO_ERRCLS
714    if (rgLIMValidateSap (pst->dstInst - RG_INST_START, suId) != ROK)
715    {
716       RGDBGERRNEW(pst->dstInst - RG_INST_START, (rgPBuf(pst->dstInst - RG_INST_START),"RgLiTfuNonRtInd() SAP Validation failed.\n"));
717       RETVALUE(RFAILED);
718    }
719 #endif
720    rgDHMFreeTbBufs(pst->dstInst - RG_INST_START);
721    RETVALUE(ROK);
722 }  /* RgLiTfuNonRtInd */
723
724 #endif
725 /**********************************************************************
726  
727          End of file
728 **********************************************************************/