📄 dsmcc.cpp
字号:
#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 + -