2 * Copyright 2009 Martin Mathieson
3 * (originally based upon wlan_stat_dlg.c)
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 - limit by display filter
29 - Help button and documentation
37 #ifdef HAVE_SYS_TYPES_H
38 #include <sys/types.h>
45 #include <epan/packet.h>
46 #include <epan/packet_info.h>
48 #include <epan/dissectors/packet-mac-lte.h>
50 #include "../register.h"
51 #include "../simple_dialog.h"
52 #include "../stat_menu.h"
54 #include "gtk/dlg_utils.h"
55 #include "gtk/gui_stat_menu.h"
56 #include "gtk/gui_utils.h"
57 #include "gtk/help_dlg.h"
60 /**********************************************/
61 /* Table column identifiers and title strings */
68 UL_RETX_FRAMES_COLUMN,
72 DL_RETX_FRAMES_COLUMN,
93 static const gchar *ue_titles[] = { "RNTI",
94 "UL Frames", "UL Bytes", "UL CRC Errors", "UL ReTX Frames",
95 "DL Frames", "DL Bytes", "DL CRC Errors", "DL ReTX Frames"};
97 static const gchar *channel_titles[] = { "CCCH",
98 "LCID 1", "LCID 2", "LCID 3", "LCID 4", "LCID 5",
99 "LCID 6", "LCID 7", "LCID 8", "LCID 9", "LCID 10",
103 /* Stats for one UE */
104 typedef struct mac_lte_row_data {
105 /* Key for matching this row */
108 gboolean is_predefined_data;
111 guint32 UL_total_bytes;
112 guint32 UL_CRC_errors;
113 guint32 UL_retx_frames;
116 guint32 DL_total_bytes;
117 guint32 DL_CRC_errors;
118 guint32 DL_retx_frames;
120 guint32 UL_bytes_for_lcid[11];
121 guint32 UL_sdus_for_lcid[11];
122 guint32 DL_bytes_for_lcid[11];
123 guint32 DL_sdus_for_lcid[11];
127 /* One row/UE in the UE table */
128 typedef struct mac_lte_ep {
129 struct mac_lte_ep* next;
130 struct mac_lte_row_data stats;
136 /* Common channel stats */
137 typedef struct mac_lte_common_stats {
145 } mac_lte_common_stats;
147 static const char * selected_ue_row_names[] = {"UL SDUs", "UL Bytes", "DL SDUs", "DL Bytes"};
149 static mac_lte_common_stats common_stats;
151 static GtkWidget *mac_lte_common_bch_frames;
152 static GtkWidget *mac_lte_common_bch_bytes;
153 static GtkWidget *mac_lte_common_pch_frames;
154 static GtkWidget *mac_lte_common_pch_bytes;
155 static GtkWidget *mac_lte_common_rar_frames;
156 static GtkWidget *mac_lte_common_rar_entries;
158 /* Labels in selected UE 'table' */
159 static GtkWidget *selected_ue_column_entry[NUM_CHANNEL_COLUMNS][5];
162 /* Top-level dialog and labels */
163 static GtkWidget *mac_lte_stat_dlg_w = NULL;
164 static GtkWidget *mac_lte_stat_common_channel_lb = NULL;
165 static GtkWidget *mac_lte_stat_ues_lb = NULL;
166 static GtkWidget *mac_lte_stat_selected_ue_lb = NULL;
169 /* Used to keep track of whole MAC LTE statistics window */
170 typedef struct mac_lte_stat_t {
171 GtkTreeView *ue_table;
172 mac_lte_ep_t* ep_list;
176 /* Reset the statistics window */
178 mac_lte_stat_reset(void *phs)
180 mac_lte_stat_t* mac_lte_stat = (mac_lte_stat_t *)phs;
181 mac_lte_ep_t* list = mac_lte_stat->ep_list;
187 if (mac_lte_stat_dlg_w != NULL) {
188 g_snprintf(title, sizeof(title), "Wireshark: LTE MAC Traffic Statistics: %s",
189 cf_get_display_name(&cfile));
190 gtk_window_set_title(GTK_WINDOW(mac_lte_stat_dlg_w), title);
193 g_snprintf(title, sizeof(title), "UL/DL-SCH data (0 UEs)");
194 gtk_frame_set_label(GTK_FRAME(mac_lte_stat_ues_lb), title);
196 memset(&common_stats, 0, sizeof(common_stats));
198 /* Remove all entries from the UE list */
199 store = GTK_LIST_STORE(gtk_tree_view_get_model(mac_lte_stat->ue_table));
200 gtk_list_store_clear(store);
206 mac_lte_stat->ep_list = NULL;
208 /* Set all of the channel counters to 0 */
209 for (n=1; n <=4; n++) {
210 for (i=CCCH_COLUMN; i < NUM_CHANNEL_COLUMNS; i++) {
211 gtk_label_set_text(GTK_LABEL(selected_ue_column_entry[i][n]), "0");
217 /* Allocate a mac_lte_ep_t struct to store info for new UE */
218 static mac_lte_ep_t* alloc_mac_lte_ep(struct mac_lte_tap_info *si, packet_info *pinfo _U_)
227 if (!(ep = g_malloc(sizeof(mac_lte_ep_t)))) {
231 /* Copy SI data into ep->stats */
232 ep->stats.rnti = si->rnti;
234 /* Counts for new UE are all 0 */
235 ep->stats.UL_frames = 0;
236 ep->stats.DL_frames = 0;
237 ep->stats.UL_total_bytes = 0;
238 ep->stats.DL_total_bytes = 0;
239 ep->stats.UL_CRC_errors = 0;
240 ep->stats.DL_CRC_errors = 0;
241 ep->stats.UL_retx_frames = 0;
242 ep->stats.DL_retx_frames = 0;
244 for (n=0; n < 11; n++) {
245 ep->stats.UL_sdus_for_lcid[n] = 0;
246 ep->stats.UL_bytes_for_lcid[n] = 0;
248 ep->stats.DL_total_bytes = 0;
249 for (n=0; n < 11; n++) {
250 ep->stats.DL_sdus_for_lcid[n] = 0;
251 ep->stats.DL_bytes_for_lcid[n] = 0;
256 ep->iter_valid = FALSE;
262 /* Process stat struct for a MAC LTE frame */
264 mac_lte_stat_packet(void *phs, packet_info *pinfo, epan_dissect_t *edt _U_,
269 /* Get reference to stat window instance */
270 mac_lte_stat_t *hs = (mac_lte_stat_t *)phs;
271 mac_lte_ep_t *tmp = NULL, *te = NULL;
273 /* Cast tap info struct */
274 struct mac_lte_tap_info *si = (struct mac_lte_tap_info *)phi;
280 common_stats.all_frames++;
282 /* For common channels, just update global counters */
283 switch (si->rntiType) {
285 common_stats.pch_frames++;
286 common_stats.pch_bytes += si->single_number_of_bytes;
290 common_stats.bch_frames++;
291 common_stats.bch_bytes += si->single_number_of_bytes;
294 common_stats.rar_frames++;
295 common_stats.rar_entries += si->number_of_rars;
298 /* Drop through for per-UE update */
305 /* For per-UE data, must create a new row if none already existing */
307 /* Allocate new list */
308 hs->ep_list = alloc_mac_lte_ep(si, pinfo);
309 /* Make it the first/only entry */
312 /* Look among existing rows for this RNTI */
313 for (tmp = hs->ep_list;(tmp != NULL); tmp = tmp->next) {
314 if (tmp->stats.rnti == si->rnti) {
320 /* Not found among existing, so create a new one anyway */
322 if ((te = alloc_mac_lte_ep(si, pinfo))) {
323 /* New item is head of list */
324 te->next = hs->ep_list;
330 /* Really should have a row pointer by now */
335 /* Update entry with details from si */
336 te->stats.rnti = si->rnti;
337 te->stats.is_predefined_data = si->isPredefinedData;
338 if (si->crcStatusValid && !si->crcStatus) {
339 if (si->direction == DIRECTION_UPLINK) {
340 te->stats.UL_CRC_errors++;
344 te->stats.DL_CRC_errors++;
350 if (si->direction == DIRECTION_UPLINK) {
351 if (si->reTxCount >= 1) {
352 te->stats.UL_retx_frames++;
355 te->stats.UL_frames++;
357 if (si->isPredefinedData) {
358 te->stats.UL_total_bytes += si->single_number_of_bytes;
361 for (n=0; n < 11; n++) {
362 if (si->bytes_for_lcid[n]) {
363 te->stats.UL_sdus_for_lcid[n] += si->sdus_for_lcid[n];
365 te->stats.UL_bytes_for_lcid[n] += si->bytes_for_lcid[n];
366 te->stats.UL_total_bytes += si->bytes_for_lcid[n];
373 if (si->reTxCount >= 1) {
374 te->stats.DL_retx_frames++;
378 te->stats.DL_frames++;
380 if (si->isPredefinedData) {
381 te->stats.DL_total_bytes += si->single_number_of_bytes;
384 for (n=0; n < 11; n++) {
385 if (si->bytes_for_lcid[n]) {
386 te->stats.DL_sdus_for_lcid[n] += si->sdus_for_lcid[n];
388 te->stats.DL_bytes_for_lcid[n] += si->bytes_for_lcid[n];
389 te->stats.DL_total_bytes += si->bytes_for_lcid[n];
398 /* Draw the UE details table according to the current UE selection */
400 mac_lte_ue_details(mac_lte_ep_t *mac_stat_ep)
405 /**********************************/
406 /* Set data one row at a time */
409 for (n=0; n < PREDEFINED_COLUMN-1; n++) {
410 g_snprintf(buff, sizeof(buff), "%u", mac_stat_ep ? mac_stat_ep->stats.UL_sdus_for_lcid[n] : 0);
411 gtk_label_set_text(GTK_LABEL(selected_ue_column_entry[n+1][1]), buff);
416 g_snprintf(buff, sizeof(buff), "%u", mac_stat_ep->stats.is_predefined_data ?
417 mac_stat_ep->stats.UL_frames :
421 g_snprintf(buff, sizeof(buff), "%u", 0);
423 gtk_label_set_text(GTK_LABEL(selected_ue_column_entry[PREDEFINED_COLUMN][1]), buff);
427 for (n=0; n < PREDEFINED_COLUMN-1; n++) {
428 g_snprintf(buff, sizeof(buff), "%u",
429 (mac_stat_ep) ? mac_stat_ep->stats.UL_bytes_for_lcid[n] : 0);
430 gtk_label_set_text(GTK_LABEL(selected_ue_column_entry[n+1][2]), buff);
435 g_snprintf(buff, sizeof(buff), "%u", mac_stat_ep->stats.is_predefined_data ?
436 mac_stat_ep->stats.UL_total_bytes :
440 g_snprintf(buff, sizeof(buff), "%u", 0);
442 gtk_label_set_text(GTK_LABEL(selected_ue_column_entry[PREDEFINED_COLUMN][2]), buff);
446 for (n=0; n < PREDEFINED_COLUMN-1; n++) {
447 g_snprintf(buff, sizeof(buff), "%u",
448 mac_stat_ep ? mac_stat_ep->stats.DL_sdus_for_lcid[n] : 0);
449 gtk_label_set_text(GTK_LABEL(selected_ue_column_entry[n+1][3]), buff);
453 g_snprintf(buff, sizeof(buff), "%u", mac_stat_ep->stats.is_predefined_data ?
454 mac_stat_ep->stats.DL_frames :
458 g_snprintf(buff, sizeof(buff), "%u", 0);
460 gtk_label_set_text(GTK_LABEL(selected_ue_column_entry[PREDEFINED_COLUMN][3]), buff);
464 for (n=0; n < PREDEFINED_COLUMN-1; n++) {
465 g_snprintf(buff, sizeof(buff), "%u",
466 mac_stat_ep ? mac_stat_ep->stats.DL_bytes_for_lcid[n] : 0);
467 gtk_label_set_text(GTK_LABEL(selected_ue_column_entry[n+1][4]), buff);
471 g_snprintf(buff, sizeof(buff), "%u", mac_stat_ep->stats.is_predefined_data ?
472 mac_stat_ep->stats.DL_total_bytes :
476 g_snprintf(buff, sizeof(buff), "%u", 0);
478 gtk_label_set_text(GTK_LABEL(selected_ue_column_entry[PREDEFINED_COLUMN][4]), buff);
483 /* (Re)draw the whole dialog window */
485 mac_lte_stat_draw(void *phs)
488 guint16 number_of_ues = 0;
491 /* Look up the statistics window */
492 mac_lte_stat_t *hs = (mac_lte_stat_t *)phs;
493 mac_lte_ep_t* list = hs->ep_list, *tmp = 0;
495 GtkListStore *ues_store;
496 GtkTreeSelection *sel;
500 /* Common channel data */
501 g_snprintf(buff, sizeof(buff), "BCH Frames: %u", common_stats.bch_frames);
502 gtk_label_set_text(GTK_LABEL(mac_lte_common_bch_frames), buff);
503 g_snprintf(buff, sizeof(buff), "BCH Bytes: %u", common_stats.bch_bytes);
504 gtk_label_set_text(GTK_LABEL(mac_lte_common_bch_bytes), buff);
505 g_snprintf(buff, sizeof(buff), "PCH Frames: %u", common_stats.pch_frames);
506 gtk_label_set_text(GTK_LABEL(mac_lte_common_pch_frames), buff);
507 g_snprintf(buff, sizeof(buff), "PCH Bytes: %u", common_stats.pch_bytes);
508 gtk_label_set_text(GTK_LABEL(mac_lte_common_pch_bytes), buff);
509 g_snprintf(buff, sizeof(buff), "RAR Frames: %u", common_stats.rar_frames);
510 gtk_label_set_text(GTK_LABEL(mac_lte_common_rar_frames), buff);
511 g_snprintf(buff, sizeof(buff), "RAR Entries: %u", common_stats.rar_entries);
512 gtk_label_set_text(GTK_LABEL(mac_lte_common_rar_entries), buff);
515 /* Per-UE table entries */
516 ues_store = GTK_LIST_STORE(gtk_tree_view_get_model(hs->ue_table));
518 /* Set title that shows how many UEs currently in table */
519 for (tmp = list; (tmp!=NULL); tmp=tmp->next, number_of_ues++);
520 g_snprintf(title, sizeof(title), "UL/DL-SCH data (%u UEs)", number_of_ues);
521 gtk_frame_set_label(GTK_FRAME(mac_lte_stat_ues_lb), title);
523 /* Update title to include number of UEs and frames */
524 g_snprintf(title, sizeof(title), "Wireshark: LTE MAC Traffic Statistics: %s (%u UEs, %u frames)",
525 cf_get_display_name(&cfile),
527 common_stats.all_frames);
528 gtk_window_set_title(GTK_WINDOW(mac_lte_stat_dlg_w), title);
532 /* For each row/UE/C-RNTI in the model */
533 for (tmp = list; tmp; tmp=tmp->next) {
534 if (tmp->iter_valid != TRUE) {
535 /* Add to list control if not drawn this UE before */
536 gtk_list_store_append(ues_store, &tmp->iter);
537 tmp->iter_valid = TRUE;
540 /* Set each column for this row */
541 gtk_list_store_set(ues_store, &tmp->iter,
542 RNTI_COLUMN, tmp->stats.rnti,
543 UL_FRAMES_COLUMN, tmp->stats.UL_frames,
544 UL_BYTES_COLUMN, tmp->stats.UL_total_bytes,
545 UL_CRC_ERRORS_COLUMN, tmp->stats.UL_CRC_errors,
546 UL_RETX_FRAMES_COLUMN, tmp->stats.UL_retx_frames,
547 DL_FRAMES_COLUMN, tmp->stats.DL_frames,
548 DL_BYTES_COLUMN, tmp->stats.DL_total_bytes,
549 DL_CRC_ERRORS_COLUMN, tmp->stats.DL_CRC_errors,
550 DL_RETX_FRAMES_COLUMN, tmp->stats.DL_retx_frames,
555 /* If there is a UE selected, update its counters in details window */
556 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(hs->ue_table));
557 if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
560 gtk_tree_model_get(model, &iter, TABLE_COLUMN, &ep, -1);
561 mac_lte_ue_details(ep);
566 /* What to do when a list item is selected/unselected */
567 static void mac_lte_select_cb(GtkTreeSelection *sel, gpointer data _U_)
573 if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
574 /* Show details of selected UE */
575 gtk_tree_model_get(model, &iter, TABLE_COLUMN, &ep, -1);
576 mac_lte_ue_details(ep);
579 mac_lte_ue_details(NULL);
585 /* Destroy the stats window */
586 static void win_destroy_cb(GtkWindow *win _U_, gpointer data)
588 mac_lte_stat_t *hs = (mac_lte_stat_t *)data;
590 protect_thread_critical_region();
591 remove_tap_listener(hs);
592 unprotect_thread_critical_region();
594 if (mac_lte_stat_dlg_w != NULL) {
595 window_destroy(mac_lte_stat_dlg_w);
596 mac_lte_stat_dlg_w = NULL;
598 mac_lte_stat_reset(hs);
603 /* Create a new MAC LTE stats dialog */
604 static void mac_lte_stat_dlg_create(void)
607 GString *error_string;
608 GtkWidget *ues_scrolled_window;
610 GtkWidget *top_level_vbox;
612 GtkWidget *common_row_hbox;
614 GtkWidget *selected_ue_hb;
616 GtkWidget *selected_ue_vbox[NUM_CHANNEL_COLUMNS];
617 GtkWidget *selected_ue_column_titles[5];
624 GtkTreeView *tree_view;
625 GtkCellRenderer *renderer;
626 GtkTreeViewColumn *column;
627 GtkTreeSelection *sel;
632 hs = g_malloc(sizeof(mac_lte_stat_t));
636 g_snprintf(title, sizeof(title), "Wireshark: LTE MAC Statistics: %s",
637 cf_get_display_name(&cfile));
638 mac_lte_stat_dlg_w = window_new_with_geom(GTK_WINDOW_TOPLEVEL, title, "LTE MAC Statistics");
641 gtk_window_set_default_size(GTK_WINDOW(mac_lte_stat_dlg_w), 750, 300);
643 /* Will stack widgets vertically inside dlg */
644 top_level_vbox = gtk_vbox_new(FALSE, 3); /* FALSE = not homogeneous */
645 gtk_container_add(GTK_CONTAINER(mac_lte_stat_dlg_w), top_level_vbox);
647 gtk_container_set_border_width(GTK_CONTAINER(top_level_vbox), 6);
648 gtk_widget_show(top_level_vbox);
651 /**********************************************/
652 /* Common Channel data */
653 /**********************************************/
654 mac_lte_stat_common_channel_lb = gtk_frame_new("Common Channel Data");
656 /* Will add BCH and PCH counters into one row */
657 common_row_hbox = gtk_hbox_new(FALSE, 0);
658 gtk_container_add(GTK_CONTAINER(mac_lte_stat_common_channel_lb), common_row_hbox);
659 gtk_container_set_border_width(GTK_CONTAINER(common_row_hbox), 5);
661 gtk_box_pack_start(GTK_BOX(top_level_vbox), mac_lte_stat_common_channel_lb, FALSE, FALSE, 0);
663 /* Create labels (that will hold label and counter value) */
664 mac_lte_common_bch_frames = gtk_label_new("BCH Frames:");
665 gtk_misc_set_alignment(GTK_MISC(mac_lte_common_bch_frames), 0.0f, .5f);
666 gtk_container_add(GTK_CONTAINER(common_row_hbox), mac_lte_common_bch_frames);
667 gtk_widget_show(mac_lte_common_bch_frames);
669 mac_lte_common_bch_bytes = gtk_label_new("BCH Bytes:");
670 gtk_misc_set_alignment(GTK_MISC(mac_lte_common_bch_bytes), 0.0f, .5f);
671 gtk_container_add(GTK_CONTAINER(common_row_hbox), mac_lte_common_bch_bytes);
672 gtk_widget_show(mac_lte_common_bch_bytes);
674 mac_lte_common_pch_frames = gtk_label_new("PCH Frames:");
675 gtk_misc_set_alignment(GTK_MISC(mac_lte_common_pch_frames), 0.0f, .5f);
676 gtk_container_add(GTK_CONTAINER(common_row_hbox), mac_lte_common_pch_frames);
677 gtk_widget_show(mac_lte_common_pch_frames);
679 mac_lte_common_pch_bytes = gtk_label_new("PCH Bytes:");
680 gtk_misc_set_alignment(GTK_MISC(mac_lte_common_pch_bytes), 0.0f, .5f);
681 gtk_container_add(GTK_CONTAINER(common_row_hbox), mac_lte_common_pch_bytes);
682 gtk_widget_show(mac_lte_common_pch_bytes);
684 mac_lte_common_rar_frames = gtk_label_new("RAR Frames:");
685 gtk_misc_set_alignment(GTK_MISC(mac_lte_common_rar_frames), 0.0f, .5f);
686 gtk_container_add(GTK_CONTAINER(common_row_hbox), mac_lte_common_rar_frames);
687 gtk_widget_show(mac_lte_common_rar_frames);
689 mac_lte_common_rar_entries = gtk_label_new("RAR Entries:");
690 gtk_misc_set_alignment(GTK_MISC(mac_lte_common_rar_entries), 0.0f, .5f);
691 gtk_container_add(GTK_CONTAINER(common_row_hbox), mac_lte_common_rar_entries);
692 gtk_widget_show(mac_lte_common_rar_entries);
694 /**********************************************/
696 /**********************************************/
698 mac_lte_stat_ues_lb = gtk_frame_new("UL/DL-SCH Data (0 UEs)");
699 ues_vb = gtk_vbox_new(FALSE, 0);
700 gtk_container_add(GTK_CONTAINER(mac_lte_stat_ues_lb), ues_vb);
701 gtk_container_set_border_width(GTK_CONTAINER(ues_vb), 5);
703 ues_scrolled_window = scrolled_window_new(NULL, NULL);
704 gtk_box_pack_start(GTK_BOX(ues_vb), ues_scrolled_window, TRUE, TRUE, 0);
705 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(ues_scrolled_window),
708 /* Create the table of UE data */
709 store = gtk_list_store_new(NUM_UE_COLUMNS, G_TYPE_INT,
710 G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, /* UL */
711 G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, /* DL */
713 hs->ue_table = GTK_TREE_VIEW(tree_view_new(GTK_TREE_MODEL(store)));
714 gtk_container_add(GTK_CONTAINER (ues_scrolled_window), GTK_WIDGET(hs->ue_table));
715 g_object_unref(G_OBJECT(store));
717 tree_view = hs->ue_table;
718 gtk_tree_view_set_headers_visible(tree_view, TRUE);
719 gtk_tree_view_set_headers_clickable(tree_view, TRUE);
721 /* Create the titles for each column of the per-UE table */
722 for (i = 0; i < TABLE_COLUMN; i++) {
723 renderer = gtk_cell_renderer_text_new();
724 column = gtk_tree_view_column_new_with_attributes(ue_titles[i], renderer,
726 gtk_tree_view_column_set_sort_column_id(column, i);
729 /* Expand first column (RNTI, which is Key) */
730 gtk_tree_view_column_set_expand(column, TRUE);
732 /* For other columns, set all of the free space to be on the left */
733 g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL);
735 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
736 gtk_tree_view_column_set_resizable(column, TRUE);
737 gtk_tree_view_append_column(tree_view, column);
740 /* Set callback function for selecting a row in the UE table */
741 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(hs->ue_table));
742 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
743 g_signal_connect(sel, "changed", G_CALLBACK(mac_lte_select_cb), hs);
745 gtk_box_pack_start(GTK_BOX(top_level_vbox), mac_lte_stat_ues_lb, TRUE, TRUE, 0);
748 /**********************************************/
749 /* Details of selected UE */
750 /**********************************************/
752 mac_lte_stat_selected_ue_lb = gtk_frame_new("Selected UE details");
754 selected_ue_hb = gtk_hbox_new(FALSE, 6);
755 gtk_container_add(GTK_CONTAINER(mac_lte_stat_selected_ue_lb), selected_ue_hb);
756 gtk_container_set_border_width(GTK_CONTAINER(selected_ue_hb), 5);
758 /********************************/
759 /* First (row titles) column */
760 selected_ue_vbox[0] = gtk_vbox_new(FALSE, 0);
761 gtk_container_add(GTK_CONTAINER(selected_ue_hb), selected_ue_vbox[0]);
763 selected_ue_column_titles[0] = gtk_label_new("");
764 gtk_misc_set_alignment(GTK_MISC(selected_ue_column_titles[0]), 0.0f, 0.0f);
765 gtk_container_add(GTK_CONTAINER(selected_ue_vbox[0]), selected_ue_column_titles[0]);
767 for (n=1; n < 5; n++) {
768 selected_ue_column_titles[n] = gtk_label_new(selected_ue_row_names[n-1]);
769 gtk_misc_set_alignment(GTK_MISC(selected_ue_column_titles[n]), 0.0f, 0.0f);
770 gtk_container_add(GTK_CONTAINER(selected_ue_vbox[0]), selected_ue_column_titles[n]);
771 gtk_widget_show(selected_ue_column_titles[n]);
775 /*************************/
777 for (i=CCCH_COLUMN; i < NUM_CHANNEL_COLUMNS; i++) {
778 selected_ue_vbox[i] = gtk_vbox_new(FALSE, 0);
779 gtk_container_add(GTK_CONTAINER(selected_ue_hb), selected_ue_vbox[i]);
782 selected_ue_column_entry[i][0] = gtk_label_new(channel_titles[i-1]);
783 gtk_misc_set_alignment(GTK_MISC(selected_ue_column_entry[i][0]), 0.5f, 0.0f);
784 gtk_container_add(GTK_CONTAINER(selected_ue_vbox[i]), selected_ue_column_entry[i][0]);
787 /* Counts for this channel */
788 for (n=1; n < 5; n++) {
789 selected_ue_column_entry[i][n] = gtk_label_new("0");
790 gtk_misc_set_alignment(GTK_MISC(selected_ue_column_entry[i][n]), 1.0f, 0.0f);
791 gtk_container_add(GTK_CONTAINER(selected_ue_vbox[i]), selected_ue_column_entry[i][n]);
792 gtk_widget_show(selected_ue_column_entry[i][n]);
796 gtk_box_pack_start(GTK_BOX(top_level_vbox), mac_lte_stat_selected_ue_lb, FALSE, FALSE, 0);
799 /**********************************************/
800 /* Register the tap listener */
801 /**********************************************/
803 error_string = register_tap_listener("mac-lte", hs, NULL,
808 simple_dialog (ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
809 g_string_free (error_string, TRUE);
815 /************************************/
817 /************************************/
819 bbox = dlg_button_row_new (GTK_STOCK_CLOSE, GTK_STOCK_HELP, NULL);
820 gtk_box_pack_end (GTK_BOX(top_level_vbox), bbox, FALSE, FALSE, 0);
822 /* Add the close button */
823 close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
824 window_set_cancel_button(mac_lte_stat_dlg_w, close_bt, window_cancel_button_cb);
826 help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
827 g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_STATS_LTE_MAC_TRAFFIC_DIALOG);
830 g_signal_connect(mac_lte_stat_dlg_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
831 g_signal_connect(mac_lte_stat_dlg_w, "destroy", G_CALLBACK(win_destroy_cb), hs);
833 /* Show the window */
834 gtk_widget_show_all(mac_lte_stat_dlg_w);
835 window_present(mac_lte_stat_dlg_w);
838 cf_retap_packets(&cfile, FALSE);
839 gdk_window_raise(mac_lte_stat_dlg_w->window);
843 /* Show window, creating if necessary */
844 static void mac_lte_stat_launch(GtkWidget *w _U_, gpointer data _U_)
846 if (mac_lte_stat_dlg_w) {
847 reactivate_window(mac_lte_stat_dlg_w);
849 mac_lte_stat_dlg_create();
853 /* Register this tap listener (need void on own so line register function found) */
855 register_tap_listener_mac_lte_stat(void)
857 register_stat_menu_item("LTE MAC...", REGISTER_STAT_GROUP_TELEPHONY,
858 mac_lte_stat_launch, NULL, NULL, NULL);