aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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