diff options
author | Martin Mathieson <martin.r.mathieson@googlemail.com> | 2013-08-30 04:08:57 +0000 |
---|---|---|
committer | Martin Mathieson <martin.r.mathieson@googlemail.com> | 2013-08-30 04:08:57 +0000 |
commit | a09ee6af031b399848a0322054519489f6d963f6 (patch) | |
tree | b8700ebd6c5024a4504ff6c1aa30a6249b9af0c7 | |
parent | d9eb37b849a70a8bc8ad0c61b3fa8f2c3d689f7c (diff) | |
download | wireshark-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.cnf | 23 | ||||
-rw-r--r-- | asn1/lte-rrc/packet-lte-rrc-template.c | 16 | ||||
-rw-r--r-- | epan/dissectors/packet-mac-lte.c | 287 | ||||
-rw-r--r-- | epan/dissectors/packet-mac-lte.h | 23 |
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(<e_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 |