aboutsummaryrefslogtreecommitdiffstats
path: root/asn1/lte-rrc
diff options
context:
space:
mode:
authorMartin Mathieson <martin.r.mathieson@googlemail.com>2013-08-19 17:06:42 +0000
committerMartin Mathieson <martin.r.mathieson@googlemail.com>2013-08-19 17:06:42 +0000
commit641032ea44eac1f6e0f1b187527aac3f9b5e8df0 (patch)
treee6191048e36b2bf68bd4173dcfddec0ec24876ed /asn1/lte-rrc
parent85667447f1c2536948cd1c8660f4bf5de767d35e (diff)
Gather together dedicated DRX configuration, and make sure that it
is internally consistent. TODO: include r11 sequence that can overwrite some of these values. TODO: actx->private_data gets reused for several purposes, need to separate these uses out and avoid possible conflicts... svn path=/trunk/; revision=51429
Diffstat (limited to 'asn1/lte-rrc')
-rw-r--r--asn1/lte-rrc/lte-rrc.cnf158
-rw-r--r--asn1/lte-rrc/packet-lte-rrc-template.c112
2 files changed, 263 insertions, 7 deletions
diff --git a/asn1/lte-rrc/lte-rrc.cnf b/asn1/lte-rrc/lte-rrc.cnf
index 6b7f700e49..c1c50e526b 100644
--- a/asn1/lte-rrc/lte-rrc.cnf
+++ b/asn1/lte-rrc/lte-rrc.cnf
@@ -750,13 +750,6 @@ CQI-ReportConfigSCell-r10/nomPDSCH-RS-EPRE-Offset-r10 STRINGS=VALS(lte_rrc_nomPD
#.FN_FTR MAC-MainConfig/eag_1/sr-ProhibitTimer-r9
proto_item_append_text(actx->created_item, " SR period%s", (timer > 1) ? "s" : "");
-#.FN_BODY DRX-Config/setup/shortDRX/drxShortCycleTimer VAL_PTR=&timer
- guint32 timer;
-%(DEFAULT_BODY)s
-
-#.FN_FTR DRX-Config/setup/shortDRX/drxShortCycleTimer
- proto_item_append_text(actx->created_item, " shortDRX-Cycle%s", plurality(timer, "", "s"));
-
#.FN_BODY PDSCH-ConfigCommon/referenceSignalPower
%(DEFAULT_BODY)s
proto_item_append_text(actx->created_item, "dBm");
@@ -1295,3 +1288,154 @@ SoundingRS-UL-ConfigDedicated/setup/duration STRINGS=TFS(&lte_rrc_duration_val)
}
actx->private_data = NULL;
+
+
+
+#.FN_BODY DRX-Config/setup
+ /* Accumulate values in drx_config while dissecting DRX config */
+ static drx_config_t drx_config;
+ memset(&drx_config, 0, sizeof(drx_config));
+ actx->private_data = &drx_config;
+%(DEFAULT_BODY)s
+ /* Verify that config is valid */
+ drx_check_config_sane(&drx_config, actx);
+
+ /* Unset again afterwards */
+ actx->private_data = NULL;
+
+#.FN_BODY DRX-Config/setup/onDurationTimer VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->onDurationTimer = drx_lookup_onDurationTimer(value);
+
+#.FN_BODY DRX-Config/setup/drx-InactivityTimer VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->inactivityTimer = drx_lookup_inactivityTimer(value);
+
+#.FN_BODY DRX-Config/setup/drx-RetransmissionTimer VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->retransmissionTimer = drx_lookup_retransmissionTimer(value);
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->longCycle = drx_lookup_longCycle(value);
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf10 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf20 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf32 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf40 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf64 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf80 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf128 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf160 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf256 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf320 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf512 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf640 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf1024 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf1280 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf2048 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/longDRX-CycleStartOffset/sf2560 VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->cycleOffset = value;
+
+#.FN_BODY DRX-Config/setup/shortDRX/shortDRX-Cycle VAL_PTR=&value
+ guint32 value;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->shortCycleConfigured = TRUE;
+ config->shortCycle = drx_lookup_shortCycle(value);
+
+#.FN_BODY DRX-Config/setup/shortDRX/drxShortCycleTimer VAL_PTR=&timer
+ guint32 timer;
+ drx_config_t* config = (drx_config_t*)actx->private_data;
+%(DEFAULT_BODY)s
+ config->shortCycleTimer = timer;
+
+#.FN_FTR DRX-Config/setup/shortDRX/drxShortCycleTimer
+ proto_item_append_text(actx->created_item, " shortDRX-Cycle%s", plurality(timer, "", "s"));
+
diff --git a/asn1/lte-rrc/packet-lte-rrc-template.c b/asn1/lte-rrc/packet-lte-rrc-template.c
index a50ce558ea..37331a86d6 100644
--- a/asn1/lte-rrc/packet-lte-rrc-template.c
+++ b/asn1/lte-rrc/packet-lte-rrc-template.c
@@ -204,6 +204,7 @@ static expert_field ei_lte_rrc_commercial_mobile_alert_sys = EI_INIT;
static expert_field ei_lte_rrc_unexpected_type_value = EI_INIT;
static expert_field ei_lte_rrc_unexpected_length_value = EI_INIT;
static expert_field ei_lte_rrc_too_many_group_a_rapids = EI_INIT;
+static expert_field ei_lte_rrc_invalid_drx_config = EI_INIT;
/* Forward declarations */
static int dissect_DL_DCCH_Message_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
@@ -1942,6 +1943,116 @@ dissect_lte_rrc_featureGroupIndRel9Add(tvbuff_t *featureGroupIndRel9Add_tvb, asn
proto_tree_add_bits_item(subtree, hf_lte_rrc_eutra_cap_feat_group_ind_64, featureGroupIndRel9Add_tvb, 31, 1, ENC_BIG_ENDIAN);
}
+
+
+/* Functions to get enum values out of indices parsed */
+/* If entry not found, return last element of array */
+static guint32 drx_lookup_onDurationTimer(guint32 idx)
+{
+ static const guint32 vals[] = {1,2,3,4,5,6,8,10,20,30,40,50,60,80,100,200};
+ if (idx < sizeof(vals)) {
+ return vals[idx];
+ }
+ else {
+ return (sizeof(vals)/(sizeof(guint32)) - 1);
+ }
+}
+
+static guint32 drx_lookup_inactivityTimer(guint32 idx)
+{
+ static const guint32 vals[] = {1,2,3,4,5,6,8,10,20,30,40,50,60,80,100,200,300,
+ 500,750,1280,1920,2560,0};
+ if (idx < sizeof(vals)) {
+ return vals[idx];
+ }
+ else {
+ return (sizeof(vals)/(sizeof(guint32)) - 1);
+ }
+}
+
+static guint32 drx_lookup_retransmissionTimer(guint32 idx)
+{
+ static const guint32 vals[] = {1,2,4,6,8,16,24,33};
+ if (idx < sizeof(vals)) {
+ return vals[idx];
+ }
+ else {
+ return (sizeof(vals)/(sizeof(guint32)) - 1);
+ }
+}
+
+static guint32 drx_lookup_longCycle(guint32 idx)
+{
+ static const guint32 vals[] = {10,20,32,40,64,80,128,160,256,320,512,640,1024,1280,2048,2560};
+ if (idx < sizeof(vals)) {
+ return vals[idx];
+ }
+ else {
+ return (sizeof(vals)/(sizeof(guint32)) - 1);
+ }
+}
+
+static guint32 drx_lookup_shortCycle(guint32 idx)
+{
+ static const guint32 vals[] = {2,5,8,10,16,20,32,40,64,80,128,160,256,320,512,640};
+ if (idx < sizeof(vals)) {
+ return vals[idx];
+ }
+ else {
+ return (sizeof(vals)/(sizeof(guint32)) - 1);
+ }
+}
+
+/* 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 {
+ guint32 onDurationTimer;
+ guint32 inactivityTimer;
+ guint32 retransmissionTimer;
+ guint32 longCycle;
+ guint32 cycleOffset;
+ /* Optional Short cycle */
+ gboolean shortCycleConfigured;
+ guint32 shortCycle;
+ guint32 shortCycleTimer;
+} drx_config_t;
+
+
+static void drx_check_config_sane(drx_config_t *config, asn1_ctx_t *actx)
+{
+ /* OnDuration must be shorter than long cycle */
+ if (config->onDurationTimer >= config->longCycle) {
+ expert_add_info_format_text(actx->pinfo, actx->created_item, &ei_lte_rrc_invalid_drx_config,
+ "OnDurationTimer (%u) should be less than long cycle (%u)",
+ config->onDurationTimer, config->longCycle);
+ }
+
+ if (config->shortCycleConfigured) {
+ /* Short cycle must be < long, and be a multiple of it */
+ if (config->shortCycle >= config->longCycle) {
+ expert_add_info_format_text(actx->pinfo, actx->created_item, &ei_lte_rrc_invalid_drx_config,
+ "Short DRX cycle (%u) must be shorter than long cycle (%u)",
+ config->shortCycle, config->longCycle);
+ }
+ /* Long cycle needs to be an exact multiple of the short cycle */
+ else if (config->shortCycle && ((config->longCycle % config->shortCycle) != 0)) {
+ expert_add_info_format_text(actx->pinfo, actx->created_item, &ei_lte_rrc_invalid_drx_config,
+ "Short DRX cycle (%u) must divide the long cycle (%u) exactly",
+ config->shortCycle, config->longCycle);
+
+ }
+ /* OnDuration shouldn't be longer than the short cycle */
+ if (config->onDurationTimer >= config->shortCycle) {
+ expert_add_info_format_text(actx->pinfo, actx->created_item, &ei_lte_rrc_invalid_drx_config,
+ "OnDurationTimer (%u) should not be longer than the short cycle (%u)",
+ config->onDurationTimer, config->shortCycle);
+ }
+ /* TODO: check that (shortCycle*shortCycleTimer) < longCycle ? */
+ }
+}
+
+
#include "packet-lte-rrc-fn.c"
static void
@@ -2540,6 +2651,7 @@ void proto_register_lte_rrc(void) {
{ &ei_lte_rrc_unexpected_type_value, { "lte_rrc.unexpected_type_value", PI_MALFORMED, PI_ERROR, "Unexpected type value", EXPFILL }},
{ &ei_lte_rrc_unexpected_length_value, { "lte_rrc.unexpected_length_value", PI_MALFORMED, PI_ERROR, "Unexpected type length", EXPFILL }},
{ &ei_lte_rrc_too_many_group_a_rapids, { "lte_rrc.too_many_groupa_rapids", PI_MALFORMED, PI_ERROR, "Too many group A RAPIDs", EXPFILL }},
+ { &ei_lte_rrc_invalid_drx_config, { "lte_rrc.invalid_drx_config", PI_MALFORMED, PI_ERROR, "Invalid dedicated DRX config detected", EXPFILL }},
};
expert_module_t* expert_lte_rrc;