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