/*************************************************************************** * Copyright (c) 2012, Broadcom Corporation * All Rights Reserved * Confidential Property of Broadcom Corporation * * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. * * $brcm_Workfile: $ * $brcm_Revision: $ * $brcm_Date: $ * * Module Description: test A56 message filtering * * Revision History: * * $brcm_Log: $ * * ***************************************************************************/ #include "bstd.h" #include "bkni.h" #include "bdbg.h" #include "serial.h" #include "input_parser.h" #include "bcrc32.h" #include "bsettop.h" #include "bsettop_smessage.h" #include "test_tuner.h" #include "si.h" #include "si_nim.h" #include "si_ntm.h" #include "si_vcm.h" #include "test_a56.h" BDBG_MODULE(test_a56); #define MAX_MSG_BUFFERS 0x400 #define MSG_BUFFER_SIZE 0x1000 static bool initialized = false; unsigned char a56_msg_buffer[MSG_BUFFER_SIZE]; //static smessage_stream_t stt_msg = NULL; //static smessage_stream_t rrt_msg = NULL; static smessage_stream_t nim_msg = NULL; static smessage_stream_t ntm_msg = NULL; static smessage_stream_t vcm_msg = NULL; static smessage_stream_params_t params; static SI_NIM_CDT_Callback_t nim_cdt_cb = { NULL, NULL }; static SI_NIM_MMT_Callback_t nim_mmt_cb = { NULL, NULL }; static SI_NTM_SNT_Callback_t ntm_snt_cb = { NULL, NULL }; static SI_VCM_VCT_Callback_t vcm_vct_cb = { NULL, NULL }; /* function prototype */ void a56_nim_cdt_cb(NIM_CDT_INFO *pCDT, void *data); void a56_nim_mmt_cb(NIM_MMT_RECORD *pMMT, void *data); void a56_vcm_vct_cb(SI_VCM_VCT_CHANNEL *pChannel, void *data); void a56_stop(void); /* default QAM tuner */ static int tuner_band = TUNER_BAND; /* * Summary: * choose chich tuner to use (QAM tuner or OOB tuner) */ bool a56_test_choose_tuner(int tuner) { #ifdef OOB_TUNER_SUPPORT tuner_band = tuner ? OOB_TUNER_BAND : TUNER_BAND; #else tuner_band = TUNER_BAND; #endif } void *a56_msg_callback(void *context, size_t data_size) { uint8_t *msg; SI_RET_CODE rc; msg = (uint8_t*)a56_msg_buffer; BDBG_WRN(("table ID=0x%hx, size %u", msg[0], data_size)); switch (*msg) { case SI_NIM_TABLE_ID: rc = SI_NIM_parse(msg); if (SI_SUCCESS != rc) { BDBG_WRN(("NIM parse error (rc=0x%x)\n",rc)); } else { BDBG_WRN(("SI_NIM_CDT_Complete=%d\n",SI_NIM_CDT_Complete())); BDBG_WRN(("SI_NIM_MMT_Complete=%d\n",SI_NIM_MMT_Complete())); /* initialize it so that it can be redisplay again */ SI_NIM_Init((SI_NIM_CDT_Callback_t *)&nim_cdt_cb, (SI_NIM_MMT_Callback_t *)&nim_mmt_cb, 0xFF, 0xFF); } break; case SI_NTM_TABLE_ID: rc = SI_NTM_parse(msg); if (SI_SUCCESS != rc) { BDBG_WRN(("NTM parse error (rc=0x%x)\n",rc)); } else { BDBG_WRN(("SI_NTM_SNT_Complete=%d\n",SI_NTM_SNT_Complete())); /* initialize it so that it can be redisplay again */ SI_NTM_Init((SI_NTM_SNT_Callback_t *)&ntm_snt_cb, 0xFF); } break; case SI_VCM_TABLE_ID: rc = SI_VCM_parse(msg); if (SI_SUCCESS != rc) { BDBG_WRN(("VCM parse error (rc=0x%x)\n",rc)); } else { BDBG_WRN(("SI_VCM_Complete=%d\n", SI_VCM_Complete())); SI_VCM_Init((SI_VCM_VCT_Callback_t *)&vcm_vct_cb, 0xFF); } break; } return msg; } char *transmission_system_str[16] = { "unknown", "ITU-T annex A", "ITU-T annex B", "ITU-R", "ATSC", "DigiCipher", "ITU-T annex C", "ITU-T annex D", "reserved", "reserved", "reserved", "reserved", "reserved", "reserved", "reserved", "reserved", }; char *inner_coding_mode_str[16] = { "rate 5/11 coding", "rate 1/2 coding", "reserved", "rate 3/5 coding", "reserved", "rate 2/3 coding", "reserved", "rate 3/4 coding", "rate 4/5 coding", "rate 5/6 coding", "reserved", "rate 7/8 coding", "reserved", "reserved", "reserved", "none" }; char *modulation_format_str[32] = { "unknown", "QPSK", "BPSK", "OQPSK", "VSB 8", "VSB 16", "QAM 16", "QAM 32", "QAM 64", "QAM 80", "QAM 96", "QAM 112", "QAM 128", "QAM 160", "QAM 192", "QAM 224", "QAM 256", "QAM 320", "QAM 384", "QAM 448", "QAM 512", "QAM 640", "QAM 768", "QAM 896", "QAM 1024", "reserved", "reserved", "reserved", "reserved", "reserved", "reserved", "reserved" }; /* * Summary: * A56 Parser NIM MMT Callback. */ void a56_nim_mmt_cb(NIM_MMT_RECORD *pMMT, void *data) { BKNI_Printf("%24s = %d\n", "index", pMMT->idx); BKNI_Printf("%24s = %s\n", "modulation format", modulation_format_str[pMMT->modulation_format % 32]); BKNI_Printf("%24s = %s\n", "transmission system", transmission_system_str[pMMT->transmission_system % 16]); BKNI_Printf("%24s = %s\n", "inner coding mode", inner_coding_mode_str[pMMT->inner_coding_mode % 16]); BKNI_Printf("%24s = %d\n", "symbol rate", pMMT->symbol_rate); } /* * Summary: * A65 Parser NIM CDT Callback. */ void a56_nim_cdt_cb(NIM_CDT_INFO *pCDT, void *data) { BKNI_Printf("idx = %d\n", pCDT->idx); BKNI_Printf("freq_khz = %d\n", pCDT->freq_khz); } /* * Summary: * Stop NIM filtering */ void a56_nim_stop() { if (NULL != nim_msg) { if (b_ok != smessage_stop(nim_msg)) { BDBG_ERR(("%s:%d",__FILE__, __LINE__)); return; } smessage_close(nim_msg); nim_msg = NULL; } } /* * Summary: * Start nim filtering */ int a56_nim_start(unsigned short network_pid) { int cerr = 0; a56_stop(); nim_msg = smessage_open(smessage_format_psi); if (NULL == nim_msg) { BDBG_ERR(("%s",__func__)); cerr = -1; return cerr; } smessage_stream_params_init(¶ms, nim_msg); params.band = tuner_band; params.pid = (uint16_t)network_pid; params.filter.coef[0] = SI_NIM_TABLE_ID; params.filter.mask[0] = 0x00; params.filter.excl[0] = 0xff; params.filter.coef[3] = 0x00; /* protocol_version */ params.filter.mask[3] = 0x00; params.filter.excl[3] = 0xff; params.buffer = a56_msg_buffer; params.buffer_size = sizeof(a56_msg_buffer); /* processing is done in callback */ params.data_ready_callback = a56_msg_callback; params.overflow = NULL; /* don't set the callback */ params.callback_context = NULL; SI_NIM_Init((SI_NIM_CDT_Callback_t *)&nim_cdt_cb, (SI_NIM_MMT_Callback_t *)&nim_mmt_cb, 0xFF, 0xFF); if (b_ok != smessage_start(¶ms, nim_msg)) { BDBG_ERR(("%s:%d",__FILE__, __LINE__)); cerr = -1; } return cerr; } /* * Summary: * A65 Parser NTM SNT Callback. * */ void a56_ntm_snt_cb(SI_NTM_SNT_t *snt, void *data) { unsigned char code[3]; code[0] = (unsigned char)((snt->iso639 >> 16) & 0xFF); code[1] = (unsigned char)((snt->iso639 >> 8) & 0xFF); code[2] = (unsigned char)((snt->iso639 >> 0) & 0xFF); BKNI_Printf("%18s = %c%c%c\n", "language", code[0], code[1], code[2]); BKNI_Printf("%18s = %d (0x%x)\n", "source ID", snt->source_id, snt->source_id); BKNI_Printf("%18s = %d\n","application type", snt->application_type); snt->mtt[snt->name_length] = 0; /* it is MMS format, so skip 2 bytes to get string directly */ BKNI_Printf("%18s = %s\n", "name", &snt->mtt[2]); } /* * Summary: * Start ntm filtering */ int a56_ntm_start(unsigned short network_pid) { int cerr = 0; a56_stop(); ntm_msg = smessage_open(smessage_format_psi); if (NULL == ntm_msg) { BDBG_ERR(("%s",__func__)); cerr = -1; return cerr; } smessage_stream_params_init(¶ms, ntm_msg); params.band = tuner_band; params.pid = (uint16_t)network_pid; params.filter.coef[0] = SI_NTM_TABLE_ID; params.filter.mask[0] = 0x00; params.filter.excl[0] = 0xff; params.filter.coef[3] = 0x00; /* protocol_version */ params.filter.mask[3] = 0x00; params.filter.excl[3] = 0xff; params.buffer = a56_msg_buffer; params.buffer_size = sizeof(a56_msg_buffer); /* processing is done in callback */ params.data_ready_callback = a56_msg_callback; params.overflow = NULL; /* don't set the callback */ params.callback_context = NULL; SI_NTM_Init((SI_NTM_SNT_Callback_t *)&ntm_snt_cb, 0xFF); if (b_ok != smessage_start(¶ms, ntm_msg)) { BDBG_ERR(("%s:%d",__FILE__, __LINE__)); cerr = -1; } return cerr; } /* * Summary: * Stop NTM filtering */ void a56_ntm_stop() { if (NULL != ntm_msg) { if (b_ok != smessage_stop(ntm_msg)) { BDBG_ERR(("%s:%d",__FILE__, __LINE__)); return; } smessage_close(ntm_msg); ntm_msg = NULL; } } /* * Summary: * Start vcm filtering */ int a56_vcm_start(unsigned short network_pid) { int cerr = 0; a56_stop(); vcm_msg = smessage_open(smessage_format_psi); if (NULL == vcm_msg) { BDBG_ERR(("%s",__func__)); cerr = -1; return cerr; } smessage_stream_params_init(¶ms, vcm_msg); params.band = tuner_band; params.pid = (uint16_t)network_pid; params.filter.coef[0] = SI_VCM_TABLE_ID; params.filter.mask[0] = 0x00; params.filter.excl[0] = 0xff; params.filter.coef[3] = 0x00; /* protocol_version */ params.filter.mask[3] = 0x00; params.filter.excl[3] = 0xff; params.buffer = a56_msg_buffer; params.buffer_size = sizeof(a56_msg_buffer); /* processing is done in callback */ params.data_ready_callback = a56_msg_callback; params.overflow = NULL; /* don't set the callback */ params.callback_context = NULL; SI_VCM_Init((SI_VCM_VCT_Callback_t *)&vcm_vct_cb, 0xFF); if (b_ok != smessage_start(¶ms, vcm_msg)) { BDBG_ERR(("%s:%d",__FILE__, __LINE__)); cerr = -1; } return cerr; } char *transport_type_str[2] = { "MPEG-2 transport", "non-MPEG-2 transport", }; char *channel_type_str[16] = { "normal", "hidden", "local access", "NVOD access", "reserved", }; #define CHANNEL_TYPE_MAX 4 /* * Summary: * A65 Parser VCM VCT Callback. * */ void a56_vcm_vct_cb(SI_VCM_VCT_CHANNEL *channel, void *data) { int tmp; BKNI_Printf("%24s = %d\n", "vcn mode", channel->vcn_mode); BKNI_Printf("%24s = %d (0x%x)\n", "channel num 1", channel->channum1, channel->channum1); BKNI_Printf("%24s = %d (0x%x)\n", "channel num 2", channel->channum2, channel->channum2); BKNI_Printf("%24s = 0x%x\n", "app flag", channel->appflag); BKNI_Printf("%24s = %d (0x%x)\n", "Source ID", channel->source_ID, channel->source_ID); BKNI_Printf("%24s = %d\n", "path select", channel->path_select); BKNI_Printf("%24s = %s\n", "transport type", transport_type_str[channel->transport_type % 2]); tmp = channel->channel_type; if (tmp >= CHANNEL_TYPE_MAX) tmp = CHANNEL_TYPE_MAX; BKNI_Printf("%24s = %s\n", "channel type", channel_type_str[tmp]); BKNI_Printf("%24s = %d (0x%x)\n", "CDT reference", channel->CDT_reference, channel->CDT_reference); BKNI_Printf("%24s = %d\n", "program num", channel->ChanPropUnion.mpeg_prop.prog_num); BKNI_Printf("%24s = %s\n", "more program", channel->more_prop ? "yes" : "no"); BKNI_Printf("%24s = %d\n", "TSID", channel->tsid); BKNI_Printf("%24s = %d\n", "service type", channel->serv_type); BKNI_Printf("%24s = 0x%x\n", "channel bits", channel->chanbits); BKNI_Printf("%24s = %d (0x%x)\n", "VCT ID", channel->vct_id, channel->vct_id); BKNI_Printf("%24s = %d\n", "HD flag", channel->hd_flag); BKNI_Printf("%24s = %d\n", "3D flag", channel->threed_flag); BKNI_Printf("%24s = %d\n", "MPEG4 flag", channel->mpeg4_flag); BKNI_Printf("%24s = %d\n", "SDV flag", channel->sdv_flag); BKNI_Printf("%24s = 0x%x\n", "Included", channel->included); if (channel->included & VCM_VCT_FREQ_SPEC_INCLUDED) { BKNI_Printf("%24s = %d\n", "frequency unit", channel->frequency_unit); BKNI_Printf("%24s = %d\n", "frequency", channel->frequency); } if (channel->included & VCM_VCT_SYMBOL_RATE_INCLUDED) { BKNI_Printf("%24s = %d\n", "symbol rate", channel->symbol_rate); } } /* * Summary: * Stop VCM filtering */ void a56_vcm_stop() { if (NULL != vcm_msg) { if (b_ok != smessage_stop(vcm_msg)) { BDBG_ERR(("%s:%d",__FILE__, __LINE__)); return; } smessage_close(vcm_msg); vcm_msg = NULL; } } /* * Summary: * Initialize A56 nim module */ static void a56_nim_init(void) { nim_cdt_cb.cb = a56_nim_cdt_cb; nim_cdt_cb.data = NULL; nim_mmt_cb.cb = a56_nim_mmt_cb; nim_mmt_cb.data = NULL; } /* * Summary: * Initialize A56 ntm module */ static void a56_ntm_init(void) { ntm_snt_cb.cb = a56_ntm_snt_cb; ntm_snt_cb.data = NULL; } /* * Summary: * Initialize A56 vcm module */ static void a56_vcm_init(void) { vcm_vct_cb.cb = a56_vcm_vct_cb; vcm_vct_cb.data = NULL; } /* * Summary: * Initialize A56 test module * */ bool a56_init(void) { if (initialized) return true; initialized = true; a56_nim_init(); a56_ntm_init(); a56_vcm_init(); return true; } /* * Summary: * stop A56 test modules * */ void a56_stop(void) { a56_nim_stop(); a56_ntm_stop(); a56_vcm_stop(); } /* * Summary: * run given test (0 nim, 1 ntm, 2 vcm, 3 stt) */ bool a56_test_start(int which, unsigned short network_pid) { if (!initialized) { BDBG_ERR(("%s: not initialized yet",__func__)); return false; } switch (which) { case A56_NIM: a56_nim_start(network_pid); break; case A56_NTM: a56_ntm_start(network_pid); break; case A56_VCM: a56_vcm_start(network_pid); break; } return true; } /* * Summary: * stop the given test */ bool a56_test_stop(void) { if (!initialized) { BDBG_ERR(("%s: not initialized yet",__func__)); return false; } a56_stop(); return true; }