source: svn/newcon3bcm2_21bu/nexus/lib/playback_ip/apps/ip_strm_cablecard.c

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

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

  • Property svn:executable set to *
File size: 115.1 KB
Line 
1/***************************************************************************
2 *     (c)2002-2011 Broadcom Corporation
3 * 
4 *  This program is the proprietary software of Broadcom Corporation and/or its licensors,
5 *  and may only be used, duplicated, modified or distributed pursuant to the terms and
6 *  conditions of a separate, written license agreement executed between you and Broadcom
7 *  (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
8 *  no license (express or implied), right to use, or waiver of any kind with respect to the
9 *  Software, and Broadcom expressly reserves all rights in and to the Software and all
10 *  intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11 *  HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12 *  NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE. 
13 *   
14 *  Except as expressly set forth in the Authorized License,
15 *   
16 *  1.     This program, including its structure, sequence and organization, constitutes the valuable trade
17 *  secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18 *  and to use this information only in connection with your use of Broadcom integrated circuit products.
19 *   
20 *  2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21 *  AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22 *  WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23 *  THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24 *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25 *  LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26 *  OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27 *  USE OR PERFORMANCE OF THE SOFTWARE.
28 * 
29 *  3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30 *  LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31 *  EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32 *  USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33 *  THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34 *  ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35 *  LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36 *  ANY LIMITED REMEDY.
37 *
38 * $brcm_Workfile: ip_strm_cablecard.c $
39 * $brcm_Revision: 5 $
40 * $brcm_Date: 12/8/11 3:13p $
41 *
42 * Module Description:
43 *
44 * Revision History:
45 *
46 * $brcm_Log: /nexus/lib/playback_ip/apps/ip_strm_cablecard.c $
47 *
48 * 5   12/8/11 3:13p mphillip
49 * SW7346-481: 7346/7425 B0 support exposed a lack of
50 *  NEXUS_Security_GetDefaultClearKey calls
51 *
52 * 4   9/14/10 3:55p garetht
53 * SW7420-1046: Minor fixes to support cablecard
54 *
55 * 3   9/2/10 2:53p garetht
56 * SW7420-1046: Add support for sending 6xQAM256 streams to the cablecard
57 *
58 * 2   8/6/10 11:30a garetht
59 * SW7420-919: Add support for DSG CableCARD
60 *
61 * 1   7/30/10 2:42p garetht
62 * SW7420-919: Add CableCARD support to Ip_streamer
63 *
64 *
65 *
66 ****************************************************************************/
67
68
69#include <stdio.h>
70#include <string.h>
71#include <unistd.h>
72#include <stdlib.h>
73#include <fcntl.h>
74#include <pthread.h>
75#include <time.h>
76#include <errno.h>
77#include <sys/types.h>
78#include <sys/socket.h>
79#include <sys/ioctl.h>
80#include <netinet/in.h>
81#include <net/if.h>
82#include <termios.h>
83
84#include "bstd.h"
85#include "bkni.h"
86
87#include "mpod.h"
88#include "mpod_util.h"
89#include "mpod_apinfo.h"
90#include "mpod_diag.h"
91#include "mpod_feature.h"
92#include "mpod_dsg.h"
93#include "mpod_ext_chan.h"
94#include "mpod_mmi.h"
95#include "mpod_link.h"
96#include "mpod_download.h"
97#include "mpod_feature.h"
98#include "mpod_homing.h"
99#include "mpod_hc.h"
100#include "mpod_sas.h"
101#include "mpod_diag.h"
102#include "mpod_mmi.h"
103#include "mpod_systime.h"
104#include "mpod_ca.h"
105#include "mpod_cp.h"
106#include "mpod_res.h"
107#include "mpod_snmp.h"
108#include "test_cp.h"
109#include "mpod_resrc_mgr.h"
110#include "mpod_headend_comm.h"
111#include "mpod_host_property.h"
112
113#if NEXUS_HAS_SECURITY
114#include "nexus_security.h"
115#endif
116
117#ifdef CDL_SUPPORT
118#include "b_cdl_lib.h"
119#include "cdl_adpu.h"
120#include "cdl_dsg.h"
121#endif
122
123#ifdef ESTB_CFG_SUPPORT
124#include "b_estb_cfg_lib.h"
125#endif
126
127#include "ip_strm_cablecard.h"
128#include "nexus_platform.h"
129#include "nexus_core_utils.h"
130#include "nexus_frontend.h"
131#include "nexus_recpump.h"
132#include "nexus_playpump.h"
133#include "ts_psi.h"
134#include "ts_pmt.h"
135
136#include <signal.h>
137#include <termios.h>
138struct termios OriginalTerminalIO;
139
140#define MAX_TUNER           (NEXUS_MAX_FRONTENDS-1)
141#define CABLECARD_DEVICE        "/dev/pod"
142#define MAX_MPEG_SECTION_LEN    4096
143
144#ifdef LINUX
145static pthread_mutex_t g_cablecard_mutex = PTHREAD_MUTEX_INITIALIZER;
146#define cablecard_lock() pthread_mutex_lock(&g_cablecard_mutex)
147#define cablecard_unlock() pthread_mutex_unlock(&g_cablecard_mutex)
148#else
149error "Not Supported"
150#endif
151
152static Cablecard g_cablecard;
153static B_MPOD_SAS_HANDLE SasConnections[32]; /* max 32 connections allowed by the Host 2.0 spec */
154static uint8_t SasData[8] = {0xde,0xad, 0xbe, 0xef, 0x01, 0x23, 0x45, 0x67};
155static cablecard_program_info pg_info[MAX_CABLECARD_ROUTE];
156#if NEXUS_HAS_SECURITY
157static NEXUS_KeySlotHandle keyslot[MAX_CABLECARD_ROUTE];
158#endif
159
160/* generic CabelCARD information */
161static CableCARDInfo info;
162extern int gExitThread;
163#if 0
164static pthread_t gCablecardMenuThreadId;
165#endif
166static NEXUS_PlaypumpHandle switchPlaypump[2];
167static NEXUS_RecpumpHandle switchRecpump[2];
168static uint32_t switchMap[2] = {NEXUS_ParserBand_eMax,NEXUS_ParserBand_eMax};
169static NEXUS_PidChannelHandle videoPidChannels[2];
170static NEXUS_PidChannelHandle audioPidChannels[2];
171static NEXUS_PidChannelHandle pcrPidChannels[2];
172static NEXUS_PidChannelHandle patPidChannels[2];
173static NEXUS_PidChannelHandle pmtPidChannels[2]; 
174static NEXUS_PidChannelHandle caPidChannels[2];
175static NEXUS_MpodInputHandle mpodPlaypumpInput[2];
176
177BDBG_MODULE(ip_strm_cablecard);
178
179// external call to DSGCC lib
180int InitializeDsgCcApplication(void);
181 void CableCardCallbackSetDSGMode( unsigned char * data, unsigned short len );
182 void CableCardCallbackDSG_Directory( unsigned char *data, unsigned short len );
183 void CableCardCallbackDSGPacketError( unsigned char err_status );
184 void CableCardCallbackConfig_Advanced_DSG( unsigned char *pkt_obj_ptr, unsigned short len );
185 void CableCardCallbackDSGFlowID( unsigned long flow_id );
186 unsigned long CableCardCallbackIPUDhcp( unsigned long flowid, unsigned char *mac,
187        unsigned char opt_len, unsigned char *opt_data, unsigned char *ret_option, int *ropt_len );
188 unsigned char CableCardCallbackSocketFlowConfig(unsigned long id, unsigned char *opt_data,
189                                                        unsigned long opt_len);
190 unsigned char CableCardCallbackDeleteFlowReq(unsigned long flowid);
191 void CableCardCallbackSendIPUData( unsigned char *pdata, unsigned long len );
192 void CableCardCallbackSendSocketFlowUsData( unsigned long id, unsigned char *opt_data, unsigned long opt_len );
193 void CableCardRemovedCallbackCleanUp( void );
194
195static void cablecard_in(void);
196static void cablecard_out(void);
197static void cablecard_error(void);
198static void cablecard_reset(void);
199static void OOB_Tx_Docsis(void);
200static void page_cleanup(void);
201static int bcm_3255_tristate_oob_pins(void);
202static int bcm_3255_enable_oob_pins(void);
203
204
205void removeKeyCb(
206    uint16_t programNumber,
207    uint8_t ltsid
208    );
209
210static void default_lock_callback(
211    void *context,
212    int param
213    )
214{
215    BSTD_UNUSED(context);
216    BSTD_UNUSED(param);
217}
218
219static void b_reset_mpod_route(
220    NEXUS_MpodHandle mpod
221    )
222{
223    NEXUS_MpodInputSettings settings;
224    unsigned pr_band;
225    NEXUS_MpodInputHandle mpod_input;
226
227    NEXUS_MpodInput_GetDefaultSettings(&settings);
228    settings.bandType = NEXUS_MpodBandType_eParserBand;
229    settings.allPass = false;
230    settings.mpodPreFilter = false;
231
232    for ( pr_band = 0; pr_band < MAX_CABLECARD_ROUTE; pr_band++)
233    {
234        settings.band.parserBand = (NEXUS_ParserBand)pr_band;
235        mpod_input = NEXUS_MpodInput_Open(mpod, &settings);
236        NEXUS_MpodInput_Close(mpod_input);
237    }
238}
239
240static uint32_t dialogs[8];
241#define MARK_AS_VALID(number)   (dialogs[(number) >> 5] |=  (1 << ((number) & 0x1f)))
242#define MARK_AS_INVALID(number) (dialogs[(number) >> 5] &= ~(1 << ((number) & 0x1f)))
243#define CHECK_IF_VALID(number)  (dialogs[(number) >> 5] &   (1 << ((number) & 0x1f)))
244
245#if 0
246int GetInputChar(
247    void
248    )
249{
250    struct termios oldattr, tattr;
251    int in;
252
253    tcgetattr(0, &tattr);
254    oldattr = tattr;
255    tattr.c_lflag &= ~(ICANON);
256    /* tattr.c_lflag &= ~(ECHO); */
257    tattr.c_cc[VTIME] = 0;
258    tattr.c_cc[VMIN] = 1;
259    tcsetattr(0, TCSANOW, &tattr);
260
261    in = fgetc(stdin);
262
263    tcsetattr(0, TCSANOW, &oldattr);
264
265    return in;
266}
267
268#define MAX_CABLECARD_APP 10
269void *cablecardMenuThread(
270    void *data
271    )
272{
273    char *appUrl, *appName, cachedUrl[MAX_CABLECARD_APP][256];
274    uint8_t type, numApps, i, appLen, urlLen, cachedUrlLen[MAX_CABLECARD_APP], dialogNb, selection;
275    uint16_t version, manuId;
276    MPOD_RET_CODE err;
277    char cmd[256];
278
279    BSTD_UNUSED(data);
280    BKNI_Sleep(15000);
281   
282    while (!gExitThread) {
283
284        err  = B_Mpod_AppInfoGetManuID(&manuId);
285        err |= B_Mpod_AppInfoGetVersionNum(&version);
286        err |= B_Mpod_AppInfoGetNumApps(&numApps);
287
288        if(err)
289        {
290            printf("\n!!!!ERROR retrieving application dialogs\n\n");
291        }
292        else
293        {
294            for(i = 0; i < numApps; i++)
295            {
296                err = B_Mpod_AppInfoGetType(i, &type);
297                if(err) printf("ERROR B_Mpod_AppInfoGetType\n");
298                err |= B_Mpod_AppInfoGetName(i, &appName, &appLen);
299                if(err) printf("ERROR B_Mpod_AppInfoGetName\n");
300                err |= B_Mpod_AppInfoGetURL(i, &appUrl, &urlLen);
301                if(err) printf("ERROR B_Mpod_AppInfoGetURL\n");
302
303                /* cache the URL's */
304                if (i < MAX_CABLECARD_APP)
305                {
306                    BKNI_Memcpy(&cachedUrl[i][0], appUrl, 256);
307                    cachedUrlLen[i] = urlLen;
308                }
309                printf("%d: %s\n", i, appName);
310            }
311        }   
312
313        printf("\nEnter Option:");
314        cmd[0] = GetInputChar();
315        printf("\n");
316       
317        if((cmd[0] < '0') || (cmd[0] > '9')) continue;
318        selection = cmd[0] - '0';
319        if(selection >= numApps) continue;
320       
321        err = B_Mpod_MMIHostOpenDialog(cachedUrl[selection], cachedUrlLen[selection], &dialogNb);
322        if(err)
323        {
324            printf("ERROR Opening Menu Page\n");
325        }
326        else
327        {
328            MARK_AS_VALID(dialogNb);
329        }
330        BKNI_Sleep(5000);
331    }
332
333    pthread_exit(NULL);
334}
335#endif
336
337#ifdef MPODXSIX
338static pthread_t dataCbThread;
339
340void *dataready_thread(
341    void *data
342    )
343{
344    BSTD_UNUSED(data);
345
346    const void *data_buffer;
347    size_t data_buffer_size, desc_size;
348    int i;
349    void *desc;
350
351    while(1)
352    {
353        BKNI_Sleep(15);
354
355        for(i=0; i<2; i++)
356        {
357            if(switchRecpump[i])
358            {
359                if (NEXUS_Recpump_GetDataBuffer(switchRecpump[i], &data_buffer, &data_buffer_size))
360                    continue;
361                NEXUS_Playpump_GetBuffer(switchPlaypump[i], &desc, &desc_size);
362                if(desc_size)
363                {
364                    ((NEXUS_PlaypumpDesc *)desc)->addr = (void *)data_buffer;
365                    ((NEXUS_PlaypumpDesc *)desc)->length = data_buffer_size;
366                    NEXUS_Playpump_ReadComplete(switchPlaypump[i], 0, sizeof(NEXUS_PlaypumpDesc));
367                }
368                else
369                {
370                    data_buffer_size = 0;
371                    printf("Failed to get playpump descriptor\n");
372                }
373                   
374                NEXUS_Recpump_DataWriteComplete(switchRecpump[i], data_buffer_size);
375            }
376        }
377    }
378}
379#endif
380
381static void dataready_callback(
382    void *context,
383    int param
384    )
385{
386    BSTD_UNUSED(param);
387    BSTD_UNUSED(context);
388}
389
390static void overflow_callback(
391    void *context,
392    int param
393    )
394{
395    BSTD_UNUSED(param);
396    BDBG_ERR(("overflow %s", (const char *)context));
397}
398
399cablecard_t cablecard_open(
400    cablecard_setting_t setting
401    )
402{
403    int pod, i;
404    cablecard_t cablecard = &g_cablecard;
405    B_MPOD_IF_SETTINGS IfSettings;
406    NEXUS_MpodOpenSettings Mpodsetting;
407    pthread_t dsgccThread;
408   
409    SetSignalMask();
410    tcgetattr(STDIN_FILENO, &OriginalTerminalIO);
411    signal(SIGCHLD, SIG_IGN);
412    pthread_create(&dsgccThread, NULL, (void *(*)(void *))(InitializeDsgCcApplication), NULL);
413
414    memset(cablecard, 0, sizeof(struct Cablecard));
415    memset(keyslot, 0, sizeof(keyslot));
416   
417    cablecard->oob_mode = setting->oob_mode;
418    cablecard->us_mode = setting->us_mode;
419
420#ifdef ESTB_CFG_SUPPORT
421    /*
422    *  load the estb_cfg
423    */
424    B_Estb_cfg_Init("/perm");
425    B_Estb_cfg_Init("/dyn");
426    B_Estb_cfg_Init("/sys");
427    B_Estb_cfg_Open("/perm", "./perm.bin");
428    B_Estb_cfg_Open("/dyn", "./dyn.bin");
429    B_Estb_cfg_Open("/sys", "./sys.bin");
430#endif
431
432
433    /* open POD driver device*/
434    pod = open(CABLECARD_DEVICE, O_RDWR);
435    if (pod < 0) {
436        BDBG_ERR(("Unable to open cablecard device: %s\n", CABLECARD_DEVICE));
437        return NULL;
438    }
439    cablecard->pod = pod;
440
441    /* open MPOD XPT module*/
442    NEXUS_Mpod_GetDefaultOpenSettings(&Mpodsetting);
443    Mpodsetting.mpodMode = NEXUS_MpodMode_eMpod;
444    Mpodsetting.bandType = NEXUS_MpodBandType_eParserBand;
445
446    Mpodsetting.byteSync = 1;
447    Mpodsetting.clockDelay = 1;
448    Mpodsetting.invertClock = 0;
449
450    cablecard->mpod = NEXUS_Mpod_Open(0, &Mpodsetting);
451    if ( cablecard->mpod == NULL)
452    {
453        BDBG_ERR(("Unable to open NEXUS mpod "));
454        return NULL;
455    }
456
457    b_reset_mpod_route(cablecard->mpod );
458
459    BKNI_Memset(pg_info, 0, sizeof(pg_info));
460
461    IfSettings.cardInsertedCb = cablecard_in;
462    IfSettings.cardRemovedCb = cablecard_out;
463    IfSettings.cardErrorCb = cablecard_error;
464    IfSettings.cardResetCb = cablecard_reset;
465    B_Mpod_Init(&IfSettings);
466
467    /* Initializing MPOD stack */
468    cablecard_init();
469    B_Mpod_TestCpInit();
470
471    /* clear all Card related Info*/
472    memset(&info, 0, sizeof(info));
473
474    CableCardRemovedCallbackCleanUp();
475    bcm_3255_tristate_oob_pins();
476
477#ifdef MPODXSIX
478    /* configure record and playback channels */
479    for (i=0;i<2;i++)
480    {
481        NEXUS_PlaypumpOpenSettings playpumpOpenSettings;
482        NEXUS_PlaypumpSettings playpumpSettings;
483        NEXUS_RecpumpOpenSettings recpumpOpenSettings;
484        NEXUS_RecpumpSettings recpumpSettings;
485        NEXUS_MpodInputSettings settings;
486
487        switchMap[i] = NEXUS_ParserBand_eMax;
488
489        NEXUS_Playpump_GetDefaultOpenSettings(&playpumpOpenSettings);
490        playpumpOpenSettings.numDescriptors = 2000;
491
492        switchPlaypump[i] = NEXUS_Playpump_Open((NEXUS_NUM_PLAYPUMPS-1)-i, &playpumpOpenSettings);
493       
494        if (!switchPlaypump[i])
495        {
496            BDBG_ERR(("NEXUS Error at %d, Exiting...\n", __LINE__));
497        }
498
499        BDBG_ERR(("Open playpump %p", switchPlaypump[i]));
500       
501        NEXUS_Playpump_GetSettings(switchPlaypump[i], &playpumpSettings);
502        playpumpSettings.mode = NEXUS_PlaypumpMode_eScatterGather;
503        playpumpSettings.allPass = false;
504
505        NEXUS_Playpump_SetSettings(switchPlaypump[i], &playpumpSettings);
506        NEXUS_MpodInput_GetDefaultSettings(&settings);
507        settings.bandType = NEXUS_MpodBandType_ePlaypump;
508        settings.allPass = false;
509        settings.mpodPreFilter = true;
510        settings.band.playpump = switchPlaypump[i];
511
512        mpodPlaypumpInput[i] = NEXUS_MpodInput_Open(cablecard->mpod, &settings);
513
514        NEXUS_Recpump_GetDefaultOpenSettings(&recpumpOpenSettings);
515        recpumpOpenSettings.data.bufferSize = (188*4096) + 68;
516        /* threshold is the least common mulitple of a 188 byte transport packet and 4096 atomSize */
517        recpumpOpenSettings.data.dataReadyThreshold = (188*2048);
518       
519        switchRecpump[i] = NEXUS_Recpump_Open((NEXUS_NUM_RECPUMPS-1)-i, &recpumpOpenSettings);
520        if (!switchRecpump[i])
521        {
522            BDBG_ERR(("NEXUS Error at %d, Exiting...\n", __LINE__));
523        }
524       
525        BDBG_ERR(("Open recpump %p", switchRecpump[i]));
526
527        NEXUS_Recpump_GetSettings(switchRecpump[i], &recpumpSettings);
528        recpumpSettings.data.dataReady.callback = dataready_callback;
529        recpumpSettings.data.dataReady.context = (void *) i;
530        recpumpSettings.index.dataReady.callback = dataready_callback;
531        recpumpSettings.index.dataReady.context = (void *) i; 
532        recpumpSettings.data.overflow.callback = overflow_callback;
533        recpumpSettings.data.overflow.context = (void *)"data";
534        recpumpSettings.index.overflow.callback = overflow_callback;
535        recpumpSettings.index.overflow.context = (void *)"index";
536        NEXUS_Recpump_SetSettings(switchRecpump[i], &recpumpSettings);
537    }
538
539    if (pthread_create(&dataCbThread, NULL, dataready_thread, (void *)NULL))
540    {
541        BDBG_ERR(("Failed to create CableCARD pthread, errno %d", errno));
542        BDBG_ASSERT(0);
543    }
544#endif
545
546#if 0
547    if (pthread_create(&gCablecardMenuThreadId, NULL, cablecardMenuThread, (void *)NULL))
548    {
549        BDBG_ERR(("Failed to create CableCARD pthread, errno %d", errno));
550        BDBG_ASSERT(0);
551    }
552#endif
553
554    return cablecard;
555}
556
557void cablecard_close(
558    void
559    )
560{
561    int i;
562
563    cablecard_t cablecard = cablecard_get_instance();
564
565#ifdef MPODXSIX
566    for (i=0;i<2;i++)
567    {
568        if(mpodPlaypumpInput[i])
569            NEXUS_MpodInput_Close(mpodPlaypumpInput[i]);
570        if(switchPlaypump[i])
571            NEXUS_Playpump_Close(switchPlaypump[i]);
572        if(switchRecpump[i])
573            NEXUS_Recpump_Close(switchRecpump[i]);
574    }
575   
576    pthread_join(dataCbThread, NULL);
577#endif
578#if 0
579    pthread_join(gCablecardMenuThreadId, NULL);*/
580#endif
581
582    if (cablecard->mpod)
583    {
584        for (i=0; i<MAX_CABLECARD_ROUTE; i++)
585        {
586            if ( NULL != cablecard->mpod_input[i])
587                NEXUS_MpodInput_Close(cablecard->mpod_input[i]);
588
589            if(pg_info[i].valid) removeKeyCb(pg_info[i].program_number, pg_info[i].ltsid);
590        }
591        NEXUS_Mpod_Close(cablecard->mpod);
592    }
593
594    if (cablecard->pod) {
595        B_Mpod_Done(cablecard->pod);
596        B_Mpod_TestCpDone();
597        B_Mpod_AppInfoShutdown();
598        B_Mpod_MmiShutdown();
599        B_Mpod_SasShutdown();
600        B_Mpod_DownloadShutdown();
601        B_Mpod_FeatureShutdown();
602        B_Mpod_DsgShutdown();
603        B_Mpod_HostControlShutdown();
604        B_Mpod_DiagsShutdown();
605        B_Mpod_CaShutdown();
606        B_Mpod_CpShutdown();
607        B_Mpod_HeadendCommShutdown();
608        B_Mpod_SnmpShutdown();
609        B_Mpod_HostPropertiesShutdown();
610        B_Mpod_SystimeShutdown();
611        B_Mpod_HomingShutdown();
612        B_Mpod_ExtendedChShutdown();
613
614        close(cablecard->pod);
615    }
616
617    if (cablecard->mpeg_section)
618        BKNI_Free(cablecard->mpeg_section);
619
620    cablecard->mpeg_section = NULL;
621    cablecard->cablecard_in = false;
622
623    CableCardRemovedCallbackCleanUp();
624    bcm_3255_tristate_oob_pins();
625
626    /* set terminal back to main app*/
627    tcsetattr(STDIN_FILENO, TCSANOW, &OriginalTerminalIO);
628    signal(SIGINT, SIG_IGN);
629   
630#ifdef ESTB_CFG_SUPPORT
631    /*
632    *  load the estb_cfg
633    */
634    B_Estb_cfg_Close("/perm");
635    B_Estb_cfg_Close("/dyn");
636    B_Estb_cfg_Uninit("/perm");
637    B_Estb_cfg_Uninit("/dyn");
638#endif
639
640}
641
642
643#ifdef MPODXSIX
644void cablecard_unswitch_parser_band(
645    NEXUS_ParserBand parserBand,
646    NEXUS_PidChannelHandle *videoPidChannel,
647    NEXUS_PidChannelHandle *audioPidChannel,
648    NEXUS_PidChannelHandle *pcrPidChannel,
649    NEXUS_PidChannelHandle *patPidChannel,
650    NEXUS_PidChannelHandle *pmtPidChannel, 
651    NEXUS_PidChannelHandle *caPidChannel
652    )
653{
654    cablecard_t cablecard = cablecard_get_instance();
655    NEXUS_RecpumpHandle recpump;
656    NEXUS_PlaypumpHandle playpump;
657    NEXUS_MpodInputSettings settings;
658   
659    if((switchMap[0] == parserBand) || (switchMap[1] == parserBand))
660    {
661        uint32_t index = (parserBand == switchMap[0]) ? 0 : 1;
662       
663        switchMap[index] = NEXUS_ParserBand_eMax;
664        recpump = switchRecpump[index];
665        playpump = switchPlaypump[index];
666
667        BDBG_MSG(("Unswitch parser band %d playpump %p recpump %p", parserBand, playpump, recpump));
668       
669        NEXUS_Playpump_Stop(playpump);
670        NEXUS_Recpump_Stop(recpump); 
671        NEXUS_Recpump_RemoveAllPidChannels(recpump);
672        NEXUS_Playpump_CloseAllPidChannels(playpump);
673
674
675        *videoPidChannel = videoPidChannels[index];
676        *audioPidChannel = audioPidChannels[index];
677        *pcrPidChannel = pcrPidChannels[index];
678        *patPidChannel = patPidChannels[index];
679        *pmtPidChannel = pmtPidChannels[index];
680        *caPidChannel = caPidChannels[index];
681
682        if (NULL == cablecard->mpod_input[parserBand])
683        {
684            NEXUS_MpodInput_GetDefaultSettings(&settings);
685           
686            settings.bandType = NEXUS_MpodBandType_eParserBand;
687            settings.allPass = false;
688#ifdef MPODXSIX
689            settings.mpodPreFilter = true;
690#else
691            settings.mpodPreFilter = false;
692#endif
693            settings.band.parserBand = parserBand;
694            cablecard->mpod_input[parserBand] = NEXUS_MpodInput_Open(cablecard->mpod, &settings);
695        }
696    }
697}
698
699NEXUS_PlaypumpHandle cablecard_switch_parser_band(
700    NEXUS_ParserBand parserBand
701    )
702{
703
704    cablecard_t cablecard = cablecard_get_instance();
705    NEXUS_PlaypumpHandle playpump;
706
707    if(switchMap[0] != NEXUS_ParserBand_eMax)
708    {
709        if(switchMap[1] != NEXUS_ParserBand_eMax)
710        {
711            BDBG_MSG(("Do not switch parser band %d", parserBand));
712            return NULL;
713        }
714        else
715        {
716            switchMap[1] = parserBand;
717            playpump = switchPlaypump[1];
718        }
719    }
720    else
721    {
722        switchMap[0] = parserBand;
723        playpump = switchPlaypump[0];
724    }
725
726    BDBG_ERR(("Switch parser band %d for playpump %p", parserBand, playpump));
727   
728    if (NULL != cablecard->mpod_input[parserBand])
729    {
730        NEXUS_MpodInput_Close(cablecard->mpod_input[parserBand]);
731        cablecard->mpod_input[parserBand] = NULL;
732    }
733   
734    return playpump;
735}
736
737void cablecard_add_pid_channels(
738    NEXUS_PlaypumpHandle playpumpHandle,
739    NEXUS_PidChannelHandle videoPidChannel,
740    NEXUS_PidChannelHandle audioPidChannel,
741    NEXUS_PidChannelHandle pcrPidChannel,
742    NEXUS_PidChannelHandle patPidChannel,
743    NEXUS_PidChannelHandle pmtPidChannel, 
744    NEXUS_PidChannelHandle caPidChannel
745    )
746{
747    uint32_t index = (playpumpHandle == switchPlaypump[0]) ? 0 : 1;
748    NEXUS_RecpumpHandle recpump = switchRecpump[index];
749
750    if(videoPidChannel) NEXUS_Recpump_AddPidChannel(recpump, videoPidChannel, NULL);
751    if(audioPidChannel) NEXUS_Recpump_AddPidChannel(recpump, audioPidChannel, NULL);
752    if(pcrPidChannel)   NEXUS_Recpump_AddPidChannel(recpump, pcrPidChannel, NULL);
753    if(patPidChannel)   NEXUS_Recpump_AddPidChannel(recpump, patPidChannel, NULL);
754    if(pmtPidChannel)   NEXUS_Recpump_AddPidChannel(recpump, pmtPidChannel, NULL);
755    if(caPidChannel)    NEXUS_Recpump_AddPidChannel(recpump, caPidChannel, NULL);
756   
757    videoPidChannels[index] = videoPidChannel;
758    audioPidChannels[index] = audioPidChannel;
759    pcrPidChannels[index] = pcrPidChannel;
760    patPidChannels[index] = patPidChannel;
761    pmtPidChannels[index] = pmtPidChannel;
762    caPidChannels[index] = caPidChannel;
763
764    NEXUS_Playpump_Start(playpumpHandle);
765    NEXUS_Recpump_Start(recpump); 
766    BDBG_MSG(("Starting playpump %p recpump %p", playpumpHandle, recpump));
767}
768
769#endif
770
771/*
772Summary:
773   Enable routing tuner's transport output to CableCARD.
774Description:
775*/
776int cablecard_route_add_tuner(
777   cablecard_t cablecard,
778   NEXUS_FrontendHandle frontend
779   )
780{
781    NEXUS_ParserBand pr_band;
782    NEXUS_MpodInputSettings settings;
783    NEXUS_FrontendUserParameters userParams;
784
785    if (cablecard == NULL || frontend == NULL) return -1;
786
787    BDBG_MSG(("Routing Tuners to MPOD"));
788
789    NEXUS_MpodInput_GetDefaultSettings(&settings);
790    settings.bandType = NEXUS_MpodBandType_eParserBand;
791    settings.allPass = false;
792#ifdef MPODXSIX
793    settings.mpodPreFilter = true;
794#else
795    settings.mpodPreFilter = false;
796#endif
797    NEXUS_Frontend_GetUserParameters(frontend, &userParams);
798    pr_band = userParams.param1&0x7;
799    settings.band.parserBand = pr_band;
800
801    if (NULL == cablecard->mpod_input[pr_band])
802    {
803        cablecard->mpod_input[pr_band] = NEXUS_MpodInput_Open(cablecard->mpod, &settings);
804        if (cablecard->mpod_input[pr_band] == NULL) return -1;
805    }
806    else
807    {
808        BDBG_WRN((" tuner has already been routed to MPOD"));
809    }
810
811    return 0;
812}
813
814/*
815Summary:
816   Disable routing tuner's transport output to CableCARD.
817Description:
818*/
819int cablecard_route_remove_tuner(
820   cablecard_t cablecard,
821   NEXUS_FrontendHandle frontend
822   )
823{
824    NEXUS_ParserBand pr_band;
825    NEXUS_FrontendUserParameters userParams;
826
827    if (cablecard == NULL || frontend == NULL) return -1;
828
829    BDBG_MSG(("Routing Tuners away from MPOD"));
830
831    NEXUS_Frontend_GetUserParameters(frontend, &userParams);
832    pr_band = userParams.param1&0x7;
833
834    if (NULL != cablecard->mpod_input[pr_band])
835    {
836        NEXUS_MpodInput_Close(cablecard->mpod_input[pr_band]);
837        cablecard->mpod_input[pr_band] = NULL;
838    }
839    else
840    {
841        BDBG_MSG((" tuner has already been disconnected from MPOD"));
842    }
843    return 0;
844}
845
846int cablecard_go(
847    void
848    )
849{
850    cablecard_t cablecard = cablecard_get_instance();
851   
852    B_Mpod_Go(cablecard->pod);
853    return 0;
854}
855
856cablecard_t cablecard_get_instance(
857    void
858    )
859{
860    return (&g_cablecard);
861}
862
863int cablecard_get(
864    cablecard_t cablecard,
865    cablecard_setting_t setting
866    )
867{
868    if (cablecard == NULL || setting == NULL) return -1;
869    setting->oob_mode = cablecard->oob_mode;
870    setting->us_mode = cablecard->us_mode;
871    return 0;
872}
873
874int cablecard_set(
875    cablecard_t cablecard,
876    cablecard_setting_t setting
877    )
878{
879    if (cablecard == NULL|| setting == NULL) return -1;
880    cablecard->oob_mode = setting->oob_mode;
881    cablecard->us_mode = setting->us_mode;
882    return 0;
883}
884
885#define ISO936_CODE_LENGTH 3
886#define MAX_PROGRAM_CC_SERVICE  32
887typedef struct
888{
889    uint16_t pid;
890    uint8_t streamType;
891    uint16_t ca_pid;
892    unsigned char iso639[ISO936_CODE_LENGTH];
893} EPID;
894
895typedef struct
896{
897    uint8_t ccType;
898    uint8_t ccService;
899    unsigned char iso639[ISO936_CODE_LENGTH];
900} ECC;
901
902#define MAX_PROGRAM_MAP_PIDS    12
903typedef struct
904{
905    uint16_t program_number;
906    uint16_t map_pid;
907    uint8_t  version;
908    uint8_t  broadcast_flag;
909    uint8_t  num_cc;
910    ECC      cc[MAX_PROGRAM_CC_SERVICE];
911    uint16_t pcr_pid;
912    uint16_t ca_pid;
913    uint8_t  num_video_pids;
914    EPID     video_pids[MAX_PROGRAM_MAP_PIDS];
915    uint8_t  num_audio_pids;
916    EPID     audio_pids[MAX_PROGRAM_MAP_PIDS];
917    uint8_t  num_other_pids;
918    EPID     other_pids[MAX_PROGRAM_MAP_PIDS];
919    uint32_t pmt_size;
920    uint8_t *pmt;
921} PROGRAM_INFO_T;
922
923static char atsc_id[4] = "GA94";
924static char scte_id[4] = "SCTE";
925void tsPsi_procProgDescriptors(
926    const uint8_t *p_bfr,
927    unsigned bfrSize,
928    PROGRAM_INFO_T *progInfo
929    )
930{
931    int i,j;
932    char *cc_ptr;
933    TS_PSI_descriptor descriptor;
934
935    for( i = 0, descriptor = TS_PMT_getDescriptor( p_bfr, bfrSize, i );
936        descriptor != NULL;
937        i++, descriptor = TS_PMT_getDescriptor( p_bfr, bfrSize, i ) )
938    {
939        switch (descriptor[0])
940        {
941        case TS_PSI_DT_CA:
942            progInfo->ca_pid = ((descriptor[4] & 0x1F) << 8) + descriptor[5];
943            break;
944        case TS_PSI_DT_Registration:
945            if (memcmp(atsc_id, &descriptor[2], 4) ==0)
946                BDBG_WRN((" ATSC MPEG2 registration descriptor"));
947            else if (memcmp(scte_id, &descriptor[2], 4) == 0)
948                BDBG_WRN((" SCTE MPEG2 registration descriptor"));
949            else
950                BDBG_WRN((" unknown MPEG2 registration descriptor"));
951            break;
952        case TS_PSI_DT_ATSC_RedistributionControl:
953            progInfo->broadcast_flag = true;
954            break;
955        case TS_PSI_DT_ATSC_CaptionService:
956            progInfo->num_cc = descriptor[2]&0x1f;
957            cc_ptr = (char*)&descriptor[3];
958            for (j=0;j<progInfo->num_cc;j++)
959            {
960                memcpy(progInfo->cc[j].iso639,cc_ptr,3);
961                cc_ptr +=3;
962                progInfo->cc[j].ccType = *cc_ptr>>7;
963                progInfo->cc[j].ccService = *cc_ptr&0x3f;
964                cc_ptr += 3;
965            }
966            break;
967        case TS_PSI_DT_ATSC_ContentAdvisory:
968            break;
969        default:
970            break;
971        }
972    }
973}
974
975void tsPsi_procStreamDescriptors(
976    const uint8_t *p_bfr,
977    unsigned bfrSize,
978    int streamNum,
979    EPID *ePidData
980    )
981{
982    int i;
983    TS_PSI_descriptor descriptor;
984
985    for( i = 0, descriptor = TS_PMT_getStreamDescriptor( p_bfr, bfrSize, streamNum, i );
986        descriptor != NULL;
987        i++, descriptor = TS_PMT_getStreamDescriptor( p_bfr, bfrSize, streamNum, i ) )
988    {
989        switch (descriptor[0])
990        {
991        case TS_PSI_DT_CA:
992            ePidData->ca_pid = ((descriptor[4] & 0x1F) << 8) + descriptor[5];
993            break;
994        case TS_PSI_DT_ATSC_ComponentName:
995            break;
996        case TS_PSI_DT_ATSC_AC3_Audio:
997            break;
998        default:
999            break;
1000        }
1001    }
1002}
1003
1004#define ADD_VIDEO_PID(P_INFO, PID, TYPE, PMT, PMTSIZE, INDEX) \
1005    do { \
1006    if( (P_INFO)->num_video_pids < MAX_PROGRAM_MAP_PIDS ) \
1007    { \
1008    BDBG_MSG(("  vpid[%d] 0x%x, type 0x%x", (P_INFO)->num_video_pids, (PID), (TYPE))); \
1009    (P_INFO)->video_pids[(P_INFO)->num_video_pids].pid = (PID); \
1010    (P_INFO)->video_pids[(P_INFO)->num_video_pids].streamType = (TYPE); \
1011    tsPsi_procStreamDescriptors((PMT), (PMTSIZE), (INDEX), &(P_INFO)->video_pids[(P_INFO)->num_video_pids] ); \
1012    (P_INFO)->num_video_pids++; \
1013    } \
1014    } while (0)
1015#define ADD_AUDIO_PID(P_INFO, PID, TYPE, PMT, PMTSIZE, INDEX) \
1016    do { \
1017    if( (P_INFO)->num_audio_pids < MAX_PROGRAM_MAP_PIDS ) \
1018    { \
1019    BDBG_MSG(("  apid[%d] 0x%x, type 0x%x", (P_INFO)->num_audio_pids, (PID), (TYPE))); \
1020    (P_INFO)->audio_pids[(P_INFO)->num_audio_pids].pid = (PID); \
1021    (P_INFO)->audio_pids[(P_INFO)->num_audio_pids].streamType = (TYPE); \
1022    tsPsi_procStreamDescriptors((PMT), (PMTSIZE), (INDEX), &(P_INFO)->audio_pids[(P_INFO)->num_audio_pids] ); \
1023    (P_INFO)->num_audio_pids++; \
1024    } \
1025    } while (0)
1026#define ADD_OTHER_PID(P_INFO, PID, TYPE, PMT, PMTSIZE, INDEX) \
1027    do { \
1028    if( (P_INFO)->num_other_pids < MAX_PROGRAM_MAP_PIDS ) \
1029    { \
1030    BDBG_MSG(("  opid[%d] 0x%x, type 0x%x", (P_INFO)->num_audio_pids, (PID), (TYPE))); \
1031    (P_INFO)->other_pids[(P_INFO)->num_other_pids].pid = (PID); \
1032    (P_INFO)->other_pids[(P_INFO)->num_other_pids].streamType = (TYPE); \
1033    tsPsi_procStreamDescriptors((PMT), (PMTSIZE), (INDEX), &(P_INFO)->other_pids[(P_INFO)->num_other_pids] ); \
1034    (P_INFO)->num_other_pids++; \
1035    } \
1036    } while (0)
1037
1038void parsePMT(
1039    const void *pmt,
1040    unsigned pmtSize,
1041    PROGRAM_INFO_T *p_programInfo
1042    )
1043{
1044    int i;
1045    TS_PMT_stream pmt_stream;
1046    TS_PSI_header header;
1047
1048    TS_PSI_getSectionHeader(pmt, &header );
1049
1050    /* Store the main information about the program */
1051    p_programInfo->program_number   = header.table_id_extension;
1052    p_programInfo->version          = header.version_number;
1053    p_programInfo->pcr_pid          = TS_PMT_getPcrPid(pmt, pmtSize);
1054
1055    /* find and process Program descriptors */
1056    tsPsi_procProgDescriptors(pmt, pmtSize, p_programInfo );
1057
1058    /* Find the video and audio pids... */
1059    p_programInfo->num_video_pids   = 0;
1060    p_programInfo->num_audio_pids   = 0;
1061    p_programInfo->num_other_pids   = 0;
1062
1063    for( i = 0; i < TS_PMT_getNumStreams(pmt, pmtSize); i++ )
1064    {
1065        int descIdx = 0;
1066        if (TS_PMT_getStream(pmt, pmtSize, i, &pmt_stream )) {
1067            BDBG_WRN(("Invalid PMT data detected"));
1068            continue;
1069        }
1070
1071        switch( pmt_stream.stream_type )
1072        {
1073        /* video formats */
1074        case TS_PSI_ST_11172_2_Video:  /* MPEG-1 */
1075            ADD_VIDEO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_VideoCodec_eMpeg1, pmt, pmtSize, i);
1076            break;
1077        case TS_PSI_ST_ATSC_Video:   /* ATSC MPEG-2 */
1078            ADD_VIDEO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_VideoCodec_eMpeg2, pmt, pmtSize, i);
1079            break;
1080        case TS_PSI_ST_13818_2_Video: /* MPEG-2 */
1081            ADD_VIDEO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_VideoCodec_eMpeg2, pmt, pmtSize, i);
1082            break;
1083        case TS_PSI_ST_14496_2_Video: /* MPEG-4 Part 2 */
1084            ADD_VIDEO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_VideoCodec_eMpeg4Part2, pmt, pmtSize, i);
1085            break;
1086        case TS_PSI_ST_14496_10_Video: /* H.264/AVC */
1087            ADD_VIDEO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_VideoCodec_eH264, pmt, pmtSize, i);
1088            break;
1089        case TS_PSI_ST_AVS_Video: /* AVS */
1090            ADD_VIDEO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_VideoCodec_eAvs, pmt, pmtSize, i);
1091            break;
1092        case TS_PSI_ST_SMPTE_VC1:      /* VC-1 */
1093            /* need to parse descriptor and then subdescriptor to determine profile */
1094            for (;;) {
1095                TS_PSI_descriptor desc = TS_PMT_getStreamDescriptor(pmt, pmtSize, i, descIdx);
1096                if (desc == NULL) break;
1097                descIdx++;
1098
1099                switch(desc[0]) {
1100                case TS_PSI_DT_Registration:
1101                    /* calculate and check format_identifier */
1102                    {
1103                    uint32_t format_identifier = (desc[2] << 24) + (desc[3] << 16) + (desc[4] << 8) + desc[5];
1104                    if (format_identifier == 0x56432D31) {
1105                        /* check that proper sub-descriptor exists */
1106                        int subdescriptor_tag = desc[6];
1107                        if (subdescriptor_tag == 0x01) {
1108                            int profile_level = desc[7];
1109                            if (profile_level >= 0x90)  /* Advanced Profile ES */
1110                                ADD_VIDEO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_VideoCodec_eVc1, pmt, pmtSize, i);
1111                            else /* Simple/Main Profile ES */
1112                                ADD_VIDEO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_VideoCodec_eVc1SimpleMain, pmt, pmtSize, i);
1113                        }
1114                    }
1115                    }
1116                    break;
1117                default:
1118                    break;
1119                }
1120            }
1121            break;
1122
1123        /* audio formats */
1124        case TS_PSI_ST_11172_3_Audio: /* MPEG-1 */
1125            ADD_AUDIO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_AudioCodec_eMpeg, pmt, pmtSize, i);  /* Same baudio_format for MPEG-1 or MPEG-2 audio */
1126            break;
1127        case TS_PSI_ST_13818_3_Audio: /* MPEG-2 */
1128            ADD_AUDIO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_AudioCodec_eMpeg, pmt, pmtSize, i);  /* Same baudio_format for MPEG-1 or MPEG-2 audio */
1129            break;
1130        case TS_PSI_ST_13818_7_AAC:  /* MPEG-2 AAC */
1131            ADD_AUDIO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_AudioCodec_eAac, pmt, pmtSize, i);    /* Note baudio_format_aac = MPEG-2 AAC */
1132            break;
1133        case TS_PSI_ST_14496_3_Audio: /* MPEG-4 AAC */
1134            ADD_AUDIO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_AudioCodec_eAacPlus, pmt, pmtSize, i);   /* Note baudio_format_aac_plus = MPEG-4 AAC */
1135            break;
1136        case TS_PSI_ST_ATSC_AC3:      /* ATSC AC-3 */
1137            ADD_AUDIO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_AudioCodec_eAc3, pmt, pmtSize, i);
1138            break;
1139        case TS_PSI_ST_ATSC_EAC3:     /* ATSC Enhanced AC-3 */
1140            ADD_AUDIO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_AudioCodec_eAc3Plus, pmt, pmtSize, i);
1141            break;
1142        case TS_PSI_ST_AVS_Audio:     /* AVS */
1143            ADD_AUDIO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_AudioCodec_eAvs, pmt, pmtSize, i);
1144            break;
1145
1146
1147        /* video or audio */
1148        case TS_PSI_ST_13818_1_PrivatePES:  /* examine descriptors to handle private data */
1149            for (;;) {
1150                TS_PSI_descriptor desc = TS_PMT_getStreamDescriptor(pmt, pmtSize, i, descIdx);
1151                if (desc == NULL) break;
1152                descIdx++;
1153
1154                switch(desc[0]) {
1155                /* video formats */
1156                case TS_PSI_DT_VideoStream:
1157                    /* MPEG_1_only_flag is bit 2 of desc[2], this determines MPEG-1/2 */
1158                    if ((desc[2] & 0x04) == 1)
1159                        ADD_VIDEO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_VideoCodec_eMpeg1, pmt, pmtSize, i);
1160                    else
1161                        ADD_VIDEO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_VideoCodec_eMpeg2, pmt, pmtSize, i);
1162                    break;
1163                case TS_PSI_DT_MPEG4_Video:
1164                    ADD_VIDEO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_VideoCodec_eMpeg4Part2, pmt, pmtSize, i);
1165                    break;
1166                case TS_PSI_DT_AVC:
1167                    ADD_VIDEO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_VideoCodec_eH264, pmt, pmtSize, i);
1168                    break;
1169                case TS_PSI_DT_AVS_Video:
1170                    ADD_VIDEO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_VideoCodec_eAvs, pmt, pmtSize, i);
1171                    break;
1172
1173                /* audio formats */
1174                case TS_PSI_DT_AudioStream:
1175                    ADD_AUDIO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_AudioCodec_eMpeg, pmt, pmtSize, i);   /* Same baudio_format for MPEG-1 or MPEG-2 audio */
1176                    break;
1177                case TS_PSI_DT_MPEG2_AAC:
1178                    ADD_AUDIO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_AudioCodec_eAac, pmt, pmtSize, i);   /* Note baudio_format_aac = MPEG-2 AAC */
1179                    break;
1180                case TS_PSI_DT_MPEG4_Audio:
1181                    ADD_AUDIO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_AudioCodec_eAacPlus, pmt, pmtSize, i); /* Note baudio_format_aac_plus = MPEG-4 AAC */
1182                    break;
1183                case TS_PSI_DT_DVB_AAC:
1184                    ADD_AUDIO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_AudioCodec_eAacPlus, pmt, pmtSize, i); /* Note baudio_format_aac_plus = MPEG-4 AAC */
1185                    break;
1186                case TS_PSI_DT_DVB_AC3:
1187                    ADD_AUDIO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_AudioCodec_eAc3, pmt, pmtSize, i);
1188                    break;
1189                case TS_PSI_DT_DVB_EnhancedAC3:
1190                    ADD_AUDIO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_AudioCodec_eAc3Plus, pmt, pmtSize, i);
1191                    break;
1192                case TS_PSI_DT_DVB_DTS:
1193                    ADD_AUDIO_PID(p_programInfo, pmt_stream.elementary_PID, NEXUS_AudioCodec_eDts, pmt, pmtSize, i);
1194                    break;
1195                default:
1196                    break;
1197                }
1198            }
1199            break;
1200        default:
1201            if( p_programInfo->num_other_pids < MAX_PROGRAM_MAP_PIDS )
1202            {
1203                ADD_OTHER_PID(p_programInfo, pmt_stream.elementary_PID, pmt_stream.stream_type, pmt, pmtSize, i);
1204            }
1205            break;
1206        }
1207        /* If we get any data our status is complete! */
1208    } /* EFOR Program map loop */
1209}
1210
1211
1212static uint32_t cablecard_get_index(
1213    uint8_t ltsid
1214    )
1215{
1216    uint32_t i;
1217
1218    /* assumption: this will not be called unless there is at least one available slot */
1219
1220    /* already assigned? */
1221    for (i=0;i<MAX_CABLECARD_ROUTE;i++)
1222    {
1223        if ((pg_info[i].ltsid == ltsid) && pg_info[i].valid)
1224            return i;
1225    }
1226
1227    /* otherwise pick first available */
1228    for (i=0;i<MAX_CABLECARD_ROUTE;i++)
1229    {
1230        if (!(pg_info[i].valid))
1231            return i;
1232    }
1233
1234    return 0xFFFF;
1235}
1236
1237int cablecard_inquire_program(
1238    cablecard_t cablecard,
1239    cablecard_program_info_t info
1240    )
1241{
1242    MPOD_RET_CODE       ret;
1243
1244    if (cablecard == NULL) return -1;
1245    BDBG_MSG((" inquire program ltsid %d PG num %d video_pid 0x%x", info->ltsid, info->program_number, info->video_pid));
1246    ret = B_Mpod_CaSendPmt((unsigned char *)info->pmt, B_MPOD_CA_QUERY, info->program_index, info->ltsid, info->source_id
1247                );
1248    return (ret != MPOD_SUCCESS);
1249}
1250
1251void removeKeyCb(
1252    uint16_t programNumber,
1253    uint8_t ltsid
1254    )
1255{
1256#if NEXUS_HAS_SECURITY
1257    int i;
1258    NEXUS_Error rc;
1259   
1260    for (i=0;i<MAX_CABLECARD_ROUTE;i++)
1261    {
1262        if ((pg_info[i].program_number == programNumber) && (pg_info[i].ltsid == ltsid) && pg_info[i].valid) break;
1263    }
1264   
1265    if (i >= MAX_CABLECARD_ROUTE) {
1266        BDBG_ERR((" can't match based on ltsid and PG number"));
1267        return;
1268    }
1269
1270    BDBG_MSG(("Removing CPKey for program number %d, ltsid %d\n", programNumber, ltsid));
1271
1272    if (keyslot[i])
1273    {
1274        if (pg_info[i].audio_pid[0] != 0 && pg_info[i].audio_pid[0] != 0x1fff)
1275        {
1276            rc = NEXUS_Security_RemovePidChannelFromKeySlot(keyslot[i], pg_info[i].audio_pidchannel[0]);
1277            if (rc != 0) 
1278            {
1279                BDBG_ERR(("NEXUS_Security_RemovePidChannelFromKeySlot: failed "));
1280            }
1281        }
1282
1283        if (pg_info[i].video_pid != 0 && pg_info[i].video_pid != 0x1fff)
1284        {
1285            rc = NEXUS_Security_RemovePidChannelFromKeySlot(keyslot[i], pg_info[i].video_pidchannel);
1286            if (rc != 0)
1287            {
1288                BDBG_ERR(("NEXUS_Security_RemovePidChannelFromKeySlot: failed "));
1289            }
1290        }
1291
1292        NEXUS_Security_FreeKeySlot(keyslot[i]);
1293        BDBG_MSG(("Free keyslot %p ", keyslot[i]));
1294        keyslot[i] = NULL;       
1295    }
1296       
1297#else
1298    BSTD_UNUSED(programNumber);
1299    BSTD_UNUSED(ltsid);
1300#endif
1301}
1302
1303void progKeyCb(
1304    uint8_t *desABAKey,
1305    uint16_t programNumber,
1306    uint8_t ltsid
1307    )
1308{
1309#if NEXUS_HAS_SECURITY
1310    int i;
1311    NEXUS_Error rc;
1312    NEXUS_SecurityClearKey ClearKey;
1313
1314    for (i=0;i<MAX_CABLECARD_ROUTE;i++)
1315    {
1316        if (pg_info[i].program_number == programNumber && pg_info[i].ltsid == ltsid) break;
1317    }
1318   
1319    if (i >= MAX_CABLECARD_ROUTE) {
1320        BDBG_ERR((" can't match based on ltsid and PG number"));
1321        return;
1322    }
1323
1324    BDBG_MSG((" CP: ltsid 0x%x ecmpid 0x%x Vpid 0x%x Apid 0x%x", ltsid, pg_info[i].ca_pid, pg_info[i].video_pid,
1325        pg_info[i].audio_pid[0]));
1326
1327    if (!keyslot[i])
1328    {
1329        NEXUS_SecurityAlgorithmSettings config_algorithm;
1330        NEXUS_SecurityKeySlotSettings Settings;
1331       
1332        NEXUS_Security_GetDefaultAlgorithmSettings(&config_algorithm);
1333        config_algorithm.terminationMode = NEXUS_SecurityTerminationMode_eCipherStealing;
1334        config_algorithm.algorithm = NEXUS_SecurityAlgorithm_e3DesAba;
1335        config_algorithm.algorithmVar = NEXUS_SecurityAlgorithmVariant_eEcb;
1336       
1337        NEXUS_Security_GetDefaultKeySlotSettings(&Settings);
1338        Settings.keySlotEngine = NEXUS_SecurityEngine_eCa;
1339        BDBG_MSG(("Allocating new key slot"));
1340        keyslot[i] = NEXUS_Security_AllocateKeySlot(&Settings);
1341        if (keyslot[i]== NULL) goto err;
1342        rc = NEXUS_Security_ConfigAlgorithm(keyslot[i], &config_algorithm);
1343        if (rc != 0) goto err;
1344    }
1345
1346    /* Route a clear key */
1347    ClearKey.keySize = 16; /* 16 bytes (128 bits) */
1348    BKNI_Memcpy(ClearKey.keyData, desABAKey, ClearKey.keySize);
1349   
1350    NEXUS_Security_GetDefaultClearKey(&ClearKey);
1351    ClearKey.keyEntryType = NEXUS_SecurityKeyType_eOdd;
1352    rc = NEXUS_Security_LoadClearKey( keyslot[i], &ClearKey);
1353    if (rc != 0) goto err;
1354    ClearKey.keyEntryType = NEXUS_SecurityKeyType_eEven;
1355    rc = NEXUS_Security_LoadClearKey( keyslot[i], &ClearKey);
1356    if (rc != 0) goto err;
1357
1358    if (pg_info[i].video_pid != 0 && pg_info[i].video_pid != 0x1fff)
1359    {
1360        BDBG_MSG(("Video Key, pid ch %d", pg_info[i].video_pidchannel));
1361        rc = NEXUS_Security_AddPidChannelToKeySlot(keyslot[i], pg_info[i].video_pidchannel);
1362        if (rc != 0) goto err;
1363    }
1364
1365    if (pg_info[i].audio_pid[0] != 0 && pg_info[i].audio_pid[0] != 0x1fff)
1366    {
1367        BDBG_MSG(("Audio Key, pid ch %d", pg_info[i].audio_pidchannel[0]));
1368        rc = NEXUS_Security_AddPidChannelToKeySlot(keyslot[i], pg_info[i].audio_pidchannel[0]);
1369        if (rc != 0) goto err;
1370    }
1371
1372    return;
1373err:
1374    BDBG_ERR(("Error in enabling 3des decryption\n"));
1375    return;
1376#else
1377    BSTD_UNUSED(desABAKey);
1378    BSTD_UNUSED(programNumber);
1379    BSTD_UNUSED(ltsid);
1380#endif
1381}
1382
1383int cablecard_enable_program(
1384    uint8_t* pmt,
1385    uint32_t pmtSize,
1386    NEXUS_ParserBand parserBand,
1387    NEXUS_PidChannelHandle videoPidChannel,
1388    NEXUS_PidChannelHandle audioPidChannel,
1389    uint32_t source_id,
1390    uint16_t *caPid
1391    )
1392{
1393    MPOD_RET_CODE   ret;
1394    cablecard_program_info info;
1395    PROGRAM_INFO_T p_programInfo;
1396    uint32_t j;
1397    uint8_t ltsid;
1398    NEXUS_PidChannelStatus status;
1399    NEXUS_PlaypumpHandle playpump;
1400
1401    if(pmtSize == 0) return -1;
1402
1403    printf("cablecard_enable_program\n");
1404    NEXUS_PidChannel_GetStatus(videoPidChannel, &status);
1405    info.video_pidchannel = status.pidChannelIndex;
1406    NEXUS_PidChannel_GetStatus(audioPidChannel, &status);
1407    info.audio_pidchannel[0] = status.pidChannelIndex;
1408   
1409    parsePMT((const void *)pmt, pmtSize, &p_programInfo);
1410   
1411    /* retrieve ltsid. Input parser band or playback parser band? */
1412    ltsid = parserBand; /* if input parser band, ltsid = parser band index */
1413    if((switchMap[0] == parserBand) || (switchMap[1] == parserBand))
1414    {
1415        /* playback parser band */
1416        NEXUS_PlaypumpStatus playpumpStatus;
1417       
1418        playpump = (switchMap[0] == parserBand) ? switchPlaypump[0] : switchPlaypump[1];
1419        NEXUS_Playpump_GetStatus(playpump, &playpumpStatus);
1420        ltsid = playpumpStatus.index + 0x10; /* ltsid = playback parser band index + 0x10 */
1421    }
1422   
1423    info.program_index = cablecard_get_index(ltsid);
1424    BDBG_ASSERT((info.program_index < MAX_CABLECARD_ROUTE));
1425
1426    /* convert p_programInfo to cablecard_program_info_t */
1427    info.source_id = source_id;
1428    info.program_number = p_programInfo.program_number;
1429    info.video_pid = p_programInfo.video_pids[0].pid;
1430    info.ca_pid = 0;
1431    for (j=0;j<MAX_AUDIO_STREAM;j++)
1432    {
1433        info.audio_pid[j] = p_programInfo.audio_pids[j].pid;
1434    }
1435    if (p_programInfo.num_video_pids && p_programInfo.video_pids[0].ca_pid)
1436    {
1437        info.ca_pid = p_programInfo.video_pids[0].ca_pid;
1438    }
1439    else if (p_programInfo.num_audio_pids && p_programInfo.audio_pids[0].ca_pid)
1440    {
1441        info.ca_pid = p_programInfo.audio_pids[0].ca_pid;
1442    }
1443    if (p_programInfo.ca_pid)
1444    {
1445        info.ca_pid = p_programInfo.ca_pid;
1446    }
1447    if (!info.ca_pid)
1448    {
1449        BDBG_MSG((" NO CA pid found!"));
1450    }
1451    *caPid = info.ca_pid;
1452    info.ltsid = ltsid;
1453    info.valid = true;
1454    BKNI_Memcpy(info.pmt, pmt, pmtSize);
1455
1456    BDBG_MSG((" enable program ltsid %d PG num %d video_pid 0x%x ca_pid 0x%x", ltsid, info.program_number, info.video_pid, info.ca_pid));
1457
1458    ret = B_Mpod_CaSendPmt((unsigned char *)pmt, B_MPOD_CA_OK_DESCRAMBLE, info.program_index, ltsid, source_id);
1459   
1460    pg_info[info.program_index] = info;
1461
1462    if (ret == MPOD_SUCCESS) {
1463        B_Mpod_CpAddProgram(info.program_index,info.program_number, info.ca_pid, ltsid);
1464    }
1465
1466    return (ret != MPOD_SUCCESS);
1467}
1468
1469int cablecard_disable_program(
1470    NEXUS_ParserBand parserBand
1471    )
1472{
1473    MPOD_RET_CODE       ret;
1474    cablecard_program_info info;
1475    uint8_t ltsid, index;
1476    NEXUS_PlaypumpHandle playpump;
1477   
1478    /* retrieve ltsid. Input parser band or playback parser band? */
1479    ltsid = parserBand; /* if input parser band, ltsid = parser band index */
1480    if((switchMap[0] == parserBand) || (switchMap[1] == parserBand))
1481    {
1482        /* playback parser band */
1483        NEXUS_PlaypumpStatus playpumpStatus;
1484       
1485        playpump = (switchMap[0] == parserBand) ? switchPlaypump[0] : switchPlaypump[1];
1486        NEXUS_Playpump_GetStatus(playpump, &playpumpStatus);
1487        ltsid = playpumpStatus.index + 0x10; /* ltsid = playback parser band index + 0x10 */
1488    }
1489   
1490    index = cablecard_get_index(ltsid);
1491    BDBG_ASSERT((index < MAX_CABLECARD_ROUTE));
1492   
1493    info = pg_info[index];
1494    ret = B_Mpod_CaSendPmt((unsigned char *)info.pmt, B_MPOD_CA_NOT_SELECTED, info.program_index, ltsid, info.source_id);
1495
1496    B_Mpod_CpRemoveProgram(index);
1497
1498    info.valid = false;
1499   
1500    BDBG_MSG((" disable program ltsid %d PG num %d video_pid 0x%x ca_pid 0x%x", ltsid, info.program_number, info.video_pid, info.ca_pid));
1501
1502    return 0;
1503}
1504
1505int cablecard_set_mpeg_section_callback(
1506    cablecard_t cablecard,
1507    cablecard_mpeg_callback callback
1508    )
1509{
1510    if (cablecard == NULL) return -1;
1511
1512    if (!cablecard->mpeg_section) {
1513        cablecard->mpeg_section = (unsigned char *)BKNI_Malloc(MAX_MPEG_SECTION_LEN);
1514        cablecard->mpeg_section_len = 0;
1515    }
1516    cablecard->si_callback = callback;
1517
1518    return 0;
1519}
1520
1521int cablecard_get_mpeg_section(
1522    cablecard_t cablecard,
1523    void *buffer,
1524    size_t size
1525    )
1526{
1527    if (cablecard == NULL) return -1;
1528
1529    if (cablecard->mpeg_section) {
1530        cablecard_lock();
1531        size = (cablecard->mpeg_section_len > size)? size : cablecard->mpeg_section_len;
1532        BKNI_Memcpy(buffer, cablecard->mpeg_section, size);
1533        cablecard_unlock();
1534        return size;
1535    }
1536
1537    return -1;
1538}
1539
1540static int bcm_3255_tristate_oob_pins(
1541    void
1542    )
1543{
1544    NEXUS_3255GpioPinSettings settings;
1545    NEXUS_PlatformConfiguration platformConfig;
1546    int rc;
1547
1548    settings.mode = NEXUS_GpioMode_eOutputOpenDrain;
1549    NEXUS_Platform_GetConfiguration(&platformConfig);
1550    rc = NEXUS_Frontend_3255_SetGpioPinSettings(platformConfig.frontend[MAX_TUNER], NEXUS_3255GpioPin_eOob, &settings);
1551    return rc;
1552}
1553
1554static int bcm_3255_enable_oob_pins(
1555    void
1556    )
1557{
1558    NEXUS_3255GpioPinSettings settings;
1559    NEXUS_PlatformConfiguration platformConfig;
1560
1561    settings.mode = NEXUS_GpioMode_eOutputPushPull;
1562    NEXUS_Platform_GetConfiguration(&platformConfig);
1563    return NEXUS_Frontend_3255_SetGpioPinSettings(platformConfig.frontend[MAX_TUNER], NEXUS_3255GpioPin_eOob, &settings);
1564}
1565
1566void cablecard_in(
1567    void
1568    )
1569{
1570    cablecard_t cablecard = cablecard_get_instance();
1571    NEXUS_PlatformConfiguration platformConfig;
1572    int i;
1573
1574    BDBG_WRN((" CableCard is in\n"));
1575    bcm_3255_enable_oob_pins();
1576    cablecard->cablecard_in = true;
1577    page_cleanup();
1578    NEXUS_Platform_GetConfiguration(&platformConfig);
1579    for (i=0;i<5;i++)
1580    {
1581        if (platformConfig.frontend[i])
1582            cablecard_route_add_tuner(cablecard, platformConfig.frontend[i]);
1583    }
1584}
1585
1586void cablecard_out(
1587    void
1588    )
1589{
1590    cablecard_t cablecard = cablecard_get_instance();
1591    NEXUS_PlatformConfiguration platformConfig;
1592    int i;
1593
1594    BDBG_WRN((" CableCard is out\n"));
1595    cablecard->cablecard_in = false;
1596    cablecard_reset();
1597    bcm_3255_tristate_oob_pins();
1598    NEXUS_Platform_GetConfiguration(&platformConfig);
1599    for (i=0;i<5;i++)
1600    {
1601        if (platformConfig.frontend[i])
1602            cablecard_route_remove_tuner(cablecard, platformConfig.frontend[i]);
1603    }
1604}
1605
1606void cablecard_error(
1607    void
1608    )
1609{
1610    BDBG_WRN((" CableCard Error\n"));
1611}
1612
1613void cablecard_reset(
1614    void
1615    )
1616{
1617#ifdef ESTB_CFG_SUPPORT
1618    unsigned int  cdl_group_id = 0;
1619#endif
1620    CableCardRemovedCallbackCleanUp();
1621    memset(&info, 0, sizeof(info));
1622#if 0
1623    channel_mgr_reset_map();
1624#endif
1625    page_cleanup();
1626#ifdef ESTB_CFG_SUPPORT
1627    B_Estb_cfg_Set_uint32("/dyn/estb/group_id", cdl_group_id);
1628#endif
1629}
1630
1631int cablecard_set_dsgtunnel_handler(
1632    cablecard_t cablecard,
1633    cablecard_dsg_handler  *dsg_handler
1634    )
1635{
1636    if (cablecard->num_of_dsg_handler >= MAX_DSGTUNNEL_HANDLER) return -1;
1637    cablecard->dsg_handler[cablecard->num_of_dsg_handler++] = *dsg_handler;
1638    return 0;
1639}
1640
1641unsigned char BcmSendDSGTunnelDataToHost(
1642    unsigned char *pBufData,
1643    unsigned int pktlen,
1644    unsigned long client_type,
1645    unsigned long client_id
1646    )
1647{
1648
1649    cablecard_t cablecard = cablecard_get_instance();
1650    unsigned short     ether_type, GutsLen;
1651    unsigned char     *pFirstBuffData = pBufData;
1652    int i;
1653
1654    if (cablecard == NULL) return -1;
1655
1656   /*
1657     * Only forward these types (0800,0806) to TCPIP all others return.
1658     */
1659    ether_type = ((unsigned char *)pFirstBuffData)[12];
1660    ether_type <<= 8;
1661    ether_type |= ((unsigned char *)pFirstBuffData)[13];
1662
1663    /*
1664     * discard non-IP ethernet packet data
1665     */
1666    if (ether_type != 0x0800) {
1667        printf("err1, ether_type=%04x(%04x)\n", ether_type, 0x0800);
1668        return -1;
1669    }
1670
1671    /*
1672     * Passed IP checking, now the protocol type is farther in to the packet.
1673     * Evaluate it to make checking for UDP.
1674     */
1675    if (((unsigned char *)pFirstBuffData)[14 + 9] != 17/*IPPROTO_UDP*/) {
1676        printf("err2, Not UDP packet=%02x(%02x)\n", ((unsigned char *)pFirstBuffData)[14 + 9], 17/*IPPROTO_UDP*/ );
1677        return -1;
1678    }
1679
1680    /*
1681     * get the UDP packet length, subtract 8 for UDP header
1682     */
1683    GutsLen = ((unsigned char *)pFirstBuffData)[14 + 20 + 4];
1684    GutsLen <<= 8;
1685    GutsLen |= ((unsigned char *)pFirstBuffData)[14 + 20 + 5];
1686    pktlen = GutsLen - 8;
1687
1688    /*
1689     * offset to start of UDP data
1690     */
1691    pBufData = pFirstBuffData + 14 + 20 + 8;
1692
1693    // we have NOT seen any HE to send out new Broadcasting tunnels with BT header
1694    if (getenv("BT_HEADER") != NULL) {
1695        if (client_type == DSG_CLIENT_TYPE_BROADCAST) {
1696        /* TODO:: process BT header. Skip now*/
1697            pBufData += 4;
1698            pktlen -= 4;
1699        }
1700    }
1701
1702    if (pktlen <= 0) {
1703        printf(" error in DSG tunnel data %d\n", pktlen);
1704        return -1;
1705    }
1706
1707    // first dispatch the DSG tunnel to registered external handlers
1708    for (i=0;i<cablecard->num_of_dsg_handler;i++)
1709    {
1710        if (cablecard->dsg_handler[i].callback != NULL
1711            && client_id == cablecard->dsg_handler[i].client_id
1712            && client_type == cablecard->dsg_handler[i].client_type)
1713        {
1714            (*cablecard->dsg_handler[i].callback)(pBufData, pktlen);
1715            return 0;
1716        }
1717    }
1718
1719    if (client_type == DSG_CLIENT_TYPE_BROADCAST) {
1720        BDBG_MSG((" Got Broadcast DSG tunnel!\n"));
1721
1722        switch ( client_id ) {
1723            case DSG_CLIENT_BROADCAST_TYPE_SCTE65:
1724                BDBG_MSG((" Got SCTE 65 DSG tunnel! \n"));
1725                if (cablecard->mpeg_section) {
1726                    cablecard_lock();
1727                    cablecard->mpeg_section_len = (pktlen > MAX_MPEG_SECTION_LEN)? MAX_MPEG_SECTION_LEN : pktlen;
1728                    BKNI_Memcpy(cablecard->mpeg_section, pBufData, cablecard->mpeg_section_len);
1729                    cablecard_unlock();
1730                }
1731                /* This callback will pass SI data (MPEG2 section) to SI parsing library*/
1732                if (cablecard->si_callback)
1733                    (*cablecard->si_callback)(cablecard, cablecard->mpeg_section_len);
1734                break;
1735            case DSG_CLIENT_BROADCAST_TYPE_SCTE18:
1736                BDBG_MSG((" Got SCTE 18 DSG tunnel! \n"));
1737                break;
1738            case DSG_CLIENT_BROADCAST_TYPE_XAIT_CVT:
1739                BDBG_MSG((" Got CVT or XAIT DSG tunnel! ID 0x%2x\n", pBufData[0]));
1740#ifdef CDL_SUPPORT
1741                /* CVT: table ID is 0xd9; XAIT: table ID is 0x74*/
1742                /*fixme: how to tell it's CVT or XAIT? */
1743                /* debug only, use a cvt captured in file */
1744#if 0
1745                {
1746                    int fp;
1747                    char fn_cvt[128] ="./signed_cvt_capture.bin";
1748                    if ((fp  = open(fn_cvt, O_RDONLY)) < 0) {
1749                        BDBG_ERR(("cannot open %s", fn_cvt));
1750                    } else {
1751                        pktlen = read(fp, pBufData, pktlen);
1752                        BDBG_ERR(("cvt pktlen %d bytes", pktlen));
1753                        close(fp);
1754                    }
1755                }
1756#endif
1757                if (pBufData[0] == 0xd9) {
1758                    BDBG_ERR(("pktlen %d", pktlen));
1759                    cdl_dsg_cvt_process(NULL, pBufData, pktlen);
1760                }
1761#endif
1762                break;
1763        case DSG_CLIENT_BROADCAST_TYPE_OCCD:
1764                BDBG_MSG((" Got OCAP Comon Download DSG tunnel!"));
1765                break;
1766        case DSG_CLIENT_BROADCAST_TYPE_OBJECT_CAROUSEL:
1767                BDBG_MSG((" Got Object Carousel DSG tunnel!"));
1768                break;
1769            default:
1770                BDBG_MSG((" Got unknown type Broadcast tunnel!"));
1771                break;
1772        }
1773    } else if (client_type ==  DSG_CLIENT_TYPE_APPLICATION ){
1774        BDBG_MSG((" Got Application type DSG tunnel!\n"));
1775    } else if (client_type ==  DSG_CLIENT_TYPE_WELLKNOWN_MACADDR){
1776        BDBG_MSG((" Got Well-Known Macaddr  DSG tunnel!  \n"));
1777    } else if (client_type ==  DSG_CLIENT_TYPE_CAS){
1778        BDBG_WRN((" Got CA DSG tunnel! Should NOT be terminated at Host!\n"));
1779    } else {
1780        BDBG_WRN((" Got unknown type DSG tunnel!\n"));
1781    }
1782
1783    return 0;
1784}
1785
1786unsigned char BcmSendDSGTunnelDataToPOD(
1787    unsigned char *pBufData,
1788    unsigned int pktlen,
1789    unsigned long flow_id
1790    )
1791{
1792    unsigned char *ptr=NULL, ret_val;
1793
1794    BDBG_MSG((" BcmSendDSGTunnelDataToPOD len %d  flowID 0x%x", pktlen, flow_id));
1795
1796    if (pktlen>=65535)
1797    {
1798        printf("too big %d\n", pktlen);
1799        return 1; /* Change the return value */
1800    }
1801
1802    /* Need to stick 2 bytes of length count infront of the packet per Opencable spec...
1803     The buffer will be Queued and sent to cablecard in link layer Send thread
1804     The buffer will be freed in link layer.
1805     So, have to allocate buffer and copy the entire packet.
1806     Not the best solution in town, will optimize later.*/
1807    ptr = (unsigned char*)BKNI_Malloc(pktlen+4);
1808    if( ptr )
1809        BKNI_Memcpy(ptr+2, pBufData, pktlen);
1810    else
1811        BDBG_ASSERT((0));
1812
1813    /* add 2 byte length */
1814    *ptr = pktlen >> 8;
1815    *(ptr+1) = pktlen & 0xff;
1816
1817    ret_val = (unsigned char) B_Mpod_LinkH2CSendExtData(flow_id, pktlen+2, ptr);
1818    if( ret_val != 0 )
1819        printf("\n!CableCard Not Rdy! RX DSG tunnel packet with MacAddr=0x%08lx_%04x, pktlen=%d\n", *(unsigned long *)(pBufData), *(unsigned short *)(pBufData+4), pktlen );
1820
1821    /* free(ptr); free at link layer  */
1822
1823    return ret_val;
1824
1825}
1826
1827/*for IP-U and socket flow*/
1828unsigned char BcmSendDataToPOD(
1829    unsigned char *pBufData,
1830    unsigned int pktlen,
1831    unsigned long flow_id
1832    )
1833{
1834
1835    unsigned char *ptr=NULL, ret_val;
1836
1837    if (pktlen>=65535)
1838    {
1839        printf("too big %d\n", pktlen);
1840        return 1;
1841    }
1842
1843    BDBG_MSG((" BcmSendDataToPOD len %d  flowID 0x%x", pktlen, flow_id));
1844
1845/*  // Need to have a check here if the CableCard is present/absent,
1846    // if cablecard is not present, no need to waste time copy packet, just return
1847    // if( CableCard is not present )
1848    //  return POD_NOT_READY;
1849
1850    // No Need to stick 2 bytes of length count infront of the packet per Opencable spec...
1851    // The buffer will be Queued and sent to cablecard in link layer Send thread
1852    // The buffer will be freed in link layer.
1853    // So, have to allocate buffer and copy the entire packet.
1854    // Not the best solution in town, will optimize later.*/
1855    ptr =(unsigned char*)BKNI_Malloc(pktlen);
1856    if( ptr )
1857        BKNI_Memcpy (ptr, pBufData, pktlen);
1858    else
1859        return -1;
1860
1861    /*printf("************** BcmSendDataToPOD **************\n"); */
1862
1863    ret_val = (unsigned char) B_Mpod_LinkH2CSendExtData(flow_id, pktlen, ptr);
1864    if( ret_val )
1865        printf("\n!CableCard Not Rdy! RX DSG tunnel packet with MacAddr=0x%08lx_%04x, pktlen=%d\n", *(unsigned long *)(pBufData), *(unsigned short *)(pBufData+4), pktlen );
1866
1867    /* free(ptr); free at link layer  */
1868    return ret_val;
1869
1870}
1871
1872void POD_Api_Lost_Flow_Ind(
1873    unsigned long id,
1874    unsigned char status
1875    )
1876{
1877    printf("\nsent to Cablecard: lost_flow_ind id=0x%x, status=%d!\n", (unsigned int)id, (int)status);
1878    B_Mpod_ExtChLostFlow(id, (B_MPOD_EXT_LOST_FLOW_REAS)status);
1879}
1880
1881void POD_Api_Send_DCD_Info(
1882    void *dcd_ptr,
1883    unsigned short dcd_len
1884    )
1885{
1886    /* skip first three bytes to comform latest CCIF spec*/
1887    /* TODO:: wait for DSG-CC final fix*/
1888    if (info.extSession > 4)
1889    {
1890        B_Mpod_DsgSendDcdInfo((uint8_t*)dcd_ptr, (uint32_t)dcd_len);
1891    } else      if (info.extSession) {
1892        B_Mpod_ExtChSendDcdInfo((uint8_t*)dcd_ptr, (uint32_t)dcd_len);
1893    } else
1894        BDBG_ERR((" both DSG and extended channel have NOT opened yet"));
1895}
1896
1897void POD_Api_Send_DSG_Message(
1898    void *dsg_message_ptr,
1899    unsigned short dsg_message_len
1900    )
1901{
1902    if (info.extSession > 4)
1903    {
1904        B_Mpod_DsgSendDSGMessage((uint8_t *)dsg_message_ptr,(uint32_t)dsg_message_len);
1905    } else if (info.extSession) {
1906        B_Mpod_ExtChSendDSGMessage((uint8_t *)dsg_message_ptr,(uint32_t)dsg_message_len);
1907    } else
1908        BDBG_ERR((" both DSG and extended channel have NOT opened yet"));
1909}
1910
1911/* For the DSG and Ext Channel Settings */
1912void CableCardCallback_DSG_Packet_Error(
1913    uint8_t *data,
1914    uint32_t len
1915    )
1916{
1917    BSTD_UNUSED(len);
1918    CableCardCallbackDSGPacketError((unsigned char)*data);
1919}
1920
1921void CableCardCallback_ExtSet_DSG_Mode(
1922    uint8_t *data,
1923    uint32_t len
1924    )
1925{
1926    info.mode = (B_MPOD_EXT_OP_MODE)data[0];
1927    info.extSession = 4;
1928
1929    /* HPNX pro send us basic DSG mode without mac_addr*/
1930    if ( (data[0] == B_MPOD_EXT_DSG || data[0] == B_MPOD_EXT_DSG_ONE_WAY) && len == 1) return;
1931
1932    /* if switch to DSG mode, we need to switch docsis Upstream mode*/
1933    if ( data[0] != B_MPOD_EXT_OOB) OOB_Tx_Docsis();
1934
1935    CableCardCallbackSetDSGMode((unsigned char *)data, (unsigned short)len);
1936}
1937
1938void CableCardCallback_DSGSet_DSG_Mode(
1939    uint8_t *data,
1940    uint32_t len
1941    )
1942{
1943    info.mode = (B_MPOD_EXT_OP_MODE)data[0];
1944    info.extSession = 5;
1945
1946    /* HPNX pro send us basic DSG mode without mac_addr*/
1947    if ( (data[0] == B_MPOD_EXT_DSG || data[0] == B_MPOD_EXT_DSG_ONE_WAY) && len == 1) return;
1948
1949    /* if switch to DSG mode, we need to switch docsis Upstream mode*/
1950    if ( data[0] != B_MPOD_EXT_OOB) OOB_Tx_Docsis();
1951
1952    CableCardCallbackSetDSGMode((unsigned char *)data, (unsigned short)len);
1953}
1954
1955void CableCardCallback_DSG_Directory(
1956    uint8_t *data,
1957    uint32_t len
1958    )
1959{
1960    int vct_id_included, vct_id = 0;
1961    unsigned char *ptr = data;
1962
1963    /* get VCT id if possible*/
1964    vct_id_included = (*ptr++ & 0x01);
1965    if (vct_id_included) {
1966        vct_id = (data[len-2]<<8)|data[len-1];
1967        BDBG_MSG((" VCI_ID included in DSG_directory %d", vct_id));
1968        info.vctId = vct_id;
1969        /*TODO:: notify application for SI data filtering*/
1970    }
1971    CableCardCallbackDSG_Directory((unsigned char *)data, (unsigned short)len);
1972}
1973
1974void CableCardCallback_IPU_Dhcp(
1975    uint32_t flowId,
1976    uint8_t *data,
1977    uint32_t len
1978    )
1979{
1980    unsigned char status = 0, flowtype = 0x00, flags = 1;
1981    unsigned short max_pdu_size = 1500;
1982    unsigned long ipaddr = 0xc0a80001;
1983    unsigned char *ropt_data = NULL;
1984    int ropt_len = 128; /*Guessing: max return option length*/
1985    uint8_t *a = &(data[1]);
1986    unsigned int optLen = data[7];
1987    unsigned char *optBytes = &(data[8]);
1988
1989    BDBG_MSG(("MacAddr: %02x:%02x:%02x:%02x:%02x:%02x, option length: %d",
1990                  a[0],a[1],a[2],a[3],a[4],a[5], optLen));
1991
1992    memcpy(info.macaddr, a, 6);
1993    if( len == (optLen + 8) && optLen && optBytes )
1994    {
1995        printf("\n dhcp option field (hex):");
1996        for(ipaddr=0; ipaddr<optLen; ipaddr++ )
1997        {
1998            if( (ipaddr % 32) == 0 )
1999                printf("\n");
2000            printf(" %02x", optBytes[ipaddr] );
2001        }
2002        printf("\n");
2003    }
2004    else {
2005        optLen = 0;
2006        printf(" No dhcp option field!");
2007    }
2008
2009    ropt_data = (unsigned char *)malloc( ropt_len );
2010    if( ropt_data == NULL )
2011    {
2012        printf("Error! Cannot allocate space for dhcp option data\n");
2013        return;
2014    }
2015
2016    /*Call Host to send DHCP and WAIT for the response*/
2017    ipaddr = CableCardCallbackIPUDhcp( flowId, a, optLen,
2018                                        optBytes, ropt_data, &ropt_len );
2019
2020    ipaddr = htonl(ipaddr);
2021    printf("DHCP reply with IPAddress 0x%08lx with option-field data len=%d\n\n", ipaddr, ropt_len);
2022
2023    /* Network is unavailable*/
2024    if (ipaddr == 0) {
2025        status =  B_MPOD_EXT_DEL_FLOW_NETUNAVAIL;
2026        ropt_len = 0;
2027    }
2028    memcpy(info.ipaddr, &ipaddr, 4); //TODO:: ipv6
2029
2030    B_Mpod_ExtChIpUnicastFlowCnf( flowId, (B_MPOD_EXT_NEW_FLOW_CNF_STAT)status, (unsigned char *)&ipaddr, flowtype, flags, max_pdu_size, ropt_len, ropt_data);
2031
2032    /*When this function return, the ropt_data pointer can be freed.*/
2033
2034    free(ropt_data);
2035}
2036
2037B_MPOD_EXT_NEW_FLOW_CNF_STAT CableCardCallback_Req_Ipm_Flow(
2038    uint32_t flowId,
2039    uint32_t mgid
2040    )
2041{
2042    BSTD_UNUSED(flowId);
2043    BSTD_UNUSED(mgid);
2044    return 0;
2045}
2046
2047B_MPOD_EXT_NEW_FLOW_CNF_STAT CableCardCallback_DSG_Flow_Id(
2048    uint32_t flowId
2049    )
2050{
2051    CableCardCallbackDSGFlowID(flowId); /* For DSG flow */
2052    return B_MPOD_EXT_NEW_FLOW_GRANTED;
2053}
2054
2055void CableCardCallback_Socket_Flow_Config(
2056    uint32_t flowId,
2057    uint8_t *opt_data,
2058    uint32_t opt_len
2059    )
2060{
2061    unsigned short max_pdu_size = 1500;
2062    unsigned char status;
2063
2064    status = CableCardCallbackSocketFlowConfig(flowId, opt_data, opt_len);
2065    BDBG_MSG(("-----New_flow_req type Socket: id=%d, opt_len=%d", flowId, opt_len));
2066
2067    B_Mpod_ExtChSocketFlowCnf(flowId, (B_MPOD_EXT_NEW_FLOW_CNF_STAT)status, max_pdu_size, opt_len, opt_data);
2068
2069}
2070
2071static void CableCardCallback_Flow_Req_Failed(
2072    B_MPOD_EXT_SERV_TYPE serviceType,
2073    B_MPOD_EXT_NEW_FLOW_CNF_STAT status
2074    )
2075{
2076    BSTD_UNUSED(serviceType);
2077    BSTD_UNUSED(status);
2078}
2079
2080static void CableCardCallback_New_Flow_Cnf_Cb(
2081    uint32_t flowId,
2082    B_MPOD_EXT_SERV_TYPE serviceType,
2083    uint16_t pid
2084    )
2085{
2086    BDBG_MSG(("received %s flowId=%d serviceType=%d pid=%d\n", __FUNCTION__, flowId, (uint32_t) serviceType, pid));
2087}
2088
2089B_MPOD_EXT_DEL_FLOW_CNF_STAT CableCardCallback_Delete_Flow_Req(
2090    uint32_t flowId,
2091    B_MPOD_EXT_SERV_TYPE serviceType
2092    )
2093{
2094    if (serviceType == B_MPOD_EXT_FLOW_IP_U || serviceType ==   B_MPOD_EXT_FLOW_IP_M || serviceType == B_MPOD_EXT_FLOW_SOCKET)
2095    {
2096        CableCardCallbackDeleteFlowReq(flowId);
2097        return B_MPOD_EXT_DEL_FLOW_GRANTED;
2098    } else
2099        return B_MPOD_EXT_DEL_FLOW_UNAUTH;
2100}
2101
2102static void CableCardCallback_Del_Flow_Cnf_Cb(
2103    uint32_t flowId,
2104    B_MPOD_EXT_SERV_TYPE serviceType
2105    )
2106{
2107    BSTD_UNUSED(flowId);
2108    BSTD_UNUSED(serviceType);
2109}
2110
2111static void CableCardCallback_Lost_Flow_Cb(
2112    uint32_t flowId,
2113    B_MPOD_EXT_SERV_TYPE serviceType,
2114    B_MPOD_EXT_LOST_FLOW_REAS reason
2115    )
2116{
2117    BSTD_UNUSED(flowId);
2118    BSTD_UNUSED(serviceType);
2119    BSTD_UNUSED(reason);
2120}
2121
2122void CableCardCallback_Config_Advanced_DSG(
2123    uint8_t *data,
2124    uint32_t len
2125    )
2126{
2127    CableCardCallbackConfig_Advanced_DSG(data, len);
2128}
2129
2130void CableCardCallback_Rcv_Flow_Data(
2131    uint32_t flowId,
2132    B_MPOD_EXT_SERV_TYPE serviceType,
2133    uint8_t *data,
2134    uint32_t len
2135    )
2136{
2137    if(serviceType == B_MPOD_EXT_FLOW_IP_U) {
2138        CableCardCallbackSendIPUData(data, len );
2139    }
2140    else if(serviceType == B_MPOD_EXT_FLOW_SOCKET) {
2141        CableCardCallbackSendSocketFlowUsData( flowId, data, len );
2142    }
2143    else if (serviceType == B_MPOD_EXT_FLOW_MPEG) {
2144        cablecard_t cablecard = cablecard_get_instance();
2145
2146        if (cablecard->mpeg_section) {
2147            cablecard_lock();
2148            cablecard->mpeg_section_len = (len  > MAX_MPEG_SECTION_LEN)? MAX_MPEG_SECTION_LEN : len;
2149            BKNI_Memcpy(cablecard->mpeg_section, data, cablecard->mpeg_section_len);
2150            cablecard_unlock();
2151        }
2152        /* This callback will notify SI parser thread to process new SI data*/
2153        if (cablecard->si_callback)
2154            (*cablecard->si_callback)(cablecard, cablecard->mpeg_section_len);
2155    }
2156    else {
2157        /* do nothing */
2158        BDBG_WRN((" unhandled service type flow data %d", serviceType ));
2159    }
2160}
2161
2162static void apInfoInfo_Changed_Cb(
2163    void
2164    )
2165{
2166    int id;
2167    cablecard_t cablecard = cablecard_get_instance();
2168    cablecard_setting s;
2169
2170    BDBG_MSG(("apInfoInfoRdyCb Callback Called\n"));
2171    B_Mpod_AppInfoGetManuID(&info.vendorId);
2172    id = ((info.vendorId>>8)&0xff);
2173    B_Mpod_AppInfoGetVersionNum(&info.version);
2174    B_Mpod_AppInfoGetSerialNum(info.serialNum, &info.serialLen);
2175    B_Mpod_AppInfoGetMacAddr(info.macaddr);
2176    if (info.serialLen == 0)
2177    {
2178        memset(info.serialNum, 0, sizeof(info.serialNum));
2179        memset(info.macaddr, 0, sizeof(info.macaddr));
2180    }
2181    /* set correct OOB upstream mode according to card vendor ID*/
2182    BDBG_MSG((" CableCARD manufacture_id 0x%x",info.vendorId));
2183    // use symbolrate to automatically set correct OOB mode
2184    cablecard_get(cablecard, &s);
2185    s.us_mode = (id == 0) ? NEXUS_FrontendUpstreamMode_ePodDvs178: NEXUS_FrontendUpstreamMode_ePodDvs167;
2186    s.oob_mode = (id == 0) ? NEXUS_FrontendOutOfBandMode_ePod_Dvs178Qpsk: NEXUS_FrontendOutOfBandMode_ePod_Dvs167Qpsk;
2187    BDBG_WRN((" set OOB mode to %s", ((id==0)? "DVS178" : "DVS167")));
2188    cablecard_set(cablecard,&s);
2189
2190}
2191
2192static uint32_t dialogs[8];
2193#define MARK_AS_VALID(number)   (dialogs[(number) >> 5] |=  (1 << ((number) & 0x1f)))
2194#define MARK_AS_INVALID(number) (dialogs[(number) >> 5] &= ~(1 << ((number) & 0x1f)))
2195#define CHECK_IF_VALID(number)  (dialogs[(number) >> 5] &   (1 << ((number) & 0x1f)))
2196
2197typedef struct cablecard_message_t {
2198    char diag_message[NUM_CABLECARD_LINES][NUM_CABLECARD_CHARS]; /* for the app info recieved when we send the URLs */
2199    unsigned int diag_message_filled;   /* no: of lines on the page filled */
2200}cablecard_message ;
2201
2202static cablecard_message cablecard_page;
2203
2204static void page_cleanup(
2205    void
2206    )
2207{
2208    int j=0;
2209    for(j=0;j<NUM_CABLECARD_LINES;j++) {
2210        memset(cablecard_page.diag_message[j], 0, NUM_CABLECARD_CHARS);
2211    }
2212}
2213
2214/* No of lines to be updated */
2215unsigned int get_num_lines_filled(
2216    void
2217    )
2218{
2219    return cablecard_page.diag_message_filled;
2220}
2221
2222char *get_cablecard_info(
2223    int line_num
2224    )
2225{
2226    return cablecard_page.diag_message[line_num];
2227}
2228
2229/* To recieve the various App info thro a callback for the URLs sent  */
2230void cablecard_receive_app_info_query(
2231    uint8_t *html,
2232    uint16_t len,
2233    uint8_t dialogNb,
2234    uint8_t fileStatus
2235    )
2236{
2237    int i=0, cnt=0, j=0;
2238    BSTD_UNUSED(dialogNb);
2239    BSTD_UNUSED(fileStatus);
2240
2241    for (i=0;i<NUM_CABLECARD_LINES;i++)
2242    {
2243        while (j < NUM_CABLECARD_CHARS-1 && cnt <len)
2244        {
2245            if ((html[cnt] != '<') && (html[cnt] != '&') && (html[cnt] != '\n') && (html[cnt] != '\0'))
2246            {
2247                cablecard_page.diag_message[i][j++] = html[cnt++];
2248            } else if (html[cnt] == '<'){
2249                // check the next three characters
2250                if(((html[cnt+1] == 'b')||(html[cnt+1] == 'B')) && ((html[cnt+2] == 'r')|| (html[cnt+2] == 'R'))
2251                    && (html[cnt+3] == '>')){
2252                    cnt = cnt + 4;
2253                    cablecard_page.diag_message[i][j] = 0;
2254                    goto next_line;
2255                }
2256                else{
2257                    while (html[cnt] != '>'){
2258                        cnt++;
2259                    }
2260                    cnt++;
2261                }
2262            } else if(html[cnt] == '&') {
2263                cnt+=6;
2264            } else
2265                cnt++;
2266        }
2267        if (cnt >=len) break;
2268next_line:
2269        j = 0;
2270    }
2271
2272
2273    cablecard_page.diag_message_filled = i;
2274}
2275
2276int cablecard_get_page(
2277    int app_num
2278    )
2279{
2280    unsigned short length = 0;
2281    char url_query[100];
2282    char *url_ptr;
2283    uint8_t dialogNb;
2284    uint8_t urlLen;
2285    uint8_t max_num_pages;
2286    MPOD_RET_CODE err;
2287    cablecard_t cablecard = cablecard_get_instance();
2288
2289    err = B_Mpod_AppInfoGetNumApps(&max_num_pages);
2290    if(err || app_num >= max_num_pages ){
2291        BDBG_ERR(("\n!!!!ERROR retrieving application dialogs\n\n"));
2292        return -1;
2293    }
2294
2295    err = B_Mpod_AppInfoGetURL(app_num, &url_ptr, &urlLen);
2296    if (err) return -1;
2297    strcpy(url_query, url_ptr);
2298
2299    length = strlen(url_query);
2300    cablecard_page.diag_message_filled = 0;
2301    cablecard_set_html_callback(cablecard, cablecard_receive_app_info_query);
2302    err = B_Mpod_MMIHostOpenDialog(url_query, length, &dialogNb);
2303
2304    return (err? -1 : 0);
2305}
2306
2307/* poorman's HTML parser*/
2308int cablecard_receive_MMI(
2309    char *mmi_message,
2310    int len
2311    )
2312{
2313    int length;
2314    int i = 30;
2315    int j = 0;
2316    int cnt;
2317    char  *new_mmi_message;
2318
2319    if (len <=0) return -1;
2320    new_mmi_message = (char *)malloc(len);
2321    memset(new_mmi_message, 0, len);
2322    length = len;
2323    for (cnt=0 ; cnt < (length) ; )
2324    {
2325        if (mmi_message[cnt] != '<' && mmi_message[cnt] != '&'
2326        && (mmi_message[cnt] != '\n') && (mmi_message[cnt] != '\0') )
2327        {
2328            new_mmi_message[j++] = mmi_message[cnt++];
2329        }
2330        else if (mmi_message[cnt] == '<')
2331        {
2332            while (mmi_message[cnt] != '>')
2333            {
2334                cnt++;
2335            }
2336            cnt++;
2337            new_mmi_message[j++] = ' ';
2338        }
2339        else if (mmi_message[cnt] == '&')
2340        {
2341            cnt+=6;
2342        }
2343        else
2344            cnt++;
2345    }
2346
2347    while (i <= j)
2348    {
2349        if (new_mmi_message[i] == ' ')
2350        {
2351            new_mmi_message[i] = '\n';
2352            i+=30;
2353        }
2354        else
2355        {
2356            i+=1;
2357        }
2358    }
2359    new_mmi_message[j+1] = '\0';
2360  free(new_mmi_message);
2361  return 0;
2362}
2363
2364int cablecard_set_html_callback(
2365    cablecard_t cablecard,
2366    cablecard_html_callback callback
2367    )
2368{
2369    if (cablecard == NULL) return -1;
2370    cablecard->html_callback = callback;
2371    return 0;
2372}
2373
2374static void mmiHtmlRdyCb(
2375    uint8_t *html,
2376    uint16_t len,
2377    uint8_t dialogNb,
2378    bool hostDialog,
2379    uint8_t fileStatus
2380    )
2381{
2382    BSTD_UNUSED(fileStatus);
2383    /* add NULL termination */
2384    html[len - 1] = '\0';
2385    BDBG_MSG(("mmiHtmlRdyCb Dialog %d diaglog %d len %d", hostDialog, dialogNb, len));
2386    printf("%s\n",html);
2387}
2388
2389static B_MPOD_MMI_OPEN_STATUS mmiDialogRequestCb(
2390    B_MPOD_MMI_DISPLAY_TYPE displayType,
2391    uint8_t dialogNb
2392    )
2393{
2394    BDBG_MSG(("mmiDialogRequestCb Callback Called with dialog number %d for display type %d\n", dialogNb, displayType));
2395    return B_MPOD_MMI_OK;
2396}
2397
2398static void mmiDialogCloseCb(
2399    uint8_t dialogNb
2400    )
2401{
2402    BDBG_MSG(("mmiDialogCloseCb Callback Called for dialog %d\n", dialogNb));
2403    MARK_AS_INVALID(dialogNb);
2404}
2405
2406static void mmiSessionOpenCb(
2407    uint16_t sessionNb
2408    )
2409{
2410    BSTD_UNUSED(sessionNb);
2411    BDBG_MSG(("mmiSessionOpenCb Callback Called\n"));
2412}
2413
2414static void mmiSessionCloseCb(
2415    uint16_t sessionNb
2416    )
2417{
2418    BSTD_UNUSED(sessionNb);
2419    BDBG_MSG(("mmiSessionCloseCb Callback Called\n"));
2420}
2421
2422static void dlNewCodeVersionTableCb(
2423    uint8_t * data,
2424    uint32_t len,
2425    B_MPOD_DL_CVT_HOST_RESPONSE *cvtResponse
2426    )
2427{
2428    #ifdef CDL_SUPPORT
2429        *cvtResponse = (B_MPOD_DL_CVT_HOST_RESPONSE)cdl_adpu_cvt_process(NULL, data, len);
2430    #else
2431        BSTD_UNUSED(data);
2432        BSTD_UNUSED(len);
2433   
2434        printf("MPOD_TEST-DL: Got new code version table callback");
2435        *cvtResponse = B_MPOD_DL_ACT_NO_ERROR;
2436    #endif
2437}
2438
2439uint8_t descriptorBlock[] =
2440/* tag length                      data                       */
2441{
2442    0,  12,      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,
2443    1,  11,     12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
2444    2,  10,     23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
2445    3,   9,     33, 34, 35, 36, 37, 38, 39, 40, 41,
2446    4,   8,     42, 43, 44, 45, 46, 47, 48, 49,
2447    5,   7,     50, 51, 52, 53, 54, 55, 56,
2448    6,   6,     57, 58, 59, 60, 61, 62,
2449    7,   5,     63, 64, 65, 66, 67,
2450    8,   4,     68, 69, 70, 71,
2451    9,   3,     72, 73, 74,
2452    10,  2,     75, 76,
2453    11,  1,     77
2454};
2455
2456static void dlHostInfoCb(
2457    B_MPOD_DL_SUPPORTED_DL_TYPE supportedDlType,
2458    B_MPOD_DL_HOST_INFO *hostInfo
2459    )
2460{
2461    #ifdef CDL_SUPPORT
2462        cdl_adpu_get_host_info((void*)supportedDlType, hostInfo);
2463    #else
2464        BSTD_UNUSED(supportedDlType);
2465        printf("MPOD_TEST-DL: Got Host Info callback");
2466        hostInfo->vendorId = 0x3a3a3a;
2467        hostInfo->hardwareVersionId = 0x8c8c8c8c;
2468        hostInfo->numDescriptors = 12;
2469        hostInfo->descriptors = descriptorBlock;
2470    #endif
2471}
2472
2473static const B_MPOD_FEATURE_ID TestFeatureList[] =
2474{
2475    B_MPOD_FEATURE_ID_RF_OUTPUT_CHANNEL,
2476    B_MPOD_FEATURE_ID_PARENTIAL_CTL_PIN,
2477    B_MPOD_FEATURE_ID_PARENTIAL_CTL_SETTING,
2478    B_MPOD_FEATURE_ID_IPPV_PIN,
2479    B_MPOD_FEATURE_ID_TIME_ZONE,
2480    B_MPOD_FEATURE_ID_DAYLIGHT_SAVING,
2481    B_MPOD_FEATURE_ID_AC_OUTLET,
2482    B_MPOD_FEATURE_ID_LANGUAGE,
2483    B_MPOD_FEATURE_ID_RATING_REGION,
2484    B_MPOD_FEATURE_ID_RESET_PINS,
2485    B_MPOD_FEATURE_ID_CABLE_URL,
2486    B_MPOD_FEATURE_ID_EAS_LOCATION_CODE,
2487    B_MPOD_FEATURE_ID_VCT_ID,
2488    B_MPOD_FEATURE_ID_TURN_ON_CHANNEL,
2489    B_MPOD_FEATURE_ID_TERMINAL_ASSOC,
2490    B_MPOD_FEATURE_ID_DOWNLOAD_GRP_ID,
2491    B_MPOD_FEATURE_ID_ZIP_CODE
2492};
2493
2494static void featureReqHostListCb(
2495    B_MPOD_FEATURE_ID *hostFeatures,
2496    uint8_t *hostNumFeatures
2497    )
2498{
2499    *hostNumFeatures = sizeof(TestFeatureList)/sizeof(TestFeatureList[0]);
2500    BKNI_Memcpy(hostFeatures, TestFeatureList, sizeof(TestFeatureList));
2501}
2502
2503static B_MPOD_FEATURE_PARAM TestParams[B_MPOD_FEATURE_ID_MAX]; /* adjust for 0 based below */
2504static B_MPOD_FEATURE_PARAM *RfOutput          = &TestParams[B_MPOD_FEATURE_ID_RF_OUTPUT_CHANNEL-1];
2505static B_MPOD_FEATURE_PARAM *ParentalPin       = &TestParams[B_MPOD_FEATURE_ID_PARENTIAL_CTL_PIN-1];
2506static B_MPOD_FEATURE_PARAM *ParentalSettings  = &TestParams[B_MPOD_FEATURE_ID_PARENTIAL_CTL_SETTING-1];
2507static B_MPOD_FEATURE_PARAM *PurchasePin       = &TestParams[B_MPOD_FEATURE_ID_IPPV_PIN-1];
2508static B_MPOD_FEATURE_PARAM *TimeZone          = &TestParams[B_MPOD_FEATURE_ID_TIME_ZONE-1];
2509static B_MPOD_FEATURE_PARAM *DaylightSavings   = &TestParams[B_MPOD_FEATURE_ID_DAYLIGHT_SAVING-1];
2510static B_MPOD_FEATURE_PARAM *AcOutlet          = &TestParams[B_MPOD_FEATURE_ID_AC_OUTLET-1];
2511static B_MPOD_FEATURE_PARAM *Language          = &TestParams[B_MPOD_FEATURE_ID_LANGUAGE-1];
2512static B_MPOD_FEATURE_PARAM *RatingRegion      = &TestParams[B_MPOD_FEATURE_ID_RATING_REGION-1];
2513static B_MPOD_FEATURE_PARAM *ResetPin          = &TestParams[B_MPOD_FEATURE_ID_RESET_PINS-1];
2514static B_MPOD_FEATURE_PARAM *CableUrls         = &TestParams[B_MPOD_FEATURE_ID_CABLE_URL-1];
2515static B_MPOD_FEATURE_PARAM *EmergencyAlertLoc = &TestParams[B_MPOD_FEATURE_ID_EAS_LOCATION_CODE-1];
2516static B_MPOD_FEATURE_PARAM *VirtualChannel    = &TestParams[B_MPOD_FEATURE_ID_VCT_ID-1];
2517static B_MPOD_FEATURE_PARAM *TurnOnChan        = &TestParams[B_MPOD_FEATURE_ID_TURN_ON_CHANNEL-1];
2518static B_MPOD_FEATURE_PARAM *TerminalAssoc     = &TestParams[B_MPOD_FEATURE_ID_TERMINAL_ASSOC-1];
2519static B_MPOD_FEATURE_PARAM *CommonDownload    = &TestParams[B_MPOD_FEATURE_ID_DOWNLOAD_GRP_ID-1];
2520static B_MPOD_FEATURE_PARAM *ZipCode           = &TestParams[B_MPOD_FEATURE_ID_ZIP_CODE-1];
2521
2522static B_MPOD_FEATURE_VIRTUAL_CHANNEL VirtualChannels[10];
2523static B_MPOD_FEATURE_CABLE_URL Urls[3];
2524
2525static void featureReqParamsCb(
2526    B_MPOD_FEATURE_PARAM **featParams,
2527    uint8_t *numFeatures
2528    )
2529{
2530    uint32_t i;
2531#ifdef ESTB_CFG_SUPPORT
2532    int len;
2533#endif
2534    *featParams = TestParams;
2535    *numFeatures = 17;
2536
2537    /* set up the ID's */
2538    for (i = 0; i < (int)B_MPOD_FEATURE_ID_MAX; i++) TestParams[i].feature = (B_MPOD_FEATURE_ID)(i+1);
2539    RfOutput->param.rfOutput.channel = 0x3;
2540    RfOutput->param.rfOutput.channelUi = B_MPOD_FEATURE_ENABLE_RF_CH_UI;
2541
2542    ParentalPin->param.parentalPin.chr = "09080706";
2543    ParentalPin->param.parentalPin.length = 8;
2544
2545    ParentalSettings->param.parentalSettings.factoryReset = 0;
2546    ParentalSettings->param.parentalSettings.chanCount = 10;
2547    ParentalSettings->param.parentalSettings.virtualChannels = VirtualChannels;
2548
2549    for (i = 0; i < ParentalSettings->param.parentalSettings.chanCount; i++)
2550    {
2551        ParentalSettings->param.parentalSettings.virtualChannels[i].channelMajorMinor[2] = i;
2552        ParentalSettings->param.parentalSettings.virtualChannels[i].channelMajorMinor[1] = i * 5;
2553        ParentalSettings->param.parentalSettings.virtualChannels[i].channelMajorMinor[0] = i * 10;
2554    }
2555
2556    PurchasePin->param.purchasePin.chr = "0504030";
2557    PurchasePin->param.purchasePin.length = 7;
2558
2559    TimeZone->param.timeZone.offset = 27;
2560
2561    DaylightSavings->param.daylightSavings.ctrl = B_MPOD_FEATURE_USE_DST; /* use daylight savings */
2562    DaylightSavings->param.daylightSavings.delta = 128;
2563    DaylightSavings->param.daylightSavings.entry = 0xffff0000;
2564    DaylightSavings->param.daylightSavings.exit =0x0000ffff;
2565
2566    AcOutlet->param.acOutlet.ctrl = B_MPOD_FEATURE_AC_USER_SETTING;
2567
2568#ifdef ESTB_CFG_SUPPORT
2569    B_Estb_cfg_Get_bin("/dyn/estb/lang_code", Language->param.language.ctrl, &len );
2570#else
2571    Language->param.language.ctrl[0] = 'e';
2572    Language->param.language.ctrl[1] = 'n';
2573    Language->param.language.ctrl[2] = 'g';
2574#endif
2575
2576    RatingRegion->param.ratingRegion.region = B_MPOD_FEATURE_REGION_US;
2577
2578    ResetPin->param.resetPin.ctrl = B_MPOD_FEATURE_RESET_P_C_PURCHASED_PINS;
2579
2580    CableUrls->param.cableUrls.numberOfUrls = 3;
2581    CableUrls->param.cableUrls.urls = Urls;
2582
2583    CableUrls->param.cableUrls.urls[0].length = 23;
2584    CableUrls->param.cableUrls.urls[0].type = B_MPOD_FEATURE_WEB_PORTAL; /* Web Portal URL */
2585    CableUrls->param.cableUrls.urls[0].url = "http://www.broadcom.com";
2586
2587    CableUrls->param.cableUrls.urls[1].length = 24;
2588    CableUrls->param.cableUrls.urls[1].type = B_MPOD_FEATURE_EPG; /* EPG URL */
2589    CableUrls->param.cableUrls.urls[1].url = "http://epg.broadcomm.com";
2590
2591    CableUrls->param.cableUrls.urls[2].length = 25;
2592    CableUrls->param.cableUrls.urls[2].type = B_MPOD_FEATURE_VOD; /* VOD URL */
2593    CableUrls->param.cableUrls.urls[2].url = "http://vod.broadcommm.com";
2594
2595    EmergencyAlertLoc->param.emergencyAlertLoc.stateCode = 101;
2596    EmergencyAlertLoc->param.emergencyAlertLoc.countySubdivision = 102;
2597    EmergencyAlertLoc->param.emergencyAlertLoc.countyCode = 103;
2598
2599    VirtualChannel->param.virtualChannel.vctId = 234;
2600
2601    TurnOnChan->param.turnOnChan.virtualChannel = 88;
2602    TurnOnChan->param.turnOnChan.defined  = 1;
2603
2604    TerminalAssoc->param.terminalAssoc.length = 19;
2605    TerminalAssoc->param.terminalAssoc.identifier = "This Is My Terminal";
2606
2607#ifdef ESTB_CFG_SUPPORT
2608    {
2609        unsigned int group_id = 0;
2610        B_Estb_cfg_Get_uint32("/dyn/estb/group_id", &group_id);
2611        CommonDownload->param.commonDownload.groupId = group_id;
2612    }
2613#else
2614    CommonDownload->param.commonDownload.groupId = 56;
2615#endif
2616
2617    ZipCode->param.zipCode.chr = "95118-9446";
2618    ZipCode->param.zipCode.length = 10;
2619}
2620
2621static const char *FeatureString[] =
2622{
2623    "dummy", /* features are 1-based */
2624    "rf_output_channel",
2625    "parental_control_pin",
2626    "parental_control_settings",
2627    "purchase_pin",
2628    "time_zone",
2629    "daylight_savings",
2630    "ac_outlet",
2631    "language",
2632    "rating_region",
2633    "reset_pin",
2634    "cable_URLs",
2635    "EAS_location_code",
2636    "VCT_ID",
2637    "turn_on_channel",
2638    "terminal_association",
2639    "download_group_id",
2640    "zip_code"
2641};
2642
2643static void featureRcvCardListCb(
2644    B_MPOD_FEATURE_ID *cardFeatures,
2645    uint8_t cardNumFeatures
2646    )
2647{
2648    uint32_t i;
2649
2650    printf("%s list of Card supported features\n\n", __FUNCTION__);
2651    printf("%d\n", cardNumFeatures);
2652    for(i = 0; i < cardNumFeatures; i++) printf("Feature %d = %s\n", i, FeatureString[cardFeatures[i]]);
2653    printf("\n\n\n");
2654}
2655
2656static void featureRcvParamsCb(
2657    B_MPOD_FEATURE_PARAM *featureParams,
2658    uint8_t numFeatures
2659    )
2660{
2661    uint32_t i, j;
2662#ifdef ESTB_CFG_SUPPORT
2663    unsigned int group_id;
2664#endif
2665
2666    printf("Received the following feature params from the CableCard\n\n");
2667
2668    for(i = 0; i < numFeatures; i++)
2669    {
2670        switch(featureParams[i].feature)
2671        {
2672            case B_MPOD_FEATURE_ID_RF_OUTPUT_CHANNEL:
2673                printf("RF_OUTPUT_CHANNEL\n\n");
2674                printf("Channel = %d, Channel UI is %s\n",
2675                featureParams[i].param.rfOutput.channel,
2676                (featureParams[i].param.rfOutput.channelUi) == 0x1 ? "enabled" : "disabled");
2677            break;
2678
2679            case B_MPOD_FEATURE_ID_PARENTIAL_CTL_PIN:
2680                printf("PARENTIAL_CTL_PIN\n\n");
2681                featureParams[i].param.parentalPin.chr[featureParams[i].param.parentalPin.length + 1] = '\0';
2682                printf("Pin is %s\n", featureParams[i].param.parentalPin.chr);
2683            break;
2684
2685            case B_MPOD_FEATURE_ID_PARENTIAL_CTL_SETTING:
2686                printf("PARENTIAL_CTL_SETTING\n\n");
2687                printf("%s Factory Reset, Channel Count = %d\n",
2688                (featureParams[i].param.parentalSettings.factoryReset == 0xa7) ? "Perform" : "Don't Perform",
2689                featureParams[i].param.parentalSettings.chanCount);
2690                for(j = 0; j < featureParams[i].param.parentalSettings.chanCount; j++)
2691                {
2692                    uint16_t major, minor;
2693
2694                    major = ((featureParams[i].param.parentalSettings.virtualChannels[j].channelMajorMinor[0] & 0xf) << 6) |
2695                            ((featureParams[i].param.parentalSettings.virtualChannels[j].channelMajorMinor[1] & 0xfc) >> 2);
2696                    minor = ((featureParams[i].param.parentalSettings.virtualChannels[j].channelMajorMinor[1] & 0x3) << 8) |
2697                            featureParams[i].param.parentalSettings.virtualChannels[j].channelMajorMinor[2];
2698
2699                    printf("Virtual Channel %d %d included\n", major, minor);
2700                }
2701            break;
2702
2703            case B_MPOD_FEATURE_ID_IPPV_PIN:
2704                printf("IPPV_PIN\n\n");
2705                featureParams[i].param.purchasePin.chr[featureParams[i].param.purchasePin.length + 1] = '\0';
2706                printf("Pin is %s\n", featureParams[i].param.purchasePin.chr);
2707            break;
2708
2709            case B_MPOD_FEATURE_ID_TIME_ZONE:
2710                printf("TIME_ZONE\n\n");
2711                printf("Time Zone Offset = %d\n", featureParams[i].param.timeZone.offset);
2712                info.timezoneOffset = featureParams[i].param.timeZone.offset;
2713            break;
2714
2715            case B_MPOD_FEATURE_ID_DAYLIGHT_SAVING:
2716                printf("DAYLIGHT_SAVING\n\n");
2717                printf("%s use Daylight Savings\n",
2718                    (featureParams[i].param.daylightSavings.ctrl == B_MPOD_FEATURE_USE_DST) ? "Do" : "Don't");
2719                if(featureParams[i].param.daylightSavings.ctrl == B_MPOD_FEATURE_USE_DST)
2720                {
2721                    printf("Delta = %d, Entry = %d, Exit = %d\n",
2722                    featureParams[i].param.daylightSavings.delta,
2723                    featureParams[i].param.daylightSavings.entry,
2724                    featureParams[i].param.daylightSavings.exit);
2725                    info.DSTimeDelta = featureParams[i].param.daylightSavings.delta;
2726                    info.DSTimeEntry = featureParams[i].param.daylightSavings.entry;
2727                    info.DSTimeExit = featureParams[i].param.daylightSavings.exit;
2728                }
2729            break;
2730
2731            case B_MPOD_FEATURE_ID_AC_OUTLET:
2732            {
2733                char *ACOutletStrings[] = {"Use User Setting",
2734                                           "Switched AC Outlet",
2735                                           "Unswitched AC Outlet",
2736                                           "Reserved"};
2737                printf("AC_OUTLET\n\n");
2738                printf("AC Outlet setting %s\n", ACOutletStrings[featureParams[i].param.acOutlet.ctrl & 0x3]);
2739            }
2740            break;
2741
2742            case B_MPOD_FEATURE_ID_LANGUAGE:
2743                printf("LANGUAGE\n\n");
2744                printf("Language code is %d %d %d\n",
2745                featureParams[i].param.language.ctrl[0],
2746                featureParams[i].param.language.ctrl[1],
2747                featureParams[i].param.language.ctrl[2]);
2748            break;
2749
2750            case B_MPOD_FEATURE_ID_RATING_REGION:
2751                printf("RATING_REGION\n\n");
2752                printf("Rating Region is %d\n",
2753                featureParams[i].param.ratingRegion.region);
2754            break;
2755
2756            case B_MPOD_FEATURE_ID_RESET_PINS:
2757            {
2758                char * resetPinsString[] = {"Don't reset any pin",
2759                                            "Reset parental control pin",
2760                                            "Reset purchase pin",
2761                                            "Reset parental control and purchase pin"};
2762                printf("RESET_PINS\n\n");
2763                printf("Reset Pin Setting is %s\n",
2764                resetPinsString[featureParams[i].param.resetPin.ctrl & 0x3]);
2765            }
2766            break;
2767
2768            case B_MPOD_FEATURE_ID_CABLE_URL:
2769            {
2770                printf("CABLE_URL\n\n");
2771
2772                /* populate the array with type, length and the pointer to the url */
2773                for (j = 0; j < featureParams[i].param.cableUrls.numberOfUrls; j++)
2774                {
2775                    char *urlTypeString[] = {"undefined", "Web Portal URL", "EPG URL", "VOD URL"};
2776
2777                    featureParams[i].param.cableUrls.urls[j].url[featureParams[i].param.cableUrls.urls[j].length + 1] = '\0';
2778
2779                    printf("Type %s, URL = %s\n",
2780                    urlTypeString[featureParams[i].param.cableUrls.urls[j].type & 0x3],
2781                    featureParams[i].param.cableUrls.urls[j].url);
2782                }
2783            }
2784            break;
2785
2786            case B_MPOD_FEATURE_ID_EAS_LOCATION_CODE:
2787                printf("EAS_LOCATION_CODE\n\n");
2788                printf("State Code = %d, County Subdvsn = %d, County Code = %d\n",
2789                featureParams[i].param.emergencyAlertLoc.stateCode,
2790                featureParams[i].param.emergencyAlertLoc.countySubdivision,
2791                featureParams[i].param.emergencyAlertLoc.countyCode);
2792                info.EALocCode[0] = featureParams[i].param.emergencyAlertLoc.stateCode;
2793                info.EALocCode[1] = (featureParams[i].param.emergencyAlertLoc.countySubdivision<<4)
2794                                    |(featureParams[i].param.emergencyAlertLoc.countyCode>>8);
2795                info.EALocCode[2] = featureParams[i].param.emergencyAlertLoc.countyCode&0xff;
2796            break;
2797
2798            case B_MPOD_FEATURE_ID_VCT_ID:
2799                printf("VCT_ID\n\n");
2800                printf("Virtual Channel ID = %d\n",
2801                    featureParams[i].param.virtualChannel.vctId);
2802                info.vctId = featureParams[i].param.virtualChannel.vctId;
2803            break;
2804
2805            case B_MPOD_FEATURE_ID_TURN_ON_CHANNEL:
2806                printf("TURN_ON_CHANNEL\n\n");
2807                printf("Turn-On Channel %d is %s\n", featureParams[i].param.turnOnChan.virtualChannel,
2808                featureParams[i].param.turnOnChan.defined ? "defined" : "not defined");
2809            break;
2810
2811            case B_MPOD_FEATURE_ID_TERMINAL_ASSOC:
2812                printf("TERMINAL_ASSOCIATION\n\n");
2813                featureParams[i].param.terminalAssoc.identifier[featureParams[i].param.terminalAssoc.length + 1] = '\0';
2814                printf("Terminal Association ID = %s\n", featureParams[i].param.terminalAssoc.identifier);
2815            break;
2816
2817            case B_MPOD_FEATURE_ID_DOWNLOAD_GRP_ID:
2818                printf("DOWNLOAD_GROUP_ID\n\n");
2819                printf("Download Group ID is %d\n", featureParams[i].param.commonDownload.groupId);
2820#ifdef ESTB_CFG_SUPPORT
2821                group_id = featureParams[i].param.commonDownload.groupId;
2822                B_Estb_cfg_Set_uint32("/dyn/estb/group_id", group_id);
2823#endif
2824            break;
2825
2826            case B_MPOD_FEATURE_ID_ZIP_CODE:
2827                printf("ZIP_CODE\n\n");
2828                featureParams[i].param.zipCode.chr[featureParams[i].param.zipCode.length + 1] = '\0';
2829                printf("Zip Code is %s\n", featureParams[i].param.zipCode.chr);
2830            break;
2831
2832            default:
2833                printf("ERROR: Invalid feature selected \n\n");
2834            break;
2835        }
2836
2837        featureParams[i].featureStatus = 0; /* feature param accepted */
2838
2839        printf("\n\n\n");
2840
2841    }
2842}
2843
2844static void featureParamDeniedCb(
2845    B_MPOD_FEATURE_ID feature,
2846    B_MPOD_FEATURE_STATUS status
2847    )
2848{
2849    BSTD_UNUSED(feature);
2850    BSTD_UNUSED(status);
2851
2852    printf("Param %s denied with status %d",FeatureString[feature], status );
2853}
2854
2855static B_MPOD_HC_IB_TUNE_STATUS inbandTuneCb(
2856    uint32_t freqHz,
2857    B_MPOD_HC_IB_MOD_TYPE modulation,
2858    uint8_t *ltsid
2859    )
2860{
2861    BSTD_UNUSED(freqHz);
2862    BSTD_UNUSED(modulation);
2863    BSTD_UNUSED(ltsid);
2864
2865    return B_MPOD_HC_IB_TUNE_ACCEPTED;
2866}
2867
2868static B_MPOD_HC_OOB_TX_TUNE_STATUS oobTxTuneCb(
2869    uint32_t freqHz,
2870    uint32_t powerLevel,
2871    uint32_t rate
2872    )
2873{
2874#if 1/*!(VMS93380_SUPPORT || SMS93380_SUPPORT)*/
2875    NEXUS_FrontendUpstreamSettings setting;
2876    NEXUS_Error rc;
2877    NEXUS_PlatformConfiguration platformConfig;
2878    cablecard_t cablecard = cablecard_get_instance();
2879
2880    NEXUS_Frontend_GetDefaultUpstreamSettings(&setting);
2881    setting.frequency = freqHz;
2882    setting.mode = (freqHz==0|| rate==0) ? NEXUS_FrontendUpstreamMode_eDocsis : cablecard->us_mode;
2883    setting.powerLevel = powerLevel*50; /* in hundredth of dBmV*/
2884    setting.symbolRate = rate;
2885
2886    BDBG_MSG(("Freq: %dHz  PowerLevel: %d.%ddBmV  Rate: %dbaud\n",
2887            freqHz, powerLevel >> 1, (powerLevel & 0x1) ? 5 : 0, rate));
2888
2889    NEXUS_Platform_GetConfiguration(&platformConfig);
2890    rc = NEXUS_Frontend_TuneUpstream(platformConfig.frontend[MAX_TUNER], &setting);
2891
2892    return (rc)?  B_MPOD_HC_OOB_TX_OTHER_ERROR : B_MPOD_HC_OOB_TX_TUNE_GRANTED ;
2893#else
2894    BSTD_UNUSED(freqHz);
2895    BSTD_UNUSED(powerLevel);
2896    BSTD_UNUSED(rate);
2897   
2898    /* still waiting for OOB US support */
2899    BKNI_Sleep(500);
2900    return B_MPOD_HC_OOB_TX_TUNE_GRANTED ;
2901#endif
2902}
2903
2904/* switch frontend OOB TX mode to Docsis UPstream mode*/
2905static void OOB_Tx_Docsis(
2906    void
2907    )
2908{
2909    oobTxTuneCb(0, 0, 0);
2910}
2911
2912static B_MPOD_HC_OOB_RX_TUNE_STATUS oobRxTuneCb(
2913    uint32_t freqHz,
2914    uint32_t rate,
2915    bool spectralInv
2916    )
2917{
2918    int  rc;
2919    NEXUS_PlatformConfiguration platformConfig;
2920    NEXUS_FrontendOutOfBandSettings oobSettings;
2921    cablecard_t cablecard = cablecard_get_instance();
2922
2923    if (rate == 1024000)
2924    {
2925        cablecard->us_mode = NEXUS_FrontendUpstreamMode_ePodDvs178;
2926        cablecard->oob_mode = NEXUS_FrontendOutOfBandMode_ePod_Dvs178Qpsk;
2927        BDBG_MSG(("Set to DVS178 OOB mode"));
2928    } else if (rate == 1544000/2 || rate == 3088000/2)
2929    {
2930        cablecard->us_mode = NEXUS_FrontendUpstreamMode_ePodDvs167;
2931        cablecard->oob_mode = NEXUS_FrontendOutOfBandMode_ePod_Dvs167Qpsk;
2932        BDBG_MSG(("Set to DVS167 OOB mode"));
2933    } else
2934        BDBG_WRN((" wrong OOB symbolrate!"));
2935
2936    BDBG_MSG(("Freq: %dHz  Rate: %dbps  Spectral Inversion: %s\n",
2937            freqHz, rate, spectralInv ? "true" : "false"));
2938    NEXUS_Platform_GetConfiguration(&platformConfig);
2939
2940    NEXUS_Frontend_GetDefaultOutOfBandSettings(&oobSettings);
2941    oobSettings.mode = cablecard->oob_mode;
2942    oobSettings.frequency = freqHz;
2943    oobSettings.spectrum =  (spectralInv) ?
2944        NEXUS_FrontendOutOfBandSpectrum_eInverted : NEXUS_FrontendOutOfBandSpectrum_eNonInverted;
2945    oobSettings.symbolRate = rate;
2946    oobSettings.lockCallback.callback = default_lock_callback;
2947    oobSettings.lockCallback.context = platformConfig.frontend[MAX_TUNER];
2948
2949    rc = NEXUS_Frontend_TuneOutOfBand(platformConfig.frontend[MAX_TUNER], &oobSettings);
2950    NEXUS_StartCallbacks(platformConfig.frontend[MAX_TUNER]);
2951
2952        BKNI_Sleep(500);
2953    return (rc) ?  B_MPOD_HC_OOB_RX_OTHER_ERROR : B_MPOD_HC_OOB_RX_TUNE_GRANTED ;
2954}
2955
2956static void sourceIdToFreqCb(
2957    uint16_t sourceId,
2958    uint32_t *freqHz,
2959    B_MPOD_HC_IB_MOD_TYPE *modulation
2960    )
2961{
2962    BSTD_UNUSED(sourceId);
2963    BSTD_UNUSED(freqHz);
2964    BSTD_UNUSED(modulation);
2965}
2966
2967static void delayedDownloadReqCb(
2968    void
2969    )
2970{
2971    printf("received %s\n", __FUNCTION__);
2972}
2973
2974static void homingCompleteCb(
2975    void
2976    )
2977{
2978    printf("received %s\n", __FUNCTION__);
2979}
2980
2981/* the host should NOT interrupt the download */
2982static void downloadStartingCb(
2983    B_MPOD_HOMING_DOWNLOAD_INFO *downloadInfo
2984    )
2985{
2986    char notifyString[257];
2987    char *sourceStrings[] = {"unknown", "QAM Inband", "QPSK OOB", "reserved"};
2988    char *timeoutTypeStrings[] = {"both timeouts", "transport timeout",
2989                                            "download timeout", "no_timeout"};
2990
2991    printf("received %s\n", __FUNCTION__);
2992
2993    if(downloadInfo->notifyTextLength)
2994    {
2995        strncpy(notifyString, downloadInfo->notifyText, downloadInfo->notifyTextLength);
2996        notifyString[downloadInfo->notifyTextLength] = '\0';
2997        printf("Notify Message: %s\n", notifyString);
2998    }
2999
3000    printf("Upgrade Source: %s,  Download Time %d\n",
3001            sourceStrings[downloadInfo->source & 0x3],
3002            downloadInfo->downloadTime);
3003
3004    printf("Timeout Type: %s,  Timeout Period: %d\n",
3005            timeoutTypeStrings[downloadInfo->timeoutType & 0x3],
3006            downloadInfo->downloadTimeoutPeriod);
3007}
3008
3009static void downloadCompleteCb(
3010    B_MPOD_HOMING_UPGRADE_RESET_REQUEST resetType
3011    )
3012{
3013    char *resetTypeStrings[] = {"PCMCIA Reset", "Card Reset", "No Reset", "Reserved"};
3014
3015    printf("received %s\n", __FUNCTION__);
3016    printf("requested %s\n", resetTypeStrings[resetType & 0x3]);
3017}
3018
3019static void homingTimeoutCb(
3020    void
3021    )
3022{
3023    printf("received %s\n", __FUNCTION__);
3024    printf("Resetting CableCard\n");
3025}
3026
3027/* tells the app that the requested connection for privateAppId has been established */
3028static void sasConnectCnfCallback(
3029    uint8_t *privateAppId,
3030    B_MPOD_SAS_HANDLE newSasConnection
3031    )
3032{
3033    int i;
3034
3035    for(i = 0; i < 32; i++)
3036    {
3037        if(SasConnections[i] == 0)
3038        {
3039            SasConnections[i] = newSasConnection;
3040            printf("SAS connection %d assigned for priv SAS app id %02x %02x %02x %02x %02x %02x %02x %02x\n",
3041                    i, privateAppId[0], privateAppId[1], privateAppId[2], privateAppId[3],
3042                    privateAppId[4], privateAppId[5], privateAppId[6], privateAppId[7]);
3043            return;
3044        }
3045    }
3046
3047    printf("Unable to open new SAS Connection. Connection limit has been reached\n");
3048}
3049
3050/* tells the app that the card is ready for syncrhonous communication for this privateAppId */
3051static void sasConnectionRdyCallback(
3052    B_MPOD_SAS_HANDLE sasConnection,
3053    uint8_t *privateAppId
3054    )
3055{
3056
3057    printf("Recieved connection rdy for connection %p assigned for priv SAS app id %02x %02x %02x %02x %02x %02x %02x %02x\n",
3058        (void *)sasConnection, privateAppId[0], privateAppId[1], privateAppId[2], privateAppId[3],
3059        privateAppId[4], privateAppId[5], privateAppId[6], privateAppId[7]
3060    );
3061}
3062
3063/* delivers data to the application from the card */
3064static void sasSynchDataRcvCallback(
3065    B_MPOD_SAS_HANDLE sasConnection,
3066    uint8_t *privateAppId,
3067    uint8_t *msg,
3068    uint32_t len
3069    )
3070{
3071    uint32_t i = 0;
3072    BSTD_UNUSED(sasConnection);
3073
3074    printf("Received new data through synchronous transmission from private app %02x %02x %02x %02x %02x %02x %02x %02x\n",
3075        privateAppId[0], privateAppId[1], privateAppId[2], privateAppId[3],
3076        privateAppId[4], privateAppId[5], privateAppId[6], privateAppId[7]
3077    );
3078
3079    printf("msg: \n");
3080    while(len--) printf("%x ", msg[i++]);
3081    printf("\n");
3082}
3083
3084/* delivers data to the application from the card */
3085static void sasAsynchDataRcvCallback(
3086    B_MPOD_SAS_HANDLE sasConnection,
3087    uint8_t *privateAppId,
3088    uint8_t *msg,
3089    uint32_t len)
3090{
3091    uint32_t i = 0;
3092    BSTD_UNUSED(sasConnection);
3093
3094    printf("Received new data through asynchronous transmission from private app %02x %02x %02x %02x %02x %02x %02x %02x\n",
3095        privateAppId[0], privateAppId[1], privateAppId[2], privateAppId[3],
3096        privateAppId[4], privateAppId[5], privateAppId[6], privateAppId[7]
3097    );
3098
3099    printf("msg: \n");
3100    while(len--) printf("%x ", msg[i++]);
3101    printf("\n");
3102
3103}
3104
3105/* retrieves data from the app to be sent to the card (app previously requested a syncrhonous transfer of data) */
3106static void sasGetSynchDataCallback(
3107    B_MPOD_SAS_HANDLE sasConnection,
3108    uint8_t *privateAppId,
3109    uint8_t transactionNb,
3110    uint8_t **sasMsg,
3111    uint32_t *sasLen
3112    )
3113{
3114    BSTD_UNUSED(sasConnection);
3115   
3116    printf("Received request for data for transaction number %d for private app %02x %02x %02x %02x %02x %02x %02x %02x\n",
3117        transactionNb, privateAppId[0], privateAppId[1], privateAppId[2], privateAppId[3],
3118        privateAppId[4], privateAppId[5], privateAppId[6], privateAppId[7]
3119    );
3120
3121    /* Preliminary handshake is over, allow the data to be transmitted */
3122    *sasMsg = SasData;
3123    *sasLen = 8;
3124}
3125
3126/* tells the app that the card has closed the connection for privateAppId */
3127static void sasConnectionClosedCallback(
3128    B_MPOD_SAS_HANDLE sasConnection,
3129    uint8_t *privateAppId
3130    )
3131{
3132    int i;
3133
3134    for(i = 0; i < 32; i++)
3135    {
3136        if(SasConnections[i] == sasConnection)
3137        {
3138            SasConnections[i] = 0;
3139            printf("Closing SAS connection %p assigned for priv SAS app id %02x %02x %02x %02x %02x %02x %02x %02x\n",
3140                    (void *)sasConnection, privateAppId[0], privateAppId[1], privateAppId[2], privateAppId[3],
3141                    privateAppId[4], privateAppId[5], privateAppId[6], privateAppId[7]
3142            );
3143            return;
3144        }
3145    }
3146
3147    printf("Unable to close SAS Connection. Connection not found\n");
3148}
3149
3150void diagReqCb(
3151    uint8_t numDiags,
3152    B_MPOD_DIAG_DATA *diagReqests
3153    )
3154{
3155    uint8_t i;
3156
3157    for(i = 0; i < numDiags; i++)
3158    {
3159        BDBG_MSG((" NUM: %d  Diag_id %d", i, diagReqests[i].id));
3160        diagReqests[i].status = B_MPOD_DIAG_DENIED_OTHER;
3161    }
3162}
3163
3164void caInfoCb(
3165    uint16_t *caSystemId,
3166    uint32_t numSystemId
3167    )
3168{
3169    uint32_t i;
3170    for(i = 0; i < numSystemId; i++)
3171        printf("CA System Id [%d]: %x\n", i, caSystemId[i]);
3172    if (numSystemId) info.CAId = caSystemId[0];
3173    info.CPId = CP_SYSTEM2_ID;
3174}
3175
3176void caPmtUpdateReply(
3177    B_MPOD_CA_PMT_UPDATE_INFO *replyInfo
3178    )
3179{
3180    uint32_t i;
3181    uint16_t pid;
3182    bool caEnableFlag;
3183    int caEnable;
3184
3185    printf("\nProg Idx: %d  Prog Num: %d, Src Id: %d\n",
3186            replyInfo->progIndex, replyInfo->progNum, replyInfo->srcId);
3187    printf("Trans Id: %d  LTSID: %d\n", replyInfo->transId, replyInfo->ltsid);
3188    if(replyInfo->caEnaFlag)
3189        printf("Program Level CA Enable: %d\n", replyInfo->caEna);
3190    else
3191        printf("No Program Level CA Enable\n");
3192
3193    for(i = 0; i < replyInfo->numElem; i++)
3194    {
3195        B_MPOD_CA_GET_PMT_ES_INFO(replyInfo->esInfo, i, pid, caEnableFlag, caEnable);
3196        if(caEnableFlag)
3197            printf("Es Level CA Enable:  pid:%02x  CA Enable:%d\n", pid, (uint8_t)caEnable);
3198        else
3199            printf("No Es Level CA Enable for pid %02x", pid);
3200    }
3201
3202}
3203
3204void caPmtUpdate(
3205    B_MPOD_CA_PMT_UPDATE_INFO *updateInfo
3206    )
3207{
3208    printf("%s\n", __FUNCTION__);
3209    caPmtUpdateReply(updateInfo);
3210}
3211
3212void caPmtReply(
3213    B_MPOD_CA_PMT_REPLY_INFO *replyInfo
3214    )
3215{
3216    printf("%s\n", __FUNCTION__);
3217    caPmtUpdateReply(replyInfo);
3218}
3219
3220void getAuthKeyCb(
3221    uint8_t *authKey,
3222    bool *authKeyExists
3223    )
3224{
3225    unsigned char hostId[5];
3226    B_Mpod_TestCpGetAuthKey(authKey, authKeyExists);
3227    info.authKeyStatus = true;
3228
3229    if (*authKeyExists)
3230    {
3231        B_Mpod_TestCpGetID(hostId, info.cardId);
3232        BDBG_MSG((" Get host ID and card ID"));
3233    }
3234}
3235
3236void cardAuthMsgCb(
3237    uint8_t *cardDevCert,
3238    uint8_t *cardManCert,
3239    uint8_t *dhPubKeyC,
3240    uint8_t *signC,
3241    uint8_t *hostDevCert,
3242    uint8_t *hostManCert,
3243    uint8_t *dhPubKeyH,
3244    uint8_t *signH
3245    )
3246{
3247    int ret;
3248    printf("Getting Host CP Authentication Parameters\n");
3249    B_Mpod_TestCpGetHostAuthParams(hostDevCert, hostManCert, dhPubKeyH, signH);
3250    printf("Checking Card CP Authorization, generating AuthKey\n");
3251    ret = B_Mpod_TestCpGenAuthKeyH(cardDevCert, cardManCert, dhPubKeyC, signC);
3252    if (ret&cablecard_cardcert_error)
3253    {
3254        info.certCheck = true;
3255        BDBG_ERR((" card certificate error"));
3256    }
3257    if (ret&cablecard_hostId_error)
3258    {
3259        BDBG_ERR((" HOST ID error"));
3260    }
3261    if (ret&cablecard_cardId_error)
3262    {
3263        BDBG_ERR((" card ID error"));
3264    }
3265}
3266
3267void getNonceCb(
3268    uint8_t *nonce
3269    )
3270{
3271    B_Mpod_TestCpGenerateNonce(nonce);
3272}
3273
3274void getIDCb(
3275    uint8_t * hostId,
3276    uint8_t * cardId)
3277{
3278    B_Mpod_TestCpGetID(hostId, cardId);
3279    memcpy(info.cardId, cardId, 8);
3280}
3281
3282void cpkeyGenCb(
3283    uint8_t *nHost,
3284    uint8_t *nCard,
3285    uint8_t *cpKeyA,
3286    uint8_t *cpKeyB
3287    )
3288{
3289    printf("Generating New CPKey");
3290
3291    B_Mpod_TestCpGenCPKey(nHost, nCard, cpKeyA, cpKeyB);
3292    info.CPkeyCount++;
3293}
3294
3295void calcCciAckCb(
3296    uint8_t cpVersion,
3297    uint8_t cci,
3298    uint8_t *cpKeyA,
3299    uint8_t *cpKeyB,
3300    uint8_t *cciNCard,
3301    uint8_t *cciNHost,
3302    uint16_t programNumber,
3303    uint8_t ltsid,
3304    uint16_t ecmpid,
3305    uint8_t *cciAuth,
3306    uint8_t *cciAck
3307    )
3308{
3309    printf("Calculating new CP cci ack value\n");
3310    B_Mpod_TestCpGenCciAck(cpVersion, cci, cpKeyA, cpKeyB, cciNCard,
3311                cciNHost, programNumber, ltsid, ecmpid, cciAuth, cciAck);
3312    info.cciCount++;
3313}
3314
3315void enforceCciCb(
3316    uint8_t cci_data, uint16_t prog_num, uint8_t cci_ltsid
3317    )
3318{
3319    BSTD_UNUSED(cci_data);
3320    BSTD_UNUSED(prog_num);
3321    BSTD_UNUSED(cci_ltsid);
3322
3323}
3324
3325void newValidationStatusCb(
3326    B_MPOD_CP_VALIDATION_STATUS validationStatus
3327    )
3328{
3329
3330    printf("Received new CP validation status from the card, status is %d\n", validationStatus);
3331    info.status = validationStatus;
3332}
3333
3334void resProfileInfoCb(
3335    uint8_t numStreams,
3336    uint8_t numProgs,
3337    uint8_t numEs
3338    )
3339{
3340   printf("%s streams=%d  progs=%d  elem streams=%d\n", __FUNCTION__, numStreams, numProgs, numEs);
3341}
3342
3343static void getRootOID( uint8_t *data, uint32_t len)
3344{
3345    uint32_t i;
3346    printf(" SNMP MIBs root OID\n");
3347    for (i=0;i<len;i++)
3348    {
3349        if (i) printf(".");
3350        printf("%d", data[i]);
3351    }
3352    printf("\n");
3353    if (info.rootoid) free(info.rootoid);
3354    info.rootoid = (char*)malloc(len);
3355    memcpy(info.rootoid, data, len);
3356    info.rootoidLen = len;
3357}
3358
3359static void getSnmpReply( uint8_t *data,    uint32_t len)
3360{
3361    BSTD_UNUSED(data);
3362    BSTD_UNUSED(len);
3363    // will be passed back to SNMP proxy
3364    // by calling MPOD_RET_CODE B_Mpod_SnmpReq(uint8_t *snmpMsg, uint32_t len)
3365
3366}
3367
3368/*****************
3369** Host Properties
3370*****************/
3371static void hostPropertiesReplyCb(
3372    B_MPOD_PROP_HOST_PROPS *hostProperties
3373    )
3374{
3375    int i, j;
3376
3377    printf("%s\n\n", __FUNCTION__);
3378    printf("%d properties sent from the card\n\n", hostProperties->numOfProperties);
3379
3380    for(i = 0; i < hostProperties->numOfProperties; i++)
3381    {
3382        printf("Key: ");
3383        for(j = 0; j < hostProperties->properties[i].keyLength; j++)
3384            printf("%02x ", hostProperties->properties[i].keyByte[j]);
3385
3386        printf("= ");
3387        for(j = 0; j < hostProperties->properties[i].valueLength; j++)
3388            printf("%02x ", hostProperties->properties[i].valueByte[j]);
3389
3390        printf("\n");
3391    }
3392}
3393
3394/**************
3395** Headend Comm
3396**************/
3397static void rcvHostResetVectorCb(
3398    B_MPOD_HEADEND_HOST_RESET_VECTOR *hostResetVector
3399    )
3400{
3401    printf("%s\n\n", __FUNCTION__);
3402
3403    printf("Delay = %d\n", hostResetVector->delay);
3404
3405    printf("resetEcm = %s\n",
3406        B_MPOD_HEADEND_GET_HOST_VEC_RESET_FIELD(hostResetVector, B_MPOD_HEADEND_RESET_ECM) ? "true" : "false");
3407    printf("resetSecurityElem = %s\n",
3408        B_MPOD_HEADEND_GET_HOST_VEC_RESET_FIELD(hostResetVector, B_MPOD_HEADEND_RESET_SECURITY_ELEM) ? "true" : "false");
3409    printf("resetHost = %s\n",
3410        B_MPOD_HEADEND_GET_HOST_VEC_RESET_FIELD(hostResetVector, B_MPOD_HEADEND_RESET_HOST) ? "true" : "false");
3411    printf("resetExternalDevices = %s\n",
3412        B_MPOD_HEADEND_GET_HOST_VEC_RESET_FIELD(hostResetVector, B_MPOD_HEADEND_RESET_EXTERNAL_DEVICES) ? "true" : "false");
3413    printf("resetAll = %s\n",
3414        B_MPOD_HEADEND_GET_HOST_VEC_RESET_FIELD(hostResetVector, B_MPOD_HEADEND_RESET_ALL) ? "true" : "false");
3415
3416    printf("restartOcapStack = %s\n",
3417        B_MPOD_HEADEND_GET_HOST_VEC_RESTART_FIELD(hostResetVector, B_MPOD_HEADEND_RESTART_OCAP_STACK) ? "true" : "false");
3418    printf("restartAll = %s\n",
3419        B_MPOD_HEADEND_GET_HOST_VEC_RESTART_FIELD(hostResetVector, B_MPOD_HEADEND_RESTART_ALL) ? "true" : "false");
3420
3421    printf("reloadAllOcapApps = %s\n",
3422        B_MPOD_HEADEND_GET_HOST_VEC_RELOAD_APP_FIELD(hostResetVector, B_MPOD_HEADEND_RELOAD_ALL_OCAP_APPS) ? "true" : "false");
3423    printf("reloadOcapStack = %s\n",
3424        B_MPOD_HEADEND_GET_HOST_VEC_RELOAD_APP_FIELD(hostResetVector, B_MPOD_HEADEND_RELOAD_OCAP_STACK) ? "true" : "false");
3425
3426    printf("reloadHostFirmware = %s\n",
3427        B_MPOD_HEADEND_GET_HOST_VEC_RELOAD_FW_FIELD(hostResetVector, B_MPOD_HEADEND_RELOAD_HOST_FIRMWARE) ? "true" : "false");
3428
3429    printf("clearPersistentGetFeatParams = %s\n",
3430        B_MPOD_HEADEND_GET_HOST_VEC_CLEARING_FIELD(hostResetVector, B_MPOD_HEADEND_CLEAR_PERSISTENT_GEN_FEAT_PARAMS) ? "true" : "false");
3431    printf("clearOrgDvbPersistentFs = %s\n",
3432        B_MPOD_HEADEND_GET_HOST_VEC_CLEARING_FIELD(hostResetVector, B_MPOD_HEADEND_CLEAR_ORG_DVB_PERSISTENT_FS) ? "true" : "false");
3433    printf("clearCachedUnboundApps = %s\n",
3434        B_MPOD_HEADEND_GET_HOST_VEC_CLEARING_FIELD(hostResetVector, B_MPOD_HEADEND_CLEAR_CACHED_UNBOUND_APPS) ? "true" : "false");
3435    printf("clearRegisteredLibs = %s\n",
3436        B_MPOD_HEADEND_GET_HOST_VEC_CLEARING_FIELD(hostResetVector, B_MPOD_HEADEND_CLEAR_REGISTERED_LIBS) ? "true" : "false");
3437    printf("clearPersistentHostMem = %s\n",
3438        B_MPOD_HEADEND_GET_HOST_VEC_CLEARING_FIELD(hostResetVector, B_MPOD_HEADEND_CLEAR_PERSISTENT_HOST_MEM) ? "true" : "false");
3439    printf("clearSecElemPassedValues = %s\n",
3440        B_MPOD_HEADEND_GET_HOST_VEC_CLEARING_FIELD(hostResetVector, B_MPOD_HEADEND_CLEAR_SEC_ELEM_PASSED_VALUES) ? "true" : "false");
3441    printf("clearNonAsdDvrContent = %s\n",
3442        B_MPOD_HEADEND_GET_HOST_VEC_CLEARING_FIELD(hostResetVector, B_MPOD_HEADEND_CLEAR_NON_ASD_DVR_CONTENT) ? "true" : "false");
3443    printf("clearAsdDvrContent = %s\n",
3444        B_MPOD_HEADEND_GET_HOST_VEC_CLEARING_FIELD(hostResetVector, B_MPOD_HEADEND_CLEAR_ASD_DVR_CONTENT) ? "true" : "false");
3445    printf("clearNetworkDvrContent = %s\n",
3446        B_MPOD_HEADEND_GET_HOST_VEC_CLEARING_FIELD(hostResetVector, B_MPOD_HEADEND_CLEAR_NETWORK_DVR_CONTENT) ? "true" : "false");
3447    printf("clearMediaVolInternalHdd = %s\n",
3448        B_MPOD_HEADEND_GET_HOST_VEC_CLEARING_FIELD(hostResetVector, B_MPOD_HEADEND_CLEAR_MEDIA_VOL_INTERNAL_HDD) ? "true" : "false");
3449    printf("clearMediaVolExternalHdd = %s\n",
3450        B_MPOD_HEADEND_GET_HOST_VEC_CLEARING_FIELD(hostResetVector, B_MPOD_HEADEND_CLEAR_MEDIA_VOL_EXTERNAL_HDD) ? "true" : "false");
3451    printf("clearGpfsInternalHdd = %s\n",
3452        B_MPOD_HEADEND_GET_HOST_VEC_CLEARING_FIELD(hostResetVector, B_MPOD_HEADEND_CLEAR_GPFS_INTERNAL_HDD) ? "true" : "false");
3453    printf("clearGpfsExternalHdd = %s\n",
3454        B_MPOD_HEADEND_GET_HOST_VEC_CLEARING_FIELD(hostResetVector, B_MPOD_HEADEND_CLEAR_GPFS_EXTERNAL_HDD) ? "true" : "false");
3455    printf("clearAllStorage = %s\n",
3456        B_MPOD_HEADEND_GET_HOST_VEC_CLEARING_FIELD(hostResetVector, B_MPOD_HEADEND_CLEAR_ALL_STORAGE) ? "true" : "false");
3457
3458    printf("\n");
3459}
3460
3461void cablecard_init(
3462    void
3463    )
3464{
3465    B_MPOD_APINFO_SETTINGS apInfoSettings;
3466    B_MPOD_DSG_SETTINGS dsgSettings;
3467    B_MPOD_EXT_CH_SETTINGS extChSettings;
3468    B_MPOD_RES_SETTINGS resSettings = {5 /* max simul xpt streams*/,&resProfileInfoCb};
3469    B_MPOD_MMI_SETTINGS mmiSettings = {&mmiDialogRequestCb, &mmiDialogCloseCb,
3470        &mmiHtmlRdyCb, (B_MPOD_MMI_CB_EXTERN_RDY)NULL, (B_MPOD_MMI_CB_EXTERN_RCV)NULL, &mmiSessionOpenCb,
3471        &mmiSessionCloseCb};
3472
3473    B_MPOD_SAS_SETTINGS sasSettings = {&sasConnectCnfCallback, &sasConnectionRdyCallback,
3474        &sasSynchDataRcvCallback, &sasAsynchDataRcvCallback, &sasGetSynchDataCallback,
3475        NULL, NULL, &sasConnectionClosedCallback};
3476
3477    B_MPOD_DL_SETTINGS dlSettings = {&dlHostInfoCb,&dlNewCodeVersionTableCb};
3478
3479    B_MPOD_FEATURE_SETTINGS featureSettings = {&featureReqHostListCb, &featureReqParamsCb,
3480                &featureRcvCardListCb, &featureRcvParamsCb, &featureParamDeniedCb};
3481
3482    B_MPOD_HOST_CONTROL_SETTNINGS hostControlSettings = {&inbandTuneCb, &oobTxTuneCb,
3483                                                &oobRxTuneCb, &sourceIdToFreqCb};
3484
3485    B_MPOD_HOMING_SETTINGS homingSettings = {&homingTimeoutCb, &delayedDownloadReqCb,
3486                    &homingCompleteCb, &downloadStartingCb, &downloadCompleteCb};
3487
3488    B_MPOD_DIAG_SETTINGS diagSettings = {&diagReqCb};
3489    B_MPOD_SYSTIME_SETTINGS systimeSettings = {NULL};
3490    B_MPOD_CA_SETTINGS caSettings = {&caInfoCb, &caPmtUpdate, &caPmtReply};
3491    B_MPOD_CP_SETTINGS cpSettings = {&getAuthKeyCb, &cardAuthMsgCb,
3492        &getNonceCb, &cpkeyGenCb, &removeKeyCb, &progKeyCb, &calcCciAckCb,
3493        &enforceCciCb, &newValidationStatusCb, &getIDCb};
3494
3495    B_MPOD_SNMP_SETTINGS snmpSettings = { &getRootOID, &getSnmpReply};
3496    B_MPOD_HEADEND_COMM_SETTINGS headendCommSettings = {&rcvHostResetVectorCb};
3497
3498    B_MPOD_PROP_HOST_PROPS_SETTINGS hostPropertySettings = {&hostPropertiesReplyCb};
3499
3500
3501    BKNI_Memset(SasConnections, 0, sizeof(SasConnections));
3502
3503/* Initialize the resource manager */
3504    if(B_Mpod_ResrcMgrInit())
3505    {
3506        printf("Unable to initialize resource manager\n");
3507        exit(1);
3508    }
3509
3510
3511    if(B_Mpod_SasInit(&sasSettings))
3512    {
3513        printf("Unable to initialize SAS resource\n");
3514        exit(1);
3515    }
3516
3517
3518/* DSG Settings */
3519    dsgSettings.dsgErrorCb = &CableCardCallback_DSG_Packet_Error;
3520    dsgSettings.dsgRcvSetModeCb = &CableCardCallback_DSGSet_DSG_Mode;
3521    dsgSettings.dsgRcvDirectoryCb = &CableCardCallback_DSG_Directory;
3522    if(B_Mpod_DsgInit(&dsgSettings))
3523    {
3524        printf("Unable to initialize DSG resource\n");
3525        exit(1);
3526    }
3527
3528/* Ext Channel Settings */
3529    extChSettings.reqIpUnicastFlowCbThread = &CableCardCallback_IPU_Dhcp;
3530    extChSettings.reqIpMulticastFlowCb = &CableCardCallback_Req_Ipm_Flow;
3531    extChSettings.reqDsgFlowCb = &CableCardCallback_DSG_Flow_Id;
3532    extChSettings.reqSocketFlowCbThread = &CableCardCallback_Socket_Flow_Config;
3533    extChSettings.flowReqFailedCb = &CableCardCallback_Flow_Req_Failed;
3534    extChSettings.newFlowCnfCb = &CableCardCallback_New_Flow_Cnf_Cb;
3535    extChSettings.delFlowReqCb = &CableCardCallback_Delete_Flow_Req;
3536    extChSettings.delFlowCnfCb = &CableCardCallback_Del_Flow_Cnf_Cb;
3537    extChSettings.lostFlowIndCb = &CableCardCallback_Lost_Flow_Cb;
3538    extChSettings.rcvSetDsgModeCb = &CableCardCallback_ExtSet_DSG_Mode;
3539    extChSettings.dsgErrorCb = &CableCardCallback_DSG_Packet_Error;
3540    extChSettings.configAdvDsgCb = &CableCardCallback_Config_Advanced_DSG;
3541    extChSettings.rcvFlowDataCb = &CableCardCallback_Rcv_Flow_Data;
3542    if(B_Mpod_ExtendedChInit(&extChSettings))
3543    {
3544        printf("Unable to initialize Extended Channel resource\n");
3545        exit(1);
3546    }
3547
3548/* App Info */
3549    B_Mpod_AppInfoGetDefaultCapabilities(&apInfoSettings);
3550
3551    apInfoSettings.apInfoExternalHandlerRcvCb   = NULL;
3552    apInfoSettings.apInfoChangedCb              = &apInfoInfo_Changed_Cb;
3553    if(B_Mpod_AppInfoInit(&apInfoSettings))
3554    {
3555        printf("Unable to initialize ApInfo resource\n");
3556        exit(1);
3557    }
3558
3559    if(B_Mpod_MmiInit(&mmiSettings))
3560    {
3561        printf("Unable to initialize MMI resource\n");
3562        exit(1);
3563    }
3564
3565    if(B_Mpod_DownloadInit(&dlSettings))
3566    {
3567        printf("Unable to initialize Download resource\n");
3568        exit(1);
3569    }
3570
3571    if(B_Mpod_FeatureInit(&featureSettings))
3572    {
3573        printf("Unable to initialize Feature resource\n");
3574        exit(1);
3575    }
3576
3577    if(B_Mpod_HostControlInit(&hostControlSettings))
3578    {
3579        printf("Unable to initialize Host Control resource\n");
3580        exit(1);
3581    }
3582
3583    if(B_Mpod_HomingInit(&homingSettings))
3584    {
3585        printf("Unable to initialize Homing resource\n");
3586        exit(1);
3587    }
3588
3589    if(B_Mpod_DiagsInit(&diagSettings))
3590    {
3591        printf("Unable to initialize General Diagnostic resource\n");
3592        exit(1);
3593    }
3594
3595    if(B_Mpod_SystimeInit(&systimeSettings))
3596    {
3597        printf("Unable to initialize Systime resource\n");
3598        exit(1);
3599    }
3600
3601    if(B_Mpod_CaInit(&caSettings))
3602    {
3603        printf("Unable to initialize Systime resource\n");
3604        exit(1);
3605    }
3606
3607    if(B_Mpod_CpInit(&cpSettings))
3608    {
3609        printf("Unable to initialize Systime resource\n");
3610        exit(1);
3611    }
3612
3613    if(B_Mpod_ResInit(&resSettings))
3614    {
3615        printf("Unable to initialize Res resource\n");
3616        exit(1);
3617    }
3618
3619    if(B_Mpod_SnmpInit(&snmpSettings))
3620    {
3621        printf("Unable to initialize SNMP resource\n");
3622        exit(1);
3623    }
3624
3625    if(B_Mpod_HostPropertiesInit(&hostPropertySettings))
3626    {
3627        printf("Unable to initialize Host Property resource\n");
3628        exit(1);
3629    }
3630
3631    if(B_Mpod_HeadendCommInit(&headendCommSettings))
3632    {
3633        printf("Unable to initialize HE resource\n");
3634        exit(1);
3635    }
3636
3637}
Note: See TracBrowser for help on using the repository browser.