summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Mathieson <martin.r.mathieson@googlemail.com>2013-08-30 04:08:57 +0000
committerMartin Mathieson <martin.r.mathieson@googlemail.com>2013-08-30 04:08:57 +0000
commita09ee6af031b399848a0322054519489f6d963f6 (patch)
treeb8700ebd6c5024a4504ff6c1aa30a6249b9af0c7
parentd9eb37b849a70a8bc8ad0c61b3fa8f2c3d689f7c (diff)
downloadwireshark-a09ee6af031b399848a0322054519489f6d963f6.tar.gz
The first step towards tracking and showing DRX info in MAC:
- send release from RRC - show current DRX config from each frame, including a link back to the RRC config frame - show simple DRX state for each frame (currently only offset into long cycle and whether within long cycle 'on' period) TODO: - simulate timers in response to new UL/DL transmissions or DL CRC errors - maintain whether in long or short cycle - show state of all timers svn path=/trunk/; revision=51585
-rw-r--r--asn1/lte-rrc/lte-rrc.cnf23
-rw-r--r--asn1/lte-rrc/packet-lte-rrc-template.c16
-rw-r--r--epan/dissectors/packet-mac-lte.c287
-rw-r--r--epan/dissectors/packet-mac-lte.h23
4 files changed, 329 insertions, 20 deletions
diff --git a/asn1/lte-rrc/lte-rrc.cnf b/asn1/lte-rrc/lte-rrc.cnf
index 4363dc8366..7c0b0a7d40 100644
--- a/asn1/lte-rrc/lte-rrc.cnf
+++ b/asn1/lte-rrc/lte-rrc.cnf
@@ -747,9 +747,20 @@ CQI-ReportConfigSCell-r10/nomPDSCH-RS-EPRE-Offset-r10 STRINGS=VALS(lte_rrc_nomPD
fields overwritten in the R11 extension */
drx_config_t *drx_config = private_data_get_drx_config(actx);
%(DEFAULT_BODY)s
- /* Verify that config is valid */
if (drx_config->configured) {
+ mac_lte_info* p_mac_lte_info;
+
+ /* Verify that config is valid */
drx_check_config_sane(drx_config, actx);
+
+ /* Look for UE identifier */
+ p_mac_lte_info = (mac_lte_info *)p_get_proto_data(actx->pinfo->fd, proto_mac_lte, 0);
+ if (p_mac_lte_info != NULL) {
+ /* If found, configure MAC with DRX config */
+ set_mac_lte_drx_config(p_mac_lte_info->ueid, drx_config, actx->pinfo);
+ }
+
+ /* Clear out state */
drx_config->configured = FALSE;
}
@@ -1478,3 +1489,13 @@ SoundingRS-UL-ConfigDedicated/setup/duration STRINGS=TFS(&lte_rrc_duration_val)
/* Presumably config->shortCycleConfigured will be set... */
config->shortCycle = 4;
+#.FN_BODY DRX-Config/release
+ mac_lte_info* p_mac_lte_info;
+%(DEFAULT_BODY)s
+ /* Look for UE identifier */
+ p_mac_lte_info = (mac_lte_info *)p_get_proto_data(actx->pinfo->fd, proto_mac_lte, 0);
+ if (p_mac_lte_info != NULL) {
+ /* If found, tell MAC to release DRX config */
+ set_mac_lte_drx_config_release(p_mac_lte_info->ueid, actx->pinfo);
+ }
+
diff --git a/asn1/lte-rrc/packet-lte-rrc-template.c b/asn1/lte-rrc/packet-lte-rrc-template.c
index 10c6136002..38110e9ed7 100644
--- a/asn1/lte-rrc/packet-lte-rrc-template.c
+++ b/asn1/lte-rrc/packet-lte-rrc-template.c
@@ -1792,22 +1792,6 @@ static const value_string lte_rrc_warningType_vals[] = {
/* through this API, which ensures that they will not overwrite each other!! */
/*****************************************************************************/
-/* Dedicated DRX config. Currently used to verify that a sensible config is given.
- TODO: would be good to configure MAC with these settings and (optionally) show
- DRX config and state (cycles/timers) attached to each UL/DL PDU! */
-typedef struct drx_config_t {
- gboolean configured;
- guint32 onDurationTimer;
- guint32 inactivityTimer;
- guint32 retransmissionTimer;
- guint32 longCycle;
- guint32 cycleOffset;
- /* Optional Short cycle */
- gboolean shortCycleConfigured;
- guint32 shortCycle;
- guint32 shortCycleTimer;
-} drx_config_t;
-
/**********************************************************/
/* Struct to store all current uses of packet private data */
diff --git a/epan/dissectors/packet-mac-lte.c b/epan/dissectors/packet-mac-lte.c
index 4b18ea70cb..f67fe04de2 100644
--- a/epan/dissectors/packet-mac-lte.c
+++ b/epan/dissectors/packet-mac-lte.c
@@ -222,7 +222,6 @@ static int hf_mac_lte_ul_harq_resend_time_since_previous_frame = -1;
static int hf_mac_lte_ul_harq_resend_next_frame = -1;
static int hf_mac_lte_ul_harq_resend_time_until_next_frame = -1;
-
static int hf_mac_lte_grant_answering_sr = -1;
static int hf_mac_lte_failure_answering_sr = -1;
static int hf_mac_lte_sr_leading_to_failure = -1;
@@ -231,6 +230,20 @@ static int hf_mac_lte_sr_invalid_event = -1;
static int hf_mac_lte_sr_time_since_request = -1;
static int hf_mac_lte_sr_time_until_answer = -1;
+static int hf_mac_lte_drx_config = -1;
+static int hf_mac_lte_drx_config_frame_num = -1;
+static int hf_mac_lte_drx_config_long_cycle = -1;
+static int hf_mac_lte_drx_config_cycle_offset = -1;
+static int hf_mac_lte_drx_config_onduration_timer = -1;
+static int hf_mac_lte_drx_config_inactivity_timer = -1;
+static int hf_mac_lte_drx_config_retransmission_timer = -1;
+static int hf_mac_lte_drx_config_short_cycle = -1;
+static int hf_mac_lte_drx_config_short_cycle_timer = -1;
+
+static int hf_mac_lte_drx_state = -1;
+static int hf_mac_lte_drx_state_long_cycle_offset = -1;
+static int hf_mac_lte_drx_state_long_cycle_on = -1;
+
/* Subtrees. */
static int ett_mac_lte = -1;
@@ -256,6 +269,8 @@ static int ett_mac_lte_extended_power_headroom = -1;
static int ett_mac_lte_extended_power_headroom_cell = -1;
static int ett_mac_lte_mch_scheduling_info = -1;
static int ett_mac_lte_oob = -1;
+static int ett_mac_lte_drx_config = -1;
+static int ett_mac_lte_drx_state = -1;
@@ -845,6 +860,11 @@ static gint global_mac_lte_layer_to_show = (gint)ShowRLCLayer;
/* Whether to decode Contention Resolution body as UL CCCH */
static gboolean global_mac_lte_decode_cr_body = FALSE;
+/* Whether to record config and try to show DRX state for each configured UE */
+static gboolean global_mac_lte_show_drx = FALSE;
+
+
+
/* When showing RLC info, count PDUs so can append info column properly */
static guint8 s_number_of_rlc_pdus_shown = 0;
@@ -1124,6 +1144,127 @@ typedef struct SRResult {
It maps (SRFrameNum -> SRResult) */
static GHashTable *mac_lte_sr_request_hash = NULL;
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* DRX State */
+/* Store config for each configured UE */
+/* TODO: Keep track of cycles/timer state */
+
+
+/* Entries in this table are maintained during the first pass
+ It maps (UEId -> drx_config_t) */
+static GHashTable *mac_lte_drx_config = NULL;
+
+/* Entries in this table are written during the first pass
+ It maps (Framenum -> drx_config_t) */
+static GHashTable *mac_lte_drx_config_result = NULL;
+
+/* Set DRX information to display for the current MAC frame */
+static void set_drx_info(packet_info *pinfo, mac_lte_info *p_mac_lte_info)
+{
+ /* Look up state of this UE */
+ drx_config_t *drx_config_entry = (drx_config_t *)g_hash_table_lookup(mac_lte_drx_config,
+ GUINT_TO_POINTER((guint)p_mac_lte_info->ueid));
+ if (drx_config_entry != NULL) {
+ /* Copy config into separate struct just for this frame, and add to result table */
+ drx_config_t *frame_config = se_new(drx_config_t);
+ *frame_config = *drx_config_entry;
+ g_hash_table_insert(mac_lte_drx_config_result, GUINT_TO_POINTER(pinfo->fd->num), frame_config);
+ }
+}
+
+/* Show DRX information associated with this MAC frame */
+static void show_drx_info(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, guint16 ueid _U_,
+ mac_lte_info *p_mac_lte_info)
+{
+ drx_config_t *drx_config_entry;
+
+ /* Look up entry by frame number in result table */
+ drx_config_entry = (drx_config_t *)g_hash_table_lookup(mac_lte_drx_config_result,
+ GUINT_TO_POINTER(pinfo->fd->num));
+
+ /* Show available information */
+ if (drx_config_entry != NULL) {
+ guint16 offset_into_long_cycle;
+ gboolean inside_long_on_duration;
+
+ proto_tree *drx_config_tree, *drx_state_tree;
+ proto_item *drx_config_ti, *drx_state_ti, *ti;
+
+ /* Create config subtree */
+ drx_config_ti = proto_tree_add_string_format(tree, hf_mac_lte_drx_config,
+ tvb, 0, 0, "", "DRX Config");
+ drx_config_tree = proto_item_add_subtree(drx_config_ti, ett_mac_lte_drx_config);
+ PROTO_ITEM_SET_GENERATED(drx_config_ti);
+
+ /* Link back to configuration (RRC) frame */
+ ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_frame_num, tvb,
+ 0, 0, drx_config_entry->frameNum);
+ PROTO_ITEM_SET_GENERATED(ti);
+
+ /* Config fields */
+ ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_long_cycle, tvb,
+ 0, 0, drx_config_entry->longCycle);
+ PROTO_ITEM_SET_GENERATED(ti);
+ ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_cycle_offset, tvb,
+ 0, 0, drx_config_entry->cycleOffset);
+ PROTO_ITEM_SET_GENERATED(ti);
+ ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_onduration_timer, tvb,
+ 0, 0, drx_config_entry->onDurationTimer);
+ PROTO_ITEM_SET_GENERATED(ti);
+ ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_inactivity_timer, tvb,
+ 0, 0, drx_config_entry->inactivityTimer);
+ PROTO_ITEM_SET_GENERATED(ti);
+ ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_retransmission_timer, tvb,
+ 0, 0, drx_config_entry->retransmissionTimer);
+ PROTO_ITEM_SET_GENERATED(ti);
+
+ if (drx_config_entry->shortCycleConfigured) {
+ ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_short_cycle, tvb,
+ 0, 0, drx_config_entry->shortCycle);
+ PROTO_ITEM_SET_GENERATED(ti);
+
+ ti = proto_tree_add_uint(drx_config_tree, hf_mac_lte_drx_config_short_cycle_timer, tvb,
+ 0, 0, drx_config_entry->shortCycleTimer);
+ PROTO_ITEM_SET_GENERATED(ti);
+ }
+
+ proto_item_append_text(drx_config_ti, " (Long-cycle=%u cycle-offset=%u onDuration=%u)",
+ drx_config_entry->longCycle, drx_config_entry->cycleOffset,
+ drx_config_entry->onDurationTimer);
+ if (drx_config_entry->shortCycleConfigured) {
+ proto_item_append_text(drx_config_ti, " (Short-cycle=%u Short-cycle-timer=%u)",
+ drx_config_entry->shortCycle, drx_config_entry->shortCycleTimer);
+ }
+
+
+ /* Create state subtree */
+ drx_state_ti = proto_tree_add_string_format(tree, hf_mac_lte_drx_state,
+ tvb, 0, 0, "", "DRX State");
+ drx_state_tree = proto_item_add_subtree(drx_state_ti, ett_mac_lte_drx_state);
+ PROTO_ITEM_SET_GENERATED(drx_state_ti);
+
+ /* Show where we are in current long cycle */
+ offset_into_long_cycle = ((p_mac_lte_info->sysframeNumber*10) + p_mac_lte_info->subframeNumber) %
+ drx_config_entry->longCycle;
+ ti = proto_tree_add_uint(drx_state_tree, hf_mac_lte_drx_state_long_cycle_offset, tvb,
+ 0, 0, offset_into_long_cycle);
+ PROTO_ITEM_SET_GENERATED(ti);
+
+ /* Work out if we're inside long cycle on-duration */
+ inside_long_on_duration = (offset_into_long_cycle >= drx_config_entry->cycleOffset) &&
+ (offset_into_long_cycle <= (drx_config_entry->cycleOffset+drx_config_entry->onDurationTimer));
+ ti = proto_tree_add_boolean(drx_state_tree, hf_mac_lte_drx_state_long_cycle_on, tvb,
+ 0, 0, inside_long_on_duration);
+ PROTO_ITEM_SET_GENERATED(ti);
+
+ proto_item_append_text(drx_state_ti, " (Offset-into-Long=%u, Long-cycle-on=%s)",
+ offset_into_long_cycle, inside_long_on_duration ? "True" : "False");
+ }
+}
+
/**************************************************************************/
@@ -2709,6 +2850,16 @@ static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree
tap_info->raw_length = p_mac_lte_info->length;
+ /* DRX information */
+ if (global_mac_lte_show_drx) {
+ /* Store DRX info to show first time around */
+ if (!pinfo->fd->flags.visited) {
+ set_drx_info(pinfo, p_mac_lte_info);
+ }
+ /* Show stored DRX info */
+ show_drx_info(pinfo, tree, tvb, p_mac_lte_info->ueid, p_mac_lte_info);
+ }
+
/* For uplink frames, if this is logged as a resend, look for original tx */
if (direction == DIRECTION_UPLINK) {
TrackReportedULHARQResend(pinfo, tvb, offset, tree, p_mac_lte_info, retx_ti);
@@ -4399,6 +4550,7 @@ void dissect_mac_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
return;
}
+ /* Show remaining meta information */
ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_sysframe_number,
tvb, 0, 0, p_mac_lte_info->sysframeNumber);
PROTO_ITEM_SET_GENERATED(ti);
@@ -4554,7 +4706,7 @@ void dissect_mac_lte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
ti = proto_tree_add_uint(context_tree, hf_mac_lte_context_carrier_id,
tvb, 0, 0, p_mac_lte_info->carrierId);
PROTO_ITEM_SET_GENERATED(ti);
-
+
/* May also have extra Physical layer attributes set for this frame */
show_extra_phy_parameters(pinfo, tvb, mac_lte_tree, p_mac_lte_info);
@@ -4695,6 +4847,13 @@ static void mac_lte_init_protocol(void)
if (mac_lte_ue_channels_hash) {
g_hash_table_destroy(mac_lte_ue_channels_hash);
}
+ if (mac_lte_drx_config) {
+ g_hash_table_destroy(mac_lte_drx_config);
+ }
+ if (mac_lte_drx_config_result) {
+ g_hash_table_destroy(mac_lte_drx_config_result);
+ }
+
/* Reset structs */
memset(&UL_tti_info, 0, sizeof(UL_tti_info));
@@ -4718,6 +4877,9 @@ static void mac_lte_init_protocol(void)
mac_lte_tti_info_result_hash = g_hash_table_new(mac_lte_framenum_hash_func, mac_lte_framenum_hash_equal);
mac_lte_ue_channels_hash = g_hash_table_new(mac_lte_rnti_hash_func, mac_lte_rnti_hash_equal);
+
+ mac_lte_drx_config = g_hash_table_new(mac_lte_rnti_hash_func, mac_lte_rnti_hash_equal);
+ mac_lte_drx_config_result = g_hash_table_new(mac_lte_framenum_hash_func, mac_lte_framenum_hash_equal);
}
@@ -4828,6 +4990,44 @@ static guint8 get_mac_lte_channel_priority(guint16 ueid, guint8 lcid,
}
}
+/* Configure the DRX state for this UE */
+void set_mac_lte_drx_config(guint16 ueid, drx_config_t *drx_config, packet_info *pinfo)
+{
+ if (global_mac_lte_show_drx && !pinfo->fd->flags.visited) {
+ drx_config_t *drx_config_entry;
+ drx_config_t *result_entry;
+
+ /* Find or create config struct for table entry */
+ drx_config_entry = (drx_config_t *)g_hash_table_lookup(mac_lte_drx_config, GUINT_TO_POINTER((guint)ueid));
+ if (drx_config_entry == NULL) {
+ drx_config_entry = (drx_config_t *)se_new(drx_config_t);
+ }
+ /* Copy in new config */
+ *drx_config_entry = *drx_config;
+ /* Remember frame when last changed */
+ drx_config_entry->frameNum = pinfo->fd->num;
+ /* TODO: remember previous config (if any?) */
+
+ /* Store this snapshot into the result info table */
+ result_entry = (drx_config_t *)se_new(drx_config_t);
+ *result_entry = *drx_config_entry;
+ g_hash_table_insert(mac_lte_drx_config, GUINT_TO_POINTER((guint)ueid), result_entry);
+ }
+}
+
+/* Release DRX config for this UE */
+void set_mac_lte_drx_config_release(guint16 ueid, packet_info *pinfo _U_)
+{
+ /* Find or create config struct for table entry */
+ drx_config_t *drx_config_entry = (drx_config_t *)g_hash_table_lookup(mac_lte_drx_config, GUINT_TO_POINTER((guint)ueid));
+ if (drx_config_entry != NULL) {
+ g_hash_table_remove(mac_lte_drx_config, GUINT_TO_POINTER((guint)ueid));
+ /* TODO: free entry? */
+ }
+}
+
+
+
/* Function to be called from outside this module (e.g. in a plugin) to get per-packet data */
mac_lte_info *get_mac_lte_proto_data(packet_info *pinfo)
{
@@ -5825,6 +6025,79 @@ void proto_register_mac_lte(void)
}
},
+ { &hf_mac_lte_drx_config,
+ { "DRX Configuration",
+ "mac-lte.drx-config", FT_STRING, BASE_NONE,
+ 0, 0x0, NULL, HFILL
+ }
+ },
+ { &hf_mac_lte_drx_config_frame_num,
+ { "Config Frame",
+ "mac-lte.drx-config.config-frame", FT_FRAMENUM, BASE_NONE,
+ 0, 0x0, NULL, HFILL
+ }
+ },
+ { &hf_mac_lte_drx_config_long_cycle,
+ { "Long cycle",
+ "mac-lte.drx-config.long-cycle", FT_UINT16, BASE_DEC,
+ 0, 0x0, NULL, HFILL
+ }
+ },
+ { &hf_mac_lte_drx_config_cycle_offset,
+ { "Cycle offset",
+ "mac-lte.drx-config.cycle-offset", FT_UINT16, BASE_DEC,
+ 0, 0x0, NULL, HFILL
+ }
+ },
+ { &hf_mac_lte_drx_config_onduration_timer,
+ { "OnDuration Timer",
+ "mac-lte.drx-config.onduration-timer", FT_UINT16, BASE_DEC,
+ 0, 0x0, NULL, HFILL
+ }
+ },
+ { &hf_mac_lte_drx_config_inactivity_timer,
+ { "Inactivity Timer",
+ "mac-lte.drx-config.inactivity-timer", FT_UINT16, BASE_DEC,
+ 0, 0x0, NULL, HFILL
+ }
+ },
+ { &hf_mac_lte_drx_config_retransmission_timer,
+ { "Retransmission Timer",
+ "mac-lte.drx-config.retransmission-timer", FT_UINT16, BASE_DEC,
+ 0, 0x0, NULL, HFILL
+ }
+ },
+ { &hf_mac_lte_drx_config_short_cycle,
+ { "Short cycle",
+ "mac-lte.drx-config.short-cycle", FT_UINT16, BASE_DEC,
+ 0, 0x0, NULL, HFILL
+ }
+ },
+ { &hf_mac_lte_drx_config_short_cycle_timer,
+ { "Short cycle Timer",
+ "mac-lte.drx-config.short-cycle-timer", FT_UINT16, BASE_DEC,
+ 0, 0x0, NULL, HFILL
+ }
+ },
+
+ { &hf_mac_lte_drx_state,
+ { "DRX State",
+ "mac-lte.drx-state", FT_STRING, BASE_NONE,
+ 0, 0x0, NULL, HFILL
+ }
+ },
+ { &hf_mac_lte_drx_state_long_cycle_offset,
+ { "Long cycle offset",
+ "mac-lte.drx-state.long-cycle-offset", FT_UINT16, BASE_DEC,
+ 0, 0x0, NULL, HFILL
+ }
+ },
+ { &hf_mac_lte_drx_state_long_cycle_on,
+ { "Long cycle current on",
+ "mac-lte.drx-state.long-cycle-on", FT_BOOLEAN, BASE_NONE,
+ 0, 0x0, NULL, HFILL
+ }
+ },
};
static gint *ett[] =
@@ -5851,7 +6124,9 @@ void proto_register_mac_lte(void)
&ett_mac_lte_extended_power_headroom,
&ett_mac_lte_extended_power_headroom_cell,
&ett_mac_lte_mch_scheduling_info,
- &ett_mac_lte_oob
+ &ett_mac_lte_oob,
+ &ett_mac_lte_drx_config,
+ &ett_mac_lte_drx_state
};
static const enum_val_t show_info_col_vals[] = {
@@ -5981,6 +6256,12 @@ void proto_register_mac_lte(void)
"Attempt to decode 6 bytes of Contention Resolution body as an UL CCCH PDU",
&global_mac_lte_decode_cr_body);
+ prefs_register_bool_preference(mac_lte_module, "show_drx",
+ "Show DRX Information",
+ "Apply DRX config and show DRX state within each UE",
+ &global_mac_lte_show_drx);
+
+
register_init_routine(&mac_lte_init_protocol);
}
diff --git a/epan/dissectors/packet-mac-lte.h b/epan/dissectors/packet-mac-lte.h
index 410840e541..459340e424 100644
--- a/epan/dissectors/packet-mac-lte.h
+++ b/epan/dissectors/packet-mac-lte.h
@@ -294,6 +294,29 @@ typedef struct drb_mapping_t
configuration protocol (e.g. RRC) */
void set_mac_lte_channel_mapping(drb_mapping_t *drb_mapping);
+
+/* Dedicated DRX config. Used to verify that a sensible config is given.
+ Also, beginning to configure MAC with this config and (optionally) show
+ DRX config and state (cycles/timers) attached to each UL/DL PDU! */
+typedef struct drx_config_t {
+ gboolean configured;
+ guint32 frameNum;
+ guint32 onDurationTimer;
+ guint32 inactivityTimer;
+ guint32 retransmissionTimer;
+ guint32 longCycle;
+ guint32 cycleOffset;
+ /* Optional Short cycle */
+ gboolean shortCycleConfigured;
+ guint32 shortCycle;
+ guint32 shortCycleTimer;
+} drx_config_t;
+
+/* Functions to set/release up dedicated DRX config */
+void set_mac_lte_drx_config(guint16 ueid, drx_config_t *drx_config, packet_info *pinfo);
+void set_mac_lte_drx_config_release(guint16 ueid, packet_info *pinfo);
+
+
/* Functions to be called from outside this module (e.g. in a plugin, where mac_lte_info
isn't available) to get/set per-packet data */
WS_DLL_PUBLIC