aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorMartin Mathieson <martin.r.mathieson@googlemail.com>2007-05-08 17:13:14 +0000
committerMartin Mathieson <martin.r.mathieson@googlemail.com>2007-05-08 17:13:14 +0000
commitaac8ca13557c0b6e4c8cdfe4942c8dbeabb2a62c (patch)
tree57baac369b3c46d5d6d6759117f01c568455c847 /epan/dissectors
parent5b41e5bec5c74eddf98f2f58583873079b95a335 (diff)
From Kriang Lerdsuwanakij:
This patch adds the handling of Spare Extension bytes to UMTS Frame Protocol. It also handles the case when the presence of CRC in dedicated channels is not known (i.e. when FP from a K12/K15 log is dissected). The new functionality is placed in the new function "dissect_spare_extension_and_crc". The "dch_crc_present" field inside "struct fp_info" (file packet-umts_fp.h) is also extended to handle the case of unknown CRC presence. Much of other changes is to update "offset" variable and return it so that the location of Spare Extension and CRC is available. The patch also include a small tweak to handle Frame Protocol information saved from K15. Some fields appear 8 bytes later compared to K12. The changes are in the file packet-k12.c. svn path=/trunk/; revision=21726
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/packet-k12.c21
-rw-r--r--epan/dissectors/packet-umts_fp.c375
-rw-r--r--epan/dissectors/packet-umts_fp.h2
3 files changed, 216 insertions, 182 deletions
diff --git a/epan/dissectors/packet-k12.c b/epan/dissectors/packet-k12.c
index 1bf3d78a64..b94e1dca4e 100644
--- a/epan/dissectors/packet-k12.c
+++ b/epan/dissectors/packet-k12.c
@@ -86,6 +86,7 @@ static const value_string k12_port_types[] = {
};
static void fill_fp_info(fp_info *p_fp_info, guchar *extra_info, guint length) {
+ guint adj = 0;
/* 0x11=control frame 0x30=data frame */
guint info_type = pntohs(extra_info);
/* 1=FDD, 2=TDD 3.84, 3=TDD 1.28 */
@@ -96,6 +97,11 @@ static void fill_fp_info(fp_info *p_fp_info, guchar *extra_info, guint length) {
if (!p_fp_info || length < 22)
return;
+ /* Format used by K15, later fields are
+ shifted by 8 bytes. */
+ if (pntohs(extra_info+2) == 5)
+ adj = 8;
+
p_fp_info->iface_type = IuB_Interface;
p_fp_info->release = 0; /* dummy */
@@ -109,9 +115,10 @@ static void fill_fp_info(fp_info *p_fp_info, guchar *extra_info, guint length) {
p_fp_info->is_uplink = 0;
if (info_type == 0x11) /* control frame */
- channel_type = extra_info[21];
+ channel_type = extra_info[21 + adj];
else if (info_type == 0x30) /* data frame */
- channel_type = extra_info[22];
+ channel_type = extra_info[22 + adj];
+
switch (channel_type) {
case 1:
p_fp_info->channel = CHANNEL_BCH;
@@ -154,14 +161,14 @@ static void fill_fp_info(fp_info *p_fp_info, guchar *extra_info, guint length) {
break;
}
- p_fp_info->dch_crc_present = 1; /* dummy */
+ p_fp_info->dch_crc_present = 2; /* information not available */
if (info_type == 0x30) { /* data frame */
- p_fp_info->num_chans = extra_info[23];
- for (i = 0; i < (guint)p_fp_info->num_chans && (36+i*104) <= length; ++i) {
- p_fp_info->chan_tf_size[i] = pntohl(extra_info+28+i*104);
+ p_fp_info->num_chans = extra_info[23 + adj];
+ for (i = 0; i < (guint)p_fp_info->num_chans && (36+i*104+adj) <= length; ++i) {
+ p_fp_info->chan_tf_size[i] = pntohl(extra_info+28+i*104+adj);
if (p_fp_info->chan_tf_size[i])
- p_fp_info->chan_num_tbs[i] = pntohl(extra_info+32+i*104)
+ p_fp_info->chan_num_tbs[i] = pntohl(extra_info+32+i*104+adj)
/ p_fp_info->chan_tf_size[i];
}
}
diff --git a/epan/dissectors/packet-umts_fp.c b/epan/dissectors/packet-umts_fp.c
index 23713609aa..de54632896 100644
--- a/epan/dissectors/packet-umts_fp.c
+++ b/epan/dissectors/packet-umts_fp.c
@@ -35,7 +35,6 @@
/* TODO:
- IUR interface-specific formats
- verify header & payload CRCs
- - look for (and report as expert info) possible spare extension bytes
- R7?
*/
@@ -122,6 +121,7 @@ static int hf_fp_tpc_po = -1;
static int hf_fp_multiple_rl_set_indicator = -1;
static int hf_fp_max_ue_tx_pow = -1;
static int hf_fp_congestion_status = -1;
+static int hf_fp_spare_extension = -1;
/* Subtrees. */
static int ett_fp = -1;
@@ -274,30 +274,33 @@ static int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
int offset, guint16 length, guint8 number_of_pdus);
static int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
int num_tbs, int offset);
+static void dissect_spare_extension_and_crc(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *tree, guint8 dch_crc_present,
+ int offset);
/* Dissect common control messages */
-static void dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
- int offset, struct fp_info *p_fp_info);
-static void dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
- tvbuff_t *tvb, int offset);
-static void dissect_common_ul_node_synchronisation(packet_info *pinfo, proto_tree *tree,
- tvbuff_t *tvb, int offset);
-static void dissect_common_dl_syncronisation(packet_info *pinfo, proto_tree *tree,
- tvbuff_t *tvb, int offset,
- struct fp_info *p_fp_info);
-static void dissect_common_ul_syncronisation(packet_info *pinfo, proto_tree *tree,
- tvbuff_t *tvb, int offset,
- struct fp_info *p_fp_info);
-static void dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree,
+static int dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
+ int offset, struct fp_info *p_fp_info);
+static int dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *tvb, int offset);
+static int dissect_common_ul_node_synchronisation(packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *tvb, int offset);
+static int dissect_common_dl_syncronisation(packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *tvb, int offset,
+ struct fp_info *p_fp_info);
+static int dissect_common_ul_syncronisation(packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *tvb, int offset,
+ struct fp_info *p_fp_info);
+static int dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *tvb, int offset);
+static int dissect_hsdpa_capacity_request(packet_info *pinfo, proto_tree *tree,
tvbuff_t *tvb, int offset);
-static void dissect_hsdpa_capacity_request(packet_info *pinfo, proto_tree *tree,
- tvbuff_t *tvb, int offset);
-static void dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
- tvbuff_t *tvb, int offset);
+static int dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *tvb, int offset);
static void dissect_common_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
int offset, struct fp_info *p_fp_info);
-static void dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tree,
- tvbuff_t *tvb, int offset);
+static int dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *tvb, int offset);
/* Dissect common channel types */
static void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
@@ -319,25 +322,25 @@ static void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto
/* Dissect DCH control messages */
-static void dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo,
+static int dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo,
+ tvbuff_t *tvb, int offset);
+static int dissect_dch_rx_timing_deviation(proto_tree *tree, tvbuff_t *tvb, int offset);
+static int dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo,
tvbuff_t *tvb, int offset);
-static void dissect_dch_rx_timing_deviation(proto_tree *tree, tvbuff_t *tvb, int offset);
-static void dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo,
- tvbuff_t *tvb, int offset);
-static void dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo,
- tvbuff_t *tvb, int offset);
-static void dissect_dch_outer_loop_power_control(proto_tree *tree, packet_info *pinfo,
- tvbuff_t *tvb, int offset);
-static void dissect_dch_dl_node_synchronisation(proto_tree *tree, packet_info *pinfo,
- tvbuff_t *tvb, int offset);
-static void dissect_dch_ul_node_synchronisation(proto_tree *tree, packet_info *pinfo,
+static int dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo,
+ tvbuff_t *tvb, int offset);
+static int dissect_dch_outer_loop_power_control(proto_tree *tree, packet_info *pinfo,
tvbuff_t *tvb, int offset);
-static void dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info *pinfo,
- tvbuff_t *tvb, int offset);
-static void dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo,
- tvbuff_t *tvb, int offset);
-static void dissect_dch_tnl_congestion_indication(proto_tree *tree, packet_info *pinfo,
- tvbuff_t *tvb, int offset);
+static int dissect_dch_dl_node_synchronisation(proto_tree *tree, packet_info *pinfo,
+ tvbuff_t *tvb, int offset);
+static int dissect_dch_ul_node_synchronisation(proto_tree *tree, packet_info *pinfo,
+ tvbuff_t *tvb, int offset);
+static int dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info *pinfo,
+ tvbuff_t *tvb, int offset);
+static int dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo,
+ tvbuff_t *tvb, int offset);
+static int dissect_dch_tnl_congestion_indication(proto_tree *tree, packet_info *pinfo,
+ tvbuff_t *tvb, int offset);
static void dissect_dch_control_frame(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
@@ -350,7 +353,7 @@ static void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tr
/* Dissect dedicated channels */
static void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- int offset, struct fp_info *p_fp_info);
+ int offset, struct fp_info *p_fp_info);
/* Main dissection function */
static void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
@@ -563,12 +566,45 @@ int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
}
+void dissect_spare_extension_and_crc(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *tree, guint8 dch_crc_present,
+ int offset)
+{
+ int crc_size = 0;
+ int remain = tvb_length_remaining(tvb, offset);
+ proto_item *ti = NULL;
+
+ /* Payload CRC (optional) */
+ if (dch_crc_present == 1 || (dch_crc_present == 2 && remain >= 2))
+ {
+ crc_size = 2;
+ }
+
+ if (remain > crc_size)
+ {
+ ti = proto_tree_add_item(tree, hf_fp_spare_extension, tvb,
+ offset, remain-crc_size, FALSE);
+ proto_item_append_text(ti, " (%u octets)", remain-crc_size);
+ expert_add_info_format(pinfo, ti,
+ PI_UNDECODED, PI_WARN,
+ "Spare Extension present");
+ offset += remain-crc_size;
+ }
+
+ if (crc_size)
+ {
+ proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, crc_size,
+ FALSE);
+ }
+}
+
+
/***********************************************************/
/* Common control message types */
-void dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
- int offset, struct fp_info *p_fp_info)
+int dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
+ int offset, struct fp_info *p_fp_info)
{
if (p_fp_info->channel != CHANNEL_PCH)
{
@@ -583,7 +619,7 @@ void dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbu
/* ToA */
toa = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(tree, hf_fp_toa, tvb, offset, 2, FALSE);
- offset++;
+ offset += 2;
if (check_col(pinfo->cinfo, COL_INFO))
{
@@ -605,29 +641,34 @@ void dissect_common_timing_adjustment(packet_info *pinfo, proto_tree *tree, tvbu
/* 20 bits of ToA (followed by 4 padding bits) */
toa = ((int)(tvb_get_ntoh24(tvb, offset) << 8)) / 4096;
proto_tree_add_int(tree, hf_fp_pch_toa, tvb, offset, 3, toa);
+ offset += 3;
if (check_col(pinfo->cinfo, COL_INFO))
{
col_append_fstr(pinfo->cinfo, COL_INFO, " CFN=%u, ToA=%d", cfn, toa);
}
}
+ return offset;
}
-void dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
- tvbuff_t *tvb, int offset)
+int dissect_common_dl_node_synchronisation(packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *tvb, int offset)
{
/* T1 */
guint32 t1 = tvb_get_ntoh24(tvb, offset);
proto_tree_add_item(tree, hf_fp_t1, tvb, offset, 3, FALSE);
+ offset += 3;
if (check_col(pinfo->cinfo, COL_INFO))
{
col_append_fstr(pinfo->cinfo, COL_INFO, " T1=%u", t1);
}
+
+ return offset;
}
-void dissect_common_ul_node_synchronisation(packet_info *pinfo, proto_tree *tree,
- tvbuff_t *tvb, int offset)
+int dissect_common_ul_node_synchronisation(packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *tvb, int offset)
{
guint32 t1, t2, t3;
@@ -651,10 +692,12 @@ void dissect_common_ul_node_synchronisation(packet_info *pinfo, proto_tree *tree
col_append_fstr(pinfo->cinfo, COL_INFO, " T1=%u T2=%u, T3=%u",
t1, t2, t3);
}
+
+ return offset;
}
-void dissect_common_dl_syncronisation(packet_info *pinfo, proto_tree *tree,
- tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
+int dissect_common_dl_syncronisation(packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
{
guint16 cfn;
@@ -663,6 +706,7 @@ void dissect_common_dl_syncronisation(packet_info *pinfo, proto_tree *tree,
/* CFN control */
cfn = tvb_get_guint8(tvb, offset);
proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
+ offset++;
}
else
{
@@ -671,21 +715,24 @@ void dissect_common_dl_syncronisation(packet_info *pinfo, proto_tree *tree,
proto_tree_add_item(tree, hf_fp_pch_cfn, tvb, offset, 2, FALSE);
/* 4 bits of padding follow... */
+ offset += 2;
}
if (check_col(pinfo->cinfo, COL_INFO))
{
col_append_fstr(pinfo->cinfo, COL_INFO, " CFN=%u", cfn);
}
+
+ return offset;
}
-void dissect_common_ul_syncronisation(packet_info *pinfo, proto_tree *tree,
- tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
+int dissect_common_ul_syncronisation(packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *tvb, int offset, struct fp_info *p_fp_info)
{
- dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
+ return dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
}
-void dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+int dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
{
guint8 cfn;
guint8 timing_advance;
@@ -705,10 +752,12 @@ void dissect_common_timing_advance(packet_info *pinfo, proto_tree *tree, tvbuff_
col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, TA = %u",
cfn, timing_advance);
}
+
+ return offset;
}
-void dissect_hsdpa_capacity_request(packet_info *pinfo, proto_tree *tree,
- tvbuff_t *tvb, int offset)
+int dissect_hsdpa_capacity_request(packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *tvb, int offset)
{
guint8 priority;
guint16 user_buffer_size;
@@ -729,11 +778,11 @@ void dissect_hsdpa_capacity_request(packet_info *pinfo, proto_tree *tree,
priority, user_buffer_size);
}
- /* TODO: Spare extension may follow */
+ return offset;
}
-void dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
- tvbuff_t *tvb, int offset)
+int dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *tvb, int offset)
{
proto_item *ti;
proto_item *rate_ti;
@@ -801,8 +850,6 @@ void dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
}
}
-
-
if (check_col(pinfo->cinfo, COL_INFO))
{
col_append_fstr(pinfo->cinfo, COL_INFO,
@@ -810,12 +857,12 @@ void dissect_hsdpa_capacity_allocation(packet_info *pinfo, proto_tree *tree,
max_pdu_length, credits, interval, repetition_period);
}
- /* TODO: Spare extension may follow */
+ return offset;
}
-void dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tree,
- tvbuff_t *tvb, int offset)
+int dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tree,
+ tvbuff_t *tvb, int offset)
{
guint8 pusch_set_id;
guint8 activation_cfn;
@@ -834,6 +881,7 @@ void dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tre
/* Duration */
duration = tvb_get_guint8(tvb, offset) * 10;
proto_tree_add_uint(tree, hf_fp_duration, tvb, offset, 1, duration);
+ offset++;
if (check_col(pinfo->cinfo, COL_INFO))
{
@@ -841,6 +889,8 @@ void dissect_common_dynamic_pusch_assignment(packet_info *pinfo, proto_tree *tre
" PUSCH Set Id=%u Activation CFN=%u Duration=%u",
pusch_set_id, activation_cfn, duration);
}
+
+ return offset;
}
@@ -868,36 +918,39 @@ void dissect_common_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
case COMMON_OUTER_LOOP_POWER_CONTROL:
break;
case COMMON_TIMING_ADJUSTMENT:
- dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
+ offset = dissect_common_timing_adjustment(pinfo, tree, tvb, offset, p_fp_info);
break;
case COMMON_DL_SYNCHRONISATION:
- dissect_common_dl_syncronisation(pinfo, tree, tvb, offset, p_fp_info);
+ offset = dissect_common_dl_syncronisation(pinfo, tree, tvb, offset, p_fp_info);
break;
case COMMON_UL_SYNCHRONISATION:
- dissect_common_ul_syncronisation(pinfo, tree, tvb, offset, p_fp_info);
+ offset = dissect_common_ul_syncronisation(pinfo, tree, tvb, offset, p_fp_info);
break;
case COMMON_DL_NODE_SYNCHRONISATION:
- dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
+ offset = dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
break;
case COMMON_UL_NODE_SYNCHRONISATION:
- dissect_common_ul_node_synchronisation(pinfo, tree, tvb, offset);
+ offset = dissect_common_ul_node_synchronisation(pinfo, tree, tvb, offset);
break;
case COMMON_DYNAMIC_PUSCH_ASSIGNMENT:
- dissect_common_dynamic_pusch_assignment(pinfo, tree, tvb, offset);
+ offset = dissect_common_dynamic_pusch_assignment(pinfo, tree, tvb, offset);
break;
case COMMON_TIMING_ADVANCE:
- dissect_common_timing_advance(pinfo, tree, tvb, offset);
+ offset = dissect_common_timing_advance(pinfo, tree, tvb, offset);
break;
case COMMON_HS_DSCH_Capacity_Request:
- dissect_hsdpa_capacity_request(pinfo, tree, tvb, offset);
+ offset = dissect_hsdpa_capacity_request(pinfo, tree, tvb, offset);
break;
case COMMON_HS_DSCH_Capacity_Allocation:
- dissect_hsdpa_capacity_allocation(pinfo, tree, tvb, offset);
+ offset = dissect_hsdpa_capacity_allocation(pinfo, tree, tvb, offset);
break;
default:
break;
}
+
+ /* Spare Extension */
+ dissect_spare_extension_and_crc(tvb, pinfo, tree, 0, offset);
}
@@ -1019,9 +1072,8 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
offset++;
}
- /* Payload CRC */
- proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
- offset += 2;
+ /* Spare Extension and Payload CRC */
+ dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
}
}
@@ -1079,9 +1131,8 @@ void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
/* TB data */
offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
- /* Payload CRC */
- proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
- offset += 2;
+ /* Spare Extension and Payload CRC */
+ dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
}
}
@@ -1172,9 +1223,8 @@ void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
/* TB data */
offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
- /* Payload CRC */
- proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
- offset += 2;
+ /* Spare Extension and Payload CRC */
+ dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
}
}
@@ -1238,9 +1288,8 @@ void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
/* CRCIs */
offset = dissect_crci_bits(tvb, pinfo, tree, num_tbs, offset);
- /* Payload CRC */
- proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
- offset += 2;
+ /* Spare Extension and Payload CRC */
+ dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
}
}
@@ -1312,9 +1361,8 @@ void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
/* TB data */
offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
- /* Payload CRC */
- proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
- offset += 2;
+ /* Spare Extension and Payload CRC */
+ dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
}
}
@@ -1375,9 +1423,8 @@ void dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
/* CRCIs */
offset = dissect_crci_bits(tvb, pinfo, tree, num_tbs, offset);
- /* Payload CRC */
- proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
- offset += 2;
+ /* Spare Extension and Payload CRC */
+ dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
}
}
@@ -1417,7 +1464,7 @@ void dissect_iur_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree
/************************/
/* DCH control messages */
-void dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
+int dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
{
guint8 control_cfn;
gint16 toa;
@@ -1437,9 +1484,11 @@ void dissect_dch_timing_adjustment(proto_tree *tree, packet_info *pinfo, tvbuff_
col_append_fstr(pinfo->cinfo, COL_INFO,
" CFN = %u, ToA = %d", control_cfn, toa);
}
+
+ return offset;
}
-void dissect_dch_rx_timing_deviation(proto_tree *tree, tvbuff_t *tvb, int offset)
+int dissect_dch_rx_timing_deviation(proto_tree *tree, tvbuff_t *tvb, int offset)
{
/* CFN control */
proto_tree_add_item(tree, hf_fp_cfn_control, tvb, offset, 1, FALSE);
@@ -1448,9 +1497,11 @@ void dissect_dch_rx_timing_deviation(proto_tree *tree, tvbuff_t *tvb, int offset
/* Rx Timing Deviation */
proto_tree_add_item(tree, hf_fp_dch_rx_timing_deviation, tvb, offset, 1, FALSE);
offset++;
+
+ return offset;
}
-void dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
+int dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
{
/* CFN control */
guint cfn = tvb_get_guint8(tvb, offset);
@@ -1461,9 +1512,11 @@ void dissect_dch_dl_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff
{
col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u", cfn);
}
+
+ return offset;
}
-void dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
+int dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
{
guint8 cfn;
gint16 toa;
@@ -1483,31 +1536,36 @@ void dissect_dch_ul_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff
col_append_fstr(pinfo->cinfo, COL_INFO, " CFN = %u, ToA = %d",
cfn, toa);
}
+
+ return offset;
}
-void dissect_dch_outer_loop_power_control(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
+int dissect_dch_outer_loop_power_control(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
{
/* SIR target */
float target = (float)-8.2 + ((float)0.1 * (float)(int)(tvb_get_guint8(tvb, offset)));
proto_tree_add_float(tree, hf_fp_ul_sir_target, tvb, offset, 1, target);
+ offset++;
if (check_col(pinfo->cinfo, COL_INFO))
{
- col_append_fstr(pinfo->cinfo, COL_INFO, "SIR Target = %f", target);
+ col_append_fstr(pinfo->cinfo, COL_INFO, " SIR Target = %f", target);
}
+
+ return offset;
}
-void dissect_dch_dl_node_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
+int dissect_dch_dl_node_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
{
- dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
+ return dissect_common_dl_node_synchronisation(pinfo, tree, tvb, offset);
}
-void dissect_dch_ul_node_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
+int dissect_dch_ul_node_synchronisation(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
{
- dissect_common_ul_node_synchronisation(pinfo, tree, tvb, offset);
+ return dissect_common_ul_node_synchronisation(pinfo, tree, tvb, offset);
}
-void dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
+int dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
{
int n;
guint8 cfn;
@@ -1539,27 +1597,31 @@ void dissect_dch_radio_interface_parameter_update(proto_tree *tree, packet_info
/* MAX_UE_TX_POW */
value = (tvb_get_guint8(tvb, offset) & 0x7f);
proto_tree_add_int(tree, hf_fp_max_ue_tx_pow, tvb, offset, 1, -55 + value);
+ offset++;
- /* TODO: spare extension */
+ return offset;
}
-void dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
+int dissect_dch_timing_advance(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
{
- dissect_common_timing_advance(pinfo, tree, tvb, offset);
+ return dissect_common_timing_advance(pinfo, tree, tvb, offset);
}
-void dissect_dch_tnl_congestion_indication(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
+int dissect_dch_tnl_congestion_indication(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
{
guint8 status = (tvb_get_guint8(tvb, offset) & 0x03);
/* Congestion status */
proto_tree_add_int(tree, hf_fp_congestion_status, tvb, offset, 1, FALSE);
+ offset++;
if (check_col(pinfo->cinfo, COL_INFO))
{
col_append_fstr(pinfo->cinfo, COL_INFO, " status = %s",
val_to_str(status, congestion_status_vals, "unknown"));
}
+
+ return offset;
}
@@ -1583,36 +1645,39 @@ void dissect_dch_control_frame(proto_tree *tree, packet_info *pinfo, tvbuff_t *t
switch (control_frame_type)
{
case DCH_TIMING_ADJUSTMENT:
- dissect_dch_timing_adjustment(tree, pinfo, tvb, offset);
+ offset = dissect_dch_timing_adjustment(tree, pinfo, tvb, offset);
break;
case DCH_RX_TIMING_DEVIATION:
- dissect_dch_rx_timing_deviation(tree, tvb, offset);
+ offset = dissect_dch_rx_timing_deviation(tree, tvb, offset);
break;
case DCH_DL_SYNCHRONISATION:
- dissect_dch_dl_synchronisation(tree, pinfo, tvb, offset);
+ offset = dissect_dch_dl_synchronisation(tree, pinfo, tvb, offset);
break;
case DCH_UL_SYNCHRONISATION:
- dissect_dch_ul_synchronisation(tree, pinfo, tvb, offset);
+ offset = dissect_dch_ul_synchronisation(tree, pinfo, tvb, offset);
break;
case DCH_OUTER_LOOP_POWER_CONTROL:
- dissect_dch_outer_loop_power_control(tree, pinfo, tvb, offset);
+ offset = dissect_dch_outer_loop_power_control(tree, pinfo, tvb, offset);
break;
case DCH_DL_NODE_SYNCHRONISATION:
- dissect_dch_dl_node_synchronisation(tree, pinfo, tvb, offset);
+ offset = dissect_dch_dl_node_synchronisation(tree, pinfo, tvb, offset);
break;
case DCH_UL_NODE_SYNCHRONISATION:
- dissect_dch_ul_node_synchronisation(tree, pinfo, tvb, offset);
+ offset = dissect_dch_ul_node_synchronisation(tree, pinfo, tvb, offset);
break;
case DCH_RADIO_INTERFACE_PARAMETER_UPDATE:
- dissect_dch_radio_interface_parameter_update(tree, pinfo, tvb, offset);
+ offset = dissect_dch_radio_interface_parameter_update(tree, pinfo, tvb, offset);
break;
case DCH_TIMING_ADVANCE:
- dissect_dch_timing_advance(tree, pinfo, tvb, offset);
+ offset = dissect_dch_timing_advance(tree, pinfo, tvb, offset);
break;
case DCH_TNL_CONGESTION_INDICATION:
- dissect_dch_tnl_congestion_indication(tree, pinfo, tvb, offset);
+ offset = dissect_dch_tnl_congestion_indication(tree, pinfo, tvb, offset);
break;
}
+
+ /* Spare Extension */
+ dissect_spare_extension_and_crc(tvb, pinfo, tree, 0, offset);
}
/*******************************/
@@ -1684,11 +1749,9 @@ void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
offset = dissect_crci_bits(tvb, pinfo, tree, num_tbs, offset);
}
- /* Payload CRC (optional) */
- if (p_fp_info->dch_crc_present)
- {
- proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
- }
+ /* Spare extension and payload CRC (optional) */
+ dissect_spare_extension_and_crc(tvb, pinfo, tree,
+ p_fp_info->dch_crc_present, offset);
}
}
@@ -1796,61 +1859,25 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
/* Details of each MAC-es PDU */
for (i=0; i < subframes[n].number_of_mac_es_pdus; i++)
{
- guint8 ddi;
- int ddi_offset;
- guint8 n_pdus;
- int n_pdus_offset;
+ guint64 ddi;
+ int ddi_offset;
+ guint64 n_pdus;
+ int n_pdus_offset;
/* DDI (6 bits) */
ddi_offset = offset + (bit_offset / 8);
- switch (bit_offset%8)
- {
- case 0:
- ddi = (tvb_get_guint8(tvb, ddi_offset) >> 2);
- break;
- case 2:
- ddi = (tvb_get_guint8(tvb, ddi_offset) & 0x3f);
- break;
- case 4:
- ddi = (tvb_get_ntohs(tvb, ddi_offset) >> 6) & 0x003f;
- break;
- case 6:
- ddi = (tvb_get_ntohs(tvb, ddi_offset) >> 4) & 0x003f;
- break;
- default:
- /* Can't get here, but avoid warning */
- return;
- }
-
- proto_tree_add_uint(subframe_header_tree, hf_fp_edch_ddi, tvb, ddi_offset,
- ((bit_offset%8) <= 2) ? 1 : 2, ddi);
+ proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_ddi, tvb,
+ offset*8 + bit_offset, 6, &ddi, FALSE);
subframes[n].ddi[i] = ddi;
bit_offset += 6;
/* Number of MAC-d PDUs (6 bits) */
n_pdus_offset = offset + (bit_offset / 8);
- switch (bit_offset%8)
- {
- case 0:
- n_pdus = (tvb_get_guint8(tvb, n_pdus_offset) >> 2);
- break;
- case 2:
- n_pdus = (tvb_get_guint8(tvb, n_pdus_offset) & 0x3f);
- break;
- case 4:
- n_pdus = (tvb_get_ntohs(tvb, n_pdus_offset) >> 6) & 0x003f;
- break;
- case 6:
- n_pdus = (tvb_get_ntohs(tvb, n_pdus_offset) >> 4) & 0x003f;
- break;
- default:
- /* Can't get here, but avoid warning */
- return;
- }
- proto_tree_add_uint(subframe_header_tree, hf_fp_edch_number_of_mac_d_pdus, tvb, n_pdus_offset,
- ((bit_offset%8) <= 2) ? 1 : 2, n_pdus);
+
+ proto_tree_add_bits_ret_val(subframe_header_tree, hf_fp_edch_number_of_mac_d_pdus, tvb,
+ offset*8 + bit_offset, 6, &n_pdus, FALSE);
subframes[n].number_of_mac_d_pdus[i] = n_pdus;
bit_offset += 6;
@@ -1965,13 +1992,9 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
cfn, total_bits, total_pdus, number_of_subframes);
}
- /* Payload CRC (optional) */
- /* TODO: is this test correct...? */
- /* if (p_fp_info->dch_crc_present) */
- if (tvb_length_remaining(tvb, offset) == 2)
- {
- proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
- }
+ /* Spare extension and payload CRC (optional) */
+ dissect_spare_extension_and_crc(tvb, pinfo, tree,
+ p_fp_info->dch_crc_present, offset);
}
}
@@ -2087,10 +2110,8 @@ void dissect_hsdsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
}
}
- /* TODO: may be spare extension to skip */
-
- /* Payload CRC */
- proto_tree_add_item(tree, hf_fp_payload_crc, tvb, offset, 2, FALSE);
+ /* Spare Extension and Payload CRC */
+ dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
}
}
@@ -2841,6 +2862,12 @@ void proto_register_fp(void)
"Congestion Status", HFILL
}
},
+ { &hf_fp_spare_extension,
+ { "Spare Extension",
+ "fp.spare-extension", FT_NONE, BASE_NONE, NULL, 0x0,
+ "Spare Extension", HFILL
+ }
+ },
};
diff --git a/epan/dissectors/packet-umts_fp.h b/epan/dissectors/packet-umts_fp.h
index 2dc509e3e6..d74d1cb133 100644
--- a/epan/dissectors/packet-umts_fp.h
+++ b/epan/dissectors/packet-umts_fp.h
@@ -57,7 +57,7 @@ typedef struct fp_info
guint8 release_month; /* e.g. 12 for December */
gboolean is_uplink;
gint channel; /* see definitions above */
- gboolean dch_crc_present;
+ guint8 dch_crc_present; /* 0=No, 1=Yes, 2=Unknown */
gint paging_indications;
gint num_chans;
#define MAX_FP_CHANS 64