Commit 113c5c37 authored by winckel's avatar winckel
Browse files

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)
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);
}
else {
array_info[0] = '\0';
}
if (type_child->type == TYPE_ARRAY) {
struct types_s *type_array_child;
DISPLAY_TYPE("Fld");
INDENTED_STRING(cbuf, indent, sprintf(cbuf, ".%s%s = ", type->name ? type->name : "Field", array_info));
length = strlen (cbuf);
/* 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) {
}
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;
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;
}
DISPLAY_TYPE("Fld");
INDENTED_STRING(cbuf, indent, sprintf(cbuf, ".%s%s = ", type->name ? type->name : "Field", array_info));
length = strlen (cbuf);
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));
ui_set_signal_text_cb(user_data, cbuf, length);
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);
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;
}
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 {
......
......@@ -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) {
......
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