LTE: Update MAC and RLC dissectors to Release 12

Change-Id: I036a0d1180b6481e8cc27210ed44eda4ba078a27
Reviewed-on: https://code.wireshark.org/review/5659
Reviewed-by: Martin Mathieson <martin.r.mathieson@googlemail.com>
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
This commit is contained in:
Pascal Quantin 2014-12-07 20:54:05 +01:00
parent 58fc89a83b
commit 74172aee0b
7 changed files with 286 additions and 99 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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);
/* 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;
} else {
offset++;
}
} else {
/* 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);
/* Move on to byte of next extension */
if (isOdd) {
offset += 2;
} else {
offset++;
}
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);
}

View File

@ -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) */