Beispiel #1
0
/** @brief Parse the SDT descriptors
 * Loop over the sdt descriptors and call other parsing functions if necessary
 * @param buf the buffer containing the descriptors
 * @param descriptors_loop_len the len of buffer containing the descriptors
 * @param service the associated service
 */
void parse_sdt_descriptor(unsigned char *buf,int descriptors_loop_len, mumudvb_service_t *service)
{

  while (descriptors_loop_len > 0)
  {
    unsigned char descriptor_tag = buf[0];
    unsigned char descriptor_len = buf[1] + 2;

    if (!descriptor_len)
    {
      log_message( log_module, MSG_DEBUG, "--- SDT descriptor --- descriptor_tag == 0x%02x, len is 0\n", descriptor_tag);
      break;
    }

    //The service descriptor provides the names of the service provider and the service in text form together with the service_type.
    if(descriptor_tag==0x48)
      parse_service_descriptor(buf,service);
    else if( descriptor_tag==0x53) //53 : CA identifier descriptor. This descriptor contains the CA_systems_id (the scrambling algorithms)
      show_CA_identifier_descriptor(buf);
    else if( descriptor_tag==0x49) //0x49 : Country availability descriptor.
      ts_display_country_avaibility_descriptor(log_module,buf);
    else /** @todo : Add descriptor 0x50 Component descriptor (multilingual 0x5E)*/
       /** @todo : Add descriptor 0x5D  multilingual_service_name_descriptor*/
      log_message( log_module, MSG_FLOOD, "SDT descriptor_tag : 0x%2x, descriptor_len %d\n", descriptor_tag, descriptor_len);

    buf += descriptor_len;
    descriptors_loop_len -= descriptor_len;
  }
}
Beispiel #2
0
S32 PSISI_Parse_SDT_Section(PSISI_Table_t * ptTable, U8 * ptData, U16 u16Len)
{
    _SDT_Sect_Template_t *  ptSDT_Head = NULL;
    _SDT_Item_Template_t *  ptServ_Head = NULL;

    U8      u8MemCntFlag = 1;
    S32     s32RetErr = PV_SUCCESS;

    U8 *    pu8DataPtr = NULL;
    S16     s16SectionLen = 0;
    U16     u16TS_Id = 0;
    S16     s16ServLoopLen = 0;
    U32     u32CRC = 0;

    U16     u16ServiceCnt = 0;
    U16     u16ServDescCnt = 0;
    U16     u16TextInfoCnt = 0;
    U16     u16NvodRefDescCnt = 0;
    U16     u16NvodRefInfoCnt = 0;
    U16     u16NvodTshDescCnt = 0;
    U16     u16OtherDescCnt = 0;
    U16     u16BytesCnt = 0;

    U32     u32MemSize = 0;
    U8 *    pu8MemPtr = NULL;

    SDT_Section_t *                 ptSDTSection = NULL;
    SDT_Service_t *                 ptService = NULL;
    Service_Desc_t *                ptServDesc = NULL;
    Text_Info_t *                   ptTextInfo = NULL;
    NVOD_Reference_Desc_t *         ptNvodRefDesc = NULL;
    NVOD_Ref_Info_t *               ptNvodRefInfo = NULL;
    NVOD_TimeShift_Serv_Desc_t *    ptNvodTshDesc = NULL;
    PSISI_Descriptor_t *            ptOtherDesc = NULL;
    U8 *                            pu8Bytes = NULL;

    if ((NULL == ptTable) || (NULL == ptData))
    {
        return PV_NULL_PTR;
    }

    if ( ((ptData[0] != SDT_TABLE_ID) && (ptData[0] != SDT_OTHER_TABLE_ID))
        || (u16Len < SDT_MIN_SECTION_LEN))
    {
        return PV_INVALID_PARAM;
    }
pbiinfo("[llwu]======PSISI_Parse_SDT_Section=============");
parse_begin:
    pu8DataPtr = ptData;
    ptSDT_Head = (_SDT_Sect_Template_t *)pu8DataPtr;
    s16SectionLen = (S16)((ptSDT_Head->sec_len_hi << 8) + ptSDT_Head->sec_len_lo + 3);
    u16TS_Id = (ptSDT_Head->ts_id_hi << 8) + ptSDT_Head->ts_id_lo;
	pbiinfo("[llwu]======PSISI_Parse_SDT_Section=======ts_id = %d======\n",u16TS_Id);
	//pbiinfo("[llwu]======PSISI_Parse_SDT_Section=======u8TableId = %d======\n",ptTable->u8TableId);
	//pbiinfo("[llwu]======PSISI_Parse_SDT_Section=======ts_id = %d======\n",ptTable->u16ExtendId);
	//pbiinfo("[llwu]======PSISI_Parse_SDT_Section=======table_id = %d======\n",ptSDT_Head->table_id);
    u32CRC = (pu8DataPtr[s16SectionLen - 4] << 24)
            + (pu8DataPtr[s16SectionLen - 3] << 16)
            + (pu8DataPtr[s16SectionLen - 2] << 8)
            + (pu8DataPtr[s16SectionLen - 1]);
    if (u8MemCntFlag != 0)
    {
        if ((ptTable->u8TableId != ptSDT_Head->table_id)
            || (ptTable->u16ExtendId != u16TS_Id))
        {
            return PV_INVALID_PARAM;
        }
        if (ptTable->u16SectionNum != (U16)(ptSDT_Head->last_sec_num + 1))
        {
            /* maybe table update */
            return PSISI_ERR_TABLE_UPDATE;
        }
//PBIDEBUG("[llwu]======PSISI_Parse_SDT_Section=============");
        if (ptTable->ppSection[ptSDT_Head->sec_num] != NULL)
        {
            ptSDTSection = (SDT_Section_t *)(ptTable->ppSection[ptSDT_Head->sec_num]);
            if ((ptSDTSection->u8Version != ptSDT_Head->version_number)
                || (ptSDTSection->u32CRC != u32CRC))
            {//PBIDEBUG("[llwu]======PSISI_Parse_SDT_Section=============");
                return PSISI_ERR_TABLE_UPDATE;
            }
            else
            {//PBIDEBUG("[llwu]======PSISI_Parse_SDT_Section=============");
                return PSISI_ERR_TABLE_REPEAT;
            }
        }
    }
    else
    {
        /* allocate memory */
        u32MemSize = sizeof(SDT_Section_t)
                    + (u16ServiceCnt * sizeof(SDT_Service_t))
                    + (u16ServDescCnt * sizeof(Service_Desc_t))
                    + (u16TextInfoCnt * sizeof(Text_Info_t))
                    + (u16NvodRefDescCnt * sizeof(NVOD_Reference_Desc_t))
                    + (u16NvodRefInfoCnt * sizeof(NVOD_Ref_Info_t))
                    + (u16NvodTshDescCnt * sizeof(NVOD_TimeShift_Serv_Desc_t))
                    + (u16OtherDescCnt * sizeof(PSISI_Descriptor_t))
                    + u16BytesCnt;
        u32MemSize = (u32MemSize + 3) & 0xFFFFFFFC;
        pu8MemPtr = (U8 *)psisi_section_malloc(u32MemSize);
        if (NULL == pu8MemPtr)
        {
            return PV_NO_MEMORY;
        }
        memset(pu8MemPtr, 0, u32MemSize);

        ptSDTSection = (SDT_Section_t *)pu8MemPtr;
        pu8MemPtr += sizeof(SDT_Section_t);
        if (u16ServiceCnt != 0)
        {
            ptService = (SDT_Service_t *)pu8MemPtr;
            pu8MemPtr += (u16ServiceCnt * sizeof(SDT_Service_t));
        }
        if (u16ServDescCnt != 0)
        {
            ptServDesc = (Service_Desc_t *)pu8MemPtr;
            pu8MemPtr += (u16ServDescCnt * sizeof(Service_Desc_t));
        }
        if (u16TextInfoCnt != 0)
        {
            ptTextInfo = (Text_Info_t *)pu8MemPtr;
            pu8MemPtr += (u16TextInfoCnt * sizeof(Text_Info_t));
        }
        if (u16NvodRefDescCnt != 0)
        {
            ptNvodRefDesc = (NVOD_Reference_Desc_t *)pu8MemPtr;
            pu8MemPtr += (u16NvodRefDescCnt * sizeof(NVOD_Reference_Desc_t));
        }
        if (u16NvodRefInfoCnt != 0)
        {
            ptNvodRefInfo = (NVOD_Ref_Info_t *)pu8MemPtr;
            pu8MemPtr += (u16NvodRefInfoCnt * sizeof(NVOD_Ref_Info_t));
        }
        if (u16NvodTshDescCnt != 0)
        {
            ptNvodTshDesc = (NVOD_TimeShift_Serv_Desc_t *)pu8MemPtr;
            pu8MemPtr += (u16NvodTshDescCnt * sizeof(NVOD_TimeShift_Serv_Desc_t));
        }
        if (u16OtherDescCnt != 0)
        {
            ptOtherDesc = (PSISI_Descriptor_t *)pu8MemPtr;
            pu8MemPtr += (u16OtherDescCnt * sizeof(PSISI_Descriptor_t));
        }
        if (u16BytesCnt != 0)
        {
            pu8Bytes = pu8MemPtr;
        }
        /* memory allocate finished. */

        ptSDTSection->u8TableId = ptSDT_Head->table_id;
        ptSDTSection->u8Version = ptSDT_Head->version_number;
        ptSDTSection->u16TS_Id = (ptSDT_Head->ts_id_hi << 8) + ptSDT_Head->ts_id_lo;
        ptSDTSection->u16ON_Id = (ptSDT_Head->on_id_hi << 8) + ptSDT_Head->on_id_lo;
        ptSDTSection->u32CRC = u32CRC;
        ptSDTSection->u16ServiceNum = u16ServiceCnt;
        ptSDTSection->ptService = ptService;

    }
    s16ServLoopLen = s16SectionLen - SDT_HEAD_LEN - 4;  /* 除去表头及 CRC 剩余的部分 */
    pu8DataPtr += SDT_HEAD_LEN;
	pbiinfo("[llwu]======PSISI_Parse_SDT_Section=======s16ServLoopLen = %d======\n",s16ServLoopLen);
    while (s16ServLoopLen > 0)
    {
        S16     s16DescLoopLen = 0;

        ptServ_Head = (_SDT_Item_Template_t *)pu8DataPtr;
        if (u8MemCntFlag != 0)
        {
            u16ServiceCnt++;
        }
        else
        {
            ptService->u16ServId = (ptServ_Head->service_id_hi << 8)
                                + ptServ_Head->service_id_lo;
            ptService->u8EitSchFlag = ptServ_Head->eit_schedule_flag;
            ptService->u8EitPF_Flag = ptServ_Head->eit_present_following_flag;
            ptService->u8RunningStatus = ptServ_Head->running_status;
            ptService->u8FreeCA_Mode = ptServ_Head->free_ca_mode;
            ptService->ptServDesc = NULL;
            ptService->ptNvodRefDesc = NULL;
            ptService->ptNvodTimeShiftDesc = NULL;
            ptService->u16OtherDescNum = 0;
            ptService->ptDesc = NULL;
        }
        s16DescLoopLen = (S16)((ptServ_Head->desc_loop_len_hi << 8)
                                + ptServ_Head->desc_loop_len_lo);
        pu8DataPtr += SDT_ITEM_HEAD_LEN;
        s16ServLoopLen -= (SDT_ITEM_HEAD_LEN + s16DescLoopLen);
   	//pbiinfo("[llwu]-------------  while (s16DescLoopLen > 0)---s16ServLoopLen = %d-------",s16ServLoopLen);
     
        while (s16DescLoopLen > 0)
        {
            
            U8  u8DescTag = pu8DataPtr[0];
            U8  u8DescLen = pu8DataPtr[1];

            if (SERVICE_DESCRIPTOR_TAG == u8DescTag)
            {
                if (u8MemCntFlag != 0)
                {
                    u16ServDescCnt++;
                    s32RetErr = parse_service_descriptor(pu8DataPtr, NULL,
                            &u16TextInfoCnt, &u16BytesCnt, u8MemCntFlag);
                    if( PV_SUCCESS != s32RetErr )
                    {
                        return s32RetErr;
                    }
                }
                else
                {
                    s32RetErr = parse_service_descriptor(pu8DataPtr, ptServDesc,
                            ptTextInfo, pu8Bytes, u8MemCntFlag);
		//pbiinfo("[llwu]-------------name: %s",ptServDesc->ptServName->sText);
                    if( PV_SUCCESS != s32RetErr )
                    {
                        psisi_section_free( ptSDTSection );
                        return s32RetErr;
                    }
                    if ( NULL != ptServDesc->ptServProviderName )
                    {
                        ptTextInfo++;
                        pu8Bytes += ptServDesc->ptServProviderName->u8Len;
                    }
                    if ( NULL != ptServDesc->ptServName )
                    {
                        ptTextInfo++;
                        pu8Bytes += ptServDesc->ptServName->u8Len;
                    }

                    if (NULL == ptService->ptServDesc)
                    {
                        ptService->ptServDesc = ptServDesc;
                    }
                    ptServDesc++;
                }
            }
            else if (NVOD_REFERENCE_DESCRIPTOR_TAG == u8DescTag)
            {
                if (u8MemCntFlag != 0)
                {
                    u16NvodRefDescCnt++;
                    s32RetErr= parse_nvod_reference_descriptor(pu8DataPtr, NULL,
                            &u16NvodRefInfoCnt, u8MemCntFlag);
                    if( PV_SUCCESS != s32RetErr )
                    {
                        return s32RetErr;
                    }
                }
                else
                {
                    s32RetErr = parse_nvod_reference_descriptor(pu8DataPtr, ptNvodRefDesc,
                            ptNvodRefInfo, u8MemCntFlag);
                    if( PV_SUCCESS != s32RetErr )
                    {
                        psisi_section_free( ptSDTSection );
                        return s32RetErr;
                    }
                    if (ptNvodRefDesc->u16RefInfoNum != 0)
                    {
                        ptNvodRefInfo += ptNvodRefDesc->u16RefInfoNum;
                    }

                    if (NULL == ptService->ptNvodRefDesc)
                    {
                        ptService->ptNvodRefDesc = ptNvodRefDesc;
                    }
                    ptNvodRefDesc++;
                }
            }
            else if (TIME_SHIFTED_SERVICE_DESCRIPTOR_TAG == u8DescTag)
            {
                if (u8MemCntFlag != 0)
                {
                    u16NvodTshDescCnt++;
                }
                else
                {
                    s32RetErr = parse_time_shifted_service_descriptor(pu8DataPtr, ptNvodTshDesc);
                    if( PV_SUCCESS != s32RetErr )
                    {
                        psisi_section_free( ptSDTSection );
                        return s32RetErr;
                    }
                    if (NULL == ptService->ptNvodTimeShiftDesc)
                    {
                        ptService->ptNvodTimeShiftDesc = ptNvodTshDesc;
                    }
                    ptNvodTshDesc++;
                }
            }
            else
            {
                if (u8MemCntFlag != 0)
                {
                    u16OtherDescCnt++;
                    u16BytesCnt += u8DescLen;
                }
                else
                {
                    ptOtherDesc->u8Tag = u8DescTag;
                    ptOtherDesc->u8Len = u8DescLen;
                    if (u8DescLen != 0)
                    {
                        memcpy(pu8Bytes, pu8DataPtr+2, u8DescLen);
                        ptOtherDesc->pu8Data = pu8Bytes;
                        pu8Bytes += u8DescLen;
                    }
                    else
                    {
                        ptOtherDesc->pu8Data = NULL;
                    }

                    if (NULL == ptService->ptDesc)
                    {
                        ptService->ptDesc = ptOtherDesc;
                    }
                    ptService->u16OtherDescNum++;
                    ptOtherDesc++;
                }
            }

            pu8DataPtr += (u8DescLen + 2);
            s16DescLoopLen -= (u8DescLen + 2);
        }

        ptService++;
    }

    if (u8MemCntFlag != 0)
    {
        /* calculate memory size finish, goto really parse phase */
        u8MemCntFlag = 0;
        goto parse_begin;
    }
    else
    {
        ptTable->ppSection[ptSDT_Head->sec_num] = ptSDTSection;
        ptTable->u16RecievedNum++;
    }

    return PV_SUCCESS;
}