diff options
-rw-r--r-- | asn1/lte-rrc/lte-rrc.cnf | 27 | ||||
-rw-r--r-- | asn1/lte-rrc/packet-lte-rrc-template.c | 1 | ||||
-rw-r--r-- | epan/dissectors/packet-lte-rrc.c | 42 | ||||
-rw-r--r-- | epan/dissectors/packet-mac-lte.c | 102 | ||||
-rw-r--r-- | epan/dissectors/packet-mac-lte.h | 18 | ||||
-rw-r--r-- | epan/dissectors/packet-rlc-lte.c | 182 | ||||
-rw-r--r-- | epan/dissectors/packet-rlc-lte.h | 9 |
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(<e_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(<e_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(<e_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) */ |