source: svn/zas_dstar/hal/common/dsthalPsiDsmcc.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

File size: 108.4 KB
Line 
1/****************************************************************************
2 *_Copyright (c) 2004 DST Technologies Inc.  All Rights Reserved.
3 *
4 * file name      dsthalPsiApi.c
5 * Author:        hwatk
6 * Description:   DSMCC
7 *             
8 *
9 ***************************************************************************/
10
11#include "dsthalcommon.h"
12#include "dstoslayer.h"
13#include "dsthalerror.h"
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18
19#include "dsthalPsiMemChain.h"
20#include "dsthalPsiBitBuffer.h"
21#include "dsthalPsiAtscPsip.h"
22#include "dsthalPsiMpegSi.h"
23
24/******************************************************************************
25 * Global variable declaration
26 ******************************************************************************/
27DSMCCDatabase_t *pDsmccDB = NULL;
28
29/******************************************************************************
30 * Imported variable declaration
31 ******************************************************************************/
32extern DHL_PSI_HANDLE gPsiHandle;
33
34/******************************************************************************
35 * Imported function declaration
36 ******************************************************************************/
37extern void hal_cbPSISyncEventProc ( PSIEvent event , DHL_TBL_HANDLE hTblHandle , DS_U32 userParam );
38
39/******************************************************************************
40 * Local definitions
41 ******************************************************************************/
42
43
44/******************************************************************************
45 * Local typedefs
46 ******************************************************************************/
47typedef void *(*fnAlloc_t)(int);
48typedef void (*fnFree_t)(void *);
49
50/******************************************************************************
51 * Local variables declaration
52 ******************************************************************************/
53static const DS_U8 XltIdx2Bit[ ] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
54static fnAlloc_t g_pDsmccAllocFunc = (fnAlloc_t)0;
55static fnFree_t g_pDsmccFreeFunc = (fnFree_t)0;
56
57/******************************************************************************
58 * Local function prototypes
59 ******************************************************************************/
60void DHL_PSI_CancelAllDsmccMonitors( void );
61DHL_RESULT DHL_PSI_ParseDsmccDIISection( DS_U8 *section, dsmccDIISectionPtr_t *ppDsmccDIISection );
62
63#if 0
64___DSMCC_FUNCTION___()
65#endif
66/**************************************************************************
67* Function Name : DsmccMainTask
68*
69* Description   : DSM-CC DDB thread
70*
71* Parameters    : None
72*
73* Return        : DHL_RESULT
74*                                 DHL_OK  -  success
75 **************************************************************************/
76void *DSMCC_MALLOC(int size)
77{
78        if (g_pDsmccAllocFunc)
79                return (g_pDsmccAllocFunc)(size);
80        else
81                return malloc(size);
82}
83
84void DSMCC_FREE(void *addr)
85{
86        if (g_pDsmccFreeFunc)
87                (g_pDsmccFreeFunc)(addr);
88        else
89                free(addr);
90}
91
92/**************************************************************************
93* Function Name : DHL_PSI_ActivateDsmcc
94*
95* Description   : Initializes DSM-CC module, creates DSM-CC msg queue, sema4,
96*                                 thread, and launches it.
97*
98* Parameters    :
99*
100* Return        : DHL_RESULT
101*                                 DHL_OK  -  success
102 **************************************************************************/
103DHL_RESULT DHL_PSI_ActivateDsmcc( int *pAppTaskPriority )
104{
105    DHL_RESULT                  err                             = DHL_OK;
106        //DsmccMsg_t                    dsmccMsg;
107
108        //OS_TASK_ID                    dsmccTaskID             = (OS_TASK_ID)0;
109        OS_SEMAPHORE_ID         mutexSema4              = (OS_SEMAPHORE_ID)NULL;
110        OS_SEMAPHORE_ID         controlSema4    = (OS_SEMAPHORE_ID)NULL;
111
112    if ( *pAppTaskPriority >= DSMCCDDB_TASK_PRIO )
113        *pAppTaskPriority = DSMCCDDB_TASK_PRIO - 1;
114
115        if (!g_pDsmccAllocFunc)
116                g_pDsmccAllocFunc = (fnAlloc_t)malloc;
117       
118        if (!g_pDsmccFreeFunc)
119                g_pDsmccFreeFunc = free;
120       
121        /* Take the global dsmcc binary sema4 created in the TLSys here
122         * Allow only one instance of DSM-CC processing thread
123         */
124        if ( pDsmccDB != NULL )
125        {
126                /* Give the global dsmcc binary sema4 */
127                return DHL_FAIL_CORE_DRIVER;
128        }
129
130        /* Create and initialize our own Database
131         */
132        pDsmccDB = (DSMCCDatabase_t *)malloc( sizeof(DSMCCDatabase_t) );
133
134        /* Give the global dsmcc binary sema4
135         */
136        if ( pDsmccDB == NULL )
137        {
138                err = DHL_FAIL_OUT_OF_RESOURCE;
139                goto doneError;
140        }
141
142    /* Clear the DSMCC database block
143     */
144    memset( pDsmccDB, 0, sizeof(DSMCCDatabase_t) );
145
146        /* Create Mutex Sema4
147         */
148        mutexSema4 = OS_CreateMutex("dsmccMutexSema4");
149        if ( mutexSema4 == (OS_MUTEX_ID)NULL )
150        {
151                err = DHL_FAIL_OUT_OF_RESOURCE;
152                goto doneError;
153        }
154
155        /* Create Control Sema4
156         */
157        controlSema4 = OS_CreateCountingSemaphore("dsmccControlSema4",0,0);
158        if(controlSema4 == (OS_SEMAPHORE_ID)NULL)
159        {
160                err = DHL_FAIL_OUT_OF_RESOURCE;
161                goto doneError;
162        }
163
164        /* Copy all the information into the common area in DSMCC DB structure
165         */
166        ///pDsmccDB->dsmccTaskID        = dsmccTaskID;
167        ///pDsmccDB->dsmccQ             = dsmccQ;
168        pDsmccDB->mutexSema4    = mutexSema4;
169        ///pDsmccDB->syncSema4          = syncSema4;
170
171#if 0
172        // Main Task´Â Á¦°ÅÇϰí, °¢ DDB Monitor´ç Task »ý¼º.
173       
174        /* Spawn the DSMCC thread
175         */
176        dsmccTaskID = OS_SpawnTask( (OS_TASKFUNCTION)DsmccDDBTask, "tDsmccMainTask", DSMCCDDB_TASK_PRIO, 16*1024, (DS_S32)0);
177
178    /* Synchronize with the thread launched
179     */
180    dsmccMsg.event          = eDsmccActivate;
181    dsmccMsg.param          = (void *)pDsmccDB;
182
183        OS_SendMessage(pDsmccDB->dsmccQ, (DS_U32 *)&dsmccMsg, sizeof(DsmccMsg_t));
184        OS_TakeSemaphore(pDsmccDB->syncSema4);
185#endif
186
187    pDsmccDB->isActive      = _TRUE_;
188
189    return err;
190
191doneError:
192
193//      if (dsmccQ)                     { OS_DeleteMessageQueue(dsmccQ);                }
194        if (mutexSema4)         { OS_DeleteSemaphore(mutexSema4);               }
195//      if (syncSema4)          { OS_DeleteSemaphore(syncSema4);                }
196        if (controlSema4)       { OS_DeleteSemaphore(controlSema4);             }
197        if (pDsmccDB)           { free(pDsmccDB); pDsmccDB = NULL;      }
198
199        return err;
200}
201
202/**************************************************************************
203* Function Name : DHL_PSI_DeactivateDsmcc
204*
205* Description   : Issues request to DSM-CC thread to stop and terminate
206*                                 itself.  All active DII and DDB monitors will be
207*                 terminated.
208* Parameters    :
209*
210* Return        : DHL_RESULT
211*                                 DHL_OK  -  success
212 **************************************************************************/
213DHL_RESULT DHL_PSI_DeactivateDsmcc( void )
214{
215    DHL_RESULT          err = DHL_OK;
216//    DsmccMsg_t        dsmccMsg;
217//    DS_U32      i;
218
219        if ( pDsmccDB && pDsmccDB->isActive )
220        {
221#if 0
222                dsmccMsg.event = eDsmccDeactivate;
223                OS_SendMessage(pDsmccDB->dsmccQ, &dsmccMsg, sizeof(DsmccMsg_t));
224                OS_TakeSemaphore(pDsmccDB->syncSema4);
225#else
226                // ¿©±â¼­ DDB °ü·Ã Thread¸¦ ¸ðµÎ ¾ø¾ÖÀÚ! --+
227               
228#endif
229
230//              OS_DeleteSemaphore(pDsmccDB->syncSema4);
231                OS_DeleteSemaphore(pDsmccDB->mutexSema4);
232                OS_DeleteSemaphore(pDsmccDB->controlSema4);
233//              OS_DeleteMessageQueue(pDsmccDB->dsmccQ);
234                free(pDsmccDB);
235                pDsmccDB = NULL;
236        }
237       
238        return err;
239}
240
241/**************************************************************************
242* Function Name : DHL_PSI_CancelAllDsmccMonitors
243*
244* Description   : Terminate all DII and DDB monitors and
245*                 free up the resources being used for monitoring
246*
247* Parameters    :
248*
249* Return        : DHL_RESULT
250*                                 DHL_OK  -  success
251 **************************************************************************/
252void DHL_PSI_CancelAllDsmccMonitors( void )
253{
254    DDBMsgMonContextPtr_t pDDBMsgMonContext;
255    DS_U16  i;
256
257    OS_TakeSemaphore( pDsmccDB->mutexSema4 );                               // ==>> Mutex access
258
259    for ( i = 0; i < NUM_DII_MON_CONTEXTS; i++ )
260    {
261        if ( pDsmccDB->DIIMonContexts[ i ].isUsed && pDsmccDB->DIIMonContexts[ i ].psiCtl )
262        {
263            DHL_PSI_CancelMonitor( pDsmccDB->DIIMonContexts[ i ].psiCtl );
264
265            ////(*pDsmccDB->DIIMonContexts[ i ].pfCallbackProc)( NULL );    // Notify client with NULL?
266        }
267    }
268
269    for ( i = 0; i < NUM_DDB_MON_CONTEXTS; i++ )
270    {
271        if ( pDsmccDB->DDBMonContexts[ i ].isUsed )
272        {
273            pDDBMsgMonContext = &pDsmccDB->DDBMonContexts[ i ];
274
275            if ( pDDBMsgMonContext->psiCtl )
276                DHL_PSI_CancelMonitor( pDDBMsgMonContext->psiCtl );
277
278            if ( pDDBMsgMonContext->pDDBModule != NULL )                    // Free DDB module mem chain buffer
279                        memChainDestroy( pDDBMsgMonContext->memId );
280
281            if ( pDDBMsgMonContext->pBlockRecvBitFlags )                    // Free receive bit buffer
282                free( (pDDBMsgMonContext->pBlockRecvBitFlags) );
283        }
284    }
285
286    OS_GiveSemaphore( pDsmccDB->mutexSema4 );                               // ==>> Mutex release
287}
288
289static DHL_RESULT CreateDIIContext( DsmccEventProc_t pfCallbackProc, DS_U32 *pDIIMonContextId )
290{
291        DHL_RESULT              err = DHL_OK;
292    DIIMsgMonContextPtr_t   pDIIMsgMonContext;
293    DS_U32                  i;
294
295    // Alloc memory block for DDB monitoring context and store all the DDB monitoring parameters
296    // in the allocated memory block
297    for ( i = 0; i < NUM_DII_MON_CONTEXTS; i++ )
298    {
299        if ( !pDsmccDB->DIIMonContexts[ i ].isUsed )
300        {
301            break;
302        }
303    }
304
305    if ( i >= NUM_DII_MON_CONTEXTS )
306    {
307        printf( "CreateDIIContext: Out of monitoring context\n" );
308        err = DHL_FAIL_TOO_MANY_INSTANCES;
309        return err;
310    }
311
312    // Initialize DII monitoring context structure
313    pDIIMsgMonContext = &pDsmccDB->DIIMonContexts[ i ];
314    memset( (DS_U8*)pDIIMsgMonContext, 0, sizeof(DIIMsgMonContext_t) );
315
316    pDIIMsgMonContext->isUsed           = _TRUE_;             // This context is now being used
317    pDIIMsgMonContext->pfCallbackProc   = pfCallbackProc;   // Client callback func ptr
318    *pDIIMonContextId = i;                                  // Return context ID
319
320    return err;
321}
322
323static void FreeDIIContext( DS_U32 DIIMonContextId )
324{
325    if ( DIIMonContextId < NUM_DII_MON_CONTEXTS )
326    {
327        OS_TakeSemaphore( pDsmccDB->mutexSema4 );  // Mutex access
328        pDsmccDB->DIIMonContexts[ DIIMonContextId ].isUsed = _FALSE_;
329        pDsmccDB->DIIMonContexts[ DIIMonContextId ].psiCtl = NULL;
330        OS_GiveSemaphore( pDsmccDB->mutexSema4 );  // Mutex release
331    }
332}
333
334/**************************************************************************
335* Function Name : FreeDsmccMemChain
336*
337* Description   : Destroy the previously allocated memory chain structure
338*                                       
339* Parameters    :
340*
341* Return        : ErrCode 
342*                                 noErrror  -  success
343 **************************************************************************/
344DHL_RESULT FreeDsmccMemChain(void* pDsmccMem)
345{
346        DHL_RESULT      rval = DHL_OK;
347
348    if ( pDsmccMem != NULL )
349    {
350            rval = memChainDestroy(*(((memId_t *)pDsmccMem)-1));
351    }
352
353        return (rval);
354}
355
356/**************************************************************************
357* Function Name : DHL_PSI_MonitorDsmccDII
358*
359* Description   : Setup DII message monitoring and filters
360*
361* Parameters    : transactionId - version of DII
362*                                 pfCallbackProc - client callback proc
363*
364* Return        : DHL_RESULT
365*                                 DHL_OK  -  success
366 **************************************************************************/
367//DHL_RESULT DHL_PSI_MonitorDsmccDII( DHL_PSI_HANDLE sysInfo, DS_U16 Pid, DS_U16 transactionId, DsmccEventProc_t pfCallbackProc, DHL_TBL_HANDLE *returnPsiCtl )
368DHL_RESULT DHL_PSI_MonitorDsmccDII( DHL_PSI_HANDLE sysInfo, 
369                                                                        DS_U16 Pid, 
370                                                                        DS_U16 transactionId, 
371                                                                        DsmccEventProc_t pfCallbackProc, 
372                                                                        DS_U32 userParam,
373                                                                        DHL_TBL_HANDLE *returnPsiCtl )
374{
375        DHL_RESULT      err = DHL_OK;
376        PSIMask_t               *pref;
377    DS_U32          DIIMonContextId;
378    DS_BOOL            isActive;
379        int                             Priority=80;
380       
381    // Check if the dsmcc thread is up and running...
382    isActive = (pDsmccDB) ? pDsmccDB->isActive : _FALSE_;
383
384    if ( !isActive )
385    {
386        err = DHL_PSI_ActivateDsmcc(&Priority);
387        if ( err != DHL_OK ) {
388                printf( "DHL_PSI_ActivateDsmcc: failure. (0x%x)\n", err );
389                return( DHL_FAIL_NOT_CONNECTED );
390        } else {
391                    isActive = (pDsmccDB) ? pDsmccDB->isActive : _FALSE_;
392                if ( !isActive ) {
393                        printf( "CreateDIIContext: DSMCC thread is not active\n" );
394                        return( DHL_FAIL_NOT_CONNECTED );
395                    }
396            }
397    }
398
399    // Check function arguments
400    if ( (sysInfo == NULL) || (returnPsiCtl == NULL) )
401    {
402                printf( "%s(): sysInfo = %lx  returnPsiCtl = %lu\n", __FUNCTION__, (sysInfo)?(DS_U32)sysInfo:0, (returnPsiCtl)?(DS_U32)returnPsiCtl:0 );
403        return( DHL_FAIL_NULL_POINTER );
404    }
405
406        // Acquire the table data by the specified filter(s)
407        // Currently we do not use transaction_id, since hardware PSI filter doesn't support more than 16 bytes section filter.
408        if ((err = DD_PSI_GetDsmccPSIMask       ( &pref,
409                                                                                tid_dsmcc_download_info_indication,     // DII Table ID
410                                                                                DSMCC_MESSAGE_DII,
411                                                                                _TRUE_))) 
412        {
413                printf("|%s| ERROR, LINE=%d (0x%x)\n", __FUNCTION__, __LINE__, err);
414                return( err );
415        }
416
417    // Create DII monitoring context and setup DII monitor filter
418    //
419    OS_TakeSemaphore( pDsmccDB->mutexSema4 );               // ==>> Mutex access
420
421    err = CreateDIIContext( pfCallbackProc, &DIIMonContextId );
422
423    if ( err != DHL_OK )
424    {
425        OS_GiveSemaphore( pDsmccDB->mutexSema4 );           // ==>> Mutex release
426                printf("|%s| ERROR, LINE=%d\n", __FUNCTION__, __LINE__);
427        return( err );
428    }
429
430    // Start monitoring for the dsmcc DII table
431        if ( (err = DD_PSI_MonitorPSIPid(
432                                                        sysInfo,                        // Transport Demux Unit
433                                                        Pid,                            // Packet ID to filter the DSM-CC DII msgs
434                                                        tableMode,                  // All section received table mode
435                                                        //psiCRCChange,               // Only if there's a CRC change in the DII table
436                                                        psiOneShot,
437                                                        pref,                       // PSI filter
438                                                        MAX_DSMCC_SECTION_LENGTH,   // 4Kb
439                                                        MAX_DSMCC_SECTIONS,         // 256?
440                                                        hal_cbPSISyncEventProc,          // DII event handler
441                                                        //DIIMonContextId,            // DII context ID
442                                                        userParam,
443                                                        returnPsiCtl  ) ) )
444    {
445        //printf("|%s| ERROR, LINE=%d (0x%x)\n", __FUNCTION__, __LINE__, err);
446        }
447
448    if ( err == DHL_OK )
449    {
450        // Save the current PSI monitor control in the monitor context
451        pDsmccDB->DIIMonContexts[ DIIMonContextId ].psiCtl = *returnPsiCtl;
452    }
453    else
454    {
455        pDsmccDB->DIIMonContexts[ DIIMonContextId ].isUsed = _FALSE_;
456    }
457
458    OS_GiveSemaphore( pDsmccDB->mutexSema4 );               // ==>> Mutex release
459
460        return( err );
461}
462
463/**************************************************************************
464* Function Name : DHL_PSI_CancelDII
465*
466* Description   : Cancel DII message monitoring
467*
468* Parameters    :
469*
470* Return        : DHL_RESULT
471*                                 DHL_OK  -  success
472 **************************************************************************/
473DHL_RESULT DHL_PSI_CancelDII( DHL_TBL_HANDLE psiCtl )
474{
475    DS_U32  i;
476
477    for ( i = 0; i < NUM_DII_MON_CONTEXTS; i++ )
478    {
479        if ( pDsmccDB->DIIMonContexts[ i ].isUsed && pDsmccDB->DIIMonContexts[ i ].psiCtl )
480        {
481            if ( pDsmccDB->DIIMonContexts[ i ].psiCtl == psiCtl )
482                break;
483        }
484    }
485
486    if ( i < NUM_DII_MON_CONTEXTS )
487    {
488        DHL_PSI_CancelMonitor( psiCtl );
489
490        FreeDIIContext( i );
491        return DHL_OK;
492    }
493    else
494    {
495        return DHL_FAIL_NOT_FOUND;
496    }
497}
498
499/**************************************************************************
500* Function Name : DHL_PSI_ParseDsmccDII
501*
502* Description   : Parse the entire DSMCC DII table and return the parsed
503*                                 data
504* Parameters    :
505*
506* Return        : DHL_RESULT
507*                                 DHL_OK  -  success
508 **************************************************************************/
509DHL_RESULT DHL_PSI_ParseDsmccDII( PSIDataArray_t *desc, DsmccDIIMsgPtr_t *ppDsmccDIIMsg )
510{
511        DHL_RESULT                                      err = DHL_OK;
512    DS_U8                                       **sectionArr;
513        memId_t                                 memId       = NULL;
514    memChainSetup_t                     memSetup    = { DSMCC_DII_MEM_LIMIT, NULL, NULL };
515
516    DS_U8                                       numSections;
517    dsmccDIISectionPtr_t        pDsmccDIISection;                       // DSMCC DII msg section
518
519        DIIMsgPtr_t                     spDIIMsgSection, dpDIIMsgSection;           // DII msg section
520    DsmccMsgHeaderPtr_t         spDsmccMsgHeader, dpDsmccMsgHeader;     // Dsmcc msg header
521    dsmccDIIAdaptHeaderPtr_t    spDsmccAdaptationHeader;                // Dsmcc adaptation header
522
523    //CompatblDescInfoPtr_t       spCompatblDescInfo;                     // Comp descriptor
524    ModuleInfoPtr_t             spDIIModuleInfo, dpDIIModuleInfo;       // Module info
525    DS_U8*                      spModuleInfoByte;                       // Module info bytes
526    DS_U8*                      spPrivateDataByte;                      // Private data bytes
527        DS_U16                                  i, j;
528
529
530        if ( (desc == NULL) || (ppDsmccDIIMsg == NULL) )
531        {
532                return( DHL_FAIL_INVALID_PARAM );
533        }
534
535        // sectionArr is array of pointers to DSMCC-encapsulated DII table data sections
536    //
537    sectionArr = (DS_U8 **)desc->sectPtr;
538
539    // Do sanity check
540        if ( sectionArr[0] == NULL )
541    {
542                return ( DHL_FAIL_CORE_DRIVER );
543        }
544
545        // Assume section counts is last_sectionNo + 1
546    // Get the last_sectionNo from the first section
547    // For DII message the first section is the only section and should be the last section
548    //
549        numSections = get_last_section_number( sectionArr[0] ) + 1;
550    if ( desc->numSections != numSections )
551    {
552                return (DHL_FAIL_CORE_DRIVER);
553        }
554
555        // Check whether we have all the sections in the section array
556        for ( i = 1; i < numSections; i++ )
557    {
558                if ( sectionArr[i] == NULL )
559        {
560                        return (DHL_FAIL_CORE_DRIVER);
561            }
562    }
563
564        // DII memChain creation and allocation
565        err = memChainCreate( &memId, &memSetup );
566        if ( err )
567    {
568                err = DHL_FAIL_OUT_OF_RESOURCE;
569                goto ParseExit;
570        }
571
572        // Allocate memory for DsmccDII
573        *ppDsmccDIIMsg = (DsmccDIIMsgPtr_t)((memId_t *)(memChainAlloc(memId, sizeof(DsmccDIIMsg_t) + sizeof(memId_t))) + 1);
574        if (*ppDsmccDIIMsg == NULL)
575    {
576                err = DHL_FAIL_OUT_OF_RESOURCE;
577                goto ParseExit;
578        }
579
580    // Total section numbers and allocate the memory to hold the DII msg sections
581    (*ppDsmccDIIMsg)->numSections = numSections;
582        (*ppDsmccDIIMsg)->ptrDIIMsgSections = (DIIMsgPtr_t)memChainAlloc(memId, numSections * sizeof(DIIMsg_t));
583
584        if ( (*ppDsmccDIIMsg)->ptrDIIMsgSections == NULL )
585    {
586                err = DHL_FAIL_OUT_OF_RESOURCE;
587                goto ParseExit;
588        }
589
590    //****************************************************************************/
591    // Start processing the DII message sections                                 */
592        // Parse each DSMCC DII section and copy the parsed contents                 */
593    //****************************************************************************/
594
595#if DSMCC_DEBUG
596    printf( "*** ParseDsmccDII() number of sections = %d ***\n", numSections );
597#endif
598
599    // Initialize destination pointer to DII message sections
600    dpDIIMsgSection = (*ppDsmccDIIMsg)->ptrDIIMsgSections;
601
602        for ( i = 0; i < numSections; i++, dpDIIMsgSection++ )
603    {
604        // Parse the current section
605                err = DHL_PSI_ParseDsmccDIISection( sectionArr[ i ], &pDsmccDIISection );
606
607                if ( (err != DHL_OK) || (pDsmccDIISection == NULL) )
608                        goto ParseExit;
609
610        // Initialize the "source" pointers used for data copying
611        spDIIMsgSection          = pDsmccDIISection->ptrDIIMsgSection;
612        spDsmccMsgHeader         = spDIIMsgSection->ptrDsmccMsgHeader;
613        spDsmccAdaptationHeader  = spDsmccMsgHeader->ptrDsmccAdaptationHeader;
614        //spCompatblDescInfo       = spDIIMsgSection->compatblDesc.ptrCompatblDescInfo;
615        spDIIModuleInfo          = spDIIMsgSection->ptrDIIModuleInfo;
616        spModuleInfoByte         = spDIIModuleInfo->ptrModuleInfoByte;
617        spPrivateDataByte        = spDIIMsgSection->ptrPrivateDataByte;
618
619        // Copy important repeated information into the main container structure once only
620                if ( i == 0 )
621        {
622            (*ppDsmccDIIMsg)->table_id              = pDsmccDIISection->table_id;
623            (*ppDsmccDIIMsg)->dsmcc_section_length  = pDsmccDIISection->dsmcc_section_length;
624            (*ppDsmccDIIMsg)->table_id_extension    = pDsmccDIISection->table_id_extension;
625            (*ppDsmccDIIMsg)->version_number        = pDsmccDIISection->version_number;
626            (*ppDsmccDIIMsg)->current_next_indicator= pDsmccDIISection->current_next_indicator;
627            (*ppDsmccDIIMsg)->section_number        = pDsmccDIISection->section_number;
628            (*ppDsmccDIIMsg)->last_section_number   = pDsmccDIISection->last_section_number;
629
630                        (*ppDsmccDIIMsg)->transaction_id = spDsmccMsgHeader->transaction_id;
631                        (*ppDsmccDIIMsg)->downloadId     = spDIIMsgSection->downloadId;
632                        (*ppDsmccDIIMsg)->blockSize      = spDIIMsgSection->blockSize;
633                }
634
635        // Copy DII dsmcc msg header section data
636        dpDIIMsgSection->ptrDsmccMsgHeader = (DsmccMsgHeaderPtr_t)memChainAlloc( memId, sizeof(DsmccMsgHeader_t) );
637
638            if ( dpDIIMsgSection->ptrDsmccMsgHeader == NULL )
639        {
640                    err = DHL_FAIL_OUT_OF_RESOURCE;
641                    goto ParseExit;
642            }
643        dpDsmccMsgHeader = dpDIIMsgSection->ptrDsmccMsgHeader;
644                memcpy( dpDsmccMsgHeader, spDsmccMsgHeader, sizeof(DsmccMsgHeader_t) );
645
646        // Copy the adaptation header block
647        if ( dpDsmccMsgHeader->adaptationLength > 0 )
648        {
649            dpDsmccMsgHeader->ptrDsmccAdaptationHeader =
650                (dsmccDIIAdaptHeaderPtr_t)memChainAlloc( memId, spDsmccMsgHeader->adaptationLength );
651            if ( dpDsmccMsgHeader->ptrDsmccAdaptationHeader == NULL )
652            {
653                        err = DHL_FAIL_OUT_OF_RESOURCE;
654                        goto ParseExit;
655            }
656            memcpy(     dpDsmccMsgHeader->ptrDsmccAdaptationHeader, spDsmccMsgHeader->ptrDsmccAdaptationHeader,
657                    dpDsmccMsgHeader->adaptationLength );
658        }
659
660        // Copy DII msg section data
661        dpDIIMsgSection->downloadId         = spDIIMsgSection->downloadId;
662        dpDIIMsgSection->blockSize          = spDIIMsgSection->blockSize;
663        dpDIIMsgSection->windowSize         = spDIIMsgSection->windowSize;
664        dpDIIMsgSection->ackPeriod          = spDIIMsgSection->ackPeriod;
665        dpDIIMsgSection->tCDownloadWindow   = spDIIMsgSection->tCDownloadWindow;
666        dpDIIMsgSection->tCDownloadScenario = spDIIMsgSection->tCDownloadScenario;
667
668        // Copy compatibility descriptor block
669        memcpy( (DS_U8*)&dpDIIMsgSection->compatblDesc, (DS_U8*)&spDIIMsgSection->compatblDesc, sizeof(CompatblDesc_t) );
670        if ( dpDIIMsgSection->compatblDesc.descLength > 2 )
671        {
672            DS_U8 *p_compat_sys = (DS_U8 *)NULL;
673           
674            dpDIIMsgSection->compatblDesc.descriptors =
675                (DS_U8 *)memChainAlloc( memId, dpDIIMsgSection->compatblDesc.descLength-2 );
676
677            if ( dpDIIMsgSection->compatblDesc.descriptors == NULL )
678            {
679                        err = DHL_FAIL_OUT_OF_RESOURCE;
680                        goto ParseExit;
681            }
682
683            memcpy( dpDIIMsgSection->compatblDesc.descriptors,
684                    spDIIMsgSection->compatblDesc.descriptors,
685                    dpDIIMsgSection->compatblDesc.descLength-2 );
686           
687            err=GetMpegDescriptor( dpDIIMsgSection->compatblDesc.descriptors, 
688                               dpDIIMsgSection->compatblDesc.descLength-2,
689                               COMPATBL_DESC_SYSTEM_HW,
690                               0, &p_compat_sys );
691            if (err!=DHL_OK)
692            {
693                /* If cannot find SYSTEM_HW, then try with SYSTEM_SW. */
694                err=GetMpegDescriptor( dpDIIMsgSection->compatblDesc.descriptors, 
695                                   dpDIIMsgSection->compatblDesc.descLength-2,
696                                   COMPATBL_DESC_SYSTEM_HW,
697                                   0, &p_compat_sys );
698            }
699
700            if (err==DHL_OK)
701            {
702                /* We found System_HW compatibility descriptor. */
703                CompatblDescInfoPtr_t p_desc = (CompatblDescInfoPtr_t)&dpDIIMsgSection->compatblDesc.compatblDescInfo;
704                bitBufferPtr_t          bits = NULL;
705
706                err = bitBufferCreate( &bits, p_compat_sys, dpDIIMsgSection->compatblDesc.descLength-2 );
707                if ( err )
708                {
709                        goto ParseExit;
710                }
711               
712                p_desc->descType        = bitBufferGetBits(bits, 8);
713                p_desc->descLength      = bitBufferGetBits(bits, 8);
714                p_desc->specifierType   = bitBufferGetBits(bits, 8);
715                p_desc->specifierData   = bitBufferGetBits(bits, 24);
716                p_desc->model           = bitBufferGetBits(bits, 16);
717                p_desc->version         = bitBufferGetBits(bits, 16);
718               
719                p_desc->bValid          = DS_TRUE;
720                p_desc->subDescCount    = bitBufferGetBits(bits, 8);
721               
722                if ( bits )
723                {
724                        // clean up the bitBuffer
725                        bitBufferDestroy( bits );
726                }
727            }
728        }
729
730        // Copy the DII module information data section
731        dpDIIMsgSection->numberOfModules = spDIIMsgSection->numberOfModules;
732
733        if ( dpDIIMsgSection->numberOfModules > 0 )
734        {
735            dpDIIMsgSection->ptrDIIModuleInfo =
736                (ModuleInfoPtr_t)memChainAlloc( memId, dpDIIMsgSection->numberOfModules * sizeof(ModuleInfo_t) );
737
738            if ( dpDIIMsgSection->ptrDIIModuleInfo == NULL )
739            {
740                        err = DHL_FAIL_OUT_OF_RESOURCE;
741                        goto ParseExit;
742            }
743
744            // Init module info destination ptr
745            dpDIIModuleInfo = dpDIIMsgSection->ptrDIIModuleInfo;
746
747            for ( j = 0; j < dpDIIMsgSection->numberOfModules; j++, dpDIIModuleInfo++, spDIIModuleInfo++ )
748            {
749                memcpy( dpDIIModuleInfo, spDIIModuleInfo, sizeof(ModuleInfo_t) );
750
751                if ( dpDIIModuleInfo->moduleInfoLength > 0 )
752                {
753                    DS_U8* p_desc = (DS_U8 *)NULL;
754                   
755                    dpDIIModuleInfo->ptrModuleInfoByte = (DS_U8*)memChainAlloc( memId, dpDIIModuleInfo->moduleInfoLength );
756
757                    if ( dpDIIModuleInfo->ptrModuleInfoByte == NULL )
758                    {
759                                err = DHL_FAIL_OUT_OF_RESOURCE;
760                                goto ParseExit;
761                    }
762                    // Copy the module information data bytes
763                    memcpy( dpDIIModuleInfo->ptrModuleInfoByte,
764                            spDIIModuleInfo->ptrModuleInfoByte,
765                            dpDIIModuleInfo->moduleInfoLength );
766                   
767                    /*
768                     * Parse module info descriptor.
769                     */
770                    err=GetMpegDescriptor( dpDIIModuleInfo->ptrModuleInfoByte, 
771                                       dpDIIModuleInfo->moduleInfoLength,
772                                       0xB7 /* Module Info descriptor = 0xB7 */,
773                                       0, &p_desc );
774                    if (err==DHL_OK)
775                    {
776                        dpDIIModuleInfo->module_name_length = p_desc[3];
777                        dpDIIModuleInfo->ptrModuleName = (DS_U8 *)memChainAlloc( memId, dpDIIModuleInfo->module_name_length );
778                        if ( dpDIIModuleInfo->ptrModuleName == (DS_U8 *)NULL )
779                        {
780                                    err = DHL_FAIL_OUT_OF_RESOURCE;
781                                    goto ParseExit;
782                        }
783                        memcpy( dpDIIModuleInfo->ptrModuleName, &p_desc[4], dpDIIModuleInfo->module_name_length );
784                    }
785                   
786                    /*
787                     * Parse CRC32 descriptor.
788                     */
789                    err=GetMpegDescriptor( dpDIIModuleInfo->ptrModuleInfoByte, 
790                                       dpDIIModuleInfo->moduleInfoLength,
791                                       0xB5 /* CRC32 descriptor = 0xB5 */,
792                                       0, &p_desc );
793                    if (err==DHL_OK)
794                    {
795                        dpDIIModuleInfo->bCrcFieldValid = DS_TRUE;
796                        dpDIIModuleInfo->Crc32_descriptor  = p_desc[2] << 24;
797                        dpDIIModuleInfo->Crc32_descriptor += p_desc[3] << 16;
798                        dpDIIModuleInfo->Crc32_descriptor += p_desc[4] <<  8;
799                        dpDIIModuleInfo->Crc32_descriptor += p_desc[5] <<  0;
800                    }
801                }
802            }
803        }
804        else
805        {
806            dpDIIMsgSection->ptrDIIModuleInfo = NULL;
807        }
808
809        // Copy the DII private data section
810        dpDIIMsgSection->privateDataLength = spDIIMsgSection->privateDataLength;
811
812        if ( dpDIIMsgSection->privateDataLength > 0 )
813        {
814            dpDIIMsgSection->ptrPrivateDataByte = (DS_U8*)memChainAlloc( memId, dpDIIMsgSection->privateDataLength );
815
816            if ( dpDIIMsgSection->ptrPrivateDataByte == NULL )
817            {
818                        err = DHL_FAIL_OUT_OF_RESOURCE;
819                        goto ParseExit;
820            }
821            // Copy the private information data bytes
822            memcpy( dpDIIMsgSection->ptrPrivateDataByte,
823                    spDIIMsgSection->ptrPrivateDataByte,
824                    dpDIIMsgSection->privateDataLength );
825        }
826        else
827        {
828            dpDIIMsgSection->ptrPrivateDataByte = NULL;
829        }
830
831                FreeDsmccMemChain( pDsmccDIISection );
832        }
833
834        // Parsing/copying is complete, save memId into the memChain alloc-ed
835        *(((memId_t *)(*ppDsmccDIIMsg))-1) = memId;
836
837        memId = NULL; // Reset memId so its memChain won't get destroyed
838
839ParseExit:
840
841        if ( memId )
842    {
843                memChainDestroy( memId );
844        *ppDsmccDIIMsg = NULL;
845        }
846
847        return ( err );
848}
849
850/**************************************************************************
851* Function Name : DHL_PSI_ParseDsmccDIISection
852*
853* Description   : Parse a DSMCC DII message section
854*
855* Parameters    :
856*
857* Return        : DHL_RESULT
858*                                 DHL_OK  -  success
859 **************************************************************************/
860DHL_RESULT DHL_PSI_ParseDsmccDIISection( DS_U8 *section, dsmccDIISectionPtr_t *ppDsmccDIISection )
861{
862        DHL_RESULT                                      err = DHL_OK;
863        dsmccDIISectionPtr_t    dsmccDIISectPtr = NULL;
864    DsmccMsgHeaderPtr_t     pDsmccMsgHeader;
865    DIIMsgPtr_t             pDIIMsg;
866    ModuleInfoPtr_t         pDIIModuleInfo;
867        memId_t                                 memId = NULL;
868        memChainSetup_t                 memSetup = { DSMCC_DII_MEM_LIMIT, NULL, NULL };
869
870        DS_U8                                   table_id;
871        DS_U16                                  dsmcc_section_length;
872        bitBufferPtr_t          bits = NULL;
873
874        DS_U16                                  descLength;
875    DS_U8                   *dpData;
876        DS_U16                                  i, j;
877
878        // Argument check
879        if ( section == NULL )
880        {
881                printf("ParseDsmccDIISection: NULL section addr!\n");
882                err = DHL_FAIL_INVALID_PARAM;
883                goto ParseExit;
884        }
885
886    // Perform DSM-CC DII table data validation
887    // Get table_id
888        table_id = get_table_id(section);
889
890        if ( table_id != DSMCC_DII_TABLE_ID )
891        {
892                printf("ParseDsmccDIISection: invalid table_id = %0x\n", (int) table_id);
893                err = DHL_FAIL_INVALID_PARAM;
894                goto ParseExit;
895        }
896        // Get syntax indicator: 1 = valid
897        if (get_section_syntax_indicator(section) != 1)
898    {
899                printf("ParseDsmccDIISection: section_syntax_indicator not set\n");
900                err = DHL_FAIL_INVALID_PARAM;
901                goto ParseExit;
902        }
903        // Get section length
904        dsmcc_section_length = get_section_length(section);
905
906        if ( dsmcc_section_length > (MAX_DSMCC_SECTION_LENGTH - 3) )
907    {
908                printf("ParseDsmccDIISection: invalid section_length = %0d\n", (int) dsmcc_section_length);
909                err = DHL_FAIL_INVALID_PARAM;
910                goto ParseExit;
911        }
912
913        // Create the bitBuffer object and initialize it with the current section data
914        err = bitBufferCreate( &bits, section + 3, dsmcc_section_length );
915        if ( err )
916    {
917                goto ParseExit;
918        }
919
920        // Create the memChain & allocate memory for dsmccDIISection data structure
921        err = memChainCreate( &memId, &memSetup );
922        if (err)
923    {
924                goto ParseExit;
925        }
926
927        dsmccDIISectPtr = (dsmccDIISectionPtr_t)((memId_t *)( memChainAlloc(memId, sizeof(dsmccDIISection_t) + sizeof(memId_t)) ) + 1);
928
929        if ( dsmccDIISectPtr == NULL )
930    {
931                err = DHL_FAIL_OUT_OF_RESOURCE;
932                goto ParseExit;
933        }
934
935        // Parse the section and fill the DSM-CC DII section data structure
936        dsmccDIISectPtr->table_id               = table_id;
937    dsmccDIISectPtr->dsmcc_section_length   = dsmcc_section_length;
938    dsmccDIISectPtr->table_id_extension     = bitBufferGetBits(bits, 16);   // DII transaction number
939    bitBufferSkipBits( bits, 2 );                                               // Reserved
940    dsmccDIISectPtr->version_number         = bitBufferGetBits(bits, 5);    // version number
941        dsmccDIISectPtr->current_next_indicator = bitBufferGetBits(bits, 1);    // current next indicator
942
943        if ( dsmccDIISectPtr->current_next_indicator != 1 )
944    {
945                printf("ParseDsmccDIISection: current_next_indicator not set\n");
946                err = DHL_FAIL_INVALID_PARAM;
947                goto ParseExit;
948        }
949        dsmccDIISectPtr->section_number         = bitBufferGetBits(bits, 8);    // section_number
950        dsmccDIISectPtr->last_section_number    = bitBufferGetBits(bits, 8);    // last_section_number
951
952    //****************************************************************************/
953        //* Section contents handling                                                */
954    //****************************************************************************/
955    // Allocate DII section memory
956        dsmccDIISectPtr->ptrDIIMsgSection = (DIIMsgPtr_t)memChainAlloc( memId, sizeof(DIIMsg_t) );
957
958    if ( dsmccDIISectPtr->ptrDIIMsgSection == NULL )
959    {
960                err = DHL_FAIL_OUT_OF_RESOURCE;
961                goto ParseExit;
962        }
963
964    dsmccDIISectPtr->ptrDIIMsgSection->ptrDsmccMsgHeader =
965        (DsmccMsgHeaderPtr_t)memChainAlloc( memId, sizeof(DsmccMsgHeader_t) );
966
967    if ( dsmccDIISectPtr->ptrDIIMsgSection->ptrDsmccMsgHeader == NULL )
968    {
969                err = DHL_FAIL_OUT_OF_RESOURCE;
970                goto ParseExit;
971        }
972
973    // Parse DII dsmcc header and assign them to the section data structure
974        pDsmccMsgHeader = dsmccDIISectPtr->ptrDIIMsgSection->ptrDsmccMsgHeader;
975
976    pDsmccMsgHeader->protocolDiscriminator = bitBufferGetBits(bits, 8);
977    if ( pDsmccMsgHeader->protocolDiscriminator != 0x11 )
978    {
979                printf("ParseDsmccDIISection: Invalid protocolDiscriminator = %0x\n",
980                     (int) pDsmccMsgHeader->protocolDiscriminator);
981                err = DHL_FAIL_INVALID_PARAM;
982                goto ParseExit;
983    }
984
985    pDsmccMsgHeader->dsmccType = bitBufferGetBits(bits, 8);
986    if ( pDsmccMsgHeader->dsmccType != 0x03 )
987    {
988                printf("ParseDsmccDIISection: Invalid dsmccType = %0x\n", (int) pDsmccMsgHeader->dsmccType);
989                err = DHL_FAIL_INVALID_PARAM;
990                goto ParseExit;
991    }
992
993    pDsmccMsgHeader->messageId = bitBufferGetBits(bits, 16);
994    if ( pDsmccMsgHeader->messageId != 0x1002 )
995    {
996                printf("ParseDsmccDIISection: Invalid messageId = %0x\n", (int) pDsmccMsgHeader->messageId);
997                err = DHL_FAIL_INVALID_PARAM;
998                goto ParseExit;
999    }
1000
1001    pDsmccMsgHeader->transaction_id     = bitBufferGetBits(bits, 32);
1002    bitBufferSkipBits( bits, 8 );         // Reserved
1003    pDsmccMsgHeader->adaptationLength   = bitBufferGetBits(bits, 8);
1004    pDsmccMsgHeader->messageLength      = bitBufferGetBits(bits, 16);
1005
1006
1007#if DSMCC_DEBUG
1008    printf("ParseDsmccDIISection: protocolDiscriminator   = 0x%02x\n", pDsmccMsgHeader->protocolDiscriminator );
1009    printf("ParseDsmccDIISection: dsmccType               = 0x%02x\n", pDsmccMsgHeader->dsmccType );
1010    printf("ParseDsmccDIISection: messageId               = 0x%04x\n", pDsmccMsgHeader->messageId );
1011    printf("ParseDsmccDIISection: transaction_id          = 0x%08x\n", pDsmccMsgHeader->transaction_id );
1012    printf("ParseDsmccDIISection: adaptationLength        = %d\n", pDsmccMsgHeader->adaptationLength );
1013    printf("ParseDsmccDIISection: messageLength           = %d\n", pDsmccMsgHeader->messageLength );
1014#endif
1015
1016
1017    if ( pDsmccMsgHeader->adaptationLength > 0 )
1018    {
1019        pDsmccMsgHeader->ptrDsmccAdaptationHeader =
1020            (dsmccDIIAdaptHeaderPtr_t)memChainAlloc( memId, pDsmccMsgHeader->adaptationLength );
1021        if ( pDsmccMsgHeader->ptrDsmccAdaptationHeader == NULL )
1022        {
1023                    err = DHL_FAIL_OUT_OF_RESOURCE;
1024                    goto ParseExit;
1025        }
1026
1027        // Copy the entire adaptation header block
1028        dpData = (DS_U8*)pDsmccMsgHeader->ptrDsmccAdaptationHeader;
1029                for ( j = 0; j < pDsmccMsgHeader->adaptationLength; j++ )
1030                        dpData[j] = bitBufferGetBits(bits, 8);
1031    }
1032    else
1033    {
1034        pDsmccMsgHeader->ptrDsmccAdaptationHeader = NULL;
1035    }
1036
1037    // Parse DII msg body section and assign them to the proper data structure
1038    pDIIMsg = dsmccDIISectPtr->ptrDIIMsgSection;
1039
1040    pDIIMsg->downloadId = bitBufferGetBits(bits, 32);
1041    pDIIMsg->blockSize  = bitBufferGetBits(bits, 16);
1042    pDIIMsg->windowSize = bitBufferGetBits(bits, 8);
1043    pDIIMsg->ackPeriod  = bitBufferGetBits(bits, 8);
1044    pDIIMsg->tCDownloadWindow   = bitBufferGetBits(bits, 32);
1045    pDIIMsg->tCDownloadScenario = bitBufferGetBits(bits, 32);
1046
1047    // Parse DII msg compatibility descriptor block and assign them to the proper data structure
1048    pDIIMsg->compatblDesc.descLength = bitBufferGetBits(bits, 16);
1049    pDIIMsg->compatblDesc.descCount  = bitBufferGetBits(bits, 16);
1050    pDIIMsg->compatblDesc.compatblDescInfo.bValid = DS_FALSE;
1051
1052#if DSMCC_DEBUG
1053    printf("ParseDsmccDIISection:              downloadId = 0x%08x\n", pDIIMsg->downloadId );
1054    printf("ParseDsmccDIISection:              blockSize  = %d\n", pDIIMsg->blockSize );
1055
1056    printf("ParseDsmccDIISection:              descLength = %d\n", pDIIMsg->compatblDesc.descLength );
1057#endif
1058
1059    if ( pDIIMsg->compatblDesc.descLength > 2 )
1060    {
1061        descLength = pDIIMsg->compatblDesc.descLength - 2;
1062        pDIIMsg->compatblDesc.descriptors = (DS_U8 *)memChainAlloc( memId, descLength );
1063        if ( pDIIMsg->compatblDesc.descriptors == (DS_U8 *)NULL )
1064        {
1065                    err = DHL_FAIL_OUT_OF_RESOURCE;
1066                    goto ParseExit;
1067        }
1068
1069        // Copy the entire compatibility descriptor block
1070        dpData = (DS_U8*)pDIIMsg->compatblDesc.descriptors;
1071
1072                for ( j = 0; j < descLength; j++ )
1073                        dpData[j] = bitBufferGetBits(bits, 8);
1074    }
1075    else
1076    {
1077        pDIIMsg->compatblDesc.descriptors = NULL;
1078    }
1079
1080    // Parse DII module information block and assign them to the proper data structure
1081    pDIIMsg->numberOfModules = bitBufferGetBits(bits, 16);
1082
1083#if DSMCC_DEBUG
1084    printf("ParseDsmccDIISection:         numberOfModules = %d\n", pDIIMsg->numberOfModules  );
1085#endif
1086
1087    if ( pDIIMsg->numberOfModules > 0 )
1088    {
1089        pDIIMsg->ptrDIIModuleInfo = (ModuleInfoPtr_t)memChainAlloc( memId, pDIIMsg->numberOfModules * sizeof(ModuleInfo_t) );
1090        if ( pDIIMsg->ptrDIIModuleInfo == NULL )
1091        {
1092                    err = DHL_FAIL_OUT_OF_RESOURCE;
1093                    goto ParseExit;
1094        }
1095
1096        pDIIModuleInfo = pDIIMsg->ptrDIIModuleInfo;
1097
1098        for ( i = 0; i < pDIIMsg->numberOfModules; i++, pDIIModuleInfo++ )
1099        {
1100            pDIIModuleInfo->moduleId         = bitBufferGetBits(bits, 16);
1101            pDIIModuleInfo->moduleSize       = bitBufferGetBits(bits, 32);
1102            pDIIModuleInfo->moduleVersion    = bitBufferGetBits(bits, 8);
1103            pDIIModuleInfo->moduleInfoLength = bitBufferGetBits(bits, 8);
1104            pDIIModuleInfo->module_name_length = 0;
1105            pDIIModuleInfo->bCrcFieldValid   = DS_FALSE;
1106            pDIIModuleInfo->ptrModuleName    = (DS_U8 *)NULL;
1107           
1108            if ( pDIIModuleInfo->moduleInfoLength > 0 )
1109            {
1110                pDIIModuleInfo->ptrModuleInfoByte = (DS_U8*)memChainAlloc( memId, pDIIModuleInfo->moduleInfoLength );
1111
1112                if ( pDIIModuleInfo->ptrModuleInfoByte == NULL )
1113                {
1114                            err = DHL_FAIL_OUT_OF_RESOURCE;
1115                            goto ParseExit;
1116                }
1117
1118                for ( j = 0; j < pDIIModuleInfo->moduleInfoLength; j++ )
1119                    pDIIModuleInfo->ptrModuleInfoByte[j] = bitBufferGetBits(bits, 8);
1120            }
1121        }
1122    }
1123    else
1124    {
1125        pDIIMsg->ptrDIIModuleInfo = NULL;
1126    }
1127
1128    // Parse DII private data block and assign them to the proper data structure
1129    pDIIMsg->privateDataLength = bitBufferGetBits(bits, 16);
1130
1131#if DSMCC_DEBUG
1132    printf("ParseDsmccDIISection:       privateDataLength = %d\n", pDIIMsg->privateDataLength  );
1133#endif
1134
1135    if ( pDIIMsg->privateDataLength > 0 )
1136    {
1137        pDIIMsg->ptrPrivateDataByte = (DS_U8*)memChainAlloc( memId, pDIIMsg->privateDataLength );
1138
1139        if ( pDIIMsg->ptrPrivateDataByte == NULL )
1140        {
1141                    err = DHL_FAIL_OUT_OF_RESOURCE;
1142                    goto ParseExit;
1143        }
1144
1145        for ( j = 0; j < pDIIMsg->privateDataLength; j++ )
1146            pDIIMsg->ptrPrivateDataByte[j] = bitBufferGetBits(bits, 8);
1147    }
1148    else
1149    {
1150        pDIIMsg->ptrPrivateDataByte = NULL;
1151    }
1152
1153        // Parsing complete and save memId into the memChain alloc-ed
1154        *(((memId_t *)dsmccDIISectPtr)-1) = memId;
1155
1156        memId = NULL;   // Reset memId, so dsmccDIISectPtr memChain will not get deleted
1157
1158ParseExit:
1159
1160        if ( bits )
1161    {
1162                // clean up the bitBuffer
1163                bitBufferDestroy( bits );
1164        }
1165        if ( memId )
1166    {
1167                // Incomplete parsing error, delete the dsmccDII section memChain alloc-ed
1168                memChainDestroy( memId );
1169        dsmccDIISectPtr = NULL;
1170        }
1171
1172        *ppDsmccDIISection = dsmccDIISectPtr;
1173
1174        return ( err );
1175}
1176
1177/**************************************************************************
1178* Function Name : PrintDsmccDII
1179*
1180* Description   : Dump DsmccDII message for debugging
1181*
1182* Parameters    :
1183*
1184* Return        : DHL_RESULT
1185*                                 DHL_OK  -  success
1186 **************************************************************************/
1187void DHL_PSI_PrintDsmccDII( const DsmccDIIMsgPtr_t pDsmccDIIMsg )
1188{
1189#if 1
1190
1191        DsmccDIIMsgPtr_t        ptr = pDsmccDIIMsg;
1192    DsmccMsgHeaderPtr_t     pDsmccMsgHeader;
1193    dsmccDIIAdaptHeaderPtr_t pDsmccAdaptationHeader;
1194    DS_U8*                  pAdaptByte;
1195    CompatblDescInfoPtr_t   pCompatblDescInfo;
1196    //DS_U16                  descCount;
1197    //DS_U8                   subDescCount, subDescLength;
1198    //CompatblSubDescPtr_t    pCompatblSubDesc;
1199    //DS_U8*                  pSubDescAddtlInfo;
1200    DS_U16                  numberOfModules;
1201    ModuleInfoPtr_t         pDIIModuleInfo;
1202//    DS_U8*                  pModuleInfoByte;
1203    DS_U8                   moduleInfoLength;
1204    DS_U16                  privateDataLength;
1205    DS_U8*                  pPrivateDataByte;
1206
1207    int                         i, j, k;
1208
1209        /* Argument check */
1210        printf("\n*** DSMCC Download Info Indication Message Dump ***\n");
1211
1212    // Main container data structure dump
1213        printf("      table_id                    = 0x%02X\n",    (int) ptr->table_id );                /* table_id */
1214        printf("      dsmcc_section_length        = %d\n",        (int) ptr->dsmcc_section_length );/* dsmcc_section_length */
1215        printf("      table_id_extension          = %d\n",        (int) ptr->table_id_extension );      /* table_id_extension */
1216        printf("      version_number              = %d\n",        (int) ptr->version_number );      /* version_number */
1217        printf("      current_next_indicator      = %d\n",        (int) ptr->current_next_indicator );/* current_next_indicator */
1218        printf("      firt section_number         = %d\n",        (int) ptr->section_number );      /* section_number */
1219        printf("      last_section_number         = %d\n",        (int) ptr->last_section_number );     /* last_section_number */
1220        printf("      transaction_id              = 0x%08lX\n",   ptr->transaction_id );            /* transaction_id */
1221        printf("      downloadId                  = 0x%08lX\n",   ptr->downloadId );                    /* downloadId */
1222        printf("      blockSize                   = %d\n",        (int) ptr->blockSize );               /* blockSize */
1223        printf("      numSections                 = %d\n",        (int) ptr->numSections );             /* numSections */
1224
1225    // Iterate the sections
1226        for( i = 0; i < ptr->numSections; i++ )
1227    {
1228        // Dump the header section
1229        pDsmccMsgHeader = ptr->ptrDIIMsgSections[i].ptrDsmccMsgHeader;
1230
1231        printf("\nDIIMsgSections[%d].DsmccMsgHeader:\n", i );
1232                printf("      protocolDiscriminator       = 0x%02X\n",(int)pDsmccMsgHeader->protocolDiscriminator );
1233                printf("      dsmccType                   = 0x%02X\n",(int)pDsmccMsgHeader->dsmccType );
1234                printf("      messageId                   = 0x%04X\n",(int)pDsmccMsgHeader->messageId );
1235                printf("      transaction_id              = 0x%08lX\n",pDsmccMsgHeader->transaction_id );
1236                printf("      adaptationLength            = %d\n",    (int)pDsmccMsgHeader->adaptationLength );
1237                printf("      messageLength               = %d\n",    (int)pDsmccMsgHeader->messageLength );
1238
1239        if ( pDsmccMsgHeader->adaptationLength > 0 )
1240        {
1241            pDsmccAdaptationHeader = pDsmccMsgHeader->ptrDsmccAdaptationHeader;
1242
1243                    printf("      adaptationType    = 0x%X\n", (int) pDsmccAdaptationHeader->adaptationType );
1244            if ( pDsmccAdaptationHeader->adaptationType == 0x03 )
1245            {
1246                        printf("      DIIMsgNumber    = 0x%X\n", (int) pDsmccAdaptationHeader->DIIMsgNumber );
1247            }
1248            else
1249            {
1250                pAdaptByte = (DS_U8*)&pDsmccAdaptationHeader->DIIMsgNumber;
1251                printf("      Adaptation data bytes:");
1252                for ( j = 0; j < pDsmccMsgHeader->adaptationLength-1; j++ )
1253                {
1254                    if ( (j % 36) == 0 )
1255                        printf("\n0x%02X ", (int) pAdaptByte[j] );
1256                    else
1257                        printf("0x%02X ", (int) pAdaptByte[j] );
1258                }
1259            }
1260        }
1261
1262        // Dump the body section
1263        printf("DIIMsgSections[%d].downloadId      = 0x%08lX\n",  i,  ptr->ptrDIIMsgSections[i].downloadId );
1264        printf("DIIMsgSections[%d].blockSize       = %d\n",      i,  (int) ptr->ptrDIIMsgSections[i].blockSize );
1265        printf("DIIMsgSections[%d].windowSize      = %d\n",      i,  (int) ptr->ptrDIIMsgSections[i].windowSize );
1266        printf("DIIMsgSections[%d].ackPeriod       = %d\n",      i,  (int) ptr->ptrDIIMsgSections[i].ackPeriod );
1267        printf("DIIMsgSections[%d].tCDownloadWindow   = %lu\n",  i,  ptr->ptrDIIMsgSections[i].tCDownloadWindow );
1268        printf("DIIMsgSections[%d].tCDownloadScenario = %lu\n",  i,  ptr->ptrDIIMsgSections[i].tCDownloadScenario );
1269
1270        // Dump the compatibility descriptor section
1271        printf("\nDIIMsgSections[%d].compatblDesc:\n", i );
1272                printf("      descLength  = %d\n",  (int) ptr->ptrDIIMsgSections[i].compatblDesc.descLength );
1273                printf("      descCount   = %d\n",  (int) ptr->ptrDIIMsgSections[i].compatblDesc.descCount );
1274
1275        if ( ptr->ptrDIIMsgSections[i].compatblDesc.descCount > 0 && ptr->ptrDIIMsgSections[i].compatblDesc.compatblDescInfo.bValid )
1276        {
1277            pCompatblDescInfo = &(ptr->ptrDIIMsgSections[i].compatblDesc.compatblDescInfo);
1278#if 1
1279                        printf("      descriptorType      = 0x%02X\n",  (int) pCompatblDescInfo->descType );
1280                        printf("      descriptorLength    = %d\n",      (int) pCompatblDescInfo->descLength );
1281                        printf("      specifierType       = 0x%02X\n",  (int) pCompatblDescInfo->specifierType );
1282                        printf("      specifierType       = 0x%06X (%s)\n",  (int) pCompatblDescInfo->specifierData,
1283                             pCompatblDescInfo->specifierData == 0x108A ? "Teralogic" : 
1284                             pCompatblDescInfo->specifierData == 0x1E1B ? "Digital Stream Technology" : "Unknown" );
1285
1286                        printf("      model               = 0x%04X\n",  (int) pCompatblDescInfo->model );
1287                        printf("      version             = 0x%04X\n",  (int) pCompatblDescInfo->version );
1288                        printf("      subDescriptorCount  = %d\n",      (int) pCompatblDescInfo->subDescCount );
1289#else
1290            descCount = ptr->ptrDIIMsgSections[i].compatblDesc.descCount;
1291            for ( j = 0; j < descCount; j++ )
1292            {
1293                printf("\n");
1294                        printf("      descriptorType      = 0x%02X\n",  (int) pCompatblDescInfo->descType );
1295                        printf("      descriptorLength    = %d\n",      (int) pCompatblDescInfo->descLength );
1296                        printf("      specifierType       = 0x%02X\n",  (int) pCompatblDescInfo->specifierType );
1297                        printf("      model               = %d\n",      (int) pCompatblDescInfo->model );
1298                        printf("      version             = %d\n",      (int) pCompatblDescInfo->version );
1299                        printf("      subDescriptorCount  = %d\n",      (int) pCompatblDescInfo->subDescCount );
1300
1301                if ( (subDescCount = pCompatblDescInfo[j].subDescCount) > 0 )
1302                {
1303                    pCompatblSubDesc = (CompatblSubDescPtr_t)((DS_U8*)&pCompatblDescInfo->subDescCount + 1);
1304                    for ( k = 0; k < subDescCount; k++ )
1305                    {
1306                                printf("      subDescriptor[%d].subDescriptorType    = 0x%02X\n", k, (int) pCompatblSubDesc->subDescType );
1307                                printf("      subDescriptor[%d].subDescriptorLength  = %d\n",     k, (int) pCompatblSubDesc->subDescLength );
1308
1309                        if ( (subDescLength = pCompatblSubDesc->subDescLength) > 0 )
1310                        {
1311                            printf("      subDescriptor[%d].additionalInformation:\n", k);
1312
1313                            pSubDescAddtlInfo = (DS_U8*)&pCompatblSubDesc->subDescInfoByte;
1314                            for ( l = 0; l < subDescLength; l++ )
1315                            {
1316                                if ( (l % 36) == 0 )
1317                                    printf("\n0x%02X ", (int) pSubDescAddtlInfo[l] );
1318                                else
1319                                    printf("0x%02X ", (int) pSubDescAddtlInfo[l] );
1320                            }
1321                        }
1322
1323                        // Next compatibility subDescriptor section
1324                        pCompatblSubDesc = (CompatblSubDescPtr_t)(((DS_U8*)pCompatblSubDesc) + subDescLength + 2);
1325                    }
1326                }
1327
1328                // Next compatibilityDescriptor section
1329                pCompatblDescInfo = (CompatblDescInfoPtr_t)(((DS_U8*)pCompatblDescInfo) + pCompatblDescInfo->descLength + 2);
1330            }
1331#endif
1332        }
1333
1334        // Dump the module info section
1335        printf("\nDIIMsgSections[%d].numberOfModules = %d\n\n", i, (int) ptr->ptrDIIMsgSections[i].numberOfModules );
1336
1337        if ( (numberOfModules = ptr->ptrDIIMsgSections[i].numberOfModules) > 0 )
1338        {
1339            pDIIModuleInfo = ptr->ptrDIIMsgSections[i].ptrDIIModuleInfo;
1340
1341            for ( j = 0; j < numberOfModules; j++ )
1342            {
1343                printf("DIIModuleInfo[%d]: \n", j);
1344                printf("      moduleId        = %d\n", (int) pDIIModuleInfo[j].moduleId );
1345                printf("      moduleSize      = %lu\n", pDIIModuleInfo[j].moduleSize );
1346                printf("      moduleVersion   = %d\n", (int) pDIIModuleInfo[j].moduleVersion );
1347                printf("      moduleInfoLength= %d\n", (int) pDIIModuleInfo[j].moduleInfoLength );
1348                if ( (moduleInfoLength = pDIIModuleInfo[j].moduleInfoLength) > 0 )
1349                {
1350                    printf("      module info bytes\n");
1351                    if ( pDIIModuleInfo[j].bCrcFieldValid )
1352                        printf("           CRC32: 0x%08lX\n", pDIIModuleInfo[j].Crc32_descriptor );
1353                    if ( pDIIModuleInfo[j].module_name_length )
1354                    {
1355
1356#ifndef CONV_TO_ASCII
1357#define CONV_TO_ASCII(x)    ( ((x) >= ' ' && (x) <= '~') ? (x) : '.' )
1358#endif
1359                        printf("           ModuleName: ");
1360                        for ( k = 0; k < pDIIModuleInfo[j].module_name_length; k++ )
1361                        {
1362                            printf("%c", CONV_TO_ASCII(pDIIModuleInfo[j].ptrModuleName[k]));
1363                        }
1364                        printf("\n");
1365#undef CONV_TO_ASCII
1366                    }
1367#if 0
1368                    pModuleInfoByte = pDIIModuleInfo[j].ptrModuleInfoByte;
1369
1370                    for ( k = 0; k < moduleInfoLength; k++ )
1371                    {
1372                        if ( (k % 36) == 0 )
1373                            printf("\n0x%02X ", (int) pModuleInfoByte[k] );
1374                        else
1375                            printf("0x%02X ", (int) pModuleInfoByte[k] );
1376                    }
1377#endif
1378                }
1379            }
1380        }
1381
1382        // Dump the private data section
1383        printf("\nDIIMsgSections[%d].privateDataLength = %d\n", i, (int) ptr->ptrDIIMsgSections[i].privateDataLength );
1384
1385        if ( (privateDataLength = ptr->ptrDIIMsgSections[i].privateDataLength) > 0 )
1386        {
1387            printf("DIIMsgSections[%d].privateData:\n", i);
1388
1389            pPrivateDataByte = ptr->ptrDIIMsgSections[i].ptrPrivateDataByte;
1390
1391            for ( j = 0; j < privateDataLength; j++ )
1392            {
1393                if ( (j % 36) == 0 )
1394                    printf("\n0x%02X ", (int) pPrivateDataByte[j] );
1395                else
1396                    printf("0x%02X ", (int) pPrivateDataByte[j] );
1397            }
1398        }
1399        }
1400#endif
1401}
1402
1403DHL_RESULT DHL_PSI_GetDsmccDII( DHL_PSI_HANDLE sysInfo,
1404                                                        DS_U16 pid, 
1405                                                        DS_U16 transactionId, 
1406                                                        DsmccDIIMsgPtr_t *returnDII, 
1407                                                        int timeOut )
1408{
1409
1410        void *returnPSICtl = NULL;
1411        DHL_RESULT err = DHL_OK;
1412        PSIEventProcData_t      procData;
1413        int res = 0;
1414       
1415        procData.desc = NULL;
1416        procData.err = (DS_U32)DHL_OK;
1417        procData.hEvent = OS_CreateBinarySemaphore( "semDsmccDII", 0, 0 );
1418    if (procData.hEvent == (OS_SEMAPHORE_ID)0)
1419    {
1420        printf ("DHL_PSI_GetPAT : OS_CreateBinarySemaphore() fails.\r\n");
1421        return DHL_FAIL_OUT_OF_RESOURCE;
1422    }   
1423
1424//DHL_RESULT DHL_PSI_MonitorDsmccDII( DHL_PSI_HANDLE sysInfo, DS_U16 Pid, DS_U16 transactionId, DsmccEventProc_t pfCallbackProc, DHL_TBL_HANDLE *returnPsiCtl )
1425
1426        if ((err = DHL_PSI_MonitorDsmccDII(sysInfo,
1427                                                  pid,
1428                                                  transactionId,
1429                                                  0,
1430                                                  (DS_U32)&procData,
1431                                                  &returnPSICtl))) {
1432                goto done;
1433        }
1434
1435        //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut );
1436        res = OS_TakeSemaphore_Wait( procData.hEvent, timeOut );
1437    if (res != 0)
1438     {
1439        #ifdef PSI_DBG
1440        printf("DHL_PSI_GetPMT : OS_TakeSemaphore_Wait TIMEOUT %d \r\n", timeOut);
1441        #endif
1442       
1443        //Do nothing for this.
1444        //AtiCore_EventReset( procData.hEvent );
1445        err = DHL_FAIL_TIMEOUT;
1446        goto done2;
1447     }   
1448       
1449
1450        if ((err = (DHL_RESULT)(procData.err))) {
1451                printf("DHL_PSI_GetPMT : procData.err = %d \r\n",  err );
1452                goto done2;
1453        }
1454        *returnDII = NULL;
1455        err = DHL_PSI_ParseDsmccDII( (PSIDataArray_t *)procData.desc, returnDII );
1456
1457done2:
1458        DHL_PSI_CancelDII(returnPSICtl);
1459        if( procData.desc )
1460        DD_PSI_FreePSIData(procData.desc);
1461
1462done:
1463       
1464        if(procData.hEvent)
1465        {
1466                //AtiCore_EventDelete(procData.hEvent);
1467                OS_DeleteSemaphore(procData.hEvent);
1468        }
1469        return(err);
1470}
1471
1472
1473/**************************************************************************
1474* Function Name : dsmccDDBEventProc
1475*
1476* Description   : DII event handler
1477*
1478* Parameters    :
1479*
1480* Return        :
1481*
1482 **************************************************************************/
1483static void dsmccDDBEventProc( PSIEvent psiEvent, DHL_TBL_HANDLE psiCtl, DS_U32 userParam )
1484{
1485        DHL_RESULT              err = DHL_OK;
1486        DsmccMsg_t              dsmccMsg;
1487        PSIDataArray_t  *desc = NULL;
1488        DS_U32                  DDBMonContextId = userParam;
1489       
1490    if ( pDsmccDB )
1491    {
1492        // PSI callback should not block
1493        ////OS_TakeSemaphore( pDsmccDB->mutexSema4 );    // ==>> Mutex access
1494            switch ( psiEvent )
1495        {
1496            case psiDataReceived :
1497                {
1498                        err = DD_PSI_ReadPSIData( psiCtl, &desc );
1499
1500                        if ( err != DHL_OK || (desc == NULL) )
1501                        {
1502                                printf("\ndsmccDDBEventProc: DD_PSI_ReadPSIData returned 0x%x\n",err);
1503                                break;
1504                        }
1505
1506                // Dispatch the event and data received to dsmcc main thread
1507                dsmccMsg.event      = eDsmccDDBDataReceived;
1508                    dsmccMsg.userParam  = userParam;
1509                    dsmccMsg.psiCtl     = psiCtl;
1510                dsmccMsg.desc       = desc;
1511
1512                    OS_SendMessage( pDsmccDB->DDBMonContexts[ DDBMonContextId ].dsmccQ, (DS_U32 *)&dsmccMsg, sizeof(dsmccMsg) );
1513
1514                break;
1515                }
1516
1517            default:
1518
1519                break;
1520            }
1521        ////OS_GiveSemaphore( pDsmccDB->mutexSema4 );    // ==>> Mutex release
1522    }
1523}
1524
1525/**************************************************************************
1526* Function Name : DHL_PSI_MonitorDsmccDDB
1527*
1528* Description   : Setup DDB message monitoring and filters
1529*
1530* Parameters    :
1531*
1532* Return        : DHL_RESULT
1533*                                 noErrror  -  success
1534 **************************************************************************/
1535static DHL_RESULT CreateDDBContext( DS_U32 downloadId, DS_U16 moduleId, DS_U8 moduleVersion, DS_U32 moduleSize, DS_U16 blockSize,
1536                          DsmccEventProc_t pfCallbackProc, DsmccStatusProc_t pfStatusProc, DS_U32 *pDDBMonContextId );
1537DHL_RESULT InitDDBContext( DDBMsgMonContextPtr_t pDDBMsgMonContext );
1538static void FreeDDBContext( DS_U32 DDBMonContextId );
1539static DHL_RESULT InitDsmccDDBThread(DS_U32 DDBMonContextId);
1540//static DHL_RESULT CloseDsmccDDBThread(DS_U32 DDBMonContextId);
1541DHL_RESULT DHL_PSI_MonitorDsmccDDB( DHL_PSI_HANDLE sysInfo, DS_U16 Pid, DS_U32 downloadId, DS_U16 moduleId, DS_U8 moduleVersion, DS_U32 moduleSize, DS_U16 blockSize,
1542                         DsmccEventProc_t pfCallbackProc, DsmccStatusProc_t pfStatusProc, DHL_PSI_HANDLE *returnPsiCtl )
1543{
1544        DHL_RESULT                      err = DHL_OK;
1545        PSIMask_t                               *pref;
1546    DS_U32                  DDBMonContextId;
1547    DS_BOOL                    isActive;
1548    int                                         Priority = 80;
1549
1550    // Check if the dsmcc thread is up and running...
1551    isActive = (pDsmccDB) ? pDsmccDB->isActive : _FALSE_;
1552    if ( !isActive )
1553    {
1554        err = DHL_PSI_ActivateDsmcc(&Priority);
1555        if ( err != DHL_OK ) {
1556                printf( "DHL_PSI_ActivateDsmcc: failure. (0x%x)\n", err );
1557                return( DHL_FAIL_NOT_CONNECTED );
1558        } else {
1559                    isActive = (pDsmccDB) ? pDsmccDB->isActive : _FALSE_;
1560                if ( !isActive ) {
1561                        printf( "CreateDIIContext: DSMCC thread is not active\n" );
1562                        return( DHL_FAIL_NOT_CONNECTED );
1563                    }
1564            }
1565    }
1566
1567    // Check function arguments
1568    if ( (sysInfo == NULL) || (returnPsiCtl == NULL) )
1569    {
1570        return( DHL_FAIL_NULL_POINTER );
1571    }
1572
1573    if ( !(moduleSize && blockSize) )
1574    {
1575        return( DHL_FAIL_INVALID_PARAM );
1576    }
1577
1578        // Acquire the table data by the specified filter(s)
1579        // moduleId´Â ¾î¶»°Ô ¼³Á¤Çϳª?
1580        if ((err = DD_PSI_GetDsmccPSIMask       ( &pref,
1581                                                                                tid_dsmcc_download_data_block,  // DII Table ID
1582                                                                                DSMCC_MESSAGE_DDB,
1583                                                                                _TRUE_))) 
1584        {
1585                return( err );
1586        }
1587
1588
1589    // Create DDB monitoring context
1590    OS_TakeSemaphore( pDsmccDB->mutexSema4 );               // ==>> Mutex access
1591
1592    err = CreateDDBContext( downloadId, moduleId, moduleVersion, moduleSize, blockSize, pfCallbackProc, pfStatusProc, &DDBMonContextId );
1593    if ( err != DHL_OK )
1594    {
1595        OS_GiveSemaphore( pDsmccDB->mutexSema4 );           // ==>> Mutex release
1596        return( err );
1597    }
1598
1599        err = InitDDBContext(&pDsmccDB->DDBMonContexts[ DDBMonContextId ]);
1600    if ( err != DHL_OK )
1601    {
1602        OS_GiveSemaphore( pDsmccDB->mutexSema4 );           // ==>> Mutex release
1603        FreeDDBContext(DDBMonContextId);
1604        return( err );
1605    }
1606
1607        err = InitDsmccDDBThread( DDBMonContextId );
1608        if ( err != DHL_OK )
1609    {
1610        OS_GiveSemaphore( pDsmccDB->mutexSema4 );           // ==>> Mutex release
1611        FreeDDBContext(DDBMonContextId);
1612        return( err );
1613    }
1614
1615    // Start monitoring for the dsmcc DDB section
1616        if ( (err = DD_PSI_MonitorPSIPid(
1617                                                        sysInfo,                        // Transport Demux Unit
1618                                                        Pid,                            // Packet ID to filter the DSM-CC DII msgs
1619                                                        sectionMode,                // Anytime a section is received
1620                                                        psiContinuous,              // Continuous mode
1621                                                        pref,                       // PSI filter
1622                                                        MAX_DSMCC_SECTION_LENGTH,   // 4Kb
1623                                                        MAX_DSMCC_SECTIONS,         // MIN_DSMCC_SECTIONS,         // Number of sections to be returned is 1
1624                                                        dsmccDDBEventProc,          // DII event handler
1625                                                        DDBMonContextId,            // DDB monitor context ID
1626                                                        returnPsiCtl  ) ) )
1627    {
1628        }
1629
1630    if ( err == DHL_OK )
1631    {
1632        // Save the current PSI monitor control in the monitor context
1633        pDsmccDB->DDBMonContexts[ DDBMonContextId ].psiCtl = *returnPsiCtl;
1634    }
1635    else
1636    {
1637        pDsmccDB->DDBMonContexts[ DDBMonContextId ].isUsed = _FALSE_;
1638    }
1639
1640    OS_GiveSemaphore( pDsmccDB->mutexSema4 );               // ==>> Mutex release
1641
1642        return( err );
1643}
1644
1645/**************************************************************************
1646* Function Name : DHL_PSI_CancelDDB
1647*
1648* Description   : Cancel DDB message monitoring
1649*
1650* Parameters    :
1651*
1652* Return        : DHL_RESULT
1653*                                 noErrror  -  success
1654 **************************************************************************/
1655static void FreeDBBMemChain( DS_U32 DDBMonContextId );
1656static void FreeDDBContext( DS_U32 DDBMonContextId );
1657DHL_RESULT DHL_PSI_CancelDDB( DHL_PSI_HANDLE psiCtl )
1658{
1659        DHL_RESULT err=DHL_OK;
1660    DS_U32  i;
1661
1662    for ( i = 0; i < NUM_DDB_MON_CONTEXTS; i++ )
1663    {
1664        if ( pDsmccDB->DDBMonContexts[ i ].isUsed &&
1665             pDsmccDB->DDBMonContexts[ i ].isInitialized &&
1666             pDsmccDB->DDBMonContexts[ i ].psiCtl )
1667        {
1668            if ( pDsmccDB->DDBMonContexts[ i ].psiCtl == psiCtl )
1669                break;
1670        }
1671    }
1672
1673    if ( i < NUM_DDB_MON_CONTEXTS )
1674    {
1675        DHL_PSI_CancelMonitor( psiCtl );
1676
1677                //err = CloseDsmccDDBThread(i);
1678                if ( err != DHL_OK )
1679                        printf("%s| ERROR, LINE=%d. (0x%x)\n", __FUNCTION__, __LINE__, err);
1680               
1681        // Free the DDB module mem chain and all internal memory usage when finish
1682        FreeDBBMemChain( i );
1683        FreeDDBContext( i );
1684        return DHL_OK;
1685    }
1686    else
1687    {
1688        return DHL_FAIL_NOT_FOUND;
1689    }
1690}
1691
1692static DDBMsgMonContext_t *DD_PSI_GetDsmccDDBContext(DHL_PSI_HANDLE psiCtl)
1693{
1694    DS_U32  i;
1695
1696    for ( i = 0; i < NUM_DDB_MON_CONTEXTS; i++ )
1697    {
1698        if ( pDsmccDB->DDBMonContexts[ i ].isUsed &&
1699             pDsmccDB->DDBMonContexts[ i ].isInitialized &&
1700             pDsmccDB->DDBMonContexts[ i ].psiCtl )
1701        {
1702            if ( pDsmccDB->DDBMonContexts[ i ].psiCtl == psiCtl )
1703                break;
1704        }
1705    }
1706
1707    if ( i < NUM_DDB_MON_CONTEXTS )
1708    {
1709        return &pDsmccDB->DDBMonContexts[i];
1710    }
1711    else
1712    {
1713        return (DDBMsgMonContext_t *)0;
1714    }
1715}       
1716
1717static DDBModule_t *DD_PSI_GetDsmccDDBModule(DHL_PSI_HANDLE psiCtl)
1718{
1719    DS_U32  i;
1720
1721    for ( i = 0; i < NUM_DDB_MON_CONTEXTS; i++ )
1722    {
1723        if ( pDsmccDB->DDBMonContexts[ i ].isUsed &&
1724             pDsmccDB->DDBMonContexts[ i ].isInitialized &&
1725             pDsmccDB->DDBMonContexts[ i ].psiCtl )
1726        {
1727            if ( pDsmccDB->DDBMonContexts[ i ].psiCtl == psiCtl )
1728                break;
1729        }
1730    }
1731
1732    if ( i < NUM_DDB_MON_CONTEXTS )
1733    {
1734        return pDsmccDB->DDBMonContexts[i].pDDBModule;
1735    }
1736    else
1737    {
1738        return (DDBModule_t *)0;
1739    }
1740}
1741
1742void *DHL_PSI_GetDsmccDDBBuffer(DHL_PSI_HANDLE psiCtl)
1743{
1744        DDBModule_t *pDDBModule;
1745       
1746        if (psiCtl == (DHL_PSI_HANDLE)0) {
1747                printf("%s| ERROR, Null pointer is passed\n", __FUNCTION__);
1748                return (void *)0;
1749        }
1750       
1751        pDDBModule = DD_PSI_GetDsmccDDBModule(psiCtl);
1752        if ( pDDBModule == (DDBModule_t *)0 )
1753                return (void *)0;
1754       
1755        return pDDBModule->pDDBBuffer;
1756}
1757
1758void DHL_PSI_SetDsmccAllocFreeFunc(void *AllocFunc, void *FreeFunc)
1759{
1760        g_pDsmccAllocFunc = (fnAlloc_t)AllocFunc;
1761        g_pDsmccFreeFunc = (fnFree_t)FreeFunc;
1762}
1763
1764int DHL_PSI_GetDsmccDDBProgress(DHL_PSI_HANDLE psiCtl)
1765{
1766        DDBMsgMonContext_t *pDDBCtx;
1767        int curProgress;
1768       
1769        if (psiCtl == (DHL_PSI_HANDLE)0) {
1770                printf("%s| ERROR, Null pointer is passed\n", __FUNCTION__);
1771                return -1;
1772        }
1773       
1774        pDDBCtx = DD_PSI_GetDsmccDDBContext(psiCtl);
1775        if ( pDDBCtx == (DDBMsgMonContext_t *)0 )
1776                return -1;
1777       
1778        if (pDDBCtx->blockTotal)
1779                curProgress = (pDDBCtx->blockRecvd*100)/pDDBCtx->blockTotal;
1780        else
1781                return -1;
1782       
1783        return curProgress;
1784}
1785
1786void DHL_PSI_FreeDDBBuffer(void *addr)
1787{
1788        DSMCC_FREE(addr);
1789}
1790
1791/**************************************************************************
1792* Function Name : CreateDDBContext
1793*
1794* Description   : This function is with "mutexSema4" protection
1795*                 Allocate a memory block to store the DDB monitoring
1796*                 parameters and other buffer addresses
1797* Parameters    :
1798*
1799* Return        : DHL_RESULT
1800*                                 noErrror  -  success
1801 **************************************************************************/
1802static DHL_RESULT CreateDDBContext( DS_U32 downloadId, DS_U16 moduleId, DS_U8 moduleVersion, DS_U32 moduleSize, DS_U16 blockSize,
1803                          DsmccEventProc_t pfCallbackProc, DsmccStatusProc_t pfStatusProc, DS_U32 *pDDBMonContextId )
1804{
1805        DHL_RESULT                 err = DHL_OK;
1806    DDBMsgMonContextPtr_t   pDDBMsgMonContext;
1807    DS_U32                  i;
1808
1809    // Alloc memory block for DDB monitoring context and store all the DDB monitoring parameters
1810    // in the allocated memory block
1811    for ( i = 0; i < NUM_DDB_MON_CONTEXTS; i++ )
1812    {
1813        if ( !pDsmccDB->DDBMonContexts[ i ].isUsed )
1814        {
1815            break;
1816        }
1817    }
1818
1819
1820    if ( i >= NUM_DDB_MON_CONTEXTS )
1821    {
1822        printf( "CreateDDBContext: Out of monitoring context\n" );
1823        err = DHL_FAIL_OUT_OF_RESOURCE;
1824        return err;
1825    }
1826
1827    // Initialize DDB monitoring context structure
1828    pDDBMsgMonContext = &pDsmccDB->DDBMonContexts[ i ];
1829    memset( (DS_U8*)pDDBMsgMonContext, 0, sizeof(DDBMsgMonContext_t) );
1830
1831    pDDBMsgMonContext->isUsed         = _TRUE_;                 // This context is now being used
1832    pDDBMsgMonContext->isInitialized  = _FALSE_;                // Buffers are not initialized
1833    pDDBMsgMonContext->downloadId     = downloadId;           // DDB download ID
1834    pDDBMsgMonContext->moduleId       = moduleId;             // DDB module ID
1835    pDDBMsgMonContext->moduleVersion  = moduleVersion;        // Module version
1836    pDDBMsgMonContext->moduleSize     = moduleSize;           // Module size
1837    pDDBMsgMonContext->blockSize      = blockSize;            // Module blcok size
1838    pDDBMsgMonContext->pfCallbackProc = pfCallbackProc;       // Client callback func ptr
1839    pDDBMsgMonContext->pfStatusProc   = pfStatusProc;         // Client callback func ptr
1840
1841#if DSMCC_DISKFILE
1842    pDDBMsgMonContext->pFileBlockData = NULL;
1843    pDDBMsgMonContext->pFileBlockDir  = NULL;
1844    pDDBMsgMonContext->fhDDBData      = -1;
1845    pDDBMsgMonContext->fhDDBDir       = -1;
1846#endif
1847
1848    *pDDBMonContextId = i;
1849
1850    return err;
1851}
1852
1853/**************************************************************************
1854* Function Name : FreeDDBContext
1855*
1856* Description   : Free all memory allocated for internal usage except
1857*                                 those allocated using memId memory chain
1858* Parameters    :
1859*
1860* Return        : DHL_RESULT
1861*                                 noErrror  -  success
1862 **************************************************************************/
1863static void FreeDDBContext( DS_U32 DDBMonContextId )
1864{
1865    DDBMsgMonContextPtr_t pDDBMsgMonContext;
1866
1867    if ( DDBMonContextId < NUM_DDB_MON_CONTEXTS )
1868    {
1869        pDDBMsgMonContext = &pDsmccDB->DDBMonContexts[ DDBMonContextId ];
1870
1871        if ( pDDBMsgMonContext->pBlockRecvBitFlags )
1872            free( (pDDBMsgMonContext->pBlockRecvBitFlags) );
1873
1874        OS_TakeSemaphore( pDsmccDB->mutexSema4 );  // Mutex access
1875        pDsmccDB->DDBMonContexts[ DDBMonContextId ].isUsed          = _FALSE_;
1876        pDsmccDB->DDBMonContexts[ DDBMonContextId ].isInitialized   = _FALSE_;
1877        pDsmccDB->DDBMonContexts[ DDBMonContextId ].psiCtl          = NULL;
1878        OS_GiveSemaphore( pDsmccDB->mutexSema4 );  // Mutex release
1879    }
1880}
1881
1882/**************************************************************************
1883* Function Name : InitDDBContext
1884*
1885* Description   : Allocate memory buffers for DDB msg monitoring and
1886*                 initialize other variables
1887* Parameters    :
1888*
1889* Return        : DHL_RESULT
1890*                                 noErrror  -  success
1891 **************************************************************************/
1892DHL_RESULT InitDDBContext( DDBMsgMonContextPtr_t pDDBMsgMonContext )
1893{
1894        DHL_RESULT          err;
1895    DS_U16              bitFlagBytes;
1896        memId_t                 memId       = NULL;
1897    memChainSetup_t             memSetup    = { (sizeof(DDBModule_t) + (DSMCC_DDB_MEM_LIMIT*256)), NULL, NULL };
1898               
1899        err = memChainCreate( &memId, &memSetup );
1900        if ( err )
1901    {
1902                err = DHL_FAIL_OUT_OF_RESOURCE;
1903                goto FailExit;
1904        }
1905
1906        // Allocate memory for dsmcc DDB message
1907        pDDBMsgMonContext->pDDBModule =
1908        (DDBModulePtr_t)((memId_t *)(memChainAlloc(memId, sizeof(DDBModule_t) + sizeof(memId_t))) + 1);
1909
1910        if ( pDDBMsgMonContext->pDDBModule == NULL )
1911    {
1912                err = DHL_FAIL_OUT_OF_RESOURCE;
1913
1914        if ( pDDBMsgMonContext->pfStatusProc != NULL )
1915        {
1916            (*pDDBMsgMonContext->pfStatusProc)( pDDBMsgMonContext->psiCtl, eDsmccDDBOutOfCPUMemory, -1 );
1917        }
1918
1919                goto FailExit;
1920        }
1921
1922       
1923        //pDDBMsgMonContext->pDDBModule->pDDBBuffer = (DS_U8*)memChainAlloc(memId, pDDBMsgMonContext->moduleSize );
1924        //pDDBMsgMonContext->pDDBModule->pDDBBuffer = (DS_U8*)GetTLPhysMemory(pDDBMsgMonContext->moduleSize, _TRUE_,displayUnit_main,0, "DMCC mem", 0);
1925        pDDBMsgMonContext->pDDBModule->pDDBBuffer = (DS_U8*)DSMCC_MALLOC(pDDBMsgMonContext->moduleSize);
1926        printf(" #### Allocated mem from Phy mem 0x%lx size = %lu \n\n\n",(DS_U32)pDDBMsgMonContext->pDDBModule->pDDBBuffer,pDDBMsgMonContext->moduleSize);
1927       
1928        if ( pDDBMsgMonContext->pDDBModule->pDDBBuffer == NULL )
1929    {
1930        {
1931            // If unable to allocate memory for the module, return a out of memory error
1932                    err = DHL_FAIL_OUT_OF_RESOURCE;
1933                    goto FailExit;
1934        }
1935        }
1936    else
1937    {
1938        pDDBMsgMonContext->pDDBModule->dataType = eDDBMemData;      // Memory buffering mode
1939    }
1940
1941    // Calculate the total number of blocks to allocate block-received bit flag buffer
1942    // For a 256MB module the buffer size is about 64K (256/4 * 1024)
1943    pDDBMsgMonContext->blockTotal    = pDDBMsgMonContext->moduleSize / (DS_U32)pDDBMsgMonContext->blockSize;
1944    pDDBMsgMonContext->lastBlockSize = pDDBMsgMonContext->moduleSize % (DS_U32)pDDBMsgMonContext->blockSize;
1945    if ( pDDBMsgMonContext->lastBlockSize )
1946        pDDBMsgMonContext->blockTotal++;
1947
1948    // Calculate the number of bytes required to hold the blocks' bit flags
1949    bitFlagBytes = pDDBMsgMonContext->blockTotal / 8;
1950
1951    if ( pDDBMsgMonContext->blockTotal % 8 )
1952        bitFlagBytes++;
1953
1954    // Allocate the bit flags and clear all the flags
1955    pDDBMsgMonContext->pBlockRecvBitFlags = (DS_U8 *)malloc( bitFlagBytes );
1956
1957    if ( pDDBMsgMonContext->pBlockRecvBitFlags == NULL )
1958    {
1959                err = DHL_FAIL_OUT_OF_RESOURCE;
1960                goto FailExit;
1961
1962    }
1963    memset( (DS_U8*)pDDBMsgMonContext->pBlockRecvBitFlags, 0, bitFlagBytes );
1964
1965    // At this point everything is setup and good to go!
1966    pDDBMsgMonContext->memId                      = memId;
1967    pDDBMsgMonContext->blockRecvd                 = 0;
1968    pDDBMsgMonContext->pDDBModule->moduleId       = pDDBMsgMonContext->moduleId;
1969    pDDBMsgMonContext->pDDBModule->moduleVersion  = pDDBMsgMonContext->moduleVersion;
1970    pDDBMsgMonContext->pDDBModule->moduleSize     = pDDBMsgMonContext->moduleSize;
1971    pDDBMsgMonContext->pDDBModule->blockTotal     = pDDBMsgMonContext->blockTotal;
1972    pDDBMsgMonContext->pDDBModule->blockSize      = pDDBMsgMonContext->blockSize;
1973    pDDBMsgMonContext->isInitialized              = _TRUE_;     // Set the initialized flag to _TRUE_
1974
1975        // Save memId into the memChain alloc-ed
1976        *(((memId_t *)(pDDBMsgMonContext->pDDBModule))-1) = memId;
1977
1978        memId = NULL;   // Reset memId so its memChain won't get destroyed
1979
1980
1981#if DSMCC_DEBUG
1982    printf( "DDBContext initialized:  blockTotal = %d  lastBlockSize = %d\n",
1983                   pDDBMsgMonContext->blockTotal, (DS_U32)pDDBMsgMonContext->lastBlockSize );
1984#endif
1985
1986FailExit:
1987    if ( memId )
1988    {
1989                memChainDestroy( memId );
1990        }
1991
1992        return ( err );
1993
1994}
1995
1996/**************************************************************************
1997* Function Name : FreeDBBMemChain
1998*
1999* Description   : Free all memory allocated for internal usage except
2000*                                 those allocated using memId memory chain
2001* Parameters    :
2002*
2003* Return        : DHL_RESULT
2004*                                 noErrror  -  success
2005 **************************************************************************/
2006static void FreeDBBMemChain( DS_U32 DDBMonContextId )
2007{
2008    DDBMsgMonContextPtr_t pDDBMsgMonContext;
2009
2010    if ( DDBMonContextId < NUM_DDB_MON_CONTEXTS )
2011    {
2012        pDDBMsgMonContext = &pDsmccDB->DDBMonContexts[ DDBMonContextId ];
2013        if ( pDDBMsgMonContext->pDDBModule != NULL )
2014                    memChainDestroy( pDDBMsgMonContext->memId );
2015    }
2016}
2017
2018/**************************************************************************
2019* Function Name : ParseDsmccDDB
2020*
2021* Description   : Parse the entire DSMCC DDB message and return the parsed
2022*                                 data
2023*                 Notice: DDB monitoring should operate in section mode only
2024* Parameters    :
2025*
2026* Return        : DHL_RESULT
2027*                                 noErrror  -  success
2028 **************************************************************************/
2029DHL_RESULT ParseDsmccDDB( PSIDataArray_t *desc, DS_U16 LastBlockNum, DS_U16 BlockSize,  DS_U16 LastBlockSize,
2030                       DsmccDDBMsgPtr_t *ppDsmccDDBMsg )
2031{
2032        DHL_RESULT                                  err = DHL_OK;
2033    DS_U8                                       *section;
2034        memId_t                                 memId       = NULL;
2035    memChainSetup_t                     memSetup    = { DSMCC_DDB_MEM_LIMIT , NULL, NULL };
2036
2037        DS_U8                                       table_id;
2038        DS_U16                                      dsmcc_section_length;
2039        bitBufferPtr_t              bits = NULL;
2040
2041        DDBMsgPtr_t                     pDDBMsgSection;                         // DDB msg section
2042    DsmccDnldDataHdrPtr_t       pDsmccDnldDataHdr;                      // Dsmcc Download Data Header
2043//    DS_U8*                      spBlockDataByte;                        // DDB msg payload
2044
2045    DS_U8                       *dpData;
2046    DS_U16                      BlockDataSize;
2047    DS_U16                      i;
2048    DS_U8                                       numSections;
2049
2050        if ( (desc == NULL) || (ppDsmccDDBMsg == NULL) )
2051        {
2052                return( DHL_FAIL_NULL_POINTER );
2053        }
2054
2055        // section pointer to DSMCC-encapsulated DDB table data sections
2056    //
2057    numSections = desc->numSections;
2058    section     = desc->sectPtr[0] ;
2059
2060    // Do sanity check
2061        if ( (numSections != 1) || (section == NULL) )
2062    {
2063                return ( DHL_FAIL_INVALID_PARAM );
2064        }
2065
2066
2067    // Create memory chain
2068        err = memChainCreate( &memId, &memSetup );
2069    if ( err )
2070    {
2071                err = DHL_FAIL_OUT_OF_RESOURCE;
2072                goto ParseExit;
2073        }
2074
2075    // Allocate memory for DsmccDDB structure for the client
2076        *ppDsmccDDBMsg = (DsmccDDBMsgPtr_t)((memId_t *)(memChainAlloc(memId, sizeof(DsmccDDBMsg_t) + sizeof(memId_t))) + 1);
2077        if (*ppDsmccDDBMsg == NULL)
2078    {
2079                err = DHL_FAIL_OUT_OF_RESOURCE;
2080                goto ParseExit;
2081        }
2082
2083    // Allocate the memory to hold the DDB msg section
2084        (*ppDsmccDDBMsg)->ptrDDBMsgSection = (DDBMsgPtr_t)memChainAlloc(memId, sizeof(DDBMsg_t));
2085
2086        if ( (*ppDsmccDDBMsg)->ptrDDBMsgSection == NULL )
2087    {
2088                err = DHL_FAIL_OUT_OF_RESOURCE;
2089                goto ParseExit;
2090        }
2091
2092#if DSMCC_DEBUG
2093    printf("\n*** ParseDsmccDDBSection: Start parsing (%d) section(s) ***\n", (DS_U32)numSections);
2094#endif
2095
2096    // Perform DSM-CC DDB section data validation
2097    // Get table_id
2098        table_id = get_table_id(section);
2099
2100        if ( table_id != DSMCC_DDB_TABLE_ID )
2101        {
2102                printf("ParseDsmccDDBSection: invalid table_id = %0x\n", (int)table_id);
2103                err = DHL_FAIL_NULL_POINTER;
2104                goto ParseExit;
2105        }
2106        // Get syntax indicator: 1 = valid
2107        if (get_section_syntax_indicator(section) != 1)
2108    {
2109                printf("ParseDsmccDDBSection: section_syntax_indicator not set\n");
2110                err = DHL_FAIL_NULL_POINTER;
2111                goto ParseExit;
2112        }
2113        // Get section length
2114        dsmcc_section_length = get_section_length(section);
2115
2116        if ( dsmcc_section_length > (MAX_DSMCC_SECTION_LENGTH - 3) )
2117    {
2118                printf("ParseDsmccDDBSection: invalid section_length = %0d\n", (int)dsmcc_section_length);
2119                err = DHL_FAIL_NULL_POINTER;
2120                goto ParseExit;
2121        }
2122
2123        // Create the bitBuffer object and initialize it with the current section data
2124        err = bitBufferCreate( &bits, section + 3, dsmcc_section_length );
2125        if ( err != DHL_OK )
2126    {
2127        printf( "ParseDsmccDDBSection::bitBufferCreate failed --> (0x%x)\n", err );
2128                goto ParseExit;
2129        }
2130
2131        // Parse the section and fill the DSM-CC DDB section data structure
2132    //
2133#if DSMCC_DEBUG
2134    printf("ParseDsmccDDBSection: Fill DDB section data structure\n");
2135#endif
2136
2137        (*ppDsmccDDBMsg)->table_id               = table_id;
2138    (*ppDsmccDDBMsg)->dsmcc_section_length   = dsmcc_section_length;
2139    (*ppDsmccDDBMsg)->table_id_extension     = bitBufferGetBits(bits, 16);   // Module ID
2140    bitBufferSkipBits( bits, 2 );                                                // Reserved
2141    (*ppDsmccDDBMsg)->version_number         = bitBufferGetBits(bits, 5);    // version number
2142        (*ppDsmccDDBMsg)->current_next_indicator = bitBufferGetBits(bits, 1);    // current next indicator
2143
2144        if ( (*ppDsmccDDBMsg)->current_next_indicator != 1 )
2145    {
2146                printf("ParseDsmccDDBSection: current_next_indicator not set\n");
2147                err = DHL_FAIL_NULL_POINTER;
2148                goto ParseExit;
2149        }
2150        (*ppDsmccDDBMsg)->section_number         = bitBufferGetBits(bits, 8);    // section_number
2151        (*ppDsmccDDBMsg)->last_section_number    = bitBufferGetBits(bits, 8);    // last_section_number
2152
2153#if DSMCC_DEBUG
2154        printf("ParseDsmccDDBSection:               table_id = 0x%02x\n",(DS_U32)(*ppDsmccDDBMsg)->table_id );
2155        printf("ParseDsmccDDBSection:   dsmcc_section_length = %d\n",  (DS_U32)   (*ppDsmccDDBMsg)->dsmcc_section_length );
2156        printf("ParseDsmccDDBSection:     table_id_extension = 0x%04x\n", (DS_U32)(*ppDsmccDDBMsg)->table_id_extension );
2157        printf("ParseDsmccDDBSection:         version_number = %d\n",    (DS_U32) (*ppDsmccDDBMsg)->version_number );
2158        printf("ParseDsmccDDBSection: current_next_indicator = 0x%02x\n", (DS_U32)(*ppDsmccDDBMsg)->current_next_indicator );
2159        printf("ParseDsmccDDBSection:         section_number = %d\n",     (DS_U32)(*ppDsmccDDBMsg)->section_number );
2160        printf("ParseDsmccDDBSection:    last_section_number = %d\n",    (DS_U32) (*ppDsmccDDBMsg)->last_section_number );
2161#endif
2162
2163        // Parse the DDB section and fill the DDB section data structure
2164    //
2165    // Initialize destination pointer to DDB message section
2166    pDDBMsgSection = (*ppDsmccDDBMsg)->ptrDDBMsgSection;
2167
2168    pDDBMsgSection->ptrDsmccDnldDataHdr =
2169        (DsmccDnldDataHdrPtr_t)memChainAlloc( memId, sizeof(DsmccDnldDataHdr_t) );
2170
2171    if ( pDDBMsgSection->ptrDsmccDnldDataHdr == NULL )
2172    {
2173                err = DHL_FAIL_OUT_OF_RESOURCE;
2174                goto ParseExit;
2175        }
2176
2177    // Parse DDB dsmcc download data header and assign them to the section header data structure
2178        pDsmccDnldDataHdr = pDDBMsgSection->ptrDsmccDnldDataHdr;
2179
2180    pDsmccDnldDataHdr->protocolDiscriminator = bitBufferGetBits(bits, 8);
2181    if ( pDsmccDnldDataHdr->protocolDiscriminator != 0x11 )
2182    {
2183                printf("ParseDsmccDDBSection: Invalid protocolDiscriminator = %0x\n",
2184                     (int) pDsmccDnldDataHdr->protocolDiscriminator);
2185                err = DHL_FAIL_NULL_POINTER;
2186                goto ParseExit;
2187    }
2188
2189    pDsmccDnldDataHdr->dsmccType = bitBufferGetBits(bits, 8);
2190    if ( pDsmccDnldDataHdr->dsmccType != 0x03 )
2191    {
2192                printf("ParseDsmccDDBSection: Invalid dsmccType = %0x\n", (int)pDsmccDnldDataHdr->dsmccType);
2193                err = DHL_FAIL_NULL_POINTER;
2194                goto ParseExit;
2195    }
2196
2197    pDsmccDnldDataHdr->messageId = bitBufferGetBits(bits, 16);
2198    if ( pDsmccDnldDataHdr->messageId != 0x1003 )
2199    {
2200                printf("ParseDsmccDDBSection: Invalid messageId = %0x\n", (int)pDsmccDnldDataHdr->messageId);
2201                err = DHL_FAIL_NULL_POINTER;
2202                goto ParseExit;
2203    }
2204
2205    pDsmccDnldDataHdr->downloadId       = bitBufferGetBits(bits, 32);
2206    bitBufferSkipBits( bits, 8 );         // Reserved
2207    pDsmccDnldDataHdr->adaptationLength = bitBufferGetBits(bits, 8);
2208    pDsmccDnldDataHdr->messageLength    = bitBufferGetBits(bits, 16);
2209
2210    if ( pDsmccDnldDataHdr->adaptationLength > 0 )
2211    {
2212        pDsmccDnldDataHdr->ptrDsmccAdaptationHeader =
2213            (dsmccDDBAdaptHeaderPtr_t)memChainAlloc( memId, pDsmccDnldDataHdr->adaptationLength );
2214        if ( pDsmccDnldDataHdr->ptrDsmccAdaptationHeader == NULL )
2215        {
2216                    err = DHL_FAIL_OUT_OF_RESOURCE;
2217                    goto ParseExit;
2218        }
2219
2220        // Copy the entire adaptation header block
2221        dpData = (DS_U8*)pDsmccDnldDataHdr->ptrDsmccAdaptationHeader;
2222
2223                for ( i = 0; i < pDsmccDnldDataHdr->adaptationLength; i++ )
2224                        dpData[i] = bitBufferGetBits(bits, 8);
2225    }
2226    else
2227    {
2228        pDsmccDnldDataHdr->ptrDsmccAdaptationHeader = NULL;
2229    }
2230
2231    // Parse DDB msg body section and assign them to the proper data structure
2232    pDDBMsgSection->moduleId        = bitBufferGetBits(bits, 16);
2233    pDDBMsgSection->moduleVersion   = bitBufferGetBits(bits, 8);
2234    bitBufferSkipBits( bits, 8 );                                         // Reserved
2235    pDDBMsgSection->blockNumber     = bitBufferGetBits(bits, 16);
2236
2237    if ( pDDBMsgSection->blockNumber == LastBlockNum )
2238        BlockDataSize = LastBlockSize;
2239    else
2240        BlockDataSize = BlockSize;
2241
2242
2243    pDDBMsgSection->pBlockDataByte  = (DS_U8*)memChainAlloc( memId, BlockDataSize );
2244
2245    if ( pDDBMsgSection->pBlockDataByte == NULL )
2246    {
2247                err = DHL_FAIL_OUT_OF_RESOURCE;
2248                goto ParseExit;
2249    }
2250
2251    // Copy the entire DDB payload data block
2252        for ( i = 0; i < BlockDataSize; i++ )
2253    {
2254                pDDBMsgSection->pBlockDataByte[i] = bitBufferGetBits(bits, 8);
2255    }
2256
2257#if DSMCC_DEBUG
2258        printf("ParseDsmccDDBSection:  protocolDiscriminator = 0x%02X\n", (DS_U32)pDsmccDnldDataHdr->protocolDiscriminator );
2259        printf("ParseDsmccDDBSection:              dsmccType = 0x%02X\n", (DS_U32)pDsmccDnldDataHdr->dsmccType );
2260        printf("ParseDsmccDDBSection:              messageId = 0x%04X\n", (DS_U32)pDsmccDnldDataHdr->messageId );
2261        printf("ParseDsmccDDBSection:             downloadId = 0x%08X\n", (DS_U32)pDsmccDnldDataHdr->downloadId );
2262        printf("ParseDsmccDDBSection:       adaptationLength = %d\n",    (DS_U32) pDsmccDnldDataHdr->adaptationLength );
2263        printf("ParseDsmccDDBSection:          messageLength = %d\n",    (DS_U32) pDsmccDnldDataHdr->messageLength );
2264        printf("ParseDsmccDDBSection:               moduleId = %d\n",    (DS_U32) pDDBMsgSection->moduleId );
2265        printf("ParseDsmccDDBSection:          moduleVersion = %d\n",   (DS_U32) pDDBMsgSection->moduleVersion );
2266        printf("ParseDsmccDDBSection:            blockNumber = %d\n",    (DS_U32) pDDBMsgSection->blockNumber );
2267        printf("ParseDsmccDDBSection:          BlockDataSize = %d\n",   (DS_U32)  BlockDataSize );
2268#endif
2269
2270        // Parsing/copying is complete, save memId into the memChain alloc-ed
2271        *(((memId_t *)(*ppDsmccDDBMsg))-1) = memId;
2272
2273        memId = NULL; // Reset memId so its memChain won't get destroyed
2274
2275ParseExit:
2276
2277        if ( bits )
2278    {
2279                // clean up the bitBuffer
2280                bitBufferDestroy( bits );
2281        }
2282
2283    if ( memId )
2284    {
2285                memChainDestroy( memId );
2286        *ppDsmccDDBMsg = NULL;
2287        }
2288
2289        return ( err );
2290
2291}
2292
2293/**************************************************************************
2294* Function Name : DDBSectionRecvd
2295*
2296* Description   : Check for existing block
2297*
2298* Parameters    :
2299*
2300* Return        : DHL_RESULT
2301*                                 noErrror  -  success
2302 **************************************************************************/
2303DS_BOOL DDBSectionRecvd( DDBMsgMonContextPtr_t pDDBMsgMonContext, DS_U16 blockNumber )
2304{
2305    DS_U32  byteOffset  = blockNumber / 8;
2306    DS_U8   bitFlagIdx  = blockNumber % 8;
2307    DS_U8   *pBitFlags;
2308
2309    if ( pDDBMsgMonContext && (pDDBMsgMonContext->pBlockRecvBitFlags) )
2310    {
2311        pBitFlags = (DS_U8*)pDDBMsgMonContext->pBlockRecvBitFlags + byteOffset;
2312
2313        return( ((*pBitFlags) & XltIdx2Bit[ bitFlagIdx ]) ? _TRUE_ : _FALSE_ );
2314    }
2315
2316    return _FALSE_;
2317}
2318
2319/**************************************************************************
2320* Function Name : ProcessDDBSection
2321*
2322* Description   :
2323*
2324* Parameters    :
2325*
2326* Return        : DHL_RESULT
2327*                                 noErrror  -  success
2328 **************************************************************************/
2329eDSMCCRetval_t ProcessDDBSection( DDBMsgMonContextPtr_t pDDBMsgMonContext, DDBMsgPtr_t pDDBMsgSection )
2330{
2331    DS_U32  byteOffset;
2332    DS_U16  blockSize;
2333    DS_U8   bitFlagIdx;
2334    DS_U8   *pBitFlags;
2335    DS_U8   *pModuleBlock;
2336//    DS_U16  rcvBlockIdx;
2337
2338    // Memory buffering mode
2339    if ( pDDBMsgMonContext->pDDBModule->dataType == eDDBMemData )
2340    {
2341#if 1//DSMCC_DEBUG
2342        printf( "ProcessDsmccDDB: DDB Section #%ld Total blocks: %ld\n", (DS_U32)pDDBMsgSection->blockNumber, pDDBMsgMonContext->blockTotal );
2343#endif
2344
2345        byteOffset = pDDBMsgSection->blockNumber * pDDBMsgMonContext->blockSize;
2346
2347        // Check for any bound error
2348        if ( byteOffset < pDDBMsgMonContext->moduleSize )
2349        {
2350            pModuleBlock = (DS_U8*)pDDBMsgMonContext->pDDBModule->pDDBBuffer + byteOffset;
2351
2352            // Check if this is the last block
2353            if ( pDDBMsgSection->blockNumber == (pDDBMsgMonContext->blockTotal-1) )
2354                blockSize = pDDBMsgMonContext->lastBlockSize;
2355            else
2356                blockSize = pDDBMsgMonContext->blockSize;
2357
2358            // Copy the data block into its correct spot
2359            memcpy( pModuleBlock, pDDBMsgSection->pBlockDataByte, blockSize );
2360
2361            // Set the bit flag for this block number
2362            byteOffset  = pDDBMsgSection->blockNumber / 8;
2363            bitFlagIdx  = pDDBMsgSection->blockNumber % 8;
2364            pBitFlags   = (DS_U8*)pDDBMsgMonContext->pBlockRecvBitFlags + byteOffset;
2365            (*pBitFlags) |= XltIdx2Bit[ bitFlagIdx ];
2366        }
2367        else
2368        {
2369            return eDsmccDDBMemOutOfBound;
2370        }
2371    }
2372#if DSMCC_DISKFILE
2373    else // Diskfile buffering mode
2374    {
2375        rcvBlockIdx  = pDDBMsgMonContext->recvdBlockIndex++;
2376        byteOffset   = rcvBlockIdx * pDDBMsgMonContext->blockSize;
2377        pModuleBlock = (DS_U8*)pDDBMsgMonContext->pFileBlockData + byteOffset;
2378
2379        // Check if this is the last block
2380        if ( pDDBMsgSection->blockNumber == (pDDBMsgMonContext->blockTotal-1) )
2381            blockSize = pDDBMsgMonContext->lastBlockSize;
2382        else
2383            blockSize = pDDBMsgMonContext->blockSize;
2384
2385        // Copy the data block into the current buffer empty slot
2386        memcpy( pModuleBlock, pDDBMsgSection->pBlockDataByte, blockSize );
2387
2388        // Set the corresponding block number and index
2389        pDDBMsgMonContext->pFileBlockDir[ rcvBlockIdx ].blockNumber = pDDBMsgSection->blockNumber;
2390        pDDBMsgMonContext->pFileBlockDir[ rcvBlockIdx ].blockIndex  = (DS_U16)pDDBMsgMonContext->blockRecvd;
2391
2392        // Set the bit flag for this block number
2393        byteOffset  = pDDBMsgSection->blockNumber / 8;
2394        bitFlagIdx  = pDDBMsgSection->blockNumber % 8;
2395        pBitFlags   = (DS_U8*)pDDBMsgMonContext->pBlockRecvBitFlags + byteOffset;
2396        (*pBitFlags) |= XltIdx2Bit[ bitFlagIdx ];
2397
2398        // If buffers are filled up, write out the data into diskfiles
2399        if ( pDDBMsgMonContext->recvdBlockIndex >= DSMCC_FILE_BUFSECTIONS )
2400        {
2401            WriteDDBCaptureFiles( pDDBMsgMonContext, pDDBMsgMonContext->recvdBlockIndex );
2402            pDDBMsgMonContext->recvdBlockIndex = 0;     // Reset receive block index
2403        }
2404    }
2405#endif
2406
2407    return eDsmccDDBBlockRecvd;
2408}
2409
2410/**************************************************************************
2411* Function Name : ProcessDsmccDDB
2412*
2413* Description   : Parse and process DSMCC DDB message received
2414*
2415* Parameters    :
2416*
2417* Return        : DHL_RESULT
2418*                                 noErrror  -  success
2419 **************************************************************************/
2420eDSMCCRetval_t ProcessDsmccDDB( PSIDataArray_t            *desc,
2421                                DDBMsgMonContextPtr_t   pDDBMsgMonContext,
2422                                DDBModulePtr_t          *ppDDBModule )
2423{
2424        DHL_RESULT                 err;
2425//    DS_U16                  BlockDataSize;
2426    DsmccDDBMsgPtr_t        pDsmccDDBMsg;
2427    DDBMsgPtr_t             pDDBMsgSection;
2428    DsmccDnldDataHdrPtr_t   pDsmccDnldDataHdr;
2429    eDSMCCRetval_t          retVal;
2430
2431    // Set DDB module return ptr to NULL
2432    (*ppDDBModule) = NULL;
2433
2434    // Check if DDB monitor context has been setup
2435    if ( !pDDBMsgMonContext->isInitialized )
2436    {
2437        err = InitDDBContext( pDDBMsgMonContext );
2438
2439        if ( err != DHL_OK )
2440        {
2441            return ( eDsmccDDBInitContextFail );
2442        }
2443    }
2444
2445    // Parse the DDB message received
2446    err = ParseDsmccDDB( desc, pDDBMsgMonContext->blockTotal-1, pDDBMsgMonContext->blockSize,
2447                         pDDBMsgMonContext->lastBlockSize, &pDsmccDDBMsg );
2448
2449    if ( err != DHL_OK )
2450    {
2451        if ( err == DHL_FAIL_OUT_OF_RESOURCE )
2452        {
2453            return( eDsmccDDBOutOfCPUMemory );
2454        }
2455    }
2456
2457    if ( pDsmccDDBMsg == NULL )
2458    {
2459        printf( "ProcessDsmccDDB::pDsmccDDBMsg == NULL\n" );
2460        return ( eDsmccDDBParseError );
2461    }
2462
2463    // Check and validate module information
2464    pDDBMsgSection = pDsmccDDBMsg->ptrDDBMsgSection;
2465
2466    pDsmccDnldDataHdr = pDDBMsgSection->ptrDsmccDnldDataHdr;
2467
2468    // Check and compare download ID
2469    if ( pDDBMsgMonContext->downloadId != pDsmccDnldDataHdr->downloadId )
2470    {
2471        //printf( "ProcessDsmccDDB: Mismatched downloadId ( cur = %lu   rcv = %lu )\n", pDDBMsgMonContext->downloadId, pDsmccDnldDataHdr->downloadId );
2472
2473        FreeDsmccMemChain( pDsmccDDBMsg );
2474        return ( eDsmccDDBWrongDownloadId );
2475    }
2476
2477    // Check and compare module ID
2478    if ( pDDBMsgMonContext->moduleId != pDDBMsgSection->moduleId )
2479    {
2480        printf( "ProcessDsmccDDB: Mismatched moduleId ( cur = %d   rcv = %d )\n",
2481                      (int) pDDBMsgMonContext->moduleId, (int) pDDBMsgSection->moduleId );
2482
2483        FreeDsmccMemChain( pDsmccDDBMsg );
2484        return ( eDsmccDDBWrongModuleId );
2485    }
2486
2487    // Check and compare module version, if different should we flush the entire section received?
2488    if ( pDDBMsgMonContext->moduleVersion != pDDBMsgSection->moduleVersion )
2489    {
2490        printf( "ProcessDsmccDDB: Mismatched version ( cur = %d  rcv = %d\n",
2491                      (int) pDDBMsgMonContext->moduleVersion, (int) pDDBMsgSection->moduleVersion );
2492
2493        FreeDsmccMemChain( pDsmccDDBMsg );
2494        return ( eDsmccDDBWrongVersion );
2495    }
2496
2497    // Check for valid block number
2498    if ( pDDBMsgSection->blockNumber >= pDDBMsgMonContext->blockTotal )
2499    {
2500        printf( "ProcessDsmccDDB: Invalid block number = %d  block total = %d\n",
2501                      (int) pDDBMsgSection->blockNumber, (int) pDDBMsgMonContext->blockTotal );
2502
2503        FreeDsmccMemChain( pDsmccDDBMsg );
2504        return ( eDsmccDDBInvalidBlockNum );
2505    }
2506
2507    // Check if this block has been received before
2508    if ( DDBSectionRecvd(pDDBMsgMonContext, pDDBMsgSection->blockNumber) )
2509    {
2510        ////printf( "ProcessDsmccDDB: DDB Section #%d has been received\n", pDDBMsgSection->blockNumber );
2511        FreeDsmccMemChain( pDsmccDDBMsg );
2512        return ( eDsmccDDBBlockRecvd );
2513    }
2514
2515    // Process and saved the block received
2516    retVal = ProcessDDBSection( pDDBMsgMonContext, pDsmccDDBMsg->ptrDDBMsgSection );
2517
2518    // Free the parsed DDB msg mem chain
2519    FreeDsmccMemChain( pDsmccDDBMsg );
2520
2521    if ( retVal == eDsmccDDBBlockRecvd )
2522    {
2523        // Update the DDB monitor variables
2524        pDDBMsgMonContext->blockRecvd++;
2525
2526        if ( pDDBMsgMonContext->pfStatusProc != NULL )
2527        {
2528            (*pDDBMsgMonContext->pfStatusProc)( pDDBMsgMonContext->psiCtl, eDsmccDDBBlockRecvd, pDDBMsgMonContext->blockRecvd );
2529        }
2530
2531        // Check if all the DDB message sections have been received and
2532        // return the complete module to the client
2533        if ( pDDBMsgMonContext->blockRecvd >= pDDBMsgMonContext->blockTotal )
2534        {
2535#if DSMCC_DISKFILE
2536            if ( pDDBMsgMonContext->pDDBModule->dataType == eDDBFileData )
2537            {
2538                WriteDDBCaptureFiles( pDDBMsgMonContext, pDDBMsgMonContext->recvdBlockIndex );
2539                CloseDDBCaptureFiles( pDDBMsgMonContext );
2540            }
2541#endif
2542            (*ppDDBModule) = pDDBMsgMonContext->pDDBModule;
2543
2544            return( eDsmccDDBTableIsComplete );
2545        }
2546    }
2547
2548    // DDB message section has been received and saved
2549    return ( retVal );
2550}
2551
2552
2553
2554void DsmccDDBTask( DS_U32 DDBMonContextId )
2555{
2556    DHL_RESULT                      err = DHL_OK;
2557    DsmccMsg_t              dsmccMsg;
2558        PSIDataArray_t          *desc;
2559    DS_U32                          len/*, i*/;
2560    DsmccEventProc_t        dsmccClientProc;
2561    DDBMsgMonContextPtr_t   pDDBMsgMonContext;
2562    DDBModulePtr_t          pDDBModule;
2563    eDSMCCRetval_t          retVal;
2564        int                     processDsmccDDBData = _TRUE_;
2565
2566        if ( DDBMonContextId >= NUM_DDB_MON_CONTEXTS ) {
2567                printf("%s:%d| Invalid DDBMonContextId, terminate DsmccDDBTask.\n", __FUNCTION__, __LINE__);
2568                return;
2569        }
2570
2571    //printf("%s::Is Entering... DDBMonContextId=%ld\n", __FUNCTION__, DDBMonContextId);
2572       
2573    while( _TRUE_ )
2574    {
2575        pDDBMsgMonContext = &pDsmccDB->DDBMonContexts[ DDBMonContextId ];
2576        if ( pDDBMsgMonContext->isUsed != _TRUE_ )
2577                printf("%s:%d| WARNING: MsgMonContext is used with isUsed = 0\n", __FUNCTION__, __LINE__);
2578       
2579        //OS_Delay(100);
2580       
2581        err = (DHL_RESULT)OS_ReceiveMessage(pDDBMsgMonContext->dsmccQ, (DS_U32 *)&dsmccMsg, sizeof(DsmccMsg_t), &len);
2582        if ( err != OS_OK )
2583        {
2584            printf("Receive Message returned %d\n", err);
2585        }
2586        else
2587        {
2588            switch (dsmccMsg.event)
2589            {
2590                                case eDsmccActivate :
2591                                //printf("%s::Is Running... DDBMonContextId=%ld\n", __FUNCTION__, DDBMonContextId);
2592                                        /* Just for sanity check
2593                                         */
2594                                        if ( pDDBMsgMonContext->isUsed != _TRUE_ )
2595                                                printf("%s::ERROR! DDB Context is not initialized, but try to use this!\n", __FUNCTION__);
2596                                               
2597                                        OS_GiveSemaphore( pDsmccDB->DDBMonContexts[ DDBMonContextId ].syncSema4 );  // Signal that we're up and running
2598
2599                                        break;
2600
2601                                case eDsmccDeactivate :
2602#if DSMCC_DEBUG
2603                                printf("%s::Is Shutting down...\n", __FUNCTION__);
2604#endif
2605                    //DHL_PSI_CancelAllDsmccMonitors();                 // Terminate all active monitors
2606
2607#if 0
2608                                        if(     pDDBModule->pDDBBuffer != NULL)
2609                                        {
2610                                                DSMCC_FREE(pDDBModule->pDDBBuffer);
2611                                                //FreeTLPhysMemory(pDDBModule->pDDBBuffer);
2612                                                pDDBModule->pDDBBuffer = NULL;
2613                                        }
2614#endif
2615                                        OS_GiveSemaphore( pDsmccDB->DDBMonContexts[ DDBMonContextId ].syncSema4 );  // Signal that we're shutting down
2616
2617                                        OS_SelfDeleteTask();
2618
2619                                        return;
2620
2621                case eDsmccDDBDataReceived :
2622                                        if (processDsmccDDBData == _FALSE_)
2623                                        {
2624                                                /* spurious response in the queue. ignore */
2625                                                /* There is a memory leak here for PSI data.
2626                                                 */
2627                                                break;
2628                                        }
2629
2630                    // Get the DDB data
2631                    desc = dsmccMsg.desc;
2632
2633                    // Get the DDB Monitor Context
2634                    DDBMonContextId = dsmccMsg.userParam;
2635
2636                    // Verify the monitoring parameter
2637                    if ( DDBMonContextId < NUM_DDB_MON_CONTEXTS )
2638                    {
2639                        pDDBMsgMonContext = &pDsmccDB->DDBMonContexts[ DDBMonContextId ];
2640
2641                        #if DSMCC_DEBUG
2642                                        printf("%s::ProcessDsmccDDB: eDsmccDDBDataReceived\n", __FUNCTION__);
2643                        #endif
2644
2645                        retVal = ProcessDsmccDDB( desc, pDDBMsgMonContext, &pDDBModule );
2646
2647                        // If the DDB module is ready, invoke the client's callback function
2648                        // and pass the complete DDB module image
2649                        if ( retVal == eDsmccDDBTableIsComplete )
2650                        {
2651                            dsmccClientProc = pDDBMsgMonContext->pfCallbackProc;
2652
2653                            if ( dsmccClientProc != NULL )
2654                            {
2655                                // Client must call: FreeDsmccMemChain(pDDBModule)
2656                                (*dsmccClientProc)( pDDBMsgMonContext->psiCtl, (void *)pDDBModule );
2657                            }
2658                            else
2659                            {
2660                                FreeDBBMemChain( DDBMonContextId );
2661                            }
2662
2663                            // Free the parsed DDB module and all internal memory usage when finish
2664                            DHL_PSI_CancelMonitor( dsmccMsg.psiCtl );
2665                            //FreeDDBContext( DDBMonContextId );
2666
2667
2668                                                        /* ignore all further spurious responses in the queue */
2669                                                        processDsmccDDBData = _FALSE_;
2670                        }
2671                        else
2672                        {
2673#if DSMCC_DEBUG
2674                            // Do other processing necessary as the retVal indicates
2675                                        printf("%s::ProcessDsmccDDB: retVal = %d\n", __FUNCTION__, retVal);
2676#endif
2677
2678                                                if ( pDDBMsgMonContext->pfStatusProc != NULL )
2679                                                {
2680                                                    (*pDDBMsgMonContext->pfStatusProc)( pDDBMsgMonContext->psiCtl, retVal, -1 );
2681                                                }
2682
2683                            // If the return value is out of CPU memory maybe we should terminate the
2684                            // DDB monitoring at this point
2685                            if ( retVal == eDsmccDDBOutOfCPUMemory )
2686                            {
2687                                            printf("%s::ProcessDsmccDDB: Out of CPU memory\n", __FUNCTION__);
2688       
2689                                DHL_PSI_CancelMonitor( dsmccMsg.psiCtl );
2690
2691                                // Free the DDB module mem chain and all internal memory usage when finish
2692                                FreeDBBMemChain( DDBMonContextId );
2693                                FreeDDBContext( DDBMonContextId );
2694
2695                                                                /* ignore all further spurious responses in the queue */
2696                                                                processDsmccDDBData = _FALSE_;
2697                            }
2698                        }
2699                    }
2700                    else
2701                    {
2702                        // Invalid DDB monitor parameter block, abort this DDB monitoring
2703                                    printf("%s::Invalid DDBMsgMonContext: abort the DDB monitoring...\n", __FUNCTION__);
2704                        DHL_PSI_CancelMonitor( dsmccMsg.psiCtl );
2705
2706                                                /* ignore all further spurious responses in the queue */
2707                                                processDsmccDDBData = _FALSE_;
2708
2709                        // DDB monitor context is corrupted but we don't know if this is a valid context ptr
2710                        // if ( pDDBMsgMonContext && pDDBMsgMonContext->memId )
2711                        // {
2712                        //     memChainDestroy( pDDBMsgMonContext->memId );
2713                        // }
2714
2715                        // FreeDDBContext( DDBMonContextId );      // Free all internal memory usage when finish
2716                    }
2717
2718                    DD_PSI_FreePSIData( desc );
2719
2720                    break;
2721
2722                default:
2723
2724                    break;
2725            }
2726        }
2727    }
2728}
2729
2730static DHL_RESULT InitDsmccDDBThread(DS_U32 DDBMonContextId)
2731{
2732        DHL_RESULT err = DHL_OK;
2733        OS_MESSAGEQUEUE_ID      dsmccQ                  = (OS_MESSAGEQUEUE_ID)NULL;
2734        DsmccMsg_t                      dsmccMsg;
2735        OS_TASK_ID                      dsmccTaskID             = (OS_TASK_ID)0;
2736        OS_MUTEX_ID                     syncSema4               = (OS_MUTEX_ID)NULL;
2737
2738    if ( !(pDsmccDB->DDBMonContexts[ DDBMonContextId ].dsmccTaskID) )
2739    {
2740        /* Create the DSMCC thread Message Q
2741         */
2742        dsmccQ = OS_CreateMessageQueue("dsmccQ",0,30, sizeof(DsmccMsg_t) );
2743        if ( dsmccQ == (OS_MESSAGEQUEUE_ID)NULL )
2744        {
2745                err = DHL_FAIL_OUT_OF_RESOURCE;
2746                goto doneError;
2747        }
2748   
2749        /* Create Event Sema4
2750         */
2751        syncSema4 = OS_CreateBinarySemaphore("dsmccSyncSema4", 0, _FALSE_);
2752        if ( syncSema4 == (OS_SEMAPHORE_ID)NULL )
2753        {
2754                err = DHL_FAIL_OUT_OF_RESOURCE;
2755                goto doneError;
2756        }
2757   
2758        /* Spawn the DSMCC thread
2759         */
2760        dsmccTaskID = OS_SpawnTask( (OS_TASKFUNCTION)DsmccDDBTask, "tDsmccDDBTask", DSMCCDDB_TASK_PRIO, 16*1024, (DS_S32)DDBMonContextId);
2761        if (dsmccTaskID == (OS_TASK_ID)NULL) {
2762                err = DHL_FAIL_OUT_OF_RESOURCE;
2763                goto doneError;
2764        }
2765       
2766        pDsmccDB->DDBMonContexts[ DDBMonContextId ].dsmccQ = dsmccQ;
2767        pDsmccDB->DDBMonContexts[ DDBMonContextId ].dsmccTaskID = dsmccTaskID;
2768        pDsmccDB->DDBMonContexts[ DDBMonContextId ].syncSema4 = syncSema4;
2769    }
2770       
2771    /* Synchronize with the thread launched
2772     */
2773    dsmccMsg.event          = eDsmccActivate;
2774    dsmccMsg.param          = (void *)pDsmccDB;
2775
2776        OS_SendMessage(pDsmccDB->DDBMonContexts[ DDBMonContextId ].dsmccQ, (DS_U32 *)&dsmccMsg, sizeof(DsmccMsg_t));
2777        OS_TakeSemaphore(pDsmccDB->DDBMonContexts[ DDBMonContextId ].syncSema4);
2778
2779        return err;
2780
2781doneError:
2782        if (err != DHL_OK)
2783                printf("%s| failure. (0x%x)\n", __FUNCTION__, err);
2784       
2785        return err;
2786}
2787
2788#if 0
2789static DHL_RESULT CloseDsmccDDBThread(DS_U32 DDBMonContextId)
2790{
2791        DsmccMsg_t                      dsmccMsg;
2792
2793        if ( pDsmccDB && pDsmccDB->DDBMonContexts[ DDBMonContextId ].isUsed  ) {
2794                dsmccMsg.event = eDsmccDeactivate;
2795                fprintf(stderr, "|%s:%d|\n", __FUNCTION__, __LINE__);
2796                OS_SendMessage(pDsmccDB->DDBMonContexts[ DDBMonContextId ].dsmccQ, (DS_U32 *)&dsmccMsg, sizeof(DsmccMsg_t));
2797                fprintf(stderr, "|%s:%d|\n", __FUNCTION__, __LINE__);
2798                OS_TakeSemaphore(pDsmccDB->DDBMonContexts[ DDBMonContextId ].syncSema4);
2799                fprintf(stderr, "|%s:%d|\n", __FUNCTION__, __LINE__);
2800               
2801                //OS_DeleteSemaphore(pDsmccDB->DDBMonContexts[ DDBMonContextId ].syncSema4);
2802                fprintf(stderr, "|%s:%d|\n", __FUNCTION__, __LINE__);
2803                //OS_DeleteMessageQueue(pDsmccDB->DDBMonContexts[ DDBMonContextId ].dsmccQ);
2804                fprintf(stderr, "|%s:%d|\n", __FUNCTION__, __LINE__);
2805        } else {
2806                printf("%s| WARNING: DDB Thread %ld is already closed.\n", __FUNCTION__, DDBMonContextId);
2807        }
2808       
2809        return DHL_OK;
2810}
2811#endif
2812
2813#if 0
2814___DEBUG_FUNCTION__()
2815#endif
2816
2817
2818void hpsi_test_dii(int pid, int timeOut)
2819{
2820        DHL_RESULT dhlResult = DHL_OK;
2821        DsmccDIIMsgPtr_t DsmccDIIMsg;
2822       
2823        dhlResult = DHL_PSI_GetDsmccDII( gPsiHandle, pid, 0, &DsmccDIIMsg, timeOut ? timeOut : 500 );
2824        if ( dhlResult != DHL_OK ) {
2825                printf("%s| DHL_PSI_GetDsmccDII() returns with 0x%x\n", __FUNCTION__, dhlResult);
2826                return;
2827        }
2828        DHL_PSI_PrintDsmccDII( DsmccDIIMsg );
2829        FreeDsmccMemChain( DsmccDIIMsg);
2830}
2831
2832static DS_U32 startTick=0;
2833void DdbCallback( DHL_PSI_HANDLE *psiCtl, void *pDdbData )
2834{
2835        printf("Elapsed Time = %ld.%ld sec\n", (OS_GetTickCount()-startTick) / 100, (OS_GetTickCount()-startTick) % 100 );
2836}
2837
2838static int dsmccDdbErr = 0;
2839void DdbStatus( DHL_PSI_HANDLE *psiCtl, eDSMCCRetval_t dsmccRetval, DS_U32 blkRcv )
2840{
2841        int curProgress;
2842        static int oldProgress = -1;
2843       
2844        switch(dsmccRetval) {
2845                case eDsmccDDBInitContextFail:
2846                        printf("DDB Status: eDsmccDDBInitContextFail\n");
2847                        break;
2848                       
2849                case eDsmccDDBOutOfCPUMemory:
2850                        printf("DDB Status: eDsmccDDBOutOfCPUMemory\n");
2851                        dsmccDdbErr = 1;
2852                        break;
2853                       
2854                case eDsmccDDBParseError:
2855                        printf("DDB Status: eDsmccDDBParseError\n");
2856                        dsmccDdbErr = 1;
2857                        break;
2858
2859                case eDsmccDDBWrongDownloadId:
2860                        //printf("DDB Status: eDsmccDDBWrongDownloadId\n");
2861                        break;
2862
2863                case eDsmccDDBWrongModuleId:
2864                        printf("DDB Status: eDsmccDDBWrongModuleId\n");
2865                        break;
2866
2867                case eDsmccDDBWrongVersion:
2868                        printf("DDB Status: eDsmccDDBWrongVersion\n");
2869                        break;
2870
2871                case eDsmccDDBInvalidBlockNum:
2872                        printf("DDB Status: eDsmccDDBInvalidBlockNum\n");
2873                        dsmccDdbErr = 1;
2874                        break;
2875
2876                case eDsmccDDBMemOutOfBound:
2877                        printf("DDB Status: eDsmccDDBMemOutOfBound\n");
2878                        dsmccDdbErr = 1;
2879                        break;
2880
2881                case eDsmccDDBTableIsComplete:
2882                case eDsmccDDBBlockRecvd:
2883                        curProgress = DHL_PSI_GetDsmccDDBProgress( psiCtl ); 
2884                        if ( oldProgress != curProgress )
2885                                printf("Progress: %d\n", curProgress);
2886                       
2887                        oldProgress = curProgress;
2888                        break;
2889               
2890                default:
2891                        printf("DDB Status: spurious DSMCC return value %d\n", dsmccRetval);
2892        }
2893}
2894
2895void hpsi_test_ddb(int pid, int dId, int mId, int mVer, int moduleSize, int blockSize, int timeOut)
2896{
2897        DHL_RESULT dhlResult = DHL_OK;
2898        void *returnPSICtl = NULL;
2899
2900        startTick = OS_GetTickCount();
2901        dhlResult = DHL_PSI_MonitorDsmccDDB( gPsiHandle, pid, dId, mId, mVer, moduleSize, blockSize, (DsmccEventProc_t)DdbCallback, (DsmccStatusProc_t)DdbStatus, &returnPSICtl);
2902        if ( dhlResult != DHL_OK ) 
2903                printf("%s:%d| ERROR, return(0x%x)\n", __FUNCTION__, __LINE__, dhlResult);
2904}
2905
2906static int WriteDataOnFile(char *filename, unsigned char *ptr, int len)
2907{
2908        FILE *fp;
2909        int n, total;
2910       
2911        fp = fopen(filename, "w+");
2912        if ( !fp )
2913                return -1;
2914       
2915        total = 0;
2916        do {
2917                n = fwrite( &ptr[total], sizeof(unsigned char), ((total+4096)<=len)?4096:(len-total), fp);
2918                if ( n <0 )
2919                        return -1;
2920                total += n;
2921        } while(total<len);
2922       
2923        fclose(fp);
2924       
2925        return 0;
2926}
2927
2928extern int DD_PSI_CalculateCRC( unsigned char *pTargetData , int iByteCount );
2929extern unsigned long crc32(unsigned long, unsigned char *, unsigned int);
2930   
2931void hpsi_test_dsmcc(int modelId, int timeout)
2932{
2933        DHL_RESULT dhlResult = DHL_OK;
2934        MPEG_PAT *returnPat = NULL;
2935        MPEG_PMT *returnPmt = NULL;
2936        DS_U32 *dsmccPidList;
2937        int timeOut = 10000;
2938        int PidListLen = 0;
2939        int i, j, n=0;
2940        int found = 0;
2941        DsmccDIIMsgPtr_t DsmccDIIMsg;
2942        DS_U32 dsmccPID = 0xFFFF;
2943        DHL_PSI_HANDLE ddbHandle = (DHL_PSI_HANDLE)NULL;
2944        DS_U32 *bufferPtr = (DS_U32 *)0;
2945
2946    DS_U32  crcCalculated;
2947    DS_U16                  moduleId;
2948    DS_U32                  moduleSize;
2949    DS_U8                   moduleVersion;
2950        DS_U32                  downloadId;
2951        DS_U16                                  blockSize;
2952       
2953        startTick = OS_GetTickCount();
2954        dsmccDdbErr = 0;
2955        dsmccPidList = malloc(256*4);
2956        //
2957        // 1. Get PAT
2958        //
2959        dhlResult = DHL_PSI_GetPAT(gPsiHandle , &returnPat, timeOut);
2960        if(DHL_ERROR(dhlResult))
2961                printf("%s |error| 0x%x There is some error!! \n",__FUNCTION__,dhlResult);
2962
2963        //
2964        // 2. Search for any program which contains DSMCC
2965        //
2966        for (i = 0; i < returnPat->numPrograms; ++i) 
2967        {
2968                returnPmt = NULL;
2969               
2970                printf("\r\nGet PMT : program #%d: program_map_PID = %d = 0x%04X\n",
2971                                                        returnPat->programs[i].program_number,
2972                                                        returnPat->programs[i].program_map_PID, returnPat->programs[i].program_map_PID);
2973               
2974                dhlResult = DHL_PSI_GetPMT(gPsiHandle,
2975                        returnPat->programs[i].program_map_PID, 
2976                        returnPat->programs[i].program_number, 
2977                        &returnPmt, 
2978                        timeOut );
2979
2980                if (dhlResult != DHL_OK) {
2981                        printf("%s| Cannot retrieve PMT.\n", __FUNCTION__);
2982                        continue;
2983                }
2984               
2985                dhlResult = DHL_PSI_GetDsmccPIDs( returnPmt, dsmccPidList, &PidListLen );
2986                if (dhlResult != DHL_OK) {
2987                        printf("%s| Cannot find any DSMCC in this PMT-%d.\n", __FUNCTION__, i);
2988                        continue;
2989                }
2990               
2991                //
2992                // 3. Search for any PID which match modelId
2993                //
2994                for(j=0; j<PidListLen; j++) {
2995                        dhlResult = DHL_PSI_GetDsmccDII( gPsiHandle, dsmccPidList[j], 0, &DsmccDIIMsg, timeOut ? timeOut : 500 );
2996                        if ( dhlResult != DHL_OK ) {
2997                                printf("%s| DHL_PSI_GetDsmccDII() returns with 0x%x\n", __FUNCTION__, dhlResult);
2998                                continue;
2999                        }
3000
3001                        for( n=0; n < DsmccDIIMsg->numSections; n++ )
3002                        {
3003                        if ( DsmccDIIMsg->ptrDIIMsgSections[n].compatblDesc.descCount > 0 && 
3004                             DsmccDIIMsg->ptrDIIMsgSections[n].compatblDesc.compatblDescInfo.bValid ) {
3005                            if ( DsmccDIIMsg->ptrDIIMsgSections[n].compatblDesc.compatblDescInfo.specifierType == 1 &&
3006                                 DsmccDIIMsg->ptrDIIMsgSections[n].compatblDesc.compatblDescInfo.specifierData != 0x1E1B )
3007                            {
3008                                 printf("DSMCC message is found, but the IEEE_OUT is not our vendor. (0x%06lX)\n", DsmccDIIMsg->ptrDIIMsgSections[n].compatblDesc.compatblDescInfo.specifierData);
3009                                 continue;
3010                            }
3011                           
3012                                if ( DsmccDIIMsg->ptrDIIMsgSections[n].compatblDesc.compatblDescInfo.model == modelId )
3013                    {
3014                                        found = 1;
3015                                        break;
3016                                } 
3017                                else 
3018                                {
3019                                        printf("PID[0x%04lX] modelId=0x%04X (%d) is different from requested 0x%04X (%d).\n", dsmccPidList[j], 
3020                                                DsmccDIIMsg->ptrDIIMsgSections[n].compatblDesc.compatblDescInfo.model,
3021                                                DsmccDIIMsg->ptrDIIMsgSections[n].compatblDesc.compatblDescInfo.model, 
3022                                                modelId, modelId);
3023                                }
3024                        }
3025                    }
3026                   
3027                    if (found) {
3028                        dsmccPID = dsmccPidList[j];
3029                        break;
3030                    }
3031                }
3032               
3033                if ( j<PidListLen ) /* found */
3034                        break;
3035        }
3036       
3037        //
3038        // 3. If found, then starts downloading...
3039        //
3040        if (found && dsmccPID != 0xFFFF) {
3041                moduleId = DsmccDIIMsg->ptrDIIMsgSections[n].ptrDIIModuleInfo->moduleId;
3042                moduleSize = DsmccDIIMsg->ptrDIIMsgSections[n].ptrDIIModuleInfo->moduleSize;
3043                moduleVersion = DsmccDIIMsg->ptrDIIMsgSections[n].ptrDIIModuleInfo->moduleVersion;
3044                downloadId = DsmccDIIMsg->downloadId;
3045                blockSize = DsmccDIIMsg->blockSize;
3046
3047                printf("::: DII Table::::\n\t[ modelId = 0x%04X ]\n\t[ moduleId = %u ]\n\t[ moduleSize = %ld ]\n\t[ moduleVersion = %d ]\n\t[ downloadId = 0x%08lX ]\n\t[ blockSize = %d ]\n",
3048                        modelId, moduleId, moduleSize, moduleVersion, downloadId, blockSize );
3049
3050                dhlResult = DHL_PSI_MonitorDsmccDDB( gPsiHandle, dsmccPID, downloadId, moduleId, moduleVersion, moduleSize, blockSize, DdbCallback, DdbStatus, &ddbHandle );
3051                if ( dhlResult != DHL_OK ) {
3052                        printf("%s| ERROR, LINE=%d (0x%X)\n", __FUNCTION__, __LINE__, dhlResult);
3053                        goto done;
3054                } 
3055       
3056        /* Wait until all DDB is receiving...
3057         */
3058        do {
3059                if ( DHL_PSI_GetDsmccDDBProgress(ddbHandle) == 100 )
3060                        break;
3061               
3062                if (dsmccDdbErr) {
3063                        printf("%s| error occurred during receiving DDB.\n", __FUNCTION__);
3064                        break;
3065                }
3066               
3067                if ( OS_GetTickCount() > (startTick+timeout) )
3068                {
3069                    printf("Timeout.\n");
3070                    goto done;
3071                }
3072                   
3073                OS_mDelay(100);
3074        } while(1);
3075       
3076        bufferPtr = (DS_U32 *)DHL_PSI_GetDsmccDDBBuffer(ddbHandle);
3077                DHL_PSI_CancelDDB(ddbHandle);
3078                       
3079        /* Burning it!
3080         */
3081        printf("Buffer pointer is 0x%08lX, size=%ld\n", (DS_U32)bufferPtr, moduleSize);
3082       
3083                startTick = OS_GetTickCount();
3084        //DHL_UTIL_FirmwareUpdate( (unsigned char *)bufferPtr, testCBFunc );
3085        printf("Elapsed Time: %ld.%ld sec\n", (OS_GetTickCount()-startTick)/100, (OS_GetTickCount()-startTick)%100);
3086       
3087        if ( DsmccDIIMsg->ptrDIIMsgSections[n].ptrDIIModuleInfo->bCrcFieldValid == DS_FALSE )
3088        {
3089            printf("DII doesn't includes CRC32_descriptor. Ignore CRC.\n");
3090        }
3091        else
3092        {
3093            crcCalculated = (DS_U32)crc32( 0, (unsigned char *)bufferPtr, moduleSize );
3094            //crcCalculated = (DS_U32)DD_PSI_CalculateCRC( (unsigned char *)bufferPtr, moduleSize );
3095            if ( crcCalculated == DsmccDIIMsg->ptrDIIMsgSections[n].ptrDIIModuleInfo->Crc32_descriptor )
3096                printf("CRC32 is exact matched.\n");
3097            else
3098                printf("ERROR: CRC32 is not matched!!! (calculated: 0x%08lX, read: 0x%08lX)\n", 
3099                    crcCalculated, DsmccDIIMsg->ptrDIIMsgSections[n].ptrDIIModuleInfo->Crc32_descriptor );
3100        }
3101        WriteDataOnFile("./rx.dat", (unsigned char *)bufferPtr, moduleSize);
3102       
3103        } else {
3104                printf("%s| ERROR, couldn't find any DSMCC\n", __FUNCTION__);
3105        }
3106
3107done:   
3108        if (dsmccPidList)
3109                free(dsmccPidList);
3110   
3111    if (ddbHandle)
3112        DHL_PSI_CancelDDB(ddbHandle);
3113}
Note: See TracBrowser for help on using the repository browser.