aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--asn1/lte-rrc/lte-rrc.cnf27
-rw-r--r--asn1/lte-rrc/packet-lte-rrc-template.c1
-rw-r--r--epan/dissectors/packet-lte-rrc.c42
-rw-r--r--epan/dissectors/packet-mac-lte.c102
-rw-r--r--epan/dissectors/packet-mac-lte.h18
-rw-r--r--epan/dissectors/packet-rlc-lte.c182
-rw-r--r--epan/dissectors/packet-rlc-lte.h9
7 files changed, 284 insertions, 97 deletions
diff --git a/asn1/lte-rrc/lte-rrc.cnf b/asn1/lte-rrc/lte-rrc.cnf
index aa9f011ad3..af7e55e670 100644
--- a/asn1/lte-rrc/lte-rrc.cnf
+++ b/asn1/lte-rrc/lte-rrc.cnf
@@ -794,7 +794,7 @@ CQI-ReportConfigSCell-r10/nomPDSCH-RS-EPRE-Offset-r10 STRINGS=VALS(lte_rrc_nomPD
p_mac_lte_info = (mac_lte_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_mac_lte, 0);
if (p_mac_lte_info != NULL) {
/* Tell MAC to use extended BSR sizes configuration */
- set_mac_lte_extended_bsr_sizes(p_mac_lte_info->ueid, TRUE);
+ set_mac_lte_extended_bsr_sizes(p_mac_lte_info->ueid, TRUE, actx->pinfo);
}
#.FN_BODY PDSCH-ConfigCommon/referenceSignalPower
@@ -1236,28 +1236,29 @@ SoundingRS-UL-ConfigDedicated/setup/duration STRINGS=TFS(&lte_rrc_duration_val)
expert_add_info(actx->pinfo, actx->created_item, &ei_lte_rrc_commercial_mobile_alert_sys);
#.FN_BODY DRB-ToAddMod
- struct mac_lte_info *p_mac_lte_info;
+ struct mac_lte_info *p_mac_lte_info;
+ struct rlc_lte_info *p_rlc_lte_info;
/* Get the struct and clear it out */
drb_mapping_t *drb_mapping = private_data_get_drb_mapping(actx);
memset(drb_mapping, 0, sizeof(*drb_mapping));
%(DEFAULT_BODY)s
/* Need UE identifier */
p_mac_lte_info = (mac_lte_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_mac_lte, 0);
- if (p_mac_lte_info == NULL) {
- return offset;
- }
- else {
+ if (p_mac_lte_info) {
drb_mapping->ueid = p_mac_lte_info->ueid;
+ /* Tell MAC about this mapping */
+ set_mac_lte_channel_mapping(drb_mapping);
}
- /* Tell MAC about this mapping */
- set_mac_lte_channel_mapping(drb_mapping);
-
/* Also tell RLC how many PDCP sequence number bits */
if (drb_mapping->pdcp_sn_size_present) {
- set_rlc_lte_drb_pdcp_seqnum_length(drb_mapping->ueid,
- drb_mapping->drbid,
- drb_mapping->pdcp_sn_size);
+ p_rlc_lte_info = (rlc_lte_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_rlc_lte, 0);
+ if (p_rlc_lte_info) {
+ set_rlc_lte_drb_pdcp_seqnum_length(actx->pinfo,
+ p_rlc_lte_info->ueid,
+ drb_mapping->drbid,
+ drb_mapping->pdcp_sn_size);
+ }
}
/* Clear out the struct again */
@@ -1549,7 +1550,7 @@ SoundingRS-UL-ConfigDedicated/setup/duration STRINGS=TFS(&lte_rrc_duration_val)
/* as the UE could have locally dropped the previous RRC Connection */
set_mac_lte_drx_config_release(p_mac_lte_info->ueid, actx->pinfo);
/* Also tell MAC to release extended BSR sizes configuration */
- set_mac_lte_extended_bsr_sizes(p_mac_lte_info->ueid, FALSE);
+ set_mac_lte_extended_bsr_sizes(p_mac_lte_info->ueid, FALSE, actx->pinfo);
/* TODO: also release PDCP security config here */
}
%(DEFAULT_BODY)s
diff --git a/asn1/lte-rrc/packet-lte-rrc-template.c b/asn1/lte-rrc/packet-lte-rrc-template.c
index b8971e2cf2..10e8acd03d 100644
--- a/asn1/lte-rrc/packet-lte-rrc-template.c
+++ b/asn1/lte-rrc/packet-lte-rrc-template.c
@@ -70,6 +70,7 @@ static gboolean system_info_value_current_set;
extern int proto_mac_lte;
+extern int proto_rlc_lte;
extern int proto_pdcp_lte;
diff --git a/epan/dissectors/packet-lte-rrc.c b/epan/dissectors/packet-lte-rrc.c
index de738b63da..d9d9066b9f 100644
--- a/epan/dissectors/packet-lte-rrc.c
+++ b/epan/dissectors/packet-lte-rrc.c
@@ -78,6 +78,7 @@ static gboolean system_info_value_current_set;
extern int proto_mac_lte;
+extern int proto_rlc_lte;
extern int proto_pdcp_lte;
@@ -180,7 +181,7 @@ typedef enum _RAT_Type_enum {
} RAT_Type_enum;
/*--- End of included file: packet-lte-rrc-val.h ---*/
-#line 78 "../../asn1/lte-rrc/packet-lte-rrc-template.c"
+#line 79 "../../asn1/lte-rrc/packet-lte-rrc-template.c"
/* Initialize the protocol and registered fields */
static int proto_lte_rrc = -1;
@@ -2355,7 +2356,7 @@ static int hf_lte_rrc_CandidateCellInfoList_r10_item = -1; /* CandidateCellInfo
static int hf_lte_rrc_dummy_eag_field = -1; /* never registered */
/*--- End of included file: packet-lte-rrc-hf.c ---*/
-#line 83 "../../asn1/lte-rrc/packet-lte-rrc-template.c"
+#line 84 "../../asn1/lte-rrc/packet-lte-rrc-template.c"
static int hf_lte_rrc_eutra_cap_feat_group_ind_1 = -1;
static int hf_lte_rrc_eutra_cap_feat_group_ind_2 = -1;
@@ -3578,7 +3579,7 @@ static gint ett_lte_rrc_CandidateCellInfoList_r10 = -1;
static gint ett_lte_rrc_CandidateCellInfo_r10 = -1;
/*--- End of included file: packet-lte-rrc-ett.c ---*/
-#line 201 "../../asn1/lte-rrc/packet-lte-rrc-template.c"
+#line 202 "../../asn1/lte-rrc/packet-lte-rrc-template.c"
static gint ett_lte_rrc_featureGroupIndicators = -1;
static gint ett_lte_rrc_featureGroupIndRel9Add = -1;
@@ -12990,7 +12991,8 @@ static const per_sequence_t DRB_ToAddMod_sequence[] = {
static int
dissect_lte_rrc_DRB_ToAddMod(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
- struct mac_lte_info *p_mac_lte_info;
+ struct mac_lte_info *p_mac_lte_info;
+ struct rlc_lte_info *p_rlc_lte_info;
/* Get the struct and clear it out */
drb_mapping_t *drb_mapping = private_data_get_drb_mapping(actx);
memset(drb_mapping, 0, sizeof(*drb_mapping));
@@ -12999,21 +13001,21 @@ dissect_lte_rrc_DRB_ToAddMod(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx
/* Need UE identifier */
p_mac_lte_info = (mac_lte_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_mac_lte, 0);
- if (p_mac_lte_info == NULL) {
- return offset;
- }
- else {
+ if (p_mac_lte_info) {
drb_mapping->ueid = p_mac_lte_info->ueid;
+ /* Tell MAC about this mapping */
+ set_mac_lte_channel_mapping(drb_mapping);
}
- /* Tell MAC about this mapping */
- set_mac_lte_channel_mapping(drb_mapping);
-
/* Also tell RLC how many PDCP sequence number bits */
if (drb_mapping->pdcp_sn_size_present) {
- set_rlc_lte_drb_pdcp_seqnum_length(drb_mapping->ueid,
- drb_mapping->drbid,
- drb_mapping->pdcp_sn_size);
+ p_rlc_lte_info = (rlc_lte_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_rlc_lte, 0);
+ if (p_rlc_lte_info) {
+ set_rlc_lte_drb_pdcp_seqnum_length(actx->pinfo,
+ p_rlc_lte_info->ueid,
+ drb_mapping->drbid,
+ drb_mapping->pdcp_sn_size);
+ }
}
/* Clear out the struct again */
@@ -13857,7 +13859,7 @@ dissect_lte_rrc_T_extendedBSR_Sizes_r10(tvbuff_t *tvb _U_, int offset _U_, asn1_
p_mac_lte_info = (mac_lte_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_mac_lte, 0);
if (p_mac_lte_info != NULL) {
/* Tell MAC to use extended BSR sizes configuration */
- set_mac_lte_extended_bsr_sizes(p_mac_lte_info->ueid, TRUE);
+ set_mac_lte_extended_bsr_sizes(p_mac_lte_info->ueid, TRUE, actx->pinfo);
}
@@ -18963,7 +18965,7 @@ dissect_lte_rrc_RRCConnectionSetup(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t
/* as the UE could have locally dropped the previous RRC Connection */
set_mac_lte_drx_config_release(p_mac_lte_info->ueid, actx->pinfo);
/* Also tell MAC to release extended BSR sizes configuration */
- set_mac_lte_extended_bsr_sizes(p_mac_lte_info->ueid, FALSE);
+ set_mac_lte_extended_bsr_sizes(p_mac_lte_info->ueid, FALSE, actx->pinfo);
/* TODO: also release PDCP security config here */
}
offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
@@ -35409,7 +35411,7 @@ static int dissect_UEAssistanceInformation_r11_PDU(tvbuff_t *tvb _U_, packet_inf
/*--- End of included file: packet-lte-rrc-fn.c ---*/
-#line 2283 "../../asn1/lte-rrc/packet-lte-rrc-template.c"
+#line 2284 "../../asn1/lte-rrc/packet-lte-rrc-template.c"
static void
dissect_lte_rrc_DL_CCCH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
@@ -44240,7 +44242,7 @@ void proto_register_lte_rrc(void) {
NULL, HFILL }},
/*--- End of included file: packet-lte-rrc-hfarr.c ---*/
-#line 2453 "../../asn1/lte-rrc/packet-lte-rrc-template.c"
+#line 2454 "../../asn1/lte-rrc/packet-lte-rrc-template.c"
{ &hf_lte_rrc_eutra_cap_feat_group_ind_1,
{ "Indicator 1", "lte-rrc.eutra_cap_feat_group_ind_1",
@@ -45800,7 +45802,7 @@ void proto_register_lte_rrc(void) {
&ett_lte_rrc_CandidateCellInfo_r10,
/*--- End of included file: packet-lte-rrc-ettarr.c ---*/
-#line 2908 "../../asn1/lte-rrc/packet-lte-rrc-template.c"
+#line 2909 "../../asn1/lte-rrc/packet-lte-rrc-template.c"
&ett_lte_rrc_featureGroupIndicators,
&ett_lte_rrc_featureGroupIndRel9Add,
@@ -45870,7 +45872,7 @@ void proto_register_lte_rrc(void) {
/*--- End of included file: packet-lte-rrc-dis-reg.c ---*/
-#line 2962 "../../asn1/lte-rrc/packet-lte-rrc-template.c"
+#line 2963 "../../asn1/lte-rrc/packet-lte-rrc-template.c"
register_init_routine(&lte_rrc_init_protocol);
}
diff --git a/epan/dissectors/packet-mac-lte.c b/epan/dissectors/packet-mac-lte.c
index 5e0584c6d0..9b8af4b470 100644
--- a/epan/dissectors/packet-mac-lte.c
+++ b/epan/dissectors/packet-mac-lte.c
@@ -37,7 +37,7 @@ void proto_reg_handoff_mac_lte(void);
/* Described in:
* 3GPP TS 36.321 Evolved Universal Terrestrial Radio Access (E-UTRA)
- * Medium Access Control (MAC) protocol specification v11.0.0
+ * Medium Access Control (MAC) protocol specification v12.3.0
*/
@@ -424,6 +424,7 @@ static const true_false_string mac_lte_scell_status_vals = {
"Deactivated"
};
+#define LONG_DRX_COMMAND_LCID 0x1a
#define ACTIVATION_DEACTIVATION_LCID 0x1b
#define UE_CONTENTION_RESOLUTION_IDENTITY_LCID 0x1c
#define TIMING_ADVANCE_LCID 0x1d
@@ -443,6 +444,7 @@ static const value_string dlsch_lcid_vals[] =
{ 8, "8"},
{ 9, "9"},
{ 10, "10"},
+ { LONG_DRX_COMMAND_LCID , "Long DRX Command"},
{ ACTIVATION_DEACTIVATION_LCID , "Activation/Deactivation"},
{ UE_CONTENTION_RESOLUTION_IDENTITY_LCID, "UE Contention Resolution Identity"},
{ TIMING_ADVANCE_LCID , "Timing Advance"},
@@ -1079,14 +1081,20 @@ typedef enum rlc_channel_type_t {
rlcTM,
rlcUM5,
rlcUM10,
- rlcAM
+ rlcAM,
+ rlcAMulExtLiField,
+ rlcAMdlExtLiField,
+ rlcAMextLiField
} rlc_channel_type_t;
static const value_string rlc_channel_type_vals[] = {
- { rlcTM, "TM"},
- { rlcUM5 , "UM, SN Len=5"},
- { rlcUM10, "UM, SN Len=10"},
- { rlcAM , "AM"},
+ { rlcTM , "TM"},
+ { rlcUM5 , "UM, SN Len=5"},
+ { rlcUM10 , "UM, SN Len=10"},
+ { rlcAM , "AM"},
+ { rlcAMulExtLiField, "AM, UL Extended LI Field"},
+ { rlcAMdlExtLiField, "AM, DL Extended LI Field"},
+ { rlcAMextLiField , "AM, UL/DL Extended LI Field"},
{ 0, NULL }
};
@@ -2859,7 +2867,7 @@ static void call_rlc_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
guint8 mode, guint8 direction, guint16 ueid,
guint16 channelType, guint16 channelId,
guint8 UMSequenceNumberLength,
- guint8 priority)
+ guint8 priority, gboolean rlcExtLiField)
{
tvbuff_t *rb_tvb = tvb_new_subset_length(tvb, offset, data_length);
struct rlc_lte_info *p_rlc_lte_info;
@@ -2879,6 +2887,7 @@ static void call_rlc_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
p_rlc_lte_info->channelId = channelId;
p_rlc_lte_info->pduLength = data_length;
p_rlc_lte_info->UMSequenceNumberLength = UMSequenceNumberLength;
+ p_rlc_lte_info->extendedLiField = rlcExtLiField;
/* Store info in packet */
p_add_proto_data(wmem_file_scope(), pinfo, proto_rlc_lte, 0, p_rlc_lte_info);
@@ -3526,14 +3535,17 @@ static void show_ues_tti(packet_info *pinfo, mac_lte_info *p_mac_lte_info, tvbuf
/* Lookup channel details for lcid */
static void lookup_rlc_channel_from_lcid(guint16 ueid,
guint8 lcid,
+ guint8 direction,
rlc_channel_type_t *rlc_channel_type,
guint8 *UM_seqnum_length,
- gint *drb_id)
+ gint *drb_id,
+ gboolean *rlc_ext_li_field)
{
/* Zero params (in case no match is found) */
*rlc_channel_type = rlcRaw;
*UM_seqnum_length = 0;
*drb_id = 0;
+ *rlc_ext_li_field = FALSE;
if (global_mac_lte_lcid_drb_source == (int)FromStaticTable) {
@@ -3552,6 +3564,19 @@ static void lookup_rlc_channel_from_lcid(guint16 ueid,
case rlcUM10:
*UM_seqnum_length = 10;
break;
+ case rlcAMulExtLiField:
+ if (direction == DIRECTION_UPLINK) {
+ *rlc_ext_li_field = TRUE;
+ }
+ break;
+ case rlcAMdlExtLiField:
+ if (direction == DIRECTION_DOWNLINK) {
+ *rlc_ext_li_field = TRUE;
+ }
+ break;
+ case rlcAMextLiField:
+ *rlc_ext_li_field = TRUE;
+ break;
default:
break;
}
@@ -3584,6 +3609,19 @@ static void lookup_rlc_channel_from_lcid(guint16 ueid,
case rlcUM10:
*UM_seqnum_length = 10;
break;
+ case rlcAMulExtLiField:
+ if (direction == DIRECTION_UPLINK) {
+ *rlc_ext_li_field = TRUE;
+ }
+ break;
+ case rlcAMdlExtLiField:
+ if (direction == DIRECTION_DOWNLINK) {
+ *rlc_ext_li_field = TRUE;
+ }
+ break;
+ case rlcAMextLiField:
+ *rlc_ext_li_field = TRUE;
+ break;
default:
break;
}
@@ -4684,7 +4722,8 @@ static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree
RLC_AM_MODE, direction, p_mac_lte_info->ueid,
CHANNEL_TYPE_SRB, lcids[n], 0,
get_mac_lte_channel_priority(p_mac_lte_info->ueid,
- lcids[n], direction));
+ lcids[n], direction),
+ FALSE);
/* Hide raw view of bytes */
PROTO_ITEM_SET_HIDDEN(sdu_ti);
@@ -4698,40 +4737,41 @@ static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree
rlc_channel_type_t rlc_channel_type;
guint8 UM_seqnum_length;
gint drb_id;
+ gboolean rlc_ext_li_field;
guint8 priority = get_mac_lte_channel_priority(p_mac_lte_info->ueid,
lcids[n], direction);
lookup_rlc_channel_from_lcid(p_mac_lte_info->ueid,
lcids[n],
+ p_mac_lte_info->direction,
&rlc_channel_type,
&UM_seqnum_length,
- &drb_id);
+ &drb_id,
+ &rlc_ext_li_field);
/* Dissect according to channel type */
switch (rlc_channel_type) {
case rlcUM5:
- call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
- RLC_UM_MODE, direction, p_mac_lte_info->ueid,
- CHANNEL_TYPE_DRB, (guint16)drb_id, UM_seqnum_length,
- priority);
- break;
case rlcUM10:
call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
RLC_UM_MODE, direction, p_mac_lte_info->ueid,
CHANNEL_TYPE_DRB, (guint16)drb_id, UM_seqnum_length,
- priority);
+ priority, FALSE);
break;
case rlcAM:
+ case rlcAMulExtLiField:
+ case rlcAMdlExtLiField:
+ case rlcAMextLiField:
call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
RLC_AM_MODE, direction, p_mac_lte_info->ueid,
CHANNEL_TYPE_DRB, (guint16)drb_id, 0,
- priority);
+ priority, rlc_ext_li_field);
break;
case rlcTM:
call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
RLC_TM_MODE, direction, p_mac_lte_info->ueid,
CHANNEL_TYPE_DRB, (guint16)drb_id, 0,
- priority);
+ priority, FALSE);
break;
case rlcRaw:
/* Nothing to do! */
@@ -5163,12 +5203,12 @@ static void dissect_mch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, pro
/* Call RLC dissector */
call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
RLC_UM_MODE, DIRECTION_DOWNLINK, 0,
- CHANNEL_TYPE_MCCH, 0, 5, 0);
+ CHANNEL_TYPE_MCCH, 0, 5, 0, FALSE);
} else if ((lcids[n] <= 28) && global_mac_lte_call_rlc_for_mtch) {
/* Call RLC dissector */
call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length,
RLC_UM_MODE, DIRECTION_DOWNLINK, 0,
- CHANNEL_TYPE_MTCH, 0, 5, 0);
+ CHANNEL_TYPE_MTCH, 0, 5, 0, FALSE);
} else {
/* Dissect SDU as raw bytes */
sdu_ti = proto_tree_add_bytes_format(tree, hf_mac_lte_mch_sdu, tvb, offset, pdu_lengths[n],
@@ -5858,7 +5898,19 @@ void set_mac_lte_channel_mapping(drb_mapping_t *drb_mapping)
if (drb_mapping->rlcMode_present) {
switch (drb_mapping->rlcMode) {
case RLC_AM_MODE:
- ue_mappings->mapping[lcid].channel_type = rlcAM;
+ if (drb_mapping->rlc_ul_ext_li_field == TRUE) {
+ if (drb_mapping->rlc_dl_ext_li_field == TRUE) {
+ ue_mappings->mapping[lcid].channel_type = rlcAMextLiField;
+ } else {
+ ue_mappings->mapping[lcid].channel_type = rlcAMulExtLiField;
+ }
+ } else {
+ if (drb_mapping->rlc_dl_ext_li_field == TRUE) {
+ ue_mappings->mapping[lcid].channel_type = rlcAMdlExtLiField;
+ } else {
+ ue_mappings->mapping[lcid].channel_type = rlcAM;
+ }
+ }
break;
case RLC_UM_MODE:
if (drb_mapping->um_sn_length_present) {
@@ -5956,10 +6008,12 @@ void set_mac_lte_rapid_ranges(guint group_A, guint all_RA)
}
/* Configure the BSR sizes for this UE (from RRC) */
-void set_mac_lte_extended_bsr_sizes(guint16 ueid, gboolean use_ext_bsr_sizes)
+void set_mac_lte_extended_bsr_sizes(guint16 ueid, gboolean use_ext_bsr_sizes, packet_info *pinfo)
{
- g_hash_table_insert(mac_lte_ue_ext_bsr_sizes_hash, GUINT_TO_POINTER((guint)ueid),
- GUINT_TO_POINTER((guint)use_ext_bsr_sizes));
+ if (!PINFO_FD_VISITED(pinfo)) {
+ g_hash_table_insert(mac_lte_ue_ext_bsr_sizes_hash, GUINT_TO_POINTER((guint)ueid),
+ GUINT_TO_POINTER((guint)use_ext_bsr_sizes));
+ }
}
/* Function to be called from outside this module (e.g. in a plugin) to get per-packet data */
diff --git a/epan/dissectors/packet-mac-lte.h b/epan/dissectors/packet-mac-lte.h
index 21eb098bbe..653422b8b8 100644
--- a/epan/dissectors/packet-mac-lte.h
+++ b/epan/dissectors/packet-mac-lte.h
@@ -287,18 +287,20 @@ int is_mac_lte_frame_retx(packet_info *pinfo, guint8 direction);
/* Some are optional, and may not be seen (e.g. on reestablishment) */
typedef struct drb_mapping_t
{
- guint16 ueid; /* Mandatory */
- guint8 drbid; /* Mandatory */
+ guint16 ueid; /* Mandatory */
+ guint8 drbid; /* Mandatory */
gboolean lcid_present;
- guint8 lcid; /* Part of LogicalChannelConfig - optional */
+ guint8 lcid; /* Part of LogicalChannelConfig - optional */
gboolean rlcMode_present;
- guint8 rlcMode; /* Part of RLC config - optional */
+ guint8 rlcMode; /* Part of RLC config - optional */
+ gboolean rlc_ul_ext_li_field; /* Part of RLC config - optional */
+ gboolean rlc_dl_ext_li_field; /* Part of RLC config - optional */
gboolean um_sn_length_present;
- guint8 um_sn_length; /* Part of RLC config - optional */
+ guint8 um_sn_length; /* Part of RLC config - optional */
gboolean ul_priority_present;
- guint8 ul_priority; /* Part of LogicalChannelConfig - optional */
+ guint8 ul_priority; /* Part of LogicalChannelConfig - optional */
gboolean pdcp_sn_size_present;
- guint8 pdcp_sn_size; /* Part of pdcp-Config - optional */
+ guint8 pdcp_sn_size; /* Part of pdcp-Config - optional */
} drb_mapping_t;
@@ -334,7 +336,7 @@ void set_mac_lte_drx_config_release(guint16 ueid, packet_info *pinfo);
void set_mac_lte_rapid_ranges(guint groupA, guint all_RA);
/* RRC can indicate whether extended BSR sizes are used */
-void set_mac_lte_extended_bsr_sizes(guint16 ueid, gboolean use_ext_bsr_sizes);
+void set_mac_lte_extended_bsr_sizes(guint16 ueid, gboolean use_ext_bsr_sizes, 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 */
diff --git a/epan/dissectors/packet-rlc-lte.c b/epan/dissectors/packet-rlc-lte.c
index 6c3b2c7404..4b7d2bea52 100644
--- a/epan/dissectors/packet-rlc-lte.c
+++ b/epan/dissectors/packet-rlc-lte.c
@@ -40,7 +40,7 @@
/* Described in:
* 3GPP TS 36.322 Evolved Universal Terrestial Radio Access (E-UTRA)
- * Radio Link Control (RLC) Protocol specification v9.3.0
+ * Radio Link Control (RLC) Protocol specification v12.1.0
*/
/* TODO:
@@ -77,7 +77,6 @@ static const enum_val_t pdcp_drb_col_vals[] = {
{NULL, NULL, -1}
};
static gint global_rlc_lte_call_pdcp_for_drb = (gint)PDCP_drb_SN_signalled;
-static gint signalled_pdcp_sn_bits = 12;
static gboolean global_rlc_lte_call_rrc_for_ccch = TRUE;
static gboolean global_rlc_lte_call_rrc_for_mcch = FALSE;
@@ -92,6 +91,17 @@ static gboolean global_rlc_lte_heur = FALSE;
/* Re-assembly of segments */
static gboolean global_rlc_lte_reassembly = TRUE;
+/* Tree storing UE related parameters */
+#define NO_EXT_LI 0x0
+#define UL_EXT_LI 0x1
+#define DL_EXT_LI 0x2
+typedef struct rlc_ue_parameters {
+ guint32 id;
+ guint8 ext_li_field;
+ guint8 pdcp_sn_bits;
+} rlc_ue_parameters;
+static wmem_tree_t *ue_parameters_tree;
+
/**************************************************/
/* Initialize the protocol and registered fields. */
int proto_rlc_lte = -1;
@@ -346,7 +356,7 @@ static const value_string header_only_vals[] =
/* These are for keeping track of UM/AM extension headers, and the lengths found */
/* in them */
static guint8 s_number_of_extensions = 0;
-#define MAX_RLC_SDUS 64
+#define MAX_RLC_SDUS 192
static guint16 s_lengths[MAX_RLC_SDUS];
@@ -675,7 +685,8 @@ static void write_pdu_label_and_info_literal(proto_item *pdu_ti, proto_item *sub
/* Dissect extension headers (common to both UM and AM) */
static int dissect_rlc_lte_extension_header(tvbuff_t *tvb, packet_info *pinfo _U_,
proto_tree *tree,
- int offset)
+ int offset,
+ rlc_lte_info *p_rlc_lte_info)
{
guint8 isOdd;
guint64 extension = 1;
@@ -688,8 +699,6 @@ static int dissect_rlc_lte_extension_header(tvbuff_t *tvb, packet_info *pinfo _U
proto_tree *extension_part_tree;
proto_item *extension_part_ti;
- isOdd = (s_number_of_extensions % 2);
-
/* Extension part subtree */
extension_part_ti = proto_tree_add_string_format(tree,
hf_rlc_lte_extension_part,
@@ -699,27 +708,46 @@ static int dissect_rlc_lte_extension_header(tvbuff_t *tvb, packet_info *pinfo _U
extension_part_tree = proto_item_add_subtree(extension_part_ti,
ett_rlc_lte_extension_part);
- /* Read next extension */
- proto_tree_add_bits_ret_val(extension_part_tree, hf_rlc_lte_extension_e, tvb,
- (offset*8) + ((isOdd) ? 4 : 0),
- 1,
- &extension, ENC_BIG_ENDIAN);
+ if (p_rlc_lte_info->extendedLiField == FALSE) {
+ isOdd = (s_number_of_extensions % 2);
- /* Read length field */
- proto_tree_add_bits_ret_val(extension_part_tree, hf_rlc_lte_extension_li, tvb,
- (offset*8) + ((isOdd) ? 5 : 1),
- 11,
- &length, ENC_BIG_ENDIAN);
+ /* Read next extension */
+ proto_tree_add_bits_ret_val(extension_part_tree, hf_rlc_lte_extension_e, tvb,
+ (offset*8) + ((isOdd) ? 4 : 0),
+ 1,
+ &extension, ENC_BIG_ENDIAN);
- proto_item_append_text(extension_part_tree, " (length=%u)", (guint16)length);
+ /* Read length field */
+ proto_tree_add_bits_ret_val(extension_part_tree, hf_rlc_lte_extension_li, tvb,
+ (offset*8) + ((isOdd) ? 5 : 1),
+ 11,
+ &length, ENC_BIG_ENDIAN);
- /* Move on to byte of next extension */
- if (isOdd) {
- offset += 2;
+ /* Move on to byte of next extension */
+ if (isOdd) {
+ offset += 2;
+ } else {
+ offset++;
+ }
} else {
- offset++;
+ /* Read next extension */
+ proto_tree_add_bits_ret_val(extension_part_tree, hf_rlc_lte_extension_e, tvb,
+ (offset*8),
+ 1,
+ &extension, ENC_BIG_ENDIAN);
+
+ /* Read length field */
+ proto_tree_add_bits_ret_val(extension_part_tree, hf_rlc_lte_extension_li, tvb,
+ (offset*8) + 1,
+ 15,
+ &length, ENC_BIG_ENDIAN);
+
+ /* Move on to byte of next extension */
+ offset += 2;
}
+ proto_item_append_text(extension_part_tree, " (length=%u)", (guint16)length);
+
s_lengths[s_number_of_extensions++] = (guint16)length;
}
@@ -765,6 +793,10 @@ static void show_PDU_in_tree(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb
rlc_lte_info *rlc_info, gboolean whole_pdu, rlc_channel_reassembly_info *reassembly_info,
sequence_analysis_state state)
{
+ wmem_tree_key_t key[3];
+ guint32 id;
+ rlc_ue_parameters *params;
+
/* Add raw data (according to mode) */
proto_item *data_ti = proto_tree_add_item(tree,
(rlc_info->rlcMode == RLC_AM_MODE) ?
@@ -825,7 +857,19 @@ static void show_PDU_in_tree(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb
break;
case PDCP_drb_SN_signalled:
/* Use whatever was signalled (e.g. in RRC) */
- p_pdcp_lte_info->seqnum_length = signalled_pdcp_sn_bits;
+ id = (rlc_info->channelId << 16) | rlc_info->ueid;
+ key[0].length = 1;
+ key[0].key = &id;
+ key[1].length = 1;
+ key[1].key = &PINFO_FD_NUM(pinfo);
+ key[2].length = 0;
+ key[2].key = NULL;
+
+ params = (rlc_ue_parameters *)wmem_tree_lookup32_array_le(ue_parameters_tree, key);
+ if (params && (params->id != id)) {
+ params = NULL;
+ }
+ p_pdcp_lte_info->seqnum_length = params ? params->pdcp_sn_bits : 12;
break;
default:
@@ -2117,7 +2161,7 @@ static void dissect_rlc_lte_um(tvbuff_t *tvb, packet_info *pinfo,
/*************************************/
/* UM header extension */
if (fixed_extension) {
- offset = dissect_rlc_lte_extension_header(tvb, pinfo, um_header_tree, offset);
+ offset = dissect_rlc_lte_extension_header(tvb, pinfo, um_header_tree, offset, p_rlc_lte_info);
}
/* Extract these 2 flags from framing_info */
@@ -2422,6 +2466,9 @@ static void dissect_rlc_lte_am(tvbuff_t *tvb, packet_info *pinfo,
proto_item *truncated_ti;
rlc_channel_reassembly_info *reassembly_info = NULL;
sequence_analysis_state seq_anal_state = SN_OK;
+ guint32 id;
+ wmem_tree_key_t key[3];
+ rlc_ue_parameters *params;
/* Hidden AM root */
am_ti = proto_tree_add_string_format(tree, hf_rlc_lte_am,
@@ -2506,7 +2553,21 @@ static void dissect_rlc_lte_am(tvbuff_t *tvb, packet_info *pinfo,
/*************************************/
/* AM header extension */
if (fixed_extension) {
- offset = dissect_rlc_lte_extension_header(tvb, pinfo, am_header_tree, offset);
+ if (!PINFO_FD_VISITED(pinfo)) {
+ id = (p_rlc_lte_info->channelId << 16) | p_rlc_lte_info->ueid;
+ key[0].length = 1;
+ key[0].key = &id;
+ key[1].length = 1;
+ key[1].key = &PINFO_FD_NUM(pinfo);
+ key[2].length = 0;
+ key[2].key = NULL;
+ params = (rlc_ue_parameters *)wmem_tree_lookup32_array_le(ue_parameters_tree, key);
+ if (params && (params->id == id)) {
+ p_rlc_lte_info->extendedLiField = (p_rlc_lte_info->direction == DIRECTION_UPLINK) ?
+ (params->ext_li_field & UL_EXT_LI): (params->ext_li_field & DL_EXT_LI);
+ }
+ }
+ offset = dissect_rlc_lte_extension_header(tvb, pinfo, am_header_tree, offset, p_rlc_lte_info);
}
/* Header is now complete */
@@ -2718,10 +2779,13 @@ static gboolean dissect_rlc_lte_heur(tvbuff_t *tvb, packet_info *pinfo,
p_rlc_lte_info->channelId = tvb_get_ntohs(tvb, offset);
offset += 2;
break;
+ case RLC_LTE_EXT_LI_FIELD_TAG:
+ p_rlc_lte_info->extendedLiField = TRUE;
+ break;
case RLC_LTE_PAYLOAD_TAG:
/* Have reached data, so set payload length and get out of loop */
- p_rlc_lte_info->pduLength= tvb_reported_length_remaining(tvb, offset);
+ p_rlc_lte_info->pduLength = tvb_reported_length_remaining(tvb, offset);
continue;
default:
@@ -2952,15 +3016,72 @@ static void rlc_lte_init_protocol(void)
reassembly_report_hash = g_hash_table_new(rlc_result_hash_func, rlc_result_hash_equal);
}
-
-/* Configure number of PDCP SN bits to use for DRB channels.
- TODO: currently assume all UEs/Channels will use the same SN length... */
-void set_rlc_lte_drb_pdcp_seqnum_length(guint16 ueid _U_, guint8 drbid _U_,
+/* Configure number of PDCP SN bits to use for DRB channels */
+void set_rlc_lte_drb_pdcp_seqnum_length(packet_info *pinfo, guint16 ueid, guint8 drbid,
guint8 userplane_seqnum_length)
{
- signalled_pdcp_sn_bits = userplane_seqnum_length;
+ wmem_tree_key_t key[3];
+ guint32 id;
+ rlc_ue_parameters *params;
+
+ if (PINFO_FD_VISITED(pinfo)) {
+ return;
+ }
+
+ id = (drbid << 16) | ueid;
+ key[0].length = 1;
+ key[0].key = &id;
+ key[1].length = 1;
+ key[1].key = &PINFO_FD_NUM(pinfo);
+ key[2].length = 0;
+ key[2].key = NULL;
+
+ params = (rlc_ue_parameters *)wmem_tree_lookup32_array_le(ue_parameters_tree, key);
+ if (params && (params->id != id)) {
+ params = NULL;
+ }
+ if (params == NULL) {
+ params = (rlc_ue_parameters *)wmem_new(wmem_file_scope(), rlc_ue_parameters);
+ params->id = id;
+ params->ext_li_field = NO_EXT_LI;
+ wmem_tree_insert32_array(ue_parameters_tree, key, (void *)params);
+ }
+ params->pdcp_sn_bits = userplane_seqnum_length;
}
+/*Configure LI field for AM DRB channels */
+void set_rlc_lte_drb_li_field(packet_info *pinfo, guint16 ueid, guint8 drbid,
+ gboolean ul_ext_li_field, gboolean dl_ext_li_field)
+{
+ wmem_tree_key_t key[3];
+ guint32 id;
+ rlc_ue_parameters *params;
+
+ if (PINFO_FD_VISITED(pinfo)) {
+ return;
+ }
+
+ id = (drbid << 16) | ueid;
+ key[0].length = 1;
+ key[0].key = &id;
+ key[1].length = 1;
+ key[1].key = &PINFO_FD_NUM(pinfo);
+ key[2].length = 0;
+ key[2].key = NULL;
+
+ params = (rlc_ue_parameters *)wmem_tree_lookup32_array_le(ue_parameters_tree, key);
+ if (params && (params->id != id)) {
+ params = NULL;
+ }
+ if (params == NULL) {
+ params = (rlc_ue_parameters *)wmem_new(wmem_file_scope(), rlc_ue_parameters);
+ params->id = id;
+ params->pdcp_sn_bits = 12;
+ wmem_tree_insert32_array(ue_parameters_tree, key, (void *)params);
+ }
+ params->ext_li_field = ul_ext_li_field ? UL_EXT_LI : NO_EXT_LI;
+ params->ext_li_field |= dl_ext_li_field ? DL_EXT_LI : NO_EXT_LI;
+}
void proto_register_rlc_lte(void)
{
@@ -3493,6 +3614,7 @@ void proto_register_rlc_lte(void)
"for reassembly to work",
&global_rlc_lte_reassembly);
+ ue_parameters_tree = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
register_init_routine(&rlc_lte_init_protocol);
}
diff --git a/epan/dissectors/packet-rlc-lte.h b/epan/dissectors/packet-rlc-lte.h
index 3eec50cfde..7b44d3e361 100644
--- a/epan/dissectors/packet-rlc-lte.h
+++ b/epan/dissectors/packet-rlc-lte.h
@@ -52,11 +52,12 @@ typedef struct rlc_lte_info
guint8 rlcMode;
guint8 direction;
guint8 priority;
+ guint8 UMSequenceNumberLength;
guint16 ueid;
guint16 channelType;
guint16 channelId;
guint16 pduLength;
- guint8 UMSequenceNumberLength;
+ gboolean extendedLiField;
} rlc_lte_info;
@@ -86,8 +87,10 @@ typedef struct rlc_lte_tap_info {
/* Configure number of PDCP SN bits to use for DRB channels. */
-void set_rlc_lte_drb_pdcp_seqnum_length(guint16 ueid, guint8 drbid, guint8 userplane_seqnum_length);
+void set_rlc_lte_drb_pdcp_seqnum_length(packet_info *pinfo, guint16 ueid, guint8 drbid, guint8 userplane_seqnum_length);
+/* Configure LI field for AM DRB channels. */
+void set_rlc_lte_drb_li_field(packet_info *pinfo, guint16 ueid, guint8 drbid, gboolean ul_ext_li_field, gboolean dl_ext_li_field);
/*****************************************************************/
/* UDP framing format */
@@ -143,6 +146,8 @@ void set_rlc_lte_drb_pdcp_seqnum_length(guint16 ueid, guint8 drbid, guint8 userp
#define RLC_LTE_CHANNEL_ID_TAG 0x07
/* 2 bytes, network order */
+#define RLC_LTE_EXT_LI_FIELD_TAG 0x08
+/* 0 byte, tag presence indicates that AM DRB PDU is using an extended LI field of 15 bits */
/* RLC PDU. Following this tag comes the actual RLC PDU (there is no length, the PDU
continues until the end of the frame) */