Add support for FP E-DCH T2 frames.

svn path=/trunk/; revision=35188
This commit is contained in:
Martin Mathieson 2010-12-15 01:45:43 +00:00
parent da59dc4c46
commit dc24655c06
3 changed files with 309 additions and 3 deletions

View File

@ -1099,6 +1099,7 @@ static dissector_handle_t look_for_dissector(char *protocol_name)
(strcmp(protocol_name, "fp_r5") == 0) ||
(strcmp(protocol_name, "fp_r6") == 0) ||
(strcmp(protocol_name, "fp_r7") == 0) ||
(strcmp(protocol_name, "fp_r8") == 0) ||
(strcmp(protocol_name, "fpiur_r5") == 0)) {
return find_dissector("fp");
@ -1231,6 +1232,9 @@ void attach_fp_info(packet_info *pinfo, gboolean received, const char *protocol_
else if (strcmp(protocol_name, "fp_r7") == 0) {
p_fp_info->release = 7;
}
else if (strcmp(protocol_name, "fp_r8") == 0) {
p_fp_info->release = 8;
}
else if (strcmp(protocol_name, "fpiur_r5") == 0) {
p_fp_info->release = 5;
}
@ -1272,6 +1276,12 @@ void attach_fp_info(packet_info *pinfo, gboolean received, const char *protocol_
p_fp_info->release_month = 3;
break;
case 8:
p_fp_info->release_year = 2010;
p_fp_info->release_month = 6;
break;
default:
p_fp_info->release_year = 0;
p_fp_info->release_month = 0;
@ -1360,6 +1370,13 @@ void attach_fp_info(packet_info *pinfo, gboolean received, const char *protocol_
for (n=0; n < p_fp_info->no_ddi_entries; n++) {
p_fp_info->edch_macd_pdu_size[n] = outhdr_values[i++];
}
if (strcmp(protocol_name, "fp_r8") == 0) {
p_fp_info->edch_type = outhdr_values[i++];
}
else {
p_fp_info->edch_type = 0;
}
}
/* Interface must be IuB */
@ -1810,6 +1827,7 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
(strcmp(protocol_name, "fp_r5") == 0) ||
(strcmp(protocol_name, "fp_r6") == 0) ||
(strcmp(protocol_name, "fp_r7") == 0) ||
(strcmp(protocol_name, "fp_r8") == 0) ||
(strcmp(protocol_name, "fpiur_r5") == 0)) {
parse_outhdr_string(tvb_get_ptr(tvb, outhdr_start, outhdr_length));

View File

@ -96,6 +96,19 @@ static int hf_fp_edch_number_of_mac_d_pdus = -1;
static int hf_fp_edch_pdu_padding = -1;
static int hf_fp_edch_tsn = -1;
static int hf_fp_edch_mac_es_pdu = -1;
static int hf_fp_edch_user_buffer_size = -1;
static int hf_fp_edch_no_macid_sdus = -1;
static int hf_fp_edch_number_of_mac_is_pdus = -1;
static int hf_fp_edch_macis_descriptors = -1;
static int hf_fp_edch_macis_lchid = -1;
static int hf_fp_edch_macis_length = -1;
static int hf_fp_edch_macis_flag = -1;
static int hf_fp_edch_macis_tsn = -1;
static int hf_fp_edch_macis_ss = -1;
static int hf_fp_edch_macis_sdu = -1;
static int hf_fp_frame_seq_nr = -1;
static int hf_fp_hsdsch_pdu_block_header = -1;
static int hf_fp_hsdsch_pdu_block = -1;
@ -177,6 +190,8 @@ static int ett_fp_ddi_config = -1;
static int ett_fp_edch_subframe_header = -1;
static int ett_fp_edch_subframe = -1;
static int ett_fp_edch_maces = -1;
static int ett_fp_edch_macis_descriptors = -1;
static int ett_fp_edch_macis_pdu = -1;
static int ett_fp_hsdsch_new_ie_flags = -1;
static int ett_fp_rach_new_ie_flags = -1;
static int ett_fp_hsdsch_pdu_block_header = -1;
@ -195,8 +210,8 @@ static gboolean preferences_call_mac_dissectors = TRUE;
static gboolean preferences_show_release_info = TRUE;
/* E-DCH channel header information */
struct subframe_info
/* E-DCH (T1) channel header information */
struct edch_t1_subframe_info
{
guint8 subframe_number;
guint8 number_of_mac_es_pdus;
@ -204,6 +219,17 @@ struct subframe_info
guint16 number_of_mac_d_pdus[64];
};
/* E-DCH (T2) channel header information */
struct edch_t2_subframe_info
{
guint8 subframe_number;
guint8 number_of_mac_is_pdus;
guint8 number_of_mac_is_sdus[16];
guint8 mac_is_lchid[16][16];
guint16 mac_is_length[16][16];
};
static const value_string channel_type_vals[] =
{
{ CHANNEL_RACH_FDD, "RACH_FDD" },
@ -296,6 +322,16 @@ static const value_string hsdshc_mac_entity_vals[] = {
{ 0, NULL }
};
/* TODO: add and use */
static const value_string segmentation_status_vals[] = {
{ 0, "" },
{ 1, "" },
{ 2, "" },
{ 3, "" },
{ 0, NULL }
};
/* Dedicated control types */
#define DCH_OUTER_LOOP_POWER_CONTROL 1
@ -458,6 +494,10 @@ static void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tr
static void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
int offset, struct fp_info *p_fp_info);
static void dissect_e_dch_t2_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
int offset, struct fp_info *p_fp_info,
int number_of_subframes);
/* Main dissection function */
static void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
@ -2285,7 +2325,11 @@ static void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_
guint8 number_of_subframes;
guint8 cfn;
int n;
struct subframe_info subframes[16];
struct edch_t1_subframe_info subframes[16];
if (p_fp_info->edch_type == 1) {
col_append_str(pinfo->cinfo, COL_INFO, " (T2)");
}
/* Header CRC */
proto_tree_add_item(tree, hf_fp_edch_header_crc, tvb, offset, 2, FALSE);
@ -2340,6 +2384,13 @@ static void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_
proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
offset++;
/* Remainder of T2 data frame differs here... */
if (p_fp_info->edch_type == 1) {
dissect_e_dch_t2_channel_info(tvb, pinfo, tree, offset, p_fp_info,
number_of_subframes);
return;
}
/* EDCH subframe header list */
for (n=0; n < number_of_subframes; n++)
{
@ -2562,6 +2613,175 @@ static void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_
}
}
/* Dissect the remainder of the T2 frame that differs from T1 */
static void dissect_e_dch_t2_channel_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
int offset, struct fp_info *p_fp_info _U_,
int number_of_subframes)
{
int n;
int pdu_no;
static struct edch_t2_subframe_info subframes[16];
guint64 total_macis_sdus;
guint16 macis_sdus_found = 0;
gboolean F;
proto_item *subframe_macis_descriptors_ti = NULL;
/* User Buffer size */
proto_tree_add_bits_item(tree, hf_fp_edch_user_buffer_size, tvb, offset*8,
18, FALSE);
offset += 2;
/* Spare is in-between... */
/* Total number of MAC-is SDUs */
proto_tree_add_bits_ret_val(tree, hf_fp_edch_no_macid_sdus, tvb, offset*8+4,
12, &total_macis_sdus, FALSE);
offset += 2;
/* EDCH subframe header list */
for (n=0; n < number_of_subframes; n++) {
proto_item *subframe_header_ti;
proto_tree *subframe_header_tree;
/* Add subframe header subtree */
subframe_header_ti = proto_tree_add_string_format(tree, hf_fp_edch_subframe_header, tvb, offset, 0,
"", "Subframe");
subframe_header_tree = proto_item_add_subtree(subframe_header_ti, ett_fp_edch_subframe_header);
/* Number of HARQ Retransmissions */
proto_tree_add_item(subframe_header_tree, hf_fp_edch_harq_retransmissions, tvb,
offset, 1, FALSE);
/* Subframe number */
subframes[n].subframe_number = (tvb_get_guint8(tvb, offset) & 0x07);
proto_tree_add_item(subframe_header_tree, hf_fp_edch_subframe_number, tvb,
offset, 1, FALSE);
offset++;
/* Number of MAC-is PDUs */
subframes[n].number_of_mac_is_pdus = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
proto_tree_add_item(subframe_header_tree, hf_fp_edch_number_of_mac_is_pdus,
tvb, offset, 1, FALSE);
/* Next 4 bits are spare */
offset++;
/* Show summary in root */
proto_item_append_text(subframe_header_ti, " (SFN %u, %u MAC-is PDUs)",
subframes[n].subframe_number, subframes[n].number_of_mac_is_pdus);
proto_item_set_len(subframe_header_ti, 2);
}
/* MAC-is PDU descriptors for each subframe follow */
for (n=0; n < number_of_subframes; n++) {
proto_tree *subframe_macis_descriptors_tree;
/* Add subframe header subtree */
subframe_macis_descriptors_ti = proto_tree_add_string_format(tree, hf_fp_edch_macis_descriptors, tvb, offset, 0,
"", "MAC-is descriptors (SFN %u)", subframes[n].subframe_number);
proto_item_set_len(subframe_macis_descriptors_ti, subframes[n].number_of_mac_is_pdus*2);
subframe_macis_descriptors_tree = proto_item_add_subtree(subframe_macis_descriptors_ti,
ett_fp_edch_macis_descriptors);
/* Find a sequence of descriptors for each MAC-is PDU in this subframe */
for (pdu_no=0; pdu_no < subframes[n].number_of_mac_is_pdus; pdu_no++) {
proto_item *f_ti = NULL;
subframes[n].number_of_mac_is_sdus[pdu_no] = 0;
do {
/* Check we haven't gone past the limit */
if (macis_sdus_found++ > total_macis_sdus) {
expert_add_info_format(pinfo, f_ti, PI_MALFORMED, PI_ERROR,
"Found too many (%u) MAC-is SDUs - header said there were %u",
macis_sdus_found, (guint16)total_macis_sdus);
}
/* LCH-ID */
subframes[n].mac_is_lchid[pdu_no][subframes[n].number_of_mac_is_sdus[pdu_no]] = (tvb_get_guint8(tvb, offset) & 0xf0) >> 4;
proto_tree_add_item(subframe_macis_descriptors_tree, hf_fp_edch_macis_lchid, tvb, offset, 1, FALSE);
/* Length */
subframes[n].mac_is_length[pdu_no][subframes[n].number_of_mac_is_sdus[pdu_no]] = (tvb_get_ntohs(tvb, offset) & 0x0ffe) >> 1;
proto_tree_add_item(subframe_macis_descriptors_tree, hf_fp_edch_macis_length, tvb, offset, 2, FALSE);
offset++;
/* Flag */
F = tvb_get_guint8(tvb, offset) & 0x01;
f_ti = proto_tree_add_item(subframe_macis_descriptors_tree, hf_fp_edch_macis_flag, tvb, offset, 1, FALSE);
subframes[n].number_of_mac_is_sdus[pdu_no]++;
offset++;
} while (F);
}
}
/* Check overall count of MAC-is SDUs */
if (macis_sdus_found != total_macis_sdus) {
expert_add_info_format(pinfo, subframe_macis_descriptors_ti, PI_MALFORMED, PI_ERROR,
"Frame contains %u MAC-is SDUs - header said there would be %u!",
macis_sdus_found, (guint16)total_macis_sdus);
}
/* Now PDUs */
for (n=0; n < number_of_subframes; n++) {
/* MAC-is PDU */
for (pdu_no=0; pdu_no < subframes[n].number_of_mac_is_pdus; pdu_no++) {
int sdu_no;
guint8 ss, tsn;
guint32 total_bytes = 0;
proto_item *ti;
proto_item *macis_pdu_ti;
proto_tree *macis_pdu_tree;
/* Add subframe header subtree */
macis_pdu_ti = proto_tree_add_string_format(tree, hf_fp_edch_subframe_header, tvb, offset, 0,
"", "MAC-is PDU (SFN=%u #%u)",
subframes[n].subframe_number, pdu_no+1);
macis_pdu_tree = proto_item_add_subtree(macis_pdu_ti, ett_fp_edch_macis_pdu);
/* SS */
ss = (tvb_get_guint8(tvb, offset) & 0xc0) >> 6;
proto_tree_add_item(macis_pdu_tree, hf_fp_edch_macis_ss, tvb, offset, 1, FALSE);
/* TSN */
tsn = tvb_get_guint8(tvb, offset) & 0x03;
proto_tree_add_item(macis_pdu_tree, hf_fp_edch_macis_tsn, tvb, offset, 1, FALSE);
offset++;
/* MAC-is SDUs (i.e. MACd PDUs) */
for (sdu_no=0; sdu_no < subframes[n].number_of_mac_is_sdus[pdu_no]; sdu_no++) {
ti = proto_tree_add_item(macis_pdu_tree, hf_fp_edch_macis_sdu, tvb,
offset,
subframes[n].mac_is_length[pdu_no][sdu_no],
FALSE);
proto_item_append_text(ti, " (LCH-ID=%u Len=%u)",
subframes[n].mac_is_lchid[pdu_no][sdu_no],
subframes[n].mac_is_length[pdu_no][sdu_no]);
offset += subframes[n].mac_is_length[pdu_no][sdu_no];
total_bytes += subframes[n].mac_is_length[pdu_no][sdu_no];
}
proto_item_append_text(macis_pdu_ti, " - SS=%u TSN=%u (%u bytes in %u SDUs)",
ss, tsn, total_bytes, subframes[n].number_of_mac_is_sdus[pdu_no]);
}
}
/* Spare extension and payload CRC (optional) */
dissect_spare_extension_and_crc(tvb, pinfo, tree,
p_fp_info->dch_crc_present, offset);
}
/**********************************************************/
/* Dissect an HSDSCH channel */
@ -3472,6 +3692,71 @@ void proto_register_fp(void)
NULL, HFILL
}
},
{ &hf_fp_edch_user_buffer_size,
{ "User Buffer Size",
"fp.edch.user-buffer-size", FT_UINT24, BASE_DEC, NULL, 0x0,
NULL, HFILL
}
},
{ &hf_fp_edch_no_macid_sdus,
{ "No of MAC-is SDUs",
"fp.edch.no-macis-sdus", FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL
}
},
{ &hf_fp_edch_number_of_mac_is_pdus,
{ "Number of Mac-is PDUs",
"fp.edch.number-of-mac-is-pdus", FT_UINT8, BASE_DEC, 0, 0xf0,
NULL, HFILL
}
},
{ &hf_fp_edch_macis_descriptors,
{ "MAC-is Descriptors",
"fp.edch.mac-is.descriptors", FT_STRING, BASE_NONE, NULL, 0x0,
NULL, HFILL
}
},
{ &hf_fp_edch_macis_lchid,
{ "LCH-ID",
"fp.edch.mac-is.lchid", FT_UINT8, BASE_HEX, 0, 0xf0,
NULL, HFILL
}
},
{ &hf_fp_edch_macis_length,
{ "Length",
"fp.edch.mac-is.length", FT_UINT16, BASE_DEC, 0, 0x0ffe,
NULL, HFILL
}
},
{ &hf_fp_edch_macis_flag,
{ "Flag",
"fp.edch.mac-is.lchid", FT_UINT8, BASE_HEX, 0, 0x01,
"Indicates if another entry follows", HFILL
}
},
{ &hf_fp_edch_macis_ss,
{ "SS",
/* TODO: VALS */
"fp.edch.mac-is.tsn", FT_UINT8, BASE_HEX, 0, 0xc0,
"Segmentation Status", HFILL
}
},
{ &hf_fp_edch_macis_tsn,
{ "TSN",
"fp.edch.mac-is.tsn", FT_UINT8, BASE_HEX, 0, 0x3f,
"Transmission Sequence Number", HFILL
}
},
{ &hf_fp_edch_macis_sdu,
{ "MAC-is SDU",
"fp.edch.mac-is.sdu", FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL
}
},
{ &hf_fp_frame_seq_nr,
{ "Frame Seq Nr",
"fp.frame-seq-nr", FT_UINT8, BASE_DEC, 0, 0xf0,
@ -3985,6 +4270,8 @@ void proto_register_fp(void)
&ett_fp_edch_subframe_header,
&ett_fp_edch_subframe,
&ett_fp_edch_maces,
&ett_fp_edch_macis_descriptors,
&ett_fp_edch_macis_pdu,
&ett_fp_hsdsch_new_ie_flags,
&ett_fp_rach_new_ie_flags,
&ett_fp_hsdsch_pdu_block_header,

View File

@ -94,6 +94,7 @@ typedef struct fp_info
gint no_ddi_entries;
guint8 edch_ddi[MAX_EDCH_DDIS];
guint edch_macd_pdu_size[MAX_EDCH_DDIS];
guint8 edch_type; /* 1 means T2 */
gint cur_tb; /* current transport block (required for dissecting of single TBs */
gint cur_chan; /* current channel, required to retrieve the correct channel configuration for UMTS MAC */