Addded ASN1 CHOISE handling to use the selected union member to display message details.
git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4361 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -11,7 +11,7 @@ char *enum_type_get_name_from_value(struct types_s *type, uint32_t value)
|
||||
char *enum_name = "UNKNOWN";
|
||||
types_t *enum_value;
|
||||
|
||||
/* Loop on eache enumeration values */
|
||||
/* Loop on each enumeration values */
|
||||
for (enum_value = type->child; enum_value; enum_value = enum_value->next) {
|
||||
if (value == enum_value->init_value) {
|
||||
enum_name = enum_value->name;
|
||||
@@ -34,6 +34,7 @@ int enum_type_dissect_from_buffer(
|
||||
|
||||
for (values = type->child; values; values = values->next) {
|
||||
if (value == values->init_value) {
|
||||
values->parent = type;
|
||||
values->type_dissect_from_buffer(
|
||||
values, ui_set_signal_text_cb, user_data, buffer, offset, parent_offset,
|
||||
type->name == NULL ? indent: indent+4);
|
||||
|
||||
@@ -6,10 +6,13 @@
|
||||
#include "enum_value_type.h"
|
||||
#include "ui_interface.h"
|
||||
|
||||
uint32_t last_enum_value;
|
||||
|
||||
int enum_value_dissect_from_buffer(
|
||||
struct types_s *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data,
|
||||
buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent)
|
||||
{
|
||||
struct types_s *type_parent = NULL;
|
||||
uint32_t value = 0;
|
||||
|
||||
DISPLAY_PARSE_INFO("enum_value", type->name, offset, parent_offset);
|
||||
@@ -19,6 +22,24 @@ int enum_value_dissect_from_buffer(
|
||||
int length = 0;
|
||||
char cbuf[50 + strlen(type->name)];
|
||||
|
||||
/* Search for enum variable name and check if it is used in association with a union type */
|
||||
{
|
||||
if (type->parent != NULL) {
|
||||
/* Ignore ENUMERATION and TYPEDEF parents */
|
||||
for (type_parent = type->parent; (type_parent != NULL) && ((type_parent->type == TYPE_ENUMERATION) || (type_parent->type == TYPE_TYPEDEF));
|
||||
type_parent = type_parent->parent) {
|
||||
}
|
||||
}
|
||||
if ((type_parent != NULL) && (type_parent->name != NULL) && (strcmp(type_parent->name, "present") == 0))
|
||||
{
|
||||
/* ASN1 union, keep the "present" member */
|
||||
last_enum_value = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_enum_value = 0;
|
||||
}
|
||||
}
|
||||
sprintf(cbuf, "(0x%08x) %s;\n", value, type->name);
|
||||
length = strlen(cbuf);
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#ifndef ENUM_VALUE_TYPE_H_
|
||||
#define ENUM_VALUE_TYPE_H_
|
||||
|
||||
extern uint32_t last_enum_value;
|
||||
|
||||
int enum_value_dissect_from_buffer(
|
||||
struct types_s *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data,
|
||||
buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent);
|
||||
|
||||
@@ -24,55 +24,67 @@ int field_dissect_from_buffer(
|
||||
CHECK_FCT(buffer_has_enouch_data(buffer, parent_offset + offset, type->size / 8));
|
||||
|
||||
if (type->bits == -1) {
|
||||
if (type->child != NULL) {
|
||||
/* Ignore TYPEDEF children */
|
||||
for (type_child = type->child; type_child != NULL && type_child->type == TYPE_TYPEDEF; type_child =
|
||||
type_child->child) {
|
||||
}
|
||||
|
||||
if (type_child->type == TYPE_ARRAY) {
|
||||
struct types_s *type_array_child;
|
||||
if ((type->name != NULL) && (strcmp(type->name, "_asn_ctx") == 0)) {
|
||||
/* Hide ASN1 asn_struct_ctx_t struct that hold context for parsing across buffer boundaries */
|
||||
/*
|
||||
INDENTED_STRING(cbuf, indent, sprintf(cbuf, ".asn_ctx ...\n"));
|
||||
length = strlen (cbuf);
|
||||
|
||||
ui_set_signal_text_cb(user_data, cbuf, length);
|
||||
*/
|
||||
}
|
||||
else {
|
||||
if (type->child != NULL) {
|
||||
/* Ignore TYPEDEF children */
|
||||
for (type_array_child = type_child->child;
|
||||
type_array_child != NULL && type_array_child->type == TYPE_TYPEDEF; type_array_child =
|
||||
type_array_child->child) {
|
||||
for (type_child = type->child; type_child != NULL && type_child->type == TYPE_TYPEDEF; type_child =
|
||||
type_child->child) {
|
||||
}
|
||||
|
||||
sprintf (array_info, "[%d]", type_child->size / type_array_child->size);
|
||||
if (type_child->type == TYPE_ARRAY) {
|
||||
struct types_s *type_array_child;
|
||||
|
||||
/* Ignore TYPEDEF children */
|
||||
for (type_array_child = type_child->child;
|
||||
type_array_child != NULL && type_array_child->type == TYPE_TYPEDEF; type_array_child =
|
||||
type_array_child->child) {
|
||||
}
|
||||
|
||||
sprintf (array_info, "[%d]", type_child->size / type_array_child->size);
|
||||
}
|
||||
else {
|
||||
array_info[0] = '\0';
|
||||
}
|
||||
|
||||
DISPLAY_TYPE("Fld");
|
||||
INDENTED_STRING(cbuf, indent, sprintf(cbuf, ".%s%s = ", type->name ? type->name : "Field", array_info));
|
||||
length = strlen (cbuf);
|
||||
|
||||
ui_set_signal_text_cb(user_data, cbuf, length);
|
||||
|
||||
indent_child = indent;
|
||||
if (type_child->type == TYPE_ARRAY || type_child->type == TYPE_STRUCT || type_child->type == TYPE_UNION) {
|
||||
DISPLAY_BRACE(ui_set_signal_text_cb(user_data, "{", 1);)
|
||||
ui_set_signal_text_cb(user_data, "\n", 1);
|
||||
indent_child += 4;
|
||||
}
|
||||
if (type_child->type == TYPE_FUNDAMENTAL || type_child->type == TYPE_POINTER) {
|
||||
indent_child = 0;
|
||||
}
|
||||
|
||||
type->child->parent = type;
|
||||
CHECK_FCT(type->child->type_dissect_from_buffer(
|
||||
type->child, ui_set_signal_text_cb, user_data, buffer,
|
||||
parent_offset, offset + type->offset, indent_child));
|
||||
|
||||
DISPLAY_BRACE(
|
||||
if (type_child->type == TYPE_ARRAY || type_child->type == TYPE_STRUCT || type_child->type == TYPE_UNION) {
|
||||
DISPLAY_TYPE("Fld");
|
||||
INDENTED_STRING(cbuf, indent, sprintf(cbuf, "};\n"));
|
||||
length = strlen (cbuf);
|
||||
|
||||
ui_set_signal_text_cb(user_data, cbuf, length);
|
||||
});
|
||||
}
|
||||
else {
|
||||
array_info[0] = '\0';
|
||||
}
|
||||
|
||||
DISPLAY_TYPE("Fld");
|
||||
INDENTED_STRING(cbuf, indent, sprintf(cbuf, ".%s%s = ", type->name ? type->name : "Field", array_info));
|
||||
length = strlen (cbuf);
|
||||
|
||||
ui_set_signal_text_cb(user_data, cbuf, length);
|
||||
|
||||
indent_child = indent;
|
||||
if (type_child->type == TYPE_ARRAY || type_child->type == TYPE_STRUCT || type_child->type == TYPE_UNION) {
|
||||
DISPLAY_BRACE(ui_set_signal_text_cb(user_data, "{", 1);)
|
||||
ui_set_signal_text_cb(user_data, "\n", 1);
|
||||
indent_child += 4;
|
||||
}
|
||||
if (type_child->type == TYPE_FUNDAMENTAL || type_child->type == TYPE_POINTER) {
|
||||
indent_child = 0;
|
||||
}
|
||||
|
||||
CHECK_FCT(type->child->type_dissect_from_buffer(
|
||||
type->child, ui_set_signal_text_cb, user_data, buffer,
|
||||
parent_offset, offset + type->offset, indent_child));
|
||||
|
||||
DISPLAY_BRACE(
|
||||
if (type_child->type == TYPE_ARRAY || type_child->type == TYPE_STRUCT || type_child->type == TYPE_UNION) {
|
||||
DISPLAY_TYPE("Fld");
|
||||
INDENTED_STRING(cbuf, indent, sprintf(cbuf, "};\n"));
|
||||
length = strlen (cbuf);
|
||||
|
||||
ui_set_signal_text_cb(user_data, cbuf, length);
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -14,6 +14,7 @@ int typedef_dissect_from_buffer(
|
||||
|
||||
/* Simply call next_type */
|
||||
if (type->child != NULL) {
|
||||
type->child->parent = type;
|
||||
type->child->type_dissect_from_buffer(
|
||||
type->child, ui_set_signal_text_cb, user_data, buffer, offset, parent_offset, indent);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "rc.h"
|
||||
|
||||
#include "enum_value_type.h"
|
||||
#include "union_type.h"
|
||||
#include "../libresolver/locate_root.h"
|
||||
#include "ui_interface.h"
|
||||
@@ -34,6 +35,7 @@ int union_dissect_from_buffer(
|
||||
{
|
||||
int length = 0;
|
||||
char cbuf[200];
|
||||
int union_child = 0;
|
||||
|
||||
DISPLAY_PARSE_INFO("union", type->name, offset, parent_offset);
|
||||
|
||||
@@ -45,6 +47,21 @@ int union_dissect_from_buffer(
|
||||
// INDENTED(stdout, indent, fprintf(stdout, "<%s>\n", type->name));
|
||||
DISPLAY_TYPE("Uni");
|
||||
INDENTED_STRING(cbuf, indent, sprintf(cbuf, "%s {\n", type->name));
|
||||
|
||||
if (type->parent != NULL)
|
||||
{
|
||||
if ((type->parent->name != NULL) && (strcmp(type->parent->name, "choice") == 0))
|
||||
{
|
||||
/* ASN1 union */
|
||||
|
||||
if ((last_enum_value > 0) && (last_enum_value <= type->nb_members))
|
||||
{
|
||||
union_child = last_enum_value - 1;
|
||||
|
||||
g_debug("ASN1 union \"%s\' detected, use member %d", type->name, union_child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
length = strlen (cbuf);
|
||||
@@ -52,9 +69,9 @@ int union_dissect_from_buffer(
|
||||
ui_set_signal_text_cb(user_data, cbuf, length);
|
||||
|
||||
/* Only dissect the first field present in unions */
|
||||
if (type->members_child[0] != NULL)
|
||||
type->members_child[0]->type_dissect_from_buffer(
|
||||
type->members_child[0], ui_set_signal_text_cb, user_data, buffer,
|
||||
if (type->members_child[union_child] != NULL)
|
||||
type->members_child[union_child]->type_dissect_from_buffer(
|
||||
type->members_child[union_child], ui_set_signal_text_cb, user_data, buffer,
|
||||
offset, parent_offset, type->name == NULL ? indent : indent + 4);
|
||||
|
||||
if (type->name) {
|
||||
|
||||
Reference in New Issue
Block a user