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

📄 dsmcc_biop.cpp

📁 数字电视中间件小型库
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    #ifdef BIOP_STRICT
        if(ste.header.object_kind != BIOP_ALIAS_TYPE_ID_STE) {
            return false;
        }
    #endif

    // Get the event names from the objectInfo bytes
    uint8_t oi_index = 12 + ste.header.object_info[0];

    uint16_t eventnames_count = (ste.header.object_info[oi_index] << 8) | ste.header.object_info[oi_index + 1];
    oi_index += 2;

    ste.event_ids.resize(eventnames_count);
    ste.event_names.resize(eventnames_count);

    for(uint16_t i = 0; i < eventnames_count; ++i) {
        std::string event_name;
        uint8_t event_name_length = ste.header.object_info[oi_index++];
        event_name.assign(ste.header.object_info.begin() + oi_index, ste.header.object_info.begin() + oi_index + event_name_length - 1);
        ste.event_names[i] = event_name;
        #ifdef BIOP_TRACE_STREAMEVENTMESSAGE
            BIOP_TRACE_STR("StreamEventMessage", "event_name", event_name.c_str());
        #endif
    }

    buffer += ste.header.flat_size();

    uint8_t taps_count = buffer[0];

    #ifdef BIOP_TRACE_STREAMEVENTMESSAGE
        BIOP_TRACE_NUM("StreamEventMessage", "taps_count", taps_count, "2");
    #endif

    if(taps_count < 1) {
        return false;
    }

    // Shift the buffer and read the one mandatory tap
    ++buffer;
    BIOP_TRACE_INDENT(1);
    if(!parse(ste.tap, buffer)) {
        return false;
    }
    BIOP_TRACE_INDENT(-1);

    #ifdef BIOP_STRICT
        if(ste.tap.use != BIOP_PROGRAM_USE) {
            return false;
        }
    #endif    

    // Now shift are loop over all other taps to tell us what we 're missing out on
    buffer += ste.tap.flat_size();

    BIOP_TRACE_INDENT(1);
    for(uint8_t i = 1; i < taps_count; ++i) {
        Tap dummy_tap;
        if(!parse(dummy_tap, buffer)) {
            return false;
        }
        buffer += dummy_tap.flat_size();
        BIOP_TRACE_GENERAL("StreamEventMessage", "Skipped one tap beyond the first");
    }
    BIOP_TRACE_INDENT(-1);

    // Finally, read the event ids
    uint8_t eventids_count = buffer[0];
    #ifdef BIOP_STRICT
        if(eventnames_count != eventids_count) {
            BIOP_TRACE_GENERAL("StreamEventMessage", "event_names_count and event_ids_count mismatch");
            return false;
        }
    #endif

    ++buffer;

    for(uint16_t i = 0; i < eventnames_count; ++i) {
        uint16_t event_id = (buffer[0] << 8) | buffer[1];
        ste.event_ids[i] = event_id;
        buffer += 2;
        #ifdef BIOP_TRACE_STREAMEVENTMESSAGE
            BIOP_TRACE_NUM("StreamEventMessage", "event_id", event_id, "4");
        #endif
    }

    return true;
}

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

    uint32_t i, temp;

    #ifdef BIOP_STRICT
        header.magic = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
        if(header.magic != BIOP_MAGIC_BIOP) {
            return false;
        }
    
        // TR 101 202 dictates:
        header.biop_version_major = buffer[4]; // must be 0x01
        header.biop_version_minor = buffer[5]; // must be 0x00
        header.byte_order         = buffer[6]; // must be 0x00
        header.message_type       = buffer[7]; // must be 0x00
    
        if(((header.biop_version_major << 24) | (header.biop_version_minor << 16) | (header.byte_order << 8) | header.message_type) != 0x01000000) {
            return false;
        }
    #endif

    header.message_size = (buffer[8] << 24) | (buffer[9] << 16) | (buffer[10] << 8) | buffer[11];

    temp = buffer[12];
    header.object_key.resize(temp);

    #ifdef BIOP_TRACE_MESSAGEHEADER
        BIOP_TRACE_NUM("MessageHeader", "message_size", header.message_size, "8");
        BIOP_TRACE_NUM("MessageHeader", "object_key_length", temp, "2");
    #endif

    #ifdef BIOP_STRICT
        if(temp > 4) {  // TR 101 202 page 37
            return false;
        }
    #endif

    // Reposition the buffer to start reading object key
    buffer += 13;
    for(i = 0; i < temp; ++i) {
        header.object_key[i] = buffer[i];
    }

    #ifdef BIOP_TRACE_MESSAGEHEADER
        BIOP_TRACE_DUMP("MessageHeader", "object_key", buffer, header.object_key.size());
    #endif

    buffer += temp;
    temp = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];

    #ifdef BIOP_STRICT
        if(temp != 4) { // TR 101 202
            return false;
        }
    #endif

    // Reposition the buffer to start reading object kind info
    buffer += 4;
    header.object_kind = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];

    #ifdef BIOP_TRACE_MESSAGEHEADER
        BIOP_TRACE_NUM("MessageHeader", "object_kind_length", temp, "8");
        BIOP_TRACE_NUM("MessageHeader", "object_kind", header.object_kind, "8");
    #endif

    // Reposition the buffer to start reading object info
    buffer += temp;

    temp = (buffer[0] << 8) | buffer[1];
    header.object_info.resize(temp);

    buffer += 2;
    for(i = 0; i < temp; ++i) {
        header.object_info[i] = buffer[i];
    }

    #ifdef BIOP_TRACE_MESSAGEHEADER
        BIOP_TRACE_NUM("MessageHeader", "object_info_length", header.object_info.size(), "4");
        BIOP_TRACE_DUMP("MessageHeader", "object_info", buffer, header.object_info.size());
    #endif

    buffer += temp;
    temp = buffer[0];
    header.service_context_list.resize(temp);

    #ifdef BIOP_TRACE_MESSAGEHEADER
        BIOP_TRACE_NUM("MessageHeader", "service_context_list_length", temp, "2");
    #endif

    // Reposition the buffer to start reading service context list
    ++buffer;
    BIOP_TRACE_INDENT(1);
    for(i = 0; i < temp; ++i) {
        BIOP::ServiceContext servcon;
        if(!parse(servcon, buffer)) {
            return false;
        }
        header.service_context_list[i] = servcon;
        buffer += servcon.flat_size();
    }
    BIOP_TRACE_INDENT(-1);

    header.message_body_length = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];

    #ifdef BIOP_TRACE_MESSAGEHEADER
        BIOP_TRACE_NUM("MessageHeader", "message_body_length", header.message_body_length, "8");
    #endif

    return true;
}

bool BIOP::parse(ServiceContext& sc, uint8_t* buffer) {
    sc.id = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];

    uint16_t data_length = (buffer[4] << 8) | buffer[5];
    sc.data.resize(data_length);

    buffer += 6;
    for(int i = 0; i < data_length; ++i) {
        sc.data[i] = buffer[i];
    }

    #ifdef BIOP_TRACE_SERVICECONTEXT
        BIOP_TRACE_NUM("ServiceContext", "id", sc.id, "8");
        BIOP_TRACE_NUM("ServiceContext", "data_length", data_length, "4");
        BIOP_TRACE_DUMP("ServiceContext", "data", buffer, data_length);
    #endif

    return true;
}

bool BIOP::parse(Binding& bind, uint8_t* buffer) {
    BIOP_TRACE_INDENT(1);
    if(!parse(bind.name, buffer)) {
        return false;
    }
    BIOP_TRACE_INDENT(-1);

    buffer += bind.name.flat_size();

    bind.type = buffer[0];
    ++buffer;

    #ifdef BIOP_TRACE_BINDING
        BIOP_TRACE_NUM("Binding", "type", bind.type, "2");
    #endif

    BIOP_TRACE_INDENT(1);
    if(!parse(bind.ior, buffer)) {
        return false;
    }
    BIOP_TRACE_INDENT(-1);

    buffer += bind.ior.flat_size();

    uint16_t object_info_length = (buffer[0] << 8) | buffer[1];
    buffer += 2;

    bind.object_info.resize(object_info_length);
    for(int i = 0; i < object_info_length; ++i) {
        bind.object_info[i] = buffer[i];
    }

    #ifdef BIOP_TRACE_BINDING
        BIOP_TRACE_NUM("Binding", "object_info_length", object_info_length, "4");
        BIOP_TRACE_DUMP("Binding", "object_info", buffer, object_info_length);
    #endif

    return true;
}

bool BIOP::parse(Name& name, uint8_t* buffer) {

    uint8_t components = buffer[0];
    ++buffer;

    #ifdef BIOP_TRACE_NAME
        BIOP_TRACE_NUM("Name", "name_components_count", components, "2");
    #endif

    #ifdef BIOP_STRICT
        // TR 101 202 p37
        if(components != 1) {
            return false;
        }
    #endif

    uint8_t id_length = buffer[0];
    name.id.resize(id_length);

    ++buffer;
    for(uint8_t i = 0; i < id_length; ++i) {
        name.id[i] = buffer[i];
    }

    #ifdef BIOP_TRACE_NAME
        BIOP_TRACE_NUM("NameComponent", "id_length", id_length, "2");
        BIOP_TRACE_DUMP("NameComponent", "id", buffer, id_length);
    #endif

    buffer += id_length;

    uint8_t kind_length = buffer[0];
    name.kind.resize(kind_length);

    ++buffer;
    for(uint8_t i = 0; i < kind_length; ++i) {
        name.kind[i] = buffer[i];
    }

    #ifdef BIOP_TRACE_NAME
        BIOP_TRACE_NUM("NameComponent", "kind_length", kind_length, "4");
        BIOP_TRACE_DUMP("NameComponent", "kind", buffer, kind_length);
    #endif

    return true;
}

bool BIOP::parse(IOR& ior, uint8_t* buffer) {    uint32_t type_id_length = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];

    #ifdef BIOP_STRICT
        if(type_id_length != 4) {
            return false;
        }
    #endif

    buffer += 4;

    #ifdef BIOP_TRACE_IOR
        BIOP_TRACE_NUM("IOR", "type_id_length", type_id_length, "8");
        BIOP_TRACE_STR("IOR", "type_id", buffer);
    #endif

    for(uint32_t i = 0; i < type_id_length; ++i) {
        ior.type_id[i] = buffer[i];
    }

    // CDR alignment, pad type_id to a 4-byte boundary
    buffer += type_id_length + (type_id_length % 4 ? 4 - (type_id_length % 4) : 0);

    uint32_t tagged_profiles_count = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
    ior.profiles.resize(tagged_profiles_count);    buffer += 4;
    #ifdef BIOP_TRACE_IOR
        BIOP_TRACE_NUM("IOR", "tagged_profiles", tagged_profiles_count, "8");
    #endif

    for(uint32_t i = 0; i < tagged_profiles_count; ++i) {        uint32_t profile_id_tag      = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];        uint32_t profile_data_length = (buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
        #ifdef BIOP_TRACE_IOR
            BIOP_TRACE_NUM("IOR", "profile_id_tag", profile_id_tag, "8");
            BIOP_TRACE_NUM("IOR", "profile_data_length", profile_data_length, "8");
        #endif
    
        #ifdef BIOP_STRICT
            if(profile_id_tag & 0xfffffff0 != 0x49534f00) {
                return false;            }
        #endif
        ior.profiles[i].id_tag = profile_id_tag;

        BIOP_TRACE_INDENT(1);        switch(profile_id_tag & 0xf) {
            case 0x5:   // Lite Options Protocol profile
                printf("############### LITE OPTIONS PROFILE ###################");
                if(!BIOP::parse(ior.profiles[i].lite, buffer)) {
                    return false;
                }
                break;            case 0x6:   // BIOP profile
                if(!BIOP::parse(ior.profiles[i].biop, buffer)) {
                    return false;
                }                break;            default:
                #ifdef BIOP_TRACE_IOR
                    BIOP_TRACE_NUM("IOR", "Invalid profile_id_tag", profile_id_tag, "8");
                #endif
                return false;
        }
        BIOP_TRACE_INDENT(-1);        buffer += profile_data_length + 8;    }
    return true;

}
bool BIOP::parse(LiteOptionsProfile& prof, uint8_t* buffer) {
    return false;
}

bool BIOP::parse(BIOPProfile& prof, uint8_t* buffer) {

    #ifdef BIOP_STRICT
        uint32_t id_tag = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
        if(id_tag != BIOP_PROFILE_ID_BIOP) {
            return false;
        }
    #endif
    prof.data_length     = (buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
    prof.small_endian    = buffer[8];
    prof.component_count = buffer[9];

    #ifdef BIOP_TRACE_BIOPPROFILE
        BIOP_TRACE_NUM("BIOPProfile", "data_length", prof.data_length, "8");
        BIOP_TRACE_NUM("BIOPProfile", "data_byte_order", prof.small_endian, "2");
        BIOP_TRACE_NUM("BIOPProfile", "component_count", prof.component_count, "2");
    #endif
    
    #ifdef BIOP_STRICT
        if(prof.small_endian) { // TR 101 202 says it has to be big endian
            return false;
        }
    #endif

    buffer += 10;

    BIOP_TRACE_INDENT(1);
    for(int i = 0; i < prof.component_count; ++i) {
        uint32_t component_id_tag = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
        switch(component_id_tag) {
            case BIOP_COMPONENT_ID_CONNBIND:
                if(!parse(prof.conn_binder, buffer)) {
                    return false;
                }
                buffer += 5 + prof.conn_binder.data_length;
                break;
            case BIOP_COMPONENT_ID_OBJECTLOC:
                if(!parse(prof.object_location, buffer)) {
                    return false;
                }
                buffer += 5 + prof.object_location.data_length;
                break;
            default:
                return false;
                break;
        }
    }
    BIOP_TRACE_INDENT(-1);

    return true;
}

⌨️ 快捷键说明

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