Commit ecf07e38 authored by Cedric Roux's avatar Cedric Roux
Browse files

- itti_analyzer v0.2:

	* Moved all GUI calls to main thread
	* Refine socket interface
	* Added origin/destination task id on message display list

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4258 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 3dc3d6ae
......@@ -4,7 +4,7 @@ define([svnversion], esyscmd([sh -c "svnversion ..|tr -d '\n'"]))
AC_DEFINE(SVN_REVISION, "svnversion", [SVN Revision])
AC_INIT([itti_debugger], [0.1.svnversion], [openair_admin@eurecom.fr])
AC_INIT([itti_debugger], [0.2.svnversion], [openair_admin@eurecom.fr])
AC_CANONICAL_BUILD
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([1.11 silent-rules])
......@@ -90,4 +90,4 @@ AC_CONFIG_FILES(
libui/Makefile \
Makefile \
)
AC_OUTPUT
\ No newline at end of file
AC_OUTPUT
......@@ -75,12 +75,6 @@ int main(int argc, char *argv[])
G_LOG_FLAG_FATAL |
G_LOG_FLAG_RECURSION);
if (!g_thread_supported())
g_thread_init(NULL);
/* Secure gtk */
gdk_threads_init();
/* Initialize the widget set */
gtk_init(&argc, &argv);
......
......@@ -6,13 +6,23 @@
typedef struct {
pthread_t thread;
uint16_t port;
char *remote_ip;
int sd;
struct sockaddr_in si_me;
char *ip_address;
uint16_t port;
/* The pipe used between main thread (running GTK) and the socket thread */
int pipe_fd;
/* Time used to avoid refreshing UI every time a new signal is incoming */
gint64 last_data_notification;
uint8_t nb_signals_since_last_update;
/* The last signals received which are not yet been updated in GUI */
GList *signal_list;
} socket_data_t;
int socket_connect_to_remote_host(const char *remote_ip, const uint16_t port);
int socket_connect_to_remote_host(const char *remote_ip, const uint16_t port,
int pipe_fd);
int socket_disconnect_from_remote_host(void);
......
......@@ -6,6 +6,21 @@
#include "enum_type.h"
#include "ui_interface.h"
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 */
for (enum_value = type->child; enum_value; enum_value = enum_value->next) {
if (value == enum_value->init_value) {
enum_name = enum_value->name;
break;
}
}
return enum_name;
}
int enum_type_dissect_from_buffer(
struct types_s *type, buffer_t *buffer, uint32_t offset,
uint32_t parent_offset, int indent)
......
......@@ -3,6 +3,8 @@
#ifndef ENUM_TYPE_H_
#define ENUM_TYPE_H_
char *enum_type_get_name_from_value(struct types_s *type, uint32_t value);
int enum_type_dissect_from_buffer(
struct types_s *type, buffer_t *buffer, uint32_t offset,
uint32_t parent_offset, int indent);
......
......@@ -9,6 +9,7 @@
#include "union_type.h"
#include "ui_interface.h"
#include "ui_notif_dlg.h"
#include "../libresolver/locate_root.h"
#include "../libresolver/resolvers.h"
......@@ -21,15 +22,15 @@ extern int debug_parser;
# define INDENT_START 0
#endif
#define PARSER_DEBUG(fmt, args...) \
do { \
if (debug_parser) \
fprintf(stdout, "WARNING: "fmt, ##args); \
#define PARSER_DEBUG(fmt, args...) \
do { \
if (debug_parser) \
g_debug("WARNING: "fmt, ##args); \
} while(0)
#define PARSER_ERROR(fmt, args...) \
do { \
fprintf(stderr, "FATAL: "fmt, ##args); \
g_error("FATAL: "fmt, ##args); \
} while(0)
types_t *root = NULL;
......@@ -582,66 +583,54 @@ static int parse_pointer_type(xmlNode *node, types_t **head) {
static int parse_elements(xmlNode * a_node, types_t **head) {
xmlNode *cur_node = NULL;
xmlNode *child_node = NULL;
unsigned long nb_nodes;
unsigned long node_count = 0;
nb_nodes = xmlChildElementCount (a_node);
for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
node_count++;
sleep (1);
ui_interface.ui_progress_bar_set_fraction ((double) node_count / nb_nodes);
for (child_node = cur_node->children; child_node; child_node = child_node->next) {
if (child_node->type == XML_ELEMENT_NODE) {
if (strcmp ((char *) child_node->name, "Enumeration") == 0) {
CHECK_FCT_DO(parse_enumeration(child_node, head), goto fail);
CHECK_FCT_DO(parse_enumeration(child_node, head), return RC_FAIL);
}
else
if (strcmp ((char *) child_node->name, "FundamentalType") == 0) {
CHECK_FCT_DO(parse_fundamental(child_node, head), goto fail);
CHECK_FCT_DO(parse_fundamental(child_node, head), return RC_FAIL);
}
else
if (strcmp ((char *) child_node->name, "Struct") == 0) {
CHECK_FCT_DO(parse_struct(child_node, head), goto fail);
CHECK_FCT_DO(parse_struct(child_node, head), return RC_FAIL);
}
else
if (strcmp ((char *) child_node->name, "Union") == 0) {
CHECK_FCT_DO(parse_union(child_node, head), goto fail);
CHECK_FCT_DO(parse_union(child_node, head), return RC_FAIL);
}
else
if (strcmp ((char *) child_node->name, "Typedef") == 0) {
CHECK_FCT_DO(parse_typedef(child_node, head), goto fail);
CHECK_FCT_DO(parse_typedef(child_node, head), return RC_FAIL);
}
else
if (strcmp ((char *) child_node->name, "File") == 0) {
CHECK_FCT_DO(parse_file(child_node, head), goto fail);
CHECK_FCT_DO(parse_file(child_node, head), return RC_FAIL);
}
else
if (strcmp ((char *) child_node->name, "Field") == 0) {
CHECK_FCT_DO(parse_field(child_node, head), goto fail);
CHECK_FCT_DO(parse_field(child_node, head), return RC_FAIL);
}
else
if (strcmp ((char *) child_node->name, "ReferenceType") == 0) {
CHECK_FCT_DO(parse_reference_type(child_node, head), goto fail);
CHECK_FCT_DO(parse_reference_type(child_node, head), return RC_FAIL);
}
else
if (strcmp ((char *) child_node->name, "ArrayType") == 0) {
CHECK_FCT_DO(parse_array_type(child_node, head), goto fail);
CHECK_FCT_DO(parse_array_type(child_node, head), return RC_FAIL);
}
else
if (strcmp ((char *) child_node->name, "PointerType") == 0) {
CHECK_FCT_DO(parse_pointer_type(child_node, head), goto fail);
CHECK_FCT_DO(parse_pointer_type(child_node, head), return RC_FAIL);
}
}
}
}
ui_interface.ui_progress_bar_terminate ();
return RC_OK;
fail: ui_interface.ui_progress_bar_terminate ();
return RC_FAIL;
}
int xml_parse_buffer(const char *xml_buffer, const int size) {
......@@ -651,7 +640,7 @@ int xml_parse_buffer(const char *xml_buffer, const int size) {
return -1;
}
fprintf(stdout, "Parsing XML definition from buffer\n");
g_debug("Parsing XML definition from buffer");
/* This initialize the library and check potential ABI mismatches
* between the version it was compiled for and the actual shared
......@@ -662,8 +651,8 @@ int xml_parse_buffer(const char *xml_buffer, const int size) {
doc = xmlReadMemory(xml_buffer, size, NULL, NULL, 0);
if (doc == NULL) {
fprintf (stderr, "Failed to parse buffer: %s\n", xml_buffer);
ui_interface.ui_notification_dialog (DIALOG_WARNING, "Fail to parse XML buffer");
g_warning("Failed to parse buffer: %s", xml_buffer);
// ui_notification_dialog(DIALOG_WARNING, "Fail to parse XML buffer");
return RC_FAIL;
}
......@@ -686,8 +675,8 @@ int xml_parse_file(const char *filename) {
doc = xmlReadFile (filename, NULL, 0);
if (doc == NULL) {
fprintf (stderr, "Failed to parse %s\n", filename);
ui_interface.ui_notification_dialog (DIALOG_WARNING, "Failed to parse file %s", filename);
g_warning("Failed to parse %s\n", filename);
// ui_notification_dialog(DIALOG_WARNING, "Failed to parse file %s", filename);
return RC_FAIL;
}
......@@ -703,17 +692,17 @@ static int xml_parse_doc(xmlDocPtr doc) {
dissect_file = fopen ("./dissect.xml", "w");
/* Get the root element node */
root_element = xmlDocGetRootElement (doc);
root_element = xmlDocGetRootElement(doc);
ret = parse_elements (root_element, &head);
ret = parse_elements(root_element, &head);
/* Free the document */
xmlFreeDoc (doc);
xmlFreeDoc(doc);
/* Free the global variables that may
* have been allocated by the parser.
*/
xmlCleanupParser ();
xmlCleanupParser();
if (ret == RC_OK) {
resolve_typedefs (&head);
......@@ -724,34 +713,38 @@ static int xml_parse_doc(xmlDocPtr doc) {
resolve_struct (&head);
resolve_file (&head);
resolve_union (&head);
/* Locate the root element which corresponds to the MessageDef struct */
CHECK_FCT(locate_root("MessageDef", head, &root));
/* Locate the message id enumeration */
CHECK_FCT(locate_type("MessagesIds", head, &messages_id_enum));
CHECK_FCT(locate_type("originTaskId", head, &origin_task_id_type));
CHECK_FCT(locate_type("destinationTaskId", head, &destination_task_id_type));
// root->type_hr_display(root, 0);
if (dissect_file != NULL) {
root->type_file_print (root, 0, dissect_file);
}
ui_interface.dissector_ready = 1;
}
fclose (dissect_file);
return ret;
}
int dissect_signal(const uint32_t message_number) {
buffer_t *buffer;
int dissect_signal(buffer_t *buffer) {
// buffer_t *buffer;
if (root == NULL) {
ui_interface.ui_notification_dialog (DIALOG_ERROR, "No message XML file provided");
// ui_notification_dialog(DIALOG_ERROR, "No message XML file provided");
return RC_FAIL;
}
CHECK_FCT(buffer_get_from_mn(message_number, &buffer));
// CHECK_FCT(buffer_get_from_mn(message_number, &buffer));
if (buffer == NULL) {
fprintf (stderr, "Failed buffer %u in list\n", message_number);
g_error("Failed buffer is NULL\n");
return RC_FAIL;
}
root->type_dissect_from_buffer (root, buffer, 0, 0, INDENT_START);
root->type_dissect_from_buffer(root, buffer, 0, 0, INDENT_START);
return RC_OK;
}
......@@ -4,10 +4,12 @@
#ifndef XML_PARSE_H_
#define XML_PARSE_H_
extern types_t *root;
int xml_parse_file(const char *filename);
int xml_parse_buffer(const char *xml_buffer, const int size);
int dissect_signal(const uint32_t message_number);
int dissect_signal(buffer_t *buffer);
#endif /* XML_PARSE_H_ */
......@@ -6,9 +6,15 @@
#include "rc.h"
#include "types.h"
#include "enum_type.h"
#include "locate_root.h"
#include "xml_parse.h"
int locate_root(const char *root_name, types_t *head, types_t **root) {
types_t *messages_id_enum = NULL;
types_t *origin_task_id_type = NULL;
types_t *destination_task_id_type = NULL;
int locate_root(const char *root_name, types_t *head, types_t **root_elm) {
types_t *next_type;
/* The root element is for example : MessageDef.
......@@ -22,7 +28,7 @@ int locate_root(const char *root_name, types_t *head, types_t **root) {
g_warning("Empty list detected");
return -1;
}
if (!root) {
if (!root_elm) {
g_warning("NULL root reference");
return -1;
}
......@@ -35,7 +41,7 @@ int locate_root(const char *root_name, types_t *head, types_t **root) {
break;
}
}
*root = next_type;
*root_elm = next_type;
return (next_type == NULL) ? -2 : 0;
}
......@@ -46,7 +52,7 @@ int locate_type(const char *type_name, types_t *head, types_t **type) {
* This element is the entry for other sub-types.
*/
if (!type_name) {
g_warning("FATAL: no root element name provided");
g_warning("FATAL: no element name provided");
return RC_BAD_PARAM;
}
if (!head) {
......@@ -69,16 +75,46 @@ int locate_type(const char *type_name, types_t *head, types_t **type) {
int get_message_id(types_t *head, buffer_t *buffer, uint32_t *message_id) {
uint32_t value;
types_t *type_message_id;
if (!head || !message_id || !buffer)
return RC_BAD_PARAM;
CHECK_FCT(locate_type("messageId", head, &type_message_id));
g_assert(message_id != NULL);
g_assert(buffer != NULL);
/* MessageId is an offset from start of buffer */
value = buffer_get_uint32_t (buffer, type_message_id->offset);
value = buffer_get_uint32_t(buffer, messages_id_enum->offset);
*message_id = value;
return RC_OK;
}
char *get_origin_task_id(buffer_t *buffer) {
char *origin_task_id = "UNKNOWN";
uint32_t origin_task_id_value;
/* Fetch task id value */
if (buffer_fetch_bits(buffer, origin_task_id_type->offset,
origin_task_id_type->child->size, &origin_task_id_value) == RC_OK) {
origin_task_id = enum_type_get_name_from_value(origin_task_id_type->child,
origin_task_id_value);
}
return origin_task_id;
}
char *get_destination_task_id(buffer_t *buffer) {
char *destination_task_id = "UNKNOWN";
uint32_t destination_task_id_value;
/* Fetch task id value */
if (buffer_fetch_bits(buffer, destination_task_id_type->offset,
destination_task_id_type->child->size, &destination_task_id_value) == RC_OK) {
destination_task_id = enum_type_get_name_from_value(destination_task_id_type->child,
destination_task_id_value);
}
return destination_task_id;
}
char *message_id_to_string(uint32_t message_id)
{
return enum_type_get_name_from_value(messages_id_enum, message_id);
}
#ifndef LOCATE_ROOT_H_
#define LOCATE_ROOT_H_
extern types_t *messages_id_enum;
extern types_t *origin_task_id_type;
extern types_t *destination_task_id_type;
int locate_root(const char *root_name, types_t *head, types_t **root);
int locate_type(const char *type_name, types_t *head, types_t **type);
int get_message_id(types_t *head, buffer_t *buffer, uint32_t *message_id);
char *message_id_to_string(uint32_t message_id);
char *get_origin_task_id(buffer_t *buffer);
char *get_destination_task_id(buffer_t *buffer);
#endif /* LOCATE_ROOT_H_ */
......@@ -2,17 +2,19 @@ AM_CFLAGS = \
@ADD_CFLAGS@ \
-I$(top_srcdir)/common \
-I$(top_srcdir)/libbuffers \
-I$(top_srcdir)/libparser
-I$(top_srcdir)/libparser \
-I$(top_srcdir)/libresolver
noinst_LTLIBRARIES = libui.la
libui_la_LDFLAGS = -all-static
libui_la_SOURCES = \
ui_main_screen.c ui_main_screen.h \
ui_menu_bar.c ui_menu_bar.h \
ui_callbacks.c ui_callbacks.h \
ui_tree_view.c ui_tree_view.h \
ui_main_screen.c ui_main_screen.h \
ui_menu_bar.c ui_menu_bar.h \
ui_callbacks.c ui_callbacks.h \
ui_tree_view.c ui_tree_view.h \
ui_signal_dissect_view.c ui_signal_dissect_view.h \
ui_notifications.c ui_notifications.h \
ui_interface.c ui_interface.h \
ui_notebook.c ui_notebook.h
ui_notifications.c ui_notifications.h \
ui_notif_dlg.c ui_notif_dlg.h \
ui_interface.c ui_interface.h \
ui_notebook.c ui_notebook.h
......@@ -5,6 +5,9 @@
#include "rc.h"
#include "socket.h"
#include "ui_notif_dlg.h"
#include "ui_main_screen.h"
#include "ui_callbacks.h"
#include "ui_interface.h"
......@@ -12,6 +15,12 @@
#include "ui_tree_view.h"
#include "ui_signal_dissect_view.h"
#include "types.h"
#include "locate_root.h"
#include "xml_parse.h"
static gboolean ui_handle_socket_connection_failed(gint fd);
gboolean ui_callback_on_open(GtkWidget *widget,
GdkEvent *event,
gpointer data)
......@@ -41,23 +50,22 @@ ui_callback_on_select_signal(GtkTreeSelection *selection,
if (gtk_tree_model_get_iter(model, &iter, path))
{
gchar *name;
GValue buffer_store = G_VALUE_INIT;
gpointer buffer;
// g_value_init (&buffer_store, G_TYPE_POINTER);
gtk_tree_model_get(model, &iter, 0, &name, -1);
// gtk_tree_model_get(model, &iter, 0, &name, -1);
gtk_tree_model_get_value(model, &iter, COL_BUFFER, &buffer_store);
buffer = g_value_get_pointer(&buffer_store);
if (!path_currently_selected)
{
if (ui_interface.dissector_ready != 0) {
uint32_t message_number;
sscanf(name, "%u", &message_number);
/* Clear the view */
CHECK_FCT_DO(ui_signal_dissect_clear_view(), return FALSE);
// g_print ("%s is going to be selected.\n", name);
CHECK_FCT_DO(ui_interface.dissect_signal(message_number), return FALSE);
} else {
ui_notification_dialog(DIALOG_ERROR, "No XML signal description"
" provided\n");
}
/* Clear the view */
CHECK_FCT_DO(ui_signal_dissect_clear_view(), return FALSE);
CHECK_FCT_DO(dissect_signal((buffer_t*)buffer), return FALSE);
}
else
{
......@@ -69,21 +77,162 @@ ui_callback_on_select_signal(GtkTreeSelection *selection,
return TRUE;
}
void ui_signal_add_to_list(gpointer data, gpointer user_data)
{
buffer_t *signal_buffer;
signal_buffer = (buffer_t *)data;
get_message_id(root, signal_buffer, &signal_buffer->message_id);
ui_tree_view_new_signal_ind(signal_buffer->message_number,
message_id_to_string(signal_buffer->message_id),
get_origin_task_id(signal_buffer),
get_destination_task_id(signal_buffer),
data);
}
static gboolean ui_handle_update_signal_list(gint fd, const void *data,
size_t data_length)
{
pipe_new_signals_list_message_t *signal_list_message;
signal_list_message = (pipe_new_signals_list_message_t *)data;
g_assert(signal_list_message != NULL);
g_assert(signal_list_message->signal_list != NULL);
g_list_foreach(signal_list_message->signal_list, ui_signal_add_to_list, NULL);
free(data);
return TRUE;
}
static gboolean ui_handle_socket_connection_failed(gint fd)
{
GtkWidget *dialogbox;
dialogbox = gtk_message_dialog_new(GTK_WINDOW(ui_main_data.window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Failed to connect to provided host/ip address");
gtk_dialog_run(GTK_DIALOG(dialogbox));
gtk_widget_destroy(dialogbox);
/* Re-enable connect button */
ui_enable_connect_button();
return TRUE;
}
static gboolean ui_handle_socket_connection_lost(gint fd)
{
GtkWidget *dialogbox;
dialogbox = gtk_message_dialog_new(GTK_WINDOW(ui_main_data.window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Connection with remote host has been lost");
gtk_dialog_run(GTK_DIALOG(dialogbox));
gtk_widget_destroy(dialogbox);
/* Re-enable connect button */
ui_enable_connect_button();
return TRUE;
}
static gboolean ui_handle_socket_xml_definition(gint fd, const void *data,
size_t data_length)
{
pipe_xml_definition_message_t *xml_definition_message;
xml_definition_message = (pipe_xml_definition_message_t *)data;
g_assert(xml_definition_message != NULL);
g_assert(data_length == sizeof(pipe_xml_definition_message_t));
xml_parse_buffer(xml_definition_message->xml_definition,
xml_definition_message->xml_definition_length);
free(data);
return TRUE;
}
gboolean ui_pipe_callback(gint source, gpointer user_data)
{