/****************************************************************************** * (c)2008-2010 Broadcom Corporation * * This program is the proprietary software of Broadcom Corporation and/or its licensors, * and may only be used, duplicated, modified or distributed pursuant to the terms and * conditions of a separate, written license agreement executed between you and Broadcom * (an "Authorized License"). Except as set forth in an Authorized License, Broadcom grants * no license (express or implied), right to use, or waiver of any kind with respect to the * Software, and Broadcom expressly reserves all rights in and to the Software and all * intellectual property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU * HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY * NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE. * * Except as expressly set forth in the Authorized License, * * 1. This program, including its structure, sequence and organization, constitutes the valuable trade * secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof, * and to use this information only in connection with your use of Broadcom integrated circuit products. * * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" * AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO * THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, * LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION * OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF * USE OR PERFORMANCE OF THE SOFTWARE. * * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS * LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR * EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR * USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT * ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF * ANY LIMITED REMEDY. * * $brcm_Workfile: $ * $brcm_Revision: $ * $brcm_Date: $ * * Module Description: * * Revision History: * * $brcm_Log: $ * *****************************************************************************/ #include "nexus_msg.h" #include "nexus_platform.h" #include "nexus_pid_channel.h" #include "nexus_parser_band.h" #include "nexus_message.h" #include "ministd.h" #include "bstd.h" #include "bkni.h" BDBG_MODULE(nexus_msg); #define NEXUS_MSG_STK_SIZE 1024 typedef struct nexus_p_msg_t { b_task_t task_h; unsigned short pid; unsigned char name[64]; unsigned int stack[NEXUS_MSG_STK_SIZE]; }nexus_p_msg_t; void message_callback(void *context, int param) { BSTD_UNUSED(param); BKNI_SetEvent((BKNI_EventHandle)context); } #if 1 void msg_main(void *data) { NEXUS_PidChannelHandle pidChannel; NEXUS_MessageHandle msg; NEXUS_MessageSettings settings; NEXUS_MessageStartSettings startSettings; NEXUS_ParserBandSettings parserBandSettings; NEXUS_PidChannelSettings pidChannelSettings; BKNI_EventHandle event; NEXUS_Error rc; nexus_p_msg_t *p_msg = (nexus_p_msg_t*)data; BDBG_ERR(("Start filter for PID[0x%04x]\n",p_msg->pid)); NEXUS_PidChannel_GetDefaultSettings(&pidChannelSettings); pidChannel = NEXUS_PidChannel_Open(NEXUS_ParserBand_e0, p_msg->pid, &pidChannelSettings); BKNI_CreateEvent(&event); NEXUS_Message_GetDefaultSettings(&settings); settings.dataReady.callback = message_callback; settings.dataReady.context = event; //settings.maxContiguousMessageSize = 4096; msg = NEXUS_Message_Open(&settings); BDBG_ASSERT(msg); NEXUS_Message_GetDefaultStartSettings(msg, &startSettings); startSettings.pidChannel = pidChannel; /* use the default filter for any data */ /* Read the PAT a few times */ while (1) { const uint8_t *buffer; size_t size; int message_length; rc = NEXUS_Message_Start(msg, &startSettings); BDBG_ASSERT(!rc); rc = NEXUS_Message_GetBuffer(msg, (const void **)&buffer, &size); BDBG_ASSERT(!rc); if (!size) { BERR_Code rc = BKNI_WaitForEvent(event, 5 * 1000); /* wait 5 seconds */ if (rc) { BDBG_ERR(("Timeout waiting for section[0x%04x]\n",p_msg->pid)); } NEXUS_Message_Stop(msg); continue; } #define TS_READ_16( BUF ) ((uint16_t)((BUF)[0]<<8|(BUF)[1])) #define TS_PSI_GET_SECTION_LENGTH( BUF ) (uint16_t)(TS_READ_16( &(BUF)[1] ) & 0x0FFF) /* We should always get whole PAT's because maxContiguousMessageSize is 4K */ message_length = TS_PSI_GET_SECTION_LENGTH(buffer) + 3; /* XPT HW is configured to pad all messages to 4 bytes. If we are calling NEXUS_Message_ReadComplete based on message length and not the size returned by NEXUS_Message_GetBuffer, then we must add that pad. If we are wrong, NEXUS_Message_ReadComplete will fail. */ if (message_length % 4) { message_length += 4 - (message_length % 4); } if (size < (size_t)message_length) { BDBG_ERR(("Invalid Section Length[0x%04x](size %d < msg_length %d)\n",p_msg->pid,size,(size_t)message_length)); } // printf("Found Section[0x%04x]: id=%d size=%d\n", p_msg->pid, buffer[0], message_length); /* only complete one PAT */ rc = NEXUS_Message_ReadComplete(msg, size); BDBG_ASSERT(!rc); NEXUS_Message_Stop(msg); // bos_sleep(10); } NEXUS_Message_Stop(msg); NEXUS_Message_Close(msg); NEXUS_PidChannel_Close(pidChannel); NEXUS_Platform_Uninit(); return; } #else void msg_main(void *data) { NEXUS_PidChannelHandle pidChannel; NEXUS_MessageHandle msg; NEXUS_MessageSettings settings; NEXUS_MessageStartSettings startSettings; NEXUS_ParserBandSettings parserBandSettings; NEXUS_PidChannelSettings pidChannelSettings; BKNI_EventHandle event; NEXUS_Error rc; nexus_p_msg_t *p_msg = (nexus_p_msg_t*)data; BDBG_ERR(("Start filter for PID[0x%04x]\n",p_msg->pid)); NEXUS_PidChannel_GetDefaultSettings(&pidChannelSettings); pidChannel = NEXUS_PidChannel_Open(NEXUS_ParserBand_e0, p_msg->pid, &pidChannelSettings); BKNI_CreateEvent(&event); NEXUS_Message_GetDefaultSettings(&settings); settings.dataReady.callback = message_callback; settings.dataReady.context = event; settings.maxContiguousMessageSize = 4096; msg = NEXUS_Message_Open(&settings); BDBG_ASSERT(msg); NEXUS_Message_GetDefaultStartSettings(msg, &startSettings); startSettings.pidChannel = pidChannel; /* use the default filter for any data */ rc = NEXUS_Message_Start(msg, &startSettings); BDBG_ASSERT(!rc); /* Read the PAT a few times */ while (1) { const uint8_t *buffer; size_t size; int message_length; rc = NEXUS_Message_GetBuffer(msg, (const void **)&buffer, &size); BDBG_ASSERT(!rc); if (!size) { BERR_Code rc = BKNI_WaitForEvent(event, 5 * 1000); /* wait 5 seconds */ if (rc) { BDBG_ERR(("Timeout waiting for section[0x%04x]\n",p_msg->pid)); } continue; } #define TS_READ_16( BUF ) ((uint16_t)((BUF)[0]<<8|(BUF)[1])) #define TS_PSI_GET_SECTION_LENGTH( BUF ) (uint16_t)(TS_READ_16( &(BUF)[1] ) & 0x0FFF) /* We should always get whole PAT's because maxContiguousMessageSize is 4K */ message_length = TS_PSI_GET_SECTION_LENGTH(buffer) + 3; /* XPT HW is configured to pad all messages to 4 bytes. If we are calling NEXUS_Message_ReadComplete based on message length and not the size returned by NEXUS_Message_GetBuffer, then we must add that pad. If we are wrong, NEXUS_Message_ReadComplete will fail. */ if (message_length % 4) { message_length += 4 - (message_length % 4); } if (size < (size_t)message_length) { BDBG_ERR(("Invalid Section Length[0x%04x](size %d < msg_length %d)\n",p_msg->pid,size,(size_t)message_length)); } // printf("Found Section[0x%04x]: id=%d size=%d\n", p_msg->pid, buffer[0], message_length); /* only complete one PAT */ rc = NEXUS_Message_ReadComplete(msg, size); BDBG_ASSERT(!rc); // bos_sleep(10); } NEXUS_Message_Stop(msg); NEXUS_Message_Close(msg); NEXUS_PidChannel_Close(pidChannel); NEXUS_Platform_Uninit(); return; } #endif static int s_msg_thread_cnt = 0; int nexus_msg_start(unsigned short pid) { b_task_params task_params; nexus_p_msg_t *p_msg = (nexus_p_msg_t*)malloc(sizeof(nexus_p_msg_t)); BDBG_ASSERT(p_msg); p_msg->pid = pid; snprintf(p_msg->name,64,"nexus_msg_%d",pid); task_params.name=p_msg->name; task_params.priority = 60 + s_msg_thread_cnt++; task_params.stack_size = NEXUS_MSG_STK_SIZE; task_params.stack = p_msg->stack; bos_start_task(&(p_msg->task_h), &task_params, msg_main,p_msg); }