diff options
author | Martin Mathieson <martin.r.mathieson@googlemail.com> | 2019-04-27 17:45:09 +0100 |
---|---|---|
committer | Martin Mathieson <martin.r.mathieson@googlemail.com> | 2019-04-29 23:39:58 +0000 |
commit | dd708676d3c887058420a667c5e924cf037b39cb (patch) | |
tree | bb658b8270b472e743ec067079b0e2d1c31d30db /epan | |
parent | ca553bcb2a78ab65476bf4f2b2a35e7578064de0 (diff) |
NR: Configure LCID -> RLC Bearer config from RRC
Change-Id: Ida6af4ccd2157f967b9d2340e6f12319e4dbe688
Reviewed-on: https://code.wireshark.org/review/32998
Petri-Dish: Martin Mathieson <martin.r.mathieson@googlemail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Martin Mathieson <martin.r.mathieson@googlemail.com>
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/asn1/nr-rrc/nr-rrc.cnf | 90 | ||||
-rw-r--r-- | epan/dissectors/asn1/nr-rrc/packet-nr-rrc-template.c | 7 | ||||
-rw-r--r-- | epan/dissectors/packet-catapult-dct2000.c | 17 | ||||
-rw-r--r-- | epan/dissectors/packet-mac-lte.c | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-mac-nr.c | 258 | ||||
-rw-r--r-- | epan/dissectors/packet-mac-nr.h | 26 | ||||
-rw-r--r-- | epan/dissectors/packet-nr-rrc.c | 108 |
7 files changed, 452 insertions, 56 deletions
diff --git a/epan/dissectors/asn1/nr-rrc/nr-rrc.cnf b/epan/dissectors/asn1/nr-rrc/nr-rrc.cnf index 714efd3971..4ae512adc3 100644 --- a/epan/dissectors/asn1/nr-rrc/nr-rrc.cnf +++ b/epan/dissectors/asn1/nr-rrc/nr-rrc.cnf @@ -843,3 +843,93 @@ T-Reselection DISPLAY=BASE_DEC|BASE_UNIT_STRING STRINGS=&units_seconds #.TYPE_ATTR EUTRA-NS-PmaxValue/additionalPmax DISPLAY=BASE_DEC|BASE_UNIT_STRING STRINGS=&units_dbm + + + +#.FN_BODY RLC-BearerConfig + struct mac_nr_info *p_mac_nr_info; + /* Get the struct and clear it out */ + nr_drb_mapping_t *drb_mapping = &nr_rrc_get_private_data(actx)->drb_mapping; + memset(drb_mapping, 0, sizeof(nr_drb_mapping_t)); +%(DEFAULT_BODY)s + /* Need UE identifier */ + p_mac_nr_info = (mac_nr_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_mac_nr, 0); + if (p_mac_nr_info) { + drb_mapping->ueid = p_mac_nr_info->ueid; + /* Tell MAC about this mapping */ + set_mac_nr_bearer_mapping(drb_mapping); + } + + +#.FN_BODY DRB-Identity VAL_PTR=&value + guint32 value; + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; +%(DEFAULT_BODY)s + mapping->drbid = (guint8)value; + + +#.FN_BODY RLC-Config VAL_PTR=&value + guint32 value; + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; +%(DEFAULT_BODY)s + mapping->rlcMode = (value==0) ? RLC_AM_MODE : RLC_UM_MODE; + mapping->rlcMode_present = TRUE; + + +#.FN_BODY LogicalChannelIdentity VAL_PTR=&value + guint32 value; + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; +%(DEFAULT_BODY)s + mapping->lcid = (guint8)value; + mapping->lcid_present = TRUE; + + +#.FN_BODY UL-UM-RLC +%(DEFAULT_BODY)s + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; + mapping->tempDirection = DIRECTION_UPLINK; + +#.FN_BODY DL-UM-RLC +%(DEFAULT_BODY)s + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; + mapping->rlcMode_present = TRUE; + mapping->rlcMode = RLC_UM_MODE; + mapping->tempDirection = DIRECTION_DOWNLINK; + +#.FN_BODY UL-AM-RLC +%(DEFAULT_BODY)s + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; + mapping->tempDirection = DIRECTION_UPLINK; + +#.FN_BODY DL-AM-RLC +%(DEFAULT_BODY)s + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; + mapping->tempDirection = DIRECTION_DOWNLINK; + + +#.FN_BODY SN-FieldLengthUM VAL_PTR=&value + guint32 value; +%(DEFAULT_BODY)s + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; + if (mapping->tempDirection == DIRECTION_UPLINK) { + mapping->rlcUlSnLength_present = TRUE; + mapping->rlcUlSnLength = (value=0) ? 6 : 12; + } + else { + mapping->rlcDlSnLength_present = TRUE; + mapping->rlcDlSnLength = (value=0) ? 6 : 12; + } + + +#.FN_BODY SN-FieldLengthAM VAL_PTR=&value + guint32 value; +%(DEFAULT_BODY)s + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; + if (mapping->tempDirection == DIRECTION_UPLINK) { + mapping->rlcUlSnLength_present = TRUE; + mapping->rlcUlSnLength = (value=0) ? 12 : 18; + } + else { + mapping->rlcDlSnLength_present = TRUE; + mapping->rlcDlSnLength = (value=0) ? 12 : 18; +} diff --git a/epan/dissectors/asn1/nr-rrc/packet-nr-rrc-template.c b/epan/dissectors/asn1/nr-rrc/packet-nr-rrc-template.c index 9a5113ed03..98c16b170d 100644 --- a/epan/dissectors/asn1/nr-rrc/packet-nr-rrc-template.c +++ b/epan/dissectors/asn1/nr-rrc/packet-nr-rrc-template.c @@ -21,12 +21,15 @@ #include <epan/reassemble.h> #include <epan/exceptions.h> #include <epan/show_exception.h> +#include <epan/proto_data.h> #include <wsutil/str_util.h> #include "packet-per.h" #include "packet-gsm_map.h" #include "packet-cell_broadcast.h" +#include "packet-mac-nr.h" +#include "packet-rlc-nr.h" #include "packet-lte-rrc.h" #include "packet-nr-rrc.h" @@ -45,6 +48,8 @@ static wmem_map_t *nr_rrc_etws_cmas_dcs_hash = NULL; static reassembly_table nr_rrc_sib7_reassembly_table; static reassembly_table nr_rrc_sib8_reassembly_table; +extern int proto_mac_nr; + /* Include constants */ #include "packet-nr-rrc-val.h" @@ -113,6 +118,7 @@ typedef struct { guint16 message_identifier; guint8 warning_message_segment_type; guint8 warning_message_segment_number; + nr_drb_mapping_t drb_mapping; } nr_rrc_private_data_t; /* Helper function to get or create a struct that will be actx->private_data */ @@ -125,6 +131,7 @@ nr_rrc_get_private_data(asn1_ctx_t *actx) return (nr_rrc_private_data_t*)actx->private_data; } + static void nr_rrc_call_dissector(dissector_handle_t handle, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { diff --git a/epan/dissectors/packet-catapult-dct2000.c b/epan/dissectors/packet-catapult-dct2000.c index d04c877fe9..89d4c99a63 100644 --- a/epan/dissectors/packet-catapult-dct2000.c +++ b/epan/dissectors/packet-catapult-dct2000.c @@ -29,6 +29,8 @@ #include "packet-rlc-lte.h" #include "packet-pdcp-lte.h" +#include "packet-mac-nr.h" + void proto_reg_handoff_catapult_dct2000(void); void proto_register_catapult_dct2000(void); @@ -853,6 +855,7 @@ static void dissect_rrc_lte_nr(tvbuff_t *tvb, gint offset, LogicalChannelType logicalChannelType; guint16 cell_id; guint8 bcch_transport = 0; + guint32 ueid = 0; tvbuff_t *rrc_tvb; /* Top-level opcode */ @@ -892,7 +895,7 @@ static void dissect_rrc_lte_nr(tvbuff_t *tvb, gint offset, logicalChannelType = Channel_DCCH; /* UEId */ - proto_tree_add_item(tree, hf_catapult_dct2000_ueid, tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item_ret_uint(tree, hf_catapult_dct2000_ueid, tvb, offset, 2, ENC_BIG_ENDIAN, &ueid); offset += 2; /* Get tag of channel type */ @@ -1099,6 +1102,18 @@ static void dissect_rrc_lte_nr(tvbuff_t *tvb, gint offset, /* Send to RRC dissector, if got here, have sub-dissector and some data left */ if ((protocol_handle != NULL) && (tvb_reported_length_remaining(tvb, offset) > 0)) { + + /* Set MAC-NR info for this PDU. Needed so that UEId can be found for this frame, + * as used by MAC/RLC/PDCP configuration from RRC dissector */ + if (ueid) { + struct mac_nr_info *p_mac_nr_info; + p_mac_nr_info = wmem_new0(wmem_file_scope(), struct mac_nr_info); + p_mac_nr_info->ueid = ueid; + p_mac_nr_info->direction = (isUplink) ? DIRECTION_UPLINK : DIRECTION_DOWNLINK; + /* Store info in packet */ + set_mac_nr_proto_data(pinfo, p_mac_nr_info); + } + rrc_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector_only(protocol_handle, rrc_tvb, pinfo, tree, NULL); } diff --git a/epan/dissectors/packet-mac-lte.c b/epan/dissectors/packet-mac-lte.c index 5f6fde3140..75cef3c50f 100644 --- a/epan/dissectors/packet-mac-lte.c +++ b/epan/dissectors/packet-mac-lte.c @@ -4318,7 +4318,7 @@ static void lookup_rlc_channel_from_lcid(guint16 ueid, } } else { - /* Look up the mappings for this UE */ + /* Look up the dynamic mappings for this UE */ ue_dynamic_drb_mappings_t *ue_mappings = (ue_dynamic_drb_mappings_t *)g_hash_table_lookup(mac_lte_ue_channels_hash, GUINT_TO_POINTER((guint)ueid)); if (!ue_mappings) { return; diff --git a/epan/dissectors/packet-mac-nr.c b/epan/dissectors/packet-mac-nr.c index 23b566d0c2..1d612d1d2c 100644 --- a/epan/dissectors/packet-mac-nr.c +++ b/epan/dissectors/packet-mac-nr.c @@ -351,6 +351,13 @@ static gint global_mac_nr_layer_to_show = (gint)ShowRLCLayer; /***********************************************************************/ /* How to dissect lcid 3-32 (presume drb logical channels) */ +/* Where to take LCID -> DRB mappings from */ +enum lcid_drb_source { + FromStaticTable, FromConfigurationProtocol +}; +static gint global_mac_nr_lcid_drb_source = (gint)FromStaticTable; + + static const value_string drb_lcid_vals[] = { { 3, "LCID 3"}, { 4, "LCID 4"}, @@ -409,7 +416,8 @@ static const value_string rlc_bearer_type_vals[] = { typedef struct lcid_drb_mapping_t { guint32 lcid; guint32 drbid; - rlc_bearer_type_t bearer_type; + rlc_bearer_type_t bearer_type_ul; + rlc_bearer_type_t bearer_type_dl; } lcid_drb_mapping_t; /* Mapping entity */ @@ -418,11 +426,32 @@ static guint num_lcid_drb_mappings = 0; UAT_VS_DEF(lcid_drb_mappings, lcid, lcid_drb_mapping_t, guint8, 3, "LCID 3") UAT_DEC_CB_DEF(lcid_drb_mappings, drbid, lcid_drb_mapping_t) -UAT_VS_DEF(lcid_drb_mappings, bearer_type, lcid_drb_mapping_t, rlc_bearer_type_t, rlcAM12, "AM") +UAT_VS_DEF(lcid_drb_mappings, bearer_type_ul, lcid_drb_mapping_t, rlc_bearer_type_t, rlcAM12, "AM") +UAT_VS_DEF(lcid_drb_mappings, bearer_type_dl, lcid_drb_mapping_t, rlc_bearer_type_t, rlcAM12, "AM") /* UAT object */ static uat_t* lcid_drb_mappings_uat; +/* Dynamic mappings (set by configuration protocol) + LCID is the index into the array of these */ +typedef struct dynamic_lcid_drb_mapping_t { + gboolean valid; + gint drbid; + rlc_bearer_type_t bearer_type_ul; + rlc_bearer_type_t bearer_type_dl; + guint8 ul_priority; // N.B. not yet in rlc_nr_info +} dynamic_lcid_drb_mapping_t; + +typedef struct ue_dynamic_drb_mappings_t { + dynamic_lcid_drb_mapping_t mapping[33]; /* Index is LCID (2-32) */ + guint8 drb_to_lcid_mappings[33]; /* Also map drbid (1-32) -> lcid */ +} ue_dynamic_drb_mappings_t; + +static GHashTable *mac_nr_ue_bearers_hash = NULL; + + + + /* When showing RLC info, count PDUs so can append info column properly */ static guint8 s_number_of_rlc_pdus_shown = 0; @@ -776,7 +805,7 @@ static const value_string buffer_size_8bits_vals[] = { 96, "3934 < BS <= 4189"}, { 97, "4189 < BS <= 4461"}, { 98, "4461 < BS <= 4751"}, - { 99, "4751 < BS <= 5059"}, + { 99, "4751 < BS <= 5059"}, { 100, "5059 < BS <= 5387"}, { 101, "5387 < BS <= 5737"}, { 102, "5737 < BS <= 6109"}, @@ -1374,59 +1403,80 @@ static proto_item* dissect_me_phr_ph(tvbuff_t *tvb, packet_info *pinfo _U_, prot } -static void set_rlc_seqnum_length(rlc_bearer_type_t rlc_bearer_type, - guint8 direction _U_, - guint8 *seqnum_length) +static guint8 get_rlc_seqnum_length(rlc_bearer_type_t rlc_bearer_type) { switch (rlc_bearer_type) { case rlcUM6: - *seqnum_length = 6; - break; + return 6; case rlcUM12: - *seqnum_length = 12; - break; - + return 12; case rlcAM12: - *seqnum_length = 12; - break; + return 12; case rlcAM18: - *seqnum_length = 18; - break; + return 18; default: - break; + /* Not expected */ + return 0; } } -/* Lookup channel details for lcid */ -static void lookup_rlc_channel_from_lcid(guint16 ueid _U_, - guint8 lcid, - guint8 direction, - rlc_bearer_type_t *rlc_bearer_type, - guint8 *seqnum_length, - gint *drb_id) +/* Lookup bearer details for lcid */ +static gboolean lookup_rlc_bearer_from_lcid(guint16 ueid, + guint8 lcid, + guint8 direction, + rlc_bearer_type_t *rlc_bearer_type, /* out */ + guint8 *seqnum_length, /* out */ + gint *drb_id) /* out */ { /* Zero params (in case no match is found) */ *rlc_bearer_type = rlcRaw; *seqnum_length = 0; *drb_id = 0; - /* Look up in static (UAT) table */ - guint m; - for (m=0; m < num_lcid_drb_mappings; m++) { - if (lcid == lcid_drb_mappings[m].lcid) { + if (global_mac_nr_lcid_drb_source == (int)FromStaticTable) { - *rlc_bearer_type = lcid_drb_mappings[m].bearer_type; + /* Look up in static (UAT) table */ + guint m; + for (m=0; m < num_lcid_drb_mappings; m++) { + if (lcid == lcid_drb_mappings[m].lcid) { - /* Set seqnum_length and rlc_ext_li_field */ - set_rlc_seqnum_length(*rlc_bearer_type, direction, seqnum_length); + /* Found, set out parameters */ + if (direction == DIRECTION_UPLINK) { + *rlc_bearer_type = lcid_drb_mappings[m].bearer_type_ul; + } + else { + *rlc_bearer_type = lcid_drb_mappings[m].bearer_type_dl; + } + *seqnum_length = get_rlc_seqnum_length(*rlc_bearer_type); + *drb_id = lcid_drb_mappings[m].drbid; + return TRUE; + } + } + return FALSE; + } + else { + /* Look up the dynamic mappings for this UE */ + ue_dynamic_drb_mappings_t *ue_mappings = (ue_dynamic_drb_mappings_t *)g_hash_table_lookup(mac_nr_ue_bearers_hash, GUINT_TO_POINTER((guint)ueid)); + if (!ue_mappings) { + return FALSE; + } - /* Set drb_id */ - *drb_id = lcid_drb_mappings[m].drbid; - break; + /* Look up setting gleaned from configuration protocol */ + if (!ue_mappings->mapping[lcid].valid) { + return FALSE; } + + /* Found, set out params */ + *rlc_bearer_type = (direction == DIRECTION_DOWNLINK) ? + ue_mappings->mapping[lcid].bearer_type_ul : + ue_mappings->mapping[lcid].bearer_type_dl; + *seqnum_length = get_rlc_seqnum_length(*rlc_bearer_type); + *drb_id = ue_mappings->mapping[lcid].drbid; + + return TRUE; } } @@ -1596,7 +1646,7 @@ static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree } /* Call RLC if configured to do so for this SDU */ - if ((lcid >= 3) && (lcid <= 32)) { + if ((lcid >= 4) && (lcid <= 32)) { /* Look for mapping for this LCID to drb channel set by UAT table */ rlc_bearer_type_t rlc_bearer_type; guint8 seqnum_length; @@ -1604,12 +1654,12 @@ static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree // TODO: priority not set. guint8 priority = 0; - lookup_rlc_channel_from_lcid(p_mac_nr_info->ueid, - lcid, - p_mac_nr_info->direction, - &rlc_bearer_type, - &seqnum_length, - &drb_id); + lookup_rlc_bearer_from_lcid(p_mac_nr_info->ueid, + lcid, + p_mac_nr_info->direction, + &rlc_bearer_type, + &seqnum_length, + &drb_id); /* Dissect according to channel type */ switch (rlc_bearer_type) { @@ -2628,11 +2678,105 @@ static void* lcid_drb_mapping_copy_cb(void* dest, const void* orig, size_t len _ /* Copy all items over */ d->lcid = o->lcid; d->drbid = o->drbid; - d->bearer_type = o->bearer_type; + d->bearer_type_ul = o->bearer_type_ul; + d->bearer_type_dl = o->bearer_type_dl; return d; } +static void set_bearer_type(dynamic_lcid_drb_mapping_t *mapping, guint8 rlcMode, guint8 rlcSnLength, guint8 direction) +{ + rlc_bearer_type_t *type_var = (direction == DIRECTION_UPLINK) ? + &mapping->bearer_type_ul : + &mapping->bearer_type_dl; + + switch (rlcMode) { + case RLC_AM_MODE: + switch (rlcSnLength) { + case 12: + *type_var = rlcAM12; + break; + case 18: + *type_var = rlcAM18; + break; + + default: + break; + } + break; + case RLC_UM_MODE: + switch (rlcSnLength) { + case 6: + *type_var = rlcUM6; + break; + case 12: + *type_var = rlcUM12; + break; + + default: + break; + } + break; + + default: + break; + } +} + + +/* Set LCID -> RLC channel mappings from signalling protocol (i.e. RRC or similar). */ +void set_mac_nr_bearer_mapping(nr_drb_mapping_t *drb_mapping) +{ + ue_dynamic_drb_mappings_t *ue_mappings; + guint8 lcid = 0; + + /* Check lcid range */ + if (drb_mapping->lcid_present) { + lcid = drb_mapping->lcid; + + /* Ignore if LCID is out of range */ + if ((lcid < 4) || (lcid > 32)) { + return; + } + } + + /* Look for existing UE entry */ + ue_mappings = (ue_dynamic_drb_mappings_t *)g_hash_table_lookup(mac_nr_ue_bearers_hash, + GUINT_TO_POINTER((guint)drb_mapping->ueid)); + if (!ue_mappings) { + /* If not found, create & add to table */ + ue_mappings = wmem_new0(wmem_file_scope(), ue_dynamic_drb_mappings_t); + g_hash_table_insert(mac_nr_ue_bearers_hash, + GUINT_TO_POINTER((guint)drb_mapping->ueid), + ue_mappings); + } + + /* If lcid wasn't supplied, need to try to look up from drbid */ + if ((lcid == 0) && (drb_mapping->drbid <= 32)) { + lcid = ue_mappings->drb_to_lcid_mappings[drb_mapping->drbid]; + } + if (lcid == 0) { + /* Still no lcid - give up */ + return; + } + + /* Set array entry */ + ue_mappings->mapping[lcid].valid = TRUE; + ue_mappings->mapping[lcid].drbid = drb_mapping->drbid; + ue_mappings->drb_to_lcid_mappings[drb_mapping->drbid] = lcid; + + /* Fill in available RLC info */ + if (drb_mapping->rlcMode_present) { + if (drb_mapping->rlcUlSnLength_present) { + set_bearer_type(&ue_mappings->mapping[lcid], drb_mapping->rlcMode, drb_mapping->rlcUlSnLength, DIRECTION_UPLINK); + } + if (drb_mapping->rlcDlSnLength_present) { + set_bearer_type(&ue_mappings->mapping[lcid], drb_mapping->rlcMode, drb_mapping->rlcDlSnLength, DIRECTION_DOWNLINK); + } + } +} + + /* Function to be called from outside this module (e.g. in a plugin) to get per-packet data */ mac_nr_info *get_mac_nr_proto_data(packet_info *pinfo) { @@ -2645,6 +2789,20 @@ void set_mac_nr_proto_data(packet_info *pinfo, mac_nr_info *p_mac_nr_info) p_add_proto_data(wmem_file_scope(), pinfo, proto_mac_nr, 0, p_mac_nr_info); } +/* Initializes the hash tables each time a new + * file is loaded or re-loaded in wireshark */ +static void mac_nr_init_protocol(void) +{ + mac_nr_ue_bearers_hash = g_hash_table_new(g_direct_hash, g_direct_equal); +} + +static void mac_nr_cleanup_protocol(void) +{ + g_hash_table_destroy(mac_nr_ue_bearers_hash); +} + + + void proto_register_mac_nr(void) { static hf_register_info hf[] = @@ -4280,10 +4438,17 @@ void proto_register_mac_nr(void) module_t *mac_nr_module; expert_module_t* expert_mac_nr; + static const enum_val_t lcid_drb_source_vals[] = { + {"from-static-stable", "From static table", FromStaticTable}, + {"from-configuration-protocol", "From configuration protocol", FromConfigurationProtocol}, + {NULL, NULL, -1} + }; + static uat_field_t lcid_drb_mapping_flds[] = { UAT_FLD_VS(lcid_drb_mappings, lcid, "LCID (3-32)", drb_lcid_vals, "The MAC LCID"), UAT_FLD_DEC(lcid_drb_mappings, drbid,"DRBID id (1-32)", "Identifier of logical data channel"), - UAT_FLD_VS(lcid_drb_mappings, bearer_type, "RLC Channel Type", rlc_bearer_type_vals, "The MAC LCID"), + UAT_FLD_VS(lcid_drb_mappings, bearer_type_ul, "UL RLC Bearer Type", rlc_bearer_type_vals, "UL Bearer Mode"), + UAT_FLD_VS(lcid_drb_mappings, bearer_type_dl, "DL RLC Bearer Type", rlc_bearer_type_vals, "DL Bearer Mode"), UAT_END_FIELDS }; @@ -4305,6 +4470,12 @@ void proto_register_mac_nr(void) "Attempt to decode BCCH, PCCH and CCCH data using NR RRC dissector", &global_mac_nr_attempt_rrc_decode); + prefs_register_enum_preference(mac_nr_module, "lcid_to_drb_mapping_source", + "Source of LCID -> drb channel settings", + "Set whether LCID -> drb Table is taken from static table (below) or from " + "info learned from control protocol (i.e. RRC)", + &global_mac_nr_lcid_drb_source, lcid_drb_source_vals, FALSE); + lcid_drb_mappings_uat = uat_new("Static LCID -> drb Table", sizeof(lcid_drb_mapping_t), "drb_bearerconfig", @@ -4325,6 +4496,9 @@ void proto_register_mac_nr(void) "LCID -> DRB Mappings Table", "A table that maps from configurable lcids -> RLC bearer configs", lcid_drb_mappings_uat); + + register_init_routine(&mac_nr_init_protocol); + register_cleanup_routine(&mac_nr_cleanup_protocol); } void proto_reg_handoff_mac_nr(void) diff --git a/epan/dissectors/packet-mac-nr.h b/epan/dissectors/packet-mac-nr.h index 921a6b22ac..6d3f925fb8 100644 --- a/epan/dissectors/packet-mac-nr.h +++ b/epan/dissectors/packet-mac-nr.h @@ -108,6 +108,32 @@ void set_mac_nr_proto_data(packet_info *pinfo, mac_nr_info *p_mac_nr_info); continues until the end of the frame) */ #define MAC_NR_PAYLOAD_TAG 0x01 + +/* Type to store parameters for configuring LCID->RLC channel settings for DRB */ +/* Some are optional, and may not be seen (e.g. on reestablishment) */ +typedef struct nr_drb_mapping_t +{ + guint16 ueid; /* Mandatory */ + guint8 drbid; /* Mandatory */ + gboolean lcid_present; + guint8 lcid; /* Part of LogicalChannelConfig - optional */ + gboolean rlcMode_present; + guint8 rlcMode; /* Part of RLC config - optional */ + + guint8 tempDirection; /* So know direction of next SN length... */ + + gboolean rlcUlSnLength_present; + guint8 rlcUlSnLength; /* Part of RLC config - optional */ + gboolean rlcDlSnLength_present; + guint8 rlcDlSnLength; /* Part of RLC config - optional */ +} nr_drb_mapping_t; + + +/* Set details of an LCID -> drb channel mapping. To be called from + configuration protocol (i.e. RRC) */ +void set_mac_nr_bearer_mapping(nr_drb_mapping_t *drb_mapping); + + /* * Editor modelines - http://www.wireshark.org/tools/modelines.html * diff --git a/epan/dissectors/packet-nr-rrc.c b/epan/dissectors/packet-nr-rrc.c index 32665e0460..29d49e449d 100644 --- a/epan/dissectors/packet-nr-rrc.c +++ b/epan/dissectors/packet-nr-rrc.c @@ -29,12 +29,15 @@ #include <epan/reassemble.h> #include <epan/exceptions.h> #include <epan/show_exception.h> +#include <epan/proto_data.h> #include <wsutil/str_util.h> #include "packet-per.h" #include "packet-gsm_map.h" #include "packet-cell_broadcast.h" +#include "packet-mac-nr.h" +#include "packet-rlc-nr.h" #include "packet-lte-rrc.h" #include "packet-nr-rrc.h" @@ -53,6 +56,8 @@ static wmem_map_t *nr_rrc_etws_cmas_dcs_hash = NULL; static reassembly_table nr_rrc_sib7_reassembly_table; static reassembly_table nr_rrc_sib8_reassembly_table; +extern int proto_mac_nr; + /* Include constants */ /*--- Included file: packet-nr-rrc-val.h ---*/ @@ -239,7 +244,7 @@ typedef enum _T_targetRAT_Type_enum { } T_targetRAT_Type_enum; /*--- End of included file: packet-nr-rrc-val.h ---*/ -#line 50 "./asn1/nr-rrc/packet-nr-rrc-template.c" +#line 55 "./asn1/nr-rrc/packet-nr-rrc-template.c" /* Initialize the protocol and registered fields */ static int proto_nr_rrc = -1; @@ -3083,7 +3088,7 @@ static int hf_nr_rrc_overheatingIndicationProhibitTimer = -1; /* T_overheatingI static int dummy_hf_nr_rrc_eag_field = -1; /* never registered */ /*--- End of included file: packet-nr-rrc-hf.c ---*/ -#line 54 "./asn1/nr-rrc/packet-nr-rrc-template.c" +#line 59 "./asn1/nr-rrc/packet-nr-rrc-template.c" static int hf_nr_rrc_serialNumber_gs = -1; static int hf_nr_rrc_serialNumber_msg_code = -1; static int hf_nr_rrc_serialNumber_upd_nb = -1; @@ -4286,7 +4291,7 @@ static gint ett_nr_rrc_T_overheatingAssistanceConfig = -1; static gint ett_nr_rrc_OverheatingAssistanceConfig = -1; /*--- End of included file: packet-nr-rrc-ett.c ---*/ -#line 90 "./asn1/nr-rrc/packet-nr-rrc-template.c" +#line 95 "./asn1/nr-rrc/packet-nr-rrc-template.c" static gint ett_nr_rrc_DedicatedNAS_Message = -1; static gint ett_rr_rrc_targetRAT_MessageContainer = -1; static gint ett_nr_rrc_nas_Container = -1; @@ -4313,6 +4318,7 @@ typedef struct { guint16 message_identifier; guint8 warning_message_segment_type; guint8 warning_message_segment_number; + nr_drb_mapping_t drb_mapping; } nr_rrc_private_data_t; /* Helper function to get or create a struct that will be actx->private_data */ @@ -4325,6 +4331,7 @@ nr_rrc_get_private_data(asn1_ctx_t *actx) return (nr_rrc_private_data_t*)actx->private_data; } + static void nr_rrc_call_dissector(dissector_handle_t handle, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { @@ -13877,8 +13884,15 @@ dissect_nr_rrc_CellGroupId(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _ static int dissect_nr_rrc_LogicalChannelIdentity(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + guint32 value; + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index, - 1U, maxLC_ID, NULL, FALSE); + 1U, maxLC_ID, &value, FALSE); + + mapping->lcid = (guint8)value; + mapping->lcid_present = TRUE; + + return offset; } @@ -14244,8 +14258,14 @@ dissect_nr_rrc_T_cnAssociation(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *ac static int dissect_nr_rrc_DRB_Identity(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + guint32 value; + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index, - 1U, 32U, NULL, FALSE); + 1U, 32U, &value, FALSE); + + mapping->drbid = (guint8)value; + + return offset; } @@ -26400,8 +26420,19 @@ static const value_string nr_rrc_SN_FieldLengthAM_vals[] = { static int dissect_nr_rrc_SN_FieldLengthAM(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + guint32 value; offset = dissect_per_enumerated(tvb, offset, actx, tree, hf_index, - 2, NULL, FALSE, 0, NULL); + 2, &value, FALSE, 0, NULL); + + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; + if (mapping->tempDirection == DIRECTION_UPLINK) { + mapping->rlcUlSnLength_present = TRUE; + mapping->rlcUlSnLength = (value=0) ? 12 : 18; + } + else { + mapping->rlcDlSnLength_present = TRUE; + mapping->rlcDlSnLength = (value=0) ? 12 : 18; +} return offset; } @@ -26651,6 +26682,10 @@ dissect_nr_rrc_UL_AM_RLC(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_ offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index, ett_nr_rrc_UL_AM_RLC, UL_AM_RLC_sequence); + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; + mapping->tempDirection = DIRECTION_UPLINK; + + return offset; } @@ -26795,6 +26830,11 @@ dissect_nr_rrc_DL_AM_RLC(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_ offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index, ett_nr_rrc_DL_AM_RLC, DL_AM_RLC_sequence); + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; + mapping->tempDirection = DIRECTION_DOWNLINK; + + + return offset; } @@ -26823,8 +26863,21 @@ static const value_string nr_rrc_SN_FieldLengthUM_vals[] = { static int dissect_nr_rrc_SN_FieldLengthUM(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + guint32 value; offset = dissect_per_enumerated(tvb, offset, actx, tree, hf_index, - 2, NULL, FALSE, 0, NULL); + 2, &value, FALSE, 0, NULL); + + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; + if (mapping->tempDirection == DIRECTION_UPLINK) { + mapping->rlcUlSnLength_present = TRUE; + mapping->rlcUlSnLength = (value=0) ? 6 : 12; + } + else { + mapping->rlcDlSnLength_present = TRUE; + mapping->rlcDlSnLength = (value=0) ? 6 : 12; + } + + return offset; } @@ -26840,6 +26893,10 @@ dissect_nr_rrc_UL_UM_RLC(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_ offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index, ett_nr_rrc_UL_UM_RLC, UL_UM_RLC_sequence); + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; + mapping->tempDirection = DIRECTION_UPLINK; + + return offset; } @@ -26855,6 +26912,12 @@ dissect_nr_rrc_DL_UM_RLC(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_ offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index, ett_nr_rrc_DL_UM_RLC, DL_UM_RLC_sequence); + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; + mapping->rlcMode_present = TRUE; + mapping->rlcMode = RLC_UM_MODE; + mapping->tempDirection = DIRECTION_DOWNLINK; + + return offset; } @@ -26920,9 +26983,16 @@ static const per_choice_t RLC_Config_choice[] = { static int dissect_nr_rrc_RLC_Config(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + guint32 value; + nr_drb_mapping_t *mapping = &nr_rrc_get_private_data(actx)->drb_mapping; offset = dissect_per_choice(tvb, offset, actx, tree, hf_index, ett_nr_rrc_RLC_Config, RLC_Config_choice, - NULL); + &value); + + mapping->rlcMode = (value==0) ? RLC_AM_MODE : RLC_UM_MODE; + mapping->rlcMode_present = TRUE; + + return offset; } @@ -27135,9 +27205,23 @@ static const per_sequence_t RLC_BearerConfig_sequence[] = { static int dissect_nr_rrc_RLC_BearerConfig(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + struct mac_nr_info *p_mac_nr_info; + /* Get the struct and clear it out */ + nr_drb_mapping_t *drb_mapping = &nr_rrc_get_private_data(actx)->drb_mapping; + memset(drb_mapping, 0, sizeof(nr_drb_mapping_t)); offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index, ett_nr_rrc_RLC_BearerConfig, RLC_BearerConfig_sequence); + /* Need UE identifier */ + p_mac_nr_info = (mac_nr_info *)p_get_proto_data(wmem_file_scope(), actx->pinfo, proto_mac_nr, 0); + if (p_mac_nr_info) { + drb_mapping->ueid = p_mac_nr_info->ueid; + /* Tell MAC about this mapping */ + set_mac_nr_bearer_mapping(drb_mapping); + } + + + return offset; } @@ -41815,7 +41899,7 @@ static int dissect_SystemInformation_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _ /*--- End of included file: packet-nr-rrc-fn.c ---*/ -#line 353 "./asn1/nr-rrc/packet-nr-rrc-template.c" +#line 360 "./asn1/nr-rrc/packet-nr-rrc-template.c" void proto_register_nr_rrc(void) { @@ -53164,7 +53248,7 @@ proto_register_nr_rrc(void) { NULL, HFILL }}, /*--- End of included file: packet-nr-rrc-hfarr.c ---*/ -#line 361 "./asn1/nr-rrc/packet-nr-rrc-template.c" +#line 368 "./asn1/nr-rrc/packet-nr-rrc-template.c" { &hf_nr_rrc_serialNumber_gs, { "Geographical Scope", "nr-rrc.serialNumber.gs", @@ -54465,7 +54549,7 @@ proto_register_nr_rrc(void) { &ett_nr_rrc_OverheatingAssistanceConfig, /*--- End of included file: packet-nr-rrc-ettarr.c ---*/ -#line 495 "./asn1/nr-rrc/packet-nr-rrc-template.c" +#line 502 "./asn1/nr-rrc/packet-nr-rrc-template.c" &ett_nr_rrc_DedicatedNAS_Message, &ett_rr_rrc_targetRAT_MessageContainer, &ett_nr_rrc_nas_Container, @@ -54516,7 +54600,7 @@ proto_register_nr_rrc(void) { /*--- End of included file: packet-nr-rrc-dis-reg.c ---*/ -#line 527 "./asn1/nr-rrc/packet-nr-rrc-template.c" +#line 534 "./asn1/nr-rrc/packet-nr-rrc-template.c" nr_rrc_etws_cmas_dcs_hash = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_direct_hash, g_direct_equal); |