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

📄 dsmcc.cpp

📁 数字电视中间件小型库
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include  <string.h>
#include "dsmcc.h"

bool DSM_CC::parse(DownloadInfoIndication& dii, uint8_t* buffer) {
    if(!parse(dii.header, buffer)) {
        return false;
    }

    buffer += dii.header.flat_size();   // skipping 12 bytes, the length of the header

    dii.download_id = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];    dii.block_size  = (buffer[4] << 8) | buffer[5];
    #ifdef DSM_CC_STRICT

        // All of this is dictated by ETSI TR 101 202 and/or the MHEG Profile 1.06

        if(dii.block_size > DSM_CC_MAX_BLOCK_SIZE) {
            return false;
        }

        // window_size
        if(buffer[6] != 0x00) {
            return false;
        }

        // ack_period
        if(buffer[7] != 0x00) {
            return false;
        }

        // tc_download_window
        if(buffer[8] != 0x00 || buffer[9] != 0x00 || buffer[10] != 0x00 || buffer[11] != 0x00) {
            return false;
        }

        // tc_download_scenario is unused (4 bytes)

        // compatibility_descriptor
        if(buffer[16] != 0x00 || buffer[17] != 0x00) {
            return false;
        }
    #endif    dii.num_modules = (buffer[18] << 8) | buffer[19];

    return true;
}

bool DSM_CC::parse(MessageHeader& header, uint8_t* buffer) {

    header.protocol_discriminator = buffer[0];

    #ifdef DSM_CC_STRICT
        if(header.protocol_discriminator != 0x11) { // as per TR 101 202
            return false;
        }
    #endif

    header.dsmcc_type = buffer[1];

    #ifdef DSM_CC_STRICT
        if(header.dsmcc_type != 0x03) { // as per TR 101 202
            return false;
        }
    #endif

    header.message_id = (buffer[2] << 8) | buffer[3];

    #ifdef DSM_CC_STRICT
        if(header.message_id < 0x1001 || header.message_id > 0x1006) { // as per ISO 13818-6
            return false;
        }
    #endif

    header.transaction_id = (buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];

    #ifdef DSM_CC_STRICT
        // reserved field
        if(buffer[8] != 0xff) {
            return false;
        }
    #endif

    header.adaptation_length = buffer[9];
    header.message_length = (buffer[10] << 8) | buffer[11];

    #ifdef DSM_CC_STRICT
        // The MHEG profile says we may ignore this
        if(header.adaptation_length != 0) {
            return false;
        }
    #endif

    return true;
}

bool DSM_CC::parse(DownloadDataBlock& block, uint8_t* buffer) {

    if(!parse(block.header, buffer)) {
        return false;
    }

    // Header length = 12 bytes + adaptation header length
    buffer += (12 + block.header.adaptation_length);

    block.module_id = (buffer[0] << 8) | buffer[1];
    block.module_version = buffer[2];

    #ifdef DSM_CC_STRICT
        // Check "reserved" field, must be 0xff
        if(buffer[3] != 0xff) {
            return false;
        }
    #endif

    block.block_number = (buffer[4] << 8) | buffer[5];

    // Length of payload that follows: header.message_length() - header.adaptation_length() - 6 bytes we just parsed
    block.payload_size    = block.header.message_length - block.header.adaptation_length - 6;
    block.payload_pointer = buffer + 6;

    return true;
}

DSM_CC::ModuleTracker::ModuleTracker() :
    have_module_info(false),
    received_blocks_count(0),
    received_blocks(0), contents(0) {}
    
DSM_CC::ModuleTracker::~ModuleTracker() {
    if(received_blocks) {
        delete[] received_blocks;
    }
    if(contents) {
        delete[] contents;
    }
}


void DSM_CC::ModuleTracker::SetParameters(const tracked_module_t& mod) {
    if(have_module_info) {
        return;
    }

    tracked_module = mod;

    // We just need to allocate memory for the received_blocks flags and the contents

    if(tracked_module.num_blocks > 0) {
        size_t rb_size = mod.num_blocks / 32 + 1; // if num_blocks % 32 == 0 we could save the +1 but who cares?
        received_blocks = new uint32_t[rb_size];

        if(received_blocks == 0) {
            return;
        }

        contents = new uint8_t[mod.module_size];

        if(contents == 0) {
            return;
        }
    }

    have_module_info = true;
}

bool DSM_CC::ModuleTracker::InterestedInObject(uint32_t object_key, uint8_t object_key_length) {
    uint32_t key_mask  = 0xffffffff << ((4 - object_key_length) * 8);
    uint64_t key = (static_cast<uint64_t>(key_mask) << 32) | (object_key & key_mask);

    for(std::vector<uint64_t>::const_iterator i = interesting_objects.begin(); i != interesting_objects.end(); ++i) {
        if(*i == key) {
            return true;
        }
    }

    return false;
}

void DSM_CC::ModuleTracker::MarkObject(uint32_t object_key, uint8_t object_key_length, bool mark) {
    uint32_t key_mask  = 0xffffffff << ((4 - object_key_length) * 8);
    uint64_t key = (static_cast<uint64_t>(key_mask) << 32) | (object_key & key_mask);

    for(std::vector<uint64_t>::iterator i = interesting_objects.begin(); i != interesting_objects.end(); ++i) {
        if(*i == key) {
            if(mark) {
                return;
            }
            else {
                // To remove this element, copy the last element on top of it and then pop the last element
                *i = interesting_objects.back();
                interesting_objects.pop_back();
            }
        }
    }
    
    // It didn't exist, so if we want to add it push it at the end of the vector
    if(mark) {
        #ifdef DSM_CC_TRACE_MODULETRACKER
            DSM_CC_TRACE_NUM("ModuleTracker", "Now interested in object with mask", key_mask, "8");
            DSM_CC_TRACE_NUM("ModuleTracker", "Now interested in object with key ", (object_key & key_mask), "8");
        #endif
        interesting_objects.push_back(key);
    }
}

bool DSM_CC::ModuleTracker::ProcessDDB(const DownloadDataBlock& block) {
    if(!have_module_info) {
        return true;
    }

    if(block.module_id != tracked_module.module_id) {
        #ifdef DSM_CC_TRACE_MODULETRACKER
            DSM_CC_TRACE_NUM("ModuleTracker", "Bad module id received, was expecting", tracked_module.module_id, "4");
            DSM_CC_TRACE_NUM("ModuleTracker", "Bad module id received, instead received", block.module_id, "4");
        #endif
        return false;
    }

    if(block.module_version != tracked_module.module_version) {
        #ifdef DSM_CC_TRACE_MODULETRACKER
            DSM_CC_TRACE_NUM("ModuleTracker", "For module_id", tracked_module.module_id, "4");
            DSM_CC_TRACE_NUM("ModuleTracker", "Bad module version received, was expecting", tracked_module.module_version, "4");
            DSM_CC_TRACE_NUM("ModuleTracker", "Bad module version received, instead received", block.module_version, "4");
        #endif        return true;    }

    uint32_t array_offset = block.block_number & 0xffffffe0;
    uint32_t mask         = 1 << (block.block_number & 0x1f);

    if(received_blocks[array_offset] & mask) {
        // We already have this one
        return true;
    }

    if(block.block_number < tracked_module.num_blocks - 1) {
        if(block.payload_size != tracked_module.block_size) {
            #ifdef DSM_CC_TRACE_MODULETRACKER
                DSM_CC_TRACE_NUM("ModuleTracker", "Bad block payload size, was expecting", tracked_module.block_size, "8");

⌨️ 快捷键说明

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