⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsmcc.h

📁 数字电视中间件小型库
💻 H
📖 第 1 页 / 共 3 页
字号:
                        // Skip first 22 bytes: the first 20 bytes must be 0xff, 21 and 22 must be 0x00                        // Skip next two bytes: they hold the message length, our parser doesn't need it                            // Next 4 bytes (24 - 27) hold the datatype_id_length. Not relevant to us here.                            // What we want to do is check the first (and if it's an OC, only) 4 bytes of                        // the datatype_id, and decide if this is an OC. Normally this would not be needed                        // if enough descriptors were being given for the streams, but I 've seen many                        // cases where they are not.    
                        buffer += header.flat_size();                        uint32_t datatype_id = (buffer[28] << 24) | (buffer[29] << 16) | (buffer[30] << 8) | buffer[31];                            // TR 101 202 specifies that in an Object Carousel, the identifier here will be                         // the null-terminated string "srg" ALWAYS, so the check is quite simple.                        if (datatype_id != BIOP_ALIAS_TYPE_ID_SRG) {                            return false;                        }                        else {                            BIOP::ServiceGatewayInfo sgi;                            if(!parse(sgi, &buffer[24])) {
                                return false;                            }
                            if(!ProcessDSI(component_tag, sgi, table_id_ext)) {
                                return false;
                            }                        }                        break;                }
                return true;            }

            bool StreamNeeded() {
                return !streams_needed.empty();
            }

            uint8_t StreamTag() {
                if(!StreamNeeded()) {
                    return 0;
                }

                uint8_t tag = streams_needed.back();
                streams_needed.pop_back();
                return tag;
            }

        private:

            bool Track(uint32_t download_id, uint16_t table_id_ext) {
                if(download_trackers.contains(download_id)) {
                    return false;
                }
            
                dsmcc_trace("[CarouselTracker] Now tracking download_id = 0x%08x, current table_id_ext is 0x%04x\n", download_id, table_id_ext);
                download_trackers[download_id] = new DownloadTracker(download_id);
                download_stats[download_id].last_table_id_ext = table_id_ext;
                return true;
            }

            bool Untrack(uint32_t download_id) {
                if(!download_trackers.contains(download_id)) {
                    return false;
                }
                
                delete download_trackers[download_id];
                download_trackers.remove(download_id);
                download_stats.remove(download_id);
                return true;
            }

            bool Reset(uint32_t download_id, uint16_t table_id_ext) {
                if(Untrack(download_id)) {
                    return Track(download_id, table_id_ext);
                }
                else {
                    return false;
                }
            }

            uint8_t* ModuleGetBuffer(uint32_t download_id, uint16_t module_id) const {
                return CompletedModule(download_id, module_id) ? download_trackers[download_id]->ModuleGetBuffer(module_id) : 0;
            }

            tracked_module_t ModuleGetParameters(uint32_t download_id, uint16_t module_id) const {
                return download_trackers.contains(download_id) ? download_trackers[download_id]->ModuleGetParameters(module_id) : DSM_CC::tracked_module_t();
            }

            bool ModuleHaveParameters(uint32_t download_id, uint16_t module_id) const {
                return download_trackers.contains(download_id) ? download_trackers[download_id]->ModuleHaveParameters(module_id) : false;
            }

            uint8_t* CopyModuleContents(uint32_t download_id, uint16_t module_id) const {
                uint8_t* data(0);
            
                if(!download_trackers.contains(download_id)) {
                    return data;
                }
            
                uint8_t* source = ModuleGetBuffer(download_id, module_id);

                if(source == 0 || !ModuleHaveParameters(download_id, module_id)) {
                    return data;
                }

                tracked_module_t module = ModuleGetParameters(download_id, module_id);

                if(module.z_compression_method == 0) {
                    // That's easy
                    data = new uint8_t[module.module_size];
                    if(data == 0) {
                        return data;
                    }
            
                    memcpy(data, source, module.module_size);
                    return data;
                }
            
                #ifdef Z_OK
                    data = new uint8_t[module.z_original_size];
                    if(data == 0) {
                        return data;
                    }
                
                    z_stream zstream;
                    zstream.next_in   = source;
                    zstream.avail_in  = module.module_size;
                    zstream.next_out  = data;
                    zstream.avail_out = module.z_original_size;
                    zstream.zalloc    = Z_NULL;
                    zstream.zfree     = Z_NULL;
                    zstream.opaque    = Z_NULL;
                
                    int status = inflateInit(&zstream);
                
                    if(status != Z_OK) {
                        delete[] data;
                        return data = 0;
                    }
                
                    status = inflate(&zstream, Z_FINISH);
                
                    if(status != Z_STREAM_END) {
                        delete[] data;
                        return data = 0;
                    }
                
                    status = inflateEnd(&zstream);
                
                    if(status != Z_OK) {
                        delete[] data;
                        return data = 0;
                    }
                
                    return data;
                
                #endif
            
                // This is reached if zlib is not included when building MythTV
                // Tough luck, only uncompressed modules can be processed if so
                return data;

            }

            bool ProcessDDB(uint8_t component_tag, const DownloadDataBlock& block) {
                (void)component_tag;

                if(!download_trackers.contains(block.header.download_id)) {
                    dsmcc_trace("[CarouselTracker] Rejected DDB for unknown download_id = 0x%08x\n", block.header.download_id);
                    return false;
                }

                // If the module has been completed, we don't need to do anything
                if(CompletedModule(block.header.download_id, block.module_id)) {                    return true;                }
                if(!download_trackers[block.header.download_id]->ProcessDDB(block)) {
                    return false;
                }

                bool success = true;

                // Now, maybe receiving this block resulted in the module becoming complete?
                if(CompletedModule(block.header.download_id, block.module_id)) {                            tracked_module_t module = ModuleGetParameters(block.header.download_id, block.module_id);                    uint8_t* data = CopyModuleContents(block.header.download_id, block.module_id);

                    uint32_t size = module.z_compression_method ? module.z_original_size : module.module_size;                                if(data == 0) {
                        #ifdef DSM_CC_TRACE_CAROUSELTRACKER
                            DSM_CC_TRACE_NUM("CarouselTracker", "Failed to allocate memory for completed module with id", block.module_id, "4");
                        #endif
                        return false;
                    }
                    // One by one, process the BIOP messages in this module                    uint8_t* currentmessage = data;
                    while(currentmessage < data + size) {                        BIOP::MessageHeader header;                        BIOP::parse(header, currentmessage);                                    uint32_t currentsize = header.flat_size() + header.message_body_length;                                    switch(header.object_kind) {                            case BIOP_ALIAS_TYPE_ID_SRG:                                {                                    BIOP::ServiceGateway srg;                                    BIOP::parse(srg, currentmessage);                                                                            success = ObjectArrived(block.header.download_id, block.module_id, srg);                                    break;                                }                            case BIOP_ALIAS_TYPE_ID_DIR:                                {                                    BIOP::DirectoryMessage dm;                                    BIOP::parse(dm, currentmessage);                                                success = ObjectArrived(block.header.download_id, block.module_id, dm);                                    break;                                }                            case BIOP_ALIAS_TYPE_ID_FIL:                                {                                    BIOP::FileMessage fm;                                    BIOP::parse(fm, currentmessage);                                                success = ObjectArrived(block.header.download_id, block.module_id, fm);                                    break;                                }
                            case BIOP_ALIAS_TYPE_ID_STR:                                {                                    BIOP::StreamMessage str;                                    BIOP::parse(str, currentmessage);                                                success = ObjectArrived(block.header.download_id, block.module_id, str);                                    break;                                }
                            case BIOP_ALIAS_TYPE_ID_STE:                                {                                    BIOP::StreamEventMessage ste;                                    BIOP::parse(ste, currentmessage);                                                success = ObjectArrived(block.header.download_id, block.module_id, ste);                                    break;                                }                            default:
                                #ifdef DSM_CC_TRACE_CAROUSELTRACKER
                                    DSM_CC_TRACE_NUM("CarouselTracker", "Unknown BIOP object kind", header.object_kind, "8");
                                #endif
                                success = false;                        }
                        if(!success) {
                            break;
                        }
                        currentmessage += currentsize;                    }                    delete[] data;                }
                //return true;
                return success;

            }

            bool ProcessDII(uint8_t component_tag, const DownloadInfoIndication& indication, const BIOP::DIIModuleLoopItem& mitem) {
                if(!download_trackers.contains(indication.download_id)) {
                    return false;
                }

                if(download_trackers[indication.download_id]->ProcessDII(indication, mitem)) {
                    #ifdef DSM_CC_TRACE_CAROUSELTRACKER
                        DSM_CC_TRACE_NUM("CarouselTracker", "Accepted from DII module_id", mitem.module_id, "8");
                    #endif
            
                    // The download tracker has accepted it as interesting, therefore we must begin
                    // accepting DDBs for this module. Also, mark the current version of the download
                    // control message as already available (not interesting anymore)
                    MarkDownloadData(mitem.module_info.tap.assoc_tag, BIOP::REQUESTED);
                    MarkDownloadControl(component_tag, indication.header.transaction_id, BIOP::AVAILABLE);
            
                    return true;
                }
            
                return false;

            }

            bool ProcessDSI(uint8_t component_tag, const BIOP::ServiceGatewayInfo& sgi, uint16_t table_id_ext) {
                #ifdef DSM_CC_STRICT
                    if(component_tag == 0) {
                        DSM_CC_TRACE_GENERAL("CarouselTracker", "ERROR: Incoming DSI message has no component_tag identity");
                        return false;
                    }
                #endif

                if(sgi.ior.profiles[0].id_tag != BIOP_PROFILE_ID_BIOP) {
                   return false;
                }
                const BIOP::BIOPProfile& profile = sgi.ior.profiles[0].biop;
                

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -