Commit 113c5c37 authored by winckel's avatar winckel

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
parent c1088427
...@@ -11,7 +11,7 @@ char *enum_type_get_name_from_value(struct types_s *type, uint32_t value) ...@@ -11,7 +11,7 @@ char *enum_type_get_name_from_value(struct types_s *type, uint32_t value)
char *enum_name = "UNKNOWN"; char *enum_name = "UNKNOWN";
types_t *enum_value; 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) { for (enum_value = type->child; enum_value; enum_value = enum_value->next) {
if (value == enum_value->init_value) { if (value == enum_value->init_value) {
enum_name = enum_value->name; enum_name = enum_value->name;
...@@ -34,6 +34,7 @@ int enum_type_dissect_from_buffer( ...@@ -34,6 +34,7 @@ int enum_type_dissect_from_buffer(
for (values = type->child; values; values = values->next) { for (values = type->child; values; values = values->next) {
if (value == values->init_value) { if (value == values->init_value) {
values->parent = type;
values->type_dissect_from_buffer( values->type_dissect_from_buffer(
values, ui_set_signal_text_cb, user_data, buffer, offset, parent_offset, values, ui_set_signal_text_cb, user_data, buffer, offset, parent_offset,
type->name == NULL ? indent: indent+4); type->name == NULL ? indent: indent+4);
......
...@@ -6,10 +6,13 @@ ...@@ -6,10 +6,13 @@
#include "enum_value_type.h" #include "enum_value_type.h"
#include "ui_interface.h" #include "ui_interface.h"
uint32_t last_enum_value;
int enum_value_dissect_from_buffer( int enum_value_dissect_from_buffer(
struct types_s *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, 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) buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent)
{ {
struct types_s *type_parent = NULL;
uint32_t value = 0; uint32_t value = 0;
DISPLAY_PARSE_INFO("enum_value", type->name, offset, parent_offset); DISPLAY_PARSE_INFO("enum_value", type->name, offset, parent_offset);
...@@ -19,6 +22,24 @@ int enum_value_dissect_from_buffer( ...@@ -19,6 +22,24 @@ int enum_value_dissect_from_buffer(
int length = 0; int length = 0;
char cbuf[50 + strlen(type->name)]; 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); sprintf(cbuf, "(0x%08x) %s;\n", value, type->name);
length = strlen(cbuf); length = strlen(cbuf);
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#ifndef ENUM_VALUE_TYPE_H_ #ifndef ENUM_VALUE_TYPE_H_
#define ENUM_VALUE_TYPE_H_ #define ENUM_VALUE_TYPE_H_
extern uint32_t last_enum_value;
int enum_value_dissect_from_buffer( int enum_value_dissect_from_buffer(
struct types_s *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, 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); buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent);
......
...@@ -24,55 +24,67 @@ int field_dissect_from_buffer( ...@@ -24,55 +24,67 @@ int field_dissect_from_buffer(
CHECK_FCT(buffer_has_enouch_data(buffer, parent_offset + offset, type->size / 8)); CHECK_FCT(buffer_has_enouch_data(buffer, parent_offset + offset, type->size / 8));
if (type->bits == -1) { if (type->bits == -1) {
if (type->child != NULL) { if ((type->name != NULL) && (strcmp(type->name, "_asn_ctx") == 0)) {
/* Ignore TYPEDEF children */ /* Hide ASN1 asn_struct_ctx_t struct that hold context for parsing across buffer boundaries */
for (type_child = type->child; type_child != NULL && type_child->type == TYPE_TYPEDEF; type_child = /*
type_child->child) { INDENTED_STRING(cbuf, indent, sprintf(cbuf, ".asn_ctx ...\n"));
} length = strlen (cbuf);
if (type_child->type == TYPE_ARRAY) { ui_set_signal_text_cb(user_data, cbuf, length);
struct types_s *type_array_child; */
}
else {
if (type->child != NULL) {
/* Ignore TYPEDEF children */ /* Ignore TYPEDEF children */
for (type_array_child = type_child->child; for (type_child = type->child; type_child != NULL && type_child->type == TYPE_TYPEDEF; type_child =
type_array_child != NULL && type_array_child->type == TYPE_TYPEDEF; type_array_child = type_child->child) {
type_array_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;
else {
array_info[0] = '\0';
}
DISPLAY_TYPE("Fld"); /* Ignore TYPEDEF children */
INDENTED_STRING(cbuf, indent, sprintf(cbuf, ".%s%s = ", type->name ? type->name : "Field", array_info)); for (type_array_child = type_child->child;
length = strlen (cbuf); type_array_child != NULL && type_array_child->type == TYPE_TYPEDEF; type_array_child =
type_array_child->child) {
}
ui_set_signal_text_cb(user_data, cbuf, length); sprintf (array_info, "[%d]", type_child->size / type_array_child->size);
}
else {
array_info[0] = '\0';
}
indent_child = indent; DISPLAY_TYPE("Fld");
if (type_child->type == TYPE_ARRAY || type_child->type == TYPE_STRUCT || type_child->type == TYPE_UNION) { INDENTED_STRING(cbuf, indent, sprintf(cbuf, ".%s%s = ", type->name ? type->name : "Field", array_info));
DISPLAY_BRACE(ui_set_signal_text_cb(user_data, "{", 1);) length = strlen (cbuf);
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( ui_set_signal_text_cb(user_data, cbuf, length);
type->child, ui_set_signal_text_cb, user_data, buffer,
parent_offset, offset + type->offset, indent_child));
DISPLAY_BRACE( indent_child = indent;
if (type_child->type == TYPE_ARRAY || type_child->type == TYPE_STRUCT || type_child->type == TYPE_UNION) { if (type_child->type == TYPE_ARRAY || type_child->type == TYPE_STRUCT || type_child->type == TYPE_UNION) {
DISPLAY_TYPE("Fld"); DISPLAY_BRACE(ui_set_signal_text_cb(user_data, "{", 1);)
INDENTED_STRING(cbuf, indent, sprintf(cbuf, "};\n")); ui_set_signal_text_cb(user_data, "\n", 1);
length = strlen (cbuf); indent_child += 4;
}
if (type_child->type == TYPE_FUNDAMENTAL || type_child->type == TYPE_POINTER) {
indent_child = 0;
}
ui_set_signal_text_cb(user_data, cbuf, length); 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 { else {
......
...@@ -14,6 +14,7 @@ int typedef_dissect_from_buffer( ...@@ -14,6 +14,7 @@ int typedef_dissect_from_buffer(
/* Simply call next_type */ /* Simply call next_type */
if (type->child != NULL) { if (type->child != NULL) {
type->child->parent = type;
type->child->type_dissect_from_buffer( type->child->type_dissect_from_buffer(
type->child, ui_set_signal_text_cb, user_data, buffer, offset, parent_offset, indent); type->child, ui_set_signal_text_cb, user_data, buffer, offset, parent_offset, indent);
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "rc.h" #include "rc.h"
#include "enum_value_type.h"
#include "union_type.h" #include "union_type.h"
#include "../libresolver/locate_root.h" #include "../libresolver/locate_root.h"
#include "ui_interface.h" #include "ui_interface.h"
...@@ -34,6 +35,7 @@ int union_dissect_from_buffer( ...@@ -34,6 +35,7 @@ int union_dissect_from_buffer(
{ {
int length = 0; int length = 0;
char cbuf[200]; char cbuf[200];
int union_child = 0;
DISPLAY_PARSE_INFO("union", type->name, offset, parent_offset); DISPLAY_PARSE_INFO("union", type->name, offset, parent_offset);
...@@ -45,6 +47,21 @@ int union_dissect_from_buffer( ...@@ -45,6 +47,21 @@ int union_dissect_from_buffer(
// INDENTED(stdout, indent, fprintf(stdout, "<%s>\n", type->name)); // INDENTED(stdout, indent, fprintf(stdout, "<%s>\n", type->name));
DISPLAY_TYPE("Uni"); DISPLAY_TYPE("Uni");
INDENTED_STRING(cbuf, indent, sprintf(cbuf, "%s {\n", type->name)); 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); length = strlen (cbuf);
...@@ -52,9 +69,9 @@ int union_dissect_from_buffer( ...@@ -52,9 +69,9 @@ int union_dissect_from_buffer(
ui_set_signal_text_cb(user_data, cbuf, length); ui_set_signal_text_cb(user_data, cbuf, length);
/* Only dissect the first field present in unions */ /* Only dissect the first field present in unions */
if (type->members_child[0] != NULL) if (type->members_child[union_child] != NULL)
type->members_child[0]->type_dissect_from_buffer( type->members_child[union_child]->type_dissect_from_buffer(
type->members_child[0], ui_set_signal_text_cb, user_data, buffer, type->members_child[union_child], ui_set_signal_text_cb, user_data, buffer,
offset, parent_offset, type->name == NULL ? indent : indent + 4); offset, parent_offset, type->name == NULL ? indent : indent + 4);
if (type->name) { if (type->name) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment