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 - Break down traffic by cell?
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",
411 mac_stat_ep ? mac_stat_ep->stats.UL_sdus_for_lcid[n] : 0);
412 gtk_label_set_text(GTK_LABEL(selected_ue_column_entry[n+1][1]), buff);
417 g_snprintf(buff, sizeof(buff), "%u",
418 mac_stat_ep->stats.is_predefined_data ? mac_stat_ep->stats.UL_frames : 0);
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",
436 mac_stat_ep->stats.is_predefined_data ? mac_stat_ep->stats.UL_total_bytes : 0);
439 g_snprintf(buff, sizeof(buff), "%u", 0);
441 gtk_label_set_text(GTK_LABEL(selected_ue_column_entry[PREDEFINED_COLUMN][2]), buff);
445 for (n=0; n < PREDEFINED_COLUMN-1; n++) {
446 g_snprintf(buff, sizeof(buff), "%u",
447 mac_stat_ep ? mac_stat_ep->stats.DL_sdus_for_lcid[n] : 0);
448 gtk_label_set_text(GTK_LABEL(selected_ue_column_entry[n+1][3]), buff);
452 g_snprintf(buff, sizeof(buff), "%u",
453 mac_stat_ep->stats.is_predefined_data ? mac_stat_ep->stats.DL_frames : 0);
456 g_snprintf(buff, sizeof(buff), "%u", 0);
458 gtk_label_set_text(GTK_LABEL(selected_ue_column_entry[PREDEFINED_COLUMN][3]), buff);
462 for (n=0; n < PREDEFINED_COLUMN-1; n++) {
463 g_snprintf(buff, sizeof(buff), "%u",
464 mac_stat_ep ? mac_stat_ep->stats.DL_bytes_for_lcid[n] : 0);
465 gtk_label_set_text(GTK_LABEL(selected_ue_column_entry[n+1][4]), buff);
469 g_snprintf(buff, sizeof(buff), "%u",
470 mac_stat_ep->stats.is_predefined_data ? mac_stat_ep->stats.DL_total_bytes : 0);
473 g_snprintf(buff, sizeof(buff), "%u", 0);
475 gtk_label_set_text(GTK_LABEL(selected_ue_column_entry[PREDEFINED_COLUMN][4]), buff);
480 /* (Re)draw the whole dialog window */
482 mac_lte_stat_draw(void *phs)
485 guint16 number_of_ues = 0;
488 /* Look up the statistics window */
489 mac_lte_stat_t *hs = (mac_lte_stat_t *)phs;
490 mac_lte_ep_t* list = hs->ep_list, *tmp = 0;
492 GtkListStore *ues_store;
493 GtkTreeSelection *sel;
497 /* Common channel data */
498 g_snprintf(buff, sizeof(buff), "BCH Frames: %u", common_stats.bch_frames);
499 gtk_label_set_text(GTK_LABEL(mac_lte_common_bch_frames), buff);
500 g_snprintf(buff, sizeof(buff), "BCH Bytes: %u", common_stats.bch_bytes);
501 gtk_label_set_text(GTK_LABEL(mac_lte_common_bch_bytes), buff);
502 g_snprintf(buff, sizeof(buff), "PCH Frames: %u", common_stats.pch_frames);
503 gtk_label_set_text(GTK_LABEL(mac_lte_common_pch_frames), buff);
504 g_snprintf(buff, sizeof(buff), "PCH Bytes: %u", common_stats.pch_bytes);
505 gtk_label_set_text(GTK_LABEL(mac_lte_common_pch_bytes), buff);
506 g_snprintf(buff, sizeof(buff), "RAR Frames: %u", common_stats.rar_frames);
507 gtk_label_set_text(GTK_LABEL(mac_lte_common_rar_frames), buff);
508 g_snprintf(buff, sizeof(buff), "RAR Entries: %u", common_stats.rar_entries);
509 gtk_label_set_text(GTK_LABEL(mac_lte_common_rar_entries), buff);
512 /* Per-UE table entries */
513 ues_store = GTK_LIST_STORE(gtk_tree_view_get_model(hs->ue_table));
515 /* Set title that shows how many UEs currently in table */
516 for (tmp = list; (tmp!=NULL); tmp=tmp->next, number_of_ues++);
517 g_snprintf(title, sizeof(title), "UL/DL-SCH data (%u UEs)", number_of_ues);
518 gtk_frame_set_label(GTK_FRAME(mac_lte_stat_ues_lb), title);
520 /* Update title to include number of UEs and frames */
521 g_snprintf(title, sizeof(title), "Wireshark: LTE MAC Traffic Statistics: %s (%u UEs, %u frames)",
522 cf_get_display_name(&cfile),
524 common_stats.all_frames);
525 gtk_window_set_title(GTK_WINDOW(mac_lte_stat_dlg_w), title);
529 /* For each row/UE/C-RNTI in the model */
530 for (tmp = list; tmp; tmp=tmp->next) {
531 if (tmp->iter_valid != TRUE) {
532 /* Add to list control if not drawn this UE before */
533 gtk_list_store_append(ues_store, &tmp->iter);
534 tmp->iter_valid = TRUE;
537 /* Set each column for this row */
538 gtk_list_store_set(ues_store, &tmp->iter,
539 RNTI_COLUMN, tmp->stats.rnti,
540 UL_FRAMES_COLUMN, tmp->stats.UL_frames,
541 UL_BYTES_COLUMN, tmp->stats.UL_total_bytes,
542 UL_CRC_ERRORS_COLUMN, tmp->stats.UL_CRC_errors,
543 UL_RETX_FRAMES_COLUMN, tmp->stats.UL_retx_frames,
544 DL_FRAMES_COLUMN, tmp->stats.DL_frames,
545 DL_BYTES_COLUMN, tmp->stats.DL_total_bytes,
546 DL_CRC_ERRORS_COLUMN, tmp->stats.DL_CRC_errors,
547 DL_RETX_FRAMES_COLUMN, tmp->stats.DL_retx_frames,
552 /* If there is a UE selected, update its counters in details window */
553 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(hs->ue_table));
554 if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
557 gtk_tree_model_get(model, &iter, TABLE_COLUMN, &ep, -1);
558 mac_lte_ue_details(ep);
563 /* What to do when a list item is selected/unselected */
564 static void mac_lte_select_cb(GtkTreeSelection *sel, gpointer data _U_)
570 if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
571 /* Show details of selected UE */
572 gtk_tree_model_get(model, &iter, TABLE_COLUMN, &ep, -1);
573 mac_lte_ue_details(ep);
576 mac_lte_ue_details(NULL);
582 /* Destroy the stats window */
583 static void win_destroy_cb(GtkWindow *win _U_, gpointer data)
585 mac_lte_stat_t *hs = (mac_lte_stat_t *)data;
587 protect_thread_critical_region();
588 remove_tap_listener(hs);
589 unprotect_thread_critical_region();
591 if (mac_lte_stat_dlg_w != NULL) {
592 window_destroy(mac_lte_stat_dlg_w);
593 mac_lte_stat_dlg_w = NULL;
595 mac_lte_stat_reset(hs);
600 /* Create a new MAC LTE stats dialog */
601 static void mac_lte_stat_dlg_create(void)
604 GString *error_string;
605 GtkWidget *ues_scrolled_window;
607 GtkWidget *top_level_vbox;
609 GtkWidget *common_row_hbox;
611 GtkWidget *selected_ue_hb;
613 GtkWidget *selected_ue_vbox[NUM_CHANNEL_COLUMNS];
614 GtkWidget *selected_ue_column_titles[5];
621 GtkTreeView *tree_view;
622 GtkCellRenderer *renderer;
623 GtkTreeViewColumn *column;
624 GtkTreeSelection *sel;
629 hs = g_malloc(sizeof(mac_lte_stat_t));
633 g_snprintf(title, sizeof(title), "Wireshark: LTE MAC Statistics: %s",
634 cf_get_display_name(&cfile));
635 mac_lte_stat_dlg_w = window_new_with_geom(GTK_WINDOW_TOPLEVEL, title, "LTE MAC Statistics");
638 gtk_window_set_default_size(GTK_WINDOW(mac_lte_stat_dlg_w), 750, 300);
640 /* Will stack widgets vertically inside dlg */
641 top_level_vbox = gtk_vbox_new(FALSE, 3); /* FALSE = not homogeneous */
642 gtk_container_add(GTK_CONTAINER(mac_lte_stat_dlg_w), top_level_vbox);
644 gtk_container_set_border_width(GTK_CONTAINER(top_level_vbox), 6);
645 gtk_widget_show(top_level_vbox);
648 /**********************************************/
649 /* Common Channel data */
650 /**********************************************/
651 mac_lte_stat_common_channel_lb = gtk_frame_new("Common Channel Data");
653 /* Will add BCH and PCH counters into one row */
654 common_row_hbox = gtk_hbox_new(FALSE, 0);
655 gtk_container_add(GTK_CONTAINER(mac_lte_stat_common_channel_lb), common_row_hbox);
656 gtk_container_set_border_width(GTK_CONTAINER(common_row_hbox), 5);
658 gtk_box_pack_start(GTK_BOX(top_level_vbox), mac_lte_stat_common_channel_lb, FALSE, FALSE, 0);
660 /* Create labels (that will hold label and counter value) */
661 mac_lte_common_bch_frames = gtk_label_new("BCH Frames:");
662 gtk_misc_set_alignment(GTK_MISC(mac_lte_common_bch_frames), 0.0f, .5f);
663 gtk_container_add(GTK_CONTAINER(common_row_hbox), mac_lte_common_bch_frames);
664 gtk_widget_show(mac_lte_common_bch_frames);
666 mac_lte_common_bch_bytes = gtk_label_new("BCH Bytes:");
667 gtk_misc_set_alignment(GTK_MISC(mac_lte_common_bch_bytes), 0.0f, .5f);
668 gtk_container_add(GTK_CONTAINER(common_row_hbox), mac_lte_common_bch_bytes);
669 gtk_widget_show(mac_lte_common_bch_bytes);
671 mac_lte_common_pch_frames = gtk_label_new("PCH Frames:");
672 gtk_misc_set_alignment(GTK_MISC(mac_lte_common_pch_frames), 0.0f, .5f);
673 gtk_container_add(GTK_CONTAINER(common_row_hbox), mac_lte_common_pch_frames);
674 gtk_widget_show(mac_lte_common_pch_frames);
676 mac_lte_common_pch_bytes = gtk_label_new("PCH Bytes:");
677 gtk_misc_set_alignment(GTK_MISC(mac_lte_common_pch_bytes), 0.0f, .5f);
678 gtk_container_add(GTK_CONTAINER(common_row_hbox), mac_lte_common_pch_bytes);
679 gtk_widget_show(mac_lte_common_pch_bytes);
681 mac_lte_common_rar_frames = gtk_label_new("RAR Frames:");
682 gtk_misc_set_alignment(GTK_MISC(mac_lte_common_rar_frames), 0.0f, .5f);
683 gtk_container_add(GTK_CONTAINER(common_row_hbox), mac_lte_common_rar_frames);
684 gtk_widget_show(mac_lte_common_rar_frames);
686 mac_lte_common_rar_entries = gtk_label_new("RAR Entries:");
687 gtk_misc_set_alignment(GTK_MISC(mac_lte_common_rar_entries), 0.0f, .5f);
688 gtk_container_add(GTK_CONTAINER(common_row_hbox), mac_lte_common_rar_entries);
689 gtk_widget_show(mac_lte_common_rar_entries);
691 /**********************************************/
693 /**********************************************/
695 mac_lte_stat_ues_lb = gtk_frame_new("UL/DL-SCH Data (0 UEs)");
696 ues_vb = gtk_vbox_new(FALSE, 0);
697 gtk_container_add(GTK_CONTAINER(mac_lte_stat_ues_lb), ues_vb);
698 gtk_container_set_border_width(GTK_CONTAINER(ues_vb), 5);
700 ues_scrolled_window = scrolled_window_new(NULL, NULL);
701 gtk_box_pack_start(GTK_BOX(ues_vb), ues_scrolled_window, TRUE, TRUE, 0);
702 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(ues_scrolled_window),
705 /* Create the table of UE data */
706 store = gtk_list_store_new(NUM_UE_COLUMNS, G_TYPE_INT,
707 G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, /* UL */
708 G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, /* DL */
710 hs->ue_table = GTK_TREE_VIEW(tree_view_new(GTK_TREE_MODEL(store)));
711 gtk_container_add(GTK_CONTAINER (ues_scrolled_window), GTK_WIDGET(hs->ue_table));
712 g_object_unref(G_OBJECT(store));
714 tree_view = hs->ue_table;
715 gtk_tree_view_set_headers_visible(tree_view, TRUE);
716 gtk_tree_view_set_headers_clickable(tree_view, TRUE);
718 /* Create the titles for each column of the per-UE table */
719 for (i = 0; i < TABLE_COLUMN; i++) {
720 renderer = gtk_cell_renderer_text_new();
721 column = gtk_tree_view_column_new_with_attributes(ue_titles[i], renderer,
723 gtk_tree_view_column_set_sort_column_id(column, i);
726 /* Expand first column (RNTI, which is Key) */
727 gtk_tree_view_column_set_expand(column, TRUE);
729 /* For other columns, set all of the free space to be on the left */
730 g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL);
732 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
733 gtk_tree_view_column_set_resizable(column, TRUE);
734 gtk_tree_view_append_column(tree_view, column);
737 /* Set callback function for selecting a row in the UE table */
738 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(hs->ue_table));
739 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
740 g_signal_connect(sel, "changed", G_CALLBACK(mac_lte_select_cb), hs);
742 gtk_box_pack_start(GTK_BOX(top_level_vbox), mac_lte_stat_ues_lb, TRUE, TRUE, 0);
745 /**********************************************/
746 /* Details of selected UE */
747 /**********************************************/
749 mac_lte_stat_selected_ue_lb = gtk_frame_new("Selected UE details");
751 selected_ue_hb = gtk_hbox_new(FALSE, 6);
752 gtk_container_add(GTK_CONTAINER(mac_lte_stat_selected_ue_lb), selected_ue_hb);
753 gtk_container_set_border_width(GTK_CONTAINER(selected_ue_hb), 5);
755 /********************************/
756 /* First (row titles) column */
757 selected_ue_vbox[0] = gtk_vbox_new(FALSE, 0);
758 gtk_container_add(GTK_CONTAINER(selected_ue_hb), selected_ue_vbox[0]);
760 selected_ue_column_titles[0] = gtk_label_new("");
761 gtk_misc_set_alignment(GTK_MISC(selected_ue_column_titles[0]), 0.0f, 0.0f);
762 gtk_container_add(GTK_CONTAINER(selected_ue_vbox[0]), selected_ue_column_titles[0]);
764 for (n=1; n < 5; n++) {
765 selected_ue_column_titles[n] = gtk_label_new(selected_ue_row_names[n-1]);
766 gtk_misc_set_alignment(GTK_MISC(selected_ue_column_titles[n]), 0.0f, 0.0f);
767 gtk_container_add(GTK_CONTAINER(selected_ue_vbox[0]), selected_ue_column_titles[n]);
768 gtk_widget_show(selected_ue_column_titles[n]);
772 /*************************/
774 for (i=CCCH_COLUMN; i < NUM_CHANNEL_COLUMNS; i++) {
775 selected_ue_vbox[i] = gtk_vbox_new(FALSE, 0);
776 gtk_container_add(GTK_CONTAINER(selected_ue_hb), selected_ue_vbox[i]);
779 selected_ue_column_entry[i][0] = gtk_label_new(channel_titles[i-1]);
780 gtk_misc_set_alignment(GTK_MISC(selected_ue_column_entry[i][0]), 0.5f, 0.0f);
781 gtk_container_add(GTK_CONTAINER(selected_ue_vbox[i]), selected_ue_column_entry[i][0]);
784 /* Counts for this channel */
785 for (n=1; n < 5; n++) {
786 selected_ue_column_entry[i][n] = gtk_label_new("0");
787 gtk_misc_set_alignment(GTK_MISC(selected_ue_column_entry[i][n]), 1.0f, 0.0f);
788 gtk_container_add(GTK_CONTAINER(selected_ue_vbox[i]), selected_ue_column_entry[i][n]);
789 gtk_widget_show(selected_ue_column_entry[i][n]);
793 gtk_box_pack_start(GTK_BOX(top_level_vbox), mac_lte_stat_selected_ue_lb, FALSE, FALSE, 0);
796 /**********************************************/
797 /* Register the tap listener */
798 /**********************************************/
800 error_string = register_tap_listener("mac-lte", hs, NULL, 0,
805 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
806 g_string_free(error_string, TRUE);
812 /************************************/
814 /************************************/
816 bbox = dlg_button_row_new (GTK_STOCK_CLOSE, GTK_STOCK_HELP, NULL);
817 gtk_box_pack_end (GTK_BOX(top_level_vbox), bbox, FALSE, FALSE, 0);
819 /* Add the close button */
820 close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
821 window_set_cancel_button(mac_lte_stat_dlg_w, close_bt, window_cancel_button_cb);
823 help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
824 g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_STATS_LTE_MAC_TRAFFIC_DIALOG);
827 g_signal_connect(mac_lte_stat_dlg_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
828 g_signal_connect(mac_lte_stat_dlg_w, "destroy", G_CALLBACK(win_destroy_cb), hs);
830 /* Show the window */
831 gtk_widget_show_all(mac_lte_stat_dlg_w);
832 window_present(mac_lte_stat_dlg_w);
835 cf_retap_packets(&cfile);
836 gdk_window_raise(mac_lte_stat_dlg_w->window);
840 /* Show window, creating if necessary */
841 static void mac_lte_stat_launch(GtkWidget *w _U_, gpointer data _U_)
843 if (mac_lte_stat_dlg_w) {
844 reactivate_window(mac_lte_stat_dlg_w);
846 mac_lte_stat_dlg_create();
850 /* Register this tap listener (need void on own so line register function found) */
852 register_tap_listener_mac_lte_stat(void)
854 register_stat_menu_item("_LTE MAC...", REGISTER_STAT_GROUP_TELEPHONY,
855 mac_lte_stat_launch, NULL, NULL, NULL);