aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-mac-lte.c
diff options
context:
space:
mode:
authorMartin Mathieson <martin.r.mathieson@googlemail.com>2013-10-03 15:04:39 +0000
committerMartin Mathieson <martin.r.mathieson@googlemail.com>2013-10-03 15:04:39 +0000
commita0201b0c0b12062c179208de1bafc4ed4d8e2e59 (patch)
tree5df53b200db0ab8088ee348a81a1d36c92e75933 /epan/dissectors/packet-mac-lte.c
parenta891f3e70b9efa4980feb830fba3b96e0bbaf39d (diff)
More DRX changes - getting closer (still mostly untested)
svn path=/trunk/; revision=52342
Diffstat (limited to 'epan/dissectors/packet-mac-lte.c')
-rw-r--r--epan/dissectors/packet-mac-lte.c240
1 files changed, 159 insertions, 81 deletions
diff --git a/epan/dissectors/packet-mac-lte.c b/epan/dissectors/packet-mac-lte.c
index 8dd2c5301d..a3333c4051 100644
--- a/epan/dissectors/packet-mac-lte.c
+++ b/epan/dissectors/packet-mac-lte.c
@@ -1185,7 +1185,7 @@ static GHashTable *mac_lte_sr_request_hash = NULL;
/* Config for current cycle/timer state for a configured UE */
-/* Entries in this table are maintained during the first pass
+/* Entries inp_state this table are maintained during the first pass
It maps (UEId -> drx_state_t) */
static GHashTable *mac_lte_drx_ue_state = NULL;
@@ -1236,22 +1236,89 @@ typedef enum drx_timer_type_t {
} drx_timer_type_t;
/* Start the specified timer. Use the time period in the config */
-static void mac_lte_drx_start_timer(drx_state_t *p_state _U_, drx_timer_type_t timer_type _U_, guint8 timer_id _U_)
+static void mac_lte_drx_start_timer(drx_state_t *p_state, drx_timer_type_t timer_type, guint8 timer_id)
{
- /* TODO! */
+ /* Get current time in ms */
+ /* TODO: should this be relative to firstCycleStart to avoid overflowing? */
+ guint64 currentTime = (p_state->currentTime.secs * 1000) + (p_state->currentTime.nsecs / 1000000);
+
+ guint64 *pTimer;
+ guint16 timerLength;
+
+ /* Get pointer to timer value, and fetch from config how much to add to it */
+ switch (timer_type) {
+ case drx_inactivity_timer:
+ pTimer = &(p_state->inactivityTimer);
+ timerLength = p_state->config.inactivityTimer;
+ break;
+ case drx_rtt_timer:
+ pTimer = &(p_state->RTT[timer_id]);
+ timerLength = 8;
+ break;
+ case drx_retx_timer:
+ pTimer = &(p_state->retransmissionTimer[timer_id]);
+ timerLength = p_state->config.retransmissionTimer;
+ break;
+ case drx_short_cycle_timer:
+ pTimer = &(p_state->shortCycleTimer);
+ timerLength = p_state->config.shortCycle * p_state->config.shortCycleTimer;
+ break;
+ }
+
+ /* Set timer */
+ *pTimer = currentTime + timerLength;
}
/* Stop the specified timer. */
static void mac_lte_drx_stop_timer(drx_state_t *p_state _U_, drx_timer_type_t timer_type _U_, guint8 timer_id _U_)
{
- /* TODO! */
+ /* Set indicated timer value to 0 */
+ switch (timer_type) {
+ case drx_inactivity_timer:
+ p_state->inactivityTimer = G_GUINT64_CONSTANT(0);
+ break;
+ case drx_rtt_timer:
+ p_state->RTT[timer_id] = G_GUINT64_CONSTANT(0);
+ break;
+ case drx_retx_timer:
+ p_state->retransmissionTimer[timer_id] = G_GUINT64_CONSTANT(0);
+ break;
+ case drx_short_cycle_timer:
+ p_state->shortCycleTimer = G_GUINT64_CONSTANT(0);
+ break;
+ }
}
/* Has the specified timer expired? */
-static gboolean mac_lte_drx_has_timer_expired(drx_state_t *p_state _U_, drx_timer_type_t timer_type _U_, guint8 timer_id _U_)
+static gboolean mac_lte_drx_has_timer_expired(drx_state_t *p_state, drx_timer_type_t timer_type, guint8 timer_id)
{
- /* TODO! */
- return FALSE;
+ /* Get current time in ms */
+ /* TODO: should this be relative to firstCycleStart to avoid overflowing? */
+ guint64 currentTime = (p_state->currentTime.secs * 1000) + (p_state->currentTime.nsecs / 1000000);
+
+ guint64 *pTimer = NULL;
+
+ /* Get pointer to timer value */
+ switch (timer_type) {
+ case drx_inactivity_timer:
+ pTimer = &(p_state->inactivityTimer);
+ break;
+ case drx_rtt_timer:
+ pTimer = &(p_state->RTT[timer_id]);
+ break;
+ case drx_retx_timer:
+ pTimer = &(p_state->retransmissionTimer[timer_id]);
+ break;
+ case drx_short_cycle_timer:
+ pTimer = &(p_state->shortCycleTimer);
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ /* TODO: verify using SFN/SF ? */
+ return (currentTime >= *pTimer);
}
@@ -1310,79 +1377,85 @@ static void mac_lte_drx_control_element_received(guint16 ueid)
/* Update the DRX state of the UE based on previous info and current time.
This is called every time a UE with DRX configured has an UL or DL PDU */
-static void update_drx_info(drx_state_t *ue_state, packet_info *pinfo,
- guint16 SFN, guint16 SF)
+static void update_drx_info(packet_info *pinfo, mac_lte_info *p_mac_lte_info)
{
int harq_id;
+ /* Look up state of this UE */
+ drx_state_t *ue_state = (drx_state_t *)g_hash_table_lookup(mac_lte_drx_ue_state,
+ GUINT_TO_POINTER((guint)p_mac_lte_info->ueid));
+ if (ue_state != NULL) {
+ guint16 SFN = p_mac_lte_info->sysframeNumber;
+ guint16 SF = p_mac_lte_info->subframeNumber;
- /* Make sure time reference has been set */
- if (!ue_state->firstCycleStartSet) {
- guint16 subframes = SFN*10 + SF;
-
- /* Set firstCycleStart to be the previous SFN=0, SF=0 */
- if (pinfo->fd->abs_ts.nsecs > ((subframes % 1000)*1000)) {
- ue_state->firstCycleStart.secs = pinfo->fd->abs_ts.secs - (subframes/1000);
- ue_state->firstCycleStart.nsecs = pinfo->fd->abs_ts.nsecs - (subframes*1000);
- }
- else {
- ue_state->firstCycleStart.secs = pinfo->fd->abs_ts.secs - (subframes/1000) - 1;
- ue_state->firstCycleStart.nsecs = 1000000 + pinfo->fd->abs_ts.nsecs - (subframes*1000);
+ /* Make sure the first time reference has been set */
+ if (!ue_state->firstCycleStartSet) {
+ guint16 subframes = SFN*10 + SF;
+
+ /* Set firstCycleStart to be the previous SFN=0, SF=0 */
+ if (pinfo->fd->abs_ts.nsecs > ((subframes % 1000)*1000)) {
+ ue_state->firstCycleStart.secs = pinfo->fd->abs_ts.secs - (subframes/1000);
+ ue_state->firstCycleStart.nsecs = pinfo->fd->abs_ts.nsecs - (subframes*1000);
+ }
+ else {
+ ue_state->firstCycleStart.secs = pinfo->fd->abs_ts.secs - (subframes/1000) - 1;
+ ue_state->firstCycleStart.nsecs = 1000000 + pinfo->fd->abs_ts.nsecs - (subframes*1000);
+ }
+ ue_state->firstCycleStartSet = TRUE;
+
+ /* Set current time to now */
+ ue_state->currentTime = pinfo->fd->abs_ts;
+ ue_state->currentSFN = SFN;
+ ue_state->currentSF = SF;
}
- ue_state->firstCycleStartSet = TRUE;
- /* Set current time to now */
- ue_state->currentTime = pinfo->fd->abs_ts;
- ue_state->currentSFN = SFN;
- ue_state->currentSF = SF;
- }
-
- /* Will loop around these checks, once for each subframe between previous
- currentTime for this UE, and the time now!!! */
- /* It *should* be possible to just deal with the elapsed time all at once,
- but much harder to get right, so loop. */
-
- /* TODO: what to do if there is a huge gap between previous frame and now?? */
-
- /* TODO: add a test that ensures we are still in the correct SFN cycle! */
- while ((ue_state->currentSFN != SFN) || (ue_state->currentSF != SF)) {
+ /* Will loop around these checks, once for each subframe between previous
+ currentTime for this UE, and the time now!!! */
+ /* It *should* be possible to just deal with the elapsed time all at once,
+ but much harder to get right, so loop. */
- /* TODO check for timers that have expired and change state accordingly */
+ /* TODO: what to do if there is a huge gap between previous frame and now?? */
- /* Check for HARQ RTT Timer expiring.
- In practice only one could expire in any given subframe... */
- for (harq_id = 0 ; harq_id < 8; harq_id++) {
- if (mac_lte_drx_has_timer_expired(ue_state, drx_rtt_timer, harq_id)) {
+ /* TODO: add a test that ensures we are still in the correct SFN cycle! */
+ while ((ue_state->currentSFN != SFN) || (ue_state->currentSF != SF)) {
+
+ /* TODO check for timers that have expired and change state accordingly */
+
+ /* Check for HARQ RTT Timer expiring.
+ In practice only one could expire in any given subframe... */
+ for (harq_id = 0 ; harq_id < 8; harq_id++) {
+ if (mac_lte_drx_has_timer_expired(ue_state, drx_rtt_timer, harq_id)) {
mac_lte_drx_start_timer(ue_state, drx_retx_timer, harq_id);
+ }
}
- }
-
- /* Reception of DRX command is dealt with separately at the moment... */
-
- /* Inactivity timer expired */
- if (mac_lte_drx_has_timer_expired(ue_state, drx_inactivity_timer, 0)) {
- if (ue_state->config.shortCycleConfigured) {
+
+ /* Reception of DRX command is dealt with separately at the moment... */
+
+ /* Inactivity timer expired */
+ if (mac_lte_drx_has_timer_expired(ue_state, drx_inactivity_timer, 0)) {
+ if (ue_state->config.shortCycleConfigured) {
ue_state->inShortCycle = TRUE;
mac_lte_drx_start_timer(ue_state, drx_short_cycle_timer, 0);
+ }
}
- }
-
- /* Move subframe along by one */
- if (ue_state->currentSFN == 1023) {
- ue_state->currentSFN = 0;
- }
- else {
- ue_state->currentSFN++;
- }
- if (ue_state->currentSF == 9) {
- ue_state->currentSF = 0;
- }
- else {
- ue_state->currentSF++;
- }
+
+ /* Move subframe along by one */
+ if (ue_state->currentSFN == 1023) {
+ ue_state->currentSFN = 0;
+ }
+ else {
+ ue_state->currentSFN++;
+ }
+ if (ue_state->currentSF == 9) {
+ ue_state->currentSF = 0;
+ }
+ else {
+ ue_state->currentSF++;
+ }
+ }
+
+ /* Set current time to now */
+ ue_state->currentTime = pinfo->fd->abs_ts;
}
-
- /* Set current time to now */
- ue_state->currentTime = pinfo->fd->abs_ts;
}
/* Set DRX information to display for the current MAC frame.
@@ -1393,12 +1466,9 @@ static void set_drx_info(packet_info *pinfo, mac_lte_info *p_mac_lte_info)
drx_state_t *ue_state = (drx_state_t *)g_hash_table_lookup(mac_lte_drx_ue_state,
GUINT_TO_POINTER((guint)p_mac_lte_info->ueid));
if (ue_state != NULL) {
- /* Copy config into separate struct just for this frame, and add to result table */
+ /* Copy UE snapshot for this frame, and add to result table */
drx_state_t *frame_result = wmem_new(wmem_file_scope(), drx_state_t);
- /* Update start of UE to now */
- update_drx_info(ue_state, pinfo, p_mac_lte_info->sysframeNumber, p_mac_lte_info->subframeNumber);
-
/* Deep-copy this snapshot for this frame */
*frame_result = *ue_state;
@@ -1426,7 +1496,7 @@ static void show_drx_info(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
proto_item *drx_config_ti, *drx_state_ti, *ti;
/************************************/
- /* Create config subtree */
+ /* 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);
@@ -1505,6 +1575,9 @@ static void show_drx_info(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
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");
+
+ /* TODO: Show which timers are still running and how long they have to go.
+ Or complain if DRX looks like it should be on. */
}
}
@@ -3092,23 +3165,28 @@ static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree
/* Update DRX state of UE */
if (p_mac_lte_info->reTxCount == 0 && !pinfo->fd->flags.visited) {
- if (p_mac_lte_info == DIRECTION_UPLINK) {
- mac_lte_drx_new_ulsch_data(p_mac_lte_info->ueid);
+
+ /* Update UE state to this subframe */
+ update_drx_info(pinfo, p_mac_lte_info);
+
+ /* Changes of state caused by events */
+ if (p_mac_lte_info == DIRECTION_UPLINK) {
+ mac_lte_drx_new_ulsch_data(p_mac_lte_info->ueid);
+ }
+ else {
+ if (p_mac_lte_info->crcStatusValid != crc_success) {
+ mac_lte_drx_dl_crc_error(p_mac_lte_info->ueid);
}
else {
- if (p_mac_lte_info->crcStatusValid != crc_success) {
- mac_lte_drx_dl_crc_error(p_mac_lte_info->ueid);
- }
- else {
- mac_lte_drx_new_dlsch_data(p_mac_lte_info->ueid);
- }
+ mac_lte_drx_new_dlsch_data(p_mac_lte_info->ueid);
}
+ }
}
/* Show current DRX state in tree */
if (global_mac_lte_show_drx) {
if (!pinfo->fd->flags.visited) {
- /* Update UE state and store copy for this frame */
+ /* Store snapshot of UE state for this frame */
set_drx_info(pinfo, p_mac_lte_info);
}
/* Show stored DRX info every time */