Initial commit
[o-du/l2.git] / src / 5gnrmac / rg_dux.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_dux.c 
28   
29 **********************************************************************/
30
31 /** @file rg_dux.c
32 @brief This module handles de-multiplexing of the data recieved at MAC.
33 */
34
35 static const char* RLOG_MODULE_NAME="MAC";
36 static int RLOG_FILE_ID=176;
37 static int RLOG_MODULE_ID=4096;
38 /* header include files -- defines (.h) */
39 #include "envopt.h"        /* environment options */
40 #include "envdep.h"        /* environment dependent */
41 #include "envind.h"        /* environment independent */
42   
43 #include "gen.h"           /* general */
44 #include "ssi.h"           /* system services */
45
46 #include "cm_lte.h"        /* Common LTE */
47 #include "cm_tkns.h"       /* Common Token Defines */
48 #include "cm_llist.h"      /* Common Link List Defines */
49 #include "cm_hash.h"       /* Common Hash List Defines */
50 #include "cm_mblk.h"       /* common memory link list library */
51
52 #include "rg_env.h"        /* MAC Environment Defines */
53 #include "tfu.h"           /* CRG Interface defines */
54 #include "crg.h"           /* CRG Interface defines */
55 #include "rg_sch_inf.h"           /* RGR Interface defines */
56 #include "rgu.h"           /* RGU Interface defines */
57 #include "lrg.h"           /* LRG Interface defines */
58
59 #include "rg.h"            /* MAC defines */
60 #include "rg_err.h"        /* MAC error defines */
61
62 /* header/extern include files (.x) */
63 #include "gen.x"           /* general */
64 #include "ssi.x"           /* system services */
65 #include "cm5.x"           /* common timers */
66 #include "cm_lib.x"        /* common library */
67 #include "cm_lte.x"        /* Common LTE */
68 #include "cm_tkns.x"       /* Common Token Definitions */
69 #include "cm_llist.x"      /* Common Link List Definitions */
70 #include "cm_lib.x"        /* Common Library Definitions */
71 #include "cm_hash.x"       /* Common Hash List Definitions */
72 #include "cm_mblk.x"       /* common memory link list library */
73
74 #include "rgu.x"           /* RGU types */
75 #include "tfu.x"           /* CRG Interface includes */
76 #include "crg.x"           /* CRG Interface includes */
77 #include "rg_sch_inf.x"    /* SCH Interface includes */
78 #include "rg_prg.x"        /* PRG interface includes */
79 #include "rgu.x"           /* RGU Interface includes */
80 #include "lrg.x"           /* LRG Interface includes */
81
82 #include "rg.x"            /* MAC includes */
83
84 /* local defines */
85
86 /* local typedefs */
87  
88 /* local externs */
89  
90 /* forward references */
91
92 #define RG_DUX_ALLOC(_pdu, _size, _dataPtr, _ret) {\
93    _ret = cmGetMem((Ptr)&_pdu->memCp, _size, (Ptr *)&_dataPtr); \
94 }
95
96 #define RG_INIT_SDU(_sdu, _lcId, _len) {\
97    (_sdu)->lcId = (_lcId); \
98    (_sdu)->len = (_len); \
99    (_sdu)->mBuf = NULLP; \
100    (_sdu)->sduLstEnt.next = NULLP; \
101    (_sdu)->sduLstEnt.prev = NULLP; \
102    (_sdu)->sduLstEnt.node = (PTR)(_sdu); \
103 }
104
105 #define RG_EXT_BS(_bsr, _bs1, _bs2, _bs3, _bs4)  {\
106    _bs1 = _bsr[0] >> 2; \
107    _bs2 = (((_bsr[0] & 0x3) << 4) | (_bsr[1] >> 4)); \
108    _bs3 = (((_bsr[1] & 0x0F) << 2) | (_bsr[2] >> 6)); \
109    _bs4 = _bsr[2] & 0x3F; \
110 }
111
112 #define RG_UNPACK_LONG_BSR(_bsr, _mBuf, _ret) {\
113    _ret = SRemPreMsgMult((_bsr), 3, (_mBuf)); \
114 }
115
116 #define RG_UNPACK_SHORT_BSR(_bsr, _mBuf, _ret) {\
117    _ret = SUnpkU8((_bsr), (_mBuf)); \
118 }
119
120 #define RG_UNPACK_TRUNC_BSR(_bsr, _mBuf, _ret) {\
121    _ret = SUnpkU8((_bsr), (_mBuf)); \
122 }
123
124 #define RG_UNPACK_PHR(_phr, _mBuf, _ret) {\
125    _ret = SUnpkU8((_phr), (_mBuf)); \
126 }
127
128 #define RG_UNPACK_CRNTI(_rnti, _mBuf, _ret) {\
129    Data _unpkArray[2];\
130    *_rnti = 0;\
131    _ret = SRemPreMsgMult(_unpkArray, (MsgLen) 2, _mBuf);\
132    if (_ret == ROK)\
133    {\
134       *_rnti = (U16) PutHiByte(*_rnti, (U8) _unpkArray[0]);\
135       *_rnti = (U16) PutLoByte(*_rnti, (U8) _unpkArray[1]);\
136    }\
137 }
138
139 /* For EXT PHR DEMUX */
140 #define RG_UNPACK_EXT_PHR_CI(_ci, _mBuf, _ret) {\
141    _ret = SUnpkU8((_ci), (_mBuf)); \
142 }
143
144 #define RG_UNPACK_EXT_PHR(_extPhr, _mBuf, _ret) {\
145    _ret = SUnpkU8((_extPhr), (_mBuf)); \
146 }
147
148
149
150 /**
151  * @brief Handles the insertion of SDU in to PDU.
152  *
153  * @details
154  *
155  *     Function: rgDUXInsSdu
156  *     
157  *     This API handles the insertion of SDU in to PDU.
158  *     
159  *     Processing Steps: 
160  *      - Append the sdu to the sduLst of pdu.
161  *
162  *  @param[in]  Inst        inst
163  *  @param[out] *pdu
164  *  @param[in]  lcId
165  *  @param[in]  sduLen
166  *  @param[out] *err
167  *  @return  S16
168  *      -# ROK 
169  *      -# RFAILED 
170  **/
171 #ifdef ANSI
172 PRIVATE S16 rgDUXInsSdu
173 (
174 Inst        inst,
175 RgMacPdu    *pdu,
176 RgMacSdu    **sdu,
177 U8          lcId,
178 U16         sduLen,
179 RgErrInfo   *err
180 )
181 #else
182 PRIVATE S16 rgDUXInsSdu(inst,pdu, sdu, lcId, sduLen, err)
183 Inst        inst;
184 RgMacPdu    *pdu;
185 RgMacSdu    **sdu,
186 U8          lcId;
187 U16         sduLen;
188 RgErrInfo   *err;
189 #endif
190 {
191    S16         ret;
192    RgMacSdu    *sduAloc = NULLP;
193
194    TRC2(rgDUXInsSdu)
195
196    RG_DUX_ALLOC(pdu, sizeof(RgMacSdu), sduAloc, ret);
197    if(ret != ROK)
198    {
199       RLOG1(L_ERROR, "Allocation of RgSubHdr failed for LCID:%d",lcId);
200       err->errCause = RGERR_DUX_MEM_EXHAUST;
201       RETVALUE(RFAILED);
202    }
203    *sdu = sduAloc; 
204    RG_INIT_SDU(sduAloc, lcId, sduLen);
205    cmLListAdd2Tail(&pdu->sduLst, &sduAloc->sduLstEnt);
206    RETVALUE(ROK);
207 }
208
209 /**
210  * @brief Handles extracting the CE sub headers from the MAC PDU.
211  *
212  * @details
213  *
214  *     Function: rgDUXExtSubHdr
215  *     
216  *     This API handles extracting the  sub headers from the MAC PDU.
217  *     
218  *     Processing Steps: 
219  *      - Extract the each sub header.
220  *
221  *  @param[in]  Inst        inst
222  *  @param[out]  *pdu
223  *  @param[in]  *mBuf
224  *  @param[out] *lcId
225  *  @param[out] *len
226  *  @param[out] *err
227  *  @return  S16
228  *      -# ROK 
229  *      -# RFAILED 
230  **/
231 #ifdef ANSI
232 PRIVATE S16 rgDUXExtSubHdr
233 (
234 Inst        inst,
235 RgMacPdu    *pdu,
236 Buffer      *mBuf,
237 U8          *lcId,
238 U16         *len,
239 RgErrInfo   *err
240 )
241 #else
242 PRIVATE S16 rgDUXExtSubHdr(inst,pdu, mBuf, lcId,
243 len, err)
244 Inst        inst;
245 RgMacPdu    *pdu;
246 Buffer      *mBuf;
247 U8          *lcId;
248 U16         *len;
249 RgErrInfo   *err;
250 #endif
251 {
252    U8             byte;
253    U8             fmt=0;
254  
255    TRC2(rgDUXExtSubHdr)
256
257    *len = 0;   
258    if(SUnpkU8(&byte,mBuf) != ROK)
259    {
260       RLOG0(L_ERROR, "SUnpkU8 failed");
261       err->errCause = RGERR_DUX_UNPACK_FAILURE;
262       RETVALUE(RFAILED);
263    }
264    /* Extract the lcid */
265    RG_EXT_LCID(*lcId, byte);
266
267    /*note: RG_EXT_PHR_LCID currently not considered */
268    if(*lcId <= RG_DEDLC_MAX_LCID)
269    {  /* variable size MAC Sub PDU */
270       RG_EXT_FORMT_BIT(fmt,byte);
271       if(SUnpkU8(&byte, mBuf) != ROK)
272       {
273          RLOG0(L_ERROR, "SUnpkU8 failed");
274          err->errCause = RGERR_DUX_UNPACK_FAILURE;
275          RETVALUE(RFAILED);
276       }
277       *len = byte;
278       if(fmt)
279       {
280          if(SUnpkU8(&byte,mBuf) != ROK)
281          {
282             RLOG0(L_ERROR, "SUnpkU8 failed");
283             err->errCause = RGERR_DUX_UNPACK_FAILURE;
284             RETVALUE(RFAILED);
285          }
286          *len = (*len << 8) | byte;
287       }
288    }
289    RETVALUE(ROK);
290 } /* rgDUXExtSubHdr */
291
292 /**
293  * @brief Handles extracting the CEs from the MAC PDU.
294  *
295  * @details
296  *
297  *     Function: rgDUXExtCe
298  *     
299  *     This API handles extracting the CEs from the MAC PDU.
300  *     
301  *     Processing Steps: 
302  *      - Based on the ce sub header extract the ce.
303  *
304  *  @param[in]  Inst        inst
305  *  @param[in,out]  *pdu
306  *  @param[out] *ceInfo
307  *  @param[in]  *mBuf
308  *  @param[in] lcId
309  *  @param[in] subPduLen
310  *  @param[out] *err
311  *  @return  S16
312  *      -# ROK 
313  *      -# RFAILED 
314  **/
315 #ifdef ANSI
316 PRIVATE S16 rgDUXExtCe
317 (
318 Inst        inst,
319 RgMacPdu    *pdu,
320 RgInfCeInfo  *ceInfo,
321 Buffer       *mBuf,
322 U8          lcId,
323 U16         subPduLen,
324 RgErrInfo    *err
325 )
326 #else
327 PRIVATE S16 rgDUXExtCe(inst,pdu, ceInfo, mBuf,lcId,subPduLen, err)
328 Inst        inst;
329 RgMacPdu    *pdu;
330 RgInfCeInfo  *ceInfo;
331 Buffer       *mBuf;
332 U8          lcId;
333 U16         subPduLen;
334 RgErrInfo    *err;
335 #endif
336 {
337    S16            ret;
338
339    TRC2(rgDUXExtCe);
340
341    switch(lcId)
342    {
343       case RG_EXT_PHR_LCID:
344          {
345             U8 Ci;
346             U8 sCellIdx;
347             U8 extPhrOctet;
348             U8 extPhrPCmax;
349             RgInfExtPhrCEInfo *extPhr;
350
351             RG_UNPACK_EXT_PHR_CI(&Ci,mBuf,ret);
352             if(ret != ROK)
353             {
354                RLOG1(L_ERROR,"Unpacking of EXT PHR failed LCID:%d",lcId);
355                err->errCause = RGERR_DUX_UNPACK_FAILURE;
356                RETVALUE(RFAILED);
357             }
358
359             /* Not handling Type 2 PHR report as simultaneous PUSCH/PUCCH
360                is not supported as of now */
361             extPhr = &ceInfo->ces.extPhr;
362             extPhr->numServCells = 0;
363
364             /* Setting first BIT as PCELL field even though reserved is always
365                reported by UE */
366             Ci |= 0x1;
367             for (sCellIdx = 0; (Ci && sCellIdx < CM_LTE_MAX_CELLS); sCellIdx++)
368             {
369                if (Ci & 0x1)
370                {
371                   extPhr->servCellPhr[extPhr->numServCells].sCellIdx = sCellIdx;
372                   RG_UNPACK_EXT_PHR(&extPhrOctet,mBuf,ret);
373                   if(ret != ROK)
374                   {
375                      RLOG1(L_ERROR,"Unpacking of EXT PHR failed LCID:%d",lcId);
376                      err->errCause = RGERR_DUX_UNPACK_FAILURE;
377                      RETVALUE(RFAILED);
378                   }
379
380                   /* extPhrOctet: Bits : 7 6 5 4 3 2 1 0
381                    *                     P V x x x x x x
382                    *                         <6x Bit phr>
383                    */
384                   /* P : P Back off applied or not */
385                   extPhr->servCellPhr[extPhr->numServCells].phr = (extPhrOctet & 0x3F);
386                   extPhr->servCellPhr[extPhr->numServCells].pBackOff = 
387                      ((extPhrOctet >> 7) & 0x01);
388
389                   /* V: Virtual PCMAX or Real Tx PCMAX */
390                   if (extPhrOctet & 0x40)
391                   {
392                      extPhr->servCellPhr[extPhr->numServCells].pCmax = RG_REF_PCMAX;
393                   }
394                   else
395                   {
396                      RG_UNPACK_EXT_PHR(&extPhrPCmax,mBuf,ret);
397                      if(ret != ROK)
398                      {
399                         RLOG1(L_ERROR,"Unpacking of EXT PHR failed LCID:%d",lcId);
400                         err->errCause = RGERR_DUX_UNPACK_FAILURE;
401                         RETVALUE(RFAILED);
402                      }
403                      extPhr->servCellPhr[extPhr->numServCells].pCmax = (extPhrPCmax & 0x3F);
404                   }
405                   extPhr->numServCells++;
406                }
407                Ci >>= 1;
408             }
409
410             ceInfo->bitMask |= RG_EXT_PHR_CE_PRSNT;
411          }
412          break;
413
414       case RG_PHR_LCID:
415          {
416             RG_UNPACK_PHR(&ceInfo->ces.phr,mBuf,ret);
417             if(ret != ROK)
418             {
419                RLOG1(L_ERROR,"Unpacking of PHR failed LCID:%d",lcId);
420                err->errCause = RGERR_DUX_UNPACK_FAILURE;
421                RETVALUE(RFAILED);
422             }
423             ceInfo->bitMask |= RG_PHR_CE_PRSNT;
424          }
425          break;
426       case RG_TRUNC_BSR_LCID:
427          {
428             RG_UNPACK_TRUNC_BSR(&ceInfo->ces.bsr.truncBsr,mBuf,ret);
429             if(ret != ROK)
430             {
431                RLOG1(L_ERROR,"Unpacking of Trunc BSR failed LCID:%d",lcId);
432                err->errCause = RGERR_DUX_UNPACK_FAILURE;
433                RETVALUE(RFAILED);
434             }
435             ceInfo->bitMask |= RG_TRUNC_BSR_CE_PRSNT;
436          }
437          break;
438       case RG_SHORT_BSR_LCID:
439          {
440             RG_UNPACK_SHORT_BSR(&ceInfo->ces.bsr.shortBsr,mBuf,ret);
441             if(ret != ROK)
442             {
443                RLOG1(L_ERROR,"Unpacking of Short BSR failed LCID:%d",lcId);
444                err->errCause = RGERR_DUX_UNPACK_FAILURE;
445                RETVALUE(RFAILED);
446             }
447             ceInfo->bitMask |= RG_SHORT_BSR_CE_PRSNT;
448          }
449          break;
450       case RG_LONG_BSR_LCID:
451          {
452             U8 longBsr[3] = {0}; /* KW_FIXX */
453             RG_UNPACK_LONG_BSR(longBsr,mBuf,ret);
454             if(ret != ROK)
455             {
456                RLOG1(L_ERROR,"Unpacking of Long BSR failed LCID:%d",lcId);
457                err->errCause = RGERR_DUX_UNPACK_FAILURE;
458                RETVALUE(RFAILED);
459             }
460             RG_EXT_BS(longBsr, 
461                   ceInfo->ces.bsr.longBsr.bs1, 
462                   ceInfo->ces.bsr.longBsr.bs2, 
463                   ceInfo->ces.bsr.longBsr.bs3, 
464                   ceInfo->ces.bsr.longBsr.bs4);
465             ceInfo->bitMask |= RG_LONG_BSR_CE_PRSNT;
466          }
467          break;
468       case RG_CRNTI_LCID:
469          {
470             RG_UNPACK_CRNTI(&ceInfo->ces.cRnti,mBuf,ret);
471             if(ret != ROK)
472             {
473                RLOG1(L_ERROR,"Unpacking of C-RNTI failed LCID:%d",lcId);
474                err->errCause = RGERR_DUX_UNPACK_FAILURE;
475                RETVALUE(RFAILED);
476             }
477             ceInfo->bitMask |= RG_CRNTI_CE_PRSNT;
478          }
479          break;
480       default:
481          RLOG1(L_ERROR, "Invalid LCID:%u received",lcId); 
482          err->errCause = RGERR_DUX_INV_LCID_RX;
483          RETVALUE(RFAILED);
484    }
485    RETVALUE(ROK);
486 } /* rgDUXExtCe  */
487
488
489 /**
490  * @brief Handles extracting the SDU from the MAC PDU.
491  *
492  * @details
493  *
494  *     Function: rgDUXExtSdu
495  *     
496  *     This API handles extracting the SDU corresponding to a logical channel.
497  *     
498  *     Processing Steps: 
499  *      - Based on the length stored in the sub header extract the SDU.
500  *
501  *  @param[in]  Inst        inst
502  *  @param[in,out]  *pdu
503  *  @param[out] *ceInfo
504  *  @param[in]  *mBuf
505  *  @param[in] lcId
506  *  @param[in] subPduLen
507  *  @param[out] *err
508  *  @return  S16
509  *      -# ROK 
510  *      -# RFAILED 
511  **/
512 #ifdef ANSI
513 PRIVATE S16 rgDUXExtSdu
514 (
515 Inst        inst,
516 RgMacPdu    *pdu,
517 RgInfCeInfo  *ceInfo,
518 Buffer      **mBuf,
519 U8          lcId,
520 U16         subPduLen,
521 RgErrInfo   *err
522 )
523 #else
524 PRIVATE S16 rgDUXExtSdu(inst,pdu, ceInfo,mBuf,lcId,subPduLen,err)
525 Inst        inst;
526 RgMacPdu    *pdu;
527 RgInfCeInfo  *ceInfo;
528 Buffer      **mBuf;
529 U8          lcId;
530 U16         subPduLen;
531 RgErrInfo   *err;
532 #endif
533 {
534    S16         ret;
535    Buffer      *tmpBuf1;
536    Buffer      *tmpBuf2 = NULLP;
537    RgMacSdu    *sdu;
538
539    TRC2(rgDUXExtSdu)
540
541    if(lcId == RG_CCCH_LCID)
542    {
543       ceInfo->bitMask |= RG_CCCH_SDU_PRSNT;
544    }
545
546    if(rgDUXInsSdu(inst,pdu, &sdu,lcId, subPduLen, err) != ROK)
547    {
548       RG_FREE_MSG(*mBuf);
549       RETVALUE(RFAILED);
550    }
551
552    tmpBuf1 = *mBuf;
553    {
554       ret = SSegMsg(tmpBuf1,subPduLen,&tmpBuf2);
555       if((ret != ROK) && (!((ret == ROKDNA) )))
556       {
557          RG_FREE_MSG(tmpBuf1);
558          RLOG0(L_ERROR,"SSegMsg failed");
559          err->errCause = RGERR_DUX_RLC_PDU_CREAT_FAIL;
560          RETVALUE(RFAILED);
561       }
562       sdu->mBuf = tmpBuf1;
563       *mBuf = tmpBuf2;
564    }
565    RETVALUE(ROK);
566 }   /* rgDUXExtSdu */
567
568 /**
569  * @brief Handles de-multiplexing of the data recieved at MAC.
570  *
571  * @details
572  *
573  *     Function: rgDUXDemuxData
574  *     
575  *     This API handles de-multiplexing of the data recieved at MAC.
576  *     
577  *     Invoked by: rgTOMTfuDatInd of TOM 
578  *     
579  *     Processing Steps: 
580  *      - De-multiplex the mBuf
581  *
582  *  @param[in]  Inst        inst
583  *  @param[in]  *pdu 
584  *  @param[in]  *mBuf 
585  *  @param[out] *err 
586  *  @return  S16
587  *      -# ROK 
588  *      -# RFAILED 
589  **/
590 #ifdef ANSI
591 PUBLIC S16 rgDUXDemuxData
592 (
593 Inst          inst,
594 RgMacPdu      *pdu,
595 RgInfCeInfo   *ceInfo,
596 Buffer        **mBuf,
597 RgErrInfo     *err
598 )
599 #else
600 PUBLIC S16 rgDUXDemuxData(inst,pdu, ceInfo, mBuf, err)
601 Inst          inst;
602 RgMacPdu      *pdu;
603 RgInfCeInfo   *ceInfo;
604 Buffer        **mBuf;
605 RgErrInfo     *err;
606 #endif
607 {
608    U8          lcId;
609    U16          subPduLen;
610    MsgLen      len;  
611    TRC2(rgDUXDemuxData)
612
613    ceInfo->bitMask = 0x0000;
614
615    /* Initialize the sdu list */
616    cmLListInit(&pdu->sduLst);
617
618    if(*mBuf == NULLP) 
619    {
620       RLOG0(L_ERROR, "Null Buffer Recevived");
621       RETVALUE(RFAILED);
622    }
623    do
624    {
625       /* UL Message format  order : 
626            PduSubHdr+SubPDU,PduSubHdr+SubPDU,...CeSubHdr+Ce,CeSubPdu+Ce,...,PADSubHdr+PAD */
627       /* Extract the Sub headers */
628       if(rgDUXExtSubHdr(inst,pdu, *mBuf, &lcId, 
629                &subPduLen, err) != ROK)
630       {
631          RG_FREE_MSG(*mBuf);          
632          RLOG0(L_ERROR, "Failed to extract pad sub headers");
633          RETVALUE(RFAILED);
634       }
635       if(lcId == RG_PAD_LCID)
636       { /*at end of MAC PDU,  Padding started */ 
637          RG_FREE_MSG(*mBuf);          
638          RETVALUE(ROK);
639       }
640       if(lcId <= RG_DEDLC_MAX_LCID)
641       {
642          /* Extract the sdus */
643          if(rgDUXExtSdu(inst,pdu,ceInfo, mBuf,lcId,subPduLen, err) != ROK)
644          {
645             /* Fix : syed rgDUXExtSdu would have segmented mBuf and hence
646              * will be responsible for freeing mBuf */
647             *mBuf = NULLP;
648             RLOG0(L_ERROR, "failed to Extract the sdus");
649             RETVALUE(RFAILED);
650          }
651          if(*mBuf == NULLP) /* if message read completes then return */
652          {
653             RETVALUE(ROK);
654          }
655       }
656       else
657       {
658          /* Extract the ces */
659          if(rgDUXExtCe(inst,pdu,ceInfo,*mBuf, lcId,subPduLen, err) != ROK)
660          {
661             RG_FREE_MSG(*mBuf);       
662             RLOG0(L_ERROR, " failed to Extract the ces");
663             RETVALUE(RFAILED);
664          }
665       }
666       if(SFndLenMsg(*mBuf,&len) != ROK)
667       {
668          RG_FREE_MSG(*mBuf);
669          RLOG0(L_ERROR,"mBuf length check failed");
670          err->errCause = RGERR_DUX_UNPACK_FAILURE;
671          RETVALUE(RFAILED);
672       }
673    }while(len);
674
675    RG_FREE_MSG(*mBuf);
676    RETVALUE(ROK);
677 }  /* rgDUXDemuxData */
678
679 /**********************************************************************
680  
681          End of file
682 **********************************************************************/