Re-arrange dissection of UL/DL-SCH so easier to test for ommitted SDUs.

svn path=/trunk/; revision=29845
This commit is contained in:
Martin Mathieson 2009-09-10 18:12:41 +00:00
parent b97cfa22fd
commit 019625d876
1 changed files with 330 additions and 331 deletions

View File

@ -962,6 +962,7 @@ static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree
gboolean have_seen_data_header = FALSE;
gboolean have_seen_bsr = FALSE;
gboolean expecting_body_data = FALSE;
guint32 is_truncated = FALSE;
col_append_fstr(pinfo->cinfo, COL_INFO, "%s: (SF=%u) UEId=%u ",
(direction == DIRECTION_UPLINK) ? "UL-SCH" : "DL-SCH",
@ -1163,100 +1164,21 @@ static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree
proto_item_set_len(pdu_header_ti, offset);
/* TODO: some valid PDUs don't have any bodies, so don't want expert info.
Use expecting_body_data to track this */
/* There might not be any data, if only headers were logged */
truncated_ti = proto_tree_add_uint(tree, hf_mac_lte_sch_header_only, tvb, 0, 0,
tvb_length_remaining(tvb, offset) == 0);
if (tvb_length_remaining(tvb, offset) == 0) {
PROTO_ITEM_SET_GENERATED(truncated_ti);
expert_add_info_format(pinfo, truncated_ti, PI_SEQUENCE, PI_NOTE,
"MAC PDU SDUs have been ommitted");
return;
}
else {
PROTO_ITEM_SET_HIDDEN(truncated_ti);
}
/************************************************************************/
/* Dissect SDUs / control elements / padding. */
/************************************************************************/
/* Dissect control element bodies first */
for (n=0; n < number_of_headers; n++) {
/* Data SDUs treated identically for Uplink or downlink channels */
/* Get out of loop once see any data SDU subheaders */
if (lcids[n] <= 10) {
proto_item *sdu_ti;
volatile guint16 data_length = (pdu_lengths[n] == -1) ?
tvb_length_remaining(tvb, offset) :
pdu_lengths[n];
/* Dissect SDU */
sdu_ti = proto_tree_add_bytes_format(tree, hf_mac_lte_sch_sdu, tvb, offset, pdu_lengths[n],
tvb_get_ptr(tvb, offset, pdu_lengths[n]),
"SDU (%s, length=%u bytes)",
val_to_str(lcids[n],
(direction == DIRECTION_UPLINK) ?
ulsch_lcid_vals :
dlsch_lcid_vals,
"Unknown"),
data_length);
/* Look for Msg3 data so that it may be compared with later
Contention Resolution body */
if ((lcids[n] == 0) && (direction == DIRECTION_UPLINK) && (data_length == 6)) {
if (!pinfo->fd->flags.visited) {
guint key = p_mac_lte_info->rnti;
Msg3Data *data = g_hash_table_lookup(mac_lte_msg3_hash, GUINT_TO_POINTER(key));
/* Look for previous entry for this UE */
if (data == NULL) {
/* Allocate space for data and add to table */
data = se_alloc(sizeof(Msg3Data));
g_hash_table_insert(mac_lte_msg3_hash, GUINT_TO_POINTER(key), data);
break;
}
/* Fill in data details */
data->framenum = pinfo->fd->num;
memcpy(&data->data, tvb_get_ptr(tvb, offset, data_length), data_length);
}
}
/* CCCH frames can be dissected directly by LTE RRC... */
if ((lcids[n] == 0) && global_mac_lte_attempt_rrc_decode) {
tvbuff_t *rrc_tvb = tvb_new_subset(tvb, offset, data_length, data_length);
/* Get appropriate dissector handle */
volatile dissector_handle_t protocol_handle = 0;
if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
protocol_handle = find_dissector("lte-rrc.ul.ccch");
}
else {
protocol_handle = find_dissector("lte-rrc.dl.ccch");
}
/* Hide raw view of bytes */
PROTO_ITEM_SET_HIDDEN(sdu_ti);
/* Call it (catch exceptions so that stats will be updated) */
TRY {
call_dissector_only(protocol_handle, rrc_tvb, pinfo, tree);
}
CATCH_ALL {
}
ENDTRY
}
offset += data_length;
/* Update tap byte count for this channel */
tap_info->bytes_for_lcid[lcids[n]] += data_length;
tap_info->sdus_for_lcid[lcids[n]]++;
}
else {
/* See if its a control PDU type */
/* Process what should be a valid control PDU type */
if (direction == DIRECTION_DOWNLINK) {
/****************************/
@ -1365,25 +1287,7 @@ static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree
/* No payload */
break;
case PADDING_LCID:
/* No payload, unless its the last subheader, in which case
it extends to the end of the PDU */
if (n == (number_of_headers-1)) {
if (tvb_length_remaining(tvb, offset) > 0) {
proto_tree_add_item(tree, hf_mac_lte_padding_data,
tvb, offset, -1, FALSE);
}
padding_length_ti = proto_tree_add_int(tree, hf_mac_lte_padding_length,
tvb, offset, 0,
p_mac_lte_info->length - offset);
PROTO_ITEM_SET_GENERATED(padding_length_ti);
/* Make sure the PDU isn't bigger than reported! */
if (offset > p_mac_lte_info->length) {
expert_add_info_format(pinfo, padding_length_ti, PI_MALFORMED, PI_ERROR,
"MAC PDU is longer than reported length (reported=%u, actual=%u)",
p_mac_lte_info->length, offset);
}
}
/* No payload (in this position) */
break;
default:
@ -1492,9 +1396,112 @@ static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree
}
break;
case PADDING_LCID:
/* No payload, unless its the last subheader, in which case
it extends to the end of the PDU */
if (n == (number_of_headers-1)) {
/* No payload, in this position */
break;
default:
break;
}
}
}
/* There might not be any data, if only headers (plus control data) were logged */
is_truncated = ((tvb_length_remaining(tvb, offset) == 0) && expecting_body_data);
truncated_ti = proto_tree_add_uint(tree, hf_mac_lte_sch_header_only, tvb, 0, 0,
is_truncated);
if (is_truncated) {
PROTO_ITEM_SET_GENERATED(truncated_ti);
expert_add_info_format(pinfo, truncated_ti, PI_SEQUENCE, PI_NOTE,
"MAC PDU SDUs have been ommitted");
return;
}
else {
PROTO_ITEM_SET_HIDDEN(truncated_ti);
}
/* Now process remaining bodies, which should all be data */
for (; n < number_of_headers; n++) {
/* Data SDUs treated identically for Uplink or downlink channels */
proto_item *sdu_ti;
volatile guint16 data_length;
/* Break out if meet padding */
if (lcids[n] == PADDING_LCID) {
break;
}
data_length = (pdu_lengths[n] == -1) ?
tvb_length_remaining(tvb, offset) :
pdu_lengths[n];
/* Dissect SDU */
sdu_ti = proto_tree_add_bytes_format(tree, hf_mac_lte_sch_sdu, tvb, offset, pdu_lengths[n],
tvb_get_ptr(tvb, offset, pdu_lengths[n]),
"SDU (%s, length=%u bytes)",
val_to_str(lcids[n],
(direction == DIRECTION_UPLINK) ?
ulsch_lcid_vals :
dlsch_lcid_vals,
"Unknown"),
data_length);
/* Look for Msg3 data so that it may be compared with later
Contention Resolution body */
if ((lcids[n] == 0) && (direction == DIRECTION_UPLINK) && (data_length == 6)) {
if (!pinfo->fd->flags.visited) {
guint key = p_mac_lte_info->rnti;
Msg3Data *data = g_hash_table_lookup(mac_lte_msg3_hash, GUINT_TO_POINTER(key));
/* Look for previous entry for this UE */
if (data == NULL) {
/* Allocate space for data and add to table */
data = se_alloc(sizeof(Msg3Data));
g_hash_table_insert(mac_lte_msg3_hash, GUINT_TO_POINTER(key), data);
}
/* Fill in data details */
data->framenum = pinfo->fd->num;
memcpy(&data->data, tvb_get_ptr(tvb, offset, data_length), data_length);
}
}
/* CCCH frames can be dissected directly by LTE RRC... */
if ((lcids[n] == 0) && global_mac_lte_attempt_rrc_decode) {
tvbuff_t *rrc_tvb = tvb_new_subset(tvb, offset, data_length, data_length);
/* Get appropriate dissector handle */
volatile dissector_handle_t protocol_handle = 0;
if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
protocol_handle = find_dissector("lte-rrc.ul.ccch");
}
else {
protocol_handle = find_dissector("lte-rrc.dl.ccch");
}
/* Hide raw view of bytes */
PROTO_ITEM_SET_HIDDEN(sdu_ti);
/* Call it (catch exceptions so that stats will be updated) */
TRY {
call_dissector_only(protocol_handle, rrc_tvb, pinfo, tree);
}
CATCH_ALL {
}
ENDTRY
}
offset += data_length;
/* Update tap byte count for this channel */
tap_info->bytes_for_lcid[lcids[n]] += data_length;
tap_info->sdus_for_lcid[lcids[n]]++;
}
/* Now padding, if present, extends to the end of the PDU */
if (lcids[number_of_headers-1] == PADDING_LCID) {
if (tvb_length_remaining(tvb, offset) > 0) {
proto_tree_add_item(tree, hf_mac_lte_padding_data,
tvb, offset, -1, FALSE);
@ -1512,14 +1519,6 @@ static void dissect_ulsch_or_dlsch(tvbuff_t *tvb, packet_info *pinfo, proto_tree
}
}
break;
default:
break;
}
}
}
}
}